/* Sistema de diseño "Obsidian Monitor" (docs/print-design): paleta Material dark
   con acentos vibrantes, Inter + JetBrains Mono, sidebar fija y tarjetas glass. */

:root {
  /* superficies (tonal layering) */
  --bg: #10131a;
  --surface-lowest: #0b0e15;
  --panel: #191b23;
  --panel-mid: #1d2027;
  --panel-high: #272a31;
  --panel-highest: #32353c;
  --border: #424754;

  /* texto */
  --text: #e1e2ec;
  --text-secondary: #c2c6d6;
  --muted: #8c909f;

  /* semánticos vibrantes */
  --up: #4edea3;
  --degraded: #ffb786;
  --down: #e74c3c;
  --unknown: #8c909f;

  /* primario (periwinkle / electric blue) */
  --accent: #adc6ff;
  --accent-strong: #4d8eff;
  --on-accent: #00285d;

  --danger-solid: #93000a;
  --on-danger-solid: #ffdad6;

  /* fondo "glass" reutilizado por tarjetas/tablas; variables propias para que
     los sitios que las usan (paneles embebibles y el Lienzo) puedan tener
     tema claro sin tocar el resto de la app, que sigue siempre en oscuro */
  --glass-bg: rgba(29, 32, 39, .6);
  --glass-header-bg: rgba(11, 14, 21, .55);
  --glass-type-bg: rgba(173, 198, 255, .12);

  --radius: 8px;
  --radius-lg: 12px;
  --shadow-ambient: 0 10px 25px rgba(0, 0, 0, .5);
}

/* tema claro: lo usan /canvas y los paneles embebibles (?theme=light), ver
   theme-toggle en canvas.js y el selector "Tema" del generador de paneles;
   el resto de la app siempre se sirve con la paleta oscura de arriba */
:root[data-theme="light"] {
  --bg: #f2f3f7;
  --surface-lowest: #ffffff;
  --panel: #ffffff;
  --panel-mid: #eef0f4;
  --panel-high: #e3e6ee;
  --panel-highest: #d5d9e3;
  --border: #cdd2dd;

  --text: #1b1e27;
  --text-secondary: #454a58;
  --muted: #666c7c;

  --up: #0f9d68;
  --degraded: #b5650a;
  --down: #c62f28;
  --unknown: #666c7c;

  --accent: #2f5fd6;
  --accent-strong: #2f5fd6;
  --on-accent: #ffffff;

  --danger-solid: #c62f28;
  --on-danger-solid: #ffffff;

  --glass-bg: rgba(255, 255, 255, .75);
  --glass-header-bg: rgba(230, 232, 238, .8);
  --glass-type-bg: rgba(47, 95, 214, .1);

  --shadow-ambient: 0 10px 25px rgba(27, 30, 39, .12);
}

* { box-sizing: border-box; }

html { background: var(--bg); }

body {
  margin: 0 auto;
  max-width: 1600px;
  display: flex;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

.mono, td.mono {
  font-family: "JetBrains Mono", ui-monospace, "Cascadia Mono", monospace;
  font-size: .82rem;
}

.material-symbols-outlined {
  font-size: 20px;
  line-height: 1;
  vertical-align: middle;
  font-variation-settings: "wght" 400;
}
.msi-fill { font-variation-settings: "FILL" 1, "wght" 400; }

/* ---------- barra lateral de navegación ---------- */

.sidenav {
  /* sticky (no fixed) para que participe en el layout y el conjunto
     sidebar + contenido pueda centrarse con el max-width del body */
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
  flex: 0 0 232px;
  width: 232px;
  padding: 1.2rem 1rem;
  background: var(--panel);
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: .4rem;
  z-index: 50;
}
.sidenav .brand { padding: 0 .5rem; margin-bottom: 1.6rem; }
.sidenav .brand h1 {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--accent);
  display: flex;
  align-items: center;
  gap: .55rem;
}
.sidenav .brand h1 a {
  color: inherit;
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: .55rem;
}
.brand-icon { width: 28px; height: 28px; flex: 0 0 auto; }
.sidenav .brand p {
  margin: .2rem 0 0;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .05em;
  color: var(--muted);
}
.sidenav nav { display: flex; flex-direction: column; gap: .35rem; }
.sidenav nav a {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .55rem .7rem;
  border-radius: var(--radius);
  color: var(--text-secondary);
  text-decoration: none;
  font-size: .9rem;
  transition: background .15s ease, color .15s ease;
}
.sidenav nav a:hover { background: var(--panel-high); color: var(--text); }
.sidenav nav a.active {
  background: #00a572;
  color: #00311f;
  font-weight: 700;
}
.sidenav nav a.subitem {
  margin-left: 1.4rem;
  padding: .4rem .7rem;
  font-size: .84rem;
  background: rgba(78, 222, 163, .1);
  color: var(--up);
  font-weight: 600;
}

