﻿/* FARMA-Enfermería - estilos de la web.
   Los colores, tipografías y espaciados salen de los tokens; aquí sólo se compone. */

*{box-sizing:border-box}
/* El hueco de la barra de desplazamiento se reserva desde el primer momento.
   Si no, al aparecer la barra al terminar la carga, todo se desplaza a la
   izquierda de golpe y se ve el tirón justo cuando aterriza el logo. */
html{scrollbar-gutter:stable;
  /* Tamaño del logo en la pantalla de carga y en el centro del inicio.
     Lo usan el logo del inicio y los cálculos de posición de los iconos. */
  --logo-inicio:min(38vmin,200px)}
body{margin:0}
img{max-width:100%;display:block}
button{font:inherit;cursor:pointer;border:0;background:none;color:inherit}
input,select{font:inherit}

.contenedor{max-width:var(--container);margin:0 auto;padding:0 var(--gutter)}
.oculto{display:none !important}

/* El atributo `hidden` de HTML esconde poniendo `display:none`, pero lo hace
   con la prioridad más baja que existe, así que CUALQUIER regla nuestra que
   diga `display` lo anula sin avisar y el elemento sigue ahí ocupando sitio.

   Pasó con las tarjetas del acceso: `.acceso-caja` es `display:flex`, y la
   tarjeta escondida seguía contando. El panel medía 830 px con una tarjeta de
   448 dentro y la de entrar se salía por arriba de la pantalla.

   Con esto, `hidden` esconde de verdad, aquí y en cualquier sitio donde se
   use más adelante. */
[hidden]{display:none !important}

/* ---------- Cabecera ---------- */
/* Translucidez al 50%: se ve pasar el contenido por debajo.
   El desenfoque sube para que el texto de la barra siga legible. */
.cabecera{position:sticky;top:0;z-index:20;background:rgba(252,252,251,.5);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid var(--border-subtle);
  opacity:0;transition:opacity 900ms var(--ease-standard)}
/* Es lo primero que aparece cuando termina la carga. */
body.barra .cabecera{opacity:1}
.cabecera .contenedor{display:flex;align-items:center;gap:var(--sp-5);height:72px}
.marca{display:flex;align-items:center;gap:var(--sp-3);text-decoration:none}
.marca img{width:40px;height:40px;object-fit:contain}
/* La marca va en dos renglones, al lado del logo: FARMA arriba y Enfermería
   debajo. La interlínea se aprieta para que los dos se lean como un bloque a
   la altura del logo y no como dos líneas sueltas. */
.marca-texto{display:flex;flex-direction:column;line-height:1.05;
  font-family:var(--font-display);color:var(--text-title)}
.marca-texto .arriba{font-size:var(--fs-h4);font-weight:var(--fw-bold);
  letter-spacing:.01em}
.marca-texto .abajo{font-size:var(--fs-sm);font-weight:var(--fw-regular);
  color:var(--text-body)}

.nav{margin-left:auto;display:flex;gap:var(--sp-2);flex-wrap:wrap}

/* En una pantalla estrecha los cuatro botones no caben en una fila, y con
   `flex-wrap` se apilaban: medido en un móvil de 375, la barra pedía 190 px de
   alto dentro de una cabecera de 72, así que se salían por debajo del cristal
   y quedaban encima del contenido.

   Se pasa a una fila que se desplaza de lado. Se prefiere a apilarlos porque
   la cabecera mide 72 y esa medida no es decorativa: la lee el vuelo del logo
   y la usa #vista-inicio para meterse debajo. Y se prefiere a esconder
   botones porque los cuatro son el mapa de la guía; el que no se ve, no
   existe.

   La barra de desplazamiento se oculta: se arrastra con el dedo, que es el
   gesto natural en el sitio donde pasa esto. */
@media (max-width:700px){
  .nav{flex-wrap:nowrap;overflow-x:auto;
    scrollbar-width:none;-ms-overflow-style:none;
    -webkit-overflow-scrolling:touch}
  .nav::-webkit-scrollbar{display:none}
  .nav button{white-space:nowrap;padding:var(--sp-2) var(--sp-3)}
  /* El texto de la marca sobra donde no cabe: el logo ya identifica la web,
     y lo que se gana son 45 px para los botones. */
  .marca-texto{display:none}
}
/* La barra en Lora, como la marca y como las fichas. */
.nav button{padding:var(--sp-2) var(--sp-4);border-radius:var(--radius-pill);
  font-family:var(--font-serif);font-size:var(--fs-body);
  color:var(--text-body);transition:background var(--dur-fast) var(--ease-standard)}
.nav button:hover{background:var(--surface-tint)}
.nav button[aria-current="page"]{background:var(--brand-primary);color:var(--text-onbrand)}

/* ---------- El perfil ----------
   En la esquina derecha, en espejo del logo y del mismo tamaño exacto: 40 px,
   el mismo que .marca img. Si un día cambia el del logo, cambia también aquí. */
.perfil{position:relative;flex:none}

/* `overflow:hidden` para que la foto se recorte en redondo dentro del
   círculo, y `position:relative` para que pueda ponerse encima de la inicial
   sin sacarla de ahí. */
.perfil-circulo{width:40px;height:40px;border-radius:50%;
  overflow:hidden;position:relative;
  display:flex;align-items:center;justify-content:center;
  background:var(--brand-primary);color:var(--text-onbrand);
  font-family:var(--font-display);font-size:var(--fs-body-lg);
  font-weight:var(--fw-semibold);line-height:1;text-transform:uppercase;
  box-shadow:var(--shadow-xs);
  transition:transform var(--dur-base) var(--ease-standard),
             box-shadow var(--dur-base) var(--ease-standard)}
/* `cover` y no `contain`: la foto llena el círculo aunque no sea cuadrada del
   todo. Recortar un poco es mejor que dejar barras a los lados, y de todas
   formas ya viene recortada en cuadrado desde el navegador. */
.perfil-foto{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

.perfil-circulo:hover{transform:scale(1.06);box-shadow:var(--shadow-sm)}
.perfil-circulo:focus-visible{outline:none;box-shadow:var(--shadow-focus)}

/* El menú cuelga del círculo, alineado por la derecha para que no se salga
   por el borde de la ventana. Mismo cristal que la barra del buscador y que
   la tarjeta del acceso: es el material de la casa. */
/* Cristal, sí, pero MUCHO más cerrado que el de la barra del buscador y el de
   la tarjeta del acceso, y por una razón concreta: aquellos flotan sobre el
   fondo, que es liso, mientras que éste cae sobre el contenido de la web -una
   ficha, una lista de escalas- y a .62 se leía el texto de debajo cruzándose
   con las opciones. Un menú tiene que poder leerse de un vistazo, y para eso
   necesita tapar lo que hay detrás.

   Sigue siendo translúcido y sigue desenfocando: se intuye lo que pasa por
   debajo, que es lo bonito, pero ya no compite con lo que pone encima. */
.perfil-menu{position:absolute;top:calc(100% + var(--sp-3));right:0;z-index:30;
  min-width:260px;max-width:min(320px,90vw);
  display:flex;flex-direction:column;gap:var(--sp-1);
  background:rgba(255,255,255,.93);
  backdrop-filter:blur(20px) saturate(1.4);
  -webkit-backdrop-filter:blur(20px) saturate(1.4);
  border:1px solid rgba(255,255,255,.8);
  border-radius:var(--radius-lg);padding:var(--sp-4);
  box-shadow:var(--shadow-lg);
  opacity:0;transform:translateY(-6px);
  transition:opacity var(--dur-base) var(--ease-standard),
             transform var(--dur-base) var(--ease-standard)}
body.perfil-abierto .perfil-menu{opacity:1;transform:translateY(0)}

/* El saludo es lo primero que se lee, así que va en la tipografía de los
   títulos y con su tamaño. El correo, debajo y en pequeño: es un dato de
   comprobación -«sí, soy yo»-, no algo que haya que leer cada vez. */
.perfil-saludo{margin:0;font-family:var(--font-display);
  font-size:var(--fs-h4);color:var(--text-title);line-height:var(--lh-heading);
  overflow-wrap:anywhere}
.perfil-correo{margin:0 0 var(--sp-3);
  font-size:var(--fs-xs);color:var(--text-muted);
  overflow-wrap:anywhere}

/* Cada opción en su óvalo, y Cerrar Sesión es una más de la lista: van a ir
   apareciendo otras al lado y ninguna tiene por qué mandar sobre el resto.
   Translúcidas también, para que el menú entero se lea como una sola pieza de
   cristal y no como recuadros pegados encima. */
.perfil-opciones{display:flex;flex-direction:column;gap:var(--sp-2)}

/* Lo que se dice mientras la foto sube, o lo que falló. Va donde estaba el
   correo, así que no mueve las opciones de sitio al aparecer. */
.perfil-aviso{margin:0 0 var(--sp-3);
  font-size:var(--fs-xs);color:var(--brand-primary);font-weight:var(--fw-semibold)}

/* Los óvalos, en rosa muy pálido en vez de en blanco transparente. Sobre un
   menú ya casi opaco, el blanco translúcido no se veía: se confundía con el
   propio menú y los óvalos desaparecían. Con el tinte de la marca se
   distinguen sin necesidad de tapar nada. */
.perfil-opcion{text-align:left;
  padding:var(--sp-2) var(--sp-4);border-radius:var(--radius-pill);
  background:var(--surface-tint);
  border:1px solid transparent;
  font-size:var(--fs-sm);font-weight:var(--fw-semibold);
  color:var(--brand-primary);
  transition:background var(--dur-fast) var(--ease-standard),
             border-color var(--dur-fast) var(--ease-standard)}
.perfil-opcion:hover{background:var(--rose-200);
  border-color:var(--border-strong)}
.perfil-opcion:focus-visible{outline:none;box-shadow:var(--shadow-focus)}

/* El perfil sólo existe cuando hay alguien dentro. Durante la carga y el
   acceso no hay nadie, así que no se enseña un círculo vacío. */
body:not(.barra) .perfil{display:none}

/* ---------- Círculo de carga ----------
   Rosa muy pastel -casi blanco- para que el logo, que ya es rosa, destaque.
   El marco lo coloca y lo achica; el halo, dentro, es el que deriva. Así
   una transformación no pisa la otra.

   Las tres manchas van cerca del centro y con el mismo radio: si se
   reparten hacia los lados, su unión se lee como un óvalo, no como
   un círculo. */
/* Fijo a la ventana y por detrás de todo: el círculo acompaña a cualquier
   sección de la web, no sólo al inicio. El marco lo recorta en los bordes. */
.circulo-marco{position:fixed;inset:0;overflow:hidden;z-index:0;pointer-events:none}
main{position:relative;z-index:1}

/* La posición y el tamaño los escribe el JavaScript en --tx, --ty y --escala,
   fotograma a fotograma. Sin transiciones de CSS: si las hubiera, pelearían
   con el seguimiento del ratón. Es UN SOLO elemento en todos los estados. */
/* El tamaño del círculo durante la carga vive AQUÍ y en ningún otro sitio:
   es el valor por defecto de --escala mientras el JavaScript no haya escrito
   nada, y es también el que lee inicio.js para su ESCALA_CENTRO. Si estuviera
   escrito en los dos lados, el primer pintado y el primer fotograma podrían
   no coincidir, y esa diferencia se ve como un pantallazo. */
:root{--escala-carga:1.3;
  /* Lo que tarda cada paso de Celestia: el círculo en condensarse en el
     brillo, los tres en desprenderse, los cuatro en cambiar de forma y los
     cuatro en recogerse arriba. Son los mismos CEL_ROSA, CEL_DESPRENDER,
     CEL_MORFAR y CEL_POSAR de celestia.js, que es quien encadena los pasos:
     si cambia uno hay que cambiar el otro, o un paso empezaría antes de que
     acabe el anterior. */
  --dur-rosa:1600ms;
  --dur-celestia:1200ms;--dur-morfar:1100ms;--dur-posar:1000ms}

/* La opacidad SÍ lleva transición, y sólo ella: es lo único del círculo que
   no escribe el bucle. La usa Celestia para atenuarlo cuando la chispa
   grande sale de él (ver body.celestia-brillo, al final del archivo). */
.halo-marco{position:absolute;left:50%;top:50%;pointer-events:none;
  width:min(82vmin,660px);height:min(82vmin,660px);
  transition:opacity var(--dur-slow) var(--ease-standard);
  transform:translate(-50%,-50%)
            translate(var(--tx,0px),var(--ty,0px))
            scale(var(--escala,var(--escala-carga)))}
/* El desenfoque lleva transición porque Celestia lo cierra: para que el
   círculo pueda dejar de ser una nube y pasar a ser un disco. */
.halo{position:absolute;inset:0;filter:blur(40px);
  transition:filter var(--dur-rosa,1600ms) var(--ease-standard);
  animation:deriva 11s ease-in-out infinite}
@keyframes deriva{
  0%,100%{transform:translate(-2%,-2%) scale(1)}
  33%    {transform:translate(2%,2%)   scale(1.04)}
  66%    {transform:translate(-1%,2%)  scale(.98)}}

/* Tres manchas girando a distinta velocidad: el degradado nunca se repite igual. */
.halo i{position:absolute;inset:0;display:block;border-radius:50%}
.halo i{transition:opacity var(--dur-rosa,1600ms) var(--ease-standard)}
.halo i:nth-child(1){background:radial-gradient(closest-side circle at 46% 44%,var(--rose-200) 0%,var(--rose-100) 46%,transparent 82%);
  animation:orbita 9s linear infinite}
.halo i:nth-child(2){background:radial-gradient(closest-side circle at 55% 47%,var(--rose-100) 0%,var(--rose-200) 48%,transparent 84%);
  animation:orbita 13s linear infinite reverse}
.halo i:nth-child(3){background:radial-gradient(closest-side circle at 50% 56%,var(--rose-200) 0%,var(--rose-100) 50%,transparent 84%);
  animation:orbita 17s linear infinite}
@keyframes orbita{to{transform:rotate(360deg)}}

/* ---------- El círculo, volviéndose rosa puro ----------
   Es el paso más largo de la transición porque es el que hay que poder seguir
   con la vista: la nube rosa pálido de siempre se va condensando, sin dejar
   de ser ella, en el círculo rosa de Celestia.

   Y es UNA sola transición, no dos. Antes eran dos -primero la nube se volvía
   un disco rosa liso, y después ese disco se cambiaba por el brillo- y en el
   cambio se veía un salto, porque el disco era de un rosa plano y el brillo
   lleva el degradado de Celestia: se notaba el relevo. Ahora no hay relevo
   que notar. Lo que se enciende mientras las nubes se apagan es directamente
   el brillo, todavía redondo, del tamaño exacto que tenía el círculo y con su
   mismo desenfoque. No hay ningún estado intermedio que pueda desencajar,
   porque no hay ningún elemento intermedio.

   `--celestia-disco` es de qué tamaño queda el círculo al condensarse, en
   tanto por uno de lo que mide el halo. Vive AQUÍ, y celestia.js lo lee para
   saber de qué tamaño tiene que nacer el brillo. Si se cambia este número, el
   brillo nace del tamaño nuevo sin tocar nada más. */
:root{--celestia-disco:.46}

/* Las nubes se apagan a la vez que el brillo se enciende, y en el mismo
   tiempo: es el cruce, y es lo único que pasa en este paso. El desenfoque se
   va cerrando de camino, para que los últimos fotogramas de la nube ya sean
   los de algo con forma y el cruce no tenga que salvar ninguna distancia. */
body.celestia-rosa .halo{filter:blur(10px)}
body.celestia-rosa .halo i{opacity:0}

@keyframes entrarLogo{from{opacity:0;transform:scale(.55)}to{opacity:1;transform:scale(1)}}
@keyframes respirar{0%,100%{transform:scale(1)}50%{transform:scale(1.045)}}

body.cargando{overflow:hidden}

/* ---------- Vista de inicio ----------
   Sólo el logo centrado y los iconos flotando a su alrededor. */
/* Ocupa la ventana entera y se mete bajo la cabecera (que es translúcida y
   va por encima). Así el centro del escenario coincide con el centro de la
   ventana, que es donde estaba el logo de la pantalla de carga.

   La ventana entera MENOS un píxel, que es el borde de abajo de la cabecera:
   ella mide 73 -sus 72 más el borde- y esto sube 72, así que sin descontarlo
   el documento saca un píxel por debajo de la ventana. Un píxel basta para
   que el navegador pinte la barra de desplazamiento entera, en una pantalla
   en la que no hay absolutamente nada que desplazar. Se descuenta aquí y no
   se toca el -72px: esa medida la lee aterrizar() para el vuelo del logo. */
#vista-inicio{position:relative;padding:0;margin-top:-72px;
  min-height:calc(100vh - var(--border-width));display:flex;align-items:center}

