/* ============================================================
   base.css — el sistema de diseno. Piel Indigo.

   ---- POR QUE HAY DOS HOJAS Y NO UNA ----

   Esta trae todo lo que necesita CUALQUIER pantalla: los colores,
   la tipografia, el fondo, los formularios, los botones y los
   avisos. app.css trae lo que solo usan las pantallas con sesion:
   la barra, el mazo de tarjetas, el puente, el presupuesto.

   El corte no es por prolijidad. saldo.html —la pantalla de los 8
   segundos, la que se abre desde el correo— carga SOLO esta, igual
   que antes cargaba una sola hoja. No paga ni un byte del
   dashboard por existir. Todo lo que se le agregue a app.css es
   gratis para ella.

   ---- TODO EL COLOR VIVE ARRIBA ----

   Ni una regla de mas abajo escribe un color a mano. Cambiar la
   piel entera es cambiar el bloque de variables, nada mas.
   ============================================================ */

/* ============================================================
   LA TIPOGRAFIA — Instrument Sans, elegida por Joel el 2026-08-15.

   ---- ALOJADA AQUI, NUNCA DESDE GOOGLE FONTS ----

   El archivo vive en css/fuentes/ y son 29 KB. Cargarla con el
   <link> de Google seria mas facil y esta prohibido, y el motivo no
   es la velocidad: Google Fonts le manda la IP de cada usuario a
   Google en cada carga. La politica de privacidad de este proyecto
   dice textualmente que no hay rastreadores y lista cuatro
   proveedores. Ese <link> convertiria esa frase en falsa y obligaria
   a modificar el documento legal.

   ---- SOLO EN TITULARES ----

   Los titulos usan Instrument Sans; el cuerpo, los formularios y
   TODO EL DINERO siguen con la del sistema. Tres razones:

   1. Las cifras. En un Mac la del sistema es San Francisco, cuyos
      numeros son excelentes, y ya llevan tabular-nums en ocho
      lugares. Cambiar la fuente de los montos es arriesgar el unico
      sitio donde una cifra desalineada se nota de inmediato.
   2. El peso. Un solo archivo en vez de dos o tres.
   3. El salto. Mientras la fuente baja, el texto se dibuja con la
      del sistema; si eso pasara en un parrafo largo se veria el
      salto, en un titular casi no.

   ---- UN ARCHIVO PARA TODOS LOS PESOS ----

   Es variable: cubre de 400 a 700 sin descargar una fuente por peso.
   Por eso el @font-face declara un RANGO en font-weight.

   ---- swap ----

   font-display: swap dibuja con la del sistema mientras baja, en vez
   de dejar el titulo invisible. Un titular que tarda en aparecer es
   peor que uno que cambia de forma.
   ============================================================ */
