/* ============================================================
   LAYOUT · estructura, cabecera, el cajón y la navegación
   Sistema "CÉDULA OFICIAL" (v2.0)
   Mobile-first: se escribe primero el teléfono y se amplía.
   ============================================================ */

/* ============================================================
   0 · EL HILO DE SEGURIDAD
   La cinta tricolor de 3px que cruza el borde superior de cada
   superficie fija (cabecera, cajón, dock). Es lo que ata todas
   las pantallas: si lo ves, estás en el juego.

   El brillo que lo recorre es MUY lento a propósito (9s): tiene
   que registrarse de refilón, no llamar la atención mientras se
   juega. Es el reflejo de un billete al inclinarlo, no un LED.
   ============================================================ */
.hilo-seguridad {
  position: relative;
  height: 3px;
  background: var(--hilo);
  overflow: hidden;
  flex-shrink: 0;
}
.hilo-seguridad::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.85), transparent);
  transform: translateX(-100%);
  animation: hilo-brilla 9s var(--ease) infinite;
}
@keyframes hilo-brilla {
  0%, 72%  { transform: translateX(-100%); }
  100%     { transform: translateX(100%); }
}

/* ============================================================
   1 · VISTAS DE ENTRADA (login / nueva partida)
   La caja es una cédula: troquelada, con el hilo arriba y la
   marca de agua del escudo detrás.
   ============================================================ */
#vista-login, #vista-nueva {
  min-height: 100dvh;
  position: relative;
  display: flex; align-items: center; justify-content: center;
  padding: var(--e-4);
  padding-block: max(var(--e-5), env(safe-area-inset-top)) max(var(--e-5), env(safe-area-inset-bottom));
  overflow: hidden;
}
.fondo-ilustrado {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  /* Cuando el fondo es un SVG inline, el recorte lo hace su propio
     preserveAspectRatio="slice". Cuando ya es una ilustración raster (un
     <img>), sin esto se estira: object-fit hace el mismo recorte centrado
     y el SVG lo ignora, así que sirve para los dos casos. */
  object-fit: cover;
  object-position: center;
  color: var(--tinta-3);
  opacity: .32;
  pointer-events: none;
  z-index: 0;
  /* Respira muy despacio, como una foto proyectada. 60 segundos:
     no se percibe como animación, se percibe como que está vivo. */
  animation: fondo-respira 60s ease-in-out infinite alternate;
}
@keyframes fondo-respira {
  from { transform: scale(1); }
  to   { transform: scale(1.06); }
}

.caja-entrada {
  position: relative; z-index: 1;
  width: 100%; max-width: 448px;
  background: var(--superficie);
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--r-md);
  padding: var(--e-5);
  padding-top: var(--e-6);
  box-shadow: var(--sombra-3);
  text-align: center;
  animation: cedula-entra var(--vel-lenta) var(--ease-sello) both;
  overflow: hidden;
}
/* El hilo de seguridad sobre el borde superior de la cédula */
.caja-entrada::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 4px;
  background: var(--hilo);
}
/* Marca de agua: el número de serie del documento, como en un
   billete. Decorativo puro, por eso va en un pseudo-elemento y
   no en el DOM (un lector de pantalla no tiene nada que hacer
   con él). */
