/* ---------------------------------------------------------------------------
   Peltify — Scan (2026-08-27, third pass on Nick's feedback).

   THE SHAPE. The page's name, one line of status only when there is something
   to act on, then a compact toolbar carrying the primary Scan button and a
   search field on the left with the counted summary and the last-scan stamp on
   the right, then a TABLE.

   WHY A TABLE. Nick's reference is the AWS S3 bucket console: "something about
   this doesn't feel official enough. Doesn't feel trustable." A list of cards
   is a brochure; a header row with sortable columns and a tick in the first
   column is a console. Columns: pick · Platform · Status · Items · a chevron
   that folds the plan open inline.

   FIFTH PASS, 2026-08-27. Nick: the page "feels too childish or not really
   concrete and professional enough. It should feel like a real TOOL that
   performs REAL actions… I want the checkbox to be as big as the actual [row]
   itself. a nice square that's literally on the left side so it can be
   clicked… everything on the scan page to just feel more structured."

   So: the tick cell is a square with a hairline down its right edge and the
   button fills it; Last read folded into the Status cell as a second line
   ("Last scanned Aug 27, 6:14 PM") so a state and its evidence are read
   together; status is plain ink text with a coloured dot rather than a pill;
   the zebra banding is gone (a firm header plus a hairline per row is enough,
   and the banding fought the tick column's hover tint); every edge is a 1px
   hairline.

   SIXTH PASS, 2026-08-27. Nick: "I WANT THE UI of the scan page to be BIG just
   like the brain gallery" and "make the platform down / up arrow be DOWN by
   default."

   The table is now drawn at the gallery's scale rather than a console's: 88px
   rows, a 56px white logo tile carrying the platform's own colour as an inset
   ring (`.bgal-logo`'s exact idea), a 21px/800 name with the route word beside
   it in grey (`.bgal-name`), the two status lines at 14px and 13.5px, the item
   count at 19px/800 hard right (`.bgal-n`), and a round chevron far right
   (`.bgal-chev`). The tick cell grew with the row: 88 tall, 72 wide, the whole
   of it the button. The toolbar's controls went to 44px to match, and the page
   lost its 1120px cap so the rows are as wide as the gallery's are.

   THE CHEVRON POINTS DOWN WHEN THE ROW IS CLOSED, which is every row on a
   freshly opened page, and turns over to point up when it is opened. The glyph
   itself is drawn pointing down, so "closed" needs no transform at all and the
   direction cannot be got the wrong way round; `is-up` is the only rotation in
   the file. The header's sort arrow follows the same rule — ascending, the
   default, points DOWN, the way you read the column.

   WHAT WENT. The sub-line under the title, the trust strip at the foot, the
   allowance line (it belongs in Settings › Billing), and the spinner that used
   to sit on top of the platform logos — "looks ugly as hell". A scan in
   progress spins in the Status cell, next to the word Scanning, where the
   claim it belongs to is.

   THE GATE. With no paired extension Port the page has no browser hand, so the
   whole surface is blurred behind a scrim and a panel says what to install.
   Three rules govern it:
     - It fills `main.surface` — the element the shell draws every view into —
       and nothing else. The rail and the topbar live OUTSIDE `main.surface`,
       so they stay lit and reachable. It is absolute against that box, never
       fixed to the viewport.
     - It is a SIBLING of the blurred element, never a child, because a CSS
       filter becomes the containing block for its positioned descendants and a
       gate inside the blur would be blurred by the thing it is covering.
     - It cannot be dismissed and the page behind it cannot be scrolled. Both
       locks are written with `:has()` against the live gate node, so they lift
       by themselves the moment that node leaves the DOM — the shell clears the
       surface on a view change, and nothing has to remember to undo anything.

   Tokens come from tokens.css; .rise, .fade, .spin, .tick, .pop-scrim and
   .pop-panel come from motion.css. Nothing here redefines them.
   --------------------------------------------------------------------------- */

.scan { position: relative; display: block; min-height: 420px; }

/* NO NARROWER THAN THE GALLERY. `.surface-wide` already caps every view at
   1180px; a second cap here made the scan rows visibly meaner than the Brain
   gallery's, which is the comparison Nick actually made. */
.sc-page {
  display: flex; flex-direction: column; gap: 20px;
}

/* Blurred, inert, and unreadable to a screen reader — because nothing behind
   the gate can be acted on until the extension is there. 13.16: this is the
   platform LIST, not the whole page; the submenus above it stay legible. */
.scx-list.is-blurred {
  filter: blur(7px) saturate(0.75);
  pointer-events: none; user-select: none;
  transition: filter 320ms var(--ease);
}

.sc-sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

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

.sc-head { display: flex; flex-direction: column; gap: 7px; }
.sc-head h2 {
  margin: 0; font-size: 28px; line-height: 1.1; letter-spacing: -0.03em;
  color: var(--ink);
}

/* ONE line of status, and only when there is something to act on. Never two
   claims about one Chrome — that contradiction is the reason this exists. */
.sc-state {
  display: inline-flex; align-items: center; gap: 7px;
  margin: 0; font-size: 12.5px; color: var(--ink-soft);
  align-self: flex-start;
}
.sc-state svg { flex: none; }
.sc-state.is-ok svg { color: var(--ok); }
.sc-state.is-warn { color: var(--warn); }
.sc-state.is-warn svg { color: var(--warn); }
.sc-state.is-idle svg { color: var(--ink-faint); }

/* ---------------------------------------------------------------- the bar --- */

/* A TOOLBAR, NOT A HEADER. Nick, 2026-08-27 (fifth pass): the page "feels too
   childish… It should feel like a real TOOL that performs REAL actions." So the
   controls sit in one band — primary action hard left, search beside it, the
   counted summary and the last-scan stamp hard right — with 1px hairlines
   throughout. Nothing on it is a bubble.

   44px, not 40, since the gallery pass: a 40px control under an 88px row reads
   as a control for a different, smaller page. */
.sc-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 0;
}
.sc-bar-l { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; }
.sc-bar-r {
  display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
  margin-left: auto; flex: none;
}

