/* ══════════════════════════════════════════════════════════════════════════════
   responsive.css — capa de compatibilidad multiplataforma
   ══════════════════════════════════════════════════════════════════════════════

   QUE ES: una capa ADITIVA que se carga DESPUES de admin.css y monitoreo.css
   (y de login.css en la pantalla de acceso). No edita ni una sola regla de las
   existentes: solo las complementa donde faltaba cobertura.

   POR QUE ASI: admin.css y monitoreo.css suman ~280 KB con 31 media queries
   repartidas en 12 breakpoints distintos. Editarlas en sitio para arreglar el
   comportamiento movil obligaria a tocar cientos de reglas vivas, con riesgo
   real de romper el escritorio, que hoy funciona. Una capa al final consigue lo
   mismo y es REVERSIBLE AL 100%: se quita el <link> de admin.html / login.html
   y la plataforma vuelve exactamente al estado anterior.

   NO TOCA LA BASE DE DATOS NI NINGUN ENDPOINT. Es solo presentacion.

   Diagnostico que la motiva (medido el 23/08/2026 en el propio panel):
     · 123 de 123 campos de formulario por debajo de 16px  -> Safari iOS hace
       ZOOM al enfocar cualquiera de ellos. Es la causa de que en iPhone "no se
       vea igual que en Android".
     · 0 usos de safe-area-inset -> muescas y barra inferior del iPhone.
     · 139 de 154 objetivos tactiles por debajo de 44px (guia de Apple).
     · Rejillas con columnas fijas sin variante movil: recortaban hasta 186 px
       de contenido inalcanzable a 320 px de ancho.
     · backdrop-filter sin prefijo -webkit- en 10 sitios -> sin desenfoque en
       Safari < 18, con perdida de legibilidad sobre fondos translucidos.
     · Sin tope de ancho -> el layout se estiraba sin limite en 4K/ultrawide.

   ORDEN DE LAS SECCIONES (de lo global a lo especifico, para que la cascada
   quede predecible):
     1. Base multiplataforma
     2. Alturas de viewport modernas (dvh/svh)
     3. Safari iOS: el zoom al enfocar campos
     4. Safe-area: muesca, Dynamic Island y barra inferior
     5. Prefijos -webkit- que faltaban
     6. Rejillas de columna fija sin variante movil
     7. Tablas y contenido ancho
     8. Objetivos tactiles
     9. Pantallas grandes
   ══════════════════════════════════════════════════════════════════════════════ */


/* ══════════════════════════════════════════════════════════════════════════════
   1. BASE MULTIPLATAFORMA
   Reglas globales inocuas: no cambian ningun tamano ni color, solo evitan
   comportamientos por defecto que difieren entre navegadores.
   ══════════════════════════════════════════════════════════════════════════════ */

html {
    /* Safari iOS infla el texto por su cuenta al rotar a horizontal ("text
       autosizing"). Con 100% respeta el tamano que declara el CSS, que es lo
       que ya hace Chrome en Android. Sin esto, la misma pantalla se ve con
       tipografias distintas en iPhone y en Android. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    /* Quita el destello gris que Safari/Chrome moviles pintan al tocar.
       El :active y :hover propios de la plataforma siguen funcionando. */
    -webkit-tap-highlight-color: transparent;
}

/* Un codigo de equipo, un JID de WhatsApp o un correo largo no deben poder
   ensanchar su contenedor y desbordar la pantalla. */
body, td, th, p, span, label, div {
    overflow-wrap: break-word;
}

/* Ningun medio se sale de su caja, en ningun navegador. */
img, video, canvas, svg, model-viewer {
    max-width: 100%;
}

/* Firefox y Safari calculan distinto el ancho minimo de un item flex; sin esto
   un hijo con contenido ancho estira al padre y provoca scroll horizontal. */
@media (pointer: coarse), (max-width: 1100px) {
    .main, .main-content, .content-section {
        min-width: 0;
    }
}


