/* Lo propio de Finanzas. AdminLTE no se toca: si algo hay que cambiar, va aca.
 *
 * Dos reglas que atraviesan todo el archivo:
 *
 *   1. Ningun dato se codifica SOLO con color. Toda barra lleva su nombre y su
 *      valor en texto, y donde hay dos series se distinguen ademas por textura.
 *      Un daltonismo, una pantalla al sol o una impresion en blanco y negro no
 *      deberian borrar informacion.
 *   2. Todo tiene que leerse en un celular de ~375px de ancho. La pagina nunca
 *      se desliza de costado: solo las tablas, adentro de su propia caja.
 */

/* ---------- Los colores ----------
 *
 * Todo el diseno cuelga de estas nueve variables, asi que cambiar de tema es
 * redefinirlas y nada mas.
 *
 * Los colores del tema claro NO son los del oscuro aclarados: son otros tonos,
 * elegidos contra el fondo blanco y medidos. Un azul que se lee bien sobre
 * #1b1b1b se pierde sobre blanco, y al reves. Se verificaron con el validador
 * de la guia de visualizacion: contraste contra el fondo >= 3:1 y separacion
 * entre el azul y el violeta, que es el unico par que aparece lado a lado (la
 * barra de gasto comprometido contra discrecional).
 *
 * El violeta cambio en los DOS temas. El anterior, #9b7ede, estaba a 1.7 de
 * distancia del azul para un ojo con deuteranopia y a 11.0 para uno sin nada:
 * dos barras pegadas que se veian del mismo color. Ahora son 8.5 y 22.8.
 */

:root {
  --fin-fondo-pagina: #121212;
  --fin-fondo-caja: #1b1b1b;
  --fin-fondo-hueco: #232323;
  --fin-borde: #333333;
  --fin-verde: #2fb380;
  --fin-rojo: #e5484d;
  --fin-amarillo: #f0b429;
  --fin-azul: #4c9be8;
  /* Sin uso hoy: era la mitad discrecional de la barra de gasto comprometido,
     que salio del panel. Se deja medido para cuando vuelva: contra el azul da
     8.5 de separacion en deuteranopia y 22.8 a ojo normal. El anterior,
     #9b7ede, daba 1.7 y 11.0, o sea dos barras del mismo color. */
  --fin-violeta: #f08ab5;
}

[data-bs-theme='light'] {
  --fin-fondo-pagina: #f4f5f7;
  --fin-fondo-caja: #ffffff;
  --fin-fondo-hueco: #eceef1;
  --fin-borde: #d9dce1;
  --fin-verde: #0f7b55;
  --fin-rojo: #c0282d;
  --fin-amarillo: #9a6700;
  --fin-azul: #1f6feb;
  /* Idem, medido contra el fondo claro: 14.0 y 25.1. */
  --fin-violeta: #b3309c;

  --bs-body-bg: var(--fin-fondo-pagina);
  --bs-secondary-bg: var(--fin-fondo-caja);
  --bs-tertiary-bg: var(--fin-fondo-caja);
  --bs-border-color: var(--fin-borde);
  --bs-primary: var(--fin-azul);
  --bs-primary-rgb: 31, 111, 235;
  --bs-link-color: var(--fin-azul);
  --bs-link-hover-color: #1a5fd0;
}

[data-bs-theme='dark'] {
  --bs-body-bg: var(--fin-fondo-pagina);
  --bs-body-bg-rgb: 18, 18, 18;
  --bs-body-color: #f1f1f1;
  --bs-secondary-bg: var(--fin-fondo-caja);
  --bs-tertiary-bg: var(--fin-fondo-caja);
  --bs-border-color: var(--fin-borde);
  --bs-emphasis-color: #ffffff;
  --bs-primary: var(--fin-azul);
  --bs-primary-rgb: 76, 155, 232;
  --bs-link-color: var(--fin-azul);
  --bs-link-hover-color: #79b8ef;
}

/* Las tarjetas tienen que verse mas claras que la pagina, igual que el bloque
   del patrimonio. Esto va sobre .card y no adentro de [data-bs-theme] porque
   Bootstrap declara --bs-card-bg SOBRE LA PROPIA .card:

       .card { ... --bs-card-bg: var(--bs-body-bg) }

   y una variable declarada en el elemento le gana a la que hereda de arriba.
   Puesto en el tema, el valor se escribia y nunca llegaba: las tarjetas salian
   del mismo color que el fondo y parecian transparentes. */
.card {
  --bs-card-bg: var(--fin-fondo-caja);
  --bs-card-border-color: var(--fin-borde);
}

/* ---------- Entrar ---------- */

#pantalla-login {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

#pantalla-login .card {
  width: 100%;
  max-width: 26rem;
  background: var(--fin-fondo-caja);
  border: 1px solid var(--fin-borde);
}

#pantalla-login .form-control {
  font-size: 1.1rem;
  padding: 0.65rem 1rem;
}

/* ---------- El menu ---------- */

#pantalla-app .sidebar-menu .nav-link.active {
  background-color: var(--fin-azul);
  color: #ffffff;
  font-weight: 600;
}

/* ---------- El aviso ----------
   Flota arriba de todo, incluso encima de un modal abierto: el error de una
   funcion de la base se tiene que ver justo donde se estaba trabajando. */

#fin-aviso {
  position: fixed;
  left: 50%;
  bottom: 1rem;
  transform: translateX(-50%);
  z-index: 2000;
  max-width: min(32rem, calc(100vw - 2rem));
  margin: 0;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.5);
}

/* ---------- Tipografia comun ---------- */

.fin-subtitulo {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.7;
  margin: 1.25rem 0 0.5rem;
}

.fin-subtitulo:first-child {
  margin-top: 0;
}

.fin-rotulo {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.65;
}

.fin-nota {
  font-size: 0.8rem;
  opacity: 0.7;
  overflow-wrap: break-word;
}

/* Las cifras van en la MISMA familia que el resto y con digitos de ancho
   fijo: columnas de plata que bailan de ancho se leen como ruido. El 800 de
   antes hacia que el navegador sintetizara un peso que no existe en la fuente
   y salia otra letra. */
.fin-cifra {
  font-family: inherit;
  font-size: 1.5rem;
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
  margin-top: 0.15rem;
  overflow-wrap: break-word;
}

.fin-cifra-ok {
  color: var(--fin-verde);
}

.fin-cifra-mal {
  color: var(--fin-rojo);
}

/* ---------- Tarjetas del panel ---------- */

.fin-tarjetas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.fin-tarjeta {
  padding: 0.95rem 1.05rem;
  border-radius: 0.6rem;
  background: var(--fin-fondo-caja);
  border: 1px solid var(--fin-borde);
  min-width: 0;
}

/* Las cuatro tarjetas del mes pesan lo mismo: son cuatro lecturas del mismo
   mes, ninguna manda sobre las otras. La tasa de ahorro lleva una linea de
   acento al costado, no un tamano distinto: marcarla agrandandola competia
   con el patrimonio de arriba, que si es el numero principal. */
.fin-tarjeta-acento {
  border-left: 3px solid var(--fin-azul);
}