@font-face {
  font-family: 'Instrument Sans';
  src: url('fuentes/instrument-sans.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --sistema: system-ui, -apple-system, "Segoe UI", sans-serif;
  --titulares: 'Instrument Sans', var(--sistema);
  --cuerpo: var(--sistema);

  /* ---- Superficies ----

     ---- #121212 DESDE EL 2026-08-16, Y ES NEUTRO A PROPOSITO ----

     Antes el fondo era #080a18 y las superficies #10142b / #171d3c:
     un indigo muy oscuro, familia del morado de marca. Joel pidio el
     #121212 estandar, y con el la escala de grises pasa a ser NEUTRA
     entera. Dejar el fondo neutro y las cajas azuladas habria creado
     un choque de temperatura —las superficies se leen mucho mas
     azules cuando lo que tienen debajo perdio su matiz— que se ve
     como un error de color y no como una decision.

     Los tres escalones salen de la escala de Material para tema
     oscuro, que es de donde sale el #121212: 00dp para el fondo,
     01dp para la superficie y algo mas alto para la elevada. La
     separacion entre fondo y superficie quedo en 1,124 de contraste
     contra el 1,084 de antes, o sea que las cajas se despegan un
     poco MEJOR que con el indigo.

     El color de marca no se pierde: sigue en los acentos, en la
     malla del fondo y en las particulas. Lo que se neutralizo es el
     lienzo, no la pintura. */
  --fondo:            #121212;
  --superficie:       #1e1e1e;
  --superficie-alta:  #262626;
  --linea:            #333333;

  /* ---- Texto ----

     Tambien neutros, por lo mismo. Medido contra el fondo nuevo:
     la tinta da 16,00 y el gris suave 6,99, los dos por encima de
     lo que daban sus versiones azuladas. */
  --tinta:            #ededed;
  --suave:            #9e9e9e;

  /* ---- Acentos — elegidos por Joel el 2026-08-15 ----

     El morado que eligio es #4c16ca. NO se puede usar para todo, y
     esto se midio antes de ponerlo:

       texto blanco encima ............ 9,23  (excelente)
       como borde sobre el fondo ...... 2,13  (el minimo es 3)

     O sea que es un fondo de boton buenisimo y un borde inservible.
     El morado anterior tenia el problema al reves: 5,1 de borde
     pero solo 3,86 con letra blanca, y por eso existia un
     --acento-boton oscurecido como apaño. El color nuevo resuelve
     ese apaño y crea el problema contrario.

     La salida es la misma estructura de siempre pero al derecho:
     --acento-boton es el elegido, y --acento es SU HERMANO CLARO,
     el mismo matiz de 258 grados aclarado hasta dar 4,81 de
     contraste sobre el fondo. Son familia de verdad, no dos moradas
     que se parecen. */
  --acento:           #8c63ee;   /* bordes, focos, brillos */
  --acento-2:         #22d3ee;
  --acento-boton:     #4c16ca;   /* fondos solidos, con letra blanca */

  /* ---- EL NARANJA DE MARCA, y por que casi no aparece ----

     #ff6b35, elegido por Joel. Vive UNICAMENTE en la decoracion del
     heroe. Nunca en un chip, nunca en un estado, nunca en una cifra,
     y el motivo es un numero:

       --cat-deuda esta en matiz 20 grados
       este naranja esta en matiz 16

     CUATRO GRADOS. Son el mismo color, uno pastel y otro saturado.
     Si el naranja de marca sale del heroe, la persona deja de poder
     distinguir si algo naranja es de la marca o es su balde de
     deuda. Contra el ambar de "Alto" hay 24 grados, que tampoco es
     mucho.

     No se guarda como variable global a proposito: una variable
     invita a usarla, y esta no se puede usar. Vive escrita en el
     heroe de inicio.css y en ningun otro sitio. */

  /* ---- El semaforo: CUATRO tramos desde el 2026-08-15 ----

     Eran tres, y con tres todo lo que pasara del 27% era el mismo
     rojo: deber el 40% del cupo y deber el 95% se veian igual. No
     son lo mismo, ni para el puntaje ni para quien tiene que salir
     de ahi.

       --bueno   0-9    Excelente
       --bien    10-29  Bien
       --medio   30-49  Alto
       --malo    50+    Critico

     ---- COLORES DE SEMAFORO DE VERDAD, desde el 2026-08-16 ----

     Joel: "los verdes, rojos y amarillos son como palidos, no son
     un color bien llamativo que se vea claro". Tenia razon. La
     paleta anterior era una menta, una lima, un ambar y un rosa:
     colores de interfaz, elegidos para convivir. El problema es que
     este no es un adorno sino un SEMAFORO, y un semaforo tiene que
     gritar el estado desde lejos y sin leer el numero.

     Los cuatro nuevos se eligieron MIDIENDO, no a ojo, porque cada
     uno tiene que servir para dos cosas a la vez: como texto —el
     numero grande, el nombre del tramo— y como FONDO SOLIDO de una
     insignia con letra encima. El peor de los ocho casos es el rojo
     como texto en oscuro, con 5,16, y el minimo es 4,5.

     ---- Y EL SEGUNDO PASA A SER AZUL ----

     Antes era una lima, o sea un verde mas. La lima resolvia a
     medias el problema de siempre: dos verdes parecidos obligan a
     leer la cifra para saber en cual estas, que es justo lo que el
     semaforo viene a evitar. El celeste lo resuelve entero.

     Lo que se pierde hay que decirlo: el azul no significa "vas
     bien" como lo significa el verde, asi que la escalera deja de
     ser un degradado de bueno a malo. Se puede pagar porque en esta
     app el color NUNCA es el dato — al lado siempre esta la palabra
     ("Bien") y debajo la escalera con su rango. Es la misma regla
     por la que la tarjeta cerrada lleva una insignia ademas del
     gris. */
  --bueno:            #22e06a;   /* 0-9    verde de semaforo */
  --bien:             #3fc9ff;   /* 10-29  celeste */
  --medio:            #ffd21e;   /* 30-49  amarillo, todavia no emergencia */
  --malo:             #ff3b47;   /* 50+    rojo */

  /* ---- LOS MISMOS CUATRO, PARA COSAS QUE NO SON TEXTO ----

     Joel, viendo el tema claro: "al cambiar a ese color mostaza
     pierde algo de magia". Es verdad, y la causa es que el tema
     claro tiene que apagar los cuatro para que se LEAN.

     Pero eso solo vale para el texto. Una barra de color, una
     franja o una rayita no se leen: se ven. Ahi el amarillo de
     semaforo no tiene ningun problema de contraste porque no hay
     ninguna letra encima, y es justamente donde vive casi todo el
     color de la pantalla.

     Por eso hay dos familias. Las de arriba pintan LETRAS y cambian
     con el tema; estas pintan FORMAS y son las mismas siempre. Que
     no esten repetidas en el bloque del tema claro no es un olvido:
     es la definicion.

     Quien elige cual no es cada regla suelta —eso se desincroniza—
     sino las clases nivel-* de app.css, que ponen las dos de una
     vez: `color` para la letra y `--vivo` para la forma. */
  --bueno-vivo:       #22e06a;
  --bien-vivo:        #3fc9ff;
  --medio-vivo:       #ffd21e;
  --malo-vivo:        #ff3b47;

  /* Los cuatro del semaforo son colores claros, asi que la letra
     que va ENCIMA de ellos (un chip, una insignia) siempre es
     oscura. Una sola variable para los cuatro evita que alguna
     quede en blanco sobre amarillo. */
  --sobre-color:      #121212;

  /* El contorno del riel de utilizacion. Joel: la pista vacia "se
     pierde con el fondo", y mas todavia en claro. Es cierto y no es
     un detalle: si no se ve donde TERMINA la barra, el relleno deja
     de ser una proporcion y pasa a ser una manchita de color. Sin
     el marco, un 20% y un 60% se parecen.
     Va como variable y no escrito en app.css porque cambia con el
     tema: casi blanco sobre oscuro, casi negro sobre claro. */
  --borde-riel:       rgba(255, 255, 255, .22);

  /* ---- Los cuatro baldes del presupuesto ----

     Un color por categoría, y el MISMO en los dos lugares donde
     aparece: la barra del reparto y el borde del gasto en la lista.
     Esa repetición es el punto entero — la persona ve el color
     cada vez que mira sus gastos y termina sabiendo los cuatro
     baldes sin que nadie se los explique.

     No se reusan los del semáforo: ahí el color significa "estás
     bien o estás mal", y un gasto no está bien ni mal, está en un
     balde. Mezclarlos haría que un gasto de gusto pintado de ámbar
     se leyera como una advertencia. */
  --cat-necesidad:    #58b6f5;   /* el techo y la comida: sereno */
  --cat-gusto:        #c98cf5;   /* lo que se elige */
  /* Este verde ERA el mismo de "vas bien" hasta el 2026-08-16, y
     dejo de serlo cuando el semaforo paso a colores de semaforo. No
     se cambio con el a proposito: un balde del presupuesto no es un
     estado, y la regla de la semana 6 ya separaba las dos familias
     —pintar el ahorro con nivel-excelente diria algo que no es—.
     Que ahora tengan hex distinto solo hace visible una separacion
     que ya existia. */
  --cat-ahorro:       #34e5a0;
  --cat-deuda:        #ff9f6e;   /* lo que sale sí o sí */

  /* ---- Retícula y particulas ---- */
  --reticula:         rgba(124, 108, 255, .11);
  --particula:        rgba(160, 150, 255, .30);

  /* ---- Sombras ----

     Eran moradas —rgba(60,40,160) y rgba(80,60,220)— y funcionaban
     sobre el indigo: eran el mismo color del fondo, mas saturado, o
     sea que se leian como profundidad y no como color.

     Sobre un fondo neutro esa misma sombra deja de ser profundidad y
     pasa a ser un halo violeta alrededor de cada caja. Van en negro,
     que es lo que hace una sombra sobre una escala de grises. */
  --sombra:      0 1px 2px rgba(0,0,0,.55), 0 8px 28px rgba(0,0,0,.40);
  --sombra-alta: 0 2px 6px rgba(0,0,0,.60), 0 24px 56px rgba(0,0,0,.50);

  /* El neon morado al interactuar. Es UNA variable y no tres reglas
     sueltas para que el brillo del boton, el de la tarjeta y el del
     campo enfocado sean exactamente el mismo. */
  --neon: 0 0 0 1px color-mix(in srgb, var(--acento) 55%, transparent),
          0 0 22px color-mix(in srgb, var(--acento) 26%, transparent);

  /* ---- LA ESCALA DE AIRE, desde el 2026-08-16 ----

     Joel: "no hay una jerarquia establecida en toda la pagina de
     cuantos pixeles debe haber entre un elemento y el otro".

     Y era cierto y se midio: entre el titulo y su bajada habia 18
     px, entre la bajada y el contenido CERO, entre una etiqueta y
     su campo 9, y entre secciones 40. Seis valores distintos, todos
     puestos a ojo en la regla de cada componente. Con espacios
     arbitrarios el ojo no puede agrupar: no sabe que va junto con
     que, porque la distancia no significa nada.

     Son cuatro escalones y cada uno dice UNA cosa:

       --aire-par     lo que va pegado porque es una sola idea
                      —un titulo y su bajada, una etiqueta y su campo—
       --aire-dentro  piezas distintas dentro del mismo bloque
       --aire-bloque  de un bloque al siguiente
       --aire-seccion de una seccion a otra

     Lo que importa no son los numeros sino que haya SALTO entre
     ellos: cada escalon es alrededor del doble del anterior, asi que
     "esto va junto" y "esto es otra cosa" se distinguen sin leer.
     Es la misma decision que la escala de tamanios de la landing,
     que arreglo el mismo problema con la tipografia. */
  --aire-par:     .4rem;
  --aire-dentro:  .85rem;
  --aire-bloque:  1.6rem;
  --aire-seccion: 2.5rem;

  /* ---- EL UNICO TAMANIO DE LA ESCALA QUE VIVE ACA, y su porque ----

     El resto de la escala (--t-etiqueta, --t-cuerpo, --t-heroe...) vive
     en inicio.css, porque es de la landing y saldo.html no tiene que
     pagarla. Este esta aca porque **base.css lo USA**: la regla `.pie`,
     que se mudo desde inicio.css el 2026-08-16.

     Se mudo la regla y se dejo la variable atras. Consecuencia, medida
     el 2026-08-17 en terminos.html: el pie salia a **16px en vez de
     14**, porque `var(--t-chico)` no estaba definida en ninguna hoja que
     esa pagina cargue. No rompio nada y por eso no lo vio nadie — el pie
     simplemente era mas grande, y esta asi en produccion desde ese dia.

     Va en UN solo sitio a proposito: se borro de `.lienzo` en inicio.css
     en vez de dejar las dos. Dos definiciones del mismo token en dos
     hojas que la landing carga juntas es como `.tramo` dejo la pagina de
     inicio escrita en mayusculas dos semanas. */
  --t-chico: .875rem;

  --curva: 16px;

  /* Los controles nativos —la casilla, el selector de fecha, la
     barra de desplazamiento— se pintan solos con esto. Sin ello, en
     medio de una pantalla oscura sale un calendario blanco. */
  color-scheme: dark;
}

/* ============================================================
   EL TEMA CLARO

   ---- POR QUE UN SOLO BLOQUE Y NO DOS ----

   Lo habitual es escribir la paleta clara dos veces: una dentro de
   @media (prefers-color-scheme) y otra para el interruptor. Dos
   copias de dieciocho colores es una copia que dentro de tres meses
   va a estar desincronizada.

   Acá el atributo data-tema SIEMPRE está puesto: lo escribe un
   script de tres líneas en el <head> de cada página, que lee la
   preferencia guardada y, si no hay ninguna, le pregunta al sistema
   operativo. Va en el head y no en un archivo aparte a propósito:
   un archivo externo llega después del primer dibujo y la pantalla
   parpadea en blanco antes de ponerse oscura.

   ---- LO QUE NO CAMBIA DE TEMA ----

   Las tarjetas de crédito. Son un objeto físico y una tarjeta black
   es black con la luz prendida o apagada. Sus colores se calculan
   desde tono y acabado, no desde estas variables.

   ---- POR QUÉ EL SELECTOR PERDIÓ EL `:root` el 2026-08-16 ----

   Decía `:root[data-tema="claro"]`, o sea que la paleta clara solo
   podía existir en el `<html>`: o toda la página era clara o
   ninguna parte lo era.

   La landing alterna secciones oscuras y claras, y en la semana 5
   eso se había descartado con el argumento de que "una banda blanca
   obligaría a invertir texto, botones, sombras y semáforo dentro de
   ella: serían dos sistemas de diseño en una página". El argumento
   era bueno entonces y dejó de serlo cuando se construyó el tema
   claro: **el segundo sistema ya existe, está probado y se usa a
   diario.**

   Sin el `:root`, estas dieciocho variables se pueden poner en
   CUALQUIER elemento y todo lo que haya adentro las hereda. Una
   sección con `data-tema="claro"` se vuelve clara entera —tinta,
   líneas, superficies, sombras, semáforo— sin una sola regla nueva
   y sin duplicar ni un color.

   Lo que NO cambia: el script del `<head>` sigue escribiendo el
   atributo en el `<html>` igual que siempre, así que el interruptor
   de tema de la aplicación funciona exactamente como antes. Esto
   solo agrega la posibilidad de anidarlo.
   ============================================================ */
[data-tema="claro"] {
  /* El fondo tira a gris azulado y la superficie es blanco puro. La
     diferencia tiene que ser CLARA: con #f3f4fb contra #ffffff las
     bandas alternadas de la landing no se distinguian y la pagina
     volvia a leerse como una sola cosa muy larga. */
  --fondo:            #e9ebf6;
  --superficie:       #ffffff;
  --superficie-alta:  #f4f5fc;
  --linea:            #d6d9ec;

  --tinta:            #12142b;
  /* Más oscuro que su gemelo del tema oscuro: sobre blanco, un gris
     que se lee bien en negro se vuelve ilegible. */
  --suave:            #5c618a;

  /* En el tema claro el morado profundo sirve para las dos cosas: el
     problema del contraste esta al reves. Sobre blanco, #4c16ca da
     9,23 como texto y como borde se ve perfecto; el que no serviria
     aca es el hermano claro. */
  --acento:           #4c16ca;
  --acento-2:         #0e8fa8;
  --acento-boton:     #4c16ca;

  /* Los cuatro del semáforo se oscurecen, y esto NO es opcional: los
     del tema oscuro son colores de semáforo pensados para brillar
     sobre negro, y sobre blanco no se leen. El amarillo #ffd21e da
     1,4 de contraste sobre blanco — invisible— contra los 5,43 de
     este. Mismos matices, otra luminosidad: el verde sigue siendo
     verde y el celeste sigue siendo azul, solo que se pueden leer.
     Los ocho valores están medidos; el peor de este tema es 5,43. */
  --bueno:            #0a7a3c;
  --bien:             #0b6b96;
  --medio:            #8a6300;
  --malo:             #c11421;

  /* Y por eso este se da vuelta: ahora la letra que va ENCIMA de un
     chip de color tiene que ser blanca, no casi negra. */
  --sobre-color:      #ffffff;

  /* En claro la pista del riel es casi del color del panel, asi que
     sin contorno desaparece del todo. Mas fuerte que el del tema
     oscuro —.28 contra .22— porque una linea negra sobre un fondo
     claro se percibe mas debil que una blanca sobre uno oscuro. */
  --borde-riel:       rgba(18, 20, 43, .28);

  /* Los cuatro baldes también se oscurecen: sobre blanco, los del
     tema oscuro no llegan al contraste mínimo. */
  --cat-necesidad:    #1f6fa8;
  --cat-gusto:        #7c3ca8;
  --cat-ahorro:       #0a7a54;
  --cat-deuda:        #b4551f;

  /* Mas opacas que las del tema oscuro: un punto tenue sobre negro
     brilla, y el mismo punto sobre blanco simplemente no esta. */
  --reticula:         rgba(91, 70, 232, .16);
  --particula:        rgba(91, 70, 232, .70);

  /* ---- MAS FUERTES QUE ANTES, y por que hacia falta ----

     Joel: "en modo oscuro se ve bien porque ya tiene como un leve
     brillo claro, pero en el modo claro no se nota y se pierde con
     el fondo". Tenia razon y la causa es que un panel claro sobre un
     fondo claro no tiene NINGUNA otra senal de que esta despegado:
     en el tema oscuro el panel es mas claro que el fondo y ya con
     eso flota, pero aca el panel es blanco sobre un gris muy
     clarito y la diferencia es de cuatro por ciento de luminosidad.
     La sombra es lo unico que lo levanta, y estaba en .06.

     Se subio a .10 la de contacto y se le agrego una tercera
     parada corta: la de contacto define el borde, la media da el
     volumen y la larga y suave apoya la caja en el fondo. Tres
     paradas y no una porque una sola sombra grande se ve como una
     mancha y no como un objeto levantado. */
  --sombra:      0 1px 2px rgba(18,20,43,.10),
                 0 4px 10px rgba(40,30,90,.08),
                 0 14px 34px rgba(40,30,90,.10);
  --sombra-alta: 0 2px 4px rgba(18,20,43,.12),
                 0 8px 18px rgba(40,30,90,.12),
                 0 26px 56px rgba(40,30,90,.18);

  color-scheme: light;
}

/* ---- El interruptor del tema ----

   Una pildora con los dos iconos siempre a la vista y una perilla
   que se corre de un lado al otro. Antes era un boton redondo que
   cambiaba de icono, y tenia dos problemas: se veia estirado —el
   grid alojaba los dos iconos aunque uno estuviera oculto, asi que
   la caja media dos filas de alto— y sobre todo no mostraba que
   hay dos estados. Un icono que se reemplaza es un boton; una
   perilla que se desliza es un interruptor, y eso es lo que esto
   es. */
.tema {
  /* ---- LAS MEDIDAS VAN EN VARIABLES, Y NO ES PROLIJIDAD ----

     El ancho estaba escrito DOS veces: aca en `width` y otra vez
     dentro del `calc` que corre la perilla. Mientras la pildora midio
     siempre lo mismo eso no molesto — y el dia que la barra lateral
     la achico para caber contraida, `width` cambio y el `calc` no:
     la perilla quedo sin caer sobre ninguno de los dos iconos.

     Un dato repetido en dos reglas se desincroniza en cuanto una de
     las dos se toca. Es la misma razon por la que las clases
     `nivel-*` ponen el color del texto y el de la forma de una vez.
     Ahora la pildora publica sus medidas y todo lo demas se deriva:
     para achicarla basta redefinir estas tres. */
  --tema-ancho: 3.6rem;
  --tema-alto: 2rem;
  --tema-perilla: 1.45rem;

  position: relative;
  display: inline-flex;
  align-items: center;
  width: var(--tema-ancho);
  height: var(--tema-alto);
  padding: 0;
  flex-shrink: 0;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: var(--fondo);
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .2s ease, background .2s ease;
}
.tema:hover { border-color: var(--acento); box-shadow: var(--neon); }

/* Los dos iconos se quedan quietos. El que NO esta activo se apaga
   en vez de desaparecer: asi la pildora siempre mide lo mismo y se
   entiende de un vistazo que hay dos lados. */
/* Cada icono ocupa exactamente media pildora y se centra en su
   mitad. Antes iban con space-between y un relleno a los costados,
   que los dejaba cerca de los bordes mientras la perilla se movia
   por su cuenta: nunca coincidian. Ahora las dos cosas se calculan
   contra la misma mitad y la perilla cae centrada sobre el icono. */
.tema-icono {
  position: relative; z-index: 1;
  flex: 1;
  display: grid; place-items: center;
  font-size: .8rem; line-height: 1;
  transition: color .25s ease;
}
/* El activo queda DEBAJO de la perilla, que es índigo oscuro, así
   que va en blanco: con el color del texto normal desaparecía
   dentro del degradado y la píldora se veía con un solo icono. */
/* Los iconos son SVG y no los caracteres ☀ y ☾. El glifo de la luna
   trae aire de sobra a un costado —cuanto, depende de la tipografia
   que tenga instalada cada persona— asi que centrado se veia
   corrido, y compensarlo a mano solo lo arreglaba en una maquina.
   Un viewBox de 24x24 se centra solo en cualquier lado. */
.tema-icono svg { width: .95rem; height: .95rem; display: block; }

.tema-icono:first-of-type { color: var(--suave); }               /* el sol */
.tema-icono:last-of-type  { color: #fff; }                        /* la luna */
:root[data-tema="claro"] .tema-icono:first-of-type { color: #fff; }
:root[data-tema="claro"] .tema-icono:last-of-type  { color: var(--suave); }

/* La perilla. Empieza a la derecha (tema oscuro, la luna) y se
   corre a la izquierda cuando se prende la luz.

   ---- LA CUENTA, ESCRITA PARA QUE NADIE LA AJUSTE A OJO ----

   La perilla tiene que caer CENTRADA SOBRE EL ICONO, y los iconos
   son dos `flex: 1`, o sea media pildora cada uno. Entonces la
   posicion no se deduce de los margenes sino de las mitades:

     carril  = ancho - 2px   (el borde, porque `left` mide por dentro)
     centro de la mitad izquierda = carril / 4
     left    = ese centro - media perilla
     correrse a la otra mitad = carril / 2, ni un pixel mas

   **Y el carril empieza en CERO, no en 1px.** Un hijo absoluto se
   posiciona contra el padding box, o sea que `left: 0` ya cae dentro
   del borde: sumarle el pixel del borde lo cuenta dos veces. Se vio
   midiendo los cuatro casos —dos tamanos por dos temas— y dando **1px
   de desvio en los cuatro**. Un error constante en todos los casos es
   un offset de mas; uno que cambia con el tamano seria la formula.
   Vale la distincion: dice donde buscar.

   La version anterior la anclaba a `.175rem` del borde y la corria
   "lo que sobra". Con la pildora grande quedaba a un pixel y medio
   del centro del icono, que no se nota; con la pildora chica de la
   barra contraida el mismo error es proporcionalmente el triple y se
   ve de una. **Centrar contra la mitad da exacto en los dos
   tamanos** — y en cualquier otro que aparezca. */
.tema-perilla {
  position: absolute;
  top: 50%;
  left: calc((var(--tema-ancho) - 2px) / 4 - var(--tema-perilla) / 2);
  width: var(--tema-perilla); height: var(--tema-perilla);
  margin-top: calc(var(--tema-perilla) / -2);
  border-radius: 50%;
  background: linear-gradient(140deg, var(--acento), var(--acento-2));
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
  transition: transform .28s cubic-bezier(.35,.75,.35,1);
  transform: translateX(calc((var(--tema-ancho) - 2px) / 2));  /* oscuro */
}
:root[data-tema="claro"] .tema-perilla { transform: translateX(0); }

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--fondo);
  color: var(--tinta);
  font-family: var(--cuerpo);
  line-height: 1.5;
  /* La barra de arriba es pegajosa y el fondo va detras de todo:
     sin esto, en pantallas cortas el fondo termina antes que el
     contenido y aparece una franja negra. */
  min-height: 100vh;
}

/* ============================================================
   EL FONDO — la retícula

   Un solo pseudo-elemento fijo, detras de todo. No es un <div>
   porque no es contenido: un lector de pantalla no tiene por que
   enterarse de que hay cuadritos.

   Se desvanece hacia abajo con una mascara. Una retícula pareja de
   arriba a abajo compite con el texto; asi se ve arriba, donde solo
   hay aire, y desaparece donde empiezan los numeros.
   ============================================================ */
/* ============================================================
   LAS PARTICULAS — la capa que flota detras de todo

   Vive aca y no en app.css desde el 2026-08-17, para que las cuatro
   pantallas de sesion puedan tenerlas sin cargar el tablero entero.
   El porque completo esta en el hueco que dejo en app.css.

   Son DOS pseudo-elementos y no un motor de particulas: cientos de
   nodos y un requestAnimationFrame corriendo siempre es bateria que
   alguien paga. Estas son dos capas de puntos repetidos que se
   desplazan con `transform`, que el navegador resuelve sin volver a
   dibujar nada, y el desplazamiento es un multiplo exacto del patron
   para que el bucle no de un salto visible.

   Las tiene la pantalla que lleve el `<div class="particulas">`.
   `saldo.html` no lo lleva a proposito: ahi no se mueve nada.
   ============================================================ */
.particulas {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}

.particulas::before,
.particulas::after {
  content: "";
  position: absolute;
  /* Se desborda por los cuatro lados para que las capas puedan
     moverse sin dejar un borde vacio al llegar al final. */
  inset: -30%;
  background-repeat: repeat;
  will-change: transform;
}

.particulas::before {
  background-image:
    radial-gradient(1.6px 1.6px at  30px  40px, var(--particula), transparent),
    radial-gradient(1.2px 1.2px at 170px  90px, var(--particula), transparent),
    radial-gradient(2px   2px   at  90px 200px, var(--particula), transparent),
    radial-gradient(1.2px 1.2px at 220px 230px, var(--particula), transparent),
    radial-gradient(1.6px 1.6px at 130px 140px, var(--particula), transparent);
  background-size: 260px 260px;
  animation: flotar-cerca 110s linear infinite;
}

.particulas::after {
  /* La capa lejana: puntos mas chicos y mas tenues. */
  background-image:
    radial-gradient(1px 1px at  50px  20px, var(--particula), transparent),
    radial-gradient(1px 1px at 150px 120px, var(--particula), transparent),
    radial-gradient(1px 1px at  20px 160px, var(--particula), transparent);
  background-size: 190px 190px;
  opacity: .6;
  animation: flotar-lejos 170s linear infinite;
}

@keyframes flotar-cerca {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-260px, -520px, 0); }
}
@keyframes flotar-lejos {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(190px, -380px, 0); }
}


