/* ==========================================================================
   Componentes — el vocabulario visual de la app
   ========================================================================== */

/* ==========================================================================
   1. Armazón
   ========================================================================== */

/*
 * El armazón va fijo al viewport, no con height: 100dvh.
 *
 * En una PWA instalada en iOS, dvh no siempre resuelve al alto real y la app
 * se queda corta: aparece una franja muerta debajo y la barra inferior da la
 * sensación de flotar a media pantalla. `position: fixed; inset: 0` mide
 * exactamente el viewport visible, sin depender de cómo interprete el
 * navegador las unidades de altura.
 */
#app {
  position: fixed;
  inset: 0;
  z-index: var(--z-contenido);
  width: 100%;
  max-width: var(--ancho-app);
  margin-inline: auto;
  display: grid;
  grid-template-rows: auto 1fr;
  overflow: hidden;
}

/* En pantallas anchas la app se centra con marco de cristal */
@media (min-width: 620px) {
  #app {
    height: min(100dvh, 940px);
    margin-block: auto;
    border-radius: var(--r-3xl);
    border: 1px solid var(--cristal-borde);
    box-shadow: var(--sombra-flotante);
    background: rgb(var(--verde-950-rgb) / 0.28);
  }
  [data-tema="claro"] #app { background: rgb(255 255 255 / 0.30); }
}

/*
 * La vista es solo el hueco por el que se mira: no desplaza ni acolcha nada.
 * De eso se encarga cada pantalla, y así cada pestaña conserva su propia
 * posición de scroll cuando cambias de una a otra.
 */
.vista {
  grid-row: 2;
  overflow: hidden;
  position: relative;
  min-height: 0;
}

/* ---- Pantalla suelta (rutas que no son pestaña) ------------------------- */

.pantalla {
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  padding-inline: var(--margen);
  padding-bottom: var(--hueco-nav);
  scrollbar-gutter: stable;
}

.pantalla--sin-nav { padding-bottom: calc(var(--seguro-abajo) + var(--e-6)); }
.pantalla--limpia { padding-inline: 0; scrollbar-gutter: auto; }

/* ==========================================================================
   1b. Pestañas: las tres secciones viven a la vez
   ========================================================================== */

/*
 * Inicio, Juegos y Progreso no se desmontan al cambiar de una a otra: están
 * las tres montadas, una al lado de la otra, y lo que se mueve es la pista.
 *
 * Eso resuelve tres cosas de golpe: no hay que volver a construir el HTML en
 * cada cambio, las animaciones de entrada no se repiten cada vez, y cada
 * pestaña conserva por dónde iba el scroll —que es exactamente lo que
 * distingue una app de una web.
 */
.pista {
  display: flex;
  height: 100%;
  width: 100%;
  will-change: transform;
  touch-action: pan-y;
}

.pista--animada {
  transition: transform 360ms var(--ease-deslizar);
}

.hoja-tab {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  padding-inline: var(--margen);
  padding-bottom: var(--hueco-nav);
  scrollbar-gutter: stable;
}

/* Las que no se ven no reciben toques ni salen en el orden de tabulación */
.hoja-tab[aria-hidden="true"] { pointer-events: none; }

/* ==========================================================================
   2. Cabecera
   ========================================================================== */

.cabecera {
  grid-row: 1;
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: calc(var(--seguro-arriba) + var(--e-4)) var(--margen) var(--e-4);
  min-height: calc(var(--seguro-arriba) + 64px);
}

/* Al cambiar de sección la cabecera no salta: se funde. Es medio segundo de
   detalle que separa una app de una web que repinta. */
.cabecera--entra > * {
  animation: aparecer var(--d-media) var(--ease-suave) both;
}

