/*
 * Tema del admin — Cartelería Digital, Dean & Dennys
 *
 * Toma la paleta y las fuentes de Aperturas y Gestión de Proyectos, para que
 * las apps del ecosistema se vean como una sola cosa y no como cinco sistemas
 * distintos pegados con SSO.
 *
 * Se apoya en las variables CSS que el admin de Django ya expone en vez de
 * pelear selector por selector: así una actualización de Django no rompe el
 * tema. Los bloques de abajo son solo lo que las variables no alcanzan a
 * cubrir: tipografía de títulos, radios y densidad.
 *
 * Hay tema claro y oscuro de verdad (02/09/2026). Antes las tres selecciones
 * recibían la misma paleta oscura, así que el botón de tema de Django cambiaba
 * el `data-theme` y no pasaba nada: un control que no hace nada es peor que no
 * tenerlo, porque el que lo aprieta cree que algo se rompió.
 *
 * Cómo está armado, y por qué así: el oscuro vive en `:root` —o sea que es el
 * de arranque— y el claro REDEFINE SOLO LAS VARIABLES `--dd-*`. Las variables
 * que consume Django (`--body-bg`, `--header-bg`, ...) se declaran una sola
 * vez en términos de las `--dd-*`, y como todos los selectores apuntan al
 * MISMO elemento (`:root` ES `html`), el navegador resuelve cada una con el
 * valor que gana en la cascada. Sin eso habría que duplicar las sesenta.
 */

:root,
html[data-theme="dark"] {
  /* ---- Paleta base (idéntica a Gestión de Proyectos) ---- */
  --dd-bg:         #0d1117;
  --dd-surface:    #161b22;
  --dd-surface2:   #1c2128;
  --dd-surface3:   #21262d;
  --dd-border:     #21262d;
  --dd-border-l:   #30363d;
  --dd-text:       #e6edf3;
  --dd-dim:        #8b949e;
  --dd-muted:      #6e7681;
  --dd-green:      #238636;
  --dd-green-l:    #3fb950;
  --dd-yellow:     #d29922;
  --dd-yellow-l:   #e3b341;
  --dd-red:        #da3633;
  --dd-red-l:      #f85149;
  --dd-blue:       #1f6feb;
  --dd-blue-l:     #58a6ff;
  --dd-radius:     10px;
  --dd-radius-s:   7px;

  /* ---- Velos y sombras ----
     Estaban escritos a mano como rgba(255,255,255,...) y rgba(0,0,0,...) por
     todo el archivo. Aclarar con blanco funciona sobre fondo oscuro y sobre
     fondo claro no hace absolutamente nada; oscurecer es al revés. Por eso son
     variables: es lo único que no se puede resolver cambiando la paleta. */
  --dd-hover:        rgba(255, 255, 255, .08);   /* botón chico al pasar */
  --dd-hover-fila:   rgba(255, 255, 255, .025);  /* fila de una tabla */
  --dd-hover-suave:  rgba(255, 255, 255, .015);
  --dd-abierto:      rgba(255, 255, 255, .012);  /* bloque desplegado */
  --dd-sombra:       rgba(0, 0, 0, .45);
  --dd-velo:         rgba(0, 0, 0, .55);         /* atrás del cajón lateral */

  /* ---- Variables que consume el admin de Django ---- */
  --primary:       var(--dd-green);
  --secondary:     var(--dd-surface);
  --accent:        var(--dd-green-l);
  --primary-fg:    #fff;

  --body-fg:          var(--dd-text);
  --body-bg:          var(--dd-bg);
  --body-quiet-color: var(--dd-dim);
  --body-loud-color:  #fff;

  --header-color:          var(--dd-text);
  --header-branding-color: var(--dd-green-l);
  --header-bg:             var(--dd-surface);
  --header-link-color:     var(--dd-text);

  --breadcrumbs-fg:      var(--dd-muted);
  --breadcrumbs-link-fg: var(--dd-dim);
  --breadcrumbs-bg:      var(--dd-surface);

  --link-fg:          var(--dd-blue-l);
  /* Por la variable y no por un celeste fijo: sobre fondo blanco un
     #79c0ff es casi invisible. Asi se da vuelta con la paleta. */
  --link-hover-color: var(--dd-blue-l);
  --link-selected-fg: var(--dd-green-l);

  --hairline-color: var(--dd-border);
  --border-color:   var(--dd-border-l);

  --error-fg: var(--dd-red-l);

  --message-success-bg: rgba(35, 134, 54, .15);
  --message-warning-bg: rgba(210, 153, 34, .15);
  --message-error-bg:   rgba(218, 54, 51, .15);

  --darkened-bg:  var(--dd-surface);
  --selected-bg:  var(--dd-surface2);
  --selected-row: rgba(63, 185, 80, .12);

  --button-fg:               #fff;
  --button-bg:               var(--dd-surface3);
  --button-hover-bg:         var(--dd-border-l);
  --default-button-bg:       var(--dd-green);
  --default-button-hover-bg: var(--dd-green-l);
  --close-button-bg:         var(--dd-surface3);
  --close-button-hover-bg:   var(--dd-border-l);
  --delete-button-bg:        var(--dd-red);
  --delete-button-hover-bg:  var(--dd-red-l);

  --object-tools-fg:       var(--dd-text);
  --object-tools-bg:       var(--dd-surface3);
  --object-tools-hover-bg: var(--dd-border-l);

  --font-family-primary: 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-family-monospace: 'DM Mono', ui-monospace, Consolas, monospace;

  color-scheme: dark;
}

/* --------------------------------------------------------------------------
   Encabezado
   -------------------------------------------------------------------------- */

/* Fijo al hacer scroll, igual que la topbar de Aperturas y Proyectos. En un
   listado de 700 pantallas, perder de vista dónde estás parado y cómo salir es
   exactamente lo que no queremos.

   Va `fixed` y no `sticky`. Con sticky el encabezado se despegaba a media
   página: el admin trae `html, body { height: 100% }` y `#container` como
   contenedor flex, y en esa combinación el bloque contenedor del sticky no es
   el que uno espera. `fixed` se ancla al viewport y no depende de la caja de
   ningún antepasado, así que no hay layout que lo pueda romper.

   La contrapartida: al ser fixed sale del flujo, y hay que devolverle su altura
   al contenido con el padding-top de #container. Por eso la altura es un número
   fijo y no `auto` — si cambia, hay que cambiar los tres valores juntos. */
#header {
  border-bottom: 1px solid var(--dd-border);
  padding: 0 24px;
  height: 52px;
  box-sizing: border-box;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 200;
}

/* El hueco que deja el header al salir del flujo. */
#container { padding-top: 52px; }

/* Las migas quedan pegadas abajo del header, que es donde dicen dónde estás. */
div.breadcrumbs {
  position: sticky;
  top: 52px;
  z-index: 190;
}

/* La barra lateral se ancla debajo de las dos, si no se le monta encima. */
#nav-sidebar { top: 88px; }

/* El ancla de los saltos internos tiene que respetar el header fijo, si no el
   título del formulario queda tapado al volver de un error de validación. */
#content-start, .form-row[id], fieldset[id] { scroll-margin-top: 96px; }

#site-name a,
#site-name a:link,
#site-name a:visited {
  font-family: 'Anton', Impact, 'Arial Narrow', sans-serif;
  font-size: 21px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--dd-text);
  font-weight: 400;
}

/* El acento verde en una sola palabra, como el logo de las otras apps. */
#site-name a::after {
  content: " · DEAN & DENNYS";
  color: var(--dd-green-l);
  font-size: 11px;
  letter-spacing: 2px;
  vertical-align: middle;
  margin-left: 6px;
}

#user-tools {
  font-size: 11px;
  color: var(--dd-muted);
  text-transform: none;
  letter-spacing: 0;
}

#user-tools a {
  border-bottom: 0;
  padding: 4px 9px;
  border-radius: 6px;
  background: var(--dd-surface2);
  border: 1px solid var(--dd-border);
  color: var(--dd-dim);
}

#user-tools a:hover { background: var(--dd-surface3); color: var(--dd-text); }

div.breadcrumbs {
  border-bottom: 1px solid var(--dd-border);
  padding: 9px 24px;
  font-size: 11px;
  letter-spacing: .04em;
}

/* --------------------------------------------------------------------------
   Títulos y módulos
   -------------------------------------------------------------------------- */

#content h1,
.dashboard #content h1 {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1;
  margin-bottom: 18px;
}

.module {
  background: var(--dd-surface);
  border: 1px solid var(--dd-border-l);
  border-radius: var(--dd-radius);
  overflow: hidden;
}

