:root {
  --background: #0a0a0b;
  --foreground: #fafafa;
  --card: #18181b;
  --card-foreground: #fafafa;
  --border: #27272a;
  --input: #27272a;
  --muted: #27272a;
  --muted-foreground: #a1a1aa;
  --accent: #27272a;
  --primary: #3b82f6;
  --primary-foreground: #ffffff;
  --secondary: #27272a;
  --secondary-foreground: #e4e4e7;
  --destructive: #7f1d1d;
  --destructive-foreground: #fecaca;
  --success-bg: rgba(74, 222, 128, .15);
  --success-fg: #4ade80;
  --danger-bg: rgba(248, 113, 113, .15);
  --danger-fg: #f87171;
  --warning-bg: rgba(251, 191, 36, .15);
  --warning-fg: #fbbf24;
  --chart-down: #3b82f6;
  --chart-up: #93c5fd;
  --radius: .625rem;
}
* { box-sizing: border-box; }

.scroll-top-btn {
  position: fixed; left: 1.5rem; bottom: 1.5rem; z-index: 900;
  width: 2.75rem; height: 2.75rem; padding: 0; border-radius: 9999px;
  display: flex; align-items: center; justify-content: center;
  background: var(--secondary); color: var(--secondary-foreground); border: 1px solid var(--border);
  box-shadow: 0 4px 12px rgba(0, 0, 0, .3);
  opacity: 0; pointer-events: none; transform: translateY(.5rem);
  transition: opacity .2s ease, transform .2s ease, background-color .15s;
}
.scroll-top-btn.visible { opacity: 1; pointer-events: auto; transform: translateY(0); }
.scroll-top-btn:hover { background: var(--accent); opacity: 1; }
body {
  font-family: system-ui, sans-serif; margin: 2rem; background: var(--background); color: var(--foreground);
  /* deja lugar abajo de todo el contenido para que el boton flotante de
     "volver arriba" (fixed, bottom-left) no quede pisando el ultimo
     parrafo de la pagina cuando se scrollea hasta el final */
  padding-bottom: 5rem;
}
.site-header { margin-bottom: 1.25rem; display: flex; align-items: flex-start; gap: 1.5rem; }
/* header-actions va primero en el HTML (antes que la tarjeta de Trafico
   Total) y flex:0 0 auto -- asi el logo y el boton de ocultar/mostrar
   graficos quedan siempre arriba a la izquierda, sin moverse de lugar
   cuando la tarjeta de Trafico Total desaparece (display:none al ocultar
   graficos, o directamente ausente sin cache). El grafico, con
   flex:1 1 auto, ocupa lo que queda a la derecha. */
.header-actions { display: flex; flex-direction: column; align-items: flex-start; gap: .4rem; flex: 0 0 auto; }
.logo { height: 5rem; width: auto; display: block; flex: 0 0 auto; }
.provider-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
.total-traffic-card { flex: 1 1 auto; min-width: 0; }
/* height fija (no solo min-height): esta tarjeta vive sola en .site-header
   (flex, align-items:center) sin nada que acote su altura -- sin una altura
   CSS explicita el canvas queda dependiendo de la relacion de ancho/alto de
   su propio buffer interno (que el JS reescribe en cada frame para el DPI),
   lo que retroalimenta un crecimiento sin control ("se ve enorme") */
.total-traffic-card canvas { height: 5.5rem; min-height: 5.5rem; }
body.charts-hidden .provider-grid, body.charts-hidden .total-traffic-card { display: none; }

/* grilla de la pestaña Info (address-lists/pools) -- misma disposicion que
   .provider-grid pero clase separada a proposito: no tiene que ver con los
   graficos de consumo, no debe ocultarse con el boton "Ocultar graficos" */
.info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }

.page-nav { margin-bottom: 1rem; display: flex; align-items: center; }
.page-nav a {
  color: var(--muted-foreground); margin-right: 1.25rem; text-decoration: none;
  font-size: .9rem; font-weight: 500; padding-bottom: .35rem; border-bottom: 2px solid transparent;
}
.page-nav a:hover { color: var(--foreground); }
.page-nav a.active { color: var(--foreground); border-bottom-color: var(--primary); }
form { margin-bottom: 1.25rem; display: flex; gap: .5rem; }

.search-row { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.search-row form { margin-bottom: 0; }
.alerts-card { flex: 0 1 auto; }
.alerts-card .card-content { padding: .6rem 1rem; }
.alerts-card .card-content p { margin: .3rem 0; }
.alerts-card .card-content p:first-child { margin-top: 0; }
.alerts-card .card-content p:last-child { margin-bottom: 0; }
input[type=text], input[type=password] {
  height: 2.25rem; padding: 0 .75rem; font-size: .85rem; width: 22rem;
  border-radius: calc(var(--radius) - 2px); border: 1px solid var(--border);
  background: var(--input); color: var(--foreground);
}
input[type=text]:focus, input[type=password]:focus { outline: 2px solid var(--primary); outline-offset: 1px; }

/* pantalla de login (templates/login.html) -- pagina standalone, no usa
   base.html, asi que estas reglas quedan con su propio namespace .login-*
   para no pisar el resto de los estilos */
body.login-page {
  margin: 0; padding: 0; min-height: 100vh; width: 100%;
  display: flex; align-items: center; justify-content: center;
  background:
    linear-gradient(rgba(10, 10, 11, .55), rgba(10, 10, 11, .55)),
    url("background-login.png") center center / cover no-repeat fixed,
    var(--background);
}
.login-card {
  display: flex; flex-direction: column; gap: .6rem;
  width: 22rem; max-width: calc(100vw - 2.5rem);
  background: rgba(24, 24, 27, .85); backdrop-filter: blur(6px);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 2rem 1.75rem 1.75rem; box-shadow: 0 20px 50px rgba(0, 0, 0, .45);
}
.login-logo { height: 7rem; width: auto; margin: 0 auto .5rem; display: block; }
.login-subtitle { margin: 0 0 .5rem; text-align: center; color: var(--muted-foreground); font-size: .82rem; }
.login-error {
  margin: 0 0 .25rem; padding: .5rem .75rem; border-radius: calc(var(--radius) - 2px);
  background: var(--danger-bg); color: var(--danger-fg); font-size: .82rem; text-align: center;
}
.login-label { font-size: .78rem; color: var(--muted-foreground); margin-bottom: -.35rem; }
.login-card input[type=text], .login-card input[type=password] { width: 100%; }
.login-btn {
  margin-top: .5rem; height: 2.4rem; background: var(--primary); color: var(--primary-foreground);
  border: none; font-weight: 600; font-size: .88rem;
}
.login-btn:hover { opacity: .9; }
button, .btn-logout {
  display: inline-flex; align-items: center; justify-content: center;
  height: 2.25rem; padding: 0 1rem; font-size: .85rem; font-weight: 500;
  border-radius: calc(var(--radius) - 2px); border: 1px solid var(--border);
  background: var(--secondary); color: var(--secondary-foreground); cursor: pointer;
  transition: opacity .15s, background-color .15s, border-color .15s;
  text-decoration: none;
}
button:hover, .btn-logout:hover { background: var(--accent); opacity: 1; }
button:disabled { opacity: .5; cursor: not-allowed; }
table { border-collapse: collapse; width: 100%; }
.muted { color: var(--muted-foreground); font-size: .82rem; }
.text-danger { color: var(--danger-fg); font-size: .82rem; }
.text-warning { color: var(--warning-fg); font-size: .82rem; }
.text-success { color: var(--success-fg); font-size: .82rem; }
.hint { color: var(--muted-foreground); font-size: .78rem; margin: -.75rem 0 1.25rem; }
/* en Info el hint va justo debajo del nav (sin el buscador de por medio como
   en las otras pestañas), asi que el margen negativo de .hint lo deja
   demasiado pegado a las solapas -- se le da su propio margen positivo */
.info-hint { margin-top: .75rem; }

.card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.provider-card { transition: background 2.5s ease; }
.provider-card.card-highlight { background: var(--warning-bg); transition: none; }
.card-header { display: flex; align-items: center; gap: .5rem; padding: .7rem 1rem; border-bottom: 1px solid var(--border); flex: 0 0 auto; }
.card-header-center { justify-content: center; }
.card-title { font-weight: 600; font-size: .92rem; }
.card-subtitle { color: var(--muted-foreground); font-size: .8rem; }
.checked-ago { font-size: .72rem; white-space: nowrap; }
.ip-link { color: var(--primary); font-size: .8rem; text-decoration: none; }
.ip-link:hover { text-decoration: underline; }

.btn-reboot, .btn-toggle-charts, .btn-logout {
  height: 1.6rem; padding: 0 .65rem; font-size: .72rem; font-weight: 600;
  background: var(--secondary); color: var(--secondary-foreground); border: 1px solid var(--border);
}
.btn-reboot:hover, .btn-toggle-charts:hover, .btn-logout:hover { background: var(--accent); opacity: 1; }
.card-content { padding: .4rem 1rem .8rem; flex: 1 1 auto; }
.card-content > table td { padding: .4rem 0; border-bottom: 1px solid var(--border); font-size: .85rem; vertical-align: top; }
.card-content > table tr:last-child > td { border-bottom: none; }
.card-content > table td:first-child { color: var(--muted-foreground); width: 9rem; white-space: nowrap; }

.badge {
  display: inline-flex; align-items: center; border-radius: 9999px; padding: .15rem .55rem;
  font-size: .68rem; font-weight: 600; letter-spacing: .02em; text-transform: uppercase; line-height: 1.4;
}
.badge-success { background: var(--success-bg); color: var(--success-fg); }
.badge-danger { background: var(--danger-bg); color: var(--danger-fg); }
.badge-warning { background: var(--warning-bg); color: var(--warning-fg); }
.badge-muted { background: var(--muted); color: var(--muted-foreground); }

.mod-bars { display: inline-flex; align-items: flex-end; gap: 2px; height: .95rem; margin-right: .4rem; vertical-align: middle; }
.mod-bar-seg { width: .22rem; background: var(--muted); border-radius: 1px; }
.mod-bar-seg.seg-1 { height: 25%; }
.mod-bar-seg.seg-2 { height: 50%; }
.mod-bar-seg.seg-3 { height: 75%; }
.mod-bar-seg.seg-4 { height: 100%; }
.mod-bar-seg.lit { background: var(--success-fg); }

.client-block { display: flex; align-items: stretch; gap: 1rem; margin-bottom: 1.25rem; }
.card.client-details, .card.client-ping { display: flex; flex-direction: column; }
.client-details { flex: 0 1 28rem; max-width: 28rem; min-width: 0; }
.client-ping { flex: 1 1 auto; min-width: 24rem; }

.diag-content { display: flex; flex-direction: row; height: 100%; padding: 0; }
.diag-half { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; padding: .75rem 1rem; }
.diag-half + .diag-half { border-left: 1px solid var(--border); }
.diag-half .ping-out, .diag-half .rate-wrap { flex: 1 1 auto; min-height: 0; }

.btn-ping, .btn-scan {
  width: 100%; background: var(--secondary); color: var(--secondary-foreground); border: 1px solid var(--border);
}
.btn-ping:hover, .btn-scan:hover { background: var(--accent); opacity: 1; }
.btn-ping.active { background: var(--destructive); color: var(--destructive-foreground); border-color: transparent; }
.btn-scan { width: auto; height: 1.9rem; padding: 0 .7rem; font-size: .78rem; }

.ping-out {
  margin-top: .5rem; display: flex; flex-direction: column; overflow: hidden;
  background: var(--background); border: 1px solid var(--border); border-radius: calc(var(--radius) - 4px);
}
.ping-log {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: .5rem .6rem;
  font-family: ui-monospace, SFMono-Regular, monospace; font-size: 1.05rem; line-height: 1.6;
  white-space: pre-wrap; color: var(--muted-foreground);
}
.ping-summary {
  flex: 0 0 auto; padding: .5rem .6rem; border-top: 1px solid var(--border);
  font-size: 1.05rem; line-height: 1.6;
}
.ping-stat-row {
  display: flex; justify-content: space-between; gap: 1rem;
  font-variant-numeric: tabular-nums;
}
.ping-stat-row .ping-stat-label { color: var(--muted-foreground); }
.ping-stat-row .ping-stat-val { color: var(--foreground); font-weight: 600; }
.rate-wrap { margin-top: .6rem; display: flex; flex-direction: column; }
canvas {
  width: 100%; height: 6rem; flex: 1 1 auto; min-height: 6rem; display: block;
  background: var(--background); border: 1px solid var(--border); border-radius: calc(var(--radius) - 4px);
}
.rate-legend { display: flex; gap: 1rem; font-size: .72rem; margin-top: .5rem; color: var(--muted-foreground); }
.legend-item { display: inline-flex; align-items: center; gap: .35rem; }
.legend-dot { width: .5rem; height: .5rem; border-radius: 2px; flex: 0 0 auto; }

.chart-tooltip {
  display: none; position: fixed; z-index: 1000; pointer-events: none;
  background: var(--background); border: 1px solid var(--border); border-radius: var(--radius);
  padding: .4rem .6rem; font-size: .72rem; color: var(--foreground);
  box-shadow: 0 10px 25px rgba(0, 0, 0, .35);
}
.chart-tooltip-row { display: flex; align-items: center; gap: .4rem; white-space: nowrap; min-width: 9rem; }
.chart-tooltip-val { margin-left: auto; padding-left: .75rem; font-variant-numeric: tabular-nums; color: var(--muted-foreground); }
.dot-down { background: var(--chart-down); }
.dot-up { background: var(--chart-up); }
.rate-now { font-size: .74rem; margin-top: .25rem; min-height: 1.1rem; color: var(--muted-foreground); font-variant-numeric: tabular-nums; }

.dhcp-sub { margin-top: .3rem; }
.dhcp-sub th { text-align: left; color: var(--muted-foreground); font-size: .72rem; font-weight: 500; padding: 0 .5rem .25rem 0; }
.dhcp-sub td { padding: .3rem .5rem .3rem 0; border-bottom: 1px solid var(--border); font-size: .82rem; }
.dhcp-sub td:first-child, .dhcp-sub th:first-child { width: 11rem; max-width: 11rem; white-space: normal; word-break: break-word; padding-right: 1rem; }
.dhcp-sub td:first-child .muted { display: block; margin-top: .1rem; }

.pool-table { width: 100%; margin-top: .3rem; }
.pool-table th { text-align: left; color: var(--muted-foreground); font-size: .72rem; font-weight: 500; padding: 0 .5rem .25rem 0; }
.pool-table td { padding: .3rem .5rem .3rem 0; border-bottom: 1px solid var(--border); font-size: .82rem; }
.pool-table td:first-child { white-space: normal; word-break: break-word; }
.pool-table td:last-child, .pool-table th:last-child { text-align: right; padding-right: 0; font-variant-numeric: tabular-nums; }
.pool-table td .muted { display: block; font-size: .72rem; margin-top: .1rem; }
.hostname-link { color: var(--primary); text-decoration: none; }
.hostname-link:hover { text-decoration: underline; }
.scan-out { margin-top: .4rem; }
.log-out { margin-top: .4rem; }
.reboot-out:empty { margin-top: 0; }
.scan-out table { margin-top: .3rem; }
.scan-out td { padding: .3rem .4rem; border-bottom: 1px solid var(--border); font-size: .82rem; }
tr.better td { background: rgba(74, 222, 128, .08); }

#nodos-filter { margin-bottom: 0; }

/* pestaña Nodos: una tarjeta por nodo, con un cano de color a la izquierda
   segun la marca del equipo (mismo criterio que MARCA_POR_TIPO en
   dashboard.py) -- ubiquiti/radio celeste, mikrotik/switch gris, mimosa
   naranja, para poder distinguir el tipo de un vistazo en la grilla. */
.node-grid { display: flex; flex-direction: column; gap: .75rem; }
.node-card { border-left-width: 3px; transition: background 2.5s ease; }
.node-card-radio { border-left-color: #38bdf8; }
.node-card-radio .card-header { background: rgba(56, 189, 248, .08); }
.node-card-switch { border-left-color: #a1a1aa; }
.node-card-switch .card-header { background: rgba(161, 161, 170, .08); }
.node-card-mimosa { border-left-color: #fb923c; }
.node-card-mimosa .card-header { background: rgba(251, 146, 60, .08); }
.node-card .card-content { padding-bottom: .6rem; }
.node-card-body { display: flex; gap: 1rem; align-items: stretch; }
.node-card-body table { flex: 1 1 auto; min-width: 0; }
/* fotos de producto bajadas de los sitios de los fabricantes -- fondo blanco
   fijo (no var(--card)) a proposito: son fotos de catalogo pensadas para
   fondo claro, se ven mal recortadas sobre el tema oscuro del dashboard.
   align-items:stretch (arriba) hace que la imagen tome la misma altura que
   la tabla de al lado -- se define solo el ancho, la altura queda en 100%. */
.node-image { flex: 0 0 9rem; width: 9rem; height: 100%; min-height: 5.5rem; object-fit: contain; background: #fff; border-radius: var(--radius); padding: .3rem; }
.node-actions { margin-top: .5rem; }

/* pantallas angostas (celulares) -- .client-ping tiene min-width:24rem que en
   escritorio evita que el panel de diagnostico quede too angosto, pero en un
   celular ese minimo por si solo ya ocupa casi todo el viewport y empuja
   .client-details a 0 (queda invisible). Se apilan verticalmente y se sacan
   los anchos minimos/fijos pensados para escritorio. */
@media (max-width: 768px) {
  body { margin: 1rem; padding-bottom: 4rem; }
  .client-block { flex-direction: column; }
  .client-details { max-width: none; flex: 1 1 auto; }
  .client-ping { min-width: 0; flex: 1 1 auto; }
  .diag-content { flex-direction: column; height: auto; }
  .diag-half { flex: none; }
  .diag-half + .diag-half { border-left: none; border-top: 1px solid var(--border); }
  .ping-out { min-height: 12rem; }
  /* altura fija (no min-height) para que .ping-log haga scroll interno en vez de
     crecer sin techo con cada ping -- en escritorio la altura la acota la tarjeta,
     pero aca .diag-content queda con height:auto asi que nada mas la limitaba. */
  .ping-log { height: 8rem; }
  form { flex-wrap: wrap; }
  input[type=text], input[type=password] { width: 100%; }
  /* .card recorta (overflow:hidden) lo que no entra -- en escritorio el
     ancho sobra, pero en un celular un texto largo sin espacios (hostname,
     nombre de fabricante, etc.) empuja la tabla mas ancha que la tarjeta y
     el sobrante queda invisible, cortado a la mitad de una palabra. */
  .card-content > table td, .dhcp-sub td, .dhcp-sub th, .pool-table td {
    overflow-wrap: anywhere;
  }
  /* 9rem (etiqueta) + 11rem (columna MAC) pensados para escritorio no
     entran juntos en el ancho real de un celular -- a la columna Hostname
     casi no le queda lugar y el overflow-wrap de arriba la parte letra por
     letra. Se angostan ambas para que quede espacio utilizable. */
  .card-content > table td:first-child { width: 7rem; white-space: normal; }
  .dhcp-sub td:first-child, .dhcp-sub th:first-child { width: auto; max-width: 45%; }
  .node-card-body { flex-direction: column; align-items: center; }
  .node-image { width: 9rem; height: 9rem; }
}
.node-card.row-highlight { background: var(--warning-bg); transition: none; }