/* THE PRIMARY BUTTON, TOP-LEFT — the "Create bucket" position. */
.sc-go {
  display: inline-flex; align-items: center; gap: 8px; flex: none;
  height: 44px; padding: 0 20px;
  border: 1px solid var(--violet); border-radius: var(--r-box);
  background: var(--violet); color: #fff;
  font: inherit; font-size: 15px; font-weight: 700; letter-spacing: -0.01em;
  cursor: pointer;
  transition: transform 140ms var(--ease), filter 140ms var(--ease);
}
.sc-go:hover:not(:disabled) { filter: brightness(1.07); }
.sc-go:active:not(:disabled) { transform: scale(0.985); }
.sc-go:disabled {
  background: var(--white); color: var(--ink-faint);
  border-color: var(--line); cursor: not-allowed;
}
.sc-go:disabled svg { opacity: 0.5; }
.sc-go-n {
  display: inline-grid; place-items: center; min-width: 21px; height: 21px;
  padding: 0 6px; border-radius: var(--r-box);
  background: rgba(255, 255, 255, 0.22);
  font-family: var(--font-mono); font-size: 12.5px; font-weight: 700;
}
.sc-go.is-stop { background: var(--coral-dark); border-color: var(--coral-dark); }

.sc-search {
  display: flex; align-items: center; gap: 10px; flex: 1 1 240px;
  min-width: 180px; max-width: 340px;
  padding: 0 14px; height: 44px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--white); color: var(--ink-faint);
  transition: border-color 140ms var(--ease), box-shadow 140ms var(--ease);
}
.sc-search:focus-within {
  border-color: var(--violet);
  box-shadow: 0 0 0 3px var(--violet-wash);
}
.sc-search svg { flex: none; }
.sc-search-in {
  flex: 1 1 auto; min-width: 0; height: 100%;
  border: 0; background: none; outline: none;
  font: inherit; font-size: 15px; color: var(--ink);
}
.sc-search-in::placeholder { color: var(--ink-faint); }

/* The counted summary and the stamp, top-right. Both are arithmetic over what
   is on screen or a moment read off the log — never a rounded impression. */
.sc-tally {
  margin: 0; flex: none;
  font-family: var(--font-mono); font-size: 13px; color: var(--ink-soft);
  letter-spacing: -0.01em; white-space: nowrap;
}
.sc-stamp {
  margin: 0; flex: none; white-space: nowrap;
  font-size: 12.5px; color: var(--ink-faint); letter-spacing: 0.01em;
}
.sc-stamp b { font-family: var(--font-mono); font-weight: 600; color: var(--ink-soft); }

/* -------------------------------------------------------------- the table --- */

.sc-tablewrap {
  border: 1px solid var(--line); border-radius: var(--r-box);
  background: var(--white); overflow-x: auto;
}
.sc-table {
  width: 100%; border-collapse: collapse; table-layout: auto;
  font-size: 15px;
}

/* THE HEADER IS FIRM, and taller than it was: 11.5px uppercase labels on a
   deeper band, a full-weight hairline under it, and an arrow only on the
   column that is actually sorted. */
.sc-th {
  padding: 0; text-align: left; font-weight: 700;
  font-size: 11.5px; letter-spacing: 0.075em; text-transform: uppercase;
  color: var(--ink-faint);
  background: var(--paper-deep, var(--paper));
  border-bottom: 1px solid var(--line-strong);
  white-space: nowrap;
}
.sc-th.is-sorted { color: var(--ink); }
.sc-sort {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 15px 20px;
  border: 0; background: none; font: inherit; color: inherit;
  font-size: inherit; font-weight: inherit;
  letter-spacing: inherit; text-transform: inherit;
  cursor: pointer; text-align: left;
}
.sc-sort:hover { color: var(--violet); }
.sc-sort.is-on { color: var(--ink); }
.sc-sort:focus-visible { outline: 2px solid var(--violet); outline-offset: -3px; }
/* THE GLYPH IS DRAWN POINTING DOWN. Ascending — the direction the table opens
   in — is therefore the untransformed one, so nothing on a freshly opened page
   points up. `is-up` is the only rotation. */
.sc-sort-arrow { display: inline-grid; place-items: center; flex: none; }
.sc-sort-arrow.is-off { opacity: 0; }
.sc-sort-arrow.is-down svg { transform: none; }
.sc-sort-arrow.is-up svg { transform: rotate(180deg); }
/* The Status header carries both of its cell's lines, so the two labels sit
   side by side under one heading with a hairline slash between them. */
.sc-th-sep { color: var(--line-strong); padding: 0 1px; }
.sc-th.sc-c-status .sc-sort { padding-left: 0; padding-right: 0; }
.sc-th.sc-c-status { padding-left: 20px; padding-right: 20px; }
.sc-th-plain { display: inline-block; padding: 15px 20px; }
.sc-th.sc-c-pick { padding: 0; width: 72px; border-right: 1px solid var(--line); }
.sc-th.sc-c-items { text-align: right; }
.sc-th.sc-c-fold { width: 56px; }

/* THE ROW, AT THE GALLERY'S SCALE. 88px, one hairline under it, and a hover
   that tints in the platform's own colour rather than lifting. No zebra: with
   a firm header and a hairline per row, banding was one texture too many and
   it fought the tick column's own tint. */
.sc-row {
  background: var(--white);
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer;
  transition: background 120ms var(--ease);
}
.sc-row:hover { background: color-mix(in srgb, var(--tile-accent, var(--violet)) 5%, var(--white)); }
.sc-row.is-open { background: color-mix(in srgb, var(--tile-accent, var(--violet)) 8%, var(--white)); }
.sc-row.is-soon { color: var(--ink-faint); cursor: default; }
.sc-row.is-hidden, .sc-foldrow.is-hidden { display: none; }
.sc-row td { height: 88px; padding: 10px 20px; vertical-align: middle; }
/* THE SELECTION MARK SITS ON THE TICK, not on the name: the square is what
   was pressed, so the bar that says "this one is in the scan" belongs on its
   own edge. */
.sc-row.is-on td.sc-c-pick { box-shadow: inset 4px 0 0 var(--tile-accent, var(--violet)); }

/* THE TICK IS THE WHOLE CELL (Nick: "I want the checkbox to be as big as the
   actual [row] itself. a nice square that's literally on the left side so it
   can be clicked"). 88 tall by 72 wide, hairline down its right edge, and the
   button fills it edge to edge — the 26px box inside is only what the square
   looks like. */
