/* ===========================================================================
   PLATE — the substrate for Underspire's authoring tools.

   THESIS: every tool is a keyed specimen. A subject is drawn once at full
   size, its parts lettered, and a legend beneath binds every mark to a name
   and a state. It refuses the admin dashboard (shell + sidebar + card grid +
   one accent) and its predictable opposite, the phosphor terminal.

   OWN-WORLD: 19th-c hand-tinted anatomical atlas. Bone line on a plate field
   mounted to a darker board, inside a double platemark. Four washes with
   fixed meanings — bone set, ochre inherited, carmine attention, terre verte
   committed, Prussian reference — each always paired with its legend word.
   Spectral roman and italic for captions and specimen names, Archivo Narrow
   tracked for engraved legends, Departure Mono only where the payload is
   real monospaced game text. Square corners throughout: a platemark has no
   radius.

   This file owns tokens and primitives. Per-surface plates live beside it.
   Faces are self-hosted OFL; see docs/DATA_LICENSES.md.
   =========================================================================== */

@font-face {
  font-family: "Spectral";
  src: url("fonts/Spectral-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Spectral";
  src: url("fonts/Spectral-Italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Spectral";
  src: url("fonts/Spectral-SemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Archivo Narrow";
  src: url("fonts/ArchivoNarrow-var.woff2") format("woff2");
  font-weight: 400 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Departure Mono";
  src: url("fonts/DepartureMono-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}

:root {
  color-scheme: dark;

  /* --- the atlas: board, plate field, recess ------------------------------ */
  --board:        #14181a;   /* mount board the plate is pasted to */
  --plate:        #1e2427;   /* the plate field itself */
  --plate-hi:     #252c30;   /* raised region inside the plate */
  --plate-recess: #171c1e;   /* wells, inputs, preview grounds */

  /* --- ink ---------------------------------------------------------------- */
  --line:      #e8e4d8;      /* engraved line, body text   12.4:1 on plate */
  --line-2:    #a9b0ac;      /* caption, secondary          7.1:1 on plate */
  --line-3:    #78817e;      /* placeholder, disabled       3.6:1 — never body */
  --rule:      rgba(232, 228, 216, 0.16);
  --rule-firm: rgba(232, 228, 216, 0.30);
  --rule-hair: rgba(232, 228, 216, 0.09);

  /* --- the four washes. Each is a role, never decoration, and every use is
         paired with a legend word so it survives greyscale. ---------------- */
  --ochre:        #d9a441;   /* inherited / computed / live value   7.0:1 */
  --ochre-fill:   #6a4d18;
  /* The wash at reading strength, for a row that is merely current rather
     than carrying a value: the bench index selection and the counters'
     hover. Both referenced this before it was declared, so the selected
     entry in every tool's rail was marked only by its inset rule. */
  --ochre-faint:  rgba(217, 164, 65, 0.10);
  --carmine:      #e8776a;   /* attention: invalid, unsaved, destructive 5.5:1 */
  --carmine-fill: #8e2f28;
  --terre:        #7fae86;   /* committed: saved, spawned, confirmed 6.2:1 */
  --terre-fill:   #35543c;
  --prussian:     #6ea3c4;   /* reference out: prototypes, links, cross-refs 5.8:1 */
  --prussian-fill:#274a60;

  /* --- faces -------------------------------------------------------------- */
  --f-plate:  "Spectral", Georgia, "Times New Roman", serif;
  --f-legend: "Archivo Narrow", "Roboto Condensed", system-ui, sans-serif;
  --f-data:   "Departure Mono", ui-monospace, "DejaVu Sans Mono", monospace;

  --fs-legend: 11px;   /* engraved legend, tracked caps */
  --fs-key:    12px;   /* the lettered key marks */
  --fs-meta:   13px;
  --fs:        15px;
  --fs-cap:    15px;   /* italic caption */
  --fs-fig:    20px;   /* plate number */
  --fs-title:  27px;   /* specimen name */
  --track:     0.14em;

  /* --- measure ------------------------------------------------------------ */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 36px; --s7: 56px;
  --prose: 68ch;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

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

html { -webkit-text-size-adjust: 100%; }

body.plate-world {
  margin: 0;
  min-height: 100vh;
  background: var(--board);
  color: var(--line);
  font: 400 var(--fs)/1.55 var(--f-plate);
  font-variant-numeric: tabular-nums;
}

/* The plate is a work surface, not a document.

   Every tool scrolled as one page. The running head left the viewport, the
   colophon's sticky bar sat on top of whatever was under it, and the index and
   the proof — sticky, which is not fixed — slid away at both ends of a long
   plate. The further into a garment you got, the less of the instrument you
   could see, which is the reverse of what a keyed plate is for: the legend
   exists to be read against the subject, not after it.

   Above phone widths the shell holds the viewport. Head and colophon are fixed
   rows and the only thing that moves is the pane being worked in. A phone has
   no room for three panes and keeps the document scroll. */
@media (min-width: 721px) {
  body.plate-world {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;
    height: 100dvh;
    overflow: hidden;
  }
  /* `margin: 0 auto` on a grid item turns off stretch, so both of these have
     to be told to fill the row or they shrink to their own content. */
  .pl-runhead,
  .pl-sheet { width: 100%; }
  .pl-sheet { min-height: 0; overflow-y: auto; }
}

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

a.pl-skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--plate); color: var(--line); padding: var(--s3) var(--s4);
  border: 1px solid var(--ochre);
}
a.pl-skip:focus { left: var(--s4); top: var(--s4); }

/* --- focus is never removed --------------------------------------------- */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--ochre);
  outline-offset: 2px;
}

/* ===========================================================================
   1. RUNNING HEAD — the atlas page, not an app chrome bar.
   =========================================================================== */

.pl-runhead {
  display: flex; align-items: baseline; gap: var(--s4);
  max-width: 1560px; margin: 0 auto;
  padding: var(--s4) var(--s5) var(--s2);
  border-bottom: 1px solid var(--rule-firm);
}
.pl-runhead__atlas {
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line-2);
}
.pl-runhead__subject {
  font-family: var(--f-plate);
  font-style: italic;
  font-size: var(--fs-cap);
  color: var(--line);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pl-runhead__spacer { flex: 1; }
.pl-runhead__fig {
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line-2);
  white-space: nowrap;
}
.pl-runhead nav { display: flex; gap: var(--s3); align-items: baseline; }

/* ===========================================================================
   2. PLATE — the mounted field, inside its platemark.
   =========================================================================== */

.pl-sheet {
  max-width: 1560px;
  margin: 0 auto;
  padding: var(--s5) var(--s5) var(--s7);
}

.pl-plate {
  position: relative;
  background: var(--plate);
  border: 1px solid var(--rule-firm);
  padding: var(--s5);
}
/* the platemark: the impression the copper plate leaves in the sheet */
.pl-plate::before {
  content: "";
  position: absolute; inset: 5px;
  border: 1px solid var(--rule-hair);
  pointer-events: none;
}
.pl-plate > * { position: relative; }

.pl-plate--recess { background: var(--plate-recess); }
.pl-plate--flush  { padding: 0; }
.pl-plate--flush::before { inset: 4px; }

/* plate number, set into the top-left of the field like an engraver's mark */
.pl-fig {
  display: block;
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line-2);
  margin-bottom: var(--s2);
}

