/**
 * Núcleo del design system de la intranet (Tabler 1.4.0 + Bootstrap 5).
 * Versión del kit de Elora: lleva además, en el mismo orden que en el origen,
 * el modo compacto, el chip de TomSelect, las teclas (`kbd`), el foco de un
 * botón que envuelve un campo y la transición del contenido al abrir el panel
 * de Elora. Con esto, las pantallas de Elora se pintan igual que en el origen
 * (comprobado elemento a elemento en Chrome, en los dos temas).
 * La guía que lo explica: tabler/design-system/design-system-intranet.md.
 * Extraído de un proyecto en producción: SOLO las reglas genéricas, sin las de
 * pantallas concretas. Cada bloque explica el fallo medido que lo justifica.
 * Los ejemplos de los comentarios (alumnos, caja, créditos…) son del proyecto
 * de origen: se dejan porque explican el porqué, no porque apliquen aquí.
 * Cargar DESPUÉS de tabler.min.css.
 */

/* ── Barra superior: un solo sitio que sepa cuánto mide ────────────────────
   Todo lo que se queda pegado al bajar (índices de pantalla, tarjetas de
   resumen, cabeceras de tabla) tiene que pararse JUSTO debajo de la barra. Cada
   pantalla se inventaba su número —1rem, 5rem, 80px, 20px— y ninguna acertaba,
   porque el alto real no estaba escrito en ninguna parte. Ahora sí, y quien lo
   necesite usa `.sticky-bajo-cabecera` en vez de un `style` a mano.

   El z-index queda por DEBAJO del 1020 de la barra a propósito: un bloque de
   contenido no puede taparla nunca. Por debajo de 992 px no hay barra superior
   —sus acciones viven en el menú lateral—, así que el hueco es cero.
   (Nota del kit: esto se escribió con el menú a la izquierda. Con el layout
   «fluid» la barra existe en todos los anchos; el valor se deja como en el
   origen para que todo se vea igual, y es lo primero que mirar si algo pegado
   arriba se mete bajo la barra en una tablet.) */
:root { --sb-cabecera: 0px; }

@media (min-width: 992px) {
    /* Medido en el navegador en los dos temas, no estimado: los 56 px de suelo
       que Tabler da a la barra, más 1 del borde inferior. El `+1rem` del offset
       de abajo deja colchón por si alguna pieza crece; si algún día se pasa de
       ahí, lo que se pegue debajo se meterá bajo la barra y se verá enseguida. */
    :root { --sb-cabecera: 57px; }
}

.sticky-bajo-cabecera {
    position: sticky;
    top: calc(var(--sb-cabecera) + 1rem);
    z-index: 1010;
}

/* El aviso emergente de haber fichado. Va DEBAJO de la barra, no encima: al
   pegarlo arriba del todo tapaba el buscador de alumnos y los avisos, que es
   justo la esquina que la persona necesita ver mientras trabaja. */
.aviso-bajo-cabecera {
    top: calc(var(--sb-cabecera) + 0.5rem);
}

/* Cabecera de tabla que se queda al bajar dentro de su propio contenedor con
   scroll. Solo tiene que ganar a sus celdas, nunca a los desplegables de la
   página: por eso no usa `.sticky-top`, cuyo 1020 los taparía. */
.sticky-cabecera-tabla {
    position: sticky;
    top: 0;
    z-index: 2;
}

/* Aquí había un parche que ponía TODO badge de color en blanco. Sobre el azul
   claro medía 3,05:1, y sobre amarillo o lima habría sido peor: blanco sobre
   un fondo claro no se lee.

   Cada color de Tabler declara su propio color de contraste; lo que hace falta
   es usarlo, no imponer el blanco. Los tonos claros (amarillo, lima, cian,
   verde, turquesa, naranja, azur y sus alias) llevan texto oscuro — se corrige
   más abajo, donde se declaran. */
.badge.bg-blue:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-blue-fg); }
.badge.bg-azure:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-azure-fg); }
.badge.bg-indigo:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-indigo-fg); }
.badge.bg-purple:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-purple-fg); }
.badge.bg-pink:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-pink-fg); }
.badge.bg-red:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-red-fg); }
.badge.bg-orange:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-orange-fg); }
.badge.bg-yellow:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-yellow-fg); }
.badge.bg-lime:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-lime-fg); }
.badge.bg-green:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-green-fg); }
.badge.bg-teal:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-teal-fg); }
.badge.bg-cyan:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-cyan-fg); }
.badge.bg-primary:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-primary-fg); }
.badge.bg-secondary:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-secondary-fg); }
.badge.bg-success:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-success-fg); }
.badge.bg-warning:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-warning-fg); }
.badge.bg-danger:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-danger-fg); }
.badge.bg-info:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-info-fg); }
.badge.bg-dark:not([class*="-lt"]) { --tblr-badge-color: var(--tblr-dark-fg); }

/**
 * Tamaño de los iconos de fuente dentro de contenedores de Tabler.
 *
 * Tabler dimensiona .empty-icon (3rem) y .alert-icon (1.25rem) pensando en un
 * SVG en línea, que ocupa el hueco entero. Nosotros usamos la fuente de iconos
 * (.ti), y un glifo hereda el tamaño de texto del padre: 14 px. Resultado: en
 * el estado vacío salía un punto diminuto en un hueco de 48 px.
 *
 * Se le da al glifo el tamaño que Tabler ya reservó para el hueco. `.modal-icon`
 * es nuestra, para el icono grande de un modal de confirmación: Tabler no trae
 * ninguna utilidad de 3rem y la alternativa era un tamaño escrito a mano en la
 * plantilla, que es justo lo que el sistema prohíbe.
 * Documentado en Docs/design-system/intranet.md, apartado 6.
 */
.empty-icon > .ti,
.empty-icon.ti,
.modal-icon.ti {
    font-size: 3rem;
    line-height: 1;
}

.alert-icon.ti,
.alert-icon > .ti {
    font-size: 1.25rem;
    line-height: 1;
}

/**
 * Menú de acciones (botón derecho sobre una fila).
 *
 * Cada opción lleva su color según lo que hace, y al pasar por encima se ilumina
 * con ESE color, no con un gris genérico: el gris obliga a leer la etiqueta para
 * saber qué vas a pulsar; el tinte propio se reconoce antes de leer. La idea
 * viene del menú de conversaciones, que es el que quiso dirección como patrón.
 *
 * `currentColor` es el color que ya tiene la opción por su clase `text-*`, así
 * que esto funciona para cualquier color sin escribir uno solo a mano.
 */
#menu-acciones .dropdown-item:hover,
#menu-acciones .dropdown-item:focus {
    background-color: color-mix(in oklab, currentColor 12%, transparent);
}


/* --------------------------------------------------------------------------
   Botones de acción por familia

   Medido sobre los doce colores de Tabler en los dos temas: sólo el primario y
   el gris llegan a 4,5:1 en ambos. Los rellenos vivos (verde 2,63) y los
   contornos (azure 3,05 en claro, azul 2,94 en oscuro) suspenden siempre en
   uno de los dos, porque su color es fijo y el fondo no.

   Aquí el color de la familia se mezcla con el color del cuerpo: en el tema
   claro tira a oscuro y en el oscuro tira a claro, con la misma regla y sin
   escribir ningún color a mano. El relleno pleno queda para la acción
   principal de la pantalla; todo lo demás va en contorno.
   -------------------------------------------------------------------------- */
.btn-accion {
    /* 62% dejaba el verde de «Vender créditos» en 4,41:1 sobre blanco: los
       colores claros necesitan más mezcla para despegar del fondo. */
    --tblr-btn-color: color-mix(in oklab, var(--accion) 48%, var(--tblr-body-color));
    --tblr-btn-border-color: color-mix(in oklab, var(--accion) 40%, transparent);
    --tblr-btn-bg: transparent;
    --tblr-btn-hover-color: var(--tblr-btn-color);
    --tblr-btn-hover-bg: color-mix(in oklab, var(--accion) 12%, transparent);
    --tblr-btn-hover-border-color: var(--accion);
    --tblr-btn-active-color: var(--tblr-btn-color);
    --tblr-btn-active-bg: color-mix(in oklab, var(--accion) 20%, transparent);
    --tblr-btn-active-border-color: var(--accion);
}
.btn-accion .ti { color: var(--accion); }

.accion-dinero        { --accion: var(--tblr-green); }
.accion-comunicacion  { --accion: var(--tblr-azure); }
.accion-gestion       { --accion: var(--tblr-blue); }
.accion-problema      { --accion: var(--tblr-orange); }
.accion-destruye      { --accion: var(--tblr-red); }


/* Icono que acompaña a una cifra. Mismo truco que los botones de acción: el
   color de la familia mezclado con el del texto, para que se vea en los dos
   temas (el verde de Tabler sobre fondo claro se queda en 2,74:1). */
.icono-dato { color: color-mix(in oklab, var(--accion, currentColor) 58%, var(--tblr-body-color)); }

/* Tinte: una fila o una tarjeta teñidas sin tocar el color del texto.

   NO se usa `bg-<color>-lt` para esto: esa clase fija también el color del
   TEXTO, así que tiñe de naranja el contenido entero —enlaces, fechas y badges
   incluidos— y se lleva por delante cualquier `text-reset`.

   El tinte además se mezcla con el fondo del sitio donde cae, así que aguanta
   los dos temas. En comentarios el color llega de la base de datos
   (`comentarios_categorias`), donde se escogió para papel blanco: azul #2014ff
   sobre #9bb9fa da 2,8:1 y la categoría «para eliminar» es negro sobre negro. */
.tinte-orange { --tinte: var(--tblr-orange); }
.tinte-red    { --tinte: var(--tblr-red); }
.tinte-green  { --tinte: var(--tblr-green); }
.tinte-yellow { --tinte: var(--tblr-yellow); }
.tinte-azure  { --tinte: var(--tblr-azure); }