/* ══════════════════════════════════════════════════════════════════════════════
   2. ALTURAS DE VIEWPORT MODERNAS
   En Safari iOS, 100vh mide la ventana SIN las barras del navegador: cualquier
   elemento con height:100vh queda mas alto que el area visible y su parte
   inferior cae detras de la barra de direcciones. dvh mide el area realmente
   visible y se reajusta al ocultarse las barras.
   Se declara vh primero como respaldo: los navegadores que no entienden dvh
   ignoran la segunda linea y conservan el comportamiento actual.
   ══════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 767px) {

    /* El drawer de navegacion. Con 100vh sus ultimas opciones (tema, cerrar
       sesion) quedaban tapadas por la barra inferior de Safari. */
    .sidebar {
        height: calc(100vh - 52px) !important;
        height: calc(100dvh - 52px) !important;
    }

    .mobile-nav-backdrop {
        height: calc(100vh - 52px);
        height: calc(100dvh - 52px);
    }
}

/* Modales a pantalla completa: mismo problema, el pie del dialogo (donde estan
   Guardar y Cancelar) quedaba fuera de alcance. */
@media (max-width: 900px) {
    .graficas-modal__dialog,
    .inc-modal,
    .setpoint-modal,
    .kpi-modal__dialog,
    .tab-modal {
        max-height: calc(100vh - 24px);
        max-height: calc(100dvh - 24px);
    }
}


/* ══════════════════════════════════════════════════════════════════════════════
   3. SAFARI iOS: EL ZOOM AL ENFOCAR CAMPOS
   ══════════════════════════════════════════════════════════════════════════════
   Safari en iPhone/iPad hace zoom automatico sobre cualquier campo con
   font-size < 16px, y NO vuelve a alejarse al salir. Resultado: el usuario
   toca un filtro y la pantalla se queda ampliada y descuadrada. Chrome en
   Android no hace esto, y de ahi que "no se vea igual".

   El panel usa una escala tipografica densa de escritorio: la raiz esta en
   16px pero el body baja a 11.2px y los campos heredan hasta 10.4px.

   La solucion NO es bloquear el zoom con maximum-scale=1 en el viewport: eso
   impide tambien el pinch-to-zoom y deja la plataforma inaccesible para quien
   necesita ampliar. Lo correcto es subir los campos a 16px, y solo en tactil.
   En movil 10.4px era ilegible de todos modos.

   Se usa !important porque varias reglas del bloque movil existente ya fijan
   font-size en estos mismos campos con la misma especificidad o mayor.

   EL CRITERIO ES EL PUNTERO, NO EL ANCHO. Con (max-width: 1024px) la regla NO
   coincidia en un iPad Pro en vertical, que mide exactamente 1024px: por el
   factor de pixel del dispositivo la consulta se evalua en 1024.x y queda
   fuera. Verificado en el navegador el 23/08/2026. (pointer: coarse) acierta
   en cualquier dispositivo tactil sea cual sea su resolucion, y el ancho de
   1100px se conserva como respaldo para ventanas de escritorio estrechas.
   ══════════════════════════════════════════════════════════════════════════════ */

