/* ============================================================
   Hábitos 90 · Reset Wellness — Estilos
   Paleta: crema, verde profundo, gris casi negro. Fraunces + Inter.
   ============================================================ */

:root {
  --crema: #F1EDE3;
  --tarjeta: #FAF8F1;
  --tinta: #2B2B26;

  /* La segunda voz del texto: notas, rótulos, metadatos, el eje del gráfico.
     Todo lo que acompaña a un dato sin ser el dato.

     Es una tinta aclarada y no un verde apagado, y eso no fue una preferencia
     — fue lo único que la aritmética dejaba. El texto de apoyo tiene que
     leerse (4,5:1) y tiene que verse distinto del principal. Con los dos en
     verde eso es imposible:

         --verde mide 6,47:1 sobre la crema, y el suelo del texto es 4,5
         6,47 / 4,5 = 1,44

     Cualquier color que apenas cumpla 4,5 sobre la crema queda a 1,44:1 de
     --verde, y ese número no depende del tono ni de la saturación: sale solo
     de los dos objetivos. Un verde de apoyo legible es, por obligación, un
     verde que ya no se distingue del principal.

     Así que la jerarquía sale del TONO y no de la luminosidad. Gris al lado
     de verde se distingue aunque midan parecido; verde al lado de verde, no.
     Del cuerpo del texto se separa en 2,68, que sí es luminosidad. */
  --tinta-suave: #6C6C60;    /* 4,6:1 sobre la crema · 5,0:1 sobre la tarjeta */

  --linea: #DDD6C4;

  /* El fondo de un campo que se escribe.
   *
   * Existe porque durante semanas fue `#fff` escrito a mano en seis reglas, y
   * un literal no cambia de tema. De noche --tinta se vuelve #EFEBE0 y el
   * fondo seguía siendo blanco: 1,08:1, que no es «poco contraste» — es no
   * ver el número que acabas de teclear.
   *
   * De día el campo es MÁS claro que la tarjeta; de noche, más oscuro. La
   * relación se invierte porque lo que dice «acá se escribe» es el escalón,
   * no el brillo. */
  --campo: #fff;

  /* El ámbar de «atención»: el paso antes de la alerta, en el semáforo del
     coach y en todo lo que está a medias —un nivel pendiente, una revisión,
     un macro que hay que precisar.
     Nace del mismo repaso que --campo. Era #C08A4B y #8a6a2e escritos a mano
     en seis reglas —dos ámbares casi iguales, como pasó con el ladrillo—, y
     ninguno de los dos llegaba: 2,83:1 el punto y 3,13:1 la letra de noche.
     Este valor lo pide la LETRA, que es lo más exigente de los dos: con 5,0
     cumple los 4,5 del texto y de paso le sobra para el punto de 10px. */
  --ambar: #8F6222;          /* 5,0:1 sobre la tarjeta · 4,6:1 sobre el fondo */

  /* ---- El verde ----
     Uno solo, y todo lo demás son pasos suyos.

     Antes eran dos familias distintas viviendo en la misma pantalla: un oliva
     amarillento (74°) para la marca y el texto, y este verde profundo (135°)
     para lo que se toca. La idea era que uno fuera siempre identidad y el otro
     siempre estado, y que separarlos por trabajo evitaría que se leyeran como
     un error de impresión. No funcionó: sesenta grados de tono no se explican
     con un reparto de roles, y la app se veía como dos apps.

     Ahora hay un tono —135°— y una escala dentro de él. La regla del cambio
     fue conservar la LUMINOSIDAD de cada token y mover solo el tono, para que
     ninguna relación de contraste que ya funcionaba se rompiera. Todas
     subieron o quedaron igual; ninguna bajó de su mínimo.

     Es verde y no naranjo a propósito. El naranjo es el color de la racha —la
     llama, el miedo a cortarla— y esta app eligió lo contrario cuando le puso
     margen de 2 y comodines. El verde es el color de lo que se acumula, que es
     la mecánica que sí construiste. */
  --verde: #2E5E3A;          /* 6,5:1 sobre la crema · 7,1:1 sobre la tarjeta */
  /* El mismo verde, más claro. Ya NO es para texto: quedan sus catorce usos
     de dibujo —la curva de la pareja, un borde, un foco, un fondo— donde el
     mínimo es 3:1 y con 3,22 cumple. El texto se fue a --tinta-suave, y el
     porqué está escrito arriba. Si alguna vez vuelve a pintar una letra,
     pruebas/contraste.mjs falla: ese token ya no entra en un color: ni en
     un fill:. */
  --verde-suave: #6C9476;    /* 3,2:1 sobre la tarjeta — dibujo, no letra */

  /* Escala del calendario: el mismo tono, de claro a oscuro, según cuánto se
     marcó ese día. Los dos pasos de acá y el --verde son el tercero.

     El paso del medio es el que cuesta: heredado del oliva quedaba en 1,28:1
     contra el primero, que es donde dos tonos vecinos dejan de leerse como dos
     cosas. Se resolvió aclarando el PRIMERO y no oscureciendo el segundo,
     porque el número del día va en --tinta encima de los dos y necesita 4,5:1:
     bajar el segundo a 51% de luminosidad lo dejaba en 4,44 y rompía el suelo.
     Aclarando el primero el paso sube a 1,48:1 sin tocar nada de eso. */
  --nivel-parcial: #98BDA2;
  --nivel-casi: #709E7C;

  /* Lo que se toca —la casilla marcada, el anillo cuando el día ya cuenta, el
     botón principal— es el mismo verde, y por eso apunta al token en vez de
     repetir el número: si el verde de la app cambia, cambia entero.
     Sigue siendo un token aparte porque el rol es distinto, y porque el día
     que el acento tenga que separarse del resto, esta línea es el único sitio
     donde hay que tocarlo. */
  --accion: var(--verde);

  /* El único color de la app que dice "esto fue para el otro lado". Es un
     ladrillo apagado y no un rojo de semáforo, por la misma razón por la que
     lo bueno se pinta con el verde de la app: en una paleta de crema y verde,
     un rojo de alerta prestado se lee como un error de la app y no como un
     dato del cuerpo. Contrasta 5,3:1 sobre la tarjeta, así que se lee. */
  --ladrillo: #9C5442;

  --fraunces: 'Fraunces', Georgia, serif;
  --inter: 'Inter', system-ui, sans-serif;

  /* ---- La escala ----
     Seis tamaños y cuatro radios. No están acá porque queden bonitos: están
     porque seis tamaños se recuerdan y treinta no, y el que escriba la próxima
     pantalla necesita poder saber cuál le tocaba sin ir a medir la de al lado.

     El 0,75 es para rótulos en mayúscula. Todavía hay minúsculas usándolo —
     esas suben a --t-apoyo pantalla por pantalla en las fases 2 a 4, que es
     cuando se puede mirar cada texto y decidir si es rótulo o es prosa.

     Nada de tamaño ni de radio se escribe a mano: pruebas/tokens.mjs falla si
     aparece uno, salvo que lleve al lado un comentario que diga
     «fuera-de-escala» y el motivo. */
  --t-rotulo: .75rem;      /* 12px · rótulos en mayúscula */
  --t-apoyo: .875rem;      /* 14px · notas, metadatos, texto de apoyo */
  --t-cuerpo: 1rem;        /* 16px · prosa y campos de formulario */
  --t-subtitulo: 1.25rem;  /* 20px */
  --t-titulo: 1.75rem;     /* 28px */
  --t-display: 3rem;       /* 48px · cifras grandes, nunca prosa */

  /* Cada radio con un trabajo, y ninguno haciendo el del otro: la superficie
     que contiene, el control que se toca, la píldora que dice un estado y el
     círculo que es un punto. */
  --r-superficie: 24px;
  --r-control: 12px;
  --r-pilla: 999px;
  --r-circulo: 50%;

  /* Los controles del sistema —el calendario nativo, la lista de un select,
     la barra de scroll— los pinta el navegador, no esta hoja. Sin esto se
     quedan en claro dentro de una app oscura. Lo escribe el JS al arrancar. */
  color-scheme: light;
}

/* ============================================================
   La misma app, de noche
   ============================================================
   La app se marca después de comer —lo dicen los comentarios de fechas.js y
   es lo que hace todo el mundo— y hasta hoy eso significaba un rectángulo
   crema a pantalla completa a las diez de la noche.

   No es una paleta nueva: son los MISMOS diez tokens con los papeles dados
   vuelta. Ninguna pantalla, ninguna clase y ningún componente sabe que esto
   existe, porque todos leen los tokens y ninguno escribe un color.

   Las relaciones de contraste están medidas contra estos valores, no contra
   los claros: pruebas/contraste.mjs corre los mismos doce pares dos veces,
   una por paleta. Cambiar un número de acá sin mirar esa prueba es la forma
   conocida de dejar a alguien sin poder leer una cifra.

   Dos cosas se invierten y conviene saber por qué:

   · La escala del calendario va de OSCURO a CLARO, al revés que de día. Es lo
     que espera el ojo sobre un fondo negro: más marcado, más luz.

   · El día perfecto queda claro con el número oscuro encima, mientras los dos
     pasos de abajo son verdes oscuros con el número claro. El salto es a
     propósito y es el mismo que de día: el día completo tiene que separarse
     del casi.

   Tres formas de elegir, y las tres tienen que funcionar:
     1. sin decir nada        → manda el teléfono (prefers-color-scheme)
     2. eligiendo «Claro»     → data-tema="claro" gana sobre el teléfono
     3. eligiendo «Oscuro»    → data-tema="oscuro" gana sobre el teléfono   */

@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --crema: #191814;
    --tarjeta: #24231D;
    --tinta: #EFEBE0;
    --tinta-suave: #ABA595;
    --linea: #3B382F;
    --campo: #14130F;
    --ambar: #D9A85E;
    --verde: #8FC49E;
    --verde-suave: #6C9476;
    --nivel-parcial: #2F4A36;
    --nivel-casi: #40684C;
    --ladrillo: #D28C77;
    color-scheme: dark;
  }
}

:root[data-tema="oscuro"] {
  --crema: #191814;
  --tarjeta: #24231D;
  --tinta: #EFEBE0;
  --tinta-suave: #ABA595;
  --linea: #3B382F;
  --campo: #14130F;
  --ambar: #D9A85E;
  --verde: #8FC49E;
  --verde-suave: #6C9476;
  --nivel-parcial: #2F4A36;
  --nivel-casi: #40684C;
  --ladrillo: #D28C77;
  color-scheme: dark;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--inter);
  background: var(--crema);
  color: var(--tinta);
  line-height: 1.5;
  min-height: 100dvh;
}

.hidden { display: none !important; }

button { font: inherit; color: inherit; cursor: pointer; background: none; border: none; }

/* ---------- Piezas de identidad ---------- */

/* En el teléfono es un título de pantalla, no una cifra: con --t-display
   («Privacidad y seguridad») se iba a tres líneas. El salto a la cifra grande
   se lo queda la pantalla ancha, más abajo. */
.titulo {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-titulo);
  color: var(--tinta);
  line-height: 1.15;
}

/* A tamaño grande el espaciado por defecto de la fuente sobra: las letras se
   ven apiladas en vez de talladas. Apretarlas un poco es de las cosas más
   baratas que se pueden hacer —no mueve ninguna caja— y es lo que más separa
   un titular hecho de uno por defecto.

   Solo de 28px para arriba. Aplicado al texto corrido lo haría ilegible, que
   es el error clásico de copiar esta idea sin el umbral. */
.titulo, .titulo-app, .reto-dia, #core-hoy, .meta-valor, .descanso-reloj {
  letter-spacing: -.02em;
}

/* Fraunces trae un eje "WONK" que deforma algunas letras (la J salía
   torcida). Se apaga aquí y también en la URL de Google Fonts. */
.titulo, .titulo-app, .cal-titulo, .seccion-titulo, .res-grupo, .det-grupo,
.campana-nombre, .modal-fecha, .nivel-actual,
#puntos-hoy, .ranking-pos,
.ranking-puntos, .total-item strong, .res-cuenta strong,
.campana-total strong, .celebracion-badge {
  font-variation-settings: 'SOFT' 0, 'WONK' 0;
}

/* Cifras tabulares donde los números forman columna.
   Con cifras proporcionales el 1 es mucho más angosto que el 8, así que en una
   cuadrícula de días el número se corre dentro de su casilla y la columna sale
   temblorosa; y en una lista de «marcados/días» los dos números bailan de fila
   en fila. Solo va donde se COMPARAN cifras: en una cifra suelta, las
   proporcionales se leen mejor y por eso el resto de la app no lleva esto.

   OJO: los días de los dos calendarios son <button> y llevan `font: inherit`
   para quitarse el estilo del navegador. El atajo `font` reescribe TODAS las
   sub-propiedades, esta incluida, así que ahí hay que repetirla después —y no
   avisa: la regla se aplica, se pisa, y los números siguen bailando. */
.cal-dia, .rc-dia, .total-item strong, .res-cuenta {
  font-variant-numeric: tabular-nums;
}

/* ---------- Marca ---------- */

.marca-grande {
  display: block;
  margin: 0 auto 0.9rem;
  max-width: 100%;
  height: auto;
}

.app-marca { display: flex; align-items: center; gap: 0.7rem; min-width: 0; }

.marca-chica { flex-shrink: 0; }

/* UNA TARJETA TRAE SU RELLENO. No lo pone cada vista, no lo pone cada tarjeta:
   lo trae la clase.

   Durante mucho tiempo `.tarjeta` era solo fondo, borde y esquinas, y el
   relleno lo agregaba cada vista por separado (#vista-perfil, #vista-metas,
   #vista-historial, #vista-solicitudes, la portada pública). Hoy nunca tuvo la
   suya. Consecuencia: toda tarjeta nueva en Hoy nacía con el texto tocando el
   borde, y había que acordarse de escribirle una regla propia. Pasó con la
   tarjeta de metas, con la del reto, con la de la foto, con el diario de
   comidas y con el diario de ejercicios — cinco veces, cada una con su parche
   y su comentario explicando el mismo tropiezo.

   Ahora el valor por defecto vive acá. Las tarjetas que ya tenían su propio
   relleno lo conservan: sus reglas son más específicas o van más abajo, y
   ganan igual. Si una tarjeta nueva necesita otra medida, se le escribe; si no
   se le escribe nada, se ve bien. Eso es lo que cambió.

   La única excepción es abajo, y es una sola idea: una tarjeta que ES una
   lista no lleva relleno. */
.tarjeta {
  background: var(--tarjeta);
  border: 1px solid var(--linea);
  border-radius: var(--r-superficie);
  padding: 1.2rem;
}

/* Cuando la tarjeta es la lista misma, el relleno va en cada fila y no en la
   tarjeta: así las líneas divisorias llegan de borde a borde en vez de quedar
   flotando con un margen a los lados.

   Solo estas dos lo necesitan declarado. Las otras listas del proyecto
   —.sem-lista, .res-lista, .val-lista— ya fijan su propio relleno más abajo y
   con eso les basta; .admin-lista vive en Perfil, cuya regla de vista manda
   sobre esta. Si agregas otra tarjeta-lista en Hoy o en el panel de coach,
   este es el lugar. */