tr.tinte      { --tblr-table-bg: color-mix(in oklab, var(--tinte) 16%, var(--tblr-bg-surface)); }
.card.tinte   { background-color: color-mix(in oklab, var(--tinte) 12%, var(--tblr-card-bg, var(--tblr-bg-surface))); }


/* Alpine no define `x-cloak`: sin esta regla, todo lo que está oculto hasta que
   arranca el JS aparece un instante al cargar la página y luego desaparece. */
[x-cloak] { display: none !important; }

/* Separador entre dos columnas de un mismo bloque, solo cuando van una al lado
   de la otra. Bootstrap trae `border-end` pero no su versión por tamaño, y en
   móvil —donde las columnas se apilan— un borde lateral no separa nada. */
@media (min-width: 768px) {
    .border-md-end { border-right: 1px solid var(--tblr-border-color); }
}

/* --------------------------------------------------------------------------
   Modo compacto

   La intranet se usa en pantallas grandes y con muchas filas a la vez: cajas,
   cuadrantes, listados de alumnos, el grid de clases. Con los espaciados de
   fábrica de Tabler caben pocas cosas de una vez y hay que hacer scroll para
   todo.

   Aquí se aprieta lo que solo es aire —el relleno de tarjetas, tablas y
   cabeceras— y NO se toca el tamaño del texto ni las zonas pulsables: apretar
   la letra es hacerla más difícil de leer, no más eficiente.

   Se enciende poniendo la clase `compacto` en <body>; para volver atrás, se
   quita. Nada más.
   -------------------------------------------------------------------------- */
body.compacto {
    --tblr-card-spacer-x: .875rem;
    --tblr-card-spacer-y: .625rem;
    --tblr-page-padding: .75rem;
    --tblr-page-padding-y: 1rem;
}
body.compacto .card { margin-bottom: 1rem !important; }
body.compacto .card-header { min-height: auto; padding-top: .625rem; padding-bottom: .625rem; }
body.compacto .table > :not(caption) > * > * { padding-top: .4rem; padding-bottom: .4rem; }
body.compacto .list-group-item { padding-top: .5rem; padding-bottom: .5rem; }
body.compacto .page-header { margin-top: .75rem; margin-bottom: .75rem; }
body.compacto .row-cards > * { --tblr-gutter-y: .75rem; }

/* Las zonas pulsables NO se aprietan: por debajo de 32px se falla al hacer clic. */
body.compacto .btn { min-height: 2.25rem; }

/* --------------------------------------------------------------------------
   Secciones con color

   Una pantalla larga —la ficha del alumno, el detalle de caja, el grid— es una
   pila de tarjetas iguales. La línea que Tabler pone bajo el `card-header` es
   de un 10% de opacidad: existe, pero al hacer scroll no separa nada.

   Cada apartado lleva su color en una banda a la izquierda y en el icono del
   título. El color NO se elige por gusto: sale de la misma tabla de familias
   que gobierna botones y menús (Docs/design-system/intranet.md).

   El fondo de la cabecera se tiñe solo un 7%, lo justo para que se distinga del
   cuerpo sin volver a los bloques de color pleno que había antes.
   -------------------------------------------------------------------------- */
.seccion { border-left: 4px solid var(--seccion, var(--tblr-border-color)); }
.seccion > .card-header {
    background-color: color-mix(in oklab, var(--seccion, transparent) 7%, transparent);
    border-bottom-color: color-mix(in oklab, var(--seccion, var(--tblr-border-color)) 35%, transparent);
}
/* El icono del título toma el color de su familia. El selector solo miraba
   `.ti` —la fuente de iconos— y en toda la intranet los iconos son SVG en
   línea: la promesa estaba escrita y no se cumplía en ninguna pantalla. */
.seccion > .card-header .card-title > .ti:first-child,
.seccion > .card-header .card-title > svg:first-child { color: var(--seccion); }

/* El título de un apartado pesa más que el de una tarjeta cualquiera. El
   `card-title` de Tabler es 1rem, que con el subtítulo de 0,875 justo debajo
   apenas jerarquiza: aquí sube a 1,125rem y a peso 600. */
.seccion > .card-header .card-title {
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.75rem;
}
.seccion > .card-header .card-title > .ti:first-child { font-size: 1.25rem; }
.seccion > .card-header .card-title > svg:first-child { width: 1.25rem; height: 1.25rem; }

.seccion-dinero        { --seccion: var(--tblr-green); }
.seccion-comunicacion  { --seccion: var(--tblr-azure); }
.seccion-clase         { --seccion: var(--tblr-purple); }
.seccion-gente         { --seccion: var(--tblr-blue); }
.seccion-aviso         { --seccion: var(--tblr-orange); }
.seccion-problema      { --seccion: var(--tblr-red); }


/* --------------------------------------------------------------------------
   Barra de acciones de un formulario largo

   Editar una clase son tres pantallas de scroll: los botones de guardar tienen
   que acompañar, no esperar al final. Estaba resuelto clavando la barra al
   borde de la ventana (`position: fixed` con `left: 0`), y así se salía del
   contenido: se metía por debajo del menú lateral y no cuadraba con nada.

   `sticky` hace lo mismo sin salirse: la barra vive dentro del formulario, se
   pega abajo mientras haya formulario por delante y aterriza sola al final. No
   hace falta ni reservar hueco al final de la página ni tocar el z-index de
   los modales.

   Los márgenes negativos son el hueco lateral del contenedor de Bootstrap: sin
   ellos el contenido se colaría por los dos costados al hacer scroll.
   -------------------------------------------------------------------------- */
.barra-acciones {
    position: sticky;
    bottom: 0;
    z-index: 3;
    margin-block-start: 1rem;
    margin-inline: calc(var(--tblr-gutter-x, 1.5rem) * -.5);
    padding: .75rem calc(var(--tblr-gutter-x, 1.5rem) * .5);
    background-color: var(--tblr-body-bg);
    border-top: 1px solid var(--tblr-border-color);
    box-shadow: 0 -.5rem 1rem -.5rem rgba(0, 0, 0, .15);
}

/* --------------------------------------------------------------------------
   Índice de apartados

   Editar una clase son tres pantallas de scroll, así que arriba hay un índice.
   Sus enlaces NO tienen color propio: toman el del apartado al que llevan, el
   mismo que pinta su banda. Antes eran doce colores distintos —amarillo, rosa,
   lima, azul, naranja, teal, índigo…— elegidos uno a uno y sin significado:
   el índice y la página se contradecían.

   Se pone `seccion-<familia>` en el enlace, pero NO `seccion`: esa clase dibuja
   la banda de la izquierda, que en un botón no pinta nada.
   -------------------------------------------------------------------------- */
.btn.enlace-seccion {
    --tblr-btn-color: color-mix(in oklab, var(--seccion, var(--tblr-secondary)) 62%, var(--tblr-body-color));
    --tblr-btn-border-color: color-mix(in oklab, var(--seccion, var(--tblr-border-color)) 40%, transparent);
    --tblr-btn-bg: transparent;
    --tblr-btn-hover-color: var(--tblr-btn-color);
    --tblr-btn-hover-bg: color-mix(in oklab, var(--seccion, var(--tblr-secondary)) 12%, transparent);
    --tblr-btn-hover-border-color: var(--seccion, var(--tblr-secondary));
    --tblr-btn-active-color: var(--tblr-btn-color);
    --tblr-btn-active-bg: color-mix(in oklab, var(--seccion, var(--tblr-secondary)) 20%, transparent);
    --tblr-btn-active-border-color: var(--seccion, var(--tblr-secondary));
}

/* El apartado en el que estás: relleno de su color, no un borde más gordo.
   `scale` movía los de al lado al hacer scroll. */
.btn.enlace-seccion.active {
    font-weight: 600;
    --tblr-btn-bg: color-mix(in oklab, var(--seccion, var(--tblr-secondary)) 18%, transparent);
    --tblr-btn-border-color: var(--seccion, var(--tblr-secondary));
}


/* --------------------------------------------------------------------------
   El nivel de una clase, en una fila de tabla

   El color de fondo dice el nivel de un vistazo: es regla de dirección y por eso
   manda en el grid (`celda-clase`). En una tabla no cabe un fondo entero, así que
   el nivel va en una marca de color delante del nombre. El color sale de la ficha
   del nivel en la base de datos —no es un color escrito a mano— y se pasa por
   `--nivel`, igual que en el grid.
   -------------------------------------------------------------------------- */
.marca-nivel {
    display: inline-block;
    width: .5rem;
    height: 1.1em;
    margin-right: .5rem;
    border-radius: 2px;
    background-color: var(--nivel, var(--tblr-border-color));
    vertical-align: -.15em;
}

/* --------------------------------------------------------------------------
   La cabecera de una pantalla de centro

   19 pantallas pintaban su cabecera entera con el color del centro y escribían
   encima con un color fijo. Medido: ninguno de los cuatro colores aguanta un
   solo color de texto. Sobre texto oscuro, Quevedo (#ce0000) da 2,71:1 y el
   azul por defecto 2,96:1 —por debajo del 3:1 que pide el mínimo hasta para
   texto grande—. Sobre texto blanco, Sol (#06d0cc) da 1,93:1 y América 3,00:1.
   Es decir: elijas el texto que elijas, la mitad de los centros salen ilegibles.

   El color del centro sigue estando —identifica dónde estás de un vistazo— pero
   como filete y punto, no como fondo. El texto va con el color del tema, así que
   es legible en los cuatro centros y en los dos temas, sin excepciones.
   -------------------------------------------------------------------------- */
.page-header.cabecera-centro {
    --centro: var(--tblr-primary);
    background-color: transparent;
    border-inline-start: .25rem solid var(--centro);
    padding-inline-start: 1rem;
}

/* Cuando la cabecera trae su propio contenedor, el filete va en él: puesto en el
   padre se queda pegado al menú lateral, a media pantalla del título que marca. */