/* ---------- El patrimonio: el numero principal del panel ----------
   Va arriba, suelto, sin card que lo envuelva. Antes vivia al fondo adentro de
   una caja adentro de otra caja, y el dato mas importante quedaba chico. */

.fin-hero-caja {
  margin-bottom: 1rem;
}

.fin-hero {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 0.75rem;
}

.fin-hero-moneda {
  padding: 1.3rem 1.4rem;
  border-radius: 0.75rem;
  background: var(--fin-fondo-caja);
  border: 1px solid var(--fin-borde);
  min-width: 0;
}

.fin-hero-cifra {
  font-family: inherit;
  font-size: clamp(2.1rem, 5.5vw, 3rem);
  font-weight: 650;
  line-height: 1.05;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
  margin-top: 0.3rem;
  overflow-wrap: break-word;
}

/* Las tres partes del patrimonio, una al lado de la otra y separadas por una
   linea: son el desglose del numero de arriba, no una lista aparte. */
.fin-hero-partes {
  display: flex;
  flex-wrap: wrap;
  /* Flex y no grid a proposito: con grid de fracciones las tres partes se
     estiran hasta los bordes y en una pantalla ancha quedan a medio metro una
     de otra, como si no tuvieran nada que ver entre si. Son el desglose de un
     mismo numero: van juntas, a la izquierda, y el aire sobra a la derecha. */
  gap: 0.85rem 2.75rem;
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--fin-borde);
}

.fin-hero-parte {
  min-width: 6.5rem;
}

.fin-hero-parte-valor {
  font-size: 1.05rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  margin-top: 0.15rem;
  overflow-wrap: break-word;
}

.fin-hero-parte-nota {
  font-size: 0.72rem;
  opacity: 0.55;
  margin-top: 0.1rem;
}

/* ---------- Vacios ----------
   Un bloque sin datos no puede pesar lo mismo que uno con datos: ocupa menos y
   se apaga, para que el ojo pase de largo en vez de leer cuatro veces que no
   hay nada. */

.fin-vacio {
  font-size: 0.88rem;
  opacity: 0.5;
  margin: 0;
}

section[data-vista='panel'] .card-header,
section[data-vista='reportes'] .card-header {
  padding-top: 0.7rem;
  padding-bottom: 0.7rem;
}

section[data-vista='panel'] .card-title,
section[data-vista='reportes'] .card-title {
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.7;
}

/* ---------- Barras y proporciones ----------
   Sin libreria de graficos: ancho en porcentaje mas el numero al lado. */

.fin-barra-pista {
  width: 100%;
  height: 0.85rem;
  border-radius: 0.5rem;
  background: var(--fin-fondo-hueco);
  border: 1px solid var(--fin-borde);
  overflow: hidden;
}

.fin-barra-relleno {
  height: 100%;
  border-radius: 0.5rem;
  background: var(--fin-azul);
  transition: width 0.2s ease;
}

.fin-barra-relleno.fin-barra-alerta {
  background: var(--fin-amarillo);
}

.fin-barra-relleno.fin-barra-mal {
  background: var(--fin-rojo);
}

/* Una sola barra partida en dos. El segundo tramo va rayado ademas de tener
   otro color: asi se distinguen tambien sin ver color. */
/* ---------- Patrimonio ----------
   Una caja por moneda. No hay caja de total combinado a proposito. */

.fin-patrimonio {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.75rem;
}

.fin-patrimonio-moneda {
  padding: 0.9rem;
  border-radius: 0.6rem;
  background: var(--fin-fondo-hueco);
  border: 1px solid var(--fin-borde);
  min-width: 0;
}

.fin-detalle {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.15rem 0.75rem;
  margin: 0.75rem 0 0;
  font-size: 0.88rem;
}

.fin-detalle dt {
  font-weight: 400;
  opacity: 0.75;
  min-width: 0;
  overflow-wrap: break-word;
}

