/* ==========================================================================
   Pantallas de la aplicación
   --------------------------------------------------------------------------
   Se carga SOLO en las pantallas de la aplicación, no en la portada. Reutiliza
   las variables de app.css, así que el modo oscuro y la paleta salen gratis y
   no hay un segundo juego de colores que mantener.
   ========================================================================== */

/* `hidden` tiene que ganar SIEMPRE.
   El atributo se apoya en `display:none` de la hoja del navegador, que pierde
   contra cualquier regla nuestra con clase: `.form{display:grid}` bastaba para
   que un panel oculto se siguiera pintando. Toda la aplicación esconde y enseña
   bloques con `hidden`, así que esto no es un parche puntual sino la regla que
   sostiene el mecanismo. */
[hidden]{display:none !important}

/* El aire de arriba y de abajo era de portada, no de pantalla de trabajo: 64px
   de cabecera y 110px de pie para llegar a un formulario de cuatro campos. Una
   pantalla a la que se viene a hacer algo empieza antes. */
.pantalla{
  position:relative;                      /* ancla de la capa .dcl */
  padding:clamp(24px,4vw,44px) 0 clamp(48px,7vw,80px);
  /* `dvh` y no `vh`: `vh` es el alto con la interfaz del navegador retraída,
     que en un móvil casi nunca es el alto que hay delante. Los dos declarados,
     en este orden, para que quien no entienda el segundo se quede con el
     primero. Ver el bloque 6 de `cascara.css`. */
  min-height:60vh;
  min-height:60dvh;
}
/* El contenido, por encima de la decoración. `.dcl` ya trae z-index:0. */
.pantalla > .wrap{position:relative;z-index:1}

/* Colocación de los blobs en las pantallas de la aplicación.
   Mismo criterio que en la portada: los de opacidad media o alta se quedan
   fuera de la columna de texto. Aquí van todos en la suave y sangrando por los
   bordes, porque la columna está centrada y el ancho útil es poco. */
.pantalla .b1{top:-6%;right:-16%;width:min(42%,440px);transform:rotate(22deg)}
.pantalla .b2{bottom:-10%;left:-18%;width:min(36%,380px);transform:rotate(-64deg)}
/* La retícula de puntos es lo más visible de la capa: solo cuando hay margen
   real a los lados de la columna, nunca por debajo del texto. */
.pantalla .d1{display:none}
@media (min-width:1180px){
  .pantalla .d1{display:block;left:1%;top:14%;width:170px;height:140px}
}

.col-estrecha{max-width:44rem;margin-inline:auto}
.col-ancha{max-width:60rem;margin-inline:auto}

.pantalla h1{
  font-size:var(--fs-h2);line-height:var(--lh-head);
  letter-spacing:var(--track-tight);margin-bottom:var(--sp-4);
}

/* --- Cabecera de pantalla -------------------------------------------------
   La portada abre con pastilla, titular grande con una palabra subrayada a
   mano y entradilla. Las pantallas de la aplicación abrían con un h1 un
   escalón por debajo y nada más: mismo producto, dos caras distintas. Esto es
   la cara de la portada, con las piezas que ya existen en app.css. */

.cabecera-pantalla{margin-bottom:clamp(20px,3vw,32px)}
.cabecera-pantalla .eyebrow{margin-bottom:var(--sp-4)}
.pantalla .cabecera-pantalla h1{
  font-size:clamp(1.95rem,5.2vw,3.15rem);
  line-height:var(--lh-tight);letter-spacing:-.04em;
  margin-bottom:var(--sp-4);
}
.pantalla .cabecera-pantalla .lead{max-width:46ch;margin-bottom:0}
.cabecera-pantalla .titulo-fila{margin-bottom:0}
/* Dentro de una fila de título el h1 comparte línea con la pastilla de estado o
   con un botón, y su margen inferior los descuadra. Hace falta repetir el
   `.cabecera-pantalla` para no perder contra la regla de arriba. */
.pantalla .cabecera-pantalla .titulo-fila h1{margin-bottom:0}
.pantalla h2{
  font-size:var(--fs-h3);line-height:var(--lh-head);
  letter-spacing:-.02em;margin-bottom:var(--sp-3);
}
.pantalla .lead{
  font-size:var(--fs-lead);line-height:1.66;color:var(--ink-soft);
  margin-bottom:var(--sp-6);
}
.pantalla p{line-height:var(--lh-body)}
/* `:not(.btn)` no es un adorno: `.pantalla a` (0,1,1) gana por especificidad a
   `.btn-1` (0,1,0), asi que sin esto cualquier boton que sea un enlace -«Nuevo
   acuerdo», «Crear el primero»- pierde su color de texto y sale en azul oscuro
   sobre el verde del boton, ilegible. */
.pantalla a:not(.btn){color:var(--teal-strong);text-underline-offset:3px}

.titulo-fila{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:var(--sp-3);margin-bottom:var(--sp-5);
}
.titulo-fila h1{margin-bottom:0}

.migas{font-size:var(--fs-small);margin-bottom:var(--sp-4)}
.migas a{font-weight:var(--fw-bold);text-decoration:none}
.migas a:hover{text-decoration:underline}

/* --- Avisos --------------------------------------------------------------
   Un solo sitio para todo lo que la aplicación tiene que decir. Vive en una
   región aria-live: aquí hay pasos que tardan —generar claves, cifrar— y sin
   esto quien usa un lector de pantalla no sabría si el botón ha hecho algo. */

.aviso{
  border-radius:var(--r-2);padding:var(--sp-3) var(--sp-4);
  margin-bottom:var(--sp-5);font-size:var(--fs-small);line-height:1.5;
  border:1px solid var(--line);background:var(--surface-2);color:var(--ink);
}
.aviso-error{
  border-color:var(--notice-line);background:var(--notice-bg);color:var(--coral-strong);
  font-weight:var(--fw-bold);
}
.aviso-exito{border-color:var(--ui-teal);background:var(--tint-teal);color:var(--teal-strong)}

/* --- Tarjetas ------------------------------------------------------------
   `--r-4` y no `--r-3`: es el radio de `.card` en la portada. Eran dos radios
   distintos para la misma idea de tarjeta y se notaba al pasar de una a otra. */

.tarjeta{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-4);padding:clamp(18px,2.8vw,26px);
  box-shadow:var(--sh-s);margin-bottom:var(--sp-5);
}
.tarjeta > :last-child{margin-bottom:0}

/* El aviso, dentro de una tarjeta, sin ser otra tarjeta.
   `.notice` de la portada trae fondo, borde entero, radio y sombra: puesto
   dentro de una tarjeta son dos superficies anidadas para decir una frase. Aquí
   se queda sólo con lo que hace el trabajo, que es la barra coral del margen. */
.notice-plano{
  margin-block:var(--sp-4);padding:0 0 0 var(--sp-4);
  background:none;border:0;border-left:3px solid var(--ui-coral);
  border-radius:0;box-shadow:none;max-width:none;
}

/* --- Tarjeta con badge ----------------------------------------------------
   La tarjeta de la portada lleva un badge circular de color que ordena la
   lectura de un vistazo. Aquí encabeza cada bloque —un campo del acuerdo, el
   bloque de compartir, el de retirar— con el mismo vocabulario: `.badge` y sus
   variantes `.t/.p/.c` salen tal cual de app.css.

   La portada levanta la tarjeta al pasar por encima; aquí no, porque dentro
   hay un textarea al que estás apuntando y moverlo es hostil. El realce se da
   con `:focus-within`, que es cuando aporta algo. */

.tarjeta-campo{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-4);padding:clamp(16px,2.4vw,24px);
  box-shadow:var(--sh-s);margin-bottom:var(--sp-4);
  transition:box-shadow .2s ease,border-color .2s ease;
}
.tarjeta-campo:focus-within{box-shadow:var(--sh-m);border-color:var(--line-strong)}
.tarjeta-campo > :last-child{margin-bottom:0}

