/* ============================================================================
   view-acceso-umbral.css — EL UMBRAL. La pantalla de acceso al correo.

   Sustituye a la lámina de `view-acceso.css` SÓLO en /acceso. La hoja vieja
   sigue viva y sin tocar porque `vistas/estado.html` (404/403/500) comparte
   con ella `.lamina`, `.marca`, `.legal` y `.estado__salidas`: rehacerla
   habría rediseñado seis páginas para rediseñar una.

   LA TESIS. El acceso no es un formulario dentro de una tarjeta dentro de una
   página: es un umbral. Se quita la caja, se quita el logotipo escrito, se
   quita todo lo que no sean dos campos y un botón, y lo que queda se centra
   sobre el isotipo de la casa a media luz. La marca no se rotula, se habita.

   DE DÓNDE SALE. Del proyecto de diseño «Rediseño login minimalista
   disruptivo» (claude.ai/design), lámina `Acceso Correo Factible.dc.html`.
   ESCRITORIO: cuadros 1b (retícula y edición Pantalla), 2a (edición Papel)
   y 2b/2c (credencial rechazada) → §§2–13 de esta hoja.
   TELÉFONO: cuadros 3a–3d, 402 × 874 → §14, que es una tabla de medidas
   propia y no un factor de escala; allí está el porqué.
   El comp presenta los cuadros del teléfono dentro de `ios-frame.jsx`. Ese
   archivo es ANDAMIAJE —lleva `@ds-adherence-ignore` y dibuja el bisel, la
   isla dinámica, la barra de estado y un teclado de iOS—, así que no se
   portó ni una línea: de él sólo se tomaron las medidas del hueco seguro
   (62 px arriba, 34 abajo), y aquí se piden con `env(safe-area-inset-*)`,
   que las da reales en vez de a ojo.
   El comp escribe los colores en hexadecimal; aquí
   están traducidos a los tokens del sistema, que es de donde salieron: casi
   todos coinciden al dígito (#4886FE es --marca-500, #F0F2F6 es --txt-1,
   #9398A3 es --txt-3, #E67978 es --riesgo, #ECEDF1 es --lienzo de papel).
   Las tres divergencias de color están marcadas «DIVERGENCIA DE COLOR» en su
   sitio; las cuatro correcciones de accesibilidad van aquí debajo.

   LO QUE NO SE HEREDÓ DEL COMP, Y POR QUÉ
   · El subrayado del campo. El comp lo dibuja en --regla-media: 1.57:1 contra
     el fondo en pantalla y 1.36:1 en papel. Ese subrayado es lo ÚNICO que
     dice dónde está el control —con el campo de contraseña vacío no hay ni
     texto ni marcador de posición—, así que le aplica el piso de 3:1 de
     WCAG 1.4.11. Sube a --medida-llena: 5.44:1 y 4.32:1. Es la única razón
     por la que esta pantalla no es idéntica al comp, y fue una decisión
     tomada, no un descuido.
   · El marcador de posición en #767C88. En el comp está escrito una sola vez,
     en la hoja global del lienzo oscuro, y las láminas de papel lo heredan
     sin querer: sobre #ECEDF1 mide 3.58:1. Aquí sale de --u-txt-suave, o sea
     --txt-2, y cambia con la edición. Sigue distinguiéndose del valor escrito
     porque lo que se teclea va en --txt-1, dos escalones más fuerte.
   · `outline: none` en los campos. El sistema tiene UN anillo de foco y esta
     hoja no es quién para apagarlo. El campo enfocado se dice con el
     subrayado en color de marca y 2 px; el resto de controles llevan el
     anillo de --foco como en todo el producto.
   · El contador «2 intentos restantes». Es dato real —vive en la tabla
     `intentos_acceso`— pero decir en voz alta cuánto le queda a quien está
     probando contraseñas es una decisión de seguridad, no de diseño, y este
     login está escrito a propósito para no ser un oráculo. La caja de aviso
     tiene el renglón preparado (`.umbral__detalle`) y se enciende sola si
     alguna vez el servidor manda `error_detalle`.
   ========================================================================= */

/* --- 1. LAS DOS CARAS DEL UMBRAL ----------------------------------------
   Mismo mecanismo de tres estados que `tokens.css` §10.b: sin atributo manda
   el equipo, y `[data-tema]` manda sobre el equipo en las dos direcciones.
   El bloque de papel se repite en la consulta de medios y en el atributo, y
   no se factoriza, por la misma razón que allá: quien tiene el equipo en
   oscuro tiene que poder pedir papel.                                      */

