/*
 * Capa de compatibilidad tras la migración de Bootstrap 3.4.1 a Bootstrap 5.3.8
 * (vulnerabilidad CVE-2025-1647 / EOL de la rama v3).
 *
 * La plataforma ya usa marcado real de Bootstrap 5 (cards, form-check, navbar
 * real, btn-close, etc.). Lo que queda en esta hoja NO es deuda de migración
 * pendiente de arreglar: son casos permanentes en los que BS5 no ofrece un
 * equivalente exacto (paleta de color BS3, iconos de librerías de terceros)
 * o en los que el marcado real de la plataforma difiere intencionadamente
 * del de un proyecto BS5 "de catálogo" (navbar con <li><a> en vez de
 * dropdown-item plano, modales sin contenedor .modal en algún caso puntual).
 *
 * Cargar DESPUÉS de css/bootstrap.min.css (v5) en todas las páginas que lo usen.
 */

/* ---------- img-fluid (BS3: img-responsive) ----------
   El .img-responsive de BS3 llevaba display:block (necesario para que
   funcione el centrado con margin:auto). El .img-fluid de BS5 (su
   renombrado) solo trae max-width:100% y height:auto, sin display:block:
   una <img> sigue siendo inline por defecto, así que el margin:auto de
   "mx-auto" no tiene ningún efecto sobre ella (margin auto solo centra
   elementos de bloque). Resultado: la imagen se queda pegada a la
   izquierda de su contenedor en vez de centrada, y todo el hueco restante
   (10% cuando se usa width="90%", como en home.php) se acumula a la
   derecha en vez de repartirse a ambos lados. Se restaura el display:block
   que tenía en BS3. */
.img-fluid {
    display: block;
}

/* ---------- .hidden (utilidad de BS3, eliminada en BS4/5) ----------
   Bootstrap 3.4.1 traía la utilidad genérica ".hidden { display:none !important; }".
   BS4/5 la retiraron (su equivalente actual es ".d-none"), pero bastantes
   ficheros de operaciones (formularios de creación SMS/WhatsApp/Email, secciones
   opcionales como "Solicitud de documentos", etc. — ~58 ficheros) siguen usando
   JS que hace classList.add/remove/toggle('hidden', ...) sobre esta clase.
   Al no existir ya en el CSS, esos bloques se quedaban siempre visibles aunque
   el interruptor/checkbox correspondiente estuviera apagado. Se restaura tal
   cual estaba en BS3 en vez de reescribir cada punto de JS. */
/* ---------- .bg-* sobre filas de tabla (<tr>) ----------
   Bastantes tablas (empresas_listar.php, usuarios_listar.php, informes...)
   colorean filas enteras con clases genéricas como class="bg-primary" (thead)
   o class="bg-info"/"bg-danger" (empresa activa/inactiva), tal cual se hacía
   en BS3. En BS5 esto deja de verse: el propio componente .table pinta el
   fondo de cada <td>/<th> con "background-color: var(--bs-table-bg)" (que
   por defecto vale --bs-body-bg, blanco opaco) para soportar su sistema de
   theming con variables CSS (rayado, hover, .table-primary, etc.). Ese fondo
   opaco de cada celda tapa por completo el background-color que .bg-primary/
   .bg-info/.bg-danger (con !important) ponen en el <tr> padre — la fila
   "pierde" el color aunque la regla se siga aplicando. Se corrige poniendo
   --bs-table-bg:transparent en esas filas: como es una custom property,
   hereda a las celdas hijas, su fondo pasa a transparente y el color del
   <tr> vuelve a verse, igual que en BS3. */
.table > :not(caption) > tr.bg-secondary,
.table > :not(caption) > tr.bg-light,
.table > :not(caption) > tr.bg-dark {
    --bs-table-bg: transparent;
}

/* .bg-primary también es un caso aparte: en BS3 ".bg-primary" ponía a la vez
   "color:#fff; background-color:#434343" (pensada como cabecera de tabla
   oscura con texto claro). La utilidad ".bg-primary" de BS5 solo trae el
   background-color, sin tocar el color de texto — por eso las cabeceras
   (<tr class="bg-primary"> en las tablas de listado) quedaban con fondo
   oscuro pero letras en negro, casi ilegibles. Se restaura el texto en
   blanco solo para este caso (fila de tabla), sin tocar ".bg-primary" en
   botones/badges que puedan depender del comportamiento normal de BS5. */
.table > :not(caption) > tr.bg-primary {
    --bs-table-bg: transparent;
    color: #fff;
}
.table > :not(caption) > tr.bg-primary > * {
    color: #fff;
}

/* Pasteles BS3 en filas de tabla (trazabilidad, listados…).
   brand-theme redefine --bs-info/--bs-success/--bs-danger/--bs-warning a
   colores de marca (botones/alertas). En <tr> hace falta el pastel literal
   de BS3; si --bs-table-bg queda transparent, el .bg-success de marca
   (#1a9988) se ve a través de las celdas (fila CORRECTA en teal oscuro). */
.table > :not(caption) > tr.bg-info {
    --bs-table-bg: #d9edf7;
    color: #31708f;
}
.table > :not(caption) > tr.bg-info > * {
    color: #31708f;
    --bs-table-bg: #d9edf7;
}
.table > :not(caption) > tr.bg-success {
    --bs-table-bg: #dff0d8;
    color: #3c763d;
}
.table > :not(caption) > tr.bg-success > * {
    color: #3c763d;
    --bs-table-bg: #dff0d8;
}
.table > :not(caption) > tr.bg-danger {
    --bs-table-bg: #f2dede;
    color: #a94442;
}
.table > :not(caption) > tr.bg-danger > * {
    color: #a94442;
    --bs-table-bg: #f2dede;
}
.table > :not(caption) > tr.bg-warning {
    --bs-table-bg: #fcf8e3;
    color: #8a6d3b;
}
.table > :not(caption) > tr.bg-warning > * {
    color: #8a6d3b;
    --bs-table-bg: #fcf8e3;
}

.hidden {
    display: none !important;
}

/* Input file nativo marcado como .hidden: en BS5 .form-control[type=file]
   es display:block y el CSP ignora style="display:none" inline, así que
   "Elegir archivos" quedaba visible junto al botón personalizado. */
input[type="file"].form-control.hidden,
input[type="file"].hidden {
    display: none !important;
}

/* Fila de adjuntos (#listaArchivos): nombre + switch + eliminar en una línea.
   Refuerzo global (el CSS de formularios también lo declara) porque el flex
   inline lo bloquea el CSP y las <label> anidadas pasaban a caja de bloque. */
#listaArchivos li,
#listaArchivos .lista-archivos-item,
#listaArchivos li > div,
#listaArchivos .lista-archivos-fila {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    gap: 10px !important;
}
#listaArchivos li label:not(.hidden),
#listaArchivos li button {
    display: inline-block !important;
    flex: 0 0 auto !important;
    width: auto !important;
    margin: 0 !important;
}

/* ---------- Contenedores condicionales de operaciones (oPassword, oEnvioProgramado,
   oMapeoContainer, oEleccion, oOTP, mapeoContainer, etc.) ----------
   Todos arrancan con style="display:none" inline y JS los muestra con
   el.style.display = 'block' al activar su switch/checkbox correspondiente.
   Ese inline plano se estaba perdiendo en la práctica (se veían visibles
   sin activar el switch), así que se refuerza aquí con !important mientras
   el propio atributo style siga diciendo "none". Al ser un selector de
   atributo, es "vivo": en cuanto JS cambia el inline a display:block, este
   [style*="display: none"] deja de coincidir y el contenedor se muestra con
   normalidad, sin tocar el JS de cada formulario. */
.hidden-fields-container[style*="display: none"],
.hidden-fields-container[style*="display:none"] {
    display: none !important;
}

/* Mismo problema que arriba, pero en contenedores que no llevan la clase
   .hidden-fields-container: secciones desplegables de "Añadir cláusulas",
   "Aceptación previa obligatoria" y "Datos del destinatario en certificados"
   (peticiones de firma). Selector reactivo vía [style*="display: none"]:
   deja de coincidir en cuanto el JS del checkbox cambia el inline style. */
.oAnadirClausulas[style*="display: none"],
.oAnadirClausulas[style*="display:none"],
.oAceptacionPrevia[style*="display: none"],
.oAceptacionPrevia[style*="display:none"],
#oDatosDestinatarioCertificado[style*="display: none"],
#oDatosDestinatarioCertificado[style*="display:none"] {
    display: none !important;
}

/* ---------- Tamaño de fuente base ----------
   El bootstrap.css (BS3) de develop tenía $font-size-base: 14px (visible en
   .form-control, .btn, .h5, etc., todos con font-size:14px "quemado"), y
   solo el <body> se sobrescribía aparte a 16px para el texto suelto. BS5 de
   fábrica asume que 1rem = 16px (fuente del navegador) y usa rem por todas
   partes (padding, font-size, border-radius, gaps...), así que con el
   mismo <html> sin tocar todo sale ~14% más grande que en develop: botones,
   inputs, badges, tablas, cards, etc.
   En vez de perseguir cada regla en rem una a una, se reescala el <html> al
   mismo factor (14/16 = 87.5%) que tenía el proyecto original, y se
   mantiene el <body> en 16px explícito (independiente del rem), igual que
   en develop. Así todo el sistema de tamaños de BS5 (que está construido en
   rem) recupera automáticamente la escala de BS3 sin tocar cada selector. */
html {
    font-size: 87.5%; /* 14px (14/16): misma escala de BS3. 75%/12px dejaba
    menús, dropdowns y el resto de componentes en rem visiblemente más
    pequeños que en develop. */
}
body {
    font-size: 16px; /* texto suelto, igual que en develop */
}
/* Los h1-h6 de BS5 usan tamaño "fluido" (clamp entre rem y vw, distinto en
   cada breakpoint) en vez del tamaño fijo en px que tenía BS3. Se fijan los
   6 tamaños de develop (base 14px). */
h1, .h1 { font-size: 36px; }
h2, .h2 { font-size: 30px; }
h3, .h3 { font-size: 24px; }
h4, .h4 { font-size: 18px; }
h5, .h5 { font-size: 14px; }
h6, .h6 { font-size: 12px; }

/* ---------- container-fluid sin padding lateral (BS3) ----------
   El bootstrap.css de develop tenía .container-fluid { padding-left:0;
   padding-right:0 } (personalizado; el BS3 de fábrica trae 15px). BS5 de
   fábrica vuelve a meter su propio padding lateral (0.75rem) en todas las
   .container-fluid de la plataforma (el wrapper de index.php, el de dentro
   del <nav>, etc.), lo que deja un hueco en blanco a la izquierda/derecha
   que develop nunca tuvo. Se restaura a 0 en todas partes, igual que en
   develop. */
.container-fluid {
    padding-left: 0;
    padding-right: 0;
}

/* Landing CONFIRMA: necesita padding lateral (BS5 + shell propio). */
body.landing-page .container-fluid.landing-shell {
    padding-left: 15px;
    padding-right: 15px;
}

/* Contenido de sección (generarSoportes, listados, formularios) suelto
   bajo el .container-fluid de index.php, al mismo nivel que img.bg
   (position:fixed; z-index:-5). Si el overflow-x:hidden del wrapper
   crea stacking context, la capa negativa de la imagen puede tapar el
   formulario y la página se ve blanca/vacía. Se fuerza capa por encima.
   El .row restaura la rejilla BS5 (las .col-md-* + offset ya no flotan). */
.container-fluid.sil-overflow-x-hidden > .breadcrumb,
.container-fluid.sil-overflow-x-hidden > .row,
.container-fluid.sil-overflow-x-hidden > [class*="col-"],
.container-fluid.sil-overflow-x-hidden > .pastilla {
    position: relative;
    z-index: 1;
}
.container-fluid.sil-overflow-x-hidden > .row {
    width: 100%;
    margin-left: 0;
    margin-right: 0;
}

