/*
 * Marcos comunes de CRATOS: una sola escala de espacio, radio, borde y tipografía de
 * estructura para todas las vistas. Se carga después del tema (app.min.css) y de los css
 * propios, y solo toca marcos: márgenes, paddings, radios, bordes, alturas y tamaños de los
 * textos de estructura. No cambia la paleta ni la fuente ni los iconos.
 *
 * Fuentes de la norma: el mockup de la plataforma (erp-gubernamental.iademo.com: página con
 * 24 px de margen, secciones a 24 px, tarjetas con borde de 1 px y radio 12, título de página
 * 24 px, botón de 36 px con radio 8), la retícula de 8 puntos que comparten Material Design,
 * Carbon y Bootstrap (múltiplos de 4 y 8, espacio interno menor o igual que el externo) y la
 * regla de una sola acción primaria por vista.
 *
 * La raíz tipográfica pasa a 16 px en _HeadCSS para que las utilidades rem de Bootstrap caigan
 * en la retícula (mb-3 = 16, p-4 = 24, mb-4 = 24). El cuerpo sigue en 15 px.
 */

:root {
    /* Gris del texto secundario. El del tema (#9ba6b7) da 2,46 a 1 sobre blanco y no llega al 4,5
       que pide la norma AA para texto normal; este llega a 5,4 sobre blanco y 4,6 sobre el fondo de
       la página, sin salirse de la gama de grises del tema. En oscuro se mantiene el del tema, que
       ahí sí cumple (5,5 a 1). */
    --ux-texto-secundario: #5f6b7d;

    /* Una sola familia en toda la aplicación. El tema traía Nunito Sans y una monoespaciada
       (SFMono/Consolas) para códigos y montos: ambas se sustituyen por Roboto. Los números de las
       tablas mantienen la alineación en columna con cifras tabulares, sin necesidad de otra fuente. */
    --ux-fuente: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    /* Letra de datos: una sola familia para códigos, identificadores y cifras de las tablas, la
       misma en todos los módulos. Mantiene las columnas de números alineadas y distingue el dato
       del texto corrido sin traer una tercera familia. */
    --ux-fuente-datos: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
    --highdmin-font-sans-serif: var(--ux-fuente);
    --highdmin-font-monospace: var(--ux-fuente-datos);
    --ux-transicion: 160ms ease-out;
    --ux-espacio-1: 4px;
    --ux-espacio-2: 8px;
    --ux-espacio-3: 12px;
    --ux-espacio-4: 16px;
    --ux-espacio-5: 24px;
    --ux-espacio-6: 32px;
    --ux-radio-control: 8px;
    --ux-radio-tarjeta: 12px;
    --ux-borde-color: rgba(0, 0, 0, 0.1);
    --ux-borde: 1px solid var(--ux-borde-color);
    --ux-alto-control: 36px;
}

html[data-bs-theme="dark"] {
    --ux-borde-color: rgba(255, 255, 255, 0.12);
}

/* ---------- Página: un margen de 24 px, medido una sola vez ---------- */

.page-content {
    padding-left: 0;
    padding-right: 0;
    padding-top: var(--ux-espacio-5);
}

.page-content > .page-container,
.app-topbar .page-container.topbar-menu {
    padding-left: var(--ux-espacio-5);
    padding-right: var(--ux-espacio-5);
}

@media (max-width: 767.98px) {
    .page-content > .page-container,
    .app-topbar .page-container.topbar-menu {
        padding-left: var(--ux-espacio-4);
        padding-right: var(--ux-espacio-4);
    }
}

/* Muchas vistas envuelven su contenido en container-fluid: ese envoltorio no suma margen. */
.page-content > .page-container > .container-fluid,
.page-content > .page-container > .container {
    padding-left: 0;
    padding-right: 0;
    max-width: none;
}

/* ---------- Barra superior: el título de la vista cabe en una línea ---------- */

/* El título de la barra repite el de la página. Se deja como referencia de contexto, de menor
   peso, con ancho acotado y como mucho dos renglones (los títulos no se truncan con puntos
   suspensivos, según las guías de escritura de interfaz; se acota el ancho para que nunca se
   parta en cuatro renglones sobre los iconos de la barra). La miga de la barra se retira: la
   vista ya trae la suya. */