.escenario{position:relative;z-index:1;width:100%;
  min-height:min(64vh,540px);display:flex;align-items:center;justify-content:center}

/* Entra con el mismo zoom que tenía la pantalla de carga y respira sin
   parar de principio a fin. Nada interrumpe esta animación. */
/* `backwards` y no `both`: con `both`, la animación de entrada seguiría
   imponiendo su opacidad final para siempre y el logo no podría apagarse
   al elegir destino. Con `backwards` deja de mandar en cuanto termina. */
.logo-central{position:relative;z-index:1;
  width:var(--logo-inicio);height:var(--logo-inicio);object-fit:contain;
  animation:entrarLogo 1500ms var(--ease-standard) backwards,
            respirar 3.2s var(--ease-standard) 1500ms infinite;
  transition:opacity 900ms var(--ease-standard)}

/* ---------- Acceso ----------
   El panel que pide usuario y contraseña. No es una pantalla: es lo único
   que se le añade al estado de carga, y va colocado igual que los iconos del
   inicio, respecto al centro del escenario. Durante la carga ese centro es
   donde está el logo, así que el panel cae justo debajo sin empujarlo: está
   fuera del flujo y el logo no llega a enterarse de que existe.

   Son dos clases y no una porque el logo y la tarjeta no se van a la vez al
   salir: `body.accediendo` es que el logo ha hecho sitio, y
   `body.acceso-puesto` es que la tarjeta está a la vista. Al entrar se ponen
   casi juntas; al salir se quita primero la de la tarjeta y sólo después la
   del logo, que es lo que hace que se lea como una cosa detrás de otra.

   Hay dos colocaciones. En una pantalla ancha el logo se aparta a la
   IZQUIERDA y la tarjeta aparece a su derecha, los dos a la misma altura. En
   una estrecha eso no cabe -el logo, el hueco y la tarjeta piden 648 px de
   ancho-, así que la tarjeta se queda debajo del logo y lo que se aparta es
   hacia arriba. Cuál de las dos manda lo dice `--acceso-lado`, y lo decide
   esta hoja: acceso.js sólo lo lee para saber en qué dirección medir. */
:root{--acceso-lado:0}

/* Aquí NO hay nada que tape el desplazamiento, y es a propósito. Durante el
   acceso salía barra, y el arreglo está en #vista-inicio, más arriba: sobraba
   un píxel. No se veía antes porque `body.cargando` lo tenía bloqueado, y
   durante el acceso esa clase ya no está -el círculo ronda, no está cargando-,
   así que al quitarla se destapó.

   Se probó a taparlo con `overflow:hidden` aquí y era peor por dos razones.
   Una: con el desbordamiento tapado el navegador deja de reservar el hueco de
   la barra -medido, de 15 px a 0- y lo recupera al entrar, con lo que la
   página se corre de lado justo en la transición; cambiar un salto por otro
   no es arreglarlo. Y dos: dejaría sin salida a quien tenga la ventana tan
   baja que la tarjeta no le quepa. Quitado el píxel, si de verdad sobra
   contenido la barra sale y sirve; si no sobra, no sale. */

/* Colocación de pantalla estrecha: la tarjeta debajo del logo, y entra
   subiendo, igual que los iconos del inicio. */
.acceso{position:absolute;left:50%;z-index:2;
  top:calc(50% + var(--logo-inicio) * 0.5 + var(--sp-7));
  width:min(88vw,400px);
  opacity:0;transform:translate(-50%,14px);
  transition:opacity 900ms var(--ease-standard),
             transform 900ms var(--ease-standard)}
body.acceso-puesto .acceso{opacity:1;transform:translate(-50%,0)}

/* La tarjeta entra un poco después que el logo: primero se abre el hueco y
   después llega ella a ocuparlo. Si entran a la vez, la tarjeta cruza por
   encima del logo mientras éste todavía se está apartando.

   El retraso vive en la clase y no en `.acceso` a posta: así sólo cuenta al
   entrar. Al salir, la clase se quita, con ella se va el retraso y la tarjeta
   empieza a irse en el acto, que es lo que hace falta para que se vea salir
   antes que nada. */
body.acceso-puesto .acceso{transition-delay:300ms}

/* Colocación de pantalla ancha: el logo a la izquierda y la tarjeta a su
   derecha, centradas las dos a la misma altura. La tarjeta ya no entra
   subiendo sino desde la derecha, que es de donde viene. */
@media (min-width:860px){
  :root{--acceso-lado:1}
  .acceso{top:50%;
    left:calc(50% + var(--logo-inicio) * 0.5 + var(--sp-8));
    transform:translate(28px,-50%)}
  body.acceso-puesto .acceso{transform:translate(0,-50%)}
}

/* El cristal de la barra de FARMA-Search, con los mismos valores exactos:
   blanco a media opacidad, el fondo desenfocado por detrás y un borde muy
   fino. Es el material de la casa y no hay razón para inventar otro. Lo único
   que cambia es la forma, que aquí no es una píldora sino una tarjeta. */
.acceso-caja{display:flex;flex-direction:column;gap:var(--sp-4);
  background:rgba(255,255,255,.62);
  backdrop-filter:blur(20px) saturate(1.4);
  -webkit-backdrop-filter:blur(20px) saturate(1.4);
  border:1px solid rgba(255,255,255,.8);
  border-radius:var(--radius-xl);padding:var(--sp-6) var(--sp-5);
  box-shadow:var(--shadow-md)}

/* No hay título: el título es el logo, que está justo encima y se lee mucho
   mejor que cualquier rótulo que se pusiera aquí. Sólo la entradilla, en la
   tipografía de los textos de sección. */
.acceso-intro{margin:0;text-align:center;font-family:var(--font-display);
  font-size:var(--fs-body-lg);color:var(--text-title);line-height:var(--lh-heading)}

/* La de recuperar sí lleva título, y ahí la entradilla pasa a ser lo que es:
   una explicación, no un rótulo. Por eso baja de tamaño y de peso. */
.acceso-titulo{margin:0;text-align:center;font-family:var(--font-display);
  font-size:var(--fs-h3);color:var(--text-title);line-height:var(--lh-heading)}
.acceso-intro-menor{font-family:var(--font-body);font-size:var(--fs-sm);
  color:var(--text-muted);line-height:var(--lh-body)}

/* ---------- El cruce de las dos tarjetas ----------
   Al pulsar "¿Olvidaste tu contraseña?" las dos se mueven a la vez y hacia el
   mismo lado: la de entrar se va por la derecha apagándose y la de recuperar
   entra desde la izquierda. Van juntas a posta, como una cinta que corre: si
   una esperara a la otra se leerían como dos pasos, y aquí es un solo gesto.
   Al volver, el mismo movimiento del revés.

   La que se va se saca del flujo mientras dura el cruce (ver .saliendo). Es lo
   que permite que la caja tome ya el alto de la que entra, de modo que el
   grupo se recoloque durante el viaje y no de un tirón al final. */
.acceso-caja{transition:opacity 520ms var(--ease-standard),
                        transform 520ms var(--ease-standard)}

.acceso-caja.saliendo{position:absolute;top:0;left:0;width:100%;
  pointer-events:none;opacity:0}
.acceso-caja.saliendo.hacia-la-derecha{transform:translateX(38px)}
.acceso-caja.saliendo.hacia-la-izquierda{transform:translateX(-38px)}

/* El punto de partida de la que entra. Se le quita en cuanto empieza el
   cruce y desde ahí se deja caer en su sitio. */
.acceso-caja.entrando{opacity:0}
.acceso-caja.entrando.desde-la-izquierda{transform:translateX(-38px)}
.acceso-caja.entrando.desde-la-derecha{transform:translateX(38px)}