.fin-detalle dd {
  margin: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- Registrar movimiento ----------
   El monto es lo primero, lo mas grande y lo que tiene el foco. */

.fin-monto-grande {
  font-size: 1.75rem;
  font-weight: 700;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.fin-campo-monto .input-group-text {
  font-size: 1.2rem;
  min-width: 3.5rem;
  justify-content: center;
}

.fin-segmento .btn {
  font-weight: 600;
}

.fin-mas {
  border-top: 1px solid var(--bs-border-color);
  padding-top: 0.75rem;
}

.fin-mas > summary {
  cursor: pointer;
  font-size: 0.9rem;
  opacity: 0.8;
  list-style-position: inside;
}

.fin-mas > summary:hover {
  opacity: 1;
}

/* Filas de la division. Categoria ancha, monto angosto, nota flexible, quitar
   pegado a la derecha. En celular cada fila se apila. */
.fin-partida-fila {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(5.5rem, 0.8fr) minmax(0, 1fr) auto;
  gap: 0.4rem;
  margin-bottom: 0.4rem;
  align-items: center;
}

.fin-partida-monto {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.fin-resto {
  font-weight: 700;
  font-size: 0.95rem;
}

.fin-resto-falta {
  color: var(--fin-amarillo);
}

.fin-resto-sobra {
  color: var(--fin-rojo);
}

.fin-resto-ok {
  color: var(--fin-verde);
}

/* ---------- Lista de movimientos ---------- */

/* Tachado ademas de opaco: no depende solo de un color para leerse. */
.fin-anulado {
  opacity: 0.55;
  text-decoration: line-through;
}

.fin-motivo {
  text-decoration: none;
  opacity: 0.9;
}

/* La fila recien guardada se marca sola por un momento, para saber que entro. */
.fin-fila-nueva > td {
  box-shadow: inset 0.25rem 0 0 var(--fin-verde);
}

.fin-detalle-partidas td {
  background: var(--fin-fondo-hueco);
}

.fin-lista-partidas {
  list-style: none;
  margin: 0;
  padding: 0.25rem 0;
}

.fin-lista-partidas li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem;
  padding: 0.2rem 0;
}

.fin-partida-nombre {
  font-weight: 600;
}

.fin-partida-valor {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- Presupuesto (sobres) ---------- */

.fin-resumen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 0.75rem;
}

.fin-resumen-item {
  padding: 0.75rem;
  border-radius: 0.5rem;
  background: var(--fin-fondo-hueco);
  border: 1px solid var(--fin-borde);
  min-width: 0;
}

.fin-resumen-valor {
  font-size: 1.35rem;
  font-weight: 700;
  overflow-wrap: break-word;
}

.fin-sobre {
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--bs-border-color);
}

.fin-sobre:last-child {
  border-bottom: 0;
}

.fin-sobre-encabezado {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.fin-sobre-nombre {
  font-weight: 600;
  min-width: 0;
  overflow-wrap: break-word;
}

.fin-sobre-cifra {
  font-size: 1.45rem;
  font-weight: 800;
  line-height: 1.2;
  margin-top: 0.35rem;
}

/* El arrastre es el punto entero del diseno de sobres: cuando llega plata del
   mes pasado se dice con todas las letras, no se deduce de dos numeros. */
.fin-arrastre {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  font-size: 0.85rem;
  padding: 0.45rem 0.6rem;
  border-radius: 0.4rem;
  background: rgba(47, 179, 128, 0.12);
  border: 1px solid rgba(47, 179, 128, 0.4);
  color: #8fe0be;
}

/* ---------- Cuentas ---------- */

.fin-moneda-encabezado {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.5rem 0 0.35rem;
  border-bottom: 1px solid var(--bs-border-color);
  margin-bottom: 0.5rem;
}

.fin-cuenta {
  padding: 0.75rem;
  border-radius: 0.5rem;
  background: var(--fin-fondo-hueco);
  border: 1px solid var(--fin-borde);
  margin-bottom: 0.6rem;
}

.fin-cuenta-inactiva {
  opacity: 0.55;
}

.fin-cuenta-arriba {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem;
}

.fin-cuenta-rotulo {
  font-weight: 600;
  overflow-wrap: break-word;
}

.fin-cuenta-monto {
  font-size: 1.2rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.fin-cuenta-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.6rem;
}

/* ---------- Programados ---------- */

.fin-vencido {
  color: var(--fin-rojo);
  font-weight: 700;
}

.fin-vence-hoy {
  color: var(--fin-amarillo);
  font-weight: 700;
}

.fin-vence-pronto {
  font-weight: 600;
}

/* ---------- Categorias ---------- */

.fin-grupo {
  padding: 0.75rem;
  border-radius: 0.5rem;
  background: var(--fin-fondo-hueco);
  border: 1px solid var(--fin-borde);
  margin-bottom: 0.6rem;
}

.fin-grupo-encabezado {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.fin-grupo-rotulo {
  font-weight: 700;
}

.fin-categorias {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 0.4rem;
}

.fin-categoria {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.6rem;
  border-radius: 0.4rem;
  background: var(--fin-fondo-caja);
  border: 1px solid var(--fin-borde);
  min-width: 0;
}

.fin-categoria-nombre {
  overflow-wrap: break-word;
  min-width: 0;
}

.fin-categoria-inactiva {
  opacity: 0.55;
}

/* ---------- La barra lateral ----------
 *
 * Todo lo que no es navegacion se fue de la barra de arriba para aca: el boton
 * de Registrar arriba del menu, y al fondo la fecha, el usuario y la salida.
 * La barra de arriba queda con el hamburguesa y nada mas.
 */

/* La barra entra al sistema de temas del proyecto. Los grises que traia
   AdminLTE (#343a40 en oscuro, #e9ecef en claro) no salen de esta paleta y en
   claro quedaban a once unidades del fondo de la pagina: la barra y el
   contenido se fundian y no se veia donde terminaba una y empezaba el otro.

   El criterio es el mismo que en el resto de la app: las SUPERFICIES son del
   color de la tarjeta y el SUELO es el de la pagina. La barra es una
   superficie, igual que una tarjeta.

   Y lleva raya a la derecha, que es lo que de verdad marca el limite. En
   oscuro la diferencia de fondo alcanzaba sola; en claro no, y apoyarse solo
   en ella era dejar el borde a merced de cuanto brillo tenga la pantalla. */
.app-sidebar {
  display: flex;
  flex-direction: column;
  background-color: var(--fin-fondo-caja) !important;
  border-right: 1px solid var(--fin-borde);
}

.app-sidebar .sidebar-wrapper {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.fin-sidebar-pie {
  flex: 0 0 auto;
  padding: 0.75rem 0.9rem;
  border-top: 1px solid var(--fin-borde);
}

.fin-sidebar-fecha {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.5;
  margin-bottom: 0.35rem;
}

.fin-sidebar-usuario {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

/* El correo puede ser largo y la barra es angosta: se corta con puntos en vez
   de empujar el boton de salir fuera de la pantalla. */
.fin-sidebar-quien {
  min-width: 0;
  font-size: 0.82rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fin-sidebar-usuario a {
  flex: 0 0 auto;
  color: inherit;
  opacity: 0.7;
  font-size: 1.05rem;
  line-height: 1;
}

.fin-sidebar-usuario a:hover {
  opacity: 1;
}

/* ---------- La franja de arriba ----------
   Arriba de 992px no existe: el hamburguesa esta adentro de la barra lateral y
   una franja entera de pantalla para no mostrar nada es espacio regalado.
   Abajo de 992px la barra lateral esta escondida del todo, asi que esa franja
   es la UNICA manera de abrirla y tiene que quedarse. */
.app-header .nav-link {
  padding-top: 0.4rem;
  padding-bottom: 0.4rem;
}

@media (min-width: 62rem) {
  .app-header {
    display: none;
  }
}

/* El hamburguesa de adentro de la barra, al lado del nombre. */
.fin-marca {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.fin-plegar {
  flex: 0 0 auto;
  color: inherit;
  opacity: 0.6;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0.35rem 0.5rem;
}

.fin-plegar:hover {
  color: inherit;
  opacity: 1;
}

/* Abajo de 992px el hamburguesa de la franja de arriba es el que manda: dejar
   los dos seria ofrecer dos botones para lo mismo a dos centimetros. */
@media (max-width: 61.9375rem) {
  .fin-plegar {
    display: none;
  }
}

/* ---------- Barra lateral plegada (modo mini) ----------
   AdminLTE achica la barra a 4.6rem y esconde el texto de SUS propios items.
   Lo de abajo hace lo mismo con los bloques propios de este proyecto: el boton
   de Registrar queda como un mas, y del pie sobrevive solo la salida.

   Ya NO cuelgan de :not(:hover). Antes si, porque AdminLTE volvia a abrir la
   barra entera al pasar el mouse y lo escondido tenia que reaparecer. Con
   sidebar-without-hover eso no pasa mas, y dejar el :not(:hover) seria peor
   que inutil: al pasar el mouse reaparecerian el correo y la fecha adentro de
   una columna de 4.6rem, desbordandola. */

.sidebar-mini.sidebar-collapse .app-sidebar .fin-sidebar-fecha,
.sidebar-mini.sidebar-collapse .app-sidebar .fin-sidebar-quien {
  display: none;
}

.sidebar-mini.sidebar-collapse .app-sidebar .fin-sidebar-pie {
  padding-left: 0.6rem;
  padding-right: 0.6rem;
}

.sidebar-mini.sidebar-collapse .app-sidebar .fin-sidebar-usuario {
  justify-content: center;
}

.sidebar-mini.sidebar-collapse .app-sidebar .fin-marca {
  justify-content: center;
}

/* ---------- La barra de abajo (solo en celular) ----------
 *
 * Reemplaza al menu lateral en el telefono. El hamburguesa vivia en la esquina
 * de arriba a la izquierda, que es la mas lejos del pulgar de cualquier mano, y
 * cambiar de pantalla costaba dos toques: abrir el menu y elegir. Aca cuesta
 * uno y la mano no se mueve.
 *
 * Cuatro items y "Mas". Siete no entran sin que cada uno quede de un centimetro,
 * y con menos de 44px de alto un dedo no le acierta.
 */

.fin-barra-abajo {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1035;
  background: var(--fin-fondo-caja);
  border-top: 1px solid var(--fin-borde);
  /* La franja del gesto de inicio en los telefonos sin boton fisico: sin esto
     el dedo del sistema se come el toque del ultimo item. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.fin-abajo-item {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  padding: 0.5rem 0.2rem;
  border: 0;
  background: none;
  color: inherit;
  opacity: 0.6;
  text-decoration: none;
  font-size: 0.68rem;
}

.fin-abajo-item i {
  font-size: 1.25rem;
  line-height: 1;
}

.fin-abajo-item span {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El item activo va en color Y en opacidad llena: el color solo no alcanza
   cuando los cinco iconos son del mismo gris. */
.fin-abajo-item.active {
  opacity: 1;
  color: var(--fin-azul);
}

/* ---------- La hoja de "Mas" ---------- */

/* Dos clases en el selector, no una, y la altura por VARIABLE y no por valor.
   Bootstrap define la hoja asi:

       .offcanvas.offcanvas-bottom { height: var(--bs-offcanvas-height); max-height: 100% }

   Con un solo .fin-hoja el navegador le daba la razon a Bootstrap por
   especificidad, y la hoja quedaba clavada en 30vh: entraban tres items y los
   otros cuatro caian abajo del borde de la pantalla, sin forma de llegar.

   Es la misma trampa que con --bs-card-bg: a una variable que la libreria
   declara sobre el propio elemento hay que pisarla EN ese elemento, no
   heredandola de arriba. */
.offcanvas.fin-hoja {
  /* auto para que mida lo que mide su contenido, con techo para que nunca pase
     de la pantalla; lo que sobre se desliza adentro de la lista. */
  --bs-offcanvas-height: auto;
  max-height: 80vh;
}

.fin-hoja {
  border-top: 1px solid var(--fin-borde);
  border-top-left-radius: 1rem;
  border-top-right-radius: 1rem;
  background: var(--fin-fondo-caja);
}

.fin-hoja-lista {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  overflow-y: auto;
  /* La hoja TAPA la barra de abajo (z-index 1045 contra 1035), asi que no hay
     que dejarle lugar: reservarle cuatro centimetros solo estiraba la hoja con
     un hueco vacio al final. Queda el inset del gesto de inicio, que si hace
     falta en los telefonos sin boton fisico. */
  padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
}

.fin-hoja-item {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.8rem 0.5rem;
  border-radius: 0.5rem;
  color: inherit;
  text-decoration: none;
}

.fin-hoja-item i {
  font-size: 1.15rem;
  opacity: 0.7;
  width: 1.5rem;
  text-align: center;
}

/* El pie de la hoja: separado por una raya, como el de la barra lateral. Es
   informacion de fondo, no otra opcion mas de la lista. */
.fin-hoja-pie {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--fin-borde);
}

.fin-hoja-item:hover,
.fin-hoja-item:focus {
  background: var(--fin-fondo-hueco);
  color: inherit;
}

/* ---------- El boton flotante ----------
   Solo abajo de 992px, que es donde sidebar-expand-lg esconde la barra lateral.
   Arriba de eso el boton de la barra ya esta visible y este seria un duplicado
   tapando contenido. */

.fin-flotante {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  right: 1rem;
  /* El inset de abajo deja libre la franja del gesto de inicio en los telefonos
     sin boton fisico; sin eso el dedo del sistema se come el toque. */
  bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  z-index: 1030;
  width: 3.5rem;
  height: 3.5rem;
  border: 0;
  border-radius: 50%;
  background: var(--fin-azul);
  color: #ffffff;
  font-size: 1.4rem;
  line-height: 1;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
}

.fin-flotante:active {
  transform: scale(0.94);
}

/* Aire al final de toda pantalla para que el boton no tape la ultima fila. */
.app-content {
  padding-bottom: 5.5rem;
}

@media (max-width: 61.9375rem) {
  .fin-barra-abajo {
    display: flex;
  }

  /* La franja de arriba existia solo para el hamburguesa, y el hamburguesa
     existia solo para abrir el menu lateral. Con la barra de abajo ninguno de
     los dos hace falta: son dos centimetros de pantalla recuperados. */
  .app-header {
    display: none;
  }

  /* El flotante sube por encima de la barra. Sin esto tapa el item del medio,
     que es justo el mas facil de tocar. */
  .fin-flotante {
    bottom: calc(5rem + env(safe-area-inset-bottom, 0px));
  }

  /* Aire al final para que ni la barra ni el flotante tapen la ultima fila. */
  .app-content {
    padding-bottom: 8rem;
  }
}

/* El contenido arranca pegado a la barra de arriba: AdminLTE deja muy poco
   aire y el bloque del patrimonio, que es grande, queda como colgado del borde.
   Un respiro arriba separa "donde estoy" de "que estoy mirando". */
.app-content {
  padding-top: 1.25rem;
}

/* ---------- Reportes ----------
 *
 * Sin libreria de graficos: SVG a mano, igual que el resto del proyecto. Tres
 * reglas que vienen de la guia de visualizacion y que acá se cumplen a mano:
 *
 *   1. Marcas finas y grilla casi invisible. Los bloques gruesos y saturados
 *      del tablero viejo gritan sin decir nada; la tinta se gasta en el dato.
 *   2. Un solo eje por grafico, nunca dos escalas en el mismo dibujo: alinear
 *      dos escalas distintas inventa una correlacion que no esta en los datos.
 *   3. Un ranking lleva UN solo color para todas sus barras. Pintar mas oscura
 *      la barra mas larga codifica dos veces el mismo dato y quema el unico
 *      canal libre que quedaba.
 */

.fin-filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: flex-end;
  margin-bottom: 1rem;
}

.fin-filtro {
  min-width: 9rem;
}

.fin-filtro .form-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.6;
  margin-bottom: 0.2rem;
}

/* El lienzo. position relative porque el globo de datos se posiciona encima. */
.fin-lienzo {
  position: relative;
  width: 100%;
}

.fin-lienzo svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Grilla y ejes recesivos: tienen que poder ignorarse. Nunca punteados: el
   punteado mete ruido y se lee como "dato estimado", que es otra cosa. */
.fin-grilla {
  stroke: var(--fin-borde);
  stroke-width: 1;
  shape-rendering: crispEdges;
}

.fin-eje-texto {
  fill: currentColor;
  opacity: 0.55;
  font-size: 0.7rem;
}

.fin-serie-linea {
  fill: none;
  stroke: var(--fin-azul);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.fin-serie-area {
  fill: var(--fin-azul);
  opacity: 0.12;
}

/* El anillo del color del fondo separa el punto de la linea que pasa debajo. */
.fin-serie-punto {
  fill: var(--fin-azul);
  stroke: var(--fin-fondo-caja);
  stroke-width: 2;
}

.fin-dato-rotulo {
  fill: currentColor;
  font-size: 0.72rem;
  font-weight: 600;
}

.fin-barra-ingreso {
  fill: var(--fin-verde);
}

.fin-barra-egreso {
  fill: var(--fin-rojo);
}

.fin-cruz {
  stroke: currentColor;
  stroke-width: 1;
  opacity: 0.35;
}

/* El globo de datos. Nace oculto y no intercepta el mouse: si lo hiciera, se
   escaparia de abajo del cursor y parpadearia. */
.fin-globo {
  position: absolute;
  pointer-events: none;
  z-index: 5;
  min-width: 8rem;
  padding: 0.5rem 0.65rem;
  border-radius: 0.5rem;
  background: var(--fin-fondo-hueco);
  border: 1px solid var(--fin-borde);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  font-size: 0.8rem;
  transform: translate(-50%, -115%);
}

.fin-globo-titulo {
  font-weight: 600;
  margin-bottom: 0.2rem;
}

.fin-globo-fila {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-variant-numeric: tabular-nums;
}

/* La leyenda SIEMPRE esta cuando hay dos series o mas: la identidad no puede
   depender solo del color. */
.fin-leyenda-grafico {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.1rem;
  margin-bottom: 0.75rem;
  font-size: 0.8rem;
}

.fin-leyenda-punto {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 0.2rem;
  margin-right: 0.35rem;
  vertical-align: -0.05em;
}

/* ---------- Ranking de barras horizontales ----------
   Nombre arriba, valor a la derecha, barra abajo: el dato se lee en texto aunque
   la barra no se vea (daltonismo, pantalla al sol, impresion en gris). */

.fin-ranking {
  display: grid;
  gap: 0.6rem 2rem;
}

/* Un ranking que ocupa toda la pantalla deja barras de metro y medio para
   comparar cuatro cuentas. En caja ancha se parte en columnas. */
@media (min-width: 62rem) {
  .fin-ranking-ancho {
    grid-template-columns: 1fr 1fr;
  }
}

.fin-ranking-fila {
  min-width: 0;
}

.fin-ranking-encabezado {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.85rem;
  margin-bottom: 0.2rem;
}

.fin-ranking-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fin-ranking-valor {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  opacity: 0.8;
}

.fin-ranking-pista {
  height: 0.45rem;
  border-radius: 0.25rem;
  background: var(--fin-fondo-hueco);
  overflow: hidden;
}

.fin-ranking-relleno {
  height: 100%;
  border-radius: 0.25rem;
  background: var(--fin-azul);
}

/* ---------- La lista de cada tarjeta del panel ----------
 *
 * Las listas van completas, asi que se deslizan adentro de su propia caja. Si
 * creciera la pagina, tres tarjetas de 2, 17 y 18 filas dejarian el Panel de
 * dos metros de alto y habria que bajar media pantalla para ver la tercera.
 *
 * El alto es FIJO y no "lo que mida el contenido": asi las tres tarjetas miden
 * igual aunque una tenga dos filas y otra dieciocho, y la fila de abajo queda
 * pareja. Esta elegido para que se corte a mitad de una fila, que es la unica
 * senal honesta de que hay mas abajo: un corte limpio parece el final.
 */

.fin-top {
  margin-top: 1rem;
}

.fin-top,
.fin-lista-scroll {
  max-height: 20rem;
  overflow-y: auto;
  /* Sin esto, el borde del relleno de la ultima barra queda pegado a la barra
     de deslizamiento. */
  padding-right: 0.35rem;
}

/* Barra de deslizamiento fina y siempre a la vista. La de por defecto en
   Windows es ancha y clara, y adentro de una tarjeta oscura canta. */
.fin-top,
.fin-lista-scroll {
  scrollbar-width: thin;
  scrollbar-color: var(--fin-borde) transparent;
}

.fin-top::-webkit-scrollbar,
.fin-lista-scroll::-webkit-scrollbar {
  width: 0.4rem;
}

.fin-top::-webkit-scrollbar-track,
.fin-lista-scroll::-webkit-scrollbar-track {
  background: transparent;
}

.fin-top::-webkit-scrollbar-thumb,
.fin-lista-scroll::-webkit-scrollbar-thumb {
  background: var(--fin-borde);
  border-radius: 0.2rem;
}

.fin-top::-webkit-scrollbar-thumb:hover,
.fin-lista-scroll::-webkit-scrollbar-thumb:hover {
  background: var(--fin-azul);
}

/* La barra del top del mismo color que la cifra grande de su tarjeta: verde lo
   que entra, rojo lo que sale. Con la cifra verde y la barra azul, la tarjeta
   se leia como dos cosas distintas pegadas una encima de la otra.
   (.fin-barra-ingreso y .fin-barra-egreso ya existian para las barras SVG de
   Reportes, pero aquellas pintan con fill y estas con background: mismo
   significado, propiedad distinta, no se pisan.) */
.fin-ranking-relleno.fin-barra-ingreso {
  background: var(--fin-verde);
}

.fin-ranking-relleno.fin-barra-egreso {
  background: var(--fin-rojo);
}

/* ---------- El bloque del patrimonio, en dos columnas ----------
   A la izquierda el numero y de que esta hecho; a la derecha donde esta
   guardado. Antes las cuentas iban debajo y sobraba media pantalla a la derecha
   del numero grande.

   La columna de cuentas se mide por su contenido (auto) y la otra se come el
   resto (1fr), no al reves: una lista de montos tiene un ancho natural, y
   estirarla deja el nombre y la cifra separados por medio metro. */
.fin-hero-cuerpo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 1.25rem 2.5rem;
  align-items: start;
}

.fin-hero-principal {
  min-width: 0;
}

.fin-hero-cuentas {
  min-width: 0;
  padding-left: 2.5rem;
  border-left: 1px solid var(--fin-borde);
}

.fin-cuenta-fila {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2rem;
  padding: 0.3rem 0;
  font-size: 0.9rem;
}

.fin-cuenta-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fin-cuenta-saldo {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Angosto: las dos columnas se apilan y la raya vertical pasa a ser
   horizontal, que es la que separa cuando una cosa esta debajo de la otra. */
@media (max-width: 55rem) {
  .fin-hero-cuerpo {
    grid-template-columns: 1fr;
  }

  .fin-hero-cuentas {
    padding-left: 0;
    padding-top: 1rem;
    border-left: 0;
    border-top: 1px solid var(--fin-borde);
  }
}

/* El mismo semaforo que las barras del presupuesto, para las del panel: a
   partir del 80% avisa, pasado el 100% alarma. El color nunca va solo, siempre
   lleva el porcentaje al lado y el texto de cuanto queda debajo. */
.fin-ranking-relleno.fin-barra-alerta {
  background: var(--fin-amarillo);
}

.fin-ranking-relleno.fin-barra-mal {
  background: var(--fin-rojo);
}

/* ---------- Cabecera de tabla con filtros plegados ----------
 *
 * Los filtros vivian sueltos en la cabecera y la hacian crecer a dos o tres
 * renglones segun el ancho, empujando la tabla hacia abajo. Metidos adentro de
 * un desplegable, la cabecera mide siempre lo mismo y lo que se ve es la tabla,
 * que es a lo que se vino.
 *
 * El embudo lleva un punto cuando hay un filtro puesto: un desplegable cerrado
 * no deja ver que adentro hay algo cambiado, y sin esa senal se mira una lista
 * recortada creyendo que es la lista entera.
 */

.fin-barra-tabla {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: nowrap;
  min-width: 0;
}

.fin-barra-tabla .card-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fin-conteo {
  flex: 0 0 auto;
  font-size: 0.78rem;
  opacity: 0.55;
  white-space: nowrap;
}

.fin-boton-filtro {
  position: relative;
  flex: 0 0 auto;
}

.fin-filtro-marca {
  position: absolute;
  top: -0.2rem;
  right: -0.2rem;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--fin-azul);
  border: 2px solid var(--fin-fondo-caja);
}

.fin-panel-filtro {
  /* Bootstrap reposiciona el desplegable con JS al abrirlo, pero si eso llegara
     a fallar el panel se iria por el borde derecho y quedaria la mitad afuera.
     Esto lo ancla a la derecha igual, y el ancho maximo lo deja adentro de la
     pantalla incluso en un telefono angosto. */
  right: 0;
  left: auto;
  max-width: calc(100vw - 2rem);
  min-width: 15rem;
  padding: 0.85rem;
  background: var(--fin-fondo-caja);
  border: 1px solid var(--fin-borde);
}

.fin-filtro-campo {
  margin-bottom: 0.75rem;
}

.fin-filtro-campo .form-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.6;
  margin-bottom: 0.2rem;
}

/* ---------- La tabla de movimientos ----------
 *
 * Sin rayado. El de Bootstrap pinta una fila si y una no, y esa alternancia se
 * lee como si las filas claras significaran algo. No significan nada: es
 * decoracion que aparenta ser dato. Una linea fina entre filas separa igual y
 * no promete nada.
 */

.fin-tabla-mov > tbody > tr > td {
  border-bottom: 1px solid var(--fin-borde);
}

.fin-tabla-mov > tbody > tr:hover > td {
  background: var(--fin-fondo-hueco);
}

/* La tabla desplaza DENTRO de su caja y no arrastra la pagina entera. Dos
   razones: con sesenta y nueve filas la pantalla medía dos metros, y sobre todo
   es lo que hace posible el encabezado fijo de abajo. */
.fin-tabla-caja {
  max-height: 65vh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--fin-borde) transparent;
}

.fin-tabla-caja::-webkit-scrollbar {
  width: 0.4rem;
}

.fin-tabla-caja::-webkit-scrollbar-track {
  background: transparent;
}

.fin-tabla-caja::-webkit-scrollbar-thumb {
  background: var(--fin-borde);
  border-radius: 0.2rem;
}

/* Los titulos se quedan arriba al desplazar. Con sesenta y nueve filas, a la
   tercera vuelta de rueda ya no se sabe si la columna de la derecha es el monto
   o la cuenta, y hay que subir hasta arriba para acordarse. */
.fin-tabla-mov thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--fin-fondo-caja);
  border-bottom: 1px solid var(--fin-borde);
}

/* El segundo renglon de una celda: el tipo de cuenta, la nota, el destino de
   un traspaso. Mismo asunto que la linea de arriba, por eso van juntos, pero
   mas apagado para que no compitan. */
.fin-m-sub {
  font-size: 0.8rem;
  opacity: 0.6;
  margin-top: 0.1rem;
}

/* El tipo de movimiento, con el mismo codigo de color que los montos: verde lo
   que entra, rojo lo que sale, gris el traspaso. Un traspaso no es ni bueno ni
   malo, mueve plata de bolsillo: pintarlo de cualquiera de los dos seria
   mentir. El texto dice cual es, el color solo acompana. */
.fin-tipo {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border-radius: 1rem;
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid currentColor;
}

.fin-tipo-ingreso {
  color: var(--fin-verde);
}

.fin-tipo-egreso {
  color: var(--fin-rojo);
}

.fin-tipo-transferencia {
  color: inherit;
  opacity: 0.55;
}

/* Las etiquetas, debajo de la categoria. Son marcas transversales: no cuelgan
   del grupo ni de la categoria, por eso van aparte y no en la misma linea. */
.fin-m-etiquetas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.25rem;
}