.caja-entrada::after {
  content: 'SERIE PY · 001';
  position: absolute; bottom: 9px; right: 12px;
  font-family: var(--f-dato);
  font-size: 9px; letter-spacing: .16em;
  color: var(--tinta-3); opacity: .5;
  pointer-events: none;
}
@keyframes cedula-entra {
  from { opacity: 0; transform: translateY(22px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

.caja-entrada .logotipo {
  width: 100%; max-width: 310px; height: auto;
  margin: 0 auto var(--e-3);
  color: var(--tinta);
}
.caja-entrada .lema {
  font-family: var(--f-titulo); font-style: italic;
  color: var(--py-oro); font-size: var(--t-sm);
  letter-spacing: .02em;
  margin-bottom: var(--e-5);
}
#banner-premios {
  display: block; text-align: center; text-decoration: none;
  position: relative; overflow: hidden;
  background: var(--foil-oro);
  color: #2a1c02; font-weight: 800; font-size: var(--t-sm);
  font-family: var(--f-titulo); letter-spacing: .04em;
  padding: var(--e-3); border-radius: var(--r-sm);
  margin: calc(var(--e-5) * -1) 0 var(--e-4);
  box-shadow: var(--sombra-1);
  transition: transform var(--vel-rapida) var(--ease), box-shadow var(--vel-rapida) var(--ease);
}
/* Acá el foil SÍ corre en bucle: es un premio en guaraníes, y el
   brillo es exactamente el argumento. Es un solo elemento por
   pantalla, así que no compite con nada. */
#banner-premios::after {
  content: '';
  position: absolute; inset: 0;
  background: var(--foil);
  transform: translateX(-100%);
  animation: banner-foil 4.5s var(--ease) infinite;
}
@keyframes banner-foil {
  0%, 55% { transform: translateX(-100%); }
  100%    { transform: translateX(100%); }
}
#banner-premios:hover { transform: translateY(-2px); box-shadow: var(--sombra-2); }
#banner-premios strong { font-family: var(--f-dato); }

.caja-entrada form { text-align: left; }
.caja-entrada .campo { margin-bottom: var(--e-3); }
.caja-entrada .etiqueta { margin-top: var(--e-4); }

/* Toggle de tema flotante en las pantallas de entrada */
.tema-flotante { position: absolute; top: var(--e-2); right: var(--e-2); z-index: 2; }

/* Enlace sutil (aviso legal) */
.enlace-sutil {
  display: block; width: 100%;
  min-height: var(--tap);
  margin-top: var(--e-2);
  font-size: var(--t-sm);
  color: var(--tinta-3);
  text-decoration: underline;
  text-underline-offset: 3px;
  background: none; border: none;
}
.enlace-sutil:hover { color: var(--tinta); }

/* Tabs tipo segmento (login / registro) · pestañas de carpeta */
.tabs-segmento {
  display: flex; gap: 3px;
  background: var(--superficie-3);
  border: 1px solid var(--borde);
  border-radius: var(--r-md);
  padding: 3px;
  margin-bottom: var(--e-4);
}
.tabs-segmento button {
  position: relative;
  flex: 1; min-height: var(--tap);
  border-radius: var(--r-sm);
  font-family: var(--f-titulo);
  font-size: var(--t-sm); font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--tinta-2);
  transition: background var(--vel-rapida) var(--ease), color var(--vel-rapida) var(--ease);
}
.tabs-segmento button:hover { color: var(--tinta); }
.tabs-segmento button.activo {
  background: var(--superficie); color: var(--tinta);
  box-shadow: var(--sombra-1);
}
.tabs-segmento button.activo::after {
  content: '';
  position: absolute; left: 12px; right: 12px; bottom: 4px; height: 2px;
  background: var(--hilo);
  animation: subrayado-crece var(--vel-media) var(--ease) both;
}
@keyframes subrayado-crece {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* Fila doble (título + nombre) */
.fila-doble { display: grid; grid-template-columns: minmax(96px, .38fr) 1fr; gap: var(--e-2); }

/* ============================================================
   2 · CABECERA · la barra de mando
   Vidrio sobre el guilloche: el fondo se sigue viendo detrás,
   apenas desenfocado, así que la trama no se corta en dos.
   ============================================================ */
#cabecera {
  position: sticky; top: 0; z-index: var(--z-sticky);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e-3);
  padding: var(--e-2) var(--e-3);
  padding-top: max(var(--e-2), env(safe-area-inset-top));
  background: color-mix(in srgb, var(--superficie) 88%, transparent);
  backdrop-filter: blur(10px) saturate(1.1);
  border-bottom: 1px solid var(--borde-fuerte);
  box-shadow: var(--sombra-1);
}
/* El hilo de seguridad, arriba de todo */
#cabecera::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--hilo);
}

/* La marca NUNCA puede desaparecer.
   El bug que esto arregla: .cab-acciones tenía flex-shrink:0 (no cedía ni un
   píxel) y .cab-marca solo min-width:0 (cedía hasta 0). En un teléfono de
   390px los controles pedían 416px, así que la marca colapsaba a ancho CERO
   y el título se dibujaba por encima de los íconos. Con un ancho mínimo
   propio, la marca se queda con su lugar. Desde v2.0 además sobra aire,
   porque los íconos sueltos se mudaron al cajón. */
