/* ==========================================================================
   CÁSCARA DE APLICACIÓN · cabecera de 56px, barra inferior de cuatro destinos,
   pie de una línea y el hueco que hay que reservar abajo.

   POR QUÉ ESTA HOJA EXISTE Y NO ESTÁ TODO EN `app.css`
   ---------------------------------------------------
   `app.css` está intocable mientras dure este trabajo: lo tiene el agente de la
   portada. Todo lo que aquí haría falta escribir allí —tokens nuevos, geometría
   de la cáscara— vive en esta hoja, que se carga DESPUÉS. La fase 5 la dobla
   dentro de `app.css` el día que ese agente la suelte.

   POR QUÉ AQUÍ NO HAY NI UN HEXADECIMAL
   -------------------------------------
   Riesgo 1 del apartado 10 de la especificación. Los tokens que usa esta hoja
   —`--r-3`, `--r-pill`, `--btn-fill`, `--btn-ink`, `--teal-strong`, `--ink`,
   `--ink-soft`, `--line-soft`, `--sh-s`, `--fs-micro`, `--fs-h3`, `--fw-bold`,
   `--sp-*`, `--pad`, `--focus`, `--surface`, `--bg`— viven todos en el `:root`
   de `app.css`. Si el agente de la portada renombra uno, con `var()` el fallo
   se ve de golpe —el estilo desaparece— y con un hexadecimal copiado sería una
   desincronización silenciosa: un color parecido, y nadie se entera.

   La ÚNICA excepción es la sombra hacia arriba de `.nav-app`, que la
   especificación escribe literal en 5.3 y para la que no existe token: se copia
   tal cual y no se inventa uno nuevo.

   La cáscara se ve SIEMPRE, instalada o no (decisión 1 del dueño): aquí no hay
   ni una consulta de `display-mode`.
   ========================================================================== */


/* ==========================================================================
   1 · TOKENS DE LA BARRA INFERIOR
   ========================================================================== */

:root{
  /* EL REPARTO, AHORA EN TOKENS Y NO EN UN COMENTARIO.
     Antes aquí había un `76px` escrito a mano y, al lado, un comentario que
     pedía por favor que nadie tocara ninguna de las cuatro cifras sin volver a
     sumar. Eso funciona hasta la primera vez que alguien cambia el interlineado
     del rótulo y no vuelve. Ahora las cuatro cifras son tokens y el alto es la
     suma: si se cambia una, el hueco reservado abajo cambia solo y no pueden
     divergir.

       5  relleno superior     --nav-app-pad-t   → .nav-app{padding-top}
     + 54  fila de iconos      --nav-app-fila    → .nav-app-icono, .barra-app-circulo
     +  4  hueco icono↔rótulo  --nav-app-gap     → .nav-app-dest{gap}
     + 13  línea del rótulo    --nav-app-lh      → .nav-app-txt{line-height}
     ────
       76  --nav-app-h                                                         */
  --nav-app-pad-t:5px;
  --nav-app-fila:54px;
  --nav-app-gap:4px;
  --nav-app-lh:13px;
  --nav-app-h:calc(var(--nav-app-pad-t) + var(--nav-app-fila)
                 + var(--nav-app-gap)   + var(--nav-app-lh));

  /* El relleno de abajo. La versión anterior era `env(safe-area-inset-bottom)`
     a secas, y ahí hay un caso que no cubre: en un Android con navegación por
     botones —y en cualquier navegador donde `env()` devuelve 0— el rótulo se
     queda apoyado en el canto físico de la pantalla. Ninguna barra de
     aplicación hace eso. 4px es el mínimo, y la zona segura manda en cuanto
     existe.

     Que sea un token, y no un número escrito dos veces, es lo que garantiza
     que el hueco reservado siga cuadrando: los dos salen de aquí. */
  --nav-app-pad-b:max(4px, env(safe-area-inset-bottom));

  /* Cuánto sube el círculo de «Crear» por encima de su fila.
     ES EL ÚNICO NÚMERO DE TODA LA BARRA QUE SE PUEDE MOVER A OJO: subirlo hace
     el círculo más saliente, bajarlo lo devuelve a ras. No afecta a ninguna
     otra medida —el círculo se eleva con `transform`, que no ocupa sitio— así
     que cambiarlo no obliga a recalcular ni el alto de la barra ni el hueco. */
  --nav-app-elev:10px;

  /* NO HAY TOKEN PARA EL DIÁMETRO DEL CÍRCULO, y es deliberado: es
     EXACTAMENTE `--nav-app-fila`, y tener un segundo nombre para el mismo
     número es tener dos números en cuanto alguien cambie uno. Si el círculo
     fuera más alto que su fila, empujaría su propio rótulo hacia abajo y
     «Crear» dejaría de compartir línea de base con los otros cuatro — que es la
     corrección 2 a la maqueta y el motivo por el que se escribió todo esto.
     (El antiguo `--nav-app-fab` se retira con la clase `.nav-app-fab`, que la
     plantilla ya no emite: ahora es `.barra-app-circulo`.) */

  /* LO QUE EL CÍRCULO SOBRESALE POR ENCIMA DEL CANTO DE LA BARRA.
     Los primeros 5px de la elevación se los come el relleno superior de la
     barra: el círculo sube dentro de su propia casilla antes de salirse. Lo que
     asoma de verdad es lo que pase de ahí, y sólo eso hay que reservar.

     Se calcula en vez de escribirse porque `--nav-app-elev` es el único número
     que este fichero invita a mover a ojo: si alguien lo sube a 20, el saliente
     pasa a 15 y el hueco reservado se entera solo. Con la cifra escrita a mano,
     no se enteraría — y el círculo taparía la última línea de la pantalla, que
     es exactamente el fallo que este bloque de tokens existe para impedir.

     `max(0px, …)` porque con la elevación por debajo del relleno el círculo no
     sobresale nada y la resta saldría negativa. */
  --nav-app-saliente:max(0px, var(--nav-app-elev) - var(--nav-app-pad-t));

  /* Lo que hay que reservar abajo para que la barra no tape nada.
     76 + 5 de saliente + 34 de zona segura = 115px, en línea con la barra de
     iOS (49+34) y con la de Material (80). */
  --nav-app-hueco:calc(var(--nav-app-h) + var(--nav-app-pad-b)
                     + var(--nav-app-saliente));
}

