/* ==========================================================================
   Components: the repeated structures every view is assembled from.
   ========================================================================== */

/* --- App shell ----------------------------------------------------------- */

#app {
  min-height: 100%;
}

.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--sidebar-w);
  background: var(--surface-lowest);
  border-right: 1px solid var(--stroke);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  z-index: 50;
}

.sidebar-brand {
  height: var(--header-h);
  padding: 0 var(--sp-md);
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--surface-low);
  border-bottom: 1px solid var(--stroke);
  flex-shrink: 0;
}

.brand-mark {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  font-family: var(--font-headline);
  font-size: var(--fs-headline-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--primary);
}

.nav {
  padding: var(--sp-sm);
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}

.nav-group {
  padding: var(--sp-md) var(--sp-sm) var(--sp-xs);
  color: var(--outline);
}

.nav-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-sm);
  padding: var(--sp-sm);
  border-radius: var(--r-lg);
  color: var(--on-surface-variant);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
  user-select: none;
}

.nav-item:hover {
  background: var(--surface-high);
  color: var(--on-surface);
}

.nav-item[aria-current="page"] {
  background: var(--primary-container);
  color: var(--on-primary-container);
  font-weight: 600;
  box-shadow: var(--glow-live);
}

.nav-item .ico {
  width: 18px;
  text-align: center;
  flex-shrink: 0;
}

/* Counters and state badges sit on one line; the label truncates instead. */
.nav-item > span:last-child { white-space: nowrap; flex-shrink: 0; }
.nav-item .t-body { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sidebar-foot {
  margin: var(--sp-sm);
  padding: var(--sp-md);
  background: var(--surface-low);
  border: 1px solid var(--stroke);
  border-radius: var(--r-xl);
  flex-shrink: 0;
}

.header {
  position: fixed;
  top: 0;
  left: var(--sidebar-w);
  right: 0;
  height: var(--header-h);
  padding: 0 var(--sp-lg);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
  /* Tier-1 smoked acrylic over whatever scrolls beneath. */
  background: rgb(var(--header-rgb) / 0.85);
  backdrop-filter: blur(var(--blur-2));
  -webkit-backdrop-filter: blur(var(--blur-2));
  border-bottom: 1px solid var(--stroke);
  z-index: 40;
}

.main {
  padding-left: var(--sidebar-w);
  padding-top: var(--header-h);
}

.view {
  padding: var(--gutter) var(--margin) var(--sp-xl);
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
  position: relative;
  animation: fade-up var(--t-base) var(--ease);
  /* The ambient blobs are deliberately hung past the edges — `.ambient-b` sits
     200px beyond the right one — and an absolutely positioned child still
     counts toward scrollable overflow. Every page therefore carried a
     horizontal scrollbar and 200px of empty document for decoration nobody can
     interact with.

     `clip` rather than `hidden`: `hidden` would make this a scroll container,
     which changes what `position: sticky` inside it sticks to. Nothing here
     relies on that today — the sticky table headers stick within their own
     `.table-wrap` — but the difference is invisible until something does. */
  overflow-x: clip;
}

@media (max-width: 1200px) {
  .sidebar { transform: translateX(-100%); transition: transform var(--t-base) var(--ease); }
  .sidebar.open { transform: none; }
  .header { left: 0; }
  .main { padding-left: 0; }
  .view { padding: var(--sp-md); }
}

/* Ambient sub-surface glow: radial bloom behind the content, never on top. */
.ambient {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  z-index: 0;
  filter: blur(100px);
}
.ambient-a { top: -140px; left: -120px; width: 420px; height: 420px; background: rgb(var(--accent-rgb) / 0.10); }
.ambient-b { top: 40%; right: -200px; width: 420px; height: 420px; background: rgb(78 222 163 / 0.09); }
.ambient-c { bottom: -80px; left: 30%; width: 520px; height: 280px; background: rgb(var(--accent-rgb) / 0.05); filter: blur(90px); }

/* --- Widget: the glass panel everything lives in ------------------------- */

.widget {
  position: relative;
  z-index: 1;
  background: var(--glass-1);
  backdrop-filter: blur(var(--blur-1));
  -webkit-backdrop-filter: blur(var(--blur-1));
  border: 1px solid var(--stroke);
  border-radius: var(--r-xl);
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* Isolate each widget's layout and paint: a chart repainting at 60fps
     must never force the rest of the page to reflow. */
  contain: layout style;
  transition: border-color var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}

/* Dynamic top hairline that illuminates on hover. */
.widget::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(var(--fg-rgb) / 0.10), transparent);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  opacity: 0;
  transition: opacity var(--t-base) var(--ease);
  pointer-events: none;
}
.widget:hover::before { opacity: 1; }

