/*================================================================================
	Item Name: Frest HTML Admin Template
	Version: 1.0
	Author: PIXINVENT
	Author URL: http://www.themeforest.net/user/pixinvent
================================================================================

NOTE:
------
PLACE HERE YOUR OWN SCSS CODES AND IF NEEDED, OVERRIDE THE STYLES FROM THE OTHER STYLESHEETS.
WE WILL RELEASE FUTURE UPDATES SO IN ORDER TO NOT OVERWRITE YOUR STYLES IT'S BETTER LIKE THIS.  */

/* -----------------------------------------------------------------------------
   Acciones de tablas (columna ACCIONES): los <button> (impresora, dinero,
   usuario, correo, etc.) deben comportarse igual que los <a> de acción:
   mismo color por defecto (#394c62), mismo hover azul (#175ee4), caja sin
   padding/bordes y MISMA línea base que los iconos <a> (vertical-align
   baseline pisa el "middle" que inyecta la clase .btn de Bootstrap, causante
   de los iconos corridos hacia abajo).
   ---------------------------------------------------------------------------- */
.invoice-action {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.25rem;
  /* La celda exige su ancho de una línea: evita que la columna de acciones
     se comprima y parta los iconos en "dos columnas" (ej. cadena de custodia).
     El wrap sigue disponible si el contenedor es realmente más angosto. */
  min-width: max-content;
}

.invoice-action > * {
  margin: 0 !important;
}

button.invoice-action-edit {
  color: #394c62;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  font-size: inherit;
  font-weight: inherit;
  line-height: 1;
  text-decoration: none;
  vertical-align: baseline;
}

button.invoice-action-edit:hover {
  color: #175ee4;
}

/* Anula el "top: 3px" que bootstrap-extended aplica a ".btn i" (centrado
   pensado para el padding original del botón): sin padding, ese empuje dejaba
   la impresora 3px más abajo que los demás iconos. */
button.invoice-action-edit i {
  color: inherit;
  position: static;
  top: auto;
}
/* ==========================================================================
   Quality Labs — capa de diseño propia (rama styling)
   --------------------------------------------------------------------------
   Este archivo se carga DESPUÉS de todo el CSS del tema y ANTES de @yield('css').
   Las páginas cargan datatables.min.css en @yield (o sea, DESPUÉS de aquí),
   así que las reglas que compiten con DataTables llevan el prefijo `body`
   para ganar por especificidad aunque el orden las ponga en desventaja.
   Sincronizar con: public/dist/assets/scss/style.scss
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Header — accesos rápidos, usuario, desplegables
   -------------------------------------------------------------------------- */

.header-navbar .bookmark-wrapper .bookmark-icons .nav-link,
.header-navbar .nav-link-expand,
.header-navbar .menu-toggle {
    color: #6E819C;
    border-radius: .5rem;
    transition: background-color .15s ease, color .15s ease;
}

.header-navbar .bookmark-wrapper .bookmark-icons .nav-link:hover,
.header-navbar .nav-link-expand:hover,
.header-navbar .menu-toggle:hover {
    background-color: rgba(90, 141, 238, .10);
    color: #5A8DEE;
}

.header-navbar .bookmark-wrapper .bookmark-icons .ficon {
    font-size: 1.3rem;
}

/* Usuario */
.dropdown-user-link .user-name {
    font-weight: 500;
    font-size: .95rem;
    color: #394C62;
}

.dropdown-user-link .user-status {
    font-size: .72rem;
    color: #828D99;
}

.dropdown-user-link img.round {
    box-shadow: 0 0 0 0 rgba(90, 141, 238, 0);
    transition: box-shadow .2s ease;
}

.dropdown-user-link:hover img.round {
    box-shadow: 0 0 0 3px rgba(90, 141, 238, .35);
}

/* Desplegables del header: el tema anima 0.8s (muy lento), borde y sombra suaves */
.header-navbar .navbar-container ul.nav li.dropdown .dropdown-menu {
    animation-duration: .18s;
    border: 1px solid #ECEEF2;
    border-radius: .5rem;
    box-shadow: 0 10px 30px rgba(36, 41, 61, .14);
    padding: .4rem 0;
}

.dropdown-item {
    transition: background-color .15s ease, color .15s ease;
}

.dropdown-item:hover {
    color: #5A8DEE;
    background-color: rgba(90, 141, 238, .10);
}

/* --------------------------------------------------------------------------
   2. Menú horizontal (barra de secciones)
   Nota: se ancla en #main-menu-navigation porque `.header-navbar` y
   `.navbar-expand-sm` viven en el MISMO div (el descendant combinator exige
   anidación estricta y no matcheaba).
   -------------------------------------------------------------------------- */

.horizontal-menu #main-menu-navigation > li > .nav-link {
    position: relative;
    transition: color .18s ease, background-color .18s ease;
}

/* Hover suave (gana a navbar-dark y al color base del tema) */
.horizontal-menu #main-menu-navigation > li:not(.active) > .nav-link:hover {
    background-color: rgba(90, 141, 238, .10);
    color: #5A8DEE;
}

/* Activo: tinte primario en vez del gris del tema + indicador animado */
.horizontal-menu #main-menu-navigation > li.active > .nav-link {
    background-color: rgba(90, 141, 238, .14);
    color: #5A8DEE;
    border-radius: 4px;
}

.horizontal-menu #main-menu-navigation > li > .nav-link::after {
    /* "" + !important anula el glifo chevron de bootstrap-extended
       (content: "\ea48" !important), que al posicionarse absoluto a la
       izquierda se solapaba con el icono del laboratorio al abrir el menu */
    content: "" !important;
    position: absolute;
    left: .85rem;
    right: .85rem;
    bottom: 3px;
    height: 3px;
    border-radius: 3px;
    background-color: #5A8DEE;
    transform: scaleX(0);
    transform-origin: center;
    transition: transform .25s ease;
}

.horizontal-menu #main-menu-navigation > li.active > .nav-link::after,
.horizontal-menu #main-menu-navigation > li.dropdown.show > .nav-link::after {
    transform: scaleX(1);
}

/* --------------------------------------------------------------------------
   3. Tablas — densidad, cabecera, filas
   -------------------------------------------------------------------------- */

/* Densidad: un poco más compacto que el default de Bootstrap (.75rem).
   Se excluye .table-sm para no pisar su propia densidad. */
.table:not(.table-sm) td,
.table:not(.table-sm) th {
    padding: .58rem .7rem;
    overflow-wrap: break-word;
}

/* Cabecera con fondo sutil para separarla del cuerpo.
   .thead-dark / .thead-light tienen mayor especificidad y siguen ganando. */
.table thead th {
    background-color: #F6F7F9;
}

/* Fila bajo el cursor (filas con clase propia: grupales/estados, no se tocan) */
.table tbody tr:not([class]) {
    transition: background-color .12s ease;
}

.table tbody tr:not([class]):hover {
    background-color: rgba(90, 141, 238, .06);
}

/* Botones de acciones en celdas: más compactos para que quepan en línea */
.table .btn-sm {
    padding: .22rem .45rem;
    font-size: .78rem;
    border-radius: .35rem;
    line-height: 1.35;
}

.table td .btn {
    vertical-align: middle;
}

/* Enlaces dentro de celdas: transición y subrayado al pasar */
.table td a:not(.btn) {
    transition: color .15s ease;
}

.table td a:not(.btn):hover {
    color: #4A78D6;
    text-decoration: underline;
}

/* Iconos de orden (boxicons dentro de las th): más livianos y sin doble flecha gritona */
.table.dataTable thead th.sorting::before,
.table.dataTable thead th.sorting::after,
.table.dataTable thead th.sorting_asc::before,
.table.dataTable thead th.sorting_asc::after,
.table.dataTable thead th.sorting_desc::before,
.table.dataTable thead th.sorting_desc::after,
.table.dataTable thead th.sorting_asc_disabled::before,
.table.dataTable thead th.sorting_asc_disabled::after,
.table.dataTable thead th.sorting_desc_disabled::before,
.table.dataTable thead th.sorting_desc_disabled::after {
    color: #B4BDCC;
    font-size: .85rem;
    top: 9px;
    right: 4px;
}

.table.dataTable thead th.sorting_asc::before,
.table.dataTable thead th.sorting_desc::after {
    color: #5A8DEE;
}

/* --------------------------------------------------------------------------
   4. DataTables — barra superior, información, paginación, vacío
   -------------------------------------------------------------------------- */

body div.dataTables_wrapper div.dataTables_length,
body div.dataTables_wrapper div.dataTables_filter {
    margin: .45rem 0 .2rem;
}

body div.dataTables_wrapper div.dataTables_length label,
body div.dataTables_wrapper div.dataTables_filter label {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: 0;
    font-size: .78rem;
    font-weight: 500;
    letter-spacing: .05em;
    color: #6E819C;
}

/* Buscador "Buscar:" contra el borde derecho de la tabla.
   El layout de DataTables + Bootstrap4 genera la barra superior como
   <'row'<'col-md-6'l><'col-md-6'f>>: el filtro vive en la columna derecha,
   pero datatables.min.css fuerza text-align:center y el input quedaba
   flotando a media tabla, sin ningún anclaje al borde.
   Se alinea el contenido de la columna al final, de modo que el input queda
   a ras del borde derecho (mismo sangrado de 15px que la tabla). */
body div.dataTables_wrapper div.dataTables_filter {
    float: none;
    text-align: right;
}

body div.dataTables_wrapper div.dataTables_filter label {
    justify-content: flex-end;
}

/* Altura común de los dos controles de la barra superior: el input
   (form-control, padding .42rem) era más alto que el select de
   "Mostrar N registros", los dos textos quedaban a distinta altura y la fila
   se veía torcida. */
body div.dataTables_wrapper div.dataTables_filter input,
body div.dataTables_wrapper div.dataTables_length select {
    height: 2.15rem;
}

/* Buscador de la tabla: caja con ícono a la derecha (misma idea que la búsqueda global) */
body div.dataTables_wrapper div.dataTables_filter input {
    display: inline-block;
    width: 13rem;
    max-width: 100%;
    margin-left: 0;
    padding: .42rem 2.15rem .42rem .8rem;
    font-size: .85rem;
    color: #475F7B;
    border: 1px solid #DFE3E7;
    border-radius: .5rem;
    background-color: #FFF;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23828D99' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='7' cy='7' r='5'/%3E%3Cpath d='M11 11l4 4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .65rem center;
    transition: border-color .15s ease, box-shadow .15s ease;
    -webkit-appearance: none;
    appearance: none;
}

body div.dataTables_wrapper div.dataTables_filter input:focus {
    outline: 0;
    border-color: #5A8DEE;
    box-shadow: 0 0 0 .175rem rgba(90, 141, 238, .18);
}

body div.dataTables_wrapper div.dataTables_length select {
    font-size: .82rem;
    border: 1px solid #DFE3E7;
    border-radius: .45rem;
    transition: border-color .15s ease, box-shadow .15s ease;
}

