/* El armazón de secciones, para las DOS caras.
 *
 * Dos secciones una al lado de la otra. En el móvil la pantalla se reparte con
 * un flex de alto fijo —cabecera arriba, barra abajo, y en medio el carrusel,
 * que es lo único que se mueve—; en pantalla ancha el carrusel no existe y
 * manda la pestaña de arriba.
 *
 * Va aquí y no dentro de la hoja del comité porque la cara pública tiene
 * exactamente lo mismo: portada y calendario. Los colores salen de las
 * variables de cada cara, que ya son las mismas, así que esta hoja no sabe
 * nada del tema claro ni del oscuro.
 *
 * Lo que NO está aquí: la piel de la cabecera. El comité tiene su barra azul y
 * la cara pública la suya; lo que se comparte es cómo se reparte la pantalla.
 */

.hidden { display: none !important; }

/* ------------------------------------------------------------- secciones */
/* Las dos mitades de la aplicación. En pantalla ancha van en la cabecera; en
   el móvil se esconden y mandan las de la barra de abajo.

   En el móvil se puede además pasar deslizando, pero el gesto va SUMADO a las
   pestañas, nunca en su lugar: un gesto no se ve, así que no puede ser la
   única forma de llegar a media aplicación. Y con ratón no existe. */

.secciones { display: flex; gap: 6px; margin-right: auto; }

.seccion {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: transparent;
  color: rgba(255, 255, 255, .78);
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
}
.seccion svg { width: 18px; height: 18px; flex: none; }
/* Sólo con ratón: en una pantalla táctil el "hover" se dispara al tocar y se
   queda encendido después, que es justo lo contrario de lo que dice. */