@media (pointer: coarse), (max-width: 1100px) {

    /* SOLO LOS CONTROLES DE ENTRADA DE TEXTO. Corregido el 24/08/2026: la lista
       incluia <select> y los campos de fecha/hora, y no debia.
       Safari iOS hace zoom al enfocar un control que abre TECLADO y muestra
       CURSOR. Un <select> abre el selector de rueda y un input[type=date] abre
       el calendario: ni teclado ni cursor, y por tanto ningun zoom. Tenerlos
       aqui, y encima con !important, los clavaba en 16px sin necesidad y era la
       razon de que los selects y las fechas se vieran enormes en el telefono.
       Su tamano lo fija ahora mobile.css, a la escala del menu. */
    input[type="text"],
    input[type="password"],
    input[type="email"],
    input[type="number"],
    input[type="search"],
    input[type="tel"],
    input[type="url"],
    input[type="file"],
    input:not([type]),
    textarea {
        font-size: 16px !important;
        min-height: 44px;
        line-height: 1.3;
    }

    /* Los que no disparan zoom conservan area tactil, pero no tamano impuesto. */
    select,
    input[type="date"],
    input[type="time"],
    input[type="datetime-local"],
    input[type="month"] {
        min-height: 44px;
        line-height: 1.3;
    }

    /* Los campos de fecha y hora de iOS abren un selector nativo. Con
       appearance:none (que admin.css aplica a los campos de formulario) el
       control se colapsa y deja de mostrar la fecha elegida. Aqui se le
       devuelve su apariencia nativa solo en tactil. */
    input[type="date"],
    input[type="time"],
    input[type="datetime-local"],
    input[type="month"] {
        -webkit-appearance: none;
        appearance: none;
        /* iOS alinea estos campos arriba; centrarlos evita el recorte visual. */
        display: block;
        width: 100%;
        box-sizing: border-box;
    }

    /* Safari iOS ignora el padding vertical en <select> si no se le da altura
       explicita, y el texto queda pegado al borde. */
    select {
        background-image: none;
        padding-right: 28px;
    }

    /* El buscador del componente de seleccion (ss-search) es un input mas. */
    /* El buscador del widget si es entrada de texto real: se queda en 16px. */
    .ss-dropdown .ss-search,
    .ss-dropdown .ss-search input {
        font-size: 16px !important;
    }
}

/* Los campos del login tambien estaban a 14px: la primera pantalla que ve el
   usuario en el iPhone ya disparaba el zoom. */
@media (pointer: coarse), (max-width: 1100px) {
    .login-panel input,
    .login-form input,
    form input[name="usuario"],
    form input[name="password"] {
        font-size: 16px !important;
        min-height: 44px;
    }
}


/* ══════════════════════════════════════════════════════════════════════════════
   4. SAFE-AREA: MUESCA, DYNAMIC ISLAND Y BARRA INFERIOR
   ══════════════════════════════════════════════════════════════════════════════
   admin.html ahora declara viewport-fit=cover, que extiende la pagina de borde
   a borde (sin las franjas negras que Safari dibujaba antes). A cambio, hay que
   apartar el contenido de la muesca y de la barra de gestos con env().

   env(safe-area-inset-*) vale 0 en cualquier navegador o dispositivo sin
   muesca, asi que estas reglas son inertes fuera del iPhone: Android, escritorio
   y iPad sin muesca no cambian en nada.
   ══════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 767px) {

    /* Header fijo: crece hacia arriba lo que mida la muesca y empuja su
       contenido por debajo de ella. */
    .mobile-header {
        height: calc(52px + env(safe-area-inset-top));
        padding-top: env(safe-area-inset-top);
        padding-left: calc(16px + env(safe-area-inset-left));
        padding-right: calc(16px + env(safe-area-inset-right));
    }

    /* El contenido se separa del header ya crecido. */
    .main {
        padding-top: calc(52px + env(safe-area-inset-top)) !important;
    }

    /* El drawer arranca bajo el header y termina sobre la barra de gestos. */
    .sidebar {
        top: calc(52px + env(safe-area-inset-top)) !important;
        height: calc(100dvh - 52px - env(safe-area-inset-top)) !important;
        padding-bottom: env(safe-area-inset-bottom);
    }

    .mobile-nav-backdrop {
        top: calc(52px + env(safe-area-inset-top));
    }

    /* En horizontal la muesca queda a un lado: sin esto el texto del contenido
       se mete debajo de ella. */
    .main-content {
        padding-left: max(14px, env(safe-area-inset-left));
        padding-right: max(14px, env(safe-area-inset-right));
        padding-bottom: max(24px, env(safe-area-inset-bottom));
    }
}

/* Modales: sus botones de accion no deben caer bajo la barra de gestos. */
@media (max-width: 900px) {
    .graficas-modal__dialog,
    .inc-modal,
    .setpoint-modal,
    .kpi-modal__dialog,
    .tab-modal,
    .confirm-dialog,
    .profile-modal__dialog {
        margin-bottom: env(safe-area-inset-bottom);
    }
}


