/* ==========================================================================
   ERP-Pro — componentes del panel (2.3.3, tanda 2 de la auditoria de UX).
   --------------------------------------------------------------------------
   QUE ES ESTO. Las piezas que comparten todas las pantallas y que no son de
   ninguna en concreto:

     1. Listados en el movil: la fila de la tabla como tarjeta
     2. Tablas que no caben: desplazamiento dentro de su caja
     3. Menu de acciones de la fila («⋯»)
     4. Cargando: esqueleto y barra en lugar del «Procesando...» suelto
     5. Vacios que dicen que hacer
     6. Barra de guardado
     7. Familia de etiquetas: los estados con clase propia de cada modulo
     8. Pantallas que desbordaban el movil por su cuenta

   Lo GOBIERNA el JavaScript (`assets/js/app-list.js` y
   `assets/js/app-savebar.js`): pone las clases segun el ancho y el contenido,
   y aqui solo se dibuja. Por eso el ancho del cambio a tarjetas es un AJUSTE
   (Apariencia → «Listados en el movil», atributo `data-erp-cards` del <html>)
   y no una media query fija: una media query no puede leer un ajuste.

   Se carga con CUALQUIER capa -tambien `classic`-, en el panel y en el portal,
   detras de erp-base.css y delante de la capa de diseño. Igual que alli, todo
   var() lleva respaldo: en la clasica los tokens no existen.

   ESPECIFICIDAD. El bundle del tema cualifica por elemento
   (`table.dataTable tbody td`, `div.dataTables_wrapper div...`), asi que
   aqui los selectores de la tabla en tarjetas van tambien por elemento
   (`table.erp-cards-on > tbody > tr > td`) y con la clase de estado: ganan sin
   `!important` salvo donde el tema ya lo usa (anchos en linea de DataTables,
   `white-space: nowrap` de las celdas).
   ========================================================================== */

/* ================================== 1. LISTADOS EN EL MOVIL: TARJETAS ===== */

/* Cada fila es una tarjeta: el titulo (la columna principal) arriba, las
   acciones a su derecha, el estado debajo como etiqueta y dos o tres datos con
   la etiqueta de su columna. Lo demas, plegado detras de «Ver N datos mas»: no
   se corta nada.

   Las clases las pone app-list.js en cada dibujado:
     td.erp-card__check    la casilla de seleccion
     td.erp-card__title    la columna principal
     td.erp-card__actions  los botones de la fila
     td.erp-card__status   la columna de estado (una etiqueta)
     td.erp-card__extra    lo que va plegado
     td.erp-card__blank    una celda sin nada que enseñar
     td.erp-card__more     el boton «Ver N datos mas» (lo añade app-list.js)
   y `data-erp-label` en cada celda con el texto de su cabecera. */

table.erp-cards-on {
    display: block;
    width: 100% !important;
    min-width: 0 !important;
    border: 0 !important;
    margin: 0 !important;
    background: transparent;
}

/* La cabecera no se ve, pero sigue ahi para el lector de pantalla. */
table.erp-cards-on > thead {
    display: block !important;
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
}

table.erp-cards-on > tfoot {
    display: none;
}

table.erp-cards-on > tbody {
    display: block;
    width: 100%;
}