body div.dataTables_wrapper div.dataTables_length select:focus {
    outline: 0;
    border-color: #5A8DEE;
    box-shadow: 0 0 0 .175rem rgba(90, 141, 238, .18);
}

body div.dataTables_wrapper div.dataTables_info {
    padding-top: .9rem;
    font-size: .8rem;
    color: #828D99;
}

body div.dataTables_wrapper div.dataTables_paginate ul.pagination {
    margin: .65rem 0 .3rem;
}

/* Estado vacío */
body table.dataTable tbody td.dataTables_empty {
    padding: 2.5rem 1rem;
    color: #828D99;
    font-size: .88rem;
}

/* Resaltado sutil de la coincidencia del buscador dentro de las celdas.
   Lo pinta el JS global (mark.ql-search-hit) al escribir en el input
   "Buscar" de cada tabla. Hereda el color del texto, solo tiñe el fondo. */
body table.dataTable tbody mark.ql-search-hit {
    background-color: rgba(90, 141, 238, .28);
    color: inherit;
    border-radius: 2px;
    padding: 0 1px;
}

/* --------------------------------------------------------------------------
   5. Paginación (en DataTables y en cualquier otra vista)
   -------------------------------------------------------------------------- */

.pagination {
    flex-wrap: wrap;
}

.pagination .page-item .page-link {
    min-width: 2rem;
    margin: 0 2px;
    padding: .32rem .65rem;
    font-size: .85rem;
    color: #596F88;
    border: 1px solid transparent;
    border-radius: .4rem;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease;
}

.pagination .page-item:not(.disabled) .page-link:hover {
    background-color: rgba(90, 141, 238, .12);
    border-color: rgba(90, 141, 238, .30);
    color: #5A8DEE;
}

.pagination .page-item.active .page-link {
    background-color: #5A8DEE;
    border-color: #5A8DEE;
    color: #FFF;
    font-weight: 500;
    box-shadow: 0 2px 6px rgba(90, 141, 238, .38);
}

.pagination .page-item.disabled .page-link {
    background-color: #F5F6F8;
    border-color: transparent;
    color: #A3AFBD;
}

/* --------------------------------------------------------------------------
   6. Cards — elevación y cabecera
   -------------------------------------------------------------------------- */

.card {
    border: 1px solid #E9ECF0;
    border-radius: .55rem;
    box-shadow: 0 1px 2px rgba(36, 41, 61, .04), 0 8px 24px rgba(36, 41, 61, .05);
}

.card > .card-header {
    background-color: #FFF;
    border-bottom: 1px solid #EEF0F3;
}

.card-title {
    color: #394C62;
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   7. Formularios y botones
   -------------------------------------------------------------------------- */

.form-control {
    transition: border-color .15s ease, box-shadow .15s ease;
}

.form-control:focus {
    border-color: #5A8DEE;
    box-shadow: 0 0 0 .175rem rgba(90, 141, 238, .16);
}

/* Nota: btn-light del tema queda GRIS sólido a propósito (colors.css lo fija
   con !important) y no se usa en ninguna vista; si hace falta un botón neutro
   claro, usar la variante del tema .btn-light-secondary (bg #E6EAEE). */

/* Anillo de foco unificado para todos los botones (el tema define anillos
   distintos por variante) */
.btn:focus,
.btn.focus {
    box-shadow: 0 0 0 .175rem rgba(90, 141, 238, .35);
}

/* --------------------------------------------------------------------------
   8. Breadcrumbs, alertas y SweetAlert2
   -------------------------------------------------------------------------- */

/* Breadcrumbs (cabecera de páginas) */
.breadcrumb .breadcrumb-item a {
    transition: color .15s ease;
}

.breadcrumb .breadcrumb-item a:hover {
    color: #5A8DEE;
}

.breadcrumb .breadcrumb-item.active {
    color: #394C62;
}

.breadcrumb .breadcrumb-item + .breadcrumb-item::before {
    color: #A3AFBD;
}

/* Alertas (validaciones, estados) */
.alert {
    border: 0;
    border-radius: .5rem;
    box-shadow: 0 2px 10px rgba(36, 41, 61, .07);
    font-size: .9rem;
    padding: .95rem 1.15rem;
}

.alert .close {
    opacity: .45;
    text-shadow: none;
}

.alert .close:hover {
    opacity: .9;
}

/* SweetAlert2 (sólo se usan toasts en la app): acorde al tema */
body .swal2-popup.swal2-toast {
    border-radius: .6rem;
    box-shadow: 0 10px 30px rgba(36, 41, 61, .18);
    font-family: "Rubik", Helvetica, Arial, serif;
    padding: .7rem 1.1rem;
    margin: .75rem;
}

body .swal2-popup.swal2-toast .swal2-title {
    font-size: .95rem;
    font-weight: 500;
    color: #394C62;
}

body .swal2-popup.swal2-toast .swal2-html-container,
body .swal2-popup.swal2-toast .swal2-content {
    font-size: .85rem;
    color: #596F88;
}

body .swal2-timer-progress-bar {
    background-color: #5A8DEE;
}

body .swal2-confirm,
body .swal2-styled.swal2-confirm {
    background-color: #5A8DEE;
    border-radius: .4rem;
}

body .swal2-confirm:hover,
body .swal2-styled.swal2-confirm:hover {
    background-color: #4A78D6;
}

body .swal2-styled.swal2-confirm:focus {
    box-shadow: 0 0 0 .175rem rgba(90, 141, 238, .35);
}

body .swal2-cancel,
body .swal2-styled.swal2-cancel {
    background-color: #FFF;
    border: 1px solid #DFE3E7;
    border-radius: .4rem;
    color: #596F88;
}

body .swal2-cancel:hover,
body .swal2-styled.swal2-cancel:hover {
    background-color: #F2F4F4;
}

/* --------------------------------------------------------------------------
   9. Modales
   -------------------------------------------------------------------------- */

.modal-content {
    border: 0;
    border-radius: .6rem;
    box-shadow: 0 24px 60px rgba(36, 41, 61, .28);
}

.modal-footer {
    flex-wrap: wrap;
    row-gap: .5rem;
    column-gap: .5rem;
}

/* --------------------------------------------------------------------------
   10. Responsividad
   -------------------------------------------------------------------------- */

@media (max-width: 991.98px) {
    html body .content .content-wrapper {
        padding: 1.5rem 1.25rem 0;
    }
}

@media (max-width: 767.98px) {
    /* Tablas más compactas en pantallas chicas */
    .table:not(.table-sm) td,
    .table:not(.table-sm) th {
        padding: .5rem .5rem;
    }

    /* Buscador de tabla a todo el ancho */
    body div.dataTables_wrapper div.dataTables_filter input {
        width: 100%;
        flex: 1 1 auto;
        min-width: 0;
    }
}

@media (max-width: 575.98px) {
    html body .content .content-wrapper {
        padding: 1rem .85rem 0;
    }

    .modal-dialog {
        margin: .75rem auto;
        max-width: calc(100% - 1.5rem);
    }
}

/* --------------------------------------------------------------------------
   11. Detalles globales — scrollbar, selección, foco, movimiento reducido
   -------------------------------------------------------------------------- */

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background-color: #C6CDD9;
    border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
    background-color: #A8B1C1;
}

::-webkit-scrollbar-corner {
    background: transparent;
}

::selection {
    background-color: rgba(90, 141, 238, .28);
}

a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid rgba(90, 141, 238, .65);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* --------------------------------------------------------------------------
   12. Fondos animados ("aurora") — login y ruta /
   --------------------------------------------------------------------------
   Sólo se pinta donde exista el marcador <div class="ql-bg" aria-hidden="true">
   (auth/login.blade.php y home-landing.blade.php, vía @yield('page_bg')).

   Coste de rendimiento, medido a propósito:
   · el degradado base es position:fixed => se rasteriza UNA vez, no se repinta
     con el scroll (no usamos background-attachment: fixed, que sí cuesta);
   · la única animación mueve el glow con transform => trabaja el compositor,
     0 repintado y 0 CPU (nada de animar background-position ni box-shadow);
   · sin filter: blur(), sin backdrop-filter, sin canvas, sin librerías ni
     peticiones de red.
   -------------------------------------------------------------------------- */

.ql-bg {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    /* Detrás del contenido (que es position:relative) y encima del fondo del
       body: no tapa nada, ni siquiera los clics. */
    z-index: -1;
    pointer-events: none;
    overflow: hidden;
}

/* --- Login: azul medio y luminoso; la tarjeta blanca mantiene contraste --- */
html body.ql-auth-bg {
    /* El tema traía una foto (auth-bg.jpg): aquí manda el degradado. */
    background: linear-gradient(158deg, #0C2F5C 0%, #14508F 48%, #1F6FBB 100%);
    background-attachment: scroll;
}

.ql-bg--auth {
    background:
        radial-gradient(56% 50% at 14% 8%, rgba(45, 140, 235, .50), transparent 66%),
        radial-gradient(50% 46% at 90% 14%, rgba(120, 170, 245, .38), transparent 64%),
        radial-gradient(76% 60% at 50% 118%, rgba(45, 140, 235, .52), transparent 66%);
}

/* Luz fija en la esquina superior derecha */
.ql-bg--auth::before {
    content: "";
    position: absolute;
    top: -16vmax;
    right: -12vmax;
    width: 44vmax;
    height: 44vmax;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(174, 205, 255, .34), transparent 72%);
}

/* Luz a la deriva: la única animación de la página */
.ql-bg--auth::after {
    content: "";
    position: absolute;
    left: -14vmax;
    bottom: -20vmax;
    width: 62vmax;
    height: 62vmax;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(45, 140, 235, .45), transparent 70%);
    animation: ql-bg-drift 36s ease-in-out infinite alternate;
    will-change: transform;
}

/* --- Home (/): aurora clara; las tarjetas siguen mandando sobre el fondo --- */
.ql-bg--home {
    background:
        radial-gradient(54% 48% at 4% -6%, rgba(90, 141, 238, .30), transparent 68%),
        radial-gradient(46% 42% at 98% 4%, rgba(0, 207, 221, .18), transparent 68%),
        radial-gradient(70% 58% at 55% 112%, rgba(13, 139, 245, .22), transparent 68%),
        linear-gradient(165deg, #E9F1FF 0%, #F3F7FD 55%, #F2F4F4 100%);
}

.ql-bg--home::after {
    content: "";
    position: absolute;
    top: -18vmax;
    right: -14vmax;
    width: 54vmax;
    height: 54vmax;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(90, 141, 238, .24), transparent 70%);
    animation: ql-bg-drift 44s ease-in-out infinite alternate;
    will-change: transform;
}

/* Desplazamiento puro: sólo transform (GPU), sin repintado */
@keyframes ql-bg-drift {
    from {
        transform: translate3d(0, 0, 0) scale(1);
    }

    to {
        transform: translate3d(-16vmax, 18vmax, 0) scale(1.14);
    }
}

/* Red de partículas (public/dist/assets/js/ql-particles.js): canvas que ocupa
   la capa .ql-bg entera y hereda su z-index y pointer-events:none. */
.ql-particles {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: block;
}