.app-topbar .topbar-item .page-title {
    font-size: 16px;
    font-weight: 500;
    line-height: 24px;
    margin: 0;
    max-width: clamp(200px, 32vw, 520px);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
}

.app-topbar .topbar-item .breadcrumb {
    display: none;
}

/* Por debajo de 1200 px la barra se llena de iconos y el título repetido ya no cabe entero: se retira,
   porque la cabecera de la página lo muestra completo un poco más abajo. */
@media (max-width: 1199.98px) {
    .app-topbar .topbar-item:has(.page-title) {
        display: none !important;
    }
}

/* ---------- Cabecera de página: título, subtítulo y una acción primaria a la derecha ---------- */

.page-content .page-title-box {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ux-espacio-4);
    margin: 0 0 var(--ux-espacio-5);
}

.page-content .page-title-box > * {
    min-width: 0;
}

.page-content .page-title-box .page-title,
.page-content .page-title-box h1,
.page-content .page-title-box h2,
.page-content .page-title-box h3,
.page-content .page-title-box h4 {
    font-size: 24px;
    font-weight: 500;
    line-height: 32px;
    margin: 0;
    /* El token de énfasis del tema es el color del cuerpo al 75 %, más claro que el texto normal:
       para el título de la página se usa el color pleno. */
    color: var(--highdmin-body-color);
    overflow-wrap: anywhere;
}

.page-content .page-title-box .page-subtitle,
.page-content .page-title-box .text-muted,
.page-content .page-title-box p {
    font-size: 14px;
    line-height: 20px;
    margin: var(--ux-espacio-1) 0 0;
    color: var(--ux-texto-secundario);
}

.page-content .page-title-box .breadcrumb {
    margin: 0 0 var(--ux-espacio-2);
    font-size: 13px;
}

.page-content .page-title-box .page-title-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--ux-espacio-2);
    margin-left: auto;
}

/* El tema pone la miga en .page-title-right, a la derecha del título. La norma la quiere encima del
   título y a la izquierda (patrón de cabecera de Atlassian y del mockup), así que ese bloque pasa a
   ser la primera fila de la caja sin tocar las 74 vistas que lo usan. Los botones van en
   .page-title-actions, no aquí. */
.page-content .page-title-box .page-title-right {
    order: -1;
    flex: 0 0 100%;
    margin: 0;
}

.page-content .page-title-box .page-title-right .breadcrumb {
    justify-content: flex-start;
}

@media (max-width: 767.98px) {
    .page-content .page-title-box .page-title,
    .page-content .page-title-box h1,
    .page-content .page-title-box h2,
    .page-content .page-title-box h3,
    .page-content .page-title-box h4 {
        font-size: 20px;
        line-height: 28px;
    }

    .page-content .page-title-box .page-title-actions,
    .page-content .page-title-box .page-title-right {
        width: 100%;
        margin-left: 0;
    }

    .page-content .page-title-box .page-title-actions .btn,
    .page-content .page-title-box .page-title-right .btn {
        flex: 1 1 auto;
    }
}

/* ---------- Tarjetas: borde de 1 px, radio 12, cuerpo de 24, sin sombra ---------- */

.page-content .card {
    --highdmin-card-border-width: 1px;
    --highdmin-card-border-color: var(--ux-borde-color);
    --highdmin-card-border-radius: var(--ux-radio-tarjeta);
    --highdmin-card-inner-border-radius: calc(var(--ux-radio-tarjeta) - 1px);
    --highdmin-card-spacer-y: var(--ux-espacio-5);
    --highdmin-card-spacer-x: var(--ux-espacio-5);
    --highdmin-card-cap-padding-y: var(--ux-espacio-4);
    --highdmin-card-cap-padding-x: var(--ux-espacio-5);
    --highdmin-card-group-margin: var(--ux-espacio-5);
    box-shadow: none;
}

/* En telefono todo va a un solo ritmo de 16 px: el margen de la pagina ya bajaba de 24 a 16, y
   ahora baja tambien el cuerpo de las tarjetas. Con dos tarjetas anidadas de 24 px, una tabla en
   modo tarjeta dentro de un formulario se quedaba con 214 px utiles de 375 y las cifras no cabian. */
