/* ==========================================================================
   APP — Layout y componentes
   ==========================================================================

   Todos los valores salen de theme.css. Si encontrás un color literal acá,
   es un error: movelo a un token.

   Orden del archivo:
     1. Base
     2. Re-teñido de Bootstrap
     3. Shell de la aplicación (sidebar, topbar, contenido)
     4. Componentes propios
     5. DataTables
     6. HTMX
     7. Responsive
   ========================================================================== */

/* ==========================================================================
   1. Base
   ========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background-color: var(--surface-sunken);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: var(--leading-base);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    color: var(--neutral-900);
    font-weight: var(--weight-semi);
    line-height: var(--leading-tight);
    margin: 0;
}

a {
    color: var(--link);
    text-decoration: none;
}

a:hover {
    color: var(--link-hover);
    text-decoration: underline;
}

/* Un foco visible es un requisito de accesibilidad, no un detalle estético.
   Se reemplaza el outline del navegador por uno del color de marca. */
:focus-visible {
    outline: none;
    box-shadow: var(--ring);
    border-radius: var(--radius-sm);
}

code, kbd, pre {
    font-family: var(--font-mono);
    font-size: 0.9em;
}

/* ==========================================================================
   2. Re-teñido de Bootstrap
   ==========================================================================

   Bootstrap 5.3 resuelve los colores de sus componentes en tiempo de
   compilación: `.btn-primary` trae el azul escrito como literal. Redefinir
   `--bs-primary` no alcanza. Lo que sí funciona es reasignar las variables
   por componente, que es lo que se hace acá.

   Esto es lo que permite tener el sistema teñido con la paleta propia sin
   Sass, sin Node y sin recompilar nada.
   ========================================================================== */

:root {
    --bs-body-font-family: var(--font-sans);
    --bs-body-font-size: var(--text-base);
    --bs-body-color: var(--text);
    --bs-body-bg: var(--surface-sunken);
    --bs-border-color: var(--border);
    --bs-border-radius: var(--radius-md);
    --bs-border-radius-sm: var(--radius-sm);
    --bs-border-radius-lg: var(--radius-lg);
    --bs-link-color: var(--link);
    --bs-link-hover-color: var(--link-hover);
    --bs-primary: var(--brand-600);
    --bs-primary-rgb: 13, 148, 136;
    --bs-focus-ring-color: rgba(13, 148, 136, 0.25);
}

.btn {
    --bs-btn-font-size: var(--text-base);
    --bs-btn-font-weight: var(--weight-medium);
    --bs-btn-padding-y: 0.4rem;
    --bs-btn-padding-x: 0.85rem;
    --bs-btn-border-radius: var(--radius-md);
    transition: background-color var(--transition-fast),
                border-color var(--transition-fast),
                box-shadow var(--transition-fast);
}

.btn-primary {
    --bs-btn-bg: var(--brand-600);
    --bs-btn-border-color: var(--brand-600);
    --bs-btn-hover-bg: var(--brand-700);
    --bs-btn-hover-border-color: var(--brand-700);
    --bs-btn-active-bg: var(--brand-800);
    --bs-btn-active-border-color: var(--brand-800);
    --bs-btn-disabled-bg: var(--brand-300);
    --bs-btn-disabled-border-color: var(--brand-300);
}

.btn-outline-primary {
    --bs-btn-color: var(--brand-700);
    --bs-btn-border-color: var(--brand-600);
    --bs-btn-hover-bg: var(--brand-600);
    --bs-btn-hover-border-color: var(--brand-600);
    --bs-btn-active-bg: var(--brand-700);
    --bs-btn-active-border-color: var(--brand-700);
}

/* Un enlace con aspecto de botón no se subraya al pasar el cursor: el
   `a:hover` de Bootstrap (0,1,1) le gana a `.btn` (0,1,0). */
a.btn:hover,
a.btn:focus {
    text-decoration: none;
}

/* Botón tonal: para acciones hermanas del mismo rango (p. ej. "Armar de
   eventos" / "Armar de servicios"). Ninguna es la principal, así que ninguna
   va rellena; y el hover solo profundiza el tinte, nunca se vuelve sólido,
   para que no parezca "seleccionado". */