.widget.elevated {
  background: var(--glass-2);
  backdrop-filter: blur(var(--blur-2));
  -webkit-backdrop-filter: blur(var(--blur-2));
  border-top-color: var(--stroke-bevel);
}

.widget.live   { border-color: var(--signal-live); box-shadow: var(--glow-live); }
.widget.ok     { border-color: var(--signal-ok); box-shadow: var(--glow-ok); }
.widget.warn   { border-color: var(--signal-warn); box-shadow: var(--glow-warn); }
.widget.crit   { border-color: var(--signal-crit); box-shadow: var(--glow-crit); }

.widget-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-sm);
  padding: var(--sp-md) var(--sp-md) var(--sp-sm);
  flex-shrink: 0;
  min-height: 40px;
}

.widget-title {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  min-width: 0;
}

.widget-body {
  padding: 0 var(--sp-md) var(--sp-md);
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
}

.widget-body.flush { padding: 0; }
.widget-body.tight { padding: 0 var(--sp-sm) var(--sp-sm); }

/* Control dock in a widget header: time-range switches, inspectors. */
.dock {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  background: var(--surface-high);
  border-radius: var(--r-lg);
  flex-shrink: 0;
}

.dock button {
  padding: 3px 8px;
  border: 0;
  background: transparent;
  border-radius: var(--r-md);
  font-family: var(--font-mono);
  font-size: var(--fs-label-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-surface-variant);
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.dock button:hover { color: var(--on-surface); }
.dock button[aria-pressed="true"] {
  background: var(--surface-container);
  color: var(--primary-container);
}

/* --- Stat: the big metric readout ---------------------------------------- */

.stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.stat-value {
  font-family: var(--font-mono);
  font-size: var(--fs-metric);
  line-height: var(--lh-metric);
  font-weight: 600;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.stat-value.sm { font-size: 20px; line-height: 26px; }

.stat-unit {
  font-size: var(--fs-body-sm);
  font-weight: 500;
  color: var(--on-surface-variant);
  margin-left: 2px;
}

.stat-delta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-family: var(--font-mono);
  font-size: var(--fs-label-sm);
  font-weight: 600;
  letter-spacing: 0.06em;
}

/* --- Pulse indicator ------------------------------------------------------ */

.pulse {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--signal-ok);
}

.pulse::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: pulse-ring 2s cubic-bezier(0, 0, 0.2, 1) infinite;
}

.pulse.sm { width: 6px; height: 6px; }
.pulse.ok   { background: var(--signal-ok); }
.pulse.live { background: var(--signal-live); }
.pulse.warn { background: var(--signal-warn); }
.pulse.crit { background: var(--signal-crit); }
/* Offline is the one state that should not draw the eye. */
.pulse.idle { background: var(--signal-idle); }
.pulse.idle::after { animation: none; }