@media (max-width: 767.98px) {
    .page-content .card {
        --highdmin-card-spacer-y: var(--ux-espacio-4);
        --highdmin-card-spacer-x: var(--ux-espacio-4);
        --highdmin-card-cap-padding-x: var(--ux-espacio-4);
    }

    /* Una fila de Bootstrap pone de margen negativo la mitad de su canal. Con g-4 son 18 px, mas
       que los 16 de relleno de la pagina o de una tarjeta, y la fila asomaba 2 px por cada lado y
       daba scroll lateral a la pagina (Detalle de Estudio Previo). En telefono el canal horizontal
       de las filas anchas se queda en 32 px: 16 de margen, justo el relleno. */
    .page-content .row.g-4,
    .page-content .row.gx-4,
    .page-content .row.g-5,
    .page-content .row.gx-5 {
        /* El tema compila Bootstrap con prefijo propio: la variable es --highdmin-gutter-x, y en
           este tema g-4 vale 2,25 rem. */
        --highdmin-gutter-x: calc(var(--ux-espacio-4) * 2);
    }

    /* Paginadores. El de _PaginationAlpine ponia el selector de tamaño y nueve botones en una
    fila sin salto, unos 420 px, y en siete listados asomaba por la derecha. El de Bootstrap
    (ul.pagination) tampoco saltaba de linea. En el telefono los dos se centran y pueden ir en
    dos lineas. */
    .pagination-container {
        justify-content: center;
        text-align: center;
    }

    .pagination-controls,
    .pagination-buttons,
    .page-content .pagination {
        flex-wrap: wrap;
        justify-content: center;
        row-gap: var(--ux-espacio-2);
    }

    .pagination-btn {
        min-width: 36px;
        padding-left: var(--ux-espacio-2);
        padding-right: var(--ux-espacio-2);
    }
}

/* Las utilidades de sombra que algunas vistas ponen en la tarjeta no rompen la norma. */
.page-content .card.shadow,
.page-content .card.shadow-sm,
.page-content .card.shadow-lg {
    box-shadow: none !important;
}

.page-content .card .card-header {
    border-bottom: var(--ux-borde);
    background-color: transparent;
}

.page-content .card .card-footer {
    border-top: var(--ux-borde);
    background-color: transparent;
    padding: var(--ux-espacio-4) var(--ux-espacio-5);
}

.page-content .card .card-title,
.page-content .card .header-title {
    font-size: 16px;
    font-weight: 500;
    line-height: 24px;
    margin-bottom: 0;
}

/* Solo el título que abre un cuerpo de tarjeta separa 16 px de lo que sigue; en la cabecera de la
   tarjeta el título convive con botones a la derecha y no debe empujarlos. */
.page-content .card .card-body > .card-title {
    margin-bottom: var(--ux-espacio-4);
}

.page-content .card .card-header:has(> .card-title, > .header-title) {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ux-espacio-2);
}

/* Las tarjetas de una misma fila del grid se separan 24 px entre sí y de la siguiente fila. */
.page-content .row > [class*="col-"] > .card:last-child {
    margin-bottom: var(--ux-espacio-5);
}

/* Filas de indicadores (KPI): 16 px entre tarjetas de la misma fila. */
.page-content .row.g-3 > [class*="col-"] > .card,
.page-content .row.kpi-row > [class*="col-"] > .card {
    margin-bottom: 0;
}

.page-content .row.kpi-row {
    /* El tema compila Bootstrap con prefijo propio: la variable es --highdmin-gutter-y. Con
       --bs-gutter-* esta regla no hacia nada, el canal vertical valia 0 y las tarjetas se tocaban
       en cuanto la fila pasaba a una segunda linea (en el telefono, siempre). El horizontal se
       deja el del tema para no mover el escritorio. */
    --highdmin-gutter-y: var(--ux-espacio-4);
    margin-bottom: var(--ux-espacio-5);
}

/* Todas las tarjetas de una fila de indicadores miden lo mismo de alto. Sin esto, la que tiene
   dos renglones de aclaración crece y las de al lado quedan cortas, y la fila se ve escalonada. */
.page-content .row.kpi-row > [class*="col-"] {
    display: flex;
}

.page-content .row.kpi-row > [class*="col-"] > .card {
    width: 100%;
}

/* kpi-cards.css fija el radio de .kpi-card en 0,5rem después del tema y le ganaba a la variable. */
.page-content .card.kpi-card {
    border-radius: var(--ux-radio-tarjeta);
}