/* ---- APAGADA EL 2026-08-15, por pedido de Joel ----

   La reticula estuvo desde la semana 5 y dejo de convencer. Se apaga
   con --reticula-fuerza en 0 y NO se borra el codigo, a proposito:
   asi volver atras es cambiar un cero por un uno, y probar un punto
   medio es poner .4. Borrarla habria obligado a reescribirla para
   volver a verla, y este proyecto no tiene git.

   Si dentro de un mes sigue apagada, ahi si se borra. */
:root { --reticula-fuerza: 0; }

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  opacity: var(--reticula-fuerza);
  background-image:
    linear-gradient(to right,  var(--reticula) 1px, transparent 1px),
    linear-gradient(to bottom, var(--reticula) 1px, transparent 1px);
  background-size: 44px 44px;
  -webkit-mask-image: radial-gradient(120% 85% at 50% 0%, #000 25%, transparent 75%);
          mask-image: radial-gradient(120% 85% at 50% 0%, #000 25%, transparent 75%);
}

/* ============================================================
   MENOS MOVIMIENTO

   Va aca arriba y no al final del archivo a proposito: es lo
   primero que hay que ver al abrir la hoja. Hay gente a la que el
   movimiento le produce mareo de verdad, y esto se decidio desde
   el primer dia, no como parche despues.

   Apaga animaciones y transiciones de TODO, incluido lo que se
   agregue manana sin acordarse de esta regla.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   TIPOGRAFIA
   ============================================================ */
/* ---- COMO SE PARTEN LAS LINEAS ----

   Un titulo de dos renglones donde el primero llega al borde y el
   segundo tiene dos palabras se lee mal, igual que un subtitulo de
   Netflix cortado en mitad de una frase. Las guias de subtitulado
   dicen lo mismo hace decadas: renglones parejos, no cortar
   despues de una preposicion o un articulo, y no dejar una palabra
   sola al final.

   Las dos primeras las hace el navegador:

   - balance reparte el texto en renglones del mismo largo. Va en
     titulos y no en parrafos largos porque el navegador solo lo
     aplica hasta unas pocas lineas.
   - pretty se encarga de los parrafos: evita que sobre una palabra
     sola en el ultimo renglon.

   La tercera —no cortar despues de "de", "en", "para"— no la sabe
   ningun navegador. Esa se resuelve escribiendo un espacio duro
   (&nbsp;) entre la preposicion y su palabra en las frases donde
   importa, que son los titulos grandes de la landing. */
h1, h2, h3 {
  /* La unica familia que usa la fuente propia. Todo lo demas —el
     cuerpo, los formularios y sobre todo las cifras— se queda con la
     del sistema. El porque esta arriba, en el bloque del @font-face. */
  font-family: var(--titulares);
  margin: 0; line-height: 1.2; letter-spacing: -.02em;
  text-wrap: balance;
}
h1 { font-size: 1.5rem; font-weight: 660; }
h2 { font-size: 1.05rem; font-weight: 640; }

p, li, small, dd, dt { text-wrap: pretty; }
p { margin: 0; }

a { color: var(--acento); text-decoration-color: color-mix(in srgb, var(--acento) 45%, transparent); }
a:hover { text-decoration-color: var(--acento); }

/* Toda cifra con esto: sin ancho tabular, un numero que cambia de
   9% a 11% mueve la columna entera de al lado. */
strong, b, dd, .cifra { font-variant-numeric: tabular-nums; }

/* ============================================================
   LA HOJA — el contenedor angosto

   Lo usan las pantallas de una sola cosa: entrar, recuperar,
   clave nueva, el enlace magico, el formulario de una tarjeta.
   El dashboard y el presupuesto NO: esos son de ancho completo y
   viven en app.css.
   ============================================================ */
/* ============================================================
   ENCABEZADO — la marca fuera de la hoja.

   Pedido por Joel en la semana 9: "sacar el logo de la caja de
   login y ponerlo arriba como header, como en la landing". Tenia
   razon y el motivo es de jerarquia: la marca DENTRO del recuadro
   se lee como el titulo del formulario —como si la app se llamara
   igual que el paso— y ademas empuja el formulario hacia abajo. La
   marca pertenece a la pagina, no al formulario.

   Aca vive tambien el interruptor de tema, que hasta ahora flotaba
   en position:fixed sobre la esquina. Flotando se le monta encima
   al contenido cuando la pantalla es corta; en el encabezado tiene
   su sitio y no pisa nada.

   Se alinea con la hoja usando el MISMO ancho (30rem), asi que la
   marca queda a plomo con el borde izquierdo del recuadro. Si algun
   dia .hoja cambia de ancho, hay que cambiarlo en los dos.

   saldo.html NO lo usa, y es a proposito: es la pantalla de los 8
   segundos, no tiene navegacion por diseño, y su marca dentro de la
   hoja se lee como una firma y no como un menu. No se toca.
   ============================================================ */
.encabezado {
  width: min(30rem, 100%);
  margin: 1.5rem auto -0.5rem;
  padding-inline: .25rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}

.hoja {
  position: relative;
  width: min(30rem, 100%);
  margin: 2rem auto;
  padding: 1.75rem;
  background: var(--superficie);
  border: 1px solid var(--linea);
  border-radius: var(--curva);
  box-shadow: var(--sombra);
}

@media (max-width: 480px) {
  .hoja { margin: 0; padding: 1.25rem 1rem 2rem; border: none; border-radius: 0;
          min-height: 100vh; box-shadow: none; background: transparent; }
  /* En esta medida la hoja pierde el recuadro y se pega a los bordes
     con 1rem de relleno. El encabezado tiene que usar EXACTAMENTE ese
     relleno o la marca queda un dedo mas a la izquierda que los
     campos que encabeza — que es de esas cosas que no se saben
     nombrar pero se ven. */
  .encabezado { padding-inline: 1rem; margin-bottom: 0; }
}

/* La marca. El punto solo ya identifica; en pantallas angostas el
   nombre se esconde y el punto se queda. */
/* ---- POR QUE LA MARCA LLEVA TRATAMIENTO PROPIO ----

   Joel lo reporto en la semana 9 y tenia razon: "Mes bajo control"
   al lado de otro texto no se sabe donde empieza ni donde termina.
   Son cuatro palabras comunes en espaniol, asi que sin una senial
   visual el ojo las lee como parte de la frase.

   Se resuelve con tres cosas:

     1. El nombre NUNCA se parte en dos renglones (nowrap). Una
        marca cortada a la mitad deja de leerse como un nombre.
     2. Va en --tinta, el color mas fuerte, mientras el texto que
        la rodea vive en --suave. El contraste hace el trabajo.
     3. El simbolo a la izquierda le pone principio.

   El punto 3 era un cuadradito de relleno hasta el 2026-08-21, y
   decia aqui mismo "cuando exista el logo, reemplaza al punto y lo
   demas queda igual". Eso fue exactamente lo que paso: el simbolo
   entro y los puntos 1 y 2 no se tocaron. */
/* El nombre va en la tipografia de TITULARES y no en la del cuerpo.
   Joel lo pidio el 2026-08-21 mirando el logo original: "la
   tipografia tal vez no va con la misma de la pagina". Tenia razon, y
   de paso arregla lo otro que senialo —que las palabras no median
   igual—: escrito como texto, y no dibujado dentro del SVG, las tres
   palabras comparten font-size por construccion. En el PNG original
   estan estiradas para justificarse a un mismo ancho, y por eso MES
   sale mas chico que CONTROL.

   OJO: esto le cuesta la fuente a quien lo cargue. `saldo.html` la
   apaga en su propio <style>, junto con h1/h2/h3, y con eso el .woff2
   de 29 KB no se pide. Si algun dia se le pone --titulares a algo
   mas, hay que mirar esa lista. */
.marca { display: flex; align-items: center; gap: .55rem;
         font-family: var(--titulares);
         font-weight: 600; letter-spacing: -.012em; font-size: 1.02em;
         color: var(--tinta); white-space: nowrap; }

/* La marca es el boton de inicio de todo el sitio, que es donde la
   gente lo busca por costumbre. Como <a> tiene que perder el
   subrayado y el color de enlace, o se lee como un enlace mas
   dentro de la frase, que es justo el problema que vino a resolver. */
a.marca { text-decoration: none; }
a.marca:hover .marca-logo { transform: rotate(-18deg) scale(1.06); }

/* ============================================================
   EL SIMBOLO DE LA MARCA

   Un anillo partido en dos mitades con punta de flecha —el ciclo
   del mes, que es de lo que trata el producto— y dentro tres
   barras que suben.

   ---- POR QUE ES UN SVG ESCRITO Y NO EL PNG ----

   El original que trajo Joel es un PNG de 1,1 MB. Como archivo
   suelto —<img src="logo.png">— no puede leer las variables de CSS,
   asi que habria que mantener DOS archivos, uno por tema, y
   rehacerlos los dos cada vez que se toque un color. Es la misma
   razon por la que el SVG de la malla va escrito en el <body> y no
   como imagen. Inline, el logo cambia solo con el tema y pesa unos
   700 bytes.

   ---- POR QUE SE REDIBUJO EN VEZ DE CALCARLO ----

   En el original las dos mitades NO son la misma pieza rotada: una
   cubre 175 grados y la otra 164. Once grados de diferencia que no
   se saben nombrar mirando pero se ven. Aca las dos salen de la
   misma funcion con 180 grados de diferencia exactos.
   Lo genera `herramientas/logo.py`; los numeros —radio 46, grosor
   13, la flecha sobresaliendo 2,6 a cada lado— estan medidos sobre
   el PNG y no elegidos a ojo.

   Y las barras van CONTENIDAS dentro del anillo, que es donde se
   aparta del original a proposito: alli la barra alta cruza el arco
   por arriba, y cruzando, a 16px —el favicon— las barras y el
   anillo se funden en una mancha.

   ---- EL COLOR, Y LA REGLA DEL NARANJA ----

   El morado cambia con el tema y NO es un capricho: #4c16ca da 2,13
   de contraste sobre el fondo oscuro, o sea invisible. En oscuro va
   su hermano claro, que es la pareja que --acento / --acento-boton
   ya resuelve para todo lo demas.

   El naranja se queda igual en los dos: es luminoso y funciona
   sobre fondo claro y oscuro.

   OJO CON LO SIGUIENTE, que es la parte que hay que respetar: las
   variables se declaran AQUI DENTRO, en .marca, y no en :root. El
   bloque del naranja de mas arriba dice por que —"una variable
   invita a usarla, y esta no se puede usar", porque esta a 4 grados
   de matiz de --cat-deuda—. Declaradas en .marca solo las heredan el
   simbolo y su nombre: un chip del dashboard que escriba
   var(--marca-nar) no resuelve a nada. La proteccion no depende de
   que nadie se acuerde.

   ---- POR QUE SON CUATRO Y NO DOS ----

   Es la distincion que el proyecto ya tiene para el semaforo, donde
   --bueno pinta LETRAS y --bueno-vivo pinta FORMAS. Aqui pasa lo
   mismo y por la misma razon: el anillo no lleva nada encima y puede
   ir con el tono pleno en los dos temas, pero el nombre SI es texto
   y en tema claro el naranja pleno no se lee. Medido:

     #ff6b35 como texto sobre blanco ....... 2,84   (el minimo es 4,5)
     #ff6b35 como texto sobre --fondo ...... 2,39
     #ab4824, mismo matiz, mas oscuro ...... 5,70 y 4,80   OK

   El primero que pasaba era #b24b25, con 4,50 clavado sobre --fondo.
   Se bajo un escalon mas a proposito: un margen de CERO se rompe el
   dia que alguien mueva el fondo dos puntos, y nadie va a volver a
   medir esto por un cambio de fondo.

   Y el morado del nombre en tema oscuro NO es --acento, aunque lo
   parezca: #8c63ee da 4,08 sobre --superficie, que es justo el fondo
   de la barra lateral donde vive la marca. #9469fc, mismo matiz, da
   4,51. Cuatro centesimas por debajo del minimo no se ven mirando, y
   por eso se miden.
   ============================================================ */
.marca {
  --marca-mor:       #9469fc;   /* LETRA — 4,51 sobre --superficie */
  --marca-nar:       #ff6b35;   /* LETRA — 5,88 sobre --superficie */
  --marca-mor-vivo:  var(--acento);   /* FORMA — el anillo y las barras */
  --marca-nar-vivo:  #ff6b35;
}
[data-tema="claro"] .marca {
  --marca-mor:       #4c16ca;   /* 9,23 sobre blanco */
  --marca-nar:       #ab4824;   /* 5,70 sobre blanco, 4,80 sobre --fondo */
  --marca-mor-vivo:  var(--acento-boton);
}

.marca-logo {
  width: 1.9rem; height: 1.9rem; flex-shrink: 0; display: block;
  transition: transform .25s cubic-bezier(.34, 1.4, .64, 1);
}
.marca-logo .l-mor,
.marca-logo .l-bar { fill: var(--marca-mor-vivo); }
.marca-logo .l-nar { fill: var(--marca-nar-vivo); }

/* El nombre en dos colores, como el logo que trajo Joel: la primera
   palabra en morado y el resto en naranja. Va con <b> y no con dos
   <span> por una razon practica: si el CSS no carga, <b> deja el
   nombre legible igual.

   El peso NO cambia —los dos van en 600, el de .marca— porque lo que
   separa las dos mitades es el color. Poniendo ademas negrita, "Mes"
   se leeria como una palabra distinta y no como la primera parte del
   mismo nombre. */
.marca b { font-weight: inherit; color: var(--marca-mor); }
.marca span { color: var(--marca-nar); }

/* El nombre METIDO EN UN PARRAFO, que es el otro caso: los terminos
   y la landing lo escriben en mitad de una frase. Ahi no cabe el
   punto de color, asi que el trabajo lo hacen el peso, el color y
   sobre todo el nowrap. */
.nombre-marca {
  font-weight: 650; color: var(--tinta); white-space: nowrap;
}

/* ============================================================
   ICONO GRANDE

   El simbolo de las pantallas que solo dicen una cosa: "revisa tu
   correo", "tu cuenta quedo confirmada". Son pantallas sin datos y
   sin formulario, y sin algo que mirar se leen como un error.

   Va en base.css y no en app.css porque la usan entrar.html y
   confirmado.html, que son de las que cargan una sola hoja. Son
   nueve lineas; saldo.html las paga y no las usa, y eso esta bien
   por lo que costaria la alternativa: una hoja mas, o sea una
   peticion mas, justo en la pantalla que no puede pagarla.
   ============================================================ */
.icono-grande {
  width: 3.5rem; height: 3.5rem; margin: 0 auto 1rem;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--acento);
  background: color-mix(in srgb, var(--acento) 14%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--acento) 28%, transparent);
}
.icono-grande svg { width: 1.75rem; height: 1.75rem; }
/* El verde del "listo", que no es el acento: un tilde morado no se
   lee como confirmacion. Reusa --bueno, el mismo verde de "vas
   bien" del semaforo, para no inventar un color nuevo. */