.page-header.cabecera-centro:has(> .container-xl) {
    border-inline-start: 0;
    padding-inline-start: 0;
}

.page-header.cabecera-centro > .container-xl {
    border-inline-start: .25rem solid var(--centro);
    padding-inline-start: 1rem;
}

.page-header.cabecera-centro .page-title,
.page-header.cabecera-centro .page-pretitle,
.page-header.cabecera-centro .breadcrumb,
.page-header.cabecera-centro .breadcrumb a {
    color: inherit;
}

/* El punto acompaña al nombre del centro donde se diga cuál es. */
.punto-centro {
    display: inline-block;
    width: .625rem;
    height: .625rem;
    border-radius: 50%;
    background-color: var(--centro, var(--tblr-primary));
    vertical-align: baseline;
}

/* --------------------------------------------------------------------------
   Pestañas en el tema oscuro

   Tabler deja `--tblr-nav-link-color` en `--tblr-gray-500` para los dos temas.
   Medido sobre el fondo oscuro real: 3,67:1, por debajo del 4,5:1 que exige
   una lectura normal. En una barra de siete pestañas, seis están siempre en
   ese gris: se lee la que ya sabes cuál es y no las demás.
   -------------------------------------------------------------------------- */
[data-bs-theme="dark"] .nav-tabs {
    --tblr-nav-link-color: var(--tblr-gray-300);
    --tblr-nav-link-hover-color: var(--tblr-body-color);
}

/* --------------------------------------------------------------------------
   El texto que va ENCIMA de un color

   DECISIÓN DE DIRECCIÓN, 6-sep-2026. La cabecera de una tarjeta de la intranet
   es de COLOR PLENO con texto blanco: `card-header bg-<color> text-white`. Es
   lo que dice CLAUDE.md y es lo que manda.

   Hasta hoy aquí se hacía lo contrario: los siete colores claros de Tabler no
   aguantan el blanco —yellow 2,13:1 · lime 2,44 · green 2,74 · cyan 3,04 ·
   orange 3,04 · azure 3,05 · teal 3,12, con el listón en 4,5:1— y la pasada de
   accesibilidad de agosto lo arregló poniendo el TEXTO oscuro. Eso resolvía el
   contraste quitando el color, que es justo lo que no se quería.

   El arreglo correcto es al revés: se OSCURECE EL TONO, no se cambia el texto.
   Cada uno de los siete se ha bajado hasta que el blanco puro pasa de 4,75:1,
   dejando el tono más claro que cumple —para no perder el color más de lo
   imprescindible—:

       azure  #4299e1 → #3376ad   4,84:1        orange #f76707 → #c15005   4,75:1
       teal   #0ca678 → #09815e   4,87:1        yellow #f59f00 → #9d6600   4,85:1
       green  #2fb344 → #228332   4,82:1        lime   #74b816 → #507f0f   4,79:1
       cyan   #17a2b8 → #127d8e   4,83:1

   `blue` (5,00:1), `indigo` (4,98), `purple` (4,85), `red` (4,66) y `pink`
   (4,62) ya pasan con blanco puro y NO se tocan: son los colores de marca.

   Se toca la variable del color, no la clase `.bg-<color>`, para que el tono
   nuevo llegue de una vez a todo lo que lo usa: fondos, botones (`btn-green`),
   badges, cintas, tintes `-lt` y el `-darken` del hover, que Tabler deriva por
   `color-mix` de esta misma variable. El fondo es el color, no el tema, así
   que un solo valor vale en claro y en oscuro.

   Y por eso `--tblr-<color>-fg` vuelve a ser BLANCO PURO —no `--tblr-light`,
   que es #f9fafb y resta un 2% de contraste—: escribir `text-white` a mano y
   dejar que lo ponga Tabler dan ya el mismo resultado correcto.
   -------------------------------------------------------------------------- */
/* El selector tiene que cubrir TAMBIÉN `[data-bs-theme]`, no solo `:root`.
   Tabler declara la paleta en `:root,[data-bs-theme=light]`, así que cualquier
   elemento con ese atributo —la barra lateral lo lleva— vuelve a declarar los
   colores viejos MÁS CERCA de la tarjeta, y por herencia gana el suyo. Con el
   atributo también aquí, el tono nuevo manda en los dos sitios. */
:root,
[data-bs-theme] {
    --tblr-azure:  #3376ad;
    --tblr-teal:   #09815e;
    --tblr-green:  #228332;
    --tblr-orange: #c15005;
    --tblr-yellow: #9d6600;
    --tblr-lime:   #507f0f;
    --tblr-cyan:   #127d8e;

    --tblr-azure-rgb:  51,118,173;
    --tblr-teal-rgb:   9,129,94;
    --tblr-green-rgb:  34,131,50;
    --tblr-orange-rgb: 193,80,5;
    --tblr-yellow-rgb: 157,102,0;
    --tblr-lime-rgb:   80,127,15;
    --tblr-cyan-rgb:   18,125,142;

    /* Los alias semánticos son EL MISMO COLOR con otro nombre, y Tabler los
       declara aparte: `success` es el verde, `warning` el amarillo e `info` el
       azure. Si no se bajan también, quien escribe el nombre de negocio —que es
       lo que pide cualquier guía— se lleva el tono viejo y 2,74:1. */
    --tblr-success:     #228332;
    --tblr-warning:     #9d6600;
    --tblr-info:        #3376ad;
    --tblr-success-rgb: 34,131,50;
    --tblr-warning-rgb: 157,102,0;
    --tblr-info-rgb:    51,118,173;

    /* Blanco puro sobre los doce. Ya no hay ninguno que no lo aguante. */
    --tblr-blue-fg:    #fff;
    --tblr-azure-fg:   #fff;
    --tblr-indigo-fg:  #fff;
    --tblr-purple-fg:  #fff;
    --tblr-pink-fg:    #fff;
    --tblr-red-fg:     #fff;
    --tblr-orange-fg:  #fff;
    --tblr-yellow-fg:  #fff;
    --tblr-lime-fg:    #fff;
    --tblr-green-fg:   #fff;
    --tblr-teal-fg:    #fff;
    --tblr-cyan-fg:    #fff;
    --tblr-primary-fg: #fff;
    --tblr-success-fg: #fff;
    --tblr-warning-fg: #fff;
    --tblr-danger-fg:  #fff;
    --tblr-info-fg:    #fff;
}

/* --------------------------------------------------------------------------
   El icono de un botón necesita su hueco

   Al pasar la intranet al juego de iconos de casa quedaron a la vista los
   botones cuyo icono no llevaba separación: «Pagar matrícula» se servía con la
   caja registradora pegada a la P. Antes tampoco la tenían, pero el icono de
   Font Awesome era más estrecho y disimulaba.

   Se resuelve aquí y no en doscientos sitios. Solo actúa si el icono NO trae
   ya su propio margen, así que no rompe nada de lo que estaba bien puesto.
   -------------------------------------------------------------------------- */
.btn > .ti:first-child:not(:only-child):not([class*="me-"]):not([class*="m-"]),
.dropdown-item > .ti:first-child:not(:only-child):not([class*="me-"]):not([class*="m-"]),
.nav-link > .ti:first-child:not(:only-child):not([class*="me-"]):not([class*="m-"]) {
    margin-inline-end: .375rem;
}

/* --------------------------------------------------------------------------
   Los desplegables de búsqueda (TomSelect) siguen el tema

   El tema oficial de TomSelect para Bootstrap 5 fija el color del texto a mano:

       .ts-control, .ts-control input, .ts-dropdown { color: #343a40 }

   Un gris oscuro para los dos temas. El fondo sí sale de una variable, así que
   en el tema oscuro quedaba texto gris oscuro sobre fondo oscuro. De ahí que
   tres pantallas lo parchearan por su cuenta forzando el fondo a blanco con
   `!important`: arreglaba la lectura, pero dejaba el desplegable siempre claro
   dentro de una intranet oscura.

   Aquí el texto sale del tema, y entonces el fondo puede salir también del
   tema. Los `!important` son para ganarle al `!important` del propio tema de
   TomSelect, no a Tabler.

   EXCEPCIÓN DECLARADA (kit de Elora): la bandeja de conversaciones incluye el
   parcial `intranet/partials/tomselect-theme`, que se carga DESPUÉS de esta hoja
   y con el mismo peso, así que en esa pantalla el desplegable sale blanco con
   texto oscuro en los dos temas (la caja sí sigue el tema). Medido en Chrome:
   fondo #ffffff y opciones #1e293b en claro y en oscuro. Es la interfaz de Elora
   tal como está en el origen; no se copia a otras pantallas. Ver la guía,
   «Excepciones declaradas».
   -------------------------------------------------------------------------- */
.ts-control,
.ts-control input,
.ts-dropdown {
    color: var(--tblr-body-color) !important;
    background-color: var(--tblr-bg-surface) !important;
}
.ts-dropdown {
    border-color: var(--tblr-border-color) !important;
    box-shadow: var(--tblr-box-shadow-lg);
}
.ts-dropdown .option:hover,
.ts-dropdown .option.active {
    background-color: color-mix(in oklab, var(--tblr-primary) 12%, var(--tblr-bg-surface)) !important;
    color: var(--tblr-body-color) !important;
}
.ts-dropdown .optgroup-header,
.ts-dropdown .no-results {
    color: var(--tblr-secondary) !important;
    background-color: var(--tblr-bg-surface-secondary) !important;
}
/* Lo que coincide con lo escrito: amarillo fijo sobre texto claro no se lee. */
.ts-dropdown [data-selectable] .highlight {
    background-color: color-mix(in oklab, var(--tblr-yellow) 35%, transparent);
    color: inherit;
}

/* --------------------------------------------------------------------------
   Utilidades que Tabler no trae y aquí hacen falta
   -------------------------------------------------------------------------- */

