/*Write your custom css in this file.*/
.dt-print-view{
     tfoot tr:first-child {
          display: none;
     }
}

@media print {
     .dt-print-view tfoot {
          display: table-row-group;
     }
}

table.dataTable tbody th, table.dataTable tbody td {
  padding: 4px 10px !important;
}
 
/* Historial de búsqueda */
.busqueda-autocomplete {
    position: absolute;
    z-index: 10000;
    background: #fff;
    width: 100%;
    border-radius: 0 0 12px 12px;
    box-shadow: 0 6px 32px 0 rgba(30, 41, 59, 0.14);
    max-height: 240px;
    overflow-y: auto;
    margin-top: 2px;
    left: 0;
    border: none;
    padding: 0;
    animation: fadeInAutocomplete 0.18s;
    font-family: 'Inter', 'Segoe UI', Arial, sans-serif;
}

@keyframes fadeInAutocomplete {
    from { opacity: 0; transform: translateY(-8px);}
    to { opacity: 1; transform: translateY(0);}
}

.busqueda-autocomplete li {
    padding: 12px 18px;
    cursor: pointer;
    font-size: 14px;
    color: #1e293b;
    background: transparent;
    transition: background 0.15s, color 0.15s, padding-left 0.18s;
    border-bottom: 1px solid #f1f5f9;
    position: relative;
}

.busqueda-autocomplete li:last-child {
    border-bottom: none;
}

.busqueda-autocomplete li:hover,
.busqueda-autocomplete li.active {
    background: linear-gradient(90deg, #f1f5f9 90%, #e0e7ef 100%);
    color: #174ea6;
    padding-left: 30px;
}

.busqueda-autocomplete li::before {
    display: none;
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 12px;
    color: #38bdf8;
    opacity: 0.7;
}
.busqueda-autocomplete li.active::before,
.busqueda-autocomplete li:hover::before {
    display: inline;
}

@media (max-width: 600px) {
    .busqueda-autocomplete {
        font-size: 15px;
    }
    .busqueda-autocomplete li {
        padding: 12px 10px;
    }
}
/* --- */

/* =============================
   Selectores globales para Select2
   (aplican siempre, independientemente del tema)
   NOTA: Los colores de fondo se pueden parametrizar desde la configuración general
   ============================= */
/* Select2 v3 - caja y texto */
.select2-container .select2-choice {
    background-color: #EDEFF2;
    border-color: #C7CED6;
    color: #0F172A !important;
}
.select2-container .select2-choice > .select2-chosen {
    color: #323e5c !important; /*Color de la opcion seleccionada en el despegable*/
}
/* Select2 v3 - hover/focus */
.select2-container-active .select2-choice,
.select2-dropdown-open.select2-drop-above .select2-choice {
    border-color: #8FA2B8;
    box-shadow: 0 0 0 3px rgba(143, 162, 184, 0.25) !important;
    background-color: #E6E9EE;
}
/* Select2 v3 - desplegable y opciones */
.select2-drop {
    background-color: #F4F6F8;
    border-color: #C7CED6;
}
.select2-results .select2-result-label {
    color: #0F172A !important;
}
.select2-results .select2-highlighted {
    background-color: #DDE3EA;
    color: #0F172A !important;
}
/* Múltiple (chips) */
.select2-container-multi .select2-choices {
    background-color: #EDEFF2;
    border-color: #C7CED6;
}
.select2-container-multi .select2-choices .select2-search-choice {
    background-color: #D9DEE6;
    border-color: #C7CED6;
    color: #0F172A !important;
}

/* Select2 v4 - caja */
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    background-color: #EDEFF2;
    border-color: #C7CED6;
    color: #0F172A !important;
}
.select2-container--default .select2-selection--single .select2-selection__rendered,
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
    color: #0F172A !important;
}
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--multiple {
    border-color: #8FA2B8;
    box-shadow: 0 0 0 3px rgba(143, 162, 184, 0.25) !important;
    background-color: #E6E9EE;
}
.select2-dropdown {
    background-color: #F4F6F8;
    border-color: #C7CED6;
}
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable,
.select2-container--default .select2-results__option[aria-selected=true] {
    background-color: #DDE3EA;
    color: #0F172A !important;
}

/* =============================
   Selector de temas (paleta de colores bajo el usuario)
   ============================= */
.theme-changer .color-tag {
    border: 2px solid #000000;
    box-sizing: border-box;
}

/* Chosen */
.chosen-container-single .chosen-single,
.chosen-container .chosen-choices {
    background-color: #EDEFF2;
    border-color: #C7CED6;
    color: #0F172A !important;
}
.chosen-container-active .chosen-single,
.chosen-container-active .chosen-choices {
    border-color: #8FA2B8;
    box-shadow: 0 0 0 3px rgba(143, 162, 184, 0.25) !important;
    background-color: #E6E9EE;
}
.chosen-container .chosen-drop {
    background-color: #F4F6F8;
    border-color: #C7CED6;
}
.chosen-container .chosen-results li.highlighted {
    background-color: #DDE3EA;
    color: #0F172A !important;
}

/* =============================
   Inputs/Selects/Textareas globales
   (mismo gris que los despegables)
   NOTA: Los colores de fondo se pueden parametrizar desde la configuración general
   ============================= */
/* Base - excluir checkboxes y radios */
.form-control:not(input[type="checkbox"]):not(input[type="radio"]),
input[type="text"],
input[type="number"],
input[type="email"],
input[type="password"],
input[type="search"],
select,
textarea {
    background-color: #EDEFF2;
    border-color: #C7CED6;
    color: #0F172A;
}

/* Placeholder */
::placeholder {
    color: #6B7280 !important;
    opacity: 1;
}

/* Focus - excluir checkboxes y radios */
.form-control:focus:not(input[type="checkbox"]):not(input[type="radio"]),
input:focus:not(input[type="checkbox"]):not(input[type="radio"]),
textarea:focus,
select:focus {
    background-color: #FFFFFF;
    border-color: #8FA2B8;
    box-shadow: 0 0 0 3px rgba(143, 162, 184, 0.25) !important;
    color: #0F172A;
}

/* Deshabilitados */
.form-control[disabled],
input[disabled],
textarea[disabled],
select[disabled] {
    background-color: #EEF2F6;
    color: #6B7280 !important;
    opacity: 1 !important;
}

/* ============================================================
   Capa "flat" estilo Laravel / Vue — SOLO forma y tipografía.
   El color sigue siendo de los temas (assets/css/color/*.css).

   Los bordes son semitransparentes a propósito: sobre fondo claro
   se ven gris suave y sobre los temas oscuros se aclaran solos,
   en vez de dibujar una línea blanca alrededor de cada tarjeta.
   ============================================================ */
:root {
    --ui-font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --ui-radius: 4px;
    --ui-hairline: rgba(130, 140, 160, 0.25);
    --ui-page-bg: #f2f5f8;
    --ui-accent: #6690F4; /* lo sobrescribe el script segun el tema activo */
}

html, body {
    font-family: var(--ui-font);
    font-size: 14px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Fondo de página neutro en lugar del lavanda #EEF1F9.
   Sin !important: los temas oscuros y los skins completos siguen mandando.
   Estas cuatro superficies deben ir siempre iguales o se ve una costura
   al plegar el menú lateral. */
html, body,
#left-menu-toggle-mask,
.default-bg,
.project-overview-for-client {
    background-color: var(--ui-page-bg);
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--ui-font);
    font-weight: 600;
}

/* Superficies planas: fuera las sombras difusas, dentro la línea de 1px */
.card,
.widget-container .card,
.sidebar,
.sidebar-brand,
.navbar-custom,
.page-title {
    box-shadow: none !important;
    -webkit-box-shadow: none !important;
}