/* UNA TARJETA ES UNA SECCIÓN; DENTRO VAN FILAS, NO TARJETAS.
   -------------------------------------------------------------------------
   Regla de la casa para los paneles de ajustes, y no es cuestión de gusto: una
   superficie blanca con sombra y radio dentro de otra superficie blanca con
   sombra y radio no jerarquiza nada —los dos niveles pesan lo mismo— y sólo
   añade dos bordes que el ojo tiene que descartar. Lo que va dentro de una
   tarjeta se separa con una línea fina y nada más: ver `.lista-filas`.

   El ritmo vertical de una tarjeta que NO es formulario lo pone esta regla. El
   `.form` lo resuelve con el hueco de su rejilla; una sección suelta apila
   párrafos, listas y botones sin un solo margen, y eso es lo que dejaba los
   bloques de Google y de las llaves pegados al borde y unos encima de otros. */
.tarjeta-campo:not(.form) > * + *{margin-top:var(--sp-3)}
/* El título ya no se separa a mano: lo separa el hueco de la rejilla o la regla
   de arriba. Sumar los dos era lo que dejaba 36px entre un título y su campo. */
.tarjeta-campo > .campo-cabecera{margin-bottom:0}
/* `.acciones` trae su propio margen inferior para cuando va suelta en la
   pantalla; dentro de una tarjeta ese margen se suma al ritmo y sobra. */
.tarjeta-campo > .acciones{margin-bottom:0}

/* Variante de aviso: el bloque de límites y el de retirar. Coral es el color
   con el que esta marca dice «esto importa», no «esto ha fallado». */
.tarjeta-campo-alerta{border-color:var(--notice-line);background:var(--notice-bg)}
.tarjeta-campo-alerta .campo textarea,
.tarjeta-campo-alerta .campo input[type=text]{background:var(--surface)}

.campo-cabecera{
  display:flex;align-items:center;flex-wrap:wrap;
  gap:var(--sp-3);margin-bottom:var(--sp-3);
}
/* El badge de la portada mide 62px y encabeza una tarjeta suelta; aquí va en
   línea con el título, así que baja a 40px. */
.campo-cabecera .badge{width:40px;height:40px;margin-bottom:0;flex:none}
/* `flex:1 1 0` y no `1 1 auto`: con base automática el título mide lo que mide
   su texto sin partir, y en un móvil un título largo —«Dónde tienes la sesión
   abierta»— no cabía junto al icono y se caía entero a la línea de abajo,
   dejando el círculo solo. Con base cero se queda al lado y parte el texto. */
.pantalla .campo-cabecera h2,
.pantalla .campo-cabecera h3{
  font-size:var(--fs-h3);line-height:var(--lh-head);letter-spacing:-.025em;
  margin-bottom:0;flex:1 1 0;min-width:0;
}
/* El título es la etiqueta del campo: al pulsarlo se enfoca el textarea, y no
   hace falta una segunda etiqueta escondida diciendo lo mismo. */
.campo-cabecera label{cursor:pointer}
/* Fondo `--surface` y no `--tint-coral`: la pastilla vive dentro de una tarjeta
   que YA es coral, y coral sobre coral dejaba el texto en 3,4:1. Sobre blanco
   `--coral-strong` da 5,6:1. Es la misma receta que `.eyebrow` en la portada. */
.campo-cabecera .etiqueta-clave{
  flex:none;font-size:var(--fs-micro);font-weight:var(--fw-black);
  letter-spacing:var(--track-wide);text-transform:uppercase;
  color:var(--coral-strong);background:var(--surface);
  border:1px solid var(--notice-line);border-radius:var(--r-pill);
  padding:.34em .8em;
}
/* Con `.pantalla` delante por lo mismo que el rótulo del paso: `.pantalla p`
   es (0,1,1) y le ganaba el interlineado a una clase suelta. */
.pantalla .campo-intro{
  font-size:var(--fs-small);color:var(--ink-soft);
  line-height:1.55;margin-bottom:var(--sp-4);
}

/* --- Asistente por pasos --------------------------------------------------
   Es la pantalla que enseña el móvil de la portada: barra de progreso, «Paso
   N de 3» y un bloque cada vez. */

/* La flecha del botón principal se desplaza al pasar por encima; la del de
   volver, al revés. Es el gesto de la portada, sin inventar nada. */
.btn-2:hover .arw-izq{transform:translateX(-3px)}
.arw-izq{transition:transform .18s ease}

/* `.pantalla` delante no sobra: `.pantalla h2` es (0,1,1) y le ganaría a
   `.paso-titulo` (0,1,0) el tamaño y el interletrado, dejando el rótulo del
   paso como un h2 normal en vez del microtítulo que tiene que ser. */
.pantalla .paso-titulo{
  font-size:var(--fs-small);font-weight:var(--fw-black);
  letter-spacing:var(--track-wide);text-transform:uppercase;
  color:var(--teal-strong);margin-bottom:var(--sp-2);
}
.paso-titulo:focus-visible{outline:3px solid var(--focus);outline-offset:4px;border-radius:var(--r-1)}

.progreso{
  height:10px;border-radius:var(--r-pill);overflow:hidden;
  background:var(--surface-2);border:1px solid var(--line);
  margin-bottom:var(--sp-3);
}
/* Mismo degradado que la barra del móvil de la portada. El ancho va por
   `data-paso` y no por `style`: la CSP es `style-src 'self'` y en todo el
   sitio no hay un solo atributo de estilo en línea. */
.progreso > span{
  display:block;height:100%;width:0;border-radius:var(--r-pill);
  background:linear-gradient(90deg,var(--ui-teal),var(--ui-purple));
  transition:width .34s cubic-bezier(.2,.8,.3,1);
}
.progreso[data-paso="1"] > span{width:33.34%}
.progreso[data-paso="2"] > span{width:66.67%}
.progreso[data-paso="3"] > span{width:100%}

.progreso-fila{
  display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:var(--sp-2);margin-bottom:var(--sp-5);
}
.progreso-fila .paso-de{
  font-size:var(--fs-micro);font-weight:var(--fw-black);
  letter-spacing:var(--track-wide);text-transform:uppercase;color:var(--teal-strong);
}
.progreso-fila .paso-que{font-size:var(--fs-small);color:var(--ink-soft)}

/* Barra de navegación del asistente.
   Estuvo pegada abajo con `position:sticky` y hubo que quitarlo: flotando sobre
   el contenido tapaba las últimas filas de la lista y se comía sus clics, que
   es el peor fallo posible en una pantalla donde marcar una casilla ES la
   acción. Y sobraba: partir el formulario en tres pasos ya deja cada pantalla
   lo bastante corta como para tener el botón a mano. */
.barra-acciones{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-3);
  margin-top:var(--sp-6);
  padding:var(--sp-5) 0 max(var(--sp-4),env(safe-area-inset-bottom));
  border-top:1px solid var(--line);
}
.barra-acciones .btn{flex:1 1 auto;min-width:min(100%,200px)}
.barra-acciones .empuje{display:none}
/* Nada de `order` para subir «Continuar» en móvil: reordenar visualmente sin
   reordenar el DOM deja el recorrido del tabulador al revés de lo que se ve, y
   quien navega con teclado acaba pulsando «Atrás» creyendo que avanza. El orden
   es el del marcado —atrás, adelante— en todos los anchos. */
@media (min-width:560px){
  .barra-acciones .btn{flex:0 0 auto}
  .barra-acciones .empuje{display:block;flex:1 1 auto}
}

/* --- Opciones seleccionables ----------------------------------------------
   Las filas con tick del móvil de la portada, aquí de verdad. El radio nativo
   se esconde pero sigue siendo el que manda: recibe el foco, responde a las
   flechas y se agrupa por `name`. El estado marcado se pinta con `:checked ~`,
   que funciona en todas partes; `:has()` solo añade el tinte de la fila. */

