/* ─── FUENTES (Inter y Syne, en static/fonts) ─────────
   Van en el propio servidor y no en Google Fonts: abren sin internet (portal cautivo, MikroTik
   caído) y ya están en el primer cuadro de cada página, así el texto no salta de Segoe UI a Inter
   (ni el logo a Syne) al cambiar de módulo. Licencia OFL al lado (OFL-Inter.txt, OFL-Syne.txt).
   Son fuentes variables: un archivo por grupo de caracteres sirve todos los grosores, y el
   navegador baja solo el grupo que la página usa (unicode-range; Guaraní usa el vietnamita).
   Si se cambia un archivo, subir el ?v= acá y en los <link rel="preload"> de las plantillas.
   Nunca @import a Google: dejaba la pantalla en blanco ~20 s cuando el servidor no tiene internet. */
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url(/static/fonts/inter-latin.woff2?v=1) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url(/static/fonts/inter-latin-ext.woff2?v=1) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url(/static/fonts/inter-vietnamese.woff2?v=1) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Syne'; font-style: normal; font-weight: 700 800; font-display: swap;
  src: url(/static/fonts/syne-latin.woff2?v=1) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Syne'; font-style: normal; font-weight: 700 800; font-display: swap;
  src: url(/static/fonts/syne-latin-ext.woff2?v=1) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ═══════════════════════════════════════════════════
   CONETATE — Design System v4.0
   Minimalista · Azul Francia Institucional
   Paleta por pasos (estilo Radix): cada color tiene su
   par para modo oscuro y claro. Los nombres de variables
   de v3 se mantienen para no romper plantillas ni JS.
   ═══════════════════════════════════════════════════ */

/* ─── DARK MODE VARIABLES (default) ─────────────── */
:root {
  /* Superficies: bg = página, bg2 = tarjeta, bg3 = campo/hover, bg4 = activo */
  --bg:           #0E1117;
  --bg2:          #161A22;
  --bg3:          #1E232D;
  --bg4:          #272D39;
  --border:       #2B3240;
  --border-strong:#3B4454;
  --soft-bg:      rgba(255, 255, 255, 0.04);   /* relleno sutil dentro de tarjetas */
  --soft-border:  rgba(255, 255, 255, 0.08);

  /* Marca */
  --blue-main:    #0055A4;   /* relleno de botones y activo (texto blanco encima) */
  --blue-bright:  #2F7FE0;
  --blue-light:   #6CB2FF;   /* azul para texto, foco y acentos */
  --blue-deep:    #003380;
  --blue-glow:    rgba(108, 178, 255, 0.12);
  --blue-border:  rgba(108, 178, 255, 0.28);
  --blue:         var(--blue-light);   /* alias usado por portal y login */
  --on-accent:    #FFFFFF;

  /* Texto */
  --text:         #ECEEF2;
  --text2:        #A8B0BD;
  --text3:        #8D96A6;

  /* Estados */
  --green:        #3DD68C;
  --green-bg:     rgba(61, 214, 140, 0.12);
  --green-border: rgba(61, 214, 140, 0.28);
  --red:          #FF8F8F;
  --red-bg:       rgba(255, 143, 143, 0.12);
  --red-border:   rgba(255, 143, 143, 0.28);
  --amber:        #FFC53D;
  --amber-bg:     rgba(255, 197, 61, 0.12);
  --amber-border: rgba(255, 197, 61, 0.28);
  --orange:       #FF9F5A;
  --purple:       #B4A2FF;
  --purple-bg:    rgba(180, 162, 255, 0.12);
  --purple-border:rgba(180, 162, 255, 0.28);

  /* Elevación (sombras suaves, sin brillos) */
  --shadow-sm:    0 1px 2px rgba(0, 0, 0, 0.30);
  --shadow-md:    0 4px 14px rgba(0, 0, 0, 0.35);
  --shadow-lg:    0 16px 40px rgba(0, 0, 0, 0.45);
  --shadow-blue:  0 12px 32px rgba(0, 0, 0, 0.40);
  --focus-ring:   0 0 0 3px rgba(108, 178, 255, 0.30);

  --radius-sm:    8px;
  --radius-md:    10px;
  --radius-lg:    14px;
  --radius-xl:    18px;
  --sidebar-bg:   #0B0E13;
  --sidebar-w:    252px;
  --grad:         linear-gradient(135deg, #0055A4 0%, #1D6FD1 100%);
  --chart-grid:   rgba(255, 255, 255, 0.06);

  /* Movimiento: una sola curva y tres duraciones para todo el sistema */
  --ease:         cubic-bezier(0.2, 0.8, 0.2, 1);
  --dur-fast:     150ms;
  --dur-base:     220ms;
  --dur-slow:     320ms;
  --transition:   var(--dur-base) var(--ease);

  color-scheme: dark;
}

/* ─── LIGHT MODE VARIABLES ───────────────────────── */
[data-theme="light"] {
  --bg:           #F6F7F9;
  --bg2:          #FFFFFF;
  --bg3:          #F0F2F5;
  --bg4:          #E5E8ED;
  --border:       #DDE1E8;
  --border-strong:#C5CBD5;
  --soft-bg:      rgba(16, 24, 40, 0.03);
  --soft-border:  rgba(16, 24, 40, 0.08);

  --blue-main:    #0055A4;
  --blue-bright:  #0B63C1;
  --blue-light:   #0B63C1;
  --blue-deep:    #003380;
  --blue-glow:    rgba(0, 85, 164, 0.08);
  --blue-border:  rgba(0, 85, 164, 0.22);

  --text:         #1C2024;
  --text2:        #4B5260;
  --text3:        #5E6676;

  --green:        #18794E;
  --green-bg:     rgba(24, 121, 78, 0.09);
  --green-border: rgba(24, 121, 78, 0.24);
  --red:          #CE2C31;
  --red-bg:       rgba(206, 44, 49, 0.08);
  --red-border:   rgba(206, 44, 49, 0.22);
  --amber:        #A35200;
  --amber-bg:     rgba(255, 170, 0, 0.14);
  --amber-border: rgba(163, 82, 0, 0.24);
  --orange:       #CC4E00;
  --purple:       #6550B9;
  --purple-bg:    rgba(101, 80, 185, 0.09);
  --purple-border:rgba(101, 80, 185, 0.24);

  --shadow-sm:    0 1px 2px rgba(16, 24, 40, 0.06);
  --shadow-md:    0 4px 14px rgba(16, 24, 40, 0.08);
  --shadow-lg:    0 16px 40px rgba(16, 24, 40, 0.12);
  --shadow-blue:  0 12px 32px rgba(0, 51, 128, 0.12);
  --focus-ring:   0 0 0 3px rgba(0, 85, 164, 0.18);

  --sidebar-bg:   #FBFBFC;
  --chart-grid:   rgba(16, 24, 40, 0.06);

  color-scheme: light;
}

/* ─── RESET ──────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html { scroll-behavior: smooth; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
a { text-decoration: none; color: inherit; }
button, input, select, textarea { font-family: inherit; }
:focus-visible { outline: 2px solid var(--blue-light); outline-offset: 2px; box-shadow: var(--focus-ring); }

/* Cambio de tema suave: app.js agrega .theme-anim a <html> solo durante
   el cambio, así no hay transiciones globales pesadas el resto del tiempo. */
html.theme-anim *, html.theme-anim *::before, html.theme-anim *::after {
  transition: background-color var(--dur-slow) var(--ease),
              color var(--dur-slow) var(--ease),
              border-color var(--dur-slow) var(--ease),
              fill var(--dur-slow) var(--ease),
              stroke var(--dur-slow) var(--ease) !important;
}

/* ─── ONDA DE TEMA ───────────────────────────────── */
/* El círculo y la aurora los anima app.js (ondaDeTema). Solo con .tema-onda: la
   navegación entre módulos mantiene sus propias reglas de transición. */
html.tema-onda::view-transition-old(root),
html.tema-onda::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
.tema-aurora {
  position: fixed; inset: 0;
  width: 100vw; height: 100vh;
  z-index: 9998;
  pointer-events: none;
  view-transition-name: tema-aurora;
}
::view-transition-group(tema-aurora) { animation: none; z-index: 1; }
::view-transition-old(tema-aurora) { display: none; }
::view-transition-new(tema-aurora) { animation: none; mix-blend-mode: normal; }

/* El botón va en su propia capa durante la onda: así su animación se ve en vivo,
   encima de la pantalla congelada, y no recortada por el círculo. */
html.tema-onda #themeBtn { view-transition-name: tema-boton; }
::view-transition-group(tema-boton) { animation: none; z-index: 2; }
::view-transition-old(tema-boton) { display: none; }
::view-transition-new(tema-boton) { animation: none; mix-blend-mode: normal; }

/* Giro del ícono (lo anima app.js: aplicarConGiro). El punto de giro está debajo del
   botón y overflow recorta el arco, como un astro que sale por el horizonte. */
#themeBtn.tema-giro { overflow: hidden; }
#themeBtn.tema-giro::after { display: none; }
#themeBtn.tema-giro svg { transform-origin: 50% 190%; }
#themeBtn .tema-fantasma { position: absolute; inset: 0; margin: auto; pointer-events: none; }
.tema-halo { position: absolute; inset: 0; border-radius: 50%; pointer-events: none; opacity: 0; }
.tema-halo-sol { background: radial-gradient(circle, var(--amber) 0%, transparent 68%); }
.tema-halo-luna { background: radial-gradient(circle, var(--purple) 0%, transparent 68%); }
.tema-estrella { position: absolute; border-radius: 50%; background: var(--purple); pointer-events: none; opacity: 0; }
#themeBtn svg { transition: transform var(--dur-slow) var(--ease); }
@media (hover: hover) {
  #themeBtn:not(.tema-giro):hover svg { transform: rotate(-14deg) scale(1.1); }
}

/* ─── TOP LOADING BAR ────────────────────────────── */
.top-loader {
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  height: 2px;
  z-index: 9999;
  overflow: hidden;
  pointer-events: none;
}
.top-loader::after {
  content: '';
  position: absolute;
  top: 0; left: -40%;
  width: 40%;
  height: 100%;
  background: linear-gradient(90deg, transparent, var(--blue-light), transparent);
  animation: topLoad 900ms var(--ease) forwards;
}
@keyframes topLoad {
  0%   { left: -40%; opacity: 1; }
  100% { left: 100%; opacity: 0; }
}

/* ─── LAYOUT ─────────────────────────────────────── */
.app-layout {
  display: flex;
  min-height: 100vh;
}

/* ═══════════════════════════════════════════════════
   SIDEBAR
   ═══════════════════════════════════════════════════ */
.sidebar {
  width: var(--sidebar-w);
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 100;
  transition: width var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  overflow: hidden;
}

/* Logo: sin línea debajo, el menú empieza a continuación (como la muestra visual) */
.sb-logo {
  padding: 28px 22px 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.sb-logo-text {
  font-family: 'Syne', sans-serif;
  font-size: 18px; font-weight: 800;
  color: var(--text);
  white-space: nowrap;
  letter-spacing: -.3px;
}
/* El «NET» del logo toma el color de la marca: cambia con el tema claro/oscuro y con el
   color que se elija en Configuración (marca_css() sobrescribe --blue-light) */
.logo-net { color: var(--blue-light); transition: color var(--dur-fast) var(--ease); }

/* Envoltorio del menú: en escritorio no cuenta para el diseño (las .sb-section siguen
   siendo hijas directas de la barra); en celular es la barra de abajo */
.sb-menu { display: contents; }

/* Nav sections */
.sb-section {
  padding: 20px 14px 4px;
  flex-shrink: 0;
}
.sb-section-label {
  font-size: 11px;
  color: var(--text3);
  text-transform: uppercase;
  letter-spacing: 1.4px;
  padding: 0 14px;
  margin-bottom: 8px;
  font-weight: 600;
  white-space: nowrap;
}

/* Nav items: más grandes y en píldora; el activo se marca con el fondo de la marca */
.sb-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 450;
  cursor: pointer;
  color: var(--text2);
  margin-bottom: 4px;
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
  white-space: nowrap;
  position: relative;
}
.sb-item svg { flex-shrink: 0; width: 17px; height: 17px; }
.sb-item:hover {
  background: var(--bg3);
  color: var(--text);
}
/* El fondo del activo es un elemento propio (.sb-indicador, primer hijo de cada ítem) y no el
   fondo del enlace: al cambiar de módulo, la transición lo desliza del ítem viejo al nuevo (ver
   TRANSICIÓN ENTRE MÓDULOS). El ícono, el texto y la insignia van encima (position: relative). */
.sb-item.active {
  background: none;
  color: var(--blue-light);
  font-weight: 600;
}
.sb-item > :not(.sb-indicador) { position: relative; }
.sb-indicador {
  display: none;
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
}
.sb-item.active .sb-indicador { display: block; background: var(--blue-glow); }
/* La rayita del activo solo se usa en el menú de abajo del celular (ver RESPONSIVE); va en el
   indicador para que se deslice con él */
.sb-indicador::after {
  content: '';
  position: absolute;
  display: none;
  background: var(--blue-light);
}

/* Sidebar badge */
.sb-badge {
  margin-left: auto;
  font-size: 12px;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: 20px;
  background: var(--green-bg);
  color: var(--green);
  white-space: nowrap;
}

/* Sidebar footer */
.sb-footer {
  margin-top: auto;
  padding: 14px 10px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}
.sb-user {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 6px;
  border-radius: var(--radius-sm);
  transition: background var(--dur-fast) var(--ease);
  cursor: default;
}
.sb-user:hover { background: var(--bg3); }
.sb-avatar {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--grad);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600;
  flex-shrink: 0;
  color: #fff;
}
.sb-uname {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sb-urole {
  font-size: 12px;
  color: var(--text3);
  white-space: nowrap;
}
.sb-logout {
  color: var(--text3);
  transition: color var(--dur-fast) var(--ease);
  flex-shrink: 0;
}
.sb-logout:hover { color: var(--red); }

/* ═══════════════════════════════════════════════════
   MAIN CONTENT
   ═══════════════════════════════════════════════════ */
.main-content {
  margin-left: var(--sidebar-w);
  flex: 1;
  padding: 24px 28px;
  min-height: 100vh;
  transition: margin-left var(--dur-slow) var(--ease);
  position: relative;
  min-width: 0;
}

/* ─── TOPBAR ─────────────────────────────────────── */
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}
.topbar-title {
  font-size: 22px;
  font-weight: 650;
  letter-spacing: -.02em;
}
.topbar-sub {
  font-size: 13px;
  color: var(--text3);
  margin-top: 3px;
  font-weight: 400;
}
.topbar-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* ═══════════════════════════════════════════════════
   CARDS
   ═══════════════════════════════════════════════════ */
.card {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px 24px;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
}
.card:hover {
  border-color: var(--border-strong);
}
.card-title {
  font-size: 12px;
  color: var(--text3);
  text-transform: uppercase;
  letter-spacing: .6px;
  font-weight: 600;
  margin-bottom: 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* ─── STAT CARDS ─────────────────────────────────── */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  margin-bottom: 20px;
}
.stat-card {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--dur-base) var(--ease), transform var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
  position: relative;
  overflow: hidden;
}
.stat-card::before {
  content: '';
  position: absolute;
  left: 0; top: 0; right: 0;
  height: 2px;
  background: var(--border);
}
.stat-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}
.stat-card.stat-blue::before   { background: var(--blue-light); }
.stat-card.stat-green::before  { background: var(--green); }
.stat-card.stat-purple::before { background: var(--purple); }
.stat-card.stat-amber::before  { background: var(--amber); }
.stat-card.stat-red::before    { background: var(--red); }

.stat-icon {
  width: 36px; height: 36px;
  border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px;
  margin-bottom: 14px;
  background: var(--bg3);
}
.stat-val {
  font-size: 30px;
  font-weight: 650;
  letter-spacing: -.02em;
  margin-bottom: 4px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.stat-label {
  font-size: 13px;
  color: var(--text2);
  font-weight: 500;
}
.stat-trend {
  font-size: 12px;
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Variantes de color reutilizables (en lugar de colores fijos en plantillas) */
.c-green  { color: var(--green); }
.c-red    { color: var(--red); }
.c-amber  { color: var(--amber); }
.c-blue   { color: var(--blue-light); }
.c-purple { color: var(--purple); }
.c-muted  { color: var(--text2); }
.bg-green  { background: var(--green-bg); }
.bg-red    { background: var(--red-bg); }
.bg-amber  { background: var(--amber-bg); }
.bg-blue   { background: var(--blue-glow); }
.bg-purple { background: var(--purple-bg); }

/* ═══════════════════════════════════════════════════
   BUTTONS
   ═══════════════════════════════════════════════════ */
.btn {
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
  text-decoration: none;
  white-space: nowrap;
  line-height: 1.3;
}
.btn:active { transform: scale(.98); }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primary {
  background: var(--blue-main);
  color: var(--on-accent);
}
.btn-primary:hover {
  background: var(--blue-deep);
  box-shadow: var(--shadow-sm);
}
[data-theme="light"] .btn-primary:hover { background: #00468A; }
.btn-ghost {
  background: var(--bg2);
  color: var(--text2);
  border-color: var(--border);
}
.btn-ghost:hover {
  background: var(--bg3);
  border-color: var(--border-strong);
  color: var(--text);
}
.btn-danger {
  background: var(--red-bg);
  color: var(--red);
  border-color: var(--red-border);
}
.btn-danger:hover {
  background: var(--red);
  color: var(--bg2);
  border-color: var(--red);
}
.btn-success {
  background: var(--green-bg);
  color: var(--green);
  border-color: var(--green-border);
}
.btn-success:hover {
  background: var(--green);
  color: var(--bg2);
  border-color: var(--green);
}
.btn-sm {
  padding: 5px 10px;
  font-size: 12px;
  border-radius: 7px;
}

/* ═══════════════════════════════════════════════════
   FORMS
   ═══════════════════════════════════════════════════ */
.field { margin-bottom: 14px; }
.f-label {
  font-size: 12px;
  color: var(--text2);
  letter-spacing: .2px;
  margin-bottom: 6px;
  display: block;
  font-weight: 500;
}
.f-input {
  width: 100%;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 13px;
  color: var(--text);
  outline: none;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.f-input:hover { border-color: var(--border-strong); }
.f-input:focus {
  border-color: var(--blue-light);
  box-shadow: var(--focus-ring);
}
.f-input::placeholder { color: var(--text3); }
.f-select {
  width: 100%;
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 13px;
  color: var(--text);
  outline: none;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1L5 5L9 1' stroke='%23878F9C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 32px;
}
.f-select:hover { border-color: var(--border-strong); }
.f-select:focus { border-color: var(--blue-light); box-shadow: var(--focus-ring); }
/* Campo con ícono a la izquierda (portal y login) */
.f-wrap { position: relative; }
.f-icon {
  position: absolute;
  left: 12px; top: 50%;
  transform: translateY(-50%);
  color: var(--text3);
  pointer-events: none;
  transition: color var(--dur-fast) var(--ease);
}
.f-wrap:focus-within .f-icon { color: var(--blue-light); }
.f-input-icon { padding-left: 38px !important; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.form-grid .full { grid-column: 1 / -1; }

/* ═══════════════════════════════════════════════════
   TABLES
   ═══════════════════════════════════════════════════ */
.table-wrap {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.table-header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.table-cols {
  display: grid;
  padding: 9px 20px;
  font-size: 11px;
  color: var(--text3);
  text-transform: uppercase;
  letter-spacing: .6px;
  font-weight: 600;
  border-bottom: 1px solid var(--border);
  background: var(--soft-bg);
}
.table-row {
  display: grid;
  padding: 11px 20px;
  border-bottom: 1px solid var(--border);
  align-items: center;
  font-size: 13px;
  transition: background var(--dur-fast) var(--ease);
}
.table-row:last-child { border-bottom: none; }
.table-row:hover { background: var(--soft-bg); }

/* Table avatar */
.t-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--blue-glow);
  color: var(--blue-light);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600;
  flex-shrink: 0;
}

/* Empty state */
.empty-state {
  padding: 48px 32px;
  text-align: center;
  color: var(--text3);
  animation: fadeIn var(--dur-slow) var(--ease) both;
}
.empty-state-icon {
  width: 48px; height: 48px;
  background: var(--bg3);
  border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 14px;
  font-size: 22px;
}
.empty-state p { font-size: 13px; color: var(--text2); }
.empty-state small {
  font-size: 12px;
  display: block;
  margin-top: 4px;
  color: var(--text3);
}

/* ═══════════════════════════════════════════════════
   TAGS / BADGES
   ═══════════════════════════════════════════════════ */
.tag {
  font-size: 12px;
  font-weight: 500;
  padding: 2px 9px;
  border-radius: 6px;
  display: inline-block;
  white-space: nowrap;
  transition: background var(--dur-base) var(--ease), color var(--dur-base) var(--ease);
}
.tag-green  { background: var(--green-bg);  color: var(--green); }
.tag-red    { background: var(--red-bg);    color: var(--red); }
.tag-amber  { background: var(--amber-bg);  color: var(--amber); }
.tag-blue   { background: var(--blue-glow); color: var(--blue-light); }
.tag-purple { background: var(--purple-bg); color: var(--purple); }
.tag-gray   { background: var(--bg3);       color: var(--text2); }
.tag[hidden] { display: none; }   /* el display de .tag le ganaba al atributo hidden */

/* Log tags */
.log-tag-success { background: var(--green-bg);  color: var(--green); }
.log-tag-danger  { background: var(--red-bg);    color: var(--red); }
.log-tag-info    { background: var(--blue-glow); color: var(--blue-light); }
.log-tag-neutral { background: var(--bg3);       color: var(--text2); border: 1px solid var(--border); }

/* ═══════════════════════════════════════════════════
   TOGGLE SWITCH
   ═══════════════════════════════════════════════════ */
.toggle {
  width: 38px; height: 22px;
  border-radius: 11px;
  cursor: pointer;
  display: flex;
  align-items: center;
  padding: 2px 3px;
  transition: background var(--dur-base) var(--ease), border-color var(--dur-base) var(--ease);
  flex-shrink: 0;
}
.toggle.off { background: var(--bg4); border: 1px solid var(--border); }
.toggle.on  { background: var(--blue-main); border: 1px solid transparent; }
.toggle-knob {
  width: 16px; height: 16px;
  background: #fff;
  border-radius: 50%;
  transition: transform var(--dur-base) var(--ease);
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.toggle.on .toggle-knob { transform: translateX(16px); }

/* ═══════════════════════════════════════════════════
   MODAL
   ═══════════════════════════════════════════════════ */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 8, 14, .6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease);
}
[data-theme="light"] .modal-overlay { background: rgba(16, 24, 40, .35); }
.modal-overlay.show { opacity: 1; pointer-events: all; }
.modal {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 26px;
  width: 100%;
  max-width: 460px;
  transform: scale(.97) translateY(6px);
  opacity: 0;
  transition: transform var(--dur-base) var(--ease), opacity var(--dur-base) var(--ease);
  box-shadow: var(--shadow-lg);
}
.modal-overlay.show .modal { transform: none; opacity: 1; }
.modal-title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -.01em;
  margin-bottom: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.modal-close {
  width: 28px; height: 28px;
  border-radius: var(--radius-sm);
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text2);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.modal-close:hover { background: var(--bg3); color: var(--text); }

/* ═══════════════════════════════════════════════════
   TOAST NOTIFICATIONS
   ═══════════════════════════════════════════════════ */
.toast-container {
  position: fixed;
  bottom: 24px;
  right: 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 9999;
}
.toast {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 11px 14px;
  font-size: 13px;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 9px;
  box-shadow: var(--shadow-lg);
  animation: toastIn var(--dur-slow) var(--ease) both;
  min-width: 220px;
  max-width: 360px;
  position: relative;
  overflow: hidden;
}
.toast::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--border);
}
.toast.success::before { background: var(--green); }
.toast.error::before   { background: var(--red); }
.toast.warning::before { background: var(--amber); }
.toast.info::before    { background: var(--blue-light); }
@keyframes toastIn {
  from { opacity: 0; transform: translateY(8px) scale(.98); }
  to   { opacity: 1; transform: none; }
}

/* ═══════════════════════════════════════════════════
   SEARCH INPUT
   ═══════════════════════════════════════════════════ */
.search-wrap { position: relative; }
.search-input {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 7px 12px 7px 32px;
  font-size: 13px;
  color: var(--text);
  outline: none;
  width: 220px;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), width var(--dur-base) var(--ease);
}
.search-input:hover { border-color: var(--border-strong); }
.search-input:focus {
  border-color: var(--blue-light);
  box-shadow: var(--focus-ring);
}
.search-input::placeholder { color: var(--text3); }
.search-icon {
  position: absolute;
  left: 11px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text3);
  pointer-events: none;
}

