/* styles.css — the Console's base layout + component styles.
   Direction: dark, serif for moments that matter, plain sans for everything else,
   one warm gold accent used sparingly. See the approved mockup for the full concept.

   Tokens (--ground, --gold, --ink, ...) now live in ./styles/tokens.css —
   the single source of truth, loaded before this file (see index.html and
   ./styles/README.md). Everything below is unchanged and keeps working
   exactly as before; only the token *declarations* moved, not their
   values. */

html,
body {
  margin: 0;
  min-height: 100%;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  position: relative;
  /* Safety net: prevent horizontal scroll and unwanted pinch zoom gestures */
  overflow-x: hidden;
  overscroll-behavior-x: none;
  touch-action: pan-y;
  -webkit-text-size-adjust: 100%;
}

.shell {
  max-width: 100vw;
  overflow-x: hidden;
}

/* Ambient glow backdrop for ultra-premium dark aesthetic */
body::before {
  content: "";
  position: fixed;
  top: -250px;
  left: 50%;
  transform: translateX(-50%);
  width: 1200px;
  height: 700px;
  background: radial-gradient(circle, rgba(212, 175, 55, 0.07) 0%, rgba(6, 182, 212, 0.04) 45%, rgba(0, 0, 0, 0) 75%);
  pointer-events: none;
  z-index: -1;
}

#app {
  min-height: 100%;
}

/* Top Navigation Bar & Router Navigation */
.sov-nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: 1600px;
  margin: 0 auto 24px;
  padding: 12px 24px;
  background: rgba(15, 23, 42, 0.65);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}

.sov-nav-brand {
  display: flex;
  align-items: center;
  gap: 10px;
}

.sov-brand-logo {
  font-family: var(--serif);
  font-size: 1.125rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: var(--gold-bright);
}

.sov-brand-badge {
  font-family: var(--mono);
  font-size: 0.65rem;
  font-weight: 600;
  padding: 2px 6px;
  background: var(--gold-glow);
  color: var(--gold);
  border-radius: 4px;
  border: 1px solid rgba(212, 175, 55, 0.3);
}

.sov-nav-links {
  display: flex;
  align-items: center;
  gap: 8px;
}

.sov-nav-link {
  background: transparent;
  border: 1px solid transparent;
  color: var(--ink-muted);
  font-family: var(--sans);
  font-size: 0.875rem;
  font-weight: 500;
  padding: 8px 16px;
  border-radius: 10px;
  cursor: pointer;
  transition: all 200ms ease;
  text-decoration: none;
}

.sov-nav-link:hover {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.05);
}

.sov-nav-link.active {
  color: #ffffff;
  background: linear-gradient(135deg, rgba(212, 175, 55, 0.2) 0%, rgba(15, 19, 28, 0.9) 100%);
  border-color: rgba(212, 175, 55, 0.4);
  box-shadow: 0 4px 15px rgba(212, 175, 55, 0.15);
}

.shell {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 48px 24px;
  max-width: 420px;
  margin: 0 auto;
}

.seal {
  margin-bottom: 24px;
}

.content {
  width: 100%;
  display: flex;
  flex-direction: column;
  flex: 1;
}

/* Shortened + opacity-only 2026-08-11 (was 360ms + a 6px slide): every desk
   sub-page swap (Live Monitor -> Jobs -> Tape Library -> Profiles) re-keys
   this same Html.Keyed content node, so the FULL entrance animation played
   on every same-desk tab switch, not just real app-level transitions — the
   "separately-built pages bolted together" feeling a UX audit called out
   directly. A quick fade reads as "the page updated"; the slide read as
   "a new screen just loaded". */
.content > * {
  animation: content-enter 120ms ease-out both;
}

@keyframes content-enter {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .content > * {
    animation: none;
  }
}

.centered {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
}

h1 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.75rem;
  text-align: center;
  margin: 0;
}

h2 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.375rem;
  margin: 0 0 12px;
}

.tag {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-align: center;
  margin: -8px 0 24px;
}

.copy {
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--ink-muted);
  text-align: center;
  margin: 0 0 28px;
}

.muted {
  color: var(--ink-muted);
  font-size: 0.875rem;
}

.welcome {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
}

.actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  margin-top: 8px;
  /* .actions is shared by the pre-auth wallet flow (wants full-width
     buttons — those now carry .btn-block explicitly, whose own width:100%
     wins over align-items regardless) and several authed-app single/pair-
     button rows (Claim/Unclaim this Desk, Strategies & Backtests, ...)
     that do NOT want that: flex-column's default align-items:stretch was
     silently full-widthing those too. flex-start fixes the authed case
     without changing the wallet flow's .btn-block buttons at all. */
  align-items: flex-start;
}

.btn {
  border: none;
  border-radius: 14px;
  padding: 16px;
  font-family: var(--sans);
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
  letter-spacing: 0.01em;
  transition: transform 150ms ease, box-shadow 150ms ease, background-color 150ms ease, border-color 150ms ease, opacity 150ms ease;
}

/* .btn used to default to width:100% — correct for the narrow (420px)
   pre-auth wallet flow it was written for, wrong everywhere else: a real
   UX-audit finding (2026-08-11, "Frame") measured a toolbar button at
   1232px wide on the 1600px authed shell. Five separate call sites had
   each independently pasted the same 4-line "width:auto" override to
   fight it (see the git history for this comment). .btn now defaults to
   its natural inline size; screens that genuinely want the old full-width
   button (the wallet flow) opt in with this class explicitly. */
.btn-block {
  width: 100%;
}

.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.btn:active:not(:disabled) {
  transform: scale(0.98);
}

.btn-primary {
  background: linear-gradient(180deg, #d9b767, var(--gold));
  color: #0b0e14;
}

.btn-primary:hover:not(:disabled) {
  box-shadow: 0 4px 20px -4px rgba(var(--gold-soft-rgb), 0.45);
  transform: translateY(-1px);
}

.btn-secondary {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}

.btn-secondary:hover:not(:disabled) {
  border-color: var(--gold-dim);
  background: rgba(var(--gold-soft-rgb), 0.06);
}

.btn-link {
  background: transparent;
  color: var(--ink-muted);
  font-weight: 400;
  padding: 8px;
}

.btn-link:hover:not(:disabled) {
  color: var(--ink);
}

.btn-danger {
  background: transparent;
  color: var(--red);
  border: 1px solid var(--red);
}

.btn-danger:hover:not(:disabled) {
  background: rgba(217, 105, 95, 0.1);
}

.mnemonic-screen,
.restore-screen,
.password-screen,
.home-screen {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* The gap above spaces .password-screen's DIRECT children — h2, p.copy, form —
   and stops at the form, because a <form> is a plain block and nothing here gave
   it a gap of its own. So on "Set a password" the two password inputs and the
   Finish button rendered flush against each other with 0px between them, while
   the welcome screen next door looked right because it puts its buttons in
   .actions, which is a flex column with its own gap.
   Observed 2026-09-06 on an iPhone 16 Pro simulator. Same structure, and the
   same defect, on the Unlocking screen's form inside .welcome. */
.password-screen form,
.welcome form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* flex-direction:column's default align-items is `stretch` — .home-screen
   deliberately keeps that default (viewIdentityCard/viewAppSection are real
   full-width cards that need it), but its two trailing .btn-link actions
   ("Lock" / "Turn off Face ID") inherited it too and silently filled the
   whole row (proven live: "Lock" measured 1232px on the 1600px authed
   shell — a real UX-audit finding, "Frame", 2026-08-11). align-self opts
   just these two out, without touching the cards above them. */
.home-screen > .btn-link {
  align-self: flex-start;
}

.mnemonic-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 16px;
  margin-bottom: 4px;
}

.mnemonic-word {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--mono);
  font-size: 0.8125rem;
}

.mnemonic-index {
  color: var(--ink-faint);
  font-size: 0.6875rem;
  width: 16px;
  text-align: right;
}

.mnemonic-input {
  width: 100%;
  min-height: 100px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: 14px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.875rem;
  padding: 14px;
  resize: vertical;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}

input[type="password"],
input[type="text"] {
  width: 100%;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 0.9375rem;
  padding: 14px;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}

input[type="password"]:focus,
input[type="text"]:focus,
.mnemonic-input:focus {
  outline: none;
  border-color: var(--gold-dim);
  box-shadow: 0 0 0 3px rgba(var(--gold-soft-rgb), 0.16);
}

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.8125rem;
  color: var(--ink-muted);
  cursor: pointer;
  margin-bottom: 8px;
}

.error {
  color: var(--red);
  font-size: 0.8125rem;
  margin: 0;
}

.qr-code {
  display: flex;
  justify-content: center;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 16px;
}

.qr-code img {
  width: 100%;
  max-width: 240px;
  border-radius: 8px;
}

.npub {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink-faint);
  word-break: break-all;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  padding: 4px 12px;
  display: inline-block;
  user-select: all;
}

.signed-proof {
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px;
  margin-top: 4px;
}

.signed-proof p {
  margin: 4px 0;
  font-family: var(--mono);
  font-size: 0.6875rem;
  word-break: break-all;
}

/* Home screen — identity, wallet security, connection check. (The persona
   note and app launcher were deleted 2026-09-17, console-shell PR 1.) */

.identity-card {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--surface-glass);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 16px;
  padding: 16px;
}

.identity-avatar {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--gold-dim);
  color: var(--gold);
  font-family: var(--serif);
  font-size: 1.125rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.identity-meta {
  min-width: 0;
  flex: 1;
  text-align: left;
}

.identity-label {
  margin: 0 0 4px;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.identity-meta .npub {
  margin: 0 0 6px;
  padding: 6px 10px;
  font-size: 0.6875rem;
  display: inline-block;
}

.identity-meta .muted {
  margin: 0;
}

/* Wallet Home & Lifecycle Cards */
.wallet-home {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
}

.wallet-actions-section {
  width: 100%;
}

.btn-cockpit-enter {
  padding: 14px 20px;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  border-radius: 12px;
}

.wallet-security-card,
.wallet-danger-card {
  background: var(--surface-glass);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 16px;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  text-align: left;
}

.wallet-danger-card {
  border-color: rgba(239, 68, 68, 0.2);
  background: rgba(239, 68, 68, 0.03);
}

.wallet-card-title {
  margin: 0 0 4px 0;
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-family: var(--mono);
  color: var(--ink-muted);
}

.wallet-card-title.text-danger {
  color: #f87171;
}

.wallet-security-row,
.wallet-danger-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 8px;
  border-top: 1px solid rgba(255, 255, 255, 0.04);
}

.security-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.security-name {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink);
}

.security-name.text-danger {
  color: #f87171;
}

.security-desc {
  font-size: 0.75rem;
  color: var(--ink-faint);
  line-height: 1.4;
}

.connection-check {
  display: flex;
  flex-direction: column;
  /* Same flex-column stretch-by-default issue as .home-screen above — no
     full-width children here to preserve, so flex-start on the container
     itself is the simpler fix. */
  align-items: flex-start;
  gap: 10px;
}

/* Desks screen — institutional grid dashboard. See Main.elm's viewDesks. */

.desks-screen {
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 100%;
  max-width: 1440px;
  margin: 0 auto;
}

.desks-screen-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.desks-title-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.desks-title {
  font-family: var(--serif);
  font-size: 1.65rem;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
  letter-spacing: -0.01em;
}

.desks-subtitle {
  font-size: 0.875rem;
  color: var(--ink-muted);
  margin: 0;
}

.desks-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  gap: 20px;
  list-style: none;
  padding: 0;
  margin: 0;
}

.enclave-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background: var(--surface-raised);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
  padding: 20px;
  min-height: 180px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
  transition: all 200ms cubic-bezier(0.16, 1, 0.3, 1);
  position: relative;
  overflow: hidden;
}

.enclave-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(212, 175, 55, 0.4), transparent);
  opacity: 0;
  transition: opacity 200ms ease;
}

.enclave-card:hover {
  border-color: rgba(212, 175, 55, 0.35);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45), 0 0 15px rgba(212, 175, 55, 0.08);
  transform: translateY(-2px);
}

.enclave-card:hover::before {
  opacity: 1;
}

.enclave-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.enclave-identity {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.enclave-icon {
  font-size: 1.4rem;
  line-height: 1;
  padding: 8px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
}

.enclave-names {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.enclave-title {
  font-family: var(--serif);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: 0.01em;
}

.enclave-host-pill {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--gold-dim);
  letter-spacing: 0.02em;
}

.enclave-status-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 20px;
}

.status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}

.status-dot-up {
  background: #10b981;
  box-shadow: 0 0 8px #10b981;
  animation: pulse-green 2.5s infinite;
}

.status-dot-stale {
  background: #f59e0b;
  box-shadow: 0 0 8px #f59e0b;
}

.status-dot-error {
  background: #ef4444;
  box-shadow: 0 0 8px #ef4444;
}

@keyframes pulse-green {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.6; transform: scale(0.85); }
}

.enclave-card-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}

.enclave-badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.enclave-badge {
  font-family: var(--mono);
  font-size: 0.72rem;
  padding: 3px 8px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.07);
  color: var(--ink-muted);
}

.enclave-badge-feed {
  color: var(--cyan, #38bdf8);
  border-color: rgba(56, 189, 248, 0.2);
}

.enclave-badge-ver {
  color: var(--gold);
  border-color: rgba(212, 175, 55, 0.2);
}

.enclave-active-row {
  display: flex;
  align-items: center;
}

.enclave-runners-active {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: #10b981;
  font-weight: 600;
}

.enclave-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
}

.enclave-npub {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--ink-faint);
}

.enclave-card-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.enclave-open-btn {
  padding: 6px 14px;
  font-size: 0.8rem;
  font-weight: 600;
  border-radius: 8px;
}

.enclave-card-add {
  border: 1px dashed rgba(212, 175, 55, 0.25);
  background: rgba(15, 23, 42, 0.25);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 180px;
}

.enclave-card-add:hover {
  border-color: var(--gold);
  background: rgba(212, 175, 55, 0.04);
}

.enclave-add-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.enclave-add-icon {
  font-size: 1.8rem;
  color: var(--gold);
  line-height: 1;
}

.enclave-add-title {
  font-family: var(--serif);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
}

.enclave-add-desc {
  font-size: 0.78rem;
  color: var(--ink-muted);
}

.desks-empty-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 48px 24px;
  background: var(--surface-raised);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 20px;
  gap: 12px;
  max-width: 500px;
  margin: 40px auto;
}

.empty-icon {
  font-size: 2.5rem;
}

/* ── KPI Grid & Enclave Telemetry (DeskSection.elm) ─────────────────── */

.desk-section {
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 100%;
  max-width: 1440px;
  margin: 0 auto;
}

.desk-section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.desk-heading {
  font-family: var(--serif);
  font-size: 1.65rem;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 4px;
}

.desk-subheading {
  font-size: 0.875rem;
  color: var(--ink-muted);
  margin: 0;
}

.desk-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}

.kpi-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background: var(--surface-raised);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 14px;
  padding: 16px 18px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}

.kpi-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.kpi-card-title {
  font-family: var(--mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
}

.kpi-card-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.kpi-stat {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--ink);
}

.kpi-stat-gold {
  color: var(--gold-bright);
}

.kpi-stat-good {
  color: #10b981;
}

.kpi-stat-bad {
  color: #ef4444;
}

.kpi-meta {
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--ink-muted);
}

.kpi-fault-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 4px;
}

.kpi-fault-item {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: #ef4444;
  background: rgba(239, 68, 68, 0.1);
  padding: 4px 8px;
  border-radius: 4px;
}

.runners-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--surface-raised);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  padding: 20px;
}

.runners-section-title {
  font-family: var(--serif);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
}

.runners-empty {
  color: var(--ink-muted);
  font-size: 0.875rem;
  padding: 16px 0;
}

.runners-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}

.runner-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  padding: 12px;
}

.runner-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.runner-id {
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--gold);
}

.runner-type {
  font-size: 0.72rem;
  color: var(--cyan, #38bdf8);
}

.runner-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 0.78rem;
  color: var(--ink-muted);
}

.runner-ticks {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--ink);
  font-weight: 500;
}

.recorders-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--surface-raised);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  padding: 20px;
}

.recorder-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(34, 197, 94, 0.2);
  border-radius: 10px;
  padding: 14px;
}

.recorder-id {
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: #22c55e;
}

.recorder-badge {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  color: #22c55e;
  background: rgba(34, 197, 94, 0.1);
  border: 1px solid rgba(34, 197, 94, 0.25);
  padding: 2px 8px;
  border-radius: 6px;
  letter-spacing: 0.04em;
}

.recorder-venue {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ink);
}

/* ── App shell + nav bar (Institutional Glass Redesign) ──────────────── */