/* FALLO #22 · a partir de 820px la barra no existe, así que el hueco tampoco.
   Sin esto `--nav-app-hueco` seguiría valiendo 76px + zona segura en escritorio
   y todo lo que se ancla a él —el `padding-bottom` del body, la tarjeta de
   instalar de la fase 3— reservaría 76px de nada. Se pone a 0 y todos los
   `calc()` que lo usan se colapsan solos, sin repetir ninguna regla. */
@media (min-width:820px){ :root{ --nav-app-hueco:0px } }


/* ==========================================================================
   2 · LA CABECERA DE LA APLICACIÓN
   ========================================================================== */

/* `position:sticky` REVOCA a propósito `ESPECIFICACION-MOVIL.md:534-536`. El
   motivo es concreto: en la aplicación instalada no hay botón de atrás del
   navegador, así que la flecha de esta cabecera es la ÚNICA salida de
   `/acuerdos/{id}` y de `/nuevo`. Perderla al bajar es un callejón sin salida. Y
   con el teclado abierto en `/nuevo` la barra inferior se aparta (bloque 5), o
   sea que la cabecera es el único cromo que queda en pantalla.

   Sin hairline inferior y sin sombra: medido sobre la maqueta, esa hairline no
   existe —la columna que pasa entre el título y el primer contenido es crema
   uniforme—. Fondo `--bg` opaco y ya está. Opaco no es cosmético: es lo que
   impide que el contenido se vea pasar por debajo al desplazar.

   z-index 50: por encima de la pantalla y por debajo de la barra inferior (60),
   que es la que nunca puede quedar tapada. */
.cabecera-app{
  position:sticky;top:0;z-index:50;
  background:var(--bg);

  /* LA ZONA SEGURA DE ARRIBA. Falta esto y la aplicación instalada empieza
     PEGADA a la hora y a la batería: el documento declara `viewport-fit=cover`,
     así que en modo autónomo el contenido arranca en el píxel 0, por debajo de
     la barra de estado, y el logotipo queda medio tapado por el reloj. Es de
     las cosas que más delatan que lo que se ha instalado es una web.

     En una pestaña normal `env(safe-area-inset-top)` vale 0 —de eso ya se
     ocupa el navegador con su propia interfaz— así que esta línea sólo hace
     algo donde hace falta y no descuadra nada en el resto. */
  padding-top:env(safe-area-inset-top);

  /* El cromo no se selecciona ni parpadea al tocarlo. El contenido de la
     pantalla no entra aquí: sigue siendo texto que se puede marcar y copiar. */
  -webkit-tap-highlight-color:transparent;
  -webkit-user-select:none;
  user-select:none;
}

