/* ==========================================================================
   IRON ROUTE — LA ESQUINA SUPERIOR DERECHA, DONDE TRES COSAS SE PISABAN

   MEDIDO sobre la captura del dueño (1908×1038) y confirmado en 1440, 1024,
   768 y 375:

     · `#ir-r4-auth-btn`  («Iniciar sesión»)  142×44, anclado a `right: 12px`
     · `.irc-capas`       (Calle/Satélite/Oscuro/Claro/Relieve)  603×62,
                          también anclado a `right: 12px`
     · `.search-header`   (el buscador)       480×72, centrado arriba

   Los tres viven en la misma franja superior y ninguno sabe de los otros:

     1. El botón de cuenta tapa el chip «Relieve» de la barra de capas.
        `elementFromPoint` sobre ese chip devuelve el botón de login — o sea
        que **una de las cinco capas base no se puede elegir en escritorio**.
     2. La barra de capas se mete debajo del buscador por la izquierda:
        `.irc-capas` pierde el **20,2 %** de su área bajo `.search-header`, y
        el chip «Calle» devuelve `input#searchInput` al pulsarlo. **Dos de
        cinco capas muertas.**
     3. En teléfono el botón de cuenta se sienta ENCIMA del buscador:
        `142×48@221,12` contra `221×48@69,12` = **69×48 px de solape**, y el
        micrófono queda tapado.

   Nada de esto es un fallo de un archivo: es que cuatro módulos distintos
   anclan a la misma esquina con `position: fixed` y `right`, y el que se
   carga después gana. Esta hoja reparte esa franja de una vez.

   LA REGLA QUE SE APLICA:
   En una franja compartida, quien tiene ancho variable cede. El buscador es
   lo que más se usa y se queda donde está; el botón de cuenta es el más
   pequeño y se queda en la esquina; **la barra de capas se aparta**, porque
   es la única que puede reducirse o bajar sin perder nada.
   ========================================================================== */

/* ── 1 · Escritorio: los tres en la misma fila, sin tocarse ──────────────── */
@media (min-width: 900px) {
  /* El botón de cuenta se queda en la esquina: 12px del borde, 154px de
     reserva contando su ancho máximo con un correo largo. */
  .irc-capas {
    right: 178px;
    max-width: calc(100vw - 178px - 12px);
  }
}

/* Pantallas donde el buscador y las capas todavía se rozarían: la barra de
   capas baja una fila en vez de meterse debajo del buscador. */
@media (min-width: 900px) and (max-width: 1500px) {
  .irc-capas {
    top: 84px;          /* justo debajo de la cabecera de búsqueda (72px) */
    right: 12px;
    max-width: calc(100vw - 24px);
  }
}

/* ── 2 · Teléfono y tablet: nadie se sienta encima del buscador ──────────── */
@media (max-width: 899px) {
  /* El buscador ocupa toda la franja de arriba. El botón de cuenta baja
     debajo, alineado a la derecha. 8px de aire para que no parezca pegado. */
  #ir-r4-auth-btn,
  #ir-topright-user {
    top: calc(72px + env(safe-area-inset-top, 0px) + 8px) !important;
    right: 12px !important;
  }

  /* Y las capas debajo del botón de cuenta, no al lado: en 375px no caben en
     la misma fila y lo que no cabe se sale. */
  .irc-capas {
    top: calc(72px + env(safe-area-inset-top, 0px) + 8px + 52px);
    right: 12px;
    left: 12px;
    max-width: none;
  }
}

/* ── 3 · La barra de capas nunca se sale por los lados ───────────────────
   Medido: `.irc-lista` salía a `172×270@191,140` en un teléfono de 375 y se
   quedaba abierta. Se acota al ancho disponible y se le da scroll propio en
   vez de desbordar. */
