:root {
  --bg: #12141a;
  --surface: #1b1f27;
  --surface-2: #22262f;
  --border: #2b303b;
  --ink: #e9e7e0;
  --ink-dim: #9aa0ac;
  --paper: #f3f0e6;
  --paper-ink: #23241f;
  --paper-ink-dim: #6b6a5f;
  --green: #33a374;
  --red: #e2574c;
  --blue: #5b82f0;
  --amber: #d9a441;

  --sidebar-w: 230px;
  --sidebar-peek: 8px;

  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

* { box-sizing: border-box; }

/* el motor WebKit que trae JavaFX WebView (la app de escritorio, ver
   DesktopApp.java) es mas viejo que Chrome/Safari actuales y no siempre
   infiere "appearance: none" solo porque un <button> ya trae su propio
   background/border — sin este reset, botones como .info-tip (que no
   tienen relleno propio) se ven con el marco nativo del SO por detras del
   icono en vez de solo el icono. En Chrome esto no cambia nada porque ya
   se comportaba asi. */
button {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

/* scrollbar delgada y semitransparente en vez de la barra ancha de
   scrollbar gris por defecto — sobre todo por el WebView de la app de
   escritorio (JavaFX/WebKit), que no tiene forma de pedirle al SO una
   barra mas discreta salvo por CSS. Un navegador de verdad que ya trae
   la suya propia mas moderna simplemente ignora estas reglas. */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background-color: rgba(154, 160, 172, 0.35);
  background-clip: padding-box;
  border: 2px solid transparent;
  border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover {
  background-color: rgba(154, 160, 172, 0.55);
}
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(154, 160, 172, 0.35) transparent;
}

.hidden { display: none !important; }

/* ---------- pantallas de autenticacion ---------- */

.auth-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E") repeat,
    radial-gradient(520px 360px at 50% 22%, rgba(255, 255, 255, 0.10), transparent 68%),
    radial-gradient(circle at 50% 40%, var(--surface) 0%, var(--bg) 70%);
}

.auth-wrap {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
  animation: auth-in 0.55s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes auth-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .auth-wrap { animation: none; }
}

.auth-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.auth-logo {
  width: 88px;
  height: 88px;
  border-radius: 19px;
  box-shadow:
    0 22px 44px -18px rgba(0, 0, 0, 0.6),
    0 0 0 1px rgba(255, 255, 255, 0.05) inset,
    0 0 64px -10px rgba(255, 255, 255, 0.35);
}

.auth-wordmark {
  margin: 0;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 21px;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* "regla de bitacora": tres trazos claros que replican en miniatura
   las lineas del logo (ver scripts/icon.svg) — refuerza la identidad
   de marca fuera del icono en vez de dejar el logo aislado. */
.auth-rule {
  display: flex;
  align-items: center;
  gap: 5px;
}
.auth-rule span {
  display: block;
  height: 3px;
  border-radius: 2px;
  background: var(--paper);
}
.auth-rule span:nth-child(1) { width: 38px; }
.auth-rule span:nth-child(2) { width: 26px; opacity: 0.8; }
.auth-rule span:nth-child(3) { width: 16px; opacity: 0.6; }

.auth-card {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 34px 30px 30px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: relative;
  box-shadow:
    0 30px 70px -24px rgba(0, 0, 0, 0.55),
    0 2px 8px -4px rgba(0, 0, 0, 0.4);
}

/* filo superior tipo "vidrio": una linea de 1px que separa la tarjeta
   del fondo sin depender de mas contraste de borde. */
.auth-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 18px;
  right: 18px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.16), transparent);
}

.auth-card .field input {
  background: var(--bg);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.auth-card .field input:focus {
  border-color: var(--blue);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 0 3px rgba(91, 130, 240, 0.18);
}

.auth-card .btn-primary {
  background: linear-gradient(135deg, #ffffff, #d7d3c6);
  color: #23241f;
  font-weight: 700;
  box-shadow: 0 12px 26px -14px rgba(0, 0, 0, 0.5);
}
.auth-card .btn-primary:hover { filter: brightness(0.97); }

/* .field trae "flex: 1 1 120px" pensado para filas horizontales que se
   envuelven (ver mas abajo) — dentro de .auth-card, que es una columna,
   ese flex-basis de 120px infla cada campo a esa altura aunque el
   contenido mida la mitad. Se anula solo aqui. */
.auth-card .field {
  flex: 0 1 auto;
}

.auth-card h1 {
  margin: 0 0 2px;
  font-family: var(--font-mono);
  font-size: 24px;
}

.auth-sub {
  margin: -8px 0 4px;
  font-size: 13px;
  color: var(--ink-dim);
}

.auth-error {
  margin: 0;
  font-size: 13px;
  color: var(--red);
}

/* ---------- botones ---------- */

.btn {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  border-radius: 8px;
  padding: 10px 16px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.08s ease, background 0.15s ease, border-color 0.15s ease;
}
.btn:active { transform: scale(0.97); }

.btn-block { width: 100%; }

.btn-ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--ink);
}
.btn-ghost:hover { border-color: var(--ink-dim); }

/* accion destructiva de verdad (borrar toda la base de datos, etc.) —
   se ve como .btn-ghost pero en rojo, para que no se confunda con un
   boton "ghost" cualquiera. */
.btn-peligro {
  background: transparent;
  border-color: var(--red);
  color: var(--red);
}
.btn-peligro:hover { background: rgba(226, 87, 76, 0.12); }
.btn-peligro:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.btn-peligro:disabled:hover { background: transparent; }

.btn-primary {
  background: var(--blue);
  color: #f5f7ff;
}
.btn-primary:hover { filter: brightness(1.08); }