.pl-specimen {
  margin: 0 0 var(--s2);
  font-family: var(--f-plate);
  font-weight: 600;
  font-size: var(--fs-title);
  line-height: 1.15;
  letter-spacing: -0.012em;
  color: var(--line);
  text-wrap: balance;
}
.pl-specimen em { font-weight: 400; font-style: italic; color: var(--line-2); }

/* the caption: what the specimen is, in its own terms */
.pl-caption {
  max-width: var(--prose);
  margin: 0;
  font-style: italic;
  font-size: var(--fs-cap);
  color: var(--line-2);
}

/* ===========================================================================
   3. KEYS AND LEGEND — the load-bearing pair.
   =========================================================================== */

/* a lettered key mark, placed on the subject */
.pl-key {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.5em; height: 1.5em; padding: 0 0.3em;
  font-family: var(--f-legend);
  font-size: var(--fs-key);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--line);
  border: 1px solid var(--rule-firm);
  background: var(--plate-recess);
  vertical-align: baseline;
}
.pl-key--ochre    { color: var(--ochre);    border-color: var(--ochre); }
.pl-key--carmine  { color: var(--carmine);  border-color: var(--carmine); }
.pl-key--terre    { color: var(--terre);    border-color: var(--terre); }
.pl-key--prussian { color: var(--prussian); border-color: var(--prussian); }