/* Rejilla de tres columnas, alto 56px.
   `min-height` y no `height` porque a partir de 820px esta misma cabecera se
   lleva los cuatro destinos de la barra y tiene que poder crecer. Por debajo de
   820px el contenido nunca pasa de 56px —el título no envuelve, ver abajo—, así
   que ahí mide 56 clavados, que es lo que comprueba la verificación 11.4. */
.cabecera-app-in{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;
  gap:var(--sp-2);
  min-height:56px;
}

/* OJO AL NOMBRE. La variante de la cabecera y el control de volver comparten
   clase: `<header class="cabecera-app cabecera-app-atras">` y dentro
   `<a class="cabecera-app-atras">`. Por eso el header se selecciona siempre con
   las dos clases juntas y el control siempre como hijo de `.cabecera-app-in`.
   No se toca uno creyendo tocar el otro. */

/* En la variante `atras` la tercera columna EXISTE aunque esté vacía, o el
   título no queda centrado respecto al marco. Medido en la maqueta: «Detalle
   del acuerdo» está centrado respecto al MARCO, no respecto al hueco que deja
   la flecha. Se consigue declarando las tres pistas explícitas: una pista
   declarada existe aunque ningún hijo caiga dentro —y en móvil los destinos van
   `display:none`, o sea que salen de la rejilla y no pueden hacer de tercera
   columna—. `minmax(44px,auto)` para que en escritorio esa tercera pista pueda
   crecer y acoger la fila de destinos. */
.cabecera-app.cabecera-app-atras .cabecera-app-in{
  grid-template-columns:minmax(44px,auto) minmax(0,1fr) minmax(44px,auto);
}

/* 44px es la zona táctil mínima, no el tamaño del dibujo: la flecha mide 24. */
.cabecera-app-in > .cabecera-app-atras{
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;
  margin-inline-start:calc(var(--sp-3) * -1);   /* alinea el DIBUJO con el
                                                   margen, no la zona táctil */
  padding:0;border:0;background:none;
  color:var(--ink);text-decoration:none;cursor:pointer;
  border-radius:var(--r-pill);
}
.cabecera-app-in > .cabecera-app-atras svg{width:24px;height:24px}

/* FALLO #20 · EL TÍTULO NO ENVUELVE NUNCA. Obligatorio.
   A 320px quedan 280 − 88 = 192px para el texto, y «Detalle del acuerdo» son 19
   caracteres en `--fs-h3` con `font-weight:var(--fw-black)` por la regla
   `h1,h2,h3` de `app.css:247` —que además lleva `text-wrap:balance`, o sea que
   FAVORECE el corte en dos líneas equilibradas—. No cabe, envuelve, y la
   cabecera deja de medir 56px justo en la variante que el dueño pidió que fuera
   una sola línea. `text-wrap:nowrap` es lo que gana a `balance`. */
.cabecera-app-titulo{
  min-width:0;
  white-space:nowrap; text-wrap:nowrap;
  overflow:hidden; text-overflow:ellipsis;

  /* DESVIACIÓN CONSCIENTE DE LA MAQUETA. Dibuja «Cuenta» a unos 26-28px: eso es
     un H1 de página puesto donde va un título de barra. Con 26px la cabecera
     dejaría de medir 56 y en `/cuenta` la tira de seis pestañas caería por
     debajo del pliegue. Se usa `--fs-h3`. */
  font-size:var(--fs-h3);
  line-height:1.25;                 /* fijo, o el alto de la barra depende de la
                                       métrica de la fuente que haya cargado */
  text-align:center;
}

/* La variante `titulo` no lleva flecha: el título arranca en el margen. */
.cabecera-app-titulo-izq{text-align:start}

/* El logotipo, al mismo tamaño que en la web de venta por debajo de 640px
   (`app.css:993`), para que cambiar de una cáscara a otra no dé un salto. */
.cabecera-app-marca{
  display:inline-flex;align-items:center;
  text-decoration:none;
}
.cabecera-app-marca img{
  display:block;
  height:1.75rem;width:auto;
  object-fit:contain;
}

/* Los cuatro destinos, cuando suben a la cabecera. Por debajo de 820px están en
   la barra inferior y aquí NO se dibujan: si no, saldrían dos veces. */
