/* ===========================================================================
   DIRECTION A — THE READING ROOM
   Warm, document-first, unhurried. Paper and ink; one vermilion accent carries
   every state on the page. Typography is the whole design: a bookish serif for
   the human sentence, a mono for the machine record beneath it.

   THREE SURFACES, ONE MEANING EACH. Every ground here is one of three weights
   of the same warm stock, and each weight means exactly one thing:
     --paper       the desk and every heading  (masthead, slate, section head
                   bands, the manuscript header, the pinned verdict bar)
     --paper-read  THE SHEET, the lightest and calmest ground on the page --
                   the manuscript prose sits here and nothing tints it
     --paper-sunk  THE MACHINE REGISTER -- every machine line, the rubric
                   well, the tool-name column, the status bar
   So a fact is one object on two stocks, and a section announces itself by
   the band its heading sits on. No borders, no radius, no shadow: the tone
   carries it, and every band bleeds past the text into the gutter so it has
   no vertical edge to be a card by.

   pairs: --ink/--paper, --ink/--paper-read, --ink/--paper-sunk, --ink/--paper-lift,
          --ink-2/--paper, --ink-2/--paper-read, --ink-2/--paper-sunk, --ink-2/--paper-lift,
          --ink-3/--paper, --ink-3/--paper-read, --ink-3/--paper-sunk, --ink-3/--paper-lift,
          --accent/--paper, --accent/--paper-read, --accent/--paper-sunk, --accent/--paper-lift,
          --accent/--accent-wash, --ink/--accent-wash, --ink-2/--accent-wash,
          --paper-read/--accent,
          --rule-2/--paper ui, --rule-2/--paper-read ui, --rule-2/--paper-sunk ui,
          --accent-line/--paper-read ui,
          --accent/--paper ui, --accent/--paper-read ui, --accent/--paper-sunk ui
   =========================================================================== */

:root{
  /* --- warm ground: three sheets of paper, not three greys ---------------- */
  --paper:      #F2ECDF;   /* the desk — slate column, rail, chrome           */
  --paper-read: #FBF7EF;   /* the sheet you read — manuscript column          */
  --paper-sunk: #E9E1D0;   /* recessed: rubric well, rail head, stubs         */
  --paper-lift: #F7F1E4;   /* the selected row, quietly warmer than the desk  */
  --paper-fold: #EFE7D7;   /* THE FOLD along the frame — and only that. Every
                              ground the human alone acts on: the rubric well
                              they retune, the bar they decide from.           */

  /* --- ink ---------------------------------------------------------------- */
  --ink:    #211E19;       /* the human sentence                              */
  --ink-2:  #4A4238;       /* supporting prose, secondary sentences           */
  --ink-3:  #695F51;       /* THE MACHINE REGISTER — deliberately quieter.
                              Two steps darker than the inherited #6B6153: that
                              value measured 4.666:1 on --paper-sunk, which is
                              where every machine line on this page lives, and
                              the floor is 4.67. Same tone, now 4.810:1.        */

  /* --- hairlines (no boxes; rules only where a rule means something) ------ */
  --rule:   #DDD3BF;
  --rule-2: #8A7A5C;      /* every real control border: 3.2:1 min on all 3 grounds */

  /* --- the one accent. Every state on this page is this colour. ----------- */
  --accent:      #973112;  /* refusal, human-only, the cut, integrity marks   */
  --accent-line: #C87A55;  /* accent hairline, low-emphasis                   */
  --accent-wash: #F4DDD1;  /* payload ground, human-only key ground           */
  --backdrop:    rgba(33,30,25,.42);  /* modal veil, warm not neutral         */

  /* --- type ---------------------------------------------------------------- */
  /* every full-bleed band bleeds by exactly its container's gutter, so the
     text left edge never moves. Each container sets its own. */
  --gut: 14px;

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, "Times New Roman", serif;
  --mono:  ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  /* --- motion (05-ui-spec §4.4) ------------------------------------------- */
  --flip-dur:  260ms;
  --flip-ease: cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{ box-sizing:border-box; }
[hidden]{ display:none !important; }
/* the frame is fixed at 1280x800, so no element gets a margin it did not ask for */
h1,h2,h3,p,ul,ol,figure,blockquote,table{ margin:0; }

html,body{ height:100%; }
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--serif);
  font-size:16px;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  overflow:hidden;               /* no page scroll in either axis at 1280x800 */
}

/* the machine register: one class, used everywhere the contract is named */
.m{
  font-family:var(--mono);
  font-size:12.5px;
  line-height:1.55;
  letter-spacing:.01em;
  color:var(--ink-3);
  font-variant-ligatures:none;
}
.m b{ font-weight:600; color:var(--ink-2); }
.m-cap{
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ink-3);
}
.said{ font-size:17px; line-height:1.42; color:var(--ink); margin:0; }
.said-sm{ font-size:14.5px; line-height:1.45; color:var(--ink-2); margin:0; }

/* the hatch is the texture of a deliberate absence — never a loading state */
.hatch{
  background-image:repeating-linear-gradient(135deg,
    var(--rule-2) 0 1px, transparent 1px 4px);
  background-color:var(--paper-sunk);
}

button{ font:inherit; color:inherit; background:none; border:0; padding:0; cursor:pointer; }
:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:1px; }
::selection{ background:var(--accent-wash); color:var(--ink); }

/* ============================== FRAME ==================================== */
.app{
  height:100dvh;
  display:grid;
  grid-template-rows:46px minmax(0,1fr) 26px;
}

/* ---------------------------- masthead ----------------------------------- */
#masthead{
  display:flex; align-items:center; gap:14px;
  padding:0 20px;
  border-bottom:1px solid var(--rule);
  background:var(--paper);
}
.wordmark{ font-size:19px; letter-spacing:.005em; }
.wordmark b{ font-weight:600; }
.wordmark span{ color:var(--ink-3); font-size:14px; }
#fiction-banner{
  margin-left:auto; margin-right:auto;
  font-size:13px; color:var(--ink-2);
  border-bottom:1px solid var(--accent-line);
  padding-bottom:1px;
}
.mast-act{
  font-size:14px; color:var(--ink-2);
  border-bottom:1px solid var(--rule-2); padding-bottom:1px;
}
.mast-act:hover{ color:var(--accent); border-bottom-color:var(--accent); }

/* ------------------------------ room ------------------------------------- */
#room{
  display:grid;
  grid-template-columns:328px minmax(0,1fr);
  min-height:0;
}
#room > *{ min-height:0; min-width:0; }

/* ============================== SLATE ==================================== */
.sr-only{ position:absolute; top:0; left:0; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }

#slate{
  position:relative;
  border-right:1px solid var(--rule);
  display:grid;
  grid-template-columns:minmax(0,1fr);      /* or min-content blows the track */
  grid-template-rows:auto minmax(0,1fr);
  background:var(--paper);
}

/* the rubric well is retuned by the human and by nobody else, so it sits on
   the fold — the same ground the decision bar sits on, and the only two
   grounds on this page the assistant has no tool to touch */
#rubric{ padding:12px 22px 11px; border-bottom:1px solid var(--rule-2); background:var(--paper-fold); }
.rubric-head h2{ font-size:15.5px; font-weight:600; }
.rubric-sub{ display:flex; align-items:center; gap:8px; margin-bottom:7px; }
.crit{ display:grid; grid-template-columns:60px 1fr 22px; align-items:center; gap:8px; height:19px; }
.crit label{ font-family:var(--mono); font-size:11.5px; letter-spacing:.06em; color:var(--ink-2); text-transform:uppercase; }
.crit output{ font-family:var(--mono); font-size:12.5px; text-align:right; color:var(--ink-2); }
.crit output.is-hot{ color:var(--accent); font-weight:600; }

input[type=range]{
  -webkit-appearance:none; appearance:none;
  width:100%; height:14px; background:none; cursor:ew-resize; margin:0;
}
input[type=range]::-webkit-slider-runnable-track{
  height:3px; border-radius:0;
  background:linear-gradient(to right, var(--accent) 0 var(--fill), var(--rule-2) var(--fill) 100%);
}
input[type=range]::-moz-range-track{
  height:3px; background:linear-gradient(to right, var(--accent) 0 var(--fill), var(--rule-2) var(--fill) 100%);
}
input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:3px; height:15px; margin-top:-6px;
  background:var(--accent); border:0; border-radius:0;
}
input[type=range]::-moz-range-thumb{
  width:3px; height:15px; background:var(--accent); border:0; border-radius:0;
}

.rubric-foot{ display:flex; align-items:center; gap:7px; margin-top:9px; flex-wrap:wrap; }
.step{
  width:20px; height:20px; line-height:18px; text-align:center;
  font-family:var(--mono); font-size:13px; color:var(--ink-2);
  border:1px solid var(--rule-2);
}
.step:hover{ border-color:var(--accent); color:var(--accent); }
[data-bind="accept-slots"]{ font-family:var(--mono); font-size:13px; font-weight:600; min-width:9px; text-align:center; }
.reset-link{ margin-left:auto; font-family:var(--mono); font-size:10.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3); border-bottom:1px solid var(--rule-2); }
.reset-link:hover{ color:var(--accent); border-bottom-color:var(--accent); }