.card {
    border: 1px solid var(--ui-hairline);
    border-radius: var(--ui-radius);
}

/* Las vistas que se cargan por pestaña traen su propia .card, así que al
   anidarse dentro de la .card que dibuja las pestañas salían dos marcos.
   Se quita el borde de la de dentro; el fondo se deja, si no el listado
   se ve sobre el gris de la página.
   Rise envuelve a veces el parcial en un .tab-content extra (p. ej. ficha
   de empleado: general_info / job_info / account_settings). */
.tab-content > .tab-pane > .card,
.tab-content > .tab-pane > form > .card,
.tab-content > .tab-pane > .tab-content > .card,
.tab-content > .tab-pane > .tab-content > form > .card {
    border: 0;
    border-radius: 0;
    margin-top: 0;
    margin-bottom: 0;
    box-shadow: none;
}

/* Ficha de oportunidad: misma caja que estimates (page-wrapper + .card).
   El título interno está oculto; las pestañas hacen de cabecera. */
.opportunity-details-view .page-title {
    display: none;
}

.opportunity-details-view #project-tabs {
    margin-bottom: 0;
    border-bottom: 1px solid var(--ui-hairline);
}

.opportunity-details-view .tab-content {
    margin-top: 0;
    padding-top: 0;
}

.opportunity-details-view .tab-title {
    border-bottom: 0;
}

/* Ficha de inventario: misma caja que estimates (page-wrapper + .card). */
.inventory-view > .card > .page-title {
    margin: 0;
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
}

.inventory-view-meta {
    border-bottom: 1px solid var(--ui-hairline);
    color: #4e5e6a;
}

.leads-details-view > .card > .page-title {
    margin: 0;
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
}

.leads-details-view #supplier-tabs {
    margin-bottom: 0;
    border-bottom: 1px solid var(--ui-hairline);
}

.assets-details-view > .card > .page-title {
    margin: 0;
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
}

.assets-details-view .nav-tabs.title {
    margin-bottom: 0;
    border-bottom: 1px solid var(--ui-hairline);
}

.tpvl-view-layout > .card {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

#page-content.page-wrapper.tpvl-view-layout {
    display: flex;
    flex-direction: column;
    height: calc(100vh - 65px);
    max-height: calc(100vh - 65px);
    overflow: hidden;
    box-sizing: border-box;
}

.tpvl-view-layout > .card > .tpv-sticky-header {
    border-bottom: 1px solid var(--ui-hairline);
}

.tpvl-view-layout > .card > .tpv-sticky-header > .page-title {
    margin: 0;
    border: 0;
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
}

.tpvl-view-layout > .card > .tpv-sticky-header .nav-tabs.title {
    margin-bottom: 0;
    border-bottom: 0;
}

.tpvl-view-layout #order-status-bar {
    border: 0;
    border-radius: 0;
    overflow: visible;
    box-shadow: none;
    margin-top: 0;
    padding-top: 0;
    padding-right: 370px;
}

.tpvl-view-layout #order-status-bar > .no-border {
    padding: 0 15px 8px 15px !important;
}

.tickets-details-view > .row > #ticket-left-panel > .card > .page-title {
    margin: 0;
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
}

.tickets-details-view #ticket-detail-tabs {
    margin-bottom: 0;
    border-bottom: 1px solid var(--ui-hairline);
}

#page-content.page-wrapper.packing-details-view {
    padding: 12px !important;
    margin: 0 !important;
    background: #e9edf2;
}

#page-content.page-wrapper.packing-details-view > .packing-view-card {
    background: transparent;
    border: 0;
    border-radius: 0;
    margin-bottom: 0;
    box-shadow: none;
}

/* Packing (listado y ficha): el menú se oculta del todo, no se deja
   el hueco de 250px / 70px de .page-container. */
body.packing-view-layout .page-container,
body.packing-view-layout.sidebar-toggled .page-container {
    margin-left: 0 !important;
}

body.packing-view-layout .navbar-custom,
body.packing-view-layout.sidebar-toggled .navbar-custom {
    left: 0 !important;
}

body.packing-view-layout .sidebar,
body.packing-view-layout.sidebar-toggled .sidebar,
body.packing-view-layout #sidebar-toggle-btn,
body.packing-view-layout #sidebar-menu_scroll {
    display: none !important;
}

body.packing-view-layout #default-navbar {
    margin-left: 0 !important;
}

.clients-details-view > .card > .page-title {
    margin: 0;
    border-bottom: 0;
    border-radius: var(--ui-radius);
}

.clients-details-view .clients-info-widgets-row {
    gap: 12px;
    padding: 12px 0;
    margin-left: 0;
    margin-right: 0;
}

.clients-details-view #client-tabs {
    margin-bottom: 0;
    border-bottom: 1px solid var(--ui-hairline);
}

.project-details-view > .card > .project-title-section > .page-title {
    margin: 0;
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
}

.project-details-view #project-tabs {
    margin-bottom: 0;
    border-bottom: 1px solid var(--ui-hairline);
}

#page-content.page-wrapper.project-details-view {
    padding: 10px 12px 12px !important;
}

.card .card-header,
.bg-white .card-header {
    padding: 12px 16px;
    border-bottom: 1px solid var(--ui-hairline);
}

.card .card-header:first-child {
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
}

.card .card-body {
    padding: 16px;
}

.card-footer {
    border-top: 1px solid var(--ui-hairline);
}

/* El contenedor de cada vista traía 25px por los cuatro lados. En pantallas
   de tabla ancha ese aire come sitio y da aspecto antiguo; se recorta el
   margen exterior, algo más arriba porque la barra superior ya separa.
   En móvil sigue mandando el #page-content de app.all.css, que va con
   !important dentro de su media query. */
.page-wrapper {
    padding: 10px 12px 12px;
}

.page-title {
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
    border-bottom: 1px solid var(--ui-hairline);
}

/* Ficha de presupuesto / pedido / factura: la cabecera no vive
   dentro de .card, así que no hereda el marco de 1px del contenedor. */