.cab-marca { display: flex; align-items: center; gap: var(--e-2); min-width: 0; flex: 1 1 auto; }
.cab-marca img, .cab-marca svg {
  width: 36px; height: 36px; flex-shrink: 0;
  transition: transform var(--vel-media) var(--ease-sello);
}
.cab-marca:hover img { transform: rotate(-7deg) scale(1.07); }
.cab-textos { min-width: 0; }
.cab-titulo {
  /* display:block NO es cosmético: el título es un <span>, o sea inline, y en
     un elemento inline el overflow:hidden y el text-overflow:ellipsis de acá
     abajo simplemente NO se aplican. */
  display: block;
  font-family: var(--f-titulo); font-weight: 700;
  font-size: var(--t-sm); line-height: 1.1;
  letter-spacing: .08em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cab-titulo em { color: var(--py-oro); font-style: normal; }
.cab-fecha {
  font-family: var(--f-dato);
  font-size: var(--t-xs); color: var(--tinta-2);
  letter-spacing: .04em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: block;
}
.cab-acciones { display: flex; align-items: center; gap: var(--e-1); flex-shrink: 0; }

/* Chip de usuario */
.cab-usuario {
  display: flex; align-items: center; gap: var(--e-2);
  min-height: var(--tap);
  padding: var(--e-1) var(--e-2);
  background: transparent;
  border: 1px solid var(--borde); border-radius: var(--r-md);
  color: var(--tinta);
  max-width: 190px;
  transition: background var(--vel-rapida) var(--ease), border-color var(--vel-rapida) var(--ease);
}
.cab-usuario:hover { background: var(--superficie-2); border-color: var(--borde-fuerte); }
.cab-usuario img { width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0; border: 1.5px solid var(--py-oro); }
.cab-usuario-txt { min-width: 0; text-align: left; }
.cab-usuario small {
  display: block; font-family: var(--f-titulo);
  font-size: 10px; color: var(--tinta-3); line-height: 1.1;
  text-transform: uppercase; letter-spacing: .08em;
}
.cab-usuario strong {
  display: block; font-size: var(--t-sm); line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* En teléfono el nombre se va: el avatar alcanza para identificarse
   y el ancho hace falta para la marca. */
@media (max-width: 599px) {
  .cab-usuario-txt { display: none; }
  .cab-usuario { padding: var(--e-1); }
}

/* ============================================================
   3 · EL CAJÓN · el menú nuevo
   ------------------------------------------------------------
   Antes había seis íconos sueltos apretados en la cabecera, y en
   un teléfono de 390px no entraban: la solución vieja era
   esconder la mitad y confiar en que el jugador los encontrara en
   otro lado. Ahora hay UN botón, y adentro está todo el sitio
   agrupado y con nombre.

   Entra deslizándose desde la derecha; los grupos aparecen
   escalonados detrás de él, así el ojo los lee en orden en vez de
   recibir doce enlaces de golpe.
   ============================================================ */
#btn-cajon {
  position: relative;
  display: inline-flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 4px;
  width: var(--tap); height: var(--tap);
  border-radius: var(--r-md);
  border: 1px solid var(--borde);
  background: var(--superficie-2);
  color: var(--tinta);
  transition: background var(--vel-rapida) var(--ease), border-color var(--vel-rapida) var(--ease), transform var(--vel-rapida) var(--ease);
}
#btn-cajon:hover { background: var(--superficie-3); border-color: var(--borde-fuerte); }
#btn-cajon:active { transform: translateY(1px); box-shadow: var(--sombra-hundida); }
/* Las tres barras se dibujan en CSS: son tres divs de 2px que al
   abrir el cajón se convierten en una X. */
#btn-cajon i {
  display: block; width: 18px; height: 2px;
  background: currentColor; border-radius: 2px;
  transition: transform var(--vel-media) var(--ease), opacity var(--vel-rapida) var(--ease);
}
#btn-cajon i:nth-child(2) { width: 13px; margin-right: 5px; }
body.cajon-abierto #btn-cajon i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
body.cajon-abierto #btn-cajon i:nth-child(2) { opacity: 0; }
body.cajon-abierto #btn-cajon i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Globito de no leídos sobre el botón del cajón: si los mensajes
   viven adentro, el aviso tiene que verse desde afuera.

   Se espeja del contador que app.js ya mantiene (#badge-mensajes,
   que ahora vive dentro del cajón) con :has, en vez de agregarle
   al JS del juego otro elemento que actualizar. Una sola fuente
   de verdad: si el contador está visible, el punto está visible. */
#btn-cajon .punto-aviso {
  display: none;
  position: absolute; top: 4px; right: 4px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--acento);
  box-shadow: 0 0 0 2px var(--superficie);
  animation: latido 2s ease-in-out infinite;
}
body:has(#badge-mensajes:not(.oculto)) #btn-cajon .punto-aviso { display: block; }

/* El rótulo "Administración" sigue al enlace de admin: app.js le
   saca .oculto solo cuando el usuario tiene rol admin, y el título
   del grupo no tiene por qué aparecer solo. */
#grupo-admin { display: none; }
.cajon-cuerpo:has(#btn-panel-admin:not(.oculto)) #grupo-admin { display: flex; }
@keyframes latido {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.35); opacity: .75; }
}

#cajon-fondo {
  position: fixed; inset: 0; z-index: calc(var(--z-cajon) - 1);
  background: rgba(6, 9, 15, .6);
  backdrop-filter: blur(3px);
  opacity: 0; visibility: hidden;
  transition: opacity var(--vel-media) var(--ease), visibility var(--vel-media);
}
body.cajon-abierto #cajon-fondo { opacity: 1; visibility: visible; }