.module > h2,
.module caption,
.inline-group h2 {
  background: var(--dd-surface2);
  color: var(--dd-dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 10px 14px;
  border-bottom: 1px solid var(--dd-border);
}


/* ---------------------------------------------------------------------------
   TEMA CLARO
   ---------------------------------------------------------------------------
   Solo las `--dd-*`: las de Django ya están escritas en términos de éstas y se
   recalculan solas. Ver la explicación del encabezado.

   El botón de tema de Django cicla auto → claro → oscuro y escribe
   `data-theme` en <html>. "auto" hay que atenderlo aparte porque no es un
   valor fijo: sigue lo que diga el sistema operativo, y por eso el bloque va
   repetido adentro de un `prefers-color-scheme`. Es la única duplicación del
   archivo y no se puede evitar en CSS: un `@media` no entra en una lista de
   selectores.
   --------------------------------------------------------------------------- */

html[data-theme="light"] {
  --dd-bg:           #f6f8fa;   /* la página; las tarjetas van en blanco encima */
  --dd-surface:      #ffffff;
  --dd-surface2:     #f6f8fa;
  --dd-surface3:     #eaeef2;
  --dd-border:       #d8dee4;
  --dd-border-l:     #afb8c1;
  --dd-text:         #1f2328;
  --dd-dim:          #59636e;
  --dd-muted:        #818b98;
  /* Los `-l` se INVIERTEN de sentido. En oscuro son la versión */
  /* más clara —la que resalta contra el fondo—; en claro tienen */
  /* que ser la más OSCURA, o el acento verde queda ilegible. */
  /* El nombre miente un poco; el papel es el mismo: resaltar. */
  --dd-green:        #1f883d;
  --dd-green-l:      #116329;
  --dd-yellow:       #9a6700;
  --dd-yellow-l:     #7d4e00;
  --dd-red:          #cf222e;
  --dd-red-l:        #a40e26;
  --dd-blue:         #0969da;
  --dd-blue-l:       #0550ae;
  /* Sobre fondo claro se OSCURECE en vez de aclarar. */
  --dd-hover:        rgba(0, 0, 0, .06);
  --dd-hover-fila:   rgba(0, 0, 0, .035);
  --dd-hover-suave:  rgba(0, 0, 0, .022);
  --dd-abierto:      rgba(0, 0, 0, .018);
  --dd-sombra:       rgba(31, 35, 40, .12);
  --dd-velo:         rgba(31, 35, 40, .38);
  /* Blanco sobre fondo blanco: el único de los tres `#fff` del */
  /* bloque de arriba que hay que dar vuelta. Los otros dos van */
  /* sobre botones de color y siguen estando bien. */
  --body-loud-color: #1f2328;
}

@media (prefers-color-scheme: light) {
  html[data-theme="auto"] {
    --dd-bg:           #f6f8fa;   /* la página; las tarjetas van en blanco encima */
    --dd-surface:      #ffffff;
    --dd-surface2:     #f6f8fa;
    --dd-surface3:     #eaeef2;
    --dd-border:       #d8dee4;
    --dd-border-l:     #afb8c1;
    --dd-text:         #1f2328;
    --dd-dim:          #59636e;
    --dd-muted:        #818b98;
    /* Los `-l` se INVIERTEN de sentido. En oscuro son la versión */
    /* más clara —la que resalta contra el fondo—; en claro tienen */
    /* que ser la más OSCURA, o el acento verde queda ilegible. */
    /* El nombre miente un poco; el papel es el mismo: resaltar. */
    --dd-green:        #1f883d;
    --dd-green-l:      #116329;
    --dd-yellow:       #9a6700;
    --dd-yellow-l:     #7d4e00;
    --dd-red:          #cf222e;
    --dd-red-l:        #a40e26;
    --dd-blue:         #0969da;
    --dd-blue-l:       #0550ae;
    /* Sobre fondo claro se OSCURECE en vez de aclarar. */
    --dd-hover:        rgba(0, 0, 0, .06);
    --dd-hover-fila:   rgba(0, 0, 0, .035);
    --dd-hover-suave:  rgba(0, 0, 0, .022);
    --dd-abierto:      rgba(0, 0, 0, .018);
    --dd-sombra:       rgba(31, 35, 40, .12);
    --dd-velo:         rgba(31, 35, 40, .38);
    /* Blanco sobre fondo blanco: el único de los tres `#fff` del */
    /* bloque de arriba que hay que dar vuelta. Los otros dos van */
    /* sobre botones de color y siguen estando bien. */
    --body-loud-color: #1f2328;
  }
}

/* ---------------------------------------------------------------------------
   Que las inline anchas se puedan LEER

   La tabla de Pantallas tiene once columnas y se iba del ancho de la ventana:
   las últimas quedaban cortadas y la única forma de verlas era bajar el zoom
   del navegador.

   Lo que la recortaba es `.module { overflow: hidden }` de más arriba, que
   está ahí para que las esquinas redondeadas no se vean rotas. Por eso no
   alcanzaba con ponerle scroll a `.tabular`: la tabla ya venía cortada un
   nivel más afuera. Acá se libera SOLO el eje horizontal y solo dentro de las
   inline, así el redondeo se mantiene.

   Y `min-width: max-content` es la otra mitad: sin eso el navegador apreta las
   columnas para que entren, la barra no aparece nunca porque técnicamente ya
   "entra", y lo que se ve es ilegible.
   --------------------------------------------------------------------------- */
.inline-group .module,
.inline-group .tabular {
  overflow-x: auto;
}
.inline-group .tabular table {
  min-width: max-content;
}

/* Y que las columnas ocupen lo que necesitan y no lo que Django les da por
   defecto. El nombre de una pantalla es "Menu board 3": con un campo de 400 px
   se comía media fila y empujaba fuera de la vista las columnas del final. Con
   esto la fila entra sola en un portátil, y el scroll de arriba queda como red
   para las pantallas más angostas. */
.inline-group td.field-nombre input { width: 14em; }
.inline-group td.field-posicion input,
.inline-group td.field-ancho_px input,
.inline-group td.field-alto_px input { width: 6em; }

.module h3 { color: var(--dd-dim); }

/* El índice en dos zonas: CONTENIDO y CONFIGURACIÓN son rótulos, no cajas. */
.dashboard .module > h2 {
  background: transparent;
  border-bottom: 1px solid var(--dd-border-l);
  color: var(--dd-green-l);
  font-size: 11px;
  letter-spacing: .16em;
}

.dashboard .module table th { font-weight: 500; }

/* El encabezado de "Locales y pantallas" lleva la leyenda a la derecha. */
.module.locales > h2 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}

/* El titulo empuja al resto contra la derecha. Sin esto, space-between reparte
   los cuatro elementos del encabezado por igual y el buscador queda flotando
   en el medio, lejos de la lista que filtra. */
.module.locales > h2 > span:first-child { margin-right: auto; }

/* El buscador de locales. Angosto a proposito: filtra una lista de codigos
   cortos, no es una caja de texto libre, y ocupar media pantalla lo haria
   parecer mas importante que la lista misma. */
.loc-buscar {
  width: 180px; padding: 4px 9px;
  font-size: 11px; font-weight: 500;
  text-transform: none; letter-spacing: 0;
  color: var(--dd-text); background: var(--dd-surface2);
  border: 1px solid var(--dd-border-l); border-radius: 6px;
}
.loc-buscar:focus { outline: none; border-color: var(--dd-green-l); }
.loc-buscar::placeholder { color: var(--dd-muted); }

/* Cuando el filtro no deja nada, hay que DECIRLO. Una lista vacia sin
   explicacion se lee como "se rompio el panel", no como "no hay coincidencias":
   son dos reacciones muy distintas de quien esta mirando. */
.loc-sin-resultados {
  padding: 14px 4px; font-size: 11px; color: var(--dd-muted);
}

/* --------------------------------------------------------------------------
   Tablas
   -------------------------------------------------------------------------- */

#changelist table thead th {
  background: var(--dd-surface2);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dd-muted);
  border-bottom: 1px solid var(--dd-border-l);
}

#changelist table tbody tr:hover > * { background: var(--dd-surface2); }
#changelist table tbody td, #changelist table tbody th { border-bottom: 1px solid var(--dd-border); }
.row1, .row2 { background: transparent; }

#changelist-search {
  background: var(--dd-surface);
  border: 1px solid var(--dd-border-l);
  border-radius: var(--dd-radius);
  padding: 10px 12px;
}

/* --------------------------------------------------------------------------
   Controles
   -------------------------------------------------------------------------- */

input[type=text], input[type=password], input[type=email], input[type=url],
input[type=number], input[type=tel], input[type=time], input[type=date],
textarea, select, .vTextField {
  background: var(--dd-surface2);
  border: 1px solid var(--dd-border-l);
  border-radius: var(--dd-radius-s);
  color: var(--dd-text);
  padding: 8px 10px;
  line-height: 1.4;
}