.opciones{display:grid;gap:var(--sp-2)}

.opcion{
  display:flex;align-items:center;gap:var(--sp-3);cursor:pointer;
  background:var(--bg);border:1px solid var(--line-strong);
  border-radius:var(--r-2);padding:.8em .95em;
  transition:border-color .16s ease,background-color .16s ease;
}
.opcion input{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
/* `--ink-soft` por lo mismo que la casilla: un hairline no llega a los 3:1 que
   pide el límite visual de un control. */
.opcion .marca{
  flex:none;width:22px;height:22px;border-radius:50%;
  border:2px solid var(--ink-soft);background:var(--surface);
  display:grid;place-items:center;
  transition:border-color .16s ease;
}
.opcion .marca::after{
  content:"";width:10px;height:10px;border-radius:50%;
  background:var(--ui-teal);transform:scale(0);
  transition:transform .16s cubic-bezier(.2,.8,.3,1);
}
.opcion .texto{font-weight:var(--fw-bold);font-size:var(--fs-small);line-height:1.35}

.opcion input:checked ~ .marca{border-color:var(--ui-teal)}
.opcion input:checked ~ .marca::after{transform:scale(1)}
.opcion:hover{border-color:var(--ui-teal)}
.opcion:has(input:checked){border-color:var(--ui-teal);background:var(--tint-teal)}
.opcion:has(input:focus-visible){outline:3px solid var(--focus);outline-offset:2px}

/* --- Listas que se marcan -------------------------------------------------
   Las filas con tick del móvil de la portada, aquí de verdad y escribibles.
   Cada fila es una casilla más una línea de texto editable; lo que se guarda es
   el texto de las marcadas, no una referencia a ninguna lista cerrada.

   La casilla nativa se esconde pero es la que manda: recibe el foco, responde a
   la barra espaciadora y la etiqueta la asocia. El cuadrado se pinta con
   `:checked ~`, que funciona en todas partes; `:has()` solo añade el tinte de
   la fila y su ausencia no deja nada sin estado visible. */

.lista-check{display:grid;gap:var(--sp-2)}

.fila-check{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;
  gap:var(--sp-3);
  background:var(--bg);border:1px solid var(--line-strong);
  border-radius:var(--r-2);padding:.45em .5em .45em .7em;
  transition:border-color .16s ease,background-color .16s ease;
}
.fila-check:focus-within{outline:3px solid var(--focus);outline-offset:2px}
.fila-check:has(input[type=checkbox]:checked){border-color:var(--ui-teal);background:var(--tint-teal)}

.marca-check{display:grid;place-items:center;cursor:pointer;padding:.25em}
.marca-check input{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
/* Cuadrado redondeado, como el tick de la portada. El relleno usa el par
   `--btn-fill` / `--btn-ink`, que ya está comprobado de contraste en los dos
   modos; el teal de marca sobre blanco no llegaba a 3:1. */
/* El borde va en `--ink-soft` y no en `--line-strong`. `--line-strong` es un
   token de hairline: sobre el fondo de la fila da 1,5:1, y el límite visual de
   un control tiene que llegar a 3:1 (WCAG 1.4.11). Justo aquí importa el doble,
   porque NINGUNA sugerencia arranca marcada: al entrar en el paso 1 lo único
   que hay en pantalla son casillas vacías. */
.marca-check .caja{
  width:24px;height:24px;border-radius:8px;flex:none;
  border:2px solid var(--ink-soft);background:var(--surface);
  transition:background-color .16s ease,border-color .16s ease;
}
.marca-check .caja::after{
  content:"";display:block;width:5px;height:9px;margin:3.5px 0 0 7px;
  border-right:2.6px solid var(--btn-ink);border-bottom:2.6px solid var(--btn-ink);
  transform:rotate(45deg) scale(.4);opacity:0;
  transition:transform .16s cubic-bezier(.2,.8,.3,1),opacity .16s ease;
}
.marca-check input:checked ~ .caja{background:var(--btn-fill);border-color:var(--btn-fill)}
.marca-check input:checked ~ .caja::after{transform:rotate(45deg) scale(1);opacity:1}

/* La línea crece con su texto.
   El envoltorio es una rejilla de una sola celda; el `::after` lleva el mismo
   texto —copiado por JS en `data-linea`— y es quien fija el alto. El textarea
   ocupa esa misma celda y lo hereda. Así una línea larga se parte en un móvil en
   vez de recortarse, y no hace falta escribir `style.height` desde JS, que es lo
   que la CSP `style-src 'self'` no quiere ver aquí. */
/* EL TAMAÑO SE SUBE AQUÍ, EN EL ENVOLTORIO, Y NO EN EL TEXTAREA.
   El campo tenía `--fs-small` (15px) y por debajo de 16 Safari amplía la página
   al enfocarlo. Pero el textarea y el medidor comparten celda y tipografía por
   `font:inherit`, y el alto de la fila lo fija el medidor: subir sólo el
   textarea dejaría al medidor midiendo con otra letra y la línea saldría con el
   alto equivocado justo en las que están a punto de partirse, que son las
   únicas donde esto importa. Subiendo el envoltorio, los dos suben a la vez y
   siguen midiendo lo mismo. */
.linea-crece{
  display:grid;min-width:0;
  font-size:max(var(--fs-input), var(--fs-small));
  font-weight:var(--fw-bold);line-height:1.45;
  color:var(--ink);
}
/* El texto medidor y el textarea comparten celda y tipografía. Si midieran
   distinto, el alto saldría mal justo en las líneas que están al borde de
   partirse, que son las únicas donde esto importa. */
.linea-crece::after,
.fila-check .linea{
  grid-area:1/1/2/2;
  font:inherit;color:inherit;padding:.45em 0;
  white-space:pre-wrap;overflow-wrap:anywhere;
}
.linea-crece::after{content:attr(data-linea) " ";visibility:hidden}
.fila-check .linea{
  width:100%;min-width:0;
  background:transparent;border:0;resize:none;overflow:hidden;
}
.fila-check .linea:focus-visible{outline:0}
.fila-check .linea::placeholder{color:var(--ink-soft);font-weight:400}
/* Sin marcar es una sugerencia, no un acuerdo: se lee más floja. El peso lo
   cambia el envoltorio, nunca el textarea, para que el medidor lo herede. */
.fila-check:not(:has(input[type=checkbox]:checked)) .linea-crece{
  color:var(--ink-soft);font-weight:600;
}

.fila-check .quitar{
  flex:none;width:32px;height:32px;border-radius:50%;
  display:grid;place-items:center;
  background:transparent;border:0;cursor:pointer;color:var(--ink-soft);
  transition:background-color .16s ease,color .16s ease;
}
.fila-check .quitar:hover{background:var(--tint-coral);color:var(--coral-strong)}
.fila-check .quitar:focus-visible{outline:3px solid var(--focus);outline-offset:1px}

.cuenta{
  flex:none;font-size:var(--fs-micro);font-weight:var(--fw-black);
  letter-spacing:var(--track-wide);text-transform:uppercase;color:var(--ink-soft);
}
.cuenta.tiene{color:var(--teal-strong)}

.pie-lista-check{
  display:block;margin-top:var(--sp-3);
  font-size:var(--fs-small);color:var(--ink-soft);line-height:1.5;
}

/* --- Palabra para parar ---------------------------------------------------
   La pastilla que el móvil de la portada enseña con «Naranja», aquí escribién-
   dose sola. Es la única pieza del acuerdo que se puede ver antes de guardar,
   y es justo la que más se olvida. */

/* `wrap` y no dos columnas fijas: la palabra admite 40 caracteres y la pastilla
   no parte, así que en dos columnas una palabra larga estrujaba el campo hasta
   dejarlo inservible. Al envolver, la pastilla se baja a su propia línea. */
.fila-palabra{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-3)}
.fila-palabra > input{flex:1 1 12rem;min-width:0}
.chip-vivo{
  flex:0 1 auto;max-width:100%;
  display:inline-flex;align-items:center;gap:.4em;
  font-size:var(--fs-small);font-weight:var(--fw-black);
  background:var(--tint-coral);color:var(--coral-strong);
  border:1px solid var(--notice-line);border-radius:var(--r-pill);
  padding:.45em .9em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* --- Panel oscuro de cifrado ----------------------------------------------
   La versión corta del panel de compromisos de la portada. La promesa de que
   el texto se cifra aquí es lo que sostiene todo el producto: merece el único
   momento invertido de la pantalla, no un pie de página. */

/* INVERSIÓN DE TOKENS POR ÁMBITO — y esto es un arreglo, no un adorno.

   Dentro de este panel hay enlaces: «política de privacidad» en la primera
   línea. Los pinta `.pantalla a:not(.btn)` con `--teal-strong`, que es el teal
   PROFUNDO —#006B72— pensado para leerse sobre crema. Sobre el navy de este
   panel eso da del orden de 1,3:1: el enlace está ahí, del color del fondo, y
   no se lee. Es el mismo texto en verde del que se quejó el dueño, y no es que
   estuviera mal colocado: es que era invisible.

   Se arregla con el mecanismo que `app.css` ya usa en las bandas oscuras de la
   portada (`.sx-banda-oscura`): se reasignan los tokens de rol DENTRO del
   ámbito y todas las reglas de fuera siguen siendo las mismas, sin duplicar un
   solo componente y sin un color nuevo. Todos los valores apuntan a `--panel-*`,
   que están definidos en los dos modos.

   Medido: `--panel-teal` (#5FE0DB) da 5,0:1 sobre el extremo claro del
   degradado (`--panel-2`, #12586F) y 6,1:1 sobre el oscuro (`--panel`). El
   peor punto es 5,0:1, o sea AA de sobra para texto pequeño. Lo que había
   antes —`--teal-strong`, #006B72— daba 1,3:1 sobre ese mismo extremo claro:
   el enlace estaba, pero no se veía. */
.panel-cifrado{
  --ink:var(--panel-ink);
  --ink-soft:var(--panel-soft);
  --teal-strong:var(--panel-teal);
  --teal-ink:var(--panel-teal);
  --line:var(--panel-line);
  --line-soft:var(--panel-line);
  --focus:var(--panel-teal);

  position:relative;overflow:hidden;
  background:linear-gradient(150deg,var(--panel-2),var(--panel) 58%);
  border:1px solid var(--panel-line);
  border-radius:var(--r-4);padding:clamp(22px,3.4vw,34px);
  color:var(--panel-ink);box-shadow:var(--sh-m);
  margin-bottom:var(--sp-5);
}
.panel-cifrado > *{position:relative;z-index:1}
.panel-cifrado .pdots{
  position:absolute;z-index:0;right:-6%;top:-26%;
  width:min(200px,46%);height:min(200px,46%);
  color:var(--panel-dot);
  background-image:radial-gradient(currentColor 1.7px,transparent 1.8px);
  background-size:14px 14px;
  -webkit-mask-image:radial-gradient(ellipse at center,#000 40%,transparent 74%);
          mask-image:radial-gradient(ellipse at center,#000 40%,transparent 74%);
}
.panel-cifrado .kicker{
  display:inline-block;font-size:.8rem;font-weight:var(--fw-black);
  letter-spacing:var(--track-wide);text-transform:uppercase;
  color:var(--panel-teal);margin-bottom:var(--sp-3);
}
.pantalla .panel-cifrado h2{color:var(--panel-ink);margin-bottom:var(--sp-3)}
.pantalla .panel-cifrado p{color:var(--panel-soft)}

.lista-cifrado{display:grid;gap:var(--sp-3);margin-top:var(--sp-4)}
.lista-cifrado li{
  display:flex;align-items:flex-start;gap:var(--sp-3);
  color:var(--panel-soft);font-size:var(--fs-small);line-height:1.5;
}
.lista-cifrado svg{flex:none;margin-top:.18em;color:var(--panel-teal)}
.lista-cifrado strong{color:var(--panel-ink)}

/* --- Repaso antes de cifrar ----------------------------------------------- */

.repaso{
  background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-3);padding:clamp(18px,2.8vw,26px);
  margin-bottom:var(--sp-5);
}
.repaso:empty{display:none}
.repaso .ayuda{margin:0}

/* --- Formularios --------------------------------------------------------- */

.form{display:grid;gap:var(--sp-4)}

/* Un botón es un grid item, y un grid item se estira: por eso «Cambiar
   contraseña» salía como una píldora del ancho de la tarjeta, que es el tamaño
   de un botón de portada, no el de una acción de ajustes. Se ajusta a su texto
   y se queda a la izquierda, en el flujo del formulario. */
.form > .btn{justify-self:start}
/* La excepción: en un móvil estrecho el botón que cierra el formulario sí gana
   yendo a lo ancho, que es donde el pulgar lo encuentra sin apuntar. */
@media (max-width:559px){ .form > .btn-1{justify-self:stretch} }

.campo{display:grid;gap:var(--sp-2)}
.campo > label{font-weight:var(--fw-bold);color:var(--ink);font-size:var(--fs-small)}
/* La ayuda, pegada a SU campo. Con el mismo hueco que el resto quedaba a media
   distancia entre el campo que explica y el siguiente, y había que leerla dos
   veces para saber de cuál hablaba: 4px abajo contra 16px hasta el siguiente. */
.campo > .ayuda{margin-top:calc(var(--sp-1) - var(--sp-2))}

/* `max(--fs-input, --fs-body)` y no `--fs-body` a secas. Hoy los dos valen 16px
   y la regla parece redundante; deja de serlo en cuanto alguien tiene el tamaño
   base del navegador en 14px, porque `--fs-body` es `1rem` y bajaría con él. Por
   debajo de 16px Safari en iOS amplía la página al enfocar el campo y no la
   devuelve: el formulario de entrar se queda a un zoom y medio de distancia. */
.campo input[type=text],
.campo input[type=email],
.campo input[type=password],
.campo textarea,
.campo select{
  width:100%;font:inherit;
  font-size:max(var(--fs-input), var(--fs-body));
  color:var(--ink);
  background:var(--bg);border:1px solid var(--line-strong);
  border-radius:var(--r-1);padding:.62em .8em;
}
.campo textarea{resize:vertical;line-height:var(--lh-body);min-height:5em}

/* EL FOCO, VISIBLE PERO NO DE 2005.
   Antes: 3px macizos de morado, separados 1px del campo. Se ve, sí, y parece un
   formulario de administración. Ahora son 2px de trazo pegados al borde —que es
   el mínimo que pide WCAG 2.4.11 y da de sobra sobre cualquiera de los dos
   fondos— más un halo de 4px en el mismo morado al 15 %, que es lo que le da
   volumen. El borde del campo se tiñe además del color del foco, así que el
   canal no es sólo el contorno: si el halo no se dibujara, el campo enfocado se
   distinguiría igual.

   `box-shadow` y no un segundo `outline` porque sólo hay uno por elemento, y el
   halo tiene que poder convivir con el contorno. En alto contraste el sistema
   descarta la sombra y deja el contorno, que es justo lo que hace falta. */
.campo input:focus-visible,
.campo textarea:focus-visible,
.campo select:focus-visible{
  outline:2px solid var(--focus);outline-offset:0;border-color:var(--focus);
  box-shadow:0 0 0 4px var(--tint-purple);
}

/* EL RELLENO AUTOMÁTICO NO PINTA EL CAMPO DE AMARILLO.
   Chrome y Safari pintan de amarillo pálido —o de azul, según versión— todo
   campo que rellenan de su almacén, y ese color no lo controla `background`:
   sólo se tapa con una sombra interior gigante. Es un fallo de aspecto muy
   visible justo en `/entrar`, que es donde el navegador rellena, y en modo
   oscuro además deja el texto negro sobre amarillo. Se devuelve el campo a los
   tokens de la casa. */
.campo input:-webkit-autofill,
.campo input:-webkit-autofill:hover,
.campo input:-webkit-autofill:focus{
  -webkit-text-fill-color:var(--ink);
  -webkit-box-shadow:0 0 0 100px var(--bg) inset;
  caret-color:var(--ink);
}

.campo-check{
  grid-template-columns:auto 1fr;align-items:start;gap:var(--sp-3);
}
.campo-check input{margin-top:.25em;width:1.15em;height:1.15em;accent-color:var(--ui-teal);flex:none}
.campo-check label{font-weight:400;color:var(--ink);line-height:var(--lh-body);font-size:var(--fs-small)}

.pantalla .ayuda,
.ayuda{font-size:var(--fs-small);color:var(--ink-soft);line-height:1.55}
.ayuda a{color:var(--teal-strong)}

/* --- Pestañas de entrar / crear cuenta ----------------------------------- */

/* Control segmentado en pastilla, no subrayado: el resto de la interfaz está
   hecho de píldoras —botones, estados, chips— y una pestaña subrayada era la
   única forma que no rimaba con nada. */
.pestanas{
  display:flex;gap:var(--sp-1);margin-bottom:var(--sp-5);
  background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-pill);padding:5px;
}
.pestanas button{
  flex:1 1 0;font:inherit;font-weight:var(--fw-black);font-size:var(--fs-small);
  background:transparent;border:0;border-radius:var(--r-pill);
  color:var(--ink-soft);padding:.62em 1em;cursor:pointer;
  transition:background-color .16s ease,color .16s ease,box-shadow .16s ease;
}
.pestanas button[aria-selected=true]{
  background:var(--surface);color:var(--teal-strong);box-shadow:var(--sh-s);
}
.pestanas button:focus-visible{outline:3px solid var(--focus);outline-offset:-2px}

/* --- Panel de ajustes ----------------------------------------------------
   `/cuenta` era una pila de siete tarjetas: para llegar a la última había que
   pasar por delante de las seis anteriores. Aquí es lo de siempre en una
   pantalla de ajustes —las secciones a la izquierda, la abierta a la derecha—
   y no hay nada que aprender.

   La rejilla se enciende con `data-pestanas`, que pone `ui/cuenta.js` al
   arrancar. Sin JavaScript no hay atributo, no hay dos columnas y la navegación
   sigue `hidden`: la pantalla se queda en la pila completa de siempre, que es
   exactamente lo que hay que ver cuando no hay nadie para cambiar de pestaña.

   No hay `.pestanas` reutilizado aquí: aquel es un segmentado de dos opciones
   en pastilla, que a cinco secciones en columna no le sirve. Los colores,
   radios y espacios son los mismos tokens. */

.ajustes[data-pestanas]{
  display:grid;
  grid-template-columns:minmax(0,13.5rem) minmax(0,1fr);
  gap:clamp(16px,2.4vw,32px);
  align-items:start;
}

.ajustes-nav{display:grid;gap:var(--sp-1);align-content:start}

/* Pegada arriba: el panel de accesos ocupa varias pantallas y sin esto habría
   que volver al principio cada vez que se quiere cambiar de sección. */
@media (min-width:721px){
  .ajustes[data-pestanas] .ajustes-nav{position:sticky;top:var(--sp-5)}
}
/* A partir de 820px la cabecera del sitio también es sticky, así que hay que
   dejarle su alto libre o se comería la primera pestaña. */
@media (min-width:820px){
  .ajustes[data-pestanas] .ajustes-nav{top:calc(var(--head-h) + var(--sp-3))}
}

.ajustes-tab{
  display:block;width:100%;text-align:left;
  font:inherit;font-size:var(--fs-small);font-weight:var(--fw-bold);
  color:var(--ink-soft);background:transparent;
  border:1px solid transparent;border-radius:var(--r-2);
  padding:.55em .85em;cursor:pointer;
  transition:background-color .16s ease,color .16s ease,border-color .16s ease;
}
.ajustes-tab:hover{background:var(--surface-2);color:var(--ink)}
/* Mismo recurso que la pestaña seleccionada de `.pestanas`: la activa se
   levanta a `--surface` con su sombra y las demás se quedan en el fondo. */
.ajustes-tab[aria-selected=true]{
  background:var(--surface);border-color:var(--line);
  color:var(--teal-strong);font-weight:var(--fw-black);box-shadow:var(--sh-s);
}
.ajustes-tab:focus-visible{outline:3px solid var(--focus);outline-offset:2px}

/* `min-width:0` para que una tarjeta ancha —la lista de sesiones, el enlace de
   compartir— se estreche con la columna en vez de estirar la rejilla. */
.ajustes-panel{min-width:0}
.ajustes-panel > :last-child{margin-bottom:0}

/* En pantalla estrecha la columna se sube entera y se convierte en una tira que
   se arrastra de lado. Ni acordeón ni menú desplegable: son dos estados más que
   mantener para enseñar cinco palabras que caben en una línea y media. */
@media (max-width:720px){
  .ajustes[data-pestanas]{grid-template-columns:minmax(0,1fr)}
  .ajustes[data-pestanas] .ajustes-nav{
    grid-auto-flow:column;grid-auto-columns:max-content;gap:var(--sp-2);
    overflow-x:auto;overscroll-behavior-x:contain;
    margin-bottom:var(--sp-5);padding-bottom:var(--sp-3);
    border-bottom:1px solid var(--line);
    /* Inercia al arrastrar. Sin esto la tira se para en seco donde levantas el
       dedo, y esa es la diferencia entre arrastrar y hacer scroll. */
    -webkit-overflow-scrolling:touch;
    /* La tira se para donde empieza una pestaña, nunca a mitad de una palabra.
       `proximity` y no `mandatory`: con obligatorio, un arrastre corto salta
       hasta la siguiente aunque sólo quisieras asomarte. */
    scroll-snap-type:x proximity;
    /* SIN BARRA DE DESPLAZAMIENTO. Una barra gris debajo de unas pestañas es de
       las cosas que sólo se ven en una web; ninguna aplicación la dibuja. La
       señal de que hay más a la derecha la da la última pestaña cortada contra
       el borde, que es para lo que está el `::after`.

       SIN DESVANECIDO EN EL BORDE, que era la otra opción: un degradado fijo a
       la derecha se ve también cuando las pestañas caben enteras, y entonces
       parece que falta algo que no falta. */
    scrollbar-width:none;
    -ms-overflow-style:none;
  }
  .ajustes[data-pestanas] .ajustes-nav::-webkit-scrollbar{width:0;height:0}
  /* Sin esto la última pestaña se corta contra el borde y no se ve que hay más
     a la derecha. */
  .ajustes[data-pestanas] .ajustes-nav::after{content:'';width:var(--sp-2)}
  .ajustes-tab{white-space:nowrap;scroll-snap-align:start}
}

/* --- Lista de acuerdos ---------------------------------------------------
   Fechas y estados, nunca contenido: no se puede mostrar lo que no se puede
   leer, y la API tampoco lo devuelve al listar. */

.lista-acuerdos{list-style:none;display:grid;gap:var(--sp-3);margin-bottom:var(--sp-5)}

.lista-acuerdos a{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-3);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-4);
  padding:clamp(18px,2.8vw,24px);text-decoration:none;color:var(--ink);
  box-shadow:var(--sh-s);
  transition:border-color .16s ease,transform .2s cubic-bezier(.2,.8,.3,1),box-shadow .2s ease;
}
.lista-acuerdos a:hover{
  border-color:var(--ui-teal);transform:translateY(-4px);box-shadow:var(--sh-m);
}
.lista-acuerdos a:focus-visible{outline:3px solid var(--focus);outline-offset:2px}