#cajon {
  position: fixed; top: 0; right: 0; bottom: 0;
  z-index: var(--z-cajon);
  width: min(370px, 88vw);
  display: flex; flex-direction: column;
  background: var(--superficie);
  background-image: var(--textura-papel);
  background-size: var(--trama-escala);
  border-left: 1px solid var(--borde-fuerte);
  box-shadow: var(--sombra-modal);
  transform: translateX(102%);
  visibility: hidden;
  transition: transform var(--vel-media) var(--ease), visibility var(--vel-media);
  overscroll-behavior: contain;
}
body.cajon-abierto #cajon { transform: none; visibility: visible; }
/* El hilo de seguridad, esta vez vertical, sobre el canto izquierdo */
#cajon::before {
  content: '';
  position: absolute; top: 0; left: 0; bottom: 0; width: 3px;
  background: var(--hilo-v);
}

.cajon-cab {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e-3);
  padding: var(--e-4);
  padding-top: max(var(--e-4), env(safe-area-inset-top));
  border-bottom: 1px solid var(--borde);
  flex-shrink: 0;
}
.cajon-marca { display: flex; align-items: center; gap: var(--e-2); min-width: 0; }
.cajon-marca img { width: 34px; height: 34px; flex-shrink: 0; }
.cajon-marca strong {
  display: block; font-family: var(--f-titulo);
  font-size: var(--t-sm); text-transform: uppercase; letter-spacing: .07em;
  line-height: 1.15;
}
.cajon-marca small {
  display: block; font-family: var(--f-dato);
  font-size: 10px; color: var(--tinta-3); letter-spacing: .1em;
}

.cajon-cuerpo {
  flex: 1; overflow-y: auto;
  padding: var(--e-3) var(--e-3) var(--e-5);
  padding-bottom: max(var(--e-5), env(safe-area-inset-bottom));
}

.cajon-grupo {
  font-family: var(--f-titulo);
  font-size: var(--t-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: var(--track-etiqueta);
  color: var(--tinta-3);
  padding: var(--e-4) var(--e-2) var(--e-2);
  display: flex; align-items: center; gap: var(--e-2);
}
.cajon-grupo::after { content: ''; flex: 1; height: 1px; background: var(--borde); }

.cajon-item {
  position: relative;
  display: flex; align-items: center; gap: var(--e-3);
  width: 100%;
  min-height: 48px;
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-md);
  border: 1px solid transparent;
  color: var(--tinta);
  text-decoration: none;
  font-size: var(--t-sm); font-weight: 600;
  text-align: left;
  transition: background var(--vel-rapida) var(--ease),
              border-color var(--vel-rapida) var(--ease),
              transform var(--vel-rapida) var(--ease),
              padding-left var(--vel-rapida) var(--ease);
}
.cajon-item:hover {
  background: var(--superficie-2);
  border-color: var(--borde);
  padding-left: calc(var(--e-3) + 4px);
}
.cajon-item:active { transform: translateX(2px) scale(.99); }
/* El filete que aparece al costado al pasar por encima: el mismo
   gesto del clasificador de las tarjetas. */
.cajon-item::before {
  content: '';
  position: absolute; left: 0; top: 8px; bottom: 8px; width: 3px;
  border-radius: 3px;
  background: var(--py-oro);
  transform: scaleY(0);
  transition: transform var(--vel-rapida) var(--ease);
}
.cajon-item:hover::before, .cajon-item.actual::before { transform: scaleY(1); }
.cajon-item.actual {
  background: var(--superficie-2);
  border-color: var(--borde);
  color: var(--tinta);
}
.cajon-ico {
  width: 34px; height: 34px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm);
  background: var(--superficie-3);
  color: var(--py-oro);
  font-size: 16px;
  transition: background var(--vel-rapida) var(--ease), transform var(--vel-media) var(--ease-sello);
}
.cajon-item:hover .cajon-ico { background: var(--alerta-suave); transform: rotate(-6deg) scale(1.07); }
.cajon-ico svg { width: 18px; height: 18px; }
.cajon-txt { min-width: 0; flex: 1; }
.cajon-txt small {
  display: block; font-size: var(--t-xs); font-weight: 500;
  color: var(--tinta-3); line-height: 1.25;
}
.cajon-item .badge-cajon {
  flex-shrink: 0;
  background: var(--acento); color: var(--acento-txt);
  font-family: var(--f-dato);
  font-size: 10px; font-weight: 800;
  border-radius: var(--r-full);
  min-width: 19px; height: 19px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 5px;
}
.cajon-item.peligrosa { color: var(--peligro); }
.cajon-item.peligrosa .cajon-ico { color: var(--peligro); }

