/* ╔══════════════════════════════════════════════════════════════════════╗
   ║  ElectroSoftERP — Capa MÍNIMA sobre ArchitectUI HTML PRO nativo        ║
   ║                                                                          ║
   ║  Política estricta: NO pelear con `base.min.css`. Solo añadir helpers   ║
   ║  que no estén en la plantilla nativa:                                   ║
   ║    1) Tipografía Inter (sobrescribe la sans-serif del tema)             ║
   ║    2) Z-index modal por encima del sidebar fixed (bug nativo BS4)       ║
   ║    3) Form labels visibles (BS4 los hace muy pequeños)                  ║
   ║    4) Toast container (no incluido en ArchitectUI)                      ║
   ║    5) Helpers ERP: tabular-nums, POS, page-title small refinement       ║
   ║                                                                          ║
   ║  Todo lo demás (cards, badges, botones, sidebar, tablas, dropdowns)     ║
   ║  se respeta del CSS nativo de ArchitectUI sin modificación.             ║
   ╚══════════════════════════════════════════════════════════════════════╝ */


/* ────────────────────────────────────────────────────────────────────────
   1) TIPOGRAFÍA Inter (Google Fonts) sobre el sans-serif base
   ──────────────────────────────────────────────────────────────────────── */
html, body,
.app-header, .app-sidebar, .app-main, .vertical-nav-menu,
.page-title-heading, .card-title, .card-header, .table, .form-control, .btn,
input, button, select, textarea {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
}