#slate-scroll{ overflow-y:auto; overflow-x:hidden; padding:6px 0 14px; }
#slate-list{ list-style:none; margin:0; padding:0; }

/* a slate row is not a card. No box, no fill, no shadow — rank, title, score. */
.row{
  position:relative; width:100%; text-align:left;
  display:grid; grid-template-columns:24px minmax(0,1fr) 42px;
  align-items:baseline; column-gap:10px;
  padding:6px 22px 6px 20px;
  border-left:2px solid transparent;
}
.row:hover{ background:var(--paper-lift); }
.row.is-sel{ border-left-color:var(--accent); background:var(--paper-lift); }
.row__rank{ font-family:var(--mono); font-size:11.5px; color:var(--ink-3); }
.row__title{
  font-size:14.5px; line-height:1.32; color:var(--ink);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.row__score{ font-family:var(--mono); font-size:12.5px; text-align:right; color:var(--ink-2); font-variant-numeric:tabular-nums; }
.row.is-below .row__title{ color:var(--ink-3); }
.row.is-below .row__score{ color:var(--ink-3); }
.row__marks{ grid-column:2 / 4; display:flex; gap:10px; margin-top:1px; }
.mark{ font-family:var(--mono); font-size:10px; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-3); white-space:nowrap; }
.mark.is-accent{ color:var(--accent); }
.row.crossed-up{ animation:crossUp 900ms var(--flip-ease); }
.row.crossed-down{ animation:crossDown 900ms var(--flip-ease); }
@keyframes crossUp{ 0%,60%{ background:var(--accent-wash); } 100%{ background:transparent; } }
@keyframes crossDown{ 0%,60%{ background:var(--paper-sunk); } 100%{ background:transparent; } }

/* the cut line is the one rule on this page that is allowed to be loud */
.cut{ list-style:none; margin:8px 0 7px; padding:0 22px 0 20px; }
.cut-inner{ display:flex; align-items:center; gap:10px; }
.cut-rule{ flex:1; height:0; border-top:1.5px solid var(--accent); }
.cut-label{
  font-family:var(--mono); font-size:10.5px; font-weight:700; letter-spacing:.16em;
  text-transform:uppercase; color:var(--accent); white-space:nowrap;
}
.cut-tie{ padding:5px 22px 0 20px; }
.cut-tie p:not(.m){ font-size:13.5px; line-height:1.34; color:var(--ink-2); }
.cut-tie .m{
  display:block; background:var(--paper-sunk);
  margin:3px -22px 0 -20px; padding:3px 22px 4px 20px;
}

/* ================== READING COLUMN - one document ======================= */
#reading{
  background:var(--paper-read);
  display:grid; grid-template-columns:minmax(0,1fr);
  grid-template-rows:auto auto minmax(0,1fr) auto;
}

/* --- THE COUPLING SYSTEM -----------------------------------------------
   Every fact on this page is one block of two lines on two stocks. The human
   sentence on the sheet, then its machine line directly beneath it on the
   same left edge, sunk onto a heavier stock. 26px of air before the next
   block. The pair is bound by that shared left edge; the tint extends the
   binding rather than replacing it, and it runs out past the text into the
   gutter on both sides, so the band has no vertical edge and cannot read as
   a box. The only other ornament is the accent bar that marks a refusal,
   and it hangs in the margin so the shared left edge never moves.       */
.pair{ margin:0 0 26px; max-width:none; }
.pair:last-child{ margin-bottom:0; }
.say{ font-size:17.5px; line-height:1.44; color:var(--ink); font-weight:400; max-width:88ch; }
/* the machine register gets its own stock: one weight down from the sheet,
   run out to both gutters. Same left edge, different paper.             */
.sub{
  display:block;
  font-family:var(--mono); font-size:12.5px; line-height:1.55; letter-spacing:.01em;
  color:var(--ink-3);
  background:var(--paper-sunk);
  margin:5px calc(-1 * var(--gut)) 0;
  padding:5px var(--gut) 6px;
}
.sub b{ color:var(--ink-2); font-weight:600; }
.sub .hot{ color:var(--accent); font-weight:600; }
h2.say{ font-size:22px; }
/* --- SECTION HEADS -------------------------------------------------------
   A section announces itself with a band of desk stock running the whole
   width of the sheet, carrying its own two-line pair. This is the only thing
   dividing one section from the next, and it is why the prose below can stay
   the lightest, quietest ground on the page.                            */
.pair-h{
  background:var(--paper);
  max-width:none;
  margin:0 calc(-1 * var(--gut)) 18px;
  padding:11px var(--gut) 10px;
}
.doc-sec{ margin-bottom:30px; }
.doc-sec:last-child{ margin-bottom:0; }
.pair.is-refused{ border-left:2px solid var(--accent); padding-left:16px; margin-left:-18px; }
/* a refusal's machine band stops at the accent bar rather than covering it */
.is-refused > .sub{ margin-left:-16px; padding-left:16px; }

/* --- THE STAMP ------------------------------------------------------------
   A refusal is the page doing its job, so it is marked the way a clerk marks
   a document that has been ruled on: struck ink, a little off-square, sitting
   in the line rather than in a coloured tray. No fill and no error red -- the
   paper shows through it, and it is the same vermilion that carries every
   other state on this page.                                              */
/* once you have decided, the refusal stops being a live state and becomes a
   line in the record -- so the stamp moves down onto the machine line. */
.sub .stamp{ vertical-align:-1px; margin-right:8px; }
.stamp{
  display:inline-block; vertical-align:1px;
  font-family:var(--mono); font-size:11px; font-weight:700; line-height:1.35;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent);
  border:2px solid var(--accent);
  padding:3px 8px 2px;
  margin:0 10px 1px 0;
  transform:rotate(-1.6deg);
  white-space:nowrap;
}
/* a spread, not a sidebar: two blocks of the same document, each still
   carrying its own sentence with its own machine line under it */
.duo{ --gut:14px; display:grid; grid-template-columns:1fr 1fr; gap:46px; margin-bottom:26px; }
.duo .doc-sec{ margin-bottom:0; }
.duo .pair{ max-width:none; margin-bottom:0; }
.duo #unblind-out{ margin-top:22px; }
/* In the two-up spread every band runs off its own OUTER edge of the sheet and
   stops in the gutter between the columns. Three edges, one of them bled away:
   a band, never a panel. */
.duo > .doc-sec > .pair-h{ margin-bottom:14px; padding-top:9px; padding-bottom:8px; }
.duo > .doc-sec:first-child .pair-h,
.duo > .doc-sec:first-child .sub{
  margin-left:-40px;  padding-left:40px;
  margin-right:-16px; padding-right:16px;
}
.duo > .doc-sec:last-child .pair-h,
.duo > .doc-sec:last-child .sub{
  margin-left:-16px;  padding-left:16px;
  margin-right:-40px; padding-right:40px;
}
/* a head band already carries the air below it */
.pair > .withheld:first-child,
.pair > .act-row:first-child{ margin-top:0; }

/* --- manuscript header ------------------------------------------------- */
#ms-head{ padding:11px 40px 9px; border-bottom:1px solid var(--rule); background:var(--paper); }
.ms-eyebrow{ display:flex; align-items:center; gap:12px; margin-bottom:5px; }
.chip-fiction{
  font-family:var(--mono); font-size:10px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--accent); border:1px solid var(--accent-line); padding:2px 6px;
}
.eyebrow-end{ margin-left:auto; display:flex; align-items:center; gap:12px; }
#ms-title{ font-size:25px; line-height:1.18; font-weight:400; letter-spacing:-.006em; max-width:58ch; }
#ms-meta{ font-size:13.5px; color:var(--ink-3); margin-top:4px; }

/* --- the quiet section nav: it scrolls, it never hides ----------------- */
#doc-nav{ display:flex; align-items:center; gap:22px; padding:9px 40px 8px; min-width:0; overflow:hidden;
  background:var(--paper); border-bottom:1px solid var(--rule); }
.head-row{ display:flex; align-items:baseline; gap:22px; }
.head-row .recv{ margin-left:auto; }
.navword{ font-size:14.5px; color:var(--ink-3); border-bottom:1.5px solid transparent; padding-bottom:3px; white-space:nowrap; }
.navword:hover{ color:var(--ink); }
.navword.is-here{ color:var(--ink); border-bottom-color:var(--accent); }
.recv{ display:flex; align-items:baseline; gap:11px; }
.recvword{ font-family:var(--mono); font-size:12px; color:var(--ink-3); border-bottom:1.5px solid transparent; padding-bottom:3px; white-space:nowrap; }
.recv-label{ font-family:var(--mono); font-size:10.5px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-3); }
.recvword[aria-pressed=true]{ color:var(--accent); border-bottom-color:var(--accent); }

#desk-body{ --gut:40px; overflow-y:auto; overflow-x:hidden; padding:16px 40px 34px; scroll-behavior:smooth; }