/* ---------- El enlace de la tarjeta ----------
   Es un botón, no un enlace, porque no lleva a ninguna parte: cambia lo que
   se ve aquí mismo. Pero se lee como un enlace, que es lo que la gente busca
   con la vista debajo de una contraseña. */
.acceso-enlace{align-self:center;padding:0;
  font-size:var(--fs-sm);color:var(--text-link);
  text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;
  transition:color var(--dur-fast) var(--ease-standard)}
.acceso-enlace:hover{color:var(--text-link-hover)}
.acceso-enlace:focus-visible{outline:none;box-shadow:var(--shadow-focus);
  border-radius:var(--radius-xs)}

/* El botón, a lo ancho: en un formulario de dos campos es el único sitio a
   donde se va, así que no tiene que competir con nada.

   Y de cristal, como la barra del buscador y como la propia tarjeta: el rosa
   va en degradado y translúcido, con el fondo desenfocado por detrás, así que
   el círculo que ronda se le ve pasar por debajo y el botón cambia de matiz
   según por dónde ande. Es el material de la casa, aquí también.

   Los dos rosas son los oscuros de la marca -rose-700 y rose-900- y no los
   claros, y no es por gusto: con los claros a esta transparencia el texto
   crema encima se quedaba en 2,2 de contraste, ilegible. Así se mide 5,8, que
   ya está por encima del mínimo. Si alguien sube la transparencia, que mida
   antes: se aclara el fondo y el texto se pierde. */
.acceso .boton{width:100%;justify-content:center;margin-top:var(--sp-1);
  background:linear-gradient(135deg,
              rgba(158,35,95,.86) 0%,
              rgba(94,19,57,.9) 100%);
  backdrop-filter:blur(14px) saturate(1.3);
  -webkit-backdrop-filter:blur(14px) saturate(1.3);
  border:1px solid rgba(255,255,255,.38);
  box-shadow:var(--shadow-sm);
  transition:background var(--dur-base) var(--ease-standard),
             box-shadow var(--dur-base) var(--ease-standard),
             transform var(--dur-fast) var(--ease-standard)}
.acceso .boton:hover{background:linear-gradient(135deg,
              rgba(158,35,95,.94) 0%,
              rgba(94,19,57,.97) 100%);
  box-shadow:var(--shadow-md)}
.acceso .boton[disabled]{opacity:.55;cursor:default;box-shadow:var(--shadow-sm)}
.acceso .boton[disabled]:hover{background:linear-gradient(135deg,
              rgba(158,35,95,.86) 0%,
              rgba(94,19,57,.9) 100%)}

/* El ojo vive dentro de la caja del campo, igual que el aspa de limpiar vive
   dentro de la barra del buscador, y con el mismo comportamiento: discreto
   hasta que se pasa por encima. */
.acceso .ojo{flex:none;display:flex;align-items:center;color:var(--text-muted);
  padding:0;transition:color var(--dur-fast) var(--ease-standard)}
.acceso .ojo:hover{color:var(--brand-primary)}
.acceso .ojo:focus-visible{outline:none;box-shadow:var(--shadow-focus);
  border-radius:var(--radius-sm)}
/* La raya del ojo tachado está siempre dibujada; lo que se enciende y se
   apaga es ella sola. Con dos iconos distintos, uno podría quedar descuadrado
   respecto al otro; con uno solo, es imposible. */
.acceso .ojo .raya{opacity:0;transition:opacity var(--dur-fast) var(--ease-standard)}
.acceso .ojo.viendo .raya{opacity:1}

/* El aviso de error no se despega del campo al que se refiere: aquí el margen
   de arriba que trae .aviso sobra, porque la caja ya reparte el aire. */
.acceso .aviso{margin-top:0}

.acceso-pie{margin:0;text-align:center;
  font-size:var(--fs-xs);color:var(--text-muted)}

/* ---------- ¿Cómo te llamas? ----------
   Sólo la primera vez que entra alguien. Ocupa el sitio exacto del logo -el
   centro del escenario- porque es un relevo, no una llegada: el logo se apaga
   y esto se enciende en el mismo punto, así que se lee como una cosa que se
   convierte en otra. Por eso los dos van con el mismo tiempo.

   El círculo grande sigue detrás, quieto, como en cualquier carga. La barra
   es la del buscador con sus propias clases: aquí sólo se le quita el margen
   de abajo, que allí sirve para separarla de los resultados y aquí sobra. */
.pregunta-nombre{position:absolute;left:50%;top:50%;z-index:2;
  transform:translate(-50%,-50%);
  width:min(90vw,560px);
  display:flex;flex-direction:column;align-items:center;gap:var(--sp-5);
  opacity:0;pointer-events:none;
  transition:opacity 620ms var(--ease-standard)}
body.preguntando-nombre .pregunta-nombre{opacity:1;pointer-events:auto}

/* El logo se aparta apagándose, no moviéndose: si se fuera a algún lado
   habría que decidir a dónde, y no hay ningún sitio mejor que el suyo. */
body.preguntando-nombre .logo-central{opacity:0}

/* Los iconos no hace falta apagarlos: la pregunta sale sólo durante la
   entrada, cuando todavía no existen. Había una regla para apagarlos y era
   para "Cambiar mi nombre", que se quitó. */

.pregunta-nombre .buscador{margin:0;width:100%}
.pregunta-texto{margin:0;text-align:center;
  font-family:var(--font-display);font-size:var(--fs-h2);
  color:var(--text-title);line-height:var(--lh-heading)}

/* ---------- El logo hace sitio ----------
   El logo y la tarjeta tienen que quedar centrados COMO GRUPO, no cada uno
   por su lado. Centrado cada uno por su lado, el logo se queda en el medio y
   la tarjeta entera cuelga de él: entre los dos ocupan el doble hacia un lado
   que hacia el otro y el grupo sale descentrado. Medido antes de arreglarlo,
   en una ventana de 720 px de alto el botón de Entrar caía 148 px por debajo
   del borde.

   Así que el que se aparta es el escenario entero -logo y tarjeta, que es lo
   único que hay encendido-, lo justo para que el grupo quede centrado. En
   pantalla ancha se aparta hacia la izquierda y en estrecha hacia arriba, y
   es la misma cuenta en los dos casos, sólo que cambiando de eje. Las dos
   medidas se escriben siempre: la que no toca vale cero y no estorba, así que
   aquí no hay que preguntar nada.

   Y por eso el logo se mueve: se aparta al abrirse la tarjeta y vuelve a su
   sitio al cerrarse, con la misma curva y el mismo tiempo que todo lo demás.
   No es un efecto aparte, es el mismo gesto de siempre: hacer sitio y
   recuperarlo. La transición vive en .escenario y no en el logo porque el
   logo ya tiene dueño para su `transform` -la respiración- y dos animaciones
   no pueden compartirlo. Es la misma razón por la que .orbe y .cara van
   separadas.

   Cuánto hay que apartarse depende de lo grande que sea la tarjeta, y eso
   desde aquí no se sabe: lo mide acceso.js, igual que app.js mide y escribe
   --ancho-corto para la barra acortada. */
.escenario{transition:transform 900ms var(--ease-standard)}
body.accediendo .escenario{
  transform:translate(calc(var(--izquierda-acceso,0px) * -1),
                      calc(var(--subida-acceso,0px)    * -1))}

/* ---------- Iconos flotantes ----------
   Van colocados con --x/--y respecto al centro del escenario.
   La posición la fija .orbe; el flotar, el hijo .cara: así una cosa
   no pisa la otra (ambas usarían transform). */
.orbe{position:absolute;left:calc(50% + var(--x));top:calc(50% + var(--y));
  transform:translate(-50%,-50%) scale(.2);opacity:0;
  display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);
  transition:opacity 900ms var(--ease-standard) calc(var(--i) * 600ms),
             transform 900ms cubic-bezier(.2,.9,.3,1) calc(var(--i) * 600ms)}
body.orbes .orbe{opacity:1;transform:translate(-50%,-50%) scale(1)}

/* Los iconos son ilustraciones del mismo estilo que el logo, así que van
   sueltas: sin disco ni borde detrás, igual que el logo del centro. */
.orbe .cara{width:var(--ancho,112px);height:112px;display:block;
  animation:flotar var(--dur-flote,7s) ease-in-out var(--retraso,0s) infinite}
.orbe .cara img{width:100%;height:100%;object-fit:contain;
  filter:drop-shadow(0 6px 14px rgba(94,19,57,.16));
  transition:transform var(--dur-base) var(--ease-standard),
             filter var(--dur-base) var(--ease-standard)}
.orbe:hover .cara img,.orbe:focus-visible .cara img{transform:scale(1.09);
  filter:drop-shadow(0 12px 26px rgba(94,19,57,.30))}
.orbe:focus-visible{outline:none}
.orbe .nombre{font-family:var(--font-display);font-size:var(--fs-body);
  font-weight:var(--fw-semibold);color:var(--text-title);white-space:nowrap}

/* Recorrido corto pero perceptible, y con un punto de escala para que
   recuerde a la deriva del círculo de carga. */
@keyframes flotar{
  0%,100%{transform:translate(0,0) scale(1)}
  20%    {transform:translate(9px,-14px) scale(1.02)}
  40%    {transform:translate(-6px,-22px) scale(1)}
  60%    {transform:translate(-11px,-9px) scale(.985)}
  80%    {transform:translate(5px,4px) scale(1.01)}}

/* Al elegir destino se apagan los otros dos iconos y ya está: en la pantalla
   se quedan el logo, el icono pulsado y el círculo. El degradado sigue
   moviéndose con normalidad: no se toca. */
body.enfocando .orbe:not(.elegido){opacity:0;transition-delay:0ms}

/* Después el icono simplemente se apaga donde está: ni crece, ni encoge,
   ni se mueve. Quien vuelve al centro es el círculo, el mismo que se achicó.
   El tamaño se fija aquí porque al retirar la clase `orbes` el icono
   volvería a su escala reducida y se vería encoger mientras se apaga. */
.orbe.apagando{opacity:0 !important;
  transform:translate(-50%,-50%) scale(1) !important;
  transition:opacity 900ms var(--ease-standard) !important}

/* Al elegir destino, el logo no cambia de nada: ni de tamaño, ni de sitio,
   ni de opacidad. Sigue respirando igual que en la carga, y por eso no hay
   aquí ninguna regla que lo toque. Quien se mueve es el círculo, y de eso
   se encarga inicio.js. */


@keyframes desvanecer{from{opacity:0}to{opacity:1}}

/* (Las reglas de .revelable van al final del archivo: ver "Aparición al
   desplazarse". Tienen que declararse después de las tarjetas para que su
   transición no quede anulada por la de éstas.) */

/* Quien haya pedido menos movimiento entra directo, sin vuelo ni respiración. */
@media (prefers-reduced-motion:reduce){
  .halo,.halo i,
  .logo-central,.orbe .cara{animation:none}
  .halo-marco{transition:none}
}

/* En pantallas estrechas los iconos se apilan bajo el logo. */
/* En pantallas estrechas los iconos se acercan al logo, pero siguen
   colocados alrededor: el logo debe quedar centrado en la ventana para
   que el relevo con la pantalla de carga siga siendo invisible. */
@media (max-width:720px){
  .orbe .cara{width:88px;height:88px}
  .orbe .nombre{font-size:var(--fs-sm)}
}

.eyebrow{font-size:var(--fs-xs);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--brand-accent);font-weight:var(--fw-bold);margin:0 0 var(--sp-3)}

/* ---------- Cambiar de sección desde la barra ----------
   Se apaga lo que hay MENOS EL LOGO, que es el que viaja. Ni la sección
   entera ni el círculo: sólo su contenido. Ver irDesdeLaBarra() en inicio.js.

   La salida dura lo mismo para todo (380 ms) para que se lea como una sola
   cosa apagándose y no como varias a destiempo. */
body.saliendo-seccion .cabecera-seccion h2,
body.saliendo-seccion .cabecera-seccion .intro,
body.saliendo-seccion .azulejo,
body.saliendo-seccion .rejilla > .tarjeta,
body.saliendo-seccion #ficha,
body.saliendo-seccion #panel-buscador,
body.saliendo-seccion #panel-calculadora,
body.saliendo-seccion #panel-escala{
  opacity:0 !important;
  transition:opacity 380ms var(--ease-standard) !important}