.btn-tonal {
    --bs-btn-bg: var(--brand-50);
    --bs-btn-border-color: var(--brand-200);
    --bs-btn-color: var(--brand-800);
    --bs-btn-hover-bg: var(--brand-100);
    --bs-btn-hover-border-color: var(--brand-300);
    --bs-btn-hover-color: var(--brand-900);
    --bs-btn-active-bg: var(--brand-200);
    --bs-btn-active-border-color: var(--brand-300);
    --bs-btn-active-color: var(--brand-900);
    --bs-btn-focus-shadow-rgb: 13, 148, 136;
}

.icon-excel {
    color: var(--excel);
}

.btn-tonal svg {
    color: var(--brand-600);
}

.btn-light {
    --bs-btn-bg: var(--surface);
    --bs-btn-border-color: var(--border-strong);
    --bs-btn-color: var(--text);
    --bs-btn-hover-bg: var(--neutral-100);
    --bs-btn-hover-border-color: var(--border-strong);
}

.btn-danger {
    --bs-btn-bg: var(--danger);
    --bs-btn-border-color: var(--danger);
    --bs-btn-hover-bg: var(--danger-text);
    --bs-btn-hover-border-color: var(--danger-text);
}

.form-control,
.form-select {
    border-color: var(--border-strong);
    border-radius: var(--radius-md);
    color: var(--text);
    font-size: var(--text-base);
    padding: 0.45rem 0.7rem;
}

.form-control:focus,
.form-select:focus {
    border-color: var(--brand-500);
    box-shadow: var(--ring);
}

.form-control::placeholder {
    color: var(--text-subtle);
}

.form-label {
    color: var(--neutral-700);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    margin-bottom: var(--space-1);
}

.form-control.is-invalid,
.form-select.is-invalid {
    border-color: var(--danger);
}

.form-control.is-invalid:focus,
.form-select.is-invalid:focus {
    box-shadow: 0 0 0 3px rgba(185, 28, 28, 0.18);
}

.invalid-feedback {
    color: var(--danger);
    font-size: var(--text-xs);
}

.form-text {
    color: var(--text-muted);
    font-size: var(--text-xs);
}

.modal-content {
    border: none;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}

.modal-header,
.modal-footer {
    border-color: var(--border);
    padding: var(--space-4) var(--space-5);
}

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

.modal-title {
    font-size: var(--text-lg);
}

.dropdown-menu {
    --bs-dropdown-border-color: var(--border);
    --bs-dropdown-border-radius: var(--radius-md);
    --bs-dropdown-font-size: var(--text-base);
    --bs-dropdown-link-active-bg: var(--brand-600);
    box-shadow: var(--shadow-md);
}

/* ==========================================================================
   3. Shell de la aplicación
   ========================================================================== */

.app {
    min-height: 100vh;
}

/* --- Sidebar --- */

.app-sidebar {
    background-color: var(--surface-inverse);
    bottom: 0;
    color: var(--neutral-300);
    display: flex;
    flex-direction: column;
    left: 0;
    position: fixed;
    top: 0;
    transition: width var(--transition-base), transform var(--transition-base);
    width: var(--sidebar-width);
    z-index: var(--z-sidebar);
}

.app-sidebar__brand {
    align-items: center;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    color: var(--text-inverse);
    display: flex;
    flex-shrink: 0;
    gap: var(--space-3);
    height: var(--topbar-height);
    padding: 0 var(--space-4);
    text-decoration: none;
}

.app-sidebar__brand:hover {
    color: var(--text-inverse);
    text-decoration: none;
}

.app-sidebar__logo {
    align-items: center;
    background-color: var(--brand-600);
    border-radius: var(--radius-md);
    display: flex;
    flex-shrink: 0;
    height: 32px;
    justify-content: center;
    width: 32px;
}

.app-sidebar__name {
    font-size: var(--text-md);
    font-weight: var(--weight-semi);
    letter-spacing: -0.01em;
    white-space: nowrap;
}

.app-sidebar__nav {
    flex: 1;
    list-style: none;
    margin: 0;
    overflow-y: auto;
    padding: var(--space-3) var(--space-2);
}

.app-sidebar__section {
    color: var(--neutral-500);
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
    letter-spacing: 0.06em;
    padding: var(--space-4) var(--space-3) var(--space-2);
    text-transform: uppercase;
    white-space: nowrap;
}

.app-sidebar__link {
    align-items: center;
    border-radius: var(--radius-md);
    color: var(--neutral-300);
    display: flex;
    gap: var(--space-3);
    margin-bottom: 2px;
    padding: var(--space-2) var(--space-3);
    transition: background-color var(--transition-fast), color var(--transition-fast);
    white-space: nowrap;
}