.sc-row td.sc-c-pick {
  padding: 0; width: 72px; height: 88px;
  border-right: 1px solid var(--line);
}
.sc-check {
  display: grid; place-items: center;
  width: 72px; height: 88px;
  border: 0; background: none; padding: 0; cursor: pointer;
  transition: background 120ms var(--ease);
}
.sc-check:hover:not(:disabled) { background: var(--violet-wash); }
.sc-check:active:not(:disabled) { background: var(--violet-wash-strong); }
.sc-check:disabled { cursor: not-allowed; }
.sc-check:focus-visible { outline: 2px solid var(--violet); outline-offset: -3px; }
.sc-box {
  display: grid; place-items: center; width: 26px; height: 26px;
  border: 2px solid var(--line-strong); border-radius: var(--r-box);
  background: var(--white); color: transparent;
  transition: border-color 140ms var(--ease), background 140ms var(--ease),
              transform 180ms var(--bounce);
}
.sc-check:hover:not(:disabled) .sc-box { border-color: var(--violet); }
.sc-check:disabled .sc-box { border-color: var(--line); background: var(--paper); }
.sc-box svg { opacity: 0; transform: scale(0.4); }
.sc-row.is-on .sc-box { border-color: var(--violet); background: var(--violet); color: #fff; }
.sc-row.is-on .sc-box svg { opacity: 1; transform: none; }
/* THE POP BELONGS TO THE LANDING, NOT TO EVERY REPAINT. `is-newtick` is set
   only on a row that was not ticked on the previous paint, so a scan reporting
   progress five times a second does not flash every tick on the page. */
.sc-row.is-on.is-newtick .sc-box { animation: pop-in 260ms var(--bounce) both; }
.sc-row.is-on.is-newtick .sc-box svg { animation: tick-pop 400ms var(--bounce) both; }

/* THE PLATFORM, AT GALLERY SIZE. A 56px white logo tile wearing the app's own
   colour as an inset ring, then the name at 21px/800 with the one grey route
   word beside it — the same three parts, in the same order and at the same
   weights, as a `.bgal-hd` header. */
.sc-body {
  display: inline-flex; align-items: center; gap: 16px; min-width: 0;
  border: 0; background: none; padding: 0; font: inherit; color: inherit;
  text-align: left; cursor: pointer;
}
.sc-body:focus-visible { outline: 2px solid var(--violet); outline-offset: 4px; border-radius: var(--r-box); }
.sc-logo {
  display: inline-grid; place-items: center; width: 56px; height: 56px; flex: none;
  border-radius: var(--r-art); background: var(--white);
  border: 1px solid var(--line-soft);
  /* The app's own colour, and only as a hairline: a full-bleed brand block
     would make the row belong to Spotify rather than to the person. */
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--tile-accent, var(--violet)) 22%, transparent);
}
.sc-logo img { display: block; width: 34px; height: 34px; border-radius: var(--r-art); }
.sc-who {
  display: inline-flex; align-items: baseline; gap: 10px;
  min-width: 0; flex-wrap: wrap;
}
.sc-name {
  font-size: 21px; font-weight: 800; letter-spacing: -0.02em;
  color: var(--ink); white-space: nowrap;
}
.sc-route {
  flex: none; font-size: 13px; color: var(--ink-soft); white-space: nowrap;
  letter-spacing: 0.005em;
}
.sc-row.is-soon .sc-name { color: var(--ink-faint); }
.sc-row.is-soon .sc-logo { filter: grayscale(1); opacity: 0.55; }

/* THE STATUS COLUMN, TWO LINES. A dot carries the colour, the words stay ink —
   a status is not a coloured pill, and text never wears the data hue. The only
   spinner on this page is the one that replaces the dot. */
.sc-c-status { min-width: 260px; }
.sc-stat-row { display: flex; align-items: center; gap: 12px; }
.sc-stat { display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
.sc-stat b { font-weight: 700; font-size: 15px; color: var(--ink); letter-spacing: -0.01em; }
.sc-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--ink-faint);
}
.sc-stat-spin { flex: none; width: 13px; height: 13px; }
.sc-stat-sub {
  font-size: 13px; color: var(--ink-soft); font-family: var(--font-mono);
  white-space: nowrap;
}
.sc-stat.is-ok .sc-dot, .sc-stat.is-ready .sc-dot { background: var(--ok); }
.sc-stat.is-warn .sc-dot { background: var(--warn); }
.sc-stat.is-bad .sc-dot { background: var(--coral-dark); }
.sc-stat.is-run .sc-dot, .sc-stat.is-run .sc-stat-spin { color: var(--violet); background: var(--violet); }
.sc-stat.is-run .sc-stat-spin { background: none; }
.sc-stat.is-muted .sc-dot, .sc-stat.is-soon .sc-dot { background: var(--line-strong); }
.sc-stat.is-muted b, .sc-stat.is-soon b { color: var(--ink-faint); font-weight: 600; }
.sc-stat-link {
  flex: none;
  border: 0; background: none; padding: 0;
  font: inherit; font-size: 13.5px; font-weight: 700; color: var(--violet);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.sc-stat-link:hover { filter: brightness(1.15); }

/* The second line: when this platform was last read, as a day and a time. */
.sc-last-line {
  display: block; margin-top: 4px;
  font-size: 13.5px; color: var(--ink-soft); white-space: nowrap;
  letter-spacing: 0.005em;
}
.sc-last-line.is-unknown { color: var(--ink-faint); }

/* THE COUNT, HARD RIGHT AND BOLD — `.bgal-n`'s weight, because it is the same
   fact the gallery shows: how much this platform actually gave up. */
.sc-c-items {
  text-align: right; white-space: nowrap;
  font-size: 19px; font-weight: 800; letter-spacing: -0.02em;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.sc-row.is-soon .sc-c-items { color: var(--ink-faint); font-weight: 700; }

/* THE CHEVRON, FAR RIGHT. Drawn pointing DOWN, which is the closed row and
   therefore every row on a page that has just been opened; `is-up` turns it
   over when the plan is folded open. */
.sc-row td.sc-c-fold { padding-left: 0; padding-right: 16px; width: 56px; }
.sc-chev {
  display: grid; place-items: center; width: 36px; height: 36px;
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--ink-faint); border-radius: 50%;
  transition: color 140ms var(--ease), background 140ms var(--ease);
}
.sc-chev:hover { color: var(--ink); background: var(--violet-wash); }
.sc-chev:focus-visible { outline: 2px solid var(--violet); outline-offset: -2px; }
.sc-chev svg { display: block; transition: transform 320ms var(--ease); }
.sc-chev.is-down svg { transform: none; }
.sc-chev.is-up svg { transform: rotate(180deg); }

@media (prefers-reduced-motion: reduce) {
  .sc-chev svg { transition: none; }
}

/* The fold: the plan, and the sentence that explains the row's status. It is
   indented to the name's own column, so a step reads as belonging to the
   platform above it rather than to the table. */
.sc-foldrow {
  border-bottom: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--tile-accent, var(--violet)) 4%, var(--white));
}
.sc-c-foldcell { padding: 0 !important; height: auto !important; }
.sc-fold {
  display: flex; flex-direction: column; gap: 12px;
  padding: 2px 24px 22px 92px;
}
.sc-why { margin: 0; font-size: 14px; color: var(--ink-soft); line-height: 1.55; max-width: 74ch; }
.sc-steplist {
  margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 9px;
}
.sc-steplist li { display: flex; align-items: center; gap: 12px; font-size: 14px; }
.sc-steplist li.is-waiting { color: var(--ink-faint); }
.sc-steplist li.is-failed .sc-step-label { color: var(--coral-dark); }
.sc-steplist li.is-empty .sc-step-label { color: var(--ink-soft); }
.sc-step-label { flex: 1 1 auto; min-width: 0; }
.sc-step-note {
  flex: none; font-size: 12.5px; font-family: var(--font-mono); color: var(--ink-soft);
  padding: 3px 8px; border-radius: var(--r-box); background: var(--paper-deep);
}