/* Al salir del inicio, los iconos se recogen todos a la vez: sin el
   escalonado de la entrada, que aquí duraría casi dos segundos. */
body.recogiendo-inicio .orbe{opacity:0;transform:translate(-50%,-50%) scale(.86);
  transition:opacity 380ms var(--ease-standard),
             transform 380ms var(--ease-standard)}

/* Al volver al inicio, el logo del centro no entra desde cero: releva a uno
   que ya está posado en su sitio, así que se le quita `entrarLogo` y su
   retraso, y se queda sólo respirando. */
body.logo-puesto .logo-central{
  animation:respirar 3.2s var(--ease-standard) infinite}

.seccion{padding:var(--sp-8) 0}
.seccion > .contenedor > h2{font-size:var(--fs-h2);margin-bottom:var(--sp-2)}
.seccion .intro{color:var(--text-muted);margin:0 0 var(--sp-6);max-width:var(--container-narrow)}
.rejilla{display:grid;gap:var(--sp-5);grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}

/* ---------- Tarjetas ---------- */
.tarjeta{background:var(--surface-card);border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-xs);padding:var(--sp-5)}
.tarjeta.elevada{box-shadow:var(--shadow-md)}
.tarjeta h3{font-size:var(--fs-h3);margin-bottom:var(--sp-2)}
.tarjeta p{margin:0;color:var(--text-muted);font-size:var(--fs-sm)}

.tarjeta-boton{text-align:left;width:100%;
  transition:box-shadow var(--dur-base) var(--ease-standard),
             border-color var(--dur-base) var(--ease-standard)}
.tarjeta-boton:hover{box-shadow:var(--shadow-md);border-color:var(--border-strong)}

/* ---------- Botones ---------- */
.boton{display:inline-flex;align-items:center;gap:var(--sp-2);
  padding:var(--sp-3) var(--sp-5);border-radius:var(--radius-pill);
  background:var(--brand-primary);color:var(--text-onbrand);font-weight:var(--fw-semibold);
  transition:background var(--dur-fast) var(--ease-standard)}
.boton:hover{background:var(--rose-600)}
.boton:active{transform:scale(.98)}
.boton:focus-visible{outline:none;box-shadow:var(--shadow-focus)}
.boton.fantasma{background:none;color:var(--brand-primary);
  border:1px solid var(--border-strong)}
.boton.fantasma:hover{background:var(--surface-tint)}

/* ---------- Formularios ---------- */
.campo{display:flex;flex-direction:column;gap:var(--sp-2)}
.campo label{font-size:var(--fs-sm);font-weight:var(--fw-semibold);color:var(--text-title)}
.campo .entrada{display:flex;align-items:center;gap:var(--sp-2);
  border:1px solid var(--border-subtle);border-radius:var(--radius-md);
  background:var(--white);padding:0 var(--sp-3)}
.campo .entrada:focus-within{border-color:var(--focus-ring);box-shadow:var(--shadow-focus)}
.campo input,.campo select{border:0;outline:none;background:none;padding:var(--sp-3) 0;
  width:100%;color:var(--text-title)}
.campo .sufijo{font-size:var(--fs-sm);color:var(--text-muted);white-space:nowrap}
.campos{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4)}
@media (max-width:560px){.campos{grid-template-columns:1fr}}

/* ---------- Resultados ---------- */
.resultados{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);margin-top:var(--sp-5)}
@media (max-width:560px){.resultados{grid-template-columns:1fr}}
.dato{background:var(--surface-invert);color:var(--text-onbrand);
  border-radius:var(--radius-lg);padding:var(--sp-5);text-align:center}
.dato.plano{background:var(--surface-tint);color:var(--text-title)}
.dato .valor{font-family:var(--font-display);font-size:var(--fs-h1);line-height:var(--lh-tight)}
.dato .unidad{font-size:var(--fs-body);opacity:.8;margin-left:4px}
.dato .etiqueta{font-size:var(--fs-xs);letter-spacing:var(--ls-caps);
  text-transform:uppercase;opacity:.85;margin-top:var(--sp-2)}

/* ---------- Avisos ---------- */
.aviso{border-radius:var(--radius-md);padding:var(--sp-4);font-size:var(--fs-sm);
  border:1px solid transparent;margin-top:var(--sp-4)}
.aviso strong{display:block;margin-bottom:4px;color:var(--text-title)}
.aviso.info{background:var(--info-100);border-color:var(--info-500)}
.aviso.exito{background:var(--success-100);border-color:var(--success-500)}
.aviso.alerta{background:var(--warning-100);border-color:var(--warning-500)}
.aviso.peligro{background:var(--danger-100);border-color:var(--danger-500)}

.descargo{font-size:var(--fs-xs);color:var(--text-muted);margin-top:var(--sp-4);
  padding-top:var(--sp-4);border-top:1px solid var(--border-subtle)}

/* ---------- Cabecera de sección (logo + título + entradilla) ---------- */
.cabecera-seccion{text-align:center;margin-bottom:var(--sp-7)}
/* El logo de la cabecera va en dos piezas, y no por capricho: `transform`
   sólo admite un dueño. El marco es el que viaja desde el centro de la
   pantalla (inicio.js le escribe su transición), y la imagen de dentro es la
   que respira. Al ir anidadas, las dos transformaciones se multiplican en vez
   de pisarse, y el logo respira también mientras vuela y ya colocado. */
.cabecera-seccion .logo-seccion{display:block;width:72px;height:72px;margin:0 auto var(--sp-4)}
.cabecera-seccion .logo-seccion img{width:100%;height:100%;object-fit:contain;
  animation:respirar 3.2s var(--ease-standard) infinite}
.cabecera-seccion h2{font-family:var(--font-display);font-size:var(--fs-h1);
  line-height:var(--lh-tight);margin-bottom:var(--sp-3)}
.cabecera-seccion .intro{max-width:var(--container-narrow);margin:0 auto;
  color:var(--text-muted);font-size:var(--fs-body-lg)}

/* ---------- Mosaico de buscadores ----------
   Las tres opciones son cuadrículas translúcidas: dejan pasar el círculo
   rosa que se pasea por detrás, igual que hace la barra superior. Nada de
   relleno sólido ni de sombras marcadas; lo que las separa del fondo es
   el desenfoque y un borde muy fino. */
.mosaico{display:grid;gap:var(--sp-5);
  grid-template-columns:repeat(3,1fr);max-width:960px;margin:0 auto}
@media (max-width:880px){.mosaico{grid-template-columns:1fr;max-width:460px}}

/* Velo bajo y desenfoque alto: lo que sostiene la legibilidad no es tapar el
   fondo, es difuminarlo. Con blur(24) lo de detrás pierde todo detalle y el
   texto -tinta oscura- se lee limpio aunque el cristal deje ver el círculo.

   La opacidad tarda 900 ms como en el inicio: es lo que dura el apagarse de
   los otros dos al elegir uno. */
.azulejo{display:flex;flex-direction:column;align-items:flex-start;
  gap:var(--sp-2);text-align:left;width:100%;
  padding:var(--sp-6) var(--sp-5) var(--sp-5);
  border-radius:var(--radius-xl);
  background:rgba(255,255,255,.28);
  backdrop-filter:blur(24px) saturate(1.15);
  -webkit-backdrop-filter:blur(24px) saturate(1.15);
  border:1px solid rgba(255,255,255,.55);
  box-shadow:var(--shadow-xs);
  transition:background var(--dur-base) var(--ease-standard),
             border-color var(--dur-base) var(--ease-standard),
             box-shadow var(--dur-base) var(--ease-standard),
             opacity 900ms var(--ease-standard),
             transform var(--dur-base) var(--ease-standard)}
.azulejo:hover{background:rgba(255,255,255,.46);
  border-color:var(--border-strong);box-shadow:var(--shadow-md);
  transform:translateY(-3px)}
.azulejo:focus-visible{outline:none;box-shadow:var(--shadow-focus)}

/* ---------- Elegir uno de los tres ----------
   Mismo gesto que en el inicio: se apagan los otros dos y los textos, y el
   elegido se queda a solas antes de irse. El logo y el círculo no se tocan:
   ellos siguen su viaje. */
body.eligiendo .cabecera-seccion h2,
body.eligiendo .cabecera-seccion .intro,
body.eligiendo .azulejo:not(.elegido){opacity:0;transition-delay:0ms}
/* El elegido se apaga donde está: ni crece, ni encoge, ni se mueve. */
.azulejo.apagandose{opacity:0 !important;transform:none !important;
  transition:opacity 900ms var(--ease-standard) !important}

/* La ilustración va suelta, sin disco ni recuadro detrás: el azulejo ya es la
   superficie. Igual que los iconos del inicio, y con la misma sombra. */
.azulejo-icono{display:block;margin-bottom:var(--sp-3)}
.azulejo-icono img{width:92px;height:92px;object-fit:contain;
  filter:drop-shadow(0 6px 14px rgba(94,19,57,.16));
  transition:transform var(--dur-base) var(--ease-standard),
             filter var(--dur-base) var(--ease-standard)}
.azulejo:hover .azulejo-icono img{transform:scale(1.06);
  filter:drop-shadow(0 12px 26px rgba(94,19,57,.28))}
.azulejo-icono svg{width:34px;height:34px}
.azulejo h3{font-family:var(--font-display);font-size:var(--fs-h3)}
/* Sobre cristal, el texto pide un punto más de contraste que sobre papel. */
.azulejo p{margin:0;color:var(--text-body);font-size:var(--fs-sm)}

/* Barra de vuelta al mosaico, encima del buscador abierto. */
.cabecera-buscador{display:flex;align-items:center;gap:var(--sp-4);
  flex-wrap:wrap;max-width:760px;margin:0 auto var(--sp-5)}

/* Sólo una flecha. El texto sobraba: se sabe de dónde se viene. Mismo cristal
   que la barra y que las cuadrículas.

   Es el botón redondo de la web, y por eso lo comparte también el de enviar
   de Celestia: una sola declaración para los dos, en vez de dos que hay que
   acordarse de cambiar a la vez. Lo único que cambia entre ellos es hacia
   dónde apunta la flecha. */
.volver,.enviar{display:flex;align-items:center;justify-content:center;
  width:42px;height:42px;border-radius:50%;
  color:var(--brand-primary);
  background:rgba(255,255,255,.45);
  backdrop-filter:blur(16px) saturate(1.15);
  -webkit-backdrop-filter:blur(16px) saturate(1.15);
  border:1px solid rgba(255,255,255,.7);
  box-shadow:var(--shadow-xs);
  transition:background var(--dur-base) var(--ease-standard),
             border-color var(--dur-base) var(--ease-standard),
             box-shadow var(--dur-base) var(--ease-standard),
             transform var(--dur-base) var(--ease-standard)}
.volver svg,.enviar svg{transition:transform var(--dur-base) var(--ease-standard)}
.volver:hover,.enviar:hover{background:rgba(255,255,255,.65);
  border-color:var(--border-strong);box-shadow:var(--shadow-md)}
/* Al pasar por encima, la flecha se asoma hacia atrás. */
.volver:hover svg{transform:translateX(-2px)}
/* Y al pulsarlo se hunde y da un golpe de luz alrededor. */
.volver:active,.enviar:active{transform:scale(.9)}
.volver:active svg{transform:translateX(-4px)}
.volver:focus-visible,.enviar:focus-visible{outline:none;box-shadow:var(--shadow-focus)}

/* ---------- Buscador grande ----------
   Una barra de cristal y nada más: fondo blanco a media opacidad con el
   fondo desenfocado por detrás, borde muy fino y esquinas de píldora.
   Sin resplandores ni gradientes: se probaron y se quitaron a propósito. */
/* Al elegir un resultado la barra se acorta hasta dejar sólo la lupa y el
   nombre. El ancho exacto lo mide app.js y lo escribe en --ancho-corto: no se
   puede poner aquí porque depende de lo largo que sea el nombre. */
.buscador{position:relative;max-width:760px;margin:0 auto var(--sp-7);
  transition:max-width 620ms var(--ease-standard)}