.icono-grande.listo {
  color: var(--bueno);
  background: color-mix(in srgb, var(--bueno) 14%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--bueno) 28%, transparent);
}

/* ============================================================
   PESTANAS

   Solo las usa la pantalla de ingreso, para alternar entre "ya
   tengo cuenta" y "crear cuenta". Las pantallas con sesion navegan
   con la barra de arriba, que vive en app.css.
   ============================================================ */
.pestanas {
  display: flex; gap: .4rem;
  padding: .3rem;
  margin-bottom: 1.5rem;
  background: var(--fondo);
  border: 1px solid var(--linea);
  border-radius: 12px;
}

.pestana {
  flex: 1;
  padding: .6rem;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--suave);
  font: inherit; font-size: .9rem;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, box-shadow .2s ease;
}
.pestana:hover { color: var(--tinta); }

.pestana.activa {
  background: var(--superficie-alta);
  color: var(--tinta);
  font-weight: 620;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--acento) 40%, transparent);
}

/* ============================================================
   FORMULARIOS
   ============================================================ */
.forma { display: flex; flex-direction: column; }

label { font-size: .85rem; font-weight: 600; margin-top: 1rem; }

/* Se listan uno por uno y no "input" a secas para no pisar la
   casilla de verificacion, que necesita su tamano nativo. */