/* grupo "Opciones" en árbol dentro de la sidebar */
.nav-group { display: flex; flex-direction: column; }
.nav-toggle {
  display: flex;
  align-items: center;
  gap: .6rem;
  width: 100%;
  padding: .55rem .7rem;
  border-radius: var(--radius);
  background: none;
  border: none;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: .9rem;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.nav-toggle:hover { background: var(--panel-high); color: var(--text); }
.nav-group.open .nav-toggle { color: var(--text); }
.nav-toggle .nav-chevron { margin-left: auto; font-size: 18px; transition: transform .15s ease; }
.nav-group.open .nav-toggle .nav-chevron { transform: rotate(180deg); }

.nav-tree {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  margin: .1rem 0 0 1.05rem;
  padding-left: .65rem;
  border-left: 1px solid var(--border);
  max-height: 0;
  overflow: hidden;
  transition: max-height .2s ease;
}
.nav-group.open .nav-tree { max-height: 20rem; margin-top: .3rem; margin-bottom: .2rem; }
.nav-tree-item {
  display: flex;
  align-items: center;
  gap: .55rem;
  width: 100%;
  padding: .42rem .6rem;
  border-radius: 6px;
  background: none;
  border: none;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: .82rem;
  text-align: left;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.nav-tree-item .material-symbols-outlined { font-size: 17px; }
.nav-tree-item:hover { background: var(--panel-high); color: var(--accent); }
.nav-tree-item.nav-tree-danger:hover { color: var(--down); background: rgba(231, 76, 60, .1); }

/* ---------- área principal ---------- */

.content {
  flex: 1;
  padding: 1.6rem 2.2rem 3rem;
  min-width: 0;
  border-right: 1px solid var(--border);
}

/* cabecera de página */
.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.4rem;
}
.page-header .page-title {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--accent);
}
.page-eyebrow {
  display: flex;
  align-items: center;
  gap: .4rem;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--up);
  margin-bottom: .3rem;
}
.live-line {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin-top: .35rem;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .03em;
  color: var(--muted);
}
.panel-filters-line {
  margin: .3rem 0 0;
  font-size: .78rem;
}
.live-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--up);
  animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}
.page-meta {
  display: flex;
  align-items: center;
  gap: .8rem;
  flex-wrap: wrap;
  margin-top: .4rem;
  color: var(--text-secondary);
}
.header-nav { display: flex; gap: .5rem; align-items: center; }
.header-nav a {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  color: var(--text);
  text-decoration: none;
  font-size: .88rem;
  font-weight: 600;
  background: var(--panel-high);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .5rem .9rem;
  transition: border-color .15s ease, color .15s ease;
}
.header-nav a:hover { border-color: var(--accent); color: var(--accent); }

h2 {
  font-size: .8rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .08em;
}
.muted { color: var(--muted); font-size: .85rem; }

