/* Monitoreo CCTV — interfaz de sala de control.
   Oscura a proposito: en un monitor que esta prendido todo el dia, un fondo
   claro cansa la vista y le roba contraste a la imagen de las camaras. */

:root {
  --bg: #0d1014;
  --panel: #161b22;
  --line: #262d36;
  --text: #dfe4ea;
  --muted: #7d8794;
  --accent: #2f81f7;
  --ok: #3fb950;
  --warn: #d29922;
  --error: #f85149;
  --bar-height: 48px;
  --gap: 2px;
  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  overflow: hidden;
}

[hidden] { display: none !important; }

/* ── Login ───────────────────────────────────────────────────────── */

.login {
  display: grid;
  place-items: center;
  height: 100%;
}

.login-card {
  display: grid;
  gap: 8px;
  width: min(360px, calc(100vw - 32px));
  padding: 28px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
}

.login-card h1 {
  margin: 0 0 12px;
  font-size: 19px;
  font-weight: 600;
}

.login-card label {
  font-size: 12px;
  color: var(--muted);
}

.login-card input {
  padding: 9px 11px;
  background: #0d1117;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  font-size: 14px;
}

.login-card input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

.login-card button.login-submit {
  margin-top: 10px;
  padding: 10px;
  background: var(--accent);
  border: 0;
  border-radius: 6px;
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.login-card button.login-submit:hover { filter: brightness(1.1); }
.login-card button.login-submit:disabled { opacity: .6; cursor: progress; }

.error {
  margin: 4px 0 0;
  color: var(--error);
  font-size: 13px;
}

/* ── Barra superior ──────────────────────────────────────────────── */

#app {
  display: grid;
  grid-template-rows: var(--bar-height) 1fr;
  height: 100%;
}

.bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.brand { font-size: 15px; letter-spacing: .2px; }
.spacer { flex: 1; }
.user { color: var(--muted); font-size: 13px; }
.page-info { color: var(--muted); font-size: 13px; min-width: 62px; text-align: center; }

.bar button {
  padding: 5px 11px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}