.btn-link {
  background: none;
  border: none;
  color: var(--ink-dim);
  text-decoration: underline;
  padding: 6px 4px;
  cursor: pointer;
  font-size: 13px;
}

/* iconos svg (ver public/js/icons.js): heredan color via currentColor, asi
   que las clases .pos/.neg/.neu/etc que antes pintaban el glifo unicode
   siguen funcionando igual sobre el <svg>. */
.icon {
  display: inline-block;
  vertical-align: -3px;
  flex-shrink: 0;
}
.icon-inline {
  vertical-align: -2.5px;
  margin-right: 1px;
}

.btn-icon {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--ink-dim);
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
}
.btn-icon:hover { background: var(--surface-2); color: var(--ink); }
.btn-icon.danger:hover { color: var(--red); }

/* ---------- layout: app con sidebar ---------- */

.app-shell {
  display: flex;
  min-height: 100vh;
}

/* sidebar "peek": colapsada solo se asoma una tira de --sidebar-peek en el
   borde izquierdo (fondo + su propio borde derecho) y se despliega entera
   al pasar el cursor (o al enfocar algo adentro con teclado), flotando
   sobre el contenido en vez de empujarlo — asi se siente integrada sin
   ocupar espacio permanente. En telefono (ver @media abajo) vuelve a su
   comportamiento normal de barra fija arriba. */
.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 22px 16px;
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  overflow-y: auto;
  z-index: 40;
  transform: translateX(calc(-1 * var(--sidebar-w) + var(--sidebar-peek)));
  transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.22s ease;
}

.sidebar:hover,
.sidebar:focus-within {
  transform: translateX(0);
  box-shadow: 20px 0 44px -20px rgba(0, 0, 0, 0.55);
}

@media (prefers-reduced-motion: reduce) {
  .sidebar { transition: none; }
}

/* "fijar sidebar" (Configuración → Apariencia): el usuario prefiere que
   se quede siempre desplegada en vez de solo asomar y expandirse al
   pasar el cursor. #vista-app trae la clase .sidebar-fijada cuando ese
   ajuste esta prendido (ver app.js) — el contenido se corre para dejarle
   su espacio de forma permanente, en vez de que la sidebar flote encima.
   Solo aplica en el mismo ancho donde existe el modo "peek" — en
   telefono la sidebar ya vuelve a su barra fija arriba (ver @media mas
   abajo), sin relacion con este ajuste. */
@media (min-width: 721px) {
  .sidebar-fijada .sidebar {
    transform: translateX(0);
    box-shadow: none;
  }
  .sidebar-fijada .main {
    margin-left: var(--sidebar-w);
  }
}

/* "mostrar marca en el sidebar" (Configuración → Apariencia): oculta solo
   el logo + "Bitácora" (.brand-mark), nunca todo .sidebar-brand — ese
   contenedor tambien aloja #btnMenu, el boton de hamburguesa que en
   telefono debe seguir visible aunque la marca este apagada. */
.marca-oculta .brand-mark {
  display: none;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 26px;
  padding: 0 6px;
}

.brand-mark {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.brand-logo {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  flex-shrink: 0;
  box-shadow: 0 4px 10px -4px rgba(0, 0, 0, 0.5);
}

/* boton "hamburguesa": solo existe para telefono (ver @media abajo) —
   en escritorio/tablet el menu completo ya esta siempre visible en el
   sidebar, no hace falta desplegar nada. */
.btn-menu {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--ink);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin-bottom: 2px;
}

.sidebar-brand h1 {
  margin: 0;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.01em;
}

/* envuelve nav + utilidades + ajustes + footer. En escritorio es un
   div "invisible" mas (flex:1 en columna, igual que antes de existir
   este wrapper); en telefono se convierte en el panel desplegable —
   ver @media abajo. */
.sidebar-panel {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* fondo oscurecido detras del panel movil, para cerrar tocando afuera.
   sin efecto en escritorio (ver @media abajo). */
.sidebar-backdrop { display: none; }

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: 1px solid transparent;
  color: var(--ink-dim);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 14px;
  padding: 10px 12px;
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
}
.nav-item:hover { background: var(--surface-2); }
.nav-item.active {
  background: var(--surface-2);
  color: var(--ink);
  border-color: var(--border);
}

.nav-icon {
  font-family: var(--font-mono);
  font-weight: 700;
  width: 18px;
  text-align: center;
}
.nav-item.active .nav-icon.pos { color: var(--green); }
.nav-item.active .nav-icon.neg { color: var(--red); }
.nav-item.active .nav-icon.neu { color: var(--blue); }

.sidebar-footer {
  border-top: 1px solid var(--border);
  padding-top: 14px;
  margin-top: 14px;
}

/* todos los modulos del sidebar (los sueltos y los de adentro del
   acordeon de Movimientos) se ven exactamente igual — el tamaño "grande"
   que antes solo tenian Dashboard/Resumen general — para que activar,
   desactivar o reordenar cualquiera desde Configuración → Módulos no
   tambien le cambie el aspecto. */
.sidebar-nav-ajustes {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 12px;
  margin-top: 8px;
  border-top: 1px solid var(--border);
}

/* acordeon "Movimientos" (Ingresos/Gastos/Traspaso, o el subconjunto que
   este activo): el boton se ve como cualquier nav-item, solo le
   agregamos la flechita empujada al extremo derecho; el contenido se
   oculta por default y solo se muestra con la clase .expandido (ver
   nav.js). */
.sidebar-acordeon-boton { width: 100%; justify-content: space-between; }
.sidebar-acordeon-flecha {
  display: inline-flex;
  color: var(--ink-dim);
  transition: transform 0.15s ease;
}
.sidebar-acordeon.expandido .sidebar-acordeon-flecha { transform: rotate(90deg); }
.sidebar-acordeon-contenido {
  display: none;
  flex-direction: column;
  gap: 4px;
  margin: 4px 0 4px 12px;
}
.sidebar-acordeon.expandido .sidebar-acordeon-contenido { display: flex; }