.fin-chip {
  /* Una etiqueta partida en dos renglones se lee como dos etiquetas. Si no
     entra, se corta con puntos. */
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 0.05rem 0.45rem;
  border-radius: 1rem;
  background: var(--fin-fondo-hueco);
  border: 1px solid var(--fin-borde);
  font-size: 0.72rem;
  opacity: 0.85;
}

/* Anular en gris, y rojo solo cuando se lo apunta. Es la accion que menos se
   usa de esta pantalla y la unica que no se puede deshacer: que este a mano no
   quiere decir que tenga que gritar en cada fila. */
.fin-accion-fila,
.fin-anular {
  color: inherit;
  opacity: 0.35;
  padding: 0.2rem 0.35rem;
  line-height: 1;
}

/* Editar se ilumina en el color de siempre; anular, en rojo. El color aparece
   recien al apuntarlos: en reposo los dos son del mismo gris para que ninguno
   compita con los datos de la fila. */
.fin-accion-fila:hover,
.fin-accion-fila:focus {
  opacity: 1;
  color: var(--fin-azul);
}

.fin-anular:hover,
.fin-anular:focus {
  opacity: 1;
  color: var(--fin-rojo);
}

.fin-accion-fila i,
.fin-anular i {
  font-size: 1.05rem;
}