.bar button:hover { background: #1d232c; }
.bar button:disabled { opacity: .35; cursor: default; }
.layouts { display: flex; gap: 4px; }
.layouts button.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Volver al orden original: siempre en su lugar, pero sin llamar la atencion. */
.subtle { opacity: .35; border-color: transparent; background: transparent; }
.subtle:hover:not(:disabled), .subtle:focus-visible { opacity: 1; }
.subtle:disabled { opacity: .15; cursor: default; }

/* Mover camaras del mosaico arrastrandolas. */
.grid { user-select: none; }
.grid .cell[data-camera-id] { cursor: grab; }
body.dragging-camera, body.dragging-camera * { cursor: grabbing !important; }
.grid .cell.dragging { opacity: .4; }
.grid .cell.drop-target { outline: 2px solid var(--accent); outline-offset: -2px; }
#prev-page.drop-target, #next-page.drop-target { outline: 2px solid var(--accent); }
.drag-ghost {
  position: fixed; left: 0; top: 0; z-index: 50; pointer-events: none;
  padding: 4px 10px; border-radius: 6px; font-size: 12px;
  background: var(--accent); color: #fff; box-shadow: 0 4px 14px rgba(0, 0, 0, .5);
}

/* Boton ⇄ de cada celda: aparece al pasar el mouse. */
.cell-swap {
  position: absolute; top: 6px; right: 6px; z-index: 2;
  padding: 2px 8px; font-size: 14px; line-height: 1.2;
  background: rgba(0, 0, 0, .55); border: 1px solid var(--line); color: var(--text);
  opacity: 0; transition: opacity .15s; cursor: pointer;
}
.cell:hover .cell-swap, .cell-swap:focus-visible { opacity: 1; }
.cell.empty .cell-swap, .grid.zoomed .cell-swap { display: none; }
@media (hover: none) { .cell-swap { opacity: .8; } }

.swap-dialog {
  width: min(460px, calc(100vw - 32px)); max-height: 70vh;
  background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 8px;
  padding: 16px; display: none; flex-direction: column; gap: 10px;
}
.swap-dialog[open] { display: flex; }
.swap-dialog::backdrop { background: rgba(0, 0, 0, .55); }
.swap-dialog h2 { margin: 0; font-size: 15px; }
.swap-list { overflow: auto; display: flex; flex-direction: column; gap: 2px; min-height: 0; flex: 1; }
.swap-dialog input {
  width: 100%; box-sizing: border-box; padding: 8px 10px; font: inherit; font-size: 13px;
  background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 6px;
}
.swap-dialog input:focus { outline: none; border-color: var(--accent); }
.swap-dialog button {
  font: inherit; font-size: 13px; color: var(--text); cursor: pointer;
  background: transparent; border: 1px solid transparent; border-radius: 6px; padding: 7px 10px;
}
.swap-list button { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; text-align: left; }
.swap-list button:hover, .swap-list button:focus-visible { background: #1d232c; border-color: var(--line); outline: none; }
#swap-cancel { border-color: var(--line); background: var(--bg); }
#swap-cancel:hover { background: #1d232c; }
.swap-list small { color: var(--muted); }
.swap-empty { color: var(--muted); margin: 8px 0; }

.badge {
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .5px;
}

/* ── Mosaico ─────────────────────────────────────────────────────── */

/* El unico parametro de la disposicion es --cols: pasar de 4 a 9 o a 16
   camaras es cambiar esa variable, sin tocar nada de JavaScript.
   Las filas se derivan solas y todas miden lo mismo. */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  grid-auto-rows: 1fr;
  gap: var(--gap);
  padding: var(--gap);
  height: 100%;
  min-height: 0;
  background: #05070a;
}

.cell {
  position: relative;
  min-width: 0;
  min-height: 0;
  background: #000;
  border: 1px solid transparent;
  overflow: hidden;
}

.cell:hover { border-color: var(--line); }

.cell video {
  width: 100%;
  height: 100%;
  /* `contain` y no `cover`: recortar la imagen de una camara de seguridad
     puede sacar de cuadro justo lo que hay que ver. */
  object-fit: contain;
  display: block;
  background: #000;
}

/* Imagen que llega comprimida horizontalmente (el modo "Lite" de un DVR entrega
   960x1080, un 1920x1080 con la mitad de las columnas). Se dibuja en una caja
   con la proporcion real, la mas grande que entre en la celda, y se estira el
   cuadro para llenarla.
   Con `object-fit: contain` no alcanza: respeta la proporcion del cuadro tal
   como llega, que es justo la equivocada. */
.cell.ana {
  container-type: size;
  display: grid;
  place-items: center;
}

.cell.ana video {
  width: min(100cqw, calc(100cqh * var(--aspect)));
  height: min(100cqh, calc(100cqw / var(--aspect)));
  object-fit: fill;
}

.overlay {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 9px;
  background: linear-gradient(transparent, rgba(0, 0, 0, .75));
  font-size: 12px;
  pointer-events: none;
}

.cell-name {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.cell-clock {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  color: var(--text);
}

.cell-state {
  max-width: 70%;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-left: auto;
  color: var(--muted);
  font-size: 11px;
  white-space: nowrap;
}

.cell[data-state="live"]  .cell-state { color: var(--ok); }
.cell[data-state="error"] .cell-state { color: var(--error); }
.cell[data-state="connecting"] .cell-state { color: var(--warn); }

/* Celda vacia cuando la pagina no se llena. */
.cell.empty { background: #0a0d11; }
.cell.empty video, .cell.empty .overlay { display: none; }

/* Una camara sola ocupa toda la pantalla: ahi si conviene el main stream. */
.grid.single { --cols: 1; }

@media (max-width: 720px) {
  /* En un telefono, mas de dos columnas no deja ver nada util. */
  .grid { grid-template-columns: repeat(min(var(--cols), 2), 1fr); }
  .brand, .user { display: none; }
}

/* ── Administracion de equipos ───────────────────────────────────── */

.admin {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: grid;
  grid-template-rows: var(--bar-height) 1fr;
  background: var(--bg);
}

.admin-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.admin-bar button {
  padding: 5px 11px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}

.admin-bar button:hover { background: #1d232c; }

.admin-body { overflow: auto; padding: 16px; }

/* Configuracion global de la superposicion de hora — no es un equipo, va
   aparte de la tabla, arriba de ella. */
.clock-settings {
  display: grid;
  gap: 10px;
  max-width: 480px;
}

.clock-settings h3 { margin: 0; font-size: 13px; color: var(--text); }

.clock-settings label {
  display: grid;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}

.clock-settings input,
.clock-settings select {
  padding: 7px 9px;
  background: #0d1117;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  font-size: 13px;
}

.clock-settings small { color: #5f6a77; font-size: 11px; }
.clock-settings .row { display: flex; align-items: center; gap: 10px; }

.clock-settings .check {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text);
  font-size: 13px;
}
.clock-settings .check input { width: auto; }

.clock-settings button {
  padding: 6px 12px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}
.clock-settings button:hover { background: #1d232c; }

.clock-status { font-size: 12px; color: var(--muted); }
.clock-status.bad { color: var(--error); }
.clock-status.good { color: var(--ok); }

.devices {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.devices th {
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-weight: 500;
  text-align: left;
}

.devices td {
  padding: 8px 10px;
  border-bottom: 1px solid #1b2129;
}

.devices tr:hover td { background: #131920; }

.devices .actions { text-align: right; white-space: nowrap; }

.devices .actions button {
  margin-left: 6px;
  padding: 3px 9px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 5px;
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
}

.devices .actions button.danger { color: var(--error); border-color: #45262a; }
.devices .actions button:hover { background: #1d232c; }

.pill {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
}

.pill.on  { background: #12301c; color: var(--ok); }
.pill.off { background: #2a2118; color: var(--warn); }

.admin-message { color: var(--muted); font-size: 13px; min-height: 18px; }
.admin-message.bad { color: var(--error); }
.admin-message.good { color: var(--ok); }

/* Formulario de alta y edicion. */
.device-form {
  position: absolute;
  top: var(--bar-height);
  right: 0;
  bottom: 0;
  width: min(440px, 100vw);
  overflow: auto;
  display: grid;
  align-content: start;
  gap: 12px;
  padding: 20px;
  background: var(--panel);
  border-left: 1px solid var(--line);
}

.device-form h2 { margin: 0 0 4px; font-size: 16px; }

.device-form label {
  display: grid;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}

.device-form input,
.device-form select {
  padding: 8px 10px;
  background: #0d1117;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  font-size: 14px;
}
/* Lo que no se puede cambiar (el identificador al editar) no debe parecer
   editable: apagado, sin borde de campo y sin el resaltado del foco. */
.device-form input[readonly] {
  background: transparent;
  border-color: transparent;
  padding-left: 0;
  color: var(--muted);
  cursor: default;
}
.device-form input[readonly]:focus,
.device-form input[readonly]:focus-visible { outline: none; border-color: transparent; box-shadow: none; }

.device-form small { color: #5f6a77; font-size: 11px; }
.device-form .row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.device-form .row .narrow { max-width: 110px; }

.device-form .check {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text);
  font-size: 13px;
}

.device-form .check input { width: auto; }

/* Excepciones de proporcion por canal: una grilla compacta, no una fila por
   canal como el resto del formulario — con hasta 56 canales, una fila cada
   una haria el panel interminable. */
.channel-aspect-rows {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 6px;
}

.channel-aspect-rows .chrow {
  display: grid;
  gap: 2px;
}

.channel-aspect-rows .chrow span {
  font-size: 10px;
  color: var(--muted);
}

.channel-aspect-rows select {
  padding: 4px 6px;
  font-size: 11px;
}

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}

.form-actions button {
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}

.form-actions button[type="submit"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}

/* Administracion de usuarios: asignacion de camaras. Una casilla por camara,
   agrupadas por equipo, porque con decenas de camaras una lista plana no se usa. */
#user-cameras-box { display: grid; gap: 8px; }
#user-cameras-box h3 { margin: 0; font-size: 13px; color: var(--text); }
#user-cameras-box[hidden] { display: none; }

.cam-acl {
  display: grid;
  gap: 10px;
  max-height: 340px;
  overflow: auto;
  padding: 8px;
  background: #0d1117;
  border: 1px solid var(--line);
  border-radius: 6px;
}

.cam-acl .grp-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--muted);
}

.cam-acl .grp-head button {
  padding: 1px 7px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 5px;
  color: var(--text);
  font-size: 11px;
  cursor: pointer;
}

.cam-acl label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text);
}

.cam-acl label input { width: auto; padding: 0; }
.cam-acl .grp-items { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 3px 10px; }
.cam-acl [hidden] { display: none; }

/* Tuerca de configuracion en la barra: solo el icono. */
.bar .icon-btn { display: inline-grid; place-items: center; padding: 4px 7px; }
.bar .icon-btn svg { display: block; }

/* Pantalla de configuracion: menu lateral + la seccion elegida. */
.config-layout {
  display: grid;
  grid-template-columns: 190px 1fr;
  min-height: 0;
}

.config-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 8px;
  background: var(--panel);
  border-right: 1px solid var(--line);
}

.config-nav button {
  padding: 9px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--muted);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

.config-nav button:hover { background: #1d232c; color: var(--text); }
.config-nav button.active { background: #1d232c; border-color: var(--line); color: var(--text); font-weight: 600; }

.config-pane[hidden] { display: none; }

.pane-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}

.pane-head h2 { margin: 0; font-size: 16px; }

.pane-head button {
  padding: 5px 11px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}

.pane-head button:hover { background: #1d232c; }

/* En pantallas angostas el menu pasa arriba, en fila. */
@media (max-width: 700px) {
  .config-layout { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .config-nav { flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--line); }
  .config-nav button { white-space: nowrap; }
}

/* Limites: uso actual y capacidad, debajo del formulario. */
.lim-usage { display: grid; gap: 6px; margin-top: 6px; font-size: 12px; color: var(--muted); }
.lim-usage p { margin: 0; }
.lim-usage .warn { color: var(--warn); }
.rec-purge { align-items: flex-end; }
.rec-purge button.danger { color: var(--error); border-color: #45262a; }
.rec-purge button.danger:disabled { opacity: .5; cursor: not-allowed; }

/* Version instalada, en la barra junto a la tuerca. */
.app-version { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }

/* Texto explicativo dentro de una seccion de configuracion. */
.pane-note { margin: 0; font-size: 12px; color: var(--muted); line-height: 1.5; }
.pane-note strong { color: var(--text); }

/* ── Grabaciones ─────────────────────────────────────────────────── */
.playback .pb-title { color: var(--muted); font-size: 13px; }
.pb-layout { display: grid; grid-template-columns: 240px 1fr; min-height: 0; }
.pb-side {
  display: flex; flex-direction: column; gap: 10px; padding: 12px;
  background: var(--panel); border-right: 1px solid var(--line); min-height: 0;
}
.pb-side input {
  padding: 7px 9px; background: #0d1117; border: 1px solid var(--line);
  border-radius: 6px; color: var(--text); font-size: 13px;
}
.pb-cameras { display: flex; flex-direction: column; gap: 2px; overflow: auto; flex: 1; min-height: 120px; }
.pb-cameras button, .pb-cal-head button, .pb-controls button, .pb-tl-head button, .pb-goto button {
  padding: 5px 9px; background: transparent; border: 1px solid var(--line);
  border-radius: 6px; color: var(--text); font-size: 12px; cursor: pointer;
}
.pb-cameras button { text-align: left; border-color: transparent; color: var(--muted); }
.pb-cameras button:hover { background: #1d232c; color: var(--text); }
.pb-cameras button.active { background: #1d232c; border-color: var(--line); color: var(--text); font-weight: 600; }
.pb-cal-head { display: flex; align-items: center; justify-content: space-between; font-size: 13px; }
.pb-calendar { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.pb-calendar .dow { font-size: 10px; color: var(--muted); text-align: center; }
.pb-calendar button {
  padding: 5px 0; background: transparent; border: 1px solid transparent; border-radius: 5px;
  color: #4b5563; font-size: 12px;
}
.pb-calendar button.has { color: var(--text); background: #16263d; cursor: pointer; }
.pb-calendar button.has:hover { border-color: var(--accent); }
.pb-calendar button.active { background: var(--accent); color: #fff; font-weight: 600; }

.pb-main { display: grid; grid-template-rows: 1fr auto auto auto auto; gap: 8px; padding: 12px; min-height: 0; }
.pb-stage { position: relative; background: #000; border-radius: 6px; min-height: 0; overflow: hidden; }
.pb-stage video { width: 100%; height: 100%; object-fit: contain; display: block; }
.pb-clock {
  position: absolute; left: 12px; bottom: 10px; padding: 3px 9px; border-radius: 5px;
  background: rgba(0, 0, 0, .65); color: #fff; font: 600 18px/1.3 ui-monospace, monospace;
}
.pb-controls { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pb-controls button.primary { background: var(--accent); border-color: var(--accent); color: #fff; min-width: 96px; }
.pb-speeds { display: inline-flex; gap: 3px; margin-left: 8px; }
.pb-speeds button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.pb-goto { display: inline-flex; gap: 4px; margin-left: auto; }
.pb-goto input {
  width: 90px; padding: 5px 8px; background: #0d1117; border: 1px solid var(--line);
  border-radius: 6px; color: var(--text); font: 13px ui-monospace, monospace;
}
.pb-tl-head { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); }
.pb-hover { font-family: ui-monospace, monospace; color: var(--text); }
.pb-status { font-size: 12px; }
.pb-status.bad { color: var(--error); }
.pb-timeline { width: 100%; height: 64px; background: #0d1117; border: 1px solid var(--line); border-radius: 6px; cursor: pointer; }
@media (max-width: 800px) {
  .pb-layout { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .pb-cameras { max-height: 140px; }
}

/* Configuracion -> Grabacion */
.pane-sub { margin: 22px 0 6px; font-size: 14px; }
.rec-cams { max-height: none; }
.rec-items { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 4px 14px; }
.rec-items label { display: grid; grid-template-columns: auto 1fr auto 70px; align-items: center; gap: 6px; }
.rec-items select { padding: 2px 4px; background: #0d1117; border: 1px solid var(--line); border-radius: 5px; color: var(--text); font-size: 11px; }
.rec-state { font-size: 10px; color: var(--muted); }
.rec-state.grabando { color: var(--ok); }
.rec-state.error { color: var(--error); }
.rec-cams-actions { margin-top: 10px; display: flex; gap: 10px; align-items: center; }
.rec-cams-actions button { padding: 6px 12px; background: var(--accent); border: 0; border-radius: 6px; color: #fff; cursor: pointer; }

/* ── Login: logo, ojito y pie ───────────────────────────────────── */
.login { position: relative; }
.login-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.login-brand img { display: block; }
.logo-text { font-size: 21px; font-weight: 800; letter-spacing: .5px; color: var(--text); }
.logo-text span, .brand-name span { color: var(--accent); font-weight: 600; }
.logo-sub { font-size: 12px; color: var(--muted); }
.brand { display: inline-flex; align-items: center; gap: 7px; }
.brand img { display: block; }

.pw-field { position: relative; display: grid; }
.pw-field input { padding-right: 40px; }
.pw-eye {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center; width: 32px; height: 32px; padding: 0;
  background: transparent; border: 0; border-radius: 5px; color: var(--muted); cursor: pointer;
}
.pw-eye:hover { color: var(--text); background: #1d232c; }
.pw-eye .pw-slash { display: none; }
.pw-eye.on .pw-slash { display: inline; }
.pw-eye.on { color: var(--accent); }

.login-footer {
  position: fixed; left: 0; right: 0; bottom: 0;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px 8px;
  padding: 10px 16px; border-top: 1px solid var(--line); background: var(--panel);
  color: var(--muted); font-size: 12px; text-align: center;
}
.login-footer strong { color: var(--text); font-weight: 600; }
.login-footer a { color: var(--muted); text-decoration: none; }
.login-footer a:hover { color: var(--text); }
.login-footer .sep { opacity: .5; }
@media (max-width: 600px) { .login-footer .sep { display: none; } .login-footer { flex-direction: column; } }

.pb-export { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pb-export button {
  padding: 5px 10px; background: transparent; border: 1px solid var(--line);
  border-radius: 6px; color: var(--text); font-size: 12px; cursor: pointer;
}
.pb-export button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.pb-export button:disabled { opacity: .4; cursor: default; }
.pb-range { font-size: 12px; color: var(--muted); font-family: ui-monospace, monospace; }
.pb-range.bad { color: var(--error); }

/* Grabaciones: la misma correccion de proporcion que las celdas del vivo. */
.pb-stage.ana { container-type: size; display: grid; place-items: center; }
.pb-stage.ana video {
  width: min(100cqw, calc(100cqh * var(--aspect)));
  height: min(100cqh, calc(100cqw / var(--aspect)));
  object-fit: fill;
}

/* Grabaciones: punto rojo en las camaras que estan grabando ahora. */
.pb-cameras button { display: flex; align-items: center; gap: 7px; }
.pb-cameras button::after {
  content: ''; flex: none; width: 8px; height: 8px; margin-left: auto; border-radius: 50%;
  background: transparent;
}
.pb-cameras button.rec::after {
  background: #ef4444; box-shadow: 0 0 0 3px rgba(239, 68, 68, .18);
  animation: rec-pulse 2s ease-in-out infinite;
}
@keyframes rec-pulse { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .pb-cameras button.rec::after { animation: none; } }

/* Trabajando: una rueda que gira y los segundos que pasan. Con menos
   movimiento pedido, la rueda queda quieta pero el contador sigue. */
.busy { display: inline-flex; align-items: center; gap: .5em; }
.busy::before {
  content: ''; width: 1em; height: 1em; flex: none; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent;
  animation: busy-spin .8s linear infinite;
}
@keyframes busy-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .busy::before { animation: none; opacity: .6; } }