.irc-capas {
  max-width: calc(100vw - 24px);
  box-sizing: border-box;
}
.irc-capas .irc-lista {
  max-width: calc(100vw - 24px);
  max-height: min(60vh, 420px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* ── 4 · El pie legal deja de montarse sobre los accesos rápidos ──────────
   Medido: `.ir-footer-id` (z-index 1199) solapaba `.quick-tiles` (z 800) en
   **1648×10 px** a 1908, y **375×17 px** en el teléfono. Diez píxeles no
   parecen nada hasta que son diez píxeles de una línea de 9,5 px: se pierde
   el trazo inferior de las letras y el número de USDOT se lee mal.

   Y la letra sube de 9,5 px a 12, que es el suelo del sistema. Un
   identificador federal que no se puede leer no cumple su función. */
.ir-footer-id {
  font-size: 12px !important;
  line-height: 1.3 !important;
  padding: 4px 10px calc(4px + env(safe-area-inset-bottom, 0px)) !important;
}
.ir-footer-id span { font-size: 12px !important; }

/* ── 5 · Los accesos rápidos se apartan del pie ──────────────────────────── */
.quick-tiles {
  margin-bottom: 6px;
}

/* ── 6 · Objetivos táctiles que estaban por debajo del suelo ──────────────
   Medido en teléfono: 19 de 77 controles por debajo de 48 px. Estos son los
   del mapa, que son los que se pulsan con el camión parado en un arcén. */
@media (max-width: 899px) {
  #menuBtn,
  #voiceBtn,
  #locateBtn,
  #layersBtn,
  #truckRestrictBtn,
  #ir-r4-auth-btn,
  #ir-topright-user {
    min-width: 48px;
    min-height: 48px;
  }
  #swapRouteBtn,
  .ir-pf5-close,
  .fab-collapse-toggle,
  .r25-collapse-btn { min-width: 48px; min-height: 48px; }
}
/* Con ratón el suelo baja a 40, nunca menos. */
@media (min-width: 900px) {
  .fab-collapse-toggle,
  .r25-collapse-btn,
  #swapRouteBtn,
  .ir-pf5-close { min-width: 40px; min-height: 40px; }
}

/* ── 7 · Las etiquetas por debajo de 12 px ────────────────────────────────
   `ecosystem-core` fija el suelo en 12 px y no admite excepciones fuera del
   modo navegación (que sube a 20). Medido: 29 nodos por debajo en escritorio
   y 23 en teléfono. Estos son los que se leen de verdad. */
.tile-label,
.nav-tab span,
.menu-tagline,
.menu-version,
.ir-base-layer-heading { font-size: 12px !important; }

/* La atribución de Leaflet viene a 10px de la propia librería. Sube a 12 —
   es un requisito de licencia de OpenStreetMap: el crédito tiene que ser
   legible, no solo estar. */
.leaflet-control-attribution,
.leaflet-control-attribution a { font-size: 12px !important; }

/* ── 8 · Campos por debajo de 16 px → iOS hace zoom al enfocar ────────────
   Medido: 14 campos. El zoom descoloca la pantalla de alguien que puede
   estar parado en el arcén escribiendo una dirección. */
input, select, textarea,
#searchInput, #tripOrigin, #tripDest,
#vehicleType, #vehicleHeight, #vehicleWeight, #vehicleLength {
  font-size: 16px;
}

/* ── 9 · En escritorio no hace falta la barra de pestañas del teléfono ────
   Medido: `.bottom-nav 480×64@714,974` — una barra de 480 px flotando en un
   lienzo de 1908, con `transform: translate(-240px, 0)` para centrarla.

   Con el raíl de navegación a la izquierda (240-260 px, siempre visible) y
   los accesos rápidos abajo, esa barra es la TERCERA navegación de la misma
   pantalla. Tres formas de ir al mismo sitio no es generosidad: es que nadie
   sabe cuál es la buena. */
.ir-escritorio .bottom-nav,
.ir-escritorio .nav-tabs { display: none; }
/* Y el hueco que reservaba deja de reservarse. */
.ir-escritorio { --nav-height: 0px; }


/* ══════════════════════════════════════════════════════════════════════════
   `hidden` TIENE QUE ESCONDER — la salvaguarda general

   El desplegable de capas se quedó abierto para siempre en el teléfono porque
   su hoja de estilos le daba `display: flex` y eso le gana al `[hidden]` que
   aplica el navegador. `map-layers.js` hacía `lista.hidden = true` y no pasaba
   nada.

   No es un fallo de ese archivo: es una trampa del lenguaje que muerde a
   cualquiera que ponga `display` en una clase y luego use `hidden` en el JS.
   En esta base hay 20 sitios que usan `hidden` desde JavaScript.

   Se pone el suelo aquí, para todos, y con `!important` porque el rival
   —`display: flex` en una clase— tiene la misma especificidad y a veces
   aparece en una hoja posterior. Es de los pocos sitios donde `!important`
   es la herramienta correcta: se está restaurando el comportamiento del
   navegador, no compitiendo con otra decisión de diseño.

   Excepción declarada: `.irc-lista` en escritorio, que vive abierta en fila
   por decisión de producto y lo dice en su propia media query. */
