/* Settings surfaces: the ⚙ dropdown, the Storage modal (Setup + Manage
   files) and the Keybinds editor.

   Ported from the "Storage Management - Final" design doc, which authors
   everything as inline styles on top of the design-system tokens. Those tokens
   already exist app-side in ledger.css, so this file only carries the two the
   DS defines and the app didn't need until now, plus the component rules.

   Namespaces: .stg- storage · .smenu- settings menu · .kb- keybinds ·
   .pcpu- core picker. */

:root {
  /* From the DS effects token file. Hover feedback throughout these surfaces
     is colour-only — no transform — which is what keeps a dense keyboard map
     from flickering as the pointer crosses it. */
  --dr-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --transition-colors:
    background-color 0.1s var(--dr-ease),
    border-color 0.1s var(--dr-ease),
    color 0.1s var(--dr-ease);

  /* Two more DS tokens ledger.css never needed. --indigo-800 in particular is
     load-bearing: it colours the drive map's "allocated · reserved" slice, and
     an unresolvable var() inside a conic-gradient is invalid at computed-value
     time — which blanks the ENTIRE gradient, not just that one stop. A missing
     token here costs the whole chart, so both are declared rather than assumed. */
  --indigo-800: #292989;
  --danger: var(--red);
}

/* The library page squares every corner inside .app / .modal-root
   (`border-radius: 0 !important` in ledger.css — the "instrument" direction).
   These four are genuinely circular affordances, not panels, so they opt back
   out the same way the existing round elements do. Miss one and the drive map
   becomes a square with a square hole in it. */
.modal-root .stg-donut-ring,
.modal-root .stg-donut-hub { border-radius: 50% !important; }
.modal-root .stg-range::-webkit-slider-thumb { border-radius: 50% !important; }
.modal-root .stg-range::-moz-range-thumb { border-radius: 50% !important; }

/* ══════════════════════════════════════════════════════════════════════
   Shared modal chrome
   ══════════════════════════════════════════════════════════════════════ */

/* These modals lay out their own header/tabs/body/footers rather than using
   the generic .modal-card slots, so they opt out of the shared padding. */
.modal-card.stg-modal,
.modal-card.kb-modal {
  width: 830px;
  max-width: calc(100vw - 48px);
  padding: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-modal);
}
.modal-card.kb-modal { width: 848px; }

/* The storage modal is a FIXED box. Its two tabs have different natural
   heights, and the drive-map legend grows by a row when auto-delete is on —
   left alone, the card would jump every time either changed, which reads as
   the window twitching rather than as content updating. So the height is
   pinned and the panes inside absorb the difference. */
.modal-card.stg-modal {
  height: 611px;
  box-sizing: border-box;
  max-height: calc(100vh - 48px);
  /* Anchors the long-job overlay below. */
  position: relative;
}

/* ── Long-job overlay (compacting / migrating) ───────────────────────────
   Covers the whole card rather than just the pane: while these run, every
   control behind it is either inert or actively dangerous to press, and a
   half-covered dialog invites the user to try. */
.stg-job {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.stg-job-inner {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
/* Each creature carries its own stage box (380-420 x 210-250; see STAGE in
   creature-loader.js), so a variant swap mid-job would resize this block and
   shunt the title, bar and counters below it up and down. Reserve the LARGEST
   footprint once and centre whatever is mounted inside it: the frame is then
   identical for every variant and nothing moves at the 15s rotation. Keep this
   in step with the widest/tallest entry in STAGE. */
.stg-job-loader {
  flex: none;
  width: 420px;
  height: 250px;
  max-width: 100%;
  overflow: hidden;      /* a narrow window clips the stage rather than widening the card */
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 6px;
}
.stg-job-title { font-size: 14px; font-weight: 600; }
.stg-job-track {
  width: 100%;
  height: 4px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  overflow: hidden;
}
.stg-job-track i {
  display: block;
  height: 100%;
  background: var(--brand);
  /* Eased so the sub-file ticks read as motion rather than as jitter. */
  transition: width 0.25s var(--dr-ease);
}
.stg-job-line {
  width: 100%;
  display: flex;
  align-items: baseline;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.stg-job-line .stg-spacer { flex: 1; }
.stg-job-item {
  width: 100%;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 15px;
}
.stg-job-note {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-faint);
  text-align: center;
  max-width: 340px;
}

.stg-head {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 12px 10px 10px 18px;
}
.stg-eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}
.stg-title { font-size: 15px; font-weight: 600; }
.stg-head .stg-spacer { flex: 1; }
.stg-x {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  /* a 14px svg face: keep the 26px box the "×" used to make, glyph centred */
  padding: 0;
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  align-self: center;
  transition: var(--transition-colors);
}
.stg-x:hover { color: var(--text); background-color: rgba(255, 255, 255, 0.05); }

.stg-sub {
  padding: 0 18px 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}

/* Underline tabs (the DS "Tabs / underline" variant). */
.stg-tabs {
  display: flex;
  align-items: stretch;
  gap: 0;
  padding: 0 18px;
  border-bottom: 1px solid var(--border);
}
.stg-tab {
  appearance: none;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 600;
  padding: 9px 14px;
  cursor: pointer;
  transition: var(--transition-colors);
}
.stg-tab:hover { color: var(--text); }
.stg-tab.on { color: var(--text); border-bottom-color: var(--brand); }

/* Section rule: "// save location ─────────────" */
.stg-rule {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-faint);
  letter-spacing: 0.02em;
}
.stg-rule .stg-rule-line { flex: 1; height: 1px; background: var(--border); }
/* Text on a section line is always lowercase (user rule 2026-09-28). */
.stg-rule > span, .pu-rulehead > span { text-transform: lowercase; }

/* Buttons. The design leans on the DS Button; these are the same three
   variants it uses (default / primary / ghost) plus the text-danger one the
   "Delete all" wrapper produces. */
.stg-btn {
  appearance: none;
  height: 36px;
  padding: 0 14px;
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: var(--transition-colors);
}
.stg-btn:hover:not(:disabled) { background-color: var(--surface-hover); }
.stg-btn:disabled { opacity: 0.45; cursor: default; }
.stg-btn.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.stg-btn.primary:hover:not(:disabled) { background-color: var(--brand-hover); }
.stg-btn.ghost { background: transparent; border-color: transparent; color: var(--text-muted); }
.stg-btn.ghost:hover:not(:disabled) { color: var(--text); background-color: rgba(255, 255, 255, 0.05); }
/* Destructive reads as ordinary text until the pointer is on it — the design's
   .stg-delwrap treatment. A permanently-red button in a dense toolbar is noise;
   red on hover is a warning at the moment it matters. */
.stg-btn.danger { color: var(--text); }
.stg-btn.danger:hover:not(:disabled) { color: var(--danger); border-color: var(--danger); }
.stg-btn.sm { height: 34px; font-size: 12px; padding: 0 12px; }

.stg-field {
  height: 36px;
  padding: 0 10px;
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 13px;
  min-width: 0;
}
.stg-field:focus { outline: none; border-color: var(--accent-border); }
select.stg-field { cursor: pointer; }
.stg-field.sm { height: 34px; font-size: 12px; }

/* ══════════════════════════════════════════════════════════════════════
   Storage modal — Setup tab
   ══════════════════════════════════════════════════════════════════════ */

.stg-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* min-height:0 all the way down is what lets the fixed card height win over
   the content's natural height instead of being pushed out by it. */
.stg-cols { flex: 1; min-height: 0; display: flex; align-items: stretch; }
.stg-cols > * { min-height: 0; overflow-y: auto; }

/* Left: the drive map. */
.stg-map {
  position: relative;
  width: 302px;
  flex: none;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-right: 1px solid var(--border);
}

.stg-donut-wrap { display: flex; align-items: center; justify-content: center; padding: 4px 0; }
.stg-donut { position: relative; width: 204px; height: 204px; }
/* The ring and its hub are the two genuinely circular things here — they keep
   their 50% against the squared-corner reset (see ledger.css --radius: 0). */