.shell-app {
  max-width: 100%;
  width: 100%;
  padding: 0;
  align-items: stretch;
}

.shell-app .content {
  max-width: 1440px;
  margin: 0 auto;
  width: 100%;
  box-sizing: border-box;
  padding: 28px 24px 48px;
  padding-bottom: calc(48px + var(--safe-bottom, 0px));
}

.shell-frame {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(8, 12, 20, 0.88);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35);
}

.shell-bar {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  max-width: 1440px;
  margin: 0 auto;
  padding: calc(var(--space-2) + var(--safe-top, 0px)) calc(var(--space-4) + var(--safe-right, 0px)) var(--space-2)
    calc(var(--space-4) + var(--safe-left, 0px));
}

.shell-brand-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.shell-brand-icon {
  font-size: 1.1rem;
  color: var(--gold-bright);
}

.shell-brand {
  font-family: var(--serif);
  font-weight: 800;
  letter-spacing: 0.12em;
  font-size: 1.05rem;
  color: var(--gold-bright);
}

.shell-switcher {
  max-width: 18rem;
  background: rgba(15, 23, 42, 0.85);
  border: 1px solid rgba(212, 175, 55, 0.3);
  color: var(--ink);
  border-radius: 8px;
  padding: 6px 12px;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 180ms ease;
}

.shell-switcher:hover {
  border-color: var(--gold);
  background: rgba(30, 41, 59, 0.95);
}

.shell-menu {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}

.shell-menu-item {
  padding: 6px 14px;
  border-radius: 8px;
  color: var(--ink-muted);
  text-decoration: none;
  font-size: 0.85rem;
  font-weight: 500;
  border: 1px solid transparent;
  transition: all 180ms ease;
}

.shell-menu-item:hover {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.05);
}

.shell-menu-item.active {
  color: #ffffff;
  background: linear-gradient(135deg, rgba(212, 175, 55, 0.22) 0%, rgba(30, 41, 59, 0.8) 100%);
  border-color: rgba(212, 175, 55, 0.45);
  box-shadow: 0 0 12px rgba(212, 175, 55, 0.15);
}

.shell-wallet {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 20px;
  padding: 5px 12px;
  color: var(--ink);
  cursor: pointer;
  transition: all 180ms ease;
}

.shell-wallet:hover {
  background: rgba(212, 175, 55, 0.1);
  border-color: rgba(212, 175, 55, 0.4);
}

.shell-wallet-label {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--gold-dim);
}

.status-strip {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  max-width: 1440px;
  margin: 0 auto;
  padding: 6px calc(var(--space-4) + var(--safe-right, 0px)) 6px calc(var(--space-4) + var(--safe-left, 0px));
  font-size: 0.78rem;
  font-family: var(--mono);
  color: var(--ink-muted);
  background: rgba(0, 0, 0, 0.25);
  border-top: 1px solid rgba(255, 255, 255, 0.03);
}

.status-cell {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.status-strip-wrong {
  color: var(--red);
}

@media (max-width: 720px) {
  .shell-menu { margin-left: 0; overflow-x: auto; }
  .shell-bar { flex-wrap: wrap; }
}

@media (max-width: 560px) {
  .shell-bar {
    padding: calc(var(--space-2) + var(--safe-top, 0px)) calc(var(--space-3) + var(--safe-right, 0px)) var(--space-2)
      calc(var(--space-3) + var(--safe-left, 0px));
  }
}

/* Desks dashboard — the single expanded panel for whichever desk the
   switcher has selected, replacing the old stacked-card-per-desk list. */

.desks-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  padding: 32px 4px;
}

.desks-empty .btn {
  width: auto;
  padding: 10px 16px;
}

/* Add Desk modal — a popup (2026-08-10 redesign), not an always-visible
   inline form permanently eating layout space above the desk list. */

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(4, 5, 8, 0.72);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: content-enter 200ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.modal-panel {
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 22px;
  box-shadow: 0 24px 60px -12px rgba(0, 0, 0, 0.6);
}

.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.modal-head h3 {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.125rem;
}

@media (max-width: 560px) {
  .app-nav {
    padding: 12px 16px;
    gap: 10px;
  }

  .shell-bar {
    /* Carries the safe-area insets, like the base rule. Without this the
       narrow-screen override would win at equal specificity and silently
       undo the fix on phones — the only place this media query applies. */
    padding: calc(var(--space-2) + var(--safe-top, 0px)) calc(var(--space-3) + var(--safe-right, 0px)) var(--space-2)
      calc(var(--space-3) + var(--safe-left, 0px));
    gap: var(--space-2);
  }

  .shell-app .content {
    padding: 20px 16px 40px;
  }
}

/* Below 768px the primary nav is a FIXED bottom bar (styles.css:925) that sits
   OVER the content column, so the column has to reserve its height or whatever
   lands last on a screen — a save button, "Strategies & Backtests" — is half
   hidden under it. Measured bar height at 375px: 63.75px (10px padding top and
   bottom + a 42.75px link + a 1px top border). Reserved with real headroom
   rather than an exact match so a larger font size or browser zoom can't eat
   the clearance.

   Must stay AFTER the max-width:560px block above, which re-sets `.shell-app
   .content`'s padding with the shorthand at equal specificity and would
   otherwise win. 767px, not 768px, so this never overlaps the min-width:768px
   query that makes the bar sticky instead of fixed. */
@media (max-width: 767px) {
  .shell-app .content {
    /* 63px bar + 40px breathing room + the home-indicator inset the bar now
       also reserves — without the inset term the bar grows but the clearance
       does not, and the last row of content hides behind it. */
    padding-bottom: calc(63px + 40px + var(--safe-bottom, 0px));
  }
}

/* Manage screen — claim/unclaim + job list/stop over the real command channel. */

.desk-manage-screen {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.desk-manage-divider {
  width: 100%;
  border: none;
  border-top: 1px solid var(--line);
  margin: 4px 0;
}

.claim-section,
.jobs-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.jobs-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.jobs-section-head .desk-detail-title {
  margin: 0;
}

.jobs-section-head .btn-link {
  padding: 4px 8px;
  font-size: 0.75rem;
}

/* Every other wide table here scrolls inside its own wrapper (see
   .ladder-rung-table-wrap); this one had none, so its widest column -- a full
   ISO timestamp in a monospace font, which cannot shrink -- ran off the right
   edge on a phone and was UNREACHABLE, because html/body carry overflow-x:
   hidden and clip rather than scroll. Reported 2026-09-06 from an iPhone. */
.jobs-table-wrap {
  overflow-x: auto;
}

.jobs-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}

.jobs-table th {
  text-align: left;
  padding: 6px 8px;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border-bottom: 1px solid var(--line);
}

.jobs-table td {
  padding: 8px;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  vertical-align: middle;
}

.jobs-table tr:last-child td {
  border-bottom: none;
}

/* Activity card — view toggle, filter/sort bar, type badges (2026-08-10). */

.jobs-head-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

.jobs-view-toggle {
  display: flex;
  gap: 6px;
  padding: 3px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  width: fit-content;
}

.sov-toggle-btn {
  width: auto;
  padding: 5px 12px;
  border-radius: 7px;
  border: none;
  background: transparent;
  color: var(--ink-muted);
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease;
}

.sov-toggle-btn:hover {
  color: var(--ink);
}

.sov-toggle-btn-active {
  background: var(--surface);
  color: var(--gold);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.jobs-filter-sort {
  display: flex;
  gap: 8px;
}

.jobs-filter-select {
  width: auto;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 0.75rem;
  cursor: pointer;
}

.actions-inline {
  display: flex;
  align-items: center;
  gap: 8px;
}

.actions-inline .btn {
  width: auto;
  padding: 4px 10px;
  font-size: 0.75rem;
}

.job-type-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 8px;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 600;
  white-space: nowrap;
}

.job-type-analysis {
  background: var(--color-accent-soft);
  color: var(--gold);
}

.job-type-trade {
  background: var(--color-danger-bg);
  color: var(--red);
}

.job-type-data {
  background: rgba(139, 147, 163, 0.12);
  color: var(--ink-muted);
}

/* Overview + Settings — the redesigned Manage Desk screen (viewDeskManage in
   Main.elm dispatches between the two over ONE DeskManageModel; a gear icon
   toggles `settingsOpen`, no second screen/transport). Uses the .sov-* card/
   chip primitives (components.css) throughout, per that directory's README. */

.overview-screen,
.settings-screen {
  display: flex;
  flex-direction: column;
  gap: var(--space-4, 14px);
}

.screen-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3, 10px);
}

.screen-header-title h2 {
  margin: 0 0 2px 0;
}

.screen-header-title .npub {
  margin: 0;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex: none;
  border-radius: var(--radius-chip, 9999px);
  background: var(--color-surface-elevated, var(--surface-raised));
  border: 1px solid var(--color-border, var(--line));
  color: var(--ink-muted);
  font-size: 1.1rem;
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease, transform 150ms ease;
}

.icon-btn:hover {
  color: var(--gold);
  border-color: var(--gold-dim);
}

/* The gear-turn detail is specific to Settings, not every icon-btn (a close
   X or a chevron shouldn't spin) — opt in per button, not by default. */
.icon-btn-spin:hover {
  transform: rotate(24deg);
}

/* Icons.elm's shared sizing rule — every icon inherits its box from the
   caller's own font-size via 1em, rather than carrying fixed width/height
   attributes (the brand seal's svg used to hardcode width="40" then have it
   silently overridden by .app-nav-seal's CSS — this makes that trick the
   deliberate, universal rule instead of an accident in one place). */
.sov-icon {
  width: 1em;
  height: 1em;
  display: inline-block;
  vertical-align: -0.125em;
  flex: none;
}

.fund-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4, 14px);
}

.fund-hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4, 16px);
  flex-wrap: wrap;
}

.fund-hero-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.fund-hero-amount {
  font-family: var(--serif);
  font-size: var(--text-3xl, 2.25rem);
  color: var(--ink);
  line-height: 1.1;
  letter-spacing: -0.01em;
}

.fund-windows {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.fund-drawdown-note {
  margin: 0;
}

.fund-sparkline {
  flex: 1 1 220px;
  max-width: 280px;
  min-width: 160px;
}

.fund-sparkline-empty {
  display: flex;
  align-items: center;
  min-height: 48px;
}

.fund-sparkline-svg {
  width: 100%;
  height: 64px;
  display: block;
  overflow: visible;
}

.fund-sparkline-area {
  fill: var(--color-accent-soft, rgba(var(--gold-soft-rgb), 0.1));
  stroke: none;
}

.fund-sparkline-line {
  stroke-width: 1.75;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.fund-sparkline-line-up {
  stroke: var(--emerald);
}

.fund-sparkline-line-down {
  stroke: var(--red);
}

.fund-sparkline-dot {
  fill: var(--gold-bright);
}

.jobs-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3, 10px);
}

.job-state-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.settings-soon {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-start;
}

/* Tape Library — recorded-tape cards + coverage/gap calendar (TapeLibrary.elm).
   Uses the motion tokens (motion.css) for entrance/skeleton/transition, and the
   .sov-* primitives (components.css) for chips/inputs — see that directory's
   README, which names this screen explicitly. */

.tape-library-wrap {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Live Monitoring — quote board, correlation matrix, job activity. Its Elm
   screen (LiveMonitoring.elm) was deleted 2026-09-17, console-shell PR 1; the
   .live-* rules below outlived it in this pass — only the families this PR's
   own deletion named were swept. Layout/scroll rules only: color and panel
   background come from the `.sov-*` primitives (components.css) this screen
   reused — see that directory's README ("no existing bespoke equivalent" is
   exactly the case a live heatmap/quote-board is). */

.live-monitor-wrapper {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.live-monitor-header-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
  margin-bottom: 8px;
}

.live-monitor-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
}

@media (min-width: 1200px) {
  .live-monitor-grid {
    grid-template-columns: 1.6fr 1fr;
  }
}

.live-grid-main {
  display: flex;
  flex-direction: column;
  gap: 18px;
  /* Grid items default to min-width:auto, sized to their content's
     max-content width — so a grid track never actually shrinks below
     whatever the widest un-wrapped child (the candidate filter/toolbar
     row) needs, silently pushing 169px of the page off-screen on mobile
     with no way to reach it. min-width:0 lets the track (and everything
     in it) actually respect the 1fr it was given. */
  min-width: 0;
}

.live-grid-side {
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-width: 0;
}