[hidden]:not(.irc-lista) { display: none !important; }

@media (min-width: 1024px) {
  /* La excepción, escrita donde se ve: en ancho la lista de capas no se
     oculta nunca, es una barra de cinco chips. */
  .irc-lista[hidden] { display: flex !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   LOS AVISOS, EN EL TELÉFONO, ABAJO

   MEDIDO: el contenedor de avisos salía `299×756` — tres cuartos de la
   pantalla— porque DOS hojas definen la misma clase con anclajes opuestos y
   se mezclan: `styles.css:1237` lo ancla con `top`, y `ui-fixes-p0.css:9` con
   `bottom`. Con los dos puestos, la caja se estira de arriba abajo.

   Consecuencia real: un aviso de «No se pudo obtener tu ubicación» —que sale
   siempre que alguien deniega el GPS, o sea a menudo— aparecía ARRIBA y
   tapaba el botón de cuenta. `elementFromPoint` sobre ese botón devolvía
   `toast-message`.

   Se decide por abajo, que es lo que `ui-fixes-p0` ya quería y además es
   donde los espera cualquiera que use un teléfono: arriba está el buscador,
   y un aviso que tapa el buscador tapa lo que la persona iba a hacer. */
@media (max-width: 899px) {
  #toastContainer {
    top: auto;
    /* Por encima de la fila de botones flotantes, no encima de ellos. Medido:
       con 12 px el aviso caia sobre `#rrBoton` (Reportar) y `elementFromPoint`
       devolvia el aviso — o sea que durante los segundos que dura el aviso, el
       boton de reportar una restriccion no se podia pulsar. Y el aviso mas
       frecuente es «No se pudo obtener tu ubicacion», que sale justo cuando
       alguien acaba de denegar el GPS y va a querer tocar algo. */
    /* Por encima de TODA la fila de botones flotantes, no solo de uno.
       Medido en dos pasadas: con 12 px el aviso tapaba «Reportar»; con 84 px
       dejó de taparlo y empezó a tapar «+ VIAJE», que había subido para no
       pisar los accesos rápidos. Tres botones flotantes en la franja de abajo
       es lo que obliga a este número; el aviso se sube por encima de los tres
       y se acabó el juego de las sillas. */
    bottom: calc(var(--nav-height, 64px) + 160px + env(safe-area-inset-bottom, 0px));
    left: 12px;
    right: 12px;
    width: auto;
    max-width: none;
    transform: none;
    height: auto;
    max-height: 40vh;
    align-items: stretch;
  }
}
/* En escritorio se ancla arriba a la derecha y se le da alto propio: sin esto
   la caja también se estiraba 894 px, y aunque no roba clics
   (`pointer-events: none`), una caja de ese tamaño es una bomba de relojería
   el día que alguien le ponga `auto`. */
@media (min-width: 900px) {
  #toastContainer {
    bottom: auto;
    height: auto;
    max-height: 60vh;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   LOS TRES SOLAPES QUE QUEDABAN — medidos, no estimados

   1 · LA BARRA DE CAPAS SE METE 67 px BAJO EL BUSCADOR
       Medido a 1908: buscador `480×72@714`, o sea de 714 a 1194. Barra de
       capas `603×62@1127`, o sea empieza en 1127. **67 px de solape**, y ahí
       cae el primer chip: «Calle». Se ve medio tapado y `elementFromPoint`
       sobre él devuelve el buscador.

       La primera versión de esta hoja lo ancló a `right: 178px` contando el
       espacio del botón de cuenta. Correcto por la derecha, y no miré la
       izquierda: es una barra de 603 px, no cabe en el hueco que queda.

       Se baja una fila, debajo del buscador. No estorba a nada y ahí no
       compite con nadie — que es lo que se pedía desde el principio.

   2 · EL FAB «+ VIAJE» PISA LA FILA DE ACCESOS RÁPIDOS
       Medido: `107×56@1107,882` contra tiles `1648×94@260,930` = **107×8 px**.
       Ocho píxeles, pero justo sobre el borde superior del tile DESCANSO, que
       queda con la esquina comida.

   3 · DOS BOTONES DE PLEGAR PARA EL MISMO GRUPO
       `.fab-collapse-toggle` en `1856,648` y `.r25-collapse-btn` en
       `1162,632`. Dos controles idénticos, dos paradas de tabulación, **y dos
       claves distintas en el almacenamiento** (`ironroute_fab_collapsed` y
       `fab_collapsed`), para un solo grupo de tres botones.

       Se queda el que vive DENTRO del grupo que pliega —`.r25-collapse-btn`,
       justo encima de los tres botones— porque es el que se entiende sin
       explicación. El otro flota solo contra el borde derecho, a 700 px de lo
       que controla.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 900px) {
  /* 1 · debajo del buscador, en todos los anchos: la barra mide 603 px y en
     ningún tamaño realista cabe entre el buscador y el botón de cuenta. */
  .irc-capas {
    top: calc(72px + env(safe-area-inset-top, 0px) + 12px);
    right: 12px;
    max-width: calc(100vw - 24px);
  }

  /* 2 · el FAB, por encima de la fila de tiles */
  #fabNewTrip,
  .fab-new-trip { bottom: calc(var(--nav-height, 0px) + 118px); }

  /* 3 · un solo botón de plegar */
  .fab-collapse-toggle { display: none; }
}

@media (max-width: 899px) {
  /* En teléfono el que sobra es el otro: `.r25-collapse-btn` está dentro del
     grupo, que ahí es estrecho, y `.fab-collapse-toggle` es el que la gente
     ya conoce de la versión anterior. Se queda uno igual. */
  .r25-collapse-btn { display: none; }
  #fabNewTrip,
  .fab-new-trip { bottom: calc(var(--nav-height, 64px) + 96px + env(safe-area-inset-bottom, 0px)); }
}

/* ══════════════════════════════════════════════════════════════════════════
   LO QUE SALIÓ DE LA CAPTURA DEL IPHONE (430×932, producción)

   1 · EL PIE LEGAL SE CORTA — y con él el MC#
       Medido: `scrollWidth 542` en `clientWidth 430`. El texto es
       «TruckerProfit Inc., a Sultan Freight Logistics company · USDOT 4353234
       · MC# 1702404» y en pantalla acababa en «USDOT 4353234 · …».

       **El MC# no es decoración.** `ecosystem-core` lo exige en el pie de toda
       página pública junto al USDOT, y es lo que un conductor o un broker usa
       para comprobar en FMCSA que la empresa existe. Un identificador federal
       recortado por 112 píxeles no cumple su función.

       Se deja envolver en dos líneas. No se recorta el texto ni se baja de
       12 px: lo que sobra es el ancho, no el contenido.

   2 · DOS BOTONES DE PLEGAR, UNO ENCIMA DEL OTRO
       Medido: `.r25-collapse-btn 48×48@370,466` y
       `.fab-collapse-toggle 48×48@374,500` — **14 px de solape**, dos círculos
       pisándose en el borde derecho.

       Ya se había intentado esconder uno con `.r25-collapse-btn { display:
       none }` en esta misma hoja, y no funcionó: `bundle-r5.js` inyecta un
       `<style id="r25-css">` EN TIEMPO DE EJECUCIÓN, o sea que su regla entra
       en el `<head>` después que este archivo y gana con la misma
       especificidad.

       No se sube a `!important`: se sube la especificidad usando el padre
       real, que es `.map-controls`. Empatar por especificidad legítima es
       mejor que empezar una carrera de `!important` — y esa carrera ya va por
       103 en estas hojas.

   3 · «REPORTAR» TAPA EL PRIMER ACCESO RÁPIDO
       Medido: el primer tile es `128×78@12,772` y `elementFromPoint` sobre su
       centro devuelve `rrBoton`. El acceso «Planificador» —el primero de los
       diez y el más usado— **no se puede pulsar en un teléfono**.

       El botón de reportar se sube a la misma franja que «+ VIAJE», que ya
       está por encima de los tiles. Los dos flotan sobre el mapa, uno a cada
       lado, y ninguno pisa la fila de abajo.
   ══════════════════════════════════════════════════════════════════════════ */

/* 1 · el pie legal cabe entero */
.ir-footer-id {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  text-align: center;
}

/* 2 · un solo botón de plegar, ganando por especificidad y no con !important */
@media (max-width: 899px) {
  .map-controls .r25-collapse-btn { display: none; }
}
@media (min-width: 900px) {
  .map-controls .fab-collapse-toggle,
  body > .fab-collapse-toggle { display: none; }
}

/* 3 · «Reportar» sube a la franja de los botones flotantes */
@media (max-width: 899px) {
  .rr-lanzar,
  #rrBoton {
    bottom: calc(var(--nav-height, 64px) + 96px + env(safe-area-inset-bottom, 0px));
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   LA FRANJA DE ABAJO, APILADA DE UNA VEZ

   Llevo tres parches empujando piezas de esta zona una por una: subí el aviso
   y tapó «Reportar»; lo subí más y tapó «+ VIAJE»; subí «Reportar» y el pie
   creció a dos líneas y se comió los accesos rápidos.

   MEDIDO ahora mismo, y por eso paro de empujar:

     iPhone 430×932        y 724..772  botones flotantes
                           y 768..854  accesos rápidos
                           y 829..868  pie legal      ← 25 px encima de los tiles
                           y 868..932  barra de pestañas

     1440×900              y 840..888  «Reportar»     ← 46 px encima de los tiles
                           y 792..886  accesos rápidos
                           y 877..900  pie legal      ← 9 px encima de los tiles

   Cinco cosas fijadas al borde inferior por cuatro archivos distintos, cada
   una con su propio `bottom` calculado a mano. Cada vez que una cambia de
   alto —y el pie acaba de cambiar, al dejarlo envolver— se pisan otra vez.

   LA SOLUCIÓN no es otro empujón: es que **haya un solo sitio donde se decide
   el orden**. De abajo arriba:

       barra de pestañas  →  pie legal  →  accesos rápidos  →  flotantes

   Cada franja se coloca a partir de la altura de la de abajo, no de un número
   escrito a mano. Si el pie vuelve a crecer, todo lo demás sube solo.
   ══════════════════════════════════════════════════════════════════════════ */
:root {
  /* CERO desde que el pie legal salió del mapa (ver `bundle-r5.js`,
     `injectFooter`). La variable se queda —no se borra— porque de ella cuelgan
     nueve cálculos: ponerla a 0 baja la pila entera 42 px y devuelve esa franja
     al mapa, que es justo lo que se buscaba. Borrarla habría obligado a tocar
     los nueve y a arriesgar un desajuste en cada uno.

     Y sigue siendo una variable, no un 0 escrito nueve veces, por si mañana
     hay que devolver una banda de estado ahí abajo. */
  --ir-pie: 0px;
  --ir-tiles: 92px;
  --ir-hueco: 8px;
}
@media (min-width: 900px) {
  :root { --ir-pie: 0px; --ir-tiles: 100px; }
}

/* Los accesos rápidos, justo encima del pie legal. */
.quick-tiles,
.ir-escritorio .quick-tiles {
  bottom: calc(var(--nav-height, 64px) + var(--ir-pie) + var(--ir-hueco));
}

/* Los botones flotantes, justo encima de los accesos rápidos. Uno a cada
   lado, así que comparten franja sin pisarse: «Reportar» a la izquierda,
   «+ VIAJE» a la derecha. */
#fabNewTrip,
.fab-new-trip,
.rr-lanzar,
#rrBoton {
  bottom: calc(var(--nav-height, 64px) + var(--ir-pie) + var(--ir-hueco)
               + var(--ir-tiles) + var(--ir-hueco));
}
.ir-escritorio .rr-lanzar,
.ir-escritorio #rrBoton { left: auto; right: 12px; }
.ir-escritorio #fabNewTrip,
.ir-escritorio .fab-new-trip { right: auto; left: calc(var(--rail-w, 260px) + 12px); }

/* Y los avisos por encima de todo lo anterior. */
@media (max-width: 899px) {
  #toastContainer {
    bottom: calc(var(--nav-height, 64px) + var(--ir-pie) + var(--ir-hueco)
                 + var(--ir-tiles) + var(--ir-hueco) + 56px + var(--ir-hueco));
  }
}