.buscador.corta{max-width:var(--ancho-corto,320px)}
/* Con la barra corta el campo ya no se escribe: se mira. Quien manda para
   volver a buscar es la lupa. */
.buscador.corta input{pointer-events:none;text-overflow:ellipsis}
/* Fuera del todo, no sólo apagada: apagada seguía ocupando su sitio y, como
   los elementos de una caja flexible no encogen por debajo de su contenido,
   el aspa se salía por fuera de la píldora ya acortada. */
.buscador.corta .limpiar{display:none}
.buscador.corta .lupa{cursor:pointer;color:var(--brand-primary)}
.buscador.corta .lupa:hover{color:var(--rose-500);transform:scale(1.08)}

/* La lupa es un botón desde el principio, aunque sólo haga algo cuando la
   barra está corta. Así no cambia de sitio ni de tamaño al acortarse. */
.buscador .lupa{flex:none;display:flex;align-items:center;justify-content:center;
  color:var(--brand-primary);cursor:default;
  transition:color var(--dur-base) var(--ease-standard),
             transform var(--dur-base) var(--ease-standard)}
.buscador .lupa:focus-visible{outline:none;box-shadow:var(--shadow-focus);
  border-radius:var(--radius-pill)}

.buscador .caja{position:relative;z-index:1;
  display:flex;align-items:center;gap:var(--sp-3);
  background:rgba(255,255,255,.62);
  backdrop-filter:blur(20px) saturate(1.4);
  -webkit-backdrop-filter:blur(20px) saturate(1.4);
  border:1px solid rgba(255,255,255,.8);
  border-radius:var(--radius-pill);padding:var(--sp-4) var(--sp-5);
  box-shadow:var(--shadow-sm);
  transition:box-shadow var(--dur-base) var(--ease-standard),
             background var(--dur-base) var(--ease-standard),
             border-color var(--dur-base) var(--ease-standard),
             transform var(--dur-base) var(--ease-standard)}
.buscador .caja:hover{border-color:rgba(255,255,255,.95);box-shadow:var(--shadow-md)}
/* Al escribir, el cristal se aclara un punto y la barra se levanta. */
.buscador .caja:focus-within{background:rgba(255,255,255,.78);
  border-color:var(--white);box-shadow:var(--shadow-lg);transform:translateY(-2px)}
.buscador .caja svg{flex:none;color:var(--brand-primary)}
/* `min-width:0` para que el campo pueda encogerse: sin esto no baja de su
   contenido mínimo y la caja desborda la píldora cuando la barra se acorta. */
.buscador input{flex:1;min-width:0;border:0;outline:none;background:none;
  font-size:var(--fs-body-lg);color:var(--text-title);padding:var(--sp-1) 0}
.buscador input::placeholder{color:var(--ink-300)}
.buscador .limpiar{flex:none;color:var(--text-muted);font-size:var(--fs-h3);
  line-height:1;padding:0 var(--sp-2);opacity:0;pointer-events:none;
  transition:opacity var(--dur-fast) var(--ease-standard)}
.buscador.con-texto .limpiar{opacity:1;pointer-events:auto}
.buscador .limpiar:hover{color:var(--brand-primary)}

/* Sugerencias en vivo */
.sugerencias{position:absolute;top:calc(100% + var(--sp-2));left:0;right:0;z-index:15;
  background:var(--white);border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);
  overflow:hidden;animation:aparecer var(--dur-base) var(--ease-standard);
  transition:opacity 260ms var(--ease-standard),
             transform 260ms var(--ease-standard)}
@keyframes aparecer{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}

/* Al borrar lo escrito, el panel NO se mueve: son sus renglones los que se
   recogen, exactamente igual que cuando se descarta uno escribiendo (ver
   .sugerencias button.saliendo, más abajo). Aquí sólo se apaga el cristal
   que los sostiene, para que el último fotograma no acabe en un filo.

   `animation:none` no sobra: si el panel acababa de aparecer, su animación
   de entrada seguiría mandando sobre la opacidad y no se apagaría. */
.sugerencias.yendose{opacity:0;animation:none;pointer-events:none}
.sugerencias button{display:flex;align-items:center;gap:var(--sp-3);width:100%;
  text-align:left;padding:var(--sp-3) var(--sp-5);
  border-bottom:1px solid var(--border-subtle);
  transition:background var(--dur-fast) var(--ease-standard)}
.sugerencias button:last-child{border-bottom:0}

/* Las que el buscador descarta no desaparecen de golpe: se apagan y se
   recogen. Y las que entran, entran encendiéndose. Las que siguen valiendo
   no se tocan, así que ni parpadean ni se mueven: sólo les cambia el
   resaltado rosa de la parte escrita. */
.sugerencias button{overflow:hidden;
  transition:background var(--dur-fast) var(--ease-standard),
             opacity 260ms var(--ease-standard),
             max-height 260ms var(--ease-standard),
             padding 260ms var(--ease-standard)}
.sugerencias button.entrando,
.sugerencias button.saliendo{opacity:0;max-height:0;
  padding-top:0;padding-bottom:0;border-bottom-width:0}
.sugerencias button{max-height:80px}
.sugerencias .sin-nada .nombre{color:var(--text-muted)}
.sugerencias button:hover,.sugerencias button.activa{background:var(--surface-tint)}
.sugerencias .nombre{font-family:var(--font-display);font-weight:var(--fw-semibold);
  font-size:var(--fs-body-lg);color:var(--text-title)}
.sugerencias .via{font-size:var(--fs-sm);color:var(--text-muted);margin-left:auto;
  text-align:right;white-space:nowrap}
.sugerencias mark{background:var(--rose-200);color:var(--brand-primary);
  font-weight:var(--fw-bold);border-radius:3px;padding:0 2px}

.alias{font-size:var(--fs-sm);color:var(--text-muted);margin-top:var(--sp-2)}

/* ---------- Iconos de tarjeta ---------- */
.icono{width:56px;height:56px;border-radius:var(--radius-md);
  background:var(--surface-tint);color:var(--brand-primary);
  display:flex;align-items:center;justify-content:center;margin-bottom:var(--sp-4);
  transition:background var(--dur-base) var(--ease-standard),
             transform var(--dur-base) var(--ease-standard)}
.tarjeta-boton:hover .icono{background:var(--brand-primary);color:var(--text-onbrand);
  transform:scale(1.06)}
.tarjeta-boton{transform:translateY(0)}
.tarjeta-boton:hover{transform:translateY(-3px);background:var(--cream-100)}

.insignia{display:inline-block;padding:4px var(--sp-3);border-radius:var(--radius-pill);
  background:var(--surface-tint);color:var(--brand-primary);
  font-size:var(--fs-xs);font-weight:var(--fw-bold);
  letter-spacing:var(--ls-caps);text-transform:uppercase}

/* ---------- Ficha farmacológica ----------
   De cristal, como las cuadrículas y la barra: la misma superficie en toda
   la sección. El velo va algo más alto que en los azulejos porque aquí hay
   mucho texto seguido y en párrafos largos el fondo cansa la lectura. */
.tarjeta.ficha{background:rgba(255,255,255,.48);
  backdrop-filter:blur(26px) saturate(1.25);
  -webkit-backdrop-filter:blur(26px) saturate(1.25);
  border:1px solid rgba(255,255,255,.6);
  border-radius:var(--radius-xl)}

.ficha .encabezado{background:rgba(253,238,240,.5);
  margin:calc(var(--sp-5) * -1) calc(var(--sp-5) * -1) var(--sp-6);
  padding:var(--sp-5) var(--sp-6);
  border-bottom:1px solid rgba(255,255,255,.6);
  border-radius:var(--radius-xl) var(--radius-xl) 0 0}
.ficha .encabezado h3{font-family:var(--font-display);font-size:var(--fs-h2);
  margin-bottom:var(--sp-2)}
/* Grupo y subgrupo, una al lado de la otra y con la misma etiqueta. */
.ficha .encabezado .etiquetas{display:flex;flex-wrap:wrap;gap:var(--sp-2);
  margin:0 0 var(--sp-3)}
.ficha .encabezado .alias{margin-top:0}

/* La ficha aparece cuando la barra ha terminado de acortarse, y se va igual
   al pulsar la lupa. Un desvanecimiento a secas apenas se lee en una tarjeta
   tan grande: parece que estaba y ya. Con un palmo de recorrido -sube al
   entrar, baja al salir- el ojo sí registra el gesto.

   El orden importa: `saliendo` va después de `entrando` porque comparten
   especificidad y necesita imponer su duración, más corta. */
/* Curva pareja y no la de la web (--ease-standard). Aquí lo que importa es
   que el cambio se VEA, y esa curva está tan cargada al principio que a un
   cuarto del tiempo ya se ha ido el 72%: se esfuma de golpe y luego se
   arrastra. Con ésta la opacidad avanza a ritmo constante. */
#ficha{transition:opacity 700ms cubic-bezier(.35,0,.65,1),
                  transform 700ms cubic-bezier(.35,0,.65,1)}
/* `transition:none` al apagarla, y no es un detalle: sin esto, poner la clase
   arrancaba un fundido de 700 ms de 1 a 0, y al quitarla un fotograma después
   la ficha volvía hacia 1 desde casi 1. Nunca llegaba a estar apagada, así
   que nunca se la veía encenderse. Apagar es instantáneo; encender, no. */
#ficha.entrando{opacity:0;transform:translateY(18px);transition:none}
#ficha.saliendo{opacity:0;transform:translateY(12px);
  transition:opacity 520ms cubic-bezier(.35,0,.65,1),
             transform 520ms cubic-bezier(.35,0,.65,1)}

/* Toda la ficha en Lora, texto incluido. En el resto de la web el cuerpo va
   en la de palo; aquí no, porque la ficha es lo que se lee de verdad y es lo
   que más se parece a la guía impresa. */
.ficha,.ficha p,.ficha li,.ficha dd,.ficha dt,.volteada{font-family:var(--font-serif)}

/* Los doce apartados. Cada uno con su regla arriba: es lo que deja pasar la
   vista de un apartado a otro sin tener que leerlos. */
.apartado{padding-top:var(--sp-5);border-top:1px solid var(--border-subtle)}
.apartado:first-child{padding-top:0;border-top:0}
.apartado + .apartado{margin-top:var(--sp-5)}
/* Título en Lora y en el rosa de marca, del tamaño de un h4: sin mayúsculas
   ni espaciado forzado, que en una serif se leen peor. */
.apartado > h3{font-family:var(--font-serif);font-size:var(--fs-h4);
  color:var(--brand-accent);font-weight:var(--fw-semibold);
  margin-bottom:var(--sp-3)}
.apartado p{margin:0 0 var(--sp-3);color:var(--text-body)}
.apartado p:last-child{margin-bottom:0}
.apartado ul{margin:0;padding-left:var(--sp-5);color:var(--text-body)}
.apartado li{margin-bottom:var(--sp-2)}
.apartado li:last-child{margin-bottom:0}

/* Subapartados: los de la posología y las fases. Van sangrados y con un
   filete a la izquierda para que se lean como partes de su apartado, no como
   apartados nuevos. */
.apartado .parte{margin-top:var(--sp-5);padding-left:var(--sp-4);
  border-left:2px solid var(--rose-200)}
.apartado .parte:first-of-type{margin-top:0}
.apartado .parte h4{font-family:var(--font-serif);font-size:var(--fs-body-lg);
  font-weight:var(--fw-semibold);color:var(--text-title);
  margin-bottom:var(--sp-2);display:flex;align-items:baseline;gap:var(--sp-2)}
/* El número de la fase, en su disco. Va como parte del título y no como
   lista numerada para que el orden lo mande el código y no el navegador. */
.apartado .parte h4 .numero{flex:none;width:22px;height:22px;border-radius:50%;
  background:var(--surface-tint);color:var(--brand-primary);
  font-family:var(--font-sans);font-size:var(--fs-xs);font-weight:var(--fw-bold);
  display:inline-flex;align-items:center;justify-content:center;
  align-self:center}

/* Pares etiqueta/valor: lo que se lee como ficha técnica. */
.apartado .datos{margin:0 0 var(--sp-3);display:grid;
  grid-template-columns:auto 1fr;gap:var(--sp-1) var(--sp-3)}