/* ---------- Movimientos en pantalla angosta ----------
 *
 * Seis columnas en 375px solo se leen deslizando de costado, y nadie desliza.
 * Abajo de 48rem cada fila deja de ser fila y pasa a ser una ficha:
 *
 *     Jardin de Asia                  -Bs 480,00
 *     Cena del cumple
 *     [Egreso]  13/09 · Tarjeta Visa tarjeta
 *     Alimentacion > cena  [cumple de mi hermana]          [x]
 *
 * Se arma con grid y areas nombradas, no con flex y "order". Con flex el orden
 * se respeta pero los anchos no, y las celdas terminaban cayendo donde querian.
 * Las areas dicen exactamente donde va cada cosa.
 */

@media (max-width: 48rem) {
  .fin-tabla-mov thead {
    display: none;
  }

  .fin-tabla-mov,
  .fin-tabla-mov tbody {
    display: block;
    width: auto;
  }

  .fin-tabla-mov tr {
    display: grid;
    grid-template-columns: auto auto 1fr auto;
    grid-template-areas:
      'detalle detalle detalle monto'
      'tipo    fecha   cuenta  cuenta'
      'clas    clas    clas    accion';
    align-items: baseline;
    column-gap: 0.45rem;
    row-gap: 0.3rem;
    padding: 0.85rem 0.9rem;
    border-bottom: 1px solid var(--fin-borde);
  }

  /* El fondo de celda tiene que irse: Bootstrap lo pinta celda por celda y con
     las celdas en bloque quedaban manchas grises sueltas detras de cada dato. */
  .fin-tabla-mov > tbody > tr > td {
    display: block;
    padding: 0;
    border: 0;
    background: none;
    min-width: 0;
  }

  .fin-tabla-mov > tbody > tr:hover > td {
    background: none;
  }

  .fin-m-detalle {
    grid-area: detalle;
    font-weight: 600;
  }

  .fin-m-monto {
    grid-area: monto;
  }

  .fin-m-tipo {
    grid-area: tipo;
  }

  .fin-m-fecha {
    grid-area: fecha;
  }

  .fin-m-cuenta {
    grid-area: cuenta;
  }

  .fin-m-categoria {
    grid-area: clas;
  }

  .fin-m-accion {
    grid-area: accion;
    text-align: right;
  }

  .fin-m-fecha,
  .fin-m-cuenta,
  .fin-m-categoria {
    font-size: 0.82rem;
    opacity: 0.75;
  }

  /* En la ficha el segundo renglon de una celda va en linea con el primero.
     Van los DOS a inline: poner solo el segundo no alcanza, porque el primero
     sigue siendo bloque y se queda con el renglon entero. */
  .fin-m-cuenta > div,
  .fin-m-categoria > div {
    display: inline;
  }

  /* Los dos renglones pasan a estar en linea, asi que necesitan separacion:
     sin esto quedaba "cenaAlimentacion" pegado, como una sola palabra. */
  .fin-m-cuenta .fin-m-sub,
  .fin-m-categoria .fin-m-sub {
    margin-left: 0.35rem;
  }

  /* Las etiquetas si vuelven a ser bloque: son chips y en linea se mezclarian
     con el nombre de la categoria. */
  .fin-m-etiquetas {
    display: inline-flex;
    margin-top: 0;
    margin-left: 0.4rem;
    vertical-align: middle;
  }

  /* El punto separador se dibuja en CSS y no se escribe en el dato: asi no
     aparece colgando cuando una celda viene vacia. */
  .fin-m-cuenta:not(:empty)::before {
    content: '·';
    margin-right: 0.45rem;
    opacity: 0.5;
  }

  .fin-tabla-mov .fin-detalle-partidas td {
    grid-area: auto / 1 / auto / -1;
  }

  .fin-tabla-mov .fin-mov-vacio {
    grid-area: auto / 1 / auto / -1;
    text-align: center;
  }

  /* La caja deja de tener techo: en el telefono la pagina ya desplaza y dos
     areas de desplazamiento anidadas se pelean con el dedo. */
  .fin-tabla-caja {
    max-height: none;
    overflow-y: visible;
  }
}

