/* =============================================================
   MODERNIZACIÓN UI — 2025
   ============================================================= */

/* --- RadioButtonGroup: borde sutil y prolijo --- */
.my-radiobutton-group {
    gap: 4px !important;
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    padding: 3px;
    box-shadow: inset 0 1px 2px rgba(0,0,0,.04);
    display: inline-flex !important;
}
.my-radiobutton-group .btn {
    cursor: pointer;
    border-radius: 7.2px !important;
    border: 1px solid transparent !important;
    background: transparent !important;
    color: #64748b !important;
    box-shadow: none !important;
    padding: 5px 10px !important;
    transition: background .15s, color .15s, border-color .15s, box-shadow .15s;
    font-size: .8rem;
}
.my-radiobutton-group .btn:hover {
    background: #ffffff !important;
    color: #334155 !important;
    border-color: #e2e8f0 !important;
    box-shadow: 0 1px 3px rgba(0,0,0,.08) !important;
}
.my-radiobutton-group .btn.active {
    background: #ffffff !important;
    color: #1e40af !important;
    border-color: #dbeafe !important;
    box-shadow: 0 1px 4px rgba(30,64,175,.12) !important;
    font-weight: 600;
}

/* ===================================================================
   LA BASE DE LA FUENTE: 13px, COMO EL GESTOR (14/09/2026, decision de Pablo)
   ===================================================================
   Master0.Master pone class="text-sm" en <html>, y AdminLTE lo resuelve como
   .text-sm { font-size: .875rem !important } (theme.css ~16627) = 14px.
   El GESTOR corre en 13px, y ese 8% era la mayor parte de "ISPBoss se ve mas
   grande": lo heredan campos, grillas, botones y cabeceras, porque todo el
   tema esta en rem. Se fija en px para que no dependa del zoom de fuente del
   navegador. Gana por especificidad (html + clase contra clase sola). */
html.text-sm { font-size: 13px !important; }

/* --- Cards: sombra suave, sin borde lateral azul AdminLTE --- */
.card {
    border: none !important;
    border-radius: 12px !important;
    box-shadow: 0 1px 3px rgba(0,0,0,.07), 0 4px 18px rgba(0,0,0,.06) !important;
    transition: box-shadow .2s;
}
.card:hover {
    box-shadow: 0 2px 6px rgba(0,0,0,.09), 0 6px 24px rgba(0,0,0,.08) !important;
}
.card.card-outline {
    border-top: none !important;
}
/* Fondo gris claro de "card neutra" — se aplica solo cuando el header NO tiene
   una clase de fondo propia (bg-info, bg-success, bg-primary, bg-warning,
   bg-danger, bg-dark, bg-secondary). De lo contrario, el header con su color
   propio quedaba "tapado" por este fondo gris debido a la alta especificidad
   del selector con multiples :not().
   ⚠ Por lo mismo se le agrega `:not([class*="card-mod-"])` (27/08/2026): las
   cabeceras de ficha con línea de color van con el header BLANCO, y su regla
   —tres clases— no tiene con qué ganarle a este selector, que suma ~18. Medido
   en vivo: el header salía `#f8fafc` en vez de `#fff`. La exclusión es además
   lo correcto semánticamente: una card de módulo NO es una card neutra. */
/* `:not(.vtl-card)` (22/09/2026): la Línea de Vida del abonado lleva cabecera BLANCA con
   acento pastel, como las `card-*` que la rodean (ver "Línea de Vida del Abonado" al final). */
/* `:not(.card-subheader)` (16/09/2026): una BANDA de sección también es un `.card-header`
   cuando la dibuja cc:CollapsableBox, y esta regla -que pesa unas veinte clases y lleva
   fondo con !important- le pisaba el fondo y el tamaño de letra. La banda tiene su estilo
   propio, más abajo ("BANDA DE SECCIÓN DENTRO DE UNA TARJETA"). */
.card:not(.card-primary):not(.card-secondary):not(.card-success):not(.card-danger):not(.card-warning):not(.card-info):not(.card-dark):not(.abonado-ficha-card):not(.vtl-card):not([class*="card-mod-"]) > .card-header:not(.bg-info):not(.bg-primary):not(.bg-success):not(.bg-warning):not(.bg-danger):not(.bg-dark):not(.bg-secondary):not([class*="bg-gradient-"]):not(.card-subheader) {
    border-radius: 12px 12px 0 0 !important;
    border-bottom: 1px solid rgba(0,0,0,.06) !important;
    background: #f8fafc !important;
    font-weight: 600;
    font-size: .88em;
    color: #374151;
    padding: .75rem 1.1rem;
}
/* =============================================================
   CABECERAS DE CARD: DE BLOQUE SATURADO A PASTEL
   =============================================================
   27/08/2026, a pedido de Pablo sobre la solapa Resumen de la ficha del
   abonado: ocho paneles, ocho tratamientos distintos —azul pleno, pizarra
   plena, degradé cyan, blanco— uno al lado del otro.

   No hizo falta inventar nada: este archivo es un fork de un estado anterior
   del mismo archivo del GESTOR (`SofMic.Framework.Admin\scss\_sm-cards-color.scss`),
   con la MISMA estructura y los valores viejos. Allá esos siete degradés ya
   se convirtieron a pastel; acá se traen tal cual, con los mismos hex, para
   que un `bg-info` se vea igual en los dos productos.

   EL COLOR SEMÁNTICO NO SE PIERDE, cambia de rol: en vez de ser el fondo de un
   bloque que pesa más que su propio contenido, es un pastel del mismo tono con
   el texto oscuro de esa familia. Un panel de error sigue leyéndose como rojo;
   lo que deja de hacer es gritar por encima del dato.

   Los íconos y los `small` pasan de blanco fijo a `inherit`: si heredan el
   tono oscuro del pastel se leen; con el `#fff` de antes desaparecían. */