.apartado .datos dt{color:var(--text-title);font-weight:var(--fw-semibold)}
.apartado .datos dd{margin:0;color:var(--text-body)}
@media (max-width:560px){
  .apartado .datos{grid-template-columns:1fr;gap:0}
  .apartado .datos dt{margin-top:var(--sp-2)}
}

/* La nota: lo que matiza lo anterior sin ser lo principal. */
.apartado .nota{margin-top:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  background:rgba(248,245,244,.7);border-left:2px solid var(--rose-300);
  border-radius:0 var(--radius-sm) var(--radius-sm) 0;
  font-size:var(--fs-sm);color:var(--text-muted)}
.apartado .nota strong{color:var(--brand-primary)}

/* ---------- Cuadrículas que se voltean ----------
   Efectos adversos e interacciones. Delante sólo el nombre; el porqué está
   detrás y se ve al pulsarla. Mismo cristal que el resto de la sección. */
.volteables{display:grid;gap:var(--sp-3);
  grid-template-columns:repeat(auto-fill,minmax(190px,1fr))}
.volteable{display:flex;align-items:center;justify-content:center;
  min-height:76px;padding:var(--sp-4);text-align:center;
  border-radius:var(--radius-lg);
  background:rgba(255,255,255,.42);
  backdrop-filter:blur(14px) saturate(1.15);
  -webkit-backdrop-filter:blur(14px) saturate(1.15);
  border:1px solid rgba(255,255,255,.7);
  box-shadow:var(--shadow-xs);
  transition:background var(--dur-base) var(--ease-standard),
             border-color var(--dur-base) var(--ease-standard),
             box-shadow var(--dur-base) var(--ease-standard),
             opacity var(--dur-base) var(--ease-standard),
             transform var(--dur-base) var(--ease-standard)}
.volteable .nombre{font-family:var(--font-serif);font-size:var(--fs-body);
  font-weight:var(--fw-semibold);color:var(--text-title);line-height:var(--lh-heading)}
.volteable:hover{background:rgba(255,255,255,.62);border-color:var(--border-strong);
  box-shadow:var(--shadow-md);transform:translateY(-2px)}
.volteable:focus-visible{outline:none;box-shadow:var(--shadow-focus)}
/* Mientras está en alto, su hueco se queda vacío: así la rejilla no se
   recoloca y la vuelta encaja en el sitio exacto. */
.volteable.en-alto{opacity:0;pointer-events:none}

/* ---------- Gravedad ----------
   Efectos adversos e interacciones, los dos igual. La tarjeta entera se tiñe
   de uno de tres tonos: rojo lo que hay que vigilar sí o sí, ámbar lo
   intermedio, verde lo poco probable o lo leve. Sin rótulos ni leyenda: los
   tres colores ya se entienden solos, y en un apartado que se lee de un
   vistazo cualquier texto de más estorba.

   Los tres colores son los que la web ya usa para los avisos y para los
   tramos de las escalas -danger, warning, success-: no hay ningún color
   nuevo. Van muy rebajados a propósito: la mezcla es poco más de la mitad
   del tono y el resto blanco traslúcido, de modo que la tarjeta se tiñe pero
   sigue siendo el mismo cristal del resto de la sección y el texto en tinta
   oscura no pierde ni un punto de contraste.

   Las tres parejas se declaran una sola vez y las usan la cuadrícula del
   apartado y la tarjeta ya volteada. */
.grado-alta {--tinte:var(--danger-100); --filo:var(--danger-500)}
.grado-media{--tinte:var(--warning-100);--filo:var(--warning-500)}
.grado-baja {--tinte:var(--success-100);--filo:var(--success-500)}

.volteable[class*="grado-"]{
  background:color-mix(in srgb,var(--tinte) 52%,rgba(255,255,255,.58));
  border-color:color-mix(in srgb,var(--filo) 20%,rgba(255,255,255,.7))}
.volteable[class*="grado-"]:hover{
  background:color-mix(in srgb,var(--tinte) 74%,rgba(255,255,255,.62));
  border-color:color-mix(in srgb,var(--filo) 40%,rgba(255,255,255,.7))}

/* La que se levanta es la misma tarjeta, así que se lleva su color puesto. */
.volteada[class*="grado-"] .cara{
  background:color-mix(in srgb,var(--tinte) 42%,rgba(255,255,255,.9));
  border-color:color-mix(in srgb,var(--filo) 20%,rgba(255,255,255,.85))}

/* El cursor que parpadea mientras el nombre se escribe de vuelta. Se apoya en
   el propio texto, así que sigue a la última letra sin tener que medirla. */
.volteable .nombre.escribiendo::after{content:"";display:inline-block;
  width:1px;height:1em;margin-left:2px;vertical-align:-.15em;
  background:var(--brand-accent);animation:cursor .7s steps(1) infinite}
@keyframes cursor{0%,49%{opacity:1}50%,100%{opacity:0}}

/* El velo de detrás. Del mismo cristal que todo lo demás, sólo que a pantalla
   completa: no oscurece, difumina. */
.velo-volteo{position:fixed;inset:0;z-index:60;
  background:rgba(252,252,251,.45);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  opacity:0;transition:opacity var(--dur-slow) var(--ease-standard)}
.velo-volteo.abierto{opacity:1}

/* La cuadrícula en alto. Se monta ya a su tamaño final y de encajarla sobre
   la pequeña y soltarla se encarga app.js.

   La altura NO está escrita aquí: la pone el texto. Las explicaciones van de
   dos renglones a doce, y con una altura fija las largas se salían por
   debajo de la tarjeta. Quien manda es la cara de detrás, que es la que
   lleva el texto: va en el flujo y por eso estira el giro. La de delante,
   que está vacía, se pone encima ocupando lo que haya salido.

   Y como la altura ya no se sabe de antemano, centrarla tampoco se puede
   hacer con un margen escrito a mano: lo mide y lo escribe app.js. */
.volteada{position:fixed;z-index:61;left:50%;top:50%;
  width:min(420px,88vw);perspective:1200px;pointer-events:none}
.volteada .giro{position:relative;width:100%;
  transform-style:preserve-3d;
  transition:transform var(--dur-slow) var(--ease-standard)}
.volteada.abierta .giro{transform:rotateY(180deg)}

.volteada .cara{display:flex;
  border-radius:var(--radius-xl);padding:var(--sp-5);
  background:rgba(255,255,255,.86);
  backdrop-filter:blur(22px) saturate(1.2);
  -webkit-backdrop-filter:blur(22px) saturate(1.2);
  border:1px solid rgba(255,255,255,.85);
  box-shadow:var(--shadow-lg);
  -webkit-backface-visibility:hidden;backface-visibility:hidden}
.volteada .delante{position:absolute;inset:0;
  align-items:center;justify-content:center;text-align:center}
.volteada .delante .nombre{font-family:var(--font-serif);font-size:var(--fs-h4);
  font-weight:var(--fw-semibold);color:var(--text-title)}
/* `min-height` y no `height`: es el suelo para las explicaciones cortas, para
   que una de dos renglones no salga como una pastilla. De ahí para arriba
   crece con el texto. Y un techo, por si alguna se dispara. */
.volteada .detras{position:relative;transform:rotateY(180deg);
  flex-direction:column;pointer-events:auto;
  min-height:210px;max-height:82vh;overflow-y:auto}
.volteada .detras h5{font-family:var(--font-serif);font-size:var(--fs-h4);
  color:var(--brand-accent);font-weight:var(--fw-semibold);
  margin:0 var(--sp-6) var(--sp-3) 0;line-height:var(--lh-heading)}
.volteada .detras p{margin:0;color:var(--text-body);font-size:var(--fs-sm)}
.volteada .cerrar{position:absolute;top:var(--sp-3);right:var(--sp-4);
  font-size:var(--fs-h3);line-height:1;color:var(--text-muted);
  padding:var(--sp-1) var(--sp-2);border-radius:var(--radius-sm);
  transition:color var(--dur-fast) var(--ease-standard)}
.volteada .cerrar:hover{color:var(--brand-primary)}

@media (prefers-reduced-motion:reduce){
  .volteada,.volteada .giro,.velo-volteo{transition:none}
}

/* ---------- Escalas ---------- */
.item-escala{border-bottom:1px solid var(--border-subtle);padding:var(--sp-4) 0}
.item-escala:last-of-type{border-bottom:0}
.item-escala p{font-weight:var(--fw-semibold);color:var(--text-title);
  margin:0 0 var(--sp-3);font-size:var(--fs-body)}
.opciones{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.opciones label{display:flex;align-items:center;gap:var(--sp-2);cursor:pointer;
  border:1px solid var(--border-subtle);border-radius:var(--radius-pill);
  padding:var(--sp-2) var(--sp-4);font-size:var(--fs-sm);
  transition:all var(--dur-fast) var(--ease-standard)}
.opciones label:hover{border-color:var(--border-strong);background:var(--rose-100)}
.opciones input{accent-color:var(--brand-primary)}
.opciones input:checked + span{font-weight:var(--fw-semibold);color:var(--brand-primary)}

/* ---------- Pie ---------- */
.pie{background:var(--surface-invert);color:var(--text-onbrand);
  padding:var(--sp-7) 0}
.pie p{margin:0 0 var(--sp-2);font-size:var(--fs-sm);opacity:.85}
.pie strong{font-family:var(--font-display);font-size:var(--fs-h4)}

/* ---------- Aparición al desplazarse ----------
   Va al final a propósito: .tarjeta-boton declara su propia transición y,
   al tener la misma especificidad, ganaba la que se escribe después.
   Por eso el desvanecimiento de las tarjetas se cortaba de golpe.
   Aquí se listan todas las propiedades juntas para que convivan.

   --i es la posición dentro de la rejilla: escalona la entrada. */
.revelable{opacity:0;
  transition:opacity 900ms var(--ease-standard) calc(var(--i,0) * 160ms),
             box-shadow var(--dur-base) var(--ease-standard),
             border-color var(--dur-base) var(--ease-standard),
             background var(--dur-base) var(--ease-standard),
             transform var(--dur-base) var(--ease-standard)}
.revelable.visto{opacity:1}
/* Al salir de pantalla se apaga rápido y sin escalonar, para que al volver
   a entrar el escalonado se vuelva a apreciar. */
.revelable:not(.visto){transition-duration:500ms;transition-delay:0ms}


/* En pantallas estrechas los iconos se recogen: en píxeles no cabrían.

   El `!important` no es un adorno: pintarOrbes() escribe --x y --y en el
   atributo `style` de cada icono, y un estilo en línea le gana a cualquier
   regla de la hoja por muy específica que sea. Sin esto, estas tres líneas
   no llegaban a aplicarse nunca y en el móvil los iconos de los lados se
   salían de la pantalla. */
@media (max-width:720px){
  .orbe[data-id="buscador"]    {--x:-33% !important;--y:-2% !important}
  .orbe[data-id="calculadoras"]{--x:33% !important;--y:-2% !important}
  .orbe[data-id="escalas"]     {--x:0% !important;--y:34% !important}
}

/* ---------- Llegada a una sección ----------
   Va al final del archivo por lo mismo que .revelable: comparte especificidad
   con las tarjetas y con los azulejos, y necesita ganarles.

   Mientras el logo vuela del centro a la cabecera, la sección espera apagada.
   Después entran los textos, y por último las cuadrículas. Los tiempos los
   lleva inicio.js: aquí sólo se dice cómo se ve cada paso. */

/* La cabecera no puede apagarse durante el vuelo: es donde está el logo. */
/* (La cabecera ya no se apaga al desplazarse: quedó fuera del vigilante,
   porque su entrada la manda la coreografía. Ver OBSERVABLES en inicio.js.) */
/* Por encima del resto mientras cruza la pantalla. */
body.aterrizando .cabecera-seccion .logo-seccion{position:relative;z-index:5}
/* `transition:none` mientras esperan: si no, se apagarían con un fundido a la
   vista en lugar de estar ya apagados cuando llega la sección. La transición
   sólo tiene que correr al encenderse, y por eso vive en la regla de abajo. */
body.aterrizando .cabecera-seccion h2,
body.aterrizando .cabecera-seccion .intro{opacity:0;transition:none}
.cabecera-seccion h2,
.cabecera-seccion .intro{transition:opacity 800ms var(--ease-standard)}

/* Las cuadrículas esperan a que los textos hayan terminado de entrar.
   Se excluye la que se acaba de elegir: esa se está apagando con su propio
   fundido y cortárselo aquí se vería como un tijeretazo.

   Los paneles -el buscador abierto, la calculadora, la escala- esperan lo
   mismo. Se montan mientras la pantalla es la de carga, así que si no se les
   apagara aquí asomarían por debajo del logo en mitad del viaje. */
body.esperando-cuadriculas .azulejo:not(.apagandose),
body.esperando-cuadriculas .rejilla > .tarjeta,
body.esperando-cuadriculas #panel-buscador,
body.esperando-cuadriculas #panel-calculadora,
body.esperando-cuadriculas #panel-escala{opacity:0 !important;transition:none !important}

/* Y entran con un fundido, a la vez que las cuadrículas hacen su zoom. */
#panel-buscador,#panel-calculadora,#panel-escala{
  transition:opacity 700ms var(--ease-standard)}