.page-content .kpi-card:hover,
.page-content .card.kpi-card:hover {
    box-shadow: none !important;
}

/* ---------- Botones: 36 px, radio 8, 14 px con peso 500 ---------- */

.btn {
    --highdmin-btn-padding-y: 7px;
    --highdmin-btn-padding-x: 14px;
    --highdmin-btn-font-size: 14px;
    --highdmin-btn-font-weight: 500;
    --highdmin-btn-line-height: 20px;
    --highdmin-btn-border-radius: var(--ux-radio-control);
    font-size: 14px !important;
}

.btn-sm,
.btn-group-sm > .btn {
    --highdmin-btn-padding-y: 5px;
    --highdmin-btn-padding-x: 10px;
    --highdmin-btn-font-size: 13px;
    --highdmin-btn-line-height: 20px;
    --highdmin-btn-border-radius: 6px;
    font-size: 13px !important;
}

.btn-lg,
.btn-group-lg > .btn {
    --highdmin-btn-padding-y: 10px;
    --highdmin-btn-padding-x: 18px;
    --highdmin-btn-font-size: 15px;
    --highdmin-btn-line-height: 22px;
    font-size: 15px !important;
}

/* Botón de solo icono: cuadrado, del mismo alto que el resto. */
.btn.btn-icon {
    width: var(--ux-alto-control);
    height: var(--ux-alto-control);
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.btn.btn-icon.btn-sm {
    width: 32px;
    height: 32px;
}

/* ---------- Tablas: celdas de 12 x 16, cabecera de 13 px con peso 500 ---------- */

.page-content .table > :not(caption) > * > * {
    padding: var(--ux-espacio-3) var(--ux-espacio-4);
    vertical-align: middle;
}

.page-content .table-sm > :not(caption) > * > * {
    padding: var(--ux-espacio-2) var(--ux-espacio-3);
}

.page-content .table > thead > tr > th {
    font-size: 13px !important;
    font-weight: 500;
    line-height: 20px;
    color: var(--ux-texto-secundario);
    white-space: nowrap;
}

.page-content .card > .table-responsive,
.page-content .card > .table {
    margin-bottom: 0;
}

.page-content .card > .table-responsive > .table > :not(caption) > * > *:first-child,
.page-content .card > .table > :not(caption) > * > *:first-child {
    padding-left: var(--ux-espacio-5);
}

.page-content .card > .table-responsive > .table > :not(caption) > * > *:last-child,
.page-content .card > .table > :not(caption) > * > *:last-child {
    padding-right: var(--ux-espacio-5);
}

/* ---------- Formularios: etiqueta de 14 px, control de 40 px con radio 8 ---------- */

.form-label {
    font-size: 14px;
    font-weight: 500;
    line-height: 20px;
    margin-bottom: 6px;
}

.form-control,
.form-select {
    border-radius: var(--ux-radio-control);
    padding: 8px 12px;
    font-size: 14px !important;
    line-height: 22px;
}

.form-control-sm,
.form-select-sm {
    padding: 5px 10px;
    font-size: 13px !important;
    line-height: 20px;
    border-radius: 6px;
}

textarea.form-control {
    min-height: 96px;
}

.input-group > .form-control,
.input-group > .form-select,
.input-group-text {
    border-radius: var(--ux-radio-control);
}

.form-text,
.invalid-feedback,
.text-danger.field-validation-error,
span[data-valmsg-for] {
    font-size: 13px;
    line-height: 18px;
    display: block;
    margin-top: var(--ux-espacio-1);
}

/* Botonera de un formulario: Cancelar a la izquierda del primario, separados 8 px, a la derecha. */
.form-actions,
.page-content .modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: var(--ux-espacio-2);
    flex-wrap: wrap;
}

.form-actions {
    padding-top: var(--ux-espacio-4);
    border-top: var(--ux-borde);
    margin-top: var(--ux-espacio-5);
}

/* ---------- Modales, alertas y otros marcos ---------- */

.modal-content {
    border-radius: var(--ux-radio-tarjeta);
    border: var(--ux-borde);
}

.modal-header,
.modal-footer {
    padding: var(--ux-espacio-4) var(--ux-espacio-5);
}

.modal-body {
    padding: var(--ux-espacio-5);
}

.modal-title {
    font-size: 18px;
    font-weight: 500;
    line-height: 24px;
}