.tarjeta.lista-habitos,
.tarjeta.org-lista { padding: 0; }

.cargando, .estado-vacio {
  text-align: center;
  color: var(--tinta-suave);
  padding: 2.5rem 1.5rem;
}

.estado-vacio p + p { margin-top: 0.35rem; }
.vacio-emoji { font-size: var(--t-titulo); }

/* ---------- Aviso de configuración ---------- */

.config-aviso {
  max-width: 480px;
  margin: 15vh auto 0;
  padding: 0 1.25rem;
}

.config-aviso .tarjeta { padding: 2rem 1.5rem; text-align: center; }
.config-aviso p { margin-top: 0.75rem; }
.config-aviso code {
  background: var(--crema);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  padding: 0.1rem 0.4rem;
  font-size: 0.9em;
}

/* ---------- Auth ---------- */

.vista-auth {
  max-width: 440px;
  margin: 0 auto;
  padding: 12vh 1.25rem 3rem;
}

.auth-header { text-align: center; margin-bottom: 1.75rem; }
.subtitulo { color: var(--tinta-suave); margin-top: 0.4rem; }

.auth-card { padding: 1.5rem; }

.auth-tabs {
  display: flex;
  background: var(--crema);
  border-radius: var(--r-pilla);
  padding: 4px;
  margin-bottom: 1.4rem;
}

.auth-tab {
  flex: 1;
  padding: 0.55rem;
  border-radius: var(--r-pilla);
  font-weight: 500;
  color: var(--tinta-suave);
}

.auth-tab.activa {
  background: var(--tarjeta);
  color: var(--tinta);
  font-weight: 600;
  border: 1px solid var(--linea);
}

.campo { margin-bottom: 1rem; }

.campo label {
  display: block;
  font-size: var(--t-apoyo);
  font-weight: 600;
  margin-bottom: 0.35rem;
}

/* Los campos de escribir, en toda la app. Iba pegado a .campo, así que un
   campo suelto —el del diario de comidas, sin ir más lejos— salía con el
   aspecto crudo del navegador y parecía de otra aplicación. Va por tipo y no
   por "input" a secas para no tocar las casillas de los hábitos.

   min-width: los campos de fecha traen un ancho mínimo propio del navegador
   que los hacía sobresalir de la tarjeta por la derecha. */
input[type="text"],
input[type="tel"],
input[type="number"],
input[type="date"],
input[type="email"],
input[type="password"],
input[type="search"],
textarea {
  display: block;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  font: inherit;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--campo);
  color: var(--tinta);
  -webkit-appearance: none;
  appearance: none;
}

input[type="text"]:focus,
input[type="tel"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
input[type="email"]:focus,
input[type="password"]:focus,
input[type="search"]:focus,
textarea:focus {
  outline: 2px solid var(--verde-suave);
  outline-offset: 1px;
  border-color: var(--verde-suave);
}

/* Safari en iOS ignora el alto de los campos de fecha sin esto. */
input[type="date"] { min-height: 2.9rem; }

.btn-primario {
  width: 100%;
  padding: 0.85rem;
  margin-top: 0.25rem;
  background: var(--accion);
  color: var(--crema);
  border-radius: var(--r-control);
  font-weight: 600;
  font-size: var(--t-cuerpo);
  transition: opacity 0.15s;
}

.btn-primario:disabled { opacity: 0.6; cursor: wait; }

.auth-error {
  margin-top: 0.9rem;
  text-align: center;
  font-size: var(--t-cuerpo);
  color: var(--ladrillo);
}

.auth-info {
  margin-top: 0.9rem;
  text-align: center;
  font-size: var(--t-cuerpo);
  color: var(--verde);
  background: #E7E6D8;
  background: color-mix(in srgb, var(--verde-suave) 15%, transparent);
  border-radius: var(--r-control);
  padding: 0.7rem 0.9rem;
}

.link-texto {
  display: block;
  margin: 0.85rem auto 0;
  font-size: var(--t-apoyo);
  font-weight: 500;
  color: var(--tinta-suave);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* La misma cosa pero dentro de una frase, y como <button> porque suele ser una
   acción y no una dirección. Vive acá al lado de .link-texto, y no en la sección
   de la función que la necesitó primero, para que la siguiente no invente otra
   clase igual con otro nombre. */
.link-en-linea {
  font: inherit;
  padding: 0;
  color: var(--tinta-suave);
  background: transparent;
  border: 0;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

/* ---------- Estructura de la app ---------- */

/* El <meta viewport> lleva viewport-fit=cover, así que la app ocupa también
   la franja de la hora y la batería del iPhone. Sin el inset de arriba, el
   encabezado queda debajo del reloj; y en horizontal, el texto se mete bajo
   la muesca. Abajo ya estaba contemplado por la barra de navegación. */
#vista-app {
  max-width: 520px;
  margin: 0 auto;
  padding:
    calc(1.25rem + env(safe-area-inset-top))
    calc(1.1rem + env(safe-area-inset-right))
    calc(5.5rem + env(safe-area-inset-bottom))
    calc(1.1rem + env(safe-area-inset-left));
}

.app-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 1.25rem;
}

.titulo-app {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-titulo);
  line-height: 1.15;
}

.saludo { font-size: var(--t-apoyo); color: var(--tinta-suave); margin-top: 0.15rem; }

.btn-salir {
  position: relative;
  flex-shrink: 0;
  font-size: var(--t-apoyo);
  font-weight: 500;
  color: var(--tinta-suave);
  padding: 0.45rem 0.9rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-pilla);
  background: var(--tarjeta);
}

/* Contador de niveles por confirmar (solo lo ve el administrador) */
.badge {
  position: absolute;
  top: -6px;
  right: -4px;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: var(--r-pilla);
  background: #8a3b2e;
  color: #fff;
  font-size: var(--t-rotulo);
  font-weight: 700;
  line-height: 20px;
  text-align: center;
}

/* ---------- Navegación inferior ---------- */

.nav-inferior {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 0.25rem;
  /* Color sólido primero: Safari antiguo ignora color-mix y se queda con este. */
  background: var(--tarjeta);
  background: color-mix(in srgb, var(--tarjeta) 92%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--linea);
  padding: 0.5rem 0.75rem calc(0.6rem + env(safe-area-inset-bottom));
}

.nav-btn {
  flex: 1;
  max-width: 140px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  font-size: var(--t-rotulo);
  font-weight: 500;
  color: var(--tinta-suave);
  padding: 0.35rem 0;
  border-radius: var(--r-control);
}

.nav-btn svg { width: 22px; height: 22px; }
.nav-btn.activa { color: var(--verde); font-weight: 600; }

/* ---------- Pantalla Hoy ---------- */

/* El rótulo va PEGADO a su número, aunque le cueste dos líneas.
   Estuvo un rato al pie de la tarjeta, cruzando las dos columnas, porque así
   cabía en una línea. Cabía y dejaba de funcionar: separado del 5/7, se leía
   como el pie de toda la tarjeta y no como la etiqueta del anillo — alguien
   que conoce la app entera lo leyó como si fuera un dato semanal del ranking.
   Un rótulo que no toca lo que rotula no es un rótulo.
   Devolverlo a su sitio cuesta 6px de alto. Los vale. */
.resumen-hoy {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 1.25rem 1.4rem;
  margin-bottom: 1.4rem;
}

.anillo-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
  width: 118px;
}

.anillo { position: relative; width: 118px; height: 118px; }
.anillo-svg { width: 100%; height: 100%; transform: rotate(-90deg); }

.anillo-fondo { fill: none; stroke: var(--linea); stroke-width: 9; }

/* Un solo color, y es el del acento. Estaba en --verde-suave, que contra su
   propia pista da 2,29:1 — por debajo del 3:1 que necesita un gráfico para
   distinguirse. Se notaba poco mientras el anillo era decorativo; ahora es la
   única respuesta a «¿el día cuenta ya?» y tiene que leerse. Con el acento son
   5,22:1.

   Que el día cuente no lo dice un cambio de color sino el anillo lleno, más el
   rótulo de abajo, que cambia de texto, se pone en acento y agrega el visto.
   Tres señales para el mismo hecho bastan; una cuarta sobra. */
.anillo-progreso {
  fill: none;
  stroke: var(--accion);
  stroke-width: 9;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.35s ease;
}

/* El rótulo que dice qué está contando el anillo. Es el primer uso de verdad
   de --t-rotulo: mayúscula, chico y con tracking, que es donde ese tamaño se
   lee como etiqueta en vez de como letra chica. */
.anillo-pie {
  font-size: var(--t-rotulo);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--tinta-suave);
  text-align: center;
  line-height: 1.2;
  text-wrap: balance;
}

/* El pie es el rótulo del anillo, así que va del color del anillo. Cuando la
   app tenía dos verdes, dejarlo del otro ponía uno al lado del otro a tres
   píxeles de distancia, que es exactamente cómo se ve un error de impresión.
   Ahora hay uno solo y el problema no puede volver, pero la regla se queda:
   un rótulo es de la pieza que rotula. */
.anillo-pie.cuenta { color: var(--accion); }
.anillo-pie.cuenta::before { content: '✓ '; }

.anillo-centro {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-direction: row;
  align-content: center;
  flex-wrap: wrap;
}

#core-hoy {
  font-family: var(--fraunces);
  font-size: var(--t-titulo);
  font-weight: 600;
  line-height: 118px;
}

.anillo-max { font-size: var(--t-apoyo); color: var(--tinta-suave); line-height: 118px; }

.fecha-hoy {
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
  margin-bottom: 0.2rem;
}

/* La racha es lo único de esta pantalla que se puede perder hoy, y estaba del
   tamaño de un pie de foto. El peso 300 es deliberado: en una cifra grande el
   semibold se ve de cupón y el ligero se ve caro. El tracking negativo es lo
   que hace que se lea tallada y no apilada. */
.racha-linea {
  display: flex;
  align-items: baseline;
  gap: .4rem;
  margin-bottom: 0.15rem;
}

#racha-hoy {
  font-family: var(--fraunces);
  font-size: var(--t-display);
  font-weight: 300;
  letter-spacing: -.03em;
  line-height: 1;
}

#racha-texto { font-size: var(--t-cuerpo); color: var(--tinta-suave); }

.dato-puntos { font-size: var(--t-apoyo); color: var(--tinta-suave); }
.dato-puntos span { font-weight: 600; color: var(--tinta); }

.seccion-titulo {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-subtitulo);
  margin: 1.3rem 0 0.6rem;
}

.lista-habitos { list-style: none; overflow: hidden; }

.lista-habitos li + li { border-top: 1px solid var(--linea); }

/* La lista deja de ser una ficha y pasa a ser una banda de borde a borde.
   No es solo carácter —se lee bitácora y no repisa de fichas—: el relleno del
   contenedor y el borde de la tarjeta se comían 37px de ancho en CADA fila. El
   margen de una tarjeta se paga una vez; el ancho lo pierden todas.

   Los márgenes negativos deshacen el relleno de #vista-app, incluida su zona
   segura, para que la banda llegue al borde también en un teléfono con muesca. */
.tarjeta.lista-habitos {
  margin-left: calc(-1.1rem - env(safe-area-inset-left));
  margin-right: calc(-1.1rem - env(safe-area-inset-right));
  border-left: 0;
  border-right: 0;
  border-radius: 0;
}

/* Con una sola línea la fila mide 53px. El mínimo declarado es 48px, que es lo
   que se toca sin mirar; los 53 salen del relleno y del texto, no de un número
   inventado. La fila baja 8px respecto de las dos líneas de antes: es densidad,
   no un objetivo táctil más grande. */
.habito {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  min-height: 48px;
  padding: 0.9rem 1.1rem;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.habito input { position: absolute; opacity: 0; pointer-events: none; }

.check-visual {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border: 2px solid var(--linea);
  border-radius: var(--r-control);
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.check-visual svg { width: 17px; height: 17px; }

.habito input:checked + .check-visual {
  background: var(--accion);
  border-color: var(--accion);
  color: var(--crema);
}

/* El peso normal es deliberado. Cuando todas las etiquetas van en semibold no
   resalta ninguna, y el peso deja de servir para decir qué importa más. */
.habito-info { display: flex; flex-direction: column; min-width: 0; }
.habito-label { font-weight: 400; }

.habito input:checked ~ .habito-info .habito-label {
  color: var(--tinta-suave);
}

/* Sugerencia del día bajo un hábito (audio, libro). Va fuera del
   <label> para que tocar el enlace no marque la casilla. */
.habito-extra {
  margin: -0.35rem 1.1rem 0.85rem calc(1.1rem + 28px + 0.9rem);
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
  line-height: 1.45;
}

.extra-prefijo { font-weight: 600; }

.habito-extra a {
  color: var(--verde);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  /* Área tocable más generosa sin alterar el diseño. */
  display: inline-block;
  padding: 0.25rem 0;
}

.nota-dia {
  text-align: center;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
  margin-top: 1.2rem;
}

/* ---------- En qué nivel de hábitos voy ----------
   Una línea bajo la nota del día, con su mismo peso visual: informa, no manda.
   El control para cambiarlo está en Perfil.

   NO se llama .nivel-actual: esa clase ya existe y es el NIVEL DE NEGOCIO
   —Supervisor y compañía— en Fraunces 1.35rem. Dos cosas distintas con el
   mismo nombre, y la de más abajo gana: esta línea salía como un titular
   serif enorme en medio de la pantalla Hoy. */

.nivel-habitos-linea {
  margin-top: 0.35rem;
  text-align: center;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
}

/* ---------- Ranking ---------- */

.nota-periodo {
  margin-bottom: 1.1rem;
  text-align: center;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
}

.tabs-periodo {
  display: flex;
  background: var(--tarjeta);
  border: 1px solid var(--linea);
  border-radius: var(--r-pilla);
  padding: 4px;
  margin-bottom: 1.1rem;
}

.tab-periodo {
  flex: 1;
  padding: 0.5rem;
  border-radius: var(--r-pilla);
  font-size: var(--t-cuerpo);
  font-weight: 500;
  color: var(--tinta-suave);
}

.tab-periodo.activa {
  background: var(--verde);
  color: var(--crema);
  font-weight: 600;
}

/* El relleno lo ponen las filas, no la tarjeta.
   Se pagaba dos veces —19,2 px de la tarjeta más 17,6 px de cada fila, por los
   dos lados— y eran 73,6 px de los 375 de un teléfono gastados en aire antes de
   escribir nada. Es el mismo descuido de siempre: una .tarjeta ya trae su
   relleno y quien mete filas dentro le añade el suyo.
   Al quitarlo las filas llegan al borde, que es además como se ve un ranking:
   la línea que separa cruza entera y la fila tuya es una banda, no un parche
   flotando en el medio. El overflow recorta las esquinas a la tarjeta. */
.ranking { list-style: none; overflow: hidden; padding: 0; }
.ranking-fila {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.85rem 1.1rem;
}
.ranking-fila + .ranking-fila { border-top: 1px solid var(--linea); }

.ranking-yo {
  background: #EBE9DC;
  background: color-mix(in srgb, var(--verde-suave) 14%, var(--tarjeta));
}

.ranking-pos {
  width: 2rem;
  text-align: center;
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-cuerpo);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

.ranking-info { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.ranking-nombre {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;   /* sin esto el nombre largo no se acorta y empuja los enlaces */
}
.ranking-nombre em { font-style: normal; font-weight: 400; color: var(--tinta-suave); font-size: 0.85em; }
.ranking-meta { font-size: var(--t-apoyo); color: var(--tinta-suave); }

/* La cifra que ordena la tabla, con su rótulo debajo.
   Iba todo en una línea —«27 días»— y así la columna cambiaba de ancho en cada
   fila, según los dígitos del número y según el plural: 43 px en la última fila
   y 69 px en la primera. Las cifras no formaban columna, cada una caía en un
   sitio distinto, y comparar es lo único que se hace con un ranking. Ancho fijo
   y tabular, que es lo que las alinea de verdad. */
.ranking-puntos {
  flex-shrink: 0;
  width: 3.25rem;
  text-align: center;
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-subtitulo);
  line-height: 1.15;
  color: var(--verde);
  font-variant-numeric: tabular-nums;
}
.ranking-puntos small {
  display: block;
  font-family: var(--inter);
  font-size: var(--t-rotulo);
  font-weight: 500;
  color: var(--tinta-suave);
}

/* ---------- Historial ---------- */

#vista-historial .tarjeta { padding: 1.2rem 1.2rem 1rem; }

.cal-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.9rem;
}

.cal-titulo { font-family: var(--fraunces); font-weight: 600; font-size: var(--t-subtitulo); }

.cal-flecha {
  width: 36px;
  height: 36px;
  border-radius: var(--r-pilla);
  border: 1px solid var(--linea);
  font-size: var(--t-subtitulo);
  line-height: 1;
  color: var(--verde);
  background: var(--crema);
}
.cal-flecha:disabled { opacity: 0.35; cursor: default; }

.cal-cabecera, .cal-grilla {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}

.cal-cabecera {
  margin-bottom: 6px;
  text-align: center;
  font-size: var(--t-rotulo);
  font-weight: 600;
  color: var(--tinta-suave);
}

.cal-dia {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-control);
  font-size: var(--t-apoyo);
  font-weight: 500;
}