/* ---------- tarjetas resumen (glass + línea de acento inferior) ---------- */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1rem;
  margin-bottom: 1.6rem;
}
.card {
  position: relative;
  overflow: hidden;
  background: var(--glass-bg);
  backdrop-filter: blur(12px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1rem 1.2rem 1.1rem;
}
.card::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 3px;
  background: var(--accent-strong);
}
.card.up::after { background: var(--up); }
.card.degraded::after { background: var(--degraded); }
.card.down::after { background: var(--down); }
.card.unknown::after { background: var(--accent); }
.card-clickable { cursor: pointer; transition: background .15s ease, border-color .15s ease; }
a.card { display: block; text-decoration: none; color: inherit; }
.card-clickable:hover { background: color-mix(in srgb, var(--text) 12%, transparent); border-color: var(--accent); }
.card-value {
  font-size: 2.1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.card-label {
  color: var(--muted);
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  margin-top: .3rem;
}
.card.up .card-value { color: var(--up); }
.card.degraded .card-value { color: var(--degraded); }
.card.down .card-value { color: var(--down); }
.card.unknown .card-value { color: var(--accent); }
.card-unit { font-size: 1rem; font-weight: 600; color: var(--muted); letter-spacing: normal; }
#d-rtt-avg { color: var(--accent); }
#s-slowest, #s-fastest { display: flex; flex-direction: column; gap: .2rem; }
#s-slowest .stat-name, #s-fastest .stat-name { font-size: 1.05rem; overflow-wrap: break-word; }
#s-slowest .stat-detail, #s-fastest .stat-detail { font-size: .85rem; font-weight: 500; opacity: .8; }

/* ---------- tablas ---------- */

table {
  width: 100%;
  /* border-collapse:collapse impide que el navegador pinte el border-radius/borde
     exterior de la tabla (se ignora por spec), dejando un borde apenas visible;
     separate + border-spacing:0 se ve igual celda a celda pero sí respeta el
     borde/radio exterior, homogéneo con el resto de tarjetas de la app. */
  border-collapse: separate;
  border-spacing: 0;
  background: var(--glass-bg);
  backdrop-filter: blur(12px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
th, td {
  text-align: left;
  padding: .6rem .8rem;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  font-size: .88rem;
}
th {
  background: var(--glass-header-bg);
  color: var(--muted);
  font-weight: 700;
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  cursor: pointer;
  user-select: none;
}
/* las cabeceras pueden partirse en varias líneas sin problema; los VALORES no
   deben partirse nunca (mitad de un número en cada línea) */
td.mono { white-space: nowrap; }

/* anchos explícitos para /unstable: con reparto automático, una cabecera de una
   sola palabra larga (p. ej. "Disponibilidad") fuerza su columna a ser tan ancha
   como esa palabra entera, dejando un hueco enorme frente a valores mucho más
   cortos ("76.7%"). Fijar el ancho por columna evita depender de esa heurística. */
#unstable-table th:nth-child(1) { width: 8%; }
#unstable-table th:nth-child(2) { width: 15%; }
#unstable-table th:nth-child(3) { width: 12%; }
#unstable-table th:nth-child(4) { width: 8%; }
#unstable-table th:nth-child(5) { width: 9%; }
#unstable-table th:nth-child(6) { width: 10%; }
#unstable-table th:nth-child(7) { width: 10%; }
#unstable-table th:nth-child(8) { width: 10%; }
#unstable-table th:nth-child(9) { width: 9%; }
#unstable-table th:nth-child(10) { width: 9%; }
th[data-sort].sorted { color: var(--accent); }
th:not([data-sort]) { cursor: default; }
tbody tr:nth-child(even) { background: color-mix(in srgb, var(--text) 3%, transparent); }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.band-table { margin-bottom: 0; }

/* tablas de resumen lado a lado */
.summary-row {
  display: flex;
  gap: 1.25rem;
  margin-bottom: 1.6rem;
}
.summary-row .bands { flex: 1 1 50%; min-width: 0; }

/* scrollbar oscura reutilizable, acorde al estilo de la app */
.location-scroll,
.favorites-scroll,
.chart-scroll {
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border) var(--panel);
}
.location-scroll::-webkit-scrollbar,
.favorites-scroll::-webkit-scrollbar,
.chart-scroll::-webkit-scrollbar { width: 8px; }
.location-scroll::-webkit-scrollbar-track,
.favorites-scroll::-webkit-scrollbar-track,
.chart-scroll::-webkit-scrollbar-track { background: var(--panel); border-radius: 10px; }
.location-scroll::-webkit-scrollbar-thumb,
.favorites-scroll::-webkit-scrollbar-thumb,
.chart-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 10px; }
.location-scroll::-webkit-scrollbar-thumb:hover,
.favorites-scroll::-webkit-scrollbar-thumb:hover,
.chart-scroll::-webkit-scrollbar-thumb:hover { background: var(--accent); }

/* lista de ubicaciones (5 filas visibles) */
.location-scroll {
  max-height: 250px;
  border-radius: var(--radius-lg);
}
.location-scroll,
.favorites-scroll {
  /* el fondo (con blur) vive en el contenedor, no en la tabla: un <div> con
     overflow propio recorta su propio fondo a border-radius de forma fiable,
     mientras que el fondo de un <table> hijo con overflow visible (necesario
     para que el position:sticky del encabezado ancle a este contenedor y no
     a la propia tabla) se salía del recorte redondeado y dejaba las esquinas
     cuadradas. */
  background: var(--glass-bg);
  backdrop-filter: blur(12px);
  border: 1px solid var(--border);
}
.location-scroll table,
.favorites-scroll table {
  margin-bottom: 0;
  border-radius: 0;
  overflow: visible;
  background: transparent;
  backdrop-filter: none;
  border: none;
}
/* las esquinas exteriores se redondean celda a celda (siempre fiable, a
   diferencia de depender de que el contenedor recorte al table hijo) */
.location-scroll thead th:first-child,
.favorites-scroll thead th:first-child { border-top-left-radius: var(--radius-lg); }
.location-scroll thead th:last-child,
.favorites-scroll thead th:last-child { border-top-right-radius: var(--radius-lg); }
.location-scroll tbody tr:last-child td:first-child,
.favorites-scroll tbody tr:last-child td:first-child { border-bottom-left-radius: var(--radius-lg); }
.location-scroll tbody tr:last-child td:last-child,
.favorites-scroll tbody tr:last-child td:last-child { border-bottom-right-radius: var(--radius-lg); }

/* encabezado fijo al hacer scroll dentro de la tabla (band-table y location-scroll) */
.band-table thead th,
.favorites-scroll thead th {
  position: sticky;
  top: 0;
  background: var(--panel-mid);
  z-index: 1;
}

/* lista de favoritas (mínimo 6 filas visibles) */
.favorites-scroll {
  max-height: 325px;
  border-radius: var(--radius-lg);
  margin-bottom: .8rem;
}
section.printers { margin-bottom: 2rem; }
.section-title {
  display: flex;
  align-items: center;
  gap: .45rem;
}
.section-title .material-symbols-outlined { color: var(--degraded); font-size: 18px; }

/* gráficos de barras (15 impresoras visibles, con el eje X incluido al final) */
.chart-scroll { max-height: 460px; }

/* estado: punto con halo (ring) */
.badge {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-size: .8rem;
  font-weight: 600;
}
.badge::before {
  content: "";
  width: .55rem; height: .55rem;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 18%, transparent);
}
.badge.up { color: var(--up); }
.badge.degraded { color: var(--degraded); }
.badge.down { color: var(--down); }
.badge.unknown { color: var(--unknown); }

