/* ---- indicadores del modal ---- */
.sigbar { flex: 1; height: 6px; border-radius: 1px; background: var(--surface-2); overflow: hidden; }
.sigbar-fill { height: 100%; border-radius: 1px; }
.sigbar-pct { font-size: 12.5px; color: var(--muted); font-weight: 500; min-width: 54px; text-align: right; font-variant-numeric: tabular-nums; }
.gauge { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.gauge .sig-lbl { color: var(--muted); }
.gauge .sigbar { max-width: 150px; }
.wifi-ind, .sas-ind { display: flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 500; color: var(--txt); }
/* Los puntos que arma ble.js quedan ocultos: el icono de la linea los reemplaza. */
.wifi-ind .wifi-dot, .sas-ind .sas-dot { display: none; }
.wifi-ind.wifi-off, .sas-ind.sas-off { color: var(--txt); }
.wifi-ind.wifi-desc, .sas-ind.sas-desc { color: var(--muted); }

/* ---- modal (bottom-sheet en mobile, centrado en desktop) ---- */
.modal { position: fixed; inset: 0; background: var(--overlay); display: grid; place-items: end center; z-index: 20; }
.modal-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius) var(--radius) 0 0; width: min(560px, 100%);
  padding: 18px; max-height: 88vh; overflow: auto;
  box-shadow: var(--shadow-float);
  padding-bottom: max(18px, env(safe-area-inset-bottom));
}
@media (min-width: 620px) {
  .modal { place-items: center; }
  .modal-card { border-radius: var(--radius); padding: 22px; }
}
/* Identidad de la maquina: UID con la placa al lado, modelo en negrita y
   ubicacion en tenue. Solo el renglon del UID comparte ancho con los botones;
   modelo y ubicacion usan todo el ancho, asi un modelo largo no se recorta. */
.modal-head {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start;
  column-gap: 10px; margin-bottom: 4px;
}
.modal-ident { display: contents; }
.modal-head-acciones { grid-column: 2; grid-row: 1; }
.modal-maquina, .modal-ubicacion { grid-column: 1 / -1; }
#modal-title, .dialog-title { font-family: var(--font-display); font-weight: 650; font-size: 18px; letter-spacing: .01em; }
/* Si UID y placa no entran al lado de los botones, la placa baja: el UID no se recorta. */
.modal-titulo {
  grid-column: 1; grid-row: 1; display: flex; flex-wrap: wrap; align-items: baseline;
  column-gap: 8px; row-gap: 0; min-width: 0; padding-top: 4px;
}
#modal-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 22px; line-height: 1.25; }
.modal-placa {
  flex-shrink: 0; color: var(--muted); font-size: 13px; font-weight: 500;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: .02em;
}
.modal-maquina { display: flex; align-items: center; gap: 2px; min-width: 0; font-size: 16px; font-weight: 600; line-height: 1.35; }
#modal-modelo { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* El lapiz conserva sus 44px tactiles sin agrandar el renglon del modelo. */
.modal-maquina .btn-icon { margin: -8px 0; color: var(--muted); }
.modal-ubicacion { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 14.5px; color: var(--muted); }
.modal-ubicacion .ico { width: 16px; height: 16px; flex-shrink: 0; }
#modal-ubicacion-texto { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.modal-head-acciones { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.modal-head .btn-ghost { border-color: transparent; background: transparent; min-width: 44px; padding: 10px; }
.modal-head .btn-ghost:hover { background: var(--surface-2); }
/* Resetear es lo que el operador busca cuando la carga queda bloqueada por una
   puerta o un tilt: borde grueso en color de texto para que se encuentre de un
   vistazo, sin relleno para no competir con Cargar. */
.modal-head .btn-reset-estado {
  min-width: 0; min-height: 44px; padding: 8px 14px; border: 2px solid var(--txt);
  color: var(--txt); font-size: 15px; font-weight: 600; gap: 8px;
}
.btn-reset-estado .ico { width: 19px; height: 19px; }
/* Operador: Resetear va bajo la carga, a todo el ancho, con el mismo borde grueso. */
.modal-pie .btn-reset-estado {
  width: 100%; min-height: 48px; margin-top: 10px; border: 2px solid var(--txt);
  background: transparent; color: var(--txt); font-size: 16px; font-weight: 600; gap: 8px;
}
/* Reconectar: aparece cuando el portal solto la placa; va arriba de la carga, a
   todo el ancho, porque hasta reconectar no se puede hacer otra cosa. */