.cabecera-app-nav{display:none}
@media (min-width:820px){
  /* Una barra inferior fija en una pantalla de 27 pulgadas es una maqueta de
     móvil pegada donde no toca. Los destinos se buscan aquí arriba con el
     ratón. */
  .cabecera-app-nav{
    display:flex;align-items:center;justify-content:flex-end;
    gap:var(--sp-2);
    flex-wrap:wrap;
  }
}

/* Los destinos, ya en la cabecera. Se visten como la navegación de la web de
   venta (`app.css`, `.nav a`) y no como otra cosa: son los mismos enlaces y
   pasar de una cáscara a otra no puede dar un salto. El activo se marca con el
   mismo par teal + tinte que usa la barra inferior, para que «dónde estoy» se
   diga igual en los dos sitios.

   `aria-current` y no una clase: el destino activo lo marca `Navegacion` en el
   servidor y aquí sólo se pinta lo que venga marcado. Es la misma regla que
   abajo. */
.cabecera-app-nav-dest{
  display:inline-flex;align-items:center;
  padding:.55em .9em;border-radius:var(--r-pill);
  font-size:var(--fs-small);font-weight:var(--fw-bold);line-height:1;
  color:var(--ink-soft);text-decoration:none;white-space:nowrap;
  transition:color .16s ease,background-color .16s ease;
}
.cabecera-app-nav-dest:hover{color:var(--teal-ink);background:var(--tint-teal)}
.cabecera-app-nav-dest[aria-current="page"]{
  color:var(--teal-strong);background:var(--tint-teal);font-weight:var(--fw-black);
}
.cabecera-app-nav-dest:focus-visible{outline:3px solid var(--focus);outline-offset:2px}

/* «Crear» ya es un `.btn .btn-1 .btn-sm`: aquí sólo se le da el aire que lo
   separa de los destinos, para que se lea como la acción y no como un quinto
   enlace que resulta que va pintado. */
.cabecera-app-nav-crear{margin-inline-start:var(--sp-2)}


/* ==========================================================================
   3 · LA BARRA INFERIOR
   ========================================================================== */

.nav-app{
  position:fixed;left:0;right:0;bottom:0;z-index:60;

  /* CINCO COLUMNAS IGUALES, SIN CONTAR HASTA CINCO.
     Antes había un `repeat(4,1fr)` escrito a mano y el día que la barra pasó a
     cinco destinos el quinto se cayó a una segunda fila. Con reparto automático
     por columnas la rejilla no sabe cuántos destinos hay ni le hace falta: crea
     una columna por hijo y todas miden lo mismo. Cuatro, cinco o los que
     vengan.

     `minmax(0,1fr)` y no `1fr` a secas, y esto sí importa a 320px: `1fr` es en
     realidad `minmax(auto,1fr)`, o sea que una columna NO se encoge por debajo
     de su contenido. Con cinco rótulos eso significa que el más largo empuja a
     los demás, las columnas dejan de ser iguales y la barra desborda a lo
     ancho. Con el mínimo en 0 la rejilla manda siempre y ninguna columna puede
     estirar la barra. */
  display:grid;
  grid-auto-flow:column;
  grid-auto-columns:minmax(0,1fr);

  background:var(--surface);
  border-radius:var(--r-3) var(--r-3) 0 0;    /* SÓLO las esquinas de arriba */

  /* Sombra hacia arriba, sin borde. Es el único valor de color literal de toda
     la hoja: la especificación lo escribe así en 5.3 y no hay token de sombra
     ascendente al que apuntar. Inventar uno aquí sería inventarlo en el sitio
     equivocado, porque los tokens viven en `app.css`. */
  box-shadow:0 -1px 12px rgba(15,74,97,.06);

  padding-top:var(--nav-app-pad-t);
  padding-bottom:var(--nav-app-pad-b);   /* zona segura, con 4px de suelo: ver
                                            el token, no es lo mismo que env() */
  /* En horizontal, el notch se come el primer destino si no se aparta. */
  padding-inline:env(safe-area-inset-left) env(safe-area-inset-right);

  transition:transform .18s ease;

  /* La barra es cromo puro: ni se selecciona, ni parpadea, ni espera a ver si
     el toque era un doble toque para ampliar. */
  -webkit-tap-highlight-color:transparent;
  -webkit-user-select:none;
  user-select:none;
}

.nav-app-dest{
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  gap:var(--nav-app-gap);
  min-width:0;                      /* el compañero del `minmax(0,1fr)`: un
                                       elemento flex tampoco encoge por debajo
                                       de su contenido mientras esto valga auto */
  text-decoration:none;color:var(--ink);
  min-height:44px;                  /* zona táctil, aunque el icono mida 24 */
  touch-action:manipulation;
  -webkit-touch-callout:none;
}