.cabecera__titulo {
  font-family: var(--f-display);
  font-size: var(--t-h3);
  font-weight: var(--peso-display-medio);
  letter-spacing: var(--track-titulo);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cabecera__sub {
  font-size: var(--t-micro);
  color: var(--texto-tenue);
  font-weight: var(--peso-texto-fuerte);
  letter-spacing: 0.02em;
}

/* ==========================================================================
   3. Botones
   ========================================================================== */

.btn {
  --btn-alto: 56px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  min-height: var(--btn-alto);
  padding-inline: var(--e-7);
  border-radius: var(--r-full);
  font-family: var(--f-texto);
  font-size: var(--t-cuerpo);
  font-weight: var(--peso-texto-fuerte);
  letter-spacing: -0.01em;
  text-align: center;
  position: relative;
  overflow: hidden;
  transition:
    transform var(--d-rapida) var(--ease-suave),
    box-shadow var(--d-rapida) var(--ease-suave),
    opacity var(--d-rapida) var(--ease-suave),
    background var(--d-rapida) var(--ease-suave);
}

.btn:active { transform: scale(0.965); }

.btn svg { width: 20px; height: 20px; flex: 0 0 auto; }
.btn--pequeno svg { width: 17px; height: 17px; }
.btn--grande svg { width: 22px; height: 22px; }

.btn:disabled {
  opacity: 0.42;
  transform: none;
  pointer-events: none;
}

.btn--bloque { width: 100%; }

.btn--primario {
  background-image: linear-gradient(135deg, var(--relleno-desde) 0%, var(--relleno-hasta) 100%);
  color: var(--relleno-texto);
  box-shadow:
    0 8px 24px rgb(var(--verde-300-rgb) / 0.26),
    inset 0 1px 0 rgb(255 255 255 / 0.45);
}

/* Brillo que cruza el botón principal: invita sin gritar */
.btn--primario::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 34%;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / 0.42), transparent);
  animation: brillo-pasa 4.5s var(--ease-respiro) infinite;
  animation-delay: 1.4s;
  pointer-events: none;
}

.btn--cristal {
  background: var(--cristal-fondo-alto);
  border: 1px solid var(--cristal-borde-alto);
  backdrop-filter: blur(var(--cristal-blur-sutil)) saturate(140%);
  -webkit-backdrop-filter: blur(var(--cristal-blur-sutil)) saturate(140%);
  color: var(--texto);
}

.btn--relieve {
  background: var(--neu-fondo);
  box-shadow: var(--sombra-neu-sutil);
  color: var(--texto);
  border: 1px solid rgb(var(--verde-300-rgb) / 0.08);
}
.btn--relieve:active { box-shadow: var(--sombra-neu-hundida); }

.btn--contorno {
  border: 1.5px solid var(--acento-borde);
  color: var(--acento);
  background: transparent;
}

.btn--fantasma {
  color: var(--texto-suave);
  background: transparent;
  padding-inline: var(--e-4);
}
.btn--fantasma:active { background: var(--acento-tenue); }

.btn--pequeno {
  --btn-alto: 42px;
  padding-inline: var(--e-5);
  font-size: var(--t-pequeno);
}

.btn--grande {
  --btn-alto: 62px;
  font-size: calc(var(--t-cuerpo) * 1.06);
}

/* Botón redondo de icono */
.btn-icono {
  width: var(--tactil);
  height: var(--tactil);
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: var(--r-full);
  background: var(--cristal-fondo);
  border: 1px solid var(--cristal-borde);
  backdrop-filter: blur(var(--cristal-blur-sutil));
  -webkit-backdrop-filter: blur(var(--cristal-blur-sutil));
  color: var(--texto);
  transition: transform var(--d-rapida) var(--ease-suave), background var(--d-rapida) var(--ease-suave);
}
.btn-icono:active { transform: scale(0.9); background: var(--acento-tenue); }
.btn-icono svg { width: 21px; height: 21px; }
.btn-icono--relieve {
  background: var(--neu-fondo);
  box-shadow: var(--sombra-neu-sutil);
  border-color: rgb(var(--verde-300-rgb) / 0.08);
}
.btn-icono--relieve:active { box-shadow: var(--sombra-neu-hundida); }

/* ==========================================================================
   4. Apilado
   ========================================================================== */

/*
 * Una pila de bloques con aire entre ellos.
 *
 * La separación es responsabilidad del contenedor, no de cada tarjeta: si
 * cada bloque llevara su propio margen inferior, bastaría con olvidarlo en
 * uno para que dos tarjetas quedaran pegadas —que es justo lo que pasaba en
 * Inicio, Perfil y la ficha de juego.
 */