/* ---------- barra de filtros ---------- */

.toolbar {
  display: flex;
  align-items: center;
  gap: .8rem;
  flex-wrap: wrap;
  margin-bottom: .8rem;
}
.toolbar h2 { margin: 0; flex: 1; }
.actions-toolbar { justify-content: flex-end; }
input[type="search"], select {
  background: var(--panel-high);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius);
  padding: .45rem .7rem;
  font-size: .88rem;
  font-family: inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}
input[type="search"]:focus, select:focus {
  outline: none;
  border-color: var(--accent-strong);
  box-shadow: 0 0 0 3px rgba(77, 142, 255, .25);
}
input[type="search"] { min-width: 220px; }

/* selector de fecha propio (reemplaza el calendario nativo del navegador) */
.datepicker { position: relative; display: inline-flex; align-items: center; gap: .3rem; }
.datepicker-toggle {
  display: flex;
  align-items: center;
  gap: .5rem;
  background: var(--panel-high);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius);
  padding: .45rem .7rem;
  font-size: .88rem;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  cursor: pointer;
  min-width: 130px;
}
.datepicker-toggle:hover, .datepicker.open .datepicker-toggle { border-color: var(--accent); }
.datepicker-text { flex: 1; text-align: left; }
.datepicker:not(.has-value) .datepicker-text { color: var(--muted); }
.datepicker-icon { font-size: .9rem; opacity: .8; }
.datepicker-clear {
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: .8rem;
  padding: .2rem;
  line-height: 1;
}
.datepicker-clear:hover { color: var(--down); }

.datepicker-panel {
  position: absolute;
  top: calc(100% + .4rem);
  left: 0;
  z-index: 50;
  width: 240px;
  background: var(--panel-mid);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-ambient);
  padding: .7rem;
}
.dp-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
.dp-month-label { font-size: .85rem; font-weight: 600; text-transform: capitalize; }
.dp-nav {
  background: none;
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  width: 1.8rem;
  height: 1.8rem;
  cursor: pointer;
  font-size: .95rem;
}
.dp-nav:hover { border-color: var(--accent); color: var(--accent); }
.dp-weekdays, .dp-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.dp-weekdays span {
  text-align: center;
  font-size: .72rem;
  color: var(--muted);
  padding: .2rem 0;
}
.dp-day {
  background: none;
  border: none;
  color: var(--text);
  border-radius: 6px;
  aspect-ratio: 1;
  font-size: .8rem;
  cursor: pointer;
}
.dp-day:hover { background: var(--panel-highest); }
.dp-day.dp-today { color: var(--accent); font-weight: 700; }
.dp-day.dp-selected { background: var(--accent-strong); color: #fff; }
.dp-day.dp-empty { cursor: default; }

a.printer-link { color: var(--accent); font-weight: 600; text-decoration: none; }
a.printer-link:hover { text-decoration: underline; }

/* ---------- paginación ---------- */

.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: .8rem;
  margin-top: .8rem;
}
.pagination[hidden] { display: none; }
.page-size {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: .85rem;
  color: var(--muted);
}
.page-size select { padding: .35rem .6rem; font-size: .85rem; }
.page-info { font-size: .85rem; }
.page-nav {
  display: flex;
  align-items: center;
  gap: .6rem;
}
.page-nav button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius);
  padding: .4rem .8rem;
  font-size: .85rem;
  cursor: pointer;
}
.page-nav button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.page-nav button:disabled { opacity: .4; cursor: not-allowed; }
#page-current { font-size: .85rem; color: var(--muted); min-width: 90px; text-align: center; }