.sc-nohits { margin: 0; padding: 6px 2px; font-size: 14px; color: var(--ink-soft); }

/* ------------------------------------------------------------- the notes --- */

.sc-notes { display: flex; flex-direction: column; gap: 4px; }
.sc-note-line { margin: 0; font-size: 12.5px; color: var(--ink-soft); }
.sc-updated { margin: 0; display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ok); }
.sc-updated svg { flex: none; }
.sc-done-cta { margin: 0; display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-soft); }
.sc-done-cta svg { flex: none; color: var(--ok); }
.sc-warn {
  margin: 0; display: flex; align-items: flex-start; gap: 8px;
  padding: 12px 14px; border-radius: var(--r-lg); max-width: 74ch;
  border: 1px solid color-mix(in srgb, var(--warn) 45%, var(--line));
  background: color-mix(in srgb, var(--warn) 8%, var(--white));
  font-size: 13px; line-height: 1.5; color: var(--ink);
}
.sc-warn svg { flex: none; margin-top: 2px; color: var(--warn); }

/* --------------------------------------------------------------- the gate --- */

/* THE WHOLE PAGE, NOT THE TABLE'S BOX. Nick, 2026-08-27: the gate "doesn't
   take up the SCAN PAGE. Its only the box containing all platforms… It should
   be WITHIN the box next to [the rail and the header]… the whole 'page' but
   NOT over the left sidebar / top header." `main.surface` is exactly that
   region, so scan.js parks the gate node there and this positions it against
   it. `.surface` is only made a containing block WHILE a gate is open, so no
   other view inherits the change. */
.surface:has(> .sc-gate.is-open) {
  position: relative;
  overflow: hidden;
  min-height: 0;      /* a grid item's automatic minimum would defeat the clip */
}

/* SCROLL IS LOCKED WHILE THE GATE STANDS. The page behind it is not for
   reading, and a scrim that scrolls off the top is not a gate. Pinning the
   shell to the viewport is what makes `inset: 0` above mean "the visible
   page" rather than "however tall the table happens to be". */
/* 26.1 — NO LONGER. Nick: "The scan page cant scroll if extensions not
   installed … but I cant scroll on it." The gate lives inside the Scan pane
   now (below), which is taller than a laptop window, so the lock left its
   panel half below the fold with no way down. The page scrolls; the panel
   rides along (sticky), and the scrim still swallows every click. */

.sc-gate {
  display: none;
  position: absolute; inset: 0; z-index: 15;   /* under the topbar's 20 */
  justify-items: center; align-content: center;
  padding: clamp(20px, 5vh, 56px) 16px;
  background: rgba(20, 12, 30, 0.30);
  backdrop-filter: blur(2px);
  overflow: auto;
}
/* THE ONLY THING A REPAINT TOUCHES. The node is built once and kept, so the
   two animations below play when the gate genuinely appears and never again —
   they used to replay on every engine poll, which is the flicker Nick saw. */
.sc-gate.is-open {
  display: grid;
  animation: fade-in 240ms var(--soft) both;
}
.sc-gate-panel {
  width: min(520px, 100%);
  display: flex; flex-direction: column; gap: 13px;
  padding: 30px;
  border-radius: var(--r-xl); background: var(--white);
  box-shadow: var(--raise-hi);
  animation: sheet-in 380ms var(--bounce) both;
  text-align: left;
}
.sc-gate-mark {
  display: inline-grid; place-items: center; width: 44px; height: 44px;
  border-radius: var(--r-box); background: var(--violet-wash); color: var(--violet);
}
.sc-gate-panel h3 { margin: 0; font-size: 22px; letter-spacing: -0.025em; }
.sc-gate-panel p { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-soft); max-width: 52ch; }

.sc-gate-links { display: flex; flex-direction: column; gap: 9px; margin-top: 2px; }
.sc-gate-link {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 14px 18px;
  border: 1.5px solid var(--line); border-radius: var(--r-lg);
  background: var(--paper); color: var(--ink); text-decoration: none;
  font-size: 14.5px; font-weight: 600;
  transition: border-color 180ms var(--ease), transform 180ms var(--bounce),
              box-shadow 180ms var(--ease);
}
.sc-gate-link:hover {
  border-color: var(--violet); transform: translateY(-2px); box-shadow: var(--raise);
}
.sc-gate-soon {
  flex: none; padding: 3px 9px; border-radius: var(--r-box);
  background: var(--violet-wash); color: var(--violet);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
}
.sc-gate-foot { font-size: 12px !important; color: var(--ink-faint) !important; }

/* ------------------------------------------------------------- the popups --- */

.scan-pop { padding: 22px; display: flex; flex-direction: column; gap: 16px; }
.scan-pop-h { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.scan-pop-h h3 { margin: 0; font-size: 19px; letter-spacing: -0.02em; }
.scan-pop-sub { margin: 5px 0 0; font-size: 13px; color: var(--ink-soft); max-width: 52ch; line-height: 1.5; }
.scan-pop-note { margin: 0; font-size: 12.5px; color: var(--ink-soft); }

/* --------------------------------------------------------- the app detail --- */

.scan-detail-top { display: flex; align-items: center; gap: 12px; }
.scan-detail-t { display: flex; flex-direction: column; gap: 2px; margin-right: auto; min-width: 0; }
.scan-detail-t b { font-size: 15px; }
.scan-detail-note { font-size: 12.5px; color: var(--ink-soft); }
.scan-detail-note.is-ok { color: var(--ok); }
.scan-detail-note.is-bad { color: var(--coral); }
.scan-detail-note.is-warn { color: var(--warn); }

.scan-chip-login {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 16px; border: 0; border-radius: var(--r-box);
  background: var(--violet); color: #fff; font: inherit; font-size: 12.5px;
  font-weight: 600; cursor: pointer;
  transition: filter 160ms var(--ease);
}
.scan-chip-login:hover { filter: brightness(1.08); }

.scan-plan { border: 1px solid var(--line); border-radius: var(--r-lg); padding: 14px 16px; background: var(--paper); }
.scan-plan-h { margin: 0 0 10px; font-size: 12px; text-transform: uppercase;
               letter-spacing: 0.08em; color: var(--ink-soft); font-weight: 600; }
.scan-plan-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 9px; }
.scan-plan-list li { display: flex; align-items: center; gap: 10px; font-size: 13.5px; }
.scan-plan-list li.is-waiting { color: var(--ink-soft); }
.scan-plan-list li.is-failed .scan-plan-label { color: var(--coral); }
.scan-plan-label { flex: 1 1 auto; min-width: 0; }
.scan-plan-note { font-size: 11.5px; color: var(--ink-soft); flex: none; }
.scan-step-wait {
  display: inline-block; width: 14px; height: 14px; border-radius: 50%;
  border: 2px dashed var(--line-strong); flex: none;
}
.scan-step-x {
  display: inline-grid; place-items: center; width: 16px; height: 16px;
  border-radius: 50%; background: var(--coral); color: #fff; flex: none;
  animation: pop-in 300ms var(--bounce) both;
}
/* A step that ran but read nothing: an amber ring with a dash — distinct from
   the green ✓ (a real read) and the red ✗ (a failure). Honesty, [AGENT-8]. */