/* ══════════════════════════════════════════════════════════════════════════════
   5. PREFIJOS -webkit- QUE FALTABAN
   Safari solo aplico backdrop-filter sin prefijo desde la version 18. En las
   anteriores (y en muchos iPhone en uso) el desenfoque simplemente no se
   dibujaba: donde el diseno cuenta con el para separar una capa translucida del
   fondo, el texto quedaba encima de lo que hubiera detras.
   Se repiten aqui los 10 sitios que no lo llevaban.
   ══════════════════════════════════════════════════════════════════════════════ */

.topbar,
.sidebar,
.graficas-modal,
.nav-flyout,
.confirm-overlay,
.inc-modal-overlay,
.setpoint-modal-overlay,
.tab-modal-overlay,
.tab-confirm-overlay,
.kpi-modal {
    -webkit-backdrop-filter: inherit;
}

/* inherit no sirve cuando la propiedad se declara en la propia regla original,
   asi que los casos con valor conocido se repiten explicitamente. */
.graficas-modal      { -webkit-backdrop-filter: blur(2px); }
.confirm-overlay     { -webkit-backdrop-filter: blur(2px); }
.nav-flyout          { -webkit-backdrop-filter: blur(10px); }

/* Scroll con inercia en todos los contenedores desplazables de movil, no solo
   en los dos que ya lo tenian. */
@media (pointer: coarse), (max-width: 1100px) {
    .table-container,
    .table-container--parametros,
    .registros-wrapper,
    .tabla-scroll,
    .dash-panel-left,
    [class*="-wrap"] {
        -webkit-overflow-scrolling: touch;
    }
}


/* ══════════════════════════════════════════════════════════════════════════════
   6. REJILLAS DE COLUMNA FIJA SIN VARIANTE MOVIL
   ══════════════════════════════════════════════════════════════════════════════
   Estas rejillas declaran una columna en px que no cabe en un telefono. Como no
   tenian regla en ninguna media query por debajo de 900px, el navegador
   mantenia la columna a su ancho fijo y el resto del contenido se salia de la
   pantalla. Con overflow-x:hidden en el body, lo que se salia no quedaba
   desplazable: quedaba RECORTADO E INALCANZABLE.

   Medido a 320 px de ancho antes del arreglo:
     .dash-body     -> 186 px de contenido fuera de pantalla
     .ctr-mid-grid  -> columna de 230 px sin sitio
     .ctr-ch-body   -> columna de 155 px sin sitio

   Todas pasan a una sola columna. En escritorio no cambia nada: estas reglas
   viven dentro de media queries.
   ══════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {

    /* Dashboard de ambientes (sensores LoRaWAN): era 360px + 1fr. */
    .dash-body {
        grid-template-columns: 1fr;
        height: auto;
        min-height: 0;
    }

    .dash-panel-chart,
    .dash-panel-map {
        min-height: 260px;
    }

    /* Tablero de control: era 1fr 1fr 230px, y dentro 155px 1fr. */
    .ctr-mid-grid,
    .ctr-ch-body {
        grid-template-columns: 1fr;
    }

    /* Auditoria: solo tenia variante a 1100px para la rejilla exterior. */
    .aud-grid {
        grid-template-columns: 1fr;
    }

    /* Informes: era 120px + minmax(170px,1fr) x2 = 580px minimos. */
    .informes-controls-grid,
    .informes-controls-grid--client {
        grid-template-columns: 1fr;
    }

    /* Tendencias: era minmax(0,1fr) + 280px. */
    .tend-layout {
        grid-template-columns: 1fr;
    }

    /* Ficha de equipo: era 1fr + 320px. */
    .equipo-top-layout {
        grid-template-columns: 1fr;
    }

    /* Programacion ON/OFF: era 140px 1fr 1fr. */
    .prog-onoff-head {
        display: none;   /* la cabecera de rejilla no aporta apilada */
    }

    .prog-onoff-row {
        grid-template-columns: 1fr;
        gap: 6px;
    }
}