input[type="email"],
input[type="password"],
input[type="text"],
input[type="number"],
input[type="date"],
select,
textarea {
  /* Sin el ancho, un <select> se encoge al de su opcion mas larga y
     queda mucho mas angosto que el campo de texto de arriba.
     Y sin el alto minimo pasa lo mismo en vertical: un select se
     dibuja mas bajo que un input aunque los dos tengan el mismo
     relleno, porque el navegador le arma su propia caja. Fijando
     los dos, todos los campos del formulario miden igual. */
  width: 100%;
  min-height: 3.1rem;
  margin-top: .35rem;
  padding: .7rem .8rem;
  background: var(--fondo);
  color: var(--tinta);
  border: 1px solid var(--linea);
  border-radius: 10px;
  font: inherit;
  /* 16px exactos: con menos, el telefono hace zoom solo al tocar el
     campo y la pantalla queda descuadrada. */
  font-size: 16px;
  transition: border-color .15s ease, box-shadow .2s ease;
}

input::placeholder { color: color-mix(in srgb, var(--suave) 70%, transparent); }

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--acento);
  box-shadow: var(--neon);
}

/* El teclado tiene que ver a donde va. Va aparte del :focus de
   arriba porque aplica a botones y enlaces, que no llevan borde. */
:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Safari le arma al <select> su propia caja y no le hace caso al
   alto minimo: por eso los desplegables se veian mas finitos que
   el campo de texto de al lado, aunque el CSS dijera lo mismo para
   los dos. Apagando la apariencia nativa la caja pasa a ser
   nuestra, y la flecha hay que dibujarla a mano.
   Va en dos reglas y no en una porque un data-uri no puede leer
   var(--tinta): el color del triangulito se escribe literal, y por
   eso hay una version por tema. */