/* ---------- Pantallas angostas (celular, ~375-400px) ----------
   Las tablas anchas se deslizan de costado adentro de su propia caja: la
   pagina en si nunca se desliza para el costado. */

.table-responsive {
  overflow-x: auto;
}

@media (max-width: 34rem) {
  .fin-tarjetas {
    grid-template-columns: 1fr;
  }

  .fin-cifra {
    font-size: 1.4rem;
  }

  /* En 375px el aire entre partes se achica: con 2.75rem de separacion la
     tercera se cae sola de renglon y queda una huerfana abajo. */
  .fin-hero-partes {
    gap: 0.75rem 1.5rem;
  }

  .fin-hero-moneda {
    padding: 1.1rem 1.15rem;
  }

  /* Cada parte de una division se apila: en 375px cuatro columnas no entran
     sin achicar la letra hasta que deja de leerse. La ubicacion va explicita
     porque el orden del DOM (categoria, monto, nota, quitar) no es el orden en
     que conviene verlas apiladas. */
  .fin-partida-fila {
    grid-template-columns: 1fr auto;
    padding-bottom: 0.5rem;
    border-bottom: 1px dashed var(--fin-borde);
  }

  .fin-partida-fila .fin-partida-categoria {
    grid-column: 1 / -1;
    grid-row: 1;
  }

  .fin-partida-fila .fin-partida-monto {
    grid-column: 1;
    grid-row: 2;
  }

  .fin-partida-fila .fin-partida-quitar {
    grid-column: 2;
    grid-row: 2;
  }

  .fin-partida-fila .fin-partida-nota {
    grid-column: 1 / -1;
    grid-row: 3;
  }

  .card-header.d-flex {
    flex-direction: column;
    align-items: stretch !important;
  }

  .fin-categorias {
    grid-template-columns: 1fr;
  }
}