.lista-acuerdos .fecha{font-weight:var(--fw-black);flex:1 1 auto}
.lista-acuerdos .detalle{font-size:var(--fs-small);color:var(--ink-soft);flex:1 1 100%}

.vacio{color:var(--ink-soft);padding:var(--sp-6) 0;text-align:center}
/* Dentro de una tarjeta de ajustes el vacío es una línea más, no una pantalla
   de bienvenida: centrado y con 32px arriba y abajo dejaba un agujero entre el
   título y el botón del pie. */
.tarjeta-campo .vacio{padding:var(--sp-2) 0;text-align:left}
.pie-lista{margin-top:var(--sp-5)}

/* --- Filas dentro de una tarjeta ------------------------------------------
   Lo que antes eran tarjetas anidadas: cada sesión y cada llave de acceso se
   pintaban como una caja blanca con sombra dentro de la caja blanca de su
   sección. Aquí son filas separadas por una línea, que es lo que son: una lista
   de cosas del mismo rango dentro de una sección que ya tiene su propio marco.

   La lista vacía se quita entera —`:empty`— para que su hueco no se quede
   abierto entre el texto y el botón del pie cuando no hay ninguna. */

.lista-filas{list-style:none;display:grid;margin-bottom:var(--sp-3)}
.lista-filas:empty{display:none}