select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 2.4rem;
  background-repeat: no-repeat;
  background-position: right .85rem center;
  background-size: .7rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%238b91be' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
}
:root[data-tema="claro"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235c618a' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
}

input[type="checkbox"], input[type="radio"] { accent-color: var(--acento); }

/* La casilla de autorizacion: texto completo, nunca premarcada. */
.casilla {
  display: flex; gap: .7rem; align-items: flex-start;
  margin-top: 1.2rem; font-weight: 400; font-size: .85rem; line-height: 1.45;
}
.casilla input { margin-top: .25rem; flex-shrink: 0; }

/* ============================================================
   BOTONES
   ============================================================ */
.principal, .secundario {
  margin-top: 1.25rem;
  padding: .8rem 1rem;
  border-radius: 10px;
  font: inherit;
  font-weight: 640;
  cursor: pointer;

  /* ---- ESTA LINEA ES PARA SAFARI, y sin ella el hover se ve tosco
     SOLO ahi ----

     Joel lo encontro el 2026-08-15 probando por casualidad en Chrome
     de incognito: el mismo archivo se veia fluido en Chrome y a
     saltos en Safari. O sea que no era el CSS ni la cache.

     La causa: cuando Safari anima un scale sobre un elemento QUE
     CONTIENE TEXTO y ese elemento no esta en su propia capa de
     composicion, vuelve a rasterizar las letras en cada cuadro en
     vez de escalar la capa ya dibujada. No va lento —va a 60— pero
     redibuja el texto diecisiete veces en el trayecto, y eso es lo
     que el ojo lee como escalones. Chrome promueve la capa solo;
     Safari espera que se lo pidan.

     will-change: transform es pedirselo. Va sobre el elemento y no
     sobre :hover a proposito: puesto en el hover llega tarde —la
     capa se crea cuando la animacion ya arranco— y se pierde
     justamente el primer tercio, que es el que se nota.

     El costo es una capa de dibujo por boton. Se puede pagar porque
     son pocos: la landing tiene cinco y saldo.html uno. Si algun dia
     hubiera decenas en una pantalla, esto habria que repensarlo. */
  will-change: transform;
  /* ---- POR QUE .28s Y NO .12s ----

     Joel lo reporto asi: "es como un interruptor, prende al poner el
     mouse y apaga al quitarlo", y comparo con las tarjetas del
     heroe, que si se sienten. Tenia razon y los numeros lo explican
     solos: el boton se movia UN pixel en 120 milisegundos. A esa
     distancia y a esa velocidad no hay nada intermedio que ver, asi
     que el ojo lo lee como un cambio de estado y no como un
     movimiento. Las tarjetas del heroe van a .5s y recorren varios
     centimetros; por eso esas si se leen.

     .28s es el punto medio a proposito: los .5s de las tarjetas en
     un boton se sienten perezosos —un boton tiene que contestar
     rapido— pero .12 no se ve. Y todas las propiedades comparten la
     misma duracion y la misma curva, para que el brillo, la sombra y
     el movimiento lleguen juntos en vez de escalonados, que era la
     otra mitad de la sensacion de tosco. */
  transition: filter      .28s cubic-bezier(.2,.7,.3,1),
              transform   .28s cubic-bezier(.2,.7,.3,1),
              box-shadow  .28s cubic-bezier(.2,.7,.3,1),
              border-color .28s cubic-bezier(.2,.7,.3,1),
              background  .28s cubic-bezier(.2,.7,.3,1);
}