/* El pie no se monta sobre nada: es el suelo, y ocupa su alto de verdad. */
.ir-footer-id {
  min-height: var(--ir-pie);
  box-sizing: border-box;
}

/* ══════════════════════════════════════════════════════════════════════════
   EL BOTÓN DE PLEGAR, POR ENCIMA DE LO QUE PLIEGA

   Medido en iPhone y en Android: **20 px de solape** entre
   `.fab-collapse-toggle` y `#locateBtn`, el primero de los tres controles del
   mapa.

   Y la aritmética lo dice sin ambigüedad. Los dos se anclan al borde inferior:

     `.map-controls`         bottom: nav + safe + 180   ·  alto 160
                             → ocupa de 180 a 340
     `.fab-collapse-toggle`  bottom: nav + safe + 320   ·  alto 48
                             → ocupa de 320 a 368

     solape = 340 − 320 = **20 px**

   El 320 se escribió cuando el grupo medía menos. Nadie rehizo la cuenta al
   añadirle el tercer botón. Es el mismo fallo que el `44px` fijo de la
   cabecera y que los cinco `bottom` de la franja inferior: **un número
   calculado a mano una vez, sobre un contenido que después creció**.

   Se calcula desde donde acaba el grupo, no desde un número suelto:
   180 (donde empieza el grupo) + 160 (lo que mide) + 8 (aire) = 348.
   ══════════════════════════════════════════════════════════════════════════ */