/* Los <select> necesitan trato aparte.

   El admin de Django les fija una altura pensada para su padding original; con
   el nuestro, el texto no entra y se cortan las tildes y las colas de las
   letras. Y como el navegador dibuja su propia flecha ENCIMA del contenido, el
   texto largo queda tapado si no se le reserva lugar a la derecha. */
select {
  height: auto;
  min-height: 34px;
  padding-right: 30px;
  appearance: none;
  -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--dd-dim) 50%),
    linear-gradient(135deg, var(--dd-dim) 50%, transparent 50%);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  max-width: 100%;
}

/* El desplegable abierto lo pinta el sistema operativo, no la página: sin esto
   quedan letras claras sobre fondo claro en Windows. */
select option {
  background: var(--dd-surface2);
  color: var(--dd-text);
}

/* Los campos de hora y fecha vienen con un ancho ínfimo del admin. */
.vTimeField, .vDateField { min-width: 100px; }

input:focus, textarea:focus, select:focus {
  border-color: var(--dd-green-l);
  outline: 0;
  box-shadow: 0 0 0 2px rgba(63, 185, 80, .18);
}

.button, input[type=submit], input[type=button], .submit-row input, a.button {
  border-radius: var(--dd-radius-s);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .01em;
  border: 1px solid var(--dd-border-l);
  padding: 8px 15px;
}

.submit-row input.default,
.button.default {
  border-color: transparent;
  font-weight: 700;
}

.object-tools a {
  border-radius: var(--dd-radius-s);
  border: 1px solid var(--dd-border-l);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: none;
}

.submit-row {
  background: var(--dd-surface);
  border: 1px solid var(--dd-border-l);
  border-radius: var(--dd-radius);
  padding: 12px 14px;
}

fieldset.collapsed { background: transparent; }

.help, p.help, .form-row div.help, div.help {
  color: var(--dd-muted);
  font-size: 11px;
  line-height: 1.5;
}

.aligned label { color: var(--dd-dim); font-size: 12px; font-weight: 600; }

/* --------------------------------------------------------------------------
   Mensajes y estados
   -------------------------------------------------------------------------- */

ul.messagelist li {
  border-radius: var(--dd-radius-s);
  border: 1px solid var(--dd-border-l);
  font-size: 13px;
  background-position: 8px 10px;
}

ul.messagelist li { position: relative; padding-right: 34px; }

/* La cruz para cerrar a mano. Existe porque el cierre automatico no puede ser
   la unica salida: si el aviso tapa algo que hace falta AHORA, esperar diez
   segundos es exactamente lo que molesta. */
.msg-cerrar {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  width: 20px; height: 20px; padding: 0; line-height: 1;
  background: none; border: 0; border-radius: 4px;
  color: var(--dd-muted); font-size: 17px; cursor: pointer;
}
.msg-cerrar:hover { background: var(--dd-hover); color: var(--dd-text); }

.msg-yendose {
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity .35s ease, transform .35s ease;
}

ul.messagelist li.success { border-color: rgba(63, 185, 80, .45); }
ul.messagelist li.warning { border-color: rgba(227, 179, 65, .45); }
ul.messagelist li.error   { border-color: rgba(248, 81, 73, .45); }

.errornote, .errorlist li {
  background: rgba(218, 54, 51, .15);
  border: 1px solid rgba(248, 81, 73, .45);
  border-radius: var(--dd-radius-s);
  color: var(--dd-red-l);
}

/* --------------------------------------------------------------------------
   Navegación lateral
   -------------------------------------------------------------------------- */

#nav-sidebar { border-right: 1px solid var(--dd-border); }
.toggle-nav-sidebar { border-right: 1px solid var(--dd-border); background: var(--dd-surface); }

#nav-sidebar .current-model a { background: var(--dd-surface3); color: var(--dd-text); }

#nav-filter {
  background: var(--dd-surface2);
  border: 1px solid var(--dd-border-l);
  border-radius: var(--dd-radius-s);
  color: var(--dd-text);
  margin: 8px;
  width: calc(100% - 16px);
}

/* --------------------------------------------------------------------------
   Login
   -------------------------------------------------------------------------- */

body.login #container {
  background: var(--dd-surface);
  border: 1px solid var(--dd-border-l);
  border-radius: var(--dd-radius);
  box-shadow: 0 14px 40px var(--dd-sombra);
}

body.login #container { padding-top: 0; }

body.login #header {
  position: static;
  height: auto;
  padding: 10px 24px;
  background: transparent;
  border-bottom: 1px solid var(--dd-border);
  border-radius: var(--dd-radius) var(--dd-radius) 0 0;
}

body.login .submit-row { border: 0; background: transparent; padding: 0; }
body.login .submit-row input { width: 100%; }

/* --------------------------------------------------------------------------
   Borrar desde la fila
   -------------------------------------------------------------------------- */

a.borrar-fila {
  color: var(--dd-muted);
  font-size: 13px;
  line-height: 1;
  padding: 3px 7px;
  border-radius: 6px;
  border: 1px solid transparent;
  text-decoration: none;
  display: inline-block;
  transition: .12s;
}

a.borrar-fila:hover {
  color: var(--dd-red-l);
  border-color: rgba(248, 81, 73, .45);
  background: rgba(218, 54, 51, .15);
}

/* Última columna: pegada a la derecha y angosta, para que no compita con los
   datos de la fila. */
#changelist table thead th:last-child,
#changelist table tbody td:last-child {
  width: 1%;
  text-align: right;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Portada: panel de estado del parque
   -------------------------------------------------------------------------- */

/* Django deja el panel flotando con un margen negativo pensado para un ancho
   fijo. Se pasa a grid para que la columna quede pegada al borde derecho sin
   importar el ancho de la ventana.

   Las áreas son explícitas y no automáticas porque #content tiene MÁS hijos
   directos que las dos columnas: el <h1> y un <br class="clear">. Sin
   asignarles lugar, el título se come la primera celda y empuja el contenido a
   la columna angosta. */
.dashboard #content.colMS {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  grid-template-areas:
    "titulo    titulo"
    "principal panel";
  gap: 0 24px;
  align-items: start;
  max-width: none;
  margin-right: 0;
  width: auto;
}

.dashboard #content.colMS > h1 { grid-area: titulo; }
.dashboard #content.colMS > br.clear { display: none; }

.dashboard #content-main {
  grid-area: principal;
  float: none;
  width: auto;
  min-width: 0;
}

.dashboard #content-related {
  grid-area: panel;
  float: none;
  width: auto;
  margin: 0;
  position: sticky;
  top: 96px;
}

.panel-estado { margin-bottom: 16px; }

/* ---- Las cifras ---- */
.pe-cifras {
  display: flex;
  border-bottom: 1px solid var(--dd-border);
}

.pe-cifra {
  flex: 1;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.pe-cifra + .pe-cifra { border-left: 1px solid var(--dd-border); }

.pe-num { font-size: 26px; font-weight: 800; letter-spacing: -.02em; line-height: 1; }
.pe-num.verde    { color: var(--dd-green-l); }
.pe-num.amarillo { color: var(--dd-yellow-l); }
.pe-num.rojo     { color: var(--dd-red-l); }
.pe-num.gris     { color: var(--dd-muted); }
.pe-de { font-size: 14px; font-weight: 600; color: var(--dd-muted); }

.pe-rot {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dd-muted);
}

/* ---- Alertas ---- */
.pe-alertas { list-style: none; margin: 0; padding: 0; }

.pe-alertas li { border-bottom: 1px solid var(--dd-border); }
.pe-alertas li:last-child { border-bottom: 0; }

/* Con enlace o sin el.
 *
 * Casi todas las alertas llevan a un listado filtrado —ver que hay 3 pantallas
 * caidas sin poder llegar a cuales son no sirve de nada— pero el aviso del
 * certificado de firma no tiene a donde ir: no es una fila de la base, es una
 * fecha. Sin esta segunda regla ese renglon salia sin margenes y sin el punto
 * de color, o sea sin lo unico que dice de que gravedad es. */
.pe-alertas a,
.pe-alertas .pe-linea {
  display: block;
  padding: 11px 14px 11px 26px;
  position: relative;
  text-decoration: none;
  color: var(--dd-text);
}

.pe-alertas a:hover { background: var(--dd-surface2); }