/* help-block de BS3 (eliminado en BS5). generarSoportes y otros forms
   lo siguen usando bajo el input; sin esta regla el texto de ayuda
   queda como span inline pegado al campo. */
.help-block {
    display: block;
    margin-top: 5px;
    color: #737373;
}

/* generarSoportes: no usa col-md/offset (en BS5 sin .row la columna
   puede quedar con alto 0 o detrás de img.bg). Caja centrada propia. */
.generar-soportes-page {
    position: relative;
    z-index: 2;
    display: block;
    clear: both;
    max-width: 900px;
    width: auto;
    margin: 30px auto;
    box-sizing: border-box;
}

/* ---------- nav-tabs BS3 (<li><a> sin .nav-link) ----------
   BS5 solo da aspecto de "pestaña" (borde, fondo, radio) a los enlaces con
   clase .nav-link. La mayoría de estas pestañas siguen usando
   <li><a data-bs-toggle="tab">Texto</a></li> sin esa clase (el JS de
   data-bs-toggle="tab" funciona igual, pero sin .nav-link el enlace se ve
   como texto suelto). Se excluye :not(.nav-link) para no interferir en los
   sitios que ya usan el marcado real de BS5 (p. ej. ajax_modalProfile.php). */
.nav-tabs > li > a:not(.nav-link) {
    position: relative;
    display: block;
    padding: 10px 15px;
    margin-right: 2px;
    line-height: 1.42857143;
    border: 1px solid transparent;
    border-radius: 4px 4px 0 0;
}
.nav-tabs > li > a:not(.nav-link):hover,
.nav-tabs > li > a:not(.nav-link):focus {
    text-decoration: none;
    background-color: #eee;
    border-color: #eee #eee #ddd;
}
.nav-tabs > li.active > a:not(.nav-link),
.nav-tabs > li.active > a:not(.nav-link):hover,
.nav-tabs > li.active > a:not(.nav-link):focus,
.nav-tabs > li > a.active:not(.nav-link),
.nav-tabs > li > a.active:not(.nav-link):hover,
.nav-tabs > li > a.active:not(.nav-link):focus {
    color: #555;
    cursor: default;
    background-color: #fff;
    border: 1px solid #ddd;
    border-bottom-color: transparent;
}

/* ---------- btn-xs (BS3, BS5 no tiene tamaño "extra pequeño" de botón) ----------
   Se restaura tal cual porque no existe una utilidad equivalente en BS5;
   varios botones de icono en tablas dinámicas dependen de este tamaño. */
.btn-xs {
    padding: 1px 5px;
    font-size: 12px;
    line-height: 1.5;
    border-radius: 3px;
}

/* ---------- form-horizontal / control-label (BS3, eliminados en BS5) ----------
   BS5 no tiene un marcador de "formulario horizontal": usa .row/.col-* +
   .col-form-label directamente. Esta plataforma sigue usando .form-horizontal
   con <label class="col-N control-label"> junto a columnas .col-N para el
   campo (marcado BS3 dentro de una rejilla ya real de BS5). Sin esta regla el
   texto de la etiqueta queda arriba-izquierda en vez de alineado en vertical
   con el campo, como en develop. */
@media (min-width: 768px) {
    .form-horizontal .control-label {
        padding-top: 7px;
        margin-bottom: 0;
        text-align: right;
    }
}
.form-horizontal .radio,
.form-horizontal .checkbox,
.form-horizontal .radio-inline,
.form-horizontal .checkbox-inline {
    padding-top: 7px;
    margin-top: 0;
    margin-bottom: 0;
}

/* ---------- "fila" de campos hecha con .form-group + col-N (BS3) ----------
   Patrón muy repetido en la plataforma (informe_accesos.php, informe_global.php,
   informe_burofaxes/consultas/evidencias/mancomunadas/contratos/campanias.php,
   varios operacion_*.php...): cada "fila" de un formulario de filtros es un
   <div class="col-md-12 col-13 form-group"> (nótese "col-13": ni entonces
   ni ahora es una clase real, es relleno visual) que mete DIRECTAMENTE
   varios pares <div class="col-md-2..."><label> + <div class="col-md-4...">
   <input>, sin envolverlos en un .row. En BS3 flotaban solos y quedaban
   uno junto a otro (varios campos por fila); en BS5 los .col-N no flotan,
   necesitan que su contenedor sea flex, así que sin él cada "columna" cae
   en su propia línea y toda la sección de filtros sale en una sola columna
   en vez de varios campos por fila. Se hace flex esta "fila falsa" para
   que sus columnas vuelvan a ir una junto a otra como en develop. */
.col-md-12.col-13.form-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
}

/* ---------- form-horizontal con .col-md-12.form-group (BS3) ----------
   empresas_editar.php (y plantillas, mapeos, modales de edición, etc.)
   marca cada fila así:

     <div class="col-md-12 form-group">
       <div class="col-md-4"><label>Empresa:</label></div>
       <div class="col-md-8"><input></div>
     </div>

   sin un .row interno. En BS3 las .col-* flotaban y la etiqueta quedaba
   a la izquierda del campo. En BS5 las columnas no flotan: sin un
   contenedor flex, cada una ocupa su propia línea y el formulario se ve
   apilado (etiqueta encima del input). La regla de .col-13 de arriba no
   aplica aquí (este marcado no lleva esa clase). Se hace flex el
   .form-group a partir de md, que es cuando .col-md-4/.col-md-8 (y
   .col-4/.col-8 de Histórico) ya tienen ancho. Se excluyen los .alert
   (banner en el propio form-group, p. ej. CRM) y los form-group sin
   columnas hijas (pestaña WhatsApp: "WhatsApp Configurado" envuelve
   solo un .alert; si se hace flex, el banner se encoge al ancho del
   texto). Las etiquetas no usan .control-label (llevan sil-pt-4px); se
   alinean a la izquierda, como en develop. */
@media (min-width: 768px) {
    .form-horizontal .form-group:not(.alert):not(.text-center):has(> [class*="col-"]) {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
    }
    /* Sin .row las .col-* de BS5 no tienen gutter; se restaura el de BS3
       (15px) para que etiqueta y campo no queden pegados. */
    .form-horizontal .form-group:not(.alert):not(.text-center):has(> [class*="col-"]) > [class*="col-"] {
        padding-left: 15px;
        padding-right: 15px;
        box-sizing: border-box;
    }
    .form-horizontal .col-md-12.form-group > [class*="col-"] > label:not(.switch) {
        display: block;
        width: 100%;
        text-align: left;
        white-space: normal;
    }
    /* help-block de BS3: el <small> de WhatsApp (y similares) debe ir
       debajo del input, no al lado. */
    .form-horizontal .form-group small.text-muted {
        display: block;
        margin-top: 5px;
    }
    /* Filas anidadas sin .row (pestaña Operaciones: Recordatorios es
       col-md-12 > col-md-3 label + col-md-9 input por día; Callback URL/
       Apikey y "Días de vigencia" igual). En BS3 flotaban en horizontal;
       en BS5 la etiqueta del día queda ENCIMA del input. */
    .form-horizontal .col-md-12.form-group [class*="col-"]:has(> [class*="col-"]) {
        display: flex;
        flex-wrap: wrap;
        align-items: flex-start;
    }
    .form-horizontal .col-md-12.form-group [class*="col-"]:has(> [class*="col-"]) > [class*="col-"] {
        padding-left: 15px;
        padding-right: 15px;
        box-sizing: border-box;
    }
}

/* ---------- form-inline (BS3, eliminado por completo en BS5) ----------
   BS4/5 quitaron .form-inline sin dejar equivalente (ahora se hace con
   utilidades d-flex). Algunos formularios de la plataforma (p. ej. el de
   cambio de contraseña y el de soporte en ajax_modalProfile.php) meten
   columnas .col-N reales DIRECTAMENTE dentro de un <form class="form-inline">
   sin envolverlas en un .row, tal cual ya se hacía en el BS3 de develop.
   Allí funcionaba porque las .col-N de BS3 flotaban (float:left) sin
   necesitar un .row/flex alrededor; las .col-N de BS5 no flotan, dependen
   de que su contenedor sea flex, así que sin .form-inline haciendo ese
   papel, cada columna cae en su propia línea (los campos "Antigua"/"Nueva"
   y el botón "Cambiar" se apilan verticalmente en vez de ir en fila). Se
   restaura .form-inline como contenedor flex con wrap, haciendo de .row
   implícito para estos formularios.

   OJO: el wrapper que genera DataTables (integración Bootstrap 3, ver más
   abajo) TAMBIÉN lleva la clase "form-inline" (junto con "dataTables_wrapper"),
   pero ahí sus hijos directos SÍ son <div class="row"> completos (el de
   "Mostrar/Buscar", el de la tabla y el de "info/paginación"), que en BS3
   simplemente se apilaban en bloque uno debajo de otro. Si a ESE wrapper
   también le aplicamos display:flex, esos tres ".row" pasan a ser items
   flex en horizontal (flex-direction:row por defecto) en vez de apilarse,
   y además cada uno se encoge a su contenido en vez de ocupar el 100% del
   ancho — por eso "Buscar:" quedaba pegado justo detrás de "Mostrar X
   registros" en vez de ir al extremo derecho de la tabla. Se excluye
   explícitamente .dataTables_wrapper para que conserve el apilado en
   bloque normal; el reparto 50/50 de Mostrar/Buscar ya lo da el propio
   .row (flex) + .col-sm-6 de Bootstrap sin necesitar esto. */
.form-inline:not(.dataTables_wrapper) {
    display: flex;
    flex-wrap: wrap;
}
/* BS3 traía también esta regla compañera (misma media query >=768px que el
   propio Bootstrap 3): dentro de .form-inline, los .form-control dejan de
   ser display:block/width:100% y pasan a inline-block/width:auto, para que
   los campos se vean a su tamaño natural en vez de ocupar toda la fila.
   Sin esto, cualquier <select>/<input class="form-control"> metido dentro
   de un .form-inline (p. ej. los controles "Mostrar X registros" / "Buscar:"
   que genera la integración Bootstrap-3 de DataTables, cuyo wrapper lleva
   la clase "dataTables_wrapper form-inline dt-bootstrap") se estira a
   ancho completo y fuerza saltos de línea alrededor, rompiendo el layout
   compacto de esos controles (visto en empresas_listar.php / usuarios_listar.php). */
@media (min-width: 768px) {
    .form-inline .form-group {
        display: inline-block;
        margin-bottom: 0;
        vertical-align: middle;
    }
    .form-inline .form-control {
        display: inline-block;
        width: auto;
        vertical-align: middle;
    }
}
/* En ajax_modalProfile.php, el bloque "Cambio de contraseña" mete
   directamente un <div class="page-header"> y un <form class="form-inline">
   como hijos sueltos de un .row, sin .col-* (ver #oDiv_perfil). En BS3 esto
   apilaba sin más porque ni .row ni esos hijos eran flex: cada uno ocupaba
   su línea de bloque normal. El .row de BS5 SÍ es flex con wrap, así que
   ahora depende de que ninguno de los dos "quepa" al lado del otro para
   que el wrap los apile — funciona casi siempre pero no está garantizado
   (ni el alto resultante es necesariamente el mismo: los márgenes de
   bloque que colapsaban en BS3 no colapsan entre items flex). Se fuerza a
   ocupar el 100% del ancho para que apilen exactamente igual que en BS3,
   sin depender de si "caben" uno al lado del otro. */