.page-title.document-details-header,
.page-title:has(#estimate-header),
.page-title:has(#order-header),
.page-title:has(#invoice-header) {
    border: 1px solid var(--ui-hairline);
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
    margin-bottom: 0;
}

/* La barra de estado va pegada a la cabecera (mismo marco, sin hueco).
   El borde se pone en el wrapper, que no se sustituye al recargar por AJAX. */
#estimate-status-bar,
#order-status-bar,
#invoice-status-bar {
    border: 1px solid var(--ui-hairline);
    border-top: 0;
    border-radius: 0 0 var(--ui-radius) var(--ui-radius);
    overflow: hidden;
    margin-top: 0;
    box-shadow: none;
}

/* Fichar: misma caja que estimates (page-wrapper + .card).
   El padding interno lo define la vista; el marco lo pone .card. */
.fichaje-page {
    max-width: 960px;
    margin: 0 auto;
}

.fichaje-panel-top,
.fichaje-tasks-section {
    border-color: var(--ui-hairline);
}

.fichaje-absence-action a,
.fichaje-tasks-card .dataTables_filter input,
.fichaje-tasks-card .dataTables_length select {
    border-color: var(--ui-hairline);
    border-radius: var(--ui-radius);
}

.page-title h1 {
    font-size: 18px;
    font-weight: 600;
}

/* Sidebar y topbar: separados por línea, no por sombra */
.sidebar {
    border-right: 1px solid var(--ui-hairline);
}

.sidebar-brand {
    border-bottom: 1px solid var(--ui-hairline);
}

.navbar-custom {
    border-bottom: 1px solid var(--ui-hairline);
}

.sidebar-menu {
    padding: 8px 0 16px;
}

/* Flex para que icono, texto y badge queden alineados de verdad.
   Se respetan los márgenes originales del span: el modo plegado
   (.sidebar-toggled) los reajusta y tiene más especificidad.

   Las filas ocupan todo el ancho, sin margen lateral ni radio: así el
   fondo del hover y el del elemento activo tienen exactamente la misma
   caja. Con márgenes, el activo (pegado al borde por su barra de acento)
   y el hover (metido hacia dentro) no cuadraban entre sí. El sangrado de
   20px a la izquierda es el que antes daban los 8 de margen más 12 de
   relleno, de modo que los iconos no se mueven de sitio. */
.sidebar-menu li a {
    display: flex;
    align-items: center;
    margin: 0;
    padding: 8px 20px;
    border-radius: 0;
    font-size: 15px;
    font-weight: 400;
    transition-duration: 150ms;
}

.sidebar-menu li a .menu-text,
.sidebar-menu li ul li a,
.sidebar-menu li.active > a,
.sidebar .sidebar-menu .nav-category {
    font-weight: 400;
}

/* Los iconos Feather vienen a 24px y con trazo 2, demasiado gruesos
   junto al texto. A 1.75 la línea queda más fina y limpia. */
.sidebar-menu li a > svg {
    width: 19px;
    height: 19px;
    flex-shrink: 0;
    stroke-width: 1.75;
}

/* Elemento activo con barra de acento en lugar de bloque macizo.
   --ui-accent y la clase .ui-sidebar-plain los publica el script de
   includes/custom_head.php: el acento se lee del .btn-primary del tema
   activo, y la clase solo se aplica si el menú tiene fondo neutro.
   Los temas que colorean el propio menú (5d78ff, Win98...) se quedan
   con su estilo, porque ahí un texto en color sobre color no se leería. */
.ui-sidebar-plain .sidebar-menu li.active > a {
    background-color: rgba(102, 144, 244, 0.12) !important;
    background-color: color-mix(in srgb, var(--ui-accent) 12%, transparent) !important;
    color: var(--ui-accent) !important;
    box-shadow: inset 3px 0 0 var(--ui-accent);
}

/* El badge iba con float, que no funciona dentro de un contenedor flex */
.sidebar-menu .badge {
    border-radius: var(--ui-radius);
    font-weight: 600;
    margin-top: 0 !important;
    margin-left: auto;
}

/* Hueco reservado para la flecha de desplegar, si no el texto se le mete debajo */
.sidebar-menu li.expand > a {
    padding-right: 32px;
}

/* En el menú plegado a 70px no hay flecha, y ese hueco reservado dejaba
   al icono sin sitio. Solo a partir de 991px: por debajo, .sidebar-toggled
   es el cajón lateral completo y ahí la flecha sí se ve. */
@media (min-width: 991px) {
    /* El plegado trae su propio relleno de 12px; al haber quitado el margen
       lateral, sin esto los iconos se irían 8px a la izquierda. */
    .sidebar-toggled .sidebar-menu li a {
        padding-left: 20px;
    }

    .sidebar-toggled .sidebar-menu li.expand > a {
        padding-right: 12px;
    }
}

.sidebar-menu li.expand > a .badge {
    margin-right: 0.4rem;
}

/* La flecha estaba clavada a "top: 1.2rem", calculado para el padding antiguo.
   Centrada al 50% ya no depende de la altura del elemento. */
#sidebar-menu li.expand > a::before,
#sidebar-menu li.expand.open > a::before {
    top: 50%;
    border-width: 0 1.5px 1.5px 0;
    padding: 2.5px;
    opacity: 0.55;
}

#sidebar-menu li.expand > a::before {
    transform: translateY(-70%) rotate(45deg);
}

#sidebar-menu li.expand.open > a::before {
    transform: translateY(-30%) rotate(-135deg);
}

/* Submenú: fuera los guiones "minus" que hacían de viñeta y en su lugar
   sangría con una guía vertical, como en los paneles actuales. */
.sidebar-menu li ul li a > svg {
    display: none;
}

.sidebar-menu li ul {
    position: relative;
}

.sidebar-menu li ul::before {
    content: "";
    position: absolute;
    left: 28px;
    top: 0;
    bottom: 0;
    width: 1px;
    background-color: var(--ui-hairline);
}

/* Submenú más compacto que el padre: la diferencia de altura es
   la que hace que se lea como subordinado y no como otra lista. */
.sidebar-menu li ul li a {
    margin: 0;
    padding: 6px 20px 6px 50px;
    border-radius: 0;
    font-size: 14px;
    font-weight: 400;
}

.sidebar-menu li.expand.open > ul {
    margin: 0 0 4px;
}

/* En modo plegado el submenú es un desplegable flotante: ahí ni guía ni sangría */
.sidebar-toggled .sidebar-menu li ul::before {
    display: none;
}

/* PerfectScrollbar pinta el raíl como absoluto sin z-index, mientras que
   .sidebar-menu li a lleva z-index 2 en el CSS base. Mientras las filas
   tenían margen lateral daba igual, pero ahora ocupan todo el ancho y sus
   fondos pasaban por encima del scroll, tapándolo a trozos.

   Se levanta el raíl por encima de las filas y se le quita el aspecto de
   pieza pegada: pulgar fino y semitransparente, que se integra igual sobre
   una fila normal, sobre el hover o sobre el elemento activo, y sin la
   pista gris que el plugin dibuja al pasar el ratón. */
.sidebar-scroll .ps__rail-y {
    z-index: 3;
    width: 11px;
}

.sidebar-scroll .ps__rail-y,
.sidebar-scroll .ps__rail-y:hover,
.sidebar-scroll .ps__rail-y:focus,
.sidebar-scroll .ps__rail-y.ps--clicking {
    background-color: transparent;
}

/* El plugin baja el raíl a 0.6 de opacidad; con un pulgar ya translúcido
   quedaría casi invisible, así que la visibilidad la marca solo su color */
.sidebar-scroll.ps:hover > .ps__rail-y,
.sidebar-scroll.ps--focus > .ps__rail-y,
.sidebar-scroll.ps--scrolling-y > .ps__rail-y {
    opacity: 1;
}

.sidebar-scroll .ps__thumb-y,
.sidebar-scroll .ps__rail-y:hover > .ps__thumb-y,
.sidebar-scroll .ps__rail-y:focus > .ps__thumb-y,
.sidebar-scroll .ps__rail-y.ps--clicking .ps__thumb-y {
    width: 5px;
    right: 3px;
    background-color: rgba(120, 130, 150, 0.4);
}

.sidebar-scroll .ps__rail-y:hover > .ps__thumb-y,
.sidebar-scroll .ps__rail-y.ps--clicking .ps__thumb-y {
    background-color: rgba(120, 130, 150, 0.6);
}

.sidebar-brand img {
    max-height: 40px;
    width: auto;
    object-fit: contain;
}

/* Controles */
.btn {
    border-radius: var(--ui-radius);
    font-family: var(--ui-font);
    font-weight: 500;
}

.form-control,
.input-group-text,
.input-group-addon,
.select2-container .select2-choice,
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple,
.chosen-container-single .chosen-single,
.chosen-container .chosen-choices {
    border-radius: var(--ui-radius);
}

.general-form .control-label,
.form-group .control-label,
label.form-label {
    font-weight: 500;
    font-size: 13.5px;
}

.nav-tabs,
.tab-title {
    border-bottom: 1px solid var(--ui-hairline);
}

.nav-tabs .nav-link,
.nav-tabs li a {
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
    font-weight: 500;
}

/* Otros datos y similares: el pie se reutiliza de un modal y el editor
   Summernote trae un marco más grueso que el hairline del resto. */
.tab-pane .modal-footer {
    border-top: 1px solid var(--ui-hairline);
    background: transparent;
    padding: 12px 0 4px;
    margin-top: 4px;
}

