/* Blackbar. One stylesheet, no framework, no webfont — the page has to work
   offline from a folder on disk, so everything it needs is in the folder. */

:root {
  --ink: #14161a;
  --ink-soft: #565c66;
  --line: #dfe3ea;
  /* A rule meant to be seen. --line is right for a box's own edge, where
     it is read against the page; between two sections of the same panel it
     is read against white on both sides, and at that contrast the sections
     ran together into one list. */
  --line-strong: #c8d2e2;
  --band: #eef3fb;
  --bg: #f6f7f9;
  --card: #ffffff;
  --accent: #1f6feb;
  --warn: #8a4b00;
  --warn-bg: #fff6e6;
  --danger: #b3261e;
  --radius: 10px;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

/* The page when it has refused to run in a frame. Plain, because whatever is
   holding the frame chose how big this is and nothing here should try to be
   an application inside it. */
.framed {
  max-width: 32rem; margin: 12vh auto; padding: 0 20px;
  font: 15px/1.55 var(--sans); color: var(--ink); text-align: center;
}
.framed h1 { font-size: 18px; margin: 0 0 10px; }
.framed p { color: var(--ink-soft); margin: 0 0 16px; }
.framed a { color: var(--accent); font-weight: 600; }

/* An author `display` beats the user agent's `[hidden] { display: none }`, so
   any element styled with a display value would ignore its own hidden
   attribute. This keeps `hidden` meaning hidden everywhere. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 20px; }

/* ---------- header ---------- */

/* The header is pinned: it is the only thing on screen that says what this
   tool is and that the file is not going anywhere, and a reviewer scrolling a
   hundred-page document should not have to scroll back up to see it. It is
   kept thin for the same reason — pinned space is space the document does not
   get.

   Its height is a variable because three other things are measured from it:
   the padding that stops the page starting underneath it, and the offset and
   height of the sticky panel beside it. */
:root { --top-h: 46px; --front-width: 760px; }

.top {
  position: fixed; top: 0; left: 0; right: 0; z-index: 20;
  background: #0d1117; color: #fff;
}
/* No wrapping: a header that grows a second line no longer matches the space
   reserved for it, and the top of the document disappears behind it. */
.top-inner {
  display: flex; align-items: center; gap: 14px; flex-wrap: nowrap;
  height: var(--top-h);
}
body { padding-top: var(--top-h); }
.mark {
  font-size: 17px; font-weight: 650; letter-spacing: -0.01em;
  display: flex; align-items: center; gap: 8px; flex: none;
}
/* Named, because .bar is also the progress bar in the overlay and the two
   had nothing to do with each other beyond a word. */
.markmark { display: block; width: 26px; height: 15px; flex: none; fill: currentColor; }
.claim {
  margin: 0; color: #9aa4b2; font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
/* Narrow enough that the tagline would crowd the name out of its own bar. */
@media (max-width: 640px) { .claim { display: none; } }

a.mark { color: inherit; text-decoration: none; }
/* The two doors between the tool and its answers, wearing the same coat: the
   header's black, white, bold. In the header it reads as part of the bar; at
   the foot of a white page it is the one dark thing on it, which is where the
   eye goes looking for the way back. */
.top-link, .faqbackbtn {
  font: inherit; font-size: 13px; font-weight: 700;
  background: #0d1117; color: #fff; border: 1px solid #0d1117;
  border-radius: var(--radius); padding: 5px 11px;
  text-decoration: none; cursor: pointer;
}
.top-link:hover, .faqbackbtn:hover { background: #222a35; border-color: #222a35; }
/* The group is pushed right, not each button, or the second one would be
   shoved off on its own. */
.top-actions { margin-left: auto; flex: none; display: flex; gap: 8px; }

/* ---------- drop ---------- */

.view { padding: 28px 0 40px; }

/* The drop box and the cards under it are one column: the box used to run the
   full width of the wrapper while the cards were capped, so its edges sat
   outside theirs. One variable holds the width so they cannot drift apart
   again. */
.drop {
  max-width: var(--front-width); margin-left: auto; margin-right: auto;
  border: 2px dashed var(--line);
  background: var(--card);
  border-radius: 14px;
  padding: 26px 24px;
  text-align: center;
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.drop:hover, .drop:focus-visible, .drop.over { border-color: var(--accent); background: #f2f7ff; outline: none; }
.drop-lead { margin: 0 0 6px; font-size: 20px; font-weight: 600; }
.drop-sub { margin: 0; color: var(--ink-soft); font-size: 14px; }
/* Deliberately quiet. Carrying on from a draft is a thing you do on your
   second visit, and it should not compete with the thing you do on your
   first. */
.drop-faint { margin: 5px 0 0; color: #9aa4b2; font-size: 12.5px; }
.link { color: var(--accent); text-decoration: underline; }

.error {
  color: var(--danger); margin: 14px auto 0; font-weight: 500;
  max-width: var(--front-width);
}

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

/* The tagline names six kinds of document now, so it runs to three lines on a
   laptop. The four cards below it have to stay above the fold at 1366x768 —
   somebody arriving should see what the tool does without scrolling — so the
   air around the hero is tighter than it was rather than the sentence being
   shorter than it should be. */
.hero { max-width: 720px; margin: 4px auto 18px; text-align: center; }
.hero h1 {
  font-size: clamp(28px, 4.4vw, 40px); line-height: 1.12; letter-spacing: -0.022em;
  margin: 0 0 12px; font-weight: 680;
}
.lede { margin: 0; font-size: 15.5px; line-height: 1.5; color: var(--ink-soft); }
.lede em { font-style: normal; color: var(--ink); font-weight: 600; }

.drop-icon { width: 34px; height: 34px; color: var(--ink-soft); margin-bottom: 10px; }
.drop:hover .drop-icon, .drop.over .drop-icon { color: var(--accent); }

/* The same column and the same heading as the section under it, so the front
   page reads as a set of sections rather than as a stack of loose boxes. */
.keyfeatures { margin: 20px auto 0; max-width: var(--front-width); }
/* Tighter than the heading below it, because this one has to earn its room:
   the four cards under it are the last thing above the fold on a 1366x768
   screen, and the suite fails the page if they drop below it. */
.keyfeatures h2 { font-size: 18px; margin: 0 0 2px; }
.features {
  list-style: none; padding: 0; margin: 8px auto 0; max-width: var(--front-width);
  display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.features li {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px 17px;
}
.features h3 {
  margin: 0 0 6px; font-size: 14.5px; font-weight: 650;
  display: flex; align-items: center; gap: 9px;
}
.features .ico {
  flex: none; width: 26px; height: 26px; border-radius: 7px; padding: 4px;
  background: #0d1117; color: #fff;
}
.features p { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); }
.features code {
  font-size: 12px; background: #eef1f6; padding: 1px 4px; border-radius: 4px; color: var(--ink);
}

.busy-line { margin: 0; display: flex; align-items: center; gap: 9px; }

/* Progress, where there is progress to report. A run whose length is not
   known keeps the spinner and shows no bar, rather than showing a bar that
   does not move. */
/* One row per leg of the job. Both are drawn from the start, so the shape of
   the work is visible before it begins — and when a run is paused, which part
   of it got how far. */
.leg { margin-top: 12px; }
.leg-label {
  margin: 0 0 5px; display: flex; align-items: center;
  gap: 0 12px; font-size: 12.5px; font-weight: 500; color: var(--ink-soft);
}
.leg-count { font-variant-numeric: tabular-nums; }

.bar {
  height: 6px; border-radius: 999px;
  background: #e6eaf1; overflow: hidden;
}
/* In the foot, a leg is one line: what is running, then the bar, then the
   page it is on, then the way to stop it. Stacked -- the name above, the bar
   below -- it was two lines per leg in a row that is already the height of a
   button, and on a phone that pushed the buttons off the bottom.
   The label keeps its markup and gives up its box, so the name, the count and
   the stop button become items of the same row as the bar and can be put in
   that order. Rebuilding the row for the foot alone would mean two shapes of
   leg to keep in step, and the dialog's stacked one is right where it is. */
/* A grid, not a row of rows: two legs of one run are two readings of the same
   wait, and bars of different lengths because one is called "Matching words"
   and the other "Searching images" invite a comparison between them that
   means nothing. Three columns -- what is running, the bar, the page it is on
   -- so every bar starts and ends in the same place. */
.runlegs { display: grid; grid-template-columns: max-content 1fr max-content; }
.runlegs .leg {
  margin: 0; display: grid; grid-column: 1 / -1;
  grid-template-columns: subgrid; align-items: center; gap: 10px;
}
.runlegs .leg-label { display: contents; }
/* The row as well as the column. The count is written before the bar in the
   markup -- it belongs to the label -- and auto-placement will not go
   backwards to fill column 2 once column 3 of that row is taken, so the bar
   was landing on a second row of its own. */
.runlegs .leg-label > span:first-child { grid-area: 1 / 1; }
.runlegs .leg .bar { grid-area: 1 / 2; min-width: 60px; }
.runlegs .leg-count { grid-area: 1 / 3; margin-left: 0; }
.bar > i {
  display: block; height: 100%; width: 0;
  background: var(--accent); border-radius: inherit;
  transition: width 140ms linear;
}
.busy-note {
  margin: 12px 0 0; font-size: 12px; line-height: 1.45;
  color: var(--ink-soft); font-weight: 400;
}
#busy-pause { margin-top: 12px; width: 100%; }

/* Places the reader was unsure of. Amber, not red: red is "this will be
   covered", and these are "this might need covering, and nothing has decided
   yet". Using the same colour for both would make a warning look like a
   promise. */
.doubthint { color: #7a4100; }

/* ---------- review ---------- */

.review { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 22px; align-items: start; }
@media (max-width: 900px) { .review { grid-template-columns: 1fr; } }

.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  position: sticky;
  /* Below the pinned header, not underneath it. */
  top: calc(var(--top-h) + 16px);
  max-height: calc(100vh - var(--top-h) - 56px);
  overflow-y: auto;
}
.panel-head {
  /* The file name sits on its own line above the buttons. Side by side, a
     long name and five controls fought over one row and the name lost, being
     the half that was ellipsised away. */
  display: flex; flex-direction: column; align-items: stretch; gap: 8px;
  padding: 12px 14px; border-bottom: 1px solid var(--line-strong);
  position: sticky; top: 0; background: var(--card); z-index: 2;
}
.panel-head h2 {
  font-size: 13.5px; margin: 0; font-weight: 650;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------- the tools ---------- */
/*
   Four icons, joined into one bar: move, mark, undo, open another file.
   They were words before, and words did not fit — a 320px panel against five
   labelled controls meant the row overflowed and the reviewer had to scroll
   sideways to reach the last of them. Icons of a fixed size cannot overflow,
   so the row is sized by construction rather than by hoping the labels stay
   short: four 38px cells is 152px whatever language the tooltips are in.

   Every one keeps its text for a screen reader, and carries a title so the
   pointer explains it too.
*/
.tools { display: flex; flex: none; align-self: flex-start; }
.tool {
  width: 38px; height: 34px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-right-width: 0;
  cursor: pointer;
}
.tool:last-child { border-right-width: 1px; }
.tool:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.tool:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.tool svg {
  width: 19px; height: 19px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Dividers between the three kinds: what dragging does, how big the pages
   are, and the two that do something once. Seamless is not the same as
   undifferentiated. */
#zoom-out, #undo { border-left: 1px solid var(--line); }

/* Not the selected one. Hover is a pseudo-class and beat the attribute
   selector below on specificity, so pointing at the tool already in use
   turned it grey — which reads as deselecting it. */
/* Not the stack: it is two buttons sharing a cell, and greying the cell would
   answer a pointer that is only over one of them. */
.tool:hover:not(:disabled):not([aria-pressed="true"]):not(.toolstack) { background: #eef1f6; }
/* Selected is darkened, not tinted: the reviewer has to be able to tell at a
   glance which of the two dragging means, and a pale highlight on a pale
   panel does not carry that. */
.tool[aria-pressed="true"] {
  background: var(--accent); border-color: var(--accent); color: #fff;
  position: relative; z-index: 1;
}
/* Still blue under the pointer, a shade down: it is already the one in use,
   and the only thing hover has to say is that it is a button. */
.tool[aria-pressed="true"]:hover:not(:disabled) {
  background: #1a5fd0; border-color: #1a5fd0;
}
/* Two buttons in one icon's worth of room: the top half and the bottom half.
   The cell keeps the toolbar's own border and size so the row stays seamless,
   and the halves inside it carry nothing but their arrow. */
/* The stack is a div holding two buttons, so it misses the rounding every
   other icon gets from being a button — which left one square-cornered cell in
   a row of rounded ones. It is stated here rather than inherited.

   overflow keeps a half's hover inside those corners, so the grey follows the
   icon's shape instead of squaring off its outer edge. */
.toolstack {
  flex-direction: column; padding: 0;
  border-radius: 8px; overflow: hidden;
}
.toolstack .half {
  flex: 1; width: 100%; min-height: 0; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; color: inherit; cursor: pointer;
}
.toolstack .half svg { width: 17px; height: 11px; }
.toolstack .half:hover:not(:disabled) { background: #eef1f6; }
.toolstack .half:disabled { color: var(--ink-soft); opacity: .55; cursor: default; }
.toolstack .half:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.tool:disabled { color: var(--ink-soft); opacity: .55; cursor: default; }
.tool:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; z-index: 2; }

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

/* ---------- collapsible sections ---------- */
/*
   The panel used to be one long column of controls, each with a paragraph
   explaining itself. Everything was visible at once and most of it was prose,
   so the part you wanted was always somewhere below the part you did not.
   Sections group it, the explanations moved to the front page, and what is
   left of them hides behind a "?" until asked for.
*/

/* Each section reads as a band rather than as a line in a list.
   The heading sits on its own tint and the body stays white, so the eye is
   given two cues for one boundary — a change of shade and a rule it can
   actually see — without spending the height that gaps between cards would
   cost on a phone. */
.sect { border-bottom: 1px solid var(--line-strong); }
.sect:last-of-type { border-bottom: 0; }
.sect > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; gap: 8px;
  /* Short. A heading bar is a label, and five of them at eleven pixels of
     air top and bottom spent more of a 320px column on saying where things
     are than on the things. */
  padding: 7px 14px; font-size: 13px; font-weight: 600;
  background: var(--band); border-bottom: 1px solid var(--line);
}
/* A shut section is a heading and nothing else, so the rule under it would be
   a line under a line. */
.sect:not([open]) > summary { border-bottom-color: transparent; }
.sect > summary::-webkit-details-marker { display: none; }
.sect > summary::before {
  content: ''; flex: none; width: 7px; height: 7px; margin-right: 1px;
  border-right: 1.6px solid var(--ink-soft); border-bottom: 1.6px solid var(--ink-soft);
  transform: rotate(-45deg); transition: transform .15s;
}
.sect[open] > summary::before { transform: rotate(45deg); }
.sect > summary:hover { background: #e2ebf9; }
/* The title takes only the room its words need, so the mark that explains the
   section sits against it rather than adrift in the middle of the row. What
   grows is the gap after the mark, which puts the count back on the right. */
.s-title { flex: none; }
.sect > summary > .why { margin-right: auto; }
.s-note {
  font-weight: 500; font-size: 11.5px; color: var(--ink-soft);
  background: #eef1f6; border-radius: 20px; padding: 1px 8px;
}
.s-note:empty { display: none; }
.s-note.on { background: #e8f0fe; color: var(--accent); }
/* Even air above and below what a section holds. It was 2px at the top and
   14 at the bottom, from when the heading had more of its own: the box you
   type a word into sat tight under the heading and floated well clear of the
   next one, and the same gap under the last detector read as a missing row. */
.s-body { padding: 10px 14px 11px; }
/* The list of detectors keeps less of it, top and bottom, for the same reason
   its rows are tighter. */
#kindsect .s-body { padding-top: 5px; padding-bottom: 6px; }

/* A hint you ask for rather than one you have to read past. */
.why {
  flex: none; width: 16px; height: 16px; border-radius: 50%; padding: 0;
  /* A shade darker than it was: the headings it sits on carry a tint now,
     and the old grey was nearly the same colour as the band under it. */
  background: #dbe2ec; color: var(--ink-soft); border: 0;
  /* An "i" for information, not a "?" for a question the reviewer is being
     asked. Serif, because a sans-serif lower-case i in a 16px circle is a
     bare stroke and a dot, which reads as a stray mark rather than a letter. */
  font-family: Georgia, "Times New Roman", serif;
  font-size: 11px; font-weight: 700; font-style: italic;
  line-height: 16px; text-align: center;
  cursor: help; margin-left: 6px;
}
.why:hover, .why[aria-expanded="true"] { background: var(--accent); color: #fff; }
.why:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* One shared bubble, positioned from script. A tooltip parented to the
   control it explains gets clipped by the scrolling panel it lives in, so
   this one is a child of <body> and placed in viewport coordinates. */
.tipbubble {
  position: fixed; z-index: 60; max-width: 260px;
  background: #0d1117; color: #fff; font-size: 12.5px; line-height: 1.45;
  padding: 8px 10px; border-radius: 8px;
  box-shadow: 0 6px 20px rgba(9, 14, 24, 0.28);
}

.field { margin-bottom: 16px; }
.field > label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; }
textarea {
  width: 100%; font: 13px/1.5 var(--mono); padding: 8px 9px;
  border: 1px solid var(--line); border-radius: 8px; resize: vertical; background: #fff; color: var(--ink);
}
textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
.hint { margin: 6px 0 0; font-size: 12.5px; color: var(--ink-soft); }
/* Directly under the tools it describes. It used to sit at the foot of the
   panel, below every section, which put the sentence explaining what dragging
   does a long scroll away from the buttons that change it. */
.tip { margin: 0; font-size: 12.5px; color: var(--ink-soft); }

.check { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; margin-top: 10px; }
/* Unless it is the first thing in a section, where the section's own padding
   has already left the air and the two together read as a gap. */
.s-body > .check:first-child { margin-top: 0; }
.check input { margin: 0; flex: none; }

/* Tighter than the sections above it, deliberately. The detectors are a list
   of switches to glance down and mostly leave alone — the reviewer's attention
   belongs to the words they typed and the marks on the page — and rows set at
   reading spacing gave a secondary list the weight of the primary one. */
.kinds { display: flex; flex-direction: column; gap: 0; }
.kind { display: flex; align-items: center; gap: 8px; padding: 2px 6px; border-radius: 7px; cursor: pointer; }
.kind:hover { background: #f2f4f8; }
/* The switch for all of them, reading as the heading of the list rather than
   as another row of it. */
.kindall {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 2px 6px 5px; margin-bottom: 3px; border-bottom: 1px solid var(--line);
  font-size: 12px; color: var(--ink-soft);
}
.kindall input { flex: none; margin: 0; }
.kindall:hover { color: var(--ink); }
.kind input { flex: none; margin: 0; }
.kind .name { flex: 1; font-size: 13px; }
/* The same circle the words and the pictures carry: it answers the same
   question, so it has to look like the same control. Size and shape come from
   the rule they share; only the reset a <button> needs is here. */
.kind .n {
  font: inherit; font-variant-numeric: tabular-nums;
  border: 0; color: var(--ink-soft); background: #eef1f6;
}
.kind .n:not(:disabled) { cursor: pointer; }
.kind .n:disabled { cursor: default; }
.kinds .tally { list-style: none; }

.counts {
  font-size: 12.5px; color: var(--ink-soft);
  border-top: 1px solid var(--line); padding: 12px 14px;
}
.counts strong { color: var(--ink); }
.counts:empty { display: none; }

/* ---------- pages ---------- */

.stage { min-width: 0; }
/* --zoom is what the two magnifier buttons move. The pages are laid out at
   the width of the column and then scaled from there, so zooming is a
   property of the view and never of the canvases: the pixels a redaction is
   measured against do not change when the reviewer leans in. */
.pages {
  display: flex; flex-direction: column; gap: 18px; align-items: flex-start;
  --zoom: 1;
}
.page { width: calc(100% * var(--zoom)); flex: none; }
.page {
  position: relative; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; box-shadow: 0 1px 3px rgba(16, 22, 32, .06);
  /* Notes are placed in shares of the page's width and sized in container
     units, so zooming, a phone turning on its side and a window being dragged
     wider all move them without a line of JavaScript. */
  container-type: inline-size;
}
/* The wrapper owns the shape — its aspect-ratio comes from the page — so a
   canvas that has given up its bitmap does not collapse the document under
   the reviewer's scroll position. */
.page canvas {
  display: block; width: 100%; height: 100%;
  cursor: crosshair; touch-action: none;
}
/* Moving, not marking: the pointer says so before anything is dragged. */
.tool-pan .page canvas { cursor: grab; }
.tool-pan .page canvas:active { cursor: grabbing; }
.page .num {
  position: absolute; top: 8px; left: 8px; background: rgba(13,17,23,.75); color: #fff;
  font-size: 11px; padding: 2px 7px; border-radius: 20px; pointer-events: none;
}

/* ---------- notes written on the page ---------- */

/* The layer itself catches nothing: a press that misses a note is a press on
   the page, and must still pan it or draw a mark. */
.notelayer { position: absolute; inset: 0; pointer-events: none; }

/* A note belongs to its tool. With the tool put away the note is part of the
   page — drawn on it, carried into the export — and not a thing that can be
   picked up, retyped or dragged by a press meant for the document. */
.notechip { pointer-events: none; }
.placing-text .notechip { pointer-events: auto; }
.notechip {
  position: absolute;
  left: calc(var(--x) * 1cqw); top: calc(var(--y) * 1cqw);
  width: calc(var(--w) * 1cqw); min-height: calc(var(--h) * 1cqw);
  font: calc(var(--s) * 1cqw)/1.3 Helvetica, Arial, "Helvetica Neue", sans-serif;
  cursor: move; touch-action: none;
}
/* Nothing is drawn round a note that is not in hand. What is on the page is
   the note, and an outline round every one of them would be a set of boxes
   the reviewer never asked for over a document they are reading. */
.notechip.on { outline: 1px dashed var(--accent); outline-offset: 3px; }

/* The words while they are being typed. Same family, same size, same colour
   as the canvas will paint them in, so the note does not jump when the caret
   leaves it. */
.notewrite {
  display: block; width: 100%; min-height: calc(var(--h) * 1cqw);
  margin: 0; padding: 0; border: 0; outline: 0; resize: none; overflow: hidden;
  background: transparent; color: inherit; font: inherit; letter-spacing: inherit;
}
.notewrite::placeholder { color: currentColor; opacity: .45; }

/* The controls. They exist only while a note is in hand, sit above it, and
   are sized in screen pixels rather than page ones: a note the size of a
   caption and a note the size of a heading need the same buttons. */
.notebar {
  position: absolute; bottom: calc(100% + 8px); left: 0;
  display: flex; align-items: center; gap: 5px; padding: 4px 6px;
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 2px 10px rgba(16, 22, 32, .16);
  font: 12px/1 var(--sans); color: var(--ink); white-space: nowrap;
  cursor: default; touch-action: none;
}
/* A note near the top of the page has no room above it. */
.notechip.low .notebar { bottom: auto; top: calc(100% + 8px); }

.notedot {
  width: 16px; height: 16px; padding: 0; border-radius: 50%;
  border: 1px solid rgba(16, 22, 32, .25); cursor: pointer;
}
.notedot.on { box-shadow: 0 0 0 2px var(--accent); }
.notestep {
  min-width: 24px; height: 22px; padding: 0 5px; cursor: pointer;
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px; font: 12px/1 var(--sans);
}
.notestep:hover { background: var(--line); }
.notebin { color: var(--danger); }

/* The corner that sets how wide the note is, and therefore where its words
   wrap. Only the width: the height is whatever the words need. */
.notegrab {
  position: absolute; right: -5px; bottom: -5px; width: 12px; height: 12px;
  background: var(--accent); border: 2px solid var(--card); border-radius: 50%;
  cursor: ew-resize; touch-action: none;
}

/* Waiting for the tap that says where a note goes. */
.placing-text .page canvas { cursor: text; }

/* A line drawn by hand. The chip is only a place to hang the controls and
   something to press on to choose the line again: the line itself is painted
   on the canvas, by the function that also paints the exported page, so
   nothing here decides how it looks. No outline of its own — the canvas draws
   a dashed box round the chosen one, where it can follow the shape of the
   stroke rather than a rectangle in the layer above it. */
.inkchip {
  position: absolute; pointer-events: none;
  left: calc(var(--x) * 1cqw); top: calc(var(--y) * 1cqw);
  width: calc(var(--w) * 1cqw); height: calc(var(--h) * 1cqw);
  touch-action: none;
}
/* An unchosen line's chip takes no presses: a line is chosen by pressing the
   line itself, on the canvas, where the press can be measured against the
   stroke rather than against the rectangle round it — the rectangle round a
   long diagonal is mostly empty, and it would sit over the page catching
   drags meant for the page. The chosen one is different: it is the handle for
   moving the line, and the cursor says so. */
.inkchip .notebar { pointer-events: auto; }
.inkchip.on { pointer-events: auto; cursor: move; }
/* And the same cursor before the press, over a line the pen is passing over,
   so that "this can be picked up" is known without trying it. */
.inking .page canvas.over-ink { cursor: move; }
/* A ring rather than a crosshair. A crosshair is the cursor for aiming at a
   point, and this is a pen: the ring is roughly the nib, and the dot in the
   middle is where it will land. */
.inking .page canvas {
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><circle cx="12" cy="12" r="8" fill="none" stroke="white" stroke-width="3"/><circle cx="12" cy="12" r="8" fill="none" stroke="black" stroke-width="1.5"/><circle cx="12" cy="12" r="1" fill="black"/></svg>') 12 12, crosshair;
}
/* Thinner and thicker, not smaller and bigger, so the two steps read as one
   control rather than as the note bar's A- and A+. */
.inkbarrow .notestep { min-width: 22px; font-weight: 600; }
/* What the next line will look like, at the size it will be drawn. */
.inkshow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 6px; background: var(--bg);
  border: 1px solid var(--line);
}
.inknib { display: block; border-radius: 50%; }

.textview {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px; margin: 0; font: 13.5px/1.7 var(--mono); white-space: pre-wrap;
  word-break: break-word; max-height: 70vh; overflow: auto;
}
.textview mark { background: #14161a; color: #14161a; border-radius: 2px; }
.textview mark.off { background: #ffe9a8; color: var(--ink); }

/* ---------- export ---------- */

/* Grey rather than white.
   The bar sits over a document that is itself white, and a white bar on a
   white page reads as part of the page until it moves. Grey makes it a
   surface of its own without re-theming everything on it: the blue Redact
   button, the ghosted Export beside it, and the progress bars all keep the
   contrast they were drawn for, which a dark bar would have taken away. */
.exportbar {
  position: sticky; bottom: 0; margin-top: 20px;
  /* The same band the panel's section headings wear. The foot is the other
     heading on the screen -- it says what is happening rather than what is
     where -- and two greys for the two of them read as two unrelated
     surfaces. */
  background: var(--band); border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 12px 16px; display: flex; justify-content: flex-end; align-items: center;
  gap: 16px; flex-wrap: wrap; box-shadow: 0 -2px 10px rgba(16,22,32,.07);
}
/* Everything the foot says, said firmly. It is competing with a document for
   attention and it only ever carries one or two lines. */
.exportbar, .exportbar .hint, .exportbar .leg-label, .exportbar .ranline {
  font-weight: 600;
}
/* The bars' own track was --line, which is nearly the bar's new background:
   an empty progress bar had all but vanished into it. */
.exportbar .leg .bar { background: #dbe1ea; }
/* What is running, reported where the buttons that started it are. It takes
   the left of the row and lets the buttons keep the right. */
.runbar {
  flex: 1 1 260px; min-width: 200px;
  display: flex; align-items: center; gap: 12px;
}
/* The bar itself keeps to the left half of the row. Stretched the whole way
   across it ran up against the buttons, and a progress bar that touches the
   thing it is greying out reads as part of it. */
.runlegs { flex: 0 1 75%; min-width: 0; margin-right: auto; }
.runlegs .leg + .leg { margin-top: 4px; }
/* The finished sentence sits at the start of the bar and takes the room it
   needs: nowrap was right for "Reading 4 of 12" and wrong for a sentence,
   which was being pushed into the middle and then run under the buttons. */
.runbar .hint { margin: 0; margin-right: auto; }
/* What a run says when it is over: one line per run, each with the colour its
   marks wear on the page, so the sentence and the outlines match. */
.ranline { display: flex; align-items: baseline; gap: 7px; }
.ranline + .ranline { margin-top: 3px; }
.randot {
  flex: none; width: 8px; height: 8px; border-radius: 50%;
  position: relative; top: -1px;
}
.randot.green { background: #1a7f37; }
.randot.amber { background: #d98b1f; }
/* A run's own control, beside the name of what is running. Quieter than the
   buttons it shares the bar with: stopping a run is a way out, not the thing
   the reviewer came here to press. */
.runctl {
  flex: none; margin-left: 8px; padding: 0 7px;
  background: transparent; border: 1px solid var(--line-strong);
  border-radius: 999px; color: var(--ink-soft);
  font: inherit; font-size: 10px; font-weight: 500; line-height: 16px;
  white-space: nowrap;
}
/* Beside the bars rather than in the first of them: it belongs to the run,
   which is all of them. Two words on two lines, so it is a square at the end
   of the block instead of a pill whose width comes out of the bars. */
.runbar > .runctl {
  align-self: stretch; margin: 0; padding: 3px 9px;
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 0; border-radius: 8px;
  line-height: 1.25; text-align: center;
}
.runbar > .runctl:hover:not(:disabled) { border-color: var(--ink-soft); color: var(--ink); }
.runctl:hover:not(:disabled) { border-color: var(--ink-soft); color: var(--ink); }
.runctl:disabled { cursor: default; opacity: .7; }
.leg-count { margin-left: auto; }
.runbar .ghost { flex: none; padding: 5px 12px; }
/* The question at the end of the second-check line. A link rather than a
   button: it is the last two words of a sentence, and a bordered control
   there would have been a fourth thing to press in a row of three. */
.checklink {
  background: none; border: 0; padding: 0; margin-left: 4px;
  font: inherit; color: #8a5a10; font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}
.checklink:hover { color: var(--warn); }
@media (max-width: 640px) {
  .runbar { flex-wrap: wrap; }
}
/* Three buttons, each wide enough for the longest thing it ever says, so
   nothing under the pointer moves when a state changes. */
.exportgo { display: flex; align-items: center; gap: 10px; }
.exportgo > button { min-width: 124px; justify-content: center; }

button { font: inherit; cursor: pointer; border-radius: 8px; }
.primary { background: var(--accent); color: #fff; border: 1px solid var(--accent); padding: 9px 18px; font-weight: 600; }
.primary:hover { background: #1a5fd0; }
.primary:disabled { background: #9db8e6; border-color: #9db8e6; cursor: not-allowed; }
.ghost { background: transparent; border: 1px solid var(--line); color: var(--ink-soft); padding: 5px 10px; font-size: 12.5px; }
.ghost:hover { border-color: var(--ink-soft); color: var(--ink); }

/* The one action in the panel that starts something, rather than adjusting
   what is already there, so it does not read as another grey control. */
.accent {
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  font-weight: 600; font-size: 13px; padding: 5px 10px;
}
.accent:hover { filter: brightness(1.08); }
.accent.on, .accent:active { filter: brightness(0.94); }

/* ---------- busy ---------- */

.busy { position: fixed; inset: 0; background: rgba(246,247,249,.86); display: grid; place-items: center; z-index: 20; }
.busy-inner {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px 22px; font-weight: 500; min-width: 260px; max-width: 360px;
}
.spinner { width: 16px; height: 16px; border: 2px solid var(--line); border-top-color: var(--accent); border-radius: 50%; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 2.4s; } }

.foot { padding: 26px 20px 40px; color: var(--ink-soft); font-size: 13px; }
.foot p { margin: 0; max-width: 720px; }
.foot-links {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.foot-links a {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--ink); font-weight: 600; text-decoration: none;
}
.foot-links a:hover { color: var(--accent); text-decoration: underline; }
.ghico { width: 16px; height: 16px; flex: none; }
/* The separator is decoration between two items that wrap independently. */
.foot-sep { color: var(--line); }

/* ---------- terms feedback and image matching ---------- */

/* ---------- adding a word ---------- */
/*
   A one-line box, and the word is added when the reviewer says so rather than
   as they type. The list below is then a list of decisions, not a running
   transcript of the keyboard — which is what a textarea made it, and why the
   tally used to flicker through the matches for every prefix of a name.
*/
.termadd { display: flex; gap: 0; }
.termadd input {
  flex: 1; min-width: 0; font: inherit; font-size: 14px;
  padding: 9px 11px; background: #fff; color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius) 0 0 var(--radius);
}
.termadd input:focus {
  outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent);
  position: relative; z-index: 1;
}
.termadd button {
  flex: none; width: 40px; display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0; margin-left: -1px; cursor: pointer;
}
.termadd button:hover { background: #1a5fd0; }
.termadd button:disabled { background: #b9c3d2; border-color: #b9c3d2; cursor: default; }
.termadd button svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* The same shape as the box you type a word into, because it asks the same
   kind of question — name a thing to redact. A full-width slab of blue said
   "this is the important one", and it is not: most documents are redacted by
   typing. */
.pickrow {
  display: flex; width: 100%; padding: 0;
  background: none; border: 0; cursor: pointer; text-align: left;
}
.pickfield {
  flex: 1; min-width: 0; font-size: 14px; color: var(--ink-soft);
  padding: 9px 11px; background: #fff;
  border: 1px solid var(--line); border-right: 0;
  border-radius: var(--radius) 0 0 var(--radius);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pickgo {
  flex: none; width: 40px; display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.pickgo svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round;
}
.pickrow:hover .pickgo { background: #1a5fd0; }
.pickrow:focus-visible .pickfield { outline: 2px solid var(--accent); outline-offset: -1px; }
/* While picking, the row is the way out of it. */
body.picking .pickfield { color: var(--ink); font-weight: 600; }
/* The plus turns into a cross, and a cross that undoes something is red. In
   black it read as another button in the row rather than the way out. */
body.picking .pickgo { background: var(--danger); border-color: var(--danger); }
body.picking .pickrow:hover .pickgo { background: #8f1d17; border-color: #8f1d17; }
body.picking .pickgo svg { transform: rotate(45deg); }
/* Cancel lives in this section. The heading must not collapse it. */
#imagesect.pick-locked > summary { cursor: default; }
#imagesect.pick-locked > summary:hover { background: var(--band); }
#imagesect.pick-locked > summary::before { opacity: .4; }

/* ---------- picking a logo: everything else gets out of the way ---------- */
/*
   Drawing a box around a logo is the one thing in this tool that happens on
   the document rather than in the panel, and the instruction for it used to be
   a sentence nobody read. Dimming says it instead: what is lit is what you can
   use — the page, and the section you started from.
*/
body.picking::before {
  content: ''; position: fixed; inset: 0; z-index: 40;
  background: rgba(13, 17, 23, 0.55);
}
body.picking .stage,
body.picking #imagesect { position: relative; z-index: 41; }
body.picking #imagesect { background: var(--card); border-radius: var(--radius); }
/* The zoom buttons stay usable while a box is being drawn, so the toolbar has
   to come up through the dimming with the document and the Images section.
   Enabled but under a sheet is not usable. */
/* The head is sticky with a z-index of its own, which makes it a stacking
   context — so raising the toolbar inside it got the toolbar no further than
   the top of the head. The head is what has to come up. */
body.picking .panel-head { z-index: 41; }
body.picking .tools {
  position: relative;
  background: var(--card); border-radius: var(--radius);
}
/* ---------- the sample slide on the front page ---------- */
/*
   Someone deciding whether to trust this with a confidential document should
   be able to see what it produces without handing one over first.
*/
.sample-lede { margin: 0 0 14px; color: var(--ink-soft); line-height: 1.6; font-size: 14px; }
/* ---------- the gallery ----------
   Six slides on a strip that scrolls sideways, each one held as two pictures
   with one of them hidden. Both are in the page rather than swapped by src, so
   the toggle is instant and cannot flash a half-loaded picture at someone who
   is comparing two versions of the same page — which is the whole exercise. */
.gallery { max-width: var(--front-width); margin: 34px auto 0; }
.gallery h2 { font-size: 19px; margin: 0 0 6px; letter-spacing: -0.01em; }

.galtop {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin: 0 0 10px; flex-wrap: wrap;
}
.galswitch {
  display: inline-flex; padding: 3px; gap: 3px;
  background: var(--bg); border: 1px solid var(--line); border-radius: 999px;
}
.galside {
  padding: 5px 14px; border: 0; border-radius: 999px; cursor: pointer;
  background: transparent; color: var(--ink-soft);
  font: 500 13px/1 var(--sans);
}
.galside:hover { color: var(--ink); }
.galside.on { background: var(--card); color: var(--ink); box-shadow: 0 1px 3px rgba(16, 22, 32, .14); }
.galside:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.galnav { display: inline-flex; align-items: center; gap: 8px; }
.galcount { color: var(--ink-soft); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.galarrow {
  width: 30px; height: 30px; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-radius: 50%;
}
.galarrow:hover:not(:disabled) { border-color: var(--ink-soft); }
.galarrow:disabled { opacity: .38; cursor: default; }
.galarrow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.galarrow svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; }

.galstrip {
  display: flex; gap: 14px; margin: 0; padding: 0; list-style: none;
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  /* No bar under the pictures. The arrows and the count above them are the
     control, and a second one along the bottom was a grey line across a
     section whose whole job is to be looked at. Flicking and dragging still
     work; only the bar is gone. */
  scrollbar-width: none; -ms-overflow-style: none;
}
.galstrip::-webkit-scrollbar { width: 0; height: 0; display: none; }
.galstrip:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.galslide { flex: 0 0 100%; scroll-snap-align: center; }
/* Hidden with a class rather than the hidden attribute: both pictures stay in
   the layout's mind, so the strip does not resize as the toggle is used. */
.galimg { display: none; width: 100%; height: auto; }
.galred { display: block; }
.gallery.showing-original .galorig { display: block; }
.gallery.showing-original .galred { display: none; }

.galshot {
  display: block; width: 100%; padding: 0; position: relative;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; cursor: zoom-in;
}
.galshot:hover { border-color: #b9c3d2; }
.galshot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sample-zoom {
  position: absolute; right: 10px; bottom: 10px;
  background: rgba(13, 17, 23, 0.82); color: #fff;
  font-size: 11.5px; padding: 4px 9px; border-radius: 999px;
}
/* The slide is wide and detailed; on a phone it is a thumbnail of itself and
   the point is the tap that makes it big. */
@media (max-width: 640px) {
  .sample-zoom { right: 8px; bottom: 8px; }
  /* Room for a thumb rather than a mouse. */
  .galtop { gap: 8px; }
  .galside { padding: 6px 16px; }
  /* On a phone the row is tight, and a swipe does what the edge arrows do. */
  .bigbar { gap: 6px; }
  .bigbar .galcount { display: none; }
  .bigedge { width: 34px; height: 52px; }
}
@media (prefers-reduced-motion: reduce) { .galstrip { scroll-behavior: auto; } }

/* A width, not a maximum. The overlay centres its box on its contents, and an
   image asked to be 100% of a box that is sizing itself to the image settles
   at whatever the image's own minimum happens to be — which on a wide screen
   left the slide far smaller than the room it had. */
.sampleinner {
  position: relative;
  min-width: 0; width: min(1100px, 96vw); max-width: none;
  max-height: 94vh; overflow-y: auto;
}
.samplestage {
  margin: 0; background: #eef1f6; border: 1px solid var(--line);
  border-radius: var(--radius); padding: 8px; overflow: auto;
  /* Every gesture over the picture is handled in app.js — two fingers zoom,
     one moves it about — so the browser must not claim any of them first. */
  touch-action: none; cursor: grab;
}
.samplestage:active { cursor: grabbing; }

/* The strip's two controls, over the enlarged picture. Left of the close X
   rather than under it, and above the picture rather than beside it, because
   the picture is the dialog and a row of chrome would push it down. */
.bigbar {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 10px;
}
/* The switch on the left, the count and the arrows on the right, the way out
   at the far end — all of it above the slide rather than over it. */
.bigbar .galnav { margin-left: auto; }
/* In the row now, not floating over the picture. */
.bigbar .sample-x { position: static; }
.bigbar .galcount { padding: 4px 8px; }

/* The picture, with a way through the slides at each edge. */
.bigframe { position: relative; min-width: 0; }
.bigedge {
  position: absolute; z-index: 2; top: 50%; transform: translateY(-50%);
  width: 44px; height: 64px; padding: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 10px;
  background: rgba(13, 17, 23, .32); color: #fff;
  opacity: .5; transition: opacity .15s ease, background .15s ease;
}
.bigedge.left { left: 10px; }
.bigedge.right { right: 10px; }
.bigedge:hover { opacity: 1; background: rgba(13, 17, 23, .6); }
.bigedge:focus-visible { opacity: 1; outline: 2px solid #fff; outline-offset: 2px; }
.bigedge:disabled { opacity: 0; pointer-events: none; }
.bigedge svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 2.2; }
/* Over the picture rather than under it: the dialog is the picture now, and a
   row of its own for one button would put the thing being looked at further
   from the middle of the screen. */
.dialog-x,
.sample-x {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  width: 32px; height: 32px; padding: 0;
  flex: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .92); color: var(--ink);
  border: 1px solid var(--line); border-radius: 999px; cursor: pointer;
  box-shadow: 0 1px 4px rgba(16, 22, 32, .18);
}
.dialog-x:hover, .sample-x:hover { background: #fff; border-color: var(--ink-soft); }
.dialog-x:focus-visible, .sample-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dialog-x svg,
.sample-x svg {
  width: 17px; height: 17px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round;
}
/* The whole slide, fitted, and as large as the fingers ask for after that.
   It used to open at a 680px minimum so a laptop could read the small print
   without any way to zoom; now that double-clicking and pinching work
   everywhere, the picture starts whole — which is what someone opening it
   wants to see first — and the width the zoom moves is the only thing that
   changes it. */
#samplebig { display: block; width: var(--big, 100%); height: auto; }

/* On a phone the picture is the screen.
   
   It used to open inside the same white card every other dialog uses, with a
   border, a grey mat and a page-width minimum — so the one thing worth seeing
   arrived smaller than the phone, inside two frames, and had to be dragged
   sideways before any of it could be read. Full width, no card, and the
   fingers do the rest. */
@media (max-width: 900px) {
  #samplebox { padding: 0; }
  /* On a phone the picture is the screen. The row of controls sits above it
     and the picture takes what is left, which is a column — it was a row from
     when the controls floated on top, and with them in flow that laid the bar
     and the slide side by side. */
  .sampleinner {
    width: 100vw; max-width: 100vw; max-height: 100vh;
    padding: 0; border: 0; border-radius: 0; background: transparent;
    display: flex; flex-direction: column; justify-content: center;
  }
  .bigbar {
    margin: 0; padding: 8px 10px;
    background: rgba(255, 255, 255, .92);
  }
  .bigframe { width: 100%; }
  .samplestage {
    width: 100%; max-height: 100vh;
    padding: 0; border: 0; border-radius: 0; background: transparent;
    overflow: auto;
  }
  .dialog-x, .sample-x { top: 12px; right: 12px; }
  .bigbar .sample-x { top: auto; right: auto; }
}

/* What one picked image's search found, under that image's row. */
/* Where this image's bar could stand, as three settings rather than a
   paragraph about where the scores fell. The first is where it stands now and
   is a readout, not an offer; the other two are one press away. The one the
   scores point at is the one in colour. */
/* In the row now, not under it. */
.barwheel { display: flex; gap: 6px; margin: 0; flex-wrap: wrap; }
/* Small enough that three of them, a thumbnail, a tally and a cross all sit
   on one row of a panel three hundred pixels wide. */
.barpip {
  flex: none; width: 46px; height: 46px; padding: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; text-align: center; border-radius: 50%;
  background: var(--card); border: 1px solid var(--line); color: var(--ink);
  font: inherit; cursor: pointer;
}
.barpip b { font: 600 11.5px/1 var(--sans); font-variant-numeric: tabular-nums; }
.barpip i { font: 400 8px/1.1 var(--sans); font-style: normal; color: var(--ink-soft); }
.barpip:hover { border-color: var(--ink-soft); }
.barpip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The one in use. The search puts the bar where the scores point, so this is
   normally the recommendation as well — it is filled rather than outlined, and
   there is nothing to press, so nothing that looks pressable. */
.barpip.now {
  cursor: default;
  border-color: var(--accent); background: rgba(31, 111, 235, .1); color: var(--accent);
}
.barpip.now b, .barpip.now i { color: var(--accent); }
/* And what the scores point at when the bar is somewhere else, because the
   reviewer moved it: outlined, and one press away. */
.barpip.best:not(.now) { border-color: var(--accent); }
.barpip.best:not(.now) b { color: var(--accent); }
.barpip.best:not(.now):hover { background: rgba(31, 111, 235, .07); }

.imgnote {
  list-style: none; margin: -4px 0 8px; padding: 0 2px 0 12px;
  font-size: 11.5px; line-height: 1.45; color: var(--ink-soft);
}
.imgnote.warnhint { margin-left: 12px; padding-left: 10px; color: var(--warn); }

/* ---------- what it is used for ---------- */
/*
   Cards rather than a list, because these are alternatives to each other: a
   reader is looking for the one that describes them, not reading all six.
   Two columns where there is room, one on a phone.
*/
/* The same column as everything else on the front page. It was wider, from
   when it was a grid of six cards that needed the room; as one box it has to
   line up with the gallery under it or the page looks like two pages. */
.uses { margin: 40px auto 0; max-width: var(--front-width); }
.uses h2 { font-size: 20px; margin: 0 0 8px; }
/* One box, five lines. Six cards in a grid read as six things to compare,
   which is not what a list of jobs is: it is one answer to "what do people
   open this for", and a reader should be able to run down it. */
.usegrid {
  list-style: none; margin: 18px 0 0; padding: 4px 6px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
}
.usecard {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 12px; border-top: 1px solid var(--line);
}
.usecard:first-child { border-top: 0; }
.usecard p { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); }
.usecard strong { color: var(--ink); font-weight: 600; }
.useico {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px;
  background: rgba(31, 111, 235, .08); color: var(--accent);
}
.useico svg { width: 17px; height: 17px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* Confirming a pick. The crop is shown big, because the whole point is to see
   what was actually caught — at the size it sits on the page a logo is a few
   dozen pixels and a box a little too wide looks exactly like a box that
   fits. */
/* Never taller than the screen, whatever shape the pick is: the buttons at the
   foot are how the dialog is answered, and a tall pick used to push them off
   the bottom of a phone. */
.cropinner {
  min-width: 0; max-width: min(560px, 94vw);
  max-height: 92vh; overflow-y: auto;
}
.cropstage {
  margin: 10px 0 6px; display: flex; justify-content: center; align-items: center;
  background: #eef1f6; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 8px; overflow: hidden;
}
/* The canvas is sized to fit in script, so nothing here needs to clamp it —
   and a clamp on one side only is what squashed the mark. If one ever applies,
   height: auto keeps the shape. */
#cropview {
  max-width: 100%; height: auto;
  touch-action: none; cursor: crosshair; display: block;
}
#cropsize { margin: 0 0 2px; font-variant-numeric: tabular-nums; }

/* The way out of picking, sitting over the document. Red, because it undoes
   the thing that is happening; above the dimming, because everything dimmed
   is unreachable and this must not be. */
/* Only on a phone. On a laptop the way out of picking is the Cancel in the
   panel, which is right there and never covered — a second cross floating over
   the document was one more thing to explain. */
.pickstop { display: none; }
@media (max-width: 900px) {
.pickstop[data-show="yes"] { display: flex; }
}
.pickstop {
  position: fixed; z-index: 45; top: calc(var(--top-h) + 12px); left: 14px;
  width: 38px; height: 38px; padding: 0;
  align-items: center; justify-content: center;
  background: var(--danger); color: #fff; border: 0; border-radius: 999px;
  box-shadow: 0 2px 10px rgba(13, 17, 23, 0.35);
}
.pickstop:hover { background: #8f1d17; }
.pickstop svg {
  width: 20px; height: 20px; fill: none; stroke: currentColor;
  stroke-width: 2.4; stroke-linecap: round;
}

/* Above the dimming, not under it. A full-size look at a picked image is
   opened from the one section picking leaves lit, and it was being drawn
   behind the very overlay that section is sitting on top of. */
/* Dialogs go above the dimming, not under it. The crop box always opens while
   picking, so without this the button to accept a pick sits behind the sheet
   that picking puts over the page and cannot be pressed at all. */
#imagebox, #cropbox, #passbox { z-index: 60; }

/* A word in the list is a thing the reviewer put there, so it reads as an
   object with a way to take it off, not as a line of text. */
.termcounts li.word {
  background: #f4f6fa; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 6px 6px 6px 11px; margin-bottom: 6px; gap: 8px;
}
.termcounts li.word .t { font-weight: 550; }
.termdrop {
  flex: none; width: 24px; height: 24px; padding: 0; border: 0; background: none;
  color: var(--ink-soft); cursor: pointer; border-radius: 6px; font-size: 16px;
  line-height: 1; display: flex; align-items: center; justify-content: center;
}
.termdrop:hover { background: #e3e8f0; color: var(--ink); }

.termcounts, .templates { list-style: none; margin: 8px 0 0; padding: 0; }
.termcounts li, .templates li {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; padding: 3px 0; color: var(--ink-soft);
}
.termcounts .t, .templates .t { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); }
/* ---------- where a word actually is ---------- */
/*
   The tally is a button: the number answers "how many", and pressing it
   answers "where". Red for what the reading found, amber for what the shape
   check turned up — the same two colours they are drawn in on the page, since
   a mark the reading found and one a matcher guessed at do not deserve equal
   trust.
*/
.termcounts .n:disabled { cursor: default; }
.termcounts button.n, .templates button.n { font: inherit; border: 0; cursor: pointer; }
.templates button.n:disabled, .termcounts .n:disabled { cursor: default; }
.termcounts button.n[aria-expanded="true"] { background: var(--accent); color: #fff; }

/* A list of page numbers is a reference, not reading: it is scanned for the
   one that is wanted and then left. Small and tight, so twenty of them are a
   list to run an eye down rather than a scroll.

   Named for both sections, because .templates li below sets a padding and a
   border and lands later in the file — so the same dropdown under a picked
   image came out taller, with a rule between every page. */
.termcounts li.tally, .templates li.tally { display: block; padding: 0 0 6px; border: 0; }
.tallywhere { list-style: none; margin: 0; padding: 0 0 0 2px; }
/* A row, not a block. The rule below says flex, but this one is the more
   specific of the two and was left saying block, which put the cross on a
   line of its own under the page it belongs to. */
.termcounts .tallywhere li, .templates .tallywhere li {
  display: flex; align-items: center; gap: 2px; padding: 0; border: 0;
}
.tallyspot {
  display: flex; align-items: center; gap: 7px; width: 100%;
  font: inherit; font-size: 11.5px; line-height: 1.25; text-align: left;
  background: none; border: 0; border-radius: 5px;
  padding: 2px 6px; color: var(--ink-soft); cursor: pointer;
}
.tallyspot:hover { background: #eef1f6; color: var(--ink); }
.tallyspot .dot {
  width: 7px; height: 7px; border-radius: 2px; flex: none;
  background: #118a4e;
}
.tallyspot.shape .dot { background: #d98b1f; }
/* A place the check proposed and stood down from: neither a mark nor a
   find, so neither green nor amber. */
.tallyspot.refused .dot { background: transparent; border: 1px solid var(--ink-soft); }
.tallyspot .how { margin-left: auto; font-size: 10.5px; color: var(--ink-soft); }
/* The row holds two controls now: the place, and a way to say no to it. */
.tallywhere li { display: flex; align-items: center; gap: 2px; }
.tallywhere li .tallyspot { flex: 1; min-width: 0; }
.tallydrop {
  flex: none; width: 20px; height: 20px; padding: 0; line-height: 1;
  background: none; border: 0; border-radius: 5px; cursor: pointer;
  color: var(--ink-soft); font-size: 14px;
}
.tallydrop:hover { background: #fdeceb; color: var(--danger); }
.tallydrop:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.termcounts .n, .templates .n {
  font-variant-numeric: tabular-nums; background: #eef1f6;
  border-radius: 20px; padding: 1px 8px; flex: none;
}

/* Circles, and two of them.
   Green is what the reading found, amber what the second check added —
   the same two colours they are drawn in on the page, so the panel and the
   document agree about which is which. A round badge rather than a pill
   because it holds a count, not a label. */
.termcounts .n, .templates .n, .kind .n {
  min-width: 24px; height: 24px; border-radius: 999px;
  padding: 0 6px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 650; box-sizing: border-box;
}
.termcounts .n.dot-green, .templates .n.dot-green, .kind .n.dot-green { background: #e3f3ea; color: #0f6b3d; }
.termcounts .n.dot-shape { background: #fdf0dc; color: #9a5b06; }
.termcounts .n.dot-green:not(:disabled):hover, .templates .n.dot-green:not(:disabled):hover,
.kind .n.dot-green:not(:disabled):hover { background: #cfe9db; }
.termcounts .n.dot-shape:not(:disabled):hover { background: #f7e3c2; }
.termcounts .n.dot-green[aria-expanded="true"], .templates .n.dot-green[aria-expanded="true"],
.kind .n.dot-green[aria-expanded="true"] { background: #118a4e; color: #fff; }
.termcounts .n.dot-shape[aria-expanded="true"] { background: #d98b1f; color: #fff; }
/* The same mark the panel draws, shown inline in the sentence that counts
   them. Not a description of a red circle but the red circle. */
.qmark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 999px;
  background: #fdecea; color: #d92d20; font-weight: 650; font-size: 12px;
  /* Centred on the text it sits in, not hung off the baseline. A fixed
     nudge in pixels is a guess about one font at one size, and it read as a
     mark that had slipped. */
  vertical-align: middle; margin: 0 2px;
}
/* And the line it sits in keeps its height, so the sentence does not jump
   when the mark appears. */
/* Left, and taking the room, so the buttons stay where they are whatever it
   says. It is the same place the report appears after a run. */
#exportnote { line-height: 1.5; margin-right: auto; }
#exportnote:empty { display: none; }

/* A term that matched nothing is the one thing in this panel a reviewer must
   not skim past: it looks identical to a term that worked. */
/* Not "nothing found" but "nothing has looked yet" — red, because it marks
   the one thing on the panel that is not an answer. */
.termcounts .n.unknown, .templates .n.unknown, .kind .n.unknown,
.termcounts .n.dot-green.unknown {
  background: #fdecea; color: #d92d20; font-weight: 650;
}
.termcounts li.none .n.dot-green { background: var(--warn-bg); color: var(--warn); }
.termcounts li.none .t { color: var(--warn); }

/* A card of its own, like a typed word's row: the thumbnail, the settings
   the scores point at, the tally and the way to remove it. Taller than a
   word's row because the settings are circles rather than a number. */
/* The card is the picked image's own row, and only that row. Every li in the
   section was taking the card's background, its border and its 58px of
   height -- including the list of page numbers a tally opens, which turned
   five page references into five cards. Those are the same rows the text
   section draws, and they stay that way. */
.templates li.imgrow {
  background: #f4f6fa; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 6px 6px 6px 8px; margin-bottom: 6px; gap: 7px; min-height: 58px;
}
.templates li.imgrow:last-child { margin-bottom: 0; }
.templates canvas {
  width: 42px; height: 28px; object-fit: contain; flex: none;
  border: 1px solid var(--line); border-radius: 4px; background: #fff;
}
/* The × that drops a picked image. Named, because "the button in the row"
   used to mean this one and now also means the tally beside it and every
   page number in the list it opens — all of which this was quietly
   restyling to 15px. */
.templatedrop {
  border: 0; background: transparent; color: var(--ink-soft);
  font-size: 15px; line-height: 1; padding: 2px 5px; flex: none;
}
.templatedrop:hover { color: var(--danger); }

button.wide { width: 100%; padding: 8px; }
button.wide.on { background: var(--accent); color: #fff; border-color: var(--accent); }

.senshead {
  display: flex; align-items: center; gap: 4px;
  margin: 12px 0 0; font-size: 11.5px; color: var(--ink-soft);
}

/* The bar belongs to one picked image, so it lives on that image's row,
   between the thumbnail that says which image and the tally that says how
   many. It took the caption's place, which was empty: a picture of the logo
   needs no label saying "picked image". */
.rowsens { flex: 1; min-width: 0; display: flex; align-items: center; }

/* While picking, the page invites a different kind of drag. A crosshair, not
   the thick cell cross: the thing being aimed at is a box corner, and the fine
   lines say where it will land. */
.page.picking canvas { cursor: crosshair; }
.page.picking { outline: 2px solid var(--accent); outline-offset: -1px; }

/* A hint that has turned into a warning — a search that found nothing. */
.warnhint {
  background: var(--warn-bg); color: var(--warn);
  border-left: 3px solid #d98b1f; padding: 8px 10px;
  border-radius: 0 6px 6px 0; margin-top: 8px;
}

#undo:disabled { opacity: .45; cursor: not-allowed; }



/* ---------- placeholder labels and the legend ---------- */

.legend { list-style: none; margin: 8px 0; padding: 0; }
.legend li {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 0; border-bottom: 1px solid var(--line);
}
.legend li:last-child { border-bottom: 0; }

.labelinput {
  font: 600 11.5px/1.3 var(--mono);
  width: 118px; flex: none; padding: 4px 6px;
  border: 1px solid var(--line); border-radius: 6px; background: #fff; color: var(--ink);
}
.labelinput:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
.labelinput.edited { border-color: var(--accent); background: #f2f7ff; }

.legend .what {
  flex: 1; min-width: 0; font-size: 12.5px; color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.legend .n {
  flex: none; font-size: 11.5px; font-variant-numeric: tabular-nums;
  background: #eef1f6; border-radius: 20px; padding: 1px 8px; color: var(--ink-soft);
}


code {
  font: 11.5px var(--mono); background: #eef1f6;
  padding: 1px 4px; border-radius: 4px;
}

/* The key download is the one control here that can undo everything the tool
   just did, so it does not look like the others. */
.hint.danger {
  color: var(--danger); background: #fdf2f1;
  border-left: 3px solid var(--danger);
  padding: 8px 10px; border-radius: 0 6px 6px 0; margin-top: 8px;
}
#downloadkey { margin-top: 12px; border-color: #e6c9c6; color: var(--danger); }
#downloadkey:hover { border-color: var(--danger); }

/* ---------- marking up, then redacting ---------- */

/* Redact is the action; Export only becomes the action once it has been run. */
.primary.ghostly {
  background: transparent; color: var(--accent); border-color: #bcd3f5;
}
.primary.ghostly:hover:not(:disabled) { background: #f2f7ff; border-color: var(--accent); }
.primary.ghostly:disabled { background: transparent; color: #9db8e6; border-color: #dbe6f8; }

/* Red while there are still question marks in the panel, which is what the
   button is there to answer. It turns blue for the decision to cover what was
   found, and green once it is covered. */
.primary.hunt { background: #d92d20; border-color: #d92d20; }
.primary.hunt:hover { background: #b42318; border-color: #b42318; }

/* Once applied the button says so in green, and stays pressable: "Redacted" is
   a state the reviewer can step back out of for another look at what a bar is
   covering, not a dead end. */
.primary.done, .primary.done:hover {
  background: #e8f3ec; color: #1a6b3c; border-color: #bfe0cb;
}
.primary.done:hover { background: #d9ebe1; }

.templates .waiting { color: var(--warn); font-style: italic; }

/* A pending mark in a text document mirrors a pending box on a page: outlined
   in green and still readable. */
.textview mark.pending {
  background: rgba(17, 138, 78, .13); color: var(--ink);
  box-shadow: inset 0 0 0 1.5px #118a4e; border-radius: 2px;
}

#sweepbox {
  margin-top: 10px; padding: 10px 11px;
  background: var(--warn-bg); border-left: 3px solid #d98b1f;
  border-radius: 0 var(--radius) var(--radius) 0;
}
#sweepbox .hint { margin: 0 0 8px; }

/* ---------- a near miss, offered as a picture ---------- */
/*
   The check cannot tell a true copy the bar turned away from a lookalike the
   bar was right about: on the benchmark decks the true miss scored lower than
   the false one. A person can tell instantly, but only by looking, so the
   cut-out is the largest thing in the card and the buttons sit under it.
*/
/* Under the word it is about, inside that word's row in the term list. */
.offer {
  margin: 2px 0 4px; padding: 8px 9px 7px;
  background: var(--warn-bg); border: 1px solid #e6cd9a;
  border-left: 3px solid #d98b1f; border-radius: var(--radius);
}
.offerlead {
  margin: 0 0 6px; font-size: 11.5px; line-height: 1.4; color: #6b4a10;
}
.offershot {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: 3px; background: #fff;
}
/* One row: where it is, then yes and no. */
.offerrow { display: flex; align-items: center; gap: 6px; margin-top: 7px; }
.offerwhere {
  flex: 1; min-width: 0; text-align: left;
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: 11px; color: #6b4a10; text-decoration: underline;
  text-underline-offset: 2px; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis;
}
.offerwhere:hover { color: var(--ink); }
.offeryes, .offerno {
  flex: none; width: 30px; height: 26px; padding: 0;
  background: #fff; border: 1px solid var(--line-strong); border-radius: 6px;
  font: inherit; font-size: 14px; line-height: 1; cursor: pointer;
}
.offeryes { color: #1a7f37; }
.offerno { color: var(--danger); }
.offeryes:hover { background: #eaf6ed; border-color: #1a7f37; }
.offerno:hover { background: #fdeceb; border-color: var(--danger); }
.offeryes:focus-visible, .offerno:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}

/* ---------- reviewing: a fixed frame, two scrolling columns ---------- */
/*
   While a document is open the page itself does not scroll. The header and
   the export bar are always where they were, and the panel and the document
   each scroll on their own — so reaching the Redact button never means
   scrolling past the document, and scrolling the document never takes the
   controls away with it.

   The front page is left alone: it is an ordinary page and reads like one.
*/
/* 100dvh, not 100vh.
   On a phone the visible viewport is shorter than 100vh for as long as the
   browser's own bar is showing, so a frame built to 100vh puts its bottom —
   the Search and Export buttons — underneath that bar. The vh line stays as a
   fallback for browsers without dvh. */
body.reviewing { height: 100vh; height: 100dvh; overflow: hidden; }
body.reviewing > main.wrap {
  height: calc(100vh - var(--top-h));
  height: calc(100dvh - var(--top-h));
  display: flex; flex-direction: column; min-height: 0;
}
body.reviewing > footer.foot { display: none; }
body.reviewing #view-review {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
  padding: 18px 0 0;
}
body.reviewing .review { flex: 1; min-height: 0; align-items: stretch; }
body.reviewing .panel {
  position: static; max-height: none; height: 100%;
  overflow-y: auto; overflow-x: hidden;
  /* The room for the scrollbar is always there, whether or not there is a
     scrollbar in it. Expanding a section used to make one appear and pull the
     whole panel a few pixels left, which moved the tally circle out from under
     a finger already on its way to it and onto the X beside it. */
  scrollbar-gutter: stable;
}
body.reviewing .stage {
  height: 100%; overflow: auto;
  /* Room for the shadow the export bar casts, so the last page does not sit
     flush against it. */
  padding-bottom: 4px;
}
body.reviewing .exportbar { position: static; flex: none; margin: 14px 0 18px; }

/* ---------- questions ---------- */
.faqmain { padding: 30px 20px 60px; max-width: 760px; }
.faqtitle { font-size: 30px; letter-spacing: -0.02em; margin: 0 0 6px; }
.faq { border-top: 1px solid var(--line); padding: 20px 0 4px; }
.faq h2 { font-size: 17px; margin: 0 0 8px; letter-spacing: -0.01em; }
.faq p { margin: 0 0 12px; color: var(--ink-soft); line-height: 1.6; }
.faq .ph {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px;
  background: #eef1f6; border-radius: 4px; padding: 1px 5px; color: var(--ink);
}
.faqlink a, .faqback a { color: var(--accent); text-decoration: none; font-weight: 600; }
.faqlink a:hover, .faqback a:hover { text-decoration: underline; }
.faqlink a { display: inline-flex; align-items: center; gap: 7px; }
.faqback { margin-top: 28px; border-top: 1px solid var(--line); padding-top: 20px; }

/* ---------- naming the file on the way out ---------- */
/*
   A file called "Project Falcon - KAG term sheet.pdf" undoes a redaction the
   moment it is attached to an email, and nothing inside the document is to
   blame. So the name is offered for editing before anything is saved, with
   anything that was covered inside the document taken out of it first.
*/
/* Tinted rather than white: it sits on top of a white document, and a white
   card on a white page reads as part of it. */
.nameinner {
  max-width: 460px; text-align: left;
  background: #f4f6fa; border: 1px solid #dfe4ec;
}
/* One shape for all three: a box on the left, the name, and one quiet line
   under it. They were three paragraphs of different lengths, each wrapping
   around its own checkbox and starting in a different place. */
.nameopts {
  margin-top: 16px; border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden;
}
.nameopt {
  display: grid; grid-template-columns: 18px 1fr; gap: 0 10px;
  align-items: start; padding: 11px 13px; margin: 0;
  font-size: 13px; cursor: pointer;
}
.nameopt + .nameopt { border-top: 1px solid var(--line); }
.nameopt:hover { background: var(--band); }
.nameopt input { margin: 2px 0 0; flex: none; }
.nameopt-text { display: block; min-width: 0; }
.nameopt-name { display: block; font-weight: 600; color: var(--ink); }
.namefaint {
  display: block; margin-top: 2px; font-size: 12px; line-height: 1.45;
  color: var(--ink-soft);
}
.nameinput { background: #fff; }
.namehead { margin: 0 0 14px; font-size: 17px; letter-spacing: -0.01em; }
.namelabel { display: block; font-size: 12.5px; color: var(--ink-soft); margin-bottom: 6px; }
.nameinput {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 14px;
  padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--radius);
  background: #fff; color: var(--ink);
}
.nameinput:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
.namego { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; }

/* ---------- asking before something is thrown away ---------- */
/*
   Opening another file discards the one on screen, and unlike a reload the
   browser cannot offer to stop it: nothing is navigating, so beforeunload
   never fires. The tool has to ask for itself.
*/
.confirmbody { margin: 0; color: var(--ink-soft); font-size: 13.5px; line-height: 1.55; }
.primary.danger { background: #d92d20; border-color: #d92d20; }
.primary.danger:hover { background: #b42318; }

/* Reset / load-new dialog: actions stacked full-width so three choices stay
   readable on a phone, with a corner X instead of a Cancel row. */
.confirminner {
  position: relative;
  max-width: 400px;
  width: min(400px, calc(100vw - 32px));
  padding: 22px 22px 20px;
  box-sizing: border-box;
}
.confirminner .namehead { padding-right: 36px; margin-bottom: 10px; }
.confirmgo {
  display: flex; flex-direction: column; gap: 10px;
  margin-top: 18px;
}
/* One question, two answers, read left to right. */
.sweepgo { flex-direction: row; }
.sweepgo .confirm-action { flex: 1; }
/* The colour of what the check finds. */
.primary.amber {
  background: #d98b1f; border-color: #d98b1f; color: #fff;
}
.primary.amber:hover { background: #c07a15; border-color: #c07a15; }
.confirmgo .confirm-action {
  width: 100%; box-sizing: border-box;
  min-height: 44px; justify-content: center; text-align: center;
  font-size: 14px; border-radius: 10px;
}
#confirmreset {
  background: #fff; border: 1px solid var(--line); color: var(--ink);
  order: 1;
}
#confirmreset:hover { border-color: var(--ink-soft); background: #fafbfc; }
#confirmsave { order: 2; }
#confirmyes { order: 3; }

@media (max-width: 900px) {
  .confirminner {
    width: calc(100vw - 24px);
    max-width: none;
    padding: 20px 16px 16px;
    border-radius: 14px;
  }
  .confirmgo { gap: 8px; margin-top: 16px; }
  .confirmgo .confirm-action { min-height: 48px; font-size: 15px; }
}


/* Post-Search offer to run a second check. The way out on the left, the
   thing being offered on the right, where the eye finishes -- these were
   stacked, so the order was set by number rather than by markup, and the
   numbers stayed behind when the two went side by side. */
#sweepofferskip { order: 1; background: #fff; border: 1px solid var(--line); color: var(--ink); }
#sweepoffergo { order: 2; }
#sweepofferskip:hover { border-color: var(--ink-soft); background: #fafbfc; }

/* Long sidebar notes: short summary, full text on expand. */
.sidebar-note-more {
  margin: 0;
  border: none;
  background: transparent;
  padding: 0;
}
.sidebar-note-more > summary {
  cursor: pointer;
  list-style: none;
  color: inherit;
  font: inherit;
  line-height: inherit;
  user-select: none;
}
.sidebar-note-more > summary::-webkit-details-marker { display: none; }
.sidebar-note-more > summary .sidebar-note-toggle {
  display: inline;
  margin-left: 4px;
  text-decoration: underline;
  text-underline-offset: 2px;
  opacity: 0.85;
}
.sidebar-note-more[open] > summary .sidebar-note-toggle::after { content: none; }
.sidebar-note-full { margin-top: 6px; }

/* A draft is a few kilobytes of marks, not the document, so it is worth
   saying what was and was not saved. */
.drafthint {
  margin: 0; font-size: 12.5px; color: var(--accent);
  background: #eef4ff; border-radius: var(--radius); padding: 8px 10px;
}

/* ---------- the picked image, full size ---------- */
/*
   The thumbnail is 42 pixels wide, which is enough to tell two picks apart and
   not enough to check that the right thing was picked. Clicking it shows what
   was actually cut out.
*/
.imageinner { max-width: 560px; text-align: left; background: #f4f6fa; border: 1px solid #dfe4ec; }
.imageframe {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px; display: flex; align-items: center; justify-content: center;
  max-height: 60vh; overflow: auto;
}
#imagefull { max-width: 100%; height: auto; display: block; image-rendering: auto; }
.templates canvas { cursor: zoom-in; }

/* ---------- one thing at a time, on a small screen ---------- */
/*
   Side by side, the panel and the document each got about 300 pixels of a
   844-pixel phone: too little to read a page in and too little to work the
   controls in. So on a narrow screen one of them is open and the other is a
   strip down the side — tapped or swiped to trade places.

   A strip rather than nothing at all, because a pane that vanishes is a pane
   you have to remember is there. The toolbar sits above both, since which
   half is open has no bearing on wanting to undo something or zoom in.
*/
.peek { display: none; }

@media (max-width: 900px) {
  body.reviewing #view-review { padding-top: 12px; }
  body.reviewing .review {
    position: relative; display: flex; gap: 8px;
    grid-template-columns: none;
  }
  body.reviewing .panel, body.reviewing .stage {
    min-width: 0; transition: flex-basis .18s ease;
  }

  /* The open half takes what is left; the shut one is a strip, and its
     contents are clipped rather than reflowed — a panel squeezed to 46 pixels
     would spend the animation rearranging itself. */
  body.reviewing[data-pane="edit"] .panel { flex: 1 1 auto; }
  body.reviewing[data-pane="edit"] .stage { flex: 0 0 46px; overflow: hidden; }
  body.reviewing[data-pane="doc"] .stage { flex: 1 1 auto; }
  body.reviewing[data-pane="doc"] .panel { flex: 0 0 46px; overflow: hidden; }

  /* Nothing inside a shut pane is touchable: the tap belongs to the strip. */
  body.reviewing[data-pane="edit"] .stage > *,
  body.reviewing[data-pane="doc"] .panel > * { pointer-events: none; }

  .peek {
    /* Above the shut pane, not beside it: a page number badge is positioned
       inside that pane and would otherwise show through the strip. */
    display: block; position: absolute; top: 0; bottom: 0; width: 46px; z-index: 3;
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius); cursor: pointer; padding: 0;
    font: inherit; font-size: 12.5px; font-weight: 600; color: var(--ink-soft);
    writing-mode: vertical-rl; text-orientation: mixed;
    display: flex; align-items: center; justify-content: center;
  }
  .peek[hidden] { display: none; }
  .peek:hover { color: var(--ink); background: #eef1f6; }
  #peek-edit { left: 0; }
  #peek-doc { right: 0; }

  /* The toolbar is lifted out of the panel and sits above both halves, so it
     is there whichever one is open. */
  body.reviewing .panel-head.afloat {
    position: static; border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--card); margin-bottom: 10px; flex: none;
  }

  /* Two rows on a phone, not one. Three buttons at their desktop width come
     to more than the screen is wide, so the row was overflowing to the left
     with Search cut in half by the edge — and the report above them kept its
     desktop height whether it said anything or not. Stacked, each part gets
     the width it needs and the bar is as tall as what is in it. */
  .exportbar {
    padding: 10px 12px; gap: 8px; flex-wrap: wrap; align-items: stretch;
  }
  .exportbar > * { flex: 1 1 100%; min-width: 0; }
  .exportbar .exportgo { gap: 8px; display: flex; }
  #exportnote { display: none; }
  /* Equal thirds of whatever the screen is, rather than a fixed width each. */
  .exportgo > button { flex: 1 1 0; min-width: 0; padding: 10px 6px;
    white-space: nowrap; }
  .runbar { flex: 1 1 100%; min-width: 0; }
  .runlegs { flex: 1 1 auto; min-width: 0; }
  /* The report wraps to as many lines as it needs and takes no room when it
     has nothing to say. */
  #runfoot[hidden] { display: none; }
  /* The dot sits on the first line of what it marks. Aligned to the top of a
     sentence that wraps to three lines it reads as a bullet floating above
     its own text; the baseline is the line the reader starts on. */
  .ranline { align-items: baseline; }
  /* Shorter. Three buttons at desktop height, stacked under a two-line
     report, took a third of a phone screen to say what to press next. */
  .exportgo > button { padding: 8px 6px; }

  /* Pinch is how anyone zooms anything on a phone, and on the document it
     means the document. Handing the gesture to the browser zoomed the whole
     app instead — panel, toolbar and header swelling together, with the page
     no more readable than before. The canvas keeps every touch and the
     two-finger one drives the document's own zoom. */
  .page canvas { touch-action: none; }

  /* Room for a thumb. The zoom and tool buttons are 34px on a desktop, which
     is a comfortable click and an awkward tap. */
  .tool { width: 44px; height: 40px; }
  .termadd input, .termadd button { min-height: 44px; }
  .termdrop { width: 32px; height: 32px; }
}

/* ---------- the Organise sheet ---------- */

/* Thumbnails wide enough that a page is recognisable at a glance — which is
   the whole job, since the reviewer is looking for "the one with the chart"
   rather than reading it — and small enough that a deck fits in the panel
   without becoming a second document to scroll. */
.sheet {
  list-style: none; margin: 10px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr));
  gap: 8px;
  max-height: 340px; overflow-y: auto;
}
.sheetpage { position: relative; }
.sheethint {
  display: block; width: 100%; box-sizing: border-box;
  margin: 12px 0 4px;
  padding: 18px 10px;
  text-align: center;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  border: 1px dashed var(--line);
  border-radius: 8px;
  background: #f7f8fb;
  cursor: pointer;
}
.sheethint:hover {
  border-color: var(--ink-soft);
  color: var(--ink);
}
.sheethint:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
body.file-dropping .sheethint {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(31, 111, 235, .06);
}
.sheetpage.just-added .sheetface {
  animation: sheet-in .22s ease-out;
}
@keyframes sheet-in {
  from { transform: scale(.86); opacity: 0; }
  to { transform: none; opacity: 1; }
}
.sheetface {
  display: block; width: 100%; padding: 0; cursor: pointer;
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  overflow: hidden; line-height: 0;
}
.sheetface canvas { width: 100%; height: auto; display: block; }
.sheetface:hover { border-color: var(--ink-soft); }
.sheetpage.picked .sheetface {
  border-color: var(--accent); box-shadow: 0 0 0 2px rgba(31, 111, 235, .25);
}
/* The number sits on the page rather than under it: under it, a grid of
   thumbnails becomes a grid of thumbnails and a grid of numbers. */
.sheetnum {
  position: absolute; left: 4px; bottom: 4px;
  background: rgba(20, 22, 26, .78); color: #fff;
  font-size: 11px; font-weight: 600; line-height: 1;
  padding: 3px 5px; border-radius: 4px; pointer-events: none;
}
.sheetpage.picked .sheetnum { background: var(--accent); }

/* Dragging lives on the grip, not on the page, so that a tap still selects
   and a finger dragged across the sheet still scrolls the panel. */
.grip {
  position: absolute; top: 3px; right: 3px; width: 20px; height: 20px;
  border-radius: 4px; cursor: grab; touch-action: none;
  background: rgba(255, 255, 255, .9); border: 1px solid var(--line);
  background-image: radial-gradient(currentColor 1px, transparent 1px);
  background-size: 5px 5px; background-position: 4px 4px;
  background-repeat: repeat; color: var(--ink-soft);
}
.grip:hover { color: var(--ink); border-color: var(--ink-soft); }
.sheetpage.dragging { opacity: .4; }
.sheetpage.dragging .grip { cursor: grabbing; }
.sheetpage.dropping .sheetface { border-color: var(--accent); border-style: dashed; }

#sheet-picked { margin-top: 8px; font-weight: 500; color: var(--ink); }

/* On a phone the panel is the whole screen when it is showing, so the sheet
   can take more of it and the thumbnails can be bigger than a fingertip. */
@media (max-width: 860px) {
  .sheet { grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); max-height: none; }
  .grip { width: 26px; height: 26px; background-size: 6px 6px; }
}

/* The page in the hand while it is being dragged. Fixed to the viewport and
   out of the way of hit-testing, so the pointer still finds the tile
   underneath it rather than the copy following the cursor. */
.sheetghost {
  position: fixed; left: 0; top: 0; z-index: 90;
  pointer-events: none; will-change: transform;
  width: 96px; line-height: 0;
  border-radius: 6px; overflow: visible;
  filter: drop-shadow(0 8px 18px rgba(20, 22, 26, .28));
}
.sheetghost canvas {
  width: 100%; height: auto; display: block;
  border-radius: 6px; border: 1px solid var(--accent);
  background: #fff;
}
.sheetghost.fileghost {
  width: 40px;
  opacity: 0.55;
  filter: drop-shadow(0 4px 10px rgba(20, 22, 26, .18));
}
.sheetghost.fileghost canvas {
  background: rgba(255, 255, 255, 0.5);
  border-color: rgba(31, 111, 235, 0.7);
}
/* Two pages behind it, so carrying several looks like carrying several. */
.sheetghost.stacked::before, .sheetghost.stacked::after {
  content: ''; position: absolute; inset: 0;
  border-radius: 6px; background: #fff; border: 1px solid var(--line);
  z-index: -1;
}
.sheetghost.stacked::before { transform: translate(4px, 4px) rotate(2deg); }
.sheetghost.stacked::after { transform: translate(8px, 8px) rotate(4deg); }
.ghostcount {
  position: absolute; top: -7px; right: -7px;
  min-width: 20px; height: 20px; padding: 0 5px;
  background: var(--accent); color: #fff; border-radius: 999px;
  font-size: 11px; font-weight: 700; line-height: 20px; text-align: center;
}

/* Nothing on the page should select or auto-scroll while a page is in the
   hand — a drag that highlights half the panel behind it reads as broken. */
body.dragging-page { user-select: none; -webkit-user-select: none; }
body.dragging-page .grip { cursor: grabbing; }
body.file-dropping #organisesect { outline: 2px dashed var(--accent); outline-offset: -2px; }

/* Where it will land: a line standing in the gap between the two pages it
   would go between. A tile that merely changes colour cannot say whether the
   page lands before it or after it, and while dragging that is the only thing
   the reviewer wants to know. */
.dropline {
  position: fixed; left: 0; top: 0; z-index: 89;
  width: 3px; border-radius: 2px;
  background: var(--accent); pointer-events: none;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .75), 0 1px 4px rgba(31, 111, 235, .5);
}
/* A cap at each end, so it reads as an insertion point rather than as a
   border that has appeared on one of the pages. */
.dropline::before, .dropline::after {
  content: ''; position: absolute; left: 50%; width: 9px; height: 3px;
  margin-left: -4.5px; border-radius: 2px; background: var(--accent);
}
.dropline::before { top: 0; }
.dropline::after { bottom: 0; }

/* Holding an icon asks what it is, so the browser must not offer its own
   long-press menu or start selecting text on top of the answer. */
.tool, .tool .half { -webkit-touch-callout: none; touch-action: manipulation; }

/* The hint lives in the section heading now, beside the word it explains,
   rather than as a paragraph above the thumbnails taking room the sheet
   needs. Inside a <summary>, so it must not look like part of the title. */
.sect > summary > .why { margin-left: 6px; }

/* ---------- the Organise section holds the panel still ---------- */
/*
   Opening the sheet used to give a 320-pixel column two scrollbars, one
   inside the other: the reviewer scrolls the outer one looking for more pages
   and arrives at the foot of the panel instead. So while the sheet is open
   the panel stops scrolling and the thumbnails take whatever height is spare,
   which makes them the only thing that can need a scrollbar.

   How much that is, is measured in script rather than declared here. The
   obvious version — a flex column down through the panel — does not survive
   contact with <details>: everything inside one that is not the <summary>
   sits in an anonymous box of the browser's own, so `flex: 1` on the section
   body never makes it a flex item of the section. Measured on a 14-page
   document: the section was 404 pixels tall and its body 697, hanging out of
   the bottom and taking the panel's scrollbar with it.
*/
@media (min-width: 901px) {
  body.organising .panel { overflow: hidden; }
}

/* The five actions as a joined bar, like the one above the document. */
.sheettools { margin-bottom: 10px; }
.sheettools .tool { flex: 1; }
.toolred { color: var(--danger); }
.toolred:hover:not(:disabled) { background: #fdf2f1; color: var(--danger); }

/* The four sections, standing as one line while the sheet has the panel.
   Shaped like the headings it replaces, so it reads as a row of the panel
   rather than as a control that has appeared in the middle of one. */
.sectroll {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 14px; font: inherit; font-size: 13px; font-weight: 600;
  color: var(--ink-soft); text-align: left; cursor: pointer;
  background: var(--band); border: 0; border-bottom: 1px solid var(--line-strong);
  border-radius: 0;
}
.sectroll:hover { background: #e2ebf9; color: var(--ink); }
/* The same chevron the headings carry, pointing the way it points on a shut
   one — because that is what this is: four shut sections in a single row. */
.sectroll::before {
  content: ''; flex: none; width: 7px; height: 7px; margin-right: 1px;
  border-right: 1.6px solid var(--ink-soft); border-bottom: 1.6px solid var(--ink-soft);
  transform: rotate(-45deg);
}

/* ---------- choosing several pages ---------- */
/*
   Entered by holding a thumbnail. A phone has no shift and no ctrl, so
   without this the sheet could select exactly one page and the Keep and
   Remove actions were controls for a job that could not be set up.
*/
.pickedrow {
  display: flex; align-items: center; gap: 8px;
  margin-top: 8px; min-height: 26px;
}
.pickedrow .hint { margin: 0; flex: 1; font-weight: 500; color: var(--ink); }
#choose-done { flex: none; padding: 3px 12px; }

/* The tick sits where the eye already goes for a state — top right, opposite
   the page number — and it is drawn empty rather than absent when unticked,
   so a set of pages reads as a set of choices rather than as some pages
   having sprouted a mark. */
.tick {
  position: absolute; top: 5px; left: 5px;
  width: 17px; height: 17px; border-radius: 50%;
  border: 1.5px solid var(--ink-soft); background: rgba(255, 255, 255, .92);
  pointer-events: none;
}
.sheetpage.picked .tick {
  background: var(--accent); border-color: var(--accent);
}
.sheetpage.picked .tick::after {
  content: ''; position: absolute; left: 4.5px; top: 2px;
  width: 4px; height: 8px; border: solid #fff;
  border-width: 0 2px 2px 0; transform: rotate(45deg);
}
/* While choosing, the grip would be a second thing to aim at in the same
   corner as the tick and a drag nobody meant to start. */
body.choosing .grip { display: none; }
/* Holding a thumbnail must not also offer the browser's own long-press menu
   or start selecting the page number underneath the finger. */
.sheetface { -webkit-touch-callout: none; }
body.choosing { -webkit-user-select: none; user-select: none; }

/* ---------- how it compares ---------- */
/*
   Wider than the rest of the front page, because a five-column table squeezed
   into a 760-pixel column is a table nobody reads. The Blinded column is
   marked out, and every other cell is a plain statement of what that tool
   does — including where it does something this one does not. A comparison
   that only wins is a comparison nobody believes.
*/
.versus { max-width: var(--front-width); margin: 40px auto 0; }
.versus h2 { font-size: 19px; margin: 0 0 6px; letter-spacing: -0.01em; }

/* A table has to be able to overflow somewhere on a narrow screen, and
   sideways inside its own box is better than sideways for the whole page. */
.versus-scroll {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card);
}
/* Short enough cells that five columns fit the same 760-pixel column as the
   rest of the front page. The minimum is what the table needs to stay
   readable rather than what it happens to want: below it, the box scrolls. */
.versus-table {
  border-collapse: collapse; width: 100%; min-width: 640px;
  font-size: 12.5px; line-height: 1.45;
}
.versus-table th, .versus-table td {
  text-align: left; vertical-align: top; padding: 9px 10px;
  border-bottom: 1px solid var(--line);
}
.versus-table tbody tr:last-child th,
.versus-table tbody tr:last-child td { border-bottom: 0; }
.versus-table thead th {
  font-size: 12.5px; font-weight: 650; color: var(--ink-soft);
  background: #f7f9fc; border-bottom: 1px solid var(--line);
  position: sticky; top: 0;
}
/* The row label carries the question, so it reads as one even when the eye is
   halfway across the table. */
.versus-table tbody th {
  font-weight: 600; color: var(--ink); width: 22%; background: #fbfcfe;
}
.versus-table td { color: var(--ink-soft); width: 19.5%; }

/* Ours. Marked by weight rather than by colour: the Blinded column is in the
   full ink the rest of the page uses, and the three peers are a shade back —
   which is the difference the eye reads first, before it reads a word. */
.versus-table .us { color: var(--ink); background: #f2f7ff; }
.versus-table thead th { color: var(--ink-soft); }
.versus-table thead .us { color: var(--ink); background: #e8f0fe; }
/* The mark, at the size of the word beside it, so the column is recognisable
   from across a room and the header still reads as a header. */
.versus-us { display: inline-flex; align-items: center; gap: 7px; }
.versus-us .markmark { width: 20px; height: 11.5px; }
.versus-table tbody td.us { border-left: 1px solid #cfe0fb; border-right: 1px solid #cfe0fb; }
.versus-table tbody tr:last-child td.us { border-bottom: 1px solid #cfe0fb; }

@media (max-width: 820px) {
  .versus { max-width: calc(100vw - 32px); }
}

/* ---------- the foot of the page ---------- */
.foot {
  max-width: var(--front-width); margin: 40px auto 0; padding-bottom: 8px;
  display: flex; align-items: center; justify-content: center;
  gap: 8px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--ink-soft);
}
.foot-name { font-weight: 650; color: var(--ink); }
.foot-dot { color: #c3cbd8; }
/* One of the three is a button, because the questions are a view rather than
   a page, and one is a link out. They have to look like the same thing. */
.footlink {
  font: inherit; color: var(--ink-soft); background: none; border: 0;
  padding: 0; cursor: pointer; text-decoration: underline;
  text-underline-offset: 2px;
}
.footlink:hover { color: var(--accent); }
.footlink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }


/* ---------- the thumb down the side of a long document ---------- */
/*
   A phone's own scrollbar is a hairline that fades in during a flick and
   cannot be caught, so forty pages is forty flicks. This one is the height of
   a finger and says which page it is passing, because a fast way to end up
   somewhere unknown is not faster.

   Sticky inside the scroller rather than fixed to the screen: it belongs to
   the document half, and the foot and the header are not its to cover. The
   zero height with `top` and `align-self` keeps it out of the flow entirely
   -- it is an overlay on the pages, not a column beside them.
*/
.scrub {
  position: sticky; top: 0; z-index: 6;
  height: 0; pointer-events: none;
}
.scrub[hidden] { display: none; }
.scrub-thumb {
  pointer-events: auto; position: absolute; right: 4px; top: 0;
  width: 18px; border-radius: 999px;
  background: rgba(16, 22, 32, .28);
  border: 1px solid rgba(255, 255, 255, .75);
  box-shadow: 0 1px 3px rgba(16, 22, 32, .25);
  touch-action: none; cursor: grab;
}
.scrub-thumb.held, .scrub-thumb:active { background: rgba(16, 22, 32, .55); cursor: grabbing; }
.scrub-thumb:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Beside the thumb, to its left, where the finger holding the thumb is not.
   Translated by half its own height so the number is level with the middle of
   the thumb whatever the number says. */
.scrub-say {
  pointer-events: none; position: absolute; right: 30px; top: 0;
  transform: translateY(-50%);
  padding: 5px 10px; border-radius: 999px; white-space: nowrap;
  background: #0d1117; color: #fff;
  font: 600 12.5px/1.2 var(--sans);
  box-shadow: 0 2px 8px rgba(16, 22, 32, .3);
}
.scrub-say[hidden] { display: none; }