/* =====================================================================
   Modelo contable: lo propio de este proyecto
   ===================================================================== */

/* El boton de anotar. Vive flotando abajo a la derecha y NO se mueve nunca:
   es el unico boton que se toca todos los dias, y uno que cambia de lugar
   segun la pantalla obliga a buscarlo cada vez. Sobre la barra de abajo en
   telefono, pegado al borde en escritorio. */
.fin-boton-flotante {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 1030;
  width: 3.5rem;
  height: 3.5rem;
  border: 0;
  border-radius: 50%;
  background: var(--bs-primary);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  box-shadow: 0 0.4rem 1rem rgba(0, 0, 0, 0.35);
  cursor: pointer;
}

.fin-boton-flotante:active {
  transform: scale(0.94);
}

@media (max-width: 991.98px) {
  /* Arriba de la barra de abajo, no debajo: si se superponen, el boton queda
     tapado justo en el telefono, que es donde mas se usa. */
  .fin-boton-flotante {
    bottom: 5rem;
  }
}

/* Scroll interno y TODAS las filas. PLAN.md seccion 9: cortar las listas en
   las primeras cinco esconde justo el mes que se quiere revisar. */
.fin-scroll-lista {
  max-height: calc(100vh - 16rem);
  overflow-y: auto;
}

.fin-mov-fila {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--fin-borde, rgba(128, 128, 128, 0.25));
}

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

.fin-mov-cab {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
}

.fin-mov-fecha {
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
  white-space: nowrap;
}

.fin-mov-desc {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}

.fin-mov-total {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Las lineas del movimiento: de donde salio y a que se fue. Van en chico y
   corridas, porque el dato que se busca al repasar es la descripcion y el
   total; el detalle esta para confirmar, no para leer de corrido. */
.fin-mov-lineas {
  list-style: none;
  margin: 0.35rem 0 0;
  padding: 0 0 0 0.75rem;
}

.fin-mov-lineas li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
  padding: 0.1rem 0;
}

.fin-mov-cuenta {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fin-mov-monto {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.fin-mov-motivo {
  font-size: 0.8rem;
  margin-top: 0.35rem;
  color: var(--bs-danger-text-emphasis, var(--bs-danger));
}

.fin-mov-acciones {
  margin-top: 0.5rem;
}

/* El tachado de .fin-anulado se hereda a los hijos y vuelve ilegible el
   motivo, que es justamente lo que hay que poder leer. */
.fin-anulado .fin-mov-motivo {
  text-decoration: none;
}

.fin-cuentas-tabla {
  padding: 0.5rem 1rem;
}

.fin-cuenta-grupo {
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
  min-width: 7rem;
  white-space: nowrap;
}

/* Los avisos van arriba y por encima del modal: un error que aparece detras
   del formulario que lo produjo no lo ve nadie. */
#fin-avisos {
  position: fixed;
  top: 1rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2000;
  width: min(92vw, 30rem);
  pointer-events: none;
}

#fin-avisos .alert {
  margin-bottom: 0.5rem;
}

/* El reparto entre varias categorias: el monto no se achica aunque el nombre
   de la cuenta sea largo. */
.fin-destino .fin-destino-monto {
  max-width: 8rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Las pestanas de los modales de registro: que se estas anotando.
   Separadas del formulario por una linea, porque son de otro nivel: eligen
   QUE formulario estas viendo, no completan uno. */
.fin-tipos {
  margin-bottom: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--fin-borde, rgba(128, 128, 128, 0.25));
}