.card-header[class*="bg-gradient-info"],    .card-header.bg-info    { background: linear-gradient(160deg,#ecfeff,#cffafe) !important; color:#155e75 !important; }
.card-header[class*="bg-gradient-primary"], .card-header.bg-primary { background: linear-gradient(160deg,#eef2ff,#e0e7ff) !important; color:#3730a3 !important; }
.card-header[class*="bg-gradient-success"], .card-header.bg-success { background: linear-gradient(160deg,#ecfdf5,#d1fae5) !important; color:#065f46 !important; }
.card-header[class*="bg-gradient-danger"],  .card-header.bg-danger  { background: linear-gradient(160deg,#fef2f2,#fee2e2) !important; color:#991b1b !important; }
.card-header[class*="bg-gradient-warning"], .card-header.bg-warning { background: linear-gradient(160deg,#fffbeb,#fef3c7) !important; color:#92400e !important; }
.card-header[class*="bg-gradient-dark"],    .card-header.bg-dark    { background: linear-gradient(160deg,#f1f5f9,#e2e8f0) !important; color:#1e293b !important; }
.card-header[class*="bg-gradient-secondary"], .card-header.bg-secondary { background: linear-gradient(160deg,#f8fafc,#f1f5f9) !important; color:#334155 !important; }
/* `bg-blue` es de AdminLTE y no existe en el GESTOR; acá lo usa una cabecera
   suelta. Va con el mismo pastel que `bg-primary` para no dejarla azul plena
   al lado de las demás. */
.card-header.bg-blue { background: linear-gradient(160deg,#eef2ff,#e0e7ff) !important; color:#3730a3 !important; }
.card-header.bg-info, .card-header.bg-primary, .card-header.bg-success,
.card-header.bg-warning, .card-header.bg-danger, .card-header.bg-dark,
.card-header.bg-secondary, .card-header.bg-blue { font-weight: 600; padding: .55rem 1rem; }
/* `inherit` y no un hex: así cada header le pasa a sus íconos el tono oscuro de
   SU familia, y no hay que repetir siete colores. El `!important` es para
   ganarle al `text-white` que varias cabeceras traen escrito en el markup. */
.card-header.bg-info i, .card-header.bg-primary i, .card-header.bg-success i,
.card-header.bg-warning i, .card-header.bg-danger i, .card-header.bg-dark i,
.card-header.bg-secondary i, .card-header.bg-blue i { color: inherit !important; opacity: .8; }
.card-header.bg-info small, .card-header.bg-primary small, .card-header.bg-success small,
.card-header.bg-warning small, .card-header.bg-danger small, .card-header.bg-dark small,
.card-header.bg-secondary small, .card-header.bg-blue small { color: inherit !important; opacity: .7; }
/* LO QUE TRAE EL BLANCO ESCRITO EN EL MARKUP.
   Con la cabecera saturada tenía sentido; sobre el pastel es blanco sobre casi
   blanco. Son pocos y concretos —el botón de colapsar del panel de Score
   (`btn btn-tool text-white`) y cuatro `small.text-white-50` de la venta de
   conceptos— pero desaparecen del todo, así que van por regla y no dejándolos
   al azar. `inherit` los devuelve al tono oscuro de su familia.
   Pesa dos clases más el hijo: le gana a `.text-white` / `.text-white-50`, que
   fuerzan pero pesan una. */
.card-header.bg-info [class*="text-white"],    .card-header.bg-info .btn-tool,
.card-header.bg-primary [class*="text-white"], .card-header.bg-primary .btn-tool,
.card-header.bg-success [class*="text-white"], .card-header.bg-success .btn-tool,
.card-header.bg-warning [class*="text-white"], .card-header.bg-warning .btn-tool,
.card-header.bg-danger [class*="text-white"],  .card-header.bg-danger .btn-tool,
.card-header.bg-dark [class*="text-white"],    .card-header.bg-dark .btn-tool,
.card-header.bg-secondary [class*="text-white"], .card-header.bg-secondary .btn-tool,
.card-header.bg-blue [class*="text-white"],    .card-header.bg-blue .btn-tool,
.card-header[class*="bg-gradient-"] [class*="text-white"],
.card-header[class*="bg-gradient-"] .btn-tool { color: inherit !important; opacity: .75; }

/* --- Cards de color SÓLIDO (`card card-primary`, `card-info`, …) ---------
   Son 26 en el producto, y AdminLTE les pinta la cabecera entera del color de
   la clase. Acá pasan al patrón del GESTOR: cabecera BLANCA con el título
   oscuro, y la identidad de color se muda a una línea de acento de 3px arriba
   más el ícono del título. Es el mismo criterio que ya se aplicó a las
   cabeceras de ficha con `card-mod-*`, extendido a las que no la tienen.

   ⚠ EL `!important` DE LA LÍNEA DE ACENTO NO ES CAPRICHO, y conviene entender
   por qué: más arriba en este archivo está `.card { border: none !important }`.
   Es un atajo (`border`, no `border-top`) y con `!important`, así que le gana a
   cualquier `border-top` posterior por más específico que sea. El GESTOR borró
   esa regla justamente por esto —allá los cuatro colores de módulo estaban
   escritos, cargados, matcheando y sin verse—. Acá se deja donde está y se le
   empata con otro `!important`, que es lo que ya venía haciendo `card-mod-*`.

   `:not(.card-outline)` en todos: las outline son las de ficha y las de
   gráfico, que ya tienen su propio tratamiento y no se tocan. */
.card.card-primary:not(.card-outline)   { border-top: 3px solid #6366f1 !important; }
.card.card-info:not(.card-outline)      { border-top: 3px solid #06b6d4 !important; }
.card.card-success:not(.card-outline)   { border-top: 3px solid #10b981 !important; }
.card.card-danger:not(.card-outline)    { border-top: 3px solid #ef4444 !important; }
.card.card-warning:not(.card-outline)   { border-top: 3px solid #f59e0b !important; }
.card.card-secondary:not(.card-outline) { border-top: 3px solid #64748b !important; }
.card.card-dark:not(.card-outline)      { border-top: 3px solid #334155 !important; }
/* El fondo se queda con `!important` porque una card de color sólido puede
   traer además una utility `bg-*` en su propia cabecera —el markup lo hace en
   varios lugares— y esas fuerzan de fábrica. */
.card.card-primary:not(.card-outline) > .card-header,
.card.card-info:not(.card-outline) > .card-header,
.card.card-success:not(.card-outline) > .card-header,
.card.card-danger:not(.card-outline) > .card-header,
.card.card-warning:not(.card-outline) > .card-header,
.card.card-secondary:not(.card-outline) > .card-header,
.card.card-dark:not(.card-outline) > .card-header {
    background: #fff !important;
    color: #334155 !important;
    border-bottom: 1px solid rgba(0,0,0,.06) !important;
    border-radius: 12px 12px 0 0 !important;
    font-weight: 600;
}
.card.card-primary:not(.card-outline) > .card-header .card-title,
.card.card-info:not(.card-outline) > .card-header .card-title,
.card.card-success:not(.card-outline) > .card-header .card-title,
.card.card-danger:not(.card-outline) > .card-header .card-title,
.card.card-warning:not(.card-outline) > .card-header .card-title,
.card.card-secondary:not(.card-outline) > .card-header .card-title,
.card.card-dark:not(.card-outline) > .card-header .card-title { color: #334155 !important; font-weight: 600; }
.card.card-primary:not(.card-outline) > .card-header .card-title i   { color: #6366f1 !important; }
.card.card-info:not(.card-outline) > .card-header .card-title i      { color: #06b6d4 !important; }
.card.card-success:not(.card-outline) > .card-header .card-title i   { color: #10b981 !important; }
.card.card-danger:not(.card-outline) > .card-header .card-title i    { color: #ef4444 !important; }
.card.card-warning:not(.card-outline) > .card-header .card-title i   { color: #f59e0b !important; }
.card.card-secondary:not(.card-outline) > .card-header .card-title i { color: #64748b !important; }
.card.card-dark:not(.card-outline) > .card-header .card-title i      { color: #334155 !important; }
/* Los botones de herramienta del header quedaban blancos sobre blanco. */
.card.card-primary:not(.card-outline) > .card-header .btn-tool,
.card.card-info:not(.card-outline) > .card-header .btn-tool,
.card.card-success:not(.card-outline) > .card-header .btn-tool,
.card.card-danger:not(.card-outline) > .card-header .btn-tool,
.card.card-warning:not(.card-outline) > .card-header .btn-tool,
.card.card-secondary:not(.card-outline) > .card-header .btn-tool,
.card.card-dark:not(.card-outline) > .card-header .btn-tool { color: #94a3b8 !important; }

/* --- La CARD ENTERA pintada (`card bg-primary`, `card bg-gradient-info`) ---
   Quedan pocas, pero son las más pesadas de todas: no es la cabecera sino el
   panel completo en color saturado. Mismo tratamiento pastel, y la cifra y el
   título heredan el tono oscuro para que se sigan leyendo.

   `:not([class*="card-"])` deja afuera a las que además tienen una clase de
   familia (`card-outline`, `card-mod-*`, `home-kpi`…), que ya tienen su propio
   tratamiento más arriba. */
.card.bg-primary:not([class*="card-"]),   .card.bg-gradient-primary   { background: linear-gradient(160deg,#eef2ff,#e0e7ff) !important; color:#3730a3 !important; border:1px solid #e0e7ff !important; }
.card.bg-info:not([class*="card-"]),      .card.bg-gradient-info      { background: linear-gradient(160deg,#ecfeff,#cffafe) !important; color:#155e75 !important; border:1px solid #cffafe !important; }
.card.bg-success:not([class*="card-"]),   .card.bg-gradient-success   { background: linear-gradient(160deg,#ecfdf5,#d1fae5) !important; color:#065f46 !important; border:1px solid #d1fae5 !important; }
.card.bg-danger:not([class*="card-"]),    .card.bg-gradient-danger    { background: linear-gradient(160deg,#fef2f2,#fee2e2) !important; color:#991b1b !important; border:1px solid #fee2e2 !important; }
.card.bg-warning:not([class*="card-"]),   .card.bg-gradient-warning   { background: linear-gradient(160deg,#fffbeb,#fef3c7) !important; color:#92400e !important; border:1px solid #fef3c7 !important; }
.card.bg-secondary:not([class*="card-"]), .card.bg-gradient-secondary { background: linear-gradient(160deg,#f8fafc,#f1f5f9) !important; color:#334155 !important; border:1px solid #e2e8f0 !important; }
.card.bg-dark:not([class*="card-"]),      .card.bg-gradient-dark      { background: linear-gradient(160deg,#f1f5f9,#e2e8f0) !important; color:#1e293b !important; border:1px solid #e2e8f0 !important; }
.card[class*="bg-"] .card-body h1, .card[class*="bg-"] .card-body h4 { color: inherit; }
.card[class*="bg-"] .card-body .text-muted { color: inherit !important; opacity: .65; }

/* --- Tabla / GridView --- */
.table { border-collapse: separate !important; border-spacing: 0 !important; }
.table thead th {
    background: #f1f5f9 !important; color: #334155 !important;
    font-size: .85em !important; font-weight: 700 !important;
    text-transform: uppercase !important; letter-spacing: .04em !important;
    border-bottom: 2px solid #e2e8f0 !important; border-top: none !important;
    padding: .55rem .85rem !important; white-space: nowrap;
}
.table tbody tr { transition: background .1s; }
.table tbody tr:hover > td { background: #f0f7ff !important; }
.table tbody td {
    vertical-align: middle !important; border-top: 1px solid #f1f5f9 !important;
    color: #374151; font-size: .9em;
}
.table tbody td:not(.p-0):not(.p-1):not(.p-2) { padding: .5rem .85rem !important; }
.table-striped tbody tr:nth-of-type(odd) { background-color: #fafbfc !important; }

/* =============================================================
   GRILLAS — criterio de diseño portado del GESTOR
   =============================================================
   Modernizar una grilla es dar AIRE y JERARQUÍA, no sacar elementos.
   Lo que hace el trabajo es el espacio, el peso tipográfico y las celdas
   de dos líneas; si igual parece cargada, el problema es CUÁNTAS columnas
   tiene, no las rayas.

   POR QUÉ ESTE ARCHIVO Y NO `Includes/scss/_my-gridview.scss`:
   el .scss es la fuente correcta a futuro, pero compila al bundle
   `Includes/css/theme.css` (543 KB) con Web Compiler, y regenerarlo con
   otro compilador de sass reescribe el archivo entero. `ispboss.css` es
   CSS plano, se sirve suelto DESPUÉS del bundle y ya existe para esto
   mismo ("MODERNIZACIÓN UI"), así que no hay paso de build.
   ⚠ Y OJO: `CHRS.Framework.AppManager\Includes\scss\_my-gridview.scss`
   es una copia DIVERGENTE y MUERTA — la ruta que la servía
   (`EmbeddedResourceRouteHandler`) está comentada entera en
   `RoutesConfig.vb`. Editarla no cambia nada en ninguna pantalla.
   ============================================================= */

/* --- GLOBAL: cifras alineadas para poder compararlas de un vistazo ---
   Toda columna declarada align="right" es plata o cantidad. Con las cifras
   tabulares las comas caen en la misma vertical y dos importes se comparan
   sin leerlos. No cambia el markup de ninguna pantalla. */
.my-gridview table > thead > tr > th[align="right"],
.my-gridview table > tbody > tr > td[align="right"],
.my-gridview table > tfoot > tr > td[align="right"] {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

/* --- OPT-IN: `my-gridview-limpia` — sin líneas verticales ---
   La `CssClass` de la pantalla va al DIV de afuera: `GridView.vb` guarda lo
   que pida el markup (`Dim css = CssClass`) ANTES de pisar CssClass con
   "table table-bordered". O sea que la clase llega acá tal cual.

   ⚠ `TableBordered="false"` NO saca las líneas verticales, aunque el nombre
   lo prometa: en `GridView.vb` la clase `table-bordered` está HARDCODEADA en
   el Render y `TableBordered` sólo decide el borde EXTERIOR del contenedor
   (`my-gridview-bordered`). Las verticales las dibuja el `border-left` de
   `_my-gridview.scss`, y es eso lo que apaga esta clase. */
.my-gridview.my-gridview-limpia .table-bordered > thead > tr > th,
.my-gridview.my-gridview-limpia .table-bordered > tbody > tr > th,
.my-gridview.my-gridview-limpia .table-bordered > tfoot > tr > th,
.my-gridview.my-gridview-limpia .table-bordered > thead > tr > td,
.my-gridview.my-gridview-limpia .table-bordered > tbody > tr > td,
.my-gridview.my-gridview-limpia .table-bordered > tfoot > tr > td {
    border-left: none !important;
}

/* --- OPT-IN: `my-gridview-densa` — para documentos y plata ---
   Densa vs cómoda es por lo que la grilla HACE, no por gusto: en un listado
   de entidades vas a buscar UNA y el aire ayuda; en un historial de
   comprobantes estás comparando MUCHAS y cada píxel de alto es una fila
   menos. Necesita !important y especificidad porque le compite el
   `.table tbody td:not(.p-0)...` de más arriba, que ya trae !important. */
.my-gridview.my-gridview-densa table > tbody > tr > td:not(.p-0):not(.p-1):not(.p-2) {
    padding: .35rem .6rem !important;
}
.my-gridview.my-gridview-densa table > thead > tr > th {
    padding: .4rem .6rem !important;
}

/* --- La celda de identidad: nombre arriba, referencia abajo ---
   Concentra las tres cosas que identifican a una persona y con eso libera
   DOS columnas (el código y la razón social dejan de ser columnas propias).
   El link va en el NOMBRE, que es lo que uno estaba leyendo igual, y no en
   un número de tres dígitos.

   El `max-width` NO es decorativo: la del abonado es la única columna de
   ancho variable de estas grillas y con `ItemStyle-Wrap="false"` un nombre
   largo estira la tabla y manda la pantalla al costado. */
.ispboss-celda { display: block; min-width: 0; }
.ispboss-celda-nombre {
    display: block;
    font-weight: 600;
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* En una grilla de DOCUMENTOS el sujeto de la fila es el documento, no la
   persona: el nombre se apaga a peso normal y tamaño secundario, y se
   distingue del subtítulo por COLOR, no por cuerpo. */
.ispboss-celda-secundaria .ispboss-celda-nombre { font-weight: 400; font-size: .9em; }
/* El link en el color del cuerpo y no en el azul de Bootstrap: con el azul
   era lo único de color de la fila —diez manchas azules apiladas— y le
   ganaba al sujeto. El subrayado aparece al pasar el mouse. */
.ispboss-celda-nombre > a { color: inherit; text-decoration: none; }
.ispboss-celda-nombre > a:hover,
.ispboss-celda-nombre > a:focus { color: inherit; text-decoration: underline; }
.ispboss-celda-sub {
    display: block;
    font-size: .8em;
    color: #64748b;
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.5;
}
/* El segundo renglón de una celda cualquiera (el período debajo del código,
   el atraso debajo del vencimiento). Mismo peso que el subtítulo: es un dato
   secundario, no un dato chico. */
.ispboss-celda-linea2 { display: block; font-size: .8em; color: #64748b; line-height: 1.5; }

/* --- El código del comprobante ---
   El tipo y el punto de venta ya están ADENTRO del código
   (`FB 00007-00123456`), así que no van como columnas propias.
   Apagar a la persona no alcanza si el documento no pesa: el número va en
   semibold. */
.ispboss-codigo { font-weight: 600; white-space: nowrap; }
/* Lo que RESTA —nota de crédito, anticipo— va en ámbar y no en rojo: no es
   un error, es algo que hay que NOTAR. El rojo se reserva para la plata que
   alguien debe. */
.ispboss-codigo-resta { color: #92400e; }

/* --- Importes y saldo ---
   positivo → ROJO    hay plata pendiente
   cero     → NEUTRO  saldada; NO es una buena noticia que merezca verde
   negativo → ÁMBAR   saldo a favor: casi siempre un pago de más o una NC sin
                      aplicar, o sea algo que alguien tiene que mirar.
   ⚠ El ámbar del negativo NO se apaga nunca: un saldo a favor no lo dice
   ninguna otra columna —la pastilla de estado lo cuenta como "Pagada"—. */
.ispboss-importe { font-weight: 600; white-space: nowrap; }
.ispboss-saldo-cero     { color: #94a3b8; font-weight: 600; }
.ispboss-saldo-deuda    { font-weight: 700; }
.ispboss-saldo-favor    { color: #92400e; font-weight: 700; }
/* Diez "$ 0,00" apilados hay que leerlos para descartarlos; una raya se
   descarta sola. */
.ispboss-nada { color: #cbd5e1; }

/* --- Fila de la grilla: que las dos líneas no la estiren de más --- */
.my-gridview table > tbody > tr > td .ispboss-celda-sub,
.my-gridview table > tbody > tr > td .ispboss-celda-linea2 { margin-top: 1px; }

/* --- Badges --- */
/*
   ESCALA DE REDONDEO — la del GESTOR, convertida a pixeles.

   Allá es `--bs-border-radius-sm: 0.45rem` / `--bs-border-radius: 0.6rem` /
   `-lg: 0.75rem` / `-xl: 0.9rem`. ⚠ Esos `rem` NO se pueden copiar tal cual: el `:root` del
   GESTOR queda en los 16px del navegador y el de ISPBoss está en 14px, así que un `0.6rem`
   escrito acá daría 8,4px en vez de los 9,6px que se ven allá. Va el pixel, igual que en el
   bloque de KPIs de más abajo y por la misma razón.

     0.45rem → 7.2px    badges, chips, botones de grupo, inputs chicos
     0.6rem  → 9.6px    inputs, combos, botones
     0.75rem → 12px     cards y dropdowns  (ya estaban en 12px, no se tocaron)
     0.9rem  → 14.4px   overlays tipo modal

   Lo que NO entra en la escala y se deja como está: círculos (50%), píldoras (999px / 20px),
   scrollbars, y los componentes propios de ISPBoss que en el GESTOR no existen —el sidebar de
   AdminLTE, sobre todo—, donde "como el GESTOR" no define ningún valor.
*/
/* El tamaño va en `rem`, como el GESTOR (`--bs-badge-font-size: .8rem` = 10,4px sobre 13).
   Estaba en `.72em` y un `em` se achica con lo que lo rodea: dentro del `<small>` de la
   última actualización daba 7,5px y en celdas anidadas de grilla 6,7px. */
.badge {
    border-radius: 7.2px !important; font-weight: 500 !important; font-size: .8rem !important;
    letter-spacing: .02em; padding: .28em .6em !important;
    /* Centrado del contenido, como el GESTOR. Sin esto un badge más alto que su texto
       —los que llevan ícono— deja la letra pegada al borde de arriba. */
    display: inline-flex; align-items: center; justify-content: center;
    line-height: 1; vertical-align: middle;
}
/* Dentro de una grilla, fijo y más chico que afuera. Las `.8rem` del GESTOR, aplicadas a las
   grillas de acá, alargaban un 11% Órdenes de servicio y Tickets (hasta ~23 pastillas por fila,
   una densidad que el GESTOR no tiene) y sumaban 234px de ancho a Abonados. En 8,45px quedan
   con la densidad de siempre y todas del mismo tamaño: con `em` las de segunda línea caían a 6,7px. */
td .badge { font-size: .65rem !important; }
.badge.badge-success, .badge.bg-success, .badge.bg-green  { background: rgba(34,197,94,.13)  !important; color: #15803d !important; }
.badge.badge-danger,  .badge.bg-danger,  .badge.bg-red    { background: rgba(239,68,68,.11)   !important; color: #b91c1c !important; }
.badge.badge-warning, .badge.bg-warning                   { background: rgba(245,158,11,.13)  !important; color: #92400e !important; }
.badge.badge-info,    .badge.bg-info                      { background: rgba(59,130,246,.12)  !important; color: #1d4ed8 !important; }
.badge.badge-primary, .badge.bg-primary                   { background: rgba(99,102,241,.12)  !important; color: #4338ca !important; }
.badge.badge-secondary,.badge.bg-secondary                 { background: rgba(100,116,139,.11) !important; color: #475569 !important; }
/* badge en div: mantener inline-block */
div.badge { display: inline-block !important; }

/* --- Badge de color arbitrario (portado del GESTOR) ---
   Para los códigos de grilla cuyo color NO sale de la paleta semántica sino de una
   tabla del ISP —depósitos, por ejemplo—. El color va por `--c` desde el markup:

       <span class="badge badge-suave" style="--c: RGB(196,234,22)">Deposito VMM</span>

   El `color-mix` reproduce el mismo tratamiento suave de los badges semánticos —13% de
   tinte sobre blanco, texto al 72% mezclado con pizarra— pero para cualquier color, sin
   tener que escribir una regla por cada fila de la tabla. Y resuelve el problema real de
   estas paletas: son colores elegidos por el operador, muchos clarísimos (amarillos,
   verdes flúor), que como texto o como relleno pleno no se leen; mezclados contra
   #1e293b sí.

   El bloque de arriba NO es un fallback decorativo: es el que corre en cualquier motor
   sin `color-mix`, y deja un gris legible en vez de un badge sin fondo.

   ⚠ OJO CON LOS COLORES CLAROS — MEDIDO, NO ESTIMADO (27/08/2026).
   La fórmula asume un color con algo de saturación y de oscuridad. Sobre los 23 colores
   cargados hoy en `WebDepositos`, que los eligió el operador, da:

       13 de 23 por debajo de 4,5:1 (mínimo AA)
        9 de 23 por debajo de 3:1
       peor caso: rgb(247,248,248) → 1,85:1   (un color casi blanco)
                  RGB(247,251,47)  → 1,92:1   (amarillo flúor)

   O sea que un badge con uno de esos colores NO SE LEE. No es un defecto del port —el
   GESTOR usa esta misma fórmula— sino de la paleta: un color casi blanco no puede ser a
   la vez fondo tintado y texto. Antes de usar `badge-suave` sobre una tabla cargada por
   el operador, o se limpia la paleta, o hay que meterle un piso de contraste. */
.badge.badge-suave {
    --c: #64748b;
    background: rgba(100,116,139,.11) !important;
    color: #475569 !important;
    /* !important porque `.badge` de más arriba fija font-weight 500 con !important, y sin
       esto la especificidad mayor de `.badge.badge-suave` igual perdía. */
    font-weight: 600 !important;
}
@supports (background: color-mix(in srgb, red 13%, white)) {
    .badge.badge-suave {
        background: color-mix(in srgb, var(--c) 13%, #fff) !important;
        color: color-mix(in srgb, var(--c) 72%, #1e293b) !important;
    }
}

/* --- Badges dentro de un card-header de color: LA EXCEPCIÓN SE RETIRA ---
   Acá vivía una regla que pasaba esos badges a PASTILLA BLANCA SÓLIDA con
   sombra. Existía por una razón buena: el estilo "soft" de arriba —fondo
   tintado translúcido y texto oscuro— está pensado para fondos blancos, y
   sobre el azul o el pizarra plenos de las cabeceras viejas ese translúcido se
   perdía y el texto oscuro no se leía.

   Se retira el 27/08/2026, junto con el pase de las cabeceras a pastel: ya no
   hay ninguna cabecera saturada contra la que defenderse. Y la regla dejó de
   ser inofensiva para volverse el problema — una pastilla BLANCA sobre una
   cabecera blanca o pastel desaparece, y lo único que la dibujaba era su
   sombra.

   No se reemplaza por nada: sin esta excepción los badges vuelven solos al
   estilo "soft" de las líneas de arriba, que es exactamente el que corresponde
   sobre un fondo claro. El color semántico (verde / rojo / ámbar) se conserva
   igual, ahora en el fondo tintado y en el texto.

   Si alguna vez vuelve una cabecera de color pleno, esta regla vuelve con
   ella; mientras tanto sobra. */

/* --- Botones --- */
.btn { border-radius: 9.6px !important; font-size: .82em !important; font-weight: 500; transition: all .15s !important; letter-spacing: .01em; }
.btn-primary  { background: #2563eb !important; border-color: #2563eb !important; }
.btn-primary:hover  { background: #1d4ed8 !important; border-color: #1d4ed8 !important; }
.btn-secondary { background: #64748b !important; border-color: #64748b !important; color: #fff !important; }
.btn-secondary:hover { background: #475569 !important; border-color: #475569 !important; color: #fff !important; }
.btn-info     { background: #0ea5e9 !important; border-color: #0ea5e9 !important; color: #fff !important; }
.btn-info:hover     { background: #0284c7 !important; border-color: #0284c7 !important; }
.btn-success  { background: #16a34a !important; border-color: #16a34a !important; }
.btn-success:hover  { background: #15803d !important; border-color: #15803d !important; }
.btn-danger   { background: #dc2626 !important; border-color: #dc2626 !important; }
.btn-danger:hover   { background: #b91c1c !important; border-color: #b91c1c !important; }
.btn-warning  { background: #d97706 !important; border-color: #d97706 !important; color: #fff !important; }
.btn-warning:hover  { background: #b45309 !important; border-color: #b45309 !important; }

/* =============================================================
   CABECERA DE PANTALLA CON ACCIONES  (control `cc:PageHeaderBar`)
   =============================================================
   Los botones de Guardar / Volver / Eliminar estaban en un
   `<div class="col-md-auto">` a la derecha del formulario, apilados en
   vertical con `btn-block btn-app` —o sea con el ícono ARRIBA del texto y la
   letra a 1.2rem—. Esa columna se lleva ancho en las 90 pantallas de edición
   del sistema, y el formulario, que es lo que la persona mira, se angosta
   para pagarla. La cabecera, mientras tanto, es una fila casi vacía.

   Acá los botones pasan a la cabecera, en HORIZONTAL, sólo ícono con el
   texto en el tooltip y en `btn-outline-*`. El ancho vuelve al formulario.
   ============================================================= */
/* El ancla del slug de la pantalla (scrollspy del menú lateral). Va como div
   vacío y no como id del <section>, porque el <section> ES el control y ya
   lleva su propio id: ver la nota en `PageHeaderBar.vb`. No ocupa nada. */
.my-page-headerbar .my-page-anchor { height: 0; overflow: hidden; }
.my-page-headerbar .my-page-headerbar-row { margin-left: 0; margin-right: 0; }
.my-page-headerbar .my-page-headerbar-title { padding-left: 0; }
.my-page-headerbar h1 { font-size: 1.5rem; line-height: 1.4; }
.my-page-headerbar h1 > i { color: #94a3b8; margin-right: .35rem; font-size: .9em; }
.my-page-headerbar h1 > small { color: #64748b; font-size: .62em; margin-left: .4rem; }

/* LA BARRA, COMO LA DEL GESTOR (14/09/2026). Medido contra demo.gestor.ar con
   getComputedStyle sobre `.sm-page-headerbar`: allá la fila del título es una
   barra BLANCA con sombra abajo, que se queda pegada bajo el navbar al
   scrollear; el ícono del título va en el índigo de resaltado y el subtítulo
   en mayúsculas chicas. Acá era gris `#f8f9fa`, sin sombra y sin sticky, con
   el ícono en slate, y por eso las dos cabeceras se veían distintas aunque
   el markup fuera el mismo.
   top = alto del navbar fijo + su borde de 1px, el mismo calc que usa
   .ispboss-navbar. Si el navbar cambia de alto, esto se corre con él.
   ⚠ Debajo de 992px el top va en 0 (bloque "Mobile: prevenir overflow
   horizontal global"): ahí el contenedor del sticky ya arranca bajo el navbar.
   Las proporciones (título 1rem, botones .8em, barra de 3.5rem) salen de
   medir el GESTOR con la misma base de fuente: allá el título es 1.05em
   y el botón .82em sobre 13px. */
.my-page-headerbar {
    background: #fff !important;
    border-bottom: 1px solid #dee2e6;
    box-shadow: 0 2px 5px rgba(0,0,0,.1);
    position: sticky;
    top: calc(3.2rem + 1px);   /* = alto del navbar, ver .ispboss-navbar */
    z-index: 1020;
    min-height: 3.8rem;        /* 49,4px sobre base 13: lo que mide el GESTOR */
    padding: .25rem 1rem !important;
    margin-bottom: .75rem;
    /* La fila mide ~26px y la barra 49,4: sin esto la fila se pega arriba y
       todo el sobrante queda abajo (título y botones 3,2px sobre el centro). */
    display: flex;
    flex-direction: column;
    justify-content: center;
}
/* ⚠ EL PADDING DE ARRIBA NO SE APLICABA (16/09/2026). La barra también lleva
   `content-header`, y `.content-header { padding: 8px 15px 4px !important }`
   (bloque "Content header", más abajo) tiene el mismo peso y gana por orden:
   quedaban 8px arriba y 4px abajo. Acá se sube la especificidad en vez de
   tocar aquella regla, que es la de las 18 pantallas con el `uc:PageHeader`
   viejo. Sólo el vertical: el horizontal de 15px es el que se ve hoy y
   moverlo corre el título respecto del contenido. */
.content-header.my-page-headerbar {
    padding-top: .25rem !important;
    padding-bottom: .25rem !important;
}

/* ⚠ MIENTRAS HAY UN MODAL ABIERTO, LA BARRA DEJA DE SER CONTEXTO DE APILADO.
   Sin esto, TODO modal que viva adentro de la barra se abre GRISADO Y MUERTO:
   se ve, pero el fondo oscuro de Bootstrap le queda ENCIMA y se come cada click.
   Medido en Abonados\Default.aspx el 18/09/2026: apuntando al centro del cuadro y
   al botón Generar, el que recibía el click era `.modal-backdrop`.

   El modal vale `z-index: 1050` y el fondo `1040`, así que la cuenta parece a
   favor del modal — pero esos números sólo compiten ADENTRO de la barra. El fondo
   cuelga del <body>, y ahí lo que compite es la barra entera, que vale 1020.

   Aparecio al mudar los botones al `cc:PageHeaderBar`: `BotonReportes.ascx` trae el
   boton Y el modal en el mismo control, asi que el modal se mudo con el boton y
   quedo adentro de la barra. Le pasa a todos los que viven ahi (reportes, filtros),
   no solo al de reportes; los que cuelgan fuera —ucComunicacion— nunca fallaron.

   VAN LAS DOS DECLARACIONES, y probar con una sola no alcanza (lo probé):
     · `position: sticky` crea contexto de apilado SIEMPRE, tenga z-index o no;
     · el `z-index: 1020` cuenta IGUAL con la posición estática, porque el <div>
       del UpdatePanel que contiene a la barra es `display: grid` y la barra es un
       ítem de grilla — y un ítem de grilla con z-index propio también crea contexto.

   No se pierde el sticky: con un modal abierto el body queda en `overflow: hidden`
   y la página no scrollea, así que no hay nada de lo que despegarse. */
body.modal-open .my-page-headerbar {
    position: static;
    z-index: auto;
}
.my-page-headerbar h1 > i { color: #6366f1; }
.my-page-headerbar h1 > small {
    text-transform: uppercase;
    font-size: .6em;
    letter-spacing: .02em;
    color: #94a3b8;
}

/* El ícono grande de la cabecera de una FICHA (el `far fa-edit fa-2x` al lado
   del nombre del registro), en el mismo índigo. Es el `.sm-icono-resaltado`
   del GESTOR con el prefijo de la casa. Va con la cadena entera del selector
   porque más abajo `.card.card-outline[class*="card-mod-"] > .card-header i`
   pinta TODO ícono de esas cabeceras en slate con !important, y a eso sólo
   se le gana con más especificidad. */
.ispboss-icono-resaltado,
.card.card-outline[class*="card-mod-"] > .card-header i.ispboss-icono-resaltado { color: #6366f1 !important; }

/* La derecha: primero el breadcrumb, después los botones.
   Los botones van en el EXTREMO y no al revés — son el ancla que la persona
   busca, y un ancla tiene que caer siempre en el mismo píxel, sin importar
   cuánto mida el breadcrumb de esa pantalla. */
.my-page-headerbar .my-page-headerbar-right {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: .25rem .75rem;
    padding-right: 0;
    min-width: 0;
}
.my-page-headerbar .my-page-breadcrumb {
    margin: 0;
    padding: 0;
    background: transparent;
    font-size: .82rem;
}

/* El slot de acciones. `flex-wrap` no es decorativo: `btnReactivar`,
   `btnEliminar` y `btnComunicarIndividual` nacen con Visible="false" y los
   prende el codebehind, así que la cantidad de botones cambia en vivo y los
   que quedan tienen que reacomodarse solos. */
.my-page-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .35rem;
}
/* Sólo ícono: el texto vive en el ToolTip. Cuadrado, para que ocho botones
   sigan siendo una fila legible y no un párrafo de palabras. */
.my-page-actions .btn {
    min-width: 2.25rem;
    padding: .35rem .6rem !important;
    font-size: .82em !important;    /* era .9em; el GESTOR va en .82em */
}
.my-page-actions .btn > i { font-size: .95rem; line-height: 1.35; }
/* Anula el `btn-block` y el `btn-app` por si una pantalla migrada se los
   deja puestos: adentro del slot mandan el flex y el ícono en línea. */
.my-page-actions .btn.btn-block { display: inline-flex !important; width: auto !important; }
.my-page-actions .btn.btn-app { font-size: .82em !important; white-space: nowrap; }
.my-page-actions .btn.btn-app > i { display: inline !important; }

/* ⚠ El margen manual lo pone el MARKUP de cada pantalla: los botones vienen
   con `ml-2` y alguno con `ml-3`, heredados de cuando vivían apilados en la
   columna de la derecha. Sumado al `gap` del flex daba un espaciado DESPAREJO
   —el Eliminar separado del resto— que es lo que se veía desprolijo. Acá manda
   el gap y nada más; así no hay que tocar el markup de las 77 pantallas. */
.my-page-actions .btn[class*="ml-"],
.my-page-actions .btn[class*="mr-"] { margin-left: 0 !important; margin-right: 0 !important; }

/* El ORDEN de la fila, tomado del GESTOR. El markup de cada pantalla declara los
   botones al revés (Guardar primero) y reordenarlo a mano son 98 archivos, así
   que el orden se impone acá con `order` de flex.
   ⚠ Esto separa el orden VISUAL del orden del DOM, así que el foco por teclado
   sigue el markup. Es el precio de no tocar 98 pantallas; si algún día se
   reordena el markup, este bloque se borra y no cambia nada.

   ⚠⚠ ORDENAR SÓLO POR COLOR NO ALCANZA, y así salió mal la primera vez: el botón
   IMPRIMIR también es `-secondary`, igual que el Volver. Al empatar en `order`
   mandaba el orden del DOM y el Imprimir terminaba A LA DERECHA del Volver.
   El "salir" se ancla por ID —`btnCancelar` está en 94 pantallas y `btnVolver`
   en 1—, que es mucho más confiable que el color.
   Orden pedido por Pablo (27/08/2026), leído de la barra del GESTOR:
   imprimir · teléfono · eliminar · GUARDAR · SALIR (siempre el último). */
.my-page-actions .btn { order: 1; }                              /* imprimir, exportar, archivo, sync */
.my-page-actions .btn[class*="-warning"] { order: 2; }           /* autorizar, reactivar, cumplir */
.my-page-actions .btn[class*="-info"] { order: 3; }              /* comunicar (el teléfono) */
.my-page-actions .btn[class*="-danger"] { order: 4; }            /* eliminar */
.my-page-actions .btn[class*="-success"] { order: 5; }           /* GUARDAR: la primaria */
.my-page-actions .btn[id$="btnCancelar"],
.my-page-actions .btn[id$="btnVolver"] { order: 6; }             /* SALIR: SIEMPRE el último */

/* La primaria lleva TEXTO, como en el GESTOR: un botón de sólo ícono no puede
   ser el ancla de la pantalla. El texto sale del `ToolTip` que la pantalla ya
   declara, así que no hay nada que duplicar ni traducir.
   ⚠ Pero NO se lee de `title`: Bootstrap, al inicializar el tooltip, VACÍA el
   `title` y se lleva el texto a `data-original-title` (para que el navegador no
   dibuje su propio globito encima del suyo). Medido en vivo: `title=""` y
   `data-original-title="Guardar"`. Por eso van las dos reglas — la de
   `data-original-title` para cuando el tooltip ya se inicializó, y la de `title`
   para el instante previo y para los botones sin tooltip. */
.my-page-actions .btn[class*="-success"][title]:not([title=""])::after {
    content: " " attr(title);
    font-weight: 600;
    margin-left: .1rem;
}
.my-page-actions .btn[class*="-success"][data-original-title]:not([data-original-title=""])::after {
    content: " " attr(data-original-title);
    font-weight: 600;
    margin-left: .1rem;
}

/* En pantallas chicas el breadcrumb se va y los botones se quedan: el
   breadcrumb es orientación, los botones son la tarea. */
@media (max-width: 767.98px) {
    .my-page-headerbar .my-page-breadcrumb { display: none; }
    .my-page-headerbar .my-page-headerbar-title { padding-right: .5rem; }
}

/* --- Inputs --- */
.form-control, .custom-select {
    border-radius: 9.6px !important; border-color: #e2e8f0 !important;
    transition: border-color .15s, box-shadow .15s !important;
}
.form-control:focus, .custom-select:focus {
    border-color: #2563eb !important; box-shadow: 0 0 0 3px rgba(37,99,235,.12) !important;
}
/* Input-group: alinear alturas y border-radius */
.input-group .form-control,
.input-group .custom-select { font-size: inherit !important; }
.input-group > .form-control:not(:last-child),
.input-group > .custom-select:not(:last-child) { border-radius: 9.6px 0 0 9.6px !important; }
.input-group > .input-group-append > .btn { border-radius: 0 9.6px 9.6px 0 !important; }
.input-group > .input-group-append > .btn,
.input-group > .form-control { height: auto !important; min-height: calc(1.5em + .75rem + 2px); }

/* --- Group header row (grillas anidadas) --- */
.ispboss-grid-group-header {
    padding: 6px 12px !important;
    background: #f1f5f9 !important;
    border-bottom: 1px solid #e2e8f0 !important;
    font-size: .82rem;
    line-height: 1.5;
    overflow: hidden; /* clearfix for float-right children */
}
.ispboss-grid-group-header .text-muted { color: #64748b !important; }
/* Forzar la tabla interna (nested grid) a ocupar todo el ancho del td */
td.p-0 > table,
td.p-0 > .gridview-wrapper > table,
td.p-0 > div > table { width: 100% !important; }
/* El td que contiene el grupo puede expandirse libremente */
.table > tbody > tr > td.p-0 { width: auto !important; }

/* --- Empty state en grilla --- */
.table > thead + tbody tr:only-child td[colspan],
.table > thead ~ tbody tr:only-child td[colspan] {
    text-align: center; padding: 2.5rem 1rem !important; color: #94a3b8; font-size: .88em;
}

/* --- Sidebar de filtros --- */
.sidebar-panel-sidebar {
    overflow-y: auto !important; max-height: calc(100vh - 120px) !important;
    position: sticky !important; top: 10px !important;
}

/* --- Select2 --- */
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    border: 1.5px solid #e2e8f0 !important; border-radius: 9.6px !important;
    min-height: calc(1.5em + .65rem + 2px) !important;
    background: #fff !important; transition: border-color .15s, box-shadow .15s !important;
}
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--single,
.select2-container--default.select2-container--open .select2-selection--multiple {
    border-color: #2563eb !important; box-shadow: 0 0 0 3px rgba(37,99,235,.12) !important; outline: none !important;
}
.select2-container--default .select2-selection--single .select2-selection__rendered,
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
    color: #374151 !important; font-size: .84em !important; padding: 0 1.4rem 0 .75rem !important; line-height: 1.5 !important;
}
.select2-container--default .select2-selection--single .select2-selection__placeholder,
.select2-container--default .select2-selection--multiple .select2-selection__placeholder { color: #94a3b8 !important; }
/* Un combo deshabilitado tiene que verse deshabilitado. El "background: #fff !important"
   de arriba pisaba el gris que theme.css define para .select2-container--disabled, asi que
   ningun cc:DropDownList con Enabled=False se distinguia de uno habilitado. */
.select2-container--default.select2-container--disabled .select2-selection--single,
.select2-container--default.select2-container--disabled .select2-selection--multiple {
    background: #e9ecef !important; border-color: #dee2e6 !important; cursor: not-allowed !important;
}
.select2-dropdown {
    border: 1.5px solid #e2e8f0 !important; border-radius: 12px !important;
    box-shadow: 0 4px 20px rgba(0,0,0,.1) !important; overflow: hidden !important; margin-top: 3px !important;
}
.select2-container--default .select2-search--dropdown .select2-search__field {
    border: 1.5px solid #e2e8f0 !important; border-radius: 7.2px !important;
    padding: 5px 10px !important; font-size: .82em !important; outline: none !important;
}
.select2-container--default .select2-search--dropdown .select2-search__field:focus {
    border-color: #2563eb !important; box-shadow: 0 0 0 3px rgba(37,99,235,.1) !important;
}
.select2-results__option {
    font-size: .83em !important; padding: .42rem .75rem !important;
    color: #374151 !important; border-radius: 0 !important; transition: background .1s !important;
}
.select2-container--default .select2-results__option--highlighted[aria-selected] { background: #eff6ff !important; color: #1d4ed8 !important; }
.select2-container--default .select2-results__option[aria-selected=true] { background: #dbeafe !important; color: #1d4ed8 !important; }
.select2-container--default .select2-selection--multiple .select2-selection__choice {
    background: #eff6ff !important; border: 1px solid #bfdbfe !important; border-radius: 7.2px !important;
    color: #1d4ed8 !important; font-size: .82em !important; padding: 3px 8px !important; margin: 3px 3px 0 0 !important;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove { color: #93c5fd !important; margin-right: 4px !important; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { color: #1d4ed8 !important; }

/* ===== AbonadoFicha — tira lateral colapsada ===== */
.ficha-col-strip {
    flex: 0 0 60px !important; max-width: 60px !important; min-width: 0 !important;
    padding: 0 !important; position: relative;
    background: linear-gradient(180deg, #eef2ff 0%, #f0f7ff 60%, #f8faff 100%);
    border-radius: 0 0 0 12px;
    box-shadow: inset -1px 0 0 #c7d7f5, 2px 0 12px rgba(99,102,241,.08);
}
.ficha-col-strip .abonado-ficha-card { background: transparent !important; border: none !important; box-shadow: none !important; margin: 0 !important; }
.ficha-col-strip .abonado-ficha-card .card-header {
    padding: 10px 0 6px 0 !important; background: transparent !important;
    border: none !important; display: flex !important; justify-content: center !important;
}
.ficha-col-strip .abonado-ficha-toggle-btn,
.ficha-col-strip .abonado-ficha-card .card-header .col,
.ficha-col-strip .abonado-ficha-card .stretched-link { display: none !important; }
.ficha-col-strip .abonado-ficha-body { display: none !important; }
/* Otras cards hermanas de la ficha (ej. "Ordenes del abonado en los ultimos 30 dias")
   no deben verse en la tira lateral colapsada de 60px */
.ficha-col-strip > .card:not(.abonado-ficha-card) { display: none !important; }
.ficha-col-strip .abonado-ficha-avatar-wrapper {
    cursor: pointer; display: inline-flex !important;
    flex-direction: column; align-items: center;
}
.ficha-col-strip .abonado-ficha-avatar-wrapper:hover .abonado-avatar {
    transform: scale(1.06); box-shadow: 0 4px 16px rgba(0,0,0,.22);
}
.ficha-col-strip .abonado-ficha-expand-badge { opacity: 1 !important; }
.ficha-strip-actions { display: none; flex-direction: column; align-items: center; padding: 10px 0 8px 0; gap: 7px; }
.ficha-col-strip .ficha-strip-actions { display: flex !important; }
.ficha-strip-btn {
    width: 36px; height: 36px; border-radius: 50%;
    border: 1.5px solid #e2e8f0; background: #ffffff;
    display: flex !important; align-items: center; justify-content: center;
    color: #64748b; font-size: 13px; text-decoration: none !important;
    transition: background .15s, border-color .15s, color .15s, transform .15s;
    position: relative; z-index: 3; box-shadow: 0 1px 3px rgba(0,0,0,.08);
}
.ficha-strip-btn:hover {
    background: #eff6ff; border-color: #2563eb; color: #2563eb;
    transform: scale(1.12); box-shadow: 0 3px 8px rgba(37,99,235,.2); text-decoration: none !important;
}
.ficha-strip-btn + .tooltip { margin-left: 4px; }

/* ===== AbonadoFicha — avatar con iniciales ===== */
.abonado-avatar {
    width: 48px; height: 48px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-weight: 700; font-size: 1.1rem;
    user-select: none; flex-shrink: 0; transition: transform .2s, box-shadow .2s;
}
.abonado-ficha-expand-badge {
    position: absolute; bottom: -3px; right: -3px;
    width: 20px; height: 20px; background: #fff; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 2px 5px rgba(0,0,0,.18); font-size: 9px; color: #374151;
    opacity: 0; transition: opacity .2s; pointer-events: none;
}
.ficha-collapsed .abonado-ficha-expand-badge { opacity: 1; }
.abonado-ficha-header-nombre { position: relative; }
.abonado-nombre-link-cover { position: absolute; inset: 0; z-index: 1; display: block !important; }
.abonado-ficha-header-nombre span { position: relative; z-index: 2; pointer-events: none; }
.abonado-nombre-link-cover { cursor: pointer; }
.abonado-nombre-link-cover:hover ~ span,
.abonado-ficha-header-nombre:hover span { text-decoration: underline; color: #ffffff !important; }
.abonado-nombre-link { color: inherit !important; text-decoration: none !important; }
.abonado-nombre-link:hover { text-decoration: underline !important; color: inherit !important; }
.ficha-strip-nav {
    width: 30px; height: 30px; border-radius: 8px; border: 1.5px dashed #b4c6ef;
    background: transparent; display: flex !important; align-items: center; justify-content: center;
    color: #94a3b8; font-size: 11px; text-decoration: none !important;
    transition: background .15s, border-color .15s, color .15s;
    position: relative; z-index: 3; margin-top: 2px;
}
.ficha-strip-nav:hover { background: #eff6ff; border-color: #6366f1; border-style: solid; color: #6366f1 !important; text-decoration: none !important; }
.ficha-strip-sep { width: 32px; height: 1px; background: linear-gradient(to right, transparent, #c7d7f5, transparent); margin: 2px 0; }

/* ===== AbonadoFicha — header moderno ===== */
.abonado-ficha-card { border: none !important; box-shadow: 0 2px 12px rgba(0,0,0,.1) !important; border-radius: 12px !important; overflow: hidden; }
/* Cabecera GRIS (23/09/2026; antes azul-índigo con degradé): el gris del hover de los
   btn-outline-secondary (#6c757d, el "secondary" de Bootstrap). Se probó pintarla con el color del
   estado y se descartó. El color vive en una variable porque lo usa también la versión de celular
   (más abajo, "3b."). */
:root { --ficha-header-bg: #6c757d; }
.abonado-ficha-card > .abonado-ficha-header,
.abonado-ficha-card .abonado-ficha-header {
    background: var(--ficha-header-bg) !important;
    border-bottom: none !important; padding: 14px 14px 12px 14px !important;
    box-shadow: 0 1px 3px rgba(0,0,0,.12);
}
/* Nombre del abonado: más grande y con el espaciado de título (23/09/2026). Hasta dos renglones
   antes de cortar con "…", para que un apellido compuesto no quede mutilado a 1366. */
.abonado-ficha-header-nombre {
    font-size: 1.05rem; font-weight: 700; letter-spacing: -.015em; color: #ffffff; line-height: 1.25;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.abonado-ficha-header-nombre .abonado-nombre-link,
.abonado-ficha-header-nombre .abonado-nombre-link span { color: #ffffff !important; text-decoration: none !important; }
.abonado-ficha-header-nombre .abonado-nombre-link:hover,
.abonado-ficha-header-nombre .abonado-nombre-link:hover span { color: #ffffff !important; text-decoration: underline !important; }
.abonado-ficha-header-domicilio { font-size: .72rem; color: #ffffff; opacity: .85; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.abonado-ficha-header-domicilio i { font-size: .65rem; opacity: .7; }

/* Estado: primera fila de la lista. La pastilla la arma GrillaHelper.Chip (suave, con el color
   de Tablas), igual que Zona, Localidad, Categoría y el resto de la ficha: esto es sólo el
   contenedor, sin fondo propio. */
.abonado-ficha-estado { display: inline-block; }

/* Los DATOS de la lista (lo de la derecha) con la letra y el color de los rótulos (Inter 13px,
   #212529), un punto más firmes (500) sin llegar a negrita. Las pastillas (estado, deuda,
   comprobantes) tienen la suya. */
.abonado-ficha-card .list-group-item.d-flex:not(.abonado-ficha-comp) > :last-child:not(.abonado-ficha-pastillas):not(.abonado-ficha-estado),
.abonado-ficha-fecha { font-size: 13px; font-weight: 500; color: #212529; }
.abonado-ficha-fecha { margin-left: 2px; }

/* Facturas pendientes de pago: cuántas y cuánto, en una pastilla con los MISMOS pastel que la
   de Última factura: rojo si hay deuda (el de impaga), verde si no hay (el de paga). */
.abonado-ficha-pastillas { display: inline-flex; align-items: center; gap: 4px; }
.abonado-ficha-card .abonado-ficha-deuda {
    display: inline-block; padding: .15rem .55rem; border-radius: 999px; border: 1px solid transparent;
    font-size: .76rem; font-weight: 600; line-height: 1.3;
}
.abonado-ficha-card .abonado-ficha-deuda-si { background: #fef2f2; border-color: #fee2e2; color: #b91c1c; }
.abonado-ficha-card .abonado-ficha-deuda-no { background: #f0fdf4; border-color: #dcfce7; color: #15803d; }
/* La cantidad de facturas, en su propia pastilla y un punto más firme que la del importe. */
.abonado-ficha-card .abonado-ficha-deuda-cantidad {
    min-width: 1.6rem; text-align: center; padding: .15rem .45rem;
    background: #fee2e2; border-color: #fecaca; color: #991b1b;
}

/* Último pago / última factura en UNA línea: rótulo a la izquierda, fecha y comprobante a la
   derecha. Si no entra (columna angosta), la pastilla baja sola: por eso el flex-wrap.
   El recibo en gris pastel; la factura también en pastel: verde (paga), amarillo (parcial) o
   rojo (impaga). */
.abonado-ficha-comp-dato { display: inline-flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: 6px; margin-left: auto; }
.abonado-ficha-comp-badge {
    display: inline-block; padding: .15rem .45rem; border-radius: 6px; border: 1px solid transparent;
    font-size: .68rem; font-weight: 600; white-space: nowrap;
}
.abonado-ficha-comp-recibo  { background: #f1f3f5; border-color: #e5e7eb; color: #495057; }
.abonado-ficha-comp-paga    { background: #f0fdf4; border-color: #dcfce7; color: #15803d; }
.abonado-ficha-comp-parcial { background: #fefce8; border-color: #fef3c7; color: #a16207; }
.abonado-ficha-comp-impaga  { background: #fef2f2; border-color: #fee2e2; color: #b91c1c; }

/* Botonera "Generar para este abonado" (OS / TKT / FC / REC / FIN). Cada botón abre el ALTA con el
   abonado cargado. Botones sueltos con aire entre ellos (no el btn-group pegado de Bootstrap), el
   ícono más chico que el fa-2x del markup, un "+" arriba a la derecha que dice que generan algo, y
   un hover en gris pastel en vez del gris oscuro relleno de btn-outline-secondary. */
.abonado-ficha-accesos-titulo { font-size: .72rem; color: #6c757d; margin: 0 0 6px 2px; }
.abonado-ficha-card .btn-group.btn-block { display: flex; gap: 6px; }
.abonado-ficha-card .btn-group.btn-block > .btn {
    flex: 1 1 0; margin-left: 0 !important; border-radius: 8px !important;
}
.abonado-ficha-accesos > .btn {
    position: relative; padding: .4rem .2rem .35rem; font-size: .72rem; line-height: 1.2;
    color: #495057; border-color: #dee2e6;
}
.abonado-ficha-accesos > .btn .fa-2x { font-size: 1.15rem; margin-bottom: 2px; }
.abonado-ficha-accesos > .btn::after {
    content: "+"; position: absolute; top: 2px; right: 6px;
    font-size: .8rem; font-weight: 700; line-height: 1; color: #adb5bd;
}
.abonado-ficha-accesos > .btn:hover,
.abonado-ficha-accesos > .btn:focus { background: #f1f3f5; border-color: #adb5bd; color: #212529; box-shadow: none; }
.abonado-ficha-accesos > .btn:hover::after { color: #495057; }

/* Ver geolocalización: ícono de mapa al lado del domicilio, en la cabecera. La línea pasa a flex
   para que, con una dirección larga, se corte el TEXTO con "…" y el ícono quede siempre visible. */
.abonado-ficha-header-domicilio { display: flex; align-items: center; }
.abonado-ficha-domicilio-texto { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.abonado-ficha-geo { display: inline-flex; flex-shrink: 0; }
.abonado-ficha-header .abonado-ficha-geo-btn {
    padding: 0 0 0 6px; border: 0; vertical-align: baseline; line-height: 1;
    font-size: .8rem; color: #ffffff !important; opacity: .85; position: relative; z-index: 3;
}
.abonado-ficha-header .abonado-ficha-geo-btn:hover { opacity: 1; text-decoration: none; }
.abonado-ficha-header .abonado-ficha-toggle-btn { color: #ffffff !important; opacity: .85; transition: opacity .15s; }
.abonado-ficha-header .abonado-ficha-toggle-btn:hover { color: #ffffff !important; opacity: 1; }
/* Sin el círculo de iniciales con la ficha abierta (23/09/2026). En la tira plegada sigue: ahí es
   lo único que se ve y el botón para desplegarla. */
.abonado-ficha-avatar-col { display: none !important; }
.ficha-col-strip .abonado-ficha-avatar-col { display: block !important; margin-right: 0 !important; }
.ficha-col-strip .abonado-ficha-header { padding: 10px 0 6px 0 !important; }

/* ===================================================================
   ispboss — Navbar moderno
   =================================================================== */
.ispboss-navbar {
    background: #ffffff !important;
    box-shadow: 0 2px 8px rgba(0,0,0,.06) !important;
    /* ALTO = el que AdminLTE reserva para el contenido cuando <html> lleva
       text-sm: .text-sm .layout-navbar-fixed ... ~ .content-wrapper { margin-top:
       calc(3.2rem + 1px) } (theme.css ~8972). Estaba en 54px, o sea 8px mas alto
       que ese margen: el contenido nacia tapado por el navbar. Y es la altura del
       GESTOR (45,5px medidos el 14/09/2026). El avatar de 32px + los 6px de padding
       de .ispboss-navbar-user entran justo. */
    min-height: calc(3.2rem + 1px);
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}
.ispboss-navbar-avatar {
    width: 32px; height: 32px; border-radius: 50%;
    background: linear-gradient(135deg, #1e40af 0%, #4f46e5 100%);
    color: #fff; font-size: .7rem; font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0; letter-spacing: .03em;
}
.ispboss-navbar-avatar-lg { width: 46px; height: 46px; font-size: 1rem; }
.ispboss-navbar-user { display: flex !important; align-items: center; gap: 8px; padding: 4px 10px !important; /* 4px: sobre base 13 el navbar mide 42,6 y el avatar 32 */ border-radius: 8px; transition: background .15s; }
.ispboss-navbar-user:hover { background: #f1f5f9; }
.ispboss-navbar-username { font-size: .8rem; font-weight: 500; color: #374151; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ispboss-user-dropdown { min-width: 230px !important; border: 1px solid #e2e8f0 !important; border-radius: 12px !important; box-shadow: 0 8px 24px rgba(0,0,0,.12) !important; padding: 0 !important; overflow: hidden; }
.ispboss-dropdown-user-header { display: flex; align-items: center; gap: 10px; padding: 14px 16px; background: #f8fafc; border-bottom: 1px solid #f1f5f9; }
.ispboss-user-dropdown .dropdown-item { padding: 9px 16px; font-size: .85rem; color: #374151; transition: background .12s; }
.ispboss-user-dropdown .dropdown-item:hover { background: #f1f5f9; color: #111827; }
.ispboss-navbar-empresa-logo { max-height: 28px; max-width: 100px; opacity: .65; object-fit: contain; }

/* ===================================================================
   ispboss — Sidebar moderno
   =================================================================== */
.ispboss-sidebar { background: #0f172a !important; }
.ispboss-sidebar .sidebar { background: transparent !important; overflow-x: hidden; }
/* ALTO FIJO = el margen con que AdminLTE baja el menu. Con navbar fijo el logo es
   position:fixed y el .sidebar arranca en calc(3.2rem + 1px) (theme.css ~8883) =
   42,6px sobre base 13. Estaba en min-height 54px + borde: tapaba los primeros
   12px del menu, y se veia cuando el primer item tenia fondo (FAVORITOS abierto,
   la pastilla cortada arriba). Es tambien el alto del navbar: las dos lineas de
   abajo quedan alineadas.
   El !important del alto: con el menu ANGOSTO AdminLTE le pone height:auto
   (.layout-navbar-fixed.sidebar-collapse .wrapper .brand-link, mas especifica) y
   el logo se encogia a 20px, dejando un hueco oscuro arriba del menu. */
.ispboss-brand-link { background: #0f172a !important; border-bottom: 1px solid #1e293b !important; padding: 0 16px !important; display: flex !important; align-items: center; height: calc(3.2rem + 1px) !important; box-sizing: border-box; }
.ispboss-brand-link:hover { background: #1e293b !important; }
/* Brand mini (colapsado) */
.ispboss-logo-mini {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    width: 100%; gap: 4px;
}
.ispboss-mini-icon { font-size: 1.2rem; color: #818cf8; line-height: 1; }
.ispboss-mini-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: #6366f1;
    animation: ispboss-dot-pulse 2.4s ease-in-out infinite;
    box-shadow: 0 0 6px rgba(99,102,241,.8);
}
@keyframes ispboss-dot-pulse {
    0%, 100% { opacity: .4; transform: scale(.8); box-shadow: 0 0 4px rgba(99,102,241,.4); }
    50%       { opacity: 1;  transform: scale(1.2); box-shadow: 0 0 10px rgba(99,102,241,.9), 0 0 20px rgba(99,102,241,.4); }
}

/* Brand full (expandido) */
.ispboss-logo-full { display: flex; align-items: center; justify-content: center; width: 100%; }
.ispboss-brand-block {
    display: flex; flex-direction: row;
    align-items: baseline; justify-content: center;
    gap: 7px; width: 100%;
}
.ispboss-brand-name {
    font-size: 1.35rem; font-weight: 800; color: #f1f5f9;
    letter-spacing: .5px; line-height: 1;
    text-shadow: 0 0 20px rgba(129,140,248,.3);
    white-space: nowrap;
}
.ispboss-brand-ai {
    display: flex; align-items: center; gap: 0;
    font-size: .9rem; font-weight: 600;
    color: #818cf8; letter-spacing: .06em;
    line-height: 1; white-space: nowrap; padding-bottom: 1px;
}
.ispboss-ai-text { color: #818cf8; }
.ispboss-ai-cursor {
    color: #6366f1; font-weight: 300; margin-left: 1px;
    animation: ispboss-blink .85s step-end infinite;
}
@keyframes ispboss-blink {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0; }
}


/* Nav items */
/* Legibilidad: el texto de los módulos ya tenía buen contraste sobre el #0f172a
   (11:1), así que se deja como estaba — subirlo más lo vuelve blanco y chillón.
   Lo que costaba leer eran los elementos SECUNDARIOS, que estaban muy hundidos
   contra el fondo: íconos (3,3:1), submenús (6,3:1) y títulos de sección (1,5:1,
   prácticamente invisibles). Ahí se gana legibilidad sin aclarar el conjunto.
   El cuerpo sube de 13,2px a 14px, PERO sin tocar color ni peso: lo que hacía
   ver el menú "lavado" era la combinación de tamaño + seminegrita + texto casi
   blanco, no el tamaño solo. */
.ispboss-sidebar .nav-sidebar > .nav-item { margin: 1px 8px; }
.ispboss-sidebar .nav-sidebar .nav-link { color: #cbd5e1 !important; border-radius: 8px !important; padding: 7px 12px !important; font-size: .875rem; line-height: 1.45; transition: background .15s, color .15s; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ispboss-sidebar .nav-sidebar .nav-link:hover { background: #1e293b !important; color: #e2e8f0 !important; }
.ispboss-sidebar .nav-sidebar .nav-link.active,
.ispboss-sidebar .nav-sidebar .nav-item.menu-open > .nav-link { background: linear-gradient(135deg, #1e40af 0%, #3730a3 100%) !important; color: #ffffff !important; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
.ispboss-sidebar .nav-sidebar .nav-link .nav-icon { color: #8b9bb4 !important; transition: color .15s; width: 1.2rem; font-size: .9rem; }
.ispboss-sidebar .nav-sidebar .nav-link:hover .nav-icon,
.ispboss-sidebar .nav-sidebar .nav-link.active .nav-icon { color: #818cf8 !important; }
.ispboss-sidebar .nav-sidebar .nav-link p .right,
.ispboss-sidebar .nav-sidebar .nav-link p .float-right { color: #7c8ea6 !important; transition: transform .2s; }
.ispboss-sidebar .nav-treeview > .nav-item > .nav-link { padding-left: 1.25rem !important; padding-right: 8px !important; font-size: .84rem; color: #b6c2d2 !important; }
.ispboss-sidebar .nav-treeview > .nav-item > .nav-link:hover { background: #1e293b !important; color: #e2e8f0 !important; }
.ispboss-sidebar .nav-treeview > .nav-item > .nav-link.active { background: #1e3a5f !important; color: #93c5fd !important; box-shadow: none; }
/* Badges en el menú del sidebar */
.ispboss-sidebar .nav-sidebar .badge,
.ispboss-sidebar .nav-sidebar .right.badge {
    background: rgba(99,102,241,.18) !important;
    color: #e0e7ff !important;
    border: 1px solid rgba(99,102,241,.45) !important;
    font-size: .68rem !important;
    font-weight: 700 !important;
    padding: .2em .55em !important;
    border-radius: 20px !important;
    letter-spacing: .02em;
    min-width: 1.6em;
    text-align: center;
}
.ispboss-sidebar .nav-sidebar .nav-link.active .badge,
.ispboss-sidebar .nav-sidebar .nav-item.menu-open > .nav-link .badge {
    background: rgba(255,255,255,.22) !important;
    color: #fff !important;
    border-color: rgba(255,255,255,.4) !important;
}

/* Estaba en #334155: sobre el fondo del sidebar daba 1,5:1, no se leía nada. */
.ispboss-sidebar .nav-header { color: #7c8ea6 !important; font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; padding: 10px 20px 4px; }

/* DIVISORES dentro de un módulo ("Cajas y cuentas", "Configuración"...).
   Alinean con el padding-left de 2.2rem de las pantallas hermanas, para que se lean
   como el rótulo del bloque y no como un ítem más. El primero no lleva margen arriba:
   pegado al título del módulo quedaba un hueco que parecía un corte.
   El tamaño NO se pisa: hereda los .68rem de la regla de arriba, que es el de todas
   las cabeceras del sidebar. Con .62rem daban 8,7px contra los 11,8px de las
   pantallas y se leían como letra chica, no como rótulo. */
/* =============================================================================
   PALETA DEL PANEL DEL GESTOR, tal cual
   =============================================================================
   Los valores salen de SofMic.Framework.Admin\scss\_sm-menu.scss, no de mi
   criterio. Se copian los de ul.sm-rail-list y sus estados.

     ítem            #94a3b8   .95rem
     ícono           #475569   .75rem   ancho 1.2rem
     divisor         #22d3ee   .66rem   700   MAYÚSCULAS   letter-spacing .07em
     hover           fondo #334155   texto #e2e8f0   ícono #818cf8
     activo          fondo #1e3a5f   texto #93c5fd   ícono #93c5fd
     destacada       ícono #34d399
     favorito        #fbbf24

   El divisor en CIAN y no en índigo: es el color que el gestor le puso, y además
   deja el índigo libre para el hover del ícono, que es otra señal.
   ============================================================================= */
/* LA SANGRÍA DEL SUBMENÚ, ACHICADA.
   Se sumaban tres capas: 8px de margen del <li>, 16px que AdminLTE le mete al
   .nav-treeview por la clase nav-child-indent, y 35px de padding del ítem. Medido:
   el nombre arrancaba en el pixel 90 de un sidebar de 250 — 36% del ancho gastado
   en margen, y por eso los nombres largos no entraban.
   Queda la sangría suficiente para distinguir una pantalla de su módulo, y nada más. */
.ispboss-sidebar .nav-sidebar.nav-child-indent .nav-treeview { padding-left: 8px; }

.ispboss-sidebar .nav-treeview .nav-header {
    padding: .7rem 12px .2rem 1.25rem;
    margin-top: 2px;
    color: #22d3ee !important;
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ispboss-sidebar .nav-treeview .nav-header:first-child { margin-top: 0; padding-top: .2rem; }

.ispboss-sidebar .nav-treeview > .nav-item > .nav-link { color: #94a3b8 !important; }
.ispboss-sidebar .nav-treeview > .nav-item > .nav-link .nav-icon {
    color: #475569 !important;
    font-size: .75rem;
    width: 1.2rem;
    text-align: center;
}

/* PANTALLA PRINCIPAL DEL MÓDULO: la que se usa todos los días. Se le enciende el
   ícono para encontrarla sin leer la lista. Cuáles son lo decide CargarMenu, por
   ruta, con el parámetro Menu.PantallasDestacadas para pisarlo por cliente.

   VERDE Y NO ÁMBAR: el ámbar ya es la estrella de favoritos, y son dos cosas
   distintas — el favorito lo elige el operador, la principal la define el producto.
   Dos señales del mismo color se leen como una sola y dejan de decir nada.

   VA ANTES del :hover y del .active a propósito: las tres reglas empatan en
   especificidad, así que decide el orden. Puesta acá, el hover y la marca de la
   pantalla abierta le ganan, que es lo correcto — el estado de ahora importa más
   que una etiqueta permanente. */
.ispboss-sidebar .nav-treeview > .nav-item > .nav-link.ispboss-destacada .nav-icon { color: #34d399 !important; }

.ispboss-sidebar .nav-treeview > .nav-item > .nav-link:hover { background: #334155 !important; color: #e2e8f0 !important; }
.ispboss-sidebar .nav-treeview > .nav-item > .nav-link:hover .nav-icon { color: #818cf8 !important; }
.ispboss-sidebar .nav-treeview > .nav-item > .nav-link.active { background: #1e3a5f !important; color: #93c5fd !important; box-shadow: none; }
.ispboss-sidebar .nav-treeview > .nav-item > .nav-link.active .nav-icon { color: #93c5fd !important; }

/* Los clones ya viven dentro de un .nav-treeview, así que toman el estilo de
   cualquier otra pantalla del menú sin necesidad de reglas propias. Antes colgaban
   del primer nivel y había que replicarles a mano el padding, el tamaño y el ícono
   de un ítem de submenú: eso es lo que se veía desalineado. */

/* FAVORITOS DEL MENÚ
   ---------------------------------------------------------------------------
   La estrella vive DENTRO del <a>, posicionada absoluta contra él: metida en el
   flujo empujaba el texto y los nombres largos ("Aprovisionamiento Conexiones")
   se cortaban con puntos suspensivos aunque hubiera lugar.
   Aparece al pasar el mouse por el ítem, o siempre si ya está marcada — una
   estrella marcada que se esconde no le dice al operador que ese ítem es suyo. */
.ispboss-sidebar .nav-sidebar .nav-link { position: relative; }
.ispboss-sidebar .ispboss-fav-star {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    background: none; border: 0; padding: 2px 5px; line-height: 1;
    color: #64748b; font-size: .72rem; cursor: pointer; opacity: 0;
    transition: opacity .12s ease, color .12s ease;
}
.ispboss-sidebar .nav-link:hover .ispboss-fav-star,
.ispboss-sidebar .ispboss-fav-star:focus,
.ispboss-sidebar .ispboss-fav-star.activa { opacity: 1; }
.ispboss-sidebar .ispboss-fav-star:hover { color: #fbbf24; }
.ispboss-sidebar .ispboss-fav-star.activa { color: #f59e0b; }
/* El badge de contadores ocupa el mismo rincón derecho: si conviven, la estrella
   le queda encima. Con badge, la estrella se corre a su izquierda. */
.ispboss-sidebar .nav-link:has(.badge) .ispboss-fav-star { right: 2.4rem; }

/* La lista clonada arriba del menú. Mismo sangrado que las pantallas de un
   módulo abierto, para que se lea como un bloque más y no como otra cosa. */
.ispboss-sidebar .ispboss-fav-header { color: #f59e0b !important; }
.ispboss-sidebar .ispboss-fav-header i { margin-right: 6px; font-size: .7rem; }

/* FAVORITOS y RECIENTES son MÓDULOS del menú, con su flecha y su desplegable.
   No son un rótulo con ítems sueltos abajo, y el motivo no es estético:

     * AdminLTE esconde TODOS los .nav-header al colapsar el sidebar
       (theme.css: .sidebar-collapse .nav-sidebar .nav-header). Medido a 74px:
       display:none. Los favoritos quedaban arriba de todo sin nada que dijera qué
       eran. Un módulo, en cambio, muestra su ícono.
     * Los ítems colgaban del primer nivel y tomaban el estilo de un módulo: íconos
       de otro tamaño y sin alinear con el texto. Adentro del .nav-treeview toman el
       mismo estilo que cualquier otra pantalla del menú, y por eso se ven parejos.

   El ícono del módulo lleva su color propio: es la única señal que queda cuando el
   menú está angosto y no hay texto. */
.ispboss-sidebar .ispboss-bloque-fav > .nav-link .nav-icon { color: #f59e0b !important; }
.ispboss-sidebar .ispboss-bloque-rec > .nav-link .nav-icon { color: #22d3ee !important; }
.ispboss-sidebar .ispboss-bloque > .nav-link > p { font-size: .78rem; letter-spacing: .06em; }

/* Una línea al final del bloque, para que se lea como un grupo aparte y no como el
   principio del menú. Sobrevive al colapso, que es cuando más falta hace. */
.ispboss-sidebar .ispboss-bloque { border-bottom: 1px solid #1e293b; padding-bottom: 4px; margin-bottom: 4px !important; }

/* Los clones se desbordaban del sidebar: medido, 322px de ancho adentro de 250. El
   <ul> del menú es flex y sus <li> no se encogen por debajo de su contenido, así que
   el nombre largo empujaba el ítem afuera y quedaba cortado contra el borde. */
.ispboss-sidebar .ispboss-bloque,
.ispboss-sidebar .ispboss-fav-item,
.ispboss-sidebar .ispboss-rec-item { min-width: 0; max-width: 100%; }
.ispboss-sidebar .ispboss-bloque .nav-link { max-width: 100%; overflow: hidden; }
.ispboss-sidebar .ispboss-bloque .nav-link > p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* EL vertical-align NO ES ADORNO. El <p> del menú es inline-block, y a un inline-block
   con overflow distinto de visible el navegador le cambia la línea base: deja de
   alinearse por el texto y pasa a hacerlo por su borde inferior. O sea que el
   overflow:hidden de la regla de arriba —el que hace posible el ellipsis— desalinea
   el ícono del nombre como efecto colateral.
   Medido: el menú normal alinea con 0,5px de diferencia y estos bloques daban 4,9px,
   que es lo que se ve como el ícono flotando más arriba que el texto.
   Con middle los dos se centran contra el mismo eje y la diferencia desaparece. */
.ispboss-sidebar .ispboss-bloque .nav-link > p,
.ispboss-sidebar .ispboss-bloque .nav-link > .nav-icon { vertical-align: middle; }

/* EL MENÚ ANGOSTO ABIERTO CON EL MOUSE: los ítems salían SIN TEXTO, sólo el ícono.
   Se veía en FAVORITOS y RECIENTES, y sólo ahí.

   AdminLTE, al colapsar el sidebar, le pone `width: 0` al <p> de cada ítem
   (theme.css: `.sidebar-mini.sidebar-collapse .nav-sidebar .nav-link p`). Cuando el
   sidebar se abre por hover, la regla de más abajo le devuelve `display`, `opacity` y
   `visibility`... pero NO el ancho: el <p> se queda en 0.

   Los ítems del menú normal igual se leen de casualidad: su <p> tiene overflow
   visible, así que el texto desborda ese ancho 0 y se pinta igual. Los bloques
   clonados NO, porque llevan `overflow: hidden` para el ellipsis (ver arriba) — y
   ancho 0 + overflow hidden es texto recortado a nada.

   Medido con el sidebar colapsado y abierto por hover: de los 162 <p> del menú los
   únicos con ancho 0 y overflow oculto eran los del bloque (su cabecera y sus clones).
   Con `width: auto` ese <p> mide 96px y se lee. Aplica SÓLO colapsado + abierto, así
   que el menú fijo no se toca; y va sobre todos los ítems, no sólo los del bloque,
   para que mañana cualquier otro que necesite ellipsis no repita el mismo agujero. */
.sidebar-mini.sidebar-collapse .main-sidebar:hover .nav-sidebar .nav-link > p,
.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .nav-sidebar .nav-link > p { width: auto; }

/* Los divisores de sección ("Conceptos", "Valores", "Detalles"...) los esconde AdminLTE
   al colapsar —tienen sentido: en 74px no entra un rótulo— pero después no los repone
   al abrir por hover. Resultado: el mismo módulo se ve con rótulos si el menú está fijo
   y sin rótulos si lo abriste con el mouse. Son 24 en el menú completo. */
.sidebar-mini.sidebar-collapse .main-sidebar:hover .nav-sidebar .nav-header,
.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .nav-sidebar .nav-header { display: block; }

.ispboss-sidebar .ispboss-fav-item > .nav-link { padding-left: 1.25rem !important; font-size: .84rem; color: #b6c2d2 !important; }
.ispboss-sidebar .ispboss-fav-item > .nav-link:hover { background: #1e293b !important; color: #e2e8f0 !important; }
.ispboss-sidebar .ispboss-fav-item > .nav-link.active { background: #1e3a5f !important; color: #93c5fd !important; box-shadow: none; }
.ispboss-sidebar .sidebar::-webkit-scrollbar { width: 4px; }
.ispboss-sidebar .sidebar::-webkit-scrollbar-track { background: transparent; }
.ispboss-sidebar .sidebar::-webkit-scrollbar-thumb { background: #1e293b; border-radius: 4px; }
.ispboss-sidebar-empresa { padding: 10px 12px; border-top: 1px solid #1e293b; display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; }
.ispboss-sidebar-empresa-logo { max-height: 22px; max-width: 60px; opacity: .35; object-fit: contain; display: block; }
.ispboss-sidebar-empresa-logo-xl { max-height: 22px; max-width: 110px; opacity: .35; object-fit: contain; display: none; }
body:not(.sidebar-mini) .ispboss-sidebar-empresa-logo { display: none; }
body:not(.sidebar-mini) .ispboss-sidebar-empresa-logo-xl { display: block; }

/* =============================================================
   CABECERAS DE SECCION: se va el gris pizarra pleno
   =============================================================
   27/08/2026, a pedido de Pablo. Las secciones internas ("Conceptos",
   "Valores", "Detalles"...) usan `bg-gray` de AdminLTE: una barra GRIS
   PIZARRA PLENA con el texto en blanco. Es el mismo problema que la cabecera
   azul --un bloque saturado que pesa mas que su propio contenido--, solo que
   repetido varias veces por pantalla. El GESTOR no usa esa clase: sus
   secciones son un `card-header` claro con el texto oscuro.

   Se REDEFINE la clase en vez de tocar el markup: son 117 ocurrencias en 51
   archivos, y todas las de seccion comparten el mismo patron
   (`bg-gray px-3 py-2 ...`). Una regla contra 117 ediciones.

   IMPORTANTE: el `:not(.badge)` no es decorativo. De las 117, UNA es
   `class="badge bg-gray"` --una pastilla, donde el gris pleno SI
   corresponde--. Sin la exclusion esa pastilla quedaria con texto claro
   sobre fondo claro. Contadas una por una antes de escribir esto. */
.bg-gray:not(.badge) {
    background-color: #f8fafc !important;
    color: #374151 !important;
    border-bottom: 1px solid rgba(0,0,0,.06) !important;
    font-weight: 600;
    font-size: .88em;
}
/*  El icono venia en blanco porque el fondo era oscuro: sobre claro
    desaparecia. Los botones de accion de la barra (Ingresar, Agregar) NO se
    tocan: son la accion de la seccion, no decoracion. */
.bg-gray:not(.badge) > i,
.bg-gray:not(.badge) > .fas,
.bg-gray:not(.badge) > .far { color: #64748b !important; }

/* =============================================================
   CABECERAS DE FICHA: blancas con una línea de color arriba
   =============================================================
   Portado del GESTOR (27/08/2026), a pedido de Pablo. Acá las fichas usan
   `card card-primary`, que en AdminLTE pinta el header de AZUL PLENO: un bloque
   de color saturado ocupando el ancho, que le gana a todo lo demás de la
   pantalla —incluido el número del comprobante, que es el dato que uno vino a
   leer—. El GESTOR usa `card-outline` + una clase de módulo: header BLANCO y
   una línea de 3px arriba. El color pasa de ser el fondo a ser un acento.

   🔑 EL COLOR ES POR MÓDULO, NO POR ESTADO. En el GESTOR ventas es verde,
   compras azul, cobranzas violeta: te ubica en qué parte del sistema estás,
   y por eso es estable —no cambia con el estado del documento—. Acá se
   respetan los colores del GESTOR en los módulos que existen en los dos
   (cobranzas violeta, ABM cyan) y se eligen los demás sin repetir tono.

   ⚠ El `!important` no es capricho: más arriba en este mismo archivo hay
   `.card.card-outline { border-top: none !important }`, puesto para matar el
   borde que AdminLTE dibuja por defecto. Estas reglas suman una clase más, así
   que ganan por especificidad, pero necesitan el `!important` para empatarle. */
.card.card-outline[class*="card-mod-"] { border-top-width: 3px !important; border-top-style: solid !important; }

.card.card-outline.card-mod-facturacion  { border-top-color: #22c55e !important; } /* verde: es la "ventas" de acá */
.card.card-outline.card-mod-cobranzas    { border-top-color: #a855f7 !important; } /* violeta, igual que el GESTOR */
.card.card-outline.card-mod-abonados     { border-top-color: #ec4899 !important; } /* rosa: son los "clientes" */
.card.card-outline.card-mod-ordenes      { border-top-color: #f97316 !important; } /* naranja: el trabajo en la calle */
.card.card-outline.card-mod-soporte      { border-top-color: #ef4444 !important; } /* rojo suave: tickets e incidencias */
.card.card-outline.card-mod-red          { border-top-color: #0d9488 !important; } /* teal: la planta */
.card.card-outline.card-mod-materiales   { border-top-color: #ffc107 !important; } /* amarillo, como stocks del GESTOR */
.card.card-outline.card-mod-comunicaciones { border-top-color: #3b82f6 !important; } /* azul */
.card.card-outline.card-mod-abm          { border-top-color: #06b6d4 !important; } /* cyan, igual que el GESTOR */

/* El header va BLANCO. Sin esto se lo come la regla de "card neutra" de más
   arriba, que le pone el gris `#f8fafc` a todo header sin clase de fondo. */
.card.card-outline[class*="card-mod-"] > .card-header {
    /*  ⚠ GRIS CLARO, no blanco (27/08, corregido a pedido de Pablo: "no tiene el
        mismo tono grisecito del gestor"). Es el mismo #f8fafc que usan las
        cabeceras de seccion y los campos, asi que toda la cromatica del
        producto queda en un solo gris y el blanco se reserva al CONTENIDO. */
    background: #f8fafc !important;
    color: #1e293b !important;
    border-bottom: 1px solid rgba(0,0,0,.06) !important;
}
/*  El ícono grande y el número heredaban el blanco del fondo azul: sobre blanco
    desaparecían. */
.card.card-outline[class*="card-mod-"] > .card-header i,
.card.card-outline[class*="card-mod-"] > .card-header h3,
.card.card-outline[class*="card-mod-"] > .card-header .h3 { color: #1e293b !important; }
.card.card-outline[class*="card-mod-"] > .card-header .text-muted,
.card.card-outline[class*="card-mod-"] > .card-header small { color: #64748b !important; }

/* El borde de la barra superior. Antes venía de un `style=` inline armado con
   `Empresa.ColorBarra`, una clave que NO EXISTE en AppConfig: la declaración
   quedaba sin color, el navegador la descartaba entera y mandaba el borde por
   defecto de AdminLTE — por eso no coincidía con el del GESTOR. Acá queda
   explícito y con el mismo gris que usa el resto del tema. */
.ispboss-navbar { border-bottom: 1px solid #e2e8f0 !important; }

/* ===== Content header (título de página) ===== */
.content-header {
    padding: 8px 15px 4px !important;
}
.content-header h1,
.content-header .h1 {
    font-size: 1.05rem !important;   /* era 1.1rem; el GESTOR va en 1.05em sobre base 13px */
    font-weight: 700 !important;
    margin-bottom: 0 !important;
    line-height: 1.3 !important;
    color: #1e293b !important;
}
.content-header h1 small,
.content-header .h1 small {
    font-size: .72rem !important;
    color: #94a3b8 !important;
    font-weight: 400 !important;
    margin-left: 6px !important;
}
.content-header .breadcrumb {
    margin-bottom: 0 !important;
    padding: 3px 0 !important;
    background: transparent !important;
    font-size: .75rem !important;
}

/* ── Abonados: tabs nav scrolleable ────────────────────────────── */
/* min-width:0 es clave: sin él el flex-item no puede achicarse por debajo
   de su contenido intrínseco y overflow-x:auto nunca recorta */
/* LA BARRA DE SCROLL SE ESCONDE (15/09/2026, como el GESTOR).
   Estaba pintada a mano: 3px de alto con el thumb en indigo y scrollbar-width: thin. En una
   tira de solapas una barra de scroll se lee como un error -y ademas ALARGA la tira y empuja
   el contenido-. Lo que avisa que hay mas es la flecha del borde, mas abajo.
   Medido en el GESTOR (demo.gestor.ar, ficha de cliente): scrollbar-width: none y la barra
   ocupando 0px de alto. */
.abonado-tabs-nav {
    min-width: 0;
    overflow-x: auto !important;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.abonado-tabs-nav::-webkit-scrollbar { display: none; }
.abonado-tabs-nav .nav-item { flex-shrink: 0; }
.abonado-tabs-nav .nav-link {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: .35em .75em;
    font-size: .78rem;
    white-space: nowrap;
    line-height: 1.2;
}
/* Mobile (< sm): la tira se corre, NO se queda sin rotulos (15/09/2026).
   Antes el nav-link iba a font-size: 0 y abajo de 576px quedaban solo los iconos. Diecisiete
   iconos sin texto no se leen: el usuario tiene que adivinar cual es cual, y los de Comprob.,
   Cta.Cte. y Archivos son parecidos entre si. El GESTOR no hace eso -medido en demo.gestor.ar
   con la ventana angosta: las pastillas conservan icono Y rotulo, y la tira se desliza con el
   dedo-, y lo que avisa que hay mas es la flecha. Aca queda igual: se achica el aire, no el
   texto. */
@media (max-width: 575px) {
    .abonado-tabs-nav .nav-link {
        padding: .45em .6em;
        font-size: .72rem;
    }
    .abonado-tabs-nav .nav-link > span > i { font-size: 15px; }
    .abonado-tabs-nav .nav-link .badge { font-size: .6rem !important; padding: .18em .45em !important; }
}

/* ── LA SEÑAL DE QUE LA TIRA SIGUE PARA EL COSTADO ──────────────── */
/* Port de _sm-tabs.scss del GESTOR (bloque "LA SEÑAL DE QUE LA TIRA SIGUE PARA EL COSTADO").
   Quien las prende es Includes\js\MyNavs.js, que pone y saca .my-nav-mas-izq / .my-nav-mas-der
   midiendo scrollLeft contra scrollWidth. Tiene que ser JS: no hay forma en CSS de preguntar
   si un elemento desborda, y una señal incondicional se veria tambien cuando la tira entra
   entera, que es el caso normal en un escritorio grande.

   Y LA FLECHA SE PUEDE APRETAR, que no es un lujo: con el mouse NO HAY GESTO. En un telefono
   el dedo arrastra, pero en un escritorio una tira con overflow-x solo se mueve con
   shift+rueda o con un trackpad, que nadie descubre solo.

   VAN COMO ::before Y ::after Y NO COMO ELEMENTOS. La tira es lo que scrollea, asi que un hijo
   absoluto se iria corriendo con el contenido; y agregar elementos de verdad significaria que
   el JS los inyecte adentro de un UpdatePanel, que los borra en cada postback parcial. Un
   pseudo con position: sticky se queda pegado al borde del area visible sin tocar el DOM.

   El prefijo .content-wrapper deja afuera al menu lateral, que tambien es un ul.nav-pills. */
.content-wrapper .nav-tabs.my-nav-mas-izq::before,
.content-wrapper .nav-pills.my-nav-mas-izq::before,
.content-wrapper .nav-tabs.my-nav-mas-der::after,
.content-wrapper .nav-pills.my-nav-mas-der::after {
    position: sticky;
    z-index: 2;
    flex: 0 0 auto;
    align-self: stretch;
    width: 2.2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    /* La pieza va de borde a borde: sin esto le queda el padding de la tira arriba y abajo, y
       ahi la sombra ensucia ese padding pero no la pieza, dibujando la silueta de un
       rectangulo blanco. El valor es el padding de la tira (p-2 = .5rem). */
    margin-top: -.5rem;
    margin-bottom: -.5rem;
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: .8rem;
    line-height: 1;
    color: #495057;
    /* El click sobre un pseudo le llega al elemento que lo origina -la tira- y MyNavs.js lo
       atiende ahi, mirando por que lado del ancho cayo. Asi la flecha se puede apretar sin
       existir como elemento. */
    cursor: pointer;
    pointer-events: auto;
}
/* El offset negativo es lo que hace que la flecha llegue al borde de la TIRA y no al del
   contenido, y el margen negativo lo que la monta SOBRE la ultima solapa en vez de sumarle
   ancho: si sumara, "cuanto desborda" cambiaria al prenderse y la señal parpadearia sola. */
.content-wrapper .nav-tabs.my-nav-mas-izq::before,
.content-wrapper .nav-pills.my-nav-mas-izq::before {
    content: "\f053";
    left: -.5rem;
    margin-right: -2.2rem;
    background: #fff;
    box-shadow: 10px 0 14px -4px rgba(255,255,255,.95);
}
.content-wrapper .nav-tabs.my-nav-mas-der::after,
.content-wrapper .nav-pills.my-nav-mas-der::after {
    content: "\f054";
    right: -.5rem;
    margin-left: -2.2rem;
    background: #fff;
    box-shadow: -10px 0 14px -4px rgba(255,255,255,.95);
}

/* ── Abonados: ficha lateral — no colapsar en mobile (< lg) ─────── */
/* El colapso usa localStorage: si quedó colapsada en desktop y se abre
   en mobile, ficha-col-strip pondría la columna en 60px con el card
   transparente y sin body. Reseteamos todo a estado expandido normal.

   RED DE SEGURIDAD, NO CAMINO NORMAL (16/09/2026). Desde que AbonadoFicha.ascx acomoda la
   ficha cuando el ancho cruza el corte, la tira no debería existir nunca por debajo de 992.
   Este bloque queda para el instante entre que cambia el ancho y corre el JS. Y en ese
   instante tiene que dejar LEGIBLE la cabecera: la tira le pone fondo transparente con
   !important (regla de la tira, más arriba) y el nombre es blanco, así que sin el punto 3b
   el nombre quedaba blanco sobre blanco. El corte es 991.98, el de Bootstrap: con 991 había
   una franja de medio píxel donde ni esto ni las columnas se aplicaban. */
@media (max-width: 991.98px) {
    /* 1. Columna: vuelve a ancho completo */
    .ficha-col-strip {
        flex: 0 0 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        padding-left: 15px !important;
        padding-right: 15px !important;
        background: transparent !important;
        box-shadow: none !important;
    }
    /* 2. Card: restaurar apariencia normal */
    .ficha-col-strip .abonado-ficha-card {
        background: #fff !important;
        border: none !important;
        box-shadow: 0 2px 12px rgba(0,0,0,.1) !important;
        margin: 0 0 1rem !important;
    }
    /* 3. Header: restaurar padding y alineación */
    .ficha-col-strip .abonado-ficha-card .card-header,
    .ficha-col-strip .abonado-ficha-header {
        padding: 14px 14px 12px !important;
        justify-content: flex-start !important;
        display: block !important;
    }
    /* 3b. Y su fondo gris, que es lo que hace legible el nombre blanco. */
    .ficha-col-strip .abonado-ficha-card .card-header,
    .ficha-col-strip .abonado-ficha-card .abonado-ficha-header {
        background: var(--ficha-header-bg) !important;
    }
    /* 4. Mostrar body y ocultar elementos de strip */
    .ficha-col-strip .abonado-ficha-body  { display: block !important; }
    .ficha-col-strip .ficha-strip-actions { display: none  !important; }
    /* 5. La tira de 60px no se usa acá, pero el botón de plegar SÍ: ver el bloque de abajo. */
    /* 6. La columna hermana (tabs) también vuelve a full width */
    .ficha-col-strip ~ [class*="col-"] {
        flex: 0 0 100% !important;
        max-width: 100% !important;
    }
}

/* ── Abonados: en pantalla chica la ficha se PLIEGA como acordeón ──── */
/* EL BOTÓN DE PLEGAR NO HACÍA NADA EN EL CELULAR (15/09/2026).
   La ficha es una columna `col-lg-3`, así que por debajo de 992px pasa a ancho completo y se
   planta ARRIBA del contenido con todo el cuerpo desplegado -estado, scoring, zona, localidad,
   unidad de negocio, categoría, IVA, fechas, atributos y los cinco accesos rápidos-, o sea más
   de una pantalla de celular antes de llegar a las solapas.

   Y plegarla no servía: `fichaToggle` marca la columna con `ficha-col-strip` para pasar a la
   tira de 60px del escritorio, pero el bloque de acá arriba deshace esa tira con `!important`
   -y con razón: una tira de 60px al costado no tiene sentido en un teléfono-. Resultado: el
   botón se apretaba, la clase se ponía, y en la pantalla no cambiaba nada.

   Acá el plegado es lo que corresponde a una pantalla angosta: un ACORDEÓN. Queda la cabecera
   -avatar, nombre y domicilio, que es lo que identifica al abonado- y se esconde el cuerpo y el
   mapa del pie. Así la ficha ocupa un renglón y el contenido empieza arriba de todo, que es el
   espíritu del cajón superpuesto que usa el GESTOR por debajo de xl (ver el comentario de
   `SofMic.Framework.Admin\scss\_sm-sidebar-layout.scss`: "por debajo de ese ancho el panel es un
   cajón superpuesto (position: absolute)").

   NACE PLEGADA Y `ficha-abierta` LA DESPLIEGA (16/09/2026). La primera versión hacía al revés
   -desplegada y el JS la plegaba reusando `ficha-collapsed`, la clase de la tira- y eso traía
   dos problemas: se veía desplegada un instante antes de cerrarse, y le llegaban los estilos
   de la tira. Ahora el estado por defecto lo pone el CSS, sin esperar a nadie, y la clase del
   acordeón es propia. La maneja `acomodar()` en AbonadoFicha.ascx.

   Los `:not()` suben el peso a tres: las reglas del bloque de arriba pesan dos y llevan
   `!important`, así que hay que ganarles por especificidad. */
@media (max-width: 991.98px) {
    .abonado-ficha-card:not(.ficha-abierta) .abonado-ficha-body { display: none !important; }
    /* El botón de plegar se ve SIEMPRE en pantalla chica: es la única forma de abrirla y de
       recuperar la pantalla. */
    .abonado-ficha-card .abonado-ficha-toggle-btn { display: inline-flex !important; }
    /* El chevron es el de la tira ("hacia la izquierda"). Acá el cuerpo se abre hacia ABAJO,
       así que apunta abajo cuando está plegada y arriba cuando está abierta. */
    .abonado-ficha-card .abonado-ficha-toggle-btn > i { transition: transform .2s; transform: rotate(-90deg); }
    .abonado-ficha-card.ficha-abierta .abonado-ficha-toggle-btn > i { transform: rotate(90deg); }
    /* Plegada, el globito del avatar avisa que tocándolo se abre. */
    .abonado-ficha-card:not(.ficha-abierta) .abonado-ficha-expand-badge { opacity: 1; }
    /* Plegada, la cabecera no necesita el aire de abajo: es un renglón, no una tarjeta. */
    .abonado-ficha-card:not(.ficha-abierta) { margin-bottom: .75rem !important; }
}

/* ── Layout: los grids del content deben poder achicarse ─────────── */
/* theme.css arma content-wrapper > content > div como grids anidados y les
   define las FILAS con minmax(0,1fr), pero deja las COLUMNAS en `auto`. Una
   columna `auto` se dimensiona al min-content del contenido, así que basta un
   descendiente ancho (una grilla, una tabla con nowrap) para estirar el track
   muy por encima del viewport — en un celular de 375px el contenido se armaba
   a ~820px. Como el content tiene overflow-x:hidden, eso no scrollea: se
   RECORTA, y en la ficha del abonado desaparecía toda la columna de valores
   (Estado, Zona, Localidad...) sin forma de llegar a ella.
   minmax(0,1fr) permite que la columna baje del min-content, igual que ya se
   hace con las filas. Lo ancho de verdad (grillas) scrollea solo, porque el
   GridView ya se renderiza dentro de .table-responsive. */
.my-content-wrapper,
.my-content-wrapper > .my-content,
.my-content-wrapper > .my-content > div {
    grid-template-columns: minmax(0, 1fr);
}

/* ── Un modal colgado de la raíz del content SIGUE SIENDO un modal ─ */
/* La regla de arriba —`.my-content-wrapper > .my-content > div`, que viene de
   theme.css— le pone `display: grid` a TODO div hijo directo del content, y le
   gana en especificidad a la `.modal { display: none }` de Bootstrap: dos
   clases más un elemento contra una sola clase.
   Un modal escrito AL LADO del UpdatePanel —o sea, fuera del ContentTemplate—
   deja entonces de esconderse: queda position:fixed, inset 0, opacity:0 por
   `.fade:not(.show)` y pointer-events:auto. Es una lámina TRANSPARENTE del
   tamaño de la ventana que se come todos los clicks. La pantalla se ve
   perfecta, no tira un solo error en consola, y no responde a nada.
   Apareció en Comunicaciones\WhatsAppCuentas.aspx (modRegistroMeta, el popup
   del registro insertado de Meta): con las tres claves de Meta cargadas el
   modal se renderiza y la pantalla entera queda muerta —no abre "Nueva", no
   entra a una cuenta, no filtra—. Sin las claves el PlaceHolder no lo
   renderiza y la pantalla anda, así que el defecto aparece JUSTO cuando se
   habilita la función, que es cuando nadie lo está buscando.
   Va por CLASE y no por ID para que valga en cualquier pantalla que haga lo
   mismo. El `display: block` que Bootstrap escribe INLINE al abrirlo le gana
   igual, así que el modal sigue funcionando. */
.my-content-wrapper > .my-content > div.modal {
    display: none;
}

/* ── Mobile: prevenir overflow horizontal global ─────────────────── */
/* Red de seguridad para lo que igual se pase de ancho.

   DEJA AFUERA A LAS PANTALLAS CON BARRA DE TÍTULO (15/09/2026). Antes la regla caía sobre los
   tres cajones sin excepción, y eso ANULABA la cabecera pegajosa en TODO el producto por debajo
   de 992px: `overflow-x: hidden` convierte al elemento en contenedor de scroll -no se puede
   cerrar un solo eje: el `overflow-y: visible` se computa a `auto`- y un `position: sticky` se
   resuelve contra el ancestro que recorta. Como `.content` NO SCROLLEA NUNCA (scrollea el
   documento), la barra se quedaba sin nada contra que pegarse y se iba con la página.

   Medido en beta a 941px sobre Órdenes de Servicio: con scrollY 1002 la barra estaba en
   top -959, o sea fuera de la pantalla, y con ella el botón Guardar. A 1531px la misma barra se
   queda en top 43. En el GESTOR, a 847px y scrollY 1040, la fila de título queda en top 53 y
   `.content` computa `overflow-y: visible`: ahí está toda la diferencia.

   El arreglo es el del GESTOR (`SofMic.Framework.Admin\scss\_sm-core.scss`, mismo problema y
   mismo diagnóstico): abrir la cadena SÓLO donde hay una fila pegajosa que preservar. La
   contención horizontal la siguen tomando descendientes -el `minmax(0, 1fr)` de los grids del
   content, más abajo, y el `.table-responsive` del GridView-, que al no ser ancestros de la
   barra no vuelven a romperla.

   Las pantallas sin `cc:PageHeaderBar` (las 18 que siguen con el `uc:PageHeader` viejo) no
   cambian: conservan el overflow, que es lo que les evita el scroll horizontal, y no tienen
   ninguna fila pegajosa que arruinar.

   Y SE FUE EL `top: 0` QUE VIVÍA ACÁ: existía porque `.content` recortaba y el alto del navbar
   se contaba dos veces (la barra se dibujaba 42,6px más abajo y tapaba lo que seguía). Abierta
   la cadena, el sticky vuelve a resolverse contra la ventana y corresponde el mismo
   `top: calc(3.2rem + 1px)` que en escritorio. Los dos cambios van juntos: si se toca uno solo,
   vuelve el defecto. */
@media (max-width: 991px) {
    .wrapper:not(:has(.my-page-headerbar)),
    .content-wrapper:not(:has(.my-page-headerbar)),
    .content:not(:has(.my-page-headerbar)) { overflow-x: hidden; }
}

/* ── Mobile: columnas secundarias de las grillas ─────────────────── */
/* Las grillas con muchas columnas (Abonados: 15) se arman a ~1500px y, aunque
   .table-responsive deja scrollear, en un celular obliga a arrastrar media
   pantalla para leer una fila. Las columnas marcadas con col-mobile-hide se
   ocultan en pantallas chicas y queda lo necesario para identificar al abonado
   y actuar (código, nombre, estado, saldo); el dato completo sigue estando en
   la ficha. Se marcan por clase y no por posición porque el toggle de columnas
   ML cambia los índices en tiempo de ejecución. */
@media (max-width: 767.98px) {
    /*  OCULTAR COLUMNAS SE QUEDA EN 768, y a propósito: es una decisión de CONTENIDO
        -qué datos sobran para identificar al abonado y actuar- y no de acomodamiento.
        En una tablet de 900px las columnas entran y sirven; esconderlas ahí sería
        sacarle información a una pantalla que tiene lugar. Lo que sí sube a 992 es
        acomodar la tabla, en el bloque de abajo. */
    .col-mobile-hide { display: none !important; }
}

/* ── Tablet y celular apaisado: la grilla se acomoda, no se estira ── */
/* HASTA 992 Y NO HASTA 768 (16/09/2026). Estas reglas vivían con las de arriba, o sea
   que entre 768 y 991 -una tablet, y cualquier celular dado vuelta- la grilla se
   quedaba con el comportamiento de escritorio COMPLETO: nowrap, el padding de .85rem
   y los anchos inline de las 15 columnas. Justo la franja donde la tabla ya no entra
   pero todavía no se activaba nada.
   El GESTOR corta en `media-breakpoint-down(lg)` = 991.98 para grilla, solapas y el
   ícono de ordenar (`_sm-gridview.scss`, `_sm-tabs.scss`). Acá va igual. */
@media (max-width: 991.98px) {
    /* El markup marca casi todas las celdas con Wrap="false" (nowrap). Sin esto
       las pocas columnas que quedan igual estiran la tabla por encima del ancho
       del celular: "NOMBRE COMPLETO" solo ya no entra en una línea. */
    .table-responsive > table > thead > tr > th,
    .table-responsive > table > tbody > tr > td { white-space: normal !important; }
    /* SIN ESTO LO DE ARRIBA NO HACE NADA, y por eso la grilla seguía saliéndose
       de la pantalla en el celular (15/09/2026).
       Los anchos de columna se emiten como ATRIBUTO INLINE: el markup pone
       HeaderStyle-Width="1%" / ItemStyle-Width="5%" (ver Abonados\Default.aspx),
       repartidos para las 15 columnas de un escritorio. Un ancho inline le gana
       a cualquier hoja, así que dejar que el texto envuelva no alcanza: la tabla
       vuelve a estirarse hasta el ancho que piden esos porcentajes.
       Es la misma regla que el GESTOR (`_sm-gridview.scss`, "width: auto
       !important" sobre los th), y va con descendiente puro y no con la cadena
       de `>`: hay grillas que meten un `.gridview-wrapper` entre el td y la
       tabla (ver `td.p-0 > .gridview-wrapper > table` más arriba en esta hoja),
       y ahí la cadena de hijos directos se corta y la regla no aplica. */
    .table-responsive th { width: auto !important; }
    .table-responsive th,
    .table-responsive td { white-space: normal !important; }
    /* El padding de .85rem por lado se come ~55px de los 375 disponibles.
       Los :not() replican la regla base para ganarle en especificidad. */
    .table-responsive .table thead th,
    .table-responsive .table tbody td:not(.p-0):not(.p-1):not(.p-2) { padding: .4rem .35rem !important; }
}

/* ── Mobile: la fila de acciones deja de escribir y muestra íconos ── */
/* EN UN CELULAR LOS BOTONES DE LA CABECERA NO ENTRAN, Y NO PODÍAN NI PARTIRSE
   (15/09/2026). Tres reglas de esta hoja se sumaban, y ninguna estaba dentro de una
   media query:
     · `.my-page-actions .btn { white-space: nowrap }` -más abajo-, que impide cortar;
     · el `::after` que le INYECTA el texto del ToolTip a la primaria, leyendo `title`
       o `data-original-title`;
     · el padding y el min-width de escritorio.
   Entre las tres, Guardar es un bloque indivisible de ~110px en un renglón donde ya
   hay seis u ocho hermanos: a 375px la fila se desarma.

   El GESTOR resuelve esto mismo por debajo de md dejando TODOS los botones en sólo
   ícono, Guardar incluido (`_sm-shell.scss`, `.sm-page-actions .btn:has(> i)` con
   `font-size: 0` y el ícono devuelto a su tamaño). Acá va igual: el rótulo ya vive en
   el ToolTip, así que no se pierde información, y ocho acciones vuelven a ser una fila
   legible en vez de un párrafo.

   El `:has(> i)` acota a los botones que TIENEN ícono: uno de sólo texto se quedaría
   mudo, y esta hoja ya usa `:has()` en otros lados. */
@media (max-width: 767.98px) {
    .my-page-actions .btn:has(> i) { font-size: 0 !important; }
    .my-page-actions .btn:has(> i) > i,
    .my-page-actions .btn:has(> i) > .badge { font-size: .95rem; }
    /*  Y DE PASO SE PUEDEN APRETAR CON EL DEDO. Sin rótulo el botón quedaba en 30x29,
        y el mínimo cómodo para un dedo son 44 -el número que el GESTOR escribe en
        `_sm-buttons.scss`: "min-height: 44px; // el minimo comodo para el dedo"-. A
        30px se falla el toque o se aprieta el de al lado, que en esta fila puede ser
        Eliminar. El lugar sobra: cinco botones de 44 más los espacios son ~240 de los
        375 de un teléfono, contra los 195 que ocupaban con texto. */
    .my-page-actions .btn:has(> i) {
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    /* Y se va el texto inyectado en la primaria, que es el que más ancho pedía. */
    .my-page-actions .btn[class*="-success"][title]:not([title=""])::after,
    .my-page-actions .btn[class*="-success"][data-original-title]:not([data-original-title=""])::after {
        content: none !important;
    }
}

/* ── Tablet y celular: la botonera de costado se acuesta en tira ─── */
/* EN PANTALLA CHICA CAÍAN CINCO BOTONES GIGANTES DEBAJO DEL FORMULARIO (16/09/2026).
   El alta del abonado y el cambio de titularidad ponen sus acciones en un
   `<div class="col-xl-auto">` con `btn-block btn-app` y `MinWidth="100px"`: en un
   escritorio es una columna lateral, pero por debajo de xl Bootstrap le da el ancho
   completo y esa columna pasa a ser una PILA al final de la página. Con `btn-app`
   -60px de alto cada uno, de AdminLTE- son cinco bloques enormes que hay que
   scrollear entero para encontrar "Siguiente".

   El GESTOR tiene el mismo patrón resuelto en `_sm-buttons.scss` con un mixin, y su
   comentario describe este defecto exacto: "pierde la tira en pantalla chica, sin que
   nadie lo note: solo en celular caen los botones gigantes debajo del contenido".

   Acá se acuestan en una tira que reparte el ancho. NO se les cambia el orden -el
   GESTOR además los sube con `order: -1`-: en un alta por pasos, "Siguiente" y
   "Cancelar" después del formulario es el orden natural de lectura, y moverlos arriba
   sería cambiar el flujo del asistente, no acomodarlo.

   El `height: auto` es lo que desarma el `btn-app`, y el `min-width` en !important
   hace falta porque el `MinWidth="100px"` del control se emite como estilo INLINE. */
@media (max-width: 1199.98px) {
    .row > [class*="col-"][class*="-auto"]:has(> .btn.btn-block) {
        display: flex;
        flex-wrap: wrap;
        align-items: stretch;
        gap: .5rem;
        width: 100%;
        max-width: 100%;
        flex: 0 0 100%;
    }
    .row > [class*="col-"][class*="-auto"]:has(> .btn.btn-block) > .btn {
        flex: 1 1 auto;
        width: auto !important;
        min-width: 0 !important;
        height: auto !important;
        min-height: 44px;
        margin: 0 !important;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: .35rem;
        font-size: .85rem;
    }
    /* El ícono va al lado del rótulo, no encima: `btn-app` los apila. */
    .row > [class*="col-"][class*="-auto"]:has(> .btn.btn-block) > .btn > i {
        display: inline;
        font-size: 1rem;
        margin: 0;
    }
}

/* ── Mobile: con el menú abierto, el fondo no se mueve ───────────── */
/* AdminLTE dibuja el menú como cajón con un velo (`#sidebar-overlay`) pero NO frena el
   scroll del body: arrastrar sobre el velo mueve la página de atrás mientras el menú
   queda quieto, y al cerrarlo uno aparece en otro lado del listado. Se lee como que la
   pantalla está rota. El GESTOR lo frena con esta misma línea (`_sm-shell.scss`,
   `body.sidebar-open { overflow: hidden }`). */
@media (max-width: 991px) {
    body.sidebar-open { overflow: hidden; }
}

/* ── Mobile: botones de acceso rápido de la ficha ───────────────── */
/* Los 5 btn con fa-2x en btn-group hacen overflow en pantallas chicas */
@media (max-width: 575px) {
    .abonado-ficha-card .btn-group.btn-block {
        display: flex !important;
        flex-wrap: wrap !important;
    }
    .abonado-ficha-card .btn-group.btn-block .btn {
        flex: 1 1 30% !important;   /* 3 por fila en el peor caso */
        min-width: 0 !important;
        padding: .45rem .3rem !important;
        font-size: .72rem;
    }
    .abonado-ficha-card .btn-group.btn-block .btn .fas,
    .abonado-ficha-card .btn-group.btn-block .btn .far,
    .abonado-ficha-card .btn-group.btn-block .btn .fab {
        font-size: 1.4em !important;  /* fa-2x → más chico */
    }
    /* Botón Ver Geolocalización: texto que no desborde */
    .abonado-ficha-card #divBotonGeolocalizacion .btn {
        font-size: .8rem;
        padding: .4rem .5rem !important;
    }
}

/* ===== Venta de Conceptos — secciones coloreadas ===== */
/* Cada seccion (Conceptos / Planes / Promociones / Totales / Calendario) usa
   un card propio con su color de header. Reducimos espaciado interno de las
   grillas para que el card se sienta compacto. */
.venta-totales .table { margin-bottom: 0 !important; }
.venta-totales .table td { padding: .55rem .9rem !important; border-color: #f1f5f9 !important; }
.venta-totales .table tr:last-child td {
    background: linear-gradient(180deg, #f8fafc, #eef2f7) !important;
    border-top: 2px solid #cbd5e1 !important;
    font-size: 1.05rem;
}
.venta-totales .table tr:last-child .venta-total-final { color: #0f172a !important; }
.venta-total-final { letter-spacing: .2px; }

/* =============================================================
   PALETA DE COMANDOS (Ctrl+K) — portada del GESTOR
   -------------------------------------------------------------
   Reemplaza al buscador global que vivia en el navbar. Las clases
   mantienen el prefijo .gpal- del GESTOR a proposito: los dos
   productos comparten el mismo JS y asi un arreglo se porta
   copiando y pegando, sin renombrar nada.
   El disparador es la pastilla .gpal-trigger de la barra blanca.
   Del 15 al 16/09/2026 estuvo como item "Buscar" arriba del menu
   lateral; volvio a la barra a pedido de Pablo. En celular la
   reemplaza una lupa sola (ver Master1.master).
   ============================================================= */
.gpal-trigger {
    display: flex; align-items: center; gap: 8px;
    background: #f1f5f9; border: 1px solid #e2e8f0; border-radius: 8px;
    color: #94a3b8; font-size: .78rem; cursor: pointer;
    padding: 5px 12px; margin-left: 14px; min-width: 240px;
    transition: border-color .15s, background .15s, box-shadow .15s;
    user-select: none; align-self: center;
}
.gpal-trigger:hover { background: #fff; border-color: #c7d2fe; box-shadow: 0 1px 6px rgba(99,102,241,.12); }
.gpal-trigger i { font-size: .72rem; }
.gpal-trigger span { flex: 1; text-align: left; }
.gpal-trigger kbd {
    background: #fff; border: 1px solid #e2e8f0; border-bottom-width: 2px;
    border-radius: 5px; color: #94a3b8; font-size: .62rem; padding: 1px 6px;
    font-family: inherit;
}

/* =============================================================
   ACCESOS DE LA BARRA DE ARRIBA, contra el borde izquierdo:
   Inicio, Mapa de procesos y Ayuda (15/09/2026, como el GESTOR).
   -------------------------------------------------------------
   CUADRADOS Y GRISES, los tres iguales: van pegados en la misma
   barra, asi que tienen que leerse como UN GRUPO y no como tres
   cosas distintas puestas al lado. El destacado queda para la
   pantalla en la que estas parado.
   ============================================================= */
.ispboss-navbar .ispboss-nav-accesos { display: flex; align-items: center; gap: 6px; margin-left: 6px; }
.ispboss-navbar .ispboss-nav-accesos > a {
    width: 34px; height: 34px; padding: 0;
    display: flex; align-items: center; justify-content: center;
    border-radius: 6px; color: #64748b; background: #f1f5f9;
    transition: background .15s, color .15s;
}
.ispboss-navbar .ispboss-nav-accesos > a:hover { background: #e2e8f0; color: #334155; text-decoration: none; }
.ispboss-navbar .ispboss-nav-accesos > a[aria-current="page"] { background: #e0e7ff; color: #4f46e5; }
/* En el celular la barra ya va apretada (hamburguesa, campana, megafono, usuario): los accesos
   se esconden y siguen estando en el menu. */
@media (max-width: 575.98px) {
    .ispboss-navbar .ispboss-nav-accesos { display: none; }
}

/* =============================================================
   MAPA DE PROCESOS (Procesos.aspx) — portado del GESTOR
   -------------------------------------------------------------
   Las clases mantienen el prefijo .proc- del GESTOR a proposito,
   igual que la paleta: los dos productos dibujan la misma tira y
   asi un arreglo se porta copiando y pegando.
   Cada circuito define su color en tres variables, y los pasos lo
   leen: sin eso la tira de cobranza se marcaria con el indigo del
   circuito de altas.
   ============================================================= */
.proc-flow { display: flex; align-items: stretch; gap: 6px; flex-wrap: wrap; }
.proc-alta     { --proc: #6366f1; --proc-soft: #eef2ff; }
.proc-cobro    { --proc: #0891b2; --proc-soft: #e0f2fe; }
.proc-mora     { --proc: #dc2626; --proc-soft: #fee2e2; }
.proc-reclamo  { --proc: #059669; --proc-soft: #d1fae5; }
.proc-step {
    flex: 1 1 0; min-width: 130px; position: relative;
    display: flex; flex-direction: column; align-items: center; text-align: center;
    gap: 6px; padding: 14px 10px 12px;
    background: #fff; border: 1px solid #e8edf4; border-radius: .5rem;
    color: #334155 !important; text-decoration: none !important;
    transition: transform .15s, box-shadow .15s, border-color .15s;
}
a.proc-step:hover { transform: translateY(-3px); border-color: #c7d2fe; box-shadow: 0 8px 22px rgba(99,102,241,.16); }
.proc-step-icon {
    width: 44px; height: 44px; border-radius: 50%; flex: 0 0 auto;
    display: flex; align-items: center; justify-content: center;
    background: var(--proc-soft, #eef2ff); color: var(--proc, #6366f1); font-size: 1.05rem;
}
.proc-step-nombre { font-size: .84rem; font-weight: 700; color: #0f172a; line-height: 1.15; }
.proc-step-desc { font-size: .72rem; color: #64748b; line-height: 1.35; }
.proc-step-badge {
    margin-top: auto; font-size: .7rem; font-weight: 600; color: #64748b;
    background: #f1f5f9; border-radius: 20px; padding: 2px 9px; white-space: nowrap;
}
.proc-badge-warn { background: #fef3c7; color: #92400e; }
.proc-badge-danger { background: #fee2e2; color: #b91c1c; }
/* El paso que el usuario NO tiene permitido se muestra igual, en gris y sin link: el mapa
   explica el proceso completo aunque esa persona no opere todas las etapas. */
.proc-step-off { opacity: .55; filter: grayscale(.6); cursor: not-allowed; }
.proc-step-opcional {
    position: absolute; top: 7px; right: 8px;
    font-size: .58rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    color: #94a3b8; border: 1px dashed #cbd5e1; border-radius: 20px; padding: 0 6px;
}
.proc-arrow { align-self: center; color: #cbd5e1; flex: 0 0 auto; font-size: .85rem; }
.proc-step-col { flex: 1 1 0; min-width: 130px; display: flex; flex-direction: column; gap: 5px; }
.proc-step-col .proc-step { flex: 1 1 auto; min-width: 0; }
.proc-step-actions { display: flex; gap: 5px; }
.proc-step-actions a {
    flex: 1 1 0; text-align: center; font-size: .68rem; font-weight: 600;
    color: #64748b !important; background: #fff; border: 1px solid #e8edf4;
    border-radius: .25rem; padding: 2px 4px; text-decoration: none !important;
    transition: border-color .15s, color .15s;
}
.proc-step-actions a:hover { border-color: #c7d2fe; color: #4338ca !important; }
.proc-step-actions a i { margin-right: 4px; font-size: .6rem; }
.proc-tip {
    margin-top: 12px; font-size: .78rem; color: #64748b;
    background: #f8fafc; border: 1px dashed #e2e8f0; border-radius: .375rem; padding: 7px 12px;
}
.proc-tip i { color: #6366f1; margin-right: 5px; }
.proc-tip a { font-weight: 600; }
/* En el celular la tira se apila: seis pasos de 130px al lado no entran, y con wrap quedaban
   dos arriba y cuatro abajo sin que se entienda el orden. Apilados, las flechas giran. */
@media (max-width: 575.98px) {
    .proc-flow { flex-direction: column; }
    .proc-arrow { transform: rotate(90deg); }
}

/* =============================================================
   PALETA DE COMANDOS (Ctrl+K) — el overlay
   ============================================================= */
.gpal-overlay {
    position: fixed; inset: 0; z-index: 4000;
    background: rgba(15,23,42,.45);
    -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
    display: flex; align-items: flex-start; justify-content: center;
    padding-top: 12vh;
}
.gpal-box {
    width: min(620px, 92vw);
    background: #fff; border-radius: 14.4px;
    box-shadow: 0 24px 70px rgba(15,23,42,.35);
    overflow: hidden; animation: gpalIn .14s ease;
}
@keyframes gpalIn { from { transform: translateY(-8px) scale(.98); opacity: 0; } to { transform: none; opacity: 1; } }
.gpal-input-wrap {
    display: flex; align-items: center; gap: 10px;
    padding: 13px 16px; border-bottom: 1px solid #eef2f7;
}
.gpal-input-wrap i { color: #94a3b8; }
.gpal-input-wrap input {
    flex: 1; border: none; outline: none; background: transparent;
    font-size: .95rem; color: #1e293b;
}
.gpal-input-wrap input::placeholder { color: #b6c0cf; }
.gpal-esc {
    background: #f1f5f9; border-radius: 5px; color: #94a3b8;
    font-size: .62rem; font-weight: 600; padding: 2px 7px; cursor: pointer;
}
.gpal-results { max-height: 52vh; overflow-y: auto; padding: 6px 0 10px; }
.gpal-group {
    font-size: .64rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: #94a3b8; padding: 10px 16px 4px;
}
.gpal-item {
    display: flex; align-items: center; gap: 11px;
    padding: 7px 16px; cursor: pointer; text-decoration: none !important;
}
.gpal-item i {
    width: 28px; height: 28px; border-radius: 8px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: #eef2ff; color: #6366f1; font-size: .72rem;
}
.gpal-item-txt { min-width: 0; }
.gpal-item-titulo { font-size: .84rem; color: #1e293b; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gpal-item-det { font-size: .7rem; color: #94a3b8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gpal-item.sel, .gpal-item:hover { background: #f5f7ff; }
.gpal-item.sel .gpal-item-titulo { color: #4338ca; }
.gpal-vacio { text-align: center; color: #94a3b8; font-size: .84rem; padding: 26px 10px; }
.gpal-vacio i { display: block; font-size: 1.5rem; color: #d7dee8; margin-bottom: 8px; }
/* Salidas del asistente cuando la búsqueda no encontró nada. Se distinguen del resto de la
   lista por el color del icono: no son una pantalla más, son otra forma de resolverlo.
   Verde = preguntar (consulta el manual). Morado = hacer, el mismo del avatar del bot. */
.gpal-item-bot i { background: #ecfdf5; color: #059669; }
.gpal-item-hacerlo i { background: #f5f3ff; color: #7c3aed; }

/* ===================================================================
   BOTON "?" DE AYUDA DE PANTALLA
   Lo emite PageHeaderBar adentro del <h1>. Nace OCULTO: lo muestra el
   script del chat, que es el unico que sabe si el asistente esta
   prendido. Con el bot apagado no aparece en ninguna pantalla.
   =================================================================== */
.my-page-ayuda-btn {
    display: none;
    width: 26px; height: 26px; border-radius: 50%;
    border: 1px solid #e2e8f0; background: #fff; color: #6366f1;
    cursor: pointer; font-size: .62em; padding: 0;
    vertical-align: middle; margin-left: 8px;
    align-items: center; justify-content: center;
    transition: background .12s, box-shadow .12s; outline: none;
}
.my-page-ayuda-btn.visible { display: inline-flex; }
.my-page-ayuda-btn:hover { background: #eef2ff; box-shadow: 0 1px 4px rgba(99,102,241,.25); }
/* Primera visita: un pulso corto para que se descubra donde esta la ayuda. Una sola vez. */
.my-page-ayuda-btn.nueva { animation: ispbossAyudaPulse 1.6s ease-in-out 4; }
@keyframes ispbossAyudaPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(99,102,241,.45); }
    50%      { box-shadow: 0 0 0 7px rgba(99,102,241,0); }
}
.gpal-buscando { text-align: center; color: #94a3b8; font-size: .74rem; padding: 8px 10px; }

/* ===================================================================
   TIRA DEL COMPROBANTE (Controles/ProcesoComprobante.ascx) - riel compacto
   -------------------------------------------------------------------
   PORTADO DEL GESTOR tal cual, desde
   SofMic.GESTOR.Admin\includes\scss\_proceso-comprobante.scss.
   Los nombres de clase conservan el prefijo proc- A PROPOSITO: un
   arreglo que se haga alla se trae aca copiando y pegando, y al reves.
   Si tocas algo de este bloque, fijate si corresponde tocarlo alla.

   Dos cambios respecto del original, y ninguno es cosmetico:
     1. var(--sm-pill-radius) no existe en ISPBoss (es del framework del
        GESTOR): va el literal 999px, que es lo que aquella variable vale.
     2. Estrena el estado .proc-st-bad, que el GESTOR no tiene: alla
        ningun paso puede FALLAR, aca AFIP puede rechazar un comprobante
        y eso no es lo mismo que "todavia no".

   Las paletas (--proc / --proc-soft) pintan SOLO el "estas aca" y el
   boton "+": el estado va en verde/ambar/rojo/punteado.
   =================================================================== */
/* La paleta del riel pinta SOLO el "estas aca" y el boton "+", asi que NO puede ser ni
   verde (#28a745 = paso hecho) ni ambar (#e0a800 = a medias) ni roja (#dc3545 = fallo):
   se confundiria con el estado. Por eso cobranzas toma el violeta de su modulo
   (card-mod-cobranzas, mas arriba) pero facturacion NO toma su verde. */
.proc-facturacion { --proc: #6366f1; --proc-soft: #eef2ff; } /* indigo, el acento del producto */
.proc-cobranza    { --proc: #a855f7; --proc-soft: #f3e8ff; } /* violeta, igual que su card */

.proc-riel { position: relative; }
.proc-rail { list-style: none; display: flex; margin: 0; padding: 0; align-items: flex-start; }
.proc-st {
    position: relative; flex: 1 1 0; min-width: 86px; padding-top: 22px;
    text-align: center; display: flex; flex-direction: column; align-items: center; gap: 2px;
}
/* la via */
.proc-st::before {
    content: ""; position: absolute; top: 8px; left: -50%;
    width: 100%; height: 2px; background: #dee2e6;
}
.proc-st:first-child::before { display: none; }
.proc-st-done::before, .proc-st-part::before { background: #28a745; }
.proc-st-na::before { background: repeating-linear-gradient(90deg, #ced4da 0 3px, transparent 3px 7px); }

/* EL CIRCULO ES EL BOTON del paso */
.proc-pt {
    position: absolute; top: 0; left: 50%; transform: translateX(-50%);
    width: 18px; height: 18px; border-radius: 50%;
    background: #fff; border: 2px solid #dee2e6;
    display: flex; align-items: center; justify-content: center;
    font-size: 11px; font-weight: 700; line-height: 1; color: transparent; text-decoration: none;
}
a.proc-pt:hover { border-color: var(--proc, #6366f1); }
.proc-st-done .proc-pt { background: #28a745; border-color: #28a745; color: #fff; }
.proc-st-part .proc-pt { background: #fff; border-color: #e0a800; color: #e0a800; }
.proc-st-todo .proc-pt { background: #fff; border-color: #ced4da; }
.proc-st-bad  .proc-pt { background: #fff; border-color: #dc3545; color: #dc3545; }
.proc-st-na   .proc-pt { background: transparent; border-style: dashed; border-color: #ced4da; }
.proc-st-aca .proc-pt {
    background: var(--proc, #6366f1); border-color: var(--proc, #6366f1); color: #fff;
    box-shadow: 0 0 0 4px var(--proc-soft, #eef2ff);
}
/* el paso que se puede GENERAR: "+" y comportamiento de boton */
a.proc-pt-mas {
    border-style: solid; border-color: var(--proc, #6366f1);
    color: var(--proc, #6366f1); background: var(--proc-soft, #eef2ff);
}
a.proc-pt-mas:hover {
    background: var(--proc, #6366f1); color: #fff;
    box-shadow: 0 0 0 4px var(--proc-soft, #eef2ff);
}

.proc-lb { display: block; font-size: 11.5px; line-height: 1.25; color: #495057; font-weight: 600; }
.proc-st-aca .proc-lb { color: var(--proc, #6366f1); font-weight: 700; }
.proc-st-na .proc-lb { color: #adb5bd; text-decoration: line-through; font-weight: 500; }
.proc-sb { display: block; font-size: 9.5px; line-height: 1.3; color: #868e96; }
.proc-st-part .proc-sb { color: #a9670f; }
.proc-st-bad .proc-sb { color: #dc3545; font-weight: 700; }
.proc-st-aca .proc-sb { color: var(--proc, #6366f1); }
/* el verbo de la accion: es lo que explica que hace el "+" */
.proc-sb.proc-verbo { color: var(--proc, #6366f1); font-weight: 700; }
.proc-dt { display: block; font-size: 9.5px; line-height: 1.3; color: #adb5bd; }

/* documentos generados, colgando de SU estacion */
.proc-docs { display: flex; flex-direction: column; gap: 2px; align-items: center; margin-top: 3px; }
.proc-doc {
    display: block; max-width: 104px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: 9px; letter-spacing: -.01em; padding: 1px 5px; border-radius: 999px;
    border: 1px solid #dee2e6; background: #f8f9fa; color: #495057; text-decoration: none;
}
.proc-doc:hover { border-color: var(--proc, #6366f1); color: var(--proc, #6366f1); text-decoration: none; }
.proc-doc-actual {
    border-color: var(--proc, #6366f1); background: var(--proc-soft, #eef2ff);
    color: var(--proc, #6366f1); font-weight: 700;
}
.proc-doc-mas { border-style: dashed; color: #868e96; cursor: pointer; }
.proc-doc-oculto { display: none; }
/* El despliegue se hace con una clase en el CONTENEDOR, no tocando el style de cada chip:
   poner style.display = "" no alcanza, porque la regla de arriba lo vuelve a esconder. */
.proc-docs-abierto .proc-doc-oculto { display: block; }

@media (max-width: 767.98px) {
    .proc-rail { flex-wrap: wrap; row-gap: 10px; }
    .proc-st { min-width: 33%; }
}

/* =============================================================
   CONTROLES DE FORMULARIO: label suave, calendario y combo como el GESTOR
   =============================================================
   27/08/2026, a pedido de Pablo ("los combos y fechas estan mas lindos en
   gestor"). Comparadas las dos pantallas lado a lado, la diferencia son tres
   cosas concretas, no el gusto:

   1. EL LABEL COMPITE CON EL DATO. Aca sale negro, en negrita y del mismo
      cuerpo que el valor, asi que "Fec.Venc." pesa igual que la fecha. En el
      GESTOR el label es gris y mas chico: rotula, no compite. El dato es lo
      que uno vino a leer.
   2. EL ADORNO DEL CAMPO ES UN BLOQUE GRIS DURO pegado al input
      (`input-group-text` con el gris de Bootstrap 4: #e9ecef sobre borde #ced4da).
      ⚠ CORREGIDO EL 27/08/2026, MISMO DIA. Este punto decia que en el GESTOR el
      icono va DENTRO del campo "sin recuadro propio", y no es asi: alla el
      DatePicker renderiza un `.btn.btn-default`, que en su tema es #f8f9fa con
      borde #e2e8f0 —y hasta tiene un hover propio para cuando vive adentro de un
      input-group—. O sea que SI hay recuadro; lo que cambia es que es mucho mas
      suave que el gris de Bootstrap 4, y en la comparacion a ojo eso se leyo como
      "no tiene". Pablo eligio la fidelidad al GESTOR.
      El control ahora emite `btn btn-default` (ver DatePicker.vb / TimePicker.vb /
      ColorPicker.vb en el framework), asi que las reglas de `input-group-text` de
      mas abajo YA NO LO ALCANZAN: quedan para los 5 markups que todavia escriben
      `input-group-text` a mano —el sobre de AbonadoAlta y compania—.
   3. El chevron del combo es negro y duro; alla es gris y liviano, y ademas vive
      en su propio botoncito. Ver el bloque del final de esta seccion.

   No se toca la X de limpiar de select2: es funcionalidad, no decoracion.
   Solo se le baja el peso visual. */

/*  1. El label */
.form-group > label,
.form-group > .control-label {
    /*  ⚠ En rem NO da lo mismo que en el GESTOR: AdminLTE tiene la base en 14px
        y el GESTOR (Bootstrap 5) en 16px, asi que el mismo `.8rem` daba aca
        10,92px -medido- contra 12,8px alla. Va en px para que el resultado
        sea el mismo y no el numero. */
    font-size: 12.8px !important;
    font-weight: 500 !important;
    color: #6b7280 !important;
    margin-bottom: .25rem !important;
    letter-spacing: .01em;
}

/*  2. El boton del calendario: sin fondo propio, integrado al campo.
    El borde de la izquierda se saca para que no parta el control en dos. */
.input-group-append > .input-group-text,
.input-group-prepend > .input-group-text {
    background-color: transparent !important;
    border-color: #e2e8f0 !important;
    color: #94a3b8 !important;
}
.input-group-append > .input-group-text { border-left: 0 !important; }
.input-group-prepend > .input-group-text { border-right: 0 !important; }
/*  Y el input pierde su borde del lado que toca al icono, asi los dos quedan
    como un solo campo con el icono adentro. */
.input-group > .form-control:not(:last-child) { border-right: 0 !important; }

/*  3. El chevron del combo, en su botoncito — portado del GESTOR
    ("la flecha en el gestor tiene como un botoncito, aca no", Pablo).

    Alla la flecha no es un triangulito suelto sino una caja pegada al borde derecho
    del campo, con el mismo #f8f9fa del boton del calendario. Se apoya en tres cosas:

    a) Los offsets van en CERO y no en negativo. El GESTOR usa
       `calc(-1 * var(--bs-border-width))` para que el botoncito tape el borde del campo,
       y eso alla cierra porque su borde es exactamente 1px. Aca el select2 declara
       1.5px y el navegador lo redondea —`borderTopWidth` computa 1px, medido—, asi que
       cualquier offset negativo depende del redondeo: con -1.5px sobresalia 2px y con
       -1px, 1px. En cero encastra exacto (mismo alto que el campo, 0 de desborde) y deja
       de depender del DPR de la pantalla.
    b) `border-radius: inherit` en las esquinas derechas: asi acompaña solo el radio
       del campo (9.6px) sin repetir el numero, y si mañana cambia la escala esto la
       sigue sin tocarse.
    c) El triangulo CSS que trae select2 (el `b` con `border-top`) se anula y se
       reemplaza por el chevron \f078 de FontAwesome, que es lo que dibuja el GESTOR.
       El peso 900 es obligatorio: \f078 solo existe en el set SOLIDO.

    ⚠ `width` va en px y no en `2rem` como el original: la base del GESTOR es 16px y
    la de ISPBoss 14, asi que `2rem` daria 28px en vez de los 32 que se ven alla. */
.select2-container--default .select2-selection--single .select2-selection__arrow,
.select2-container--default .select2-selection--multiple .select2-selection__arrow {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 32px !important;
    top: 0 !important;
    bottom: 0 !important;
    right: 0 !important;
    height: auto !important;
    background-color: #f8f9fa !important;
    border: 1px solid #e2e8f0 !important;
    border-top-right-radius: inherit !important;
    border-bottom-right-radius: inherit !important;
    transition: background-color .12s ease-in-out !important;
}
.select2-container--default .select2-selection--single:hover .select2-selection__arrow,
.select2-container--default .select2-selection--multiple:hover .select2-selection__arrow {
    background-color: #e9ecef !important;
}
.select2-container--default .select2-selection--single .select2-selection__arrow b,
.select2-container--default .select2-selection--multiple .select2-selection__arrow b {
    position: static !important;
    margin: 0 !important;
    border: 0 !important;
    width: auto !important;
    height: auto !important;
    font-size: 8.68px !important;   /* .62rem del GESTOR, a 14px de base */
    line-height: 1 !important;
    color: #6c757d !important;
}
.select2-container--default .select2-selection--single .select2-selection__arrow b:before,
.select2-container--default .select2-selection--multiple .select2-selection__arrow b:before {
    content: "\f078";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    text-rendering: auto;
    -webkit-font-smoothing: antialiased;
}
/*  El texto del combo tiene que despejar el botoncito, si no queda por debajo. */
.select2-container--default .select2-selection--single .select2-selection__rendered {
    padding-right: 40px !important;
}
.select2-container--default .select2-selection--single .select2-selection__clear { color: #cbd5e1 !important; font-weight: 400 !important; }
.select2-container--default .select2-selection--single .select2-selection__clear:hover { color: #64748b !important; }

/* =============================================================
   El navbar mide 54 y el contenido arrancaba en 45,8: SE PISABAN
   =============================================================
   27/08/2026. `.ispboss-navbar` declara `min-height: 54px` (mas arriba en este
   archivo, parte de la modernizacion del navbar) pero `.content-wrapper`
   conservaba el `margin-top: 45.8px` que AdminLTE calcula para SU navbar. Los
   dos valores nunca se sincronizaron: 8,2px de solape.

   Estuvo tapado hasta hoy porque debajo del navbar solo habia espacio en
   blanco. Al mover los botones de accion a la cabecera de pagina, esos 8px
   pasaron a estar ocupados y los botones quedaron ENCIMADOS sobre la barra.
   O sea: el bug es viejo, el sintoma es nuevo. */
/* 14/09/2026: el navbar volvio a calc(3.2rem + 1px) (ver .ispboss-navbar), asi
   que el margen vuelve al MISMO calc. Los dos valores tienen que moverse juntos;
   si uno cambia solo, se repite el solape de arriba. */
.content-wrapper { margin-top: calc(3.2rem + 1px) !important; }

/* =============================================================
   CAMPOS: blancos, como el GESTOR; el gris es solo para lo deshabilitado
   =============================================================
   15/09/2026. Hasta hoy este bloque pintaba los campos de #f8fafc diciendo que
   "el GESTOR pinta los campos con un gris muy claro". NO ES ASI: medido con
   getComputedStyle en demo.gestor.ar/Conceptos, inputs, selects y select2 son
   #fff con borde #e2e8f0, y el gris (--bs-secondary-bg = #e9ecef) queda para
   el deshabilitado. El unico gris claro dentro de un campo habilitado es el
   botoncito de la flecha del combo (#f8f9fa, mas arriba), que no se toca.
   Con el fondo gris, un campo editable se leia como deshabilitado ("Numero de
   operacion", "Gracia hasta" en Pagos declarados), que es lo que marco Pablo. */
.form-control:not([type=checkbox]):not([type=radio]),
.custom-select {
    background-color: #fff !important;
}
/*  El deshabilitado tiene que seguir leyendose COMO deshabilitado. */
.form-control:disabled, .form-control[readonly] { background-color: #e9ecef !important; }
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple { background-color: #fff !important; }

/* =============================================================
   LA BARRA DE CONSULTA: botones de CONTORNO, no bloques solidos
   =============================================================
   27/08/2026, comparando `Facturacion\Financiaciones` contra `Ventas\
   Expediciones` del GESTOR. Aca la barra de arriba de cada listado tiene la
   lupa en GRIS OSCURO PLENO y el "+ Nuevo" en AZUL PLENO; en el GESTOR los dos
   son de contorno. Con la fila de acciones ya pasada a outline, esta barra era
   lo unico que quedaba en bloques solidos, y es la primera que se ve al entrar
   a una pantalla.

   Son 104 `btnBuscar` con `btn-secondary` y 82 `btnNuevo` con `btn-primary`:
   186 botones. Se hace por CSS anclando por ID -igual que el boton de salir de
   la fila de acciones-, no editando 98 markups.

   La lupa se acota a `.input-group` A PROPOSITO: hay 5 `btnBuscar` que NO viven
   en la barra (paneles de busqueda a ancho completo, con `w-100`/`btn-block`),
   y ahi el boton solido es la accion principal del panel y corresponde. */
.input-group [id$="btnBuscar"].btn-secondary {
    background-color: transparent !important;
    border-color: #cbd5e1 !important;
    color: #64748b !important;
}
.input-group [id$="btnBuscar"].btn-secondary:hover {
    background-color: #f1f5f9 !important;
    color: #334155 !important;
}

/*  El "+ Nuevo": sigue siendo la accion primaria del listado, pero se dice con
    el color del texto y el borde, no con un bloque azul. */
[id$="btnNuevo"].btn-primary {
    background-color: transparent !important;
    border-color: #2563eb !important;
    color: #2563eb !important;
    font-weight: 600;
}
[id$="btnNuevo"].btn-primary:hover {
    background-color: #2563eb !important;
    color: #fff !important;
}


/* =============================================================
   CAJAS KPI (`Controles/CajaVariacion.ascx`) — portado del GESTOR
   =============================================================
   27/08/2026. El control es el MISMO de los dos lados; lo que allá lo hace ver
   distinto es el tema `home-dash kpi-modern` que se le pone por encima
   (`SofMic.GESTOR.Admin\includes\scss\_inicio.scss`). Acá salía "pelado": un
   `card` con `<h4>` y `<h1>` de Bootstrap adentro y nada más.

   POR QUÉ SE VEÍAN ENORMES Y VACÍAS. La base de `rem` de ISPBoss es 16px; la
   del GESTOR, 13px. Los mismos `h4`/`h1` que allá dan 19,5px y 32,5px acá dan
   24px y 40px, centrados y con el aire de un `card-body py-3`: cuatro cajas
   ocupaban una pantalla entera para decir cuatro números.

   ES OPT-IN. Ninguna de estas reglas se aplica sin las clases en el markup, así
   que las 23 pantallas que ya usan `CajaVariacion` quedan exactamente igual
   hasta que se las convierta una por una.

   TRES DESVÍOS RESPECTO DEL ORIGINAL, y ninguno es de gusto:

     1. Los `rem` van re-escalados por 13/16 (título .69→.70rem, cifra
        1.65→1.40rem, hero 2.3→1.90rem). Copiados tal cual se verían 23% más
        grandes que en el GESTOR, que es justamente el problema que se viene a
        arreglar. Lo que se conserva es el TAMAÑO EN PÍXELES, no el número.

     2. `var(--bs-border-radius-lg)` es de Bootstrap 5 y acá estamos en 4.3.1:
        va `12px`, que es el radio que ya tiene `.card` más arriba en este
        archivo.

     3. El alto parejo lo da el `gap` de la grilla más el `h-100` que el control
        ya trae en su markup, en vez del `margin-bottom` + `calc(100% - 12px)`
        del GESTOR. Allá el control no lleva `h-100`; acá sí, y `.h-100` de
        Bootstrap es `height: 100% !important`, así que el `calc` habría que
        pelearlo con otro `!important` para terminar en el mismo lugar.

   ⚠ Los `!important` de acá abajo son para empatarle a `.card` de más arriba en
   este mismo archivo (`border: none !important` + sombra difusa) y a las
   utilities que el control trae escritas en su markup (`text-center`, `py-3`,
   `m-0`). Todos los selectores suman al menos dos clases, así que ganan por
   especificidad; el `!important` es solo para poder competir.
   ============================================================= */

.home-dash { max-width: none; }

/* El rótulo de cada bloque de cajas. Chiquito y en versalita: ordena sin
   competirle a las cifras, que son lo que se vino a leer. */
.home-sec-title {
    color: #475569;
    font-weight: 700;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .09em;
    margin: 14px 0 10px 1px;
}
.home-dash > .home-sec-title:first-child { margin-top: 0; }

/* GRILLA DE KPI SIN FILAS HUÉRFANAS, Y POR ANCHO DE CONTENEDOR.
   El patrón de la casa (`col-xl col-md-6`) reparte por VIEWPORT, y estas
   pantallas viven adentro de un `section.my-container` que además puede tener
   la barra de filtros abierta al lado: el contenido mide bastante menos que el
   monitor y un media query no se entera. Con `container-type` el corte lo
   decide el ancho real disponible.

   Los cortes son siempre PARES —4 → 2 → 1, nunca 3+1— porque con tres columnas
   angostas el importe se parte al medio.

   LOS UMBRALES ESTÁN MEDIDOS, NO ELEGIDOS. El importe más largo que emite hoy
   Facturación ("$ 2.433.175.346,00") mide 190px a la tipografía de la cifra;
   más 35px de padding y 2px de borde, la tarjeta necesita 227px para no partir
   el número en dos renglones. De ahí salen los dos cortes:
       4 columnas → 4×227 + 3×12 de gap = 944  → 950px
       2 columnas → 2×227 + 1×12 de gap = 466  → 470px
   El 860px del GESTOR acá NO alcanza: a 889px de contenedor las cuatro columnas
   dan 213px y el importe cae a dos líneas. (Medido el 27/08/2026 sobre el CSS
   real; si algún día crece la tipografía de la cifra, estos dos números se
   recalculan igual.)

   OJO: `container-type` va en este envoltorio propio y NO en `.home-dash`.
   `contain: inline-size` hace que el elemento deje de tomar el ancho de su
   contenido, y `.home-dash` en algunas pantallas es item de un flex: ahí
   colapsaría a ancho 0. `.kpi-zone` es un bloque simple que hereda el ancho del
   padre, así que la contención es inocua.

   Las DOS columnas son la base y no una `@container` más: un navegador sin
   soporte de container queries se queda en la base, y dos columnas es un
   fallback razonable en cualquier ancho. Con una sola quedaría una tira
   vertical larguísima en el monitor de un operador. */
.kpi-zone { container-type: inline-size; }
.home-dash .kpi-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    align-items: stretch;
}
/* DOS FILAS DE CAJAS SEGUIDAS NO SE TOCAN. El `gap` separa las cajas ADENTRO de
   una grilla, no una grilla de la siguiente: en los tableros de Mora y de
   Conversaciones, que apilan dos, las filas quedaban pegadas (0 px, medido el
   15/09/2026). Mismo aire que entre caja y caja. */
.home-dash .kpi-grid + .kpi-grid { margin-top: 12px; }
@container (min-width: 950px) {
    .home-dash .kpi-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@container (max-width: 470px) {
    .home-dash .kpi-grid { grid-template-columns: minmax(0, 1fr); }
}
/* El celular, para el navegador que no entienda lo de arriba. */
@media (max-width: 575.98px) {
    .home-dash .kpi-grid { grid-template-columns: minmax(0, 1fr); }
}

/* LA ZONA CON MENOS DE CUATRO CAJAS OCUPA IGUAL TODO EL ANCHO.
   ============================================================
   Corregido el 27/08/2026, reportado por Pablo sobre la solapa Resumen de la
   ficha del abonado. `repeat(4, 1fr)` reparte en cuatro columnas HAYA O NO
   cuatro cajas: esa pantalla tiene tres y quedaba un hueco del cuarto del
   ancho a la derecha. Con los `col-lg-4` de antes eso no pasaba, porque
   Bootstrap reparte entre las columnas que uno escribe.

   Y no era solo el caso de tres. Una zona de UNA sola caja —el "% Facturas
   Pagas" que en el Escritorio va en su propia sección, la caja suelta de
   Cobranzas > Cajas— quedaba ocupando un cuarto del ancho, y las de DOS
   —Categorías de Movimientos— la mitad. El hueco crecía cuanto menos cajas
   tenía la zona, que es exactamente al revés de lo que uno espera.

   Se resuelve por CANTIDAD DE HIJOS y no agregando una clase por variante:
   `:has(> :last-child:nth-child(N))` matchea la grilla cuyo último hijo es
   además el enésimo, o sea la que tiene exactamente N cajas. Así ninguna
   pantalla tiene que declarar cuántas cajas puso, y una zona que mañana gane
   o pierda una caja se reacomoda sola.

   POR QUE NO `auto-fit`, que seria una linea: porque devuelve el corte de tres
   columnas que el bloque de arriba evita a proposito —una tarjeta de 227px es
   el minimo para que un importe de ISPBoss no se parta, y `auto-fit` no
   distingue entre "tres porque hay tres cajas" y "tres porque no entran
   cuatro"—. Acá las tres columnas salen solo cuando las cajas son tres.

   Van DENTRO del `@container (min-width: 950px)`: abajo de ese ancho manda el
   corte por espacio (2 o 1 columna), que es el que evita que se parta el
   número. La de una sola caja va afuera y vale a cualquier ancho: una tarjeta
   sola no tiene con quién compartir la fila.

   Los navegadores sin `:has()` se quedan con las cuatro columnas y el hueco.
   Es el mismo piso que ya pide el `@container` de arriba (Chrome/Edge 105+),
   asi que no agrega un requisito nuevo. */
.home-dash .kpi-grid:has(> :only-child) { grid-template-columns: minmax(0, 1fr); }
@container (min-width: 950px) {
    .home-dash .kpi-grid:has(> :last-child:nth-child(3)) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .home-dash .kpi-grid:has(> :last-child:nth-child(2)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .home-dash .kpi-grid:has(> :only-child)              { grid-template-columns: minmax(0, 1fr); }
}

/* LA TARJETA. Tile blanco compacto con una barra de color al costado; el color
   identifica el dato, no lo grita. */
.home-dash .home-kpi {
    position: relative;
    overflow: hidden;
    min-height: 84px;
    margin-bottom: 0 !important;
    background: #fff !important;
    border: 1px solid #e2e8f0 !important;
    border-radius: 12px !important;
    box-shadow: 0 1px 3px rgba(15,23,42,.06) !important;
    color: #0f172a !important;
    transition: transform .15s, box-shadow .15s, border-color .15s;
}
.home-dash .home-kpi:hover {
    transform: translateY(-2px);
    border-color: #c7d2fe !important;
    box-shadow: 0 8px 22px rgba(99,102,241,.14) !important;
}
.home-dash .home-kpi::before {
    content: "";
    position: absolute;
    top: 0; bottom: 0; left: 0;
    width: 4px;
    background: var(--kpi, #6366f1);
}

/* ARRIBA, NO CENTRADO. Centrar hace que la caja con menos contenido baje TODO
   su bloque: la que no tiene línea de período anterior arrancaría su rótulo
   varios píxeles más abajo que sus vecinas y las cifras quedarían escalonadas.
   Con `flex-start` todas arrancan en el mismo punto y el sobrante de altura
   queda abajo, donde no desalinea nada. */
.home-dash .home-kpi .card-body {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: 2px;
    min-width: 0;
    text-align: left !important;
    padding: 13px 16px 12px 19px !important;
}

/* El título. Una sola línea con puntos suspensivos: dos títulos de distinto
   largo no pueden empujar la cifra de una caja y de la otra no. */
.home-dash .home-kpi .card-body > h4,
.home-dash .home-kpi .card-body > .h4 {
    display: block;
    font-size: .70rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .055em;
    line-height: 1.35;
    color: #64748b;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* EL "?" DE AYUDA VA A LA ESQUINA, ABSOLUTO.
   El control lo emite INLINE adentro del `<h4>`, y ese `<h4>` acá pasa a
   `display: block` con `overflow: hidden`: inline quedaba comido por los puntos
   suspensivos del título. Absoluto sale del flujo y va donde el ojo lo busca.

   No lo recorta el `overflow: hidden` del `<h4>`: su bloque contenedor es
   `.card` (Bootstrap ya la deja `position: relative`), que es ANCESTRO del
   `<h4>`, y en ese caso el recorte no aplica.

   Y baja de `text-primary` a gris: son ocho signos de pregunta azules por
   pantalla compitiéndole a las cifras. Se enciende al pasar por arriba. */
.home-dash .home-kpi .card-body > h4 > [data-toggle="tooltip"],
.home-dash .home-kpi .card-body > .h4 > [data-toggle="tooltip"] {
    position: absolute;
    top: .4rem;
    right: .55rem;
    line-height: 1;
    z-index: 2;
    margin: 0 !important;
}
.home-dash .home-kpi .card-body > h4 > [data-toggle="tooltip"] > i,
.home-dash .home-kpi .card-body > .h4 > [data-toggle="tooltip"] > i {
    color: #cbd5e1 !important;
    font-size: .78rem;
    transition: color .15s;
}
.home-dash .home-kpi:hover .card-body > h4 > [data-toggle="tooltip"] > i,
.home-dash .home-kpi:hover .card-body > .h4 > [data-toggle="tooltip"] > i {
    color: #6366f1 !important;
}

/* LA CIFRA. `tabular-nums` para que dos importes de una misma fila alineen sus
   dígitos y se puedan comparar de un vistazo; `keep-all` para que un importe
   nunca se parta al medio del número (a lo sumo baja de línea en el espacio
   que sigue al $). */
.home-dash .home-kpi .card-body > h1,
.home-dash .home-kpi .card-body > .h1 {
    font-size: 1.40rem;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.2;
    color: #0f172a;
    font-variant-numeric: tabular-nums;
    word-break: keep-all;
    overflow-wrap: normal;
}

/* LA LÍNEA DE VARIACIÓN: el % como píldora suave y la referencia del período
   anterior en gris.

   VA CON `> p, > div` Y NO SOLO CON `> div`, que es como está escrito en el
   GESTOR. Allá el control emite un `<div>`; acá el mismo control emite un
   `<p class="m-0">`. Es una diferencia de una letra que se arregla en el
   `.ascx`… pero ese `.ascx` lo comparten 23 pantallas más, y ninguna de ellas
   entra en este rediseño todavía. Se paga con un selector de dos líneas antes
   que con un cambio en un control compartido que hoy no hace falta.
   Si algún día el control se unifica con el del GESTOR, el `> div` ya está.

   ⚠ EL `:not(.caja-descripcion)` NO ES DECORATIVO. La descripción de la caja
   es TAMBIÉN un `<p>` hijo directo del `card-body`, así que sin la exclusión
   entra por este selector y se lleva puesto su `display: -webkit-box` —el que
   hace funcionar el `-webkit-line-clamp: 2`—, reemplazándolo por `flex`. Con
   eso la descripción deja de truncarse: a 1000px de ancho se iba a tres
   líneas y empujaba la cifra 14,6px más abajo que la de sus vecinas.
   Medido el 27/08/2026. Este selector pesa más que el de `.caja-descripcion`
   (suma el elemento `p`), así que no alcanzaba con reordenar. */
.home-dash .home-kpi .card-body > p:not(.caja-descripcion),
.home-dash .home-kpi .card-body > div {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 2px;
    min-width: 0;
    font-size: .70rem;
    color: #94a3b8;
}
.home-dash .home-kpi .card-body > p:not(.caja-descripcion) > .text-success,
.home-dash .home-kpi .card-body > p:not(.caja-descripcion) > .text-danger,
.home-dash .home-kpi .card-body > p:not(.caja-descripcion) > .text-secondary,
.home-dash .home-kpi .card-body > div > .text-success,
.home-dash .home-kpi .card-body > div > .text-danger,
.home-dash .home-kpi .card-body > div > .text-secondary {
    flex: 0 0 auto;
    font-size: .68rem;
    font-weight: 700;
    padding: 1px 8px;
    border-radius: 999px;
}
.home-dash .home-kpi .card-body > p:not(.caja-descripcion) > .text-success,
.home-dash .home-kpi .card-body > div > .text-success   { background: #ecfdf5; color: #059669 !important; }
.home-dash .home-kpi .card-body > p:not(.caja-descripcion) > .text-danger,
.home-dash .home-kpi .card-body > div > .text-danger    { background: #fef2f2; color: #dc2626 !important; }
.home-dash .home-kpi .card-body > p:not(.caja-descripcion) > .text-secondary,
.home-dash .home-kpi .card-body > div > .text-secondary { background: #f1f5f9; color: #64748b !important; }
.home-dash .home-kpi .card-body > p:not(.caja-descripcion) > .text-muted,
.home-dash .home-kpi .card-body > div > .text-muted {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #94a3b8 !important;
}

/* LA CIFRA PROTAGONISTA. Va a todo el ancho y FUERA de la grilla —no como una
   tarjeta más del mismo tamaño perdida en el medio— porque es la respuesta de
   la pantalla y las otras son sus partes. Ésta sí va centrada: no tiene
   vecinas con las que alinear, y pegada arriba deja un hueco abajo que se ve. */
.home-dash .kpi-hero { margin-bottom: 12px; }
.home-dash .kpi-hero .home-kpi {
    background: linear-gradient(105deg, #f4f7ff, #fff 72%) !important;
    border-color: #d7e0f5 !important;
}
.home-dash .kpi-hero .home-kpi .card-body { justify-content: center; }
.home-dash .kpi-hero .home-kpi .card-body > h1,
.home-dash .kpi-hero .home-kpi .card-body > .h1 { font-size: 1.90rem; }
@media (max-width: 575.98px) {
    .home-dash .kpi-hero .home-kpi .card-body > h1,
    .home-dash .kpi-hero .home-kpi .card-body > .h1 { font-size: 1.55rem; }
}

/* La paleta. Los nombres y los hex son los del GESTOR, para que una misma
   magnitud tenga el mismo color en los dos productos. */
.home-kpi-indigo { --kpi: #6366f1; }
.home-kpi-green  { --kpi: #10b981; }
.home-kpi-cyan   { --kpi: #06b6d4; }
.home-kpi-blue   { --kpi: #3b82f6; }
.home-kpi-teal   { --kpi: #14b8a6; }
.home-kpi-amber  { --kpi: #f59e0b; }
.home-kpi-red    { --kpi: #ef4444; }
.home-kpi-slate  { --kpi: #94a3b8; }


/* =============================================================
   EL BUSCADOR, ADENTRO DE LA FILA DEL TITULO
   =============================================================
   27/08/2026, comparando `Facturacion/Financiaciones` contra `Ventas/
   Expediciones` del GESTOR. Alla el titulo, el buscador y los botones comparten
   UNA fila. Aca el titulo se llevaba una fila entera y la barra de consulta
   -buscador + exportar + "+ Nuevo"- otra debajo: una fila de alto regalada en
   cada listado, arriba de todo, que es donde mas se nota.

   El markup se muda al `<DefaultActionsTemplate>` de `cc:PageHeaderBar`, que ya
   se dibuja en la fila del titulo. Lo que falta ponerle es el ANCHO:
   `.my-page-actions` es un flex pensado para botones cuadrados de un solo icono,
   y un `.input-group` de Bootstrap 4 es `width: 100%`, asi que metido ahi adentro
   se come la fila entera -y ademas ARRASTRA al resto a un segundo renglon, o sea
   que la fila que se queria ganar se pierde igual-. Ese es, textualmente, el
   motivo por el que `Comunicaciones/WhatsAppCuentas` habia dejado el buscador
   afuera; con estas reglas ya no hace falta.

   La receta es la misma del GESTOR (`_sm-shell.scss`, regla
   `.sm-page-headerbar .sm-search-bar.input-group`): ancho propio, un tope, y
   `width: auto` para que el `width: 100%` del input-group deje de mandar.
   El piso de 9rem es para que no quede un cuadradito inutil cuando la fila se
   aprieta; abajo de 768px pasa a renglon propio. */
/*  LA CAJA DE LAS ACCIONES TIENE QUE PEDIR EL ANCHO, NO CONFORMARSE.
    `.my-page-actions` es un item flex de `.my-page-headerbar-right` con
    `flex-basis: auto`, o sea que se mide por su contenido. Medido en vivo: con
    el buscador adentro Chrome le calcula 346px cuando el contenido pide 426, y
    el propio contenedor -que es `flex-wrap: wrap`- se parte en dos renglones
    solo. O sea: el buscador entraba a la fila del titulo pero los botones se
    caian abajo, y la fila que se queria ganar se perdia igual. Se le dice que
    ocupe lo que hay (`flex: 1 1 auto`) y que su contenido siga pegado a la
    derecha (`justify-content: flex-end`), que es donde estaba.

    Va con `:has()` y solo cuando hay buscador A PROPOSITO: las 77 pantallas de
    edicion que solo tienen botones no necesitan nada de esto y se quedan
    exactamente como estan. Es el mismo idioma que usa el GESTOR en
    `_sm-shell.scss` (`> .sm-page-actions:has(> .sm-search-bar)`). Sin `:has()`
    -navegador viejo- el peor caso es el de hoy: los botones bajan un renglon.
    El `min-width: 0` va aparte y para todas: un item flex arranca en
    `min-width: auto` -el ancho de su contenido- y sin eso el contenedor no
    puede ceder y EMPUJA al titulo. */
.my-page-headerbar .my-page-actions {
    min-width: 0;
    max-width: 100%;
}
.my-page-headerbar .my-page-actions:has(> .my-page-search) {
    flex: 1 1 auto;
    justify-content: flex-end;
}
.my-page-headerbar .my-page-actions .my-page-search {
    flex: 0 1 20rem;
    width: auto;
    max-width: 20rem;
    /*  min-width: 0 y no 9rem (15/09/2026). Un ítem flex con piso de 117px NO PUEDE
        ENCOGERSE, así que en una cabecera angosta el buscador no cede y son los botones
        los que se caen de renglón. Con 0 el buscador se achica y la fila aguanta entera,
        que es lo que hace el GESTOR (`_sm-shell.scss`: flex 1 1 14rem, min-width 0). */
    min-width: 0;
}
.my-page-headerbar .my-page-actions .my-page-search > .form-control {
    min-width: 0;
}

/*  A LA MISMA ALTURA QUE LOS BOTONES DE AL LADO.
    El buscador venia de una barra donde era la pieza mas alta: `.form-control`
    mide `calc(1.5em + .75rem + 2px)` = 38px, y la regla de mas arriba de este
    archivo se lo fija con `!important` a los dos lados del input-group. En el
    slot los vecinos son los botones de accion, que `.my-page-actions .btn` deja
    en ~35px, y 3px alcanzan para que la fila se vea despareja. Se lo baja al
    alto del boton con la MISMA cuenta -padding .35rem + font .9em- para que
    sigan atados si algun dia se toca uno. Los `!important` son para ganarle a
    esas dos reglas, que tambien los tienen. */
.my-page-headerbar .my-page-actions .my-page-search > .form-control,
.my-page-headerbar .my-page-actions .my-page-search > .input-group-append > .btn {
    height: calc(1.5em + .7rem + 2px) !important;
    min-height: 0 !important;
    font-size: .9em !important;
    padding-top: .35rem !important;
    padding-bottom: .35rem !important;
}

/*  EN PANTALLA CHICA, RENGLON PROPIO.
    Abajo de 768px el menu lateral ya esta plegado y la fila es solo titulo +
    acciones, pero el titulo mas los tres botones no dejan lugar para un cuadro
    de busqueda usable. Se lo manda abajo, a todo el ancho: los botones -que son
    la accion- se quedan arriba y el buscador -que es el filtro- queda debajo,
    entero. Es lo que hace el GESTOR en su propio breakpoint. El `order` alto lo
    saca de adelante de los botones sin tocar el markup: los botones de la fila
    estan en `order: 1`. */
@media (max-width: 767.98px) {
    /*  Y la mitad derecha de la cabecera baja ENTERA abajo del titulo. Sin esto
        el `100%` de aca abajo es el 100% de lo poco que le queda al lado del
        titulo: medido en un iPhone de 375px, 169px de buscador. Tambien va con
        `:has()` para no cambiarle la cabecera a las 77 pantallas de edicion,
        que en el celular siguen con los botones al lado del titulo. */
    .my-page-headerbar .my-page-headerbar-right:has(.my-page-search) {
        flex: 0 0 100%;
        max-width: 100%;
    }
    .my-page-headerbar .my-page-actions .my-page-search {
        flex: 1 1 100%;
        max-width: none;
        order: 9;
    }
}

/*  EL MODAL DEL CONTROL DE REPORTES NO ES PARTE DE LA FILA.
    `uc:OpcionesReportes` no es solo el boton de descarga: el mismo control trae,
    como hermano, su modal "Opciones Disponibles" con cuatro botones
    `btn-block h-100` y el icono a `fa-2x d-block`. Al entrar el control al slot,
    ese modal pasa a ser DESCENDIENTE de `.my-page-actions` y se come las reglas
    de la fila -min-width de 2.25rem, padding y font de boton chico, `btn-block`
    anulado, icono al tamano del texto-: los cuatro botones del modal quedaban
    chiquitos, en linea y sin el icono grande. El modal se dibuja `position:
    fixed`, fuera de la fila, asi que nada de eso le corresponde. Se lo devuelve
    a lo que era.
    Esta regla no es de esta pantalla: le va a hacer falta a TODO listado que
    mueva su `uc:OpcionesReportes` a la cabecera. */
.my-page-actions .modal .btn {
    min-width: 0;
    padding: .375rem .75rem !important;
    font-size: 1rem !important;
}
.my-page-actions .modal .btn.btn-block {
    display: block !important;
    width: 100% !important;
}
.my-page-actions .modal .btn > i {
    font-size: inherit;
    line-height: inherit;
}
.my-page-actions .modal .btn > i.fa-2x {
    font-size: 2em;
}

/*  GUARD del selector de vista (grilla / agrupada) dentro del slot.
    Al entrar a `.my-page-actions`, sus botones pasan a ser descendientes y se comen
    `min-width: 2.25rem` + el padding de los botones de accion. `.my-radiobutton-group .btn`
    empata en especificidad (2 clases) pero esta ANTES en el archivo, asi que perdia.
    Es el mismo caso que el guard del modal de reportes: un control compuesto que entra
    al slot se lleva puestas las reglas pensadas para botones sueltos.
    Vale para las 23 pantallas que tienen este selector en la barra. */
.my-page-actions .my-radiobutton-group { flex: 0 0 auto; }
.my-page-actions .my-radiobutton-group .btn {
    min-width: 0 !important;
    padding: 5px 10px !important;
    font-size: .8rem !important;
    order: 0 !important;
}


/* =====================================================================
   CABECERA DE GRILLA CON COLOR DE MODULO, Y EL ESTADO VACIO
   =====================================================================
   Portado del GESTOR el 27/08/2026. Es la segunda mitad del sistema de
   color por modulo: la primera son las `card-mod-*` de mas arriba en
   este mismo archivo.

   QUE HACE EL GESTOR, EXACTAMENTE (mirado antes de escribir esto):

   1) EL GESTOR NO PINTA EL <thead> CON EL COLOR DEL MODULO. Su cabecera
      de grilla es gris y neutra. Sale de
      `SofMic.Framework.Admin\scss\_sm-table.scss`, regla
      `.table > thead > tr > th`: fondo #f8f9fa, texto #64748b, peso 600,
      SIN mayusculas, tamaño .88em, raya de abajo de 1px #dfe4ea.
      El comentario que tiene arriba cuenta el recorrido: la cabecera
      "dejo de gritar" el 22/08 —tenia fondo gris, mayusculas, peso 700 y
      letra espaciada, las cuatro cosas juntas— y el fondo fue
      #f1f5f9 -> blanco (revertido el mismo dia) -> #eceff4 -> #f8f9fa.
      El ISPBoss de hoy tiene EXACTAMENTE la version vieja de esa regla
      (#f1f5f9, uppercase, 700, letter-spacing .04em, raya de 2px).

   2) EL COLOR DEL MODULO LO PONE LA CARD QUE CONTIENE LA GRILLA, con una
      linea de 3px arriba. Lo declara la app, no el framework:
      `SofMic.GESTOR.Admin\includes\scss\_cards.scss` (compilado a
      `includes\css\theme.css`) ->
      `.card-outline.card-ventas { border-top: 3px solid #22C55E }`
      y sus ocho hermanas (compras, pagos, cobranzas, clientes, stocks,
      tesoreria, proveedores, abm). Es la MISMA paleta que ya usan las
      `card-mod-*` de este archivo.

   3) Y —esto es lo que faltaba ver— EN EL GESTOR ESA CLASE ESTA EN LA
      CARD DE LA CONSULTA: 66 de los 68 `divResultGrilla` del GESTOR son
      "card card-<modulo> card-outline". En ISPBoss, 86 de los 93 siguen
      siendo "card card-info card-outline", y card-info JUNTO CON
      card-outline NO DIBUJA NADA: el framework apaga a proposito el
      borde de toda card outline porque `TabsContainer.vb` emite
      card-info en todas las solapas. O sea que la grilla se ve sin
      color por la CARD que la envuelve, no por el <thead>.

   QUE SE HACE ACA, ENTONCES:

     A. La cabecera se pone sobria como la del GESTOR.
     B. Cuando la grilla vive adentro de una card con `card-mod-*`, la
        raya de abajo de la cabecera toma el COLOR DEL MODULO y el fondo
        un tinte del mismo tono, lavado al 7%. El acento es una LINEA,
        igual que en el GESTOR; el fondo sigue siendo casi blanco y el
        texto sigue gris. No se pinta la cabecera del color pleno.
     C. El estado vacio se porta tal cual, con el icono y todo.

   Todo por selector descendiente: NO hace falta tocar el markup de
   ninguna grilla. Lo que si falta —y es markup, no CSS— es ponerle
   `card-mod-*` a los 86 `divResultGrilla` que siguen en card-info.
   Hecho de piloto en RemitosInternos\Default.aspx.

   COMO SE REVIERTE: se borra este bloque entero. Nada de aca lo
   necesita nadie mas; las reglas viejas siguen escritas mas arriba y
   vuelven a mandar solas.
   ===================================================================== */

/* --- A. LA CABECERA, SOBRIA COMO LA DEL GESTOR ---
   Mismos valores que `.table > thead > tr > th` de _sm-table.scss. Se
   escribe con el MISMO selector que la regla vieja de mas arriba
   (`.table thead th`) y mas abajo en el archivo: empata en especificidad
   y en !important, asi que gana por orden y se ve el diff de un vistazo.
   No se redeclaran el padding, el border-top ni el white-space: esos
   siguen viniendo de alla y no cambian. */
.table thead th {
    background: #f8f9fa !important;
    color: #64748b !important;
    font-size: .88em !important;
    font-weight: 600 !important;
    text-transform: none !important;
    letter-spacing: .01em !important;
    border-bottom: 1px solid #dfe4ea !important;
}

/*  EL LINK DE ORDENAMIENTO HEREDA EL COLOR DEL TITULO.
    Sin esto la cabecera sale de DOS colores en la misma grilla: las
    columnas con SortExpression las dibuja el GridView como un <a> con su
    propio color, y las que no lo tienen quedan como texto plano con el
    color del th. Gana el del th a proposito: que una columna se pueda
    ordenar no la hace mas importante que sus vecinas. */
.table > thead > tr > th > a,
.table > thead > tr > th > a:hover,
.table > thead > tr > th > a:focus {
    color: inherit !important;
}

/* --- B. EL ACENTO DE MODULO EN LA CABECERA ---
   La grilla hereda el color de la card que la contiene. Con
   `[class*="card-mod-"]` alcanza para la geometria (raya de 2px), y cada
   modulo pone despues su color y su tinte.

   POR QUE 2px Y NO 3px: la card ya dibuja su linea de 3px arriba. Si la
   cabecera repitiera el mismo grosor, la pantalla quedaria con dos rayas
   iguales a diez pixeles de distancia. 2px la lee como acento y no como
   una segunda tapa.

   EL TINTE ES DEL 7% SOBRE BLANCO, calculado, no elegido a ojo: el
   criterio del producto es que el blanco se reserva al CONTENIDO y que
   la cabecera va en un gris muy claro. Un <thead> del color pleno del
   modulo iria en contra de eso y ademas del GESTOR, que directamente no
   lo pinta. El texto queda en el #64748b de siempre: sobre un tinte del
   7% la luminancia baja menos de dos puntos, asi que el contraste es el
   mismo que sobre el #f8f9fa neutro. */

/* --- C. EL ESTADO VACIO, COMO EL DEL GESTOR ---
   Hoy ISPBoss muestra el texto pelado y en un gris oscuro: la regla que
   manda es `.my-gridview table > tbody > tr.gv-emptyrow td` del bundle
   `Includes\css\theme.css` (linea 18949), con color #6c757d y nada mas.
   El GESTOR le agrega el dibujito de la caja abierta arriba del texto y
   lo aclara. Se porta literal de
   `SofMic.Framework.Admin\scss\_sm-gridview.scss`:

     .sm-gridview table > tbody > tr.gv-emptyrow > td  ->  centrado,
        padding 2rem 1rem, color #94a3b8, .88rem, fondo blanco, sin borde
     .gv-emptyrow td::before  ->  Font Awesome 5 solid "\f49e"
        (caja abierta), en bloque, 1.7rem, #d7dee8

   LOS !important SON NECESARIOS Y SE PUEDE COMPROBAR: el padding se lo
   disputa `.table tbody td:not(.p-0):not(.p-1):not(.p-2)` de mas arriba
   en este archivo, que fuerza .5rem .85rem; el borde superior se lo
   disputa `.table tbody td`, que tambien fuerza; y el fondo del hover se
   lo lleva `.table tbody tr:hover > td`, que pintaria de celeste el
   cartel de "no hay nada", cosa que en el GESTOR no pasa.

   La celda del <td colspan> que arma el GridView solo —el otro caso de
   grilla vacia— ya estaba resuelta mas arriba ("Empty state en grilla")
   con los mismos colores, asi que no se toca. */
.my-gridview table > tbody > tr.gv-emptyrow > td {
    text-align: center !important;
    padding: 2rem 1rem !important;
    color: #94a3b8 !important;
    font-size: .88rem !important;
    background: #fff !important;
    border: none !important;
}
.my-gridview table > tbody > tr.gv-emptyrow:hover > td {
    background: #fff !important;
}
.gv-emptyrow td::before {
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    content: "\f49e";
    display: block;
    font-size: 1.7rem;
    color: #d7dee8;
    margin-bottom: .45rem;
}

/*  EL DIBUJO ES LA MITAD FACIL: LO QUE IMPORTA ES EL TEXTO.
    El default de "No se encontraron datos para su busqueda" lo pone
    `CHRS.Framework.Controls\GridView.vb` (linea 195) cuando la pantalla
    no declara EmptyDataText, y hoy lo estan usando ~293 de las 382
    grillas del sitio. Ese texto es correcto cuando hay un filtro puesto
    y MIENTE cuando la tabla esta vacia porque todavia no se cargo nada.

    El GESTOR resuelve esto por pantalla y en el markup, con dos formas
    distintas segun donde vive la grilla:
      - consulta con filtros:  "No hay ventas con los filtros aplicados"
      - grilla de una ficha:   "El contrato no tiene novedades",
                               "Este cliente todavia no tiene usuarios del
                                portal.", "La promocion todavia no da nada:
                                cargale un beneficio"
    Y en un solo lugar lo decide en tiempo de ejecucion:
    `Informes\AgentesRecaudacion.aspx.vb` (lineas 214-223) cambia el
    EmptyDataText segun falte la jurisdiccion, falte el periodo, o no
    haya observaciones. Eso ultimo es code-behind: no se puede hacer
    desde el CSS ni desde el markup.
    Ver el piloto en RemitosInternos\Default.aspx. */

/* =============================================================
   EL MODAL NO HEREDA EL *ORDEN* DE LA FILA DE ACCIONES
   =============================================================
   27/08/2026. Reportado como "encimamiento de botones ... en el modal de
   comunicaciones, y son los botones de antes". Medido EN VIVO, con Chrome
   sobre la sesion ya abierta del usuario, en `Facturacion/Default.aspx` y en
   `OrdenesServicio/Default.aspx`.

   Primero, lo que NO era: el modal de `uc:Comunicacion` esta sano. Medida de
   su footer -"Generacion de Comunicaciones"-: Cerrar / Generar / Generar y
   Enviar separados 7px, y su cadena de padres muere en `#upnGeneral`, o sea
   que NO cuelga de `.my-page-actions`. En las 10 pantallas que lo usan el
   control se declara SIEMPRE fuera de `cc:PageHeaderBar`.

   El que se encima es el hermano de al lado: `Controles/BotonReportes.ascx`
   -"Generacion de Reportes"-, que tiene exactamente los mismos dos botones,
   Cerrar gris y Generar azul, y por eso se lo confunde con el de
   comunicaciones. Su cadena de padres SI arranca en `DIV.my-page-actions`:
   el control entra al slot por el `<DefaultActionsTemplate>` y se lleva el
   modal adentro, igual que `uc:OpcionesReportes`.

   Pero lo que se come no es el TAMANO -de eso ya se ocupa el guard
   `.my-page-actions .modal .btn` de mas arriba, y funciona: el Cerrar mide los
   mismos 77px adentro y afuera del slot-. Lo que se come es el ORDEN:

     .my-page-actions .btn                 { order: 1 }   -> Cerrar  (btn-secondary)
     .my-page-actions .btn[class*="-info"] { order: 3 }   -> Generar (btn-info)

   El markup del control declara Generar PRIMERO y Cerrar despues; el `order`
   los da vuelta. Y ahi esta la trampa: los margenes del footer de Bootstrap 4
   se reparten por posicion en el DOM, NO por posicion visual:

     .modal-footer > :not(:first-child) { margin-left:  .25rem }
     .modal-footer > :not(:last-child)  { margin-right: .25rem }

   Con el orden invertido, los 3,5px de cada lado quedan en los bordes de
   AFUERA de la fila y la junta del medio se queda con CERO. Medido:

     sin esta regla ->  Cerrar 1162..1237 | Generar 1237..1329   separacion 0px
     con esta regla ->  Generar 1158..1250 | Cerrar 1257..1333   separacion 7px

   Cero de separacion entre dos botones PLENOS de colores distintos es lo que
   se ve como "encimados": los bordes se tocan y los dos leen como un solo
   bloque de dos colores.

   El modal se dibuja `position: fixed`, fuera de la fila: el orden de la barra
   no le corresponde. Se lo devuelve a su propio orden de markup, que es el
   layout que tenia antes de que el control entrara a la cabecera.

   DESCARTADO por medicion: `.my-page-actions .btn[class*="ml-"]` no tiene nada
   que ver aca. Ninguno de los cuatro controles con modal que entran al slot
   -`BotonReportes`, `ModalFiltros`, `ComprobanteModalPDF` y
   `OrdenServicioModalPDF`- usa `ml-*` / `mr-*` en sus botones; el espaciado lo
   pone el `.modal-footer` y no el markup.

   Alcance: 20 pantallas meten uno de esos cuatro controles adentro de
   `cc:PageHeaderBar` -19 el de reportes, 10 el de filtros, 3 los de PDF-. Solo
   el de reportes se encimaba, porque es el unico cuyo footer tiene dos botones
   de COLORES distintos, que es lo que los manda a `order` distintos; la regla
   cubre a los cuatro igual, que es lo que hace falta para que no vuelva a
   pasar cuando alguien agregue un boton mas. */
.my-page-actions .modal .btn { order: 0 !important; }

/* El texto que la barra le pega a la primaria tampoco le corresponde: adentro
   de un modal un `-success` es un boton mas, no el ancla de la pantalla.
   Hoy no dispara -el `btnGenerar` de `ModalFiltros` es `btn-success` pero no
   declara `ToolTip`, asi que no tiene `title` ni `data-original-title`-, pero
   alcanza con que alguien le ponga uno para que aparezca el texto duplicado
   adentro del modal. El `:not(.dropdown-toggle)` es para no comerse el caret
   de un dropdown, que tambien vive en `::after`. */
.my-page-actions .modal .btn[class*="-success"]:not(.dropdown-toggle)::after {
    content: none !important;
}

/* =============================================================
   EL BOTON QUE CIERRA UN MODAL, A CONTORNO
   =============================================================
   La otra mitad de lo que se reporto: "son los botones de antes". En la fila
   de acciones ya son todos `btn-outline-*`, pero adentro de los modales
   siguen plenos, y la diferencia se nota justo cuando el modal se abre ARRIBA
   de la barra que se acaba de modernizar.

   El criterio NO es pasar todo a contorno. Leido del GESTOR
   -`Compras/CentroCompras.aspx`, que es lo ultimo que se hizo alla-:

     <button class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal">Cancelar</button>
     <button class="btn btn-sm btn-primary" id="btnGenerarParcial">Generar remito</button>

   o sea: el que SALE va a contorno y el que CONFIRMA se queda pleno. En un
   modal la accion de confirmar es la razon de ser de la ventana; dejarla en
   contorno la iguala con el Cerrar y el modal se queda sin ancla. Asi que aca
   se toca UNICAMENTE el boton de salida, y se lo reconoce por su
   `data-dismiss="modal"` -es el que cierra sin hacer nada- y nunca por color:
   `btn-secondary` tambien lo usan botones que SI hacen algo.

   Alcance: 27 botones de cierre en 22 archivos -20 `btn-secondary` y 6
   `btn-default`, mas uno que ya venia a contorno y no se toca-. Va por
   `data-dismiss` y no por pantalla, asi que cubre tambien los modales que se
   agreguen despues.

   Los colores son los de `btn-outline-secondary` de Bootstrap, medidos en vivo
   sobre el `btnReportes` de la barra -#6c757d en borde y texto, fondo
   transparente, y relleno al hacer hover-, para que el Cerrar del modal se vea
   igual que los botones de la cabecera y no como un tercer estilo. */
.modal-footer .btn.btn-secondary[data-dismiss="modal"],
.modal-footer .btn.btn-default[data-dismiss="modal"] {
    background: transparent !important;
    border-color: #6c757d !important;
    color: #6c757d !important;
}
.modal-footer .btn.btn-secondary[data-dismiss="modal"]:hover,
.modal-footer .btn.btn-secondary[data-dismiss="modal"]:focus,
.modal-footer .btn.btn-default[data-dismiss="modal"]:hover,
.modal-footer .btn.btn-default[data-dismiss="modal"]:focus {
    background: #6c757d !important;
    border-color: #6c757d !important;
    color: #fff !important;
}

/* --- D. LA MISMA CABECERA CUANDO LA GRILLA VIENE VACIA ---
   Va aparte y no junto con el bloque A de mas arriba a proposito: este
   archivo lo estan escribiendo dos sesiones a la vez y agregar al final
   no le pisa el trabajo a nadie.

   EL PORQUE, QUE NO ES OBVIO: el <thead> de una grilla del framework
   SOLO EXISTE CUANDO HAY FILAS. `CHRS.Framework.Controls\GridView.vb`
   (linea 266) hace `If Rows.Count() > 0 Then ... HeaderRow.TableSection =
   TableRowSection.TableHeader`, o sea que con la grilla vacia la fila de
   titulos se queda adentro del <tbody> como `tr.gv-header` y ningun
   selector que empiece con `thead` la alcanza.

   Por eso `theme.css` escribe todas sus reglas de cabecera dos veces
   (`> thead > tr.gv-header` y `> tbody > tr.gv-header`), y por eso el
   GESTOR hace lo mismo en `_sm-gridview.scss` con un `> thead, > tbody`
   que envuelve al `tr.gv-header`.

   Sin esto, la pantalla vacia —que es justo la que se esta arreglando en
   el punto C— mostraria la cabecera con el estilo viejo y la llena con
   el nuevo. Se repiten aca las mismas declaraciones del bloque A y del
   bloque B para el camino del tbody. */
.my-gridview table > tbody > tr.gv-header > th {
    background: #f8f9fa !important;
    color: #64748b !important;
    font-size: .88em !important;
    font-weight: 600 !important;
    text-transform: none !important;
    letter-spacing: .01em !important;
    border-bottom: 1px solid #dfe4ea !important;
}
.my-gridview table > tbody > tr.gv-header > th a,
.my-gridview table > tbody > tr.gv-header > th a:hover,
.my-gridview table > tbody > tr.gv-header > th a:focus {
    color: inherit !important;
}

/*  EL HOVER DE FILA NO LLEGA A LA CABECERA Y NO HAY QUE APAGARLO.
    Con la fila de titulos adentro del <tbody>, `.table tbody tr:hover > td`
    la trata como una fila mas, pero apunta a los <td> y las celdas de
    titulo son <th> (GridView deja UseAccessibleHeader en True). Se probo
    agregar un apagado explicito y se saco: cualquier regla de `:hover`
    sobre esas celdas le gana al fondo de mas arriba por ser mas
    especifica, y el tinte del modulo se apagaba al pasar el mouse. */

/* --- E. EL AIRE DEL ESTADO VACIO: LA CORRECCION QUE HIZO FALTA ---
   MEDIDO EN EL NAVEGADOR, no razonado: la celda del cartel quedaba con
   8px x 13,6px de padding en vez de los 32px x 16px que pide el bloque C.
   O sea el estado vacio se dibujaba APLASTADO, con el icono y el texto
   apretados contra el borde de la fila.

   Quien ganaba: `.table tbody td:not(.p-0):not(.p-1):not(.p-2)`, mas
   arriba en este archivo, que fuerza `.5rem .85rem`. Pesa CUATRO clases
   (la de .table mas una por cada :not) y dos elementos; el selector del
   bloque C pesa dos clases y cuatro elementos, y en especificidad las
   clases se cuentan antes que los elementos, asi que perdia aunque los
   dos tengan !important.

   Se le repite la misma cadena de :not al selector del cartel: pasa a
   cinco clases y cuatro elementos y gana. Los :not ademas no son de
   adorno, dicen lo correcto: si alguien le pone p-0 a la celda es porque
   quiere manejar el aire a mano.

   (Es exactamente la misma trampa que el GESTOR dejo anotada en
   `_sm-gridview.scss`: "mientras la regla general forzaba, ESTE cartel
   perdia. Medido: la celda tenia 5,2px de padding en vez de los 2rem que
   pide, o sea que el estado vacio se venia dibujando aplastado desde que
   se escribio".) */
.my-gridview table > tbody > tr.gv-emptyrow > td:not(.p-0):not(.p-1):not(.p-2) {
    padding: 2rem 1rem !important;
}

/* =============================================================
   Dos huecos que dejo el barrido de las 105 pantallas
   =============================================================
   1. Los botones CON TEXTO se pueden partir en dos renglones.
      `+ Nuevo` esta en 80 pantallas, y hay `Ejecutar Prediccion` y
      `Nueva Promocion`. En anchos intermedios el texto se parte, el boton
      crece a dos lineas y SUBE el alto de la fila --justo lo contrario de lo
      que este cambio vino a hacer, que fue ganar 30px--. `.btn-app` ya tenia
      el nowrap; los demas no.
   2. `btn-default` no tenia regla en el slot. `Tablas\SeguridadPerfiles.aspx`
      trae `btnExportarExcel` con esa clase y quedaba como el UNICO boton
      solido claro de su fila. Se lo pasa a contorno como al resto.
      (`btn-default` es de Bootstrap 3: en BS4 no existe y hereda el gris del
      navegador, por eso desentona con todo lo demas.) */
.my-page-actions .btn { white-space: nowrap; }

.my-page-actions .btn.btn-default {
    background-color: transparent !important;
    border-color: #cbd5e1 !important;
    color: #64748b !important;
}
.my-page-actions .btn.btn-default:hover {
    background-color: #f1f5f9 !important;
    color: #334155 !important;
}

/*  Los hijos del slot que NO son `.btn` (el contenedor del selector de vista y
    los `.btn-group`) no tenian `flex: 0 0 auto`: hoy andan, pero un flex sin
    base declarada se encoge cuando la fila se aprieta. */
.my-page-actions > #divResultTypeContainer,
.my-page-actions > .btn-group { flex: 0 0 auto; }

/*  ⚠ REVERTIDO EL 27/08/2026, a pedido de Pablo mirando la pantalla.
    Aca habia 18 reglas que le ponian al <thead> un TINTE de fondo del color del
    modulo mas una raya de 2px del mismo color. En Abonados eso daba una cabecera
    ROSA con doble linea fucsia, y no es lo que hace el GESTOR: alla la cabecera
    de la grilla es GRIS NEUTRA y el color del modulo aparece UNA sola vez, en la
    linea de 3px de arriba de la CARD.
    El diagnostico original era correcto -'el GESTOR NO pinta el thead'- y aun asi
    se termino pintando. La regla que queda es la sobria de mas arriba; el color
    vive en `.card.card-outline[class*="card-mod-"] { border-top: 3px }`. */

/*  La cifra del KPI: 1.40 -> 1.70rem (27/08/2026).
    Pablo dijo primero que el numero se veia chico y despues, con un `clamp()`
    atado al ancho del contenedor, que quedaba MUY GRANDE. El clamp estaba mal
    pensado: en una tarjeta estirada a 700px la cifra se disparaba.
    Queda un valor FIJO, un escalon por encima del anterior (+21%): se nota
    contra el rotulo pero no cambia el alto de la tarjeta ni depende del ancho.
    Si hay que moverlo, es este numero y nada mas. */
.home-dash .home-kpi .card-body > h1,
.home-dash .home-kpi .card-body > .h1 { font-size: 1.70rem !important; }

/*  REGLA BASE de la descripcion, para las cajas que NO llevan `home-kpi`.
    Ese CssClass lo setea el codebehind, y hay pantallas que no lo hacen
    (DashboardConceptos, Cobranzas/Dashboard, Cajas, CajasRegistros...). Sin esta
    regla, ahi la descripcion sale con el tamano y el color de un parrafo normal:
    mas grande y mas oscura que el titulo de la caja, o sea al reves de lo que
    tiene que ser. Los valores son los mismos que la regla de abajo. */
.caja-descripcion {
    font-size: .72rem;
    line-height: 1.3;
    color: #94a3b8;
    margin-top: 2px !important;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/*  La descripcion opcional de la caja KPI. Va chica y gris: acompana al numero,
    no le compite. Se trunca a dos lineas para que una descripcion larga no
    cambie el alto de la tarjeta y desalinee la fila.

    RESERVA UNA LINEA, Y DOS SOLO CUANDO HACEN FALTA (min-height).
    Desde que la descripcion pasa a ir ENTRE EL TITULO Y LA CIFRA —como en el
    GESTOR— todo lo que va abajo arranca donde termina ella. Truncar a dos
    lineas evita que una descripcion larguisima estire la tarjeta, pero NO
    alcanza para alinear: una caja con descripcion de una linea y su vecina con
    una de dos dejan sus cifras a distinta altura, y en una fila de cuatro eso
    se lee como un escalon. Medido el 27/08/2026: 49,7px contra 64,2px.

    La primera version reservaba SIEMPRE dos lineas. Alineaba, pero a cambio
    metia un renglon vacio entre el texto y la cifra en toda caja de una sola
    linea —que en un monitor normal son TODAS—, y ese hueco se ve. Reportado
    por Pablo.

    El umbral esta MEDIDO, no elegido. Se rendirizaron las 87 descripciones que
    hoy existen en el sistema y se busco a que ancho empiezan a cortarse:

        contenedor 1600px (columna de 400px) -> 0 de 87 se cortan
        contenedor 1550px (columna de 388px) -> 2
        contenedor 1400px (columna de 350px) -> 7
        contenedor 1200px (columna de 300px) -> 21

    O sea que de 1600 para arriba la reserva de dos lineas no compra alineacion
    —ya estan todas alineadas en una— y solo agrega hueco. Por eso arriba de ese
    ancho se reserva UNA, y abajo DOS, que es donde empieza a haber algo que
    alinear.

    2,6em = 2 lineas exactas y 1,3em = 1 (font-size .72rem x line-height 1,3).
    El sobrante de altura cae al final de la tarjeta, donde no corre nada.

    OJO SI SE ESCRIBEN DESCRIPCIONES MAS LARGAS: el 1600 vale para los textos de
    hoy. Una descripcion notablemente mas larga se va a cortar antes y va a
    desalinear su fila entre 1600 y ese punto. Se arregla acortando el texto o
    bajando el umbral; el script que hizo la medicion es reproducible.

    Las cajas SIN descripcion no emiten el elemento y no reservan nada. Hoy eso
    es inocuo: de las 31 zonas del sistema, 26 tienen descripcion en todas sus
    cajas y 5 en ninguna — no hay una sola zona mixta. Si algun dia se arma una,
    la caja sin descripcion va a quedar con su cifra mas arriba que las otras;
    la solucion es ponerle descripcion, no sacar esta regla. */
.home-dash .home-kpi .caja-descripcion {
    font-size: .72rem;
    line-height: 1.3;
    color: #94a3b8;
    margin-top: 2px !important;
    min-height: 1.3em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
/*  Abajo de 1600 de contenedor si hay descripciones que se cortan, asi que ahi
    se reservan las dos lineas para que las cifras de la fila sigan alineadas.
    El `kpi-hero` queda afuera a proposito: no vive adentro de un `.kpi-zone`,
    asi que esta consulta no lo alcanza — y como es una tarjeta sola, no tiene
    con quien alinearse. */
@container (max-width: 1599px) {
    .home-dash .home-kpi .caja-descripcion { min-height: 2.6em; }
}

/* --- Tipografia: Inter --- */
/*
   La misma fuente que usa el GESTOR, traida de su `inter-4`. Es una VARIABLE FONT: un solo
   archivo de 48 KB cubre todos los pesos de 100 a 900, por eso no hay un woff2 por peso.
   Subset latino: no trae cirilico ni griego.

   `font-display: swap` es deliberado: el texto se dibuja con la fuente del sistema y cambia a
   Inter cuando termina de bajar. Se ve un reflow de un parpadeo la primera vez, pero nunca una
   pantalla en blanco si el archivo tarda o falla.

   El stack conserva entera la cola que traia AdminLTE, con Inter adelante: si el woff2 no
   carga, cae en Segoe UI y la app se ve como se veia antes.

   Sin !important a proposito. Este archivo se linkea DESPUES del bundle themeCSS
   (ver Master0.Master), asi que a igual especificidad gana este. Los tres selectores son los
   tres lugares donde theme.css declara el stack: `body` (de donde hereda casi todo) y
   `.tooltip` / `.popover`, que lo repiten porque se cuelgan del body y no heredan del contenedor.
*/
@font-face {
    font-family: "Inter";
    src: url("../inter-4/inter-latin-var.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

:root {
    --font-family-sans-serif: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}

body,
.tooltip,
.popover {
    font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}


/* ============================================================================
   CONCEPTOS / VENTA DEL ABONADO  (Abonados\Controles\AbonadoConceptosVenta.ascx)

   Todo esto vivia adentro del .ascx: parte como atributos style= sueltos y parte
   como un bloque <style> de 24 reglas metido en el markup del modal de turnos, o
   sea que se re-emitia en cada render de ese panel.

   NO ESTA TODO: cinco style= se quedaron inline a proposito y no son un olvido.
    - Los cuatro que arma el JS al construir la grilla de turnos llevan valores
      calculados en el momento (el color de la cuadrilla, el ancho de la barra de
      ocupacion segun el porcentaje): no hay clase que pueda expresarlos.
    - El display:none inicial de #vtGrillaTable, porque el JS la muestra con
      $('#vtGrillaTable').show(), y .show() de jQuery limpia el display INLINE. Si
      el none viniera de aca, la tabla no apareceria nunca.
   ============================================================================ */

/* Resumen de tramos de un descuento escalonado, debajo del renglon del concepto. */
.venta-tramos-resumen { margin-left: 2px; }

/* --- Modal de confirmacion de venta --- */
.venta-modal-header-confirmar {
    background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
    color: #fff;
}
.venta-modal-subtitulo { opacity: .85; }

/* --- Turno de visita tecnica: caja de seleccion --- */
.vt-card-header { font-size: 13px; }

.vt-sel-box {
    border: 2px solid #28a745;
    border-radius: 8px;
    padding: 10px 12px;
    background: #f0fff4;
}
.vt-sel-txt { color: #155724; }

.vt-clear-btn { padding: 1px 6px; font-size: 11px; }

/* El JS le pisa el border-style (dashed -> solid) cuando ya hay un turno elegido:
   el estilo inline que escribe gana sobre esta clase, asi que esto es solo el
   estado inicial. */
.vt-abrir-btn { border-style: dashed; border-width: 2px; padding: 12px; }

/* --- Turno de visita tecnica: modal de la grilla --- */
.vt-modal-header-grilla {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: #fff;
}
.vt-sem-label { font-size: 14px; }
.vt-grilla-scroll { overflow-x: auto; }
.vt-grilla-table { table-layout: fixed; min-width: 700px; }
.vt-empty-icon { font-size: 2em; display: block; margin-bottom: 8px; opacity: .4; }

/* --- Turno de visita tecnica: celdas de la grilla ---
   Venian del bloque <style> inline del .ascx, tal cual. */
.vtslot {
    border-radius: 6px;
    padding: 4px 3px;
    text-align: center;
    cursor: pointer;
    font-size: 11px;
    line-height: 1.3;
    min-height: 42px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    transition: all .15s;
}
.vtslot.disponible { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.vtslot.disponible:hover { background: #28a745; color: #fff; transform: scale(1.03); }
.vtslot.llenando { background: #fff3cd; color: #856404; border: 1px solid #ffeaa7; }
.vtslot.llenando:hover { background: #ffc107; color: #212529; transform: scale(1.03); }
.vtslot.lleno { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; cursor: not-allowed; opacity: .6; }
.vtslot.vacio { background: #f8f9fa; color: #adb5bd; border: 1px dashed #dee2e6; cursor: default; }

.vtbarra { height: 5px; border-radius: 3px; background: #e9ecef; width: 90%; margin-top: 3px; }
.vtbarraf { height: 100%; border-radius: 3px; }

/* Primera columna: cuadrilla + horario */
.turno-fila-cuad {
    vertical-align: middle !important;
    padding: 4px 6px !important;
    background: #f8f9fa;
    width: 140px;
    min-width: 130px;
}
.turno-cuad-nombre { font-size: 11px; font-weight: 700; color: #343a40; line-height: 1.2; text-align: center; }
.turno-cuad-bar { height: 3px; border-radius: 2px; margin: 3px 2px 4px 2px; }
.turno-cuad-horario { font-size: 10px; color: #6c757d; text-align: center; }

/* Cabecera compacta */
#vtGrillaTable th { padding: 3px 2px; border-bottom: 2px solid #dee2e6; white-space: nowrap; text-align: center; }
#vtGrillaTable td { padding: 2px; vertical-align: middle; }
.turno-th-dow { display: block; font-size: 9px; font-weight: 700; text-transform: uppercase; color: #6c757d; }
.turno-th-dia { display: block; font-size: 13px; font-weight: 700; color: #343a40; }
.turno-th-mes { display: block; font-size: 9px; color: #6c757d; }
.turno-col-hoy .turno-th-dia {
    background: #1a73e8;
    color: #fff !important;
    border-radius: 50%;
    width: 22px;
    height: 22px;
    line-height: 22px;
    display: inline-block;
    text-align: center;
    margin: 0 auto;
}

/* Origen de una novedad que entro por un plan comercial o por una promocion.
   Eran dos style= elegidos con un If en el markup; son dos estados, o sea una clase. */
.venta-origen-plan  { background-color: #cfe2ff; color: #084298; }
.venta-origen-promo { background-color: #d1e7dd; color: #0f5132; }

/* Celda vacia de la primera columna de la grilla de turnos (la arma el JS). */
.turno-th-spacer { width: 140px; background: #fff; border: none; }

/* ============================================================================
   BOTONES SUAVES EN LA FILA DE SOLAPAS  (port de la regla del GESTOR)

   En el GESTOR esto no son clases sueltas sino una REGLA DE SISTEMA, escrita en
   SofMic.Framework.Admin/scss/_sm-buttons.scss: tres lugares, tres tratos.

       .sm-page-actions   la fila de titulo        -> de contorno
       .card-subheader    la banda de una seccion  -> suaves
       .sm-tabs-header    la fila de solapas       -> suaves

   O sea que alla un <cc:Button CssClass="btn-success"> puesto adentro de la tira de
   solapas se dibuja SUAVE aunque el markup pida el relleno: es la barra la que
   decide, no cada boton. Por eso ninguna barra del GESTOR tiene bloques de color
   saturado compitiendo con las solapas.

   Esto es ese mismo trato para ISPBoss, sobre .my-tabs-header, que es lo que emite
   CHRS.Framework.Controls.TabsContainer.

   LA FORMULA ES LA DE ALLA: fondo blanco, borde con el color aclarado al 70%, letra
   en el color pleno. Hover aclara al 94%, activo al 88%. Deshabilitado se queda
   blanco y lo que se apaga es la letra �si se le sacara tambien el borde dejaria de
   leerse como un boton�.

   LOS COLORES SALEN DEL BLOQUE "--- Botones ---" DE ESTE MISMO ARCHIVO, no de
   theme.css. ISPBoss reemplaza la paleta de Bootstrap entera (#2563eb, #64748b,
   #16a34a, ...) y lo hace con !important, asi que un primer intento escrito con los
   colores viejos de theme.css salio a medias: la letra tomaba el color nuevo y el
   fondo se quedaba con el relleno. De ahi que estas reglas tambien lleven !important.

   SOLO TOCA LOS RELLENOS. Los btn-outline-* de la barra �Eliminar, Reactivar, Cambio
   de titularidad, Comunicar, Descargar, Baja Total� quedan como estan, igual que en
   el GESTOR.

   .btn-app QUEDA AFUERA a proposito. Es el boton cuadrado de 60px de alto de
   AdminLTE: otra FORMA de boton, no otro color. El GESTOR no tiene esa variante asi
   que su regla nunca se topa con el caso; aca el unico que la usa dentro de una barra
   es el "Volver" de la ficha del abonado, y un cuadrado de 60px en blanco no se lee
   como el resto de la familia suave.
   ============================================================================ */

.my-tabs-header .btn-primary:not(.btn-app) {
    background: #fff !important;
    border-color: #bed0f9 !important;
    color: #2563eb !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-primary:not(.btn-app):hover,
.my-tabs-header .btn-primary:not(.btn-app):focus {
    background: #f2f6fe !important;
    border-color: #2563eb !important;
    color: #2563eb !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-primary:not(.btn-app):not(:disabled):not(.disabled):active,
.my-tabs-header .btn-primary:not(.btn-app):not(:disabled):not(.disabled).active {
    background: #e5ecfd !important;
    border-color: #2563eb !important;
    color: #2563eb !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-primary:not(.btn-app):disabled,
.my-tabs-header .btn-primary:not(.btn-app).disabled {
    background: #fff !important;
    border-color: #d8e3fb !important;
    color: #87a9f4 !important;
    opacity: 1;
}

.my-tabs-header .btn-secondary:not(.btn-app) {
    background: #fff !important;
    border-color: #d0d5dc !important;
    color: #64748b !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-secondary:not(.btn-app):hover,
.my-tabs-header .btn-secondary:not(.btn-app):focus {
    background: #f6f7f8 !important;
    border-color: #64748b !important;
    color: #64748b !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-secondary:not(.btn-app):not(:disabled):not(.disabled):active,
.my-tabs-header .btn-secondary:not(.btn-app):not(:disabled):not(.disabled).active {
    background: #eceef1 !important;
    border-color: #64748b !important;
    color: #64748b !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-secondary:not(.btn-app):disabled,
.my-tabs-header .btn-secondary:not(.btn-app).disabled {
    background: #fff !important;
    border-color: #e3e6ea !important;
    color: #aab3bf !important;
    opacity: 1;
}

.my-tabs-header .btn-success:not(.btn-app) {
    background: #fff !important;
    border-color: #b9e3c9 !important;
    color: #16a34a !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-success:not(.btn-app):hover,
.my-tabs-header .btn-success:not(.btn-app):focus {
    background: #f1f9f4 !important;
    border-color: #16a34a !important;
    color: #16a34a !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-success:not(.btn-app):not(:disabled):not(.disabled):active,
.my-tabs-header .btn-success:not(.btn-app):not(:disabled):not(.disabled).active {
    background: #e3f4e9 !important;
    border-color: #16a34a !important;
    color: #16a34a !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-success:not(.btn-app):disabled,
.my-tabs-header .btn-success:not(.btn-app).disabled {
    background: #fff !important;
    border-color: #d5eede !important;
    color: #7fcc9b !important;
    opacity: 1;
}

.my-tabs-header .btn-danger:not(.btn-app) {
    background: #fff !important;
    border-color: #f4bebe !important;
    color: #dc2626 !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-danger:not(.btn-app):hover,
.my-tabs-header .btn-danger:not(.btn-app):focus {
    background: #fdf2f2 !important;
    border-color: #dc2626 !important;
    color: #dc2626 !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-danger:not(.btn-app):not(:disabled):not(.disabled):active,
.my-tabs-header .btn-danger:not(.btn-app):not(:disabled):not(.disabled).active {
    background: #fbe5e5 !important;
    border-color: #dc2626 !important;
    color: #dc2626 !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-danger:not(.btn-app):disabled,
.my-tabs-header .btn-danger:not(.btn-app).disabled {
    background: #fff !important;
    border-color: #f9d8d8 !important;
    color: #ec8888 !important;
    opacity: 1;
}

.my-tabs-header .btn-warning:not(.btn-app) {
    background: #fff !important;
    border-color: #f4d6b4 !important;
    color: #d97706 !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-warning:not(.btn-app):hover,
.my-tabs-header .btn-warning:not(.btn-app):focus {
    background: #fdf7f0 !important;
    border-color: #d97706 !important;
    color: #d97706 !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-warning:not(.btn-app):not(:disabled):not(.disabled):active,
.my-tabs-header .btn-warning:not(.btn-app):not(:disabled):not(.disabled).active {
    background: #faefe1 !important;
    border-color: #d97706 !important;
    color: #d97706 !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-warning:not(.btn-app):disabled,
.my-tabs-header .btn-warning:not(.btn-app).disabled {
    background: #fff !important;
    border-color: #f8e7d2 !important;
    color: #eab476 !important;
    opacity: 1;
}

.my-tabs-header .btn-info:not(.btn-app) {
    background: #fff !important;
    border-color: #b7e4f8 !important;
    color: #0ea5e9 !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-info:not(.btn-app):hover,
.my-tabs-header .btn-info:not(.btn-app):focus {
    background: #f1fafe !important;
    border-color: #0ea5e9 !important;
    color: #0ea5e9 !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-info:not(.btn-app):not(:disabled):not(.disabled):active,
.my-tabs-header .btn-info:not(.btn-app):not(:disabled):not(.disabled).active {
    background: #e2f4fc !important;
    border-color: #0ea5e9 !important;
    color: #0ea5e9 !important;
    box-shadow: none !important;
}
.my-tabs-header .btn-info:not(.btn-app):disabled,
.my-tabs-header .btn-info:not(.btn-app).disabled {
    background: #fff !important;
    border-color: #d4effb !important;
    color: #7acef3 !important;
    opacity: 1;
}

/* ============================================================================
   SOLAPAS CON SUBRAYADO  (port de la regla del GESTOR)

   En el GESTOR las solapas no son la pestaña con caja de Bootstrap sino un
   SUBRAYADO: la tira es plana, la activa se marca con una línea de 2.5px abajo y
   el texto pasa a indigo. Está escrito en
   SofMic.Framework.Admin/scss/_sm-tabs.scss, bloque "LAS SOLAPAS DEL AREA DE
   CONTENIDO", y de ahí salen tal cual los seis colores y las cuatro medidas de
   este bloque.

   Acá el control es el mismo —CHRS.Framework.Controls.TabsContainer, 67
   pantallas— pero el vestido es el viejo: theme.css le pone a la solapa activa un
   "box-shadow: inset 0 4px 0 #3c8dbc", o sea una línea ARRIBA, más dos insets
   laterales que le dibujan los costados de la caja, y encima el fondo gris del
   body. Eso es lo que se lee como una pestaña de carpeta.

   TRES COSAS CAMBIAN, Y LAS TRES SON LA MISMA IDEA:

   1. La marca del activo pasa de ARRIBA a ABAJO. Una línea arriba separa la
      solapa del panel que está mostrando; una abajo la ata a él.

   2. La línea de abajo pasa de la TIRA a la CABECERA, pero SÓLO donde hay una
      cabecera (ver el bloque siguiente: la tira suelta conserva la suya).
      Dibujada por el <ul>, terminaba donde termina el <ul> —o sea donde empiezan
      los botones— y quedaba un tramo del ancho sin subrayar justo abajo de
      "Guardar", que se ve como si la cabecera estuviera cortada. La cabecera es
      la pieza que ocupa el ancho completo.

   3. La tira no se parte en dos renglones: se corre. .nav trae flex-wrap: wrap
      de Bootstrap, así que con seis solapas y cinco botones en la misma fila
      armaba una segunda fila y empujaba el contenido para abajo. Una tira de
      solapas es UNA línea por definición.

   NO SE PORTAN LAS FLECHAS de "esto sigue para el costado" que el GESTOR dibuja
   sobre la tira cuando desborda: son dos pseudos que prende y apaga
   SofMic.Navs.js midiendo scrollLeft contra scrollWidth, y sin ese JS la señal no
   existe. Queda para cuando se porte el JS.

   LAS PILLS QUEDAN AFUERA. Este bloque toca .nav-tabs solamente; el TabsContainer
   en DisplayType="Pills" sigue exactamente como está.

   EL SELECTOR VA DOBLE, y no es por las dudas. theme.css escribe lo suyo como
   ".my-tabs-container .nav-tabs.tabs-primary .nav-item .nav-link" —cinco clases,
   porque TabsContainer.vb le pega " tabs-primary" al <ul> SIEMPRE— así que un
   selector corto no le gana. El corto igual hace falta para la única tira de
   ISPBoss escrita a mano (Controles\ConceptosBuscador.ascx), que no vive adentro
   de ningún .my-tabs-container.

   Y EL box-shadow SE APAGA CON !important porque ahí theme.css llega a OCHO
   clases —la variante ":first-of-type" de has-error— y no hay selector razonable
   que le gane por especificidad.
   ============================================================================ */

/* LA LÍNEA POR DEFECTO ES DE LA TIRA, Y SÓLO SE MUDA CUANDO HAY CABECERA.

   Es el orden del GESTOR y no da lo mismo darlo vuelta. Una tira escrita a mano
   —el Buscador de Conceptos, que es un <ul class="nav nav-tabs"> suelto adentro
   de un modal— no tiene ningún .my-tabs-header donde apoyarse: si la línea se
   declara únicamente en la cabecera, esa tira se queda SIN subrayado y flotando
   sobre el contenido. Así que la línea es de la tira por defecto, y se le saca
   sólo adentro de un .my-tabs-container, que es donde hay una cabecera que la
   dibuja de punta a punta. */
.content-wrapper .nav-tabs {
    border-bottom: 1px solid #e2e8f0;
    background: transparent;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    /* EL stretch NO ES REDUNDANTE, aunque sea el default de un flex container.
       Medido en pantalla: con "overflow-x: auto" el <ul> se vuelve un contenedor
       de scroll y Chrome le reserva abajo los 4px de la barra horizontal —
       clientHeight 41 contra offsetHeight 45— así que la línea de flex mide 41 y
       las solapas se quedan ahí, mientras el <ul> mide 45 porque la cabecera lo
       estira a la altura de los botones. Resultado: el subrayado del activo
       quedaba 4px POR ENCIMA de la línea de la cabecera, flotando, que es
       exactamente lo que este port vino a arreglar. Con el stretch explícito el
       link llega hasta el fondo y el subrayado se apoya en la línea (medido:
       0px). */
    align-items: stretch;
}

/* Y ACÁ SE MUDA. Cuando el TabsContainer trae un <OptionsTemplate>, la cabecera
   son dos piezas: la tira y, a la derecha, los botones. Dibujada por la tira, la
   línea terminaba donde termina la tira —o sea donde empiezan los botones— y
   quedaba un tramo del ancho sin subrayar justo abajo de "Guardar", que se lee
   como si la cabecera estuviera cortada. La cabecera es la pieza que ocupa el
   ancho completo, así que la línea es suya. */
.content-wrapper .my-tabs-header {
    border-bottom: 1px solid #e2e8f0;
    align-items: stretch;
}

.content-wrapper .my-tabs-container .nav.nav-tabs {
    border-bottom: none;
}

/* La barra de scroll, discreta y sólo al pasar el mouse: una de 15px no sólo se
   ve, ALARGA la tira de solapas y empuja el contenido. */
.content-wrapper .nav-tabs::-webkit-scrollbar { height: 4px; }
.content-wrapper .nav-tabs::-webkit-scrollbar-track { background: transparent; }
.content-wrapper .nav-tabs::-webkit-scrollbar-thumb { background: transparent; border-radius: 4px; }
.content-wrapper .nav-tabs:hover::-webkit-scrollbar-thumb { background: #cbd5e1; }

/* El display:flex del <li> y del <a> no es decorativo: sin él el link conserva su
   alto de contenido, el aire que sobra le queda ABAJO, y el subrayado del activo
   flota separado de la línea de la cabecera en vez de apoyarse en ella. */
.content-wrapper .nav-tabs .nav-item,
.content-wrapper .my-tabs-container .nav.nav-tabs .nav-item {
    display: flex;
}

.content-wrapper .nav-tabs .nav-link,
.content-wrapper .my-tabs-container .nav.nav-tabs .nav-item .nav-link {
    display: flex;
    align-items: center;
    white-space: nowrap;
    border: none;
    border-bottom: 2.5px solid transparent;
    border-radius: 0;
    background: transparent;
    color: #64748b;
    font-weight: 500;
    font-size: .85rem;
    padding: .8rem 1rem;
    transition: color .15s, border-color .15s;
}

.content-wrapper .nav-tabs .nav-link:hover,
.content-wrapper .my-tabs-container .nav.nav-tabs .nav-item .nav-link:hover {
    color: #1e293b;
    border-bottom-color: #cbd5e1;
}

.content-wrapper .nav-tabs .nav-link.active,
.content-wrapper .my-tabs-container .nav.nav-tabs .nav-item .nav-link.active {
    color: #4338ca;
    border-bottom-color: #6366f1;
    background: transparent;
    font-weight: 600;
    /* La caja de la pestaña vieja: la línea azul de arriba y los dos insets que
       le dibujaban los costados. Ver arriba por qué va forzado. */
    box-shadow: none !important;
}

/* La solapa que tiene un campo inválido adentro se sigue marcando en rojo, con la
   misma gramática nueva: el color y el subrayado, no una línea arriba. */
.content-wrapper .nav-tabs .nav-link.has-error,
.content-wrapper .my-tabs-container .nav.nav-tabs .nav-item .nav-link.has-error {
    color: #dc2626;
}

.content-wrapper .nav-tabs .nav-link.has-error.active,
.content-wrapper .my-tabs-container .nav.nav-tabs .nav-item .nav-link.has-error.active {
    color: #dc2626;
    border-bottom-color: #dc2626;
}

.content-wrapper .nav-tabs .nav-link .badge { margin-left: 4px; }


/* ----------------------------------------------------------------------------
   LAS SOLAPAS QUE SE REPARTEN EL ANCHO SIGUEN CENTRADAS

   Son las de DisplayLayout="Justified" —33 pantallas: los filtros de dos o tres
   opciones tipo "Con deuda / Sin deuda / Todos"— y sin esto el port las rompía.

   Bootstrap 4 resuelve .nav-justified con "flex-basis: 0; flex-grow: 1;
   text-align: center" sobre el .nav-item, y eso alcanza mientras el .nav-link
   sea un bloque con texto en línea: el link llena la celda y el texto se centra
   solo. Pero acá el <li> pasó a ser display: flex —lo necesita para que la
   solapa llegue hasta el fondo de la tira y el subrayado se apoye en la línea—
   y eso cambia las dos cosas de una: el link deja de llenar la celda (en el eje
   principal un item flex no se estira, se encoge a su contenido) y el
   text-align deja de gobernarlo (en un contenedor flex manda justify-content).

   Medido antes de esta regla, en una tira de tres solapas dentro de 700px:
   celdas de 222.7px con la solapa midiendo 90.3 y arrancando en 0. O sea el
   rótulo pegado a la izquierda y el subrayado del activo cubriendo un tercio de
   su celda.

   EL GESTOR SÓLO NECESITA EL justify-content, y no es que se le haya olvidado la
   otra mitad: allá Bootstrap 5 declara ".nav-justified .nav-item .nav-link {
   width: 100% }", así que el link llena la celda por su cuenta. En Bootstrap
   4.3.1 esa regla no existe y hay que decirlo. Se dice con flex y no con
   width: 100% porque el link ya es un item flex: es la propiedad que gobierna
   de verdad su ancho.
   ---------------------------------------------------------------------------- */
.content-wrapper .nav-tabs.nav-justified .nav-link,
.content-wrapper .my-tabs-container .nav.nav-tabs.nav-justified .nav-item .nav-link {
    flex: 1 1 auto;
    justify-content: center;
}


/* ============================================================================
   LOS BOTONES DE LA FILA DE SOLAPAS RESPIRAN

   Se aplica sobre los TabsContainer que declaran CssClass="my-tabs-con-acciones",
   o sea los de la ficha del abonado. No es global: una tira sin botones no lo
   necesita y no hay por qué cambiarle la altura a las otras pantallas.

   POR QUE HACE FALTA, medido en pantalla: el TabsContainer de CHRS.Framework
   emite <div class="my-tabs-header d-flex"> sin padding, pegado al borde de la
   card, y al lado del <ul> de las solapas cuelga un <div> pelado con los botones.
   La fila la fija la tira, y el botón es más bajo: quedaba apretado contra el
   borde de arriba y el de abajo.

   Es el mismo trato del GESTOR (_sm-tabs.scss, "Y LOS BOTONES RESPIRAN"): el aire
   va en el contenedor de las ACCIONES, no en la cabecera. La solapa de al lado
   tiene .8rem de padding vertical, así que con .4rem el botón queda centrado
   contra ella sin estirar la cabecera.

   ANTES ESTO ERA OTRA COSA, y vale saber por qué cambió: se resolvía con padding
   en la cabecera más "align-self: flex-start" en el <ul>, porque el border-bottom
   que subraya las solapas era del <ul> y, al estirarse éste a la altura de la
   fila, el subrayado se despegaba de las solapas. Ahora la línea es de la
   cabecera (ver el bloque de arriba), así que el <ul> puede estirarse tranquilo:
   el subrayado del activo se apoya en la línea porque el .nav-link es flex y
   llega hasta el fondo de la tira.
   ============================================================================ */
.my-tabs-con-acciones > .my-tabs-header > div { padding: .4rem .6rem; }

/* ============================================================================
   CARTELES DE ESTADO — el alert de Bootstrap, con la paleta de la casa.

   POR QUÉ EXISTE: `alert-warning` es un amarillo pleno que grita por encima del
   dato. Es exactamente lo que este archivo ya corrigió para las cabeceras de
   card (ver el bloque de pasteles más arriba) y para los badges (rgba al 11-13%
   con texto oscuro saturado), pero los `.alert` habían quedado afuera.

   MISMOS HEX QUE LAS CABECERAS, a propósito. Un panel de aviso y una cabecera
   `bg-warning` en la misma pantalla tienen que ser el mismo amarillo; si cada
   uno trae el suyo, la pantalla se ve armada por dos personas distintas.

   AHORA SÍ PISA `.alert` GLOBAL (01/09/2026). Antes esto vivía sólo en
   `.ispboss-cartel`, que había que pedir explícitamente, porque cambiar todos
   los alerts del sistema de una es una decisión de producto. La decisión se
   tomó: eran 115 alerts crudos en 59 archivos —50 de ellos `alert-warning`— y
   pedir la clase pantalla por pantalla dejaba el sistema mezclado por tiempo
   indefinido. `ispboss-cartel` SIGUE EXISTIENDO y sigue siendo válida: ahora
   sólo aporta la geometría de la caja (padding y radio propios) y el pastel
   para el caso en que se use SIN la clase `.alert` de Bootstrap
   (Cobranzas/PagosDeclarados.aspx es el único hoy).

   ⚠ EL `!important` NO ES OPCIONAL Y NO ES DESPROLIJIDAD — es obligatorio.
   AdminLTE, dentro de `theme.css`, redefine

       .bg-warning, .alert-warning { background-color: #ffc107 !important; }   (línea ~5485)

   y lo mismo para primary/success/info/danger. Una regla sin `!important` acá
   NO haría absolutamente nada por más que ispboss.css cargue después: contra un
   `!important` no gana el orden. Por eso además el selector es `.alert.alert-X`
   (0,2,0) y no `.alert-X` (0,1,0): entre dos `!important` gana el más
   específico. Y al pedir las DOS clases, esto no toca a quien use `alert-X`
   como utilidad de color suelta.

   NO se tocan las `.bg-*`: AdminLTE las declara en el MISMO selector que las
   `.alert-*`, y las cabeceras de card ya tienen su propio tratamiento arriba.
   ============================================================================ */
.ispboss-cartel {
    border: 1px solid transparent;
    border-radius: .35rem;
    padding: .7rem .9rem;
}

.alert.alert-warning,   .ispboss-cartel.alert-warning   { background: linear-gradient(160deg,#fffbeb,#fef3c7) !important; color:#92400e !important; border-color:#fde68a !important; }
.alert.alert-danger,    .ispboss-cartel.alert-danger    { background: linear-gradient(160deg,#fef2f2,#fee2e2) !important; color:#991b1b !important; border-color:#fecaca !important; }
.alert.alert-success,   .ispboss-cartel.alert-success   { background: linear-gradient(160deg,#ecfdf5,#d1fae5) !important; color:#065f46 !important; border-color:#a7f3d0 !important; }
.alert.alert-info,      .ispboss-cartel.alert-info      { background: linear-gradient(160deg,#ecfeff,#cffafe) !important; color:#155e75 !important; border-color:#a5f3fc !important; }
.alert.alert-secondary, .ispboss-cartel.alert-secondary { background: linear-gradient(160deg,#f8fafc,#f1f5f9) !important; color:#334155 !important; border-color:#e2e8f0 !important; }

/* Los tres que AdminLTE NO pisa (no están en su lista de `.bg-*`), pero que sí
   se usan en el sistema: dark (11), light (2) y primary (1). Van igual, para
   que no queden tres carteles con el look viejo de Bootstrap en medio de los
   demás. Primary en azul y no en el celeste de AdminLTE (#3c8dbc), que contra
   los pasteles de esta paleta se lee como un info desteñido. */
.alert.alert-primary,   .ispboss-cartel.alert-primary   { background: linear-gradient(160deg,#eff6ff,#dbeafe) !important; color:#1e40af !important; border-color:#bfdbfe !important; }
.alert.alert-dark,      .ispboss-cartel.alert-dark      { background: linear-gradient(160deg,#f1f5f9,#e2e8f0) !important; color:#0f172a !important; border-color:#cbd5e1 !important; }
.alert.alert-light,     .ispboss-cartel.alert-light     { background: linear-gradient(160deg,#fcfcfd,#f8fafc) !important; color:#475569 !important; border-color:#e2e8f0 !important; }

/* El `hr` y el `alert-link` de Bootstrap traen su propio color por variante y
   quedan desafinados contra el pastel. Heredar es lo correcto: el link se
   distingue por el subrayado y el peso, no por otro tono. */
.alert.alert-warning hr, .alert.alert-danger hr, .alert.alert-success hr,
.alert.alert-info hr, .alert.alert-secondary hr, .alert.alert-primary hr,
.alert.alert-dark hr, .alert.alert-light hr { border-top-color: currentColor !important; opacity: .2; }

.alert .alert-link { color: inherit !important; text-decoration: underline; font-weight: 600; }

/* La X de cerrar de AdminLTE viene negra al 50%; sobre el pastel se ve sucia y
   además no acompaña al tono de la variante. */
.alert.alert-dismissible .close { color: inherit; opacity: .55; text-shadow: none; }
.alert.alert-dismissible .close:hover { opacity: .9; }

/* El ícono hereda el tono oscuro del pastel — con un color fijo se pierde
   contra el fondo claro, que es el mismo motivo por el que los íconos de las
   cabeceras pasaron a `inherit`. Y se achica: a `fa-2x` competía con el texto. */
.ispboss-cartel .ispboss-cartel-icono { color: inherit; opacity: .75; font-size: 1.35rem; }

/* La tarjeta de un comprobante cuyo archivo no se puede leer. Se muestra en vez del
   ícono de imagen rota del navegador, que no dice nada y se lee como un bug de la
   pantalla. El registro sigue a la vista a propósito: que la foto esté declarada y el
   archivo falte es un dato, no algo para esconder. La prende el `onerror` del <img>. */
.ispboss-comprobante-roto {
    display: none;
    align-items: center;
    justify-content: center;
    width: 190px; height: 130px;
    border: 1px dashed #cbd5e1;
    border-radius: .35rem;
    background: #f8fafc;
    color: #64748b;
    font-size: .85rem;
}

/* =============================================================
   ZONA PARA SOLTAR UN ARCHIVO
   =============================================================
   04/09/2026, para la Bandeja de Ingesta de Cobranzas. El borde punteado es lo
   que dice "acá se suelta" sin tener que escribirlo: es la convención de
   cualquier gestor de archivos, y es la razón de que sea punteado y no sólido
   -un borde sólido se lee como una tarjeta más de la pantalla-.

   Sirve para cualquier pantalla que quiera recibir un archivo arrastrado; el JS
   que la maneja engancha por la clase `.ispboss-dropzone`, no por un ID. */
.ispboss-dropzone {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .75rem;
    padding: 1rem 1.25rem;
    border: 2px dashed #cbd5e1;
    border-radius: .35rem;
    background: #f8fafc;
    transition: border-color .15s ease, background-color .15s ease;
}

.ispboss-dropzone-icono { font-size: 1.75rem; color: #94a3b8; }

.ispboss-dropzone-texto { flex: 1 1 14rem; }

/* min-width para que el custom-file de Bootstrap no colapse a cero cuando la
   fila se aprieta: sin esto, en una pantalla angosta el input queda de un par
   de píxeles y el botón Buscar no se puede tocar. */
.ispboss-dropzone-controles {
    display: flex;
    align-items: center;
    flex: 0 1 26rem;
    min-width: 16rem;
}

.ispboss-dropzone-controles .custom-file { flex: 1 1 auto; }

/* El boton NO se encoge y NO parte el texto. Sin esto el flex le come el ancho
   para darselo al input y "Subir" cae abajo del icono, en dos renglones. */
.ispboss-dropzone-controles .btn { flex: 0 0 auto; white-space: nowrap; }

/* Mientras el archivo está encima. La clase la pone y la saca el JS de la
   pantalla; el color es el mismo azul de `card-info` para que el resaltado se
   lea como "esto te está esperando" y no como un error. */
.ispboss-dropzone.soltando {
    border-color: #17a2b8;
    background: #e8f6f8;
}

.ispboss-dropzone.soltando .ispboss-dropzone-icono { color: #17a2b8; }


/* =============================================================
   EL BOTON DE REPORTES DE LA BARRA: contorno, y las dos mitades unidas
   =============================================================
   03/09/2026, reportado mirando `Cobranzas\BloquesIngresos`: en la fila del
   titulo la lupa y el "+ Nuevo" son de contorno y en el medio quedaban DOS
   bloques gris oscuro, que ademas se veian como dos pastillas pegoteadas en
   vez de un boton partido.

   Es `uc:OpcionesReportes` (`Controles\OpcionesReportes.ascx`), y se quedo
   afuera del pase a contorno del 27/08 por tres motivos que se suman:

   1. COLOR. Sus dos botones traen `btn-secondary` escrito a mano EN EL MARKUP
      DEL CONTROL, y sus IDs son `btnDefault` / `btnDropdown`. Las reglas del
      pase anclan por ID -`btnBuscar`, `btnNuevo`, `btnCancelar`- asi que
      ninguna lo alcanzaba, y se quedaba con el `#64748b` pleno de la regla
      `.btn-secondary` de mas arriba de este archivo. Era el unico solido de
      la fila.

   2. ESQUINAS. `.btn { border-radius: 9.6px !important }` (mas arriba, bloque
      "Botones"). Las reglas de Bootstrap que enderezan las esquinas internas
      de un `.btn-group` -`_button-group.scss`, "Reset rounded corners"- NO
      llevan `!important`, asi que PIERDEN: las dos mitades quedaban redondeadas
      por los cuatro lados y el `margin-left: -1px` del grupo las superponia.
      Ese mordisco entre las dos es lo que se veia. Por eso hay que reponerlo
      con `!important`: es un `!important` de este mismo archivo el que lo pisa,
      no Bootstrap.

   3. ANCHO DE LA FLECHA. `.my-page-actions .btn { min-width: 2.25rem; padding:
      .35rem .6rem !important }` le gana al `padding: .5625rem` que Bootstrap le
      da a `.dropdown-toggle-split`, asi que la flechita quedaba tan ancha como
      un boton entero en vez de ser una pestania.

   EL COLOR ES EL DE `btn-outline-secondary` (#6c757d), no el de la lupa
   (#cbd5e1). No es de gusto: el control hermano `uc:BotonReportes` esta en 25
   pantallas y TODAS las que renderizan le pasan `btn-outline-secondary` desde
   el markup -queda un `btn-secondary` solido en `Abonados\AbonadosEstadistica`,
   pero adentro de un `<%-- --%>`, o sea que no se dibuja-. O sea que el boton
   de reportes de esta fila YA tiene un look, y este control era el UNICO que no
   lo seguia. Mismo criterio que el Cerrar de los modales, mas abajo.

   VA POR ID Y NO POR `:has()` A PROPOSITO: `btnDefault` y `btnDropdown` son
   unicos en todo el Web -solo existen en este control- y asi anda tambien en
   navegadores sin `:has()`. Es el idioma que ya usa el resto del archivo.

   ⚠ EL GUARD `.btn-group >` NO ES DECORATIVO. Cuando la pantalla no declara
   ningun `<uc:ReporteItem>`, el codebehind apaga `btnDropdown` y NO le pone
   `btn-group` al contenedor (`OpcionesReportes.ascx.vb`, "If btnDropdown.Visible").
   Ahi `btnDefault` queda solo y tiene que conservar sus cuatro esquinas
   redondeadas; sin el guard le aplastariamos el lado derecho contra la nada.

   Alcance: 63 pantallas, y las 63 lo tienen adentro del `<DefaultActionsTemplate>`,
   asi que acotarlo a `.my-page-actions` las cubre a todas. (Son 65 archivos si se
   cuenta con grep a secas: `Comunicaciones\Templates` y `Tablas\PlanesComerciales`
   lo tienen SOLO adentro de un `<%-- --%>`. Al contar usos de un control en este
   sistema hay que sacar los bloques comentados primero, o el numero miente.)
   (`CHRS.TvCloud.Portal.Web` tiene su propia copia del control y su propio CSS:
   no se toca desde aca.) */
.my-page-actions .btn[id$="btnDefault"],
.my-page-actions .btn[id$="btnDropdown"] {
    background-color: transparent !important;
    border-color: #6c757d !important;
    color: #6c757d !important;
}
.my-page-actions .btn[id$="btnDefault"]:hover,
.my-page-actions .btn[id$="btnDropdown"]:hover,
.my-page-actions .btn[id$="btnDropdown"]:focus,
.my-page-actions .btn-group.show > .btn[id$="btnDropdown"] {
    background-color: #6c757d !important;
    border-color: #6c757d !important;
    color: #fff !important;
}

/* Las esquinas internas, planas: vuelve a ser UN boton partido y no dos. */
.my-page-actions .btn-group > .btn[id$="btnDefault"] {
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
}
.my-page-actions .btn-group > .btn[id$="btnDropdown"] {
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
}

/* La flecha es una pestania, no un boton: se le saca el `min-width` de la fila
   y se le devuelve el padding angosto de `.dropdown-toggle-split`. */
.my-page-actions .btn-group > .btn[id$="btnDropdown"] {
    min-width: 0 !important;
    padding-left: .45rem !important;
    padding-right: .45rem !important;
}


/* ============================================================================
   BANDA DE SECCIÓN DENTRO DE UNA TARJETA (`.card-subheader`)
   ============================================================================
   14/09/2026. Port de `SofMic.Framework.Admin\scss\_cards.scss`. En el GESTOR
   es el par `card-subheader` + `h3.card-title` con el que toda ficha separa
   sus secciones (Contacto y Empresa, Datos de la Oportunidad, Registrar
   actividad...). ISPBoss ya la escribía en Conversaciones\Configuracion.aspx
   pero NINGUNA hoja la definía: se dibujaba como un `card-header` más.

   Es una banda, no una cabecera: más baja, gris muy claro, título chico. Se
   usa en las fichas de Oportunidades e Interesados, adentro de las solapas. */
/* 16/09/2026: AL DÍA CON EL GESTOR (`SofMic.Framework.Admin\scss\_sm-card-subheader.scss`).
   El port del 14/09 era de una versión anterior: título en minúsculas y con ícono violeta.
   La banda de hoy lleva el rótulo EN MAYÚSCULAS con aire entre letras, fondo #f4f6fa y SIN
   ícono -la banda ya dice qué sección es; el ícono sumaba ruido a cada renglón-. Los botones
   de la banda vuelven a letra normal. */
.card-subheader {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    padding: .4rem .8rem;
    background: #f4f6fa;
    color: #475569;
    font-size: .8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    border-top: 1px solid #e8edf4;
    border-bottom: 1px solid #e8edf4;
    border-radius: 0;
}
/* Pegada al borde de arriba de su contenedor no repite la línea: la solapa o
   la tira de arriba ya la dibujan. */
.card-subheader:first-child,
.tab-body > .card-subheader:first-child,
.tab-body > div > .card-subheader:first-child { border-top: 0; }
.card-subheader > i,
.card-subheader > .card-title > i { display: none; }
.card-subheader .card-title {
    float: none;
    margin: .4rem 0;
    font-size: .8rem;
    font-weight: 700;
    color: #334155;
}
.card-subheader .btn,
.card-subheader .dropdown-menu { text-transform: none; letter-spacing: normal; }
.card-subheader .btn { margin: .15rem 0; }
.card-subheader .btn + .btn { margin-left: .5rem; }

/* ── LA SECCIÓN PLEGABLE: `cc:CollapsableBox` con banda `card-subheader` ── */
/* Como las secciones de un comprobante del GESTOR (Detalles, Comercial, Económico...):
   una banda al ras -no una tarjeta flotante adentro de otra-, con el "−/+" a la IZQUIERDA,
   toda la banda clickeable, y una línea de 3px al costado que se enciende en violeta cuando
   la sección está abierta o bajo el mouse. En el GESTOR es la regla de
   `.sm-collapsable-box` del mismo `_sm-card-subheader.scss`.

   ACOTADO A LAS CAJAS CON BANDA (`:has(> .card-subheader)`): el mismo control se usa en la
   configuración de Facturación con otro encabezado (una pastilla), y esas no se tocan.

   El control de ISPBoss dibuja el botón DESPUÉS del título, flotando a la derecha
   (`CHRS.Framework.Controls\CollapsableBox.vb`); el del GESTOR lo dibuja antes. Acá se lo
   trae a la izquierda con `order: -1` -la banda es flex-, sin tocar el framework. Y la banda
   entera se vuelve el área de click con un `::after` que la cubre, que es lo que hace el
   `stretched-link` del GESTOR: un click sobre el pseudo le llega al botón. Los botones que
   la banda tenga a la derecha ("Cargar Reserva Puerto" en Órdenes) se suben por encima de
   esa capa, si no quedarían tapados. */
/* Los !important no son capricho: la regla general `.card` del principio de esta hoja pone
   `border: none`, `border-radius: 12px` y sombra, todo con !important, y como esta hoja carga
   después de Bootstrap le gana hasta a `rounded-0` y `shadow-none`. Sin esto la línea de
   color no aparecía (medido: `border-left: 0px none`) y cada sección era una tarjeta
   redondeada con sombra. El selector pesa más que `.card`, así que gana. */
.my-collapsable-box.card:has(> .card-subheader) {
    margin-bottom: 0;
    border: 0 !important;
    border-left: 3px solid #c7d2fe !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    transition: border-left-color .12s ease-in-out;
}
.my-collapsable-box.card:has(> .card-subheader):hover,
.my-collapsable-box.card:has(> .card-subheader):not(.collapsed-card) { border-left-color: #6366f1 !important; }
.my-collapsable-box > .card-subheader { position: relative; padding-left: .4rem; }
.my-collapsable-box > .card-subheader > .card-tools {
    order: -1;
    float: none;
    margin: 0 .2rem 0 0;
}
.my-collapsable-box > .card-subheader > .card-tools > .btn-tool {
    /* STATIC, o la capa de abajo no cubre la banda: el botón viene con position:relative y
       el ::after se anclaba a él. Medido: la capa medía 23x20, el botón, en vez de la banda. */
    position: static;
    padding: .15rem .45rem;
    color: #64748b;
    font-size: .75rem;
}
.my-collapsable-box > .card-subheader > .card-tools > .btn-tool::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
}
.my-collapsable-box > .card-subheader .btn:not(.btn-tool),
.my-collapsable-box > .card-subheader a:not(.btn-tool),
.my-collapsable-box > .card-subheader input,
.my-collapsable-box > .card-subheader select { position: relative; z-index: 2; }
.my-collapsable-box:has(> .card-subheader) > .card-body { border-bottom: 1px solid #e8edf4; }


/* ============================================================================
   FICHA DE OPORTUNIDAD / INTERESADO: la tira de trabajo y el feed
   ============================================================================
   Comercial\Oportunidades.aspx e Interesados\Default.aspx. La ficha es UNA
   tarjeta con solapas -el esquema del Centro de Oportunidades del GESTOR-:
   cabecera, la tira de la próxima acción y las solapas. */

/* La tira: entre la cabecera y las solapas, un renglón que dice qué hay que
   hacer y cuándo. El semáforo lo pone el badge (danger / warning / info). */
.my-proxima-accion { background: #fafbfd; }
.my-proxima-accion .h5 { font-weight: 700; color: #1e293b; }

/* El mapa de la ficha del interesado vive en una columna al lado del
   domicilio, no debajo. Alto fijo: sin alto Google Maps dibuja 0px. */
.my-mapa-ficha { height: 360px; }

/* EL FEED (port de `.act-feed` del Centro de Oportunidades). Historial como
   lista alineada y no como la línea de tiempo de AdminLTE: el riel vertical
   con los círculos grandes metía mucho aire entre ítems y desalineaba la fecha
   de la nota. Cada contacto es una fila con el mismo grid -ícono, tipo, cuándo
   y quién, la nota, y lo que quedó agendado ESE día-, agrupadas por mes. */
.my-feed { padding-top: .75rem; }
.my-feed-periodo {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 14px 0 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #94a3b8;
}
.my-feed-periodo:first-child { margin-top: 0; }
.my-feed-periodo::after { content: ""; flex: 1 1 auto; height: 1px; background: #e2e8f0; }
.my-feed-item {
    display: flex;
    gap: 10px;
    padding: 8px 6px;
    border-bottom: 1px solid #f1f5f9;
}
.my-feed-item:hover { background: #f8fafc; }
.my-feed-item:last-child { border-bottom: 0; }
.my-feed-icono {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(59, 130, 246, .12);
    color: #1d4ed8;
    text-align: center;
    line-height: 28px;
    font-size: 12px;
}
.my-feed-cuerpo { flex: 1 1 auto; min-width: 0; }
.my-feed-cab { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.my-feed-tipo { font-weight: 600; font-size: 12.5px; color: #1e293b; }
.my-feed-cuando { margin-left: auto; font-size: 11px; color: #94a3b8; white-space: nowrap; }
.my-feed-nota { font-size: 12.5px; color: #334155; white-space: pre-line; margin-top: 1px; }
.my-feed-agenda {
    display: inline-block;
    margin-top: 4px;
    padding: 1px 7px;
    border-radius: 3px;
    background: #f1f5f9;
    font-size: 11px;
    color: #64748b;
}


/* ============================================================================
   EMBUDO COMERCIAL (`Comercial/Embudo.aspx`)
   ============================================================================
   14/09/2026. El tablero se rehízo con la gramática del Embudo del GESTOR
   (SofMic.GESTOR.Admin\Oportunidades\Embudo.aspx): columna gris con la
   cabecera del color de la etapa, tarjetas blancas con el semáforo de la
   próxima acción en el borde izquierdo, columna vacía punteada, y señal
   visual al arrastrar. Ya no son `card` de AdminLTE: la columna tiene su
   propia geometría.

   Lo único que sigue inline es el color de la etapa, y no se puede evitar:
   sale de `WebOportunidadesEtapas.Color`, es dato de la base. Viaja como
   variable CSS (`--etapa-color`) en el `style=` de la columna.

   EL SCROLL ES DEL TABLERO Y NO DE LA PAGINA. Con diez etapas configuradas el
   body scrollearía de costado y se llevaría la cabecera y el menú con él; así
   el que se mueve es el carril y el resto de la pantalla se queda quieto. */
.my-embudo-scroll {
    overflow-x: auto;
    overflow-y: hidden;
    padding: 2px 2px 14px;
    scroll-behavior: smooth;
}

/* `min-content` para que el carril mida lo que miden sus columnas y no lo que
   mide el contenedor: sin esto las columnas se comprimirían en vez de generar
   el scroll. */
.my-embudo-pista {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    min-width: min-content;
    min-height: 420px;
}

/* Ancho FIJO, no elástico: una columna que se ensancha cuando el ISP tiene tres
   etapas y se angosta cuando tiene diez hace que la misma tarjeta se lea
   distinto en cada instalación. */
.my-embudo-columna {
    flex: 0 0 310px;
    width: 310px;
    display: flex;
    flex-direction: column;
    background: #f4f5f7;
    border: 1px solid #e3e6e9;
    border-radius: 7px;
    max-height: calc(100vh - 21rem);
    min-height: 360px;
    transition: box-shadow .15s, border-color .15s;
}
/* La columna sobre la que se está por soltar. La clase la pone el JS del
   tablero en `dragover` y la saca en `dragleave`/`drop`. */
.my-embudo-columna.is-destino {
    border-color: #6366f1;
    box-shadow: 0 0 0 2px rgba(99, 102, 241, .25);
}

/* LA CABECERA LLEVA EL COLOR DE LA ETAPA como fondo y no como un hilo de 3px:
   es lo que hace que el tablero se lea como un embudo y no como una fila de
   tarjetas iguales. Letra blanca con sombra, porque el color lo elige el ISP y
   puede ser claro. */
.my-embudo-cabecera {
    position: sticky;
    top: 0;
    z-index: 3;
    padding: 9px 11px;
    border-radius: 6px 6px 0 0;
    background: var(--etapa-color, #64748b);
    color: #fff;
    text-shadow: 0 1px 1px rgba(0, 0, 0, .2);
    box-shadow: 0 1px 0 rgba(0, 0, 0, .08);
}
.my-embudo-titulo {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-weight: 700;
    font-size: 13px;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.my-embudo-titulo > span:first-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
.my-embudo-cantidad {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    min-width: 21px;
    height: 19px;
    padding: 0 6px;
    border-radius: 10px;
    background: rgba(0, 0, 0, .22);
    font-size: 10.5px;
    font-weight: 700;
    text-shadow: none;
}
.my-embudo-sub {
    display: flex;
    justify-content: space-between;
    gap: 6px;
    margin-top: 2px;
    font-size: 10.5px;
    opacity: .92;
}
.my-embudo-sub b { font-weight: 700; }

/* El cuerpo scrollea SOLO en vertical y con tope: son hasta 25 tarjetas por
   columna (`TarjetasPorColumna`), y sin tope la columna más cargada estira el
   tablero entero y desalinea las cabeceras del resto. */
.my-embudo-lista {
    flex: 1 1 auto;
    min-height: 80px;
    padding: 8px;
    overflow-y: auto;
}

/* LA TARJETA. El borde izquierdo es el semáforo de la próxima acción: se ve
   sin leer la tarjeta. Las clases `es-*` las calcula el codebehind
   (`EstadoAccion`). */
.my-embudo-tarjeta {
    position: relative;
    background: #fff;
    border: 1px solid #dee2e6;
    border-left: 4px solid #ced4da;
    border-radius: 6px;
    padding: 8px 9px;
    margin-bottom: 8px;
    font-size: 12px;
    cursor: grab;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
    transition: box-shadow .15s, transform .15s, border-color .15s, opacity .15s;
}
.my-embudo-tarjeta:last-child { margin-bottom: 0; }
.my-embudo-tarjeta:hover {
    border-color: #adb5bd;
    box-shadow: 0 4px 12px rgba(0, 0, 0, .12);
    transform: translateY(-1px);
}
.my-embudo-tarjeta:active { cursor: grabbing; }
/* La que se está arrastrando se atenúa en su lugar: así se ve de dónde salió. */
.my-embudo-tarjeta.is-arrastrando { opacity: .4; }

.my-embudo-tarjeta.es-vencida { border-left-color: #dc3545; }
.my-embudo-tarjeta.es-hoy     { border-left-color: #fd7e14; }
.my-embudo-tarjeta.es-pronto  { border-left-color: #ffc107; }
.my-embudo-tarjeta.es-futura  { border-left-color: #ced4da; }
.my-embudo-tarjeta.es-sin     { border-left-color: #adb5bd; border-left-style: dashed; }

/* El título es un link pero no tiene que parecer uno: dentro de una tarjeta
   arrastrable el subrayado se lee como que el gesto es "click" y no
   "arrastrar". */
.my-embudo-tarjeta-titulo {
    display: block;
    font-weight: 600;
    font-size: 12.5px;
    line-height: 1.25;
    color: #212529;
}
.my-embudo-tarjeta-titulo:hover { color: #2563eb; text-decoration: none; }
.my-embudo-tarjeta-quien {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 3px;
    color: #495057;
    line-height: 1.3;
}
.my-embudo-tarjeta-quien > span:first-of-type {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.my-embudo-tarjeta-quien .badge { flex: 0 0 auto; font-size: 9.5px; }

.my-embudo-tarjeta-linea {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 8px;
    margin-top: 7px;
}
.my-embudo-tarjeta-accion { min-width: 0; font-size: 11.5px; line-height: 1.25; }
.my-embudo-tarjeta-accion-fecha {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 2px 5px;
    border-radius: 3px;
    background: #f1f3f5;
    white-space: nowrap;
}
.my-embudo-tarjeta-accion.es-vencida { color: #dc3545; font-weight: 600; }
.my-embudo-tarjeta-accion.es-hoy     { color: #fd7e14; font-weight: 600; }
.my-embudo-tarjeta-accion.es-pronto  { color: #b8860b; font-weight: 600; }
.my-embudo-tarjeta-accion.es-futura  { color: #6c757d; }
.my-embudo-tarjeta-accion.es-sin     { color: #6c757d; font-style: italic; }
.my-embudo-tarjeta-importe { font-weight: 700; white-space: nowrap; }
.my-embudo-tarjeta-nota {
    margin-top: 3px;
    color: #59636e;
    font-size: 11px;
    line-height: 1.25;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Quién la tiene, como chip al pie y separado por una línea punteada, igual que
   los chips del Embudo del GESTOR. */
.my-embudo-tarjeta-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 8px;
    align-items: center;
    margin-top: 6px;
    padding-top: 5px;
    border-top: 1px dashed #e9ecef;
    color: #868e96;
    font-size: 10.5px;
}
.my-embudo-chip { background: #f1f3f5; border-radius: 3px; padding: 0 5px; color: #6c757d; }

/* La columna vacía dice que se puede soltar acá: es el único lugar del tablero
   donde no hay ninguna tarjeta que insinúe el gesto. */
.my-embudo-vacia {
    text-align: center;
    color: #adb5bd;
    font-size: 11.5px;
    padding: 14px 6px;
    border: 1px dashed #dee2e6;
    border-radius: 5px;
}

@media (max-width: 767.98px) {
    .my-embudo-columna { flex-basis: 86vw; width: 86vw; max-height: calc(100vh - 16rem); }
}

/* =========================================================================
   TIMELINE SUAVE (`.timeline-suave`): Mis últimas acciones del home y los timelines de Comprobantes e Histórico de estados de la ficha del abonado
   El `.timeline` de AdminLTE tal como viene está pensado para ocupar una
   página: círculos de 30px pintados a pleno, rótulo de fecha rojo saturado,
   títulos de 16px y cajas con sombra. En la columna lateral del home quedaba
   más grande y más fuerte que las tarjetas vecinas ("Actividad del equipo
   hoy"), así que acá se lleva a esa misma escala: 0.82 / 0.78 / 0.7rem.
   El color del módulo llega por `--c` y se usa con la misma fórmula que
   `badge-suave` (13% de tinte sobre blanco, ícono en el tono oscuro).
   ========================================================================= */
.timeline.timeline-suave { margin: 0; }
.timeline.timeline-suave::before { left: 13px; width: 2px; background: #e9ecef; }
.timeline.timeline-suave > div { margin: 0 0 8px; }
.timeline.timeline-suave > .time-label { margin: 4px 0 10px; }
.timeline.timeline-suave > .time-label > .badge { font-size: 0.72rem; padding: 4px 8px; }

.timeline.timeline-suave > div > .tl-ico {
    --c: #64748b;
    left: 0;
    width: 26px;
    height: 26px;
    line-height: 26px;
    font-size: 11px;
    background: rgba(100,116,139,.13);
    color: #475569;
    box-shadow: 0 0 0 3px #fff;   /* separa el círculo de la línea vertical */
}
@supports (background: color-mix(in srgb, red 13%, white)) {
    .timeline.timeline-suave > div > .tl-ico {
        background: color-mix(in srgb, var(--c) 13%, #fff);
        color: color-mix(in srgb, var(--c) 72%, #1e293b);
    }
}

.timeline.timeline-suave > div > .timeline-item {
    margin: 0 0 0 36px;
    box-shadow: none;
    background: transparent;
    border-bottom: 1px solid #f1f3f5;
    padding-bottom: 6px;
    overflow-wrap: anywhere;
}
.timeline.timeline-suave > div:last-child > .timeline-item { border-bottom: 0; }
.timeline.timeline-suave > div > .timeline-item > .timeline-header {
    border: 0;
    padding: 3px 0 0;
    font-size: 0.82rem;
    line-height: 1.25;
}
.timeline.timeline-suave > div > .timeline-item > .timeline-header > a { color: #343a40; }
.timeline.timeline-suave > div > .timeline-item > .timeline-header > a:hover { color: #007bff; }
.timeline.timeline-suave .tl-hora { color: #adb5bd; font-size: 0.7rem; font-weight: 400; margin-top: 2px; }
.timeline.timeline-suave > div > .timeline-item > .timeline-body { padding: 2px 0 0; }
.timeline.timeline-suave .timeline-body ul { margin: 0; padding-left: 14px; color: #6c757d; font-size: 0.78rem; }

/* =========================================================================
   TARJETAS PASTEL (`.tarjetas-pastel`): el home (Usuarios/Default.aspx) y la solapa Resumen del abonado (Abonados/Default.aspx)
   Todas las tarjetas del home van con el patrón de la ficha del abonado:
   cabecera blanca, título oscuro e ícono de color, con una línea de acento
   de 3px ARRIBA en las tarjetas anchas (`card card-*`) y a la IZQUIERDA en
   las cajas angostas (`home-acento-izq home-acento-<color>`).
   A diferencia de la ficha, acá la línea y el ícono van en pastel (300 y 400
   de la misma paleta que las líneas globales de `card-*`). Se acota a
   `.tarjetas-pastel` a propósito: las reglas globales de `card-*` las usan ~26
   tarjetas del producto y no se tocan desde acá.
   ========================================================================= */
.tarjetas-pastel .card.card-primary:not(.card-outline)   { border-top-color: #a5b4fc !important; }
.tarjetas-pastel .card.card-info:not(.card-outline)      { border-top-color: #67e8f9 !important; }
.tarjetas-pastel .card.card-success:not(.card-outline)   { border-top-color: #6ee7b7 !important; }
.tarjetas-pastel .card.card-danger:not(.card-outline)    { border-top-color: #fca5a5 !important; }
.tarjetas-pastel .card.card-warning:not(.card-outline)   { border-top-color: #fcd34d !important; }
.tarjetas-pastel .card.card-secondary:not(.card-outline) { border-top-color: #cbd5e1 !important; }
.tarjetas-pastel .card.card-primary:not(.card-outline)   > .card-header .card-title i { color: #818cf8 !important; }
.tarjetas-pastel .card.card-info:not(.card-outline)      > .card-header .card-title i { color: #22d3ee !important; }
.tarjetas-pastel .card.card-success:not(.card-outline)   > .card-header .card-title i { color: #34d399 !important; }
.tarjetas-pastel .card.card-danger:not(.card-outline)    > .card-header .card-title i { color: #f87171 !important; }
.tarjetas-pastel .card.card-warning:not(.card-outline)   > .card-header .card-title i { color: #fbbf24 !important; }
.tarjetas-pastel .card.card-secondary:not(.card-outline) > .card-header .card-title i { color: #94a3b8 !important; }
/* El `card-title` de AdminLTE es de 1.1rem: al lado de las grillas del home
   quedaba grande. Una sola escala para todas las cabeceras de la página. */
.tarjetas-pastel .card > .card-header { padding: .55rem 1rem; }
.tarjetas-pastel .card > .card-header .card-title { font-size: .9rem; }

/* Cajas angostas: acento a la izquierda. El `!important` en el color le gana
   al `border-left-color` que el code-behind escribe inline en el panel
   Resumen (rojo o verde saturado). */
.tarjetas-pastel .home-acento-izq { border-left: 3px solid #cbd5e1 !important; }
.tarjetas-pastel .home-acento-indigo { border-left-color: #a5b4fc !important; }
.tarjetas-pastel .home-acento-amber  { border-left-color: #fcd34d !important; }
.tarjetas-pastel .home-acento-green  { border-left-color: #6ee7b7 !important; }
.tarjetas-pastel .home-acento-slate  { border-left-color: #cbd5e1 !important; }
.tarjetas-pastel .home-acento-red    { border-left-color: #fca5a5 !important; }
.tarjetas-pastel .home-acento-indigo small > i { color: #818cf8; }
.tarjetas-pastel .home-acento-amber  small > i { color: #fbbf24; }
.tarjetas-pastel .home-acento-green  small > i { color: #34d399; }

/* Filas de Alertas y Reportes: la misma escala que "Actividad del equipo hoy"
   (0.82 / 0.78 / 0.7rem), con separador fino en vez de <hr>. */
.home-lista-item { padding: .5rem 1rem; border-bottom: 1px solid #f1f3f5; font-size: .82rem; }
.home-lista-item:last-child { border-bottom: 0; }
.home-lista-titulo { font-weight: 600; color: #343a40; line-height: 1.3; }
.home-lista-titulo .badge { font-size: .68rem; vertical-align: 1px; }
.home-lista-texto { color: #6c757d; font-size: .78rem; margin-top: 2px; }
.home-lista-fecha { color: #adb5bd; font-size: .7rem; }

/* --- TARJETAS PASTEL: agregados de la solapa Resumen del abonado ----------- */
/* Cajas KPI: la línea de la izquierda en el pastel de su familia. Sólo acá
   adentro; en Facturación y demás tableros siguen con el tono medio. */
.tarjetas-pastel .home-kpi-indigo { --kpi: #a5b4fc; }
.tarjetas-pastel .home-kpi-green  { --kpi: #6ee7b7; }
.tarjetas-pastel .home-kpi-cyan   { --kpi: #67e8f9; }
.tarjetas-pastel .home-kpi-blue   { --kpi: #93c5fd; }
.tarjetas-pastel .home-kpi-teal   { --kpi: #5eead4; }
.tarjetas-pastel .home-kpi-amber  { --kpi: #fcd34d; }
.tarjetas-pastel .home-kpi-red    { --kpi: #fca5a5; }
.tarjetas-pastel .home-kpi-slate  { --kpi: #cbd5e1; }

.tarjetas-pastel .my-gridview-limpia { font-size: .8rem; }
.tarjetas-pastel .card-subheader .card-title { font-size: .72rem; }
.tarjetas-pastel .card-body > .btn-link { font-size: .8rem; }
.abonado-os-grupo { background: #f8fafc; padding: .35rem .75rem; font-size: .75rem; color: #64748b; border-top: 1px solid #f1f5f9; }
.abonado-card-nota { background: #fff !important; border-top: 1px solid #f1f5f9; font-size: .72rem; color: #94a3b8; text-align: center; padding: .4rem .75rem; }

/* Timeline suave con detalle (Comprobantes): rubros, renglones y total. */
.timeline.timeline-suave .timeline-body { font-size: .78rem; color: #6c757d; }
.timeline.timeline-suave .timeline-body dt { font-weight: 600; color: #475569; margin-top: 2px; }
.timeline.timeline-suave .timeline-body .fa-circle { font-size: .5rem; vertical-align: 2px; }
.timeline.timeline-suave > div > .timeline-item > .timeline-footer { padding: 2px 0 0; font-size: .78rem; color: #343a40; }
.timeline.timeline-suave .timeline-header .badge { font-size: .68rem; }

/* =========================================================================
   ABONADO: SCORE COMPACTO (Abonados/Controles/AbonadoPaneScoring.ascx)
   Medidor chico a la izquierda y puntaje al lado; antes el semicírculo
   ocupaba todo el ancho de la tarjeta y el número iba abajo en un h1.
   ========================================================================= */
.abonado-score-gauge { width: 120px; flex-shrink: 0; }
.abonado-score-valor { font-size: 1.3rem; font-weight: 700; line-height: 1.1; }
.abonado-score-fecha { font-size: .7rem; color: #94a3b8; margin-top: 2px; }
.abonado-score-ia { font-size: .75rem; color: #475569; margin-top: 4px; }
.abonado-score-tabla { font-size: .75rem; }
.abonado-score-tabla th { font-size: .7rem; font-weight: 600; color: #94a3b8; border-bottom: 1px solid #f1f5f9; }
.abonado-score-tabla th i { opacity: .6; }
.abonado-score-tabla .badge { font-size: .68rem; min-width: 1.6rem; }

/* =========================================================================
   ABONADO: TARJETAS PASTEL (Abonados/Default.aspx, `.tarjetas-pastel`)
   Hasta el 23/09/2026 este bloque tenía también la "ficha pastel", un override
   de AbonadoFicha.ascx sólo para esta pantalla (cabecera blanca, filas a
   0.82rem). Se sacó: la ficha se ve igual en las doce pantallas que la usan, con
   el estilo base de "AbonadoFicha — header moderno", más arriba.
   ========================================================================= */

/* Línea de Vida del Abonado: no lleva `card-secondary` porque AdminLTE blanquea
   los <a> de la cabecera de esas cards (y "Cargar" y los chips son links). El
   acento y el título se le dan acá, iguales a los de una `card-secondary`. */
.tarjetas-pastel .card.vtl-card { border-top: 3px solid #cbd5e1 !important; }
.tarjetas-pastel .card.vtl-card > .card-header { background: #fff; border-bottom: 1px solid rgba(0,0,0,.06); }
.tarjetas-pastel .card.vtl-card > .card-header .card-title { color: #334155; font-weight: 600; }
.tarjetas-pastel .card.vtl-card > .card-header .card-title i { color: #94a3b8; }

/* Timeline de Comprobantes del abonado (AbonadoComprobantesTimeline.ascx).
   Renglones del detalle: código de ancho FIJO para que todas las descripciones
   arranquen en la misma vertical; lo que no entra se corta con "…" y se lee
   completo en el `title`. El importe, a la derecha. */
.comp-renglon { display: flex; align-items: baseline; gap: 8px; line-height: 1.45; }
.comp-renglon .comp-cod { flex: 0 0 5.5rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.comp-renglon .comp-desc { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.comp-renglon .comp-imp { flex: 0 0 auto; text-align: right; white-space: nowrap; }
/* El chip del período va entre el tipo y el número, con un espacio a cada lado. */
.comp-periodo:not(:empty) { margin: 0 4px 0 2px; }
.comp-periodo .badge { font-size: .66rem; vertical-align: 1px; }

/* Grillas del home (Últimos 10 Tickets, Últimos 5 Grupos de OS): la misma escala
   que las filas `home-lista-*` de las demás tarjetas. Sin esto las celdas tomaban
   la letra base (11.7px) y los títulos de columna iban en negrita. */
/* En `td`/`th` y no en la tabla: la grilla del framework les aplica un `em` propio a las
   celdas, que se multiplicaba con este tamaño y las dejaba en 9px. */
.tarjetas-pastel .home-grilla td { font-size: .78rem; }
/* Los títulos de columna los fija la cabecera de `.my-gridview` con !important (ver
   "tr.gv-header" más arriba): hace falta el mismo !important y más peso. */
.tarjetas-pastel .my-gridview.home-grilla table tr > th { font-size: .72rem !important; color: #94a3b8 !important; }
.tarjetas-pastel .home-grilla .home-lista-titulo { font-size: .82rem; }
.tarjetas-pastel .home-grilla .badge { font-size: .66rem; }

/* ==========================================================================
   CELULAR: CUATRO ARREGLOS QUE VALEN PARA TODAS LAS PANTALLAS (23/09/2026)
   Salieron del recorrido de las 144 pantallas del menú a 390px: los cuatro
   aparecían en casi todas, y los cuatro son de piezas compartidas, así que se
   arreglan acá una vez y no pantalla por pantalla.
   ========================================================================== */

/* 1. LA BARRA DE TÍTULO SE PARTE EN DOS RENGLONES, como el GESTOR.
   El título es `col-auto` y los botones `col`: con un título largo el título se
   queda con todo y a la botonera le sobran las migas. Medido en la ficha de Tipos
   de Ordenes de Servicio: título 326px, botones 34px → Guardar, Volver y Eliminar
   APILADOS en columna y una cabecera de ~200px. En la ficha de caja además
   desbordaba la página (397 sobre 390).
   Los listados con buscador ya se partían (`:has(.my-page-search)`, más arriba);
   esto lo extiende a las fichas y a las pantallas sin buscador: el título arriba a
   todo el ancho (puede cortar en dos líneas) y los botones abajo, en fila, a la
   derecha. Con botones de 44px entran siete por renglón. */
@media (max-width: 767.98px) {
    .my-page-headerbar .my-page-headerbar-title,
    .my-page-headerbar .my-page-headerbar-right {
        flex: 0 0 100%;
        max-width: 100%;
    }
    .my-page-headerbar .my-page-headerbar-right { padding-left: 0; }
}

/* 2. EL QUE ABRE LOS FILTROS PASA A SER UN BOTÓN FLOTANTE ABAJO A LA IZQUIERDA.
   Cerrado es un cuadrado de 40x38 `position: absolute` pegado al borde izquierdo
   del contenido, ENCIMA de lo que haya ahí: se comía la primera letra de las
   tarjetas ("ENDIENTES < 24HS"), el título de la primera columna ("ligo") y el
   número de filtros activos quedaba montado sobre el embudo. Pasaba en casi todas
   las pantallas con filtros.
   Queda como espejo del botón del chat (#btnChatFab, abajo a la derecha, en
   Master1.master) y a mano al scrollear. SÓLO CERRADO: abierto (`.show`) el toggle
   es la cabecera del panel ("Filtros" + cerrar) y tiene que seguir siendo eso.
   Sólo el panel de la izquierda: el de la derecha no apareció en el recorrido.
   El z-index queda debajo del chat (1046) y del modal (1050). */
@media (max-width: 991.98px) {
    .my-sidebar-container.my-sidebar-left:not(.show) .my-sidebar-toggle {
        position: fixed;
        top: auto;
        left: 16px;
        bottom: 28px;
        width: 48px;
        min-width: 48px;
        height: 48px;
        padding: 0;
        align-items: center;
        justify-content: center;
        overflow: visible;
        border: 0 !important;
        border-radius: 50%;
        background: #fff;
        color: #6366f1;
        box-shadow: 0 4px 14px rgba(15, 23, 42, .22);
        z-index: 1040;
    }
    .my-sidebar-container.my-sidebar-left:not(.show) .my-sidebar-toggle h5 { display: none; }
    /* El número de filtros activos, como globito en la esquina y no encima del ícono. */
    .my-sidebar-container.my-sidebar-left:not(.show) .my-sidebar-toggle .badge {
        top: -3px;
        left: auto;
        right: -3px;
        min-width: 1.25rem;
        border-radius: 1rem;
    }
}

/* 3. GRILLAS: LOS IMPORTES NO SE PARTEN, Y SE NOTA CUANDO HAY MÁS A LA DERECHA.
   El bloque mobile de grillas (más arriba) pone `white-space: normal !important` a
   TODAS las celdas para que la tabla entre. A los montos eso los partía en dos
   renglones: "$" arriba y "40.600,00" abajo. Las columnas numéricas llegan con
   `align="right"` (atributo del GridView), así que se las exceptúa por ahí.
   La sombra: una grilla que scrollea adentro de su tarjeta no avisaba que seguía,
   y lo que quedaba oculto era justo el importe o las acciones.
   ⚠ NO SIRVEN LAS "SOMBRAS DE SCROLL" CLÁSICAS (degradados en el fondo del
   contenedor con `background-attachment: local`): cada `tr` de la grilla tiene
   fondo blanco propio y las tapa. Medido: la franja no se veía.
   Va entonces una franja PEGADA al borde derecho: el `::after` del contenedor es un
   ítem flex al lado de la tabla, con `position: sticky; right: 0` se queda en el
   borde mientras la tabla pasa por debajo, y `margin-left` negativo lo monta encima
   de la última columna en vez de sumar ancho. Se apaga sola con una animación
   atada al scroll del propio contenedor: al llegar al final se desvanece, y si la
   tabla ENTRA no hay scroll, la línea de tiempo queda inactiva y la franja nunca se
   ve. Donde el navegador no tiene `animation-timeline` la franja no aparece, que
   es lo mismo que había antes. */
@media (max-width: 991.98px) {
    .table-responsive td[align="right"],
    .table-responsive th[align="right"] { white-space: nowrap !important; }

    .my-gridview .table-responsive { display: flex; }
    .my-gridview .table-responsive > table { flex: 1 0 auto; }
    .my-gridview .table-responsive::after {
        content: "";
        flex: 0 0 14px;
        margin-left: -14px;
        position: sticky;
        right: 0;
        pointer-events: none;
        background: linear-gradient(to left, rgba(15, 23, 42, .18), rgba(15, 23, 42, 0));
        opacity: 0;
    }
    @supports (animation-timeline: scroll()) {
        .my-gridview .table-responsive::after {
            animation: ispboss-grilla-sigue linear both;
            animation-timeline: scroll(nearest inline);
        }
    }
}
@keyframes ispboss-grilla-sigue {
    0%, 92% { opacity: 1; }
    100% { opacity: 0; }
}

/* 4. LA FRANJA GRIS DEL BORDE IZQUIERDO.
   Con el menú cerrado el aside queda en left -250px pero conserva la sombra de
   `elevation-4` (AdminLTE, con !important), que asoma ~10px sobre el borde de
   TODAS las pantallas. Abierto (`sidebar-open`) la sombra sí va: separa el menú
   del contenido que queda debajo. */
@media (max-width: 991.98px) {
    body:not(.sidebar-open) .main-sidebar.elevation-4 { box-shadow: none !important; }
}

/* ── Pantallas con solapas de página: la fila de las solapas no se estira ── */
/* theme.css arma el cajón del contenido con DOS filas —`auto minmax(0, 1fr)`,
   pensadas para "barra de título + contenido"—. Las pantallas con `uc:Solapas`
   (Aprovisionamiento, Causas, Órdenes sin cerrar, Bajas sin cerrar) tienen TRES
   hijos: la barra, las solapas y el contenido. Las solapas caían en la fila
   elástica y se comían todo el alto que sobraba: medido en Órdenes sin cerrar a
   1366px, 264px de solapas con 39 de contenido y un hueco en blanco encima de la
   grilla (en celular, hasta ~1.100px). No era sólo de celular. Se agrega la fila
   que falta, y sólo cuando detrás de la barra vienen las solapas. */
.my-content-wrapper > .my-content > div:has(> .content-header + ul.nav-tabs) {
    grid-template-rows: auto auto minmax(0, 1fr);
}

/* ── "Por favor seleccione el abonado" en las fichas nuevas, en el celular ── */
/* El aviso (`divAbonadoMensaje`, un `.my-overlay` en OS, Tickets, Comprobantes,
   Recibos, Cuentas Corrientes y Financiaciones) va centrado sobre el formulario
   con un velo blanco al 50%. En escritorio el formulario es bajo y se entiende;
   en celular mide ~800px, el mensaje quedaba a mitad de camino y los rótulos de
   los campos se leían ENCIMA del texto. Acá: arriba, con el velo casi opaco, y el
   ícono sin el 3x. */
@media (max-width: 991.98px) {
    .my-overlay-wrapper > .my-overlay[id$="divAbonadoMensaje"] {
        justify-content: flex-start;
        padding-top: 1.5rem;
    }
    .my-overlay-wrapper > .my-overlay[id$="divAbonadoMensaje"]::after { opacity: .9; }
    .my-overlay-wrapper > .my-overlay[id$="divAbonadoMensaje"] .my-overlay-message { font-size: 1.1rem; }
    .my-overlay-wrapper > .my-overlay[id$="divAbonadoMensaje"] .my-overlay-message > i { font-size: 2rem; }
}

/* ── Órdenes de Servicio: los chips de la columna Tipo se parten en el celular ── */
/* La grilla agrupada (grdDatos con una grdOrdenes anidada por grupo) ya esconde bajo 992
   todo salvo Número, Generación y Tipo, y bajo 768 también Generación (col-mobile-hide, en
   la cabecera Y en la anidada, en espejo). Lo que seguía estirando la tabla era un chip de
   Tipo que no corta ("ONU-HG8145 - ONU GPON WiFi dual band - Serie 4857544300A1000A"):
   medido a 390px, 456px de tabla en 364 de lugar. `.badge` es nowrap de Bootstrap; acá
   sólo en esta grilla y sólo en celular, para no deformar los chips cortos del resto. */
@media (max-width: 767.98px) {
    table[id*="grdOrdenes"] .badge { white-space: normal; text-align: left; }
}

/* ── Embudo comercial en el celular: una etapa por pantalla y columnas vacías bajas ── */
/* Las columnas de 310px fijos quedaban a mitad de camino al deslizar, y una vacía medía 360px
   de alto (el `min-height` de escritorio, pensado para que haya dónde soltar): con varias etapas
   vacías el tablero era casi todo hueco. En el celular no se suelta —el arrastrar de HTML5 no se
   dispara con el dedo; se mueve con "Mover a…" (Comercial\Embudo.aspx)— así que la columna mide
   lo que tiene, cada una casi el ancho de la pantalla, y el tablero encastra como en Despacho. */
@media (max-width: 767.98px) {
    .my-embudo-scroll { scroll-snap-type: x mandatory; }
    .my-embudo-pista { min-height: 0; }
    .my-embudo-columna {
        flex: 0 0 min(310px, calc(100vw - 64px));
        width: min(310px, calc(100vw - 64px));
        min-height: 0;
        scroll-snap-align: start;
    }
}

/* ── Tableros en el celular: gráficos más bajos ── */
/* Cada tablero fija el alto en línea (`.chart-container` de 260 a 600px, con
   maintainAspectRatio:false) pensando en una columna de medio escritorio. A 340px de ancho un
   gráfico de 600px es una torre de una pantalla y media, y los de 380–400 son casi cuadrados de
   más: se recorría el tablero entero para ver cuatro números. Acá se bajan por tramo; el eje X y
   la leyenda de las tortas los acomoda Includes\js\utils-chartsjs.js. `!important` porque el alto
   viene en el atributo style de cada .aspx. */
@media (max-width: 767.98px) {
    .chart-container { height: 240px !important; }
    .chart-container[style*="380px"],
    .chart-container[style*="400px"] { height: 300px !important; }
    .chart-container[style*="600px"] { height: 380px !important; }
}