#oDiv_perfil .row > .page-header,
#oDiv_perfil .row > form {
    flex: 0 0 100%;
    max-width: 100%;
}
/* Dentro de #oFormularioPassword, "Antigua"/"Nueva" meten <div class="col-3">
   (etiqueta) y <div class="col-9"> (input) como hijos sueltos de su propio
   .form-group, sin .row, igual que en develop (col-xs-3/col-xs-9 flotaban
   solos en BS3 sin necesitar .row). Sin flex, esas dos columnas se apilan
   (etiqueta encima, input debajo) en vez de ir en la misma línea, lo que
   además hace que el bloque "Antigua"/"Nueva" (dos líneas) quede más alto
   que el bloque del botón "Cambiar" (una sola línea), desalineando el
   botón respecto a los campos. Se hace flex para que etiqueta+input vayan
   en la misma línea (como en develop) y se centra verticalmente. */
#oFormularioPassword > .form-group,
#oFormularioSoporte > .form-group {
    display: flex;
    align-items: center;
}
/* El .tab-content del modal de perfil tiene una altura fija en px
   (.sil-h-245px / .sil-h-215px, con !important) pensada para el alto que
   ocupaba este contenido en BS3, más compacto que en BS5. Con esa altura
   fija, el contenido real (panel de 2FA, botón de caducar, formulario de
   contraseña) queda más alto que la caja y se sale visualmente por debajo
   del modal. En vez de forzar scroll interno (no se quiere scroll), se
   deja que la caja crezca a lo que ocupe su contenido, como hacía el
   modal completo en develop: el modal simplemente es un poco más alto,
   pero todo queda dentro de su recuadro sin cortar ni scrollear nada. */
#oModalPassword .tab-content {
    height: auto !important;
    overflow: visible;
}
/* Con las columnas "Antigua"/"Nueva" ya en una sola línea, las tres
   columnas del formulario (Antigua, Nueva, Cambiar) quedan prácticamente
   con la misma altura; align-items:center en el propio .form-inline
   termina de alinear el botón "Cambiar" en vertical con los campos. */
#oFormularioPassword.form-inline {
    align-items: center;
}

/* ---------- checkbox / radio (BS3, sustituidos por .form-check en BS5) ----------
   Hay DOS marcados en la plataforma:

   1) ficha_contacto.php / contactos.php:
      <div class="checkbox"><label><input type="checkbox">Texto</label></div>
      El input VA DENTRO del label. BS3 lo sacaba del flujo con
      position:absolute y padding-left:20px en el label.

   2) empresas_editar.php / ajax_modalEditarRemitente.php:
      <div class="col-md-4"><label>Texto</label></div>
      <div class="col-md-8"><div class="checkbox"><input></div></div>
      El input NO está dentro del label: el label va en otra columna.
      Si se aplica el position:absolute de (1) aquí, el checkbox se
      desplaza -20px y se pinta ENCIMA del final de la etiqueta
      ("Habilitar Soporte Documen", "Activar CR", "PartnerGre"...).

   La regla absoluta solo aplica al patrón (1). El (2) deja el input
   estático, alineado con los .form-control de la columna de campos. */
.radio,
.checkbox {
    position: relative;
    display: block;
    margin-top: 10px;
    margin-bottom: 10px;
}
.radio label,
.checkbox label {
    min-height: 20px;
    padding-left: 20px;
    margin-bottom: 0;
    font-weight: 400;
    cursor: pointer;
}
.radio label input[type="radio"],
.checkbox label input[type="checkbox"] {
    position: absolute;
    margin-left: -20px;
    margin-top: 4px;
}

/* Jerarquía de permisos (ajax_modalEditarUsuario.php).
   Cada nivel es un .divPermisos con huecos col-md-1 / col-md-2 + checkbox
   col-md-1 + etiqueta. En BS3 esas columnas flotaban y el hueco indentaba
   hijos y nietos. En BS5 las col no flotan: el hueco ocupa una línea
   vacía y checkbox+etiqueta quedan todos alineados a la izquierda.
   Se vuelve a una fila (flex) y se ocultan los <br> de relleno. */
.divPermisos {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    width: 100%;
}
.divPermisos > .divPermisos {
    flex: 0 0 100%;
    max-width: 100%;
}
.divPermisos > br {
    display: none;
}
.divPermisos > .col-md-1 {
    flex: 0 0 8.33333333%;
    max-width: 8.33333333%;
    width: 8.33333333%;
    box-sizing: border-box;
}
.divPermisos > .col-md-2 {
    flex: 0 0 16.66666667%;
    max-width: 16.66666667%;
    width: 16.66666667%;
    box-sizing: border-box;
}
.divPermisos > .col-md-9 {
    flex: 0 0 75%;
    max-width: 75%;
    width: 75%;
    box-sizing: border-box;
}
.divPermisos > .col-md-10 {
    flex: 0 0 83.33333333%;
    max-width: 83.33333333%;
    width: 83.33333333%;
    box-sizing: border-box;
}
.divPermisos > .col-md-11 {
    flex: 0 0 91.66666667%;
    max-width: 91.66666667%;
    width: 91.66666667%;
    box-sizing: border-box;
}

/* ---------- page-header (BS3, eliminado en BS4/5) ---------- */
.page-header {
    padding-bottom: 9px;
    margin: 40px 0 20px;
    border-bottom: 1px solid #eee;
}

/* ---------- breadcrumb (BS3) ----------
   El marcado sigue siendo <ol class="breadcrumb"><li><a>...</a></li></ol>
   (sin .breadcrumb-item, que es lo que exige BS5 para el separador "/" y el
   padding). Se restaura el aspecto BS3 completo: fondo gris, padding propio
   y separador "/" entre <li>, porque el <ol class="breadcrumb"> de BS5 no
   lleva fondo ni padding por defecto y no dibuja separador sin
   .breadcrumb-item. */
.breadcrumb {
    padding: 8px 15px;
    margin-bottom: 20px;
    list-style: none;
    background-color: transparent;
    border-radius: 4px;
}
.breadcrumb > li {
    display: inline-block;
}
.breadcrumb > li + li:before {
    padding: 0 5px;
    color: #ccc;
    content: "/\00a0";
}
.breadcrumb > li.active {
    color: #777;
}

/* ---------- Modales (BS3, con valores fijos en vez de las custom properties
   --bs-modal-* de BS5). Se mantienen para que el modal tenga exactamente el
   mismo aspecto (radios, sombras, paddings) que en develop. ---------- */
.modal-open {
    overflow: hidden;
}
.modal-dialog {
    position: relative;
    width: auto;
    margin: 10px;
}
.modal-content {
    position: relative;
    background-color: #fff;
    background-clip: padding-box;
    border: 1px solid rgba(0, 0, 0, .2);
    border-radius: 6px;
    outline: 0;
    box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
}
/* Overlay de modal a pantalla completa.
   En BS5 .modal (z-index 1055) cubre el viewport POR ENCIMA de
   .modal-backdrop. Si .modal no llega a height:100% o el backdrop queda
   oculto, se ve el formulario blanco (opaco y más bajo que la ventana).
   El atenuado visible se pinta en body.modal-open::before (position:fixed
   a toda la pantalla). .modal queda transparente; .modal-content es el
   único recuadro blanco. */
body.modal-open::before {
    content: "";
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1050;
    background-color: rgba(0, 0, 0, 0.5);
    pointer-events: none;
}
/* Un .modal sin .show no debe interceptar clics (formulario de operación). */
.modal:not(.show) {
    pointer-events: none;
}
.modal.show {
    pointer-events: auto;
}
.modal {
    background-color: transparent !important;
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: 100% !important;
    max-height: none !important;
}
.modal.show {
    background-color: transparent !important;
}
.modal-backdrop {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1050;
    background-color: #000;
    /* El atenuado visible es body.modal-open::before; evitar doble capa. */
    opacity: 0 !important;
    pointer-events: none;
}
.modal-header {
    min-height: 16.43px;
    padding: 15px;
    border-bottom: 1px solid #e5e5e5;
}
/* En BS3 el botón de cerrar iba primero en el HTML (<button class="close">
   antes del <h3 class="modal-title">) y se colocaba a la derecha con
   float:right, dejando que el título (bloque, text-center) ocupara el
   resto del ancho y se centrara en el hueco restante. La plataforma sigue
   usando ese mismo orden en el HTML (botón primero, título después; ver
   ajax_modalProfile.php), pero .modal-header de BS5 es flex, y float no
   tiene ningún efecto dentro de un contenedor flex: sin más, el botón y el
   título quedan pegados los dos al principio (izquierda), en vez de
   título-izquierda/botón-derecha. Se reordena con order + margin-left:auto
   en el botón, el equivalente real en flex de aquel float:right. */
.modal-header .modal-title {
    order: 1;
}
.modal-header .btn-close {
    order: 2;
    margin-left: auto;
}
.modal-title {
    margin: 0;
    line-height: 1.42857143;
}
.modal-body {
    position: relative;
    padding: 15px;
}
.modal-footer {
    padding: 15px;
    text-align: right;
    border-top: 1px solid #e5e5e5;
}
.modal-footer .btn + .btn {
    margin-bottom: 0;
    margin-left: 5px;
}
.modal-footer .btn-block + .btn-block {
    margin-left: 0;
}
@media (min-width: 768px) {
    .modal-dialog {
        --bs-modal-width: 600px;
        width: 600px;
        max-width: 600px;
        margin: 30px auto;
    }
    .modal-content {
        box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
    }
    .modal-sm {
        --bs-modal-width: 300px;
        width: 300px;
        max-width: 300px;
    }
}
@media (min-width: 992px) {
    /* BS5 usa max-width:var(--bs-modal-width) con 800px en .modal-lg;
       sin pisar la variable/max-width, width:900px no ensancha el modal. */
    .modal-lg {
        --bs-modal-width: 900px;
        width: 900px;
        max-width: 900px;
    }
}
@media (min-width: 1200px) {
    .modal-xl {
        --bs-modal-width: 1140px;
        width: 1140px;
        max-width: 1140px;
    }
}

/* ---------- Glyphicons (Bootstrap 5 no incluye iconos propios) ----------
   NOTA: esto NO es deuda de migración eliminable. datetimepicker.min.js y
   select(1.13.14).min.js son librerías de terceros minificadas que generan
   internamente marcado con clases glyphicon-* (calendario, flechas, ok,
   reloj) y no pueden editarse. Esta fuente y sus iconos deben permanecer
   de forma permanente aunque el resto de la plataforma esté ya en BS5.
   5 iconos propios de la app (ok, refresh, eye-open, eye-close, copy)
   + 4 usados por datetimepicker.min.js (time, calendar, chevron-up/down). */