.stg-donut-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
}
.stg-donut-hub {
  position: absolute;
  inset: 58px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
}
.stg-donut-big {
  font-family: var(--font-mono);
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.stg-donut-cap {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}

.stg-legend { display: flex; flex-direction: column; }
.stg-legend-row { display: flex; align-items: center; gap: 8px; padding: 3.5px 0; }
.stg-swatch { flex: none; width: 10px; height: 10px; border: 1px solid var(--border); }
.stg-legend-label {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
}
.stg-legend-gb {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.stg-legend-pct {
  width: 36px;
  text-align: right;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

/* Right: the controls. */
.stg-form { flex: 1; min-width: 0; padding: 14px 18px 18px; display: flex; flex-direction: column; gap: 13px; }
.stg-row { display: flex; gap: 8px; align-items: center; }
.stg-row .stg-grow { flex: 1; min-width: 0; }
.stg-note {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  margin-top: -6px;
  overflow-wrap: anywhere;
}

/* Segmented control (recording quality). */
.stg-seg { display: inline-flex; background: var(--surface-raised); border: 1px solid var(--border); padding: 2px; }
.stg-seg button {
  appearance: none;
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  padding: 4px 12px;
  cursor: pointer;
  transition: var(--transition-colors);
}
.stg-seg button:hover { color: var(--text); }
.stg-seg button.on { background: var(--brand); color: #fff; }

.stg-toggle-row { display: flex; align-items: flex-start; gap: 12px; }
.stg-toggle-copy { flex: 1; min-width: 0; }
.stg-toggle-title { font-size: 13px; font-weight: 600; }
.stg-toggle-caption { margin-top: 3px; font-size: 11.5px; line-height: 1.45; color: var(--text-muted); }
.stg-toggle-side { flex: none; display: flex; align-items: center; gap: 8px; }
.stg-toggle-state { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint); }
.stg-toggle-state.on { color: var(--accent); }
.stg-switch {
  position: relative;
  width: 40px;
  height: 22px;
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  cursor: pointer;
  padding: 0;
  transition: var(--transition-colors);
}
.stg-switch .stg-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: var(--slate-400);
  transition: left 0.12s var(--dr-ease), background-color 0.1s var(--dr-ease);
}
.stg-switch[aria-pressed='true'] { background: var(--brand); border-color: var(--brand); }
.stg-switch[aria-pressed='true'] .stg-knob { left: 20px; background: #fff; }

.stg-cap { display: flex; flex-direction: column; gap: 9px; }
.stg-cap-row { display: flex; align-items: center; gap: 12px; }
.stg-range {
  appearance: none;
  -webkit-appearance: none;
  flex: 1;
  min-width: 0;
  height: 4px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  outline: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
}
.stg-range::-webkit-slider-runnable-track { height: 4px; background: transparent; }
.stg-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px;
  height: 13px;
  margin-top: -5px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--brand);
  cursor: pointer;
}
.stg-range::-moz-range-track { height: 4px; background: transparent; }
.stg-range::-moz-range-thumb {
  width: 13px; height: 13px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--brand);
  cursor: pointer;
}
.stg-cap-num { flex: none; display: flex; align-items: center; gap: 6px; }
.stg-cap-num input { width: 76px; }
.stg-cap-unit { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }

.stg-warn {
  padding: 8px 10px;
  background: var(--gold-dim);
  border: 1px solid rgba(240, 194, 68, 0.4);
  color: var(--gold);
  font-size: 11.5px;
  line-height: 1.5;
}