/* ---------- botones ---------- */

button { font-family: inherit; }
.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  background: var(--accent-strong);
  border: 1px solid var(--accent-strong);
  color: #fff;
  border-radius: var(--radius);
  padding: .5rem 1rem;
  font-size: .88rem;
  font-weight: 700;
  cursor: pointer;
  transition: filter .15s ease;
}
.btn-primary:hover { filter: brightness(1.12); }
.btn-primary:disabled { opacity: .6; cursor: not-allowed; }

.btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius);
  padding: .5rem 1rem;
  font-size: .88rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.btn-secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(173, 198, 255, .08);
}
.btn-secondary.btn-danger:hover {
  border-color: var(--down);
  color: var(--down);
  background: rgba(255, 180, 171, .08);
}
.btn-secondary .material-symbols-outlined,
.btn-primary .material-symbols-outlined { font-size: 18px; }

.export-hint { margin: .2rem 0 0; }

/* acciones de fila (estrella / editar / eliminar) con acentos semánticos */
.row-actions { white-space: nowrap; }
.btn-icon {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 6px;
  width: 1.9rem;
  height: 1.9rem;
  line-height: 1;
  cursor: pointer;
  margin-right: .3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.btn-icon .material-symbols-outlined { font-size: 17px; }
.btn-icon:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); background: rgba(173, 198, 255, .1); }
.btn-icon.btn-danger:hover { color: var(--down); border-color: color-mix(in srgb, var(--down) 40%, transparent); background: rgba(255, 180, 171, .1); }
.btn-icon.btn-favorite:hover { color: var(--degraded); border-color: color-mix(in srgb, var(--degraded) 40%, transparent); background: rgba(255, 183, 134, .1); }
.btn-icon.btn-favorite.active {
  color: var(--degraded);
  border-color: color-mix(in srgb, var(--degraded) 45%, transparent);
  background: rgba(255, 183, 134, .12);
}

/* ---------- modales ---------- */

dialog {
  background: var(--panel-mid);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 0;
  width: min(420px, 90vw);
  box-shadow: var(--shadow-ambient);
}
dialog::backdrop { background: rgba(0, 0, 0, .6); backdrop-filter: blur(2px); }
.modal-body {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  padding: 1.3rem 1.4rem;
}
.modal-body h2 {
  margin: 0 0 .6rem;
  color: var(--text);
  text-transform: none;
  letter-spacing: normal;
  font-size: 1.1rem;
}
.modal-body p { margin: 0; font-size: .9rem; line-height: 1.5; overflow-wrap: break-word; }
.modal-body label {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
  margin-top: .4rem;
}
.modal-body input, .modal-body select, .modal-body textarea {
  background: var(--surface-lowest);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius);
  padding: .5rem .7rem;
  font-size: .95rem;
  width: 100%;
  font-family: inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.modal-body textarea { resize: vertical; line-height: 1.4; }
.modal-body input:focus, .modal-body select:focus, .modal-body textarea:focus {
  outline: none;
  border-color: var(--accent-strong);
  box-shadow: 0 0 0 3px rgba(77, 142, 255, .25);
}
#pf-ip { font-family: "JetBrains Mono", ui-monospace, monospace; }

/* selector de fichero con arrastrar y soltar */
.dropzone {
  border: 2px dashed var(--border);
  border-radius: var(--radius-lg);
  padding: 1.4rem 1rem;
  text-align: center;
  cursor: pointer;
  background: var(--surface-lowest);
  transition: border-color .15s ease, background .15s ease;
}
.dropzone:hover { border-color: var(--accent); }
.dropzone.dragover {
  border-color: var(--accent-strong);
  background: rgba(77, 142, 255, .08);
}
.dropzone.has-file { border-style: solid; border-color: var(--up); }
.dropzone-inner { display: flex; flex-direction: column; align-items: center; gap: .3rem; pointer-events: none; }
.dropzone-icon { font-size: 28px; color: var(--muted); }
.dropzone.dragover .dropzone-icon, .dropzone.has-file .dropzone-icon { color: var(--accent); }
.dropzone-text { font-size: .88rem; color: var(--text-secondary); }
.dropzone-browse { color: var(--accent); text-decoration: underline; }
.dropzone-hint { font-size: .78rem; margin-top: .1rem; }
.dropzone-filename {
  display: flex;
  align-items: center;
  gap: .4rem;
  font-size: .88rem;
  font-weight: 600;
  color: var(--up);
  font-family: "JetBrains Mono", ui-monospace, monospace;
}