:root {
  /* DIVERGENCIA DE COLOR 1 de 3. El lienzo del umbral es más profundo que --lienzo
     (0.165): el acceso es la única pantalla del producto sin nada alrededor,
     y el halo necesita negro de verdad debajo para leerse como luz y no como
     un degradado gris. Dos centésimas de luminosidad, y sólo aquí.         */
  --u-lienzo: oklch(0.141 0.011 275);

  --u-txt-fuerte: var(--txt-1);
  /* DIVERGENCIA DE COLOR 3 de 3, y la única que se descubrió mirando la pantalla en
     vez de leyendo el comp. La microtipografía va en --txt-2, no en el
     --txt-3 que pide el comp, porque TODA ella cae encima del isotipo: el
     rótulo de contraseña cruza el travesaño de la A y la casilla cruza la
     pata derecha. Medido sobre el trazo del isotipo, que es el peor fondo
     que hay en esta pantalla:
         --txt-3   pantalla 3.19:1   papel 3.43:1   ← los dos por debajo
         --txt-2   pantalla 4.96:1   papel 4.97:1
     Un escalón de tinta cuesta menos que apagar el isotipo, y además apagarlo
     no habría bastado: en papel el halo por sí solo ya deja --txt-3 en
     4.25:1, así que ni con el isotipo al 0 % pasaba.
     No hace falta repetirla en los bloques de papel: --txt-2 ya cambia de
     edición por su cuenta en tokens.css.                                   */
  --u-txt-suave:  var(--txt-2);

  /* El subrayado del campo. Ver la nota de arriba: 5.44:1 sobre el lienzo. */
  --u-linea:      var(--medida-llena);
  --u-acento:     var(--marca-500);   /* #4886FE, el mismo de la regla viva */
  --u-sobre:      var(--txt-invertido);          /* 5.58:1 sobre el acento  */

  /* El halo y los dos aros. El comp los escribe en rgba; son la marca y el
     índigo del sistema a porcentaje, así que se dicen con color-mix y
     cambian solos de edición.                                             */
  --u-halo: radial-gradient(circle,
              color-mix(in oklab, var(--marca-500) 22%, transparent),
              color-mix(in oklab, var(--indigo-600) 10%, transparent) 45%,
              transparent 68%);
  --u-aro:        color-mix(in oklab, var(--marca-400) 14%, transparent);
  --u-aro-vivo:   color-mix(in oklab, var(--marca-300) 55%, transparent);
  --u-aro-falla:  color-mix(in oklab, var(--riesgo)    38%, transparent);

  /* El isotipo es un PNG blanco sobre transparente. En pantalla se deja tal
     cual a media luz; en papel hay que apagarlo y desaturarlo o se pierde
     contra la hoja.                                                        */
  --u-iso-opacidad: 0.16;
  --u-iso-filtro:   none;
}

@media (prefers-color-scheme: light) {
  :root:not([data-tema="pantalla"]) {
    --u-lienzo:     var(--lienzo);       /* #ECEDF1, el del sistema tal cual */
    --u-linea:      var(--medida-llena); /* #666F81 · 4.32:1 sobre la hoja   */
    /* DIVERGENCIA DE COLOR 2 de 3. El comp pide #1F5FD8 para el acento de papel, que
       no es ninguno de los escalones de la rampa. --marca-600 es el vecino
       (#266BE7) y es además lo que el sistema ya usa en papel para la regla
       de margen viva. Blanco sobre él mide 4.71:1.                          */
    --u-acento:     var(--marca-600);
    --u-sobre:      var(--sobre-marca);
    --u-halo: radial-gradient(circle,
                color-mix(in oklab, var(--marca-600) 13%, transparent),
                color-mix(in oklab, var(--indigo-600)  7%, transparent) 45%,
                transparent 68%);
    --u-aro:        color-mix(in oklab, var(--marca-600) 14%, transparent);
    --u-aro-vivo:   color-mix(in oklab, var(--marca-600) 42%, transparent);
    --u-aro-falla:  color-mix(in oklab, var(--riesgo)    30%, transparent);
    --u-iso-opacidad: 0.12;
    --u-iso-filtro:   brightness(0.16) saturate(0);
  }
}

