:root {
  /* ── Paleta base (no modificar sin sign-off de Martín) ── */
  --bg: #f4f7fb;
  --panel: #ffffff;
  --text: #172033;
  --muted: #6b7280;
  --line: #e5e7eb;
  --border: #e5e7eb;          /* alias de --line para compatibilidad PWA */
  --primary: #2563eb;
  --primary-hover: #1d4ed8;
  --primary-dark: #1e40af;
  --primary-deep: #1e3a8a;
  --primary-soft: #dbeafe;
  --on-primary: #ffffff;
  --accent: #2563eb;
  --danger: #dc2626;
  --success: #16a34a;
  --success-dark: #15803d;      /* alias usado en descuento de cupón (tabla) */
  --warning: #f59e0b;
  --soft-primary: #dbeafe;
  /* Alias de compatibilidad para vars sueltas usadas en JS sin fallback */
  --color-muted: var(--muted);  /* tabla fotocopias */
  --gris-borde: var(--border);  /* modal landing leads */
  --gris-bg: #f9fafb;           /* footer modal landing leads */
  --soft-danger: #fee2e2;
  --soft-success: #dcfce7;
  --shadow: 0 10px 30px rgba(15, 23, 42, .08);
  --radius: 18px;

  /* ── Tokens Opción B (2026-05-27) — solo agregar, no romper nada ── */

  /* Border-radius */
  --radius-xs:   4px;
  --radius-sm:   6px;
  --radius-md:  10px;
  --radius-lg:  14px;
  --radius-xl:  18px;          /* = --radius actual */
  --radius-full: 999px;

  /* Espaciado (escala 4px) */
  --space-1:  4px;
  --space-2:  8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 28px;             /* = padding actual de .view */

  /* Escala tipográfica */
  --font-xs:   11px;
  --font-sm:   12px;
  --font-base: 14px;
  --font-md:   15px;
  --font-lg:   17px;
  --font-xl:   22px;
  --font-2xl:  25px;

  /* Pesos tipográficos */
  --fw-normal:    500;
  --fw-semibold:  600;
  --fw-bold:      700;
  --fw-extrabold: 800;

  /* Sombras */
  --shadow-sm: 0 1px 3px rgba(15, 23, 42, .06);
  --shadow-md: 0 4px 12px rgba(15, 23, 42, .08);
  --shadow-lg: 0 10px 30px rgba(15, 23, 42, .10);
  --shadow-xl: 0 20px 60px rgba(15, 23, 42, .15);

  /* Modal canónico — valores unificados para todos los sistemas de modal */
  --modal-padding-header: 14px 20px;
  --modal-padding-body:   18px 20px;
  --modal-padding-footer: 12px 20px;
  --modal-header-font-size:   16px;
  --modal-header-font-weight: 600;

  /* Transiciones */
  --transition-fast: .12s ease;
  --transition-base: .18s ease;

  /* ── Aliases semánticos (2026-07-03 Homogeneización UI FASE 1) ── */
  /* --surface / --surface-2: aliases de --panel / --bg para uso en
     componentes nuevos que prefieren nombres semánticos Material-style.
     No reemplazan --panel/--bg en código existente (no-op visual). */
  --surface:   #ffffff;           /* = --panel */
  --surface-2: #f9fafb;           /* superficie secundaria (fondos de th, footer de modal) */
  /* --ink: color de texto principal (alias de --text para contextos de tipografía) */
  --ink: #172033;                  /* = --text */
  /* Elevaciones semánticas */
  --elev-1: var(--shadow-sm);     /* = 0 1px 3px rgba(15,23,42,.06) — cards planas */
  --elev-2: var(--shadow-md);     /* = 0 4px 12px rgba(15,23,42,.08) — cards normales */
  --elev-3: var(--shadow-lg);     /* = 0 10px 30px rgba(15,23,42,.10) — modales */
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
  background: var(--bg);
  color: var(--text);
  /* 2026-05-15: REMOVIDO `zoom: 0.8` que estaba desde
     16b7efa (feat ui: Stock con pestañas + UX facturación). Era
     un parche viejo para "hacer entrar más cosas" en pantallas
     chicas, pero corrompía todos los cálculos de altura del proyecto:
     - calc(100vh - Npx) de los listados fallaba (zoom escala viewport).
     - .view:has(.comprobante-page) height calculaba mal.
     - El body terminaba midiendo menos que la ventana → franja vacía
       abajo en muchas pantallas.
     Pedido de Martín 2026-05-15: 'auditar de dónde sale el zoom 0.8
     y por qué se puso. Si se puede sacar sin romper, mejor — destraba
     muchas otras cosas'.
     Si después aparecen pantallas donde el contenido no entra, se
     resuelve con layout (flex/grid) o reduciendo font-size puntual,
     NO con zoom global. */
}

button,
input,
select,
textarea {
  font-family: inherit;
}

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

.sidebar {
  width: 290px;
  background: #0f172a;
  color: white;
  padding: 18px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 4px 16px;
  border-bottom: 1px solid rgba(255,255,255,.12);
  margin-bottom: 14px;
}

.sidebar-header .brand-empresa {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  flex: 1 1 auto;
}

.sidebar-header .brand-empresa img {
  max-height: 36px;
  max-width: 48px;
  object-fit: contain;
  background: #fff;
  border-radius: 4px;
  padding: 2px;
  flex-shrink: 0;
}

.sidebar-header .brand-empresa span {
  font-size: 13px;
  font-weight: 500;
  opacity: 0.9;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.brand-icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: linear-gradient(135deg, #60a5fa, #fca5a5);
  display: grid;
  place-items: center;
  font-weight: 900;
  font-size: 13px;
  flex-shrink: 0;
}

.brand-text {
  line-height: 1.15;
}

.brand h1 {
  font-size: 14px;
  margin: 0;
  font-weight: 800;
  letter-spacing: .2px;
}

.brand p {
  margin: 2px 0 0;
  color: #cbd5e1;
  font-size: 11px;
}

.btn-candado {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  background: #f8fafc;
  color: #64748b;
  font-size: 15px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background .15s, color .15s, border-color .15s;
  padding: 0;
  flex-shrink: 0;
}

.btn-candado:hover {
  background: #f1f5f9;
  color: #334155;
}

.btn-candado.active {
  color: #16a34a;
  border-color: #86efac;
  background: #f0fdf4;
}

.menu {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.menu-item,
.menu-parent {
  width: 100%;
  border: 0;
  text-align: left;
  padding: 12px 14px;
  border-radius: 13px;
  cursor: pointer;
  background: transparent;
  color: #e5e7eb;
  font-size: 15px;
}

.menu-parent {
  color: #93c5fd;
  font-weight: 700;
  margin-top: 8px;
}

.menu-parent::after {
  content: "▾";
  float: right;
}

.menu-item:hover,
.menu-parent:hover {
  background: rgba(255,255,255,.08);
}

.menu-item.active {
  background: var(--primary);
  color: var(--on-primary, #fff);
  font-weight: 700;
}

.submenu {
  display: none;
  padding-left: 10px;
}

.submenu.open {
  display: block;
}

.submenu .menu-item {
  font-size: 14px;
  padding: 10px 14px;
}

/* Cambio 2026-05-10: el botón secundario "↗" del menú se removió. Ahora
 * cada .menu-item abre por default en una pestaña nueva del navegador
 * (Shift+click navega en la actual). Comportamiento documentado en el
 * `title` del button. */

.menu-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 6px;
  margin-left: 6px;
  border-radius: 999px;
  background: #d97706;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
}

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

.topbar {
  background: rgba(255,255,255,.82);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  padding: 22px 28px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 18px;
  position: sticky;
  top: 0;
  z-index: 5;
}

.topbar h2 {
  margin: 0;
  font-size: 25px;
}

.topbar p {
  margin: 5px 0 0;
  color: var(--muted);
}

.top-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

/* Botón Salir: rojo distintivo, anclado al final de la topbar.
   Antes era btn btn-light y se confundía con los otros botones; el
   usuario reportó que visualmente "se iba hasta la última fila de la
   tabla" — síntoma de que no resaltaba como acción separada. */
.btn-logout {
  background: #dc2626;
  color: #fff;
  border: 0;
  border-radius: 8px;
  padding: 8px 14px;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
  white-space: nowrap;
  transition: background .12s;
}
.btn-logout:hover { background: #b91c1c; }
.btn-logout:active { background: #991b1b; }
.btn-logout:focus-visible {
  outline: 2px solid #fca5a5;
  outline-offset: 2px;
}

.status {
  padding: 8px 12px;
  border-radius: 999px;
  background: var(--soft-success);
  color: #166534;
  font-size: 13px;
  font-weight: 700;
}

.view {
  padding: 28px;
}

/* .page-title — título de sección canónico (2026-05-27: antes solo en CC, sin estilo) */
.page-title {
  font-size: var(--font-xl, 22px);
  font-weight: var(--fw-extrabold, 800);
  color: var(--text);
  margin: 0 0 var(--space-4, 16px);
  padding: 0;
  line-height: 1.2;
}

.grid {
  display: grid;
  gap: 18px;
}

.grid-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.grid-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.grid-5 {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

.info-table td {
  padding: 6px 10px;
  border-bottom: 1px dashed #e5e7eb;
  font-size: 13px;
}
.info-table td:first-child {
  width: 200px;
  color: #6b7280;
}
.info-table tr:last-child td {
  border-bottom: 0;
}

.card {
  background: var(--panel);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-2);
  padding: 22px;
  border: 1px solid rgba(15,23,42,.04);
}

.card h3 {
  margin: 0 0 14px;
}

.kpi {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.kpi .label {
  color: var(--muted);
  font-size: 14px;
}

.kpi .value {
  font-size: 28px;
  font-weight: 900;
  margin-top: 8px;
}

.kpi .emoji {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  background: #f1f5f9;
  border-radius: 16px;
  font-size: 24px;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(160px, 1fr));
  gap: 14px;
}

.field label {
  display: block;
  font-weight: 700;
  color: #374151;
  margin-bottom: 7px;
  font-size: 14px;
}

/* Ojito del PIN (2026-09-01) — botón dentro del input, alineado a la derecha.
   ⚠ Sólo revela lo que se está ESCRIBIENDO: el PIN guardado va hasheado con
   pbkdf2 y no se puede mostrar (ver el comentario en app.js, wiring del modal
   de usuario). El padding-right del input deja el lugar para el botón. */
.pin-wrap { position: relative; display: block; }
.pin-wrap > .input { width: 100%; padding-right: 38px; }
.pin-eye {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  background: transparent;
  border: 0;
  padding: 4px 6px;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  border-radius: 6px;
  opacity: 0.65;
  transition: opacity 0.12s, background 0.12s;
}
.pin-eye:hover { opacity: 1; background: #f3f4f6; }
.pin-eye:focus-visible { outline: 2px solid #2563eb; outline-offset: 1px; opacity: 1; }

/* Bugfix 2026-05-16 — Form CRM (nuevo lead) y otros modales usaban
   .field / .grid-row / .grid-col sin reglas asociadas, por lo que los
   inputs aparecían apretados sin espaciado. Estas reglas son defensive:
   aplican solo a `.field` sin nested label (uso genérico de spacing
   entre campos) y a las grids de 2 columnas habituales. */
.field {
  margin-bottom: 12px;
}
.field > label {
  display: block;
  font-weight: 600;
  color: #374151;
  margin-bottom: 6px;
  font-size: 13px;
}
.grid-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 12px;
}
.grid-row > .grid-col {
  display: flex;
  flex-direction: column;
}
.grid-col > label {
  display: block;
  font-weight: 600;
  color: #374151;
  margin-bottom: 6px;
  font-size: 13px;
}

.input,
select,
textarea {
  width: 100%;
  border: 1px solid #d1d5db;
  background: #fff;
  padding: 11px 12px;
  border-radius: var(--radius-md);
  outline: none;
  font-size: 14px;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.input:focus,
select:focus,
textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}

textarea {
  min-height: 86px;
  resize: vertical;
}

.btn {
  border: 0;
  border-radius: var(--radius-md);
  padding: 7px 14px;
  font-weight: 700;
  cursor: pointer;
  font-size: 13px;
  line-height: 1.3;
  transition: background var(--transition-fast), color var(--transition-fast), box-shadow var(--transition-fast), border-color var(--transition-fast);
}

.btn-primary {
  background: var(--primary);
  color: white;
}

.btn-primary:hover {
  background: var(--primary-dark);
}

/* 2026-06-01 (Martín): botón "Ver tienda en vivo" con estilo gradient verde +
   ícono de "abrir en pestaña nueva". Distingue de los Publicar/Despublicar
   normales y refuerza que abre la pestaña pública. */
.tw-ver-vivo-btn {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important;
  color: #fff !important;
  text-decoration: none !important;
  display: inline-flex !important;
  align-items: center;
  gap: 4px;
  box-shadow: 0 2px 6px rgba(5, 150, 105, 0.25);
  transition: transform 0.12s, box-shadow 0.12s, filter 0.12s;
  border-radius: var(--radius-md);
}
.tw-ver-vivo-btn:hover {
  background: linear-gradient(135deg, #059669 0%, #047857 100%) !important;
  filter: brightness(1.05);
  transform: translateY(-1px);
  box-shadow: 0 4px 10px rgba(5, 150, 105, 0.35);
}
.tw-ver-vivo-btn:active {
  transform: translateY(0);
  box-shadow: 0 1px 3px rgba(5, 150, 105, 0.3);
}

.btn-light,
.btn-secondary {
  background: var(--border, #e5e7eb);
  color: #111827;
}

/* 2026-06-01: unificado con PWAs — sólido rojo + texto blanco (más
   claro como acción destructiva, estándar Material/GitHub). El estilo
   pastel anterior (--soft-danger bg + #991b1b text) se reemplaza acá. */
.btn-danger {
  background: var(--danger);
  color: #fff;
  border: 1px solid var(--danger);
}
.btn-danger:hover { background: #b91c1c; border-color: #b91c1c; }
.btn-danger:disabled { background: #fca5a5; border-color: #fca5a5; cursor: not-allowed; }

/* 2026-07-03: btn-success migrado a sólido (var(--success) / blanco) para
   coherencia con btn-danger/btn-primary. El pastel anterior (#dcfce7)
   era inconsistente con el resto de acciones primarias. */
.btn-success {
  background: var(--success);
  color: #fff;
  border: 1px solid var(--success);
}
.btn-success:hover { background: #15803d; border-color: #15803d; }
.btn-success:disabled { background: #86efac; border-color: #86efac; cursor: not-allowed; }

.btn-warning {
  background: #fef3c7;
  color: #92400e;
}

/* Badge-botón de alerta (ej: NCs pendientes MP) — tono sólido ámbar */
.btn-warning-solid {
  background: var(--warning);
  color: #fff;
  border: 1px solid var(--warning);
  border-radius: var(--radius-sm);
}
.btn-warning-solid:hover { background: #d97706; border-color: #d97706; }

.actions {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}

table {
  border-collapse: collapse;
  width: 100%;
  background: #fff;
}

th {
  text-align: left;
  padding: 13px;
  font-size: 13px;
  color: #374151;
  background: var(--surface-2, #f9fafb);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

td {
  padding: 12px 13px;
  border-bottom: 1px solid #f1f5f9;
  vertical-align: middle;
  font-size: 14px;
  font-variant-numeric: tabular-nums; /* Montserrat: protege alineación en cols de montos/cantidades */
}

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

/* --- Precio por lista (#12): tabla mejorada en el editor de artículos --- */
.precios-lista-table tbody tr:nth-child(even) { background: #fafbfc; }
.precios-lista-table tbody tr:hover { background: #f3f6fb; }
.precios-lista-table .pl-nombre { font-weight: 600; color: #1f2937; }
.precios-lista-table .pl-precio-cell {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.precios-lista-table .product-lista-precio-input {
  width: 140px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.precios-lista-table .pl-precio-calc {
  font-weight: 600;
  color: #475569;
  font-variant-numeric: tabular-nums;
}
.precios-lista-table .pl-readonly td { color: #64748b; }
.pl-tag {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: 6px;
  line-height: 16px;
}
.pl-tag-base { background: #eef2ff; color: #4f46e5; }
.pl-tag-calc { background: #f1f5f9; color: #94a3b8; }

/* =====================================================================
   REFORMA VISUAL A — start (2026-05-19, REVERSIBLE — git revert <hash>)
   Para revertir: git revert <commit-hash> y bumpeá el cache buster.
   ===================================================================== */

/* --- Parte 1: Sistema unificado de pills (badges de estado) --- */
/* 5 clases canónicas semánticas */
.pill {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: 999px;
  line-height: 18px;
  white-space: nowrap;
}
.pill-ok      { background: #e1f2e8; color: #2f8f5b; }
.pill-warn    { background: #fdf2d8; color: #bf7708; }
.pill-info    { background: #dbe7fb; color: #2461c8; }
.pill-danger  { background: #fde8e8; color: #c0392b; }
.pill-neutral { background: #f1f3f7; color: #4a5568; }

/* Aliases backward-compat: las clases viejas siguen funcionando
   como sinónimos de las nuevas pills. NO eliminar. */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: 999px;
  line-height: 18px;
  white-space: nowrap;
}
.badge-green,   .badge-success              { background: #e1f2e8; color: #2f8f5b; }
.badge-yellow,  .badge-warn, .badge-orange  { background: #fdf2d8; color: #bf7708; }
.badge-blue,    .badge-info                 { background: #dbe7fb; color: #2461c8; }
.badge-red,     .badge-error, .badge-danger, .badge-warning { background: #fde8e8; color: #c0392b; }
.badge-gray,    .badge-grey, .badge-neutral, .badge-light   { background: #f1f3f7; color: #4a5568; }
/* Homogeneización 2026-08-13 (Martín: "diseñame esos combos"): matices que
   faltaban en el set canónico. violet = manual/especial · sky = info
   secundaria · solid-* = alto contraste (fondo pleno, texto blanco). */
.badge-violet,  .badge-purple               { background: #f3e8ff; color: #7e22ce; }
.badge-sky,     .badge-celeste              { background: #e0f2fe; color: #0369a1; }
.badge-teal                                 { background: #d5f5f0; color: #0f766e; }
.badge-solid-danger  { background: #dc2626; color: #fff; }
.badge-solid-warn    { background: #f59e0b; color: #fff; }
.badge-solid-neutral { background: #64748b; color: #fff; }
.badge-solid-info    { background: #1e40af; color: #fff; }

/* =====================================================================
   REFORMA VISUAL A — end (badges)
   ===================================================================== */

/* Chip "provisorio" al lado del número del comprobante (feature #19/F3.5):
   indica que el número final puede shiftearse si otra pestaña guarda primero.
   El definitivo se confirma en el toast post-save. */
.badge-provisional {
  display: inline-block;
  background: #fde68a;
  color: #92400e;
  border: 1px solid #f59e0b;
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-left: 6px;
  cursor: help;
}

/* Candado "solo oficial" (F2-F4 2026-06-04): cuando el candado está cerrado,
   los saldos de CC/dashboard se recalculan contando SOLO comprobantes oficiales.
   Se pintan en celeste para dejar claro que NO es la deuda real, sino la vista
   filtrada. El badge acompaña al título. Es 100% cosmético. */
.saldo-solo-oficial {
  color: #0284c7 !important;
}
.saldo-solo-oficial-badge {
  background: #e0f2fe;
  color: #0369a1;
  margin-left: 8px;
  cursor: help;
}

/* === Card "Información del depósito" en detalle de venta === */
#deposito-info-card { background: #fff7ed; border: 1px solid #fdba74; }
.dep-checklist {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}
.dep-checklist-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  background: white;
  border: 1px solid #e5e7eb;
}
.dep-checklist-row.done { background: #f0fdf4; border-color: #86efac; }
.dep-checklist-row.pending { background: #f9fafb; border-color: #e5e7eb; opacity: 0.85; }
.dep-checklist-mark {
  font-size: 20px;
  font-weight: 800;
  width: 24px;
  text-align: center;
  flex-shrink: 0;
  line-height: 1;
}
.dep-checklist-row.done .dep-checklist-mark { color: #16a34a; }
.dep-checklist-row.pending .dep-checklist-mark { color: #9ca3af; }
.dep-checklist-label { font-weight: 600; font-size: 14px; }
.dep-checklist-detail {
  font-size: 12px;
  color: #6b7280;
  margin-top: 3px;
  line-height: 1.4;
}

.dep-fotos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 8px;
}
.dep-foto-thumb-link {
  display: block;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  overflow: hidden;
  cursor: zoom-in;
  background: white;
}
.dep-foto-thumb {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  display: block;
}
.dep-foto-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  cursor: zoom-out;
}
.dep-foto-lightbox img {
  max-width: 95vw;
  max-height: 95vh;
  object-fit: contain;
}
.dep-foto-lightbox-close {
  position: absolute;
  top: 16px;
  right: 16px;
  background: rgba(255,255,255,0.2);
  color: white;
  border: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  font-size: 24px;
  cursor: pointer;
}

/* ── Tabs de sección canónicas (FASE 3 homogeneización, 2026-07-03) ─────────
   .section-tabs  → contenedor flex con línea inferior
   .section-tab   → botón individual; estado activo/inactivo por clase .active
   Estilo Material: subrayado inferior en --primary, sin bordes pesados.
   Todas las familias divergentes (crm/cml/twc/cartera/conciliacion) migradas
   a estas dos clases. Las clases legacy (.ml-tab, .inner-tab)
   se mantienen como aliases del mismo token visual. (.emp-tab migrado a
   .product-modal-tab en homogeneización 2026-08-13, ver app.js modal empleado)
   ─────────────────────────────────────────────────────────────────────────── */
.section-tabs {
  display: flex;
  gap: 0;
  border-bottom: 2px solid var(--border, #e2e8f0);
  margin-bottom: var(--space-4, 14px);
  flex-wrap: wrap;
  overflow-x: auto;
}

.section-tab {
  appearance: none;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 10px 20px;
  font-size: 14px;
  font-weight: 400;
  color: var(--muted, #475569);
  cursor: pointer;
  margin-bottom: -2px;
  white-space: nowrap;
  transition: color var(--transition-fast, .15s), border-color var(--transition-fast, .15s);
}

.section-tab:hover {
  color: var(--primary);
}

.section-tab.active {
  color: var(--primary);
  font-weight: 600;
  border-bottom-color: var(--primary);
}

/* Badge de conteo dentro de una section-tab */
.section-tab .tab-badge {
  display: inline-block;
  border-radius: 10px;
  padding: 1px 6px;
  font-size: 11px;
  font-weight: 600;
  margin-left: 4px;
  background: var(--border, #e6e8ec);
  color: #374151;
  transition: background var(--transition-fast, .15s), color var(--transition-fast, .15s);
}

.section-tab.active .tab-badge {
  background: var(--primary);
  color: #fff;
}

/* Tabs secundarias y compatibilidad legacy (.ml-tabs, .inner-tabs): */
.ml-tabs,
.page-tabs.page-tabs-secondary {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 14px;
  flex-wrap: wrap;
}

.ml-tab,
.page-tabs.page-tabs-secondary .page-tab {
  appearance: none;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 10px 16px;
  font-weight: 600;
  font-size: 14px;
  color: var(--muted);
  cursor: pointer;
  margin-bottom: -1px;
}

.ml-tab:hover,
.page-tabs.page-tabs-secondary .page-tab:hover {
  color: var(--text);
}

.ml-tab.active,
.page-tabs.page-tabs-secondary .page-tab.active {
  color: var(--primary);
  border-bottom-color: var(--primary);
}

/* Tabs primarias: estilo "segmented control" con fondo y pills,
   visualmente más prominentes que las secundarias para dejar clara
   la jerarquía cuando aparecen las dos al mismo tiempo. */
.page-tabs.page-tabs-primary {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px;
  background: #eef1f5;
  border-radius: 10px;
  border: 1px solid #e2e6eb;
  margin-bottom: 16px;
}

.page-tabs.page-tabs-primary .page-tab {
  appearance: none;
  background: transparent;
  border: 0;
  border-radius: 7px;
  padding: 8px 16px;
  font-weight: 600;
  font-size: 13px;
  color: #4b5563;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, box-shadow .12s ease;
}

.page-tabs.page-tabs-primary .page-tab:hover:not(.active) {
  color: #1c2433;
  background: rgba(255,255,255,.55);
}

.page-tabs.page-tabs-primary .page-tab.active {
  background: #ffffff;
  color: var(--primary);
  box-shadow: 0 1px 2px rgba(15,23,42,.08), 0 1px 1px rgba(15,23,42,.04);
}

.ml-status-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 12px;
  cursor: pointer;
}

.ml-status-badge.connected {
  background: var(--soft-success);
  color: #166534;
}

.ml-status-badge.disconnected {
  background: #f1f5f9;
  color: #64748b;
}

.ml-status-badge::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

/* Task #4 2026-05-20 — badge FLEX sin despachar. */
.ml-flex-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 12px;
  cursor: pointer;
}
.ml-flex-badge .ml-flex-icon { font-size: 14px; line-height: 1; }
.ml-flex-badge[data-urgencia="normal"]  { background: #f1f5f9; color: #475569; }
.ml-flex-badge[data-urgencia="urgente"] { background: #fef3c7; color: #b45309; }
.ml-flex-badge[data-urgencia="critico"] { background: #fee2e2; color: #b91c1c; animation: ml-flex-pulse 1.6s ease-in-out infinite; }
@keyframes ml-flex-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, .55); }
  50%      { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
}

.doc-total {
  display: flex;
  justify-content: flex-end;
  margin-top: 18px;
}

.total-box {
  min-width: 330px;
  background: #f8fafc;
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 16px;
}

.total-row {
  display: flex;
  justify-content: space-between;
  margin: 8px 0;
}

.total-row.big {
  font-size: 24px;
  font-weight: 900;
  border-top: 1px solid var(--line);
  padding-top: 12px;
  margin-top: 12px;
}

/* Mobile: el cuadro de totales (min-width 330px + justify-end) se desbordaba
   y quedaba cortado por el borde izquierdo en pantallas angostas. En mobile
   ocupa el ancho completo y no se sale. */

hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 20px 0;
}

.toast {
  position: fixed;
  bottom: 22px;
  right: 22px;
  background: #111827;
  color: white;
  padding: 14px 18px;
  border-radius: 14px;
  box-shadow: var(--shadow);
  display: none;
  z-index: 20;
  max-width: 430px;
}

.toast.show {
  display: block;
}

.empty {
  color: var(--muted);
  text-align: center;
  padding: 28px;
}

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

.comp-item {
  display: grid;
  grid-template-columns: 1fr 120px 42px;
  gap: 8px;
  align-items: center;
}

.notice {
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  color: #1e3a8a;
  padding: 14px 16px;
  border-radius: 14px;
  margin-bottom: 16px;
}

@media (max-width: 1000px) {
  #app {
    flex-direction: column;
  }

  .sidebar {
    width: 100%;
    height: auto;
    position: relative;
  }

  .grid-2,
  .grid-3,
  .grid-4,
  .grid-5,
  .form-grid {
    grid-template-columns: 1fr;
  }

  .topbar {
    flex-direction: column;
    align-items: flex-start;
  }

  .view {
    padding: 16px;
  }
}


.combo-comp-item {
  grid-template-columns: 1fr 120px minmax(220px, auto) 42px;
}

.combo-cost-detail {
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: var(--muted);
  font-size: 13px;
  background: #f8fafc;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 8px 10px;
}

/* Artículo englobante (2026-09-16): el desglose del surtido debajo de la lista
   de englobados. Números alineados a la derecha con tabular-nums para que la
   columna de sumas se lea de un vistazo. */
.englobante-total {
  margin-top: 14px; border: 1px solid #e2e8f0; border-radius: 8px;
  background: #f8fafc; padding: 10px 14px;
}
.englobante-total-head {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: #64748b; margin-bottom: 6px;
}
.englobante-total-row {
  display: flex; justify-content: space-between; gap: 12px; align-items: baseline;
  font-size: 13px; color: #475569; padding: 3px 0; font-variant-numeric: tabular-nums;
}
.englobante-total-row > span:first-child { min-width: 0; overflow-wrap: anywhere; }
.englobante-total-sum {
  border-top: 1px solid #e2e8f0; margin-top: 5px; padding-top: 7px;
  color: #0f172a; font-weight: 600; font-size: 14px;
}

@media (max-width: 1000px) {
  .combo-comp-item {
    grid-template-columns: 1fr;
  }
}


.product-form-locked-note {
  color: var(--muted);
  font-size: 12px;
  margin-top: 4px;
}


.notice-danger {
  border-color: #fecaca !important;
  background: #fff1f2 !important;
  color: #991b1b !important;
  margin-top: 14px;
}

/* === Modal "Editar recibo" (rediseño estético 2026-08-25) ===
   Solo presentación — abrirEdicionCompletaRecibo() en app.js sigue leyendo
   los mismos ids/name= de siempre para armar el payload. */
.rec-edit-section-title {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink, #1e293b);
}

.rec-edit-valores-table th,
.rec-edit-valores-table td {
  padding: 8px 10px;
  font-size: 13px;
  vertical-align: middle;
}

.rec-edit-valores-table thead th {
  text-align: left;
  color: var(--muted, #64748b);
  font-weight: 600;
  background: #f8fafc;
  border-bottom: 1px solid var(--line, #e2e8f0);
  white-space: nowrap;
}

.rec-edit-valores-table tbody tr {
  border-bottom: 1px solid var(--line, #e2e8f0);
}

.rec-edit-valores-table tbody tr:last-child {
  border-bottom: none;
}

.rec-edit-valores-table select,
.rec-edit-valores-table input {
  min-width: 90px;
}

.rec-edit-valores-table select {
  min-width: 128px;
}

.rec-edit-td-importe input {
  min-width: 100px;
  text-align: right;
}

/* La tabla respira sin scroll interno salvo que haya muchas filas (>6),
   donde refrescarScrollValores() agrega esta clase por JS. */
.rec-edit-table-scroll-active {
  max-height: 300px;
  overflow-y: auto;
}

.rec-edit-imp-table th,
.rec-edit-imp-table td {
  padding: 8px 10px;
  font-size: 13px;
}

.rec-edit-imp-table thead th {
  text-align: left;
  color: var(--muted, #64748b);
  font-weight: 600;
  background: #f8fafc;
  border-bottom: 1px solid var(--line, #e2e8f0);
}

.rec-edit-imp-empty {
  padding: 20px 8px;
  color: #9ca3af;
  font-size: 13px;
  text-align: center;
}

.rec-edit-add-row {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  flex-wrap: wrap;
}

@media (max-width: 768px) {
  .rec-edit-add-row {
    flex-direction: column;
    align-items: stretch;
  }

  .rec-edit-add-row .field {
    width: 100% !important;
  }
}

/* === Reclamo de compra (al proveedor) === */
.reclamo-compra-block {
  margin-top: 14px;
  padding: 12px 14px;
  border-radius: 10px;
  background: #f9fafb;
  border: 1px solid var(--line, #e5e7eb);
}
.reclamo-compra-block.reclamo-abierto {
  background: #fffbeb;
  border-color: #fde68a;
}
.reclamo-compra-block.reclamo-resuelto {
  background: #ecfdf5;
  border-color: #a7f3d0;
}
.reclamo-compra-block h4 {
  font-size: 14px;
  margin: 0;
}

/* === Panel de faltantes (aviso al facturar pedido) === */
.faltantes-panel {
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-left: 4px solid #d97706;
}
.faltantes-panel-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.faltantes-panel-header h3 {
  margin: 0;
  font-size: 15px;
  color: #92400e;
}
.faltantes-panel-icon {
  font-size: 20px;
  line-height: 1;
}
.faltantes-panel-help {
  margin: 0 0 10px;
  font-size: 13px;
  color: #78350f;
}
.faltantes-panel-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}
.faltantes-panel-list li {
  display: grid;
  grid-template-columns: 60px 1fr;
  gap: 8px;
  padding: 8px 10px;
  background: white;
  border: 1px solid #fde68a;
  border-radius: 8px;
  font-size: 13px;
}
.faltantes-cant {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #d97706;
  color: white;
  font-weight: 700;
  border-radius: 6px;
  padding: 2px 8px;
  min-width: 40px;
}
.faltantes-art { color: #1f2937; }
.faltantes-motivo {
  grid-column: 2;
  font-size: 12px;
  color: var(--muted);
  margin-top: 4px;
  font-style: italic;
}


.small-help {
  margin-top: 6px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}


/* ============================================================
   LOGIN — estética SaaS premium ILUSOFT
   Estructura:
     #login-screen
       .login-bg-decor   (orbs + dotgrid)
       .login-topbrand   (ILUSOFT | Gestión comercial)
       .login-card.login-card-v2
         .login-card-hero  (eyebrow + h2 + subtítulo)
         .login-card-form  (inputs + botón + links)
       .login-footer     (© 2026 ILUSOFT…)
   No toca lógica: IDs login-empresa/login-user/login-pin/login-btn intactos.
   ============================================================ */
.login-screen {
  position: fixed;
  inset: 0;
  display: none;
  z-index: 9999;
  overflow: hidden;
  background:
    radial-gradient(120% 80% at 80% 0%, rgba(59, 130, 246, .35) 0%, transparent 55%),
    radial-gradient(110% 80% at 0% 100%, rgba(96, 165, 250, .22) 0%, transparent 60%),
    linear-gradient(135deg, #050d22 0%, #0b1a3b 45%, #11265a 100%);
  color: #e2e8f0;
  font-family: inherit;
}

.login-screen.show {
  display: block;
}

/* Decoración: orbs con blur + dot-grid suave */
.login-bg-decor {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.login-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  opacity: .55;
  will-change: transform;
}
.login-orb-1 {
  width: 520px; height: 520px;
  top: -160px; left: -120px;
  background: radial-gradient(circle, rgba(96,165,250,.85) 0%, rgba(59,130,246,0) 70%);
}
.login-orb-2 {
  width: 460px; height: 460px;
  bottom: -140px; right: -120px;
  background: radial-gradient(circle, rgba(56,189,248,.7) 0%, rgba(2,132,199,0) 70%);
}
.login-orb-3 {
  width: 360px; height: 360px;
  top: 40%; left: 55%;
  background: radial-gradient(circle, rgba(99,102,241,.45) 0%, rgba(79,70,229,0) 70%);
  filter: blur(110px);
  opacity: .45;
}
.login-dotgrid {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255,255,255,.08) 1px, transparent 1px);
  background-size: 22px 22px;
  mask-image: radial-gradient(ellipse at center, #000 30%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse at center, #000 30%, transparent 75%);
}

/* Branding superior izquierdo */
.login-topbrand {
  position: absolute;
  top: 28px;
  left: 32px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  letter-spacing: .04em;
  z-index: 2;
  color: rgba(226, 232, 240, .92);
}
.login-topbrand-mark {
  font-weight: 800;
  letter-spacing: .14em;
  color: #fff;
  text-shadow: 0 1px 0 rgba(0,0,0,.25);
}
.login-topbrand-sep {
  color: rgba(148, 163, 184, .55);
  font-weight: 400;
}
.login-topbrand-tag {
  color: rgba(186, 213, 255, .85);
  font-weight: 500;
}

/* Card centrado */
.login-card {
  position: relative;
  z-index: 2;
  width: min(460px, calc(100vw - 32px));
  margin: 0 auto;
  margin-top: clamp(72px, 12vh, 130px);
  background: #ffffff;
  border-radius: 24px;
  border: 1px solid rgba(255,255,255,.6);
  box-shadow:
    0 30px 80px -20px rgba(8, 22, 56, .55),
    0 12px 30px -10px rgba(8, 22, 56, .35),
    0 0 0 1px rgba(15, 23, 42, .04);
  padding: 40px 40px 32px;
  color: var(--text);
}

.login-card-hero {
  text-align: center;
  margin-bottom: 22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.login-card-hero .login-empresa-logo {
  width: 64px;
  height: 64px;
  object-fit: contain;
  border-radius: 16px;
  margin-bottom: 6px;
}
.login-eyebrow {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: 999px;
  background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
  color: #1d4ed8;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
}
.login-card-hero h2 {
  margin: 6px 0 0;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -.01em;
  color: #0f172a;
  line-height: 1.2;
}
.login-subtitle {
  margin: 4px 0 0;
  font-size: 14px;
  color: var(--muted);
}

.login-card-form .field {
  margin-bottom: 14px;
}
.login-card-form .field label {
  font-size: 13px;
  font-weight: 700;
  color: #334155;
  margin-bottom: 6px;
}

/* Inputs con ícono */
.login-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.login-input-icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #94a3b8;
  pointer-events: none;
  transition: color .15s ease;
}
.login-input.input {
  height: 50px;
  padding: 12px 14px 12px 44px;
  border-radius: 14px;
  border: 1px solid #e2e8f0;
  background: #f8fafc;
  font-size: 15px;
  color: #0f172a;
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.login-input.input::placeholder {
  color: #94a3b8;
}
.login-input.input:hover {
  background: #fff;
  border-color: #cbd5e1;
}
.login-input.input:focus {
  background: #fff;
  border-color: #2563eb;
  box-shadow:
    0 0 0 4px rgba(37, 99, 235, .14),
    0 1px 2px rgba(15, 23, 42, .04);
}
.login-input-wrap:focus-within .login-input-icon {
  color: #2563eb;
}
.login-input-pw {
  padding-right: 48px;
}
.login-pw-toggle {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 10px;
  color: #94a3b8;
  cursor: pointer;
  transition: color .15s ease, background-color .15s ease;
}
.login-pw-toggle:hover {
  color: #1d4ed8;
  background: #eff6ff;
}
.login-pw-toggle.is-on {
  color: #1d4ed8;
}

/* Botón principal con gradiente */
.btn.login-submit {
  width: 100%;
  height: 50px;
  margin-top: 6px;
  border-radius: 14px;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .01em;
  color: #fff;
  background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 50%, #1e3a8a 100%);
  box-shadow:
    0 12px 24px -10px rgba(37, 99, 235, .55),
    0 2px 4px rgba(15, 23, 42, .12),
    inset 0 1px 0 rgba(255,255,255,.18);
  transition: transform .12s ease, box-shadow .15s ease, filter .15s ease;
}
.btn.login-submit:hover {
  filter: brightness(1.06);
  box-shadow:
    0 16px 32px -10px rgba(37, 99, 235, .65),
    0 3px 6px rgba(15, 23, 42, .14),
    inset 0 1px 0 rgba(255,255,255,.22);
}
.btn.login-submit:active {
  transform: translateY(1px);
}
.btn.login-submit:focus-visible {
  outline: 3px solid rgba(37, 99, 235, .35);
  outline-offset: 2px;
}

/* Hint de empresa preseleccionada */
.login-hint-empresa {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 12px auto 0;
  padding: 6px 12px;
  background: #ecfdf5;
  color: #065f46;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  width: fit-content;
}
.login-hint-empresa .login-hint-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #10b981;
  box-shadow: 0 0 0 3px rgba(16, 185, 129, .2);
}

/* Footer copyright */
.login-footer {
  position: absolute;
  bottom: 18px;
  left: 0;
  right: 0;
  text-align: center;
  font-size: 12px;
  color: rgba(203, 213, 225, .7);
  letter-spacing: .04em;
  z-index: 2;
}

/* Responsive mobile */

.permisos-categorias {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 8px;
}

.permisos-cat {
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}

.permisos-cat-titulo {
  background: #1e293b;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 7px 14px;
}

.permissions-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 0;
  padding: 6px 8px;
  background: #f8fafc;
}

.perm-check {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 14px;
  cursor: pointer;
}

.perm-check:hover {
  background: #e8f0ff;
}

.perm-check input {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.permisos-tree details {
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
}

.permisos-tree details + details {
  margin-top: 10px;
}

.permisos-tree summary {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;
  list-style: none;
  padding: 9px 14px;
}

.permisos-tree summary::-webkit-details-marker {
  display: none;
}

.permisos-cat-summary {
  background: #1e293b;
  color: #fff;
  font-size: 13px;
}

.permisos-cat-summary strong {
  font-weight: 700;
  letter-spacing: .04em;
}

.permisos-grupo-summary {
  background: #eef2f7;
  color: #1e293b;
  font-size: 13px;
  font-weight: 600;
}

.permisos-tree .perm-tree-arrow {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform .15s ease;
  margin-right: 2px;
  opacity: .75;
}

.permisos-tree details:not([open]) .perm-tree-arrow {
  transform: rotate(-45deg);
}

.perm-counter {
  margin-left: auto;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  background: rgba(255, 255, 255, .15);
  border-radius: 999px;
  padding: 2px 9px;
}

.permisos-grupo-summary .perm-counter {
  background: #fff;
  border: 1px solid #cbd5e1;
}

.permisos-cat-body {
  padding: 8px 12px 12px;
  background: #f8fafc;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.permisos-grupo-tree {
  border: 1px solid #cbd5e1;
}

.permisos-grupo-body {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0;
  padding: 4px 6px;
  background: #fff;
}

/* Permisos en pestañas — alternativa al árbol expandible. Usa la misma
   barra .product-modal-tabs que el editor de cliente/producto, una pestaña
   por categoría, panel único visible. */
.permisos-tabs-wrap {
  border: 1px solid #cbd5e1;
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
  margin-top: 6px;
}

/* ═══════════════════════════════════════════════════════════════════════
   F2 Sprint Rol CAJERO 2026-05-16 — Lockdown visual.
   Aplica al <body> según `body.classList` que setea setPage en app.js:
     - .rol-cajero-any: cualquiera de los 2 roles (CAJERO o ADMIN_CAJERO).
     - .rol-cajero-puro: CAJERO simple (no puede precios/desc/clientes).
     - .rol-admin-cajero: encargado de caja (precios + clientes + CC OK).
   ═══════════════════════════════════════════════════════════════════════ */

/* Sidebar: ocultar items que no sean del whitelist por rol.
   Items con [data-route] que NO están en estas listas → display: none. */

/* CAJERO puro: solo ve Inicio + Nueva Venta + Comprobantes + Mi cuenta
   + opcionalmente PWA Depósito/Vendedores (vía permiso fino aparte). */
body.rol-cajero-puro .menu-item:not([data-route="dashboard"]):not([data-route="ventas-nueva"]):not([data-route="comprobantes"]):not([data-route="ventas-listado"]):not([data-route="mi-cuenta"]):not([data-route="notificaciones"]):not([data-route="pwa-deposito-redirect"]):not([data-route="pwa-vendedores-redirect"]) {
  display: none !important;
}
body.rol-cajero-puro .menu-group:not(:has(.menu-item:not([style*="display: none"]))) {
  display: none !important;
}

/* ADMIN_CAJERO: lo del CAJERO + Clientes + Tesorería (CC). */
body.rol-admin-cajero .menu-item:not([data-route="dashboard"]):not([data-route="ventas-nueva"]):not([data-route="comprobantes"]):not([data-route="ventas-listado"]):not([data-route="mi-cuenta"]):not([data-route="notificaciones"]):not([data-route="pwa-deposito-redirect"]):not([data-route="pwa-vendedores-redirect"]):not([data-route="clientes"]):not([data-route="clientes-cc"]):not([data-route="tesoreria-recibos"]):not([data-route="tesoreria-pagos"]):not([data-route="tesoreria-cc"]):not([data-route="tesoreria-cobranzas"]) {
  display: none !important;
}
body.rol-admin-cajero .menu-group:not(:has(.menu-item:not([style*="display: none"]))) {
  display: none !important;
}

/* CAJERO puro: read-only en inputs de precio, descripción y descuento dentro
   de comprobantes. ADMIN_CAJERO sí puede editarlos — no aplica.
   Cubre V2 (.cv2-line) Y V1 (data-field="...") ambos. */
body.rol-cajero-puro .cv2-line input[data-cv2-field="precio"],
body.rol-cajero-puro .cv2-line input[data-cv2-field="descripcion"],
body.rol-cajero-puro .cv2-line input[data-cv2-field="descuento"],
body.rol-cajero-puro .cv2-line input[data-cv2-field="descuento_pct"],
/* V1 main: inputs con data-field="..." en las líneas del comprobante. */
body.rol-cajero-puro input[data-field="precio_unitario"],
body.rol-cajero-puro input[data-field="descripcion"],
body.rol-cajero-puro input[data-field="descuento"],
body.rol-cajero-puro input[data-field="descuento_pct"],
body.rol-cajero-puro input[data-field="descuento_porcentaje"],
/* Inputs de descuento general del documento (V1 y V2). */
body.rol-cajero-puro input[name="descuento_general_porcentaje"],
body.rol-cajero-puro input[name="descuento_general_pct"],
body.rol-cajero-puro input#descuento-general-pct,
body.rol-cajero-puro input#cv2-descuento-general {
  pointer-events: none !important;
  background: #f1f5f9 !important;
  color: #475569 !important;
}

/* CAJERO puro: ocultar botones "Nuevo cliente" / "Editar cliente" desde
   el comprobante (los modales se siguen abriendo en read-only desde otros
   accesos, pero este atajo no aparece). */
body.rol-cajero-puro .btn-nuevo-cliente,
body.rol-cajero-puro .btn-editar-cliente,
body.rol-cajero-puro .cv2-cliente-edit,
body.rol-cajero-puro [data-action="nuevo-cliente"],
body.rol-cajero-puro [data-action="editar-cliente"] {
  display: none !important;
}

/* Banner sutil arriba para que el rol cajero sepa que está en modo PV. */
body.rol-cajero-any #topbar::after {
  content: "🛒 Modo caja";
  background: #0ea5e9;
  color: #fff;
  padding: 3px 10px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  margin-left: 12px;
  align-self: center;
}
body.rol-admin-cajero #topbar::after {
  content: "🛒 Modo caja (encargado)";
  background: #6366f1;
}

/* Override 2026-05-16 (Martín): el modal de usuario tiene ~12 pestañas y
   el wrap apilaba 2-3 filas que se veían apretadas. Rediseño: layout de 2
   "lanes" — permisos a la izquierda (contenido), pestañas verticales a la
   derecha (sidebar rail). Modal más ancho. */
.user-editor-modal {
  max-width: min(1500px, 98vw) !important;
}

.user-editor-modal .permisos-tabs-wrap {
  display: grid;
  grid-template-columns: 1fr 260px;
  grid-template-areas: "body tabs";
}

.user-editor-modal .perm-tabs-bar {
  grid-area: tabs;
  flex-direction: column !important;
  flex-wrap: nowrap !important;
  padding: 8px 0;
  background: #f1f5f9;
  border-bottom: 0;
  border-left: 1px solid #e2e8f0;
  overflow-y: auto;
  overflow-x: hidden;
  align-self: stretch;
  gap: 2px;
  /* Mismo tope que el body: con muchas secciones la barra crecía más que el
     panel y se solapaba con el footer (Guardar) en pantallas chicas. Ahora
     scrollea dentro de su columna. */
  max-height: min(60vh, 540px);
}

.user-editor-modal .perm-tabs-bar .perm-tab {
  flex-shrink: 0;
  border-radius: 0 !important;
  border-bottom: 0 !important;
  border-left: 3px solid transparent !important;
  padding: 10px 14px !important;
  font-size: 13px;
  text-align: left;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  white-space: normal;
  line-height: 1.3;
}

.user-editor-modal .perm-tabs-bar .perm-tab:hover {
  background: #e2e8f0;
  color: #1e3a8a;
}

.user-editor-modal .perm-tabs-bar .perm-tab.active {
  background: #fff !important;
  border-left: 3px solid #1e3a8a !important;
  border-bottom: 0 !important;
  color: #1e3a8a;
  font-weight: 700;
}

.user-editor-modal .perm-tabs-bar .perm-tab .perm-tab-counter {
  margin-left: 0;
  padding: 1px 8px;
  flex-shrink: 0;
}

.user-editor-modal .perm-tabs-body {
  grid-area: body;
}

/* Fallback para pantallas chicas (< 900px): vuelve a scroll horizontal arriba. */
@media (max-width: 900px) {
  .user-editor-modal .permisos-tabs-wrap {
    grid-template-columns: 1fr;
    grid-template-areas: "tabs" "body";
  }
  .user-editor-modal .perm-tabs-bar {
    flex-direction: row !important;
    border-left: 0;
    border-bottom: 1px solid #e2e8f0;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 8px 12px 0;
    align-self: auto;
  }
  .user-editor-modal .perm-tabs-bar .perm-tab {
    width: auto;
    white-space: nowrap;
    border-left: 0 !important;
    border-bottom: 2px solid transparent !important;
  }
  .user-editor-modal .perm-tabs-bar .perm-tab.active {
    border-left: 0 !important;
    border-bottom: 2px solid #1e3a8a !important;
  }
}

.perm-tabs-body {
  padding: 14px 16px;
  background: #f8fafc;
  max-height: min(60vh, 540px);
  overflow-y: auto;
}

.perm-tab-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.perm-tab-header {
  display: flex;
  justify-content: flex-end;
  padding: 4px 0;
  border-bottom: 1px dashed #e2e8f0;
}

.perm-tab-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  cursor: pointer;
  user-select: none;
}

.perm-tab-counter {
  margin-left: 8px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  background: rgba(255, 255, 255, .8);
  border: 1px solid #cbd5e1;
  border-radius: 999px;
  padding: 1px 8px;
  color: #64748b;
  font-weight: 600;
}

.perm-tab.active .perm-tab-counter {
  background: #dbeafe;
  border-color: #93c5fd;
  color: #1d4ed8;
}

.permisos-grupo {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
}

.permisos-grupo-header {
  padding: 10px 14px;
  background: #1e293b;
  color: #fff;
  display: flex;
  align-items: center;
  gap: 8px;
}

.permisos-grupo-header .perm-tab-toggle {
  color: #fff;
  font-weight: 700;
  width: 100%;
}

.perm-cat-toggle,
.perm-grupo-toggle {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* Feature #113 (2026-06-26): overrides por informe individual */
.perm-informe-grid {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 10px;
}

.perm-informe-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 0;
  border-bottom: 1px solid #f1f5f9;
  font-size: 13px;
}

.perm-informe-fila:last-child {
  border-bottom: none;
}

.perm-informe-nombre {
  flex: 1;
  color: #334155;
}

.perm-informe-select {
  min-width: 130px;
  max-width: 150px;
  font-size: 12px;
  padding: 3px 8px;
  border-radius: 6px;
  border: 1px solid #cbd5e1;
  background: #f8fafc;
}

.perm-informe-select option[value="true"] { color: #15803d; }
.perm-informe-select option[value="false"] { color: #b91c1c; }


.client-search-wrap {
  position: relative;
}

.search-clear-btn {
  position: absolute;
  top: 9px;
  right: 10px;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 10px;
  background: #eef2f7;
  color: #334155;
  font-size: 20px;
  font-weight: 800;
  cursor: pointer;
  line-height: 1;
}

.search-clear-btn:hover {
  background: #fee2e2;
  color: #991b1b;
}

.search-results {
  display: none;
  position: absolute;
  z-index: 80;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  max-height: 320px;
  overflow: auto;
  background: white;
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 18px 45px rgba(15, 23, 42, 0.18);
  padding: 6px;
}

.search-results.show {
  display: block;
}

.search-result-item {
  width: 100%;
  text-align: left;
  border: 0;
  border-radius: 12px;
  background: white;
  padding: 10px 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: var(--text);
}

.search-result-item:hover {
  background: #eff6ff;
}

.search-result-item span {
  color: var(--muted);
  font-size: 12px;
}

.search-empty {
  padding: 12px;
  color: var(--muted);
  font-size: 13px;
}


.btn:disabled,
button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}


.product-search-wrap {
  position: relative;
  min-width: 260px;
}

.product-search-input {
  padding-right: 12px;
}

.product-search-results {
  display: none;
  position: absolute;
  z-index: 90;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  min-width: 360px;
  max-height: 340px;
  overflow: auto;
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 18px 45px rgba(15, 23, 42, 0.18);
  padding: 6px;
}

.product-search-results.show {
  display: block;
}

.product-search-result {
  width: 100%;
  text-align: left;
  border: 0;
  border-radius: 12px;
  background: white;
  padding: 10px 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: var(--text);
}

.product-search-result:hover {
  background: #eff6ff;
}

.product-search-result span {
  color: var(--muted);
  font-size: 12px;
}

.comp-item .product-search-wrap {
  min-width: 320px;
}

.table-wrap .product-search-results {
  min-width: 520px;
}

@media (max-width: 900px) {
  .product-search-results,
  .table-wrap .product-search-results {
    min-width: 100%;
  }
}


/* Tabla de valores de tesorería — estilo grilla comprobante */
.tes-valores-grid-wrap {
  overflow-x: auto;
  margin: 0 0 4px;
}

.tes-valores-grid {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  table-layout: auto;
}

.tes-valores-grid thead th {
  background: var(--bg-alt, #f8fafc);
  border-bottom: 1px solid var(--line);
  padding: 6px 8px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  white-space: nowrap;
  color: var(--muted);
}

.tes-valores-grid td {
  padding: 4px 6px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

.tes-valores-grid td input,
.tes-valores-grid td select {
  width: 100%;
  box-sizing: border-box;
  padding: 4px 6px;
  font-size: 13px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  outline: none;
  transition: border-color .12s, box-shadow .12s;
}

.tes-valores-grid td input:focus,
.tes-valores-grid td select:focus {
  border-color: var(--primary, #2563eb);
  box-shadow: 0 0 0 2px rgba(37,99,235,.12);
}

.tes-valores-grid tbody tr:has(:focus) {
  background: #eff6ff;
}

.tes-valores-grid tbody tr:has(:focus) td {
  border-bottom-color: #bfdbfe;
}

.tes-valores-grid .tes-importe-input {
  text-align: right;
}

/* Columna Medio fija, columna X angosta */
.tes-valores-grid td:first-child { min-width: 130px; width: 150px; }
.tes-valores-grid td:last-child  { width: 36px; text-align: center; }
.tes-valores-grid td:last-child .btn { padding: 2px 7px; font-size: 13px; }

/* =====================================================================
   UX RECIBOS — Panel de ayuda por medio de pago
   Implementado 2026-05-31 (brief UX recibos Martín).
   Aparece debajo de la grilla de valores al elegir un medio
   distinto de EFECTIVO. Mobile ≤768px: overlay fullscreen.
   ===================================================================== */

.tes-ayuda-medio {
  margin: 8px 0 4px;
  border: 1px solid #bfdbfe;
  border-radius: 10px;
  background: #f0f7ff;
  font-size: 13px;
  animation: tes-ayuda-in .15s ease;
}

@keyframes tes-ayuda-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.tes-ayuda-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px 6px;
  border-bottom: 1px solid #bfdbfe;
  background: #dbeafe;
  border-radius: 9px 9px 0 0;
}

.tes-ayuda-titulo {
  font-size: 12px;
  color: #1e40af;
  font-weight: 500;
}

.tes-ayuda-cerrar {
  background: none;
  border: none;
  font-size: 18px;
  line-height: 1;
  color: #6b7280;
  cursor: pointer;
  padding: 0 4px;
}

.tes-ayuda-cerrar:hover { color: #111; }

.tes-ayuda-body {
  padding: 10px 14px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 14px;
}

.tes-ayuda-seccion {
  min-width: 0;
}

.tes-ayuda-seccion-titulo {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: #1e40af;
  margin-bottom: 6px;
}

.tes-ayuda-campo {
  margin-bottom: 6px;
  line-height: 1.35;
}

.tes-ayuda-campo-nombre {
  font-weight: 600;
  color: #1f2937;
  font-size: 12px;
}

.tes-ayuda-campo-sep {
  color: #9ca3af;
  margin: 0 3px;
  font-size: 11px;
}

.tes-ayuda-campo-ayuda {
  color: #374151;
  font-size: 12px;
}

.tes-ayuda-campo-ejemplo {
  display: block;
  font-size: 11px;
  color: #6b7280;
  margin-top: 1px;
  padding-left: 4px;
}

.tes-ayuda-cuando {
  margin: 0;
  color: #374151;
  font-size: 12px;
  line-height: 1.45;
}

.tes-ayuda-reglas {
  margin: 0;
  padding-left: 16px;
  color: #374151;
  font-size: 12px;
  line-height: 1.55;
}

.tes-ayuda-reglas li { margin-bottom: 3px; }

.tes-ayuda-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 12px 8px;
  border-top: 1px solid #bfdbfe;
  gap: 10px;
}

/* Mobile: overlay fullscreen ≤768px */

/* Estilos legados — se mantienen por si algún partial los usa */
.tes-line {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)) 42px;
  gap: 10px;
  align-items: end;
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 12px;
  margin-bottom: 10px;
  background: #f8fafc;
}

.tes-line .tes-wide {
  grid-column: span 2;
}

@media (max-width: 1100px) {
  .tes-line {
    grid-template-columns: 1fr;
  }

  .tes-line .tes-wide {
    grid-column: auto;
  }
}


.search-count {
  padding: 8px 10px;
  color: var(--muted);
  font-size: 12px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
}

.inner-card {
  box-shadow: none;
  border: 1px solid var(--line);
  margin: 0;
}

.image-placeholder {
  min-height: 130px;
  border: 1px dashed var(--line);
  border-radius: 16px;
  display: grid;
  place-items: center;
  color: var(--muted);
  background: #f8fafc;
  margin-bottom: 10px;
}

.product-photo-preview {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.product-photo-preview img {
  width: 150px;
  height: 150px;
  object-fit: contain;
  background: #f8fafc;
  border: 1px solid var(--line);
  border-radius: 16px;
}

.product-thumb {
  width: 52px;
  height: 52px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #f8fafc;
}

/* ── Galería de fotos por artículo (2026-05-21) ── */
.prod-fotos-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 4px 0;
  min-height: 48px;
}

.prod-fotos-empty {
  color: var(--muted);
  font-size: 13px;
  padding: 16px;
}

.prod-foto-thumb-wrap {
  position: relative;
  width: 120px;
  height: 120px;
  border: 2px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: #f8fafc;
  transition: border-color .15s;
  cursor: grab;
  user-select: none;
}

.prod-foto-thumb-wrap:hover {
  border-color: var(--primary);
}

.prod-foto-thumb-wrap[data-foto-idx]:active {
  cursor: grabbing;
}

.prod-foto-thumb {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.prod-foto-thumb.prod-foto-principal {
  border: none;
}

.prod-foto-badge-principal {
  position: absolute;
  top: 4px;
  left: 4px;
  background: var(--primary);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 10px;
  pointer-events: none;
  line-height: 1.4;
}

.prod-foto-actions {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0,0,0,.55);
  display: flex;
  gap: 4px;
  padding: 4px 5px;
  opacity: 0;
  transition: opacity .15s;
}

.prod-foto-thumb-wrap:hover .prod-foto-actions {
  opacity: 1;
}

/* .btn-xs — definición canónica unificada (2026-05-27: resuelto duplicado en línea ~5200) */
.btn-xs {
  padding: 2px 8px;
  font-size: var(--font-xs, 11px);
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
  border: none;
  font-weight: var(--fw-semibold, 600);
  line-height: 1.4;
}

.prod-foto-meta {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-top: 10px;
}

.prod-fotos-meta {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-top: 10px;
}

.prod-fotos-count {
  font-size: 13px;
  color: var(--muted);
  font-weight: 600;
}

.prod-foto-add-label {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.searchable-select {
  position: relative;
}

.searchable-results {
  z-index: 120;
}

select.master-field {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 14px;
  min-height: 44px;
  padding: 0 12px;
  background: white;
  color: var(--text);
  font: inherit;
}


/* v1.25 menu horizontal */

#app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.sidebar {
  width: 100%;
  background: #0f172a;
  color: white;
  padding: 14px 20px;
  position: sticky;
  top: 0;
  height: auto;
  overflow: visible;
  z-index: 40;
  box-shadow: 0 8px 24px rgba(0,0,0,.14);
}

.brand {
  padding: 8px 6px 14px;
  margin-bottom: 12px;
}

.menu {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: flex-start;
}

.menu-group {
  position: relative;
}

.menu-item,
.menu-parent {
  width: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: left;
  padding: 11px 14px;
  white-space: nowrap;
}

.menu-parent {
  margin-top: 0;
  background: rgba(255,255,255,.04);
  color: #dbeafe;
}

.menu-parent::after {
  content: "▾";
  float: none;
  margin-left: 8px;
}

.menu-item {
  background: rgba(255,255,255,.02);
}

.menu-group.single .menu-item {
  background: transparent;
}

.submenu {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  min-width: 240px;
  padding: 10px;
  border-radius: 14px;
  background: #0b1220;
  box-shadow: 0 18px 40px rgba(2,6,23,.35);
  border: 1px solid rgba(255,255,255,.10);
  z-index: 60;
}

.submenu.open {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.submenu .menu-item {
  width: 100%;
  justify-content: flex-start;
  font-size: 14px;
  padding: 10px 12px;
  background: transparent;
}

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

/* DESACTIVADO 2026-05-11: el topbar pasó a `position: fixed; top: 0` con el
   nuevo layout horizontal. Las reglas viejas `top: 112px` rompían el fixed.
.topbar {
  top: 112px;
}
*/

@media (max-width: 980px) {
  .menu {
    gap: 8px;
  }
  .menu-item,
  .menu-parent {
    font-size: 14px;
    padding: 10px 12px;
  }
}


/* v1.26 autocomplete over table */

.table-wrap-autocomplete {
  position: relative;
  overflow: visible;
  z-index: 1;
}

.table-wrap-autocomplete table,
.table-wrap-autocomplete tbody,
.table-wrap-autocomplete tr,
.table-wrap-autocomplete td,
.table-wrap-autocomplete th {
  overflow: visible;
}

.table-wrap-autocomplete td {
  position: relative;
}

.table-wrap-autocomplete .product-search-wrap {
  position: relative;
  z-index: 20;
}

.table-wrap-autocomplete .product-search-results {
  z-index: 5000;
  min-width: max(360px, 100%);
  max-width: 760px;
}

.table-wrap-autocomplete .product-search-results.show {
  display: block;
}

/* Header y filas en tablas de items de comprobantes. */
.comprobante-items-card table th {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  padding: 8px 8px;
  line-height: 1.2;
  white-space: nowrap;
}
.comprobante-items-card table td {
  padding: 6px 8px;
  font-size: 15px;
}
.comprobante-items-card table td input,
.comprobante-items-card table td select {
  font-size: 15px;
  padding: 8px 10px;
  height: 38px;
}

/* Tabla de items: layout fijo, los inputs ocupan 100% de la celda y se ven como cells. */
.comprobante-items-card table { table-layout: fixed; width: 100%; }
.comprobante-items-card td input,
.comprobante-items-card td select {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  text-overflow: ellipsis;
}
/* Celda con foco: celeste claro de fondo + borde celeste fuerte. La fila
   completa se tinta levemente para que sea obvio en qué renglón estás
   trabajando. */
.comprobante-items-card td input:focus,
.comprobante-items-card td select:focus {
  background: #dbeafe;
  border-color: #2563eb;
  box-shadow: 0 0 0 1px #2563eb inset;
  outline: none;
}
.comprobante-items-card tbody tr:has(.input:focus) {
  background: #eff6ff;
}
.comprobante-items-card tbody tr:has(.input:focus) td {
  background: transparent;
}
.comprobante-items-card tbody tr:has(.input:focus) td:has(.input:focus) {
  background: #dbeafe;
}
.comprobante-items-card td:has(input[data-field="codigo"]) { width: 22%; }
.comprobante-items-card td:has(input[data-field="descripcion"]) { width: 36%; }
.comprobante-items-card td:has(input[data-field="cantidad"]) { width: 9%; }
.comprobante-items-card td:has(input[data-field="precio_unitario"]) { width: 11%; }
.comprobante-items-card td:has(input[data-field="descuento_porcentaje"]),
.comprobante-items-card td:has(input[data-field="descuento"]) { width: 8%; }
.comprobante-items-card td input[data-field="cantidad"],
.comprobante-items-card td input[data-field="precio_unitario"],
.comprobante-items-card td input[data-field="descuento_porcentaje"],
.comprobante-items-card td input[data-field="descuento"] { text-align: right; }

/* Sacar las flechitas (spinners) de los inputs numéricos de comprobantes:
   cantidad, precio, descuento de línea, descuento general, plazo, tributos.
   Solo se modifican tipeando, sin botoncitos arriba/abajo. */
.comprobante-modal-overlay input[type="number"]::-webkit-outer-spin-button,
.comprobante-modal-overlay input[type="number"]::-webkit-inner-spin-button,
.comprobante-items-card input[type="number"]::-webkit-outer-spin-button,
.comprobante-items-card input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.comprobante-modal-overlay input[type="number"],
.comprobante-items-card input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
.comprobante-items-card td .line-subtotal { white-space: nowrap; display: block; text-align: right; }
.comprobante-items-card td:last-child { width: 44px; text-align: center; }
.comprobante-items-card td:last-child .btn { padding: 4px 8px; font-size: 12px; }

/* Auto-shrink: si el contenido no entra, el JS marca con .desc-shrink y reducimos fuente. */
.comprobante-items-card td input[data-field="descripcion"].desc-shrink,
.comprobante-items-card td input[data-field="codigo"].desc-shrink { font-size: 12px; letter-spacing: -0.2px; }
.comprobante-items-card td input[data-field="descripcion"].desc-shrink-2,
.comprobante-items-card td input[data-field="codigo"].desc-shrink-2 { font-size: 11px; letter-spacing: -0.3px; }

/* Listado de artículos — wrapper específico para que el scroll y sticky no afecten otras tablas. */
.table-articulos-wrap {
  width: 100%;
  overflow-x: auto;
  overflow-y: auto;
  max-height: calc(100vh - 280px);
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  background: #fff;
}

/* Tabla de resultados de informe — comparte el comportamiento sticky del
   listado de artículos: scroll vertical interno + thead pegado al tope.
   Mismo cálculo de max-height para que el header del informe quede visible
   mientras scrolleás resultados largos. */
.table-informe-wrap {
  width: 100%;
  overflow-x: auto;
  overflow-y: auto;
  max-height: calc(100vh - 280px);
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  background: #fff;
}
.table-informe-wrap table {
  border-collapse: collapse;
  width: 100%;
}
.table-informe-wrap thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  background: #f8fafc;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2px;
  text-transform: uppercase;
  text-align: left;
  padding: 8px 10px;
  box-shadow: 0 1px 0 #e2e8f0;
  white-space: nowrap;
}
.table-informe-wrap tbody td {
  padding: 6px 10px;
  font-size: 13px;
  line-height: 1.25;
  border-bottom: 1px solid #eef2f7;
  white-space: nowrap;
}
.table-informe-wrap tbody tr:hover { background: #f1f5f9; }
.table-informe-wrap tfoot td {
  position: sticky;
  bottom: 0;
  background: #f1f5f9;
  font-weight: 600;
  border-top: 1px solid #e2e8f0;
  padding: 8px 10px;
}
.table-articulos-wrap .product-list-table {
  table-layout: auto;
  border-collapse: collapse;
  /* No fuerzo width:100% para que la tabla pueda exceder y aparezca el scroll horizontal. */
}
.product-list-table th,
.product-list-table td {
  white-space: nowrap;
  padding: 6px 10px;
  font-size: 13px;
  line-height: 1.25;
  border-bottom: 1px solid #eef2f7;
  vertical-align: middle;
}
.product-list-table th {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2px;
  text-transform: uppercase;
  text-align: left;
  background: #f8fafc;
  position: sticky;
  top: 0;
  z-index: 2;
  box-shadow: 0 1px 0 #e2e8f0;
}
.product-list-table tbody tr:hover { background: #f1f5f9; }
/* F1 listado unificado (2026-06-14): header ordenable por columna. */
th.th-sortable { cursor: pointer; user-select: none; white-space: nowrap; }
th.th-sortable:hover { background: #eef2f7; }
th.th-sorted { color: var(--color-primary, #1f4e8c); background: #eef4fb; }
/* COLS-ORD (2026-08-06): feedback al arrastrar columnas por el encabezado */
th.th-col-dragging { opacity: .45; }
th.th-col-drag-over { background: #eef2ff; box-shadow: inset 3px 0 0 var(--primary, #2563eb); }
/* Filtros compactos de listado: menos alto vertical → más filas a la vista. */
h3.listado-buscar-titulo { margin: 0 0 3px; font-size: 12.5px; }
.listado-filtros.form-grid { gap: 4px 10px; margin-bottom: 4px; }
.listado-filtros .field { margin-bottom: 0; }
.listado-filtros .field label,
.listado-filtros .field > label { margin-bottom: 1px; font-size: 11px; font-weight: 600; }
.listado-filtros .input,
.listado-filtros select,
.listado-filtros input[type="date"] { padding-top: 4px; padding-bottom: 4px; font-size: 13px; }
/* Buscador unificado: ícono 🔍 + botón limpiar (×). */
.buscador-wrap { position: relative; display: block; }
.buscador-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); font-size: 12px; opacity: .5; pointer-events: none; line-height: 1; }
.buscador-input.input { padding-right: 30px !important; text-indent: 0; }
.buscador-clear { position: absolute; right: 5px; top: 50%; transform: translateY(-50%); border: 0; background: transparent; color: #6b7280; font-size: 17px; line-height: 1; cursor: pointer; padding: 1px 6px; border-radius: 6px; }
.buscador-clear:hover { background: #eef2f7; color: #111; }
.buscador-clear[hidden] { display: none; }
/* A+B 2026-05-14: matchea el #bae6fd genérico de .cliente-row-selected
   para que el highlight sea uniforme en todos los listados. */
.product-list-table tbody tr.cliente-row-selected { background: #bae6fd; }
/* Anchos mínimos por columna: legibles, sin apretar contenido. */
/* Bug fix 2026-05-17 (post-V1): columna del checkbox de selección masiva.
   Antes el <th> tenía width:36px inline pero los <td> no, y al no tener
   data-col ninguna regla específica la limitaba → en viewports anchos se
   expandía absorbiendo espacio sobrante. Ahora width/min/max:36px en ambos
   th y td vía data-col="check", con padding lateral reducido. */
/* 2026-05-17 post-V1 (sugerencia Martín "ponelo a la derecha y listo"):
   el checkbox de selección masiva se MOVIÓ al final del <tr>. Así la
   primera columna pasa a ser una con texto (que naturalmente no se
   expande) y el checkbox al final ocupa solo 36px sin importar viewport.
   La regla específica del data-col="check" con !important se mantiene
   como red de seguridad. */
.product-list-table th[data-col="check"],
.product-list-table td[data-col="check"] {
  width: 36px !important;
  min-width: 36px !important;
  max-width: 36px !important;
  text-align: center !important;
  padding: 6px 4px !important;
}
.product-list-table td[data-col="check"] input[type="checkbox"] {
  width: 14px;
  height: 14px;
  margin: 0;
  vertical-align: middle;
}
.product-list-table th[data-col="modificado"],   .product-list-table td[data-col="modificado"]   { min-width: 95px; }
/* Columna Código / SKU — 2026-05-28 (iter 3): el max-width sobre <td> no
   funciona con table-layout:auto. La columna se ancha al contenido.
   Solución: el render envuelve el código en <span class="sku-clip"> y el
   ellipsis se aplica al span (block con max-width propio). El td se mantiene
   con min-width corto para que no quede demasiado estrecho cuando no hay
   contenido. Diagnóstico del user con DOM inspector — gracias 🙏. */
.product-list-table th[data-col="codigo"],
.product-list-table td[data-col="codigo"] {
  min-width: 90px;
}
.product-list-table .sku-clip {
  display: inline-block;
  /* Tope a 30 chars: ≈220px en sans-serif a 13-14px (chars promedio ~7px).
     Cubre Grupo Islandia (máx 28 chars) y deja margen. Códigos descriptivos
     de Tienda Lúdica (50+ chars) quedan truncados con … y tooltip en hover. */
  max-width: 220px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}
.product-list-table th[data-col="codigo_barras"],.product-list-table td[data-col="codigo_barras"]{ min-width: 120px; }
.product-list-table th[data-col="nombre"],       .product-list-table td[data-col="nombre"]       { min-width: 240px; max-width: 420px; overflow: hidden; text-overflow: ellipsis; text-align: left; padding-left: 12px; }
.product-list-table th[data-col="tipo"],         .product-list-table td[data-col="tipo"]         { min-width: 80px; }
.product-list-table th[data-col="categoria"],    .product-list-table td[data-col="categoria"]    { min-width: 110px; }
.product-list-table th[data-col="rubro"],        .product-list-table td[data-col="rubro"]        { min-width: 110px; }
.product-list-table th[data-col="marca"],        .product-list-table td[data-col="marca"]        { min-width: 110px; }
.product-list-table th[data-col="proveedor"],    .product-list-table td[data-col="proveedor"]    { min-width: 130px; }
.product-list-table th[data-col="precio"],       .product-list-table td[data-col="precio"]       { min-width: 100px; text-align: right; }
.product-list-table th[data-col="precio_neto"],  .product-list-table td[data-col="precio_neto"]  { min-width: 100px; text-align: right; }
.product-list-table th[data-col="iva_alicuota"], .product-list-table td[data-col="iva_alicuota"] { min-width: 60px; text-align: right; }
.product-list-table th[data-col="costo"],        .product-list-table td[data-col="costo"]        { min-width: 90px; text-align: right; }
.product-list-table th[data-col="stock"],        .product-list-table td[data-col="stock"]        { min-width: 70px; text-align: right; }
.product-list-table th[data-col="stock_minimo"], .product-list-table td[data-col="stock_minimo"] { min-width: 80px; text-align: right; }
/* Auto-shrink solo para nombre que no entra (el JS lo aplica). */
.product-list-table td[data-col="nombre"].name-shrink { font-size: 12px; letter-spacing: -0.2px; }
.product-list-table td[data-col="nombre"].name-shrink-2 { font-size: 11px; letter-spacing: -0.3px; }

/* === 2026-06-22: "más onda" al listado de Artículos === */
/* Código/SKU como pill monoespaciado. */
.product-list-table .prod-sku-pill {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 11.5px;
  background: #f1f5f9;
  color: #334155;
  padding: 2px 7px;
  border-radius: 6px;
  white-space: nowrap;
}
/* Nombre un toque más presente. */
.product-list-table td[data-col="nombre"] strong { font-weight: 650; color: #0f172a; }
/* Chips suaves para Categoría / Rubro / Marca / Tipo. */
.product-list-table .prod-chip {
  display: inline-block;
  font-size: 11.5px;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: 999px;
  line-height: 1.55;
  white-space: nowrap;
}
.product-list-table .prod-chip--cat   { background: #eef2ff; color: #4338ca; }
.product-list-table .prod-chip--rubro { background: #ecfeff; color: #0e7490; }
.product-list-table .prod-chip--marca { background: #fdf4ff; color: #a21caf; }
/* Precio destacado, números tabulares (alinean prolijo). */
.product-list-table .prod-precio { font-weight: 700; color: #0f172a; font-variant-numeric: tabular-nums; }
.product-list-table td[data-col="precio_neto"],
.product-list-table td[data-col="costo"] { font-variant-numeric: tabular-nums; }
/* Stock como pill con color por nivel. */
.product-list-table .prod-stock-pill {
  display: inline-block;
  min-width: 32px;
  text-align: center;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 12.5px;
}
.product-list-table .prod-stock--ok  { background: #dcfce7; color: #166534; }
.product-list-table .prod-stock--low { background: #fef3c7; color: #92400e; }
.product-list-table .prod-stock--out { background: #fee2e2; color: #b91c1c; }
/* Filas un poco más aireadas + zebra muy sutil. La fila seleccionada conserva
   su resaltado (excluida del zebra/hover para no pisar el azul). */
.product-list-table tbody tr.prod-row > td { padding-top: 7px; padding-bottom: 7px; }
.product-list-table tbody tr.prod-row:nth-child(even):not(.cliente-row-selected) { background: #fafbfc; }
.product-list-table tbody tr.prod-row:hover:not(.cliente-row-selected) { background: #eef4fc; }


/* v1.27 menu tabs estilo escritorio */
#app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.sidebar {
  width: 100%;
  height: auto;
  position: sticky;
  top: 0;
  z-index: 120;
  overflow: visible;
  padding: 0;
  background: linear-gradient(180deg, #5b5b5f 0%, #3f4146 100%);
  color: #fff;
  box-shadow: 0 10px 24px rgba(0,0,0,.18);
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 18px 6px;
  margin: 0;
  border-bottom: 1px solid rgba(255,255,255,.12);
}

.brand-icon {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  font-size: 18px;
}

.brand h1 {
  font-size: 16px;
  margin: 0;
  color: #ffffff;
}

.brand p {
  margin: 2px 0 0;
  font-size: 12px;
  color: #e5e7eb;
}

.menu {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-end;
  gap: 3px;
  padding: 6px 10px 0;
  overflow-x: auto;
  overflow-y: visible;
  background: linear-gradient(180deg, #4a4c51 0%, #3a3c41 100%);
}

.menu::-webkit-scrollbar {
  height: 7px;
}

.menu::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,.2);
  border-radius: 999px;
}

.menu-group {
  position: relative;
  flex: 0 0 auto;
}

.menu-item,
.menu-parent {
  width: auto;
  min-width: 112px;
  border: 1px solid rgba(255,255,255,.14);
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  padding: 13px 16px;
  background: linear-gradient(180deg, #5d6065 0%, #43464b 100%);
  color: #ffffff;
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08);
}

.menu-group.single .menu-item {
  background: linear-gradient(180deg, #5d6065 0%, #43464b 100%);
}

.menu-item:hover,
.menu-parent:hover,
.menu-group:has(.submenu.open) > .menu-parent,
.menu-item.active {
  background: linear-gradient(180deg, #75b5e9 0%, #4d96d2 100%);
  color: #ffffff;
}

.menu-parent::after {
  content: "▼";
  float: none;
  margin-left: 9px;
  font-size: 10px;
  opacity: .95;
}

.submenu {
  display: none;
  position: absolute;
  left: 0;
  top: calc(100% - 1px);
  min-width: 235px;
  padding: 0;
  background: linear-gradient(180deg, #6cb0e0 0%, #4b97d2 100%);
  border: 1px solid #2f5f87;
  border-radius: 0 0 8px 8px;
  box-shadow: 0 10px 18px rgba(0,0,0,.35);
  overflow: hidden;
  z-index: 160;
}

.submenu.open {
  display: block;
}

.submenu .menu-item {
  width: 100%;
  min-width: 0;
  display: block;
  text-align: left;
  border: none;
  border-top: 1px solid rgba(255,255,255,.22);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  padding: 12px 14px;
  font-size: 14px;
  font-weight: 700;
}

.submenu .menu-item:first-child {
  border-top: none;
}

.submenu .menu-item:hover,
.submenu .menu-item.active {
  background: rgba(255,255,255,.16);
}

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

/* DESACTIVADO 2026-05-11: ver explicación arriba.
.topbar {
  top: 112px;
}
*/

@media (max-width: 1100px) {
  .menu {
    padding-bottom: 6px;
  }

  .menu-item,
  .menu-parent {
    min-width: auto;
    padding: 11px 13px;
    font-size: 14px;
  }
}

/* v1.28 vendedores — badge-yellow unificado en REFORMA VISUAL A (alias arriba) */


/* v1.29 fix menú horizontal con submenús verticales */
.menu {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-end;
  gap: 3px;
  overflow-x: auto;
  overflow-y: visible;
}

.menu-group {
  position: relative;
  display: block;
  flex: 0 0 auto;
}

.menu-parent,
.menu-group.single .menu-item {
  white-space: nowrap;
}

.submenu {
  display: none;
  position: absolute;
  left: 0;
  top: calc(100% - 1px);
  min-width: 240px;
  flex-direction: column;
  align-items: stretch;
  z-index: 9999;
}

.submenu.open {
  display: flex;
}

.submenu .menu-item {
  display: block;
  width: 100%;
  min-width: 0;
  text-align: left;
  white-space: nowrap;
  margin: 0;
}

.submenu .menu-item + .menu-item {
  margin-top: 0;
}


/* v1.30 menu dropdown estilo web */
#app {
  display: block;
  min-height: 100vh;
}

.sidebar {
  width: 100%;
  height: auto;
  position: sticky;
  top: 0;
  z-index: 80;
  overflow: visible;
  padding: 0;
  background: #ffffff;
  color: var(--text);
  border-bottom: 1px solid #e5e7eb;
  box-shadow: 0 8px 24px rgba(15, 23, 42, .08);
}

.brand {
  max-width: 1380px;
  margin: 0 auto;
  padding: 16px 24px;
  border-bottom: 1px solid #eef2f7;
  color: var(--text);
}

.brand-icon {
  background: linear-gradient(135deg, #2563eb, #60a5fa);
  color: #fff;
}

.brand p {
  color: #6b7280;
}

.menu {
  max-width: 1380px;
  margin: 0 auto;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 10px;
  padding: 0 18px;
  overflow-x: auto;
  overflow-y: visible;
  background: #ffffff;
}

.menu-group,
.menu-group.single {
  position: relative;
  flex: 0 0 auto;
}

.menu-item,
.menu-parent {
  width: auto;
  min-width: 0;
  border: 0;
  border-radius: 0;
  padding: 16px 14px;
  background: transparent;
  color: #1f2937;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  position: relative;
}

.menu-parent {
  margin-top: 0;
  color: #1f2937;
}

.menu-parent::after {
  content: '▾';
  float: none;
  margin-left: 8px;
  color: #6b7280;
  font-size: 11px;
}

.menu-item:hover,
.menu-parent:hover,
.menu-item.active,
.menu-group:has(.submenu.open) > .menu-parent {
  background: transparent;
  color: #2563eb;
}

.menu-item.active::after,
.menu-parent:hover::before,
.menu-group:has(.submenu.open) > .menu-parent::before,
.menu-group.single .menu-item:hover::before,
.menu-group.single .menu-item.active::before {
  content: '';
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 0;
  height: 3px;
  background: #2563eb;
  border-radius: 999px 999px 0 0;
}

.submenu {
  display: none;
  position: absolute;
  left: 0;
  top: calc(100% + 2px);
  min-width: 260px;
  padding: 10px 0;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 0 0 14px 14px;
  box-shadow: 0 18px 40px rgba(15, 23, 42, .16);
  z-index: 9999;
}

.submenu.open {
  display: block;
}

.submenu .menu-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 12px 18px;
  color: #374151;
  font-size: 14px;
  font-weight: 500;
}

.submenu .menu-item:hover,
.submenu .menu-item.active {
  background: #eff6ff;
  color: #1d4ed8;
}

.submenu .menu-item::after,
.submenu .menu-item::before {
  display: none !important;
}

.main {
  width: 100%;
}

/* DESACTIVADO 2026-05-11: ver explicación arriba.
.topbar {
  top: 118px;
  z-index: 40;
}
*/

.view {
  max-width: 1400px;
  margin: 0 auto;
}

@media (max-width: 980px) {
  .menu {
    padding: 0 12px;
  }
}


/* v1.34 documentos comerciales */
.document-type-card {
  margin-bottom: 18px;
}

.document-type-header {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  align-items: flex-start;
  margin-bottom: 16px;
}

.document-type-header h3 {
  margin-bottom: 6px;
}

.document-type-header p {
  margin: 0;
  color: var(--muted);
}

.document-type-groups {
  display: grid;
  gap: 16px;
}

.document-type-group h4 {
  margin: 0 0 10px;
  color: #1f2937;
}

.document-type-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}

.document-type-option {
  border: 1px solid #dbe3ef;
  background: #ffffff;
  border-radius: 14px;
  padding: 14px;
  text-align: left;
  cursor: pointer;
  box-shadow: 0 8px 22px rgba(15, 23, 42, .05);
}

.document-type-option strong {
  display: block;
  color: #0f172a;
  margin-bottom: 4px;
}

.document-type-option span {
  display: block;
  color: #64748b;
  font-size: 13px;
}

.document-type-option:hover,
.document-type-option.selected {
  border-color: #2563eb;
  background: #eff6ff;
}

@media (max-width: 1100px) {
  .document-type-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}



/* v1.35 pedidos y documentos comerciales — badge-blue unificado en REFORMA VISUAL A (alias arriba) */

.document-type-option[disabled],
.document-type-option.disabled {
  opacity: .55;
  cursor: not-allowed;
}

/* Override forzado del z-index del login (otras capas usan 100000+). */
.login-screen.show {
  display: block !important;
  z-index: 999999;
}

/* Acciones secundarias del login (recuperar contraseña / soporte). */
.login-extra-actions {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid #eef2f7;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 13px;
  flex-wrap: wrap;
}
.login-extra-sep {
  color: #cbd5e1;
  font-weight: 400;
}
.login-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 0;
  color: #1d4ed8;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  padding: 6px 8px;
  border-radius: 8px;
  text-decoration: none;
  transition: background-color .12s ease, color .12s ease;
}
.login-link svg {
  flex-shrink: 0;
  opacity: .85;
}
.login-link:hover {
  color: #1e40af;
  background: #eff6ff;
}
.login-link:hover svg { opacity: 1; }

/* ==========================================================
   FIX FINAL V1.36 - MENÚ HORIZONTAL + DROPDOWN VISIBLE
   Incorporado sobre v1.35 para que no vuelva al menú vertical.
   ========================================================== */

#app {
  display: block !important;
  min-height: 100vh !important;
}

/* Barra superior completa */
.sidebar {
  width: 100% !important;
  height: auto !important;
  min-height: 0 !important;
  position: sticky !important;
  top: 0 !important;
  z-index: 10000 !important;
  overflow: visible !important;
  padding: 0 !important;
  background: #ffffff !important;
  color: #172033 !important;
  border-bottom: 1px solid #e5e7eb !important;
  box-shadow: 0 8px 24px rgba(15, 23, 42, .08) !important;
}

/* Encabezado con logo */
.brand {
  max-width: none !important;
  margin: 0 !important;
  padding: 14px 24px !important;
  border-bottom: 1px solid #eef2f7 !important;
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  color: #172033 !important;
}

.brand-icon {
  width: 44px !important;
  height: 44px !important;
  border-radius: 14px !important;
  background: linear-gradient(135deg, #2563eb, #60a5fa) !important;
  color: #ffffff !important;
  display: grid !important;
  place-items: center !important;
  font-weight: 900 !important;
}

.brand h1 {
  margin: 0 !important;
  font-size: 18px !important;
  color: #172033 !important;
}

.brand p {
  margin: 3px 0 0 !important;
  color: #6b7280 !important;
  font-size: 13px !important;
}

/* Contenedor del menú principal */
.menu {
  max-width: none !important;
  margin: 0 !important;
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 0 !important;
  padding: 0 18px !important;
  overflow-x: visible !important;
  overflow-y: visible !important;
  background: #ffffff !important;
  position: relative !important;
  z-index: 5000 !important;
}

/* Cada categoría principal queda una al lado de la otra */
.menu-group,
.menu-group.single {
  position: relative !important;
  display: inline-block !important;
  flex: 0 0 auto !important;
  width: auto !important;
  min-width: 0 !important;
  overflow: visible !important;
}

/* Botones principales */
.menu-item,
.menu-parent {
  width: auto !important;
  min-width: 0 !important;
  max-width: none !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  border: 0 !important;
  border-radius: 0 !important;
  margin: 0 !important;
  padding: 16px 13px !important;
  background: transparent !important;
  color: #1f2937 !important;
  font-size: 15px !important;
  font-weight: 600 !important;
  line-height: 1 !important;
  white-space: nowrap !important;
  cursor: pointer !important;
  position: relative !important;
  text-align: center !important;
  box-shadow: none !important;
}

.menu-parent {
  margin-top: 0 !important;
}

/* Flechita de desplegable */
.menu-parent::after {
  content: "▾" !important;
  display: inline-block !important;
  float: none !important;
  margin-left: 8px !important;
  color: #6b7280 !important;
  font-size: 11px !important;
  opacity: 1 !important;
}

/* Hover / activo */
.menu-item:hover,
.menu-parent:hover,
.menu-item.active,
.menu-group:has(.submenu.open) > .menu-parent {
  background: transparent !important;
  color: #2563eb !important;
}

/* Línea inferior azul */
.menu-group.single .menu-item:hover::before,
.menu-group.single .menu-item.active::before,
.menu-parent:hover::before,
.menu-group:has(.submenu.open) > .menu-parent::before {
  content: "" !important;
  position: absolute !important;
  left: 12px !important;
  right: 12px !important;
  bottom: 0 !important;
  height: 3px !important;
  background: #2563eb !important;
  border-radius: 999px 999px 0 0 !important;
}

/* Dropdown visible por click y por hover */
.menu-group:hover > .submenu,
.submenu.open {
  display: block !important;
}

/* Dropdown */
.submenu {
  display: none !important;
  position: absolute !important;
  left: 0 !important;
  top: calc(100% + 1px) !important;
  min-width: 255px !important;
  width: max-content !important;
  max-width: 380px !important;
  padding: 8px 0 !important;
  background: #ffffff !important;
  border: 1px solid #dbe3ef !important;
  border-radius: 0 0 14px 14px !important;
  box-shadow: 0 18px 40px rgba(15, 23, 42, .22) !important;
  z-index: 999999 !important;
  overflow: visible !important;
}

/* 2026-06-14: pestañas pegadas al borde derecho (ej. Contabilidad). Su
   submenú abriría hacia la derecha y se cortaría contra el borde de la
   pantalla. ajustarSubmenusOverflow() detecta el desborde por geometría y
   marca el grupo; acá lo anclamos a la derecha para que abra hacia la
   izquierda y entre completo. */
.menu-group.submenu-overflow-right > .submenu {
  left: auto !important;
  right: 0 !important;
}

/* Opciones internas una debajo de otra.
   2026-05-24 hotfix TL (v2): el !important del display pisaba el filtro JS
   que ocultaba ítems por servicio/permiso. El intento previo con
   :not([style*="display: none"]) tuvo efecto colateral: items con
   display:none igualmente caían fuera del selector y perdían TODOS los
   estilos visuales (color, padding, text-align), quedando visibles con
   apariencia rota (azul + centrados desde reglas heredadas).
   Nueva estrategia: clase explícita `.menu-item-hidden` aplicada por el JS,
   con regla específica más abajo. El selector vuelve a aplicar TODOS los
   estilos a CUALQUIER .submenu .menu-item; el ocultamiento se logra con
   la clase .menu-item-hidden + !important más adelante. */
.submenu .menu-item {
  display: block !important;
  width: 100% !important;
  min-width: 255px !important;
  text-align: left !important;
  justify-content: flex-start !important;
  padding: 13px 18px !important;
  color: #374151 !important;
  background: #ffffff !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  line-height: 1.2 !important;
  white-space: nowrap !important;
}
/* 2026-05-24 hotfix TL: cuando aplicarBloqueosSeccionesMenu detecta un
   servicio deshabilitado / sección bloqueada / permiso faltante, agrega
   esta clase al menu-item. Vence al display:block !important de arriba
   por orden + especificidad equivalente + !important. */
.menu-item.menu-item-hidden,
.menu-group.menu-group-hidden,
.sidebar .menu-item.menu-item-hidden,
.sidebar .menu-group.menu-group-hidden {
  display: none !important;
}

/* Hover en opciones del dropdown */
.submenu .menu-item:hover,
.submenu .menu-item.active {
  background: #eff6ff !important;
  color: #1d4ed8 !important;
}

/* Evita líneas decorativas dentro del dropdown */
.submenu .menu-item::before,
.submenu .menu-item::after {
  display: none !important;
  content: none !important;
}

/* Contenido principal */
.main {
  width: 100% !important;
  min-width: 0 !important;
}

/* DESACTIVADO 2026-05-11: esta regla con `position: sticky !important` y
   `top: 116px !important` era la principal culpable de que el topbar nuevo
   (que debe estar fixed top:0 sobre el menu horizontal) quedara "flotante"
   y bajara con el scroll. La sustituye el bloque #app > .topbar de más abajo.
.topbar {
  position: sticky !important;
  top: 116px !important;
  z-index: 20 !important;
}
*/

/* Vista centrada */
.view {
  max-width: 1440px !important;
  margin: 0 auto !important;
}

/* Responsive */
@media (min-width: 769px) and (max-width: 1100px) {
  .sidebar {
    position: static !important;
  }

  .brand {
    padding: 12px 16px !important;
  }

  .menu {
    padding: 0 10px !important;
    overflow-x: auto !important;
  }

  .menu-item,
  .menu-parent {
    padding: 14px 12px !important;
    font-size: 14px !important;
  }

  .topbar {
    top: 0 !important;
  }
}


/* v1.37 selector resumido de documentos comerciales */
.document-type-card-compact {
  margin-top: 4px;
}

.document-type-grid-compact {
  grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
}

.document-type-card-compact .document-type-option {
  min-height: 88px;
}

@media (max-width: 1100px) {
  .document-type-grid-compact {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}



/* Badge BCRA — aparece en el editor de venta cuando el cliente
   tiene situación BCRA > 1 o cheques rechazados. */
.bcra-warning-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 10px;
  background: #dc2626;
  color: #ffffff;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .3px;
  vertical-align: middle;
  box-shadow: 0 0 0 2px #fee2e2;
  animation: bcra-pulse 1.6s ease-in-out infinite;
}

@keyframes bcra-pulse {
  0%, 100% { box-shadow: 0 0 0 2px #fee2e2; }
  50% { box-shadow: 0 0 0 4px #fecaca; }
}

/* v1.38 fix buscador de productos sobre documentos */
.product-search-wrap {
  position: relative !important;
  z-index: 60 !important;
}

.product-search-results {
  position: absolute !important;
  top: calc(100% + 6px) !important;
  left: 0 !important;
  right: auto !important;
  min-width: max(360px, 100%) !important;
  max-width: 720px !important;
  max-height: 320px !important;
  overflow-y: auto !important;
  z-index: 999999 !important;
  background: #ffffff !important;
  border: 1px solid #dbe3ef !important;
  border-radius: 14px !important;
  box-shadow: 0 18px 40px rgba(15, 23, 42, .18) !important;
}

.product-search-results.show {
  display: block !important;
}

/* A+B 2026-05-15 — fix scroll/paginación listados is-listado:
   excluimos .list-sticky-wrap (familia A) porque comparte el mismo div
   con .table-wrap y necesita overflow:auto para scroll horizontal +
   confinar la tabla dentro del wrap (sino la paginación queda abajo
   del overflow visible y no se ve). El wrap interno (tbody/tr/td)
   también debe respetar el clip del wrap is-listado. */
.table-wrap:not(.list-sticky-wrap),
.table-wrap:not(.list-sticky-wrap) table,
.table-wrap:not(.list-sticky-wrap) tbody,
.table-wrap:not(.list-sticky-wrap) tr,
.table-wrap:not(.list-sticky-wrap) td {
  overflow: visible !important;
}


/* v1.58 — La "fila azul de pestañas internas de navegación" (contenedor
 * `.open-tabs` y la regla `.tab-close`) fue removida el 2026-05-10 a
 * pedido del usuario. Cada sección abre ahora en una pestaña real del
 * navegador (window.open), aprovechando el deep-link via hash.
 *
 * **No removemos** la clase `.open-tab` porque varios listados internos
 * la siguen usando como "estilo de tab azul" para sus sub-pestañas
 * (ej. el switcher de tipo de documento en Documentos de Ventas y de
 * Compras: `#ventas-tabs-grupo`, `#compras-tabs-grupo`, `.rec-tabs`).
 * Ese estilo se mantiene tal cual estaba antes del refactor. */
.open-tab {
  position: relative !important;
  border: none !important;
  background: #c4cad4 !important;
  border-radius: 10px 10px 0 0 !important;
  padding: 9px 14px 10px 14px !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  color: #475569 !important;
  white-space: nowrap !important;
  cursor: pointer !important;
  margin-bottom: 0 !important;
  max-width: 240px !important;
  min-width: 110px !important;
  transition: background .15s ease, color .15s ease !important;
}

.open-tab:hover {
  background: #d2d7e0 !important;
  color: #1e293b !important;
}

.open-tab.active {
  background: #1e3a8a !important;
  color: #ffffff !important;
  box-shadow: 0 -2px 0 #1e3a8a inset, 0 -1px 8px rgba(30,58,138,0.25) !important;
  z-index: 2 !important;
}

.open-tab.active:hover {
  background: #1e40af !important;
  color: #ffffff !important;
}


/* v1.39 validación CUIT único */
.input.duplicated-cuit {
  border-color: #dc2626 !important;
  background: #fff1f2 !important;
}


/* v1.40 buscador de productos flotante en documentos */
.product-floating-results {
  display: none;
  max-height: 340px;
  overflow-y: auto;
  background: #ffffff;
  border: 1px solid #dbe3ef;
  border-radius: 16px;
  box-shadow: 0 22px 60px rgba(15, 23, 42, .24);
  padding: 6px;
}

.product-floating-results.show {
  display: block !important;
}

.product-floating-results .product-search-result {
  width: 100%;
  text-align: left;
  border: 0;
  border-radius: 12px;
  background: white;
  padding: 11px 13px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: #0f172a;
}

.product-floating-results .product-search-result:hover {
  background: #eff6ff;
}

.product-floating-results .product-search-result span {
  color: #64748b;
  font-size: 12px;
}


/* v1.41 cancelar documento / confirmar salida */
/* 2026-05-15 (spec final Martín): franja "Documento seleccionado..."
   ELIMINADA del HTML (los 3 callsites: venta, compra, NC compra).
   Botón nuevo .doc-back-btn-floating reemplaza la "X" — es un
   botón discreto "← Cambiar tipo" arriba a la derecha del body,
   delicado y poco invasivo. Pedido Martín: 'hay una cruz para volver
   a la pantalla de elegir comprobante hacela un botón para volver
   atrás y que este a la derecha arriba pero delicadamente'. */
.doc-back-btn-floating {
  position: absolute;
  top: 10px;
  right: 50px; /* deja espacio para el botón × de cerrar pestaña a su derecha */
  border: 1px solid rgba(15, 23, 42, .12);
  border-radius: 6px;
  background: rgba(255, 255, 255, .9);
  color: #475569;
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  padding: 5px 10px;
  cursor: pointer;
  z-index: 6;
  transition: background .15s, color .15s, border-color .15s;
}
.doc-back-btn-floating:hover {
  background: #fff;
  color: #0f172a;
  border-color: rgba(15, 23, 42, .25);
}


/* v1.42 líneas libres + buscador de producto */
.product-search-wrap .small-help {
  font-size: 11px;
  color: #64748b;
  margin-top: 4px;
}

.product-floating-results {
  display: none;
  max-height: 360px;
  overflow-y: auto;
  background: #ffffff;
  border: 1px solid #dbe3ef;
  border-radius: 16px;
  box-shadow: 0 22px 60px rgba(15, 23, 42, .28);
  padding: 6px;
  z-index: 99999999 !important;
}

.product-floating-results.show {
  display: block !important;
}

.product-floating-results .product-search-result {
  width: 100%;
  text-align: left;
  border: 0;
  border-radius: 12px;
  background: #ffffff;
  padding: 11px 13px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: #0f172a;
}

.product-floating-results .product-search-result:hover {
  background: #eff6ff;
}

.product-floating-results .product-search-result span {
  color: #64748b;
  font-size: 12px;
}


/* v1.44 selección de producto confiable */
.product-floating-result {
  user-select: none;
  pointer-events: auto !important;
}

.product-floating-result strong,
.product-floating-result span {
  pointer-events: none;
}

.product-floating-results {
  pointer-events: auto !important;
}


/* v1.45 producto seleccionable + botón usar producto */
.product-floating-result {
  cursor: pointer !important;
}

.product-floating-result em {
  margin-top: 4px;
  color: #2563eb;
  font-style: normal;
  font-weight: 800;
  font-size: 12px;
}

.product-search-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
}

.btn-mini {
  padding: 6px 9px !important;
  font-size: 12px !important;
  border-radius: 10px !important;
}


/* v1.46 selector inline de productos: sin datalist ni desplegable duplicado */
.product-search-wrap {
  position: relative !important;
}

.inline-product-results {
  display: none;
  position: absolute;
  left: 0;
  top: calc(100% + 4px);
  width: min(560px, 82vw);
  z-index: 999999;
  background: #ffffff;
  border: 1px solid #dbe3ef;
  border-radius: 14px;
  box-shadow: 0 18px 42px rgba(15, 23, 42, .20);
  padding: 8px;
}

.inline-product-results.show {
  display: block !important;
}

.product-inline-select {
  width: 100%;
  border: 0;
  outline: none;
  background: #ffffff;
  font-size: 14px;
}

.product-inline-select option {
  padding: 9px;
}

.product-search-results:not(.inline-product-results),
.product-floating-results {
  display: none !important;
}


/* v1.47 líneas de documentos estables */
.inline-product-results {
  display: none;
  position: absolute;
  left: 0;
  top: calc(100% + 4px);
  width: min(620px, 86vw);
  max-height: 360px;
  overflow-y: auto;
  z-index: 9999999;
  background: #ffffff;
  border: 1px solid #dbe3ef;
  border-radius: 14px;
  box-shadow: 0 18px 42px rgba(15, 23, 42, .22);
  padding: 8px;
}

.inline-product-results.show {
  display: block !important;
}

.product-result-btn {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  align-items: center;
  border: 0;
  background: #ffffff;
  border-radius: 12px;
  padding: 10px 12px;
  text-align: left;
  cursor: pointer;
}

.product-result-btn:hover {
  background: #eff6ff;
}

.product-result-btn strong {
  color: #0f172a;
}

.product-result-btn span {
  color: #64748b;
  font-size: 12px;
}

.product-result-btn b {
  grid-row: 1 / span 2;
  grid-column: 2;
  color: #2563eb;
  font-size: 13px;
}

.product-search-results:not(.inline-product-results),
.product-floating-results {
  display: none !important;
}


/* v1.48 corrección total/documentos + selector directo */
.product-direct-select {
  max-width: 150px;
  border: 1px solid #dbe3ef;
  border-radius: 10px;
  padding: 6px 8px;
  background: #ffffff;
  font-size: 12px;
}

.product-search-actions {
  flex-wrap: wrap;
}

.total-box [data-total-total],
.total-box .total-row.big strong {
  color: #0f172a;
}


/* v1.49 ventas reconstruido estable */
.simple-product-cell {
  position: relative;
  min-width: 300px;
}
.inline-product-results {
  display: none;
  position: absolute;
  left: 0;
  top: calc(100% + 4px);
  width: min(620px, 86vw);
  max-height: 360px;
  overflow-y: auto;
  z-index: 9999999;
  background: #ffffff;
  border: 1px solid #dbe3ef;
  border-radius: 14px;
  box-shadow: 0 18px 42px rgba(15, 23, 42, .22);
  padding: 8px;
}
.inline-product-results.show {
  display: block !important;
}
.product-result-btn {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  align-items: center;
  border: 0;
  background: #ffffff;
  border-radius: 12px;
  padding: 10px 12px;
  text-align: left;
  cursor: pointer;
}
.product-result-btn:hover {
  background: #eff6ff;
}
.product-result-btn strong { color: #0f172a; }
.product-result-btn span { color: #64748b; font-size: 12px; }
.product-result-btn b {
  grid-row: 1 / span 2;
  grid-column: 2;
  color: #2563eb;
  font-size: 13px;
}
.product-search-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  flex-wrap: wrap;
}
.product-direct-select {
  max-width: 180px;
  border: 1px solid #dbe3ef;
  border-radius: 10px;
  padding: 6px 8px;
  background: #ffffff;
  font-size: 12px;
}

.table-wrap-autocomplete .simple-product-cell,
.compra-lines-card .simple-product-cell {
  min-width: 300px;
  max-width: 360px;
}

.table-wrap-autocomplete .inline-product-results,
.compra-lines-card .inline-product-results {
  width: 100%;
  min-width: 100%;
  max-width: 100%;
}

.compra-doc-card {
  width: 100%;
}

.lista-precio-form {
  max-width: 1180px;
  margin-left: auto;
  margin-right: auto;
}

.lista-precio-editor {
  margin-top: 14px;
}

.lista-precio-search {
  max-width: 360px;
}


/* v1.50 clientes/vendedores fix */
#venta-cliente-results,
.search-results {
  z-index: 9999999 !important;
}

#venta-cliente-results.show {
  display: block !important;
  max-height: 360px !important;
  overflow-y: auto !important;
  background: #ffffff !important;
  border: 1px solid #dbe3ef !important;
  border-radius: 14px !important;
  box-shadow: 0 18px 42px rgba(15, 23, 42, .22) !important;
}

#venta-cliente-results .search-result-item {
  width: 100%;
  text-align: left;
  border: 0;
  background: #ffffff;
  padding: 12px 14px;
  display: block;
  cursor: pointer;
}

#venta-cliente-results .search-result-item:hover {
  background: #eff6ff;
}

#venta-cliente-results .search-result-item strong {
  display: block;
}

#venta-cliente-results .search-result-item span {
  color: #64748b;
  font-size: 12px;
}


/* v1.51 vendedores y zonas */
.master-field {
  width: 100%;
}


/* v1.53 botón agregar línea abajo */
.line-actions-bottom {
  display: flex;
  align-items: center;
  gap: 12px;
  justify-content: flex-start;
  margin-top: 14px;
  margin-bottom: 10px;
}

.line-actions-bottom .btn {
  min-width: 160px;
}


/* v1.55 numeración automática */
.readonly-number,
input[readonly].readonly-number {
  background: #f8fafc;
  color: #475569;
  cursor: not-allowed;
}


/* archivos maestros */
.global-master-search {
  position: relative;
  width: min(360px, 34vw);
  min-width: 260px;
}

.global-master-search .input {
  border-radius: 999px;
  padding-left: 16px;
  padding-right: 16px;
  background: #ffffff;
}

.global-master-results {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(520px, 92vw);
  max-height: 420px;
  overflow-y: auto;
  z-index: 10000000;
  background: #ffffff;
  border: 1px solid #dbe3ef;
  border-radius: 14px;
  box-shadow: 0 18px 42px rgba(15, 23, 42, .22);
  padding: 8px;
}

.global-master-results.show {
  display: block;
}

.global-master-count,
.global-master-empty {
  padding: 8px 10px;
  color: #64748b;
  font-size: 12px;
  font-weight: 700;
}

.global-master-result {
  width: 100%;
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 3px 12px;
  align-items: center;
  border: 0;
  background: #ffffff;
  border-radius: 12px;
  padding: 10px 12px;
  text-align: left;
  cursor: pointer;
}

.global-master-result:hover {
  background: #eff6ff;
}

.global-master-result span {
  grid-row: 1 / span 2;
  color: #2563eb;
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
}

.global-master-result strong {
  color: #0f172a;
  min-width: 0;
  overflow-wrap: anywhere;
}

.global-master-result small {
  color: #64748b;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* ── Buscador global: sección headers ─────────────────────────────────────── */
.global-search-section-header {
  padding: 10px 10px 4px 10px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #94a3b8;
  border-top: 1px solid #f1f5f9;
  margin-top: 4px;
}
.global-search-section-header:first-child {
  border-top: 0;
  margin-top: 0;
}

/* ── Buscador global: conceptos expandidos ────────────────────────────────── */
.global-concepto-wrap {
  padding: 8px 12px 10px 12px;
  border-radius: 10px;
}
.global-concepto-wrap:hover {
  background: #f5f3ff;
}
.global-concepto-titulo {
  font-size: 13px;
  font-weight: 700;
  color: #0f172a;
  margin-bottom: 5px;
}
.global-concepto-cat {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #7c3aed;
  margin-top: 4px;
  margin-bottom: 2px;
}
.global-concepto-destino {
  display: inline-block;
  background: #ede9fe;
  color: #4c1d95;
  border: 0;
  border-radius: 6px;
  padding: 3px 8px;
  font-size: 12px;
  cursor: pointer;
  margin: 2px 3px 2px 0;
  transition: background .12s;
}
.global-concepto-destino:hover {
  background: #c4b5fd;
  color: #2e1065;
}
/* Concepto con 1 solo destino: render simplificado igual que global-master-result */
.global-concepto-simple span {
  color: #7c3aed;
  text-transform: none;
  font-weight: 700;
  font-size: 12px;
}

/* ── Buscador global: funciones ───────────────────────────────────────────── */
.global-funcion-result span {
  color: #16a34a;
  text-transform: uppercase;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .05em;
}

/* ── CV2 Tesorería: 2 columnas Valores | Pendientes ─────────────────────────
   Fix 2026-05-30: con TRANSFERENCIA los campos del valor son muchos (banco,
   cód operación, fecha, banco origen cliente) y la columna izquierda crecía
   libre, empujando el panel de pendientes fuera del viewport. Grid con ancho
   garantizado al panel de pendientes + overflow-x interno en valores. */
.cv2-tes-two-col-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
  gap: 12px;
  align-items: start;
}
.cv2-tes-valores-col {
  min-width: 0;
  overflow-x: auto;
}
.cv2-tes-imputaciones-col {
  min-width: 280px;
}
@media (max-width: 1100px) {
  .cv2-tes-two-col-wrap {
    grid-template-columns: 1fr;
  }
}

/* ── Toggle switch reutilizable (PWA Depósito habilitados) ────────────────── */
.toggle-switch {
  display: inline-flex;
  align-items: center;
  position: relative;
  width: 44px;
  height: 24px;
  cursor: pointer;
  user-select: none;
}
.toggle-switch input[type="checkbox"] {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
}
.toggle-slider {
  position: absolute;
  inset: 0;
  border-radius: 24px;
  background: #cbd5e1;
  transition: background .18s;
}
.toggle-slider::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0,0,0,.2);
  transition: transform .18s;
}
.toggle-switch input:checked + .toggle-slider {
  background: #2563eb;
}
.toggle-switch input:checked + .toggle-slider::before {
  transform: translateX(20px);
}
.toggle-switch input:disabled + .toggle-slider {
  opacity: .5;
  cursor: not-allowed;
}

.section-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.section-title-row h3 {
  margin: 0;
}

.confirm-dialog-backdrop {
  z-index: 10000010;
}

.confirm-dialog {
  /* 2026-05-16 Martín: ensanchar (440→640) para que avisos largos se lean mejor. */
  width: min(640px, 92vw);
  background: #ffffff;
  border: 1px solid #cbd5e1;
  border-radius: 10px;
  box-shadow: 0 28px 60px rgba(15, 23, 42, .32);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.confirm-dialog-header {
  padding: 14px 18px;
  background: #eef6ff;
  border-bottom: 1px solid #cbd5e1;
}

.confirm-dialog-header h3 {
  margin: 0;
  font-size: 17px;
  color: #0f172a;
}

.confirm-dialog-body {
  padding: 18px;
  font-size: 15px;
  color: #1f2937;
  line-height: 1.45;
}

.confirm-dialog-footer {
  padding: 12px 16px;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  border-top: 1px solid #e5e7eb;
  background: #f8fafc;
}

/* Variantes de color para appAlert (reusa la base .confirm-dialog).
   Header coloreado por tipo: error rojo, warn ámbar, ok verde, info azul. */
.app-alert-backdrop { z-index: 10000020; }
/* 2026-05-16 Martín: ensanchar app-alert (420→640) idem confirmDialog. */
.app-alert-dialog { width: min(640px, 92vw); }
.app-alert-body { white-space: pre-line; }

/* quickInputModal — mini-modal para alta inline de un campo (ej: + Nuevo
   transporte). z-index 10000025: por encima de .app-alert-backdrop (10000020)
   y de .bulk-modal-backdrop (10000001) donde vive el modal cliente. No usa
   z-index inline para evitar que CSS de clase quede pisado por specificity. */
.quick-input-modal-backdrop {
  z-index: 10000025;
}
.quick-input-dialog {
  width: min(480px, 92vw);
}
.quick-input-dialog .confirm-dialog-body {
  padding: 20px 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.quick-input-dialog .confirm-dialog-body label {
  font-size: 13px;
  font-weight: 600;
  color: #374151;
  margin: 0;
}
.quick-input-dialog .confirm-dialog-body .input {
  width: 100%;
  font-size: 15px;
  padding: 10px 12px;
  border-radius: 8px;
}
.quick-input-dialog .confirm-dialog-footer {
  padding: 12px 20px;
}
.app-alert-error .app-alert-header { background: #fee2e2; border-bottom-color: #fca5a5; }
.app-alert-error .app-alert-header h3 { color: #991b1b; }
.app-alert-warn  .app-alert-header { background: #fef3c7; border-bottom-color: #fcd34d; }
.app-alert-warn  .app-alert-header h3 { color: #92400e; }
.app-alert-ok    .app-alert-header { background: #d1fae5; border-bottom-color: #6ee7b7; }
.app-alert-ok    .app-alert-header h3 { color: #065f46; }
.app-alert-info  .app-alert-header { background: #dbeafe; border-bottom-color: #93c5fd; }
.app-alert-info  .app-alert-header h3 { color: #1e3a8a; }

.bulk-modal-backdrop {
  position: fixed;
  inset: 0;
  /* 2026-05-19 (Martín): subido de 10000001 a 10000008 para que pickers
     (cliente, producto, marca, rubro) queden encima del modal-overlay
     (10000005) cuando se abren desde un modal padre. confirm-dialog
     (10000010) sigue encima del picker. */
  z-index: 10000008;
  /* Homogeneización F3 (2026-06-17): backdrop alineado al del .app-modal (.55). */
  background: rgba(15, 23, 42, .55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  overscroll-behavior: contain;
}

.bulk-modal {
  width: min(1320px, 96vw);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border: 1px solid #93c5fd;
  /* Homogeneización F3 (2026-06-17): radio alineado al del .app-modal (14px,
     la familia dominante con 382 usos) para que las 3 familias de modales
     tengan el mismo chrome. */
  border-radius: 14px;
  box-shadow: var(--shadow-xl, 0 28px 80px rgba(15, 23, 42, .34));
  overflow: hidden;
}

.bulk-modal-header,
.bulk-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3, 12px);
  /* 2026-06-01: alineado con --modal-padding-header/footer del sistema */
  padding: var(--modal-padding-header, 14px 20px);
  background: #eef6ff;
  border-bottom: 1px solid #cbd5e1;
}
.bulk-footer { padding: var(--modal-padding-footer, 12px 20px); }

.bulk-modal-header h3 {
  margin: 0;
  font-size: var(--modal-header-font-size, 16px);
  font-weight: var(--modal-header-font-weight, 600);
}

.bulk-modal-header p {
  margin: 3px 0 0;
  color: #64748b;
  font-size: var(--font-sm, 12px);
}

.bulk-toolbar {
  display: grid;
  grid-template-columns: 1fr 180px 210px;
  gap: var(--space-2, 8px);
  /* 2026-06-01: padding alineado con modal-padding-body */
  padding: var(--modal-padding-body, 18px 20px);
  border-bottom: 1px solid var(--border, #e5e7eb);
  background: #f8fafc;
}

.bulk-table-wrap {
  overflow: auto;
  min-height: 280px;
}

.bulk-table-wrap table {
  min-width: 860px;
}

.bulk-table-wrap th {
  position: sticky;
  top: 0;
  z-index: 1;
}

.bulk-product-row:hover {
  background: #eff6ff;
}

.bulk-product-row.bulk-row-highlighted,
.bulk-product-row.bulk-row-highlighted:hover,
.bulk-cliente-row.bulk-row-highlighted,
.bulk-cliente-row.bulk-row-highlighted:hover,
tr.bulk-row-highlighted,
tr.bulk-row-highlighted:hover {
  background: #bae6fd;
  outline: 2px solid #38bdf8;
  outline-offset: -2px;
}

/* Filas de tablas listadas con navegación por flechas: clientes, proveedores
   (reusan .cliente-row), productos, ventas, compras, ofertas, listas de precios. */
.cliente-row:hover,
.venta-row:hover,
.compra-row:hover,
.prod-row:hover,
.of-row:hover,
.lp-row:hover,
.stock-rep-row:hover,
.stock-ext-row:hover { background: #f1f5f9; }
.cliente-row-selected,
.cliente-row-selected:hover {
  background: #bae6fd;
  outline: 2px solid #38bdf8;
  outline-offset: -2px;
}
.cliente-row:focus,
.venta-row:focus,
.compra-row:focus,
.prod-row:focus,
.of-row:focus,
.lp-row:focus,
.stock-rep-row:focus,
.stock-ext-row:focus { outline: 2px solid var(--primary); outline-offset: -2px; }

/* Constructor de informes (Fase 3): chips + drop zones + pivot */
.inf-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: #e0f2fe;
  color: #075985;
  border: 1px solid #bae6fd;
  border-radius: 16px;
  font-size: 12px;
  cursor: grab;
  user-select: none;
  white-space: nowrap;
}
.inf-chip:active { cursor: grabbing; }
.inf-chip.in-zone {
  background: #bae6fd;
  color: #0c4a6e;
  border-color: #38bdf8;
}
.inf-chip .inf-chip-x {
  cursor: pointer;
  opacity: 0.6;
  font-weight: 700;
  margin-left: 2px;
}
.inf-chip .inf-chip-x:hover { opacity: 1; color: #b91c1c; }
.inf-chip select {
  border: 1px solid #bae6fd;
  background: #fff;
  border-radius: 4px;
  padding: 1px 4px;
  font-size: 11px;
  margin-left: 2px;
}

.inf-pool {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px;
  border: 1px dashed #cbd5e1;
  border-radius: 6px;
  background: #f8fafc;
  min-height: 44px;
}
.inf-zone {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px;
  border: 1px dashed #94a3b8;
  border-radius: 6px;
  background: #fff;
  min-height: 44px;
  transition: background 0.15s, border-color 0.15s;
}
.inf-zone.empty::before {
  content: attr(data-empty-label);
  color: #94a3b8;
  font-size: 12px;
  font-style: italic;
  align-self: center;
}
.inf-zone.drag-over {
  background: #ecfeff;
  border-color: #06b6d4;
  border-style: solid;
}
.inf-zone-label {
  display: block;
  font-weight: 600;
  font-size: 13px;
  margin-bottom: 4px;
  color: #475569;
}

.inf-pivot-table {
  border-collapse: collapse;
  width: 100%;
}
.inf-pivot-table th, .inf-pivot-table td {
  border: 1px solid #e2e8f0;
  padding: 6px 10px;
  text-align: right;
  font-size: 13px;
}
.inf-pivot-table th { background: #f1f5f9; font-weight: 600; text-align: center; }
.inf-pivot-table th.row-header { text-align: left; background: #f8fafc; }
.inf-pivot-table td.row-header { text-align: left; font-weight: 600; background: #f8fafc; }
.inf-pivot-table .row-total td, .inf-pivot-table .row-total th { background: #e0f2fe; font-weight: 600; }
.inf-pivot-table .col-total { background: #e0f2fe; font-weight: 600; }
.inf-pivot-table .grand-total { background: #bae6fd; font-weight: 700; }

.inf-filtro-row {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
  padding: 6px 0;
}
.inf-filtro-row .input { padding: 4px 8px; font-size: 13px; }

/* Query-builder anidado And/Or (FILT-F1 2026-08-05). Grupos de condiciones
   combinadas con Y/O y subgrupos anidados, al estilo del CRM de referencia. */
.inf-filtro-grupo {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 8px 10px;
  background: #f8fafc;
}
.inf-filtro-grupo.es-root { background: transparent; border-style: dashed; }
.inf-filtro-grupo .inf-filtro-grupo { margin: 4px 0; background: #fff; }
.inf-grupo-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.inf-grupo-comb { display: inline-flex; border: 1px solid #cbd5e1; border-radius: 6px; overflow: hidden; }
.inf-comb-btn {
  border: none;
  background: #fff;
  color: #64748b;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 12px;
  cursor: pointer;
}
.inf-comb-btn + .inf-comb-btn { border-left: 1px solid #cbd5e1; }
.inf-comb-btn.active { background: var(--primary); color: #fff; }
.inf-grupo-rm { padding: 3px 10px !important; font-size: 12px !important; }
.inf-grupo-body { padding-left: 8px; border-left: 2px solid #e2e8f0; }
.inf-grupo-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
/* FILT-F4: badge de conteo del botón "Filtros avanzados" en toolbars de
   listados — misma pastilla que .listado-filtros-toggle .filtros-badge
   (styles-mobile.css), acá en versión desktop. */
.btn .filtros-badge {
  background: var(--primary);
  color: #fff;
  border-radius: 10px;
  padding: 1px 7px;
  font-size: 11px;
  font-weight: 700;
  margin-left: 4px;
}

/* Tabs internos (ej. Stock: Existencias / Movimientos) */
.inner-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid #e2e8f0;
  margin-bottom: 14px;
}
.inner-tab {
  padding: 8px 18px;
  border: none;
  background: transparent;
  cursor: pointer;
  font-size: 14px;
  color: #64748b;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.inner-tab.active {
  color: var(--primary);          /* era #0ea5e9 (sky-500), unificado a --primary 2026-05-27 */
  border-bottom-color: var(--primary);
  font-weight: 600;
}
.inner-tab:hover:not(.active) { color: #334155; }

.cliente-titulo-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  position: sticky;
  top: 0;
  background: #fff;
  z-index: 5;
  padding: 8px 0;
  border-bottom: 1px solid #eef2f7;
}
.cliente-titulo-row > h3 { margin: 0; }
.cliente-row-actions {
  margin: 0 auto;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.cliente-row-actions-empty {
  margin: 0 auto;
  color: #94a3b8;
  font-style: italic;
}

.bulk-product-check,
#bulk-select-visible {
  width: 18px;
  height: 18px;
}

.bulk-stock-danger {
  color: #dc2626;
  font-weight: 800;
}

.bulk-stock-warning {
  color: #d97706;
  font-weight: 800;
}

.bulk-footer {
  border-top: 1px solid #cbd5e1;
  border-bottom: 0;
}

#bulk-visible-count {
  color: #475569;
  font-size: 13px;
  font-weight: 800;
}

.product-editor-modal {
  /* 2026-10-05 (Martín): "ponerlo en pantalla completa como la de cuenta
     corriente" — a 1520px la tabla de Trazabilidad (Movimientos de stock)
     seguía cortando la columna Detalle. Ahora el editor de artículo ocupa TODA
     la pantalla (como la vista full de CC), para que las tablas internas entren
     y, si igual sobran, scrolleen horizontal (ver .product-editor-body .table-wrap). */
  width: 100vw;
  max-width: 100vw;
  height: 100vh;
  max-height: 100vh;
  border-radius: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* 2026-06-17 (Martín): el editor de cliente/proveedor (master) necesita MÁS ANCHO para
   que entre la tabla de Cuenta Corriente (muchas columnas) sin scroll horizontal molesto.
   Los demás product-editor (productos) quedan en 1100px. */
.master-editor-modal { max-width: min(1520px, 97vw) !important; }

/* 2026-10-05: pantalla completa → sin padding en el backdrop (el modal ocupa
   todo el viewport, como la vista full de cuenta corriente). */
.bulk-modal-backdrop.product-editor-backdrop {
  padding: 0;
  box-sizing: border-box;
}

/* Header de modales de maestros (clientes/proveedores/artículos) — alineado
   con el modal de Nueva Venta (header azul brand con texto blanco y botón
   cerrar blanco). Acordado 2026-05-09. Override sobre .bulk-modal-header
   genérico (que es claro).
   Fix 2026-05-25: usar var(--primary-deep) en lugar de #1e3a8a hardcodeado
   para que el header respete el tema de color activo del usuario. */
.product-editor-modal .product-editor-header,
.product-editor-modal .bulk-modal-header {
  background: var(--primary-deep, #1e3a8a);
  color: #fff;
  border-bottom: 0;
  padding: 12px 18px;
  flex-shrink: 0;
  transition: background 0.2s ease;
}
/* En modo edición activo el header usa --primary-dark (tono más brillante)
   para indicar visualmente que el modal es editable.
   El data-modo-lectura vive en el backdrop (.bulk-modal-backdrop), que es
   padre del .product-editor-modal — por eso el selector empieza desde ahí. */
[data-modo-lectura="0"] .product-editor-header,
[data-modo-lectura="0"] .product-editor-modal .bulk-modal-header {
  background: var(--primary-dark, #1e40af);
}
.product-editor-modal .product-editor-header h3,
.product-editor-modal .bulk-modal-header h3 {
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  margin: 0;
}
.product-editor-modal .product-editor-header p,
.product-editor-modal .bulk-modal-header p {
  color: rgba(255, 255, 255, .82);
  font-size: 12px;
  margin: 3px 0 0;
}
.product-editor-modal .product-editor-header .btn-light,
.product-editor-modal .bulk-modal-header .btn-light {
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, .35);
}
.product-editor-modal .product-editor-header .btn-light:hover,
.product-editor-modal .bulk-modal-header .btn-light:hover {
  background: rgba(255, 255, 255, .15);
  border-color: rgba(255, 255, 255, .55);
}

/* Tabs sobre fondo claro (pedido usuario 2026-05-09: que las pestañas NO
   estén dentro de la franja superior azul). Quedan en banda blanca debajo
   del header con la pestaña activa marcada por borde inferior azul brand
   en lugar de fondo. */
.product-modal-tabs {
  display: flex;
  gap: 4px;
  padding: 0 16px;
  background: #ffffff;
  border-bottom: 1px solid #e2e8f0;
  /* 2026-05-21 fix: pasar de flex-wrap (apilaba tabs en 2 filas) a scroll
     horizontal — más prolijo cuando hay muchas pestañas. */
  flex-wrap: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  flex-shrink: 0;
}
.product-modal-tabs button {
  flex-shrink: 0;
  white-space: nowrap;
}

.product-modal-tab {
  border: 0;
  background: transparent;
  color: #475569;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  padding: 10px 14px;
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  position: relative;
  top: 1px;
  border-bottom: 2px solid transparent;
  transition: color var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast);
}

.product-modal-tab:hover {
  color: #1e3a8a;
  background: #f1f5f9;
}

.product-modal-tab.active {
  background: transparent;
  color: #1e3a8a;
  font-weight: 700;
  border-bottom: 2px solid #1e3a8a;
}

.product-editor-body {
  overflow: auto;
  padding: 16px;
  background: #ffffff;
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
/* 2026-10-05 (Martín): las tablas anchas del editor (Trazabilidad / Movimientos
   de stock, Costos·compras) deben SCROLLEAR horizontal dentro de su .table-wrap,
   no cortarse en el borde. En el body flex-column las secciones necesitan
   min-width:0 para poder encogerse y que el overflow-x del wrap tome efecto. */
.product-editor-body > *,
.product-editor-body .product-editor-section { min-width: 0; max-width: 100%; }
.product-editor-body .table-wrap { max-width: 100%; overflow-x: auto; }

/* 2026-05-21 fix: forzar grid de 3 cols responsive en el editor de productos
   en lugar del default que renderiza 4 cols de px fijo y desborda el modal. */
.product-editor-body .form-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px 16px;
  align-items: start;
}
.product-editor-body .form-grid .field {
  min-width: 0;
}
.product-editor-body .form-grid .field[style*="grid-column"] {
  grid-column: 1 / -1;
}

.product-editor-section,
.product-analysis-section {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: #ffffff;
  padding: 14px;
}

.product-editor-notice {
  margin-bottom: 12px;
}

.product-editor-panels,
.product-analysis-columns {
  margin-top: 14px;
}

.product-editor-panel {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: #f8fafc;
  padding: 14px;
}

.product-editor-panel h3,
.product-analysis-section h3 {
  margin: 0 0 12px;
  font-size: 16px;
}

.product-editor-actions {
  justify-content: flex-end;
  margin-top: 18px;
  position: sticky;
  bottom: -16px;
  background: #ffffff;
  border-top: 1px solid #e2e8f0;
  padding: 12px 0 0;
}

.product-analysis-empty {
  border: 1px dashed #cbd5e1;
  border-radius: 8px;
  padding: 28px;
  text-align: center;
  color: #64748b;
  font-weight: 800;
  background: #f8fafc;
}

/* 2026-06-07 — Cross-selling (editor de producto). El feature se shippeó sin
   CSS propio: el dropdown de búsqueda y las cards de vinculados se veían sin
   estilo ("el contenedor estaba mal"). Sigue la misma paleta del editor
   (#e2e8f0 / radius 8px / #f8fafc) que las demás pestañas (ej. Precio por lista). */
#cs-search-area {
  position: relative;
}
.cs-search-dropdown {
  margin-top: 6px;
  max-width: 460px;
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: #ffffff;
}
.cs-search-dropdown:empty {
  display: none;
}
.cs-search-item {
  display: grid;
  grid-template-columns: 130px 1fr auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  border-bottom: 1px solid #f1f5f9;
  background: #ffffff;
  text-align: left;
  cursor: pointer;
  font-size: 13px;
}
.cs-search-item:last-child {
  border-bottom: 0;
}
.cs-search-item:hover {
  background: #f1f5f9;
}
.cs-search-codigo {
  color: #64748b;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cs-search-nombre {
  color: #0f172a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cs-search-precio {
  color: #0f172a;
  font-weight: 800;
  white-space: nowrap;
  justify-self: end;
}
.cs-search-loading {
  padding: 12px;
  color: #64748b;
  font-size: 13px;
}

.cs-cards-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
}
.cs-card {
  display: flex;
  align-items: center;
  gap: 10px;
  position: relative;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: #f8fafc;
  padding: 8px 10px;
}
.cs-card-thumb {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid #e2e8f0;
  background: #fff;
}
.cs-card-no-foto {
  background: #e2e8f0;
}
.cs-card-info {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}
.cs-card-codigo {
  color: #64748b;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cs-card-nombre {
  color: #0f172a;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cs-card-precio {
  color: #0f172a;
  font-size: 13px;
  font-weight: 800;
}
.cs-card-remove {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border: 0;
  border-radius: 6px;
  background: #fee2e2;
  color: #b91c1c;
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
}
.cs-card-remove:hover {
  background: #fecaca;
}

.product-analysis-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(150px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.product-analysis-kpi {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: #f8fafc;
  padding: 12px;
  min-height: 104px;
}

.product-analysis-kpi span,
.product-analysis-kpi small {
  display: block;
  color: #64748b;
  font-size: 12px;
  font-weight: 800;
}

.product-analysis-kpi strong {
  display: block;
  margin: 7px 0 5px;
  color: #0f172a;
  font-size: 17px;
  overflow-wrap: anywhere;
}

.product-cost-chart {
  height: 190px;
  display: grid;
  grid-template-columns: repeat(12, minmax(44px, 1fr));
  gap: 8px;
  align-items: end;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: #f8fafc;
  padding: 12px;
  overflow-x: auto;
}

.product-cost-point {
  min-width: 44px;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
}

.product-cost-point span {
  font-size: 11px;
  color: #475569;
  font-weight: 800;
  white-space: nowrap;
}

.product-cost-bar {
  width: 100%;
  min-height: 12px;
  border-radius: 6px 6px 0 0;
  background: linear-gradient(180deg, #60a5fa, #2563eb);
}

.product-cost-point small {
  font-size: 11px;
  color: #64748b;
  font-weight: 800;
}

.product-analysis-lines {
  display: grid;
  gap: 9px;
}

.product-analysis-lines div {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  border-bottom: 1px solid #e2e8f0;
  padding-bottom: 9px;
}

.product-analysis-lines div:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.product-analysis-lines span {
  color: #64748b;
  font-weight: 800;
}

.product-analysis-lines strong {
  text-align: right;
  color: #0f172a;
}

.table-wrap.product-analysis-table {
  overflow-x: auto !important;
}

.table-wrap.product-analysis-table table {
  min-width: 760px !important;
}

.master-editor-card {
  overflow: hidden;
}

.master-editor-tabs {
  margin: 12px -16px 14px;
}

.master-editor-panel {
  padding-top: 2px;
}

.master-editor-modal .master-code-kpi {
  width: min(260px, 100%);
  min-height: auto;
  margin-bottom: 12px;
}

.cliente-editor-general {
  border-bottom: 1px solid #e5e7eb;
  padding-bottom: 10px;
  margin-bottom: 8px;
}

.cliente-general-grid {
  grid-template-columns: minmax(160px, 220px) 1fr;
  align-items: start;
}

.cliente-general-obs textarea {
  min-height: 56px;
  resize: vertical;
}

.cliente-general-grid .field[data-master-field="activo"] select {
  font-weight: 600;
}

.client-account-grid {
  grid-template-columns: repeat(5, minmax(150px, 1fr));
}

/* CC-ANCHO (2026-06-02): el min-width original causaba scroll horizontal
   en el modal CC. Movido a la sección CC-ANCHO más abajo que usa
   table-layout:fixed + anchos por columna para controlar el espacio. */

/* 2026-06-01: fix conflicto de specificity en tablas sortables dentro de
   .table-wrap. Diagnóstico del user (con DevTools en producción):
   - L5404 `.table-wrap:not(.list-sticky-wrap) table { table-layout:fixed }`
     forzaba anchos chicos y comprimía las columnas numéricas.
   - L5436 `.table-wrap:not(.list-sticky-wrap) td { overflow-wrap:anywhere }`
     daba permiso al browser para cortar el número en cualquier carácter
     (incl. en medio de un import como "$ 100.000.000," / "00") cuando
     no entraba en el ancho fijo.
   Selector apuntado a table.sortable-table — specificity 0,0,3,2 gana
   contra la legacy (0,0,2,1) sin recurrir a hacks ni inline-style. */
.table-wrap:not(.list-sticky-wrap) table.sortable-table {
  table-layout: auto !important;
}
.table-wrap:not(.list-sticky-wrap) table.sortable-table th,
.table-wrap:not(.list-sticky-wrap) table.sortable-table td {
  white-space: nowrap !important;
  overflow-wrap: normal !important;
  word-wrap: normal !important;
  word-break: normal !important;
}

.cc-access-table .actions {
  white-space: nowrap;
}

/* Columna checkbox de selección (Mejora B) */
.cc-access-table .cc-sel-cell {
  width: 32px;
  text-align: center;
  padding: 4px 6px;
}
.cc-access-table .cc-sel-check {
  cursor: pointer;
  width: 15px;
  height: 15px;
  accent-color: var(--primary, #2c6ef2);
}

/* Columna Estado (Mejora A) */
.cc-access-table .cc-estado-cell {
  text-align: center;
  white-space: nowrap;
}

/* 2026-06-17 (Martín): la tabla CC del modal (ccDetalleTable) NO usa .sortable-table,
   así que sin estas reglas la descripción (apertura MERNET, multi-línea) se montaba con
   los montos. Mismo criterio que las demás tablas CC: NOWRAP en todas las celdas +
   scroll horizontal (cada celda se dimensiona a su contenido, no se solapan). Los montos
   alineados a la derecha; la descripción multi-línea mantiene sus saltos propios (<div>)
   pero cada línea no envuelve. Todo alineado arriba. */
/* CLAVE: la regla general `.table-wrap:not(.list-sticky-wrap) table` (más arriba)
   le mete table-layout:fixed + width:100% + min-width:0 → columnas de ancho fijo →
   la descripción larga (MERNET) desborda su celda y se monta con los montos. Acá lo
   overrideamos a `auto` (como los listados generales / .sortable-table): cada columna
   toma su ancho según contenido y la tabla crece a la derecha con scroll horizontal. */
.cc-access-table > table {
  table-layout: auto !important;
  width: auto !important;
  min-width: 100% !important;
}
.cc-access-table > table td,
.cc-access-table > table th {
  vertical-align: top;
  white-space: nowrap;
}
.cc-access-table td.cc-num {
  text-align: right;
}
.cc-access-table td.cc-desc {
  padding-right: 18px;
}

/* Redimensionado de columnas tipo Excel (col-resize.js) — agarre en el borde derecho
   de cada <th>. No cambia el position del th si ya era sticky (lo hace el JS). */
table.col-resizable thead th { -webkit-user-select: none; user-select: none; }
.col-resize-handle {
  position: absolute;
  top: 0;
  right: 0;            /* DENTRO del th: si va afuera (right negativo) lo tapa la columna vecina y no se puede agarrar */
  width: 10px;
  height: 100%;
  cursor: col-resize;
  z-index: 20;
  touch-action: none;
}
.col-resize-handle:hover { background: rgba(37, 99, 235, .35); }
body.col-resizing,
body.col-resizing * { cursor: col-resize !important; user-select: none !important; }
/* Tabla ya "congelada" a fixed: clipear el contenido para que al angostar una columna
   el texto no se monte sobre la de al lado (Excel-like). Solo afecta tablas resizeadas. */
table.col-resize-active td,
table.col-resize-active th { overflow: hidden; text-overflow: ellipsis; }

#master-panel-cuenta,
#master-panel-operaciones {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.client-account-tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.client-account-tab > .card.cc-saldo-sticky {
  flex-shrink: 0;
  position: static;
}
.client-account-tab > .product-analysis-grid {
  flex-shrink: 0;
}
.client-account-tab > .product-analysis-section {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.client-account-tab > .product-analysis-section > .cc-filtros {
  flex-shrink: 0;
}
.client-account-tab > .product-analysis-section > .cc-access-table {
  flex: 1;
  min-height: 0;
  overflow-x: auto !important;
  overflow-y: auto !important;
}

@media (max-width: 1100px) {
  .top-actions {
    width: 100%;
    flex-wrap: wrap;
    justify-content: flex-start;
  }

  .global-master-search {
    width: 100%;
    min-width: 0;
    order: -1;
  }

  .global-master-results {
    left: 0;
    right: auto;
    width: min(100%, 92vw);
  }

  .bulk-toolbar {
    grid-template-columns: 1fr;
  }

  .bulk-modal-backdrop {
    align-items: stretch;
    padding: 10px;
  }

  .bulk-modal {
    max-height: 96vh;
  }

  .product-editor-modal {
    height: 96vh;
    max-height: 96vh;
  }

  .product-analysis-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .product-editor-panels,
  .product-analysis-columns {
    grid-template-columns: 1fr;
  }
}


/* Ajuste de grillas para trabajar a pantalla completa con bases grandes. */
.view {
  width: 100% !important;
  max-width: none !important;
  padding: 18px 14px !important;
}

.card {
  border-radius: var(--radius-md) !important;
  padding: 16px !important;
}

/* Homogeneización F2 (2026-06-17): utilidades de espaciado para reemplazar los
   estilos inline de margin en las cards (mismo valor → sin cambio visual). */
.mt-10 { margin-top: 10px; }
.mt-12 { margin-top: 12px; }
.mt-14 { margin-top: 14px; }
.mt-16 { margin-top: 16px; }
.mt-18 { margin-top: 18px; }
.mb-12 { margin-bottom: 12px; }
.mb-14 { margin-bottom: 14px; }
.mb-16 { margin-bottom: 16px; }
.text-right { text-align: right; }

/* 2026-05-16: excluimos .list-sticky-wrap. La regla original ponía
   overflow-x:hidden + overflow-y:visible !important, lo que mataba el
   scroll del wrap is-listado (la tabla se desbordaba abajo y empujaba
   la paginación fuera del viewport). Los wraps que NO son list-sticky
   (modales, sub-tablas) siguen con el comportamiento previo: ancho
   completo, sin scroll vertical propio. */
.table-wrap:not(.list-sticky-wrap) {
  width: 100% !important;
  max-width: 100% !important;
  overflow-x: hidden !important;
  overflow-y: visible !important;
  border-radius: var(--radius-md) !important;
}
.table-wrap.list-sticky-wrap {
  width: 100% !important;
  max-width: 100% !important;
  border-radius: var(--radius-md) !important;
}

/* A+B 2026-05-15: excluimos los listados is-listado (list-sticky-wrap)
   de esta regla. Esos listados quieren table-layout: auto + width natural
   para que las columnas tomen su ancho según contenido y la tabla crezca
   a la derecha con scroll horizontal en lugar de comprimir / superponer
   texto. El listado de Artículos (.table-articulos-wrap) ya funciona así.
   Capilla Sixtina 2026-05-15: .cliente-list-wrap eliminado de los :not()
   (clase ya no existe en el HTML — migrada a .list-sticky-wrap). */
.table-wrap:not(.list-sticky-wrap) table {
  width: 100% !important;
  min-width: 0 !important;
  table-layout: fixed !important;
}
/* Para los wraps de listados is-listado: tabla en layout auto, sin width
   fijo, sin min-width 0. Así las celdas con nowrap fuerzan ancho mínimo
   propio y la tabla puede exceder el wrap → aparece scroll horizontal. */
.table-wrap.list-sticky-wrap table {
  table-layout: auto;
}

.table-wrap.table-wrap-autocomplete {
  overflow: visible !important;
}

.table-wrap.table-wrap-autocomplete table {
  table-layout: auto !important;
}

/* =====================================================================
   REFORMA VISUAL A — start (Parte 2: respiración tablas)
   ===================================================================== */

/* A+B 2026-05-14: excluimos los listados is-listado (list-sticky-wrap)
   de esta regla legacy. Esos listados quieren nowrap + scroll horizontal,
   no wrapping multi-línea. El listado de Artículos (.table-articulos-wrap)
   es el modelo. Capilla Sixtina 2026-05-15: .cliente-list-wrap ya no existe.
   Bugfix Martín 2026-05-16: el selector `.table-wrap th` incluía
   list-sticky-wrap por error (sin :not()), aplicaba white-space:normal
   al thead de clientes y lo wrappeaba multi-línea, ensanchando la fila
   verticalmente. Fix: agregar :not(.list-sticky-wrap) también al th.
   REFORMA VISUAL A 2026-05-19: padding aumentado a 10px 12px para
   respiración, con clase .data-table-compact como escape hatch. */
.table-wrap:not(.list-sticky-wrap) th,
.table-wrap:not(.list-sticky-wrap) td {
  padding: 10px 12px !important;
  font-size: 13px !important;
  line-height: 1.3 !important;
  white-space: normal !important;
  overflow-wrap: anywhere !important;
  word-break: normal !important;
  vertical-align: middle !important;
}

.table-wrap:not(.list-sticky-wrap) th {
  font-size: 12px !important;
}

/* Clase escape hatch para tablas densas por diseño (items de venta,
   stock con muchas columnas, etc.) */
.data-table-compact th,
.data-table-compact td,
.table-wrap.data-table-compact th,
.table-wrap.data-table-compact td {
  padding: 5px 8px !important;
  vertical-align: middle !important;
}

/* list-sticky-table: thead compacto, nowrap (sino se ensancha) */
.table-wrap.list-sticky-wrap th {
  font-size: 12px;
  padding: 9px 12px;
  white-space: nowrap;
  line-height: 1.2;
}

/* list-sticky-table: celdas con respiración */
.table-wrap.list-sticky-wrap td {
  padding: 10px 12px;
  vertical-align: middle;
}

/* =====================================================================
   REFORMA VISUAL A — end (respiración tablas)
   ===================================================================== */

.table-wrap:not(.list-sticky-wrap) td.actions {
  display: table-cell !important;
  white-space: normal !important;
}

.table-wrap td.actions .btn {
  width: 100%;
  margin: 2px 0;
  padding: 7px 8px;
  border-radius: 8px;
  font-size: 12px;
}

.table-wrap .badge {
  padding: 4px 7px;
  font-size: 11px;
}

.product-list-table th:nth-child(1),
.product-list-table td:nth-child(1) {
  width: 36px;
  text-align: center;
}

.product-list-table th:nth-child(2),
.product-list-table td:nth-child(2) {
  width: 10%;
}

.product-list-table th:nth-child(3),
.product-list-table td:nth-child(3) {
  width: 9%;
}

.product-list-table th:nth-child(4),
.product-list-table td:nth-child(4) {
  width: 24%;
}

.product-list-table th:nth-child(5),
.product-list-table td:nth-child(5) {
  width: 6%;
}

.product-list-table th:nth-child(6),
.product-list-table td:nth-child(6),
.product-list-table th:nth-child(7),
.product-list-table td:nth-child(7),
.product-list-table th:nth-child(8),
.product-list-table td:nth-child(8) {
  width: 9%;
}

.product-list-table th:nth-child(9),
.product-list-table td:nth-child(9) {
  width: 8%;
}

.product-list-table th:nth-child(10),
.product-list-table td:nth-child(10),
.product-list-table th:nth-child(11),
.product-list-table td:nth-child(11) {
  width: 6%;
}

.product-list-table th:nth-child(12),
.product-list-table td:nth-child(12) {
  width: 10%;
}

/* ── Variantes producto — listado admin (F1 2026-05-31) ──────────────────────
   Prefijo: prod-var-* para distinguir de reglas canónicas.
   Patrón de fila expandible clonado de .pedidos-ml-row / .pedidos-ml-item-row
   ─────────────────────────────────────────────────────────────────────────── */

/* Triángulo expand en fila padre */
.prod-var-expand-icon {
  display: inline-block;
  font-size: 9px;
  color: #94a3b8;
  margin-right: 5px;
  transition: color 0.12s;
  user-select: none;
  cursor: pointer;
}
.prod-row-con-variantes[data-expanded="true"] .prod-var-expand-icon {
  color: var(--primary, #2563eb);
}
.prod-row-con-variantes[data-expanded="true"] > td {
  background: #eff6ff;
}

/* Badge Σ en columna stock del padre */
.prod-var-stock-sigma {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  color: #3b82f6;
  background: #dbeafe;
  border-radius: 3px;
  padding: 0 3px;
  vertical-align: middle;
  margin-left: 2px;
}

/* Fila hija (una por variante activa) */
.prod-var-hija > td {
  padding: 0;
}
.prod-var-hija-td {
  background: #f0f9ff;
  border-bottom: 1px solid #e0f2fe;
  padding: 6px 10px !important;
}
.prod-var-hija:last-of-type .prod-var-hija-td {
  border-bottom: 2px solid #c7d2fe;
}
.prod-var-hija-contenido {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  flex-wrap: wrap;
}
.prod-var-hija-indent {
  display: inline-block;
  width: 20px;
  border-left: 2px solid #c3dafe;
  height: 16px;
  margin-right: 4px;
}
.prod-var-miniatura {
  width: 32px;
  height: 32px;
  object-fit: cover;
  border-radius: 4px;
  border: 1px solid #c3dafe;
  flex-shrink: 0;
}
.prod-var-sin-img {
  display: inline-block;
  width: 32px;
  height: 32px;
  line-height: 32px;
  text-align: center;
  color: #cbd5e1;
  font-size: 16px;
}
.prod-var-sku {
  font-size: 11px;
  background: #dbeafe;
  color: #1d4ed8;
  padding: 2px 6px;
  border-radius: 4px;
  font-family: monospace;
  white-space: nowrap;
}
.prod-var-combinacion {
  color: #475569;
  font-size: 12px;
}
.prod-var-stock {
  color: #374151;
  white-space: nowrap;
}
.prod-var-precio {
  color: #059669;
  font-weight: 600;
  white-space: nowrap;
}

/* ── Mobile: variantes apiladas debajo del nombre (≤768px) ───────────────── */
.prod-var-mobile-list {
  display: none; /* oculto en desktop */
  margin-top: 4px;
  flex-direction: column;
  gap: 3px;
}
.prod-var-mobile-chip {
  display: inline-block;
  font-size: 11px;
  color: #374151;
  background: #f0f9ff;
  border: 1px solid #bae6fd;
  border-radius: 4px;
  padding: 2px 6px;
  white-space: nowrap;
}
.prod-var-mobile-chip--more {
  color: #1d4ed8;
  background: #dbeafe;
  border-color: #93c5fd;
  cursor: pointer;
}


@media (max-width: 1100px) {
  .view {
    padding: 12px 8px !important;
  }

  .card {
    padding: 12px !important;
  }

  .table-wrap th,
  .table-wrap td {
    padding: 7px 6px !important;
    font-size: 12px !important;
  }
}

/* ── Módulo Ofertas ──────────────────────────────────────────────────── */
.of-check-list {
  max-height: 180px;
  overflow-y: auto;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px;
  padding: 8px 10px;
  background: var(--bg, #f4f7fb);
  margin-top: 4px;
  display: flex;
  flex-wrap: wrap;
  gap: 2px 0;
}

.of-check-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 6px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
  width: 100%;
}

.of-check-row:hover {
  background: var(--soft-primary, #eff6ff);
}

.of-check-row input[type="checkbox"] {
  flex-shrink: 0;
}


/* Dashboard v1.56 — KPIs, notas y agenda */
.dashboard-kpis {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 14px;
}

@media (max-width: 1100px) {
  .dashboard-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


.btn-sm {
  padding: 6px 12px;
  font-size: 13px;
}

/* .btn-xs eliminado aquí — ver definición canónica más arriba */

/* Notas */
.notas-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
}

.nota-item {
  background: #fef3c7;
  border: 1px solid #fcd34d;
  border-radius: 8px;
  padding: 10px;
  min-height: 110px;
  display: flex;
  flex-direction: column;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .06);
}

.nota-color-amarillo { background: linear-gradient(160deg, #fef3c7, #fde68a); border-color: #f59e0b; }
.nota-color-rosa     { background: linear-gradient(160deg, #fce7f3, #fbcfe8); border-color: #ec4899; }
.nota-color-verde    { background: linear-gradient(160deg, #d1fae5, #a7f3d0); border-color: #10b981; }
.nota-color-azul     { background: linear-gradient(160deg, #dbeafe, #bfdbfe); border-color: #3b82f6; }
.nota-color-naranja  { background: linear-gradient(160deg, #ffedd5, #fed7aa); border-color: #f97316; }
.nota-color-violeta  { background: linear-gradient(160deg, #ede9fe, #ddd6fe); border-color: #8b5cf6; }

.nota-item {
  position: relative;
  transition: transform .15s ease, box-shadow .15s ease;
}

.nota-item:hover {
  transform: translateY(-2px) rotate(-.4deg);
  box-shadow: 0 6px 14px rgba(0, 0, 0, .12);
}

.nota-colors {
  display: flex;
  gap: 4px;
  margin-bottom: 6px;
  opacity: .55;
  transition: opacity .15s ease;
}

.nota-item:hover .nota-colors { opacity: 1; }

.nota-color-chip {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1.5px solid rgba(0, 0, 0, .15);
  cursor: pointer;
  padding: 0;
  transition: transform .1s ease, box-shadow .1s ease;
}

.nota-color-chip:hover {
  transform: scale(1.25);
}

.nota-color-chip.active {
  border-color: #1f2937;
  border-width: 2.5px;
  box-shadow: 0 0 0 2px #ffffff inset, 0 1px 4px rgba(0, 0, 0, .2);
}

/* Color picker grande dentro del modal */
.nota-colors-pick {
  display: flex;
  gap: 10px;
}

.nota-colors-pick .nota-color-chip {
  width: 32px;
  height: 32px;
}

.btn-icon-x {
  border: 0;
  background: transparent;
  color: #6b7280;
  font-size: 18px;
  line-height: 1;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  cursor: pointer;
  padding: 0;
}

.btn-icon-x:hover {
  background: rgba(0, 0, 0, .08);
  color: #1f2937;
}

.nota-texto {
  flex: 1;
  white-space: pre-wrap;
  outline: none;
  font-size: 13px;
  color: #1f2937;
  margin-bottom: 6px;
  min-height: 60px;
}

.nota-texto:focus {
  background: rgba(255, 255, 255, .6);
  border-radius: 4px;
}

.nota-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px dashed rgba(0, 0, 0, .12);
  padding-top: 5px;
  font-size: 11px;
  color: #6b7280;
  gap: 6px;
}

/* Agenda */
.agenda-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 420px;
  overflow-y: auto;
}

.agenda-item {
  display: grid;
  grid-template-columns: auto 92px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  background: #ffffff;
}

.agenda-item.hoy {
  background: #eff6ff;
  border-color: #93c5fd;
}

.agenda-item.vencido {
  background: #fef2f2;
  border-color: #fca5a5;
}

.agenda-item.completado {
  opacity: .6;
}

.agenda-item.completado .agenda-titulo {
  text-decoration: line-through;
}

.agenda-fecha {
  text-align: center;
}

.agenda-dia {
  font-weight: 600;
  font-size: 12px;
  color: #374151;
}

.agenda-hora {
  font-size: 11px;
  color: #6b7280;
}

.agenda-titulo {
  font-weight: 600;
  font-size: 14px;
  color: #1f2937;
}

.agenda-desc {
  color: #6b7280;
  margin-top: 2px;
}

.agenda-check {
  width: 18px;
  height: 18px;
  cursor: pointer;
}

/* Dashboard modules — drag & drop */
.dashboard-modules {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: minmax(180px, auto);
  gap: 18px;
  margin-top: 18px;
  /* 2026-06-14: cada card abraza su contenido en lugar de estirarse para igualar
     a la card más alta de la fila (eso dejaba espacio blanco abajo, ej. en
     "Comprobantes vencidos" con su lista cap a 300px). */
  align-items: start;
}

@media (max-width: 980px) {
  .dashboard-modules { grid-template-columns: 1fr; }
}

.dashboard-module {
  position: relative;
  transition: opacity .15s ease, transform .15s ease;
  overflow: hidden;
}

.dashboard-module[data-cols="2"] { grid-column: span 2; }
.dashboard-module[data-rows="2"] { grid-row: span 2; }

.dashboard-module.resizing {
  outline: 2px dashed #1d4ed8;
  outline-offset: -2px;
}

.dashboard-resize-handle {
  position: absolute;
  bottom: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: #94a3b8;
  cursor: nwse-resize;
  background: rgba(255,255,255,0.85);
  border-radius: 4px;
  user-select: none;
  z-index: 2;
  transition: color .1s, background .1s, transform .1s;
}

.dashboard-resize-handle:hover {
  color: #1d4ed8;
  background: #e0e7ff;
  transform: scale(1.1);
}

@media (max-width: 980px) {
  /* En mobile el grid es 1 columna; resize no aplica. */
  .dashboard-module[data-cols="2"],
  .dashboard-module[data-rows="2"] {
    grid-column: auto;
    grid-row: auto;
  }
  .dashboard-resize-handle { display: none; }
}

.dashboard-module.dragging {
  opacity: .5;
  transform: scale(.99);
}

.dashboard-module-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

/* 2026-06-14: "ocultar este módulo para mí" + barra Personalizar Inicio. */
.dashboard-module-hide {
  margin-left: auto;
  border: 0;
  background: transparent;
  color: #94a3b8;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 7px;
  border-radius: 6px;
  opacity: .5;
  transition: opacity .12s, background .12s, color .12s;
}
.dashboard-module:hover .dashboard-module-hide { opacity: 1; }
.dashboard-module-hide:hover { background: #fee2e2; color: #b91c1c; }
.dashboard-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 10px;
}
.dashboard-hidden-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  margin-left: 4px;
  border-radius: 8px;
  background: #2563eb;
  color: #fff;
  font-size: 10px;
  font-weight: 700;
}

.dashboard-drag-handle {
  cursor: grab;
  color: #94a3b8;
  font-weight: 700;
  letter-spacing: -2px;
  font-size: 18px;
  user-select: none;
  padding: 2px 4px;
  border-radius: 4px;
  transition: background .1s ease, color .1s ease;
}

.dashboard-drag-handle:hover {
  background: #e5e7eb;
  color: #475569;
}

.dashboard-drag-handle:active { cursor: grabbing; }

/* KPI alert + sub label */
.kpi-alert {
  border-left: 4px solid #b91c1c;
  background: linear-gradient(135deg, #fff, #fef2f2);
}

.kpi-alert .value { color: #991b1b; }

.kpi-sub {
  font-size: 12px;
  color: #6b7280;
  margin-top: 2px;
}

/* Ojito privacidad dashboard — oculta montos en KPIs desktop */
.kpis-montos-ocultos .kpi .value,
.kpis-montos-ocultos .kpi .kpi-sub {
  filter: blur(6px);
  user-select: none;
  cursor: pointer;
  transition: filter .2s ease;
}
.kpis-montos-ocultos .kpi:hover .value,
.kpis-montos-ocultos .kpi:hover .kpi-sub {
  filter: blur(3px);
}

/* Ojito privacidad dashboard — oculta valores monetarios en mobile-lite */
.mobile-lite-tiles-ocultos [data-kpi-monetario] .mobile-lite-tile-value {
  filter: blur(6px);
  user-select: none;
  cursor: pointer;
  transition: filter .2s ease;
}

/* Botón ojito en toolbar — mismo estilo que btn-light btn-sm */
.dashboard-ojito-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  background: #fff;
  color: #374151;
  font-size: 13px;
  cursor: pointer;
  line-height: 1.4;
  transition: background .15s ease, border-color .15s ease;
}
.dashboard-ojito-btn:hover {
  background: #f3f4f6;
  border-color: #9ca3af;
}
.dashboard-ojito-btn svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* Modal */
/* ============================================================================
   JERARQUÍA DE OVERLAYS DEL ERP — leeme antes de agregar otra clase de modal.
   ----------------------------------------------------------------------------
   Convenciones canónicas (sprint unificación 2026-05-23):
   - .modal-overlay / .app-modal-overlay / .modal-mask  → z-index 10000005
       Modales genéricos. Backdrop oscuro. Usar para alta/edición de entidades,
       sub-modales que abren desde el comprobante, etc.
   - .bulk-modal-backdrop                               → z-index 10000008
       Pickers grandes con multi-selección o búsqueda full-screen (cliente,
       proveedor, producto, etiquetas, vincular ML). Más alto que .modal-overlay
       para abrirse encima de un modal padre.
   - .confirm-dialog-backdrop / .app-alert-backdrop     → z-index 10000010+
       Confirms y appAlert. Por encima de todo lo anterior.
   - .quick-input-modal-backdrop                        → z-index 10000025
       Mini-modal para alta inline (ej: + Nuevo transporte). Más alto que
       appAlert porque puede dispararse desde un appAlert.
   - .comprobante-modal-overlay                         → z-index 10000000
       Legacy V1 del comprobante. NO usar para nada nuevo (V2 + Feature #19
       pasaron a in-page).
   - .master-editor-modal                               → padding-only modal
       Clientes/proveedores con 7 tabs. Usa .modal-overlay para backdrop.
   ============================================================================ */
/* 2026-06-14: modales legacy (.modal-mask/.modal-overlay/.modal-card/.modal-box)
   migrados a app-modal-* en public/app.js. Los alias y el chain de hijos que
   antes vivían acá se eliminaron (eran CSS muerto). La PWA depósito usa su
   propio styles.css, no este. Queda solo el shell canónico app-modal-*. */
.app-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, .55);
  display: flex;
  align-items: center;
  justify-content: center;
  /* Por encima de .comprobante-modal-overlay (10000000) y .bulk-modal-backdrop
     (10000001), por debajo de .confirm-dialog-backdrop (10000010). Necesario
     para que sub-modales como "Vincular producto" y "Crear producto desde
     línea" se vean al abrirse desde el modal del comprobante de compra. */
  z-index: 10000005;
  animation: appModalFadeIn .15s ease;
  overscroll-behavior: contain;
}
/* (bloques legacy .modal-overlay/.modal-mask > .modal/.modal-box/.modal-card +
   sus .modal-header/.modal-body/.modal-footer/.modal-close eliminados 2026-06-14:
   markup migrado a app-modal-* en app.js. El shell canónico app-modal vive más
   abajo; .app-modal-close se promovió a clase canónica.) */

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

.app-modal {
  background: var(--surface, #fff);
  border-radius: 14px;
  box-shadow: var(--shadow-xl, 0 20px 60px rgba(15, 23, 42, .35));
  width: 90%;
  max-width: 480px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: appModalSlideIn .2s ease;
}

@keyframes appModalSlideIn {
  from { transform: translateY(-20px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.app-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--modal-padding-header, 14px 20px);
  border-bottom: 1px solid var(--border, #e5e7eb);
}

.app-modal-header h3 {
  margin: 0;
  font-size: var(--modal-header-font-size, 16px);
  font-weight: var(--modal-header-font-weight, 600);
}

.app-modal-body {
  padding: var(--modal-padding-body, 18px 20px);
  overflow-y: auto;
}

.app-modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: var(--modal-padding-footer, 12px 20px);
  border-top: 1px solid var(--border, #e5e7eb);
  background: var(--surface-2, #f9fafb);
}

/* 2026-06-14: .app-modal-close canónico (antes solo existía el legacy
   .modal-mask/.modal-overlay .modal-close). Al migrar los modales legacy a
   app-modal-*, el botón cerrar usa esta clase. Botón sin marco, equis gris. */
.app-modal-close {
  background: none;
  border: 0;
  font-size: 22px;
  line-height: 1;
  color: var(--muted, #64748b);
  cursor: pointer;
  padding: 2px 8px;
}
.app-modal-close:hover { color: var(--ink, #1e293b); }

/* Headers ordenables (sortable) */
table th.sortable-th {
  cursor: pointer;
  user-select: none;
  position: relative;
  padding-right: 18px !important;
}
table th.sortable-th:hover {
  background: #eef2ff;
}
table th.sortable-th::after {
  content: "↕";
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  opacity: .35;
  font-size: 10px;
}
table th.sortable-th.sorted-asc::after {
  content: "▲";
  opacity: 1;
}
table th.sortable-th.sorted-desc::after {
  content: "▼";
  opacity: 1;
}

/* Cuando hay un modal abierto, bloqueamos el scroll del fondo. Sin esto, la
   rueda del mouse sobre el overlay (que es position:fixed pero deja pasar el
   evento wheel) termina desplazando el <body> de atrás. */
html:has(.comprobante-modal-overlay:not(.modal-minimized), .app-modal-overlay:not(.modal-minimized), .bulk-modal-backdrop:not(.modal-minimized)),
body:has(.comprobante-modal-overlay:not(.modal-minimized), .app-modal-overlay:not(.modal-minimized), .bulk-modal-backdrop:not(.modal-minimized)) {
  overflow: hidden;
}

/* Bugfix Martín 2026-05-16 noche: recibos/OP tipo Original/Proforma en
   fila superior delicada + comprobante full-width.
   Las clases .tipo-oficial-bar/.tipo-oficial-toggle/.tipo-oficial-pill
   reemplazan al viejo <select> de "tipo de recibo/orden" en
   renderTesoreriaRecibos / renderTesoreriaPagos. */
.tipo-oficial-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 10px 14px;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  margin: 0 0 14px 0;
}
.tipo-oficial-toggle {
  display: flex;
  gap: 0;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-radius: 999px;
  padding: 3px;
  flex-shrink: 0;
}
.tipo-oficial-pill {
  border: none;
  background: transparent;
  color: #475569;
  padding: 5px 18px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s;
  font-family: inherit;
}
.tipo-oficial-pill:hover:not([disabled]):not(.active) {
  background: #f1f5f9;
}
.tipo-oficial-pill.active {
  background: var(--primary);
  color: var(--on-primary, #fff);
}
.tipo-oficial-pill[disabled] {
  cursor: not-allowed;
  opacity: .55;
}
.tipo-oficial-help {
  flex: 1;
  min-width: 220px;
  font-size: 11.5px;
  color: #64748b;
  line-height: 1.4;
}

/* Comprobante full-width modal: el body del modal usa todo el ancho
   disponible. Para que el wrapper externo también lo respete, usamos
   :has() sobre el overlay. Fallback: el body ya tiene flex 1 y ancho 100%. */
.comprobante-fullwidth-modal {
  width: 100%;
  max-width: none;
}
.comprobante-modal-overlay:has(.comprobante-fullwidth-modal) > .comprobante-modal,
.comprobante-modal-overlay:has(.comprobante-fullwidth-modal) > .comprobante-modal-content {
  max-width: 100vw !important;
  width: 100vw !important;
  margin: 0 !important;
}

/* Comprobante modal (ventas/compras en popup estilo MerNet) */
.comprobante-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, .55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
  z-index: 10000000;
  animation: appModalFadeIn .15s ease;
  overflow: hidden;
  overscroll-behavior: contain;
}

/* Feature #19 (2026-05-10): comprobante in-page (pestaña Chrome real).
   El comprobante deja de ser overlay y ocupa #view. La página se comporta
   como un "modal de alto fijo": el header azul queda fijo arriba, la barra
   de Guardar+Totales queda fija abajo, y el cuerpo (cliente + items +
   condición + observaciones) scrollea internamente. Esto restaura el sticky
   que tenía el modal viejo (.comprobante-modal-header + .comprobante-modal-body
   con flex:1; overflow:auto) sin necesitar overlay.

   Cuando #view contiene una .comprobante-page lo forzamos a layout flex que
   llene la altura útil (viewport menos topbar de ~80px). El padding default
   del .view (28px) se elimina para que el comprobante use todo el ancho. */
.view:has(.comprobante-page) {
  padding: 0;
  /* 2026-05-15 (zoom-removal + fullheight): SIN número mágico. Replicamos
     el patrón TABLES-OPTIN — el .main padre se vuelve flex column 100vh
     (regla siguiente) y este view absorbe TODO el alto sobrante con
     flex:1. Sin calc(100vh - Npx). El criterio de aceptación de Martín
     es: 'la pantalla de comprobante ocupa el 100% del alto visible, en
     distintos tamaños de ventana, sin franja vacía abajo'. */
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  display: flex;
}
/* Hacer el .main flex column 100vh cuando contiene un comprobante,
   igual que se hace con is-listado. El #view interior usa flex:1 y
   absorbe el alto sobrante sin necesidad de números mágicos. */
.main:has(> .view:has(.comprobante-page)) {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}
#app:has(> #afip-modo-banner:not([style*="display:none"]):not([style*="display: none"])) > .main:has(> .view:has(.comprobante-page)) {
  height: calc(100vh - 122px);
}
/* D-F1 (2026-05-14): Layout fullscreen del comprobante cuando el usuario
   activa `usar_comprobante_fullscreen`. El número mágico `calc(100dvh -
   100px)` es la raíz de la "franja blanca cortada abajo" que reporta el
   operador — falla cuando el banner AFIP está visible, en mobile, o cuando
   el chrome del ERP cambia de altura. Replicamos el patrón TABLES-OPTIN
   (que funciona para listados): .main flex column de altura 100vh y el
   #view absorbe TODO el sobrante. Sin números mágicos. */
.main:has(> .view:has(.comprobante-page.comprobante-fs)) {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}
#app:has(> #afip-modo-banner:not([style*="display:none"]):not([style*="display: none"])) > .main:has(> .view:has(.comprobante-page.comprobante-fs)) {
  height: calc(100vh - 122px);
}
.view:has(.comprobante-page.comprobante-fs) {
  /* Anula el `height: calc(100dvh - 100px)` legacy de la regla previa.
     Con flag ON, el view absorbe el alto vía flex sin número mágico. */
  height: auto;
  flex: 1;
  min-height: 0;
}
/* Zona 1 expandida (firma Martín 2026-05-14): cuando flag ON, el header
   muestra razón social + CUIT + lista + condición + dirección. La línea
   .comprobante-page-header-entidad se llena con todos esos campos en
   updateComprobanteHeaderEntidadInfo. La franja azul gana 1-2 líneas. */
.comprobante-page.comprobante-fs .comprobante-page-header-entidad {
  /* Más respiro vertical para 2-3 líneas de info del cliente. */
  gap: 4px 18px;
}
.comprobante-page.comprobante-fs .comprobante-header-entidad-cli {
  /* Razón social + CUIT van en una línea propia, tipografía un poco más
     marcada para que el operador no la pierda de vista. */
  flex-basis: 100%;
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  letter-spacing: .01em;
}
/* Mobile compacto (firma Martín 2026-05-14): zona 1 en 1-2 líneas. */
.comprobante-page {
  background: #fff;
  border-radius: 0;
  box-shadow: none;
  /* 2026-05-15 (spec final): position:relative para anclar los botones
     flotantes (.doc-back-btn-floating, .comprobante-modal-close-floating). */
  position: relative;
  /* HOTFIX 2026-05-15: !important defensivo después de bug reportado
     de "el comprobante entero no scrollea". Garantiza la cadena flex
     completa para que el body interno pueda absorber el espacio y
     scrollear sin que otras reglas la rompan. */
  display: flex !important;
  flex-direction: column !important;
  overflow: hidden !important;
  flex: 1 !important;
  min-height: 0 !important;
}
/* 2026-05-15 (spec final): la barra azul del header del comprobante
   queda OCULTA (Martín: 'las dos primeras filas azules ya no tiene
   sentido tampoco, porque el titulo esta arriba de todo'). El page-
   title del chrome ya muestra el tipo + cliente. El botón cerrar (×)
   pasa a flotante absoluto en la esquina superior derecha del page. */
.comprobante-page-header {
  display: none;
}
/* Botón × flotante para cerrar el comprobante (reemplaza el botón
   que vivía dentro de .comprobante-page-header-main). El JS sigue
   bindeando #comprobante-modal-close, así que el helper que lo
   busca al crear el page sigue funcionando. */
.comprobante-page > .comprobante-modal-close-floating {
  position: absolute;
  top: 8px;
  right: 14px;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 999px;
  background: rgba(15, 23, 42, .06);
  color: #475569;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  z-index: 6;
  display: flex;
  align-items: center;
  justify-content: center;
}
.comprobante-page > .comprobante-modal-close-floating:hover {
  background: rgba(15, 23, 42, .12);
  color: #1e293b;
}
/* Línea sticky con info del cliente / proveedor (dirección, localidad, lista,
   condición). Se llena vía updateComprobanteHeaderEntidadInfo desde el
   renderer. Si no hay entidad, el atributo `hidden` la oculta. */
.comprobante-page-header-entidad {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, .18);
  font-size: 12px;
  color: rgba(255, 255, 255, .92);
  line-height: 1.4;
}
.comprobante-page-header-entidad[hidden] { display: none; }
.comprobante-header-entidad-part {
  white-space: nowrap;
}
.comprobante-header-entidad-label {
  font-weight: 600;
  color: rgba(255, 255, 255, .72);
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: 11px;
}
.comprobante-page-body {
  flex: 1 !important;
  min-height: 0 !important;
  overflow: hidden !important;
  padding: 10px 14px 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* Todo lo que NO es items ni save-bar queda anclado arriba con
   flex-shrink:0 — fijo, no scrollea. */
.comprobante-page-body > *:not(.comprobante-items-card):not(.comprobante-save-bar) {
  flex-shrink: 0;
}
/* Cards de encabezado: más finas, juntas, delicadas (Martín spec
   final: 'hace mas delicado la informacion de arriba, contenedores
   mas chicos y juntos'). */
.comprobante-page-body > .card:not(.comprobante-items-card) {
  padding: 8px 12px;
  border-radius: 4px;
  margin: 0;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
}
.comprobante-page-body > .card:not(.comprobante-items-card) .form-grid {
  gap: 6px 10px;
}
.comprobante-page-body > .card:not(.comprobante-items-card) .field {
  margin-bottom: 0;
}
.comprobante-page-body > .card:not(.comprobante-items-card) .field label {
  font-size: 10px;
  font-weight: 600;
  margin-bottom: 1px;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: #475569;
}
.comprobante-page-body > .card:not(.comprobante-items-card) .field .input,
.comprobante-page-body > .card:not(.comprobante-items-card) .field select,
.comprobante-page-body > .card:not(.comprobante-items-card) .field input {
  padding: 5px 8px;
  font-size: 12.5px;
  height: 28px;
  border-radius: 4px;
}
.comprobante-page-body > .card:not(.comprobante-items-card) .small-help {
  font-size: 10.5px;
  margin-top: 1px;
}
/* Items-card: ocupa todo el espacio restante (más espacio = más
   filas visibles, como pidió Martín). */
.comprobante-page-body > .comprobante-items-card {
  flex: 1 1 auto;
  min-height: 220px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 8px 12px;
  border-radius: 4px;
  margin: 0;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
}
.comprobante-page-body > .comprobante-items-card > .section-title-row,
.comprobante-page-body > .comprobante-items-card > .line-actions-bottom {
  flex-shrink: 0;
}
.comprobante-page-body > .comprobante-items-card > .table-wrap {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: auto;
}
/* Wrap con autocomplete: el dropdown del buscador de productos
   necesita poder salir del wrap. Trade-off conocido: overflow:visible
   pierde el scroll-y del wrap, pero ahora el padre items-card es
   overflow:hidden + flex:1 → la tabla con altura natural queda
   contenida y si excede, el SCROLL es del propio items-card por
   tener overflow:hidden? No — necesita ser overflow:auto. Compromiso:
   wrap-autocomplete con overflow:visible + max-height para forzar
   altura. El items-card ENVOLVENTE hace el scroll. */
.comprobante-page-body > .comprobante-items-card > .table-wrap-autocomplete {
  flex: 1 1 auto;
  min-height: 0;
  overflow: visible;
}
/* Cuando el wrap interno es autocomplete (overflow:visible), el SCROLL
   debe estar en el items-card. Lo cambiamos a overflow-y:auto SOLO
   cuando contiene un .table-wrap-autocomplete. */
.comprobante-page-body > .comprobante-items-card:has(> .table-wrap-autocomplete) {
  overflow-y: auto;
  overflow-x: hidden;
}
/* Save-bar: ahora vive fuera del scroll, anclada abajo por flex. */
.comprobante-page-body > .comprobante-save-bar {
  flex-shrink: 0;
  margin-top: 0;
  position: static;
  padding: 10px 14px;
  border-radius: 4px;
  background: #fff;
  border-top: 1px solid #e5e7eb;
}
/* 2026-05-15 (zoom-removal + 5 filas + sticky header): después de
   sacar el zoom 0.8 global, el scroll del body funciona perfecto.
   Ahora podemos sumar STICKY a la primera card del body (encabezado
   del cliente/proveedor) Y al thead de la tabla de artículos sin
   romper el dropdown del autocomplete (que sigue con overflow:visible
   porque el body es bloque scroll, no flex column).

   Pedido de Martín: 'desde el título hasta la fila de nombre de las
   columnas de artículos no se mueva, siempre fijo + que se vean al
   menos 5 filas a la vez'. */

/* Thead sticky DENTRO del items-card cuando el scroll está ahí
   (caso autocomplete) o dentro del wrap (caso table-wrap simple).
   En ambos casos sticky top:0 relativo al scroll container más
   cercano funciona correctamente. */
.comprobante-page-body .comprobante-items-card thead th {
  position: sticky;
  top: 0;
  z-index: 4;
  background: #f1f5f9;
}
/* Pegada al fondo del body scrolleable: la barra "Total + Guardar". Queda
   visible sin importar cuánto se scrollee la tabla de artículos. */
.comprobante-page-body .comprobante-save-bar {
  position: sticky;
  bottom: 0;
  background: #fff;
  border-top: 1px solid #e5e7eb;
  margin-top: 16px;
  padding: 12px 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
  z-index: 5;
}
/* Headers de la tabla de artículos también sticky dentro del scroll del body.
   El usuario pidió ver más renglones — con el body más alto y la tabla con
   thead sticky, se aprovecha todo el espacio vertical. */
.comprobante-page-body .comprobante-items-card table thead th {
  position: sticky;
  top: 0;
  background: #f1f5f9;
  z-index: 2;
}

/* Botones chicos al lado del código de una línea de compra para vincular
   el código suelto a un producto del catálogo o crear el producto al vuelo.
   Se muestran sólo cuando la línea no quedó matcheada a ningún producto. */
.line-link-actions {
  display: flex;
  gap: 4px;
  margin-top: 4px;
  flex-wrap: wrap;
}
.line-link-btn {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 5px;
  border: 1px solid #cbd5e1;
  background: #f1f5f9;
  color: #1e3a8a;
  cursor: pointer;
  font-weight: 600;
  white-space: nowrap;
  line-height: 1.25;
}
.line-link-btn:hover { background: #dbeafe; border-color: #93c5fd; }
.line-link-btn.create {
  background: #fef3c7;
  color: #92400e;
  border-color: #fcd34d;
}
.line-link-btn.create:hover { background: #fde68a; }

.comprobante-modal {
  background: #fff;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  width: 100%;
  max-width: 1180px;
  /* Altura fija (no max) para que el modal NO cambie de tamaño cuando el
     contenido crece (renglones del comprobante, pestañas del editor de
     usuarios, etc.). El cuerpo scrollea internamente vía .comprobante-modal-body
     (flex: 1; min-height: 0; overflow-y: auto). */
  height: 90vh;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: appModalSlideIn .2s ease;
}

.comprobante-modal-header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 18px;
  background: var(--primary-deep, #1e3a8a);
  color: var(--on-primary, #fff);
}

.comprobante-modal-header h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
}

.comprobante-modal-close,
.comprobante-modal-min {
  background: transparent;
  border: 0;
  color: #fff;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 8px;
  border-radius: 4px;
}

.comprobante-modal-close:hover,
.comprobante-modal-min:hover {
  background: rgba(255, 255, 255, .15);
}

.modal-window-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Estado minimizado del overlay del comprobante: no quitamos el DOM, sólo
   ocultamos visualmente para conservar foco/scroll/inputs cargados. */
.comprobante-modal-overlay.modal-minimized,
.bulk-modal-backdrop.modal-minimized,
.app-modal-overlay.modal-minimized {
  display: none !important;
}

/* Stack de chips minimizados: se apilan a la izquierda del chip más reciente
   en una fila horizontal abajo a la derecha. Permite tener varios modales
   minimizados a la vez (ej. la ficha del producto + el ajuste de stock). */
.modal-chip-stack {
  position: fixed;
  bottom: 16px;
  right: 16px;
  display: flex;
  flex-direction: row-reverse;
  gap: 8px;
  z-index: 9999990;
  pointer-events: none;
}
.modal-chip-stack .modal-chip-stacked {
  position: static !important;
  pointer-events: auto;
}

/* Cartel sticky de "tu sesión cierra en X s" (Sprint J3, 2026-05-10).
 * Aparece abajo a la izquierda — la derecha la ocupa el chip stack de
 * modales minimizados. Click postpone el cierre. */
.idle-countdown-chip {
  position: fixed;
  bottom: 16px;
  left: 16px;
  background: #b91c1c;
  color: #fff;
  border: 0;
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .25);
  z-index: 9999991;
  max-width: 360px;
  animation: idle-countdown-pulse 2s ease-in-out infinite;
}
.idle-countdown-chip:hover {
  background: #991b1b;
}
.idle-countdown-chip strong {
  font-size: 16px;
  margin: 0 2px;
}
@keyframes idle-countdown-pulse {
  0%, 100% { box-shadow: 0 8px 24px rgba(185, 28, 28, .35); }
  50%      { box-shadow: 0 8px 32px rgba(185, 28, 28, .65); }
}

/* Chip flotante cuando el modal está minimizado (estilo "barra de tareas"). */
.modal-chip-minimized {
  position: fixed;
  bottom: 16px;
  right: 16px;
  background: var(--primary-deep, #1e3a8a);
  color: var(--on-primary, #fff);
  border: 0;
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .25);
  z-index: 9999990;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 360px;
}
.modal-chip-minimized:hover { background: var(--primary-dark, #1e40af); }
.modal-chip-icon { opacity: .85; }
.modal-chip-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.modal-chip-action {
  opacity: .85;
  margin-left: 4px;
  font-size: 14px;
}

.comprobante-modal-body {
  /* 2026-05-15 (madrugada 4): el div del body tiene 2 clases
     (comprobante-page-body + comprobante-modal-body). Antes esta
     regla tenía overflow-y:auto !important, que peleaba con el
     overflow:hidden !important de .comprobante-page-body (que es el
     que activa el patrón flex-3-zonas: solo items-card scrollea).
     Como `comprobante-modal-body` viene DESPUÉS en el CSS, su
     !important ganaba y el body entero scrolleaba, rompiendo el
     sticky header/footer del comprobante. Removido overflow-y de
     acá: la cadena flex de `.comprobante-page-body` ya cumple.
     Mantenemos flex/min-height por defensa. */
  flex: 1 !important;
  min-height: 0 !important;
  padding: 10px 14px;
}

/* 2026-06-22 (Martín): homogeneización del scroll de modales. El shell
   .comprobante-modal lo reusan editores planos (Nuevo/Editar usuario, Nuevo
   catálogo PDF, modal genérico) que NO usan el patrón de 3 zonas de
   .comprobante-page-body. Sin overflow propio, su contenido largo (p.ej. el
   Horario de trabajo del usuario) se cortaba contra el overflow:hidden del
   contenedor. Regla única: todo body de modal que NO sea el body-3-zonas del
   comprobante scrollea internamente. El comprobante real queda intacto. */
.comprobante-modal-body:not(.comprobante-page-body) {
  overflow-y: auto;
}

.comprobante-save-bar .doc-total {
  margin: 0;
  flex: 1 1 auto;
  justify-content: flex-start;
}

.comprobante-save-bar .total-box {
  background: transparent;
  border: 0;
  padding: 0;
}

.comprobante-modal-body .total-box {
  min-width: 0;
  width: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  align-items: baseline;
  justify-content: flex-end;
  padding: 6px 12px;
  border-radius: 10px;
}

.comprobante-modal-body .total-row {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  margin: 0;
  font-size: 13px;
}

.comprobante-modal-body .total-row.big {
  font-size: 16px;
  font-weight: 800;
  border-top: 0;
  padding-top: 0;
  margin-top: 0;
  margin-left: 4px;
}

.comprobante-modal-body .card {
  margin-bottom: 6px;
  padding: 8px 12px;
}
/* Compactar el header del comprobante para que la primera fila de la tabla
   de items entre sin scroll. Ajustes acotados al modal — afuera no aplican. */
.comprobante-modal-body .section-title-row { margin-bottom: 6px; }
.comprobante-modal-body .document-selected-notice {
  padding: 6px 10px !important;
  font-size: 12px;
  margin-bottom: 6px !important;
}
.comprobante-modal-body .doc-cancel-btn {
  width: 26px;
  height: 26px;
  font-size: 16px;
}
.comprobante-modal-body .notice { margin-bottom: 6px; }
.comprobante-items-card table th { padding: 4px 6px; font-size: 11px; }

.comprobante-save-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  position: sticky;
  bottom: 0;
  background: #fff;
  padding: 10px 0 4px;
  margin-top: 8px;
  border-top: 1px solid #e5e7eb;
  z-index: 5;
}

/* Cuando la barra de guardar de un modal sólo tiene el botón (sin total al
   lado), alinearlo a la derecha. Aplica a Recibo, Orden de Pago, etc. */
.comprobante-save-bar:has(> button:only-child) {
  justify-content: flex-end;
}

.comprobante-save-btn {
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 600;
}
/* Indicador visual del shortcut F10 en el botón primario del modal. */
.comprobante-save-btn::after,
.app-modal-footer .btn-primary:last-child::after {
  content: " · F10";
  opacity: .65;
  font-weight: 500;
  font-size: 0.85em;
}

/* Inputs/selects compactos dentro del modal de comprobante */
.comprobante-modal-body input.input,
.comprobante-modal-body select,
.comprobante-modal-body select.input {
  padding: 3px 8px;
  font-size: 13px;
  min-height: 28px;
  height: 28px;
}

.comprobante-modal-body .field label {
  font-size: 11px;
  margin-bottom: 1px;
  display: block;
}

.comprobante-modal-body .small-help {
  font-size: 10px;
  margin-top: 1px;
  line-height: 1.25;
}

.comprobante-modal-body .form-grid {
  gap: 4px 10px;
}

.comprobante-modal-body .card {
  box-shadow: none;
  border: 1px solid #e5e7eb;
}

@media (max-width: 1100px) {
  .comprobante-modal-overlay { padding: 8px; }
  .comprobante-modal { max-width: 100%; border-radius: 8px; }
  .comprobante-modal-body { padding: 12px; }
}

.ref-comprobante,
.ref-cliente,
.ref-proveedor {
  color: #1d4ed8;
  text-decoration: underline;
  cursor: pointer;
}
.ref-comprobante:hover,
.ref-cliente:hover,
.ref-proveedor:hover {
  color: #1e3a8a;
}

/* =================== Filtros CC y paginación =================== */

.cc-filtros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px 14px;
  align-items: end;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 14px;
}

/* Fix 2026-05-19 (Martín): la tabla de movimientos quedaba metida adentro
   del grid .cc-filtros y el auto-fit le asignaba 1 sola columna (~148px),
   con el texto aplastado en vertical. Forzamos grid-column: 1 / -1 para
   que ocupe el ancho completo del grid. También aplica a cualquier
   wrapper de tabla que caiga dentro del bloque de filtros. */
.cc-filtros .cc-access-table,
.cc-filtros .table-wrap,
.cc-filtros .table-wrap-autocomplete {
  grid-column: 1 / -1;
}

.cc-filtro-grupo {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.cc-filtro-grupo > label {
  font-size: 12px;
  color: #475569;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.cc-filtro-grupo select,
.cc-filtro-grupo input[type="date"],
.cc-filtro-grupo input[type="search"],
.cc-filtro-grupo input[type="text"] {
  width: 100%;
  padding: 7px 9px;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  font-size: 14px;
  background: white;
  box-sizing: border-box;
}

.cc-filtro-grupo input:disabled {
  background: #f1f5f9;
  color: #94a3b8;
  cursor: not-allowed;
}

.cc-filtro-grupo-buscar {
  grid-column: span 2;
}

.cc-filtro-checkbox {
  flex-direction: row;
  align-items: center;
  gap: 6px;
}

.cc-filtro-checkbox label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 13px;
  color: #1e293b;
  font-weight: 500;
}

.cc-filtro-checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 0;
}

.cc-filtro-acciones {
  align-items: stretch;
}

.cc-filtro-acciones .btn {
  width: 100%;
}

.pagination {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  padding: 8px 4px;
}

.pagination-info {
  font-size: 13px;
  color: #475569;
}

.pagination-controls {
  display: flex;
  flex-wrap: nowrap;       /* 2026-06-14: los botones ‹ 1 2 … › NO se parten a otro renglón */
  gap: 4px;
  align-items: center;
  white-space: nowrap;
}

.pagination-btn {
  min-width: 32px;
  padding: 5px 10px;
  border: 1px solid #cbd5e1;
  background: white;
  color: #1e293b;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.12s;
}

.pagination-btn:hover:not(:disabled) {
  background: #f1f5f9;
  border-color: #94a3b8;
}

.pagination-btn.active {
  background: #1e293b;
  color: white;
  border-color: #1e293b;
}

.pagination-btn:disabled {
  background: #f8fafc;
  color: #cbd5e1;
  cursor: not-allowed;
  border-color: #e2e8f0;
}

.pagination-ellipsis {
  padding: 5px 6px;
  color: #94a3b8;
  font-size: 13px;
}

/* 2026-05-16: selector de filas/página universal en el footer de paginación.
   Aparece a la izquierda de los botones de página (cuando hay >1) o solo,
   con el contador "X filas", cuando hay 1 sola página. */
.pagination-pagesize-label {
  font-size: 13px;
  color: #475569;
  margin-right: 4px;
  white-space: nowrap;
}
.pagination-pagesize {
  padding: 4px 8px;
  font-size: 13px;
  max-width: 80px;
  margin-right: 8px;
}

/* ============ MOBILE MENU (sidebar overlay + burger) ============ */
.mobile-menu-toggle {
  display: none;
  background: transparent;
  border: 0;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 12px;
  margin-right: 6px;
  color: inherit;
  align-self: center;
}

.mobile-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 998;
}
.mobile-backdrop.open {
  display: block;
}

@media (max-width: 1000px) {
  /* Sobrescribe el layout column anterior y vuelve sidebar overlay deslizante */
  #app {
    flex-direction: row;
  }
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: 280px;
    height: 100vh;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    z-index: 999;
    overflow-y: auto;
    box-shadow: 0 0 30px rgba(0, 0, 0, 0.0);
  }
  .sidebar.open {
    transform: translateX(0);
    box-shadow: 0 0 30px rgba(0, 0, 0, 0.3);
  }
  main {
    width: 100%;
  }
  .mobile-menu-toggle {
    display: inline-flex;
    align-items: center;
  }
}

/* === Dashboard: Recordatorio de tareas === */
.rec-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  border-bottom: 1px solid #e5e7eb;
  margin-bottom: 12px;
}

.rec-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  font-size: 13px;
  background: transparent;
  border: none;
  border-bottom: 3px solid transparent;
  color: #475569;
  cursor: pointer;
  border-radius: 4px 4px 0 0;
  transition: background .1s ease, color .1s ease, border-color .1s ease;
}

.rec-tab:hover { background: #f1f5f9; color: #1e293b; }

.rec-tab.active {
  color: #1d4ed8;
  border-bottom-color: #1d4ed8;
  background: #eff6ff;
}

.rec-tab-emoji { font-size: 14px; }

.rec-tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: #e5e7eb;
  color: #6b7280;
  font-size: 11px;
  font-weight: 700;
}

.rec-tab-badge.with-items { background: #1d4ed8; color: #fff; }
.rec-tab.active .rec-tab-badge.with-items { background: #1e40af; }

.rec-empty {
  padding: 24px 12px;
  text-align: center;
  color: #6b7280;
  font-size: 14px;
}

.rec-table th { font-size: 12px; }
.rec-row { cursor: pointer; }
.rec-row:hover { background: #f8fafc; }
.rec-row:focus { outline: 2px solid #1d4ed8; outline-offset: -2px; }
/* 2026-05-15: si la fila está SELECCIONADA y además hovered, el azul
   del selected gana sobre el gris hover (sino visualmente pierde
   el highlight al pasar el mouse). */
.rec-row.cliente-row-selected,
.rec-row.cliente-row-selected:hover {
  background: #bae6fd;
}

.rec-dias {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.rec-dias-verde { background: #d1fae5; color: #065f46; }
.rec-dias-amber { background: #fef3c7; color: #92400e; }
.rec-dias-rojo  { background: #fee2e2; color: #991b1b; }

/* Etiquetas ML + despacho rápido FLEX (2026-08-20): barra de selección
   masiva arriba de la tabla del Recordatorio de tareas. */
.rec-bulk-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 12px;
  margin-bottom: 8px;
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  font-size: 13px;
}
.rec-bulk-count { color: #1e3a8a; font-weight: 600; }
.rec-check-col { width: 28px; text-align: center; }

/* === Editor de horario de trabajo en usuarios === */
.horario-grid {
  display: flex;
  flex-direction: column;
  gap: 6px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 10px;
  background: #f8fafc;
}

.horario-row {
  display: grid;
  grid-template-columns: 160px 110px 30px 110px;
  gap: 10px;
  align-items: center;
}

.horario-check {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.horario-dia-label { font-weight: 600; color: #374151; }

.horario-row .input { padding: 4px 6px; font-size: 14px; }
.horario-row .input:disabled { background: #f1f5f9; color: #94a3b8; cursor: not-allowed; }

/* === Sección colapsable dentro del editor de usuarios === */
.user-editor-section {
  margin-top: 20px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
}

.user-editor-section > summary {
  cursor: pointer;
  list-style: none;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  background: #f8fafc;
  border-bottom: 1px solid transparent;
  user-select: none;
}

.user-editor-section[open] > summary {
  border-bottom-color: #e5e7eb;
}

.user-editor-section > summary::-webkit-details-marker { display: none; }
.user-editor-section > summary::marker { content: ""; }

.user-editor-section > summary::before {
  content: "▶";
  font-size: 10px;
  color: #6b7280;
  transition: transform .12s ease;
}

.user-editor-section[open] > summary::before {
  transform: rotate(90deg);
}

.user-editor-section-title {
  font-weight: 700;
  font-size: 16px;
  color: #1e293b;
  flex-shrink: 0;
}

.user-editor-section-hint {
  font-size: 13px;
  color: #6b7280;
  flex: 1;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-editor-section > :not(summary) {
  padding: 0 14px 14px;
}

.user-editor-section > :first-of-type:not(summary) {
  padding-top: 12px;
}

.horario-sep {
  text-align: center;
  color: #6b7280;
  font-size: 12px;
}


/* === Modal de usuario: barra superior con datos básicos siempre visible === */
/* Se monta como hermano flex entre el header del modal y el body scrollable
   para que Nombre, Usuario, Mail, PIN, Rol, Vendedor y Depósito queden a la
   vista mientras se scrollea por permisos / horario. */
.user-editor-toolbar {
  flex-shrink: 0;
  padding: 10px 14px;
  background: #f8fafc;
  border-bottom: 1px solid #e5e7eb;
}

.user-editor-toolbar .form-grid {
  margin: 0;
  gap: 8px 12px;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.user-editor-toolbar .field label {
  font-size: 12px;
  margin-bottom: 2px;
}

.user-editor-toolbar input.input,
.user-editor-toolbar select {
  padding: 5px 8px;
  font-size: 13px;
  min-height: 30px;
  height: 30px;
  border-radius: 8px;
}

/* Barra de acciones (Guardar / Cancelar) anclada al pie del modal de
   usuario. flex-shrink:0 garantiza que no se comprima al crecer el body. */
.user-editor-actions {
  flex-shrink: 0;
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: flex-end;
  padding: 10px 14px;
  background: #fff;
  border-top: 1px solid #e5e7eb;
  box-shadow: 0 -2px 6px rgba(15, 23, 42, .04);
}

.user-editor-actions .btn { padding: 8px 18px; font-weight: 600; }


/* ===== AFIP "Mis Comprobantes Recibidos" — dropzone del modal de sync ===== */
.afip-sync-dropzone {
  margin-top: 14px;
  border: 2px dashed #cbd5e1;
  border-radius: 10px;
  background: #f8fafc;
  padding: 22px 16px;
  text-align: center;
  transition: all 0.15s ease;
  cursor: pointer;
  outline: none;
}
.afip-sync-dropzone:hover,
.afip-sync-dropzone:focus-visible {
  border-color: #94a3b8;
  background: #f1f5f9;
}
.afip-sync-dropzone.is-drag {
  border-color: #2563eb;
  background: #eff6ff;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);
}
.afip-sync-dropzone-icon {
  font-size: 28px;
  color: #64748b;
  margin-bottom: 4px;
}
.afip-sync-dropzone-title {
  font-weight: 600;
  font-size: 15px;
  color: #1e293b;
}
.afip-sync-dropzone-sub {
  font-size: 13px;
  color: #475569;
  margin-top: 2px;
}
.afip-sync-dropzone-status {
  margin-top: 10px;
  padding: 8px 10px;
  background: #ecfdf5;
  border: 1px solid #a7f3d0;
  border-radius: 6px;
  color: #065f46;
  font-size: 13px;
  text-align: left;
}

/* ===== Popup flotante: borrador AFIP siendo editado ===== */
.afip-float-panel {
  position: fixed;
  top: 90px;
  right: 16px;
  width: 280px;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(15, 23, 42, 0.18);
  z-index: 10000005;
  font-size: 13px;
  color: #1e293b;
  overflow: hidden;
}
.afip-float-panel.is-collapsed .afip-float-panel-body {
  display: none;
}
.afip-float-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 12px;
  background: #eff6ff;
  border-left: 4px solid #3b82f6;
  font-size: 14px;
  color: #1e3a8a;
}
.afip-float-panel-close {
  background: transparent;
  border: none;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  color: #1e3a8a;
  padding: 0 4px;
}
.afip-float-panel-close:hover { color: #0f172a; }
.afip-float-panel-body {
  padding: 10px 14px 12px;
}
.afip-float-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 3px 0;
  border-bottom: 1px dotted #e2e8f0;
}
.afip-float-row:last-of-type { border-bottom: none; }
.afip-float-row > span { color: #64748b; }
.afip-float-row > strong { font-weight: 600; text-align: right; }
.afip-float-sep {
  border: none;
  border-top: 1px solid #e2e8f0;
  margin: 6px 0;
}
.afip-float-status {
  margin-top: 8px;
  padding-top: 8px;
  font-size: 14px;
}
@media (max-width: 1100px) {
  .afip-float-panel {
    width: 220px;
    right: 8px;
    top: 70px;
  }
}

/* ===== Panel "faltantes informados desde depósito" en form de venta ===== */
.faltantes-panel {
  margin: 12px 0;
  padding: 12px 14px;
  border-left: 4px solid #f59e0b;
  background: #fffbeb;
  border-radius: 8px;
  color: #78350f;
}
.faltantes-panel-titulo {
  font-weight: 600;
  margin-bottom: 6px;
}
.faltantes-panel ul {
  margin: 6px 0 8px;
  padding-left: 22px;
}
.faltantes-panel-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}


/* === v1.55.2 — Listado con header pegajoso completo ======================
   En cada pestaña con listado, todo el bloque de cabecera (título + acciones
   + filtros + búsqueda + fila "Acciones" sobre la tabla) queda estático,
   incluso con muchas filas. Estrategia: la `.view` que contiene un listado
   se convierte en un flex column del alto del viewport (descontado el menú
   superior); la card que envuelve la tabla pasa a flex:1 con flex column
   adentro, y solo la `.table-wrap` (o `.table-articulos-wrap`) scrollea.

   Excluye:
   - `.table-wrap-autocomplete` (resultados inline de búsqueda).
   - `.product-analysis-table` (análisis de producto, no es un listado).
*/

/* TABLES-V5 (2026-05-14): la .view de listado YA NO tiene altura fija
   con calc(100vh - Npx). La altura se hereda del estirado flex de .main
   (regla TABLES-OPTIN — ver más abajo). Las 4 reglas viejas con
   `height: calc(100vh - ...)` se borraron porque competían entre sí y
   ninguna llenaba la pantalla en pantallas grandes.
   La regla que SÍ queda es .view.is-listado (flex column) + el ancho de
   .main:has(>.view.is-listado) que define la altura efectiva.

   La regla heredada `.view > .card:has(>...)` que ponía flex column en
   la card también se borró (queda en .view.is-listado > .card:last-child
   de la regla nueva). */

/* La table-wrap (genérica o de productos) es la única zona scrolleable. */
.view > .card > .table-wrap:not(.table-wrap-autocomplete):not(.product-analysis-table),
.view > .card > .table-articulos-wrap {
  flex: 1 1 auto !important;
  min-height: 0 !important;
  max-height: none !important;
  overflow-y: auto !important;
}

/* Thead pegajoso al tope del table-wrap (table-articulos-wrap ya lo trae).
   2026-09-09: se suma .table-wrap.list-sticky-wrap SIN exigir la cadena
   .view > .card — las islas (ej. Usuarios y permisos en config-sh) meten un
   div intermedio de re-render (#usu-tabla-inner) que rompía el matcheo por
   hijos directos: el th quedaba static y col-resize.js lo pisaba a relative. */
.view > .card > .table-wrap:not(.table-wrap-autocomplete) thead th,
.table-wrap.list-sticky-wrap thead th {
  position: sticky;
  top: 0;
  z-index: 4;
  background: #f9fafb;
  box-shadow: inset 0 -1px 0 #e2e8f0;
}

/* TABLES-V5 (2026-05-14): el bloque v1.55.3 con `height: calc(100vh - 130px) !important`
   y el media query asociado también se borraron. La altura del listado
   ahora viene del flex de .main (TABLES-OPTIN) y del :last-child que
   absorbe (regla nueva más abajo). El padding 6px 10px + gap del
   listado también está en .view.is-listado de TABLES-OPTIN. */

/* Topbar más compacta (impacta global, pero la altura queda igual de
   legible y libera ~24px verticales). */
.topbar {
  padding: 8px 28px !important;
}
.topbar h2 {
  font-size: 18px !important;
  line-height: 1.2 !important;
}
.topbar p {
  margin: 1px 0 0 !important;
  font-size: 12px !important;
  line-height: 1.2 !important;
}

/* Cards del listado: menos padding y sin borde redondo grande. */
.view > .card:has(> .table-wrap:not(.table-wrap-autocomplete):not(.product-analysis-table)),
.view > .card:has(> .table-articulos-wrap),
.view > .card:has(+ .card > .table-wrap),
.view > .card:has(+ .card > .table-articulos-wrap) {
  padding: 8px 12px !important;
  border-radius: var(--radius-sm) !important;
}

/* Cabecera de cada card (título + actions row + filas tipo "Acciones"):
   menos margin para liberar verticales. */
.view > .card > .section-title-row,
.view > .card > .cliente-titulo-row {
  margin-bottom: 4px !important;
}
.view > .card > .section-title-row > h3,
.view > .card > .cliente-titulo-row > h3 {
  font-size: 14px !important;
  line-height: 1.2 !important;
  margin: 0 !important;
}

/* Form-grid de filtros y buscador: menos gap y margin. */
.view > .card > .form-grid {
  gap: 4px 10px !important;
  margin: 4px 0 !important;
}
.view > .card > .form-grid .field label {
  font-size: 11px !important;
  margin-bottom: 2px !important;
}
.view > .card > .form-grid input.input,
.view > .card > .form-grid select,
.view > .card > .form-grid select.input,
.view > .card > .form-grid textarea {
  padding: 4px 8px !important;
  font-size: 13px !important;
  height: auto !important;
  min-height: 28px !important;
}

/* Botones del header de listado: más compactos. */
.view > .card > .section-title-row .btn,
.view > .card > .cliente-titulo-row .btn,
.view > .card > .actions .btn {
  padding: 4px 10px !important;
  font-size: 12px !important;
  min-height: 26px !important;
}

/* small-help y contador del listado: menos margen. */
.view > .card > .small-help {
  margin: 2px 0 !important;
  font-size: 11px !important;
}

/* Filas de la tabla del listado: menos padding (gana ~12-14px por fila). */
.view > .card > .table-wrap:not(.table-wrap-autocomplete) th,
.view > .card > .table-wrap:not(.table-wrap-autocomplete) td {
  padding: 4px 8px !important;
  font-size: 12px !important;
  line-height: 1.2 !important;
}

.view > .card > .table-articulos-wrap th,
.view > .card > .table-articulos-wrap td {
  padding: 4px 8px !important;
  font-size: 12px !important;
  line-height: 1.2 !important;
}

/* Botones dentro de la columna Acciones: mucho más chicos para no inflar
   la fila. */
.view > .card > .table-wrap td.actions .btn,
.view > .card > .table-articulos-wrap td.actions .btn {
  padding: 2px 6px !important;
  font-size: 11px !important;
  margin: 1px 0 !important;
  min-height: 22px !important;
}

/* Pill "sin clasificar" para tipo_proveedor null (P4 — tipos de proveedor). */
.tipo-prov-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
}
.tipo-prov-pill-vacio {
  background: #fff3cd;
  color: #856404;
  border: 1px solid #ffe69c;
}

/* ===== Popup flotante: "Código no encontrado" en línea de compra (P3) =====
   Mismo posicionamiento que .afip-float-panel para no tapar el modal del
   comprobante. Sin overlay backdrop: el comprobante de atrás sigue visible y
   editable. */
.codigo-compra-float-panel {
  position: fixed;
  top: 90px;
  right: 16px;
  width: 320px;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(15, 23, 42, 0.18);
  z-index: 10000010;
  font-size: 13px;
  color: #1e293b;
  overflow: hidden;
}
.codigo-compra-float-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 12px;
  background: #fef3c7;
  border-left: 4px solid #f59e0b;
  font-size: 14px;
  color: #92400e;
}
.codigo-compra-float-close {
  background: transparent;
  border: none;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  color: #92400e;
  padding: 0 4px;
}
.codigo-compra-float-close:hover { color: #451a03; }
.codigo-compra-float-body {
  padding: 12px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.codigo-compra-float-opt {
  text-align: left;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
  white-space: normal;
}
.codigo-compra-float-opt-title {
  font-weight: 600;
  font-size: 13px;
  line-height: 1.2;
}
.codigo-compra-float-opt-help {
  font-size: 11px;
  font-weight: 400;
  opacity: .85;
  line-height: 1.3;
}
@media (max-width: 1100px) {
  .codigo-compra-float-panel {
    width: 270px;
    right: 8px;
    top: 70px;
  }
}

/* Modal de ambigüedad de código en compras: highlight de fila navegable. */
.ambig-row { outline: none; }
.ambig-row:focus,
.ambig-row.ambig-row-selected {
  background: #dbeafe;
  outline: 2px solid #2563eb;
  outline-offset: -2px;
}
.ambig-row:hover { background: #eff6ff; }

/* Editor de cliente — secciones del tab "Económicos" y panel de contactos
   del tab "Otros datos". */
.cliente-econ-subgrid + .cliente-econ-subgrid {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid #e2e8f0;
}
.cliente-econ-subtitle {
  margin: 0 0 10px;
  font-size: 14px;
  font-weight: 800;
  color: #1e293b;
  text-transform: uppercase;
  letter-spacing: .5px;
}
.cliente-contactos-table th {
  font-size: 12px;
  font-weight: 700;
  color: #475569;
  text-transform: uppercase;
  letter-spacing: .3px;
  border-bottom: 1px solid #cbd5e1;
}
.cliente-contactos-table tbody tr + tr {
  border-top: 1px solid #f1f5f9;
}
.cliente-contactos-table .cli-contacto-del {
  padding: 4px 8px;
  line-height: 1;
  color: #b91c1c;
}
.cliente-envio-actions { display: flex; gap: 8px; }

/* Pestaña "Observaciones" del editor de cliente: textarea full-width
   pegada al ancho del modal y con altura cómoda. */
.cliente-observaciones-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cliente-observaciones-textarea {
  width: 100%;
  min-height: 320px;
  resize: vertical;
  font-size: 14px;
  line-height: 1.5;
  padding: 10px 12px;
}

/* Listado de clientes — buscador acotado (no ancho completo). */
.card .form-grid > .field.cliente-search-field {
  grid-column: auto;
  max-width: 520px;
}

/* Capilla Sixtina 2026-05-15: familia B (cliente-list-wrap / cliente-list-sticky /
   col-codigo / col-nombre) migrada a familia A (list-sticky-wrap / list-sticky-table /
   col-sticky-1 / col-sticky-2). Las reglas duplicadas se eliminaron aquí. El
   ancho mínimo de la columna "Nombre" (260px) se trasladó a col-sticky-2 en el
   bloque F-FUT-4 más abajo. */

/* Filas de selección de proveedores en captura — hover via CSS para
   cumplir CSP sin 'unsafe-inline' (sprint seguridad sesión 2 2026-05-09). */
.cap-prov-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px;
  cursor: pointer;
  border-radius: 4px;
}
.cap-prov-row:hover {
  background: #f1f5f9;
}
.cap-prov-row-text {
  font-size: .92rem;
}

/* === v1.56 — Venta/Compra: header de grilla sticky + footer opaco ===========
   Pedido usuario 2026-05-10. La grilla de líneas (venta/compra/NC/ND/remito)
   tiene `table-wrap-autocomplete` que pone `overflow: visible` para que el
   dropdown de búsqueda no se recorte. Eso impide el sticky-en-overflow
   tradicional. La solución acá es anclar el thead al modal scrolleable
   (`.comprobante-modal-body { overflow-y: auto }`, ver bloque arriba):
   con `position: sticky; top: 0` el thead queda pegado al borde superior
   del modal mientras las filas y los headers de comprobante se desplazan.
   
   El z-index queda por debajo del dropdown de productos (`5000`) y por
   encima de las filas (~10).
*/
.comprobante-items-card thead th {
  position: sticky;
  top: 0;
  z-index: 6;
  background: #ffffff !important;
  box-shadow: inset 0 -1px 0 #e2e8f0;
}

/* Footer (.comprobante-save-bar) ya tiene `position: sticky; bottom: 0;
   background: #fff` desde v1.55+. Reforzamos con box-shadow para que la
   separación visual con las filas que pasen por debajo sea clara. Pedido
   usuario 2026-05-10: "fondo blanco que no permita ver lo de atrás". */
.comprobante-modal-body .comprobante-save-bar,
.comprobante-save-bar {
  background: #ffffff !important;
  box-shadow: 0 -6px 12px rgba(15, 23, 42, 0.08);
}

/* === 2026-05-11 — Banner global AFIP modo Homologación =====================
   Pedido usuario: cuando el ambiente AFIP está en HOMOLOGACION (testing) hay
   que dejar muy claro en todas las pantallas que los comprobantes no son
   fiscales. Banner sticky debajo del topbar, color ámbar, no se puede pasar
   por alto. Aparece sólo si state.catalogos.afip_modo === "HOMOLOGACION". */
.afip-modo-banner {
  background: #fef3c7;
  color: #92400e;
  border-bottom: 2px solid #f59e0b;
  padding: 10px 16px;
  font-size: 13px;
  text-align: center;
  font-weight: 500;
  z-index: 50;
}
.afip-modo-banner a {
  color: #7c2d12;
  text-decoration: underline;
  margin-left: 6px;
}

/* ----------------------------------------------------------------------
 * Modales con tabs en modo lectura
 *
 * Los editores master (clientes/proveedores/vendedores) y de producto
 * arrancan en modo lectura cuando se abren para "ver" un registro
 * existente — el botón "Modificar" abajo a la derecha es el que activa
 * la edición. El JS toggle `dataset.modoLectura="1"/"0"` en el modal y
 * además seta `disabled`/`readOnly` por input. Este bloque CSS es la
 * defensa adicional: bloquea pointer-events en TODOS los inputs/selects/
 * textareas del modal (incluso los de pestañas ocultas con display:none),
 * para que ningún wireup posterior pueda re-habilitar inputs de forma
 * accidental por su lógica propia (ej. syncClienteDocumentoField al
 * cambiar tipo de documento). Reportado por usuario 2026-05-10:
 * "el botón Modificar solo afecta la primer pestaña, en las que siguen
 *  puedo hacer cambios sin tocarlo".
 * ---------------------------------------------------------------------- */
[data-modo-lectura="1"] .product-editor-body input:not([type="button"]):not([type="submit"]):not([type="reset"]),
[data-modo-lectura="1"] .product-editor-body select,
[data-modo-lectura="1"] .product-editor-body textarea,
[data-modo-lectura="1"] .product-editor-section input:not([type="button"]):not([type="submit"]):not([type="reset"]),
[data-modo-lectura="1"] .product-editor-section select,
[data-modo-lectura="1"] .product-editor-section textarea,
[data-modo-lectura="1"] .product-editor-panel input:not([type="button"]):not([type="submit"]):not([type="reset"]),
[data-modo-lectura="1"] .product-editor-panel select,
[data-modo-lectura="1"] .product-editor-panel textarea {
  pointer-events: none !important;
  user-select: none;
  background-color: #f9fafb !important;
  cursor: not-allowed !important;
}
[data-modo-lectura="1"] .product-editor-body .client-account-tab input,
[data-modo-lectura="1"] .product-editor-body .client-account-tab select,
[data-modo-lectura="1"] .product-editor-body .client-account-tab textarea,
[data-modo-lectura="1"] .product-editor-body .client-account-tab input:not([type="button"]):not([type="submit"]):not([type="reset"]) {
  pointer-events: auto !important;
  user-select: auto;
  background-color: #fff !important;
  cursor: auto !important;
  opacity: 1;
}
/* Botones de "+ Agregar" / "ARCA" / etc. dentro de las tabs también
 * se bloquean en modo lectura — son acciones de edición. */
[data-modo-lectura="1"] .product-editor-body .btn,
[data-modo-lectura="1"] .product-editor-section .btn,
[data-modo-lectura="1"] .product-editor-panel .btn {
  pointer-events: none !important;
  opacity: 0.55;
  cursor: not-allowed !important;
}
[data-modo-lectura="1"] .product-editor-body .client-account-tab .btn {
  pointer-events: auto !important;
  opacity: 1;
  cursor: pointer !important;
}
/* Excepción: los botones de la barra de acciones (Modificar / Cancelar)
 * SIEMPRE deben funcionar para poder activar la edición o cerrar. */
[data-modo-lectura="1"] .product-editor-actions .btn,
[data-modo-lectura="1"] .product-editor-actions button,
[data-modo-lectura="1"] .actions .btn,
[data-modo-lectura="1"] #save-master,
[data-modo-lectura="1"] #save-product,
[data-modo-lectura="1"] #cancel-master,
[data-modo-lectura="1"] #cancel-edit-product,
[data-modo-lectura="1"] .product-modal-tab,
[data-modo-lectura="1"] .product-modal-tabs button {
  pointer-events: auto !important;
  opacity: 1;
  cursor: pointer !important;
}


/* =============================================================================
   Topbar full-width arriba + sidebar fija exactamente debajo (2026-05-11).
   Pedido del usuario: "la barra que tiene el título y termina en el botón
   Salir debe estar arriba de todo fija con el menú exactamente por debajo".
   Convertimos #app de flex (sidebar-izq + main-der) a grid 2-col x 3-fila:
     fila 1: topbar full-width (sticky top:0)
     fila 2: banner AFIP (opcional, mismo full-width)
     fila 3: sidebar (col1) + main (col2)
   Reglas previas de .sidebar (width:290px; position:sticky; height:100vh)
   quedan overrideadas más abajo.
============================================================================= */
/* Layout horizontal 2026-05-11 (pedido del usuario): NO MÁS sidebar lateral.
   Filas apiladas, las dos primeras sticky (siempre visibles al scroll):
     fila 1: topbar fina (search, badges, Mi cuenta, Salir) — sticky top:0
     fila 2: menú horizontal con dropdowns por grupo — sticky debajo
     fila 3: banner AFIP (opcional)
     fila 4: contenido principal (#view) */
#app {
  display: block !important;
  min-height: 100vh;
  /* Compensación para el header unificado (header-row 52 + menu 46 = 98px). */
  padding-top: 98px;
}
/* Topbar legacy oculta — su contenido ahora vive dentro del sidebar header-row. */
#app > .topbar.topbar-legacy-hidden {
  display: none !important;
}
#app > .topbar > div:nth-child(2) {
  flex: 0 1 auto;
  min-width: 0;
}
#app > .topbar #page-title {
  font-size: 14px;
  margin: 0;
  font-weight: 600;
  color: #fff;
  letter-spacing: .2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#app > .topbar #page-subtitle {
  display: none;
}
#app > .topbar .top-actions {
  /* Todo a la izquierda (sin margin-left:auto) para mantener lógica con
     el menú horizontal de abajo. */
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: nowrap;
}
#app > .topbar .global-master-search {
  position: relative;
  min-width: 220px;
  max-width: 320px;
  width: auto;
}
#app > .topbar .global-master-search input,
#app > .topbar .global-master-search .input {
  width: 100%;
  /* Override de la regla vieja `background:#fff` que hacía blanco sobre
     blanco con el topbar oscuro. */
  background: rgba(255, 255, 255, .12) !important;
  color: #fff !important;
  border: 1px solid rgba(255, 255, 255, .18) !important;
  border-radius: 999px;
  padding: 0 16px;
  height: 30px;
  font-size: 13px;
}
#app > .topbar .global-master-search input::placeholder {
  color: rgba(255, 255, 255, .55);
}
#app > .topbar .global-master-search input:focus {
  background: rgba(255, 255, 255, .18) !important;
  border-color: rgba(96, 165, 250, .6) !important;
  outline: none;
}
#app > .topbar .ml-status-badge {
  background: rgba(255, 255, 255, .08);
  color: #cbd5e1;
  border: 1px solid rgba(255, 255, 255, .12);
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .5px;
}
#app > .topbar .ml-status-badge.disconnected { color: #fca5a5; }
#app > .topbar .ml-status-badge.connected { color: #6ee7b7; }
#app > .topbar #current-user-badge {
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Botón mobile-menu-toggle: oculto en desktop (≥769px) porque el menú es
   horizontal, no drawer. */
@media (min-width: 769px) {
  #app > .topbar #mobile-menu-toggle {
    display: none !important;
  }
}
/* Inputs y botones de la topbar adaptados al fondo oscuro. */
#app > .topbar .input,
#app > .topbar input.input,
#app > .topbar select.input {
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .12);
  color: #fff;
  height: 32px;
  font-size: 13px;
}
#app > .topbar .input::placeholder { color: rgba(255, 255, 255, .45); }
#app > .topbar .input:focus {
  border-color: #60a5fa;
  background: rgba(255, 255, 255, .1);
  outline: none;
}
#app > .topbar .btn,
#app > .topbar .btn-light {
  background: rgba(255, 255, 255, .08);
  color: #e2e8f0;
  border: 1px solid rgba(255, 255, 255, .12);
  height: 32px;
  padding: 0 12px;
  font-size: 12.5px;
  font-weight: 500;
  border-radius: 6px;
  transition: background .12s, color .12s;
}
#app > .topbar .btn:hover,
#app > .topbar .btn-light:hover {
  background: rgba(96, 165, 250, .18);
  color: #fff;
}
#app > .topbar .btn-logout {
  background: rgba(220, 38, 38, .18);
  color: #fecaca;
  border-color: rgba(220, 38, 38, .35);
  height: 32px;
  padding: 0 14px;
  font-size: 12.5px;
  font-weight: 600;
  border-radius: 6px;
}
#app > .topbar .btn-logout:hover {
  background: #dc2626;
  color: #fff;
}
#app > .topbar .status {
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .1);
  color: #cbd5e1;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 12px;
}
#app > .topbar .btn-candado {
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .12);
  color: #cbd5e1;
}
#app > .topbar .btn-candado:hover { background: rgba(255, 255, 255, .12); color: #fff; }
#app > .topbar .btn-candado.active { color: #34d399; }
/* La unión topbar↔menú: ambas son del mismo color #0f172a — el divisor es
   un border sutil casi imperceptible que solo marca la línea de separación. */
#app > .sidebar {
  position: fixed !important;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  width: 100% !important;
  height: auto !important;
  /* Bloque header unificado: header-row (44) + menu (44) = 88px. */
  background: var(--primary-deep, #1e3a8a);
  color: var(--on-primary, #fff);
  padding: 0 !important;
  overflow: visible !important;
  border-top: 0;
  border-bottom: 1px solid rgba(96, 165, 250, .28);
  box-shadow: 0 4px 14px rgba(30, 58, 138, .35);
  display: block;
  box-sizing: border-box;
  transform: none !important;
}
/* Fila superior del header dentro del sidebar — buscador + título + badges. */
#app > .sidebar .header-row {
  height: 52px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 20px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
  background: linear-gradient(180deg, var(--primary-dark, #1e40af) 0%, var(--primary-deep, #1e3a8a) 100%);
}
#app > .sidebar .header-row .header-title {
  flex: 0 1 auto;
  min-width: 0;
}
#app > .sidebar .header-row #page-title {
  font-size: 18px;
  margin: 0;
  font-weight: 700;
  color: #fff;
  letter-spacing: .2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#app > .sidebar .header-row #page-subtitle {
  display: none;
}
#app > .sidebar .header-row .top-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: nowrap;
}
/* Bloque de íconos de estado (candado, campana, ML) a la izquierda del
   buscador. Todos en línea horizontal con gap fijo. */
#app > .sidebar .header-row .header-status-icons {
  display: flex !important;
  align-items: center;
  gap: 6px;
  margin-right: 4px;
}
#app > .sidebar .header-row .header-status-icons .btn-candado,
#app > .sidebar .header-row .header-status-icons .menu-icon-btn {
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(255, 255, 255, .2);
  color: #fff;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  padding: 0;
  transition: background .12s, border-color .12s;
}
#app > .sidebar .header-row .header-status-icons .btn-candado:hover,
#app > .sidebar .header-row .header-status-icons .menu-icon-btn:hover {
  background: rgba(255, 255, 255, .22);
  border-color: rgba(255, 255, 255, .35);
}
#app > .sidebar .header-row .header-status-icons .btn-candado.active {
  background: rgba(52, 211, 153, .22);
  border-color: rgba(52, 211, 153, .5);
  color: #6ee7b7;
}
#app > .sidebar .header-row .header-status-icons .ml-status-badge {
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(255, 255, 255, .2);
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  color: #cbd5e1;
  display: inline-flex;
  align-items: center;
}
#app > .sidebar .header-row .header-status-icons .ml-status-badge.disconnected { color: #fca5a5; }
#app > .sidebar .header-row .header-status-icons .ml-status-badge.connected { color: #6ee7b7; }
#app > .sidebar .header-row .global-master-search {
  position: relative;
  min-width: 240px;
  max-width: 360px;
  width: auto;
}
#app > .sidebar .header-row .global-master-search input,
#app > .sidebar .header-row .global-master-search .input {
  width: 100%;
  background: rgba(255, 255, 255, .14) !important;
  color: #fff !important;
  border: 1px solid rgba(255, 255, 255, .22) !important;
  border-radius: 999px;
  padding: 0 16px;
  height: 30px;
  font-size: 13px;
}
#app > .sidebar .header-row .global-master-search input::placeholder {
  color: rgba(255, 255, 255, .55);
}
#app > .sidebar .header-row .global-master-search input:focus {
  background: rgba(255, 255, 255, .2) !important;
  border-color: rgba(147, 197, 253, .7) !important;
  outline: none;
}
#app > .sidebar .header-row #current-user-badge {
  background: rgba(255, 255, 255, .1);
  color: #e0e7ff;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, .14);
}
#app > .sidebar .header-row #api-status {
  background: rgba(255, 255, 255, .08);
  color: #cbd5e1;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 11.5px;
  border: 1px solid rgba(255, 255, 255, .12);
}
#app > .sidebar .header-row #topbar-empresa-switch {
  background: rgba(255, 255, 255, .14) !important;
  color: #fff !important;
  border: 1px solid rgba(255, 255, 255, .22) !important;
  height: 28px;
  font-size: 12.5px;
  border-radius: 6px;
  padding: 0 10px;
}
/* Options del select desplegado: en muchos browsers se renderizan con
   fondo blanco — si el `color` del select es blanco, el texto queda
   invisible. Forzamos negro sobre blanco solo para las options. */
#app > .sidebar .header-row #topbar-empresa-switch option {
  background: #fff !important;
  color: #1e293b !important;
}
/* Dropdown "Mi cuenta" en la header-row: botón translúcido con dropdown
   anclado a la derecha. Inherita la lógica del .menu-group/.menu-parent
   pero con estilo propio para encajar en el header. */
.header-mi-cuenta {
  position: relative;
  height: 32px;
  display: inline-flex;
  align-items: center;
}
.header-mi-cuenta .menu-parent {
  /* Estilo premium ERP: gradiente azul suave + sombra elegante + ícono de
     usuario. Texto blanco en negrita. */
  background: linear-gradient(135deg, rgba(255, 255, 255, .22) 0%, rgba(255, 255, 255, .12) 100%) !important;
  border: 1px solid rgba(255, 255, 255, .35) !important;
  color: #ffffff !important;
  font-size: 13.5px;
  font-weight: 700 !important;
  letter-spacing: .25px;
  height: 36px;
  padding: 0 16px 0 12px;
  border-radius: 10px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: background .15s ease, border-color .15s ease, transform .1s ease, box-shadow .15s ease;
  box-shadow: 0 2px 8px rgba(15, 23, 42, .12), inset 0 1px 0 rgba(255, 255, 255, .15);
  white-space: nowrap;
}
.header-mi-cuenta .menu-parent .mi-cuenta-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .9);
  color: #1e3a8a;
  font-size: 12px;
  flex-shrink: 0;
}
.header-mi-cuenta .menu-parent .mi-cuenta-label {
  display: inline-block;
}
.header-mi-cuenta .menu-parent::after {
  content: "▾";
  font-size: 10px;
  opacity: .85;
  color: #fff;
  margin-left: 2px;
}
.header-mi-cuenta .menu-parent:hover {
  background: linear-gradient(135deg, rgba(255, 255, 255, .3) 0%, rgba(255, 255, 255, .18) 100%) !important;
  border-color: rgba(255, 255, 255, .5) !important;
  box-shadow: 0 4px 14px rgba(15, 23, 42, .22), inset 0 1px 0 rgba(255, 255, 255, .25);
  transform: translateY(-1px);
}
.header-mi-cuenta .menu-parent:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(15, 23, 42, .15);
}
.header-mi-cuenta .submenu {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  /* Desplazado 12px hacia la derecha respecto al borde derecho del botón —
     así el contenido no queda apretado contra el borde del header. */
  right: -12px;
  min-width: 260px;
  max-width: calc(100vw - 24px);
  background: #111e36;
  border: 1px solid rgba(96, 165, 250, .25);
  border-radius: 10px;
  box-shadow: 0 14px 32px rgba(0, 0, 0, .35);
  padding: 8px 0;
  z-index: 1100;
  flex-direction: column;
  animation: submenuFadeIn .15s ease-out;
}
.header-mi-cuenta:hover .submenu,
.header-mi-cuenta .submenu.open {
  display: flex !important;
}
.header-mi-cuenta .submenu .menu-item {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 22px;
  background: transparent;
  border: 0;
  color: #e2e8f0;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  text-align: left;
  width: 100%;
  border-radius: 0;
  transition: background .12s, color .12s, padding .12s;
}
.header-mi-cuenta .submenu .menu-item:hover {
  background: rgba(96, 165, 250, .18);
  color: #fff;
  padding-left: 26px;
}
.header-mi-cuenta .menu-item-danger {
  color: #fca5a5 !important;
}
.header-mi-cuenta .menu-item-danger:hover {
  background: rgba(220, 38, 38, .22) !important;
  color: #fee2e2 !important;
}
#app > .sidebar .header-row #mobile-menu-toggle {
  background: transparent;
  border: 0;
  color: #fff;
  font-size: 22px;
  cursor: pointer;
  padding: 0;
  width: 32px;
  height: 32px;
  display: none;
}
#app > .sidebar .menu {
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 2px;
  padding: 0 14px;
  overflow-x: visible;
  overflow-y: visible;
  height: 100%;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,.15) transparent;
}
/* Íconos a la izquierda del menú: candado, campana CRM, badge ML. */
.menu-left-icons {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px 0 0;
  margin-right: 8px;
  border-right: 1px solid rgba(255, 255, 255, .12);
  height: 100%;
}
.menu-left-icons .btn-candado,
.menu-left-icons .menu-icon-btn {
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .14);
  color: #dbeafe;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  padding: 0;
  transition: background .12s, color .12s, border-color .12s;
}
.menu-left-icons .btn-candado:hover,
.menu-left-icons .menu-icon-btn:hover {
  background: rgba(255, 255, 255, .16);
  color: #fff;
}
.menu-left-icons .btn-candado.active {
  background: rgba(52, 211, 153, .18);
  border-color: rgba(52, 211, 153, .45);
  color: #6ee7b7;
}
.menu-left-icons .ml-status-badge {
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .14);
  padding: 5px 10px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  color: #cbd5e1;
}
.menu-left-icons .ml-status-badge.disconnected { color: #fca5a5; }
.menu-left-icons .ml-status-badge.connected { color: #6ee7b7; }
/* Dropdown "Mi cuenta" anclado a la derecha del menú. Combinamos
   `margin-left: auto` (empuja al final del flex row) con `order: 999`
   para garantizar que vaya al final aunque el HTML lo ponga en otro
   orden, y `position: relative` para que el dropdown se ancle a este
   elemento. */
.menu-mi-cuenta {
  margin-left: auto !important;
  order: 999 !important;
  border-left: 1px solid rgba(255, 255, 255, .12);
  padding-left: 4px;
}
#app > .sidebar .menu-mi-cuenta .menu-parent {
  padding: 0 18px;
  font-weight: 600;
  color: #fff;
}
#app > .sidebar .submenu.submenu-right {
  left: auto;
  right: 0;
  border-radius: 0 0 0 10px;
}
#app > .sidebar .menu-item-danger {
  color: #fca5a5 !important;
}
#app > .sidebar .menu-item-danger:hover {
  background: rgba(220, 38, 38, .22) !important;
  color: #fee2e2 !important;
}
#app > .sidebar .menu::-webkit-scrollbar { height: 4px; }
#app > .sidebar .menu::-webkit-scrollbar-thumb { background: rgba(255,255,255,.15); border-radius: 2px; }
#app > .sidebar .menu-group {
  position: relative;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  height: 100%;
}
#app > .sidebar .menu-parent,
#app > .sidebar .menu-group.single .menu-item {
  display: inline-flex;
  align-items: center;
  height: 46px;
  padding: 0 18px;
  background: transparent;
  border: 0;
  color: #dbeafe;
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: .15px;
  cursor: pointer;
  border-radius: 0;
  white-space: nowrap;
  transition: background .15s ease, color .15s ease, box-shadow .15s ease;
  position: relative;
}
#app > .sidebar .menu-parent::after {
  content: "▾";
  font-size: 9px;
  margin-left: 6px;
  opacity: .55;
  transition: transform .15s ease;
}
#app > .sidebar .menu-group:hover .menu-parent::after,
#app > .sidebar .menu-group .submenu.open ~ .menu-parent::after {
  transform: rotate(-180deg);
  opacity: 1;
}
#app > .sidebar .menu-parent:hover,
#app > .sidebar .menu-group.single .menu-item:hover {
  background: rgba(255, 255, 255, .07);
  color: #fff;
}
#app > .sidebar .menu-item.active,
#app > .sidebar .menu-group.single .menu-item.active {
  background: rgba(96, 165, 250, .14);
  color: #fff;
  box-shadow: inset 0 -3px 0 #60a5fa;
}
#app > .sidebar .menu-group:has(.menu-item.active) > .menu-parent {
  color: #fff;
  background: rgba(96, 165, 250, .1);
  box-shadow: inset 0 -3px 0 #60a5fa;
}
#app > .sidebar .submenu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 240px;
  background: #111e36;
  border: 1px solid rgba(96, 165, 250, .15);
  border-radius: 0 0 10px 10px;
  box-shadow: 0 14px 32px rgba(0, 0, 0, .35);
  padding: 8px 0;
  z-index: 1001;
  flex-direction: column;
  animation: submenuFadeIn .15s ease-out;
}
@keyframes submenuFadeIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
#app > .sidebar .submenu.open,
#app > .sidebar .menu-group:hover .submenu {
  display: flex !important;
}
#app > .sidebar .submenu .menu-item {
  display: flex;
  align-items: center;
  height: 38px;
  padding: 0 18px;
  background: transparent;
  border: 0;
  color: #e2e8f0;
  font-size: 13px;
  font-weight: 400;
  cursor: pointer;
  white-space: nowrap;
  text-align: left;
  width: 100%;
  border-radius: 0;
  transition: background .12s, color .12s;
}
#app > .sidebar .submenu .menu-item:hover {
  background: rgba(96, 165, 250, .18);
  color: #fff;
  padding-left: 22px;
}
#app > .sidebar .submenu .menu-item.active {
  background: rgba(96, 165, 250, .22);
  color: #fff;
  font-weight: 500;
  border-left: 3px solid #60a5fa;
  padding-left: 15px;
}
#app > .sidebar .sidebar-mobile-footer {
  display: none !important;
}
/* MODO-MOBILE F0 (2026-08-02): default oculto en la hoja base. styles-mobile
   (gateada por el media del <link>) lo muestra con inline-flex !important.
   Antes lo "ocultaba" el propio styles-mobile fuera de su wrapper, pero esa
   hoja no aplica en desktop, y con el modo forzado-escritorio en el celu
   tampoco — el default tiene que vivir acá. */
.mobile-topbar-logout {
  display: none;
}
#app > #afip-modo-banner {
  position: fixed !important;
  top: 98px;
  left: 0;
  right: 0;
  z-index: 998;
}
/* Si el banner AFIP está visible, sumar altura al padding-top del app. */
#app:has(> #afip-modo-banner:not([style*="display:none"]):not([style*="display: none"])) {
  padding-top: 122px;
}
#app > .main {
  width: 100%;
  min-width: 0;
}
/* Reducir el espacio entre el bloque topbar+menú y el contenido (KPIs).
   Antes era padding:28px (1700) — ahora 10px arriba y mantenemos los
   laterales/abajo para que no se vea pegado al borde.
   2026-05-16: excluimos .is-listado. El selector #app > .main > .view tiene
   especificidad (1,0,2) que vencía al (0,2,0) de .view.is-listado incluso
   con !important, aplicando padding-bottom:24px y empujando el footer de la
   tabla fuera del viewport. La variante .is-listado ya usa padding:6px 24px 0. */
#app > .main > .view:not(.is-listado) {
  padding: 10px 24px 24px !important;
}

/* =============================================================================
   Premium ILUSOFT dialog (post-save de venta y otros momentos celebratorios).
   Tono pedido por el usuario 2026-05-10: mismo lenguaje del login premium
   del ERP — fondo azul oscuro con gradiente, badge ILUSOFT, tipografía
   moderna. Se invoca desde `confirmDialogPremium(message, opts)`. No
   reemplaza el `confirmDialog` estándar (que sigue sobrio para el resto).
============================================================================= */
.premium-dialog-backdrop {
  background: rgba(15, 23, 42, .72);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 10000;
}
.premium-dialog {
  background: linear-gradient(135deg, #1a2233 0%, #0f1419 100%);
  color: #e6e8ec;
  border-radius: 18px;
  padding: 0;
  overflow: hidden;
  box-shadow: 0 30px 60px rgba(0, 0, 0, .45), 0 0 0 1px rgba(255, 255, 255, .04);
  width: min(460px, 92vw);
  font-family: 'Montserrat', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  animation: premiumDialogIn .2s ease-out;
}
@keyframes premiumDialogIn {
  from { opacity: 0; transform: translateY(8px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.premium-dialog-hero {
  position: relative;
  padding: 30px 34px 18px;
  background:
    radial-gradient(circle at 0% 0%, rgba(96, 165, 250, .25), transparent 55%),
    radial-gradient(circle at 100% 0%, rgba(252, 165, 165, .12), transparent 50%),
    linear-gradient(135deg, #1e40af 0%, #1e3a8a 100%);
}
.premium-dialog-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 20% 50%, rgba(255, 255, 255, .06), transparent 40%),
    repeating-linear-gradient(45deg, transparent 0 12px, rgba(255, 255, 255, .015) 12px 13px);
  pointer-events: none;
}
.premium-dialog-badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 3px;
  color: #bfdbfe;
  margin-bottom: 10px;
  text-transform: uppercase;
}
.premium-dialog-hero h3 {
  font-size: 22px;
  font-weight: 700;
  color: #fff;
  margin: 0;
  letter-spacing: .2px;
  position: relative;
  z-index: 1;
}
.premium-dialog-subtitle {
  margin: 4px 0 0;
  font-size: 12px;
  color: rgba(255, 255, 255, .55);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  font-weight: 500;
  position: relative;
  z-index: 1;
}
.premium-dialog-body {
  padding: 22px 34px 8px;
  font-size: 14px;
  line-height: 1.55;
  color: #cbd5e1;
}
.premium-dialog-footer {
  padding: 16px 34px 26px;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}
.premium-dialog-cancel,
.premium-dialog-ok {
  cursor: pointer;
  padding: 10px 22px;
  border-radius: 10px;
  font-weight: 600;
  font-size: 14px;
  transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.premium-dialog-cancel {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, .18);
  color: #cbd5e1;
}
.premium-dialog-cancel:hover {
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .28);
}
.premium-dialog-ok {
  background: linear-gradient(135deg, #3b82f6, #2563eb);
  color: #fff;
  border: none;
  box-shadow: 0 8px 22px rgba(37, 99, 235, .35);
}
.premium-dialog-ok:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 28px rgba(37, 99, 235, .5);
}
.premium-dialog-ok:active {
  transform: translateY(0);
}

/* F-FUT-4 (2026-05-14): clases genéricas de header sticky + columnas sticky para
   listados principales (proveedores, ventas, compras, pedidos, tesorería-listado,
   clientes). Productos queda excluido porque ya usa table-articulos-wrap propio.

   2026-05-14 update (TABLES-FULL-HEIGHT): las tablas usan
   `calc(100vh - --list-sticky-chrome-h)` en vez de 70vh fijo. La variable
   --list-sticky-chrome-h se define en :root y aplica a TODOS los .list-sticky-wrap.

   Capilla Sixtina 2026-05-15: renderClientesListado migrado a esta familia.
   La familia B (cliente-list-wrap/sticky/col-codigo/col-nombre como layout)
   fue eliminada — una sola regla cubre todos los listados. */
:root {
  /* Topbar (~60px) + page title block (~70px) + filtros/acciones (~70px)
     + paddings y márgenes (~20px) ≈ 220px. Si el chrome del ERP cambia
     mucho de altura habrá que ajustar este valor. */
  --list-sticky-chrome-h: 220px;
}
/* 2026-07-01 — REVERTIDO (ticket #157, Nicol): `will-change:transform` + `contain`
   + `translateZ(0)` sobre el scroll container rompían el scroll (rueda del mouse y
   flechas) en TODOS los listados/secciones. La ganancia de perf no lo compensa. El
   container queda como estaba (max-height + overflow) y el header sticky simple. El
   alivio de performance queda por el PAGE_SIZE_DEFAULT=50 (que no afecta el scroll). */
.list-sticky-wrap {
  max-height: calc(100vh - var(--list-sticky-chrome-h));
  overflow: auto;
}
/* 2026-07-02: scrollbar siempre visible y arrastrable en listados.
   Sin estos estilos, macOS/Chrome usan overlay-scrollbar que desaparece
   al no hacer scroll → el usuario no sabe que la tabla scrollea.
   - Firefox: thin + colores de tema.
   - WebKit: barra de 8px, thumb gris redondeado, track transparente.
   SIN scrollbar-gutter: stable — ese flag en un contenedor con overflow
   bidireccional (overflow-x + overflow-y) reserva 12px en AMBOS bordes
   (derecha para barra Y, abajo para barra X) incluso sin overflow real,
   lo que (a) corta la última columna del wrap, (b) rompe el thead sticky
   (el scroll container queda mal reconocido por Chromium con overflow
   bidireccional + border-radius) y (c) agrega espacio muerto al fondo.
   La barra custom sigue visible cuando hay overflow (overlay en macOS,
   barra normal en Windows/Linux). 2026-07-03 bugfix. */
.list-sticky-wrap {
  scrollbar-width: thin;
  scrollbar-color: #9ca3af #f3f4f6;
}
.list-sticky-wrap::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
.list-sticky-wrap::-webkit-scrollbar-track {
  background: #f3f4f6;
  border-radius: 4px;
}
.list-sticky-wrap::-webkit-scrollbar-thumb {
  background: #9ca3af;
  border-radius: 4px;
  border: 1px solid #f3f4f6;
  background-clip: padding-box;
}
.list-sticky-wrap::-webkit-scrollbar-thumb:hover {
  background: #6b7280;
  background-clip: padding-box;
}
.list-sticky-table thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  background: #f9fafb;
  background-clip: padding-box;
}
.list-sticky-table tbody tr {
  scroll-margin-top: 36px;
}
/* A+B 2026-05-14 — Sticky horizontal REMOVIDO en col-sticky-1/2 (Martín):
   generaba layers de compositing distintas que rompían el highlight
   selected/hover. Solo dejamos ancho mínimo y no-wrap. El header
   vertical sticky (thead) sigue. */
.list-sticky-table td.col-sticky-1,
.list-sticky-table th.col-sticky-1 {
  min-width: 110px;
  /* 2026-06-07: se quitó `max-width: 130px`. Con nowrap + overflow visible,
     los números de comprobante largos (ej. MERNET-0008-00009644, ~20 chars)
     se desbordaban del tope de 130px y pisaban la columna Fecha (col-sticky-2).
     Sin el cap, la celda se ajusta al contenido; el scroll horizontal del wrap
     (.list-sticky-wrap overflow-x:auto) absorbe el ancho extra. */
  white-space: nowrap;
}
.list-sticky-table td.col-sticky-2,
.list-sticky-table th.col-sticky-2 {
  white-space: nowrap;
}
.list-sticky-table td {
  white-space: nowrap;
}

/* CC-STICKY (2026-05-14): el header (Saldo + acciones) y los títulos de la
   tabla de detalle de cuenta corriente quedan sticky cuando el operador
   scrollea por la lista de movimientos. Aplica en:
   - openClienteCcModal (modal desde listado clientes)
   - renderCuentaClientes (route cc-clientes)
   - renderCuentaProveedores (route cc-proveedores)
   El scroll vive en `.comprobante-modal-body` (overflow-y: auto). Ambos
   elementos sticky usan `top: 0` y `top: <altura saldo>` para apilarse
   visualmente sin solaparse. */
#cc-detalle-modal-overlay .comprobante-modal-body {
  overflow-y: auto;
}
.cc-saldo-sticky {
  position: sticky;
  top: 0;
  z-index: 5;
  background: #fff;
}
.cc-thead-sticky thead th {
  position: sticky;
  /* Approximate height of .cc-saldo-sticky (card padding ~ 14px + h3 ~ 32px
     + actions margin ~ 14px = ~60px). Hardcodeo seguro: si el saldo crece,
     la thead se solapa ~10px pero sigue legible. */
  top: 60px;
  z-index: 2;
  background: #f9fafb;
  box-shadow: inset 0 -1px 0 0 #e5e7eb;
}

/* CC-ANCHO (2026-06-02): la columna Descripción de la tabla de movimientos
   CC se ensancha por textos largos (descripciones MERNET "Saldo inicial
   (MERNET)" + sub-línea de observaciones). Limitamos el ancho máximo y
   forzamos word-wrap para que la tabla entre en el modal sin scroll
   horizontal. Las columnas numéricas (Debe/Haber/Saldo/Pendiente) y las
   de fecha/tipo/número se controlan con white-space:nowrap para que no
   se partan. */
.cc-access-table table {
  table-layout: fixed;
  width: 100%;
}
/* Anchos de columnas fijos: sel(28) | fecha(80) | tipo(90) | numero(110) |
   desc(flex) | debe(80) | haber(80) | pendiente(80) | saldo(80) | estado(60) | acceso(70) */
.cc-access-table table th:nth-child(1),
.cc-access-table table td:nth-child(1) { width: 28px; padding-left: 4px; padding-right: 4px; }
.cc-access-table table th:nth-child(2),
.cc-access-table table td:nth-child(2) { width: 80px; white-space: nowrap; }
.cc-access-table table th:nth-child(3),
.cc-access-table table td:nth-child(3) { width: 90px; }
.cc-access-table table th:nth-child(4),
.cc-access-table table td:nth-child(4) { width: 110px; white-space: nowrap; }
/* Descripción: ancho flexible con max-width para no explotar la tabla */
.cc-access-table table th:nth-child(5),
.cc-access-table table td:nth-child(5) {
  max-width: 220px;
  overflow-wrap: break-word;
  word-break: break-word;
}
.cc-access-table table th:nth-child(6),
.cc-access-table table td:nth-child(6) { width: 80px; white-space: nowrap; text-align: right; }
.cc-access-table table th:nth-child(7),
.cc-access-table table td:nth-child(7) { width: 80px; white-space: nowrap; text-align: right; }
.cc-access-table table th:nth-child(8),
.cc-access-table table td:nth-child(8) { width: 80px; white-space: nowrap; text-align: right; }
.cc-access-table table th:nth-child(9),
.cc-access-table table td:nth-child(9) { width: 80px; white-space: nowrap; text-align: right; }
.cc-access-table table th:nth-child(10),
.cc-access-table table td:nth-child(10) { width: 60px; }
.cc-access-table table th:nth-child(11),
.cc-access-table table td:nth-child(11) { width: 70px; }
/* Contenido MERNET: la sub-línea wrappea automáticamente por overflow-wrap.
   El font-size ya es 11px (definido inline en ccMernetAperturaDescHtml). */

/* En mobile (<=768px), el modal usa width 100% y el sticky sigue siendo
   útil porque la altura del modal puede ser limitada. No deshabilitamos
   acá (a diferencia de F-FUT-4) porque el CC modal no tiene mobile-cards. */

/* WELCOME-TEST (2026-05-14): pop-up de bienvenida para test@gmail.com
   con gatito SVG blanco y negro que rota infinito. Se muestra cada vez
   que el usuario entra (no se persiste). */
.welcome-test-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000050;
  animation: welcome-test-fadein 0.25s ease-out;
}
@keyframes welcome-test-fadein {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.welcome-test-modal {
  background: linear-gradient(180deg, #ffffff, #f8fafc);
  border-radius: 16px;
  padding: 28px 32px 24px;
  max-width: 460px;
  width: calc(100% - 32px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
  text-align: center;
  position: relative;
  animation: welcome-test-pop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes welcome-test-pop {
  from { transform: scale(0.7); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}
.welcome-test-close {
  position: absolute;
  top: 8px;
  right: 12px;
  background: transparent;
  border: 0;
  font-size: 24px;
  color: #94a3b8;
  cursor: pointer;
  line-height: 1;
  padding: 4px 8px;
  border-radius: 4px;
}
.welcome-test-close:hover { color: #1e293b; background: #f1f5f9; }
.welcome-test-cat {
  display: flex;
  justify-content: center;
  margin: 4px 0 14px;
}
.welcome-test-cat svg {
  /* Animación: gira indefinidamente. 4s por vuelta = suave, no marea. */
  animation: welcome-test-spin 4s linear infinite;
  transform-origin: 60px 60px;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.12));
}
@keyframes welcome-test-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.welcome-test-modal h2 {
  margin: 0 0 12px;
  font-size: 20px;
  color: #0d6e4e;
  font-weight: 700;
}
.welcome-test-mensaje {
  margin: 0 0 10px;
  font-size: 14px;
  color: #334155;
  line-height: 1.5;
}
.welcome-test-actions {
  margin-top: 18px;
  display: flex;
  justify-content: center;
}
.welcome-test-actions .btn {
  padding: 10px 24px;
  font-size: 15px;
  font-weight: 600;
}
/* Pausar la rotación si el usuario prefiere reduce motion (a11y). */
@media (prefers-reduced-motion: reduce) {
  .welcome-test-cat svg { animation: none; }
  .welcome-test-overlay,
  .welcome-test-modal { animation: none; }
}

/* === TABLES-OPTIN (2026-05-14) ============================================
   Cuarto intento de full-height para listados, ahora OPT-IN PURO. Pedido
   de Martín: "después de 3 parches que se rompían entre sí, vamos por
   opt-in: solo los .view con clase explícita reciben el modelo flex".

   Por qué los 3 anteriores fallaron:
   - TABLES-FULL-HEIGHT (calc 100vh - 220px fijo): el chrome de cada
     listado varía 180-280px → hueco gris o cortado.
   - TABLES-FLEX-HEIGHT v1 (height: 100dvh): 100dvh era el viewport
     completo, no el área restante después de la topbar/banner.
   - TABLES-FLEX-HEIGHT v2 (position: absolute + inset 0): .main no
     tenía altura propia → colapsó al alto del contenido restante
     cuando el .view salió del flujo. Reportado con 1 fila en Ventas
     y gris abajo.

   Estrategia A opt-in:
   - JS agrega `.view.is-listado` SOLO en las 12 rutas problemáticas
     (productos, clientes, proveedores, ventas-listado, compras-listado,
     listas-precios, productos-ofertas, depositos, stock, transferencias,
     tesoreria-listado, catalogos). Ver TABLES_OPTIN_LISTADO_ROUTES en
     app.js.
   - `.main:has(>.view.is-listado)` se convierte en flex column con
     altura fija al viewport (descontando banner AFIP). El navegador
     reparte solo entre el chrome de la página y el listado.
   - Las pantallas NO listado (dashboard, comprobante, ABMs, configs)
     quedan IGUAL — la regla `.main` base no se toca.

   Sin cambios a `#app`, `.main` base, `.view` base. Cero riesgo en
   pantallas no listadas. Reversible: sacar la clase y vuelve al
   comportamiento previo.
*/

/* .main solo se vuelve container flex cuando contiene un listado.
   Las demás pantallas siguen exactamente como antes.
   2026-05-16 FIX R4: #app tiene padding-top: 98px (header-row 52px + menú
   46px, ver línea 6781). Con height:100vh el .main desbordaba el viewport
   exactamente 98px hacia abajo, dejando la paginación (footer del listado)
   fuera de la pantalla. El fix descuenta esos 98px del height. */
.main:has(> .view.is-listado) {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 98px);
  overflow: hidden;
}

/* Si el banner AFIP está visible, #app recibe `padding-top: 122px` en vez
   de los 98px habituales (ver línea 7422). Descontamos 122px en total. */
#app:has(> #afip-modo-banner:not([style*="display:none"]):not([style*="display: none"])) > .main:has(> .view.is-listado) {
  height: calc(100vh - 122px);
}

/* En mobile (≤768px) el layout es block: .sidebar es drawer fixed,
   .main ocupa toda la pantalla en flujo normal. Cambiamos a 100dvh
   para colapsar el chrome del browser móvil. */

/* El .view del listado consume todo el alto del .main vía flex. */
.view.is-listado {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* PDF-LISTADOS-PADDING (2026-05-14): hipótesis Z del agente — quitar
     padding-bottom del .view.is-listado. El gap del flex (6px) ya
     separa las cards entre sí; el padding-bottom solo agregaba aire
     muerto debajo de la última card. Era `6px 24px` (top y bottom 6px),
     ahora `6px 24px 0` (bottom 0). */
  padding: 6px 24px 0 !important;
  gap: 6px;
}

/* La última card del listado (la que contiene el wrap scrolleable) no
   necesita margin-bottom — el padding del .view ya cubre el límite
   inferior, y el gap del flex maneja la separación entre cards. */
.view.is-listado > .card:last-child {
  margin-bottom: 0 !important;
}

/* TABLES-V5 (2026-05-14): ÚNICA regla para el alto interno del listado.
   No usa :has(), no usa calc, no usa !important — solo flex distribution
   simple basado en :first-child / :last-child.

   Diagnóstico de Martín confirmado con DevTools: las cards no tenían
   flex-grow, el sobrante quedaba como espacio en blanco abajo. Las 4
   reglas viejas con `height: calc(100vh - Npx)` se borraron en el
   commit anterior.

   Cómo funciona ahora:
   - .view.is-listado es flex column (regla previa) y recibe altura del
     .main flex container (también de TABLES-OPTIN).
   - TODAS las cards directas del .view.is-listado arrancan como
     `flex: 0 0 auto` (toman su tamaño natural — chrome / filtros).
   - La ÚLTIMA card (la del listado) sobreescribe a `flex: 1 1 auto`
     con `min-height: 0`, lo que la fuerza a absorber TODO el espacio
     sobrante del .view.
   - El wrap interno (.table-wrap / .table-articulos-wrap /
     .list-sticky-wrap) hereda `flex: 1 1 auto`
     + `min-height: 0` para scrollear adentro.
     Capilla Sixtina 2026-05-15: .cliente-list-wrap eliminado.

   Cuando el listado tiene UNA SOLA card (productos, clientes, etc.),
   :last-child es también :first-child y la regla de :last-child gana
   por especificidad (+1 pseudo-clase). flex: 1 1 auto aplica. OK.

   Cuando hay 2+ cards (filtros + tabla), las de chrome son 0 0 auto,
   la última es 1 1 auto. Reparto natural. */
.view.is-listado > .card {
  flex: 0 0 auto;
}
.view.is-listado > .card:last-child {
  flex: 1 1 auto;
  min-height: 0;
  /* A+B 2026-05-14: card flex column ⇒ chrome (título + buscador +
     filtros + fila acciones) anclado arriba, SOLO el wrap scrolea. Esto
     hace que el wrap llegue hasta el fondo de la pantalla sin franja
     muerta y que los filtros queden fijos al scrollear. */
  display: flex;
  flex-direction: column;
}
/* Hijos directos del card que no son el wrap: chrome (title-row,
   form-grid de búsqueda y de filtros, fila de acciones, paginación).
   NO deben encogerse cuando la card flex distribuye espacio. Solo el
   wrap (con flex: 1 1 auto abajo) absorbe el sobrante.
   2026-07-07 (bug paginación oculta en desktop, ver Memorias del sistema.md):
   se excluye también `[id$="-tabla-inner"]` — el wrapper que envuelve
   wrap+paginación (patrón "buscadores homogéneos / repintado parcial",
   2026-07-01, commits fc6958f/a5bc90d/68eecb7) para que reciba SU PROPIO
   flex:1 1 auto en la regla de abajo en vez de quedar flex-shrink:0 sin
   flex-grow ni display:flex (lo que hacía que el .list-sticky-wrap de
   adentro ignorara su flex:1 1 auto, creciera con TODAS las filas y
   empujara la paginación fuera del viewport, recortada por el
   overflow:hidden de .view.is-listado). */
.view.is-listado > .card:last-child > *:not(.table-wrap):not(.table-articulos-wrap):not(.list-sticky-wrap):not([id$="-tabla-inner"]) {
  flex-shrink: 0;
}
/* 2026-07-07: el wrapper `#*-tabla-inner` (ver comentario arriba) es hijo
   directo del card is-listado y contiene wrap + paginación. Necesita ser
   flex column con flex:1 1 auto — igual que el card mismo (regla de
   arriba) — para que el .list-sticky-wrap de adentro (que tiene
   flex:1 1 auto + min-height:0, ver más abajo) reciba un contexto flex
   real y scrollee internamente en vez de crecer con el contenido. Sin
   esto el bug afecta a TODOS los listados con este wrapper: productos,
   clientes, proveedores, ventas, compras, tesorería, CC, stock,
   valores-oficiales, transferencias, empleados, usuarios, papelera. */
.view.is-listado > .card:last-child > [id$="-tabla-inner"] {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}
/* 2026-07-07: dentro del wrapper flex-column de arriba, la paginación
   (hermana del wrap, no cubierta por la regla de flex-shrink:0 porque
   esa apunta a hijos DIRECTOS de .card, y ahora la paginación cuelga de
   `#*-tabla-inner`) no debe encogerse — solo el .list-sticky-wrap (con
   flex:1 1 auto) absorbe el espacio sobrante. */
.view.is-listado > .card:last-child > [id$="-tabla-inner"] > .pagination {
  flex-shrink: 0;
}
/* 2026-05-16 R5: protección general para cualquier elemento que no sea
   .card dentro del view is-listado (ej: futuros chips, banners inline).
   R6 (fix definitivo): tienda-web-productos/clientes y ml-publicaciones ya
   mueven sus .page-tabs DENTRO de la primera .card — el view solo tiene
   .card como hijos directos, igual que ventas/clientes/etc. Esta regla
   queda como defensa ante futuros usos no previstos. */
.view.is-listado > :not(.card) {
  flex-shrink: 0;
}
/* A+B 2026-05-14: TODAS las celdas (td y th) de listados is-listado en
   una sola línea. Si la suma de anchos excede el viewport, aparece
   scroll horizontal (gracias a overflow-x:auto del wrap más abajo).
   La regla legacy `.table-wrap td white-space:normal !important` ya
   está excluida con :not() para list-sticky-wrap,
   así que acá no hace falta !important. El listado de Artículos
   (.product-list-table) es el modelo: nowrap simple sin overrides.
   Capilla Sixtina 2026-05-15: .cliente-list-table/.cliente-list-wrap
   eliminados (migrados a .list-sticky-table/.list-sticky-wrap). */
.view.is-listado > .card:last-child .list-sticky-table th,
.view.is-listado > .card:last-child .list-sticky-table td,
.view.is-listado > .card:last-child .product-list-table th,
.view.is-listado > .card:last-child .product-list-table td {
  white-space: nowrap;
}
.view.is-listado > .card:last-child .table-wrap,
.view.is-listado > .card:last-child .table-articulos-wrap,
.view.is-listado > .card:last-child .list-sticky-wrap {
  flex: 1 1 auto;
  min-height: 0;
  /* A+B 2026-05-14: cancela el max-height legacy de .list-sticky-wrap
     dentro de is-listado. Con flex column del card, el wrap absorbe
     la altura disponible hasta el fondo de la pantalla sin cap legacy.
     Capilla Sixtina 2026-05-15: .cliente-list-wrap ya no existe como clase. */
  max-height: none;
  /* A+B 2026-05-14: scroll horizontal explícito para que las filas
     queden en UNA sola línea sin importar el ancho del viewport
     (pedido de Martín). Sin overflow-x:auto el browser podía comprimir
     las columnas y wrappear el contenido a varias líneas. */
  overflow-x: auto;
  /* TABLES-V5 SCROLL-DEFENSE (2026-05-14): defensas cero-riesgo
     contra "scroll vuelve para arriba" (#28). Pedido de Martín
     post-deploy de TABLES-OPTIN.
     - overflow-y: scroll ⇒ la barra vertical queda SIEMPRE visible
       (objetivo de 94104c3) sin necesitar scrollbar-gutter:stable que
       rompía el thead sticky + cortaba la última columna. En is-listado
       los listados siempre tienen múltiples filas → la barra se ve útil.
       overscroll-behavior: contain compensa el posible "salto" residual.
     - overflow-anchor: auto ⇒ si el browser detecta cambio de contenido
       arriba (re-render parcial, sortable, autocomplete), ancla la
       posición del scroll al elemento visible más cercano en vez de
       saltar al top.
     - scroll-behavior: auto ⇒ explícito "no smooth", evita que un
       hash-change / setPage dispare animación que empuja al top.
     - overscroll-behavior: contain ⇒ en mobile/touchpad, evita que el
       scroll del wrap propague al body cuando llega al borde (que era
       lo que parecía "saltar al top"). */
  overflow-y: scroll;
  overflow-anchor: auto;
  scroll-behavior: auto;
  overscroll-behavior: contain;
}
/* 2026-07-03: en mobile el wrap is-listado vuelve a overflow:visible (el
   layout block del mobile ya no usa el flex + max-height del shell, así
   que el scroll del listado lo maneja la página). Colocado DESPUÉS de la
   regla de overflow-y:scroll (misma especificidad, mayor posición → gana). */

/* Bug scroll #2 — 2026-05-20: detalle inline de comprobante (viewDocument)
   dentro de .view.is-listado sin usar .comprobante-page ni .table-wrap sticky.
   El card queda cortado a la altura visible porque .view.is-listado tiene
   overflow:hidden y el card tiene flex:1 1 auto sin overflow propio.
   La tabla interna usa .table-wrap-autocomplete, que queda EXCLUIDA del
   selector :not(.table-wrap-autocomplete) del scroll del wrap.

   Fix: cuando el card directo del view.is-listado NO contiene ningún
   .table-wrap interno (ni sticky, ni autocomplete), el card mismo es el
   contenedor scrolleable. Esto cubre viewDocument (ventas/compras) y
   cualquier otro detalle inline futuro que siga el mismo patrón.

   NO aplica a los listados tabulares: esos siempre tienen .table-wrap /
   .list-sticky-wrap / .table-articulos-wrap como hijo directo del card,
   por lo que el :has(.table-wrap) los excluye. */
.view.is-listado > .card:not(:has(.table-wrap)):not(:has(.list-sticky-wrap)):not(:has(.table-articulos-wrap)) {
  overflow-y: auto;
  min-height: 0;
}

/* === MOBILE-LITE (2026-05-14) =========================================
   Vista mobile minimalista del ERP. Activación opt-in vía class
   `body.mobile-lite-mode` que JS pone al entrar en route mobile-lite-*.
   Cuando el body tiene la clase:
   - Sidebar legacy + topbar legacy + banner AFIP se ocultan
   - #app pasa a layout block normal (sin flex row)
   - .main toma todo el ancho
   - El chrome mobile-lite (topbar simple + bottom-nav) se monta dentro
     de #view por JS
*/
body.mobile-lite-mode { zoom: 1 !important; }
body.mobile-lite-mode > #app {
  display: block !important;
  min-height: 100dvh !important;
  padding: 0 !important;
}
body.mobile-lite-mode > #app > .sidebar,
body.mobile-lite-mode > #app > #topbar,
body.mobile-lite-mode > #app > #afip-modo-banner {
  display: none !important;
}
body.mobile-lite-mode > #app > .main {
  width: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  display: block !important;
  height: auto !important;
}
body.mobile-lite-mode > #app > .main > #view {
  padding: 0 !important;
  margin: 0 !important;
  min-height: 100dvh !important;
  display: flex !important;
  flex-direction: column !important;
  background: #f1f5f9;
}

.mobile-lite-topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  height: 52px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
  color: #fff;
  box-shadow: 0 2px 8px rgba(0,0,0,.25);
}
.mobile-lite-topbar-title {
  flex: 1;
  font-size: 16px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: -.2px;
}
.mobile-lite-toggle-clasica,
.mobile-lite-logout-btn {
  background: transparent;
  border: 0;
  color: rgba(255,255,255,.85);
  padding: 7px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  transition: background .15s;
}
.mobile-lite-toggle-clasica:active,
.mobile-lite-logout-btn:active {
  background: rgba(255,255,255,.15);
}

.mobile-lite-bottom-nav {
  position: sticky;
  bottom: 0;
  z-index: 50;
  height: 60px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: #fff;
  border-top: 1px solid #e5e7eb;
  box-shadow: 0 -2px 12px rgba(0,0,0,.08);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.mobile-lite-nav-btn {
  background: transparent;
  border: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  cursor: pointer;
  color: #94a3b8;
  font-size: 11px;
  padding: 4px 0;
  position: relative;
  transition: color .15s;
}
.mobile-lite-nav-btn.active { color: #1e293b; }
.mobile-lite-nav-btn.active::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 28px;
  height: 3px;
  background: #1e293b;
  border-radius: 0 0 4px 4px;
}
.mobile-lite-nav-btn.active .mobile-lite-nav-icon { transform: scale(1.12); }
.mobile-lite-nav-icon { font-size: 22px; line-height: 1; transition: transform .15s ease; }
.mobile-lite-nav-label { font-size: 10px; font-weight: 600; letter-spacing: .1px; }
.mobile-lite-bottom-nav.mobile-lite-bottom-nav-5 { grid-template-columns: repeat(5, 1fr); }
.mobile-lite-bottom-nav.mobile-lite-bottom-nav-5 .mobile-lite-nav-label { font-size: 9px; }
.mobile-lite-bottom-nav.mobile-lite-bottom-nav-5 .mobile-lite-nav-icon { font-size: 20px; }

.mobile-lite-content {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: #f1f5f9;
}
.mobile-lite-section {
  background: #fff;
  border-radius: 14px;
  padding: 16px;
  box-shadow: 0 1px 4px rgba(0,0,0,.06), 0 0 0 1px rgba(0,0,0,.03);
}
.mobile-lite-h2 { font-size: 16px; font-weight: 700; margin: 0 0 12px; color: #0f172a; letter-spacing: -.2px; }
.mobile-lite-h3 { font-size: 14px; font-weight: 600; margin: 12px 0 6px; color: #374151; }
.mobile-lite-cli-datos { display: flex; flex-direction: column; gap: 4px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; }
.mobile-lite-cli-field { display: flex; gap: 6px; font-size: 13px; line-height: 1.4; }
.mobile-lite-cli-label { color: #64748b; font-weight: 500; white-space: nowrap; min-width: 80px; }
.mobile-lite-cli-obs .mobile-lite-cli-label { min-width: 80px; }
.mobile-lite-cli-obs span:last-child { color: #475569; font-size: 12px; word-break: break-word; }
.mobile-lite-empty { color: #9ca3af; font-size: 13px; margin: 6px 0 0; text-align: center; }
.mobile-lite-error { color: #b91c1c; background: #fef2f2; padding: 12px; border-radius: 10px; margin: 12px; }
.mobile-lite-loading { color: #6b7280; text-align: center; padding: 32px 12px; }

.mobile-lite-tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.mobile-lite-tile {
  background: #fff;
  border-radius: 12px;
  padding: 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 88px;
  border: 1px solid #e9eef4;
  box-shadow: 0 1px 3px rgba(0,0,0,.05);
  transition: box-shadow .15s;
}
.mobile-lite-tile-clickable { cursor: pointer; }
.mobile-lite-tile-clickable:active { box-shadow: 0 0 0 2px #93c5fd; background: #f8fafc; }
.mobile-lite-tile-alert { background: #fff5f5; border-color: #fecaca; }
.mobile-lite-tile-icon { font-size: 20px; line-height: 1; }
.mobile-lite-tile-label { font-size: 11px; color: #64748b; font-weight: 500; text-transform: uppercase; letter-spacing: .4px; }
.mobile-lite-tile-value { font-size: 19px; font-weight: 700; color: #0f172a; letter-spacing: -.3px; }
.mobile-lite-tile-alert .mobile-lite-tile-value { color: #dc2626; }

.mobile-lite-tareas, .mobile-lite-movs { display: flex; flex-direction: column; gap: 0; }
.mobile-lite-tarea, .mobile-lite-mov {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  padding: 9px 2px;
  border-bottom: 1px solid #f1f5f9;
}
.mobile-lite-tarea:last-child, .mobile-lite-mov:last-child { border-bottom: 0; }
.mobile-lite-tarea-icon { font-size: 14px; }
.mobile-lite-tarea-txt { flex: 1; color: #334155; }
.mobile-lite-mov-fecha { color: #94a3b8; font-size: 11px; min-width: 68px; }
.mobile-lite-mov-desc { flex: 1; color: #334155; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mobile-lite-mov-importe { font-weight: 700; color: #0f172a; font-size: 13px; }
.mobile-lite-mov-importe.pos { color: #15803d; }
.mobile-lite-mov-importe.neg { color: #dc2626; }

.mobile-lite-section-actions { padding: 4px; background: transparent; box-shadow: none; }
.mobile-lite-action-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  background: #fff;
  border-radius: 12px;
  color: #1e293b;
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
  margin-bottom: 8px;
  border: 1px solid #e2e8f0;
  box-shadow: 0 1px 3px rgba(0,0,0,.05);
  transition: box-shadow .15s, background .15s;
}
.mobile-lite-action-link:last-child { margin-bottom: 0; }
.mobile-lite-action-link:active { background: #f8fafc; box-shadow: 0 0 0 2px #93c5fd; }

.mobile-lite-list {
  display: flex;
  flex-direction: column;
  margin: 8px 0 0;
  max-height: 60dvh;
  overflow-y: auto;
}
.mobile-lite-list-movs { max-height: 70dvh; }
.mobile-lite-list-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border-bottom: 1px solid #f3f4f6;
  cursor: pointer;
  background: #fff;
}
.mobile-lite-list-item:active { background: #f9fafb; }
.mobile-lite-list-item-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.mobile-lite-list-item-main strong {
  font-size: 14px;
  color: #0f172a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mobile-lite-list-item-sub { font-size: 11px; color: #6b7280; }
.mobile-lite-saldo {
  font-size: 13px;
  font-weight: 700;
  padding: 4px 8px;
  border-radius: 6px;
  white-space: nowrap;
}
.mobile-lite-saldo.zero { background: #f3f4f6; color: #6b7280; }
.mobile-lite-saldo.pos { background: #fef2f2; color: #991b1b; }
.mobile-lite-saldo.neg { background: #ecfdf5; color: #166534; }
.mobile-lite-cc-saldo {
  font-size: 14px;
  color: #374151;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 6px 0 10px;
}
.mobile-lite-back {
  background: transparent;
  border: 0;
  color: #2563eb;
  font-size: 13px;
  font-weight: 500;
  margin-bottom: 8px;
  padding: 4px 0;
  cursor: pointer;
}

.mobile-lite-field { margin-bottom: 12px; display: flex; flex-direction: column; gap: 4px; }
.mobile-lite-field label { font-size: 12px; color: #6b7280; font-weight: 600; }
.mobile-lite-input {
  width: 100%;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 15px;
  background: #fff;
  box-sizing: border-box;
  color: #0f172a;
  text-align: left;
}
.mobile-lite-input:focus { outline: 2px solid #60a5fa; outline-offset: 0; border-color: #60a5fa; }
.mobile-lite-btn-primary, .mobile-lite-btn-secondary {
  border: 0;
  border-radius: 8px;
  padding: 12px 14px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  width: 100%;
  margin: 8px 0 0;
}
.mobile-lite-btn-primary { background: #0f172a; color: #fff; }
.mobile-lite-btn-primary:disabled { background: #9ca3af; cursor: not-allowed; }
.mobile-lite-btn-secondary { background: #f3f4f6; color: #0f172a; border: 1px solid #e5e7eb; }
.mobile-lite-items { margin: 6px 0 8px; display: flex; flex-direction: column; gap: 8px; }
.mobile-lite-item-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px;
  background: #f9fafb;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
}
.mobile-lite-item-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.mobile-lite-item-main strong {
  font-size: 13px;
  color: #0f172a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mobile-lite-item-detail { font-size: 11px; color: #6b7280; }
.mobile-lite-item-del {
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 50%;
  background: #fee2e2;
  color: #b91c1c;
  font-size: 18px;
  cursor: pointer;
  flex-shrink: 0;
}
.mobile-lite-total-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 15px;
  font-weight: 700;
  padding: 12px 0;
  border-top: 1px solid #e5e7eb;
  margin-top: 12px;
}
.mobile-lite-help { font-size: 11px; color: #6b7280; margin: 4px 0 0; text-align: center; }

.mobile-lite-picker-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.5);
  z-index: 100;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.mobile-lite-picker {
  background: #fff;
  width: 100%;
  height: 85dvh;
  border-radius: 12px 12px 0 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.mobile-lite-picker-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  border-bottom: 1px solid #e5e7eb;
}
.mobile-lite-picker-header .mobile-lite-input { flex: 1; }
.mobile-lite-picker-close {
  width: 36px;
  height: 36px;
  border: 0;
  background: #f3f4f6;
  border-radius: 50%;
  font-size: 20px;
  cursor: pointer;
}
.mobile-lite-picker-list {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Mobile-lite v2 (2026-05-25): overlay + modal genéricos para tiles
   clickeables (top morosos, stock crítico) y formularios (cobrar). */
.mobile-lite-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: rgba(15, 23, 42, 0.55);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
}
.mobile-lite-modal {
  width: 100%;
  max-width: 540px;
  max-height: 88dvh;
  background: #fff;
  border-radius: 16px 16px 0 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: mobile-lite-slide-up .18s ease;
}
@keyframes mobile-lite-slide-up {
  from { transform: translateY(20px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.mobile-lite-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid #e5e7eb;
  background: #f8fafc;
}
.mobile-lite-modal-header h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: #0f172a;
}
.mobile-lite-modal-close {
  background: transparent;
  border: 0;
  font-size: 18px;
  color: #64748b;
  cursor: pointer;
  padding: 4px 8px;
}
.mobile-lite-modal-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 8px 0;
}
.mobile-lite-modal-footer-note {
  padding: 8px 16px 14px;
  font-size: 11px;
  color: #6b7280;
  text-align: center;
  background: #f8fafc;
  border-top: 1px solid #e5e7eb;
  margin: 0;
}
.mobile-lite-list-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 16px;
  width: 100%;
  background: #fff;
  border: 0;
  border-bottom: 1px solid #f3f4f6;
  font-family: inherit;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
  color: #0f172a;
}
.mobile-lite-list-row:active { background: #f9fafb; }
.mobile-lite-list-row-static { cursor: default; }
.mobile-lite-list-row-static:active { background: #fff; }
.mobile-lite-list-row-main {
  flex: 1;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mobile-lite-list-row-meta {
  font-size: 12px;
  color: #6b7280;
}

/* Mobile-lite v2: form de cobrar inline (modal). */
.mobile-lite-form-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 16px;
}
.mobile-lite-form-field > label {
  font-size: 12px;
  font-weight: 600;
  color: #475569;
}
.mobile-lite-form-field > input,
.mobile-lite-form-field > select,
.mobile-lite-form-field > textarea {
  font-size: 15px;
  padding: 10px 12px;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  background: #fff;
  width: 100%;
  box-sizing: border-box;
  min-height: 44px;
}
.mobile-lite-form-actions {
  display: flex;
  gap: 10px;
  padding: 12px 16px;
  border-top: 1px solid #e5e7eb;
  background: #f8fafc;
}
.mobile-lite-form-actions button {
  flex: 1;
  min-height: 44px;
  border-radius: 8px;
  border: 0;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.mobile-lite-form-actions .btn-cancel {
  background: #f1f5f9;
  color: #475569;
  border: 1px solid #cbd5e1;
}
.mobile-lite-form-actions .btn-confirm {
  background: #16a34a;
  color: #fff;
}
.mobile-lite-form-actions .btn-confirm:disabled {
  background: #94a3b8;
  cursor: not-allowed;
}
.mobile-lite-form-warning {
  margin: 8px 16px 0;
  padding: 10px 12px;
  background: #fef3c7;
  border: 1px solid #fde68a;
  border-radius: 8px;
  color: #92400e;
  font-size: 12px;
}

/* Mobile-lite F1: menú completo drawer */
.mobile-lite-menu-group-title {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #94a3b8;
  padding: 12px 16px 4px;
}
.mobile-lite-menu-drawer .mobile-lite-modal-body {
  padding: 4px 0 8px;
}
.mobile-lite-menu-item {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: none;
  border: none;
  border-bottom: 1px solid #f1f5f9;
  text-align: left;
  cursor: pointer;
  font-size: 15px;
  color: #0f172a;
}
.mobile-lite-menu-item:active {
  background: #f8fafc;
}

/* ============================================================
   Stock Mobile-Lite (F2 — 2026-06-19)
   Buscador + ficha con stock_por_deposito + escáner BarcodeDetector.
   ============================================================ */

/* Fila de búsqueda: input + botón escáner */
.mls-search-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.mls-search-row .mobile-lite-input {
  flex: 1;
}
.mls-scan-btn {
  flex-shrink: 0;
  width: 46px;
  height: 46px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #f8fafc;
  color: #374151;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.mls-scan-btn:active { background: #e2e8f0; }

/* Resultados de búsqueda */
.mls-results-list {
  display: flex;
  flex-direction: column;
  margin-top: 4px;
}
.mls-prod-row {
  align-items: center;
  gap: 10px;
}
.mls-prod-thumb {
  width: 40px;
  height: 40px;
  border-radius: 6px;
  object-fit: cover;
  flex-shrink: 0;
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
}
.mls-prod-thumb-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  width: 40px;
  height: 40px;
  border-radius: 6px;
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
}
.mls-cod {
  display: block;
  font-size: 11px;
  color: #6b7280;
  font-weight: 400;
  margin-top: 1px;
}
.mls-stock-badge {
  font-size: 13px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 12px;
  background: #ecfdf5;
  color: #166534;
  white-space: nowrap;
  flex-shrink: 0;
}
.mls-stock-cero {
  background: #fef2f2;
  color: #991b1b;
}

/* Ficha de artículo */
.mls-ficha-header {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 12px;
}
.mls-ficha-foto {
  width: 72px;
  height: 72px;
  border-radius: 10px;
  object-fit: cover;
  flex-shrink: 0;
  border: 1px solid #e5e7eb;
  background: #f3f4f6;
}
.mls-ficha-foto-empty {
  width: 72px;
  height: 72px;
  border-radius: 10px;
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  flex-shrink: 0;
}
.mls-ficha-titulo {
  flex: 1;
  min-width: 0;
}
.mls-tipo-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 10px;
  background: #e0f2fe;
  color: #0369a1;
  display: inline-block;
  margin-top: 4px;
}
.mls-ficha-datos {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 4px;
}
.mls-ficha-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
  gap: 8px;
}
.mls-ficha-label {
  color: #64748b;
  font-weight: 500;
  white-space: nowrap;
}

/* Stock por depósito */
.mls-depo-list {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  overflow: hidden;
}
.mls-depo-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 14px;
  border-bottom: 1px solid #f1f5f9;
  font-size: 13px;
}
.mls-depo-row:last-child { border-bottom: 0; }
.mls-depo-nombre { color: #374151; }
.mls-depo-total {
  background: #f1f5f9;
  font-weight: 700;
}
.mls-qty { font-weight: 700; }
.mls-qty-ok { color: #166534; }
.mls-qty-cero { color: #991b1b; }
.mls-stock-minimo {
  font-size: 11px;
  color: #6b7280;
  margin: 6px 0 0;
  text-align: right;
}

/* Escáner de código de barras */
.mls-scanner-modal {
  max-height: 92dvh;
}
.mls-scanner-body {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #000;
  overflow: hidden;
  min-height: 300px;
}
.mls-scan-video {
  width: 100%;
  height: 100%;
  max-height: 55dvh;
  object-fit: cover;
  display: block;
}
/* Retícula de encuadre */
.mls-scan-reticle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 200px;
  height: 120px;
  border: 2px solid rgba(255,255,255,0.7);
  border-radius: 8px;
  box-shadow: 0 0 0 9999px rgba(0,0,0,0.35);
  pointer-events: none;
}
.mls-scan-status {
  position: absolute;
  bottom: 12px;
  left: 0;
  right: 0;
  text-align: center;
  color: #fff;
  font-size: 12px;
  background: rgba(0,0,0,0.45);
  padding: 6px 12px;
  margin: 0;
}


/* Mobile-lite Compras / Tesorería / Caja Chica - 2026-06-19 */
.mls-toolbar { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
.mls-search { flex: 1; }
.mls-list { display: flex; flex-direction: column; gap: 8px; }
.mls-compra-card { cursor: pointer; }
.mls-item-card { background: var(--color-bg-alt, #f8f8f8); }
.mls-detalle { background: var(--color-bg-alt, #f8f8f8); border-radius: 8px; padding: 12px; margin-bottom: 12px; }
.mls-detalle-row { display: flex; justify-content: space-between; gap: 8px; padding: 5px 0; border-bottom: 1px solid var(--color-border, #e5e7eb); font-size: 14px; }
.mls-detalle-row:last-child { border-bottom: none; }
.mls-label { color: var(--color-muted, #6b7280); font-size: 13px; flex-shrink: 0; }
.mls-add-item-section { background: var(--color-bg-alt, #f8f8f8); border-radius: 8px; padding: 12px; margin: 12px 0; display: flex; flex-direction: column; gap: 8px; }
.mls-item-row { display: flex; gap: 6px; }
.mls-input-cant { width: 64px; min-width: 64px; }
.mls-input-precio { flex: 1; }
.mls-input-iva { width: 90px; min-width: 90px; }
.mls-item-form-card { position: relative; }
.mls-btn-remove-item { padding: 2px 8px; font-size: 12px; background: none; color: #dc2626; border: 1px solid #dc2626; border-radius: 4px; cursor: pointer; }
.mls-total-bar { display: flex; justify-content: space-between; align-items: center; padding: 12px; background: var(--color-bg-alt, #f8f8f8); border-radius: 8px; margin: 12px 0; font-weight: 600; }
.mls-total-amount { font-size: 18px; font-weight: 700; }
.mls-back-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.mls-step-badge { margin-left: auto; font-size: 11px; color: #6b7280; background: #f3f4f6; border-radius: 10px; padding: 2px 8px; white-space: nowrap; }
.mls-section-header { font-weight: 600; font-size: 16px; }
.mls-selected-tag { background: #eff6ff; color: #2563eb; padding: 4px 10px; border-radius: 16px; font-size: 13px; display: inline-block; margin-top: 4px; }
.mls-suggestions { border: 1px solid var(--color-border, #e5e7eb); border-radius: 6px; max-height: 160px; overflow-y: auto; background: white; margin-top: 2px; }
.mls-suggestion-item { padding: 9px 12px; cursor: pointer; font-size: 14px; border-bottom: 1px solid var(--color-border, #e5e7eb); }
.mls-suggestion-item:last-child { border-bottom: none; }
.mls-suggestion-item:active, .mls-suggestion-item:hover { background: #f3f4f6; }
.mls-cuenta-card { cursor: default; }
.mls-total-card { background: #eff6ff; border: 1px solid #2563eb; }
.mls-mov-card { font-size: 14px; }
.mls-pos { color: #16a34a; }
.mls-neg { color: #dc2626; }
.mls-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 58vw; display: inline-block; }
.mls-caja-card { cursor: pointer; }
.mls-cajas-list { display: flex; flex-direction: column; gap: 8px; }
.mls-cuentas-list { display: flex; flex-direction: column; gap: 8px; }
.mls-movs-list { display: flex; flex-direction: column; gap: 8px; }
.mls-items-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.mls-form { display: flex; flex-direction: column; gap: 8px; padding-bottom: 24px; }
.mls-banner-ok { background: #d1fae5; color: #065f46; padding: 8px 12px; border-radius: 6px; margin-bottom: 8px; font-size: 14px; }
.mls-banner-error { background: #fee2e2; color: #991b1b; padding: 8px 12px; border-radius: 6px; margin-bottom: 8px; font-size: 14px; }
.mls-overlay-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; font-weight: 600; font-size: 16px; }
.mls-card-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 4px; }
.mls-badge { font-size: 11px; padding: 2px 7px; border-radius: 10px; font-weight: 600; white-space: nowrap; }
.mls-badge-ok { background: #d1fae5; color: #065f46; }
.mls-badge-pending { background: #fef9c3; color: #713f12; }
.mls-card-title { font-weight: 600; font-size: 14px; }
.mls-card-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 13px; }
.mls-muted { color: var(--color-muted, #6b7280); font-size: 12px; }
.mls-amount { font-weight: 600; white-space: nowrap; }

/* ============================================================
   Filtros-row — barra de filtros unificada para listados.
   Audit visual 2026-05-16.
   ============================================================ */
.filtros-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-bottom: 10px;
}
/* label inline: "Tipo: <select>" */
.filtro-inline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: #374151;
  white-space: nowrap;
}
.filtro-inline select,
.filtro-inline input[type="text"],
.filtro-inline input[type="date"],
.filtro-inline input[type="month"] {
  font-size: 13px;
  padding: 6px 10px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #fff;
  outline: none;
}
.filtro-inline select:focus,
.filtro-inline input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(37,99,235,.12);
}
/* checkbox inline: "☐ Solo no leídas" */
.filtro-check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: #374151;
  cursor: pointer;
  user-select: none;
}
/* input búsqueda de texto libre */
.filtro-q {
  flex: 1;
  min-width: 200px;
  font-size: 13px;
  padding: 6px 10px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #fff;
  outline: none;
}
.filtro-q:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(37,99,235,.12);
}

/* Sprint C-2 — Tabs rendiciones (sustituye style="background:" inline) */
.rd-tabs {
  display: flex;
  border-bottom: 1px solid #e2e8f0;
  flex-wrap: wrap;
  margin-top: 8px;
}

.rd-tab {
  padding: 10px 16px;
  cursor: pointer;
  border: none;
  background: #f8fafc;
  font-weight: 400;
  border-bottom: 2px solid transparent;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  transition: background-color .15s ease, border-color .15s ease;
}

.rd-tab:hover:not(.active) {
  background: #f1f5f9;
}

.rd-tab.active {
  background: #fff;
  font-weight: 600;
  border-bottom-color: #3b82f6;
}

/* Facturación Masiva F3 */
.fm-row-invalid { background: #fff5f5; }
.fm-row-warning { background: #fffbeb; }
.fm-row-invalid:hover { background: #fee2e2; }
.fm-row-warning:hover { background: #fef3c7; }


/* D2.4 2026-05-18: modal flotante de Ajuste de stock con look V2
   (no puede usar clases cv2-* porque comprobante-v2.css solo se
   carga en la página fullscreen del comprobante, no en index.html). */
#ajuste-stock-overlay .ajuste-stock-modal {
  font-family: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
  color: #0f172a;
}
#ajuste-stock-overlay .ajuste-stock-modal h3,
#ajuste-stock-overlay .ajuste-stock-modal h4 {
  font-weight: 600;
  letter-spacing: -0.01em;
}
#ajuste-stock-overlay .ajuste-stock-modal .form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
#ajuste-stock-overlay .ajuste-stock-modal .field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
#ajuste-stock-overlay .ajuste-stock-modal .field label {
  font-size: 12px;
  font-weight: 500;
  color: #475569;
  text-transform: none;
}
#ajuste-stock-overlay .ajuste-stock-modal .input,
#ajuste-stock-overlay .ajuste-stock-modal select.input,
#ajuste-stock-overlay .ajuste-stock-modal textarea.input {
  padding: 7px 10px;
  border: 1px solid #cbd5e1;
  border-radius: 4px;
  font-size: 13px;
  background: #fff;
  color: #0f172a;
  font-family: inherit;
  width: 100%;
  box-sizing: border-box;
}
#ajuste-stock-overlay .ajuste-stock-modal .input:focus,
#ajuste-stock-overlay .ajuste-stock-modal select.input:focus,
#ajuste-stock-overlay .ajuste-stock-modal textarea.input:focus {
  outline: none;
  border-color: #1e3a8a;
  box-shadow: 0 0 0 3px rgba(30, 58, 138, .12);
}
#ajuste-stock-overlay .ajuste-stock-modal .table-wrap {
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  overflow: hidden;
}
#ajuste-stock-overlay .ajuste-stock-modal table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
#ajuste-stock-overlay .ajuste-stock-modal thead th {
  background: #f1f5f9;
  color: #334155;
  font-weight: 600;
  text-align: left;
  padding: 7px 10px;
  border-bottom: 1px solid #e2e8f0;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
#ajuste-stock-overlay .ajuste-stock-modal tbody td {
  padding: 6px 10px;
  border-bottom: 1px solid #f1f5f9;
}
#ajuste-stock-overlay .ajuste-stock-modal tbody tr:last-child td {
  border-bottom: 0;
}
#ajuste-stock-overlay .ajuste-stock-modal .btn-primary {
  background: var(--primary, #1e3a8a);
  color: var(--on-primary, #fff);
  border: 0;
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s;
}
#ajuste-stock-overlay .ajuste-stock-modal .btn-primary:hover { background: var(--primary-hover, #1e40af); }
#ajuste-stock-overlay .ajuste-stock-modal .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
#ajuste-stock-overlay .ajuste-stock-modal .btn-light {
  background: #f1f5f9;
  color: #334155;
  border: 1px solid #cbd5e1;
  padding: 7px 14px;
  border-radius: 4px;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.15s;
}
#ajuste-stock-overlay .ajuste-stock-modal .btn-light:hover { background: #e2e8f0; }

/* ============================================================
   MÓDULOS — estilos extraídos de inline <style> en app.js
   (Opción B Fase 2, 2026-05-27 — antes inyectados en innerHTML)
   ============================================================ */

/* ── Centros de Costo — tabs dentro de card (sin margin-bottom externo) ── */
/* Migrado de inline style a .page-tabs.page-tabs-secondary en 2026-05-27 */
.cc-tabs {
  padding: 0 12px;
  margin-bottom: 0;          /* overrides default 14px — cc-content tiene su propio padding */
}
.cc-tab-disabled {
  opacity: 0.45;
  cursor: not-allowed !important;
  pointer-events: none;
}
.cc-tab-badge {
  vertical-align: middle;
  margin-left: 4px;
  text-transform: none;
  letter-spacing: 0;
}
.cc-tab-hint {
  font-weight: 400;
  font-size: var(--font-xs, 11px);
  color: var(--muted);
}

/* ── Tienda Editor Visual (twe-*) — extraído de tweInjectStyles() 2026-05-27 ──
   Colores #1f4e8c → var(--primary-dark), #2c6ef2 → var(--primary),
   #1a5de0 / #163e72 → var(--primary-hover), #c0392b → var(--danger)           */
.twe-topbar{position:sticky;top:0;z-index:50;display:flex;gap:6px;padding:8px 12px;background:#fff;border-bottom:1px solid #e1e5eb;flex-wrap:wrap;align-items:center;min-height:48px;}
.twe-topbar .twe-status{flex:1;font-size:12px;color:#6b7280;display:flex;align-items:center;gap:8px;}
.twe-topbar .twe-status.dirty{color:#e67e22;}
.twe-topbar .twe-status-dot{width:8px;height:8px;border-radius:50%;background:#6b7280;display:inline-block;flex-shrink:0;}
.twe-topbar .twe-status.dirty .twe-status-dot{background:#e67e22;}
.twe-topbar .twe-status-saved .twe-status-dot{background:#27ae60;}
.twe-topbar .twe-blk-count{font-size:11px;color:#9ca3af;padding-left:10px;border-left:1px solid #e1e5eb;margin-left:4px;white-space:nowrap;}
.twe-topbar button{padding:6px 12px;font-size:12px;border-radius:var(--radius-sm,6px);border:1px solid #d1d5db;background:#fff;color:#3a4252;cursor:pointer;white-space:nowrap;font-weight:500;}
.twe-topbar button:hover:not(:disabled){background:#f5f7fa;border-color:#b0b8c4;}
.twe-topbar button:disabled{opacity:.4;cursor:not-allowed;}
.twe-topbar button.primary{background:var(--primary);color:var(--on-primary);border-color:var(--primary);font-weight:600;}
.twe-topbar button.primary:hover:not(:disabled){background:var(--primary-hover);border-color:var(--primary-hover);}
.twe-topbar button.secondary{border:1px solid #d1d5db;background:#fff;color:#3a4252;}
.twe-topbar .twe-topbar-divider{width:1px;height:24px;background:#e1e5eb;margin:0 4px;flex-shrink:0;}
.twe-topbar button.danger{color:var(--danger);border-color:#fca5a5;}
.twe-layout{display:grid;grid-template-columns:340px 1fr 300px;height:calc(100vh - 120px);min-height:560px;gap:0;background:#e8ecf0;position:relative;overflow:hidden;isolation:isolate;}
/* min-height:0 + min-width:0 son OBLIGATORIOS en grid items para que overflow:auto funcione. */
.twe-sidebar-left{min-height:0;min-width:0;background:#fbfcfd;border-right:1px solid #dfe3eb;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;scrollbar-gutter:stable;}
.twe-sidebar-left::-webkit-scrollbar{width:10px;}
.twe-sidebar-left::-webkit-scrollbar-track{background:transparent;}
.twe-sidebar-left::-webkit-scrollbar-thumb{background:#cdd3dd;border-radius:6px;border:2px solid transparent;background-clip:padding-box;}
.twe-sidebar-left::-webkit-scrollbar-thumb:hover{background:#aab2bf;background-clip:padding-box;border:2px solid transparent;}
.twe-canvas-area{min-height:0;min-width:0;background:#e8ecf0;overflow-y:auto;padding:20px;display:flex;flex-direction:column;align-items:center;}
.twe-props-panel{min-height:0;min-width:0;background:#fff;border-left:1px solid #e6e8ec;overflow-y:auto;display:flex;flex-direction:column;}
/* Secciones del sidebar: panel limpio sin floating, separadas por divider suave. */
.twe-sb-section{background:#fff;border-bottom:1px solid #ecedf2;transition:background .2s ease;}
.twe-sb-section:last-child{border-bottom:none;}
.twe-sb-section:hover{background:#fdfefe;}
.twe-sb-section-head{display:flex;align-items:center;gap:10px;padding:14px 18px 12px 22px;font-size:11px;font-weight:700;color:#475569;text-transform:uppercase;letter-spacing:.85px;background:transparent;position:relative;transition:color .15s ease;}
.twe-sb-section:hover .twe-sb-section-head{color:#1e293b;}
.twe-sb-section-head::before{content:"";position:absolute;left:14px;top:50%;transform:translateY(-50%);width:3px;height:14px;background:linear-gradient(180deg,#3b82f6 0%,var(--primary,#1f4e8c) 100%);border-radius:2px;transition:height .2s ease,box-shadow .2s ease;}
.twe-sb-section:hover .twe-sb-section-head::before{height:18px;box-shadow:0 0 8px rgba(59,130,246,.35);}
.twe-sb-section-body{padding:4px 18px 18px;}
.twe-sb-colores-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
.twe-sb-color-item{position:relative;}
.twe-sb-color-item label{display:block;font-size:10px;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.4px;margin-bottom:5px;}
.twe-sb-color-item input[type=color]{height:38px;width:100%;border:1px solid #e2e8f0;border-radius:8px;padding:3px;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease,transform .12s ease;background:#fff;}
.twe-sb-color-item input[type=color]:hover{border-color:#94a3b8;box-shadow:0 2px 6px rgba(15,23,42,.07);transform:translateY(-1px);}
.twe-sb-color-item input[type=color]:focus{outline:none;border-color:var(--primary,#1f4e8c);box-shadow:0 0 0 3px rgba(31,78,140,.15);}
.twe-sb-font-sel{width:100%;padding:7px 10px;border:1px solid #d1d5db;border-radius:var(--radius-sm,6px);font-size:12px;font-family:inherit;box-sizing:border-box;margin-top:8px;}
.twe-sb-savebar{padding:8px 0 2px;display:flex;justify-content:flex-end;}
.twe-sb-savebar button{padding:6px 14px;font-size:12px;border-radius:var(--radius-sm,6px);border:1px solid var(--primary-dark);background:var(--primary-dark);color:#fff;cursor:pointer;}
.twe-sb-savebar button:hover{background:var(--primary-deep);}
.twe-sb-hero-imgs{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px;}
.twe-sb-hero-thumb{position:relative;width:68px;height:44px;border:1px solid #e6e8ec;border-radius:4px;overflow:hidden;background:#f6f7f9;}
.twe-sb-hero-thumb-loading{display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#eef2f7 25%,#f8fafc 50%,#eef2f7 75%);background-size:200% 200%;animation:twe-skeleton 1.6s ease-in-out infinite;border-color:#cbd5e1;}
.twe-spinner{width:18px;height:18px;border:2px solid rgba(31,78,140,.18);border-top-color:var(--primary,#1f4e8c);border-radius:50%;animation:twe-spin .8s linear infinite;}
@keyframes twe-spin{to{transform:rotate(360deg);}}
@keyframes twe-skeleton{0%{background-position:200% 0;}100%{background-position:-200% 0;}}
.twe-sb-hero-thumb img{width:100%;height:100%;object-fit:cover;}
.twe-sb-hero-thumb button{position:absolute;top:1px;right:1px;background:var(--danger);color:#fff;border:0;border-radius:50%;width:16px;height:16px;font-size:9px;cursor:pointer;line-height:1;padding:0;}
.twe-sb-hero-add{width:68px;height:44px;border:2px dashed #c0c8d4;border-radius:4px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#6b7280;font-size:10px;text-align:center;background:#fff;}
/* Hero items (lista vertical con link por imagen, 2026-05-29) */
.twe-hero-items{display:flex;flex-direction:column;gap:8px;}
.twe-hero-item{display:flex;align-items:center;gap:8px;padding:6px;background:#fafbfc;border:1px solid #e6e8ec;border-radius:6px;}
.twe-hero-item-thumb{position:relative;flex:0 0 72px;width:72px;height:48px;border-radius:4px;background-size:cover;background-position:center;background-color:#f0f3f7;border:1px solid #e6e8ec;}
.twe-hero-item-num{position:absolute;top:2px;left:2px;background:rgba(0,0,0,.65);color:#fff;font-size:9px;font-weight:700;padding:1px 5px;border-radius:3px;line-height:1.2;}
.twe-hero-item-fields{flex:1;min-width:0;}
.twe-hero-item-link{width:100%;padding:6px 8px;border:1px solid #d1d5db;border-radius:6px;font-size:12px;font-family:inherit;box-sizing:border-box;background:#fff;}
.twe-hero-item-link:focus{outline:none;border-color:var(--primary,#1f4e8c);box-shadow:0 0 0 3px rgba(31,78,140,.12);}
/* #29: control de versión mobile por slide del hero */
.twe-hero-mob-row{display:flex;align-items:center;gap:6px;margin-top:6px;}
.twe-hero-mob-add{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:#6b7280;border:1px dashed #cbd5e1;border-radius:6px;padding:3px 8px;cursor:pointer;background:#f9fafb;}
.twe-hero-mob-add:hover{border-color:var(--primary,#1f4e8c);color:var(--primary,#1f4e8c);background:#eef4fb;}
.twe-hero-mob-thumb{display:inline-block;width:28px;height:40px;border-radius:4px;background-size:cover;background-position:center;border:1px solid #d1d5db;}
.twe-hero-mob-del{border:none;background:#fee2e2;color:#b91c1c;border-radius:4px;width:20px;height:20px;line-height:1;cursor:pointer;font-size:13px;}
.twe-hero-mob-del:hover{background:#fecaca;}
.twe-hero-item-del{flex:0 0 24px;width:24px;height:24px;border-radius:50%;border:0;background:transparent;color:#9ca3af;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1;padding:0;transition:background .12s,color .12s;}
.twe-hero-item-del:hover{background:var(--danger,#dc2626);color:#fff;}
.twe-hero-add-row{margin-top:2px;}
.twe-hero-add-btn{display:flex;align-items:center;justify-content:center;height:38px;border:2px dashed #c0c8d4;border-radius:6px;cursor:pointer;color:#6b7280;font-size:12px;font-weight:500;text-align:center;background:#fff;transition:background .12s,border-color .12s,color .12s;}
.twe-hero-add-btn:hover{background:#eef4fb;border-color:var(--primary,#1f4e8c);color:var(--primary,#1f4e8c);}
.twe-sb-field{margin-bottom:8px;}
.twe-sb-field label{display:block;font-size:10px;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.3px;margin-bottom:3px;}
.twe-sb-field input,.twe-sb-field select{width:100%;padding:6px 8px;border:1px solid #d1d5db;border-radius:var(--radius-sm,6px);font-size:12px;font-family:inherit;box-sizing:border-box;}
.twe-sb-field input[type=number]{width:100%;}
.twe-sb-2col{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
.twe-sb-logo-slot{display:flex;gap:10px;align-items:center;padding:8px;border:1px dashed #c0c8d4;border-radius:var(--radius-sm,6px);margin-bottom:8px;background:#fafbfc;}
.twe-sb-logo-slot img{max-width:80px;max-height:48px;object-fit:contain;background:#fff;border-radius:3px;padding:2px;}
.twe-sb-logo-slot .ph{width:80px;height:48px;background:#f6f7f9;border-radius:3px;display:flex;align-items:center;justify-content:center;color:#aab1bd;font-size:18px;}
.twe-list{overflow-y:visible;padding:0;}
.twe-list-empty{text-align:center;color:#94a3b8;padding:24px 10px;font-size:12px;}
.twe-block-row{display:flex;align-items:center;gap:8px;padding:10px 12px;border:1px solid #e6e8ec;border-radius:9px;margin-bottom:7px;background:#fff;cursor:grab;transition:border-color .15s ease,box-shadow .15s ease,transform .12s ease,background .15s ease;position:relative;}
.twe-block-row:hover{border-color:#cbd5e1;box-shadow:0 2px 5px rgba(15,23,42,.05);transform:translateX(1px);}
.twe-block-row.selected{border-color:var(--primary-dark);background:linear-gradient(90deg,#eef4fc 0%,#f5f9ff 100%);box-shadow:0 0 0 2px rgba(30,64,175,.18),0 2px 4px rgba(30,64,175,.10);}
.twe-block-row.selected::before{content:"";position:absolute;left:-1px;top:8px;bottom:8px;width:3px;background:var(--primary-dark);border-radius:0 2px 2px 0;}
.twe-block-row.dragging{opacity:.4;cursor:grabbing;}
.twe-block-row.drop-target{border-top:3px solid var(--primary-dark);}
.twe-block-row .drag-handle{color:#cbd5e1;font-size:14px;cursor:grab;user-select:none;transition:color .12s ease;}
.twe-block-row:hover .drag-handle{color:#64748b;}
/* #58 F5: drag&drop del constructor de menú por rubros */
.twc-mb-row{cursor:default;transition:opacity .12s ease,border-color .12s ease;}
.twc-mb-row.dragging{opacity:.4;cursor:grabbing;}
.twc-mb-row.drop-target{border-top:3px solid var(--primary-dark) !important;}
.twc-mb-row .mb-drag-handle{color:#cbd5e1;font-size:15px;cursor:grab;user-select:none;transition:color .12s ease;}
.twc-mb-row:hover .mb-drag-handle{color:#64748b;}
.twe-block-row .icon{font-size:17px;flex-shrink:0;}
.twe-block-row .title{flex:1;font-weight:600;font-size:12.5px;color:#1e293b;min-width:0;overflow:hidden;text-overflow:ellipsis;}
.twe-block-row .title small{display:block;color:#64748b;font-weight:400;font-size:10.5px;margin-top:1px;}
.twe-block-row.hidden{opacity:.55;background:#fafbfc;}
.twe-block-row.hidden .title{opacity:.75;}
.twe-block-row .twe-row-btn{background:transparent;border:0;cursor:pointer;font-size:13px;padding:4px 6px;color:#94a3b8;border-radius:5px;transition:background .12s ease,color .12s ease;}
.twe-block-row .twe-row-btn:hover{background:#eef2f7;color:#1e293b;}
.twe-block-row .twe-row-btn.danger:hover{background:#fee2e2;color:var(--danger);}
.twe-add-btn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:11px;border:1.5px dashed #cbd5e1;border-radius:9px;background:#fcfdfe;color:var(--primary-dark);font-weight:600;cursor:pointer;font-size:13px;transition:background .15s ease,border-color .15s ease,color .15s ease,box-shadow .15s ease;letter-spacing:.2px;}
.twe-add-btn:hover{background:linear-gradient(135deg,#eef4fc 0%,#f5f9ff 100%);border-color:var(--primary-dark);border-style:solid;box-shadow:0 2px 8px rgba(31,78,140,.12);color:var(--primary);}
.twe-add-btn:active{transform:scale(.98);}
.twe-props-head{padding:12px 14px;border-bottom:1px solid #e6e8ec;font-size:12px;font-weight:700;color:#374151;text-transform:uppercase;letter-spacing:.5px;background:#f8f9fb;}
.twe-props-empty{padding:24px 14px;text-align:center;color:#9ca3af;font-size:12px;}
.twe-form{padding:12px 14px;background:#fff;}
.twe-form h4{margin:0 0 10px;font-size:12px;color:var(--primary-dark);display:flex;justify-content:space-between;align-items:center;}
.twe-form h4 button{background:transparent;border:0;color:#6b7280;cursor:pointer;font-size:11px;}
.twe-form .twe-field{margin-bottom:9px;}
.twe-form label{display:block;font-size:10px;color:#6b7280;text-transform:uppercase;letter-spacing:.3px;margin-bottom:3px;font-weight:600;}
.twe-form input,.twe-form select,.twe-form textarea{width:100%;padding:7px 9px;border:1px solid #d1d5db;border-radius:var(--radius-sm,6px);font-size:12px;font-family:inherit;box-sizing:border-box;}
.twe-form textarea{min-height:70px;}
.twe-form input[type=color]{height:32px;padding:2px;cursor:pointer;}
.twe-form input[type=checkbox]{width:auto;}
.twe-form .twe-row{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
.twe-form .help{font-size:10px;color:#6b7280;margin:3px 0 0;}
/* 2026-06-20: botones de alineación en panel hero */
.twe-align-btns{display:flex;gap:6px;}
.twe-align-btn{flex:1;padding:7px 4px;border:1px solid #d1d5db;border-radius:6px;background:#fff;color:#374151;font-size:12px;font-weight:600;cursor:pointer;transition:background .12s,border-color .12s,color .12s;text-align:center;}
.twe-align-btn:hover{background:#eef4fc;border-color:var(--primary-dark,#1f4e8c);color:var(--primary-dark,#1f4e8c);}
.twe-align-btn.active{background:var(--primary-dark,#1f4e8c);border-color:var(--primary-dark,#1f4e8c);color:#fff;}
/* 2026-05-28: overflow:hidden con max-height causaba que bloques bajos (Marcas/Novedades)
   queden recortados sin scroll. Cambiado a overflow-y:auto + max-height vh-relativa para
   que el visor permita scroll vertical y se vean todos los bloques. */
.twe-canvas-frame{background:#fff;border-radius:8px;box-shadow:0 4px 24px rgba(0,0,0,.10);width:100%;max-width:1100px;min-height:400px;height:calc(100vh - 220px);overflow:hidden;display:flex;flex-direction:column;}
.twe-canvas-frame iframe{flex:1;width:100%;border:0;display:block;}
.twe-canvas-inner{padding:0;}
.twe-canvas-block{border-bottom:1px solid #f0f2f5;padding:28px 32px;position:relative;cursor:pointer;}
.twe-canvas-block:hover{background:#fafbff;outline:2px dashed #93c5fd;}
.twe-canvas-block.selected{outline:2px solid var(--primary-dark);background:#eef4fc;}
.twe-canvas-block-label{position:absolute;top:4px;left:8px;font-size:10px;font-weight:600;color:var(--primary-dark);background:rgba(238,244,252,.9);padding:2px 6px;border-radius:3px;pointer-events:none;}
.twe-canvas-empty{text-align:center;padding:60px 20px;color:#9ca3af;}
.twe-canvas-empty .icon{font-size:40px;display:block;margin-bottom:10px;}
.twe-paleta{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;}
.twe-paleta-item{padding:16px 14px 14px;border:1px solid #e6e8ec;border-radius:10px;background:#fff;cursor:pointer;text-align:center;transition:border-color .18s ease,background .18s ease,box-shadow .18s ease,transform .18s ease;position:relative;overflow:hidden;}
.twe-paleta-item::after{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;background:linear-gradient(90deg,#3b82f6 0%,var(--primary-dark,#1f4e8c) 100%);transform:scaleX(0);transform-origin:left;transition:transform .35s ease;}
.twe-paleta-item:hover{border-color:var(--primary-dark);background:linear-gradient(180deg,#fafcff 0%,#eef4fc 100%);box-shadow:0 6px 18px rgba(31,78,140,.12),0 0 0 1px rgba(31,78,140,.08);transform:translateY(-2px);}
.twe-paleta-item:hover::after{transform:scaleX(1);}
.twe-paleta-item:active{transform:translateY(0);}
.twe-paleta-item .icon{font-size:26px;display:inline-block;margin-bottom:8px;transition:transform .25s ease;transform-origin:center;will-change:transform;}
.twe-paleta-item .label{font-weight:600;font-size:13px;color:#1e293b;}
.twe-paleta-item .desc{font-size:11px;color:#64748b;margin-top:4px;line-height:1.4;}
.twe-paleta-item:hover .desc{color:#475569;}

/* Animaciones específicas del icono por tipo de bloque. Cada una sugiere
   visualmente qué hace el bloque sin necesidad de leer la descripción. */
@keyframes twePal-pop{0%,100%{transform:scale(1);}50%{transform:scale(1.25);}}
@keyframes twePal-bounce{0%,100%{transform:translateY(0);}30%{transform:translateY(-6px);}60%{transform:translateY(0);}}
@keyframes twePal-shake{0%,100%{transform:rotate(0deg);}25%{transform:rotate(-8deg);}75%{transform:rotate(8deg);}}
@keyframes twePal-spin{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}
@keyframes twePal-slide-x{0%{transform:translateX(-8px);}50%{transform:translateX(8px);}100%{transform:translateX(-8px);}}
@keyframes twePal-tick{0%,100%{transform:rotate(0deg) scale(1.1);}25%{transform:rotate(8deg) scale(1.1);}75%{transform:rotate(-8deg) scale(1.1);}}
@keyframes twePal-pulse{0%,100%{transform:scale(1);opacity:1;}50%{transform:scale(1.15);opacity:.85;}}
@keyframes twePal-flip{0%{transform:rotateY(0deg);}50%{transform:rotateY(180deg);}100%{transform:rotateY(360deg);}}
@keyframes twePal-shimmer{0%,100%{transform:scale(1);filter:brightness(1);}50%{transform:scale(1.15);filter:brightness(1.3);}}
@keyframes twePal-marquee{0%{transform:translateX(-12px);}100%{transform:translateX(12px);}}
@keyframes twePal-truck{0%{transform:translateX(-10px);}50%{transform:translateX(10px);}51%{transform:translateX(10px) scaleX(-1);}100%{transform:translateX(-10px) scaleX(-1);}}
@keyframes twePal-roll{0%{transform:translateY(0) rotate(0deg);}50%{transform:translateY(-4px) rotate(180deg);}100%{transform:translateY(0) rotate(360deg);}}

.twe-paleta-item:hover .icon{animation:twePal-pop .6s ease infinite;}
.twe-paleta-item[data-add-type="hero"]:hover .icon{animation:twePal-slide-x 1.8s ease-in-out infinite;}
.twe-paleta-item[data-add-type="grid_productos"]:hover .icon{animation:twePal-pulse 1.2s ease-in-out infinite;}
.twe-paleta-item[data-add-type="categorias"]:hover .icon,
.twe-paleta-item[data-add-type="marcas"]:hover .icon,
.twe-paleta-item[data-add-type="banner_marca"]:hover .icon{animation:twePal-flip 1.4s ease infinite;}
.twe-paleta-item[data-add-type="texto_html"]:hover .icon{animation:twePal-shake .9s ease-in-out infinite;}
.twe-paleta-item[data-add-type="cta"]:hover .icon{animation:twePal-pulse .9s ease-in-out infinite;}
.twe-paleta-item[data-add-type="banner_promo"]:hover .icon,
.twe-paleta-item[data-add-type="banner_medio_pago"]:hover .icon{animation:twePal-pulse 1s ease-in-out infinite;}
.twe-paleta-item[data-add-type="galeria"]:hover .icon{animation:twePal-spin 2.2s linear infinite;}
.twe-paleta-item[data-add-type="announcement_bar"]:hover .icon{animation:twePal-marquee 1.6s ease-in-out infinite;}
.twe-paleta-item[data-add-type="newsletter"]:hover .icon{animation:twePal-bounce 1.2s ease-in-out infinite;}
.twe-paleta-item[data-add-type="countdown"]:hover .icon{animation:twePal-tick 1.4s ease-in-out infinite;}
.twe-paleta-item[data-add-type="banner_cuotas"]:hover .icon{animation:twePal-bounce 1.4s ease-in-out infinite;}
.twe-paleta-item[data-add-type="barra_envio_gratis"]:hover .icon{animation:twePal-truck 2s ease-in-out infinite;}
.twe-paleta-item[data-add-type="trust_badges"]:hover .icon{animation:twePal-shimmer 1.4s ease-in-out infinite;}
.twe-paleta-item[data-add-type="banner_cookies"]:hover .icon{animation:twePal-roll 1.6s ease-in-out infinite;}
.twe-paleta-item[data-add-type="redes_sociales"]:hover .icon{animation:twePal-pulse 1s ease-in-out infinite;}
.twe-paleta-item[data-add-type="medios_pago_logos"]:hover .icon{animation:twePal-flip 1.6s ease infinite;}
.twe-paleta-item[data-add-type="defensa_consumidor"]:hover .icon{animation:twePal-shake 1.2s ease-in-out infinite;}
.twe-paleta-item[data-add-type="ubicacion_mapa"]:hover .icon{animation:twePal-bounce 1.3s ease-in-out infinite;}
.twe-paleta-item[data-add-type="coleccion_tags"]:hover .icon{animation:twePal-flip 1.5s ease infinite;}
.twe-paleta-item[data-add-type="calculadora_envio"]:hover .icon{animation:twePal-tick 1.2s ease-in-out infinite;}

/* Mejora del cuadro modal en sí — más espacioso para que las animaciones respiren. */
.twe-paleta-item .label{transition:color .18s ease;}
.twe-paleta-item:hover .label{color:var(--primary-dark);}
.twe-image-list{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px;}
.twe-image-thumb{position:relative;width:90px;height:60px;border:1px solid #ddd;border-radius:4px;background-size:cover;background-position:center;background-color:#f6f7f9;}
.twe-image-thumb button{position:absolute;top:2px;right:2px;background:var(--danger);color:#fff;border:0;border-radius:50%;width:20px;height:20px;font-size:11px;cursor:pointer;line-height:1;padding:0;}
.twe-mobile-block{padding:30px 18px;text-align:center;}
.twe-mobile-block h3{margin:0 0 8px;}
.twe-mobile-block .icon{font-size:48px;margin-bottom:12px;}
@media (max-width:1100px){.twe-layout{grid-template-columns:1fr;}.twe-props-panel{display:none;}}
.twe-adj-btn{width:100%;text-align:left;font-size:12px;padding:8px 10px;border:1px solid #e1e5eb;border-radius:var(--radius-sm,6px);background:#fafbfc;color:#374151;cursor:pointer;font-weight:500;transition:background var(--transition-fast,.12s),border-color var(--transition-fast,.12s);}
.twe-adj-btn:hover{background:#eef4fc;border-color:var(--primary-dark);color:var(--primary-dark);}
/* ── Tienda v3 — Versionado histórico (2026-05-27) ── */
.twe-ver-badge{display:inline-block;background:var(--primary-dark);color:#fff;border-radius:10px;font-size:10px;font-weight:700;padding:1px 6px;margin-left:4px;vertical-align:middle;line-height:1.5;}
.twe-ver-list{max-height:220px;overflow-y:auto;border-top:1px solid #f0f2f5;}
.twe-ver-item{padding:9px 14px;border-bottom:1px solid #f0f2f5;cursor:pointer;background:#fff;transition:background .1s;}
.twe-ver-item:hover{background:#eef4fc;}
.twe-ver-item:last-child{border-bottom:0;}

/* ── Módulo Comisiones (M1) — renderComisionesInforme ── */
.com-inf-ranking td, .com-inf-ranking th { padding: 7px 10px; }
.com-inf-ranking td.num { text-align: right; }
.com-inf-badge-ok {
  display: inline-block;
  background: #dcfce7;
  color: #166534;
  border-radius: 12px;
  padding: 2px 8px;
  font-size: var(--font-sm, 12px);
  font-weight: var(--fw-semibold, 600);
}
.com-inf-badge-0 {
  display: inline-block;
  background: #f1f5f9;
  color: #64748b;
  border-radius: 12px;
  padding: 2px 8px;
  font-size: var(--font-sm, 12px);
}
.com-inf-total-row { background: #f8fafc; font-weight: var(--fw-semibold, 600); }
.com-inf-detail-table td, .com-inf-detail-table th { padding: 5px 8px; font-size: var(--font-sm, 12px); }
.com-inf-motivo-ok   { color: var(--success); }
.com-inf-motivo-skip { color: #94a3b8; }

/* ── Módulo Informes (F15) — renderInformes ── */
.inf-cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
  margin-top: 14px;
}
.inf-cat-card {
  background: #fff;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: var(--radius-md, 10px);
  padding: 14px;
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.04));
}
.inf-cat-title {
  margin: 0 0 10px 0;
  font-size: 1.05rem;
  color: #0f172a;
}
.inf-card-sub-header {
  font-size: var(--font-xs, 11px);
  font-weight: var(--fw-semibold, 600);
  color: #64748b;
  text-transform: uppercase;
  letter-spacing: .04em;
  margin: 8px 0 4px 0;
  padding-bottom: 2px;
  border-bottom: 1px dashed #e2e8f0;
}
.inf-card-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 6px; }
.inf-card-item {
  all: unset;
  cursor: pointer;
  padding: 8px 10px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid transparent;
  display: block;
  transition: background var(--transition-fast, .12s), border-color var(--transition-fast, .12s);
}
.inf-card-item:hover { background: #f1f5f9; }
.inf-card-item.is-selected { background: #dbeafe; border-color: #93c5fd; }
.inf-card-item-title { font-size: 0.92rem; font-weight: var(--fw-normal, 500); color: #0f172a; }
.inf-card-badge {
  display: inline-block;
  font-size: 0.65rem;
  font-weight: var(--fw-bold, 700);
  padding: 1px 5px;
  border-radius: var(--radius-xs, 4px);
  vertical-align: middle;
  margin-right: 4px;
}
.inf-card-badge.sys    { background: #e0f2fe; color: #075985; border: 1px solid #bae6fd; }
.inf-card-badge.tenant { background: #fef3c7; color: #92400e; border: 1px solid #fde68a; }
.inf-card-badge.user   { background: #e0e7ff; color: #3730a3; border: 1px solid #c7d2fe; }

/* ── Módulo Suscripciones (M3) — renderSuscripcionesDashboard ── */

/* ============================================================
   TEMA DE COLOR — versión A (2026-05-18)
   Selector por usuario desde "Mi cuenta". Cada paleta sobreescribe
   solo las variables de marca/acento; los grises de UI y los colores
   semánticos (danger/success/warning) no se tocan.
   Variables afectadas: --primary, --primary-hover, --primary-dark,
   --primary-deep, --primary-soft, --on-primary, --accent, --soft-primary.
   Default: "azul" (idéntico al :root base, no produce ningún override).
   ============================================================ */

:root[data-theme="rosa"] {
  --primary:      #db2777;
  --primary-hover:#be185d;
  --primary-dark: #9d174d;
  --primary-deep: #831843;
  --primary-soft: #fce7f3;
  --on-primary:   #ffffff;
  --accent:       #db2777;
  --soft-primary: #fce7f3;
}

:root[data-theme="verde"] {
  --primary:      #16a34a;
  --primary-hover:#15803d;
  --primary-dark: #166534;
  --primary-deep: #14532d;
  --primary-soft: #dcfce7;
  --on-primary:   #ffffff;
  --accent:       #16a34a;
  --soft-primary: #dcfce7;
}

:root[data-theme="amarillo"] {
  --primary:      #eab308;
  --primary-hover:#ca8a04;
  --primary-dark: #a16207;
  --primary-deep: #854d0e;
  --primary-soft: #fef9c3;
  --on-primary:   #1f2937;
  --accent:       #eab308;
  --soft-primary: #fef9c3;
}

:root[data-theme="naranja"] {
  --primary:      #ea580c;
  --primary-hover:#c2410c;
  --primary-dark: #9a3412;
  --primary-deep: #7c2d12;
  --primary-soft: #ffedd5;
  --on-primary:   #ffffff;
  --accent:       #ea580c;
  --soft-primary: #ffedd5;
}

:root[data-theme="rojo"] {
  --primary:      #dc2626;
  --primary-hover:#b91c1c;
  --primary-dark: #991b1b;
  --primary-deep: #7f1d1d;
  --primary-soft: #fee2e2;
  --on-primary:   #ffffff;
  --accent:       #dc2626;
  --soft-primary: #fee2e2;
}

:root[data-theme="crema"] {
  --primary:      #d4623a;
  --primary-hover:#b04d2b;
  --primary-dark: #9a3d22;
  --primary-deep: #7c2d12;
  --primary-soft: #fef3e6;
  --on-primary:   #ffffff;
  --accent:       #d4623a;
  --soft-primary: #fef3e6;
}

:root[data-theme="celeste"] {
  --primary:      #0ea5e9;
  --primary-hover:#0284c7;
  --primary-dark: #0369a1;
  --primary-deep: #075985;
  --primary-soft: #e0f2fe;
  --on-primary:   #ffffff;
  --accent:       #0ea5e9;
  --soft-primary: #e0f2fe;
}

:root[data-theme="azul"] {
  --primary:      #2563eb;
  --primary-hover:#1d4ed8;
  --primary-dark: #1e40af;
  --primary-deep: #1e3a8a;
  --primary-soft: #dbeafe;
  --on-primary:   #ffffff;
  --accent:       #2563eb;
  --soft-primary: #dbeafe;
}

/* D2.21 — Layout 2 columnas Mi cuenta */
.mc-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  align-items: start;
}
.mc-col {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Picker de tema en Mi cuenta */
.tema-color-picker {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  max-width: 240px;
  margin-top: 8px;
}
.tema-color-swatch {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  cursor: pointer;
  border: 3px solid transparent;
  transition: transform .15s, border-color .15s;
  outline-offset: 2px;
}
.tema-color-swatch:hover {
  transform: scale(1.1);
}
.tema-color-swatch:focus-visible {
  outline: 2px solid var(--primary, #2563eb);
}
.tema-color-swatch.active {
  border-color: #0f172a;
  box-shadow: 0 0 0 2px #fff inset;
}

/* ─────────────────────────────────────────────────────────────────────────────
   Pestaña Pedidos ML — F2 (2026-05-27)
───────────────────────────────────────────────────────────────────────────── */
.pedidos-ml-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}

.pedidos-ml-filtros {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
  padding: 12px 14px;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
}

.pedidos-ml-filtro-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.pedidos-ml-filtro-label {
  font-size: 11px;
  font-weight: 600;
  color: #64748b;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  min-width: 80px;
  flex-shrink: 0;
}

.pedidos-ml-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.pedidos-ml-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: 20px;
  border: 1.5px solid #cbd5e1;
  background: #fff;
  color: #475569;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
  line-height: 1.5;
}
.pedidos-ml-chip:hover {
  background: #e0e7ff;
  border-color: #a5b4fc;
  color: #3730a3;
}
.pedidos-ml-chip.active {
  background: var(--primary, #2563eb);
  border-color: var(--primary, #2563eb);
  color: #fff;
  font-weight: 600;
}
.pedidos-ml-chip.active:hover {
  background: var(--primary-deep, #1d4ed8);
  border-color: var(--primary-deep, #1d4ed8);
  color: #fff;
}
.pedidos-ml-chip-count {
  opacity: 0.75;
  font-weight: 400;
}

.pedidos-ml-search {
  min-width: 200px;
}

/* Contenedor tabla: card aireada estilo MUI (scoped, no afecta .table-wrap global) */
.pedidos-ml-wrap.table-wrap {
  border: 1px solid var(--line);
  border-radius: var(--radius-md, 10px);
  box-shadow: var(--shadow-sm, 0 1px 3px rgba(15,23,42,.06));
  overflow: hidden;           /* clip el scroll horizontal dentro del card */
  overflow-x: auto;
}

/* Tabla de órdenes */
.pedidos-ml-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.pedidos-ml-table thead th {
  background: #f8fafc;
  color: #64748b;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.pedidos-ml-table tbody td {
  padding: 14px 14px;
  border-bottom: 1px solid #f1f5f9;
  vertical-align: middle;
}
/* Última fila de pedido: divisor un poco más marcado antes del próximo bloque */
.pedidos-ml-item-row:last-of-type > td {
  border-bottom: 1px solid var(--line);
}
.pedidos-ml-row:hover > td {
  background: #f8fafc;
  transition: background 0.1s;
}
.pedidos-ml-row[data-expanded="true"] > td {
  background: #f0f9ff;
}
.pedidos-ml-expand-icon {
  display: inline-block;
  font-size: 9px;
  color: #94a3b8;
  margin-right: 4px;
  transition: transform 0.12s;
  user-select: none;
}
.pedidos-ml-row[data-expanded="true"] .pedidos-ml-expand-icon {
  color: var(--primary, #2563eb);
}

/* Filas de items (maestro/detalle siempre visible 2026-06-18).
   Sub-filas son siempre visibles; el triángulo de la fila padre sirve para
   colapsar si el usuario lo desea, pero el estado por defecto es expandido. */
.pedidos-ml-item-row { display: table-row; }
.pedidos-ml-item-row.is-collapsed { display: none; }
.pedidos-ml-item-row > td {
  background: #f8fbff;
  padding: 8px 14px 8px 28px;
  border-bottom: 1px solid #e9f2ff;
  font-size: 12px;
}
/* Imagen thumbnail del ítem ML dentro de la sub-fila */
.pedidos-ml-item-thumb {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid #dbeafe;
  vertical-align: middle;
  flex-shrink: 0;
}
.pedidos-ml-item-thumb-placeholder {
  display: inline-block;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm, 6px);
  background: #e9f2ff;
  vertical-align: middle;
  flex-shrink: 0;
}
.pedidos-ml-item-content {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
/* Título del producto: ellipsis sin inline-style */
.pedidos-ml-item-content strong {
  max-width: 320px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* El gap de 8px en item-content ya cubre el espacio entre badge y botón Vincular */
.pedidos-ml-vincular-btn {
  margin-left: 0;
}

/* Estado de carga */
.pedidos-ml-loading {
  padding: 32px;
  text-align: center;
}

/* Botón sm para acciones en tabla */
.btn.btn-sm {
  padding: 3px 10px;
  font-size: 12px;
}

/* ---- Editor de ajuste de ítems ML (F3) ---- */
.ml-ajuste-editor {
  padding: 4px 2px;
}

.ml-ajuste-item-row {
  border-bottom: 1px solid #f1f5f9;
  transition: background 0.1s;
}
.ml-ajuste-item-row:hover {
  background: #f8fafc;
}

.ml-ajuste-eliminado td {
  text-decoration: line-through;
  opacity: 0.5;
}

.ml-ajuste-agregados {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 14px 16px;
}

.ml-ajuste-preview {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  background: #f0fdf4;
  border: 1px solid #bbf7d0;
  border-radius: 8px;
  font-size: 14px;
}

.ml-ajuste-preview-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.ml-ajuste-preview-row span {
  color: #475569;
}

/* Botón danger outline para quitar ítems */
.btn.btn-danger-outline {
  border: 1.5px solid #fca5a5;
  color: #dc2626;
  background: #fff;
}
.btn.btn-danger-outline:hover {
  background: #fef2f2;
  border-color: #dc2626;
}

/* Banner empresa en Tienda Web (.tw-emp-*) eliminado 2026-05-28 — revertido por pedido del user. */

/* =========================================================================
   Tienda Web Config (twc-*) — estilos estáticos migrados desde inyección JS
   ========================================================================= */
.twc-section {
  background: #fff;
  border: 1px solid #e6e8ec;
  border-radius: 8px;
  margin-bottom: 10px;
  overflow: hidden;
}
.twc-section-head {
  width: 100%;
  text-align: left;
  background: #f6f7f9;
  border: 0;
  padding: 14px 18px;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: #1c2433;
}
.twc-section-head:hover { background: #eef2f7; }
.twc-section-head .twc-section-arrow {
  transition: transform .15s;
  font-size: 14px;
  color: #6b7280;
}
.twc-section.collapsed .twc-section-arrow { transform: rotate(-90deg); }
.twc-section-body {
  padding: 18px;
  border-top: 1px solid #e6e8ec;
  background: #fff;
}
/* Selector maestro de modo de menú */
.twc-menu-modo-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 10px;
}
.twc-menu-modo-opt {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  border: 1.5px solid #e2e8f0;
  border-radius: 10px;
  padding: 12px 14px;
  cursor: pointer;
  background: #fff;
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.twc-menu-modo-opt:hover { border-color: #cbd5e1; background: #f8fafc; }
.twc-menu-modo-opt.is-active {
  border-color: var(--color-primary, #1f4e8c);
  background: #f0f6ff;
  box-shadow: 0 0 0 1px var(--color-primary, #1f4e8c) inset;
}
.twc-menu-modo-opt input[type="radio"] { margin-top: 3px; width: auto; flex: 0 0 auto; }
.twc-menu-modo-opt .twc-menu-modo-body strong { font-size: 13.5px; color: #1c2433; }
/* Banner de estado activo/inactivo de cada motor de menú */
.twc-menu-estado {
  font-size: 12.5px;
  line-height: 1.45;
  border-radius: 8px;
  padding: 9px 12px;
  margin: 0 0 12px;
}
.twc-menu-estado.is-on { background: #ecfdf5; border: 1px solid #a7f3d0; color: #065f46; }
.twc-menu-estado.is-off { background: #f8fafc; border: 1px solid #e2e8f0; color: #64748b; }
.twc-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 10px;
}
.twc-row.three { grid-template-columns: 1fr 1fr 1fr; }
.twc-field label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: .3px;
  margin-bottom: 4px;
}
.twc-field input[type=text],
.twc-field input[type=number],
.twc-field input[type=tel],
.twc-field input[type=email],
.twc-field input[type=url],
.twc-field input[type=search],
.twc-field input:not([type]),
.twc-field select,
.twc-field textarea {
  width: 100%;
  border: 1px solid #d1d5db;
  background: #fff;
  padding: 11px 12px;
  border-radius: 12px;
  outline: none;
  font-size: 14px;
  font-family: inherit;
  box-sizing: border-box;
}
.twc-field input[type=text]:focus,
.twc-field input[type=number]:focus,
.twc-field input[type=tel]:focus,
.twc-field input[type=email]:focus,
.twc-field input[type=url]:focus,
.twc-field input[type=search]:focus,
.twc-field input:not([type]):focus,
.twc-field select:focus,
.twc-field textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, .12);
}
.twc-field input[type=color] {
  height: 42px;
  width: 100%;
  border: 1px solid #d1d5db;
  border-radius: 12px;
  padding: 4px;
  background: #fff;
  cursor: pointer;
}
.twc-field input[type=file] { font-size: 13px; }
.twc-check {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 6px 0;
}
.twc-check input { width: auto; }
.twc-check label {
  margin: 0;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: #1c2433;
  font-size: 13px;
}
.twc-img-slot {
  display: flex;
  gap: 14px;
  align-items: center;
  padding: 10px;
  border: 1px dashed #c0c8d4;
  border-radius: 6px;
}
.twc-img-slot img {
  max-width: 120px;
  max-height: 80px;
  object-fit: contain;
  background: #f6f7f9;
  border-radius: 4px;
  padding: 4px;
}
.twc-img-slot .ph {
  width: 120px;
  height: 80px;
  background: #f6f7f9;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #aab1bd;
  font-size: 24px;
}
.twc-help {
  font-size: 12px;
  color: #6b7280;
  margin: 4px 0 0;
}
.twc-savebar {
  position: sticky;
  bottom: 0;
  background: #fff;
  padding: 14px 0;
  margin-top: 14px;
  border-top: 1px solid #e6e8ec;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}
/* Tabs de la pantalla Config */
.twc-config-wrap {
  padding: 20px;
}
.twc-config-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}
.twc-config-header h3 { margin: 0; }
.twc-config-header .small-help { margin: 4px 0 0; }
/* .twc-tabset es alias de .section-tabs; los estilos de .twc-tab-btn
   están en .section-tab (canónica). Solo se preserva el layout del contenedor
   y el media-query de .twc-config-header. */
.twc-tabset {
  margin: 0 0 16px;
}

/* ── Panel variantes producto (#25 sprint tienda 2026-05-29) ────────────────── */
.pv-panel { padding: 16px 0; }
.pv-section { border: 1px solid #e2e8f0; border-radius: 8px; padding: 16px; background: #fff; }
.pv-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.pv-atrib-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.pv-atrib-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 20px;
  border: 1.5px solid #cbd5e1;
  background: #f8fafc;
  cursor: pointer;
  font-size: 13px;
  transition: border-color .15s, background .15s;
  user-select: none;
}
.pv-atrib-chip input[type="checkbox"] { margin: 0; accent-color: #1d4ed8; }
.pv-atrib-chip:hover { border-color: #93c5fd; background: #eff6ff; }
.pv-atrib-chip--activo { border-color: #1d4ed8; background: #eff6ff; color: #1d4ed8; font-weight: 600; }
.pv-table { width: 100%; font-size: 13px; }
.pv-table th { font-size: 12px; white-space: nowrap; }
/* Grilla manual de productos — picker estilo TiendaNube (2026-06-01) */
.twe-prod-list{display:flex;flex-direction:column;gap:6px;margin-bottom:8px;}
.twe-prod-item{display:flex;align-items:center;gap:8px;padding:6px 8px;background:#fafbfc;border:1px solid #e6e8ec;border-radius:6px;transition:background .1s,border-color .1s;}
.twe-prod-item:hover{background:#f1f5f9;border-color:#cbd5e1;}
.twe-prod-item.dragging-prod{opacity:.35;cursor:grabbing;}
.twe-prod-item.drop-target-prod{border-top:2px solid var(--primary-dark,#1e40af);}
.twe-prod-drag{color:#c0c8d4;font-size:14px;cursor:grab;user-select:none;flex-shrink:0;padding:0 2px;}
.twe-prod-drag:hover{color:#64748b;}
.twe-prod-thumb{flex:0 0 40px;width:40px;height:40px;border-radius:4px;object-fit:cover;background:#f0f3f7;border:1px solid #e6e8ec;}
.twe-prod-thumb-ph{flex:0 0 40px;width:40px;height:40px;border-radius:4px;background:#f0f3f7;border:1px solid #e6e8ec;display:flex;align-items:center;justify-content:center;color:#c0c8d4;font-size:18px;}
.twe-prod-info{flex:1;min-width:0;}
.twe-prod-name{font-size:12px;font-weight:600;color:#1e293b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.twe-prod-code{font-size:10px;color:#6b7280;}
.twe-prod-del{flex:0 0 22px;width:22px;height:22px;border-radius:50%;border:0;background:transparent;color:#9ca3af;font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;transition:background .12s,color .12s;}
.twe-prod-del:hover{background:#fee2e2;color:#dc2626;}
.twe-prod-counter{font-size:11px;color:#6b7280;margin-bottom:6px;}
.twe-prod-agregar{display:flex;align-items:center;justify-content:center;height:34px;border:1.5px dashed #c0c8d4;border-radius:6px;cursor:pointer;color:#475569;font-size:12px;font-weight:500;background:#fff;transition:background .12s,border-color .12s,color .12s;width:100%;}
.twe-prod-agregar:hover{background:#eef4fb;border-color:var(--primary,#1f4e8c);color:var(--primary,#1f4e8c);}
.twe-prod-empty{text-align:center;padding:16px 8px;color:#94a3b8;font-size:12px;border:1.5px dashed #e6e8ec;border-radius:6px;background:#fafbfc;}
/* Picker de productos de tienda */
.twe-picker-row{transition:background .1s;}
.twe-picker-row:hover{background:#f8fafc;}
.twe-picker-row-sel{background:#eff6ff;}
.twe-picker-row-sel:hover{background:#dbeafe;}

/* =============================================================================
   FIX: Menú grupo colapsado a 1 ítem visible — clase dinámica .menu-group-single-dyn
   FIX2 2026-06-02: el .menu-parent PERMANECE VISIBLE con el label del GRUPO
   (ej: "Proveedores", no "Listado de proveedores"). Se oculta solo la flecha
   caret (::after). El submenu queda oculto. El click handler en app.js ya
   detecta el grupo con 1 item y navega directo a su ruta.
============================================================================= */
/* Mostrar el menu-parent (label del grupo), sin flecha caret */
.menu-group-single-dyn > .menu-parent {
  display: inline-flex !important;
}
.menu-group-single-dyn > .menu-parent::after {
  display: none !important;
  content: "" !important;
}
/* Mantener el submenu oculto — no se despliega */
.menu-group-single-dyn > .submenu {
  display: none !important;
}

/* ── Botones chicos (2026-06-17) ─────────────────────────────────────────── */
.btn-mini { border-radius: 8px !important; }
.btn-xs { border-radius: 8px; }

/* Toolbar INLINE del resultado del informe (2026-06-17): buscador + export (Excel/PDF/
   Word) agrupados a la DERECHA, arriba de la tabla, dentro del card. Una sola pantalla. */
.informe-result-toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.informe-fullview-actions { display: flex; gap: 6px; }
.informe-fullview-search { max-width: 230px; min-width: 150px; height: 32px; }
/* Columnas ordenables del resultado del informe (click en el encabezado) */
.informe-modal-body thead th { cursor: pointer; user-select: none; }
.informe-modal-body thead th:hover { background: #e2e8f0; }
.informe-modal-body thead th[data-sort-dir="asc"]::after { content: " \25B2"; font-size: 9px; color: #64748b; }
.informe-modal-body thead th[data-sort-dir="desc"]::after { content: " \25BC"; font-size: 9px; color: #64748b; }

/* 2026-06-17 (Martín): el doble-click en el número de comprobante no debe seleccionar
   el texto del link (interfería con el handler). Va junto al debounce de viewDocument. */
.ver-comprobante-link { -webkit-user-select: none; user-select: none; }

/* ── Fotocopias: administrador de precios — layout responsivo (2026-06-20) ──
   La card de config de fotocopias NO tiene max-width fijo: aprovecha todo el
   ancho disponible del .view (como las demás pantallas de config del ERP).
   La tabla de escalones de hojas usa inputs más anchos y la card la contiene
   sin ahogarla. En mobile (<768px) la tabla hace scroll horizontal (ya tenía
   overflow-x:auto) y las grillas colapsan a 1 columna (hereda .form-grid media).
   El toggleCard header usa flex wrap para que en mobile apile el botón abajo. */
.fc-toggle-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.fc-config-card {
  /* sin max-width: ocupa el ancho del .view como las demás config-cards */
}
/* Tabla de escalones de páginas: inputs un poco más anchos en desktop */
@media (min-width: 900px) {
  .fc-escpag-table input.input {
    width: 80px !important;
  }
  .fc-escpag-table .fc-escpag-desde {
    width: 80px !important;
  }
}
/* Extras y Colores: en desktop ancho (≥1100px) usa hasta 4 cols ya que
   .form-grid tiene repeat(4, minmax(160px, 1fr)) por defecto — se respeta.
   En rango medio (768–1099px) forzamos 3 cols para aprovechar el ancho sin
   aplastar los labels. */
@media (min-width: 768px) and (max-width: 1099px) {
  .fc-config-card .form-grid {
    grid-template-columns: repeat(3, minmax(140px, 1fr));
  }
}
/* Contraseña del admin: en desktop ocupa hasta la mitad del card, no un
   cuarto fijo (max-width:340px original era inline, se sobreescribe acá). */
@media (min-width: 900px) {
  .fc-config-card .fc-admin-pass-field {
    max-width: 440px;
  }
}
/* Mobile ≤ 767px: tablas de escalones en scroll horizontal, grillas a 1 col
   (heredado de la media de .form-grid ≤1000px), contraseña full-width. */

/* ============================================================================
   WIZARD DE ONBOARDING
   ============================================================================ */

#erp-wizard-toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 9999;
  max-width: 380px;
  width: calc(100vw - 48px);
  opacity: 0;
  transform: translateY(16px) scale(0.97);
  transition: opacity 0.28s ease, transform 0.28s ease;
  pointer-events: none;
}

#erp-wizard-toast.wizard-toast-in {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

#erp-wizard-toast.wizard-toast-out {
  opacity: 0;
  transform: translateY(10px) scale(0.97);
}

.wizard-toast-inner {
  background: #fff;
  border: 1px solid #c7d2e8;
  border-left: 4px solid var(--primary);
  border-radius: 10px;
  box-shadow: 0 4px 24px rgba(44,110,242,.15), 0 1px 4px rgba(0,0,0,.08);
  padding: 16px 18px 14px;
}

.wizard-toast-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.wizard-toast-icon {
  color: var(--primary);
  font-size: 18px;
  flex-shrink: 0;
  line-height: 1;
}

.wizard-toast-title {
  flex: 1;
  font-size: 14px;
  font-weight: 600;
  color: #1a2944;
}

.wizard-toast-close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 20px;
  color: #6b7a99;
  line-height: 1;
  padding: 0 2px;
  flex-shrink: 0;
  transition: color .15s;
}
.wizard-toast-close:hover { color: #1a2944; }

.wizard-toast-body {
  font-size: 13px;
  color: #3d4f6b;
  line-height: 1.55;
  margin: 0 0 12px;
}

.wizard-toast-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.wizard-btn-skip {
  font-size: 12px;
  color: #6b7a99;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}
.wizard-btn-skip:hover { color: #1a2944; }


/* ==========================================================================
   PULIDO VISUAL 2026-06-28 — Login + Dashboard + Micro-interacciones
   Performance: solo transform/opacity (GPU), 60fps. No layout thrash.
   Reduced-motion: animaciones desactivadas con @media prefers-reduced-motion.
   ========================================================================== */

/* ---------- 1. LOGIN — fondo animado + card entrada ---------- */

/* Orbs del fondo: movimiento flotante lento y suave */
@keyframes loginOrbDrift1 {
  0%   { transform: translate(0, 0) scale(1); }
  33%  { transform: translate(18px, -22px) scale(1.04); }
  66%  { transform: translate(-12px, 14px) scale(.97); }
  100% { transform: translate(0, 0) scale(1); }
}
@keyframes loginOrbDrift2 {
  0%   { transform: translate(0, 0) scale(1); }
  40%  { transform: translate(-16px, 20px) scale(1.05); }
  75%  { transform: translate(10px, -14px) scale(.96); }
  100% { transform: translate(0, 0) scale(1); }
}
@keyframes loginOrbDrift3 {
  0%   { transform: translate(0, 0) scale(1); }
  50%  { transform: translate(14px, 18px) scale(1.06); }
  100% { transform: translate(0, 0) scale(1); }
}

/* Dotgrid: pulso de opacidad muy sutil */
@keyframes loginDotPulse {
  0%, 100% { opacity: .55; }
  50%       { opacity: .85; }
}

/* Card de login: entrada con fade + scale */
@keyframes loginCardIn {
  from { opacity: 0; transform: translateY(18px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.login-orb-1 {
  animation: loginOrbDrift1 14s ease-in-out infinite;
}
.login-orb-2 {
  animation: loginOrbDrift2 17s ease-in-out infinite;
}
.login-orb-3 {
  animation: loginOrbDrift3 11s ease-in-out infinite;
}
.login-dotgrid {
  animation: loginDotPulse 8s ease-in-out infinite;
}
.login-card {
  animation: loginCardIn .45s cubic-bezier(.22,.68,0,1.2) both;
}

/* ---------- 2. DASHBOARD — hover lift en cards y KPIs ---------- */

/* KPI cards: aparecen con opacidad 0 y se revelan vía JS (stagger).
   La clase .kpi-reveal-ready la agrega JS cuando el dashboard carga. */
.card.kpi {
  transition: box-shadow .18s ease, transform .18s ease;
  will-change: transform;
}
.card.kpi:hover {
  transform: translateY(-3px);
  box-shadow:
    0 8px 24px rgba(15,23,42,.13),
    0 2px 6px rgba(15,23,42,.07);
}

/* Dashboard modules: hover lift */
.dashboard-module.card {
  transition: box-shadow .18s ease, transform .18s ease, opacity .15s ease;
}
.dashboard-module.card:hover {
  transform: translateY(-2px);
  box-shadow:
    0 6px 20px rgba(15,23,42,.10),
    0 2px 5px rgba(15,23,42,.06);
  will-change: transform;
}

/* Estado inicial de reveal (antes del stagger JS) */
.kpi-stagger-init {
  opacity: 0;
  transform: translateY(10px) scale(.98);
  transition: opacity .35s ease, transform .35s ease;
}
.kpi-stagger-init.kpi-stagger-in {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.module-stagger-init {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .35s ease, transform .35s ease;
}
.module-stagger-init.module-stagger-in {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- 3. MICRO-INTERACCIONES GLOBALES ---------- */

/* Botones: hover/active con leve elevación */
.btn {
  transition: background .14s ease, transform .1s ease, box-shadow .12s ease, opacity .1s ease;
}
.btn:not(:disabled):hover {
  transform: translateY(-1px);
  box-shadow: 0 3px 8px rgba(15,23,42,.14);
  will-change: transform;
}
.btn:not(:disabled):active {
  transform: translateY(0) scale(.97);
  box-shadow: none;
}
/* .btn:disabled ya definido en línea 2056 — no duplicar */

/* Inputs: foco con anillo suave */
.input:focus,
input.input:focus,
textarea.input:focus,
select.input:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(59,130,246,.18), 0 1px 3px rgba(15,23,42,.08);
  border-color: var(--primary, #1e3a8a);
  transition: box-shadow .15s ease, border-color .15s ease;
}

/* Modales: salida con fade (la entrada ya estaba animada vía appModalSlideIn) */
@keyframes appModalSlideOut {
  from { transform: translateY(0); opacity: 1; }
  to   { transform: translateY(12px) scale(.98); opacity: 0; }
}
@keyframes appModalFadeOut {
  from { opacity: 1; }
  to   { opacity: 0; }
}
.app-modal.modal-closing {
  animation: appModalSlideOut .18s ease forwards;
}
.app-modal-overlay.modal-overlay-closing {
  animation: appModalFadeOut .18s ease forwards;
}

/* Tabs: transición del indicador inferior */
.product-modal-tab {
  transition: color .14s ease, background .14s ease, border-bottom-color .14s ease;
}

/* Filas de tabla: hover sutil */
tbody tr {
  transition: background .1s ease;
}

/* Foco accesible visible en elementos interactivos */
:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* ---------- 4. REDUCED-MOTION — respeto total ---------- */
@media (prefers-reduced-motion: reduce) {
  /* Login: sin animaciones de fondo ni entrada */
  .login-orb-1, .login-orb-2, .login-orb-3,
  .login-dotgrid, .login-card {
    animation: none !important;
  }

  /* Dashboard: revelar inmediatamente sin transiciones */
  .kpi-stagger-init,
  .module-stagger-init {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .card.kpi, .dashboard-module.card {
    transition: none !important;
    will-change: auto;
  }
  .card.kpi:hover, .dashboard-module.card:hover {
    transform: none !important;
  }

  /* Botones: sin movimiento, solo color */
  .btn {
    transition: background .12s ease, opacity .12s ease !important;
    will-change: auto;
  }
  .btn:not(:disabled):hover { transform: none !important; box-shadow: none !important; }
  .btn:not(:disabled):active { transform: none !important; }

  /* Modales: sin slide */
  .app-modal { animation: none !important; }
  .app-modal-overlay { animation: none !important; }
  .app-modal.modal-closing { animation: none !important; }
  .app-modal-overlay.modal-overlay-closing { animation: none !important; }

  /* Tabs: sin transición */
  .product-modal-tab { transition: none !important; }

  /* Filas: sin transición */
  tbody tr { transition: none !important; }
}

/* ============================================================
   LOGÍSTICA — RUTAS: tarjetas mobile (≤768px)
   Scoped con prefijo .rutas-* para no contaminar el global.
   ============================================================ */

/* Card-header del listado: wrap en mobile para que el botón
   "+ Nueva ruta" no se solape con el título */
.rutas-card-header-wrap {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.rutas-card-header-wrap strong { flex: 1; min-width: 0; }

/* Contenedor del listado de cards */
.rutas-cards-mobile {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px;
}

/* Cada card individual */
.rutas-card-mobile {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 14px 14px 12px;
  box-shadow: 0 1px 3px rgba(0,0,0,.06);
}

/* Cabecera: swatch + nombre + conteo clientes */
.rutas-card-mobile__header {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.rutas-card-mobile__nombre {
  font-size: 16px;
  font-weight: 600;
  color: #111827;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rutas-card-mobile__clientes {
  font-size: 12px;
  color: #6b7280;
  white-space: nowrap;
}

/* Descripción */
.rutas-card-mobile__desc {
  font-size: 13px;
  color: #6b7280;
  margin: 0 0 8px;
  line-height: 1.4;
}

/* Localidades */
.rutas-card-mobile__locs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 12px;
}
.rutas-card-mobile__loc {
  font-size: 12px;
}
.rutas-card-mobile__empty-loc {
  font-size: 12px;
  color: #9ca3af;
}

/* Botones de acción */
.rutas-card-mobile__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.rutas-card-mobile__actions .btn {
  min-height: 40px;
  font-size: 14px;
  padding: 0 14px;
  flex-shrink: 0;
}
/* "Dar de baja" destacado en rojo, separado visualmente */
.rutas-card-mobile__baja {
  color: #ef4444 !important;
  margin-left: auto;
}

/* ==========================================================================
   WIZARD TOUR GUIADO (motor spotlight + tooltip)
   ========================================================================== */

/* Overlay del tour — cubre TODO excepto el elemento resaltado (box-shadow) */
#wizard-tour-overlay {
  position: fixed;
  inset: 0;
  /* z-index debajo de confirm-dialog (10000010) pero encima de todo lo demás */
  z-index: 10000007;
  pointer-events: none; /* los clicks en el spotlight pasan al elemento real */
  transition: box-shadow .25s ease;
}
#wizard-tour-overlay.wizard-tour-active {
  pointer-events: auto;
}

/* Panel tooltip del tour */
#wizard-tour-panel {
  position: fixed;
  z-index: 10000008;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 8px 40px rgba(15,23,42,.28), 0 1px 4px rgba(0,0,0,.08);
  border: 1px solid #e2e8f0;
  width: 300px;
  max-width: calc(100vw - 24px);
  padding: 20px 20px 16px;
  animation: wizardPanelIn .2s ease;
}
@keyframes wizardPanelIn {
  from { opacity: 0; transform: translateY(6px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.wizard-tour-panel-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 8px;
  gap: 8px;
}
.wizard-tour-panel-title {
  font-weight: 700;
  font-size: .95rem;
  color: #1e293b;
  flex: 1;
  line-height: 1.3;
}
.wizard-tour-panel-close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 18px;
  color: #94a3b8;
  padding: 0 2px;
  line-height: 1;
  flex-shrink: 0;
  transition: color .12s;
}
.wizard-tour-panel-close:hover { color: #1e293b; }

.wizard-tour-panel-body {
  font-size: .88rem;
  color: #475569;
  line-height: 1.55;
  margin-bottom: 16px;
}

.wizard-tour-panel-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.wizard-tour-counter {
  font-size: .78rem;
  color: #94a3b8;
  flex-shrink: 0;
}
.wizard-tour-nav {
  display: flex;
  align-items: center;
  gap: 6px;
}
.wizard-tour-skip {
  font-size: .78rem;
  color: #94a3b8;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  transition: color .12s;
}
.wizard-tour-skip:hover { color: #475569; }

/* Borde iluminado sobre el elemento resaltado */
#wizard-tour-highlight-ring {
  position: fixed;
  z-index: 10000007;
  border: 2px solid var(--primary);
  border-radius: 6px;
  pointer-events: none;
  box-shadow: 0 0 0 2px rgba(44,110,242,.18);
  transition: all .2s ease;
}

/* Mobile: panel fijo abajo */

/* Botón "?" en la topbar */
#wizard-help-wrap {
  position: relative;
  display: none; /* se muestra via JS si wizardEsActivo() */
}
#wizard-help-btn {
  /* hereda .menu-icon-btn styles del topbar */
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -.5px;
}

/* Dropdown del "?" */
#wizard-help-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  background: #fff;
  border: 1px solid #e6e8ec;
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0,0,0,.12);
  min-width: 220px;
  z-index: 10000009;
  overflow: hidden;
}
#wizard-help-dropdown.open { display: block; }
.wizard-help-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 11px 16px;
  font-size: .88rem;
  color: #1e293b;
  cursor: pointer;
  transition: background .1s;
}
.wizard-help-item:hover:not(:disabled) { background: #f1f5f9; }
.wizard-help-item:disabled {
  color: #94a3b8;
  cursor: default;
}
.wizard-help-divider {
  height: 1px;
  background: #f1f5f9;
  margin: 0;
}

/* ── Wizard Checklist "Primeros pasos" (F2 2026-07-01) ─────────────────────── */
#wizard-cl-dash-wrap {
  margin-bottom: 14px;
}

.wizard-checklist-card {
  padding: 14px 16px 12px;
  border-left: 4px solid var(--primary);
}

.wizard-cl-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  gap: 8px;
}

.wizard-cl-titulo-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: .95rem;
}

.wizard-cl-icono {
  color: #f59e0b;
  font-size: 1.1rem;
}

.wizard-cl-badge {
  background: #eff6ff;
  color: var(--primary);
  border: 1px solid #bfdbfe;
  border-radius: 999px;
  font-size: .78rem;
  padding: 1px 9px;
  font-weight: 600;
}

.wizard-cl-toggle {
  font-size: .82rem;
  color: #64748b;
  padding: 2px 6px;
  white-space: nowrap;
}

.wizard-cl-progress-wrap {
  height: 5px;
  background: #e2e8f0;
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 10px;
}

.wizard-cl-progress-bar {
  height: 100%;
  background: var(--primary);
  border-radius: 3px;
  transition: width .4s ease;
}

.wizard-cl-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.wizard-cl-paso {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: #fff;
  transition: border-color .15s;
}

.wizard-cl-paso.wizard-cl-hecho {
  background: #f0fdf4;
  border-color: #bbf7d0;
}

.wizard-cl-check {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid #cbd5e1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .85rem;
  color: #94a3b8;
  margin-top: 1px;
}

.wizard-cl-hecho .wizard-cl-check {
  border-color: #16a34a;
  color: #16a34a;
  background: #dcfce7;
}

.wizard-cl-info {
  flex: 1;
  min-width: 0;
}

.wizard-cl-label {
  display: block;
  font-size: .9rem;
  font-weight: 600;
  color: #1e293b;
  line-height: 1.3;
}

.wizard-cl-hecho .wizard-cl-label {
  color: #166534;
  text-decoration: line-through;
  font-weight: 400;
}

.wizard-cl-desc {
  display: block;
  font-size: .8rem;
  color: #64748b;
  margin-top: 2px;
  line-height: 1.4;
}

.wizard-cl-ir {
  flex-shrink: 0;
  font-size: .8rem;
  padding: 3px 10px;
}

.wizard-cl-tildar {
  flex-shrink: 0;
  font-size: 1rem;
  color: #94a3b8;
  padding: 3px 6px;
}

.wizard-cl-tildar:hover {
  color: #16a34a;
}


/* =========================================================
   POS FULLSCREEN (body.pos-fullscreen)
   Clase aplicada SOLO en la ruta #venta-basica.
   Oculta el chrome del ERP (topbar + sidebar) y expande
   el punto de venta a viewport completo.
   Se quita en setPage() al navegar a cualquier otra sección.
   IMPORTANTE: reglas NUEVAS bajo este scope — no modifica
   nada de lo existente.
   ========================================================= */

/* Ocultar topbar y sidebar del ERP */
body.pos-fullscreen #topbar,
body.pos-fullscreen .sidebar {
  display: none !important;
}

/* El <main> del ERP ya tiene margin-left por el sidebar;
   en fullscreen lo anulamos para que ocupe todo */
body.pos-fullscreen main.main {
  margin: 0 !important;
  padding: 0 !important;
  width: 100vw !important;
  max-width: 100vw !important;
  height: 100dvh !important;
  min-height: 100dvh !important;
  overflow: hidden !important;
}

/* El contenedor #view que recibe el innerHTML del POS */
body.pos-fullscreen #view {
  height: 100dvh !important;
  overflow: hidden !important;
  padding: 0 !important;
}

body.pos-fullscreen .pos-wrap {
  height: 100dvh !important;
  min-height: 100dvh !important;
  overflow: hidden;
}

/* ── Ranking en lista (Analytics tienda: productos/categorías/búsquedas más
   vistas) ── Fila "posición · nombre · valor" en una sola línea. Robusta en
   mobile: el nombre trunca con ellipsis (min-width:0) y el valor a la derecha
   NUNCA se corta ni queda fuera del viewport. Sirve igual en desktop. */
.rank-list { list-style: none; margin: 0; padding: 0; }
.rank-list-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 2px;
  border-bottom: 1px dashed var(--border, #e2e8f0);
}
.rank-list-row:last-child { border-bottom: 0; }
.rank-list-pos {
  flex: 0 0 auto;
  min-width: 16px;
  color: var(--muted, #6b7280);
  font-size: 12px;
  font-weight: 600;
  text-align: right;
}
.rank-list-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink, #172033);
  font-weight: 500;
}
.rank-list-val {
  flex: 0 0 auto;
  color: var(--ink, #172033);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* === Diagrama de procesos por empresa — TANDA 2 (F3), 2026-08-19 ===========
   Prefijo pc- para todo lo específico del diagrama (nodos/flechas/simulación).
   El panel de edición del paso reusa .bulk-modal/.badge/.btn canónicos; acá
   solo lo que es realmente nuevo (ejes del modal + filas de delta). */
.pc-diagrama-wrap { overflow-x: auto; padding: 6px 2px 14px; }
.pc-diagrama {
  display: flex;
  align-items: stretch;
  gap: 0;
  min-width: max-content;
  padding: 4px 2px;
}
.pc-node {
  flex: 0 0 auto;
  min-width: 148px;
  max-width: 190px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 10px);
  background: var(--panel);
  padding: 10px 12px;
  text-align: left;
  font: inherit;
  color: inherit;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.pc-node-fijo {
  background: #f1f5f9;
  border-style: dashed;
  color: var(--muted);
  justify-content: center;
  align-items: center;
  text-align: center;
  min-width: 100px;
  max-width: 120px;
}
.pc-node-fijo .pc-node-title { font-weight: 600; font-size: 13px; }
.pc-node-config {
  cursor: pointer;
  transition: box-shadow .15s ease, transform .15s ease;
}
.pc-node-config:hover, .pc-node-config:focus-visible {
  box-shadow: 0 4px 14px rgba(15,23,42,.12);
  transform: translateY(-1px);
  outline: none;
  border-color: var(--primary);
}
.pc-node-config .pc-node-title { font-weight: 700; font-size: 14px; }
.pc-node-off { opacity: .55; }
.pc-node-off .pc-node-title { text-decoration: line-through; text-decoration-color: var(--muted); }
.pc-node-badges { display: flex; flex-wrap: wrap; gap: 4px; }

.pc-arrow {
  flex: 0 0 auto;
  width: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pc-arrow svg { width: 100%; height: 20px; display: block; }
.pc-arrow-line {
  fill: none;
  stroke: var(--primary);
  stroke-width: 2.5;
  stroke-dasharray: 6 6;
}
.pc-arrow-off .pc-arrow-line {
  stroke: var(--muted);
  stroke-dasharray: 3 5;
  opacity: .6;
}
.pc-arrow-head { fill: var(--primary); }
.pc-arrow-off .pc-arrow-head { fill: var(--muted); opacity: .6; }

/* Animación de flujo (dash-offset). Respeta prefers-reduced-motion: sin la
   preferencia "reduce" (o sea, sin preferencia explícita o con "no-preference"),
   las flechas activas laten; con reduce, quedan estáticas. */
@media (prefers-reduced-motion: no-preference) {
  .pc-arrow:not(.pc-arrow-off) .pc-arrow-line {
    animation: pc-flow 1.1s linear infinite;
  }
}
@keyframes pc-flow {
  to { stroke-dashoffset: -24; }
}

.pc-simular-dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 4px rgba(22,163,74,.2);
  transform: translate(-50%, -50%);
  transition: left .7s ease-in-out, top .7s ease-in-out;
  pointer-events: none;
  z-index: 5;
}
.pc-simular-tooltip {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(-50%, -100%);
  background: var(--text);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 8px;
  border-radius: 6px;
  white-space: nowrap;
  opacity: 0;
  transition: left .7s ease-in-out, top .7s ease-in-out, opacity .2s ease;
  pointer-events: none;
  z-index: 6;
}
.pc-simular-tooltip.show { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .pc-simular-dot, .pc-simular-tooltip { transition: none; }
}

.pc-proceso-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }

.pc-modal-axis { border: 1px solid var(--border); border-radius: var(--radius-md, 10px); padding: 10px 12px; margin-bottom: 10px; }
.pc-modal-axis-desc { color: var(--muted); font-size: 12.5px; margin-top: 4px; }
.pc-delta-row { padding: 3px 0; font-size: 13px; }
.pc-delta-otorga { color: var(--success-dark, #15803d); }
.pc-delta-quita { color: var(--danger); }
.pc-delta-warning { color: #92400e; background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px; padding: 8px 10px; margin-top: 6px; font-size: 13px; }

/* F1 MODO-MOBILE (2026-08-02): los bloques @media mobile (max-width <=768px)
   que vivian en este archivo se MOVIERON a styles-mobile.css — asi el modo
   mobile forzado (erp_modo_mobile="1") tambien los aplica en pantallas anchas.
   Regla: estilos mobile nuevos van a styles-mobile.css, NO aca. Los @media de
   layout ancho (900/1000/1100/min-width) siguen aca porque son de desktop. */

/* 2026-08-21 CSP fix: hover del checkbox de tipo en el popover de filtro de
   Conciliación MP (mpconc-tipos-pop) — antes onmouseover/onmouseout inline,
   muertos por CSP script-src sin unsafe-inline. Reemplazado por :hover puro. */
.mpconc-tipo-row:hover {
  background: #f1f5f9;
}

/* ── Filtros compactos en popup (2026-08-22, Martín: "que los filtros sean un
   popup así la UI queda menos cargada y los listados muestran más
   comprobantes") ─────────────────────────────────────────────────────────
   Motor JS: iluFiltrosCompactos() en app.js. La card de filtros colapsa a
   una barra (nodos .ilu-filtros-keep = tabs + buscador + fila de acciones)
   y el resto se abre como popup centrado (la MISMA card, mismos ids y
   listeners — cero cambios de wiring). */
.ilu-filtros-compacta > * { display: none !important; }
.ilu-filtros-compacta > .ilu-filtros-keep { display: flex !important; margin: 0 !important; }
.ilu-filtros-compacta > .ilu-filtros-barra { display: flex !important; }
.ilu-filtros-compacta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.ilu-filtros-compacta > .ilu-filtros-keep.field { flex: 1 1 240px; }
.ilu-filtros-compacta > .ilu-filtros-keep.field > label { display: none; }
.ilu-filtros-compacta > .ilu-filtros-keep[data-keep-fila] { flex-basis: 100%; justify-content: space-between; flex-wrap: wrap; gap: 10px; }
.ilu-filtros-barra { display: none; align-items: center; gap: 8px; }
.ilu-filtros-popup-card {
  position: fixed !important;
  z-index: 10011;
  left: 50%;
  top: 6vh;
  transform: translateX(-50%);
  width: min(980px, 94vw);
  max-height: 86vh;
  overflow: auto;
}
.ilu-filtros-popup-card { box-shadow: 0 24px 64px rgba(15, 23, 42, .38); }
.ilu-filtros-popup-card .ilu-filtros-barra { display: none !important; }
.ilu-filtros-backdrop { position: fixed; inset: 0; background: rgba(15, 23, 42, .45); z-index: 10010; }
.ilu-filtros-cerrar-wrap { display: none; }
.ilu-filtros-popup-card .ilu-filtros-cerrar-wrap {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  position: sticky;
  bottom: 0;
  background: var(--card-bg, #fff);
  padding: 10px 0 2px;
  margin-top: 12px;
  border-top: 1px solid #e5e7eb;
}
@media (max-width: 768px) {
  .ilu-filtros-popup-card { top: 3vh; max-height: 92vh; width: 96vw; }
}

/* ── Densidad de tablas por usuario (2026-08-23, Martín: "que las tablas se
   vean más cómodamente en pantallas de 17 pulgadas") ─────────────────────
   Selector en Mi cuenta → Apariencia → Vista. Per-equipo (localStorage
   erp_densidad_tablas), clase sobre <body>. Solo tablas del ERP web —
   comprobante-v2 y las PWAs tienen sus propias hojas y no se tocan. */
body.densidad-tablas-comoda th {
  font-size: 14px;
  padding: 15px 14px;
}
body.densidad-tablas-comoda td {
  font-size: 15.5px;
  padding: 14px 15px;
}
body.densidad-tablas-compacta th {
  font-size: 12px;
  padding: 8px 10px;
}
body.densidad-tablas-compacta td {
  font-size: 13px;
  padding: 6px 10px;
}

/* Popup de filtros: las SOLAPAS de tipo de comprobante son navegación, no
   filtros — dentro del popup se ocultan (2026-08-23, Martín: "cuando abra
   este popup no tendrían que aparecer los tipos de comprobantes"). En la
   barra compacta siguen visibles como siempre. */
.ilu-filtros-popup-card > [data-keep-tabs] {
  display: none !important;
}

/* Elementos que viven SOLO dentro del popup de filtros (2026-08-23, Martín:
   "filtros avanzados que esté dentro del popup") — en la barra compacta se
   ocultan; al abrir el popup aparecen con el resto de los controles. */
.ilu-filtros-compacta [data-solo-popup] {
  display: none !important;
}

/* ── Tabla CC: fin del solape con descripciones largas (2026-08-24, Martín:
   "cuando son columnas muy anchas podemos mejorar la UI para que no pase
   esto" — captura: la descripción del recibo pintada ENCIMA de Debe/Haber).
   Causa: convivían dos reglas (.cc-access-table > table auto !important vs
   .cc-access-table table fixed con anchos nth-child); cuando ganaba fixed,
   el nowrap desbordaba la celda y se montaba sobre la siguiente. Acá se
   fuerza SIEMPRE layout auto y la Descripción envuelve con tope de ancho —
   las descripciones largas pasan a 2-3 líneas en vez de estirar la tabla
   (menos scroll horizontal) y el solape es imposible por diseño. */
.cc-access-table table,
.cc-access-table > table {
  table-layout: auto !important;
  width: auto !important;
  min-width: 100% !important;
}
.cc-access-table td.cc-desc {
  white-space: normal !important;
  overflow-wrap: break-word;
  max-width: 420px;
  min-width: 240px;
}
.cc-access-table td.cc-num {
  white-space: nowrap !important;
}

/* Cinturón anti-solape (2026-08-24, segunda pasada): pase lo que pase con el
   layout de la tabla CC, una celda desbordada JAMÁS se pinta sobre la vecina
   — el contenido se recorta en su celda. Con layout auto (el caso normal) es
   inofensivo: las celdas dimensionan por contenido y nada se recorta. */
.cc-access-table td {
  overflow: hidden;
}

/* Modal Nuevo despacho (2026-08-27, Martín: "es un modal angosto, estaría
   bueno que sea más amplio"): dos columnas en desktop — qué sale a la
   izquierda, cómo sale a la derecha — y una sola columna en mobile. */
@media (max-width: 900px) {
  .desp-modal-cols { grid-template-columns: 1fr !important; }
}

/* Tarea 3 (2026-09-20, Martín: "los turnos anteriores en la pantalla, como
   tabla al lado del turno actual, no en un modal"). Pantalla de Caja/Turno
   (renderCajaTurno): dos columnas en desktop — turno actual a la izquierda,
   historial de turnos anteriores a la derecha — apiladas en mobile via
   styles-mobile.css (mismo criterio que .desp-modal-cols de arriba). */
.caja-turno-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
  gap: 16px;
  align-items: start;
}
.caja-turno-col-actual .card,
.caja-turno-col-historial .card {
  max-width: none; /* el ancho lo da la columna del grid, no el max-width fijo de siempre */
}

/* 2026-09-29 (Martín, flechas en compras/stock): el encabezado fijo tapaba la
   fila seleccionada al subir con el teclado. scrollIntoView respeta
   scroll-margin-top → la fila queda debajo del thead. */
.list-sticky-wrap tbody tr,
.table-wrap tbody tr { scroll-margin-top: 44px; }

/* Armador de publicaciones ML (2026-10-08, U1-U3): 2 columnas + vista previa
   con lo que cobra ML. En pantallas angostas la vista previa baja abajo. */
.mlarm-filtros { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.mlarm-filtros input[type="text"] { flex: 1; min-width: 220px; max-width: 420px; }
.mlarm-chk { display: inline-flex; align-items: center; gap: 6px; font-weight: normal; cursor: pointer; }
.mlarm-chks { display: flex; flex-direction: column; gap: 4px; justify-content: center; }
.mlarm-warn { color: #b45309; }
.mlarm-req { color: var(--danger); }
.mlarm-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 20px; margin-top: 14px; align-items: start; }
.mlarm-form { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.mlarm-sec { border: 1px solid var(--line); border-radius: 8px; padding: 12px 14px; background: var(--panel); }
.mlarm-sec h4 { margin: 0 0 8px; font-size: 14px; }
.mlarm-sec:empty { display: none; }
.mlarm-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.mlarm-4col { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 4px; }
.mlarm-4col input { width: 100%; }
.mlarm-cat-btn { margin: 2px; }
.mlarm-foto { position: relative; cursor: pointer; border: 2px solid transparent; border-radius: 6px; padding: 2px; }
.mlarm-foto.sel { border-color: var(--primary); }
.mlarm-foto img { width: 72px; height: 72px; object-fit: cover; border-radius: 4px; display: block; }
.mlarm-foto input { position: absolute; top: 4px; left: 4px; }
.mlarm-preview { position: sticky; top: 12px; display: flex; flex-direction: column; gap: 12px; }
.mlarm-prev-card { border: 1px solid var(--line); border-radius: 8px; padding: 12px; background: var(--panel); }
.mlarm-prev-img { aspect-ratio: 1 / 1; background: var(--bg); border-radius: 6px; display: flex; align-items: center; justify-content: center; overflow: hidden; margin-bottom: 8px; }
.mlarm-prev-img img { width: 100%; height: 100%; object-fit: contain; }
.mlarm-prev-tit { font-size: 15px; margin: 4px 0; line-height: 1.3; word-break: break-word; }
.mlarm-prev-precio { font-size: 24px; font-weight: 600; }
.mlarm-prev-envio { color: var(--success); font-weight: 600; font-size: 13px; margin-top: 4px; }
.mlarm-prev-vars { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 4px; }
.mlarm-costos { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; background: var(--panel); font-size: 13px; }
.mlarm-costos-tit { font-weight: 600; margin-bottom: 6px; }
.mlarm-costos-row { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; }
.mlarm-costos-neto { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 6px; font-weight: 700; font-size: 15px; }
.mlarm-acciones { display: flex; gap: 8px; }
.mlarm-acciones .btn { flex: 1; }
.mlarm-ok { color: var(--success); font-weight: 600; font-size: 13px; }
.mlarm-err { color: var(--danger); font-size: 13px; }
.mlarm-err ul, .mlarm-avisos { margin: 4px 0 0; padding-left: 18px; }
.mlarm-avisos { color: #b45309; font-size: 12px; }
@media (max-width: 900px) {
  .mlarm-grid { grid-template-columns: 1fr; }
  .mlarm-preview { position: static; }
}
@media (max-width: 560px) {
  .mlarm-2col { grid-template-columns: 1fr; }
  .mlarm-4col { grid-template-columns: 1fr 1fr; }
}

/* Importar envío a Full a PANTALLA COMPLETA (2026-10-08, Martín). */
#pc-modal-content.mlf-import-full {
  width: 100vw; height: 100vh; max-width: none; max-height: none; margin: 0;
  border-radius: 0; padding: 16px 20px; box-sizing: border-box;
  display: flex; flex-direction: column; overflow: hidden;
}
.mlf-import-full .mlf-res { flex: 1; min-height: 0; display: flex; flex-direction: column; margin-top: 14px; }
.mlf-import-full .mlf-tabla { flex: 1; min-height: 160px; overflow: auto; }
.mlf-res .mlf-tabla { max-height: none; }
.mlf-res:not(:has(.mlf-tabla)) { overflow: auto; }