.note-editor,
.note-editor .note-toolbar,
.note-editor .note-statusbar .note-resizebar,
.note-editor .note-toolbar .btn {
    border-color: var(--ui-hairline) !important;
}

.note-editor.note-frame,
.note-editor.note-airframe {
    border-radius: var(--ui-radius);
    box-shadow: none;
}

/* Estas celdas llevaban el lavanda fijo, que además se veía mal en los temas
   oscuros. La línea semitransparente se adapta a cualquier fondo. */
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > th,
.table-bordered > tbody > tr > td,
.table-bordered > tfoot > tr > th,
.table-bordered > tfoot > tr > td {
    border-color: var(--ui-hairline);
}

/* Tablas: cabecera algo más marcada, densidad de filas intacta */
table.dataTable thead th,
table.dataTable thead td {
    font-weight: 600;
    border-bottom: 1px solid var(--ui-hairline);
}

.dataTables_wrapper .dataTables_paginate .paginate_button {
    border-radius: var(--ui-radius) !important;
}

/* Paneles flotantes: borde en lugar de halo */
.dropdown-menu {
    border: 1px solid var(--ui-hairline);
    border-radius: var(--ui-radius);
    box-shadow: none;
}

/* El modal es el único sitio donde la elevación significa algo: está de
   verdad por encima de la página. Al aplanar el resto de superficies le
   quité la sombra y se quedaba pegado al fondo, como un recorte. Vuelve,
   pero en dos capas suaves en vez del halo duro de antes, y con un radio
   mayor que el de los controles porque es una superficie flotante. */
.modal-content {
    border: 1px solid var(--ui-hairline);
    border-radius: 8px;
    box-shadow: 0 10px 15px -3px rgba(15, 23, 42, 0.14),
                0 4px 6px -4px rgba(15, 23, 42, 0.10);
}

/* Cabecera, cuerpo y pie venían con tres sangrados distintos (23px, 14px
   y 30px), así que el título, los campos y los botones no caían en la
   misma vertical. Ahora comparten los 20px. */
.modal-header {
    padding: 16px 20px;
    align-items: center;
    position: relative;
}

/* Hueco a la derecha para los tres botones de ventana, que van pegados a la
   esquina. Sin él, un título largo pasaría por debajo. */
.modal-header.ui-modal-has-controls {
    padding-right: 132px;
}

/* La aspa original se queda en el sitio, solo que sin verse: hay código de
   la aplicación que la pulsa desde JavaScript y así sigue funcionando. */
.ui-modal-has-controls > .btn-close {
    display: none;
}

.modal-body {
    padding: 20px;
}

/* Casi todos los formularios envuelven el contenido en un .container-fluid,
   que suma sus 12px de canal a los del modal y dejaba las etiquetas 12px
   más adentro que el título. Sin ese relleno, el margen negativo de .row y
   el de las columnas se cancelan y todo cae en la misma vertical. */
.modal-body > .container-fluid {
    padding-left: 0;
    padding-right: 0;
}

.modal-footer {
    padding: 14px 20px;
    gap: 8px;
}

/* Bootstrap separa los botones con márgenes en cada hijo, y app.all.css
   añade otros 10px al segundo. Eso desplazaba el último botón respecto al
   borde, así que el pie no cerraba en la misma vertical que el título.
   El hueco lo pone gap y los márgenes se anulan. */
.modal-footer > *,
.modal-footer .btn + .btn {
    margin: 0;
}

.modal-header,
.modal-footer {
    border-color: var(--ui-hairline);
}

.modal-title {
    font-size: 16px;
    font-weight: 600;
    line-height: 1.4;
}

/* El fondo negro puro de Bootstrap ensucia; en tono pizarra el contenido
   de detrás se apaga sin virar a gris sucio. */
.modal-backdrop {
    background-color: #0f172a;
}

.modal-backdrop.show {
    opacity: 0.45;
}

/* --- Modales como ventanas -----------------------------------------
   Los modales se manejan como ventanas: minimizar, maximizar, cerrar y
   estirar desde la esquina, con la medida guardada en localStorage para
   que al reabrir el mismo formulario vuelva como se dejó. Quien lo mueve
   todo es assets/js/modal-window.js.

   El tamaño viaja en dos variables en línea en vez de en width/height
   directos: así la regla deja de aplicarse sola cuando el diálogo pasa
   a pantalla completa, que tiene su propio ancho y no admite otro. */
.modal-dialog.ui-modal-resized:not(.modal-fullscreen):not(.ui-modal-maximized):not(.ui-modal-min) {
    width: var(--ui-modal-w) !important;
    max-width: var(--ui-modal-w) !important;
    height: var(--ui-modal-h);
}

.ui-modal-resized:not(.modal-fullscreen) .modal-content {
    height: 100%;
}

/* Con la altura fijada arriba manda el marco, y el cuerpo se queda con lo
   que sobra entre cabecera y pie.

   Ese alto sobrante lo calcula el script y lo pone en línea, en min-height
   y max-height, porque no hay forma de conseguirlo solo con CSS: entre el
   marco y el cuerpo hay envoltorios que cambian de un modal a otro (el
   contenedor del contenido ajax, el <form>, la zona de adjuntos...) y
   algunos llevan su propio display en línea, que además el código de la
   vista alterna. Acotar el cuerpo no depende de nada de eso.

   height:auto anula la altura en línea que deja PerfectScrollbar, y el
   overflow gana al hidden que ese mismo plugin pone sobre .ps. */
.ui-modal-resized:not(.modal-fullscreen) .modal-body {
    height: auto !important;
    overflow-y: auto !important;
}

.ui-modal-resized:not(.modal-fullscreen) .modal-body > .ps__rail-x,
.ui-modal-resized:not(.modal-fullscreen) .modal-body > .ps__rail-y {
    display: none !important;
}

/* Los tres botones de ventana, pegados a la esquina superior derecha y con
   la altura entera de la barra de título, como en Windows. */
.ui-modal-controls {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    display: flex;
    z-index: 5;
}

.ui-modal-btn {
    position: relative;
    width: 44px;
    padding: 0;
    border: 0;
    border-radius: 0;
    background-color: transparent;
    color: inherit;
    opacity: 0.75;
    transition: background-color 120ms linear, opacity 120ms linear;
}

.ui-modal-btn:last-child {
    /* El radio interior del marco, para no desbordar la esquina redondeada. */
    border-top-right-radius: 7px;
}

.ui-modal-btn:hover {
    opacity: 1;
    background-color: rgba(128, 138, 157, 0.2);
}

.ui-modal-btn:focus {
    outline: 0;
    box-shadow: none;
}

/* El aspa se pone en rojo al pasar por encima, como la de Windows. */
.ui-modal-close:hover {
    background-color: #e81123;
    color: #fff;
    opacity: 1;
}

/* Los iconos son rayas y cuadros hechos con los pseudoelementos: se ven
   nítidos a cualquier zoom y heredan el color del texto, así que valen igual
   en los temas claros y en los oscuros. */
.ui-modal-btn::before,
.ui-modal-btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    background-color: currentColor;
}

.ui-modal-minimize::before {
    width: 10px;
    height: 1px;
    margin-left: -5px;
}

.ui-modal-maximize::before {
    width: 10px;
    height: 10px;
    margin: -5px 0 0 -5px;
    border: 1px solid currentColor;
    background-color: transparent;
}

/* Maximizado, el cuadro pasa a ser dos superpuestos: el icono de restaurar.
   En la barra no, porque allí ese botón no restaura sino que vuelve a abrir
   la ventana, y el icono de dos cuadros diría lo contrario. */
.ui-modal-maximized:not(.ui-modal-min) .ui-modal-maximize::before {
    width: 8px;
    height: 8px;
    margin: -2px 0 0 -5px;
}