:root[data-tema="papel"] {
  --u-lienzo:     var(--lienzo);
  --u-linea:      var(--medida-llena);
  --u-acento:     var(--marca-600);
  --u-sobre:      var(--sobre-marca);
  --u-halo: radial-gradient(circle,
              color-mix(in oklab, var(--marca-600) 13%, transparent),
              color-mix(in oklab, var(--indigo-600)  7%, transparent) 45%,
              transparent 68%);
  --u-aro:        color-mix(in oklab, var(--marca-600) 14%, transparent);
  --u-aro-vivo:   color-mix(in oklab, var(--marca-600) 42%, transparent);
  --u-aro-falla:  color-mix(in oklab, var(--riesgo)    30%, transparent);
  --u-iso-opacidad: 0.12;
  --u-iso-filtro:   brightness(0.16) saturate(0);
}

/* --- 2. EL RITMO DEL UMBRAL ---------------------------------------------
   §6.b de tokens.css prohíbe el número suelto en una vista, y con razón. El
   comp trae su propia proporción —34 entre bloques, 24 dentro del formulario,
   10 entre rótulo y campo— que no cae en la escala de 4 px del sistema. En
   vez de esparcir los literales por la hoja se declaran aquí: quien quiera
   apretar o soltar el umbral cambia estas cinco líneas y nada más.        */
.umbral {
  --u-aire-bloque:  34px;   /* entre el título y el formulario              */
  --u-aire-campo:   24px;   /* entre dos campos                             */
  --u-aire-rotulo:  10px;   /* entre el rótulo y su campo                   */
  --u-ancho:       389px;   /* la columna del formulario                    */
  --u-radio-boton: 999px;   /* el botón es la única forma redonda de aquí   */
}

/* --- 3. LAS DOS FAMILIAS -------------------------------------------------
   Space Grotesk para la prosa y JetBrains Mono para la microtipografía en
   versalitas. NO son las familias del producto: «Factible Prosa» es
   humanista y tranquila porque tiene que aguantar ocho horas de bandeja, y
   el umbral se mira cuatro segundos y quiere decir otra cosa. Es la única
   pantalla del sistema con tipografía propia, y es deliberado.

   Van SERVIDAS DESDE AQUÍ, como las del sistema y por la misma regla: dos
   woff2 variables, locales, sin red. Cargarlas del CDN de Google habría
   metido una dependencia de terceros que bloquea el primer pintado en la
   puerta de entrada del correo corporativo, y ninguna pantalla de acceso
   debería depender de que un tercero conteste. Son 53 KB entre las dos.
   Procedencia y licencias: app/static/fonts/PROCEDENCIA-UMBRAL.txt        */
@font-face {
  font-family: "Umbral Prosa";
  src: url("../assets/fonts/SpaceGrotesk.woff2") format("woff2");
  font-weight: 300 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Umbral Cifra";
  src: url("../assets/fonts/JetBrainsMono.woff2") format("woff2");
  font-weight: 400 800; font-style: normal; font-display: swap;
}

/* --- 4. EL ARMAZÓN -------------------------------------------------------
   Esta hoja la carga SÓLO `vistas/acceso.html`, así que puede vestir el
   <body> sin pisarle la página a nadie. El fondo se pinta aquí y no en
   `.umbral` porque si el contenido crece más que la ventana —teléfono
   acostado, cuerpo de letra grande— el hueco de abajo tiene que ser del
   mismo color y no el --lienzo del sistema.                               */
body { background: var(--u-lienzo); }

.umbral {
  position: relative;
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: var(--e-8) var(--e-4);
  /* Los aros miden más que la ventana a propósito: se salen y se recortan.
     Sin esto el de 700 px produce barra horizontal en cualquier portátil.

     `clip` en vez del `hidden` que había aquí. NO es un arreglo de un fallo:
     se midió el caso peor —iPhone SE con el teclado fuera, 375 × 336 útiles,
     con la caja de aviso puesta— y con `hidden` el botón Entrar TAMBIÉN se
     alcanzaba. La razón es que esta lámina tiene `min-height` y no `height`,
     así que crece con su contenido y nunca llega a desbordarse de sí misma:
     lo que desborda es la raíz, y la raíz se desplaza con normalidad.
     El cambio es de precisión, no de rescate. `hidden` en UN solo eje sí
     obligaría al otro a `auto` y convertiría la lámina en un panel con
     desplazamiento propio; `clip` no arrastra esa regla, así que deja el
     recorte horizontal escrito sin depender de que el `min-height` de arriba
     no se convierta nunca en un `height`.
     Y si algún navegador no entiende `clip` (Safari anterior al 16), no hay
     red que se caiga: los aros ya los recorta `.umbral__fondo`, que lleva su
     propio `overflow: hidden` y mide exactamente lo mismo que la lámina.   */
  overflow-x: clip;
  background: var(--u-lienzo);
  color: var(--u-txt-fuerte);
  font-family: "Umbral Prosa", ui-sans-serif, system-ui, sans-serif;
}