.usuario-actual {
  font-size: 13px;
  font-weight: 600;
  padding: 0 4px 4px;
}

.sidebar-footer .btn-link { padding-left: 4px; }

.selector-tema {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 4px 10px;
  font-size: 12px;
  color: var(--ink-dim);
}
.selector-tema select {
  font-family: var(--font-sans);
  font-size: 12px;
  background: var(--surface-2);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 6px;
}

/* mismo selector de Tema, pero para la tarjeta de Configuración → Apariencia
   (usa el tamaño de fuente normal en vez del compacto del pie del sidebar). */
.selector-tema-select {
  flex-shrink: 0;
  font-family: var(--font-sans);
  font-size: 13px;
  background: var(--surface-2);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 8px;
}

/* ---------- main / contenido ---------- */

.main {
  flex: 1;
  min-width: 0;
  padding: 24px 28px 50px;
}

.main-header {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 30px;
  flex-wrap: wrap;
}

.main-header .ticket { flex: 1 1 320px; margin-bottom: 0; }

/* ---------- ticket resumen (elemento distintivo) ---------- */

.ticket {
  position: relative;
  background: var(--paper);
  color: var(--paper-ink);
  border-radius: 10px 10px 0 0;
  padding: 16px 20px 20px;
  box-shadow: 0 12px 24px -18px rgba(0, 0, 0, 0.6);
}

.ticket::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -11px;
  height: 11px;
  background:
    linear-gradient(135deg, transparent 50%, var(--bg) 50%) 0 0,
    linear-gradient(-135deg, transparent 50%, var(--bg) 50%) 0 0;
  background-size: 16px 16px;
  background-repeat: repeat-x;
}

.ticket-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 4px 0;
}

.ticket-title {
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--paper-ink-dim);
  border-bottom: 1px dashed #c9c4b0;
  padding-bottom: 8px;
  margin-bottom: 4px;
}

.leader { color: var(--paper-ink-dim); }

.amount { font-weight: 600; }
.amount.pos { color: #1f7a54; }
.amount.neg { color: #b8392f; }

.ticket-subdivisor {
  border-top: 1px dashed #c9c4b0;
  margin-top: 4px;
  padding-top: 8px;
}

.ticket-total {
  border-top: 1px dashed #c9c4b0;
  margin-top: 4px;
  padding-top: 8px;
  font-size: 15px;
}
.ticket-total .amount { font-weight: 700; }

/* chip de color propio de cada caja en el ticket — el color viene del
   inline style de resumen.js (colorTexto/colorFondo de esa caja
   especifica), esta clase solo da la forma de pastilla. */
.amount.caja-chip {
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 13px;
}

/* ---------- secciones (ventas / gastos) ---------- */

.seccion-titulo {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin: 0 0 14px;
}

.seccion-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.seccion-header .seccion-titulo { margin: 0; }

/* agrupa el filtro de caja y el botón de imprimir a la derecha del
   seccion-header (ver Gastos/Ingresos), para que justify-content:
   space-between siga dejando el resumen del mes a la izquierda y este
   grupo pegado a la derecha, en vez de repartir 3 items sueltos. */
.seccion-header-acciones {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.filtro-caja {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--ink);
  border-radius: 6px;
  padding: 7px 8px;
  font-family: var(--font-sans);
  font-size: 13px;
}
.filtro-caja:focus { outline: none; border-color: var(--blue); }

/* boton "i" junto a un titulo, con el globo de texto que aparece al
   hover/foco — reemplaza los parrafos largos que explicaban de que
   trataba toda una seccion (ver icons.js, infoTip()). */
.info-tip {
  position: relative;
  display: inline-flex;
  align-items: center;
  vertical-align: -3px;
  margin-left: 6px;
  padding: 0;
  background: none;
  border: none;
  color: var(--ink-dim);
  cursor: help;
}
.info-tip:hover,
.info-tip:focus-visible { color: var(--ink); }
.info-tip:focus { outline: none; }

/* width/height en 0 + overflow:hidden mientras esta oculto: "visibility:
   hidden" NO saca al globo del flujo (ver el comentario de la misma
   frase en el media print, mas abajo) — sin este recorte, el globo
   entero (hasta 260px de ancho) segue ocupando espacio de layout aunque
   sea invisible, y en los "i" cercanos al borde derecho o inferior de
   la ventana eso alcanzaba a empujar el scroll del documento entero,
   apareciendo una barra de scroll fantasma. Al mostrarse (hover/foco)
   recupera su tamano real. */
.info-tip-globo {
  position: absolute;
  left: 0;
  top: calc(100% + 8px);
  z-index: 20;
  width: 0;
  height: 0;
  overflow: hidden;
  max-width: 260px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.45;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink);
  box-shadow: 0 12px 24px -12px rgba(0, 0, 0, 0.5);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.12s ease, transform 0.12s ease;
  pointer-events: none;
}
.info-tip:hover .info-tip-globo,
.info-tip:focus .info-tip-globo,
.info-tip:focus-within .info-tip-globo {
  width: max-content;
  height: auto;
  overflow: visible;
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* Antes era "display:flex; flex-wrap:wrap" — un vestigio de una version
   mas simple pensada para un formulario de una sola fila de campos. Las
   4 formas que usan esta clase (Caja, Usuario, Articulo, Ajuste manual
   de Inventario) ya envuelven sus campos en .form-secciones/
   .form-seccion-campos, que traen su propio wrap — con .form TAMBIEN en
   flex-row, .form-secciones y .form-acciones quedaban como dos items de
   esa fila en vez de apilarse, y el boton terminaba flotando a la
   derecha de las tarjetas en vez de abajo. Como bloque normal, todo se
   apila de arriba a abajo como cualquier form comun. */
.form {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  margin-bottom: 22px;
}

/* ---------- layout dividido: tabla (izquierda) + constructor (derecha) ---------- */
/* usado en paginas con una tabla de movimientos y un formulario para
   agregar/editar (Ingresos, Gastos, Inventario) — grid-template-areas deja
   poner .panel-tabla primero en el HTML (orden de lectura natural) pero
   pintarlo a la izquierda, sin importar el ancho de cada columna. En
   pantallas angostas colapsa a una sola columna, con el constructor
   arriba (como era el orden original antes de dividir en dos paneles). */
.contenido-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
  grid-template-areas: "tabla constructor";
  align-items: start;
  gap: 24px;
}
.panel-tabla { grid-area: tabla; min-width: 0; }
.panel-constructor { grid-area: constructor; min-width: 0; }

/* posicion del constructor (Configuración → Apariencia): invierte cual
   columna queda a la izquierda. Va detras de un min-width a proposito —
   asi nunca compite en especificidad con el colapso a una sola columna
   de abajo, que debe ganar siempre sin importar esta preferencia. */
@media (min-width: 981px) {
  .contenido-split.constructor-izquierda {
    grid-template-columns: minmax(320px, 420px) minmax(0, 1fr);
    grid-template-areas: "constructor tabla";
  }
}

@media (max-width: 980px) {
  .contenido-split {
    grid-template-columns: 1fr;
    grid-template-areas:
      "constructor"
      "tabla";
  }
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 120px;
  /* sin esto, un <select> con una opcion larga (p. ej. el alias de una
     caja) no se encoge por debajo de su contenido dentro de la fila con
     flex-wrap — el min-width por default de un flex item es "auto", no
     0, asi que en motores mas estrictos que Chrome (como el WebView de
     la app de escritorio) el campo se sale del formulario en vez de
     achicarse o pasar a la siguiente linea. */
  min-width: 0;
}
.field.small { flex: 0 1 100px; }
.field.grow { flex: 2 1 200px; }
.field.full { flex: 1 1 100%; }

.field label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
}