@media (max-width: 768px) {
  .sov-nav-bar {
    flex-direction: column;
    gap: 12px;
    padding: 12px 14px;
    border-radius: 12px;
  }

  .sleeve-selector-bar {
    flex-direction: column;
    align-items: flex-start;
  }

  .candidate-header-row {
    flex-direction: column;
    align-items: flex-start;
  }

  .candidate-search-input {
    width: 100%;
  }

  .live-candidate-table, .live-candidate-table tbody, .live-candidate-table tr, .live-candidate-table td {
    display: block;
    width: 100%;
  }
  .live-candidate-table thead {
    display: none;
  }
  .live-candidate-table tr {
    background: rgba(255, 255, 255, 0.02);
    margin-bottom: 12px;
    border-radius: 12px;
    padding: 12px 16px;
    border: 1px solid rgba(255, 255, 255, 0.06);
  }
  .live-candidate-table td {
    padding: 8px 0;
    text-align: right;
    position: relative;
    border-bottom: 1px solid rgba(255, 255, 255, 0.04);
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .live-candidate-table td:last-child {
    border-bottom: none;
  }
  .live-candidate-table td:nth-child(1)::before { content: "Candidate Pair"; color: var(--ink-faint); }
  .live-candidate-table td:nth-child(2)::before { content: "Screen ρ"; color: var(--ink-faint); }
  .live-candidate-table td:nth-child(3)::before { content: "Spread z"; color: var(--ink-faint); }
  .live-candidate-table td:nth-child(4)::before { content: "Action / Kind"; color: var(--ink-faint); }
  .live-candidate-table td:nth-child(5)::before { content: "Diagnostic"; color: var(--ink-faint); }
}

.tape-library-screen {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.tape-library-head {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
}

.tape-library-head .btn-link {
  padding: 4px 8px;
  font-size: 0.75rem;
  flex: 0 0 auto;
}

.tape-toggle {
  display: flex;
  gap: 8px;
}

.tape-toggle-btn {
  flex: 1;
  width: auto;
  padding: 10px;
  font-size: 0.8125rem;
}

.tape-toggle-active {
  border-color: var(--gold-dim);
  color: var(--gold);
  background: rgba(var(--gold-soft-rgb), 0.08);
}

.tape-library-body > * {
  animation: sov-fade-in var(--dur-slow) var(--ease-out) both;
}

.tape-search {
  margin-bottom: 10px;
}

.tape-empty,
.tape-error {
  padding: 18px 4px;
  text-align: center;
}

/* ── Tape Library, rebuilt 2026-08-14 ────────────────────────────────────────
   The card grid this replaced (.tape-grid/.tape-card/.tape-card-head/
   .tape-name/.tape-archive-badge/.tape-catalog) rendered every tape's chips,
   three stats, span line and per-source breakdown at once, ~60 tapes deep,
   twice (an "On-desk" tab and an "Archived" tab over the same list). Those
   rules are deleted rather than left orphaned. The IA is now
   summary → venue group → day row → one tape's detail, so the styles below are
   for exactly those four levels plus the two things that must be able to
   interrupt: the gap list and the shrink warning. */

/* Summary strip — the "what do I have" answer, above everything */

.tape-summary {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tape-summary-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.tape-summary-item {
  flex: 1 1 8rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  text-align: left;
}

/* The gaps tile is also the way INTO the coverage view, so it reads as
   pressable — the only item in this row that is. */
.tape-summary-item-action {
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: border-color var(--dur-fast) var(--ease-standard),
    background var(--dur-fast) var(--ease-standard);
}

.tape-summary-item-action:hover {
  border-color: var(--gold-dim);
  background: rgba(var(--gold-soft-rgb), 0.06);
}

.tape-summary-label {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.tape-summary-value {
  font-size: 0.9375rem;
  color: var(--ink);
}

.tape-summary-value-warn {
  color: var(--amber);
}

.tape-summary-sub {
  font-size: 0.6875rem;
}

.tape-summary-note {
  margin: 0;
  font-size: 0.6875rem;
}

/* Shrink warning — a repair that returned LESS data than it started with.
   Deliberately the loudest thing on the screen: recorded ticks cannot be
   re-bought from a venue's REST, so this is unrecoverable if ignored. */

.tape-shrink-warn {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  border: 1px solid var(--red);
  border-radius: 12px;
  background: var(--color-danger-bg);
}

.tape-shrink-title {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--ink);
}

.tape-shrink-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 0.75rem;
}

.tape-shrink-name {
  font-family: var(--mono);
  color: var(--ink);
  overflow-wrap: anywhere;
}

.tape-shrink-delta {
  font-family: var(--mono);
  color: var(--red);
}

.tape-shrink-row .btn-link {
  padding: 2px 6px;
  font-size: 0.6875rem;
}

/* Two-view toggle — each half carries the count that says whether it's worth
   opening, so the choice isn't blind. */

.tape-toggle-count {
  display: block;
  margin-top: 2px;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}

.tape-toggle-active .tape-toggle-count {
  color: var(--gold-dim);
}

/* Filters */

.tape-filters {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 10px;
}

.tape-facet {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

.tape-facet-label {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Venue groups → day rows → one tape's detail */

.tape-groups {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tape-group {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
}

.tape-group-skeleton {
  height: 3.25rem;
  border-radius: 12px;
}

.tape-group-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard);
}

.tape-group-head:hover {
  background: rgba(var(--gold-soft-rgb), 0.05);
}

.tape-group-caret {
  flex: none;
  width: 0.75rem;
  color: var(--ink-faint);
}

.tape-group-venue {
  font-family: var(--mono);
  font-size: 0.8125rem;
  color: var(--ink);
  white-space: nowrap;
}

.tape-group-meta {
  flex: 1;
  min-width: 0;
  font-size: 0.6875rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tape-group-size,
.tape-group-ticks {
  flex: none;
  font-family: var(--mono);
  font-size: 0.6875rem;
}

.tape-group-size {
  color: var(--ink);
}

.tape-group-note {
  margin: 0;
  padding: 0 14px 10px;
  font-size: 0.6875rem;
}

.tape-rows {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--line);
}

.tape-row-wrap {
  border-bottom: 1px solid var(--line);
}

.tape-row-wrap:last-child {
  border-bottom: 0;
}

.tape-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 14px 8px 26px;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard);
}

.tape-row:hover,
.tape-row-open {
  background: rgba(var(--gold-soft-rgb), 0.05);
}

.tape-row-day {
  flex: none;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.tape-row-size {
  flex: none;
  min-width: 4.5rem;
  font-family: var(--mono);
  font-size: 0.6875rem;
  color: var(--ink-muted);
}

.tape-row-count {
  flex: 1;
  min-width: 0;
  font-size: 0.6875rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tape-row-durable {
  flex: none;
  min-width: 4.5rem;
  text-align: right;
  white-space: nowrap;
}

.tape-row-detail {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px 14px 26px;
  border-top: 1px solid var(--line);
  background: var(--surface-raised);
}

.tape-detail-name {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.tape-meta {
  margin: 0;
}

/* Gap list — the coverage view's control surface, above the month matrix */

.tape-gaps {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
}

.tape-gaps-clear {
  padding: 10px 14px;
}

.tape-gaps-clear p {
  margin: 0;
  font-size: 0.75rem;
}

.tape-gaps-title {
  margin: 0 0 4px;
  font-size: 0.75rem;
  color: var(--ink-muted);
}

.tape-gap-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 5px 0;
  border-top: 1px solid var(--line);
  font-size: 0.75rem;
}

.tape-gap-day {
  flex: none;
  min-width: 5.5rem;
  font-family: var(--mono);
  color: var(--ink);
}

.tape-gap-weekday {
  flex: none;
  min-width: 4.5rem;
  font-size: 0.6875rem;
}

.tape-gap-row .tape-matrix-source {
  flex: none;
  min-width: 6rem;
}

/* The status chip carries its own vertical padding; without this it makes the
   whole row a third taller than the text needs, and seven of them stack up. */
.tape-gap-row .tape-cal-status-chip {
  flex: none;
  padding: 1px 7px;
}

.tape-gap-ticks {
  flex: 1 1 10rem;
  font-family: var(--mono);
  font-size: 0.6875rem;
}

.tape-gap-action {
  flex: none;
  display: flex;
  justify-content: flex-end;
}

.tape-gap-action .btn {
  width: auto;
  padding: 4px 14px;
  font-size: 0.75rem;
}

/* Narrow screens: the group/row/gap lines are single-line at desktop width and
   must degrade by WRAPPING onto a second line, never by truncating the venue
   name or the tick count mid-word — which is what happens by default, and it
   hides the very figure the row exists to show. */
@media (max-width: 560px) {
  .tape-group-head,
  .tape-row {
    flex-wrap: wrap;
  }

  .tape-group-meta,
  .tape-row-count {
    flex: 1 1 100%;
    order: 3;
    white-space: normal;
  }

  .tape-group-size,
  .tape-group-ticks {
    margin-left: auto;
  }

  .tape-gap-day,
  .tape-gap-weekday,
  .tape-gap-row .tape-matrix-source {
    min-width: 0;
  }

  .tape-gap-ticks {
    flex: 1 1 100%;
  }
}

.tape-catalog-missing {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tape-chip-row,
.tape-source-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tape-stat-row {
  display: flex;
  gap: 16px;
}

.tape-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tape-stat-label {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.tape-stat-value {
  font-size: 0.9375rem;
  color: var(--ink);
}

.tape-span,
.tape-sources-note {
  margin: 0;
}

/* Coverage calendar */

.tape-cal {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tape-cal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.tape-cal-header .btn-link {
  padding: 4px 8px;
  font-size: 0.75rem;
  flex: 0 0 auto;
}

.tape-cal-title {
  margin: 0;
  font-family: var(--serif);
  font-size: 1rem;
}

.tape-source-selector {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tape-source-pick {
  cursor: pointer;
  transition: background-color var(--dur-fast, 150ms) var(--ease-standard, ease),
    color var(--dur-fast, 150ms) var(--ease-standard, ease);
}

/* The "+N other sources" / "Fewer sources" reveal — visually quieter than a
   real source chip so it doesn't compete with the two markets that matter. */
.tape-source-pick-toggle {
  opacity: 0.65;
  font-style: italic;
}

.tape-source-pick-toggle:hover {
  opacity: 1;
}

/* Kept only for the loading skeleton's placeholder shape (viewCalendarSkeleton)
   — the real grid is the source x day matrix below. */
.tape-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}

.tape-cal-cell {
  aspect-ratio: 1;
  border-radius: 8px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
}

/* Source x day coverage matrix — one row per source, one column per day.
   Reuses .ladder-rung-table-wrap/.ladder-rung-table (Ladders.elm) for the
   horizontal-scroll table shell; these rules are only the matrix-specific
   parts on top of it. */
.tape-matrix-wrap {
  margin-top: 4px;
}

.tape-matrix th.tape-matrix-daycol {
  text-align: center;
  width: 28px;
  padding: 6px 2px;
}

.tape-matrix-source {
  font-family: var(--mono);
  font-size: 0.6875rem;
  white-space: nowrap;
}

.tape-matrix-cell-wrap {
  padding: 2px !important;
  text-align: center;
}

/* 30px, not the 24px this was when a cell carried only a glyph. The cell now
   encodes two things at once — which status, and how full — and a level needs
   vertical room before a 60%% day and a 100%% day look different at a glance. */
.tape-matrix-cell {
  position: relative;
  width: 30px;
  height: 30px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.625rem;
  line-height: 1;
  border: 1px solid var(--line);
  background: var(--surface-raised);
  color: var(--ink);
  cursor: pointer;
  overflow: hidden;
  transition: transform var(--dur-fast, 150ms) var(--ease-standard, ease);
}

/* How full the day is, rising from the floor of the cell. Inherits the status
   colour via currentColor-on-the-parent rather than picking its own, so a thin
   PRESENT day and a thin PARTIAL day stay visibly different states — the level
   adds magnitude to the status, it never replaces it. */
.tape-matrix-fill {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: currentColor;
  opacity: 0.45;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .tape-matrix-fill {
    transition: height var(--dur-slow, 400ms) var(--ease-out, ease);
  }
}

/* The glyph rides above the level — it is the colourblind-safe signal and must
   stay legible whatever the fill height. */
.tape-matrix-glyph {
  position: relative;
  z-index: 1;
}

.tape-matrix-cell:hover {
  transform: translateY(-1px);
}

/* No evidence at all for this (source, day) — a plain, non-interactive cell
   rather than a clickable dead end that opens an empty detail panel. */
.tape-matrix-cell-empty {
  cursor: default;
  background: transparent;
  border-style: dashed;
  border-color: var(--line);
}

.tape-matrix-cell-empty:hover {
  transform: none;
}

.tape-cal-selected {
  box-shadow: 0 0 0 2px var(--gold);
}

.tape-cal-status-present {
  background: rgba(63, 191, 143, 0.22);
  border-color: rgba(63, 191, 143, 0.4);
  color: rgb(63, 191, 143);
}

.tape-cal-status-partial {
  background: rgba(224, 151, 63, 0.22);
  border-color: rgba(224, 151, 63, 0.4);
  color: rgb(224, 151, 63);
}

.tape-cal-status-missing {
  background: rgba(217, 105, 95, 0.22);
  border-color: rgba(217, 105, 95, 0.4);
  color: rgb(217, 105, 95);
}

/* "trades-only" — the day has records, often a great many, but NOTHING in the
   quote channel, so the correlation engine (which runs on quote mids) cannot
   use it at all. It shares MISSING's red hue rather than partial's amber on
   purpose: this is not "some of the data", it is "none of the data that
   matters", and three such alpaca-sip days (2026-08-10/11/12) were nearly fed
   to a week-long baseline backtest precisely because they looked healthy. The
   solid-left/hollow-right split gradient is its non-hue signal (matching the
   ◧ glyph): one channel filled, one empty. */
.tape-cal-status-trades-only {
  background: linear-gradient(
    to right,
    rgba(217, 105, 95, 0.3) 0,
    rgba(217, 105, 95, 0.3) 50%,
    transparent 50%,
    transparent 100%
  );
  border-color: rgba(217, 105, 95, 0.55);
  border-style: dashed;
  color: rgb(217, 105, 95);
}

/* "closed" (market known-closed, e.g. a weekend/holiday) and "unknown" (zero
   evidence either way — no source has any data for this day at all) used to
   be byte-for-byte identical, leaving an operator unable to tell "we know
   nothing was expected" apart from "we simply have no evidence" at a glance —
   and relying on hue alone between statuses is a colorblind-accessibility
   problem regardless. Each now gets a distinct, non-hue treatment: closed = a
   subtle diagonal hatch on a faint fill (there's a real, known answer here,
   just not tick data); unknown = a dashed border on a fully transparent fill
   (nothing to show at all). "untracked" (a real source this Desk's repair
   pipeline was never built to fetch/repair — see TapeLibrary.elm's
   SourceCoverage.repairable doc) gets its own third treatment, a dotted
   border, so it's never confused with either. */
.tape-cal-status-closed {
  background: repeating-linear-gradient(
    135deg,
    transparent 0,
    transparent 3px,
    var(--line) 3px,
    var(--line) 4px
  );
  border-color: var(--line);
  color: var(--ink-faint);
}

.tape-cal-status-unknown {
  background: transparent;
  border-style: dashed;
  border-color: var(--line);
  color: var(--ink-faint);
}

.tape-cal-status-untracked {
  background: var(--surface-raised);
  border-style: dotted;
  border-color: var(--ink-faint);
  color: var(--ink-faint);
}

.tape-cal-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.tape-cal-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.6875rem;
  color: var(--ink-muted);
}

/* Same shape/size as a real matrix cell (a small rounded square with its
   status glyph centered), not an 8px dot — otherwise the non-hue treatments
   (closed's hatch, untracked's dotted ring) this legend exists to teach are
   illegible at dot size. See .tape-matrix-cell below for the paired rule. */
.tape-cal-legend-swatch {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.5625rem;
  line-height: 1;
  flex: none;
}

.tape-cal-detail {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
}

.tape-cal-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.tape-cal-detail-head .desk-detail-title {
  margin: 0;
}

.tape-cal-detail-head .btn-link {
  padding: 4px 8px;
  font-size: 0.75rem;
  flex: 0 0 auto;
}

.tape-detail-table td {
  vertical-align: top;
}

.tape-cal-status-chip {
  align-self: flex-start;
}

.tape-repair-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* .btn's base rule sets width:100% and a generous vertical padding — inside a
   table cell that makes Repair a slab as tall as the row it sits in. It is the
   single most consequential control here (it can trigger an hours-long
   re-fetch), so it should read as a deliberate button, not as the cell. */
.tape-repair-actions .btn {
  width: auto;
  padding: 4px 14px;
  font-size: 0.75rem;
}

.tape-repair-status {
  margin: 0;
}

/* .tape-cal-replace-row is gone with the whole-day Full Replace row it styled
   — that action posted a job type the Desk removed 2026-08-09 (venue-day tapes
   only), so it could only ever fail. */

.live-monitor-screen {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.live-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.live-panel-head h3 {
  margin: 0;
}

.live-panel-head .btn-link {
  padding: 4px 8px;
  font-size: 0.75rem;
  flex: 0 0 auto;
}

.live-banner {
  margin: 0;
  padding: 14px 18px;
  border-radius: 12px;
  font-size: 0.875rem;
  line-height: 1.5;
  border: 1px solid var(--line);
  background: var(--surface-glass);
  backdrop-filter: blur(16px) saturate(180%);
  color: var(--ink-muted);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
  transition: all 250ms ease;
}

.live-banner-connecting {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--ink-muted);
  border-color: rgba(212, 175, 55, 0.2);
  background: rgba(15, 23, 42, 0.5);
}

.pulse-ring {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #f3d068;
  box-shadow: 0 0 0 0 rgba(243, 208, 104, 0.7);
  animation: pulse-ring-glow 1.5s infinite cubic-bezier(0.66, 0, 0, 1);
  flex-shrink: 0;
}

@keyframes pulse-ring-glow {
  0% {
    box-shadow: 0 0 0 0 rgba(243, 208, 104, 0.7);
  }
  70% {
    box-shadow: 0 0 0 10px rgba(243, 208, 104, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(243, 208, 104, 0);
  }
}

.live-banner-info {
  border-color: var(--gold-glow);
  background: linear-gradient(135deg, rgba(212, 175, 55, 0.08) 0%, rgba(15, 19, 28, 0.60) 100%);
  color: var(--ink);
  box-shadow: 0 4px 20px rgba(212, 175, 55, 0.12), inset 0 1px 0 rgba(243, 208, 104, 0.2);
}

.live-banner-warn {
  border-color: rgba(245, 158, 11, 0.35);
  color: var(--amber);
  background: rgba(245, 158, 11, 0.1);
}

/* SVG Icon Styling Alignment */
.sov-icon {
  width: 1.15em;
  height: 1.15em;
  flex-shrink: 0;
}

.sleeve-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.candidate-search-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.candidate-search-wrap .sov-icon {
  position: absolute;
  left: 10px;
  color: var(--ink-muted);
  pointer-events: none;
}

.candidate-search-wrap .candidate-search-input {
  padding-left: 32px;
}

.badge-with-icon {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* Multi-Strategy Sleeve Selector Bar */
.sleeve-selector-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
  padding: 10px 14px;
  background: rgba(15, 23, 42, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  flex-wrap: wrap;
}

.sleeve-label {
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.sleeve-pill {
  padding: 6px 14px;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink-muted);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 20px;
  cursor: pointer;
  transition: all 150ms ease;
}

.sleeve-pill:hover {
  background: rgba(212, 175, 55, 0.12);
  color: var(--gold-bright);
}

.sleeve-pill.active {
  background: rgba(212, 175, 55, 0.2);
  color: var(--gold-bright);
  border-color: var(--gold);
  box-shadow: 0 0 12px rgba(212, 175, 55, 0.25);
}

.sleeve-pill-disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Candidate Toolbar & Search Header */
.candidate-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}

.candidate-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.candidate-search-input {
  width: 220px;
  padding: 6px 12px;
  font-family: var(--sans);
  font-size: 0.8125rem;
  color: var(--ink);
  background: rgba(0, 0, 0, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  outline: none;
  transition: border-color 150ms ease;
}

.candidate-search-input:focus {
  border-color: var(--gold);
}

.toolbar-pill-group {
  display: flex;
  align-items: center;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  padding: 2px;
}

.tb-pill {
  padding: 4px 10px;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink-muted);
  background: transparent;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: all 120ms ease;
}

.tb-pill.active {
  background: rgba(212, 175, 55, 0.25);
  color: var(--gold-bright);
}

/* Novice-Friendly Candidate Explanation Card */
.sov-card-explanation {
  margin-bottom: 20px;
  padding: 18px 22px;
  background: rgba(15, 23, 42, 0.4);
  border: 1px solid rgba(212, 175, 55, 0.2);
  border-radius: 12px;
  backdrop-filter: blur(12px);
}

/* The card is a <details>; its header is the <summary> the reader clicks.
   Collapsed, the header alone is the whole card — so it carries no bottom
   margin until the disclosure is actually open. */
.explanation-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  cursor: pointer;
  list-style: none;
}

.explanation-header::-webkit-details-marker {
  display: none;
}

.sov-card-explanation[open] .explanation-header {
  margin-bottom: 10px;
}

/* The gate thresholds stay visible while collapsed — they are the numbers an
   operator checks when nothing qualifies; the prose behind them is not. */
.explanation-gates {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.explanation-gate-chip {
  font-family: var(--mono);
  font-size: 0.6875rem;
}

.explanation-title {
  font-family: var(--serif);
  font-size: 1rem;
  font-weight: 700;
  color: var(--gold-bright);
}

.explanation-badge {
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  padding: 2px 8px;
  background: rgba(212, 175, 55, 0.15);
  color: var(--gold);
  border-radius: 4px;
  border: 1px solid rgba(212, 175, 55, 0.3);
}

.explanation-body {
  font-size: 0.875rem;
  color: var(--ink-muted);
  margin-bottom: 14px;
  line-height: 1.5;
}

.explanation-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
}

.explanation-step {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
}

.step-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  background: var(--gold-glow);
  color: var(--gold-bright);
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 700;
  border-radius: 50%;
  flex-shrink: 0;
}

.step-title {
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 2px 0;
}

.step-desc {
  font-size: 0.75rem;
  color: var(--ink-muted);
  margin: 0;
  line-height: 1.3;
}

/* High-Contrast Structured Terminal Log Viewer */
.live-job-log {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 420px;
  overflow-y: auto;
  padding: 12px 16px;
  background: #030407;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  font-family: var(--mono);
  font-size: 0.8125rem;
  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
}

.structured-log-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 8px;
  border-radius: 6px;
  transition: background 150ms ease;
  line-height: 1.4;
}

.structured-log-row:hover {
  background: rgba(255, 255, 255, 0.04);
}

.log-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}

.log-dot-error {
  background: #f43f5e;
  box-shadow: 0 0 8px rgba(244, 63, 94, 0.8);
}

.log-dot-warn {
  background: #f59e0b;
  box-shadow: 0 0 8px rgba(245, 158, 11, 0.8);
}

.log-dot-success {
  background: #10b981;
  box-shadow: 0 0 8px rgba(16, 185, 129, 0.8);
}

.log-dot-info {
  background: #06b6d4;
  box-shadow: 0 0 6px rgba(6, 182, 212, 0.6);
}

.log-time-chip {
  color: #64748b;
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

.log-cat-badge {
  color: #f3d068;
  background: rgba(212, 175, 55, 0.1);
  border: 1px solid rgba(212, 175, 55, 0.25);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  flex-shrink: 0;
}

.log-message {
  color: #e2e8f0;
  word-break: break-word;
}

.log-row-error .log-message {
  color: #fda4af;
  font-weight: 500;
}

.log-row-warn .log-message {
  color: #fde68a;
}

.log-row-success .log-message {
  color: #6ee7b7;
}

.live-banner-danger {
  border-color: rgba(244, 63, 94, 0.35);
  color: var(--red);
  background: rgba(244, 63, 94, 0.1);
  box-shadow: 0 4px 20px rgba(244, 63, 94, 0.15);
}

.live-status-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* Candidate Diagnostics & Refusal Breakdown Table */

.live-candidate-card {
  background: var(--surface-glass);
  backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 20px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
  margin-top: 16px;
}

.live-candidate-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 0.8125rem;
}

.live-candidate-table th {
  text-align: left;
  padding: 10px 12px;
  color: var(--ink-faint);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--line);
}

.live-candidate-table td {
  padding: 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 0.75rem;
}

.badge-success {
  background: rgba(16, 185, 129, 0.15);
  color: #34d399;
  border: 1px solid rgba(16, 185, 129, 0.35);
  padding: 3px 8px;
  border-radius: 6px;
  font-weight: 600;
}

.badge-armed {
  background: rgba(16, 185, 129, 0.15);
  color: #34d399;
  border: 1px solid rgba(16, 185, 129, 0.35);
  padding: 3px 8px;
  border-radius: 6px;
  font-weight: 600;
}

.badge-refused-drop {
  background: rgba(6, 182, 212, 0.15);
  color: #38bdf8;
  border: 1px solid rgba(6, 182, 212, 0.35);
  padding: 3px 8px;
  border-radius: 6px;
}

.badge-unwarmed {
  background: rgba(148, 163, 184, 0.15);
  color: #cbd5e1;
  border: 1px solid rgba(148, 163, 184, 0.35);
  padding: 3px 8px;
  border-radius: 6px;
}

/* Correlation matrix */

.live-zoom-controls {
  display: flex;
  align-items: center;
  gap: 4px;
}

.live-zoom-controls .btn {
  width: auto;
  padding: 2px 10px;
}

.live-hover-reading {
  min-height: 1.25rem;
  font-family: var(--mono);
  font-size: 0.8125rem;
}

.live-matrix-scroll {
  overflow: auto;
  max-width: 100%;
  max-height: 70vh;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 8px;
  background: var(--surface-raised);
}

.live-matrix-label {
  font-family: var(--mono);
  font-size: 8px;
  fill: var(--ink-muted);
}

.live-pair-lists {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-top: 14px;
}

@media (min-width: 720px) {
  .live-pair-lists {
    grid-template-columns: 1fr 1fr;
  }
}

.live-pair-list .jobs-table {
  font-size: 0.75rem;
}

/* Job activity */

.live-job-filter-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 2px 0 12px 0;
}