.fila-ajuste{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-3);
  padding:var(--sp-3) 0;border-top:1px solid var(--line);
}
.fila-ajuste:first-child{border-top:0;padding-top:var(--sp-2)}
.fila-ajuste .cuerpo{flex:1 1 13rem;min-width:0}
.fila-ajuste .btn{flex:none}
/* El nombre del dispositivo y su pastilla, en la misma línea. */
.fila-ajuste .fila-titulo{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);
  font-weight:var(--fw-bold);
}
.fila-ajuste .ayuda{margin-top:2px}

/* En estrecho la fila se apila y el botón baja: en fila, un botón y tres líneas
   de fecha dejan el texto en una columna de dos palabras. */
@media (max-width:559px){
  .fila-ajuste{flex-direction:column;align-items:stretch;gap:var(--sp-2)}
  /* `flex-basis` va por el eje principal, y aquí el eje principal pasa a ser el
     vertical: sin esto las 13rem del cuerpo dejaban de ser un ancho mínimo y
     pasaban a ser 208px de ALTO, con un agujero entre las fechas y el botón. */
  .fila-ajuste .cuerpo{flex:0 0 auto}
  .fila-ajuste .btn{align-self:flex-start}
}

/* El botón que cierra una tarjeta con lista —«Cerrar las demás sesiones»— va
   detrás de su propia línea, como pie de la sección y no como una fila más. */
