/* widgets/qc-proof — QC v2.1, "THE WORK, TOLD AS A STORY".

   Craig re-specced the QC room on 2026-08-07: the unit is a COMPLETED WORK ITEM, each one told as
   a plain story with its paper beside it, and reviewed with "a little bitty green check mark" in
   the top-right corner of the card.

   ── THIS IS A READING SURFACE, AND IT IS TYPED LIKE ONE ──────────────────────────────────────
   The --fs-* tokens are DASHBOARD DENSITY — right for a floor of numbers, too tight for prose.
   Craig's reading-type floor applies here: a room meant to be READ wants ~16px body. The story
   text is 16px/1.6 with a measure capped near 68 characters, because these cards are read one
   after another by Marianne and by Sergio, whose English is his second language. Chrome (chips,
   captions, meta) keeps the small tokens; SENTENCES never do.

   ── COURT-HONEST COLOUR ──────────────────────────────────────────────────────────────────────
   --action (vivid green) is CRAIG-COURT ONLY and appears nowhere in this file. The review check
   earns its own quieter green (--signal) so a ticked card reads as done without borrowing the
   owner's alarm ink. An exception is amber. NO RED anywhere: a card whose picture is missing gets
   an amber word, not a shout — the work is probably fine and the paper is what is missing.

   ── NO DRAWERS (standing law) ────────────────────────────────────────────────────────────────
   The story and its paper are laid out together, always. Nothing on this surface hides behind a
   disclosure triangle; that is the whole reason the room exists. */

#ops-pane-qcportal .q21-wrap { display: flex; flex-direction: column; min-height: 0;
  color: var(--motm-grey-900); }

/* ── head ─────────────────────────────────────────────────────────────────────────────────── */
.q21-head { display: flex; align-items: flex-start; gap: 20px; padding: 0 0 14px; }
.q21-head-l { min-width: 0; flex: 1 1 auto; }
.q21-eyebrow { font-size: var(--fs-label); font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--motm-warning); }
.q21-title { font-size: 22px; font-weight: 700; color: var(--canopy); line-height: 1.25; margin-top: 3px; }
.q21-sub { margin-top: 6px; font-size: 15px; color: var(--motm-grey-700); line-height: 1.55;
  max-width: 780px; }

.q21-meter { flex: 0 0 auto; text-align: right; }
.q21-meter-n { font-size: var(--fs-num); font-weight: 700; color: var(--canopy); line-height: 1;
  font-variant-numeric: tabular-nums; }
.q21-meter-reviewed { color: var(--signal); }
.q21-meter-l { font-size: var(--fs-label); font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--motm-grey-700); margin-top: 6px; }
.q21-meter-s { font-size: var(--fs-micro); color: var(--motm-grey-500); margin-top: 3px; max-width: 270px; }

/* The close-packet waiting count. A SECOND rail under the same meter, ruled off rather than run
   on — the two numbers count different things (work items vs books) and must never read as one
   running total. */
.q21-waiting { display: block; margin-top: 12px; padding: 9px 12px; text-align: right;
  border: 1px solid var(--brand-line-pale); border-top: 2px solid var(--canopy-line);
  border-radius: 8px; background: var(--brand-mist); cursor: pointer; max-width: 300px;
  font-size: var(--fs-label); color: var(--motm-grey-800); }
.q21-waiting:hover, .q21-waiting.is-on { background: var(--brand-wash); border-color: var(--canopy-line); }
.q21-waiting-n { font-size: 20px; font-weight: 700; color: var(--canopy);
  font-variant-numeric: tabular-nums; }
.q21-waiting-of { color: var(--motm-grey-700); }
.q21-waiting-s { display: block; font-size: var(--fs-micro); color: var(--motm-grey-500); margin-top: 2px; }

/* ── filters ──────────────────────────────────────────────────────────────────────────────── */
.q21-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 12px 0; border-top: 1px solid var(--brand-line-pale); }
.q21-chip { border: 1px solid var(--brand-line-pale); background: #fff; border-radius: 999px;
  padding: 6px 13px; font-size: var(--fs-label); color: var(--motm-grey-800); cursor: pointer;
  white-space: nowrap; }
.q21-chip b { font-variant-numeric: tabular-nums; color: var(--canopy); margin-left: 3px; }
.q21-chip:hover { border-color: var(--brand-line-soft); background: var(--brand-mist); }
.q21-chip.is-on { background: var(--canopy); border-color: var(--canopy); color: #fff; }
.q21-chip.is-on b { color: var(--brand-mint); }
.q21-chipsep { color: var(--motm-grey-400); padding: 0 2px; }
.q21-sel, .q21-search { border: 1px solid var(--brand-line-pale); border-radius: 8px;
  padding: 6px 10px; font-size: var(--fs-label); color: var(--motm-grey-800); background: #fff;
  max-width: 260px; }
.q21-search { min-width: 220px; flex: 1 1 220px; }
.q21-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-label);
  color: var(--motm-grey-700); cursor: pointer; white-space: nowrap; }

/* THE COVERAGE SENTENCE — Craig's honesty rule on the face of the room. Quiet, but never small
   enough to skip: it is the difference between a queue that IS everything and one that is a
   measured sample of it. */
.q21-coverage { font-size: 13.5px; line-height: 1.55; color: var(--motm-grey-600);
  background: var(--brand-mist); border-left: 3px solid var(--brand-line-soft);
  border-radius: 0 8px 8px 0; padding: 8px 14px; margin: 0 0 10px; max-width: 1080px; }
.q21-coverage b { color: var(--motm-grey-800); font-variant-numeric: tabular-nums; }
/* The claim reads as a sentence, not as a widget: no disclosure triangle, and the only affordance
   is the quiet link at the end of the line. `list-style: none` plus the ::-webkit- rule is what it
   takes to drop the marker in every engine we serve. */
.q21-coverage > summary { cursor: pointer; list-style: none; }
.q21-coverage > summary::-webkit-details-marker { display: none; }
/* COURT-HONEST COLOUR, ENFORCED ON THIS FILE'S OWN RULE (fixed 8/9). The header above declares
   that --action is Craig-court-only and "appears nowhere in this file" — and then this one link
   spent it twice, on a coverage disclosure that is not the owner's alarm and never was. A comment
   that outlives the thing it describes is worse than no comment, because it reads as authoritative
   and nobody re-checks it. The link is chrome; it takes --canopy. */
.q21-cov-more { color: var(--canopy); margin-left: 8px; white-space: nowrap;
  border-bottom: 1px solid color-mix(in srgb, var(--canopy) 35%, transparent); }
.q21-coverage[open] .q21-cov-more { color: var(--motm-grey-500); border-bottom-color: transparent; }
.q21-cov-d { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--brand-line-pale); }

/* ── the feed ─────────────────────────────────────────────────────────────────────────────── */
.q21-panes { min-height: 0; }
.q21-panes.is-close { display: grid; grid-template-columns: minmax(230px, 300px) minmax(0, 1fr);
  gap: 16px; align-items: start; }
.q21-feed { display: flex; flex-direction: column; gap: 10px; }
.q21-feed.is-grouped { gap: 6px; }

/* ── BY CLIENT ────────────────────────────────────────────────────────────────────────────────
   A collapsed row is a line of type, not a card: the whole point is that fifty books fit on a
   screen and she picks one. Court-honest — the count of what is left to review is stated, never
   coloured as an alarm; a book with nothing left says so in --signal, the room's quiet green. */
.q21-group { border: 1px solid var(--brand-line-pale); border-radius: 10px; background: #fff;
  overflow: hidden; }
.q21-group.is-open { border-color: var(--brand-line-soft); }
.q21-ghead { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 8px 12px; border: 0; background: transparent; cursor: pointer; font: inherit; }
.q21-ghead:hover { background: var(--brand-mist); }
.q21-ghead:focus-visible { outline: 2px solid var(--canopy); outline-offset: -2px; }
.q21-gcar { flex: 0 0 auto; color: var(--motm-grey-400); font-size: 11px;
  transition: transform .12s ease; }