/* --- Logo flotante de la ruta / ---
   El logo sube y baja con un leve balanceo; la sombra elíptica de abajo se
   achica y aclara cuando él sube. Sólo transform/opacity => compositor. El
   drop-shadow del logo es estático: se rasteriza una vez dentro de su capa. */
.ql-logo-float {
    position: relative;
    display: inline-block;
    padding-bottom: 2.2rem;
}

.ql-logo-float img {
    position: relative;
    z-index: 1;
    filter: drop-shadow(0 14px 18px rgba(20, 70, 150, .18));
    animation: ql-logo-float 7s ease-in-out infinite;
    will-change: transform;
}

.ql-logo-float::after {
    content: "";
    position: absolute;
    left: 18%;
    right: 18%;
    bottom: .4rem;
    height: 18px;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(20, 60, 130, .28), transparent);
    animation: ql-logo-shadow 7s ease-in-out infinite;
    will-change: transform, opacity;
}

@keyframes ql-logo-float {
    0%, 100% {
        transform: translate3d(0, 0, 0) rotate(0deg);
    }

    25% {
        transform: translate3d(0, -10px, 0) rotate(-.6deg);
    }

    50% {
        transform: translate3d(0, -16px, 0) rotate(0deg);
    }

    75% {
        transform: translate3d(0, -8px, 0) rotate(.6deg);
    }
}

@keyframes ql-logo-shadow {
    0%, 100% {
        transform: scaleX(1);
        opacity: 1;
    }

    50% {
        transform: scaleX(.78);
        opacity: .55;
    }
}

/* Accesibilidad y batería: quien pida menos movimiento, no lo ve */
@media (prefers-reduced-motion: reduce) {

    .ql-bg--auth::after,
    .ql-bg--home::after,
    .ql-logo-float img,
    .ql-logo-float::after {
        animation: none;
    }
}



/* ============================================================
   13. Cards de Parametros > Entorno (hover)
   Alcance: solo las vistas con <section id="widgets-Statistics" class="ql-entorno">
   Entorno, Muestras, Analisis, Inventarios y Equipos.
   ============================================================ */
#widgets-Statistics.ql-entorno .card {
    position: relative;
    transition: transform .25s ease, box-shadow .25s ease, background-color .25s ease, border-color .25s ease;
}

#widgets-Statistics.ql-entorno .card:hover {
    z-index: 3;
    transform: scale(1.05);
    background-color: #F3F7FE;
    border-color: #BFD3FA;
    box-shadow: 0 12px 26px rgba(90, 141, 238, .30), 0 3px 8px rgba(36, 41, 61, .10);
}

#widgets-Statistics.ql-entorno .card:hover .livicon-evo [stroke]:not([stroke="none"]),
#widgets-Statistics.ql-entorno .card:hover .badge-circle svg [stroke]:not([stroke="none"]) {
    stroke: #5A8DEE;
}

/* Quien pide menos movimiento: sin crecer ni sombra */
@media (prefers-reduced-motion: reduce) {

    #widgets-Statistics.ql-entorno .card,
    #widgets-Statistics.ql-entorno .card:hover {
        transform: none;
        transition: none;
    }
}

/* ============================================================
   14. Acciones de tablas — label en hover (tooltip propio)
   ============================================================ */
.invoice-action-edit {
    position: relative;
}

.invoice-action-edit::after {
    content: attr(data-ql-tip);
    position: absolute;
    bottom: calc(100% + 7px);
    left: 50%;
    transform: translateX(-50%) translateY(3px);
    max-width: 220px;
    padding: .28rem .6rem;
    font-size: .72rem;
    font-weight: 500;
    line-height: 1.3;
    white-space: nowrap;
    color: #FFF;
    background-color: #394C62;
    border-radius: .35rem;
    box-shadow: 0 4px 12px rgba(36, 41, 61, .25);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .15s ease, transform .15s ease, visibility .15s;
    z-index: 1080;
}

.invoice-action-edit::before {
    content: "";
    position: absolute;
    bottom: calc(100% + 2px);
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: #394C62;
    border-bottom: 0;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .15s ease, visibility .15s;
    z-index: 1080;
}

.invoice-action-edit[data-ql-tip]:hover::after,
.invoice-action-edit[data-ql-tip]:focus-visible::after,
.invoice-action-edit[data-ql-tip]:hover::before,
.invoice-action-edit[data-ql-tip]:focus-visible::before {
    opacity: 1;
    visibility: visible;
}

.invoice-action-edit[data-ql-tip]:hover::after,
.invoice-action-edit[data-ql-tip]:focus-visible::after {
    transform: translateX(-50%) translateY(0);
}

/* Color según la acción, en el ícono: base.blade.php pone data-ql-tone
   leyendo el label (Eliminar -> danger, Aprobar/Liberar/Abrir -> success,
   Devolver/Cerrar -> warning, Ver/Imprimir/Correo -> info,
   Editar/Agregar -> primary; el resto, neutral). Cada ícono queda en una
   ficha con un tinte suave de su color, que se intensifica en hover. Tonos
   oscurecidos de la paleta del tema (>= 3.9:1 sobre el tinte, mínimo para
   íconos 3:1); en temas
   oscuros, sus variantes claras. --ql-tone es "r, g, b" para usarlo en
   rgb() y rgba(). */
.invoice-action-edit[data-ql-tone] {
    --ql-tone: 57, 76, 98;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: .45rem;
    color: rgb(var(--ql-tone)) !important;
    background-color: rgba(var(--ql-tone), .10);
    vertical-align: middle;
    text-decoration: none;
    transition: background-color .15s ease, color .15s ease;
}

.invoice-action-edit[data-ql-tone] + .invoice-action-edit[data-ql-tone] {
    margin-left: .3rem !important;
}

.invoice-action-edit[data-ql-tone] i {
    color: inherit !important;
}

.invoice-action-edit[data-ql-tone]:hover,
.invoice-action-edit[data-ql-tone]:focus-visible {
    background-color: rgba(var(--ql-tone), .20);
}

.invoice-action-edit[data-ql-tone="danger"]  { --ql-tone: 201, 48, 44; }
.invoice-action-edit[data-ql-tone="success"] { --ql-tone: 30, 123, 75; }
.invoice-action-edit[data-ql-tone="warning"] { --ql-tone: 166, 90, 0; }
.invoice-action-edit[data-ql-tone="info"]    { --ql-tone: 11, 112, 135; }
.invoice-action-edit[data-ql-tone="primary"] { --ql-tone: 52, 97, 193; }

html[data-theme-mode="dark"] .invoice-action-edit[data-ql-tone]           { --ql-tone: 196, 207, 222; }
html[data-theme-mode="dark"] .invoice-action-edit[data-ql-tone="danger"]  { --ql-tone: 255, 128, 128; }
html[data-theme-mode="dark"] .invoice-action-edit[data-ql-tone="success"] { --ql-tone: 102, 214, 154; }
html[data-theme-mode="dark"] .invoice-action-edit[data-ql-tone="warning"] { --ql-tone: 255, 186, 92; }
html[data-theme-mode="dark"] .invoice-action-edit[data-ql-tone="info"]    { --ql-tone: 92, 208, 228; }
html[data-theme-mode="dark"] .invoice-action-edit[data-ql-tone="primary"] { --ql-tone: 140, 176, 255; }

html[data-theme-mode="dark"] .invoice-action-edit[data-ql-tone] {
    background-color: rgba(var(--ql-tone), .14);
}

html[data-theme-mode="dark"] .invoice-action-edit[data-ql-tone]:hover,
html[data-theme-mode="dark"] .invoice-action-edit[data-ql-tone]:focus-visible {
    background-color: rgba(var(--ql-tone), .26);
}

@media (prefers-reduced-motion: reduce) {

    .invoice-action-edit::after,
    .invoice-action-edit::before {
        transition: none;
    }
}

/* ==========================================================================
   15. Profundidad, luz y micro-interacciones
   --------------------------------------------------------------------------
   Capa ADITIVA: no cambia colores de marca, tipografías ni estructuras; sólo
   suma degradados muy tenues, sombras escalonadas y transiciones sobre lo que
   ya pinta el tema (Frest / Bootstrap 4). Objetivo: que la app deje de verse
   plana sin tocar UNA sola línea de HTML.

   Reglas de convivencia con el tema, verificadas en su CSS:
   · colors.css fija `.btn-primary`, `.bg-rgba-*` etc. con
     `background: ... !important`, y ese atajo además reinicia background-image.
     Por eso los degradados de esos elementos se declaran con `background-image`
     (+ `!important` donde hace falta) y NUNCA con el atajo `background`: así el
     color del tema sigue mandando y nosotros sólo añadimos luz encima.
   · bootstrap-extended pone `box-shadow: none !important` en .btn:focus /
     .btn:active y en `.header-navbar.navbar-static-top`. No se lucha contra
     eso: no se declara sombra propia en esos estados (al pulsar un botón la
     sombra se va, que es exactamente el comportamiento que ya tenía).
   · `transform` sólo en .card y .btn, nunca en filas ni celdas de tabla: un
     translate de 1-2px no provoca reflow y no molesta a DataTables.
   · Todo entra en el bloque global de `prefers-reduced-motion` de la sección
     11, así que quien pida menos movimiento no recibe ninguna animación.
   ========================================================================== */

/* --- 15.1 Fondo del shell: degradado vertical corto, da profundidad arriba ---
   Sólo el layout interno (horizontal-layout + horizontal-menu). Las páginas
   públicas (blank-page: login, registro, solicitudes) quedan fuera a propósito:
   tienen su propio fondo (aurora / bg-full-screen-image) y no queremos pisarlo. */