.ui-modal-maximized:not(.ui-modal-min) .ui-modal-maximize::after {
    width: 8px;
    height: 8px;
    margin: -5px 0 0 -2px;
    border: 1px solid currentColor;
    background-color: transparent;
}

.ui-modal-close::before,
.ui-modal-close::after {
    width: 13px;
    height: 1px;
    margin-left: -6.5px;
}

.ui-modal-close::before {
    transform: rotate(45deg);
}

.ui-modal-close::after {
    transform: rotate(-45deg);
}

/* Maximizado: el diálogo ocupa la ventana entera y pierde los redondeos,
   igual que una ventana maximizada de verdad. El alto del cuerpo lo sigue
   repartiendo el script, no la clase modal-fullscreen de Bootstrap, que da
   por hecho que el cuerpo cuelga directamente del marco.

   Los :not(.ui-modal-min) dejan paso al estado minimizado, que manda sobre
   todos los demás: una ventana maximizada sigue estando maximizada mientras
   se la tiene recogida en la barra, y al volver a abrirla debe salir como
   estaba, pero entretanto lo que se ve es la barra. */
.modal-dialog.ui-modal-maximized:not(.ui-modal-min) {
    width: 100% !important;
    max-width: 100% !important;
    height: 100%;
    margin: 0;
}

.ui-modal-maximized:not(.ui-modal-min) .modal-content {
    height: 100%;
    border-width: 0;
    border-radius: 0;
}

.ui-modal-maximized:not(.ui-modal-min) .ui-modal-btn:last-child {
    border-top-right-radius: 0;
}

/* Minimizado: el modal se recoge en una barra abajo a la izquierda y suelta
   la página, que es justo para lo que se minimiza. El fondo oscuro se quita
   y el contenedor deja pasar los clics; solo la barra los recibe. */
.modal.ui-modal-minimized {
    pointer-events: none;
    overflow: visible;
}

body.ui-modal-minimized-open {
    overflow: auto !important;
    padding-right: 0 !important;
}

body.ui-modal-minimized-open .modal-backdrop {
    display: none !important;
}

/* Las reglas del tamaño guardado y del maximizado se apartan solas cuando el
   diálogo lleva ui-modal-min, así que aquí no hace falta pelear por el peso
   del selector: la barra siempre mide lo mismo y va abajo, venga la ventana
   del tamaño que venga. */
.modal.ui-modal-minimized .modal-dialog {
    position: fixed;
    left: 12px;
    bottom: 0;
    width: 320px !important;
    max-width: calc(100vw - 24px) !important;
    height: auto !important;
    margin: 0;
    pointer-events: auto;
    transform: none !important;
}

.modal.ui-modal-minimized .modal-dialog .modal-content {
    height: auto;
    border-radius: 6px 6px 0 0;
}

/* Solo se ve la barra de título. Se oculta con display para que el
   formulario siga en el sitio con lo que hubiera escrito. */
.modal.ui-modal-minimized .modal-content > *:not(.modal-header) {
    display: none !important;
}

.modal.ui-modal-minimized .modal-header {
    border-bottom: 0;
    cursor: pointer;
    padding-right: 90px;
}