.principal {
  /* Transparente y no `none`, y la diferencia se midio: con `none`
     el boton primario mide 50px y el secundario 52, porque el borde
     de 1px del secundario suma arriba y abajo. Puestos uno al lado
     del otro —los dos planes de la landing, el "Entrar" junto al
     "Crear cuenta"— quedan desalineados por 2px, que es de esas
     cosas que nadie sabe nombrar pero que hacen ver una pagina
     descuidada. Joel lo reporto en la semana 9 mirando los planes.

     El borde transparente le da al primario la misma caja que al
     secundario sin pintarle nada encima. */
  border: 1px solid transparent;
  background: var(--acento-boton);
  color: #fff;
}
/* El crecimiento que Joel pide con la palabra "zoom": 3% de escala
   mas tres pixeles hacia arriba.

   El 3 salio de medir, no de tantear. El boton del heroe mide
   174 x 55 px: al 2% crecia 3,5 px de ancho, que sobre 174 sigue
   siendo casi nada. Al 3% crece 5,2 px, que ya se ve. Mas de ahi
   empieza a parecer un boton de juguete.

   Van las dos cosas juntas y no una: la escala es la que se lee como
   "crece", la subida es la que le da el despegue. Con la subida sola
   parecia un salto; con la escala sola se ve plano. */
.principal:hover { filter: brightness(1.12);
                   transform: translateY(-3px) scale(1.03);
                   box-shadow: var(--neon); }
/* Al pulsar se hunde por debajo de su tamanio normal, y rapido. Ese
   contraste —lento al crecer, seco al hundirse— es lo que hace que
   un boton se sienta fisico. */
.principal:active { transform: translateY(0) scale(.985);
                    transition-duration: .06s; }

.secundario {
  width: 100%;
  border: 1px solid var(--linea);
  background: var(--superficie-alta);
  color: var(--tinta);
}
/* El secundario NO TENIA transform, o sea que "Ver cómo funciona" no
   se movia en absoluto: solo le cambiaban el borde y la sombra, de
   golpe. Era la mitad de la sensacion de interruptor que reporto
   Joel. Ahora crece igual que el primario: dos botones lado a lado
   no pueden reaccionar distinto. */