.app-sidebar__link:hover {
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--text-inverse);
    text-decoration: none;
}

.app-sidebar__link.active {
    background-color: var(--brand-600);
    color: var(--text-inverse);
    font-weight: var(--weight-medium);
}

.app-sidebar__link svg {
    flex-shrink: 0;
    height: 18px;
    width: 18px;
}

/*
 * Un grupo de enlaces: el rótulo no navega a ningún lado, solo nombra lo que
 * cuelga debajo. Hoy es «Pagos», con Eventos y Servicios adentro.
 */
.app-sidebar__group {
    align-items: center;
    color: var(--neutral-400);
    display: flex;
    gap: var(--space-3);
    margin-bottom: 2px;
    padding: var(--space-2) var(--space-3);
    white-space: nowrap;
}

.app-sidebar__group svg {
    flex-shrink: 0;
    height: 18px;
    width: 18px;
}

/* Los hijos del grupo, corridos a la altura del texto del rótulo. */
.app-sidebar__link--sub {
    padding-left: calc(var(--space-3) + 18px + var(--space-3));
}

.app-sidebar__footer {
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    color: var(--neutral-500);
    flex-shrink: 0;
    font-size: var(--text-xs);
    padding: var(--space-3) var(--space-4);
    white-space: nowrap;
}

/* --- Sidebar plegada (escritorio) --- */

.sidebar-collapsed .app-sidebar {
    width: var(--sidebar-width-collapsed);
}

.sidebar-collapsed .app-sidebar__name,
.sidebar-collapsed .app-sidebar__section,
.sidebar-collapsed .app-sidebar__group,
.sidebar-collapsed .app-sidebar__link span,
.sidebar-collapsed .app-sidebar__footer {
    display: none;
}

.sidebar-collapsed .app-sidebar__link {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}

.sidebar-collapsed .app-sidebar__brand {
    justify-content: center;
    padding: 0;
}

.sidebar-collapsed .app-main {
    margin-left: var(--sidebar-width-collapsed);
}

/* --- Topbar --- */

.app-topbar {
    align-items: center;
    background-color: var(--surface);
    border-bottom: 1px solid var(--border);
    display: flex;
    gap: var(--space-3);
    height: var(--topbar-height);
    padding: 0 var(--space-5);
    position: sticky;
    top: 0;
    z-index: var(--z-topbar);
}

.app-topbar__toggle {
    align-items: center;
    background: none;
    border: none;
    border-radius: var(--radius-md);
    color: var(--text-muted);
    cursor: pointer;
    display: flex;
    height: 36px;
    justify-content: center;
    padding: 0;
    width: 36px;
}

.app-topbar__toggle:hover {
    background-color: var(--neutral-100);
    color: var(--text);
}

.app-topbar__spacer {
    flex: 1;
}

.app-topbar__user {
    align-items: center;
    background: none;
    border: none;
    border-radius: var(--radius-md);
    color: var(--text);
    cursor: pointer;
    display: flex;
    gap: var(--space-3);
    padding: var(--space-1) var(--space-2);
}

.app-topbar__user:hover {
    background-color: var(--neutral-100);
}

.avatar {
    align-items: center;
    background-color: var(--brand-100);
    border-radius: var(--radius-full);
    color: var(--brand-800);
    display: flex;
    flex-shrink: 0;
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
    height: 32px;
    justify-content: center;
    width: 32px;
}

.app-topbar__identity {
    line-height: 1.2;
    text-align: left;
}

.app-topbar__identity strong {
    display: block;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
}

.app-topbar__identity small {
    color: var(--text-muted);
    font-size: var(--text-xs);
}

/* --- Contenido --- */

.app-main {
    margin-left: var(--sidebar-width);
    min-height: 100vh;
    transition: margin-left var(--transition-base);
}

.app-content {
    margin: 0 auto;
    max-width: var(--content-max);
    padding: var(--space-5);
}

/* Overlay para la sidebar en móvil */
.app-overlay {
    background-color: rgba(15, 23, 42, 0.5);
    inset: 0;
    opacity: 0;
    pointer-events: none;
    position: fixed;
    transition: opacity var(--transition-base);
    z-index: var(--z-overlay);
}

/* ==========================================================================
   4. Componentes propios
   ========================================================================== */

/* --- Encabezado de página --- */

