:root {
  color-scheme: light;
  /* Command Deck — Light (contraparte del NOC) */
  --ink: #14202e;
  --muted: #5a6b7f;
  --line: #d7e0ea;
  --panel: #ffffff;
  --canvas: #eef2f7;
  --nav: #0a1120;
  --nav-soft: #16202f;
  --blue: #1583c4;
  --teal: #0e7490;
  --green: #17915a;
  --amber: #a86a00;
  --red: #cf3b46;
  --violet: #6d28d9;
  --shadow: 0 18px 42px rgba(20, 31, 43, 0.12);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: Inter, Segoe UI, Arial, sans-serif;
  color: var(--ink);
  background: var(--canvas);
}

button,
input,
select {
  font: inherit;
}

.app-shell {
  display: grid;
  grid-template-columns: 272px minmax(0, 1fr);
  min-height: 100vh;
}

[hidden] {
  display: none !important;
}

.auth-gate {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 24px;
  background: radial-gradient(1200px 600px at 50% -10%, #1a2633, var(--nav));
}

.auth-card {
  display: grid;
  gap: 14px;
  width: min(380px, 100%);
  padding: 28px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  box-shadow: var(--shadow);
}

.auth-brand {
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}

.auth-brand span {
  color: var(--muted);
}

.auth-card h1 {
  font-size: 22px;
}

.auth-sub {
  margin: -8px 0 4px;
  color: var(--muted);
  font-size: 14px;
}

.auth-field {
  display: grid;
  gap: 6px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

.auth-field input {
  height: 42px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
}

.auth-card .primary-action {
  margin-top: 4px;
  width: 100%;
}

.auth-error {
  min-height: 18px;
  margin: 0;
  color: var(--red);
  font-size: 13px;
  font-weight: 700;
}

.session-chip {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 42px;
  padding: 0 6px 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  color: var(--ink);
  font-size: 13px;
  font-weight: 700;
}

.sidebar {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 24px 18px;
  color: #e8eef5;
  background: var(--nav);
  /* Keep the nav fixed in the viewport while only the content scrolls. */
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 4px 8px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.brand strong {
  display: block;
  font-size: 20px;
}

.brand span,
.tenant-card span,
.tenant-card small {
  color: #9fb0c1;
}

.brand-mark {
  display: grid;
  width: 44px;
  height: 44px;
  place-items: center;
  border-radius: 8px;
  background: #e8f4ff;
}

.brand-mark svg {
  width: 30px;
  fill: none;
  stroke: var(--teal);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 3;
}

.nav {
  display: grid;
  gap: 6px;
}

.nav-item {
  width: 100%;
  min-height: 42px;
  padding: 0 12px;
  color: #c9d5e2;
  text-align: left;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
}

.nav-item:hover,
.nav-item.active {
  color: #ffffff;
  background: var(--nav-soft);
  border-color: rgba(255, 255, 255, 0.08);
}

.tenant-card {
  display: grid;
  gap: 6px;
  margin-top: auto;
  padding: 14px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  background: var(--nav-soft);
}

.workspace {
  min-width: 0;
  padding: 24px;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 18px;
}

.eyebrow {
  margin: 0 0 4px;
  color: var(--teal);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1 {
  margin-bottom: 0;
  font-size: 30px;
}

h2 {
  font-size: 18px;
}

h3 {
  margin-bottom: 6px;
  font-size: 15px;
}

.topbar-actions {
  display: flex;
  align-items: end;
  gap: 12px;
}

.search {
  display: grid;
  gap: 5px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

.search input {
  width: min(360px, 36vw);
  height: 42px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
}

.primary-action,
.ghost-action {
  height: 42px;
  padding: 0 14px;
  border-radius: 8px;
  cursor: pointer;
}

.link-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

.token-line {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.token-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .6px;
  opacity: .6;
}
.token-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  background: rgba(127, 127, 127, .16);
  padding: 4px 9px;
  border-radius: 6px;
  word-break: break-all;
  max-width: 100%;
}
.token-btn {
  height: 30px;
  padding: 0 11px;
  font-size: 12px;
}

.primary-action {
  color: #fff;
  border: 1px solid #174dc0;
  background: var(--blue);
}

.ghost-action {
  color: var(--ink);
  border: 1px solid var(--line);
  background: #fff;
}

.ghost-action.danger {
  height: 34px;
  padding: 0 12px;
  color: #b42318;
  border: 1px solid #f3b9b3;
  background: #fff5f4;
}

.ghost-action.danger:hover {
  color: #fff;
  border-color: #b42318;
  background: #b42318;
}

/* Compact inline action buttons inside inventory tables (Instalar parche). */
.compact-table .ghost-action {
  height: 30px;
  padding: 0 12px;
  font-size: 12px;
  color: var(--blue);
  border: 1px solid #b9ccf3;
  background: #f2f6ff;
}

.compact-table .ghost-action:hover {
  color: #fff;
  border-color: var(--blue);
  background: var(--blue);
}

.compact-table .ghost-action.danger {
  height: 30px;
  color: #b42318;
  border-color: #f3b9b3;
  background: #fff5f4;
}

.compact-table .ghost-action.danger:hover {
  color: #fff;
  border-color: #b42318;
  background: #b42318;
}

.compact-table .ghost-action:disabled {
  opacity: 0.6;
  cursor: default;
}

/* Live progress bar shown in a row while a remote action runs. */
.action-progress {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 150px;
}

.action-progress-track {
  position: relative;
  flex: 1;
  height: 10px;
  border-radius: 6px;
  background: #e7ebf0;
  overflow: hidden;
}

.action-progress-fill {
  height: 100%;
  width: 0;
  border-radius: 6px;
  background-color: #1aa34a;
  background-image: repeating-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.22) 0,
    rgba(255, 255, 255, 0.22) 8px,
    transparent 8px,
    transparent 16px
  );
  background-size: 22px 22px;
  transition: width 0.5s ease;
  animation: action-stripes 0.7s linear infinite;
}

@keyframes action-stripes {
  0% { background-position: 0 0; }
  100% { background-position: 22px 0; }
}

.action-progress-fill.is-fail,
.action-progress.is-fail .action-progress-fill {
  background: linear-gradient(90deg, #b42318, #e0584b);
  animation: none;
}

.action-progress-label {
  font-size: 11px;
  font-weight: 600;
  color: #1aa34a;
  white-space: nowrap;
}

.action-progress.is-fail .action-progress-label {
  color: #b42318;
}

.action-progress.is-done .action-progress-label {
  color: #1aa34a;
}

/* Per-partition disk usage bars shown above the volumes table. */
.disk-bars {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 4px 0 18px;
}

.disk-bar-head {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 6px;
}

.disk-bar-track {
  height: 12px;
  border-radius: 7px;
  background: #e7ebf0;
  overflow: hidden;
}

.disk-bar-fill {
  height: 100%;
  border-radius: 7px;
  transition: width 0.4s ease;
}

.disk-bar-fill.is-ok { background: #1aa34a; }
.disk-bar-fill.is-warn { background: #d98c00; }
.disk-bar-fill.is-bad { background: #b42318; }

.disk-bar-foot {
  margin-top: 6px;
  font-size: 12px;
  color: var(--muted);
}

/* Endpoints table: multiple inline actions + "update available" badge. */
.row-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 200px;
}

.ver-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  color: #8a5a00;
  background: #fff4e0;
  border: 1px solid #f0c88a;
}

/* Search box above the installed-software list. */
.inv-search-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.inv-search {
  flex: 1;
  max-width: 360px;
  height: 38px;
  padding: 0 14px;
  border-radius: 8px;
  border: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink);
  background: #fff;
}

.inv-search:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(23, 77, 192, 0.12);
}

.inv-count {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted, #667085);
}

.content {
  display: grid;
  gap: 18px;
}

.grid {
  display: grid;
  gap: 16px;
}

.grid.metrics {
  grid-template-columns: repeat(4, minmax(150px, 1fr));
}

.grid.metrics-6 {
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
@media (max-width: 720px) { .grid.metrics-6 { grid-template-columns: repeat(2, minmax(130px, 1fr)); } }

.grid.two {
  grid-template-columns: minmax(0, 1.3fr) minmax(340px, 0.7fr);
}

.panel,
.metric,
.record-card {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  box-shadow: var(--shadow);
}

.panel {
  padding: 18px;
}

.metric {
  display: grid;
  gap: 10px;
  min-height: 128px;
  padding: 16px;
}

.metric span {
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
}

.metric strong {
  font-size: 30px;
}

.metric small {
  color: var(--muted);
}

.metric .trend.good {
  color: var(--green);
}

.metric .trend.warn {
  color: var(--amber);
}

.metric .trend.bad {
  color: var(--red);
}

.table-wrap {
  overflow-x: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  padding: 12px 10px;
  text-align: left;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

th {
  color: var(--ink-2);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
}

.pill {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 0 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 800;
}

.pill.ok {
  color: #075b2c;
  background: #dcfce7;
}

.pill.warn {
  color: #7a3c00;
  background: #fef3c7;
}

.pill.bad {
  color: #7f1d1d;
  background: #fee2e2;
}

.pill.info {
  color: #164b8f;
  background: #dbeafe;
}

/* Selector editable de clase de productividad (UAM · tabla de apps/dominios). */
.uam-cls-set {
  min-height: 26px;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 12px;
  font-weight: 800;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: none;
}
.uam-cls-set:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.uam-cls-set.uam-cls-neutral {
  color: #164b8f;
  background: #dbeafe;
}
.uam-cls-set.uam-cls-productive {
  color: #075b2c;
  background: #dcfce7;
}
.uam-cls-set.uam-cls-unproductive {
  color: #7f1d1d;
  background: #fee2e2;
}
.uam-cls-set option {
  color: initial;
  background: var(--panel, #fff);
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.segmented {
  display: inline-flex;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #eef3f7;
}

.segmented button {
  height: 32px;
  padding: 0 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
}

.segmented button.active {
  background: #fff;
  box-shadow: 0 1px 4px rgba(20, 31, 43, 0.12);
}

.record-list {
  display: grid;
  gap: 12px;
}

.record-card {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px;
  padding: 14px;
}

.record-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  color: var(--muted);
  font-size: 13px;
}

.risk-bar {
  height: 10px;
  overflow: hidden;
  border-radius: 999px;
  background: #e8eef5;
}

.risk-bar > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--green), var(--amber), var(--red));
}

.automation-grid {
  grid-template-columns: repeat(3, minmax(210px, 1fr));
}

.script-card {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.script-card code {
  display: block;
  padding: 10px;
  overflow-x: auto;
  color: #dbeafe;
  border-radius: 8px;
  background: #0b1220;
}

.inventory-layout {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

.inventory-sidebar {
  position: sticky;
  top: 18px;
}

/* Inventario con grupos: 3 columnas lado a lado -> árbol de grupos | lista de
   endpoints | detalle. Solo aplica cuando la sección lleva .inv-grouped (el árbol
   está presente); la vista de Seguridad usa .inventory-layout normal (2 columnas). */
/* Responsive: reducir columnas del inventario en pantallas medianas/pequenas */
@media (max-width:1280px){ .inventory-layout.inv-grouped{ grid-template-columns:200px 264px minmax(0,1fr) !important; } }
@media (max-width:1120px){ .inventory-layout.inv-grouped{ grid-template-columns:172px 232px minmax(0,1fr) !important; gap:12px !important; } }
.ep-tree, .ep-tree *{ min-width:0; }
.ep-tree .grp-name, .ep-tree .tenant-name{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.inventory-layout.inv-grouped {
  grid-template-columns: 224px 292px minmax(0, 1fr);
}
.inventory-layout.inv-grouped > .ep-tree {
  margin: 0;
}

.endpoint-selector-list {
  display: grid;
  gap: 8px;
}

.endpoint-selector {
  display: grid;
  gap: 4px;
  width: 100%;
  min-height: 74px;
  padding: 11px;
  text-align: left;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  cursor: pointer;
  transition: border-color .16s ease, box-shadow .16s ease, transform .12s ease, background .16s ease;
}

.endpoint-selector:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
  box-shadow: var(--elev-1);
  transform: translateY(-1px);
}

.endpoint-selector:active { transform: translateY(0) scale(.995); }

.endpoint-selector strong,
.endpoint-selector span,
.endpoint-selector small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.endpoint-selector span,
.endpoint-selector small {
  color: var(--muted);
}

.endpoint-selector.active {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--line));
  background: color-mix(in srgb, var(--accent) 8%, var(--panel));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

.endpoint-selector.active::after {
  content: "";
  position: absolute;
  left: 0; top: 50%; transform: translateY(-50%);
  width: 3px; height: 56%; border-radius: 0 3px 3px 0;
  background: var(--accent);
}

.inventory-detail {
  display: grid;
  gap: 16px;
  min-width: 0;
}

.inventory-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.inventory-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.inventory-panel {
  box-shadow: none;
}

.inv-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 7px;
  margin-bottom: 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  box-shadow: var(--shadow);
}

.inv-tab {
  height: 34px;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease, box-shadow 0.16s ease, transform 0.12s ease;
}

.inv-tab:hover {
  color: var(--ink);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.inv-tab:active { transform: scale(.97); }

.inv-tab.active {
  color: #fff;
  background: var(--blue);
  border-color: color-mix(in srgb, var(--blue) 70%, #000);
  box-shadow: 0 2px 10px color-mix(in srgb, var(--blue) 32%, transparent);
}

.inv-tab-content > .inventory-panel {
  box-shadow: var(--shadow);
}

.inv-subhead {
  margin: 18px 0 8px;
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--muted);
}

.inv-subhead:first-child {
  margin-top: 4px;
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 12px;
}

.field-row {
  display: grid;
  gap: 4px;
  min-height: 58px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--canvas);
  transition: border-color .16s ease, background .16s ease;
}

.field-row:hover {
  border-color: color-mix(in srgb, var(--accent) 38%, var(--line));
  background: color-mix(in srgb, var(--accent) 6%, var(--canvas));
}

.field-row span {
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
}

.field-row strong {
  overflow-wrap: anywhere;
  font-size: 14px;
}

.compact-table th,
.compact-table td {
  padding: 10px 12px;
  font-size: 13px;
}

/* ===== Tablas estandar (inventario y listas) — armonizadas con el modelo CPU/field-grid ===== */
.inventory-panel .table-wrap {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  margin-top: 14px;
}
.inventory-panel .disk-bars { margin-top: 14px; }
.inventory-panel .field-grid { margin-top: 14px; }
.inventory-panel .compact-table { border-collapse: separate; border-spacing: 0; }
.inventory-panel .compact-table thead th {
  background: var(--canvas);
  color: var(--blue);
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
.inventory-panel .compact-table thead th:first-child { border-top-left-radius: 12px; }
.inventory-panel .compact-table thead th:last-child { border-top-right-radius: 12px; }
.inventory-panel .compact-table tbody td { border-bottom: 1px solid var(--line); transition: background .14s ease; }
.inventory-panel .compact-table tbody tr:last-child td { border-bottom: none; }
.inventory-panel .compact-table tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--canvas) 50%, transparent); }
.inventory-panel .compact-table tbody tr:hover td { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.inventory-panel .compact-table td[colspan] { text-align: center; color: var(--muted); font-style: italic; padding: 22px; background: none; }

.toolbar-cluster {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

/* Centralized patches view */
.patch-count {
  min-width: 2.2rem;
  padding: 2px 12px;
  font-weight: 700;
  font-size: 13px;
  color: var(--blue);
  background: #eef3fe;
  border: 1px solid #c4d4f5;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.patch-count:hover,
.patch-count.is-open {
  color: #fff;
  background: var(--blue);
  border-color: var(--blue);
}
.patch-actions {
  white-space: nowrap;
}
.patch-actions .ghost-action {
  margin-left: 6px;
}
.patch-endpoints-row > td {
  background: #f4f7fa;
}
.patch-endpoints {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 2px;
}
.patch-chip {
  display: inline-block;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
}

/* Software inventory: per-endpoint uninstall rows (progress bar + error). */
.sw-ep-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 2px;
}
.sw-ep-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 6px 10px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.sw-ep-host {
  min-width: 180px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
.sw-ep-ver {
  color: var(--muted);
  font-weight: 500;
}
.sw-ep-action {
  min-width: 150px;
}
.sw-ep-action .action-progress {
  margin: 0;
}
.sw-ep-error {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 240px;
  padding: 4px 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--danger);
  background: rgba(225, 70, 70, 0.08);
  border: 1px solid rgba(225, 70, 70, 0.30);
  border-radius: 6px;
}
.sw-ep-error-msg {
  flex: 1;
  line-height: 1.3;
}
.sw-err-dismiss {
  border: none;
  background: transparent;
  color: var(--danger);
  font-weight: 700;
  cursor: pointer;
  padding: 0 2px;
  line-height: 1;
}
.sw-row-err {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  font-size: 11px;
  font-weight: 700;
  color: var(--danger);
  background: rgba(225, 70, 70, 0.10);
  border: 1px solid rgba(225, 70, 70, 0.30);
  border-radius: 999px;
  vertical-align: middle;
}
[data-theme="dark"] .sw-ep-row { background: var(--nav-soft); }
/* The "Atendida" button always sits beside a silent "Desinstalar". */
button[data-uninstall-attended] { margin-left: 6px; }

/* Connected user line on the endpoint selector cards. */
.endpoint-selector .es-user {
  color: var(--teal);
  font-weight: 600;
}

/* Usuarios tab: current user + en linea / desconectados toggle. */
.session-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 14px;
}
.session-current {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.session-current span {
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
}
.session-current strong {
  font-size: 16px;
  color: var(--ink);
}
.segmented {
  display: inline-flex;
  padding: 3px;
  gap: 3px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--canvas);
}
.seg-btn {
  height: 34px;
  padding: 0 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
}
.seg-btn:hover {
  color: var(--ink);
}
.seg-btn.active {
  color: #fff;
  background: var(--blue);
  border-color: #174dc0;
}

.download-menu {
  position: relative;
}

.download-menu summary {
  display: inline-flex;
  align-items: center;
  list-style: none;
  user-select: none;
}

.download-menu summary::-webkit-details-marker {
  display: none;
}

.download-menu summary::marker {
  content: "";
}

.download-menu-list {
  position: absolute;
  right: 0;
  z-index: 20;
  display: grid;
  gap: 4px;
  min-width: 260px;
  margin-top: 6px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  box-shadow: var(--shadow);
}

.download-menu-list a,
.download-menu-list button {
  display: grid;
  gap: 2px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 6px;
  color: var(--ink);
  text-align: left;
  text-decoration: none;
  background: transparent;
  cursor: pointer;
}

.download-menu-list a small,
.download-menu-list button small {
  color: var(--muted);
}

.download-menu-list a:hover,
.download-menu-list button:hover {
  background: #eef3f7;
}

.head-status {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.live-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  height: 26px;
  border-radius: 999px;
  background: #ecfdf3;
  color: #067647;
  font-size: 12px;
  font-weight: 800;
}

.live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #12b76a;
  animation: live-pulse 1.6s ease-in-out infinite;
}

@keyframes live-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(18, 183, 106, 0.5); }
  50% { opacity: 0.6; box-shadow: 0 0 0 5px rgba(18, 183, 106, 0); }
}

.control-tag {
  padding: 1px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #f1f5f9;
  font-size: 11px;
  font-weight: 700;
}

.ai-plan {
  margin: 0;
  padding: 14px;
  overflow-x: auto;
  white-space: pre-wrap;
  font-family: Inter, Segoe UI, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #f8fafc;
}

.empty-state {
  display: grid;
  gap: 8px;
  padding: 40px 24px;
  text-align: center;
}

.empty-state p,
.muted-note {
  margin: 0;
  color: var(--muted);
}

.empty-state p {
  max-width: 560px;
  margin: 0 auto;
}

.muted-note {
  padding: 10px 2px;
  font-size: 14px;
}

.toast {
  display: none;
  padding: 12px 14px;
  color: #063f3a;
  border: 1px solid #99f6e4;
  border-radius: 8px;
  background: #ccfbf1;
}

.toast.show {
  display: block;
}