/* Borde discontinuo: lo piden los huecos vacíos del cuadrante y su leyenda.
   El `!important` es para ganarle al del atajo `.border`, no a nadie más. */
.border-dashed { border-style: dashed !important; }

/* El resalte de una cabecera de tabla ordenable. Iba con un negro al 3% que en
   el tema oscuro es invisible: sobre oscuro hay que ACLARAR, no oscurecer. */
.cursor-pointer { cursor: pointer; }
.cursor-pointer:hover,
table.js-sortable th:hover {
    background-color: color-mix(in oklab, var(--tblr-body-color) 6%, transparent);
}

/* --------------------------------------------------------------------------
   El color de un enlace en el tema oscuro

   Medido en el navegador sobre la tabla de alumnos: un enlace normal, sin
   ninguna clase, se sirve en `#066fd1` —el azul de marca— también con el tema
   en oscuro. Sobre el fondo de una tarjeta eso da **2,94:1**, cuando el mínimo
   de una lectura normal es 4,5.

   No es un descuido de una pantalla: son TODOS los enlaces de la intranet. El
   nombre de cada alumno del listado, las migas de pan, los enlaces de cada
   tabla. Tabler trae un azul más claro para el tema oscuro, pero en esta
   instalación su regla no llega a aplicarse y la variable se queda en el azul
   de marca.

   El documento del design system ya lo avisaba desde el principio: «el azul de
   marca #206bc4 da ~2,8:1 sobre gris oscuro — ilegible; en oscuro va el azul de
   enlace de Tabler, #6aa9e3». Faltaba que alguien lo aplicara.
   -------------------------------------------------------------------------- */
[data-bs-theme="dark"] {
    /* Con el tema oscuro el gris secundario de Tabler se aclara (gray-400) y
       el texto del botón se queda en blanco por defecto: 2,43:1 en «Cancelar»,
       «Hoy», «Exportar CSV». En tema claro el gris es más oscuro y el blanco
       sí vale, por eso esto va solo aquí. */
    --tblr-secondary-fg: var(--tblr-dark);
    /* El gris apagado no cambiaba con el tema: se quedaba en el del tema claro
       y sobre el fondo oscuro daba 3,04:1. Está en cientos de sitios. */
    --tblr-muted: #98a2b3;
    --tblr-secondary-color: #98a2b3;
    --tblr-link-color: #6aa9e3;
    --tblr-link-color-rgb: 106, 169, 227;
    --tblr-link-hover-color: #8dbde9;
    --tblr-link-hover-color-rgb: 141, 189, 233;
}

/* Los puntos suspensivos del paginador («… 8 9 10 …») iban en el gris de un
   elemento deshabilitado: 2,09:1 en claro y 3,15 en oscuro, medidos. No es un
   botón apagado, es un separador que hay que poder leer. */
.page-item.disabled .page-link,
.pagination .page-link.disabled {
    color: var(--tblr-secondary);
}

/* El aviso de «botón derecho sobre una fila para sus acciones» vive sobre la
   cabecera teñida de una tarjeta, y ahí `text-secondary` se quedaba en 4,39:1
   — a una centésima del mínimo. Sobre un fondo teñido, el texto de apoyo tira
   del color del cuerpo. */
.card-header:not([class*="bg-"]) .text-secondary:not(.text-white),
.card-subtitle:not(.text-white) {
    color: color-mix(in oklab, var(--tblr-body-color) 85%, transparent) !important;
}

/* Los enlaces del pie medían 16 px de alto: por debajo del mínimo que se puede
   acertar con el dedo o con un ratón con poca puntería (24 px, WCAG 2.2).
   Se les da altura sin moverlos de sitio. */
.footer .list-inline-item > a,
.footer-transparent .list-inline-item > a {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
}

/* Los badges «suaves» de Tabler (bg-green-lt y compañía) pintan el color PURO
   sobre un fondo que es ese mismo color al 10%. Medido: «Sin faltas» en verde
   daba 2,49:1 y «Leader» en azul 4,33:1. Están por toda la intranet.

   La salida es mezclar el color con el color del CUERPO: en tema claro el
   cuerpo es oscuro y lo oscurece, en oscuro es claro y lo aclara. Un solo
   bloque para los dos temas, y el color sigue siendo reconocible. */
.bg-blue-lt { color: color-mix(in oklab, var(--tblr-blue) 55%, var(--tblr-body-color)) !important; }
.bg-azure-lt { color: color-mix(in oklab, var(--tblr-azure) 45%, var(--tblr-body-color)) !important; }
.bg-indigo-lt { color: color-mix(in oklab, var(--tblr-indigo) 55%, var(--tblr-body-color)) !important; }
.bg-purple-lt { color: color-mix(in oklab, var(--tblr-purple) 55%, var(--tblr-body-color)) !important; }
.bg-pink-lt { color: color-mix(in oklab, var(--tblr-pink) 55%, var(--tblr-body-color)) !important; }
.bg-red-lt { color: color-mix(in oklab, var(--tblr-red) 40%, var(--tblr-body-color)) !important; }
.bg-orange-lt { color: color-mix(in oklab, var(--tblr-orange) 36%, var(--tblr-body-color)) !important; }
.bg-yellow-lt { color: color-mix(in oklab, var(--tblr-yellow) 40%, var(--tblr-body-color)) !important; }
.bg-lime-lt { color: color-mix(in oklab, var(--tblr-lime) 40%, var(--tblr-body-color)) !important; }
.bg-green-lt { color: color-mix(in oklab, var(--tblr-green) 45%, var(--tblr-body-color)) !important; }
.bg-teal-lt { color: color-mix(in oklab, var(--tblr-teal) 45%, var(--tblr-body-color)) !important; }
.bg-cyan-lt { color: color-mix(in oklab, var(--tblr-cyan) 45%, var(--tblr-body-color)) !important; }
.bg-primary-lt { color: color-mix(in oklab, var(--tblr-primary) 55%, var(--tblr-body-color)) !important; }
.bg-secondary-lt { color: color-mix(in oklab, var(--tblr-secondary) 55%, var(--tblr-body-color)) !important; }
.bg-success-lt { color: color-mix(in oklab, var(--tblr-success) 45%, var(--tblr-body-color)) !important; }
.bg-warning-lt { color: color-mix(in oklab, var(--tblr-warning) 32%, var(--tblr-body-color)) !important; }
.bg-danger-lt { color: color-mix(in oklab, var(--tblr-danger) 55%, var(--tblr-body-color)) !important; }
.bg-info-lt { color: color-mix(in oklab, var(--tblr-info) 55%, var(--tblr-body-color)) !important; }

/* Los enlaces de la miga de pan medían 20x14: por debajo del mínimo pulsable.
   El primero es solo un icono de casa, y de ancho tampoco llegaba. */
.breadcrumb-item > a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 24px;
    min-width: 24px;
}

/* Los colores de Tabler no cambian con el tema: el primario sigue siendo el
   mismo azul con el fondo oscuro detrás. Medido: «Editar texto» y «Categorías»
   a 2,94:1, «Eliminar» en rojo a 3,15:1, «Validez terminada» a 3,54:1.

   Misma salida que en los badges suaves: mezclar el color con el color del
   CUERPO. En tema claro lo oscurece, en oscuro lo aclara, y el resultado sigue
   siendo azul, rojo o verde. Una regla por color, válida para los dos temas. */
.text-blue { color: color-mix(in oklab, var(--tblr-blue) 55%, var(--tblr-body-color)) !important; }
.text-azure { color: color-mix(in oklab, var(--tblr-azure) 48%, var(--tblr-body-color)) !important; }
.text-indigo { color: color-mix(in oklab, var(--tblr-indigo) 55%, var(--tblr-body-color)) !important; }
.text-purple { color: color-mix(in oklab, var(--tblr-purple) 55%, var(--tblr-body-color)) !important; }
.text-pink { color: color-mix(in oklab, var(--tblr-pink) 55%, var(--tblr-body-color)) !important; }
.text-red { color: color-mix(in oklab, var(--tblr-red) 50%, var(--tblr-body-color)) !important; }
.text-orange { color: color-mix(in oklab, var(--tblr-orange) 48%, var(--tblr-body-color)) !important; }
.text-yellow { color: color-mix(in oklab, var(--tblr-yellow) 38%, var(--tblr-body-color)) !important; }
.text-lime { color: color-mix(in oklab, var(--tblr-lime) 38%, var(--tblr-body-color)) !important; }
.text-green { color: color-mix(in oklab, var(--tblr-green) 42%, var(--tblr-body-color)) !important; }
.text-teal { color: color-mix(in oklab, var(--tblr-teal) 48%, var(--tblr-body-color)) !important; }
.text-cyan { color: color-mix(in oklab, var(--tblr-cyan) 48%, var(--tblr-body-color)) !important; }
.text-primary { color: color-mix(in oklab, var(--tblr-primary) 55%, var(--tblr-body-color)) !important; }
.text-success { color: color-mix(in oklab, var(--tblr-success) 42%, var(--tblr-body-color)) !important; }
.text-warning { color: color-mix(in oklab, var(--tblr-warning) 34%, var(--tblr-body-color)) !important; }
.text-danger { color: color-mix(in oklab, var(--tblr-danger) 50%, var(--tblr-body-color)) !important; }
.text-info { color: color-mix(in oklab, var(--tblr-info) 48%, var(--tblr-body-color)) !important; }

/* Y lo mismo para los botones que se pintan con el color en el texto:
   el de contorno y el de enlace. Aquí el color va por variable. */
