/* ==========================================================================
   De Salas CRM · cáscara de aplicación para móvil e iPad
   --------------------------------------------------------------------------
   Convierte el CRM en una app con barra superior y barra inferior de pestañas
   SIN tocar la versión de escritorio: todo cuelga de html.app-movil, que
   activa el script en línea de includes/pwa_head.php cuando la pantalla es de
   móvil/tablet o el puntero es táctil (iPad apaisado incluido).

   En PC con ratón la clase no se pone nunca y el CRM se ve exactamente igual
   que hoy.
   ========================================================================== */

:root {
    --app-topbar-alto: 56px;
    --app-tabbar-alto: 60px;
    --app-azul: #12418d;
    --app-azul-claro: #e8eefb;
    --app-barra: #1e293b;
}

/* La cáscara solo existe en modo app.
   Todo lo estructural va con !important a propósito: main.css tiene reglas
   antiguas del tipo `header { position: relative !important }` para domar las
   cabeceras de página, y bastaba una copia cacheada de main.css para que la
   barra superior dejara de ser fija y empujara el contenido fuera de pantalla. */
.app-topbar,
.app-tabbar {
    display: none !important;
}

/* --------------------------------------------------------------------------
   1. Estructura general
   -------------------------------------------------------------------------- */
html.app-movil .app-topbar,
html.app-movil .app-tabbar {
    display: flex !important;
}

/* La cabecera móvil antigua (la inyectaba sidebar.php) queda sustituida. */
html.app-movil .mobile-topbar {
    display: none !important;
}

/* Hueco para las dos barras fijas. La clase .app-con-barras la pone
   includes/app_movil.php, así que solo se reserva en las pantallas que de
   verdad las llevan (el login y demás páginas públicas no). */
html.app-movil.app-con-barras main,
html.app-movil.app-con-barras .main-content {
    padding-top: calc(var(--app-topbar-alto) + env(safe-area-inset-top)) !important;
    padding-bottom: calc(var(--app-tabbar-alto) + env(safe-area-inset-bottom)) !important;
}

/* Scroll de página completa en las pantallas que en escritorio scrollean por
   dentro (fichas, listados con cabecera fija). La clase la pone
   assets/js/app-movil.js solo donde es seguro. */
/* Sin esto el que scrollea es <body> (html y body llevan height:100% por la
   clase h-full): el móvil no colapsa la barra de direcciones y el rebote de
   iOS se comporta raro. Con height auto scrollea el viewport, como debe. */
html.app-movil.app-scroll-pagina,
html.app-movil.app-scroll-pagina body {
    height: auto !important;
    min-height: 100% !important;
}
html.app-movil.app-scroll-pagina body > .flex {
    height: auto !important;
    min-height: 100% !important;
    align-items: flex-start !important;
}
html.app-movil.app-scroll-pagina main,
html.app-movil.app-scroll-pagina .main-content {
    height: auto !important;
    min-height: 100vh !important;
    overflow: visible !important;
}
/* La cadena de contenedores que encajonaba el scroll (la marca el JS).
   Ojo con el flex: con `flex: 0 0 auto` dentro de un contenedor en fila la caja
   se dimensiona por su contenido, y la tabla ancha del listado la estiraba a
   35.000px. Con `1 1 auto` + min-width 0 se queda en el ancho disponible. */
html.app-movil.app-scroll-pagina .app-suelto {
    overflow: visible !important;
    height: auto !important;
    max-height: none !important;
    flex: 1 1 auto !important;
    min-width: 0 !important;
    max-width: 100% !important;
}
/* La cabecera de la ficha deja de estar pegada: en móvil roba media pantalla. */
html.app-movil.app-scroll-pagina main > header {
    position: static !important;
}

/* En iPad apaisado (>=1024px con pantalla táctil) el CSS de escritorio seguiría
   dejando el sidebar fijo y un margen de 16rem. En modo app el menú es un cajón,
   igual que en el móvil. */
html.app-movil #sidebar {
    position: fixed !important;
    top: 0;
    bottom: 0;
    left: 0;
    width: 280px !important;
    transform: translateX(-100%);
    z-index: 60 !important;
    box-shadow: 5px 0 25px rgba(0, 0, 0, 0.25) !important;
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
}
html.app-movil #sidebar.open-mobile {
    transform: translateX(0) !important;
}
html.app-movil #sidebar .sidebar-toggle-btn {
    display: none !important;
}
html.app-movil #sidebar ~ main,
html.app-movil #sidebar ~ .main-content,
html.app-movil #sidebar.collapsed ~ main,
html.app-movil #sidebar.collapsed ~ .main-content {
    margin-left: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
}