.pila {
  display: grid;
  /*
   * minmax(0, 1fr) y no 1fr: por defecto un hijo de grid no se encoge por
   * debajo de su contenido, así que un carrusel de 1100 px estiraba la
   * columna entera en vez de desplazarse dentro de ella. Con esto la
   * columna manda y el carrusel vuelve a hacer scroll como debe.
   */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--e-5);
  align-content: start;
}

.pila--amplia { gap: var(--e-6); }
.pila--junta { gap: var(--e-3); }

/* Dentro de una pila, las secciones no añaden su propio margen: mandaría
   el mayor de los dos y el ritmo se volvería irregular. */
.pila > .seccion { margin-block: 0; }

/* ==========================================================================
   5. Tarjetas
   ========================================================================== */

.tarjeta {
  border-radius: var(--r-xl);
  padding: var(--e-6);
}

.tarjeta--compacta { padding: var(--e-5); }
.tarjeta--amplia { padding: var(--e-7); }

/* Tarjeta pulsable (todo el bloque es un botón) */
.tarjeta-boton {
  display: block;
  width: 100%;
  text-align: start;
  transition:
    transform var(--d-rapida) var(--ease-suave),
    box-shadow var(--d-media) var(--ease-suave),
    border-color var(--d-media) var(--ease-suave);
}
.tarjeta-boton:active {
  transform: scale(0.982);
  border-color: var(--acento-borde);
}

/* ==========================================================================
   5. Fichas y etiquetas
   ========================================================================== */

.ficha {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  padding: 7px 14px;
  border-radius: var(--r-full);
  background: var(--acento-tenue);
  border: 1px solid rgb(var(--verde-300-rgb) / 0.16);
  font-size: var(--t-micro);
  font-weight: var(--peso-texto-fuerte);
  color: var(--acento);
  letter-spacing: -0.005em;
  white-space: nowrap;
  line-height: 1.35;
}

.ficha--suave {
  background: var(--cristal-fondo);
  border-color: var(--cristal-borde);
  color: var(--texto-suave);
}

.ficha--solida {
  background-image: linear-gradient(135deg, var(--relleno-desde), var(--relleno-hasta));
  color: var(--relleno-texto);
  border-color: transparent;
}

.ficha svg { width: 14px; height: 14px; flex: 0 0 auto; }

/* Punto de dominio cognitivo */
.punto {
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  flex: 0 0 auto;
  background: var(--acento);
}

/* ==========================================================================
   6. Campos de formulario
   ========================================================================== */

.campo { display: block; }

.campo__etiqueta {
  display: block;
  font-size: var(--t-micro);
  font-weight: var(--peso-texto-fuerte);
  color: var(--texto-suave);
  margin-bottom: var(--e-2);
  padding-inline-start: var(--e-4);
}

.campo__envoltorio {
  position: relative;
  display: flex;
  align-items: center;
  border-radius: var(--r-full);
  background: var(--neu-fondo-hundido);
  box-shadow: var(--sombra-neu-hundida);
  transition: box-shadow var(--d-media) var(--ease-suave);
}

.campo__envoltorio:focus-within {
  box-shadow: var(--sombra-neu-hundida), var(--resplandor);
}

.campo__icono {
  display: grid;
  place-items: center;
  width: 52px;
  flex: 0 0 auto;
  color: var(--texto-tenue);
}
.campo__icono svg { width: 19px; height: 19px; }

.campo__entrada {
  flex: 1;
  min-width: 0;
  height: 58px;
  padding-inline: var(--e-3) var(--e-5);
  font-size: 16px; /* < 16px provoca zoom automático en iOS */
  font-weight: var(--peso-texto-medio);
  color: var(--texto);
  background: transparent;
  border-radius: var(--r-full);
}
.campo__envoltorio > .campo__entrada:first-child { padding-inline-start: var(--e-6); }

.campo__entrada::placeholder { color: var(--texto-tenue); font-weight: var(--peso-texto); }
.campo__entrada:focus { outline: none; }
.campo__entrada:-webkit-autofill {
  -webkit-text-fill-color: var(--texto);
  transition: background-color 9999s ease-out;
}

.campo__accion {
  width: 48px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  color: var(--texto-tenue);
  border-radius: var(--r-full);
}
.campo__accion svg { width: 19px; height: 19px; }