.btn-reconectar { width: 100%; min-height: 48px; margin: 0 0 12px; font-size: 16px; font-weight: 600; gap: 8px; }
.btn-reconectar .ico { width: 19px; height: 19px; }
/* Log plegado del operador: el rotulo dice si abre o cierra. */
.actividad-ocultar { display: none; }
.actividad[open] .actividad-ver { display: none; }
.actividad[open] .actividad-ocultar { display: inline; }
.actividad[open] > summary { color: var(--txt); }
.modal-status { color: var(--muted); font-size: 14.5px; font-weight: 600; }
.modal-status.ok { color: var(--ok-txt); }
.modal-status.err { color: var(--err-txt); }
.modal-status.busy { color: var(--txt); }
.modal-status.indet { color: var(--warn-txt); }

/* Tablero del modal: una linea por fuente de estado (operación, servicio, SAS,
   Wi-Fi), cada una con su icono. Cada linea trae sus iconos posibles y el CSS
   muestra el que corresponde a la clase que ble.js ya pone, asi el icono nunca
   contradice al texto. */
.tablero { margin: 12px 0 18px; padding: 14px 0; border-block: 1px solid var(--line); }
/* Operador: el resultado va solo arriba de la carga, sin filetes, y el enlace
   (SAS, Wi-Fi, senal) debajo, cerrado por un filete. Antes de conectar el enlace no
   tiene lineas visibles: se oculta en vez de dejar un filete suelto. */
.tablero-resultado { margin: 12px 0; padding: 0; border: 0; }
.tablero-enlace { margin: 0 0 4px; padding: 0 0 12px; border-top: 0; }
.tablero-enlace:not(:has(.tl > div:not([hidden]))) { display: none; }
.tablero-lineas { display: grid; gap: 8px; min-width: 0; }
.tl { display: flex; align-items: flex-start; gap: 12px; min-width: 0; }
.tl:has(> [hidden]) { display: none; }
.tl > .ico { display: none; width: 20px; height: 20px; flex: 0 0 20px; color: var(--muted); }
/* El texto arranca a la altura del icono (no centrado en el alto reservado). */
.tl > div { flex: 1; min-width: 0; min-height: 20px; display: flex; align-items: flex-start; line-height: 20px; }
.tl-op > .modal-status { line-height: 24px; }
.tl-gauge { padding-left: 32px; }
.tl-gauge > .gauge { align-items: center; }
/* Operación: el icono grande dice si la carga entró. Desde que se toca Cargar se
   reservan dos renglones para su texto (tres en el celular), asi el modal no salta
   entre "cargando", OK, FALLÓ e INDETERMINADO. Antes de cargar no se reserva: con
   "Conectado" solo quedaba un hueco sobre el tablero. */
.tl-op > .ico { width: 24px; height: 24px; flex-basis: 24px; }
.tl-op > .modal-status { font-size: 16px; }
.modal.carga-activa .tl-op > .modal-status { min-height: 48px; }
.tl-op:not(:has(.ok, .err, .busy, .indet)) > .i-def { display: block; }
.tl-op:has(.ok) > .i-ok { display: block; color: var(--ok); }
.tl-op:has(.err) > .i-err { display: block; color: var(--err); }
.tl-op:has(.busy) > .i-busy { display: block; color: var(--accent); animation: girar 1s linear infinite; }
.tl-op:has(.indet) > .i-indet { display: block; color: var(--warn); }
.tl-estado:has(.estado-reparacion) > .i-rep { display: block; color: var(--warn); }
.tl-estado:has(.estado-retirado) > .i-ret { display: block; }
.tl-sas:not(:has(.sas-off)) > .i-def, .tl-wifi:not(:has(.wifi-off)) > .i-def { display: block; }
.tl-sas:has(.sas-off) > .i-off { display: block; color: var(--err); }
.tl-wifi:has(.wifi-off) > .i-off { display: block; color: var(--warn); }