/* --------------------------------------------------------------------------
   2. Barra superior
   -------------------------------------------------------------------------- */
.app-topbar {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    /* 52 y no 50: varias pantallas tienen superposiciones propias en z-50 que,
       al ir después en el DOM, se pintaban por encima de la navegación. */
    z-index: 52 !important;
    width: auto !important;
    align-items: center;
    gap: 0.25rem;
    height: calc(var(--app-topbar-alto) + env(safe-area-inset-top));
    padding: 0 max(0.5rem, env(safe-area-inset-right)) 0 max(0.5rem, env(safe-area-inset-left));
    padding-top: env(safe-area-inset-top);
    background: var(--app-barra);
    border-bottom: 1px solid #0f172a;
    color: #f8fafc;
    box-sizing: border-box;
}

.app-topbar-titulo {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    padding-left: 0.375rem;
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: #f8fafc;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* El logotipo sustituye al título en el panel, donde el título no aporta nada. */
.app-topbar-logo {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    padding-left: 0.375rem;
}
.app-topbar-logo img {
    height: 30px;
    width: auto;
    max-width: 140px;
    object-fit: contain;
}

.app-topbar-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 0.625rem;
    background: transparent;
    color: #cbd5e1;
    cursor: pointer;
    position: relative;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}
.app-topbar-btn:active {
    background: rgba(255, 255, 255, 0.1);
    color: #ffffff;
}

/* Contador de alertas sin leer. */
.app-topbar-badge {
    position: absolute;
    top: 5px;
    right: 5px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    background: #ef4444;
    border: 2px solid var(--app-barra);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 13px;
    text-align: center;
    box-sizing: border-box;
}

/* --------------------------------------------------------------------------
   3. Barra inferior de pestañas
   -------------------------------------------------------------------------- */
.app-tabbar {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    z-index: 52 !important; /* ver nota en .app-topbar */
    align-items: stretch;
    height: calc(var(--app-tabbar-alto) + env(safe-area-inset-bottom));
    padding-bottom: env(safe-area-inset-bottom);
    background: #ffffff;
    border-top: 1px solid #e2e8f0;
    box-shadow: 0 -1px 12px rgba(15, 23, 42, 0.06);
    box-sizing: border-box;
}

.app-tab {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-width: 0;
    border: 0;
    background: transparent;
    color: #64748b;
    font-size: 10.5px;
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    padding: 6px 2px;
    -webkit-tap-highlight-color: transparent;
    position: relative;
}
.app-tab span {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.app-tab svg {
    width: 22px;
    height: 22px;
    flex: 0 0 auto;
}

/* La pestaña activa lleva la pastilla azul de marca. */
.app-tab-icono {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 28px;
    border-radius: 999px;
    transition: background-color 0.15s ease;
}
.app-tab[aria-current="page"] {
    color: var(--app-azul);
}
.app-tab[aria-current="page"] .app-tab-icono {
    background: var(--app-azul-claro);
}
.app-tab:active .app-tab-icono {
    background: #f1f5f9;
}

/* Contadores sobre el icono (tareas pendientes, alertas). */
.app-tab-badge {
    position: absolute;
    top: 2px;
    left: 50%;
    margin-left: 6px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    background: #ef4444;
    border: 2px solid #ffffff;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 13px;
    text-align: center;
    box-sizing: border-box;
}

/* --------------------------------------------------------------------------
   4. Ajustes de convivencia
   -------------------------------------------------------------------------- */
/* El botón del asistente flotaba sobre la barra de pestañas. */
html.app-movil #asisLauncher,
html.app-movil .asis-launcher {
    bottom: calc(var(--app-tabbar-alto) + env(safe-area-inset-bottom) + 12px) !important;
}

/* Barras flotantes de acciones masivas: por encima de las pestañas. */
html.app-movil .barra-flotante-masiva {
    bottom: calc(var(--app-tabbar-alto) + env(safe-area-inset-bottom) + 12px) !important;
}

/* Avisos de la PWA: idem. */
html.app-movil .pwa-aviso {
    bottom: calc(var(--app-tabbar-alto) + env(safe-area-inset-bottom) + 12px);
}

/* Aviso flotante de "guardado correctamente" de la ficha de inmueble: caía
   justo debajo de la barra de pestañas y no llegaba a verse. */
html.app-movil #flash-toast {
    left: max(0.75rem, env(safe-area-inset-left)) !important;
    right: max(0.75rem, env(safe-area-inset-right)) !important;
    bottom: calc(var(--app-tabbar-alto) + env(safe-area-inset-bottom) + 12px) !important;
    justify-content: center;
}