/* --- Chips & badges ------------------------------------------------------- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  padding: 2px var(--sp-sm);
  border-radius: var(--r-full);
  background: var(--surface-container);
  border: 1px solid transparent;
  font-family: var(--font-mono);
  font-size: var(--fs-label-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-surface-variant);
  white-space: nowrap;
  flex-shrink: 0;
}

.chip .dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

.chip.ok   { background: var(--tint-ok);   color: var(--signal-ok); }
.chip.live { background: var(--tint-live); color: var(--signal-live); }
.chip.warn { background: var(--tint-warn); color: var(--signal-warn); }
.chip.crit { background: var(--tint-crit); color: var(--signal-crit-text); border-color: rgb(239 68 68 / 0.4); }
.chip.info { background: var(--tint-info); color: var(--signal-info); }
.chip.plain { background: var(--surface-high); color: var(--on-surface-variant); }

.chip.solid-live { background: var(--primary-container); color: var(--on-primary-container); }

.badge-count {
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--r-full);
  background: var(--signal-crit);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-xs);
  padding: 6px var(--sp-md);
  border-radius: var(--r-lg);
  border: 1px solid var(--stroke-strong);
  background: rgb(var(--panel-2-rgb) / 0.6);
  color: var(--on-surface);
  font-size: var(--fs-body-sm);
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}

.btn:hover { border-color: var(--primary-container); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn:disabled:hover { border-color: var(--stroke-strong); }

.btn.primary {
  background: var(--primary-container);
  border-color: var(--primary-container);
  color: var(--on-primary-container);
  font-weight: 600;
}
.btn.primary:hover { box-shadow: 0 0 12px rgb(var(--accent-rgb) / 0.4); }

.btn.danger {
  background: rgb(239 68 68 / 0.15);
  border-color: var(--signal-crit);
  color: var(--signal-crit-text);
}
.btn.danger:hover { background: var(--signal-crit); color: #16070a; }

.btn.ghost { background: transparent; border-color: var(--stroke); }
.btn.sm { padding: 3px var(--sp-sm); font-size: var(--fs-label-sm); font-family: var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; }
.btn.icon { padding: 6px; width: 30px; height: 30px; }

/* --- Inputs --------------------------------------------------------------- */

.input,
.select {
  width: 100%;
  padding: 6px var(--sp-sm);
  background: rgb(var(--panel-rgb) / 0.8);
  border: 1px solid rgb(var(--fg-rgb) / 0.12);
  border-radius: var(--r-lg);
  color: var(--on-surface);
  font-family: var(--font-mono);
  font-size: var(--fs-code);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}

.input::placeholder { color: var(--outline); }

.input:focus,
.select:focus {
  outline: none;
  border-color: var(--primary-container);
  box-shadow: 0 0 0 1px var(--primary-container);
}

