:root { --bg:#090d12; --panel:#101720; --line:#27333f; --muted:#91a0ae; --text:#e9f0f5; --cyan:#56d3e6; --high:#ff5e66; --medium:#ffad52; --low:#e6d267; --info:#6ed7a3; }
* { box-sizing:border-box; }
body { margin:0; min-width:320px; background:var(--bg); color:var(--text); font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
/* Height, not min-height: an operations wall that scrolls the page is a wall
   nobody can read. Capping the shell forces the findings list to scroll inside
   its own panel and keeps the mosaic whole on one screen. */
.console-shell { max-width:1800px; margin:auto; height:100vh; padding:18px; display:flex; flex-direction:column; gap:14px; }
.topbar, .metrics, .panel, .footer { border:1px solid var(--line); background:var(--panel); }
.topbar { min-height:58px; display:flex; align-items:center; justify-content:space-between; padding:0 16px; gap:16px; }
.brand { display:flex; align-items:center; gap:10px; letter-spacing:.13em; font-weight:800; font-size:18px; }
.brand-mark { color:#061016; background:var(--cyan); padding:4px 8px; font-weight:900; }
.live-dot, .feed-indicator { font-size:11px; color:var(--cyan); border:1px solid #287384; padding:4px 7px; letter-spacing:.08em; white-space:nowrap; }
/* A replay must not borrow the live badge's colour: the difference between a run
   in flight and a recording of one is exactly what this badge exists to state. */
.live-dot.is-replay { color:var(--muted); border-color:var(--line); }
.run-state, .clock, .footer { color:var(--muted); font-size:12px; letter-spacing:.04em; }
.metrics { display:grid; grid-template-columns:220px 220px 1fr; min-height:88px; }
.metric { padding:13px 18px; border-right:1px solid var(--line); display:flex; flex-direction:column; justify-content:center; }
.metric-value { font-size:35px; font-weight:800; color:var(--cyan); line-height:1.3; }
.metric-label { margin-top:7px; text-transform:uppercase; font-size:10px; letter-spacing:.09em; color:var(--muted); }
.severity-totals { display:flex; align-items:center; justify-content:space-around; gap:8px; padding:10px; }
.total { font-size:12px; font-weight:700; padding:8px 10px; border-left:4px solid; background:#0c1219; }
.total b { font-size:25px; margin-right:5px; }.total-high{color:var(--high);border-color:var(--high)}.total-medium{color:var(--medium);border-color:var(--medium)}.total-low{color:var(--low);border-color:var(--low)}.total-info{color:var(--info);border-color:var(--info)}
.wall-grid { display:grid; grid-template-columns:minmax(0,2.3fr) minmax(340px,.72fr); gap:14px; flex:1; min-height:0; }
.panel { min-height:0; display:flex; flex-direction:column; }.panel-heading { display:flex; justify-content:space-between; align-items:flex-start; padding:14px 16px; border-bottom:1px solid var(--line); gap:10px; }
.eyebrow { color:var(--cyan); font-size:10px; letter-spacing:.12em; }.panel h1,.panel h2 { font-size:19px; margin:5px 0 0; letter-spacing:.02em; }.panel h2 span { color:var(--muted); font-weight:400; }.wall-status { display:flex; align-items:center; flex-wrap:wrap; justify-content:flex-end; gap:8px; }.wall-mode { color:var(--cyan); border:1px solid #287384; padding:3px 5px; font-size:9px; letter-spacing:.08em; white-space:nowrap; }.wall-mode.is-evidence { color:var(--high); border-color:var(--high); }.wall-mode.is-unavailable { color:var(--medium); border-color:var(--medium); }.sequence { color:var(--muted); font-size:10px; white-space:nowrap; }
.mosaic-stage { position:relative; display:flex; align-items:center; justify-content:center; flex:1; min-height:410px; overflow:hidden; background:#070a0e; }.mosaic-stage img { display:none; max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain; }.mosaic-stage.is-unavailable img { opacity:.22; }.tile-layer { position:absolute; pointer-events:none; }.mosaic-empty { color:var(--muted); max-width:350px; text-align:center; line-height:1.6; padding:24px; }
.tile { position:absolute; border:2px solid rgba(86,211,230,.8); box-shadow:inset 0 0 0 1px rgba(0,0,0,.55); transition:background .2s,border-color .2s,box-shadow .2s; }.tile-label { position:absolute; top:0; left:0; max-width:100%; padding:3px 5px; background:rgba(5,12,17,.88); color:#dffbff; font-size:10px; line-height:1.3; overflow-wrap:anywhere; }.tile.is-witness { border-color:var(--high); background:rgba(255,94,102,.16); box-shadow:0 0 0 1px var(--high), inset 0 0 26px rgba(255,94,102,.3); z-index:2; }.tile.is-witness .tile-label { background:var(--high); color:#180609; font-weight:800; }
.mosaic-caption { margin:0; padding:11px 16px; border-top:1px solid var(--line); color:var(--muted); font-size:11px; line-height:1.45; }
.findings { overflow:auto; flex:1; padding:9px; background:#0b1016; }.findings-empty { color:var(--muted); text-align:center; padding:40px 18px; font-size:13px; line-height:1.6; }
.finding { border:1px solid var(--line); border-left:5px solid var(--severity); margin-bottom:8px; padding:11px; background:#111923; cursor:pointer; }.finding:hover,.finding.is-active { background:#162331; border-color:#607386; }.finding-head { display:flex; gap:7px; align-items:center; flex-wrap:wrap; }.pill { padding:3px 6px; font-weight:800; font-size:10px; letter-spacing:.05em; background:var(--severity); color:#0b1016; }.finding-kind { color:#d3dfe8; font-size:11px; }.finding-axis { margin-left:auto; color:var(--muted); font-size:10px; }.finding-summary { margin:9px 0 7px; font:600 14px/1.4 ui-sans-serif,system-ui,sans-serif; }.finding-surface { color:var(--cyan); font-size:11px; }.evidence { border-top:1px solid #283541; padding-top:7px; margin-top:7px; color:#b8c6d0; font-size:10px; line-height:1.45; }.evidence strong { color:var(--muted); font-weight:700; }.footer { padding:10px 13px; display:flex; justify-content:space-between; gap:10px; }
@media (max-width:1560px) {
  .console-shell { height:auto; min-height:100vh; }
  .wall-grid { grid-template-columns:1fr; }
  /* Width becomes the only constraint: the stage wraps the image instead of
     capping it, so the wall is as large as the screen allows and never clipped. */
  .mosaic-stage { flex:none; min-height:0; }
  .mosaic-stage img { max-height:none; }
  .findings-panel { min-height:420px; max-height:72vh; }
}
@media (max-width:900px) { .console-shell{height:auto;min-height:100vh}.wall-grid{grid-template-columns:1fr}.findings-panel{min-height:420px}.mosaic-stage img{max-height:none}.metrics{grid-template-columns:1fr 1fr}.severity-totals{grid-column:1/-1;border-top:1px solid var(--line)} }
@media (max-width:600px) { .console-shell{padding:8px}.run-state{flex:1 0 100%;min-width:0;order:3;overflow-wrap:anywhere}.topbar{padding:6px 10px;flex-wrap:wrap}.metrics{grid-template-columns:1fr 1fr}.metric{padding:12px}.metric-value{font-size:30px;line-height:1.3}.severity-totals{flex-wrap:wrap;justify-content:flex-start}.footer{flex-direction:column}.mosaic-stage{min-height:260px}.tile-label{font-size:7px;padding:2px}.finding-summary{font-size:13px} }

/* The evidence inspector. A seven-context wall is unreadable at panel size, so
   one witness at a time fills the viewport at its own pixels, and the tiles on
   the wall become the way in. */
.inspect-button { background:#132030; border:1px solid var(--line); color:var(--cyan); cursor:pointer; font:800 10px/1 ui-monospace,monospace; letter-spacing:.06em; padding:6px 9px; }
.inspect-button:hover { background:#1b2c40; border-color:var(--cyan); }
.inspect-button:focus-visible,.inspector-close:focus-visible,.inspector-witness:focus-visible { outline:2px solid var(--cyan); outline-offset:2px; }
.mosaic-stage img { cursor:zoom-in; }
.mosaic-stage .tile { pointer-events:auto; cursor:zoom-in; }
.tile-layer { pointer-events:none; }

.inspector { position:fixed; inset:0; z-index:60; display:flex; flex-direction:column; background:rgba(4,7,11,.97); }
.inspector[hidden] { display:none; }
.inspector-bar { align-items:center; border-bottom:1px solid var(--line); display:flex; flex-wrap:wrap; gap:14px; padding:10px 16px; }
.inspector-bar h2 { font:800 17px/1.2 ui-sans-serif,system-ui,sans-serif; margin:2px 0 0; }
.inspector-witnesses { display:flex; flex-wrap:wrap; gap:5px; margin-inline-start:auto; }
.inspector-witness { background:#111923; border:1px solid var(--line); color:#c9d6e2; cursor:pointer; font:700 10px/1 ui-monospace,monospace; letter-spacing:.04em; padding:7px 8px; }
.inspector-witness:hover { border-color:#607386; }
.inspector-witness.is-active { background:var(--cyan); border-color:var(--cyan); color:#04252b; }
.inspector-witness.is-evidence { border-color:var(--high); color:#ffd7d9; }
.inspector-witness.is-evidence.is-active { background:var(--high); color:#180609; }
.inspector-close { background:#1b0d10; border:1px solid var(--high); color:#ffd7d9; cursor:pointer; font:800 10px/1 ui-monospace,monospace; padding:7px 9px; }
/* Not justify-content:center. A flex item wider than its scroll container gets
   centred by overflowing equally on both sides, and the overflow on the start
   side is unreachable by scrolling — the first witness could never be brought
   into view. */
.inspector-stage { align-items:flex-start; display:flex; flex:1; justify-content:flex-start; overflow:auto; padding:14px; }
/* No max-height: the point is native pixels, and the stage scrolls to reach
   them. Clamping here is what made the wall unreadable in the first place. */
/* flex:none matters. As a shrinkable flex item the image collapsed back to its
   intrinsic width no matter what width was set on it, which is the whole bug
   the inspector exists to fix, reappearing inside the fix. */
.inspector-frame { flex:none; position:relative; }
.inspector-stage img { display:block; flex:none; height:auto; image-rendering:crisp-edges; max-width:none; }
.inspector-caption { border-top:1px solid var(--line); color:var(--muted); font-size:11px; line-height:1.5; margin:0; padding:11px 16px; }
@media (max-width:1560px) {
  .console-shell { height:auto; min-height:100vh; }
  .wall-grid { grid-template-columns:1fr; }
  /* Width becomes the only constraint: the stage wraps the image instead of
     capping it, so the wall is as large as the screen allows and never clipped. */
  .mosaic-stage { flex:none; min-height:0; }
  .mosaic-stage img { max-height:none; }
  .findings-panel { min-height:420px; max-height:72vh; }
}
@media (max-width:900px) { .inspector-witnesses { margin-inline-start:0; width:100%; } }

/* A recorded sweep holds every settled frame it captured. Reading the file in
   one fetch and drawing only the last of them threw the sweep away, so a
   completed run replays instead of snapping to its final moment. */
.scrubber { align-items:center; border-top:1px solid var(--line); display:flex; gap:10px; padding:8px 16px; }
.scrubber[hidden] { display:none; }
.scrubber span { color:var(--muted); font:700 10px/1 ui-monospace,monospace; letter-spacing:.05em; white-space:nowrap; }
.scrubber input { accent-color:var(--cyan); flex:1; min-width:0; }

/* Which pixels are this witness. Without it the neighbouring tile bleeds into
   the view and reads as part of the evidence. */
.inspector-window { position:absolute; border:2px solid var(--cyan); box-shadow:0 0 0 9999px rgba(4,7,11,.82); pointer-events:none; }
.inspector-window.is-evidence { border-color:var(--high); }


/* The transport controls failed the 44px rule the wall enforces on everything
   it sweeps — 24px tall for the two buttons, 16px for the scrubber. They were
   added today, so this is the tool catching its own console on the first sweep
   after the change. */
.inspect-button { min-height:44px; min-width:44px; padding-inline:12px; }
.scrubber input { min-height:44px; }