/* Y como los flotantes subieron, el grupo de controles del mapa sube con
   ellos: medido, `#truckRestrictBtn` quedaba **44x18 px detrás de «+ VIAJE»**.

   Todo se calcula desde la misma pila, de abajo arriba, para que no vuelva a
   descuadrarse cuando algo cambie de alto:

     flotantes  = nav + pie + hueco + tiles + hueco
     controles  = flotantes + alto del flotante + hueco
     plegar     = controles + alto del grupo   + hueco
*/
:root {
  --ir-flot-alto: 56px;      /* «+ VIAJE», el más alto de la fila */
  --ir-controles: 160px;     /* tres botones de 48 + dos huecos de 8 */
}
@media (min-width: 900px) {
  :root { --ir-controles: 226px; }   /* ahí miden 52 y hay más aire */
}

.map-controls {
  bottom: calc(var(--nav-height, 64px) + var(--ir-pie) + var(--ir-hueco)
               + var(--ir-tiles) + var(--ir-hueco)
               + var(--ir-flot-alto) + var(--ir-hueco));
}

.fab-collapse-toggle,
.r25-collapse-btn {
  bottom: calc(var(--nav-height, 64px) + var(--ir-pie) + var(--ir-hueco)
               + var(--ir-tiles) + var(--ir-hueco)
               + var(--ir-flot-alto) + var(--ir-hueco)
               + var(--ir-controles) + var(--ir-hueco));
}
@media (max-width: 899px) {
  .fab-collapse-toggle { right: 12px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   EL AVISO YA NO SE SIENTA ENCIMA DE LOS CONTROLES — y esta vez por geometría

   Historial honesto: este aviso se ha movido TRES veces esta sesión. Con
   12 px tapaba «Reportar». Con 84 px tapaba «+ VIAJE». Subido por encima de
   los tres flotantes, medido en iPhone 430×932:

       #toastContainer   x 12..418   y 608..654
       .map-controls     x 370..418  y 494..654     ← 48 px de solape

   Y `elementFromPoint` sobre `#truckRestrictBtn` devolvía `.toast-message`.
   O sea: mientras dura el aviso —y el más frecuente es «No se pudo obtener tu
   ubicación», justo cuando alguien va a tocar algo— el botón de restricciones
   de camión no se puede pulsar.

   Subirlo otra vez sería la cuarta ronda del mismo juego, y perdería igual:
   la columna de controles mide 160 px y el aviso es de ancho completo, así
   que en algún punto de esa franja se van a cruzar SIEMPRE.

   Se arregla por el otro eje. La columna de controles vive pegada a la
   derecha (48 px de ancho + 12 px de margen). El aviso se detiene antes de
   llegar: `right: 68px`. Ya no es una cuestión de a qué altura está — no
   comparten carril, y no lo harán aunque mañana la pila crezca.

   Queda ancho de sobra: en 360 px el aviso mide 280, que a 13 px son unos 40
   caracteres por línea. En 430, 350.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 899px) {
  #toastContainer {
    right: calc(12px + 48px + 8px);   /* margen + ancho de la columna + hueco */
  }
  /* Y la caja en sí no recibe toques; solo los avisos que hay dentro. Sin
     esto, una caja de 40vh de alto con `pointer-events: auto` sería una bomba
     de relojería el día que alguien la herede. */
  #toastContainer { pointer-events: none; }
  #toastContainer > * { pointer-events: auto; }
}