.select {
  cursor: pointer;
  appearance: none;
  padding-right: 24px;
  background-image: linear-gradient(45deg, transparent 50%, var(--outline) 50%),
    linear-gradient(135deg, var(--outline) 50%, transparent 50%);
  background-position: calc(100% - 13px) 12px, calc(100% - 8px) 12px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.select option { background: var(--surface-high); color: var(--on-surface); }

/* The console's own dropdown (lib/select.js): the <select> stays, hidden, as
   the value; this button and its menu are what the operator sees. */
.pselect-native { display: none !important; }
.pselect {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  max-width: 100%;
  text-align: left;
  cursor: pointer;
  padding-right: 26px;
  background-image: linear-gradient(45deg, transparent 50%, var(--outline) 50%),
    linear-gradient(135deg, var(--outline) 50%, transparent 50%);
  background-position: calc(100% - 13px) 50%, calc(100% - 8px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  line-height: 1.4;
}
.pselect.input { background-color: rgb(var(--panel-rgb) / 0.8); }
.pselect:hover:not(:disabled) { border-color: rgb(var(--fg-rgb) / 0.22); }
.pselect:focus-visible,
.pselect.open {
  outline: none;
  border-color: var(--primary-container);
  box-shadow: 0 0 0 1px var(--primary-container);
}
.pselect.open {
  background-image: linear-gradient(135deg, transparent 50%, var(--primary-container) 50%),
    linear-gradient(45deg, var(--primary-container) 50%, transparent 50%);
}
.pselect:disabled { opacity: 0.5; cursor: not-allowed; }
.pselect[hidden] { display: none; }
.pselect-text {
  flex: 1;
  min-width: 0;
  min-height: 1.4em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pselect-menu {
  position: fixed;
  z-index: 300;
  display: flex;
  flex-direction: column;
  max-width: min(480px, calc(100vw - 16px));
  background: var(--glass-3);
  border: 1px solid var(--stroke-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--elev-3);
  backdrop-filter: blur(var(--blur-2));
  -webkit-backdrop-filter: blur(var(--blur-2));
  overflow: hidden;
  animation: pselect-in 110ms var(--ease);
  transform-origin: top center;
}
.pselect-menu.up { transform-origin: bottom center; }
@keyframes pselect-in {
  from { opacity: 0; transform: translateY(-3px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
.pselect-menu.up { animation-name: pselect-in-up; }
@keyframes pselect-in-up {
  from { opacity: 0; transform: translateY(3px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .pselect-menu { animation: none; } }
.pselect-filter.input {
  margin: 6px 6px 2px;
  width: auto;
  flex-shrink: 0;
}
.pselect-list {
  overflow-y: auto;
  padding: 4px;
  overscroll-behavior: contain;
}
.pselect-group {
  padding: 8px 10px 4px;
  color: var(--outline);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.pselect-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px 6px 6px;
  border-radius: var(--r-md, 6px);
  color: var(--on-surface);
  font-family: var(--font-mono);
  font-size: var(--fs-code);
  cursor: pointer;
  white-space: nowrap;
}
.pselect-item.active { background: var(--tint-live); }
.pselect-item[aria-selected="true"] { color: var(--primary-container); }
.pselect-item[aria-disabled="true"] { opacity: 0.4; cursor: default; }
.pselect-check {
  width: 14px;
  flex-shrink: 0;
  text-align: center;
  color: var(--primary-container);
  font-size: 12px;
}
.pselect-label { overflow: hidden; text-overflow: ellipsis; }
.pselect-empty { padding: 10px 12px; color: var(--on-surface-variant); }

.field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
  min-width: 0;
}

.search {
  position: relative;
  display: flex;
  align-items: center;
}
.search .ico {
  position: absolute;
  left: var(--sp-sm);
  color: var(--outline);
  pointer-events: none;
  font-size: 13px;
}
.search .input { padding-left: 28px; }

.switch {
  position: relative;
  width: 34px;
  height: 18px;
  border-radius: var(--r-full);
  background: var(--surface-highest);
  border: 1px solid var(--stroke);
  cursor: pointer;
  flex-shrink: 0;
  padding: 0;
  transition: background var(--t-base) var(--ease), border-color var(--t-base) var(--ease);
}
.switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--outline);
  transition: transform var(--t-base) var(--ease), background var(--t-base) var(--ease);
}
.switch[aria-checked="true"] {
  background: var(--secondary-container);
  border-color: var(--secondary);
}
.switch[aria-checked="true"]::after {
  transform: translateX(16px);
  background: var(--secondary-fixed);
}

/* --- Tables: 32px rows, zebra by alpha tier ------------------------------- */

.table-wrap {
  overflow: auto;
  border-radius: var(--r-lg);
}

table.data {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--fs-body-sm);
}

table.data thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface-low);
  padding: var(--sp-sm) var(--sp-md);
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--fs-label-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--outline);
  white-space: nowrap;
  border-bottom: 1px solid var(--stroke);
  user-select: none;
}

table.data thead th.sortable { cursor: pointer; }
table.data thead th.sortable:hover { color: var(--on-surface-variant); }
table.data thead th[aria-sort] { color: var(--primary-container); }

table.data tbody td {
  height: var(--row-h);
  padding: 0 var(--sp-md);
  border-bottom: 1px solid rgb(var(--fg-rgb) / 0.03);
  white-space: nowrap;
  vertical-align: middle;
}

table.data tbody tr:nth-child(odd) { background: rgb(var(--fg-rgb) / 0.012); }

table.data tbody tr {
  transition: background var(--t-fast) var(--ease);
  position: relative;
}

table.data tbody tr:hover { background: rgb(var(--accent-rgb) / 0.05); }

/* Left edge marker on hover, drawn on the first cell so it does not disturb
   the row's box. */
table.data tbody tr:hover td:first-child { box-shadow: inset 2px 0 0 var(--primary-container); }

table.data tbody tr.selected { background: rgb(var(--accent-rgb) / 0.08); }
table.data tbody tr.selected td:first-child { box-shadow: inset 2px 0 0 var(--primary-container); }
table.data tbody tr.clickable { cursor: pointer; }

table.data td.num { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
table.data th.num { text-align: right; }

/* --- Meters --------------------------------------------------------------- */

.meter {
  width: 100%;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--surface-container);
  overflow: hidden;
}

.meter.thin { height: 3px; }
.meter.thick { height: 10px; }

.meter > i {
  display: block;
  height: 100%;
  border-radius: var(--r-full);
  background: var(--signal-ok);
  transition: width var(--t-slow) var(--ease), background var(--t-base) var(--ease);
}

.meter > i.ok   { background: var(--signal-ok); }
.meter > i.live { background: var(--signal-live); }
.meter > i.warn { background: var(--signal-warn); }
.meter > i.crit { background: var(--signal-crit); }

/* Segmented meter for quota/limit displays. */
.meter.seg { background: repeating-linear-gradient(90deg, var(--surface-container) 0 3px, transparent 3px 5px); }

/* --- Log stream ----------------------------------------------------------- */

.logline {
  display: grid;
  grid-template-columns: 92px 58px 170px 1fr;
  gap: var(--sp-sm);
  padding: 3px var(--sp-md);
  font-family: var(--font-mono);
  font-size: var(--fs-code);
  line-height: 18px;
  border-bottom: 1px solid rgb(var(--fg-rgb) / 0.03);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease);
  align-items: baseline;
}