@font-face {
    font-family: "Glyphicons Halflings";
    src: url(../fonts/glyphicons-halflings-regular.eot);
    src: url(../fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"),
         url(../fonts/glyphicons-halflings-regular.woff2) format("woff2"),
         url(../fonts/glyphicons-halflings-regular.woff) format("woff"),
         url(../fonts/glyphicons-halflings-regular.ttf) format("truetype"),
         url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg");
}
.glyphicon {
    position: relative;
    top: 1px;
    display: inline-block;
    font-family: "Glyphicons Halflings";
    font-style: normal;
    font-weight: 400;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
.glyphicon-ok:before { content: "\e013"; }
.glyphicon-refresh:before { content: "\e031"; }
.glyphicon-eye-open:before { content: "\e105"; }
.glyphicon-eye-close:before { content: "\e106"; }
.glyphicon-copy:before { content: "\e205"; }
.glyphicon-time:before { content: "\e023"; }
.glyphicon-calendar:before { content: "\e109"; }
.glyphicon-chevron-up:before { content: "\e113"; }
.glyphicon-chevron-down:before { content: "\e114"; }

/* ---------- form-group (BS3, eliminado en BS5 -> utilidades mb-3) ----------
   No se renombra la clase porque operacionesWhatsapp.js hace
   .closest('.form-group') para localizar el contenedor; se mantiene el
   nombre y se restaura solo el margen. */
.form-group {
    margin-bottom: 15px;
}

/* ---------- panel (BS3) migrado a estructura real de card (BS5) ----------
   La estructura ya es real BS5: <div class="card panel-default|info|primary|
   success|warning|danger"><div class="card-header">...<div class="card-body">
   ...<div class="card-footer">. Las clases de color panel-* se conservan
   intencionadamente (no son deuda: BS5 no tiene un tema de color equivalente
   a los tonos exactos de BS3) para que el resultado sea visualmente idéntico
   a develop. Estas reglas son permanentes mientras se quiera mantener esa
   paleta exacta. */
.card.panel-default,
.card.panel-info,
.card.panel-primary,
.card.panel-success,
.card.panel-warning,
.card.panel-danger {
    margin-bottom: 20px;
    border-radius: 4px;
    box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
}
.card.panel-default > .card-header,
.card.panel-info > .card-header,
.card.panel-primary > .card-header,
.card.panel-success > .card-header,
.card.panel-warning > .card-header,
.card.panel-danger > .card-header {
    padding: 10px 15px;
    border-top-left-radius: 3px;
    border-top-right-radius: 3px;
}
.card.panel-default > .card-body,
.card.panel-info > .card-body,
.card.panel-primary > .card-body,
.card.panel-success > .card-body,
.card.panel-warning > .card-body,
.card.panel-danger > .card-body {
    padding: 15px;
}
.card.panel-default > .card-footer,
.card.panel-info > .card-footer,
.card.panel-primary > .card-footer,
.card.panel-success > .card-footer,
.card.panel-warning > .card-footer,
.card.panel-danger > .card-footer {
    padding: 10px 15px;
    background-color: #f5f5f5;
    border-bottom-right-radius: 3px;
    border-bottom-left-radius: 3px;
}
.panel-title {
    margin-top: 0;
    margin-bottom: 0;
    font-size: 16px;
    color: inherit;
}
.panel-default {
    border-color: #ddd;
}
.panel-default > .card-header {
    color: #333;
    background-color: #f5f5f5;
    border-color: #ddd;
}
.panel-info {
    border-color: #455660;
}
.panel-info > .card-header {
    color: #fff;
    background-color: #24292E;
    border-color: #455660;
}
.panel-primary {
    border-color: var(--bs-primary, #337ab7);
}
.panel-primary > .card-header {
    color: #fff;
    background-color: var(--bs-primary, #337ab7);
    border-color: var(--bs-primary, #337ab7);
}
.panel-success {
    border-color: #d6e9c6;
}
.panel-success > .card-header {
    color: #1a9988;
    background-color: #dff0d8;
    border-color: #d6e9c6;
}
.panel-warning {
    border-color: #faebcc;
}
.panel-warning > .card-header {
    color: #00B0C7;
    background-color: #fcf8e3;
    border-color: #faebcc;
}
.panel-danger {
    border-color: #ebccd1;
}
.panel-danger > .card-header {
    color: #dd7e6b;
    background-color: #f2dede;
    border-color: #ebccd1;
}

/* ---------- panel-group / panel-collapse (BS3, "acordeón" de paneles) ----------
   ajax_modalOperacion*.php usan el patrón de acordeón de BS3: varios
   .panel dentro de un .panel-group, cada uno con su .panel-collapse.collapse
   controlado por data-bs-toggle="collapse" (ya renombrado). El JS de collapse
   de BS5 no depende del nombre de estas clases envolventes, así que
   funcionalmente ya funcionan; solo se restaura el margen entre paneles que
   traía BS3 (si no, quedan todos pegados unos a otros). */
.panel-group {
    margin-bottom: 20px;
}
.panel-group .card {
    margin-bottom: 0;
    overflow: hidden;
}
.panel-group .card + .card {
    margin-top: 5px;
}

/* ---------- navbar-nav / dropdown-menu con estructura <li><a> (BS3) ----------
   BS5 solo da estilo a .dropdown-item (enlace plano); esta plataforma sigue
   usando <li><a> dentro de .dropdown-menu, igual que en BS3 (ver menu.php).
   El padding lateral (15px) venía en BS3 del componente base .nav > li > a
   (padding: 10px 15px), pero el <ul> actual solo lleva la clase
   .navbar-nav (sin .nav), así que ese padding-left/right nunca llega: en su
   lugar entra el de BS5 (.navbar-nav .nav-link usa
   --bs-navbar-nav-link-padding-x, solo 0.5rem = la mitad), y los puntos de
   menú quedan más juntos que en develop. Se fija el mismo padding lateral
   de 15px que tenía el .nav > li > a original.
   Nota: hace falta !important en el padding lateral porque BS5 mete su
   propio ".navbar-expand-md .navbar-nav .nav-link { padding-left/right:
   var(--bs-navbar-nav-link-padding-x) }" con 3 clases (más específico que
   este selector de 1 clase + 2 elementos), así que sin !important gana BS5
   y el padding de 15px nunca llegaría a aplicarse. */
.navbar-nav {
    margin: 7.5px -15px;
}
.navbar-nav > li > a {
    padding-top: 10px;
    padding-bottom: 10px;
    padding-left: 15px !important;
    padding-right: 15px !important;
    line-height: 20px;
}
@media (min-width: 768px) {
    .navbar-nav {
        float: left;
        margin: 0;
    }
    .navbar-nav > li {
        float: left;
    }
    .navbar-nav > li > a {
        padding-top: 15px;
        padding-bottom: 15px;
    }
}
.dropdown-menu > li > a {
    display: block;
    padding: 3px 20px;
    clear: both;
    font-weight: 400;
    line-height: 1.42857143;
    color: #333;
    white-space: nowrap;
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
    color: #262626;
    text-decoration: none;
    background-color: #f5f5f5;
}
.dropdown-menu .divider {
    height: 1px;
    margin: 9px 0;
    overflow: hidden;
    background-color: #e5e5e5;
}
.navbar-nav .open .dropdown-menu,
.navbar-nav .dropdown:hover .dropdown-menu {
    position: static;
    float: none;
    width: auto;
    background-color: transparent;
    border: 0;
    box-shadow: none;
}
@media (min-width: 768px) {
    /* El <a class="dropdown-toggle"> del menú principal (menu.php) no lleva
       data-bs-toggle="dropdown": no dispara el JS Dropdown de BS5 (que
       depende de Popper, no cargado en este proyecto), se abre solo por
       CSS al hacer :hover, igual que en BS3. El .dropdown-menu de BS5 ya
       no trae top/left propios en su CSS base (antes en BS3 sí: todo el
       posicionamiento moderno se delega a Popper) — sin Popper y sin estos
       valores, el navegador coloca el menú en su "posición estática" por
       defecto, que no es debajo del enlace sino arriba a la izquierda de
       la página. Se fijan aquí top/left explícitos, igual que hacía BS3. */
    .navbar-nav .open .dropdown-menu,
    .navbar-nav .dropdown:hover .dropdown-menu {
        position: absolute;
        top: 100%;
        left: 0;
        z-index: 1000;
        float: left;
        width: auto;
        background-color: #fff;
        border: 1px solid rgba(0, 0, 0, .15);
        box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
    }
}
.dropdown:hover .dropdown-menu,
.dropdown.open .dropdown-menu {
    display: block;
}

/* ---------- navbar-header / navbar-inverse (BS3) ----------
   Siguen en uso en menu.php y pagookko.php. ---------- */
.navbar-header {
    float: left;
}

/* ---------- Texto de los enlaces del menú (BS3: color propio de
   .navbar-inverse/.navbar-default; en BS5 ese color solo lo dan las
   variables --bs-navbar-color, que a su vez solo consume .nav-link) ----------
   menu.php sigue usando <li><a> sueltos (sin la clase .nav-link) dentro de
   .navbar-nav, tanto en el menú principal como en el bloque de la derecha
   (campana / usuario / cerrar sesión). Sin .nav-link, ese <a> no coge el
   color de .navbar-dark/.navbar-inverse y cae en el color de enlace global
   de brand-theme.css (--bs-link-color: #24292E, gris casi negro pensado
   para texto sobre fondo BLANCO). Sobre el fondo oscuro del navbar
   (#24292E / #2b3136) ese gris queda prácticamente invisible. Se fija aquí
   el mismo gris claro que daba BS3 en sus navbars oscuros. */
.navbar-default .navbar-nav > li > a,
.navbar-inverse .navbar-nav > li > a {
    color: rgba(255, 255, 255, .55);
}
.navbar-default .navbar-nav > li > a:hover,
.navbar-default .navbar-nav > li > a:focus,
.navbar-inverse .navbar-nav > li > a:hover,
.navbar-inverse .navbar-nav > li > a:focus {
    color: rgba(255, 255, 255, .75);
}

/* La campana (icono con "sil-font-size-140pc", 140% del tamaño de fuente
   normal) y el icono de cerrar sesión conviven en el mismo <ul> flex con
   enlaces de texto normal (usuario) a tamaño 100%. Sin centrado vertical
   explícito, el <li> (que se estira a toda la altura de la barra por el
   align-items:stretch por defecto de flex) deja cada <a> alineado a su
   línea de base normal, y el glifo más grande de la campana asoma más
   arriba que el texto/icono de al lado en vez de quedar centrado con
   ellos. Se centra el contenido de cada <li> verticalmente, sea cual sea
   el tamaño de fuente de su icono/texto. */
.navbar-nav > li {
    display: flex;
    align-items: center;
}

/* El icono de "cerrar sesión" (fa-sign-out) lleva la utilidad .text-info,
   pensada para texto sobre fondo blanco (usa --bs-info, que brand-theme.css
   fija a #24292E, el mismo gris casi negro del fondo del navbar). Sobre el
   navbar queda invisible por el mismo motivo que el resto de enlaces; como
   .text-info aplica su color con !important, hace falta !important también
   aquí para ganarle, limitado a este icono concreto del navbar. */
.navbar-default .navbar-nav > li > a .text-info,
.navbar-inverse .navbar-nav > li > a .text-info {
    color: rgba(255, 255, 255, .55) !important;
}

/* ---------- navbar-right (BS3, "float:right"; sin equivalente en BS5) ----------
   El bloque de la derecha (campana / usuario / cerrar sesión en menu.php)
   usa <ul class="nav navbar-nav navbar-right">. En BS3 float:right lo
   empujaba al borde derecho de la barra; dentro de .navbar-collapse (flex
   en BS5 desde que lleva navbar-expand-md) float ya no tiene efecto, así
   que ambos <ul> (menú principal y este) quedan pegados uno junto a otro
   en vez de éste ir al extremo derecho. margin-left:auto es el equivalente
   real en flex: consume todo el espacio sobrante a su izquierda. */
.navbar-nav.navbar-right {
    margin-left: auto;
}

/* ---------- navbar en flex (BS5) ----------
   .navbar-header y .collapse.navbar-collapse son ahora los dos items flex
   directos de .container-fluid, y BS5 le pone justify-content:space-between
   de fábrica a ese contenedor. El float:left de arriba no sirve de nada
   dentro de un contenedor flex (float se ignora en los items flex), así que
   con solo esos dos items, space-between separa todo el bloque del menú
   (el collapse entero) hacia el borde derecho, dejando un hueco enorme
   entre el logo y "Envíos" en vez de ir pegados como en BS3 (donde ambos
   flotaban a la izquierda uno tras otro). Se fuerza flex-start para que
   queden juntos a la izquierda, y flex-grow en el collapse para que el
   ms-auto del segundo <ul> (campana/usuario) siga empujando hasta el borde
   derecho real de la barra, como ya hacía. */
.navbar > .container-fluid {
    justify-content: flex-start;
}
.navbar .navbar-collapse {
    flex-grow: 1;
    /* .navbar > .container-fluid tiene align-items:center de fábrica en
       BS5, así que el collapse solo ocupa el alto de su propio contenido
       (el texto) y queda centrado dentro del alto mayor que marca el logo,
       dejando franjas del fondo oscuro del navbar arriba y abajo del fondo
       claro de .sil-background-color-2b3136 (campana/usuario). align-self
       en el propio collapse ignora ese align-items del padre y lo estira a
       todo el alto de la barra; como ni .navbar-nav ni sus <li> fijan
       align-items/align-self propios, la altura se propaga por defecto
       (stretch) hasta el <ul> con el fondo claro, que así lo cubre entero. */
    align-self: stretch;
}
/* .navbar-header lleva un "col-4" heredado de develop que en BS3 no era una
   clase real (BS3 solo tiene col-xs/sm/md/lg-4, no "col-4" a secas), así que
   no pintaba nada; en BS5 sí es una utilidad real (ancho fijo 33.333% +
   flex-basis + gutters) y mete un hueco que nunca estuvo en el diseño
   original. Se neutraliza para que el logo solo ocupe su ancho natural. */
.navbar-header.col-4 {
    flex: 0 0 auto;
    width: auto;
    max-width: none;
    padding-left: 0;
    padding-right: 0;
}
.navbar-inverse {
    background-color: #222;
    border-color: #080808;
}
.navbar-inverse .navbar-brand {
    color: #9d9d9d;
}
.navbar-inverse .navbar-brand:hover,
.navbar-inverse .navbar-brand:focus {
    color: #fff;
}

/* ---------- input-group-btn (BS3, en BS5 los botones son hijos directos
   de .input-group) ----------
   login.php sigue envolviendo el botón "mostrar contraseña" en
   <span class="input-group-btn"> dentro de .input-group, tal cual BS3. El
   .input-group de BS5 es flex y solo une bordes/radios entre sus HIJOS
   DIRECTOS; con el <span> de por medio, el botón deja de ser hijo directo y
   el conjunto input+botón pierde la unión visual (borde partido, radio
   suelto en el botón). display:contents saca el <span> de la jerarquía de
   layout sin tocar el HTML: el <button> pasa a comportarse como hijo
   directo del flex de .input-group, igual que si no estuviera envuelto. */
.input-group-btn {
    display: contents;
}

/* ---------- table-condensed (BS3, renombrada a table-sm en BS4/5) ----------
   ~38 ficheros siguen usando "table-condensed" (celdas con menos padding).
   BS5 no reconoce ese nombre en absoluto (solo "table-sm"), así que esas
   tablas se quedaban con el padding normal (0.5rem), más altas/grandes de
   lo que deberían. Se replica el mismo padding que da "table-sm". */
.table-condensed > :not(caption) > * > * {
    padding: 0.25rem 0.25rem;
}

/* ---------- Margen inferior de tablas (BS3: 20px fijos) ----------
   El .table de BS5 trae margin-bottom:1rem, que con el reescalado de
   fuente base a 87.5% (ver arriba) equivale a 14px en vez de los 20px
   fijos que tenía BS3. El hueco entre una tabla y lo que viene justo
   debajo (botones, paneles...) queda visiblemente más apretado que
   antes. Se restaura el valor fijo de BS3. */
.table {
    margin-bottom: 20px;
}

/* ---------- Bordes y zebra de tablas (regresión BS5) ----------
   En BS3, .table ponía border-top en cada celda y .table-bordered
   aplicaba border:1px solid #ddd en th/td (rejilla completa).
   En BS5, .table-bordered deja las celdas con border-width: 0 Npx
   (solo verticales); las horizontales deberían venir del <tr>, pero
   el fondo opaco de cada td (--bs-table-bg) las tapa.
   Además, el zebra de jquery.dataTables solo aplica con .stripe/.display,
   y los listados (oDataTable / datatable-es) no llevan esas clases ni
   table-striped — se pierde el sombreado impar que se veía antes. */
.table-bordered {
    border: 1px solid #ddd;
}
.table-bordered > :not(caption) > * > * {
    border: 1px solid #ddd !important;
}
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td {
    border-bottom-width: 2px !important;
}
.table > :not(caption) > * > * {
    border-top: 1px solid #ddd;
}

/* Zebra BS3 (#f9f9f9) para table-striped y filas odd de DataTables */
.table {
    --bs-table-striped-bg: #f9f9f9;
}
.table-striped > tbody > tr:nth-of-type(odd) > * {
    --bs-table-bg-type: #f9f9f9;
}
/* No aplicar zebra sobre filas con tinte de estado ni sobre filas seleccionadas
   (DataTables .selected). Estos :not() dan alta especificidad; sin :not(.selected)
   el sombreado cebra tapa el contraste de la selección. */
table.dataTable > tbody > tr.odd:not(.bg-info):not(.bg-danger):not(.bg-warning):not(.bg-primary):not(.bg-success):not(.selected) > *,
.table.oDataTable > tbody > tr.odd:not(.bg-info):not(.bg-danger):not(.bg-warning):not(.bg-primary):not(.bg-success):not(.selected) > *,
.table.datatable-es > tbody > tr.odd:not(.bg-info):not(.bg-danger):not(.bg-warning):not(.bg-primary):not(.bg-success):not(.selected) > * {
    --bs-table-bg-type: #f9f9f9;
    box-shadow: inset 0 0 0 9999px #f9f9f9;
}
table.dataTable > tbody > tr.even:not(.bg-info):not(.bg-danger):not(.bg-warning):not(.bg-primary):not(.bg-success):not(.selected) > *,
.table.oDataTable > tbody > tr.even:not(.bg-info):not(.bg-danger):not(.bg-warning):not(.bg-primary):not(.bg-success):not(.selected) > *,
.table.datatable-es > tbody > tr.even:not(.bg-info):not(.bg-danger):not(.bg-warning):not(.bg-primary):not(.bg-success):not(.selected) > * {
    --bs-table-bg-type: transparent;
    box-shadow: none;
}

/* ---------- input-lg / input-sm (BS3, renombradas a form-control-lg/sm
   en BS4/5) ---------- */
.input-lg {
    min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));
    padding: 0.5rem 1rem;
    font-size: 1.25rem;
    border-radius: var(--bs-border-radius-lg);
}
.input-sm {
    min-height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2));
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
    border-radius: var(--bs-border-radius-sm);
}

/* ---------- caret (BS3, flechita de los dropdown-toggle) ----------
   BS5 ya dibuja su propia flecha con un ::after en .dropdown-toggle vía
   CSS. Esta plataforma sigue generando ADEMÁS su propio <b class="caret">
   a mano (menu.php y varios modales de previsualización/plantillas)
   dentro de ese mismo .dropdown-toggle: con las reglas de abajo (que
   restauran el triángulo de BS3 para cuando "caret" se usa fuera de un
   dropdown-toggle) se veían las DOS flechas a la vez. Se oculta la manual
   solo cuando va dentro de un .dropdown-toggle, que es el caso real de
   este proyecto; fuera de ahí (si lo hubiera) se sigue viendo la de BS3. */
.dropdown-toggle .caret {
    display: none;
}
.caret {
    display: inline-block;
    width: 0;
    height: 0;
    margin-left: 2px;
    vertical-align: middle;
    border-top: 4px solid;
    border-right: 4px solid transparent;
    border-left: 4px solid transparent;
}

/* ---------- label / label-* (BS3, renombrada a "badge" en BS4/5) ----------
   Varios ficheros de operaciones generan <span class="label label-info|
   label-default"> desde JS para marcar "Plantilla"/"PDF". BS5 solo estiliza
   ".badge" (sin ".label"), así que estos quedaban como texto plano sin
   fondo ni forma de etiqueta. Se restaura el aspecto de BS3, usando los
   colores de marca (brand-theme.css) en vez de los de BS3 de fábrica para
   que combine con el resto de badges/botones ya migrados. */
.label {
    display: inline;
    padding: .2em .6em .3em;
    font-size: 75%;
    font-weight: 700;
    line-height: 1;
    color: #fff;
    text-align: center;
    white-space: nowrap;
    vertical-align: baseline;
    border-radius: .25em;
}
.label-default {
    background-color: #777;
}
.label-primary {
    background-color: var(--bs-primary, #337ab7);
}
.label-success {
    background-color: var(--bs-success, #5cb85c);
}
.label-info {
    background-color: var(--bs-info, #5bc0de);
}
.label-warning {
    background-color: var(--bs-warning, #f0ad4e);
}
.label-danger {
    background-color: var(--bs-danger, #d9534f);
}

/* ---------- pull-left / pull-right / center-block (BS3, sin clase
   equivalente en BS5: ahora son float-start/float-end/mx-auto) ---------- */
.pull-left {
    float: left;
}
.pull-right {
    float: right;
}
.center-block {
    display: block;
    margin-left: auto;
    margin-right: auto;
}

/* ---------- img-thumbnail (BS3, sigue existiendo en BS5 pero con otro
   aspecto por defecto) ---------- */
.img-thumbnail {
    display: inline-block;
    max-width: 100%;
    height: auto;
    padding: 4px;
    line-height: 1.42857143;
    background-color: #fff;
    border: 1px solid #ddd;
    border-radius: 4px;
}

/* ---------- Modal de previsualización/confirmación de operaciones ----------
   (#oModalPrevisualizacion / #oModalPrevisualizacionBUROFAX)
   Este CSS vivía como un <style> embebido dentro del HTML que devuelve
   ajax_modalPrevisualizacion(BUROFAX).php e insertado vía $('body').append().
   Ese <style> nunca llegaba a aparecer en el DOM (confirmado en el
   inspector), así que se traslada aquí, a una hoja que ya se carga de forma
   fiable en el <head> desde el arranque de la página. */
#oModalPrevisualizacion.modal,
#oModalPrevisualizacionBUROFAX.modal {
    overflow: auto !important;
    background-color: transparent !important;
    height: 100% !important;
}
#oModalPrevisualizacion .modal-dialog,
#oModalPrevisualizacionBUROFAX .modal-dialog {
    width: 900px;
    max-width: calc(100vw - 20px);
    margin: 30px auto;
}
#oModalPrevisualizacion .modal-content,
#oModalPrevisualizacionBUROFAX .modal-content {
    display: flex !important;
    flex-direction: column !important;
    overflow: visible !important;
    border-radius: 6px !important;
}
#oModalPrevisualizacion .modal-header,
#oModalPrevisualizacionBUROFAX .modal-header {
    flex-shrink: 0 !important;
    overflow: visible !important;
}
#oModalPrevisualizacion .modal-body,
#oModalPrevisualizacionBUROFAX .modal-body {
    overflow: visible !important;
    flex-shrink: 0 !important;
}
/* La regla base de Bootstrap (.tab-content > .tab-pane { display:none })
   no se estaba respetando para la pestaña inactiva al abrir el modal (se
   veían "Resumen" y "Destinatarios" apilados a la vez). Se refuerza aquí
   con !important, sin depender de por qué la regla base no ganaba. */
#oModalPrevisualizacion .tab-content > .tab-pane,
#oModalPrevisualizacionBUROFAX .tab-content > .tab-pane {
    display: none !important;
}
#oModalPrevisualizacion .tab-content > .tab-pane.active,
#oModalPrevisualizacionBUROFAX .tab-content > .tab-pane.active {
    display: block !important;
}
/* Editor de plantillas DOCUMENTO: mismo apilado Resumen+PDF si BS5 no
   desactiva el panel previo (marcado legado o modal inyectado por AJAX). */