/* label de un campo opcional (p. ej. "Hora") con su propio checkbox de
   activar/desactivar — sin este flex, el checkbox nativo (mucho mas alto
   que el texto de 11px) se desalinea del texto usando solo vertical-align. */
.field-label-check {
  display: flex;
  align-items: center;
  gap: 5px;
}
.field-label-check input[type='checkbox'] {
  width: 13px;
  height: 13px;
  margin: 0;
  flex-shrink: 0;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--ink);
  border-radius: 6px;
  padding: 9px 10px;
  font-family: var(--font-sans);
  font-size: 14px;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--blue);
}
.field textarea { resize: vertical; min-height: 40px; }
.field input[type="color"] { padding: 3px 4px; height: 38px; cursor: pointer; }

.field-actions {
  flex: 1 1 100%;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  margin-top: 4px;
}

.list { display: flex; flex-direction: column; gap: 2px; }

/* ---------- formulario dividido en secciones (ventas) ---------- */

.form-secciones {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 16px;
}

.form-seccion {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px 16px;
}

.form-seccion-titulo {
  margin: 0 0 12px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.form-seccion-campos {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* antes era una fila suelta directo sobre el fondo de la pagina, sin
   caja ni borde — quedaba flotando entre/despues de las tarjetas
   .form-seccion en vez de leerse como parte intencional del formulario.
   Con el mismo tratamiento de tarjeta que .form-seccion, se ve como una
   barra de accion a proposito. */
.form-acciones {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  margin-bottom: 22px;
}

.badge-tarjeta {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
  margin-left: 6px;
  margin-right: 6px;
  vertical-align: middle;
}

.badge-admin {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--green);
  background: rgba(51, 163, 116, 0.15);
  border-radius: 4px;
  padding: 1px 6px;
  margin-right: 6px;
  vertical-align: middle;
}

.empty {
  color: var(--ink-dim);
  font-size: 13px;
  padding: 12px 4px;
}

.row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--border);
}

.row-main { flex: 1; min-width: 0; }

.row-title {
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.row-sub {
  font-size: 12px;
  color: var(--ink-dim);
  margin-top: 2px;
}

.row-amount {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
}
.row-amount.pos { color: var(--green); }
.row-amount.neg { color: var(--red); }

/* el chip de caja junto a las etiquetas INGRESO/GASTO/Traspaso en cada
   renglon (Ingresos, Gastos, Resumen general, Traspasos): sin esto
   heredaba el tamaño de .amount.caja-chip (13px, pensado para cuando el
   chip va solo, como en el ticket del header) — se veia mas grande que
   esas etiquetas de 10px, y como .row-title recorta con
   overflow:hidden, sin alinearlo al centro el chip mas alto quedaba con
   el borde inferior redondeado cortado. */
.row-title .caja-chip {
  font-size: 10px;
  padding: 1px 8px;
  vertical-align: middle;
}

.row-actions { display: flex; gap: 2px; }

/* ---------- gastos: resumen y navegacion por mes ---------- */

.mes-resumen {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink-dim);
  margin: 0 0 10px;
  padding: 0 4px;
}
.mes-resumen strong { color: var(--ink); font-weight: 600; }

/* siempre el segundo renglon de #filtroPeriodo (Día/Semana/Mes), justo
   debajo de esos tabs — el margen/aire de arriba se recorto (antes
   pensado para separarse de una lista larga cuando este nav vivia solo
   al final de la pagina) para que las dos filas se vean como un mismo
   control, no como dos widgets distintos. */