/* the legend block: key -> name -> state, in fixed columns */
.pl-legend {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-meta);
}
.pl-legend caption {
  text-align: left;
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line-2);
  padding-bottom: var(--s2);
}
.pl-legend th {
  text-align: left; font-weight: 400;
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line-2);
  border-bottom: 1px solid var(--rule-firm);
  padding: 0 var(--s3) var(--s1) 0;
}
.pl-legend td {
  padding: var(--s1) var(--s3) var(--s1) 0;
  border-bottom: 1px solid var(--rule-hair);
  color: var(--line);
  vertical-align: baseline;
}
.pl-legend tr:last-child td { border-bottom: 0; }
.pl-legend td.pl-num { font-family: var(--f-data); text-align: right; }
.pl-legend td.tl-state-cell { width: 1%; white-space: nowrap; }

/* a state word carrying its wash. Colour is never the only signal. */
.pl-state {
  display: inline-flex; align-items: baseline; gap: 0.5ch;
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  white-space: nowrap;
}
.pl-state::before {
  content: ""; width: 7px; height: 7px; flex: none;
  transform: translateY(-1px);
  background: currentColor;
}
.pl-state--set       { color: var(--line); }
.pl-state--inherited { color: var(--ochre); }
.pl-state--attention { color: var(--carmine); }
.pl-state--committed { color: var(--terre); }
.pl-state--reference { color: var(--prussian); }

/* ===========================================================================
   4. ENGRAVED LEGEND LABELS AND FILL-IN LINES.
   =========================================================================== */

.pl-label,
.pl-field > label,
.pl-field > .pl-label {
  display: block;
  margin: 0 0 var(--s1);
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  font-weight: 400;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line-2);
}

.pl-field { margin: 0 0 var(--s4); min-width: 0; }
.pl-field__note {
  margin: var(--s1) 0 0;
  font-size: var(--fs-meta);
  font-style: italic;
  color: var(--line-2);
  max-width: var(--prose);
}

/* the ruled fill-in line: a plate form is ruled, not boxed */
.pl-input,
.pl-field input[type="text"],
.pl-field input[type="number"],
.pl-field input[type="search"],
.pl-field select {
  width: 100%;
  min-height: 34px;
  padding: var(--s1) var(--s2) var(--s1) 0;
  color: var(--line);
  font: 400 var(--fs)/1.4 var(--f-plate);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-firm);
  border-radius: 0;
  outline: none;
  transition: border-color 120ms var(--ease), background-color 120ms var(--ease);
}
.pl-textarea,
.pl-field textarea {
  width: 100%;
  min-height: 88px;
  padding: var(--s2);
  color: var(--line);
  font: 400 var(--fs)/1.5 var(--f-plate);
  background: var(--plate-recess);
  border: 1px solid var(--rule);
  border-radius: 0;
  outline: none;
  resize: vertical;
  transition: border-color 120ms var(--ease);
}
.pl-input:hover, .pl-textarea:hover,
.pl-field :is(input, select, textarea):hover { border-color: var(--rule-firm); }

.pl-input:focus, .pl-textarea:focus,
.pl-field :is(input, select, textarea):focus {
  border-color: var(--ochre);
  background-color: rgba(217, 164, 65, 0.05);
}
.pl-input::placeholder, .pl-textarea::placeholder,
.pl-field :is(input, textarea)::placeholder { color: var(--line-3); font-style: italic; }

.pl-field select {
  appearance: none;
  padding-right: var(--s5);
  background-image: linear-gradient(45deg, transparent 50%, var(--line-2) 50%),
                    linear-gradient(135deg, var(--line-2) 50%, transparent 50%);
  background-position: right 12px center, right 7px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}
.pl-field select option { background: var(--plate); color: var(--line); }

:is(input, select, textarea):disabled { opacity: 0.45; cursor: not-allowed; }

/* a checkbox / radio row reads as a ticked legend entry */
.pl-tick {
  display: flex; align-items: baseline; gap: var(--s2);
  margin: var(--s3) 0 0;
  color: var(--line);
  font-size: var(--fs);
  cursor: pointer;
}
.pl-tick input { accent-color: var(--ochre); flex: none; }