.cal-hueco { visibility: hidden; }
.cal-vacio { background: var(--crema); color: var(--tinta-suave); border: 1px solid var(--linea); }
.cal-futuro { background: transparent; color: var(--linea); }
/* Tres estados con un solo significado cada uno, y los nombres lo dicen.
   Se llamaban `parcial` y `casi`, que describían cuánto llenaste la lista y no
   lo único que importa: si el día sirvió para la racha. Un día «casi» sonaba a
   estar cerca cuando podía perfectamente haber contado — o al revés. */
/* El calendario es una ESCALA, y una escala vive en una sola familia: el mismo
   tono subiendo de intensidad. Con dos verdes en la app esto costaba: el
   remate tenía que ser el oliva oscuro y no el acento, porque poner un verde
   de otra familia al final de una cuadrícula donde los cuadros se tocan es
   donde dos verdes parecidos se ven como un error de imprenta.

   Ahora los tres pasos son el mismo tono a 62%, 53% y 27% de luminosidad, y el
   remate es el verde de la app sin que eso rompa nada. Lo que era una excepción
   que había que explicar es ahora la escala entera. */
.cal-nollego { background: var(--nivel-parcial); color: var(--tinta); }
.cal-cuenta { background: var(--nivel-casi); color: var(--tinta); }
.cal-perfecto { background: var(--verde); color: var(--crema); font-weight: 600; }
.cal-hoy { outline: 2px solid var(--tinta); outline-offset: 1px; }

/* ---------- El calendario del reto ---------- */
/* Noventa días seguidos en una sola vista. Comparte los tonos con el
   calendario del Historial —son el mismo significado y sería raro que el mismo
   día se viera de dos colores según dónde lo mires— pero no su cuadrícula: acá
   los días son más chicos porque son muchos más y el trabajo es ver la FORMA
   del tramo, no leer cada número. */
.rc-cabecera, .rc-grilla {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}

.rc-cabecera {
  margin-bottom: 4px;
  text-align: center;
  font-size: var(--t-rotulo);
  font-weight: 600;
  color: var(--tinta-suave);
}

.rc-dia {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-control);
  font: inherit;
  font-size: var(--t-rotulo);
  font-weight: 500;
  font-variant-numeric: tabular-nums;   /* después de `font`, que la borra */
  border: 0;
  padding: 0;
}

.rc-hueco { visibility: hidden; }
.rc-vacio { background: var(--crema); color: var(--tinta-suave); border: 1px solid var(--linea); }
.rc-nollego { background: var(--nivel-parcial); color: var(--tinta); }
.rc-cuenta { background: var(--nivel-casi); color: var(--tinta); }
.rc-perfecto { background: var(--verde); color: var(--crema); font-weight: 600; }
.rc-futuro { background: transparent; color: var(--linea); }

/* El tramo que esta pantalla no cargó. Se dibuja y se dice por qué, en vez de
   desaparecer: un hueco sin explicación se lee como un día fallado. */
.rc-lejos {
  background: repeating-linear-gradient(45deg,
    var(--crema), var(--crema) 3px, var(--linea) 3px, var(--linea) 4px);
  color: var(--tinta-suave);
}

.rc-hoy { outline: 2px solid var(--tinta); outline-offset: 1px; }

.rc-detalle {
  margin-top: 0.7rem;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
  min-height: 1.5em;
}

.cal-leyenda {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.45rem 0.9rem;
  margin-top: 1rem;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
}

.cal-leyenda span { display: flex; align-items: center; gap: 0.35rem; }

.cal-punto {
  width: 12px;
  height: 12px;
  border-radius: var(--r-circulo);
  display: inline-block;
}

/* Los días del calendario son botones: se anula el estilo por defecto. */
button.cal-dia {
  font: inherit;
  font-size: var(--t-apoyo);
  font-weight: 500;
  font-variant-numeric: tabular-nums;   /* después de `font`, que la borra */
  cursor: pointer;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
}

button.cal-dia:active { transform: scale(0.92); }
button.cal-dia:focus-visible { outline: 2px solid var(--tinta); outline-offset: 2px; }

.cal-pista {
  text-align: center;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  margin-top: 0.75rem;
}

.totales-mes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.7rem;
  margin-top: 0.9rem;
}

.total-item {
  padding: 0.9rem 0.5rem !important;
  text-align: center;
  display: flex;
  flex-direction: column;
}

.total-item strong {
  font-family: var(--fraunces);
  font-size: var(--t-titulo);
  font-weight: 600;
  color: var(--verde);
}

.total-item span { font-size: var(--t-rotulo); color: var(--tinta-suave); }

/* ---------- Resumen por hábito ---------- */

.res-nota {
  text-align: center;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
  margin-bottom: 0.9rem;
}

.res-grupo {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-cuerpo);
  margin: 1rem 0 0.5rem;
}

.res-lista { list-style: none; padding: 0.3rem 0; }

.res-fila { padding: 0.6rem 1.1rem; }
.res-fila + .res-fila { border-top: 1px solid var(--linea); }

.res-texto {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.4rem;
}

.res-label { font-size: var(--t-cuerpo); font-weight: 500; }

.res-cuenta {
  flex-shrink: 0;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
  white-space: nowrap;
}

.res-cuenta strong {
  font-family: var(--fraunces);
  font-size: var(--t-cuerpo);
  color: var(--verde);
}

.res-barra {
  height: 6px;
  background: var(--crema);
  border-radius: var(--r-pilla);
  overflow: hidden;
}

.res-barra i {
  display: block;
  height: 100%;
  background: var(--verde-suave);
  border-radius: var(--r-pilla);
  transition: width 0.3s ease;
}

/* ---------- Metas del mes ---------- */

/* «Voy» y «Meta» tienen que caer justo encima de sus campos, y ni el gap ni
   el relleno se adivinan: salen de medir. El gap es la distancia real entre
   campo y campo (0,25rem + el «de» + 0,25rem) y el relleno derecho es cero,
   porque cualquier valor ahí corre los dos rótulos a la izquierda y ninguno
   vuelve a coincidir. Medido a 360px: 0,0 px de desvío en los dos. */
.meta-cabecera {
  display: flex;
  justify-content: flex-end;
  gap: 1.4rem;
  font-size: var(--t-rotulo);
  font-weight: 600;
  color: var(--tinta-suave);
  padding: 0 0 0.4rem;
}

.meta-cabecera span { width: 5.4rem; text-align: center; }

.meta-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.5rem 0;
}

.meta-fila + .meta-fila { border-top: 1px solid var(--linea); }

.meta-label { font-size: var(--t-apoyo); font-weight: 500; flex: 1; }

.meta-inputs { display: flex; align-items: center; gap: 0.25rem; flex-shrink: 0; }

/* 5rem y no 4,6, y el relleno de los lados a 0,15rem.
 *
 * Con 4,6rem un PVT de «4.759,50» pide 76px en una caja de 72 y el navegador
 * se come el último carácter: la pantalla mostraba «4.759,5C». No es que
 * faltara mucho — faltaban cuatro píxeles.
 *
 * El ancho se compró donde era barato. Subir la caja a 5,5rem también cabía,
 * pero le quitaba 24px a la columna del nombre y «Puntos de volumen (PVT)»
 * pasaba de dos líneas a tres: 21px más de alto en dos filas para ganar 14 de
 * ancho. Quitando relleno se consigue lo mismo costando 6px de columna, y las
 * filas no crecen ni un píxel.
 *
 * Nada de font-variant-numeric: tabular-nums acá. En Inter las cifras
 * tabulares son MÁS anchas —«14.772,77» pasa de 80 a 86px— y volvería a
 * cortar justo lo que esto vino a arreglar. */
.meta-inputs input {
  width: 5.4rem;
  font: inherit;
  font-size: var(--t-cuerpo);
  text-align: center;
  padding: 0.45rem 0.15rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--campo);
  color: var(--tinta);
}

.meta-inputs input:focus { outline: 2px solid var(--verde-suave); outline-offset: 1px; }

.meta-sep { font-size: var(--t-rotulo); color: var(--tinta-suave); }

#vista-metas .tarjeta { padding: 1.2rem; }

/* En un teléfono estrecho la tarjeta cede relleno para que la cifra no pierda
   ancho. Los 5,4rem que necesita «99.999,99» caben de sobra a 375 y 390, pero
   a 360 le quitan trece píxeles a la columna del nombre y «Puntos de volumen
   (PVT)» pasa a tres líneas. Trece píxeles de relleno valen menos que eso.
   Por encima de 370 no hace falta y la tarjeta se queda como está. */
@media (max-width: 370px) {
  #vista-metas .tarjeta { padding: 0.85rem; }
}
#vista-metas .btn-primario { margin-top: 1rem; }

/* Mes y año como <select>: Safari de iPhone/iPad no soporta
   <input type="month"> y lo degrada a un cuadro de texto libre. */
.sup-selects {
  display: flex;
  gap: 0.5rem;
  margin: 0.5rem 0 0.7rem;
}

/* Forma y color los pone la regla global de <select>; acá solo el reparto
   del ancho, que es lo propio de esta pantalla. */
.sup-selects select {
  flex: 1;
  font-size: var(--t-cuerpo);
}

.sup-antiguo {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  font-size: var(--t-apoyo);
  line-height: 1.4;
  padding: 0.3rem 0;
  cursor: pointer;
}

.sup-antiguo input {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  margin-top: 0.05rem;
  accent-color: var(--verde);
}

.btn-secundario {
  width: 100%;
  padding: 0.7rem;
  margin-top: 0.6rem;
  border: 1px solid var(--verde);
  border-radius: var(--r-control);
  color: var(--verde);
  font-weight: 600;
  background: transparent;
}

/* ---------- Desplegables ---------- */
/* Uno solo para toda la app. Antes cada pantalla resolvía lo suyo: los de
   Perfil tenían forma y los de Mi gente salían con el estilo crudo del
   navegador, distinto además en cada teléfono.

   La lista que se abre al tocarlo NO se puede tocar desde acá: la dibuja el
   sistema operativo. Lo que se ve igual en todas partes es el control
   cerrado, que es lo que se mira el 99% del tiempo. */

select {
  display: block;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  font: inherit;
  padding: 0.75rem 2.6rem 0.75rem 1rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background-color: var(--crema);
  color: var(--tinta);
  -webkit-appearance: none;
  appearance: none;
  /* La doble flecha, arriba y abajo: dice "esto se despliega" mucho mejor
     que una sola, que se confunde con un acordeón que baja.
     El color va escrito a mano —%232E5E3A es --verde— porque dentro de un
     data: URI no entra var(). Es el único sitio de la hoja donde el verde
     está copiado, así que si el verde cambia, esta línea cambia con él.
     Y por lo mismo hay una segunda copia más abajo, para la paleta oscura:
     el verde profundo sobre un fondo negro no se ve. Las dos las vigila
     pruebas/copias.mjs. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'%3E%3Cpath d='M2.5 8 6 4.5 9.5 8M2.5 12 6 15.5 9.5 12' fill='none' stroke='%232E5E3A' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
  background-size: 0.7rem 1.15rem;
}

select:focus-visible {
  outline: 2px solid var(--verde);
  outline-offset: 1px;
}

select:disabled {
  color: var(--tinta-suave);
  opacity: 1;            /* Safari lo aclara tanto que no se lee */
}

/* ---------- Perfil ---------- */

#vista-perfil .tarjeta { padding: 1.2rem; }

/* Forma y tamaño de los campos: la regla global. Acá ya no hace falta nada.
   La flecha del select también. Importa que se vea: con el país, alguien de
   otro país vería "Chile +56" sin sospechar que se puede cambiar. */

/* País y número, uno sobre otro: hay nombres largos ("República Democrática
   del Congo") que al costado quedarían cortados en un celular. */
.campo-telefono {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.nota-campo {
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  margin-top: 0.35rem;
  line-height: 1.45;
}

/* .nota-campo nació como el pie de un campo —de ahí el margen de arriba y
   ninguno abajo—, pero también se usa como párrafo suelto, y ahí dos seguidas
   quedan casi pegadas y la que precede a un campo se pega a su etiqueta. Se
   arregla en el encuentro y no en la clase: tocar .nota-campo movería su
   pie en las docenas de sitios donde ya está bien. */
.nota-campo + .nota-campo { margin-top: 0.8rem; }
.nota-campo + .campo { margin-top: 0.9rem; }

.nota-error { color: var(--ladrillo); }

/* Avisa que un dato sí lo ve el equipo, para que nadie se lleve sorpresas. */
.nota-visible {
  background: #EBE9DC;
  background: color-mix(in srgb, var(--verde-suave) 14%, transparent);
  border-radius: var(--r-control);
  /* Mas aire del que parece necesario, a proposito. Estas notas casi siempre
     empiezan con un emoji, y en iOS los emoji usan Apple Color Emoji, con
     metricas distintas de la tipografia del texto: estiran la primera linea y
     el recuadro queda apretado abajo. Con este padding y esta altura de linea
     da igual que emoji sea. */
  padding: 0.75rem 0.85rem;
  margin: 0 0 1rem;
  font-size: var(--t-apoyo);
  line-height: 1.55;
}

.nivel-actual {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-subtitulo);
  color: var(--verde);
}