/* Rejillas declaradas con style en linea en admin.html. Un estilo en linea gana
   a cualquier hoja externa, asi que aqui hace falta !important. Se corrigen desde
   la capa para no tener que editar el marcado.
   #accesos-checks era repeat(2, minmax(180px,1fr)) = 370px minimos con el gap:
   a 320px de ancho recortaba 63px de la segunda columna. */
@media (max-width: 560px) {
    #accesos-checks {
        grid-template-columns: 1fr !important;
    }
}

/* Cada ficha lleva DATOS (2 columnas) + un visor 3D fijo. Por debajo de ~560px
   de tarjeta la columna de datos se estrangula y las etiquetas largas ("CAPACIDAD
   ENFRIAMIENTO") se parten letra a letra. Se sube el minimo a 560px para que solo
   entren las tarjetas que caben COMODAS: 2 por fila en un monitor normal, 1 en
   laptop. `min(560px, 100%)` conserva ese ancho en escritorio pero deja que la
   tarjeta se encoja en moviles sin desbordar. Sin media query: es correcto en
   todos los tamanos. */
.info-general-cards {
    grid-template-columns: repeat(auto-fit, minmax(min(560px, 100%), 1fr));
}

.graficas-section-grid,
.monitoreo-cards-grid,
[class*="cards-grid"] {
    grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
}


/* ══════════════════════════════════════════════════════════════════════════════
   7. TABLAS Y CONTENIDO ANCHO
   Una tabla de registros con 12 columnas no cabe en un telefono y no debe
   intentarlo: lo correcto es que se desplace DENTRO de su contenedor, sin
   arrastrar la pagina entera. La mayoria ya tenia envoltorio; estas son las que
   no, mas una red de seguridad para las que genera el JS.
   ══════════════════════════════════════════════════════════════════════════════ */

@media (pointer: coarse), (max-width: 1100px) {

    .table-container,
    .table-container--parametros,
    .registros-wrapper,
    .data-table-wrap,
    .tabla-scroll {
        overflow-x: auto;
        max-width: 100%;
    }

    /* Red de seguridad: cualquier tabla cuyo padre directo no tenga scroll
       propio recibe uno. Con display:block el <table> deja de expandir al
       ancestro y pasa a desplazarse el mismo. */
    .main-content > table,
    .content-section > table,
    .admin-form > table {
        display: block;
        overflow-x: auto;
        max-width: 100%;
    }

    /* Las celdas no se parten en varias lineas: es preferible desplazar la
       tabla que apilar un dato numerico en tres renglones. */
    .data-table th,
    .data-table td,
    .registros-table th,
    .registros-table td {
        white-space: nowrap;
    }

    /* Los <pre> de diagnostico de la IA y los JSON de payload desbordaban. */
    pre, code {
        white-space: pre-wrap;
        overflow-wrap: break-word;
        max-width: 100%;
    }

    /* Los lienzos de Chart.js necesitan un padre que no crezca con ellos. */
    .chart-wrap,
    .dash-chart-wrap,
    .tend-chart-wrap,
    .acum-chart-wrap,
    .setpoint-chart-wrap {
        max-width: 100%;
        overflow: hidden;
    }
}


/* ══════════════════════════════════════════════════════════════════════════════
   8. OBJETIVOS TACTILES
   La guia de interfaz de Apple pide 44x44 px como minimo alcanzable con el
   dedo; Material Design pide 48. Medidos 139 de 154 controles por debajo de 44,
   y 115 por debajo de 32. Se amplian solo en punteros gruesos (dedo), asi que
   el raton en escritorio conserva la densidad actual.
   ══════════════════════════════════════════════════════════════════════════════ */