/* --- the withheld byline: absence, set as deliberately as a name ------- */
.withheld{ display:flex; flex-wrap:wrap; gap:9px 20px; margin-top:13px; }
.wf{ display:flex; align-items:center; gap:6px; }
.wf__name{ font-family:var(--mono); font-size:11.5px; color:var(--ink-2); }
.wf__void{ height:15px; width:var(--w); display:block; }
#id-revealed{ display:flex; flex-wrap:wrap; align-items:baseline; gap:5px 20px; margin-top:11px; }
.id-val{ font-size:16px; color:var(--ink); }
.act-row{ display:flex; align-items:center; gap:13px; margin-top:12px; }

/* --- ONLY YOU -------------------------------------------------------------
   This was a filled vermilion chip reading HUMAN ONLY beside a key glyph, and
   a cold reader took it for a lock: something disabled, something broken. It
   is the opposite — it marks the moves that are YOURS and that the assistant
   has no tool for. So it is set as an attribution rather than as a badge: no
   fill, no padlock, plain words, and the SAME filled square that means "you"
   in the masthead legend and on a decided queue row. Authority is quiet; a
   warning is loud, and this was reading as a warning.                       */
.only-you{
  display:inline-flex; align-items:center; gap:6px; white-space:nowrap;
  font-family:var(--mono); font-size:10.5px; letter-spacing:.11em; text-transform:uppercase;
  color:var(--accent);
  border-bottom:1px solid var(--accent); padding-bottom:1px;
}
.only-you svg{ width:8px; height:8px; fill:var(--accent); stroke:none; }
.act{ font-size:14.5px; color:var(--accent); border-bottom:1px solid var(--accent); padding-bottom:1px; }
.act:hover{ border-bottom-width:2px; }
.act[disabled]{ color:var(--ink-3); border-bottom-color:var(--rule-2); cursor:default; }

/* --- the manuscript itself: the hero of the page ---------------------- */
.prose{ max-width:68ch; }
.prose p:not(.sub){ margin:0 0 15px; font-size:16.5px; line-height:1.68; color:var(--ink); }
.prose p:last-child{ margin-bottom:0; }
.sec{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink-3); margin:0 0 8px; padding-bottom:5px; border-bottom:1px solid var(--rule);
  max-width:68ch;
}
.prose .q-ver{ border-bottom:1px solid var(--accent-line); }
.payload{
  display:block; background:var(--accent-wash); color:var(--ink);
  border-left:3px solid var(--accent); padding:10px 13px; margin:0 0 15px; max-width:68ch;
  font-family:var(--mono); font-size:12.5px; line-height:1.6;
}
.payload .m-cap{ display:block; color:var(--accent); margin-bottom:5px; }
.void{
  display:block; max-width:68ch; margin:0 0 15px;
  border:1px dashed var(--rule-2); padding:11px 14px;
  font-family:var(--mono); font-size:11.5px; letter-spacing:.05em; color:var(--ink-3);
}
.void.is-tall{ padding:16px 13px; }

/* --- findings --------------------------------------------------------- */
.quote{
  margin:7px 0 0; padding-left:14px; border-left:1px solid var(--accent-line);
  font-size:16px; line-height:1.52; font-style:italic; color:var(--ink-2); max-width:72ch;
}

/* --- the record: the same two-line block, one per event --------------- */
.filters{ display:flex; gap:14px; margin:0 0 15px; }
.filt{
  font-family:var(--mono); font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-3); border-bottom:1px solid transparent; padding-bottom:2px;
}
.filt[aria-pressed=true]{ color:var(--ink); border-bottom-color:var(--accent); }
.filt.is-ref[aria-pressed=true]{ color:var(--accent); }
.ev{ position:relative; margin:0 0 17px; max-width:none; }
.ev:last-child{ margin-bottom:0; }
/* the actor is carried by SHAPE, not colour: filled square = you, open diamond = agent */
.ev__g{ position:absolute; left:-23px; top:6px; }
.ev__g svg{ width:10px; height:10px; }
.ev[data-actor=human] .ev__g svg{ fill:var(--ink); stroke:none; }
.ev[data-actor=agent] .ev__g svg{ fill:none; stroke:var(--ink-3); stroke-width:1.5; }
.ev .say{ font-size:16.5px; }
.ev.is-refused{ border-left:2px solid var(--accent); padding-left:16px; margin-left:-18px; }
.ev.is-refused .ev__g{ left:-5px; }
.ev.is-refused .ev__g svg{ stroke:var(--accent); }
.ev details summary{ list-style:none; cursor:pointer; }
.ev details summary::-webkit-details-marker{ display:none; }
.ev details summary:hover .say{ color:var(--accent); }
.ev__peek{ font-family:var(--mono); font-size:10.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-3); border-bottom:1px solid var(--rule-2); }
/* the raw return: machine stock again, inset and ruled so it reads as an
   expansion of the line above rather than as another record of its own */
.ev__more{
  font-family:var(--mono); font-size:12px; line-height:1.6; color:var(--ink-3);
  background:var(--paper-sunk); padding:11px 14px; margin-top:9px; max-width:80ch;
  border-left:2px solid var(--rule-2);
  white-space:pre-wrap; overflow-x:auto;
}
.ev__more b{ color:var(--accent); font-weight:400; }
.ev__link{ font-size:16.5px; line-height:1.42; color:var(--ink); text-align:left; max-width:94ch; border-bottom:1px solid var(--rule-2); }
.ev__link:hover{ color:var(--accent); border-bottom-color:var(--accent); }

/* --- the seven tools -------------------------------------------------- */
table.tools{ border-collapse:collapse; max-width:calc(88ch + 11px); width:calc(100% + 11px); margin-left:-11px; }
table.tools th{
  font-family:var(--mono); font-size:10px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-3); font-weight:400; text-align:right; padding:0 0 6px; border-bottom:1px solid var(--rule);
}
table.tools th:first-child,table.tools th:nth-child(2){ text-align:left; }
table.tools td{ font-size:15px; padding:5px 0; color:var(--ink-2); text-align:right; }
table.tools td:first-child{
  text-align:left; font-family:var(--mono); font-size:13px; color:var(--ink);
  background:var(--paper-sunk); padding:5px 26px 5px 11px; white-space:nowrap;
}
table.tools th:first-child{ padding-right:26px; padding-left:11px; }
table.tools th:nth-child(3),table.tools th:nth-child(4),
table.tools td:nth-child(3),table.tools td:nth-child(4){ width:96px; }
table.tools td:nth-child(2){ text-align:left; }
table.tools td.hint{ font-family:var(--mono); font-size:12px; color:var(--ink-3); }
table.tools td.yes{ font-family:var(--mono); font-size:12px; color:var(--accent); }

.honesty{ max-width:80ch; }
.honesty p{ font-size:15.5px; line-height:1.64; color:var(--ink-2); }

/* --- verdict: pinned, so the human-only decision is never off-frame --- */
#verdict{
  --gut:40px; background:var(--paper-fold);
  border-top:1px solid var(--rule-2); padding:10px 40px 11px;
  display:grid; grid-template-columns:minmax(0,1fr) auto; gap:26px; align-items:center;
}
/* it bleeds left to the frame and stops at its own column, never under the
   controls sitting beside it */
/* the band now spans the bar, so it bleeds into BOTH gutters like every
   other machine line rather than stopping short of a control column. */
#verdict > .sub{ margin-right:calc(-1 * var(--gut)); padding-right:var(--gut); }
.rec-group{ display:flex; border:1px solid var(--rule-2); }
.rec-group button{ font-size:13.5px; padding:6px 12px; color:var(--ink-2); border-right:1px solid var(--rule-2); }
.rec-group button:last-child{ border-right:0; }
.rec-group button[aria-checked=true]{ background:var(--accent); color:var(--paper-read); }
.rec-group button:hover:not([aria-checked=true]){ background:var(--paper-lift); color:var(--ink); }
.commit{ font-size:14px; padding:6px 16px; border:1px solid var(--accent); color:var(--accent); background:var(--paper); }
.commit:hover{ background:var(--accent); color:var(--paper-read); }
#verdict-row{ display:flex; align-items:center; gap:13px; }
#verdict.is-committed .say{ color:var(--accent); }

/* ============================== STATUS BAR =============================== */
#status{
  display:flex; align-items:center; gap:0;
  padding:0 20px; border-top:1px solid var(--rule); background:var(--paper-sunk);
}
#status .m{ font-size:11px; }
.sep{ color:var(--rule-2); padding:0 8px; }
#status .fict{ margin-left:auto; color:var(--accent); }

/* ================================ DIALOGS ================================ */
dialog{
  border:1px solid var(--rule-2); background:var(--paper-read); color:var(--ink);
  padding:0; box-shadow:none;
}
dialog::backdrop{ background:var(--backdrop); }