.live-job-filter-tab {
  border: 1px solid var(--color-border-soft, rgba(38, 44, 58, 0.55));
  cursor: pointer;
}

.live-job-card {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 8px;
  background: var(--surface-raised);
}

.live-job-head {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  white-space: nowrap;
  font-size: 0.85rem;
}

.live-job-type {
  font-weight: 600;
  font-family: var(--sans);
  color: var(--ink);
}

.live-job-metrics {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink-muted);
  text-align: right;
}

.live-job-progress {
  margin-top: 8px;
}

.live-job-stage {
  margin: 4px 0 0;
  font-size: 0.75rem;
}

.live-job-detail {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Ladders — parameter-tuning ladder list + rung table (Ladders.elm). Uses the
   motion tokens (motion.css) for entrance/skeleton, and the .sov-* primitives
   (components.css) for chips — see that directory's README. Layout/scroll
   rules only, same division of labor the Tape Library block above draws. */

.ladders-wrap {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ladders-screen {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* ── Profiles screen ─────────────────────────────────────────────────── */

.profiles-wrap,
.profiles-screen {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.profiles-head {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.profiles-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 14px;
}

.profile-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: rgba(22, 27, 34, 0.7);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  padding: 16px 18px;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
  transition:
    border-color var(--dur-fast, 150ms) var(--ease-standard, ease),
    box-shadow var(--dur-fast, 150ms) var(--ease-standard, ease),
    transform var(--dur-fast, 150ms) var(--ease-standard, ease),
    background var(--dur-fast, 150ms) var(--ease-standard, ease);
}

.profile-row:hover {
  background: rgba(30, 38, 48, 0.85);
  border-color: rgba(212, 160, 23, 0.45);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35), 0 0 12px rgba(212, 160, 23, 0.12);
  transform: translateY(-2px);
}

.profile-row-top {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
}

.profile-row-name {
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 600;
  color: #f0f6fc;
  letter-spacing: -0.01em;
  flex: 0 0 auto;
}

.profile-row-meta {
  flex: 0 0 auto;
  margin-left: auto;
  font-size: 0.72rem;
  font-family: var(--mono);
  color: #8b949e;
  background: rgba(255, 255, 255, 0.04);
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  white-space: nowrap;
}

.profile-row-title {
  width: 100%;
  color: #8b949e;
  font-size: 0.82rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* An auto-generated ladder-rung snapshot, not a profile an operator wrote —
   visually recessive so the real, hand-edited profiles (there are usually a
   handful) stand out from what can be dozens of these. */
.profile-row-snapshot {
  padding: 8px 16px;
  box-shadow: none;
  background: transparent;
  border-style: dashed;
}

.profile-row-snapshot .profile-row-name {
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--muted);
}

.profile-row-snapshot .profile-row-title {
  display: none;
}

.profile-detail-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 4px;
}

.profile-detail-head h2 {
  font-size: var(--text-xl, 1.375rem);
}

.profile-json {
  font-family: var(--mono);
  font-size: 0.78rem;
  line-height: 1.6;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-card, 14px);
  padding: 18px 20px;
  overflow-x: auto;
  white-space: pre;
  box-shadow: var(--shadow-card);
}

/* ── Profiles: the editor ─────────────────────────────────────────────────
   Reuses the screen's existing language (.profile-row, .profile-json, .btn,
   .sov-input) rather than introducing a second one. Everything below is
   layout + state colour for the parts that did not exist while this screen
   was read-only: the save bar, the tab strip, the generated knob editor, and
   the reflective document editor.                                            */

.profiles-head-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

.profile-dirty {
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--amber);
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 2px 8px;
}

.profile-notice {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 12px;
  animation: sov-fade-in var(--dur-base) var(--ease-out) both;
}

.profile-notice-text {
  min-width: 0;
}

.profile-notice-good {
  border-color: var(--emerald);
}

.profile-notice-bad {
  border-color: var(--red);
}

/* The save bar is deliberately loud about consequence — it is the one place
   an edit becomes a change to what this Desk will actually trade. */
.profile-savebar {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-card, 14px);
  padding: 16px 18px;
  box-shadow: var(--shadow-card);
}

.profile-savebar-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.profile-savebar-note {
  font-size: 0.78rem;
  margin: 0;
}

.profile-confirm {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px;
  margin-top: 4px;
}

.profile-confirm-danger {
  border-color: var(--red);
}

.profile-confirm h3 {
  margin: 0;
}

.profile-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--line);
  margin: 18px 0 6px;
}

.profile-tab {
  background: none;
  border: none;
  border-radius: 8px 8px 0 0;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  padding: 9px 16px;
  cursor: pointer;
  font-size: 0.88rem;
  font-weight: 500;
  transition: color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    background-color var(--dur-fast) var(--ease-standard);
}

.profile-tab:hover {
  color: var(--ink);
  background: var(--color-surface-hover, rgba(255, 255, 255, 0.04));
}

.profile-tab-active {
  color: var(--gold-bright, var(--gold));
  border-bottom-color: var(--gold);
  background: var(--color-surface-hover, rgba(255, 255, 255, 0.04));
}

.profile-pane {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding-top: 16px;
  animation: sov-fade-in var(--dur-base) var(--ease-out) both;
}

.profile-pane-lede {
  color: var(--muted);
  max-width: 68ch;
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.5;
}

.profile-sleeves {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.profile-sleeve {
  display: flex;
  flex-direction: column;
  gap: 18px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-card, 14px);
  padding: 22px 24px;
  box-shadow: var(--shadow-elevated);
}

.profile-sleeve-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

.profile-sleeve-title {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.profile-sleeve-head h3 {
  margin: 0;
  font-family: var(--mono);
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--gold-bright, var(--gold));
}

/* What this strand IS, without opening a single step. */
.profile-sleeve-summary {
  font-size: 0.78rem;
  color: var(--muted);
}

/* ── The sleeve as a PIPELINE, not a form ──────────────────────────────────
   A sleeve is strategy → engine → venues → routing, in that order, and the
   order is the meaning. Rendering all of it as one flat column lost that and
   made the screen unreadable (owner, 2026-08-20). Each step now carries its
   own answer while closed, and the fixed-width label column is what makes a
   stack of steps read as a table rather than a pile.                        */

.profile-steps {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.profile-step {
  border-radius: var(--radius-sm, 8px);
  border: 1px solid transparent;
  transition: border-color var(--dur-fast, 150ms) var(--ease-standard, ease);
}

.profile-step-open {
  background: var(--surface);
  border-color: var(--line);
}

.profile-step-head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-radius: var(--radius-sm, 8px);
  padding: 10px 12px;
  cursor: pointer;
  color: var(--ink);
  transition: background-color var(--dur-fast, 150ms) var(--ease-standard, ease);
}

.profile-step-head:hover {
  background: var(--color-surface-hover, rgba(255, 255, 255, 0.04));
}

.profile-step-num {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 0.65rem;
  color: var(--muted);
}

.profile-step-open .profile-step-num {
  border-color: var(--gold-dim);
  color: var(--gold);
}

/* Fixed width so every step's ANSWER starts at the same x — this single rule
   is most of what turns the stack into a readable table. */
.profile-step-label {
  flex: 0 0 auto;
  width: 11ch;
  font-size: 0.85rem;
  font-weight: 500;
}

.profile-step-summary-text {
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profile-step-caret {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.75rem;
}

.profile-step-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 6px 16px 18px 44px;
  animation: sov-fade-in var(--dur-fast) var(--ease-out) both;
}

.profile-sleeve-head-actions {
  display: flex;
  gap: 4px;
}

.profile-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* A single value is a single value — a full-1100px input for "main" or "mic"
   reads as a paragraph field and hides how short the real answer is. */
.profile-field > .sov-input,
.profile-measure-row > .sov-input {
  width: auto;
  max-width: 34ch;
}

/* .profile-field is a stretch column, so a bare button in it would span the
   pane and centre its own label — an "+ Add a measure" that looks like a
   primary full-width action it isn't. */
.profile-field > .btn,
.profile-confirm > .btn,
.profile-confirm > .sov-input {
  align-self: flex-start;
}

.profile-confirm > .sov-input {
  width: auto;
  min-width: 28ch;
}

.profile-field-label {
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.profile-field-help {
  font-size: 0.75rem;
  margin: 0;
  max-width: 72ch;
}

.profile-inline-field {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* .sov-input is width:100% by design; inside an inline field it must sit NEXT
   to its label rather than wrapping under it, or every one-line field reads as
   a full-width form row and the block structure disappears. */
.profile-inline-field .sov-input {
  width: auto;
  flex: 0 1 26ch;
  min-width: 14ch;
}

.profile-inline-label {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--muted);
  min-width: 12ch;
  flex: 0 0 auto;
}

.profile-inline-readonly {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink);
}

.profile-inline-error {
  color: var(--red);
  font-size: 0.75rem;
  margin: 0;
}

.profile-link-danger {
  color: var(--red);
}

.profile-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

/* Measure pipeline — the numbered index is the point: order IS the pipeline. */
.profile-measure-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.profile-measure-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm, 8px);
  padding: 8px 10px;
}

.profile-measure-index {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.profile-venue-rows {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.profile-venue-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--color-accent-dim, var(--gold-dim));
  border-radius: var(--radius-sm, 8px);
  padding: 12px 14px;
}

.profile-venue-row-fields {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* The instance/account picker (VENUE-INSTANCE-MODEL.md step three) sits under a
   venue row's own fields — same left rail, tighter gap since its rows are already
   inline fields, not a second fields row. */
.profile-venue-instance {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  margin-top: 2px;
}

/* Severity-colored replacement for the old plain-text binding facts line —
   "not usable on either mode" now reads differently at a glance from "no
   binding on record yet" (the common, non-error case) or "fully ready". */
.profile-venue-binding-chip {
  align-self: flex-start;
  font-size: 0.72rem;
}

/* Small icon-label buttons — "small useful buttons" for add/remove/duplicate
   actions that used to be bare text links. Icon size/spacing come from
   .sov-btn + .sov-icon; this only adds the danger-tint modifier .sov-btn-*
   doesn't have. */
.profile-icon-btn {
  font-size: 0.78rem;
  padding: 4px 10px;
}

.profile-icon-btn-danger {
  color: var(--red);
}

.profile-icon-btn-danger:hover:not(:disabled) {
  color: var(--red);
  background: rgba(244, 63, 94, 0.1);
}

/* An opt-in "Pro tip" — collapsed by default so a dense form doesn't drown in
   permanent help text; see Profiles.elm's viewProTip for when to reach for
   this instead of the always-visible .profile-field-help paragraph. */
.profile-protip-trigger {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.72rem;
  color: var(--muted);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.profile-protip-trigger:hover {
  color: var(--gold);
}

.profile-protip-body {
  margin: 4px 0 0;
  font-size: 0.75rem;
  max-width: 60ch;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--color-accent-soft);
  border: 1px solid var(--color-border-soft);
  color: var(--ink);
}

/* The blocking-issues list in the save bar — same red as .profile-inline-error
   but grouped, since Save can now be blocked by more than one field at once. */
.profile-savebar-issues {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.profile-savebar-issue {
  padding-left: 10px;
}

.profile-routing {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.profile-solve {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--surface);
  border: 1px dashed var(--color-border-strong, var(--line));
  border-radius: var(--radius-sm, 8px);
  padding: 14px 16px;
}

.profile-solve-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.profile-solve-result {
  border-top: 1px solid var(--line);
  padding-top: 8px;
}

.profile-solve-head {
  font-family: var(--mono);
  font-size: 0.8rem;
  margin: 0 0 4px;
}

.profile-solve-knobs {
  list-style: none;
  padding: 0;
  margin: 6px 0 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.78rem;
}

.profile-solve-key {
  font-family: var(--mono);
}

.profile-shared {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px;
}

.profile-shared h3 {
  margin: 0;
}

.profile-reflective {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.profile-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.profile-block-label {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
}

.profile-block-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-left: 1px solid var(--line);
  padding-left: 12px;
}

.profile-json-inline {
  margin: 0;
}

.profile-knob-pointer {
  font-size: 0.68rem;
  color: var(--muted);
  font-style: italic;
}

/* The generated knob editor. Groups fold by default and open when this
   profile actually sets something in them — see defaultExpandedGroups. */
.profile-knob-sleeve {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
}

.profile-knob-sleeve h3 {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.95rem;
}

/* Find-a-setting. The Tuning tab serves ~35 knobs per strategy and a profile
   typically sets two, so SEARCH — not an accordion hunt — is how an operator
   reaches the one they want (owner, 2026-08-20: "hard ... to find the knobs or
   settings to adjust"). */
.profile-knob-search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-card, 14px);
  padding: 8px 12px;
}