/* --- 5. EL FONDO: halo, isotipo y dos aros ------------------------------
   Cuatro capas centradas, todas decorativas y todas fuera del árbol de
   accesibilidad (el <div> lleva aria-hidden). Ninguna recibe el ratón.

   Las medidas del comp están sobre un lienzo fijo de 1160×740. Aquí cada
   una lleva su `min()` contra vmin para que en un teléfono encojan en vez
   de recortarse: el halo tiene que seguir siendo un halo a 360 px.        */
.umbral__fondo {
  position: absolute;
  inset: 0;
  display: grid;
  /* LA PISTA SE CLAVA AL CONTENEDOR. Estas dos líneas no son adorno: sin
     ellas el fondo se descentra en cuanto la ventana es más estrecha que la
     capa más ancha, y en un teléfono siempre lo es.

     Las cuatro capas comparten `grid-area: 1 / 1`, así que la cuadrícula
     tiene UNA pista implícita, y una pista implícita se dimensiona al
     max-content de lo que lleva dentro: 520 px en el teléfono, 820 en
     escritorio. Mientras la ventana es más ANCHA que eso, `justify-content`
     estira la pista hasta los filos y todo cae en su sitio —por eso en
     escritorio nunca se vio—. Pero en cuanto la ventana es más ESTRECHA, la
     pista ya no puede encoger por debajo de su max-content: arranca pegada
     al filo izquierdo, se sale por la derecha, y `place-items: center`
     centra cada capa respecto de LA PISTA, no de la pantalla. El triángulo
     se iba a la derecha, y cuanto más estrecho el teléfono, más lejos.
     Medido, con el centro del isotipo clavado en 260 px (la mitad de los
     520 del halo) mientras la columna del formulario sí se centraba bien:
         ancho 430 → +45 px      ancho 402 → +59 px
         ancho 375 → +72 px      ancho 360 → +80 px

     Con la pista clavada al contenedor las capas vuelven a centrarse en la
     pantalla y desbordan por los dos lados por igual, que es lo que se
     quería desde el principio. El `minmax(0, …)` es lo que impide que el
     contenido vuelva a inflar la pista; un `1fr` a secas tiene mínimo
     automático y volvería a crecer hasta el max-content.

     OJO con lo que esto NO arregla, porque parece lo mismo y no lo es: si el
     contenido no cabe (ventana corta, teclado fuera) la lámina crece, el
     fondo crece con ella y su centro deja de coincidir con el de la mirilla.
     Eso es correcto y se queda: el fondo pertenece a la página y acompaña al
     formulario al desplazarse. Clavarlo a la mirilla pediría `position:
     fixed` y entonces el halo resbalaría contra el formulario, que es peor. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows:    minmax(0, 1fr);
  place-items: center;
  pointer-events: none;
  overflow: hidden;
}
.umbral__fondo > * { grid-area: 1 / 1; }

.umbral__halo {
  inline-size: min(820px, 115vmin);
  block-size:  min(820px, 115vmin);
  border-radius: 50%;
  background: var(--u-halo);
  animation: u-respirar 8s ease-in-out infinite;
}

/* El isotipo NO respira. En el comp está fuera del halo justamente para eso:
   un logotipo que late se lee como un elemento de interfaz cargando, y este
   sólo tiene que estar ahí.                                               */
.umbral__iso {
  inline-size: min(420px, 59vmin);
  block-size:  min(420px, 59vmin);
  object-fit: contain;
  opacity: var(--u-iso-opacidad);
  filter: var(--u-iso-filtro);
}

.umbral__aro {
  border-radius: 50%;
  border: 1px solid var(--u-aro);
}
.umbral__aro--interior {
  inline-size: min(540px, 76vmin);
  block-size:  min(540px, 76vmin);
  /* El único filo vivo de la pantalla: dice hacia dónde gira. */
  border-top-color: var(--u-aro-vivo);
  animation: u-girar 22s linear infinite;
}
.umbral__aro--exterior {
  inline-size: min(700px, 98vmin);
  block-size:  min(700px, 98vmin);
  border-style: dashed;
  animation: u-girar 46s linear infinite reverse;
}
/* Credencial rechazada: el filo vivo del aro interior se vuelve riesgo. Es
   la única señal de error que se sale de la columna, y es muda —el mensaje
   lo da la caja de aviso; esto sólo tiñe el ambiente.                     */
.umbral--rechazo .umbral__aro--interior { border-top-color: var(--u-aro-falla); }

/* --- 6. LA COLUMNA ------------------------------------------------------ */
.umbral__columna {
  position: relative;   /* por encima del fondo, sin z-index: basta el orden */
  inline-size: min(var(--u-ancho), 100%);
  display: flex;
  flex-direction: column;
  gap: var(--u-aire-bloque);
}
/* La sacudida del comp. Se aplica a la columna entera y una sola vez: es el
   acuse físico de «esto no entró», y en cuanto termina la pantalla queda
   quieta para poder volver a escribir.                                    */
.umbral--rechazo .umbral__columna {
  animation: u-sacudir 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

.umbral__encabezado {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-3);
  text-align: center;
}
.umbral__titulo {
  margin: 0;
  font: 500 30px/1.15 "Umbral Prosa", ui-sans-serif, system-ui, sans-serif;
  letter-spacing: -0.02em;
  color: var(--u-txt-fuerte);
  text-wrap: balance;
}
/* El renglón que sólo aparece cuando se llegó aquí desde dentro: había
   cookie y ya no hay sesión. El catálogo de estados pide decir qué pasó y
   qué se conservó, en vez de enseñar un formulario sin explicación.       */
.umbral__nota {
  margin: 0;
  max-inline-size: 34ch;
  font: 400 13px/1.5 "Umbral Prosa", ui-sans-serif, system-ui, sans-serif;
  color: var(--u-txt-suave);
}

/* --- 7. EL FORMULARIO --------------------------------------------------- */
.umbral__forma {
  display: flex;
  flex-direction: column;
  gap: var(--u-aire-campo);
  animation: u-surgir 0.34s cubic-bezier(0.18, 0.7, 0.4, 1) both;
}

.umbral__campo {
  display: flex;
  flex-direction: column;
  gap: var(--u-aire-rotulo);
}

/* La microtipografía en versalitas: es lo que le da el aire de instrumento.
   El entrelestrado de 0.16em es del comp y es mucho más ancho que el
   --espaciado-versalita del sistema (0.08em), a propósito: aquí hay tres
   rótulos en toda la pantalla, no una tabla de columnas.                  */
.umbral__rotulo {
  font: 500 10.5px "Umbral Cifra", ui-monospace, "SF Mono", monospace;
  letter-spacing: 0.16em;
  text-align: center;
  color: var(--u-txt-suave);
  text-transform: uppercase;
}
.umbral--rechazo .umbral__rotulo { color: var(--riesgo); }

.umbral__control {
  inline-size: 100%;
  box-sizing: border-box;
  padding: 10px 2px 12px;
  background: transparent;
  border: none;
  border-block-end: 1px solid var(--u-linea);
  color: var(--u-txt-fuerte);
  font: 400 18px "Umbral Prosa", ui-sans-serif, system-ui, sans-serif;
  text-align: center;
  transition: border-color var(--dur-2) var(--curva-estandar),
              border-width var(--dur-1) var(--curva-estandar);
}
.umbral__control::placeholder {
  color: var(--u-txt-suave);
  opacity: 1;   /* Firefox se lo baja al 54 % por su cuenta */
}
/* La contraseña se escribe con puntos: un poco de aire entre ellos hace que
   se cuenten de un vistazo. */
.umbral__control[type="password"] { letter-spacing: 0.06em; }

/* EL FOCO DEL CAMPO. El comp apaga el contorno; aquí no se apaga, se
   sustituye por algo que dice más: el subrayado se pone en color de marca y
   dobla su grosor. Se compensa el píxel que crece con el relleno de abajo
   para que la línea base del texto no salte al enfocar.                   */
.umbral__control:focus-visible {
  outline: none;
  border-block-end-width: 2px;
  border-block-end-color: var(--u-acento);
  padding-block-end: 11px;
}
.umbral--rechazo .umbral__control { border-block-end-color: var(--riesgo); }

/* EL AUTORRELLENO. Sin esto Chrome pinta el campo de amarillo y se lleva por
   delante toda la pantalla: un fondo sólido donde el diseño dice que no hay
   caja. No se puede quitar el fondo, así que se tapa con una sombra interior
   del color del lienzo y se fuerza el color del texto. La transición
   larguísima es el truco de siempre para que el amarillo no llegue a
   pintarse en el primer fotograma.                                        */
.umbral__control:-webkit-autofill,
.umbral__control:-webkit-autofill:hover,
.umbral__control:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--u-txt-fuerte);
  -webkit-box-shadow: 0 0 0 100px var(--u-lienzo) inset;
  caret-color: var(--u-txt-fuerte);
  transition: background-color 100000s ease-in-out 0s;
}