.mes-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}

.mes-nav-actual {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  min-width: 140px;
  text-align: center;
}

#mesSiguiente:disabled { cursor: default; }

/* ---------- dashboard: kpis ---------- */

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin-bottom: 24px;
}

.kpi-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.kpi-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
}

.kpi-valor {
  font-family: var(--font-mono);
  font-size: 22px;
  font-weight: 700;
}
.kpi-valor.pos { color: var(--green); }
.kpi-valor.neg { color: var(--red); }

.kpi-desglose {
  font-size: 10.5px;
  color: var(--ink-dim);
  font-family: var(--font-mono);
}

/* ---------- dashboard: tarjeta de grafica ---------- */

.dash-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 20px 20px;
  margin-bottom: 20px;
}

.dash-card-header h3 {
  margin: 0 0 14px;
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--ink-dim);
  font-weight: 600;
  text-transform: uppercase;
}

.dash-card-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}
.dash-card-header h3 { margin: 0; }

/* ---------- dashboard: nota de acceso desde la red local ---------- */

.nota-red-local {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-dim);
  padding: 10px 14px;
  border: 1px dashed var(--border);
  border-radius: 8px;
}
.nota-red-local strong {
  font-family: var(--font-mono);
  color: var(--ink);
  font-weight: 600;
}
.nota-red-local .btn-link {
  margin-left: auto;
}

.leyenda {
  font-size: 12px;
  color: var(--ink-dim);
  display: flex;
  align-items: center;
  gap: 6px;
}
.punto {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-left: 10px;
}
.punto:first-child { margin-left: 0; }
.punto.pos { background: var(--green); }
.punto.neg { background: var(--red); }

.chart-svg { width: 100%; height: auto; display: block; margin-top: 8px; }
.barra-pos { fill: var(--green); }
.barra-neg { fill: var(--red); }
.chart-eje { stroke: var(--border); stroke-width: 1; }
.chart-label {
  fill: var(--ink-dim);
  font-family: var(--font-mono);
  font-size: 11px;
}

/* ---------- configuracion ---------- */

.config-intro {
  font-size: 13px;
  color: var(--ink-dim);
  margin: -6px 0 18px;
  max-width: 60ch;
}

.campo-ayuda {
  font-size: 11.5px;
  color: var(--ink-dim);
  margin: 6px 0 0;
}
.campo-ayuda code {
  font-family: var(--font-mono);
  background: var(--bg);
  padding: 1px 4px;
  border-radius: 4px;
}

.btn-file { cursor: pointer; padding: 8px 14px; }

/* ---------- tarjetas de interruptor (Configuracion: Modulos / Apariencia) ---------- */
/* una tarjeta por ajuste booleano — icono + titulo/descripcion + un
   interruptor real (checkbox nativo, solo que estilizado como riel en vez
   de casilla), en vez de la lista suelta de <label><input>texto largo</label>
   de antes. */

.modulos-lista {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 24px;
}

.modulo-card {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
  cursor: pointer;
  transition: border-color 0.15s ease;
}
.modulo-card:hover { border-color: var(--ink-dim); }
.modulo-card:has(input:checked) { border-color: var(--blue); }

/* variante para una fila de accion (icono + texto + boton) en vez de un
   interruptor — la tarjeta ya no es en si misma el elemento clickeable. */
.modulo-card.modulo-card-accion { cursor: default; }
.modulo-card.modulo-card-accion.modulo-card-riesgo { border-color: rgba(226, 87, 76, 0.35); }

.modulo-icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--ink-dim);
}

.modulo-texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.modulo-titulo { font-size: 14px; font-weight: 600; }
.modulo-desc { font-size: 12.5px; color: var(--ink-dim); }

.modulo-switch {
  position: relative;
  flex-shrink: 0;
  width: 38px;
  height: 22px;
}
.modulo-switch input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.modulo-switch-riel {
  position: absolute;
  inset: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.modulo-switch-riel::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--ink-dim);
  transition: transform 0.15s ease, background 0.15s ease;
}
.modulo-switch input:checked + .modulo-switch-riel {
  background: var(--blue);
  border-color: var(--blue);
}
.modulo-switch input:checked + .modulo-switch-riel::before {
  transform: translateX(16px);
  background: #f5f7ff;
}
.modulo-switch input:focus-visible + .modulo-switch-riel {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

/* ---------- Configuracion → Modulos: reordenar + grupo "Movimientos" ---------- */

.modulo-card-reordenable { cursor: default; }
.modulo-card-reordenable:hover { border-color: var(--border); }

/* envuelve icono+texto+switch en un <label> (fuera de .modulo-orden, para
   que subir/bajar sea un control aparte que nunca dispare el toggle) —
   sin esto el unico punto que de verdad prende/apaga el modulo es el
   riel de 38x22px, un blanco chiquito y facil de fallar; con el <label>
   todo el icono y el texto tambien cuentan como "click en el switch",
   igual que ya funcionaba en las tarjetas de Apariencia. */
.modulo-card-toggle {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1;
  min-width: 0;
  cursor: pointer;
}

.modulo-orden {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex-shrink: 0;
}
.modulo-orden-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 17px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface-2);
  color: var(--ink-dim);
  cursor: pointer;
}
.modulo-orden-btn:hover:not(:disabled) { color: var(--ink); border-color: var(--ink-dim); }
.modulo-orden-btn:disabled { opacity: 0.3; cursor: default; }
.modulo-orden-btn .icon { width: 12px; height: 12px; }

/* la fila de "Movimientos" no tiene interruptor propio (se muestra sola
   si al menos una hija esta activa) — el badge deja claro cuantas lo
   estan sin tener que desplegar nada. */