/* ═══════════════════════════════════════════════════
   BACKGROUND EFFECTS
   ═══════════════════════════════════════════════════ */
.bg-grid {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: radial-gradient(var(--border) 1px, transparent 1px);
  background-size: 24px 24px;
  opacity: .35;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 30%, transparent 75%);
  mask-image: radial-gradient(ellipse at center, #000 30%, transparent 75%);
}

/* ═══════════════════════════════════════════════════
   THEME BUTTON
   ═══════════════════════════════════════════════════ */
.theme-btn {
  width: 34px; height: 34px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  color: var(--text2);
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
  position: relative;
}
.theme-btn:hover {
  border-color: var(--border-strong);
  background: var(--bg3);
  color: var(--text);
}
.theme-btn svg { transition: transform var(--dur-slow) var(--ease); }
.theme-btn:active svg { transform: rotate(30deg); }
.theme-btn[title]::after {
  content: attr(title);
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%) translateY(-2px);
  background: var(--bg2);
  border: 1px solid var(--border);
  color: var(--text2);
  font-size: 12px;
  padding: 3px 8px;
  border-radius: 6px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  box-shadow: var(--shadow-md);
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.theme-btn:hover[title]::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
/* Los botones de la barra de arriba están pegados al borde derecho: su ayuda se alinea a la
   derecha del botón y abre hacia adentro. Centrada, aunque invisible, se salía de la pantalla
   y aparecía una barra de desplazamiento horizontal en todo el panel. */
.topbar-actions .theme-btn[title]::after { left: auto; right: 0; transform: translateY(-2px); }
.topbar-actions .theme-btn:hover[title]::after { transform: translateY(0); }

/* Botón de tema flotante (portal, login, bienvenida) */
.theme-fixed {
  position: fixed;
  top: 16px; right: 16px;
  width: 36px; height: 36px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px;
  z-index: 100;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.theme-fixed:hover { border-color: var(--border-strong); background: var(--bg3); }

/* Variante sobria y transparente (login admin): sin fondo ni sombra,
   solo el ícono; al pasar el mouse aparece un borde tenue. */
.theme-fixed.theme-ghost {
  top: 20px; right: 20px;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--text3);
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.theme-fixed.theme-ghost:hover {
  color: var(--text);
  border-color: var(--soft-border);
  background: var(--soft-bg);
}
.theme-fixed.theme-ghost svg { transition: transform var(--dur-slow) var(--ease); }
.theme-fixed.theme-ghost:active svg { transform: rotate(30deg) scale(.92); }

/* ═══════════════════════════════════════════════════
   STATUS INDICATORS
   ═══════════════════════════════════════════════════ */
.status-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 500;
  padding: 4px 11px;
  border-radius: 20px;
  border: 1px solid var(--border);
  transition: background var(--dur-base) var(--ease), color var(--dur-base) var(--ease), border-color var(--dur-base) var(--ease);
}
.status-pill.online {
  background: var(--green-bg);
  color: var(--green);
  border-color: var(--green-border);
}
.pulse {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--green);
  animation: pulse 2s ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}
/* Estado del MikroTik en la barra de arriba: solo el punto de color, del tamaño de los botones
   de al lado (verde = conectado, rojo = desconectado, ámbar = mantenimiento, gris = verificando).
   El texto queda en el title (al pasar el mouse) y para lectores de pantalla. */
#mikrotik-pill {
  width: 34px; height: 34px; padding: 0;
  justify-content: center; border-radius: var(--radius-sm);
  cursor: help;
}
#mikrotik-pill-texto { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
#mikrotik-pill .pulse { width: 10px; height: 10px; }
#mikrotik-pill { position: relative; }
#mikrotik-pill:focus { outline: none; }
#mikrotik-pill:focus-visible { box-shadow: var(--focus-ring); }

/* Ficha del estado: se abre al pasar el puntero, con Tab o con un toque (.abierta) */
.estado-ficha {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 300;
  width: 290px; padding: 12px 14px 10px;
  background: var(--bg2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  font-size: 12.5px; font-weight: 400; line-height: 1.4; text-align: left; cursor: default;
  opacity: 0; visibility: hidden; transform: translateY(-4px);
  transition: opacity .15s var(--ease), transform .15s var(--ease), visibility 0s linear .15s;
}
/* Puente invisible entre el punto y la ficha, para que no se cierre al bajar el puntero */
.estado-ficha::before { content: ""; position: absolute; left: 0; right: 0; top: -10px; height: 10px; }
#mikrotik-pill:hover .estado-ficha,
#mikrotik-pill:focus-visible .estado-ficha,
#mikrotik-pill.abierta .estado-ficha {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity .15s var(--ease), transform .15s var(--ease), visibility 0s;
}
.ef-titulo { display: flex; align-items: center; gap: 8px; margin: 0 0 6px; font-weight: 600; font-size: 13px; }
.ef-punto { width: 9px; height: 9px; border-radius: 50%; background: var(--text3); flex-shrink: 0; }
.estado-ficha[data-estado="online"]  .ef-punto { background: var(--green); }
.estado-ficha[data-estado="offline"] .ef-punto,
.estado-ficha[data-estado="viejo"]   .ef-punto { background: var(--red); }
.estado-ficha[data-estado="mant"]    .ef-punto { background: var(--amber); }
.ef-seccion {
  margin: 8px 0 2px; padding-top: 7px; border-top: 1px solid var(--border);
  font-size: 11px; font-weight: 600; letter-spacing: .02em; color: var(--text3);
}
.ef-fila { display: flex; justify-content: space-between; gap: 12px; padding: 2px 0; }
.ef-fila > span:first-child { color: var(--text2); flex-shrink: 0; }
.ef-fila > span:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.ef-bien  { color: var(--green); }
.ef-mal   { color: var(--red); }
.ef-aviso { color: var(--amber); }
.ef-pie { margin: 8px 0 0; font-size: 11px; color: var(--text3); }
@media screen and (max-width: 768px) {
  /* En el celular el punto está fijo en el encabezado: la ficha va pegada al borde derecho */
  .estado-ficha { position: fixed; top: 50px; right: 12px; width: min(290px, calc(100vw - 24px)); }
}
@media (prefers-reduced-motion: reduce) { .estado-ficha { transition: none; } }
@media print { .estado-ficha { display: none; } }

/* ═══════════════════════════════════════════════════
   ANIMATIONS
   ═══════════════════════════════════════════════════ */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.fade-up   { animation: fadeUp var(--dur-slow) var(--ease) both; }
.fade-up-1 { animation: fadeUp var(--dur-slow) var(--ease) 40ms both; }
.fade-up-2 { animation: fadeUp var(--dur-slow) var(--ease) 80ms both; }
.fade-up-3 { animation: fadeUp var(--dur-slow) var(--ease) 120ms both; }
.fade-up-4 { animation: fadeUp var(--dur-slow) var(--ease) 160ms both; }

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ─── TRANSICIÓN ENTRE MÓDULOS ───────────────────── */
/* View Transitions API entre páginas del mismo sitio: el navegador saca
   una "foto" de la página saliente y funde con la entrante, sin pantalla
   en blanco. Navegadores sin soporte navegan como siempre. */
@view-transition { navigation: auto; }

/* Piezas que se animan por separado:
   - sidebar:     sin ningún efecto, cambia al instante
   - nav-*:       cada ítem del menú, quieto y por encima del indicador (el viejo activo y el
                  nuevo cruzan su color en 300 ms)
   - menu-activo: el fondo del ítem activo (.sb-indicador), se desliza del viejo al nuevo
   - contenido:   el área principal, «fade through»
   El resto (fondo) hace el fundido por defecto del navegador.
   Los nombres solo existen mientras dura la transición (.vt-activa, la
   pone/quita base.html): un nombre fijo en .main-content crearía un
   contexto de apilamiento y los modales quedarían debajo del menú. */
html.vt-activa .sidebar        { view-transition-name: sidebar; }
html.vt-activa .main-content   { view-transition-name: contenido; }
html.vt-activa #nav-dashboard { view-transition-name: nav-dashboard; }
html.vt-activa #nav-usuarios { view-transition-name: nav-usuarios; }
html.vt-activa #nav-sesiones { view-transition-name: nav-sesiones; }
html.vt-activa #nav-red { view-transition-name: nav-red; }
html.vt-activa #nav-logs { view-transition-name: nav-logs; }
html.vt-activa #nav-config { view-transition-name: nav-config; }
html.vt-activa .sb-item.active .sb-indicador { view-transition-name: menu-activo; }

::view-transition-group(sidebar),
::view-transition-old(sidebar),
::view-transition-new(sidebar) { animation: none; }
::view-transition-group(sidebar) { z-index: 1; }
/* En celular el menú de abajo va con nombre propio (ver RESPONSIVE): también queda quieto */
::view-transition-group(menu-abajo),
::view-transition-old(menu-abajo),
::view-transition-new(menu-abajo) { animation: none; }
::view-transition-group(menu-abajo) { z-index: 1; }
/* En celular, los tres botones del encabezado (estado, buscar, tema) también: por encima del
   encabezado (z-index 2) para que no los tape mientras dura la transición */
::view-transition-group(boton-estado), ::view-transition-group(boton-buscar), ::view-transition-group(boton-tema),
::view-transition-old(boton-estado), ::view-transition-old(boton-buscar), ::view-transition-old(boton-tema),
::view-transition-new(boton-estado), ::view-transition-new(boton-buscar), ::view-transition-new(boton-tema) { animation: none; }
::view-transition-group(boton-estado), ::view-transition-group(boton-buscar), ::view-transition-group(boton-tema) { z-index: 2; }
/* Duración total del cambio de módulo: el único número a tocar para hacerlo más rápido o más
   lento (el contenido, el indicador y los ítems se reparten este tiempo). Con 300 ms y con 460 ms
   el usuario lo sintió demasiado rápido; mientras dura, la página no recibe clics, así que
   conviene no pasar de ~700 ms. */
:root { --vt-duracion: 600ms; }

/* Indicador del menú: viaja del ítem viejo al nuevo (el navegador anima posición y tamaño) por
   encima de la barra (1) y debajo de los ítems (3), así el texto se sigue leyendo */
::view-transition-group(menu-activo) {
  z-index: 2;
  animation-duration: var(--vt-duracion);
  animation-timing-function: var(--ease);
}
::view-transition-group(nav-dashboard),
::view-transition-group(nav-usuarios),
::view-transition-group(nav-sesiones),
::view-transition-group(nav-red),
::view-transition-group(nav-logs),
::view-transition-group(nav-config) {
  z-index: 3;
  animation-duration: var(--vt-duracion);
}

/* Contenido: «fade through», lo que recomienda Material para pantallas del mismo nivel (los
   módulos no van uno detrás de otro, así que no se desliza con dirección). El viejo se apaga
   rápido (35 % del tiempo) y el nuevo aparece con un acercamiento mínimo anclado arriba (el
   título no salta), empezando un poco antes de que el viejo termine de apagarse. */
::view-transition-old(contenido) {
  animation: vtApagar calc(var(--vt-duracion) * .35) cubic-bezier(.4, 0, 1, 1) both;
}
::view-transition-new(contenido) {
  animation: vtAparecer calc(var(--vt-duracion) * .7) var(--ease) calc(var(--vt-duracion) * .3) both;
  transform-origin: 50% 0;
}
@keyframes vtApagar   { to   { opacity: 0; } }
@keyframes vtAparecer { from { opacity: 0; transform: scale(.98); } }

/* Al llegar por transición, el módulo entra entero con el «fade through» de arriba: sin las
   animaciones de carga normales (.fade-up) ni entrada escalonada por bloques. La escalonada
   sumaba casi 1 s con partes del módulo todavía invisibles y se sentía como un retraso. */
html.vt-nav .top-loader { display: none; }
html.vt-nav .main-content .fade-up, html.vt-nav .main-content .fade-up-1,
html.vt-nav .main-content .fade-up-2, html.vt-nav .main-content .fade-up-3,
html.vt-nav .main-content .fade-up-4 { animation: none; }
/* Clic en el menú y el módulo nuevo todavía no llega (más de 150 ms): la barra de arriba corre en
   la pantalla actual (.navegando la pone base.html). Va después de la regla de .vt-nav para
   ganarle: una pantalla a la que se llegó por transición tiene la barra oculta. */
html.navegando .top-loader { display: block; }
html.navegando .top-loader::after { animation: topCargando 1s var(--ease) infinite; }
@keyframes topCargando { from { left: -40%; opacity: 1; } to { left: 100%; opacity: 1; } }

/* ─── SALIDA DEL PANEL (cerrar sesión) ─────────────── */
/* De una pantalla del panel al login (cerrar sesión o sesión vencida) la página entera se funde
   con el login: el panel se aleja un poco y el login se acerca a su lugar. Sin las piezas del
   cambio de módulo (menú quieto, indicador...): el login no las tiene, y el menú quedaba
   congelado hasta el final y desaparecía de golpe. El tipo «salida» lo pone login_admin.html y
   base.html no nombra las piezas cuando el destino no es un módulo. Las dos imágenes se cruzan
   con el mismo tiempo (como el fundido normal), así nunca se ve el fondo vacío entre una y otra. */
html:active-view-transition-type(salida)::view-transition-old(root) {
  animation: vtPanelSale 520ms cubic-bezier(.4, 0, .2, 1) both;
}
html:active-view-transition-type(salida)::view-transition-new(root) {
  animation: vtLoginEntra 520ms var(--ease) both;
}
@keyframes vtPanelSale  { to   { opacity: 0; transform: scale(.97); } }
@keyframes vtLoginEntra { from { opacity: 0; transform: scale(1.03); } }
/* La tarjeta del login ya entra con la transición: sin su animación propia (sería doble) */
html.vt-salida .glass-card { animation: none; }

/* ═══════════════════════════════════════════════════
   SCROLLBAR
   ═══════════════════════════════════════════════════ */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--bg4); border-radius: 8px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--border-strong); }

/* Firefox scrollbar */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--bg4) transparent;
}

/* ═══════════════════════════════════════════════════
   LOG DOTS
   ═══════════════════════════════════════════════════ */
.log-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  margin-top: 3px;
}
.dot-green  { background: var(--green); }
.dot-red    { background: var(--red); }
.dot-blue   { background: var(--blue-light); }
.dot-amber  { background: var(--amber); }
.dot-purple { background: var(--purple); }
.dot-gray   { background: var(--text3); }

/* ═══════════════════════════════════════════════════
   ADMIN AVATAR ROLES
   ═══════════════════════════════════════════════════ */
.avatar-super {
  background: var(--grad);
  color: #fff;
}
.avatar-admin {
  background: var(--bg3);
  color: var(--text2);
  border: 1px solid var(--border);
}
.admin-avatar-icon {
  width: 32px; height: 32px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600;
  flex-shrink: 0;
}

/* ═══════════════════════════════════════════════════
   REGLA ICON (Control de Red)
   ═══════════════════════════════════════════════════ */
/* Íconos SVG de trazo (los mismos 24×24 del menú), nunca emojis: toman el color
   del texto con currentColor, así andan en tema claro y oscuro. */
.regla-icon {
  width: 40px; height: 40px;
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background var(--dur-base) var(--ease), color var(--dur-base) var(--ease);
}
.regla-icon-blocked { background: var(--red-bg);   color: var(--red); }
.regla-icon-allowed { background: var(--green-bg); color: var(--green); }

/* Encabezado de cada categoría */
.regla-cat-titulo {
  display: flex; align-items: center; gap: 9px;
  font-size: 13px; font-weight: 600; color: var(--text);
  letter-spacing: .1px; text-transform: none;
}
.regla-cat-ic {
  width: 28px; height: 28px;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: var(--blue-glow);
  color: var(--blue-light);
}
.regla-cat-cuenta { color: var(--text3); font-weight: 500; font-size: 12px; text-transform: none; letter-spacing: 0; }

/* Estado de la regla: el ícono acompaña al texto (no es solo color) */
.regla-estado { display: inline-flex; align-items: center; gap: 5px; }
.regla-estado svg { flex-shrink: 0; }
.regla-estado.tag-red   .ic-permitido,
.regla-estado.tag-green .ic-bloqueado { display: none; }

/* Elegir la categoría en «Nueva regla»: tarjetitas con ícono (radio por debajo) */
.regla-cats { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; }
.regla-cat { position: relative; cursor: pointer; }
.regla-cat input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.regla-cat-caja {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 11px 4px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg3);
  color: var(--text2);
  font-size: 12px; font-weight: 500; text-align: center; line-height: 1.2;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.regla-cat:hover .regla-cat-caja { color: var(--text); border-color: var(--blue-border); }