.campo__ayuda {
  display: block;
  font-size: var(--t-micro);
  color: var(--texto-tenue);
  margin-top: var(--e-2);
  padding-inline-start: var(--e-4);
  min-height: 1.2em;
}
.campo__ayuda[data-tono="atencion"] { color: var(--atencion); }
.campo__ayuda[data-tono="logro"] { color: var(--logro); }

/* ==========================================================================
   7. Interruptor
   ========================================================================== */

.interruptor {
  --w: 54px;
  --h: 32px;
  position: relative;
  width: var(--w);
  height: var(--h);
  flex: 0 0 auto;
  border-radius: var(--r-full);
  background: var(--neu-fondo-hundido);
  box-shadow: var(--sombra-neu-hundida);
  transition: background var(--d-media) var(--ease-suave);
}

/* Zona de toque generosa sin agrandar el dibujo: el interruptor mide 54×32
   pero se puede acertar en un rectángulo de 66×50. */
.interruptor::before {
  content: "";
  position: absolute;
  inset: -9px -6px;
  border-radius: var(--r-full);
}

.interruptor::after {
  content: "";
  position: absolute;
  top: 4px;
  left: 4px;
  width: calc(var(--h) - 8px);
  height: calc(var(--h) - 8px);
  border-radius: var(--r-full);
  background: var(--texto-tenue);
  transition:
    transform var(--d-media) var(--ease-elastico),
    background var(--d-media) var(--ease-suave);
}

.interruptor[aria-checked="true"] {
  background-image: linear-gradient(135deg, var(--relleno-hondo-desde), var(--relleno-hondo-hasta));
  box-shadow: inset 0 1px 3px rgb(2 14 15 / 0.35);
}
.interruptor[aria-checked="true"]::after {
  transform: translateX(calc(var(--w) - var(--h)));
  background: var(--verde-100);
}

/* ==========================================================================
   8. Control segmentado
   ========================================================================== */

.segmentado {
  display: flex;
  gap: 4px;
  padding: 5px;
  border-radius: var(--r-full);
  background: var(--neu-fondo-hundido);
  box-shadow: var(--sombra-neu-hundida);
}

.segmentado__opcion {
  flex: 1;
  min-height: 40px;
  padding-inline: var(--e-3);
  border-radius: var(--r-full);
  font-size: var(--t-micro);
  font-weight: var(--peso-texto-fuerte);
  color: var(--texto-tenue);
  transition: color var(--d-rapida) var(--ease-suave), background var(--d-media) var(--ease-suave);
  white-space: nowrap;
}

.segmentado__opcion[aria-selected="true"] {
  background-image: linear-gradient(135deg, var(--relleno-desde), var(--relleno-hasta));
  color: var(--relleno-texto);
  box-shadow: var(--sombra-1);
}

/* ==========================================================================
   9. Navegación inferior
   ========================================================================== */

/*
 * La barra se superpone al contenido; no es una fila del armazón.
 *
 * Cuando ocupaba su propia fila dejaba debajo una franja del color del fondo,
 * y el desenfoque de cristal no tenía nada que desenfocar: se veía una banda
 * lisa. Flotando encima, detrás de la pastilla pasa la app —las tarjetas, el
 * texto, lo que toque— que es lo que da sentido al material.
 *
 * El hueco para que el contenido no se quede debajo lo pone cada pantalla con
 * --hueco-nav, no la barra.
 *
 * Va pegada abajo: el indicador de inicio de iOS vive dentro de los 34 px del
 * área segura, y restarle un poco deja la pastilla cerca del borde sin llegar
 * a pisarlo.
 */
.nav {
  position: absolute;
  left: var(--margen);
  right: var(--margen);
  bottom: var(--nav-abajo);
  z-index: var(--z-nav);
  padding: var(--nav-relleno);
  border-radius: var(--r-full);
  background: var(--cristal-fondo-alto);
  border: 1px solid var(--cristal-borde-alto);
  backdrop-filter: blur(26px) saturate(160%);
  -webkit-backdrop-filter: blur(26px) saturate(160%);
  box-shadow: var(--sombra-3);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 4px;
}