.modal-actions { display: flex; gap: 10px; margin-bottom: 10px; }
.modal-actions.secondary { flex-wrap: wrap; }
.modal-actions.secondary .btn { flex: 1; font-size: 13.5px; }
.acciones-menu { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px; margin: 10px 0 4px; }
.mas-acciones { margin: 12px 0 0; }
.mas-acciones > summary {
  display: flex; align-items: center; gap: 8px; min-height: 44px; cursor: pointer;
  font-size: 14px; font-weight: 600; color: var(--muted); list-style: none;
}
.mas-acciones > summary::-webkit-details-marker { display: none; }
.mas-acciones > summary::before {
  content: ""; width: 7px; height: 7px; border-right: 1.75px solid currentColor; border-bottom: 1.75px solid currentColor;
  transform: rotate(-45deg); transition: transform .15s ease-out;
}
.mas-acciones[open] > summary::before { transform: rotate(45deg); }
.mas-acciones > summary:hover { color: var(--txt); }
.mas-acciones > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
/* Bloque de carga antes del log: separado del estado y de las acciones de
   mantenimiento para que el monto sea facil de revisar antes de enviarlo. */
.modal-pie {
  margin: 0 0 14px; padding: 12px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
@media (min-width: 620px) { .modal-pie { padding: 14px; } }
.modal-pie .modal-actions { margin-bottom: 0; }
/* El monto formateado es lo mas grande del modal: es lo que no se puede leer mal. */
.monto-vista {
  min-height: 42px; margin: 0 0 8px; font-size: 32px; font-weight: 600; letter-spacing: -.02em;
  line-height: 1.3; font-variant-numeric: tabular-nums; color: var(--txt);
}
.monto-vista:empty::before { content: "Elegí o escribí un monto"; font-size: 15px; font-weight: 500; color: var(--muted); letter-spacing: 0; }
.acciones-menu .btn { font-size: 13.5px; font-weight: 500; min-height: 42px; }
/* ---- montos frecuentes (chips arriba del campo de carga) ---- */
/* Cuatro en una fila entran en un celular angosto: el texto va corto ($300K) y el
   alto se mantiene en los 44px tactiles que usa el resto de los botones. */
.montos-rapidos { display: flex; gap: 8px; margin-bottom: 10px; }
.montos-rapidos .btn-monto {
  flex: 1 1 0; min-width: 0; padding: 10px 4px; font-size: 15px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.montos-rapidos .btn-monto:hover:not(:disabled) { border-color: var(--accent); }
/* El elegido queda marcado para leer de un vistazo que monto va a salir. */
.montos-rapidos .btn-monto.elegido {
  color: var(--accent-txt); background: var(--accent-soft); border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
#carga-row { align-items: stretch; }
#monto, .dialog-input {
  flex: 1; padding: 11px 12px; border-radius: var(--radius-sm); border: 1px solid var(--line-strong);
  background: var(--surface); color: var(--txt); font-size: 16px; width: 100%;
}
#monto {
  font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums;
  padding: 8px 14px; min-height: 52px;
}
#btn-cargar { min-width: 120px; min-height: 52px; font-size: 16px; }
#monto:focus, .dialog-input:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); box-shadow: none; }
#monto:disabled {
  background: var(--surface-2); color: var(--muted); cursor: not-allowed;
}
#monto::placeholder { font-size: 16px; font-weight: 400; color: var(--muted); }
.dialog-options {
  width: 100%; max-width: 100%; max-height: min(42vh, 280px); overflow-y: auto; overflow-x: hidden;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm); background: var(--surface);
  -webkit-overflow-scrolling: touch;
}
.dialog-options:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); box-shadow: none; }
.dialog-wait-overlay { cursor: wait; }
.dialog-wait {
  width: min(90vw, 390px); display: flex; align-items: center; gap: 16px;
  padding: 22px; cursor: wait; align-self: center; justify-self: center;
  border-radius: var(--radius);
}
.dialog-wait-copy { min-width: 0; }
.dialog-wait .dialog-title { display: block; font-weight: 600; margin-bottom: 4px; }
.dialog-wait .dialog-msg { margin: 0; color: var(--muted); line-height: 1.45; }
.dialog-spinner {
  width: 28px; height: 28px; flex: 0 0 28px; border-radius: 50%;
  border: 2.5px solid var(--line); border-top-color: var(--accent);
  animation: dialog-spin .8s linear infinite;
}
@keyframes dialog-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .dialog-spinner { animation-duration: 1.6s; }
}
.dialog-option {
  display: flex; align-items: center; gap: 8px; width: 100%; max-width: 100%; min-width: 0;
  padding: 10px 12px; border: 0; border-bottom: 1px solid var(--line); background: transparent;
  color: var(--txt); cursor: pointer; text-align: left; font: inherit; min-height: 44px;
}
.dialog-option:last-child { border-bottom: 0; }
.dialog-option:hover { background: var(--surface-2); }
.dialog-option.selected { background: var(--accent-soft); box-shadow: inset 2px 0 0 var(--accent); }
.dialog-option-label { min-width: 0; flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }
.dialog-option-badge {
  flex: 0 0 auto; padding: 2px 7px; border-radius: 4px;
  border: 1px solid color-mix(in srgb, var(--ok) 45%, var(--line)); color: var(--ok-txt);
  font-size: 11.5px; font-weight: 600;
}
.dialog-option-meta { flex: 0 1 auto; max-width: 62%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: 12px; }
.wifi-network-dialog {
  width: min(92vw, 520px); max-height: min(84vh, 620px);
  align-self: center; justify-self: center; border-radius: var(--radius);
}
/* Diálogo de pocas opciones cortas (elegir el estado del slot): a 560px queda un
   cartel enorme para dos palabras. El 100% mantiene la hoja inferior a lo ancho
   en el celular, que es como se opera; lo que se angosta es el escritorio. */