/* ══════════════════════════════════════════════════════════════════════════
   EL BOTÓN DE PLEGAR SIGUE A LO QUE PLIEGA

   `installFabCollapse()` pone `.collapsed` sobre `.map-controls`, que entonces
   mide ~0. Pero el botón se anclaba con `--ir-controles: 160px` fijo, así que
   al plegar quedaba flotando 160 px por encima de nada, en mitad del mapa.

   Nadie lo había reportado porque hay que plegar para verlo — y plegar es
   justo lo que hace quien tiene la pantalla llena, o sea quien más lo sufre.

   `:has()` lee el estado del hermano siguiente (Safari 15.4+, Chrome 105+).
   Si un navegador viejo no lo soporta, no aplica nada y se queda como estaba:
   el botón sigue donde está hoy, que es el comportamiento actual. Ninguna
   regresión, solo la mejora donde hay soporte.
   ══════════════════════════════════════════════════════════════════════════ */
body:has(.map-controls.collapsed) .fab-collapse-toggle,
body:has(.map-controls.collapsed) .r25-collapse-btn {
  /* Queda el `+ var(--ir-hueco)` del cálculo, o sea 8 px por encima del grupo
     plegado. Que es exactamente donde debe estar. */
  --ir-controles: 0px;
}

/* ══════════════════════════════════════════════════════════════════════════
   UNA HOJA ABIERTA MANDA SOBRE LOS BOTONES DEL MAPA

   Medido con la hoja de capas abierta, en iPhone 390×844 y en 1440×900:

     #panelLayers      z:1100
     #rrBoton          z:1150   ← 127×48 encima del contenido de la hoja
     .ir-footer-id     z:1199   ← 390×39 encima
     .bottom-nav       z:1200   ← 390×64 encima

   El botón «Reportar» quedaba flotando dentro de la hoja, tapando una fila
   entera de capas. No es un descuido de un archivo: son cuatro capas de
   z-index que crecieron por separado, cada una defendiéndose de la anterior.

   La regla que faltaba es de comportamiento, no de número: **cuando hay una
   hoja abierta, el mapa está tapado, así que sus botones no pintan nada.**
   Se van los cinco. Vuelven solos al cerrar.

   La barra de navegación y el pie SÍ se quedan encima: son la salida y la
   identidad legal, y taparlos deja a alguien dentro de una hoja sin puerta.
   Lo que se arregla es que la hoja no siga POR DEBAJO de ellos, que es lo que
   hacía con `bottom: 0` — su último renglón era inalcanzable.
   ══════════════════════════════════════════════════════════════════════════ */