.modal.ui-modal-minimized .modal-title {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* Minimizada ya está minimizada: ese botón no pinta nada. */
.modal.ui-modal-minimized .ui-modal-minimize {
    display: none;
}

/* Los avisos flotantes venían con z-index 100, muy por debajo de los 1055 de
   un modal, así que quedaban tapados. Antes daba igual, porque con el modal
   abierto el fondo oscuro los escondía de todas formas; ahora la ventana
   minimizada comparte el borde de abajo con ellos y se los comía justo
   cuando hay algo que leer. Solo sube el aviso flotante: los que se pintan
   dentro del cuerpo de un modal no llevan esta clase y se quedan donde
   están. */
.app-alert.animate {
    z-index: 1060;
}

.ui-modal-resizer {
    position: absolute;
    right: 1px;
    bottom: 1px;
    z-index: 5;
    width: 16px;
    height: 16px;
    cursor: nwse-resize;
    opacity: 0.28;
    border-bottom-right-radius: 7px;
    /* Rayado en diagonal con un degradado repetido: sin icono ni imagen, y
       como usa currentColor se ve igual en los temas claros y en los oscuros. */
    background-image: repeating-linear-gradient(-45deg,
            currentColor 0 1.5px,
            transparent 1.5px 4px);
    touch-action: none;
}

.ui-modal-resizer:hover {
    opacity: 0.55;
}

/* Maximizada no se puede estirar: ya ocupa toda la ventana. */
.ui-modal-maximized .ui-modal-resizer {
    display: none;
}

/* Al arrastrar, el puntero cruza el texto del modal y el navegador lo iría
   seleccionando; el cursor se fija para que no parpadee al pasar por encima
   de botones y campos. */
.ui-modal-resizing,
.ui-modal-resizing * {
    cursor: nwse-resize !important;
    user-select: none !important;
}

/* En móvil el modal ya ocupa casi toda la pantalla: no hay margen que estirar
   ni que maximizar, así que de los tres botones se queda solo el de cerrar,
   que si no se comerían medio ancho de la barra de título.

   De ignorar la medida guardada en el escritorio se encarga el script, que ni
   siquiera le pone la clase al diálogo. Aquí había unas reglas que deshacían
   el tamaño, pero era pelear por el peso de los selectores: en cuanto el de
   arriba creció, dejaron de ganar sin que se notara. */
@media (max-width: 575.98px) {
    .ui-modal-resizer,
    .ui-modal-minimize,
    .ui-modal-maximize {
        display: none;
    }

    .modal-header.ui-modal-has-controls {
        padding-right: 56px;
    }
}

.dropdown-item {
    border-radius: 2px;
}

.badge {
    border-radius: var(--ui-radius);
    font-weight: 600;
}

.list-group-item {
    border-color: var(--ui-hairline);
}

/* appTable: scroll horizontal (toggle en popover del ojo) */
.table-responsive.apptable-horizontal-scroll,
.dataTables_wrapper.apptable-horizontal-scroll {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.table-responsive.apptable-horizontal-scroll::-webkit-scrollbar,
.dataTables_wrapper.apptable-horizontal-scroll::-webkit-scrollbar {
    height: 0;
    display: none;
}

.apptable-sticky-hscroll {
    position: fixed;
    z-index: 1040;
    height: 14px;
    overflow-x: auto;
    overflow-y: hidden;
    background: rgba(255, 255, 255, 0.96);
    border-top: 1px solid var(--ui-hairline, #e2e7f1);
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
    -webkit-overflow-scrolling: touch;
}

.apptable-sticky-hscroll-inner {
    height: 1px;
}

.table-responsive.apptable-horizontal-scroll table.dataTable,
.dataTables_wrapper.apptable-horizontal-scroll table.dataTable {
    width: max-content !important;
    min-width: 100%;
    table-layout: auto !important;
}

.table-responsive.apptable-horizontal-scroll table.dataTable th,
.table-responsive.apptable-horizontal-scroll table.dataTable td,
.dataTables_wrapper.apptable-horizontal-scroll table.dataTable th,
.dataTables_wrapper.apptable-horizontal-scroll table.dataTable td {
    white-space: nowrap !important;
    width: auto !important;
    max-width: none !important;
}

.apptable-horizontal-scroll table.dataTable .w25 { min-width: 25px; }
.apptable-horizontal-scroll table.dataTable .w70 { min-width: 70px; }
.apptable-horizontal-scroll table.dataTable .w80 { min-width: 80px; }
.apptable-horizontal-scroll table.dataTable .w100 { min-width: 100px; }
.apptable-horizontal-scroll table.dataTable .w125 { min-width: 125px; }
.apptable-horizontal-scroll table.dataTable .w150 { min-width: 150px; }
.apptable-horizontal-scroll table.dataTable .w175 { min-width: 175px; }
.apptable-horizontal-scroll table.dataTable .w200 { min-width: 200px; }
.apptable-horizontal-scroll table.dataTable .w250 { min-width: 250px; }
.apptable-horizontal-scroll table.dataTable .w300 { min-width: 300px; }
.apptable-horizontal-scroll table.dataTable .w400 { min-width: 400px; }
.apptable-horizontal-scroll table.dataTable .min-w150 { min-width: 150px; }
.apptable-horizontal-scroll table.dataTable .w5p { min-width: 60px; }
.apptable-horizontal-scroll table.dataTable .w10p { min-width: 80px; }
.apptable-horizontal-scroll table.dataTable .w15p { min-width: 100px; }
.apptable-horizontal-scroll table.dataTable .w20p { min-width: 120px; }
.apptable-horizontal-scroll table.dataTable .w25p { min-width: 140px; }
.apptable-horizontal-scroll table.dataTable .w30p { min-width: 160px; }

/* Columnas fijadas con scroll horizontal */
.apptable-col-fixed {
    background-color: #fff !important;
}

.apptable-col-fixed-head {
    background-color: #fff !important;
}

.apptable-col-fixed-last {
    box-shadow: 4px 0 6px -2px rgba(0, 0, 0, 0.12);
}

table.dataTable tbody tr:hover .apptable-col-fixed,
table.dataTable.display tbody tr:hover .apptable-col-fixed {
    background-color: #f2f4f6 !important;
}

table.dataTable tbody tr.active .apptable-col-fixed,
table.dataTable.display tbody tr.active .apptable-col-fixed {
    background-color: #6690F4 !important;
    color: #fff !important;
}

.apptable-column-pin-header {
    background-color: #f8f9fa;
}

.apptable-pin-header-label {
    min-width: 88px;
    text-align: center;
    font-size: 11px;
    font-weight: 600;
    color: #6c757d;
    letter-spacing: 0.02em;
    flex-shrink: 0;
}

.apptable-column-item .apptable-pin-label {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 88px;
    flex-shrink: 0;
}

.apptable-reset-defaults {
    background-color: #f8f9fa;
}

.apptable-reset-defaults .apptable-reset-layout-btn {
    font-size: 12px;
}

/* Redimensionar columnas arrastrando entre cabeceras */
table.dataTable.apptable-col-resize-enabled thead th {
    position: relative;
}

.apptable-col-resizer {
    position: absolute;
    top: 0;
    right: 0;
    width: 8px;
    height: 100%;
    cursor: col-resize;
    user-select: none;
    z-index: 45;
    touch-action: none;
}

.apptable-col-resizer:hover {
    background: rgba(102, 144, 244, 0.25);
}

body.apptable-col-resizing,
body.apptable-col-resizing * {
    cursor: col-resize !important;
    user-select: none !important;
}

/* Contener columnas ampliadas dentro del fondo blanco (sin modo scroll horizontal) */
.apptable-table-scroll-clip {
    width: 100%;
    max-width: 100%;
}

.apptable-table-scroll-clip.apptable-col-overflow {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
    background-color: #fff;
}

.apptable-table-scroll-clip.apptable-col-overflow > table.dataTable {
    width: max-content !important;
    min-width: 100%;
}

/* --- Kanban ---------------------------------------------------------
   Las seis vistas de tablero (oportunidades, tareas, tareas de proyecto,
   tickets, proyectos y leads/proveedores) comparten las clases kanban-col,
   kanban-col-title, kanban-item-list y kanban-item, así que todo lo de aquí
   les vale a las seis. Las de leads y proveedores ponen en la misma etiqueta
   lead-kanban-item y kanban-item, de modo que entran solas.

   Lo que había venía de app.all.css (líneas 5156 y siguientes): tarjetas en
   display:table de 300px fijos, columnas flotadas y cabeceras en bloques
   blancos sueltos.

   El HTML no se toca, así que esto se deshace borrando la sección. */

/* El tinte se va del contenedor a cada columna. Así cada una se lee como un
   carril, y el hueco que dejan las que tienen pocas tarjetas pasa a
   entenderse como carril vacío en vez de como un fallo de maquetación: la
   altura la fija el script de cada vista a lo alto de la ventana, y de ella
   depende que se carguen más tarjetas al bajar, así que no se toca.

   El fondo del contenedor era un gris fijo (#D9DEE2) que cada tema tapaba
   por su cuenta; en transparente manda el de la página. */
.kanban-container {
    background: transparent;
    padding-top: 12px;
}

/* Los 30px de separación entre carriles (dos márgenes de 15) se quedan en 10,
   y los 20 que sobran se los lleva el ancho del carril.

   El reparto tiene que sumar 335px, que es lo que el script de las siete
   vistas da por hecho al calcular el ancho del tablero entero: si la suma se
   queda corta sobra sitio al final del tablero, y si se pasa, la última
   columna se cae de fila. El relleno no entra en la cuenta porque el
   box-sizing de Bootstrap lo mete dentro del ancho.

   --kanban-status lo publica kanban-fullscreen.js desde el color que ya
   trae la cabecera. Hasta que llega, el carril usa un gris neutro. */
.kanban-col {
    --kanban-status: rgba(130, 140, 160, 0.7);
    width: 325px;
    margin: 0 5px;
    padding: 0 0 6px;
    overflow: hidden;
    border: 1px solid var(--ui-hairline);
    border-radius: 8px;
    background-color: rgba(130, 140, 160, 0.07);
    box-shadow: inset 0 3px 0 var(--kanban-status);
}

@supports (background: color-mix(in srgb, red 10%, transparent)) {
    .kanban-col {
        background-color: color-mix(in srgb, var(--kanban-status) 8%, transparent);
    }
}

/* Cabecera del carril: tinte del estado, punto de color y el borde inferior
   original apagado, porque el capuchón de 3px de la columna ya cumple ese
   papel y con los dos a la vez sobraba. */
.kanban-col-title {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 12px 10px;
    margin: 0 0 6px;
    background: rgba(130, 140, 160, 0.08);
    color: inherit;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-radius: 0;
    border-bottom-width: 0 !important;
}

.kanban-col-title::before {
    content: "";
    flex: 0 0 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--kanban-status);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--kanban-status) 22%, transparent);
}

@supports not (background: color-mix(in srgb, red 10%, transparent)) {
    .kanban-col-title::before {
        box-shadow: 0 0 0 3px rgba(130, 140, 160, 0.18);
    }
}

@supports (background: color-mix(in srgb, red 10%, transparent)) {
    .kanban-col-title {
        background: color-mix(in srgb, var(--kanban-status) 14%, transparent);
    }
}

/* El contador iba con float, que en un contenedor flex no hace nada; el
   hueco lo abre el margen automático. */
.kanban-col-title .kanban-item-count {
    margin-left: auto;
    min-width: 22px;
    padding: 2px 7px;
    border-radius: 999px;
    background-color: rgba(130, 140, 160, 0.2);
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
    text-align: center;
    text-transform: none;
}

@supports (background: color-mix(in srgb, red 10%, transparent)) {
    .kanban-col-title .kanban-item-count {
        background-color: color-mix(in srgb, var(--kanban-status) 22%, transparent);
    }
}

/* El alto de la lista lo fija el script de cada vista con un style en línea,
   pero app.all.css lo remataba con un max-height de 730px que se lo comía en
   cuanto la ventana daba de sí: las columnas se quedaban cortas y sobraba
   fondo por debajo. Soltando el máximo manda el alto calculado, que es de lo
   que además depende que se carguen más tarjetas al llegar abajo. */