.q21-group.is-open .q21-gcar { transform: rotate(90deg); color: var(--canopy); }
.q21-gname { font-size: 15px; font-weight: 650; color: var(--canopy); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.q21-gcount { flex: 0 0 auto; display: inline-flex; align-items: baseline; gap: 8px;
  font-size: var(--fs-micro); color: var(--motm-grey-500); letter-spacing: .03em; }
.q21-gtodo { font-weight: 700; color: var(--motm-grey-800); }
.q21-gdone { font-weight: 600; color: var(--signal); }
.q21-gmixes { flex: 1 1 auto; display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 5px;
  min-width: 0; }
.q21-gmix { font-size: var(--fs-micro); color: var(--motm-grey-600); background: var(--brand-mist);
  border: 1px solid var(--brand-line-pale); border-radius: 999px; padding: 1px 8px;
  white-space: nowrap; }
.q21-gmix.is-more { background: transparent; border-color: transparent; color: var(--motm-grey-400); }
.q21-gmix b { font-weight: 700; color: var(--motm-grey-800); }
.q21-gbody { display: flex; flex-direction: column; gap: 8px; padding: 2px 8px 8px;
  border-top: 1px solid var(--brand-line-pale); background: var(--brand-frost); }
.q21-gbody .q21-card { margin-top: 6px; }
.q21-gmore { font-size: var(--fs-micro); color: var(--motm-grey-500); padding: 4px 6px 2px; }

.q21-view { border: 1px solid var(--brand-line-pale); background: #fff; border-radius: 8px;
  padding: 6px 12px; font-size: var(--fs-label); color: var(--canopy); cursor: pointer;
  margin-left: auto; }
.q21-view:hover { background: var(--brand-mist); border-color: var(--brand-line-soft); }
.q21-listnote { font-size: var(--fs-micro); color: var(--motm-grey-500); letter-spacing: .02em; }
.q21-more { align-self: flex-start; border: 1px solid var(--brand-line-pale); background: #fff;
  border-radius: 8px; padding: 9px 16px; font-size: var(--fs-label); color: var(--canopy);
  cursor: pointer; }
.q21-more:hover { background: var(--brand-mist); border-color: var(--brand-line-soft); }

/* ── THE CARD ─────────────────────────────────────────────────────────────────────────────── */
.q21-card { border: 1px solid var(--brand-line-pale); border-radius: 12px; background: #fff;
  overflow: hidden; }
.q21-card.is-done { background: var(--brand-mist); border-color: var(--brand-line-soft); }
/* A flagged card is NOT an alarm — it is a card with a note on it and a bot on the way back.
   Amber edge, no fill, no red: calm alerts. */
.q21-card.is-flagged { border-left: 3px solid var(--motm-warning); }

/* DENSITY ROUND 2 — the header was 56px measured, of which ~20px was a line holding one chip.
   The chip is a run-in to the headline now, so the header is the headline plus its padding. */
.q21-card-h { display: flex; align-items: flex-start; gap: 10px; padding: 7px 12px 4px; }
.q21-card-t { margin: 0; flex: 1 1 auto; min-width: 0; font-size: 15px; line-height: 1.32;
  font-weight: 650; color: var(--canopy); }
.q21-card-kind { font-size: var(--fs-micro); font-weight: 600; text-transform: uppercase;
  letter-spacing: .07em; color: var(--signal); background: var(--signal-tint);
  border-radius: 999px; padding: 2px 8px; margin-right: 7px;
  /* inline-block on the h3's own baseline: the chip leads the headline and wraps with it rather
     than claiming a line of its own */
  display: inline-block; vertical-align: 1px; }
.q21-card-cn { font-size: var(--fs-label); font-weight: 600; color: var(--motm-grey-600);
  letter-spacing: .02em; margin-right: 7px; }
.q21-card-cn::after { content: '·'; margin-left: 7px; color: var(--brand-line-soft); }

/* THE GREEN CHECK. Craig asked for "a little bitty green check mark" top-right, and one click is
   the whole action — so it is small, unmistakable, and it has a real pressed state. --signal, not
   --action: vivid green is Craig-court and this is Marianne's room. */
.q21-card-act { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 8px; }

/* ── THE WHOLE ROW IS THE DOOR (Craig 2026-08-10) ─────────────────────────────────────────────
   "The whole row should be clickable." The cursor is the only affordance that says so before she
   clicks, and the hover wash is what says WHICH row she is about to open in a column of 181.
   The wash is on the header alone, not the card, so an open card does not light up its whole
   body when her pointer crosses the headline on the way to the check. */
.q21-card-h { cursor: pointer; transition: background .12s ease; }
.q21-card-h:hover { background: var(--brand-frost); }
/* The two controls keep their own cursor: they do something other than open the row, and a
   uniform pointer everywhere would hide that difference. */
.q21-card-h .q21-check:disabled { cursor: default; }

/* ── DATE · TIME · OFFICER ON THE FOLDED LINE (Craig 2026-08-10) ─────────────────────────────
   "the summarized row should have date stamps, time stamps, and officer names."

   IT IS A READING, NOT AN ALARM, so it is built to disappear until looked at: micro type, grey,
   no fill, no border, no colour of its own — the same discipline the door beside it runs on, and
   for the same reason (this sits on every row in the room, so anything with weight becomes 181
   small alarms down a filtered column). No red anywhere near it; nothing here is a warning.

   IT COSTS NO HEIGHT. The row's height is set by the 26px check, and this is one line of 11px
   type sitting in the same flex cluster — measured shut-row height is unchanged.

   IT STANDS DOWN FIRST WHEN THE ROOM IS NARROW. On a small viewport the headline is what a
   reviewer needs and the officer/clock are what she can get by opening the row, so the cluster
   drops rather than wrapping the header onto a second line. */
.q21-meta { display: inline-flex; align-items: center; gap: 5px; margin-right: 4px;
  font: 600 var(--fs-micro)/1 Inter, system-ui, sans-serif; color: var(--motm-grey-500);
  white-space: nowrap; letter-spacing: .01em; }
.q21-meta-x { color: var(--brand-line-soft); font-weight: 400; }
/* The officer is the one part of the cluster a reviewer scans FOR ("which bot did the Ricci
   batch?"), so it carries a half-step more weight than the clock beside it — and no more. */
.q21-meta-w { color: var(--motm-grey-600); }
/* A NAMED GAP IS NOT AN ALARM. "no trooper on record" is nine rows in 866 and it is a fact about
   our own record-keeping, not a problem with the work — so it steps BACK from the officers beside
   it rather than forward. No amber, no red: this room's calm-alerts rule holds here too. */
.q21-meta-w.is-gap { color: var(--motm-grey-400); font-weight: 500; font-style: italic; }
@media (max-width: 900px) { .q21-meta { display: none; } }

/* ── THE DOOR ON A FOLDED CARD (Craig 8/10 11:47) ──────────────────────────────────────────
   Quiet by construction. It sits beside the check on every one of seventeen rows, so a fill or a
   border colour would read as seventeen small alarms down the column — the same reason the
   re-verified stamp draws nothing when it has no opinion. Text button, muted until hover, and it
   carries its own label ("Show the reasoning · 3 pictures") because a bare chevron would make her
   open cards just to learn whether opening was worth it. */
.q21-open { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px;
  border: none; background: none; padding: 3px 2px; cursor: pointer;
  font: 600 var(--fs-micro)/1 Inter, system-ui, sans-serif; color: var(--motm-grey-600);
  transition: color .12s ease; }
.q21-open:hover { color: var(--signal); }
.q21-open svg { width: 13px; height: 13px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .14s ease; }
.q21-open.is-on svg { transform: rotate(180deg); }
.q21-open:focus-visible { outline: 2px solid var(--canopy); outline-offset: 2px; border-radius: 4px; }
/* A SHUT CARD IS A LINE, NOT A BOX. The header's own bottom padding is what is left once the body
   stops painting, so it closes up rather than leaving a stub of empty card below the line. */
.q21-card.is-shut .q21-card-h { padding-bottom: 7px; }
/* 26px, not 30px: measured, the BUTTON was setting the header's height, not the headline beside
   it — so four pixels off the check is four pixels off every card in the room. Still comfortably
   past the 24px touch floor, and still "a little bitty green check mark". */
.q21-check { width: 26px; height: 26px; border-radius: 50%; cursor: pointer;
  border: 1.5px solid var(--brand-line-soft); background: #fff; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .12s ease, border-color .12s ease; }
.q21-check svg { width: 17px; height: 17px; fill: none; stroke: var(--brand-line-soft);
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.q21-check:hover:not(:disabled) { border-color: var(--signal); background: var(--signal-tint); }
.q21-check:hover:not(:disabled) svg { stroke: var(--signal); }
.q21-check.is-on { background: var(--signal); border-color: var(--signal); }
.q21-check.is-on svg { stroke: #fff; }
.q21-check:disabled { opacity: .4; cursor: default; }
.q21-check:focus-visible { outline: 2px solid var(--canopy); outline-offset: 2px; }

/* ── story + paper, side by side (NO DRAWERS) ─────────────────────────────────────────────── */
/* THE PAPER GETS REAL ROOM. First shipped at 300px against a 1200px story column, which left
   ~300px of dead space beside the text (the measure caps at 68ch) AND made every check image and
   statement too small to read — on a surface whose entire purpose is "here's the check image,
   clear as day". The story column is capped instead, and the width it gives up goes to the
   evidence rather than to whitespace. */
/* ── DENSITY (Craig 8/7: "Way too much white space... a reviewer should see several items per
      screen, not 1.5") ────────────────────────────────────────────────────────────────────────
   Three things were making one card fill two thirds of a screen, and all three are fixed here
   rather than by shrinking the pictures alone:
     1. THE RESERVED COLUMN. The paper track was minmax(280px, 440px) whether or not anything
        drew in it. On 8/7 nothing did, so every card carried up to 440px of nothing — that is
        the white space he asked about. It is narrower now, and .is-nopaper collapses it
        entirely for a card that filed no picture.
     2. THE STACK. Two artifacts stacked vertically at 260px each is 560px of card before the
        story is read. They sit SIDE BY SIDE now and are thumbnails at ~118px — this room's
        pictures are a click away from full size, so a thumbnail is doing a thumbnail's job.
     3. THE RUN-IN LABELS. "What we found / What we did / Why" each took their own line above
        their sentence: six lines of type to carry three sentences. They read as run-in headings
        now, which is three lines back on every card in the room.
   Type comes down a step with it (16→14.5) but stays above --fs-body: these are sentences a
   reviewer reads all day, and the measure is still capped. */
/* ── DENSITY, ROUND 2 (Craig 8/7 3:58p) ──────────────────────────────────────────────────────
   Round one narrowed the reserved column and stopped stacking the tiles. Craig looked at the
   result and said the cards STILL reserve too much height — "a 3-line story sits in a card ~4x
   its content height" — and asked, of a card carrying several pictures, "wouldn't the thumbnails
   be smaller?"
   Measured on the live deploy before touching anything (tools/qc-v23-box-breakdown.js), a
   typical card was 251px tall and spent it like this:
       header  56   ← ~20 of it a line holding one chip
       story   99   ← the actual content
       paper  144   ← TALLER THAN THE STORY, so the picture set the card's height, not the words
       footer  39
   and a card with ONE picture drew that picture 360px wide — the full width of the reserved
   column — which is not a thumbnail, it is a second copy of the proof pane.
   Three changes, each aimed at a measured line of that table:
     1. THE COLUMN SIZES TO ITS TILES. `auto`, not minmax(230px, 360px). A one-picture card gives
        the width back to the story instead of holding 360px open for one thumbnail.
     2. THE TILES SHRINK AS THEY MULTIPLY — the size table below. One picture 144px, three 98px,
        and the picture box always shorter than a normal story, so THE STORY DECIDES THE CARD'S
        HEIGHT. That is what "cards size to content" has to mean mechanically.
     3. Header and footer come down, and the no-picture note stops being a box.
   The detail is not lost anywhere: the lightbox now navigates, so the rail is an index into it
   rather than a place to read a statement. Craig's own words for the trade — "the story is the
   star, thumbnails a compact evidence rail". */
/* ── ONE COLUMN, ALWAYS (Craig 8/9 9:26p — the evidence order) ────────────────────────────────
   The second track is gone. It held the thumbnails LEVEL WITH THE TOP OF THE STORY, so on the card
   he opened, the receipts were the first thing his eye met and the line and the reason — the two
   things he was actually looking for — were beside and below them. "I see the receipts… but I
   don't think that's the right evidence."
   The stack is now THE LINE · THE WHY · THE PAPER on every card, so the rail becomes a strip under
   the argument it supports. The old `.is-nopaper` collapse is what every card does now; the class
   is kept because it still tightens the gap on a card with no strip at all. */
.q21-card-b { display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 10px; padding: 0 12px 9px; align-items: start; }
.q21-card.is-nopaper .q21-card-b { gap: 5px; }

/* THE SIZE TABLE. The repeat() count must be a literal — a custom property cannot stand in for
   it — so the three cases DOC_CAP allows are written out. The auto-fill default below catches
   any future cap without leaving a card unstyled. */
.q21-card[data-pics="1"] { --q21-tile: 144px; --q21-pic: 92px; }
.q21-card[data-pics="2"] { --q21-tile: 118px; --q21-pic: 80px; }
.q21-card[data-pics="3"] { --q21-tile: 98px;  --q21-pic: 70px; }
.q21-card[data-pics="1"] .q21-paper { grid-template-columns: var(--q21-tile); }
.q21-card[data-pics="2"] .q21-paper { grid-template-columns: repeat(2, var(--q21-tile)); }
.q21-card[data-pics="3"] .q21-paper { grid-template-columns: repeat(3, var(--q21-tile)); }
/* A RAIL HOLDING A SENTENCE GETS WIDTH INSTEAD OF HEIGHT. `.has-note` is set by the fill code the
   moment a frame comes back with prose rather than bytes — which, measured, is most of them. Wide
   and three lines beats narrow and eight, and it costs the card nothing because the rail still
   ends up shorter than the story. Only the one- and two-frame cases widen: three notes at this
   width would be wider than the story they sit beside. */
.q21-card.has-note[data-pics="1"] { --q21-tile: 250px; }
.q21-card.has-note[data-pics="2"] { --q21-tile: 168px; }
.q21-story { min-width: 0; }
.q21-s { margin: 0 0 4px; font-size: 14.5px; line-height: 1.45; color: var(--motm-grey-800);
  max-width: 74ch; }
.q21-s:last-child { margin-bottom: 0; }
.q21-s-k { font-size: var(--fs-micro); font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--motm-grey-500); margin-right: 7px; }
.q21-s-k::after { content: ''; }
.q21-s-why { color: var(--motm-grey-600); }

/* Fixed tracks, sized by the table above — never `1fr`. A fractional track is what stretched a
   single thumbnail to 360px: it fills whatever the column is, so the column has to be told a
   width first, and then the two negotiate a picture nobody asked for. Fixed tile, `auto` column,
   and the rail is exactly as wide as the pictures in it. */
/* THE RAIL IS A STRIP NOW, not a column — it runs along the bottom of the argument, so it wants
   flow across rather than a fixed track count. The per-card size table above still governs the
   tile width; this just stops reserving a column-shaped hole for it. */
.q21-paper { min-width: 0; display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; }
.q21-card[data-pics="1"] .q21-paper,
.q21-card[data-pics="2"] .q21-paper,
.q21-card[data-pics="3"] .q21-paper { grid-template-columns: none; }
.q21-paper .q21-doc { width: var(--q21-tile, 98px); }
.q21-nopaper { flex: 1 1 100%; }
/* IT SAYS WHAT IT IS. A picture under a reason is a supporting exhibit; the label is what stops it
   reading as the evidence rather than the corroboration of it. */
.q21-paper-k { flex: 1 1 100%; font-size: var(--fs-micro); font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--motm-grey-500); margin-bottom: 1px; }

/* Inside a book, every card repeating that book's name is a line of type saying what the header
   above it already said. The kind chip stays — that is the part that differs card to card. */
.q21-gbody .q21-card-cn { display: none; }
.q21-doc { margin: 0; border: 1px solid var(--brand-line-pale); border-radius: 8px;
  background: var(--brand-frost); overflow: hidden; position: relative; }
.q21-doc-b { overflow: hidden; display: flex;
  align-items: center; justify-content: center; background: #fff; }
/* A FIXED height, set by the size table above, but ONLY once there is a picture in it. That is
   what makes the rail's height predictable and keeps it under the story, so the story decides how
   tall a card is. Scoping it to `.is-zoomable` matters: a frame that came back with a SENTENCE
   instead of bytes ("this one is a client document", "claimed, not found") puts that sentence in
   this box, and a fixed 92px with overflow:hidden would clip the room's own honesty about why a
   picture is missing. Those frames stay auto-height. */
.q21-doc-b.is-zoomable { height: var(--q21-pic, 92px); cursor: zoom-in; }
/* `cover` from the TOP, not `contain`: a screenshot's useful part is its top-left, and letterboxing
   a wide capture into a card makes it unreadable at this size. Clicking opens it full-size. */
.q21-doc-b img { width: 100%; height: 100%; object-fit: cover;
  object-position: top center; display: block; }
.q21-doc-s { font-size: var(--fs-micro); color: var(--motm-grey-500); padding: 4px 8px;
  letter-spacing: .03em; border-top: 1px solid var(--brand-line-pale); }
/* THE CAPTION RIDES ON THE PICTURE once there is a picture to ride on — 24px per tile back, and
   it is the same move the Confidence Room's row thumbs already make (.cdc-th-cap), so the two
   rooms read alike. Scoped to `.is-zoomable`, which is set exactly when an image lands: a frame
   still loading, or one that came back with a sentence instead of bytes, keeps its caption BELOW
   where it cannot cover the words. */
.q21-doc-b.is-zoomable + .q21-doc-s { position: absolute; left: 0; right: 0; bottom: 0;
  border-top: 0; padding: 3px 7px; color: #eaf2ec; letter-spacing: .04em;
  background: linear-gradient(to top, rgba(12,26,19,.9), rgba(12,26,19,.42) 72%, transparent);
  /* A caption is a SENTENCE now — it names the system and what the shot proves — so `nowrap` and
     an ellipsis would cut it at "The question, po…" and hand the reviewer nothing. Two lines,
     wrapped, costs no card height because the overlay sits on the picture. Where two lines are
     not enough the whole sentence is still on the frame's title and under the lightbox. */
  white-space: normal; line-height: 1.3; overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.q21-doc-b.is-zoomable + .q21-doc-s.is-ok { color: #eaf2ec; }
.q21-doc-s.is-ok { color: var(--signal); }
.q21-doc-s.is-warn { color: var(--motm-warning); }
/* "still coming up" is a queue position, not a problem — grey, so it cannot read as a finding.
   Court-honest colour: amber is reserved for something a reviewer has to act on, and a file
   partway up the rail is not that. It clears itself within a few ticks. */
.q21-doc-s.is-soft { color: var(--motm-grey-500); }
.q21-doc-note { font-size: var(--fs-micro); line-height: 1.4; color: var(--motm-grey-500);
  padding: 3px 2px; letter-spacing: .03em; align-self: center; }
/* No frame around a sentence. The border, the frost fill and the caption's rule are all there to
   say "this is a picture"; on a note they are chrome around type, and they were charging ~30px a
   card to say nothing. The words and their warn colour are untouched. */
.q21-doc.is-note { border: 0; background: transparent; }
.q21-doc.is-note .q21-doc-b { background: transparent; }
.q21-doc.is-note .q21-doc-note { padding: 0; font-size: 11.5px; line-height: 1.4;
  color: var(--motm-grey-600); }
.q21-doc.is-note .q21-doc-s { border-top: 0; padding: 3px 0 0; font-weight: 700; }
/* One line, no box. See the note in render.js — this used to be a dashed 39px block plus a 16px
   grid gap, on the majority of cards in the room, to say one thing. */
.q21-nopaper { font-size: 12px; line-height: 1.45; color: var(--motm-grey-500);
  padding: 2px 0 0 9px; border-left: 2px solid var(--brand-line-pale); }
/* 78px, not 118px: this is a SCROLLING preview of a text artifact, so its height is a choice
   rather than a constraint — and at 118px it was the tallest thing on its card, which put it in
   charge of that card's height for no reason a reviewer benefits from. */
.q21-txt { margin: 0; padding: 7px 8px; font-size: 11.5px; line-height: 1.45; white-space: pre-wrap;
  word-break: break-word; max-height: 78px; overflow: auto; color: var(--motm-grey-700); }
.q21-pdf { display: block; padding: 8px 10px; font-size: 12.5px; color: var(--canopy);
  text-decoration: underline; text-align: center; }

.q21-card-f { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 4px 12px; border-top: 1px solid var(--brand-line-pale); background: var(--brand-mist); }
.q21-who { font-size: var(--fs-micro); color: var(--motm-grey-500); letter-spacing: .03em; }
.q21-note { font-size: 13px; color: var(--motm-warning); font-style: italic; }
.q21-by { font-size: var(--fs-micro); color: var(--signal); }
.q21-sp { flex: 1 1 auto; }
.q21-flag { border: 1px solid var(--brand-line-pale); background: #fff; border-radius: 7px;
  padding: 5px 12px; font-size: var(--fs-label); color: var(--motm-grey-700); cursor: pointer; }
.q21-flag:hover:not(:disabled) { border-color: var(--motm-warning); color: var(--motm-warning); }
.q21-flag.is-on { border-color: var(--motm-warning); color: var(--motm-warning);
  background: var(--motm-warning-tint, #fdf6e7); }
.q21-flag:disabled { opacity: .4; cursor: default; }

/* ── the zoom (a check image, "clear as day") ─────────────────────────────────────────────── */
/* .q21-zoom IS GONE — this room no longer has a lightbox of its own. Craig, 8/7 3:58p: one
   lightbox component, not two behaviours. The overlay is `.fg-lb` / window.FgLightbox, styled in
   widgets/command-desk/styles.css, and both rooms open it. The rule is deleted rather than left
   unused on purpose: a dead selector is how a second overlay quietly comes back. */

/* ── close-packet scope ───────────────────────────────────────────────────────────────────── */
.q21-books { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.q21-book { text-align: left; border: 1px solid var(--brand-line-pale); background: #fff;
  border-radius: 9px; padding: 9px 12px; cursor: pointer; }
.q21-book:hover { background: var(--brand-mist); }
.q21-book.is-sel { border-color: var(--canopy); background: var(--brand-wash); }
.q21-book.is-wait { border-left: 3px solid var(--motm-warning); }
.q21-book-n { display: block; font-size: var(--fs-body); font-weight: 600; color: var(--motm-grey-900); }
.q21-book-s { display: block; font-size: var(--fs-micro); color: var(--motm-grey-500); margin-top: 2px; }
.q21-packet { min-width: 0; }

/* ── honest empty ─────────────────────────────────────────────────────────────────────────── */
.q21-empty { border: 1px dashed var(--brand-line-pale); border-radius: 12px; padding: 28px 24px;
  background: var(--brand-mist); }
.q21-empty-wide { max-width: 760px; }
.q21-empty .h { font-size: 17px; font-weight: 650; color: var(--canopy); }
.q21-empty .b { margin-top: 7px; font-size: 15px; line-height: 1.6; color: var(--motm-grey-600);
  max-width: 62ch; }

/* ── narrow ───────────────────────────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  /* The rail goes under the story rather than beside it; the tiles keep the size table's widths,
     so the row simply wraps. (The two flex rules that used to sit here were dead — .q21-paper has
     been a grid since round one, and `flex-direction` on a grid does nothing.) */
  .q21-card-b { grid-template-columns: minmax(0, 1fr); }
  .q21-panes.is-close { grid-template-columns: minmax(0, 1fr); }
  .q21-head { flex-direction: column; }
  .q21-meter { text-align: left; }
  .q21-waiting { text-align: left; }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   QC v2.4 — THE FRONT DOOR: worth your eyes, the silence, and the health glance
   builder2, 2026-08-07 · job 00-builder2-qc-v24-eyes-silence-rework-20260807

   Everything below obeys the same two rules as the rest of this file. COURT-HONEST COLOUR: --action
   is Craig-court only and appears nowhere here; a drifted card and a dark book both earn AMBER
   (--motm-warning), never red. NO RED AT ALL — a book that recorded nothing is a question, and a
   transaction whose category moved is a thing to read, and neither is an emergency. And the rework
   tiles are deliberately the quietest thing on the page: they are about a bot's work, and a tile
   that shouts turns a coaching glance into an accusation.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── the door switch ──────────────────────────────────────────────────────────────────────── */
.q21-door { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 12px 0;
  border-top: 1px solid var(--brand-line-pale); }
.q21-door-b { border: 1px solid var(--brand-line-pale); background: #fff; border-radius: 999px;
  padding: 7px 15px; font-size: var(--fs-label); color: var(--motm-grey-800); cursor: pointer;
  white-space: nowrap; }
.q21-door-b b { font-variant-numeric: tabular-nums; color: var(--canopy); margin-left: 4px; }
.q21-door-b:hover { border-color: var(--brand-line-soft); background: var(--brand-mist); }
.q21-door-b.is-on { background: var(--canopy); border-color: var(--canopy); color: #fff; }
.q21-door-b.is-on b { color: var(--brand-mint); }
/* The silence count lives here because the silence SECTION sits below the shortlist — this is
   what keeps it above the fold. It is a button and it jumps; a count that looks clickable and
   is not is the dead-click defect. */
.q21-door-n { font-size: var(--fs-label); color: var(--motm-warning); margin-left: 4px;
  background: none; border: 0; border-bottom: 1px dotted currentColor; padding: 2px 0;
  cursor: pointer; }
.q21-door-n:hover { color: var(--canopy); }

/* ── sections ─────────────────────────────────────────────────────────────────────────────── */
.q21-panes.is-eyes { display: flex; flex-direction: column; gap: 26px; overflow: auto;
  padding-top: 4px; }
.q21-sect { min-width: 0; }
.q21-sect-h { font-size: 18px; font-weight: 700; color: var(--canopy); line-height: 1.3; margin: 0; }
/* A SENTENCE, so it takes the reading floor and not the dashboard tokens (see the file header). */
.q21-sect-s { margin: 6px 0 14px; font-size: 15px; line-height: 1.6; color: var(--motm-grey-700);
  max-width: 74ch; }
.q21-sect-n { margin: 12px 0 0; font-size: 13px; line-height: 1.55; color: var(--motm-grey-500);
  max-width: 74ch; }
.q21-sect-n-wide { max-width: none; }
.q21-feed.is-eyes { display: flex; flex-direction: column; gap: 10px; }

/* ── the re-verified stamp ────────────────────────────────────────────────────────────────── */
/* Sits at the top of the story column, above "What we found", because it changes how the story
   underneath it should be read. Quiet by construction: a rule down the left, no box, no icon. */
.q21-stamp { border-left: 3px solid var(--brand-line-soft); padding: 1px 0 1px 10px;
  margin: 0 0 10px; }
.q21-stamp-h { display: block; font-size: 13px; font-weight: 650; color: var(--motm-grey-700);
  letter-spacing: .01em; }
.q21-stamp-b { display: block; margin-top: 2px; font-size: 13px; line-height: 1.5;
  color: var(--motm-grey-600); max-width: 68ch; }
.q21-stamp.is-ok { border-left-color: var(--signal); }
.q21-stamp.is-ok .q21-stamp-h { color: var(--signal); }
/* DRIFT AND MISSING ARE AMBER, NOT RED. The work may well be right and the books may have moved
   for a good reason; this is the room saying "read this one", not "something is broken". */
.q21-stamp.is-drift, .q21-stamp.is-missing { border-left-color: var(--motm-warning); }
.q21-stamp.is-drift .q21-stamp-h, .q21-stamp.is-missing .q21-stamp-h { color: var(--motm-warning); }
.q21-stamp.is-unk { border-left-color: var(--brand-line-pale); }
.q21-stamp.is-unk .q21-stamp-h { color: var(--motm-grey-500); font-weight: 600; }
/* The card itself takes the faintest possible tint — enough to find it while scrolling, not
   enough to read as an alarm beside its neighbours. */
.q21-card.is-drifted { border-color: var(--motm-warning); }

/* ── silence ──────────────────────────────────────────────────────────────────────────────── */
.q21-sils { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 10px; }
.q21-sil { border: 1px solid var(--brand-line-pale); border-radius: 12px; background: #fff;
  padding: 14px 16px; display: flex; flex-direction: column; gap: 6px; }
.q21-sil.is-dark { border-color: var(--motm-warning); background: #fffdf7; }
.q21-sil-h { font-size: 15px; font-weight: 650; color: var(--canopy); line-height: 1.4; }
.q21-sil-b { font-size: 14px; line-height: 1.55; color: var(--motm-grey-600); max-width: 60ch; }
.q21-sil-f { display: flex; align-items: center; gap: 10px; margin-top: 4px; }
.q21-sil-who { font-size: var(--fs-micro); color: var(--motm-grey-500); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.q21-sil-go { margin-left: auto; flex: none; border: 1px solid var(--brand-line-pale);
  background: #fff; border-radius: 8px; padding: 6px 12px; font-size: var(--fs-label);
  color: var(--canopy); cursor: pointer; }
.q21-sil-go:hover { background: var(--brand-mist); border-color: var(--brand-line-soft); }
/* Not a button, because there is nothing behind it — see the note in silenceHtml. */
.q21-sil-no { margin-left: auto; flex: none; font-size: var(--fs-micro); color: var(--motm-grey-400); }

/* ── rework health ────────────────────────────────────────────────────────────────────────── */
.q21-rws { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 8px; }
.q21-rw { border: 1px solid var(--brand-line-pale); border-radius: 10px; background: var(--brand-frost);
  padding: 11px 13px; }
.q21-rw-n { font-size: 14px; font-weight: 650; color: var(--canopy); margin-bottom: 5px; }
.q21-rw-r { font-size: 13px; line-height: 1.5; color: var(--motm-grey-600);
  font-variant-numeric: tabular-nums; }
.q21-rw-r b { font-weight: 700; color: var(--motm-grey-800); }
.q21-rw-r.is-back b { color: var(--motm-warning); }
.q21-rw-fix { margin-top: 3px; padding-top: 4px; border-top: 1px solid var(--brand-line-pale); }
/* The absent-rate sentence is grey and small ON PURPOSE — it is the honest shape of an empty
   ledger, and dressing it as a number would invite a judgement the data cannot carry. */
.q21-rw-none { color: var(--motm-grey-400); font-size: 12px; line-height: 1.45; }

@media (max-width: 900px) {
  .q21-sils, .q21-rws { grid-template-columns: 1fr; }
}

/* A frame whose note is a repeat of one already on the card — folded, never removed (the count
   moves onto the first note instead, so no file goes unmentioned). See `prose` in render.js. */
.q21-doc.is-folded { display: none; }

/* ════════════════════════════════════════════════════════════════════════════════════════════
   THE RECONCILE PROOF SPREAD (builder2, 2026-08-07)

   Craig, 4:07p: "Build a pretty display showing the bank statement side by side with the
   reconcile report and that it matched to the penny. We have way more capability than we are
   using." The spread is the STAR of a reconcile card — full width, under the work slip, with the
   thumbnail rail stood down (see cardHtml: the pictures are counted, never painted, beside it).

   COURT-HONEST COLOUR, WHICH ON THIS PANE IS THE WHOLE ETHIC. --action (vivid green) is Craig's
   court and is never used here. A TIE gets the room's quiet --signal green; an OPEN DIFFERENCE
   gets --motm-warning, which is amber, NOT red — an untied account is a fact to route, not an
   alarm to sound, and every red on this glass belongs to Craig's court alone.

   NOTHING HERE DRAWS A NUMBER THAT ISN'T THERE. Every figure row is emitted only when its value
   resolved; the gaps render as sentences (.rps-gap), never as a zero or an em-dash standing in
   for money. See the tie-out header in render.js for why that is a law and not a preference. */
.q21-card.is-spread .q21-card-b { grid-template-columns: minmax(0, 1fr); gap: 5px; }
/* With the spread carrying the card, the stood-down picture rail is a SENTENCE, not a tile grid —
   it must not inherit the 98px track table or it wraps "2 pictures filed with this work" down four
   lines in a column the width of a thumbnail that is no longer there. */
.q21-card.is-spread .q21-paper { grid-template-columns: minmax(0, 1fr); }
.q21-card.is-spread .q21-doc-note { padding: 0; }
.rps { margin: 2px 12px 11px; border: 1px solid var(--brand-line-pale); border-radius: 12px;
  background: var(--brand-frost); overflow: hidden; }

/* THE VERDICT, AT THE TOP, BIGGEST THING ON THE CARD. It is the one line a reviewer needs when
   the answer is yes, and the one she must not be able to misread when the answer is no. */
.rps-head { padding: 13px 16px 12px; background: #fff;
  border-bottom: 1px solid var(--brand-line-pale); }
.rps-verdict { display: block; font-size: var(--fs-label); font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--motm-grey-500); }
.rps-fig { display: block; margin-top: 4px; font-size: 27px; font-weight: 700; line-height: 1.12;
  color: var(--canopy); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.rps-sub { display: block; margin-top: 5px; font-size: 14px; line-height: 1.45;
  color: var(--motm-grey-600); max-width: 78ch; }
.rps[data-state="tied"] .rps-head { background: var(--signal-tint); border-color: #c5dccd; }
.rps[data-state="tied"] .rps-verdict { color: var(--signal); }
.rps[data-state="tied"] .rps-fig { color: var(--signal); }
.rps[data-state="off-by"] .rps-fig,
.rps[data-state="conflict"] .rps-fig { color: var(--motm-warning); }
.rps[data-state="off-by"] .rps-verdict,
.rps[data-state="conflict"] .rps-verdict { color: var(--motm-warning); }

/* SIDE BY SIDE IS THE ASK, SO IT IS A REAL TWO-TRACK GRID with a rule between the panels — the
   statement on the left, the books on the right, and the eye crossing once. The probe measures
   these two boxes' geometry rather than trusting this rule to have applied. */
.rps-cols { display: grid; grid-template-columns: 1fr 1fr; }
.rps-p { padding: 13px 16px 14px; min-width: 0; }
.rps-stmt { border-right: 1px solid var(--brand-line-pale); }
.rps-p-h { font-size: var(--fs-micro); font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--motm-grey-500); margin-bottom: 7px; }
.rps-acct { font-size: 14.5px; font-weight: 650; color: var(--canopy); line-height: 1.3; }
.rps-l4 { font-weight: 600; color: var(--motm-grey-500); font-variant-numeric: tabular-nums; }
.rps-per { margin-top: 2px; font-size: 12.5px; color: var(--motm-grey-500); }

/* The figure rows. Tabular numerals so the statement's ending balance and the books' cleared
   balance line up digit-for-digit across the rule — which is the comparison Craig is making. */
.rps-r { display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin-top: 8px; padding-top: 7px; border-top: 1px dotted var(--brand-line-pale); }
.rps-k { font-size: 13px; color: var(--motm-grey-600); }
.rps-v { font-size: 15px; font-weight: 650; color: var(--motm-grey-800);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.rps-r.is-key .rps-v { font-size: 18px; font-weight: 700; color: var(--canopy); }
.rps[data-state="tied"] .rps-r.is-key .rps-v { color: var(--signal); }
.rps-r.is-open .rps-v { color: var(--motm-warning); }

/* A GAP IS A SENTENCE, NEVER A BLANK. This is the same law the document frames run under: the
   pane must always end in words, so "we don't know" can never be mistaken for "it's fine". */
.rps-gap { margin-top: 9px; font-size: 12.5px; line-height: 1.5; color: var(--motm-grey-500); }
.rps-note { margin-top: 9px; font-size: 12.5px; line-height: 1.5; color: var(--motm-grey-500); }
.rps-court { margin-top: 9px; padding: 7px 10px; border-radius: 8px; background: #fdf3e0;
  font-size: 12.5px; line-height: 1.5; color: #7a5312; }
.rps-court b { font-weight: 700; }

/* Narrow: the panels stack and the rule moves to the top edge of the second one, so the reading
   order (statement, then books) survives losing the side-by-side. */
@media (max-width: 900px) {
  .rps-cols { grid-template-columns: 1fr; }
  .rps-stmt { border-right: 0; border-bottom: 1px solid var(--brand-line-pale); }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   THE REASONING — the six sections (Craig ruling, 2026-08-08 2:14p)
   ══════════════════════════════════════════════════════════════════════════════════════════════
   "A reviewer must be able to agree or disagree with the bot's judgment without opening
   QuickBooks." Everything here serves reading, not density. That is a deliberate reversal of the
   8/7 density rounds, and it is the right one BECAUSE OF WHAT THESE CARDS ARE: the density work
   was aimed at hundreds of near-identical mechanical rows, where a tall card meant scrolling past
   the same three sentences over and over. A judgment card is the opposite — it is rare (2 of 741
   items the day this shipped), and a reviewer opens it precisely to read it. Compressing the one
   card someone came to read, to save space on cards nobody stops at, would be the trade backwards.

   MEASURE, NOT WIDTH. Prose gets ~78ch and normal line-height; the --fs-* tokens stay where they
   belong, on the floor of numbers. Both reviewers read English as a second language, and a wall
   of type is where a second-language reader loses the thread first. */
.q21-reason { min-width: 0; }
.q21-card.is-reasoned .q21-card-b { grid-template-columns: minmax(0, 1fr); }

/* THE NUMBERS ARE LOAD-BEARING, NOT ORNAMENT. Craig asked for "clearly outlined". A reviewer who
   reads English as a second language should be able to find "what did you actually ask" without
   parsing the three sections above it — the numeral is the handle that makes that possible. */
.q21-r { margin: 0 0 13px; }
.q21-r:last-child { margin-bottom: 0; }
.q21-r-h { display: flex; align-items: center; gap: 8px; margin: 0 0 5px;
  font-size: var(--fs-label); font-weight: 700; letter-spacing: .075em; text-transform: uppercase;
  color: var(--motm-grey-600); }
.q21-r-n { display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; border-radius: 50%; flex: none;
  background: var(--brand-mist); color: var(--canopy);
  font-size: 10px; font-weight: 700; letter-spacing: 0; }
.q21-r-ul { margin: 0; padding-left: 17px; max-width: 78ch; }
.q21-r-ul li { font-size: 14.5px; line-height: 1.5; color: var(--motm-grey-800); margin-bottom: 3px; }
.q21-r-ul li:last-child { margin-bottom: 0; }
.q21-r-p { margin: 0; font-size: 14.5px; line-height: 1.5; color: var(--motm-grey-800);
  max-width: 78ch; }

/* SECTION 3 IS THE ONE A REVIEWER ARGUES WITH, so it is the one that carries weight — a left rule
   in the room's own green and a slightly darker ink. It is not an alarm and must never read as
   one: --action is Craig-court and appears nowhere in this file. */
.q21-r-why { border-left: 2px solid var(--canopy-line); padding-left: 11px;
  color: var(--motm-grey-900, var(--motm-grey-800)); }

/* THE QUESTION, AS THE CLIENT SEES IT. A quotation, not a summary — the reviewer is checking our
   voice with the client, so the words have to be the words. */
.q21-q { margin-top: 8px; border: 1px solid var(--brand-line-pale); border-radius: 9px;
  background: var(--brand-frost); padding: 9px 12px; max-width: 78ch; }
.q21-q + .q21-q { margin-top: 7px; }
.q21-q-m { font-size: var(--fs-micro); color: var(--motm-grey-500); letter-spacing: .03em;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.q21-q-s { margin-top: 3px; font-size: 13.5px; font-weight: 650; color: var(--canopy);
  line-height: 1.4; }
.q21-q-b { margin: 6px 0 0; padding-left: 11px; border-left: 2px solid var(--brand-line-pale);
  font-size: 14.5px; line-height: 1.55; color: var(--motm-grey-800); font-style: normal; }

/* AN UNRECORDED QUESTION MUST NOT BE ABLE TO LOOK LIKE A RECORDED ONE. Different container, no
   quotation rule, and a chip that says so — because a quote a reviewer trusts and we invented is
   worse than an admitted gap. Dashed, in neutral ink: this is a gap in OUR record-keeping, not a
   fault in the bookkeeping, and colouring it as a failure would misdirect the reviewer's eye. */
.q21-q.is-nogap { background: transparent; border-style: dashed; }
.q21-q-flag { font-size: var(--fs-micro); font-weight: 650; letter-spacing: .04em;
  color: var(--motm-grey-600); background: var(--brand-mist); border-radius: 999px;
  padding: 1px 8px; }
.q21-q-n { margin-top: 5px; font-size: 13.5px; line-height: 1.5; color: var(--motm-grey-600); }

/* OUR TEMPLATE, EVERY CLIENT. Tabular numerals so amounts line up down the column, and the
   wrapper scrolls rather than letting a long description squeeze the money out of view. */
.q21-bd-w { overflow-x: auto; }
.q21-bd { border-collapse: collapse; font-size: 13.5px; min-width: 100%; }
.q21-bd th { text-align: left; font-size: var(--fs-micro); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--motm-grey-500); padding: 0 12px 4px 0;
  border-bottom: 1px solid var(--brand-line-pale); white-space: nowrap; }
.q21-bd td { padding: 6px 12px 6px 0; color: var(--motm-grey-800); vertical-align: top;
  border-bottom: 1px solid var(--brand-line-pale); }
.q21-bd tr:last-child td { border-bottom: 0; }
.q21-bd-date, .q21-bd-ref { white-space: nowrap; color: var(--motm-grey-600); }
.q21-bd-amount { font-variant-numeric: tabular-nums; font-weight: 650; white-space: nowrap;
  color: var(--canopy); }
.q21-bd-now { color: var(--motm-grey-600); }

/* Section 5 holds the same frames the rail used to, so they inherit the tile sizes above. They
   get a little more room here — this is the proof a reviewer is being asked to look AT, not an
   index into a lightbox beside a story. */
.q21-card.is-reasoned { --q21-tile: 232px; --q21-pic: 128px; }
.q21-card.is-reasoned .q21-doc { display: inline-block; width: var(--q21-tile);
  vertical-align: top; margin-right: 8px; }

/* THE CAPTION COMES OFF THE PICTURE IN SECTION 5, and this is the one place it earns the height.
   Craig's ask was "screenshots proving they landed in Double" — so a reviewer has to be able to
   read, from the caption alone, which system each shot is of and what it proves. Riding on the
   picture, that sentence is white-on-photo at 11px over whatever the screenshot happens to be;
   below it, it is ordinary type she can read at a glance, and it may take the three lines it
   needs instead of being clamped. The tile is wider here for the same reason: this is the proof
   she is being asked to look AT, not an index into a lightbox beside a story. */
.q21-card.is-reasoned .q21-r .q21-doc-b.is-zoomable + .q21-doc-s {
  position: static; display: block; background: none; padding: 5px 1px 0;
  color: var(--motm-grey-600); letter-spacing: .01em; font-size: 12px; line-height: 1.4;
  -webkit-line-clamp: none; white-space: normal; }
.q21-card.is-reasoned .q21-r .q21-doc-b.is-zoomable + .q21-doc-s.is-ok { color: var(--motm-grey-600); }
/* The admission gets no colour of its own beyond the room's warn tone — it is a gap in OUR record,
   the same register the section-4 gap box uses, not an alarm about the client's books. */
.q21-card.is-reasoned .q21-r .q21-doc-b.is-zoomable + .q21-doc-s.is-warn { color: var(--motm-grey-500);
  font-style: italic; }
.q21-card.is-reasoned .q21-doc { background: transparent; border-color: transparent; }
.q21-card.is-reasoned .q21-doc-b.is-zoomable { border: 1px solid var(--brand-line-pale);
  border-radius: 8px; }
/* A pdf frame has no picture to caption, so its sentence sits under the link. */
.q21-doc-cap { display: block; margin-top: 4px; font-size: 12px; line-height: 1.4;
  color: var(--motm-grey-600); }
/* THE SUBSTITUTION NOTICE — a MARK on the tile, the SENTENCE under the row. A `matched` frame
   shows a file the bot did not name, and the reviewer is being asked to confirm it is the right
   one, so amber (this is theirs to act on) rather than the grey of "still coming up". The first
   cut put the whole sentence on the thumbnail as a plate: on a 144px tile it clamped to three
   unreadable lines, covered the photograph it was describing, and ran into the caption overlay.
   A picture and a paragraph cannot share 144 pixels — so the tile carries one glance of amber
   and the words go where there is room for them. */
.q21-doc.is-swapped { border-color: var(--motm-warning); box-shadow: inset 0 2px 0 var(--motm-warning); }
/* Its own row under the tiles, in BOTH layouts .q21-paper takes: flex-wrap by default, and a
   fixed-column grid at data-pics 1-3. flex-basis and grid-column each speak to one of them. */
.q21-swapnotes { flex: 0 0 100%; grid-column: 1 / -1; min-width: 0;
  display: flex; flex-direction: column; gap: 3px; margin-top: 6px; }
.q21-swapnote { font-size: 12px; line-height: 1.45; color: var(--motm-grey-600);
  padding: 2px 0 2px 9px; border-left: 2px solid var(--motm-warning); }

/* WHERE THE BOT DID NOT EXPLAIN ITSELF. Neutral, dashed, quiet — it is a note about a gap in our
   record, and the reviewer still has real work to check above it. Amber or red here would turn
   83 items into 83 alarms about a standard that is days old, which is a way of teaching people to
   scroll past it. */
.q21-unexplained { margin-top: 7px; border: 1px dashed var(--brand-line-pale); border-radius: 8px;
  padding: 6px 10px; font-size: 13px; line-height: 1.45; color: var(--motm-grey-500);
  max-width: 74ch; }

/* Provenance sits ABOVE section 1, because it changes how everything under it should be read. */
.q21-r-prov { margin: 0 0 11px; border-left: 2px solid var(--brand-line-pale); padding-left: 11px;
  font-size: 12.5px; line-height: 1.45; color: var(--motm-grey-500); max-width: 78ch; }
.q21-r-prov span { display: block; margin-top: 3px; font-size: var(--fs-micro); line-height: 1.4;
  color: var(--motm-grey-500); opacity: .85; }

/* ════════════════════════════════════════════════════════════════════════════════════════════
   THE SOURCE LINE, THE CHECKED TABLE, THE VERDICT, THE DRILL   (rebuild 2026-08-09)
   ════════════════════════════════════════════════════════════════════════════════════════════
   Everything below serves one rule: a reviewer must be able to disagree with the bot WITHOUT
   opening QuickBooks. Colour stays court-honest — no --action, no red. Amber (--motm-warning)
   means "our filing is thin", which is a note to us, never an alarm for the owner. */

/* ── the source line ─────────────────────────────────────────────────────────────────────────
   MONOSPACE IS NOT DECORATION. `PL*` has to read as four characters rather than as a word
   somebody typed — that one distinction is what a card got wrong on 8/8 and it cost a re-work
   cycle. The line never wraps prettily and is never folded: it scrolls, so what a reviewer reads
   is exactly what the bank sent, byte for byte. */
.q21-memo-w { margin: 0 0 12px; }
.q21-memo, .cds-memo { background: var(--brand-frost); border: 1px solid var(--brand-line-pale);
  border-left: 3px solid var(--canopy-line); border-radius: 7px; padding: 7px 10px; }
.q21-memo-k, .cds-memo-k { display: block; font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--motm-grey-500); margin-bottom: 3px; }
.q21-memo code, .cds-memo code { display: block; font-family: ui-monospace, SFMono-Regular,
  "SF Mono", Menlo, Consolas, monospace; font-size: 12.5px; line-height: 1.45;
  color: var(--motm-grey-900); white-space: pre; overflow-x: auto; }
.q21-memo-cut, .cds-memo-cut { display: block; margin-top: 4px; font-size: var(--fs-micro);
  color: var(--motm-warning); }
.q21-memo-why { margin-top: 5px; font-size: 13px; color: var(--motm-grey-600); line-height: 1.5; }
/* A borrowed component that arrived WITHOUT its lender is marked, not hidden — see esMemo(). */
.q21-memo.is-orphan { border-left-color: var(--motm-warning); }

/* ── absence is a badge, and it is LOUDER than presence ──────────────────────────────────────
   A card that quietly omits its source line reads exactly like a card that never needed one.
   That indistinguishability IS the defect, so the gap gets weight the filled state does not. */
.q21-miss, .cds-miss { display: inline-block; font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--motm-warning);
  background: color-mix(in srgb, var(--motm-warning) 12%, transparent);
  border: 1px dashed color-mix(in srgb, var(--motm-warning) 45%, transparent);
  border-radius: 5px; padding: 2px 7px; }
.q21-memo-w.is-none { padding: 8px 10px; background: color-mix(in srgb, var(--motm-warning) 5%, transparent);
  border: 1px dashed color-mix(in srgb, var(--motm-warning) 30%, transparent); border-radius: 7px; }

/* ── what I checked: a table, never bullets ─────────────────────────────────────────────────── */
.q21-chk-w { margin-top: 4px; }
.q21-chk { width: 100%; border-collapse: collapse; font-size: 13.5px; line-height: 1.5; }
.q21-chk th { text-align: left; font-size: var(--fs-micro); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--motm-grey-500); border-bottom: 2px solid var(--brand-line-soft);
  padding: 5px 9px 5px 0; white-space: nowrap; }
.q21-chk td { border-bottom: 1px solid var(--brand-line-pale); padding: 7px 9px 7px 0;
  vertical-align: top; color: var(--motm-grey-800); }
.q21-chk td:first-child { width: 52%; }
.q21-chk tr.is-loose td { background: color-mix(in srgb, var(--motm-warning) 4%, transparent); }
.q21-chk .q21-memo { margin-top: 6px; }
.q21-em, .cds-em { color: var(--motm-grey-400); }
.q21-chk-n { margin-top: 7px; font-size: 12.5px; color: var(--motm-grey-600); line-height: 1.5; }
.q21-chk-n b { color: var(--motm-warning); }

/* ── the verdict: three words, and a visible refusal of any fourth ─────────────────────────── */
.q21-verdict { display: inline-block; font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase; border-radius: 5px; padding: 3px 8px; }
.q21-verdict.is-tied { color: var(--signal); background: var(--signal-tint); }
.q21-verdict.is-exc { color: var(--motm-warning);
  background: color-mix(in srgb, var(--motm-warning) 12%, transparent); }
/* "Will not close" is OUR problem, not Craig's — stated plainly in ink, never in alarm colour. */
.q21-verdict.is-open { color: var(--motm-grey-800); background: var(--brand-mist); }
/* A fourth word never ships silently. This is meant to be seen and fixed. */
.q21-verdict.is-refused { color: var(--motm-warning); background: transparent;
  border: 1px dashed var(--motm-warning); text-transform: none; letter-spacing: 0; }
.rps-state { font-size: var(--fs-micro); color: var(--motm-grey-500); margin-left: 8px; }

/* ── review by exception: quiet, and never a nag ────────────────────────────────────────────── */
.q21-since { margin: 0 0 14px; padding: 8px 12px; border-radius: 8px; background: var(--brand-mist);
  border: 1px solid var(--brand-line-pale); font-size: 13px; color: var(--motm-grey-700); }
.q21-since b { color: var(--canopy); font-variant-numeric: tabular-nums; }
.q21-since-n { color: var(--motm-grey-500); }
.q21-since.is-first { color: var(--motm-grey-600); }

.q21-rev { font-size: var(--fs-micro); color: var(--motm-grey-500); }
.q21-rev.is-none { color: var(--motm-grey-400); font-style: italic; }

/* ── the payee, as a door ────────────────────────────────────────────────────────────────────
   A payee we can PROVE against the client's own chart is underlined and clickable. Everything we
   cannot prove stays plain text with no affordance at all — the room never offers a door it
   cannot open, because a dead link on a vendor name teaches a reviewer to stop clicking. */
.q21-payee { font: inherit; color: inherit; background: none; border: 0; padding: 0;
  cursor: pointer; border-bottom: 1px dashed color-mix(in srgb, var(--canopy) 55%, transparent); }
.q21-payee:hover { color: var(--canopy); border-bottom-style: solid; }
.q21-payee.is-pending { border-bottom-color: color-mix(in srgb, var(--motm-grey-400) 70%, transparent); }
.q21-payee.is-unresolved { border-bottom-style: dotted;
  border-bottom-color: color-mix(in srgb, var(--motm-warning) 60%, transparent); }

/* ── the drill panel ─────────────────────────────────────────────────────────────────────────
   A side sheet, not a modal over the card: the reviewer is comparing the drill AGAINST the story
   they were reading, so the story must stay on screen. */
/* Z-INDEX 2100 IS LOAD-BEARING AND HERE IS WHY, because the number looks arbitrary and is not.
   This room does not live in the document flow — it is mounted inside `#fg-portal`, which is
   `position:fixed; z-index:2000`. The panel is appended to <body>, so at the z-index of 60 it
   first shipped with it drew UNDERNEATH the entire room: correct size, correct position, real
   `getBoundingClientRect`, and invisible to a human.

   Every DOM check passed. `open`, `painted` and `onScreen` were all true, because they measure
   geometry and geometry was perfect — the panel was simply behind 2000 units of room. Only a
   screenshot and an `elementFromPoint` at its own centre caught it, which is why the harness now
   asserts the panel is the TOP element and not merely a well-shaped one.

   2100 clears the portal with room to spare and stays far below the app's modal/lightbox tier
   (9600–10070), so a real modal still covers this panel, as it should. */
.q21-dr { position: fixed; top: 0; right: 0; width: min(680px, 94vw); height: 100vh;
  background: var(--brand-wash, #fff); border-left: 1px solid var(--brand-line-soft);
  box-shadow: -8px 0 28px rgba(24, 37, 31, .13); z-index: 2100; overflow-y: auto;
  transform: translateX(100%); transition: transform .18s ease; }
.q21-dr.is-open { transform: translateX(0); }
.q21-dr-h { position: sticky; top: 0; background: var(--brand-wash, #fff); display: flex;
  align-items: baseline; gap: 10px; padding: 16px 20px 12px;
  border-bottom: 1px solid var(--brand-line-pale); }
.q21-dr-t { font-size: 17px; font-weight: 700; color: var(--canopy); }
.q21-dr-c { font-size: var(--fs-micro); color: var(--motm-grey-500); text-transform: uppercase;
  letter-spacing: .07em; }
.q21-dr-x { margin-left: auto; border: 0; background: none; font-size: 22px; line-height: 1;
  color: var(--motm-grey-500); cursor: pointer; padding: 0 2px; }
.q21-dr-b { padding: 14px 20px 40px; }
.q21-dr-k { font-size: var(--fs-micro); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--motm-grey-500); margin: 18px 0 7px; }
/* THE DENOMINATOR IS THE POINT. "3 of 3" is weighable; a bare "100%" hides its own sample size. */
.q21-dr-rule { background: var(--signal-tint); border: 1px solid
  color-mix(in srgb, var(--signal) 30%, transparent); border-radius: 8px; padding: 9px 12px; }
.q21-dr-rule-h { display: block; font-weight: 700; color: var(--canopy); font-size: 14.5px; }
.q21-dr-rule-b { display: block; margin-top: 3px; font-size: 12px; color: var(--motm-grey-600);
  line-height: 1.5; }
.q21-dr-n { margin-top: 8px; font-size: 12.5px; color: var(--motm-grey-600); line-height: 1.55; }
.q21-dr-tw { overflow-x: auto; }
.q21-dr-t { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.q21-dr-t th { text-align: left; font-size: var(--fs-micro); text-transform: uppercase;
  letter-spacing: .06em; color: var(--motm-grey-500); border-bottom: 2px solid var(--brand-line-soft);
  padding: 5px 8px 5px 0; white-space: nowrap; }
.q21-dr-t td { border-bottom: 1px solid var(--brand-line-pale); padding: 6px 8px 6px 0;
  vertical-align: top; }
.q21-dr-amt { font-variant-numeric: tabular-nums; white-space: nowrap; }
.q21-dr-memo { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11.5px; color: var(--motm-grey-700); white-space: pre; }
.q21-drdoor { display: inline-block; font-size: var(--fs-micro); color: var(--canopy);
  border-bottom: 1px solid color-mix(in srgb, var(--canopy) 40%, transparent); white-space: nowrap;
  margin-right: 8px; }
/* A MISSING DOOR IS A STATED FACT (Craig 8/9 12:05), never blank space. */
.q21-drnodoor { display: inline-block; font-size: var(--fs-micro); color: var(--motm-grey-400);
  font-style: italic; }
.q21-dr-a { margin-top: 10px; padding: 10px 12px; border-radius: 8px; background: var(--brand-mist);
  border: 1px solid var(--brand-line-pale); }
.q21-dr-a.is-answered { border-color: color-mix(in srgb, var(--signal) 35%, transparent); }
.q21-dr-a-m { font-size: var(--fs-micro); font-weight: 700; color: var(--motm-grey-600); }
.q21-dr-a-q { margin-top: 5px; font-size: 12.5px; color: var(--motm-grey-600); }
.q21-dr-a-b { margin: 6px 0 6px; padding-left: 10px; border-left: 2px solid var(--canopy-line);
  font-size: 13px; color: var(--motm-grey-900); line-height: 1.5; }
.q21-dr-a-n { margin-top: 5px; font-size: 12.5px; color: var(--motm-grey-500); font-style: italic; }
/* "we could not identify this name" and "this vendor has no past" are different facts. */
.q21-dr-unres { font-size: 14px; color: var(--motm-grey-800); line-height: 1.55; }
.q21-dr-unres b { color: var(--motm-warning); }
.q21-dr-none { font-size: 13.5px; color: var(--motm-grey-600); line-height: 1.6; }
.q21-dr-src { margin-top: 16px; display: flex; flex-wrap: wrap; gap: 6px; }
.q21-dr-src-i { font-size: var(--fs-micro); padding: 2px 7px; border-radius: 4px;
  background: var(--brand-mist); color: var(--motm-grey-600); }
.q21-dr-src-i.is-no_coverage { color: var(--motm-warning); }
.q21-dr-as { margin-top: 12px; font-size: var(--fs-micro); color: var(--motm-grey-400); }

/* The date is one token and must never wrap into three lines to save four pixels. */
.q21-dr-d { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* The door sits under the line it opens (see drillDoors) — it used to be a fifth column and got
   clipped at the panel edge, which is the worst possible thing to clip: the only control here
   whose whole purpose is to be clicked. */
.q21-dr-dw { margin-top: 4px; }
/* The verbatim line may be long. It scrolls inside its own cell rather than widening the table
   past the panel — the line is never truncated, because truncating it is the original defect. */
.q21-dr-t td .q21-dr-memo { display: block; max-width: 100%; overflow-x: auto; }

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   THE DOOR RAIL AND THE EVIDENCE STACK        (Craig's two convictions, 2026-08-09 9:26p)
   ══════════════════════════════════════════════════════════════════════════════════════════════
   "The buttons at the bottom are not clickable into the 149 items for Mission Control or 116 for
   Rangers… you have to go to this other tab."  ·  "I see the receipts… but that's not showing me
   what the transaction looked like in the bank feed and a rationale as to why you chose it."   */

/* ── a count that is a door LOOKS like one, and one that is not must not ────────────────────────
   Craig's affordance law cuts both ways here. Every count in this room now declares itself in the
   markup, and the styling has to make the same declaration to the eye — otherwise the sweep is
   satisfied and the reviewer still cannot tell which numbers will do something. A door gets an
   underline on hover and a pointer; a no-door count gets a dotted underline and a help cursor
   carrying its own reason, so "nothing to open here" is legible without a click that goes
   nowhere. `.q21-cnt-bare` is for a count living inside a sentence or a big numeral, where a
   pill or a border would shout. */
.q21-cnt { font: inherit; color: inherit; }
button.q21-cnt { cursor: pointer; }
button.q21-cnt.q21-cnt-bare { background: none; border: 0; padding: 0; margin: 0;
  border-radius: 3px; text-align: inherit; }
button.q21-cnt.q21-cnt-bare:hover { text-decoration: underline; text-underline-offset: 2px; }
button.q21-cnt.q21-cnt-bare:focus-visible { outline: 2px solid var(--canopy); outline-offset: 2px; }
.q21-cnt.is-none { border-bottom: 1px dotted var(--brand-line-soft); cursor: help; }
.q21-cnt.is-here { border-bottom: 0; }

/* The per-bot tiles. These were three divs; two of them are buttons now and must not read as a
   form — the tile keeps its calm and only gains the underline on hover. */
button.q21-rw-r { display: block; width: 100%; text-align: left; background: none; border: 0;
  padding: 0; font: inherit; }
button.q21-rw-r:hover { text-decoration: underline; text-underline-offset: 2px; }
button.q21-rw-r:focus-visible { outline: 2px solid var(--canopy); outline-offset: 2px; }
.q21-rw-extra { display: block; font-size: var(--fs-micro); color: var(--motm-grey-400);
  line-height: 1.4; margin-top: 2px; }

/* The book row stopped being one big button so its kind counts could become doors of their own
   (a button cannot live inside a button). The row keeps the look it had: the hover belongs to the
   whole row, and the toggle still fills the left of it. */
.q21-ghead { display: flex; align-items: center; gap: 10px; width: 100%; }
.q21-ghead:hover { background: var(--brand-mist); }
.q21-ghead-t { display: flex; align-items: center; gap: 10px; flex: 0 1 auto; min-width: 0;
  background: none; border: 0; font: inherit; text-align: left; cursor: pointer;
  padding: 9px 4px 9px 12px; }
.q21-ghead-t:focus-visible { outline: 2px solid var(--canopy); outline-offset: -2px; }
.q21-gmixes { padding-right: 12px; }
button.q21-gmix { cursor: pointer; }
button.q21-gmix:hover { border-color: var(--canopy-line); background: #fff; }
.q21-gmore { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.q21-gmore-n { font-size: var(--fs-micro); color: var(--motm-grey-400); }

/* WHAT IS NARROWING THE ROOM, AND THE WAY BACK OUT. Doors can set filters with no control of
   their own (a re-check sample, a bot's send-backs, what is new since her last visit) — and a
   filter she cannot see is a filter she cannot clear. Eight hours in a room that quietly stopped
   showing her everything is the failure this strip exists to prevent. */
.q21-active { display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  margin: 0 0 12px; padding: 7px 12px; border-radius: 8px; background: var(--brand-mist);
  border: 1px solid var(--brand-line-pale); font-size: 13px; color: var(--motm-grey-700); }
.q21-active-l { font-size: var(--fs-micro); font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--motm-grey-500); }
.q21-active b { font-variant-numeric: tabular-nums; color: var(--canopy); }
.q21-active-x { margin-left: auto; border: 1px solid var(--brand-line-soft); background: #fff;
  border-radius: 999px; padding: 3px 11px; font: inherit; font-size: 12.5px; cursor: pointer;
  color: var(--canopy); }
.q21-active-x:hover { background: var(--canopy); border-color: var(--canopy); color: #fff; }

/* ── THE LEAD EXHIBIT: the line, as a row ──────────────────────────────────────────────────────
   The bytes keep every rule the source line already had (monospace, never folded, scrolls rather
   than truncates — `PL*` must read as four characters). What is new is the HEAD: the amount and
   the date ride on the same rule as the label, so the block reads as a transaction row rather
   than as a caption under a paraphrase. The amount is tabular and right-aligned because a column
   of figures a reviewer scans all day has to line up. */
.q21-feedline { margin: 0 0 12px; }
.q21-feedline-h { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.q21-feedline-k { font-size: var(--fs-micro); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--motm-grey-500); }
.q21-feedline-amt { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 700;
  font-size: 14.5px; color: var(--motm-grey-900); white-space: nowrap; }
.q21-feedline-when { font-size: var(--fs-micro); color: var(--motm-grey-500); white-space: nowrap; }
.q21-feedline.is-none .q21-feedline-amt { margin-left: auto; }
.q21-feedline-why { margin-top: 5px; font-size: 13px; color: var(--motm-grey-600); line-height: 1.5; }
/* The label is carried by the head above, so the borrowed component's own label is hidden rather
   than blanked. `EvidenceStory.memo` substitutes its own default for an empty label — passing ''
   would print "Source line" a second line under ours — so the shared helper keeps its contract
   untouched and this room hides the duplicate on its own side. */
.q21-feedline .q21-memo-k, .q21-feedline .cds-memo-k { display: none; }

/* THE GAP, SAID ONCE. We do not store the bank's own descriptor — `raw_memo` is the lane's
   Change-Log line, which quotes it more often than not. One coverage sentence, at the top of the
   queue, rather than a badge on 727 cards: this room already learned that a placeholder repeated
   across the queue turns a fact into background noise. */
.q21-feedgap { margin: 0 0 12px; font-size: 12.5px; line-height: 1.5; color: var(--motm-grey-500);
  max-width: 96ch; }

/* ── THE DEBT, WEARING ITS OWN NAME ────────────────────────────────────────────────────────────
   It used to be a Why paragraph reading "The lane gave no reasoning — flagged." — same grey, same
   size, same slot as a real explanation, on two cards in three. It is still deliberately quiet
   (no amber, no red: 655 alarms teach a reader to scroll past), but it is no longer disguised as
   an answer, and it names the bot, because "no reasoning recorded" reads as a gap in this room
   while "Seals did not write down why" reads as a gap in the work. */
.q21-unexplained-k { display: block; font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--motm-grey-500);
  margin-bottom: 2px; }

/* ── THE BOOK DIRECTORY AND ITS PAYEE LIST (8/9 evening) ────────────────────────────────────────
   Craig drilled two books he has worked for months and found nothing, because until tonight the
   only door into a payee's history was its name appearing on an open card — so a book with no open
   work had no doors, and a book with no open work is a book that is going well.

   COURT-HONEST COLOUR. A book that cannot be read is drawn in grey with the word "unreadable" and
   its failing layer, NOT in alarm: eight of forty-three books are dark tonight and eight red rows
   is a wall the reader learns to scroll past. The one place that does carry warning weight is the
   refusal sentence, because that is the rail declining to state its own coverage — one line, once,
   above the list. Alarm stays in Craig's court; this is the fleet reporting on itself. */
.q21-vbooks .q21-cov-d { padding-top: 4px; }
.q21-vb { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 6px;
  margin: 8px 0 10px; }
.q21-vb-i { display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  text-align: left; cursor: pointer; padding: 7px 10px; border-radius: 7px;
  border: 1px solid var(--brand-line-pale); background: var(--brand-wash, #fff); }
.q21-vb-i:hover { border-color: color-mix(in srgb, var(--canopy) 38%, transparent);
  background: var(--brand-mist); }
.q21-vb-n { font-size: 13px; font-weight: 600; color: var(--canopy); line-height: 1.3; }
.q21-vb-m { font-size: var(--fs-micro); color: var(--motm-grey-500);
  font-variant-numeric: tabular-nums; }
.q21-vb-i.is-dark .q21-vb-n { color: var(--motm-grey-500); }
.q21-vb-i.is-dark { background: var(--brand-mist); border-style: dashed; }
.q21-vb-n + .q21-vb-m { margin-top: 1px; }
.q21-vb-refused { font-size: 13px; color: var(--motm-grey-700); line-height: 1.55;
  background: var(--signal-tint); border-left: 3px solid var(--signal);
  border-radius: 0 7px 7px 0; padding: 8px 11px; margin: 6px 0 10px; }
.q21-vb-refused b { color: var(--canopy); }
.q21-vbooks .q21-vb-n:last-child { margin-top: 6px; }

/* The per-book payee list inside the drill panel. Same three states the panel itself draws — a
   pulled answer, a queued one, and one that would not resolve — because a list that flattened them
   would be the "unknown history reads as empty history" failure arriving one level up. */
.q21-dr-bk { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 6px; }
.q21-dr-bk-i { display: flex; flex-direction: column; align-items: flex-start; text-align: left;
  cursor: pointer; padding: 8px 11px; border-radius: 7px; background: var(--brand-wash, #fff);
  border: 1px solid var(--brand-line-pale); }
.q21-dr-bk-i:hover { border-color: color-mix(in srgb, var(--canopy) 38%, transparent);
  background: var(--brand-mist); }
.q21-dr-bk-n { font-size: 13px; font-weight: 600; color: var(--canopy); line-height: 1.3; }
.q21-dr-bk-m { font-size: var(--fs-micro); color: var(--motm-grey-500);
  font-variant-numeric: tabular-nums; }
.q21-dr-bk-i.is-ok { border-left: 3px solid var(--signal); }
.q21-dr-bk-i.is-pend { border-left: 3px dashed var(--brand-line-soft); }
.q21-dr-bk-i.is-unres .q21-dr-bk-n { color: var(--motm-grey-500); }