.regla-cat input:checked + .regla-cat-caja {
  background: var(--blue-glow);
  border-color: var(--blue-border);
  color: var(--blue-light);
  font-weight: 600;
}
.regla-cat input:focus-visible + .regla-cat-caja { box-shadow: var(--focus-ring); }
@media (max-width: 640px) {
  .regla-cats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Ayuda del campo de dominios */
.regla-ayuda { font-size: 12px; color: var(--text3); margin-top: 6px; line-height: 1.55; }
.regla-ayuda code { font-family: ui-monospace, Consolas, monospace; font-size: 11.5px; color: var(--text2); }

/* ─── NUEVA REGLA: PESTAÑAS, CATÁLOGO Y TABLA DE DOMINIOS ─── */
.modal.modal-regla { max-width: 720px; }
.modal-regla [hidden] { display: none !important; }   /* .btn, .cat-item… tienen su propio display */
.regla-pestanas { margin-bottom: 16px; }
.regla-pestanas button { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 7px; font-family: inherit; padding: 8px 10px; }

.cat-buscar { margin-bottom: 10px; }
.cat-filtros { margin-bottom: 12px; }
.cat-filtros .filter-chip { font-family: inherit; }
.cat-filtros .filter-chip svg { flex-shrink: 0; }

/* La lista se desplaza sola y el pie con «Agregar» queda siempre a la vista. Alto fijo:
   al buscar, el diálogo no cambia de tamaño con cada letra. */
.cat-lista {
  height: min(46vh, 430px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 2px 4px 2px 2px;
  margin: 0 -4px 0 -2px;
}
.cat-grupo + .cat-grupo { margin-top: 14px; }
.cat-grupo-titulo {
  font-size: 11px; font-weight: 600; color: var(--text3);
  text-transform: uppercase; letter-spacing: .6px;
  margin: 0 0 8px;
}
.cat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 8px; }
.cat-item { position: relative; min-width: 0; }
.cat-sel {
  width: 100%;
  display: flex; align-items: center; gap: 10px;
  padding: 9px 40px 9px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg3);
  color: var(--text);
  font: inherit; text-align: left;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.cat-sel:hover:not(:disabled) { border-color: var(--blue-border); }
.cat-sel:disabled { cursor: default; }
.cat-ic {
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--blue-glow); color: var(--blue-light);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.cat-ic > span { display: flex; }
.cat-ic-ok { display: none !important; }
.cat-txt { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cat-nombre { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cat-det { font-size: 11.5px; color: var(--text3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Elegido: borde y fondo de la marca, el ícono pasa a ser una tilde */
.cat-item.elegido .cat-sel { border-color: var(--blue-main); background: var(--blue-glow); }
.cat-item.elegido .cat-ic { background: var(--blue-main); color: #fff; }
.cat-item.elegido .cat-ic-cat,
.cat-completo .cat-ic-cat { display: none !important; }
.cat-item.elegido .cat-ic-ok,
.cat-completo .cat-ic-ok { display: flex !important; }
/* Ya está en la lista y completo: tilde verde, sin elegir */
.cat-completo .cat-sel { background: transparent; border-style: dashed; padding-right: 9px; }
.cat-completo .cat-ic { background: var(--green-bg); color: var(--green); }
.cat-completo .cat-nombre { color: var(--text2); }
/* Está en la lista pero le faltan dominios del catálogo */
.cat-incompleto .cat-sel { padding-right: 9px; }
.cat-incompleto .cat-det { color: var(--amber); }
.cat-editar {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 28px; height: 28px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid transparent; background: none;
  color: var(--text3); cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.cat-editar:hover { background: var(--bg2); border-color: var(--border); color: var(--text); }
.cat-vacio { text-align: center; color: var(--text3); font-size: 12.5px; padding: 24px 8px; line-height: 1.5; }
.cat-pie {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid var(--border);
}
.cat-cuenta { flex: 1 1 140px; font-size: 12.5px; color: var(--text2); }

/* Tabla de dominios de «Desde cero» */
.dom-cabeza { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.dom-cuenta { font-size: 12px; color: var(--text3); }
.dom-agregar { display: flex; gap: 8px; }
.dom-agregar .f-input { flex: 1; min-width: 0; }
.dom-agregar .btn { flex-shrink: 0; }
.dom-error { color: var(--red); font-size: 12px; margin-top: 6px; line-height: 1.45; }
.dom-caja {
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  max-height: 232px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.dom-tabla { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.dom-tabla th {
  position: sticky; top: 0; z-index: 1;
  background: var(--bg3);
  text-align: left; font-size: 11px; font-weight: 600; color: var(--text3);
  text-transform: uppercase; letter-spacing: .5px;
  padding: 7px 10px;
  border-bottom: 1px solid var(--border);
}
.dom-tabla td { padding: 5px 10px; border-top: 1px solid var(--border); vertical-align: middle; }
.dom-tabla tbody tr:first-child td { border-top: 0; }
.dom-tabla tbody tr:hover td { background: var(--bg3); }
.dom-tabla .dom-n { width: 34px; color: var(--text3); font-variant-numeric: tabular-nums; }
.dom-nombre { font-family: ui-monospace, Consolas, monospace; color: var(--text); overflow-wrap: anywhere; }
.dom-tabla td.dom-cubre { font-family: ui-monospace, Consolas, monospace; color: var(--text3); overflow-wrap: anywhere; }
.dom-tabla .dom-acc { width: 40px; text-align: right; }
.dom-quitar {
  width: 26px; height: 26px; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid transparent; background: none;
  color: var(--text3); cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.dom-quitar:hover { color: var(--red); background: var(--red-bg); }
.dom-vacia { padding: 18px 14px; text-align: center; color: var(--text3); font-size: 12.5px; line-height: 1.5; }
.dom-vacia p { margin: 0; }
/* Tabla de muestra de «Regla personalizada» vacía: se nota que es un ejemplo, no un dato */
.dom-vacia .dom-ejemplo-titulo {
  margin: 14px 0 6px; text-align: left;
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .5px;
}
.dom-ejemplo {
  border: 1px dashed var(--border); border-radius: var(--radius-sm);
  border-collapse: separate; border-spacing: 0; overflow: hidden;
  text-align: left; font-style: italic; opacity: .75;
}
.dom-ejemplo th { position: static; }
.dom-ejemplo .dom-nombre { color: var(--text2); }
.dom-tabla.dom-ejemplo tbody tr:hover td { background: none; }
.f-opcional { font-weight: 400; color: var(--text3); }
.dom-sugerencia {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px;
  margin-top: 8px; padding: 7px 8px 7px 11px;
  font-size: 12.5px; color: var(--text2);
  background: var(--blue-glow);
  border: 1px solid var(--blue-border);
  border-radius: var(--radius-sm);
}
.dom-sugerencia span { flex: 1 1 180px; }
.dom-nota {
  margin-top: 8px; padding: 7px 11px;
  font-size: 12px; line-height: 1.5;
  color: var(--amber); background: var(--amber-bg);
  border-radius: var(--radius-sm);
}
@media (max-width: 560px) {
  .dom-tabla .dom-cubre { display: none; }
  .cat-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .regla-pestanas button { padding: 8px 6px; font-size: 12px; }
  /* Que «Agregar» entre en la pantalla sin desplazar el diálogo: filtros en una fila
     que se desliza, sin el texto de ayuda (la tarjeta ya dice lo que le falta) */
  /* (.filter-chips va más abajo en esta hoja: con dos clases le gana) */
  .cat-filtros.filter-chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
  .cat-filtros::-webkit-scrollbar { display: none; }
  .cat-filtros .filter-chip { flex-shrink: 0; }
  .cat-ayuda { display: none; }
  .cat-lista { height: min(44vh, 430px); }
  .cat-det { white-space: normal; }
  .cat-cuenta { flex-basis: 100%; }
  .cat-pie .btn { flex: 1; justify-content: center; }
}

/* ═══════════════════════════════════════════════════
   PÁGINAS PÚBLICAS — Portal, Bienvenido, Login
   (antes glassmorphism; ahora tarjeta sólida sin blur,
   más liviana en celulares y con buen contraste)
   ═══════════════════════════════════════════════════ */

/* Background */
.glass-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: var(--bg);
  overflow: hidden;
}

/* Halo de fondo estático (sin blur ni animación infinita) */
.blob {
  position: fixed;
  border-radius: 50%;
  pointer-events: none;
  z-index: 0;
  opacity: 1;
}
.blob-1 {
  width: 640px; height: 640px;
  background: radial-gradient(circle, rgba(47,127,224,0.16) 0%, transparent 65%);
  top: -280px; left: -220px;
}
.blob-2 {
  width: 520px; height: 520px;
  background: radial-gradient(circle, rgba(0,85,164,0.14) 0%, transparent 65%);
  bottom: -240px; right: -200px;
}
.blob-3 { display: none; }
[data-theme="light"] .blob-1 { background: radial-gradient(circle, rgba(11,99,193,0.10) 0%, transparent 65%); }
[data-theme="light"] .blob-2 { background: radial-gradient(circle, rgba(0,85,164,0.08) 0%, transparent 65%); }

/* Card */
.glass-card {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-blue);
  position: relative;
  z-index: 10;
  width: 100%;
  animation: glassIn var(--dur-slow) var(--ease) both;
  overflow: hidden;
}
@keyframes glassIn {
  from { opacity: 0; transform: translateY(12px) scale(.99); }
  to   { opacity: 1; transform: none; }
}

/* Inputs */
.glass-input {
  width: 100%;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 14px;
  color: var(--text);
  outline: none;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.glass-input:hover { border-color: var(--border-strong); }
.glass-input:focus {
  border-color: var(--blue-light);
  box-shadow: var(--focus-ring);
}
.glass-input::placeholder { color: var(--text3); }

/* Primary button */
.btn-glass-primary {
  width: 100%;
  padding: 12px;
  background: var(--blue-main);
  color: var(--on-accent);
  border: none;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: background var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn-glass-primary:hover {
  background: var(--blue-deep);
  box-shadow: 0 6px 18px rgba(0,85,164,0.28);
}
.btn-glass-primary:active { transform: scale(.99); }
.btn-glass-primary:disabled { opacity: .7; cursor: wait; }

/* Brillo del botón: solo al pasar el mouse, no en bucle */
.shimmer {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,.18) 50%, transparent 100%);
  transform: translateX(-100%);
  pointer-events: none;
}
.btn-glass-primary:hover .shimmer {
  transform: translateX(100%);
  transition: transform 700ms var(--ease);
}

/* Secondary button */
.btn-glass-secondary {
  width: 100%;
  padding: 10px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text2);
  font-size: 13px;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.btn-glass-secondary:hover {
  background: var(--bg3);
  border-color: var(--border-strong);
  color: var(--text);
}

/* Alerts */
.alert-glass-error {
  background: var(--red-bg);
  border: 1px solid var(--red-border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 13px;
  color: var(--red);
  display: flex;
  align-items: center;
  gap: 8px;
  animation: alertIn var(--dur-base) var(--ease) both;
}
@keyframes alertIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
.alert-glass-warn {
  background: var(--amber-bg);
  border: 1px solid var(--amber-border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 13px;
  color: var(--amber);
  display: flex;
  align-items: flex-start;
  gap: 8px;
  text-align: left;
  line-height: 1.55;
  animation: alertIn var(--dur-base) var(--ease) both;
}

/* ─── LOADING SPINNER ─────────────────────────────── */
.spinner {
  width: 16px; height: 16px;
  border: 2px solid rgba(255,255,255,.3);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin .7s linear infinite;
  display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ─── DIVIDER ─────────────────────────────────────── */
.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0;
  font-size: 11px;
  color: var(--text3);
  text-transform: uppercase;
  letter-spacing: .5px;
  font-weight: 500;
}
.div-line {
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* ═══════════════════════════════════════════════════
   CHART CONTAINERS
   ═══════════════════════════════════════════════════ */
.chart-wrap {
  position: relative;
  width: 100%;
}
.chart-wrap canvas {
  width: 100% !important;
}

/* ═══════════════════════════════════════════════════
   DASHBOARD GRID & CHART CARDS
   ═══════════════════════════════════════════════════ */
/* Diagnóstico arriba, Actividad del sistema debajo (ancho completo) */
.dashboard-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-bottom: 16px;
}

/* Dos tarjetas lado a lado (Actividad reciente + Reglas de red). Con minmax(0, …) una
   lista de dominios sin cortes ya no ensancha la columna ni desborda la página; en
   pantallas chicas se apilan. */
.dash-dos-col {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 14px;
  margin-bottom: 16px;
}
@media (max-width: 1100px) {
  .dash-dos-col { grid-template-columns: minmax(0, 1fr); }
}

/* Interior del Diagnóstico: velocímetro + métricas | recursos + historial */
.diag-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
  align-items: center;
}
.diag-col {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}
.diag-col + .diag-col {
  padding-left: 28px;
  border-left: 1px solid var(--border);
}
@media (max-width: 900px) {
  .diag-body { grid-template-columns: 1fr; }
  .diag-col + .diag-col { padding-left: 0; border-left: none; }
}

/* Resumen de reglas: dona chica + leyenda, arriba de la lista de toggles */
.reglas-resumen {
  display: flex;
  align-items: center;
  gap: 18px;
  padding-bottom: 14px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.reglas-donut {
  position: relative;
  width: 128px;
  height: 128px;
  flex-shrink: 0;
}
.reglas-donut .donut-center-val { font-size: 24px; }
.reglas-donut .donut-center-label { font-size: 10px; }
.reglas-resumen .chart-legend {
  flex: 1;
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}
.chart-card {
  display: flex;
  flex-direction: column;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px 24px;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--dur-base) var(--ease);
}
/* El gráfico ocupa el alto sobrante cuando la fila la estira el Diagnóstico */
.chart-card .chart-wrap { flex: 1; }
/* Canvas fuera del flujo: así no sostiene el alto viejo al achicar la ventana */
.chart-card .chart-wrap > canvas { position: absolute; top: 0; left: 0; }
.chart-card:hover { border-color: var(--border-strong); }
.chart-card .card-title {
  margin-bottom: 4px;
}
.chart-card canvas {
  width: 100% !important;
}
.chart-sub {
  font-size: 12px;
  color: var(--text3);
  margin-bottom: 16px;
}

/* Estado vacío dentro de un gráfico */
.chart-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: var(--text3);
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  background: var(--soft-bg);
}
.chart-empty[hidden] { display: none; }

/* Leyenda tipo lista: punto + nombre + % + valor */
.chart-legend {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.chart-legend-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  transition: background var(--dur-fast) var(--ease);
}
.chart-legend-row:hover { background: var(--soft-bg); }
.chart-legend-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.chart-legend-name { flex: 1; color: var(--text2); }
.chart-legend-pct {
  color: var(--text3);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.chart-legend-val {
  min-width: 24px;
  text-align: right;
  color: var(--text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Doughnut center label */
.donut-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  pointer-events: none;
}
.donut-center-val {
  font-size: 30px;
  font-weight: 650;
  letter-spacing: -.02em;
  color: var(--text);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* Velocímetro (semicírculo) */
.gauge-wrap {
  position: relative;
  height: 170px;
  width: 100%;
  max-width: 320px;
  margin: 0 auto;
}
.gauge-canvas {
  position: absolute;
  inset: 0 0 18px 0;
}
.gauge-center {
  position: absolute;
  left: 0; right: 0;
  bottom: 26px;
  text-align: center;
  pointer-events: none;
}
.gauge-val {
  font-size: 34px;
  font-weight: 650;
  letter-spacing: -.02em;
  color: var(--text);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.gauge-unit {
  font-size: 11px;
  font-weight: 500;
  color: var(--text3);
  text-transform: uppercase;
  letter-spacing: .4px;
  margin-top: 4px;
}
.gauge-tick {
  position: absolute;
  bottom: 0;
  font-size: 11px;
  color: var(--text3);
  font-variant-numeric: tabular-nums;
}
.gauge-tick-min { left: 6%; }
.gauge-tick-max { right: 6%; }

/* Barra de progreso fina (CPU / RAM) */
.meter {
  height: 6px;
  background: var(--bg4);
  border-radius: 999px;
  overflow: hidden;
}
.meter-fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  transition: width var(--dur-slow) var(--ease);
}
.donut-center-label {
  font-size: 11px;
  color: var(--text3);
  margin-top: 2px;
  text-transform: uppercase;
  letter-spacing: .4px;
  font-weight: 500;
}

/* ─── STAT TREND BADGES ──────────────────────────── */
.stat-trend-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
}
.stat-trend-up {
  background: var(--green-bg);
  color: var(--green);
}
.stat-trend-down {
  background: var(--red-bg);
  color: var(--red);
}
.stat-trend-neutral {
  background: var(--bg3);
  color: var(--text2);
}

/* ─── WELCOME HEADER ─────────────────────────────── */
.welcome-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 20px;
}
.welcome-title {
  font-size: 24px;
  font-weight: 650;
  letter-spacing: -.02em;
  line-height: 1.2;
}
.welcome-sub {
  font-size: 13px;
  color: var(--text2);
  margin-top: 4px;
}

/* ─── FILTER CHIPS ───────────────────────────────── */
.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--bg2);
  color: var(--text2);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.filter-chip:hover {
  border-color: var(--border-strong);
  color: var(--text);
  background: var(--bg3);
}
.filter-chip:active { transform: scale(.97); }
.filter-chip.active {
  background: var(--blue-glow);
  color: var(--blue-light);
  border-color: var(--blue-border);
}
.filter-chip .chip-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* ─── TABLE AVATARS (enhanced) ───────────────────── */
.t-user-cell {
  display: flex;
  align-items: center;
  gap: 10px;
}
.t-user-cell .t-avatar {
  width: 32px;
  height: 32px;
}
.t-user-info {
  min-width: 0;
}
.t-user-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.t-user-email {
  font-size: 12px;
  color: var(--text3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ─── EXPORT DROPDOWN ────────────────────────────── */
.export-dropdown {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 5px;
  z-index: 200;
  min-width: 150px;
  box-shadow: var(--shadow-lg);
  display: none;
}
#exportMenu, #audExportMenu { min-width: 230px; }
.export-wrap { position: relative; }
a.export-item { text-decoration: none; }
.export-ayuda { padding: 6px 10px 8px; margin: 0 0 4px; max-width: 250px; font-size: 11px; line-height: 1.4; color: var(--text3); border-bottom: 1px solid var(--border); }
.export-dropdown.show {
  display: block;
  animation: dropIn var(--dur-base) var(--ease) both;
}
@keyframes dropIn {
  from { opacity: 0; transform: translateY(-4px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
.export-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 10px;
  border: none;
  background: none;
  color: var(--text2);
  font-size: 13px;
  cursor: pointer;
  border-radius: 6px;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.export-item:hover {
  background: var(--bg3);
  color: var(--text);
}

/* ─── MIKROTIK TEST BUTTON (enhanced) ────────────── */
.btn-test-connection {
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--purple-border);
  background: var(--purple-bg);
  color: var(--purple);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn-test-connection:hover {
  border-color: var(--purple);
  background: var(--purple-bg);
  box-shadow: 0 0 0 3px var(--purple-bg);
}
.btn-test-connection:active { transform: scale(.98); }

/* ═══════════════════════════════════════════════════
   MBOPI — MASCOTA (dibujo y lógica en static/js/mbopi.js)
   La figura es apaisada (240 × 150): cada lugar le da un ancho y un alto en esa
   proporción. Con data-mbopi-compacto las alas son cortas (152 × 104).
   ═══════════════════════════════════════════════════ */
:root { --mb-borde: #6FA8D6; }
[data-theme="light"] { --mb-borde: #2F6794; }
.mbopi {
  display: inline-block;
  position: relative;
  width: 96px; height: 60px;
  flex-shrink: 0;
  cursor: pointer;
  border-radius: 50%;
  vertical-align: middle;
  transition: transform var(--dur-base) var(--ease);
}
.mbopi[data-mbopi-ficha="no"] { cursor: default; }
.mbopi[role="button"]:hover { transform: translateY(-2px); }
.mbopi:focus-visible { outline: 2px solid var(--blue-light); outline-offset: 2px; box-shadow: var(--focus-ring); }
.mbopi-svg { width: 100%; height: 100%; display: block; overflow: visible; }
.mbopi-mini   { width: 38px; height: 26px; }
.mbopi-grande { width: 192px; height: 120px; }

/* Movimientos del dibujo */
.mb-flota  { animation: mbFlota 3s ease-in-out infinite; }
.mb-aleteo { animation: mbAleteo 1.8s ease-in-out infinite; transform-origin: 116px 128px; transform-box: view-box; }
.mb-mece   { animation: mbMece 3.6s ease-in-out infinite; transform-origin: 120px 24px; transform-box: view-box; }
.mb-gira   { animation: mbGira 6s linear infinite; transform-origin: 120px 34px; transform-box: view-box; }
.mb-led    { animation: mbLed 1s steps(2) infinite; }
.mb-onda   { animation: mbOnda 1.8s ease-in-out infinite; }
.mb-onda-2 { animation-delay: .25s; }
.mb-onda-3 { animation-delay: .5s; }
.mb-zz     { animation: mbZz 2.6s ease-in-out infinite; }
.mb-hueco  { fill: var(--bg2); }
@keyframes mbFlota  { 50% { transform: translateY(-3px); } }
@keyframes mbAleteo { 50% { transform: rotate(-7deg); } }
@keyframes mbMece   { 50% { transform: rotate(4deg); } }
@keyframes mbGira   { to  { transform: rotate(360deg); } }
@keyframes mbLed    { 50% { opacity: .25; } }
@keyframes mbOnda   { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
@keyframes mbZz     { 0% { opacity: 0; transform: translate(0, 4px); } 50% { opacity: 1; } 100% { opacity: 0; transform: translate(4px, -6px); } }

/* Sonar: anillos que se expanden al tocarlo o al cambiar de estado.
   Círculo centrado (Mbopi es más ancho que alto: sin esto sería un óvalo) */
.mb-ping {
  position: absolute; left: 50%; top: 50%;
  height: 100%; aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  border: 2px solid var(--blue-light);
  pointer-events: none;
  animation: mbPing 1.2s var(--ease) forwards;
}
.mb-ping::after {
  content: '';
  position: absolute; inset: -2px;
  border-radius: 50%;
  border: 2px solid var(--blue-light);
  pointer-events: none;
  animation: mbPing 1.2s var(--ease) .25s forwards;
  opacity: 0;
}
@keyframes mbPing { from { transform: scale(.6); opacity: .8; } to { transform: scale(1.9); opacity: 0; } }

/* Cambio de estado: sale, se redibuja y entra */
.mbopi.mb-saliendo { animation: mbSale 220ms cubic-bezier(.4, 0, 1, 1) forwards; }
.mbopi.mb-entrando { animation: mbEntra 480ms var(--ease); }
@keyframes mbSale  { to { opacity: 0; transform: scale(.85) translateY(4px); } }
@keyframes mbEntra { 0% { opacity: 0; transform: scale(.8); } 60% { opacity: 1; transform: scale(1.06); } 100% { transform: none; } }

/* Indicador del router (topbar): el punto toma el color del estado */
.status-pill.offline { background: var(--red-bg);   color: var(--red);   border-color: var(--red-border); }
.status-pill.mant    { background: var(--amber-bg); color: var(--amber); border-color: var(--amber-border); }
.status-pill.offline .pulse { background: var(--red); }
.status-pill.mant .pulse    { background: var(--amber); }
.status-pill:not(.online):not(.offline):not(.mant) .pulse { background: var(--text3); }

/* Mbopi como logo de la barra lateral (a la izquierda de "coNETate") */
.mb-compa {
  position: relative;
  z-index: 2;                       /* vuela por delante del texto del logo */
  width: 80px; height: 56px;
  margin: -4px -10px -4px -12px;    /* las puntas de las alas pueden invadir el margen */
  flex-shrink: 0;
}
.mb-compa .mbopi { width: 80px; height: 56px; }
.mb-compa.mb-accion-vuelo     { animation: mbVuelo 2.8s var(--ease); }
.mb-compa.mb-accion-voltereta { animation: mbVoltereta .95s var(--ease); }
.mb-compa.mb-accion-saludo    { animation: mbSaludo 1s var(--ease); }
.mb-compa.mb-accion-busca     { animation: mbBusca 1.6s ease-in-out; }
/* Vuelo: sale hacia la derecha por encima del nombre y vuelve a su lugar */
@keyframes mbVuelo {
  0%   { transform: none; }
  22%  { transform: translate(42px, -12px) rotate(9deg) scale(.92); }
  48%  { transform: translate(122px, -3px) rotate(3deg) scale(.86); }
  62%  { transform: translate(108px, 10px) rotate(-7deg) scale(.88); }
  84%  { transform: translate(22px, 7px)   rotate(-4deg); }
  100% { transform: none; }
}
@keyframes mbVoltereta {
  0%   { transform: none; }
  45%  { transform: translateY(-9px) rotate(-180deg); }
  85%  { transform: translateY(0) rotate(-360deg); }
  100% { transform: rotate(-360deg); }
}
@keyframes mbSaludo {
  0%, 100% { transform: none; }
  25% { transform: translateY(-6px) rotate(-7deg); }
  50% { transform: translateY(0); }
  75% { transform: translateY(-4px) rotate(7deg); }
}
@keyframes mbBusca {
  0%, 100% { transform: none; }
  20% { transform: rotate(-12deg); }
  45% { transform: rotate(10deg); }
  70% { transform: rotate(-6deg); }
}
.mb-led-lento { animation: mbLed 2.4s steps(2) infinite; }

/* Servidor detenido: aviso a pantalla completa (lo maneja app.js) */
.srv-caido {
  position: fixed; inset: 0;
  z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: rgba(5, 8, 14, .72);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease);
}
[data-theme="light"] .srv-caido { background: rgba(16, 24, 40, .45); }
.srv-caido.visible { opacity: 1; }
.srv-caido-tarjeta {
  width: 100%; max-width: 400px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: 28px 26px 24px;
  text-align: center;
  transform: translateY(10px) scale(.97);
  transition: transform var(--dur-slow) var(--ease);
}
.srv-caido.visible .srv-caido-tarjeta { transform: none; }
.srv-caido-mbopi { display: block; width: 208px; height: 130px; margin: 0 auto 8px; cursor: default; }
.srv-caido-titulo { font-size: 18px; font-weight: 650; letter-spacing: -.02em; margin-bottom: 8px; }
.srv-caido-texto  { font-size: 13.5px; color: var(--text2); line-height: 1.6; }
.srv-caido-estado {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 16px; padding: 5px 12px;
  border-radius: 20px;
  font-size: 12px; color: var(--text2);
  background: var(--soft-bg); border: 1px solid var(--soft-border);
}
.srv-caido-estado.ok { color: var(--green); background: var(--green-bg); border-color: var(--green-border); }
.srv-caido-puntos { display: inline-flex; gap: 3px; }
.srv-caido-puntos i {
  width: 5px; height: 5px; border-radius: 50%;
  background: currentColor;
  animation: mbOnda 1.2s ease-in-out infinite;
}
.srv-caido-puntos i:nth-child(2) { animation-delay: .2s; }
.srv-caido-puntos i:nth-child(3) { animation-delay: .4s; }

/* Bienvenida al administrador (la anima mbopi.js; solo al iniciar sesión) */
html.mb-bv-activa .mb-compa { opacity: 0; }
.mb-bv {
  position: fixed; inset: 0;
  z-index: 3000;
  overflow: hidden;
  cursor: pointer;
  color: #fff;
  --mb-borde: #6FA8D6;              /* el fondo siempre es oscuro, también en tema claro */
}
.mb-bv-fondo { position: absolute; inset: 0; background: rgba(5, 8, 14, .74); opacity: 0; }
[data-theme="light"] .mb-bv-fondo { background: rgba(5, 8, 14, .86); }   /* sobre fondo blanco hace falta más para que el texto se lea */
.mb-bv-figura {
  position: absolute; left: 50%; top: 42%;
  width: min(240px, 60vw); aspect-ratio: 1.6;
  translate: -50% -50%;
  opacity: 0;
  will-change: transform, opacity;
}
.mb-bv-figura .mbopi { display: block; width: 100%; height: 100%; }
.mb-bv .mb-aleteo { animation-duration: .55s; }
.mb-bv-anillo {
  position: absolute; left: 50%; top: calc(42% - 10px);
  width: 110px; height: 110px;
  margin: -55px 0 0 -55px;
  border-radius: 50%;
  border: 1.5px solid #4FC3F7;
  opacity: 0;
}
.mb-bv-texto {
  position: absolute; left: 0; right: 0;
  top: calc(42% + min(84px, 21vw));
  padding: 0 16px;
  text-align: center;
  opacity: 0;
}
.mb-bv-texto b { display: block; font-size: 24px; font-weight: 650; letter-spacing: -.02em; }
.mb-bv-texto > span { display: block; font-size: 14px; color: #C6CFDB; margin-top: 4px; }
.mb-bv-red {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 12px;
  font-style: normal; font-size: 13px;
  color: #3DD68C;
}
.mb-bv-red i { font-style: normal; }
.mb-bv-red u { display: block; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.mb-bv-red.sin  { color: #FF9C9C; }
.mb-bv-red.mant { color: #FFC53D; }
/* Despedida al cerrar sesión (salirDelPanel en app.js): misma capa que la bienvenida, sin anillos
   ni línea de la red; no se puede saltear (dura ~0,75 s y después viene el login) */
.mb-desp { cursor: default; }

/* En las notificaciones */
.toast .toast-mbopi { width: 40px; height: 28px; margin: -4px 0; }

/* Ficha "¿Quién es Mbopi?" */
.mbopi-ficha-fondo {
  position: fixed; inset: 0;
  z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: rgba(5, 8, 14, .6);
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur-base) var(--ease);
}
[data-theme="light"] .mbopi-ficha-fondo { background: rgba(16, 24, 40, .35); }
.mbopi-ficha-fondo.abierta { opacity: 1; pointer-events: all; }
.mbopi-ficha {
  position: relative;
  width: 100%; max-width: 420px;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: 26px 26px 22px;
  text-align: center;
  transform: translateY(10px) scale(.97);
  transition: transform var(--dur-slow) var(--ease);
}
.mbopi-ficha-fondo.abierta .mbopi-ficha { transform: none; }
.mbopi-ficha-fondo.abierta .mbopi-ficha > * { animation: fadeUp var(--dur-slow) var(--ease) backwards; }
.mbopi-ficha-fondo.abierta .mbopi-ficha > :nth-child(3) { animation-delay: 60ms; }
.mbopi-ficha-fondo.abierta .mbopi-ficha > :nth-child(4) { animation-delay: 100ms; }
.mbopi-ficha-fondo.abierta .mbopi-ficha > :nth-child(n+5) { animation-delay: 150ms; }
.mbopi-ficha-cerrar {
  position: absolute; top: 12px; right: 12px;
  width: 30px; height: 30px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text2);
  font-size: 18px; line-height: 1;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.mbopi-ficha-cerrar:hover { background: var(--bg3); color: var(--text); }
.mbopi-ficha-heroe { position: relative; width: 192px; height: 120px; margin: 0 auto 6px; }
.mbopi-ficha-heroe .mbopi { position: relative; z-index: 1; }
.mb-sonar i {
  position: absolute; left: 50%; top: 50%;
  width: 100px; height: 100px;
  margin: -50px 0 0 -50px;
  border-radius: 50%;
  border: 1.5px solid var(--blue-light);
  opacity: 0;
  animation: mbSonar 3s var(--ease) infinite;
}
.mb-sonar i:nth-child(2) { animation-delay: 1s; }
.mb-sonar i:nth-child(3) { animation-delay: 2s; }
@keyframes mbSonar { from { transform: scale(.7); opacity: .5; } to { transform: scale(1.5); opacity: 0; } }
.mbopi-ficha-eyebrow {
  font-size: 12px; font-weight: 600;
  letter-spacing: .2px;
  color: var(--blue-light);
}
.mbopi-ficha h3 { font-size: 20px; font-weight: 650; letter-spacing: -.02em; margin: 2px 0 10px; }
.mbopi-ficha-texto { font-size: 13.5px; color: var(--text2); line-height: 1.6; margin-bottom: 12px; text-align: left; }
.mbopi-ficha-texto strong { color: var(--text); font-weight: 600; }
.mbopi-ficha-ondas {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 10px 14px;
  border-radius: var(--radius-md);
  background: var(--soft-bg);
  border: 1px solid var(--soft-border);
}
.mbopi-ficha-ondas .mbopi-mini { width: 58px; height: 40px; }
.mb-viaje { position: relative; width: 110px; height: 22px; overflow: hidden; }
.mb-viaje i {
  position: absolute; top: 2px; left: 0;
  width: 10px; height: 18px;
  border-radius: 50%;
  border-right: 2.5px solid var(--blue-light);
  animation: mbIda 1.8s linear infinite;
}
.mb-viaje i:nth-child(2) { animation-delay: .6s; }
.mb-viaje i:nth-child(3) {               /* el eco que vuelve */
  border-right: none; border-left: 2.5px solid var(--green);
  animation-name: mbVuelta; animation-delay: .9s;
}
@keyframes mbIda    { from { transform: translateX(0); opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } to { transform: translateX(100px); opacity: 0; } }
@keyframes mbVuelta { from { transform: translateX(100px); opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } to { transform: translateX(0); opacity: 0; } }
.mb-equipo { width: 28px; height: 28px; color: var(--text2); flex-shrink: 0; }
.mbopi-ficha-pie { font-size: 11.5px; color: var(--text3); margin: 6px 0 14px; }
.mbopi-ficha-subtitulo {
  font-size: 11px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase;
  color: var(--text3); margin: 4px 0 8px;
}
.mbopi-ficha-estados { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-bottom: 18px; }
.mbopi-ficha-estados > div {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 8px 2px 6px;
  border-radius: var(--radius-sm);
  background: var(--soft-bg);
}
.mbopi-ficha-estados .mbopi { width: 78px; height: 49px; }
.mbopi-ficha-estados small { font-size: 11px; color: var(--text2); }
.mbopi-ficha-ok { width: 100%; justify-content: center; padding: 10px; }

/* ═══════════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════════ */
@media (max-width: 768px) {
  /* La barra lateral se parte en dos piezas fijas: el logo arriba y el menú (.sb-menu) abajo.
     La <nav> queda sin tamaño, sin recorte y sin posición propia. Antes la <nav> era la barra
     de abajo (fija y con overflow para deslizar el menú) y el logo, fijo adentro de ella: en
     iPhone (Safari/WebKit) un elemento fijo dentro de otro fijo con overflow se recorta a la
     caja del de afuera, y el encabezado con Mbopi y el logo no se veía (solo los botones de
     la derecha, que viven en .topbar-actions). Chrome no recorta, por eso no se notaba ahí. */
  .sidebar {
    position: static;
    width: 0; height: 0;
    overflow: visible;
    border: 0;
    background: none;
    transition: none;
  }
  .sb-menu {
    display: flex;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 100;
    height: 60px;
    overflow-x: auto; overflow-y: hidden;
    background: var(--bg2);
    border-top: 1px solid var(--border);
  }
  /* Al pasar de una pantalla a otra, el logo y el menú quedan quietos cada uno por su lado */
  html.vt-activa .sidebar { view-transition-name: none; }
  html.vt-activa .sb-logo { view-transition-name: sidebar; }
  html.vt-activa .sb-menu { view-transition-name: menu-abajo; }
  .sb-footer, .sb-section-label { display: none; }
  /* Mbopi y la marca siguen a la vista: el logo pasa a ser el encabezado fijo de arriba
     (es el mismo elemento, así sigue cambiando con el estado de la red y haciendo sus gracias) */
  .sb-logo {
    position: fixed; top: 0; left: 0; right: 0; z-index: 101;
    height: 52px; padding: 0 16px; gap: 8px;
    background: var(--bg2);
    border-bottom: 1px solid var(--border);
  }
  .sb-logo .mb-compa { width: 60px; height: 42px; margin: -2px -6px -2px -10px; }
  .sb-logo .mb-compa .mbopi { width: 60px; height: 42px; }
  .sb-section { display: flex; padding: 0; flex-shrink: 0; }
  .sb-item {
    flex-direction: column;
    padding: 8px 12px;
    font-size: 10px;
    gap: 2px;
    border-radius: 0;
    white-space: nowrap;
    color: var(--text3);
  }
  .sb-item svg { width: 15px; height: 15px; }
  .sb-indicador::after { display: block; left: 8px; right: 8px; top: 0; height: 2px; border-radius: 0 0 2px 2px; }
  .sb-badge { display: none; }
  .main-content {
    margin-left: 0;
    padding: 16px;
    padding-top: 68px;     /* debajo del encabezado con Mbopi (52 px) */
    margin-bottom: 64px;
  }
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .dashboard-grid { grid-template-columns: 1fr; }
  .topbar { flex-direction: column; align-items: flex-start; gap: 12px; }
  .topbar-actions { flex-wrap: wrap; }
  .form-grid { grid-template-columns: 1fr; }
  .welcome-header { flex-direction: column; gap: 12px; }
  .filter-chips { gap: 4px; }
  .toast-container { bottom: 76px; right: 12px; left: 12px; }   /* por encima del menú inferior */
  .toast { max-width: none; }
}
@media (max-width: 480px) {
  .search-input { width: 150px; }
  .glass-card { margin: 16px; }
  .stats-grid { grid-template-columns: 1fr 1fr; }
  .welcome-title { font-size: 20px; }
}
/* Sidebar collapsed state */
.sidebar.collapsed {
  width: 72px;
}
.sidebar.collapsed .sb-logo-text,
.sidebar.collapsed .sb-section-label,
.sidebar.collapsed .sb-item-text,
.sidebar.collapsed .sb-badge,
.sidebar.collapsed .sb-uname,
.sidebar.collapsed .sb-urole {
  display: none;
}
.sidebar.collapsed .sb-item {
  justify-content: center;
  padding: 10px;
}
.sidebar.collapsed .sb-user {
  flex-direction: column;
  padding: 8px 0;
}
.main-content.collapsed {
  margin-left: 72px;
}

/* ─── MOVIMIENTO REDUCIDO ────────────────────────── */
/* Si el usuario desactivó las animaciones en su sistema, se respetan. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* ═══════════════════════════════════════════════════
   HISTORIAL DE RED (dashboard e informe)
   ═══════════════════════════════════════════════════ */
.hist-controles { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 14px; }
.seg-ctl {
  display: flex;
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 2px;
}
.seg-ctl button {
  border: 0;
  background: none;
  color: var(--text2);
  font-size: 12px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.seg-ctl button:hover { color: var(--text); }
.seg-ctl button.on { background: var(--bg2); color: var(--text); box-shadow: var(--shadow-sm); }
.hist-rango { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 12px; color: var(--text3); }
.hist-rango[hidden] { display: none; }

/* ─── SESIONES — FILTROS ─── */
.ses-filtros { display: flex; flex-direction: column; gap: 12px; padding: 14px 20px; }   /* aire con la línea del encabezado */
.ses-filtros-fila { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.ses-filtros-fila[hidden] { display: none; }
.ses-filtros-historial { padding-top: 12px; border-top: 1px dashed var(--border); }
.ses-espacio { flex: 1; }
/* Todos los campos de la barra con el mismo alto */
.ses-filtros .search-input, .ses-filtros .f-input, .ses-filtros .f-select {
  height: 34px; padding-top: 0; padding-bottom: 0; font-size: 12.5px;
}
.ses-filtros .search-input { width: 230px; }
.ses-filtros .seg-ctl button { padding: 6px 13px; }
.ses-campo { display: inline-flex; align-items: center; gap: 8px; }
.ses-campo .f-select { width: auto; min-width: 190px; padding: 7px 34px 7px 10px; font-size: 12.5px; }
.ses-etq { font-size: 10.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--text3); }
.ses-activos { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 12px; color: var(--text3); }
.ses-activos:empty { display: none; }
.ses-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 3px 3px 10px; border-radius: 999px;
  background: var(--blue-glow); border: 1px solid var(--blue-border);
  color: var(--text); font-size: 12px; font-weight: 500;
}
.ses-chip button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border: 0; border-radius: 50%;
  background: none; color: var(--text2); font-size: 14px; line-height: 1; cursor: pointer;
}
.ses-chip button:hover { background: var(--bg3); color: var(--text); }
.ses-cierre { display: inline-flex; flex-direction: column; line-height: 1.35; }
/* Una persona con varias sesiones abiertas: una sola fila que se despliega con cada dispositivo */
.sesion-grupo .sesion-cab { cursor: pointer; }
.sesion-grupo.abierto .sesion-cab { background: var(--soft-bg); }
.ses-n-disp { display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; background: var(--blue-glow); color: var(--blue-light); vertical-align: 1px; white-space: nowrap; }
.ses-grupo-ips { font-family: monospace; font-size: 10.5px; color: var(--text3); overflow-wrap: anywhere; }
.ses-desplegar { gap: 5px; }
.ses-desplegar svg { transition: transform var(--dur-fast) var(--ease); }
.sesion-grupo.abierto .ses-desplegar svg { transform: rotate(180deg); }
.sesion-hijas { margin-left: 18px; border-left: 3px solid var(--blue-border); background: var(--soft-bg); }
.sesion-hijas .table-row { background: transparent; }
.ses-hija-num { color: var(--text3); font-size: 13px; text-align: center; }
.ses-hija-nombre { font-size: 12.5px; font-weight: 600; color: var(--text2); white-space: nowrap; display: flex; align-items: center; gap: 10px; min-width: 0; }
/* Equipo de cada sesión (sesiones.html: icono_equipo): celular, tableta, computadora o desconocido,
   con el color de la marca para que acompañe el tema claro u oscuro */
.equipo-ico {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 30px; height: 30px; border-radius: 9px;
  background: var(--blue-glow); color: var(--blue-light); border: 1px solid var(--blue-border);
}
.equipo-ico svg { width: 16px; height: 16px; }
.equipo-ico-chico { width: 18px; height: 18px; border-radius: 5px; border: 0; vertical-align: -4px; margin-right: 5px; }
.equipo-ico-chico svg { width: 12px; height: 12px; }
.equipo-txt { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.equipo-txt b { font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; }
.equipo-txt small { font-size: 11px; font-weight: 500; color: var(--text3); }
.equipo-linea { display: inline-block; max-width: 100%; vertical-align: top; font-size: 12px; color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ses-grupo-equipos { display: inline-flex; gap: 4px; }
.ses-grupo-equipos .equipo-ico-chico { width: 22px; height: 22px; margin: 0; border: 1px solid var(--blue-border); }
.ses-grupo-equipos .equipo-ico-chico svg { width: 13px; height: 13px; }
.sesion-hijas-pie { display: flex; justify-content: flex-end; padding: 8px 14px 10px; }
@media (prefers-reduced-motion: reduce) { .ses-desplegar svg { transition: none; } }
@media screen and (max-width: 1023px) {
  .sesion-hijas { margin-left: 8px; }
  .sesion-hijas .ses-hija-num, .sesion-hijas .ses-hija-vacio { display: none; }
}
.ses-cierre-hora { font-family: monospace; font-size: 12px; color: var(--text2); }
/* Estado de la sesión como ícono (sesiones.html: icono_estado). El detalle va en title y para
   lectores de pantalla; a la vista solo el tiempo fuera del WiFi o, en un grupo, cuántos hay */
.est {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  height: 24px; min-width: 24px; padding: 0 7px; border-radius: 999px;
  font-size: 11px; font-weight: 600; line-height: 1; white-space: nowrap; vertical-align: middle;
  font-variant-numeric: tabular-nums;
  transition: background var(--dur-base) var(--ease), color var(--dur-base) var(--ease);
}
.est svg { width: 13px; height: 13px; flex: none; }
.est:not(:has(.est-t)) { padding: 0; width: 24px; }
.est-conectada   { background: var(--green-bg);  color: var(--green); }
.est-ausente     { background: var(--amber-bg);  color: var(--amber); }
.est-desconocido { background: var(--blue-glow); color: var(--blue-light); }
.est-expirada    { background: var(--bg3);       color: var(--text2); }
.est-finalizada  { background: var(--red-bg);    color: var(--red); }
.est-grupo { display: inline-flex; flex-wrap: wrap; gap: 4px; vertical-align: middle; }
.ses-leyenda {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px;
  padding: 10px 20px; border-top: 1px solid var(--border);
  font-size: 11px; color: var(--text3);
}
.ses-leyenda > span { display: inline-flex; align-items: center; gap: 6px; }
.ses-leyenda > [hidden] { display: none; }
.ses-leyenda .est { height: 20px; min-width: 20px; }
.ses-leyenda .est:not(:has(.est-t)) { width: 20px; }
.ses-leyenda .est svg { width: 11px; height: 11px; }
.ses-cierre-por { font-size: 11px; color: var(--text3); }
@media screen and (max-width: 800px) {
  /* En el celular cada campo va a lo ancho, con su etiqueta arriba */
  .ses-filtros-fila > * { width: 100%; }
  .ses-filtros-fila > .f-input, .ses-filtros-fila > .f-select { width: 100% !important; }
  .ses-filtros .search-input { width: 100%; }
  .ses-campo { flex-direction: column; align-items: stretch; gap: 6px; }
  .ses-campo .f-select { min-width: 0; width: 100%; }
  .ses-campo .seg-ctl button { flex: 1; padding: 6px 4px; white-space: nowrap; }
  .ses-espacio { display: none; }
}
.hist-rango input {
  font-size: 12px;
  padding: 5px 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--bg3);
  color: var(--text);
}
.mini-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 16px; }
.mini-kpis.cinco { grid-template-columns: repeat(5, 1fr); }
@media screen and (max-width: 768px) {
  .mini-kpis, .mini-kpis.cinco { grid-template-columns: repeat(2, 1fr); }
}
.mini-kpi {
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.mini-kpi-label { font-size: 11px; color: var(--text3); text-transform: uppercase; font-weight: 600; letter-spacing: .3px; }
.mini-kpi-val { font-size: 22px; font-weight: 650; letter-spacing: -.02em; line-height: 1.2; margin-top: auto; padding-top: 4px; font-variant-numeric: tabular-nums; }
.mini-kpi-sub { font-size: 11px; color: var(--text3); margin-top: 2px; }
.hist-leyenda { display: flex; flex-wrap: wrap; gap: 16px; font-size: 12px; color: var(--text2); margin-bottom: 8px; }
.hist-leyenda i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; }
.hist-titulo { font-size: 12px; font-weight: 600; color: var(--text2); margin: 10px 0 2px; }
.hist-pie { font-size: 11px; color: var(--text3); margin-top: 10px; line-height: 1.5; }
.hist { position: relative; }
.hist svg { display: block; width: 100%; overflow: visible; }
.hist-vacio {
  padding: 36px 16px;
  text-align: center;
  font-size: 12px;
  color: var(--text3);
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  background: var(--soft-bg);
}
.hist-linea { position: absolute; top: 0; bottom: 22px; width: 1px; background: var(--border-strong); display: none; pointer-events: none; }
.hist-capa { position: absolute; inset: 0; cursor: crosshair; }
.hist-tip {
  position: absolute;
  display: none;
  pointer-events: none;
  z-index: 5;
  min-width: 190px;
  padding: 9px 12px;
  font-size: 12px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
}
.hist-tip b { display: block; font-size: 12px; margin-bottom: 5px; color: var(--text); }
.hist-tip div { display: flex; justify-content: space-between; gap: 14px; color: var(--text2); margin-top: 2px; }
.hist-tip .n { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.hist-tip i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }

/* ═══════════════════════════════════════════════════
   AUDITORÍA
   ═══════════════════════════════════════════════════ */
.aud-filtros { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 14px 20px; border-bottom: 1px solid var(--border); }
.aud-campo { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text3); }
.aud-campo input, .aud-campo select {
  font-size: 12px;
  padding: 6px 9px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--bg3);
  color: var(--text);
}
.aud-campo input:focus, .aud-campo select:focus { border-color: var(--blue-light); outline: none; box-shadow: var(--focus-ring); }
.aud-tabla-wrap { overflow-x: auto; }
.aud-tabla { width: 100%; border-collapse: collapse; font-size: 12px; }
.aud-tabla th {
  text-align: left;
  padding: 9px 12px;
  font-size: 11px;
  color: var(--text3);
  text-transform: uppercase;
  letter-spacing: .5px;
  font-weight: 600;
  white-space: nowrap;
  background: var(--soft-bg);
  border-bottom: 1px solid var(--border);
}
.aud-tabla td { padding: 10px 12px; color: var(--text2); border-bottom: 1px solid var(--border); vertical-align: top; }
.aud-tabla tbody tr:last-child td { border-bottom: none; }
.aud-tabla tbody tr:hover td { background: var(--soft-bg); }
.aud-mono { font-family: ui-monospace, Consolas, monospace; font-size: 11.5px; color: var(--text3); white-space: nowrap; }
.aud-evento { font-family: ui-monospace, Consolas, monospace; font-size: 11px; font-weight: 600; color: var(--text); white-space: nowrap; }
.aud-desc { min-width: 260px; line-height: 1.45; }
.sev-badge { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; white-space: nowrap; }
.sev-i { background: var(--bg4); color: var(--text2); }
.sev-w { background: var(--amber-bg); color: var(--amber); }
.sev-c { background: var(--red-bg); color: var(--red); }

/* ─── Auditoría: una línea por evento, agrupada por día, con detalle desplegable ─── */
/* Cada evento es un <tbody class="aud-item"> con la fila resumida y la del detalle (oculta);
   antes de cada día va un <tbody class="aud-dia"> con su título */
/* Barra arriba de la lista: cuántos eventos hay en la página y «Desplegar todos» */
.aud-barra {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 12px;
  padding: 9px 12px 9px 16px; font-size: 12px; color: var(--text3);
  /* Queda fija arriba al bajar por la lista: con todo desplegado, «Contraer todos» sigue a mano */
  position: sticky; top: 0; z-index: 3;
  background: var(--bg2); border-bottom: 1px solid var(--border);
}
/* overflow: clip (y no hidden) en la caja de la Auditoría: sigue recortando las esquinas, pero no es
   un contenedor de desplazamiento, así la barra de arriba puede quedar fija (sticky) al bajar */
.table-wrap.aud-caja { overflow: clip; }
@media (max-width: 768px) {
  .aud-barra { top: 52px; flex-wrap: nowrap; }   /* debajo del encabezado con Mbopi del celular */
  .aud-barra-ayuda { display: none; }            /* en una sola línea: «50 eventos» y el botón */
}
.aud-todos svg { transition: transform var(--dur-fast) var(--ease); }
.aud-todos[aria-pressed="true"] { color: var(--blue-light); border-color: var(--blue-border); background: var(--blue-glow); }
.aud-todos[aria-pressed="true"] svg { transform: rotate(180deg); }
.aud-lista tr[hidden] { display: none !important; }
.aud-lista .aud-dia th {
  padding: 7px 12px; font-size: 10.5px; font-weight: 600; letter-spacing: .5px; text-transform: uppercase;
  color: var(--text3); background: var(--soft-bg); border-bottom: 1px solid var(--border);
}
.aud-lista .aud-resumen { cursor: pointer; }
.aud-lista .aud-resumen td { padding: 8px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.aud-lista .aud-item.abierto .aud-resumen td { background: var(--soft-bg); border-bottom-color: transparent; }
.aud-lista td.aud-hora { width: 1%; font-family: ui-monospace, Consolas, monospace; font-size: 11.5px; color: var(--text3); white-space: nowrap; }
.aud-lista td.aud-corta { width: 100%; max-width: 0; min-width: 240px; }
.aud-que { display: flex; align-items: center; gap: 8px; min-width: 0; }
.sev-punto { flex: none; width: 8px; height: 8px; border-radius: 50%; }
.sev-punto.sev-i { background: var(--text3); opacity: .6; }
.sev-punto.sev-w { background: var(--amber); }
.sev-punto.sev-c { background: var(--red); }
.aud-titulo { flex: none; font-weight: 600; font-size: 12.5px; color: var(--text); white-space: nowrap; }
.aud-res { flex: 1; min-width: 0; color: var(--text2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aud-res::before { content: "·"; margin-right: 8px; color: var(--text3); }
.aud-lista td.aud-quien { white-space: nowrap; font-size: 11.5px; color: var(--text3); }
.aud-quien span { display: inline-block; max-width: 190px; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; }
.aud-abrir { width: 36px; text-align: right; }
.aud-flecha {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--radius-sm);
  border: 1px solid transparent; background: transparent; color: var(--text3); cursor: pointer;
  transition: transform .18s ease, color .15s, border-color .15s;
}
.aud-flecha:hover { color: var(--text); border-color: var(--border); }
.aud-item.abierto .aud-flecha { transform: rotate(90deg); color: var(--blue-light); }
.aud-lista .aud-detalle td { padding: 0 12px 14px; background: var(--soft-bg); border-bottom: 1px solid var(--border); }
.aud-det {
  display: flex; flex-direction: column; gap: 14px;
  padding: 14px 16px; border-radius: var(--radius-sm);
  background: var(--bg2); border: 1px solid var(--border);
  animation: aud-desplegar .16s ease-out;
}
@keyframes aud-desplegar { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.aud-relato-cab { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px; }
.aud-chip { padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; background: var(--bg4); color: var(--text2); }
.aud-relato-fecha { font-size: 11.5px; color: var(--text3); }
.aud-relato-txt { font-size: 13.5px; line-height: 1.6; color: var(--text); max-width: 80ch; overflow-wrap: anywhere; }
.aud-det-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(165px, 1fr)); gap: 10px 18px; margin: 0; }
.aud-det-grid dt { font-size: 10.5px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: var(--text3); margin-bottom: 3px; }
.aud-det-grid dd { margin: 0; color: var(--text); font-size: 12.5px; overflow-wrap: anywhere; }
.aud-det-grid dd.aud-mono, .aud-det-grid dd.aud-evento { white-space: normal; }
.aud-det-tit { font-size: 10.5px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: var(--text3); margin-bottom: 6px; }
.aud-det-desc { color: var(--text2); line-height: 1.5; overflow-wrap: anywhere; }
.aud-tecnico { border-top: 1px dashed var(--border); padding-top: 10px; }
.aud-tecnico summary { cursor: pointer; width: max-content; font-size: 11.5px; font-weight: 600; color: var(--text3); }
.aud-tecnico summary:hover { color: var(--text); }
.aud-tecnico[open] summary { margin-bottom: 10px; }
.aud-det .aud-cambios { border-collapse: collapse; font-size: 12px; width: 100%; max-width: 760px; }
.aud-det .aud-cambios th, .aud-det .aud-cambios td { padding: 6px 10px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: top; overflow-wrap: anywhere; background: transparent; }
.aud-det .aud-cambios thead th { font-size: 10.5px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: var(--text3); padding-top: 0; }
.aud-det .aud-cambios tbody th { font-size: 12px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--text); white-space: nowrap; width: 1%; }
.aud-det .aud-cambios tbody tr:last-child th, .aud-det .aud-cambios tbody tr:last-child td { border-bottom: none; }
.aud-det .aud-cambios del, .aud-det .aud-cambios ins { display: inline-block; padding: 1px 7px; border-radius: 5px; text-decoration: none; }
.aud-det .aud-cambios del { background: var(--red-bg); color: var(--red); text-decoration: line-through; text-decoration-thickness: 1px; }
.aud-det .aud-cambios ins { background: var(--green-bg); color: var(--green); font-weight: 600; }
.aud-det .aud-cambios-flecha { color: var(--text3); width: 1%; text-align: center !important; }
@media (prefers-reduced-motion: reduce) {
  .aud-det { animation: none; }
  .aud-flecha { transition: none; }
}
@media (max-width: 800px) {
  .aud-lista .aud-dia th { display: block; padding: 8px 16px; }
  .aud-lista .aud-item { border-bottom: 1px solid var(--border); }
  .aud-lista .aud-item.abierto { background: var(--soft-bg); }
  .aud-lista .aud-resumen {
    display: grid; grid-template-columns: auto 1fr auto; gap: 3px 10px;
    grid-template-areas: "que que abrir" "hora quien abrir";
    padding: 10px 16px; border-bottom: 0;
  }
  .aud-lista .aud-resumen td { display: block; width: auto; padding: 0; border: 0; background: transparent !important; }
  .aud-lista .aud-resumen td::before, .aud-lista .aud-detalle td::before, .aud-lista .aud-det td::before { display: none; }
  .aud-lista td.aud-corta { grid-area: que; max-width: none; min-width: 0; width: auto; }
  .aud-lista td.aud-hora { grid-area: hora; width: auto; padding-left: 16px; }
  .aud-lista td.aud-quien { grid-area: quien; min-width: 0; }
  .aud-lista td.aud-abrir { grid-area: abrir; align-self: center; width: auto; }
  .aud-quien span { max-width: 100%; }
  .aud-que { flex-wrap: wrap; row-gap: 2px; }
  .aud-titulo { white-space: normal; }
  .aud-res { flex-basis: 100%; padding-left: 16px; white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .aud-res::before { display: none; }
  .aud-lista .aud-detalle { padding: 0 16px 12px; border-bottom: 0; }
  .aud-lista .aud-detalle td { display: block; padding: 0; border: 0; background: transparent; }
  .aud-det { padding: 12px; }
  .aud-det-grid { grid-template-columns: 1fr 1fr; }
  .aud-det .aud-cambios thead { display: none; }
  .aud-det .aud-cambios, .aud-det .aud-cambios tbody, .aud-det .aud-cambios tr { display: block; width: 100%; }
  .aud-det .aud-cambios tr { display: grid; grid-template-columns: 1fr auto 1fr; gap: 4px 8px; padding: 8px 0; border-bottom: 1px solid var(--border); }
  .aud-det .aud-cambios tbody tr:last-child { border-bottom: none; }
  .aud-det .aud-cambios th, .aud-det .aud-cambios td { display: block; padding: 0; border: 0; }
  .aud-det .aud-cambios tbody th { grid-column: 1 / -1; width: auto; }
}
.aud-pie { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; padding: 12px 20px; border-top: 1px solid var(--border); font-size: 12px; color: var(--text3); }
.aud-paginas { display: flex; gap: 4px; }
.aud-paginas a, .aud-paginas span {
  min-width: 28px;
  padding: 4px 9px;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--bg3);
  color: var(--text2);
}
.aud-paginas a:hover { border-color: var(--border-strong); color: var(--text); }
.aud-paginas .on { background: var(--blue-main); border-color: var(--blue-main); color: var(--on-accent); }
.aud-paginas .off { opacity: .45; }

/* ═══════════════════════════════════════════════════
   INFORMES IMPRIMIBLES (usuarios y auditoría) — estilo documento
   Hoja A4 siempre clara. Portada con banda de datos y «Control del documento», secciones
   numeradas en barras oscuras, tablas y figuras numeradas. Los colores --i-* salen de la
   marca (marca.css_informe); los de acá son los del azul de fábrica.
   ═══════════════════════════════════════════════════ */
.doc, .doc-hoja {
  --i-oscuro: #002f5a; --i-acento: #8cb2d6; --i-acento-g: #007ff6;
  --i-serie2: #2b68a0; --i-serie3: #94b8d9; --i-kpi-etq: #d1e0ef; --i-gris: #B8C2CB;
  --i-texto: #333F48; --i-etq: #3E4A52; --i-tenue: #6B7780;
  --i-zebra: #F2F4F6; --i-linea: #E3E8ED; --i-portada: #F4F5F7;
}
body.doc-cuerpo { background: #DDE2E8 !important; color: #333F48; padding: 0 0 48px; }
.doc-barra {
  position: sticky; top: 0; z-index: 5; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 16px; background: rgba(255, 255, 255, .92); border-bottom: 1px solid #C9D0D8;
  --text: #1C2024; --text2: #4B5260; --text3: #687080; --border: #C9D0D8; --bg3: #F0F2F5;
}
.doc-barra-tip { margin-right: auto; font-size: 12px; color: #4B5260; }
.doc-hoja {
  width: 210mm; margin: 22px auto 0; background: #fff; color: var(--i-texto);
  font: 10pt/1.5 Arial, "Liberation Sans", Helvetica, sans-serif;
  box-shadow: 0 8px 30px rgba(16, 24, 40, .18); color-scheme: light;
}
.doc { padding: 16mm 16mm 12mm; }
.doc p { margin: 0 0 6px; text-align: justify; }

/* Portada */
.doc-portada {
  height: 297mm; padding: 18mm 16mm 14mm; display: flex; flex-direction: column; overflow: hidden;
  background: linear-gradient(180deg, #fff 0, #fff 60%, var(--i-portada) 60%);
}
.doc-portada-arriba { display: flex; justify-content: space-between; align-items: center; }
.doc-org { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 15pt; color: var(--i-oscuro); }
.doc-org img { height: 44px; max-width: 150px; object-fit: contain; }
.doc-org i {
  width: 42px; height: 42px; border-radius: 11px; background: var(--i-oscuro); color: var(--i-acento);
  display: grid; place-items: center; font-style: normal; font-weight: 800; font-size: 14pt;
}
.doc-wordmark { font-weight: 800; font-size: 12pt; color: var(--i-etq); letter-spacing: -.2px; }
.doc-wordmark span { color: var(--i-acento-g); }
.doc-eyebrow { margin: 34mm 0 0; font-size: 10.5pt; letter-spacing: 2px; color: var(--i-etq); font-weight: 700; text-transform: uppercase; }
.doc-titulo {
  margin: 8px 0 0; max-width: 155mm; font-size: 29pt; line-height: 1.12; font-weight: 800;
  color: var(--i-oscuro); text-transform: uppercase; letter-spacing: -.4px;
}
.doc-titulo::after { content: ""; display: block; width: 22mm; height: 5px; background: var(--i-acento-g); margin-top: 16px; }
.doc-banda {
  margin-top: 12mm; padding: 16px 20px; border-radius: 3px; background: var(--i-oscuro);
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 18px;
}
.doc-banda .ancho { grid-column: span 2; }
.doc-banda p { margin: 0; text-align: left; }
.doc-banda .e { font-size: 7.5pt; font-weight: 700; letter-spacing: .8px; color: var(--i-acento); text-transform: uppercase; }
.doc-banda .v { font-size: 9.5pt; color: #fff; font-weight: 700; margin-top: 2px; }
.doc-control { margin-top: auto; background: #fff; border: 1px solid var(--i-linea); }
.doc-control-t {
  background: var(--i-oscuro); color: #fff; font-size: 9pt; font-weight: 700; letter-spacing: .6px;
  padding: 6px 12px; text-transform: uppercase; border-left: 5px solid var(--i-acento);
}
.doc-control table { width: 100%; border-collapse: collapse; font-size: 8.8pt; }
.doc-control td { padding: 7px 12px; border-bottom: 1px solid var(--i-linea); color: var(--i-etq); vertical-align: top; }
.doc-control tr:last-child td { border-bottom: 0; }
.doc-control td:first-child { width: 34mm; font-weight: 700; color: var(--i-oscuro); }
.doc-linea { display: inline-block; width: 70mm; border-bottom: 1px solid var(--i-tenue); height: 12px; }

/* Encabezado cuando no hay portada */
.doc-cab { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding-bottom: 10px; margin-bottom: 12px; border-bottom: 3px solid var(--i-oscuro); }
.doc-cab .doc-org div { display: flex; flex-direction: column; line-height: 1.2; }
.doc-cab .doc-org span { font-size: 9pt; color: var(--i-tenue); font-weight: 600; }
.doc-cab .doc-org b { font-size: 15pt; }
.doc-cab-der { text-align: right; font-size: 8pt; color: var(--i-tenue); }
.doc-cab-der b { display: block; font-size: 10pt; color: var(--i-oscuro); }

/* Secciones, tablas y figuras */
.doc-junto, .doc-bloque { margin-bottom: 12px; }
.doc-sec {
  margin: 8px 0 8px; padding: 6px 11px; background: var(--i-oscuro); color: #fff;
  font-size: 9.5pt; font-weight: 700; letter-spacing: .6px; text-transform: uppercase;
  border-left: 5px solid var(--i-acento);
}
.doc-subsec { margin: 4px 0 5px; font-size: 10.5pt; color: var(--i-oscuro); }
.doc-cap { margin: 8px 0 5px !important; font-size: 8.8pt; font-weight: 700; color: var(--i-oscuro); text-align: left !important; }
.doc-nota { margin-top: 4px !important; font-size: 7.8pt; color: var(--i-tenue); font-style: italic; text-align: left !important; }
.doc-fig svg { display: block; width: 100%; height: auto; }
.doc-t { width: 100%; border-collapse: collapse; font-size: 8.3pt; }
.doc-t th { background: var(--i-oscuro); color: #fff; font-weight: 700; text-align: left; padding: 5px 7px; }
.doc-t td { padding: 4px 7px; border-bottom: 1px solid var(--i-linea); vertical-align: top; }
.doc-t tbody tr:nth-child(even) td { background: var(--i-zebra); }
.doc-t .n { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.doc-t tr.total td { font-weight: 700; border-top: 2px solid var(--i-oscuro); background: #fff !important; }
.doc-lista { table-layout: auto; }
.doc-lista td { overflow-wrap: anywhere; }
.doc-lista td.doc-mono, .doc-lista td.n { white-space: nowrap; overflow-wrap: normal; }
.doc-mono { font-family: Consolas, "Liberation Mono", monospace; font-size: 7.8pt; }
.doc-fecha { white-space: nowrap; }
.doc-correo { overflow-wrap: anywhere; }
.doc-tenue { color: var(--i-tenue); }
.doc-ok { color: #18794E; font-weight: 700; }
.doc-no { color: #CE2C31; font-weight: 700; }
.doc-sube { color: #18794E; font-weight: 700; }
.doc-baja { color: #CE2C31; font-weight: 700; }
.doc-igual { color: var(--i-tenue); }
.doc-sev-c { color: #CE2C31; font-weight: 700; white-space: nowrap; }
.doc-sev-w { color: #A35200; font-weight: 700; white-space: nowrap; }
.doc-sev-i { color: var(--i-tenue); white-space: nowrap; }
del.doc-antes { color: #CE2C31; }
ins.doc-despues { color: #18794E; text-decoration: none; font-weight: 700; }
.doc-cambios td:last-child { overflow-wrap: anywhere; }
.doc-kpis { display: grid; grid-template-columns: repeat(var(--n, 4), 1fr); background: var(--i-oscuro); border-radius: 3px; margin-top: 4px; }
.doc-kpis > div { padding: 10px 12px; border-right: 1px solid rgba(255, 255, 255, .14); }
.doc-kpis > div:last-child { border-right: 0; }
.doc-kpis b { display: block; color: #fff; font-size: 16pt; line-height: 1.1; }
.doc-kpis span { display: block; color: var(--i-kpi-etq); font-size: 7.5pt; margin-top: 3px; }
.doc-kpis em { display: block; margin-top: 4px; font-style: normal; font-size: 7.5pt; font-weight: 700; color: var(--i-acento); }
.doc-vinetas { margin: 0 0 4px; padding-left: 18px; }
.doc-vinetas li { margin-bottom: 4px; text-align: justify; }
.doc-firmas { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 6px; }
.doc-firmas div { border: 1px solid var(--i-linea); padding: 48px 10px 9px; text-align: center; font-size: 8pt; color: var(--i-etq); min-height: 30mm; }
.doc-firmas b { display: block; border-top: 1px solid var(--i-tenue); padding-top: 5px; color: var(--i-oscuro); }
.doc-pie-pantalla { display: flex; justify-content: space-between; margin-top: 18px; padding-top: 6px; border-top: 1px solid var(--i-linea); font-size: 7.8pt; color: var(--i-tenue); }
.doc-pie-pantalla b { color: var(--i-oscuro); }

@media screen and (max-width: 860px) {
  .doc-hoja { width: auto; margin: 12px 8px 0; }
  .doc { padding: 18px 14px; }
  .doc-portada { height: auto; min-height: 0; padding: 20px 16px; }
  .doc-eyebrow { margin-top: 40px; }
  .doc-titulo { font-size: 22pt; }
  .doc-control { margin-top: 24px; }
  .doc-banda, .doc-firmas { grid-template-columns: 1fr 1fr; }
  .doc-kpis { grid-template-columns: repeat(2, 1fr); }
  .doc-lista { display: block; overflow-x: auto; }
}

@media print {
  @page {
    size: A4;
    margin: 17mm 15mm 16mm;
    @top-left { font: 7.5pt Arial, sans-serif; color: #6B7780; vertical-align: bottom; padding-bottom: 3mm; border-bottom: .5pt solid #E3E8ED; }
    @top-right { font: 7.5pt Arial, sans-serif; color: #6B7780; vertical-align: bottom; padding-bottom: 3mm; border-bottom: .5pt solid #E3E8ED; }
    @bottom-left { font: 7.5pt Arial, sans-serif; color: #6B7780; vertical-align: top; padding-top: 3mm; border-top: .5pt solid #E3E8ED; }
    @bottom-right { content: "Página " counter(page) " de " counter(pages); font: 7.5pt Arial, sans-serif; color: #6B7780; vertical-align: top; padding-top: 3mm; border-top: .5pt solid #E3E8ED; }
  }
  /* La portada va sin márgenes ni encabezado: es la página 1 */
  @page portada { margin: 0; }
  body.doc-cuerpo { background: #fff !important; padding: 0; }
  .doc-barra, .toast-container, .doc-pie-pantalla { display: none !important; }
  .doc-hoja { width: auto; margin: 0; box-shadow: none; }
  .doc { padding: 0; }
  .doc-portada { page: portada; width: 210mm; height: 297mm; break-after: page; }
  .doc-junto, .doc-bloque, .doc-kpis, .doc-firmas, .doc-fig, .doc-t tr { break-inside: avoid; }
  .doc-sec, .doc-subsec, .doc-cap { break-after: avoid; }
  .doc-t thead { display: table-header-group; }   /* el encabezado de la tabla se repite en cada hoja */
  .doc-hoja, .doc-hoja * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ═══════════════════════════════════════════════════
   CONFIGURACIÓN (ajustes desplegables)
   ═══════════════════════════════════════════════════ */
.cfg-layout {
  display: grid;
  grid-template-columns: clamp(300px, 34%, 400px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
.cfg-ajustes, .cfg-principal { min-width: 0; }
.cfg-principal { display: flex; flex-direction: column; gap: 16px; }

.cfg-grupo-label {
  font-size: 10px;
  color: var(--text3);
  text-transform: uppercase;
  letter-spacing: .8px;
  font-weight: 600;
  padding: 0 4px;
  margin: 0 0 8px;
}
.cfg-acc + .cfg-grupo-label { margin-top: 18px; }
.cfg-acc { display: flex; flex-direction: column; gap: 8px; }
.cfg-acc form { display: contents; }   /* el form agrupa campos sin romper el apilado */

.cfg-item {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: border-color var(--dur-base) var(--ease);
}
.cfg-item:hover { border-color: var(--border-strong); }
.cfg-item.open { border-color: var(--blue-border); }

.cfg-head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  background: none;
  border: 0;
  border-radius: var(--radius-lg);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.cfg-head:focus-visible { outline: 2px solid var(--blue-light); outline-offset: -2px; box-shadow: var(--focus-ring); }
.cfg-head [hidden] { display: none !important; }
.cfg-ico {
  width: 32px; height: 32px;
  border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.cfg-ico-blue   { background: var(--blue-glow);  color: var(--blue-light); }
.cfg-ico-purple { background: var(--purple-bg);  color: var(--purple); }
.cfg-ico-green  { background: var(--green-bg);   color: var(--green); }
.cfg-ico-amber  { background: var(--amber-bg);   color: var(--amber); }
.cfg-head-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cfg-head-title { font-size: 13px; font-weight: 600; }
.cfg-head-sub {
  font-size: 11.5px;
  color: var(--text3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cfg-chev { flex-shrink: 0; color: var(--text3); transition: transform var(--dur-base) var(--ease); }
.cfg-item.open .cfg-chev { transform: rotate(180deg); }

/* Despliegue: la fila de la grilla pasa de 0fr a 1fr; lo cerrado queda fuera del foco */
.cfg-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-base) var(--ease);
}
.cfg-item.open .cfg-body { grid-template-rows: 1fr; }
.cfg-body-inner {
  min-height: 0;
  overflow: hidden;
  visibility: hidden;
  transition: visibility 0s linear var(--dur-base);
}
.cfg-item.open .cfg-body-inner { visibility: visible; transition-delay: 0s; }
.cfg-body-pad { padding: 14px 16px 16px; border-top: 1px solid var(--border); }

/* Estado del sistema */
.cfg-estado-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
.cfg-dato {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 10px 12px;
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.cfg-dato-label {
  font-size: 10.5px;
  color: var(--text3);
  text-transform: uppercase;
  letter-spacing: .6px;
  font-weight: 600;
}
.cfg-dato-val { font-size: 13px; font-weight: 500; color: var(--text); overflow-wrap: anywhere; }
.cfg-dato-val.mono  { font-family: monospace; font-weight: 400; }
.cfg-dato-val.ok    { color: var(--green); }
.cfg-dato-val.aviso { color: var(--amber); }

@media (max-width: 1000px) {
  .cfg-layout { grid-template-columns: minmax(0, 1fr); }
  .cfg-ajustes { order: 2; }   /* en pantallas angostas primero el estado y los admins */
}

/* Logo de la organización (vista previa en Organización y límites) */
.cfg-logo { display: flex; align-items: center; gap: 14px; }
.cfg-logo [hidden] { display: none !important; }
.cfg-logo-vista {
  width: 76px; height: 76px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 8px;
  background: var(--bg3);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  color: var(--text3);
}
.cfg-logo-vista.tiene { background: #fff; border: 1px solid var(--border); }   /* blanco, como en el portal */
.cfg-logo-vista img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }
.cfg-logo-acc { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }

/* ═══════════════════════════════════════════════════
   ESTILO APP: diálogo de confirmación, estados de carga,
   esqueletos y entrada/salida de filas (ver app.js)
   ═══════════════════════════════════════════════════ */

/* Diálogo de confirmación (reemplaza a confirm() del navegador) */
.dialogo-confirmar { z-index: 1100; }
.modal-confirmar {
  max-width: 400px;
  width: calc(100% - 32px);
  padding: 22px;
  display: grid;
  grid-template-columns: 40px 1fr;
  gap: 4px 14px;
  align-items: start;
}
.dlg-icono {
  width: 40px; height: 40px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: var(--blue-glow);
  color: var(--blue-light);
  border: 1px solid var(--blue-border);
}
.dlg-icono.peligro { background: var(--red-bg); color: var(--red); border-color: var(--red-border); }
.dlg-titulo { font-size: 15px; font-weight: 600; letter-spacing: -.01em; color: var(--text); line-height: 1.35; padding-top: 2px; }
.dlg-msg { font-size: 13px; color: var(--text2); line-height: 1.5; margin-top: 4px; }
.dlg-acciones { grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
@media (max-width: 480px) {
  .dlg-acciones .btn { flex: 1; justify-content: center; }
}
.btn-danger-solid { background: var(--red); color: var(--bg2); border-color: var(--red); }
.btn-danger-solid:hover { filter: brightness(.94); box-shadow: var(--shadow-sm); }

/* Botón en espera: spinner en lugar del ícono y sin segundo clic */
.btn.cargando { cursor: progress; opacity: .8; }
.btn.cargando > svg { display: none; }
.btn.cargando::before {
  content: '';
  width: 12px; height: 12px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-right-color: transparent;
  animation: spin .7s linear infinite;
}
.toggle.cargando, .card.cargando { opacity: .55; pointer-events: none; cursor: progress; }
.refrescando { opacity: .6; pointer-events: none; transition: opacity var(--dur-fast) var(--ease); }

/* Esqueleto: bloque que brilla mientras llega el dato */
.skeleton {
  position: relative;
  overflow: hidden;
  width: fit-content;
  min-width: 3ch;
  color: transparent !important;
  background: var(--bg3);
  border-radius: 6px;
  user-select: none;
  pointer-events: none;
}
span.skeleton { display: inline-block; }
.skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--soft-border), transparent);
  transform: translateX(-100%);
  animation: shimmer 1.3s var(--ease) infinite;
}
@keyframes shimmer { to { transform: translateX(100%); } }
.hist-esqueleto { width: 100%; height: 170px; border-radius: var(--radius-md); }

/* Filas que aparecen o salen al actualizar una lista */
@keyframes filaEntra { from { opacity: 0; transform: translateY(-8px); } }
@keyframes filaSale  { to   { opacity: 0; transform: translateX(14px); } }
.entra    { animation: filaEntra var(--dur-slow) var(--ease) both; }
.saliendo { animation: filaSale var(--dur-base) var(--ease) forwards; pointer-events: none; }

/* ═══════════════════════════════════════════════════
   ACCESIBILIDAD
   ═══════════════════════════════════════════════════ */
/* Enlace para saltar el menú con el teclado: aparece solo al recibir el foco */
.skip-link {
  position: fixed;
  top: 8px; left: 8px;
  z-index: 10000;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  background: var(--blue-main);
  color: var(--on-accent);
  font-size: 13px; font-weight: 600;
  transform: translateY(-160%);
  transition: transform var(--dur-fast) var(--ease);
}
.skip-link:focus { transform: none; }
.main-content:focus { outline: none; box-shadow: none; }
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* Los interruptores (.toggle) se operan con teclado: Enter o Espacio */
.toggle[role="switch"]:focus-visible { outline-offset: 3px; }
/* Modo de alto contraste de Windows: se respeta el color del sistema */
@media (forced-colors: active) {
  .btn, .f-input, .f-select, .card, .tag, .toggle { border: 1px solid CanvasText; }
  .toggle.on { background: Highlight; }
  :focus-visible { outline: 2px solid Highlight; box-shadow: none; }
}

/* ═══════════════════════════════════════════════════
   TABLAS: columnas por variable, tarjetas en celular,
   encabezados ordenables y paginación
   ═══════════════════════════════════════════════════ */
.table-cols, .table-row { grid-template-columns: var(--cols, 1fr); column-gap: 12px; }
.table-cols > *, .table-row > * { min-width: 0; }
.th-orden {
  display: inline-flex; align-items: center; gap: 4px;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit;
  cursor: pointer;
}
.th-orden:hover { color: var(--text); }
.th-orden .flecha { font-size: 9px; opacity: .45; }
[aria-sort="ascending"] > .th-orden, [aria-sort="descending"] > .th-orden { color: var(--blue-light); }
[aria-sort="ascending"] > .th-orden .flecha, [aria-sort="descending"] > .th-orden .flecha { opacity: 1; }
.solo-movil { display: none; }
.aud-select {
  background: var(--bg2); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 5px 8px; font-size: 12px;
}
.aud-paginas button {
  min-width: 30px; height: 30px; padding: 0 8px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg2); color: var(--text2); font-size: 12px; cursor: pointer;
}
.aud-paginas button:hover { border-color: var(--border-strong); color: var(--text); }
.aud-paginas button[aria-current="page"] { background: var(--blue-main); border-color: var(--blue-main); color: var(--on-accent); }
.aud-paginas button:disabled { opacity: .45; cursor: default; }
.t-fecha { font-size: 11px; color: var(--text3); }

/* Solo en pantalla: al imprimir, la hoja A4 (~690 px) no debe tomar el formato de celular.
   Hasta 1023 px: con la barra lateral, las tablas de 7-8 columnas no entran (un iPad vertical deja ~520 px). */
@media screen and (max-width: 1023px) {
  .solo-movil { display: inline-flex; }
  .solo-escritorio { display: none !important; }
  .table-cols { display: none; }
  .table-row {
    grid-template-columns: 1fr 1fr;
    gap: 10px 14px;
    padding: 14px 16px;
    align-items: start;
  }
  .table-row > [data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 3px;
    font-size: 10.5px; font-weight: 600; letter-spacing: .5px;
    text-transform: uppercase; color: var(--text3);
  }
  .table-row > .t-num { display: none; }
  .table-row > [data-label] { text-align: left !important; }
  .table-row > .celda-ancha { grid-column: 1 / -1; order: -1; }
  .table-row > .celda-acciones { grid-column: 1 / -1; display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }
  .table-row > .celda-acciones::before { display: none; }
  .table-row > span { overflow-wrap: anywhere; }
}
@media screen and (max-width: 800px) {
  /* Auditoría: la tabla pasa a tarjetas */
  .aud-tabla thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); }
  .aud-tabla, .aud-tabla tbody, .aud-tabla tr, .aud-tabla td { display: block; width: 100%; }
  .aud-tabla tr { padding: 12px 16px; border-bottom: 1px solid var(--border); }
  .aud-tabla tbody tr:last-child { border-bottom: none; }
  .aud-tabla td { display: flex; gap: 10px; padding: 3px 0; border: 0; }
  .aud-tabla td::before {
    content: attr(data-label);
    flex: 0 0 86px;
    padding-top: 1px;
    font-size: 10.5px; font-weight: 600; letter-spacing: .4px;
    text-transform: uppercase; color: var(--text3);
  }
  .aud-desc { min-width: 0; }
  .aud-mono, .aud-evento { white-space: normal; overflow-wrap: anywhere; }
  .aud-pie { justify-content: center; text-align: center; }
}

/* ═══════════════════════════════════════════════════
   IMPORTAR USUARIOS (Excel / CSV)
   ═══════════════════════════════════════════════════ */
.modal.modal-ancho { max-width: 680px; max-height: calc(100vh - 32px); overflow-y: auto; }
.imp-pasos { display: flex; gap: 8px; list-style: none; margin: 0 0 18px; padding: 0; counter-reset: paso; }
.imp-pasos li {
  flex: 1; display: flex; align-items: center; gap: 8px;
  padding-bottom: 9px; border-bottom: 2px solid var(--border);
  font-size: 12px; color: var(--text3); counter-increment: paso;
}
.imp-pasos li::before {
  content: counter(paso);
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 20px; height: 20px; border-radius: 50%;
  font-size: 11px; font-weight: 700; background: var(--bg4); color: var(--text2);
}
.imp-pasos li.on { color: var(--text); font-weight: 600; border-color: var(--blue-light); }
.imp-pasos li.hecho { border-color: var(--blue-border); }
.imp-pasos li.on::before, .imp-pasos li.hecho::before { background: var(--blue-main); color: #fff; }
.imp-zona {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 32px 16px; text-align: center; cursor: pointer;
  border: 1.5px dashed var(--border); border-radius: var(--radius-lg);
  background: var(--soft-bg); color: var(--text3);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.imp-zona:hover, .imp-zona.arrastrando { border-color: var(--blue-light); background: var(--blue-glow); color: var(--blue-light); }
.imp-zona:focus-within { box-shadow: var(--focus-ring); border-color: var(--blue-light); }
.imp-zona strong { font-size: 14px; color: var(--text); }
.imp-zona span { font-size: 12px; color: var(--text3); }
.imp-zona.cargando { pointer-events: none; opacity: .7; }
.imp-ayuda { margin-top: 12px; font-size: 12px; line-height: 1.55; color: var(--text3); }
.imp-ayuda b { color: var(--text2); }
.imp-ayuda a { color: var(--blue-light); font-weight: 600; }
.imp-archivo-info {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin-bottom: 16px; font-size: 12.5px; color: var(--text3);
}
.imp-archivo-info strong { color: var(--text); overflow-wrap: anywhere; }
.imp-archivo-info .btn { margin-left: auto; }
.imp-opc { font-weight: 400; color: var(--text3); }
.imp-check { display: flex; align-items: center; gap: 8px; margin: 2px 0 12px; font-size: 12.5px; color: var(--text2); cursor: pointer; }
.imp-existentes {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  margin: 0 0 16px; padding: 10px 12px 12px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 12.5px; color: var(--text2);
}
.imp-existentes legend { padding: 0 4px; font-size: 10.5px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: var(--text3); }
.imp-existentes label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.imp-sub { margin: 0 0 6px; font-size: 10.5px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: var(--text3); }
.imp-sub span { text-transform: none; letter-spacing: 0; font-weight: 400; }
.imp-tabla { overflow: auto; max-height: 210px; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.imp-tabla table { width: 100%; border-collapse: collapse; font-size: 12px; }
.imp-tabla th {
  position: sticky; top: 0; padding: 7px 10px; text-align: left; background: var(--bg3);
  font-size: 10.5px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: var(--text3);
}
.imp-tabla td { padding: 6px 10px; border-top: 1px solid var(--border); color: var(--text); max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.imp-tabla-errores td:last-child { white-space: normal; color: var(--text2); }
.imp-tabla td.imp-fila { width: 1%; font-family: ui-monospace, Consolas, monospace; color: var(--text3); }
.imp-vacio { color: var(--text3); font-style: italic; }
.imp-acciones { display: flex; gap: 8px; margin-top: 18px; }
.imp-acciones .btn-ghost { flex: 1; }
.imp-acciones .btn-primary { flex: 2; justify-content: center; }
.imp-resumen { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-bottom: 16px; }
.imp-dato { padding: 12px; border-radius: var(--radius-sm); background: var(--soft-bg); border: 1px solid var(--border); }
.imp-dato b { display: block; font-size: 22px; line-height: 1.15; font-weight: 700; color: var(--text2); }
.imp-dato span { font-size: 11.5px; color: var(--text3); }
.imp-dato.verde b { color: var(--green); }
.imp-dato.azul b { color: var(--blue-light); }
.imp-dato.rojo b { color: var(--red); }
.imp-nota { margin-top: 8px; font-size: 12px; line-height: 1.5; color: var(--text3); }
@media (max-width: 560px) {
  .imp-resumen { grid-template-columns: 1fr 1fr; }
  .imp-pasos li { font-size: 11px; }
}

/* ─── Ventana «Generar informe PDF» (Usuarios y Auditoría) ─── */
.inf-sub { margin: -4px 0 14px; font-size: 12px; color: var(--text3); }
.inf-datos { margin-bottom: 4px; }
.inf-fijo { padding: 8px 0 0; font-size: 13px; color: var(--text); }
.inf-sub-t { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; margin-top: 12px; }
.inf-sub-t > span:first-child { text-transform: uppercase; letter-spacing: .4px; font-weight: 600; }
.inf-ancha { grid-column: 1 / -1; }
.inf-link { border: 0; background: none; padding: 0; margin-left: 12px; font: inherit; font-size: 12px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--blue-light); cursor: pointer; }
.inf-link:hover { text-decoration: underline; }
.inf-partes { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 10px; }
.inf-opc { display: grid; grid-template-columns: 18px 1fr; gap: 1px 9px; align-items: start; padding: 8px 9px; border-radius: var(--radius-sm); cursor: pointer; }
.inf-opc:hover { background: var(--soft-bg); }
.inf-opc input { margin: 2px 0 0; width: 15px; height: 15px; accent-color: var(--blue-main); }
.inf-opc b { font-size: 12.5px; font-weight: 600; color: var(--text); }
.inf-opc span { grid-column: 2; font-size: 11px; line-height: 1.4; color: var(--text3); }
.inf-sep { height: 1px; background: var(--border); margin: 4px 0 6px; }
.inf-chips { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; padding: 0 0 8px 36px; }
.inf-chips[hidden] { display: none; }
.inf-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px 4px 8px; border-radius: 999px; background: var(--bg3); border: 1px solid var(--border); font-size: 12px; color: var(--text2); cursor: pointer; }
.inf-chip input { width: 14px; height: 14px; margin: 0; accent-color: var(--blue-main); }
.inf-resumen { margin: 12px 0 0; padding: 9px 12px; border-radius: var(--radius-sm); background: var(--soft-bg); font-size: 12px; color: var(--text2); }
.inf-resumen b { color: var(--text); }
@media (max-width: 560px) { .inf-partes { grid-template-columns: 1fr; } }

/* ═══════════════════════════════════════════════════
   BÚSQUEDA GLOBAL (Ctrl+K) Y ATAJOS
   ═══════════════════════════════════════════════════ */
.paleta {
  position: fixed; inset: 0; z-index: 1200;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 12vh 16px 16px;
  background: rgba(5, 8, 14, .55);
  backdrop-filter: blur(3px);
}
[data-theme="light"] .paleta { background: rgba(16, 24, 40, .32); }
.paleta[hidden] { display: none; }
.paleta-caja {
  width: min(640px, 100%);
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: fadeUp var(--dur-base) var(--ease) both;
}
.paleta-entrada {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  color: var(--text3);
}
.paleta-entrada input {
  flex: 1; min-width: 0;
  background: none; border: 0; outline: none;
  font-size: 15px; color: var(--text);
}
.paleta-entrada input::placeholder { color: var(--text3); }
.paleta-entrada input:focus-visible { outline: none; box-shadow: none; }   /* la caja entera ya marca el foco */
.paleta-lista { list-style: none; max-height: min(52vh, 420px); overflow-y: auto; padding: 6px; }
.paleta-grupo {
  padding: 10px 10px 4px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase;
  color: var(--text3);
}
.paleta-item {
  display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: 4px 12px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 13px;
}
.paleta-item.activo { background: var(--blue-glow); }
.paleta-item.activo .paleta-tit { color: var(--blue-light); }
.paleta-tit { color: var(--text); font-weight: 500; white-space: nowrap; }
.paleta-det { color: var(--text3); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.paleta-atajo { display: inline-flex; gap: 3px; }
.paleta-vacio { padding: 24px 12px; text-align: center; color: var(--text3); font-size: 13px; }
.paleta-pie {
  display: flex; gap: 16px; flex-wrap: wrap;
  padding: 9px 16px;
  border-top: 1px solid var(--border);
  background: var(--soft-bg);
  font-size: 11px; color: var(--text3);
}
kbd {
  display: inline-block;
  min-width: 20px; padding: 1px 6px;
  border: 1px solid var(--border); border-bottom-width: 2px; border-radius: 5px;
  background: var(--bg3); color: var(--text2);
  font: 600 11px/1.5 ui-monospace, Consolas, monospace;
  text-align: center;
}
.modal-atajos { max-width: 440px; width: calc(100% - 32px); }
.atajos-lista { margin: 14px 0 4px; display: grid; gap: 2px; }
.atajos-lista > div { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.atajos-lista > div:last-child { border-bottom: 0; }
.atajos-lista dd { color: var(--text2); text-align: right; }
.paleta-btn { cursor: pointer; }
@media (max-width: 800px) {
  .paleta { padding-top: 8vh; }
  .paleta-item { grid-template-columns: 1fr; }
  .paleta-atajo, .paleta-pie { display: none; }
}

/* ═══════════════════════════════════════════════════
   GRÁFICOS: comparación con la semana anterior, mapa de calor
   y consumo por usuario
   ═══════════════════════════════════════════════════ */
.hist-comparar { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text2); cursor: pointer; }
.hist-comparar input { accent-color: var(--blue-main); width: 14px; height: 14px; }
.mini-kpi-delta { font-size: 11px; font-weight: 600; margin-top: 2px; min-height: 15px; color: var(--text3); }
.mini-kpi-delta.sube { color: var(--green); }
.mini-kpi-delta.baja { color: var(--amber); }
.hist-leyenda i.punteada {
  width: 14px; height: 0; border-radius: 0;
  border-top: 2px dashed var(--text3); background: none;
}

.calor { display: grid; grid-template-columns: 34px repeat(24, minmax(0, 1fr)); gap: 2px; align-items: center; margin-top: 10px; }
.calor-h { font-size: 10px; color: var(--text3); text-align: left; min-height: 14px; }
.calor-d { font-size: 11px; color: var(--text2); font-weight: 500; }
.calor-celda { height: 24px; border-radius: 4px; background: var(--bg3); }
.calor-celda.con-datos { background: var(--calor-color, var(--blue-light)); opacity: calc(.14 + var(--v, 0) * .86); }
.calor-leyenda { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 11px; color: var(--text3); }
.calor-leyenda i { width: 90px; height: 8px; border-radius: 4px; background: linear-gradient(90deg, color-mix(in srgb, var(--calor-color, var(--blue-light)) 14%, transparent), var(--calor-color, var(--blue-light))); }
.calor-resumen { font-size: 12px; color: var(--text2); margin-top: 10px; min-height: 18px; }

.consumo-lista { list-style: none; display: grid; gap: 12px; margin-top: 14px; }
.consumo-top { display: flex; align-items: baseline; gap: 8px; margin-bottom: 5px; font-size: 12px; }
.consumo-nombre { color: var(--text); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.consumo-ci { color: var(--text3); font-family: ui-monospace, Consolas, monospace; font-size: 11px; }
.consumo-mb { margin-left: auto; color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.consumo-barra { height: 6px; border-radius: 3px; background: var(--bg3); overflow: hidden; }
.consumo-barra i { display: block; height: 100%; border-radius: 3px; background: var(--blue-light); transition: width var(--dur-slow) var(--ease); }
.consumo-item a { color: inherit; display: block; border-radius: var(--radius-sm); }
.consumo-vacio { padding: 26px 8px; text-align: center; color: var(--text3); font-size: 12.5px; }
@media (max-width: 800px) {
  .calor { grid-template-columns: 28px repeat(24, minmax(0, 1fr)); gap: 1px; }
  .calor-celda { height: 20px; border-radius: 3px; }
}

/* ═══════════════════════════════════════════════════
   PORTAL: selector de idioma, mensajes del administrador
   y datos de la sesión
   ═══════════════════════════════════════════════════ */
.idiomas {
  position: fixed; top: 14px; left: 14px; z-index: 30;
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--bg2); border: 1px solid var(--border); border-radius: 999px;
  box-shadow: var(--shadow-sm);
}
.idiomas a {
  padding: 4px 11px; border-radius: 999px;
  font-size: 11px; font-weight: 600; letter-spacing: .3px;
  color: var(--text2);
}
.idiomas a:hover { color: var(--text); background: var(--bg3); }
.idiomas a.on { background: var(--blue-main); color: var(--on-accent); }
.portal-mensaje {
  margin-bottom: 16px; padding: 10px 14px;
  border: 1px solid var(--blue-border); border-radius: var(--radius-md);
  background: var(--blue-glow); color: var(--text);
  font-size: 12.5px; line-height: 1.55; text-align: center;
}
.bienvenida-msg { margin: -10px 0 18px; font-size: 13px; line-height: 1.55; color: var(--text); font-weight: 500; }
.info-item.ancho { grid-column: 1 / -1; }
.nota-consumo { margin: -8px 0 16px; font-size: 10.5px; color: var(--text3); }

/* ═══════════════════════════════════════════════════
   ASISTENTE DE PRIMER USO
   ═══════════════════════════════════════════════════ */
.modal-asistente { max-width: 560px; width: calc(100% - 32px); padding: 0; display: flex; flex-direction: column; max-height: min(88vh, 720px); }
.as-cabecera { padding: 22px 24px 14px; border-bottom: 1px solid var(--border); }
.as-pasos { list-style: none; display: flex; gap: 6px; margin-top: 14px; flex-wrap: wrap; }
.as-pasos li { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text3); }
.as-pasos li span {
  width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg3); color: var(--text3); font-size: 10.5px; font-weight: 700;
}
.as-pasos li + li::before { content: ''; width: 14px; height: 1px; background: var(--border-strong); margin-right: 2px; }
.as-pasos li.actual { color: var(--text); font-weight: 600; }
.as-pasos li.actual span { background: var(--blue-main); color: var(--on-accent); }
.as-pasos li.hecho span { background: var(--green-bg); color: var(--green); }
.as-cuerpo { padding: 20px 24px; overflow-y: auto; flex: 1; }
.as-cuerpo [hidden] { display: none !important; }
.as-ayuda { font-size: 12px; color: var(--text3); line-height: 1.55; margin-top: 8px; }
.as-estado { margin-top: 10px; padding: 9px 12px; border-radius: var(--radius-sm); font-size: 12px; border: 1px solid var(--border); background: var(--bg3); }
.as-estado.ok { color: var(--green); border-color: var(--green-border); background: var(--green-bg); }
.as-estado.error { color: var(--red); border-color: var(--red-border); background: var(--red-bg); }
.as-resumen { list-style: none; display: grid; gap: 8px; margin-bottom: 12px; }
.as-resumen li { display: flex; gap: 10px; align-items: baseline; font-size: 13px; padding: 9px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.as-resumen li.ok { border-color: var(--green-border); background: var(--green-bg); }
.as-resumen li.ok span { color: var(--green); font-weight: 700; }
.as-resumen li.pendiente { color: var(--text2); }
.as-pie { display: flex; align-items: center; gap: 8px; padding: 14px 24px; border-top: 1px solid var(--border); background: var(--soft-bg); }
@media (max-width: 480px) { .as-pasos li:not(.actual) { font-size: 0; gap: 0; } .as-pasos li:not(.actual) span { font-size: 10.5px; } }
/* El atributo hidden gana también sobre los botones (.btn usa display:inline-flex) */
.btn[hidden], .btn-ghost[hidden], .btn-primary[hidden] { display: none !important; }

/* ═══════════════════════════════════════════════════
   CELULAR: PANTALLAS MÁS RESUMIDAS
   En el celular cada fila muestra lo esencial en 2 o 3 renglones (sin la etiqueta en
   mayúsculas de cada dato), las cifras van en tarjetas chicas y los botones generales del
   panel (estado del router, búsqueda y tema) suben al encabezado fijo, junto a Mbopi.
   En la computadora no cambia nada.
   ═══════════════════════════════════════════════════ */
.aud-btn-filtros { display: none; }

@media screen and (max-width: 768px) {
  /* Encabezado de cada pantalla: sin subtítulo y con los botones generales arriba */
  .topbar { gap: 10px; margin-bottom: 14px; padding-bottom: 12px; }
  .topbar-title { font-size: 20px; }
  .topbar-sub { display: none; }
  .topbar-actions { width: 100%; gap: 6px; }
  /* Ojo: la barra del título no debe llevar animación propia al cambiar de módulo. Con transform,
     lo «fijo» de adentro quedaría atado a ella: los tres botones se verían abajo, junto al título,
     y saltarían arriba al terminar (pasaba con la vieja entrada escalonada por bloques). */
  .topbar-actions > #mikrotik-pill, .topbar-actions > .paleta-btn, .topbar-actions > #themeBtn {
    position: fixed; top: 9px; z-index: 102;
  }
  .topbar-actions > #themeBtn { right: 12px; }
  .topbar-actions > .paleta-btn { right: 52px; }
  .topbar-actions > #mikrotik-pill {
    right: 92px; width: 34px; height: 34px; padding: 0;
    justify-content: center; border-radius: var(--radius-sm);
  }
  /* El estado se ve en el punto de color (y en Mbopi); el texto queda para lectores de pantalla */
  #mikrotik-pill-texto { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  #mikrotik-pill .pulse { width: 9px; height: 9px; }
  /* Menús «Exportar» (Usuarios, Auditoría): en celular el botón queda a la izquierda, así que el
     menú se abre hacia la derecha; si no, se salía de la pantalla por el borde izquierdo */
  .topbar-actions .export-dropdown { left: 0; right: auto; max-width: calc(100vw - 32px); }
  /* Al cambiar de módulo quedan quietos en el encabezado. Están dentro de .main-content y, sin
     nombre propio, viajaban en la «foto» del contenido, que entra subiendo: se veían abajo un
     instante y después saltaban arriba */
  html.vt-activa .topbar-actions > #mikrotik-pill { view-transition-name: boton-estado; }
  html.vt-activa .topbar-actions > .paleta-btn    { view-transition-name: boton-buscar; }
  html.vt-activa .topbar-actions > #themeBtn      { view-transition-name: boton-tema; }

  /* Cifras: tarjetas chicas, sin ícono ni leyenda */
  .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-bottom: 14px; }
  div:has(> .stat-card):not(.stats-grid) {
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)) !important; gap: 8px !important; margin-bottom: 14px !important;
  }
  .stat-card { padding: 11px 12px 10px; }
  /* La fila del ícono del Dashboard trae display:flex escrito en la plantilla: hace falta !important */
  .stat-card .stat-icon, .stat-card > div:has(> .stat-icon), .stat-card .stat-trend { display: none !important; }
  .stat-card .stat-val { font-size: 22px; margin-bottom: 3px; }
  .stat-card .stat-label { font-size: 11.5px; line-height: 1.3; }
  .mini-kpis, .mini-kpis.cinco { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 12px; }
  .mini-kpi { padding: 9px 10px; }
  .mini-kpi-label { font-size: 9.5px; letter-spacing: .2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .mini-kpi-val { font-size: 18px; padding-top: 2px; }
  .mini-kpi-sub { display: none; }
}

@media screen and (max-width: 1023px) {
  /* ─── Usuarios: 3 renglones por usuario ───
     [avatar] Nombre .............. Estado
              CI · correo
              1/2 disp. · Registrado    [✎][⏸][✕] */
  .topbar-actions > .search-wrap { flex: 1 1 100%; }
  .topbar-actions > .search-wrap .search-input { width: 100%; }
  .tabla-usuarios .table-row {
    grid-template-columns: 34px auto minmax(0, 1fr) auto;
    grid-template-areas: "av nom nom est" "av ci co co" "av dis fe acc";
    gap: 2px 10px; padding: 11px 14px; align-items: center;
  }
  .tabla-usuarios .table-row > [data-label]::before { display: none; }
  /* La celda del nombre trae display:flex escrito en la plantilla: hace falta !important */
  .tabla-usuarios .t-user-cell, .tabla-usuarios .t-user-cell > div:not(.t-avatar) { display: contents !important; }
  .tabla-usuarios .t-avatar { grid-area: av; align-self: start; margin-top: 2px; width: 34px; height: 34px; }
  .tabla-usuarios .t-user-name { grid-area: nom; min-width: 0; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tabla-usuarios .t-fecha { grid-area: fe; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tabla-usuarios .table-row > [data-label="CI"] { grid-area: ci; }
  .tabla-usuarios .table-row > [data-label="CI"]::after { content: "·"; margin-left: 8px; color: var(--text3); font-family: inherit; }
  .tabla-usuarios .table-row > [data-label="Correo"] { grid-area: co; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow-wrap: normal; }
  .tabla-usuarios .table-row > [data-label="Dispositivos"] { grid-area: dis; text-align: left !important; }
  .tabla-usuarios .table-row > [data-label="Dispositivos"] .tag::after { content: " disp."; }
  .tabla-usuarios .table-row > [data-label="Estado"] { grid-area: est; justify-self: end; }
  .tabla-usuarios .table-row > .celda-acciones { grid-area: acc; justify-self: end; gap: 4px; }

  /* ─── Sesiones: 3 renglones por sesión (flex con dos cortes de línea: ::before y ::after) ───
     Nombre ...................... Estado
     CI · IP · dispositivo
     Inicio · consumo              [Cerrar] */
  #sesiones-tabla .table-row { display: flex; flex-wrap: wrap; align-items: center; gap: 3px 8px; padding: 11px 14px; }
  #sesiones-tabla .table-row::before, #sesiones-tabla .table-row::after { content: ""; flex-basis: 100%; height: 0; }
  #sesiones-tabla .table-row::before { order: 3; }
  #sesiones-tabla .table-row::after { order: 6; }
  #sesiones-tabla .table-row > [data-label]::before { display: none; }
  #sesiones-tabla .table-row > .celda-ancha { order: 1; flex: 1 1 auto; min-width: 0; grid-column: auto; }
  #sesiones-tabla .table-row > [data-label="Estado"] { order: 2; margin-left: auto; }
  #sesiones-tabla .table-row > [data-label="CI"] { order: 4; }
  #sesiones-tabla .table-row > [data-label="CI"]::after { content: "·"; margin-left: 8px; color: var(--text3); }
  #sesiones-tabla .table-row > [data-label="IP / Dispositivo"] { order: 5; flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #sesiones-tabla .table-row > [data-label="IP / Dispositivo"] br { display: none; }
  #sesiones-tabla .table-row > [data-label="IP / Dispositivo"] > span + span { margin-left: 6px; }
  #sesiones-tabla .table-row > [data-label="Inicio"] { order: 7; white-space: nowrap; }
  #sesiones-tabla .table-row > [data-label="Inicio"]::after { content: "·"; margin-left: 8px; color: var(--text3); }
  #sesiones-tabla .table-row > [data-label="Consumo"] { order: 8; white-space: nowrap; }
  #sesiones-tabla .table-row > [data-label="Consumo"] br,
  #sesiones-tabla .table-row > [data-label="Consumo"] .bw-speed { display: none; }
  #sesiones-tabla .table-row > .celda-acciones { order: 9; margin-left: auto; flex: 0 0 auto; }
  /* Fila de una persona con varios dispositivos: lo que ya dice la etiqueta «N dispositivos» no se repite */
  #sesiones-tabla .sesion-cab > [data-label="IP / Dispositivo"] > span:first-child,
  #sesiones-tabla .sesion-cab > [data-label="Inicio"] br, #sesiones-tabla .sesion-cab > [data-label="Inicio"] span,
  #sesiones-tabla .sesion-cab > [data-label="Consumo"] br, #sesiones-tabla .sesion-cab > [data-label="Consumo"] span:not(.bw-total) { display: none; }
  #sesiones-tabla .sesion-cab > [data-label="IP / Dispositivo"] > .ses-grupo-ips { margin-left: 0; }
}
@media screen and (max-width: 800px) {
  /* Filtros de sesiones: búsqueda a lo ancho; consumo mínimo y orden lado a lado */
  #sesiones-tabla .ses-filtros-fila:first-child { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  #sesiones-tabla .ses-filtros-fila:first-child > .search-wrap { grid-column: 1 / -1; }
  #sesiones-tabla .ses-filtros-fila:first-child > * { width: 100% !important; min-width: 0; }
  #sesiones-tabla .ses-filtros-fila:first-child > .ses-espacio { display: none; }
  #sesiones-tabla .ses-filtros-fila:first-child > #btn-limpiar { grid-column: 1 / -1; }
  #sesiones-tabla #btn-limpiar:disabled { display: none; }   /* sin filtros puestos no hace falta */
  #sesiones-tabla #tab-desc { display: none; }

  /* ─── Auditoría: búsqueda a la vista y el resto de los filtros detrás de «Filtros» ─── */
  .aud-filtros { gap: 8px; padding: 12px 14px; }
  .aud-filtros > .aud-buscar { order: -2; flex: 1 1 160px; min-width: 0; }
  .aud-filtros > .aud-buscar input { min-width: 0 !important; width: 100%; }
  .aud-btn-filtros { display: inline-flex; order: -1; gap: 6px; }
  .aud-filtros-resumen { color: var(--blue-light); font-weight: 600; }
  /* Solo el formulario de la Auditoría (Usuarios usa .aud-filtros para «Ordenar por») */
  form.aud-filtros:not(.abiertos) > .aud-campo:not(.aud-buscar), form.aud-filtros:not(.abiertos) > .hist-rango { display: none !important; }
  .aud-filtros > button[type="submit"], .aud-filtros > span[style*="flex:1"] { display: none; }
  form.aud-filtros.abiertos > .aud-campo:not(.aud-buscar) { flex: 1 1 100%; }
  .aud-filtros.abiertos .seg-ctl { width: 100%; }
  .aud-filtros.abiertos .seg-ctl button { flex: 1; padding: 6px 4px; }
}

/* ═══════════════════════════════════════════════════
   VISITANTES (portal y panel)
   ═══════════════════════════════════════════════════ */
/* ─── Portal: enlace para pedir acceso, formulario, espera y resultado ─── */
.visitante-enlace {
  margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 6px;
  font-size: 12.5px; color: var(--text2); text-align: center;
}
.visitante-enlace a, .visitante-volver { color: var(--blue-light); font-weight: 600; text-decoration: none; }
.visitante-enlace a:hover, .visitante-volver:hover { text-decoration: underline; }
.visitante-volver { display: block; margin-top: 12px; font-size: 12.5px; text-align: center; }
.visitante-titulo-form { font-size: 15px; font-weight: 650; text-align: center; margin-bottom: 4px; letter-spacing: -.01em; }
.visitante-intro { font-size: 12.5px; color: var(--text2); text-align: center; line-height: 1.55; margin-bottom: 16px; }
.visitante-opc { color: var(--text3); font-weight: 400; }
.visitante-fila { display: grid; grid-template-columns: 1fr 1fr; gap: 0 10px; }
.visitante-fila > .field { min-width: 0; }
@media (max-width: 520px) { .visitante-fila { grid-template-columns: 1fr; } }
.step-circle.step-error { background: var(--red-bg); color: var(--red); border: 1px solid var(--red-border); }

.visitante-estado { text-align: center; padding: 2px 0; }
.visitante-icono {
  width: 64px; height: 64px; border-radius: 50%;
  margin: 2px auto 14px;
  display: flex; align-items: center; justify-content: center;
}
.visitante-icono.espera    { background: var(--amber-bg); color: var(--amber); border: 1px solid var(--amber-border); }
.visitante-icono.rechazada { background: var(--red-bg); color: var(--red); border: 1px solid var(--red-border); }
.visitante-icono.vencida   { background: var(--bg3); color: var(--text2); border: 1px solid var(--border); }
.visitante-icono.espera svg { animation: relojArena 2.6s var(--ease) infinite; }
@keyframes relojArena {
  0%, 70% { transform: rotate(0deg); }
  85%, 100% { transform: rotate(180deg); }
}
.visitante-titulo { font-size: 16px; font-weight: 650; color: var(--text); margin-bottom: 6px; letter-spacing: -.01em; line-height: 1.35; }
.visitante-sub { font-size: 12.5px; color: var(--text2); line-height: 1.6; margin-bottom: 16px; }
.visitante-motivo {
  font-size: 13px; color: var(--text); line-height: 1.5; text-align: left;
  background: var(--soft-bg); border: 1px solid var(--soft-border); border-radius: var(--radius-sm);
  padding: 9px 12px; margin: 2px 0 12px;
}
.visitante-barra { height: 4px; border-radius: 4px; background: var(--bg3); overflow: hidden; margin: 0 0 10px; }
.visitante-barra span {
  display: block; height: 100%; width: 35%; border-radius: 4px;
  background: var(--amber);
  animation: barraEspera 1.8s ease-in-out infinite;
}
@keyframes barraEspera {
  from { transform: translateX(-100%); }
  to   { transform: translateX(300%); }
}
.visitante-meta { font-size: 11.5px; color: var(--text3); margin-bottom: 16px; }
.visitante-acciones { display: flex; flex-direction: column; gap: 8px; }
.visitante-acciones a { display: flex; align-items: center; justify-content: center; text-decoration: none; }
@media (prefers-reduced-motion: reduce) {
  .visitante-icono.espera svg { animation: none; }
  .visitante-barra span { animation: none; width: 100%; opacity: .45; }
}

/* ─── Panel: solicitudes pendientes en Usuarios ─── */
#solicitudes-caja:focus { outline: none; }
.sol-caja {
  margin-bottom: 16px;
  background: var(--bg2);
  border: 1px solid var(--amber-border);
  border-radius: var(--radius-lg);
  padding: 14px 16px 6px;
}
.sol-cabecera { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 8px; }
.sol-icono {
  flex-shrink: 0; width: 32px; height: 32px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: var(--amber-bg); color: var(--amber);
}
.sol-titulo { font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.sol-sub { font-size: 11.5px; color: var(--text3); margin-top: 2px; line-height: 1.5; }
.sol-fila {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
}
.sol-datos { flex: 1; min-width: 0; }
.sol-nombre { font-size: 13px; font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.sol-motivo { font-weight: 400; color: var(--text2); }
.sol-detalle { font-size: 11.5px; color: var(--text3); margin-top: 2px; overflow-wrap: anywhere; }
.sol-hace { font-size: 11.5px; color: var(--text3); white-space: nowrap; }
.sol-acciones { display: flex; gap: 6px; flex-shrink: 0; }

/* Visitantes en la lista de usuarios */
.tag-visitante { margin-left: 6px; font-size: 10px; padding: 1px 7px; vertical-align: 1px; }
.t-vence { color: var(--purple); }
.t-vence.vencido { color: var(--text3); }

/* Diálogo de acceso (aprobar / vigencia de un visitante) */
.acc-quien { font-size: 12.5px; color: var(--text2); margin: -4px 0 14px; line-height: 1.5; }
.acc-ayuda { font-size: 11.5px; color: var(--text3); margin-top: 6px; line-height: 1.5; }
.acc-vence { color: var(--text2); font-weight: 500; }
.acc-vigencias { display: flex; flex-wrap: wrap; gap: 6px; }
.acc-vigencias .filter-chip { font-family: inherit; }
.acc-vigencias .filter-chip:disabled { opacity: .45; cursor: not-allowed; }
.acc-vigencias .filter-chip[hidden] { display: none; }
.acc-regular { margin-top: 2px; align-items: flex-start; line-height: 1.45; }
.acc-regular[hidden] { display: none; }
/* «Otra duración»: cantidad + unidad (Configuración → Visitantes y diálogo de aprobar / Acceso) */
.vig-otra { display: flex; gap: 8px; margin-top: 8px; }
.vig-otra[hidden] { display: none; }
.vig-otra .f-input { flex: 0 0 66px; width: 66px; padding-right: 6px; }
.vig-otra .f-select { flex: 1 1 auto; min-width: 0; }

/* Configuración → Administradores: la cuenta propia a la vista y las demás plegadas */
.admin-vos {
  margin-left: 6px; padding: 1px 7px; border-radius: 20px; vertical-align: 1px;
  font-size: 10px; font-weight: 600; background: var(--green-bg); color: var(--green);
}
.admins-toggle {
  width: 100%; display: flex; align-items: center; gap: 8px;
  margin-top: 2px; padding: 11px 2px 3px;
  background: none; border: 0; cursor: pointer; font-family: inherit;
  font-size: 12.5px; font-weight: 600; color: var(--blue-light); text-align: left;
}
.admins-toggle:hover .admins-toggle-txt { text-decoration: underline; }
.admins-toggle-chev { margin-left: auto; transition: transform var(--dur-fast) var(--ease); }
.admins-toggle[aria-expanded="true"] .admins-toggle-chev { transform: rotate(180deg); }
.admins-otros[hidden] { display: none; }
.admins-otros { margin-top: 4px; border-top: 1px solid var(--border); }
/* Portal: mientras espera la aprobación, la insignia del encabezado va en ámbar (no en rojo) */
.no-access-badge.espera { background: var(--amber-bg); color: var(--amber); border-color: var(--amber-border); }
.acc-regular input { margin-top: 2px; }

/* Insignia de solicitudes en el menú y aviso que se puede tocar */
.sb-badge-alerta { background: var(--amber-bg); color: var(--amber); }
.sb-badge[hidden] { display: none; }
.toast.toast-accion { cursor: pointer; }
.toast.toast-accion:hover { border-color: var(--border-strong); }

/* ─── Celulares: sin zoom al tocar un campo ───
   iPhone (y algunos navegadores de Android) acercan la pantalla al tocar un campo con letra de
   menos de 16 px y después no la vuelven a alejar. Con 16 px no hay zoom automático, y el zoom
   con los dedos sigue funcionando (no se bloquea en el viewport, por accesibilidad). */
@media screen and (pointer: coarse), screen and (max-width: 768px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
  select, textarea { font-size: 16px !important; }
}

@media screen and (max-width: 768px) {
  .sol-caja { padding: 12px 12px 4px; }
  .sol-fila { flex-wrap: wrap; gap: 8px 10px; }
  .sol-datos { flex: 1 1 calc(100% - 50px); }
  .sol-hace { order: 3; }
  .sol-acciones { order: 4; margin-left: auto; }
}

/* ═══════════════════════════════════════════════════
   TAMAÑOS INTERMEDIOS (tablet, notebook chica)
   Revisado en 320, 375, 768, 834, 1024, 1180, 1280, 1366 y 1920 px: nada se encima ni se sale.
   ═══════════════════════════════════════════════════ */
/* Botones de arriba: si no entran en una línea (Usuarios a 1024 px), bajan a otra en vez de salirse */
@media screen and (min-width: 769px) {
  .topbar { gap: 16px; }
  .topbar > div:first-child { min-width: 0; }
  .topbar-actions { flex-wrap: wrap; justify-content: flex-end; row-gap: 8px; }
}

/* Columnas más angostas mientras la pantalla no alcanza para las de siempre (hasta 1023 px las
   tablas ya van como lista). Sesiones necesita ~930 px para sus 8 columnas: a 1024 px quedan 704 y
   a 1280, 960 (el nombre quedaba en ~25 px). Fecha, consumo y acción pasan a dos líneas. */
@media screen and (min-width: 1024px) and (max-width: 1439px) {
  .tabla-sesiones .table-cols, .tabla-sesiones .table-row {
    --cols: 28px 76px minmax(110px, 1fr) 112px 72px 76px 62px 104px !important;
    column-gap: 8px;
    padding-left: 14px; padding-right: 14px;
  }
}
@media screen and (min-width: 1024px) and (max-width: 1279px) {
  .tabla-usuarios .table-cols, .tabla-usuarios .table-row {
    --cols: 28px 80px minmax(130px, 1.4fr) minmax(110px, 1fr) 56px 82px 136px !important;
    column-gap: 8px;
    padding-left: 14px; padding-right: 14px;
  }
  .tabla-usuarios .table-row > [data-label="Correo"] { overflow-wrap: anywhere; }
}

/* Dashboard en celulares chicos: la leyenda de las reglas va debajo de la dona */
@media screen and (max-width: 420px) {
  .reglas-resumen { flex-direction: column; align-items: stretch; gap: 10px; }
  .reglas-resumen .reglas-donut { margin: 0 auto; }
}

/* Informes en pantallas angostas: los títulos de las tablas pueden ir en dos líneas */
@media screen and (max-width: 860px) {
  .doc-t th, .doc-t th.n { white-space: normal; }
  .doc-t { font-size: 8pt; }
  .doc-t th, .doc-t td { padding-left: 5px; padding-right: 5px; }
  .doc-t td { overflow-wrap: anywhere; }   /* un correo largo no ensancha la tabla */
}

/* ═══════════════════════════════════════════════════
   MENÚ «MÁS» DEL CELULAR
   ═══════════════════════════════════════════════════
   La barra de abajo muestra los 4 módulos de uso diario y un botón de tres líneas («Más») que
   abre una hoja con el resto (Auditoría, Configuración) y «Cerrar sesión». Nada se desliza de
   costado. La hoja es la sección «Sistema» del mismo menú (mismos enlaces), puesta encima de la
   barra con position: absolute: .sb-menu ya no tiene overflow (no hace falta deslizar), así que
   no vuelve el recorte de WebKit con fijos dentro de fijos. Un módulo nuevo que no entre en la
   barra va en .sb-hoja. */
.sb-mas, .sb-velo, .sb-hoja-titulo, .sb-salir { display: none; }
.sb-mas .ic-x { display: none; }
html.menu-abierto .sb-mas .ic-x { display: block; }
html.menu-abierto .sb-mas .ic-menu { display: none; }

@media (max-width: 768px) {
  .sb-menu { overflow: visible; }
  .sb-section:not(.sb-hoja) { flex: 4 1 0; min-width: 0; }
  .sb-section:not(.sb-hoja) .sb-item {
    flex: 1 1 0; min-width: 0;
    padding: 8px 2px;
    align-items: center; justify-content: center;
    margin-bottom: 0;
  }
  .sb-item-text { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
  .sb-prefijo { display: none; }                         /* «Control de red» pasa a «Red» */
  #nav-red .sb-item-text { text-transform: capitalize; }

  .sb-mas {
    display: flex; flex: 1 1 0; min-width: 0;
    flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    padding: 8px 2px;
    font: inherit; font-size: 10px;
    color: var(--text3);
    background: none; border: 0; border-radius: 0;
    cursor: pointer;
    position: relative;
  }
  .sb-mas svg { width: 17px; height: 17px; }
  .sb-mas.en-hoja, html.menu-abierto .sb-mas { color: var(--blue-light); }
  .sb-mas.en-hoja::before {
    content: ''; position: absolute; top: 0; left: 8px; right: 8px; height: 2px;
    background: var(--blue-light); border-radius: 0 0 2px 2px;
  }
  .sb-mas:focus-visible { outline: none; box-shadow: inset var(--focus-ring); }

  .sb-velo {
    display: block;
    position: fixed; inset: 0; z-index: 99;
    background: rgba(0, 0, 0, .5);
    opacity: 0; pointer-events: none;
    transition: opacity var(--dur-base) var(--ease);
  }
  html.menu-abierto .sb-velo { opacity: 1; pointer-events: auto; }

  .sb-hoja {
    display: block;
    position: absolute; left: 0; right: 0; bottom: 100%;
    padding: 14px 14px 10px; margin: 0;
    background: var(--bg2);
    border: 1px solid var(--border); border-bottom: 0;
    border-radius: 16px 16px 0 0;
    box-shadow: var(--shadow-lg);
    visibility: hidden; opacity: 0; transform: translateY(12px);
    transition: transform var(--dur-base) var(--ease), opacity var(--dur-base) var(--ease),
                visibility 0s linear var(--dur-base);
  }
  html.menu-abierto .sb-hoja { visibility: visible; opacity: 1; transform: none; transition-delay: 0s; }
  .sb-hoja-titulo {
    display: block;
    margin: 0 0 6px; padding: 0 10px;
    font-size: 11px; font-weight: 600; letter-spacing: .8px; text-transform: uppercase;
    color: var(--text3);
  }
  .sb-hoja .sb-item {
    flex-direction: row; justify-content: flex-start;
    gap: 12px; width: 100%;
    padding: 12px 10px; margin-bottom: 0;
    border-radius: 10px;
    font-size: 14px;
    color: var(--text);
  }
  .sb-hoja .sb-item svg { width: 18px; height: 18px; color: var(--text2); }
  .sb-hoja .sb-item.active, .sb-hoja .sb-item.active svg { color: var(--blue-light); }
  .sb-hoja .sb-indicador::after { display: none; }
  .sb-salir {
    display: flex; align-items: center; gap: 12px;
    margin-top: 6px; padding: 14px 10px 8px;
    border-top: 1px solid var(--border);
    font-size: 14px; text-decoration: none;
    color: var(--red);
  }
}

/* ═══════════════════════════════════════════════════
   MEJORAS VISUALES (2026-11-12)
   Tinte de marca, sombras en capas, resplandor de fondo, vidrio, barra fija, tarjetas de números con
   mini gráfico, anillos, avatares con color y estados vacíos con Mbopi.
   Todo sale de las variables de marca (--blue-*): sigue a cualquier color de organización y a los dos
   temas. Lo que usa color-mix() o backdrop-filter va dentro de @supports: un navegador viejo (por
   ejemplo el del portal cautivo de un iPhone antiguo) se queda con el diseño de siempre en vez de un
   fondo transparente. Al imprimir se apaga todo (final de la sección).
   ═══════════════════════════════════════════════════ */

/* ─── Tinte de marca ───────────────────────────────
   Los grises toman un poco del color de la organización. --tinte-tarjeta tiene que valer lo mismo que
   TINTE_TARJETA_OSCURO / _CLARO de marca.py: ahí se mide el contraste del texto de acento. */
@supports (color: color-mix(in srgb, red 50%, blue)) {
  :root {
    --tinte-fondo: 6%;
    --tinte-tarjeta: 4%;
    --tinte-campo: 5%;
    --tinte-activo: 6%;
    --tinte-borde: 12%;
    --tinte-lateral: 7%;
    --bg:            color-mix(in srgb, var(--blue-main) var(--tinte-fondo),   #0E1117);
    --bg2:           color-mix(in srgb, var(--blue-main) var(--tinte-tarjeta), #161A22);
    --bg3:           color-mix(in srgb, var(--blue-main) var(--tinte-campo),   #1E232D);
    --bg4:           color-mix(in srgb, var(--blue-main) var(--tinte-activo),  #272D39);
    --border:        color-mix(in srgb, var(--blue-main) var(--tinte-borde),   #2B3240);
    --border-strong: color-mix(in srgb, var(--blue-main) var(--tinte-borde),   #3B4454);
    --sidebar-bg:    color-mix(in srgb, var(--blue-main) var(--tinte-lateral), #0B0E13);
  }
  [data-theme="light"] {
    --tinte-fondo: 3.5%;
    --tinte-tarjeta: 1.5%;
    --tinte-campo: 3.5%;
    --tinte-activo: 5%;
    --tinte-borde: 10%;
    --tinte-lateral: 3%;
    --bg:            color-mix(in srgb, var(--blue-main) var(--tinte-fondo),   #F6F7F9);
    --bg2:           color-mix(in srgb, var(--blue-main) var(--tinte-tarjeta), #FFFFFF);
    --bg3:           color-mix(in srgb, var(--blue-main) var(--tinte-campo),   #F0F2F5);
    --bg4:           color-mix(in srgb, var(--blue-main) var(--tinte-activo),  #E5E8ED);
    --border:        color-mix(in srgb, var(--blue-main) var(--tinte-borde),   #DDE1E8);
    --border-strong: color-mix(in srgb, var(--blue-main) var(--tinte-borde),   #C5CBD5);
    --sidebar-bg:    color-mix(in srgb, var(--blue-main) var(--tinte-lateral), #FBFBFC);
  }
  ::selection { background: color-mix(in srgb, var(--blue-main) 38%, transparent); }
}

/* ─── Sombras en capas ─────────────────────────────
   Una línea de luz arriba (solo en oscuro), una sombra corta y otra larga y suave; en claro la sombra
   larga lleva un poco del color de la marca. */
@supports (color: color-mix(in srgb, red 50%, blue)) {
  :root {
    --sombra-capas:   inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 28px -12px rgba(0, 0, 0, 0.60);
    --sombra-capas-h: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 2px 4px rgba(0, 0, 0, 0.40), 0 20px 38px -12px rgba(0, 0, 0, 0.70);
  }
  [data-theme="light"] {
    --sombra-capas:   0 1px 2px rgba(16, 24, 40, 0.06), 0 12px 26px -14px color-mix(in srgb, var(--blue-main) 32%, rgba(16, 24, 40, 0.35));
    --sombra-capas-h: 0 2px 4px rgba(16, 24, 40, 0.08), 0 22px 36px -14px color-mix(in srgb, var(--blue-main) 42%, rgba(16, 24, 40, 0.40));
  }
  .card, .stat-card, .table-wrap, .chart-card, .cfg-item { box-shadow: var(--sombra-capas); }
  a.card:hover, .card[onclick]:hover { box-shadow: var(--sombra-capas-h); transform: translateY(-2px); }
}

/* ─── Resplandor de fondo, símbolo de Wi-Fi y grano (solo el panel: <body class="panel">) ───
   Dos capas fijas detrás del contenido: no scrollean, no atrapan el mouse y no pesan en la página.
   El símbolo (punto y tres arcos, de la forma del ícono de Wi-Fi) queda arriba a la derecha con el punto
   justo debajo de la barra superior, en el hueco entre el título y las tarjetas. */
@supports (color: color-mix(in srgb, red 50%, blue)) {
  body.panel::before {
    content: "";
    position: fixed; inset: 0; z-index: -1; pointer-events: none;
    background:
      url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .55 0'/></filter><rect width='160' height='160' filter='url(%23n)' opacity='.05'/></svg>"),
      radial-gradient(640px 320px at calc(100% - 120px) -40px, color-mix(in srgb, var(--blue-main) 34%, transparent), transparent 72%),
      radial-gradient(520px 300px at var(--sidebar-w) 38%, color-mix(in srgb, var(--blue-main) 14%, transparent), transparent 72%);
  }
  [data-theme="light"] body.panel::before {
    background:
      url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .55 0'/></filter><rect width='160' height='160' filter='url(%23n)' opacity='.04'/></svg>"),
      radial-gradient(640px 320px at calc(100% - 120px) -40px, color-mix(in srgb, var(--blue-main) 17%, transparent), transparent 72%),
      radial-gradient(520px 300px at var(--sidebar-w) 38%, color-mix(in srgb, var(--blue-main) 8%, transparent), transparent 72%);
  }
  body.panel::after {
    content: "";
    position: fixed; top: -88px; right: 150px; width: 300px; height: 300px; z-index: -1; pointer-events: none;
    background: var(--blue-light);
    opacity: .17;
    -webkit-mask: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg fill='none' stroke='black' stroke-width='11' stroke-linecap='round'%3E%3Cpath d='M68.2 133.2A45 45 0 0 1 131.8 133.2'/%3E%3Cpath d='M43.4 108.4A80 80 0 0 1 156.6 108.4'/%3E%3Cpath d='M18.7 83.7A115 115 0 0 1 181.3 83.7'/%3E%3C/g%3E%3Ccircle cx='100' cy='165' r='11' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg fill='none' stroke='black' stroke-width='11' stroke-linecap='round'%3E%3Cpath d='M68.2 133.2A45 45 0 0 1 131.8 133.2'/%3E%3Cpath d='M43.4 108.4A80 80 0 0 1 156.6 108.4'/%3E%3Cpath d='M18.7 83.7A115 115 0 0 1 181.3 83.7'/%3E%3C/g%3E%3Ccircle cx='100' cy='165' r='11' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
  }
  [data-theme="light"] body.panel::after { opacity: .2; }
  @media (max-width: 1023px) {
    body.panel::after { top: -40px; right: 12px; width: 240px; height: 240px; }
  }
}

/* ─── Título con degradado y botón principal con brillo ─── */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .welcome-title {
    width: fit-content;
    background: linear-gradient(95deg, var(--text) 30%, var(--blue-light));
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
  }
}
@media (forced-colors: active) {
  .welcome-title { background: none; color: CanvasText; }
}
@supports (color: color-mix(in srgb, red 50%, blue)) {
  .btn-primary {
    position: relative; overflow: hidden;
    background: linear-gradient(135deg, var(--blue-main), color-mix(in srgb, var(--blue-main) 80%, #000));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 8px 20px -8px color-mix(in srgb, var(--blue-main) 80%, transparent);
  }
  .btn-primary:hover,
  [data-theme="light"] .btn-primary:hover {
    background: linear-gradient(135deg, color-mix(in srgb, var(--blue-main) 88%, #000), color-mix(in srgb, var(--blue-main) 68%, #000));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.26), 0 12px 26px -8px color-mix(in srgb, var(--blue-main) 85%, transparent);
  }
  .btn-primary::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, 0.28) 50%, transparent 65%);
    transform: translateX(-120%);
  }
  .btn-primary:hover::after { transform: translateX(120%); transition: transform .7s var(--ease); }
}

/* ─── Vidrio: buscador, menús y avisos ───────────── */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) and (color: color-mix(in srgb, red 50%, blue)) {
  .paleta-caja, .export-dropdown, .toast {
    background: color-mix(in srgb, var(--bg2) 64%, transparent);
    -webkit-backdrop-filter: blur(22px) saturate(1.6); backdrop-filter: blur(22px) saturate(1.6);
    border-color: color-mix(in srgb, var(--text) 16%, transparent);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), var(--shadow-lg);
  }
  [data-theme="light"] .paleta-caja, [data-theme="light"] .export-dropdown, [data-theme="light"] .toast {
    background: color-mix(in srgb, var(--bg2) 74%, transparent);
    border-color: color-mix(in srgb, var(--text) 12%, transparent);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8), var(--shadow-lg);
  }
}
@media (prefers-reduced-transparency: reduce) {
  .paleta-caja, .export-dropdown, .toast, .topbar.sobre-contenido { background: var(--bg2) !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
}

/* ─── Barra superior fija (solo con espacio: ≥ 1024 px) ─────────────────
   Sale del padding de .main-content con márgenes negativos (24 px arriba, 28 px a los lados).
   app.js mide su alto en --topbar-alto para que otras barras fijas (Auditoría) queden debajo. */
@media screen and (min-width: 1024px) {
  .topbar {
    position: sticky; top: 0; z-index: 60;
    margin: -24px -28px 24px;
    padding: 24px 28px 18px;
    background: var(--bg);
  }
  html { scroll-padding-top: calc(var(--topbar-alto, 0px) + 12px); }
  .aud-barra { top: var(--topbar-alto, 0px); }
}
/* Arriba de todo la barra es transparente (se ve el fondo, con su símbolo de Wi-Fi nítido); cuando el contenido
   pasa por debajo (app.js le pone .sobre-contenido al bajar) se vuelve vidrio. Sin esta clase quedaría
   transparente sobre el contenido: por eso el vidrio solo se declara cuando se sabe que se puede soltar el fondo. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) and (color: color-mix(in srgb, red 50%, blue)) {
  @media screen and (min-width: 1024px) {
    .topbar {
      background: transparent;
      transition: background-color .2s var(--ease), backdrop-filter .2s var(--ease), -webkit-backdrop-filter .2s var(--ease);
    }
    .topbar.sobre-contenido {
      background: color-mix(in srgb, var(--bg) 62%, transparent);
      -webkit-backdrop-filter: blur(16px) saturate(1.5); backdrop-filter: blur(16px) saturate(1.5);
    }
  }
}

/* ─── Tarjetas de números: borde con degradado, brillo que sigue al mouse y mini gráfico ─── */
.stat-card { --acc: var(--blue-light); }
.stat-card.stat-green  { --acc: var(--green); }
.stat-card.stat-purple { --acc: var(--purple); }
.stat-card.stat-amber  { --acc: var(--amber); }
.stat-card.stat-red    { --acc: var(--red); }
.stat-spark { display: block; width: 100%; height: 34px; margin-top: 12px; }
.stat-spark:empty { display: none; }
.stat-spark svg { display: block; width: 100%; height: 100%; overflow: visible; }
.stat-tend {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 9px;
  font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 99px; width: max-content;
  color: var(--text2); background: var(--soft-bg);
}
.stat-tend:empty { display: none; }
.stat-tend.bueno { color: var(--green); background: var(--green-bg); }
.stat-tend.malo  { color: var(--red);   background: var(--red-bg); }
@supports (color: color-mix(in srgb, red 50%, blue)) {
  .stat-card {
    border-color: transparent;
    background:
      linear-gradient(var(--bg2), var(--bg2)) padding-box,
      linear-gradient(140deg, color-mix(in srgb, var(--acc) 88%, var(--bg2)), color-mix(in srgb, var(--acc) 8%, transparent) 48%, color-mix(in srgb, var(--acc) 42%, transparent)) border-box;
    background-origin: border-box;   /* el degradado del borde se alinea con el borde y no se repite */
  }
  .stat-card::before { display: none; }
  .stat-card::after {
    content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
    transition: opacity var(--dur-base) var(--ease);
    background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 0%), color-mix(in srgb, var(--acc) 18%, transparent), transparent 65%);
  }
  .stat-card:hover { border-color: transparent; transform: translateY(-3px); box-shadow: var(--sombra-capas-h); }
  .stat-card:hover::after { opacity: 1; }
}

/* ─── Anillos de progreso (CPU y RAM del diagnóstico) ─── */
.anillo { --p: 0; --g: 10px; --c1: var(--blue-main); --c2: var(--blue-light); position: relative; width: 96px; height: 96px; flex: none; }
.anillo.aviso   { --c1: var(--amber); --c2: var(--orange); }
.anillo.critico { --c1: var(--red);   --c2: var(--red); }
.anillo::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(from -90deg, var(--c1), var(--c2) calc(var(--p) * 1%), var(--bg4) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--g)), #000 calc(100% - var(--g) + 1px));
          mask: radial-gradient(farthest-side, transparent calc(100% - var(--g)), #000 calc(100% - var(--g) + 1px));
  transition: background var(--dur-slow) var(--ease);
}
@supports (color: color-mix(in srgb, red 50%, blue)) {
  .anillo::before { filter: drop-shadow(0 0 7px color-mix(in srgb, var(--c1) 55%, transparent)); }
}
.anillo > b {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 20px; font-weight: 650; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.recursos { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 4px; }
.rec-item { display: grid; justify-items: center; gap: 6px; text-align: center; min-width: 0; }
.rec-nombre { font-size: 12px; font-weight: 600; color: var(--text2); }
.rec-detalle { font-size: 11px; color: var(--text3); }

/* ─── Avatares con color propio (el tono sale de la CI o del nombre: filtro `tono`) ───
   Los tonos evitan el amarillo-verde y el degradado es profundo: las iniciales blancas cumplen 4,5:1. */
.t-avatar.con-tono {
  color: #fff;
  background: linear-gradient(135deg, hsl(var(--h) 62% 30%), hsl(calc(var(--h) + 38) 62% 24%));
  box-shadow: 0 0 0 1.5px hsl(var(--h) 70% 55% / .55), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

/* ─── Estados vacíos con Mbopi ─── */
.empty-state .mbopi, .empty-mbopi {
  display: block; width: 168px; height: 105px; margin: 0 auto 10px;
}

/* ─── Al imprimir se apaga todo: papel blanco, sin efectos ─── */
@media print {
  body.panel::before, body.panel::after { display: none; }
  .card, .stat-card, .table-wrap, .chart-card, .cfg-item { box-shadow: none !important; }
  .welcome-title { background: none; -webkit-text-fill-color: currentColor; color: inherit; }
}