.alert {
    border-radius: var(--ux-radio-control);
    padding: var(--ux-espacio-3) var(--ux-espacio-4);
}

.badge {
    border-radius: 6px;
    font-weight: 500;
    padding: 4px 8px;
}

.nav-tabs .nav-link,
.nav-pills .nav-link {
    padding: var(--ux-espacio-2) var(--ux-espacio-4);
    font-weight: 500;
    font-size: 14px !important;
}

.dropdown-menu {
    border-radius: var(--ux-radio-control);
    border: var(--ux-borde);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
    padding: var(--ux-espacio-2);
}

.dropdown-item {
    border-radius: 6px;
    padding: var(--ux-espacio-2) var(--ux-espacio-3);
}

.pagination .page-link {
    min-width: var(--ux-alto-control);
    height: var(--ux-alto-control);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ux-radio-control);
}

/* ---------- Barra lateral: ítems de 14 px con peso 500, radio 8, 4 px entre ítems ---------- */

.sidenav-menu .side-nav-link {
    border-radius: var(--ux-radio-control);
    font-size: 14px !important;
    font-weight: 500;
    line-height: 20px;
    padding: 10px 12px;
}

.sidenav-menu .side-nav-item + .side-nav-item {
    margin-top: var(--ux-espacio-1);
}

.sidenav-menu .side-nav-link .menu-text {
    font-size: 14px !important;
    line-height: 20px;
}

.sidenav-menu .side-nav-second-level > li > a,
.sidenav-menu .side-nav-third-level > li > a {
    border-radius: 6px;
    font-size: 14px !important;
    line-height: 20px;
    padding: 8px 12px;
}

/* En el modo compacto con expansión al pasar el ratón, el texto vuelve al ancho completo. */
html[data-sidenav-size="sm-hover"] .sidenav-menu:hover .side-nav-link .menu-text {
    visibility: visible;
    white-space: normal;
}

/* ---------- Pie ---------- */

.footer {
    margin: var(--ux-espacio-5) var(--ux-espacio-5) var(--ux-espacio-5);
    border-radius: var(--ux-radio-tarjeta);
    border: var(--ux-borde);
    box-shadow: none;
    padding: var(--ux-espacio-4) var(--ux-espacio-5);
    font-size: 13px;
}

/* ---------- Utilidades de la escala para las vistas (en vez de estilos inline) ---------- */

.ux-seccion {
    margin-bottom: var(--ux-espacio-5);
}

.ux-fila-acciones {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--ux-espacio-2);
}