/* ===========================================================================
   5. CONTROLS.
   =========================================================================== */

.pl-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.6ch;
  min-height: 34px;
  padding: var(--s2) var(--s4);
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--line);
  background: transparent;
  border: 1px solid var(--rule-firm);
  border-radius: 0;
  cursor: pointer;
  transition: border-color 120ms var(--ease), background-color 120ms var(--ease), color 120ms var(--ease);
}
.pl-btn:hover:not(:disabled) { border-color: var(--line-2); background: var(--plate-hi); }
.pl-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.pl-btn--primary {
  color: var(--board);
  background: var(--ochre);
  border-color: var(--ochre);
}
.pl-btn--primary:hover:not(:disabled) { background: #e6b45c; border-color: #e6b45c; color: var(--board); }

.pl-btn--quiet { border-color: transparent; color: var(--line-2); padding-inline: var(--s2); }
.pl-btn--quiet:hover:not(:disabled) { color: var(--line); border-color: var(--rule); background: transparent; }

.pl-btn--danger { color: var(--carmine); border-color: var(--carmine-fill); }
.pl-btn--danger:hover:not(:disabled) { background: var(--carmine-fill); color: var(--line); border-color: var(--carmine); }

.pl-btn--mini { min-height: 26px; padding: var(--s1) var(--s2); font-size: 10px; }

/* an irreversible action carries a hatched guard it must be lifted past */
.pl-guard {
  /* Wraps because the rail is narrower than the guard's own row: legend above,
     field and control below. Nothing wraps in a full-width container. */
  display: inline-flex; align-items: center; flex-wrap: wrap; gap: var(--s2);
  max-width: 100%;
  padding: var(--s1) var(--s1) var(--s1) var(--s3);
  border: 1px solid var(--carmine-fill);
  background: repeating-linear-gradient(
    -45deg, transparent 0 5px, rgba(142, 47, 40, 0.30) 5px 10px);
}
.pl-guard__legend {
  font-family: var(--f-legend);
  font-size: 10px;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--carmine);
}

a { color: var(--prussian); text-decoration: none; border-bottom: 1px solid transparent; }
a:hover { border-bottom-color: currentColor; }

/* ===========================================================================
   6. THE PREVIEW WELL — where real game text is shown back.
      Monospace here is the payload's own metric, not a costume.
   =========================================================================== */

.pl-well {
  background: var(--plate-recess);
  border: 1px solid var(--rule);
  padding: var(--s3);
  font: 400 var(--fs-meta)/1.6 var(--f-data);
  color: var(--line);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.pl-well:empty::before { content: "—"; color: var(--line-3); }

/* ===========================================================================
   7. TABULAR BACK MATTER.
   =========================================================================== */

.pl-table { width: 100%; border-collapse: collapse; font-size: var(--fs-meta); }
.pl-table th {
  text-align: left; font-weight: 400;
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line-2);
  border-bottom: 1px solid var(--rule-firm);
  padding: 0 var(--s3) var(--s1) 0;
  white-space: nowrap;
}
.pl-table td {
  padding: var(--s2) var(--s3) var(--s2) 0;
  border-bottom: 1px solid var(--rule-hair);
  color: var(--line);
  vertical-align: top;
}
.pl-table tbody tr:hover td { background: var(--plate-hi); }
.pl-table .pl-num { font-family: var(--f-data); text-align: right; }

/* ===========================================================================
   8. NOTICES.
   =========================================================================== */

.pl-notice {
  display: flex; gap: var(--s2); align-items: baseline;
  padding: var(--s2) var(--s3);
  border: 1px solid var(--rule);
  border-left-width: 1px;
  background: var(--plate-recess);
  font-size: var(--fs-meta);
  color: var(--line);
}
.pl-notice__legend {
  flex: none;
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
}
.pl-notice--ok    { border-color: var(--terre-fill); }
.pl-notice--ok    .pl-notice__legend { color: var(--terre); }
.pl-notice--warn  { border-color: var(--carmine-fill); }
.pl-notice--warn  .pl-notice__legend { color: var(--carmine); }
.pl-notice--live  { border-color: var(--ochre-fill); }
.pl-notice--live  .pl-notice__legend { color: var(--ochre); }