.btn-outline-blue { --tblr-btn-color: color-mix(in oklab, var(--tblr-blue) 55%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-blue) 55%, var(--tblr-body-color)); }
.btn-outline-azure { --tblr-btn-color: color-mix(in oklab, var(--tblr-azure) 48%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-azure) 48%, var(--tblr-body-color)); }
.btn-outline-indigo { --tblr-btn-color: color-mix(in oklab, var(--tblr-indigo) 55%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-indigo) 55%, var(--tblr-body-color)); }
.btn-outline-purple { --tblr-btn-color: color-mix(in oklab, var(--tblr-purple) 55%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-purple) 55%, var(--tblr-body-color)); }
.btn-outline-pink { --tblr-btn-color: color-mix(in oklab, var(--tblr-pink) 55%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-pink) 55%, var(--tblr-body-color)); }
.btn-outline-red { --tblr-btn-color: color-mix(in oklab, var(--tblr-red) 65%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-red) 65%, var(--tblr-body-color)); }
.btn-outline-orange { --tblr-btn-color: color-mix(in oklab, var(--tblr-orange) 48%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-orange) 48%, var(--tblr-body-color)); }
.btn-outline-yellow { --tblr-btn-color: color-mix(in oklab, var(--tblr-yellow) 38%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-yellow) 38%, var(--tblr-body-color)); }
.btn-outline-lime { --tblr-btn-color: color-mix(in oklab, var(--tblr-lime) 38%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-lime) 38%, var(--tblr-body-color)); }
.btn-outline-green { --tblr-btn-color: color-mix(in oklab, var(--tblr-green) 42%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-green) 42%, var(--tblr-body-color)); }
.btn-outline-teal { --tblr-btn-color: color-mix(in oklab, var(--tblr-teal) 48%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-teal) 48%, var(--tblr-body-color)); }
.btn-outline-cyan { --tblr-btn-color: color-mix(in oklab, var(--tblr-cyan) 48%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-cyan) 48%, var(--tblr-body-color)); }
.btn-outline-primary { --tblr-btn-color: color-mix(in oklab, var(--tblr-primary) 55%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-primary) 55%, var(--tblr-body-color)); }
.btn-outline-success { --tblr-btn-color: color-mix(in oklab, var(--tblr-success) 42%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-success) 42%, var(--tblr-body-color)); }
.btn-outline-warning { --tblr-btn-color: color-mix(in oklab, var(--tblr-warning) 48%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-warning) 48%, var(--tblr-body-color)); }
.btn-outline-danger { --tblr-btn-color: color-mix(in oklab, var(--tblr-danger) 65%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-danger) 65%, var(--tblr-body-color)); }
.btn-outline-info { --tblr-btn-color: color-mix(in oklab, var(--tblr-info) 48%, var(--tblr-body-color)); --tblr-btn-border-color: color-mix(in oklab, var(--tblr-info) 48%, var(--tblr-body-color)); }
.btn-link { --tblr-btn-color: var(--tblr-link-color); --tblr-btn-hover-color: var(--tblr-link-hover-color); }

/* El botón que en realidad es un enlace («Volver al listado», «Cancelar»): algo
   le estaba pisando el color y se quedaba en un azul que no cambiaba con el
   tema, 3,55:1 sobre el fondo oscuro. Se le impone el color de enlace, que sí
   está resuelto para los dos temas. */
.btn-link,
a.btn-link {
    color: var(--tblr-link-color) !important;
}
.btn-link:hover,
a.btn-link:hover {
    color: var(--tblr-link-hover-color) !important;
}

/* Los complementos de un campo («€/h», «%», «€») iban en --tblr-gray-500, un
   gris fijo que no sigue el tema: 3,67:1 sobre el fondo oscuro. */
.input-group-text {
    color: color-mix(in oklab, var(--tblr-body-color) 78%, transparent);
}


/* El botón «fantasma» se pinta con el color en el texto, igual que el de
   contorno: misma mezcla con el color del cuerpo. */
.btn-ghost-blue { --tblr-btn-color: color-mix(in oklab, var(--tblr-blue) 55%, var(--tblr-body-color)); }
.btn-ghost-azure { --tblr-btn-color: color-mix(in oklab, var(--tblr-azure) 48%, var(--tblr-body-color)); }
.btn-ghost-indigo { --tblr-btn-color: color-mix(in oklab, var(--tblr-indigo) 55%, var(--tblr-body-color)); }
.btn-ghost-purple { --tblr-btn-color: color-mix(in oklab, var(--tblr-purple) 55%, var(--tblr-body-color)); }
.btn-ghost-pink { --tblr-btn-color: color-mix(in oklab, var(--tblr-pink) 55%, var(--tblr-body-color)); }
.btn-ghost-red { --tblr-btn-color: color-mix(in oklab, var(--tblr-red) 65%, var(--tblr-body-color)); }
.btn-ghost-orange { --tblr-btn-color: color-mix(in oklab, var(--tblr-orange) 48%, var(--tblr-body-color)); }
.btn-ghost-yellow { --tblr-btn-color: color-mix(in oklab, var(--tblr-yellow) 38%, var(--tblr-body-color)); }
.btn-ghost-lime { --tblr-btn-color: color-mix(in oklab, var(--tblr-lime) 38%, var(--tblr-body-color)); }
.btn-ghost-green { --tblr-btn-color: color-mix(in oklab, var(--tblr-green) 42%, var(--tblr-body-color)); }
.btn-ghost-teal { --tblr-btn-color: color-mix(in oklab, var(--tblr-teal) 48%, var(--tblr-body-color)); }
.btn-ghost-cyan { --tblr-btn-color: color-mix(in oklab, var(--tblr-cyan) 48%, var(--tblr-body-color)); }
.btn-ghost-primary { --tblr-btn-color: color-mix(in oklab, var(--tblr-primary) 55%, var(--tblr-body-color)); }
.btn-ghost-success { --tblr-btn-color: color-mix(in oklab, var(--tblr-success) 42%, var(--tblr-body-color)); }
.btn-ghost-warning { --tblr-btn-color: color-mix(in oklab, var(--tblr-warning) 48%, var(--tblr-body-color)); }
.btn-ghost-danger { --tblr-btn-color: color-mix(in oklab, var(--tblr-danger) 65%, var(--tblr-body-color)); }
.btn-ghost-info { --tblr-btn-color: color-mix(in oklab, var(--tblr-info) 48%, var(--tblr-body-color)); }
.btn-ghost-secondary { --tblr-btn-color: color-mix(in oklab, var(--tblr-secondary) 65%, var(--tblr-body-color)); }

/* Y el gris apagado del tema CLARO: #6b7280 sobre una tarjeta gris se queda en
   4,28:1. Es el color de texto secundario más usado del proyecto, así que
   merece cumplir también sobre fondos que no son blancos.

   Va acotado al tema claro: `:root` a secas empata en peso con el bloque del
   tema oscuro y, por ir después en el fichero, le ganaba — dejando el gris
   oscuro sobre el fondo oscuro, en 2,45:1. */
:root:not([data-bs-theme="dark"]) {
    --tblr-muted: #5b6472;
    --tblr-secondary-color: #5b6472;
}

/* El texto secundario tira de --tblr-secondary, que es a la vez el color de
   FONDO del botón secundario: no se puede oscurecer la variable sin cambiar
   botones. Se oscurece solo cuando se usa como texto, con la misma mezcla que
   el resto. Sobre una tarjeta gris daba 4,20:1, y son cientos de usos. */
.text-secondary {
    color: color-mix(in oklab, var(--tblr-secondary) 62%, var(--tblr-body-color)) !important;
}


/* La caja de una gráfica: estaba escrita a mano cuatro veces en la misma
   pantalla, con la clase sin declarar en ninguna parte. Ahora la clase pinta y
   el estilo en línea sobra. */
.chart-container {
    position: relative;
    height: 200px;
}

/* Un contador blanco dentro de una cabecera de color: el fondo del badge es
   BLANCO fijo, no sigue el tema. Ahí la mezcla con el color del cuerpo juega en
   contra —con el tema oscuro aclara el texto y lo deja en 2,83:1 sobre blanco—,
   así que sobre un fondo fijo claro el texto se oscurece siempre, y al revés
   sobre uno fijo oscuro. El patrón está en siete pantallas. */