@media (pointer: coarse) {

    button,
    .btn,
    a.btn,
    [role="button"],
    input[type="submit"],
    input[type="button"],
    .nav-item,
    .nav-group-toggle,
    .mobile-header__grid-btn {
        min-height: 44px;
        min-width: 44px;
    }

    /* Los iconos-boton de las tablas (editar, anular) son los mas pequenos y
       los mas propensos a un toque erroneo, justo donde mas duele. */
    .data-table button,
    .registros-table button,
    .table-container button {
        min-height: 40px;
        min-width: 40px;
    }

    /* Las casillas de seleccion nativas son diminutas en movil. */
    input[type="checkbox"],
    input[type="radio"] {
        min-width: 22px;
        min-height: 22px;
    }

    /* Separacion entre controles contiguos: sin ella, ampliarlos solo consigue
       que se toquen entre si. */
    .form-actions,
    .toolbar-actions,
    .aud-field--actions {
        gap: 10px;
    }
}


/* ══════════════════════════════════════════════════════════════════════════════
   9. PANTALLAS GRANDES
   No habia ningun tope de ancho ni media query por encima de 1440px: en un
   monitor 4K o ultrawide el contenido se estiraba de borde a borde, con
   formularios de una sola columna a 3000px y lineas de texto ilegibles.

   El tope arranca en 1800px para no alterar ninguna resolucion habitual
   (1366, 1440, 1600, 1920 quedan intactas).
   ══════════════════════════════════════════════════════════════════════════════ */

@media (min-width: 1800px) {

    .main-content {
        /* OJO: NO usar margin-left/right:auto aqui. .main-content es un flex item
           de .main (flex-direction:column), y un margen auto en el eje transversal
           DESACTIVA el stretch del cross-axis: la caja se encoge a su ancho de
           contenido y se centra, dejando cientos de px muertos a cada lado en TODAS
           las secciones (las graficas quedaban a 322px de 1713 disponibles).
           align-self:center + width:100% centra igual sin perder el estirado. */
        width: 100%;
        max-width: 1720px;
        align-self: center;
    }
}

@media (min-width: 2400px) {

    /* En ultrawide de verdad, tambien se limita el formulario para que sus
       campos no queden separados por medio metro de vacio. */
    .admin-form {
        max-width: 1400px;
    }
}


/* ══════════════════════════════════════════════════════════════════════════════
   10. IMPRESION Y MOVIMIENTO REDUCIDO
   admin.css ya cubre @media print y prefers-reduced-motion. Aqui solo se anade
   lo que la capa nueva podria haber roto.
   ══════════════════════════════════════════════════════════════════════════════ */

@media print {
    .mobile-header,
    .mobile-nav-backdrop {
        display: none !important;
    }

    .main-content {
        max-width: none;
    }
}

/* ══════════════════════════════════════════════════════════════════════════════
   VENTANA DE UN PARAMETRO EN MOVIL
   ══════════════════════════════════════════════════════════════════════════════
   monitoreo.css oculta el panel lateral por debajo de 768 px. Con eso se pierde
   la mitad util de la ventana: situarse en un instante y ver como estaba TODO el
   equipo en ese momento. En vez de esconderlo, se apila bajo la grafica.
   ══════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 767px) {
    .kpi-modal__body {
        flex-direction: column;
    }

    /* Vuelve a la vista, ahora debajo y con su propio desplazamiento. */
    .kpi-modal__params-panel {
        display: flex !important;
        width: 100%;
        max-height: 42%;
        border-left: none;
        border-top: 1px solid rgba(100, 116, 139, .22);
    }

    /* La lista es lo unico que se desplaza; la cabecera con la hora se queda. */
    .kpi-modal__params-panel .params-panel__list {
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* La grafica cede altura al panel, pero conserva un minimo legible. */
    .kpi-modal__chart-area {
        flex: 1 1 auto;
        min-height: 46%;
        padding: 8px 10px 10px;
    }
    .kpi-modal__chart-wrap {
        min-height: 180px;
    }
}

/* En tableta hay sitio de sobra para el panel al lado, solo algo mas estrecho. */
@media (min-width: 768px) and (max-width: 1024px) {
    .kpi-modal__params-panel {
        width: 190px;
    }
}