/* Entrada escalonada de los grupos. Se dispara solo cuando el
   cajón está abierto, así que no cuesta nada mientras está
   cerrado. */
body.cajon-abierto .cajon-cuerpo > * {
  animation: cajon-item-entra var(--vel-media) var(--ease) both;
}
body.cajon-abierto .cajon-cuerpo > *:nth-child(1)  { animation-delay: .04s; }
body.cajon-abierto .cajon-cuerpo > *:nth-child(2)  { animation-delay: .06s; }
body.cajon-abierto .cajon-cuerpo > *:nth-child(3)  { animation-delay: .08s; }
body.cajon-abierto .cajon-cuerpo > *:nth-child(4)  { animation-delay: .10s; }
body.cajon-abierto .cajon-cuerpo > *:nth-child(5)  { animation-delay: .12s; }
body.cajon-abierto .cajon-cuerpo > *:nth-child(6)  { animation-delay: .14s; }
body.cajon-abierto .cajon-cuerpo > *:nth-child(7)  { animation-delay: .16s; }
body.cajon-abierto .cajon-cuerpo > *:nth-child(8)  { animation-delay: .18s; }
body.cajon-abierto .cajon-cuerpo > *:nth-child(9)  { animation-delay: .20s; }
body.cajon-abierto .cajon-cuerpo > *:nth-child(n+10) { animation-delay: .22s; }
@keyframes cajon-item-entra {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: none; }
}

.cajon-pie {
  flex-shrink: 0;
  padding: var(--e-3) var(--e-4);
  padding-bottom: max(var(--e-3), env(safe-area-inset-bottom));
  border-top: 1px solid var(--borde);
  display: flex; align-items: center; justify-content: space-between; gap: var(--e-2);
  font-size: var(--t-xs); color: var(--tinta-3);
}
.cajon-pie .cajon-controles { display: flex; gap: var(--e-1); }

/* Mientras el cajón está abierto el fondo no scrollea */
body.cajon-abierto { overflow: hidden; }

/* ============================================================
   4 · TICKER · sin top hardcodeado (era un bug del 1.x)
   Sigue en serif: es la voz de la prensa, no la del Estado.
   ============================================================ */
#ticker {
  position: sticky; top: var(--alto-cabecera); z-index: calc(var(--z-sticky) - 1);
  overflow: hidden;
  background: var(--tinta);
  color: var(--fondo);
  height: var(--alto-ticker);
  display: flex; align-items: center;
  border-bottom: 1px solid var(--borde-fuerte);
}
#ticker-texto {
  white-space: nowrap;
  font-family: var(--f-serif);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .015em;
  padding-left: 100%;
  animation: ticker 42s linear infinite;
}
#ticker:hover #ticker-texto { animation-play-state: paused; }
.tk-item { display: inline-flex; align-items: center; gap: 5px; vertical-align: middle; }
.tk-ico { flex-shrink: 0; opacity: .85; }
.tk-sep { display: inline-block; margin: 0 14px; opacity: .5; }
@keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-100%); } }

/* ============================================================
   5 · FRANJA DE INDICADORES · las casillas del formulario
   Cada indicador es una casilla numerada de una planilla oficial.
   ============================================================ */
#franja-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
  gap: var(--e-2);
  padding: var(--e-3);
  background: color-mix(in srgb, var(--fondo-alt) 85%, transparent);
  border-bottom: 1px solid var(--borde);
}
.stat {
  position: relative;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--r-sm);
  padding: var(--e-2);
  text-align: center;
  overflow: hidden;
  transition: background var(--vel-media) var(--ease),
              border-color var(--vel-rapida) var(--ease),
              transform var(--vel-rapida) var(--ease);
}
.stat:hover { transform: translateY(-2px); border-color: var(--borde-fuerte); }
/* Filete de estado sobre el borde superior de la casilla */
.stat::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: var(--borde);
  transition: background var(--vel-media) var(--ease);
}
.stat .s-nom {
  display: flex; align-items: center; justify-content: center; gap: 3px;
  font-family: var(--f-titulo);
  font-size: var(--t-xs);
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--tinta-2);
  line-height: 1.2;
  margin-bottom: 2px;
}
.ico-stat { width: 13px; height: 13px; flex-shrink: 0; }
.stat .s-val {
  display: block;
  font-family: var(--f-dato);
  font-size: var(--t-md);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.stat.peligro { border-color: var(--peligro); }
.stat.peligro::before { background: var(--peligro); }
.stat.peligro .s-val { color: var(--peligro); }
.stat.alerta::before { background: var(--alerta); }
.stat.alerta .s-val { color: var(--alerta); }
.stat.bien::before { background: var(--ok); }
.stat.bien .s-val { color: var(--ok); }
.stat.flash-mal { animation: flash-mal 1s var(--ease); }
.stat.flash-bien { animation: flash-bien 1s var(--ease); }
@keyframes flash-mal { 0% { background: var(--peligro); } 100% { background: var(--superficie); } }
@keyframes flash-bien { 0% { background: var(--ok); } 100% { background: var(--superficie); } }

/* ============================================================
   6 · BANNER DE PUBLICIDAD · imagen fija, sin rastreo de terceros
   ============================================================ */
#banner-anuncio {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  background: var(--superficie); border-bottom: 1px solid var(--borde);
  padding: 6px;
}
#banner-anuncio a, #banner-anuncio .anuncio-sin-link { display: block; max-width: 100%; line-height: 0; }
#banner-anuncio img { max-width: 100%; max-height: 72px; width: auto; height: auto; border-radius: var(--r-sm); }
#banner-anuncio::before {
  content: 'Publicidad'; position: absolute; top: 2px; left: 8px;
  font-family: var(--f-titulo);
  font-size: 9px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--tinta-3); background: var(--superficie); padding: 0 4px;
}