/* La fila de iconos mide lo que mide el círculo. Es la CORRECCIÓN 2 a la
   maqueta, y es deliberada: allí «Crear» queda unos 8px por debajo de los otros
   rótulos, porque el círculo es más alto que los iconos y empuja el suyo hacia
   abajo. En un teléfono con barra de gestos eso mete el rótulo dentro de la
   zona segura. Igualando las alturas, los 24px de los demás quedan centrados y
   los cinco rótulos comparten línea de base. */
.nav-app-icono,
.barra-app-circulo{
  height:var(--nav-app-fila);
  display:inline-flex;align-items:center;justify-content:center;
  flex:none;
}
.nav-app-icono svg,
.barra-app-circulo svg{width:24px;height:24px}

/* GUARDA. Hoy `.nav-app-icono` es un `<span>` que hace de casilla y el dibujo
   va dentro. Si algún día la clase acabara puesta sobre el propio `<svg>` —es
   el atajo evidente al tocar la plantilla— la regla de arriba le daría 54px de
   alto al dibujo y el icono saldría gigante y deformado. Un selector de
   elemento más clase (0,1,1) gana a la clase sola (0,1,0) y lo devuelve a su
   tamaño. Hoy no casa con nada y no cuesta nada. */
svg.nav-app-icono{width:24px;height:24px}

/* Transición declarada en el icono y no en el enlace: lo único que se mueve al
   pulsar es el dibujo. */
.nav-app-icono{transition:transform .14s cubic-bezier(.2,.8,.3,1)}

/* ══════════════════════════════════════════════════════════════════════════
   EL CÍRCULO DE «CREAR» · ELEVADO Y CENTRADO

   Sube con `transform` y NO con un margen negativo, y ésa es toda la decisión
   de este bloque. Un margen negativo saca al círculo de su sitio dentro del
   flujo y arrastra consigo lo que viene detrás: el rótulo «Crear» subiría los
   mismos 10px y dejaría de compartir línea de base con los otros cuatro, que es
   exactamente el defecto que la corrección 2 a la maqueta existe para evitar.
   `transform` pinta en otro sitio pero no ocupa otro sitio: la casilla del
   círculo sigue midiendo lo que medía, el rótulo no se entera, y el alto de la
   barra —y con él el hueco reservado abajo— no cambia ni un píxel.

   Centrado sale gratis: la rejilla reparte cinco columnas iguales y «Crear» es
   la tercera, así que el círculo cae en el eje de la barra sin colocar nada a
   mano. Si algún día son seis destinos, dejará de estar centrado y habrá que
   decidir otra cosa; con cinco, no hay nada que ajustar.

   `--sh-m` y no `--sh-s`: la sombra es lo que hace que se lea como que sale de
   la barra. Con la sombra pequeña, elevarlo sólo parece un error de alineación.
   ══════════════════════════════════════════════════════════════════════════ */
.barra-app-circulo{
  width:var(--nav-app-fila);       /* el mismo número que su alto: es un círculo
                                      y tiene que caber en su fila */
  background:var(--btn-fill);color:var(--btn-ink);
  border-radius:var(--r-pill);
  box-shadow:var(--sh-m);
  transform:translateY(calc(var(--nav-app-elev) * -1));
  transition:transform .14s cubic-bezier(.2,.8,.3,1),background-color .14s ease;
}

/* PULSADO. El círculo se hunde sin perder la elevación —se repite el
   `translateY`, porque `transform` es una sola propiedad y lo que no se repita
   desaparece— y los demás iconos encogen. Es la respuesta inmediata que en
   táctil no da el `:hover`, que allí no existe. */
.nav-app-dest:active .nav-app-icono{transform:scale(.88)}
.barra-app-crear:active .barra-app-circulo{
  transform:translateY(calc(var(--nav-app-elev) * -1)) scale(.92);
}

/* Una de las cuatro cifras del reparto de `--nav-app-h`, ahora por token: si se
   cambia el interlineado hay que cambiarlo allí y el alto se recalcula solo. */
.nav-app-txt{
  font-size:var(--fs-micro);font-weight:var(--fw-bold);
  line-height:var(--nav-app-lh);
  color:var(--ink);
  letter-spacing:-.01em;
  /* NO ENVUELVE NUNCA, y esto es estructural y no estético: el reparto de
     `--nav-app-h` cuenta UNA línea de rótulo. En cuanto uno se parte en dos, la
     barra crece 13px, el hueco reservado abajo sigue reservando los de antes y
     la barra vuelve a tapar la última línea de la pantalla — que es el fallo
     que toda esta hoja está escrita para evitar. */
  max-width:100%;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}