.ux-texto-corto {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ux-min-0 {
    min-width: 0;
}

/* Vista previa larga (importaciones): alto acotado con desplazamiento propio. */
.ux-desplazable {
    max-height: 400px;
    overflow-y: auto;
}

/* Contenedor de gráfico: reserva el alto antes de que la librería pinte, sin salto de maqueta. */
.ux-grafico {
    min-height: 320px;
}

/* Estado vacio de un panel que iba a llevar grafico. No hereda el alto de .ux-grafico: reservar
   320 px para un renglon se nota en escritorio y tapa media pantalla en un movil. */
.page-content .ux-vacio-corto {
    display: flex;
    align-items: center;
    gap: var(--ux-espacio-1);
    margin: 0;
    padding: var(--ux-espacio-3) 0;
    font-size: 14px;
    color: var(--ux-texto-secundario);
}

/* Movimiento: las animaciones decorativas se desactivan si el usuario lo pide. */
@media (prefers-reduced-motion: reduce) {
    .fade-in,
    .fade-in-delay-1,
    .fade-in-delay-2,
    .fade-in-delay-3,
    .fade-in-delay-4,
    .fade-in-delay-5 {
        animation: none;
    }

    .sidenav-menu,
    .app-topbar,
    .side-nav-link {
        transition: none;
    }
}


/* ---------- Tipografía: una sola familia en toda la aplicación ---------- */

body,
.minuta-editor,
.table,
.btn,
.form-control,
.form-select,
.badge,
.dropdown-item,
.modal,
.side-nav-link,
.page-title,
.card-title {
    font-family: var(--ux-fuente) !important;
}

/* Los datos de las tablas (códigos, identificadores y cifras) llevan la letra de datos, la misma en
   todos los módulos: las columnas de números quedan alineadas y el dato se distingue del texto. */
.font-monospace,
.text-monospace,
.ux-dato,
code,
kbd,
samp,
pre,
.page-content .table td.text-end,
.page-content .table th.text-end {
    font-family: var(--ux-fuente-datos) !important;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    font-size: 14px !important;
    letter-spacing: -0.01em;
}

/* El resto de la tabla, en la letra de la aplicación con cifras tabulares. */
.page-content .table td,
.page-content .table th {
    font-variant-numeric: tabular-nums;
}

/* ---------- Movimiento: un solo sistema para toda la aplicación ---------- */

@keyframes ux-entrada {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

/* Toda tarjeta del contenido entra igual, con un escalonado corto por posición en su fila: las
   tarjetas de Presupuesto no tenían ninguna animación y las de otros módulos sí (clases fade-in). */
.page-content .card {
    animation: ux-entrada 240ms ease-out both;
    transition: border-color var(--ux-transicion), transform var(--ux-transicion);
}

.page-content .row > [class*="col-"]:nth-child(2) > .card { animation-delay: 40ms; }
.page-content .row > [class*="col-"]:nth-child(3) > .card { animation-delay: 80ms; }
.page-content .row > [class*="col-"]:nth-child(4) > .card { animation-delay: 120ms; }
.page-content .row > [class*="col-"]:nth-child(5) > .card { animation-delay: 160ms; }
.page-content .row > [class*="col-"]:nth-child(n + 6) > .card { animation-delay: 200ms; }

/* Las clases de entrada que ya usaban algunas vistas se alinean con el mismo tiempo y curva. */
.page-content .fade-in { animation: ux-entrada 240ms ease-out both; }
.page-content .fade-in-delay-1 { animation-delay: 40ms; }
.page-content .fade-in-delay-2 { animation-delay: 80ms; }
.page-content .fade-in-delay-3 { animation-delay: 120ms; }
.page-content .fade-in-delay-4 { animation-delay: 160ms; }
.page-content .fade-in-delay-5 { animation-delay: 200ms; }

/* Elevación al pasar el ratón solo en las tarjetas que resumen un dato (indicadores). */
.page-content .row.kpi-row > [class*="col-"] > .card:hover,
.page-content .card.kpi-card:hover {
    transform: translateY(-2px);
    border-color: rgba(0, 0, 0, 0.18);
}

html[data-bs-theme="dark"] .page-content .row.kpi-row > [class*="col-"] > .card:hover,
html[data-bs-theme="dark"] .page-content .card.kpi-card:hover {
    border-color: rgba(255, 255, 255, 0.24);
}

.page-content .table tbody tr,
.page-content .btn,
.page-content .side-nav-link,
.page-content a {
    transition: background-color var(--ux-transicion), color var(--ux-transicion), border-color var(--ux-transicion);
}

@media (prefers-reduced-motion: reduce) {
    .page-content .card,
    .page-content .fade-in,
    .page-content [class*="fade-in-delay"] {
        animation: none;
    }

    .page-content .row.kpi-row > [class*="col-"] > .card:hover,
    .page-content .card.kpi-card:hover {
        transform: none;
    }
}

/* Texto secundario legible en toda la aplicación (el gris del tema no llega a AA en claro). */
.page-content .text-muted,
.page-content .form-text,
.page-content small.text-muted {
    color: var(--ux-texto-secundario) !important;
}

html[data-bs-theme="dark"] {
    /* En oscuro el gris del tema sí cumple; se mantiene para no perder jerarquía. */
    --ux-texto-secundario: #9ba6b7;
}


/* ---------- Tarjetas de indicador y tablas: un solo estilo en todos los módulos ---------- */

/* El valor de una tarjeta de indicador mide lo mismo en toda la aplicación. Convivían 17,5 px en
   planes y catálogos con 24 px en contratación, y el patrón de marcado es el mismo en todas:
   una etiqueta pequeña en gris y debajo el número. El color se respeta porque en varias vistas
   codifica el estado (pendiente, aprobado, rechazado), pero el tamaño y el peso se igualan. */
.page-content .card-body p.text-muted + h1,
.page-content .card-body p.text-muted + h2,
.page-content .card-body p.text-muted + h3,
.page-content .card-body p.text-muted + h4,
.page-content .card-body p.text-muted + h5,
.page-content .card-body p.fs-13 + h4,
.page-content .row.kpi-row .card h4,
.page-content .card.kpi-card h4 {
    font-size: 24px !important;
    font-weight: 500;
    line-height: 32px;
    margin-bottom: 0;
}

.page-content .card-body p.text-muted,
.page-content .card-body p.fs-13 {
    font-size: 13px !important;
    line-height: 18px;
}

/* Las tarjetas de indicador llevan el marco común aunque la vista traiga border-0 o mb-0. */
.page-content .row.kpi-row .card,
.page-content .card.kpi-card {
    border: var(--ux-borde) !important;
}

/* Las celdas de todas las tablas usan la misma letra: 15 px normal, y solo el identificador de la
   fila va en 500. Antes convivían columnas en 600 (contratación, presupuesto) con columnas en 400
   (planes, catálogos) para el mismo tipo de dato. El color se deja a la vista porque distingue
   ejecutado, disponible y saldos. */
.page-content .table tbody td {
    font-weight: 400 !important;
}

.page-content .table tbody td:first-child {
    font-weight: 500 !important;
}

.page-content .table tbody td .badge,
.page-content .table tbody td .btn {
    font-weight: 500 !important;
}


/* ---------- Botones de acción de una fila: el mismo aspecto en todas las tablas ---------- */

/* En unos módulos eran botones rellenos de color y en otros de contorno. La maqueta usa contorno,
   que además no compite con la acción primaria de la cabecera. Se iguala aquí para las sesenta
   tablas de la aplicación, sin tocar cada vista: dentro de una celda, un botón sólido se pinta de
   contorno conservando su color (editar en el color de marca, eliminar en rojo, ver en gris). */
.page-content .table tbody td .btn[class*="btn-soft-"],
.page-content .table tbody td .btn.btn-primary,
.page-content .table tbody td .btn.btn-secondary,
.page-content .table tbody td .btn.btn-success,
.page-content .table tbody td .btn.btn-danger,
.page-content .table tbody td .btn.btn-warning,
.page-content .table tbody td .btn.btn-info,
.page-content .table tbody td .btn.btn-dark {
    background-color: transparent !important;
    background-image: none !important;
    border-width: 1px !important;
    border-style: solid !important;
    box-shadow: none !important;
}

.page-content .table tbody td .btn.btn-primary,
.page-content .table tbody td .btn.btn-soft-primary { color: var(--highdmin-primary) !important; border-color: var(--highdmin-primary) !important; }
.page-content .table tbody td .btn.btn-secondary,
.page-content .table tbody td .btn.btn-soft-secondary { color: var(--highdmin-secondary) !important; border-color: var(--highdmin-secondary) !important; }
.page-content .table tbody td .btn.btn-success,
.page-content .table tbody td .btn.btn-soft-success { color: var(--highdmin-success) !important; border-color: var(--highdmin-success) !important; }
.page-content .table tbody td .btn.btn-danger,
.page-content .table tbody td .btn.btn-soft-danger { color: var(--highdmin-danger) !important; border-color: var(--highdmin-danger) !important; }
.page-content .table tbody td .btn.btn-warning,
.page-content .table tbody td .btn.btn-soft-warning { color: var(--highdmin-warning) !important; border-color: var(--highdmin-warning) !important; }
.page-content .table tbody td .btn.btn-info,
.page-content .table tbody td .btn.btn-soft-info { color: var(--highdmin-info) !important; border-color: var(--highdmin-info) !important; }
.page-content .table tbody td .btn.btn-dark { color: var(--highdmin-body-color) !important; border-color: var(--ux-borde-color) !important; }

/* Al pasar el ratón el botón se rellena, como en el resto de la aplicación. */
.page-content .table tbody td .btn.btn-primary:hover,
.page-content .table tbody td .btn.btn-soft-primary:hover { background-color: var(--highdmin-primary) !important; color: #fff !important; }
.page-content .table tbody td .btn.btn-danger:hover,
.page-content .table tbody td .btn.btn-soft-danger:hover { background-color: var(--highdmin-danger) !important; color: #fff !important; }
.page-content .table tbody td .btn.btn-success:hover,
.page-content .table tbody td .btn.btn-soft-success:hover { background-color: var(--highdmin-success) !important; color: #fff !important; }
.page-content .table tbody td .btn.btn-info:hover,
.page-content .table tbody td .btn.btn-soft-info:hover { background-color: var(--highdmin-info) !important; color: #fff !important; }
.page-content .table tbody td .btn.btn-warning:hover,
.page-content .table tbody td .btn.btn-soft-warning:hover { background-color: var(--highdmin-warning) !important; color: #212529 !important; }
.page-content .table tbody td .btn.btn-secondary:hover,
.page-content .table tbody td .btn.btn-soft-secondary:hover { background-color: var(--highdmin-secondary) !important; color: #fff !important; }

/* Tamaño común de los botones de fila: cuadrados de 32 px con el icono centrado. */
.page-content .table tbody td .btn {
    --highdmin-btn-padding-y: 5px;
    --highdmin-btn-padding-x: 9px;
    border-radius: 6px !important;
    line-height: 1.2;
    min-height: 32px;
    min-width: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.page-content .table tbody td .btn-group,
.page-content .table tbody td .d-flex.gap-1,
.page-content .table tbody td .ux-fila-acciones {
    gap: var(--ux-espacio-1) !important;
}


/* ---------- Aviso de desplazamiento en tablas anchas ---------- */

/* Las tablas de más de diez columnas no ocultan ninguna: se desplazan dentro de su tarjeta y avisan
   de ello. La clase propia de Seguimiento se unifica aquí para que el gris cumpla la norma de
   contraste (el suyo, #9e9e9e, daba 2,8 a 1 sobre blanco). */
/* El aviso solo se ve cuando la tabla se desplaza de verdad, y eso lo decide el navegador en
   js/aviso-desliza.js, que ademas pone la clase js-aviso-desliza en <html>. Sin ese guion los
   avisos escritos en las vistas se siguen viendo como antes, que es lo que debe pasar. */
html.js-aviso-desliza .page-content .ux-aviso-desliza,
html.js-aviso-desliza .page-content .scroll-hint {
    display: none;
}

/* Cuando la tabla vive en un cuerpo de tarjeta sin relleno, el aviso se insertaba pegado al borde.
   Se le da el mismo margen lateral que tendra la tabla. */
.page-content .card-body.p-0 > .ux-aviso-desliza,
.page-content .card-body.p-0 > .scroll-hint {
    padding: var(--ux-espacio-3) var(--ux-espacio-4) 0;
}

html.js-aviso-desliza .page-content .ux-aviso-desliza.se-ve,
html.js-aviso-desliza .page-content .scroll-hint.se-ve {
    display: flex;
}

.page-content .ux-aviso-desliza,
.page-content .scroll-hint {
    font-size: 13px;
    line-height: 18px;
    color: var(--ux-texto-secundario) !important;
    margin-bottom: var(--ux-espacio-2);
    display: flex;
    align-items: center;
    gap: var(--ux-espacio-1);
}

/* El resumen de validacion de ASP.NET siempre se pinta; cuando no hay errores lleva la clase
   validation-summary-valid y este tema no traia la regla que lo oculta, asi que se veia una caja
   roja vacia encima del formulario. */
.validation-summary-valid {
    display: none;
}

/* Fila de detalle desplegable (boton Ver) en listados que solo tienen Crear y Eliminar: el
   formulario pide mas campos de los que caben en columnas y el usuario no volvia a verlos. */
.ux-detalle-fila > td {
    background: var(--highdmin-tertiary-bg);
    padding: var(--ux-espacio-2) var(--ux-espacio-3) var(--ux-espacio-3);
}
tr.ux-detalle-abierta > td {
    border-bottom-color: transparent;
}
.ux-detalle {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--ux-espacio-2) var(--ux-espacio-4);
    margin: 0;
    /* La celda abarca toda la tabla; en una tabla mas ancha que la pantalla el detalle se queda
       pegado al borde visible en vez de irse con el desplazamiento horizontal (el ancho lo fija
       ux-detalle.js con el de la caja que desplaza). */
    position: sticky;
    left: var(--ux-espacio-3);
}
.ux-detalle dt {
    font-size: 12px;
    font-weight: 500;
    color: var(--ux-texto-secundario);
}
.ux-detalle dd {
    margin: 0;
    font-size: 14px;
    overflow-wrap: anywhere;
}
[data-ux-detalle][aria-expanded="true"] {
    color: var(--highdmin-primary);
    border-color: var(--highdmin-primary);
    background: var(--highdmin-primary-bg-subtle, var(--highdmin-secondary-bg));
}