/* ============================================================
   7 · EL DOCK · las 9 pestañas del juego
   ------------------------------------------------------------
   En móvil es una barra inferior con scroll horizontal. La
   pestaña activa se levanta sobre una placa con el hilo tricolor
   arriba, y el subrayado se DIBUJA de adentro hacia afuera en
   lugar de aparecer de golpe: eso es lo que hace legible cuál se
   acaba de tocar cuando el pulgar tapa media barra.
   ============================================================ */
#pestanas {
  position: fixed; bottom: 0; left: 0; right: 0;
  z-index: var(--z-nav);
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  background: color-mix(in srgb, var(--superficie) 92%, transparent);
  backdrop-filter: blur(12px) saturate(1.1);
  border-top: 1px solid var(--borde-fuerte);
  padding-bottom: env(safe-area-inset-bottom);
  box-shadow: 0 -3px 18px rgba(0,0,0,.14);
  scrollbar-width: none;
}
#pestanas::-webkit-scrollbar { display: none; }

/* Aviso de que la barra sigue: son 9 pestañas y en un teléfono
   entran 5. El degradado del borde derecho es la señal de "hay
   más acá"; sin él, la última quedaba cortada al medio de la
   palabra y parecía un error de maquetación. */
#pestanas-envoltorio { position: relative; }
#pestanas::after {
  content: '';
  position: fixed; bottom: 0; right: 0;
  width: 34px; height: var(--alto-nav);
  pointer-events: none;
  z-index: 1;
  background: linear-gradient(90deg, transparent, var(--superficie) 78%);
}
@media (min-width: 640px) {
  #pestanas::after { display: none; }
}

#pestanas button {
  position: relative;
  flex: 0 0 auto;
  scroll-snap-align: center;
  min-width: 70px;
  min-height: var(--alto-nav);
  padding: var(--e-2) var(--e-2) calc(var(--e-2) + 2px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px;
  color: var(--tinta-3);
  background: transparent;
  transition: color var(--vel-rapida) var(--ease), background var(--vel-rapida) var(--ease);
}
/* El hilo tricolor de la pestaña activa, arriba de la placa */
#pestanas button::before {
  content: '';
  position: absolute; top: 0; left: 8px; right: 8px; height: 3px;
  background: var(--hilo);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--vel-media) var(--ease);
}
.ico-tab {
  width: 22px; height: 22px; flex-shrink: 0;
  transition: transform var(--vel-media) var(--ease-sello);
}
#pestanas button span {
  font-family: var(--f-titulo);
  font-size: var(--t-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  line-height: 1;
}
#pestanas button:hover { color: var(--tinta-2); background: var(--superficie-2); }
#pestanas button:hover .ico-tab { transform: translateY(-2px); }
#pestanas button.activo {
  color: var(--acento);
  background: var(--superficie-2);
}
#pestanas button.activo::before { transform: scaleX(1); }
#pestanas button.activo .ico-tab { transform: translateY(-2px) scale(1.1); }

/* ============================================================
   8 · CONTENIDO
   ============================================================ */
#contenido {
  position: relative;
  max-width: var(--ancho-max);
  margin: 0 auto;
  padding: var(--e-4) var(--e-3);
  /* espacio para el dock inferior + el botón flotante de fin de mes */
  padding-bottom: calc(var(--alto-nav) + 90px + env(safe-area-inset-bottom));
}

/* El panel entra como una hoja que se apoya: sube 10px y se
   asienta. Corto (260ms) porque se dispara en CADA cambio de
   pestaña y una animación lenta acá se vuelve un peaje. */