.modulo-card-grupo .modulo-titulo { display: flex; align-items: center; }
.modulo-badge {
  margin-left: 8px;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-dim);
  background: var(--surface-2);
  border-radius: 999px;
  padding: 1px 8px;
  white-space: nowrap;
}

/* referencia visual entre "Movimientos" y sus tres opciones: mismo
   sangrado + linea vertical que usa el acordeon real del sidebar (ver
   .sidebar-acordeon-contenido), para que se lea como el mismo grupo. */
.modulos-grupo { display: flex; flex-direction: column; gap: 8px; }
.modulos-grupo-hijos {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-left: 18px;
  padding-left: 14px;
  border-left: 2px solid var(--border);
}

.modulos-guardar-orden {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  background: var(--surface-2);
  border: 1px solid var(--blue);
  border-radius: 10px;
  padding: 10px 14px;
  margin: -14px 0 24px;
  font-size: 13px;
}
.modulos-guardar-orden-botones { display: flex; gap: 8px; flex-shrink: 0; }

@media (max-width: 720px) {
  .app-shell { flex-direction: column; }

  /* la barra de arriba queda compacta (logo + boton de menu); el menu
     completo se despliega como panel al tocar el boton, en vez de
     competir por espacio permanente arriba de cada pantalla. */
  .sidebar {
    width: 100%;
    height: auto;
    max-height: none;
    overflow: visible;
    position: sticky;
    top: 0;
    left: auto;
    z-index: 30;
    flex-direction: row;
    align-items: center;
    padding: 12px 16px;
    transform: none;
    box-shadow: none;
  }
  .sidebar-brand { margin-bottom: 0; flex: 1; }

  .btn-menu { display: inline-flex; }

  .sidebar-backdrop.abierto {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
  }

  /* el panel en si: oculto por default, se muestra colgando justo
     debajo de la barra (position:absolute respecto al .sidebar, que ya
     es position:sticky y por lo tanto establece ese marco). */
  .sidebar-panel {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    max-height: calc(100vh - 64px);
    overflow-y: auto;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 16px 32px -14px rgba(0, 0, 0, 0.6);
    padding: 8px 16px 16px;
  }
  .sidebar-panel.abierto { display: flex; }

  .sidebar-nav { flex: none; }
  .sidebar-footer { border-top: 1px solid var(--border); margin-top: 14px; padding-top: 14px; }

  .main { padding: 18px 16px 40px; }

  /* filas de lista (Gastos, Ingresos, Usuarios, Cajas...): en escritorio
     titulo+monto+acciones caben en una sola linea; en telefono el titulo
     y las notas suelen ocupar mas de una linea, y con todo en una sola
     fila el monto/los botones quedaban encimados con ese texto. Aqui el
     titulo+subtitulo ocupan su propia linea completa, y monto+acciones
     pasan a una segunda linea abajo. */
  .row { flex-wrap: wrap; row-gap: 6px; }
  .row-main { flex-basis: 100%; }
  .row-actions { margin-left: auto; }

  /* en telefono los dos botones se apilan, con el de imprimir a todo lo
     ancho — lado a lado quedaban muy apretados en pantallas angostas. */
  .recibo-acciones { flex-direction: column; align-items: stretch; }
  .recibo-acciones .btn-primary { min-width: 0; width: 100%; }
  .recibo-acciones .btn-link { text-align: center; }
}

/* ---------- cajas separadas (pesos / dolares), seccion Ingresos ---------- */

.caja-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
  margin: 18px 0 24px;
}

.caja-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.caja-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
}

.caja-valor {
  font-family: var(--font-mono);
  font-size: 28px;
  font-weight: 700;
}
.caja-valor.pos { color: var(--green); }

/* ---------- avisos (p. ej. pago de salario pendiente) ---------- */

.aviso {
  border: 1px solid var(--amber);
  background: rgba(217, 164, 65, 0.1);
  border-radius: 10px;
  padding: 14px 18px;
  margin-bottom: 20px;
}

.aviso-titulo {
  font-weight: 700;
  color: var(--amber);
  margin-bottom: 8px;
}

.aviso-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
  font-size: 13.5px;
}

.btn-sm {
  padding: 6px 12px;
  font-size: 12px;
  flex-shrink: 0;
}

.dash-nota {
  margin: 12px 0 0;
  font-size: 12.5px;
  color: var(--ink-dim);
}

/* ---------- comprobantes (adjuntar imagen/pdf a un ingreso o gasto) ---------- */

.field-hint {
  font-size: 10.5px;
  color: var(--ink-dim);
  margin-top: 2px;
}

.comprobante-actual {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 13px;
}

.comprobante-actual a {
  color: var(--ink);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}
.comprobante-actual a:hover { text-decoration: underline; }

.comprobante-quitar {
  background: none;
  border: none;
  color: var(--ink-dim);
  cursor: pointer;
  font-size: 13px;
  padding: 2px 6px;
  border-radius: 4px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
}
.comprobante-quitar:hover { color: var(--red); background: rgba(226, 87, 76, 0.12); }

/* ---------- badges de tipo de movimiento (seccion Resumen general) ---------- */

.badge-ingreso {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--green);
  background: rgba(51, 163, 116, 0.15);
  border-radius: 4px;
  padding: 1px 6px;
  margin-right: 6px;
  vertical-align: middle;
}

.badge-gasto {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--red);
  background: rgba(226, 87, 76, 0.15);
  border-radius: 4px;
  padding: 1px 6px;
  margin-right: 6px;
  vertical-align: middle;
}

/* ---------- badges de tipo (seccion Lista de precios) ---------- */

.badge-producto {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--green);
  background: rgba(51, 163, 116, 0.15);
  border-radius: 4px;
  padding: 1px 6px;
  vertical-align: middle;
}

