/* ═══ §12 · TAB: TELEMETRY ════════════════════════════════════════════════════════════ */

.telem-section-label {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  margin: var(--sp-lg) 0 var(--sp-sm);
  border-left: 2px solid var(--accent-red);
  padding-left: var(--sp-sm);
}
.telem-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-sm);
  margin-bottom: var(--sp-sm);
}
/* a trailing partial row never leaves a dead grid cell — the LAST tile stretches to fill
   whatever remains */
.telem-grid > .telem-card:last-child:nth-child(3n + 1) { grid-column: span 3; }
.telem-grid > .telem-card:last-child:nth-child(3n + 2) { grid-column: span 2; }
.telem-card {
  padding: var(--sp-md) var(--sp-sm);
  text-align: center;
  border-radius: 10px;
  /* grid items default to min-width:auto — a long nowrap value then forces its column wider
     than 1fr and the row overflows the panel. */
  min-width: 0;
}
.telem-value {
  font-family: var(--font-mono);
  font-size: 1rem;
  font-weight: 700;
  color: var(--accent-gold);
  margin-bottom: 4px;
  /* IT WRAPS, IT DOES NOT CLIP. A tile is ~105px wide at 390px and these are not all numbers:
     a feed-identity string runs ~190px of ink and "PAPER · paper-only" is 173, measured clipped
     to an 87px box — and that second line tells the operator no real money is at risk. */
  white-space: normal;
  overflow-wrap: anywhere;
}
.telem-label {
  font-size: 0.55rem;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ── §12.1 THE SYSTEM MONITOR — whole-tower usage: CPU + per-core, RAM + swap, disk I/O,
   per-GPU. A named-area stack so the layout is deterministic: GPUs share row 1, then CPU,
   MEMORY and DISK each take a full row. ── */
#view-telemetry > .glass-heavy { padding: 12px; }
#view-telemetry > .glass-heavy > .telem-section-label { margin: var(--sp-sm) 0 6px; }

.sysmon-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-areas: "gpu0 gpu1" "cpu cpu" "mem mem" "io io" "net net";
  gap: 8px;
  margin-top: 4px;
}
.sysmon-card.sm-gpu0 { grid-area: gpu0; }
.sysmon-card.sm-gpu1 { grid-area: gpu1; }
.sysmon-card.sm-cpu  { grid-area: cpu; }
.sysmon-card.sm-mem  { grid-area: mem; }
.sysmon-card.sm-io   { grid-area: io; }
.sysmon-card.sm-net  { grid-area: net; }
.sysmon-card.sm-gpu-solo { grid-column: 1 / -1; grid-row: 1; }
.sysmon-grid.one-gpu { grid-template-areas: "gpu0 gpu0" "cpu cpu" "mem mem" "io io" "net net"; }
/* an interface row: name on the left, its own counters wrapping under it */
.sysmon-if { margin-top: 4px; }
.sysmon-if:first-of-type { margin-top: 2px; }
.sysmon-if-name {
  font-size: 0.58rem;
  font-family: var(--font-mono);
  color: var(--accent-gold);
}
.sysmon-if-name em {
  font-style: normal;
  color: var(--text-dim);
  font-size: 0.52rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-left: 6px;
}
.sysmon-card {
  background: rgba(10, 10, 15, 0.6);
  border: 1px solid var(--glass-border);
  border-radius: 10px;
  padding: 8px 10px;
}
.sysmon-card-hdr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
}
/* THE LOAD RAMP IS SILVER → AMBER → RED, and `idle` is the QUIET end of it, not a status light.
   A meter at rest is informational ink; the colour only starts speaking once the load does, which
   is why warm and hot keep their own hues and idle carries none. */
