/* ============================================================
   WCS Dashboard — design system
   Dense, technical observability aesthetic.
   Monochrome slate chrome + semantic status colors.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap');

:root {
  --font-ui: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;

  /* radii / shadow */
  --r-sm: 6px;
  --r-md: 9px;
  --r-lg: 14px;
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 4px 16px -4px rgba(15, 23, 42, 0.12);
  --shadow-lg: 0 18px 48px -12px rgba(15, 23, 42, 0.28);

  --maxw: 1320px;
}

/* ---------- LIGHT (default) ---------- */
:root, [data-theme="light"] {
  --bg:          oklch(0.975 0.003 255);
  --bg-grid:     oklch(0.93 0.004 255);
  --surface:     oklch(1 0 0);
  --surface-2:   oklch(0.972 0.003 255);
  --surface-3:   oklch(0.955 0.004 255);
  --border:      oklch(0.915 0.005 255);
  --border-2:    oklch(0.86 0.007 255);
  --text:        oklch(0.24 0.012 262);
  --text-2:      oklch(0.46 0.011 262);
  --text-3:      oklch(0.62 0.01 262);
  --accent:      oklch(0.28 0.025 262);
  --accent-2:    oklch(0.36 0.03 262);
  --accent-text: oklch(0.99 0 0);

  /* code/log panel surface (e.g. LogViewer file content) */
  --code-bg:   oklch(0.965 0.004 255);
  --code-text: oklch(0.32 0.012 262);

  --ok:    oklch(0.62 0.15 152);
  --ok-bg: oklch(0.95 0.04 152);
  --warn:    oklch(0.69 0.14 76);
  --warn-bg: oklch(0.96 0.05 86);
  --err:    oklch(0.58 0.2 27);
  --err-bg: oklch(0.95 0.04 27);
  --info:    oklch(0.55 0.12 250);
  --info-bg: oklch(0.95 0.03 250);

  --track:   oklch(0.93 0.004 255);
  color-scheme: light;
}

/* ---------- DARK ---------- */
[data-theme="dark"] {
  --bg:          oklch(0.175 0.008 264);
  --bg-grid:     oklch(0.225 0.01 264);
  --surface:     oklch(0.21 0.01 264);
  --surface-2:   oklch(0.245 0.012 264);
  --surface-3:   oklch(0.28 0.014 264);
  --border:      oklch(0.3 0.013 264);
  --border-2:    oklch(0.38 0.016 264);
  --text:        oklch(0.95 0.004 264);
  --text-2:      oklch(0.73 0.009 264);
  --text-3:      oklch(0.58 0.011 264);
  --accent:      oklch(0.93 0.006 264);
  --accent-2:    oklch(0.82 0.01 264);
  --accent-text: oklch(0.2 0.01 264);

  /* code/log panel surface — intentionally deeper than --surface for a console feel */
  --code-bg:   oklch(0.16 0.008 264);
  --code-text: oklch(0.75 0.009 264);

  --ok:    oklch(0.74 0.16 155);
  --ok-bg: oklch(0.3 0.06 155);
  --warn:    oklch(0.82 0.14 82);
  --warn-bg: oklch(0.33 0.06 82);
  --err:    oklch(0.68 0.19 27);
  --err-bg: oklch(0.33 0.08 27);
  --info:    oklch(0.72 0.13 250);
  --info-bg: oklch(0.32 0.06 250);

  --track:   oklch(0.28 0.012 264);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* App shell: the page is exactly the viewport height — the sticky top bar sits above a single scroll area
   (<main>). This lets the Dashboard's table view fill the space between the top bar and a bottom-pinned
   event stream without the window itself scrolling. Resizing recomputes automatically (flex + 100% height). */
body {
  display: flex;
  flex-direction: column;
  background-image:
    linear-gradient(var(--bg-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px);
  background-size: 44px 44px;
  background-position: -1px -1px;
}
main { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background: radial-gradient(120% 90% at 50% -10%, transparent 40%, var(--bg) 100%);
  pointer-events: none;
  /* Behind the content (negative), not in front: this is a background vignette over the grid, not an
     overlay. At z-index:0 it layered ABOVE the static page content and darkened the lower viewport
     over the cards (the "faded bottom half"); -1 keeps the decoration without dimming content. */
  z-index: -1;
}

#root { position: relative; z-index: 1; }

::selection { background: var(--accent); color: var(--accent-text); }

.mono { font-family: var(--font-mono); font-feature-settings: "tnum" 1; }
.tnum { font-variant-numeric: tabular-nums; }

/* scrollbars */
* { scrollbar-width: thin; scrollbar-color: var(--border-2) transparent; }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 6px; border: 2px solid transparent; background-clip: padding-box; }
*::-webkit-scrollbar-track { background: transparent; }

/* ---------------- layout ---------------- */
.shell { max-width: var(--maxw); margin: 0 auto; padding: 0 22px 90px; }

/* Table view fills the viewport: top items (summary + toolbar) at their natural size, the table grows to
   fill the middle and scrolls internally (virtualized), and the event stream is pinned at the bottom. No
   page scroll. Recomputes on resize automatically (flex + 100% height). */
.shell.shell-fill { height: 100%; padding-bottom: 0; display: flex; flex-direction: column; min-height: 0; }
.shell-fill > .server-wrap { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.shell-fill .server-scroll { flex: 1 1 auto; max-height: none; }
.shell-fill .sec-head { flex: 0 0 auto; }
.shell-fill .eventlog { flex: 0 0 auto; margin-bottom: 10px; }
.shell-fill .eventlog-body { max-height: 24vh; overflow-y: auto; }

/* ---------------- server toolbar (search + filters + view toggle) ---------------- */
.server-bar { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; margin: 4px 0 14px; }
.server-bar-count { font-family: var(--font-mono); font-size: 12px; color: var(--text-3); background: var(--surface-3); border: 1px solid var(--border); border-radius: 999px; padding: 2px 9px; }
.server-bar-search { display: flex; align-items: center; gap: 8px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 7px 11px; transition: .14s; color: var(--text-3); }
.server-bar-search:focus-within { border-color: var(--accent-2); color: var(--text-2); }
.server-bar-search input { border: 0; background: transparent; outline: none; color: var(--text); font-family: var(--font-ui); font-size: 13px; width: 190px; }
.server-bar-search input::placeholder { color: var(--text-3); }
.server-bar-search .clr { cursor: pointer; color: var(--text-3); display: grid; place-items: center; }
.server-bar-search .clr:hover { color: var(--text); }

/* ---------------- combined server telemetry table ---------------- */
.server-wrap { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-sm); }
/* Bounded, vertically-scrollable container so the row list can virtualize (only on-screen rows render).
   At small fleets the table is just content height; it caps and scrolls internally once the list is long. */
.server-scroll { overflow-x: auto; overflow-y: auto; max-height: 72vh; }
table.server { width: 100%; border-collapse: collapse; }
/* Keep table header visible while the body scrolls. */
table.server thead th { position: sticky; top: 0; z-index: 1; }
table.server th {
  text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-3); padding: 11px 14px; border-bottom: 1px solid var(--border);
  cursor: pointer; user-select: none; white-space: nowrap; background: var(--surface-2);
}
table.server th:hover { color: var(--text-2); }
table.server th.num, table.server td.num { text-align: right; }
table.server th.chead { text-align: center; }
table.server th .arr { color: var(--accent); margin-left: 4px; }
table.server td { padding: 12px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }

/* Each server is a two-row <tbody> group: the data row plus a full-width badge strip beneath it.
   The pair hovers, clicks, and borders as one unit; the row separator sits under the badge row. */
tbody.server-group { cursor: pointer; transition: background .12s; }
tbody.server-group:hover { background: var(--surface-2); }
tbody.server-group tr:first-child td { border-bottom: 0; padding-bottom: 2px; }
tbody.server-group:last-child .server-badges td { border-bottom: 0; }
tbody.server-group .server-badges td { padding-top: 0; padding-bottom: 10px; }
tbody.server-group.s-warn td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
tbody.server-group.s-err  td:first-child { box-shadow: inset 3px 0 0 var(--err); }
tbody.server-group.s-ok   td:first-child { box-shadow: inset 3px 0 0 var(--ok); }

/* Horizontal badge strip across the bottom of a table row. Fixed minimum height so badges
   appearing/disappearing never changes the row height. */
.badge-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 24px; }

/* The live-activity chip sits on its own reserved line directly below the badge strip — never
   inline with the badges. The line keeps its height even when idle, so the chip coming, going, or
   changing length can't reflow the badges or change the row height. */
.activity-line { min-height: 24px; margin-top: 4px; display: flex; align-items: center; }

/* Single "Upload" button with a small Files / Folder pop-up menu (replaces the two upload buttons). */
.upload-menu-wrap { position: relative; display: inline-flex; }
.upload-menu-backdrop { position: fixed; inset: 0; z-index: 40; }
.upload-menu {
  position: absolute; top: calc(100% + 4px); right: 0; z-index: 41; min-width: 148px; padding: 5px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 6px 22px rgba(0, 0, 0, .28); display: flex; flex-direction: column; gap: 2px;
}
.upload-menu-item {
  display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 7px 10px;
  border-radius: 6px; font-size: 12.5px; color: var(--text-2); white-space: nowrap;
}
.upload-menu-item:hover { background: var(--surface-2); color: var(--text); }

/* Click-to-copy IP address (node table row, card, and detail header). Hugs its text so the click
   target and hover hint match the value; briefly turns green on copy. */
.copy-ip { position: relative; cursor: pointer; width: fit-content; max-width: 100%; border-radius: 4px; transition: color .12s; }
.copy-ip:hover { text-decoration: underline; }
.copy-ip.copied { color: var(--ok); text-decoration: none; }

/* Transient "Copied" badge floated to the right of the IP — appears, holds ~1s, then fades out. Absolutely
   positioned so it never shifts the row/card layout. */
.copy-ip-flag {
  position: absolute; left: calc(100% + 6px); top: 50%;
  display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; text-decoration: none;
  font-size: 10px; font-weight: 700; letter-spacing: .02em; color: var(--ok);
  background: color-mix(in srgb, var(--ok) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--ok) 38%, transparent);
  padding: 1px 6px; border-radius: 999px; pointer-events: none;
  animation: copy-ip-flag 1.8s ease forwards;
}
@keyframes copy-ip-flag {
  0%   { opacity: 0; transform: translateY(-50%) translateX(-4px); }
  12%  { opacity: 1; transform: translateY(-50%) translateX(0); }
  68%  { opacity: 1; transform: translateY(-50%) translateX(0); }
  100% { opacity: 0; transform: translateY(-50%) translateX(0); }
}