.dialog-angosto { width: min(380px, 100%); }
.dialog-input-wrap { position: relative; width: 100%; }
.dialog-input-wrap .dialog-input { padding-right: 50px; }
.dialog-eye {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 40px; height: 38px; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.dialog-eye:hover, .dialog-eye:focus-visible { background: var(--surface-2); color: var(--txt); outline: none; }
.modal-log {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px; font: 12px/1.55 var(--font-mono); color: var(--txt);
  height: calc(7 * 1.55em + 24px); max-height: calc(7 * 1.55em + 24px);
  white-space: pre-wrap; word-break: break-word; overflow-y: auto; overflow-x: hidden; margin: 6px 0 0;
  -webkit-overflow-scrolling: touch;
}
/* visor de log en Auditoría: más alto que el log en vivo del modal de carga */
.modal-log.tall { height: auto; max-height: 62vh; }

/* ---- diálogo genérico (reemplaza alert/confirm/prompt) ---- */
.dialog-msg { color: var(--muted); font-size: 14.5px; margin: 8px 0 16px; white-space: pre-line; }
.dialog-actions { margin-top: 4px; }
.dialog-actions .btn { flex: 1; }

/* ---- formulario de varios campos (ficha de la placa) ---- */
.dialog-form .dialog-content { margin: 10px 0 16px; }
.dialog-campos { display: grid; gap: 12px; }
.dialog-campo { display: grid; gap: 6px; }
.dialog-campo-lbl { font-size: 13px; font-weight: 500; color: var(--muted); }
.dialog-campo-error { font-size: 12.5px; font-weight: 600; color: var(--err-txt); }
.dialog-input.invalido { border-color: var(--err); }
/* Campo que ya no se puede editar (UID/marca/modelo cargados): se lee y se copia,
   pero se ve claramente que no se toca. */
.dialog-input.solo-lectura {
  background: var(--surface-2); color: var(--muted); cursor: not-allowed;
}

/* El selector de informes conserva las acciones visibles al recorrer filtros largos. */
.dialog-excel {
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
  max-height: 90vh; overflow: hidden;
}
.dialog-excel .dialog-content { min-height: 0; overflow-y: auto; }
.excel-informes { display: grid; gap: 4px; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px 10px; }
.excel-informes legend { padding: 0 4px; font-size: 13px; font-weight: 600; color: var(--muted); }
.excel-opcion { display: flex; align-items: center; gap: 8px; min-height: 32px; font-size: 14px; }
.excel-opcion input { width: 18px; height: 18px; accent-color: var(--accent); }
.excel-fechas[hidden] { display: none; }

/* ---- detalle de telemetría Wi‑Fi ---- */
.wifi-data-dialog {
  width: min(720px, 100%); max-height: 92vh; overflow: hidden;
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
}
.wifi-data-dialog .dialog-content {
  min-height: 0; overflow-y: auto; margin: 12px -5px 0; padding: 0 5px 4px;
  scrollbar-gutter: stable;
}
.wifi-data-dialog .dialog-actions,
.esp-data-dialog .dialog-actions { justify-content: flex-end; margin: 12px 0 0; }
.wifi-data-dialog .dialog-actions .dlg-cancel,
.esp-data-dialog .dialog-actions .dlg-cancel {
  flex: 0 0 auto; min-height: 40px; padding: 8px 16px;
  border-color: var(--accent); background: var(--accent); color: var(--on-accent);
}
.wifi-data-dialog .dialog-actions .dlg-cancel:hover,
.esp-data-dialog .dialog-actions .dlg-cancel:hover { border-color: var(--accent-hover); background: var(--accent-hover); }
.wifi-data-view { display: grid; gap: 12px; }
.wifi-data-overview {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  padding: 14px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2);
}
.wifi-data-identity { display: grid; gap: 2px; min-width: 0; }
.wifi-data-name { color: var(--txt); font-size: 16px; font-weight: 600; overflow-wrap: anywhere; }
.wifi-data-id { color: var(--muted); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.wifi-data-statuses { display: flex; flex-wrap: wrap; gap: 6px; }
.wifi-data-status {
  display: inline-flex; align-items: center; gap: 7px; padding: 4px 9px;
  border-radius: 4px; border: 1px solid var(--line-strong); background: var(--surface);
  color: var(--txt); font-size: 12px; font-weight: 500; white-space: nowrap;
}
.wifi-data-status::before { content: ""; width: 8px; height: 8px; flex: 0 0 8px; border-radius: 50%; background: var(--line-strong); }
.wifi-data-status.is-ok::before { background: var(--ok); }
.wifi-data-status.is-warn::before { background: var(--warn); }
.wifi-data-status.is-error::before { background: var(--err); }
.wifi-data-status.is-muted { color: var(--muted); }
.wifi-data-section {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); overflow: hidden;
}
.wifi-data-section-title {
  margin: 0; padding: 10px 14px; border-bottom: 1px solid var(--line); background: var(--surface-2);
  color: var(--txt); font-size: 13px; font-weight: 600;
}
.wifi-data-section-body { padding: 12px 14px; }
.wifi-data-kv-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 18px; }
.wifi-data-kv { display: grid; gap: 2px; min-width: 0; }
.wifi-data-label { color: var(--muted); font-size: 12px; }
.wifi-data-value { color: var(--txt); font-size: 14px; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.wifi-data-machine-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
.wifi-data-machine-item {
  display: flex; align-items: center; justify-content: space-between; gap: 9px;
  min-width: 0; padding: 8px 10px; border-radius: var(--radius-sm); border: 1px solid var(--line); font-size: 12.5px;
}
.wifi-data-machine-name { min-width: 0; color: var(--muted); overflow-wrap: anywhere; }
.wifi-data-machine-state { flex: 0 0 auto; font-size: 12px; font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.wifi-data-machine-state::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--line-strong); }
.wifi-data-machine-item.is-normal .wifi-data-machine-state { color: var(--txt); }
.wifi-data-machine-item.is-normal .wifi-data-machine-state::before { background: var(--ok); }
.wifi-data-machine-item.is-alert { border-color: color-mix(in srgb, var(--err) 45%, var(--line)); }
.wifi-data-machine-item.is-alert .wifi-data-machine-state { color: var(--err-txt); }
.wifi-data-machine-item.is-alert .wifi-data-machine-state::before { background: var(--err); }
.wifi-data-machine-item.is-unknown .wifi-data-machine-state { color: var(--muted); }
.wifi-data-meter-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 6px; }
.wifi-data-meter {
  display: grid; gap: 3px; padding: 10px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--surface-2);
}
.wifi-data-meter-label { color: var(--muted); font-size: 11.5px; font-weight: 500; }
.wifi-data-meter-value { color: var(--txt); font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.wifi-data-events { display: grid; }
.wifi-data-event { display: grid; grid-template-columns: minmax(120px, auto) 1fr; gap: 12px; padding: 9px 0; }
.wifi-data-event + .wifi-data-event { border-top: 1px solid var(--line); }
.wifi-data-event-time { color: var(--muted); font-size: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.wifi-data-event-text { min-width: 0; color: var(--txt); font-size: 13px; overflow-wrap: anywhere; }
.wifi-data-empty { margin: 3px 0; color: var(--muted); font-size: 13px; }
@media (max-width: 520px) {
  .wifi-data-dialog { max-height: 94vh; }
  .wifi-data-overview { display: grid; }
  .wifi-data-kv-grid, .wifi-data-machine-grid { grid-template-columns: 1fr; }
  .wifi-data-event { grid-template-columns: 1fr; gap: 2px; }
}