.kanban-item-list {
    max-height: none;
    padding: 0 6px;
}

.kanban-input {
    padding: 0 6px;
}

.kanban-input .form-control {
    width: 100%;
    border-radius: var(--ui-radius);
}

/* Las tarjetas eran display:table con un ancho fijo de 300px, que es lo que
   las dejaba clavadas sin importar el carril. En bloque y con ancho
   automático lo llenan. */
.kanban-item {
    position: relative;
    display: block;
    width: auto;
    margin: 0 0 8px;
    padding: 12px 14px;
    border: 1px solid var(--ui-hairline);
    border-radius: 6px;
    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.06), transparent 32px);
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.45;
    transition: border-color 140ms linear, box-shadow 140ms linear, transform 140ms ease;
}

/* El avatar vuelve a la izquierda, flotado delante del título, que es donde
   se leía como “quién la tiene” sin tapar los iconos de la derecha. */
.kanban-item .avatar {
    position: static;
    float: left;
}

.kanban-item .avatar img {
    width: 26px;
    height: 26px;
    margin-right: 10px;
    border-radius: 50%;
    object-fit: cover;
    box-shadow: 0 0 0 2px rgba(130, 140, 160, 0.18);
}

/* El título de la tarjeta es texto suelto dentro del enlace y todo lo demás
   va envuelto en div. Eso permite darle peso sin tocar el HTML: la tarjeta
   marca el tono del título y sus div vuelven al normal. */
.kanban-item > div {
    font-size: 12px;
    font-weight: 400;
}

/* Salvo en leads y proveedores, donde la tarjeta es un span y el título va
   en un enlace dentro del primer div, así que ahí hay que devolvérselo. */
.kanban-item.lead-kanban-item > div:first-child {
    font-size: 13.5px;
    font-weight: 600;
}

.kanban-item.lead-kanban-item small {
    font-size: 11.5px;
    opacity: 0.85;
}

.kanban-item .mt10 {
    margin-top: 8px;
}

.kanban-item .icon-14,
.kanban-item .icon-16 {
    opacity: 0.55;
    vertical-align: -2px;
}

.kanban-item > .meta {
    float: none;
    display: inline-flex;
    align-items: center;
    margin: 8px 6px 0 0;
}

.kanban-item .priority-badge,
.kanban-item .sub-task-icon {
    border-radius: 4px;
}

/* Al pasar el ratón se levanta un milímetro. El color de fondo del hover se
   deja como está, que es cosa de cada tema. */
.kanban-item:hover,
.kanban-item:active,
.kanban-item:focus {
    border-color: rgba(130, 140, 160, 0.45);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
    transform: translateY(-1px);
    text-decoration: none;
}

/* Barras de scroll. Las de origen las pinta a mano el <style> de cada vista
   (14px con el pulgar en gris #888 sobre pista clara, y 30 o 40px en
   tablet), y son lo que más ensucia el tablero. Ese <style> va después en el
   documento, así que para ganarle no vale con repetir el selector: se le
   antepone body, que suma un elemento y decide por especificidad sin
   depender del orden. Las reglas de tablet usan los mismos selectores, de
   modo que estas les ganan también. */
body #kanban-wrapper::-webkit-scrollbar,
body .kanban-item-list::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

body #kanban-wrapper::-webkit-scrollbar-track,
body .kanban-item-list::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 0;
}

body #kanban-wrapper::-webkit-scrollbar-thumb,
body .kanban-item-list::-webkit-scrollbar-thumb {
    border: 0;
    border-radius: 999px;
    background: rgba(120, 130, 150, 0.35);
}

body #kanban-wrapper::-webkit-scrollbar-thumb:hover,
body .kanban-item-list::-webkit-scrollbar-thumb:hover {
    background: rgba(120, 130, 150, 0.55);
}

/* El hueco donde va a caer la tarjeta: marco discontinuo teñido con el
   estado del carril, que se entiende como sitio libre. */
.kanban-sortable-ghost {
    border: 1px dashed color-mix(in srgb, var(--kanban-status) 55%, transparent);
    background-color: color-mix(in srgb, var(--kanban-status) 10%, transparent);
    background-image: none;
    box-shadow: none;
    transform: none;
}

/* La tarjeta de origen mientras se arrastra. Se atenúa y se inclina un poco,
   que es más fácil de seguir que el opacity: 0.2 de antes. */
.kanban-sortable-chosen {
    opacity: 0.45;
    box-shadow: none;
    transform: rotate(1.5deg);
}

/* Barra de filtros del kanban.
   Tres zonas fijas (las monta kanban-fullscreen.js): el botón verde de
   guardar a la izquierda, desplegables en el centro (pueden bajar de fila)
   y el buscador a la derecha, como en los listados. */
.kanban-filters-container,
#js-kanban-filter-container {
    position: relative;
    padding: 10px 12px 8px;
}

.kanban-filter-bar {
    display: flex !important;
    flex-wrap: nowrap;
    align-items: flex-start;
    gap: 8px;
}

.kanban-filter-bar > .row {
    display: none !important;
}

.kanban-filter-bar-left,
.kanban-filter-bar-right {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}

.kanban-filter-bar-left .DTTT_container,
.kanban-filter-bar-right .DTTT_container,
.kanban-filter-bar-left div.DTTT_container,
.kanban-filter-bar-right div.DTTT_container {
    float: none !important;
    display: flex;
    align-items: center;
    margin: 0 !important;
}

.kanban-filter-bar-right .btn,
.kanban-filter-bar-right .custom-filter-search,
.kanban-filter-bar-right .dataTables_filter input {
    box-sizing: border-box;
    height: 35px;
}

.kanban-filter-bar-right .btn:not(.dt-button) {
    width: 35px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.kanban-filter-bar-right .btn svg {
    margin-top: 0;
}

.kanban-filter-bar-right .custom-filter-search,
.kanban-filter-bar-right .dataTables_filter input {
    width: 200px;
    max-width: 100%;
    padding-top: 0;
    padding-bottom: 0;
    margin: 0 !important;
}

.kanban-filter-bar-mid {
    flex: 1 1 auto;
    min-width: 0;
}

.kanban-filter-bar-mid #kanban-filters {
    width: 100%;
    max-width: none;
    padding: 0;
}

.kanban-filter-bar .custom-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
}

.kanban-filter-bar .custom-toolbar .DTTT_container,
.kanban-filter-bar .custom-toolbar div.DTTT_container {
    float: none !important;
    position: relative;
    margin: 0 !important;
}

.kanban-filter-bar .custom-toolbar .navbar-collapse.show {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
    width: 100%;
    padding: 8px 0 0;
}

.kanban-filter-bar #save-filters-btn,
.kanban-filter-bar #clear-filters-btn,
.kanban-filter-bar #clear-kanban-filters-btn,
.kanban-filter-bar #kanban-all-toggle-other-filters-btn {
    margin: 0 !important;
    flex: 0 0 auto;
    height: 35px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
}

.kanban-filter-bar .kanban-fullscreen-btn {
    position: static;
    z-index: 2;
    flex: 0 0 auto;
}

.kanban-filter-bar .input-daterange {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
}

.kanban-filter-bar .input-daterange .btn {
    height: 35px;
    display: inline-flex;
    align-items: center;
}

/* Listado DataTables (oportunidades): quitar el float de la barra original
   y alinear desplegables, Excel y buscador a la misma altura. */
.datatable-tools.kanban-filter-bar {
    margin-top: 0 !important;
    margin-bottom: 8px !important;
    padding: 8px 12px 4px;
    width: 100%;
}

.kanban-filter-bar-left .toolbar-left-top,
.kanban-filter-bar-left .w140,
.kanban-filter-bar-left .float-start {
    float: none !important;
    width: auto !important;
    padding-left: 0 !important;
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
}