/* La activa va deshabilitada porque tocarla no hace nada: ya estas ahi.
   Pero deshabilitado en Bootstrap significa tambien atenuado, y eso la haria
   ver como la MENOS disponible justo siendo la actual. */
.fin-tipos .btn-primary:disabled {
  opacity: 1;
}

/* En telefono, cuatro botones en fila dejan cada uno de dos centimetros y los
   nombres se cortan. Dos y dos entran enteros. */
@media (max-width: 420px) {
  .fin-tipos {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.25rem;
  }

  .fin-tipos .btn {
    border-radius: 0.375rem !important;
  }
}

/* El modal de anotar aparece de golpe, sin la animacion de 0,3s que Bootstrap
   le pone por defecto (desliza desde arriba y funde el fondo).
   Es el boton que se toca cien veces por mes: media animacion por apertura son
   treinta segundos al ano mirando una ventana bajar. Y peor que el tiempo es
   la sensacion: con la animacion se siente lento aunque los datos ya esten en
   memoria y no haya nada que esperar.
   Sacar la clase `fade` del modal apaga la del dialogo; el fondo tiene la suya
   propia y se apaga aca. */
#fin-modal-anotar ~ .modal-backdrop,
.modal-backdrop.fade {
  transition: none;
}

/* El foco se dibuja igual, que es lo que avisa donde esta parado el teclado. */
#fin-modal-anotar .modal-dialog {
  transition: none;
}

/* Con cuanto arranco: el nombre de la cuenta a ancho fijo para que todos los
   campos de monto queden alineados en la misma columna. Sin esto cada fila
   arranca donde termina su nombre y la lista se lee en zigzag. */
.fin-ap-nombre {
  min-width: 14rem;
  justify-content: flex-start;
}

@media (max-width: 575.98px) {
  .fin-ap-nombre {
    min-width: 8rem;
  }
}

.fin-ap-monto {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* El total se despega de la lista: es la consecuencia de todo lo de arriba, no
   una fila mas. */
.fin-ap-total {
  padding-top: 1rem;
  border-top: 1px solid var(--fin-borde, rgba(128, 128, 128, 0.25));
}

/* Los tres cuerpos del modal, apilados en la MISMA celda de una grilla.
   Asi la celda mide lo que mide el mas largo y el modal nunca cambia de alto,
   sin que nadie tenga que inventar un numero: el dia que se agregue un campo,
   el alto se acomoda solo.
   Antes estaba con un height fijo de 32rem y el cuerpo mas largo quedaba con
   barra de scroll adentro. */
.fin-cuerpos {
  display: grid;
  /* min-height 0 deja que el hijo se achique cuando no entra; sin esto una
     grilla nunca encoge por debajo de su contenido y el scroll de adentro no
     llega a activarse. */
  min-height: 0;
}

.fin-cuerpos > form {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* Scroll SOLO cuando hace falta. Con pocas lineas el cuerpo mide lo que mide y
   no aparece ninguna barra; al repartir en muchas categorias crece, choca
   contra el alto de la pantalla y ahi si se desliza, dejando el boton de
   guardar siempre a la vista. Antes crecia sin limite y Guardar quedaba abajo
   de la pantalla, sin forma de llegar. */
#fin-modal-anotar .modal-content {
  max-height: calc(100vh - 3.5rem);
}

#fin-modal-anotar .modal-body {
  overflow-y: auto;
  min-height: 0;
}

/* El pie no se desliza con el cuerpo: es el que tiene Guardar. */
#fin-modal-anotar .modal-footer {
  flex-shrink: 0;
}

/* Oculto pero ocupando su lugar: eso es lo que sostiene la altura. `hidden` lo
   sacaria del layout y la celda volveria a encogerse. visibility ademas lo saca
   del recorrido del tabulador. */
.fin-cuerpo-oculto {
  visibility: hidden;
}

/* El ancho tambien fijo: estar centrado hacia que el dialogo se reacomodara
   cada vez que el contenido cambiaba. */
#fin-modal-anotar .modal-dialog {
  max-width: 34rem;
}

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

.fin-mov-cab {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
}

.fin-mov-fecha {
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
  white-space: nowrap;
}

.fin-mov-desc {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}

.fin-mov-total {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Las lineas del movimiento: de donde salio y a que se fue. Van en chico y
   corridas, porque el dato que se busca al repasar es la descripcion y el
   total; el detalle esta para confirmar, no para leer de corrido. */
.fin-mov-lineas {
  list-style: none;
  margin: 0.35rem 0 0;
  padding: 0 0 0 0.75rem;
}

.fin-mov-lineas li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
  padding: 0.1rem 0;
}

.fin-mov-cuenta {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fin-mov-monto {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.fin-mov-motivo {
  font-size: 0.8rem;
  margin-top: 0.35rem;
  color: var(--bs-danger-text-emphasis, var(--bs-danger));
}

.fin-mov-acciones {
  margin-top: 0.5rem;
}

/* El tachado de .fin-anulado se hereda a los hijos y vuelve ilegible el
   motivo, que es justamente lo que hay que poder leer. */
.fin-anulado .fin-mov-motivo {
  text-decoration: none;
}

.fin-cuentas-tabla {
  padding: 0.5rem 1rem;
}

.fin-cuenta-grupo {
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
  min-width: 7rem;
  white-space: nowrap;
}

/* Los avisos van arriba y por encima del modal: un error que aparece detras
   del formulario que lo produjo no lo ve nadie. */
#fin-avisos {
  position: fixed;
  top: 1rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2000;
  width: min(92vw, 30rem);
  pointer-events: none;
}

#fin-avisos .alert {
  margin-bottom: 0.5rem;
}

/* El reparto entre varias categorias: el monto no se achica aunque el nombre
   de la cuenta sea largo. */
.fin-destino .fin-destino-monto {
  max-width: 8rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Las pestanas de los modales de registro: que se estas anotando.
   Separadas del formulario por una linea, porque son de otro nivel: eligen
   QUE formulario estas viendo, no completan uno. */
.fin-tipos {
  margin-bottom: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--fin-borde, rgba(128, 128, 128, 0.25));
}

/* La activa va deshabilitada porque tocarla no hace nada: ya estas ahi.
   Pero deshabilitado en Bootstrap significa tambien atenuado, y eso la haria
   ver como la MENOS disponible justo siendo la actual. */
.fin-tipos .btn-primary:disabled {
  opacity: 1;
}

/* En telefono, cuatro botones en fila dejan cada uno de dos centimetros y los
   nombres se cortan. Dos y dos entran enteros. */
@media (max-width: 420px) {
  .fin-tipos {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.25rem;
  }

  .fin-tipos .btn {
    border-radius: 0.375rem !important;
  }
}

/* El editor de lineas tiene cuatro campos por fila y en pantallas angostas
   quedan de un centimetro cada uno. Abajo de 768px se apilan en dos filas de
   dos, que es lo minimo para que se puedan tocar. */
@media (max-width: 767.98px) {
  .fin-e-fila {
    flex-wrap: wrap;
  }

  .fin-e-fila > select:first-child {
    flex: 1 1 100%;
    border-radius: 0.375rem !important;
    margin-bottom: 0.25rem;
  }
}