.profile-knob-search-icon {
  color: var(--muted);
  display: inline-flex;
  font-size: 1rem;
}

.profile-knob-search .sov-input {
  flex: 1;
  background: none;
  border: none;
  padding: 4px 0;
}

.profile-knob-search .sov-input:focus {
  box-shadow: none;
}

.profile-knob-sleeve-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}

.profile-knob-sleeve-count {
  font-size: 0.75rem;
  color: var(--muted);
  margin-right: auto;
}

/* A short result set has no use for accordions — and burying a search hit
   inside a closed group is the exact complaint the search box exists to fix. */
.profile-knob-flat {
  display: flex;
  flex-direction: column;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-card, 14px);
  box-shadow: var(--shadow-card);
  padding: 4px 16px;
}

.profile-knob-groups {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.profile-knob-group {
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-card, 14px);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.profile-knob-group-head {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 13px 16px;
  cursor: pointer;
  color: var(--ink);
}

.profile-knob-group-head:hover {
  background: var(--color-surface-hover, rgba(255, 255, 255, 0.04));
}

.profile-knob-group-caret {
  color: var(--muted);
  width: 1em;
}

.profile-knob-group-name {
  flex: 1;
  font-size: 0.9rem;
  font-weight: 600;
}

.profile-knob-group-count {
  font-size: 0.72rem;
  color: var(--muted);
}

.profile-knob-group-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 16px 14px;
  border-top: 1px solid var(--line);
}

.profile-knob {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}

.profile-knob:last-child {
  border-bottom: none;
}

.profile-knob-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.profile-knob-name {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--ink);
}

.profile-knob-state {
  font-size: 0.65rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 1px 7px;
  border: 1px solid currentColor;
}

.profile-knob-state-default {
  color: var(--muted);
}

.profile-knob-state-set {
  color: var(--gold);
}

.profile-knob-tag {
  font-size: 0.65rem;
  color: var(--muted);
}

.profile-knob-doc {
  font-size: 0.75rem;
  margin: 0;
  max-width: 78ch;
}

.profile-knob-input {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 40ch;
}

.profile-knob-meta {
  font-family: var(--mono);
  font-size: 0.68rem;
  margin: 0;
}

.profile-json-editor {
  width: 100%;
  min-height: 24rem;
  line-height: 1.5;
  white-space: pre;
}

/* ── Sleeves screen (Sleeves.elm) — 2026-09-17 ─────────────────────────────
   Sleeves.elm previously rendered with no dedicated CSS at all — only the
   generic .muted/.btn/.error/.sov-* primitives applied, and the only
   .sleeve-pill/.sleeve-badge/.sleeve-selector-bar/.sleeve-label rules
   elsewhere in this file belong to Ladders.elm's rung map, not this screen.
   This region gives every class Sleeves.elm actually emits its own rule.
   Reuses the same card shape, spacing tokens and knob-row language as the
   .profile-* block above (.profile-sleeve, .profile-venue-row,
   .profile-knob) since Profiles and Sleeves render side by side per PR3's
   plan — same palette, not a new one. .sleeve-card and
   .sleeves-compare-column pair with .sov-card for the card's background/
   border/radius/shadow; the rules here are layout only. */

.sleeves-panel {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.sleeves-profile-picker {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sleeves-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sleeve-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.sleeve-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.sleeve-card-compare-check {
  flex: 0 0 auto;
}

.sleeve-card-name {
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--gold-bright, var(--gold));
}

.sleeve-card-venues {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.sleeve-card-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* ── Compare bar — appears once 1+ cards are checked for comparison ── */

.sleeves-compare-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm, 8px);
  padding: 10px 14px;
}

/* ── Single-sleeve detail panel (the "Open" action) ── */

.sleeve-detail {
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-card, 14px);
  padding: 18px 20px;
  box-shadow: var(--shadow-elevated);
}

.sleeve-detail-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}

.sleeve-detail-actions {
  display: flex;
  gap: 8px;
}

/* ── Knob tree — shared shape between the single detail panel and each
   compare column ── */

.sleeve-knob-tree {
  display: flex;
  flex-direction: column;
}

.sleeve-knob-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}

.sleeve-knob-row:last-child {
  border-bottom: none;
}

.sleeve-knob-name {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--ink);
}

.sleeve-knob-value {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--muted);
}

/* ── Compare view — 2+ sleeves side by side ── */

.sleeves-compare {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.sleeves-compare-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.sleeves-compare-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
  align-items: start;
}