.scan-step-empty, .sc-step-empty {
  display: inline-grid; place-items: center; width: 16px; height: 16px;
  border-radius: 50%; border: 2px solid var(--warn); flex: none;
  position: relative;
}
.scan-step-empty::before, .sc-step-empty::before {
  content: ""; width: 6px; height: 2px; background: var(--warn); border-radius: 1px;
}

.scan-filed { margin: 0; display: flex; align-items: flex-start; gap: 7px; font-size: 13px; line-height: 1.5; }
.scan-filed.is-ok { color: var(--ok); }
.scan-filed.is-warn { color: var(--warn); }
.scan-filed svg { flex: none; margin-top: 2px; }

.scan-why { margin: 0; font-size: 13px; color: var(--ink-soft); line-height: 1.55; max-width: 62ch; }

.scan-detail-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding-top: 14px; border-top: 1px solid var(--line);
}
.btn-link.is-danger { color: var(--coral); }

/* -------------------------------------------------------------- responsive --- */

/* UNDER 1000px THE ROW STOPS BEING A ROW OF COLUMNS. Nick, 2026-08-27: "ENSURE
   ALL UI fits in different device sizes (laptop / pc)."

   A five-column table at gallery scale needs about 1000px before the Status
   cell starts squeezing the name. Rather than let it scroll sideways — which
   hides the count and the chevron off the right edge of a laptop — the row
   becomes a small grid: the tick keeps its full-height column on the left, the
   name sits on the first line with the count and the chevron beside it, and the
   two status lines WRAP UNDERNEATH THE NAME. Every value is still on screen and
   nothing overflows.

   The header row goes with it: the column labels no longer line up with
   anything, so they collapse into one strip of sort buttons that still sorts
   the table. Losing sorting on a laptop would have been the worse trade. */
@media (max-width: 1000px) {
  /* `.sc-table tr` would out-specify `.sc-row`, so every selector that changes
     a row's display carries the row's own class. A blanket `tr { display:
     block }` here silently beat the grid below and stacked all five cells. */
  .sc-table, .sc-table > thead, .sc-table > tbody { display: block; }
  .sc-th, .sc-row td, .sc-foldrow td { display: block; }
  .sc-table tr.sc-foldrow { display: block; }
  /* …and for the same reason, the filter's hidden state has to be written at
     the same specificity, or a searched-away row would reappear as a grid. */
  .sc-table tr.sc-row.is-hidden,
  .sc-table tr.sc-foldrow.is-hidden { display: none; }

  .sc-table > thead > tr {
    display: flex; align-items: center; flex-wrap: wrap; gap: 2px;
    padding: 2px 8px;
    background: var(--paper-deep, var(--paper));
    border-bottom: 1px solid var(--line-strong);
  }
  .sc-th { border-bottom: 0; background: none; }
  .sc-th.sc-c-pick, .sc-th.sc-c-fold { display: none; }
  .sc-th.sc-c-status { padding: 0; }
  .sc-th.sc-c-items { text-align: left; }
  .sc-sort, .sc-th-plain { padding: 12px 10px; }

  .sc-table tr.sc-row {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) auto 48px;
    grid-template-areas: "pick name  items fold"
                         "pick status items fold";
    align-items: center;
    column-gap: 12px;
  }
  .sc-row td { height: auto; padding: 0; }
  .sc-row td.sc-c-pick {
    grid-area: pick; width: 64px; height: 100%; align-self: stretch;
  }
  .sc-check { width: 64px; height: 100%; min-height: 80px; }
  .sc-row td.sc-c-name { grid-area: name; padding: 12px 0 0; }
  .sc-row td.sc-c-status { grid-area: status; padding: 2px 0 12px; min-width: 0; }
  .sc-row td.sc-c-items { grid-area: items; padding: 0; text-align: right; width: auto; }
  .sc-row td.sc-c-fold { grid-area: fold; padding: 0 6px 0 0; width: auto; }

  /* The logo shrinks with the row; the name does not, because the name is the
     thing being recognised. */
  .sc-logo { width: 48px; height: 48px; border-radius: var(--r-box); }
  .sc-logo img { width: 28px; height: 28px; }
  .sc-body { gap: 12px; }
  .sc-c-status { min-width: 0; }
  .sc-stat-row { flex-wrap: wrap; row-gap: 4px; }
  .sc-last-line { white-space: normal; }
  .sc-fold { padding: 2px 16px 18px 76px; }
}

@media (max-width: 720px) {
  .sc-head h2 { font-size: 24px; }
  .sc-bar { gap: 10px; }
  .sc-bar-l { flex: 1 1 100%; }
  .sc-search { max-width: none; }
  .sc-bar-r { margin: 0; flex: 1 1 100%; align-items: flex-start; }
  .sc-tally { white-space: normal; }
  .sc-table tr.sc-row { grid-template-columns: 56px minmax(0, 1fr) auto 40px; column-gap: 10px; }
  .sc-row td.sc-c-pick, .sc-check { width: 56px; }
  .sc-logo { width: 44px; height: 44px; border-radius: var(--r-art); }
  .sc-logo img { width: 26px; height: 26px; }
  .sc-name { font-size: 18px; }
  .sc-c-items { font-size: 17px; }
  .sc-fold { padding: 2px 14px 16px 66px; }
  .scan-pop { padding: 18px; }
  .sc-gate { padding: 18px 12px; align-content: start; }
  .sc-gate-panel { padding: 24px; }
}

