/* ================================================================
   CONSOLIDATED STATS DIALOG — consolidated-stats-dialog.css
   Self-contained — read-only viewer, doesn't need the full
   create/edit form design system. Mirrors interceptor-stats-dialog.css.
   ================================================================ */

.csd-dialog {
  --csd-indigo-600: #4756e8;
  --csd-indigo-500: #5b6cf9;
  --csd-grad-brand: linear-gradient(135deg, #5b6cf9 0%, #764ba2 100%);
  --csd-surface:    #FFFFFF;
  --csd-surface-2:  #F7F8FC;
  --csd-text-primary:   #111827;
  --csd-text-secondary: #4B5878;
  --csd-text-muted:     #8E97B4;
  --csd-border:        #E2E5EF;
  --csd-border-strong: #C5CCDF;
  --csd-green:        #16A34A;
  --csd-green-bg:     rgba(22,163,74,0.10);
  --csd-red:          #DC2626;
  --csd-red-bg:       rgba(220,38,38,0.10);
  /* Same hues as the list view's status dot (biz-interceptors-tab.css
     --on/--warn/--agent-unreachable/--off) so the badge here always reads
     as "the same status" as the summary dot, not a different color scheme. */
  --csd-yellow:       #D97706;
  --csd-yellow-bg:    rgba(245,158,11,0.12);
  --csd-gray-dark:    #4B5563;
  --csd-gray-dark-bg: rgba(75,85,99,0.12);
  --csd-r-sm: 4px;
  --csd-r-md: 6px;
  --csd-r-xl: 14px;
  --csd-t: 160ms cubic-bezier(.4,0,.2,1);

  /* Widened from 1420px so the Operations tab's Endpoint/Collection/
     Operation columns (full text, no ellipsis — see .csd-col-endpoint
     etc. below) plus every counter column fit without the counter
     columns getting pushed past the dialog's right edge. max-width
     still caps it on smaller screens; .csd-list below scrolls
     horizontally as a fallback for whatever doesn't fit there.

     Trimmed back down from 1650px once the Environments table (see
     .csd-env-list-header/.csd-env-row) lost 3 wide columns — with 1650px
     of dialog width still sized for the OLD, wider Environments table,
     the now-narrower table left a big empty gutter to the right of Agent.
     1600px is the narrowest this can go without reintroducing a
     horizontal scroll on the OPERATIONS tab, though — that tab's own
     fixed-width columns (.csd-list-header/.csd-row's grid-template-columns)
     are what's actually widest here, wider than the Environments table
     even after this trim, so some residual gutter on the Environments
     tab specifically is the trade-off for keeping Operations scroll-free;
     shrinking further would just move the empty space from one tab to a
     scrollbar on the other. */
  width: 1600px !important;
  min-width: 1370px !important;
  max-width: 95vw !important;
  height: 760px !important;
  min-height: 760px !important;
  max-height: 90vh !important;
  border-radius: var(--csd-r-xl) !important;
  overflow: hidden !important;
  display: flex !important;
  flex-direction: column !important;
  box-shadow: 0 20px 60px rgba(8,12,24,.22) !important;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif !important;
}

/* ── Toolbar ──────────────────────────────────────────────── */

body md-dialog.csd-dialog md-toolbar.csd-toolbar {
  background: var(--csd-grad-brand) !important;
  box-shadow: 0 2px 12px rgba(91,108,249,.28) !important;
  min-height: 60px !important;
  max-height: 60px !important;
  flex-shrink: 0 !important;
}

body md-dialog.csd-dialog .md-toolbar-tools {
  padding: 0 18px !important;
  min-height: 60px !important;
  max-height: 60px !important;
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
}

.csd-toolbar-icon {
  color: #fff !important;
  font-size: 20px !important;
  width: 20px !important;
  height: 20px !important;
  flex-shrink: 0 !important;
}

.csd-header-info {
  display: flex !important; flex-direction: column !important; align-items: flex-start !important;
  gap: 2px !important; min-width: 0 !important; text-align: left !important;
}
.csd-header-info h2 {
  font-size: 16px !important; font-weight: 600 !important; color: #fff !important;
  margin: 0 !important; line-height: 1.2 !important; white-space: nowrap !important; text-align: left !important;
}
.csd-header-subtitle {
  font-size: 11.5px !important; color: rgba(255,255,255,.8) !important;
  white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important;
  text-align: left !important; width: 100% !important;
}

body md-dialog.csd-dialog .md-toolbar-tools > .md-icon-button {
  color: #fff !important; margin: 0 !important;
  width: 34px !important; height: 34px !important; min-width: 34px !important; min-height: 34px !important;
  border-radius: var(--csd-r-md) !important;
}
body md-dialog.csd-dialog .md-toolbar-tools > .md-icon-button md-icon { color: rgba(255,255,255,.75) !important; font-size: 18px !important; width: 18px !important; height: 18px !important; }
body md-dialog.csd-dialog .md-toolbar-tools > .md-icon-button:hover md-icon { color: #fff !important; }
body md-dialog.csd-dialog .md-toolbar-tools > .md-icon-button:hover { background: rgba(255,255,255,.12) !important; }

/* ── Content ──────────────────────────────────────────────── */

.csd-content {
  padding: 0 !important;
  background: var(--csd-surface-2) !important;
  overflow: hidden !important;
  flex: 1 1 auto !important;
  display: flex !important;
}

.csd-body {
  display: flex !important;
  flex: 1 1 auto !important;
  min-height: 0 !important;
  width: 100% !important;
}

/* ── Vertical tab nav ─────────────────────────────────────── */

.csd-tab-nav {
  flex: 0 0 200px !important;
  width: 200px !important;
  overflow-y: auto !important;
  background: var(--csd-surface) !important;
  border-right: 1px solid var(--csd-border) !important;
  padding: 12px 0 !important;
}

.csd-tab-nav-item {
  display: flex !important; align-items: center !important; gap: 10px !important;
  height: 40px !important; padding: 0 18px !important; margin: 0 8px 2px !important;
  border-radius: var(--csd-r-md) !important;
  font-size: 12.5px !important; font-weight: 600 !important; color: var(--csd-text-secondary) !important;
  cursor: pointer !important; transition: background var(--csd-t), color var(--csd-t) !important;
  white-space: nowrap !important;
}
.csd-tab-nav-item:hover { background: var(--csd-surface-2) !important; color: var(--csd-text-primary) !important; }

.csd-tab-nav-item--active {
  background: rgba(91,108,249,.10) !important;
  color: var(--csd-indigo-600) !important;
}

.csd-tab-nav-icon {
  font-size: 17px !important; width: 17px !important; height: 17px !important; min-width: 17px !important;
  margin: 0 !important; color: inherit !important;
}

.csd-tab-nav-label {
  overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important;
}

.csd-tab-panel {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  overflow-y: auto !important;
  padding: 28px 24px 20px !important;
}

/* ── Sub-tabs: Stats vs Operations ────────────────────────── */

.csd-subtab-nav {
  display: flex !important; gap: 4px !important;
  margin: 0 0 20px !important; padding-bottom: 2px !important;
  border-bottom: 1px solid var(--csd-border) !important;
}
.csd-subtab-item {
  display: inline-flex !important; align-items: center !important; gap: 7px !important;
  height: 36px !important; padding: 0 16px !important;
  font-size: 12.5px !important; font-weight: 700 !important; color: var(--csd-text-secondary) !important;
  cursor: pointer !important; user-select: none !important;
  border-bottom: 2px solid transparent !important;
  transition: color var(--csd-t), border-color var(--csd-t) !important;
}
.csd-subtab-item:hover { color: var(--csd-text-primary) !important; }
.csd-subtab-item md-icon {
  font-size: 17px !important; width: 17px !important; height: 17px !important; min-width: 17px !important;
  margin: 0 !important; color: inherit !important;
}
.csd-subtab-item--active {
  color: var(--csd-indigo-600) !important;
  border-bottom-color: var(--csd-indigo-500) !important;
}
.csd-subtab-count {
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  min-width: 18px !important; height: 18px !important; padding: 0 5px !important;
  font-size: 10px !important; font-weight: 800 !important; line-height: 1 !important;
  border-radius: 10px !important;
  background: rgba(91,108,249,.14) !important; color: var(--csd-indigo-600) !important;
}

/* ── Summary row ──────────────────────────────────────────── */

.csd-summary-row {
  display: flex !important; align-items: center !important; justify-content: space-between !important;
  gap: 10px !important; margin: 0 0 20px !important; flex-wrap: wrap !important;
}

.csd-summary-badges { display: flex !important; align-items: center !important; gap: 8px !important; flex-wrap: wrap !important; }

.csd-summary-badge {
  display: inline-flex !important; align-items: center !important; justify-content: center !important; gap: 6px !important;
  height: 28px !important; box-sizing: border-box !important; line-height: 1 !important;
  font-size: 12.5px !important; font-weight: 600 !important; color: var(--csd-text-primary) !important;
  background: var(--csd-surface) !important; border: 1px solid var(--csd-border) !important;
  padding: 0 14px !important; border-radius: 20px !important;
}
.csd-summary-badge md-icon {
  display: flex !important; align-items: center !important; justify-content: center !important;
  font-size: 16px !important; width: 16px !important; height: 16px !important; min-width: 16px !important;
  margin: 0 !important; line-height: 1 !important; color: var(--csd-indigo-500) !important;
}
.csd-summary-badge md-icon svg { width: 100% !important; height: 100% !important; }
/* Distinct from the neutral online/live badges above it — this one is
   only rendered when there's actually something to act on (ng-if guarded
   in the template), so it should read as a flag, not just another count. */
.csd-summary-badge--restart { background: rgba(71,86,232,.08) !important; border-color: rgba(71,86,232,.3) !important; color: var(--csd-indigo-600) !important; }
.csd-summary-badge--restart md-icon { color: var(--csd-indigo-600) !important; }
/* Same red as the pressure SLA alert — an upload failure is a live problem,
   not just a pending config change like restart above. */
.csd-summary-badge--upload { background: var(--csd-red-bg) !important; border-color: rgba(220,38,38,.3) !important; color: var(--csd-red) !important; }
.csd-summary-badge--upload md-icon { color: var(--csd-red) !important; }

.csd-heartbeat {
  display: flex !important; flex-direction: column !important; align-items: flex-end !important; gap: 2px !important;
  background: var(--csd-surface) !important; border: 1px solid var(--csd-border) !important;
  border-radius: var(--csd-r-md) !important; padding: 6px 14px !important; text-align: right !important;
}
.csd-heartbeat-label { font-size: 10px !important; font-weight: 700 !important; color: var(--csd-text-muted) !important; text-transform: uppercase !important; letter-spacing: .5px !important; }
.csd-heartbeat-value { font-size: 15px !important; font-weight: 800 !important; color: var(--csd-indigo-600) !important; white-space: nowrap !important; }

/* ── Status card (per-environment interceptor/live status) ───── */

.csd-status-card {
  /* Fixed footprint (not content-hugging) so every card in the row reads as
     one consistent size regardless of label/value length — the previous
     auto-width layout made "Interceptor Connection Status" balloon out
     while "Uptime" stayed tiny, so the row looked mismatched. */
  display: flex !important; flex-direction: column !important; align-items: flex-start !important;
  justify-content: center !important; gap: 4px !important;
  width: 148px !important; flex: 0 0 148px !important; box-sizing: border-box !important;
  min-height: 60px !important;
  background: var(--csd-surface) !important; border: 1px solid var(--csd-border) !important;
  border-radius: var(--csd-r-md) !important; padding: 6px 10px !important;
}
/* Pressure/Agent Latency Alert cards' timestamp — a second, smaller line
   under the badge ("since Aug 25, 1:15 PM") instead of stuffing the
   timestamp into the badge itself, which needed a much wider card and
   broke the row's otherwise-uniform width (every other card is a plain
   190px box with a short one-word badge). The card can still grow a
   little taller than its neighbors while an alert is active — same
   min-height-not-fixed-height trade every card here already makes — but
   width now stays identical across all of them. */
.csd-status-card-subvalue {
  font-size: 10px !important; font-weight: 600 !important; color: var(--csd-text-muted) !important;
  white-space: nowrap !important; line-height: 1.2 !important;
}
.csd-status-card-label {
  font-size: 10px !important; font-weight: 700 !important; color: var(--csd-text-muted) !important;
  text-transform: uppercase !important; letter-spacing: .5px !important;
  white-space: normal !important; line-height: 1.25 !important;
}
.csd-status-card-value {
  display: flex !important; align-items: center !important; flex-wrap: wrap !important; gap: 5px !important;
  font-size: 15px !important; font-weight: 800 !important; color: var(--csd-indigo-600) !important;
  white-space: nowrap !important; line-height: 1.2 !important;
}
.csd-status-card-value--agent {
  color: var(--csd-text-primary) !important; font-size: 12.5px !important; font-weight: 700 !important;
  white-space: normal !important;
}
/* Agent's own name + environment (e.g. "COMAFI (Development)") plus its
   reachability badge routinely run longer than the other cards' short
   one-word/short-number values — the shared 148px width (see
   .csd-status-card's own comment on why every OTHER card stays fixed and
   uniform) wrapped it to 2 lines even with room to spare in the row.
   Widened just this one card instead of the whole row, since the others
   never need it. */
.csd-status-card--agent {
  width: 240px !important; flex: 0 0 240px !important;
}
.csd-status-card-icon {
  font-size: 16px !important; width: 16px !important; height: 16px !important; min-width: 16px !important;
  margin: 0 !important; color: var(--csd-indigo-500) !important;
}

/* ── Section title ────────────────────────────────────────── */

.csd-section-title {
  font-size: 11px !important; font-weight: 700 !important; color: var(--csd-indigo-500) !important;
  text-transform: uppercase !important; letter-spacing: .6px !important; margin: 0 0 10px !important;
}

/* Section title with a trailing action (Lifetime Totals' "Reset All") —
   .csd-section-title keeps its own margin-bottom unchanged, this row just
   aligns it against the button on the same line. */
.csd-section-title-row {
  display: flex !important; align-items: center !important; justify-content: space-between !important;
  gap: 12px !important;
}
.csd-section-title-row .csd-section-title { margin: 0 !important; }

.csd-reset-btn {
  display: inline-flex !important; align-items: center !important; gap: 6px !important;
  height: 28px !important; padding: 0 12px !important; margin: 0 0 10px !important;
  border-radius: var(--csd-r-md) !important; border: 1px solid var(--csd-border) !important;
  background: var(--csd-surface) !important; color: var(--csd-text-secondary) !important;
  font-size: 12px !important; font-weight: 600 !important; text-transform: none !important;
  transition: var(--csd-t) !important;
}
.csd-reset-btn md-icon {
  font-size: 15px !important; width: 15px !important; height: 15px !important;
  min-width: 15px !important; min-height: 15px !important; margin: 0 !important;
  color: var(--csd-text-secondary) !important;
}
.csd-reset-btn:hover {
  background: #FFF1F0 !important; border-color: #F5C2C0 !important; color: #C0392B !important;
}
.csd-reset-btn:hover md-icon { color: #C0392B !important; }

/* ── Per-environment status list ─────────────────────────── */

.csd-env-list { background: var(--csd-surface) !important; border: 1px solid var(--csd-border) !important; border-radius: var(--csd-r-md) !important; overflow: hidden !important; margin-bottom: 22px !important; }

.csd-env-list-header, .csd-env-row {
  display: grid !important;
  /* Status merged from two columns (Status + Live) into one 4-state badge,
     wide enough to fit "Unreachable" without wrapping. Alerts (2-4 small
     icon badges, no text pill — see .csd-alert-badge--none) sits right
     after Status, both being "current state" reads at a glance. Instances
     (RUNNING count) sits right after Sync Count — both short integers.
     Avg Ping/Avg Pressure/Hogging Rate share one width — all three are
     short "NN%"/"NN ms" gauge readouts, Pressure and Hogging Rate also
     using the stacked value-over-compact-bar layout (.csd-env-col-pressure,
     shared between them). Upload Responsiveness gets extra width beyond
     that shared size — its header text ("UPLOAD RESPONSIVENESS") is long
     enough at 9.5px/uppercase that the others' width isn't enough for
     "RESPONSIVENESS" to wrap onto its own line without spilling past the
     column; see the header-cell overflow-wrap rule below for the safety
     net if a label ever gets longer than any given width can absorb.
     Hogging Rate/Upload Responsiveness themselves replaced the older
     per-environment frame-rate/byte-rate columns (Avg Frame Rcv/Upl Rate,
     Avg Frame Filt/Drop Rate, Avg Size Rcv/Upl Rate) once they existed as
     the actual load indicators those raw rates existed to let someone
     eyeball — 3 columns replaced by 2, and narrower ones at that, which
     is what opened up the leftover width every column below was widened
     to use (see the dialog's own width comment above this rule's own
     history of shrinking to compensate).

     Environment is fixed (not 1fr/minmax) — env names are short (DEV01,
     IST), so letting it flex the same as Agent would give it an equal,
     mostly-empty share of the row's leftover width instead of leaving
     that room for Agent, which actually needs it (name + reachability
     badge varies the most of anything in this row). Agent's own minmax(0,
     ...) cap keeps it from unboundedly re-ballooning to eat 100% of the
     leftover row width on a wide dialog on its own — every other column
     below gets its own explicit share of that leftover width instead, so
     it doesn't all funnel into just Agent or sit unused as a right-edge
     gutter. */
  grid-template-columns: 115px 118px 58px 85px 100px 68px 68px 55px 70px 72px 72px 110px minmax(0, 260px) !important;
  gap: 8px !important;
  padding: 0 14px !important;
  align-items: center !important;
}

.csd-env-list-header {
  height: 34px !important;
  background: linear-gradient(135deg,#f8f9ff,#f0f4ff) !important;
  border-bottom: 2px solid #e8ecff !important;
}
.csd-env-list-header > div { font-size: 9.5px !important; font-weight: 700 !important; color: var(--csd-indigo-500) !important; text-transform: uppercase !important; letter-spacing: .4px !important; line-height: 1.2 !important; overflow-wrap: break-word !important; }

.csd-env-row {
  min-height: 42px !important;
  border-bottom: 1px solid #f0f0f0 !important;
  cursor: pointer !important;
}
.csd-env-row:last-child { border-bottom: none !important; }
.csd-env-row:hover { background: #fafbff !important; }

.csd-env-col-name {
  font-size: 11.5px !important; font-weight: 700 !important; color: var(--csd-text-primary) !important;
  overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important;
}
.csd-env-col-uptime { font-size: 10.5px !important; font-weight: 700 !important; color: var(--csd-text-secondary) !important; white-space: nowrap !important; }
.csd-env-col-heartbeat { font-size: 10.5px !important; color: var(--csd-text-secondary) !important; white-space: nowrap !important; }
/* text-align: right to match .csd-env-col-num — left-aligned here (default)
   while every numeric column to its right is right-aligned made the gap
   before CAPTURED look much wider than the gaps between the other
   right-aligned numeric columns. */
.csd-env-col-sync { font-size: 11.5px !important; font-weight: 700 !important; color: var(--csd-text-primary) !important; text-align: right !important; }
.csd-env-col-num { font-size: 11px !important; font-weight: 700 !important; color: var(--csd-text-secondary) !important; text-align: right !important; }
/* min-width: 0 lets this CSS Grid item shrink below its content's intrinsic
   (nowrap) width — without it, a long agent name + badge forces the whole
   `1fr` grid track wider than its fair share, pushing the row past the
   dialog's right edge instead of ellipsizing. */
.csd-env-col-agent { font-size: 11.5px !important; color: var(--csd-text-secondary) !important; display: flex !important; align-items: center !important; min-width: 0 !important; overflow: hidden !important; }
.csd-src-empty { color: var(--csd-text-muted) !important; }

.csd-agent-name-wrap { display: flex !important; align-items: center !important; gap: 6px !important; min-width: 0 !important; overflow: hidden !important; }
.csd-agent-name-text { overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important; min-width: 0 !important; }

.csd-agent-reachable {
  font-size: 9px !important; font-weight: 800 !important; letter-spacing: .3px !important; text-transform: uppercase !important;
  padding: 1px 6px !important; border-radius: 10px !important;
  flex-shrink: 0 !important;
}
.csd-agent-reachable--yes { background: var(--csd-green-bg) !important; color: var(--csd-green) !important; }
.csd-agent-reachable--no  { background: var(--csd-red-bg) !important; color: var(--csd-red) !important; }
/* Clickable when unreachable — opens the full error/stack-trace dialog (see vm.showAgentConnectionError). Not clickable when OK, so no pointer cursor there. */
.csd-agent-reachable--clickable { cursor: pointer !important; }
.csd-agent-reachable--clickable:hover { text-decoration: underline !important; }

/* ── Status badges (reused for interceptor_status + live_status) ─── */

.csd-status-badge {
  display: inline-flex !important; align-items: center !important; gap: 5px !important;
  font-size: 10.5px !important; font-weight: 700 !important; letter-spacing: .3px !important;
  padding: 3px 9px !important; border-radius: 16px !important; border: 1px solid transparent !important;
  white-space: nowrap !important;
}
.csd-status-dot { display: inline-block !important; width: 7px !important; height: 7px !important; border-radius: 50% !important; }

.csd-status-badge--online  { background: var(--csd-green-bg) !important; color: var(--csd-green) !important; border-color: rgba(22,163,74,.3) !important; }
.csd-status-badge--online .csd-status-dot  { background: var(--csd-green) !important; }
.csd-status-badge--offline { background: var(--csd-red-bg) !important; color: var(--csd-red) !important; border-color: rgba(220,38,38,.3) !important; }
.csd-status-badge--offline .csd-status-dot { background: var(--csd-red) !important; }
.csd-status-badge--standby { background: var(--csd-yellow-bg) !important; color: var(--csd-yellow) !important; border-color: rgba(217,119,6,.3) !important; }
.csd-status-badge--standby .csd-status-dot { background: var(--csd-yellow) !important; }
.csd-status-badge--agent-unreachable { background: var(--csd-gray-dark-bg) !important; color: var(--csd-gray-dark) !important; border-color: rgba(75,85,99,.3) !important; }
.csd-status-badge--agent-unreachable .csd-status-dot { background: var(--csd-gray-dark) !important; }
.csd-status-badge--restart .csd-status-dot { background: var(--csd-indigo-600) !important; }

.csd-status-badge--live     { background: var(--csd-green-bg) !important; color: var(--csd-green) !important; border-color: rgba(22,163,74,.3) !important; }
.csd-status-badge--not-live { background: var(--csd-surface-2) !important; color: var(--csd-text-muted) !important; border-color: var(--csd-border-strong) !important; }

/* ── SLA alert badges — individual-environment tab's Pressure/Agent
   Latency Alert cards. Only rendered at all while actually SET (see the
   template's ng-if) — an "OK" card for every interceptor's every
   environment, almost always inactive, would be noise most of the time,
   so no --ok variant here to begin with. */
.csd-status-badge--alert { background: var(--csd-red-bg) !important; color: var(--csd-red) !important; border-color: rgba(220,38,38,.3) !important; }
.csd-status-badge--alert md-icon { color: var(--csd-red) !important; }
/* Not an SLA breach — a config the running process can't pick up on its
   own — so it deliberately uses the brand indigo instead of red/yellow to
   read as "action needed", not "something's wrong". */
.csd-status-badge--restart { background: rgba(71,86,232,.08) !important; color: var(--csd-indigo-600) !important; border-color: rgba(71,86,232,.3) !important; }
.csd-status-badge--restart md-icon { color: var(--csd-indigo-600) !important; }
/* Same red as the pressure/latency SLA badges above — an interceptor
   unable to upload captured frames is a live problem, same severity class. */
.csd-status-badge--upload { background: var(--csd-red-bg) !important; color: var(--csd-red) !important; border-color: rgba(220,38,38,.3) !important; }
.csd-status-badge--upload md-icon { color: var(--csd-red) !important; }
.csd-status-badge md-icon {
  font-size: 13px !important; width: 13px !important; height: 13px !important; min-width: 13px !important; min-height: 13px !important;
  margin: 0 !important;
}

/* ── General tab's per-environment Alerts column — compact icon badges,
   one per active SLA breach (pressure/agent latency), hidden entirely
   when neither is active. Differentiated by icon (compress vs speed,
   same icons Metrics Explorer uses for these two metrics) and by color,
   per metric — hover for which metric and since when (see the
   md-tooltip in the template). ── */
.csd-env-col-alerts {
  display: flex !important; align-items: center !important; gap: 4px !important;
}
.csd-alert-badge {
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  width: 22px !important; height: 22px !important; border-radius: 50% !important;
  cursor: default !important;
}
/* Angular Material's $mdPanel-based tooltip renders <md-tooltip> itself
   (there's no .md-content child in this version — confirmed live via
   getComputedStyle, an earlier attempt at this fix targeted a selector
   that never matched anything) DETACHED from its trigger, appended into
   its own .md-panel-inner-wrapper — so it can't be scoped through a
   .csd-alert-badge/.csd-status-badge ANCESTOR selector either; it simply
   isn't a descendant of the badge in the live DOM. Material's own default
   sizes the bubble for a single line (fixed height + overflow:hidden) and
   silently clips anything longer, like the restart_required reason (a
   full sentence, sometimes two) — height:auto here lets it grow, and
   white-space:pre-line preserves the explicit "\n" the controllers build
   between the lead sentence and the specific reason (see e.g.
   ConsolidatedStatsDialogController#instanceStatusTooltip) as a real line
   break while still wrapping long lines normally.

   Deliberately targets the BARE element, not `.md-show` — Material
   measures the tooltip's size to compute its top/left position BEFORE
   adding `.md-show` (that class only drives the fade-in), so a rule
   scoped to `.md-show` takes effect only AFTER Material already
   positioned the (still single-line-sized, per ITS OWN default CSS) box —
   the taller wrapped content then renders overlapping the trigger instead
   of clearing it, because the position was computed for a much smaller
   box. Applying this unconditionally means the taller size is already
   real by the time Material measures and positions it. */
md-tooltip {
  height: auto !important;
  max-width: 300px !important;
  white-space: pre-line !important;
  overflow: visible !important;
  /* Material's own default (~10px) is what made the tile tooltips added
     for Consolidated Stats' tiles (see <bm-stat-tile>, common/components/
     stat-tile) hard to read — bumped along with padding/line-height to match. */
  font-size: 13px !important;
  line-height: 1.45 !important;
  padding: 10px 12px !important;
  text-align: left !important;
  /* Material sets pointer-events:all on this element inline (unusual for
     a tooltip) — with a taller box (from the overrides above) that lets
     the bubble visually cover its own tiny (22px) trigger badge and
     intercept the hover itself, firing a mouseleave on the badge the
     instant it renders and hiding it again immediately (a one-frame
     flicker). Tooltips should never be interactive anyway. */
  pointer-events: none !important;
}
.csd-alert-badge md-icon {
  font-size: 14px !important; width: 14px !important; height: 14px !important; min-width: 14px !important; min-height: 14px !important;
  margin: 0 !important;
}
.csd-alert-badge--pressure { background: var(--csd-red-bg) !important; }
.csd-alert-badge--pressure md-icon { color: var(--csd-red) !important; }
.csd-alert-badge--latency { background: var(--csd-yellow-bg) !important; }
.csd-alert-badge--latency md-icon { color: var(--csd-yellow) !important; }
.csd-alert-badge--restart { background: rgba(71,86,232,.08) !important; }
.csd-alert-badge--restart md-icon { color: var(--csd-indigo-600) !important; }
.csd-alert-badge--upload { background: var(--csd-red-bg) !important; }
.csd-alert-badge--upload md-icon { color: var(--csd-red) !important; }
.csd-alert-badge--none { background: var(--csd-surface-2) !important; }
.csd-alert-badge--none md-icon { color: var(--csd-text-muted) !important; }

/* ── General stat tiles + distribution pie, side by side ───── */

.csd-stats-side-by-side {
  display: flex !important; align-items: flex-start !important; gap: 20px !important;
  margin-bottom: 22px !important;
}
.csd-tiles-col { flex: 1 1 auto !important; min-width: 0 !important; }
.csd-pie-col {
  flex: 0 0 300px !important; width: 300px !important;
  background: var(--csd-surface) !important; border: 1px solid var(--csd-border) !important;
  border-radius: var(--csd-r-md) !important; padding: 10px 14px !important; box-sizing: border-box !important;
}

/* ── Second chart stacked below the pie, inside the same card — see
   capture-upload-bar in the template, right under packet-distribution-pie. ── */
.csd-pie-col-divider {
  height: 1px !important; background: var(--csd-border) !important; margin: 4px 0 12px !important;
}
.csd-pie-col-subtitle {
  font-size: 11px !important; font-weight: 700 !important; color: var(--csd-indigo-500) !important;
  text-transform: uppercase !important; letter-spacing: .6px !important; margin: 0 0 6px !important;
}

/* Tile grid/shell + trend arrow now live in the shared <bm-stat-tile>
   component (common/components/stat-tile) — see consolidated-stats-dialog.html.
   .csd-pressure-bar-track/-fill below stay: still used standalone by the
   per-environment table and Runtime Instances rows (not just the tiles). */

/* ── Pressure indicator bar — same track/fill/gradient shape as the
   Agents tab's mini-metric CPU/memory bars (agents-tab.css
   .mini-metric-bar-container/.mini-metric-bar/.cpu-bar), reproduced here
   scoped to this dialog rather than depending on agents-tab.css being
   loaded. A 0-100 range indicator, not a "how much of a task is done"
   progress bar — load_pressure is a gauge (current buffer occupancy),
   not a completion percentage. */
.csd-pressure-bar-track {
  height: 5px !important; background: var(--csd-surface-2) !important; border-radius: 3px !important;
  overflow: hidden !important; margin-top: 3px !important; width: 100% !important;
}
.csd-pressure-bar-fill {
  height: 100% !important; border-radius: 3px !important; min-width: 2px !important;
  transition: width .4s ease, background .4s ease !important;
  /* NOT !important — the real color comes from the `background` set
     inline via ng-style (the pressureColor filter, common/filters.js),
     green-to-red by value. This is only the pre-JS/no-data fallback. */
  background: linear-gradient(90deg, #2196f3 0%, #1976d2 100%);
}

/* ── Same bar, compact — the per-environment table's "Avg Pressure",
   "Hogging Rate" and "Upload Responsiveness" columns (65px each), value
   stacked above a narrower track instead of the tile's full-width one. ── */
.csd-env-col-pressure {
  display: flex !important; flex-direction: column !important; align-items: flex-end !important;
  gap: 3px !important;
}
.csd-pressure-bar-track--compact { width: 48px !important; }

/* ── Empty state ──────────────────────────────────────────── */

.csd-empty-wrapper {
  display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: center !important;
  gap: 12px !important; padding: 40px 24px !important; text-align: center !important;
  color: var(--csd-text-secondary) !important; font-size: 13px !important;
  background: var(--csd-surface) !important; border: 1px solid var(--csd-border) !important; border-radius: var(--csd-r-md) !important;
}
.csd-empty-icon { font-size: 40px !important; width: 40px !important; height: 40px !important; color: var(--csd-text-muted) !important; }
.csd-empty-title { font-size: 14px !important; font-weight: 700 !important; color: var(--csd-text-primary) !important; }
.csd-empty-text { max-width: 380px !important; line-height: 1.5 !important; }

/* ── Operations list ──────────────────────────────────────── */

/* width: 100% (not left to block-auto-sizing) + overflow-x: auto — a
   guaranteed fallback for whatever the dialog's own width (see .csd-dialog
   above) still doesn't fit at a given viewport size, so nothing gets
   clipped with no way to reach it. Vertical scrolling for the whole tab is
   already handled one level up by .csd-tab-panel, so overflow-y stays
   hidden here — nothing is actually clipped vertically by it. */
.csd-list {
  background: var(--csd-surface) !important; border: 1px solid var(--csd-border) !important;
  border-radius: var(--csd-r-md) !important; overflow-x: auto !important; overflow-y: hidden !important;
  width: 100% !important; box-sizing: border-box !important;
}

.csd-list-header, .csd-row {
  display: grid !important;
  /* All fixed px, deliberately — no fr/minmax() here. A `minmax(x, 1fr)`
     track can end up wider than x when there's slack, or interact
     unpredictably with wrapping flex/grid-item content (the Endpoint
     column's badge+path, the Collection/Operation columns' wrapped text)
     to claim more room than intended — fixed tracks make the row's total
     width fully deterministic, so whether it fits or needs .csd-list's
     overflow-x above is predictable instead of content-dependent. */
  grid-template-columns: 32px 230px 170px 190px 100px 75px 75px 75px 75px 90px 90px !important;
  gap: 10px !important;
  padding: 0 16px !important;
  align-items: center !important;
  /* A block box's width:auto always equals its containing block's width —
     it does NOT grow to fit content, even a grid's own explicit fixed-px
     tracks. Since those tracks (+ gaps + padding) actually need more room
     than .csd-list's available width, they were overflowing the header's/
     row's own box silently (overflow is visible, not clipped): the last
     column or two rendered fine (children aren't clipped by their parent),
     but the header's gradient and each row's own hover-tinted background
     — painted on the box itself — stopped at the box's official (too
     narrow) edge, leaving .csd-list's plain white background exposed
     under whatever trailed past it. width: max-content makes the box
     actually size to its content (the tracks), so the background always
     covers exactly what's rendered; min-width: 100% is the floor for when
     content is narrower than .csd-list, so nothing changes there. */
  width: max-content !important;
  min-width: 100% !important;
}
/* Rows (not the header, which is always one line) top-align their cells —
   Endpoint/Collection/Operation now wrap onto multiple lines instead of
   ellipsis-truncating (see below), so cells in the same row can end up
   different heights; centering each independently looked misaligned once
   that started happening. */
.csd-row { align-items: start !important; padding-top: 8px !important; padding-bottom: 8px !important; }

.csd-list-header {
  height: 38px !important;
  background: linear-gradient(135deg,#f8f9ff,#f0f4ff) !important;
  border-bottom: 2px solid #e8ecff !important;
}
.csd-list-header > div { font-size: 10.5px !important; font-weight: 700 !important; color: var(--csd-indigo-500) !important; text-transform: uppercase !important; letter-spacing: .6px !important; }

/* ── Sortable operation columns ───────────────────────────── */

.csd-col-sortable {
  display: flex !important; align-items: center !important; gap: 3px !important;
  cursor: pointer !important; user-select: none !important;
  transition: color var(--csd-t) !important;
}
.csd-list-header .csd-col-sortable:hover { color: var(--csd-indigo-600) !important; }
.csd-list-header .csd-col-num.csd-col-sortable { justify-content: flex-end !important; }
.csd-sort-icon {
  font-size: 13px !important; width: 13px !important; height: 13px !important; min-width: 13px !important;
  margin: 0 !important; color: var(--csd-indigo-600) !important;
}

.csd-row {
  min-height: 44px !important;
  border-bottom: 1px solid #f0f0f0 !important;
  transition: background var(--csd-t) !important;
}
.csd-row:last-child { border-bottom: none !important; }
.csd-row:hover { background: #fafbff !important; }

/* No longer sourced by any live Biz Event — the row still shows its full
   last-known identity (method/path/collection/version/direction, now sticky
   on the backend, see InterceptorOperationStats#type), just visually
   de-emphasized as a whole rather than blanking individual cells. */
.csd-row--inactive { opacity: .5 !important; }
.csd-row--inactive:hover { background: #fafbff !important; opacity: .75 !important; }

.csd-col-collection, .csd-col-operation {
  font-size: 12.5px !important; font-weight: 600 !important; color: var(--csd-text-primary) !important;
  /* Always fully visible — no ellipsis/hover needed to read a name. */
  white-space: normal !important; overflow-wrap: break-word !important; word-break: break-word !important;
  /* Grid items default to min-width: auto — their content's intrinsic
     minimum, which for unbroken text can still exceed the grid's own
     fixed-px track and force the row wider than intended even with
     wrapping enabled above. min-width: 0 makes the fixed track win. */
  min-width: 0 !important;
}

.csd-col-num { font-size: 12.5px !important; font-weight: 700 !important; color: var(--csd-text-secondary) !important; text-align: right !important; }
.csd-col-num--warn { color: var(--csd-red) !important; }

/* ── Live indicator — same green/gray semantics as the interceptor list's
   own online/offline dot, but per operation rather than per interceptor:
   whether a live Biz Event currently sources it (folded in from what used
   to be the separate Live Endpoints dialog). ── */
.csd-col-live { display: flex !important; justify-content: center !important; }
.csd-live-dot {
  display: inline-block !important; width: 9px !important; height: 9px !important;
  border-radius: 50% !important;
}
.csd-live-dot--live     { background: var(--csd-green) !important; box-shadow: 0 0 0 3px var(--csd-green-bg) !important; }
.csd-live-dot--inactive { background: var(--csd-gray-dark) !important; opacity: .5 !important; }

/* ── Endpoint (method badge + path, together — not two separate
   columns) + collection version pill ──────────────────────── */
.csd-col-endpoint {
  display: flex !important; align-items: flex-start !important; gap: 6px !important;
  flex-wrap: wrap !important;
  min-width: 0 !important; /* same reasoning as .csd-col-collection/.csd-col-operation above */
}
.csd-endpoint-path {
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace !important;
  font-size: 11px !important; font-weight: 600 !important; color: var(--csd-text-secondary) !important;
  /* Always fully visible — no ellipsis/hover needed to read the path. */
  white-space: normal !important; overflow-wrap: break-word !important; word-break: break-word !important;
  padding-top: 2px !important; /* optically aligns the path's first line with the method badge's text */
  /* A flex item's own default min-width is auto (its content's intrinsic
     minimum), which for a slash-free-of-spaces path can still be wider
     than the column — 0 lets word-break above actually take effect
     instead of being overridden by that default. */
  min-width: 0 !important;
}
.csd-method-badge {
  display: inline-block !important; flex: 0 0 auto !important; font-size: 10px !important; font-weight: 800 !important;
  letter-spacing: .3px !important; padding: 2px 7px !important; border-radius: 5px !important;
  border: 1px solid transparent !important;
}
.csd-method-badge--get    { background: rgba(66,153,225,.10) !important; color: #2b6cb0 !important; border-color: rgba(66,153,225,.35) !important; }
.csd-method-badge--post   { background: rgba(56,161,105,.10) !important; color: #276749 !important; border-color: rgba(56,161,105,.35) !important; }
.csd-method-badge--put    { background: rgba(217,119,6,.10) !important; color: #b45309 !important; border-color: rgba(217,119,6,.35) !important; }
.csd-method-badge--patch  { background: rgba(217,119,6,.10) !important; color: #b45309 !important; border-color: rgba(217,119,6,.35) !important; }
.csd-method-badge--delete { background: rgba(220,38,38,.10) !important; color: var(--csd-red) !important; border-color: rgba(220,38,38,.35) !important; }

.csd-version-pill {
  display: inline-block !important; margin-left: 6px !important; font-size: 10px !important; font-weight: 700 !important;
  color: var(--csd-text-muted) !important; background: var(--csd-surface-2) !important;
  border: 1px solid var(--csd-border-strong) !important; border-radius: 999px !important; padding: 1px 6px !important;
}

/* ── Runtime Instances list — own column layout, same list chrome
   (.csd-list/.csd-list-header/.csd-row) as Operations above. All fixed
   px, deliberately — same reasoning as .csd-list-header/.csd-row's own
   grid-template-columns comment: fixed tracks keep the row's total width
   fully deterministic instead of content-dependent. ── */
.csd-ri-row {
  /* Uptime sits right after Status — same position/reasoning as the
     environment-level table's own Status → Uptime adjacency. Last Sync
     sits right after Uptime — both are "how fresh/how long" glance
     columns, kept adjacent rather than pushed to the far end of the row. */
  /* PID and Cores dropped entirely (anecdotal, not worth the width) to
     free up room for the columns that actually need it (Hostname/OS/IP)
     without the row overflowing into a horizontal scroll. */
  /* Status widened from 100px to fit the "Requires Restart" pill on one
     line (nowrap, per .csd-status-badge) without overlapping Uptime —
     taken from Hostname (already wraps to 2 lines for long pod names, so
     losing 40px just means a little more of that) and Environment (its
     values — DEV01/IST — never come close to needing 90px). */
  /* Max Mem and SDK CPU dropped entirely — the table was running long and
     neither pulled its weight next to SDK Buffer/Avg Pressure, which are
     the two that actually signal a struggling instance.
     Avg Pressure sits right after Status/Uptime (3rd column) — early
     enough to scan at a glance, right alongside the other two "is this
     instance okay" columns — same stacked value-over-compact-bar layout
     as the Environments table's own Avg Pressure/Hogging Rate columns
     (.csd-env-col-pressure, reused here), just a wider bar (see
     .csd-ri-pressure-bar-track below) since this row has the room.
     Environment only renders at all when viewing "All environments" (see
     the template's own ng-if) — pointless repeating the same value down
     every row once you're already scoped to one environment's own tab —
     so this is the WITH-Environment layout; .csd-ri-row--no-env below is
     the narrower one used instead once that column is gone. */
  grid-template-columns: 140px 85px 95px 105px 110px 160px 120px 140px 85px 95px !important;
}
/* Single-environment tabs — one fewer column (no Environment), so every
   other column gets a little more room than the "All environments" layout
   above instead of leaving that freed width as dead space. */
.csd-ri-row.csd-ri-row--no-env {
  grid-template-columns: 140px 85px 95px 105px 175px 130px 150px 90px 100px !important;
}
/* Wider than .csd-pressure-bar-track--compact (48px, used by the
   Environments table's own Avg Pressure/Hogging Rate) — this row has
   more spare width to give it, and it's the column readers scan first. */
.csd-ri-pressure-bar-track { width: 64px !important; }
.csd-ri-col-status, .csd-ri-col-env, .csd-ri-col-host, .csd-ri-col-ip, .csd-ri-col-os, .csd-ri-col-runtime, .csd-ri-col-sync {
  font-size: 12.5px !important; font-weight: 600 !important; color: var(--csd-text-primary) !important;
  /* Always fully visible — no ellipsis/hover needed to read a value. */
  white-space: normal !important; overflow-wrap: break-word !important; word-break: break-word !important;
  min-width: 0 !important;
}
.csd-ri-col-sync { font-weight: 500 !important; color: var(--csd-text-secondary) !important; }
.csd-ri-col-uptime { font-size: 10.5px !important; font-weight: 700 !important; color: var(--csd-text-secondary) !important; white-space: nowrap !important; }

/* .csd-status-badge is white-space:nowrap by default (fine for the short
   Online/Offline/Standby labels it usually shows), but "Requires Restart"
   in this specific column can render wider than the Status track (160px)
   and visually escape it — surfacing as a stray fragment of the label
   still painted after scrolling the table horizontally, since nothing
   was clipping it to begin with. Let it wrap here instead of relying on
   ever-more column width to outrun a label's own text length, and clip it
   to the cell as a hard backstop either way. */
.csd-ri-col-status .csd-status-badge {
  white-space: normal !important;
  max-width: 100% !important;
  overflow: hidden !important;
}

/* ── Direction badge (INBOUND / OUTBOUND / INBOUND_OUTBOUND) ─── */

.csd-direction-badge {
  display: inline-flex !important; align-items: center !important; gap: 3px !important;
  font-size: 9.5px !important; font-weight: 800 !important; letter-spacing: .2px !important;
  padding: 2px 6px !important; border-radius: 999px !important; white-space: nowrap !important;
  border: 1px solid transparent !important; line-height: 1.4 !important;
}
.csd-direction-badge md-icon {
  margin: 0 !important; font-size: 11px !important; width: 11px !important; height: 11px !important;
  display: flex !important; align-items: center !important; justify-content: center !important;
  line-height: 11px !important;
}
.csd-direction-badge--inbound  { background: rgba(56,161,105,.10) !important; color: #276749 !important; border-color: rgba(56,161,105,.35) !important; }
.csd-direction-badge--outbound { background: rgba(159,122,234,.12) !important; color: #6b46c1 !important; border-color: rgba(159,122,234,.35) !important; }
.csd-direction-badge--inbound_outbound { background: rgba(66,153,225,.10) !important; color: #2b6cb0 !important; border-color: rgba(66,153,225,.35) !important; }
.csd-direction-badge--unknown  { background: rgba(142,151,180,.10) !important; color: var(--csd-text-muted) !important; border-color: rgba(142,151,180,.30) !important; }

/* ── Footer ───────────────────────────────────────────────── */

.csd-actions {
  background: var(--csd-surface) !important;
  border-top: 1px solid var(--csd-border) !important;
  padding: 14px 24px !important;
  flex-shrink: 0 !important;
  display: flex !important;
}

.csd-btn-close {
  display: inline-flex !important; align-items: center !important;
  padding: 0 22px !important; height: 40px !important; border-radius: var(--csd-r-md) !important;
  font-size: 13.5px !important; font-weight: 500 !important; text-transform: none !important;
  background: var(--csd-surface) !important; color: var(--csd-text-secondary) !important;
  border: 1.5px solid var(--csd-border-strong) !important; margin: 0 !important;
}
.csd-btn-close:hover { background: var(--csd-surface-2) !important; }

/* Discovery history is distinct from inactive catalog operations. */
.csd-row.csd-row--discovered { background: #fff8e6; border-left: 3px solid #b76e00; }
.csd-discovery-badge { display: inline-block; flex-shrink: 0; padding: 2px 6px; border-radius: 4px;
  color: #764600; background: #ffebba; font-size: 10px; font-weight: 700; white-space: nowrap; }

.csd-discovery-badge--known {
  padding: 3px 8px;
  border-radius: 999px;
  color: var(--csd-gray-dark);
  background: var(--csd-gray-dark-bg);
}

.csd-discovery-badge--live {
  padding: 3px 8px;
  border-radius: 999px;
  color: var(--csd-green);
  background: var(--csd-green-bg);
}

.csd-discovery-list .csd-list-header, .csd-discovery-list .csd-row {
  grid-template-columns: 72px 520px 150px 120px 130px 95px 70px 85px !important;
  gap: 8px !important;
}
.csd-discovery-list .csd-col-endpoint {
  flex-direction: column !important;
  flex-wrap: nowrap !important;
  gap: 5px !important;
}
.csd-discovery-list .csd-endpoint-path {
  line-height: 1.5 !important;
  font-weight: 500 !important;
}
.csd-discovery-list .csd-col-collection,
.csd-discovery-list .csd-col-operation {
  font-size: 11px !important;
  font-weight: 500 !important;
  line-height: 1.5 !important;
}
.csd-discovery-list .csd-method-badge--options {
  background: var(--csd-surface-2) !important;
  color: var(--csd-text-secondary) !important;
  border-color: var(--csd-border-strong) !important;
}
.csd-row.csd-row--discovered, .csd-row.csd-row--discovered:hover {
  background: #fff8e6 !important;
  box-shadow: inset 3px 0 #b76e00;
}
.csd-discovery-hint { color: var(--csd-text-secondary); font-size: 12px; }

/* Discovery tab search */
.csd-discovery-search {
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 420px;
    margin: 4px 0 12px;
    padding: 6px 12px;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    background: #fff;
}
.csd-discovery-search:focus-within { border-color: #5b5bd6; box-shadow: 0 0 0 3px rgba(91, 91, 214, 0.12); }
.csd-discovery-search md-icon { color: #94a3b8; font-size: 20px; width: 20px; height: 20px; min-width: 20px; min-height: 20px; margin: 0; }
.csd-discovery-search input { flex: 1; border: 0; outline: 0; font-size: 13px; background: transparent; color: inherit; }
.csd-discovery-search .csd-discovery-search-clear { cursor: pointer; }