.sleeves-compare-column {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sleeves-compare-performance {
  font-family: var(--mono);
  font-size: 0.78rem;
}

/* ── Strategies & Backtesting (Strategies.elm) — 2026-09-17 ────────────────
   This screen shipped with zero dedicated CSS: its ~40 `strategies-*`
   classes (live/running bake-off cards, the leaderboard, the per-run
   attribution drill-in — waterfall, funnel, fold table, venue chart, trade
   blotter — and the full-config launch sheet) had no matching rule anywhere
   in this file, and `.sov-table` (used by three tables here) had none
   anywhere in the app. Everything below reuses the shapes already
   established by the Profiles/Sleeves regions just above (sov-card as the
   shell, a flex-column body with a consistent gap, eyebrow + value tiles)
   rather than inventing a new visual language, plus one shared `.sov-table`
   primitive other `.sov-*`-prefixed screens can now reach for too. */

/* `.sov-table` — the primitive itself. Same shape as the screen-local
   `.jobs-table`/`.venues-table` (bordered header row, bottom-ruled body
   rows, no outer border) so a table reads the same everywhere in Console;
   written once against canonical tokens instead of a fourth copy. */
.sov-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.sov-table th {
  text-align: left;
  padding: var(--space-2);
  font-family: var(--mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
}

.sov-table td {
  padding: var(--space-2);
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  vertical-align: middle;
}

.sov-table tr:last-child td {
  border-bottom: none;
}

.strategies-screen {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.strategies-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

/* The eyebrow + action row repeated at the top of every card on this screen
   (Running now / Leaderboard / Attribution / Venue attribution / ...). */
.strategies-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}

.strategies-active {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.strategies-live-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.strategies-live-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.strategies-bench-line {
  margin: 0;
  font-size: var(--text-sm);
}

.strategies-live-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.strategies-live-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 90px;
}

/* `strategies-firm` decorates the existing `.sov-chip`/`.sov-chip-success` —
   just keeps the badge from stretching to fill `.strategies-live-tile`. */
.strategies-firm {
  align-self: flex-start;
}

.strategies-leaderboard {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* `strategies-table` sits on top of `.sov-table` above — this screen's three
   tables run wide (up to 8 columns of dense per-fold/per-pair numbers), so
   the table itself scrolls horizontally rather than overflowing the card,
   the same problem `.jobs-table-wrap` exists to solve, but this screen has
   no wrapper div to hang that fix on. */
.strategies-table {
  display: block;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.strategies-table td[colspan] {
  text-align: center;
}

.strategies-sortable {
  cursor: pointer;
  user-select: none;
}

.strategies-sortable:hover {
  color: var(--ink);
}

.strategies-row {
  cursor: pointer;
  transition: background-color var(--dur-fast, 150ms) var(--ease-standard, ease);
}

.strategies-row:hover {
  background: var(--color-surface-hover);
}

.strategies-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.strategies-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.strategies-tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 130px;
  padding: 14px 16px;
}

.strategies-tile-value {
  font-size: var(--text-xl, 1.375rem);
  font-weight: 600;
  color: var(--ink);
}

.strategies-outcomes {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.strategies-outcome-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.strategies-outcome-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 160px;
  padding: 14px 16px;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm, 8px);
}

.strategies-waterfall {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.strategies-wf-row {
  display: grid;
  grid-template-columns: 15ch 1fr 9ch;
  align-items: center;
  gap: 10px;
}

.strategies-wf-label {
  font-size: var(--text-sm);
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.strategies-wf-track {
  position: relative;
  height: 10px;
  background: var(--surface-raised);
  border-radius: var(--radius-sm, 8px);
  overflow: hidden;
}

/* Width is set inline per row (proportional to the largest line in the
   waterfall); `.strategies-bar-pos`/`-neg` (set from `barClass` in
   viewWaterfallRow) carry only the color. */
.strategies-wf-bar {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  border-radius: var(--radius-sm, 8px);
  transition: width var(--dur-base, 220ms) var(--ease-standard, ease);
}

.strategies-bar-pos {
  background: var(--emerald);
}

.strategies-bar-neg {
  background: var(--red);
}

.strategies-wf-value {
  text-align: right;
}

.strategies-efficiency {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.strategies-funnel {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.strategies-venues {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.strategies-folds {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.strategies-diagnosis {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.strategies-diagnosis p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--muted);
}

.strategies-trades {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* The launch sheet is a full-screen modal — same overlay shape as
   `.sov-modal-backdrop` (fixed, centered, blurred scrim) reused here under
   this screen's own class name, since Strategies.elm's markup predates that
   shared primitive and isn't touched by this pass. */
.strategies-launch-backdrop {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  padding: var(--space-4);
  box-sizing: border-box;
  animation: sov-fade-in var(--dur-base, 220ms) var(--ease-out) both;
}

.strategies-launch-sheet {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
  max-width: 680px;
  max-height: 90vh;
  overflow-y: auto;
}

.strategies-launch-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.strategies-launch-row > * {
  flex: 1 1 160px;
}

.strategies-launch-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* Same shape as `.profile-field` above — an eyebrow label stacked over a
   single input, one column. */
.strategies-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.ladders-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.ladders-head h2 {
  margin: 0;
}

.ladders-body > * {
  animation: sov-fade-in var(--dur-slow) var(--ease-out) both;
}

.ladders-empty,
.ladders-error {
  padding: 18px 4px;
  text-align: center;
}

.ladder-list,
.ladder-stage-jobs {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ladder-rounds {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ── Jobs list (filter chips + non-ladder summary rows) ─────────────── */

.jobs-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.jobs-kind-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.jobs-kind-pick {
  cursor: pointer;
}

.jobs-kind-pick-active {
  background: rgba(var(--gold-soft-rgb), 0.1);
  border-color: var(--gold-dim);
  color: var(--ink);
}

.jobs-summary-section {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.jobs-summary-title {
  margin: 0;
  font-size: 0.85rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ── Jobs management (Jobs.elm) ──────────────────────────────────────
   The screen's own layout, plus the three things its rules demand be
   visually distinct rather than merely present: live progress on a
   running job, a "finished but produced nothing" outcome that does NOT
   read as a plain success, and a confirmation panel for consequential
   actions that cannot be mistaken for an ordinary button.

   `.jobs-summary-row`/`-type`/`-id` were removed here — the flat 3-cell
   row they styled is gone, replaced by `.jobs-row` below. */

.jobs-wrap,
.jobs-screen {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.jobs-head {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.jobs-live-badge {
  font-size: var(--text-xs);
  white-space: nowrap;
}

.jobs-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Record counts. One per job straight from the Desk's registry — see
   Jobs.elm's counting note for why nothing trade-derived is summed. */

.jobs-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.jobs-stat {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.jobs-stat-n {
  font-size: var(--text-lg);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.jobs-stat-label {
  font-size: var(--text-xs);
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.jobs-stat-accent { border-color: var(--gold-dim); }
.jobs-stat-accent .jobs-stat-n { color: var(--gold); }
.jobs-stat-ok .jobs-stat-n { color: var(--emerald); }
.jobs-stat-warn { border-color: rgba(245, 158, 11, 0.35); }
.jobs-stat-warn .jobs-stat-n { color: var(--amber); }
.jobs-stat-bad .jobs-stat-n { color: var(--red); }

.jobs-filters {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.jobs-type-filter {
  padding-top: var(--space-1);
  border-top: 1px solid var(--line);
}

/* Selection + purge. Deliberately its own bar, well away from any row's
   Stop control — the two must never sit side by side. */

.jobs-selection-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-2) var(--space-3);
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.jobs-selection-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.jobs-purge-all {
  color: var(--ink-faint);
}

.jobs-select-box {
  flex: 0 0 auto;
  width: 1.125rem;
  height: 1.125rem;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  line-height: 1;
  border: 1px solid var(--color-border-strong);
  border-radius: 4px;
  background: transparent;
  color: var(--ground);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard);
}

.jobs-select-box-on {
  background: var(--gold);
  border-color: var(--gold);
}

/* A running job gets an inert placeholder, not a checkbox that would
   imply an action the Desk will refuse. */
.jobs-select-box-off {
  border-style: dashed;
  border-color: var(--line);
  cursor: default;
}

.jobs-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  background: rgba(22, 27, 34, 0.75);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-left: 3px solid rgba(255, 255, 255, 0.15);
  border-radius: 10px;
  padding: 14px 18px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2);
  transition:
    border-color var(--dur-fast, 150ms) var(--ease-standard, ease),
    box-shadow var(--dur-fast, 150ms) var(--ease-standard, ease),
    background var(--dur-fast, 150ms) var(--ease-standard, ease);
}

.jobs-row:hover {
  background: rgba(30, 38, 48, 0.85);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
}

.jobs-row-running {
  border-left-color: #d4a017;
  box-shadow: 0 4px 16px rgba(212, 160, 23, 0.08);
}
.jobs-row-warn { border-left-color: #d29922; }
.jobs-row-bad { border-left-color: #f85149; }

.jobs-row-main {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.jobs-row-ident {
  flex: 1;
  min-width: 12rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.jobs-row-type {
  font-size: var(--text-base);
}

.jobs-row-params,
.jobs-row-when {
  font-size: var(--text-xs);
  font-family: var(--mono);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.jobs-row-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

.jobs-stop {
  color: var(--red);
}

.jobs-stopping {
  font-size: var(--text-xs);
}

.jobs-row-progress {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.jobs-row-progress-line,
.jobs-row-outcome {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
}

.jobs-row-outcome-warn {
  color: var(--amber);
}

/* ── Expanded detail ─────────────────────────────────────────────── */

.jobs-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-1);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}

.jobs-detail-head {
  margin: 0;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-faint);
}

.jobs-detail-grid {
  display: grid;
  grid-template-columns: minmax(6rem, max-content) 1fr;
  gap: var(--space-1) var(--space-4);
  font-size: var(--text-sm);
}

.jobs-detail-key {
  font-size: var(--text-xs);
}

.jobs-detail-value {
  font-family: var(--mono);
  font-size: var(--text-xs);
  overflow-wrap: anywhere;
}

.jobs-detail-note {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--leading-relaxed);
}

.jobs-detail-path {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--text-xs);
  overflow-wrap: anywhere;
  color: var(--ink-muted);
}

.jobs-detail-error {
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--color-danger-bg);
}

/* ── Notice + confirmation ───────────────────────────────────────
   The confirmation is a full-width panel with its own border and its
   own danger button, not an inline "are you sure?" beside the control
   that opened it — a stop and a purge must never be one slip apart. */

.jobs-notice {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  font-size: var(--text-sm);
}

.jobs-notice p {
  margin: 0;
  line-height: var(--leading-normal);
}

.jobs-notice-ok {
  background: var(--color-success-bg);
  border-color: rgba(16, 185, 129, 0.3);
}

.jobs-notice-bad {
  background: var(--color-danger-bg);
  border-color: rgba(244, 63, 94, 0.35);
}

/* Sticky, and load-bearing rather than decorative: the Stop control that
   opens this panel can be forty rows down the list, and a consequential
   action whose confirmation appeared off-screen would read as "the button
   did nothing" — which is how a second, harder click happens. Pinning it
   to the top of the viewport means the confirmation is always the thing
   you are looking at, wherever in the list you clicked from. It needs an
   OPAQUE background for the same reason (the surface tokens are
   translucent, and list rows scrolling visibly under a stop confirmation
   is exactly the ambiguity this panel exists to remove — hence
   --surface-opaque, added to tokens.css for this). */
.jobs-confirm {
  position: sticky;
  top: var(--space-2);
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--red);
  border-radius: var(--radius-card);
  background: var(--surface-opaque);
  box-shadow: var(--shadow-modal);
}

.jobs-confirm-title {
  margin: 0;
  font-size: var(--text-lg);
}

.jobs-confirm-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  font-size: var(--text-sm);
}

.jobs-confirm-body p {
  margin: 0;
  line-height: var(--leading-relaxed);
}

.jobs-confirm-warning {
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--color-danger-bg);
  color: var(--ink);
}

.jobs-confirm-ids {
  margin: 0;
  padding-left: var(--space-5);
  font-family: var(--mono);
  font-size: var(--text-xs);
  max-height: 12rem;
  overflow-y: auto;
}

.jobs-confirm-actions {
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
  flex-wrap: wrap;
}

.jobs-strong {
  color: var(--ink);
  font-family: var(--mono);
}

@media (max-width: 640px) {
  .jobs-row-actions {
    margin-left: 0;
    width: 100%;
    justify-content: flex-end;
  }

  .jobs-detail-grid {
    grid-template-columns: 1fr;
    gap: 0 0;
  }

  .jobs-detail-grid .jobs-detail-key {
    margin-top: var(--space-2);
  }
}

.ladder-promote-cell {
  white-space: nowrap;
}

.ladder-round {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 4px 14px 14px;
}

.ladder-round-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 0;
  cursor: pointer;
  list-style: none;
}

.ladder-round-summary::-webkit-details-marker {
  display: none;
}

.ladder-round-name {
  font-family: var(--serif);
  font-size: 1rem;
}

.ladder-round-count {
  font-size: 0.75rem;
}

.ladder-stage {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 10px;
}

.ladder-stage:not(:first-of-type) {
  margin-top: 6px;
  border-top: 1px solid var(--line);
}

.ladder-stage-name {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.ladder-rung-param-line {
  margin: 0;
  font-size: 0.75rem;
}

/* Location trail — the one line saying where in the four-level ladder
   drill the reader is. Rendered once, above every level, so it holds the
   same place on screen at every depth. Wraps rather than truncating: a
   stage name is the most useful segment and is also the longest. */
.ladder-trail {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  font-size: 0.8125rem;
}

.ladder-trail-sep {
  color: var(--ink-faint);
}

.ladder-trail-step {
  padding: 0;
  font-size: inherit;
}

/* The current level. Deliberately not a link and visibly the heaviest
   segment — the trail's job is answering "where am I", so the answer has
   to be the part the eye lands on. */
.ladder-trail-here {
  font-family: var(--mono);
  color: var(--ink);
}

.ladder-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px;
  cursor: pointer;
  transition: border-color var(--dur-fast, 150ms) var(--ease-standard, ease);
}

.ladder-card:hover {
  border-color: var(--gold-dim);
}

.ladder-card-skeleton {
  cursor: default;
}

.ladder-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.ladder-card-field {
  margin: 0;
  font-family: var(--serif);
  font-size: 1rem;
}

.ladder-card-values {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.8125rem;
}

.ladder-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.75rem;
}

.ladder-detail {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ladder-detail-head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.ladder-detail-head h3 {
  margin: 0;
  font-family: var(--serif);
}

.sov-desk-select {
  padding: 4px 10px;
  font-family: var(--mono);
  font-size: 0.75rem;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 8px;
  cursor: pointer;
}


.ladder-map-wrapper {
  margin-bottom: 28px;
  padding: 24px;
  background: rgba(15, 23, 42, 0.65);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
}

/* flex-wrap + gap added 2026-08-14: the header's left column is a title AND a
   sentence of explanatory copy, and a nowrap flex row let that copy slide under
   the action button at narrow widths instead of wrapping above it. */
.ladder-map-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: 20px;
}

.ladder-map-header > div:first-child {
  flex: 1 1 22rem;
  min-width: 0;
}

.ladder-map-title {
  margin: 0 0 4px 0;
  font-size: 1.25rem;
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.01em;
}

.ladder-map-subtitle {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

.ladder-map-frame {
  position: relative;
  display: flex;
  justify-content: center;
  padding: 12px 24px;
}

.ladder-map-rail {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 6px;
  background: linear-gradient(180deg, var(--gold-bright), var(--gold-dim));
  border-radius: 4px;
  box-shadow: 0 0 12px rgba(212, 175, 55, 0.4);
}

.ladder-map-rail-left {
  left: 20px;
}

.ladder-map-rail-right {
  right: 20px;
}

.ladder-map-rungs {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
  max-width: 900px;
  z-index: 1;
}

.ladder-map-step {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 20px;
  background: rgba(22, 27, 38, 0.6);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

.ladder-map-step:hover {
  transform: scale(1.015);
  background: rgba(30, 38, 54, 0.85);
  border-color: var(--gold);
  box-shadow: 0 8px 32px rgba(212, 175, 55, 0.15);
}

.ladder-map-step-num {
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--gold);
  white-space: nowrap;
}

.ladder-map-step-icon {
  font-size: 1.5rem;
  line-height: 1;
}

.ladder-map-step-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex-grow: 1;
}

.ladder-map-step-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.ladder-map-step-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: #f8fafc;
}

.ladder-map-step-param {
  font-family: var(--mono);
  font-size: 0.8125rem;
  color: var(--gold);
  font-weight: 500;
}

.ladder-map-step-desc {
  margin: 0;
  font-size: 0.75rem;
  color: var(--ink-faint);
}

.ladder-map-step-arrow {
  font-size: 1.25rem;
  color: var(--ink-faint);
  transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.ladder-map-step:hover .ladder-map-step-arrow {
  transform: translateX(6px);
  color: var(--gold);
}

/* MODAL OVERLAY POPUP */
.sov-modal-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(12px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  animation: sovFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}

.sov-modal-card {
  width: 90%;
  max-width: 600px;
  background: linear-gradient(145deg, rgba(20, 26, 38, 0.95), rgba(12, 15, 22, 0.98));
  border: 1px solid var(--gold-dim);
  border-radius: 16px;
  padding: 32px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(255, 255, 255, 0.05) inset;
  animation: sovSlideUp 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes sovSlideUp {
  from {
    opacity: 0;
    transform: translateY(20px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.sov-modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.sov-modal-title {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 700;
  color: #fff;
}

.sov-modal-close {
  font-size: 1.25rem;
  color: var(--ink-faint);
  cursor: pointer;
}

.sov-modal-rung-selector {
  margin-bottom: 16px;
}

.sov-modal-rung-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.sov-rung-params-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.sov-rung-param-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--text-base);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.sov-rung-param-row:hover {
  border-color: rgba(var(--gold-soft-rgb), 0.4);
  background: var(--color-surface-hover);
}

.sov-rung-param-label {
  font-family: var(--mono);
  color: var(--muted);
}

.sov-rung-param-value {
  font-family: var(--mono);
  font-weight: 600;
  color: var(--gold);
}

.sov-chip-primary {
  background: rgba(212, 175, 55, 0.15);
  color: var(--gold);
  border: 1px solid rgba(212, 175, 55, 0.4);
  font-family: var(--mono);
  font-weight: 600;
  transition: all 0.2s ease;
}

.sov-chip-primary:hover {
  background: rgba(212, 175, 55, 0.25);
  border-color: var(--gold);
}

.sov-chip-primary.active {
  background: linear-gradient(135deg, rgba(212, 175, 55, 0.9), rgba(255, 215, 0, 0.8));
  color: #0f172a;
  border-color: transparent;
  box-shadow: 0 4px 12px rgba(212, 175, 55, 0.3);
}

.sov-chip-neutral {
  background: rgba(255, 255, 255, 0.05);
  color: var(--ink);
  border: 1px solid var(--line);
  font-family: var(--mono);
  cursor: pointer;
}

.sov-chip-warning {
  background: rgba(245, 158, 11, 0.2);
  color: #f59e0b;
  border: 1px solid #f59e0b;
  font-family: var(--mono);
  font-weight: 600;
}

.sov-pulse {
  animation: sovPulse 1.5s infinite ease-in-out;
}

@keyframes sovPulse {
  0% {
    box-shadow: 0 0 0 0 rgba(212, 175, 55, 0.6);
  }
  70% {
    box-shadow: 0 0 0 8px rgba(212, 175, 55, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(212, 175, 55, 0);
  }
}

.sov-modal-metrics-sub {
  text-align: center;
  margin-top: 8px;
  font-size: 0.75rem;
}

.sov-modal-metrics-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin: 20px 0;
}

.sov-metric-card {
  display: flex;
  flex-direction: column;
  padding: 16px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  text-align: center;
  transition: all 0.2s ease;
}

.sov-metric-card:hover {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(212, 175, 55, 0.2);
}

.ladder-journey-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.ladder-journey-title {
  margin: 0 0 4px 0;
  font-size: 1.125rem;
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.01em;
}

.ladder-journey-desc {
  margin: 0;
  font-size: 0.75rem;
  color: var(--ink-faint);
}

.ladder-journey-stages {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}

.ladder-stage-card {
  display: flex;
  gap: 12px;
  padding: 12px 14px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  transition: transform 0.15s ease, border-color 0.15s ease;
}

.ladder-stage-card:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 255, 255, 0.2);
}

.sov-metric-val {
  font-family: var(--mono);
  font-size: 1.125rem;
  font-weight: 700;
  color: #fff;
  margin-top: 4px;
}

.sov-metric-val.green {
  color: #4ade80;
}

.sov-modal-actions {
  display: flex;
  gap: 12px;
  margin-top: 20px;
}

.ladder-stage-card-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-accent-dim, rgba(64, 196, 255, 0.15));
  color: #38bdf8;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 0.8125rem;
  flex-shrink: 0;
}

.ladder-stage-card-content {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
}

.ladder-stage-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}

.ladder-stage-card-title {
  font-size: 0.75rem;
  font-weight: 600;
  color: #e2e8f0;
}

.ladder-stage-card-param {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: #38bdf8;
  font-weight: 500;
}

.ladder-stage-card-desc {
  margin: 0;
  font-size: 0.6875rem;
  line-height: 1.3;
  color: var(--ink-faint);
}

.ladder-rung-table-wrap {
  overflow-x: auto;
}

.ladder-rung-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}

.ladder-rung-table th,
.ladder-rung-table td {
  padding: 8px 10px;
  text-align: left;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

.ladder-rung-table th {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.ladder-rung-table td.num {
  font-family: var(--mono);
  text-align: right;
}

.ladder-delta-cell {
  font-family: var(--mono);
}

.ladder-delta-tag {
  display: inline-block;
  font-family: var(--mono);
  font-weight: 500;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--surface-subtle);
  border: 1px solid var(--line);
}

.ladder-days-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

.ladder-days-cell .ladder-progress-track {
  width: 56px;
}

/* ─────────────────────────────────────────────────────────────────────────
   LADDERS — "tuning a sleeve" (2026-08-14)

   Three ideas, in the order they appear on screen:

   1. .ladder-tuning-* — the subject bar. What profile, what strand, what
      strategy, and whether the Desk is actually running it. Reads as a
      breadcrumb rather than a card because it is context for everything
      below, not a thing to interact with.
   2. .ladder-evidence-* — the measurement window. A thin window (one day) is
      the ONE place on this screen that gets the danger colour with no
      opt-out: it is a claim about how much a number is worth, and this desk
      has been burned by a one-day result before.
   3. .ladder-promote-* / .ladder-lens-* — the confirmation for the write, and
      the six-number lens that must never collapse to one headline figure.

   Tokens only, no literals (styles/README.md) — with two exceptions marked
   inline where an existing neighbouring rule already uses the same rgba().
   ───────────────────────────────────────────────────────────────────────── */

.ladder-tuning-target {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
  border: 1px solid var(--line);
  border-left: 2px solid var(--gold);
  border-radius: var(--radius-card);
  background: var(--surface);
}

.ladder-tuning-crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.ladder-tuning-verb {
  font-family: var(--mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.ladder-tuning-key {
  font-family: var(--mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ladder-tuning-value {
  font-family: var(--mono);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--gold);
}

.ladder-tuning-sep {
  color: var(--ink-faint);
}

.ladder-tuning-note {
  margin: 0;
  font-size: var(--text-sm);
  line-height: 1.45;
}

/* The measurement window. .ladder-evidence-thin is the one-day (or
   shorter-than-the-objective-asks) state — deliberately the loudest thing on
   the page, because the numbers beside it are a hypothesis. */
.ladder-evidence {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-2) var(--space-3);
  margin: var(--space-3) 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.ladder-evidence-thin {
  border-color: var(--color-danger);
  background: var(--color-danger-bg);
}

.ladder-evidence-count {
  font-family: var(--mono);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}

.ladder-evidence-days {
  font-family: var(--mono);
  font-size: var(--text-sm);
}

.ladder-evidence-warn {
  flex-basis: 100%;
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--color-danger);
}

.ladder-evidence-badge {
  font-size: var(--text-xs);
}

/* The Desk's own multi-criteria pick. A tint and a mark, never a re-sort:
   the table's row order is the order the ladder ran, and sorting by any one
   column is exactly the lens this screen refuses to teach. */
.ladder-rung-table-note {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--text-sm);
  line-height: 1.5;
  max-width: 78ch;
}

.ladder-rung-row-best {
  background: var(--color-accent-soft);
}

.ladder-rung-best-mark {
  color: var(--gold);
}

/* PROMOTE — the one action here that writes to a live profile. The background
   is stated OPAQUELY rather than inheriting .sov-modal-card's 0.95/0.98 alpha:
   this is the one dialog where a number read wrong costs something, and the
   rung table it sits over is dense enough to show through at 0.95. */
.ladder-promote-confirm {
  max-width: 34rem;
  background: linear-gradient(145deg, #141a26, #0c0f16);
}

.ladder-promote-rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.ladder-promote-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--line);
}

.ladder-promote-row-label {
  font-family: var(--mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ladder-promote-row-value {
  font-family: var(--mono);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--gold);
  text-align: right;
  word-break: break-word;
}

.ladder-promote-evidence {
  margin-top: var(--space-4);
}

.ladder-promote-evidence-head {
  margin: 0 0 var(--space-2) 0;
  font-family: var(--mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ladder-promote-evidence p {
  margin: var(--space-2) 0 0 0;
  font-size: var(--text-sm);
  line-height: 1.45;
}

.ladder-promote-verdict {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Six numbers, never one — see viewRungLensGrid's doc comment. Wraps to two
   columns rather than shrinking the type: the point is that all six are
   readable together. */
.ladder-lens-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
  margin: var(--space-3) 0;
}

.ladder-lens-card {
  padding: var(--space-3);
  gap: var(--space-1);
}

.ladder-lens-dir {
  font-size: var(--text-xs);
  line-height: 1.3;
}

.ladder-modal-deltas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  text-align: left;
}

.ladder-runs-head {
  margin: var(--space-6) 0 var(--space-1) 0;
  font-size: var(--text-lg);
}

.ladder-runs-note {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--text-sm);
  line-height: 1.5;
  max-width: 78ch;
}

@media (max-width: 720px) {
  .ladder-lens-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .ladder-promote-row {
    flex-direction: column;
    gap: var(--space-1);
  }

  .ladder-promote-row-value {
    text-align: left;
  }
}

.ladder-delta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ladder-live-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ladder-live-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.ladder-live-head h3 {
  margin: 0;
  font-family: var(--serif);
  font-size: 1rem;
}

.ladder-live-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ladder-day-chip {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 132px;
  padding: 8px 10px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
}

.ladder-day-chip-running {
  border-color: var(--color-accent-dim);
}

.ladder-day-chip-name {
  font-family: var(--mono);
  font-size: 0.6875rem;
  color: var(--ink-faint);
}

.ladder-day-chip-detail {
  margin: 0;
  font-size: 0.6875rem;
  line-height: 1.35;
}

.ladder-progress-track {
  height: 4px;
  background: var(--line);
  border-radius: 2px;
  overflow: hidden;
}

.ladder-progress-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: 2px;
  transition: width 400ms ease;
}

/* ── Ladder drill-down: Round > Stage > Tier > Rung ──────────────────
   The four-level navigation in Ladders.elm. One visual language repeated at
   every depth on purpose: the SAME status bar, state chip, and stale banner
   render a round, a stage, and a tier, so an operator learns to read the
   summary once and it means the same thing wherever they are. */

.ladder-drill {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ladder-drill-crumb {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ladder-drill-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.ladder-drill-head h3 {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.125rem;
}

.ladder-drill-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px;
  cursor: pointer;
  transition: border-color var(--dur-fast, 150ms) var(--ease-standard, ease);
}

.ladder-drill-card:hover {
  border-color: var(--gold-dim);
}

/* A tier card carries its own action buttons, so the card itself is not one
   big click target — only its ladder-tier-open region navigates. */
.ladder-drill-card-static,
.ladder-drill-card-static:hover {
  cursor: default;
}

.ladder-tier-open {
  display: flex;
  flex-direction: column;
  gap: 8px;
  cursor: pointer;
}

/* "Needs revalidation" is a third state, neither done nor failed — it gets its
   own left rail rather than borrowing the danger colour outright. */
.ladder-drill-card-stale {
  border-left: 3px solid var(--color-danger);
}

.ladder-drill-sub,
.ladder-drill-fields {
  margin: 0;
  font-size: 0.75rem;
}

.ladder-drill-fields {
  font-family: var(--mono);
}

.ladder-tier-best {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--color-success);
}

/* ── The status bar every level shares ─────────────────────────────── */

.ladder-verdict-wrap {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.ladder-verdict-bar {
  display: flex;
  width: 100%;
  height: 8px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--line);
}

.ladder-verdict-seg {
  height: 100%;
  flex-basis: 0;
}

.ladder-verdict-pass {
  background: var(--color-success);
}

.ladder-verdict-fail {
  background: var(--color-danger);
}

.ladder-verdict-insufficient {
  background: var(--gold-dim);
}

.ladder-verdict-unjudged {
  background: var(--ink-faint);
}

.ladder-verdict-legend,
.ladder-verdict-empty {
  margin: 0;
  font-size: 0.6875rem;
}

/* ── Stale banner + per-level actions ──────────────────────────────── */

.ladder-stale-banner {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  background: var(--color-danger-bg);
  border-radius: 10px;
  padding: 8px 10px;
}

.ladder-stale-reason {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.4;
}

.ladder-level-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.ladder-action-note {
  font-size: 0.75rem;
}

.ladder-action-failed {
  color: var(--color-danger);
}

/* ── Objective panel + per-rung verdict cell ───────────────────────── */

.ladder-objective {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 14px;
  border-radius: 12px;
}

.ladder-objective-best {
  margin: 0;
  font-size: 0.875rem;
}

.ladder-objective-spec {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.4;
}

.ladder-objective-max {
  font-family: var(--mono);
}

/* The objective's hard floors, one chip each — scanned, not read. */
.ladder-floor-chip {
  font-family: var(--mono);
  font-size: 0.6875rem;
}

.ladder-verdict-td {
  max-width: 260px;
}

.ladder-verdict-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
}

.ladder-verdict-reason {
  margin: 0;
  font-size: 0.6875rem;
  line-height: 1.35;
}

.ladder-rerun-cell,
.ladder-rerun-note {
  white-space: normal;
}

.ladder-rerun-note,
.ladder-fallback-note {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.4;
}

@media (max-width: 768px) {
  .live-candidate-table, .live-candidate-table tbody, .live-candidate-table tr, .live-candidate-table td {
    display: block !important;
    width: 100% !important;
  }
  .live-candidate-table thead, .live-candidate-table th {
    display: none !important;
  }
  .live-candidate-table tr {
    background: rgba(255, 255, 255, 0.02) !important;
    margin-bottom: 12px !important;
    border-radius: 12px !important;
    padding: 12px 16px !important;
    border: 1px solid rgba(255, 255, 255, 0.06) !important;
  }
  .live-candidate-table td {
    padding: 8px 0 !important;
    text-align: right !important;
    position: relative !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.04) !important;
    display: flex !important;
    justify-content: space-between !important;
    align-items: center !important;
  }
  .live-candidate-table td:last-child {
    border-bottom: none !important;
  }
  .live-candidate-table td:nth-child(1)::before { content: "Candidate Pair"; color: var(--ink-faint); font-weight: 600; }
  .live-candidate-table td:nth-child(2)::before { content: "Screen ρ"; color: var(--ink-faint); font-weight: 600; }
  .live-candidate-table td:nth-child(3)::before { content: "Spread z"; color: var(--ink-faint); font-weight: 600; }
  .live-candidate-table td:nth-child(4)::before { content: "Action / Kind"; color: var(--ink-faint); font-weight: 600; }
  .live-candidate-table td:nth-child(5)::before { content: "Diagnostic"; color: var(--ink-faint); font-weight: 600; }
}

/* ── Venues screen (Venues.elm) ───────────────────────────────────────────
   Built on the existing tokens and the .sov-* primitives (see
   src/styles/README.md) — no new visual language, no literal colors. The one
   genuinely new thing here is the credential form's masking, documented at
   .venues-secret-area below because it does NOT work in every browser. */

.venues-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.venues-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}

.venues-table th {
  text-align: left;
  padding: 6px 8px;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border-bottom: 1px solid var(--line);
}

.venues-table td {
  padding: 8px;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  vertical-align: middle;
}

.venues-table tr:last-child td {
  border-bottom: none;
}

.venues-wrap,
.venues-screen {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.venues-head {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
}

.venues-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.venues-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.venues-tab {
  cursor: pointer;
  border: 1px solid var(--color-border);
  background: transparent;
}

.venues-tab-active {
  border-color: var(--color-accent);
  color: var(--color-accent);
  background: var(--color-accent-soft);
}

.venues-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  animation: sov-fade-in var(--dur-slow) var(--ease-out) both;
}

.venues-panel-note,
.venues-hint {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

.venues-empty {
  margin: 0;
  padding: var(--space-6) 0;
  text-align: center;
}

.venues-mono {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}

/* ── Catalog ── */

.venues-catalog {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.venues-catalog-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  padding: var(--space-3) var(--space-4);
}

/* A disabled venue is dimmed, never hidden — an operator has to be able to see
   (and re-enable) what they switched off. */
.venues-catalog-row-off {
  opacity: 0.62;
}

.venues-catalog-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.venues-catalog-title {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.venues-catalog-label {
  font-size: var(--text-base);
  color: var(--color-ink);
}

.venues-catalog-meta,
.venues-catalog-note {
  margin: 0;
  font-size: var(--text-sm);
}

/* ── Credentials & proof ── */

.venues-vault {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
}

.venues-vault-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}

.venues-vault-head h3 {
  margin: 0;
  font-size: var(--text-lg);
}

.venues-vault-summary {
  margin: 0;
  font-size: var(--text-base);
  color: var(--color-ink);
}

.venues-vault-names {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  word-break: break-all;
}

.venues-cred-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.venues-cred-card,
.venues-cap-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
}

.venues-cred-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.venues-cred-name {
  font-family: var(--font-mono);
  font-size: var(--text-md);
  color: var(--color-ink);
}

.venues-cred-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.venues-cred-field {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-sm);
  padding: var(--space-1) 0;
  border-bottom: 1px solid var(--color-border);
}

.venues-cred-field:last-child {
  border-bottom: none;
}

.venues-cred-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.venues-probe-state {
  margin: 0;
  font-size: var(--text-sm);
}

.venues-probe-state p {
  margin: 0 0 var(--space-1) 0;
}

/* ── The credential form ── */

.venues-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-3);
}

.venues-form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.venues-form-field label {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.venues-form-label {
  font-size: var(--text-base);
  color: var(--color-ink);
}

.venues-form-actions {
  display: flex;
  gap: var(--space-2);
}

/* A PEM private key is genuinely multi-line, so it cannot be a password input
   (which strips the newlines that make it a valid key). `-webkit-text-security`
   masks a textarea's contents in Chrome and Safari; FIREFOX DOES NOT SUPPORT IT
   and will show the pasted key. Stated here rather than assumed — the field is
   still never persisted by this app and is dropped from the model on save, so
   the exposure is "visible while pasting", not "stored". */
.venues-secret-area {
  -webkit-text-security: disc;
  font-family: var(--font-mono);
  resize: vertical;
  width: 100%;
}

/* ── Proof detail ── */

.venues-proof {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-3);
}

.venues-proof h3 {
  margin: 0;
  font-size: var(--text-base);
  color: var(--color-ink);
}

.venues-proof-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.venues-proof ul {
  margin: 0;
  padding-left: var(--space-5);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

.venues-cell {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.venues-cell:last-child {
  border-bottom: none;
}

.venues-cell-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-sm);
}

.venues-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  display: block;
  overflow-x: auto;
}