/* El aviso de novedades se ancla al hueco del sidebar (left:280px, 320px de
   ancho): en un móvil de 402px se salía por la derecha. */
html.app-movil #novedades-popup {
    left: max(0.75rem, env(safe-area-inset-left)) !important;
    right: max(0.75rem, env(safe-area-inset-right)) !important;
    width: auto !important;
    bottom: calc(var(--app-tabbar-alto) + env(safe-area-inset-bottom) + 12px) !important;
    max-height: 60vh !important;
}

/* Mapas a pantalla completa (captación). Estaban dimensionados con
   calc(100vh - 64px): ni contaba las dos barras de la app ni el hecho de que la
   cabecera, con sus filtros y botones, pasa de 64px a tres líneas en un móvil.
   En vez de recalcular a mano, el mapa ocupa el hueco que quede. */
html.app-movil .map-container {
    flex: 1 1 auto !important;
    height: auto !important;
    min-height: 240px;
}

/* Barra del mapa de vendidas: el selector de oficina va en position:absolute a
   la derecha y en móvil se montaba encima del texto. Pasa a ir debajo. */
html.app-movil .barra-vendidas {
    padding: 0.5rem 0.75rem 0.625rem !important;
    flex-direction: column;
    gap: 0.5rem !important;
}
html.app-movil .barra-vendidas .oficina-form {
    position: static !important;
    transform: none !important;
}

/* La cabecera de esos mapas es h-16 (64px fijos) con selects y dos botones:
   en móvil el contenido se salía por debajo y se comía el mapa. */
html.app-movil main > header.h-16 {
    height: auto !important;
    min-height: 0 !important;
    flex-wrap: wrap !important;
    gap: 0.5rem !important;
    padding: 0.625rem 1rem !important;
}
html.app-movil main > header.h-16 > div {
    flex-wrap: wrap !important;
    gap: 0.5rem !important;
}

/* La leyenda del mapa de captación se ancla abajo a la izquierda (el JS le pone
   el "left" según el sidebar): tapaba las dos primeras pestañas. */
html.app-movil .map-legend {
    left: max(0.5rem, env(safe-area-inset-left)) !important;
    right: auto !important;
    bottom: calc(var(--app-tabbar-alto) + env(safe-area-inset-bottom) + 8px) !important;
    max-width: calc(100vw - 1rem);
}

/* Filas de formulario montadas con `style="display:flex"` (campo + botón, como
   Referencia Catastral + "Consultar Catastro"): el botón lleva nowrap y en
   móvil se salía de la tarjeta. Solo en modo app: en escritorio la fila cabe y
   debe seguir en una línea. */
html.app-movil form div[style*="display: flex"],
html.app-movil form div[style*="display:flex"] {
    flex-wrap: wrap !important;
}

/* Fichas: la rejilla de dos columnas ya colapsa a una bajo 1280px, pero el
   track seguía dimensionándose por el contenido más ancho (los items de grid
   llevan min-width:auto por defecto) y se salía de la pantalla.
   minmax(0, 1fr) es el remedio estándar a ese "grid blowout". */
html.app-movil .ficha-grid-layout {
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 1rem !important;
}
html.app-movil .ficha-grid-layout > *,
html.app-movil .ficha-main-column,
html.app-movil .ficha-sidebar-column {
    min-width: 0 !important;
    max-width: 100% !important;
}
html.app-movil .ficha-layout-container {
    padding: 1rem !important;
}

/* Línea de tiempo de actividad (fichas): el avatar sobresale 21px a la
   izquierda de la línea. Con el margen reducido del móvil se salía del
   viewport y quedaba recortado. */
html.app-movil .activity-timeline-item {
    margin-left: 2rem !important;
}