.badge-servicio {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--blue);
  background: rgba(91, 130, 240, 0.15);
  border-radius: 4px;
  padding: 1px 6px;
  vertical-align: middle;
}

.badge-paquete {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--amber);
  background: rgba(217, 164, 65, 0.15);
  border-radius: 4px;
  padding: 1px 6px;
  vertical-align: middle;
}

/* ---------- tabla generica (seccion Lista de precios) ---------- */
/* primer uso de una tabla HTML real en la app — el resto de las listas
   usa .list/.row (una tarjeta por fila), pero aqui el diseño pide
   columnas alineadas de verdad. */

.tabla-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
}

.tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.tabla th {
  text-align: left;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-dim);
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
  white-space: nowrap;
}

.tabla td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.tabla tbody tr:last-child td { border-bottom: none; }
.tabla tbody tr:hover { background: var(--surface-2); }

.tabla-nombre { font-weight: 600; }
.tabla-desc { color: var(--ink-dim); font-size: 12px; margin-top: 2px; }
.tabla-precio { font-family: var(--font-mono); color: var(--green); font-weight: 600; }
.tabla-acciones { white-space: nowrap; text-align: right; }

.disponible-indicador { display: inline-flex; align-items: center; gap: 6px; }

/* ---------- dropdown de varias opciones (categorias en Lista de precios) ---------- */
/* un boton que se ve como un <select> normal, pero abre un panel con
   checkboxes en vez de un <option> por valor — permite marcar varias a
   la vez sin el UX pobre de un <select multiple> nativo. */

.dropdown-multiselect {
  position: relative;
}
.dropdown-multiselect-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 9px 10px;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 14px;
  text-align: left;
  cursor: pointer;
}
.dropdown-multiselect-toggle:focus { outline: none; border-color: var(--blue); }
.dropdown-multiselect-toggle span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dropdown-multiselect-panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  max-height: 220px;
  overflow-y: auto;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.dropdown-multiselect-panel .chk-columna { padding: 5px 0; }
.dropdown-multiselect-separador {
  border-top: 1px solid var(--border);
  margin-top: 6px;
  padding-top: 8px;
}

/* ---------- resumen por caja (seccion Resumen general) ---------- */
/* nunca un total mezclado entre efectivo/tarjeta/dolares: una fila por
   caja, cada una con su propio ingresos/gastos/balance. */

.resumen-caja-mes {
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 0 4px;
  margin-bottom: 6px;
}
.resumen-caja-mes strong { color: var(--ink); font-weight: 600; }

.resumen-caja-fila {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-dim);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 14px;
  padding: 4px 4px;
  border-bottom: 1px dashed var(--border);
}
.resumen-caja-fila:last-of-type { border-bottom: none; margin-bottom: 10px; }

.resumen-caja-etiqueta {
  color: var(--ink);
  font-weight: 600;
  min-width: 62px;
}

.buscador {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 12px;
  margin-bottom: 14px;
  color: var(--ink-dim);
}
.buscador input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 14px;
}
.buscador input:focus { outline: none; }
.buscador input::placeholder { color: var(--ink-dim); }
.buscador .btn-icon { flex-shrink: 0; }

/* ---------- selector de color de cajas (Configuración) ---------- */

.paleta-colores {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 8px;
}

.paleta-swatch {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 12px;
  padding: 6px 14px;
  border-radius: 8px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  cursor: pointer;
  transition: transform 0.08s ease;
}
.paleta-swatch:hover { transform: translateY(-1px); }
.paleta-swatch:active { transform: scale(0.96); }

.color-personalizado {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 6px;
  flex-wrap: wrap;
}

.color-personalizado label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--ink-dim);
}

.color-personalizado input[type="color"] {
  width: 36px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: none;
  cursor: pointer;
}

/* ---------- panel exportar/importar CSV (Gastos e Ingresos) ---------- */

.panel-exportar {
  margin-top: 24px;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 4px 16px;
}

.panel-exportar summary {
  cursor: pointer;
  padding: 10px 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-dim);
  list-style: none;
}
.panel-exportar summary::-webkit-details-marker { display: none; }
.panel-exportar summary::before {
  content: '';
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 6px;
  vertical-align: -1px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 3l5 5-5 5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 3l5 5-5 5'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 0.15s ease;
}
.panel-exportar[open] summary::before { transform: rotate(90deg); }

.panel-exportar-cuerpo { padding: 4px 0 16px; }

.columnas-export {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-bottom: 14px;
}

.chk-columna {
  font-size: 12.5px;
  color: var(--ink-dim);
  display: flex;
  align-items: center;
  gap: 5px;
}

.panel-exportar-acciones {
  display: flex;
  gap: 10px;
  align-items: center;
}

#resultadoImport {
  font-size: 12.5px;
  color: var(--ink-dim);
  margin-top: 10px;
}

/* ---------- carrito de inventario (Gastos/Ingresos) y atributos (Inventario) ---------- */

.carrito-inventario, #filasAtributos {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 10px;
}

.fila-carrito, .fila-atributo {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.fila-carrito select.carrito-item { flex: 2 1 200px; min-width: 0; }
.fila-carrito input.carrito-cantidad { flex: 0 1 100px; min-width: 0; }
.fila-carrito select.carrito-tipo { flex: 0 1 110px; min-width: 0; }

.fila-atributo input.atributo-clave,
.fila-atributo input.atributo-valor { flex: 1 1 150px; min-width: 0; }

.fila-carrito select,
.fila-carrito input,
.fila-atributo input {
  font-family: var(--font-sans);
  font-size: 13px;
  padding: 7px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--ink);
}

/* ---------- imprimir comprobante ---------- */

.tabs-tipo {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}