/* ══════════════════════════════════════════════════════════════════════════
   CINCO RÓTULOS A 320px · LA CUENTA

   Con cinco columnas en la pantalla más estrecha que existe, cada destino
   dispone de 320/5 = 64px. El rótulo más largo es «Acuerdos», ocho caracteres
   en `--fw-bold`. A `--fs-micro` (0,82rem = 13,1px) mide unos 59px: entra por
   5px, y eso contando con que el tipo del sistema sea el que esperamos. En
   cuanto el usuario tiene el tamaño base del navegador por encima de 16px, no
   entra, y con `white-space:nowrap` lo que antes era una segunda línea pasa a
   ser puntos suspensivos en «Acuerdo…», que es peor.

   Así que el rótulo se mide en función del ancho REAL y no del que suponemos.
   `3.1vw` es el ancho de columna (20 % de la pantalla) menos el aire que hace
   falta a los lados; el suelo de 10px es el mismo cuerpo que usa la barra de
   pestañas de iOS, o sea que no es una talla inventada para salir del paso.

       320px → 10,0px   360px → 11,2px   390px → 12,1px
       412px → 12,8px   424px en adelante → 13,1px (el tope, `--fs-micro`)

   La consulta es `[data-destinos="5"]` y no la barra entera a propósito: con
   cuatro destinos las columnas son de 80px y el rótulo cabe a tamaño completo
   en cualquier teléfono. Encogerlo allí sería empeorar lo que ya estaba bien.
   ══════════════════════════════════════════════════════════════════════════ */
.nav-app[data-destinos="5"] .nav-app-txt{
  font-size:clamp(10px, 3.1vw, var(--fs-micro));
}

/* ACTIVO · dos cosas a la vez, igual que en la maqueta: el icono pasa de
   contorno a relleno y el par icono+rótulo pasa a teal. Sin pastilla de fondo,
   sin barrita y sin punto.

   El inactivo de la maqueta es un gris pizarra que el proyecto no tiene: se usa
   `--ink`. Efecto secundario que hay que saber: el activo queda MÁS CLARO que
   el inactivo (6,0:1 frente a 9,2:1), que es exactamente lo que hace la maqueta.

   El destino activo sale del mapa de `Navegacion`, nunca de la URL: aquí sólo
   se pinta lo que ya venga marcado con `aria-current`. */
.nav-app-dest[aria-current="page"]{color:var(--teal-strong)}
.nav-app-dest[aria-current="page"] .nav-app-txt{color:var(--teal-strong)}
/* `.nav-app-icono .relleno` y no `.nav-app-icono svg .relleno`: el descendiente
   directo cubre las dos formas posibles del marcado —la clase en el `<span>`
   que envuelve, que es la de hoy, y la clase en el propio `<svg>`— sin que
   ninguna de las dos se quede sin estado activo.

   Y esto NO da por hecho que todos los iconos se rellenen: sólo actúa sobre las
   partes marcadas con `.relleno`. `sx-ayuda` —la interrogación de Soporte— no
   tiene ninguna a propósito, así que al activarse sólo cambia de color, que es
   lo que hace también `sx-lista`. El cambio de color lo lleva la regla de
   arriba y llega a los trazos por `currentColor`, no por esta. */
.nav-app-dest[aria-current="page"] .nav-app-icono .relleno{fill:currentColor;stroke:none}

/* `outline-offset` negativo, al revés que la regla global de `app.css:250`: con
   los 3px de fuera, el foco del último destino se dibujaría fuera de la barra y
   por debajo del canto de la pantalla. */
.nav-app-dest:focus-visible{
  outline:3px solid var(--focus);
  outline-offset:-3px;
  border-radius:var(--r-2);
}


/* ==========================================================================
   4 · EL PIE DE LA CÁSCARA
   ========================================================================== */