.venues-table th {
  text-align: left;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted-soft);
  padding: var(--space-2) var(--space-3) var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}

.venues-table td {
  padding: var(--space-2) var(--space-3) var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
}

.venues-table tr:last-child td {
  border-bottom: none;
}

.venues-source {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  word-break: break-word;
}

/* ── Notices: three outcomes that must stay distinguishable ── */

.venues-notice {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-card);
  border: 1px solid var(--color-border);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

.venues-notice-good {
  border-color: var(--color-success);
  background: var(--color-success-bg);
  color: var(--color-ink);
}

.venues-notice-warn {
  border-color: var(--color-warning);
  background: var(--color-warning-bg);
  color: var(--color-ink);
}

.venues-notice-bad {
  border-color: var(--color-danger);
  background: var(--color-danger-bg);
  color: var(--color-ink);
}

.venues-error {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.venues-fold {
  /* Sits directly under the head row now (VenueInstances.elm's
     viewAdapterSection), so the rule separates it from what follows rather
     than what came before. */
  margin-bottom: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px dashed var(--line);
}

.venues-fold-toggle {
  margin-left: auto;
}

.venues-why {
  display: block;
  margin-top: var(--space-1);
}

.venues-why-warning {
  /* No .warning rule exists in this sheet; reuses .sov-chip-warning's colour
     token so a degraded why reads as caution, not failure. */
  color: #f59e0b;
  font-size: 0.8125rem;
  margin: 0;
}

@media (max-width: 768px) {
  .venues-catalog-row {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }

  .venues-cred-field {
    flex-direction: column;
    gap: 0;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   LADDER COMPOSER (LadderPlan.elm) — "which ladder do I want to run"

   A five-step sheet inside the existing .sov-modal-card shell, so it inherits
   the app's one modal treatment rather than introducing a second one. Only the
   step scaffolding, the pickers and the preview are new here.
   ───────────────────────────────────────────────────────────────────────── */

.ladder-plan-card {
  max-width: 760px;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}

.ladder-plan-body {
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-4, 20px);
  padding-right: 4px;
}

.ladder-plan-step-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.ladder-plan-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--gold-dim);
  color: var(--gold);
  font-family: var(--mono);
  font-size: 0.75rem;
}

.ladder-plan-step-title {
  font-weight: 600;
  color: #fff;
}

.ladder-plan-types {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
}