.panel { animation: panel-entra var(--vel-media) var(--ease); }
@keyframes panel-entra {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================
   9 · GRILLAS REUTILIZABLES · siempre con minmax (nunca se aplastan)
   ============================================================ */
.grid-auto  { display: grid; gap: var(--e-3); grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.grid-2     { display: grid; gap: var(--e-3); grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); }
.grid-mini  { display: grid; gap: var(--e-2); grid-template-columns: repeat(auto-fit, minmax(min(100%, 110px), 1fr)); }
.dos-columnas { display: grid; gap: var(--e-4); grid-template-columns: 1fr; align-items: start; }

/* ============================================================
   10 · BOTÓN FIN DE MES · el sello grande del mes
   ============================================================ */
.btn-finmes {
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--alto-nav) + var(--e-3) + env(safe-area-inset-bottom));
  z-index: var(--z-flotante);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--e-2);
  min-height: 52px;
  padding: var(--e-3) var(--e-6);
  font-family: var(--f-titulo);
  font-size: var(--t-md); font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase;
  background: var(--foil-rojo);
  color: #fff;
  border: 1px solid rgba(0,0,0,.3);
  border-radius: var(--r-md);
  box-shadow: 0 3px 0 var(--py-rojo-osc), 0 10px 30px rgba(200, 36, 26, .4);
  text-shadow: 0 1px 0 rgba(0,0,0,.35);
  white-space: nowrap;
  overflow: hidden;
  transition: transform var(--vel-rapida) var(--ease), box-shadow var(--vel-rapida) var(--ease), opacity var(--vel-rapida) var(--ease);
}
/* Late muy despacio para decir "te toca a vos" sin apurar a nadie */
.btn-finmes:not(:disabled) { animation: finmes-late 3.6s var(--ease) infinite; }
@keyframes finmes-late {
  0%, 88%, 100% { box-shadow: 0 3px 0 var(--py-rojo-osc), 0 10px 30px rgba(200, 36, 26, .4); }
  94%           { box-shadow: 0 3px 0 var(--py-rojo-osc), 0 10px 38px rgba(200, 36, 26, .72); }
}
.btn-finmes:hover:not(:disabled) { transform: translateX(-50%) translateY(-2px); }
.btn-finmes:active:not(:disabled) {
  transform: translateX(-50%) translateY(2px);
  box-shadow: 0 0 0 var(--py-rojo-osc), var(--sombra-hundida);
}
.btn-finmes:disabled { opacity: .45; box-shadow: none; animation: none; }

/* Botón flotante de reportar bug */
#btn-bug-flotante {
  position: fixed;
  left: var(--e-3);
  bottom: calc(var(--alto-nav) + var(--e-3) + env(safe-area-inset-bottom));
  z-index: var(--z-flotante);
  min-height: 40px;
  padding: var(--e-2) var(--e-3);
  font-family: var(--f-titulo);
  font-size: var(--t-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  background: var(--superficie); color: var(--tinta-2);
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--r-md);
  box-shadow: var(--sombra-2);
}
#btn-bug-flotante:hover { color: var(--tinta); border-color: var(--tinta-3); }

/* En teléfono los dos flotantes chocan: "Terminar el mes" está centrado y
   crece hasta ocupar casi todo el ancho, así que se monta sobre el de
   reportar bug, que vive abajo a la izquierda con el MISMO bottom. */
@media (max-width: 600px) {
  #btn-bug-flotante {
    bottom: calc(var(--alto-nav) + 52px + var(--e-3) + var(--e-2) + env(safe-area-inset-bottom));
  }
}

/* ============================================================
   11 · AVISO DE COOKIES
   ============================================================ */
#aviso-cookies {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: var(--z-toast);
  display: flex; align-items: center; justify-content: center;
  gap: var(--e-3); flex-wrap: wrap;
  padding: var(--e-4);
  padding-bottom: max(var(--e-4), env(safe-area-inset-bottom));
  background: var(--superficie);
  border-top: 3px solid transparent;
  border-image: var(--hilo) 1;
  box-shadow: 0 -6px 24px rgba(0,0,0,.24);
  animation: cookies-sube var(--vel-lenta) var(--ease) both;
}
@keyframes cookies-sube { from { transform: translateY(100%); } to { transform: none; } }
#aviso-cookies p { max-width: 60ch; font-size: var(--t-sm); color: var(--tinta-2); margin: 0; }

/* ============================================================
   12 · CAPA DE EFECTOS
   ============================================================ */