.nivel-aviso { font-size: var(--t-apoyo); margin-top: 0.4rem; }
.nivel-ok { color: var(--verde); font-weight: 600; }
.nivel-pendiente { color: var(--ambar); font-weight: 600; }

.salir-card { margin-top: 1.5rem; }

/* ---------- Parejas ---------- */

.pj-titulo {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-cuerpo);
  margin-bottom: 0.4rem;
}

#pareja-panel .btn-secundario,
#pareja-panel .btn-primario { margin-top: 0.7rem; }

#pareja-panel .campo input {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  font: inherit;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--campo);
  color: var(--tinta);
}

.pj-nada {
  margin-top: 0.9rem;
  font-size: var(--t-apoyo);
  line-height: 1.5;
  color: var(--tinta-suave);
}

.pj-encontrada {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--linea);
}

.pj-nombre {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-subtitulo);
  color: var(--verde);
}

/* Fusión de metas al formar la pareja */

.fus-ok { font-size: var(--t-apoyo); color: var(--verde); margin-top: 0.6rem; }

.fus-aviso {
  font-size: var(--t-apoyo);
  font-weight: 600;
  margin: 1rem 0 0.5rem;
}

.fus-mes {
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  padding: 0.8rem;
  margin-bottom: 0.7rem;
  background: var(--crema);
}

.fus-titulo {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-cuerpo);
  margin-bottom: 0.5rem;
}

.fus-campo { margin-bottom: 0.7rem; }
.fus-campo:last-child { margin-bottom: 0; }

.fus-etiqueta { display: block; font-size: var(--t-apoyo); font-weight: 500; }

.fus-origen {
  display: block;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  margin: 0.1rem 0 0.3rem;
}

.fus-campo input {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  font: inherit;
  font-size: var(--t-cuerpo);
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--campo);
  color: var(--tinta);
}

/* ---------- Panel de coach ---------- */

.coach-cab {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin-bottom: 0.5rem;
}

.coach-titulo { font-family: var(--fraunces); font-weight: 600; font-size: var(--t-subtitulo); }

/* Validaciones */

/* El relleno va en cada fila, no en la tarjeta, para que las líneas
   divisorias lleguen de borde a borde. */
.val-lista { list-style: none; padding: 0.3rem 0; }
.val-fila { padding: 0.8rem 1.1rem; }
.val-fila + .val-fila { border-top: 1px solid var(--linea); }

.val-info { display: flex; flex-direction: column; margin-bottom: 0.55rem; }
.val-nombre { font-weight: 600; font-size: var(--t-cuerpo); }
.val-nivel { font-size: var(--t-apoyo); color: var(--verde); }
.val-pvt { font-size: var(--t-apoyo); color: var(--tinta-suave); }

.val-acciones { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; }

.val-acciones button {
  font-size: var(--t-apoyo);
  font-weight: 600;
  padding: 0.42rem 0.85rem;
  border-radius: var(--r-pilla);
  border: 1px solid var(--linea);
}

.val-si { background: var(--verde); color: var(--crema); border-color: var(--verde); }
.val-no, .val-revocar { background: var(--crema); color: var(--tinta-suave); }
.val-acciones button:disabled { opacity: 0.5; }
.val-ok { font-size: var(--t-apoyo); font-weight: 600; color: var(--verde); }

/* «Ya aprobadas» separa las pendientes de las hechas. Cuando no queda ninguna
   pendiente es lo primero de la lista, y entonces su raya se dibujaba pegada
   al borde de la tarjeta: un separador que no separa nada. Se le quita la raya
   y el aire de arriba cuando va primero; la etiqueta se queda, porque ahí sí
   dice algo. */
.val-sep:first-child { border-top: 0; padding-top: 0.2rem; }

.val-sep {
  padding: 0.9rem 1.1rem 0.4rem;
  border-top: 1px solid var(--linea);
  font-size: var(--t-rotulo);
  font-weight: 600;
  color: var(--tinta-suave);
}

/* Semáforo */

.sem-lista { list-style: none; padding: 0.3rem 0; }

.sem-fila {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.75rem 1.1rem;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.sem-fila + .sem-fila { border-top: 1px solid var(--linea); }
.sem-fila:active { opacity: 0.6; }

.sem-punto {
  width: 10px;
  height: 10px;
  border-radius: var(--r-pilla);
  flex-shrink: 0;
}

.sem-bien .sem-punto     { background: var(--verde); }
.sem-atencion .sem-punto { background: var(--ambar); }
.sem-alerta .sem-punto   { background: var(--ladrillo); }

.sem-info { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.sem-nombre { font-weight: 600; font-size: var(--t-cuerpo); }
.sem-detalle { font-size: var(--t-apoyo); color: var(--tinta-suave); }
.sem-nivel { font-size: var(--t-rotulo); color: var(--tinta-suave); }
.sem-alerta .sem-detalle { color: var(--ladrillo); font-weight: 500; }

.sem-flecha { color: var(--linea); font-size: var(--t-subtitulo); flex-shrink: 0; }

/* Ficha individual */

/* En la ficha, estas filas van dentro de un cuerpo que ya tiene
   relleno: sin esto quedaban con el doble de sangría. */
.modal-cuerpo .res-fila { padding-left: 0; padding-right: 0; }
.modal-cuerpo .res-lista { padding: 0; }

.ficha-campana {
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  padding: 0.8rem;
  margin-bottom: 0.7rem;
  background: var(--crema);
}

.ficha-campana-nombre {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-cuerpo);
  margin-bottom: 0.3rem;
}

.ficha-campana-dato { font-size: var(--t-apoyo); line-height: 1.5; color: var(--tinta-suave); }
.ficha-campana-dato strong { color: var(--verde); }

/* Solicitar validación, en la pantalla de Metas */

.niv-pista {
  font-size: var(--t-rotulo);
  line-height: 1.45;
  color: var(--tinta-suave);
  margin-top: 0.25rem;
}

.niv-solicitar {
  width: 100%;
  margin-top: 0.5rem;
  padding: 0.45rem;
  font-size: var(--t-apoyo);
  font-weight: 600;
  color: var(--crema);
  background: var(--verde);
  border-radius: var(--r-control);
}

.niv-solicitar:disabled { opacity: 0.5; }
.niv-validado { font-size: var(--t-rotulo); font-weight: 600; color: var(--verde); margin-top: 0.4rem; }
.niv-revision { font-size: var(--t-rotulo); font-weight: 600; color: var(--ambar); margin-top: 0.4rem; }

/* Insignias en el ranking */

.ranking-insignias {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-top: 0.3rem;
}

/* Contacto en el ranking: los enlaces van en la línea del nombre, que es
   la única que no crece según cuántas insignias tenga cada persona. */
.ranking-cabecera {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
}

.ranking-contactos {
  display: flex;
  gap: 0.25rem;
  flex-shrink: 0;
}

/* Área de toque de 32px: se tocan con el pulgar, en el celular. */
.ranking-contacto {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--r-pilla);
  color: var(--verde);
  background: #DFDFCE;
  background: color-mix(in srgb, var(--verde-suave) 22%, transparent);
  text-decoration: none;
}

.ranking-contacto svg { width: 1.05rem; height: 1.05rem; display: block; }

.ranking-contacto:active {
  background: #CFCFB8;
  background: color-mix(in srgb, var(--verde-suave) 38%, transparent);
}

.insignia {
  background: #DFDFCE;
  background: color-mix(in srgb, var(--verde-suave) 22%, transparent);
  color: var(--verde);
  font-size: var(--t-rotulo);
  font-weight: 600;
  padding: 0.1rem 0.45rem;
  border-radius: var(--r-pilla);
  white-space: nowrap;
}

/* ---------- Bandeja del administrador ---------- */

.admin-lista { list-style: none; }

.admin-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
  padding: 0.75rem 0;
  flex-wrap: wrap;
}

.admin-fila + .admin-fila { border-top: 1px solid var(--linea); }

.admin-info { display: flex; flex-direction: column; min-width: 0; }
.admin-nombre { font-weight: 600; font-size: var(--t-cuerpo); }
.admin-nivel { font-size: var(--t-apoyo); color: var(--tinta-suave); }

.admin-acciones { display: flex; gap: 0.45rem; flex-shrink: 0; }

.admin-acciones button {
  font-size: var(--t-apoyo);
  font-weight: 600;
  padding: 0.4rem 0.75rem;
  border-radius: var(--r-pilla);
  border: 1px solid var(--linea);
}

.admin-si { background: var(--verde); color: var(--crema); border-color: var(--verde); }
.admin-no { background: var(--crema); color: var(--tinta-suave); }
.admin-acciones button:disabled { opacity: 0.5; }

/* ---------- Campañas de calificación ---------- */

.campana { margin-bottom: 1rem; }

.campana-bloqueada { background: var(--crema); }
.campana-bloqueada .campana-nombre { color: var(--tinta-suave); }

.campana-candado {
  margin-top: 0.6rem;
  font-size: var(--t-apoyo);
  line-height: 1.5;
  color: var(--tinta-suave);
}

.campana-cab {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.campana-nombre { font-family: var(--fraunces); font-weight: 600; font-size: var(--t-cuerpo); }
.campana-periodo { font-size: var(--t-rotulo); color: var(--tinta-suave); }

.campana-total { font-size: var(--t-apoyo); color: var(--tinta-suave); margin: 0.5rem 0 0.9rem; }
.campana-total strong { font-family: var(--fraunces); font-size: var(--t-subtitulo); color: var(--verde); }

.chip-sup {
  display: inline-block;
  background: #DFDFCE;
  background: color-mix(in srgb, var(--verde-suave) 22%, transparent);
  color: var(--verde);
  font-size: var(--t-rotulo);
  font-weight: 600;
  padding: 0.1rem 0.5rem;
  border-radius: var(--r-pilla);
}

.niv-lista { list-style: none; }
.niv-fila { padding: 0.6rem 0; }
.niv-fila + .niv-fila { border-top: 1px solid var(--linea); }

.niv-texto {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.35rem;
}

.niv-nombre { font-size: var(--t-apoyo); font-weight: 500; }
.niv-logrado .niv-nombre { font-weight: 600; }
.niv-req { font-size: var(--t-apoyo); color: var(--tinta-suave); flex-shrink: 0; }

.niv-detalle { font-size: var(--t-rotulo); color: var(--tinta-suave); margin-top: 0.3rem; }
.niv-ok { color: var(--verde); font-weight: 600; }
.niv-falta { font-weight: 500; }

.desglose-toggle {
  width: 100%;
  margin-top: 0.8rem;
  padding: 0.5rem;
  font-size: var(--t-apoyo);
  font-weight: 600;
  color: var(--verde);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--crema);
}

.desglose {
  width: 100%;
  margin-top: 0.8rem;
  border-collapse: collapse;
  font-size: var(--t-apoyo);
}

.desglose th {
  text-align: left;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--linea);
}

.desglose th:not(:first-child), .desglose td:not(:first-child) { text-align: right; }
.desglose td { padding: 0.35rem 0; border-bottom: 1px solid var(--linea); vertical-align: top; }
.desglose tfoot td { font-weight: 600; border-bottom: none; padding-top: 0.5rem; }
.desg-nulo { color: var(--tinta-suave); }

.desg-motivo {
  display: block;
  font-size: var(--t-rotulo);
  font-weight: 400;
  color: var(--tinta-suave);
}

.desg-nota {
  margin-top: 0.7rem;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  line-height: 1.5;
}

/* Con 4 pestañas el texto necesita algo menos de aire. */
@media (max-width: 380px) {
  .nav-btn { font-size: var(--t-rotulo); }
}

/* ---------- Detalle de un día (solo lectura) ---------- */

.modal-fondo {
  position: fixed;
  inset: 0;
  background: rgba(43, 43, 38, 0.45);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 70;
  animation: aparecer 0.18s ease;
}

@keyframes aparecer { from { opacity: 0; } to { opacity: 1; } }

.modal-hoja {
  background: var(--tarjeta);
  width: 100%;
  max-width: 520px;
  max-height: 85dvh;
  display: flex;
  flex-direction: column;
  border-radius: 20px 20px 0 0;
  border: 1px solid var(--linea);
  animation: subir 0.22s ease;
}

@keyframes subir { from { transform: translateY(100%); } to { transform: translateY(0); } }

.modal-cabecera {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.2rem 1.2rem 0.8rem;
  border-bottom: 1px solid var(--linea);
}

.modal-fecha {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-subtitulo);
}

/* Solo la inicial en mayúscula: "Miércoles 1 de julio", no "1 De Julio". */
.modal-fecha::first-letter { text-transform: uppercase; }

.modal-sub { font-size: var(--t-apoyo); color: var(--tinta-suave); margin-top: 0.15rem; }
.modal-sub.conto { color: var(--accion); font-weight: 600; }

.modal-cerrar {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--r-pilla);
  border: 1px solid var(--linea);
  background: var(--crema);
  color: var(--verde);
  font-size: var(--t-cuerpo);
  line-height: 1;
}

.modal-cuerpo {
  overflow-y: auto;
  padding: 0.4rem 1.2rem calc(1.4rem + env(safe-area-inset-bottom));
}

/* ---------- Peso ---------- */

.peso-caja { margin: 1.1rem 0 0.4rem; }

.peso-grafico {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
}

.peso-eje {
  font-family: var(--inter);
  font-size: 8px;  /* fuera-de-escala: escala de un SVG, no texto de interfaz */
  fill: var(--tinta-suave);
}

.peso-leyenda {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  margin-top: 0.4rem;
}
.peso-leyenda span { display: inline-flex; align-items: center; gap: 0.3rem; }
.peso-leyenda i { width: 12px; height: 3px; border-radius: var(--r-pilla); }

.peso-check {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: var(--t-apoyo);
  margin-top: 0.7rem;
  line-height: 1.4;
}
.peso-check input { margin-top: 0.15rem; flex-shrink: 0; }

.nota-auto {
  background: #E7EBDC;
  background: color-mix(in srgb, var(--verde) 12%, transparent);
  border-radius: var(--r-control);
  padding: 0.55rem 0.7rem;
  margin-bottom: 0.9rem;
}

/* ---------- Esquema de la organización ---------- */

.org-lista { list-style: none; overflow: hidden; }

/* Esta tarjeta va a ras —está en la excepción de arriba, junto a
   .lista-habitos— y el relleno lo pone cada fila. La sangría se SUMA a ese
   margen en vez de reemplazarlo; si no, el primer nivel queda pegado al borde
   de la tarjeta. */
.org-fila {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.6rem 1.1rem;
  padding-left: calc(1.1rem + var(--sangria, 0rem));
  border-top: 1px solid var(--linea);
  font-size: var(--t-cuerpo);
}
.org-fila:first-child { border-top: 0; }