/*
 * La pastilla es un elemento aparte, no el fondo del botón activo.
 *
 * Así puede moverse de forma continua: mientras deslizas entre secciones
 * acompaña al dedo en lugar de saltar de golpe al soltar, y además se puede
 * arrastrar ella sola.
 */
.nav__marca {
  position: absolute;
  top: var(--nav-relleno);
  bottom: var(--nav-relleno);
  left: var(--nav-relleno);
  border-radius: var(--r-full);
  background-image: linear-gradient(135deg, var(--relleno-desde), var(--relleno-hasta));
  box-shadow: 0 4px 14px rgb(var(--verde-300-rgb) / 0.24);
  pointer-events: none;
  z-index: 0;
  will-change: transform;
}

.nav__marca--animada {
  transition: transform 360ms var(--ease-deslizar);
}

.nav__item {
  position: relative;
  z-index: 1;
  min-height: var(--nav-item);
  display: grid;
  place-items: center;
  gap: 3px;
  grid-template-rows: auto auto;
  border-radius: var(--r-full);
  color: var(--texto-tenue);
  transition: color var(--d-rapida) var(--ease-suave);
  touch-action: none;
}

.nav__item svg {
  width: 22px;
  height: 22px;
  transition: transform var(--d-media) var(--ease-elastico);
}

.nav__texto {
  font-size: 10.5px;
  font-weight: var(--peso-texto-fuerte);
  letter-spacing: 0.01em;
  line-height: 1;
}

/* El color lo manda data-cerca, que se actualiza mientras arrastras: el texto
   cambia justo cuando la pastilla llega, no al soltar el dedo. */
.nav__item[data-cerca="si"] { color: var(--relleno-texto); }
.nav__item[data-cerca="si"] svg { transform: translateY(-1px) scale(1.06); }

.nav__item:not([data-cerca="si"]):active { background: var(--acento-tenue); }

/* Puntito de aviso (reto diario pendiente) */
.nav__punto {
  position: absolute;
  top: 9px;
  right: 50%;
  translate: 16px 0;
  width: 7px;
  height: 7px;
  border-radius: var(--r-full);
  background: var(--verde-100);
  box-shadow: 0 0 0 2px rgb(var(--verde-950-rgb) / 0.55);
  animation: latir 2.6s var(--ease-respiro) infinite;
}
.nav__item[data-cerca="si"] .nav__punto {
  background: var(--verde-950);
  box-shadow: none;
}

/* ==========================================================================
   10. Anillo de progreso
   ========================================================================== */

.anillo {
  --tam: 120px;
  --grosor: 9px;
  --valor: 0;
  position: relative;
  width: var(--tam);
  height: var(--tam);
  flex: 0 0 auto;
  display: grid;
  place-items: center;
}

.anillo__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
  overflow: visible;
}

.anillo__pista {
  fill: none;
  stroke: rgb(var(--verde-100-rgb) / 0.09);
  stroke-width: var(--grosor);
  stroke-linecap: round;
}

