/* Copiado del diseño de Franco (MisFinanzas.dc.html). No cambiar los valores
   sin que él lo pida: los cuatro temas, el neumorfismo y la tipografía son
   decisiones suyas.

   Única excepción, del 2026-09-05: `--faint` se aclaró en los cuatro temas.
   Estaba en 2,78 de contraste sobre la superficie cuando el mínimo para texto
   chico es 4,5, y no se usa para adornos sino para información real ("sin
   verificar", "vos, nunca", de qué está hecho el saldo). Se conservaron el tono
   y la saturación de Franco; solo subió la luminosidad hasta pasar 4,5 contra
   el peor de los tres fondos de cada tema. */

:root,[data-theme="violeta"]{--bg:#25253f;--surface:#2c2c4a;--surface2:#37375a;--border:rgba(255,255,255,.06);--text:#f3f1ff;--muted:#aaa8cc;--faint:#a3a2ba;--accent:#b57cff;--accent-ink:#ffffff;--grad:linear-gradient(135deg,#6f5cff 0%,#c060e0 55%,#ff5fa2 100%);--accent-soft:rgba(181,124,255,.16);--warn:#ffb955;--warn-soft:rgba(255,185,85,.16);--ok:#4fe3c4;--ok-soft:rgba(79,227,196,.14);--danger:#ff6584;--shadow-raised:-6px -6px 14px rgba(255,255,255,.035),8px 8px 20px rgba(0,0,0,.45);--shadow-sunk:inset 4px 4px 10px rgba(0,0,0,.35),inset -3px -3px 8px rgba(255,255,255,.04);--shadow:var(--shadow-raised);--shadow-in:var(--shadow-sunk)}
[data-theme="cian"]{--bg:#182236;--surface:#1e2a42;--surface2:#273552;--border:rgba(255,255,255,.06);--text:#eef5ff;--muted:#9fb1cc;--faint:#919eb7;--accent:#3fd3ea;--accent-ink:#06121c;--grad:linear-gradient(135deg,#2f8bff 0%,#35cde6 60%,#5cf0c8 100%);--accent-soft:rgba(63,211,234,.16);--warn:#ffc35c;--warn-soft:rgba(255,195,92,.16);--ok:#5cf0c8;--ok-soft:rgba(92,240,200,.14);--danger:#ff6b88;--shadow-raised:-6px -6px 14px rgba(255,255,255,.035),8px 8px 20px rgba(0,0,0,.5);--shadow-sunk:inset 4px 4px 10px rgba(0,0,0,.4),inset -3px -3px 8px rgba(255,255,255,.04);--shadow:var(--shadow-raised);--shadow-in:var(--shadow-sunk)}
[data-theme="coral"]{--bg:#2b1d2c;--surface:#332336;--surface2:#402c43;--border:rgba(255,255,255,.06);--text:#fff3f1;--muted:#c9a9b0;--faint:#ac959c;--accent:#ff8a7a;--accent-ink:#2a1013;--grad:linear-gradient(135deg,#ff5f8d 0%,#ff8a5c 60%,#ffc15c 100%);--accent-soft:rgba(255,138,122,.16);--warn:#ffcf5c;--warn-soft:rgba(255,207,92,.16);--ok:#7be0a8;--ok-soft:rgba(123,224,168,.14);--danger:#ff5f8d;--shadow-raised:-6px -6px 14px rgba(255,255,255,.035),8px 8px 20px rgba(0,0,0,.45);--shadow-sunk:inset 4px 4px 10px rgba(0,0,0,.35),inset -3px -3px 8px rgba(255,255,255,.04);--shadow:var(--shadow-raised);--shadow-in:var(--shadow-sunk)}
[data-theme="claro"]{--bg:#e7e9f3;--surface:#eef0f8;--surface2:#dfe2ee;--border:rgba(60,60,110,.06);--text:#22223a;--muted:#6a6b8c;--faint:#616287;--accent:#6f5cff;--accent-ink:#ffffff;--grad:linear-gradient(135deg,#6f5cff 0%,#c060e0 55%,#ff5fa2 100%);--accent-soft:rgba(111,92,255,.14);--warn:#c77d00;--warn-soft:rgba(199,125,0,.14);--ok:#0f9d82;--ok-soft:rgba(15,157,130,.14);--danger:#d63b5e;--shadow-raised:-6px -6px 14px rgba(255,255,255,.9),8px 8px 20px rgba(90,95,150,.22);--shadow-sunk:inset 4px 4px 10px rgba(90,95,150,.18),inset -3px -3px 8px rgba(255,255,255,.9);--shadow:var(--shadow-raised);--shadow-in:var(--shadow-sunk)}

/* El recorte horizontal y el freno de rebote van los dos en el elemento raíz,
   que es el que propaga sus reglas de desplazamiento a la ventana.

   Regresión del 2026-09-05, que dejó la aplicación sin scroll en el teléfono
   mientras la rueda del mouse andaba perfecta. `overflow-x: hidden` estaba
   además en el `body`, y eso convierte al body en su propio contenedor de
   desplazamiento. Un dedo apoyado ahí empuja ese contenedor, que no tiene nada
   que desplazar, y el movimiento tiene que encadenarse hacia la ventana para
   que la página se mueva. `overscroll-behavior-y: contain` en el body es
   justamente lo que prohíbe ese encadenamiento: el gesto moría en el body y no
   pasaba nada. La rueda no sigue ese camino, y por eso en la computadora no se
   veía.

   Medido a 390px con eventos táctiles reales: 0px de desplazamiento antes,
   399px después. */
html{overflow-x:hidden;overscroll-behavior-y:contain}
html,body{margin:0;background:var(--bg)}
body{font-family:Geist,system-ui,sans-serif;color:var(--text);-webkit-font-smoothing:antialiased}
a{color:var(--accent)}a:hover{color:var(--text)}
input,button,select{font:inherit;color:inherit}
input::placeholder{color:var(--faint)}
input[type=range]{accent-color:var(--accent)}
*{box-sizing:border-box}
@keyframes toastIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes hojaSube{from{transform:translateY(100%)}to{transform:none}}
@keyframes velo{from{opacity:0}to{opacity:1}}

/* El prototipo declaraba los estados de hover y foco con atributos propios del
   canvas. Acá son reglas normales, con los mismos valores. */
.hov:hover{border-color:var(--accent)}
.hovtext:hover{color:var(--accent)}
.hovbg:hover{background:var(--surface2)}
.hovbright:hover{filter:brightness(1.08)}
.hovdanger:hover{color:var(--danger);border-color:var(--danger)}
.hovmuted:hover{color:var(--text)}
.foc:focus{border-color:var(--accent)}
.mono{font-family:'JetBrains Mono',ui-monospace,monospace;font-variant-numeric:tabular-nums}

/* Respuesta al toque.

   En un celular no existe hover: sin esto, tocar una tarjeta no producía nada
   hasta que la pantalla se rehacía, y se sentía como que el toque no entró.
   `touch-action: manipulation` saca además el retardo del doble toque. */
button,[data-a],input{touch-action:manipulation}
button,[data-a]{-webkit-tap-highlight-color:transparent}
button:active,[data-a]:active{filter:brightness(1.35)}
.hovbg:active,.hov:active{background:var(--surface2)}

/* Objetivos de toque: 44px es el mínimo cómodo con el pulgar. Se aplica a lo
   que se toca de verdad, no a las filas de una lista, que ya son altas. */
.toque{min-height:44px}

/* El diseño mostraba escritorio y móvil con un selector de prototipo. En la app
   real lo decide el ancho de la ventana.

   Se declara solo el ocultar, y con !important: el diseño trae `display` en
   estilos en línea (grid para la barra de pestañas, flex para la barra
   lateral), que de otro modo le ganan a la clase. Así cada elemento conserva
   el display que le puso Franco cuando está visible. */
@media (max-width:899px){ .solo-escritorio{display:none!important} }
@media (min-width:900px){ .solo-movil{display:none!important} }

/* La barra de pestañas va fija al borde de la ventana.

   Antes usaba `position: sticky; bottom: 0` como último hijo de un contenedor
   del alto del contenido. Sticky con `bottom` solo impide que algo se vaya
   hacia arriba fuera de su contenedor: nunca lo levanta hasta el borde de la
   ventana. Medido: quedaba 161px por debajo del borde y había que arrastrar
   hasta el fondo para navegar.

   `--barra` es lo que mide la barra más el área segura del iPhone, y el
   contenido reserva ese espacio abajo para que nada quede tapado. */
:root{--alto-barra:64px;--barra:calc(var(--alto-barra) + env(safe-area-inset-bottom,0px))}

.barra-pestanas{
  position:fixed;
  left:0;right:0;bottom:0;
  z-index:30;
  padding-bottom:calc(10px + env(safe-area-inset-bottom,0px));
}

/* La hoja de filtros sube desde abajo, como el menú "Más" que ya existía. */
.velo{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:40;animation:velo .15s ease-out}
.hoja{
  position:fixed;left:0;right:0;bottom:0;z-index:41;
  max-height:85vh;overflow:auto;
  background:var(--surface);
  border-top:1px solid var(--border);
  border-radius:20px 20px 0 0;
  padding:8px 16px calc(20px + env(safe-area-inset-bottom,0px));
  animation:hojaSube .2s ease-out;
}
.asa{width:40px;height:4px;border-radius:2px;background:var(--surface2);margin:6px auto 14px}

/* El indicador de tirar para actualizar. Vive fuera de #raiz, que se rehace
   entero en cada pintada, y se mueve por estilo directo durante el arrastre. */
.tirador{
  position:fixed;top:8px;left:50%;z-index:20;
  width:38px;height:38px;border-radius:50%;
  display:grid;place-items:center;
  background:var(--surface);color:var(--accent);
  border:1px solid var(--border);
  box-shadow:var(--shadow-raised);
  opacity:0;pointer-events:none;
  transform:translate(-50%,0);
  transition:opacity .12s linear;
}
@media (min-width:900px){ .tirador{display:none} }

/* La barra de arriba mientras se traen datos nuevos.

   Cambiar de pestaña vaciaba la pantalla y ponía "Cargando…" en texto suelto,
   y después el contenido saltaba. Volviendo a una pantalla ya visitada eso no
   hace falta: se deja lo que había y esto avisa que viene algo. */
@keyframes progresoVa{from{transform:translateX(-100%)}to{transform:translateX(400%)}}
.progreso{
  position:fixed;top:0;left:0;right:0;height:2px;z-index:45;
  background:var(--surface2);overflow:hidden;pointer-events:none;
}
.progreso::after{
  content:"";display:block;height:100%;width:25%;
  background:var(--grad);
  animation:progresoVa 1s ease-in-out infinite;
}

/* Las cabeceras de día de la lista de movimientos se quedan arriba mientras se
   desplaza su grupo: mirando el medio de la lista se sigue sabiendo de qué día
   es lo que se está viendo. */
.dia{
  position:sticky;top:0;z-index:6;
  background:var(--bg);
  padding:6px 2px;
  margin:0 -2px;
}

/* Nada puede ensanchar la ventana.

   Un movimiento cargado por el agente guardaba el payload como una sola linea
   de JSON de trescientos caracteres sin un espacio. Esa linea estiraba su celda,
   la celda estiraba la grilla, y la pantalla entera se iba 158px fuera del
   viewport en un telefono de 390. Cualquier dato largo de verdad hace lo mismo:
   un nombre de comercio sin espacios, un identificador, un monto de siete
   cifras.

   Son tres capas, de la que arregla a la que contiene:

   1. `min-width: 0` desestima el minimo automatico de los hijos de flex y de
      grid, que por defecto es el ancho del contenido. Sin esto, un hijo largo
      empuja su pista y no hay envoltura que valga. Los estilos en linea del
      diseño que fijan un minimo propio le ganan a esta regla, que es lo que
      corresponde.
   2. `overflow-wrap: anywhere` en el texto libre: lo que no tiene donde cortar
      se corta igual, en vez de salirse.
   3. `overflow-x: clip` en la raiz es la garantia. Va `clip` y no `hidden` a
      proposito: `hidden` crearia un contenedor de desplazamiento y las
      cabeceras de dia pegadas dejarian de pegarse. */
#raiz{overflow-x:clip}
#raiz *{min-width:0}

/* Texto que viene de afuera y puede no tener donde cortar. */
.libre{overflow-wrap:anywhere;word-break:break-word}

/* El botón de cargar a mano, redondo y flotante sobre la barra de pestañas.

   Va abajo a la derecha porque es donde llega el pulgar sin cambiar el agarre
   del teléfono, y separado de las pestañas para no tocar una cosa queriendo la
   otra. Se levanta lo que mida la barra más el área segura, igual que el aviso. */
.boton-cargar{
  position:fixed;right:16px;bottom:calc(var(--barra) + 16px);z-index:31;
  width:56px;height:56px;border-radius:50%;
  display:grid;place-items:center;
  border:0;background:var(--grad);color:var(--accent-ink);
  box-shadow:0 6px 20px rgba(0,0,0,.35);
  cursor:pointer;
}
.boton-cargar:active{transform:scale(.94)}

/* Donde está el botón, el contenido reserva su alto además del de la barra: si
   no, llegando al final de la lista el botón tapa el monto de la última fila,
   que es justo lo que uno fue a mirar. Medido: la tapaba entera. */
@media (max-width:899px){
  .con-boton-cargar{padding-bottom:calc(var(--barra) + 88px)!important}
}

/* En una ventana ancha la hoja no tiene por qué ocupar todo el ancho: a 1280
   una columna de campos de punta a punta no se lee. */
@media (min-width:900px){
  .hoja{
    left:50%;right:auto;transform:translateX(-50%);
    width:min(520px, calc(100% - 48px));
    border-radius:20px 20px 0 0;
  }
  @keyframes hojaSube{from{transform:translate(-50%,100%)}to{transform:translate(-50%,0)}}
}