table.erp-cards-on > tbody > tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    column-gap: 0;
    row-gap: 3px;
    align-items: start;
    position: relative;
    padding: 12px 14px;
    background: var(--erp-surface, #ffffff) !important;
    border-bottom: 1px solid var(--erp-border, #e3e8f0);
}

table.erp-cards-on > tbody > tr:last-child {
    border-bottom: 0;
}

table.erp-cards-on > tbody > tr > td,
table.erp-cards-on.table > tbody > tr > td,
table.erp-cards-on.dataTable > tbody > tr > td {
    display: flex;
    align-items: baseline;
    gap: 10px;
    grid-column: 1 / -1;
    min-width: 0;
    width: auto !important;
    max-width: none !important;
    padding: 1px 0 !important;
    border: 0 !important;
    background: transparent !important;
    text-align: left !important;
    white-space: normal !important;
    overflow-wrap: anywhere;
    font-size: 14px;
    line-height: 1.45;
    color: var(--erp-ink, #0f1723);
}

/* La etiqueta de la columna, delante del dato. */
table.erp-cards-on > tbody > tr > td[data-erp-label]::before {
    content: attr(data-erp-label);
    flex: 0 0 38%;
    max-width: 150px;
    color: var(--erp-ink-muted, #5b6577);
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.45;
}

/* Lo que va dentro de la celda ocupa el resto, y puede partirse. */
table.erp-cards-on > tbody > tr > td > * {
    min-width: 0;
    max-width: 100%;
}

table.erp-cards-on > tbody > tr > td.erp-card__check {
    grid-column: 1;
    grid-row: 1;
    padding: 2px 10px 0 0 !important;
    align-self: start;
}

table.erp-cards-on > tbody > tr > td.erp-card__title {
    grid-column: 2;
    grid-row: 1;
    display: block;
    padding-right: 8px !important;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.35;
}

table.erp-cards-on > tbody > tr > td.erp-card__title::before,
table.erp-cards-on > tbody > tr > td.erp-card__status::before,
table.erp-cards-on > tbody > tr > td.erp-card__actions::before,
table.erp-cards-on > tbody > tr > td.erp-card__check::before,
table.erp-cards-on > tbody > tr > td.erp-card__more::before {
    content: none !important;
}

/* Lo secundario que ya traia la celda principal (el responsable bajo el
   nombre de una tarea, las acciones al pasar el raton) se lee como linea de
   apoyo. */
table.erp-cards-on > tbody > tr > td.erp-card__title small,
table.erp-cards-on > tbody > tr > td.erp-card__title .text-muted {
    font-size: 13px;
    font-weight: 400;
}

table.erp-cards-on > tbody > tr > td.erp-card__title .row-options {
    display: block;
    margin-top: 4px;
    font-size: 13px;
    font-weight: 400;
    opacity: 1 !important;
    visibility: visible !important;
}

/* Sin columna principal reconocible, la primera ocupa todo el ancho. */
table.erp-cards-on > tbody > tr:not(.erp-card--has-actions) > td.erp-card__title {
    grid-column: 1 / -1;
}

table.erp-cards-on > tbody > tr:not(.erp-card--has-check) > td.erp-card__title {
    grid-column-start: 1;
}

table.erp-cards-on > tbody > tr > td.erp-card__actions {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
    align-items: center;
}

/* Botones de la fila con zona tactil de 44 px (WCAG 2.5.5). */
table.erp-cards-on > tbody > tr > td.erp-card__actions .btn,
table.erp-cards-on > tbody > tr > td.erp-card__actions .erp-rowmenu__toggle {
    min-width: 40px;
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

table.erp-cards-on > tbody > tr > td.erp-card__status {
    grid-row: 2;
    padding-top: 2px !important;
}

table.erp-cards-on > tbody > tr > td.erp-card__blank,
table.erp-cards-on > tbody > tr > td.erp-card__extra {
    display: none !important;
}

table.erp-cards-on > tbody > tr.erp-card--open > td.erp-card__extra {
    display: flex !important;
}

table.erp-cards-on > tbody > tr.erp-card--open > td.erp-card__extra.erp-card__blank {
    display: none !important;
}

table.erp-cards-on > tbody > tr > td.erp-card__more {
    order: 99;
    padding-top: 4px !important;
}

.erp-card-more {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    padding: 4px 0;
    border: 0;
    background: none;
    color: var(--erp-link, var(--erp-accent-text, #1d4ed8));
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.erp-card-more i {
    font-size: 11px;
    transition: transform .15s ease;
}

tr.erp-card--open .erp-card-more i {
    transform: rotate(180deg);
}

/* La fila «no hay datos» y el esqueleto no son tarjetas. */
table.erp-cards-on > tbody > tr > td.dataTables_empty,
table.erp-cards-on > tbody > tr.erp-skel-row > td {
    display: block;
    grid-column: 1 / -1;
}

table.erp-cards-on > tbody > tr > td.dataTables_empty::before {
    content: none !important;
}

/* Los controles del listado alrededor de la tabla: uno debajo de otro y a
   todo el ancho, en lugar de dos columnas de Bootstrap apretadas. La clase
   va en el propio `.dataTables_wrapper`. */
div.dataTables_wrapper.erp-cards-wrap div.dataTables_length,
div.dataTables_wrapper.erp-cards-wrap div.dataTables_filter,
div.dataTables_wrapper.erp-cards-wrap div.dataTables_info,
div.dataTables_wrapper.erp-cards-wrap div.dataTables_paginate {
    float: none;
    text-align: left;
    width: 100%;
    max-width: 100%;
}

div.dataTables_wrapper.erp-cards-wrap div.dataTables_filter label {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    margin: 0;
}

div.dataTables_wrapper.erp-cards-wrap div.dataTables_filter input {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    margin-left: 0;
}

div.dataTables_wrapper.erp-cards-wrap div.dataTables_paginate ul.pagination {
    display: flex;
    flex-wrap: wrap;
    white-space: normal;
}

div.dataTables_wrapper.erp-cards-wrap > .row {
    margin-left: 0;
    margin-right: 0;
}

div.dataTables_wrapper.erp-cards-wrap > .row > [class*="col-"] {
    padding-left: 0;
    padding-right: 0;
}

/* La caja que el tema pone para el desplazamiento horizontal ya no hace
   falta: la tarjeta cabe. */
.table-responsive.erp-cards-wrap,
.erp-cards-wrap > .table-responsive {
    overflow-x: visible;
    border: 0;
}

/* ===================================== 2. TABLAS QUE NO CABEN: SCROLL ===== */

/* Una tabla que no es un listado -una matriz, un cuadro de cifras- y no cabe
   en el movil se desplaza DENTRO de su caja, no arrastra la pagina entera.
   La clase la pone app-list.js solo cuando de verdad se sale (`scrollWidth`
   mayor que el ancho disponible). */
table.erp-table-scroll {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

/* El <select> de verdad de un bootstrap-select va escondido DENTRO del
   desplegable (posicion absoluta, a la mitad de su ancho): con un `min-width`
   propio de la pantalla (el filtro de Documentos del portal pide 220 px) se
   sale por la derecha y ensancha la pagina sin verse. No se ve, asi que no
   necesita ancho. */
.bootstrap-select > select {
    min-width: 0 !important;
    max-width: 100% !important;
}

/* Lo mismo para cualquier caja que una pantalla marque como ancha. */
.erp-hscroll {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

/* ============================================ 3. MENU DE ACCIONES (⋯) ===== */

/* Una fila con varios botones y uno de ellos de borrar: la accion principal
   se queda a la vista y el resto -con «Eliminar» el ultimo, en rojo y
   separado- va al menu «⋯». El peligro deja de ser lo mas llamativo de la
   tabla y de estar a un clic. app-list.js mueve los MISMOS elementos al menu
   (no copias), asi que sus manejadores, su `href` con el token de accion y el
   dialogo de confirmacion siguen funcionando igual. */
.erp-rowmenu {
    position: relative;
    display: inline-block;
    vertical-align: middle;
}

.erp-rowactions {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}

.erp-rowmenu__toggle.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    align-self: stretch;
    padding-left: 8px;
    padding-right: 8px;
    line-height: 1;
}

.erp-rowactions > .btn,
.erp-rowactions > .erp-rowmenu {
    align-self: stretch;
}

.erp-rowactions > .erp-rowmenu {
    display: inline-flex;
}

.erp-rowmenu__menu.dropdown-menu {
    min-width: 190px;
    padding: 6px 0;
    margin: 0;
    z-index: 1060;
    border-radius: var(--erp-radius-sm, 8px);
}

/* Fijado a la ventana mientras esta abierto: dentro de `.table-responsive`
   (overflow-x: auto) un menu absoluto se recortaria por el borde de la caja. */
.erp-rowmenu__menu.is-fixed {
    position: fixed;
    right: auto;
    bottom: auto;
}

.erp-rowmenu__menu > li > a,
.erp-rowmenu__menu > li > button,
.erp-rowmenu__menu > li > form > button,
.erp-rowmenu__menu > li > form > a,
.erp-rowmenu__menu > li > .btn {
    display: flex !important;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 36px;
    margin: 0 !important;
    padding: 7px 14px !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: none !important;
    box-shadow: none !important;
    color: var(--erp-ink, #0f1723) !important;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.35;
    text-align: left;
    text-decoration: none;
    white-space: nowrap;
}

.erp-rowmenu__menu > li > form {
    margin: 0;
}

.erp-rowmenu__menu > li > a:hover,
.erp-rowmenu__menu > li > a:focus,
.erp-rowmenu__menu > li > button:hover,
.erp-rowmenu__menu > li > button:focus,
.erp-rowmenu__menu > li > form > button:hover,
.erp-rowmenu__menu > li > form > button:focus,
.erp-rowmenu__menu > li > .btn:hover,
.erp-rowmenu__menu > li > .btn:focus {
    background: var(--erp-surface-3, #eef2f6) !important;
}

.erp-rowmenu__menu > li > * > i,
.erp-rowmenu__menu > li > form > * > i {
    width: 16px;
    text-align: center;
    color: var(--erp-ink-muted, #5b6577);
}

/* El borrado: texto rojo en el menu, nunca boton macizo (el rojo macizo queda
   para el boton del dialogo de confirmacion). */
.erp-rowmenu__menu > li.erp-rowmenu__danger > a,
.erp-rowmenu__menu > li.erp-rowmenu__danger > button,
.erp-rowmenu__menu > li.erp-rowmenu__danger > form > button,
.erp-rowmenu__menu > li.erp-rowmenu__danger > .btn,
.erp-rowmenu__menu > li.erp-rowmenu__danger > * > i,
.erp-rowmenu__menu > li.erp-rowmenu__danger > form > * > i {
    color: var(--erp-danger, #b91c1c) !important;
}

.erp-rowmenu__menu > li.erp-rowmenu__danger > a:hover,
.erp-rowmenu__menu > li.erp-rowmenu__danger > a:focus,
.erp-rowmenu__menu > li.erp-rowmenu__danger > button:hover,
.erp-rowmenu__menu > li.erp-rowmenu__danger > button:focus,
.erp-rowmenu__menu > li.erp-rowmenu__danger > form > button:hover,
.erp-rowmenu__menu > li.erp-rowmenu__danger > .btn:hover {
    background: var(--erp-danger-bg, #fdeaea) !important;
}

.erp-rowmenu__menu > li.divider {
    margin: 5px 0;
}

/* ======================================================= 4. CARGANDO ====== */

/* Mientras un listado pide datos: la primera vez, filas de esqueleto con la
   forma de la tabla (el tema escondia la tabla entera y pintaba una imagen);
   las siguientes -ordenar, paginar, buscar- las filas que ya hay se atenuan y
   una barra corre bajo la cabecera. El «Procesando...» sigue ahi para el
   lector de pantalla (`role="status"`), pero no tapa la tabla. */
.dataTables_wrapper.table-loading {
    background-image: none !important;
}

.dataTables_wrapper.table-loading table thead th {
    opacity: 1 !important;
}

.dataTables_wrapper.table-loading table thead tr {
    height: auto !important;
    min-height: 0 !important;
}

.dataTables_wrapper.table-loading table tbody tr.erp-skel-row,
.dataTables_wrapper table tbody tr.erp-skel-row {
    opacity: 1 !important;
}

tr.erp-skel-row > td {
    padding-top: 13px !important;
    padding-bottom: 13px !important;
    border-color: var(--erp-border-soft, #edf1f6) !important;
    background: transparent !important;
}

.erp-skel {
    display: block;
    height: 11px;
    max-width: 100%;
    border-radius: 6px;
    background: var(--erp-surface-3, #eef2f6);
    animation: erp-skel-pulse 1.4s ease-in-out infinite;
}

.erp-skel + .erp-skel {
    margin-top: 7px;
    height: 9px;
}

@keyframes erp-skel-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: .45; }
}

div.dataTables_wrapper div.dataTables_processing.erp-processing {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    border: 0 !important;
    box-shadow: none !important;
}

table.erp-dt-busy > tbody {
    opacity: .55;
    transition: opacity .15s ease;
}

table.erp-dt-busy > thead > tr:last-child > th {
    background-image: linear-gradient(90deg, transparent 0%, var(--erp-accent, #2563eb) 50%, transparent 100%);
    background-size: 40% 2px;
    background-repeat: no-repeat;
    background-position: -40% 100%;
    animation: erp-busy-bar 1.1s linear infinite;
}

@keyframes erp-busy-bar {
    from { background-position: -40% 100%; }
    to   { background-position: 140% 100%; }
}

/* ============================================================ 5. VACIOS ==== */

/* «No hay registros» no le dice a nadie que hacer. El estado vacio dice que
   es, por que esta vacio y como llenarlo, con el mismo boton de alta de la
   pantalla; si es una busqueda sin resultados, ofrece limpiarla. Componente
   unico (`.erp-empty`): lo pinta app-list.js dentro de la celda vacia de
   DataTables, y cualquier vista lo puede escribir a mano. */
.erp-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    max-width: 460px;
    margin: 0 auto;
    padding: 30px 12px 28px;
    text-align: center;
    white-space: normal;
}

.erp-empty__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-bottom: 4px;
    border-radius: 999px;
    background: var(--erp-a-14, #e8effd);
    color: var(--erp-accent-text, #1d4ed8);
    font-size: 18px;
}

.erp-empty__title {
    margin: 0;
    font-size: 15px;
    font-weight: 650;
    line-height: 1.35;
    color: var(--erp-ink, #0f1723);
}

.erp-empty__text {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--erp-ink-muted, #5b6577);
}

.erp-empty__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin-top: 10px;
}

/* La celda que lo contiene, sin el relleno de la capa moderna: ya lo trae el
   componente. */
td.dataTables_empty.erp-empty-cell,
table.dataTable td.dataTables_empty.erp-empty-cell {
    padding: 0 !important;
    text-align: center !important;
}

/* El tema esconde el pie (paginacion e informacion) de una tabla vacia: bien,
   pero sin dejar la cabecera a medio gas. */
.app_dt_empty table thead {
    opacity: 1 !important;
}

/* =================================================== 6. BARRA DE GUARDADO == */

/* Aparece cuando hay cambios sin guardar en un formulario largo (fichas por
   pestañas y Ajustes): «2 cambios sin guardar», Descartar y Guardar cambios,
   con ⌘S / Ctrl+S. Pegada al pie del formulario mientras se desplaza
   (`sticky`), asi queda alineada con su panel sin calcular el ancho del menu;
   si algun antecesor recorta (overflow), pasa a fija sobre la ventana
   (`.erp-savebar--fixed`, con su izquierda y su ancho medidos). */
.erp-savebar {
    position: sticky;
    bottom: 0;
    z-index: 1030;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 14px;
    margin: 16px calc(-1 * var(--erp-savebar-bleed, 0px)) 0;
    padding: 10px 16px;
    padding-bottom: max(10px, env(safe-area-inset-bottom));
    background: var(--erp-surface, #ffffff);
    border: 1px solid var(--erp-border, #e3e8f0);
    border-radius: var(--erp-radius-sm, 10px);
    box-shadow: 0 -2px 6px rgba(15, 23, 42, .06), 0 12px 32px -8px rgba(15, 23, 42, .28);
    color: var(--erp-ink, #0f1723);
}

.erp-savebar[hidden] {
    display: none !important;
}

.erp-savebar--fixed {
    position: fixed;
    bottom: 12px;
    margin: 0;
}

.erp-savebar__state {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--erp-warn, #92400e);
}

.erp-savebar__state::before {
    content: "";
    flex: 0 0 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
}

.erp-savebar.is-saving .erp-savebar__state {
    color: var(--erp-ink-muted, #5b6577);
}

.erp-savebar__actions {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}

.erp-savebar__actions .btn {
    min-height: 36px;
    font-weight: 600;
}

.erp-savebar__kbd {
    display: inline-block;
    margin-left: 8px;
    padding: 0 5px;
    border-radius: 4px;
    background: rgba(255, 255, 255, .2);
    font-size: 11px;
    font-weight: 600;
    line-height: 17px;
    letter-spacing: .02em;
}

/* En el movil: a todo el ancho, pegada al borde, con botones de 44 px. El
   boton de Bastino sube para no taparla. */
@media (max-width: 767px) {
    .erp-savebar,
    .erp-savebar--fixed {
        margin-left: 0;
        margin-right: 0;
        bottom: 0;
        border-radius: 14px 14px 0 0;
        border-bottom: 0;
        border-left: 0;
        border-right: 0;
    }

    .erp-savebar__state {
        flex-basis: 100%;
    }

    .erp-savebar__actions {
        flex: 1 1 100%;
        margin-left: 0;
    }

    .erp-savebar__actions .btn {
        flex: 1 1 0;
        min-height: 44px;
    }

    .erp-savebar__kbd {
        display: none;
    }

    html.erp-savebar-open .bst-fab {
        bottom: 128px !important;
    }
}

html.erp-savebar-open .bst-fab {
    bottom: 84px;
}

@media (prefers-reduced-motion: reduce) {
    .erp-skel,
    table.erp-dt-busy > thead > tr:last-child > th,
    .erp-card-more i {
        animation: none !important;
        transition: none !important;
    }
}

/* ================================= 7. FAMILIA DE ETIQUETAS (ESTADOS) ====== */

/* Cada modulo se habia hecho sus pastillas de estado (`.ce-tag-ok`,
   `.wh-chip--in`, `.cx-pill--connected`, `.au-pill--done`...) con sus
   propios verdes y rojos, unos a 3:1 y otros a 6:1, y ninguno con modo
   oscuro. Aqui se pliegan a la familia de la tanda 1 -los tokens de estado,
   en tono suave y 4,5:1- por TONO, sin tocar el marcado de ninguna vista.
   `:root` delante sube la especificidad sobre la hoja del modulo, que se
   carga despues. La variante maciza de Apariencia tambien les llega. */

/* Bien / hecho / conectado. */
:root .ce-tag-ok, :root .ce-tag-accept, :root .ce-tag-desvirtuado, :root .ce-tag-sentencia_favorable,
:root .wh-chip--in,
:root .cx-pill--connected,
:root .au-pill--active, :root .au-pill--done, :root .au-node-badge--done,
:root .exp-chip-ok, :root .exp-tag-emerald, :root .dt-tag-emerald, :root .aia-tag-emerald {
    background-color: var(--erp-ok-bg, #e7f6ed) !important;
    color: var(--erp-ok, #166534) !important;
    border-color: transparent !important;
}

/* Atencion / en espera / pendiente. */
:root .ce-tag-warn, :root .ce-tag-review, :root .ce-tag-presunto,
:root .wh-chip--warn,
:root .cx-pill--pending, :root .cx-pill--new,
:root .au-pill--paused, :root .au-pill--waiting, :root .au-pill--queued, :root .au-pill--running,
:root .au-node-badge--waiting, :root .au-node-badge--warn,
:root .exp-chip-warn, :root .exp-tag-amber, :root .dt-tag-amber, :root .aia-tag-amber {
    background-color: var(--erp-warn-bg, #fdf1dd) !important;
    color: var(--erp-warn, #92400e) !important;
    border-color: transparent !important;
}

/* Mal / error / rechazado. */
:root .ce-tag-bad, :root .ce-tag-reject, :root .ce-tag-definitivo,
:root .wh-chip--out,
:root .cx-pill--error, :root .cx-pill--expired,
:root .au-pill--error, :root .au-pill--failed, :root .au-node-badge--error,
:root .exp-chip-bad, :root .exp-tag-rose, :root .dt-tag-rose, :root .aia-tag-rose {
    background-color: var(--erp-danger-bg, #fdeaea) !important;
    color: var(--erp-danger, #b91c1c) !important;
    border-color: transparent !important;
}

/* Informativo. */
:root .ce-tag-info,
:root .wh-chip--info,
:root .exp-tag-sky, :root .dt-tag-sky, :root .aia-tag-sky {
    background-color: var(--erp-info-bg, #e8effd) !important;
    color: var(--erp-info, #1d4ed8) !important;
    border-color: transparent !important;
}

/* Neutro / desactivado / omitido. */
:root .wh-chip--neutral,
:root .cx-pill--disabled,
:root .au-node-badge--skipped,
:root .exp-tag-stone, :root .dt-tag-stone, :root .aia-tag-stone {
    background-color: var(--erp-surface-3, #eef2f6) !important;
    color: var(--erp-ink-soft, #334155) !important;
    border-color: transparent !important;
}

/* Macizas (Apariencia → Etiquetas de estado). */
:root[data-erp-badges="solid"] .ce-tag-ok, :root[data-erp-badges="solid"] .ce-tag-accept,
:root[data-erp-badges="solid"] .wh-chip--in, :root[data-erp-badges="solid"] .cx-pill--connected,
:root[data-erp-badges="solid"] .au-pill--active, :root[data-erp-badges="solid"] .au-pill--done,
:root[data-erp-badges="solid"] .exp-chip-ok, :root[data-erp-badges="solid"] .exp-tag-emerald,
:root[data-erp-badges="solid"] .dt-tag-emerald, :root[data-erp-badges="solid"] .aia-tag-emerald {
    background-color: #15803d !important;
    color: #ffffff !important;
}

:root[data-erp-badges="solid"] .ce-tag-warn, :root[data-erp-badges="solid"] .ce-tag-review,
:root[data-erp-badges="solid"] .wh-chip--warn, :root[data-erp-badges="solid"] .cx-pill--pending,
:root[data-erp-badges="solid"] .au-pill--paused, :root[data-erp-badges="solid"] .au-pill--waiting,
:root[data-erp-badges="solid"] .exp-chip-warn, :root[data-erp-badges="solid"] .exp-tag-amber,
:root[data-erp-badges="solid"] .dt-tag-amber, :root[data-erp-badges="solid"] .aia-tag-amber {
    background-color: #b45309 !important;
    color: #ffffff !important;
}

:root[data-erp-badges="solid"] .ce-tag-bad, :root[data-erp-badges="solid"] .ce-tag-reject,
:root[data-erp-badges="solid"] .wh-chip--out, :root[data-erp-badges="solid"] .cx-pill--error,
:root[data-erp-badges="solid"] .au-pill--error, :root[data-erp-badges="solid"] .au-pill--failed,
:root[data-erp-badges="solid"] .exp-chip-bad, :root[data-erp-badges="solid"] .exp-tag-rose,
:root[data-erp-badges="solid"] .dt-tag-rose, :root[data-erp-badges="solid"] .aia-tag-rose {
    background-color: #b91c1c !important;
    color: #ffffff !important;
}

/* La clase de la familia, para lo que se escriba nuevo: `.erp-badge` con
   `--ok`, `--warn`, `--danger`, `--info` o `--neutral`. */
.erp-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    background-color: var(--erp-surface-3, #eef2f6);
    color: var(--erp-ink-soft, #334155);
}

.erp-badge--ok      { background-color: var(--erp-ok-bg, #e7f6ed);     color: var(--erp-ok, #166534); }
.erp-badge--warn    { background-color: var(--erp-warn-bg, #fdf1dd);   color: var(--erp-warn, #92400e); }
.erp-badge--danger  { background-color: var(--erp-danger-bg, #fdeaea); color: var(--erp-danger, #b91c1c); }
.erp-badge--info    { background-color: var(--erp-info-bg, #e8effd);   color: var(--erp-info, #1d4ed8); }

:root[data-erp-badges="solid"] .erp-badge--ok     { background-color: #15803d; color: #ffffff; }
:root[data-erp-badges="solid"] .erp-badge--warn   { background-color: #b45309; color: #ffffff; }
:root[data-erp-badges="solid"] .erp-badge--danger { background-color: #b91c1c; color: #ffffff; }
:root[data-erp-badges="solid"] .erp-badge--info   { background-color: #1d4ed8; color: #ffffff; }

/* ======================= 8. PANTALLAS QUE DESBORDABAN EL MOVIL ============ */

/* Lo que no es una tabla y se salia de la pantalla por su cuenta. Cada regla
   dice de que pantalla es. Ninguna recorta contenido: o se parte en lineas, o
   se desplaza dentro de su propia caja. */
@media (max-width: 767px) {
    /* Filas flexibles de las vistas (los botones de cabecera de Tramites, el
       buscador del Kanban, la fila de un elemento del centro de mando): se
       parten en varias lineas en lugar de empujar la pagina, y cada pieza
       puede encogerse por debajo de su contenido -de serie un elemento flex
       no baja de su ancho minimo, y un texto con `tw-truncate` no llega a
       recortarse nunca-. Lo que diga `tw-flex-nowrap` se respeta. */
    .content .tw-flex:not(.tw-flex-nowrap):not(.tw-flex-col):not(.tw-overflow-x-auto):not(.tw-overflow-auto),
    ._buttons {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .content .tw-flex > *,
    .content .tw-inline-flex > * {
        min-width: 0;
    }

    /* Un bloque dentro de una columna flexible tampoco puede ensancharla. */
    .content .tw-flex-col > * {
        max-width: 100%;
    }

    /* Un grupo de botones (los filtros segmentados) no puede ser mas ancho que
       la pantalla. */
    .btn-group:not(.bootstrap-select):not(.dropdown) {
        flex-wrap: wrap;
        max-width: 100%;
    }

    /* Bloques <pre> y de codigo (API, tareas programadas, copias): se
       desplazan dentro. */
    .content pre,
    .content code.erp-block,
    .content .well pre {
        max-width: 100%;
        overflow-x: auto;
        white-space: pre;
    }

    .content code {
        overflow-wrap: anywhere;
        word-break: break-word;
    }

    /* Una celda de Bootstrap no puede ensanchar su fila. */
    .content [class*="col-"] {
        min-width: 0;
    }

    /* Imagenes y graficas dentro del contenido. */
    .content img,
    .content canvas,
    .content svg:not(.fa):not([class*="fa-"]) {
        max-width: 100%;
    }

    .content canvas {
        height: auto;
    }

    /* Los tableros Kanban (leads, tareas): las columnas no se apilan, se
       desplazan a lo ancho dentro de su caja y se detienen columna a columna
       (`scroll-snap`). Cada columna mide algo menos que la pantalla, asi que
       siempre asoma la siguiente: se ve que hay mas. */
    .leads-kanban,
    .task-kanban {
        scroll-snap-type: x mandatory;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        scroll-padding-left: 2px;
    }

    .leads-kanban > .leads-kanban-col,
    .task-kanban > .task-kanban-col {
        flex: 0 0 min(280px, 82vw);
        min-width: min(280px, 82vw);
        max-width: min(280px, 82vw);
        scroll-snap-align: start;
    }

    /* Un boton con un texto largo («Ver los 12 documentos que faltan») se
       parte en dos lineas en lugar de salirse. El de bootstrap-select no: el
       suyo ya se recorta con puntos suspensivos. */
    .content .btn:not(.btn-icon):not(.dropdown-toggle) {
        white-space: normal;
        max-width: 100%;
        height: auto;
    }

    /* Las acciones de un requisito de expediente (y las de una plantilla, una
       regla o un tipo de documento): se parten en lineas dentro del
       requisito. */
    .exp-item-actions {
        flex-wrap: wrap;
        max-width: 100%;
    }

    /* Pestañas horizontales de una ficha: desplazamiento propio en una sola
       linea (la tanda 3 las agrupa). */
    .content .nav-tabs:not(.nav-stacked) {
        max-width: 100%;
    }
}

/* En una pantalla tactil no hay «pasar el raton»: las acciones que solo
   aparecian al pasarlo (requisitos de expediente) se ven siempre. */
@media (hover: none) {
    .exp-item-actions {
        opacity: 1 !important;
    }
}

/* ======================================================================
 | FILTROS COMO CHIPS (2.3.5, app-filters.js)
 |
 | El bloque de filtros de la vista se queda en el DOM, escondido, guardando
 | los campos; la fila de chips va en su sitio. Cada `var()` lleva respaldo:
 | esta hoja se carga también con la capa clásica, donde los tokens no existen.
 * ====================================================================== */
.erp-chips-src {
    display: none !important;
}

.erp-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 14px;
}

.erp-chips__list {
    display: flex;
    flex: 1 1 auto;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.erp-chips__search {
    flex: 1 1 220px;
    max-width: 340px;
    min-width: 160px;
}

.erp-chips__search .form-control {
    width: 100%;
}

.erp-chip {
    display: inline-flex;
    align-items: stretch;
    max-width: 100%;
    height: 32px;
    border: 1px dashed var(--erp-border-strong, #c7cfdb);
    border-radius: 999px;
    background: transparent;
    color: var(--erp-ink, #0f1723);
    font-size: 13px;
    transition: background-color .12s, border-color .12s;
}

.erp-chip.is-active {
    border-style: solid;
    border-color: var(--erp-accent, #2563eb);
    background: var(--erp-accent-soft, rgba(37, 99, 235, .08));
    color: var(--erp-accent-text, #1d4ed8);
}

.erp-chip__btn,
.erp-chip__x {
    display: inline-flex;
    align-items: center;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    line-height: 1;
    cursor: pointer;
}

.erp-chip__btn {
    gap: 6px;
    min-width: 0;
    padding: 0 12px;
    border-radius: 999px;
    white-space: nowrap;
}

.erp-chip__btn > .fa-plus {
    font-size: 11px;
    color: var(--erp-ink-muted, #5b6577);
}

.erp-chip:not(.is-active):hover {
    background: var(--erp-surface-3, #eef2f8);
}

.erp-chip.is-active .erp-chip__btn {
    padding-right: 4px;
}

.erp-chip__key {
    font-weight: 500;
}

.erp-chip__val {
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 600;
}

.erp-chip__x {
    justify-content: center;
    width: 26px;
    margin-right: 3px;
    border-radius: 999px;
    font-size: 12px;
}

.erp-chip__x[hidden] {
    display: none;
}

.erp-chip:not(.is-active) .erp-chip__x {
    display: none;
}

.erp-chip.is-active:not(:has(.erp-chip__x:not([hidden]))) .erp-chip__btn {
    padding-right: 12px;
}

.erp-chip__x:hover {
    background: var(--erp-accent-soft, rgba(37, 99, 235, .14));
}

.erp-chip__btn:focus-visible,
.erp-chip__x:focus-visible,
.erp-chips__clear:focus-visible {
    outline: 2px solid var(--erp-accent, #2563eb);
    outline-offset: 2px;
}

.erp-chips__clear {
    border: 0;
    background: none;
    padding: 4px 6px;
    color: var(--erp-link, var(--erp-accent-text, #1d4ed8));
    font-size: 13px;
    font-weight: 500;
}

.erp-chips__clear[hidden] {
    display: none;
}

.erp-chips__clear:hover {
    text-decoration: underline;
}

/* El panel de un chip: el campo de la vista, prestado. */
.erp-chip-panel {
    position: absolute;
    z-index: 1060;
    padding: 12px;
    border: 1px solid var(--erp-border, #e3e8f0);
    border-radius: 10px;
    background: var(--erp-surface, #fff);
    box-shadow: 0 12px 32px rgba(15, 23, 42, .16);
}

.erp-chip-panel__body > * {
    margin: 0 !important;
    width: 100%;
}

.erp-chip-panel__body .form-control,
.erp-chip-panel__body .bootstrap-select {
    width: 100% !important;
}

.erp-chip-panel__body label {
    display: block;
    margin-bottom: 6px;
}

.erp-chip-panel__foot {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 12px;
}

/* En el móvil, una sola fila que se desliza de lado: los filtros no se comen
   la primera pantalla. La búsqueda va en su propia línea, arriba. */
@media (max-width: 767px) {
    .erp-chips__search {
        flex: 1 0 100%;
        max-width: none;
    }

    .erp-chips__list {
        flex: 1 0 100%;
        flex-wrap: nowrap;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding-bottom: 2px;
    }

    .erp-chips__list::-webkit-scrollbar {
        display: none;
    }

    .erp-chip {
        flex: 0 0 auto;
        height: 36px;
    }

    .erp-chips__clear {
        flex: 0 0 auto;
        white-space: nowrap;
    }
}

/* Un enlace que estaba en el bloque de filtros («Configurar columnas»): al
   final de la fila, discreto. */
.erp-chips__link {
    margin-left: auto;
}