.logline:hover { background: rgb(var(--accent-rgb) / 0.05); }
.logline.selected { background: rgb(var(--accent-rgb) / 0.08); box-shadow: inset 2px 0 0 var(--primary-container); }
.logline .msg { white-space: pre-wrap; word-break: break-word; color: var(--on-surface-variant); }
.logline.lv-warn  .msg { color: var(--signal-warn); }
.logline.lv-error .msg,
.logline.lv-fatal .msg { color: var(--signal-crit-text); }

@media (max-width: 900px) {
  .logline { grid-template-columns: 78px 50px 1fr; }
  .logline .svc { display: none; }
}

/* --- Misc ----------------------------------------------------------------- */

.kv {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-xs) var(--sp-md);
  align-items: baseline;
}
.kv dt { color: var(--outline); font-family: var(--font-mono); font-size: var(--fs-label-sm); letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; }
.kv dd { margin: 0; font-family: var(--font-mono); font-size: var(--fs-code); text-align: right; }

.divider { height: 1px; background: var(--stroke); border: 0; margin: 0; }
.vdivider { width: 1px; align-self: stretch; background: var(--stroke); flex-shrink: 0; }

.empty {
  padding: var(--sp-xl) var(--sp-md);
  text-align: center;
  color: var(--outline);
  font-size: var(--fs-body-sm);
}

.skeleton {
  background: linear-gradient(90deg, var(--surface-container) 25%, var(--surface-high) 50%, var(--surface-container) 75%);
  background-size: 200% 100%;
  animation: pulse-fade 1.4s ease-in-out infinite;
  border-radius: var(--r-md);
}

.spinner {
  width: 14px;
  height: 14px;
  border: 2px solid var(--stroke-strong);
  border-top-color: var(--primary-container);
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}

/* Toasts: transient confirmation for a mutation. */
.toasts {
  position: fixed;
  right: var(--margin);
  bottom: var(--margin);
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  z-index: 200;
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  padding: var(--sp-sm) var(--sp-md);
  background: var(--glass-3);
  backdrop-filter: blur(var(--blur-3));
  -webkit-backdrop-filter: blur(var(--blur-3));
  border: 1px solid rgb(var(--accent-rgb) / 0.25);
  border-radius: var(--r-lg);
  box-shadow: var(--elev-3);
  font-size: var(--fs-body-sm);
  animation: fade-up var(--t-base) var(--ease);
  pointer-events: auto;
  max-width: 380px;
}

.toast.err { border-color: rgb(239 68 68 / 0.45); }
.toast.ok { border-color: rgb(78 222 163 / 0.35); }

/* Modal / drawer: Tier 3 dense smoked glass. */
.scrim {
  position: fixed;
  inset: 0;
  background: rgb(5 8 14 / 0.6);
  backdrop-filter: blur(2px);
  z-index: 150;
  animation: fade-up var(--t-fast) var(--ease);
}