@media (hover: hover) and (pointer: fine) {
  .seccion:hover { background: rgba(255, 255, 255, .12); color: #fff; }
}
.seccion.on {
  background: rgba(255, 255, 255, .16);
  border-color: rgba(255, 255, 255, .4);
  color: #fff;
}
/* El color cambia, no salta. Y al pulsar se hunde un pelo: es la señal de que
   la interfaz ha oído el dedo, y llega antes que cualquier otra cosa. */
.seccion { transition: background-color 160ms ease, color 160ms ease, transform 160ms cubic-bezier(.23, 1, .32, 1); }
.seccion:active { transform: scale(.97); }

/* ------------------------------------------ los iconos dicen dónde estás
 *
 * Tres cosas, y separarlas es lo que hace que funcione:
 *
 *   EL PESO —dónde estás— se ve QUIETO: el icono de tu sección está relleno por
 *   dentro y su línea es más gorda. Se lee de un vistazo, sin comparar con el de
 *   al lado, y no depende de haber visto nada moverse.
 *
 *   LA REJILLA DE APPS es un caso aparte y muy bonito: al entrar, cada cuadrado
 *   VIAJA AL SITIO DEL SIGUIENTE. Como son cuatro en cuadro, un cuarto de vuelta
 *   los deja EXACTAMENTE donde estaban: el dibujo final es idéntico al de
 *   partida. Por eso esto puede ser una TRANSICIÓN y no unos fotogramas —la ida
 *   al entrar, la vuelta al salir, sin nada que se quede raro—, y por eso la
 *   distancia es 11 y no otra: es justo la que separa un cuadrado del siguiente
 *   (van en x=3 y x=14). Si alguien la cambia, los cuadrados dejan de aterrizar
 *   en su sitio y el icono queda descolocado mientras estés en la sección.
 *
 *   EL RESTO DE GESTOS —el parpadeo de los días, el bandazo de la llave— van y
 *   vuelven al mismo sitio, así que no se pueden contar con una transición: son
 *   fotogramas, y los dispara armazon.js con la clase "gesto" AL ENTRAR Y AL
 *   SALIR. Colgados de .on sólo sabían contar la ida: al salir se quitaba la
 *   clase y la animación se cortaba a media frase.
 *
 * LOS GESTOS SON LOS DE lucide-animated.com, con sus números, salvo el de la
 * rejilla: allí el giro son 800 ms y aquí 450, porque allí es un adorno que se
 * mira y aquí es la respuesta a haber cambiado de sección. Lo que contesta a un
 * dedo tiene que ir por delante de él. Los demás se quedan como están: 400 por
 * día del calendario en cascada de 100 en 100, y 1050 el
 * bandazo de la llave, que además PIVOTA SOBRE SU CABEZA (transform-origin:
 * 90% 10%) y no sobre el centro. De allí se copian los dibujos y las cuentas; el
 * motor no —React y Motion—, que aquí no hace falta: esto son transiciones y
 * fotogramas de CSS, que van por su cuenta y sin dependencia ninguna.
 *
 * Se apunta a [data-nav] a secas, sin decir .seccion ni .abajo, porque las dos
 * barras llevan los mismos iconos y tienen que contar lo mismo — y eso vale
 * también para el ordenador y el móvil: NADA de esto cuelga del ratón, ver el
 * párrafo del final. El logo también
 * es [data-nav="home"], pero no tiene <svg> dentro y nunca se le pone .on, así
 * que no le toca nada.
 */

/* EL LIENZO NO RECORTA. Un SVG recorta por su viewBox, y la llave, al girar
   sobre su cabeza, saca una esquina fuera de las 24 unidades: se veía cortada a
   media vuelta. Con overflow visible el dibujo puede salirse mientras dura el
   bandazo, que es lo que tiene que pasar. */
[data-nav] svg { overflow: visible; }

[data-nav] svg > * {
  transform-box: fill-box;
  transform-origin: center;
  /* El relleno se declara AQUÍ, apagado del todo, y no en el estado.
     Los dibujos vienen con fill="none" escrito en el propio SVG, y de "none" a
     un color no hay camino que recorrer: el navegador no sabe interpolar entre
     "nada" y "azul", así que saltaría de golpe. Poniendo el color desde el
     principio con la opacidad a cero, lo que cambia es un número entre 0 y 1. */
  fill: currentColor;
  fill-opacity: 0;
  stroke-width: 1.8;
  /* El peso entra en 320 ms; el viaje de la rejilla dura 800, que es el número
     de la referencia. El grosor y el relleno obligan a repintar, al contrario
     que transform; aquí da igual y se dice a propósito, porque es un dibujo de
     23 píxeles que cambia una vez por cambio de sección. Donde sí importaría es
     en algo pegado a un dedo a 60 fotogramas por segundo, y por eso el carrusel
     no toca nada de esto. */
  transition: fill-opacity 320ms cubic-bezier(.23, 1, .32, 1),
              stroke-width 320ms cubic-bezier(.23, 1, .32, 1),
              transform 450ms ease-in-out;
}

/* EL PESO. Quieto, y por eso legible. */
[data-nav].on svg > * {
  fill-opacity: .3;
  stroke-width: 2.4;
}

/* LA REJILLA: cada cuadrado al sitio del siguiente, en el sentido del reloj.
   Los <rect> están escritos en ese orden y no en el de leer, justamente para
   esto: el primero va donde el segundo, el segundo donde el tercero, y así. */
:is([data-nav="home"], [data-nav="inicio"]).on svg > :nth-child(1) { transform: translateX(11px); }
:is([data-nav="home"], [data-nav="inicio"]).on svg > :nth-child(2) { transform: translateY(11px); }
:is([data-nav="home"], [data-nav="inicio"]).on svg > :nth-child(3) { transform: translateX(-11px); }
:is([data-nav="home"], [data-nav="inicio"]).on svg > :nth-child(4) { transform: translateY(-11px); }

/* LOS DÍAS DEL CALENDARIO: parpadean en cascada, uno cada 100 ms. Van del cuarto
   hijo en adelante —caja, raya y anillas son los tres primeros—, así que el
   orden en el que están escritos es parte del trato (ver app.html). */
@keyframes ic-dia { 50% { opacity: .3; } }
[data-nav="calendario"].gesto svg > :nth-child(n+4) { animation: ic-dia 400ms ease-in-out; }
[data-nav="calendario"].gesto svg > :nth-child(5) { animation-delay: 100ms; }
[data-nav="calendario"].gesto svg > :nth-child(6) { animation-delay: 200ms; }
[data-nav="calendario"].gesto svg > :nth-child(7) { animation-delay: 300ms; }
[data-nav="calendario"].gesto svg > :nth-child(8) { animation-delay: 400ms; }
[data-nav="calendario"].gesto svg > :nth-child(9) { animation-delay: 500ms; }

/* LA LLAVE: un bandazo, pivotando sobre su cabeza. */
@keyframes ic-llave {
  0%   { transform: rotate(0deg); }
  42%  { transform: rotate(12deg); }
  68%  { transform: rotate(-14deg); }
  88%  { transform: rotate(4deg); }
  100% { transform: rotate(0deg); }
}
[data-nav="herramientas"] svg > * { transform-origin: 90% 10%; }
[data-nav="herramientas"].gesto svg > * { animation: ic-llave 1050ms ease-in-out; }

/* Y NO HAY NADA CON EL RATÓN, a propósito.
 *
 * Lo hubo: pasar por encima de una sección ponía su icono como si estuvieras
 * dentro. La idea era "asomarse", y estaba mal. Un icono que se enciende al
 * pasarle el ratón por encima deja de decir DÓNDE ESTÁS y pasa a decir DÓNDE
 * APUNTA EL RATÓN, que es otra cosa: con el puntero cruzando la cabecera para
 * llegar a cualquier sitio, se encendían secciones en las que no estabas.
 *
 * Y sobre todo: hacía que el ordenador contara una historia distinta del móvil.
 * Es la misma aplicación y son los mismos iconos; si en un sitio la forma
 * significa "estás aquí" y en el otro significa "aquí apunta el ratón", hay que
 * aprender la aplicación dos veces.
 *
 * Ahora los iconos del carrusel cambian por una sola razón en los dos sitios:
 * entras en la sección, o te vas de ella. Los de Herramientas —el QR, las
 * notas— sí reaccionan al ratón, y ahí sí procede: son botones de una lista, no
 * dicen dónde estás. */

/* Con el movimiento al mínimo se va el baile, no el peso.
   Es la diferencia entre menos movimiento y menos información: el relleno y el
   grosor dicen en qué sección estás, igual que el color, y eso se queda. El
   viaje de la rejilla también se corta, y no se pierde nada: como acaba
   dejándola idéntica a como empezó, llegar de golpe se ve igual que no haber
   ido. Vale para las dos formas de pedirlo: la del sistema y la de los ajustes. */
@media (prefers-reduced-motion: reduce) {
  [data-nav] svg > * { animation: none !important; transition: none !important; }
}
html[data-movimiento="poco"] [data-nav] svg > * { animation: none !important; transition: none !important; }

/* --------------------------------------------------------- barra de abajo */
.barra-abajo {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 80;
  display: none;                 /* sólo en pantallas estrechas: ver al final */
  background: var(--tarjeta);
  border-top: 1px solid var(--borde);
  box-shadow: 0 -2px 14px rgba(11, 22, 96, .1);
  padding-bottom: env(safe-area-inset-bottom);
}
.abajo {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 9px 4px;
  border: none;
  border-radius: 0;
  background: transparent;
  color: var(--tinta-suave);
  font: inherit;
  font-size: 12px;     /* el rótulo de cada sección: 12 es el mínimo legible en el móvil */
  font-weight: 600;
  cursor: pointer;
}
.abajo svg { width: 23px; height: 23px; flex: none; }
.abajo.on { color: var(--azul); }
.abajo { transition: color 160ms ease, transform 160ms cubic-bezier(.23, 1, .32, 1); }
.abajo:active { transform: scale(.97); }

/* El icono de la que está puesta sube un pelo y crece un pelo. Es tan poco que
   nadie lo va a señalar, y ése es el objetivo: la pestaña activa se distingue
   por dos cosas (el color y el tamaño) en vez de por una, y el cambio tiene a
   qué agarrarse mientras la rayita viaja. Sólo transform, así que va por la
   GPU y no cuesta nada. */
.abajo svg { transition: transform 220ms cubic-bezier(.23, 1, .32, 1); }
.abajo.on svg { transform: translateY(-1px) scale(1.08); }
@media (prefers-reduced-motion: reduce) {
  .abajo.on svg { transform: none; }
}
html[data-movimiento="poco"] .abajo.on svg { transform: none; }

/* Una raya arriba, del ancho del icono: se ve cuál está puesta sin tener que
   comparar dos tonos de azul. No da saltos de una a otra — la mueve armazon.js
   pegada al dedo mientras se desliza, así que va a la mitad cuando el gesto va
   a la mitad. Sólo transform: es lo único que no pasa por layout ni por pintar. */
.indicador {
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;          /* dos secciones: media barra cada una */
  height: 3px;
  opacity: 1;
  transition: opacity 160ms ease;
  pointer-events: none;
}
.indicador::after {
  content: '';
  display: block;
  width: 34px;
  height: 100%;
  margin: 0 auto;
  border-radius: 0 0 3px 3px;
  background: var(--azul);
}
/* En una vista suelta no hay sección puesta: la raya se va. */
.barra-abajo.fuera .indicador { opacity: 0; }

/* En pantalla ancha el carrusel no es nada: display: contents lo borra como
   caja y sus dos secciones quedan como hijas directas de main, exactamente
   igual que antes de que existiera. El deslizar es cosa del móvil; aquí manda
   la pestaña, que es lo que hay a mano cuando hay ratón. */
.carrusel { display: contents; }

/* ==========================================================================
   MÓVIL: la página deja de ser una tira larga y pasa a ser una pantalla
   La cabecera arriba, la barra abajo, y en medio el carrusel, que es lo único
   que se mueve. Se hace así porque el gesto lo pide: para deslizar de una
   sección a otra las dos tienen que estar puestas a la vez, y cada una con su
   propio scroll, como en cualquier app de pestañas del móvil.

   Va AL FINAL del fichero a propósito. Una media query no añade especificidad,
   así que si esto estuviera arriba, el "display: contents" del carrusel lo
   pisaría por ser posterior, y el carrusel se quedaría sin caja.
   ========================================================================== */
@media (max-width: 860px) {
  .secciones { display: none; }
  .barra-abajo:not([hidden]) { display: flex; }
  .toast { bottom: calc(78px + env(safe-area-inset-bottom)); }

  /* La pantalla se reparte con un flex de alto fijo, y NO se le pone
     overflow: hidden a html ni a body.
     Estaba puesto y fue un error: dejaba el documento sin poder moverse, así
     que si el navegador ampliaba un poco —basta un pellizco con dos dedos, y
     con un gesto lateral eso pasa sin querer— lo que se salía por la derecha
     ya no había forma de alcanzarlo ni de volver a reducir. Sin el candado, si
     algo se sale se puede llegar a ello, que es lo que espera cualquiera.
     Con body midiendo justo la pantalla no hay nada que desplazar de todas
     formas: el candado no estaba arreglando nada. */
  html { height: 100%; }
  /* LA ALTURA NO SE LA PEDIMOS A LA UNIDAD DE PANTALLA, LA MIDE armazon.js.
   *
   * Aquí ponía "height: 100dvh" a secas, y es de donde venía el "en el móvil no
   * carga hasta que giro la pantalla". En un Android, y sobre todo con la
   * aplicación instalada, "dvh" puede tardar en valer lo que vale: si en el
   * primer reparto sale cero, esta caja mide cero, main —que es flex: 1 con
   * min-height: 0— mide cero, y el carrusel entero mide cero. La página está
   * cargada y no se ve NADA. Al girar el móvil se rehace el reparto, la unidad
   * ya vale, y aparece todo de golpe: eso es exactamente lo que se veía.
   *
   * Y explica por qué fallaba SÓLO aquí: el login usa "height: 100%" y las
   * páginas de cada app usan "min-height: 100dvh". Un min-height que sale cero
   * no encoge nada —el contenido sigue midiendo lo que mide—; un height sí.
   *
   * Ahora manda --alto-pantalla, que armazon.js escribe con
   * window.innerHeight —un número, medido en el momento— y mantiene al día al
   * girar, al volver a la aplicación y cuando el navegador esconde su barra.
   * El 100dvh se queda de respaldo por si ese código no llegara a correr. */
  body {
    height: var(--alto-pantalla, 100dvh);
    min-height: 0;
    display: flex;
    flex-direction: column;
    /* Con un carrusel horizontal dentro, tirar de lado en el borde disparaba
       el "atrás" del navegador y se salía de la aplicación sin querer. Aquí
       atrás ya está en su botón y en el gesto del sistema; el de la página
       sobra. */
    overscroll-behavior-x: none;
  }
  /* Ya no hace falta pegarla: no se mueve de sitio. */
  .top { position: static; flex: none; }
  /* Relative y no static: la raya que marca la sección va dentro con
     position: absolute, y un elemento estático no le sirve de referencia — se
     iba al principio de la página, que es donde apareció en el móvil.

     margin-top: auto la mantiene PEGADA ABAJO aunque el de en medio no esté.
     En el comité, al arrancar, <main> está oculto hasta que se confirma la
     sesión; sin esto la barra se quedaría a media altura, justo debajo de la
     cabecera, y saltaría al fondo al aparecer el contenido. Con main puesto
     —siempre, en la pública— no sobra hueco y este auto no hace nada. */
  .barra-abajo { position: relative; flex: none; margin-top: auto; }

  /* El ancho va CLAVADO a la pantalla, y no dejado a que se estire solo.
     Sin esto, main medía 442px en un móvil de 390: en un flex en columna, el
     hijo no baja de su ancho mínimo de contenido aunque la columna sea más
     estrecha, así que se llevaba por delante a todo lo que hay dentro y la
     mitad derecha de la página quedaba fuera de la pantalla. La cabecera y la
     barra sí encajaban, y por eso se veía torcido sólo de la cabecera para
     abajo. width: 100% + min-width: 0 no dejan margen a interpretación. */
  main {
    flex: 1;
    width: 100%;
    min-width: 0;
    min-height: 0;
    max-width: none;
    padding: 0;
    display: flex;
    flex-direction: column;
    /* Lo que sobre se recorta aquí dentro, no en el documento: así el recorte
       no se lleva por delante la posibilidad de moverse por la página. */
    overflow: hidden;
  }
  main > .carrusel, main > .view { flex: 1; width: 100%; min-width: 0; min-height: 0; }

  /* Pager por transform: las secciones van en fila (N anchos) y armazon.js
     traslada la fila. El gesto horizontal lo lleva el JS (una sección por
     deslizamiento); el vertical, el scroll nativo de cada sección
     (touch-action: pan-y). NO es un scroll horizontal —eso dejaba que un
     manotazo saltara varias y que el navegador lo dejara a medias—.

     EL RECORTE LO HACE <main>, NO EL CARRUSEL, Y ES IMPORTANTE.
     Aquí había un "overflow: hidden" y era el motivo de que la segunda y la
     tercera sección salieran EN BLANCO en el móvil. Un recorte se aplica a la
     caja del elemento... y esa caja se mueve con su propio transform. Al
     trasladar el carrusel -100% para enseñar la segunda, se llevaba el recorte
     consigo: la ventana por la que se mira acababa fuera de la pantalla, a la
     izquierda, y donde antes estaba quedaba el fondo pelado. La primera se veía
     porque su traslación es cero.
     La forma de hacer un pasador es: una ventana quieta y una fila que se
     mueve dentro. La ventana quieta ya existe —main, que en el móvil recorta
     (más arriba)—, así que el carrusel sólo tiene que ser la fila.

     Y la altura sigue clavada sin este recorte: main es una columna de alto
     fijo, el carrusel es su hijo con flex: 1 y min-height: 0, y cada sección se
     desplaza por dentro (overflow-y: auto). Una sección alta no empuja nada. */
  .carrusel {
    display: flex;
    touch-action: pan-y;
    transform: translateX(0);
  }
  /* Cada sección mide EXACTAMENTE lo que el visor, que es de lo que se fía el
     pasador: armazon.js traslada la fila de ancho en ancho de visor. Si el
     relleno sumara por fuera (box-sizing de caja de contenido) cada sección
     mediría 32 px de más y al pasar quedaría una tira de la anterior a la
     vista. Las dos caras ya lo ponen para todo, pero esto es de aquí.

     Y CADA UNA CON SU FONDO. Parece de adorno y es lo contrario: desde que la
     que se va se queda atrás (el paralaje de armazon.js), las dos secciones se
     PISAN — la de debajo acaba metida en el hueco de la de arriba—. Sin fondo
     propio una sección es transparente, así que se veían las dos a la vez,
     mezcladas: el calendario encima de las tarjetas de Apps. Con fondo, la de
     arriba tapa, que es lo que tiene que hacer una página que pasa por encima
     de otra.

     La sombra por el borde izquierdo es lo que remata la lectura: dice cuál de
     las dos está delante. Al estar quieto cae fuera de la pantalla, así que no
     se ve nunca de más.

     Y POSICIONADAS, que es la otra mitad del arreglo y la menos evidente. Al
     apagar la que se va (opacity < 1) el navegador la ASCIENDE en el orden de
     pintado: una caja con opacidad se pinta en el mismo turno que las
     posicionadas, que va DESPUÉS del de las cajas normales. O sea que la de
     debajo pasaba a pintarse encima de la de al lado, y encima translúcida: por
     eso se veían las tarjetas de Apps por encima del calendario. Con las tres
     posicionadas, todas van al mismo turno y manda el orden en que están
     escritas: la de la derecha, la última, encima. Que es justo la regla del
     paralaje ("la de la izquierda es la de abajo") dicha en pintura. */
  .carrusel > .view {
    flex: 0 0 100%;
    box-sizing: border-box;
    min-width: 0;
    min-height: 0;
    position: relative;
    background: var(--fondo);
    box-shadow: -14px 0 22px -12px rgba(11, 22, 96, .18);
  }

  /* El margen se va de main a cada página: ahora scrollea cada una por su
     cuenta, así que el aire tiene que ir dentro y no fuera.

     El overflow-x va escrito, y no es de adorno: poner sólo overflow-y: auto
     deja el eje horizontal en "visible", y el CSS lo convierte solo en "auto".
     Cada página se volvía un contenedor con scroll horizontal propio, que es
     justo el que tiene que llevar el carrusel. */
  main > .view, .carrusel > .view {
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior-y: contain;
    padding: 18px 16px 28px;
  }
}

/* ==========================================================================
   ENTRADA DE SECCIÓN EN PANTALLA ANCHA
   Ahí no hay carrusel que deslizar (las secciones se enseñan y esconden), así
   que el cambio era un corte seco. La nueva entra con un deslizamiento corto en
   la dirección del viaje y un fundido: moderno pero sutil, no un carrusel de
   lado a lado. Lo dispara comun/armazon.js con .animar-* y sólo mueve transform
   y opacity (va por GPU). Con el movimiento al mínimo, armazon.js ni pone la
   clase: el cambio es instantáneo.
   ========================================================================== */
/* El deslizamiento entra desde fuera; sin esto asomaría barra horizontal un
   instante. overflow-x: clip recorta en X sin volver main un contenedor de
   scroll, así que la página sigue moviéndose en vertical como siempre. */
@media (min-width: 861px) { main { overflow-x: clip; } }

/* TRANSICIÓN, NO FOTOGRAMAS.
   Esto eran tres @keyframes, y un keyframe no se puede interrumpir: al pulsar
   Apps → Calendario → Herramientas seguido, cada uno empezaba otra vez desde
   cero y se veía a tirones. Una transición se REDIRIGE desde donde esté, así
   que encadenar cambios sale suave. Lo dispara armazon.js poniendo la clase de
   por dónde entra, quitándola en el fotograma siguiente y dejando que el
   navegador haga el viaje.

   El BLUR no es un adorno: aquí la sección que se va desaparece de golpe
   (display: none), así que sin él se ven dos cosas distintas, una que
   desaparece y otra que llega. Tres píxeles de desenfoque que se van durante el
   viaje pegan las dos y el ojo lo lee como UNA transformación en vez de como
   dos objetos. Es el mismo truco de cualquier fundido que no acaba de cuadrar.

   Y el recorrido es corto —16 px y un pelo de escala—: esto se ve varias veces
   por sesión, no una. Cuanto más se repite algo, menos tiene que moverse. */
.view.animando {
  transition: opacity 240ms cubic-bezier(.23, 1, .32, 1),
              transform 240ms cubic-bezier(.23, 1, .32, 1),
              filter 240ms cubic-bezier(.23, 1, .32, 1);
  will-change: opacity, transform;
}
.view.desde-der   { opacity: 0; transform: translate3d(16px, 0, 0) scale(.994); filter: blur(3px); }
.view.desde-izq   { opacity: 0; transform: translate3d(-16px, 0, 0) scale(.994); filter: blur(3px); }
.view.desde-abajo { opacity: 0; transform: translate3d(0, 14px, 0) scale(.994); filter: blur(3px); }

/* Con el movimiento al mínimo NO se apaga la animación entera: se queda el
   fundido, que es lo que explica que ha cambiado algo, y se va lo que se mueve,
   que es lo que marea. "Menos movimiento" no es "ninguna animación".
   Vale para las dos formas de pedirlo: la del sistema y la de los ajustes. */
@media (prefers-reduced-motion: reduce) {
  .view.desde-der, .view.desde-izq, .view.desde-abajo {
    transform: none;
    filter: none;
  }
}
html[data-movimiento="poco"] .view.desde-der,
html[data-movimiento="poco"] .view.desde-izq,
html[data-movimiento="poco"] .view.desde-abajo {
  transform: none;
  filter: none;
}