/* Node rename on the detail hero: a subtle pencil trigger next to the name, and the inline editor. */
.hero-rename { background: none; border: none; color: var(--text-3); cursor: pointer; padding: 3px; border-radius: 5px; display: inline-flex; align-items: center; }
.hero-rename:hover { color: var(--accent); background: var(--surface-2); }
.rename-box { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rename-input { width: 240px; }
.rename-pw { width: 150px; }
.rename-err { color: var(--err); font-size: 12px; }
.rename-status { color: var(--text-3); font-size: 12px; }

.server-led { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.server-led.ok { background: var(--ok); }
.server-led.warn { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-bg); }
.server-led.err { background: var(--err); box-shadow: 0 0 0 3px var(--err-bg); }
.server-node .id { font-family: var(--font-mono); font-weight: 600; font-size: 13px; white-space: nowrap; }
.server-node .ip { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3); margin-top: 2px; }
.server-node .host { font-family: var(--font-mono); font-size: 9.5px; color: var(--text-3); margin-top: 1px; }
.server-cust { display: flex; align-items: center; gap: 9px; }
.server-cust .meta { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.server-cust .nm { font-size: 13px; white-space: nowrap; }
.server-cust .st { color: var(--text-3); font-size: 12px; white-space: nowrap; }
.server-gauge { display: inline-flex; align-items: center; gap: 9px; min-width: 124px; }
.server-gauge .gt { flex: 1; height: 5px; border-radius: 999px; background: var(--track); overflow: hidden; }
.server-gauge .gt > i { display: block; height: 100%; border-radius: 999px; transition: width .5s; }
.server-gauge .gn { font-family: var(--font-mono); font-size: 12.5px; font-weight: 600; width: 42px; text-align: right; }
.server-lat { font-family: var(--font-mono); font-size: 12.5px; font-weight: 600; }
.server-trend { width: 100px; height: 28px; }
.server-seen { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
.server-dash { color: var(--text-3); font-family: var(--font-mono); }

/* ---------------- top bar ---------------- */
.topbar {
  position: sticky; top: 0; z-index: 40;
  backdrop-filter: blur(14px);
  background: color-mix(in oklch, var(--bg) 82%, transparent);
  border-bottom: 1px solid var(--border);
}
.topbar-inner {
  max-width: var(--maxw); margin: 0 auto;
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px 18px;
  padding: 13px 22px;
}
.brand { display: flex; align-items: center; gap: 11px; }
.brand-mark {
  width: 32px; height: 32px; border-radius: 8px;
  background: var(--accent); color: var(--accent-text);
  display: grid; place-items: center;
  font-weight: 800; font-size: 15px; letter-spacing: -0.5px;
  box-shadow: var(--shadow-sm);
}
.brand-name { font-weight: 700; font-size: 15px; letter-spacing: -0.2px; }
.brand-ver {
  font-family: var(--font-mono); font-size: 10px; font-weight: 600; letter-spacing: .02em;
  color: var(--text-3); margin-left: 9px; padding: 2px 7px; border-radius: 999px;
  background: var(--surface-3); border: 1px solid var(--border); vertical-align: middle; position: relative; top: -1px;
  cursor: pointer; transition: color .12s, border-color .12s;
}
.brand-ver:hover { color: var(--text); border-color: var(--accent-2); }

/* ---- header release-notes link + release notes page ---- */
.topbar-link {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500;
  color: var(--text-2); cursor: pointer; padding: 6px 10px; border-radius: 8px;
  background: transparent; border: 1px solid transparent;
}
.topbar-link:hover { background: var(--surface-2); color: var(--text); }
/* viewer-count chip → click-to-open details popup */
.viewers-wrap { position: relative; display: inline-flex; }
.viewers-wrap > button.wsind { font: inherit; }
.viewers-pop {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 41;
  min-width: 300px; max-width: 380px; max-height: 60vh; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--shadow-lg); padding: 6px 8px;
}
.viewers-pop-head { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 12px; font-weight: 600; color: var(--text-2); padding: 4px 4px 8px; border-bottom: 1px solid var(--border); }
.viewers-pop-x { background: transparent; border: 0; color: var(--text-3); font-size: 17px; line-height: 1; cursor: pointer; padding: 0 2px; }
.viewers-pop-x:hover { color: var(--text); }
.viewers-pop-empty { padding: 14px 4px; color: var(--text-3); font-size: 12.5px; }
.viewer-row { padding: 8px 4px; border-bottom: 1px solid var(--border); display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.viewer-row:last-of-type { border-bottom: 0; }
.viewer-row-main { min-width: 0; flex: 1 1 auto; }
/* block-viewer ✕: low-key until hovered, turns to the error color */
.viewer-kick { flex: 0 0 auto; background: transparent; border: 0; color: var(--text-3); font-size: 17px; line-height: 1;
  cursor: pointer; padding: 0 4px; border-radius: 6px; }
.viewer-kick:hover { color: var(--err); background: var(--err-bg); }
.viewer-ban-confirm { padding: 8px 6px 10px; border-bottom: 1px solid var(--border); background: var(--surface-2); border-radius: var(--r-sm); margin: 0 2px 4px; }
.viewer-ban-msg { font-size: 12px; color: var(--text-2); margin-bottom: 8px; }
.viewer-ban-confirm .input { width: 100%; }
.viewer-ban-err { color: var(--err); font-size: 11.5px; margin-top: 6px; }
.viewer-ban-actions { display: flex; gap: 8px; margin-top: 10px; }
.viewer-loc { font-size: 13px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 6px; }
.viewer-loc-none { color: var(--text-2); font-weight: 500; }
.iso-badge { font-family: var(--font-mono); font-size: 9.5px; font-weight: 700; letter-spacing: .04em; color: var(--text-3);
  background: var(--surface-3); border: 1px solid var(--border); border-radius: 4px; padding: 1px 4px; }
.viewer-meta { margin-top: 3px; font-size: 11px; color: var(--text-3); display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.viewers-pop-credit { padding: 8px 4px 2px; font-size: 10px; color: var(--text-3); text-align: right; }
.viewers-pop-credit a { color: inherit; text-decoration: none; }
.viewers-pop-credit a:hover { color: var(--text-2); }
.rn-ver { font-size: 15px; font-weight: 700; letter-spacing: -0.2px; }
.rn-date { margin-left: auto; font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); }
.rn-sec { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-3); margin: 12px 0 6px; }
.rn-list { margin: 0; padding-left: 18px; }
.rn-list li { font-size: 13px; color: var(--text); margin: 5px 0; line-height: 1.45; }
.brand-sub { font-size: 11px; color: var(--text-3); font-weight: 500; margin-top: -2px; }

.topbar-spacer { flex: 1; }

.wsind {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px 6px 10px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border);
  font-size: 12px; font-weight: 600; color: var(--text-2);
}
.wsind .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); position: relative; }
.wsind .dot::after {
  content: ""; position: absolute; inset: -4px; border-radius: 50%;
  border: 2px solid var(--ok); opacity: 0.5; animation: ping 1.8s ease-out infinite;
}
@keyframes ping { 0%{transform:scale(0.6);opacity:.7} 80%,100%{transform:scale(1.7);opacity:0} }