/* --- the split-screen reveal -------------------------------------------- */
#dlg-split{ width:min(1160px, 94vw); height:min(720px, 92vh); }
#dlg-split .wrap{ display:grid; grid-template-rows:auto auto minmax(0,1fr) auto; height:100%; }
.split-head{ display:flex; align-items:flex-start; gap:16px; padding:16px 26px 12px; border-bottom:1px solid var(--rule); }
.split-head h2{ font-size:20px; font-weight:400; margin:3px 0 0; max-width:52ch; line-height:1.25; }
.pager{ margin-left:auto; display:flex; align-items:center; gap:9px; }
.pager button{ width:24px; height:24px; border:1px solid var(--rule-2); font-family:var(--mono); font-size:12px; color:var(--ink-2); }
.pager button:hover{ border-color:var(--accent); color:var(--accent); }
.split-lede{ padding:12px 26px; background:var(--accent-wash); border-bottom:1px solid var(--accent-line); }
.split-lede p:not(.m){ font-size:18px; line-height:1.34; color:var(--ink); max-width:76ch; }
.split-lede .m{ margin-top:5px; color:var(--ink-2); }
.split-body{ display:grid; grid-template-columns:1fr 1fr; min-height:0; }
.pane{ display:grid; grid-template-rows:auto minmax(0,1fr); min-height:0; }
.pane + .pane{ border-left:1px solid var(--rule); }
.pane__head{ display:flex; align-items:baseline; gap:9px; padding:9px 26px 8px; border-bottom:1px solid var(--rule); background:var(--paper); }
.pane__head h3{ font-size:14.5px; font-weight:600; margin:0; }
.pane__text{ position:relative; overflow-y:auto; padding:16px 26px 40px; }
.pane__text p:not(.m){ margin:0 0 13px; font-size:14.5px; line-height:1.62; color:var(--ink-2); }
.pane__text .sec{ max-width:none; }
.pane__text .payload,.pane__text .void{ max-width:none; }
.payload.is-hit{ outline:2px solid var(--accent); outline-offset:2px; }
.void.is-hit{ outline:2px solid var(--accent); outline-offset:2px; }
.split-foot{ display:grid; grid-template-columns:minmax(0,1fr) auto; gap:22px; align-items:center; padding:12px 26px; border-top:1px solid var(--rule); background:var(--paper); }
.stats{ display:flex; gap:26px; }
.stat b{ display:block; font-family:var(--mono); font-size:16px; font-weight:600; color:var(--ink); }
.stat b.sm{ font-size:11.5px; font-weight:400; padding-top:4px; }

/* --- centred dialogs ---------------------------------------------------- */
.dlg-c{ width:min(500px,92vw); padding:22px 26px 20px; }
.dlg-c h2{ font-size:20px; font-weight:400; margin:4px 0 10px; }
.caution{ border-left:3px solid var(--accent); background:var(--accent-wash); padding:10px 13px; margin:0 0 14px; }
.caution p:not(.m){ font-size:14px; line-height:1.5; color:var(--ink); }
.chips{ display:flex; flex-wrap:wrap; gap:7px; margin:8px 0 9px; }
.chips button{ font-size:12px; color:var(--ink-2); border:1px solid var(--rule-2); padding:3px 8px; }
.chips button:hover{ border-color:var(--accent); color:var(--accent); }
textarea,input[type=text]{
  width:100%; font-family:var(--serif); font-size:14.5px; line-height:1.5;
  color:var(--ink); background:var(--paper-read);
  border:1px solid var(--rule-2); padding:7px 9px; resize:none;
}
textarea:focus,input[type=text]:focus{ border-color:var(--accent); outline:none; }
input[type=text]::placeholder,textarea::placeholder{ color:var(--ink-3); }
.dlg-actions{ display:flex; align-items:center; gap:14px; margin-top:14px; }
.btn-quiet{ font-size:13.5px; color:var(--ink-2); border-bottom:1px solid var(--rule-2); padding-bottom:1px; }
.btn-quiet:hover{ color:var(--accent); border-bottom-color:var(--accent); }
.btn-firm{ margin-left:auto; font-size:13.5px; padding:6px 15px; border:1px solid var(--accent); color:var(--accent); }
.btn-firm:hover{ background:var(--accent); color:var(--paper-read); }
.btn-firm[aria-disabled=true]{ border-color:var(--rule-2); color:var(--ink-3); cursor:default; background:none; }

/* --- about -------------------------------------------------------------- */
#dlg-about{ width:min(720px,94vw); height:min(690px,92vh); }
#dlg-about .wrap{ display:grid; grid-template-rows:auto minmax(0,1fr); height:100%; }
.about-head{ display:flex; align-items:center; gap:14px; padding:16px 28px 12px; border-bottom:1px solid var(--rule); }
.about-head h2{ font-size:22px; font-weight:400; margin:0; }
.about-body{ overflow-y:auto; padding:18px 28px 28px; }
.about-body section{ margin-bottom:20px; max-width:66ch; }
.about-body h3{ font-family:var(--mono); font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-3); font-weight:400; margin:0 0 6px; }
.about-body p:not(.m){ margin:0 0 9px; font-size:15px; line-height:1.62; color:var(--ink-2); }
.about-body ol{ margin:0; padding-left:18px; font-size:15px; line-height:1.62; color:var(--ink-2); }
.about-body li{ margin-bottom:5px; }
.about-body code{ font-family:var(--mono); font-size:12.5px; color:var(--ink-3); }
.pull{
  margin:12px 0; padding-left:15px; border-left:2px solid var(--accent);
  font-size:16.5px; line-height:1.55; font-style:italic; color:var(--ink);
}
.honesty{ border-top:1px solid var(--accent-line); border-bottom:1px solid var(--accent-line); padding:12px 0; }
.honesty p{ color:var(--ink); }

/* ============================== NARROW / SHORT =========================== */
/* One compaction step, taken on either axis. Nothing is removed - the same
   sentences, voids, record and tools survive; the type and the air shrink.  */
@media (max-width:1180px), (max-height:720px){
  #room{ grid-template-columns:262px minmax(0,1fr); }
  .duo{ grid-template-columns:minmax(0,1fr); gap:0; margin-bottom:22px; }
  .duo .doc-sec{ margin-bottom:20px; }
  #ms-head,#doc-nav,#desk-body,#verdict{ padding-left:26px; padding-right:26px; }
  #desk-body,#verdict{ --gut:26px; }
  .duo > .doc-sec:first-child .pair-h,
  .duo > .doc-sec:first-child .sub,
  .duo > .doc-sec:last-child .pair-h,
  .duo > .doc-sec:last-child .sub{
    margin-left:-26px; padding-left:26px; margin-right:-26px; padding-right:26px;
  }
  .cut-tie .m{ margin-left:-14px; margin-right:-16px; padding-left:14px; padding-right:16px; }
  .pair-h{ padding-top:9px; padding-bottom:8px; margin-bottom:14px; }
  .duo > .doc-sec > .pair-h{ padding-top:8px; padding-bottom:7px; margin-bottom:12px; }
  .sub{ padding-top:3px; padding-bottom:4px; }
  .stamp{ font-size:10px; letter-spacing:.13em; padding:2px 7px 1px; margin-right:8px; }
  #ms-head{ padding-top:10px; padding-bottom:9px; }
  #ms-title{ font-size:23px; }
  #ms-meta{ font-size:12.5px; }
  #doc-nav{ padding-top:7px; padding-bottom:6px; gap:16px; }
  .navword{ font-size:13.5px; }
  .recvword{ font-size:11px; }
  #desk-body{ padding-top:12px; padding-bottom:24px; }
  h2.say{ font-size:19px; }
  .say{ font-size:16px; }
  .m,.sub{ font-size:11.5px; line-height:1.5; }
  .ev .say,.ev__link{ font-size:15.5px; }
  .pair{ margin-bottom:20px; }
  .doc-sec{ margin-bottom:26px; }
  .ev{ margin-bottom:14px; }
  .prose p:not(.sub){ font-size:15.5px; line-height:1.62; margin-bottom:12px; }
  .quote{ font-size:14.5px; }
  .withheld{ gap:4px 13px; margin-top:8px; }
  .wf__name{ font-size:10.5px; }
  .wf__void{ height:13px; }
  table.tools td{ font-size:13.5px; padding:4px 0; }
  #verdict{ padding-top:8px; padding-bottom:9px; gap:18px; }
  #verdict-row{ gap:10px; }
  .rec-group button{ font-size:12.5px; padding:5px 9px; }
  .commit{ font-size:13px; padding:5px 12px; }
  #rubric{ padding:9px 16px 9px; }
  .crit{ grid-template-columns:54px 1fr 20px; height:18px; }
  .row{ padding:5px 16px 5px 14px; }
  .row__title{ font-size:13.5px; }
  .cut{ padding:0 16px 0 14px; }
  .cut-tie{ padding-left:14px; padding-right:16px; }
}

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

/* ===========================================================================
   LIVE WIRING — added for the port, in the vocabulary already declared above.
   No new colour, no new type family, no new radius, no new shadow. Every rule
   here reuses --paper / --paper-sunk / --accent / --accent-wash and the
   .pair / .say / .sub coupling, because a fact the demo hardcoded and a fact
   the app derives must read as the same object.
   =========================================================================== */