.secundario:hover { border-color: var(--acento); box-shadow: var(--neon);
                    transform: translateY(-3px) scale(1.03); }
.secundario:active { transform: translateY(0) scale(.985);
                     transition-duration: .06s; }

/* Arriba, el bloque de prefers-reduced-motion vuelve instantaneas
   todas las transiciones, pero eso NO alcanza: el salto seguiria
   ahi, y para quien pidio no ver movimiento un salto es peor que una
   animacion suave. Aca se le quita el crecimiento al boton y queda
   solo el brillo, el borde y la sombra, que no se mueven.

   Es la misma regla que app.css ya tenia para .panel y .mazo-item.
   Hasta hoy los botones no la necesitaban porque no se movian; desde
   que crecen, si. */
@media (prefers-reduced-motion: reduce) {
  .principal:hover, .principal:active,
  .secundario:hover, .secundario:active { transform: none; }
}

/* Un enlace que tiene que verse como boton. */
.como-boton { display: block; text-align: center; text-decoration: none; }

/* Boton chico, para las acciones de una fila. */
.chico { margin-top: 0; padding: .5rem .7rem; font-size: .82rem; font-weight: 560; }

/* Un boton que en realidad es un enlace de texto. */
.enlace {
  border: none; background: none; padding: 0;
  color: var(--suave); font: inherit; font-size: .85rem;
  text-decoration: underline; cursor: pointer;
}
.enlace:hover { color: var(--tinta); }

.peligro { margin-top: 2rem; color: var(--malo); border-color: color-mix(in srgb, var(--malo) 40%, var(--linea)); }
.peligro:hover { border-color: var(--malo); box-shadow: 0 0 22px color-mix(in srgb, var(--malo) 22%, transparent); }

/* ============================================================
   AVISOS Y TEXTO SECUNDARIO
   ============================================================ */
.aviso { min-height: 1.2rem; margin-top: .8rem; font-size: .85rem; }
.aviso.malo  { color: var(--malo); }
.aviso.bueno { color: var(--bueno); }

.pista { color: var(--suave); font-size: .82rem; margin-top: .3rem; }
.nota  { color: var(--suave); font-size: .82rem; margin-top: 1.25rem; }

/* El descargo de "no es reparacion de credito", que cierra casi
   todas las pantallas. Centrado y separado del contenido: es una
   nota al pie legal, no la continuacion del texto de arriba, y
   alineado a la izquierda se leia como un parrafo mas. */
.descargo {
  text-align: center; text-wrap: balance;
  /* ---- MAS CHICO Y MAS SEPARADO, el 2026-08-16 ----

     Joel: se veia "casi del mismo tamanio" que el texto legal de
     arriba. En terminos y privacidad eso importa mas que en el resto
     de la app: la pagina ENTERA es texto legal, asi que un descargo
     del mismo cuerpo se lee como una clausula mas en vez de como la
     nota al pie que es.

     Baja a .74rem —dos escalones por debajo del cuerpo— y el aire de
     arriba se duplica. El borde se queda: es lo que dice "esto ya no
     es el documento". */
  font-size: .74rem;
  line-height: 1.55;
  opacity: .85;
  max-width: 34rem;
  margin: 4rem auto 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--linea);
}
.frase { margin-top: .8rem; font-size: .92rem; }

.destacado { color: var(--malo); }

/* Una advertencia que va DESPUES de un bloque de cifras y necesita
   despegarse de el. Con el margen normal de .pista queda pegada al
   ultimo renglon y se lee como parte de la tabla. */
.aviso-flojo { margin-top: .85rem; }

/* ============================================================
   LA CAJA DE CIFRAS

   Etiqueta a la izquierda, numero a la derecha. La cifra manda:
   nunca se parte en dos renglones y lo que cede es la etiqueta.
   ============================================================ */
.caja {
  margin-top: 1.1rem;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: .5rem 1rem;
}
.caja dt { color: var(--suave); font-size: .86rem; }
.caja dd { margin: 0; font-weight: 620; font-size: .88rem; text-align: right;
           white-space: nowrap; }

/* Cuando la caja no es una lista de cifras sino un bloque de texto
   (la invitacion a cargar la primera tarjeta), necesita su fondo. */
.bloque {
  margin-top: 1.25rem;
  padding: 1.25rem;
  background: var(--superficie-alta);
  border: 1px solid var(--linea);
  border-radius: 12px;
}

/* ============================================================
   DIALOGOS
   ============================================================ */
dialog {
  width: min(26rem, calc(100vw - 2rem));
  padding: 1.4rem;
  background: var(--superficie);
  color: var(--tinta);
  border: 1px solid var(--linea);
  border-radius: var(--curva);
  box-shadow: var(--sombra-alta);
}

dialog::backdrop { background: rgba(4, 5, 14, .7); backdrop-filter: blur(4px); }

dialog h2 { margin-bottom: .3rem; }
dialog details { margin-top: 1.2rem; }
dialog summary, details summary {
  color: var(--suave); font-size: .85rem; cursor: pointer;
}
details summary:hover { color: var(--tinta); }

/* ============================================================
   UTILIDADES
   ============================================================ */
.oculto { display: none !important; }

/* Para el texto que tiene que existir para un lector de pantalla y
   no ocupar lugar en la pantalla. */
.solo-lectores {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}


/* ============================================================
   EL PIE — mudado desde inicio.css el 2026-08-16

   Vive aca y no en inicio.css porque lo cargan tres paginas:
   index.html, terminos.html y privacidad.html. Las dos ultimas solo
   traen base.css.
   ============================================================ */
.pie {
  /* ---- YA NO SANGRA, y el porque importa ----

     Llego a tener `margin-inline: calc(50% - 50vw)` para taparle el
     grid, que era una capa fija a pantalla completa y le asomaba por
     los lados. Eso lo estiraba hasta el borde de la ventana y le
     corria el contenido 40 px respecto del logo y del boton Entrar
     del encabezado: quedaban desalineados.

     Con el grid fuera no hay nada que tapar, asi que el sangrado
     sobra. Vuelve a medir lo que mide el lienzo, que es lo que lo
     deja alineado con el resto de la pagina. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2rem 3rem;
  align-items: start;
  padding: 3rem 0 3.5rem;
  border-top: 1px solid var(--linea);
  color: var(--suave); font-size: var(--t-chico);
}
.pie-marca { max-width: 34rem; }
.pie-marca .marca { margin-bottom: 1rem; }
.pie-marca p { line-height: 1.6; }
.pie-empresa { margin-top: .8rem; opacity: .75; }

/* Apilados y no en fila: son tres destinos distintos, no una lista
   de lectura. En columna se distingue de un vistazo cuantos hay. */
.pie-enlaces { display: grid; gap: .6rem; justify-items: start; }
.pie-enlaces a { text-decoration: none; }
.pie-enlaces a:hover { text-decoration: underline; }

/* ---- EL DESCARGO, con especificidad suficiente ----

   `.descargo` sola no alcanzaba en terminos.html ni privacidad.html:
   ahi el documento define `.documento p`, que con 0-1-1 le gana a
   una clase suelta de 0-1-0. El descargo salia a .92rem, o sea del
   mismo cuerpo que el texto legal — exactamente lo que Joel pidio
   arreglar, y el cambio no se veia por eso.

   Medido en el navegador antes de tocar: 14,72 px contra los 11,84
   que pedia la regla. */
.documento p.descargo,
.hoja p.descargo {
  font-size: .74rem;
  line-height: 1.55;
  opacity: .85;
  max-width: 34rem;
  margin: 4rem auto 0;
  padding-top: 1.5rem;
}

/* Un botón apagado por el plan. No usa `disabled` —eso le quita el
   foco y quien navega con teclado pasa de largo sin saber por qué no
   puede seguir— así que el apagado es visual y el clic lo corta
   js/plan-pantalla.js. */
.apagado, [aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
  filter: saturate(.5);
}