/* generador de URLs de paneles embebibles */
dialog#panel-url-modal { width: min(560px, 90vw); }
.modal-body-wide { max-height: 85vh; overflow-y: auto; }
.copy-field { display: flex; gap: .4rem; align-items: stretch; }
.copy-field input, .copy-field textarea {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: .8rem;
  flex: 1;
}
.copy-field button {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 .6rem;
  background: var(--surface-lowest);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--muted);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.copy-field button:hover { color: var(--accent); border-color: var(--accent); }
.copy-field button.copied { color: var(--up); border-color: var(--up); }
.copy-field .material-symbols-outlined { font-size: 18px; }

/* diálogo de información / resumen (reemplaza alert()) */
.info-body { font-size: .9rem; line-height: 1.6; max-height: 50vh; overflow-y: auto; overflow-wrap: break-word; }
.info-body p { margin: 0 0 .6rem; }
.info-body strong { color: var(--text); }
.info-body ul { margin: .2rem 0 .6rem; padding-left: 1.2rem; }
.info-body li { margin-bottom: .15rem; }
dialog#info-modal { width: min(520px, 90vw); }

/* diálogo de progreso (importaciones largas) */
dialog#progress-modal { width: min(460px, 90vw); }
#progress-message { margin: 0; overflow-wrap: break-word; }
.progress-track {
  position: relative;
  height: 8px;
  border-radius: 999px;
  background: var(--surface-lowest);
  border: 1px solid var(--border);
  overflow: hidden;
  margin-top: .8rem;
}
.progress-bar-indeterminate {
  position: absolute;
  top: 0;
  left: -35%;
  height: 100%;
  width: 35%;
  border-radius: 999px;
  background: var(--accent-strong);
  animation: progress-indeterminate 1.1s ease-in-out infinite;
}
@keyframes progress-indeterminate {
  0% { left: -35%; }
  100% { left: 100%; }
}
/* variante con porcentaje real (p.ej. importar backup, que reporta progreso) */
.progress-bar-determinate {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--accent-strong);
  transition: width .2s ease;
}
.progress-track.determinate .progress-bar-indeterminate { display: none; }
.progress-track:not(.determinate) .progress-bar-determinate { display: none; }
#progress-percent { font-variant-numeric: tabular-nums; }

.btn-danger-solid {
  background: var(--danger-solid);
  border: 1px solid var(--danger-solid);
  color: var(--on-danger-solid);
  border-radius: var(--radius);
  padding: .5rem 1rem;
  font-size: .88rem;
  font-weight: 700;
  cursor: pointer;
}
.btn-danger-solid:hover { filter: brightness(1.35); }

/* ---------- notificaciones ---------- */

.toast-container {
  position: fixed;
  right: 1.2rem;
  bottom: 1.2rem;
  display: flex;
  flex-direction: column;
  gap: .6rem;
  z-index: 1000;
}
.toast {
  background: var(--panel-mid);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent-strong);
  color: var(--text);
  border-radius: var(--radius);
  padding: .7rem 1rem;
  font-size: .88rem;
  max-width: 340px;
  box-shadow: var(--shadow-ambient);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .2s ease, transform .2s ease;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast-error { border-left-color: var(--down); }
.toast-success { border-left-color: var(--up); }
.form-error { color: var(--down); font-size: .85rem; margin: .3rem 0 0; }
.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: .6rem;
  margin-top: 1rem;
}
.form-actions button[type="button"] {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius);
  padding: .5rem 1rem;
  font-size: .88rem;
  cursor: pointer;
}
.form-actions button[type="button"]:hover { border-color: var(--accent); color: var(--accent); }
.form-actions a.btn-primary { text-decoration: none; }

/* ---------- detalle de impresora ---------- */