/* --- the frame, now that the mount points carry it ---------------------- */
/* The single column is minmax(0,1fr), not the implicit `auto`. An auto column
   is sized to its widest item's MAX-CONTENT, so one nowrap row inside the
   status bar would widen the whole frame past the viewport even though that
   row is clipped. min-width:0 on the rows is the same guard one level down. */
.app{
  grid-template-rows:auto minmax(0,1fr) auto;
  grid-template-columns:minmax(0,1fr);
  width:100%; max-width:100vw;
}
.app > *{ min-width:0; }
#masthead{ height:46px; flex:0 0 auto; }
#mount-header{ display:block; background:var(--paper); }
#mount-main{
  display:grid; grid-template-columns:328px minmax(0,1fr); min-height:0;
}
#mount-main > *{ min-height:0; min-width:0; }
#mount-queue{
  position:relative; border-right:1px solid var(--rule);
  display:grid; grid-template-columns:minmax(0,1fr);
  grid-template-rows:auto minmax(0,1fr); background:var(--paper); min-height:0;
}
.reading{
  background:var(--paper-read); display:grid; grid-template-columns:minmax(0,1fr);
  grid-template-rows:auto minmax(0,1fr) auto; min-height:0;
}
.reading-head{ min-width:0; }
#mount-manuscript,#mount-findings,#mount-ledger{ display:block; }
#mount-footer{ display:block; }
/* The bar is one line at every supported size. It carries counts, not prose, so
   the honest failure when it runs out of room is to clip the least load-bearing
   item — never to wrap and grow the frame past 100dvh. */
#status{ height:26px; overflow:hidden; white-space:nowrap; }
#status > *{ flex:0 0 auto; }
#mount-tool-status{ margin:0; min-width:0; flex:0 1 auto; overflow:hidden; text-overflow:ellipsis; }
#status .fict{ min-width:0; flex:0 1 auto; overflow:hidden; text-overflow:ellipsis; }
#mount-split-screen{ display:contents; }

/* the plain-text fallback keeps its role=status announcement and gives up its
   pixels to the rendered band, which carries the same sentence */
#webmcp-absent{
  position:absolute; top:0; left:0; width:1px; height:1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap;
}

/* --- the WebMCP band: a browser without a flag, not an error ------------ */
/* neutral tone by contract (states.js WEBMCP_COPY.unavailable) — machine
   stock, the same ground every machine line on this page already sits on */
[data-bind="webmcp-band"]{
  display:flex; align-items:baseline; gap:14px; flex-wrap:wrap;
  padding:7px 20px 8px; background:var(--paper-sunk);
  border-bottom:1px solid var(--rule);
}
[data-bind="webmcp-band"] .say{ font-size:14px; }
[data-bind="webmcp-band"] .m{ flex:1 1 22ch; min-width:0; }
[data-webmcp="active"] [data-bind="webmcp-band"]{ display:none; }
[data-action="copy-flag-url"]{
  flex:0 0 auto; font-family:var(--mono); font-size:10.5px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-2);
  border:1px solid var(--rule-2); padding:3px 9px; white-space:nowrap;
}
[data-action="copy-flag-url"]:hover{ border-color:var(--accent); color:var(--accent); }
[data-bind="webmcp-failures"]{
  list-style:none; margin:5px 0 0; padding:0; flex:1 0 100%;
  font-family:var(--mono); font-size:11px; color:var(--accent);
}
[data-bind="webmcp-failures"] li{ margin-top:2px; }

/* --- the notice band: system conditions, never ledger rows -------------- */
[data-bind="notice-band"]{ display:block; }
[data-bind="notice-band"]:empty{ display:none; }
.notice{
  display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;
  padding:7px 20px 8px; border-bottom:1px solid var(--rule);
  background:var(--paper-sunk);
}
.notice .say{ font-size:14px; }
.notice .m{ flex:1 1 20ch; min-width:0; }
/* severity error borrows the accent hairline the page already uses for the
   cut and for a refusal's margin bar. Refusals never reach this band. */
.notice[data-severity="error"]{ border-left:2px solid var(--accent); }
.notice-dismiss{
  margin-left:auto; font-family:var(--mono); font-size:10.5px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3);
  border-bottom:1px solid var(--rule-2); padding-bottom:1px;
}
.notice-dismiss:hover{ color:var(--accent); border-bottom-color:var(--accent); }

/* --- the agent pulse: the sweep, in the status bar ---------------------- */
[data-bind="agent-pulse"]{ display:inline-flex; align-items:center; gap:6px; }
[data-bind="agent-pulse"] .pulse-dot{
  width:6px; height:6px; flex:0 0 auto; background:var(--ink-3);
  transform:rotate(45deg);
}
[data-bind="agent-pulse"][data-pulse="invoked"] .pulse-dot{
  background:var(--ink); animation:pulseBeat 900ms linear infinite;
}
[data-bind="agent-pulse"][data-outcome="refused"] .pulse-dot{ background:var(--accent); }
[data-bind="agent-pulse"][data-outcome="refused"]{ color:var(--accent); }
[data-bind="agent-pulse"][data-pulse="decay"]{ opacity:.55; }
@keyframes pulseBeat{ 0%,100%{ opacity:1 } 50%{ opacity:.25 } }

/* --- chips: a tool call may only ever cause a chip to appear ------------ */
.chip-refusal{
  display:inline-flex; align-items:center; gap:6px; white-space:nowrap;
  font-family:var(--mono); font-size:11px; font-weight:700; letter-spacing:.11em; text-transform:uppercase;
  color:var(--accent); border:1px solid var(--accent); padding:3px 8px;
}
button.chip-refusal:hover{ border-color:var(--accent); background:var(--accent-wash); }

/* --- empty states: the same two-line pair, so an absence reads as a fact - */
.empty{ margin:0; }
.empty .say{ color:var(--ink-2); }
.empty-action{
  display:inline-block; margin-top:9px; font-size:13.5px; color:var(--accent);
  border-bottom:1px solid var(--accent); padding-bottom:1px;
}
.empty-action:hover{ border-bottom-width:2px; }
#desk-body > [data-bind="desk-empty"]{ padding-top:6px; }
[data-bind="findings-refused-count"]{ display:block; margin-top:2px; }
.refused-link{
  font-family:var(--mono); font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--accent); border-bottom:1px solid var(--accent); padding-bottom:1px;
}
.refused-link:hover{ border-bottom-color:var(--accent); }
.refused-link[disabled]{ color:var(--ink-3); border-bottom-color:var(--rule-2); cursor:default; }

/* --- ledger controls: the export sits with the filters ------------------ */
.filters{ align-items:baseline; flex-wrap:wrap; }
[data-action="copy-ledger"]{
  margin-left:auto; font-family:var(--mono); font-size:11px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-3);
  border-bottom:1px solid var(--rule-2); padding-bottom:2px;
}
[data-action="copy-ledger"]:hover{ color:var(--accent); border-bottom-color:var(--accent); }
.copy-note{ flex:1 0 100%; margin-top:4px; }

/* --- the region error plate: scoped, so no judge sees a blank app ------- */
.plate{
  border-left:2px solid var(--accent); background:var(--paper-sunk);
  padding:10px 13px; margin:0;
}
.plate .say{ font-size:15.5px; }
.plate-actions{ display:flex; gap:14px; margin-top:8px; }
.plate-actions button{
  font-family:var(--mono); font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-2); border-bottom:1px solid var(--rule-2); padding-bottom:1px;
}
.plate-actions button:hover{ color:var(--accent); border-bottom-color:var(--accent); }

/* --- slate rows are keyed by the contract attribute now ----------------- */
#mount-queue .row{ width:100%; }

/* --- verdict, driven by state.committed --------------------------------- */
#verdict [data-bind="verdict-blocked"]{ display:block; }
#verdict [data-bind="verdict-blocked"]:empty{ display:none; }
.rec-group button[disabled]{ color:var(--ink-3); cursor:default; }
.commit[disabled]{ border-color:var(--rule-2); color:var(--ink-3); cursor:default; background:none; }

/* --- the split-screen when nothing was removed --------------------------- */
.pane__text .empty{ margin-top:4px; }

/* --- one compaction step, matching the one already declared above -------- */
@media (max-width:1180px), (max-height:720px){
  #mount-main{ grid-template-columns:262px minmax(0,1fr); }
  [data-bind="webmcp-band"],.notice{ padding-left:16px; padding-right:16px; }
  [data-bind="webmcp-band"] .say,.notice .say{ font-size:13px; }
}

/* ===========================================================================
   DENSITY CALIBRATION — one focal point per state.
   No new colour, no new family, no new tonal step: every rule below reuses
   --paper / --paper-sunk / --accent / --accent-wash and the .pair / .say / .sub
   coupling already declared above. What changes is WEIGHT and WHAT IS PRESENT,
   which is the only thing a tired reader on submission one hundred can act on.
   =========================================================================== */