/* --- 8. VER / OCULTAR --------------------------------------------------- */
.umbral__envoltura {
  position: relative;
  display: flex;
  align-items: center;
}
/* El campo de contraseña se estrecha por los DOS lados el mismo tanto: el
   texto va centrado y con relleno sólo a la derecha quedaría descentrado
   respecto del campo de correo, que es el error más visible de un
   formulario centrado. */
.umbral__envoltura .umbral__control { padding-inline: 62px; }

.umbral__ver {
  position: absolute;
  inset-inline-end: 0;
  inset-block-end: 10px;
  padding: 4px 2px;
  background: transparent;
  border: none;
  color: var(--u-txt-suave);
  font: 500 10.5px "Umbral Cifra", ui-monospace, monospace;
  letter-spacing: 0.08em;
  cursor: pointer;
  border-radius: var(--radio-1);
  transition: color var(--dur-1) var(--curva-estandar);
}
.umbral__ver:hover { color: var(--u-acento); }
.umbral__ver:focus-visible {
  outline: var(--foco-anillo) solid var(--foco);
  outline-offset: var(--foco-separacion);
  color: var(--u-acento);
}

/* --- 9. RECORDAR -------------------------------------------------------- */
.umbral__recordar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  font: 400 13px "Umbral Prosa", ui-sans-serif, system-ui, sans-serif;
  color: var(--u-txt-suave);
  cursor: pointer;
}
.umbral__casilla {
  inline-size: 15px;
  block-size: 15px;
  accent-color: var(--u-acento);
  cursor: pointer;
  margin: 0;
}
.umbral__casilla:focus-visible {
  outline: var(--foco-anillo) solid var(--foco);
  outline-offset: var(--foco-separacion);
}