.seg {
  display: inline-flex; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 8px; padding: 3px; gap: 2px;
}
.seg button {
  border: 0; background: transparent; color: var(--text-2);
  font-family: var(--font-ui); font-size: 12px; font-weight: 600;
  padding: 5px 11px; border-radius: 6px; cursor: pointer; transition: .14s;
  display: inline-flex; align-items: center; gap: 6px;
}
.seg button:hover { color: var(--text); }
.seg button.on { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm); }

/* ---------------- summary row ---------------- */
.summary {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px;
  margin: 22px 0 24px;
}
.statcard {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 16px 18px; position: relative; overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.statcard .label { font-size: 11.5px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: .07em; }
.statcard .value { font-family: var(--font-mono); font-size: 32px; font-weight: 600; letter-spacing: -1px; margin-top: 6px; line-height: 1; }
.statcard .meta { font-size: 12px; color: var(--text-2); margin-top: 8px; display:flex; align-items:center; gap:6px; }
.statcard .accentbar { position: absolute; left: 0; top: 0; bottom: 0; width: 3px; }

/* ---------------- section heads ---------------- */
.sec-head { display: flex; align-items: baseline; gap: 12px; margin: 4px 0 14px; }
.sec-title { font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-2); }
.sec-rule { flex: 1; height: 1px; background: var(--border); }

/* ---------------- company group ---------------- */
.group { margin-bottom: 14px; }
.group-head {
  display: flex; align-items: center; gap: 14px; width: 100%;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 13px 16px; cursor: pointer; transition: .14s; text-align: left;
  box-shadow: var(--shadow-sm);
}
.group-head:hover { border-color: var(--border-2); }
.group.open .group-head { border-radius: var(--r-lg) var(--r-lg) 0 0; }
.chev { color: var(--text-3); transition: transform .2s; flex-shrink: 0; }
.group.open .chev { transform: rotate(90deg); }

.avatar {
  border-radius: 9px; display: grid; place-items: center;
  font-weight: 700; letter-spacing: -.3px; flex-shrink: 0;
  background: var(--accent); color: var(--accent-text);
}
.group-name { font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
.group-sub { font-size: 12px; color: var(--text-3); margin-top: 1px; }

.pill-row { display: flex; gap: 7px; align-items: center; }
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; padding: 3px 9px; border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
.pill .dot { width: 6px; height: 6px; border-radius: 50%; }
.pill.ok   { background: var(--ok-bg);   color: var(--ok); }
.pill.warn { background: var(--warn-bg); color: var(--warn); }
.pill.err  { background: var(--err-bg);  color: var(--err); }
.pill.ok .dot{background:var(--ok)} .pill.warn .dot{background:var(--warn)} .pill.err .dot{background:var(--err)}
.pill.muted{ background: rgba(127,127,127,.14); color: var(--text-3); }

.group-body {
  border: 1px solid var(--border); border-top: 0;
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  background: var(--surface-2);
  padding: 14px; 
}
.node-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 13px; }

/* ---------------- node card ---------------- */
.ncard {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--border-2);
  border-radius: var(--r-md); padding: 14px; cursor: pointer;
  transition: transform .14s, box-shadow .14s, border-color .14s;
  position: relative;
}
.ncard:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.ncard.s-ok   { border-left-color: var(--ok); }
.ncard.s-warn { border-left-color: var(--warn); }
.ncard.s-err  { border-left-color: var(--err); }

.ncard-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.ncard-id { font-family: var(--font-mono); font-weight: 600; font-size: 14px; letter-spacing: -.3px; }
.ncard-ip { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); margin-top: 2px; }
.ncard-host { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3); margin-top: 1px; }
.ncard-cust { display: flex; align-items: center; gap: 7px; margin: 11px 0 12px; }
.ncard-cust .nm { font-size: 12.5px; color: var(--text-2); font-weight: 500; }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 6px;
  text-transform: uppercase; letter-spacing: .04em;
}
.badge .dot { width: 6px; height: 6px; border-radius: 50%; }
.badge.ok   { background: var(--ok-bg);   color: var(--ok); }
.badge.warn { background: var(--warn-bg); color: var(--warn); }
.badge.err  { background: var(--err-bg);  color: var(--err); }
.badge.ok .dot{background:var(--ok)} .badge.warn .dot{background:var(--warn)} .badge.err .dot{background:var(--err)}
.vbadge {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
  padding: 2px 6px; border-radius: 5px; background: var(--surface-3);
  color: var(--text-3); border: 1px solid var(--border);
}

/* progress bars */
.metric { margin-top: 10px; }
.metric-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 5px; }
.metric-lbl { font-size: 11px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; }
.metric-val { font-family: var(--font-mono); font-size: 12.5px; font-weight: 600; }
.bar { height: 6px; border-radius: 999px; background: var(--track); overflow: hidden; }
.bar > i { display: block; height: 100%; border-radius: 999px; transition: width .6s cubic-bezier(.4,0,.2,1); }
.bar > i.ok{background:var(--ok)} .bar > i.warn{background:var(--warn)} .bar > i.err{background:var(--err)}

.ncard-foot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 13px; padding-top: 11px; border-top: 1px solid var(--border);
  font-size: 11.5px; color: var(--text-3);
}
.ncard-foot .mono { color: var(--text-2); }