.bg-white.text-blue, .bg-white .text-blue, .bg-light.text-blue, .bg-light .text-blue { color: color-mix(in oklab, var(--tblr-blue) 62%, #182433) !important; }
.bg-white.text-azure, .bg-white .text-azure, .bg-light.text-azure, .bg-light .text-azure { color: color-mix(in oklab, var(--tblr-azure) 62%, #182433) !important; }
.bg-white.text-indigo, .bg-white .text-indigo, .bg-light.text-indigo, .bg-light .text-indigo { color: color-mix(in oklab, var(--tblr-indigo) 62%, #182433) !important; }
.bg-white.text-purple, .bg-white .text-purple, .bg-light.text-purple, .bg-light .text-purple { color: color-mix(in oklab, var(--tblr-purple) 62%, #182433) !important; }
.bg-white.text-pink, .bg-white .text-pink, .bg-light.text-pink, .bg-light .text-pink { color: color-mix(in oklab, var(--tblr-pink) 62%, #182433) !important; }
.bg-white.text-red, .bg-white .text-red, .bg-light.text-red, .bg-light .text-red { color: color-mix(in oklab, var(--tblr-red) 62%, #182433) !important; }
.bg-white.text-orange, .bg-white .text-orange, .bg-light.text-orange, .bg-light .text-orange { color: color-mix(in oklab, var(--tblr-orange) 62%, #182433) !important; }
.bg-white.text-yellow, .bg-white .text-yellow, .bg-light.text-yellow, .bg-light .text-yellow { color: color-mix(in oklab, var(--tblr-yellow) 62%, #182433) !important; }
.bg-white.text-lime, .bg-white .text-lime, .bg-light.text-lime, .bg-light .text-lime { color: color-mix(in oklab, var(--tblr-lime) 62%, #182433) !important; }
.bg-white.text-green, .bg-white .text-green, .bg-light.text-green, .bg-light .text-green { color: color-mix(in oklab, var(--tblr-green) 62%, #182433) !important; }
.bg-white.text-teal, .bg-white .text-teal, .bg-light.text-teal, .bg-light .text-teal { color: color-mix(in oklab, var(--tblr-teal) 62%, #182433) !important; }
.bg-white.text-cyan, .bg-white .text-cyan, .bg-light.text-cyan, .bg-light .text-cyan { color: color-mix(in oklab, var(--tblr-cyan) 62%, #182433) !important; }
.bg-white.text-primary, .bg-white .text-primary, .bg-light.text-primary, .bg-light .text-primary { color: color-mix(in oklab, var(--tblr-primary) 62%, #182433) !important; }
.bg-white.text-success, .bg-white .text-success, .bg-light.text-success, .bg-light .text-success { color: color-mix(in oklab, var(--tblr-success) 62%, #182433) !important; }
.bg-white.text-warning, .bg-white .text-warning, .bg-light.text-warning, .bg-light .text-warning { color: color-mix(in oklab, var(--tblr-warning) 62%, #182433) !important; }
.bg-white.text-danger, .bg-white .text-danger, .bg-light.text-danger, .bg-light .text-danger { color: color-mix(in oklab, var(--tblr-danger) 62%, #182433) !important; }
.bg-white.text-info, .bg-white .text-info, .bg-light.text-info, .bg-light .text-info { color: color-mix(in oklab, var(--tblr-info) 62%, #182433) !important; }
.bg-dark .text-blue { color: color-mix(in oklab, var(--tblr-blue) 62%, #f8fafc) !important; }
.bg-dark .text-azure { color: color-mix(in oklab, var(--tblr-azure) 62%, #f8fafc) !important; }
.bg-dark .text-indigo { color: color-mix(in oklab, var(--tblr-indigo) 62%, #f8fafc) !important; }
.bg-dark .text-purple { color: color-mix(in oklab, var(--tblr-purple) 62%, #f8fafc) !important; }
.bg-dark .text-pink { color: color-mix(in oklab, var(--tblr-pink) 62%, #f8fafc) !important; }
.bg-dark .text-red { color: color-mix(in oklab, var(--tblr-red) 62%, #f8fafc) !important; }
.bg-dark .text-orange { color: color-mix(in oklab, var(--tblr-orange) 62%, #f8fafc) !important; }
.bg-dark .text-yellow { color: color-mix(in oklab, var(--tblr-yellow) 62%, #f8fafc) !important; }
.bg-dark .text-lime { color: color-mix(in oklab, var(--tblr-lime) 62%, #f8fafc) !important; }
.bg-dark .text-green { color: color-mix(in oklab, var(--tblr-green) 62%, #f8fafc) !important; }
.bg-dark .text-teal { color: color-mix(in oklab, var(--tblr-teal) 62%, #f8fafc) !important; }
.bg-dark .text-cyan { color: color-mix(in oklab, var(--tblr-cyan) 62%, #f8fafc) !important; }
.bg-dark .text-primary { color: color-mix(in oklab, var(--tblr-primary) 62%, #f8fafc) !important; }
.bg-dark .text-success { color: color-mix(in oklab, var(--tblr-success) 62%, #f8fafc) !important; }
.bg-dark .text-warning { color: color-mix(in oklab, var(--tblr-warning) 62%, #f8fafc) !important; }
.bg-dark .text-danger { color: color-mix(in oklab, var(--tblr-danger) 62%, #f8fafc) !important; }
.bg-dark .text-info { color: color-mix(in oklab, var(--tblr-info) 62%, #f8fafc) !important; }

/* Lo que se elige en un desplegable de varios: el chip del propio TomSelect. */
.ts-wrapper .ts-control > .item {
    background: var(--tblr-primary-lt);
    /* El azul puro sobre su propio tinte se queda en 4,33:1. */
    color: color-mix(in oklab, var(--tblr-primary) 55%, var(--tblr-body-color));
    border: 1px solid var(--tblr-primary-lt);
}

/* `btn-outline-light` se pinta con --tblr-light, que es casi blanco: sobre una
   cabecera de tarjeta blanca el botón desaparece —«Análisis recientes» medía
   1,05:1, literalmente invisible—. El claro solo funciona sobre un fondo
   oscuro, y aquí el fondo es el del tema. Se pinta con el color del cuerpo, que
   sí cambia con él. */
.btn-outline-light {
    --tblr-btn-color: var(--tblr-body-color);
    --tblr-btn-border-color: var(--tblr-border-color);
    --tblr-btn-hover-color: var(--tblr-body-color);
    --tblr-btn-hover-bg: var(--tblr-bg-surface-secondary);
    --tblr-btn-hover-border-color: var(--tblr-border-color);
    --tblr-btn-active-color: var(--tblr-body-color);
    --tblr-btn-active-bg: var(--tblr-bg-surface-secondary);
}

/* La opción marcada de un grupo de selección se titula con el azul primario
   puro, que sobre el fondo oscuro se queda en 2,85:1. Misma mezcla que el
   resto de colores de texto. */
.form-selectgroup-boxes .form-selectgroup-input:checked + .form-selectgroup-label .form-selectgroup-title,
.form-selectgroup-input:checked + .form-selectgroup-label {
    color: color-mix(in oklab, var(--tblr-primary) 55%, var(--tblr-body-color));
}

/* ── El botón de icono medía 2 píxeles ─────────────────────────────────────
   Tabler compensa el relleno lateral del botón con un margen NEGATIVO en el
   icono: `.btn-icon .icon { margin: calc(-1 * var(--tblr-btn-padding-x)) }`.
   Pero `.btn-icon` ya deja ese relleno a cero, así que el margen no compensa
   nada: se come el ancho del icono y deja el botón en los 2 px de su borde.

   Medido en el navegador: el botón `2x36` con `width: 2px`, y su icono dentro
   `16x16`. En la pantalla se ven rayitas verticales de color donde tendría que
   haber un botón de editar y uno de borrar. Son 82 botones en la intranet.

   Con el margen a cero el icono ya se ve, pero el botón queda estrecho (18x36)
   porque `.btn-sm` deja el ancho mínimo en auto: se le pide que sea cuadrado. */
.btn-icon .icon {
    margin: 0;
}
.btn-icon {
    aspect-ratio: 1;
}

/* Con los botones de icono ya a su tamaño, dos de ellos no caben en una celda
   de acciones estrecha y `btn-list` los partía en dos líneas, doblando la
   altura de la fila. Dentro de una tabla, las acciones van en una sola línea. */
td > .btn-list,
th > .btn-list {
    flex-wrap: nowrap;
    justify-content: center;
}

/* ── Distintivo con un color que viene de la base ──────────────────────────
   Las categorías de compras guardan su color en la ficha, y las vistas lo
   pintaban así: fondo al 15% y texto con el color PURO. Con un amarillo eso da
   1,56:1 — el nombre de la categoría no se lee. Y una vista llegaba a construir
   la clase `text-#FFC107-fg`, que no existe.

   Se le pasa el color por variable y aquí se resuelven las dos capas, con el
   mismo criterio que el resto: el texto se mezcla con el color del cuerpo, así
   que se oscurece en tema claro y se aclara en el oscuro.

       <span class="badge distintivo-color" style="--color-dato: #ffc107">
*/
.distintivo-color {
    background-color: color-mix(in oklab, var(--color-dato, var(--tblr-secondary)) 12%, transparent) !important;
    color: color-mix(in oklab, var(--color-dato, var(--tblr-secondary)) 32%, var(--tblr-body-color)) !important;
}

/* El botón marcado de un grupo («Grid» / «Lista») se pinta con el azul puro:
   3,45:1 sobre el fondo oscuro. Misma mezcla que el resto. */
.btn {
    --tblr-btn-active-color: color-mix(in oklab, var(--tblr-primary) 55%, var(--tblr-body-color));
}

/* Una tecla escrita en pantalla («Ctrl ⇧ E», «Enter»): la usan los atajos de la
   barra y la pista de teclado del compositor de Elora. Va oscura en los dos
   temas; el gris del tema oscuro es la pareja del `--tblr-dark` del claro. */
kbd {
    padding: 0.3rem 0.6rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--tblr-light);
    background-color: var(--tblr-dark);
    border-radius: 0.375rem;
    box-shadow: 0 2px 4px color-mix(in srgb, black 20%, transparent);
}

html[data-bs-theme="dark"] kbd {
    background-color: #475569;
}


/* ── Todo lo que va encima de un color pleno se escribe en blanco ──────────
   La cabecera de color pleno es el patrón de la casa (decisión de dirección,
   6-sep-2026) y los tonos ya están bajados arriba para que el blanco pase de
   4,75:1. Lo que faltaba era que TODO lo de dentro fuese blanco: el título lo
   era, pero el subtítulo, el texto de apoyo y los rótulos tiran de
   `--tblr-body-color` o de `--tblr-secondary`, que con el tema claro son
   grises oscuros y sobre el color se hunden por debajo de 2:1.

   Antes aquí se hacía lo contrario —se devolvía el texto OSCURO a los siete
   colores claros—. Eso se retira: el contraste se arregla bajando el tono, no
   quitando el color. */
:is(.bg-blue, .bg-azure, .bg-indigo, .bg-purple, .bg-pink, .bg-red,
    .bg-orange, .bg-yellow, .bg-lime, .bg-green, .bg-teal, .bg-cyan,
    .bg-primary, .bg-success, .bg-warning, .bg-danger, .bg-info) {
    color: #fff;
}

:is(.bg-blue, .bg-azure, .bg-indigo, .bg-purple, .bg-pink, .bg-red,
    .bg-orange, .bg-yellow, .bg-lime, .bg-green, .bg-teal, .bg-cyan,
    .bg-primary, .bg-success, .bg-warning, .bg-danger, .bg-info)
:is(.card-title, .card-subtitle, .card-actions, .subheader, .text-secondary,
    .text-muted, .text-white, .form-label, .form-hint, h1, h2, h3, h4, h5, h6,
    small, label, p, span:not(.badge):not([class*="bg-"]), svg, i,
    a:not(.btn):not(.badge)) {
    color: #fff !important;
}

/* Un botón dentro de una cabecera de color: el de contorno se pinta con el
   color del cuerpo, que sobre el color pleno no se ve. Se pasa a blanco. */
:is(.bg-blue, .bg-azure, .bg-indigo, .bg-purple, .bg-pink, .bg-red,
    .bg-orange, .bg-yellow, .bg-lime, .bg-green, .bg-teal, .bg-cyan,
    .bg-primary, .bg-success, .bg-warning, .bg-danger, .bg-info)
:is(.btn-outline-secondary, .btn-ghost-secondary, .btn-link) {
    --tblr-btn-color: #fff;
    --tblr-btn-border-color: rgba(255, 255, 255, .5);
    --tblr-btn-hover-color: #fff;
    --tblr-btn-hover-bg: rgba(255, 255, 255, .18);
    --tblr-btn-hover-border-color: #fff;
    --tblr-btn-active-color: #fff;
    --tblr-btn-active-bg: rgba(255, 255, 255, .28);
}

/* Un tinte suave dentro de una fila de color: el fondo del badge es
   transparente, así que se mezcla con el de la fila y el texto se pierde
   —«extranjeros» en morado sobre una fila rosa daba 1,62:1—. Se le da fondo
   opaco sobre la superficie de la tarjeta, que es lo que aparenta ser. */
.badge[class*="-lt"] {
    background-color: color-mix(in oklab, var(--tblr-bg-surface) 88%, currentColor) !important;
}

/* Las iniciales de un avatar con fondo de color heredaban el gris del texto
   normal: «SE» en gris sobre azul, 1,31:1. */
.avatar[class*="bg-"]:not(.bg-white):not([class*="-lt"]) {
    color: var(--tblr-light);
}

/* El botón de contorno secundario se pintaba con el color de enlace sobre el
   gris del propio botón: 1,02:1 en «Todas». */
.btn-outline-secondary {
    --tblr-btn-color: var(--tblr-body-color);
    --tblr-btn-border-color: var(--tblr-border-color);
    --tblr-btn-hover-color: var(--tblr-body-color);
    --tblr-btn-active-color: var(--tblr-body-color);
}

/* El rótulo de sección y el texto de ayuda de un campo tiran de
   --tblr-secondary, que como texto se queda corto: 4,38:1 y 4,19:1. Mismo
   criterio que .text-secondary. */
.subheader,
.form-hint {
    color: color-mix(in oklab, var(--tblr-secondary) 62%, var(--tblr-body-color));
}

/* Con el tema oscuro el gris secundario se aclara, así que un `text-white`
   escrito a mano encima da 2,54:1 («Descartada»). Es el mismo caso que los diez
   colores claros, pero el gris cambia de bando según el tema. */
[data-bs-theme="dark"] .bg-secondary.text-white,
[data-bs-theme="dark"] .bg-secondary .text-white {
    color: var(--tblr-dark) !important;
}

/* Una fila resaltada (`table-warning`, `table-success`…) tiene fondo CLARO fijo
   en los dos temas, y Tabler le pone texto oscuro. Pero `.text-secondary` y
   `.text-muted` llevan !important, así que con el tema oscuro lo aclaraban y la
   fecha de una fila amarilla quedaba en 1,64:1. Dentro de esas filas mandan los
   colores de la fila. Hay 33 vistas con filas así. */
tr[class*="table-"] .text-secondary,
tr[class*="table-"] .text-muted,
tr[class*="table-"] .subheader,
tr[class*="table-"] .form-hint {
    color: color-mix(in oklab, var(--tblr-table-color, var(--tblr-body-color)) 78%, transparent) !important;
}

/* `bg-light` y `bg-white` son fondos CLAROS fijos: no siguen el tema, así que
   su texto tampoco puede seguirlo. Una tarjeta con el concepto de una remesa
   dentro quedaba en 1,18:1 — texto claro sobre casi blanco. Y al revés con
   `bg-dark`, que es oscuro siempre. */
.bg-light,
.bg-white:not(.badge) {
    color: var(--tblr-dark);
}
.bg-dark:not(.badge) {
    color: var(--tblr-light);
}

/* Dentro de una fila resaltada, que es clara en los dos temas, los botones de
   color también tienen que oscurecerse: «Gestionar» sobre una fila verde daba
   2,06:1 con el tema oscuro. Misma razón que el texto. */
tr[class*="table-"] [class*="btn-ghost-"],
tr[class*="table-"] [class*="btn-outline-"] {
    --tblr-btn-color: color-mix(in oklab, currentColor 30%, var(--tblr-table-color, var(--tblr-dark)));
}

/* …pero dentro de una cabecera con color pleno el botón claro SÍ es lo correcto:
   ahí el fondo es naranja o azul, no el del tema. Al pintarlo con el color del
   cuerpo se quedaba en 3,39:1 sobre el naranja. */
.card-header[class*="bg-"]:not([class*="-lt"]):not(.bg-white):not(.bg-light):not(.bg-transparent) [class*="btn-outline-"],
.card-header[class*="bg-"]:not([class*="-lt"]):not(.bg-white):not(.bg-light):not(.bg-transparent) [class*="btn-ghost-"],
.page-header[class*="bg-"]:not([class*="-lt"]):not(.bg-white):not(.bg-light) [class*="btn-outline-"] {
    /* Hereda el color de su cabecera en vez de traer el suyo: sobre naranja el
       blanco NO llega al mínimo (2,91:1 medido) y un botón AZUL sobre una
       cabecera turquesa se queda en 1,25:1. La cabecera ya tiene resuelto arriba
       qué color de texto aguanta su fondo; los botones de dentro lo usan. */
    color: inherit !important;
    --tblr-btn-border-color: color-mix(in oklab, currentColor 55%, transparent);
    --tblr-btn-hover-bg: color-mix(in oklab, currentColor 18%, transparent);
}

/* Los paneles deslizantes (chat y Elora) se aparcan fuera de la pantalla con un
   desplazamiento a la derecha, y eso deja la página con barra horizontal: el
   navegador cuenta ese ancho aunque no se vea nada ahí. `clip` en vez de
   `hidden` porque no crea un contexto de scroll nuevo y no rompe lo que se
   queda pegado arriba al bajar. */
html,
body {
    overflow-x: clip;
}

/* Una MUESTRA de color: el cuadrito con el color, y su código escrito al lado
   en el color del texto normal. Antes el código iba escrito ENCIMA del propio
   color, que es la manera segura de que no se lea: «#ffffff» en blanco sobre
   blanco. Un color se enseña, no se escribe encima de sí mismo. */
.muestra-color {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-variant-numeric: tabular-nums;
}
.muestra-color::before {
    content: '';
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 4px;
    background-color: var(--color-dato, var(--tblr-border-color));
    border: 1px solid var(--tblr-border-color);
    flex: 0 0 auto;
}

/* Un avatar sin foto se pintaba casi negro también con el tema claro, y sus
   iniciales en gris encima: 3,12:1. El hueco de la foto tiene que seguir el
   tema, igual que todo lo demás, y las iniciales ir en el color del cuerpo. */
/* Tabler declara --tblr-avatar-bg DENTRO de `.avatar`, así que ponerla en el
   bloque del tema no le llega: hay que declararla con la misma especificidad.
   Y el color de las iniciales es --tblr-secondary, que sobre ese fondo se
   queda corto. */
.avatar:not([class*="bg-"]):not([style*="background"]) {
    --tblr-avatar-bg: var(--tblr-bg-surface-secondary);
    color: var(--tblr-body-color);
}

/* Un enlace dentro de una fila resaltada: la fila es clara en los dos temas y el
   azul de enlace del tema oscuro encima daba 1,86:1. Mismo criterio que su
   texto: dentro de esas filas mandan los colores de la fila. */
tr[class*="table-"] a:not(.btn) {
    color: color-mix(in oklab, var(--tblr-blue) 62%, var(--tblr-table-color, var(--tblr-dark)));
}

/* El botón de un grupo de opciones cuando está marcado: usa su propia variable
   de color activo, que se quedaba en el claro sobre el gris (2,05:1). */
.btn-outline-secondary,
.btn-check:checked + .btn-outline-secondary {
    --tblr-btn-active-color: var(--tblr-body-color);
    --tblr-btn-active-bg: var(--tblr-bg-surface-secondary);
}

/* Dentro de una fila resaltada mandan los colores de la fila, y eso vale también
   para el texto de color: «Eliminado por…» en rojo sobre una fila roja clara
   daba 1,69:1. Se oscurece contra el color de texto de la propia fila. */
tr[class*="table-"] .text-blue:not([class*="-fg"]),
tr[class*="table-"] .text-azure:not([class*="-fg"]),
tr[class*="table-"] .text-indigo:not([class*="-fg"]),
tr[class*="table-"] .text-purple:not([class*="-fg"]),
tr[class*="table-"] .text-pink:not([class*="-fg"]),
tr[class*="table-"] .text-red:not([class*="-fg"]),
tr[class*="table-"] .text-orange:not([class*="-fg"]),
tr[class*="table-"] .text-yellow:not([class*="-fg"]),
tr[class*="table-"] .text-lime:not([class*="-fg"]),
tr[class*="table-"] .text-green:not([class*="-fg"]),
tr[class*="table-"] .text-teal:not([class*="-fg"]),
tr[class*="table-"] .text-cyan:not([class*="-fg"]),
tr[class*="table-"] .text-primary:not([class*="-fg"]),
tr[class*="table-"] .text-success:not([class*="-fg"]),
tr[class*="table-"] .text-warning:not([class*="-fg"]),
tr[class*="table-"] .text-danger:not([class*="-fg"]),
tr[class*="table-"] .text-info:not([class*="-fg"]) {
    color: color-mix(in oklab, currentColor 45%, var(--tblr-table-color, var(--tblr-dark))) !important;
}

/* El botón fantasma MARCADO se rellena con su color, así que su texto tiene que
   ser el de contraste de ese color y no el color mezclado: «Todos (87)» daba
   1,38:1, azul sobre azul. */
.btn-ghost-blue.active, .btn-ghost-blue:active { --tblr-btn-active-color: var(--tblr-blue-fg); --tblr-btn-active-bg: var(--tblr-blue); }
.btn-ghost-azure.active, .btn-ghost-azure:active { --tblr-btn-active-color: var(--tblr-azure-fg); --tblr-btn-active-bg: var(--tblr-azure); }
.btn-ghost-indigo.active, .btn-ghost-indigo:active { --tblr-btn-active-color: var(--tblr-indigo-fg); --tblr-btn-active-bg: var(--tblr-indigo); }
.btn-ghost-purple.active, .btn-ghost-purple:active { --tblr-btn-active-color: var(--tblr-purple-fg); --tblr-btn-active-bg: var(--tblr-purple); }
.btn-ghost-pink.active, .btn-ghost-pink:active { --tblr-btn-active-color: var(--tblr-pink-fg); --tblr-btn-active-bg: var(--tblr-pink); }
.btn-ghost-red.active, .btn-ghost-red:active { --tblr-btn-active-color: var(--tblr-red-fg); --tblr-btn-active-bg: var(--tblr-red); }
.btn-ghost-orange.active, .btn-ghost-orange:active { --tblr-btn-active-color: var(--tblr-orange-fg); --tblr-btn-active-bg: var(--tblr-orange); }
.btn-ghost-yellow.active, .btn-ghost-yellow:active { --tblr-btn-active-color: var(--tblr-yellow-fg); --tblr-btn-active-bg: var(--tblr-yellow); }
.btn-ghost-lime.active, .btn-ghost-lime:active { --tblr-btn-active-color: var(--tblr-lime-fg); --tblr-btn-active-bg: var(--tblr-lime); }
.btn-ghost-green.active, .btn-ghost-green:active { --tblr-btn-active-color: var(--tblr-green-fg); --tblr-btn-active-bg: var(--tblr-green); }
.btn-ghost-teal.active, .btn-ghost-teal:active { --tblr-btn-active-color: var(--tblr-teal-fg); --tblr-btn-active-bg: var(--tblr-teal); }
.btn-ghost-cyan.active, .btn-ghost-cyan:active { --tblr-btn-active-color: var(--tblr-cyan-fg); --tblr-btn-active-bg: var(--tblr-cyan); }
.btn-ghost-primary.active, .btn-ghost-primary:active { --tblr-btn-active-color: var(--tblr-primary-fg); --tblr-btn-active-bg: var(--tblr-primary); }
.btn-ghost-success.active, .btn-ghost-success:active { --tblr-btn-active-color: var(--tblr-success-fg); --tblr-btn-active-bg: var(--tblr-success); }
.btn-ghost-warning.active, .btn-ghost-warning:active { --tblr-btn-active-color: var(--tblr-warning-fg); --tblr-btn-active-bg: var(--tblr-warning); }
.btn-ghost-danger.active, .btn-ghost-danger:active { --tblr-btn-active-color: var(--tblr-danger-fg); --tblr-btn-active-bg: var(--tblr-danger); }
.btn-ghost-info.active, .btn-ghost-info:active { --tblr-btn-active-color: var(--tblr-info-fg); --tblr-btn-active-bg: var(--tblr-info); }
.btn-ghost-secondary.active, .btn-ghost-secondary:active { --tblr-btn-active-color: var(--tblr-secondary-fg); --tblr-btn-active-bg: var(--tblr-secondary); }

/* El avatar del usuario en la barra superior no tiene foto ni color: son dos
   letras sobre el hueco. La barra tiene su propio contexto de tema, así que el
   gris del hueco y el gris del texto acababan siendo casi el mismo —1,02:1
   medido, o sea invisible—. Se le da un par con separación garantizada. */
.navbar .avatar:not([class*="bg-"]):not([style*="background"]) {
    --tblr-avatar-bg: var(--tblr-primary);
    color: var(--tblr-primary-fg);
    font-weight: 600;
}

/* El campo de fichero del estudio de retrato va oculto con `visually-hidden`
   —no con `d-none`, que lo saca del orden de tabulación— y quien lo enfoca con
   el teclado no vería nada: el anillo se dibujaría sobre un elemento de 1 px
   recortado. Esta regla lleva el foco al botón que lo envuelve. */
.btn:focus-within {
    box-shadow: var(--tblr-btn-focus-box-shadow);
}

/* ---------------------------------------------------------------------------
   select2 con su tema por defecto: gris claro fijo en los DOS temas.
   Lo montan así TRES pantallas —devoluciones, clases particulares y ventas de
   talleres— y el desplegable salía blanco sobre fila oscura, con 46 px de alto
   contra los 40 de los campos de al lado. Aquí solo se le dan las variables de
   Tabler: el color lo sigue decidiendo el tema, no este fichero.
   No alcanza a `--bootstrap4` (tiene su ajuste más arriba), ni a
   `pantallas-recursos/form` (usa el tema de Bootstrap 5, con su propio CSS), ni
   al desplegable de talleres de `escuela/clases_form`, que pide un tema
   `tabler` del que NO hay hoja en el repositorio: ese sale sin estilo ninguno,
   y es un caso aparte todavía sin resolver.
--------------------------------------------------------------------------- */
body .select2-container--default .select2-selection--single,
body .select2-container--default .select2-selection--multiple {
    background-color: var(--tblr-bg-forms);
    border: var(--tblr-border-width) solid var(--tblr-border-color);
    border-radius: var(--tblr-border-radius);
    box-sizing: border-box;
    padding: .5625rem 1rem;
}
/* La altura fija es SOLO para el de un valor: un multiselección crece con sus
   etiquetas, y cortarlo a 40 px lo dejaría inservible. Hoy no hay ninguno con
   este tema, pero el que venga no debe heredar la trampa.
   El `!important` es a propósito: dentro del propio select2.min.css hay un
   `height: calc(1.5em + 1.25rem + 5px) !important` escrito a mano que deja el
   desplegable 6 px más alto que los campos de al lado, y no se puede vencer
   sin editar la librería. */
body .select2-container--default .select2-selection--single {
    height: 2.5rem !important;
    display: flex;
    align-items: center;
}
/* Deshabilitado: select2 lo pinta gris claro fijo, que sobre el tema oscuro se
   lee como "campo activo en blanco". Aquí se apaga como cualquier otro campo. */
body .select2-container--default.select2-container--disabled .select2-selection--single,
body .select2-container--default.select2-container--disabled .select2-selection--multiple {
    background-color: var(--tblr-bg-surface-secondary);
    opacity: .65;
}
body .select2-container--default .select2-selection--single .select2-selection__rendered {
    color: var(--tblr-body-color);
    line-height: 1.25rem;
    /* El hueco de la derecha es el sitio de la flecha, que va en posición
       absoluta: sin él, un nombre largo se corta DEBAJO de la flecha. */
    padding: 0 1.25rem 0 0;
}
body .select2-container--default .select2-selection--single .select2-selection__placeholder {
    color: var(--tblr-secondary);
}
body .select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 100%;
    top: 0;
    right: .5rem;
}
body .select2-container--default .select2-selection--single .select2-selection__arrow b {
    border-top-color: var(--tblr-secondary);
}
body .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
    border-bottom-color: var(--tblr-secondary);
}
body .select2-container--default.select2-container--focus .select2-selection--single,
body .select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--tblr-primary);
    box-shadow: 0 0 0 .25rem color-mix(in oklab, var(--tblr-primary) 25%, transparent);
}
body .select2-container--default .select2-dropdown {
    background-color: var(--tblr-bg-surface);
    border-color: var(--tblr-border-color);
    color: var(--tblr-body-color);
}
body .select2-container--default .select2-search--dropdown .select2-search__field {
    background-color: var(--tblr-bg-forms);
    border: var(--tblr-border-width) solid var(--tblr-border-color);
    border-radius: var(--tblr-border-radius);
    color: var(--tblr-body-color);
}
body .select2-container--default .select2-results__option {
    color: var(--tblr-body-color);
}
body .select2-container--default .select2-results__option--highlighted[aria-selected],
body .select2-container--default .select2-results__option[aria-selected="true"] {
    background-color: var(--tblr-primary);
    color: #fff;
}


/* El contenido se aparta con suavidad cuando se abre el panel de Elora (la
   clase `elora-open` de `.page`, que pone el layout). La transición vivía en la
   hoja del chat interno de la intranet de origen, que no viaja: sin ella el
   contenido saltaba de golpe mientras el panel entraba deslizándose. Mismo
   valor que allí y que `--elora-transition`. */
.page {
    transition: margin-right 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Layout «fluid» de Tabler (decisión de dirección, 18-sep-2026): la intranet aprovecha todo el
   ancho de la pantalla en vez de cortarse a los 1.320 px de `container-xl`.
   En Tabler se activa con `data-bs-layout="fluid"` en <html> —puesto en
   main_tabler—, pero la regla llegó en una versión posterior a la que tenemos
   descargada (tabler.min.css es de octubre de 2025), así que va aquí copiada
   literal de la referencia oficial. Cuando se actualice Tabler, este bloque
   sobra y se puede retirar sin más.
   En la intranet solo hay `container-xl` (384 usos) y `container-fluid` (26);
   `container-periodo-b` del scorecard es un id, no una clase, y no le afecta. */
html[data-bs-layout="fluid"] .container,
html[data-bs-layout="fluid"] [class*=" container-"],
html[data-bs-layout="fluid"] [class^="container-"] {
    max-width: 100%;
}