/* --- STATE 1: nothing open. The sheet carries ONE object. ---------------- */
/* Findings, the record and the tools table are real and bound at all times;
   before a manuscript is open they are six section heads of equal weight
   competing with the invitation, so they wait. One click brings them back. */
#desk-body[data-desk-state="empty"] #sec-claim,
#desk-body[data-desk-state="empty"] #sec-record,
#desk-body[data-desk-state="empty"] #sec-tools,
#desk-body[data-desk-state="empty"] #sec-honesty{ display:none; }

/* the invitation, set as the only thing on the sheet */
#desk-body[data-desk-state="empty"]{ display:grid; align-content:center; padding-bottom:64px; }
/* the wrapper takes no width cap: the machine band under the invitation has
   to run out into both gutters like every other band on the sheet, or it
   acquires a vertical edge and reads as a card. The sentence above it is
   capped instead. */
#desk-body[data-desk-state="empty"] [data-bind="desk-empty"]{
  padding-top:0; max-width:none;
}
#desk-body[data-desk-state="empty"] [data-bind="desk-empty"] .say{
  font-size:33px; line-height:1.16; letter-spacing:-.012em;
  color:var(--ink); max-width:19ch;
}
/* the fact underneath the invitation is the thesis of the whole build, so at
   this one moment the machine register is set to be READ, not skimmed past */
#desk-body[data-desk-state="empty"] [data-bind="desk-empty"] .sub{
  font-size:14.5px; line-height:1.62; color:var(--ink-2);
  background:var(--paper-sunk);
  margin:18px calc(-1 * var(--gut)) 0;
  padding:11px var(--gut) 12px;
  max-width:none;
}
#desk-body[data-desk-state="empty"] .empty-action{
  margin-top:20px; font-size:16.5px; border-bottom-width:2px; padding-bottom:2px;
}

/* --- STATE 2: a manuscript is open. The enforcement is the loud part. ---- */
/* The blinding block is the single frame that explains this project without
   audio. It gets the accent edge every other enforcement mark on the page
   already uses, so a stranger can point at it. */
#desk-body[data-desk-state="open"] [data-bind="identity-block"]{
  border-left:3px solid var(--accent);
  padding:2px 0 2px 15px;
  margin-left:-18px;
}
/* the hatch is the deliberate absence; give it enough body to read as one */
.wf__void{ border:1px solid var(--rule-2); }
.wf{ gap:7px; }

/* HUMAN ONLY sits beside the control it governs, so it must not be the
   quietest thing in the row it is in */
.act-row,.eyebrow-end,.rec-actions{ align-items:center; }

/* the pinned verdict is the human-only decision; its chip carries the rule */
#verdict .only-you{ font-size:10.5px; }

/* --- the WebMCP band is a browser caveat, not the product ---------------- */
/* It is required to be visible and it stays visible, but it is a condition of
   the machine and not an argument, so it reads as one machine line rather than
   as a headline with a button beside it. */
[data-bind="webmcp-band"]{ padding:6px 20px 7px; gap:12px; }
[data-bind="webmcp-band"] .say{
  font-size:12.5px; font-family:var(--mono); color:var(--ink-2);
  letter-spacing:.01em; flex:0 1 auto; max-width:none;
}
[data-bind="webmcp-band"] .m{ font-size:11.5px; }

/* The head collapses to nothing with nothing open, but it MUST stay a grid
   item: .reading declares three rows, and display:none on this one re-places
   the desk into the auto track and hands the 1fr to the verdict bar, which
   then floats in mid-page. Its two children are hidden individually instead. */
.reading-head[data-head-state="empty"]{ min-height:0; }

/* the status bar carries counts at both ends; they may clip, but they may
   never touch — a collided pair reads as a rendering fault, not as a limit */
#status{ column-gap:16px; }

/* The band states a browser condition in one line and stops. NOTHING in it is
   allowed to be unshrinkable: the copy is swapped per WebMCP phase, and a
   nowrap sentence that cannot shrink would widen the FRAME for whichever phase
   happened to have the longest string — a horizontal scrollbar for one frame,
   on camera. Both text runs shrink and clip instead. */
/* The band WRAPS, because webmcp.failures is a flex:1 0 100% list that must be
   able to drop onto its own line. Pinning the band to nowrap traps that list
   on the main row where its unshrinkable 100% basis is ADDED to the row, and
   the frame goes to 1407px for the second or two the failures are on screen
   during boot — a horizontal scrollbar nobody would catch in a settled-state
   check. The one line is bought instead by giving the two text runs a small
   flex-basis: they never force a wrap, they grow to fill, and they clip. */
[data-bind="webmcp-band"]{ flex-wrap:wrap; min-width:0; }
[data-bind="webmcp-band"] > *{ min-width:0; }
[data-bind="webmcp-band"] .say{
  flex:0 1 auto; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
[data-bind="webmcp-band"] .m{
  flex:1 1 12ch; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* and the failures list can never be wider than the band it sits in */
[data-bind="webmcp-failures"]{ flex:1 0 100%; min-width:0; max-width:100%; }

/* the rubric caption is chrome beside a HUMAN ONLY chip, not a machine record */
.rubric-sub .m{ font-size:11.5px; line-height:1.45; }

/* --- the pinned bar, once a refusal has happened ------------------------- */
/* The bar is one sentence and one control cluster in an `auto` track. When a
   refusal adds the stamp and the blocked-attempt chip to that cluster, `auto`
   takes the width it asks for and leaves the sentence in a ~110px gutter, four
   words tall. The sentence gets a floor and the cluster wraps instead — the
   sentence is the thing a stranger reads, so it is the thing that keeps its
   line. */
/* flat bar: sentence + controls on row 1, the machine band full width on
   row 2, the refusal alarm on row 3. Rows 2 and 3 collapse when empty. */
#verdict{
  grid-template-columns:minmax(0,1fr) auto;
  grid-template-rows:auto auto auto;
  column-gap:20px; row-gap:0; align-items:center;
}
#verdict > .say{ grid-column:1; grid-row:1; }
#verdict > #verdict-row{ grid-column:2; grid-row:1; }
#verdict > .sub{ grid-column:1 / -1; grid-row:2; }
#verdict > .verdict-alarm{ grid-column:1 / -1; grid-row:3; }
/* the cluster is the controls and nothing else, and it never wraps: a second
   control row would push the sentence off its own line. */
#verdict-row{ flex-wrap:nowrap; }
/* the notice and its chip share one line; the wrapper collapses to nothing
   while both are empty, so the bar costs nothing until the page refuses. */
.verdict-alarm{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.verdict-alarm:empty{ display:none; }
#verdict [data-bind="verdict-blocked"]{ margin-top:7px; flex:1 1 22ch; min-width:0; }
[data-bind="verdict-blocked-chip"]{ display:inline-flex; align-items:center; margin-top:7px; flex:0 0 auto; }
[data-bind="verdict-blocked-chip"][hidden]{ display:none !important; }
@media (max-width:1180px), (max-height:720px){
  #verdict{ gap:14px; }
}

/* --- short viewports: the alarm says it once ----------------------------- */
/* The assertive notice and the refusal chip are the same event twice — one for
   a screen reader, one for the eye. On a short frame the pinned bar was taking
   163px of 640 and leaving the reading column 204px, so the notice keeps its
   announcement and gives up its pixels to the chip, which carries the same fact
   visually and is the louder of the two. Nothing is removed from the a11y tree. */
@media (max-height:720px){
  #verdict [data-bind="verdict-blocked"]:not(:empty){
    position:absolute; width:1px; height:1px; margin:0;
    overflow:hidden; clip-path:inset(50%); white-space:nowrap;
  }
}

/* ===========================================================================
   COLD-READ REPAIRS — four defects a first-time reader hit on the live build.
   No new colour, family or tonal step: every rule below reuses tokens already
   declared at the top of this file.
   =========================================================================== */

/* --- 1. the section nav needs a state a reader can point at -------------- */
/* `is-here` existed but was written only by the scroll spy, so it appeared
   only AFTER a scroll landed — and a scroll that never runs never marks
   anything. The host now writes it on the click itself, and the mark is given
   enough weight to read as the current tab rather than as a hover. */
.navword{ border-bottom-width:2px; }
.navword.is-here{ color:var(--ink); border-bottom-color:var(--accent); }
.navword[aria-current="true"]{ color:var(--ink); border-bottom-color:var(--accent); }

/* --- 3. the decision bar gives up the corner overlays land in ------------ */
/* The one human-only gate on this page used to sit at the extreme bottom-right,
   which is where an injected browser or platform toolbar parks itself; with one
   on screen the Accept / Minor / Major / Reject / Commit cluster could not be
   reached at all. The controls now lead the bar from the left, and the bar
   holds its own space away from the bottom edge, so the corner a floating
   widget takes carries the sentence rather than the decision. No stylesheet can
   promise this against an arbitrary overlay — the toolbar itself has to be
   turned off — but the target is no longer in the one place overlays always
   land. */
#verdict{ grid-template-columns:auto minmax(0,1fr); padding-bottom:24px; }
#verdict > #verdict-row{ grid-column:1; grid-row:1; }
#verdict > .say{ grid-column:2; grid-row:1; }

/* --- 4. the WebMCP band is a caveat, so it is the size of a caveat ------- */
/* It stays visible, it is not dismissible, and it carries the same true
   sentence. What it stops doing is out-ranking the product: no fill, so it is
   a line under the masthead rather than a full-width plate; the capability
   sentence first, in the human register at caption size; the machine's report
   of its own condition beside it in the machine register, where every other
   condition on this page is already stated; one text control, not a bordered
   button. Still exactly one control, as the manifest requires. */
/* Both sentences WRAP rather than clip. The band was already ellipsing its own
   instruction at 1280 with the shorter copy it used to carry — "…Open in the
   ChatGPT desktop app's…" — because `.say` and `.m` are nowrap-and-clip in
   here, and a line that tells a reader how to turn the agent side on must not
   stop mid-word. Wrapped, unfilled and set two steps down in size, the band
   costs a few pixels more height than the filled plate it replaces and a great
   deal less attention, which was the complaint. */
[data-bind="webmcp-band"]{
  background:transparent;
  padding:4px 20px 5px;
  column-gap:11px; row-gap:0;
  align-items:baseline;
}
[data-bind="webmcp-band"] .say{
  font-family:var(--serif); font-size:13px; line-height:1.4; color:var(--ink-2);
  letter-spacing:0; flex:0 1 auto; max-width:none;
  white-space:normal; overflow:visible; text-overflow:clip;
}
[data-bind="webmcp-band"] .m{
  font-size:11.5px; line-height:1.45; flex:1 1 26ch;
  white-space:normal; overflow:visible; text-overflow:clip;
}
[data-action="copy-flag-url"]{
  border:0; border-bottom:1px solid var(--rule-2);
  padding:0 0 1px; color:var(--ink-3);
}
[data-action="copy-flag-url"]:hover{ color:var(--accent); border-bottom-color:var(--accent); }

/* --- the one compaction step, matching the two already declared --------- */
@media (max-width:1180px), (max-height:720px){
  #verdict{ padding-bottom:17px; }
  [data-bind="webmcp-band"]{ padding:3px 16px 4px; column-gap:9px; }
  [data-bind="webmcp-band"] .say{ font-size:12px; }
  [data-bind="webmcp-band"] .m{ font-size:10.5px; line-height:1.4; flex:1 1 22ch; }
  [data-action="copy-flag-url"]{ font-size:10px; }
}


/* ===========================================================================
   THE RAIL, THE LEGEND, THE DECK AND THE FOLIO
   ---------------------------------------------------------------------------
   Everything below repairs ONE defect: a first-time viewer landed on a working
   application and did not know what to do. Two independent readers, same
   result. The page already had headings, a nav and numbered stations — they
   say what a region IS, and a seventh would not have helped, because the thing
   a visitor has to do is not on the page at all. This product's central event
   is an agent calling a tool, and a visitor arrives with no agent in the
   conversation.

   No new colour, family or tonal step is introduced. The single addition is
   --paper-fold, which is a GROUND for the two things only the human may do,
   and --ink-3 moved two steps darker because the value it inherited measured
   4.666:1 against --paper-sunk — every machine line on this page uses that
   pair, and the floor is 4.67.
   =========================================================================== */

/* --- the third column ---------------------------------------------------- */
/* The rail is created by conversation.js and appended to #mount-main, because
   index.html's mount points are not this lane's to edit. The slate gives up
   22px and the reading column keeps 686 at 1280 — wide enough that the two-up
   spread inside .duo still reads as a spread rather than as two gutters. */
#mount-main{ grid-template-columns:282px minmax(0,1fr) 268px; }
/* the queue now carries a head between the rubric and the list; the sr-only
   status is absolutely positioned and creates no track of its own */
#mount-queue{ grid-template-rows:auto auto minmax(0,1fr); }

#rail{
  --gut:16px;
  border-left:1px solid var(--rule);
  background:var(--paper);
  min-height:0; min-width:0;
  overflow-y:auto; overflow-x:hidden;
  display:block;
}