@media (max-width: 980px) {
  .app-shell {
    grid-template-columns: 1fr;
  }

  .sidebar {
    position: static;
  }

  .nav {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .grid.metrics,
  .grid.two,
  .automation-grid,
  .inventory-layout,
  .inventory-grid,
  .field-grid {
    grid-template-columns: 1fr;
  }

  .inventory-layout.inv-grouped {
    grid-template-columns: 1fr;
  }

  .inventory-sidebar {
    position: static;
  }

  .topbar,
  .topbar-actions {
    align-items: stretch;
    flex-direction: column;
  }

  .search input {
    width: 100%;
  }
}

/* ITSM / Help Desk */
.tickets-layout { display: grid; grid-template-columns: 1.3fr 1fr; gap: 16px; align-items: start; }
@media (max-width: 1100px) { .tickets-layout { grid-template-columns: 1fr; } }
.ticket-create { gap: 8px; flex-wrap: wrap; }
.ticket-create input[type="text"] { min-width: 240px; height: 36px; padding: 0 12px; border: 1px solid var(--line); border-radius: 8px; }
.ticket-create select { height: 36px; }
.ticket-row { cursor: pointer; }
.ticket-row:hover { background: #f3f6ff; }
.ticket-row.active { background: #e7eefc; }
.ticket-thread { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.ticket-comment { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; background: #fff; }
.ticket-comment.internal { background: #fff7e6; border-color: #f0c88a; }
.ticket-comment-head { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 2px; }
.ticket-comment-head small { color: var(--muted, #667085); }
.ticket-reply { display: flex; flex-direction: column; gap: 8px; }
.ticket-reply textarea { width: 100%; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; font: inherit; resize: vertical; }
.ticket-internal { font-size: 12px; color: var(--muted, #667085); display: inline-flex; align-items: center; gap: 6px; }

/* Control remoto / escritorio remoto */
#remoteOverlay { position: fixed; inset: 0; z-index: 9999; display: flex; flex-direction: column;
  background: #0b1220; outline: none; }
.remote-bar { display: flex; align-items: center; gap: 14px; padding: 10px 16px;
  background: #111a2e; color: #e8eef5; border-bottom: 1px solid rgba(255,255,255,.1); }
.remote-bar strong { font-size: 14px; }
.remote-bar #remoteStatus { color: #9fb0c1; font-size: 12px; margin-right: auto; }
.remote-bar .primary-action.danger { background: #b42318; border-color: #8a1a12; }
.remote-stage { flex: 1; display: grid; place-items: center; overflow: hidden; }
#remoteImg { max-width: 100%; max-height: 100%; cursor: crosshair;
  box-shadow: 0 10px 40px rgba(0,0,0,.5); background: #000; user-select: none; }

/* Remote Assist — modal de solicitud (motivo/modo/duración) */
#remoteReq, #connectorModal { position: fixed; inset: 0; z-index: 9998; display: grid; place-items: center;
  background: rgba(11,18,32,.55); }

/* External connector cards (Ajustes) — info on the left, status + actions right. */
.connector-card { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.connector-info { min-width: 0; }
.connector-status { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; flex-shrink: 0; }
.connector-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.connector-actions .ghost-action { height: 32px; padding: 0 12px; font-size: 13px; }
.connector-actions .muted-note { margin: 0; font-size: 12px; }

/* ---- Report Engine (Reportes view) ---- */
.report-cat { margin-top: 18px; }
.report-cat:first-child { margin-top: 8px; }
.report-cat-title { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted);
  margin: 0 0 10px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.report-tpl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 12px; }
.report-tpl { display: flex; align-items: flex-start; gap: 14px; border: 1px solid var(--line);
  border-radius: 12px; padding: 16px; background: #fff; cursor: pointer; transition: border-color .12s, box-shadow .12s, transform .12s; }
.report-tpl:hover { border-color: var(--teal); box-shadow: var(--shadow); transform: translateY(-1px); }
.report-tpl-icon { flex-shrink: 0; width: 42px; height: 42px; border-radius: 10px; display: grid; place-items: center;
  background: #e8f4f2; color: var(--teal); }
.report-tpl-body { flex: 1; min-width: 0; }
.report-tpl-body h3 { margin: 0 0 4px; font-size: 14.5px; }
.report-tpl-body p { margin: 0; font-size: 12.5px; color: var(--muted); line-height: 1.45; }
.report-tpl-go { height: 34px; padding: 0 14px; align-self: center; flex-shrink: 0; }
.report-hist-actions { display: flex; gap: 6px; justify-content: flex-end; }
.report-hist-actions .ghost-action { height: 30px; padding: 0 12px; font-size: 12px; }
.report-hist-actions .ghost-action.danger { padding: 0 10px; }
#reportWizard { position: fixed; inset: 0; z-index: 9998; display: grid; place-items: center; background: rgba(11,18,32,.55); }
.report-wizard select { height: 38px; padding: 0 12px; border: 1px solid var(--line); border-radius: 8px; font: inherit; color: var(--ink); }
.report-wizard-check { flex-direction: row !important; align-items: center; gap: 8px !important; font-size: 13px !important; color: var(--ink) !important; font-weight: 600; }
.report-wizard-check.disabled { color: var(--muted) !important; }
.report-wizard-check input { width: 16px; height: 16px; }
.remote-req-card { width: min(440px, 92vw); background: #fff; border-radius: 14px; padding: 22px;
  box-shadow: 0 20px 60px rgba(0,0,0,.3); display: flex; flex-direction: column; gap: 10px; }
.remote-req-card h2 { margin: 0; font-size: 17px; }
.remote-req-card label { display: flex; flex-direction: column; gap: 4px; font-size: 12px;
  font-weight: 600; color: var(--muted, #647282); }
.remote-req-card input, .remote-req-card select { height: 38px; padding: 0 12px; border: 1px solid var(--line);
  border-radius: 8px; font: inherit; color: var(--ink); }
.remote-req-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 6px; }

/* Remote Assist — canvas del visor (WebSocket tiles) */
#remoteCanvas { max-width: 100%; max-height: 100%; cursor: crosshair;
  box-shadow: 0 10px 40px rgba(0,0,0,.5); background: #000; image-rendering: auto; }

/* Control remoto: verde en todas las paginas (Endpoints, Inventario, etc.). */
[data-remote-control] {
  color: #fff;
  border: 1px solid #16a34a;
  background: #16a34a;
}
[data-remote-control]:hover {
  border-color: #15803d;
  background: #15803d;
}

/* Iconos de sistema operativo en la lista de endpoints y el detalle. */
.os-icon { display: inline-flex; align-items: center; justify-content: center; line-height: 0; }
.os-icon svg { width: 56px; height: 56px; }   /* 80px reducido 30% */
/* Equipo desconectado: el icono del SO se muestra en plomo para identificar la desconexion */
.os-icon.os-offline { filter: grayscale(1); opacity: 0.5; }
.endpoint-selector { position: relative; min-height: 80px; padding-right: 50px; }
.endpoint-selector .os-icon { position: absolute; top: 50%; right: 12px; transform: translateY(-50%); }
/* Icono de SO más pequeño en las tarjetas de la lista Endpoints -> más espacio para el texto.
   (No afecta el header de detalle .os-title, que se queda en 62px.) */
.endpoint-selector .os-icon svg { width: 32px; height: 32px; }
.os-title { display: inline-flex; align-items: center; gap: 12px; }
.os-title .os-icon svg { width: 62px; height: 62px; }   /* 88px reducido 30% */

/* Dropdown de control de servicios (Inventario -> Servicios). */
.svc-dropdown { position: relative; display: inline-block; }
.svc-dropdown > summary {
  list-style: none; cursor: pointer; user-select: none;
  height: 30px; padding: 0 12px; display: inline-flex; align-items: center;
  font-size: 12px; color: var(--blue);
  border: 1px solid #b9ccf3; border-radius: 8px; background: #f2f6ff;
}
.svc-dropdown > summary::-webkit-details-marker { display: none; }
.svc-dropdown[open] > summary { color: #fff; border-color: var(--blue); background: var(--blue); }
.svc-menu {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 30;
  display: grid; min-width: 150px; padding: 6px;
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 12px 30px rgba(20, 31, 43, 0.18);
}
.svc-menu button {
  text-align: left; padding: 8px 10px; font-size: 13px;
  border: 0; border-radius: 6px; background: transparent; color: var(--ink); cursor: pointer;
}
.svc-menu button:hover { background: #eef3fb; }
.svc-menu button:disabled { color: #aab4c0; cursor: default; background: transparent; }

/* El contenedor de la tabla de servicios debe permitir que el menu desplegable
   sobresalga (overflow-x:auto fuerza overflow-y:auto y lo recortaria). */
.table-wrap:has(.svc-dropdown) { overflow: visible; }

/* ===== Xecura Automation Engine ========================================== */
.automation .auto-tab-content { display: grid; gap: 16px; }
.auto-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.auto-row-actions { display: flex; gap: 6px; }
.auto-checks { display: flex; flex-wrap: wrap; gap: 10px; }
.auto-checks-col { display: grid; gap: 8px; margin-top: 10px; }
.auto-check { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--ink); cursor: pointer; }
.auto-check input { width: 15px; height: 15px; }

/* Monospace editor / output textareas */
.auto-editor {
  width: 100%; font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 12.5px; line-height: 1.5; border: 1px solid var(--line); border-radius: 8px;
  padding: 10px 12px; background: #0f172a; color: #e2e8f0; resize: vertical; box-sizing: border-box;
}
.auto-editor[readonly] { background: #f1f5f9; color: var(--ink); }

/* Risk findings chips */
.auto-findings { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 2px; }
.auto-finding { font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px; border: 1px solid; }
.auto-finding.critical { color: #b42318; border-color: #fecdca; background: #fef3f2; }
.auto-finding.high { color: #b54708; border-color: #fedf89; background: #fffaeb; }
.auto-finding.medium { color: #854d0e; border-color: #fde68a; background: #fefce8; }
.auto-finding.low { color: #067647; border-color: #abefc6; background: #ecfdf3; }

/* Modals (script editor / execute / job detail) */
#scriptEditor, #execModal, #jobDetail {
  position: fixed; inset: 0; z-index: 9998; display: grid; place-items: center;
  background: rgba(11, 18, 32, .55); padding: 24px;
}
.auto-modal-card {
  width: min(680px, 95vw); max-height: 92vh; overflow-y: auto; background: var(--panel);
  border-radius: 14px; padding: 22px; box-shadow: 0 24px 70px rgba(0,0,0,.34);
  display: flex; flex-direction: column; gap: 12px;
}
.auto-editor-card { width: min(860px, 96vw); }
.auto-modal-head { display: flex; align-items: center; gap: 14px; }
.auto-modal-head h2 { margin: 0; font-size: 17px; flex: 1; overflow-wrap: anywhere; }
.auto-modal-actions { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.auto-editor-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.auto-modal-card label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; font-weight: 700; color: var(--muted); }
.auto-modal-card label.auto-full { grid-column: 1 / -1; }
.auto-modal-card input, .auto-modal-card select {
  height: 38px; padding: 0 12px; border: 1px solid var(--line); border-radius: 8px; font: inherit; color: var(--ink);
}
.auto-endpoint-list {
  display: grid; gap: 6px; max-height: 200px; overflow-y: auto; border: 1px solid var(--line);
  border-radius: 8px; padding: 10px; background: #f8fafc;
}
.auto-endpoint-list .auto-check { font-weight: 600; }

/* Generic modal overlay (class-based, same chrome as #execModal). */
.auto-modal {
  position: fixed; inset: 0; z-index: 9998; display: grid; place-items: center;
  background: rgba(11, 18, 32, .55); padding: 24px;
}
/* ===== Software deployment modal (.msi / .exe) ========================== */
.install-sw-card { width: min(720px, 96vw); }
.isw-step { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 14px; font-weight: 700; color: var(--ink); }
.isw-step-n { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--blue, var(--primary)); color: #fff; font-size: 12px; font-weight: 700; }
.isw-upload { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.install-sw-card .isw-upload input[type="file"] { grid-column: 1 / -1; height: auto; padding: 8px; }
.install-sw-card .isw-upload button { grid-column: 1 / -1; }
.isw-pkg-list { display: grid; gap: 6px; max-height: 210px; overflow-y: auto; }
.install-sw-card label.isw-pkg {
  display: flex; flex-direction: row; align-items: center; gap: 10px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
  cursor: pointer; color: var(--ink); font-weight: 600; background: var(--panel);
}
.install-sw-card label.isw-pkg.is-sel { border-color: var(--blue, var(--primary)); box-shadow: 0 0 0 2px rgba(37, 99, 235, .15); }
.isw-pkg-info { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.isw-pkg-meta { font-size: 12px; color: var(--muted); font-weight: 500; overflow-wrap: anywhere; }
.isw-pkg-del { border: none; background: transparent; color: var(--danger); font-weight: 700; cursor: pointer; padding: 2px 6px; line-height: 1; }
.isw-mode { width: 100%; }
.install-sw-card label.isw-all { flex-direction: row; align-items: center; color: var(--ink); font-weight: 700; margin: 2px 0; }
[data-theme="dark"] .auto-endpoint-list { background: var(--nav-soft); }
[data-theme="dark"] .install-sw-card label.isw-pkg { background: var(--nav-soft); }
/* Upload progress bar (reuses .action-progress chrome). */
.isw-upbar { margin: 2px 0 4px; }
/* Per-endpoint install progress. */
.isw-install-progress { display: grid; gap: 8px; border-top: 1px solid var(--line); padding-top: 8px; margin-top: 4px; }
.isw-prog-row { display: grid; grid-template-columns: 170px 1fr; align-items: center; gap: 12px; }
.isw-prog-host { font-size: 13px; font-weight: 700; color: var(--ink); overflow-wrap: anywhere; }
.isw-prog-row .action-progress { margin: 0; }
.isw-prog-msg { grid-column: 1 / -1; font-size: 12px; font-weight: 600; color: var(--muted); }
.isw-prog-msg.is-err { color: var(--danger); }
.isw-prog-skip { grid-column: 1 / -1; font-size: 12px; font-weight: 600; color: var(--warning, #b45309); background: rgba(245, 158, 11, .10); border: 1px solid rgba(245, 158, 11, .30); border-radius: 8px; padding: 8px 10px; }
/* Pending/active deployments panel. */
.isw-jobs-panel { border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px 12px; background: rgba(37, 99, 235, .04); }
.isw-jobs { display: grid; gap: 6px; }
.isw-job-row { display: grid; grid-template-columns: 1fr 1.2fr auto auto; align-items: center; gap: 10px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }
.isw-job-host { font-size: 13px; font-weight: 700; color: var(--ink); overflow-wrap: anywhere; }
.isw-job-pkg { font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
[data-theme="dark"] .isw-job-row { background: var(--nav-soft); }

/* Cabeceras de tabla ordenables (clic para ordenar asc/desc). */
.compact-table th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.compact-table th.sortable:hover { color: var(--blue); }
.compact-table th .sort-ind { color: var(--blue); font-weight: 700; }

/* Etiqueta divisoria dentro del menu desplegable de acciones (p. ej. "Prioridad"). */
.svc-menu-label {
  padding: 6px 10px 2px; margin-top: 4px;
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  color: var(--muted); border-top: 1px solid var(--line);
}

/* ===== Automation runbooks ============================================== */
.auto-steps-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 6px; }
.rb-steps { display: grid; gap: 10px; }
.rb-step { border: 1px solid var(--line); border-radius: 10px; padding: 12px; background: #f8fafc; }
.rb-step-top { display: flex; align-items: center; gap: 8px; }
.rb-step-order {
  display: inline-grid; place-items: center; min-width: 24px; height: 24px; border-radius: 999px;
  background: var(--blue); color: #fff; font-size: 12px; font-weight: 800; flex: none;
}
.rb-step-top .rb-step-name { flex: 1; height: 34px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; font: inherit; }
.rb-step-top select { height: 34px; border: 1px solid var(--line); border-radius: 8px; padding: 0 8px; font: inherit; }
.rb-step-ctrl { display: flex; gap: 4px; }
.rb-step-ctrl .ghost-action { padding: 4px 9px; }
.rb-step-cfg { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; align-items: end; }
.rb-step-cfg label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; font-weight: 700; color: var(--muted); }
.rb-step-cfg input, .rb-step-cfg select { height: 34px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; font: inherit; color: var(--ink); }
.rb-step-cfg .auto-check { flex-direction: row; align-items: center; }

/* Runbook per-step results in job detail */
.rb-result-list { display: grid; gap: 8px; }
.rb-result { border: 1px solid var(--line); border-left: 4px solid var(--line); border-radius: 8px; padding: 10px; background: #f8fafc; }
.rb-result.ok { border-left-color: #12b76a; }
.rb-result.fail { border-left-color: #f04438; }
.rb-result-head { display: flex; align-items: center; gap: 8px; }
.rb-result-head strong { font-size: 13px; }

/* =========================================================================
   XECURA PREMIUM VISUAL SYSTEM — theming, chrome, charts, animations
   ========================================================================= */

/* Semantic tokens layered on top of the existing palette. */
:root {
  --primary: var(--blue);
  --accent: #1583c4;
  --success: #17915a;
  --warning: #a86a00;
  --danger: #cf3b46;
  --rose: #e0576a;
  --ring-track: #e2e8ef;
  --elev-1: 0 1px 2px rgba(20,31,43,.06), 0 4px 16px rgba(20,31,43,.06);
  --elev-2: 0 18px 42px rgba(20,31,43,.12);
}

/* ---- DARK THEME (cybersecurity console) ---- */
[data-theme="dark"] {
  /* Command Deck — NOC (oscuro, centro de mando) */
  --ink: #cdd8e8;
  --muted: #7183a0;
  --line: #1d2a3d;
  --panel: #111a28;
  --canvas: #0a0e15;
  --nav: #070b12;
  --nav-soft: #131f2e;
  --blue: #38b6ea;
  --teal: #22d3ee;
  --green: #3ee0a0;
  --amber: #ffb020;
  --red: #ff5d63;
  --violet: #8b7cff;
  --primary: #38b6ea;
  --accent: #38b6ea;
  --success: #3ee0a0;
  --warning: #ffb020;
  --danger: #ff5d63;
  --rose: #fb7185;
  --ring-track: #17253a;
  --shadow: 0 18px 42px rgba(0,0,0,.5);
  --elev-1: 0 1px 2px rgba(0,0,0,.45), 0 4px 16px rgba(0,0,0,.4);
  --elev-2: 0 20px 46px rgba(0,0,0,.55);
}
[data-theme="dark"] body { background: var(--canvas); }
/* Surfaces that were hardcoded white in light mode. */
[data-theme="dark"] .search input,
[data-theme="dark"] .auth-field input,
[data-theme="dark"] .ghost-action,
[data-theme="dark"] .session-chip,
[data-theme="dark"] .primary-action.report-tpl-go,
[data-theme="dark"] .report-tpl,
[data-theme="dark"] .remote-req-card,
[data-theme="dark"] .report-wizard select,
[data-theme="dark"] .inv-search,
[data-theme="dark"] select { background: var(--nav-soft); color: var(--ink); border-color: var(--line); }
[data-theme="dark"] .auth-card { background: var(--panel); }
[data-theme="dark"] .auth-gate { background: radial-gradient(1200px 600px at 50% -10%, #0f2030, #060e1a); }
[data-theme="dark"] .kpi-card,
[data-theme="dark"] .chart-card,
[data-theme="dark"] .empty-pro { background: var(--panel); }
[data-theme="dark"] .pill.ok { color: #6ee7a8; background: rgba(34,197,94,.14); }
[data-theme="dark"] .pill.warn { color: #fcd34d; background: rgba(245,158,11,.14); }
[data-theme="dark"] .pill.bad { color: #fca5a5; background: rgba(240,68,56,.16); }
[data-theme="dark"] .pill.info { color: #93c5fd; background: rgba(59,130,246,.16); }
[data-theme="dark"] .command-center { background:
  linear-gradient(135deg, #0a1826 0%, #0d2230 55%, #0a2a2e 100%); border-color: #14324a; }
[data-theme="dark"] .compact-table .ghost-action { background: rgba(59,130,246,.12); border-color: #234; color: #93c5fd; }
[data-theme="dark"] .mini-meter, [data-theme="dark"] .dash-hbar-track { background: #14243a; }
[data-theme="dark"] .skeleton .sk { background: linear-gradient(90deg,#12243a,#1b3147,#12243a); }

/* Smooth theme transition. */
body, .panel, .metric, .sidebar, .kpi-card, .chart-card, input, select, .ghost-action {
  transition: background-color .25s ease, color .25s ease, border-color .25s ease;
}

/* ---- Header icon button (theme toggle) ---- */
.icon-btn {
  display: inline-grid; place-items: center;
  width: 42px; height: 42px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel); color: var(--ink);
  cursor: pointer; transition: background .15s, border-color .15s, transform .1s;
}
.icon-btn:hover { border-color: var(--primary); color: var(--primary); }
.icon-btn:active { transform: scale(.94); }

/* ---- Sidebar: icons, active indicator, system status ---- */
.nav-item { display: flex; align-items: center; gap: 11px; position: relative; font-weight: 600; }
.nav-ico-slot { display: inline-flex; width: 18px; height: 18px; color: #8fa3b8; flex-shrink: 0; transition: color .15s, transform .15s; }
.nav-item:hover .nav-ico-slot { color: #fff; transform: translateX(1px); }
.nav-item.active .nav-ico-slot { color: var(--teal); }
.nav-item.active::before {
  content: ""; position: absolute; left: -18px; top: 8px; bottom: 8px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--teal);
  animation: navIndicator .25s ease; box-shadow: 0 0 12px var(--teal);
}
@keyframes navIndicator { from { transform: scaleY(0); opacity: 0; } to { transform: scaleY(1); opacity: 1; } }
.sys-status { display: flex; align-items: center; gap: 8px; margin-top: 10px; padding-top: 10px;
  border-top: 1px solid rgba(255,255,255,.08); font-size: 11.5px; color: #9fb0c1; }
.sys-dot { width: 8px; height: 8px; border-radius: 50%; background: #64748b; flex-shrink: 0; }
.sys-status.ok .sys-dot { background: #22c55e; box-shadow: 0 0 0 0 rgba(34,197,94,.6); animation: pulseDot 2s infinite; }
.sys-status.warn .sys-dot { background: #f59e0b; }
@keyframes pulseDot { 0%{box-shadow:0 0 0 0 rgba(34,197,94,.5);} 70%{box-shadow:0 0 0 7px rgba(34,197,94,0);} 100%{box-shadow:0 0 0 0 rgba(34,197,94,0);} }

/* ---- Entrance animations ---- */
@keyframes revealUp { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.reveal { animation: revealUp .45s cubic-bezier(.22,1,.36,1) both; }
.reveal:nth-child(2) { animation-delay: .05s; }
.reveal:nth-child(3) { animation-delay: .10s; }
.reveal:nth-child(4) { animation-delay: .15s; }
.reveal:nth-child(5) { animation-delay: .20s; }
.kpis.reveal .kpi-card { animation: revealUp .45s cubic-bezier(.22,1,.36,1) both; }
.kpis.reveal .kpi-card:nth-child(2){animation-delay:.04s} .kpis.reveal .kpi-card:nth-child(3){animation-delay:.08s}
.kpis.reveal .kpi-card:nth-child(4){animation-delay:.12s} .kpis.reveal .kpi-card:nth-child(5){animation-delay:.16s}
.kpis.reveal .kpi-card:nth-child(6){animation-delay:.20s}
@media (prefers-reduced-motion: reduce) { .reveal, .kpis.reveal .kpi-card { animation: none !important; } }

/* ---- Command Center hero ---- */
.command-center {
  display: flex; align-items: center; justify-content: space-between; gap: 28px;
  padding: 26px 30px; border-radius: 16px; border: 1px solid #d6e3ef;
  background: linear-gradient(135deg, #0b2440 0%, #0f3a52 55%, #0d4a52 100%);
  color: #eaf4ff; box-shadow: var(--elev-2); position: relative; overflow: hidden;
}
.command-center::after { content: ""; position: absolute; inset: 0;
  background: radial-gradient(600px 200px at 90% -20%, rgba(34,211,238,.25), transparent 70%); pointer-events: none; }
.cc-eyebrow { margin: 0 0 4px; color: #7fe3d6; font-size: 12px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.cc-left h2 { margin: 0 0 6px; font-size: 26px; color: #fff; }
.cc-sub { margin: 0 0 16px; color: #b7d4e8; font-size: 14px; max-width: 52ch; }

/* ---- Cabecera comprimida (Fase 3) ---------------------------------------
   El eyebrow «Centro de operaciones» y el título «Estado global de
   infraestructura» gastaban ~200 px del espacio más caro de la pantalla para
   decirle al operador dónde está. Ese espacio pasa a las cifras. */
.command-center { padding: 12px 20px; gap: 18px; align-items: center; flex-wrap: wrap; }
.command-center.empty { flex-direction: column; align-items: flex-start; padding: 22px; }
.cc-gauge { flex: none; }
.cc-body { flex: 1 1 420px; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.cc-figs { display: grid; grid-template-columns: repeat(auto-fit, minmax(126px, 1fr)); gap: 8px; }
.cc-meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* El acordeón va en la MISMA fila, no debajo: en su propia línea añadía 40 px
   a la franja más cara de la pantalla. */
.cc-detail { flex: 0 1 auto; align-self: center; max-width: 260px; }
.command-center .dash-fig { padding: 8px 11px; }
.command-center .dash-fig strong { font-size: 26px; }

/* Las cifras de la cabecera van sobre fondo oscuro: heredan el contraste del
   hero en vez del de los paneles claros. */
.command-center .dash-fig { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.14); }
.command-center .dash-fig strong { color: #fff; }
.command-center .dash-fig span { color: #d7e9f6; }
.command-center .dash-fig small { color: #9dc0d6; }
.command-center .dash-fig.linked:hover { border-color: var(--accent); background: rgba(255,255,255,.11); }
.command-center .dash-fig.linked:focus-visible { outline: 2px solid #7fe3d6; outline-offset: 2px; }
.command-center .dash-fig.warn strong { color: #ffcf70; }

/* Tendencia. Mientras no existan instantáneas diarias, la carencia se declara
   en vez de dibujar una flecha inventada. */
.cc-delta { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600;
  padding: 3px 9px; border-radius: 999px; background: rgba(255,255,255,.07);
  border: 1px solid rgba(255,255,255,.14); color: #b7d4e8; }
.cc-delta i { font-style: normal; font-size: 9px; }
.cc-delta.none { color: #9dc0d6; font-style: italic; }
.cc-delta.good { color: #7ee6b0; } .cc-delta.bad { color: #ffb3b8; }

.command-center .dash-health-detail > summary { color: #b7d4e8; }
.command-center .dash-health-detail > summary:focus-visible { outline: 2px solid #7fe3d6; outline-offset: 2px; }
.cc-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.cc-chip { display: inline-flex; align-items: center; gap: 7px; padding: 6px 12px; border-radius: 999px;
  font-size: 12.5px; font-weight: 700; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.14); color: #eaf4ff; }
.cc-chip i { width: 8px; height: 8px; border-radius: 50%; background: #94a3b8; }
.cc-chip.ok i { background: #22c55e; } .cc-chip.warn i { background: #f59e0b; } .cc-chip.info i { background: #22d3ee; }
.cc-ring { flex-shrink: 0; }

/* ---- Health ring ---- */
.dash-ring { position: relative; width: 180px; height: 180px; }
.dash-ring-fill { transition: stroke-dashoffset 1.1s cubic-bezier(.22,1,.36,1); filter: drop-shadow(0 0 6px currentColor); }
.dash-ring-center { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; }
.dash-ring-center strong { font-size: 40px; font-weight: 800; line-height: 1; color: #fff; }
.command-center .dash-ring-center span { color: #cfe6f3; font-size: 13px; font-weight: 700; }
.command-center .dash-ring-center small { color: #8fb8cf; font-size: 11px; }

/* ---- KPI cards ---- */
.grid.kpis { grid-template-columns: repeat(6, minmax(0,1fr)); }
.kpi-card { border: 1px solid var(--line); border-radius: 14px; background: var(--panel); padding: 16px;
  box-shadow: var(--elev-1); position: relative; overflow: hidden; transition: transform .15s, box-shadow .15s, border-color .15s; }
.kpi-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--primary); opacity: .85; }
.kpi-card.ok::before { background: var(--success); } .kpi-card.warn::before { background: var(--warning); }
.kpi-card.bad::before { background: var(--danger); } .kpi-card.info::before { background: var(--primary); }
.kpi-card.teal::before { background: var(--teal); } .kpi-card.violet::before { background: var(--violet); }
.kpi-card.rose::before { background: var(--rose); }
.kpi-card.teal .kpi-dot { background: var(--teal); } .kpi-card.violet .kpi-dot { background: var(--violet); }
.kpi-card.rose .kpi-dot { background: var(--rose); }
.kpi-card.teal .kpi-ico { background: color-mix(in srgb, var(--teal) 15%, transparent); color: var(--teal); }
.kpi-card.violet .kpi-ico { background: color-mix(in srgb, var(--violet) 16%, transparent); color: var(--violet); }
.kpi-card.rose .kpi-ico { background: color-mix(in srgb, var(--rose) 16%, transparent); color: var(--rose); }
.kpi-card:hover { transform: translateY(-3px); box-shadow: var(--elev-2); border-color: var(--primary); }
.kpi-top { display: flex; align-items: center; justify-content: space-between; }
.kpi-ico { display: inline-flex; width: 34px; height: 34px; border-radius: 9px; place-items: center; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary); }
.kpi-card.ok .kpi-ico { background: color-mix(in srgb, var(--success) 14%, transparent); color: var(--success); }
.kpi-card.warn .kpi-ico { background: color-mix(in srgb, var(--warning) 16%, transparent); color: var(--warning); }
.kpi-card.bad .kpi-ico { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.kpi-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--primary); }
.kpi-card.ok .kpi-dot { background: var(--success); } .kpi-card.warn .kpi-dot { background: var(--warning); } .kpi-card.bad .kpi-dot { background: var(--danger); }
.kpi-val { display: block; font-size: 30px; font-weight: 800; margin-top: 12px; line-height: 1; }
.kpi-label { display: block; font-size: 13px; font-weight: 700; margin-top: 4px; }
.kpi-detail { color: var(--muted); font-size: 11.5px; }

/* ---- Chart cards ---- */
.grid.three { grid-template-columns: repeat(3, minmax(0,1fr)); }
.chart-card { min-height: 220px; }
.dash-empty-chart { color: var(--muted); font-size: 13px; padding: 24px 4px; text-align: center; }
.dash-donut { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.dash-donut-total { font-size: 26px; font-weight: 800; fill: var(--ink); }
.dash-donut-lbl { font-size: 11px; fill: var(--muted); }
.dash-legend { display: flex; flex-direction: column; gap: 7px; }
.dash-leg { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.dash-leg span { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }
.dash-leg strong { margin-left: auto; }
.dash-hbars { display: flex; flex-direction: column; gap: 10px; padding-top: 4px; }
.dash-hbar { display: grid; grid-template-columns: 88px 1fr 44px; align-items: center; gap: 10px; font-size: 12.5px; }
.dash-hbar-lbl { color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-hbar-track { height: 12px; border-radius: 7px; background: var(--ring-track); overflow: hidden; }
.dash-hbar-track i { display: block; height: 100%; border-radius: 7px; transition: width .9s cubic-bezier(.22,1,.36,1); }
.dash-hbar-val { text-align: right; font-weight: 700; }

/* ---- Mini CPU/RAM meter in tables ---- */
.ep-cell { display: flex; align-items: center; gap: 10px; }
.ep-os { display: inline-flex; width: 26px; height: 26px; align-items: center; justify-content: center; flex-shrink: 0; }
.ep-os svg { width: 22px; height: 22px; }
.ep-meter-cell { min-width: 90px; }
.ep-meter-cell small { color: var(--muted); font-size: 11px; }
.mini-meter { height: 7px; border-radius: 5px; background: var(--ring-track); overflow: hidden; margin-bottom: 3px; }
.mini-meter i { display: block; height: 100%; border-radius: 5px; background: var(--success); transition: width .6s ease; }
.mini-meter.warn i { background: var(--warning); } .mini-meter.bad i { background: var(--danger); }

/* ---- Premium empty state ---- */
.empty-pro { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 32px 20px; gap: 8px; }
.empty-pro-ico { display: grid; place-items: center; width: 58px; height: 58px; border-radius: 16px;
  background: color-mix(in srgb, var(--primary) 10%, transparent); color: var(--primary); margin-bottom: 4px; }
.empty-pro-ico svg { width: 26px; height: 26px; }
.empty-pro h3 { margin: 0; font-size: 16px; }
.empty-pro p { margin: 0; color: var(--muted); font-size: 13.5px; max-width: 48ch; line-height: 1.5; }
.empty-pro-actions { display: flex; gap: 10px; margin-top: 10px; }

/* ---- Skeleton loaders ---- */
.skeleton-list { display: flex; flex-direction: column; gap: 12px; padding: 8px 0; }
.skeleton-row { display: flex; align-items: center; gap: 12px; }
.sk { border-radius: 6px; background: linear-gradient(90deg,#eef2f6,#e2e8f0,#eef2f6); background-size: 200% 100%; animation: shimmer 1.3s infinite; }
.sk-dot { width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0; }
.sk-line { height: 12px; flex: 1; } .sk-line.short { max-width: 120px; }
@keyframes shimmer { 0%{background-position:200% 0;} 100%{background-position:-200% 0;} }

/* ---- Button press feedback ---- */
.primary-action:active, .ghost-action:active { transform: scale(.97); }
.primary-action, .ghost-action { transition: transform .08s ease, background-color .15s, border-color .15s, color .15s; }

/* ---- Responsive ---- */
@media (max-width: 1100px) {
  .grid.kpis { grid-template-columns: repeat(3, 1fr); }
  .grid.three { grid-template-columns: 1fr; }
  .command-center { flex-direction: column; align-items: flex-start; }
  .cc-ring { align-self: center; }
}
@media (max-width: 720px) {
  .grid.kpis { grid-template-columns: repeat(2, 1fr); }
}

/* metric() premium card — label-at-top variant (no icon) + loading spinner */
.kpi-label-top { font-size: 12.5px; font-weight: 700; color: var(--muted); }
.metric.kpi-card { min-height: 124px; }
.metric.kpi-card .kpi-val { margin-top: 10px; }

/* ===== Sparklines en vivo (cards CPU/RAM/Software, estilo Administrador de tareas) ===== */
.kpi-card-graph { min-height: 124px; }
.kpi-card-graph > :not(.kpi-spark-wrap) { position: relative; z-index: 1; }
.kpi-spark-wrap {
  position: absolute; left: 4px; right: 0; bottom: 0; height: 64%;
  z-index: 0; pointer-events: none;
}
.kpi-spark { width: 100%; height: 100%; display: block; }
.kpi-spark-area { animation: kpiSparkFade .8s ease both; }
.kpi-spark-line {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: kpiSparkDraw 1.1s cubic-bezier(.16,1,.3,1) forwards;
}
.kpi-spark-dot { transform-box: fill-box; transform-origin: center; animation: kpiSparkPulse 1.8s ease-in-out infinite; }
@keyframes kpiSparkDraw { to { stroke-dashoffset: 0; } }
@keyframes kpiSparkFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes kpiSparkPulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .4; transform: scale(1.7); } }
@media (prefers-reduced-motion: reduce) {
  .kpi-spark-line { stroke-dashoffset: 0; animation: none; }
  .kpi-spark-dot, .kpi-spark-area { animation: none; }
}
.spinner { width: 34px; height: 34px; border-radius: 50%; border: 3px solid var(--ring-track);
  border-top-color: var(--primary); animation: spin .8s linear infinite; margin-bottom: 6px; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; } }

/* Execute-modal policy block message */
.auto-block-msg { border: 1px solid #fecdca; background: #fef3f2; color: #b42318; border-radius: 8px; padding: 10px 12px; font-size: 13px; }
.auto-block-msg ul { margin: 6px 0 8px; padding-left: 18px; }
.auto-block-msg li { margin: 2px 0; }
.auto-block-msg .ghost-action { color: #b42318; border-color: #fecdca; }

/* UAM — formulario de gestión de políticas */
.uam-policy-form .field { display: flex; flex-direction: column; gap: 6px; }
.uam-policy-form .field > span { font-size: 12px; font-weight: 600; color: var(--muted); }
.uam-policy-form input[type="text"],
.uam-policy-form input[type="number"],
.uam-policy-form select,
.uam-policy-form textarea {
  width: 100%; padding: 8px 10px; font: inherit;
  border: 1px solid var(--border, #d6dbe5); border-radius: 8px;
  background: var(--surface, #fff); color: inherit;
}
.uam-policy-form textarea { resize: vertical; }

/* ===================== Filtrado Web (Web Filtering) ===================== */
.view-head { margin-bottom: 14px; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; margin-bottom: 18px; }
.stat-card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; box-shadow: var(--shadow); }
.stat-card .stat-label { color: var(--muted); font-size: 13px; }
.stat-card .stat-value { font-size: 26px; font-weight: 700; margin-top: 4px; color: var(--ink); }
.panel-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; gap: 12px; }
.panel-head h2 { margin: 0; font-size: 17px; }
.data-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.data-table th, .data-table td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.data-table th { color: var(--muted); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: .03em; }
.muted { color: var(--muted); }
.form-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.field { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
.field input, .field select, .form-row input, .form-row select { background: var(--canvas); border: 1px solid var(--line); border-radius: 9px; padding: 8px 10px; color: var(--ink); font-size: 14px; }
.check { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: var(--ink); }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.grid-2 h3, .panel h3 { font-size: 14px; margin: 0 0 8px; }
.chip-list { list-style: none; padding: 0; margin: 0 0 8px; display: flex; flex-wrap: wrap; gap: 6px; }
.chip-list li { background: var(--canvas); border: 1px solid var(--line); border-radius: 8px; padding: 4px 10px; font-size: 13px; display: inline-flex; align-items: center; gap: 6px; }
.link-btn { background: none; border: none; color: var(--danger); cursor: pointer; font-size: 13px; padding: 0 2px; }
.ghost-action.danger, .danger { color: var(--danger); }
.wf-cats { display: flex; flex-direction: column; gap: 6px; }
.wf-group summary { cursor: pointer; padding: 8px 4px; font-weight: 600; }
.wf-group .data-table td { border-bottom: 1px solid var(--line); }
select.rule-set { border-color: var(--accent); color: var(--accent); font-weight: 600; }
@media (max-width: 760px) { .grid-2 { grid-template-columns: 1fr; } }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
@media (max-width: 900px) { .grid-3 { grid-template-columns: 1fr; } }
.wf-trend { display: flex; align-items: flex-end; gap: 6px; height: 110px; padding: 6px 0; }
.wf-bar { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; }
.wf-bar > span { width: 70%; min-height: 2px; background: linear-gradient(180deg, var(--accent), var(--blue)); border-radius: 4px 4px 0 0; display: block; }
.wf-bar > small { color: var(--muted); font-size: 10px; margin-top: 4px; }
.wf-groups { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.wf-group-card { background: var(--canvas); border: 1px solid var(--line); border-radius: 12px; padding: 14px; }
.wf-group-card .pill { font-size: 11px; }
.field textarea, textarea#wfImportText { background: var(--canvas); border: 1px solid var(--line); border-radius: 9px; padding: 8px 10px; color: var(--ink); font-size: 14px; font-family: inherit; resize: vertical; }
code { background: var(--canvas); border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px; font-size: 12px; }

/* ===== Grupos de endpoints ===== */
.ep-group-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.ep-group-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 700; line-height: 1; padding: 3px 9px;
  border-radius: 999px; color: var(--chip, var(--accent));
  background: color-mix(in srgb, var(--chip, var(--accent)) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--chip, var(--accent)) 38%, transparent);
  transition: background .16s ease, transform .12s ease, box-shadow .16s ease;
}
.ep-group-chip::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--chip, var(--accent)); flex-shrink: 0;
}
.ep-group-chip:hover {
  background: color-mix(in srgb, var(--chip, var(--accent)) 22%, transparent);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--chip, var(--accent)) 24%, transparent); transform: translateY(-1px);
}
.ep-group-x { border: none; background: none; color: inherit; cursor: pointer; font-size: 13px; line-height: 1; padding: 0; opacity: .65; transition: opacity .14s, transform .12s; }
.ep-group-x:hover { opacity: 1; transform: scale(1.2); }

/* Layout de la vista Endpoints: arbol de grupos + tabla */
.ep-layout { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 18px; align-items: start; }
@media (max-width: 900px) { .ep-layout { grid-template-columns: 1fr; } }
.ep-table-area { min-width: 0; }

/* Arbol de grupos (rail izquierdo) — sistema visual refrescado */
.ep-tree {
  background: linear-gradient(180deg, var(--panel), color-mix(in srgb, var(--canvas) 60%, var(--panel)));
  border: 1px solid var(--line); border-radius: 16px;
  padding: 7px; display: flex; flex-direction: column; gap: 1px; align-self: start;
  box-shadow: var(--elev-1); position: sticky; top: 14px;
}
.ep-tree-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 10px 8px; margin-bottom: 4px; border-bottom: 1px solid var(--line);
}
.ep-tree-head-title {
  font-size: 14px; font-weight: 700; letter-spacing: .01em; color: var(--ink);
}
.ep-tree-head-count {
  font-size: 11px; font-weight: 800; color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-radius: 999px; padding: 1px 9px; min-width: 22px; text-align: center;
}
.ep-tree-head-right { display: inline-flex; align-items: center; gap: 6px; }
/* Botón para contraer/desplegar el panel "Grupos". */
.ep-tree-collapse, .ep-tree-expand {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  font-size: 15px; font-weight: 700; line-height: 1; padding: 0;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.ep-tree-collapse:hover, .ep-tree-expand:hover {
  color: var(--accent); border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
/* Estado contraído: barra fina con la flecha y una etiqueta vertical "Grupos". */
.ep-tree.is-collapsed {
  align-items: center; padding: 10px 6px; gap: 10px;
}
.ep-tree.is-collapsed .ep-tree-expand { width: 32px; height: 34px; font-size: 16px; }
.ep-tree-collapsed-label {
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
}
/* Al contraer, la columna del árbol se reduce a una barra fina y el resto gana espacio. */
.ep-layout.groups-collapsed { grid-template-columns: 48px minmax(0, 1fr); }
.inventory-layout.inv-grouped.groups-collapsed { grid-template-columns: 48px 292px minmax(0, 1fr); }
.ep-tree-node {
  position: relative; isolation: isolate;
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: none; border: none; cursor: pointer; color: var(--ink);
  font-size: 13px; font-weight: 600; padding: 8px 10px; border-radius: 10px; line-height: 1.2;
  transition: background .16s ease, color .16s ease, transform .12s ease;
}
.ep-tree-node:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.ep-tree-node:active { transform: scale(.98); }
.ep-tree-node.active {
  background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--ink); font-weight: 800;
}
.ep-tree-node.active::before {
  content: ""; position: absolute; left: 3px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 56%; border-radius: 3px; background: var(--accent);
}
.ep-tree-node svg { flex-shrink: 0; color: var(--accent); opacity: .92; transition: transform .16s ease; }
.ep-tree-node:hover svg { transform: scale(1.08); }
.ep-tree-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ep-tree-n {
  font-size: 11px; font-weight: 800; color: var(--muted); background: var(--canvas);
  border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px; min-width: 22px; text-align: center;
  transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.ep-tree-node.active .ep-tree-n { background: var(--accent); color: #fff; border-color: transparent; }
.ep-tree-all { font-weight: 700; margin-bottom: 2px; }
.ep-tree-rootline { display: flex; align-items: center; gap: 2px; border-radius: 10px; }
.ep-tree-rootline:hover .ep-tree-add { opacity: 1; }
.ep-tree-caret {
  background: none; border: none; cursor: pointer; color: var(--muted); font-size: 11px;
  width: 20px; height: 30px; flex-shrink: 0; transition: transform .2s cubic-bezier(.16,1,.3,1), color .16s; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.ep-tree-caret:hover { color: var(--accent); }
.ep-tree-caret.open { transform: rotate(90deg); }
.ep-tree-root { color: var(--ink); font-weight: 700; flex: 1; }
.ep-tree-add, .ep-tree-del {
  background: none; border: none; cursor: pointer; color: var(--muted); flex-shrink: 0;
  border-radius: 8px; line-height: 1; padding: 0; width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center; opacity: .5;
  transition: background .16s ease, color .16s ease, transform .12s ease, opacity .16s ease;
}
.ep-tree-add { font-size: 18px; font-weight: 700; }
.ep-tree-add:hover { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); opacity: 1; transform: scale(1.1); }
.ep-tree-children {
  display: flex; flex-direction: column; gap: 1px; padding-left: 13px; margin-left: 14px;
  border-left: 1.5px solid var(--line); animation: epTreeReveal .22s cubic-bezier(.16,1,.3,1);
}
@keyframes epTreeReveal { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: translateY(0); } }
.ep-tree-row { display: flex; align-items: center; border-radius: 10px; }
.ep-tree-row .ep-tree-node { flex: 1; }
.ep-tree-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; box-shadow: 0 0 0 2px color-mix(in srgb, var(--panel) 70%, transparent); }
.ep-tree-del { font-size: 16px; opacity: 0; }
.ep-tree-row:hover .ep-tree-del { opacity: .55; }
.ep-tree-del:hover { opacity: 1; color: var(--danger); background: color-mix(in srgb, var(--danger) 14%, transparent); transform: scale(1.1); }

.ep-sel-banner {
  display: flex; align-items: center; gap: 10px; margin-bottom: 12px; padding: 8px 12px;
  background: color-mix(in srgb, var(--accent) 9%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 9px; font-size: 13px; color: var(--ink);
}
.ep-sel-banner .ghost-action { margin-left: auto; height: 28px; padding: 0 12px; font-size: 12px; }

.grp-card, .grp-assign-card { max-width: 620px; width: 100%; }
.grp-create { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 6px 0 4px; }
.grp-create input[type="text"] { flex: 1 1 180px; background: var(--canvas); border: 1px solid var(--line); border-radius: 9px; padding: 9px 11px; color: var(--ink); font-size: 14px; transition: border-color .16s ease, box-shadow .16s ease; }
.grp-create input[type="text"]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
.grp-colors { display: inline-flex; gap: 6px; }
.grp-color { width: 22px; height: 22px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0; transition: transform .12s ease, box-shadow .16s ease; }
.grp-color:hover { transform: scale(1.18); }
.grp-color.active { border-color: var(--panel); box-shadow: 0 0 0 2px var(--ink), 0 2px 8px rgba(0,0,0,.18); }
.grp-list { display: grid; gap: 8px; margin-top: 14px; max-height: 46vh; overflow-y: auto; }
.grp-row { display: flex; align-items: center; gap: 10px; background: var(--canvas); border: 1px solid var(--line); border-radius: 12px; padding: 10px 13px; transition: border-color .16s ease, box-shadow .16s ease, transform .12s ease; }
.grp-row:hover { border-color: color-mix(in srgb, var(--accent) 42%, var(--line)); box-shadow: var(--elev-1); transform: translateY(-1px); }
.grp-row-main { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.grp-row-main small { color: var(--muted); font-size: 12px; }
.grp-row-main .grp-tenant { font-weight: 700; opacity: .8; }
.grp-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; box-shadow: 0 0 0 3px color-mix(in srgb, var(--panel) 70%, transparent); }
.grp-assign-list { display: grid; gap: 8px; margin: 6px 0 4px; max-height: 50vh; overflow-y: auto; }
.grp-assign-list .auto-check { background: var(--canvas); border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px; transition: border-color .16s ease, background .16s ease; }
.grp-assign-list .auto-check:hover { border-color: color-mix(in srgb, var(--accent) 42%, var(--line)); background: color-mix(in srgb, var(--accent) 7%, var(--canvas)); }

/* ===== Selección masiva + drag&drop de endpoints ===== */
.ep-check-cell { width: 34px; text-align: center; padding-left: 10px !important; padding-right: 0 !important; }
.ep-check-cell input { width: 15px; height: 15px; cursor: pointer; }
tr.ep-row { cursor: default; }
tr.ep-row.checked > td { background: color-mix(in srgb, var(--accent) 8%, transparent); }
tr.ep-row.dragging { opacity: .45; }
.ep-drag-handle { cursor: grab; color: var(--muted); font-size: 13px; letter-spacing: -2px; opacity: .5; user-select: none; }
.ep-drag-handle:active { cursor: grabbing; }
tr.ep-row:hover .ep-drag-handle { opacity: 1; }

.ep-tree-node.drag-over {
  background: color-mix(in srgb, var(--accent) 26%, transparent) !important;
  outline: 2px dashed var(--accent); outline-offset: -2px;
}

.ep-bulk-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px;
  padding: 9px 12px; border-radius: 10px; font-size: 13px; color: var(--ink);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
}
.ep-bulk-bar select {
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  padding: 6px 10px; color: var(--ink); font-size: 13px; max-width: 280px;
}
.ep-bulk-bar .primary-action, .ep-bulk-bar .ghost-action { height: 32px; padding: 0 14px; font-size: 13px; }

/* ===== Renombrar en línea + reordenar grupos ===== */
.ep-tree-group[draggable="true"] { cursor: grab; }
.ep-tree-group[draggable="true"]:active { cursor: grabbing; }
.ep-tree-row.dragging { opacity: .45; }
.ep-tree-edit {
  width: 100%; box-sizing: border-box; font-size: 13px; font-weight: 700;
  padding: 5px 8px; border: 1px solid var(--accent); border-radius: 7px;
  background: var(--panel); color: var(--ink); outline: none;
}
/* Indicador de posición de inserción al reordenar */
.ep-tree-row.drop-before { box-shadow: inset 0 2px 0 0 var(--accent); }
.ep-tree-row.drop-after { box-shadow: inset 0 -2px 0 0 var(--accent); }

/* Chips de grupo reutilizables en otras vistas (inventario, seguridad, parches, software) */
.ep-group-chips.inline { display: inline-flex; flex-wrap: wrap; gap: 4px; margin: 0 0 0 6px; vertical-align: middle; }
.ep-groups-cell { max-width: 200px; }
.ep-groups-cell .ep-group-chips { margin-top: 0; }
.endpoint-selector .ep-group-chips { margin-top: 6px; }
.patch-chip .ep-group-chips.inline, .sw-ep-host .ep-group-chips.inline { margin-left: 6px; }
#wfAsgGroup { max-width: 220px; }
.cat-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--canvas); border: 1px solid var(--line); border-radius: 8px; padding: 4px 10px; margin: 3px; font-size: 13px; }
.cat-chip small { font-size: 11px; opacity: .8; }
.cat-chip { cursor: pointer; }
.cat-chip input { margin: 0 4px 0 0; vertical-align: middle; }
.cat-chip.rule-block { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, var(--canvas)); }
.cat-chip.rule-allow { border-color: var(--green); background: color-mix(in srgb, var(--green) 8%, var(--canvas)); }
.cat-chip.rule-warn  { border-color: var(--amber); background: color-mix(in srgb, var(--amber) 10%, var(--canvas)); }

/* ===================== Configuración de Control Remoto ===================== */
.rc-section-title { font-size: 13px; font-weight: 700; color: var(--text); margin: 18px 0 8px; }
.rc-hint { color: var(--muted); font-size: 12px; margin: 2px 0 10px; }
.rc-cap-table { width: 100%; border-collapse: collapse; }
.rc-cap-table th { text-align: left; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); padding: 6px 10px; border-bottom: 1px solid var(--border); }
.rc-cap-table td { padding: 10px; border-bottom: 1px solid var(--border); vertical-align: middle; font-size: 13px; }
.rc-cap-table td .rc-cap-name { font-weight: 600; color: var(--text); }
.rc-cap-table td .rc-cap-desc { color: var(--muted); font-size: 12px; }
.rc-cap-table td:last-child { text-align: right; white-space: nowrap; }
/* Switch */
.rc-switch { position: relative; display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
.rc-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.rc-switch .rc-track { width: 40px; height: 22px; border-radius: 999px; background: color-mix(in srgb, var(--muted) 40%, transparent); transition: background .15s; flex: 0 0 auto; }
.rc-switch .rc-track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.3); transition: transform .15s; }
.rc-switch input:checked + .rc-track { background: var(--green, #16a34a); }
.rc-switch input:checked + .rc-track::after { transform: translateX(18px); }
.rc-switch .rc-state { font-size: 12px; font-weight: 600; color: var(--muted); min-width: 70px; text-align: left; }
.rc-switch input:checked ~ .rc-state { color: var(--green, #16a34a); }
.rc-radio-row { display: flex; align-items: center; gap: 8px; margin: 10px 0 2px; font-size: 13px; }
.rc-radio-row input[type="number"] { width: 72px; }
.rc-radio-help { color: var(--muted); font-size: 12px; margin: 0 0 6px 24px; line-height: 1.5; }
.rc-field { display: block; margin: 6px 0; font-size: 13px; }
.rc-check { display: flex; align-items: center; gap: 8px; font-size: 13px; margin: 8px 0; }
.rc-check.rc-indent { margin-left: 24px; }
.rc-proto { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; margin: 8px 0; }
.rc-proto .rc-proto-head { display: flex; align-items: center; gap: 8px; font-weight: 600; }
.rc-proto-body { margin: 8px 0 0 24px; display: grid; gap: 6px; }
.rc-textarea { width: 100%; min-height: 70px; resize: vertical; font-family: inherit; }
.rc-save-bar { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; }
.rc-tenant-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }

/* =========================================================================
   GEOLOCALIZACION — mapa mundial (Leaflet) + panel individual
   ========================================================================= */
.geo-wrap { display: flex; flex-direction: column; gap: 16px; }
.geo-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.geo-src-group { display: inline-flex; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: var(--panel); }
.geo-src-btn { border: 0; background: transparent; color: var(--muted); font-weight: 600; font-size: 13px; padding: 8px 14px; cursor: pointer; transition: background .15s, color .15s; }
.geo-src-btn + .geo-src-btn { border-left: 1px solid var(--line); }
.geo-src-btn:hover { color: var(--ink); }
.geo-src-btn.active { background: color-mix(in srgb, var(--accent) 16%, var(--panel)); color: var(--ink); }

.geo-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
@media (max-width: 1100px) { .geo-kpis { grid-template-columns: repeat(2, 1fr); } }

.geo-grid { display: grid; grid-template-columns: 320px 1fr; gap: 16px; align-items: start; }
@media (max-width: 960px) { .geo-grid { grid-template-columns: 1fr; } }

.geo-side { padding: 0; overflow: hidden; display: flex; flex-direction: column; max-height: 620px; }
.geo-side-head { padding: 14px 16px; font-weight: 700; border-bottom: 1px solid var(--line); color: var(--ink); }
.geo-list { overflow-y: auto; flex: 1; }
.geo-row { width: 100%; display: flex; align-items: center; gap: 10px; padding: 11px 14px; border: 0; border-bottom: 1px solid var(--line); background: transparent; cursor: pointer; text-align: left; transition: background .12s; }
.geo-row:hover { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.geo-row.active { background: color-mix(in srgb, var(--accent) 13%, transparent); box-shadow: inset 3px 0 0 var(--accent); }
.geo-row-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.geo-row-dot.on { background: var(--success); box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 25%, transparent); }
.geo-row-dot.off { background: #94a3b8; }
.geo-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.geo-row-main strong { font-size: 13px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.geo-row-main small { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.geo-badge { font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px; white-space: nowrap; }
.geo-badge.precise { background: color-mix(in srgb, var(--success) 16%, transparent); color: var(--success); }
.geo-badge.ip { background: color-mix(in srgb, var(--warning) 16%, transparent); color: var(--warning); }

.geo-map-col { display: flex; flex-direction: column; gap: 14px; }
.geo-map-shell { position: relative; z-index: 0; border-radius: 14px; overflow: hidden; border: 1px solid var(--line); box-shadow: var(--elev-1); }
.geo-map { height: 520px; width: 100%; background: var(--canvas); }
.geo-legend { position: absolute; bottom: 12px; left: 12px; z-index: 500; display: flex; gap: 12px; flex-wrap: wrap; background: color-mix(in srgb, var(--panel) 88%, transparent); backdrop-filter: blur(6px); border: 1px solid var(--line); border-radius: 10px; padding: 7px 11px; font-size: 11px; color: var(--muted); font-weight: 600; }
.geo-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 4px; vertical-align: middle; }
.geo-legend .geo-lg.on { background: var(--success); }
.geo-legend .geo-lg.off { background: #94a3b8; }
.geo-legend .geo-lg.precise { background: #fff; border: 2px solid var(--success); }
.geo-legend .geo-lg.ip { background: #fff; border: 2px dashed var(--warning); }

.geo-detail-panel { padding: 0; min-height: 120px; }
.geo-detail-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 26px; text-align: center; color: var(--muted); }
.geo-detail-empty .kpi-ico { width: 32px; height: 32px; color: var(--accent); }
.geo-detail { padding: 16px; }
.geo-detail-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.geo-detail-head > div:first-child { width: 40px; height: 40px; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; }
.geo-detail-head .os-icon svg { width: 36px !important; height: 36px !important; }
.geo-detail-title { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.geo-detail-title strong { color: var(--ink); }
.geo-detail-title span { font-size: 12px; color: var(--muted); }
.geo-detail-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 18px; margin: 0; }
@media (max-width: 640px) { .geo-detail-grid { grid-template-columns: repeat(2, 1fr); } }
.geo-detail-grid dt { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-bottom: 2px; }
.geo-detail-grid dd { margin: 0; font-size: 13px; font-weight: 600; color: var(--ink); }
.geo-detail-grid dd.mono, dd.mono { font-family: ui-monospace, "Cascadia Code", Consolas, monospace; font-weight: 500; }
.geo-detail-actions { display: flex; gap: 10px; margin-top: 16px; flex-wrap: wrap; }

.geo-note-warn { background: color-mix(in srgb, var(--warning) 12%, transparent); border: 1px solid color-mix(in srgb, var(--warning) 40%, transparent); color: var(--ink); border-radius: 10px; padding: 11px 14px; font-size: 13px; }
.geo-note-warn code { background: color-mix(in srgb, var(--warning) 18%, transparent); padding: 1px 6px; border-radius: 5px; font-size: 12px; }

/* Popup Leaflet armonizado con la consola */
.geo-popup .leaflet-popup-content-wrapper { background: var(--panel); color: var(--ink); border-radius: 12px; box-shadow: var(--elev-2); }
.geo-popup .leaflet-popup-tip { background: var(--panel); }
.geo-popup .leaflet-popup-content { margin: 12px 14px; font-family: inherit; }
.geo-pop { display: flex; flex-direction: column; gap: 6px; min-width: 190px; }
.geo-pop strong { font-size: 14px; color: var(--ink); }
.geo-pop-tenant { font-size: 12px; color: var(--muted); margin-top: -3px; }
.geo-pop-row { display: flex; align-items: center; gap: 8px; }
.geo-pop-acc { font-size: 12px; color: var(--muted); }
.geo-pop-place { font-size: 12px; color: var(--ink); }
.geo-pop-meta { font-size: 11px; color: var(--muted); }
.geo-pop-link { align-self: flex-start; margin-top: 4px; border: 0; background: transparent; color: var(--accent); font-weight: 700; font-size: 12px; cursor: pointer; padding: 0; }
.geo-pin { background: transparent; border: 0; }
.geo-pin-sel { filter: drop-shadow(0 4px 8px rgba(0,0,0,.35)); z-index: 650 !important; }

/* Tarjeta de ubicacion dentro del inventario (sin Leaflet, refresh-safe) */
.inv-geo-card { display: flex; flex-direction: column; gap: 16px; }
.inv-geo-card.empty { padding: 8px 0; }
.inv-geo-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.inv-geo-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* Leaflet en modo oscuro: controles y atribucion legibles */
[data-theme="dark"] .leaflet-bar a, [data-theme="dark"] .leaflet-control-attribution { background: var(--nav-soft); color: var(--muted); }
[data-theme="dark"] .leaflet-bar a { border-bottom-color: var(--line); }
[data-theme="dark"] .leaflet-control-attribution a { color: var(--accent); }

/* GPU manufacturer brand logo cell (Inventario de hardware > Video) */
.brand-cell { display: inline-flex; align-items: center; gap: 6px; line-height: 1; }
.brand-cell svg { flex: 0 0 auto; display: block; }

/* CPU "Marca" brand logo: large badge anchored to the right of the field box */
.field-row { position: relative; }
.brand-cell--badge svg { position: absolute; right: 14px; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; }

/* ===== Rework Filtrado Web: sub-navegación en 8 secciones + simulador ===== */
.wf-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin: 4px 0 18px; border-bottom: 1px solid var(--line); }
.wf-tab { padding: 9px 16px; border: 1px solid transparent; border-bottom: none; background: transparent;
  color: var(--muted); font-weight: 700; font-size: 13px; border-radius: 9px 9px 0 0; cursor: pointer;
  margin-bottom: -1px; transition: background var(--duration-fast, 150ms), color var(--duration-fast, 150ms); }
.wf-tab:hover { color: var(--ink); background: color-mix(in srgb, var(--blue) 8%, transparent); }
.wf-tab.active { color: var(--blue); background: var(--panel); border-color: var(--line); }
.wf-sec { display: none; }
.wf-sec.active { display: block; animation: wfFade .18s ease; }
@keyframes wfFade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.wf-toplist { list-style: none; padding: 0; margin: 6px 0 12px; }
.wf-toplist li { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.wf-sim-verdict { padding: 11px 15px; border-radius: 9px; font-size: 15px; border: 1px solid var(--line); }
.wf-v-block { background: color-mix(in srgb, var(--red) 12%, var(--canvas)); border-color: var(--red); }
.wf-v-allow { background: color-mix(in srgb, var(--green) 12%, var(--canvas)); border-color: var(--green); }
.wf-v-warn { background: color-mix(in srgb, var(--amber) 16%, var(--canvas)); border-color: var(--amber); }
tr.wf-win { background: color-mix(in srgb, var(--blue) 10%, transparent); font-weight: 700; }

/* ===== Filtrado Web: plantillas + panel de seguridad/enforcement ===== */
.wf-tpl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
.wf-tpl-card { border: 1px solid var(--line); border-radius: 12px; padding: 16px; background: var(--panel);
  display: flex; flex-direction: column; gap: 8px; transition: border-color var(--duration-fast,150ms), transform var(--duration-fast,150ms), box-shadow var(--duration-fast,150ms); }
.wf-tpl-card:hover { border-color: var(--blue); transform: translateY(-2px); box-shadow: var(--shadow); }
.wf-tpl-card h3 { margin: 0; font-size: 15px; }
.wf-tpl-card p { margin: 0; font-size: 13px; flex: 1 1 auto; }
.wf-tpl-meta { display: flex; gap: 6px; flex-wrap: wrap; }
.wf-tpl-card .ghost-action { align-self: flex-start; margin-top: 4px; }
.wf-adv { border-left: 3px solid var(--teal); }
.wf-adv h3 { margin: 16px 0 8px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.wf-adv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px 20px; align-items: start; }
.wf-adv-check { display: flex; gap: 8px; align-items: flex-start; line-height: 1.35; font-size: 14px; }
.wf-adv-check small { display: block; }

/* ===== Filtrado Web: editor de política guiado (pasos numerados) ===== */
.wf-editor { padding-top: 8px; }
.wf-editor-head { display: flex; justify-content: space-between; align-items: center; gap: 12px;
  flex-wrap: wrap; padding-bottom: 12px; margin-bottom: 4px; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--panel); z-index: 5; }
.wf-editor-head h2 { margin: 0; }
.wf-editor-note { margin: 8px 0 4px; padding: 9px 13px; border-radius: 9px; font-size: 13px;
  background: color-mix(in srgb, var(--blue) 7%, var(--canvas)); border: 1px solid color-mix(in srgb, var(--blue) 25%, var(--line)); color: var(--ink); }
.wf-draft .wf-editor-note { background: color-mix(in srgb, var(--amber) 12%, var(--canvas)); border-color: var(--amber); }
.wf-step { padding: 16px 0; border-bottom: 1px dashed var(--line); }
.wf-step:last-of-type { border-bottom: none; }
.wf-step-h { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; font-size: 15px; }
.wf-step-n { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--blue); color: #fff; font-size: 13px; font-weight: 700; flex: none; }
.wf-step-sec .wf-step-n { background: var(--teal); }
.wf-step-asg .wf-step-n { background: var(--violet); }
.wf-sub { margin: 14px 0 8px; font-size: 12.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.wf-editor-foot { display: flex; gap: 8px; align-items: center; padding-top: 16px; margin-top: 4px; border-top: 1px solid var(--line); }


/* ---- Modulo de Alertas ---------------------------------------------------- */
/* La campana usa position:relative para anclar el contador sobre el icono. */
.alert-bell { position: relative; }
.alert-badge {
  position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 9px; background: var(--warning, #d98c00);
  color: #fff; font-size: 11px; font-weight: 700; line-height: 18px;
  text-align: center; pointer-events: none;
  box-shadow: 0 0 0 2px var(--surface, #fff);
}
.alert-badge.critical {
  background: var(--danger, #b42318);
  /* Latido sutil solo cuando hay criticas: llama la atencion sin marear. */
  animation: alert-pulse 2.4s ease-in-out infinite;
}
@keyframes alert-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.12); }
}
@media (prefers-reduced-motion: reduce) {
  .alert-badge.critical { animation: none; }
}
/* Franja de color a la izquierda de cada alerta segun severidad. */
.alert-row td:first-child { border-left: 3px solid transparent; }
.alert-row.bad  td:first-child { border-left-color: var(--danger, #b42318); }
.alert-row.warn td:first-child { border-left-color: var(--warning, #d98c00); }
.alert-row.info td:first-child { border-left-color: var(--primary, #2563eb); }
.chip-sep {
  display: inline-block; width: 1px; height: 18px; margin: 0 6px;
  background: var(--border, rgba(128,128,128,.35)); vertical-align: middle;
}
.muted-small { color: var(--muted, #64748b); font-size: 12px; }
.field-row { display: flex; gap: 12px; }
.field-row > label { flex: 1; }


/* Grupo de navegacion colapsable (Gestion de Aplicaciones) */
.nav-group { display: grid; gap: 6px; }
.nav-group-head { width: 100%; min-height: 42px; padding: 0 12px; display: flex; align-items: center;
  gap: 11px; color: #c9d5e2; text-align: left; border: 1px solid transparent; border-radius: 8px;
  background: transparent; cursor: pointer; font-weight: 600; }
.nav-group-head:hover { color: #fff; background: var(--nav-soft); border-color: rgba(255,255,255,.08); }
.nav-group-head .nav-ico-slot { display: inline-flex; width: 18px; height: 18px; color: #8fa3b8; flex-shrink: 0; }
.nav-group-head:hover .nav-ico-slot { color: #fff; }
.nav-caret { margin-left: auto; font-size: 11px; color: #8fa3b8; transition: transform .18s ease; }
.nav-group.collapsed .nav-caret { transform: rotate(-90deg); }
.nav-group-body { display: grid; gap: 6px; margin-left: 10px; padding-left: 8px;
  border-left: 1px solid rgba(255,255,255,.08); }
.nav-group.collapsed .nav-group-body { display: none; }
.nav-child { min-height: 38px; font-weight: 500; }


/* Secciones del nav (7 categorias) + badge */
.nav-section { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: #6b7c90;
  margin: 14px 0 4px; padding: 0 12px; font-weight: 700; }
.nav .nav-section:first-child { margin-top: 0; }
.nav-badge { margin-left: auto; font-size: 11px; font-weight: 700; background: rgba(239,68,68,.16);
  color: #f87171; border-radius: 999px; padding: 1px 7px; line-height: 1.5; }
.nav-badge:empty { display: none; }


/* Cabeceras de seccion COLAPSABLES (mismo toggle que .nav-group) */
.nav-sec-head { width: 100%; display: flex; align-items: center; gap: 6px; padding: 5px 12px;
  margin-top: 12px; font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: #6b7c90; font-weight: 700; background: transparent; border: 1px solid transparent;
  border-radius: 6px; cursor: pointer; }
.nav-sec-head:hover { color: #c9d5e2; background: var(--nav-soft); }
.nav .nav-sec:first-child .nav-sec-head { margin-top: 0; }
.nav-sec-head .nav-caret { margin-left: auto; font-size: 10px; }
/* El cuerpo de seccion NO se indenta (a diferencia de los sub-items del grupo apps) */
.nav-sec-body { margin-left: 0; padding-left: 0; border-left: none; }


/* ===================== COMMAND DECK · firma de telemetria ===================== */
/* Reskin por tokens + tipografia mono para labels/tablas. Los logos e iconos de
   marca (Windows/Intel/AMD/Linux) son SVG con fill propio y NO se tocan. */
:root { --mono: "JetBrains Mono", ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace; }

/* Eyebrows / kickers -> telemetria monoespaciada */
.eyebrow, .cc-eyebrow { font-family: var(--mono); letter-spacing: .2em; font-size: 11px; font-weight: 600; }

/* KPI: labels mono en mayusculas + numerales tabulares + panel con profundidad */
.kpi-label, .kpi-label-top { font-family: var(--mono); text-transform: uppercase; letter-spacing: .11em; font-size: 11px; font-weight: 600; color: var(--muted); }
.kpi-val { font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.kpi-detail { font-family: var(--mono); font-size: 11px; letter-spacing: .01em; }
.kpi-card { background: linear-gradient(180deg, var(--panel), color-mix(in srgb, var(--canvas) 42%, var(--panel))); }
.kpi-card::before { opacity: 1; box-shadow: 0 0 14px -2px var(--primary); }
.kpi-card.ok::before { box-shadow: 0 0 14px -2px var(--success); }
.kpi-card.warn::before { box-shadow: 0 0 14px -2px var(--warning); }
.kpi-card.bad::before { box-shadow: 0 0 14px -2px var(--danger); }

/* Cabeceras de tabla -> mono mayusculas; celdas -> numerales tabulares */
.data-table th, .compact-table th { font-family: var(--mono); text-transform: uppercase; letter-spacing: .07em; font-size: 10.5px; font-weight: 600; color: var(--muted); }
.data-table td, .compact-table td { font-variant-numeric: tabular-nums; }

/* Badge "en vivo" -> verde senal, tematizado para el NOC */
[data-theme="dark"] .live-badge { background: rgba(62,224,160,.12); color: #7ff0c8; box-shadow: inset 0 0 0 1px rgba(62,224,160,.25); }
[data-theme="dark"] .live-dot { background: var(--success); box-shadow: 0 0 8px var(--success); }

/* Salvaguarda: nunca desaturar/filtrar logos e iconos de marca */
.os-title svg, .kpi-ico svg, .brand-logo svg, svg[aria-hidden="true"] { filter: none !important; }


/* ===================== COMMAND DECK · pasada de pulido ===================== */

/* Hero "Centro de operaciones" -> gradiente NOC cyan cohesivo (ambos temas) */
.command-center { background: linear-gradient(135deg, #0b1524 0%, #0e2536 52%, #0c2e3a 100%); border-color: #16324a; }
.command-center::after { background: radial-gradient(620px 220px at 88% -25%, color-mix(in srgb, var(--accent) 32%, transparent), transparent 70%); }
.cc-eyebrow { font-family: var(--mono); color: color-mix(in srgb, var(--accent) 82%, #ffffff); letter-spacing: .2em; }
.command-center .dash-ring-fill { filter: drop-shadow(0 0 8px currentColor); }

/* Item activo del menu -> acento cyan de mando */
.nav-item.active, .nav-group-head.active { position: relative;
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 16%, transparent), transparent 72%);
  border-color: color-mix(in srgb, var(--accent) 26%, transparent); color: #ffffff; }
.nav-item.active::before, .nav-group-head.active::before { content: ""; position: absolute; left: 0; top: 8px; bottom: 8px;
  width: 3px; border-radius: 2px; background: var(--accent); box-shadow: 0 0 10px var(--accent); }

/* Logo -> contenedor tematizado para integrar al NOC (el SVG no se toca) */
[data-theme="dark"] .brand-mark { background: color-mix(in srgb, var(--accent) 13%, #0e1a28); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent); }
[data-theme="dark"] .brand-mark svg { stroke: var(--accent); }

/* Foco accesible -> anillo cyan consistente */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; }

/* Scrollbars tematizadas (finas, oscuras en el NOC) */
* { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--muted) 45%, transparent) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 42%, transparent); border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--accent) 55%, transparent); background-clip: padding-box; }

/* KPI/paneles -> realce cyan sutil al pasar el mouse */
.kpi-card:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); box-shadow: var(--elev-2), 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent); }


/* ===================== COMMAND DECK · responsive / movil ===================== */
.nav-toggle { display: none; }
.nav-scrim { display: none; }

/* Grillas de KPIs fluidas a cualquier ancho */
@media (max-width: 1280px){ .grid.kpis { grid-template-columns: repeat(4, minmax(0,1fr)); } }
@media (max-width: 900px){ .grid.kpis, .grid.metrics { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (max-width: 620px){ .grid.kpis, .grid.metrics, .grid.metrics-6 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 380px){ .grid.kpis, .grid.metrics, .grid.metrics-6 { grid-template-columns: 1fr; } }

/* Hero "centro de operaciones" -> apila en pantallas chicas */
@media (max-width: 820px){
  .command-center { flex-direction: column; align-items: flex-start; gap: 18px; padding: 20px 20px 24px; }
  .command-center .cc-ring, .command-center .dash-ring { align-self: center; }
  .command-center .cc-left { width: 100%; }
}

/* ---- Sidebar como drawer off-canvas + hamburguesa (<= 980px) ---- */
@media (max-width: 980px){
  .app-shell { grid-template-columns: 1fr; }
  .nav-toggle { display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px;
    flex: none; border-radius: 10px; border: 1px solid var(--line); background: var(--panel); color: var(--ink); cursor: pointer; }
  .nav-toggle:hover { border-color: var(--accent); color: var(--accent); }
  .sidebar { position: fixed; top: 0; left: 0; z-index: 70; width: 284px; max-width: 86vw;
    height: 100vh; height: 100dvh; gap: 18px;
    transform: translateX(-100%); transition: transform .28s cubic-bezier(.22,1,.36,1); }
  body.nav-open .sidebar { transform: translateX(0); box-shadow: 10px 0 44px rgba(0,0,0,.5); }
  .nav-scrim { display: block; position: fixed; inset: 0; z-index: 65; background: rgba(4,8,14,.55);
    backdrop-filter: blur(2px); opacity: 0; pointer-events: none; transition: opacity .25s; }
  body.nav-open .nav-scrim { opacity: 1; pointer-events: auto; }
  body.nav-open { overflow: hidden; }
  .nav { grid-template-columns: 1fr; }
  .workspace { padding: 16px; }
  .topbar { flex-wrap: wrap; flex-direction: row; align-items: center; gap: 12px; }
  .topbar > :not(.topbar-actions):not(.nav-toggle) { flex: 1 1 auto; min-width: 0; }
  .topbar h1 { font-size: 22px; }
  .topbar-actions { flex-direction: row; flex-wrap: wrap; width: 100%; align-items: center; gap: 8px; }
  .topbar-actions .search { flex: 1 1 220px; }
  .search input { width: 100%; }
  .session-chip { margin-left: auto; }
}

/* ---- Telefonos ---- */
@media (max-width: 480px){
  .workspace { padding: 12px; }
  h1, .topbar h1 { font-size: 21px; }
  .kpi-val { font-size: 25px; }
  .command-center .cc-left h2 { font-size: 21px; }
  .primary-action#runHealthCheck { flex: 1 1 auto; }
  .table-wrap { border-radius: 10px; }
}


/* Fix overflow: los items de grid/flex deben poder encogerse (min-width:0) para
   no forzar scroll horizontal en pantallas chicas. Las tablas anchas ya scrollean
   dentro de su .table-wrap. */
#content > * { min-width: 0; }
.grid > * { min-width: 0; }
.workspace, #content { min-width: 0; max-width: 100%; }


/* ===================== COMMAND DECK · franja KPI semaforo + histograma ===================== */
.kpi-strip {
  --ink-2: color-mix(in srgb, var(--ink) 68%, var(--muted));
  display: grid; grid-template-columns: repeat(auto-fit, minmax(184px, 1fr));
  gap: 12px; overflow-x: auto; margin-bottom: 16px; padding-bottom: 2px; min-width: 0;
}
.kpi-tile, .kpi-id {
  min-height: 152px; min-width: 0; padding: 14px 15px; display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--elev-1);
  background: linear-gradient(180deg, var(--panel), color-mix(in srgb, var(--canvas) 42%, var(--panel)));
  position: relative; overflow: hidden;
}
.kpi-tile { --sig: var(--muted); }
.kpi-tile.s-ok { --sig: var(--success); }
.kpi-tile.s-warn { --sig: var(--warning); }
.kpi-tile.s-crit { --sig: var(--danger); }
.kpi-tile.s-neutral, .kpi-tile.off { --sig: var(--muted); }
.kpi-tile::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--sig); box-shadow: 0 0 12px -2px var(--sig); }
.kpi-tile-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.kpi-lbl { font-family: var(--mono); font-size: 10px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; }
.kpi-sig { width: 12px; height: 12px; border-radius: 50%; flex: none; background: var(--sig);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--sig) 18%, transparent); }
.kpi-figure { display: flex; align-items: baseline; gap: 3px; margin-top: 10px; }
.kpi-num { font-size: 27px; font-weight: 700; letter-spacing: -.03em; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--ink); }
.kpi-unit { font-size: 15px; font-weight: 600; color: var(--ink-2); }
.kpi-sub { font-size: 11.5px; color: var(--muted); margin-top: 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi-hist { display: flex; align-items: flex-end; gap: 2px; height: 34px; margin-top: auto; padding-top: 8px; }
.kpi-hist-spacer { height: 34px; margin-top: auto; }
.kpi-hist .kpi-bar { flex: 1; min-height: 2px; border-radius: 1px; background: var(--sig); opacity: .28; }
.kpi-hist .kpi-bar.hi { opacity: .9; }
.kpi-hist .kpi-bar.nul { opacity: 0; }
.kpi-hist.frozen { opacity: .4; }
.kpi-tile.off .kpi-num { color: var(--muted); }

/* Tarjeta de identidad */
.kpi-id { gap: 2px; }
.kpi-strip > .kpi-id { grid-column: span 2; }
.kpi-id .kpi-host { font-size: 22px; font-weight: 700; letter-spacing: -.02em; line-height: 1.05; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi-id .kpi-org { font-size: 12.5px; font-weight: 600; color: var(--accent); }
.kpi-id .kpi-meta { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi-id .kpi-live { display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono);
  font-size: 10.5px; color: var(--success); margin-top: 6px; }
.kpi-id .kpi-live i { width: 7px; height: 7px; border-radius: 50%; background: var(--success);
  box-shadow: 0 0 8px var(--success); animation: live-pulse 1.6s ease-in-out infinite; }
.kpi-id.off .kpi-live { color: var(--muted); }
.kpi-id.off .kpi-live i { background: var(--muted); box-shadow: none; animation: none; }
.kpi-id .kpi-rc { margin-top: auto; align-self: flex-start; }

@media (prefers-reduced-motion: reduce) { .kpi-id .kpi-live i { animation: none; } }
@media (max-width: 720px) {
  .kpi-strip { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .kpi-strip > .kpi-id { grid-column: span 2; }
}

/* =========================================================================
   DASHBOARD — módulos con estado explícito, cifras trazables y frescura.
   Tipografía tabular en toda cifra, estado nunca comunicado sólo por color
   (cada marca lleva glifo + texto accesible), y foco de teclado visible.
   ========================================================================= */

.dash-mod { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
/* Sin esto, un hijo flex no baja de su ancho de contenido y la tabla empuja el
   ancho del panel en vez de desplazarse dentro de su propio contenedor. */
.dash-mod > * { min-width: 0; max-width: 100%; }
.dash-mod .table-wrap { overflow-x: auto; }
/* Lo que un lector de pantalla lee en lugar de un gráfico va en un bloque de
   1×1 que recorta su contenido. Pero va en `position: absolute`, y el
   desbordamiento de un absoluto se propaga al panel: la tabla alternativa del
   mapa de riesgo mide 2.450 px y empujaba la página 184 px a 380 de ancho.
   `contain: strict` no lo detiene (medido); sacarlo de `absolute` sí, y con
   `clip-path: inset(50%)` sigue igual de oculto a la vista y presente para el
   lector, que es todo lo que la técnica necesita.
   Antes lo tapaba de refilón la regla que elevaba los hijos de un panel con
   dato crítico por encima de la marca de agua. Con esa marca retirada quedó al
   descubierto —y en una flota al día, sin ningún panel crítico, el desborde
   habría aparecido igual. */
.dash-mod .sr-only { position: relative; }
.dash-mod.wide { grid-column: 1 / -1; }
.dash-mod-head { align-items: baseline; gap: 12px; flex-wrap: wrap; }
.dash-mod-tools { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.dash-stack { display: flex; flex-direction: column; gap: 18px; }
.dash-sub { margin: 4px 0 0; font-size: 12px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted); }

/* ---- Marca de frescura --------------------------------------------------
   Tres estados, y cada uno con GLIFO propio además de color: el daltonismo no
   puede dejar a nadie sin saber si un panel está al día. */
.dash-fresh { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px;
  font-weight: 600; color: var(--muted); white-space: nowrap; }
.dash-fresh i { font-style: normal; font-size: 9px; line-height: 1; flex: none;
  color: var(--success); }
.dash-fresh time { font-variant-numeric: tabular-nums; }
.dash-fresh.stale { color: var(--warning); }
.dash-fresh.stale i { color: var(--warning); }
.dash-fresh.critical { color: var(--danger); font-weight: 700; }
.dash-fresh.critical i { color: var(--danger); }
.dash-fresh.unknown i { color: var(--muted); }

/* Franja global de frescura, a todo el ancho y bajo la cabecera. */
.dash-freshbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px; border-radius: 10px; font-size: 12.5px; line-height: 1.55;
  border: 1px solid color-mix(in srgb, var(--warning) 34%, transparent);
  background: color-mix(in srgb, var(--warning) 10%, var(--panel)); color: var(--ink); }
.dash-freshbar.critical { border-color: color-mix(in srgb, var(--danger) 40%, transparent);
  background: color-mix(in srgb, var(--danger) 9%, var(--panel)); }
.dash-freshbar-ico { font-style: normal; flex: none; font-size: 13px; color: var(--warning); }
.dash-freshbar.critical .dash-freshbar-ico { color: var(--danger); }
.dash-freshbar-text { margin: 0; flex: 1 1 320px; min-width: 0; }
.dash-freshbar-text b { font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  font-size: 11px; color: var(--warning); }
.dash-freshbar.critical .dash-freshbar-text b { color: var(--danger); }

/* Un panel con dato pasado se atenúa; con dato muy pasado, además lleva marca
   de agua. Debe notarse SIN leer ninguna fecha. */
.dash-mod.fresh-stale { border-color: color-mix(in srgb, var(--warning) 30%, var(--line)); }
/* Sin velo: atenuar la tarjeta bajaba el contraste de TODO su contenido y
   dejaba la pantalla a dos intensidades. El borde y el chip ya avisan. */
.dash-mod.fresh-critical { position: relative;
  border-color: color-mix(in srgb, var(--danger) 32%, var(--line)); }
.dash-mod.fresh-critical:hover, .dash-mod.fresh-critical:focus-within { opacity: 1; }
/* Marca de tiempo global de la cabecera: sustituye a repetir la fecha larga en
   cada panel. Separa "cuándo se calculó" de "de cuándo es el dato". */
.cc-stamp { margin: 0; display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
  font-size: 11.5px; font-weight: 600; color: color-mix(in srgb, #ffffff 62%, transparent); }
.cc-stamp time { font-variant-numeric: tabular-nums; }
.cc-stamp-part.stale { color: var(--warning); }
.cc-stamp-part.critical { color: #ff9aa2; }

/* =========================================================================
   DASHBOARD — rejilla de 12 columnas y franjas de peso decreciente
   -------------------------------------------------------------------------
   Antes: seis secciones con columnas FIJAS (910 px / 490 px). A 1440, 1280 y
   1024 px la suma de las dos columnas superaba el ancho disponible y la página
   entera desbordaba en horizontal (medido: 1.453 px de scroll en un viewport de
   1440). Ahora las columnas son fracciones y por debajo de 1280 px la rejilla
   se reorganiza sola.
   ========================================================================= */
/* La barra superior del área de trabajo no podía encoger ni envolver por
   encima de 980 px: a 1024 px, con la barra lateral de 272 px, sus 740 px de
   buscador + chip de sesión desbordaban la página entera en horizontal. No es
   un problema del Dashboard —afecta a todas las vistas—, pero salía en la
   medición de esta fase, así que se arregla aquí. */
.topbar { flex-wrap: wrap; }
.topbar > * { min-width: 0; }
.topbar-actions { flex: 1 1 auto; min-width: 0; flex-wrap: wrap; justify-content: flex-end; }
.topbar-actions .search { min-width: 0; flex: 1 1 200px; max-width: 340px; }
.topbar-actions .search input { width: 100%; min-width: 0; }

.dash-page { display: flex; flex-direction: column; gap: var(--dash-band-gap, 26px); }

.dash-band { display: flex; flex-direction: column; gap: 12px; }
.dash-band-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding-bottom: 2px; border-bottom: 1px solid var(--line); }
.dash-band-title { margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); }
.dash-band-head small, .dash-band > summary small { font-size: 11.5px; color: var(--muted); }

/* La franja «Explorar» va plegada: son paneles de consulta, no de decisión, y
   ocupaban un tercio del scroll sin responder a nada urgente. */
details.dash-band > summary { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  cursor: pointer; padding-bottom: 6px; border-bottom: 1px solid var(--line); list-style: none; }
details.dash-band > summary::-webkit-details-marker { display: none; }
details.dash-band > summary::before { content: "▸"; color: var(--muted); font-size: 11px; }
details.dash-band[open] > summary::before { content: "▾"; }
details.dash-band > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; border-radius: 6px; }
details.dash-band[open] > .dash-grid { margin-top: 12px; }

.dash-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 16px;
  align-items: start;          /* altura por CONTENIDO: sin filas igualadas */
}
.dash-grid > .dash-mod { grid-column: span var(--span, 6); min-width: 0; }

/* Por debajo de 1400 px una rejilla de doce columnas ya no describe nada útil.
   Con la barra lateral de 272 px, un viewport de 1280 deja ~960 px de trabajo:
   una columna de 12 mide 65 px, así que un panel de `span 3` se queda en 227 px
   y su contenido no cabe (medido: el panel de Backup necesita 241). Tres
   paneles de 320 px no entran en 960; dos de 472 sí. Ahí la rejilla deja de
   describir el diseño y se pasa a auto-fit. */
@media (max-width: 1399px) {
  .dash-grid { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
  .dash-grid > .dash-mod { grid-column: auto; }
}
@media (max-width: 700px) {
  .dash-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Destello al saltar de un panel a la fuente canónica de un dato. */
.dash-focus-flash { animation: dashFocusFlash 1.6s ease-out; outline: 2px solid var(--primary);
  outline-offset: 3px; border-radius: 12px; }
@keyframes dashFocusFlash { from { box-shadow: 0 0 0 6px color-mix(in srgb, var(--primary) 26%, transparent); }
  to { box-shadow: 0 0 0 0 transparent; } }
@media (prefers-reduced-motion: reduce) { .dash-focus-flash { animation: none; } }
.dash-inline-link { background: none; border: 0; padding: 0; font: inherit; font-weight: 600;
  color: var(--primary); cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.dash-inline-link:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 3px; }

/* ---- Cifras: numeración tabular en todo el panel -------------------------
   Sin `tabular-nums` los dígitos tienen anchos distintos y una columna de
   cifras deja de alinearse — el 1 ocupa menos que el 8 y la coma baila. En una
   pantalla que se lee comparando filas, eso cuesta lecturas. */
.dash-mod .tnum,
.dash-mod time,
.dash-mod .dash-fig strong,
.dash-mod .dash-patch-cell,
.dash-mod table td,
.dash-mod b,
.command-center time,
.command-center .dash-fig strong { font-variant-numeric: tabular-nums; }

/* ---- Cifras trazables --------------------------------------------------- */
/* 116 px y no 130: con la tipografia de la Fase 4 (cifra de 30 px y etiqueta
   en versalitas) un panel de 246 px de ancho solo cabia UNA columna de cifras
   y crecia el doble de alto de lo necesario. */
.dash-figs { display: grid; grid-template-columns: repeat(auto-fit, minmax(116px, 1fr)); gap: 10px; }
.dash-fig { display: flex; flex-direction: column; gap: 2px; align-items: flex-start; text-align: left;
  padding: 12px 14px; border: 1px solid var(--line); border-left-width: 3px; border-radius: 10px;
  background: var(--panel); color: inherit; font: inherit; cursor: default;
  transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease; }
.dash-fig.linked { cursor: pointer; }
.dash-fig.linked:hover { border-color: var(--primary); transform: translateY(-1px); box-shadow: var(--elev-1); }
.dash-fig.linked:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.dash-fig strong { font-size: 25px; font-weight: 700; line-height: 1.05; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; color: var(--ink); }
.dash-fig span { font-size: 12px; font-weight: 600; color: var(--ink); }
.dash-fig small { font-size: 11px; color: var(--muted); }
.dash-fig.ok { border-left-color: var(--success); }
.dash-fig.warn { border-left-color: var(--warning); }
.dash-fig.warn strong { color: var(--warning); }
.dash-fig.bad { border-left-color: var(--danger); }
.dash-fig.bad strong { color: var(--danger); }
.dash-fig.muted { border-left-color: var(--line); }
.dash-fig.muted strong { color: var(--muted); }

/* ---- Enlaces dentro de tablas y listas ---------------------------------- */
.dash-link { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 0; border: 0; background: none; color: var(--ink); font: inherit; font-weight: 600;
  text-align: left; cursor: pointer; border-bottom: 1px solid transparent; }
.dash-link:hover { color: var(--primary); border-bottom-color: currentColor; }
.dash-link:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; border-radius: 3px; }
.dash-link.bad { color: var(--danger); }
.dash-link.warn { color: var(--warning); }
.dash-muted { color: var(--muted); font-weight: 500; }
.dash-warn-text { color: var(--warning); font-weight: 600; }

/* ---- Píldoras de estado (glifo + texto, nunca sólo color) --------------- */
.dash-pill { display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px;
  border-radius: 999px; font-size: 11px; font-weight: 700; white-space: nowrap;
  border: 1px solid transparent; }
.dash-pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.dash-pill.ok { color: var(--success); background: color-mix(in srgb, var(--success) 12%, transparent);
  border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.dash-pill.warn { color: var(--warning); background: color-mix(in srgb, var(--warning) 14%, transparent);
  border-color: color-mix(in srgb, var(--warning) 32%, transparent); }
.dash-pill.bad { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent);
  border-color: color-mix(in srgb, var(--danger) 32%, transparent); }
.dash-pill.muted { color: var(--muted); background: color-mix(in srgb, var(--muted) 12%, transparent);
  border-color: var(--line); }

/* ---- Tablas ------------------------------------------------------------- */
.dash-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.dash-table th { text-align: left; padding: 0 10px 8px 0; font-size: 10.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.dash-table td { padding: 9px 10px 9px 0; border-top: 1px solid var(--line); vertical-align: middle; }
.dash-table .tnum { font-variant-numeric: tabular-nums; }
.dash-health-cell { display: flex; align-items: center; gap: 8px; min-width: 96px; }
.dash-health-cell .mini-meter { flex: 1; margin: 0; }

/* ---- Matriz de cobertura ------------------------------------------------ */
.dash-matrix td:not(:first-child) { text-align: center; }
.dash-matrix th:not(:first-child) { text-align: center; }
/* `position: relative` no es decorativo: sin un ancestro posicionado, el texto
   .sr-only de cada celda (position: absolute) NO lo recorta el contenedor con
   scroll de la tabla y acaba estirando el ancho de la página en móvil. */
.dash-mark { position: relative; display: inline-grid; place-content: center; width: 22px;
  height: 22px; border-radius: 7px; font-size: 12px; font-weight: 800; line-height: 1; }
.dash-mark.ok { color: var(--success); background: color-mix(in srgb, var(--success) 14%, transparent); }
.dash-mark.warn { color: var(--warning); background: color-mix(in srgb, var(--warning) 16%, transparent); }
.dash-mark.bad { color: var(--danger); background: color-mix(in srgb, var(--danger) 14%, transparent); }
.dash-mark.muted { color: var(--muted); background: color-mix(in srgb, var(--muted) 12%, transparent); }
.dash-legend-inline { display: flex; flex-wrap: wrap; gap: 14px; font-size: 11.5px; color: var(--muted); }
.dash-legend-inline span { display: inline-flex; align-items: center; gap: 6px; }

/* ---- Listas y rankings -------------------------------------------------- */
.dash-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.dash-list li { border-top: 1px solid var(--line); }
.dash-list li:first-child { border-top: 0; }
.dash-list li > .dash-link { width: 100%; padding: 9px 0; justify-content: flex-start; }
/* Columna de nombre alineada — pero sólo cuando el primer elemento ES el
   nombre: si la fila abre con una píldora de estado, estirarla a 130 px deja un
   hueco absurdo entre la etiqueta y el dato. */
.dash-list li > .dash-link > span:first-child:not(.dash-pill) { min-width: 130px; }
.dash-list li > .dash-link > .dash-muted { flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* La cifra de cierre de cada fila se alinea a la derecha en vez de saltar de
   línea cuando el nombre del producto es largo. */
.dash-list li > .dash-link > b:last-child { margin-left: auto; white-space: nowrap; }
.dash-list code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.dash-list.findings .dash-find-host { min-width: 150px; font-weight: 700; }
.dash-list.findings .dash-find-detail { flex: 1; color: var(--muted); font-weight: 500; }
.dash-list.findings .dash-pill { margin-left: auto; }

.dash-rank { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.dash-rank li { display: grid; grid-template-columns: minmax(110px, 1.1fr) minmax(60px, 2fr) auto auto;
  align-items: center; gap: 10px; font-size: 12.5px; }
.dash-rank-track { height: 6px; border-radius: 4px; background: var(--ring-track); overflow: hidden; }
.dash-rank-track i { display: block; height: 100%; border-radius: 4px; background: var(--success);
  transition: width .7s cubic-bezier(.16,1,.3,1); }
.dash-rank-track i.warn { background: var(--warning); }
.dash-rank-track i.bad { background: var(--danger); }
.dash-rank b { font-variant-numeric: tabular-nums; }

/* ---- Barra de severidad ------------------------------------------------- */
.dash-sev { display: flex; height: 9px; border-radius: 5px; overflow: hidden; background: var(--ring-track); }
.dash-sev i { height: 100%; }
.dash-sev i.bad { background: var(--danger); }
.dash-sev i.warn { background: var(--warning); }
.dash-sev i.muted { background: var(--muted); }
.dash-sev-legend { display: flex; flex-wrap: wrap; gap: 14px; font-size: 11.5px; color: var(--muted); }
.dash-sev-legend b { font-variant-numeric: tabular-nums; color: var(--ink); }
.dash-sev-legend .bad { color: var(--danger); }
.dash-sev-legend .warn { color: var(--warning); }

/* ---- Bitácora ----------------------------------------------------------- */
.dash-feed { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.dash-feed li { display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: 12px;
  padding: 9px 0; border-top: 1px solid var(--line); font-size: 12.5px; }
.dash-feed li:first-child { border-top: 0; }
.dash-feed time { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; padding-top: 2px; }
.dash-feed li > div { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
.dash-feed b { font-weight: 700; }
.dash-feed .dash-feed-text { color: var(--muted); }
.dash-feed li.kind-alert .dash-feed-text { color: var(--ink); font-weight: 600; }

/* ---- Notas, criterios y cobertura --------------------------------------- */
.dash-note { margin: 0; font-size: 11.5px; line-height: 1.55; color: var(--muted); }
.dash-note.warn { color: var(--warning); font-weight: 600; }
.dash-coverage { margin: 0; padding: 8px 11px; border-radius: 8px; font-size: 11.5px; font-weight: 600;
  color: var(--warning); background: color-mix(in srgb, var(--warning) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--warning) 26%, transparent); }
.dash-criteria { list-style: none; margin: 0; padding: 10px 0 0; border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 5px; font-size: 11.5px; color: var(--muted); }
.dash-criteria b { color: var(--ink); }

/* ---- Nota metodológica plegable ------------------------------------------
   Las explicaciones de fórmula, fuentes y límites del dato NO se borran: son
   el diferenciador del producto. Se pliegan porque ocupaban hasta seis líneas
   al pie de cada panel y descuadraban la rejilla. Siguen en el DOM, siguen
   siendo texto y las lee un lector de pantalla. */
.dash-method { margin-top: auto; }
.dash-method > summary { cursor: pointer; font-size: 11.5px; font-weight: 600; color: var(--muted);
  list-style: none; display: inline-flex; align-items: center; gap: 6px; }
.dash-method > summary::-webkit-details-marker { display: none; }
.dash-method > summary::before { content: "?"; display: inline-grid; place-items: center;
  width: 14px; height: 14px; border-radius: 50%; border: 1px solid var(--line);
  font-size: 9px; font-weight: 700; }
.dash-method > summary:hover { color: var(--ink); }
.dash-method > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; border-radius: 4px; }
.dash-method[open] > summary { margin-bottom: 6px; }

/* ---- Estados: sin datos y error ---------------------------------------- */
.dash-state { display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  padding: 22px; border-radius: 10px; border: 1px dashed var(--line); background: var(--canvas); }
.dash-state.error { border-style: solid; border-color: color-mix(in srgb, var(--danger) 40%, transparent);
  background: color-mix(in srgb, var(--danger) 7%, transparent); }
.dash-state-title { margin: 0; font-size: 13.5px; font-weight: 700; color: var(--ink); }
.dash-state-body { margin: 0; font-size: 12.5px; line-height: 1.6; color: var(--muted); max-width: 62ch; }
.dash-state.error .dash-state-body { color: var(--ink); }
/* Detalle técnico de un bloque caído: plegado y sólo presente en el DOM cuando
   el servidor lo manda, que es únicamente a roles de plataforma. */
.dash-tech { width: 100%; font-size: 11.5px; color: var(--muted); }
.dash-tech > summary { cursor: pointer; font-weight: 600; color: var(--muted); }
.dash-tech > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }
.dash-tech-type { margin: 8px 0 4px; font-weight: 700; color: var(--ink); }
.dash-tech pre { margin: 0; max-height: 220px; overflow: auto; padding: 10px; border-radius: 8px;
  background: var(--canvas); border: 1px solid var(--line); font-size: 11px; line-height: 1.5;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre-wrap; }

/* Celda de PARCHES: la cifra arriba y sobre cuántos equipos se calcula debajo.
   Antes las dos cosas iban pegadas en una línea ("3 5/7") y no se entendía. */
.dash-patch-cell { line-height: 1.35; }
.dash-patch-cell > small { display: block; font-size: 10.5px; }

/* "Ver los N restantes": las listas se cortan y declaran lo que no muestran. */
.dash-more > .dash-link { width: 100%; padding: 9px 0; font-weight: 600; color: var(--primary); }

/* ---- Esqueleto de carga: mismas dimensiones que el contenido final ------ */
.dash-skel { display: flex; flex-direction: column; gap: 11px; padding: 4px 0; }
.dash-skel span { display: block; height: 34px; border-radius: 8px;
  background: linear-gradient(90deg, var(--ring-track) 25%, var(--line) 37%, var(--ring-track) 63%);
  background-size: 400% 100%; animation: dash-shimmer 1.4s ease infinite; }
.dash-skel span:first-child { height: 52px; }
@keyframes dash-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ---- Sobre el hero, que es oscuro en AMBOS temas ------------------------ */
/* var(--muted) es gris oscuro en tema claro: sobre el degradado del hero sería
   ilegible, así que dentro de .command-center se usan tonos claros fijos. */
.command-center .dash-fresh { color: #9fc4d8; }
.command-center .dash-fresh i { box-shadow: none; }
.command-center .dash-fresh.stale { color: #ffcf7a; }
.command-center .dash-figs { margin-top: 4px; max-width: 560px; }
.command-center .dash-fig { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.16); }
.command-center .dash-fig strong,
.command-center .dash-fig span { color: #eaf4ff; }
.command-center .dash-fig small { color: #9fc4d8; }
.command-center .dash-fig.linked:hover { border-color: #7fe3d6; background: rgba(255,255,255,.12); }
.command-center .dash-fig.linked:focus-visible { outline-color: #7fe3d6; }
.command-center .dash-fig.warn strong { color: #ffcf7a; }
.command-center .dash-fig.bad strong { color: #ff9ba0; }
.command-center .cc-left { min-width: 0; }

/* ---- Desglose de la salud global ---------------------------------------- */
.dash-health-detail { margin-top: 12px; font-size: 12px; }
.dash-health-detail summary { cursor: pointer; color: var(--muted); font-weight: 600; }
.command-center .dash-health-detail summary { color: #cfe6f3; }
.command-center .dash-health-detail li,
.command-center .dash-health-detail li b { color: #eaf4ff; }
.command-center .dash-health-detail li small { color: #9fc4d8; }
.dash-health-detail summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; border-radius: 4px; }
.dash-health-detail ul { list-style: none; margin: 10px 0 0; padding: 0; display: flex;
  flex-direction: column; gap: 7px; }
.dash-health-detail li { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 4px 12px;
  align-items: baseline; }
.dash-health-detail li b { font-variant-numeric: tabular-nums; }
.dash-health-detail li small { grid-column: 1 / -1; color: var(--muted); }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

[data-theme="dark"] .dash-fig,
[data-theme="dark"] .dash-mod { background: var(--panel); }
[data-theme="dark"] .dash-state { background: var(--nav-soft); }

@media (prefers-reduced-motion: reduce) {
  .dash-skel span { animation: none; }
  .dash-fig.linked:hover { transform: none; }
  .dash-rank-track i { transition: none; }
}
@media (max-width: 900px) {
  .dash-rank li { grid-template-columns: minmax(90px, 1fr) auto auto; }
  .dash-rank .dash-rank-track { display: none; }
  .dash-list.findings .dash-pill { margin-left: 0; }
  .dash-feed li { grid-template-columns: 62px minmax(0, 1fr); }
}

/* ===== Vault — Fase 0 ===================================================== */
/* Modal propio en lugar de window.prompt/alert. Se monta en <body>, sobre el
   resto de la consola, y hereda los tokens de color del tema activo. */

.vault-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .6);
  backdrop-filter: blur(2px);
  z-index: 9998;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.vault-modal {
  background: var(--surface, #14161c);
  color: var(--text, #e9edf5);
  border: 1px solid var(--border, #2a2f3a);
  border-radius: 14px;
  box-shadow: 0 24px 64px rgba(0, 0, 0, .5);
  width: min(560px, 100%);
  max-height: 88vh;
  overflow: auto;
}

.vault-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border, #2a2f3a);
  position: sticky;
  top: 0;
  background: inherit;
}

.vault-modal-head h3 { margin: 0; font-size: 1.05rem; }
.vault-modal-body { padding: 18px 20px 22px; }

.vault-modal-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
}

.vault-field { display: block; margin-bottom: 14px; }
.vault-field > span { display: block; font-size: .82rem; opacity: .75; margin-bottom: 5px; }
.vault-field input,
.vault-field select,
.vault-field textarea {
  width: 100%;
  padding: 9px 11px;
  border-radius: 9px;
  border: 1px solid var(--border, #2a2f3a);
  background: var(--canvas, #0d0f14);
  color: inherit;
  font: inherit;
}
.vault-field textarea { resize: vertical; }
.vault-check { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; font-size: .9rem; }

.vault-secret-row { display: flex; gap: 6px; align-items: center; }
.vault-secret-row input { flex: 1; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

.vault-strength { display: block; margin-top: 6px; font-size: .78rem; }
.vault-strength.tone-bad  { color: var(--danger, #f2555a); }
.vault-strength.tone-warn { color: var(--warn, #e8a13a); }
.vault-strength.tone-good { color: var(--good, #3ecf8e); }

.vault-genopts {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 8px;
  font-size: .78rem;
  opacity: .8;
}
.vault-genopts input[type="number"] { width: 64px; padding: 3px 6px; }

/* Caja del secreto revelado: enmascarada por defecto, monoespaciada y
   seleccionable solo cuando esta visible. */
.vault-secret-box {
  margin: 14px 0;
  padding: 14px 16px;
  border-radius: 10px;
  border: 1px dashed var(--border, #2a2f3a);
  background: var(--canvas, #0d0f14);
}
.vault-secret-box code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.05rem;
  word-break: break-all;
  user-select: text;
}
.vault-secret-masked { letter-spacing: .18em; opacity: .55; user-select: none; }

.vault-timer { font-size: .8rem; opacity: .75; }

@media (max-width: 640px) {
  .vault-modal-backdrop { padding: 0; align-items: stretch; }
  .vault-modal { width: 100%; max-height: 100vh; border-radius: 0; }
}


/* ===================== COMMAND DECK · modulo Backup (Fase 0) ===================== */
.backup-banner { display:flex; gap:10px; align-items:flex-start; padding:12px 16px; border-radius:12px; margin-bottom:16px;
  background: color-mix(in srgb, var(--warning) 12%, var(--panel)); border:1px solid color-mix(in srgb, var(--warning) 40%, var(--line));
  color: var(--ink); font-size:13px; line-height:1.5; }
.backup-banner strong { color: var(--warning); }
.backup-help { display:inline-flex; align-items:center; justify-content:center; width:15px; height:15px; border-radius:50%;
  background: color-mix(in srgb, var(--warning) 22%, transparent); color: var(--warning); font-size:10px; font-weight:800; cursor:help; font-style:normal; }
.backup-row { cursor:pointer; }
.backup-row.open { background: color-mix(in srgb, var(--accent) 8%, transparent); }
.backup-detail-row td { background: color-mix(in srgb, var(--canvas) 60%, var(--panel)); }
.backup-detail { display:flex; flex-direction:column; gap:6px; padding:4px 2px; }
.backup-chip { display:inline-block; font-size:11px; padding:3px 9px; border-radius:8px; margin:2px 6px 2px 0;
  background: color-mix(in srgb, var(--muted) 14%, transparent); color: var(--ink); }

/* =========================================================================
   FASE 4 — SISTEMA VISUAL DEL DASHBOARD
   Va al final a propósito: es la capa que fija la semántica del color, el
   contraste AA y la escala tipográfica por encima de lo heredado.
   ========================================================================= */

/* ---- 1. Tokens semánticos ------------------------------------------------
   Regla de uso, y es una regla, no una sugerencia:

     --danger  ACCIÓN AHORA. Explotación confirmada, sin respaldo, fuera de
               soporte, SLA incumplido, salud por debajo de 50.
     --warn    DEGRADADO. Funciona pero se está deteriorando.
     --ok      CORRECTO. Nada que hacer.
     --info    NEUTRO. Navegación y referencia; no expresa gravedad.

   Faltaban `--bg`, `--text`, `--warn` y `--ok`, y dos reglas ya usaban
   `var(--text)` sin que existiera (caían al color heredado). Quedan definidos.

   Los tonos de marca sirven para RELLENO (barras, anillos, marcas), donde
   WCAG pide 3:1 por ser componentes gráficos. Sobre TEXTO no llegaban a
   4,5:1 — medido: éxito 4,01 · azul 4,14 · peligro 4,28 · aviso 4,44 — así
   que cada uno tiene su variante de texto, calculada bajando luminosidad en
   HSL y conservando tono y saturación. */
:root {
  --bg: var(--canvas);
  --text: var(--ink);
  --ok: var(--success);
  --warn: var(--warning);
  --info: var(--accent);
  --ok-text: #147d4e;        /* 5,16:1 sobre panel · 4,59:1 sobre lienzo */
  --warn-text: #9b6200;      /* 5,07 · 4,51 */
  --danger-text: #cd333e;    /* 5,07 · 4,51 */
  --info-text: #1374ad;      /* 5,09 · 4,52 */
  --action-bg: #12699e;      /* blanco encima: 5,93:1 */
}
/* En el tema oscuro los tonos de marca ya superan 4,5:1 sobre las dos
   superficies (medido: 5,82 el más bajo). No hacen falta variantes. */
[data-theme="dark"] {
  --bg: var(--canvas);
  --text: var(--ink);
  --ok: var(--success);
  --warn: var(--warning);
  --info: var(--accent);
  --ok-text: var(--success);
  --warn-text: var(--warning);
  --danger-text: var(--danger);
  --info-text: var(--accent);
  --action-bg: #14618f;
}

/* ---- 2. Aplicación de las variantes de texto ---------------------------- */
.dash-mod .dash-pill.ok, .dash-mod .dash-mark.ok, .dash-fig.ok strong { color: var(--ok-text); }
.dash-mod .dash-pill.warn, .dash-mod .dash-mark.warn,
.dash-fig.warn strong, .dash-link.warn, .dash-warn-text,
.dash-note.warn, .dash-coverage, .dash-sev-legend .warn { color: var(--warn-text); }
.dash-mod .dash-pill.bad, .dash-mod .dash-mark.bad,
.dash-fig.bad strong, .dash-link.bad, .dash-sev-legend .bad { color: var(--danger-text); }
.dash-fresh i { color: var(--ok-text); }
.dash-fresh.stale, .dash-fresh.stale i { color: var(--warn-text); }
.dash-fresh.critical, .dash-fresh.critical i { color: var(--danger-text); }
.dash-freshbar-text b, .dash-freshbar-ico { color: var(--warn-text); }
.dash-freshbar.critical .dash-freshbar-text b,
.dash-freshbar.critical .dash-freshbar-ico { color: var(--danger-text); }
.dash-link:hover, .dash-inline-link, .dash-more > .dash-link { color: var(--info-text); }
.primary-action { background: var(--action-bg); }
/* El texto sólo para lectores de pantalla no se ve: que no herede color de
   estado ni cuente en las auditorías de contraste. */
.sr-only { color: inherit; }

/* ---- 3. Ningún estado depende sólo del color ----------------------------
   Cada píldora lleva ya su texto; ahora lleva además una FORMA distinta en
   lugar del mismo punto redondo para los cuatro estados. */
.dash-pill::before { border-radius: 50%; }                                 /* ok: círculo */
.dash-pill.warn::before { border-radius: 1px; transform: rotate(45deg); }  /* aviso: rombo */
.dash-pill.bad::before { border-radius: 1px; }                             /* peligro: cuadrado */
.dash-pill.muted::before { border-radius: 50%; background: transparent;
  box-shadow: inset 0 0 0 1.5px currentColor; }                            /* sin dato: aro */

/* La matriz de cobertura ya usaba glifos distintos (✓ ! ✕ ? —); se les añade
   forma de contenedor para que se distingan también en escala de grises. */
.dash-mark.ok { border-radius: 50%; }
.dash-mark.warn { border-radius: 4px; }
.dash-mark.bad { border-radius: 4px; transform: rotate(45deg); }
.dash-mark.bad > i { transform: rotate(-45deg); }
.dash-mark.muted { border-radius: 50%; background: transparent;
  box-shadow: inset 0 0 0 1px var(--line); }

/* ---- 4. Escala de las barras de salud -----------------------------------
   No tenían escala: un 46 y un 74 se veían igual de malos sin saber dónde
   estaban los cortes. Se marcan los dos umbrales de la fórmula sobre la barra
   (50 = atención, 75 = estable) y se añade leyenda al panel. */
.mini-meter { position: relative; overflow: visible; }
.mini-meter > i { border-radius: 5px; }
.mini-meter::before, .mini-meter::after { content: ""; position: absolute; top: -2px; bottom: -2px;
  width: 1px; background: color-mix(in srgb, var(--ink) 38%, transparent); z-index: 2; }
.mini-meter::before { left: 50%; }
.mini-meter::after { left: 75%; }
.mini-meter i { background: var(--ok); }
.mini-meter.warn i { background: var(--warn); }
.mini-meter.bad i { background: var(--danger); }
.dash-scale-legend { display: flex; gap: 14px; flex-wrap: wrap; margin: 0; font-size: 10.5px;
  color: var(--muted); }
.dash-scale-legend b { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.dash-scale-legend > span { display: inline-flex; align-items: center; gap: 5px; }
.dash-scale-legend i { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.dash-scale-legend .ok i { background: var(--ok); }
.dash-scale-legend .warn i { background: var(--warn); }
.dash-scale-legend .bad i { background: var(--danger); }
.dash-scale-legend .tick i { width: 1px; height: 11px; border-radius: 0;
  background: color-mix(in srgb, var(--ink) 38%, transparent); }

/* ---- 5. Escala tipográfica ----------------------------------------------
   Base 16 con h2 de 18 daba una jerarquía casi nula: el título de un panel
   pesaba lo mismo que su contenido y una cifra podía medir lo mismo que su
   etiqueta. Tres niveles claros y separados:
     etiqueta   11,5 px  600  versalitas con interletraje
     título h2  15 px    600
     cifra KPI  30 px    700
   Ninguna cifra comparte tamaño con su etiqueta. */
.dash-mod-head h2 { font-size: 15px; font-weight: 600; letter-spacing: -.005em; line-height: 1.3; }
.dash-fig strong { font-size: 30px; font-weight: 700; letter-spacing: -.025em; }
.dash-fig span { font-size: 11.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); }
.dash-fig small { font-size: 11px; letter-spacing: 0; text-transform: none; }
.dash-table th { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.dash-sub { font-size: 11.5px; letter-spacing: .08em; }
/* Un panel estrecho no puede permitirse 30 px: la cifra rompería de línea. */
@media (max-width: 1399px) { .dash-fig strong { font-size: 27px; } }

/* ---- 6. La costura entre la cabecera oscura y la interfaz clara ---------
   La franja oscura terminaba en seco contra el lienzo claro y se leía como un
   bloque pegado, no como una decisión. Ahora comparte radio y sombra con los
   paneles, lleva un filo superior del color de acento — el mismo que usa el
   resto de la consola para decir «esto es navegable» — y se apoya en una
   sombra proyectada que la asienta sobre el lienzo en vez de recortarla. */
.command-center { border: 1px solid #10314a; border-top: 2px solid var(--accent);
  box-shadow: 0 10px 30px -12px rgba(11, 36, 64, .55); }
.command-center::before { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 34px;
  background: linear-gradient(to bottom, transparent, rgba(238, 242, 247, .10)); pointer-events: none; }
[data-theme="dark"] .command-center { box-shadow: 0 10px 30px -14px rgba(0, 0, 0, .7); }
[data-theme="dark"] .command-center::before { background: none; }

/* =========================================================================
   FASE 5 — VISUALIZACIONES
   Todo SVG propio: cero dependencias añadidas.
   ========================================================================= */

/* Tabla alternativa de cada gráfico: fuera de la vista, dentro del árbol de
   accesibilidad. `display:none` la sacaría de los dos. */
.sr-only, .chart-data { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

.chart-empty { margin: 0; padding: 12px 0; font-size: 11.5px; color: var(--muted); }
.chart-empty.insufficient { font-style: italic; }

/* ---- Delta de un KPI ---------------------------------------------------- */
.dash-delta { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 700;
  padding: 2px 7px; border-radius: 999px; white-space: nowrap;
  background: color-mix(in srgb, var(--muted) 10%, transparent); color: var(--muted); }
.dash-delta i { font-style: normal; font-size: 8px; }
.dash-delta small { font-weight: 500; opacity: .8; }
.dash-delta.good { color: var(--ok-text); background: color-mix(in srgb, var(--ok) 12%, transparent); }
.dash-delta.bad { color: var(--danger-text); background: color-mix(in srgb, var(--danger) 11%, transparent); }
.dash-delta.none { font-weight: 500; font-style: italic; }

/* ---- Sparkline ---------------------------------------------------------- */
.dash-spark { display: inline-flex; align-items: center; color: var(--muted); }
.dash-spark.ok { color: var(--ok); }
.dash-spark.bad { color: var(--danger); }
.dash-spark-cell { white-space: nowrap; }
.dash-spark-cell .dash-delta { margin-left: 6px; vertical-align: middle; }

/* ---- Barra apilada ------------------------------------------------------ */
.dash-stack-chart { display: flex; flex-direction: column; gap: 8px; }
.dash-stack-bar { display: flex; height: 14px; border-radius: 7px; overflow: hidden;
  background: var(--ring-track); }
.dash-stack-bar i { height: 100%; }
.dash-stack-bar i.ok { background: var(--ok); }
.dash-stack-bar i.warn { background: var(--warn); }
.dash-stack-bar i.bad { background: var(--danger); }
.dash-stack-legend { display: flex; flex-wrap: wrap; gap: 12px; font-size: 11px; color: var(--muted); }
.dash-stack-legend > span { display: inline-flex; align-items: center; gap: 5px; }
.dash-stack-legend > span.zero { opacity: .45; }
.dash-stack-legend i { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.dash-stack-legend .ok i { background: var(--ok); }
.dash-stack-legend .warn i { background: var(--warn); }
.dash-stack-legend .bad i { background: var(--danger); }
.dash-stack-legend .muted i { background: var(--muted); }
.dash-stack-legend b { color: var(--text); font-variant-numeric: tabular-nums; }

/* ---- Donut de cobertura ------------------------------------------------- */
.dash-cov-head { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.dash-cov-head .dash-note { flex: 1 1 200px; }
.dash-cov-donut { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.dash-cov-donut .dash-donut-total { font-size: 24px; font-weight: 800; fill: var(--text);
  font-variant-numeric: tabular-nums; }
.dash-cov-donut .dash-donut-lbl { font-size: 10px; fill: var(--muted); letter-spacing: .06em;
  text-transform: uppercase; }
.dash-cov-donut .dash-legend { display: flex; flex-direction: column; gap: 5px; font-size: 11.5px; }
.dash-cov-donut .dash-leg { display: flex; align-items: center; gap: 7px; color: var(--muted); }
.dash-cov-donut .dash-leg span { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.dash-cov-donut .dash-leg strong { margin-left: auto; color: var(--text);
  font-variant-numeric: tabular-nums; }

/* ---- Línea de flujo de tickets ------------------------------------------ */
.dash-flow { display: flex; flex-direction: column; gap: 7px; }
.dash-flow svg { display: block; }
.dash-flow-legend { display: flex; flex-wrap: wrap; gap: 12px; font-size: 11px; color: var(--muted); }
.dash-flow-legend > span { display: inline-flex; align-items: center; gap: 5px; }
.dash-flow-legend i { width: 10px; height: 2.5px; border-radius: 2px; flex: none; }
.dash-flow-legend .warn i { background: var(--warn); }
.dash-flow-legend .ok i { background: var(--ok); }
.dash-flow-legend .ok { color: var(--ok-text); }
.dash-flow-legend .warn { color: var(--warn-text); }
.dash-flow-legend .bad { color: var(--danger-text); }
.dash-flow-legend b { font-variant-numeric: tabular-nums; }

/* ---- Mapa de riesgo cliente × dominio ----------------------------------- */
.dash-matrix-tools { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.dash-matrix-search input { width: 200px; max-width: 100%; padding: 6px 10px; font-size: 12.5px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--text); }
.dash-matrix-search input:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.dash-matrix-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--muted); cursor: pointer; }
.dash-matrix-toggle input:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.dash-riskmatrix td.dash-matrix-cell { padding: 4px 6px 4px 0; }
.dash-heat { display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  min-width: 46px; padding: 5px 8px; border-radius: 7px; border: 1px solid transparent;
  font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; cursor: pointer;
  background: color-mix(in srgb, var(--muted) 9%, transparent); color: var(--muted); }
.dash-heat i { font-style: normal; font-size: 9px; }
.dash-heat.static { cursor: default; min-width: 0; }
.dash-heat.ok { background: color-mix(in srgb, var(--ok) 13%, transparent); color: var(--ok-text); }
.dash-heat.warn { background: color-mix(in srgb, var(--warn) 17%, transparent); color: var(--warn-text); }
.dash-heat.bad { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger-text); }
.dash-heat:not(.static):hover { border-color: currentColor; }
.dash-heat:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.dash-pager { display: flex; align-items: center; gap: 12px; justify-content: flex-end; font-size: 12px; }
.dash-pager button[disabled] { opacity: .45; cursor: not-allowed; }

/* =========================================================================
   FASE 6 — CONTROLES, DENSIDAD E IMPRESIÓN
   ========================================================================= */
.dash-controls { display: flex; flex-direction: column; gap: 10px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel); }
.dash-controls-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.dash-ctl { display: inline-flex; align-items: center; gap: 7px; font-size: 11.5px;
  font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.dash-ctl select { font-size: 12.5px; font-weight: 500; letter-spacing: 0; text-transform: none;
  padding: 5px 8px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); color: var(--text); }
.dash-ctl select:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.dash-ctl-note { font-size: 11px; color: var(--muted); flex: 1 1 240px; min-width: 0; }
.dash-ctl-label { font-size: 11.5px; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); }

.dash-views { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; flex: 1 1 260px; }
.dash-view-chip { display: inline-flex; align-items: center; border: 1px solid var(--line);
  border-radius: 999px; overflow: hidden; }
.dash-view-go { border: 0; background: none; font: inherit; font-size: 12px; font-weight: 600;
  padding: 4px 10px; color: var(--info-text); cursor: pointer; }
.dash-view-del { border: 0; border-left: 1px solid var(--line); background: none; cursor: pointer;
  padding: 4px 8px; color: var(--muted); font-size: 13px; line-height: 1; }
.dash-view-go:focus-visible, .dash-view-del:focus-visible { outline: 2px solid var(--primary);
  outline-offset: -2px; }

.dash-controls-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-left: auto; }
.dash-density { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.dash-density button { border: 0; background: none; font: inherit; font-size: 12px; font-weight: 600;
  padding: 5px 11px; color: var(--muted); cursor: pointer; }
.dash-density button.on { background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--info-text); }
.dash-density button:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }

.dash-panels-menu { position: relative; }
.dash-panels-menu > summary { cursor: pointer; font-size: 12px; font-weight: 600; color: var(--muted);
  padding: 5px 11px; border: 1px solid var(--line); border-radius: 8px; list-style: none; }
.dash-panels-menu > summary::-webkit-details-marker { display: none; }
.dash-panels-menu > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.dash-panels-menu[open] > summary { border-color: var(--primary); }
.dash-panels-menu ul { position: absolute; right: 0; top: calc(100% + 6px); z-index: 30;
  min-width: 268px; max-height: 320px; overflow: auto; margin: 0; padding: 8px;
  list-style: none; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel); box-shadow: var(--elev-2); }
.dash-panels-menu li { display: flex; align-items: center; gap: 8px; padding: 3px 4px;
  font-size: 12.5px; }
.dash-panels-menu li label { display: flex; align-items: center; gap: 7px; flex: 1; cursor: pointer; }
.dash-panel-move { display: inline-flex; gap: 2px; }
.dash-panel-move button { border: 1px solid var(--line); background: var(--panel); cursor: pointer;
  width: 22px; height: 22px; border-radius: 5px; color: var(--muted); line-height: 1; }
.dash-panel-move button:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.dash-panels-menu > .ghost-action { position: absolute; right: 0; top: calc(100% + 334px); }

/* ---- Densidad compacta ---------------------------------------------------
   No es "todo más pequeño": es menos AIRE. Los tamaños de letra de la escala
   tipográfica no se tocan, porque encogerlos rompería el contraste de
   jerarquía que se acaba de construir. */
.dash-page.density-compacta { --dash-band-gap: 16px; }
.dash-page.density-compacta .dash-grid { gap: 10px; }
.dash-page.density-compacta .dash-mod { gap: 8px; padding: 13px 15px; }
.dash-page.density-compacta .dash-figs { gap: 7px; }
.dash-page.density-compacta .dash-fig { padding: 7px 9px; }
.dash-page.density-compacta .dash-table td { padding: 6px 10px 6px 0; }
.dash-page.density-compacta .dash-list li > .dash-link { padding: 6px 0; }
.dash-page.density-compacta .command-center { padding: 10px 18px; }

/* ---- Impresión / PDF -----------------------------------------------------
   El PDF lo genera el navegador (Imprimir → Guardar como PDF): en el servidor
   haría falta un navegador sin interfaz que esta máquina no tiene. A cambio,
   lo impreso es exactamente lo que el operador ve, con la marca del MSP y con
   TODAS las notas metodológicas desplegadas — que es justo lo que el cliente
   debe recibir. */
.dash-print-head { display: none; }
@media print {
  @page { size: A4 portrait; margin: 12mm 10mm 14mm; }
  body { background: #fff; }
  .sidebar, .topbar, .nav-toggle, .nav-scrim, .dash-controls,
  .dash-mod-tools .ghost-action, .dash-pager, .dash-matrix-tools { display: none !important; }
  .app-shell { display: block; }
  .workspace { padding: 0; }
  .dash-print-head { display: flex; justify-content: space-between; align-items: flex-start;
    gap: 20px; padding: 0 0 12px; margin-bottom: 14px; border-bottom: 2px solid #14202e; }
  .dash-print-brand { margin: 0; font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
    color: #5a6b7f; }
  .dash-print-head h1 { margin: 2px 0 0; font-size: 18px; }
  .dash-print-meta { text-align: right; font-size: 10px; color: #5a6b7f; }
  .dash-print-meta p { margin: 0 0 2px; }
  .dash-print-meta .warn { color: #9b6200; max-width: 46ch; }
  /* Nada de secretos plegados en un documento que se manda a un cliente. */
  details { display: block !important; }
  details > summary { list-style: none; font-weight: 700; }
  details:not([open]) > *:not(summary) { display: revert !important; }
  .dash-method[open] > summary, .dash-method > summary { color: #5a6b7f; }
  .dash-mod { break-inside: avoid; page-break-inside: avoid; box-shadow: none;
    border: 1px solid #d7e0ea; }
  .dash-band { break-inside: auto; }
  .command-center { background: #14202e !important; -webkit-print-color-adjust: exact;
    print-color-adjust: exact; }
  .dash-mod.fresh-critical { opacity: 1; }
  /* Las tablas alternativas siguen ocultas: en papel duplicarían cada gráfico. */
}

/* =========================================================================
   FASE 7 — ACCIONES DE MAYOR IMPACTO
   ========================================================================= */
.dash-actions { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.dash-actions > li { display: flex; gap: 12px; padding: 12px 0; border-top: 1px solid var(--line); }
.dash-actions > li:first-child { border-top: 0; }
.dash-action-rank { flex: none; width: 24px; height: 24px; border-radius: 7px;
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  background: color-mix(in srgb, var(--muted) 12%, transparent); color: var(--muted);
  font-variant-numeric: tabular-nums; }
.dash-actions > li.kev .dash-action-rank { background: color-mix(in srgb, var(--danger) 14%, transparent);
  color: var(--danger-text); }
.dash-action-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.dash-action-head { margin: 0; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  font-size: 13.5px; }
.dash-action-effect { font-size: 12px; font-weight: 700; }
.dash-action-effect.bad { color: var(--danger-text); }
.dash-action-effect.muted { color: var(--muted); }
.dash-action-meta { margin: 0; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 11.5px; }
.dash-action-hosts { margin: 0; display: flex; gap: 6px; flex-wrap: wrap; }
.dash-chip { border: 1px solid var(--line); background: var(--panel); border-radius: 999px;
  padding: 2px 9px; font: inherit; font-size: 11px; font-weight: 600; color: var(--muted);
  cursor: pointer; }
.dash-chip:hover { border-color: var(--primary); color: var(--info-text); }
.dash-chip:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.dash-actions code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; }

/* =========================================================================
   FASE 8 — ACCESIBILIDAD
   ========================================================================= */

/* Foco visible en TODO lo clicable del panel. Eran decenas de botones y el
   estilo por defecto del navegador desaparecía sobre los fondos de color. */
.dash-page button:focus-visible,
.dash-page a:focus-visible,
.dash-page summary:focus-visible,
.dash-page [tabindex]:focus-visible,
.dash-page input:focus-visible,
.dash-page select:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 6px;
}
/* Sobre la cabecera oscura el azul de acento no destaca: allí el foco es claro. */
.command-center button:focus-visible,
.command-center summary:focus-visible { outline-color: #7fe3d6; }
/* Un anillo de foco recortado no se ve: los paneles con marca de agua o
   contenido desplazable dejan sitio. */
.dash-mod:focus-within { overflow: visible; }

/* Ráfaga de eventos idénticos, plegada. */
.dash-burst > summary { cursor: pointer; font-size: 11px; font-weight: 600; color: var(--muted);
  list-style: none; }
.dash-burst > summary::-webkit-details-marker { display: none; }
.dash-burst > summary::before { content: "×"; margin-right: 3px; }
.dash-burst ul { list-style: none; margin: 4px 0 0; padding: 0 0 0 10px;
  border-left: 2px solid var(--line); font-size: 10.5px; color: var(--muted); }
.dash-burst li { padding: 1px 0; }

/* La región en vivo no ocupa sitio pero anuncia los cambios de recuento. */
.dash-live { position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
  .dash-ring-fill, .mini-meter i, .dash-rank-track i { transition: none !important; }
}


/* ==========================================================================
   COMPOSICIÓN DE LA MAQUETA — franja superior del Dashboard
   Bloque ADITIVO: no modifica ninguna regla anterior. Da estructura y color
   base a las tarjetas nuevas para que funcionen con o sin la piel; la piel solo
   refina radios, sombras y tipografía encima.
   ========================================================================== */

/* Tonos de CATEGORÍA para la barra apilada. Los que ya existían (.ok/.warn/.bad)
   son de estado y no valen aquí: un sistema operativo no es «bueno» ni «malo». */
.dash-stack-bar i.c1, .dash-stack-legend .c1 i { background: var(--primary); }
.dash-stack-bar i.c2, .dash-stack-legend .c2 i { background: var(--violet); }
.dash-stack-bar i.c3, .dash-stack-legend .c3 i { background: var(--teal); }
.dash-stack-bar i.c4, .dash-stack-legend .c4 i { background: var(--rose); }
.dash-stack-bar i.c5, .dash-stack-legend .c5 i { background: var(--muted); }

/* Rejilla de la franja: la columna derecha apila salud y bandeja de trabajo. */
/* La columna derecha se comporta como un panel mas de la rejilla: hereda su
   `--span` y, cuando la rejilla pasa a `auto-fit` por debajo de 1400 px, deja
   de forzar columnas. Sin esto se quedaba con `span 4` sobre una rejilla que ya
   no tiene doce columnas y desbordaba 36 px a 1024. */
.dash-grid-maqueta { align-items: start; }
/* Alto MÍNIMO fijado por el operador tirando del borde inferior. Es un mínimo,
   nunca un alto: una tarjeta cuyo contenido crece (más filas en su tabla) sigue
   creciendo, así que redimensionar no puede recortar un dato. */
.dash-mod { min-height: var(--minh, 0); }

/* ---- Analítica de la flota ---- */
/* La fila envuelve, pero sus dos hijos siguen sin poder bajar de su ancho de
   contenido: el `min-width: auto` implicito de flex. Con `min-width: 0` si
   encogen, y la leyenda ademas envuelve sus propias marcas en lugar de
   desbordar. Sin ambas cosas la pagina se iba 23 px a 380. */
.dash-analytics-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.dash-analytics-top > * { min-width: 0; }
/* Leyenda propia: `.dash-leg` da a sus `span` un cuadrado de 11 px porque alli
   el `span` ES la muestra de color. Aqui el `span` es la etiqueta y la muestra
   es el `i`, asi que reutilizarla aplastaba el texto a 30 px y lo desbordaba. */
.dash-analytics-leg { display: flex; flex-wrap: wrap; gap: 6px 14px; flex: none;
  max-width: 100%; font-size: 11.5px; color: var(--muted); }
.dash-analytics-leg span { display: inline-flex; align-items: center; gap: 6px; }
.dash-analytics-leg i { width: 9px; height: 9px; border-radius: 3px; flex: none; }
.dash-analytics-big { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.dash-analytics-big strong { font-size: 34px; font-weight: 800; letter-spacing: -.045em; line-height: 1; }
/* La reserva de altura es la del area de check-ins cuando HAYA historico. No
   se estira mas: un hueco grande con una frase en medio se lee como pantalla
   rota, no como dato que falta. */
.dash-analytics-chart { min-height: 128px; display: grid; place-items: center; }
.dash-analytics-foot { display: flex; align-items: flex-start; gap: 22px; flex-wrap: wrap;
  padding-top: 16px; border-top: 1px solid var(--line); }
.dash-donut-pct { font-size: 17px; font-weight: 800; fill: var(--text);
  letter-spacing: -.03em; }
.dash-donuts { display: grid; grid-template-columns: repeat(3, minmax(96px, 1fr)); gap: 14px;
  text-align: center; flex: 1.35; min-width: 280px; }
.dash-donut-cell { display: flex; flex-direction: column; align-items: center; }
.dash-donut-cap { margin: 8px 0 0; font-size: 12px; font-weight: 600; color: var(--ink); }
.dash-donut-sub { margin: 2px 0 0; font-size: 10.5px; color: var(--muted); }
.dash-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 0; flex: 1; min-width: 250px; }
.dash-stat { display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  padding: 0 18px; border: 0; border-left: 1px solid var(--line); background: none;
  color: inherit; font: inherit; text-align: left; cursor: pointer; }
.dash-stat:first-child { padding-left: 0; border-left: 0; }
.dash-stat:hover .dash-stat-v { color: var(--primary); }
.dash-stat-v { font-size: 21px; font-weight: 800; letter-spacing: -.035em; color: var(--ink); }
.dash-stat-k { font-size: 11px; color: var(--muted); }

/* ---- Salud global con penalizaciones ---- */
.dash-health-row { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.dash-health-pen { flex: 1; min-width: 190px; display: flex; flex-direction: column; gap: 2px; }
.dash-pen-row { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; padding: 7px 0; border: 0; border-top: 1px solid var(--line);
  background: none; color: var(--ink-2); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; }
.dash-pen-row:first-child { border-top: 0; }
.dash-pen-row:hover span { color: var(--primary); }
.dash-pen-row b { font-variant-numeric: tabular-nums; }
/* El anillo nacio dentro de la franja azul, donde su cifra es blanca. Aqui vive
   en una tarjeta blanca: sin esto la salud queda blanca sobre blanco (1:1). */
.dash-health-row .dash-ring-center strong { color: var(--text); }
.dash-health-row .dash-ring-center span { color: var(--text); font-size: 13px; font-weight: 700; }
.dash-health-row .dash-ring-center small { color: var(--muted); font-size: 11px; }
.dash-pen-row b.bad { color: var(--danger-text, var(--danger)); }
.dash-pen-row b.warn { color: var(--warn-text, var(--warning)); }
.dash-pen-row b.ok { color: var(--ok-text, var(--success)); }
.dash-pen-row b.muted { color: var(--muted); }

/* ---- Bandeja de trabajo (tarjeta de acento) ---- */
.dash-accent { position: relative; overflow: hidden; color: #fff; border: 0;
  background: linear-gradient(150deg, #2059d4 0%, #1a45bd 55%, #16307a 100%); }
.dash-accent::after { content: ""; position: absolute; width: 190px; height: 190px;
  right: -62px; top: -62px; border-radius: 50%; background: rgba(255,255,255,.09); pointer-events: none; }
.dash-accent h2 { margin: 6px 0 10px; font-size: 19px; font-weight: 800; letter-spacing: -.03em; color: #fff; }
.dash-accent-eyebrow { position: relative; margin: 0; font-family: var(--mono); font-size: 9px;
  letter-spacing: .2em; text-transform: uppercase; color: #cfe0ff; }
.dash-accent-item { position: relative; display: flex; align-items: center; gap: 10px; width: 100%;
  margin-top: 8px; padding: 10px 12px; border: 1px solid rgba(255,255,255,.18); border-radius: 13px;
  background: rgba(255,255,255,.12); color: #fff; font: inherit; font-size: 12px;
  text-align: left; cursor: pointer; }
.dash-accent-item:hover { background: rgba(255,255,255,.2); }
/* El distintivo se OSCURECE en vez de aclararse: un velo blanco sobre el azul
   dejaba la cifra blanca en 3,25:1. Con velo oscuro el par sube por encima
   de 4,5:1 sin cambiar el aspecto de la pieza. */
.dash-accent-n { display: grid; place-content: center; width: 22px; height: 22px; flex: none;
  border-radius: 8px; background: rgba(6, 22, 62, .55); font-size: 10.5px; font-weight: 800; }
.dash-accent-go { margin-left: auto; opacity: .85; }
.dash-accent-btn { position: relative; margin-top: 14px; padding: 11px 16px; border: 0;
  border-radius: 12px; background: #fff; color: #14417f; font: inherit; font-size: 12.5px;
  font-weight: 700; cursor: pointer; }
.dash-accent-empty { position: relative; margin: 0; font-size: 12.5px; color: #d6e6ff; }

/* ---- Filas con icono (sistemas operativos) ---- */
.dash-item-ico { display: grid; place-content: center; width: 34px; height: 34px; flex: none;
  border-radius: 11px; font-size: 14px; font-weight: 700;
  background: var(--card-2, var(--canvas)); color: var(--muted); }
/* Un 12 % de tinte aclaraba el fondo lo justo para dejar el glifo en 4,34:1.
   Con 7 % el par vuelve a pasar sin tocar el color del texto. */
.dash-item-ico.bad { background: color-mix(in srgb, var(--danger) 7%, transparent); color: var(--danger-text, var(--danger)); }
.dash-item-ico.muted { background: color-mix(in srgb, var(--muted) 12%, transparent); color: var(--muted); }
.dash-item-tx { min-width: 0; flex: 1; }
.dash-item-tx b { display: block; font-size: 12.8px; font-weight: 600; color: var(--ink); }
.dash-item-tx span { display: block; margin-top: 2px; font-size: 10.8px; color: var(--muted); }

@media (max-width: 900px) {
  .dash-table time { white-space: normal; word-break: break-word; }
  .dash-analytics-foot { flex-direction: column; }
  .dash-stats { width: 100%; }
  .dash-stat { padding-left: 0; border-left: 0; }
}

/* ==========================================================================
   EDITOR DE DISPOSICIÓN
   Solo se ve dentro del modo. Fuera de él, ni una regla aplica y ni un nodo
   existe: el marcado de los tiradores no se genera.
   ========================================================================== */
.dash-edit-toggle { padding: 7px 14px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel); color: var(--text); font: inherit; font-size: 12.5px;
  font-weight: 600; cursor: pointer; }
.dash-edit-toggle:hover { border-color: var(--primary); }
/* Azul SÓLIDO, no `--primary`: en tema oscuro ese token es un azul claro y el
   texto blanco encima cae a 2,54:1. Estas piezas son cromo de control y tienen
   que leerse igual en los dos temas, así que fijan su propio azul (5,17:1 con
   blanco). Misma corrección que la del elemento activo de la navegación. */
.dash-edit-toggle.on { background: var(--sk-brand-solid, #2563eb);
  border-color: var(--sk-brand-solid, #2563eb); color: #fff; }

.dash-edit-hint { margin: 0 0 14px; padding: 11px 14px; border-radius: 12px;
  border: 1px dashed color-mix(in srgb, var(--primary) 45%, var(--line));
  background: color-mix(in srgb, var(--primary) 6%, transparent);
  font-size: 12.5px; line-height: 1.55; color: var(--text); }

/* Dentro del modo, el contenido de la tarjeta queda inerte: si no, cada
   arrastre acabaría pulsando el «Ver equipos» que hay debajo del puntero. */
.dash-editing .dash-mod > *:not(.dash-grab):not(.dash-rz) { pointer-events: none; }
/* El sitio para el asa se abre con MARGEN, no con relleno. Esto es lo que hace
   que el tamaño que ves editando sea el que queda al terminar: el margen vive
   FUERA de la caja, así que la tarjeta mide exactamente lo mismo dentro y fuera
   del modo. Con relleno (dentro de la caja) la tarjeta era 28 px más alta al
   editar y encogía al salir —el tamaño «no correspondía» a lo que se había
   ajustado—. El asa se coloca en ese margen, encima de la tarjeta, sin tapar el
   título. */
.dash-page.dash-editing .dash-mod { position: relative; margin-top: 36px;
  outline: 1px dashed color-mix(in srgb, var(--primary) 40%, transparent);
  outline-offset: 3px; user-select: none; cursor: move; }
/* Toda la tarjeta arrastra: al pasar por encima se realza para que se note que
   es agarrable, no solo el asa. Los tiradores llevan su propio cursor y se
   sientan por encima, así que sobre un borde sigue mandando el de redimensionar. */
.dash-page.dash-editing .dash-mod:hover {
  outline-color: color-mix(in srgb, var(--primary) 70%, transparent); }
.dash-editing .dash-mod.dash-dragging { opacity: .85; outline-style: solid;
  outline-color: var(--primary); z-index: 3; }

.dash-grab { position: absolute; top: -30px; left: 0; z-index: 4; display: flex; align-items: center;
  gap: 7px; max-width: 100%; padding: 5px 10px; border: 0; border-radius: 9px;
  background: var(--sk-brand-solid, #2563eb); color: #fff; font: inherit; font-size: 11px;
  font-weight: 700; cursor: grab; touch-action: none; }
.dash-grab:active { cursor: grabbing; }
.dash-grab-tx { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.dash-rz { position: absolute; z-index: 4; background: transparent; touch-action: none; }
.dash-rz::after { content: ""; position: absolute; inset: 0; margin: auto; border-radius: 99px;
  background: color-mix(in srgb, var(--primary) 55%, transparent); }
.dash-rz:hover::after, .dash-rz:focus-visible::after { background: var(--primary); }
.dash-rz:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* Borde derecho: cambia el ancho en columnas. Zona de agarre ancha para no
   tener que apuntar a una tira de píxeles. */
.dash-rz-x { top: 14px; bottom: 14px; right: -9px; width: 20px; cursor: ew-resize; }
.dash-rz-x::after { width: 4px; height: 46px; }
/* Borde inferior: cambia el alto mínimo. */
.dash-rz-y { left: 14px; right: 14px; bottom: -9px; height: 20px; cursor: ns-resize; }
.dash-rz-y::after { height: 4px; width: 46px; }
/* Esquina: las dos a la vez. */
.dash-rz-xy { right: -9px; bottom: -9px; width: 22px; height: 22px; cursor: nwse-resize; }
.dash-rz-xy::after { width: 9px; height: 9px; border-radius: 3px; }

/* Por debajo de 1400 px la rejilla abandona las doce columnas y pasa a
   `auto-fit`: ahí el ancho en columnas no describe nada, así que su tirador
   se retira en vez de mentir. Mover y cambiar el alto siguen funcionando. */
@media (max-width: 1400px) {
  .dash-rz-x, .dash-rz-xy { display: none; }
}
@media print { .dash-grab, .dash-rz, .dash-edit-hint, .dash-edit-toggle { display: none !important; } }