/* --- 10. ENTRAR ---------------------------------------------------------
   La única forma redonda del umbral, y por eso no hace falta que diga nada
   más para leerse como la acción principal.                               */
.umbral__entrar {
  padding: 15px;
  background: var(--u-acento);
  border: none;
  border-radius: var(--u-radio-boton);
  color: var(--u-sobre);
  font: 600 14.5px "Umbral Prosa", ui-sans-serif, system-ui, sans-serif;
  cursor: pointer;
  transition: transform var(--dur-2) var(--curva-salida),
              box-shadow var(--dur-2) var(--curva-estandar),
              filter var(--dur-2) var(--curva-estandar);
}
.umbral__entrar:hover {
  transform: translateY(-1px);
  filter: brightness(1.12);
  box-shadow: 0 10px 30px color-mix(in oklab, var(--u-acento) 30%, transparent);
}
.umbral__entrar:active { transform: none; filter: brightness(0.96); }
.umbral__entrar:focus-visible {
  outline: var(--foco-anillo) solid var(--foco);
  outline-offset: var(--foco-separacion);
}

/* --- 11. LA LETRA CHICA ------------------------------------------------- */
.umbral__legal {
  margin: -5px 0 0;
  text-align: center;
  font: 400 10px/1.6 "Umbral Prosa", ui-sans-serif, system-ui, sans-serif;
  color: var(--u-txt-suave);
  text-wrap: pretty;
}