/* Cabeceras pegajosas de formularios, bajo la barra superior. */
html.app-movil .sticky-header {
    top: calc(var(--app-topbar-alto) + env(safe-area-inset-top)) !important;
    z-index: 40 !important;
    /* Llevan margin:-2rem para sangrar hasta el borde del contenedor de
       escritorio; en móvil ese contenedor tiene menos padding y sobresalían
       14px por cada lado. */
    margin-left: 0 !important;
    margin-right: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* Los cajones (menú, filtros) tapan la barra de pestañas mientras están abiertos. */
html.app-movil #sidebar,
html.app-movil #settings-sidebar,
html.app-movil main aside:not(#sidebar):not(#settings-sidebar) {
    z-index: 60 !important;
}
html.app-movil #sidebar-backdrop {
    z-index: 55 !important;
}

/* ==========================================================================
   4 bis. Nada de "hover" en una pantalla táctil
   --------------------------------------------------------------------------
   Los listados esconden los botones de acción y las flechas de la galería
   detrás de :hover. En un móvil no hay hover: el primer toque solo APLICA ese
   estado —aparecen los botones y el contenido se mueve—, y el navegador
   descarta ese clic. De ahí que hubiera que tocar dos veces para entrar en un
   inmueble. Con los controles siempre a la vista, el primer toque ya entra
   (y de paso esas acciones dejan de ser inalcanzables en el móvil).
   ========================================================================== */
html.app-movil .actions-hover {
    display: flex !important;
}
html.app-movil .gallery-prev,
html.app-movil .gallery-next {
    opacity: 1 !important;
}

/* ==========================================================================
   4 ter. Sin zoom accidental
   --------------------------------------------------------------------------
   En una app instalada el pellizco para acercar no aporta nada y sí molesta:
   se dispara al desplazarse y deja la pantalla torcida. Los mapas se quedan
   fuera, que ahí el pellizco es justo lo que se necesita.

   (En Safari DENTRO del navegador iOS ignora esto a propósito, por
   accesibilidad; en la app instalada sí lo respeta.)
   ========================================================================== */
html.app-movil,
html.app-movil body {
    touch-action: pan-x pan-y;
}
html.app-movil #map,
html.app-movil #map-vendidas,
html.app-movil #map-catastro,
html.app-movil .map-container,
html.app-movil .leaflet-container,
html.app-movil .fancybox__container {
    touch-action: auto !important;
}

/* ==========================================================================
   5. Panel (dashboard) en modo app
   Mismos datos y mismos enlaces que en PC; solo cambia cómo se colocan.
   ========================================================================== */

/* El saludo sustituye a la cabecera "Dashboard", que en la app ya está en la
   barra superior. Fuera del modo app no se muestra. */
.dash-saludo {
    display: none;
}
html.app-movil .dash-saludo {
    display: block;
    margin-bottom: 1.25rem;
}
html.app-movil .dash-header-escritorio {
    display: none !important;
}
.dash-saludo-nombre {
    font-size: 1.5rem;
    font-weight: 700;
    color: #0f172a;
    letter-spacing: -0.02em;
    line-height: 1.2;
}
.dash-saludo-fecha {
    margin-top: 0.25rem;
    font-size: 0.9375rem;
    color: #64748b;
}

/* Menos aire alrededor del contenido: en un móvil 32px por lado es media pantalla. */
html.app-movil .dash-contenido {
    padding: 1rem !important;
}

/* --- Tarjetas de indicadores: 2x2 en móvil, las cuatro en fila en iPad --- */
html.app-movil .dash-kpis {
    grid-template-columns: 1fr 1fr !important;
    gap: 0.75rem !important;
    margin-bottom: 1.5rem !important;
}
html.app-movil .dash-kpis > a {
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 0.75rem !important;
    padding: 1rem !important;
}
@media (min-width: 768px) {
    html.app-movil .dash-kpis {
        grid-template-columns: repeat(4, 1fr) !important;
    }
    html.app-movil .dash-contenido {
        padding: 1.5rem !important;
    }
}

/* --- Viviendas más vendibles: tarjetas con foto grande ---
   En móvil son un carrusel horizontal; en iPad, una rejilla (ver más abajo).
   El bloque va dentro de @media screen para que al imprimir se conserve la
   lista de escritorio. */