#oModaleditarPlantilla .tab-content > .tab-pane {
    display: none !important;
}
#oModaleditarPlantilla .tab-content > .tab-pane.active,
#oModaleditarPlantilla .tab-content > .tab-pane.show.active {
    display: block !important;
}
/* Visor PDF del editor de plantillas: mismo marco que mapeo/operaciones
   (tarjeta blanca, borde, sombra) y centrado. Los .row anidados de BS5
   (flex) dejaban el iframe pegado a la izquierda. */
#oModaleditarPlantilla #oDiv_plantilla_pdf {
    padding: 15px 0 5px;
    text-align: center;
}
#oModaleditarPlantilla #oDiv_plantilla_pdf .iframe-container {
    background: #fff;
    border-radius: 8px;
    padding: 15px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    margin: 0 auto;
    max-width: 100%;
}
#oModaleditarPlantilla #oDiv_plantilla_pdf .oVisorPDF {
    display: block;
    margin-left: auto;
    margin-right: auto;
    width: 80%;
    max-width: 100%;
    height: 70vh;
    border-radius: 6px;
    border: 1px solid #e9ecef;
    background: #fff;
    box-sizing: border-box;
}
#oModalPrevisualizacion .modal-confirmar-footer,
#oModalPrevisualizacionBUROFAX .modal-confirmar-footer {
    flex-shrink: 0 !important;
    background: #f8f9fa;
    border-top: 2px solid #e9ecef;
    padding: 16px 20px 24px !important;
    border-radius: 0 0 6px 6px;
    text-align: center;
}
/* ---------- Modal de previsualización de PDF adjunto (#oModalPDF) ----------
   Mismo problema que el modal de desglose: el <style> viaja embebido en el
   HTML de ajax_modalPDF.php y se pierde al insertarlo con $('body').append().
   Se traslada aquí para que cargue de forma fiable. */