.org-nombre { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.org-usuario { font-size: 0.8em; color: var(--tinta-suave); }
.org-pendiente { font-size: var(--t-rotulo); color: var(--tinta-suave); font-style: italic; }

/* Nombre real y nivel de organización, junto al nombre en el semáforo. */
.sem-real {
  font-weight: 400;
  font-size: 0.82em;
  color: var(--tinta-suave);
}

.sem-org {
  display: inline-block;
  background: #DFDFCE;
  background: color-mix(in srgb, var(--verde-suave) 22%, transparent);
  color: var(--verde);
  font-size: var(--t-rotulo);
  font-weight: 600;
  padding: 0.05rem 0.4rem;
  border-radius: var(--r-pilla);
  vertical-align: middle;
  white-space: nowrap;
}

/* Datos que se muestran pero no se editan: el patrocinador, el código. */
.dato-fijo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.dato-etiqueta {
  font-size: var(--t-apoyo);
  font-weight: 600;
  color: var(--tinta-suave);
}

.dato-valor { font-weight: 600; }

.campo-codigo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1.1rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--linea);
}

.codigo-grande {
  font-family: var(--fraunces);
  font-size: var(--t-titulo);
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--verde);
}

/* El código de invitación se lee y se dicta: conviene que no se confunda
   con el resto del formulario. */
#input-codigo {
  font-family: var(--fraunces);
  font-size: var(--t-subtitulo);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.det-grupo {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-cuerpo);
  margin: 1rem 0 0.4rem;
}

.det-lista { list-style: none; }

.det-fila {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0;
}

.det-fila + .det-fila { border-top: 1px solid var(--linea); }

.det-marca {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border-radius: var(--r-control);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--t-apoyo);
  font-weight: 700;
}

.det-hecho .det-marca { background: var(--verde); color: var(--crema); }
.det-pendiente .det-marca { background: var(--crema); color: var(--linea); border: 1px solid var(--linea); }

.det-label { flex: 1; font-size: var(--t-cuerpo); }
.det-pendiente .det-label { color: var(--tinta-suave); }

.det-pts {
  font-size: var(--t-apoyo);
  font-weight: 600;
  color: var(--verde);
  flex-shrink: 0;
}

.det-nota {
  margin-top: 1.1rem;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  text-align: center;
}

/* ---------- Toast ---------- */

.toast {
  position: fixed;
  bottom: calc(5.5rem + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  background: var(--tinta);
  color: var(--crema);
  padding: 0.7rem 1.2rem;
  border-radius: var(--r-pilla);
  font-size: var(--t-apoyo);
  box-shadow: 0 4px 18px rgba(43, 43, 38, 0.25);
  z-index: 50;
  max-width: calc(100vw - 2rem);
  text-align: center;
}

/* ---------- Celebración de día perfecto ---------- */

.celebracion {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 60;
}

.confeti {
  position: absolute;
  top: -16px;
  border-radius: var(--r-pilla);
  animation-name: caer;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

@keyframes caer {
  0%   { transform: translateY(-20px) rotate(0deg); opacity: 1; }
  100% { transform: translateY(104vh) rotate(680deg); opacity: 0.85; }
}

.celebracion-badge {
  position: absolute;
  top: 40%;
  left: 50%;
  background: var(--tinta);
  color: var(--crema);
  padding: 0.85rem 1.5rem;
  border-radius: var(--r-pilla);
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-subtitulo);
  white-space: nowrap;
  box-shadow: 0 12px 34px rgba(43, 43, 38, 0.3);
  animation: badgeInOut 2.4s ease forwards;
}

@keyframes badgeInOut {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  14%  { opacity: 1; transform: translate(-50%, -50%) scale(1.06); }
  26%  { transform: translate(-50%, -50%) scale(1); }
  80%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1); }
}

.anillo-progreso.pulso { animation: pulsoAnillo 0.7s ease; }

@keyframes pulsoAnillo {
  0%, 100% { stroke-width: 9; }
  50%      { stroke-width: 13; }
}

@media (prefers-reduced-motion: reduce) {
  .anillo-progreso.pulso { animation: none; }
}

/* ---------- Pantallas más grandes ---------- */

@media (min-width: 640px) {
  .titulo { font-size: var(--t-display); }
  #vista-app { padding-top: 2rem; }

  /* En tablet el contenido es una columna angosta centrada: la barra
     inferior debe alinearse con ella y no estirarse de borde a borde. */
  .nav-inferior {
    max-width: 520px;
    margin: 0 auto;
    border: 1px solid var(--linea);
    border-bottom: none;
    border-radius: 20px 20px 0 0;
  }
}

/* ============================================================
   MÓDULO SOCIO
   Selector de liga, metas calculadas, bandeja de solicitudes y
   la página pública del prospecto.
   ============================================================ */

/* ---------- Selector Socio / Coach ---------- */

.cambia-liga {
  display: flex;
  gap: 0.25rem;
  background: var(--tarjeta);
  border: 1px solid var(--linea);
  border-radius: var(--r-pilla);
  padding: 0.25rem;
  margin-bottom: 1rem;
}

.liga-tab {
  flex: 1;
  padding: 0.55rem 0.5rem;
  border-radius: var(--r-pilla);
  font-size: var(--t-cuerpo);
  font-weight: 500;
  color: var(--tinta-suave);
  min-height: 44px;
}

.liga-tab.activa {
  background: var(--verde);
  color: var(--crema);
  font-weight: 600;
}

/* ---------- Metas calculadas ---------- */

.metas-socio { margin-bottom: 1rem; }

/* Son datos de consulta, no de acción: casi nunca cambian y se miran de reojo.
   Apiladas se llevaban un tercio de la primera pantalla para decir tres
   números. En fila ocupan lo que valen, y la línea divisoria hace el trabajo
   que antes hacía el espacio en blanco. */
.metas-fila {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
}

.metas-fila .meta-cifra + .meta-cifra {
  border-left: 1px solid var(--linea);
  padding-left: 0.7rem;
}

.metas-socio .meta-cifra {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.35rem 0;
}

.metas-fila .meta-cifra {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
  padding: 0;
}

.meta-valor {
  font-family: var(--fraunces);
  font-variation-settings: 'SOFT' 0, 'WONK' 0;
  font-size: var(--t-titulo);
  font-weight: 600;
  color: var(--verde);
}

.meta-nombre { font-size: var(--t-cuerpo); color: var(--tinta-suave); }

.meta-pie { margin-top: 0.6rem; }

.metas-socio.sin-peso p { font-size: var(--t-cuerpo); }

.metas-resumen {
  display: flex;
  gap: 1.2rem;
  flex-wrap: wrap;
  margin: 0.6rem 0;
  font-size: var(--t-cuerpo);
}

.metas-resumen strong { color: var(--verde); }

/* ---------- Bandeja de solicitudes ---------- */

.sol-lista { list-style: none; }
.sol-item { margin-bottom: 0.8rem; }

.sol-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
}

.sol-nombre { font-weight: 600; font-size: var(--t-cuerpo); }

.sol-estado {
  font-size: var(--t-rotulo);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 0.2rem 0.6rem;
  border-radius: var(--r-pilla);
  white-space: nowrap;
}

.sol-nueva { background: var(--verde); color: var(--crema); }
.sol-contactada { background: var(--linea); color: var(--tinta); }
.sol-agendada { background: #4F7A52; color: #fff; }
.sol-fallida { background: #B4553F; color: #fff; }
.sol-descartada { background: transparent; color: var(--tinta-suave); border: 1px solid var(--linea); }

.sol-linea { font-size: var(--t-apoyo); margin-bottom: 0.2rem; }
.sol-tel { color: var(--tinta-suave); }

.sol-acciones {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.75rem;
}

.sol-btn {
  flex: 1 1 auto;
  min-width: 44%;
  text-align: center;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
}

.sol-secundarias { justify-content: space-between; margin-top: 0.4rem; }
.sol-secundarias .link-texto { font-size: var(--t-apoyo); min-height: 44px; }

/* ---------- Enlace de prospección ---------- */

.codigo-enlace {
  font-family: var(--inter);
  font-size: var(--t-apoyo);
  word-break: break-all;
  color: var(--verde);
}

/* ---------- Página pública del prospecto ---------- */

.publico-cont {
  max-width: 560px;
  margin: 0 auto;
  padding: 1rem 1rem 3rem;
}

/* Vive en esta sección por historia, pero lo usa la pantalla Hoy. El borde
   iba escrito a mano en un ladrillo que no es --ladrillo: dos colores casi
   iguales para el mismo trabajo, que es lo que esta paleta vino a terminar.
   5,3:1 sobre la tarjeta. */
.aviso-contacto {
  border-left: 4px solid var(--ladrillo);
  margin-bottom: 1rem;
}

/* El prospecto no tiene barra inferior: la página no la necesita. */
body.publico { padding-bottom: 0; }

/* ---------- Portada del enlace público ---------- */
/* Es lo primero que ve alguien que llega desde una historia: tiene que
   explicarse solo en tres segundos y pedir la cuenta sin rodeos.

   No lo hacía. Medido en un teléfono de 375×667: la cabecera —logo de 112px,
   nombre de la marca y «Te invitó Fulana»— se llevaba 237px, el 36% de lo que
   se ve, sin que la página dijera una sola palabra de qué es esto. El botón de
   crear la cuenta caía en el píxel 745, o sea 79 por debajo del pliegue.

   Lo que había escrito acá era la portada de otro diseño —el de pedir la
   evaluación sin cuenta— que se quitó cuando esos permisos se cerraron. Nunca
   la pintó nadie: eran reglas para clases que ningún archivo escribía. */

/* La marca, en una línea: 40px y el nombre al lado. Quien llega por un enlace
   de referido no viene por la marca, que no conoce; viene por la persona. */
.portada-marca {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.25rem 0 1.1rem;
}
.portada-marca img { width: 40px; height: 40px; }
.portada-marca span {
  font-family: var(--fraunces);
  font-variation-settings: 'SOFT' 0, 'WONK' 0;
  font-size: var(--t-cuerpo);
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* El titular lleva el nombre de quien invita, y por eso es el titular. */
.portada-titular {
  font-family: var(--fraunces);
  font-variation-settings: 'SOFT' 0, 'WONK' 0;
  font-size: var(--t-titulo);
  font-weight: 600;
  line-height: 1.15;
  text-wrap: balance;
  margin-bottom: 0.6rem;
}
.portada-titular em { font-style: normal; color: var(--verde); }

.portada-pitch {
  font-size: var(--t-cuerpo);
  color: var(--tinta-suave);
  margin-bottom: 1.2rem;
  max-width: 34ch;
}

/* La muestra: tres hábitos reales, ya marcados.

   La regla vieja sigue en pie —si alguien puede marcar sin registrarse, no le
   queda razón para registrarse— y una muestra que no responde no la rompe: el
   tic va dibujado en un <svg>, no hay ningún <input> aquí dentro.

   Van marcados y no vacíos porque una casilla vacía dice «rellena esto» y una
   marcada dice «así se ve un día que contó», que es lo que hay que explicar en
   tres segundos. Además, el borde de una casilla vacía es --linea sobre la
   tarjeta: 1,36:1, que a pleno sol no está. */
.portada-muestra { margin-top: 1.1rem; }
.portada-muestra ul { list-style: none; display: grid; gap: 0.7rem; }
.portada-muestra li {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: var(--t-apoyo);
}
.portada-tic {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  border-radius: var(--r-control);
  background: var(--verde);
  display: flex;
  align-items: center;
  justify-content: center;
}
.portada-tic svg { width: 15px; height: 15px; }
.portada-pie-muestra {
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  margin-top: 0.8rem;
}

/* ---------- La invitación a la evaluación ---------- */
/* Discreta mientras la persona es nueva; con cuerpo recién al tercer día. */

.eval-linea {
  text-align: center;
  margin-top: 18px;
}
.eval-linea .link-texto {
  display: inline;
  padding: 0;
  margin: 0;
  width: auto;
}

/* El borde nombraba un token que no existía en ninguna parte, así que esta
   tarjeta se pintaba con el color de respaldo: #6B7A4F, un verde que no está
   en la paleta y que no eligió nadie. Lo malo del var() con respaldo es
   justamente eso — no se ve roto, se ve bien, solo que de otro color.
   pruebas/tokens.mjs no lo veía porque solo miraba los var() sin respaldo;
   ahora mira los dos. */
.invita-eval {
  margin-top: 20px;
  border: 1px solid var(--verde);
}
.invita-eval .btn-primario { margin-top: 12px; }
.invita-eval #eval-form { margin-top: 14px; }

.pros-item .sol-estado.sol-descartada { opacity: 0.7; }

/* La tarjeta de metas sin datos: es una invitación, no un aviso de error. */
.metas-socio.sin-peso .btn-secundario { margin-top: 0.7rem; }

/* ---------- Relleno de las tarjetas del módulo socio ----------
   Estas reglas nacieron como parche, cuando `.tarjeta` no traía relleno y las
   tarjetas de Hoy salían con el texto pegado al borde. Ya no hacen falta: el
   valor por defecto está en `.tarjeta`. Se dejan porque son el mismo 1.2rem y
   borrarlas no cambiaría nada — pero NO son el patrón a copiar. Una tarjeta
   nueva no necesita línea acá. */

.metas-socio,
.invita-eval,
.aviso-contacto { padding: 1.2rem; }

#vista-solicitudes .tarjeta { padding: 1.2rem; }

.publico-cont .tarjeta { padding: 1.2rem; }
.publico-cont .tarjeta.lista-habitos { padding: 0; }

/* La portada del enlace es la pantalla de entrada de siempre. */
.publico-cont .auth-header { text-align: center; padding: 1.5rem 0 0.5rem; }
.publico-cont .auth-card { padding: 1.5rem; }

/* El formulario de la evaluación, en su versión discreta: es una tarjeta
   suelta dentro de Hoy, así que necesita su propio margen interior. */
#eval-form.tarjeta { padding: 1.2rem; margin-top: 0.6rem; }
.invita-eval #eval-form { padding: 0; }

/* Ajuste manual de metas, dentro de la ficha de cada persona. */
.ajuste-metas { margin-top: 0.8rem; }
.ajuste-metas summary {
  cursor: pointer;
  font-size: var(--t-apoyo);
  font-weight: 600;
  color: var(--verde);
}
.ajuste-metas > *:not(summary) { margin-top: 0.6rem; }

.metas-tres {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.6rem;
}
.metas-tres .campo { margin-bottom: 0; }
.metas-tres label { font-size: var(--t-apoyo); }
.metas-tres input { padding: 0.5rem 0.6rem; }

@media (max-width: 420px) {
  .metas-tres { grid-template-columns: 1fr 1fr; }
}

/* ---------- Clubes y ligas de amigos ---------- */

/* ---------- Diario de comidas ---------- */

#vista-hoy .diario-caja { padding: 1rem 1.1rem; }

.diario-lista {
  list-style: none;
  margin: 0 0 .9rem;
  padding: 0;
}

/* El momento va de rótulo ARRIBA, no de columna al lado.
   Medido a 375px: con el momento ocupando 5,6rem fijos a la izquierda, al
   texto de la comida le quedaban 104px de ancho. «2 huevos revueltos, palta y
   una tostada integral» se partía en seis líneas y la fila medía 135px. Es lo
   mismo que le pasaba a la fila del ranking en la fase 3: una columna de ancho
   fijo se come el sitio del único dato que la persona escribió.

   Se resuelve sin tocar el JS a propósito. Este markup está escrito DOS veces
   —checkins.js para editarlo y diario.js para leerlo—, que es justo contra lo
   que avisa el comentario de diario.js, así que un arreglo que solo vive en la
   hoja no puede aplicarse a medias. */
.diario-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  padding: .5rem 0;
  border-bottom: 1px solid var(--linea);
}

.diario-item:last-child { border-bottom: 0; }

/* Dos renglones: arriba el rótulo con los gramos y el aspa a la derecha, y
   debajo la comida ocupando todo el ancho.

   El `order` se declara sobre TODOS los hijos y no solo sobre los cuatro que
   se conocen: con la IA encendida la fila gana un <details> de macros y un
   botón, y lo que no esté nombrado acá tiene que caer abajo y a lo ancho, que
   es el sitio seguro. Al revés —nombrar solo los conocidos— el elemento nuevo
   se cuela en el renglón del aspa. */
.diario-item > * { order: 2; flex: 0 0 100%; }

.diario-momento {
  order: 0;
  flex: 1 1 auto;
  font-size: var(--t-rotulo);
  font-weight: 600;
  color: var(--tinta-suave);
}

.diario-texto {
  order: 1;
  flex: 0 0 100%;
  min-width: 0;
  font-size: var(--t-cuerpo);
  line-height: 1.45;
  word-break: break-word;
}

/* ---------- Página de privacidad ---------- */
/* Es un documento, no una pantalla de la app: ancho de lectura cómodo y
   nada más. Se lee una vez, y tiene que poder leerse. */

.legal {
  max-width: 44rem;
  margin: 0 auto;
  padding: 2rem 1.1rem 4rem;
}

.legal .titulo { margin-bottom: .2rem; }

.legal-fecha {
  margin-bottom: 1.8rem;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
}

.legal h2 {
  margin: 2rem 0 .6rem;
  font-family: var(--fraunces);
  font-size: var(--t-subtitulo);
  color: var(--verde);
}

.legal p { margin-bottom: .8rem; line-height: 1.6; }

.legal ul {
  margin: 0 0 1rem 1.1rem;
  padding: 0;
}

.legal li { margin-bottom: .5rem; line-height: 1.6; }

.legal-destacado { padding: 1rem 1.1rem; margin-bottom: .8rem; }
.legal-destacado p:last-child { margin-bottom: 0; }

/* La tabla es lo más ancho del documento. En un teléfono se desplaza sola
   en vez de empujar la página entera. */
.legal-tabla-caja {
  overflow-x: auto;
  margin-bottom: .8rem;
}

.legal-tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-cuerpo);
}