@media screen {
    html.app-movil .dash-calor-lista {
        display: flex;
        gap: 0.75rem;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        padding: 0.875rem 1rem 1rem;
        scrollbar-width: none;
    }
    html.app-movil .dash-calor-lista::-webkit-scrollbar {
        display: none;
    }

    /* Cada fila pasa a ser una tarjeta: el borde completo sustituye a la línea
       divisoria de la lista de escritorio (.divide-y). */
    html.app-movil .dash-calor-row {
        position: relative;
        flex: 0 0 76%;
        max-width: 290px;
        align-items: flex-start !important;
        gap: 0 !important;
        padding: 0 !important;
        margin: 0 !important;
        border: 1px solid #e2e8f0 !important;
        border-radius: 0.875rem;
        overflow: hidden;
        background: #ffffff;
        scroll-snap-align: start;
    }

    /* Foto a todo el ancho, arriba. */
    html.app-movil .dash-calor-foto {
        order: 1;
        flex: 0 0 100% !important;
        width: 100% !important;
        height: 140px !important;
        border-radius: 0 !important;
    }

    /* El índice de calor se superpone sobre la foto, como en la app de referencia. */
    html.app-movil .dash-calor-badge {
        position: absolute;
        top: 0.5rem;
        left: 0.5rem;
        z-index: 2;
        width: 46px !important;
        padding: 0.25rem;
        border-radius: 0.625rem;
        background: rgba(255, 255, 255, 0.92);
        box-shadow: 0 2px 8px rgba(15, 23, 42, 0.18);
    }

    html.app-movil .dash-calor-info {
        order: 2;
        flex: 0 0 100% !important;
        min-width: 0 !important;
        padding: 0.75rem 0.875rem 0.5rem;
    }

    /* Las dos cajas de métricas comparten línea, a mitades. */
    html.app-movil .dash-calor-metricas {
        order: 3;
        flex: 1 1 50% !important;
        min-width: 0 !important;
        text-align: left !important;
        border-right: none !important;
        padding: 0 0.875rem 0.75rem !important;
        margin: 0 !important;
        font-size: 0.8125rem;
    }
    html.app-movil .dash-calor-metricas > div:first-child {
        font-size: 0.8125rem !important;
    }

    /* Acciones a lo ancho, con el botón "Ver" grande y cómodo. */
    html.app-movil .dash-calor-acciones {
        order: 4;
        flex: 0 0 100% !important;
        gap: 0.5rem !important;
        padding: 0 0.875rem 0.875rem;
    }
    html.app-movil .dash-calor-acciones > a {
        flex: 1 1 auto;
        text-align: center;
    }
}

/* En iPad hay sito para verlas todas a la vez: rejilla en lugar de carrusel. */
@media (min-width: 768px) {
    html.app-movil .dash-calor-lista {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
        gap: 1rem;
        overflow-x: visible;
        padding: 1rem 1.25rem 1.25rem;
    }
    html.app-movil .dash-calor-row {
        flex: 1 1 auto;
        max-width: none;
    }
    html.app-movil .dash-calor-foto {
        height: 150px !important;
    }
}

/* ==========================================================================
   6. Listados: la tabla se convierte en tarjetas (solo en móvil)
   Las etiquetas de cada celda las pone assets/js/app-movil.js a partir del
   <thead>. En iPad y en PC la tabla sigue siendo una tabla.
   ========================================================================== */