/* filtroPeriodo.js (Día/Semana/Mes) ahora se monta arriba de la lista en
   vez de abajo — sin este margen quedaba pegado al titulo/boton de
   arriba, sin nada de aire. */
#filtroPeriodo {
  margin: 4px 0 22px;
}

.tab-btn {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
}
.tab-btn:hover { border-color: var(--ink-dim); color: var(--ink); }
.tab-btn.active { background: var(--surface-2); color: var(--ink); border-color: var(--ink-dim); }

.panel-imprimir {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.opciones-imprimir {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 32px;
  margin-bottom: 20px;
}

.opciones-grupo { display: flex; flex-direction: column; gap: 8px; }

.opciones-grupo-titulo {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.opciones-radios { display: flex; gap: 16px; flex-wrap: wrap; }

.opciones-radios label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
}

/* el recibo se ve identico en pantalla y al imprimir a proposito — asi la
   vista previa nunca miente sobre lo que va a salir en el papel — por eso
   sus colores son fijos (grises neutros) y no usan las variables de tema
   claro/oscuro del resto de la app. */
.recibo-preview-wrap {
  display: flex;
  justify-content: center;
  padding: 28px;
  background: var(--surface-2);
  border-radius: 10px;
  overflow: auto;
}

.recibo-hoja {
  background: #ffffff;
  color: #1a1a1a;
  width: 320px;
}

/* el modal de Imprimir inventario (abrirModalImprimirInventario) trae
   mas controles arriba del preview que los demas modales de imprimir
   (nav de dia + 2 grupos de opciones) — un poco mas de ancho evita que
   se vea apretado, sin ensanchar el resto de los recibos/reportes. */
.modal-caja-ancha { max-width: 600px; }
.recibo-hoja-ancha { width: 420px; }

.recibo {
  padding: 22px 20px;
  font-family: var(--font-mono);
}

.recibo-corte {
  position: relative;
  border-top: 1px dashed #999;
  margin: 0 14px;
}
.recibo-corte-etiqueta {
  position: absolute;
  left: 50%;
  top: -7px;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 3px;
  background: #ffffff;
  padding: 0 6px;
  font-size: 9px;
  letter-spacing: 0.06em;
  color: #999;
  text-transform: uppercase;
}

.recibo-marca {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #777;
}

.recibo-tipo {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  margin-top: 2px;
  color: #1a1a1a;
}

.recibo-folio {
  font-size: 11px;
  color: #777;
  margin-top: 2px;
}

.recibo-linea { border-top: 1px dashed #bbb; margin: 12px 0; }

.recibo-fila {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 12px;
  padding: 3px 0;
}
.recibo-fila span:first-child { color: #777; }
.recibo-fila span:last-child { text-align: right; }

.recibo-monto {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 17px;
  font-weight: 700;
  padding-top: 4px;
  color: #1a1a1a;
}

.recibo-firma {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 34px;
  font-size: 10px;
  color: #777;
}
.recibo-firma span:first-child { width: 70%; border-top: 1px solid #999; margin-bottom: 4px; }

.recibo-acciones {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 20px 0 22px;
}
/* con dos botones primarios (Imprimir / Guardar como PDF) en la misma
   fila, min-width 220px c/u no cabe en el modal angosto (max-width
   480px) — se encogen a 160px para que quepan lado a lado en vez de
   apilarse antes de tiempo. */
.recibo-acciones .btn-primary { min-width: 160px; flex: 1 1 160px; }

/* ---------- reporte de periodo (ver reporteImpresion.js) ---------- */
/* mismo look del recibo (.recibo-marca/.recibo-tipo/.recibo-folio/
   .recibo-linea de arriba) pero con filas tabulares en vez de campos
   etiqueta/valor apilados — un renglon por movimiento, monto a la
   derecha, para que se lea como un estado de cuenta. */

.reporte-fila {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-size: 12px;
  padding: 5px 0;
  border-bottom: 1px dotted #ddd;
}
.reporte-fila-izq {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.reporte-fila-fecha { font-size: 10.5px; color: #999; }
.reporte-fila-desc { color: #1a1a1a; }
.reporte-fila-monto { flex-shrink: 0; font-weight: 700; color: #1a1a1a; }

.reporte-total {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  padding: 3px 0;
  color: #777;
}
.reporte-total.destacado {
  font-size: 15px;
  font-weight: 700;
  color: #1a1a1a;
  padding-top: 6px;
}

/* ---------- modal de impresion suelta (boton "imprimir" en Gastos/Ingresos) ---------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 100;
}

.modal-caja {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px;
  max-width: 480px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.modal-header h3 { margin: 0; }

/* al imprimir, solo se muestra el area del recibo — el resto de la app
   (menu, formularios, lista de movimientos) se oculta por completo. */
@media print {
  /* solo queda visible #areaImprimir (marcado `.imprimir-objetivo`) y la
     cadena de sus ancestros hasta <body> (`.imprimir-ancestro`) — ver
     marcarParaImprimir() en utils.js, que arma esas clases justo antes
     de cada window.print(). display:none saca a todo lo demas del
     flujo del documento por completo (a diferencia de un viejo intento
     con visibility:hidden, que solo lo volvia invisible pero sin alto
     0 — el alto invisible del resto de la app generaba paginas fantasma
     donde el modal, position:fixed, se repetia una vez por pagina). */
  body * { display: none !important; }
  .imprimir-ancestro {
    display: revert !important;
    position: static !important;
    inset: auto !important;
    background: none !important;
    padding: 0 !important;
    margin: 0 !important;
    max-width: none !important;
    max-height: none !important;
    overflow: visible !important;
  }
  .imprimir-objetivo,
  .imprimir-objetivo * {
    display: revert !important;
  }
  .recibo-hoja { width: auto; }
}