.rail-head{ --gut:16px; padding:11px 16px 0; }
.rail-head .say{ font-size:17px; line-height:1.24; letter-spacing:-.006em; max-width:none; }
.rail-head .sub{ font-size:11.5px; line-height:1.45; }

/* --- what the page says it just watched happen ---------------------------- */
/* One sentence, replaced rather than stacked, at the moment the refusal comes
   back. It is the payoff of the whole build, so it gets the payload ground the
   split-screen already uses for an attack, and its contract code sits under it
   in the machine register like every other fact on this page. */
#rail-said:empty{ display:none; }
.said-block{ --gut:16px; background:var(--accent-wash); padding:9px 16px 0; }
.said-block .say{ font-size:14px; line-height:1.36; }
.said-block .sub{ margin-top:7px; font-size:11px; }

/* --- the five steps ------------------------------------------------------- */
#rail-steps{ list-style:none; margin:0; padding:0; }
.rstep{
  --gut:16px;
  padding:9px 16px 10px;
  border-top:1px solid var(--rule);
  border-left:2px solid transparent;
}
.rstep__lab{ display:flex; align-items:baseline; gap:7px; }
.rstep__g{ flex:0 0 auto; align-self:center; line-height:0; }
.rstep__g svg{ width:8px; height:8px; fill:none; stroke:var(--ink-3); stroke-width:1.6; }
.rstep__n{
  font-family:var(--mono); font-size:10px; letter-spacing:.1em; color:var(--ink-3);
  font-variant-numeric:tabular-nums; flex:0 0 auto;
}
.rstep__t{ font-size:13.5px; line-height:1.3; color:var(--ink-2); min-width:0; }

/* the words themselves. pre-wrap keeps the break the prompt was authored with
   and still wraps inside a 288px column; the accent edge is the same one a
   refusal hangs its bar on, because this is the sentence that causes one. */
.rstep__say{
  font-family:var(--mono); font-size:11.5px; line-height:1.52;
  white-space:pre-wrap; word-break:break-word;
  color:var(--ink); background:var(--paper-read);
  border-left:2px solid var(--rule-2);
  margin:8px 0 0; padding:8px 10px;
}
.rstep__act{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:7px; }
/* the largest control in the app on purpose: it is the primary action on
   landing, and everything else here is a reading affordance */
.rstep__copy{
  flex:0 0 auto; min-height:28px;
  font-family:var(--mono); font-size:10.5px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-2); border:1px solid var(--rule-2); padding:5px 14px;
}
.rstep__copy:hover{ border-color:var(--accent); color:var(--accent); }
.rstep__copy[data-copied="no"]{ border-color:var(--accent); color:var(--accent); }
.rstep__watch{ font-size:10px; line-height:1.3; min-width:0; flex:1 1 10ch; }

.rstep__got{ margin-top:8px; }
.rstep__gotsay{ font-size:13px; line-height:1.36; color:var(--ink); }
.rstep__got .m{ display:block; margin-top:3px; font-size:10px; line-height:1.4; }

/* THE THREE STATES, and none of them is reachable by clicking. A step opens
   because the one before it really settled on the bus, and completes because
   its own tool did. */
.rstep[data-state="shut"] .rstep__t{ color:var(--ink-3); }
.rstep[data-state="now"]{ border-left-color:var(--accent); background:var(--paper-lift); }
.rstep[data-state="now"] .rstep__t{ color:var(--ink); }
.rstep[data-state="done"] .rstep__g svg{ fill:var(--accent); stroke:none; }
.rstep[data-state="done"] .rstep__say{ opacity:.62; }
.rstep[data-state="done"] .rstep__watch{ color:var(--accent); }

/* --- the visitor with no agent at all, which is most of them -------------- */
/* Leads with what works. The six lines below are states.js's own list, which
   has been true since the first build and had never been rendered anywhere.
   They carry the filled square because every one of them is a move that is
   yours. No control here: the masthead band already owns the one copy-the-flag
   control the manifest allows, and a second would be one condition reported
   twice. */
#rail-solo{ --gut:16px; padding:12px 16px 0; border-top:1px solid var(--rule-2); }
#rail-solo .say{ font-size:14px; line-height:1.34; }
#rail-solo .sub{ font-size:11px; line-height:1.45; margin-top:9px; }
.solo-list{ list-style:none; margin:8px 0 0; padding:0; }
.solo-list li{
  position:relative; padding-left:13px; margin-top:3px;
  font-size:12.5px; line-height:1.36; color:var(--ink-2);
}
.solo-list li::before{
  content:''; position:absolute; left:0; top:.52em;
  width:6px; height:6px; background:var(--ink);
}

/* --- THE KEY, printed once in the masthead -------------------------------- */
/* An open diamond is the assistant, a filled square is you. Printed the way a
   map prints its key and then used everywhere without explanation: on a step,
   on a decided row, beside every control the assistant has no tool for. This
   is what stops an accent mark from reading as a warning. */