.pie-tarjeta{
  margin-top:var(--sp-3);padding-top:var(--sp-3);
  border-top:1px solid var(--line);
}
/* Si el botón que lleva dentro está escondido —no hay otras sesiones que
   cerrar— el pie no puede dejar su línea colgando sobre nada. */
.pie-tarjeta:has(> [hidden]:only-child){display:none}

/* Estado vacío: una tarjeta con badge y una salida, no un párrafo gris.
   Es la primera pantalla de quien acaba de crear la cuenta. */
.estado-vacio{
  text-align:center;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-4);padding:clamp(28px,5vw,48px);
  box-shadow:var(--sh-s);margin-bottom:var(--sp-5);
}
.estado-vacio .badge{margin-inline:auto}
.pantalla .estado-vacio h2{margin-bottom:var(--sp-2)}
.estado-vacio p{color:var(--ink-soft);max-width:36ch;margin:0 auto var(--sp-5)}

/* --- Estado -------------------------------------------------------------- */

.estado-pill{
  font-size:var(--fs-micro);font-weight:var(--fw-black);
  letter-spacing:var(--track-wide);text-transform:uppercase;
  padding:.4em .85em;border-radius:var(--r-pill);
  background:var(--surface-2);color:var(--ink-soft);border:1px solid var(--line);
  white-space:nowrap;
}
.estado-activo{background:var(--tint-teal);color:var(--teal-strong);border-color:var(--ui-teal)}
.estado-pendiente{background:var(--tint-purple);color:var(--purple-ink);border-color:var(--ui-purple)}
.estado-retirado{background:var(--tint-coral);color:var(--coral-strong);border-color:var(--notice-line)}

/* --- Metadatos ----------------------------------------------------------- */