.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  background: var(--glass-3);
  backdrop-filter: blur(var(--blur-3));
  -webkit-backdrop-filter: blur(var(--blur-3));
  border: 1px solid rgb(var(--accent-rgb) / 0.25);
  border-radius: var(--r-xl);
  box-shadow: var(--elev-3);
  z-index: 151;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.modal-head,
.modal-foot {
  padding: var(--sp-md);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-sm);
  flex-shrink: 0;
}
.modal-head { border-bottom: 1px solid var(--stroke); }
.modal-foot { border-top: 1px solid var(--stroke); }
.modal-body { padding: var(--sp-md); overflow-y: auto; display: flex; flex-direction: column; gap: var(--sp-md); }

.drawer {
  position: fixed;
  top: var(--header-h);
  right: 0;
  bottom: 0;
  width: min(460px, 100vw);
  background: var(--glass-3);
  backdrop-filter: blur(var(--blur-3));
  -webkit-backdrop-filter: blur(var(--blur-3));
  border-left: 1px solid rgb(var(--accent-rgb) / 0.25);
  box-shadow: var(--elev-3);
  z-index: 60;
  display: flex;
  flex-direction: column;
  animation: fade-up var(--t-base) var(--ease);
}

/* Terminal-style output block. */
.term {
  background: rgb(5 8 14 / 0.85);
  border: 1px solid var(--stroke);
  border-radius: var(--r-lg);
  padding: var(--sp-sm) var(--sp-md);
  font-family: var(--font-mono);
  font-size: var(--fs-code);
  line-height: var(--lh-code);
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--on-surface-variant);
}

/* Ticker strip: a marquee of recent events. */
.ticker {
  overflow: hidden;
  position: relative;
  height: 20px;
}
.ticker > div {
  position: absolute;
  white-space: nowrap;
  animation: sweep 28s linear infinite;
}

/* Node Compare marks the value worth looking at in each row. A tint plus the
   inset rule, not a background swap: the cell still has to read as a number
   in a column of numbers, and colour alone would be lost on the operators
   this console is full of. */
table.data td.outlier {
  background: rgb(255 176 32 / 0.08);
  box-shadow: inset 0 0 0 1px var(--signal-warn);
}

/* ------------------------------------------------------- global search --
   The header's search box (lib/search.js, runzero GlobalSearch.vue). */
.gs {
  position: relative;
  width: 100%;
  max-width: 460px;
  display: flex;
  align-items: center;
}
.gs-icon {
  position: absolute;
  left: 9px;
  color: var(--outline);
  display: inline-flex;
  pointer-events: none;
}
.gs-input.input {
  padding-left: 30px;
  padding-right: 30px;
}
.gs-input::-webkit-search-cancel-button { display: none; }
.gs-kbd {
  position: absolute;
  right: 8px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--outline);
  border: 1px solid var(--stroke-strong);
  border-radius: 4px;
  padding: 0 5px;
  pointer-events: none;
}
.gs-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  max-height: min(70vh, 520px);
  overflow-y: auto;
  background: var(--glass-3);
  border: 1px solid var(--stroke-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--elev-3);
  backdrop-filter: blur(var(--blur-2));
  padding: 6px 0;
  z-index: 60;
}
.gs-panel[hidden] { display: none; }
.gs-group + .gs-group { border-top: 1px solid var(--stroke); margin-top: 4px; padding-top: 4px; }
.gs-group-title { padding: 4px 12px; text-transform: uppercase; letter-spacing: 0.06em; }
.gs-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 6px 12px;
  color: var(--on-surface);
  text-decoration: none;
  cursor: pointer;
}
.gs-item[aria-selected="true"] { background: var(--tint-live); }
.gs-primary { white-space: nowrap; }
.gs-empty { padding: 14px 12px; color: var(--on-surface-variant); display: flex; justify-content: center; }
.gs-hint, .gs-note { padding: 6px 12px 2px; }
.gs-note { font-size: 11px; }

/* My account (views/admin/account.js) */
.avatar-lg {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--surface-high);
  color: var(--primary-container);
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 600;
  flex-shrink: 0;
}
@media (max-width: 900px) {
  .gs { max-width: none; }
  .gs-kbd { display: none; }
}