.anillo__valor {
  fill: none;
  stroke: url(#gradAnillo);
  stroke-width: var(--grosor);
  stroke-linecap: round;
  transition: stroke-dashoffset var(--d-pausada) var(--ease-entrada);
}

.anillo__centro {
  display: grid;
  place-items: center;
  text-align: center;
  line-height: 1.05;
  z-index: 1;
}

.anillo__cifra {
  font-family: var(--f-display);
  font-weight: var(--peso-display);
  font-size: calc(var(--tam) * 0.27);
  letter-spacing: var(--track-titulo);
  font-variant-numeric: tabular-nums;
}

.anillo__pie {
  font-size: var(--t-etiqueta);
  font-weight: var(--peso-texto-fuerte);
  letter-spacing: var(--track-etiqueta);
  text-transform: uppercase;
  color: var(--texto-tenue);
  margin-top: 3px;
}

/* ==========================================================================
   11. Barra de progreso
   ========================================================================== */

.barra {
  --valor: 0;
  position: relative;
  height: 10px;
  width: 100%;
  border-radius: var(--r-full);
  background: rgb(var(--verde-100-rgb) / 0.08);
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgb(2 14 15 / 0.30);
}

.barra__relleno {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: calc(var(--valor) * 1%);
  border-radius: var(--r-full);
  background-image: linear-gradient(90deg, var(--verde-700), var(--verde-300) 62%, var(--verde-100));
  transition: width var(--d-pausada) var(--ease-entrada);
}

.barra--fina { height: 6px; }
.barra--gruesa { height: 14px; }

/* ==========================================================================
   12. Avatar
   ========================================================================== */

.avatar {
  --tam: 46px;
  width: var(--tam);
  height: var(--tam);
  flex: 0 0 auto;
  border-radius: var(--r-full);
  display: grid;
  place-items: center;
  overflow: hidden;
  background-image: linear-gradient(140deg, var(--relleno-hondo-desde), var(--relleno-hondo-hasta));
  color: var(--relleno-texto);
  font-family: var(--f-display);
  /* Tinta oscura sobre degradado claro: ahí los trazos finos de Jost se ven
     todavía más finos, así que las iniciales piden un punto más de cuerpo. */
  font-weight: var(--peso-display-medio);
  font-size: calc(var(--tam) * 0.40);
  letter-spacing: 0;
  box-shadow: var(--sombra-neu-sutil), inset 0 1px 0 rgb(255 255 255 / 0.30);
  user-select: none;
}

.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar--grande { --tam: 96px; }
.avatar--xl { --tam: 118px; }

/* ==========================================================================
   13. Estadística
   ========================================================================== */

.stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.stat__cifra {
  font-family: var(--f-display);
  font-size: var(--t-h2);
  font-weight: var(--peso-display);
  line-height: 1.05;
  letter-spacing: var(--track-titulo);
  font-variant-numeric: tabular-nums;
}

.stat__nombre {
  font-size: var(--t-etiqueta);
  font-weight: var(--peso-texto-fuerte);
  letter-spacing: var(--track-etiqueta);
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.rejilla-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--e-3);
}

/* ==========================================================================
   14. Aviso flotante (toast)
   ========================================================================== */

#avisos {
  position: fixed;
  left: 50%;
  translate: -50% 0;
  top: calc(var(--seguro-arriba) + var(--e-3));
  z-index: var(--z-aviso);
  width: min(calc(100% - var(--margen) * 2), calc(var(--ancho-app) - var(--margen) * 2));
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  pointer-events: none;
}

.aviso {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-4) var(--e-5);
  border-radius: var(--r-full);
  background: var(--cristal-fondo-alto);
  border: 1px solid var(--cristal-borde-alto);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  box-shadow: var(--sombra-3);
  font-size: var(--t-pequeno);
  font-weight: var(--peso-texto-fuerte);
  animation: bajar var(--d-media) var(--ease-entrada) both;
  pointer-events: auto;
}

.aviso[data-saliendo="si"] {
  animation: aparecer var(--d-rapida) var(--ease-salida) reverse both;
}

.aviso__icono {
  width: 26px;
  height: 26px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: var(--r-full);
  background: var(--acento-tenue);
  color: var(--acento);
}
.aviso__icono svg { width: 15px; height: 15px; }

/* ==========================================================================
   15. Hoja inferior (bottom sheet)
   ========================================================================== */