.meta{display:grid;gap:var(--sp-2);margin-bottom:var(--sp-4);font-size:var(--fs-small)}
.meta div{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.meta dt{font-weight:var(--fw-bold);color:var(--ink);min-width:9em}
.meta dd{margin:0;color:var(--ink-soft)}

/* --- El acuerdo, ya descifrado ------------------------------------------- */

.seccion-acuerdo{margin-bottom:var(--sp-5)}
.seccion-acuerdo:last-child{margin-bottom:0}
.seccion-acuerdo h3{
  font-size:var(--fs-small);font-weight:var(--fw-black);
  letter-spacing:var(--track-wide);text-transform:uppercase;
  color:var(--teal-strong);margin-bottom:var(--sp-2);
}
/* `pre-wrap` para respetar los saltos de línea de un textarea sin construir
   HTML: el texto entra siempre por textContent. */
.seccion-acuerdo p{white-space:pre-wrap;color:var(--ink);line-height:var(--lh-body)}

/* Lo que se acordó cosa por cosa se lee como se escribió: una lista marcada.
   Un párrafo de una sola línea sigue siendo un párrafo, así que los acuerdos
   antiguos se ven exactamente igual que antes. */
.lista-acordada{display:grid;gap:var(--sp-2)}
.lista-acordada li{
  display:flex;align-items:flex-start;gap:var(--sp-3);
  color:var(--ink);line-height:var(--lh-body);
}
.lista-acordada .punto{
  flex:none;margin-top:.28em;width:20px;height:20px;border-radius:7px;
  background:var(--btn-fill);
}
.lista-acordada .punto::after{
  content:"";display:block;width:4px;height:8px;margin:3px 0 0 6px;
  border-right:2.4px solid var(--btn-ink);border-bottom:2.4px solid var(--btn-ink);
  transform:rotate(45deg);
}

/* --- Compartir ----------------------------------------------------------- */

.bloque-compartir{border-color:var(--ui-teal)}

.qr{
  display:flex;justify-content:center;
  margin:var(--sp-5) 0;
}
.qr svg{
  width:min(260px,72vw);height:auto;
  border-radius:var(--r-2);border:1px solid var(--line);
  /* El fondo blanco lo pinta el propio SVG: un QR sobre fondo oscuro no lo
     lee ninguna cámara. */
}

.enlace-fila{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-bottom:var(--sp-3)}
/* 16px de suelo también aquí, y aquí importaba de verdad: es el campo del
   enlace del acuerdo, o sea el que la gente toca para copiarlo, y con 15px
   tocarlo ampliaba la pantalla justo cuando hay que seleccionar una URL larga.
   El monoespaciado dibuja más estrecho que la redondeada, así que subir un
   píxel no le quita sitio a nada. */
.enlace-fila input{
  flex:1 1 14rem;min-width:0;font:inherit;
  font-size:max(var(--fs-input), var(--fs-small));
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  color:var(--ink-soft);background:var(--bg);
  border:1px solid var(--line-strong);border-radius:var(--r-1);padding:.6em .75em;
}
.enlace-fila input:focus-visible{
  outline:2px solid var(--focus);outline-offset:0;border-color:var(--focus);
  box-shadow:0 0 0 4px var(--tint-purple);
}

/* --- Retirar -------------------------------------------------------------
   Coral, grande y siempre visible. Es la operación que sostiene todo lo que
   promete la portada: si costara un paso más que aceptar, el producto sería
   indefendible. */

.tarjeta-retirar{border-color:var(--notice-line);background:var(--notice-bg)}
.tarjeta-retirar h2{color:var(--coral-strong)}
.tarjeta-retirar p{color:var(--ink)}

/* `--btn-ink` y no `#fff`: era el único color literal del fichero y en modo
   oscuro `--coral-strong` es un rosa claro, así que el texto blanco sobre él
   dejaba ilegible el botón que sostiene todo lo que promete la portada.
   `--btn-ink` es blanco en claro y tinta oscura en oscuro. */
.btn-retirar{
  margin-top:var(--sp-4);
  background:var(--coral-strong);border-color:var(--coral-strong);color:var(--btn-ink);
  box-shadow:var(--sh-s);
}
.btn-retirar:hover{background:var(--coral-dark);border-color:var(--coral-dark);transform:translateY(-2px)}

.tarjeta-guardar{border-color:var(--ui-purple);background:var(--tint-purple)}

.acciones{display:flex;flex-wrap:wrap;gap:var(--sp-3);margin-bottom:var(--sp-4)}
.acciones .btn{flex:1 1 auto;min-width:min(100%,200px)}
@media (min-width:520px){ .acciones .btn{flex:0 0 auto} }

/* --- Más opciones -------------------------------------------------------- */

.mas-opciones{
  border-top:1px solid var(--line);padding-top:var(--sp-4);margin-top:var(--sp-5);
}
.mas-opciones summary{
  font-weight:var(--fw-bold);font-size:var(--fs-small);color:var(--ink-soft);
  cursor:pointer;list-style:none;
}
.mas-opciones summary::-webkit-details-marker{display:none}
.mas-opciones summary::before{content:'+ ';color:var(--ui-teal)}
.mas-opciones[open] summary::before{content:'− '}
.mas-opciones summary:focus-visible{outline:3px solid var(--focus);outline-offset:3px;border-radius:var(--r-1)}
.mas-opciones p{margin:var(--sp-4) 0;color:var(--ink-soft);font-size:var(--fs-small)}

/* --- Movimiento reducido -------------------------------------------------
   app.css ya anula duración de transiciones y animaciones en todo el sitio.
   Falta lo que no es duración: los desplazamientos. */

@media (prefers-reduced-motion: reduce){
  /* `.btn-retirar:hover` empata en especificidad con el `.btn:hover{transform:none}`
     de app.css y gana por orden de fichero, así que hay que anularlo aquí. */
  .lista-acuerdos a:hover,.btn-retirar:hover{transform:none}
  .opcion .marca::after,.marca-check .caja::after{transition:none}
}

/* --- Alto contraste (Windows) --------------------------------------------
   En este modo el sistema reemplaza los colores, y un radio cuyo estado se
   pinta con un círculo teal se quedaría sin estado visible. `Highlight` es el
   color del sistema para «esto está seleccionado». */

@media (forced-colors: active){
  .tarjeta,.tarjeta-campo,.panel-cifrado,.estado-vacio,
  .lista-acuerdos a,.opcion,.fila-check{border:1px solid CanvasText}
  .opcion .marca{forced-color-adjust:none;border-color:CanvasText;background:Canvas}
  .opcion .marca::after{background:Highlight}
  .opcion input:checked ~ .marca{border-color:Highlight}
  .marca-check .caja{forced-color-adjust:none;border-color:CanvasText;background:Canvas}
  .marca-check .caja::after{border-color:HighlightText}
  .marca-check input:checked ~ .caja{background:Highlight;border-color:Highlight}
  .lista-acordada .punto{forced-color-adjust:none;background:Highlight}
  .lista-acordada .punto::after{border-color:HighlightText}
  .progreso > span{forced-color-adjust:none;background:Highlight}
  /* La pestaña abierta se distingue por el fondo, y aquí el sistema reemplaza
     los fondos: sin esto no habría forma de ver cuál está abierta. */
  .ajustes-tab[aria-selected=true]{
    forced-color-adjust:none;background:Highlight;color:HighlightText;border-color:Highlight;
  }
}

/* --- Medidor de fuerza de la contraseña -----------------------------------
   Nunca bloquea el envío: un medidor que bloquea se convierte en una regla, y
   las reglas son las que producen «Password1!». El color no es el único canal
   (WCAG 1.4.1): el texto de al lado dice el nivel y el motivo. */

.medidor{
  height:6px;border-radius:var(--r-pill);background:var(--line);
  overflow:hidden;margin-top:var(--sp-2);
}
.medidor > span{display:block;height:100%;width:0;border-radius:var(--r-pill);
  transition:width .2s ease, background-color .2s ease}
.medidor[data-nivel="0"] > span{width:12%;background:var(--coral-strong)}
.medidor[data-nivel="1"] > span{width:32%;background:var(--coral-strong)}
.medidor[data-nivel="2"] > span{width:56%;background:var(--ui-purple)}
.medidor[data-nivel="3"] > span{width:80%;background:var(--ui-teal)}
.medidor[data-nivel="4"] > span{width:100%;background:var(--teal-strong)}

@media (prefers-reduced-motion: reduce){ .medidor > span{transition:none} }

/* Un botón que se lee como un enlace: «mostrar contraseña» es una acción, así
   que tiene que ser un <button>, pero no compite con el botón de enviar. */
.enlace-boton{
  justify-self:start;font:inherit;font-size:var(--fs-small);font-weight:var(--fw-bold);
  background:none;border:0;padding:0;cursor:pointer;
  color:var(--teal-strong);text-decoration:underline;text-underline-offset:3px;
}
.enlace-boton:focus-visible{outline:3px solid var(--focus);outline-offset:3px;border-radius:var(--r-1)}

/* --- Acceso con Google ----------------------------------------------------- */

.acceso-social{margin-bottom:var(--sp-5)}
.btn-google{width:100%;justify-content:center;background:var(--surface)}
.btn-google svg{flex:none}

/* Separador con la palabra dentro de la línea. */
.separador{
  display:flex;align-items:center;gap:var(--sp-4);
  margin:var(--sp-5) 0 0;color:var(--ink-soft);font-size:var(--fs-small);
}
.separador::before,
.separador::after{content:'';flex:1;height:1px;background:var(--line)}

/* --- Diálogo modal --------------------------------------------------------
   Lo que pinta `ui/dialogo.js`. El elemento es un `<dialog>` nativo abierto con
   `showModal()`, así que la capa superior, el fondo inerte y la trampa de foco
   NO se resuelven aquí: los pone el navegador. Esto es sólo la caja.

   Cuelga de <body> y no de `.pantalla`, de modo que ninguna de las reglas con
   `.pantalla` delante le alcanza. Por eso el título y el texto se visten aquí
   en vez de heredar de `.pantalla h2` y `.pantalla p`. */

.dialogo{
  width:min(30rem,calc(100vw - var(--sp-6)));
  width:min(30rem,calc(100dvw - var(--sp-6)));
  /* `dvh` por lo mismo que `.pantalla`, y aquí con un motivo extra: `pedirTexto()`
     abre un diálogo CON un campo, así que el teclado sube justo cuando este
     elemento está en pantalla. Con `vh` el diálogo se dimensiona contra un alto
     que ya no existe y sus botones acaban debajo del teclado. */
  max-height:min(84vh,44rem);
  max-height:min(84dvh,44rem);
  padding:0;                              /* el aire lo pone `.dialogo-caja` */
  overflow:auto;                          /* mensajes largos, sin desbordar */
  /* Al llegar al final del diálogo, seguir arrastrando movía la página de
     detrás. Con el fondo inerte eso es desconcertante: se mueve algo que no se
     puede tocar. */
  overscroll-behavior:contain;
  color:var(--ink);background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-4);
  box-shadow:var(--sh-l);
}