.ladder-plan-type {
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.ladder-plan-type:hover {
  border-color: rgba(var(--gold-soft-rgb), 0.4);
  background: var(--color-surface-hover);
}

.ladder-plan-type.active {
  border-color: var(--gold);
  background: rgba(212, 175, 55, 0.12);
}

.ladder-plan-type-id {
  font-family: var(--mono);
  font-weight: 600;
  color: var(--gold);
}

.ladder-plan-type-varies,
.ladder-plan-type-kind {
  font-size: var(--text-sm, 0.8125rem);
}

.ladder-plan-knobs {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 260px;
  overflow-y: auto;
}

.ladder-plan-knob-group-label {
  font-family: var(--mono);
  font-size: var(--text-sm, 0.8125rem);
  margin-bottom: 4px;
}

.ladder-plan-knob-rows {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 6px;
}

.ladder-plan-knob {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}

.ladder-plan-knob:hover {
  border-color: rgba(var(--gold-soft-rgb), 0.4);
  background: var(--color-surface-hover);
}

.ladder-plan-knob.active {
  border-color: var(--gold);
  background: rgba(212, 175, 55, 0.12);
}

.ladder-plan-knob-name {
  font-family: var(--mono);
  flex: 1 1 auto;
}

.ladder-plan-knob-current {
  font-family: var(--mono);
  font-weight: 600;
  color: var(--gold);
}

.ladder-plan-knob-default {
  font-size: var(--text-sm, 0.8125rem);
}

.ladder-plan-values {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.ladder-plan-values-help {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  font-size: var(--text-sm, 0.8125rem);
}

.ladder-plan-tapes {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ladder-plan-tapes-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.ladder-plan-tape-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-height: 180px;
  overflow-y: auto;
}

.ladder-plan-tape {
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  font-family: var(--mono);
  font-size: var(--text-sm, 0.8125rem);
  cursor: pointer;
}

.ladder-plan-tape.selected {
  border-color: var(--gold);
  background: rgba(212, 175, 55, 0.15);
  color: var(--gold);
}

.ladder-plan-labels {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ladder-plan-preview {
  border-top: 1px solid var(--line);
  padding-top: 14px;
}

.ladder-plan-cost {
  color: var(--ink);
}

.ladder-plan-json {
  margin: 8px 0;
  padding: 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.35);
  color: var(--ink);
  font-family: var(--mono);
  font-size: var(--text-sm, 0.8125rem);
  max-height: 220px;
  overflow: auto;
  white-space: pre;
}

.ladder-plan-notes {
  margin: 8px 0 0;
  padding-left: 18px;
  font-size: var(--text-sm, 0.8125rem);
}

.ladder-plan-notes-error {
  color: var(--danger, #f87171);
}

.ladder-plan-notes-warn {
  color: var(--warning, #fbbf24);
}

.sov-modal-footer {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

/* Advisory lock-acquire modal (viewLockModal, SovereignAgents.elm:2293). It
   sits inside the existing .modal-backdrop (styles.css:786), but its own
   markup — header with a title and a close button, a body, a footer with
   action buttons — is the .sov-modal-* shape used throughout Ladders.elm and
   LadderPlan.elm (.sov-modal-header/-title/-close/-body/-footer), not the
   single-use .modal-panel/.modal-head pair in the Add Desk modal (Main.elm),
   which has no dedicated close/body/footer classes at all. Styled to match
   the .sov-modal-* family's visual language under this modal's own class
   names, since it does not use the .sov-modal-* classes itself. */

.modal-dialog {
  width: 100%;
  max-width: 480px;
  background: linear-gradient(145deg, rgba(20, 26, 38, 0.95), rgba(12, 15, 22, 0.98));
  border: 1px solid var(--gold-dim);
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(255, 255, 255, 0.05) inset;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.modal-header h3 {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--ink);
}

.modal-close {
  background: none;
  border: 0;
  padding: 0;
  font-size: 1.25rem;
  line-height: 1;
  color: var(--ink-faint);
  cursor: pointer;
}

.modal-close:hover {
  color: var(--ink);
}

.modal-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.modal-body p {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--text-sm);
}

.input-field {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-raised);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  line-height: 1.25rem;
}

.input-field::placeholder {
  color: var(--ink-faint);
}

.input-field:focus {
  outline: none;
  border-color: var(--gold-dim);
  box-shadow: 0 0 0 3px var(--gold-glow);
}

.modal-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 20px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

.ladder-map-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.sov-rung-param-default {
  font-family: var(--mono);
  font-size: var(--text-sm, 0.8125rem);
}

/* Open positions — the live book, one row per position (LiveMonitoring.elm's
   viewOpenPositions; that screen was deleted 2026-09-17, console-shell PR 1).
   A grid rather than a table so the columns stay aligned across rows without
   a table's default spacing fighting the card. */
.live-positions {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 12px;
  border-top: 1px solid var(--line);
  padding-top: 10px;
}

.live-positions-head,
.live-positions-row {
  display: grid;
  grid-template-columns: minmax(90px, 1.4fr) 60px 80px 1fr 1fr;
  gap: 10px;
  align-items: baseline;
  padding: 5px 2px;
}

.live-positions-head {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.live-positions-row {
  border-top: 1px solid var(--line-soft, var(--line));
  font-size: 0.8125rem;
}

.live-pos-sym {
  font-family: var(--mono);
}

.live-pos-side {
  font-size: 0.75rem;
  color: var(--ink-faint);
}

/* Numbers line up column-to-column or they cannot be scanned down. */
.live-pos-qty,
.live-pos-val,
.live-pos-pl {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.live-pos-pl-up {
  color: rgb(63, 191, 143);
}

.live-pos-pl-down {
  color: rgb(217, 105, 95);
}

/* "gross" marks a P&L struck at last/mid — the cost of getting out is NOT in
   that number. Quiet, but never absent: the two kinds of mark are different
   quantities and must not read as one. */
.live-pos-gross {
  font-size: 0.5625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-left: 5px;
}

/* Not-trading alarm — the desk's stall verdict. Loud on purpose: the block only
   exists once every innocent explanation for a quiet session is already ruled
   out (LiveMonitoring.elm's Stall type; that screen was deleted 2026-09-17,
   console-shell PR 1). */
.live-banner-danger {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border: 1px solid rgba(217, 105, 95, 0.55);
  background: rgba(217, 105, 95, 0.1);
  border-radius: 10px;
  padding: 12px 15px;
}

.live-stall-head {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  color: rgb(217, 105, 95);
}

.live-stall-alerts {
  font-size: 0.75rem;
  color: var(--ink-faint);
}

/* Which gate is starving. Tone follows whether a stall is present, never the
   wording — one frame passing nothing is ordinary, twenty minutes is not. */
.live-refusal {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 15px;
  margin-top: 8px;
}

.live-refusal-danger {
  border-color: rgba(217, 105, 95, 0.4);
}

.live-refusal-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.live-refusal-stage {
  font-family: var(--serif);
  font-size: 0.9375rem;
}

.live-refusal-why {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--ink-dim, var(--ink-faint));
}

.live-refusal-top {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-top: 1px solid var(--line-soft, var(--line));
  padding-top: 8px;
}

.live-refusal-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.8125rem;
}

.live-refusal-reason {
  font-family: var(--mono);
}

.live-refusal-n {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}

/* Sleeves & wiring pane header — one short line of orientation plus an
   on-demand Pro tip, replacing the three-sentence paragraph that used to sit
   permanently above the fold. */
.profile-pane-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* =========================================================================
   MOBILE COCKPIT & TOUCH CONTROL SUITE (iOS & Web)
   ========================================================================= */

.mobile-cockpit-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding: 12px 16px;
  box-sizing: border-box;
}

.mobile-header-card {
  background: var(--surface-raised, rgba(22, 28, 42, 0.85));
  backdrop-filter: blur(20px);
  border: 1px solid var(--line, rgba(255, 255, 255, 0.08));
  border-radius: 16px;
  padding: 14px 18px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35);
}

.mobile-header-icon-box {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: rgba(212, 175, 55, 0.12);
  border: 1px solid rgba(212, 175, 55, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
}

.mobile-header-title {
  font-family: var(--serif, "Outfit", sans-serif);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink, #f7f9fc);
  margin: 0;
}

.mobile-header-subtitle {
  font-family: var(--mono, monospace);
  font-size: 0.72rem;
  color: var(--ink-muted, #94a3b8);
  margin: 2px 0 0 0;
}

.mobile-header-badge-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.mobile-telemetry-badge {
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: var(--mono, monospace);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--emerald, #10b981);
  background: rgba(16, 185, 129, 0.1);
  border: 1px solid rgba(16, 185, 129, 0.25);
  padding: 4px 8px;
  border-radius: 8px;
}

.mobile-security-badge {
  display: flex;
  align-items: center;
  gap: 4px;
  font-family: var(--sans, sans-serif);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--gold-bright, #f3d068);
  background: var(--gold-glow, rgba(212, 175, 55, 0.15));
  border: 1px solid rgba(212, 175, 55, 0.3);
  padding: 4px 8px;
  border-radius: 8px;
}

.status-pulse {
  display: inline-block;
  color: var(--emerald, #10b981);
  animation: pulseGlow 1.8s infinite ease-in-out;
}

@keyframes pulseGlow {
  0%, 100% { opacity: 0.4; transform: scale(0.9); }
  50% { opacity: 1; transform: scale(1.15); }
}

.mobile-feedback-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-radius: 12px;
  animation: fadeIn 150ms ease-out;
}

.mobile-feedback-banner.feedback-success {
  background: rgba(16, 185, 129, 0.15);
  border: 1px solid rgba(16, 185, 129, 0.4);
  color: #a7f3d0;
}

.mobile-feedback-banner.feedback-error {
  background: rgba(244, 63, 94, 0.15);
  border: 1px solid rgba(244, 63, 94, 0.4);
  color: #fecdd3;
}

.mobile-feedback-dismiss {
  background: transparent;
  border: none;
  color: inherit;
  font-size: 1rem;
  font-weight: bold;
  padding: 4px 8px;
  cursor: pointer;
  opacity: 0.75;
}

.mobile-feedback-dismiss:hover {
  opacity: 1;
}

.mobile-tab-nav {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  background: var(--surface, rgba(15, 19, 28, 0.75));
  padding: 4px;
  border-radius: 12px;
  border: 1px solid var(--line, rgba(255, 255, 255, 0.08));
}

.mobile-tab-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 8px;
  min-height: 44px;
  border-radius: 9px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-muted, #94a3b8);
  cursor: pointer;
  transition: all 150ms ease;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.mobile-tab-btn.active {
  background: var(--surface-raised, rgba(22, 28, 42, 0.9));
  border-color: var(--line-glow, rgba(201, 162, 75, 0.25));
  color: var(--ink, #f7f9fc);
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}

.mobile-emergency-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 28px 20px;
  border-radius: 20px;
  backdrop-filter: blur(20px);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  transition: all 200ms ease;
}

.mobile-emergency-card.normal {
  background: linear-gradient(180deg, rgba(30, 15, 20, 0.75) 0%, rgba(18, 12, 16, 0.9) 100%);
  border: 1px solid rgba(244, 63, 94, 0.3);
}

.mobile-emergency-card.pending {
  background: linear-gradient(180deg, rgba(35, 28, 15, 0.85) 0%, rgba(20, 16, 10, 0.95) 100%);
  border: 1px solid rgba(245, 158, 11, 0.45);
  animation: pulseGlow 1.2s infinite ease-in-out;
}

.mobile-emergency-card.halted {
  background: linear-gradient(180deg, rgba(60, 10, 15, 0.95) 0%, rgba(30, 5, 8, 0.98) 100%);
  border: 2px solid rgba(244, 63, 94, 0.8);
  box-shadow: 0 0 30px rgba(244, 63, 94, 0.35);
}

.mobile-emergency-icon-ring {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 12px;
}

.mobile-emergency-icon-ring.normal {
  background: rgba(244, 63, 94, 0.15);
  border: 1px solid rgba(244, 63, 94, 0.35);
}

.mobile-emergency-icon-ring.pending {
  background: rgba(245, 158, 11, 0.2);
  border: 1px solid rgba(245, 158, 11, 0.5);
}

.mobile-emergency-icon-ring.halted {
  background: rgba(244, 63, 94, 0.3);
  border: 2px solid rgba(244, 63, 94, 0.8);
}

.mobile-emergency-trigger-btn {
  width: 100%;
  max-width: 340px;
  min-height: 56px;
  margin-top: 18px;
  padding: 14px 20px;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: linear-gradient(180deg, #e11d48 0%, #be123c 100%);
  color: white;
  font-family: var(--sans, sans-serif);
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(225, 29, 72, 0.4);
  transition: all 120ms ease;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.mobile-emergency-trigger-btn:active {
  transform: scale(0.97);
  box-shadow: 0 4px 12px rgba(225, 29, 72, 0.3);
}

.mobile-halt-meta {
  margin-top: 16px;
  font-family: var(--mono, monospace);
  font-size: 0.72rem;
  color: #fca5a5;
  background: rgba(0, 0, 0, 0.4);
  padding: 6px 12px;
  border-radius: 8px;
  border: 1px solid rgba(244, 63, 94, 0.25);
}

.mobile-security-notice {
  text-align: center;
  padding: 8px;
}

.mobile-sleeve-card {
  background: var(--surface-raised, rgba(22, 28, 42, 0.85));
  border: 1px solid var(--line, rgba(255, 255, 255, 0.08));
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
}

.sleeve-badge {
  font-family: var(--mono, monospace);
  font-size: 0.65rem;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  letter-spacing: 0.04em;
}

.badge-active {
  background: rgba(16, 185, 129, 0.15);
  color: var(--emerald, #10b981);
  border: 1px solid rgba(16, 185, 129, 0.3);
}

.badge-throttled {
  background: rgba(245, 158, 11, 0.15);
  color: var(--amber, #f59e0b);
  border: 1px solid rgba(245, 158, 11, 0.3);
}

.badge-frozen {
  background: rgba(244, 63, 94, 0.15);
  color: var(--red, #f43f5e);
  border: 1px solid rgba(244, 63, 94, 0.3);
}

.mobile-sleeve-btn {
  min-height: 48px;
  border-radius: 10px;
  font-family: var(--sans, sans-serif);
  font-size: 0.75rem;
  font-weight: 600;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 120ms ease;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.mobile-sleeve-btn:active {
  transform: scale(0.96);
}

.btn-throttle {
  background: rgba(245, 158, 11, 0.12);
  color: #fde68a;
  border-color: rgba(245, 158, 11, 0.3);
}

.btn-freeze {
  background: rgba(244, 63, 94, 0.12);
  color: #fecdd3;
  border-color: rgba(244, 63, 94, 0.3);
}

.btn-reset {
  background: rgba(255, 255, 255, 0.05);
  color: var(--ink-muted, #94a3b8);
  border-color: var(--line, rgba(255, 255, 255, 0.08));
}

.btn-reset:hover {
  color: var(--ink, #f7f9fc);
  background: rgba(255, 255, 255, 0.08);
}

.mobile-telemetry-panel {
  background: var(--surface-raised, rgba(22, 28, 42, 0.85));
  border: 1px solid var(--line, rgba(255, 255, 255, 0.08));
  border-radius: 14px;
  padding: 16px;
}

/* RoleDeck.elm (Stakeholder Personas & Cockpits) was deleted 2026-09-17,
   console-shell PR 1 — .role-deck-screen and .role-deck-container went with
   it. The KPI/status-capsule rules below outlived it in this pass; only the
   families this PR's own deletion touched were swept. */

/* Status Capsule Ribbon */
.status-capsule-ribbon {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.625rem 1rem;
  background: var(--surface-sunken, #0b0f19);
  border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.08));
  border-radius: 10px;
  font-size: 0.8125rem;
  color: var(--ink-base, #f8fafc);
}

/* KPI Metric Cards Grid */
.kpi-cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
  width: 100%;
}

.kpi-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 1.125rem;
  background: var(--surface-raised, rgba(22, 28, 42, 0.75));
  border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.08));
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  transition: transform 150ms ease, border-color 150ms ease;
}

.kpi-card:hover {
  border-color: rgba(255, 255, 255, 0.16);
}

.kpi-card-clickable {
  cursor: pointer;
}

.kpi-card-clickable:hover {
  transform: translateY(-2px);
  border-color: var(--sapphire, #38bdf8);
}

.kpi-card-clickable:active {
  transform: translateY(0);
}

.kpi-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}

.kpi-card-title {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-muted, #94a3b8);
}

.kpi-card-value {
  font-family: var(--mono, monospace);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--ink-base, #f8fafc);
  margin-bottom: 0.375rem;
}

.kpi-card-sub {
  font-size: 0.75rem;
  color: var(--ink-muted, #94a3b8);
}

.kpi-card-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.375rem;
  border-radius: 4px;
  font-size: 0.6875rem;
  font-weight: 600;
  font-family: var(--mono, monospace);
}

.kpi-card-badge.positive {
  background: rgba(16, 185, 129, 0.15);
  color: #34d399;
  border: 1px solid rgba(16, 185, 129, 0.3);
}

.kpi-card-badge.neutral {
  background: rgba(255, 255, 255, 0.06);
  color: var(--ink-muted, #94a3b8);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

/* Sections & Panels */
.equity-chart-section,
.spread-excursion-section,
.topology-dag-section,
.adv-participation-section,
.asset-allocation-section,
.conductance-bars-section,
.worker-supervisor-section,
.schedule13d-section,
.activity-feed-section {
  display: flex;
  flex-direction: column;
  padding: 1.25rem;
  background: var(--surface-raised, rgba(22, 28, 42, 0.75));
  border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.08));
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.chart-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.timeframe-pills {
  display: inline-flex;
  align-items: center;
  background: var(--surface-sunken, #0b0f19);
  padding: 0.25rem;
  border-radius: 8px;
  border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.08));
  gap: 0.25rem;
}

.timeframe-pill-btn {
  min-height: 32px;
  min-width: 44px;
  padding: 0.25rem 0.625rem;
  background: transparent;
  border: none;
  border-radius: 6px;
  font-family: var(--mono, monospace);
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--ink-muted, #94a3b8);
  cursor: pointer;
  transition: all 120ms ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.timeframe-pill-btn:hover {
  color: var(--ink-base, #f8fafc);
  background: rgba(255, 255, 255, 0.05);
}

.timeframe-pill-btn.timeframe-pill-active {
  background: rgba(56, 189, 248, 0.15);
  color: #38bdf8;
  border: 1px solid rgba(56, 189, 248, 0.3);
}

.chart-svg-container {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.chart-legend-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.75rem;
  font-size: 0.75rem;
  color: var(--ink-muted, #94a3b8);
}

/* Activity Feed Timeline */
.feed-items-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  max-height: 480px;
  overflow-y: auto;
}

.feed-item-card {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding: 0.875rem 1rem;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  transition: background 120ms ease;
}

.feed-item-card:hover {
  background: rgba(255, 255, 255, 0.04);
}

/* Quick Actions Ribbon */
.quick-actions-ribbon {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  background: var(--surface-sunken, #0b0f19);
  border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.08));
  border-radius: 12px;
}

.action-buttons-group {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* Modal Sheets and Drill-In Overlays */
.sov-modal-backdrop,
.node-switcher-overlay {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.75);
  backdrop-filter: blur(4px);
  padding: 1rem;
  box-sizing: border-box;
}

.sov-modal-card,
.node-switcher-modal {
  width: 100%;
  max-width: 680px;
  max-height: 90vh;
  overflow-y: auto;
  background: #0f172a;
  border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.15));
  border-radius: 14px;
  padding: 1.5rem;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.modal-close-btn {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--ink-muted, #94a3b8);
  font-size: 1.25rem;
  cursor: pointer;
  border-radius: 6px;
  transition: all 120ms ease;
}

.modal-close-btn:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}

/* Mobile Responsive Optimization (<= 390px iPhone & Compact Viewports) */
@media (max-width: 768px) {
  .kpi-cards-grid {
    grid-template-columns: 1fr;
  }

  .chart-header {
    flex-direction: column;
    align-items: flex-start;
  }

  .quick-actions-ribbon {
    flex-direction: column;
    align-items: stretch;
  }

  .action-buttons-group {
    flex-direction: column;
    width: 100%;
  }

  .action-buttons-group .btn {
    width: 100%;
  }
}

@media (max-width: 390px) {
  .status-capsule-ribbon {
    padding: 0.5rem;
    gap: 0.5rem;
  }

  .timeframe-pill-btn {
    min-height: 44px;
    min-width: 48px;
    font-size: 0.75rem;
  }

  .kpi-card {
    padding: 0.875rem;
  }

  .kpi-card-value {
    font-size: 1.25rem;
  }

  .sov-modal-card,
  .node-switcher-modal {
    padding: 1rem;
    max-height: 95vh;
  }
}

/* Responsive Data Tables & Touch Scrolling */
.data-table-container,
.responsive-table-wrap {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 0.5rem 0;
}

.data-table-container table {
  min-width: 600px;
  width: 100%;
  border-collapse: collapse;
}

.data-table-container th {
  position: sticky;
  top: 0;
  background: var(--surface-raised, #1e293b);
  z-index: 2;
}

@media (max-width: 640px) {
  .data-table-container table {
    font-size: 0.75rem;
  }
}

/* iOS Touch-First Bottom Dock & Mobile Viewport Ergonomics */
.ios-bottom-dock {
  display: none;
}

@media (max-width: 768px) {
  .ios-bottom-dock {
    display: flex !important;
  }

  .mobile-dock-btn:active {
    transform: scale(0.94);
    background: rgba(56, 189, 248, 0.2) !important;
  }
}

.desk-section { padding: var(--space-4); max-width: 60rem; }
.desk-section-head { display: flex; align-items: center; justify-content: space-between; }
.desk-row { display: grid; grid-template-columns: 8rem 1fr; gap: var(--space-2); padding: var(--space-2) 0; border-bottom: 1px solid var(--line); }
.desk-label { color: var(--ink-muted); }
.desk-wrong { color: var(--red); }
.desk-fault { grid-column: 2; color: var(--red); margin: 0; }
.desk-runners { margin: 0; padding-left: 1rem; }
.desk-chip { display: inline-block; font-size: var(--text-sm, 0.8125rem); color: var(--ink-muted); }
.desk-chip-wrong { color: var(--red); }