@media (max-width: 767px) {
    html.app-movil .tabla-tarjetas,
    html.app-movil .tabla-tarjetas tbody,
    html.app-movil .tabla-tarjetas tr,
    html.app-movil .tabla-tarjetas td {
        display: block;
        width: auto !important;
        max-width: none !important;
        min-width: 0 !important;
    }

    html.app-movil .tabla-tarjetas {
        border-collapse: separate;
        border-spacing: 0;
    }

    /* La cabecera ya no hace falta: su texto viaja en cada celda. */
    html.app-movil .tabla-tarjetas thead {
        display: none;
    }

    html.app-movil .tabla-tarjetas tr {
        position: relative;
        margin: 0 0 0.75rem;
        padding: 0.875rem 1rem;
        border: 1px solid #e2e8f0;
        border-radius: 0.875rem;
        background: #ffffff;
        box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    }

    html.app-movil .tabla-tarjetas td {
        display: flex;
        align-items: baseline;
        gap: 0.75rem;
        padding: 0.3125rem 0 !important;
        border: 0 !important;
        white-space: normal !important;
        text-align: left !important;
        font-size: 0.875rem;
        line-height: 1.4;
    }

    /* Etiqueta de la columna, a la izquierda y en gris. */
    html.app-movil .tabla-tarjetas td[data-etiqueta]:not([data-etiqueta=""])::before {
        content: attr(data-etiqueta);
        flex: 0 0 40%;
        max-width: 9rem;
        color: #64748b;
        font-size: 0.75rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.02em;
        line-height: 1.5;
    }

    /* La primera celda con contenido hace de titular de la tarjeta. */
    html.app-movil .tabla-tarjetas td.celda-titular {
        display: block;
        padding-bottom: 0.5rem !important;
        margin-bottom: 0.25rem;
        border-bottom: 1px solid #f1f5f9 !important;
        font-size: 1rem;
        font-weight: 600;
        color: #0f172a;
    }
    html.app-movil .tabla-tarjetas td.celda-titular::before {
        display: none;
    }

    /* Casillas de selección y columnas de acciones: sin etiqueta y a la derecha. */
    html.app-movil .tabla-tarjetas td.celda-sin-etiqueta {
        display: flex;
        justify-content: flex-end;
        gap: 0.5rem;
    }
    html.app-movil .tabla-tarjetas td.celda-sin-etiqueta:first-child {
        position: absolute;
        top: 0.75rem;
        right: 0.75rem;
        padding: 0 !important;
    }

    /* Fila de "no hay resultados". */
    html.app-movil .tabla-tarjetas td.celda-ancha {
        display: block;
        text-align: center !important;
        color: #64748b;
    }
    html.app-movil .tabla-tarjetas td.celda-ancha::before {
        display: none;
    }

    /* El contenedor ya no necesita desplazamiento lateral. */
    html.app-movil .tabla-tarjetas {
        min-width: 0 !important;
    }

    /* Y deja de ser un contenedor desplazable, no solo de tener barra.
       Mientras siga siéndolo, Android puede quedarse con el gesto vertical que
       empiece dentro de él —que es casi toda la pantalla en un listado— y la
       página no se mueve. La marca la pone assets/js/app-movil.js al convertir
       la tabla. */
    html.app-movil .sin-scroll-lateral {
        overflow: visible !important;
    }
}

/* ==========================================================================
   7. Barras de filtros dentro de la página (Tareas)
   Apiladas ocupaban la pantalla entera antes de enseñar un solo resultado, así
   que en móvil se pliegan tras el botón de filtros de la barra superior.
   ========================================================================== */
@media (max-width: 767px) {
    html.app-movil .filtros-inline {
        display: none;
    }
    html.app-movil .filtros-inline.abierto {
        display: block;
    }
}

@media print {
    .app-topbar,
    .app-tabbar { display: none !important; }
    html.app-movil main { padding-top: 0 !important; padding-bottom: 0 !important; }
}


/* ==========================================================================
   8. Cajas que solo desplazan a lo ancho
   --------------------------------------------------------------------------
   `overflow-x: auto` obliga al navegador a calcular el eje vertical como
   `auto`, asi que carruseles y tablas anchas se convierten en contenedores de
   scroll vertical sin nada que desplazar. En Android se quedan con el gesto de
   arriba abajo y no lo ceden a la pagina: el dedo se mueve y no baja nada.

   La clase la pone assets/js/app-movil.js. Con overflow-y oculto la caja sigue
   desplazandose a lo ancho exactamente igual, pero ya no puede quedarse con el
   gesto vertical.
   ========================================================================== */
html.app-movil .sin-scroll-vertical {
    overflow-y: hidden !important;
    overscroll-behavior-y: auto !important;
}

/* ==========================================================================
   9. Que <body> no se quede con el gesto vertical
   --------------------------------------------------------------------------
   main.css le pone `overflow-x: hidden` a <body> para que la pagina no se
   pueda arrastrar de lado. El efecto colateral es que, al fijar un eje, el CSS
   obliga a calcular el otro como `auto`: <body> pasa a ser un contenedor de
   scroll vertical del tamano de toda la pagina y sin nada que desplazar. En
   Android el dedo aterriza ahi, el gesto es suyo, y no se mueve nada.

   La proteccion se sube a <html>, que es quien desplaza de verdad: la pagina
   sigue sin poder arrastrarse de lado y <body> deja de ser un contenedor de
   scroll. Medido en el aparato que fallaba (Xiaomi, Android 10).
   ========================================================================== */
html.app-movil {
    overflow-x: hidden;
}
html.app-movil body {
    overflow: visible !important;
}