/* ===========================================================================
   THE CONSOLE — 2026-08-28. Nick: "I don't want it boxed in. I want it to span
   the container box, not floating in the middle. A real list. AWS / Azure
   feel. Strong. Bold and professional. Checkmark box = a solid box with a big
   checkmark within the solid box."
   =========================================================================== */
.sc-page { gap: 14px; }
.sc-bar {
  align-items: flex-end; justify-content: space-between;
  padding: 0 0 12px; border-bottom: 2px solid var(--ink);
}
.sc-bar-l { flex-direction: column; align-items: flex-start; gap: 4px; }
.sc-bar-t { margin: 0; font-size: 26px; font-weight: 800; letter-spacing: -0.03em; color: var(--ink); }
.sc-bar-meta { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.sc-tally, .sc-stamp { margin: 0; font-size: 12px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.sc-stamp b { font-weight: 700; color: var(--ink); }
.sc-bar-r { display: flex; align-items: center; gap: 10px; }
.sc-search { border-radius: var(--r-pill); }
.sc-tablewrap { border-radius: 0; border-left: 0; border-right: 0; width: 100%; }
.sc-table { width: 100%; border-collapse: collapse; }
.sc-th {
  padding: 10px 12px; font-size: 11px; font-weight: 800; letter-spacing: 0.12em;
  color: var(--ink); background: var(--paper);
  border-bottom: 1px solid var(--ink);
}
.sc-row { border-bottom: 1px solid var(--line); }
.sc-row:hover { background: var(--paper); }
.sc-row.is-on { background: color-mix(in srgb, var(--violet) 4%, var(--white)); }
.sc-check { width: 64px; height: 84px; }
.sc-check-all { height: 40px; }
.sc-box {
  width: 28px; height: 28px; border-radius: 2px;
  border: 2px solid var(--ink); background: var(--white); color: transparent;
}
.sc-box svg { width: 20px; height: 20px; stroke-width: 3; }
.sc-check.is-on .sc-box, .sc-check-all.is-on .sc-box {
  background: var(--ink); border-color: var(--ink); color: var(--white);
}
.sc-check-all.is-some .sc-box { background: var(--ink); border-color: var(--ink); color: var(--white); }
.sc-check:hover .sc-box { border-color: var(--violet); }
.sc-logo { border-radius: var(--r-art); border: 1px solid var(--line); }
.sc-name { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; }
.sc-state { font-size: 12.5px; font-weight: 600; color: var(--ink); }
.sc-dot { width: 8px; height: 8px; border-radius: 1px; }
.sc-route, .sc-updated { font-size: 12px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.sc-go { height: 40px; padding: 0 18px; border-radius: var(--r-box); font-size: 14px; }
.sc-chev { border-radius: var(--r-box); }
.sc-foldrow { background: var(--paper); }
.sc-fold { padding: 16px 20px 18px 64px; }
.sc-steplist { counter-reset: none; padding-left: 0; list-style: none; margin: 0; }
.sc-steplist li { display: flex; align-items: baseline; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--line); }
.sc-step-n {
  flex: none; width: 22px; font-size: 11px; font-weight: 800; color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.sc-gate-panel { border-radius: var(--r-box); border: 1px solid var(--ink); }
.scan-sess { display: flex; flex-direction: column; gap: 10px; margin: 10px 0 4px; }
.scan-sess-line { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 13.5px; color: var(--ink); }
.scan-sess-line.is-ok { color: #1f7a3a; }
.scan-sess-line.is-warn { color: #b26a00; }
.scan-sess-out { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.scan-sess-go { height: 38px; padding: 0 16px; border-radius: var(--r-box); }
.scan-sess-note { margin: 0; font-size: 12px; color: var(--ink-faint); }
.scan-sess-alt summary { cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.scan-sess-alt[open] summary { margin-bottom: 8px; }
/* The search field is a field, not a shape of its own: fixed height, never
   stretched by the bar it sits in. */
.sc-bar-r { flex: 0 0 auto; align-self: flex-end; align-items: center; }
.sc-search { height: 40px; max-height: 40px; flex: 0 1 300px; }

/* ===========================================================================
   THE CLASSIC-IT PASS + THE SUBMENUS — 2026-08-30
   (infrastructure/2026-08-29/scan/SPEC.md + SPEC-engine.md).

   Nick: "I was considering going for a more classic side (ON THE SCAN PAGE
   ONLY) to make it feel more trustable and professional … Real classic IT
   font and stuff … Notice how its like 'Name' seperated by clean lines? I
   want everything clean." The reference is Azure Monitor's Virtual Machines
   view: a compact table, hairlines between rows AND columns, a tab strip
   with the search spanning under it — but not as barebones as a VM menu,
   because the platform image icons stay.

   Everything here is scoped under `.scx`, the scan page's own frame, so the
   classic font and the tightened table reach NO other page — that scoping is
   itself a spec line ("the scan page be the ONLY page that has custom and
   different font").
   =========================================================================== */

/* ---- the frame: Settings-shaped, like the Dashboard ---- */
.stg.scx { grid-template-columns: 220px minmax(0, 1fr); }
.stg.scx .stg-pane.scx-pane { max-width: none; grid-template-columns: minmax(0, 1fr); }
.scx {
  /* settings.css re-rounds every `.stg` root for the old Settings look; the
     scan page stays boxy and classic. */
  --r-sm: var(--r-box); --r-md: var(--r-box); --r-lg: 4px; --r-xl: 4px;
  /* THE CLASSIC IT FONT, THIS PAGE ONLY. Azure's own stack leads with Segoe. */
  font-family: "Segoe UI", "Segoe UI Variable Text", Tahoma,
               "Helvetica Neue", Arial, sans-serif;
}
.scx-platforms { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

/* ---- the inner tabs, BELOW the black separator line ---- */
.sc-tabs {
  display: flex; align-items: stretch; gap: 2px;
  border-bottom: 1px solid var(--line);
  margin-top: -2px;              /* sits tight under the bar's black rule */
}
.sc-tab {
  border: 0; background: none; cursor: pointer;
  padding: 9px 14px 8px;
  font: inherit; font-size: 13.5px; font-weight: 600; letter-spacing: 0.002em;
  color: var(--ink-soft);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;           /* the lit rule replaces the strip's hairline */
  transition: color 140ms var(--ease), border-color 140ms var(--ease);
}
.sc-tab:hover { color: var(--ink); }
.sc-tab.is-on { color: var(--violet); border-bottom-color: var(--violet); font-weight: 700; }
.sc-tab:focus-visible { outline: 2px solid var(--violet); outline-offset: -2px; }

/* ---- the search spans right below the tabs ---- */
.sc-search-wide {
  max-width: none; width: 100%; flex: 1 1 auto;
  height: 38px; max-height: 38px;
  border-radius: var(--r-box);
}

/* ---- the tab switch fades the table out and in ---- */
@keyframes scx-tabfade { 0% { opacity: 1; } 40% { opacity: 0; } 100% { opacity: 1; } }
.scx .sc-tablewrap.is-fading { animation: scx-tabfade 260ms var(--ease) both; }
@media (prefers-reduced-motion: reduce) {
  .scx .sc-tablewrap.is-fading { animation: none; }
}

/* ---- the table, at Azure's density: clean lines, compact rows ---- */
.scx .sc-tablewrap { border-top: 0; }
.scx .sc-table { font-size: 13.5px; }
.scx .sc-th {
  padding: 0; font-size: 11px; letter-spacing: 0.08em;
  background: var(--paper); border-bottom: 1px solid var(--line-strong);
}
.scx .sc-sort, .scx .sc-th-plain { padding: 9px 12px; }
.scx .sc-th.sc-c-status { padding-left: 12px; padding-right: 12px; }
/* Columns separated by clean lines — the NAME-column hairline Nick pointed at. */
.scx .sc-table th, .scx .sc-table td { border-right: 1px solid var(--line-soft); }
.scx .sc-table th:last-child, .scx .sc-table td:last-child { border-right: 0; }
.scx .sc-row td { height: 56px; padding: 6px 12px; }
.scx .sc-row { border-bottom: 1px solid var(--line); }
.scx .sc-logo { width: 32px; height: 32px; border-radius: var(--r-box); box-shadow: none; }
.scx .sc-logo img { width: 20px; height: 20px; }
.scx .sc-body { gap: 10px; }
.scx .sc-name { font-size: 14px; font-weight: 600; letter-spacing: -0.005em; }
.scx .sc-route { font-size: 11.5px; }
.scx .sc-stat b { font-size: 13px; }
.scx .sc-last-line { font-size: 12px; margin-top: 2px; }
.scx .sc-c-status { min-width: 220px; }
.scx .sc-c-items { font-size: 13.5px; font-weight: 700; }
.scx .sc-chev { width: 30px; height: 30px; }
.scx .sc-fold { padding: 12px 16px 16px 56px; }

/* ---- the tag checkbox: the purple box encapsulates the entire cell ----
   "I want the purple box to literally encapsulate the entire thing (left
   side) … a nice box (no rounded corners) … simply be purple with the
   checkmark being white. This full checkmark idea is cool, i imagine it to
   be like a 'tag' on those horizontal lines." Unselected keeps the neat
   outlined square — a bare white cell would not read as selectable. */
/* The pick cell keeps NO padding — `.scx .sc-row td` above would otherwise
   out-cascade the base rule's `padding: 0` (equal specificity, later wins)
   and put the white gutter Nick pointed at right back around the tag. The
   button stretches to whatever height the row actually takes. */
.scx .sc-th.sc-c-pick, .scx .sc-row td.sc-c-pick { width: 52px; }
.scx .sc-row td.sc-c-pick { padding: 0; height: 56px; }
.scx .sc-check { width: 52px; height: 100%; min-height: 56px; border-radius: 0; }
.scx .sc-check-all { height: 36px; }
.scx .sc-box {
  width: 20px; height: 20px; border-radius: 0;
  border: 2px solid var(--ink); background: var(--white);
}
.scx .sc-box svg { width: 14px; height: 14px; }
/* Selected: the whole cell is the tag. No white space, no rounded corners,
   no inset accent bar fighting the fill. */
.scx .sc-row.is-on .sc-check { background: var(--violet); }
.scx .sc-row.is-on td.sc-c-pick { box-shadow: none; }
.scx .sc-row.is-on .sc-box { border-color: transparent; background: transparent; color: #fff; }
/* Hover covers the full cell too — the half-covered hover was the complaint. */
.scx .sc-check:hover:not(:disabled) { background: var(--violet-wash); }
.scx .sc-row.is-on .sc-check:hover:not(:disabled) {
  background: color-mix(in srgb, var(--violet) 88%, var(--ink));
}
.scx .sc-check-all.is-on .sc-box, .scx .sc-check-all.is-some .sc-box {
  background: var(--violet); border-color: var(--violet); color: #fff;
  border-radius: 0;
}

/* ---- "! Needs attention": a yellow-ish hue with a triangle exclamation ---- */
.sc-bang { display: inline-grid; place-items: center; flex: none; color: var(--warn); }
.sc-stat.is-attn b { color: color-mix(in srgb, var(--warn) 75%, var(--ink)); }

/* ---- the fold's login flow ---- */
.sc-login-line {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 12px;
  border: 1px solid color-mix(in srgb, var(--warn) 45%, var(--line));
  background: color-mix(in srgb, var(--warn) 7%, var(--white));
  border-radius: var(--r-box);
}
.sc-login-k { font-size: 13px; font-weight: 700; color: var(--ink); }
.sc-login-go { height: 34px; padding: 0 14px; border-radius: var(--r-box); font-size: 13px; }
.sc-login-wait { font-size: 12.5px; color: var(--ink-soft); }
.sc-retry { height: 34px; padding: 0 14px; border-radius: var(--r-box); font-size: 13px; }
.sc-fold-actions { display: flex; gap: 10px; }
.sc-stop { height: 32px; padding: 0 14px; border-radius: var(--r-box); font-size: 12.5px; }

/* ===========================================================================
   THE ENGINE SUBMENU — a status row over a terminal (SPEC-engine.md).
   "Incredibly neat and smooth and feel like a REAL software dashboard."
   =========================================================================== */

.scx-eng { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.scx-eng-h { border-bottom: 2px solid var(--ink); }

/* "simply one horizontal row. Thats it. Just a nice horizontal box with
   however many columns." */
.scx-status {
  display: flex; align-items: stretch;
  border: 1px solid var(--line); border-radius: var(--r-box);
  background: var(--white);
  overflow-x: auto;
}
.scx-col {
  display: flex; flex-direction: column; gap: 5px; justify-content: center;
  padding: 12px 18px; min-width: 130px;
  border-right: 1px solid var(--line-soft);
}
.scx-col:last-child { border-right: 0; }
.scx-col-uptime { flex: 1 1 auto; min-width: 220px; }
.scx-k {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-faint);
}
.scx-v { font-size: 14px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink); }
.scx-v.is-ok { color: var(--ok); }
.scx-v.is-warn { color: color-mix(in srgb, var(--warn) 80%, var(--ink)); }
.scx-v.is-bad { color: var(--coral-dark); }
.scx-v.is-run { color: var(--violet); }
.scx-v.is-mute { color: var(--ink-soft); font-weight: 600; }

/* The Claude-style strip: one bar per measured minute. A gap is a minute
   nobody measured, and it is drawn as one. */
.scx-uptime { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.scx-strip { display: flex; align-items: stretch; gap: 2px; height: 16px; }
.scx-ubar { flex: 1 1 4px; max-width: 8px; min-width: 3px; border-radius: 1px; }
.scx-ubar.is-up { background: var(--ok); }
.scx-ubar.is-down { background: var(--coral-dark); }
.scx-ubar.is-gap { background: var(--line); }
.scx-upct { font-size: 11.5px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.scx-nostrip { font-size: 12.5px; color: var(--ink-faint); }

/* The terminal: shell raw-output feel, dark like the reference, terse lines
   with the smart colouring. Monospace because it is a terminal. */
.scx-term {
  position: relative;
  min-height: 340px; max-height: 62vh; overflow-y: auto;
  padding: 14px 16px 20px;
  border: 1px solid var(--ink); border-radius: var(--r-box);
  background: #101014; color: #d4d6dd;
  font-family: Consolas, "Cascadia Mono", "SF Mono", "Roboto Mono", monospace;
  font-size: 12.5px; line-height: 1.65;
}
.scx-lines { display: flex; flex-direction: column; }
.scx-line { display: flex; gap: 12px; align-items: baseline; white-space: pre-wrap; }
.scx-time { flex: none; color: #5b5e6b; font-variant-numeric: tabular-nums; }
.scx-line.is-open .scx-text { color: #7aa2f7; }
.scx-line.is-scan .scx-text { color: #d4d6dd; }
.scx-line.is-ok .scx-text { color: #64d989; }
.scx-line.is-warn .scx-text { color: #e6c164; }
.scx-line.is-err .scx-text { color: #ef6a60; }
.scx-line.is-mute .scx-text { color: #7d8090; }
.scx-cursor { display: inline-block; margin-top: 2px; color: #64d989; animation: scx-blink 1.1s steps(1) infinite; }
@keyframes scx-blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .scx-cursor { animation: none; } }

/* The clear button, below the terminal on the right (SPEC-engine). */
.scx-term-wrap { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.scx-term-foot { display: flex; justify-content: flex-end; }
.scx-clear { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; }

/* ---- phone: the two submenu tabs sit at the bottom, above the main rail,
        exactly the way the Dashboard's do ---- */
@media (max-width: 720px) {
  .scx.stg { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .scx .stg-nav {
    position: fixed; top: auto; left: 0; right: 0;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px)); z-index: 39;
    padding: 5px 8px; background: var(--paper); border-top: 1px solid var(--line);
  }
  .scx .stg-nav-h { display: none; }
  .scx .stg-navlist { display: flex; gap: 6px; }
  .scx .stg-navrow { width: auto; flex: 1 1 0; justify-content: center; padding: 8px 10px; }
  /* settings.css hides `.stg .stg-pane` on a phone until a row is picked and
     it loads AFTER this file, so the override has to outrank it. */
  .stg.scx .stg-pane.scx-pane { display: grid; }
  .scx-platforms, .scx-eng { padding-bottom: 64px; }
  .scx .sc-fold { padding: 2px 12px 14px 52px; }
  .sc-tabs { overflow-x: auto; }
  .sc-tab { white-space: nowrap; }
}

/* ---- the dropdown animates open and shut (2026-08-30, entry 5: "make the
   drop down menu be nice smooth animation") ----
   The fold rides in a one-row grid whose track animates 0fr -> 1fr, so the
   height is animated without measuring a pixel. `is-opening` is applied only
   on the paint where the row was actually opened (foldPainted gates it), and
   `is-closing` plays on the live node before the repaint removes it. */
.sc-foldwrap { display: grid; grid-template-rows: 1fr; overflow: hidden; }
.sc-foldwrap > .sc-fold { min-height: 0; }
@keyframes sc-unfold {
  from { grid-template-rows: 0fr; opacity: 0; }
  to { grid-template-rows: 1fr; opacity: 1; }
}
@keyframes sc-foldup {
  from { grid-template-rows: 1fr; opacity: 1; }
  to { grid-template-rows: 0fr; opacity: 0; }
}
.sc-foldwrap.is-opening { animation: sc-unfold 300ms var(--ease); }
.sc-foldwrap.is-closing { animation: sc-foldup 220ms var(--ease) both; }
@media (prefers-reduced-motion: reduce) {
  .sc-foldwrap.is-opening, .sc-foldwrap.is-closing { animation: none; }
}

/* ---------------------------------------------------------------------------
   2026-09-06 — Scan is a Library submenu: the pane is one boxed card, like
   the Dashboard's and the Gallery's, and the extension gate is parked INSIDE
   it (scan.js gateBox), so the blur stays inside the box. The old
   whole-surface rules above no longer match anything.
   --------------------------------------------------------------------------- */
.scx-pane {
  /* 26.1 — clip, not hidden: `hidden` makes the pane a scroll container, and
     the gate panel's sticky then stuck to a box that never scrolls. */
  position: relative; overflow: clip;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--white); box-shadow: var(--shadow-sm);
  padding: 18px 20px 20px; min-height: min(70vh, 720px);
}
.scx-pane:has(> .sc-gate.is-open) { min-height: min(70vh, 720px); }
.scx-pane > .sc-gate { position: absolute; inset: 0; border-radius: 12px;
                       align-content: start; overflow: visible; }
.scx-pane > .sc-gate .sc-gate-panel { position: sticky; top: clamp(16px, 12vh, 120px); }
.scx-pane > .sc-gate.is-open { display: grid; }
/* 13.16: the blur is on the LIST, not the page — the submenus above it stay
   readable while the gate is up. */
.scx-list.is-blurred { filter: blur(6px) saturate(0.7); }
@media (max-width: 900px) { .scx-pane { padding: 12px; border-radius: 10px; } }


/* ---- the terminal popup (2026-09-07) — the graph's scrim, blurred, with the
   same terminal inside and the one place the download lives. */
.ig-scrim.scx-term-scrim { -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); --ig-dialog-w: 880px; }
.scx-term-dlg { padding: 18px 18px 14px; display: flex; flex-direction: column; gap: 10px; max-height: 88dvh; }
.scx-term-dlg .scx-term-x { position: absolute; top: 12px; right: 12px; }
.scx-term-poph h2 { margin: 0 0 2px; font-size: 18px; }
.scx-term-poph .sc-tally { margin: 0; }
.scx-term-popbody { min-height: 0; display: flex; flex-direction: column; }
.scx-term-wrap.is-popup .scx-term { max-height: 60dvh; min-height: 240px; }
.scx-term-foot { gap: 8px; }