/* Una línea, tipografía micro, centrada, sobre `--bg`. Sale sólo en las
   pantallas SIN barra inferior, así que aquí no hay nada que reservar: la zona
   segura se la come el propio relleno de abajo.

   EL AIRE DE ARRIBA Y LA HAIRLINE SON EL ARREGLO DE «PEGADO AL PIE».
   El pie tenía 24px de relleno superior y nada más. Lo que hay justo encima
   depende de la pantalla —en `/entrar` es el panel oscuro, con su rótulo y sus
   enlaces en teal— y con 24px de separación esos enlaces se leen como si
   formaran parte del pie: dos bloques de letra pequeña, uno debajo del otro,
   sin nada que diga dónde acaba el contenido y dónde empieza la letra legal.

   Se arregla en el pie y no tocando lo que hay encima a propósito: así vale
   para CUALQUIER cosa que quede la última, hoy y cuando cambie. `--sp-6` de
   margen separa, la hairline explica por qué están separados, y el relleno
   superior sube a `--sp-5` para que la línea no quede pegada a los enlaces. */
.pie-app{
  margin-top:var(--sp-6);
  border-top:1px solid var(--line-soft);
  background:var(--bg);
  padding:var(--sp-5) var(--pad) max(var(--sp-5),env(safe-area-inset-bottom));
  font-size:var(--fs-micro);
  line-height:1.5;
  text-align:center;
  color:var(--ink-soft);
  -webkit-tap-highlight-color:transparent;
}

/* Los enlaces legales y sus puntos separadores. Envuelven en cuanto no caben,
   y al envolver los separadores quedan al final de la línea: es feo pero es
   inequívoco, y la alternativa —esconderlos por posición— exige contarlos. */
.pie-app-in{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:var(--sp-1) var(--sp-2);
  max-width:var(--wrap);
  margin-inline:auto;
}
.pie-app-sep{
  color:var(--line-strong);
  -webkit-user-select:none;
  user-select:none;
}
.pie-app a{
  color:var(--ink-soft);
  text-decoration:underline;
  text-underline-offset:2px;
  /* Zona táctil: un enlace de 13px en una fila de enlaces de 13px es imposible
     de acertar con el pulgar. El relleno vertical no descuadra la fila porque
     `.pie-app-in` centra por eje transversal. */
  display:inline-block;
  padding-block:var(--sp-1);
  touch-action:manipulation;
}
.pie-app a:hover{color:var(--teal-strong)}
.pie-app a:active{color:var(--teal-strong)}


/* ==========================================================================
   5 · ÁREA SEGURA, HUECO RESERVADO Y TECLADO
   --------------------------------------------------------------------------
   RIESGO ESCRITO QUE HAY QUE RESPETAR. `app-ui.css` documenta que la
   `.barra-acciones` del asistente estuvo pegada abajo con `position:sticky` y
   hubo que quitarlo porque tapaba las últimas filas de la lista y se comía sus
   clics, «que es el peor fallo posible en una pantalla donde marcar una casilla
   ES la acción». Ahora vuelve a haber algo anclado a ese borde. El hueco
   reservado, el `scroll-padding-bottom` y el apartado con el teclado NO son
   opcionales: son la condición de que aquello no se repita.
   ========================================================================== */

@media (max-width:819px){
  /* El hueco. Aquí SÍ puede ir en el `body`, al revés que con el banner de
     cookies (`app.css:1114-1119`): en la cáscara de aplicación el pie de tres
     columnas no existe, así que no queda una franja de otro color por debajo. */
  body:has(.nav-app){padding-bottom:var(--nav-app-hueco)}

  /* El simétrico del `scroll-padding-top` que ya existe (`app.css:337`), o el
     último campo de un formulario aterriza detrás de la barra al recibir el
     foco. */
  html:has(.nav-app){scroll-padding-bottom:var(--nav-app-hueco)}

  /* Y el de arriba, que `app.css:337` sólo declara a partir de 820px: esta
     cabecera es sticky también en móvil, así que sin esto un salto a un ancla
     deja el destino escondido detrás de ella.

     Los 56px van con la zona segura sumada, por lo mismo que la cabecera lleva
     ahora `padding-top`: en la aplicación instalada la cabecera mide 56 MÁS lo
     que ocupe la barra de estado, y sin sumarlo un ancla aterriza detrás del
     reloj. */
  html:has(.cabecera-app){
    scroll-padding-top:calc(56px + env(safe-area-inset-top));
  }
}

/* A partir de 820px la barra no existe y sus destinos suben a la cabecera.
   `--nav-app-hueco` ya vale 0px ahí (bloque 1), así que nada más que hacer. */
@media (min-width:820px){ .nav-app{display:none} }

/* SE APARTA CON EL TECLADO VIRTUAL, sin una línea de JavaScript.
   Sólo `input` y `textarea`, y no `:focus` a secas: con cualquier `:focus` la
   barra desaparecería al tabular por ella misma, o sea justo cuando alguien que
   navega con teclado la está usando. */