#capa-fx { position: fixed; inset: 0; pointer-events: none; z-index: var(--z-fx); overflow: hidden; }
.fx-caida { position: absolute; top: -40px; font-size: 26px; animation: caer linear forwards; }
@keyframes caer {
  0%   { transform: translateY(0) rotate(0); opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateY(110vh) rotate(340deg); opacity: 0; }
}
#vista-app.shake-fuerte { animation: shake-fuerte .55s cubic-bezier(.36,.07,.19,.97); }
@keyframes shake-fuerte {
  0%,100% { transform: translate(0,0); }
  10% { transform: translate(-8px,3px); } 20% { transform: translate(9px,-3px); }
  30% { transform: translate(-10px,2px); } 40% { transform: translate(10px,-2px); }
  50% { transform: translate(-7px,3px); } 60% { transform: translate(7px,-3px); }
  70% { transform: translate(-5px,2px); } 80% { transform: translate(5px,-2px); }
  90% { transform: translate(-2px,1px); }
}

/* ============================================================
   13 · TABLET · 640px
   ============================================================ */
@media (min-width: 640px) {
  #contenido { padding: var(--e-5) var(--e-4) calc(var(--alto-nav) + 90px); }
  .dos-columnas { grid-template-columns: 1fr 1fr; }
  #pestanas button { min-width: 88px; }
}

/* ============================================================
   14 · ESCRITORIO · 900px — el dock sube y se vuelve carpeta
   ============================================================ */
@media (min-width: 900px) {
  #pestanas {
    position: sticky; top: calc(var(--alto-cabecera) + var(--alto-ticker)); bottom: auto;
    max-width: var(--ancho-max);
    margin: var(--e-3) auto 0;
    border: 1px solid var(--borde);
    border-radius: var(--r-md);
    box-shadow: var(--sombra-1);
    overflow-x: visible;
    padding: 3px;
    padding-bottom: 3px;
    gap: 2px;
  }
  #pestanas button {
    flex: 1 1 0;
    min-width: 0;
    min-height: 46px;
    flex-direction: row;
    gap: var(--e-2);
    border-radius: var(--r-sm);
  }
  #pestanas button span { font-size: var(--t-sm); }
  /* En escritorio el hilo pasa al borde INFERIOR: la barra está
     arriba del contenido, así que el subrayado tiene que apuntar
     hacia lo que gobierna. */
  #pestanas button::before { top: auto; bottom: 0; left: 10px; right: 10px; }
  #pestanas button.activo { background: var(--superficie-3); }
  #pestanas button.activo .ico-tab { transform: none; }

  /* Los dos botones flotantes (Terminar el mes a la derecha, Reportar bug a
     la izquierda) miden 52 px y viven a --e-5 del piso. Con e-7 de aire el
     ultimo renglon de la pagina quedaba abajo de ellos al llegar al final:
     se veian los botones de la ultima tarjeta tapados por Terminar el mes.
     Ahora el aire es la altura del boton mas su separacion, o sea que la
     ultima fila SIEMPRE queda por arriba de los flotantes. */
  #contenido { padding-bottom: calc(52px + var(--e-5) * 2 + var(--e-4)); }

  .btn-finmes { left: auto; right: var(--e-5); bottom: var(--e-5); transform: none; }
  .btn-finmes:hover:not(:disabled) { transform: translateY(-2px); }
  .btn-finmes:active:not(:disabled) { transform: translateY(2px); }
  #btn-bug-flotante { left: var(--e-5); bottom: var(--e-5); }

  #cabecera { padding: var(--e-3) var(--e-4); }
  .cab-titulo { font-size: var(--t-md); }
  .cab-marca img, .cab-marca svg { width: 42px; height: 42px; }
}

/* ============================================================
   15 · PANTALLA GRANDE · 1200px
   ============================================================ */
@media (min-width: 1200px) {
  #franja-stats { max-width: var(--ancho-max); margin: 0 auto; border-bottom: none; }
}

/* v4.7 · LA VUELTA ATRAS
   Va al lado de Terminar el mes, mas chica y mas apagada: es una red, no
   una jugada. Se esconde sola cuando no se puede usar. */
#deshacer-caja {
  position: fixed; z-index: var(--z-flotante);
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--alto-nav) + var(--e-3) + 58px + env(safe-area-inset-bottom));
}
.btn-deshacer {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px; padding: 6px 14px;
  font-family: var(--f-titulo); font-size: var(--t-xs); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  background: var(--superficie); color: var(--tinta-2);
  border: 1px solid var(--borde-fuerte); border-radius: var(--r-md);
  cursor: pointer; box-shadow: 0 2px 10px rgba(0,0,0,.18);
  transition: transform var(--vel-rapida) var(--ease), border-color var(--vel-rapida) var(--ease);
}
.btn-deshacer:hover { border-color: var(--py-oro); transform: translateY(-1px); }
.btn-deshacer small { font-weight: 500; opacity: .7; text-transform: none; letter-spacing: 0; }
@media (min-width: 900px) {
  #deshacer-caja { left: auto; right: var(--e-5); transform: none; bottom: calc(var(--e-5) + 62px); }
}