.legal-tabla th,
.legal-tabla td {
  padding: .6rem .7rem;
  text-align: left;
  border-bottom: 1px solid var(--linea);
  vertical-align: top;
}

.legal-tabla th {
  font-size: var(--t-apoyo);
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--tinta-suave);
}

.legal-tabla td:first-child { white-space: nowrap; }

.legal-volver { margin-top: 2.5rem; }
.legal-enlace { margin: 1.5rem 0 0; text-align: center; }

/* Aceptar la política al registrarse. Casilla de verdad y no una frase al
   pie: estos son datos de salud, y ahí el consentimiento tiene que ser un
   acto, no una suposición. */
.campo-acepto {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  margin-bottom: 1rem;
  font-size: var(--t-apoyo);
  line-height: 1.5;
}

.campo-acepto input {
  flex: 0 0 auto;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: .12rem;
  accent-color: var(--verde);
}

.campo-acepto label { cursor: pointer; }

/* ---------- Gratitud del día ---------- */
/* Va debajo de su hábito, con la misma sangría que el resto del contenido
   que cuelga de un hábito (el audio, el libro). */

/* La sangría es EXACTAMENTE la de .habito-extra, que es lo que ya cuelga de
   un hábito (el audio del día, el libro del mes): el ancho de la casilla más
   el relleno y el hueco de la fila. Calcularla a ojo la dejaba a medio camino
   entre la casilla y el texto, y por la derecha se pasaba de la fila.
   Si algún día cambia el tamaño de .check-visual, cambian las dos juntas. */
.gratitud-caja {
  display: grid;
  gap: .5rem;
  margin: .1rem 1.1rem 0 calc(1.1rem + 28px + 0.9rem);
  /* Relleno abajo y no margen: un margen se colapsa hacia fuera del <li> y
     el espacio termina al final de la lista en vez de bajo el botón. Hoy no
     se nota porque la gratitud es el último hábito; el día que deje de serlo,
     el hueco aparecería en el sitio equivocado. */
  padding-bottom: .9rem;
}

.gratitud-caja textarea {
  width: 100%;
  padding: .55rem .7rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--crema);
  color: var(--tinta);
  font-family: var(--inter);
  font-size: var(--t-cuerpo);
  line-height: 1.45;
  resize: vertical;
}

.gratitud-caja textarea:focus-visible {
  outline: 2px solid var(--verde);
  outline-offset: 1px;
}

/* .btn-secundario trae width:100%, que acá lo dejaría del ancho del campo.
   Un "Anotar" de borde a borde bajo un cuadro de texto se lee como el botón
   principal de la pantalla, y no lo es. */
.gratitud-caja .btn-secundario {
  justify-self: start;
  width: auto;
  padding-left: 1.4rem;
  padding-right: 1.4rem;
}

.diario-faltan { font-weight: 600; }

/* ---------- Reto personal ---------- */

/* El relleno acá NO es para que la tarjeta tenga aire —eso ya lo da
   `.tarjeta`— sino porque estas dos quieren una medida distinta: se copia la de
   .resumen-hoy, 1.25/1.4, y no el 1.2 general. La tarjeta del reto va justo
   encima del anillo, y dos bordes de texto casi alineados se ven peor que dos
   claramente distintos. Esa es la única razón válida para escribir relleno en
   una tarjeta: querer otro número, no querer que exista. */
.reto,
.reto-vacio {
  padding: 1.25rem 1.4rem;
  margin-bottom: .8rem;
}

.reto-titulo {
  margin: 0;
  font-size: var(--t-apoyo);
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--tinta-suave);
}

/* El número grande, el que se fotografía. */
.reto-dia {
  margin: .1rem 0 .6rem;
  font-family: var(--fraunces);
  font-size: var(--t-titulo);
  line-height: 1.1;
  color: var(--verde);
}

.reto-barra {
  height: 6px;
  border-radius: var(--r-pilla);
  background: var(--linea);
  overflow: hidden;
}

.reto-barra-llena {
  height: 100%;
  border-radius: var(--r-pilla);
  background: var(--verde);
  transition: width .4s ease;
}

.reto-mensaje {
  margin: .6rem 0 0;
  font-size: var(--t-cuerpo);
  line-height: 1.45;
}

/* Mientras el día esté pendiente, el mensaje pesa más. No es alarma roja:
   la app no está retando a nadie, le está recordando lo que tiene ganado. */
.reto-riesgo .reto-mensaje {
  font-weight: 600;
  color: var(--verde);
}

/* Cuándo empieza y cuándo termina, a la vista. Sin esto, "Día 3 de 90" obliga
   a hacer la resta de cabeza para saber si el reto empezó el lunes. */
.reto-fechas {
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
  margin: .1rem 0 .7rem;
}

.reto-acciones {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin-top: 0.4rem;
}

.reto-datos {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem 1.1rem;
  margin: .7rem 0 0;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
}

.reto-datos strong {
  color: var(--tinta);
  font-variant-numeric: tabular-nums;
}

/* Ritmo interior. El reset global deja los <p> sin margen y .nota-campo solo
   trae 5,6 px arriba: el título quedaba respirando encima del párrafo.
   Tiene que superar esos 5,6 px o los márgenes se colapsan entre hermanos y
   el valor más chico no hace nada. */
.reto-vacio > p:first-child { margin-bottom: .6rem; }

.reto .link-texto,
.reto-vacio .btn-secundario { margin-top: 1rem; }

/* ---------- Ver la contraseña ---------- */

/* Envuelve solo al input, así el botón se centra contra él y no contra el
   campo entero, que arriba lleva la etiqueta. Lo crea clave.js. */
.campo-clave {
  position: relative;
  display: block;
}

/* Sitio para el botón, para que la contraseña no pase por debajo. */
.campo-clave input { padding-right: 2.9rem; }

.ojo-clave {
  position: absolute;
  right: .55rem;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: var(--r-control);
  background: none;
  color: var(--tinta-suave);
  cursor: pointer;
  /* 44px de área táctil sin agrandar el botón a la vista. */
  -webkit-tap-highlight-color: transparent;
}

.ojo-clave::after {
  content: '';
  position: absolute;
  inset: -.6rem;
}

.ojo-clave:hover { color: var(--verde); }

.ojo-clave:focus-visible {
  outline: 2px solid var(--verde);
  outline-offset: 1px;
}

/* ---------- Medidas del cuerpo ---------- */

.medidas-grilla {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .4rem .7rem;
  margin-bottom: .8rem;
}

@media (min-width: 520px) {
  .medidas-grilla { grid-template-columns: repeat(3, 1fr); }
}

.medidas-historial { margin-top: .8rem; }
.medidas-historial summary { cursor: pointer; font-size: var(--t-apoyo); }

.medidas-lista {
  list-style: none;
  margin: .6rem 0 0;
  padding: 0;
}

.medidas-lista li {
  padding: .45rem 0;
  border-bottom: 1px solid var(--linea);
}

.medidas-lista li:last-child { border-bottom: 0; }

.med-fecha {
  display: block;
  font-size: var(--t-apoyo);
  font-weight: 600;
  color: var(--tinta-suave);
}

.med-datos {
  font-size: var(--t-apoyo);
  line-height: 1.45;
}

/* La tarjeta que se sube a Instagram. Se mira una vez cada muchas semanas,
   así que el titular tiene que leerse antes que cualquier otra cosa. */
.comp-titulo {
  margin: 0;
  font-size: var(--t-apoyo);
  font-weight: 600;
  color: var(--tinta-suave);
}

.comp-fechas {
  margin: .1rem 0 .6rem;
  font-size: var(--t-apoyo);
  opacity: .75;
}

.comp-titular {
  margin: 0 0 .7rem;
  font-size: var(--t-subtitulo);
  font-weight: 700;
  line-height: 1.2;
}

.comp-lista {
  list-style: none;
  margin: 0;
  padding: 0;
}

.comp-fila {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  padding: .4rem 0;
  border-bottom: 1px solid var(--linea);
  font-size: var(--t-apoyo);
}

.comp-fila:last-child { border-bottom: 0; }

.comp-parte {
  flex: 0 0 auto;
  min-width: 4.6rem;
  font-weight: 600;
}

.comp-antes {
  flex: 1 1 auto;
  opacity: .8;
}

.comp-delta {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

/* Solo se destaca lo que sabemos que es progreso. Ver el porqué en
   medidas.js: a quien entrena fuerza, un brazo que crece es el objetivo.
   Se usa el verde de la app y no un verde de semáforo: la paleta entera es
   crema y verde, y un verde prestado se ve como un error. */
.comp-buena .comp-delta { color: var(--verde); }
.comp-buena .comp-parte { color: var(--verde); }

/* ---------- Mi pizarra ---------- */
/* La pizarra del club, personal. Solo diferencias: nunca un peso. */

.pizarra { margin-bottom: .8rem; }

.pz-lista {
  list-style: none;
  margin: .3rem 0 0;
  padding: 0;
}

/* Se envuelve a propósito. "Grasa visceral" es una etiqueta larga y en un
   teléfono de 375 px compite con el número; dejándola envolver, el dato
   nunca se aprieta ni se corta. */
.pz-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem;
  padding: .45rem 0;
  border-bottom: 1px solid var(--linea);
  font-size: var(--t-apoyo);
}

.pz-fila:last-child { border-bottom: 0; }

.pz-parte {
  flex: 1 1 auto;
  font-weight: 600;
}

.pz-total {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

/* La segunda columna de la pizarra física: contra el pesaje anterior. Solo
   la trae el peso, y va en su propia línea para no empujar el total. */
.pz-anterior {
  flex: 1 0 100%;
  text-align: right;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}

.pz-anterior:empty { display: none; }

/* Verde y rojo son los nombres con los que se pidió y con los que se piensa,
   pero los colores son los de la casa. Ver --ladrillo. */
.pz-verde  { color: var(--verde); }
.pz-rojo   { color: var(--ladrillo); }
.pz-neutro { color: var(--tinta); }

/* Los gramos anotados a mano. Suben al renglón del rótulo, junto al aspa: la
   mayoría de las filas no los va a tener, y una columna medio vacía hace
   parecer que falta algo. */
.diario-prote {
  order: 0;
  flex: 0 0 auto;
  font-size: var(--t-apoyo);
  font-weight: 600;
  color: var(--tinta-suave);
  white-space: nowrap;
}

.diario-total {
  margin: 0 0 .9rem;
  font-size: var(--t-apoyo);
  line-height: 1.5;
}

.diario-parcial {
  display: block;
  font-size: var(--t-apoyo);
  opacity: .75;
}

/* Dentro del margen de calorías del nivel 2. Es un dato, no una felicitación:
   por eso va en el verde de la app —que es como acá se pinta lo bueno— y sin
   negrita ni icono. */
.kcal-en-rango { color: var(--verde); font-weight: 600; }

/* El aviso de que la cifra calculada quedó bajo el piso. Va en el tono de
   advertencia, no en el rojo de error: no es una falla de la persona ni de la
   app, es un caso donde hace falta alguien con criterio. */
.nota-piso {
  padding: .6rem .75rem;
  border-left: 3px solid var(--ambar);
  background: rgba(138, 106, 46, .07);
  border-radius: 0 6px 6px 0;
  line-height: 1.5;
}

/* ---------- Los macros ---------- */

/* Ocupa la fila completa debajo del texto de la comida: el desglose es una
   tabla, y meterla en la misma línea que el nombre del plato la aplastaría en
   un teléfono. `flex-basis: 100%` la baja de renglón dentro del mismo li. */
.macros {
  flex: 0 0 100%;
  margin-top: .35rem;
  font-size: var(--t-apoyo);
}

/* Hijo directo, no descendiente: adentro va otro <details> (el de corregir) y
   con el selector suelto su flecha rotaba al abrir el de afuera y se quedaba
   así, apuntando a nada. */
.macros > summary,
.macros-corregir > summary,
.plegable > summary {
  cursor: pointer;
  color: var(--tinta-suave);
  list-style: none;
}

/* El triángulo por defecto es distinto en cada navegador y en iOS queda
   enorme. Se apaga y se pone uno propio, que además rota al abrir. */
.macros > summary::-webkit-details-marker,
.macros-corregir > summary::-webkit-details-marker,
.plegable > summary::-webkit-details-marker { display: none; }

.macros > summary::after,
.macros-corregir > summary::after,
.plegable > summary::after {
  content: '▸';
  display: inline-block;
  margin-left: .3rem;
  opacity: .5;
  transition: transform .15s ease;
}

.macros[open] > summary::after,
.macros-corregir[open] > summary::after,
.plegable[open] > summary::after { transform: rotate(90deg); }

/* Lo que se fija una vez y se mira poco: el objetivo y quién ve tu pizarra.
   Nacen cerradas, y su resumen dice el ESTADO —«tu coach no la ve»— que de un
   vistazo informa más que el párrafo de política que hay dentro.

   Medido en Mi pizarra, 375px: el primer campo donde se escribe algo estaba en
   el píxel 1278, casi dos pantallas por debajo, y estas dos tarjetas eran 555
   de esos píxeles. */
/* El relleno lo pone el summary, no la tarjeta —igual que .ranking se lo dejó
   a .ranking-fila, y por lo mismo—: el summary es lo único que abre, así que
   tocar el relleno de la tarjeta no hacía nada. Con el relleno de .tarjeta la
   zona táctil eran 21px, y la guía son 44. */
.plegable { padding: 0; }
.plegable > summary {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0.5rem 1.2rem;
  font-size: var(--t-apoyo);
  font-weight: 500;
}
.plegable[open] > *:not(summary) { margin: 0.7rem 1.2rem 0; }
.plegable[open] { padding-bottom: 1.2rem; }

/* Separado del desglose por una línea: lo de arriba es lo que estimó la
   máquina, lo de abajo es donde mandas tú. */
/* El flex-basis es para cuando va suelto en la fila (comida sin números);
   anidado dentro de .macros no estorba. */
.macros-corregir {
  flex: 0 0 100%;
  margin-top: .5rem;
  padding-top: .5rem;
  font-size: var(--t-apoyo);
  border-top: 1px solid rgba(0, 0, 0, .08);
}

.macros-corregir label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  margin-top: .35rem;
  font-size: var(--t-apoyo);
}