.modal-pdf-enhanced .modal-header {
    background: linear-gradient(135deg, #24292E 0%, #2d3439 100%);
    color: white;
    border-radius: 6px 6px 0 0;
    padding: 20px 25px;
    border-bottom: none;
}
.modal-pdf-enhanced .modal-header .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
    opacity: 0.9;
}
.modal-pdf-enhanced .modal-header .btn-close:hover {
    opacity: 1;
}
.modal-pdf-enhanced .modal-title {
    color: white;
    font-weight: 600;
    font-size: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 0;
}
.modal-pdf-enhanced .modal-title i {
    font-size: 24px;
}
.modal-pdf-enhanced .modal-body {
    padding: 30px;
    background: #f8f9fa;
}
.modal-pdf-enhanced .oVisorPDF {
    border: 2px solid #e9ecef;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    background: #fff;
    margin-bottom: 20px;
}
.modal-pdf-enhanced .btn-accept-enhanced {
    background: linear-gradient(135deg, #24292E 0%, #2d3439 100%);
    border: none;
    color: white;
    padding: 12px 40px;
    font-size: 16px;
    font-weight: 500;
    border-radius: 6px;
    transition: all 0.3s ease;
    box-shadow: 0 2px 4px rgba(36, 41, 46, 0.3);
}
.modal-pdf-enhanced .btn-accept-enhanced:hover {
    background: linear-gradient(135deg, #2d3439 0%, #373b3e 100%);
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(36, 41, 46, 0.4);
    color: white;
}
.modal-pdf-enhanced .modal-content {
    border: none;
    border-radius: 8px;
    overflow: hidden;
}
.modal-pdf-enhanced .pdf-viewer-container {
    background: #fff;
    border-radius: 6px;
    padding: 15px;
    margin-bottom: 15px;
}

.modal-previsualizacion-enhanced .modal-header {
    background: linear-gradient(135deg, #24292E 0%, #2d3439 100%);
    color: white;
    border-radius: 6px 6px 0 0;
    padding: 20px 25px;
    border-bottom: none;
}
.modal-previsualizacion-enhanced .modal-header .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
    opacity: 0.9;
}
.modal-previsualizacion-enhanced .modal-header .btn-close:hover {
    opacity: 1;
}
.modal-previsualizacion-enhanced .modal-title {
    color: white;
    font-weight: 600;
    font-size: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}
.modal-previsualizacion-enhanced .modal-title i {
    font-size: 24px;
}
.modal-previsualizacion-enhanced .nav-tabs {
    border-bottom: 2px solid #e9ecef;
    margin-bottom: 12px;
}
.modal-previsualizacion-enhanced .nav-tabs > li > a {
    color: #555;
    font-weight: 500;
    padding: 12px 20px;
    border: none;
    border-bottom: 3px solid transparent;
    transition: all 0.3s ease;
}
.modal-previsualizacion-enhanced .nav-tabs > li > a:hover {
    background: #f8f9fa;
    border-color: #24292E;
}
.modal-previsualizacion-enhanced .nav-tabs > li.active > a {
    color: #24292E;
    background: transparent;
    border-bottom-color: #24292E;
    font-weight: 600;
}
.modal-previsualizacion-enhanced .summary-section {
    background: #f8f9fa;
    border-left: 4px solid #24292E;
    border-radius: 6px;
    padding: 12px 15px;
    margin-bottom: 10px;
    clear: both;
    position: relative;
    z-index: 1;
}
.modal-previsualizacion-enhanced .summary-icon-box {
    background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
    border-radius: 8px;
    padding: 10px;
    text-align: center;
    box-shadow: 0 2px 4px rgba(0,0,0,0.05);
    position: relative;
    z-index: 1;
}
.modal-previsualizacion-enhanced .summary-icon-box img {
    max-width: 235px;
    width: 100%;
    height: auto;
}
.modal-previsualizacion-enhanced .summary-details {
    padding: 10px 0;
}
.modal-previsualizacion-enhanced .summary-details h4 {
    margin: 8px 0;
    color: #555;
    font-size: 16px;
}
.modal-previsualizacion-enhanced .summary-section h4 {
    margin: 5px 0;
    font-size: 18px;
}
.modal-previsualizacion-enhanced .summary-details .text-info {
    color: #24292E !important;
    font-weight: 600;
}
.modal-previsualizacion-enhanced .summary-divider {
    border-top: 2px solid #e9ecef;
    margin: 12px 0;
}
.modal-previsualizacion-enhanced .credits-box {
    background: #fff;
    border: 1px solid #e9ecef;
    border-radius: 6px;
    padding: 12px 15px;
    margin: 10px 0 8px 0;
    clear: both;
    position: relative;
    z-index: 1;
    float: none;
}
.modal-previsualizacion-enhanced .credits-box h4 {
    margin: 8px 0;
}
.modal-previsualizacion-enhanced .modal-body {
    position: relative;
    padding: 12px 15px 8px;
    overflow: visible !important;
}
.modal-previsualizacion-enhanced .modal-resumen-derecha,
.modal-previsualizacion-enhanced .modal-tab-scroll {
    padding-right: 8px;
    max-height: calc(90vh - 255px);
    min-height: 80px;
    overflow-y: auto;
    overflow-x: hidden;
    box-sizing: border-box;
    -webkit-overflow-scrolling: touch;
}
.modal-previsualizacion-enhanced .summary-section-comentario p {
    margin: 0;
    white-space: pre-wrap;
    word-break: break-word;
}
.modal-previsualizacion-enhanced .modal-documento-viewer {
    text-align: center;
    padding: 8px 0;
}
.modal-previsualizacion-enhanced .btn-confirm-enhanced {
    background: linear-gradient(135deg, #24292E 0%, #2d3439 100%);
    border: none;
    color: white;
    padding: 12px 40px;
    font-size: 16px;
    font-weight: 500;
    border-radius: 6px;
    transition: all 0.3s ease;
    box-shadow: 0 2px 4px rgba(36, 41, 46, 0.3);
}
.modal-previsualizacion-enhanced .btn-confirm-enhanced:hover {
    background: linear-gradient(135deg, #2d3439 0%, #373b3e 100%);
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(36, 41, 46, 0.4);
    color: white;
}
.modal-previsualizacion-enhanced .table {
    border-radius: 6px;
    overflow: hidden;
}
.modal-previsualizacion-enhanced .table thead tr {
    background: linear-gradient(135deg, #24292E 0%, #2d3439 100%);
    color: white;
}
.modal-previsualizacion-enhanced .table thead th {
    border: none;
    font-weight: 600;
    padding: 12px;
}
.modal-previsualizacion-enhanced .table tbody tr.bg-info {
    background: #e9ecef !important;
}
.modal-previsualizacion-enhanced .table tbody tr.bg-primary {
    background: #24292E !important;
    color: white;
    font-weight: 600;
}
.modal-previsualizacion-enhanced .table tbody tr:hover {
    background: #f0f0f0 !important;
    transition: all 0.2s ease;
}
.modal-previsualizacion-enhanced .table tbody tr.bg-primary:hover {
    background: #2d3439 !important;
}
.modal-previsualizacion-enhanced .btn-preview-enhanced {
    background: linear-gradient(135deg, #24292E 0%, #2d3439 100%);
    border: none;
    color: white;
    padding: 6px 16px;
    font-size: 13px;
    font-weight: 500;
    border-radius: 4px;
    transition: all 0.3s ease;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}
.modal-previsualizacion-enhanced .btn-preview-enhanced:hover {
    background: linear-gradient(135deg, #2d3439 0%, #373b3e 100%);
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.25);
    color: white;
}
.modal-previsualizacion-enhanced .alert-enhanced {
    border-radius: 6px;
    padding: 15px 20px;
    border: none;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
    margin: 15px 0;
}
.modal-previsualizacion-enhanced .alert-warning-enhanced {
    background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
    border-left: 4px solid #ffc107;
    color: #856404;
}
.modal-previsualizacion-enhanced .alert-danger-enhanced {
    background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
    border-left: 4px solid #dc3545;
    color: #721c24;
}
.modal-previsualizacion-enhanced .alert-enhanced i {
    margin-right: 8px;
    font-size: 18px;
}
.modal-previsualizacion-enhanced .text-truncate-custom {
    max-width: 400px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: inline-block;
    vertical-align: middle;
}
.modal-previsualizacion-enhanced .modal-confirmar-footer {
    padding: 16px 20px 24px !important;
}

/* ---------- Resto de modales AJAX con el mismo problema de <style> embebido
   (se pierde al insertarse vía $('body').append(oModal)): #oModalBiometria,
   #oModalOTP, .modal-mapeo-enhanced (#oModalMapeo / multi-plantillas),
   #oModalOperacion, #oModalOperacionChild, #oModalOperacionGrandChild,
   #oModalCampania. Todo trasladado tal cual desde su <style> original. ---------- */

/* ---- ajax_modalBiometria.php ---- */
#oModalBiometria .modal-content {
    border: none;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 12px 40px rgba(0,0,0,0.18);
}
#oModalBiometria .modal-bio-header {
    background: linear-gradient(135deg, #24292E 0%, #3d444b 100%);
    color: #fff;
    padding: 20px 28px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
#oModalBiometria .modal-bio-header-left {
    display: flex;
    align-items: center;
    gap: 13px;
}
#oModalBiometria .modal-bio-icon {
    width: 42px; height: 42px;
    border-radius: 50%;
    background: rgba(255,255,255,0.15);
    display: flex; align-items: center; justify-content: center;
    font-size: 19px;
}
#oModalBiometria .modal-bio-title {
    font-size: 17px;
    font-weight: 600;
    margin: 0;
}
#oModalBiometria .modal-bio-close {
    background: none; border: none; color: #fff;
    font-size: 24px; line-height: 1; cursor: pointer;
    opacity: 0.75; padding: 0; transition: opacity 0.2s;
}
#oModalBiometria .modal-bio-close:hover { opacity: 1; }
#oModalBiometria .modal-bio-body {
    background: #f8f9fa;
    padding: 26px 28px;
}
#oModalBiometria .bio-grid {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 20px;
}
@media (max-width: 640px) {
    #oModalBiometria .bio-grid { grid-template-columns: 1fr; }
}
#oModalBiometria .bio-card {
    background: #fff;
    border-radius: 10px;
    padding: 22px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.07);
    display: flex;
    flex-direction: column;
    align-items: center;
}
#oModalBiometria .bio-card-icon {
    width: 44px; height: 44px;
    border-radius: 50%;
    background: linear-gradient(135deg, #24292E 0%, #3d444b 100%);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-size: 20px;
    margin-bottom: 12px;
    box-shadow: 0 3px 8px rgba(36,41,46,0.22);
}
#oModalBiometria .bio-card h4 {
    font-size: 14px;
    font-weight: 600;
    color: #24292E;
    margin: 0 0 6px;
    text-align: center;
}
#oModalBiometria .bio-card p {
    font-size: 12px;
    color: #6c757d;
    margin: 0 0 14px;
    text-align: center;
}
#oModalBiometria #oImagen {
    border: 2px dashed #dee2e6;
    border-radius: 8px;
    cursor: crosshair;
    background: #fafafa;
    width: 100%;
    display: block;
    box-sizing: border-box;
    touch-action: none;
    transition: border-color 0.2s;
}
#oModalBiometria #oImagen:hover { border-color: #24292E; }
#oModalBiometria .modal-bio-footer {
    background: #fff;
    padding: 16px 28px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-top: 1px solid #e9ecef;
}
#oModalBiometria .bio-btn {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 11px 24px;
    border-radius: 6px;
    font-size: 14px; font-weight: 500;
    border: none; cursor: pointer;
    transition: all 0.25s;
}
#oModalBiometria .bio-btn-secondary {
    background: #f8f9fa;
    color: #24292E;
    border: 1px solid #dee2e6;
}
#oModalBiometria .bio-btn-secondary:hover {
    background: #e9ecef;
    border-color: #adb5bd;
}
#oModalBiometria .bio-btn-primary {
    background: linear-gradient(135deg, #24292E 0%, #3d444b 100%);
    color: #fff;
    box-shadow: 0 2px 8px rgba(36,41,46,0.25);
    font-size: 15px;
    padding: 11px 28px;
}
#oModalBiometria .bio-btn-primary:hover {
    background: linear-gradient(135deg, #3d444b 0%, #555e66 100%);
    transform: translateY(-1px);
    box-shadow: 0 4px 14px rgba(36,41,46,0.3);
    color: #fff;
}