.legend{
  flex:0 0 auto; display:flex; align-items:center; gap:14px;
  border-left:1px solid var(--rule-2); padding-left:14px;
}
.legend span{
  display:inline-flex; align-items:center; gap:6px;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-2); white-space:nowrap;
}
.legend svg{ width:9px; height:9px; }
.legend .l-agent svg{ fill:none; stroke:var(--ink-3); stroke-width:1.6; }
.legend .l-you svg{ fill:var(--accent); stroke:none; }
.legend .l-you{ color:var(--accent); }

/* --- THE STANDFIRST: the three claims, above the fold --------------------- */
/* They used to live in the About dialog. A modal nobody opens is not part of
   the product, and a judge who never clicks About never meets the argument at
   all. Set as a newspaper deck instead: one sentence, a rule, three columns,
   each naming the constraint in plain words, carrying the code the page
   actually returns, and pointing at the region that demonstrates it. */
.triad{
  --gut:40px;
  background:var(--paper);
  margin:0 calc(-1 * var(--gut)) 16px;
  padding:9px var(--gut) 10px;
  border-top:1px solid var(--accent-line);
}
.triad__lede{ font-size:16px; line-height:1.3; color:var(--ink); font-weight:400; max-width:92ch; }
.triad__cols{
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  margin-top:8px; padding-top:8px; border-top:1px solid var(--rule-2);
}
.triad__c{
  text-align:left; display:block; width:100%;
  padding:0 14px; border-left:1px solid var(--rule);
}
.triad__c:first-child{ padding-left:0; border-left:0; }
.triad__c:last-child{ padding-right:0; }
.triad__c b{ display:block; font-size:14px; font-weight:600; line-height:1.26; color:var(--ink); margin-bottom:3px; }
.triad__c .tp{ display:block; font-size:12.5px; line-height:1.34; color:var(--ink-2); margin-bottom:6px; }
.triad__c .code{
  display:inline-block;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.09em; color:var(--accent);
  border-bottom:1px solid var(--accent); padding-bottom:1px;
}
.triad__c:hover b{ color:var(--accent); }
.triad__c:hover .code{ border-bottom-width:2px; }
/* The deck is the argument, so it stays on the sheet in the empty state too —
   it is the one thing a stranger can read before choosing anything. But the
   empty desk centres its single object, and a centred deck is no longer ABOVE
   the fold, it is halfway down it. So with nothing open the sheet stacks from
   the top and the invitation buys its air with a margin instead. */
#desk-body[data-desk-state="empty"]{ align-content:start; }
#desk-body[data-desk-state="empty"] .triad{ margin-bottom:0; }
#desk-body[data-desk-state="empty"] [data-bind="desk-empty"]{ margin-top:52px; }

/* --- QUEUE POSITION, STATED RATHER THAN INFERRED -------------------------- */
.slate-head{
  --gut:20px; padding:8px 20px 9px; background:var(--paper);
  border-bottom:1px solid var(--rule);
}
.slate-head .say{ font-size:13px; line-height:1.34; color:var(--ink-2); }
.slate-head .m{ display:block; margin-top:3px; font-size:10.5px; line-height:1.4; }

/* a decided manuscript carries the same filled square that means "you"
   everywhere else on this page, so the queue gains a read/unread state that
   needs no legend of its own */
.mark{ display:inline-flex; align-items:center; gap:5px; }
.mark.is-you{ color:var(--ink-2); }
.mark.is-you::before{ content:''; width:6px; height:6px; background:var(--ink); flex:0 0 auto; }
.row.is-decided .row__title{ color:var(--ink-2); }

/* --- the folio: where this sheet sits, and whether it is done ------------- */
.folio{
  font-family:var(--mono); font-size:10px; letter-spacing:.11em; text-transform:uppercase;
  color:var(--ink-3); font-variant-numeric:tabular-nums; white-space:nowrap; flex:0 0 auto;
}
.folio b{ color:var(--ink-2); font-weight:600; }
.folio-dec{ color:var(--accent); }

/* --- the deck's third claim lands on the pinned bar ----------------------- */
/* The decision is not a section, so there is nothing to scroll to; the bar is
   already on screen. Marking it for a beat and moving focus into it is the
   honest equivalent of a jump. */
#verdict.is-pointed{ box-shadow:inset 0 0 0 2px var(--accent); }
@media (prefers-reduced-motion:no-preference){
  #verdict{ transition:box-shadow 180ms ease-out; }
}

/* --- one compaction step, matching the three already declared ------------- */
@media (max-width:1180px), (max-height:720px){
  #mount-main{ grid-template-columns:262px minmax(0,1fr) 258px; }
  .legend{ gap:10px; padding-left:11px; }
  .legend span{ font-size:9px; letter-spacing:.07em; }
  .triad{ padding-top:7px; padding-bottom:8px; margin-bottom:12px; }
  .triad__lede{ font-size:14.5px; }
  .triad__c b{ font-size:13px; }
  .triad__c .tp{ font-size:11.5px; }
  .rstep{ padding:7px 14px 8px; }
  .rstep__say{ font-size:11px; padding:7px 9px; }
  .rail-head{ padding-top:9px; }
  .rail-head .say{ font-size:15.5px; }
}

/* --- the reading column is 266px narrower now that the rail has a track --
   Two runs in the manuscript head were sized for a 952px column and clip or
   break words at 686: the eyebrow (id, chip, folio, and the ONLY YOU control
   cluster) and the six-word section nav, which was overflow:hidden and was
   therefore DROPPING its sixth word rather than showing it. A nav that cannot
   reach a section is a dead control, so both wrap instead. Every child keeps
   white-space:nowrap so the wrap happens between items and never inside a
   word — a broken "MS-
102" reads as a rendering fault. */
.ms-eyebrow{ flex-wrap:wrap; row-gap:4px; column-gap:11px; }
.ms-eyebrow > *{ flex:0 0 auto; }
.ms-eyebrow [data-bind-local="ms-id"]{ white-space:nowrap; }
.eyebrow-end{ flex:0 0 auto; }
.act{ white-space:nowrap; }
#doc-nav{ flex-wrap:wrap; row-gap:5px; column-gap:18px; overflow:visible; }
.navword{ font-size:13.5px; }

/* --- DENSITY, RE-CALIBRATED FOR THREE COLUMNS ---------------------------
   The frame is fixed at 1280x800 and the rail took 268 of the 1280, so the
   reading column went from 952 to 730. Four runs that fitted one line at 952
   were spending two or three at 730 — the verdict sentence, the deck prose,
   the manuscript title and the section nav — and between them they left the
   manuscript itself 173px of a 728px column. Nothing is removed and no copy
   is cut: the type comes down one step in the four places that were paying
   for the extra rows, and the height goes back to the sheet, which is the
   only thing on this page a reviewer actually reads at length.          */
#verdict > .say{ font-size:15px; line-height:1.3; }
#verdict{ padding-top:8px; }
.triad{ padding-top:7px; padding-bottom:8px; margin-bottom:13px; }
.triad__lede{ font-size:15px; line-height:1.28; }
.triad__cols{ margin-top:6px; padding-top:6px; }
.triad__c{ padding:0 12px; }
.triad__c b{ font-size:13px; line-height:1.24; margin-bottom:2px; }
.triad__c .tp{ font-size:11.5px; line-height:1.32; margin-bottom:5px; }
#ms-head{ padding:8px 40px 7px; }
#ms-title{ font-size:21px; line-height:1.16; }
#ms-meta{ font-size:12.5px; margin-top:3px; }
.ms-eyebrow{ margin-bottom:4px; }
#doc-nav{ padding:6px 40px 6px; column-gap:14px; row-gap:4px; }
.navword{ font-size:13px; }

/* --- the slate column at 282 --------------------------------------------
   The queue gave up 46px to the rail. The rubric caption and the queue head
   were set for 328 and were spending three lines on two lines of text, which
   pushed "Venue defaults" onto a row of its own and cost the list four rows
   of manuscripts. Same words, one step down, and the well is one block again. */
#rubric{ padding:9px 16px 9px; }
.rubric-head h2{ font-size:15px; }
.rubric-sub{ column-gap:8px; }
.rubric-sub .m{ font-size:10.5px; line-height:1.4; }
.rubric-foot{ margin-top:7px; column-gap:6px; }
.reset-link{ font-size:9.5px; }
.slate-head{ padding:7px 16px 8px; }
.slate-head .say{ font-size:12.5px; line-height:1.3; }
.slate-head .m{ font-size:10px; }

/* --- two calls to action, at two volumes ---------------------------------
   The empty sheet was tuned to carry ONE object, so the invitation was set at
   33px. It is no longer the only invitation on the page: the rail now offers
   the other half of the product, and two objects shouting at the same volume
   is the same defect as none. The human path keeps its rank as the largest
   thing on the sheet — a visitor who ignores the rail still gets a clean
   product — it just stops competing for the same glance. */
#desk-body[data-desk-state="empty"] [data-bind="desk-empty"] .say{ font-size:28px; }
#desk-body[data-desk-state="empty"] [data-bind="desk-empty"]{ margin-top:38px; }
.rail-head .say{ font-size:18px; }