/* ---------------- live event log ---------------- */
.eventlog {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-sm);
}
.eventlog-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--surface-2);
}
.eventlog-head .title { font-size: 13px; font-weight: 700; letter-spacing: .03em; }
.eventlog-body { max-height: 290px; overflow-y: auto; padding: 4px 0; }
.event {
  display: grid; grid-template-columns: 78px 78px 1fr; gap: 12px; align-items: center;
  padding: 7px 16px; font-size: 12.5px; border-bottom: 1px solid transparent;
  animation: event-in .35s ease;
}
.event:hover { background: var(--surface-2); }
@keyframes event-in { from { transform: translateX(-6px); } to { transform: none; } }
.event .time { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); }
.event .tag {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 5px; text-align: center;
}
.event .tag.info { background: var(--info-bg); color: var(--info); }
.event .tag.ok   { background: var(--ok-bg); color: var(--ok); }
.event .tag.warn { background: var(--warn-bg); color: var(--warn); }
.event .tag.err  { background: var(--err-bg); color: var(--err); }
.event .message { color: var(--text); }
.event .message b { font-weight: 600; }
.event .message b { font-family: var(--font-mono); }
.event .event-customer { color: var(--text-3); font-weight: 500; }

/* ---------------- buttons ---------------- */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-ui); font-size: 13px; font-weight: 600;
  padding: 8px 14px; border-radius: 8px; cursor: pointer; transition: .14s;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
}
.btn:hover { border-color: var(--border-2); background: var(--surface-2); }
.btn.primary { background: var(--accent); color: var(--accent-text); border-color: var(--accent); }
.btn.primary:hover { background: var(--accent-2); border-color: var(--accent-2); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn.sm { padding: 5px 10px; font-size: 12px; }
.btn.on { background: color-mix(in srgb, var(--accent) 16%, transparent); border-color: var(--accent); color: var(--accent); }
.btn.on:hover { background: color-mix(in srgb, var(--accent) 24%, transparent); }

/* Synthetic scrollbars overlaid on the browser-stream view (pan a page wider/taller than the viewport). */
.bstream-sb { position: absolute; z-index: 5; background: rgba(0,0,0,.5); touch-action: none; cursor: pointer; }
.bstream-sb.hidden { display: none; }
.bstream-sb-h { left: 0; right: 0; bottom: 0; height: 16px; }
.bstream-sb-v { top: 0; bottom: 0; right: 0; width: 16px; }
.bstream-sb-thumb { position: absolute; background: rgba(255,255,255,.9); border-radius: 8px; pointer-events: none; box-shadow: 0 0 0 1px rgba(0,0,0,.3); }
.bstream-sb-h .bstream-sb-thumb { top: 3px; bottom: 3px; }
.bstream-sb-v .bstream-sb-thumb { left: 3px; right: 3px; }
.bstream-sb:hover .bstream-sb-thumb { background: #fff; }

/* ---------------- breadcrumb ---------------- */
.crumbs { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-3); margin: 20px 0 16px; }
.crumbs a { color: var(--text-2); text-decoration: none; cursor: pointer; font-weight: 500; }
.crumbs a:hover { color: var(--text); }
.crumbs .sep { color: var(--border-2); }
.crumbs .cur { color: var(--text); font-weight: 600; font-family: var(--font-mono); }
/* breadcrumbs hosted in the sticky topbar (right of the theme buttons): drop the standalone
   vertical margin and add a small gap from the theme segment. flex-wrap lets them flow onto
   their own line when the topbar wraps on narrow screens. */
.topbar-crumbs { margin: 0 0 0 8px; flex-wrap: wrap; }

/* ---------------- node hero ---------------- */
.hero {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 20px 22px; box-shadow: var(--shadow-sm);
  position: relative; overflow: hidden;
}
.hero-accent { position: absolute; left: 0; top: 0; bottom: 0; width: 4px; }
.hero-top { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.hero-id { font-family: var(--font-mono); font-size: 24px; font-weight: 700; letter-spacing: -.6px; }
.hero-meta { display: flex; flex-wrap: wrap; gap: 18px 26px; margin-top: 18px; }
.kv .k { font-size: 10.5px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: .07em; }
.kv .v { font-size: 13.5px; margin-top: 3px; font-weight: 500; }
.kv .v.mono { font-family: var(--font-mono); font-weight: 500; }
.kv .v.sub { font-size: 12px; color: var(--text-3); margin-top: 2px; font-weight: 500; }
.hero-stats { display: flex; gap: 10px; margin-left: auto; }
.hstat {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 10px 16px; min-width: 92px; text-align: center;
}
.hstat .v { font-family: var(--font-mono); font-size: 22px; font-weight: 600; letter-spacing: -.5px; line-height: 1; }
.hstat .l { font-size: 10.5px; color: var(--text-3); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; margin-top: 6px; }

/* ---------------- perf cards ---------------- */
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm); overflow: hidden;
}
/* A file-tree card drops its overflow clip only while its Upload menu is open, so the drop-down isn't cut
   off when the list is short; the clip (and rounded corners) return as soon as the menu closes. */
.card.menu-open { overflow: visible; }
.card-head { display: flex; align-items: center; gap: 10px; padding: 14px 16px 12px; }
.card-head .ttl { font-size: 13px; font-weight: 700; letter-spacing: .02em; }
.card-head .ico { width: 28px; height: 28px; border-radius: 7px; background: var(--surface-3); display: grid; place-items: center; color: var(--text-2); }
.card-body { padding: 0 16px 16px; }

.statgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.sg .v { font-family: var(--font-mono); font-size: 20px; font-weight: 600; letter-spacing: -.5px; line-height: 1; }
.sg .v small { font-size: 12px; color: var(--text-3); font-weight: 500; }
.sg .l { font-size: 10.5px; color: var(--text-3); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; margin-top: 5px; }

/* sparkline legend */
.spark-wrap { margin-top: 14px; }
.spark-legend { display: flex; gap: 14px; margin-bottom: 6px; }
.spark-plot { position: relative; }   /* anchors the hover marker + tooltip over the sparkline */
.lg { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-2); font-weight: 600; }
.lg i { width: 14px; height: 3px; border-radius: 2px; }