/* Estimate strip. */
.stg-est {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border-top: 1px solid var(--border);
  background: var(--surface-raised);
}
.stg-est-bar { flex: none; width: 3px; height: 18px; background: var(--accent); }
.stg-est-big {
  font-family: var(--font-mono);
  font-size: 24px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.stg-est-unit { font-size: 12px; color: var(--text-muted); }
.stg-est .stg-spacer { flex: 1; }
.stg-est-note {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* Action footer. */
.stg-foot {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border-top: 1px solid var(--border);
}
.stg-foot-status {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stg-foot-status.warn { color: var(--gold); }
.stg-foot-hint { flex: 1; font-size: 11.5px; color: var(--text-muted); }

/* ══════════════════════════════════════════════════════════════════════
   Storage modal — Manage files tab
   ══════════════════════════════════════════════════════════════════════ */

.stg-manage {
  flex: 1;
  min-height: 0;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 12px;
  overflow-y: auto;
}
.stg-block { display: flex; flex-direction: column; gap: 11px; }
.stg-filters { display: flex; align-items: center; gap: 8px; }
.stg-filters-label { flex: none; font-family: var(--font-mono); font-size: 11px; color: var(--text-faint); }
.stg-filters-sep { flex: none; width: 1px; height: 20px; background: var(--border); margin: 0 2px; }
.stg-filter { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.stg-filter select { width: 82px; }

/* Selection readout — the same "3px bar + big mono number" idiom as the
   estimate strip, so the two footers read as one family. */
.stg-sel {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 44px;
  box-sizing: border-box;
  padding: 0 12px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
}
.stg-sel-bar { flex: none; width: 3px; height: 18px; background: var(--accent); }
.stg-sel-num {
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.stg-sel-num.gap { margin-left: 10px; }
.stg-sel-label { font-size: 12px; color: var(--text-muted); }
.stg-sel .stg-spacer { flex: 1; }
.stg-sel-meta {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.stg-actions { display: flex; align-items: center; gap: 10px; }
.stg-actions .stg-spacer { flex: 1; }
.stg-save-est { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.stg-save-note {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.stg-save-formula {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.stg-task { display: flex; align-items: center; gap: 12px; min-height: 40px; }
.stg-task-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.stg-task-head { font-size: 13px; font-weight: 600; }
.stg-task-sub {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stg-task-state {
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.stg-task-state.busy { color: var(--gold); }
.stg-task-state.done { color: var(--accent); }

/* Review-title list inside a destructive-action confirm (titleListHtml) —
   rendered in a plain openModal card, so it needs its own compact styling. */
.stg-confirm-list {
  margin: 0;
  padding-left: 18px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.7;
  color: var(--text-muted);
  max-height: 180px;
  overflow-y: auto;
}

/* ══════════════════════════════════════════════════════════════════════
   Settings ⚙ menu
   ══════════════════════════════════════════════════════════════════════ */

.smenu {
  position: fixed;
  z-index: 90;
  width: 340px;
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-menu);
  display: flex;
  flex-direction: column;
  padding: 5px 0;
}
/* While one of the menu's own modals is open the menu stays put, under the
   modal scrim. Pointer events go with it — the scrim covers it anyway, and a
   stray click landing on a menu row the user can barely see would fire a
   setting change they never intended. */
.smenu.smenu-behind { pointer-events: none; }
.smenu-label {
  padding: 6px 14px 4px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}
.smenu-sep { height: 1px; background: var(--border); margin: 5px 0; }
.smenu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  width: 100%;
  transition: var(--transition-colors);
}
.smenu-item:hover { background-color: var(--surface-hover); }
/* A row that only reports (the version). Same metrics, no affordance. */
.smenu-static { cursor: default; }
.smenu-static:hover { background-color: transparent; }
.smenu-item:hover .smenu-arrow { color: var(--accent); }
.smenu-item-name { flex: 1; font-family: var(--font-sans); font-size: 13px; color: var(--text); }
.smenu-item-val {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  max-width: 46%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.smenu-item-val.ok { color: var(--accent); }
.smenu-arrow { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint); transition: var(--transition-colors); }
/* Compact inline toggle — the menu's own switch, half the modal's size. */
.smenu-tg {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 2px;
  width: 30px;
  height: 16px;
  box-sizing: border-box;
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  flex: none;
  transition: var(--transition-colors);
}
.smenu-tg i { width: 10px; height: 10px; background: var(--slate-400); display: block; }
.smenu-item[aria-pressed='true'] .smenu-tg { justify-content: flex-end; background: var(--brand); border-color: var(--brand); }
.smenu-item[aria-pressed='true'] .smenu-tg i { background: #fff; }
.smenu-sub { background: var(--surface-raised); padding: 3px 0; }
.smenu-sub .smenu-item { padding: 5px 14px 5px 28px; }
/* A short description above a picker's options (Pin League to CPU Cores). */
.smenu-sub .smenu-note { margin: 0; padding: 4px 14px 6px 28px; font-size: 11px; line-height: 1.45; color: var(--text-faint); }
.smenu-mark { flex: none; width: 12px; font-family: var(--font-mono); font-size: 10px; color: var(--accent); }
.smenu-sub-name { flex: 1; font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.smenu-sub-name.on { color: var(--text); }

/* ── Core picker (Pin League to CPU Cores › Set CPU cores individually…) ──
   cpu-pin-ui.js, in the generic modal card. One box per logical CPU on an
   8-column grid; a physical core spans as many columns as it has threads, so
   the two threads of an SMT core share one frame. */
.modal-card:has(.pcpu) { width: 480px; max-width: 92vw; }
.pcpu { display: flex; flex-direction: column; gap: 14px; }
.pcpu-note { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-muted); }
.pcpu-die { display: flex; flex-direction: column; gap: 8px; }
.pcpu-grid { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 6px; }
.pcpu-core { display: flex; min-width: 0; background: var(--surface-raised); border: 1px solid var(--border); transition: var(--transition-colors); }
.pcpu-core:hover { border-color: var(--border-strong); }
.pcpu-cpu {
  position: relative; flex: 1; min-width: 0; height: 30px;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer;
  font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums;
}
.pcpu-cpu + .pcpu-cpu { border-left: 1px solid var(--border); }
/* The real checkbox stays for the keyboard; .pcpu-box draws the squared one. */
.pcpu-cpu input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; pointer-events: none; }
.pcpu-box {
  flex: none; width: 13px; height: 13px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--border-strong);
}
.pcpu-cpu input:checked + .pcpu-box { background: var(--brand); border-color: var(--brand); }
.pcpu-cpu input:checked + .pcpu-box::after {
  content: ''; width: 6px; height: 3px; margin-top: -2px;
  border-left: 2px solid #fff; border-bottom: 2px solid #fff; transform: rotate(-45deg);
}
.pcpu-cpu input:checked ~ span { color: var(--text); }
.pcpu-cpu input:focus-visible + .pcpu-box { outline: 1px solid var(--accent); outline-offset: 2px; }
.pcpu-mini {
  appearance: none; height: 20px; padding: 0 8px;
  background: var(--surface-raised); border: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 10.5px; color: var(--text-muted);
  cursor: pointer; transition: var(--transition-colors);
}
.pcpu-mini:hover { border-color: var(--border-strong); color: var(--text); }
.pcpu-status { margin: 0; min-height: 18px; font-size: 12px; line-height: 1.5; color: var(--text); }

/* ── Comms panel (Settings › recording › Comms) ──────────────────────────
   The expanded picker hosts the shared mic/Discord/mixer block
   (audio-mixer.js) — same tech as the coaching drawer, comms_* keys.
   Styled to read as part of the MENU, not a transplanted modal: labels in
   the menu's mono lowercase, sub-row type sizes, tight vertical rhythm. */
.smenu-comms { display: flex; flex-direction: column; gap: 8px; padding: 4px 14px 10px; }
.smenu-comms .smenu-item { padding: 5px 0; }
.smenu-comms .smenu-item:hover { background-color: transparent; }
.smenu-comms p.faint { margin: 0; font-size: 11px; line-height: 1.45; color: var(--text-faint); }
.smenu-field { display: flex; flex-direction: column; gap: 3px; }
.smenu-field label {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.06em; color: var(--text-faint);
}
.smenu-field select {
  width: 100%; padding: 4px 6px; font-family: var(--font-mono); font-size: 11.5px;
  color: var(--text); background: var(--surface); border: 1px solid var(--border-strong);
}
.smenu-check {
  display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text);
  cursor: pointer;
}
.smenu-check input { width: 13px; height: 13px; accent-color: var(--brand); }

/* Compact mixer inside the menu (the coaching drawer keeps the full size). */
.smenu-comms .mx { gap: 8px; padding-top: 8px; }
.smenu-comms .mx-title {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.06em; color: var(--text-faint);
}
.smenu-comms .mx-row { gap: 4px; }
.smenu-comms .mx-name { font-size: 12px; }
.smenu-comms .mx-db { font-size: 10.5px; }
.smenu-comms .mx-meter { height: 8px; }
.smenu-comms .mx-scale { font-size: 8px; }
.smenu-comms .mx-vol input[type="range"] { height: 14px; }

/* ── Audio mixer (shared: coaching drawer + Comms panel) ─────────────────
   Levels are summed into the capture track at record time, so this is the
   one chance to balance mic against the call. (Moved from ledger.css when
   the panel was shared — settings.css is the sheet both pages load.) */
.mx { display: flex; flex-direction: column; gap: 16px; padding-top: 4px; border-top: 1px solid var(--border); }
.mx-title { font-size: 12px; letter-spacing: .06em; color: var(--text-muted); }
.mx-row { display: flex; flex-direction: column; gap: 5px; }
.mx-head { display: flex; align-items: baseline; justify-content: space-between; }
.mx-name { font-size: 13px; color: var(--text); }
.mx-db { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.mx-row.off .mx-db, .mx-row.off .mx-name { color: var(--text-faint); }

/* The gradient lives on the TRACK and is REVEALED by the mask, never scaled
   with the level — otherwise "red" would slide around and -40dB would paint
   red on a quiet mic. The mask covers everything to the right of the peak. */
/* Stops are dB positions on the -60..0 scale, matching OBS's zones:
   green to -20 (66.7%), amber to -5 (91.7%), red above. */
.mx-meter {
  position: relative; height: 10px; overflow: hidden;
  background: linear-gradient(90deg,
    #2ecc71 0%, #2ecc71 66.7%,
    #d8a11e 66.7%, #d8a11e 91.7%,
    #d64545 91.7%, #d64545 100%);
}
.mx-mask { position: absolute; top: 0; bottom: 0; right: 0; left: 0; background: var(--bg); transition: left .05s linear; }
.mx-row.off .mx-meter { filter: grayscale(1) brightness(.5); }

.mx-scale { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: 9px; color: var(--text-faint); }
.mx-vol { display: flex; align-items: center; }
.mx-vol input[type="range"] { width: 100%; accent-color: var(--brand); height: 16px; }
.mx-note { margin: 2px 0 0 !important; }
.mx .faint { margin: 0; font-size: 11px; line-height: 1.5; color: var(--text-faint); }

/* ══════════════════════════════════════════════════════════════════════
   Keybinds editor
   ══════════════════════════════════════════════════════════════════════ */

.kb-body { padding: 12px 18px 14px; display: flex; flex-direction: column; gap: 10px; border-top: 1px solid var(--border); }
.kb-top { display: flex; align-items: center; gap: 8px; }
.kb-top .stg-grow { flex: 1; min-width: 0; }
.kb-cats { padding: 0; border-bottom: none; }

/* Layer picker — one button that names the layer on show, with the rest on a
   dropdown. It replaced a row of four chips: the chips spent a whole line of a
   fixed-height modal restating three values the user isn't choosing between
   most of the time. */
.kb-layerpick { position: relative; flex: none; }
.kb-layerbtn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 10px;
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 11px;
  cursor: pointer;
  transition: var(--transition-colors);
}
.kb-layerbtn:hover { background-color: var(--surface-hover); }
.kb-layerbtn[aria-expanded='true'] { border-color: var(--accent-border); }
.kb-layerbtn-k { color: var(--text-faint); }
.kb-layerbtn-v { color: var(--accent); min-width: 34px; }
.kb-layerbtn-n { color: var(--text-faint); font-variant-numeric: tabular-nums; }
.kb-layermenu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 100%;
  z-index: 30;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-menu);
  padding: 3px 0;
  display: flex;
  flex-direction: column;
}
.kb-layermenu button {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px 5px 6px;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 11px;
  transition: var(--transition-colors);
}
.kb-layermenu button:hover { background-color: var(--surface-hover); }
.kb-layermenu-v { flex: 1; color: var(--text-muted); }
.kb-layermenu button:hover .kb-layermenu-v { color: var(--text); }

.kb-rows { display: flex; flex-direction: column; gap: 4px; }
.kb-row { display: flex; gap: 4px; }
.kb-key {
  flex: 0 0 auto;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 3px;
  align-items: flex-start;
  padding: 3px 5px;
  height: 40px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text-faint);
  cursor: pointer;
  font-family: var(--font-mono);
  transition: var(--transition-colors);
  min-width: 0;
  position: relative;
}
.kb-key.wide { flex: 1 1 auto; width: auto; }
.kb-key.fn { height: 28px; }
.kb-key.inert { background: var(--surface); cursor: default; }
/* A key carrying a binding from another category still reads as occupied —
   dimmer than the current tab's, brighter than free. Without this, switching
   tabs makes the rest of the map look unassigned and users rebind over it. */
.kb-key.bound { background: var(--surface-raised); border-color: var(--accent-border); color: var(--text-muted); }
.kb-key.active { background: var(--accent-soft); border-color: var(--accent); color: var(--text); }
.kb-key.sel { background: var(--brand); border-color: var(--brand); color: #fff; }
.kb-key.preview { background: var(--accent-soft); border-color: var(--accent); color: var(--text); box-shadow: 0 0 0 2px var(--accent); }
.kb-key.involved { box-shadow: 0 0 0 2px var(--accent); }
.kb-key.mod { background: var(--surface-raised); border-color: var(--border-strong); color: var(--text-muted); }
.kb-key.mod.on { background: var(--brand); border-color: var(--brand); color: #fff; }
.kb-legend { flex: none; font-size: 9px; line-height: 1; white-space: nowrap; max-width: 100%; overflow: hidden; }
.kb-short { flex: none; font-size: 8px; line-height: 1; letter-spacing: 0.02em; white-space: nowrap; max-width: 100%; overflow: hidden; color: var(--text-muted); }
.kb-short.hl { color: var(--accent); }
/* Set by applyHover on the legend belonging to the hovered binding — outranks
   .hl so the one you're pointing at is the one that lights up. */
.kb-short.hov { color: var(--accent); }
.kb-key.sel .kb-short { color: rgba(255, 255, 255, 0.85); }

/* Stacked-key tooltip: the only way to read every action on a shared key
   without widening the cap. */
.kb-key[data-tip]:not([data-tip=''])::after {
  content: attr(data-tip);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 7px);
  transform: translateX(-50%);
  background: var(--surface);
  border: 1px solid var(--accent-border);
  color: var(--text);
  font: 10.5px/1.6 var(--font-mono);
  padding: 6px 9px;
  white-space: pre;
  z-index: 40;
  box-shadow: var(--shadow-menu);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}
.kb-key[data-tip]:not([data-tip='']):hover::after { opacity: 1; visibility: visible; }

.kb-key-legend {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-faint);
}
.kb-key-legend span { display: inline-flex; align-items: center; gap: 5px; }
.kb-key-legend i { width: 9px; height: 9px; display: block; }
.kb-key-legend i.this { background: var(--accent-soft); border: 1px solid var(--accent); }
.kb-key-legend i.other { background: var(--surface-raised); border: 1px solid var(--accent-border); }
.kb-key-legend i.free { background: var(--bg); border: 1px solid var(--border); }

.kb-status {
  display: flex;
  align-items: center;
  height: 34px;
  box-sizing: border-box;
  padding: 0 10px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
}
.kb-status span {
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}
.kb-status span.warn { color: var(--gold); }
.kb-status span.idle { color: var(--text-muted); }
.kb-status .kb-status-pre { color: var(--accent); }

.kb-scroll { height: 146px; overflow-y: auto; }
.kb-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; align-content: start; }
/* The row's tint (raised at rest, accent-soft while listening) is the
   highlight sitting behind the whole binding, so it needs air on the side it
   starts from. Only the left is padded: the right edge belongs to the unbind
   ×, which is full-height and flush by design. */
.kb-entry {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  min-width: 0;
  height: 32px;
  box-sizing: border-box;
  padding: 0 0 0 10px;
  transition: var(--transition-colors);
}
.kb-entry.listening { background: var(--accent-soft); border-color: var(--accent-border); }
/* The square that appears around a binding on hover wraps the whole slot, so a
   paired row's direction word ("back" / "fwd") is inside it rather than
   stranded alongside. It hugs the caps on the bare sides — the padding is only
   on the side the word is on, so the outline never gains a gap it doesn't need.
   The border is permanently present but transparent, so hovering can't shift
   the row by 2px. */
.kb-slot {
  display: flex;
  align-items: center;
  gap: 3px;
  background: none;
  border: 1px solid transparent;
  padding: 0;
  cursor: pointer;
  flex: none;
  transition: var(--transition-colors);
}
.kb-slot.dir-left { padding-left: 4px; }
.kb-slot.dir-right { padding-right: 4px; }
.kb-slot-dir { font-family: var(--font-mono); font-size: 9px; color: var(--text-faint); }
.kb-slot-keys { display: inline-flex; align-items: center; gap: 3px; }
/* Driven from BOTH the pointer and the editor's own hover state. :hover alone
   is a pixel-position fact the JS can't see, and .hov alone can't react to the
   pointer arriving without a mouseenter (a repaint under a stationary cursor);
   together they always agree.
   --accent-border, not --accent: at this size a full-strength outline competes
   with the selection colours it sits among, and hover is the weakest signal in
   the modal. */
.kb-slot:hover,
.kb-slot.hov { border-color: var(--accent-border); }
.kb-cap {
  box-sizing: border-box;
  min-width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  font-family: var(--font-mono);
  font-size: 10px;
  padding: 0 5px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-faint);
  white-space: nowrap;
}
.kb-cap.set { border-color: var(--border); color: var(--accent); }
.kb-cap.listening { border-color: var(--accent-border); color: var(--accent); }
/* A binding on a key this layout can't produce. Gold, not red: it still works
   if they switch back, and the status line offers the rebind. */
.kb-cap.off-layout { border-color: rgba(240, 194, 68, 0.5); color: var(--gold); }
.kb-plus { font-family: var(--font-mono); font-size: 9px; color: var(--text-faint); }
.kb-dot { flex: none; font-family: var(--font-mono); font-size: 10px; color: var(--text-faint); }
.kb-name {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 12px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kb-name i { font-style: normal; color: var(--text-faint); }
.kb-entry .stg-spacer { flex: 1; }
.kb-cfg { display: flex; align-items: center; gap: 4px; flex: none; }
.kb-cfg input {
  width: 40px;
  height: 24px;
  box-sizing: border-box;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 11px;
  padding: 0 6px;
  text-align: center;
}
/* No spinner. At 24px tall the native arrows are two 6px hit targets nobody
   can use, and they eat a third of a field that's usually typed into anyway. */
.kb-cfg input { -moz-appearance: textfield; appearance: textfield; }
.kb-cfg input::-webkit-outer-spin-button,
.kb-cfg input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.kb-cfg button {
  height: 24px;
  padding: 0 8px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: 10px;
  cursor: pointer;
  transition: var(--transition-colors);
}
.kb-cfg button:hover { color: var(--text); }
.kb-unbind {
  flex: none;
  width: 24px;
  height: 100%;
  /* the face is a display:block svg; without flex centring it hugs the left edge */
  display: inline-flex; align-items: center; justify-content: center;
  background: none;
  border: none;
  color: var(--text-faint);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: var(--transition-colors);
}
.kb-unbind:hover { color: var(--text); background-color: rgba(255, 255, 255, 0.05); }
.kb-unbind[hidden] { visibility: hidden; display: block; }

/* ══════════════════════════════════════════════════════════════════════
   Narrow windows
   ══════════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  /* Below the two-column width the drive map stops being a sidebar and
     becomes a header — stacking beats shrinking a 204px donut. */
  .stg-cols { flex-direction: column; }
  .stg-map { width: auto; border-right: none; border-bottom: 1px solid var(--border); }
  .kb-grid { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Upload flows (design: Upload Flows.dc.html) — shared by the library and
   review pages: destination popover (1b/1k), coaching slots dialog (1c–1f),
   high-elo modals (1g/1h), coin earned (1i), uploads manager (3a–3c).
   Tokens missing from one page's :root carry literal fallbacks. */

/* ── shared primitives (pu-) ── */
.pu-label { font-family: var(--font-mono); font-size: 11px; font-weight: 500; color: var(--text-muted); white-space: nowrap; }
.pu-fade { color: var(--text-faint, #5c6075); }
.pu-rule { flex: 1; height: 1px; background: var(--border); min-width: 12px; }
.pu-hint { font-family: var(--font-mono); font-size: 10px; line-height: 1.6; color: var(--text-faint, #5c6075); display: inline-flex; align-items: center; gap: 7px; }
.pu-hint.gold { color: var(--gold); }
.pu-rulehead { display: flex; align-items: center; gap: 8px; flex: none; }
.pu-tick { width: 22px; height: 2px; background: var(--accent); display: block; }
.pu-head { display: flex; align-items: center; gap: 12px; height: 50px; flex: none; padding: 0 18px; border-bottom: 1px solid var(--border); }
.pu-head h3 { margin: 0; font-size: 16px; font-weight: 600; color: var(--text); }
.pu-x { width: 26px; height: 26px; flex: none; display: inline-flex; align-items: center; justify-content: center; background: var(--surface-raised); border: 1px solid var(--border); color: var(--text-muted); cursor: pointer; padding: 0; font-family: var(--font-mono); font-size: 12px; border-radius: 0; }
.pu-x:hover { border-color: var(--accent-border); color: var(--text); }
.pu-champ { width: 34px; height: 34px; flex: none; object-fit: cover; border: 1px solid var(--border); background: var(--bg); display: inline-block; }
.pu-champ.you { border-color: var(--accent); }
.pu-champ.sm { width: 30px; height: 30px; }
.pu-vs { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #5c6075); }
.pu-matchmeta { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.pu-matchtitle { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The sub holds real info (role · date · duration · size) — it wraps rather
   than ellipsizing (the title above stays single-line; it's user text). */
.pu-matchsub { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.up-coin-chip { display: inline-flex; align-items: center; gap: 5px; padding: 2px 7px; background: var(--accent-soft, rgba(68,68,212,.14)); border: 1px solid var(--accent-border, rgba(96,96,226,.45)); font-family: var(--font-mono); font-size: 10px; color: var(--accent); flex: none; white-space: nowrap; }

/* ── high-elo single-game modal (1g) ── */
.modal-card.pu-upload-modal { width: min(560px, 94vw); max-width: none; margin: 0; padding: 0; border-radius: 0; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-modal, 0 24px 70px rgba(0,0,0,.6)); display: flex; flex-direction: column; }
/* :not([hidden]): the bug-report modal swaps two .pu-body views via the
   hidden attribute — an unscoped display here painted both at once. */
.pu-body:not([hidden]) { padding: 16px 18px; display: flex; flex-direction: column; gap: 13px; }
.pu-matchband { display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--surface-raised); border: 1px solid var(--border); }
.pu-oppside { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; max-width: 220px; }
.pu-checking { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-faint, #5c6075); }
.pu-noneligible { font-family: var(--font-mono); font-size: 10.5px; color: var(--gold); text-align: right; }
.pu-oppname { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 11px; color: var(--text); }
.pu-opprank { font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); }
.pu-payband { display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--accent-soft, rgba(68,68,212,.14)); border: 1px solid var(--accent-border, rgba(96,96,226,.45)); }
.pu-paymeta { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.pu-paytitle { font-size: 13px; font-weight: 600; color: var(--text); }
.pu-paysub { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-muted); }
.pu-payright { font-family: var(--font-mono); font-size: 11px; color: var(--accent); flex: none; }
.pu-public { display: flex; flex-direction: column; gap: 7px; }
.pu-publicgrid { display: flex; gap: 10px; }
.pu-publiccell { flex: 1; padding: 9px 10px; background: var(--surface-raised); border: 1px solid var(--border); font-family: var(--font-mono); font-size: 10.5px; line-height: 1.6; color: var(--text-muted); }
.pu-on { color: var(--text); }
.pu-foot { display: flex; align-items: center; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--border); }
/* Profile nudge (both upload modals): the card viewers get is still empty —
   name what's missing and door straight to the profile editor. */
.pu-profilenote { display: flex; align-items: center; gap: 12px; padding: 10px 12px; background: var(--surface-raised); border: 1px solid var(--border); border-left: 2px solid var(--gold); }
.pu-profilenote p { margin: 0; flex: 1; min-width: 0; font-size: 12px; line-height: 1.5; color: var(--text-muted); }
.pu-profilenote p b { color: var(--gold); font-weight: 600; }
.pu-profilenote .stg-btn { flex: none; }
.pu-batch-modal .pu-profilenote { margin: 12px 18px; flex: none; }

/* ── batch modal (1h) ── */
.modal-card.pu-batch-modal { width: min(852px, 96vw); max-width: none; margin: 0; padding: 0; border-radius: 0; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-modal, 0 24px 70px rgba(0,0,0,.6)); display: flex; flex-direction: column; max-height: calc(100dvh - 48px); }
.pu-batchband { display: flex; align-items: center; gap: 12px; padding: 9px 18px; background: var(--surface-raised); border-bottom: 1px solid var(--border); font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); flex: none; }
.pu-batchband b { color: var(--accent); font-weight: 600; }
.pu-batchlist { display: flex; flex-direction: column; overflow-y: auto; min-height: 0; }
.pu-batchrow { display: flex; align-items: center; gap: 12px; padding: 9px 18px; border-bottom: 1px solid var(--border); cursor: pointer; }
.pu-batchrow:hover { background: var(--surface-hover, #252839); }
.pu-batchrow.off { background: rgba(255, 255, 255, .012); }
.pu-batchrow.off .pu-champ, .pu-batchrow.off img { opacity: .45; }
.pu-tickbox { width: 17px; height: 17px; flex: none; display: inline-flex; align-items: center; justify-content: center; background: var(--surface-raised); border: 1px solid var(--border-strong); color: #fff; font-size: 11px; }
.pu-tickbox.on { background: var(--brand, #4444d4); border-color: var(--brand, #4444d4); }
.pu-batchmeta { width: 184px; flex: none; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pu-batchtitle { font-family: var(--font-mono); font-size: 12.5px; color: var(--accent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pu-batchrow.off .pu-batchtitle { color: var(--text-faint, #5c6075); }
.pu-batchsub { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-faint, #5c6075); }
.pu-batchopp { flex: 1; display: flex; align-items: center; gap: 8px; min-width: 0; overflow: hidden; }
.pu-oppname2 { font-family: var(--font-mono); font-size: 12px; color: var(--text); white-space: nowrap; }
.pu-batchrow.off .pu-oppname2 { color: var(--text-faint, #5c6075); }
.pu-opprank2 { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.pu-batchrow.off .pu-opprank2 { color: var(--text-faint, #5c6075); }
.pu-batchlen { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; flex: none; }
.pu-batchsize { width: 52px; text-align: right; font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; flex: none; }
.pu-batchcoin { width: 36px; text-align: right; font-family: var(--font-mono); font-size: 11px; color: var(--accent); flex: none; }
.pu-batchcoin.off { color: var(--text-faint, #5c6075); }
.pu-footnotes { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
/* The batch list fills in as the server's rank checks answer; this is the
   list while none has (checking) or after all have with nothing eligible. */
.pu-batchempty { padding: 28px 18px; text-align: center; font-family: var(--font-mono); font-size: 11px; color: var(--text-faint, #5c6075); }

/* ── coin earned (1i) — Done only, nothing spends ── */
.modal-card.pu-coin-modal { width: min(420px, 92vw); max-width: none; margin: 0; padding: 0; border-radius: 0; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-modal, 0 24px 70px rgba(0,0,0,.6)); display: flex; flex-direction: column; }
.pu-coin-hero { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 26px 22px 20px; border-bottom: 1px solid var(--border); }
.pu-coin-hero-text { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.pu-coin-amount { font-family: var(--font-mono); font-size: 26px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text); }
.pu-coin-sub { font-size: 12.5px; color: var(--text-muted); text-align: center; }
.pu-coin-balance { display: flex; align-items: center; gap: 10px; padding: 12px 18px; border-bottom: 1px solid var(--border); }
.pu-balance-read { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 15px; font-variant-numeric: tabular-nums; color: var(--text); }
.pu-coin-foot { display: flex; align-items: center; gap: 8px; padding: 12px 18px; }

/* ── coaching slots dialog (1c–1f) ── */
.modal-card.cs-modal { width: min(620px, 94vw); max-width: none; margin: 0; padding: 0; border-radius: 0; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-modal, 0 24px 70px rgba(0,0,0,.6)); display: flex; flex-direction: column; height: min(510px, calc(100dvh - 48px)); }
.cs-headsub { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.cs-headsub.gold { color: var(--gold); }
.cs-band { display: flex; align-items: center; gap: 11px; height: 62px; flex: none; padding: 0 18px; background: var(--surface-raised); border-bottom: 1px solid var(--border); }
.cs-band .pu-champ { border-color: var(--border); }
.cs-band .pu-champ.you { border-color: var(--accent); }
.cs-state { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 11px; white-space: nowrap; }
.cs-state.accent { color: var(--accent); }
.cs-state.gold { color: var(--gold); }
.cs-state.green { color: var(--green, #4dd17a); }
.cs-dot { width: 6px; height: 6px; border-radius: 50% !important; display: inline-block; }
.cs-dot.gold { background: var(--gold); }
.cs-dot.green { background: var(--green, #4dd17a); }
.cs-body { flex: 1; min-height: 0; padding: 14px 18px 16px; display: flex; flex-direction: column; gap: 10px; overflow-y: auto; }
.cs-foot { display: flex; align-items: center; gap: 12px; height: 52px; flex: none; padding: 0 18px; border-top: 1px solid var(--border); }
.cs-slots { display: flex; flex-direction: column; gap: 10px; flex: none; }
.cs-slot { display: flex; align-items: center; gap: 12px; min-height: 58px; flex: none; padding: 0 12px; background: var(--surface-raised); border: 1px solid var(--border); }
.cs-slot.free { background: rgba(255, 255, 255, .015); }
.cs-slot.target { border-color: var(--accent-border, rgba(96,96,226,.45)); }
.cs-slot.deleting { border-color: var(--danger, #ff5d5d); }
.cs-slot .pu-champ { width: 32px; height: 32px; }
.cs-slotnum { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #5c6075); width: 44px; flex: none; }
.cs-slotnum.on { color: var(--accent); }
.cs-plus { width: 32px; height: 32px; flex: none; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); color: var(--text-faint, #5c6075); font-family: var(--font-mono); font-size: 15px; }
.cs-slottitle { font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-slottitle.muted { color: var(--text-muted); font-weight: 400; }
.cs-slotsub { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-chip { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; background: var(--accent-soft, rgba(68,68,212,.14)); border: 1px solid var(--accent-border, rgba(96,96,226,.45)); font-family: var(--font-mono); font-size: 10px; letter-spacing: .03em; color: var(--accent); flex: none; white-space: nowrap; }
.cs-chip.gold { background: var(--gold-dim, rgba(240,194,68,.14)); border-color: rgba(240, 194, 68, .4); color: var(--gold); }
.cs-chip.gold i { width: 5px; height: 5px; border-radius: 50% !important; background: var(--gold); display: inline-block; }
.cs-tool { width: 28px; height: 28px; flex: none; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); background: var(--surface); color: var(--text-faint, #5c6075); padding: 0; }
button.cs-tool { cursor: pointer; color: var(--text-muted); }
button.cs-tool:hover { border-color: var(--danger, #ff5d5d); background: var(--red-dim, rgba(255,93,93,.14)); color: var(--danger, #ff5d5d); }
.cs-strip { display: flex; align-items: center; gap: 10px; min-height: 56px; flex: none; padding: 0 12px; background: var(--surface-raised); border: 1px solid var(--border); }
.cs-strip.accent { box-shadow: inset 3px 0 0 var(--accent); }
.cs-strip.danger { background: var(--red-dim, rgba(255,93,93,.14)); border-color: var(--danger, #ff5d5d); }
.cs-striptitle { font-size: 12.5px; font-weight: 600; color: var(--text); }
.cs-stripsub { font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-progress { display: flex; align-items: flex-end; gap: 12px; flex: none; }
.cs-bignum { font-family: var(--font-mono); font-size: 38px; line-height: 1; font-variant-numeric: tabular-nums; color: var(--text); }
.cs-bignum i { font-style: normal; font-size: 15px; color: var(--text-muted); }
.cs-progressmeta { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; padding-bottom: 3px; }
.cs-progressbar { height: 6px; background: var(--surface-raised); border: 1px solid var(--border); }
.cs-progressbar i { display: block; height: 100%; background: var(--brand, #4444d4); transition: width .3s ease; }
.cs-codebox { display: flex; flex-direction: column; gap: 9px; flex: none; padding: 14px; background: var(--surface-raised); border: 1px solid var(--border); }
.cs-coderow { display: flex; align-items: center; gap: 10px; }
.cs-code { font-family: var(--font-mono); font-size: 24px; font-weight: 600; letter-spacing: .08em; font-variant-numeric: tabular-nums; color: var(--text); }

/* ── uploads manager (3a/3b/3c) ── */
#uploadsDock { position: fixed; right: 8px; bottom: 8px; z-index: 3900; font-family: var(--font-sans); }
#uploadsDock[hidden] { display: none; }
.up-panel { width: 348px; background: var(--surface-raised); border: 1px solid var(--border-strong); box-shadow: var(--shadow-modal, 0 24px 70px rgba(0,0,0,.6)); display: flex; flex-direction: column; }
.up-head { display: flex; align-items: center; gap: 8px; height: 34px; flex: none; padding: 0 8px 0 11px; border-bottom: 1px solid var(--border); }
.up-head-label { font-family: var(--font-mono); font-size: 11px; font-weight: 500; color: var(--text-muted); white-space: nowrap; }
.up-badge { font-family: var(--font-mono); font-size: 10px; padding: 1px 6px; background: var(--accent-soft, rgba(68,68,212,.14)); border: 1px solid var(--accent-border, rgba(96,96,226,.45)); color: var(--accent); flex: none; }
.up-alldone { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 11px; color: var(--green, #4dd17a); flex: none; }
.up-alldone i { width: 6px; height: 6px; border-radius: 50% !important; background: var(--green, #4dd17a); display: inline-block; }
.up-pause { height: 22px; padding: 0 8px; background: transparent; border: 1px solid var(--border); color: var(--text-muted); font-family: var(--font-mono); font-size: 10px; cursor: pointer; flex: none; }
.up-pause:hover { border-color: var(--accent-border, rgba(96,96,226,.45)); color: var(--text); }
.up-x { width: 22px; height: 22px; flex: none; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 1px solid transparent; color: var(--text-muted); cursor: pointer; padding: 0; font-family: var(--font-mono); font-size: 12px; line-height: 1; }
.up-x:hover { border-color: var(--border-strong); background: var(--surface); color: var(--text); }
.up-list { display: flex; flex-direction: column; gap: 6px; padding: 8px; max-height: 46vh; overflow-y: auto; }
.up-row { display: flex; flex-direction: column; flex: none; background: var(--surface); border: 1px solid var(--border); }
.up-row:hover { border-color: var(--accent-border, rgba(96,96,226,.45)); }
.up-line { display: flex; align-items: center; gap: 9px; min-height: 42px; padding: 0 10px; }
.up-meta { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.up-title { font-size: 12px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.up-sub { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #5c6075); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.up-pct { font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums; color: var(--text); flex: none; }
.up-size { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint, #5c6075); flex: none; }
.up-err { color: var(--gold); flex: none; cursor: default; }
.up-copy { height: 22px; padding: 0 8px; background: var(--surface-raised); border: 1px solid var(--border); color: var(--text-muted); font-family: var(--font-mono); font-size: 10px; cursor: pointer; flex: none; }
.up-copy:hover { border-color: var(--accent); color: var(--accent); }
.up-bar { height: 2px; background: var(--surface-raised); flex: none; }
.up-bar i { display: block; height: 100%; background: var(--brand, #4444d4); transition: width .3s ease; }
.up-row[data-state="cancelled"] .up-title, .up-row[data-state="error"] .up-title { color: var(--text-muted); }
.up-foot { display: flex; align-items: center; gap: 8px; height: 32px; flex: none; padding: 0 10px; border-top: 1px solid var(--border); }
.up-foot-note { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #5c6075); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.up-balance { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #5c6075); }
.up-balance b { color: var(--text); font-weight: 600; }
.up-strip { position: relative; width: 214px; background: var(--surface-raised); border: 1px solid var(--border-strong); box-shadow: var(--shadow-modal, 0 24px 70px rgba(0,0,0,.6)); display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 10px; cursor: pointer; }
.up-strip:hover { border-color: var(--accent); }
.up-strip-label { font-family: var(--font-mono); font-size: 11px; color: var(--text); white-space: nowrap; }
.up-strip-fill { flex: 1; }
.up-strip-pct { font-family: var(--font-mono); font-size: 11px; font-variant-numeric: tabular-nums; color: var(--text-muted); }
.up-strip-caret { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint, #5c6075); }
.up-strip-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--surface); }
.up-strip-bar i { display: block; height: 100%; background: var(--brand, #4444d4); }

/* ── review toolbar: the upload button + destination popover (1b/1k) ── */
.up-btn { position: relative; }
.up-btn-dot { position: absolute; top: 3px; right: 4px; width: 7px; height: 7px; border-radius: 50% !important; background: var(--accent); border: 1px solid var(--surface); }
.up-pop { position: fixed; z-index: 4100; width: 308px; background: var(--surface-raised); border: 1px solid var(--border-strong); box-shadow: var(--shadow-menu, 0 12px 40px rgba(0,0,0,.5)); padding: 11px; display: flex; flex-direction: column; gap: 9px; }
.up-pop-head { display: flex; align-items: center; gap: 8px; }
.up-dest { width: 100%; display: flex; align-items: center; gap: 10px; min-height: 54px; padding: 0 11px; background: var(--surface); border: 1px solid var(--border); color: var(--text); text-align: left; cursor: pointer; font-family: var(--font-sans); }
button.up-dest:hover { border-color: var(--accent-border, rgba(96,96,226,.45)); background: var(--surface-hover, #252839); }
.up-dest.live { border-color: var(--accent-border, rgba(96,96,226,.45)); }
.up-dest.off { background: rgba(255, 255, 255, .015); cursor: not-allowed; }
.up-dest-ic { display: inline-flex; flex: none; }
.up-dest-ic.gold { color: var(--gold); }
.up-dest-ic.accent { color: var(--accent); }
.up-dest-ic.dim { opacity: .55; }
.up-dest-meta { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.up-dest-meta b { font-size: 12.5px; font-weight: 600; color: var(--text); }
.up-dest-meta b.dim { color: var(--text-faint, #5c6075); }
.up-dest-meta i { font-style: normal; font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #5c6075); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.up-dest-slots { display: flex; gap: 3px; flex: none; }
.up-dest-slots i { width: 12px; height: 4px; display: block; }
.up-dest-slots i.g { background: var(--gold); }
.up-dest-slots i.a { background: var(--accent); }
.up-dest-slots i.d { background: var(--border-strong); }
.up-dest-dash { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint, #5c6075); flex: none; }

/* ── Report a bug (Bug Report Modal design import) ─────────────────────────
   Reuses the upload-flow primitives (.pu-head/.pu-body/.pu-foot, .pu-label,
   .pu-rulehead, .stg-seg, .stg-btn). Widths per the DS Modal shell: 460 is
   the .modal-card base — this modal keeps it. */
.br-modal { width: 460px; }
/* :not([hidden]) — the form and sent views swap via the hidden attribute;
   an unscoped display rule would paint BOTH states at once (the standing
   hidden-attribute trap, which bit exactly here on the first pass). */
.br-body:not([hidden]) { display: flex; flex-direction: column; gap: 11px; }
/* The design's 8px/4px block padding sits INSIDE the modal's 18px content
   padding — compose them (16+8 / 18 / 16+4), don't replace them: replacing
   zeroed the horizontal inset and clipped the readout bracket at the edge. */
.br-body.br-sent-view:not([hidden]) { gap: 14px; padding: 24px 18px 20px; }
.br-block { display: flex; flex-direction: column; gap: 6px; }
.br-hint { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #565b73); white-space: nowrap; }
.br-seg { display: flex; gap: 2px; padding: 2px; height: 30px; }
.br-seg button { flex: 1; padding: 0 6px; text-align: center; }
.br-seg button.on { background: var(--accent-soft, rgba(78, 161, 255, .12)); color: var(--accent); box-shadow: inset 0 -2px 0 var(--accent); }
.br-caption { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #565b73); }
.br-input {
  width: 100%; height: 36px; padding: 0 11px; background: var(--surface-raised);
  border: 1px solid var(--border); color: var(--text); font-family: var(--font-sans);
  font-size: 13px; outline: none;
}
.br-input:focus { border-color: var(--accent-border, rgba(78, 161, 255, .45)); }
.br-input::placeholder { color: var(--text-faint, #565b73); }
.br-textarea { height: auto; padding: 9px 11px; resize: vertical; min-height: 88px; line-height: 1.5; }
.br-ta-label { font-family: var(--font-mono); font-size: 11px; font-weight: 500; color: var(--text-muted); }
.br-ta-label i { font-style: normal; color: var(--text-faint, #565b73); }
.br-notice {
  display: flex; flex-direction: column; gap: 8px; padding: 11px 13px;
  background: var(--surface-raised); border: 1px solid var(--border);
}
.br-notice-row { display: flex; gap: 9px; }
.br-notice-text { display: flex; flex-direction: column; gap: 2px; }
.br-notice-text .a { font-size: 12.5px; color: var(--text); }
.br-notice-text .b { font-size: 12px; color: var(--text-muted); }
.br-attached { display: flex; align-items: center; gap: 8px; border-top: 1px solid var(--border); padding-top: 8px; }
.br-toggle {
  background: none; border: none; padding: 0; color: var(--accent);
  font-family: var(--font-mono); font-size: 10px; font-weight: 600; cursor: pointer;
}
.br-files:not([hidden]) { display: flex; flex-direction: column; gap: 4px; }
.br-file { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.br-file i { width: 5px; height: 5px; background: var(--text-faint, #565b73); flex: none; border-radius: 0 !important; }
.br-file b { font-weight: 500; color: var(--text-faint, #565b73); }
.br-footnote { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #565b73); margin-top: 3px; }
.br-foot { display: flex; align-items: center; gap: 8px; }
.br-foot .stg-btn { height: 34px; }
.br-foot [data-cancel] { min-width: 76px; }
.br-foot [data-send] { min-width: 126px; }
.br-foot [data-done] { min-width: 90px; }
.br-keys { font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); }
.br-keys.faint { color: var(--text-faint, #565b73); }
.br-keys b {
  font-weight: 600; color: var(--text); background: var(--surface-raised);
  border: 1px solid var(--border); padding: 1px 5px; margin: 0 1px;
}
.br-readout { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: .04em; color: var(--green, #3ddc97); align-self: flex-start; cursor: pointer; user-select: text; background: none; border: none; padding: 0; }
.br-readout:hover .brk { color: var(--text-muted); }
.br-readout .brk { color: var(--text-faint, #565b73); font-weight: 500; }
.br-readout i { width: 7px; height: 7px; border-radius: 50% !important; background: var(--green, #3ddc97); box-shadow: 0 0 8px rgba(61, 220, 151, .5); }
.br-sent-text { display: flex; flex-direction: column; gap: 6px; }
.br-sent-title { font-size: 15px; font-weight: 600; color: var(--text); }
.br-sent-sub { font-size: 12.5px; color: var(--text-muted); line-height: 1.55; }
.br-recap {
  display: grid; grid-template-columns: 64px 1fr; gap: 7px 8px; padding: 11px 13px;
  background: var(--surface-raised); border: 1px solid var(--border);
}
.br-recap { align-items: baseline; }
.br-recap .l { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #565b73); }
.br-recap .v { font-size: 12.5px; color: var(--text); }
.br-recap .v.mono { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.br-recap .v.accent { font-family: var(--font-mono); font-size: 11px; color: var(--accent); }

/* -- Login Flow (design import): the signed-out modal ----------------------
   Three states in one card (idle / waiting / done) + the gold locked-tab
   nudge. Display rules scoped :not([hidden]); radii pinned vs the squared
   reset. Loaded after ledger.css, so the 560px width wins its old 520px. */
.modal-card.login-modal { width: min(560px, 92vw); }
.lg-body { gap: 13px; }
.lg-intro { margin: 0; font-size: 13px; line-height: 1.55; color: var(--text-muted); }
.lg-nudge:not([hidden]) {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  background: var(--gold-dim, rgba(240, 194, 68, .12)); border: 1px solid var(--gold, #f0c244);
  color: var(--gold, #f0c244);
}
.lg-nudge span { font-family: var(--font-mono); font-size: 11px; }
.lg-note { font-family: var(--font-mono); font-size: 11px; color: var(--red, #ff5d5d); }
[data-stage]:not(:empty) { display: flex; flex-direction: column; gap: 11px; }
.lg-discord-wrap { display: flex; flex-direction: column; gap: 8px; }
.lg-discord {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; height: 40px; background: var(--brand); border: 1px solid var(--brand);
  color: #fff; font-family: var(--font-sans); font-size: 14px; font-weight: 600; cursor: pointer;
}
.lg-discord:hover { background: var(--brand-hover, var(--brand)); }
.lg-caption { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #565b73); text-align: center; }
.lg-or { display: flex; align-items: center; gap: 10px; }
.lg-or span { flex: 1; height: 1px; background: var(--border); }
.lg-or i { font-style: normal; font-family: var(--font-mono); font-size: 10px; color: var(--text-faint, #565b73); }
.lg-tester-toggle {
  display: flex; align-items: center; gap: 8px; width: 100%; height: 34px; padding: 0 11px;
  background: var(--surface-raised); border: 1px solid var(--border); color: var(--text-muted);
  font-family: var(--font-mono); font-size: 11.5px; cursor: pointer;
}
.lg-tester-toggle:hover { border-color: var(--accent-border, rgba(78, 161, 255, .45)); color: var(--text); }
.lg-tester-toggle .caret { font-size: 11px; color: var(--accent); }
.lg-tester-toggle .faint { color: var(--text-faint, #565b73); }
.lg-tester:not([hidden]) { display: flex; flex-direction: column; gap: 11px; padding: 13px; background: var(--surface-raised); border: 1px solid var(--border); }
.lg-tester-fields { display: flex; gap: 10px; }
.lg-field { flex: 1; display: flex; flex-direction: column; gap: 4px; }
.lg-field span { font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em; color: var(--text-muted); }
.lg-field input {
  height: 32px; padding: 0 10px; background: var(--surface); border: 1px solid var(--border);
  color: var(--text); font-family: var(--font-sans); font-size: 13px; outline: none;
}
.lg-field input:focus { border-color: var(--accent-border, rgba(78, 161, 255, .45)); }
.lg-tester-foot { display: flex; align-items: center; gap: 12px; }
.lg-err:not([hidden]) { display: block; font-family: var(--font-mono); font-size: 11px; color: var(--red, #ff5d5d); line-height: 1.4; }
.lg-submit {
  display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px;
  background: var(--surface); border: 1px solid var(--border); color: var(--text-muted);
  font-family: var(--font-mono); font-size: 11px; font-weight: 600; cursor: pointer; flex: none;
}
.lg-submit:hover { border-color: var(--accent-border, rgba(78, 161, 255, .45)); color: var(--text); }
.lg-submit b { font-weight: 600; border: 1px solid var(--border); padding: 0 4px; font-size: 10px; }
.lg-waiting {
  display: flex; flex-direction: column; gap: 11px; padding: 14px;
  background: var(--surface-raised); border: 1px solid var(--accent-border, rgba(78, 161, 255, .45));
}
.lg-wait-head { display: flex; align-items: center; gap: 9px; font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--accent); }
.lg-wait-head .dot { width: 8px; height: 8px; border-radius: 50% !important; background: var(--accent); animation: lg-dot 1.1s ease-in-out infinite; flex: none; }
.lg-waiting p { margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--text-muted); }
.lg-scan { height: 2px; background: var(--border); overflow: hidden; }
.lg-scan i { display: block; height: 100%; width: 38%; background: var(--brand); animation: lg-scan 1.4s ease-in-out infinite; }
.lg-wait-btns { display: flex; gap: 7px; }
.lg-ghost, .lg-again {
  flex: 1; height: 30px; font-family: var(--font-mono); font-size: 11px; font-weight: 600; cursor: pointer;
  background: var(--surface-raised); border: 1px solid var(--border); color: var(--text-muted);
}
.lg-again { background: var(--surface); color: var(--text); }
.lg-ghost:hover, .lg-again:hover { border-color: var(--accent-border, rgba(78, 161, 255, .45)); color: var(--text); }
.lg-done { display: flex; flex-direction: column; gap: 13px; padding: 14px; background: var(--surface-raised); border: 1px solid var(--border); }
.lg-readout { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: .04em; color: var(--green, #3ddc97); }
.lg-readout .brk { color: var(--text-faint, #565b73); font-weight: 500; }
.lg-readout i { width: 7px; height: 7px; border-radius: 50% !important; background: var(--green, #3ddc97); box-shadow: 0 0 8px rgba(61, 220, 151, .5); }
.lg-done-who { display: flex; align-items: center; gap: 11px; }
.lg-done-who .av { width: 36px; height: 36px; flex: none; object-fit: cover; border: 1px solid var(--accent); background: var(--bg, #0c0d13); }
.lg-done-who .av-letter { display: inline-flex; align-items: center; justify-content: center; font-weight: 700; color: var(--text); }
.lg-done-who .col { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.lg-done-who .nm { font-size: 14px; font-weight: 700; color: var(--text); }
.lg-done-who .sub { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.lg-continue { width: 100%; height: 34px; background: var(--brand); border: 1px solid var(--brand); color: #fff; font-family: var(--font-sans); font-size: 13px; font-weight: 600; cursor: pointer; }
.lg-continue:hover { background: var(--brand-hover, var(--brand)); }
@keyframes lg-dot { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
@keyframes lg-scan { 0% { transform: translateX(-110%); } 100% { transform: translateX(280%); } }
@media (prefers-reduced-motion: reduce) { .lg-wait-head .dot, .lg-scan i { animation: none !important; } }