body:has(.pantalla :is(input,textarea):focus) .nav-app{transform:translateY(120%)}

@media (prefers-reduced-motion:reduce){
  .nav-app{transition:none}
  .nav-app-icono,
  .barra-app-circulo{transition:none}
  /* El icono deja de encoger al pulsar. El círculo NO puede quedarse en
     `transform:none`: su elevación también es un `transform`, así que anularlo
     lo devolvería a ras y se perdería la forma de la barra, que no es
     movimiento sino disposición. Se repite la elevación sin la escala. */
  .nav-app-dest:active .nav-app-icono{transform:none}
  .barra-app-crear:active .barra-app-circulo{
    transform:translateY(calc(var(--nav-app-elev) * -1));
  }
}


/* ==========================================================================
   6 · LA CÁSCARA OCUPA LA PANTALLA ENTERA

   `100dvh` Y NO `100vh`, que es la diferencia entre una aplicación y una web.
   `vh` es el alto del área visible con la interfaz del navegador RETRAÍDA: un
   valor que en un móvil casi nunca es el que hay en pantalla. Peor todavía con
   el teclado abierto, porque `vh` no se entera de que el teclado existe: la
   pantalla no se recorta, el botón de «Entrar» se queda por debajo del teclado
   y hay que cerrarlo para poder pulsarlo. Es EL fallo que delata una web, y
   pasa justo en `/entrar`, que es la primera pantalla que ve alguien.
   `dvh` es el alto real en cada momento y se actualiza con el teclado.

   Se declaran los dos, en este orden: el navegador que no entienda `dvh`
   descarta la segunda línea y se queda con el comportamiento de siempre.

   Y la cáscara en columna flexible: sin esto, en una pantalla corta —`/soporte`,
   un estado vacío— el pie se queda flotando a media altura con el fondo de la
   página por debajo, que es lo que hace una web y no una aplicación. Con
   `flex:1` en la pantalla, el contenido empuja el pie hasta abajo siempre.

   Todo colgado de `:has(.cabecera-app)` para que la web de venta —que no carga
   esta hoja, pero por si algún día la carga— no se vea afectada.
   ========================================================================== */

body:has(.cabecera-app){
  display:flex;
  flex-direction:column;
  min-height:100vh;
  min-height:100dvh;
}
/* `.pantalla` es `<main>`, hijo directo del `body`. `1 0 auto` y no `1 1 auto`:
   con `flex-shrink:1` una pantalla más alta que el hueco se comprimiría en vez
   de desplazarse, y el final del formulario quedaría recortado. */
body:has(.cabecera-app) > .pantalla{flex:1 0 auto}

/* EL REBOTE ELÁSTICO Y EL «TIRAR PARA RECARGAR».
   Dos gestos del navegador que ninguna aplicación tiene: arrastrar la página
   entera más allá de su final hasta ver el fondo del navegador, y tirar desde
   arriba para recargar. Dentro de la cáscara los dos son accidentes: el
   segundo, además, tira abajo el estado de la pantalla en la que estabas.
   Se apaga en `html` porque es de ahí de donde el navegador toma el
   comportamiento del área visible. */
html:has(.cabecera-app){overscroll-behavior-y:none}

/* Los nombres de las transiciones de vista. El bloque que las enciende está en
   `app.css`; aquí sólo se marcan los dos elementos que tienen que PERSISTIR
   entre páginas. Sin nombre, la barra inferior se funde con todo lo demás y
   parpadea en cada toque; con nombre, se queda quieta y sólo cambia el destino
   marcado — que es lo que hace una aplicación con pestañas.

   Dentro de la guarda de movimiento, como el bloque que los usa: un nombre sin
   transición no hace nada, pero declararlos juntos evita que alguien encienda
   una cosa y no la otra. */
@media (prefers-reduced-motion: no-preference){
  .cabecera-app{view-transition-name:cascara-cabecera}
  .nav-app{view-transition-name:cascara-barra}
}

/* El `:hover` pegajoso del táctil, en las piezas de esta hoja. Ver el bloque
   «PUNTERO QUE NO SE POSA» al final de `app.css` para el porqué. */
@media (hover:none){
  .cabecera-app-nav-dest:hover{background:none;color:var(--ink-soft)}
  .cabecera-app-nav-dest[aria-current="page"]:hover{
    background:var(--tint-teal);color:var(--teal-strong);
  }
}