/* ---- ajax_modalOTP.php ---- */
#oModalOTP .modal-content {
    border: none;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 12px 40px rgba(0,0,0,0.18);
}
#oModalOTP .modal-otp-header {
    background: linear-gradient(135deg, #24292E 0%, #3d444b 100%);
    color: #fff;
    padding: 20px 28px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
#oModalOTP .modal-otp-header-left {
    display: flex;
    align-items: center;
    gap: 13px;
}
#oModalOTP .modal-otp-icon {
    width: 42px; height: 42px;
    border-radius: 50%;
    background: rgba(255,255,255,0.15);
    display: flex; align-items: center; justify-content: center;
    font-size: 20px;
}
#oModalOTP .modal-otp-title {
    font-size: 17px;
    font-weight: 600;
    margin: 0;
}
#oModalOTP .modal-otp-close {
    background: none; border: none; color: #fff;
    font-size: 24px; line-height: 1; cursor: pointer;
    opacity: 0.75; padding: 0; transition: opacity 0.2s;
}
#oModalOTP .modal-otp-close:hover { opacity: 1; }
#oModalOTP .modal-otp-body {
    background: #f8f9fa;
    padding: 32px 28px;
    text-align: center;
}
#oModalOTP #oTitle {
    font-size: 14px;
    color: #6c757d;
    margin: 0 0 26px;
    font-weight: 400;
    line-height: 1.5;
}
#oModalOTP #oFormularioOTP {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
}
#oModalOTP #iCodigoOTP {
    width: 280px;
    padding: 14px 20px;
    font-size: 26px;
    font-weight: 700;
    text-align: center;
    letter-spacing: 10px;
    border: 2px solid #dee2e6;
    border-radius: 8px;
    background: #fff;
    color: #24292E;
    transition: border-color 0.2s, box-shadow 0.2s;
    outline: none;
}
#oModalOTP #iCodigoOTP:focus {
    border-color: #24292E;
    box-shadow: 0 0 0 3px rgba(36,41,46,0.1);
}
#oModalOTP .otp-submit-btn {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 12px 32px;
    border-radius: 6px;
    font-size: 15px;
    font-weight: 600;
    border: none;
    cursor: pointer;
    background: linear-gradient(135deg, #24292E 0%, #3d444b 100%);
    color: #fff;
    box-shadow: 0 2px 8px rgba(36,41,46,0.25);
    transition: all 0.25s;
}
#oModalOTP .otp-submit-btn:hover {
    background: linear-gradient(135deg, #3d444b 0%, #555e66 100%);
    transform: translateY(-1px);
    box-shadow: 0 4px 14px rgba(36,41,46,0.3);
    color: #fff;
}
#oModalOTP #oInformacion {
    margin-top: 20px;
}
#oModalOTP #contadorTiempo {
    font-size: 13px;
    color: #6c757d;
    font-weight: 500;
    margin: 0 0 6px;
}
#oModalOTP #contadorIntentos {
    font-size: 13px;
    font-weight: 500;
    margin: 0 0 6px;
    transition: color 0.3s;
}
#oModalOTP #mensajeAdicional h4 {
    font-size: 13px;
    margin: 6px 0;
}
#oModalOTP #mensajeError {
    font-size: 13px;
    color: #d9534f;
    font-weight: 500;
    margin: 0;
}
#oModalOTP .otp-divider {
    width: 48px;
    height: 3px;
    background: linear-gradient(135deg, #24292E, #3d444b);
    border-radius: 2px;
    margin: 16px auto 20px;
}

/* ---- ajax_modalMapeo.php + ajax_modalMapeoMultiPlantillas.php (comparten .modal-mapeo-enhanced) ---- */
.modal-mapeo-enhanced .modal-header {
    background: linear-gradient(135deg, #24292E 0%, #2d3439 100%);
    color: white;
    border-radius: 6px 6px 0 0;
    padding: 20px 25px;
    border-bottom: none;
}
.modal-mapeo-enhanced .modal-header .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
    opacity: 0.9;
}
.modal-mapeo-enhanced .modal-header .btn-close:hover {
    opacity: 1;
}
.modal-mapeo-enhanced .modal-title {
    color: white;
    font-weight: 600;
    font-size: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}
.modal-mapeo-enhanced .modal-title i {
    font-size: 24px;
}
.modal-mapeo-enhanced .nav-tabs {
    border-bottom: 2px solid #e9ecef;
    margin-bottom: 20px;
}
.modal-mapeo-enhanced .nav-tabs > li > a {
    color: #555;
    font-weight: 500;
    padding: 12px 20px;
    border: none;
    border-bottom: 3px solid transparent;
    transition: all 0.3s ease;
}
.modal-mapeo-enhanced .nav-tabs > li > a:hover {
    background: #f8f9fa;
    border-color: #24292E;
}
.modal-mapeo-enhanced .nav-tabs > li.active > a {
    color: #24292E;
    background: transparent;
    border-bottom-color: #24292E;
    font-weight: 600;
}
.modal-mapeo-enhanced .modal-body {
    padding: 25px;
    background: #f8f9fa;
}
.modal-mapeo-enhanced .modal-body .row {
    margin: 0;
}
.modal-mapeo-enhanced .iframe-container {
    background: white;
    border-radius: 8px;
    padding: 15px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    margin-bottom: 20px;
}
.modal-mapeo-enhanced .oVisorPDF {
    border-radius: 6px;
    border: 1px solid #e9ecef;
    width: 100%;
    max-width: 100%;
    display: block;
}
.modal-mapeo-enhanced .tab-content {
    padding-top: 10px;
}
.modal-mapeo-enhanced .tab-pane {
    padding: 0;
}
.modal-mapeo-enhanced .modal-footer {
    background: #f8f9fa;
    border-top: 2px solid #e9ecef;
    padding: 20px;
    border-radius: 0 0 6px 6px;
}
.modal-mapeo-enhanced .btn-mapear-enhanced {
    background: linear-gradient(135deg, #24292E 0%, #2d3439 100%);
    border: none;
    color: white;
    padding: 12px 40px;
    font-size: 16px;
    font-weight: 500;
    border-radius: 6px;
    transition: all 0.3s ease;
    box-shadow: 0 2px 4px rgba(36, 41, 46, 0.3);
}
.modal-mapeo-enhanced .btn-mapear-enhanced:hover {
    background: linear-gradient(135deg, #2d3439 0%, #373b3e 100%);
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(36, 41, 46, 0.4);
    color: white;
}
.modal-mapeo-enhanced .btn-mapear-enhanced:focus {
    outline: none;
    box-shadow: 0 4px 8px rgba(36, 41, 46, 0.4);
}
.modal-mapeo-enhanced .button-container {
    text-align: center;
    padding: 20px 0 0 0;
}

/* ---- ajax_modalOperacion.php ---- */
#oModalOperacion #oDiv_documento,
#oModalOperacion #oDiv_documento.burofax-height {
    overflow-x: auto !important;
    overflow-y: auto !important;
    text-align: left;
    width: 100%;
    box-sizing: border-box;
}
#oModalOperacion .modal-body {
    overflow-x: auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    box-sizing: border-box;
    max-width: 100%;
}
#oModalOperacion #oDiv_documento .panel-group,
#oModalOperacion #oDiv_documento .panel {
    width: 100%;
    max-width: 100%;
    float: none;
}
#oModalOperacion #oDiv_documento .panel-body {
    max-width: 100%;
    box-sizing: border-box;
}
#oModalOperacion #oDiv_documento .sil-tabla-scroll-h {
    overflow-x: auto;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
}
#oModalOperacion #oDiv_documento .sil-panel-body-heght {
    overflow: auto;
    max-width: 100%;
}
#oModalOperacion #oDiv_documento table {
    max-width: none;
}

/* ---- ajax_modalOperacionChild.php ---- */
#oModalOperacionChild.modal-operacion-enhanced .modal-body {
    overflow-x: hidden;
}
#oDiv_resumenChild.burofax-height {
    overflow-x: hidden;
    overflow-y: auto;
    max-width: 100%;
}
#oDiv_resumenChild.burofax-height .row {
    margin-left: 0;
    margin-right: 0;
    overflow: hidden;
    clear: both;
}
#oDiv_resumenChild.burofax-height .row > .col-md-6 {
    word-wrap: break-word;
    overflow-wrap: break-word;
    word-break: break-word;
    box-sizing: border-box;
    padding-right: 10px;
    padding-left: 10px;
    overflow: hidden;
}
#oDiv_resumenChild.burofax-height .row > .col-md-6 h4 {
    margin-top: 0;
    margin-bottom: 10px;
    word-wrap: break-word;
    overflow-wrap: break-word;
}
#oDiv_resumenChild.burofax-height .row > .col-md-6 h5 {
    word-wrap: break-word;
    overflow-wrap: break-word;
    word-break: break-word;
    white-space: normal;
    margin-bottom: 10px;
    line-height: 1.4;
    overflow: hidden;
    max-width: 100%;
    display: block;
}
#oDiv_resumenChild.burofax-height .row > .col-md-6 h5 b {
    display: inline-block;
    min-width: 100px;
    vertical-align: top;
    margin-right: 5px;
}
#oDiv_resumenChild.burofax-height .row > .col-md-6 h5 button {
    flex-shrink: 0;
    margin-left: 5px;
    vertical-align: middle;
}
#oDiv_resumenChild.burofax-height .row > .col-md-6 h5 > *:not(b):not(button) {
    display: inline;
    word-wrap: break-word;
}