/* Entran creciendo y escalonadas. Es una animación y no una transición a
   propósito: al acabar deja de mandar sobre `transform`, y así el hover de
   la cuadrícula vuelve a ser suyo sin heredar ni el retraso ni la duración. */
.azulejo.entra,
.rejilla > .tarjeta.entra{
  animation:entrarCuadricula 700ms var(--ease-standard) calc(var(--i,0) * 110ms) backwards}
@keyframes entrarCuadricula{
  from{opacity:0;transform:scale(.88)}
  to  {opacity:1;transform:none}}

@media (prefers-reduced-motion:reduce){
  .azulejo.entra,.rejilla > .tarjeta.entra{animation:none}
}

/* ---------- Celestia ----------
   Va al final del archivo por lo mismo que .revelable y que el aterrizaje:
   apaga cosas que declaran su propia transición -la barra, el logo, los
   iconos- y necesita ganarles. Los tiempos los lleva celestia.js; aquí sólo
   se dice cómo se ve cada paso.

   Las dos formas del dibujo están escritas abajo, en .chispa path: un
   círculo y un brillo de cuatro puntas, los dos con la misma estructura
   -cuatro curvas y los mismos cuatro extremos- para que el navegador pueda
   ir de una a la otra. Lo único que cambia son los puntos de control, que en
   el brillo se recogen hacia el centro y le hunden los costados. */

/* El cielo va detrás del contenido y por delante del círculo: el polvo se ve
   pasar por debajo de la conversación, igual que el círculo se ve pasar por
   debajo de las cuadrículas. Y no recibe pulsaciones: es un dibujo. */
/* Se enciende exactamente mientras las nubes del círculo se apagan, y en el
   mismo tiempo: los dos lados del cruce duran --dur-rosa, y por eso en ningún
   momento se ve ni una cosa sola ni las dos. */
.cielo{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;
  opacity:0;transition:opacity var(--dur-rosa,1600ms) var(--ease-standard)}
.cielo.encendido{opacity:1}
/* Sólo guarda el degradado que usan todos los brillos: no se ve. */
.cielo .tintero{position:absolute;width:0;height:0}

/* Punto de anclaje sin tamaño en el centro de la ventana, que es donde llega
   el círculo. Las cuatro chispas se colocan respecto a él, así que mover el
   grupo entero es mover este punto.

   `--achique` lo escribe celestia.js: es lo que hay que encoger el icono
   recién nacido -que mide lo que medía el círculo, y eso depende de la
   ventana- para dejarlo del tamaño con el que se queda arriba. */
.chispas{position:absolute;left:50%;top:50%;width:0;height:0;
  transition:transform var(--dur-posar,850ms) cubic-bezier(.45,.05,.25,1),
             opacity 600ms var(--ease-standard)}
/* Recogido arriba para dejar sitio a la conversación, que entra por debajo. */
.chispas.posado{transform:translateY(calc(-50vh + 165px)) scale(var(--achique,.4))}

/* Cada chispa arranca en el centro y sin tamaño. La grande es la excepción:
   nace ya del tamaño del disco rosa y sin transición (ver .montando), porque
   ella no aparece, es el círculo. --dx y --dy son su sitio en el icono,
   medidos sobre el archivo (ver CELESTIA_CHISPAS en celestia.js). */
/* Sin resplandor alrededor: el brillo se dibuja y ya está. Lo único que lleva
   el filtro es el desenfoque de mientras son círculos, que es lo que los ata
   al círculo del que salen. */
/* `--cerca` lo escribe apartarElIcono(): es cuánto se ve el grupo según lo
   cerca que le pase el texto por debajo al desplazarse. Va en cada chispa y
   no en el grupo entero porque el grupo ya usa su opacidad para otra cosa
   -apagarse al empezar a conversar- y una sola opacidad no puede servir a dos
   amos. Aquí la transición es corta, que esto sigue al dedo. */
.chispa{position:absolute;left:0;top:0;
  width:var(--ancho);height:var(--ancho);
  margin:calc(var(--ancho) / -2) 0 0 calc(var(--ancho) / -2);
  transform:translate(0,0) scale(0);
  filter:blur(var(--difuso,0px));
  opacity:var(--cerca,1);
  transition:transform var(--dur-celestia,800ms) cubic-bezier(.2,.9,.3,1),
             filter var(--dur-morfar,700ms) var(--ease-standard),
             opacity 220ms var(--ease-standard)}
.chispa svg{width:100%;height:100%;display:block;overflow:visible}

/* Mientras se monta, ni transición ni desenfoque propio: el tamaño y el sitio
   se le dan de golpe, para que el brillo esté YA donde está el disco antes de
   que se vea nada. Sin esto se le vería crecer, y crecer es aparecer. */
.cielo.montando .chispa{transition:none}

/* Mientras son círculos, los cuatro van difuminados: son trozos de una nube,
   no dibujos. La grande lleva exactamente el mismo desenfoque que el halo del
   que sale -10 px, el mismo número de body.celestia-rosa-, que es el último
   detalle que hace que el relevo entre los dos no se note. Las tres pequeñas
   llevan menos, en proporción a lo que miden. */
.cielo.nacida .chispa{--difuso:3px}
.cielo.nacida .chispa-grande{--difuso:10px;transform:translate(0,0) scale(1)}

/* Del disco se desprenden las otras tres, cada una a su sitio, todavía
   círculos. La grande tiene --dx y --dy a cero, así que esta misma regla la
   deja donde está. */
.cielo.suelta .chispa{transform:translate(var(--dx),var(--dy)) scale(1)}

/* Y sólo entonces, los cuatro a la vez, dejan de ser círculos: se les hunden
   los costados, les salen las puntas y se afilan. Van juntas la forma y el
   desenfoque porque son la misma cosa: dejar de ser nube y ser brillo. */
.cielo.estrellas .chispa{--difuso:0px}

/* El paso de círculo a brillo. Las dos formas tienen los mismos cuatro
   extremos -arriba, derecha, abajo, izquierda- y cuatro curvas cada una: por
   eso el navegador puede interpolarlas. En el círculo los puntos de control
   están fuera, empujando la curva hacia afuera; en el brillo se meten hacia
   el centro y los costados se hunden hasta dejar las cuatro puntas. */
.chispa path,.polvo path{
  d:path("M 0,-50 C 27.6,-50 50,-27.6 50,0 C 50,27.6 27.6,50 0,50 C -27.6,50 -50,27.6 -50,0 C -50,-27.6 -27.6,-50 0,-50 Z");
  transition:d var(--dur-morfar,800ms) var(--ease-standard)}
/* La marca de Celestia en la conversación entra en esta misma regla: es el
   mismo brillo, así que es la misma forma y se escribe una sola vez. */
.cielo.estrellas .chispa path,.polvo path,.marca-celestia path{
  d:path("M 0,-50 C 3,-22 22,-3 50,0 C 22,3 3,22 0,50 C -3,22 -22,3 -50,0 C -22,-3 -3,-22 0,-50 Z")}
/* La lluvia: muchos más y diminutos, subiendo despacio por toda la web.
   Cada uno lleva su sitio, su tamaño y su paso escritos por celestia.js.

   No aparecen todos a la vez: van saliendo uno detrás de otro. Eso lo hace
   --n, que es el turno de cada uno, multiplicado por el respiro que va de
   uno al siguiente. Con treinta y dos motas la lluvia tarda unos tres
   segundos en estar entera, y ese ir llenándose es justo lo que se busca.
   Al recogerse, en cambio, se van todas juntas: el retraso se pone a cero,
   porque en la vuelta lo que toca es despejar, no ir contando. */
/* La lluvia entera se enciende y se apaga con `polvoreado`, igual que cada
   mota. Que dependa de lo MISMO no es redundante: es lo que impide que asome
   de camino.

   Pasó al cerrar la conversación. La capa se destapaba porque se dejaba de
   conversar, y las motas se iban porque se quitaba `polvoreado`; una subía
   mientras las otras bajaban, y en ese cruce la lluvia se veía un instante
   justo cuando ya no debía estar. Colgando las dos de la misma clase, se van
   a la vez y no hay cruce que ver. */
.polvo{position:absolute;inset:0;opacity:0;
  transition:opacity 600ms var(--ease-standard)}
.cielo.polvoreado .polvo{opacity:1}
/* Y mientras se conversa, tapada: gana en especificidad a la de arriba. */
body.celestia-conversando .cielo .polvo{opacity:0;transition-delay:0ms}
/* La subida va en el dibujo de dentro y el encenderse en la mota de fuera, y
   no es un capricho: la subida ya anima la opacidad -entra y sale por los
   bordes de la pantalla-, y una animación le gana siempre a una transición.
   En dos elementos anidados, las dos opacidades se multiplican y cada una
   puede hacer lo suyo sin pisar a la otra. */
.polvo i{position:absolute;left:var(--iz);bottom:-40px;
  width:var(--ancho);height:var(--ancho);display:block;
  opacity:0;transition:opacity 900ms var(--ease-standard)}
.cielo.polvoreado .polvo i{opacity:1;
  transition-delay:calc(var(--n,0) * 110ms)}
.polvo svg{width:100%;height:100%;display:block;overflow:visible;
  animation:subir var(--dur) linear var(--retraso) infinite}
@keyframes subir{
  0%  {transform:translate(0,0) rotate(0deg);opacity:0}
  10% {opacity:var(--opaco)}
  85% {opacity:var(--opaco)}
  100%{transform:translate(var(--vaiven),calc(-100vh - 80px)) rotate(150deg);opacity:0}}

/* ---------- Todo lo demás, apagado ----------
   Al pulsar el icono no queda nada en pantalla salvo el círculo: ni la barra
   de arriba, ni el logo, ni los cuatro iconos, ni el propio icono de
   Celestia. Los cuatro se van a la vez y sin escalonar -que aquí duraría casi
   dos segundos-, igual que al salir del inicio desde la barra. */
body.celestia .cabecera{opacity:0;pointer-events:none;
  transition:opacity 650ms var(--ease-standard)}
/* El logo, además de apagado, con la animación quitada. Y no sobra: en la
   vuelta, el inicio se vuelve a mostrar cuando las chispas todavía están
   recogiéndose, y al dejar de estar oculto el navegador REARRANCA `entrarLogo`
   -toda animación se reinicia cuando el elemento vuelve a pintarse-. Esa
   animación va de opacidad 0 a 1, y una animación le gana siempre a una
   declaración: el logo se encendía él solo en mitad del camino de vuelta.
   Sin animación, se queda apagado hasta el final, que es cuando le toca.

   Al quitarse la clase, la animación vuelve a declararse y arranca de cero:
   el logo entra entonces con su entrada de siempre, la misma con la que
   aparece al cargar la web. */
body.celestia .logo-central{opacity:0;animation:none;
  transition:opacity 650ms var(--ease-standard)}
body.celestia .orbe{opacity:0;pointer-events:none;
  transform:translate(-50%,-50%) scale(.86);
  transition:opacity 650ms var(--ease-standard),
             transform 650ms var(--ease-standard)}

/* El círculo no se apaga aparte: lo que se apaga son sus nubes, y eso ya lo
   lleva body.celestia-rosa. No hay dos cosas de las que una se quite y otra
   se ponga; hay una que va cambiando. */