.sysmon-card-hdr b { font-family: var(--font-mono); font-size: 0.8rem; color: var(--accent-gold); }
.sysmon-card-hdr b.idle { color: var(--accent-silver); }
.sysmon-card-hdr b.warm { color: #ffd166; }
.sysmon-card-hdr b.hot  { color: var(--outcome-fade); }
.sysmon-bar {
  height: 7px;
  border-radius: 4px;
  margin: 4px 0 3px;
  background: rgba(255, 255, 255, 0.06);
  overflow: hidden;
}
.sysmon-bar-fill { height: 100%; border-radius: 4px; transition: width 0.4s ease; }
.sysmon-bar-fill.idle { background: linear-gradient(90deg, #6a6a72, var(--accent-silver)); }
.sysmon-bar-fill.warm { background: linear-gradient(90deg, #fa3, #ffd166); }
.sysmon-bar-fill.hot  { background: linear-gradient(90deg, #f25, var(--outcome-fade)); }
.sysmon-sub {
  font-size: 0.58rem;
  font-family: var(--font-mono);
  color: var(--text-dim);
  margin-top: 2px;
  line-height: 1.4;
}
.sysmon-cores { display: flex; align-items: flex-end; gap: 2px; height: 18px; margin: 3px 0 2px; }
.sysmon-core {
  flex: 1 1 auto;
  min-width: 2px;
  height: 100%;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 1px;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
.sysmon-core-fill { width: 100%; border-radius: 1px; transition: height 0.4s ease; }
.sysmon-core-fill.idle { background: var(--accent-silver); }
.sysmon-core-fill.warm { background: #ffd166; }
.sysmon-core-fill.hot  { background: var(--outcome-fade); }
.sysmon-io-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.62rem;
  margin-top: 4px;
  color: var(--text-secondary);
}
.sysmon-io-row b { font-family: var(--font-mono); color: var(--accent-gold); }
.sysmon-down {
  padding: 14px;
  text-align: center;
  font-size: 0.7rem;
  color: #ff8aa0;
  font-family: var(--font-mono);
}
/* segmented bar: CPU usr/sys/iowait · MEM apps/cache/free — same shell as .sysmon-bar */
.sysmon-seg {
  display: flex;
  height: 7px;
  border-radius: 4px;
  overflow: hidden;
  margin: 6px 0 4px;
  background: rgba(255, 255, 255, 0.06);
}
.sysmon-seg > i { height: 100%; display: block; transition: width 0.4s ease; }
.sysmon-seg > i.usr, .sysmon-seg > i.used { background: linear-gradient(90deg, #6a6a72, var(--accent-silver)); }
.sysmon-seg > i.sys   { background: linear-gradient(90deg, #fa3, #ffd166); }
.sysmon-seg > i.io    { background: linear-gradient(90deg, #f25, var(--outcome-fade)); }
.sysmon-seg > i.cache { background: rgba(192, 192, 192, 0.28); }
.sysmon-seg > i.free  { background: transparent; }
.sysmon-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 10px;
  margin-top: 4px;
  font-size: 0.56rem;
  font-family: var(--font-mono);
  color: var(--text-dim);
  line-height: 1.45;
}
.sysmon-stats b { color: var(--ink-panel); font-weight: 600; }
.sysmon-stats .warn b { color: #ffd166; }
.sysmon-stats .crit b { color: var(--outcome-fade); }
/* A secondary fact on a stats row — a device path, or the REASON a capacity is unreadable.
   Dimmer than the numbers beside it so a stated absence never competes with a measurement. */
.sysmon-stats .dim { color: var(--text-dim); opacity: 0.7; }
/* PER-MOUNT capacity — the host's real filesystems beside the raw devices. A mount path can be
   long (`/opt/sfti/sfti.wheel/sfti.data/checkpoints`) and the phone frame is 390px, so the name
   wraps on its own line rather than squeezing the numbers into a column one character wide. */
.sysmon-mount { margin-top: 6px; }
.sysmon-mount-name {
  font-size: 0.58rem;
  font-family: var(--font-mono);
  color: var(--text-dim);
  overflow-wrap: anywhere;
}
.sysmon-fs {
  display: inline-block;
  margin-left: 5px;
  padding: 0 4px;
  border-radius: 3px;
  font-size: 0.5rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--accent-silver);
  background: rgba(192, 192, 192, 0.1);
}
.sysmon-cap {
  height: 5px;
  border-radius: 3px;
  margin: 3px 0 2px;
  background: rgba(255, 255, 255, 0.06);
  overflow: hidden;
}
.sysmon-cap-fill {
  height: 100%;
  border-radius: 3px;
  background: linear-gradient(90deg, #5a5a64, var(--accent-silver));
  transition: width 0.4s ease;
}
.sysmon-disk { margin-top: 3px; }
.sysmon-disk:first-of-type { margin-top: 2px; }
.sysmon-disk-name { font-size: 0.56rem; font-family: var(--font-mono); color: var(--text-dim); }
/* GPU half-width cards are tight (~199px @414px) — shrink-proof so long names never overflow */
.sysmon-card.sm-gpu0, .sysmon-card.sm-gpu1 { min-width: 0; }
.sysmon-card.sm-gpu0 .sysmon-card-hdr span,
.sysmon-card.sm-gpu1 .sysmon-card-hdr span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 11ch;
}
/* GPU detail lines WRAP (not ellipsis) so temp/clocks are never hidden on the narrow card */
.sysmon-card.sm-gpu0 .sysmon-sub,
.sysmon-card.sm-gpu1 .sysmon-sub { white-space: normal; overflow-wrap: anywhere; }
.sysmon-proc {
  font-size: 0.54rem;
  font-family: var(--font-mono);
  color: var(--text-secondary);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sysmon-proc b { color: var(--accent-gold); }
.sysmon-proc.empty { color: var(--text-dim); opacity: 0.7; }
/* desktop breathe-back: GPUs row 1, CPU + MEM share row 2, DISK full row 3 */
@media (min-width: 720px) {
  .sysmon-grid { grid-template-areas: "gpu0 gpu1" "cpu mem" "io net"; }
  .sysmon-grid.one-gpu { grid-template-areas: "gpu0 gpu0" "cpu mem" "io net"; }
}

/* ── §12.1.1 THE SYSTEM MONITOR TRIGGER — the caption is now pressable, opening the per-container
   modal (operator 2026-08-20). A discoverable affordance, not an invisible tap target. ── */
.telem-sysmon-trigger {
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.telem-sysmon-trigger .telem-sysmon-hint {
  font-size: 0.52rem;
  color: var(--text-dim);
  text-transform: none;
  letter-spacing: 0;
  opacity: 0.75;
}

/* ── §12.1.2 THE CONTAINERS SHEET — per-container CPU/mem rings + net/disk rates, on the
   BOTTOM-SHEET chassis (modals.css §7.1: a grabber, no ✕, rising from the bottom edge). It was
   the last surface still on the centred `.composite-modal` card when every sheet around it had
   moved (operator 2026-08-22). Every rule below is chassis-agnostic and was unchanged by that
   swap — which is the point: the cards are the content, the sheet is only the frame. ── */
.dstat-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.dstat-card {
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
}
.dstat-card-error { border-color: rgba(232, 93, 42, 0.35); }
.dstat-name {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--accent-gold);
  display: flex;
  align-items: baseline;
  gap: 8px;
  overflow-wrap: anywhere;
}
.dstat-status {
  font-size: 0.58rem;
  font-weight: 400;
  color: var(--text-dim);
  text-transform: none;
}
/* DOCKER OPS (2026-08-20) — restart/stop/start, in the open space beside the name/status. Pushed
   to the far right of the flex row .dstat-name already is (align-items:baseline + this margin). */
.dstat-ops {
  margin-left: auto;
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}
.dstat-op {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--glass-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  cursor: pointer;
  transition: background 0.15s ease, opacity 0.15s ease;
  /* the anchor for the hit box below */
  position: relative;
}
/* ★ 26px OF CHROME, 44px OF FINGER. These two controls restart and stop real containers, and a
   26px target is well under the floor tap-targets.css holds every promised control to — a
   near-miss on a card that also scrolls reads exactly like a dead button, which is the symptom
   that was reported here for a different reason. The box GROWS the hit area around the same
   centre without moving a pixel of layout (26 + 2×9 = 44), the same technique tap-targets.css
   uses for the header chips. `-9px` and not more: the two buttons sit 6px apart, so a larger
   inset would overlap them and hand Restart's taps to Stop. */
.dstat-op::after { content: ''; position: absolute; inset: -9px; }
/* the hover guard (modals.css's own HOVER LAW): iOS latches `:hover` on the last-tapped element
   and never releases it, so a bare hover rule leaves a control looking permanently armed. */
@media (hover: hover) {
  .dstat-op:hover:not(:disabled) { background: rgba(230, 57, 70, 0.12); }
}
.dstat-op:active:not(:disabled) { background: rgba(230, 57, 70, 0.22); }
.dstat-op:disabled { opacity: 0.35; cursor: default; }
.dstat-op img { display: block; width: 14px; height: 14px; }
.dstat-err {
  margin-top: 4px;
  font-size: 0.64rem;
  color: #ff8aa0;
  font-family: var(--font-mono);
  line-height: 1.4;
}
.dstat-rings {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 10px 14px;
  margin: 8px 0;
}
.dstat-ring-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.dstat-ring-inner { position: relative; width: 52px; height: 52px; }
.dstat-ring { transform: rotate(-90deg); }
.dstat-ring-bg {
  fill: none;
  stroke: rgba(255, 255, 255, 0.08);
  stroke-width: 3;
}
.dstat-ring-fill {
  fill: none;
  stroke-width: 3;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.4s ease;
}
.dstat-ring-fill.idle { stroke: var(--accent-silver); }
.dstat-ring-fill.warm { stroke: #ffd166; }
.dstat-ring-fill.hot  { stroke: var(--outcome-fade); }
.dstat-ring-val {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--ink-panel);
}
.dstat-ring-lbl {
  margin-top: 3px;
  font-size: 0.52rem;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.dstat-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 3px 10px;
  font-size: 0.58rem;
  font-family: var(--font-mono);
  color: var(--text-dim);
}
.dstat-stats b { color: var(--ink-panel); font-weight: 600; }
.dstat-note {
  margin-top: 4px;
  font-size: 0.56rem;
  color: var(--text-dim);
  opacity: 0.75;
  font-style: italic;
}

/* ── §12.2 THE GATE SCORECARD — the shadow book's other half, inside the Trade Journal panel.
   One card per selection gate: what it refused, what the tape then did, and the marginal band
   a threshold move would actually re-decide. ── */
.gate-card {
  margin-top: 8px;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(10, 10, 15, 0.55);
  border: 1px solid var(--glass-border);
  font-family: var(--font-mono);
  font-size: 0.64rem;
  line-height: 1.5;
}
.gate-hd {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding-bottom: 6px;
  margin-bottom: 6px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.gate-name {
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--accent-gold);
  overflow-wrap: anywhere;
}
.gate-thr { color: var(--text-dim); font-size: 0.58rem; white-space: nowrap; }
/* THE ROW IS A GRID, NOT A FLEX RUN. At 390px the three cells cannot share one line, so the
   key rides row 1 and the value + verdict wrap under it, each keeping its own column. */
.gate-row {
  display: grid;
  grid-template-columns: minmax(0, 8em) minmax(0, 1fr);
  gap: 2px 10px;
  padding: 3px 0;
  align-items: baseline;
}
.gate-k {
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.56rem;
}
.gate-v { color: var(--ink-panel); min-width: 0; overflow-wrap: anywhere; }
.gate-v b { color: var(--accent-gold); }
.gate-why {
  grid-column: 2;
  color: var(--text-secondary);
  font-size: 0.58rem;
  min-width: 0;
  overflow-wrap: anywhere;
}
.gate-sub {
  margin: 6px 0 2px;
  color: var(--text-dim);
  font-size: 0.56rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.gate-note {
  margin-top: 6px;
  padding: 6px 8px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.02);
  color: var(--text-dim);
  font-size: 0.58rem;
  line-height: 1.55;
  overflow-wrap: anywhere;
}
.gate-note b { color: var(--ink-panel); }
.gate-note code {
  padding: 1px 4px;
  border-radius: 4px;
  background: rgba(192, 192, 192, 0.1);
  color: var(--accent-silver);
}
/* AN UNREAD INSTRUMENT IS NOT A ZERO. `.gate-dark` is the token for "not yet measured" and it
   must never look like `.gate-flat`, which means measured-and-neutral. */
.gate-dark { color: var(--text-dim); font-style: italic; }
.gate-pos  { color: var(--outcome-win); font-weight: 700; }
.gate-neg  { color: var(--outcome-fade); font-weight: 700; }
.gate-flat { color: var(--text-secondary); }
.gate-dark-card {
  margin-top: 8px;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(255, 200, 74, 0.05);
  border: 1px solid rgba(255, 200, 74, 0.2);
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  line-height: 1.55;
  overflow-wrap: anywhere;
}

/* THE CONTAINERS MODAL SAT TOO HIGH (operator 2026-08-20) — `.composite-modal-backdrop` centers
   its card with `align-items:center`, which is fine for short content but this modal's card
   routinely hits its own `max-height:85vh` cap (four-plus container cards), so the "centered" box
   is nearly full-height and its top edge lands right under the sticky ticker header with no
   breathing room. Scoped to THIS modal only, via the class the JS already adds alongside
   `.composite-modal-backdrop` — `.composite-modal-backdrop` itself is shared by six other modals
   (why/brain/engram/analytics/regime/session-plan) that are not part of this fix and must not
   move. Anchoring to the top and reserving `--header-clearance` (the same live-measured sticky-
   header height every other top-anchored surface in this app already reads, tokens.css) instead
   of guessing a pixel value is what keeps this correct if the header's own height ever changes. */
.containers-modal-backdrop {
  align-items: flex-start;
  padding-top: calc(var(--header-clearance) + var(--sp-md));
}