/* top processes by CPU (Performance card) */
.top-process-wrap { margin-top: 16px; }
.top-process-title { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-3); margin-bottom: 8px; }
.top-process-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; }
.top-process-name { flex: 0 0 38%; font-family: var(--font-mono); font-size: 12px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.top-process-bar { flex: 1; height: 5px; border-radius: 999px; background: var(--track); overflow: hidden; }
.top-process-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--info); transition: width .5s; }
.top-process-pct { font-family: var(--font-mono); font-size: 12px; font-weight: 600; width: 42px; text-align: right; color: var(--text-2); }
/* memory values ("1023MB", "7.8GB") need a touch more room than a "24.1%" figure. */
.top-process-memory { width: 62px; }
.top-process-memory small { margin-left: 1px; color: var(--text-3); font-weight: 500; }

/* live agent activity — list chip. Lives in a fixed-height strip across the card's bottom so the
   chip appearing/disappearing never changes the card height (grid rows would jump otherwise). */
.activity-strip { min-height: 24px; margin-top: 9px; display: flex; align-items: center; }
.activity-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--info) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--info) 35%, transparent);
  color: var(--info); font-size: 11.5px; font-weight: 600; max-width: 100%;
}
.activity-chip span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* fallback-endpoint marker — small amber glyph beside a node name; internal at-a-glance signal */
.fallback-ico { display: inline-flex; align-items: center; color: var(--warn); margin-left: 5px; vertical-align: -2px; cursor: help; }

/* live agent activity — detail card */
.activity-idle { display: flex; align-items: center; gap: 9px; color: var(--text-3); font-size: 13px; }
.activity-dot { width: 8px; height: 8px; border-radius: 999px; background: var(--text-3); opacity: .6; }
.activity-now { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.activity-ico { display: inline-grid; place-items: center; color: var(--info); }
.activity-desc { font-weight: 600; font-size: 13.5px; color: var(--text); }
.activity-elapsed { margin-left: auto; font-size: 11.5px; color: var(--text-3); }
.activity-bar { margin-top: 12px; height: 6px; border-radius: 999px; background: var(--track); overflow: hidden; }
.activity-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--info); transition: width .5s; }
.activity-meta { display: flex; gap: 14px; margin-top: 6px; font-size: 12px; color: var(--text-2); }

/* SQL Server card — connections/sessions history graph + cleaned version banner */
.sql-graph { margin-top: 14px; }
.sql-graph-legend { display: flex; gap: 14px; margin-bottom: 6px; }
.sql-graph-legend .legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-2); font-weight: 600; }
.sql-graph-legend .legend-item i { width: 14px; height: 3px; border-radius: 2px; }
/* SQL graph hover: transparent per-point columns, a vertical marker, and a value tooltip */
.sql-graph-body { display: flex; align-items: flex-start; gap: 6px; }
.sql-graph-axis {
  display: flex; flex-direction: column; justify-content: space-between;
  flex: 0 0 30px; width: 30px; height: 44px;
  font-family: var(--font-mono); font-size: 10px; line-height: 1; color: var(--text-3);
  text-align: right;
}
.sql-graph-axis-label { display: block; }
.sql-graph-main { flex: 1; min-width: 0; }
.sql-graph-plot { position: relative; }
.sql-graph-gridline {
  position: absolute; left: 0; right: 0; height: 1px;
  background: var(--border); opacity: .4; pointer-events: none;
}
.graph-hover-layer { position: absolute; inset: 0; display: flex; }
.graph-hover-column { flex: 1; cursor: crosshair; }
.graph-marker { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--text-3); opacity: .55; pointer-events: none; transform: translateX(-0.5px); }
.graph-tooltip {
  position: absolute; top: -4px; transform: translate(-50%, -100%);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 9px; font-size: 11px; line-height: 1.5; white-space: nowrap;
  pointer-events: none; box-shadow: 0 6px 16px rgba(0,0,0,.35); z-index: 6;
}
.graph-tooltip .dot { display: inline-block; width: 9px; height: 3px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.graph-tooltip b { font-family: var(--font-mono); margin-left: 5px; color: var(--text); }
.graph-tooltip-time { font-family: var(--font-mono); color: var(--text-2); margin-bottom: 3px; padding-bottom: 3px; border-bottom: 1px solid var(--border); }
.sql-graph-times { display: flex; justify-content: space-between; margin-top: 5px; font-family: var(--font-mono); font-size: 10px; color: var(--text-3); }
.sql-severity {
  display: inline-block; margin-left: 7px; padding: 1px 6px; border-radius: 5px;
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; vertical-align: middle;
}
.sql-severity-warning { background: var(--warn-bg); color: var(--warn); }
.sql-severity-critical { background: var(--err-bg); color: var(--err); }
/* confirmation modal */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center;
  /* No dim/blur — the page behind keeps its full brightness; the backdrop only catches outside clicks. */
  background: transparent; animation: modal-fade .15s ease;
}
.modal-card {
  width: min(440px, calc(100vw - 40px)); margin: 0;
  background: var(--surface); border: 1px solid var(--border-2);
  /* crisp ring + deep shadow so the dialog reads as elevated without dimming the page */
  box-shadow: 0 0 0 1px var(--border-2), 0 30px 80px -8px rgba(0, 0, 0, .7);
}
.modal-message { color: var(--text); font-size: 13.5px; line-height: 1.55; margin: 4px 0 0; }
.modal-warning {
  display: flex; align-items: center; gap: 7px; margin-top: 13px; padding: 9px 11px; border-radius: 7px;
  background: var(--warn-bg); color: var(--warn); font-size: 12.5px; font-weight: 600;
}
.modal-actions { display: flex; gap: 9px; margin-top: 18px; }
@keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }

/* SQL on-demand backup */
.sql-backup { margin-top: 14px; }
.btn-backup {
  display: inline-flex; align-items: center; gap: 7px; padding: 7px 13px; border-radius: 7px;
  background: var(--info-bg); color: var(--info); border: 1px solid color-mix(in srgb, var(--info) 35%, transparent);
  font-size: 12.5px; font-weight: 600; cursor: pointer; transition: background .15s;
}
.btn-backup:hover { background: color-mix(in srgb, var(--info) 22%, transparent); }
.sql-backup-label { font-size: 12.5px; font-weight: 600; color: var(--text-2); margin-bottom: 7px; }
.sql-backup-percent { font-size: 11px; color: var(--text-3); margin-top: 4px; }
.sql-backup-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.sql-backup-warn { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; color: var(--warn); }
.sql-backup-note { margin-top: 8px; font-size: 11.5px; color: var(--text-3); line-height: 1.55; max-width: 660px; }
.sql-backup-result { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
.sql-backup-result.ok { color: var(--ok); }
.sql-backup-result.err { color: var(--err); }
.sql-backup-remote { font-size: 12px; color: var(--text-3); }
.sql-version { margin-top: 12px; line-height: 1.5; }
.sql-version-product { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-2); }
.sql-version-edition { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); margin-top: 2px; }

/* disk rows */
.drive { padding: 9px 0; border-bottom: 1px solid var(--border); }
.drive:last-child { border-bottom: 0; }
.drive-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.drive-letter {
  font-family: var(--font-mono); font-weight: 700; font-size: 12px;
  width: 22px; height: 22px; border-radius: 5px; display: inline-grid; place-items: center;
  background: var(--surface-3); border: 1px solid var(--border); margin-right: 9px;
}
.drive-name { font-weight: 600; font-size: 13px; }
.drive-cap { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); }

/* network rows */
.netrow { display: flex; align-items: center; justify-content: space-between; padding: 9px 0; border-bottom: 1px solid var(--border); }
.netrow:last-child { border-bottom: 0; }
.network-interface { font-weight: 600; font-size: 13px; }
.network-capacity { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); margin-top: 1px; }
.net-rates { display: flex; gap: 16px; }
.rate { text-align: right; }
.rate .v { font-family: var(--font-mono); font-size: 13px; font-weight: 600; }
.rate .l { font-size: 10px; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; }
.rate.up .v { color: var(--info); }
.rate.dn .v { color: var(--ok); }

.websocket-stats { display: flex; gap: 18px; margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border-2); }
.websocket-stat .v { font-family: var(--font-mono); font-size: 14px; font-weight: 600; }
.websocket-stat .l { font-size: 10px; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; margin-top: 2px; }

/* ---------------- screenshot panel ---------------- */
.screenshot-bar { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.field { display: flex; flex-direction: column; gap: 5px; }
.field .lbl { font-size: 10.5px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; }
.input {
  font-family: var(--font-mono); font-size: 12.5px; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 7px;
  padding: 8px 11px; outline: none; transition: .14s;
}
.input:focus { border-color: var(--accent-2); background: var(--surface); }
.input.url { min-width: 260px; }
.input.num { width: 74px; text-align: center; }

.browser {
  margin-top: 14px; border: 1px solid var(--border); border-radius: var(--r-md);
  overflow: hidden; background: var(--surface-2);
}
.browser-chrome {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  background: var(--surface-3); border-bottom: 1px solid var(--border);
}
.browser-dots { display: flex; gap: 6px; }
.browser-dots i { width: 11px; height: 11px; border-radius: 50%; background: var(--border-2); }
.browser-url {
  flex: 1; font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3);
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 5px 10px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.browser-view {
  position: relative; aspect-ratio: 16 / 10; display: grid; place-items: center;
  background:
    repeating-linear-gradient(45deg, var(--surface-2), var(--surface-2) 11px, var(--surface-3) 11px, var(--surface-3) 22px);
}
.browser-empty { text-align: center; color: var(--text-3); }
.browser-empty .mono { font-size: 12px; }
.shot-scanline {
  position: absolute; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--info), transparent);
  box-shadow: 0 0 12px var(--info); animation: scan 1.5s ease-in-out infinite;
}
@keyframes scan { 0%{top:4%} 50%{top:94%} 100%{top:4%} }
.shot-cap { position: absolute; inset: 8px; border-radius: 6px; overflow: hidden; box-shadow: var(--shadow-md); }

/* ---------------- file tree ---------------- */
.tree-toolbar {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid var(--border); background: var(--surface-2);
}
.tree-toolbar .count { margin-left: auto; font-size: 11.5px; color: var(--text-3); font-family: var(--font-mono); }
.tree-root {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-3);
  padding: 9px 14px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 8px;
}
.tree { padding: 6px 6px 10px; max-height: 380px; overflow-y: auto; }
.trow {
  display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 6px;
  cursor: pointer; transition: background .12s; font-size: 12.5px;
}
.trow:hover { background: var(--surface-2); }
.trow .tchev { color: var(--text-3); flex-shrink: 0; transition: transform .18s; }
.trow.expanded .tchev { transform: rotate(90deg); }
.trow .tname { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trow.file .tname { font-family: var(--font-mono); font-size: 11.5px; }
.trow.flash, .trow.focus { background: rgba(80,140,255,.18); transition: background .4s; }
.tsize { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3); }
.sev {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: 1px 6px; border-radius: 4px;
}
.sev.info { background: var(--info-bg); color: var(--info); }
.sev.warn { background: var(--warn-bg); color: var(--warn); }
.sev.err  { background: var(--err-bg); color: var(--err); }
.sev.full { background: var(--info-bg); color: var(--info); }
.sev.diff { background: var(--ok-bg); color: var(--ok); }
.sev.tlog { background: var(--surface-3); color: var(--text-2); border: 1px solid var(--border); }