.range-buttons { display: flex; }
.range-buttons button {
  background: var(--panel-high);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  padding: .42rem .9rem;
  font-size: .84rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.range-buttons button:hover { color: var(--text); }
.range-buttons button:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.range-buttons button:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.range-buttons button.active {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  color: #fff;
}
#chart-resolution { margin-left: auto; }
.stat { font-size: .95rem; color: var(--muted); }
.stat strong { color: var(--text); }

.chart-box {
  background: var(--glass-bg);
  backdrop-filter: blur(12px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.1rem 1.3rem;
  margin-bottom: 1.25rem;
}
.chart-box h2 { margin-top: 0; }
.chart-box .chart-hint { margin: -.4rem 0 .8rem; }
.chart-box canvas { max-height: 300px; }
.chart-box table {
  background: transparent;
  border: none;
  backdrop-filter: none;
}

/* ---------- pantalla de gráficos ---------- */

.charts-toolbar {
  background: rgba(25, 27, 35, .92);
  backdrop-filter: blur(12px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: .9rem 1.1rem;
  margin-bottom: 1.25rem;
  align-items: flex-end;
  gap: 1.4rem;
  position: sticky;
  top: .6rem;
  z-index: 10;
  box-shadow: 0 8px 16px -8px rgba(0, 0, 0, .6);
}
.filter-group { display: flex; flex-direction: column; gap: .35rem; }
.filter-label {
  font-size: .7rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .07em;
}
.chip-group { display: flex; gap: .4rem; }
.chip { position: relative; cursor: pointer; }
.chip input { position: absolute; opacity: 0; pointer-events: none; }
.chip span {
  display: inline-block;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: .4rem .85rem;
  font-size: .84rem;
  color: var(--muted);
  user-select: none;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.chip input:checked + span {
  background: rgba(173, 198, 255, .15);
  border-color: var(--accent);
  color: var(--text);
  box-shadow: inset 0 0 12px rgba(173, 198, 255, .08);
}
.chip:hover span { border-color: var(--accent); }
.checkbox-label {
  display: flex;
  align-items: center;
  gap: .45rem;
  font-size: .88rem;
  color: var(--text);
  cursor: pointer;
  padding: .45rem 0;
  user-select: none;
}
.checkbox-label input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  accent-color: var(--accent-strong);
  cursor: pointer;
}
.chart-hint { margin: -0.4rem 0 .8rem; display: flex; gap: 1rem; flex-wrap: wrap; }
.chart-hint[hidden] { display: none; }
.legend-dot {
  display: inline-block;
  width: .65rem; height: .65rem;
  border-radius: 3px;
  margin-right: .35rem;
  vertical-align: baseline;
}
.chart-wrap { position: relative; }
.chart-wrap canvas { max-height: none; }

/* ---------- paneles embebibles (iframe / otros dashboards) ---------- */

body.panel-body {
  display: block;
  max-width: none;
  margin: 0;
}
.panel-content {
  border-right: none;
  padding: 1.2rem 1.4rem 1.6rem;
}
/* la vista embebida no tiene el límite de 6 filas del dashboard: se pide un
   mínimo de 10 favoritas visibles sin necesidad de hacer scroll */
.favorites-scroll-panel { max-height: 560px; }

/* el Lienzo, a diferencia de los paneles embebidos (pensados para ocupar
   todo el ancho de su propio iframe), se ve mejor con el contenido centrado
   y no estirado a pantalla completa en monitores anchos; "body.canvas-body"
   (no solo ".canvas-body") iguala la especificidad de "body.panel-body" de
   arriba para poder pisar su margin:0 */
body.canvas-body { width: 90vw; margin: 0 auto; }
.canvas-content { padding-left: 0; padding-right: 0; }

/* los paneles de gráficos no comparten pantalla con otras secciones, así que
   se les da más alto visible para mostrar más impresoras sin hacer scroll */
.panel-content .chart-scroll { max-height: 600px; }

/* ---------- lienzo (/canvas): paneles embebidos guardados ---------- */

.canvas-item {
  background: var(--glass-bg);
  backdrop-filter: blur(12px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: 1.4rem;
}
.canvas-item-header {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .6rem .9rem;
  border-bottom: 1px solid var(--border);
}
.canvas-item-type {
  flex: 0 0 auto;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--accent);
  background: var(--glass-type-bg);
  padding: .2rem .5rem;
  border-radius: 6px;
}
.canvas-item-label {
  flex: 1;
  min-width: 0;
  color: var(--text-secondary);
  font-size: .85rem;
  overflow-wrap: anywhere;
}
.canvas-item iframe { display: block; }

/* ---------- responsive ---------- */

/* contenedor de scroll horizontal para tablas anchas (dashboard, eventos);
   en escritorio no interfiere porque las tablas caben */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius-lg);
}
.table-scroll table { min-width: 640px; }
.favorites-scroll, .location-scroll { overflow-x: auto; }

@media (max-width: 900px) {
  body { flex-direction: column; }
  .sidenav {
    position: static;
    height: auto;
    flex: none;
    width: 100%;
    flex-direction: row;
    align-items: center;
    padding: .7rem 1rem;
    border-left: none;
    border-right: none;
    border-bottom: 1px solid var(--border);
  }
  .sidenav .brand { margin-bottom: 0; margin-right: auto; }
  .sidenav .brand h1 { font-size: 1.15rem; white-space: nowrap; }
  .sidenav .brand p { display: none; }
  .sidenav nav { flex-direction: row; gap: .3rem; align-items: center; }
  .sidenav nav a span:not(.material-symbols-outlined) { display: none; }
  .sidenav nav a.subitem { display: none; }
  /* el grupo "Opciones" se convierte en menú desplegable flotante para no
     estirar la barra superior al abrirlo */
  .nav-group { position: relative; }
  .nav-toggle { padding: .55rem .5rem; }
  .nav-toggle span:not(.material-symbols-outlined):not(.nav-chevron) { display: none; }
  .nav-tree {
    display: none;
    position: absolute;
    top: calc(100% + .5rem);
    right: 0;
    margin: 0;
    padding: .4rem;
    min-width: 200px;
    max-height: none;
    overflow: visible;
    background: var(--panel-mid);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-ambient);
    z-index: 60;
  }
  .nav-group.open .nav-tree { display: flex; margin: 0; max-height: none; }
  .content { padding: 1rem; border-right: none; }
  .toolbar h2 { flex-basis: 100%; }
  .summary-row { flex-direction: column; }
}