/* the empty state: an unlettered plate */
.pl-empty {
  display: grid; place-items: center; gap: var(--s2);
  min-height: 220px; padding: var(--s5);
  text-align: center;
  border: 1px dashed var(--rule);
  color: var(--line-2);
}
.pl-empty strong {
  font-family: var(--f-plate); font-style: italic; font-weight: 400;
  font-size: var(--fs-cap); color: var(--line);
}
.pl-empty p { margin: 0; max-width: 44ch; font-size: var(--fs-meta); }

/* ===========================================================================
   8b. THE KEYED FIGURE — the subject drawn once, its regions selectable.
       Pointer affordance only; the legend rows carry the keyboard.
   =========================================================================== */

.pl-figure {
  display: flex; gap: var(--s5); justify-content: center; align-items: flex-start;
  padding: var(--s3) 0;
}
.pl-figure__panel { margin: 0; text-align: center; flex: 1 1 0; min-width: 0; }
.pl-figure__svg { width: 100%; max-width: 168px; height: auto; display: block; margin: 0 auto; }
.pl-figure figcaption {
  margin-top: var(--s2);
  font-family: var(--f-plate); font-style: italic;
  font-size: var(--fs-meta); color: var(--line-2);
}

/* The sourced silhouette, drawn as line over the washes. The source ships
   these paths filled white; the CSS fill wins over that presentation
   attribute, which is what turns a solid silhouette into an engraved figure. */