.cbox {
  width: 16px; height: 16px; border-radius: 4px; border: 1.5px solid var(--border-2);
  display: inline-grid; place-items: center; flex-shrink: 0; transition: .12s; color: transparent;
  background: var(--surface);
}
.cbox.on { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.cbox.some { background: var(--surface-3); border-color: var(--accent-2); }


/* download footer */
.dlfoot {
  position: sticky; bottom: 16px; z-index: 30; margin-top: 18px;
  display: flex; align-items: center; gap: 16px;
  background: var(--accent); color: var(--accent-text);
  border-radius: var(--r-lg); padding: 13px 18px; box-shadow: var(--shadow-lg);
  animation: footin .3s cubic-bezier(.2,.8,.2,1);
}
@keyframes footin { from { transform: translateY(14px); } to { transform: none; } }
.dlfoot .summary-txt { font-size: 13.5px; font-weight: 600; }
.dlfoot .summary-txt small { opacity: .7; font-weight: 500; }
.dlfoot .mono { font-family: var(--font-mono); }
.dlfoot .spacer { flex: 1; }
.dlfoot .btn { background: color-mix(in oklch, var(--accent) 70%, white 30%); border: 0; color: var(--accent-text); }
[data-theme="dark"] .dlfoot .btn { background: color-mix(in oklch, var(--accent) 75%, black 25%); }
.dlfoot .btn.solid { background: var(--accent-text); color: var(--accent); }
.dlfoot .btn:hover { filter: brightness(1.06); }

/* layout cols */
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }

/* Upload progress bar in a file-card title. An indeterminate sweep while the client prepares/stages the
   package (before real download percentages arrive from the agent). */
/* "?" help badge in a card header → opens a centered help dialog (hover or click); click the backdrop closes. */
.help-badge {
  width: 16px; height: 16px; padding: 0; border-radius: 50%; border: 1px solid var(--border);
  background: var(--surface); color: var(--text-3); font-size: 11px; font-weight: 700; line-height: 1;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.help-badge:hover { color: var(--text); border-color: var(--text-3); }
.help-overlay {
  position: fixed; inset: 0; z-index: 70; background: rgba(0, 0, 0, .45);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.help-modal {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-lg);
  width: 480px; max-width: 100%; max-height: 82vh; display: flex; flex-direction: column; overflow: hidden;
}
.help-modal-head { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.help-modal-head .ttl { font-size: 13.5px; font-weight: 700; }
.help-modal-body {
  padding: 16px 18px; overflow-y: auto; font-size: 12.5px; line-height: 1.6; color: var(--text-2);
  white-space: pre-line;
}

.upbar-track { position: relative; }
.upbar-ind { position: absolute; top: 0; height: 100%; width: 38%; border-radius: 3px; animation: upbar-slide 1.1s ease-in-out infinite; }
@keyframes upbar-slide { 0% { left: -40%; } 100% { left: 100%; } }

/* progress in download (toast) */
.toast-wrap { position: fixed; right: 22px; bottom: 22px; z-index: 60; display: flex; flex-direction: column; gap: 10px; }
.toast {
  background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--info);
  border-radius: var(--r-md); padding: 12px 14px; min-width: 290px; box-shadow: var(--shadow-lg);
  animation: footin .3s ease;
}
.toast.ok { border-left-color: var(--ok); }
.toast .t-title { font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.toast .t-sub { font-size: 11.5px; color: var(--text-3); margin-top: 3px; font-family: var(--font-mono); }
.toast .t-bar { height: 4px; background: var(--track); border-radius: 999px; margin-top: 9px; overflow: hidden; }
.toast .t-bar > i { display: block; height: 100%; background: var(--info); border-radius: 999px; transition: width .2s linear; }

/* utility */
/* "backwards" (not "both"): after the entrance animation the element reverts to transform:none, so it
   doesn't leave an identity-matrix transform that would establish a containing block and make
   position:fixed modals resolve against the page instead of the viewport. */
.fade-up { animation: fadeUp .4s ease backwards; }
@keyframes fadeUp { from { transform: translateY(8px); } to { transform: none; } }
.spin { animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.flash { animation: flash 1s ease; }
@keyframes flash { 0%,100%{background:var(--surface)} 30%{background:var(--warn-bg)} }

@media (max-width: 1080px) {
  .node-grid { grid-template-columns: repeat(2, 1fr); }
  .summary { grid-template-columns: repeat(2,1fr); }
  .grid2, .two-col { grid-template-columns: 1fr; }
  .hero-stats { margin-left: 0; width: 100%; }
}
@media (max-width: 820px) {
  /* Header: let the controls wrap below the brand instead of overflowing the
     viewport (which forced a left/right scroll while the body reflowed fine). */
  .topbar-inner { gap: 10px 12px; padding: 11px 14px; }
  .topbar-spacer { flex-basis: 100%; height: 0; }   /* forces a line break after the brand */

  /* "X viewing" popup: anchored to the wrap, its 300px min-width ran off the left edge once the
     header wrapped. Drop the wrap as the positioning anchor so the popup resolves against the
     full-width sticky .topbar (its backdrop-filter is the containing block), then span the
     viewport with small margins and sit just below the header. */
  .viewers-wrap { position: static; }
  .viewers-pop { left: 8px; right: 8px; min-width: 0; max-width: none; }

  /* Table view's full-height app-shell (table fills the viewport with a pinned event stream) relies on
     a nested 100%-height flex chain that collapses on mobile — the table rendered blank while Cards
     (normal flow) worked. Fall back to normal page flow/scrolling here so the table shows and scrolls
     with the page like the Cards view. */
  .shell.shell-fill { height: auto; min-height: 0; display: block; padding-bottom: 90px; }
  .shell-fill > .server-wrap { display: block; }
  .shell-fill .server-scroll { flex: none; max-height: 72vh; }
  .shell-fill .eventlog { margin-bottom: 14px; }
  .shell-fill .eventlog-body { max-height: 290px; }
}
@media (max-width: 680px) {
  .node-grid { grid-template-columns: 1fr; }
}