.dialogo-caja{display:grid;gap:var(--sp-4);padding:clamp(20px,3.4vw,30px)}

.dialogo-titulo{
  font-size:var(--fs-h3);line-height:var(--lh-head);
  letter-spacing:-.02em;margin:0;
}
.dialogo-texto{margin:0;font-size:var(--fs-body);line-height:1.6;color:var(--ink-soft)}

/* Mismo reparto que `.acciones`: a lo ancho en un móvil, en fila y a la derecha
   en cuanto hay sitio. Cancelar va PRIMERO en el DOM porque el foco inicial es
   suyo, y en fila queda a la izquierda, que es donde se espera. */
.dialogo-botones{
  display:flex;flex-wrap:wrap;gap:var(--sp-3);
  justify-content:flex-end;margin-top:var(--sp-2);
}
.dialogo-botones .btn{flex:1 1 auto;min-width:min(100%,180px)}
@media (min-width:520px){ .dialogo-botones .btn{flex:0 0 auto} }
/* `.btn-retirar` trae `margin-top` porque en la tarjeta de retirar va suelto
   bajo un párrafo; aquí está dentro de una fila y ese margen la descuadra. */
.dialogo-botones .btn-retirar{margin-top:0}

/* Deshabilitado mientras `exigir:` no coincide. El color no es el único canal:
   se le quitan también la sombra y el desplazamiento del hover, que son lo que
   dice «esto responde». */
.dialogo-botones .btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
.dialogo-botones .btn:disabled:hover{transform:none;box-shadow:none}

/* `::backdrop` no heredaba de su elemento hasta hace poco, así que en un
   navegador algo anterior las variables de `:root` no llegan y `var(--x)` se
   quedaría en nada: el fondo saldría transparente, que es justo el fallo que no
   se puede tener aquí. Por eso los dos únicos colores literales de este bloque
   —el azul de la marca al 52 % y su equivalente oscuro— van escritos a mano. */
.dialogo::backdrop{background:rgba(15,74,97,.52)}
@media (prefers-color-scheme: dark){
  .dialogo::backdrop{background:rgba(4,20,26,.68)}
}

/* Entrada corta: el diálogo aparece donde se va a quedar. El único movimiento
   real es el de la caja, y ése ya lo anula el `*{animation-duration:.001ms}` de
   app.css con `prefers-reduced-motion`. Al `::backdrop` ese comodín no le llega
   —`*` no casa con pseudoelementos— pero lo suyo es sólo opacidad, que no es
   movimiento y es justo lo que esa preferencia no pide quitar. */
.dialogo[open]{animation:dialogo-entra .16s cubic-bezier(.2,.8,.3,1)}
.dialogo[open]::backdrop{animation:dialogo-fondo .16s ease}
@keyframes dialogo-entra{from{opacity:0;transform:translateY(10px) scale(.98)}}
@keyframes dialogo-fondo{from{opacity:0}}

/* Con el diálogo abierto el fondo es inerte pero la rueda lo sigue desplazando,
   que es desconcertante. `:has()` lo resuelve sin escribir estilos desde
   JavaScript, cosa que la CSP `style-src 'self'` no permitiría. */
html:has(.dialogo[open]){overflow:hidden}

@media (forced-colors: active){
  .dialogo{border:1px solid CanvasText}
}

/* ==========================================================================
   TACTO DE APLICACIÓN EN LAS PANTALLAS
   --------------------------------------------------------------------------
   La parte general está en `app.css`. Aquí van las piezas que sólo existen en
   la aplicación: filas, pestañas, opciones y el asistente.

   LA LÍNEA QUE NO SE CRUZA, otra vez: nada de esto toca el contenido de un
   acuerdo. Lo que está escrito dentro se marca y se copia, y las últimas
   reglas del bloque están para GARANTIZARLO aunque un ancestro decida lo
   contrario.
   ========================================================================== */

/* 1 · Sin recuadro gris al tocar y sin la espera del doble toque. */
.pestanas button,
.ajustes-tab,
.opcion,
.marca-check,
.fila-check .quitar,
.lista-acuerdos a,
.enlace-boton,
.mas-opciones summary,
.paso-titulo{
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
}

/* 2 · Los rótulos de los controles no se seleccionan al mantener el dedo.
   `.opcion .texto` y la etiqueta de una casilla son rótulos de control, no
   texto que nadie vaya a querer copiar. La línea escribible de `.fila-check`
   NO entra aquí: ésa es un textarea y es contenido. */
.pestanas button,
.ajustes-tab,
.opcion .texto,
.estado-pill,
.cuenta,
.progreso-fila{
  -webkit-user-select:none;
  user-select:none;
  -webkit-touch-callout:none;
}

/* 3 · Respuesta al pulsar.
   Las filas y las tarjetas se hunden un poco; los controles pequeños se tiñen
   en vez de moverse, porque a ese tamaño una escala del 3 % no se ve y lo que
   se lee es el color. Todo con transición corta: si tarda, deja de ser
   respuesta y pasa a ser animación. */
.lista-acuerdos a:active{transform:scale(.985);transition-duration:.06s}
.pestanas button:active,
.ajustes-tab:active{transform:scale(.97);transition-duration:.06s}
.opcion:active{background:var(--tint-teal);border-color:var(--ui-teal)}
.fila-check .quitar:active{background:var(--tint-coral);color:var(--coral-strong)}
.enlace-boton:active{color:var(--teal-ink)}
/* El menú no está aquí: vive en `movil.css`, que también carga la web de venta.
   Puesto aquí, el menú de la portada se quedaría sin estado de pulsación. */

/* 4 · El `:hover` pegajoso del táctil, en las piezas de esta hoja. Esta hoja
   carga DESPUÉS de `app.css`, así que su bloque equivalente no alcanza a lo de
   aquí y hay que repetirlo. Ver «PUNTERO QUE NO SE POSA» al final de `app.css`. */
@media (hover:none){
  .lista-acuerdos a:hover{transform:none;box-shadow:var(--sh-s)}
  .btn-retirar:hover{transform:none}
  .ajustes-tab:hover{background:transparent;color:var(--ink-soft)}
  .ajustes-tab[aria-selected=true]:hover{background:var(--surface);color:var(--teal-strong)}
}

/* 5 · EL CONTENIDO SE SELECCIONA Y SE COPIA. SIEMPRE.
   El cromo de la cáscara lleva `user-select:none` heredable, y esto es lo que
   impide que ese `none` se cuele donde no debe. En este producto no es un
   detalle: lo que hay dentro de un acuerdo es lo único que la gente puede
   querer llevarse, y el enlace de compartir ES la credencial — si no se puede
   seleccionar, no se puede compartir por ningún otro camino.

   `-webkit-touch-callout:default` devuelve además el menú de mantener pulsado
   en iOS, que es como se copia con un dedo. */
.seccion-acuerdo,
.seccion-acuerdo p,
.lista-acordada,
.lista-acordada li,
.chip-vivo,
.enlace-fila input,
.fila-check .linea,
.meta{
  -webkit-user-select:text;
  user-select:text;
  -webkit-touch-callout:default;
}

/* 6 · Movimiento reducido: las pulsaciones dejan de moverse y se quedan sólo
   con el color. El tinte no es movimiento, así que no hay nada que quitarle a
   quien pidió menos: sigue habiendo respuesta al tocar. */
@media (prefers-reduced-motion: reduce){
  .lista-acuerdos a:active,
  .pestanas button:active,
  .ajustes-tab:active{transform:none}
  .lista-acuerdos a:active{border-color:var(--ui-teal)}
}