.pl-fig-art path {
  fill: none;
  stroke: var(--line-2);
  stroke-width: 1.1;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

/* Regions are fills only, clipped to the body: no outlines of their own, so
   the figure reads as one drawing rather than a pile of shapes.

   The whole set lives in one isolated group. `opacity` on a group composites
   its children at full strength first and fades the result once, so two
   regions of the same garment may overlap at their shared boundary without
   the overlap reading darker. That overlap is what lets the boundaries be
   anatomical curves with no hairline seam between them; per-shape
   `fill-opacity` cannot do it, because there the overlap doubles. */
.pl-fig-washes { opacity: 0.62; }

.pl-fig-region { cursor: pointer; }
.pl-fig-region :is(path, ellipse, rect) {
  fill: transparent; stroke: none;
  transition: fill 140ms var(--ease);
}
.pl-fig-region:hover :is(path, ellipse, rect) { fill: rgba(232, 228, 216, 0.15); }

.pl-fig-region.is-covered :is(path, ellipse, rect) { fill: var(--carmine-fill); }
.pl-fig-region.is-covered:hover :is(path, ellipse, rect) { fill: #b3453a; }

/* the tail hangs outside the silhouette, so the drawing gives it a contour */
.pl-fig-art__tail { stroke-width: 1.25; }

/* ===========================================================================
   9. ICONS — authored, one hairline weight. No glyph substitutes.
   =========================================================================== */

.pl-i { width: 1em; height: 1em; flex: none; display: inline-block; vertical-align: -0.125em; }
.pl-i path, .pl-i line, .pl-i circle, .pl-i polyline, .pl-i rect {
  fill: none; stroke: currentColor; stroke-width: 1.25;
  stroke-linecap: square; stroke-linejoin: miter;
}

/* ===========================================================================
   10. MOTION — one authored moment: the wash settling into register.

   Colour plates were pulled one stone at a time and misregistration was the
   era's signature defect. Wash layers arrive a hair off register and settle.
   The offset never carries meaning, so reduced motion loses nothing.
   =========================================================================== */

@keyframes pl-register {
  from { transform: translate(1.5px, -1px); opacity: 0.55; }
  to   { transform: none; opacity: 1; }
}
.pl-register { animation: pl-register 220ms var(--ease) both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ===========================================================================
   11. LAYOUT HELPERS.
   =========================================================================== */

.pl-cols { display: grid; gap: var(--s5); align-items: start; }
.pl-cols--subject-legend { grid-template-columns: minmax(0, 1fr) minmax(300px, 400px); }
.pl-cols--halves { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pl-row { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: flex-end; }
.pl-row > * { flex: 1 1 180px; min-width: 0; }
.pl-row > .pl-shrink { flex: 0 0 auto; }
.pl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--s2) var(--s4); }
.pl-stack { display: grid; gap: var(--s4); }
.pl-sticky { position: sticky; top: var(--s4); }

/* The shared authoring bench: index, active work, exact proof. It is one
   engraved working surface, not a row of independent dashboard cards. */
.pl-bench {
  display: grid;
  /* Minimums are what decide whether a screen gets the bench at all, and the
     old ones needed 1,110px before the three panes would sit down together.
     A 1280 laptop at any display scaling is under that, so the surface most
     people actually opened was the phone stack: index run along the top,
     everything else in one column. These fit three panes from 900px. */
  grid-template-columns: minmax(150px, 210px) minmax(360px, 1fr) minmax(280px, 460px);
  gap: var(--s4);
  align-items: start;
}
.pl-bench__index,
.pl-bench__proof { position: sticky; top: var(--s3); }
.pl-bench__editor { min-width: 0; }

/* In the fixed shell each pane carries its own scroll, so sticky has nothing
   left to do: the pane is already the height of the frame. */
@media (min-width: 721px) {
  .pl-bench { height: 100%; min-height: 0; align-items: stretch; }
  .pl-bench__index,
  .pl-bench__editor,
  .pl-bench__proof {
    position: static;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* Between phone and 900 there is room for two columns, not three. The proof
   takes the lower half of the working column rather than stacking below it and
   pushing the editor's own length onto the page again. */
@media (min-width: 721px) and (max-width: 899px) {
  .pl-bench {
    grid-template-columns: minmax(140px, 190px) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1.7fr) minmax(0, 1fr);
  }
  .pl-bench__index { grid-column: 1; grid-row: 1 / -1; }
  .pl-bench__editor { grid-column: 2; grid-row: 1; }
  .pl-bench__proof { grid-column: 2; grid-row: 2; }
}
.pl-bench__proof { display: grid; gap: var(--s3); }
.pl-bench__index {
  border-block: 1px solid var(--rule-firm);
  background: color-mix(in srgb, var(--plate) 30%, transparent);
}
.pl-bench__label {
  display: block;
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--rule);
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line-2);
}
.pl-bench__nav { display: grid; }
.pl-bench__link {
  appearance: none;
  display: grid;
  grid-template-columns: 2.25rem minmax(0, 1fr);
  gap: var(--s2);
  align-items: baseline;
  width: 100%;
  padding: var(--s2) var(--s3);
  border: 0;
  border-bottom: 1px solid var(--rule);
  background: transparent;
  color: var(--line-2);
  text-align: left;
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  cursor: pointer;
}
.pl-bench__link:last-child { border-bottom: 0; }
.pl-bench__link:hover,
.pl-bench__link:focus-visible,
.pl-bench__link[aria-selected="true"],
.pl-bench__link[aria-current="true"] { color: var(--line); background: var(--ochre-faint); }
.pl-bench__link[aria-selected="true"],
.pl-bench__link[aria-current="true"] { box-shadow: inset 2px 0 0 var(--ochre); }
.pl-bench__key {
  font-family: var(--f-plate);
  font-size: var(--fs-cap);
  font-style: italic;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ochre);
}
.pl-bench .pl-plate { padding: var(--s4); }
.pl-bench .pl-section { margin-bottom: var(--s5); }
.pl-bench .pl-field { margin-bottom: var(--s3); }
.pl-bench .pl-rule { margin: var(--s4) 0; }
/* The counter index. An editor long enough to scroll has to say at its head
   which counters it holds and which one you are standing at — the same service
   the plate index does on tailoring, for a surface whose rail is already spent
   on a roster. It sticks to the top of its own pane, not the page. */
.pl-counters {
  position: sticky; top: 0; z-index: 5;
  display: flex; flex-wrap: wrap;
  margin: 0 0 var(--s4);
  padding: var(--s1) 0;
  background: var(--board);
  border-bottom: 1px solid var(--rule-firm);
}
.pl-counters a {
  display: flex; align-items: center; gap: var(--s2);
  min-height: 28px;
  padding: var(--s1) var(--s3);
  border-right: 1px solid var(--rule);
  color: var(--line-2); text-decoration: none;
  font-family: var(--f-legend); font-size: var(--fs-legend);
  letter-spacing: var(--track); text-transform: uppercase;
  transition: color 120ms var(--ease), background 120ms var(--ease);
}
.pl-counters a:last-child { border-right: 0; }
.pl-counters a:hover { color: var(--line); background: var(--ochre-faint); }
.pl-counters a[aria-current="true"] {
  color: var(--line);
  box-shadow: inset 0 -2px 0 var(--ochre);
}
.pl-counters__key {
  font-family: var(--f-plate); font-style: italic; font-size: var(--fs-cap);
  letter-spacing: 0; text-transform: none; color: var(--ochre);
}
.pl-bench__editor .pl-section { scroll-margin-top: 3.25rem; }