.kanban-filter-bar-left .dataTables_length {
    float: none;
    margin: 0;
}

.kanban-filter-bar-left .column-show-hide-popover {
    margin-left: 0 !important;
    width: 35px;
    height: 35px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.kanban-filter-bar-mid .custom-toolbar,
.kanban-filter-bar-mid .w-filter-right,
.kanban-filter-bar-mid .float-end {
    float: none !important;
    width: 100% !important;
    padding-right: 0 !important;
}

.kanban-filter-bar-right .dataTables_filter {
    float: none !important;
    margin: 0 !important;
    display: flex;
    align-items: center;
}

.kanban-filter-bar-right .dataTables_filter label {
    display: flex;
    align-items: center;
    margin: 0;
    gap: 6px;
}

.kanban-filter-bar-right .dt-button,
.kanban-filter-bar-right .datatable-export .btn,
.kanban-filter-bar-right .datatable-export a {
    width: auto;
    height: 35px;
    padding: 0 10px;
    display: inline-flex;
    align-items: center;
    margin: 0;
}

.kanban-filter-bar .select2-container .select2-selection--single {
    height: 35px;
    display: flex;
    align-items: center;
}

.kanban-filter-bar .select2-container--default .select2-selection--single .select2-selection__rendered {
    line-height: 33px;
    padding-top: 0;
    padding-bottom: 0;
    margin: 0;
}

.kanban-filter-bar .select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 33px;
    top: 1px;
}

@media (max-width: 799px) {
    .kanban-filter-bar {
        flex-wrap: wrap;
    }

    .kanban-filter-bar-left {
        order: 1;
    }

    .kanban-filter-bar-right {
        order: 2;
        margin-left: auto;
    }

    .kanban-filter-bar-mid {
        order: 3;
        flex-basis: 100%;
    }

    .kanban-filter-bar .custom-filter-search,
    .kanban-filter-bar .dataTables_filter input {
        width: 160px;
    }
}

/* Modo expandido. La clase la pone y la quita el script; aquí solo se apaga
   el marco de la aplicación para que el tablero se quede con la ventana.

   Los desplazamientos de .page-container son los que compensaban la barra
   superior fija y el menú lateral (margin-top 65px y margin-left 250px en
   app.all.css); sin ellos el contenido sube y se pega a la izquierda. */
body.ui-kanban-expanded #default-navbar,
body.ui-kanban-expanded .sidebar {
    display: none !important;
}

body.ui-kanban-expanded .page-container {
    margin-top: 0;
    margin-left: 0;
}

body.ui-kanban-expanded #page-content.page-wrapper {
    padding: 8px;
}

/* Document index preview (estimates, orders, invoices) */
.document-number-with-preview {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
    line-height: 1.2;
    padding-left: 10px;
}

#monthly-order-table .document-number-with-preview {
    padding-left: 15px;
}

.document-number-with-preview__main {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.document-number-with-preview .estimate-preview-trigger,
.document-number-with-preview .order-preview-trigger,
.document-number-with-preview .invoice-preview-trigger,
#monthly-estimate-table .estimate-preview-trigger,
#yearly-estimate-table .estimate-preview-trigger,
#custom-estimate-table .estimate-preview-trigger,
#monthly-order-table .order-preview-trigger,
#monthly-invoice-table .invoice-preview-trigger {
    float: none;
    flex: 0 0 18px;
    width: 18px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    opacity: 0.45;
    margin-left: 0;
    line-height: 1;
    vertical-align: middle;
}

#monthly-estimate-table .estimate-preview-trigger:hover,
#yearly-estimate-table .estimate-preview-trigger:hover,
#custom-estimate-table .estimate-preview-trigger:hover,
#monthly-estimate-table .estimate-preview-trigger.is-active,
#yearly-estimate-table .estimate-preview-trigger.is-active,
#custom-estimate-table .estimate-preview-trigger.is-active,
#monthly-order-table .order-preview-trigger:hover,
#monthly-order-table .order-preview-trigger.is-active,
#monthly-invoice-table .invoice-preview-trigger:hover,
#monthly-invoice-table .invoice-preview-trigger.is-active {
    opacity: 1;
    color: var(--bs-primary, #0d6efd);
}

#monthly-estimate-table .estimate-preview-trigger.is-active,
#yearly-estimate-table .estimate-preview-trigger.is-active,
#custom-estimate-table .estimate-preview-trigger.is-active,
#monthly-order-table .order-preview-trigger.is-active,
#monthly-invoice-table .invoice-preview-trigger.is-active {
    font-weight: 600;
}

.document-preview-panel {
    display: none;
    position: absolute;
    z-index: 1060;
    overflow: hidden;
    flex-direction: column;
    box-shadow: 0 16px 40px rgba(15, 23, 42, 0.18);
    border-radius: var(--ui-radius);
    padding: 0;
}

.document-preview-panel .document-preview-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
    height: 32px;
    padding: 0 6px 0 12px;
    border-bottom: 1px solid var(--ui-hairline, #dee2e6);
    background: #fff;
    border-radius: var(--ui-radius) var(--ui-radius) 0 0;
}

.document-preview-panel .document-preview-panel-title {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    font-weight: 600;
    line-height: 32px;
    color: #1f2937;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.document-preview-panel .document-preview-panel-actions {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: 2px;
    margin-left: 8px;
}

.document-preview-panel .document-preview-panel-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 0;
    background: transparent;
    color: #6b7280;
    border-radius: 4px;
    cursor: pointer;
    text-decoration: none;
    line-height: 1;
}

.document-preview-panel .document-preview-panel-action:hover {
    color: #111827;
    background: #f3f4f6;
}

.document-preview-panel .document-preview-panel-action .icon-16 {
    width: 15px;
    height: 15px;
}

.document-preview-panel .document-preview-panel-body {
    position: relative;
    flex: 0 1 auto;
    overflow: visible;
    background: #fff;
}

.document-preview-panel .document-preview-panel-loading {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.92);
    color: #64748b;
    font-size: 14px;
}

.document-preview-panel .estimate-preview-popover-body {
    padding: 0;
}

.document-preview-panel .estimate-preview-table-wrap {
    padding: 8px 10px 0;
}

.document-preview-panel .estimate-preview-empty {
    padding: 28px 12px;
    text-align: center;
    border: 1px dashed var(--ui-hairline);
    border-radius: var(--ui-radius);
    background: #f8fafc;
}

.document-preview-panel .estimate-preview-items-table {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}

.document-preview-panel .estimate-preview-items-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: #f8fafc;
    border-bottom: 1px solid var(--ui-hairline);
    white-space: nowrap;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #475569;
}

.document-preview-panel .estimate-preview-items-table tbody td {
    font-size: 13px;
    vertical-align: middle;
}

.document-preview-panel .estimate-preview-item-title {
    max-width: 340px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.document-preview-panel .estimate-preview-row-meta td {
    background: #f1f5f9;
    font-size: 12px;
}

.document-preview-panel .estimate-preview-row-more td {
    background: #fff;
    font-size: 12px;
}

.document-preview-panel .estimate-preview-items-count {
    padding: 4px 0 0;
    font-size: 11px;
    color: #64748b;
}

.document-preview-panel .estimate-preview-summary {
    margin: 8px 10px 10px;
    padding: 8px 10px;
    border: 1px solid var(--ui-hairline);
    border-radius: var(--ui-radius);
    background: #f8fafc;
}

.document-preview-panel .estimate-preview-summary-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 2px 0;
    font-size: 12px;
    color: #334155;
}

.document-preview-panel .estimate-preview-summary-total {
    font-size: 14px;
    font-weight: 700;
    color: #0f172a;
}