/* ---- ajax_modalOperacionGrandChild.php ---- */
#oModalOperacionGrandChild.modal-operacion-enhanced .modal-body {
    overflow-x: hidden;
}
#oDiv_resumenGrandChild.burofax-height {
    overflow-x: hidden;
    overflow-y: auto;
    max-width: 100%;
}
#oDiv_resumenGrandChild.burofax-height .row {
    margin-left: 0;
    margin-right: 0;
    overflow: hidden;
    clear: both;
}
#oDiv_resumenGrandChild.burofax-height .row > .col-md-6 {
    word-wrap: break-word;
    overflow-wrap: break-word;
    word-break: break-word;
    box-sizing: border-box;
    padding-right: 10px;
    padding-left: 10px;
    overflow: hidden;
}
#oDiv_resumenGrandChild.burofax-height .row > .col-md-6 h4 {
    margin-top: 0;
    margin-bottom: 10px;
    word-wrap: break-word;
    overflow-wrap: break-word;
}
#oDiv_resumenGrandChild.burofax-height .row > .col-md-6 h5 {
    word-wrap: break-word;
    overflow-wrap: break-word;
    word-break: break-word;
    white-space: normal;
    margin-bottom: 10px;
    line-height: 1.4;
    overflow: hidden;
    max-width: 100%;
    display: block;
}
#oDiv_resumenGrandChild.burofax-height .row > .col-md-6 h5 b {
    display: inline-block;
    min-width: 100px;
    vertical-align: top;
    margin-right: 5px;
}
#oDiv_resumenGrandChild.burofax-height .row > .col-md-6 h5 button {
    flex-shrink: 0;
    margin-left: 5px;
    vertical-align: middle;
}
#oDiv_resumenGrandChild.burofax-height .row > .col-md-6 h5 > *:not(b):not(button) {
    display: inline;
    word-wrap: break-word;
}

/* ---- ajax_modalOperacionPrincipal.php (#oModalCampania) ---- */
#oModalCampania.modal-operacion-enhanced .modal-body {
    overflow-x: hidden;
}
#oDiv_resumen.burofax-height {
    overflow-x: hidden;
    overflow-y: auto;
    max-width: 100%;
}
#oDiv_resumen.burofax-height .row {
    margin-left: 0;
    margin-right: 0;
    overflow: hidden;
    clear: both;
}
#oDiv_resumen.burofax-height .row > .col-md-6 {
    word-wrap: break-word;
    overflow-wrap: break-word;
    word-break: break-word;
    box-sizing: border-box;
    padding-right: 10px;
    padding-left: 10px;
    overflow: hidden;
}
#oDiv_resumen.burofax-height .row > .col-md-6 h4 {
    margin-top: 0;
    margin-bottom: 10px;
    word-wrap: break-word;
    overflow-wrap: break-word;
}
#oDiv_resumen.burofax-height .row > .col-md-6 h5 {
    word-wrap: break-word;
    overflow-wrap: break-word;
    word-break: break-word;
    white-space: normal;
    margin-bottom: 10px;
    line-height: 1.4;
    overflow: hidden;
    max-width: 100%;
    display: block;
}
#oDiv_resumen.burofax-height .row > .col-md-6 h5 b {
    display: inline-block;
    min-width: 100px;
    vertical-align: top;
    margin-right: 5px;
}
#oDiv_resumen.burofax-height .row > .col-md-6 h5 button {
    flex-shrink: 0;
    margin-left: 5px;
    vertical-align: middle;
}
#oDiv_resumen.burofax-height .row > .col-md-6 h5 > *:not(b):not(button) {
    display: inline;
    word-wrap: break-word;
}

/* ==========================================================================
   Restauración BS3 post-migración (clases usadas en markup sin equivalente BS5)
   Login, listados, formularios de operaciones, menú, DataTables, etc.
   ========================================================================== */

/* ---------- .btn-default (eliminado en BS4/5) ----------
   En BS3 era el botón gris bordeado por defecto. Sin esta regla queda solo
   .btn (fondo transparente / contraste pobre): login, proveedores, plantillas,
   modales de usuario, etc. */
.btn-default {
    color: #333;
    background-color: #fff;
    border-color: #ccc;
}
.btn-default:hover,
.btn-default:focus,
.btn-default.focus {
    color: #333;
    background-color: #e6e6e6;
    border-color: #adadad;
}
.btn-default:active,
.btn-default.active,
.show > .btn-default.dropdown-toggle {
    color: #333;
    background-color: #e6e6e6;
    border-color: #adadad;
}
.btn-default.disabled,
.btn-default:disabled {
    color: #333;
    background-color: #fff;
    border-color: #ccc;
    opacity: 0.65;
}

/* ---------- .btn-block (eliminado en BS5 → w-100 / d-grid) ----------
   CTAs de login, contactos/CRM y remember-pass. */
.btn-block {
    display: block;
    width: 100%;
}
.btn-block + .btn-block {
    margin-top: 5px;
}

/* ---------- .img-rounded (renombrado a .rounded en BS4/5) ----------
   Logos del menú y login. */
.img-rounded {
    border-radius: 6px;
}

/* ---------- Neutralizar jquery.dataTables.min.css en paginación BS ----------
   Ese CSS pinta .paginate_button (el <li>) con margin-left:2px, padding y
   borde propios → botones sueltos con huecos. Con el renderer bootstrap los
   estilos deben vivir solo en el <a> interior. */
.dataTables_wrapper .dataTables_paginate .pagination > li.paginate_button,
.dataTables_wrapper .dataTables_paginate .pagination > li {
    margin: 0 !important;
    margin-left: 0 !important;
    padding: 0 !important;
    min-width: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
    background-image: none !important;
    box-shadow: none !important;
    display: flex !important;
    color: inherit !important;
}
.dataTables_wrapper .dataTables_paginate .pagination > li.paginate_button:hover,
.dataTables_wrapper .dataTables_paginate .pagination > li.paginate_button:active,
.dataTables_wrapper .dataTables_paginate .pagination > li.paginate_button.current,
.dataTables_wrapper .dataTables_paginate .pagination > li.paginate_button.current:hover,
.dataTables_wrapper .dataTables_paginate .pagination > li.paginate_button.disabled,
.dataTables_wrapper .dataTables_paginate .pagination > li.paginate_button.disabled:hover {
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
    background-image: none !important;
    box-shadow: none !important;
    color: inherit !important;
}

/* ---------- Paginación tablas (DataTables BS3 + BS5 .page-link) ----------
   Aspecto de referencia: bloque continuo, texto gris, activo charcoal
   (#212529) con texto blanco, bordes #dee2e6, radios solo en extremos. */
.pagination,
.dataTables_paginate .pagination {
    --bs-pagination-padding-x: 0.75rem;
    --bs-pagination-padding-y: 0.375rem;
    --bs-pagination-font-size: 1rem;
    --bs-pagination-color: #6c757d;
    --bs-pagination-bg: #fff;
    --bs-pagination-border-width: 1px;
    --bs-pagination-border-color: #dee2e6;
    --bs-pagination-border-radius: 0.375rem;
    --bs-pagination-hover-color: #212529;
    --bs-pagination-hover-bg: #e9ecef;
    --bs-pagination-hover-border-color: #dee2e6;
    --bs-pagination-focus-color: #212529;
    --bs-pagination-focus-bg: #e9ecef;
    --bs-pagination-focus-box-shadow: none;
    --bs-pagination-active-color: #fff;
    --bs-pagination-active-bg: #212529;
    --bs-pagination-active-border-color: #212529;
    --bs-pagination-disabled-color: #6c757d;
    --bs-pagination-disabled-bg: #fff;
    --bs-pagination-disabled-border-color: #dee2e6;
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 0;
    padding-left: 0;
    list-style: none;
    margin: 0;
}
.pagination > li,
.pagination > .page-item {
    display: flex;
    margin: 0;
}
.pagination > li > a,
.pagination > li > span,
.pagination .page-link,
.dataTables_wrapper .dataTables_paginate .pagination > li > a,
.dataTables_wrapper .dataTables_paginate .pagination > li > span {
    position: relative;
    display: block;
    float: none;
    padding: 0.375rem 0.75rem !important;
    margin: 0 0 0 -1px !important;
    min-width: 0 !important;
    line-height: 1.5;
    font-size: 1rem;
    color: #6c757d !important;
    text-decoration: none !important;
    background-color: #fff !important;
    background-image: none !important;
    border: 1px solid #dee2e6 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
}
.pagination > li:first-child > a,
.pagination > li:first-child > span,
.pagination > .page-item:first-child .page-link,
.dataTables_wrapper .dataTables_paginate .pagination > li:first-child > a,
.dataTables_wrapper .dataTables_paginate .pagination > li:first-child > span {
    margin-left: 0 !important;
    border-top-left-radius: 0.375rem !important;
    border-bottom-left-radius: 0.375rem !important;
}
.pagination > li:last-child > a,
.pagination > li:last-child > span,
.pagination > .page-item:last-child .page-link,
.dataTables_wrapper .dataTables_paginate .pagination > li:last-child > a,
.dataTables_wrapper .dataTables_paginate .pagination > li:last-child > span {
    border-top-right-radius: 0.375rem !important;
    border-bottom-right-radius: 0.375rem !important;
}
.pagination > li > a:hover,
.pagination > li > span:hover,
.pagination > li > a:focus,
.pagination > li > span:focus,
.pagination .page-link:hover,
.pagination .page-link:focus,
.dataTables_wrapper .dataTables_paginate .pagination > li > a:hover,
.dataTables_wrapper .dataTables_paginate .pagination > li > a:focus {
    z-index: 2;
    color: #212529 !important;
    background-color: #e9ecef !important;
    background-image: none !important;
    border-color: #dee2e6 !important;
    box-shadow: none !important;
    outline: 0;
}
.pagination > .active > a,
.pagination > .active > span,
.pagination > .active > a:hover,
.pagination > .active > span:hover,
.pagination > .active > a:focus,
.pagination > .active > span:focus,
.pagination > .page-item.active .page-link,
.page-item.active .page-link,
.dataTables_wrapper .dataTables_paginate .pagination > .active > a,
.dataTables_wrapper .dataTables_paginate .pagination > .active > a:hover,
.dataTables_wrapper .dataTables_paginate .pagination > .active > a:focus {
    z-index: 3;
    color: #fff !important;
    cursor: default;
    background-color: #212529 !important;
    background-image: none !important;
    border-color: #212529 !important;
}
.pagination > .disabled > span,
.pagination > .disabled > span:hover,
.pagination > .disabled > span:focus,
.pagination > .disabled > a,
.pagination > .disabled > a:hover,
.pagination > .disabled > a:focus,
.pagination > .page-item.disabled .page-link,
.page-item.disabled .page-link,
.dataTables_wrapper .dataTables_paginate .pagination > .disabled > a,
.dataTables_wrapper .dataTables_paginate .pagination > .disabled > a:hover,
.dataTables_wrapper .dataTables_paginate .pagination > .disabled > span {
    color: #6c757d !important;
    cursor: not-allowed;
    pointer-events: none;
    background-color: #fff !important;
    background-image: none !important;
    border-color: #dee2e6 !important;
    opacity: 1;
}

/* Overlay "Processing…" de DataTables (sigue usando panel panel-default) */
.dataTables_processing.panel,
div.dataTables_wrapper .dataTables_processing {
    background-color: #fff;
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 10px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
}

/* ---------- Navbar oscuro: toggler visible en móvil ----------
   .navbar-default no activa las variables de .navbar-dark; el icono
   hamburguesa quedaba con stroke oscuro sobre fondo #24292E. */
.navbar.navbar-default {
    --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.35);
    --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.85%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}
.navbar.navbar-default .navbar-toggler {
    border-color: rgba(255, 255, 255, 0.35);
}