/* Ancho fijo y numérico: cuatro campos que saltan de tamaño según el número
   que traen se leen como un formulario roto. */
.macros-corregir input {
  width: 6rem;
  padding: .3rem .4rem;
  font: inherit;
  font-size: var(--t-cuerpo);
  text-align: right;
  border: 1px solid rgba(0, 0, 0, .18);
  border-radius: var(--r-control);
}

.macros-corregir button {
  margin-top: .6rem;
  width: 100%;
  padding: .45rem;
  font: inherit;
  font-size: var(--t-apoyo);
  color: var(--crema);
  background: var(--verde);
  border: 0;
  border-radius: var(--r-control);
  cursor: pointer;
}

.macros-corregir button:disabled { opacity: .5; cursor: default; }

/* La marca de que algo quedó ambiguo. Un punto, no un signo de exclamación:
   avisa sin acusar a quien escribió "un plato de arroz". */
.macros-duda {
  color: var(--ambar);
  font-weight: 700;
}

.macros-tabla {
  width: 100%;
  margin: .5rem 0 .35rem;
  border-collapse: collapse;
  font-size: var(--t-apoyo);
}

.macros-tabla td {
  padding: .22rem 0;
  border-bottom: 1px solid rgba(0, 0, 0, .06);
  vertical-align: top;
}

.macros-tabla td:not(:first-child) {
  text-align: right;
  white-space: nowrap;
  padding-left: .5rem;
}

.macros-tabla tr:last-child td { border-bottom: 0; }

.macros-cantidad {
  display: block;
  font-size: var(--t-rotulo);
  opacity: .7;
}

.macros-precisar { color: var(--ambar); }

.macros-pedir {
  flex: 0 0 100%;
  margin-top: .35rem;
  padding: .25rem 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--t-apoyo);
  text-align: left;
  color: var(--tinta-suave);
  text-decoration: underline;
  cursor: pointer;
}

.macros-pedir:disabled {
  opacity: .6;
  cursor: default;
  text-decoration: none;
}

/* Borra una comida y no pregunta. Medía 22,7 × 27,2px, que para un control
   destructivo en un teléfono es la mitad de lo que hace falta: el dedo cae al
   lado, o cae encima cuando quería tocar el texto.
   La zona crece a 44; el aspa sigue del mismo tamaño. El margen negativo
   arriba y abajo es para que la fila no engorde por esto. */
.diario-borrar {
  order: 0;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  margin: -.5rem 0;
  background: none;
  border: 0;
  padding: 0;
  font-size: var(--t-cuerpo);
  color: var(--tinta-suave);
  cursor: pointer;
}

.diario-borrar:hover { color: var(--ladrillo); }

/* En móvil el select y el botón se van abajo; el texto ocupa todo el ancho,
   que es donde de verdad se escribe. */
.diario-nuevo {
  display: grid;
  grid-template-columns: 1fr;
  gap: .5rem;
  margin-bottom: .6rem;
}

/* El ancho y la forma ya vienen de las reglas globales de campo. */

@media (min-width: 480px) {
  .diario-nuevo {
    grid-template-columns: auto 1fr 7rem auto;
    align-items: center;
  }
}

.diario-coach { margin-top: .6rem; }
.diario-coach summary { cursor: pointer; font-size: var(--t-apoyo); }
.diario-dia { margin-top: .7rem; }

.diario-fecha {
  margin: 0 0 .2rem;
  font-size: var(--t-apoyo);
  font-weight: 600;
  color: var(--verde);
}

.liga-acciones {
  margin: .2rem 0 1.1rem;
  text-align: center;
}

/* Salir o borrar no compiten con "Crear": se ven como un enlace, no como
   un botón, para que nadie los toque de pasada. */
.btn-texto {
  background: none;
  border: 0;
  padding: .4rem .6rem;
  font: inherit;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
  text-decoration: underline;
  cursor: pointer;
}

.btn-texto:hover { color: var(--verde); }
.btn-peligro { color: var(--ladrillo); }
.btn-peligro:hover { text-decoration: underline; }

/* Borrar la cuenta va plegado y al final. No escondido —tiene que poder
   encontrarse— pero tampoco al lado de "Cerrar sesión", que es lo que la
   gente busca de verdad cuando llega hasta abajo. */
/* .tarjeta no trae relleno: cada uso pone el suyo. La de "Cerrar sesión" no
   lo necesita porque solo lleva un botón de ancho completo; esta sí, que
   tiene texto y un campo. */
/* El relleno lo pone `#vista-perfil .tarjeta`, que gana por especificidad.
   No se repite acá para no dejar una declaración muerta que confunda al
   próximo que venga a cuadrar esta tarjeta. */
.borrar-card {
  margin-top: .8rem;
  border-color: rgba(154, 91, 78, .35);
}

.borrar-card summary {
  cursor: pointer;
  font-size: var(--t-cuerpo);
  font-weight: 600;
  color: var(--ladrillo);
}

.borrar-card .campo { margin-top: .8rem; }

.borrar-card .btn-peligro {
  width: 100%;
  padding: .7rem 1rem;
  border: 1px solid rgba(154, 91, 78, .45);
  border-radius: var(--r-superficie);
  background: none;
  font-family: var(--inter);
  font-size: var(--t-cuerpo);
  font-weight: 600;
  cursor: pointer;
}

.liga-estado {
  margin-bottom: .9rem;
  text-align: center;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
}

.liga-cerrada { color: var(--verde); }

.rank-nivel {
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
  font-weight: 500;
}

.lista-clubes {
  list-style: none;
  margin: 0 0 0.8rem;
  padding: 0;
  font-size: var(--t-cuerpo);
}
.lista-clubes li { padding: 0.35rem 0; border-bottom: 1px solid var(--linea); }
.lista-clubes li:last-child { border-bottom: 0; }

.ranking-lista { list-style: none; margin: 0; padding: 0; }
/* Acá vivían .ranking-item, .soy-yo y .rank-puesto/-nombre/-puntos: la fila
   del ranking de antes de la fase 3. La reescribió .ranking-fila y estas se
   quedaron. */

.liga-crear { padding: 1.2rem; margin-top: 1rem; }

/* ---------- La foto del día ---------- */

/* Decía var(--tinta-suave, …), y --tinta-suave no existe: el pie de la foto
   se pintaba de un gris tibio suyo en vez del color del texto de apoyo. */
.foto-cuenta { margin: 8px 0 12px; color: var(--tinta-suave); }

/* La cámara ocupa la pantalla entera y sale del flujo de la página.
   Encuadrar un cuerpo entero en un recuadro con la barra de pestañas debajo
   no se puede: hay que ver el sitio completo para calzar con el fantasma. */
.foto-full {  /* sin-tema: todo lo de dentro va sobre la foto */
  position: fixed;
  inset: 0;
  z-index: 60;
  background: #000;  /* sin-texto: el lienzo de la camara; sus hijos ponen su color */
  overflow: hidden;
}

/* `contain` y NO `cover`, y esto importa más de lo que parece.
   Con `cover` el vídeo se recorta para llenar la pantalla, pero el canvas
   captura el cuadro ENTERO: lo que calzas con el fantasma no sería lo que
   queda guardado. Prefiero las bandas negras a una alineación que miente. */
/* El MARCO tiene la proporcion real de la camara y se centra en la pantalla.
   Todo lo que va dentro --video, fantasma, cuadricula-- comparte esa caja.

   Esto es lo que hace honesta a la cuadricula: si las lineas se dibujaran
   sobre la pantalla completa, con bandas negras arriba y abajo, sus tercios
   no serian los tercios de la foto. Estarian mintiendo justo donde mas
   importa, que es al encuadrar. */
.foto-marco {
  position: absolute;
  inset: 0;
  margin: auto;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: 9 / 16;   /* provisional; se ajusta al abrir la camara */
}

.foto-marco video,
.foto-marco .foto-fantasma,
.foto-marco .foto-revision {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;   /* el marco YA tiene su proporcion: no recorta nada */
}

.foto-marco .foto-fantasma {
  /* Bastante para reconocer la silueta, poco para tapar lo que encuadras. */
  opacity: .35;
  pointer-events: none;
}

.foto-reloj {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 96px;  /* fuera-de-escala: cuenta regresiva a pantalla completa sobre la cámara */
  font-weight: 700;
  color: #fff;  /* sin-tema: va sobre la foto */
  text-shadow: 0 2px 18px rgba(0, 0, 0, .7);
  pointer-events: none;
}

.foto-barra-alta {
  position: absolute;
  top: 0; left: 0; right: 0;
  display: flex;
  justify-content: space-between;
  padding: calc(env(safe-area-inset-top, 0px) + 12px) 16px 12px;
}

.foto-redondo {
  width: 44px; height: 44px;
  border: 0; border-radius: var(--r-circulo);
  background: rgba(0, 0, 0, .45);
  color: #fff; font-size: var(--t-subtitulo); line-height: 1;  /* sin-tema: va sobre la foto */
  backdrop-filter: blur(6px);
}

.foto-barra-baja {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  padding: 14px 16px calc(env(safe-area-inset-bottom, 0px) + 18px);
  background: linear-gradient(to top, rgba(0, 0, 0, .72), rgba(0, 0, 0, 0));
  text-align: center;
}

.foto-pista {
  color: #fff;  /* sin-tema: va sobre la foto */
  font-size: var(--t-apoyo);
  margin: 0 0 12px;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .8);
}

.foto-esperas { display: flex; justify-content: center; gap: 8px; margin-bottom: 16px; }

.foto-espera {
  border: 0; border-radius: var(--r-pilla);
  padding: 8px 16px;
  background: rgba(255, 255, 255, .2);
  color: #fff; font: inherit; font-size: var(--t-apoyo);  /* sin-tema: va sobre la foto */
  backdrop-filter: blur(6px);
}