/* ---------- La pantalla de Celestia ----------
   Es la de FARMA-Search, y no se parece: es la misma. Lleva las mismas
   etiquetas y las mismas clases -.cabecera-seccion, .buscador, .caja, .lupa-
   así que hereda su cristal, sus medidas y sus transiciones sin que aquí haya
   que repetir ni una regla. Lo de abajo es sólo lo que esta pantalla tiene y
   la otra no.

   El logo del proyecto no aparece por ningún lado: el de Celestia son las
   cuatro chispas del cielo, que a estas alturas ya están recogidas justo
   encima. El hueco de arriba es exactamente lo que ocupan. */
/* Esta pantalla cabe en la ventana y no se desplaza: la barra de la derecha
   aquí no llevaría a ninguna parte y sólo estorba.

   Para que quepa hay que descontar la cabecera, que aunque esté apagada sigue
   ocupando sus 73 px en el flujo -es `sticky`, no `fixed`-. Con `100vh` a
   secas la sección medía la ventana entera y, empezando debajo de la
   cabecera, se salía por abajo justo esos 73 px. Y el aire de abajo va corto
   por lo mismo. Medido a 720 px de alto, que es lo justo. */
#vista-celestia{padding-top:calc(150px + 0.21 * var(--celestia-lado,460px) + var(--sp-6));
  padding-bottom:var(--sp-4);min-height:calc(100vh - 73px)}
#vista-celestia .cabecera-seccion h2{font-size:var(--fs-h1)}

/* Entran escalonadas, como los textos y las cuadrículas de cualquier otra
   sección: primero la cabecera, luego la barra y por último lo de abajo. */
#vista-celestia .cabecera-seccion,
#vista-celestia .buscador,
#vista-celestia .celestia-descargo,
#vista-celestia .celestia-salida{opacity:0;
  transition:opacity 700ms var(--ease-standard)}
body.celestia-hablando #vista-celestia .cabecera-seccion{opacity:1;transition-delay:180ms}
body.celestia-hablando #vista-celestia .buscador        {opacity:1;transition-delay:380ms}
body.celestia-hablando #vista-celestia .celestia-descargo,
body.celestia-hablando #vista-celestia .celestia-salida {opacity:1;transition-delay:560ms}

/* La marca de la barra, en el sitio de la lupa. No es un icono cualquiera: es
   el mismo brillo de cuatro puntas en que se convierte el círculo, con el
   mismo degradado. */
#celestia-barra .lupa{cursor:default}
#celestia-barra .lupa svg{overflow:visible}

/* El botón de enviar, y el de terminar, son el mismo cristal redondo que la
   flecha de volver del buscador (ver .volver, más arriba): no hay ningún
   botón nuevo en esta web. */
#celestia-barra .enviar{margin:-6px -8px -6px 0}
#celestia-barra .enviar:hover svg{transform:translateX(2px)}
#celestia-barra .enviar:active svg{transform:translateX(4px)}

/* ---------- Conversar ----------
   Al mandar el primer mensaje, la pantalla se despeja: se apagan el título,
   la entradilla, el icono de Celestia y la lluvia del fondo. Queda la barra
   sola. Y sólo entonces sube el mensaje al hueco que han dejado.

   No es un capricho: el mensaje va justo donde estaba el título, y verlos
   encendidos a los dos a la vez es texto encima de texto. */
body.celestia-conversando #vista-celestia .cabecera-seccion,
body.celestia-conversando .chispas{opacity:0;transition-delay:0ms}

/* Lo que sale de escribir. No es una ventana: no tiene marco, ni fondo, ni
   borde. Es texto sobre la página, igual que la ficha del buscador.

   Y no ocupa sitio: va colocada encima de la barra, flotando sobre el hueco
   que dejan el título y la entradilla al apagarse. Por eso la barra se queda
   exactamente donde estaba, se esté conversando o no, y conteste Celestia dos
   renglones o veinte.

   `flex-end` apoya el contenido contra la barra, así que al crecer crece
   HACIA ARRIBA, que es de lo que se trata. Y si una respuesta se pasa de
   larga, se desliza por dentro en vez de empujar nada. */
.celestia-zona{position:relative}
.conversacion{position:absolute;left:0;right:0;bottom:calc(100% + var(--sp-4));
  max-width:760px;margin:0 auto;
  display:flex;flex-direction:column;
  gap:var(--sp-4);height:var(--alto-conversacion,340px);overflow-y:auto;
  font-family:var(--font-serif);
  opacity:0;pointer-events:none;
  transition:opacity 600ms var(--ease-standard);

  /* Sin barra de desplazamiento a la vista: aquí se desliza y ya. Una barra
     que aparece en cuanto la conversación pasa de un alto empuja todo el
     texto un dedo a la izquierda, y ese salto se come justo el efecto de lo
     que está entrando. Se sigue pudiendo desplazar con la rueda y con el
     dedo, que es como se lee un chat. */
  scrollbar-width:none;-ms-overflow-style:none;

  /* Y el borde de arriba no corta: difumina. Lo que se sale por ahí al
     desplazarse se desvanece en los últimos 40 px en vez de quedar cortado a
     cuchillo, que era esa raya que se veía cruzando el primer mensaje. */
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 40px);
          mask-image:linear-gradient(to bottom,transparent 0,#000 40px)}
.conversacion::-webkit-scrollbar{display:none}
body.celestia-conversando .conversacion{opacity:1;pointer-events:auto}

/* Con poco escrito, lo hablado se apoya abajo, contra la barra; y al pasarse
   de largo, sube y se desliza.

   Esto es `margin-top:auto` en el primero y NO `justify-content:flex-end` en
   el contenedor, y la diferencia importa: con `flex-end`, en cuanto el
   contenido no cabe, lo que se sale por arriba deja de poder alcanzarse con
   la barra de desplazamiento y los primeros turnos quedan cortados y
   perdidos. Con el margen automático no pasa: cuando sobra sitio empuja hacia
   abajo, y cuando falta vale cero y se desplaza con normalidad. */
.conversacion > .turno:first-child{margin-top:auto}

.turno{display:flex;flex-direction:column;gap:var(--sp-4)}
.conversacion p{margin:0;line-height:var(--lh-body)}

/* Lo que yo escribo. Entra un palmo por debajo de su sitio y sube: es lo
   único que se mueve en este paso, y por eso se ve. */
.turno .digo-yo{align-self:flex-end;max-width:86%;
  padding:var(--sp-3) var(--sp-4);border-radius:var(--radius-lg);
  color:var(--text-onbrand);background:var(--brand-primary);
  opacity:0;transform:translateY(22px);
  transition:opacity 420ms var(--ease-standard),
             transform 420ms cubic-bezier(.2,.9,.3,1)}
.turno.subiendo .digo-yo{opacity:1;transform:none}

/* Y detrás, ya arriba mi mensaje, asoma ella. */
.turno .dice-celestia{display:flex;align-items:flex-start;gap:var(--sp-3);
  max-width:92%;opacity:0;transform:translateY(10px);
  transition:opacity 340ms var(--ease-standard),
             transform 340ms var(--ease-standard)}
.turno.responde .dice-celestia{opacity:1;transform:none}
.turno .respuesta{flex:1;padding:var(--sp-3) var(--sp-4);
  border-radius:var(--radius-lg);color:var(--text-body);
  background:color-mix(in srgb,var(--celestia-rosa) 12%,var(--white))}

/* Su marca: el mismo icono, con las mismas cuatro posiciones y la misma forma
   que los brillos del cielo (ver .marca-celestia path, más abajo). */
/* Algo más grande de lo que pide el texto: dentro de ella los brillos dan una
   vuelta, y en 36 px ese movimiento no se apreciaba. */
.marca-celestia{flex:none;display:block;width:44px;height:44px;margin-top:-2px}
.marca-celestia svg{width:100%;height:100%;display:block;overflow:visible}
/* Mientras Celestia habla, los cuatro brillos dan una vuelta: cada uno
   describe un círculo pequeño alrededor de su propio sitio y, de camino, se
   acerca y se aleja. Con los cuatro desfasados, en cualquier instante uno
   está subiendo, otro bajando y otro cruzando: se lee como movimiento, no
   como parpadeo.

   La vuelta EMPIEZA Y ACABA en el mismo punto -0% y 100% son idénticos- y eso
   no es casualidad: es lo que permite pararla sin salto. Cuando Celestia
   termina de hablar no se corta la animación donde esté, sino que se la deja
   llegar al final de la vuelta que lleva; y como el final es el sitio de
   partida, cada brillo aterriza exactamente donde tiene que estar y ahí se
   queda. Ver `pararLaMarca()` en celestia.js.

   `--giro` lo escribe celestia.js, uno por brillo, y no es el mismo para
   todos: cada uno vive dentro de un grupo con su propia escala, así que para
   que los cuatro recorran lo mismo en pantalla, al pequeño hay que darle un
   número mayor. El origen es el 0,0 de cada uno, que es justo su centro, así
   que además crecen sin desplazarse. */
.marca-celestia path{transform-origin:0 0}
.marca-celestia.latiendo path{animation:orbitar 2.2s ease-in-out infinite}
.marca-celestia.latiendo g:nth-child(2) path{animation-delay:-.55s}
.marca-celestia.latiendo g:nth-child(3) path{animation-delay:-1.1s}
.marca-celestia.latiendo g:nth-child(4) path{animation-delay:-1.65s}
@keyframes orbitar{
  0%  {transform:translate(0,0) scale(1);opacity:.8}
  25% {transform:translate(var(--giro,6px),calc(var(--giro,6px) * -1)) scale(1.18);opacity:1}
  50% {transform:translate(0,calc(var(--giro,6px) * -2)) scale(1);opacity:.9}
  75% {transform:translate(calc(var(--giro,6px) * -1),calc(var(--giro,6px) * -1)) scale(.84);opacity:1}
  100%{transform:translate(0,0) scale(1);opacity:.8}}

/* El mismo cursor que parpadea al escribirse el nombre de una cuadrícula. */
.conversacion .escribiendo::after{content:"";display:inline-block;
  width:1px;height:1em;margin-left:2px;vertical-align:-.15em;
  background:var(--brand-accent);animation:cursor .7s steps(1) infinite}

@media (prefers-reduced-motion:reduce){
  .turno .digo-yo,.turno .dice-celestia{opacity:1;transform:none;transition:none}
  .marca-celestia.latiendo path{animation:none}
}

.celestia-descargo{max-width:760px;margin:0 auto;border-top:0;padding-top:0;
  text-align:center}

/* El de terminar no es un botón sólido: es el mismo cristal de todo lo demás,
   con la píldora del resto de botones. Traslúcido, como la barra. */
.celestia-salida{text-align:center;margin-top:var(--sp-6)}
.celestia-salida .boton{border:1px solid rgba(255,255,255,.7);
  background:rgba(255,255,255,.42);color:var(--brand-primary);
  backdrop-filter:blur(16px) saturate(1.15);
  -webkit-backdrop-filter:blur(16px) saturate(1.15);
  box-shadow:var(--shadow-xs);
  transition:background var(--dur-base) var(--ease-standard),
             border-color var(--dur-base) var(--ease-standard),
             box-shadow var(--dur-base) var(--ease-standard),
             transform var(--dur-base) var(--ease-standard)}
.celestia-salida .boton:hover{background:rgba(255,255,255,.62);
  border-color:var(--border-strong);box-shadow:var(--shadow-md);
  transform:translateY(-2px)}
.celestia-salida .boton:active{transform:scale(.98)}

/* Un punto más pequeña que las otras tres: va en la segunda fila, más cerca
   del borde, y a ese tamaño cabe sin apretar contra el buscador ni contra
   las escalas. */
.orbe[data-id="celestia"] .cara{width:96px;height:96px}

/* En pantallas estrechas se recoge como los otros tres, y por lo mismo que
   ellos lleva `!important`: la posición se la escribe el JavaScript en el
   propio atributo `style`. */
@media (max-width:720px){
  .orbe[data-id="celestia"]{--x:-34% !important;--y:27% !important}
  .orbe[data-id="celestia"] .cara{width:72px;height:72px}
}

@media (prefers-reduced-motion:reduce){
  .cielo,.chispas,.chispa,.chispa path,.polvo{transition:none}
  .polvo i{animation:none}
}