body:has(.ir-pf5-panel.open) #rrBoton,
body:has(.ir-pf5-panel.open) .rr-lanzar,
body:has(.ir-pf5-panel.open) #fabNewTrip,
body:has(.ir-pf5-panel.open) .map-controls,
body:has(.ir-pf5-panel.open) .fab-collapse-toggle,
body:has(.ir-pf5-panel.open) .quick-tiles,
body:has(.bottom-sheet.open) #rrBoton,
body:has(.bottom-sheet.open) .rr-lanzar,
body:has(.bottom-sheet.open) #fabNewTrip,
body:has(.bottom-sheet.open) .map-controls,
body:has(.bottom-sheet.open) .fab-collapse-toggle,
body:has(.bottom-sheet.open) .quick-tiles {
  opacity: 0;
  pointer-events: none;
  /* `visibility` y no `display`: así la transición existe y no dan un salto
     al cerrar. Y `visibility: hidden` sí saca del orden de tabulación, que es
     lo que importa — un botón invisible que recibe el foco es peor que uno
     visible que estorba. */
  visibility: hidden;
  transition: opacity .18s ease;
}

/* ── Y ESTE ES EL ARREGLO QUE ME SALIÓ MAL A LA PRIMERA ────────────────────
   Escribí `bottom: calc(nav + pie)` sobre las hojas para que no quedaran por
   debajo de la barra. Medido acto seguido: **106 px de TODAS las hojas
   cerradas asomaban por abajo**, seis a la vez.

   La razón es que se esconden con `transform: translateY(100%)`, que las baja
   exactamente su propio alto. Eso oculta una hoja **solo si su borde inferior
   está en el borde de la pantalla**. Al subirla 106 px, `translateY(100%)` la
   deja 106 px por encima del borde… o sea, dentro.

   Mover el ancla rompe el escondite. Lo que hace falta no es mover la hoja
   sino **reservar sitio dentro de ella**: el último renglón deja de caer bajo
   la barra y el escondite sigue funcionando porque el ancla no se toca. */