code, kbd, samp, pre, .tabular-nums, .font-monospace {
    font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.tabular-nums { font-variant-numeric: tabular-nums; }


/* ────────────────────────────────────────────────────────────────────────
   2) MODALES — backdrop full viewport + bloqueo interacción del fondo
      BS4 calcula altura del backdrop con 100% del padre, lo que falla cuando
      body.modal-open tiene overflow:hidden y el body es más alto que viewport.
      Forzamos 100vw x 100vh con position:fixed inset:0.
   ──────────────────────────────────────────────────────────────────────── */

/* Backdrop SIEMPRE cubre viewport completo y con oscuridad fuerte
   IMPORTANTE: ArchitectUI nativo aplica `background-color:#000; opacity:.5` al
   .modal-backdrop.show, lo que da un gris muy ligero. Usamos #000 sólido
   con opacity 0.7 para un velo claramente notable (estilo Stripe/Linear). */
.modal-backdrop,
.modal-backdrop.show,
.modal-backdrop.fade.show {
    position: fixed !important;
    top: 0 !important; left: 0 !important;
    right: 0 !important; bottom: 0 !important;
    width: 100vw !important;
    height: 100vh !important;
    z-index: 1080 !important;
    background-color: #000 !important;
    opacity: 0.7 !important;
}

/* Modal contenedor también full viewport */
.modal {
    position: fixed !important;
    top: 0 !important; left: 0 !important;
    width: 100vw !important;
    height: 100vh !important;
    z-index: 1090 !important;
}

.tooltip { z-index: 1100 !important; }
.popover { z-index: 1100 !important; }

/* SweetAlert2 por defecto usa z-index 1060, que queda DEBAJO de nuestros
   modales (1090). Lo subimos para que las alertas/confirmaciones siempre
   aparezcan por encima de cualquier modal abierto. */
.swal2-container { z-index: 11000 !important; }

/* Cuando hay modal abierto: bajar capas del fondo y bloquear su interacción */
body.modal-open {
    overflow: hidden !important;
    padding-right: 0 !important;
}
body.modal-open .app-sidebar,
body.modal-open .app-header,
body.modal-open .app-main,
body.modal-open .app-page-title,
body.modal-open .pos-shell {
    z-index: 1 !important;
    pointer-events: none !important;
}
/* El modal y sus hijos SIEMPRE reciben clicks (anula el pointer-events:none del padre si se aplica) */
.modal, .modal-backdrop,
.modal-dialog, .modal-content,
.modal-header, .modal-body, .modal-footer {
    pointer-events: auto !important;
}

/* Modal-content limpio: borde sutil, sin sombra proyectada */
.modal-content {
    border-radius: 8px;
    border: 1px solid rgba(0, 0, 0, .12);
    box-shadow: none;
}


/* ────────────────────────────────────────────────────────────────────────
   3) SIDEBAR ICONS — ArchitectUI nativo pone opacity:.3 a .metismenu-icon
      (pensado para sidebar oscuro). En sidebar claro queda casi invisible.
      Forzamos opacidad completa y mantenemos el color que pone la clase
      (text-primary, text-warning, icon-gradient bg-*).
   ──────────────────────────────────────────────────────────────────────── */
.vertical-nav-menu i.metismenu-icon,
.vertical-nav-menu i.metismenu-state-icon,
.metismenu-icon {
    opacity: 1 !important;
}
.vertical-nav-menu li a:hover i.metismenu-icon { opacity: 1 !important; }

/* Para sidebar oscuro (clase opcional), bajar a .85 sin desaparecer */
.app-sidebar.sidebar-dark .metismenu-icon { opacity: .85 !important; }

/* Iconos sin clase de color: dar un color neutro fuerte para que se vean */
.vertical-nav-menu i.metismenu-icon:not([class*="text-"]):not([class*="icon-gradient"]) {
    color: #3f6ad8;
}

/* metismenu-state-icon (la flecha de submenú) — gris medio */
.vertical-nav-menu i.metismenu-state-icon { color: #6c757d; }

/* icon-gradient bg-* en el sidebar: ArchitectUI tiene una 2ª regla que pone
   color:#fff + background:0 0 !important, lo que en sidebar claro deja el
   icono blanco sobre blanco (invisible). Forzamos el clip a 'text' para que
   se renderice el gradient real definido por bg-mean-fruit, bg-mixed-hopes, etc. */
.vertical-nav-menu .metismenu-icon.icon-gradient,
.app-sidebar .metismenu-icon.icon-gradient {
    -webkit-background-clip: text !important;
    background-clip: text !important;
    -webkit-text-fill-color: transparent !important;
    color: transparent !important;
}

/* Si por alguna razón el gradient no aplica, fallback a brand visible */
.vertical-nav-menu .metismenu-icon.icon-gradient:not([class*="bg-"]) {
    -webkit-text-fill-color: #3f6ad8 !important;
    color: #3f6ad8 !important;
}


/* ────────────────────────────────────────────────────────────────────────
   3) FORM LABELS — BS4 los hace muy chicos y sin peso. Hacerlos legibles.
   ──────────────────────────────────────────────────────────────────────── */
label, .form-label {
    font-weight: 600;
    font-size: 13px;
    margin-bottom: 6px;
    color: #495057;
    display: block;
}


/* ────────────────────────────────────────────────────────────────────────
   4) WIDGET KPI — truncado de números muy largos (que se desbordan en RD$)
   ──────────────────────────────────────────────────────────────────────── */
/* ── Cards KPI: auto-fit del valor numérico ──
   Combinamos: tamaño conservador + flex con min-width:0 + ellipsis.
   El JS auto-fit del layout reduce más si el contenido aún excede. */
.widget-chart .widget-numbers,
.widget-chart .widget-subheading,
.widget-chart-flex {
    max-width: 100%;
    overflow: hidden;
    white-space: nowrap;
    min-width: 0;
}
/* El pie del KPI vive dentro de .widget-numbers y sí puede envolver: la regla
   de arriba le pondría nowrap y lo recortaría al primer renglón. */
.widget-chart .widget-numbers .kpi-delta { white-space: normal; overflow: visible; }
.widget-chart .widget-numbers,
.widget-content .widget-numbers,
.widget-numbers.auto-fit {
    font-variant-numeric: tabular-nums;
    /* Base conservador: 22px desktop, 15px mobile. El JS reduce más si hace falta. */
    font-size: clamp(15px, 1.2vw + .4rem, 22px) !important;
    line-height: 1.2;
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* .fit-text: el JS auto-fit reduce la fuente hasta que el contenido (nombre o monto)
   se muestre COMPLETO en una sola línea, en lugar de cortarse con ellipsis. */
.fit-text {
    display: block;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
}
/* Utilidad: permite que un flex item encoja y su contenido haga ellipsis/fit. */
.min-width-0 { min-width: 0; }

/* ── Layout: contener tablas/grillas anchas ──
   .app-main es flex y .app-main__outer/__inner son flex items con min-width:auto,
   así que una tabla ancha (p.ej. la matriz de presupuesto 12 meses) EMPUJA el ancho
   de la página en lugar de dejar que el contenedor con overflow scrollee dentro.
   min-width:0 permite que el área de contenido se ajuste al viewport y que los
   .table-responsive / .budget-matrix-wrap hagan el scroll horizontal interno. */
.app-main__outer, .app-main__inner { min-width: 0; }
/* Flex anidado (widget-chart2): min-width:0 OBLIGA al flex item a respetar el padre.
   flex-wrap permite que el <small> ("vs mes anterior") baje a otra línea si no cabe. */
.widget-chart2 .widget-chart-flex,
.widget-chart .widget-chart-flex {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    min-width: 0;
    overflow: hidden;
    width: 100%;
}
.widget-chart2 .widget-chart-flex > div,
.widget-chart .widget-chart-flex > div {
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
}
/* El <small> que acompaña al número va a línea separada */
.widget-chart2 .widget-chart-flex > div > small,
.widget-chart .widget-chart-flex > div > small {
    flex-basis: 100%;
    margin-top: 4px;
    padding-left: 0 !important;
    font-size: 11.5px !important;
    line-height: 1.2;
}
/* Icono lateral: tamaño fijo en cuadro 32x32, no compite por ancho con el número */
.widget-chart2 .widget-chart-flex > div > span:first-child,
.widget-chart .widget-chart-flex > div > span:first-child {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0 !important;
    margin-right: 4px !important;
    font-size: 18px !important;
    opacity: 1 !important;
}
.widget-chart2 .widget-chart-flex > div > span:first-child > i { font-size: 20px; }


/* ────────────────────────────────────────────────────────────────────────
   5) PAGE-TITLE refinement (compatible con app-page-title-simple)
   ──────────────────────────────────────────────────────────────────────── */
.page-title-head { display: flex; align-items: center; }
.page-title-head .icon-gradient { font-size: 30px; margin-right: 8px; }


/* ────────────────────────────────────────────────────────────────────────
   6) TOAST CONTAINER (no nativo en ArchitectUI; lo usamos en POS y forms)
   ──────────────────────────────────────────────────────────────────────── */
.erp-toast-wrap {
    position: fixed; top: 20px; right: 20px;
    /* Por encima de modales (1090) y de los popups SweetAlert (11000):
       los toasts siempre deben ser visibles, incluso sobre un modal abierto. */
    z-index: 12000;
    display: flex; flex-direction: column; gap: 10px;
    pointer-events: none;
    max-width: 380px;
}
.erp-toast {
    background: #ffffff;
    border: 1px solid #e9ecef;
    border-left: 4px solid #3f6ad8;
    border-radius: 6px;
    padding: 12px 16px;
    box-shadow: 0 8px 24px rgba(15,23,42,.16);
    color: #212529;
    pointer-events: auto;
    display: flex; align-items: flex-start; gap: 12px;
    animation: erp-toast-in 200ms ease-out;
    font-size: 14px;
    line-height: 1.4;
}
.erp-toast.success { border-left-color: #3ac47d; }
.erp-toast.danger  { border-left-color: #d92550; }
.erp-toast.warning { border-left-color: #f7b924; }
.erp-toast.info    { border-left-color: #16aaff; }
.erp-toast .erp-toast-icon { font-size: 22px; flex-shrink: 0; }
.erp-toast.success .erp-toast-icon { color: #3ac47d; }
.erp-toast.danger  .erp-toast-icon { color: #d92550; }
.erp-toast.warning .erp-toast-icon { color: #f7b924; }
.erp-toast.info    .erp-toast-icon { color: #16aaff; }
.erp-toast .erp-toast-close { background: none; border: 0; color: #6c757d; cursor: pointer; padding: 0 4px; font-size: 18px; line-height: 1; }
@keyframes erp-toast-in { from { transform: translateX(120%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }


/* ────────────────────────────────────────────────────────────────────────
   7) POS — layout enterprise sobre la grid nativa del tema
   ──────────────────────────────────────────────────────────────────────── */
/* ── MODO POS: sin scroll global, layout flex en altura completa ─────── */
body.pos-no-scroll { overflow: hidden !important; }
/* El tema reserva 60px abajo (.app-main__outer padding-bottom) para el footer.
   En POS lo anulamos: si no, .app-main__inner queda 60px más alto que el área
   visible y empuja el bloque de totales/botones fuera de la pantalla. */
body.pos-no-scroll .app-main__outer { padding-bottom: 0 !important; }
/* CLAVE (ancho): bug clásico de flex — un item de flex con min-width:auto NO se
   encoge por debajo del ancho mínimo de su contenido. Sin min-width:0 en la
   cadena, el POS (cuya barra superior + grid no quieren encoger) ensancha
   .app-main__inner más allá del viewport (~1488px a 1080) y empuja la columna
   del carrito fuera de la pantalla. Forzamos que toda la cadena pueda encoger. */
body.pos-no-scroll .app-main,
body.pos-no-scroll .app-main__outer { min-width: 0 !important; max-width: 100%; }
body.pos-no-scroll .app-main__outer { overflow-x: hidden; }
body.pos-no-scroll .app-main__inner {
    display: flex;
    flex-direction: column;
    /* CLAVE: el tema aplica flex:1 (flex-basis:0%) aquí, lo que ANULA la
       propiedad height en el eje flex. Forzamos flex:0 0 auto para que la
       altura explícita gane y el contenedor quede acotado al viewport.
       Sin esto, .app-container (min-height:100vh, puede crecer) deja que el
       contenido empuje todo y el body (overflow:hidden) recorta los botones. */
    flex: 0 0 auto !important;
    height: calc(100vh - 60px);          /* 60px = .app-header — fallback */
    height: calc(100dvh - 60px);         /* dvh: respeta barras del navegador */
    min-height: 0;
    max-height: calc(100vh - 60px);
    /* Acotar el ANCHO al área disponible: no debe crecer con el contenido. */
    width: 100%;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
    padding: 10px !important;
    overflow: hidden;
}
body.pos-no-scroll .app-page-title,
body.pos-no-scroll .app-wrapper-footer,
body.pos-no-scroll .app-footer { display: none !important; }

/* La cuenta del salón se acota al viewport igual que el mostrador —reutiliza
   `pos-no-scroll` entero— pero CONSERVA el título: ahí está la miga de pan que
   devuelve al salón, y en el mostrador no hay a dónde volver. */
body.pos-no-scroll.salon-fit .app-page-title { display: block !important; }

/* ── Topbar (compacta y de altura fija) ──────────────────────────────── */
.pos-topbar {
    background: #fff;
    border: 1px solid #e9ecef;
    border-radius: 8px;
    padding: 8px 12px;
    margin-bottom: 8px;
    display: flex;
    flex-wrap: nowrap;
    gap: 10px;
    justify-content: space-between;
    align-items: center;
    flex-shrink: 0;
    overflow: hidden;
}
.pos-topbar-left  { display: flex; flex-wrap: nowrap; gap: 12px; align-items: center; min-width: 0; overflow: hidden; }
.pos-topbar-title { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.pos-topbar-title > i { font-size: 24px; color: #3f6ad8; }
.pos-topbar-title-main { font-weight: 700; font-size: 15px; color: #212529; line-height: 1.1; }
.pos-topbar-title-sub  { font-size: 11px; color: #6c757d; margin-top: 1px; line-height: 1.1; }
.pos-topbar-title-sub i { color: #adb5bd; }
.pos-topbar-pills { display: flex; flex-wrap: nowrap; gap: 5px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.pos-topbar-pills::-webkit-scrollbar { display: none; }
.pos-topbar-actions { display: flex; flex-wrap: nowrap; gap: 5px; flex-shrink: 0; }
.pos-topbar .pos-stat-pill { padding: 4px 9px; font-size: 11.5px; white-space: nowrap; flex-shrink: 0; }
.pos-topbar .pos-stat-pill i { font-size: 12px; }

/* Barra del POS en DOS filas por debajo de 1600px.
   En una sola línea caben el título, cinco indicadores y diez botones sólo en
   pantallas muy anchas; por debajo, los indicadores se comían el espacio de los
   botones y quedaban tras un desplazamiento horizontal que nadie descubre. Con
   dos filas cada cosa tiene su sitio: arriba en qué caja se está, abajo qué se
   puede hacer. */
@media (max-width: 1599.98px) {
    .pos-topbar { flex-wrap: wrap; row-gap: 0; overflow: visible; }
    .pos-topbar-left { flex: 1 1 100%; overflow: visible; }
    .pos-topbar-pills { flex-wrap: wrap; overflow: visible; row-gap: 4px; }
    .pos-topbar-actions {
        flex: 1 1 100%;
        flex-wrap: wrap;
        justify-content: flex-start;
        row-gap: 5px;
        margin-top: 8px;
        padding-top: 8px;
        border-top: 1px solid #f1f3f5;
    }
    /* Con la fila para ellos solos, los botones se REPARTEN el ancho en vez de
       amontonarse a la izquierda dejando medio renglón vacío. Crecen desde su
       tamaño natural (`flex-basis: auto`), así que el que lleva texto —«Salón
       F10»— no queda tan estrecho como uno de sólo icono.

       El reparto lo hace flexbox: al cambiar el tamaño de la ventana se
       recalcula solo, sin JavaScript ni puntos de corte intermedios. */
    .pos-topbar-actions .pos-tool-btn {
        flex: 1 1 auto;
        min-width: 44px;          /* sigue siendo pulsable con el dedo */
        justify-content: center;
    }
}

/* Por debajo de 1100px los botones ya no caben en una línea y pasan a varias.
   Se les pone un mínimo mayor para que al repartirse no queden como tiras. */
@media (max-width: 1099.98px) {
    .pos-topbar-actions .pos-tool-btn { min-width: 64px; }
}

.pos-tool-btn {
    background: #fff;
    border: 1px solid #ced4da;
    color: #495057;
    border-radius: 6px;
    padding: 5px 10px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
    transition: all .12s;
}
.pos-tool-btn:hover { background: #f1f5f9; border-color: #3f6ad8; color: #3f6ad8; }
/* La barra admite enlaces (la vuelta al salón): sin esto se subrayan al pasar. */
a.pos-tool-btn, a.pos-tool-btn:hover { text-decoration: none; }
.pos-tool-btn i { font-size: 16px; }
.pos-tool-btn-success { background: #198754; color: #fff; border-color: #198754; }
.pos-tool-btn-success:hover { background: #146c43; border-color: #146c43; color: #fff; }
.pos-tool-btn-warning { background: #ffc107; color: #212529; border-color: #ffc107; }
.pos-tool-btn-warning:hover { background: #e0a800; border-color: #e0a800; color: #212529; }
.pos-tool-btn-danger { background: #dc3545; color: #fff; border-color: #dc3545; }
.pos-tool-btn-danger:hover { background: #b02a37; border-color: #b02a37; color: #fff; }
.pos-tool-btn-info { background: #0dcaf0; color: #053742; border-color: #0dcaf0; }
.pos-tool-btn-info:hover { background: #31d2f2; border-color: #31d2f2; color: #053742; }
/* Iconos con color en los botones neutros de la barra de acciones (los botones
   con variante sólida —success/warning/danger/info— ya llevan su propio color).
   Damos a cada acción un tinte propio para que la barra no sea toda gris. */
#btnHelp i       { color: #3f6ad8; }   /* azul   — ayuda */
#btnLock i       { color: #6f42c1; }   /* púrpura— bloquear */
#btnPin i        { color: #fd7e14; }   /* naranja— PIN */
#btnReprint i    { color: #0a94b3; }   /* cian   — reimprimir */
#btnFullscreen i { color: #12b886; }   /* teal   — pantalla completa */
/* El tinte se mantiene al pasar el ratón (el fondo hover es claro). */
/* Iconos del subtítulo (almacén / sucursal) con color en vez de gris plano. */
.pos-topbar-title-sub i:first-of-type { color: #12b886; }  /* almacén */
.pos-topbar-title-sub i:last-of-type  { color: #e8590c; }  /* sucursal */
.pos-hold-count {
    background: rgba(255,255,255,.3); color: #fff;
    border-radius: 999px; padding: 1px 7px; font-size: 11px; font-weight: 700;
    margin-left: 2px; min-width: 18px; text-align: center;
}
.pos-tool-btn-success .pos-hold-count { background: rgba(0,0,0,.15); color: #fff; }
.pos-stat-pill.stat-money { background: #d1e7dd; color: #0a3622; border-color: #a3cfbb; }
.pos-stat-pill.stat-money i { color: #198754; }
.pos-stat-pill.stat-tx { background: #cfe2ff; color: #084298; border-color: #9ec5fe; }
.pos-stat-pill.stat-tx i { color: #0d6efd; }
.pos-stat-pill.stat-clock { background: #f8f9fa; color: #495057; }
.pos-stat-pill.stat-clock i { color: #6c757d; }
.pos-stat-pill.stat-conn { font-variant-numeric: tabular-nums; }
.pos-stat-pill.stat-conn.online { background: #d1e7dd; color: #0a3622; border-color: #a3cfbb; }
.pos-stat-pill.stat-conn.online i { color: #198754; }
.pos-stat-pill.stat-conn.offline { background: #f8d7da; color: #842029; border-color: #f5c2c7; }
.pos-stat-pill.stat-conn.offline i { color: #dc3545; }

/* ── Shell — ocupa el resto del viewport con flex ────────────────────── */
.pos-shell {
    display: grid;
    grid-template-columns: 1fr 420px;
    /* Fila única acotada a la altura del contenedor: evita que la columna del
       carrito crezca con su contenido y empuje totales/botones fuera de vista.
       minmax(0,1fr) permite que los hijos (cart-list) hagan scroll interno. */
    grid-template-rows: minmax(0, 1fr);
    gap: 10px;
    flex: 1 1 auto;
    min-height: 0;
    position: relative;
    overflow: hidden;
}
@media (max-width: 1599.98px) { .pos-shell { grid-template-columns: 1fr 400px; } }
@media (max-width: 1399.98px) { .pos-shell { grid-template-columns: 1fr 370px; } }
@media (max-width: 1199.98px) { .pos-shell { grid-template-columns: 1fr 340px; } }
@media (max-width: 991.98px) {
    body.pos-no-scroll { overflow: auto !important; }
    body.pos-no-scroll .app-main__inner { height: auto; overflow: visible; }
    /* Layout apilado: la página vuelve a hacer scroll, así que las filas se
       dimensionan por contenido (no acotadas a la altura del viewport). */
    .pos-shell { grid-template-columns: 1fr; grid-template-rows: none; overflow: visible; }
    .pos-side { order: -1; }
    .pos-side, .pos-main { overflow: visible; }
    .pos-cart-list { max-height: 260px; }
    .pos-products-grid { max-height: 60vh; }
}
@media (max-width: 767.98px) {
    .pos-topbar-title-sub { display: none; }
    .pos-topbar-actions .pos-tool-btn span:not(.pos-hold-count):not(.pos-hotkey-chip) { display: none; }
    /* Aquí los botones se quedan sin rótulo (sólo icono), así que el mínimo
       ancho de la fila repartida sobra: apretados caben todos en menos filas. */
    .pos-topbar-actions .pos-tool-btn { padding: 5px 8px; min-width: 44px; }
    .pos-stat-pill { font-size: 10.5px; padding: 3px 7px; }
}

/* Fullscreen toggle */
body.pos-fullscreen .app-main__inner { padding: 6px !important; height: 100vh; }
body.pos-fullscreen .app-header,
body.pos-fullscreen .app-sidebar { display: none !important; }
body.pos-fullscreen .app-main { padding-top: 0 !important; }

/* Panels (main + side) — internal scroll */
body.pos-no-scroll .pos-main,
body.pos-no-scroll .pos-side { min-height: 0; }
body.pos-no-scroll .pos-main { overflow: hidden; }
body.pos-no-scroll .pos-side { overflow: hidden; }

.pos-main, .pos-side {
    background: #ffffff;
    border: 1px solid #e9ecef;
    border-radius: 6px;
    display: flex; flex-direction: column;
    overflow: hidden;
    min-height: 0;
    /* CLAVE: sin min-width:0 el track 1fr de productos no puede encogerse por
       debajo del ancho mínimo de su contenido (barra de búsqueda + grid), lo que
       desborda horizontalmente y empuja la columna del carrito fuera del área
       visible (overflow:hidden la recorta). Pasaba a ~1080px de ancho. */
    min-width: 0;
}

.pos-search-bar { padding: 8px 10px 6px; border-bottom: 1px solid #e9ecef; flex-shrink: 0; }
.pos-search-bar .input-group-lg .form-control,
.pos-search-bar .input-group-lg .input-group-text,
.pos-search-bar .input-group-lg .btn { padding-top: 6px; padding-bottom: 6px; font-size: 14px; height: auto; }
.pos-categories {
    display: flex; gap: 5px; flex-wrap: nowrap; overflow-x: auto;
    padding: 6px 10px;
    border-bottom: 1px solid #e9ecef;
    flex-shrink: 0;
}
.pos-cat-pill {
    padding: 4px 12px; border-radius: 999px;
    border: 1px solid #ced4da;
    background: #ffffff;
    color: #495057;
    cursor: pointer;
    font-size: 12px; font-weight: 500;
    white-space: nowrap;
    flex-shrink: 0;
    transition: all 120ms;
}
.pos-cat-pill:hover { border-color: #3f6ad8; color: #3f6ad8; }
.pos-cat-pill.active { background: #3f6ad8; color: #fff; border-color: #3f6ad8; }

.pos-products-grid {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 10px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 8px;
    align-content: start;
    background: #f8f9fa;
}
.pos-tile {
    background: #ffffff;
    border: 1px solid #e9ecef;
    border-radius: 8px;
    padding: 8px;
    cursor: pointer;
    transition: all 150ms;
    text-align: center;
    display: flex; flex-direction: column;
    user-select: none;
}
.pos-tile:hover {
    transform: translateY(-2px);
    border-color: #3f6ad8;
    box-shadow: 0 6px 16px rgba(63,106,216,.15);
}
.pos-tile .tile-img {
    width: 100%; height: 64px;
    background: #f1f4f6;
    border-radius: 6px;
    display: flex; align-items: center; justify-content: center;
    margin-bottom: 6px;
    color: #adb5bd; font-size: 28px;
    overflow: hidden;
}
.pos-tile .tile-img img { width: 100%; height: 100%; object-fit: cover; }
.pos-tile .tile-name { font-size: 12.5px; font-weight: 600; color: #212529; line-height: 1.25; min-height: 2.5em; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.pos-tile .tile-sku  { font-size: 10.5px; color: #6c757d; font-family: 'JetBrains Mono', monospace; margin-top: 1px; }
.pos-tile .tile-price { font-size: 14px; font-weight: 700; color: #3f6ad8; margin-top: 2px; font-variant-numeric: tabular-nums; }

/* Stock badge (esquina superior derecha de la tile) */
.pos-tile { position: relative; }
.pos-tile .tile-stock {
    position: absolute; top: 6px; right: 6px;
    font-size: 10px; font-weight: 700;
    padding: 2px 6px; border-radius: 999px;
    background: #d1e7dd; color: #0a3622; border: 1px solid #a3cfbb;
    font-variant-numeric: tabular-nums; letter-spacing: 0;
}
.pos-tile .tile-stock.low  { background: #fff3cd; color: #664d03; border-color: #ffe69c; }
.pos-tile .tile-stock.out  { background: #f8d7da; color: #842029; border-color: #f5c2c7; }
.pos-tile .tile-stock.untracked { background: #e9ecef; color: #6c757d; border-color: #dee2e6; }
/* Servicio / producto sin control de inventario: chip azul informativo. */
.pos-tile .tile-stock.service { background: #cfe2ff; color: #084298; border-color: #9ec5fe; }
.pos-tile.is-out { opacity: .55; }
.pos-tile.is-out::after {
    content: "AGOTADO"; position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(220,53,69,.08);
    font-weight: 800; color: #842029; font-size: 11px; letter-spacing: .1em;
    border-radius: 8px; pointer-events: none;
}

/* Toolbar de productos: switch grid/list + ordenamiento */
.pos-products-toolbar {
    display: flex; gap: 6px; align-items: center;
    padding: 4px 10px;
    border-bottom: 1px solid #e9ecef;
    background: #fff;
    font-size: 11.5px; color: #6c757d;
    flex-shrink: 0;
}
.pos-products-toolbar .pp-spacer { flex: 1; }
.pos-view-toggle { display: inline-flex; border: 1px solid #ced4da; border-radius: 6px; overflow: hidden; }
.pos-view-toggle button {
    background: #fff; border: 0; color: #6c757d; padding: 3px 9px; cursor: pointer; font-size: 12px;
}
.pos-view-toggle button.active { background: #3f6ad8; color: #fff; }

/* Modo lista (alternativa al grid) */
.pos-products-grid.view-list { grid-template-columns: 1fr; gap: 4px; padding: 8px; }
.pos-products-grid.view-list .pos-tile {
    display: grid; grid-template-columns: 50px 1fr auto auto; gap: 12px;
    align-items: center;
    text-align: left;
    padding: 6px 12px;
    border-radius: 6px;
}
.pos-products-grid.view-list .pos-tile:hover { transform: none; }
.pos-products-grid.view-list .tile-img { width: 50px; height: 50px; margin: 0; }
.pos-products-grid.view-list .tile-name { min-height: auto; -webkit-line-clamp: 1; font-size: 14px; }
.pos-products-grid.view-list .tile-sku  { display: inline; margin: 0; }
.pos-products-grid.view-list .tile-stock { position: static; align-self: center; }
.pos-products-grid.view-list .tile-price { margin: 0; }
.pos-products-grid.view-list .pos-tile.is-out::after { display: none; }

.pos-customer-bar { padding: 8px 12px; border-bottom: 1px solid #e9ecef; background: #f8f9fa; flex-shrink: 0; }
.pos-customer-bar .form-label { margin-bottom: 4px; font-size: 12px; }
.pos-cart-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 6px; }
.pos-cart-row {
    /* Layout en áreas: info + monto arriba, controles en su propia fila abajo.
       Evita que el monto (.r-total) se desborde cuando los botones no caben en
       pantallas angostas: el monto vive en su columna fija y los controles
       envuelven en una fila aparte. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "info  total"
        "ctrl  ctrl";
    column-gap: 8px; row-gap: 6px;
    align-items: center;
    padding: 7px 10px;
    border-radius: 6px;
    border: 1px solid transparent;
    margin-bottom: 3px;
    transition: background 120ms;
}
.pos-cart-row .r-info { grid-area: info; min-width: 0; }
.pos-cart-row:hover { background: #f8f9fa; border-color: #e9ecef; }
.pos-cart-row.is-active { background: #e7f1ff; border-color: #9ec5fe; box-shadow: inset 3px 0 0 #0d6efd; }
.pos-cart-row .r-name { font-weight: 600; color: #212529; font-size: 13px; line-height: 1.3; }
.pos-cart-row .r-meta { font-size: 11px; color: #6c757d; margin-top: 2px; font-family: 'JetBrains Mono', monospace; }
.pos-cart-row .r-note { font-size: 11px; color: #b45309; margin-top: 3px; font-style: italic; display: flex; align-items: center; gap: 4px; }
.pos-cart-row .r-disc-tag {
    display: inline-block; margin-left: 6px;
    background: #fff3cd; color: #664d03;
    font-size: 10px; font-weight: 700;
    padding: 1px 5px; border-radius: 4px;
}
.pos-cart-row .r-ctrl { grid-area: ctrl; display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }
.pos-cart-row .r-qty { width: 56px; text-align: center; padding: 4px; font-variant-numeric: tabular-nums; font-weight: 600; }
.pos-cart-row .r-total { grid-area: total; justify-self: end; align-self: start; font-weight: 700; color: #212529; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pos-cart-row .btn { padding: 4px 8px; }
.pos-cart-row .r-edit { background: transparent; border: 0; color: #6c757d; padding: 4px 6px; cursor: pointer; font-size: 14px; }
.pos-cart-row .r-edit:hover { color: #0d6efd; }

.pos-cart-empty { text-align: center; padding: 30px 20px; color: #adb5bd; }
.pos-cart-empty i { font-size: 48px; opacity: .4; display: block; margin-bottom: 8px; }

.pos-cart-totals { border-top: 1px solid #e9ecef; background: #f8f9fa; padding: 10px 12px; flex-shrink: 0; }
.pos-cart-totals .t-line { display: flex; justify-content: space-between; padding: 2px 0; font-size: 13px; color: #495057; }
.pos-cart-totals .t-line strong { font-variant-numeric: tabular-nums; color: #212529; }
.pos-cart-totals .t-line.t-grand {
    font-size: 19px; font-weight: 800;
    color: #212529;
    border-top: 1px dashed #ced4da;
    padding-top: 7px; margin-top: 4px;
}
.pos-cart-totals .t-line.t-grand strong { color: #3f6ad8; }

.pos-actions-row { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-top: 8px; }
.pos-actions-row .btn { padding: 7px; font-weight: 600; font-size: 13px; }
.pos-actions-row .btn-charge {
    grid-column: span 2;
    padding: 12px;
    font-size: 16px;
    font-weight: 700;
    letter-spacing: .03em;
}

.pos-stat-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 12px; font-weight: 600;
    background: #ffffff;
    border: 1px solid #e9ecef;
    color: #495057;
}
.pos-stat-pill i { font-size: 14px; }
.pos-stat-pill.open { background: #e6f7ef; color: #1d6b48; border-color: #b8e8d2; }

.pay-amount-display {
    text-align: center;
    font-size: 36px;
    font-weight: 800;
    padding: 16px;
    background: #f8f9fa;
    border-radius: 8px;
    border: 1px solid #e9ecef;
    font-variant-numeric: tabular-nums;
    color: #212529;
    margin-bottom: 12px;
    letter-spacing: -.02em;
}
.pay-amount-display .change-positive { color: #3ac47d; }
.pay-amount-display .change-negative { color: #d92550; }

.pos-hotkey-chip {
    display: inline-block;
    font-size: 10.5px; font-weight: 700;
    color: #6c757d;
    background: #f1f4f6;
    border: 1px solid #ced4da;
    border-bottom-width: 2px;
    border-radius: 5px;
    padding: 1px 5px;
    margin-left: 4px;
    font-family: 'JetBrains Mono', monospace;
}

/* ── Drawer lateral derecho (deslizable) ─────────────────────────────── */
.pos-drawer {
    position: fixed; top: 0; right: 0; bottom: 0; width: 420px; max-width: 96vw;
    background: #fff;
    box-shadow: -8px 0 30px rgba(0,0,0,0.16);
    border-left: 1px solid #dee2e6;
    z-index: 1060;
    display: flex; flex-direction: column;
    transform: translateX(100%);
    transition: transform .22s ease;
}
.pos-drawer.open { transform: translateX(0); }
.pos-drawer-backdrop {
    position: fixed; inset: 0; background: rgba(0,0,0,.25);
    opacity: 0; pointer-events: none;
    z-index: 1059; transition: opacity .22s;
}
.pos-drawer-backdrop.open { opacity: 1; pointer-events: auto; }
.pos-drawer-header {
    padding: 14px 18px;
    border-bottom: 1px solid #dee2e6;
    background: #f8f9fa;
    display: flex; align-items: center; justify-content: space-between;
}
.pos-drawer-header h5 { margin: 0; font-size: 16px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.pos-drawer-header h5 i { color: #0d6efd; }
.pos-drawer-close {
    background: transparent; border: 0; color: #6c757d; font-size: 24px;
    line-height: 1; cursor: pointer; padding: 0 6px;
}
.pos-drawer-close:hover { color: #212529; }
.pos-drawer-tabs {
    display: flex; gap: 0;
    border-bottom: 1px solid #dee2e6;
    background: #fff;
}
.pos-drawer-tab {
    flex: 1; background: transparent; border: 0;
    padding: 10px 8px; cursor: pointer;
    font-size: 12.5px; font-weight: 600; color: #6c757d;
    border-bottom: 3px solid transparent;
    display: flex; align-items: center; justify-content: center; gap: 6px;
    transition: all .12s;
}
.pos-drawer-tab:hover { color: #0d6efd; background: #f8f9fa; }
.pos-drawer-tab.active { color: #0d6efd; border-bottom-color: #0d6efd; }
.pos-drawer-tab .badge { background: #6c757d; color: #fff; border-radius: 999px; padding: 0 6px; font-size: 10px; }
.pos-drawer-tab.active .badge { background: #0d6efd; }
.pos-drawer-body { flex: 1; overflow-y: auto; padding: 12px; background: #f8f9fa; }
.pos-drawer-empty { text-align: center; padding: 40px 20px; color: #adb5bd; }
.pos-drawer-empty i { font-size: 56px; opacity: .4; display: block; margin-bottom: 10px; }

/* Filas dentro del drawer (suspendidas / ventas recientes) */
.pos-drawer-row {
    background: #fff;
    border: 1px solid #e9ecef;
    border-radius: 8px;
    padding: 10px 12px;
    margin-bottom: 8px;
    transition: all .12s;
}
.pos-drawer-row:hover { border-color: #0d6efd; box-shadow: 0 2px 6px rgba(13,110,253,.08); }
.pos-drawer-row .pdr-head {
    display: flex; justify-content: space-between; align-items: baseline;
    margin-bottom: 4px;
}
.pos-drawer-row .pdr-code {
    font-family: 'JetBrains Mono', monospace; font-weight: 700; font-size: 12px;
    color: #0d6efd;
}
.pos-drawer-row .pdr-total {
    font-weight: 700; font-size: 15px; color: #198754;
    font-variant-numeric: tabular-nums;
}
.pos-drawer-row .pdr-meta { font-size: 11.5px; color: #6c757d; margin-top: 2px; }
.pos-drawer-row .pdr-actions { display: flex; gap: 6px; margin-top: 8px; }
.pos-drawer-row .pdr-actions .btn { padding: 4px 12px; font-size: 12px; font-weight: 600; }

/* Ayuda — listado de atajos */
.pos-help-grid { display: grid; gap: 6px; }
.pos-help-row {
    display: grid; grid-template-columns: 80px 1fr; gap: 12px;
    background: #fff; border: 1px solid #e9ecef; border-radius: 6px;
    padding: 8px 12px;
}
.pos-help-row kbd {
    background: #212529; color: #fff;
    padding: 3px 10px; border-radius: 4px; font-size: 11.5px;
    font-family: 'JetBrains Mono', monospace; font-weight: 700;
    text-align: center; align-self: center;
    box-shadow: 0 2px 0 #000;
}
.pos-help-row .desc { font-size: 13px; color: #212529; align-self: center; }
.pos-help-section-title {
    font-size: 11px; font-weight: 700; color: #6c757d; letter-spacing: .12em;
    text-transform: uppercase; margin: 12px 0 6px;
}
.pos-help-section-title:first-child { margin-top: 0; }


/* ────────────────────────────────────────────────────────────────────────
   8) LOGIN — fondo gradient consistente con plantilla
   ──────────────────────────────────────────────────────────────────────── */
body.app-login-bg {
    background: linear-gradient(150deg, rgba(73, 80, 161, 0.95) 0%, rgba(124, 95, 240, 0.95) 100%);
    min-height: 100vh;
}
.erp-login-card {
    max-width: 440px;
    margin: 8vh auto;
    background: #ffffff;
    border-radius: 8px;
    box-shadow: 0 24px 64px rgba(15,23,42,.25);
    padding: 32px;
}


/* ────────────────────────────────────────────────────────────────────────
   9) PRINT (reportes PDF)
   ──────────────────────────────────────────────────────────────────────── */
@media print {
    .app-header, .app-sidebar, .app-footer, .page-title-actions { display: none !important; }
    .app-main__outer { padding-left: 0 !important; }
    .card { box-shadow: none !important; border: 1px solid #e5e7eb !important; }
}

/* ────────────────────────────────────────────────────────────────────────
   10) SIDEBAR SCROLL — fix para menús largos (Contabilidad, Manufactura, etc.)
   ──────────────────────────────────────────────────────────────────────── */
.app-sidebar {
    height: 100vh !important;
    overflow: hidden !important;
    display: flex !important;
    flex-direction: column !important;
}

.app-sidebar .app-header__logo {
    flex: 0 0 auto;
}

.app-sidebar .scrollbar-sidebar {
    flex: 1 1 auto !important;
    height: auto !important;
    max-height: calc(100vh - 60px) !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: rgba(0,0,0,0.25) transparent;
}

/* Scrollbar custom (WebKit) */
.app-sidebar .scrollbar-sidebar::-webkit-scrollbar {
    width: 6px;
}
.app-sidebar .scrollbar-sidebar::-webkit-scrollbar-track {
    background: transparent;
}
.app-sidebar .scrollbar-sidebar::-webkit-scrollbar-thumb {
    background-color: rgba(0,0,0,0.2);
    border-radius: 3px;
}
.app-sidebar .scrollbar-sidebar::-webkit-scrollbar-thumb:hover {
    background-color: rgba(0,0,0,0.4);
}

/* Scroll vertical también con el sidebar COLAPSADO (y al hacer hover sobre él).
   ArchitectUI asume PerfectScrollbar y fuerza overflow:initial / overflow:hidden
   en estos estados; como aquí NO se inicializa PerfectScrollbar, restauramos el
   scroll nativo para que en pantallas de poca altura los iconos no se recorten
   y se pueda hacer scroll hasta el último item. */
.closed-sidebar:not(.sidebar-mobile-open) .app-sidebar .scrollbar-sidebar,
.closed-sidebar:not(.sidebar-mobile-open) .app-sidebar:hover .scrollbar-sidebar {
    position: static !important;
    height: auto !important;
    max-height: calc(100vh - 60px) !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
}

/* Asegurar que el inner no fuerce altura limitada */
.app-sidebar .app-sidebar__inner {
    height: auto !important;
    min-height: 100%;
}

/* PerfectScrollbar override (ArchitectUI lo usa por default y a veces se rompe) */
.app-sidebar .ps {
    overflow: auto !important;
}
.app-sidebar .ps__rail-y {
    opacity: 0.6 !important;
}

/* Mobile: sidebar a pantalla completa cuando se abre */
@media (max-width: 991.98px) {
    .app-sidebar .scrollbar-sidebar {
        max-height: calc(100vh - 60px) !important;
    }
}

/* ─────────────────────────────────────────────────────────────────
   Logo corporativo — Nombre de la empresa (tipografía ejecutiva)
   ───────────────────────────────────────────────────────────────── */

/* Forzar visibilidad del contenedor (ArchitectUI lo oculta en algunos breakpoints) */
.app-header__logo,
.app-sidebar .app-header__logo {
    visibility: visible !important;
    opacity: 1 !important;
    background: transparent !important;
}

.app-header__logo .logo-src,
.app-sidebar .app-header__logo .logo-src,
.app-header.header-text-light .app-header__logo .logo-src,
.app-header.header-text-dark  .app-header__logo .logo-src,
.app-sidebar.sidebar-text-light .app-header__logo .logo-src,
.closed-sidebar.closed-sidebar-mobile .app-sidebar .app-header__logo .logo-src,
.closed-sidebar.closed-sidebar-mobile .app-sidebar:hover .app-header__logo .logo-src,
.sidebar-mobile-open .app-sidebar .app-header__logo .logo-src {
    background: transparent !important;
    background-image: none !important;
    width: auto !important;
    min-width: 0 !important;
    height: auto !important;
    display: inline-flex !important;
    align-items: center;
    padding: 6px 0;
    flex: 1 1 auto;
    opacity: 1 !important;
    visibility: visible !important;
    filter: none !important;
}

/* Texto principal — Manrope, peso 800, máximo contraste */
.app-header__logo .logo-src .logo-text,
.app-sidebar .app-header__logo .logo-src .logo-text {
    font-family: 'Manrope', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
    font-weight: 800 !important;
    font-size: clamp(0.82rem, 1.2vw, 0.98rem) !important;
    color: #0f172a !important;
    letter-spacing: 0.015em !important;
    text-transform: uppercase !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    line-height: 1.15 !important;
    flex: 1 1 auto;
    min-width: 0;
    opacity: 1 !important;
    visibility: visible !important;
    filter: none !important;
    text-shadow: none !important;
    -webkit-text-fill-color: #0f172a !important;
}

/* ── Colapso del sidebar (.closed-sidebar) ──────────────────────────────
   Al colapsar, ArchitectUI reduce el área de logo a 80px. Los overrides de
   arriba fuerzan el logo visible con width:auto, así que aquí lo ocultamos
   explícitamente (con mayor especificidad + !important) para que el nombre
   de la empresa NO se muestre ni desborde sobre los iconos del header. */

/* Header: el logo se oculta por completo cuando el sidebar está colapsado
   (el header no se expande por hover; solo queda el botón hamburger). */
.closed-sidebar .app-header .app-header__logo .logo-src,
.closed-sidebar .app-header .app-header__logo .logo-src .logo-text {
    display: none !important;
}

/* Sidebar (configuraciones donde su logo es visible, p.ej. móvil): ocultar el
   texto salvo cuando el sidebar se expande por hover; el logo se reduce a 80px. */
.closed-sidebar .app-sidebar:not(:hover) .app-header__logo .logo-src .logo-text {
    display: none !important;
}
.closed-sidebar .app-sidebar:not(:hover) .app-header__logo .logo-src {
    width: 21px !important;
    min-width: 0 !important;
    flex: 0 0 auto !important;
    overflow: hidden !important;
}

/* Guard anti-apilamiento de iconos: si el <ul.vertical-nav-menu> RAÍZ recibe
   por error la clase `mm-show` (p. ej. desde un script que abre los padres del
   item activo), ArchitectUI aplicaría `ul.mm-show>li>a{height:0}` a TODOS los
   items de primer nivel y sus iconos se apilarían en una sola posición. Aquí
   forzamos que los links de primer nivel conserven su altura. NO afecta a los
   submenús reales (esos son `ul.mm-show` pero no `.vertical-nav-menu`). */
.closed-sidebar .app-sidebar .app-sidebar__inner ul.vertical-nav-menu.mm-show > li > a {
    height: 2.4rem !important;
}

/* ── Menú lateral OCULTO (users.sidebar_collapsed = 2, clase .hidden-sidebar) ──
   El menú no ocupa sitio: el contenido usa todo el ancho y en la cabecera
   quedan el botón ☰ y el nombre de la empresa. Con `.sidebar-peek` (lo pone
   el guion al pulsar ☰) el menú se asoma POR ENCIMA del contenido, sin
   empujarlo, y se retira al pulsar fuera, con Esc o al navegar. En móvil
   (<992 px) manda el mecanismo propio de la plantilla (.sidebar-mobile-open),
   de ahí el :not(). */
.hidden-sidebar:not(.sidebar-mobile-open) .app-sidebar {
    transform: translateX(-100%);
    box-shadow: none;
    transition: transform .2s ease;
}
.hidden-sidebar.fixed-sidebar .app-main .app-main__outer,
.hidden-sidebar.closed-sidebar.fixed-sidebar .app-main__outer { padding-left: 0 !important; }
/* Cabecera: ☰ y luego el nombre de la empresa, en el ancho que necesiten. */
.hidden-sidebar .app-header .app-header__logo { width: auto !important; padding-right: 1.25rem; }
.hidden-sidebar .app-header .app-header__logo .logo-src { display: inline-flex !important; }
.hidden-sidebar .app-header .app-header__logo .logo-src .logo-text { display: inline !important; }
.hidden-sidebar .app-header .app-header__logo .header__pane { order: -1; margin: 0 .75rem 0 0 !important; }
/* Asomado: ancho completo, encima de todo, con sombra para que se lea como capa. */
.hidden-sidebar.sidebar-peek .app-sidebar {
    transform: translateX(0);
    width: 280px !important; min-width: 280px !important; flex-basis: 280px !important;
    z-index: 1040;
    box-shadow: 0 0 0 1px rgba(15,23,42,.06), 12px 0 40px rgba(15,23,42,.22);
}
.hidden-sidebar.sidebar-peek .app-sidebar .app-sidebar__inner .app-sidebar__heading { text-indent: initial; }

/* ─────────────────────────────────────────────────────────────────
   SweetAlert2 — tema corporativo
   ───────────────────────────────────────────────────────────────── */
.swal2-popup.erp-swal-popup {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    border-radius: 14px;
    padding: 24px 22px 20px;
    box-shadow: 0 25px 60px rgba(15, 23, 42, 0.2),
                0 8px 20px rgba(15, 23, 42, 0.08);
}
.swal2-popup .erp-swal-title {
    font-family: 'Manrope', 'Inter', sans-serif;
    font-weight: 700;
    color: #0f172a;
    font-size: 1.15rem;
    letter-spacing: 0.005em;
}
.swal2-popup .swal2-html-container,
.swal2-popup .swal2-content {
    color: #495057;
    font-size: 0.92rem;
    line-height: 1.5;
}
.swal2-styled.swal2-confirm,
.swal2-styled.swal2-cancel {
    font-family: 'Inter', sans-serif;
    font-weight: 600;
    border-radius: 8px;
    padding: 9px 18px;
    font-size: 0.875rem;
    box-shadow: none !important;
    outline: none !important;
}
.swal2-styled.swal2-confirm:focus,
.swal2-styled.swal2-cancel:focus {
    box-shadow: 0 0 0 3px rgba(63, 106, 216, 0.25) !important;
}
/* Fix: base.css pinta el botón Cancelar con fondo casi blanco (#f8f9fa) y texto
   blanco → invisible sobre el popup. Forzamos colores legibles para TODOS los
   SweetAlert, incluso los que llaman Swal.fire directo sin cancelButtonColor.
   Mismo selector específico que base.css + !important para ganar siempre. */
.swal2-popup .swal2-styled.swal2-confirm {
    background-color: #3f6ad8 !important;
    color: #fff !important;
    border: 0 !important;
}
.swal2-popup .swal2-styled.swal2-cancel {
    background-color: #6c757d !important;  /* gris sólido, legible */
    color: #fff !important;
    border: 0 !important;
}
.swal2-popup .swal2-styled.swal2-confirm:hover { background-color: #355cc0 !important; }
.swal2-popup .swal2-styled.swal2-cancel:hover  { background-color: #5a6268 !important; }
.swal2-popup .swal2-styled.swal2-deny {
    background-color: #d92550 !important;
    color: #fff !important;
    border: 0 !important;
}
.swal2-icon { margin-top: 8px; }

/* Toast */
.swal2-toast.erp-swal-toast {
    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.18) !important;
    border-radius: 12px !important;
}
.swal2-toast .swal2-title { font-size: 0.9rem !important; font-weight: 600 !important; }

/* Modal de Ayuda contextual */
.swal2-popup.erp-help-popup .erp-help-body {
    font-size: 0.93rem;
    line-height: 1.55;
    color: #344256;
}
.swal2-popup.erp-help-popup .erp-help-label {
    display: inline-block;
    font-family: 'Manrope', 'Inter', sans-serif;
    font-weight: 700;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #3f6ad8;
    margin-bottom: 4px;
}
.swal2-popup.erp-help-popup .erp-help-example {
    background: rgba(63, 106, 216, 0.06);
    border-left: 3px solid #3f6ad8;
    padding: 10px 14px;
    border-radius: 6px;
    margin-top: 4px;
}
/* ─────────────────────────────────────────────────────────────────
   Loader global (overlay translúcido + panel glass)
   Velo apenas perceptible con leve blur; panel flotante con
   transición suave de entrada/salida.
   Excluir con data-no-loader o $.ajax({silent:true}).
   ───────────────────────────────────────────────────────────────── */
.erp-loader {
    position: fixed;
    inset: 0;
    background: rgba(255, 255, 255, 0.35);
    backdrop-filter: blur(3px) saturate(110%);
    -webkit-backdrop-filter: blur(3px) saturate(110%);
    z-index: 20000;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.22s ease, visibility 0.22s ease, backdrop-filter 0.22s ease;
}
.erp-loader.is-active {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}
.erp-loader__panel {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 22px 32px 18px;
    background: rgba(255, 255, 255, 0.78);
    border: 1px solid rgba(255, 255, 255, 0.6);
    border-radius: 18px;
    box-shadow:
        0 10px 30px rgba(15, 23, 42, 0.10),
        0 2px 6px rgba(15, 23, 42, 0.06),
        inset 0 1px 0 rgba(255, 255, 255, 0.6);
    backdrop-filter: blur(12px) saturate(140%);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    transform: translateY(6px) scale(0.92);
    transition: transform 0.22s cubic-bezier(0.34, 1.3, 0.55, 1);
}
.erp-loader.is-active .erp-loader__panel {
    transform: translateY(0) scale(1);
}

/* Loader: bola roja rebotando sobre línea punteada
   (scopeado bajo el panel para no chocar con .loader de ArchitectUI) */
.erp-loader__panel .loader {
    height: 60px;
    aspect-ratio: 2;
    border-bottom: 3px solid transparent;
    background:
        linear-gradient(90deg, #524656 50%, transparent 0)
        -25% 100% / 50% 3px repeat-x border-box;
    position: relative;
    animation: l3-0 .75s linear infinite;
}
.erp-loader__panel .loader::before {
    content: "";
    position: absolute;
    inset: auto 42.5% 0;
    aspect-ratio: 1;
    border-radius: 50%;
    background: #CF4647;
    animation: l3-1 .75s cubic-bezier(0, 900, 1, 900) infinite;
}
@keyframes l3-0 {
    to { background-position: -125% 100%; }
}
@keyframes l3-1 {
    0%, 2% { bottom: 0%; }
    98%, to { bottom: .1%; }
}
@media (prefers-reduced-motion: reduce) {
    .erp-loader, .erp-loader__panel { transition: opacity 0.3s ease, visibility 0.3s ease; }
    .erp-loader__panel .loader,
    .erp-loader__panel .loader::before { animation-duration: 1.6s; }
}
/* ── LOW-07: focus visible reforzado + outline accesible ───────────────── */
:focus-visible {
    outline: 2px solid var(--c-brand, #6366f1) !important;
    outline-offset: 2px;
    border-radius: 4px;
}

/* MED-16: feedback visual de errores de validación reforzado para a11y */
.is-invalid + .invalid-feedback,
[aria-invalid="true"] + .invalid-feedback {
    display: block;
}


/* ─────────────────────────────────────────────────────────────────
   KPI cards — anti-overflow global
   Aplica a TODA `.widget-content` (KPI tiles, cards de header de
   módulos, etc.) para que números grandes (moneda, +5 dígitos)
   nunca empujen al label fuera de la card.
   ───────────────────────────────────────────────────────────────── */
.widget-content .widget-content-wrapper {
    gap: 0.75rem;
    min-width: 0;
    align-items: center;
}
.widget-content .widget-content-left {
    min-width: 0;
    flex: 1 1 0;
}
.widget-content .widget-content-right {
    flex: 0 1 auto;
    text-align: right;
    min-width: 0;
    max-width: 70%;
}
.widget-content .widget-heading,
.widget-content .widget-subheading {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Base — conservador (overridea el clamp del bloque "Cards KPI auto-fit" sin pelear) */
.widget-content .widget-numbers {
    line-height: 1.1;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}
/* Variante explícita para montos: tipografía menor para que quepa moneda (con !important
   porque el bloque "Cards KPI auto-fit" tiene una regla previa con !important).
   Aplica tanto a .widget-content (cards manuales) como a .widget-chart (helper widget_kpi). */
.widget-content .widget-numbers.kpi-money,
.widget-chart .widget-numbers.kpi-money {
    font-size: clamp(13px, 1.1vw + .3rem, 19px) !important;
    letter-spacing: -0.01em;
}
/* Cuando hay icono inline en el número, separación reducida para liberar espacio */
.widget-content .widget-numbers > i,
.widget-chart .widget-numbers .kpi-value-flex > span > i {
    font-size: 0.85em;
    vertical-align: -0.05em;
}

/* ── widget_chart_box(): indicador compacto con trazo ──────────────────────
   Los «chart boxes» de ArchitectUI apilan icono, cifra, rótulo y pie centrados:
   170px de alto cada uno, y cuatro en fila empujan el listado por debajo del
   pliegue. Aquí van en fila —icono a la izquierda, rótulo y cifra a la derecha—
   con la misma información en poco más de la mitad de alto.

   Los selectores llevan `.widget-chart.wcb` y no sólo `.wcb` a propósito: la
   hoja de ArchitectUI trae `.widget-chart .widget-numbers + .widget-subheading
   { margin-top: -0.5rem }`, que con dos clases de especificidad ganaba y subía
   el rótulo OCHO PÍXELES ENCIMA de la cifra. Se veía como un tachón. */
.widget-chart.wcb { padding: .75rem .85rem; text-align: left; }
.widget-chart.wcb .wcb-fila { display: flex; align-items: center; gap: .65rem; min-width: 0; }
.widget-chart.wcb .wcb-txt  { min-width: 0; flex: 1 1 auto; }
.widget-chart.wcb .icon-wrapper { width: 40px; height: 40px; margin: 0; flex: 0 0 40px; }
.widget-chart.wcb .icon-wrapper i { font-size: 1.3rem; }

/* El rótulo va junto al icono, en pequeño; la cifra debajo, a todo el ancho. */
.widget-chart.wcb .widget-subheading {
    margin: 0; font-size: .62rem; font-weight: 600; line-height: 1.15;
    text-transform: uppercase; letter-spacing: .03em; opacity: .75;
    /* La hoja de ArchitectUI le pone overflow:hidden y ellipsis: junto al icono
       quedan ~70px y «EFECTIVIDAD» salía como «EFECTIVIDA…». A su derecha no hay
       nada con lo que chocar, así que se deja respirar. */
    overflow: visible; text-overflow: clip;
}
.widget-chart.wcb .wcb-cifra {
    margin: .4rem 0 0; line-height: 1.15; white-space: nowrap;
    font-size: 1.45rem; max-width: 100%;
}
/* El importe se achica lo justo para caber entero. Recortado con puntos
   suspensivos no sirve de nada: media cifra no es una cifra. */
.widget-chart.wcb .widget-numbers.wcb-money {
    font-size: clamp(14px, 1.05vw + .1rem, 21px) !important;
    letter-spacing: -0.02em;
}
/* Y si aun así no cupiera (un importe de nueve dígitos, una columna estrecha),
   que se vea entero aunque baje de tamaño: el auto-ajuste del layout la reduce
   hasta que entra. Recortar una cifra con puntos suspensivos la vuelve inútil. */
.widget-chart.wcb .wcb-cifra { text-overflow: clip; }
.widget-chart.wcb .wcb-sub { margin: .45rem 0 0; font-size: .72rem; line-height: 1.2; }
/* El trazo va detrás y muy tenue: es la forma de la serie, no un gráfico que
   compita con el texto que sí hay que leer. */
.widget-chart .widget-chart-wrapper svg { max-width: 100%; }
.widget-chart.wcb .widget-chart-wrapper { opacity: .16; }

/* widget_kpi() helper: que el flex interno y el valor de la card no rompan */
.widget-chart .widget-chart-content { min-width: 0; max-width: 100%; }
.widget-chart .widget-chart-flex { min-width: 0; }
.widget-chart .kpi-value-flex {
    display: flex;
    align-items: baseline;
    flex-wrap: nowrap;
    min-width: 0;
    max-width: 100%;
    gap: 0.25rem;
}
.widget-chart .kpi-value {
    min-width: 0;
    white-space: nowrap;
    flex: 0 1 auto;
    /*
     * Sin recorte: media cifra no es una cifra. El auto-ajuste garantiza que
     * quepa entera bajando el tamaño; `clip` es sólo la última red por si el
     * JS no llegara a correr, y aun así es preferible a unos puntos suspensivos
     * que hacen leer «RD$ 471,412…» como si fueran cuatrocientos mil.
     */
    overflow: hidden;
    text-overflow: clip;
}

/*
 * La cifra en su propia línea: se ajusta al ancho disponible.
 *
 * `.kpi-fit` es lo que mide el auto-ajuste del layout, y contiene SÓLO el icono
 * y el importe. Antes el pie iba en la misma línea y arrastraba el tamaño hacia
 * abajo: con «1,173 cobro(s) · 85 cliente(s)» al lado, un importe que cabía a
 * 28 px terminaba dibujado a 10.
 */
.widget-chart .kpi-value-flex.kpi-fit {
    width: 100%;
    line-height: 1.15;
}
/* El pie, debajo y en pequeño: es el contexto de la cifra, no compite con ella. */
.widget-chart .kpi-delta {
    margin-top: .3rem;
    font-size: .78rem;
    line-height: 1.25;
    white-space: normal;      /* que envuelva antes que recortarse */
    overflow: visible;
}
.widget-chart .kpi-delta i { font-size: .9em; }
.widget-chart .widget-title {
    /* Mostrar el título COMPLETO: si no cabe en una línea, envuelve (no se recorta). */
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    word-break: break-word;
    max-width: 100%;
    line-height: 1.2;
}

/* ─────────────────────────────────────────────────────────────────
   Cards principales: que el contenido nunca rompa el ancho del grid
   ───────────────────────────────────────────────────────────────── */
.main-card, .card {
    min-width: 0;
}
.card-header {
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* ─────────────────────────────────────────────────────────────────
   Tablas: forzar `table-layout: auto` y truncate en celdas largas
   marcadas con .cell-truncate (para descripciones, direcciones, etc.).
   ───────────────────────────────────────────────────────────────── */
.table-responsive { min-width: 0; }
.table .cell-truncate {
    max-width: 240px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ─────────────────────────────────────────────────────────────────
   Badges: que el contenido de un badge largo no rompa el flujo.
   Permite multi-línea con wrap suave cuando el contenido es muy largo.
   ───────────────────────────────────────────────────────────────── */
.badge {
    white-space: normal;
    word-break: break-word;
}

/* ─────────────────────────────────────────────────────────────────
   PULIDO FINO — micro-interacciones globales (2026-06-06)
   Subtle, tema claro, sin gradientes. Transiciones suaves + hover en
   KPI cards/filas/botones, fade-in del contenido y estados vacíos
   consistentes. No altera layout, colores base ni tipografía.
   ───────────────────────────────────────────────────────────────── */

/* Transiciones suaves en elementos interactivos */
.card, .btn, .badge, .nav-link, .widget-chart,
.table tbody tr, .form-control, .form-select, .pi-kpi {
    transition: box-shadow .18s ease, transform .18s ease,
                background-color .15s ease, border-color .15s ease, color .15s ease;
}

/* KPI / widget cards: leve elevación al pasar el cursor */
.widget-chart:hover,
.card.widget-content:hover {
    transform: translateY(-3px);
    box-shadow: 0 .5rem 1.4rem rgba(33, 40, 55, .12) !important;
}

/* main-card: profundiza la sombra sin saltar (contienen tablas/formularios) */
.main-card:hover { box-shadow: 0 .4rem 1.1rem rgba(33, 40, 55, .10); }

/* Filas de listados: acento izquierdo sutil al pasar el cursor */
.table-hover tbody tr:hover { box-shadow: inset 3px 0 0 rgba(63, 106, 216, .5); }

/* Botones: micro-presión al click + sombra suave en btn-shadow */
.btn:active { transform: translateY(1px); }
.btn-shadow:hover { box-shadow: 0 .35rem .8rem rgba(33, 40, 55, .14); }

/* Chips KPI propios (pi-kpi): leve realce */
.pi-kpi:hover { box-shadow: 0 .25rem .6rem rgba(33, 40, 55, .10); }

/* Aparición suave del contenido al cargar (un solo fade, sin saltos) */
@keyframes erpFadeIn { from { opacity: 0; } to { opacity: 1; } }
.app-main__inner { animation: erpFadeIn .22s ease both; }

/* Estado vacío reutilizable + realce de celdas "Sin registros" existentes */
.empty-state { text-align: center; color: #9aa1a9; padding: 2.5rem 1rem; }
.empty-state .es-icon { font-size: 3rem; opacity: .35; display: block; margin-bottom: .5rem; }
td.text-soft.text-center, td.text-center.text-soft { color: #9aa1a9; font-style: italic; }

/* Respeto a usuarios con movimiento reducido */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ── Searchable select (combobox) — ver assets/js/erp-searchable-select.js ──── */
.ss-wrap { position: relative; }
/* Dentro de un .input-group (p. ej. el selector de categoría de gastos, que
   lleva su botón "+" al lado) el envoltorio pasa a ser el hijo flexible: si no,
   el combobox se encoge y el botón queda descolgado. */
.input-group > .ss-wrap { flex: 1 1 auto; width: 1%; }
.input-group > .ss-wrap > .ss-input { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.ss-hidden { position: absolute !important; left: -9999px; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.ss-menu { display: none; position: fixed; z-index: 2000; max-height: 260px; overflow-y: auto;
    background: #fff; border: 1px solid rgba(0, 0, 0, .15); border-radius: .25rem; box-shadow: 0 6px 18px rgba(0, 0, 0, .15); }
.ss-menu.ss-show { display: block; }
.ss-item { padding: .4rem .6rem; cursor: pointer; font-size: .85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ss-item:hover, .ss-item.ss-active { background: #e9f2ff; }
.ss-item.ss-current { font-weight: 600; }
/* Nombre completo, creciendo hacia ABAJO y nunca a lo ancho.
   Opt-in con `data-ss-multiline` en el <select> (el JS lo traslada al menú).
   Nace apagado a propósito: el menú se ancla al ancho del control, así que en
   una rejilla estrecha —los repuestos del taller van en un col-md-2 de 215px—
   un nombre de 183 caracteres ocupa siete líneas. Eso es lo correcto ahí, donde
   «CAB-UTP-006 · ROLLO C…» y «CAB-UTP-007 · ROLLO C…» eran indistinguibles,
   pero sería un estorbo en los formularios densos que sí caben en una línea. */
.ss-menu.ss-multiline .ss-item { white-space: normal; overflow: visible; text-overflow: clip;
    overflow-wrap: anywhere; line-height: 1.3; }
/* Con varias líneas por opción, las opciones dejan de distinguirse por el hueco
   entre ellas: hace falta una separación explícita. */
.ss-menu.ss-multiline .ss-item + .ss-item { border-top: 1px solid #f0f3f7; }

/* ── Combobox para el dedo (opt-in con [data-ss-touch]) ──────────────────────
   La fila de 26 px del menú normal se apunta con un ratón; en una tableta
   apoyada en la barra, con la mano mojada, se falla. Esto sube la fila por
   encima de los 44 px de cualquier guía táctil, agranda el texto y deja ver
   más opciones sin desplazar. No cambia nada donde no se pide. */
.ss-menu.ss-touch { max-height: 46vh; border-radius: .5rem; }
.ss-menu.ss-touch .ss-item { padding: .78rem .9rem; font-size: 1rem; line-height: 1.25; }
.ss-menu.ss-touch .ss-item + .ss-item { border-top: 1px solid #f2f5f9; }
.ss-menu.ss-touch .ss-item:active { background: #d8e7ff; }
.ss-input-touch { min-height: 46px; font-size: 1rem; }
/* El control táctil es un <textarea> de una fila que crece en ALTO con el nombre
   elegido (lo ajusta el JS al texto); nunca en ancho ni a mano. */
.ss-textarea { resize: none; overflow: hidden; line-height: 1.3; padding-top: .7rem; padding-bottom: .7rem; white-space: pre-wrap; word-break: break-word; }
.ss-empty { padding: .4rem .6rem; color: #888; font-size: .85rem; }
/* Pie del menú: «buscando en el catálogo» / «hay más, afine la búsqueda».
   Va separado de la lista para que no se lea como una opción más. */
.ss-empty.ss-note { border-top: 1px solid #eef2f7; color: #6b7a8d; font-size: .78rem; font-style: italic; }

/* ── Selects de categorías: resaltar las categorías MADRE ────────────────────
   Chrome/Edge/Firefox aplican estos estilos dentro del desplegable nativo;
   Safari los ignora, por eso la vista añade además el marcador «▸». */
option.cat-opt-parent { font-weight: 700; color: #1f2d3d; background-color: #f2f6fc; }
option.cat-opt-leaf   { font-weight: 400; color: #5a6a7a; }

/* ── Buscador del header → resaltado en el menú lateral (erp-sidebar-search.js) ── */
.vertical-nav-menu .erp-nav-hl mark {
    background: #ffe08a;
    color: inherit;
    padding: 0;
    border-radius: 2px;
}
.vertical-nav-menu .erp-nav-empty {
    font-style: italic;
}

/* ── Sombra de los modales centrados ────────────────────────────────────────
   ArchitectUI pone el box-shadow en el .modal-dialog (base.css ~16899), pero
   .modal-dialog-centered le da display:flex + min-height:100% (base.css ~5892),
   así que ese dialog mide TODO el alto de la ventana: la sombra se dibuja como
   una caja de pantalla completa, visible como una franja por encima y por
   debajo del modal. Se traslada al .modal-content, que es la caja que de verdad
   se ve.

   Va aquí y no en cada vista porque el defecto es del tema y lo sufren los 21
   modales centrados del sistema; parchearlos de uno en uno garantiza que el
   siguiente que alguien escriba vuelva a salir con la franja. */
.modal-dialog-centered { box-shadow: none; }
.modal-dialog-centered > .modal-content {
    box-shadow: 0 0.76875rem 2.4875rem rgba(52, 58, 64, .3),
                0 1.3375rem 1.70625rem rgba(52, 58, 64, .3),
                0 0.55rem 0.53125rem rgba(0, 0, 0, .05),
                0 0.225rem 0.4375rem rgba(52, 58, 64, .3);
}

/* ── Desglose del total (erp-total-breakdown.js) ──────────────────────────────
   El importe se ve igual que antes; el subrayado de puntos es la única pista de
   que se puede pulsar. Se usa <button> por accesibilidad de teclado, así que hay
   que quitarle todo el aspecto de botón. */
.btn-breakdown {
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    font: inherit;
    cursor: pointer;
    border-bottom: 1px dotted rgba(0, 0, 0, .35);
}
.btn-breakdown:hover,
.btn-breakdown:focus {
    color: #3f6ad8;
    border-bottom-color: #3f6ad8;
}
.erp-breakdown td { padding: .35rem .5rem; border-top: 0; }
.erp-breakdown tr + tr td { border-top: 1px solid rgba(0, 0, 0, .06); }
.erp-breakdown-total td {
    font-weight: 700;
    border-top: 2px solid rgba(0, 0, 0, .2) !important;
}
.erp-breakdown-net td { font-weight: 700; }

/* Importes sueltos del desglose: pulsar uno lo copia. Se ven como texto normal
   (una tabla llena de botones azules sería ilegible); la pista es el cursor y el
   subrayado al pasar por encima. */
.btn-bd-amount {
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    font: inherit;
    cursor: pointer;
    position: relative;
    border-bottom: 1px dotted transparent;
}
.btn-bd-amount:hover,
.btn-bd-amount:focus { border-bottom-color: currentColor; }
/* El visto va en absoluto y a la izquierda: si ocupara sitio, la cifra se
   movería justo al confirmar la copia. */
.btn-bd-amount.bd-copiado { color: #3ac47d !important; }
.btn-bd-amount.bd-copiado::after {
    content: '✓';
    position: absolute;
    left: -1.1em;
    color: #3ac47d;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Barra de acciones de una ficha  ·  action_bar() en functions.php

   El problema que resuelve: las fichas de documento acumulan diez o doce
   botones en el título —imprimir, enviar, duplicar, anular, convertir…— todos
   del mismo tamaño y peso. Para encontrar uno había que leerlos todos.

   La barra los baja del título y los reparte en grupos ROTULADOS por para qué
   sirven. El rótulo es lo que convierte la fila en algo que se recorre de un
   vistazo; sin él, agrupar sólo mueve los botones de sitio.

   En el título queda únicamente lo que hace avanzar el documento de estado
   (Editar, Emitir, Aprobar), que así sí destaca.
   ═══════════════════════════════════════════════════════════════════════════ */
.erp-actionbar {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    background: #fff;
    border: 1px solid #e9ecef;
    border-radius: .35rem;
    box-shadow: 0 .1rem .3rem rgba(0, 0, 0, .05);
    padding: .15rem .1rem;
    margin-bottom: 1rem;
}
.erp-ab-group {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: .5rem .9rem;
    position: relative;
    min-width: 0;
}
/* El separador va en ::before del grupo SIGUIENTE: así no sobra una raya al
   final ni hay que saber cuál es el último al pintarlos. */
.erp-ab-group + .erp-ab-group::before {
    content: "";
    position: absolute;
    left: 0;
    top: .55rem;
    bottom: .55rem;
    width: 1px;
    background: #dde2e8;
}
.erp-ab-label {
    font-size: 10px;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: #8a95a5;
    font-weight: 600;
    white-space: nowrap;
    margin-bottom: .4rem;
    line-height: 1;
}
.erp-ab-items {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
}
.erp-ab-items > form { display: inline-block; margin: 0; }
/* La zona de riesgo se empuja al extremo y se rotula en rojo: no se llega a
   ella por inercia al recorrer la barra de izquierda a derecha. */
.erp-ab-riesgo { margin-left: auto; }
.erp-ab-riesgo .erp-ab-label { color: #d92550; }

@media (max-width: 767.98px) {
    /* Apilados a ancho completo y con el separador en horizontal: en un móvil
       las columnas quedarían de un botón de ancho. */
    .erp-ab-group { width: 100%; padding: .5rem .75rem; }
    .erp-ab-group + .erp-ab-group::before {
        left: .75rem; right: 0; top: 0; bottom: auto; width: auto; height: 1px;
    }
    .erp-ab-riesgo { margin-left: 0; }
}


/* ═══════════════════════════════════════════════════════════════════════
   Modales del POS: caja registradora (cobrar) y arqueo (cerrar caja).

   Vivían dentro de `screen.php` como un <style> de 885 líneas. Se movieron
   TAL CUAL —sin tocar una regla— porque la pantalla de la cuenta del salón
   usa el mismo modal de cobro: dos pantallas con el mismo aspecto no pueden
   depender de una hoja que sólo carga una de ellas.
   ═══════════════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════════════
   Cash Register Modal — estilo caja registradora física
   ═══════════════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════════════
   Modal de cobrar — caja registradora · tema CLARO (Bootstrap sólido)
   ═══════════════════════════════════════════════════════════════════════ */
.cash-register-dialog {
    max-width: 1100px;
    /* El margen del diálogo entra en la cuenta del alto: Bootstrap pone
       1.75rem arriba y abajo y con `height: 100dvh - 1rem` el pie quedaba
       12 px por debajo del borde de la pantalla en un portátil de 768. */
    margin: .75rem auto;
    max-height: calc(100vh - 1.5rem);
    max-height: calc(100dvh - 1.5rem);
}
.cash-register {
    background: #fff;
    color: #212529;
    border: 0;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 10px 40px rgba(0,0,0,0.18);
    /* Cabecera y pie fijos. El cuerpo NO desplaza: el diálogo mide lo que
       mide la pantalla y lo de dentro se reparte el alto (los tamaños de
       teclas, cifras y rellenos van en `clamp()` sobre el alto de la ventana,
       así que en un portátil de 768 px se compactan solos y en un monitor
       grande se estiran). Antes el cuerpo desplazaba y en 1366×768 el
       teclado quedaba cortado por la mitad. */
    display: flex;
    flex-direction: column;
    height: calc(100vh - 1.5rem);
    height: calc(100dvh - 1.5rem);
    max-height: calc(100vh - 1.5rem);
    max-height: calc(100dvh - 1.5rem);
}
.cash-register .cr-header,
.cash-register .cr-footer { flex: 0 0 auto; }
.cash-register .modal-body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.cr-header {
    background: #f8f9fa;
    border-bottom: 1px solid #dee2e6;
    padding: clamp(8px, 1.4vh, 14px) 22px;
    color: #212529;
}
.cr-header .modal-title {
    color: #212529;
    font-weight: 700;
    letter-spacing: -0.01em;
    display: flex;
    align-items: center;
    gap: 12px;
}
.cr-header .modal-title .cr-icon { color: #0d6efd; }
.cr-icon { font-size: 22px; }
.cr-close {
    background: transparent;
    border: 0;
    color: #6c757d;
    font-size: 28px;
    line-height: 1;
    padding: 0 10px;
    cursor: pointer;
}
.cr-close:hover { color: #212529; }

.cr-grid {
    display: grid;
    grid-template-columns: 1fr 1.1fr;
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas:
        "display  methods"
        "keypad   methods";
    gap: 0;
    flex: 1 1 auto;
    min-height: 0;
}
.cr-display  { grid-area: display;  border-right: 1px solid #dee2e6; border-bottom: 1px solid #dee2e6;
               padding: clamp(10px, 2.2vh, 24px) 24px clamp(8px, 1.8vh, 20px); background: #fff; }
/* Los métodos son la única zona que puede desplazar: un local con doce
   formas de pago no cabe en ningún alto, y es una lista. */
.cr-methods  { grid-area: methods;  background: #f8f9fa; padding: clamp(10px, 1.8vh, 18px) 20px;
               border-left: 1px solid #dee2e6; overflow-y: auto; min-height: 0; }
/* El teclado reparte el alto que le queda: las teclas crecen o encogen con
   la pantalla en vez de medir siempre lo mismo. */
.cr-keypad   { grid-area: keypad;   padding: clamp(8px, 1.5vh, 16px) 20px clamp(8px, 1.8vh, 20px);
               border-right: 1px solid #dee2e6; background: #fff;
               display: flex; flex-direction: column; min-height: 0;
               /* Última red: si el alto no da (portátil de 768 con avisos), se
                  desplaza; nunca se monta sobre las denominaciones ni el pie. */
               overflow-y: auto; }

/* ── DISPLAY (panel de totales) ── */
.cr-display-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: clamp(3px, .7vh, 7px) 0;
    gap: 16px;
}
.cr-display-label {
    color: #6c757d;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}
.cr-display-value {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: clamp(17px, 2.4vh, 22px);
    color: #212529;
    letter-spacing: -0.01em;
}
.cr-display-divider {
    border-top: 1px dashed #dee2e6;
    margin: 6px 0;
}
.cr-change-row .cr-display-label {
    color: #fd7e14;
    font-size: 13px;
}
.cr-display-value.cr-change {
    font-size: clamp(26px, 4.2vh, 38px);
    color: #198754;
    letter-spacing: -0.02em;
}
.cr-display-value.cr-change.negative {
    color: #dc3545;
}
.cr-display-value.cr-total {
    color: #0d6efd;
    font-size: clamp(20px, 3.1vh, 28px);
}
.cr-short {
    margin-top: 10px;
    background: #f8d7da;
    color: #842029;
    border-left: 3px solid #dc3545;
    padding: 8px 12px;
    border-radius: 4px;
    font-size: 12.5px;
}
.cr-short strong { color: #842029; }
.cr-warn { color: #dc3545; margin-right: 4px; }

/* ── MÉTODOS DE PAGO ── */
.cr-section-title {
    color: #6c757d;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    margin-bottom: 10px;
}
.cr-section-title-mt { margin-top: clamp(8px, 1.6vh, 18px); }
/* «Elige primero el método de pago»: la rejilla de métodos parpadea al teclear
   un importe sin método elegido (ajuste pos.payment_method_required). */
@keyframes crPideMetodo { 0%, 100% { box-shadow: none; } 30%, 70% { box-shadow: 0 0 0 3px rgba(255,193,7,.75); } }
.cr-methods-grid.cr-pide-metodo { animation: crPideMetodo .9s ease-in-out 2; border-radius: 8px; }
.cr-methods-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}
.cr-method-btn {
    background: #fff;
    color: #495057;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    padding: clamp(7px, 1.3vh, 12px) 10px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    transition: all 0.12s;
}
.cr-method-btn:hover { background: #e7f1ff; border-color: #0d6efd; color: #0d6efd; }
.cr-method-btn.active {
    background: #0d6efd;
    color: #fff;
    border-color: #0d6efd;
    box-shadow: 0 0 0 2px rgba(13,110,253,0.25);
}
.cr-method-btn:disabled,
.cr-method-btn.is-used {
    opacity: 0.45;
    cursor: not-allowed;
    background: #f1f3f5;
    color: #adb5bd;
    border-color: #e9ecef;
    box-shadow: none;
}
.cr-method-icon { font-size: 22px; }

.cr-payments-list {
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    padding: 6px;
    min-height: 80px;
}
.cr-payments-empty {
    color: #6c757d;
    text-align: center;
    padding: 18px 10px;
    font-size: 12px;
    font-style: italic;
}
.cr-pay-row {
    background: #f8f9fa;
    border-radius: 6px;
    padding: 8px 10px;
    margin-bottom: 4px;
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    transition: all 0.1s;
    border: 1.5px solid transparent;
}
.cr-pay-row:hover { background: #e9ecef; }
.cr-pay-row.active {
    border-color: #0d6efd;
    background: #e7f1ff;
}
.cr-pay-row .pm-icon { font-size: 16px; color: #0d6efd; }
.cr-pay-row .pm-name { font-size: 13px; font-weight: 500; color: #212529; }
.cr-pay-row .pm-amount {
    font-family: 'JetBrains Mono', monospace;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    color: #198754;
    font-size: 15px;
}
.cr-pay-row .pm-remove {
    background: transparent;
    border: 0;
    color: #dc3545;
    font-size: 16px;
    cursor: pointer;
    padding: 2px 6px;
}

/* ── TECLADO ── */
.cr-keypad-active-info {
    background: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 6px;
    padding: 7px 12px;
    margin-bottom: 10px;
    font-size: 11.5px;
    color: #6c757d;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.cr-keypad-active-info strong {
    color: #0d6efd;
    font-weight: 600;
}
.cr-keypad-active-info .muted { letter-spacing: 0.05em; }

.cr-keys {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    /* Piso por fila: con `minmax(0, 1fr)` y teclas de 38 px mínimos, cuando el
       panel de arriba crecía (el aviso de «venta a crédito», un error del
       servidor) las filas se encogían por debajo de la tecla y los números se
       montaban unos sobre otros. Con el piso, la rejilla mide lo que miden sus
       teclas y, si de verdad no cabe, el teclado desplaza (abajo) en vez de
       solaparse. */
    grid-template-rows: repeat(4, minmax(38px, 1fr));
    gap: clamp(5px, .9vh, 8px);
    /* Crece, y encoge sólo hasta el alto de sus cuatro filas de teclas: si el
       panel desplaza, las denominaciones quedan debajo del teclado, no encima. */
    flex: 1 1 auto;
    min-height: calc(4 * 38px + 3 * 8px);
}
.cr-key {
    background: #fff;
    color: #212529;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    padding: 0;
    min-height: 38px;
    height: 100%;
    font-size: clamp(17px, 2.4vh, 22px);
    font-weight: 600;
    font-family: 'JetBrains Mono', monospace;
    cursor: pointer;
    transition: transform 0.06s, background 0.12s;
    user-select: none;
}
.cr-key:hover  { background: #e9ecef; border-color: #adb5bd; }
.cr-key:active { transform: translateY(1px); background: #dee2e6; }
.cr-key-fn      { background: #f8f9fa; color: #495057; font-size: 17px; }
.cr-key-fn:hover { background: #e9ecef; }
.cr-key-exact   { background: #6f42c1; color: #fff; border-color: #6f42c1; font-weight: 700; }
.cr-key-exact:hover { background: #59359e; border-color: #59359e; }
.cr-key-enter   { background: #198754; color: #fff; border-color: #198754; }
.cr-key-enter:hover { background: #146c43; border-color: #146c43; }

.cr-denoms {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    flex: 0 0 auto;
}
.cr-denom {
    background: #fff;
    color: #495057;
    border: 1px solid #dee2e6;
    border-radius: 6px;
    padding: clamp(5px, .9vh, 9px) 0;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    transition: all 0.12s;
    font-family: 'JetBrains Mono', monospace;
}
.cr-denom:hover { background: #e7f1ff; border-color: #0d6efd; color: #0d6efd; }
.cr-denom-exact { background: #fd7e14; color: #fff; border-color: #fd7e14; grid-column: span 1; }
.cr-denom-exact:hover { background: #e8680a; color: #fff; }
/* En pantallas bajas (portátil de 768, tableta apaisada) las seis denominaciones
   van en UNA fila: es la fila de alto que le faltaba al teclado cuando el panel
   de totales trae un aviso. */
@media (min-width: 768px) and (max-height: 820px) {
    .cr-denoms { grid-template-columns: repeat(6, 1fr); gap: 5px; }
    .cr-denom  { font-size: 12px; }
    .cr-section-title-mt { margin-top: clamp(6px, 1vh, 10px); }
    .cr-keypad-active-info { margin-bottom: 6px; padding: 5px 12px; }
    /* Y el panel de totales cede lo que le sobra: cliente y separaciones más
       ajustados, para que con dos avisos a la vez (crédito + error del
       servidor) el teclado siga cabiendo entero en 768 de alto. */
    .cr-customer { padding: 5px 10px; margin-bottom: 8px; }
    .cr-customer .cr-cust-icon { font-size: 18px; }
    .cr-display { padding-top: 10px; padding-bottom: 8px; }
    .cr-display-divider { margin: 4px 0; }
    .cr-keypad { padding-top: 6px; padding-bottom: 6px; }
    .cr-keypad .cr-section-title { margin-bottom: 6px; }
    .cr-keys { gap: 5px; min-height: calc(4 * 38px + 3 * 5px); }
}
/* Los avisos del panel de totales, compactos: una línea de más no puede
   quitarle una fila al teclado. */
.cr-display .cr-short { margin-top: 6px; padding: 6px 10px; font-size: 12px; line-height: 1.3; }

/* ── FOOTER ── */
.cr-footer {
    background: #f8f9fa;
    border-top: 1px solid #dee2e6;
    padding: clamp(8px, 1.2vh, 12px) 22px;
    flex-wrap: wrap;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
}
.cr-print-toggle {
    color: #495057;
    font-size: 13px;
    margin: 0;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
}
.cr-print-toggle input { accent-color: #0d6efd; cursor: pointer; }
.cr-actions { display: flex; gap: 8px; }
.cr-btn {
    padding: 10px 22px;
    border-radius: 8px;
    border: 1px solid transparent;
    cursor: pointer;
    font-weight: 600;
    font-size: 14px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.cr-btn-cancel { background: #fff; color: #495057; border-color: #ced4da; }
.cr-btn-cancel:hover { background: #f8f9fa; color: #212529; }
/* COBRAR es el botón de la pantalla: grande, para el dedo y para el ojo. */
.cr-btn-confirm {
    background: #198754;
    color: #fff;
    padding: 14px 44px;
    min-height: 58px;
    min-width: 260px;
    justify-content: center;
    font-size: 21px;
    letter-spacing: .02em;
    box-shadow: 0 3px 10px rgba(25,135,84,0.30);
    border-color: #198754;
}
.cr-btn-confirm .cr-hint { font-size: 11px; }
.cr-btn-cancel { min-height: 46px; }
.cr-btn-confirm:hover { background: #146c43; border-color: #146c43; }

/* ── Cobrado: el aviso que sustituye al teclado cuando la venta ya se emitió ──
   Vive DENTRO del mismo diálogo: encadenar un segundo modal de Bootstrap deja
   un fondo huérfano que se traga el clic siguiente. */
.cr-done { padding: 34px 24px; text-align: center; }
.cr-done-icon {
    width: 64px; height: 64px; margin: 0 auto 14px;
    border-radius: 50%; background: #d1e7dd; color: #0f5132;
    font-size: 34px; line-height: 64px; font-weight: 700;
}
.cr-done-title { font-size: 22px; font-weight: 700; color: #0f5132; }
.cr-done-doc   { font-size: 26px; font-weight: 700; letter-spacing: .04em; margin-top: 6px; color: #212529; }
.cr-done-ncf   { font-family: 'JetBrains Mono', ui-monospace, monospace; color: #6c757d; margin-top: 2px; }
.cr-done-actions {
    display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 26px;
}
.cr-done-actions .cr-btn { text-decoration: none; }
/* «Imprimir de nuevo»: con color propio (azul) y del MISMO tamaño que «Volver
   al salón», para que las dos salidas del aviso pesen igual a la vista. */
.cr-btn-print {
    background: #0d6efd; color: #fff; border-color: #0d6efd;
    padding: 14px 32px; min-height: 58px; min-width: 220px; justify-content: center;
    font-size: 18px; box-shadow: 0 3px 10px rgba(13,110,253,0.28);
}
.cr-btn-print:hover { background: #0b5ed7; border-color: #0b5ed7; color: #fff; }
.cr-done-actions .cr-btn-confirm { min-width: 220px; font-size: 18px; padding: 14px 32px; }
/* El diálogo, en modo «cobrado», deja de ser la caja registradora entera: una
   tarjeta centrada de 560 px con el icono grande y los dos botones. */
.cash-register-dialog.cr-done-mode { max-width: 560px; }
.cash-register-dialog.cr-done-mode .cash-register { height: auto; }
.cash-register-dialog.cr-done-mode .cr-done { padding: 40px 28px 36px; }
.cash-register-dialog.cr-done-mode .cr-done-icon { width: 84px; height: 84px; line-height: 84px; font-size: 44px; margin-bottom: 18px; }
.cash-register-dialog.cr-done-mode .cr-done-title { font-size: 26px; }
.cash-register-dialog.cr-done-mode .cr-done-doc { font-size: 30px; }
.cash-register-dialog.cr-done-mode .cr-done-ncf { font-size: 15px; margin-top: 6px; }
@media (max-width: 575.98px) {
    .cash-register-dialog.cr-done-mode .cr-done-actions .cr-btn { width: 100%; min-width: 0; }
}
.cr-btn-confirm:disabled {
    background: #e9ecef;
    color: #6c757d;
    border-color: #dee2e6;
    cursor: not-allowed;
    box-shadow: none;
}
.cr-hint {
    background: rgba(255,255,255,0.25);
    color: #fff;
    font-size: 10px;
    padding: 2px 6px;
    border-radius: 3px;
    font-weight: 700;
    letter-spacing: 0.05em;
}
.cr-btn-cancel .cr-hint { background: #e9ecef; color: #6c757d; }

/* Teléfono: apilado y con desplazamiento; ahí no cabe todo en ningún alto.
   Una tableta en vertical (768) ya va a dos columnas y sin desplazar. */
@media (max-width: 767.98px) {
    .cash-register { height: auto; }
    .cash-register .modal-body { display: block; overflow-y: auto; -webkit-overflow-scrolling: touch; }
    .cr-grid {
        display: grid;
        grid-template-columns: 1fr;
        grid-template-rows: none;
        grid-template-areas: "display" "methods" "keypad";
        min-height: 0;
    }
    /* Apilado: que cada panel fluya y sea el cuerpo del modal el que scrollea */
    .cr-methods {
        border-left: 0;
        border-top: 1px solid #dee2e6;
        max-height: none;
        overflow-y: visible;
    }
    .cr-display,
    .cr-keypad { border-right: 0; }
    .cr-keys { grid-template-rows: none; }
    .cr-key { height: auto; padding: 12px 0; }
    .cr-actions { width: 100%; }
    .cr-btn-confirm { flex: 1 1 auto; min-width: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Cierre de caja — Modal de arqueo · tema CLARO
   ═══════════════════════════════════════════════════════════════════════ */
.close-cash-dialog { max-width: 1200px; }
.close-cash {
    background: #fff;
    color: #212529;
    border: 0;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 10px 40px rgba(0,0,0,0.18);
}
.cc-header {
    background: #f8f9fa;
    border-bottom: 1px solid #dee2e6;
    padding: 14px 22px;
    color: #212529;
}
.cc-header .modal-title {
    color: #212529;
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: 12px;
}
.cc-header .modal-title .cc-icon { color: #dc3545; }
.cc-icon { font-size: 22px; }

.cc-grid {
    display: grid;
    /* minmax(0, ·fr) y no `·fr` a secas: un track `fr` lleva un mínimo automático de
       min-content, así que cualquier contenido ancho lo infla y roba espacio a los
       vecinos. Al activar «Monto manual» aparecía un <input> cuyo ancho intrínseco
       (size=20 a 1.6rem) empujaba la columna del medio de 404px a 465px y encogía la
       primera a 343px. Con minmax(0,·) el reparto es siempre 1.1 / 1.1 / 1. */
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 0;
    min-height: 580px;
}
.cc-summary { padding: 18px 20px; border-right: 1px solid #dee2e6; background: #fff; }
.cc-arqueo  { padding: 18px 20px; border-right: 1px solid #dee2e6; background: #f8f9fa; }
.cc-display { padding: 18px 20px; background: #fff; }

/* Toggle de modo manual + campo manual del arqueo de cierre */
.cc-arqueo-title { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.cc-manual-toggle {
    display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
    font-size: 11px; font-weight: 600; color: #495057; text-transform: none; letter-spacing: 0;
    background: #fff; border: 1px solid #dee2e6; border-radius: 20px; padding: 3px 10px;
}
.cc-manual-toggle input { accent-color: #0d6efd; cursor: pointer; }
.cc-manual-field {
    display: flex; align-items: center; gap: 8px;
    background: #fff; border: 2px solid #0d6efd; border-radius: 10px; padding: 10px 14px; margin: 8px 0;
}
.cc-manual-cur { font-weight: 800; color: #0d6efd; font-size: 15px; }
.cc-manual-input {
    flex: 1; border: 0; outline: 0; font-size: 1.6rem; font-weight: 800; color: #0f172a;
    text-align: right; background: transparent; font-variant-numeric: tabular-nums;
    /* `width:100%` además de `min-width:0`: sin él, el ancho intrínseco del <input>
       (20 caracteres por omisión) sigue contando como tamaño preferido del track. */
    min-width: 0; width: 100%; box-sizing: border-box;
}

.cc-summary-card {
    background: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    padding: 10px 14px;
}
.cc-summary-row {
    display: flex;
    justify-content: space-between;
    padding: 5px 0;
    font-size: 12.5px;
    color: #495057;
}
.cc-summary-row .muted { color: #6c757d; }
.cc-summary-row strong { color: #212529; font-weight: 600; }

.cc-methods-list {
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    padding: 6px;
    max-height: 200px;
    overflow-y: auto;
}
.cc-loading {
    text-align: center;
    color: #6c757d;
    padding: 20px;
    font-size: 12px;
    font-style: italic;
}
.cc-method-row {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: 6px;
    margin-bottom: 2px;
    background: #f8f9fa;
    font-size: 12.5px;
}
.cc-method-row .icon { font-size: 16px; color: #0d6efd; }
.cc-method-row .name { color: #212529; font-weight: 500; }
.cc-method-row .count {
    color: #495057;
    background: #e9ecef;
    padding: 1px 7px;
    border-radius: 10px;
    font-size: 10.5px;
}
.cc-method-row .amount {
    color: #198754;
    font-family: 'JetBrains Mono', monospace;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}

.cc-textarea {
    width: 100%;
    box-sizing: border-box;
    background: #fff;
    border: 1px solid #ced4da;
    border-radius: 8px;
    padding: 8px 12px;
    color: #212529;
    font-size: 13px;
    font-family: inherit;
    resize: vertical;
}
.cc-textarea:focus {
    outline: none;
    border-color: #0d6efd;
    box-shadow: 0 0 0 3px rgba(13,110,253,0.18);
}

/* Denominaciones */
.cc-denom-hint {
    color: #6c757d;
    font-size: 12px;
    margin-bottom: 10px;
    font-style: italic;
}
.cc-denom-table {
    width: 100%;
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    border-collapse: collapse;
    overflow: hidden;
    font-size: 13px;
}
.cc-denom-table thead th {
    background: #f8f9fa;
    color: #6c757d;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    padding: 8px 10px;
    border-bottom: 1px solid #dee2e6;
}
.cc-denom-table tbody td {
    padding: 7px 10px;
    border-bottom: 1px solid #f1f3f5;
}
.cc-denom-table tbody tr:hover { background: #f8f9fa; }
.cc-denom-icon { margin-right: 6px; font-size: 14px; vertical-align: middle; color: #0d6efd; }
.cc-denom-table tbody strong { color: #212529; font-weight: 600; }
.cc-denom-table tbody .muted {
    color: #6c757d;
    margin-left: 6px;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.cc-denom-qty {
    width: 70px;
    background: #fff;
    border: 1px solid #ced4da;
    border-radius: 5px;
    padding: 5px 8px;
    color: #212529;
    text-align: center;
    font-family: 'JetBrains Mono', monospace;
    font-weight: 600;
    font-size: 14px;
}
.cc-denom-qty:focus {
    outline: none;
    border-color: #0d6efd;
    box-shadow: 0 0 0 2px rgba(13,110,253,0.18);
    background: #fff;
}
.cc-denom-total {
    color: #495057;
    font-family: 'JetBrains Mono', monospace;
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}
.cc-denom-total.has-value { color: #198754; font-weight: 700; }
.cc-denom-table tfoot td {
    background: #f8f9fa;
    padding: 10px;
    border-top: 2px solid #0d6efd;
}
.cc-denom-table tfoot strong {
    color: #0d6efd;
    font-size: 15px;
    font-family: 'JetBrains Mono', monospace;
    font-variant-numeric: tabular-nums;
}

.cc-quickfill {
    display: flex;
    gap: 6px;
    margin-top: 10px;
    justify-content: flex-end;
}
.cc-btn-quick {
    background: #fff;
    color: #495057;
    border: 1px solid #ced4da;
    border-radius: 5px;
    padding: 5px 12px;
    font-size: 11.5px;
    cursor: pointer;
    font-weight: 500;
}
.cc-btn-quick:hover { background: #f8f9fa; color: #0d6efd; border-color: #0d6efd; }

/* Panel de totales columna 3 */
.cc-display-section {
    background: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 10px;
    padding: 14px 18px;
    margin-bottom: 14px;
}
.cc-display-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 6px 0;
    gap: 16px;
}
.cc-display-label {
    color: #6c757d;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}
.cc-display-value {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 18px;
    color: #212529;
}
.cc-display-divider {
    border-top: 1px dashed #dee2e6;
    margin: 4px 0;
}
.cc-display-neg { color: #dc3545; }

/* Aviso de rango de NCF en la caja: una tira, no un cartel. Lo que ocupa media
   pantalla se cierra sin leer a los tres días. */
.pos-ncf-alert {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 16px; font-size: 12.5px; line-height: 1.35;
    background: #fef3c7; color: #7c4a03; border-bottom: 2px solid #f59e0b;
}
.pos-ncf-alert.is-urgent { background: #fee2e2; color: #8c1d18; border-bottom-color: #dc2626; }
.pos-ncf-alert .pos-ncf-icon { font-size: 15px; line-height: 1; flex: 0 0 auto; }
.pos-ncf-alert .pos-ncf-text { flex: 1 1 auto; }
.pos-ncf-alert .pos-ncf-link {
    flex: 0 0 auto; font-weight: 700; text-decoration: underline; color: inherit; white-space: nowrap;
}

.cc-led-expected-row .cc-display-label { color: #0d6efd; font-size: 12px; }
/* «Esperado − apertura»: el efectivo que generó el turno. Va debajo del esperado
   y deliberadamente más discreto — el número contra el que se cuadra la gaveta
   sigue siendo el ESPERADO, éste es el que se entrega. */
.cc-led-net-row { padding-top: 0; }
.cc-led-net-row .cc-display-label { color: #64748b; font-size: 10px; }
.cc-led-net { font-size: 15px; color: #475569; }

/* Corregir el fondo de apertura: enlace discreto en la etiqueta y el formulario
   desplegable DENTRO del propio diálogo de cierre (encadenar dos modales de
   Bootstrap deja un velo huérfano y el segundo sale sin maquetar). */
.cc-fix-link {
    margin-left: 8px; font-size: 9.5px; font-weight: 700; text-transform: none;
    color: #f59e0b; text-decoration: underline; cursor: pointer;
}
.cc-fix-link:hover { color: #b45309; }
.cc-fix-box {
    background: rgba(245, 158, 11, .08); border: 1px solid rgba(245, 158, 11, .35);
    border-radius: 8px; padding: 10px 12px; margin: 6px 0 10px;
}
.cc-fix-box .cc-fix-lbl {
    display: block; font-size: 10px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .04em; color: #92400e; margin: 6px 0 2px;
}
.cc-fix-box .cc-fix-lbl:first-child { margin-top: 0; }
.cc-fix-actions { display: flex; gap: 6px; justify-content: flex-end; margin-top: 10px; }
.cc-fix-hint { font-size: 10px; color: #92400e; margin-top: 6px; }
.cc-otros-hint { font-size: 11px; color: #94a3b8; margin: 2px 0 6px; line-height: 1.35; }
.cc-otro-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-bottom: 1px solid #f1f5f9; font-size: 12px; }
.cc-otro-row .tag { flex: 0 0 auto; font-size: 10px; padding: 1px 6px; border-radius: 8px; background: #eef2ff; color: #4338ca; white-space: nowrap; }
.cc-otro-row .tag.danger { background: #fee2e2; color: #b91c1c; }
.cc-otro-row .tag.warning { background: #fef3c7; color: #92400e; }
.cc-otro-row .tag.success { background: #dcfce7; color: #166534; }
.cc-otro-row .tag.info { background: #e0f2fe; color: #075985; }
.cc-otro-row .doc { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #475569; }
.cc-otro-row .when { flex: 0 0 auto; color: #94a3b8; font-size: 10.5px; }
.cc-otro-row .amt { flex: 0 0 auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.cc-otro-row .amt.in  { color: #15803d; }
.cc-otro-row .amt.out { color: #b91c1c; }
.cc-otros-total { display: flex; justify-content: space-between; padding: 7px 8px; font-size: 12px; font-weight: 700; background: #f8fafc; border-radius: 6px; margin-top: 4px; }
.cc-led-note { font-size: 10.5px; color: #93c5fd; padding: 6px 2px 0; line-height: 1.4; }
.cc-led-expected { font-size: 28px; color: #0d6efd; }
.cc-led-actual   { font-size: 22px; color: #198754; }

.cc-led-diff-row .cc-display-label { font-size: 14px; }
.cc-led-diff {
    font-size: 32px;
    color: #212529;
    transition: color 0.2s;
}
.cc-led-diff.exact   { color: #198754; }
.cc-led-diff.over    { color: #fd7e14; }
.cc-led-diff.under   { color: #dc3545; }

.cc-status {
    margin-top: 10px;
    background: #cfe2ff;
    color: #084298;
    border-left: 3px solid #0d6efd;
    padding: 9px 12px;
    border-radius: 4px;
    font-size: 12.5px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.cc-status.exact   { background: #d1e7dd; color: #0a3622; border-left-color: #198754; }
.cc-status.over    { background: #fff3cd; color: #664d03; border-left-color: #fd7e14; }
.cc-status.under   { background: #f8d7da; color: #842029; border-left-color: #dc3545; }
.cc-status-icon { font-size: 16px; }

.cc-footer {
    background: #f8f9fa;
    border-top: 1px solid #dee2e6;
    padding: 12px 22px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
}
.cc-btn-confirm {
    background: #dc3545;
    border-color: #dc3545;
    box-shadow: 0 2px 6px rgba(220,53,69,0.25);
}
.cc-btn-confirm:hover { background: #b02a37; border-color: #b02a37; }
.cc-btn-confirm:disabled {
    background: #e9ecef;
    color: #6c757d;
    border-color: #dee2e6;
    box-shadow: none;
}

/* Las tres columnas se conservan hasta la tableta apaisada (1024 px): en dos
   columnas el LED del esperado cae debajo del pliegue y hay que desplazarse. */
@media (max-width: 900px) {
    .cc-grid {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
    .cc-display { grid-column: 1 / -1; border-top: 1px solid #dee2e6; }
}
@media (max-width: 700px) {
    .cc-grid { grid-template-columns: minmax(0, 1fr); }
    .cc-summary, .cc-arqueo, .cc-display {
        border-right: 0;
        border-bottom: 1px solid #dee2e6;
    }
}

/* Ajuste a pantalla. El diálogo tiene que caber ENTERO en una tableta apaisada
   (768 px de alto) sin que la página se desplace: el cajero cuenta billetes
   mirando el LED de la derecha, y si el «esperado» se va por debajo del borde
   cuenta a ciegas. Se aprietan márgenes y cuerpos de letra —no se quita nada—
   y, si la pantalla es más baja todavía, se desplaza SÓLO el cuerpo del
   diálogo, nunca la página. */
/* Bootstrap encoge .modal-xl a 800 px entre 992 y 1199: en la tableta apaisada
   el diálogo quedaba estrecho y la tercera columna caía debajo. Aquí ocupa el
   ancho que haya, hasta 1200. */
.close-cash-dialog { margin: .5rem auto; max-width: min(1200px, calc(100vw - 1rem)); }
.close-cash-dialog.modal-dialog-centered { min-height: calc(100% - 1rem); }
.close-cash { max-height: calc(100vh - 1rem); display: flex; flex-direction: column; }
.close-cash .modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.cc-grid { min-height: 0; }
.cc-header { padding: 9px 18px; }
.cc-header .modal-title { font-size: 1rem; }
.cc-icon { font-size: 18px; }
.cc-summary, .cc-arqueo, .cc-display { padding: 12px 14px; }
.cc-summary .cr-section-title, .cc-arqueo .cr-section-title { margin-bottom: 6px; }
.cc-summary .cr-section-title-mt { margin-top: 8px; }
.cc-summary-card { padding: 6px 12px; }
.cc-summary-row { padding: 2px 0; font-size: 12px; }
.cc-methods-list { padding: 4px; }
.cc-loading { padding: 10px; }
.cc-method-row { padding: 4px 8px; font-size: 12px; }
.cc-textarea { padding: 6px 10px; font-size: 12.5px; }
.cc-summary .cr-print-toggle { margin: 4px 0 0; font-size: 12px; }
.cc-denom-hint { margin-bottom: 6px; font-size: 11.5px; }
.cc-denom-table { font-size: 12.5px; }
.cc-denom-table thead th { padding: 5px 8px; }
.cc-denom-table tbody td { padding: 2px 8px; }
.cc-denom-qty { padding: 3px 6px; font-size: 13px; width: 64px; }
.cc-denom-table tfoot td { padding: 6px 8px; }
.cc-manual-field { padding: 8px 12px; }
.cc-manual-input { font-size: 1.4rem; }
.cc-quickfill { margin-top: 6px; }
.cc-display-section { padding: 8px 14px; margin-bottom: 8px; }
.cc-display-row { padding: 3px 0; }
.cc-display-value { font-size: 16px; }
.cc-led-expected { font-size: 24px; }
.cc-led-actual   { font-size: 20px; }
.cc-led-diff     { font-size: 26px; }
.cc-status { margin-top: 6px; padding: 6px 10px; font-size: 12px; }
.cc-footer { padding: 8px 18px; }
.cc-footer .cr-btn { padding: 8px 18px; font-size: 13.5px; }

@media (max-width: 1100px) {
    /* Con tres columnas en 1024 px sobra poco: fuera la coletilla «Billete/Moneda». */
    .cc-denom-table tbody .muted { display: none; }
    .cc-denom-table thead th { font-size: 9.5px; letter-spacing: .08em; }
}

/* Cuentas del salón abiertas: el aviso que el cajero tiene que marcar. */
.cc-tabs-warn {
    background: #fef2f2; border: 1px solid #fca5a5; border-left: 4px solid #dc2626;
    border-radius: 8px; padding: 8px 12px; margin-bottom: 10px; color: #7f1d1d;
}
.cc-tabs-warn-title { font-weight: 700; font-size: 12.5px; }
.cc-tabs-warn-text  { font-size: 11.5px; line-height: 1.35; margin: 2px 0 6px; }
.cc-tabs-ack { display: flex; align-items: flex-start; gap: 8px; margin: 0; font-size: 12px; font-weight: 600; cursor: pointer; }
.cc-tabs-ack input { margin-top: 2px; accent-color: #dc2626; cursor: pointer; }

/* ═══════════════════════════════════════════════════════════════════════
   Alta rápida de cliente — el documento manda
   ═══════════════════════════════════════════════════════════════════════ */
.qc-body { padding: 20px 22px 4px; }
.qc-doc-wrap {
    border: 2px solid #cfe2ff; border-radius: 12px; background: #f8fbff;
    padding: 14px 16px 12px; transition: border-color .18s, background .18s;
}
.qc-doc-wrap.is-ok   { border-color: #198754; background: #f2fbf6; }
.qc-doc-wrap.is-warn { border-color: #fd7e14; background: #fffaf3; }
.qc-doc-wrap.is-bad  { border-color: #dc3545; background: #fff5f5; }
.qc-doc-wrap.is-busy { border-color: #adb5bd; background: #f8f9fa; }
.qc-doc-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.qc-doc-head .cr-section-title { margin: 0; }
.qc-doc-badge { margin-left: auto; }
.qc-doc-input {
    font-size: 1.45rem; font-weight: 700; letter-spacing: .04em;
    font-variant-numeric: tabular-nums; height: auto; padding: 10px 14px;
    border-radius: 9px 0 0 9px; border-color: #ced4da; color: #0f172a;
}
.qc-doc-input:focus { box-shadow: none; border-color: #0d6efd; }
.qc-doc-input::placeholder {
    font-size: .92rem; font-weight: 500; letter-spacing: 0; color: #b6c0cd;
    font-variant-numeric: normal;
}
.qc-doc-btn {
    border-radius: 0 9px 9px 0; padding: 0 18px; font-size: 20px; line-height: 1;
    border: 1px solid #ced4da; border-left: 0; background: #fff; color: #0d6efd; cursor: pointer;
}
.qc-doc-btn:hover { background: #e7f1ff; }
.qc-status { font-size: 12px; line-height: 1.45; margin-top: 8px; min-height: 18px; color: #6c757d; }
.qc-status.ok   { color: #146c43; font-weight: 600; }
.qc-status.warn { color: #a15c07; }
.qc-status.bad  { color: #b02a37; font-weight: 600; }
.qc-existing {
    display: flex; align-items: center; gap: 10px; margin-top: 12px;
    background: #fff3cd; border-left: 3px solid #fd7e14; border-radius: 0 8px 8px 0;
    padding: 10px 12px; font-size: 12.5px; color: #664d03;
}
.qc-existing strong { color: #573b02; }
.qc-fields { margin-top: 18px; }
.qc-label { font-size: 12px; font-weight: 600; color: #495057; margin-bottom: 5px; display: block; }
.qc-label .req { color: #dc3545; }
.qc-input { border-radius: 8px; border-color: #ced4da; }
.qc-input:focus { border-color: #0d6efd; box-shadow: none; }
.qc-name-input { font-size: 1.05rem; font-weight: 600; padding: 10px 12px; height: auto; }
.qc-hint { font-size: 11px; color: #adb5bd; margin-top: 4px; }

/* ═══════════════════════════════════════════════════════════════════════
   Popup post-venta (SweetAlert) — botones grandes con contraste fuerte
   ═══════════════════════════════════════════════════════════════════════ */
.pos-sale-popup .swal2-actions {
    gap: 12px !important;
    margin-top: 18px !important;
}
.pos-sale-popup .swal2-confirm,
.pos-sale-popup .swal2-cancel {
    font-size: 15px !important;
    font-weight: 600 !important;
    padding: 12px 28px !important;
    border-radius: 8px !important;
    border: 0 !important;
    min-width: 160px;
    box-shadow: 0 2px 6px rgba(0,0,0,0.12) !important;
    transition: transform 0.08s, box-shadow 0.12s !important;
}
.pos-sale-popup .swal2-confirm:hover,
.pos-sale-popup .swal2-cancel:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.18) !important;
}
.pos-sale-popup .swal2-cancel {
    color: #fff !important;
    /* verde nítido — alto contraste vs fondo blanco del popup y vs el botón azul */
    background: #16a34a !important;
}
.pos-sale-popup .swal2-cancel:hover {
    background: #15803d !important;
}
.pos-sale-popup .swal2-confirm {
    color: #fff !important;
    background: #3f6ad8 !important;
}
.pos-sale-popup .swal2-confirm:hover {
    background: #2e57bf !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   Selector de cliente con búsqueda (combobox + dropdown de resultados)
   ═══════════════════════════════════════════════════════════════════════ */
.pos-customer-picker { position: relative; }
.pos-customer-results {
    display: none;
    position: absolute;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    z-index: 1080;
    background: #fff;
    border: 1px solid #ced4da;
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(15,23,42,.16);
    max-height: 320px;
    overflow-y: auto;
}
.pos-customer-results.open { display: block; }
.pos-cust-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    cursor: pointer;
    border-bottom: 1px solid #f1f3f5;
}
.pos-cust-row:last-child { border-bottom: 0; }
.pos-cust-row:hover,
.pos-cust-row.active { background: #e7f1ff; }
.pos-cust-row .pcr-icon { font-size: 18px; color: #3f6ad8; flex-shrink: 0; }
.pos-cust-row .pcr-body { min-width: 0; flex: 1; }
.pos-cust-row .pcr-name {
    font-size: 13px; font-weight: 600; color: #212529;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pos-cust-row .pcr-meta { font-size: 11px; color: #6c757d; }
.pos-cust-row .pcr-credit { font-weight: 600; }
.pos-cust-row .pcr-credit.ok      { color: #198754; }
.pos-cust-row .pcr-credit.warning { color: #fd7e14; }
.pos-cust-row .pcr-credit.danger  { color: #dc3545; }
.pos-cust-row .pcr-class {
    font-size: 10px; font-weight: 700; letter-spacing: .03em;
    padding: 1px 7px; border-radius: 10px; flex-shrink: 0;
    background: #e9ecef; color: #495057;
}
.pos-cust-row.is-default .pcr-icon { color: #6c757d; }
.pos-cust-empty { padding: 14px 12px; text-align: center; color: #6c757d; font-size: 12.5px; font-style: italic; }

/* Cliente mostrado en el modal de caja registradora */
.cr-customer {
    display: flex;
    align-items: center;
    gap: 10px;
    background: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    padding: 8px 12px;
    margin-bottom: 14px;
}
.cr-customer .cr-cust-icon { font-size: 22px; color: #0d6efd; flex-shrink: 0; }
.cr-customer .cr-cust-body { min-width: 0; flex: 1; }
.cr-customer .cr-cust-name {
    font-size: 14px; font-weight: 700; color: #212529;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cr-customer .cr-cust-meta { font-size: 11.5px; color: #6c757d; }

/* ── Con o sin comprobante, en el propio diálogo de cobro ────────────────────
   Va justo debajo del cliente porque es la misma decisión: a quién se le
   factura y con qué documento. Se ve ANTES de pulsar COBRAR, que es cuando
   todavía se puede cambiar. El interruptor sólo aparece donde la zona deja
   elegir; donde no, se informa y punto. */
.cr-fiscal {
    display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px;
    border-radius: 8px; padding: 8px 12px; margin-bottom: 14px;
    font-size: 13px; cursor: pointer;
    background: #fff8e6; border: 1px solid #ffe0a3; color: #7a5200;
}
.cr-fiscal input[type="checkbox"] { width: 18px; height: 18px; flex-shrink: 0; cursor: pointer; }
.cr-fiscal span { flex: 1; min-width: 0; }
.cr-fiscal small { width: 100%; font-size: 11px; opacity: .85; }
.cr-fiscal i { font-size: 20px; flex-shrink: 0; }
/* Sin interruptor: es un aviso, no una decisión. */
.cr-fiscal-fijo  { cursor: default; background: #fdeaef; border-color: #f7c6d3; color: #8f1533; }
.cr-fiscal-falta { cursor: default; background: #fdeaef; border-color: #f7c6d3; color: #8f1533; }

/* ── Listas de precio (/price-lists) ──────────────────────────────────────────
   La casilla de cada nivel lleva debajo una nota (diferencia contra el precio de
   venta, o el aviso de que está bajo el piso/el costo). La nota se reserva su
   sitio SIEMPRE aunque esté vacía: si apareciera y desapareciera al teclear, la
   fila daría saltos y el número que se está escribiendo se movería bajo el
   cursor. */
.erp-pl-celda { width: 8.5rem; vertical-align: top; }
.erp-pl-nota {
    display: block;
    min-height: 1.05rem;
    margin-top: .15rem;
    font-size: .72rem;
    line-height: 1.05rem;
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.erp-pl-refs { font-size: .72rem; opacity: .85; }
.erp-pl-refs i { opacity: .7; }
/* Debajo de cada precio, lo que cobra la factura con el ITBIS (o «exento»).
   Reserva su sitio igual que la nota, por la misma razón: que nada salte. */
.erp-pl-itbis {
    display: block;
    min-height: 1rem;
    margin-top: .15rem;
    font-size: .7rem;
    line-height: 1rem;
    text-align: right;
    white-space: nowrap;
    color: #6c757d;
    opacity: .9;
}

/* Bajo el costo: aviso, no error de validación — el precio es válido y se puede
   guardar, sólo que se vende perdiendo. Bajo el PISO sí usa .is-invalid de
   Bootstrap, porque esa venta el sistema la rechaza de verdad. */
.erp-pl-precio.erp-pl-aviso { border-color: #d92550; background-color: #fff6f8; }
.erp-pl-tabla tbody tr:hover .erp-pl-precio { border-color: #ced4da; }
.erp-pl-precio:focus { position: relative; z-index: 2; }

/* En pantallas estrechas la tabla scrollea en horizontal (va dentro de
   .table-responsive); el producto se queda a la vista para no perder de vista
   cuál se está tocando. */
@media (min-width: 992px) {
    .erp-pl-tabla thead th:first-child,
    .erp-pl-tabla tbody td:first-child { min-width: 18rem; }
}

/* ── Cargos bancarios (/expenses/cargos-bancarios) ────────────────────────────
   Tres estados en una misma vista: formulario, vista previa y resultado. El
   lenguaje visual es el de los importadores (import_style.php) más una tarjeta
   del banco elegido —con su RNC— que es lo que el usuario necesita ver antes de
   confirmar que ese banco se convierta en suplidor. */
.bc-bank-card { display:flex; align-items:center; gap:.85rem; padding:.8rem 1rem; border:1px solid rgba(63,106,216,.18);
    border-radius:.6rem; background:linear-gradient(135deg, rgba(63,106,216,.06), rgba(63,106,216,.015)); }
.bc-bank-card .bc-avatar { flex:0 0 auto; width:2.6rem; height:2.6rem; border-radius:.55rem; display:flex; align-items:center;
    justify-content:center; font-weight:700; font-size:.95rem; letter-spacing:.02em; color:#fff;
    background:linear-gradient(135deg,#3f6ad8,#5b86e5); box-shadow:0 2px 6px rgba(63,106,216,.35); }
.bc-bank-card .bc-name { font-weight:600; line-height:1.2; }
.bc-bank-card .bc-rnc { font-variant-numeric:tabular-nums; color:#495057; font-size:.85rem; }
.bc-bank-card .badge { font-weight:600; }

.bc-facts { display:grid; grid-template-columns:repeat(auto-fit, minmax(13rem, 1fr)); gap:.6rem; }
.bc-fact { display:flex; gap:.65rem; align-items:flex-start; padding:.65rem .8rem; border-radius:.55rem; background:rgba(0,0,0,.025); }
.bc-fact i { font-size:1.35rem; line-height:1; margin-top:.1rem; }
.bc-fact .lbl { display:block; font-size:.72rem; text-transform:uppercase; letter-spacing:.04em; color:#6c757d; }
.bc-fact .val { font-weight:600; font-size:.9rem; line-height:1.25; }
.bc-fact .sub { display:block; font-size:.78rem; color:#6c757d; font-weight:400; }

.bc-info li { display:flex; gap:.6rem; align-items:flex-start; padding:.45rem 0; border-bottom:1px dashed rgba(0,0,0,.07); }
.bc-info li:last-child { border-bottom:0; }
.bc-info li i { flex:0 0 1.5rem; font-size:1.25rem; line-height:1.1; text-align:center; }
.bc-sample { font-size:.74rem; background:#1f2937; color:#e5e7eb; border-radius:.5rem; padding:.7rem .85rem; margin:0; white-space:pre; overflow-x:auto; }
.bc-sample .h { color:#93c5fd; }

.bc-table td, .bc-table th { vertical-align:middle; }
.bc-table .bc-ncf { font-family:SFMono-Regular, Menlo, Consolas, monospace; font-size:.86rem; letter-spacing:.02em; }
.bc-table .bc-note { font-size:.8rem; }
.bc-table tfoot td { font-weight:600; background:rgba(63,106,216,.05); }

.bc-post-box { display:flex; align-items:flex-start; gap:.6rem; padding:.7rem .9rem; border:1px solid rgba(58,196,125,.35);
    border-radius:.6rem; background:rgba(58,196,125,.07); max-width:34rem; }
.bc-post-box input { margin-top:.2rem; }
.bc-post-box .form-check-label { font-weight:600; }
.bc-post-box small { font-weight:400; }

.bc-done { display:flex; align-items:center; gap:1.1rem; padding:1.1rem 1.25rem; border-radius:.7rem; color:#fff;
    background:linear-gradient(135deg,#3ac47d,#1f9d63); box-shadow:0 4px 14px rgba(58,196,125,.35); }
.bc-done .bc-check { flex:0 0 auto; width:3.2rem; height:3.2rem; border-radius:50%; background:rgba(255,255,255,.2);
    display:flex; align-items:center; justify-content:center; font-size:1.9rem; }
.bc-done h5 { margin:0 0 .15rem; font-weight:700; color:#fff; }
.bc-done .bc-done-sub { opacity:.92; font-size:.9rem; }