/* --- 12. CREDENCIAL RECHAZADA ------------------------------------------
   La caja de aviso del comp: un punto que late, el motivo, y un renglón de
   detalle que hoy nadie manda. El fondo se mezcla contra el lienzo del
   umbral —no contra --superficie-1, que aquí no existe— para que el aviso se
   hunda en la pantalla en vez de pegarse encima, que es la regla del
   sistema para los fondos semánticos.                                     */
.umbral__aviso {
  display: flex;
  align-items: flex-start;
  gap: var(--e-2);
  padding: 12px 14px;
  background: color-mix(in oklab, var(--riesgo) 16%, var(--u-lienzo));
  border: 1px solid var(--riesgo-regla);
  border-radius: var(--radio-3);
  animation: u-surgir 0.3s cubic-bezier(0.18, 0.7, 0.4, 1) both;
}
.umbral__pulso {
  flex: none;
  inline-size: 7px;
  block-size: 7px;
  margin-block-start: 6px;
  border-radius: 50%;
  background: var(--riesgo);
  animation: u-latir 2s ease-out infinite;
}
.umbral__aviso-texto {
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: start;
}
.umbral__motivo {
  font: 500 12.5px/1.35 "Umbral Prosa", ui-sans-serif, system-ui, sans-serif;
  color: var(--riesgo);
}
.umbral__detalle {
  font: 400 10.5px/1.4 "Umbral Cifra", ui-monospace, monospace;
  letter-spacing: 0.04em;
  color: var(--u-txt-suave);
}

/* --- 13. MOVIMIENTO ----------------------------------------------------- */
@keyframes u-respirar {
  0%, 100% { transform: scale(1);    opacity: 0.55; }
  50%      { transform: scale(1.12); opacity: 0.95; }
}
@keyframes u-girar { to { transform: rotate(360deg); } }
@keyframes u-surgir {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes u-sacudir {
  10%, 90%      { transform: translateX(-2px); }
  20%, 80%      { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-7px); }
  40%, 60%      { transform: translateX(7px); }
}
@keyframes u-latir {
  0%, 100% { box-shadow: 0 0 0 0   color-mix(in oklab, var(--riesgo) 35%, transparent); }
  50%      { box-shadow: 0 0 0 10px color-mix(in oklab, var(--riesgo)  0%, transparent); }
}

/* §11 de tokens.css ya pone toda animación a 1 ms cuando se pide movimiento
   reducido, y con eso las tres perpetuas de aquí se apagarían dando un
   tirón: una animación infinita recortada a un ciclo de 1 ms salta a su
   último fotograma. Se apagan explícitamente, que es lo que se quería
   decir. El halo se queda en su punto medio de opacidad para que la
   pantalla no cambie de peso, y los aros quedan quietos donde nacieron.   */
@media (prefers-reduced-motion: reduce) {
  .umbral__halo  { animation: none; opacity: 0.75; }
  .umbral__aro   { animation: none; }
  .umbral__pulso { animation: none; }
  .umbral__columna,
  .umbral--rechazo .umbral__columna,
  .umbral__forma,
  .umbral__aviso { animation: none; }
  .umbral__entrar:hover { transform: none; }
}

/* --- 14. EL TELÉFONO ----------------------------------------------------
   Cuadros 3a–3d del comp: 402 × 874, «la misma jerarquía que 2a» con todo
   recogido. NO es el diseño de escritorio encogido. Encogerlo dejaría los
   trazos del isotipo cayendo encima de cada renglón y objetivos táctiles de
   15 px; esto es la proporción que el comp calculó para la mano.

   EL CORTE EN 480 px y no en 402. Cubre de 360 (Android chico) a 430
   (iPhone Pro Max) sin dejar a nadie en el diseño de escritorio, y todo lo
   de dentro es fluido, así que la banda entera se sirve con una sola tabla.

   QUÉ CAMBIA DE VERDAD, que no es sólo escala:
   · El fondo se recoge MÁS que el texto: el halo 820→520, los aros 540→330
     y 700→430, el isotipo 420→300. En escritorio el isotipo es un fondo
     detrás de una columna de 389 px; en el teléfono el formulario ocupa
     casi todo el ancho, y si el isotipo bajara en la misma proporción sus
     trazos caerían sobre cada renglón en vez de detrás del conjunto.
   · Los objetivos CRECEN aunque la letra baje: el botón a 52 px, y la fila
     de la casilla y el botón VER a 44, que es --toque-min de tokens.css.
     Es lo contrario de encoger, y es el motivo de que esto sea una tabla
     propia y no un factor de escala.
   · El campo baja a 16 px y ni una décima menos. Por debajo de 16 px iOS
     hace zoom al enfocar y descuadra la pantalla entera: por eso el comp
     escribe 16 y no 15, y por eso este número no se toca.                 */