.foto-espera.activa { background: #fff; color: #2c2a24; font-weight: 600; }

/* El obturador redondo de siempre. Grande a propósito: se aprieta con el
   pulgar, a veces con prisa antes de correr a las marcas del suelo. */
.foto-obturador {
  width: 74px; height: 74px;
  border: 4px solid rgba(255, 255, 255, .85);
  border-radius: var(--r-circulo);
  background: #fff;  /* sin-texto: el obturador es un círculo, no lleva letras */
  box-shadow: 0 0 0 3px rgba(0, 0, 0, .25);
}

.foto-obturador:active { transform: scale(.94); }

.foto-decidir { display: flex; gap: 12px; align-items: center; justify-content: center; }
.foto-decidir .btn-texto { color: #fff; }  /* sin-tema: va sobre la foto */
.foto-decidir .btn-primario { flex: 0 0 auto; padding: 12px 28px; }

/* Sin esto el fondo se desplaza detrás de la cámara al arrastrar. */
body.sin-scroll { overflow: hidden; }

/* La cuadrícula de tercios, la misma que trae la cámara del teléfono.
   Sirve para dos cosas distintas: colocar el teléfono siempre igual, y
   colocarte tú siempre en el mismo tercio del encuadre. */
.foto-rejilla {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* Dos líneas verticales y dos horizontales, en los tercios. Un degradado
     por eje sale más barato que cuatro elementos, y no hay nada que alinear
     a mano cuando el marco cambia de proporción. */
  background-image:
    linear-gradient(to right,
      transparent calc(33.333% - 0.5px), rgba(255, 255, 255, .38) calc(33.333% - 0.5px),
      rgba(255, 255, 255, .38) calc(33.333% + 0.5px), transparent calc(33.333% + 0.5px),
      transparent calc(66.667% - 0.5px), rgba(255, 255, 255, .38) calc(66.667% - 0.5px),
      rgba(255, 255, 255, .38) calc(66.667% + 0.5px), transparent calc(66.667% + 0.5px)),
    linear-gradient(to bottom,
      transparent calc(33.333% - 0.5px), rgba(255, 255, 255, .38) calc(33.333% - 0.5px),
      rgba(255, 255, 255, .38) calc(33.333% + 0.5px), transparent calc(33.333% + 0.5px),
      transparent calc(66.667% - 0.5px), rgba(255, 255, 255, .38) calc(66.667% - 0.5px),
      rgba(255, 255, 255, .38) calc(66.667% + 0.5px), transparent calc(66.667% + 0.5px));
}

/* Redundante desde que `.tarjeta` trae relleno: es el mismo 1.2rem. Se deja
   como recordatorio de para qué se escribió — esta tarjeta se veía bien en
   Perfil y quedó sin aire al mudarse a Hoy, con el contenido tocando los
   bordes y el botón a 1 px del fondo. Mudar una tarjeta de vista ya no puede
   hacer eso. */
.foto-tarjeta {
  padding: 1.2rem;
  margin-bottom: 0.8rem;
}

/* La nota va pegada arriba: el relleno de la tarjeta ya la separa del borde. */
.foto-tarjeta .nota-visible { margin-top: 0; }

/* ---------------------------------------------------------------------------
   El diario de ejercicios
   --------------------------------------------------------------------------- */

/* El temporizador arriba y siempre visible: se toca entre serie y serie, con
   una mano y sin buscarlo. */
.descanso {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding-bottom: .6rem;
  margin-bottom: .6rem;
  border-bottom: 1px solid var(--linea);
}

.descanso-fila {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
}

/* Tabular para que los dígitos no bailen al bajar de 1:00 a 0:59. */
.descanso-reloj {
  font-family: var(--fraunces);
  font-size: var(--t-titulo);
  font-variant-numeric: tabular-nums;
  min-width: 3.2rem;
  color: var(--tinta-suave);
}

.descanso[data-corriendo="si"] .descanso-reloj { color: var(--verde); }

.descanso-botones {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem;
}

.descanso-botones button {
  padding: .3rem .5rem;
  font: inherit;
  font-size: var(--t-apoyo);
  color: var(--verde);
  background: transparent;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  cursor: pointer;
}

.descanso-botones button:active { background: var(--crema); }

/* Parar solo tiene sentido con algo corriendo. Oculto y no deshabilitado: un
   botón gris permanente es ruido en una fila que ya tiene seis. */
.descanso-parar { display: none; }
.descanso[data-corriendo="si"] .descanso-parar { display: inline-block; }

.descanso-nota { margin: 0; }

.ejercicio-lista {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ejercicio + .ejercicio {
  margin-top: .7rem;
  padding-top: .7rem;
  border-top: 1px solid var(--linea);
}

.ejercicio-cabeza {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .5rem;
  flex-wrap: wrap;
}

/* El número del ejercicio dentro del día. En una superserie se repite: ese
   número compartido ES lo que dice que van juntos, así que no lleva adorno
   más allá de la etiqueta de al lado. */
.ejercicio-num {
  flex: 0 0 auto;
  min-width: 1.5rem;
  font-family: var(--fraunces);
  font-weight: 600;
  color: var(--tinta-suave);
}

.ejercicio-num + strong { flex: 1 1 auto; }

.ejercicio-super {
  flex: 0 0 auto;
  font-size: var(--t-rotulo);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--tinta-suave);
  border: 1px solid var(--linea);
  border-radius: var(--r-pilla);
  padding: .1rem .45rem;
}

/* El dato que justifica la función entera, así que se lee sin abrir nada. */
.ejercicio-ultima,
.ejercicio-primera {
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
}

.ejercicio-ultima em { font-style: normal; opacity: .75; }

.serie-lista {
  list-style: none;
  margin: .4rem 0 .3rem;
  padding: 0;
}

.serie {
  display: flex;
  align-items: center;
  gap: .45rem;
  padding: .22rem 0;
  font-size: var(--t-apoyo);
  border-bottom: 1px solid rgba(0, 0, 0, .05);
}

.serie-num {
  width: 1.3rem;
  height: 1.3rem;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  font-size: var(--t-rotulo);
  color: var(--verde);
  background: var(--crema);
  border-radius: var(--r-circulo);
}

/* La aproximación se ve más liviana que la efectiva, porque lo es. Sin color
   propio: dos tonos del mismo verde bastan y no inventan un semáforo. */
.serie-tipo {
  flex: 0 0 4.2rem;
  font-size: var(--t-rotulo);
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--tinta-suave);
}

.serie-datos { flex: 1 1 auto; }

.serie-borrar {
  flex: 0 0 auto;
  padding: 0 .3rem;
  font: inherit;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.serie-nueva {
  display: flex;
  gap: .35rem;
  margin-top: .35rem;
}

.serie-nueva select,
.serie-nueva input {
  padding: .35rem .4rem;
  font: inherit;
  font-size: var(--t-cuerpo);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--campo);
  color: var(--tinta);
  min-width: 0;
}

.serie-nueva select { flex: 1 1 6rem; }
.serie-nueva input { flex: 1 1 3.5rem; text-align: right; }

.serie-nueva button {
  flex: 0 0 auto;
  padding: .35rem .6rem;
  font: inherit;
  font-size: var(--t-apoyo);
  color: var(--crema);
  background: var(--verde);
  border: 0;
  border-radius: var(--r-control);
  cursor: pointer;
}

.serie-nueva button:disabled { opacity: .5; }

.ejercicio-agregar { margin-top: .6rem; font-size: var(--t-apoyo); }

.ejercicio-agregar > summary {
  cursor: pointer;
  color: var(--tinta-suave);
}

.ejercicio-agregar label {
  display: block;
  margin: .5rem 0;
  font-size: var(--t-apoyo);
}

.ejercicio-agregar select,
.ejercicio-agregar input {
  width: 100%;
  margin-top: .2rem;
  padding: .35rem .4rem;
  font: inherit;
  font-size: var(--t-cuerpo);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--campo);
  color: var(--tinta);
}

#ej-nuevo {
  display: flex;
  flex-direction: column;
  gap: .35rem;
}

#ej-nuevo button {
  padding: .4rem;
  font: inherit;
  font-size: var(--t-apoyo);
  color: var(--crema);
  background: var(--verde);
  border: 0;
  border-radius: var(--r-control);
  cursor: pointer;
}

/* El glosario de tipos de serie. Cerrado por defecto: lo necesita quien recién
   parte, y quien ya sabe no debería tropezarse con él tres veces al día. */
.ejercicio-glosario {
  margin-top: .6rem;
  padding-top: .6rem;
  font-size: var(--t-apoyo);
  border-top: 1px solid var(--linea);
}

.ejercicio-glosario > summary {
  cursor: pointer;
  color: var(--tinta-suave);
}

.ejercicio-glosario p { margin-top: .45rem; }

/* ---------- Elegir rutina y elegir el día ---------- */

/* La primera pantalla de la función: una sola decisión, con opciones grandes.
   Quien no sabe entrenar no tiene que enfrentarse a un catálogo. */
.rutina-elegir {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  margin-top: .7rem;
}

.rutina-opcion {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  padding: .7rem .9rem;
  font: inherit;
  text-align: left;
  color: var(--tinta);
  background: var(--crema);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  cursor: pointer;
}

.rutina-opcion span { font-size: var(--t-apoyo); color: var(--tinta-suave); }
.rutina-opcion:disabled { opacity: .5; }

/* El día, en un desplegable. Antes eran botones en una fila que se arrastraba:
   con seis días y nombres de dos palabras, los últimos quedaban fuera de la
   pantalla y no había nada que avisara que estaban ahí. El desplegable los
   muestra todos y ocupa una línea, que es lo que hay que gastar en esto: lo
   que se viene a usar son los ejercicios de abajo. */
.rutina-dias { margin-bottom: .6rem; }

.rutina-dias .rutina-campo { display: block; margin-bottom: .2rem; }

.rutina-dias .nota-campo { margin-top: .25rem; }

/* Lo que dice la plantilla para este ejercicio. Va debajo del nombre y antes de
   las series: es lo que se lee para saber cuánto queda por hacer. */
.ejercicio-objetivo {
  display: block;
  margin-top: .1rem;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
}

/* La opción de rutina pasó de ser un botón a ser una caja: adentro va el botón
   de elegir y el desplegable para mirarla sin elegirla. */
.rutina-opcion-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .6rem;
}

.rutina-opcion-cabeza > div { display: flex; flex-direction: column; gap: .1rem; }

.rutina-opcion-cabeza button {
  flex: 0 0 auto;
  padding: .35rem .7rem;
  font: inherit;
  font-size: var(--t-apoyo);
  color: var(--crema);
  background: var(--verde);
  border: 0;
  border-radius: var(--r-control);
  cursor: pointer;
}

.rutina-opcion-cabeza button:disabled { opacity: .5; }

/* La que sigue ahora se marca con el borde, no con relleno: es información, no
   la acción principal de la pantalla. */
.rutina-opcion.es-mia { border-color: var(--verde); }

/* Los días de la rutina elegida. Antes vivían dentro de un <details> por cada
   rutina; ahora hay un desplegable y una sola vista previa, así que la lista va
   siempre abierta: con seis rutinas, obligar a tocar para ver de qué se trata
   cada una era pedirle a alguien seis toques para comparar dos. */
.rutina-ojear-lista {
  margin: .5rem 0 0;
  padding-left: 1.2rem;
  font-size: var(--t-apoyo);
}

.rutina-ojear-lista li { margin-top: .3rem; }

/* Los ejercicios del día, en una línea gris debajo de su nombre: es lo que
   alguien viene a mirar antes de decidir. */
.rutina-ojear-lista li span {
  display: block;
  color: var(--tinta-suave);
  font-size: var(--t-rotulo);
}

.rutina-campo {
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
}

/* El desplegable a ancho completo: en un teléfono, un select angosto con
   «Hombre, 6 días · la que sigues» dentro se corta a la mitad. */
#rutina-plantilla,
#rutina-dia {
  width: 100%;
  font: inherit;
  padding: .6rem .7rem;
  color: var(--tinta);
  background: var(--tarjeta);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
}

/* Con series ya anotadas el día lo manda la base, no el teléfono. Se deja
   visible y apagado en vez de esconderlo: hay que poder leer cuál es. */
#rutina-dia:disabled { opacity: .75; }

.rutina-volver {
  display: block;
  width: 100%;
  margin-top: .7rem;
  padding: .5rem;
  font: inherit;
  font-size: var(--t-apoyo);
  color: var(--verde);
  background: transparent;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  cursor: pointer;
}

/* Qué rutina se está siguiendo, discreto y con su salida al lado. */
.rutina-cual { margin-bottom: .5rem; }

/* ============================================================
   Diálogos propios (js/util.js)
   ============================================================
   Reemplazan a los doce window.confirm y window.prompt que quedaban. Reusan
   .modal-fondo y .modal-hoja, que es lo importante: la pregunta sale del
   mismo sitio que la ficha de un día o el detalle de una comida, así que se
   lee como parte de la app y no como una interrupción del navegador. */

.dlg-cuerpo {
  font-size: var(--t-cuerpo);
  line-height: 1.55;
  margin: .9rem 0 1.1rem;
}

/* Cancelar primero y confirmar después, en columna.
   En fila, el pulgar en un teléfono llega antes al de la derecha, y el de la
   derecha suele ser el que no se deshace. En columna hay que mirar cuál es
   cuál. Es medio segundo más y es exactamente el medio segundo que falta. */
.dlg-botones {
  display: flex;
  flex-direction: column-reverse;
  gap: .1rem;
  margin-bottom: .4rem;
}

/* El botón de lo que no se deshace. Ladrillo y no el rojo de un semáforo,
   por lo mismo que el resto de la app: en una paleta de crema y verde, un
   rojo prestado se lee como un error de la app y no como una advertencia. */
.btn-primario-peligro {
  width: 100%;
  padding: 0.85rem;
  margin-top: 0.25rem;
  background: var(--ladrillo);
  color: var(--crema);
  border-radius: var(--r-control);
  font-weight: 600;
  font-size: var(--t-cuerpo);
  transition: opacity 0.15s;
}

.btn-primario-peligro:disabled { opacity: 0.6; cursor: wait; }

/* El enlace que no se pudo copiar solo. 16px obligatorios: bajo eso, iOS
   hace zoom al enfocarlo y deja la hoja corrida (ver pruebas/campos.mjs). */
.dlg-enlace {
  width: 100%;
  margin: .8rem 0 .2rem;
  padding: .7rem;
  font-size: var(--t-cuerpo);
  font-family: var(--inter);
  color: var(--tinta);
  background: var(--crema);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
}

/* ============================================================
   La cola de marcas sin enviar (js/cola.js)
   ============================================================
   Va en el tono de un dato, no de un error: la marca está guardada y va a
   llegar. Un aviso rojo acá le enseñaría a la gente a desconfiar de lo que
   acaba de marcar, que es lo contrario de lo que la cola vino a arreglar. */

.dato-cola {
  margin-top: .35rem;
  font-size: var(--t-rotulo);
  color: var(--tinta-suave);
}

/* ============================================================
   Cerrar ayer (la ventana de gracia, §24 del SQL)
   ============================================================
   Solo aparece si ayer NO cuenta y todavía hay ventana, así que puede
   permitirse ser visible: quien la ve, la necesita hoy. */

.tarjeta-ayer {
  border-left: 3px solid var(--verde-suave); /* fuera-de-escala: filo, no radio */
}

.ayer-titulo {
  font-family: var(--fraunces);
  font-weight: 600;
  font-size: var(--t-subtitulo);
  margin-bottom: .3rem;
}

/* ============================================================
   Lo poco que la paleta oscura no resuelve sola
   ============================================================
   Casi toda la app cambia de tema sin una línea extra, porque lee tokens.
   Lo que queda acá es lo que no puede leer un var(): un color dentro de un
   data: URI, y un par de superficies que en claro eran blancas de verdad. */

/* La doble flecha de los <select>. El verde profundo (%232E5E3A) sobre el
   fondo oscuro es casi invisible; esta es la misma flecha en el verde claro
   de la paleta de noche (%238FC49E es --verde en oscuro). */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'%3E%3Cpath d='M2.5 8 6 4.5 9.5 8M2.5 12 6 15.5 9.5 12' fill='none' stroke='%238FC49E' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
}

:root[data-tema="oscuro"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'%3E%3Cpath d='M2.5 8 6 4.5 9.5 8M2.5 12 6 15.5 9.5 12' fill='none' stroke='%238FC49E' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* ============================================================
   El selector de tema (Perfil)
   ============================================================ */

.tema-opciones {
  display: flex;
  gap: .4rem;
  margin-top: .6rem;
}

.tema-opcion {
  flex: 1;
  padding: .6rem .3rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--crema);
  color: var(--tinta-suave);
  font-size: var(--t-apoyo);
  font-weight: 600;
}

.tema-opcion.activa {
  border-color: var(--accion);
  color: var(--verde);
  background: var(--tarjeta);
}

/* ============================================================
   El recordatorio diario (Perfil)
   ============================================================ */

.recordatorio-hora {
  width: 100%;
  margin-top: .5rem;
  padding: .7rem;
  font-size: var(--t-cuerpo);
  font-family: var(--inter);
  color: var(--tinta);
  background: var(--crema);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
}

.recordatorio-estado {
  margin-top: .6rem;
  font-size: var(--t-apoyo);
  color: var(--tinta-suave);
}

.recordatorio-estado.conto { color: var(--verde); font-weight: 600; }

/* Las cuatro pestañas de Perfil. Reusan .tabs-periodo / .tab-periodo, que es
   el mismo control que separa semana/mes/90 días en Ranking e Historial: si
   se ve igual, no hay nada nuevo que aprender. */
.perfil-tabs { margin-bottom: 1rem; }
.perfil-grupo > .seccion-titulo:first-child { margin-top: 0; }

/* ============================================================
   Bloques que se pliegan (js/util.js · pantalla Hoy)
   ============================================================
   El título se queda siempre visible: lo que se pliega es el contenido. Un
   bloque que desaparece entero no se puede volver a encontrar. */

.plegable-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .6rem;
  width: 100%;
  padding: 0;
  text-align: left;
  background: none;
  border: none;
}

.plegable-cabecera .seccion-titulo { margin-bottom: 0; }

.plegable-flecha {
  flex-shrink: 0;
  color: var(--verde);
  font-size: var(--t-subtitulo);
  line-height: 1;
  transition: transform .18s ease;
}

.plegable-cabecera.cerrado .plegable-flecha { transform: rotate(-90deg); }