/* El punto de color a la izquierda: el nivel se lee antes que el texto. */
.pe-alertas a::before,
.pe-alertas .pe-linea::before {
  content: "";
  position: absolute;
  left: 13px;
  top: 16px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.pe-error a::before,  .pe-error .pe-linea::before  { background: var(--dd-red-l); }
.pe-alerta a::before, .pe-alerta .pe-linea::before { background: var(--dd-yellow-l); }
.pe-info a::before,   .pe-info .pe-linea::before   { background: var(--dd-blue-l); }

.pe-alertas strong { display: block; font-size: 12px; font-weight: 600; }
.pe-alertas span {
  display: block;
  font-size: 11px;
  color: var(--dd-muted);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pe-ok {
  padding: 14px;
  font-size: 12px;
  color: var(--dd-muted);
  margin: 0;
}

/* ---- Eventos ---- */
.pe-eventos { list-style: none; margin: 0; padding: 0; }

.pe-eventos li {
  padding: 9px 14px;
  border-bottom: 1px solid var(--dd-border);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 9px;
  font-size: 11px;
}

.pe-ts { color: var(--dd-muted); font-variant-numeric: tabular-nums; }
.pe-que { color: var(--dd-red-l); font-weight: 600; }
.pe-donde {
  grid-column: 2;
  color: var(--dd-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El motivo puntual del evento. Va en su propio renglón y en gris: es el dato
   que responde "¿tengo que ir al local?", pero no puede competir con el tipo
   ni con la pantalla, que son lo que se escanea de un vistazo. */
.pe-porque {
  display: block;
  grid-column: 2 / -1;
  color: var(--dd-dim);
  font-size: 12px;
  line-height: 1.35;
  margin-top: 2px;
}

.pe-todos {
  display: block;
  padding: 10px 14px;
  font-size: 11px;
  font-weight: 600;
  color: var(--dd-dim);
  text-decoration: none;
}

.pe-todos:hover { color: var(--dd-green-l); }

@media (max-width: 1100px) {
  /* Una sola columna. Y hay que redefinir TAMBIÉN las áreas: dejar
     `grid-template-areas` con dos columnas y bajar `grid-template-columns` a
     una no apila nada — el navegador crea una segunda columna implícita para
     que "panel" tenga dónde ir, y el resumen terminaba ARRIBA de la lista de
     locales, que es justo lo que uno abre el panel para ver.

     El orden acá es deliberado: primero los locales y sus pantallas, después
     el resumen. En una pantalla angosta lo primero tiene que ser qué local
     está en rojo. */
  .dashboard #content.colMS {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "titulo"
      "principal"
      "panel";
    gap: 16px 0;
  }
  .dashboard #content-related { position: static; }
}

/* --------------------------------------------------------------------------
   Login: las dos puertas
   -------------------------------------------------------------------------- */

.boton-core {
  display: block;
  padding: 11px;
  margin-bottom: 18px;
  background: var(--dd-green);
  color: #fff;
  border-radius: var(--dd-radius-s);
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}

.boton-core:hover { background: var(--dd-green-l); color: #fff; }

.separador {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 16px;
  color: var(--dd-muted);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.separador::before, .separador::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--dd-border-l);
}

.nota-login {
  margin: 16px 0 0;
  font-size: 11px;
  color: var(--dd-muted);
  text-align: center;
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Locales y pantallas

   Una tarjeta por pantalla, no un chip.

   La primera version metia nombre, tres barritas de 3px y dos puntitos en una
   fila de 22px de alto, con los numeros escondidos en el "title". Entraban
   muchas pantallas en poco espacio, pero para leer un dato habia que apuntar
   el mouse y esperar. En una portada que se mira de reojo, un dato que exige
   una accion es un dato que no esta.
   -------------------------------------------------------------------------- */

.loc-bloque { border-bottom: 1px solid var(--dd-border); }
.loc-bloque:last-of-type { border-bottom: 0; }
.loc-bloque[open] { background: var(--dd-abierto); }

/* La fila cerrada: un renglon por local, pensada para leer 50 de un vistazo. */
.loc-cab {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 16px; cursor: pointer;
  list-style: none;                       /* saca el triangulo de <details> */
}
.loc-cab::-webkit-details-marker { display: none; }
.loc-cab:hover { background: var(--dd-hover-fila); }

.loc-flecha {
  width: 0; height: 0; flex-shrink: 0;
  border-left: 5px solid var(--dd-muted);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform .12s;
}
.loc-bloque[open] .loc-flecha { transform: rotate(90deg); }

.loc-punto { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.sem-verde    { background: var(--dd-green-l); }
.sem-amarillo { background: var(--dd-yellow-l); }
.sem-rojo     { background: var(--dd-red-l); }
.sem-gris     { background: var(--dd-muted); }

/* Columnas de ancho fijo, no texto suelto.

   Con el ancho libre cada renglon empieza donde termina el anterior: el nombre
   del local arranca en una x distinta en cada fila y los cuadraditos quedan
   escalonados. Leer la columna de estados de arriba a abajo —que es para lo
   que existe— obliga a ir persiguiendola con la vista. Fijando el ancho, las
   tres columnas caen a plomo y la lista se lee de un vistazo. */
.loc-cod {
  font-size: 13px; font-weight: 700; color: var(--dd-text);
  letter-spacing: .2px; flex-shrink: 0;
  min-width: 11ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.loc-desc {
  font-size: 11px; color: var(--dd-muted); flex-shrink: 0;
  width: 170px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Un cuadradito numerado por pantalla. El numero es la posicion dentro del
   local, o sea el mismo que esta pegado en la pared: si desde central se dice
   "la 3 de Devoto esta en negro", el tecnico sabe a cual pantalla ir. */
.loc-puntitos { display: flex; gap: 3px; margin-left: 14px; flex-wrap: wrap; }

.pt {
  display: inline-flex; align-items: center; justify-content: center;
  width: 13px; height: 13px; flex-shrink: 0;
  border-radius: 3px; border: 1px solid transparent;
  font-size: 8px; font-weight: 700; font-style: normal;
  color: rgba(0, 0, 0, .6);
  background: var(--dd-muted);
  font-variant-numeric: tabular-nums;
}
.pt.est-ok             { background: var(--dd-green-l); }
.pt.est-sin_reproducir { background: var(--dd-yellow-l); }
.pt.est-caida          { background: var(--dd-red-l); }
.pt.est-sin_dato       { background: var(--dd-surface3); color: var(--dd-muted);
                         border-color: var(--dd-border-l); }
.pt.est-sin_enrolar    { background: transparent; color: var(--dd-muted);
                         border: 1px dashed var(--dd-muted); }

.loc-cuenta {
  margin-left: auto; flex-shrink: 0;
  font-size: 11px; color: var(--dd-muted);
  font-variant-numeric: tabular-nums;
}
.loc-cuenta b { color: var(--dd-text); font-size: 13px; }
/* El icono de wifi de la fila toma el margen automático que empuja el contador
   a la derecha, y el contador se le pega. Oculto, el contador recupera el suyo. */
.loc-wifi { margin-left: auto; flex-shrink: 0; line-height: 1; }
.loc-wifi[hidden] { display: none; }
.loc-wifi:not([hidden]) + .loc-cuenta { margin-left: 8px; }

/* Lo que se despliega */
.loc-detalle { padding: 4px 16px 16px 40px; }

.loc-acciones { display: flex; gap: 8px; margin-bottom: 11px; }
.loc-editar {
  font-size: 11px; font-weight: 600; padding: 4px 10px; border-radius: 6px;
  border: 1px solid var(--dd-border-l); color: var(--dd-dim);
  text-decoration: none;
}
.loc-editar:hover { border-color: var(--dd-green-l); color: var(--dd-green-l); }

.loc-vacio { color: var(--dd-muted); font-size: 11px; }

/* Las tarjetas se acomodan solas: 1 pantalla ocupa su ancho comodo y 7 se
   reparten en la grilla sin que haya que decidir nada por local. */
.pan-grilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(152px, 1fr));
  gap: 8px;
}

.pan {
  display: block; padding: 8px 9px 7px;
  border: 1px solid var(--dd-border-l); border-radius: var(--dd-radius-s);
  background: var(--dd-surface2); text-decoration: none;
  transition: border-color .12s, background .12s;
}
.pan:hover { border-color: var(--dd-muted); background: var(--dd-surface3); }

/* La caja existe solo para anclar el boton de reinicio a la esquina de la
   tarjeta. La tarjeta sigue siendo un <a> entero y el boton queda afuera: un
   <button> adentro de un <a> no es HTML valido. */
.pan-caja { position: relative; }

/* El menu de acciones del equipo, en la esquina de su propia tarjeta.
   Discreto de entrada y visible al pasar el mouse: se usa una vez cada tanto,
   pero cuando se necesita hay que encontrarlo sin pensar. En una grilla de 7
   tarjetas por local, botones con texto competirian con el estado, que es lo
   que uno viene a leer. */
.pan-menu { position: absolute; top: 3px; right: 3px; z-index: 3; }
.pan-menu > summary {
  list-style: none; cursor: pointer;
  width: 19px; height: 19px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; line-height: 1;
  color: var(--dd-muted); border: 1px solid transparent; border-radius: 5px;
  opacity: .45; transition: opacity .12s, color .12s, border-color .12s;
}
.pan-menu > summary::-webkit-details-marker { display: none; }
.pan-caja:hover .pan-menu > summary { opacity: 1; }
.pan-menu[open] > summary,
.pan-menu > summary:hover {
  opacity: 1; color: var(--dd-yellow-l);
  border-color: var(--dd-yellow-l); background: var(--dd-surface3);
}

/* El menu se abre hacia la izquierda: la tarjeta esta pegada al borde derecho
   de la grilla y hacia alla no hay lugar. */
.pan-menu-caja {
  position: absolute; top: 22px; right: 0; z-index: 4;
  min-width: 178px; padding: 4px;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--dd-surface); border: 1px solid var(--dd-border-l);
  border-radius: var(--dd-radius-s);
  box-shadow: 0 6px 18px var(--dd-sombra);
}
.pan-menu-op {
  display: block; width: 100%; text-align: left;
  padding: 6px 8px; border: 0; border-radius: 5px;
  background: transparent; color: var(--dd-dim);
  font-size: 11px; font-weight: 500; line-height: 1.3;
  text-decoration: none; cursor: pointer;
}
button.pan-menu-op:hover, a.pan-menu-op:hover {
  background: var(--dd-surface3); color: var(--dd-text);
}
/* La opcion que hoy no se puede usar se muestra igual, apagada y con el motivo
   en el tooltip. Esconderla dejaria al menu cambiando de forma segun el estado
   del equipo, y nadie sabria que la opcion existe. */
.pan-menu-op.inerte { color: var(--dd-muted); cursor: default; opacity: .6; }

/* Le deja el rincon libre al menu: sin esto el nombre largo o los avisos de
   la cabecera terminan pasando por debajo. */
.pan-cab { padding-right: 17px; }

.pan-cab { display: flex; align-items: center; gap: 5px; margin-bottom: 5px; }

.pan-pos {
  display: flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; flex-shrink: 0;
  border-radius: 4px; background: var(--dd-surface3);
  font-size: 10px; font-weight: 700; color: var(--dd-dim);
  font-variant-numeric: tabular-nums;
}
.pan-nom {
  font-size: 12px; font-weight: 600; color: var(--dd-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* La forma de la pantalla, dibujada con un borde. Es la proporcion real: 16:9
   acostado y 9:16 parado. Ocupa 14 px y evita tener que abrir la pantalla para
   saber si el gancho vertical del local esta bien configurado. */
.pan-forma {
  display: inline-block; flex-shrink: 0;
  border: 1.5px solid var(--dd-muted); border-radius: 2px;
}
.pan-forma.f-horizontal { width: 15px; height: 9px; }
.pan-forma.f-vertical   { width: 9px;  height: 15px; }
/* El color lo manda el estado, y es el MISMO que la leyenda de arriba y el chip
   del local: amarillo "pantalla en negro", rojo "sin conexion". Hasta el
   17/09/2026 el televisorcito salia rojo con la pantalla en negro —o sea, del
   color de OTRO estado— mientras el chip y el borde de la tarjeta decian
   amarillo. Lo mismo la luz, unas lineas mas abajo. */
.est-ok .pan-forma             { border-color: var(--dd-green-l); }
.est-sin_reproducir .pan-forma { border-color: var(--dd-yellow-l); }
.est-caida .pan-forma          { border-color: var(--dd-red-l); }

.pan-avi { margin-left: auto; font-size: 12px; filter: grayscale(.25); }

/* La pieza está en el formato que no era: se ve con bandas negras y se lee
   mal. No es una falla del equipo, así que va en ámbar y no en rojo, pero
   tiene que estar a la vista: si no, el error solo se descubre cuando alguien
   del local llama para decir que "se ve chico". */
.pan-avi.orientacion { color: var(--dd-yellow-l); font-style: normal; filter: none; }

/* Estado del panel, siempre visible donde el agente lo informa (pedido del
   15/09/2026): blanco encendido, rojo apagado. Mientras la orden viaja, el
   color del estado pedido, titilando: se ve que el clic entró y hacia dónde va. */
.pan-avi.panel-encendido { color: var(--dd-text); filter: none; }
.pan-avi.panel-apagado   { color: var(--dd-red-l); filter: none; }
.pan-avi.panel-yendo     { filter: none; animation: panel-yendo 1.1s ease-in-out infinite; }
.pan-avi.panel-yendo.hacia-encendido { color: var(--dd-text); }
.pan-avi.panel-yendo.hacia-apagado   { color: var(--dd-red-l); }
@keyframes panel-yendo { 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) {
  .pan-avi.panel-yendo { animation: none; opacity: .55; }
}

.pan-estado { display: flex; align-items: center; gap: 5px; margin-bottom: 7px; }
.pan-etq { font-size: 10px; font-weight: 600; color: var(--dd-dim);
           overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pan-motivo {
  font-size: 10px; color: var(--dd-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Una sola luz por pantalla. Antes eran dos puntos (conexion y reproduccion)
   que habia que combinar mentalmente; el estado ya viene resuelto del backend,
   asi que se muestra resuelto. */
.pan-luz {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  background: var(--dd-muted); display: inline-block;
}
.est-ok .pan-luz,             .pan-luz.est-ok             { background: var(--dd-green-l); }
.est-sin_reproducir .pan-luz, .pan-luz.est-sin_reproducir { background: var(--dd-yellow-l); }
.est-caida .pan-luz,          .pan-luz.est-caida          { background: var(--dd-red-l); }
.est-sin_dato .pan-luz,       .pan-luz.est-sin_dato       { background: var(--dd-surface3);
                                                            border: 1px solid var(--dd-border-l); }
.est-sin_enrolar .pan-luz,    .pan-luz.est-sin_enrolar    { background: transparent;
                                                            border: 1px dashed var(--dd-muted); }

.pan.est-sin_reproducir { border-color: rgba(227, 179, 65, .45); }
.pan.est-caida          { border-color: rgba(248, 81, 73, .40); opacity: .8; }
.pan.est-sin_enrolar    { border-style: dashed; opacity: .7; }

/* ---- CPU / RAM / disco, con el numero a la vista ---- */
.pan-metricas { display: flex; flex-direction: column; gap: 3px; margin-bottom: 7px; }

.met { display: flex; align-items: center; gap: 5px; }
.met-rot {
  width: 26px; flex-shrink: 0;
  font-size: 9px; color: var(--dd-muted); text-transform: uppercase;
  letter-spacing: .2px;
}
.met-riel {
  flex: 1; height: 4px; border-radius: 2px; min-width: 20px;
  background: var(--dd-surface3); overflow: hidden;
}
.met-riel i { display: block; height: 100%; border-radius: 3px; }
.met-val {
  width: 25px; flex-shrink: 0; text-align: right;
  font-size: 10px; color: var(--dd-dim);
  font-variant-numeric: tabular-nums;
}

.b-cpu   { background: var(--dd-blue-l); }
.b-ram   { background: #a371f7; }
.b-disco { background: var(--dd-yellow-l); }

.pan-pie {
  display: flex; flex-wrap: wrap; gap: 2px 6px; align-items: center;
  padding-top: 6px; border-top: 1px solid var(--dd-border);
  font-size: 9px; color: var(--dd-muted);
  overflow: hidden;
}
.pan-pie > span + span::before {
  content: '·';
  margin-right: 5px;
  opacity: .5;
}

/* Lo que esta mal en el pie de la tarjeta: el agente que quedo viejo y el
   tiempo que la pantalla lleva sin verse. Van en rojo y en negrita porque se
   leen de reojo, desde lejos, en una pantalla llena de tarjetas. */
.pan-alerta { color: var(--dd-red-l); font-weight: 600; }
/* Atrás de la última versión, pero a su anillo todavía no le toca: es
   información, no una falla. En rojo enseñaría a ignorar el rojo. */
.pan-espera { color: var(--dd-yellow-l); }
/* Cable o wifi: el SVG usa currentColor, así que alcanza con el color. */
.red-cable { color: var(--dd-green-l); }
.red-wifi  { color: var(--dd-red-l); }

.loc-leyenda {
  display: flex; flex-wrap: wrap; gap: 4px 13px; align-items: center;
  font-size: 9px; color: var(--dd-muted);
  text-transform: none; letter-spacing: 0; font-weight: 500;
}
.loc-leyenda > span { display: flex; align-items: center; gap: 5px; }

/* Los de la leyenda son mas chicos que los de las filas: no llevan numero
   adentro, asi que no necesitan lugar para el digito. */
.loc-leyenda .pt { width: 10px; height: 10px; border-radius: 2px; }

@media (max-width: 900px) {
  .loc-cab { flex-wrap: wrap; }
  .loc-cuenta { margin-left: 0; }
  /* Sin lugar para tres columnas, alinearlas es peor que dejarlas fluir. */
  .loc-cod { min-width: 0; }
  .loc-desc { width: auto; max-width: 160px; }
}

/* --------------------------------------------------------------------------
   Login: las dos puertas
   -------------------------------------------------------------------------- */

.boton-core {
  display: block;
  padding: 11px;
  margin-bottom: 18px;
  background: var(--dd-green);
  color: #fff;
  border-radius: var(--dd-radius-s);
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}

.boton-core:hover { background: var(--dd-green-l); color: #fff; }

.separador {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 16px;
  color: var(--dd-muted);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.separador::before, .separador::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--dd-border-l);
}

.nota-login {
  margin: 16px 0 0;
  font-size: 11px;
  color: var(--dd-muted);
  text-align: center;
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Locales y pantallas
   -------------------------------------------------------------------------- */

.loc-fila {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  padding: 11px 14px;
  border-bottom: 1px solid var(--dd-border);
}

.loc-fila:last-of-type { border-bottom: 0; }
.loc-fila:hover { background: var(--dd-hover-suave); }

.loc-nombre {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 250px;
  flex-shrink: 0;
  font-size: 12px;
}

.loc-nombre a { text-decoration: none; }
.loc-nombre b { color: var(--dd-text); }
.loc-desc { color: var(--dd-muted); overflow: hidden; text-overflow: ellipsis;
            white-space: nowrap; }
.loc-cuenta { margin-left: auto; color: var(--dd-muted); font-size: 11px;
              font-variant-numeric: tabular-nums; }

.loc-editar {
  font-size: 10px; font-weight: 600; padding: 2px 7px; border-radius: 5px;
  border: 1px solid var(--dd-border-l); color: var(--dd-muted);
  text-decoration: none; flex-shrink: 0;
}
.loc-editar:hover { border-color: var(--dd-green-l); color: var(--dd-green-l); }

/* El semáforo del local: manda la peor de sus pantallas. */
.loc-punto { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.sem-verde    { background: var(--dd-green-l); }
.sem-amarillo { background: var(--dd-yellow-l); }
.sem-rojo     { background: var(--dd-red-l); }
.sem-gris     { background: var(--dd-muted); }

.loc-pantallas { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; }
.loc-vacio { color: var(--dd-muted); font-size: 11px; padding: 3px 0; }

/* ---- El chip de cada pantalla ---- */
.chip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border: 1px solid var(--dd-border-l);
  border-radius: 6px;
  background: var(--dd-surface2);
  font-size: 11px;
  color: var(--dd-dim);
  text-decoration: none;
}

.chip:hover { border-color: var(--dd-muted); color: var(--dd-text); }
.chip-nom { max-width: 130px; overflow: hidden; text-overflow: ellipsis;
            white-space: nowrap; }
.chip-sep { width: 1px; height: 12px; background: var(--dd-border-l); }
.chip-avi { font-size: 11px; filter: grayscale(.3); }

/* Dos puntos y no uno: "responde" y "se ve algo" son cosas distintas, y la
   diferencia importa — una miniPC puede estar perfecta con la pantalla en
   negro. El de arriba es la conexión; el de abajo, la reproducción. */
.chip-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
            background: var(--dd-muted); }
.chip-dot.repro { border-radius: 2px; }   /* cuadrado: se distingue sin color */

.est-ok .conexion, .conexion.est-ok { background: var(--dd-green-l); }
.est-ok .repro,    .repro.est-ok    { background: var(--dd-green-l); }

.est-sin_reproducir .conexion { background: var(--dd-green-l); }
.est-sin_reproducir .repro, .repro.est-sin_reproducir { background: var(--dd-red-l); }
.est-sin_reproducir { border-color: rgba(227, 179, 65, .45); }

.est-caida .conexion, .conexion.est-caida { background: var(--dd-red-l); }
.est-caida .repro { background: var(--dd-surface3); }
.est-caida { border-color: rgba(248, 81, 73, .40); opacity: .75; }

.est-sin_enrolar { border-style: dashed; opacity: .6; }

/* Responde, pero su agente es anterior a la 2.0 y no informa si la pantalla
   muestra algo. Gris y no rojo: no sabemos que esté mal. */
.est-sin_dato .conexion { background: var(--dd-green-l); }
.est-sin_dato .repro, .repro.est-sin_dato { background: var(--dd-surface3);
                                            border: 1px solid var(--dd-border-l); }

/* ---- Las barritas de CPU / RAM / disco ---- */
.barras {
  display: flex; align-items: flex-end; gap: 2px;
  height: 13px; flex-shrink: 0;
}
.barras i { width: 3px; border-radius: 1px; min-height: 1px; display: block; }
.b-cpu   { background: var(--dd-blue-l); }
.b-ram   { background: #a371f7; }
.b-disco { background: var(--dd-yellow-l); }

.loc-leyenda {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center;
  padding: 10px 14px; border-top: 1px solid var(--dd-border);
  font-size: 10px; color: var(--dd-muted);
}
.loc-leyenda span { display: flex; align-items: center; gap: 5px; }
.loc-leyenda i { display: inline-block; }
.loc-leyenda-barras i { width: 3px; height: 9px; border-radius: 1px; }

@media (max-width: 1400px) {
  .loc-fila { flex-direction: column; gap: 8px; }
  .loc-nombre { min-width: 0; width: 100%; }
}

/* --------------------------------------------------------------------------
   Login: las dos puertas
   -------------------------------------------------------------------------- */

.boton-core {
  display: block;
  padding: 11px;
  margin-bottom: 18px;
  background: var(--dd-green);
  color: #fff;
  border-radius: var(--dd-radius-s);
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}

.boton-core:hover { background: var(--dd-green-l); color: #fff; }

.separador {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 16px;
  color: var(--dd-muted);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.separador::before, .separador::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--dd-border-l);
}

.nota-login {
  margin: 16px 0 0;
  font-size: 11px;
  color: var(--dd-muted);
  text-align: center;
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Espacio reservado para el mapa de locales
   -------------------------------------------------------------------------- */

.reservado-cuerpo {
  padding: 40px 24px;
  text-align: center;
  color: var(--dd-muted);
  font-size: 12px;
  line-height: 1.6;
}

.reservado-cuerpo p { margin: 0 auto 8px; max-width: 460px; }

.reservado-titulo {
  font-size: 15px;
  font-weight: 700;
  color: var(--dd-dim);
  letter-spacing: -.01em;
}

.reservado-nota {
  margin-top: 18px !important;
  padding-top: 14px;
  border-top: 1px solid var(--dd-border);
  font-size: 11px;
}

/* Acceso al editor visual desde el listado de locales. */
a.boton-editor {
  display: inline-block;
  padding: 4px 11px;
  border-radius: 6px;
  border: 1px solid var(--dd-border-l);
  background: var(--dd-surface2);
  color: var(--dd-dim);
  font-size: 11px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

a.boton-editor:hover {
  border-color: var(--dd-green-l);
  color: var(--dd-green-l);
  background: rgba(63, 185, 80, .10);
}

/* --------------------------------------------------------------------------
   Progreso de las conversiones
   -------------------------------------------------------------------------- */

.avance { min-width: 150px; }

.avance-barra {
  height: 4px;
  background: var(--dd-surface3);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 4px;
}

.avance-barra i {
  display: block;
  height: 100%;
  background: var(--dd-green-l);
  border-radius: 2px;
  transition: width .4s;
}

.avance-txt { font-size: 10px; color: var(--dd-dim); }

.pill-ok, .pill-error, .pill-espera {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
}

.pill-ok     { background: rgba(35,134,54,.18);  color: var(--dd-green-l); }
.pill-error  { background: rgba(218,54,51,.18);  color: var(--dd-red-l); cursor: help; }
.pill-espera { background: rgba(31,111,235,.18); color: var(--dd-blue-l); }


/* ---- Buscador en vivo de las listas ----
   El borde cambia mientras se espera la última tecla. Sin esa señal, los 400 ms
   de pausa se leen como que el buscador no anda. */
#searchbar { transition: border-color .15s, box-shadow .15s; }
#searchbar.buscando {
  border-color: var(--dd-green, #3fb950) !important;
  box-shadow: 0 0 0 2px rgba(63, 185, 80, .16);
}

/* ===========================================================================
   TELÉFONO
   ===========================================================================

   Qué se hace con el panel parado en la calle: mirar si hay una pantalla en
   rojo, en qué local, y actuar —reiniciarla o entrar por AnyDesk—. Eso es lo
   que tiene que entrar bien en 390 px.

   Los editores NO entran acá, y no por diseño sino por mecanismo: el de
   contenido usa arrastrar y soltar de HTML5, que con el dedo no responde, y el
   de precios pide dibujar cajas al píxel. Se avisa en vez de mostrar algo roto
   (ver `.solo-escritorio`).

   El corte más chico que había era 900 px: pensado para tablet. Un teléfono
   son 390.
   =========================================================================== */

@media (max-width: 600px) {
  /* PRIMERO: devolver el encabezado al flujo.
     
     `#header` es `position: fixed` con `height: 52px` —un número fijo, con su
     comentario más arriba avisando que los tres valores van juntos— y el hueco
     se compensa con `padding-top` en `#container`. En un teléfono su contenido
     (marca + "Bienvenido/a" + los tres enlaces) ocupa tres renglones: se
     desborda de su propia caja de 52 px y pinta ENCIMA de la página. Se veía
     el menú lateral escrito arriba del nombre del usuario.

     Acá deja de ser fijo y crece lo que necesite, empujando en vez de tapar.
     Un encabezado pegado tampoco vale su costo cuando hay 700 px de alto útil.
     Y se lo arma como flex que envuelve, para no depender de si Django lo
     maqueta con float o con flex según la versión. */
  #header {
    position: static; height: auto;
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 4px 10px; padding: 8px 12px;
  }
  #branding { width: 100%; }
  #user-tools {
    position: static; float: none;
    width: 100%; margin: 0; text-align: left;
  }
  #container { padding-top: 0; }
  div.breadcrumbs { position: static; }
  /* Sin header fijo, el ancla de los saltos internos ya no tiene que esquivar
     nada. */
  #content-start, .form-row[id], fieldset[id] { scroll-margin-top: 8px; }

  /* El menú lateral lo maneja Django, que ya trae sus propias reglas para
     pantalla chica y el botón para plegarlo. Antes acá se lo anclaba en `top:
     88px` para esquivar el header fijo; sin header fijo, ese número lo
     empujaba fuera de lugar. */
  #nav-sidebar { top: 0; }

  /* Menos aire: en 390 px cada píxel de padding es contenido que no se ve. */
  #content { padding: 10px 12px !important; }
  #content h1 { font-size: 17px; }

  /* Los números del resumen en fila no entran; en dos por dos sí, y siguen
     leyéndose de un golpe de vista, que es para lo que están. */
  .pe-cifras { flex-wrap: wrap; }
  .pe-cifra { flex: 1 1 50%; min-width: 0; padding: 10px 6px; }
  .pe-cifra + .pe-cifra { border-left: 0; }
  .pe-num { font-size: 22px; }

  /* El encabezado de cada local pasa a dos renglones en vez de recortar el
     nombre a tres letras. */
  .loc-cab { flex-wrap: wrap; gap: 6px 8px; padding: 10px 12px; }
  .loc-cod { min-width: 0; }
  .loc-desc { display: none; }          /* la descripción no decide nada acá */
  .loc-cuenta { margin-left: 0; }

  /* Dos pantallas por fila. Una sola desperdicia el ancho y obliga a un scroll
     larguísimo en un local de seis. */
  .pan-grilla { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }

  /* El pie de la tarjeta (IP, versión, uptime) es lo primero que sobra cuando
     no hay lugar: se deja envolver en vez de recortarse. */
  .pan-pie { overflow: visible; font-size: 9px; }

  /* Blancos táctiles. 32 px es el mínimo cómodo con el pulgar; los botones de
     reiniciar y AnyDesk quedaban en 20 y había que apuntar. */
  .loc-acciones { flex-wrap: wrap; }
  .loc-editar, .pan-menu-op, .btn-reiniciar { min-height: 32px; }

  /* Las tablas anchas del admin ya deslizan (ver .inline-group más arriba).
     Acá se les avisa que se puede, porque en un teléfono la barra de scroll
     no se ve hasta que uno la toca. */
  .inline-group .tabular::after {
    content: 'Deslizá la tabla para ver el resto →';
    display: block; padding: 6px 12px;
    font-size: 11px; color: var(--dd-muted);
  }
}

/* Pantallas muy angostas: los pares de tarjetas quedan ilegibles. */
@media (max-width: 400px) {
  .pan-grilla { grid-template-columns: minmax(0, 1fr); }
}

/* El cartel de "esto pide una computadora". Vive acá y no en cada editor para
   que sea uno solo y diga siempre lo mismo. */
.solo-escritorio { display: none; }
@media (max-width: 760px), (pointer: coarse) and (max-width: 1024px) {
  .solo-escritorio {
    display: block;
    margin: 12px; padding: 14px 16px;
    background: var(--dd-surface2, #18212e);
    border: 1px solid var(--dd-yellow, #d29922);
    border-radius: 8px;
    color: var(--dd-text, #e6edf5);
    font-size: 13px; line-height: 1.5;
  }
  .solo-escritorio b { color: var(--dd-yellow-l, #e3b341); }
}

/* ---------------------------------------------------------------------------
   El menú en el teléfono

   Django esconde `#nav-sidebar` Y `#toggle-nav-sidebar` abajo de 767 px (está
   en su `responsive.css`), así que en un celular no hay ninguna forma de ir a
   Creatives, Playlists o Locales: se ve la portada y nada más.

   Se los devuelve, pero con otra forma. En escritorio el menú EMPUJA el
   contenido —una columna al costado—; en 390 px eso no entra. Acá se corre por
   encima, como un cajón, y el fondo se oscurece para que quede claro que hay
   algo abierto.

   Se reusa el botón y el JavaScript de Django: su script alterna la clase
   `shifted` sobre `.main`, y eso es todo lo que hace falta. Nada de markup ni
   de código propio que después haya que mantener en paralelo.
   --------------------------------------------------------------------------- */

@media (max-width: 767px) {
  /* El botón va arriba a la derecha, a la altura del encabezado, que es donde
     uno lo busca. Flotante y no dentro del encabezado: el encabezado ahora se
     va con el scroll, y el menú tiene que seguir a mano en cualquier punto de
     la página.

     Los cuatro lados se declaran a propósito. Django le pone `left: 0` y
     `top: 0` (por su clase `sticky`), así que sin anular los dos el botón se
     va a la izquierda o queda encima del título — las dos cosas ya pasaron. */
  #toggle-nav-sidebar {
    display: flex !important;
    position: fixed;
    top: 10px; right: 12px;
    left: auto; bottom: auto;
    width: 42px; height: 42px;
    flex: none;
    border: 1px solid var(--dd-border-l);
    border-radius: 50%;
    background: var(--dd-surface2);
    color: var(--dd-text);
    box-shadow: 0 4px 14px var(--dd-sombra);
    z-index: 320;
    font-size: 20px; line-height: 1;
  }
  /* Las comillas angulares de Django no se entienden como "menú" en un
     teléfono. Hamburguesa cuando está cerrado, cruz cuando está abierto. */
  #toggle-nav-sidebar::before { content: '\2630'; }
  .main.shifted #toggle-nav-sidebar::before { content: '\2715'; }

  /* El menú, como cajón por encima del contenido. */
  .main > #nav-sidebar {
    display: block !important;
    visibility: hidden;
    position: fixed;
    top: 0; bottom: 0; left: 0;
    width: min(78vw, 280px);
    max-width: 280px;
    margin: 0;
    padding-top: 56px;           /* que el botón no tape el buscador de arriba */
    background: var(--dd-surface);
    border-right: 1px solid var(--dd-border-l);
    box-shadow: 6px 0 24px var(--dd-sombra);
    overflow-y: auto;
    z-index: 300;
    transform: translateX(-100%);
    transition: transform .18s ease;
  }
  .main.shifted > #nav-sidebar {
    visibility: visible;
    transform: translateX(0);
  }

  /* El fondo oscurecido. Va sobre `.main` para no tocar el HTML, y solo
     aparece con el cajón abierto. */
  .main.shifted::before {
    content: '';
    position: fixed; inset: 0;
    background: var(--dd-velo);
    z-index: 290;
  }

  /* Sin el cajón, el contenido usa todo el ancho. */
  .main > #nav-sidebar + .content,
  .main.shifted > #nav-sidebar + .content { max-width: 100%; }
}

/* ---- Pestañas de agrupamiento en el listado de contenido ----
 *
 * Van arriba de la tabla y no en el filtro lateral: separan conjuntos que
 * Marketing usa todo el tiempo, y un filtro lateral obliga a dos clics y no
 * deja ver en cuál estás parado. El conteo al lado del nombre no es adorno —
 * una pestaña vacía y una pestaña rota se ven igual sin el número. */
.pestanas-grupo {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0 0 12px;
  border-bottom: 1px solid var(--dd-border);
  padding-bottom: 8px;
}

.pestanas-grupo a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px;
  border-radius: 6px 6px 0 0;
  font-size: 13px;
  color: var(--dd-muted);
  text-decoration: none;
  border: 1px solid transparent;
  border-bottom: 0;
}

.pestanas-grupo a:hover { color: var(--dd-text); background: var(--dd-surface2); }

/* La pestaña abierta va en el verde de la casa, el mismo del branding.

   Antes se distinguía sólo por el fondo, que sobre una superficie oscura es
   una diferencia de dos tonos de gris: en la tele del local, y en el monitor
   de cualquiera con el brillo bajo, no se veía cuál estaba abierta. El color
   hace ese trabajo mucho mejor que el contraste. */
.pestanas-grupo a.on {
  color: var(--dd-green-l);
  background: var(--dd-surface2);
  border-color: var(--dd-border);
  font-weight: 600;
  /* La línea de abajo tapa el borde del contenedor: es lo que hace que la
     pestaña se lea como pestaña y no como un botón suelto. */
  box-shadow: inset 0 2px 0 var(--dd-green-l), 0 1px 0 var(--dd-surface2);
}

.pestanas-grupo .n {
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 9px;
  background: var(--dd-border);
  color: var(--dd-muted);
  font-variant-numeric: tabular-nums;
}

.pestanas-grupo a.on .n {
  color: var(--dd-green-l);
  background: rgba(63, 185, 80, .14);
}

/* Renombrar, borrar y crear.

   Los dos primeros aparecen sólo en la pestaña abierta; se apoyan en ella y
   por eso van sin fondo, para que se lean como parte de la pestaña y no como
   tres botones más en la barra. */
.pestanas-grupo .pg-icono,
.pestanas-grupo .pg-nuevo {
  cursor: pointer;
  font-family: inherit;
  border-radius: 6px;
  border: 1px solid transparent;
  background: none;
  line-height: 1;
}

.pestanas-grupo .pg-icono {
  color: var(--dd-muted);
  font-size: 13px;
  padding: 6px 7px;
  margin-left: -2px;
}

.pestanas-grupo .pg-icono:hover {
  color: var(--dd-green-l);
  background: var(--dd-surface2);
}

/* Borrar en rojo al pasar por encima, y sólo al pasar: en reposo tiene que
   pesar lo mismo que renombrar, porque está al lado y se aprieta sin mirar. */
.pestanas-grupo .pg-borrar:hover { color: var(--dd-red-l); }

.pestanas-grupo .pg-nuevo {
  margin-left: auto;
  color: var(--dd-green-l);
  border-color: var(--dd-border-l);
  font-size: 12px;
  font-weight: 600;
  padding: 6px 12px;
}

.pestanas-grupo .pg-nuevo:hover {
  background: rgba(63, 185, 80, .12);
  border-color: var(--dd-green);
}

/* ---- Consola de diagnostico (modal desde el chip) ----------------------
   Un modal y no una pagina: la pregunta "¿que le pasa a esta?" se hace
   mirando la portada. La salida va en <pre> con scroll propio y tope de
   alto: un Get-WinEvent devuelve cientos de renglones y no puede empujar
   el resto de la ventana fuera de la pantalla. */
/* z-index POR ENCIMA de todo lo del sitio: el encabezado esta en 200 y el
   menu lateral llega a 320. Con 60, la barra de arriba tapaba el titulo y la
   X —la ventana quedaba abierta y sin forma de cerrarla con el mouse—.
   Pasó el 21/09/2026, y es el segundo intento: antes se recortaba sola por
   centrarla siendo mas alta que la pantalla. Ahora la caja nunca pasa del
   alto de la ventana, asi que centrarla es seguro. */
.con-fondo {
  position: fixed; inset: 0; z-index: 400;
  background: var(--dd-velo, rgba(0, 0, 0, .55));
  display: flex; align-items: center; justify-content: center;
  padding: 16px; overflow: auto;
}
/* Esto NO es redundante y no se borra. El JavaScript cierra la ventana con
   `hidden`, que de fábrica vale `display: none`... pero es una regla del
   navegador, y CUALQUIER `display` de una clase le gana. Sin este renglón la
   X no hace nada, y tampoco Esc ni el clic afuera, porque los tres cierran
   igual. Pasó el 21/09/2026. */
.con-fondo[hidden] { display: none; }
/* Columna flex y NO un bloque con scroll: el encabezado, el boton de abrir y
   el cuadro de texto se quedan fijos, y lo unico que scrollea es el historial
   —que es lo unico que crece, porque una salida de Get-WinEvent son cientos de
   renglones—. Con scroll en la caja entera, escribir un comando obligaba a
   subir hasta arriba de todo. */
.con-caja {
  background: var(--dd-surface2); border: 1px solid var(--dd-border);
  border-radius: var(--dd-radius, 8px); box-shadow: var(--dd-sombra, 0 8px 32px rgba(0,0,0,.4));
  width: min(860px, 100%); max-height: calc(100vh - 32px);
  display: flex; flex-direction: column; padding: 12px 14px;
}
/* Todo lo de arriba del historial es de alto fijo: si se pudiera encoger, el
   cuadro de texto se achicaria hasta desaparecer cuando la lista crece. */
.con-cab, .con-llave, .con-texto, .con-pie { flex: none; }
.con-cab { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.con-cab .con-nombre { font-size: 14px; color: var(--dd-text); }
.con-estado { font-size: 11px; color: var(--dd-muted); }
.con-estado.viva { color: var(--dd-green-l); }
.con-x {
  margin-left: auto; background: none; border: 0; cursor: pointer;
  color: var(--dd-muted); font-size: 14px; padding: 2px 6px;
}
.con-x:hover { color: var(--dd-text); }

.con-llave { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.con-abrir {
  background: var(--dd-surface3); color: var(--dd-text);
  border: 1px solid var(--dd-border-l); border-radius: var(--dd-radius-s, 5px);
  padding: 5px 12px; font-size: 12px; font-weight: 600; cursor: pointer;
}
.con-abrir.abierta { color: var(--dd-green-l); border-color: var(--dd-green); }
.con-aviso { font-size: 11px; color: var(--dd-muted); }

.con-texto {
  width: 100%; box-sizing: border-box; resize: vertical;
  background: var(--dd-surface); color: var(--dd-text);
  border: 1px solid var(--dd-border-l); border-radius: var(--dd-radius-s, 5px);
  padding: 8px; font-family: ui-monospace, Consolas, monospace; font-size: 12px;
}
.con-texto:disabled { opacity: .5; }
.con-pie { display: flex; align-items: center; gap: 10px; margin: 8px 0 12px; }
.con-mandar {
  background: var(--dd-green); color: #fff; border: 0;
  border-radius: var(--dd-radius-s, 5px); padding: 6px 16px;
  font-size: 12px; font-weight: 600; cursor: pointer;
}
.con-mandar:disabled { opacity: .45; cursor: default; }
.con-nota { font-size: 11px; color: var(--dd-muted); }

/* `min-height: 0` no es adorno: sin eso, un hijo flex no baja de su alto
   natural y la lista empuja la ventana fuera de la pantalla en vez de
   scrollear adentro. */
.con-lista {
  display: flex; flex-direction: column; gap: 10px;
  flex: 1 1 auto; min-height: 0; overflow: auto;
  border-top: 1px solid var(--dd-border); padding-top: 8px;
}
.con-vacio { font-size: 12px; color: var(--dd-muted); margin: 0; }
.con-item { border-top: 1px solid var(--dd-border); padding-top: 8px; }
.con-item-cab { font-size: 11px; color: var(--dd-muted); margin-bottom: 4px; }
.con-cmd, .con-salida {
  margin: 0 0 6px; padding: 7px 9px; white-space: pre-wrap; word-break: break-word;
  font-family: ui-monospace, Consolas, monospace; font-size: 11.5px;
  border-radius: var(--dd-radius-s, 5px); overflow: auto;
}
/* El comando va recortado y la salida no: cuando uno vuelve a mirar, lo que
   busca es la RESPUESTA. Un comando del asistente son treinta renglones y,
   completo, tapaba la salida de los tres comandos anteriores. Se despliega
   con un clic. */
.con-cmd { background: var(--dd-surface3); color: var(--dd-dim); max-height: 66px; cursor: zoom-in; }
.con-cmd.abierto { max-height: 260px; cursor: zoom-out; }
.con-salida { max-height: 300px; }
.con-salida { background: var(--dd-surface); color: var(--dd-text); }

/* En el menu del chip, la opcion queda en verde mientras la consola de esa
   pantalla este abierta: es ejecucion de comandos arbitrarios y tiene que
   saltar a la vista sin abrir nada. */
.pan-menu-op.btn-consola.abierta { color: var(--dd-green-l); font-weight: 600; }