.ir-pf5-body,
aside.bottom-sheet .sheet-content {
  padding-bottom: calc(var(--nav-height, 64px) + var(--ir-pie) + 16px);
}

@media (prefers-reduced-motion: reduce) {
  body:has(.ir-pf5-panel.open) .quick-tiles,
  body:has(.bottom-sheet.open) .quick-tiles { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   CON LA TARJETA DE UN LUGAR ABIERTA, LA FRANJA DE ABAJO ES SUYA

   `search.js` pone `ir-con-tarjeta` en el body y publica `--ir-tarjeta-alto`
   con el alto MEDIDO de la tarjeta en ese momento. Con eso:

     · Los botones flotantes del mapa se apartan, igual que con una hoja
       abierta: la tarjeta ES la tarea ahora mismo.
     · El aviso sube por encima de la tarjeta en vez de aterrizar sobre su
       botón principal. Medido en una captura: «Clima: sin conexión» cayó justo
       encima de «Cómo llegar».

   Cuarta y última vez que se toca la posición del aviso, y esta vez no es un
   número nuevo: es que la franja de abajo ahora tiene dueño declarado.
   ══════════════════════════════════════════════════════════════════════════ */
body.ir-con-tarjeta #rrBoton,
body.ir-con-tarjeta .rr-lanzar,
body.ir-con-tarjeta #fabNewTrip,
body.ir-con-tarjeta .quick-tiles,
body.ir-con-tarjeta .fab-collapse-toggle {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .18s ease;
}

body.ir-con-tarjeta #toastContainer {
  bottom: calc(var(--nav-height, 64px) + var(--ir-tarjeta-alto, 0px) + 24px);
}

/* Y los controles del mapa suben por encima de la tarjeta, que si no quedan
   detrás de ella justo cuando alguien quiere centrar el mapa en el sitio que
   acaba de encontrar. */
body.ir-con-tarjeta .map-controls {
  bottom: calc(var(--nav-height, 64px) + var(--ir-tarjeta-alto, 0px) + 24px);
}

/* ══════════════════════════════════════════════════════════════════════════
   CON EL PLANIFICADOR ABIERTO, EL AVISO NO SE SIENTA EN EL CAMPO DE DESTINO

   Medido tras pulsar «Cómo llegar»: `#irDirTo` —el campo que lleva la
   dirección que la persona acaba de elegir— devolvía `toast toast-error` en
   `elementFromPoint`. O sea que el aviso tapaba el destino justo en la
   pantalla donde se comprueba el destino.

   Misma solución que con la tarjeta y con las hojas: el aviso sube por encima
   de la superficie que manda en ese momento. Es la última franja donde faltaba.
   ══════════════════════════════════════════════════════════════════════════ */
body:has(#irDirectionsSheet.show) #toastContainer,
body:has(.ir-dir-sheet.show) #toastContainer {
  bottom: calc(var(--nav-height, 64px) + 72vh);
  max-height: 20vh;
  overflow: hidden;
}