.pl-proof-pair { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s3); }
.pl-session-note { margin-bottom: var(--s3); }

.pl-rule { height: 0; border: 0; border-top: 1px solid var(--rule); margin: var(--s5) 0; }

/* a section inside a plate: engraved head, then content */
.pl-section { margin: 0 0 var(--s6); }
.pl-section:last-child { margin-bottom: 0; }
.pl-section__head {
  display: flex; align-items: baseline; gap: var(--s2);
  margin: 0 0 var(--s3);
  padding-bottom: var(--s1);
  border-bottom: 1px solid var(--rule-firm);
}
.pl-section__head h2, .pl-section__head h3 {
  margin: 0;
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line);
}
.pl-section__head .pl-key { margin-right: var(--s1); }
.pl-section__note {
  margin: calc(-1 * var(--s2)) 0 var(--s3);
  font-style: italic; font-size: var(--fs-meta); color: var(--line-2);
  max-width: var(--prose);
}

/* ===========================================================================
   12. COLOPHON — the foot of the sheet, where the actions live.
   =========================================================================== */

.pl-colophon {
  position: sticky; bottom: 0; z-index: 20;
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s5);
  background: color-mix(in srgb, var(--board) 94%, transparent);
  border-top: 1px solid var(--rule-firm);
  backdrop-filter: blur(6px);
}
.pl-colophon__legend {
  font-family: var(--f-legend);
  font-size: var(--fs-legend);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--line-2);
  flex: none;
}
.pl-colophon__msg { flex: 1; min-width: 80px; font-size: var(--fs-meta); color: var(--line-2); }
.pl-colophon__msg.is-ok   { color: var(--terre); }
.pl-colophon__msg.is-bad  { color: var(--carmine); white-space: pre-wrap; }

/* ===========================================================================
   13. RESPONSIVE — desktop-first, readable on a phone (PRODUCT.md).
   =========================================================================== */

@media (max-width: 1100px) {
  .pl-cols--subject-legend { grid-template-columns: minmax(0, 1fr); }
  .pl-sticky { position: static; }
}
@media (min-width: 1200px) {
  .pl-proof-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  :root { --fs-title: 22px; --s5: 16px; --s6: 26px; --s7: 40px; }
  .pl-sheet { padding: var(--s4) var(--s3) var(--s7); }
  .pl-runhead { flex-wrap: wrap; gap: var(--s2); padding: var(--s3) var(--s3) var(--s2); }
  .pl-runhead__spacer { flex-basis: 100%; height: 0; }
  .pl-plate { padding: var(--s4) var(--s3); }
  .pl-cols--halves { grid-template-columns: minmax(0, 1fr); }
  .pl-grid { grid-template-columns: minmax(0, 1fr); }
  .pl-bench { grid-template-columns: minmax(0, 1fr); gap: var(--s3); }
  .pl-bench__index,
  .pl-bench__proof { position: static; grid-column: auto; }
  .pl-bench__nav { display: flex; overflow-x: auto; }
  .pl-bench__link { grid-template-columns: auto auto; width: auto; min-width: max-content; border-bottom: 0; border-right: 1px solid var(--rule); }
  .pl-bench__link[aria-selected="true"],
  .pl-bench__link[aria-current="true"] { box-shadow: inset 0 -2px 0 var(--ochre); }
  .pl-colophon { flex-wrap: wrap; padding: var(--s2) var(--s3); }
  .pl-colophon__legend { display: none; }
  .pl-colophon__msg { flex-basis: 100%; order: -1; }
  .pl-colophon .pl-btn { flex: 1; }
  /* touch targets */
  .pl-btn { min-height: 44px; }
  .pl-field :is(input, select) { min-height: 44px; }
}