/* teléfonos */
@media (max-width: 640px) {
  .content { padding: .9rem .8rem 2.5rem; }

  /* cabeceras de página apiladas */
  .page-header { flex-direction: column; align-items: stretch; gap: .7rem; }
  .page-header .page-title { font-size: 1.3rem; }
  .header-nav a { justify-content: center; }
  .page-meta { gap: .5rem; font-size: .78rem; }

  /* tarjetas resumen a 2 columnas compactas */
  .cards { grid-template-columns: repeat(2, 1fr); gap: .6rem; }
  .card { padding: .8rem .9rem .9rem; }
  .card-value { font-size: 1.6rem; }
  .card-label { font-size: .65rem; }

  /* filtros: cada control a ancho completo */
  .toolbar { gap: .6rem; }
  .toolbar input[type="search"], .toolbar select { flex: 1 1 100%; min-width: 0; }
  .charts-toolbar {
    position: static;      /* fija ocuparía media pantalla del teléfono */
    padding: .8rem .9rem;
    gap: .8rem;
  }
  .charts-toolbar .filter-group { flex: 1 1 45%; min-width: 0; }
  .charts-toolbar .filter-group select { width: 100%; }
  .chip-group { flex-wrap: wrap; }

  /* tablas y gráficos más compactos */
  th, td { padding: .5rem .6rem; font-size: .82rem; }
  .chart-box { padding: .8rem .7rem; }
  .chart-scroll { max-height: 380px; }

  /* botones de rango (detalle de impresora) sin desbordar */
  .range-buttons { flex-wrap: wrap; }
  .range-buttons button { flex: 1 1 auto; padding: .42rem .6rem; }

  /* paginación centrada y apilada */
  .pagination { justify-content: center; text-align: center; }

  /* modales y avisos a ancho de pantalla */
  dialog { width: min(420px, calc(100vw - 1.6rem)); }
  .modal-body { padding: 1rem 1.1rem; }
  .toast-container { left: .8rem; right: .8rem; }
  .toast { max-width: none; }

  /* acciones del pie de formularios en columna si no caben */
  .form-actions { flex-wrap: wrap; }
}

/* ---------- evolución (/evolution): rejilla de barras diarias por impresora ----------
   Diseño importado de Claude Design ("Grafico Impresoras"), adaptado al tema. */

.pg-scroll {
  max-height: 74vh;
  overflow-y: auto;
  padding: 8px 4px 24px 4px;
  scrollbar-width: thin;
  scrollbar-color: var(--border) var(--panel);
}
.pg-scroll::-webkit-scrollbar { width: 8px; }
.pg-scroll::-webkit-scrollbar-track { background: var(--panel); border-radius: 10px; }
.pg-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 10px; }
.pg-scroll::-webkit-scrollbar-thumb:hover { background: var(--accent); }

.pg-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--pg-card-min, 150px), 1fr));
  gap: 28px 18px;
}

.pg-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-decoration: none;
  border-radius: 8px;
}

.pg-bars {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 4px;
  height: 180px;
  /* sin width:100%: el contenedor se ciñe a las barras y la línea base
     no sobresale por los lados */
  padding: 0 2px;
  border-bottom: 1px solid var(--border);
}

.pg-bar {
  width: 12px;
  border-radius: 2px 2px 0 0;
  cursor: pointer;
  transition: opacity .12s;
}

.pg-bar:hover { opacity: .75; }

.pg-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  margin-top: 8px;
  text-align: center;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pg-card:hover .pg-name { color: var(--accent); }

.chart-tooltip {
  position: fixed;
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: .15rem;
  padding: .5rem .7rem;
  background: var(--panel, #1a1e29);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: .8rem;
  pointer-events: none;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
}