html body.horizontal-layout.horizontal-menu:not(.blank-page) {
    background-color: #F2F4F4;
    background-image: linear-gradient(180deg, #F6F9FD 0%, #F2F4F4 340px);
    background-repeat: no-repeat;
}

/* --- 15.2 Cabecera: luz en vez de plano ---
   El tema ya le pone #F2F4F4 + filete inferior; acá sólo aclaramos la mitad
   superior para que la barra "respire" y gane separación del contenido. */
.horizontal-menu .header-navbar {
    background-image: linear-gradient(180deg, #FCFDFE 0%, #F0F3F8 100%);
}

/* --- 15.3 Botones: brillo, sombra de apoyo y 1px de despegue --- */
.btn {
    transition: color .15s ease, background-color .2s ease, border-color .2s ease,
        box-shadow .2s ease, transform .15s ease;
}

/* Brillo vertical + sombra de apoyo en los botones de color.
   `.btn-light-secondary` incluida: es el neutro claro del tema (colors.css
   bloquea .btn-light con !important, por eso esa variante no está en la lista). */
.btn-primary,
.btn-success,
.btn-danger,
.btn-warning,
.btn-info,
.btn-dark,
.btn-light-secondary {
    background-image: linear-gradient(180deg,
            rgba(255, 255, 255, .22) 0%,
            rgba(255, 255, 255, 0) 45%,
            rgba(0, 0, 0, .07) 100%);
    box-shadow: 0 2px 5px rgba(36, 41, 61, .14), 0 1px 2px rgba(36, 41, 61, .08);
}

/* Al pasar el cursor: la sombra se tiñe del color del botón (mismo tono del
   tema, sólo que difuminado hacia afuera) */
.btn-primary:hover,
.btn-primary.hover {
    box-shadow: 0 5px 14px rgba(90, 141, 238, .38), 0 1px 3px rgba(36, 41, 61, .12);
}

.btn-success:hover,
.btn-success.hover {
    box-shadow: 0 5px 14px rgba(57, 218, 138, .38), 0 1px 3px rgba(36, 41, 61, .12);
}

.btn-danger:hover,
.btn-danger.hover {
    box-shadow: 0 5px 14px rgba(255, 91, 92, .38), 0 1px 3px rgba(36, 41, 61, .12);
}

.btn-warning:hover,
.btn-warning.hover {
    box-shadow: 0 5px 14px rgba(253, 172, 65, .40), 0 1px 3px rgba(36, 41, 61, .12);
}

.btn-info:hover,
.btn-info.hover {
    box-shadow: 0 5px 14px rgba(0, 207, 221, .38), 0 1px 3px rgba(36, 41, 61, .12);
}

.btn-dark:hover,
.btn-dark.hover,
.btn-light-secondary:hover,
.btn-light-secondary.hover {
    box-shadow: 0 5px 14px rgba(36, 41, 61, .22), 0 1px 3px rgba(36, 41, 61, .12);
}

/* El despegue: 1px hacia arriba, sin reflow. Al pulsar vuelve a su sitio. */
.btn:hover,
.btn.hover {
    transform: translateY(-1px);
}

.btn:active,
.btn.active {
    transform: translateY(0);
}

/* --- 15.4 Tarjetas: cabecera con luz y elevación al pasar el cursor --- */
.card {
    transition: box-shadow .25s ease, transform .25s ease, border-color .25s ease;
}

/* `.no-card-shadow` es la clase de escape que ya trae el tema: se respeta.
   Las tarjetas anidadas (.card .card) las deja planas el propio tema con
   `box-shadow: none !important`, así que no hace falta excluirlas a mano. */
.card:not(.no-card-shadow):hover {
    transform: translateY(-2px);
    box-shadow: 0 2px 4px rgba(36, 41, 61, .05), 0 16px 34px rgba(36, 41, 61, .10);
}

/* Cabecera y pie: degradado casi invisible que rompe el plano blanco.
   Se saltean las cabeceras de color (bg-*), que deben seguir sólidas. */
.card > .card-header:not([class*="bg-"]) {
    background-image: linear-gradient(180deg, #FFFFFF 0%, #FAFBFD 100%);
}

.card > .card-footer {
    background-image: linear-gradient(180deg, #FAFBFD 0%, #FFFFFF 100%);
}

/* --- 15.5 Tablas: cabecera con degradado, cebra suave y marca de foco --- */
.table:not(.table-dark) thead:not(.thead-dark):not(.thead-light) th {
    background-image: linear-gradient(180deg, #F8FAFC 0%, #EDF1F7 100%);
    border-bottom: 1px solid #DCE3EC;
    color: #394C62;
    font-size: .8rem;
    letter-spacing: .04em;
}

/* Cebra muy suave. Sólo filas SIN clase propia: las que sí la tienen
   (tr.group, estados, seleccionadas...) conservan su color intacto.
   El `:not(:hover)` es imprescindible: sin él, esta regla (misma especificidad
   que el hover de la sección 3 pero más abajo en el archivo) ganaría y las
   filas pares perderían el tinte azul al pasar el cursor. */
.table tbody tr:not([class]):nth-of-type(even):not(:hover) {
    background-color: #FAFBFD;
}

/* Marca de foco a la izquierda. Se pinta en la primera celda y no en el <tr>
   porque box-shadow sobre table-row no es comportamiento fiable en todos los
   navegadores; sobre <td> sí lo es. */
.table tbody tr:not([class]):hover td:first-child {
    box-shadow: inset 3px 0 0 rgba(90, 141, 238, .45);
}

/* Separadores de fila teñidos del color primario: el azul de marca por defecto
   y, con un tema elegido (perfil > Apariencia), el --qt-primary-rgb que inyecta
   el layout (themes.css repite la regla para ganarle a su borde neutro).
   Arriba y abajo con el mismo color: la celda trae los dos bordes y uno gris
   taparía al otro. Sólo pantalla: al imprimir quedan los grises del tema. */
@media screen {
    .table:not(.table-bordered) td {
        border-top-color: rgba(var(--qt-primary-rgb, 90, 141, 238), .38);
        border-bottom-color: rgba(var(--qt-primary-rgb, 90, 141, 238), .38);
    }
}

/* --- 15.6 Formularios: los campos dejan de ser planos --- */
.form-control,
.custom-select {
    box-shadow: 0 1px 2px rgba(36, 41, 61, .05);
}

/* Checkboxes/radios nativos (los del tema van ocultos tras su propio markup):
   en los navegadores que soportan accent-color, el color de marca manda. */
input[type="checkbox"],
input[type="radio"] {
    accent-color: #5A8DEE;
}

/* --- 15.7 Insignias (badges): volumen sin perder el color del tema --- */
.badge:not(.badge-circle):not([class*="border-"]) {
    border-radius: .35rem;
    font-weight: 500;
    letter-spacing: .03em;
    background-image: linear-gradient(180deg,
            rgba(255, 255, 255, .20) 0%,
            rgba(255, 255, 255, 0) 60%);
    box-shadow: 0 1px 2px rgba(36, 41, 61, .12);
}

/* --- 15.8 Avatares e iconos de listas (dashboard) ---
   Único !important de la sección, y es obligatorio: colors.css aplica
   `background: ... !important` a `.bg-rgba-*` y ese atajo reiniciaría el
   degradado. Sin él la regla simplemente no se vería. */
.avatar.bg-rgba-primary {
    background-image: linear-gradient(135deg,
            rgba(90, 141, 238, .30) 0%,
            rgba(90, 141, 238, .12) 100%) !important;
}

.avatar {
    transition: transform .2s ease, box-shadow .2s ease;
}

.list-group-item-action:hover .avatar {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(90, 141, 238, .28);
}

/* --- 15.9 Pestañas, progresos y listas --- */
.nav-pills .nav-link {
    transition: background-color .2s ease, color .2s ease,
        box-shadow .2s ease, transform .15s ease;
}

.nav-pills .nav-link:not(.active):hover {
    background-color: #EDF1F7;
}

.nav-pills .nav-link.active {
    background-image: linear-gradient(180deg,
            rgba(255, 255, 255, .22),
            rgba(255, 255, 255, 0));
}

.progress-bar {
    background-image: linear-gradient(180deg,
            rgba(255, 255, 255, .30) 0%,
            rgba(255, 255, 255, 0) 55%);
}

.list-group-item-action {
    transition: background-color .15s ease;
}

/* El tema pinta #F2F4F4 (gris); mismo peso, mismo sitio, tinte de marca */
.list-group-item-action:hover {
    background-color: rgba(90, 141, 238, .06);
}

/* --- 15.10 Pie de página y cabecera de contenido --- */
.footer {
    border-top: 1px solid #E9ECF0;
    background-image: linear-gradient(180deg, #FFFFFF 0%, #F6F8FB 100%);
    color: #828D99;
    font-size: .85rem;
}

.footer a {
    color: #596F88;
    transition: color .15s ease;
}

.footer a:hover {
    color: #5A8DEE;
}

/* Segunda línea de créditos, bajo "realizado con ♥ por TPG": más chica,
   en cursiva y atenuada para que no compita con la primera. Con ella el pie
   lleva menos aire arriba y abajo, para no crecer (la portada / mide
   70vh + pie y no debe aparecerle scroll). */
footer.footer {
    padding-top: .55rem;
    padding-bottom: .55rem;
}

/* Pegada a la línea de arriba: el -3px compensa el interlineado de esa línea. */
.footer .ql-footer-credit {
    display: block;
    margin-top: -3px;
    font-size: .72rem;
    font-style: italic;
    line-height: 1.1;
    opacity: .75;
}

.footer .ql-footer-coffee {
    font-style: normal;
}

.footer .btn.scroll-top {
    box-shadow: 0 6px 18px rgba(90, 141, 238, .35);
}

/* Pie siempre pegado al fondo de la pantalla. El tema lo lograba con
   `.content { min-height: calc(100% - 12.5rem) }`, que supone cabecera +
   barra de secciones + pie de 12.5rem exactos: si el pie es más bajo, o bajo
   1200 px (cabecera de 3.5rem y sin barra de secciones), quedaba un hueco
   bajo el pie. Con el <body> en columna (ya mide 100% de la pantalla) el
   contenido ocupa lo que sobre, midan lo que midan cabecera y pie. Los demás
   hijos del <body> son fixed/ocultos o scripts y no entran en el reparto. */
html body.horizontal-layout:not(.blank-page) {
    display: flex;
    flex-direction: column;
}

html body.horizontal-layout:not(.blank-page) > .app-content {
    flex: 1 0 auto;
    min-height: 0;
}

html body.horizontal-layout:not(.blank-page) > footer.footer {
    flex-shrink: 0;
}

/* Título de página y migas: mismo lenguaje visual que el resto de la capa.
   El prefijo `html body` copia la especificidad del tema para poder ganarle. */
html body .content .content-wrapper .content-header-title {
    color: #394C62;
    font-weight: 600;
    border-right-color: #DFE3EC;
}

html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item a {
    transition: color .15s ease;
}

html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item + .breadcrumb-item::before {
    color: #B9C2CE;
}

/* Sección actual como "ficha" de ubicación: borde y punto del color del tema,
   fondo de tarjeta y negrita; al entrar a la página la ficha se desliza y el
   punto destella. Se marca de dos formas en las vistas:
     · <li class="breadcrumb-item active">Texto</li>  (maestros, CRM...)
     · <li class="breadcrumb-item"><a class="text-primary">Fase</a></li>
       (flujos de laboratorio: la fase actual es un enlace en medio)
   Con .active la ficha es el <li>, así que su separador se saca afuera y
   queda centrado en el hueco de la izquierda. Los colores salen de los
   tokens del tema (--qt-*), con los del aspecto original como respaldo. */
html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb {
    align-items: center;
}

html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item.active,
html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item a.text-primary {
    position: relative;
    display: inline-block;
    padding: .05rem .7rem .05rem 1.4rem;
    border: 1px solid rgba(var(--qt-primary-rgb, 90, 141, 238), .45);
    border-radius: 999px;
    background-color: var(--qt-surface, #FFFFFF);
    box-shadow: 0 1px 3px rgba(var(--qt-primary-rgb, 90, 141, 238), .18);
    color: var(--qt-heading-strong, #394C62) !important;
    font-weight: 600;
    animation: ql-crumb-in .3s ease-out both;
}

html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item a.text-primary:hover {
    text-decoration: none;
}

html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item + .breadcrumb-item.active {
    margin-left: 1.6rem;
    padding-left: 1.4rem;
}

html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item + .breadcrumb-item.active::before {
    position: absolute;
    top: 50%;
    right: 100%;
    width: 1.6rem;
    padding: 0;
    text-align: center;
    transform: translateY(-50%);
}

html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item.active::after,
html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item a.text-primary::after {
    content: "";
    position: absolute;
    top: 50%;
    left: .6rem;
    width: .45rem;
    height: .45rem;
    margin-top: -.225rem;
    border-radius: 50%;
    background-color: var(--qt-primary-ink-page, #5A8DEE);
    animation: ql-crumb-ping 1.4s ease-out .3s 2;
}

@keyframes ql-crumb-in {
    from { opacity: 0; transform: translateX(-.4rem); }
    to   { opacity: 1; transform: none; }
}

@keyframes ql-crumb-ping {
    0%   { box-shadow: 0 0 0 0 rgba(var(--qt-primary-rgb, 90, 141, 238), .55); }
    100% { box-shadow: 0 0 0 .45rem rgba(var(--qt-primary-rgb, 90, 141, 238), 0); }
}

@media (prefers-reduced-motion: reduce) {
    html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item.active,
    html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item a.text-primary,
    html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item.active::after,
    html body .content .content-wrapper .breadcrumb-wrapper .breadcrumb .breadcrumb-item a.text-primary::after {
        animation: none;
    }
}

/* --- 15.13 Columna de acciones fijada al borde derecho de la tabla ---
   Problema: en pantallas de ~15" la tabla más ancha que su `.table-responsive`
   se scrollea en horizontal y la columna ACCIONES queda cortada en el borde
   (el icono del tacho se ve a medias). Hoy el usuario tiene que scrollear
   hasta el final para descubrir la columna.

   Solución SIN tocar HTML ni el JS que arma las filas (DataTables en muchas
   vistas): dejar la última columna "pegada" al borde derecho del scroll.
   Requisitos de `position: sticky` en celdas:
   · un ancestro con overflow: lo aporta `.table-responsive` de Bootstrap 4;
   · fondo OPACO en la celda fijada (si no, se transparenta el contenido que
     pasa por detrás al scrollear) -> cada estado de fila declara el suyo;
   · separación con `box-shadow` y NO con border: con `border-collapse:
     collapse` los bordes de una celda sticky pueden no pintarse (Safari).

   Detalle de apilado: la cabecera lleva z-index (queda por encima
   del cuerpo) y las celdas del cuerpo no. Ojo: sticky crea contexto de
   apilamiento aunque no lleve z-index, así que el label de las acciones
   (`.invoice-action-edit`, sección 14) no puede salir por encima de la
   cabecera: por eso la celda sube a z-index 4 sólo mientras se usa (abajo).
   */
.table-responsive .table thead th:last-child {
    position: sticky;
    right: 0;
    z-index: 3;
    /* Mismo degradado que la cabecera normal (15.5), para que no se note el
       corte entre la celda fijada y el resto de la fila. */
    background-color: #EDF1F7;
    background-image: linear-gradient(180deg, #F8FAFC 0%, #EDF1F7 100%);
    box-shadow: -1px 0 0 rgba(36, 41, 61, .12);
}

.table-responsive .table tbody td:last-child {
    position: sticky;
    right: 0;
    background-color: #FFF;
    box-shadow: -1px 0 0 rgba(36, 41, 61, .12);
}

/* Mientras se usa una acción, la celda fijada sube por sobre la cabecera
   (z-index 3): sticky siempre crea contexto de apilamiento, así que sin esto
   el label de la primera fila, que se dibuja hacia arriba, quedaba detrás
   del encabezado de ACCIONES. */
.table-responsive .table tbody td:last-child:hover,
.table-responsive .table tbody td:last-child:focus-within {
    z-index: 4;
}

/* Cebra: mismo color que la regla de 15.5, para que la celda fijada no
   desentone del resto de la fila. */
.table-responsive .table tbody tr:not([class]):nth-of-type(even):not(:hover) td:last-child {
    background-color: #FAFBFD;
}

/* Hover: el mismo tinte de marca de la sección 3, pero compuesto sobre blanco.
   La celda fijada es opaca: con el rgba TalCual quedaría más oscura que el
   resto de la fila. */
.table-responsive .table tbody tr:not([class]):hover td:last-child {
    background-color: #F5F8FE;
}

/* Filas de grupo de DataTables: el tema las pinta #F2F4F4. */
.table-responsive .table tbody tr.group td:last-child {
    background-color: #F2F4F4;
}

/* Comodín para filas con fondo propio puesto inline (style="background..."):
   la celda fijada lo hereda en vez de quedar blanca. */
.table-responsive .table tbody tr[style*="background"] td:last-child {
    background-color: inherit;
}

/* --- 15.14 Impresión: nada de sombras, degradados ni desplazamientos ---
   El sistema imprime OTs y reportes desde el navegador; allí sólo queremos
   tinta limpia. */
@media print {

    .card,
    .card:hover,
    .btn:hover,
    .list-group-item-action:hover {
        transform: none !important;
        box-shadow: none !important;
    }

    .table thead th {
        background-image: none;
    }

    .footer {
        background-image: none;
    }

    /* La columna fijada (15.13) vuelve a ser una celda normal: al imprimir se
       ve la tabla completa, no el recorte de la pantalla. */
    .table-responsive .table thead th:last-child,
    .table-responsive .table tbody td:last-child {
        position: static;
        box-shadow: none;
    }
}

/* --- 15.12 Submenús del menú horizontal (Microbiología, Química, Terreno...) ---
   Cada entrada de esos desplegables se marca como "destacado" al pasar el
   cursor: fondo azul de marca y texto blanco, iconos incluidos.

   Por qué hacia dónde apunta el selector: Bootstrap deja los .dropdown-item en
   un gris casi blanco (#f8f9fa) que sobre el fondo blanco del menú no se
   distingue; la regla genérica `.dropdown-item:hover` de la sección 1 los deja
   en un tinte demasiado suave para una barra de navegación. Acá manda el azul.

   Especificidad: `.horizontal-menu #main-menu-navigation ...` (1 id + 4 clases)
   le gana a Bootstrap (.dropdown-item:hover), al tema (.dropdown-menu i) y a la
   propia sección 1 de este archivo, que sigue intacta para los desplegables de
   la cabecera (usuario, notificaciones): sólo cambia el menú principal.

   El color va en degradado (#5A8DEE → #4A78D6, el azul de marca y su variante
   oscura, la misma pareja que ya usan los botones) y no plano: baja el contraste
   lo justo para que el texto blanco se lea cómodo y mantiene la coherencia con
   el resto de la app. Nada de `content`, `padding` ni `position`: el tamaño y
   la posición de cada entrada no cambian. */
.horizontal-menu #main-menu-navigation .dropdown-menu .dropdown-item {
    transition: background-color .15s ease, color .15s ease;
}

.horizontal-menu #main-menu-navigation .dropdown-menu .dropdown-item:hover,
.horizontal-menu #main-menu-navigation .dropdown-menu .dropdown-item:focus {
    background-color: #5A8DEE;
    background-image: linear-gradient(180deg, #5A8DEE 0%, #4A78D6 100%);
    color: #FFF;
}

/* El tema pinta sus iconos en #475F7B y NO hereda el color del enlace:
   hay que blanquearlos a mano o quedan oscuros sobre el azul. */
.horizontal-menu #main-menu-navigation .dropdown-menu .dropdown-item:hover i,
.horizontal-menu #main-menu-navigation .dropdown-menu .dropdown-item:focus i {
    color: #FFF;
}

/* ============================================================
   16. DataTables — indicador "Procesando..."
   El recuadro por defecto (texto plano en medio de la tabla) se reemplaza
   por una píldora con spinner sobre la tabla atenuada. base.blade.php pone
   .ql-dt-busy y data-ql-processing (el texto traducido) en el wrapper durante
   el evento processing.dt. La píldora es un pseudo-elemento del wrapper y no
   el div nativo, porque según la vista ese div queda dentro de una columna de
   0 px de ancho y no se puede centrar. Es una capa absoluta: no desplaza nada
   (0 layout shift). Prefijo body: la vista carga datatables.min.css después
   de style.css.
   ============================================================ */
body div.dataTables_wrapper {
    position: relative;
}

body div.dataTables_wrapper div.dataTables_processing {
    display: none !important;
}

body div.dataTables_wrapper table.dataTable {
    transition: opacity .18s ease;
}

body div.dataTables_wrapper.ql-dt-busy table.dataTable {
    opacity: .45;
}

body div.dataTables_wrapper.ql-dt-busy::after {
    content: attr(data-ql-processing);
    position: absolute;
    top: 96px;
    left: var(--ql-dt-cx, 50%);
    transform: translateX(-50%);
    z-index: 5;
    padding: .5rem 1rem .5rem 2.4rem;
    border-radius: 999px;
    /* Spinner: SVG animado (SMIL) como fondo => sin JS ni elementos extra */
    background: var(--qt-surface, #FFF) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='6.5' fill='none' stroke='%235A8DEE' stroke-opacity='.25' stroke-width='2'/%3E%3Cpath d='M8 1.5a6.5 6.5 0 0 1 6.5 6.5' fill='none' stroke='%235A8DEE' stroke-width='2' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 8 8' to='360 8 8' dur='.7s' repeatCount='indefinite'/%3E%3C/path%3E%3C/svg%3E") no-repeat .95rem 50% / 1rem 1rem;
    color: var(--qt-primary, #5A8DEE);
    font-size: .85rem;
    font-weight: 500;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: 0 6px 20px rgba(38, 60, 85, .16);
}

/* Skeleton de la primera carga AJAX (base.blade.php, qlSkeletonStart):
   filas con barras grises y un brillo que las recorre, en vez del cuerpo
   vacío que luego crece de golpe. Sin animación si el sistema pide
   movimiento reducido. */
body div.dataTables_wrapper.ql-dt-skeleton tr.ql-skel-row > td {
    vertical-align: middle;
}

.ql-skel-bar {
    display: block;
    height: .7rem;
    max-width: 14rem;
    border-radius: 4px;
    background: linear-gradient(90deg,
        rgba(120, 138, 165, .14) 25%,
        rgba(120, 138, 165, .26) 50%,
        rgba(120, 138, 165, .14) 75%);
    background-size: 200% 100%;
    animation: ql-skel-shine 1.3s ease-in-out infinite;
}

@keyframes ql-skel-shine {
    from { background-position: 100% 0; }
    to { background-position: -100% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .ql-skel-bar {
        animation: none;
    }
}

/* ============================================================
   17. Submenús del menú principal
   Al pasar el mouse por una opción de un desplegable cuya página es de
   tarjetas (Entorno, Muestras…, Informes) se abre a su derecha la lista
   de esas tarjetas. base.blade.php
   ("Submenús del menú principal") arma la lista y le copia fondo, borde y
   sombra del menú desplegable, según el tema. Sólo existe con el menú
   horizontal (escritorio).
   ============================================================ */
.horizontal-menu .ql-flyout {
    position: relative;
}

.horizontal-menu .ql-flyout > a.dropdown-item {
    padding-right: 2.4rem;
}

.horizontal-menu .ql-flyout > a.dropdown-item::after {
    content: "\ea4a";
    font-family: 'boxicons';
    font-size: 1rem;
    position: absolute;
    right: 14px;
    top: 50%;
    transform: translateY(-50%);
    opacity: .6;
}

.ql-flyout-menu {
    display: none;
    position: absolute;
    top: -7px;
    /* -2px: se monta sobre el borde del menú padre, para que al cruzar
       hacia la derecha el cursor no pase por un hueco y se cierre. */
    left: calc(100% - 2px);
    z-index: 11;
    min-width: 240px;
    max-height: 75vh;
    overflow-y: auto;
    margin: 0;
    padding: 6px 0;
    list-style: none;
}

.horizontal-menu .ql-flyout:hover > .ql-flyout-menu,
.horizontal-menu .ql-flyout:focus-within > .ql-flyout-menu {
    display: block;
}

.ql-flyout.ql-flyout-left > .ql-flyout-menu {
    left: auto;
    right: calc(100% - 2px);
}

/* ============================================================
   18. Móvil y tablet (< 1200 px)
   Bajo 1200 px app-menu.js quita .horizontal-menu del <body> y pasa el
   menú a vertical/overlay. Con eso dejan de aplicar las reglas del tema
   que pintan la cabecera (.horizontal-menu .header-navbar), que quedaba
   transparente: al scrollear, el contenido pasaba por detrás del ícono
   de menú y del avatar. Esta sección:
   · cabecera opaca de 3.5rem (lo mismo que el margen superior que el
     tema deja al contenido), con logo al centro;
   · menos relleno en contenedor y tarjetas para que tablas y
     formularios tengan ancho útil;
   · migas en una sola línea desplazable bajo el título;
   · barra de botones sobre las tablas a todo el ancho;
   · DataTables: controles apilados, paginación táctil y la columna
     ACCIÓN sin fijar cuando taparía la tabla (clase .ql-dt-unstick,
     la pone base.blade.php midiendo la celda);
   · modales a pantalla casi completa, campos a 16 px (iOS no hace zoom
     al enfocarlos) y objetivos táctiles de al menos 36-44 px.
   En escritorio (>= 1200 px) nada de esto aplica.
   ============================================================ */
.ql-mobile-brand {
    display: none;
}

@media (max-width: 1199.98px) {
    /* --- Primer pintado, antes de app-menu.js ---
       El <body> llega del servidor con .horizontal-menu y el JS del tema lo
       pasa a vertical/overlay recién al cargar. Mientras tanto el menú
       horizontal se pintaba como un bloque de ~420 px bajo la cabecera (que
       tampoco era fija) y empujaba el contenido; al convertirse, todo
       saltaba hacia arriba en cada navegación. Aquí ese estado ya se ve
       igual que el final: menú oculto, cabecera fija y el contenido a 3.5rem. */
    body.horizontal-menu .header-navbar.navbar-horizontal[data-menu="menu-wrapper"] {
        display: none;
    }

    body.horizontal-menu nav.header-navbar.navbar-with-menu {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 1000;
    }

    html body.horizontal-menu .app-content.content > .content-wrapper,
    html body.horizontal-menu.navbar-static .app-content.content > .content-wrapper {
        margin-top: 3.5rem;
    }

    /* --- Cabecera --- */
    nav.header-navbar.navbar-with-menu {
        background-color: var(--qt-header-to, #F2F4F4);
        background-image: linear-gradient(180deg, var(--qt-header-from, #FCFDFE) 0%, var(--qt-header-to, #F0F3F8) 100%);
        box-shadow: 0 1px 0 rgba(36, 41, 61, .08);
        transition: box-shadow .2s ease;
    }

    body.page-scrolled nav.header-navbar.navbar-with-menu {
        box-shadow: 0 4px 16px rgba(36, 41, 61, .12);
    }

    nav.header-navbar.navbar-with-menu {
        min-height: 3.5rem;
        height: 3.5rem;
        padding: 0;
    }

    nav.header-navbar.navbar-with-menu .navbar-container {
        height: 3.5rem;
        padding: 0 .5rem 0 .25rem;
    }

    nav.header-navbar.navbar-with-menu .navbar-collapse {
        height: 100%;
        align-items: center;
    }

    nav.header-navbar.navbar-with-menu .navbar-container .nav-menu-main {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        padding: 0 !important;
    }

    nav.header-navbar.navbar-with-menu .dropdown-user-link {
        display: inline-flex !important;
        align-items: center;
        min-height: 44px;
        padding: 0 .25rem !important;
    }

    nav.header-navbar.navbar-with-menu .dropdown-user-link img.round {
        width: 36px;
        height: 36px;
    }

    .ql-mobile-brand {
        display: flex;
        align-items: center;
        position: absolute;
        top: 50%;
        left: 50%;
        height: 44px;
        transform: translate(-50%, -50%);
    }

    .ql-mobile-brand img {
        height: 26px;
        width: auto;
    }

    /* Toasts: nunca más anchos que la pantalla */
    .swal2-container .swal2-popup.swal2-toast {
        max-width: calc(100vw - 1.5rem);
    }
}

@media (max-width: 767.98px) {
    /* --- Contenedor y tarjetas: ancho útil --- */
    html body .content .content-wrapper,
    html body.navbar-static .app-content .content-wrapper,
    html body.navbar-sticky .app-content .content-wrapper {
        padding: .85rem .6rem 0;
    }

    html body .card .card-body {
        padding: 1rem .85rem;
    }

    html body .card .card-header {
        padding: 1rem .85rem 0;
    }

    /* --- Título de página y migas: título arriba, migas en una línea
       desplazable debajo (antes caían en una columna angosta a la
       derecha, una opción por renglón) --- */
    html body .content .content-wrapper .content-header-title {
        float: none !important;
        border-right: 0;
        padding-right: 0 !important;
        margin-bottom: .35rem !important;
        font-size: 1.2rem;
    }

    html body .content .content-wrapper .content-header .breadcrumb-wrapper {
        display: block !important;
        padding: 0;
        margin: 0;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 1.5rem), transparent);
        mask-image: linear-gradient(90deg, #000 calc(100% - 1.5rem), transparent);
    }

    html body .content .content-wrapper .content-header .breadcrumb-wrapper::-webkit-scrollbar {
        display: none;
    }

    html body .content .content-wrapper .content-header .breadcrumb-wrapper .breadcrumb {
        flex-wrap: nowrap;
        white-space: nowrap;
        padding: .2rem 1.5rem .3rem 0 !important;
        border-left: 0;
    }

    html body .content .content-wrapper .content-header .breadcrumb-wrapper .breadcrumb .breadcrumb-item {
        flex: 0 0 auto;
    }

    /* --- Barra de botones sobre las tablas: uno por fila, a todo el ancho
       (antes quedaban escalonados por el ml-1 del segundo botón) --- */
    .card-body > .btn:not(.btn-icon):not(.float-right):not(.btn-sm),
    .card-body > a.btn:not(.btn-icon):not(.float-right):not(.btn-sm) {
        display: flex;
        width: 100%;
        align-items: center;
        justify-content: center;
        margin: 0 0 .5rem !important;
        white-space: normal;
    }

    /* Un título con botón flotante (p. ej. "Química [Checklist OT]") ya no
       angosta la grilla que viene después: la fila baja bajo el flotante. */
    .card-body .row,
    .modal-body .row {
        clear: both;
    }

    /* --- DataTables: Mostrar y Buscar apilados, a la izquierda --- */
    .dataTables_wrapper .dataTables_length,
    .dataTables_wrapper .dataTables_filter {
        text-align: left !important;
        margin-bottom: .5rem;
    }

    body div.dataTables_wrapper div.dataTables_filter label {
        display: flex;
        align-items: center;
        gap: .5rem;
        width: 100%;
        margin: 0;
    }
}

/* Teléfono y tablet (< 992 px): tablas, campos y objetivos táctiles */
@media (max-width: 991.98px) {
    /* --- DataTables --- */
    .dataTables_wrapper .dataTables_info {
        text-align: center;
        white-space: normal !important;
        padding-top: .5rem !important;
    }

    body div.dataTables_wrapper div.dataTables_paginate ul.pagination {
        justify-content: center !important;
        flex-wrap: wrap;
        row-gap: .35rem;
        margin-top: .5rem !important;
    }

    .pagination .page-link {
        min-width: 36px;
        min-height: 36px;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .table-responsive {
        -webkit-overflow-scrolling: touch;
    }

    .column-filters th .form-control {
        min-width: 6.5rem;
    }

    .column-filters th .col-filter-date {
        min-width: 36px;
        min-height: 36px;
    }

    /* Acciones: fichas táctiles de 36 px */
    .invoice-action-edit[data-ql-tone] {
        width: 2.4rem;
        height: 2.4rem;
        font-size: 1.15rem;
    }

    /* --- Formularios: 16 px para que iOS no haga zoom al enfocar --- */
    input.form-control,
    select.form-control,
    textarea.form-control,
    .custom-select,
    .select2-container .select2-selection,
    .select2-container .select2-search__field {
        font-size: 16px !important;
    }

    .select2-container {
        max-width: 100%;
    }

    .select2-container--open .select2-dropdown {
        max-width: calc(100vw - 1rem);
    }

    .select2-results__option {
        padding-top: .55rem;
        padding-bottom: .55rem;
    }

}

@media (max-width: 767.98px) {
    /* --- Modales: casi pantalla completa y con relleno corto --- */
    .modal-dialog,
    .modal-dialog.modal-lg,
    .modal-dialog.modal-xl,
    .modal-dialog.modal-full {
        max-width: calc(100% - 1rem);
        margin: .5rem auto;
    }

    /* El tema deja 15 px a cada lado del .modal: en el teléfono es ancho perdido */
    .modal {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }

    .modal-dialog-centered {
        min-height: calc(100% - 1rem);
    }

    .modal-header,
    .modal-footer {
        padding: .85rem 1rem;
    }

    .modal-body {
        padding: .85rem;
    }

    .modal-body .card .card-body {
        padding: .75rem .5rem;
    }

    .modal-body .card {
        box-shadow: none;
        margin-bottom: .75rem;
    }

    .modal-header .close {
        min-width: 44px;
        min-height: 44px;
    }

    .modal-footer > .btn {
        flex: 1 1 auto;
        margin: 0 !important;
    }

    /* --- Tarjetas de mae/home/* (Entorno, Muestras...): dos por fila y
       compactas; antes cada una ocupaba la pantalla a lo ancho --- */
    #widgets-Statistics > .row > [class*="col-"] {
        flex: 0 0 50%;
        max-width: 50%;
        padding-left: .4rem;
        padding-right: .4rem;
    }

    #widgets-Statistics > .row {
        margin-left: -.4rem;
        margin-right: -.4rem;
    }

    #widgets-Statistics .card {
        margin-bottom: .8rem;
    }

    html body #widgets-Statistics .card .card-body {
        padding: .85rem .5rem;
    }

    #widgets-Statistics .badge-circle {
        margin-top: .25rem !important;
        margin-bottom: .5rem !important;
    }

    #widgets-Statistics .card p {
        white-space: normal;
        line-height: 1.25;
    }

    /* Pie: sin datos de versión, el botón "subir" no tapa la paginación */
    .footer {
        padding: .8rem 1rem;
    }

    .footer .btn.scroll-top {
        right: 1rem;
        bottom: 1rem;
    }
}

/* Columna ACCIÓN fijada (15.13): cuando la celda ocupa más del 40 % del
   ancho visible de la tabla, fijarla tapa el resto de las columnas (en un
   teléfono, 5 acciones ocupaban 178 de 256 px). base.blade.php mide y
   pone .ql-dt-unstick en esos casos; la columna vuelve a desplazarse con
   la tabla. En escritorio la proporción no llega y sigue fijada. */
.table-responsive.ql-dt-unstick .table thead th:last-child,
.table-responsive.ql-dt-unstick .table tbody td:last-child {
    position: static;
    box-shadow: none;
}

/* --- 18.1 Menú lateral (drawer) bajo 1200 px ---
   El tema lo dejaba azul marino (semi-dark) con textos gris oscuro (contraste
   ~3:1), la opción abierta como una tarjeta blanca encima, flechas hacia
   arriba en las cerradas y el logo oscuro sobre fondo oscuro. Ahora: panel
   claro del color de superficie del tema (en los temas oscuros, su
   superficie oscura), filas de 48 px, la opción abierta con tinte y filete
   del color primario, subopciones con sangría y la cortina oscura tapando
   también la cabecera. Abre deslizando desde la izquierda (transform). */
@media (max-width: 1199.98px) {
    html body.vertical-overlay-menu .main-menu {
        left: 0;
        width: min(86vw, 320px);
        opacity: 1;
        transform: translate3d(-105%, 0, 0);
        transition: transform .28s cubic-bezier(.2, .8, .2, 1), box-shadow .28s ease;
        background: var(--qt-surface, #FFFFFF) !important;
        border-right: 1px solid var(--qt-border-soft, #E9ECF0);
        box-shadow: none;
        z-index: 1032;
    }

    html body.vertical-overlay-menu.menu-open .main-menu {
        transform: translate3d(0, 0, 0);
        box-shadow: 0 0 48px rgba(16, 22, 40, .35);
    }

    /* Cortina por sobre la cabecera fija (z-index 1000) */
    html body.vertical-overlay-menu .sidenav-overlay {
        z-index: 1031;
        background-color: rgba(16, 22, 40, .45);
        -webkit-backdrop-filter: blur(2px);
        backdrop-filter: blur(2px);
    }

    /* Encabezado: logo a color y botón cerrar de 44 px */
    html body.vertical-overlay-menu .main-menu .navbar-header {
        width: 100% !important;
        height: 4rem;
        padding: 0 .5rem 0 1.1rem;
        background: transparent !important;
        border-bottom: 1px solid var(--qt-border-soft, #E9ECF0);
    }

    html body.vertical-overlay-menu .main-menu .navbar-header .navbar-nav {
        height: 100%;
        align-items: center;
        flex-wrap: nowrap;
    }

    html body.vertical-overlay-menu .main-menu .navbar-header .navbar-brand {
        margin: 0;
        padding: 0;
    }

    html body.vertical-overlay-menu .main-menu .navbar-header .brand-logo img.logo {
        height: 30px;
        width: auto;
        max-width: none;
    }

    html body.vertical-overlay-menu .main-menu .navbar-header .nav-toggle .nav-link {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        margin: 0;
        padding: 0 !important;
        border-radius: 50%;
    }

    html body.vertical-overlay-menu .main-menu .navbar-header .nav-toggle .nav-link:active {
        background-color: rgba(var(--qt-primary-rgb, 90, 141, 238), .12);
    }

    html body.vertical-overlay-menu .main-menu .navbar-header .toggle-icon {
        font-size: 1.6rem !important;
        color: var(--qt-heading, #475F7B) !important;
    }

    html body.vertical-overlay-menu .main-menu .shadow-bottom {
        display: none !important;
    }

    html body.vertical-overlay-menu .main-menu .main-menu-content {
        height: calc(100% - 4rem) !important;
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        padding: .5rem 0 1.5rem;
    }

    html body.vertical-overlay-menu .main-menu .navigation {
        background: transparent !important;
        padding: 0 .6rem;
    }

    /* Opciones de primer nivel */
    html body.vertical-overlay-menu .main-menu .navigation > li {
        margin: 0 0 2px;
        border-radius: .6rem;
        background: transparent !important;
        border: 0 !important;
        box-shadow: none !important;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li > a {
        position: relative;
        border: 0 !important;
        min-height: 48px;
        display: flex;
        align-items: center;
        padding: .4rem 2.6rem .4rem .75rem !important;
        margin: 0 !important;
        border-radius: .6rem;
        color: var(--qt-heading-strong, #394C62) !important;
        font-size: 1rem;
        font-weight: 500;
        line-height: 1.3;
        background: transparent !important;
        transition: background-color .15s ease;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li > a span {
        color: inherit !important;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li > a > i {
        flex: 0 0 auto;
        float: none;
        margin-right: .85rem;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li > a:active {
        background-color: rgba(var(--qt-primary-rgb, 90, 141, 238), .10) !important;
    }

    /* Flecha: hacia abajo cerrada, hacia arriba abierta */
    html body.vertical-overlay-menu .main-menu .navigation li.has-sub > a:not(.mm-next)::after {
        content: "\ea4a";
        right: .85rem;
        top: 50%;
        font-size: 1.25rem;
        color: var(--qt-muted, #8494A7) !important;
        transform: translateY(-50%) rotate(90deg);
        transition: transform .2s ease;
    }

    html body.vertical-overlay-menu .main-menu .navigation li.has-sub.open > a:not(.mm-next)::after {
        transform: translateY(-50%) rotate(-90deg);
    }

    /* Opción abierta / sección actual: tinte y filete del color primario */
    html body.vertical-overlay-menu .main-menu .navigation > li.open,
    html body.vertical-overlay-menu .main-menu .navigation > li.sidebar-group-active {
        background-color: rgba(var(--qt-primary-rgb, 90, 141, 238), .07) !important;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li.open > a,
    html body.vertical-overlay-menu .main-menu .navigation > li.sidebar-group-active > a,
    html body.vertical-overlay-menu .main-menu .navigation > li.active > a {
        color: var(--qt-primary-ink, #3461C1) !important;
        font-weight: 600;
    }

    /* Subopciones */
    html body.vertical-overlay-menu .main-menu .navigation > li ul {
        padding: 0 0 .4rem !important;
        margin: 0 0 0 1.55rem !important;
        border: 0 !important;
        border-left: 2px solid rgba(var(--qt-primary-rgb, 90, 141, 238), .25) !important;
        border-radius: 0 !important;
        box-shadow: none !important;
        background: transparent !important;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li ul li {
        background: transparent !important;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li ul li > a,
    html body.vertical-overlay-menu .main-menu .navigation > li ul li:hover > a {
        border: 0 !important;
        min-height: 44px;
        display: flex;
        align-items: center;
        padding: .45rem .75rem .45rem 1rem !important;
        margin: 0 .25rem 0 0 !important;
        border-radius: 0 .5rem .5rem 0;
        color: var(--qt-text, #475F7B) !important;
        font-size: .95rem;
        white-space: normal;
        background: transparent !important;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li ul li > a > i {
        display: none;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li ul li > a:active {
        background-color: rgba(var(--qt-primary-rgb, 90, 141, 238), .12) !important;
    }

    html body.vertical-overlay-menu .main-menu .navigation > li ul li.active > a {
        color: var(--qt-primary-ink, #3461C1) !important;
        font-weight: 600;
        background-color: rgba(var(--qt-primary-rgb, 90, 141, 238), .12) !important;
        box-shadow: none !important;
    }

    /* La lista de tarjetas de escritorio (17) no existe en el drawer */
    html body.vertical-overlay-menu .ql-flyout-menu {
        display: none !important;
    }
}

/* --- 18.2 Tablas más anchas que la pantalla: deslizar con el dedo ---
   El desplazamiento táctil es el nativo de .table-responsive. Además:
   · overscroll contenido: al llegar al borde, el gesto no dispara el
     "atrás" del navegador ni arrastra la página;
   · base.blade.php muestra sobre la tabla una pista "Desliza para ver más
     columnas" mientras queda tabla a la derecha (.ql-swipe-hint) y permite
     arrastrarla con el mouse o el lápiz (útil en tablets y en el emulador). */
@media (max-width: 991.98px) {
    .table-responsive {
        overscroll-behavior-x: contain;
        touch-action: pan-x pan-y;
    }

    .table-responsive.ql-dragging {
        cursor: grabbing;
        user-select: none;
    }
}

.ql-swipe-hint {
    display: none;
}

@media (max-width: 991.98px) {
    .ql-swipe-hint {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        gap: .35rem;
        margin: 0 0 .35rem;
        color: var(--qt-muted, #828D99);
        font-size: .8rem;
        transition: opacity .25s ease;
    }

    .ql-swipe-hint i {
        font-size: 1.1rem;
        animation: ql-swipe-nudge 1.6s ease-in-out infinite;
    }

    .ql-swipe-hint.ql-swipe-done {
        opacity: 0;
    }
}

@keyframes ql-swipe-nudge {
    0%, 100% { transform: translateX(0); }
    50% { transform: translateX(5px); }
}

@media (prefers-reduced-motion: reduce) {
    .ql-swipe-hint i {
        animation: none;
    }
}

/* --- 18.3 select2 en el teléfono: hoja fija arriba ---
   El desplegable de select2 se cuelga del <body> en posición absoluta bajo
   su campo. Dentro de un modal (el body no se desplaza) un campo cerca del
   borde inferior abría la lista fuera de la pantalla, sin forma de llegar a
   las opciones. En el teléfono la lista va fija en la parte de arriba (el
   teclado sale abajo), a todo el ancho y con alto máximo. Los select2 con
   dropdownParent dentro de un modal no se tocan: se desplazan con él. */
@media (max-width: 767.98px) {
    body > .select2-container.select2-container--open {
        position: fixed !important;
        top: .5rem !important;
        left: .5rem !important;
        right: .5rem;
        width: auto !important;
        z-index: 1070;
    }

    body > .select2-container.select2-container--open .select2-dropdown {
        position: static;
        width: 100% !important;
        border: 1px solid var(--qt-border, #DFE3E7);
        border-radius: .75rem;
        overflow: hidden;
        box-shadow: 0 18px 50px rgba(16, 22, 40, .35);
    }

    body > .select2-container.select2-container--open .select2-results > .select2-results__options {
        max-height: 45vh;
        overscroll-behavior: contain;
    }

    body > .select2-container.select2-container--open .select2-search--dropdown {
        padding: .6rem;
    }
}

/* --- 18.4 Acciones de cada fila en el teléfono: botón "⋮" + hoja ---
   Bajo 768 px una celda con 2 o más acciones (.invoice-action-edit) muestra
   sólo el botón .ql-row-actions-btn; base.blade.php arma la hoja
   .ql-action-sheet con el ícono y el nombre de cada acción y, al elegir una,
   dispara el clic de la acción original. Así la columna ACCIÓN mide ~44 px
   (antes 178-219 px) y puede seguir fijada al borde derecho. */
.ql-row-actions-btn,
.ql-action-sheet {
    display: none;
}

@media (max-width: 767.98px) {
    td.ql-row-actions .invoice-action-edit {
        display: none !important;
    }

    td.ql-row-actions .invoice-action {
        min-width: 0;
    }

    td.ql-row-actions {
        width: 1%;
        white-space: nowrap;
        text-align: center;
    }

    .ql-row-actions-btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 40px;
        height: 40px;
        padding: 0;
        border: 1px solid var(--qt-border, #DFE3E7);
        border-radius: .6rem;
        background: var(--qt-surface, #FFFFFF);
        color: var(--qt-heading, #475F7B);
        font-size: 1.35rem;
        line-height: 1;
        box-shadow: 0 1px 2px rgba(36, 41, 61, .08);
    }

    .ql-row-actions-btn:active {
        background-color: rgba(var(--qt-primary-rgb, 90, 141, 238), .12);
    }

    .ql-action-sheet {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 1080;
        visibility: hidden;
        pointer-events: none;
    }

    .ql-action-sheet.show {
        visibility: visible;
        pointer-events: auto;
    }

    .ql-action-sheet-backdrop {
        position: absolute;
        inset: 0;
        background-color: rgba(16, 22, 40, .45);
        opacity: 0;
        transition: opacity .2s ease;
    }

    .ql-action-sheet.show .ql-action-sheet-backdrop {
        opacity: 1;
    }

    .ql-action-sheet-panel {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        max-height: 80vh;
        overflow-y: auto;
        overscroll-behavior: contain;
        padding: .35rem .75rem calc(.75rem + env(safe-area-inset-bottom, 0px));
        border-radius: 1.1rem 1.1rem 0 0;
        background: var(--qt-surface, #FFFFFF);
        box-shadow: 0 -12px 40px rgba(16, 22, 40, .25);
        transform: translateY(100%);
        transition: transform .25s cubic-bezier(.2, .8, .2, 1);
        outline: 0;
    }

    .ql-action-sheet.show .ql-action-sheet-panel {
        transform: translateY(0);
    }

    /* Asa del panel */
    .ql-action-sheet-panel::before {
        content: "";
        display: block;
        width: 40px;
        height: 4px;
        margin: .25rem auto .35rem;
        border-radius: 2px;
        background-color: var(--qt-border, #DFE3E7);
    }

    .ql-action-sheet-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: .5rem;
        padding: 0 0 .4rem .35rem;
        border-bottom: 1px solid var(--qt-border-soft, #E9ECF0);
    }

    .ql-action-sheet-title {
        color: var(--qt-heading-strong, #394C62);
        font-weight: 600;
        font-size: .95rem;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .ql-action-sheet-close {
        flex: 0 0 44px;
        width: 44px;
        height: 44px;
        border: 0;
        border-radius: 50%;
        background: transparent;
        color: var(--qt-muted, #828D99);
        font-size: 1.5rem;
    }

    .ql-action-sheet-list {
        list-style: none;
        margin: .35rem 0 0;
        padding: 0;
    }

    .ql-action-sheet-item {
        --ql-tone: 57, 76, 98;
        display: flex;
        align-items: center;
        gap: .85rem;
        width: 100%;
        min-height: 52px;
        padding: .4rem .35rem;
        border: 0;
        border-radius: .6rem;
        background: transparent;
        color: var(--qt-heading-strong, #394C62);
        font-size: 1rem;
        text-align: left;
    }

    .ql-action-sheet-item:active {
        background-color: rgba(var(--ql-tone), .10);
    }

    .ql-action-sheet-item:disabled {
        opacity: .45;
    }

    .ql-action-sheet-icon {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 40px;
        width: 40px;
        height: 40px;
        border-radius: .6rem;
        background-color: rgba(var(--ql-tone), .12);
        color: rgb(var(--ql-tone));
        font-size: 1.3rem;
    }

    .ql-action-sheet-icon i {
        color: inherit !important;
    }

    .ql-action-sheet-item[data-ql-tone="danger"]  { --ql-tone: 201, 48, 44; color: rgb(201, 48, 44); }
    .ql-action-sheet-item[data-ql-tone="success"] { --ql-tone: 30, 123, 75; }
    .ql-action-sheet-item[data-ql-tone="warning"] { --ql-tone: 166, 90, 0; }
    .ql-action-sheet-item[data-ql-tone="info"]    { --ql-tone: 11, 112, 135; }
    .ql-action-sheet-item[data-ql-tone="primary"] { --ql-tone: 52, 97, 193; }

    /* Temas oscuros: las variantes claras de la sección 14 */
    html[data-theme-mode="dark"] .ql-action-sheet-item[data-ql-tone]           { --ql-tone: 196, 207, 222; }
    html[data-theme-mode="dark"] .ql-action-sheet-item[data-ql-tone="danger"]  { --ql-tone: 255, 128, 128; color: rgb(255, 128, 128); }
    html[data-theme-mode="dark"] .ql-action-sheet-item[data-ql-tone="success"] { --ql-tone: 102, 214, 154; }
    html[data-theme-mode="dark"] .ql-action-sheet-item[data-ql-tone="warning"] { --ql-tone: 255, 186, 92; }
    html[data-theme-mode="dark"] .ql-action-sheet-item[data-ql-tone="info"]    { --ql-tone: 92, 208, 228; }
    html[data-theme-mode="dark"] .ql-action-sheet-item[data-ql-tone="primary"] { --ql-tone: 140, 176, 255; }

    html.ql-sheet-open,
    html.ql-sheet-open body {
        overflow: hidden;
    }
}

@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {
    .ql-action-sheet-panel,
    .ql-action-sheet-backdrop {
        transition: none;
    }
}

/* ============================================================
   19. Cabecera — buscador unificado, transparencia y progreso
   Se mantiene la distribución de siempre: accesos a la izquierda, logo
   al centro y, a la derecha, el buscador (secciones + OT) justo antes
   de pantalla completa y usuario (.ql-nav-search-slot).
   · Móvil y tablet (< 1200 px): la misma caja queda oculta y la lupa
     de la cabecera la abre como panel bajo ella (body.ql-search-open).
   · Con la página scrolleada, la barra que queda arriba (escritorio:
     la de secciones; móvil: la cabecera) se vuelve semitransparente con
     desenfoque. El vidrio va en un ::before y no en la barra misma: un
     backdrop-filter en la barra la haría bloque contenedor de sus hijos
     position: fixed (panel del buscador, submenús) y los descolocaría.
   · .ql-scroll-progress: barra fina con el avance de la página, pegada
     al borde inferior de la cabecera visible (la ubica el script que
     sigue al <nav> en base.blade.php).
   Colores con las variables de tema (--qt-*) y, sin tema, los del
   diseño por defecto. No toca PDFs ni correos.
   ============================================================ */

/* --- 19.1 Buscador: a la derecha en escritorio, panel de la lupa en móvil --- */
@media (min-width: 1200px) {
    .ql-nav-search-slot {
        display: flex;
        align-items: center;
    }
}

@media (max-width: 1199.98px) {
    .ql-nav-search-slot {
        display: none;
    }

    body.ql-search-open .ql-nav-search-slot {
        display: block !important;
        position: fixed;
        top: 3.5rem;
        left: 0;
        right: 0;
        padding: .6rem .75rem .75rem;
        background-color: var(--qt-header-to, #F0F3F8);
        border-top: 1px solid var(--qt-border-soft, rgba(36, 41, 61, .08));
        box-shadow: 0 10px 24px rgba(36, 41, 61, .16);
        animation: ql-search-in .16s ease-out;
    }

    nav.header-navbar .ql-search-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        padding: 0 !important;
        border-radius: .5rem;
    }

    body.ql-search-open nav.header-navbar .ql-search-toggle,
    body.ql-search-open nav.header-navbar .ql-search-toggle i {
        color: var(--qt-primary-ink, #5A8DEE) !important;
        background-color: rgba(var(--qt-primary-rgb, 90, 141, 238), .12);
    }
}

@keyframes ql-search-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

/* --- 19.2 Barra semitransparente al scrollear --- */
@media (min-width: 1200px) {
    html body.horizontal-menu.navbar-scrolled .header-navbar.navbar-horizontal {
        background-color: transparent !important;
        background-image: none !important;
    }

    html body.horizontal-menu.navbar-scrolled .header-navbar.navbar-horizontal::before {
        content: '';
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: -1;
        pointer-events: none;
        background: rgba(244, 246, 250, .84);
        background: color-mix(in srgb, var(--qt-surface, #F4F6FA) 76%, transparent);
        -webkit-backdrop-filter: saturate(170%) blur(14px);
        backdrop-filter: saturate(170%) blur(14px);
    }
}

@media (max-width: 1199.98px) {
    html body.page-scrolled nav.header-navbar.navbar-with-menu {
        background-color: transparent !important;
        background-image: none !important;
    }

    html body.page-scrolled nav.header-navbar.navbar-with-menu::before {
        content: '';
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: -1;
        pointer-events: none;
        background: rgba(240, 243, 248, .84);
        background: color-mix(in srgb, var(--qt-header-to, #F0F3F8) 76%, transparent);
        -webkit-backdrop-filter: saturate(170%) blur(14px);
        backdrop-filter: saturate(170%) blur(14px);
    }
}

/* Sin soporte de backdrop-filter el vidrio sería sólo transparencia y el
   contenido se leería a través: ahí la barra queda casi opaca. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    html body.horizontal-menu.navbar-scrolled .header-navbar.navbar-horizontal::before,
    html body.page-scrolled nav.header-navbar.navbar-with-menu::before {
        background: var(--qt-surface, #F4F6FA);
        opacity: .97;
    }
}

/* --- 19.3 Progreso de scroll --- */
.ql-scroll-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 98;
    pointer-events: none;
    opacity: 0;
    transition: opacity .2s ease;
}

.ql-scroll-progress.is-visible {
    opacity: 1;
}

.ql-scroll-progress span {
    display: block;
    height: 100%;
    transform: scaleX(var(--ql-progress, 0));
    transform-origin: 0 50%;
    border-radius: 0 3px 3px 0;
    background-image: linear-gradient(90deg,
            rgba(var(--qt-primary-rgb, 90, 141, 238), .35) 0%,
            rgb(var(--qt-primary-rgb, 90, 141, 238)) 100%);
    box-shadow: 0 0 8px rgba(var(--qt-primary-rgb, 90, 141, 238), .45);
    will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
    .ql-scroll-progress,
    body.ql-search-open .ql-nav-search-slot {
        transition: none;
        animation: none;
    }
}