.page-header {
    align-items: flex-start;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    justify-content: space-between;
    margin-bottom: var(--space-5);
}

.page-header__title {
    font-size: var(--text-2xl);
    letter-spacing: -0.02em;
}

.page-header__subtitle {
    color: var(--text-muted);
    margin: var(--space-1) 0 0;
}

.page-header__actions {
    display: flex;
    flex-shrink: 0;
    gap: var(--space-2);
}

/* --- Breadcrumbs --- */

.breadcrumbs {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    font-size: var(--text-sm);
    gap: var(--space-2);
    list-style: none;
    margin: 0 0 var(--space-3);
    padding: 0;
}

.breadcrumbs li {
    align-items: center;
    color: var(--text-muted);
    display: flex;
    gap: var(--space-2);
}

.breadcrumbs li:not(:last-child)::after {
    color: var(--text-subtle);
    content: "/";
}

.breadcrumbs a {
    color: var(--text-muted);
}

.breadcrumbs a:hover {
    color: var(--link);
}

.breadcrumbs li[aria-current="page"] {
    color: var(--text);
    font-weight: var(--weight-medium);
}

/* --- Card --- */

.card-app {
    background-color: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.card-app__header {
    align-items: center;
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    justify-content: space-between;
    padding: var(--space-4) var(--space-5);
}

.card-app__title {
    font-size: var(--text-md);
}

.card-app__subtitle {
    color: var(--text-muted);
    font-size: var(--text-sm);
    margin: 2px 0 0;
}

.card-app__body {
    padding: var(--space-5);
}

.card-app__body--flush {
    padding: 0;
}

/* --- Métricas del dashboard --- */

.stat {
    background-color: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: var(--space-4) var(--space-5);
}

.stat__label {
    color: var(--text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.stat__value {
    color: var(--neutral-900);
    font-size: var(--text-2xl);
    font-weight: var(--weight-semi);
    letter-spacing: -0.02em;
    margin-top: var(--space-1);
}

.stat__hint {
    color: var(--text-muted);
    font-size: var(--text-xs);
    margin-top: var(--space-1);
}

/* --- Badges --- */

.badge-soft {
    border-radius: var(--radius-full);
    display: inline-block;
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    line-height: 1.4;
    padding: 2px 10px;
    white-space: nowrap;
}

.badge-soft--success { background-color: var(--success-bg); color: var(--success-text); }
.badge-soft--danger  { background-color: var(--danger-bg);  color: var(--danger-text); }
.badge-soft--warning { background-color: var(--warning-bg); color: var(--warning-text); }
.badge-soft--info    { background-color: var(--info-bg);    color: var(--info-text); }
.badge-soft--neutral { background-color: var(--neutral-100); color: var(--neutral-600); }

/* --- Control segmentado --- */

/*
   Selector de vista: varias opciones del mismo nivel, una sola activa. La
   pista hundida agrupa las opciones como un único control, así la inactiva no
   se lee como texto suelto. La activa "sube" a superficie blanca con sombra.
   Son enlaces (cada vista tiene su URL), por eso el estado lo marca
   `aria-current` y no un `role=tab`.
*/

.segmented {
    background-color: var(--neutral-100);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    display: inline-flex;
    gap: 2px;
    max-width: 100%;
    overflow-x: auto;
    padding: 3px;
}

.segmented__item {
    border-radius: calc(var(--radius-md) - 3px);
    color: var(--text-muted);
    font-size: var(--text-base);
    font-weight: var(--weight-medium);
    padding: var(--space-2) var(--space-4);
    text-decoration: none;
    transition: background-color var(--transition-fast), color var(--transition-fast);
    white-space: nowrap;
}

.segmented__item:hover {
    color: var(--text);
    text-decoration: none;
}

.segmented__item:focus-visible {
    box-shadow: var(--ring);
    outline: none;
}

.segmented__item.is-active {
    background-color: var(--surface-raised);
    box-shadow: var(--shadow-sm), 0 0 0 1px var(--border);
    color: var(--brand-700);
    font-weight: var(--weight-semi);
}

/* --- Estado vacío --- */

.empty-state {
    align-items: center;
    display: flex;
    flex-direction: column;
    padding: var(--space-7) var(--space-5);
    text-align: center;
}

.empty-state__icon {
    align-items: center;
    background-color: var(--neutral-100);
    border-radius: var(--radius-full);
    color: var(--text-subtle);
    display: flex;
    height: 56px;
    justify-content: center;
    margin-bottom: var(--space-4);
    width: 56px;
}

.empty-state__title {
    font-size: var(--text-md);
}

.empty-state__text {
    color: var(--text-muted);
    margin: var(--space-2) 0 var(--space-4);
    max-width: 42ch;
}

/* --- Botón de acción de tabla --- */

.btn-icon {
    align-items: center;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    height: 30px;
    justify-content: center;
    padding: 0;
    transition: background-color var(--transition-fast), color var(--transition-fast);
    width: 30px;
}

.btn-icon:hover {
    background-color: var(--neutral-100);
    color: var(--text);
}

.btn-icon--danger:hover {
    background-color: var(--danger-bg);
    color: var(--danger);
}

.btn-icon svg {
    height: 16px;
    width: 16px;
}

.table-actions {
    display: flex;
    gap: var(--space-1);
    justify-content: flex-end;
}

/* --- Barra de selección --- */

/*
   Acompaña al usuario mientras baja por la tabla eligiendo pagos.

   Fija abajo y no arriba: el pulgar en un teléfono llega ahí, y en escritorio
   no tapa los encabezados de la tabla, que es lo que se está leyendo.

   El z-index queda por debajo del backdrop de un modal de Bootstrap (1050):
   cuando se abre el formulario de alta, la barra no tiene que flotar encima
   del diálogo que ella misma abrió.
*/

.selection-bar {
    align-items: center;
    background-color: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    bottom: var(--space-4);
    box-shadow: var(--shadow-lg);
    display: flex;
    gap: var(--space-5);
    justify-content: space-between;
    left: 50%;
    padding: var(--space-3) var(--space-5);
    position: fixed;
    transform: translateX(-50%);
    z-index: 1030;
}

/* `hidden` tiene que ganarle al `display: flex` de arriba, o la barra se ve
   siempre: un atributo que no hace nada es peor que no tenerlo. */
.selection-bar[hidden] {
    display: none;
}

.selection-bar__info {
    display: flex;
    font-size: var(--text-sm);
    gap: var(--space-2);
    white-space: nowrap;
}

@media (max-width: 575.98px) {
    .selection-bar {
        left: var(--space-3);
        right: var(--space-3);
        transform: none;
    }
}

/* ==========================================================================
   5. DataTables
   ==========================================================================
   Los estilos de Bootstrap 5 que trae DataTables son correctos pero genéricos.
   Acá solo se ajusta lo que choca con el resto del sistema.
   ========================================================================== */

.table {
    --bs-table-color: var(--text);
    --bs-table-border-color: var(--border);
    --bs-table-hover-bg: var(--brand-50);
    margin-bottom: 0;
}

.table > thead > tr > th {
    background-color: var(--neutral-50);
    border-bottom: 1px solid var(--border);
    color: var(--text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
    letter-spacing: 0.04em;
    padding: var(--space-3) var(--space-4);
    text-transform: uppercase;
    white-space: nowrap;
}

.table > tbody > tr > td {
    border-bottom: 1px solid var(--border);
    padding: var(--space-3) var(--space-4);
    vertical-align: middle;
}

.table > tbody > tr:last-child > td {
    border-bottom: none;
}

/* Encabezado ordenable.

   DataTables invierte el orden del encabezado en las columnas numéricas
   (`flex-direction: row-reverse`) para dejar la flecha del lado del número,
   y además le da `flex-grow: 1` al título. Combinado, el resultado es que la
   flecha se va al extremo opuesto de la celda y queda flotando lejos del
   texto al que pertenece: en dos columnas numéricas seguidas parece que las
   dos flechas fueran de la misma columna.

   Acá se fija el orden natural y se las mantiene pegadas al título. */
.table > thead > tr > th.text-end .dt-column-header,
.table > thead > tr > th.dt-type-numeric .dt-column-header {
    flex-direction: row;
    justify-content: flex-end;
}

.table > thead > tr > th.text-end .dt-column-title,
.table > thead > tr > th.dt-type-numeric .dt-column-title {
    flex-grow: 0;
}

/* Filas-tarjeta.

   Cada fila es una tarjeta suelta: la separación sale de `border-spacing`, no
   de líneas entre filas. Solo afecta a las tablas que DataTables envuelve en
   `.dt-container`; el funcionamiento (orden, búsqueda, paginación, responsive)
   no se toca, es puro aspecto.

   La tarjeta se arma con borde arriba/abajo en cada celda y borde lateral en
   la primera y la última, que además llevan el radio. El acento de hover es un
   degradado en la primera celda y no un `border-left`, para que el contenido
   no se corra 2px al pasar el mouse. */

.dt-container .table {
    border-collapse: separate;
    border-spacing: 0 var(--space-2);
    margin-top: calc(var(--space-2) * -1);
}

.dt-container .table > thead > tr > th {
    background-color: transparent;
    border-bottom: none;
    padding: var(--space-2) var(--space-4);
}

.dt-container .table > tbody > tr > td,
.dt-container .table > tbody > tr:last-child > td {
    background-color: var(--surface-raised);
    border-bottom: 1px solid var(--border);
    border-top: 1px solid var(--border);
    padding: var(--space-3) var(--space-4);
    transition: background-color var(--transition-fast),
                border-color var(--transition-fast);
}

.dt-container .table > tbody > tr > td:first-child {
    background-position: left center;
    background-repeat: no-repeat;
    background-size: 3px 100%;
    border-bottom-left-radius: var(--radius-md);
    border-left: 1px solid var(--border);
    border-top-left-radius: var(--radius-md);
}

.dt-container .table > tbody > tr > td:last-child {
    border-bottom-right-radius: var(--radius-md);
    border-right: 1px solid var(--border);
    border-top-right-radius: var(--radius-md);
}

.dt-container .table-hover > tbody > tr:hover > td {
    border-bottom-color: var(--brand-200);
    border-top-color: var(--brand-200);
}

.dt-container .table-hover > tbody > tr:hover > td:first-child {
    background-image: linear-gradient(var(--brand-500), var(--brand-500));
    border-left-color: var(--brand-200);
}

.dt-container .table-hover > tbody > tr:hover > td:last-child {
    border-right-color: var(--brand-200);
}

/* Cifras alineadas en columna: los dígitos tienen el mismo ancho. */
.dt-container .table > tbody > tr > td.text-end,
.dt-container .table > tbody > tr > td.dt-type-numeric {
    font-variant-numeric: tabular-nums;
}

.dt-container {
    padding: var(--space-4) var(--space-5);
}

.dt-container .dt-length,
.dt-container .dt-search,
.dt-container .dt-info,
.dt-container .dt-paging {
    font-size: var(--text-sm);
}

.dt-container .dt-info {
    color: var(--text-muted);
}

.dt-container .dt-search input {
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    margin-left: var(--space-2);
    padding: 0.35rem 0.6rem;
}

.dt-container .dt-search input:focus {
    border-color: var(--brand-500);
    box-shadow: var(--ring);
    outline: none;
}

.dt-container .dt-length select {
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    padding: 0.3rem 1.6rem 0.3rem 0.5rem;
}

.page-link {
    --bs-pagination-color: var(--text-muted);
    --bs-pagination-border-color: var(--border);
    --bs-pagination-hover-bg: var(--neutral-100);
    --bs-pagination-hover-color: var(--text);
    --bs-pagination-active-bg: var(--brand-600);
    --bs-pagination-active-border-color: var(--brand-600);
    --bs-pagination-focus-box-shadow: var(--ring);
    font-size: var(--text-sm);
}

/* Casillas de verificación.

   El borde por defecto de Bootstrap (#dee2e6) contra blanco da ~1.3:1: no
   cumple el 3:1 que WCAG exige a los controles de formulario, y por eso la
   casilla "desaparece" sobre una fila blanca. Con --neutral-500 el contraste
   es ~4.8:1 y se ve a simple vista sin gritar. */

.form-check-input {
    background-color: var(--surface);
    border: 1.5px solid var(--neutral-500);
    cursor: pointer;
    height: 1.125rem;
    margin-top: 0;
    transition: background-color var(--transition-fast),
                border-color var(--transition-fast),
                box-shadow var(--transition-fast);
    width: 1.125rem;
}

.form-check-input:hover:not(:disabled) {
    border-color: var(--brand-600);
    box-shadow: 0 0 0 3px var(--brand-100);
}

.form-check-input:focus-visible {
    border-color: var(--brand-600);
    box-shadow: var(--ring);
}

.form-check-input:checked,
.form-check-input:indeterminate {
    background-color: var(--brand-600);
    border-color: var(--brand-600);
}

/* Deshabilitada pero legible: Bootstrap solo baja la opacidad, y sobre un
   borde ya tenue la casilla se pierde. Acá se ve apagada sin desaparecer. */
.form-check-input:disabled {
    background-color: var(--neutral-100);
    border-color: var(--neutral-300);
    cursor: not-allowed;
    opacity: 1;
}

.form-check-input:disabled:checked {
    background-color: var(--neutral-400);
    border-color: var(--neutral-400);
}

/* La tabla nunca debe empujar el ancho de la página en pantallas chicas. */
.table-scroll {
    -webkit-overflow-scrolling: touch;
    overflow-x: auto;
}

/* ==========================================================================
   6. HTMX
   ==========================================================================
   `.htmx-indicator` arranca invisible y HTMX le agrega `.htmx-request` a la
   pieza que está esperando respuesta. Todo el feedback de carga sale de acá:
   no hace falta escribir ni una línea de JavaScript para mostrarlo.
   ========================================================================== */

.htmx-indicator {
    opacity: 0;
    transition: opacity var(--transition-base);
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
    opacity: 1;
}

/* Barra de progreso fina arriba de todo, al estilo de las webs modernas. */
.htmx-progress {
    background-color: var(--brand-500);
    height: 3px;
    left: 0;
    position: fixed;
    top: 0;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 300ms ease, opacity 200ms ease;
    width: 100%;
    z-index: 2000;
}

.htmx-progress.is-loading {
    transform: scaleX(0.7);
}

.htmx-progress.is-done {
    opacity: 0;
    transform: scaleX(1);
}

.spinner-inline {
    animation: spin 700ms linear infinite;
    border: 2px solid var(--border-strong);
    border-radius: var(--radius-full);
    border-top-color: var(--brand-600);
    display: inline-block;
    height: 14px;
    width: 14px;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* Mientras una petición está en curso, el bloque se atenúa y deja de
   aceptar clics. Evita el doble submit sin deshabilitar nada por JS. */
.htmx-request.is-busy {
    opacity: 0.55;
    pointer-events: none;
}

/* ==========================================================================
   7. Responsive
   ========================================================================== */

@media (max-width: 991.98px) {
    .app-sidebar {
        transform: translateX(-100%);
        width: var(--sidebar-width);
    }

    /* En móvil la sidebar se superpone: el contenido siempre ocupa todo. */
    .app-main,
    .sidebar-collapsed .app-main {
        margin-left: 0;
    }

    .sidebar-open .app-sidebar {
        box-shadow: var(--shadow-lg);
        transform: translateX(0);
    }

    .sidebar-open .app-overlay {
        opacity: 1;
        pointer-events: auto;
    }

    /* En móvil el plegado de escritorio no aplica: se muestra completa. */
    .sidebar-collapsed .app-sidebar__name,
    .sidebar-collapsed .app-sidebar__section,
    .sidebar-collapsed .app-sidebar__link span,
    .sidebar-collapsed .app-sidebar__footer {
        display: revert;
    }

    .sidebar-collapsed .app-sidebar__group {
        display: flex;
    }

    .sidebar-collapsed .app-sidebar__link,
    .sidebar-collapsed .app-sidebar__brand {
        justify-content: flex-start;
        padding: var(--space-2) var(--space-3);
    }

    .sidebar-collapsed .app-sidebar__link--sub {
        padding-left: calc(var(--space-3) + 18px + var(--space-3));
    }

    .app-content {
        padding: var(--space-4);
    }

    .app-topbar {
        padding: 0 var(--space-4);
    }

    .app-topbar__identity {
        display: none;
    }

    .page-header__title {
        font-size: var(--text-xl);
    }
}

@media (max-width: 575.98px) {
    /* Un importe como $324,714.00 no entra en media tarjeta a 1.75rem y se
       come el borde. Baja de tamaño solo donde hace falta. */
    .stat__value {
        font-size: var(--text-xl);
    }

    .stat {
        padding: var(--space-3) var(--space-4);
    }

    .page-header {
        flex-direction: column;
    }

    .page-header__actions {
        width: 100%;
    }

    .page-header__actions .btn {
        flex: 1;
    }

    .dt-container {
        padding: var(--space-3);
    }
}

@media print {
    .app-sidebar,
    .app-topbar,
    .page-header__actions,
    .dt-length,
    .dt-search,
    .dt-paging {
        display: none !important;
    }

    .app-main {
        margin-left: 0;
    }
}