/* El dedo en pantallas ANCHAS (tableta, portátil táctil). El teléfono trae
   sus propios objetivos más abajo y gana por orden de aparición.          */
@media (pointer: coarse) {
  .umbral__ver     { padding: 12px 10px; inset-block-end: 2px; }
  .umbral__casilla { inline-size: 18px; block-size: 18px; }
}

/* La ventana baja de un portátil de 13" con la barra de marcadores, o un
   teléfono acostado. Acotada a partir de 481 px para no pelearse con la
   tabla del teléfono, que trae su propia versión corta al final.          */
@media (max-height: 700px) and (min-width: 481px) {
  .umbral {
    --u-aire-bloque: 24px;
    --u-aire-campo: 18px;
    padding-block: var(--e-6);
  }
  .umbral__titulo { font-size: 25px; }
}

@media (max-width: 480px) {
  .umbral {
    --u-aire-bloque: 30px;
    --u-aire-campo:  22px;
    --u-aire-rotulo:  9px;
    --u-ancho: 100%;
    /* El comp mete el aire lateral en la columna; aquí va en la lámina, que
       ya tenía relleno propio, y así el fondo sigue llegando a los filos. */
    padding-inline: 30px;
    /* El notch y la barra de inicio. El comp los da por buenos porque dibuja
       dentro del marco de iOS —`ios-frame.jsx` reserva 62 px arriba y 34
       abajo—, pero en Safari de verdad hay que pedirlos, y `env()` los da
       reales en vez de a ojo. El `max()` conserva el aire de siempre en los
       teléfonos que no tienen notch.                                      */
    padding-block-start: max(var(--e-8), env(safe-area-inset-top));
    padding-block-end:   max(var(--e-8), env(safe-area-inset-bottom));
  }

  .umbral__halo          { inline-size: 520px; block-size: 520px; }
  .umbral__aro--exterior { inline-size: 430px; block-size: 430px; }
  .umbral__aro--interior { inline-size: 330px; block-size: 330px; }
  .umbral__iso           { inline-size: 300px; block-size: 300px; }

  .umbral__titulo {
    font-size: 27px;
    /* `pretty` y no `balance`, y lo dice el comp. A este ancho el título
       ocupa dos o tres renglones: lo que hay que evitar es la palabra sola
       al final, no que los renglones midan lo mismo.                      */
    text-wrap: pretty;
  }

  .umbral__rotulo  { font-size: 10px; }
  .umbral__control { font-size: 16px; padding: 12px 2px; }
  .umbral__control:focus-visible { padding-block-end: 11px; }
  .umbral__envoltura .umbral__control { padding-inline: 52px; }

  .umbral__ver {
    min-block-size: var(--toque-min);
    padding: 0 2px;
    inset-block-end: 8px;
    font-size: 10px;
  }

  .umbral__recordar {
    min-block-size: var(--toque-min);
    gap: 9px;
    font-size: 12.5px;
  }
  .umbral__casilla { inline-size: 17px; block-size: 17px; }

  .umbral__entrar { min-block-size: 52px; font-size: 15px; }

  .umbral__legal { margin-block-start: 4px; }

  .umbral__aviso   { gap: 9px; padding: 11px 13px; }
  .umbral__pulso   { margin-block-start: 5px; }
  .umbral__detalle { font-size: 10px; letter-spacing: 0.03em; }
}

/* Teléfono CORTO: iPhone SE y compañía (375 × 667), o cualquiera acostado.
   Se recorta el aire y el título; los objetivos táctiles no se tocan, que
   es justo lo que no se puede recortar en una mano.                       */
@media (max-width: 480px) and (max-height: 700px) {
  .umbral { --u-aire-bloque: 22px; --u-aire-campo: 18px; }
  .umbral__titulo { font-size: 24px; }
}

/* Nadie ha pedido esta pantalla impresa, pero si alguien la imprime que no
   salgan cuatro capas de decoración en tinta. */
@media print {
  .umbral__fondo { display: none; }
}