.velo {
  position: fixed;
  inset: 0;
  z-index: var(--z-hoja);
  background: rgb(var(--verde-950-rgb) / 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: aparecer var(--d-media) var(--ease-suave) both;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
[data-tema="claro"] .velo { background: rgb(var(--verde-700-rgb) / 0.38); }

.velo[data-saliendo="si"] { animation-direction: reverse; }

.hoja {
  width: 100%;
  max-width: var(--ancho-app);
  max-height: 88dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: var(--r-3xl) var(--r-3xl) 0 0;
  background: var(--cristal-fondo-alto);
  border: 1px solid var(--cristal-borde-alto);
  border-bottom: none;
  backdrop-filter: blur(30px) saturate(170%);
  -webkit-backdrop-filter: blur(30px) saturate(170%);
  box-shadow: var(--sombra-flotante);
  padding: var(--e-4) var(--margen) calc(var(--seguro-abajo) + var(--e-7));
  animation: hoja-entra var(--d-lenta) var(--ease-entrada) both;
}
.velo[data-saliendo="si"] .hoja {
  animation: hoja-entra var(--d-media) var(--ease-salida) reverse both;
}

@media (min-width: 620px) {
  .velo { align-items: center; }
  .hoja {
    border-radius: var(--r-3xl);
    border-bottom: 1px solid var(--cristal-borde-alto);
    margin-inline: var(--margen);
    padding-bottom: var(--e-7);
    animation-name: brotar;
  }
}

.hoja__asa {
  width: 42px;
  height: 5px;
  border-radius: var(--r-full);
  background: rgb(var(--verde-100-rgb) / 0.22);
  margin: 0 auto var(--e-5);
}

.hoja__titulo {
  font-family: var(--f-display);
  font-size: var(--t-h2);
  font-weight: var(--peso-display-medio);
  letter-spacing: var(--track-titulo);
  margin-bottom: var(--e-2);
}

/* ==========================================================================
   16. Pantalla de carga
   ========================================================================== */

#cargando {
  position: fixed;
  inset: 0;
  z-index: var(--z-carga);
  display: grid;
  place-items: center;
  background: var(--bg-base);
  transition: opacity var(--d-lenta) var(--ease-suave), visibility var(--d-lenta);
}

#cargando[hidden] {
  opacity: 0;
  visibility: hidden;
  display: grid; /* mantiene el fundido; [hidden] no debe cortarlo en seco */
  pointer-events: none;
}

.cargador {
  width: 46px;
  height: 46px;
  border-radius: var(--r-full);
  border: 3px solid rgb(var(--verde-300-rgb) / 0.18);
  border-top-color: var(--verde-300);
  animation: girar 0.85s linear infinite;
}

/* ==========================================================================
   17. Estado vacío
   ========================================================================== */

.vacio {
  display: grid;
  place-items: center;
  gap: var(--e-4);
  text-align: center;
  padding: var(--e-9) var(--e-5);
  color: var(--texto-tenue);
}

.vacio__icono {
  width: 76px;
  height: 76px;
  display: grid;
  place-items: center;
  border-radius: var(--r-full);
  background: var(--cristal-fondo);
  border: 1px solid var(--cristal-borde);
  color: var(--acento);
}
.vacio__icono svg { width: 32px; height: 32px; }

/* ==========================================================================
   18. Separador
   ========================================================================== */

.separador {
  height: 1px;
  border: none;
  background: linear-gradient(90deg, transparent, rgb(var(--verde-100-rgb) / 0.13), transparent);
  margin-block: var(--e-6);
}

.separador-texto {
  display: flex;
  align-items: center;
  gap: var(--e-4);
  color: var(--texto-tenue);
  font-size: var(--t-micro);
  font-weight: var(--peso-texto-fuerte);
  margin-block: var(--e-6);
}
.separador-texto::before,
.separador-texto::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(var(--verde-100-rgb) / 0.15), transparent);
}

/* ==========================================================================
   19. Bloques de sección
   ========================================================================== */

.seccion { margin-block: var(--e-7); }

.seccion__cabecera {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
  margin-bottom: var(--e-4);
}

.seccion__titulo {
  font-family: var(--f-display);
  font-size: var(--t-h3);
  font-weight: var(--peso-display-medio);
  letter-spacing: var(--track-titulo);
}

.seccion__enlace {
  font-size: var(--t-micro);
  font-weight: var(--peso-texto-fuerte);
  color: var(--acento);
  flex: 0 0 auto;
  /* El texto es pequeño a propósito, pero el área que se toca no debe serlo:
     44 px es el mínimo cómodo para un pulgar */
  padding: 12px 14px;
  margin: -12px -14px;
  border-radius: var(--r-full);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.seccion__enlace:active { background: var(--acento-tenue); }

/* Carrusel horizontal con scroll suave y anclaje */
.carrusel {
  display: flex;
  gap: var(--e-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--margen);
  padding-inline: var(--margen);
  padding-block: var(--e-1) var(--e-3);
  margin-inline: calc(var(--margen) * -1);
  scrollbar-width: none;
}
.carrusel::-webkit-scrollbar { display: none; }
.carrusel > * { scroll-snap-align: start; flex: 0 0 auto; }
