/* ───────────────────────────────────────────────────────────────────────────
   Convocatorias Hub · estilos propios sobre Bootstrap 5.3

   Bootstrap 5.3 expone casi todo como variables CSS, así que aquí no se pelea
   con `!important` ni se recompila Sass: se redefinen sus tokens. Lo que sí hay
   que tocar a mano son las pocas reglas donde el azul viene incrustado en el
   fichero compilado (focos de formulario, `.btn-primary`, paginación,…); están
   todas juntas en el apartado «Reconexión del acento».

   El modo oscuro se apoya en `data-bs-theme`, que el script en línea de
   `layout/base.html` fija antes del primer pintado para que no haya destello.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── Tokens ──────────────────────────────────────────────────────────────────
   El acento es terracota y no el azul de Bootstrap: distingue al Hub de
   cualquier panel hecho con la plantilla de serie y deja libres el rojo, el
   ámbar y el verde, que aquí no son decoración sino estado (pendiente de visar,
   préstamo vencido, garantía a punto de expirar).

   Un botón sólido pide bastante más contraste que el 4.5:1 del mínimo AA, así
   que se eligió por número y no a ojo: 8.45:1 con blanco encima en claro y
   9.24:1 en oscuro, los dos en AAA. En oscuro la terracota no vale —sobre fondo
   oscuro no se lee— y se sustituye por su contrapartida clara, con el texto de
   los botones en terracota casi negro. */
:root {
  --gti-acento: #823610;
  --gti-logo: #823610;
  --gti-acento-fuerte: #66290b;
  --gti-acento-suave: #f6e9df;
  --gti-acento-borde: #e6c7b0;
  --gti-acento-contraste: #ffffff;
  --gti-acento-rgb: 130, 54, 16;

  /* Lo *seleccionado* (pestaña activa, chip de filtro marcado, botón
     principal) no se rellena de terracota con letra blanca, sino al revés: fondo
     claro y letra casi negra, 14.10:1. Es lo que se pidió y además arregla un
     fallo que había en oscuro, donde el relleno ya era terracota clara pero
     Bootstrap seguía poniendo la letra en blanco: 2.15:1, ilegible. */
  --gti-acento-relleno: #f3dfd0;
  --gti-acento-relleno-fuerte: #ecd0bb;
  --gti-acento-relleno-borde: #e0bca2;
  --gti-acento-texto: #111827;

  --gti-sidebar-ancho: 250px;
  /* La isla mide 56px y lleva 10px de margen arriba y abajo. */
  --gti-navbar-alto: 76px;

  /* Una escala de radios, no un valor suelto: las piezas pequeñas (badges,
     botones) piden menos curva que los contenedores, y mezclarlos se nota. */
  --gti-radio-xs: 0.3rem;
  --gti-radio-sm: 0.45rem;
  --gti-radio: 0.625rem;
  --gti-radio-lg: 0.875rem;

  /* Tres niveles y no más. El primero para lo que solo necesita despegarse del
     fondo, el segundo para tarjetas, el tercero para lo que flota de verdad
     (menús desplegables, sidebar en móvil). */
  /* Tintadas de la terracota del acento y no negras: sobre el fondo crema
     una sombra neutra ensucia, una del mismo tono parece luz de verdad. La luz
     viene siempre de arriba, así que todas caen hacia abajo. */
  --gti-sombra-1: 0 1px 2px rgba(74, 36, 14, 0.06);
  --gti-sombra-2: 0 1px 2px rgba(74, 36, 14, 0.05), 0 2px 6px -2px rgba(74, 36, 14, 0.07);
  --gti-sombra-3: 0 12px 32px -8px rgba(74, 36, 14, 0.18), 0 3px 8px -3px rgba(74, 36, 14, 0.08);
  /* Tarjeta levantada al pasar el ratón por algo que se puede pulsar. */
  --gti-sombra-hover: 0 10px 28px -10px rgba(74, 36, 14, 0.2), 0 2px 6px -2px rgba(74, 36, 14, 0.08);

  /* Movimiento. Una curva con algo de inercia para lo que entra y se desplaza,
     y duraciones cortas: es una herramienta de trabajo, no una presentación. */
  --gti-curva: cubic-bezier(0.16, 1, 0.3, 1);
  --gti-curva-muelle: cubic-bezier(0.32, 0.72, 0, 1);
  --gti-rapido: 160ms;
  --gti-medio: 280ms;

  /* Escala de capas: por encima de la barra de Bootstrap (1030) y por debajo
     de sus modales (1050). */
  --gti-z-progreso: 1045;
  --gti-z-salto: 1060;

  --gti-superficie: #ffffff;
  --gti-sidebar-bg: #ffffff;
  --gti-sidebar-borde: #e8eaee;
  --gti-sidebar-activo: var(--gti-acento-suave);
  --gti-tabla-cabecera: #f7f8fa;

  /* Tokens de Bootstrap redefinidos. Con esto ya cambian `.text-primary`,
     `.bg-primary`, `.text-bg-primary`, los enlaces y los anillos de foco. */
  --bs-primary: var(--gti-acento);
  --bs-primary-rgb: var(--gti-acento-rgb);
  --bs-primary-bg-subtle: var(--gti-acento-suave);
  --bs-primary-border-subtle: var(--gti-acento-borde);
  --bs-primary-text-emphasis: #6e2f0e;
  --bs-link-color: var(--gti-acento);
  --bs-link-color-rgb: var(--gti-acento-rgb);
  --bs-link-hover-color: var(--gti-acento-fuerte);
  --bs-link-hover-color-rgb: 102, 41, 11;
  --bs-focus-ring-color: rgba(var(--gti-acento-rgb), 0.25);

  /* El cuerpo deja de ser blanco y las tarjetas se quedan blancas. Es lo que
     crea la jerarquía: antes todo estaba al mismo nivel y las tarjetas solo se
     distinguían por el borde. */
  --bs-body-bg: #f5f1ec;
  --bs-body-color: #1f2328;
  --bs-secondary-color: #5b636e;
  --bs-border-color: #e3e6ea;
  --bs-border-color-translucent: rgba(16, 24, 40, 0.08);
  --bs-emphasis-color: #0d1117;
}

[data-bs-theme="dark"] {
  --gti-acento: #f0a77a;
  --gti-logo: #f6ece4;
  --gti-acento-fuerte: #f5c09e;
  --gti-acento-suave: rgba(240, 167, 122, 0.14);
  --gti-acento-borde: rgba(240, 167, 122, 0.34);
  --gti-acento-contraste: #2a1206;
  --gti-acento-rgb: 240, 167, 122;

  --gti-acento-relleno: #f0a77a;
  --gti-acento-relleno-fuerte: #f5c09e;
  --gti-acento-relleno-borde: #f0a77a;
  --gti-acento-texto: #2a1206;

  --gti-sombra-1: 0 1px 2px rgba(0, 0, 0, 0.35);
  --gti-sombra-2: 0 1px 3px rgba(0, 0, 0, 0.4), 0 1px 2px -1px rgba(0, 0, 0, 0.3);
  --gti-sombra-3: 0 8px 24px -6px rgba(0, 0, 0, 0.6), 0 2px 6px -2px rgba(0, 0, 0, 0.4);
  --gti-sombra-hover: 0 10px 28px -10px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(240, 167, 122, 0.12);

  --gti-superficie: #1a1d21;
  --gti-sidebar-bg: #16191c;
  --gti-sidebar-borde: #272b30;
  --gti-tabla-cabecera: #212529;

  --bs-primary-text-emphasis: #f7cfb5;
  --bs-body-bg: #121416;
  --bs-body-color: #e3e5e8;
  --bs-secondary-color: #9aa1aa;
  --bs-border-color: #2b2f34;
  --bs-border-color-translucent: rgba(255, 255, 255, 0.1);
  --bs-emphasis-color: #ffffff;
}

/* ── Tipografía ──────────────────────────────────────────────────────────────
   Geist, autoalojada en `static/vendor/geist/` (licencia OFL): la CSP es
   `font-src 'self' data:` y el proyecto no carga nada de fuera. Son dos ficheros
   variables, uno por familia, así que todos los pesos intermedios (500, 550,
   650…) salen del mismo fichero sin descargas extra. `swap` deja el texto
   visible con la pila nativa mientras llega, que sigue de reserva detrás.
   Lo que se afina además son los detalles que en una aplicación de datos se
   notan todos los días: cifras de ancho fijo para que las columnas de fechas,
   días y porcentajes queden alineadas, y titulares algo más apretados. */
@font-face {
  font-family: "Geist";
  src: url("../vendor/geist/Geist-Variable.dfa48d5a8537.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Geist Mono";
  src: url("../vendor/geist/GeistMono-Variable.308360d8a547.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --bs-body-font-family: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text",
    "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif;
  --bs-font-monospace: "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    "Liberation Mono", monospace;
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  font-size: 0.9375rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "ss01", "cv11";
}

h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
  letter-spacing: -0.022em;
  font-weight: 620;
  text-wrap: balance;
}

p { text-wrap: pretty; }

/* Cifras tabulares donde hay que comparar en vertical. En el texto corrido no:
   ahí las proporcionales se leen mejor. */
table, .gti-cifra, .badge, code, time, .font-monospace,
.gti-gantt, .table, input[type="number"] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

code {
  font-size: 0.85em;
  padding: 0.1rem 0.3rem;
  border-radius: var(--gti-radio-xs);
  background: var(--bs-tertiary-bg);
  color: var(--bs-emphasis-color);
}

/* ── Reconexión del acento ───────────────────────────────────────────────────
   Las reglas donde Bootstrap dejó el azul escrito a fuego en el CSS compilado.
   Si se añade algún componente nuevo con color incrustado, va aquí. */
/* Los listados reutilizan `.btn-primary` como chip de filtro marcado
   (`{% if estado.activo %}btn-primary{% endif %}`), así que seleccionado y
   botón principal comparten clase y el mismo tratamiento: relleno claro, letra
   casi negra y un borde algo más marcado para que no se pierda sobre el fondo
   de página, que también es claro. */
.btn-primary {
  --bs-btn-color: var(--gti-acento-texto);
  --bs-btn-bg: var(--gti-acento-relleno);
  --bs-btn-border-color: var(--gti-acento-relleno-borde);
  --bs-btn-hover-color: var(--gti-acento-texto);
  --bs-btn-hover-bg: var(--gti-acento-relleno-fuerte);
  --bs-btn-hover-border-color: var(--gti-acento);
  --bs-btn-active-color: var(--gti-acento-texto);
  --bs-btn-active-bg: var(--gti-acento-relleno-fuerte);
  --bs-btn-active-border-color: var(--gti-acento);
  --bs-btn-disabled-color: var(--gti-acento-texto);
  --bs-btn-disabled-bg: var(--gti-acento-relleno);
  --bs-btn-disabled-border-color: var(--gti-acento-relleno-borde);
  --bs-btn-focus-shadow-rgb: var(--gti-acento-rgb);
}

/* Al pasar el ratón se rellenaba de terracota con letra blanca, que es justo lo
   que se ha quitado del resto. Se rellena del mismo claro que lo seleccionado. */
.btn-outline-primary {
  --bs-btn-color: var(--gti-acento);
  --bs-btn-border-color: var(--gti-acento-borde);
  --bs-btn-hover-color: var(--gti-acento-texto);
  --bs-btn-hover-bg: var(--gti-acento-relleno);
  --bs-btn-hover-border-color: var(--gti-acento-relleno-borde);
  --bs-btn-active-color: var(--gti-acento-texto);
  --bs-btn-active-bg: var(--gti-acento-relleno-fuerte);
  --bs-btn-active-border-color: var(--gti-acento);
  --bs-btn-disabled-color: var(--gti-acento);
  --bs-btn-disabled-border-color: var(--gti-acento-borde);
  --bs-btn-focus-shadow-rgb: var(--gti-acento-rgb);
}

.dropdown-menu {
  --bs-dropdown-link-active-bg: var(--gti-acento-relleno);
  --bs-dropdown-link-active-color: var(--gti-acento-texto);
}
.nav-pills {
  --bs-nav-pills-link-active-bg: var(--gti-acento-relleno);
  --bs-nav-pills-link-active-color: var(--gti-acento-texto);
}
.list-group {
  --bs-list-group-active-bg: var(--gti-acento-relleno);
  --bs-list-group-active-color: var(--gti-acento-texto);
  --bs-list-group-active-border-color: var(--gti-acento-relleno-borde);
}
.pagination {
  --bs-pagination-active-bg: var(--gti-acento-relleno);
  --bs-pagination-active-color: var(--gti-acento-texto);
  --bs-pagination-active-border-color: var(--gti-acento-relleno-borde);
  --bs-pagination-hover-color: var(--gti-acento-fuerte);
  --bs-pagination-focus-color: var(--gti-acento-fuerte);
  --bs-pagination-focus-bg: var(--gti-acento-suave);
  --bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(var(--gti-acento-rgb), 0.25);
}
.progress, .progress-stacked { --bs-progress-bar-bg: var(--gti-acento); }

/* `.text-bg-primary` lleva `color:#fff` escrito en el CSS compilado. Se usa en
   ocho sitios (estado «Asignado», rol, porcentaje de dedicación, aviso nuevo…),
   todos ellos etiquetas pequeñas, que es justo donde peor se lee el blanco. */
.text-bg-primary {
  background-color: var(--gti-acento-relleno) !important;
  color: var(--gti-acento-texto) !important;
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  border-color: var(--gti-acento-borde);
  box-shadow: 0 0 0 0.2rem rgba(var(--gti-acento-rgb), 0.18);
}

.form-check-input:checked,
.form-check-input[type="checkbox"]:indeterminate {
  background-color: var(--gti-acento);
  border-color: var(--gti-acento);
}

.form-range::-webkit-slider-thumb { background-color: var(--gti-acento); }
.form-range::-moz-range-thumb { background-color: var(--gti-acento); }

.nav-link:focus-visible {
  box-shadow: 0 0 0 0.2rem rgba(var(--gti-acento-rgb), 0.25);
}

/* ── Estructura ─────────────────────────────────────────────────────────── */
/* Fondo con algo de profundidad: un halo muy tenue del acento arriba a la
   derecha y grano encima. Va fijo para que no se desplace con el contenido, y
   el grano en una capa aparte que no recibe eventos. El SVG es un data URI,
   que la CSP admite en `img-src`. */
body {
  background-image:
    radial-gradient(60rem 30rem at 100% -8%, rgba(var(--gti-acento-rgb), 0.07), transparent 65%),
    radial-gradient(40rem 26rem at -10% 110%, rgba(var(--gti-acento-rgb), 0.05), transparent 60%);
  background-attachment: fixed;
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2000;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

[data-bs-theme="dark"] body::after { opacity: 0.06; mix-blend-mode: overlay; }

/* Enlace para saltar directamente al contenido con el teclado. */
.gti-saltar {
  position: fixed;
  top: 0.5rem;
  left: 0.5rem;
  z-index: var(--gti-z-salto);
  padding: 0.5rem 0.875rem;
  border-radius: var(--gti-radio-sm);
  background: var(--gti-acento-relleno);
  color: var(--gti-acento-texto);
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--gti-sombra-3);
  transform: translateY(-160%);
  /* Además de subirlo, transparente: con el rebote del scroll (macOS, iOS) la
     franja de encima de la página asoma y el enlace se veía. Sin `visibility:
     hidden`, que lo sacaría del recorrido con el tabulador. */
  opacity: 0;
  pointer-events: none;
  transition: transform var(--gti-medio) var(--gti-curva), opacity var(--gti-medio) var(--gti-curva);
}
.gti-saltar:focus { transform: translateY(0); opacity: 1; pointer-events: auto; }

/* Barra de progreso fina bajo la barra superior: avisa de que algo está
   cargando (una petición HTMX o el cambio de página) sin tapar nada. */
.gti-progreso {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: var(--gti-z-progreso);
  pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--gti-acento) 30%, var(--gti-acento-fuerte));
  transform-origin: left;
  transform: scaleX(0);
  opacity: 0;
}
.gti-progreso.activo {
  opacity: 1;
  animation: gti-progreso 2.4s var(--gti-curva) forwards;
}
.gti-progreso.fin {
  opacity: 0;
  transform: scaleX(1);
  transition: transform 0.18s ease-out, opacity 0.35s ease 0.15s;
}
@keyframes gti-progreso {
  0% { transform: scaleX(0); }
  40% { transform: scaleX(0.55); }
  100% { transform: scaleX(0.9); }
}

.gti-layout {
  display: flex;
  min-height: calc(100vh - var(--gti-navbar-alto));
}

.gti-sidebar {
  width: var(--gti-sidebar-ancho);
  flex: 0 0 var(--gti-sidebar-ancho);
  background: var(--gti-sidebar-bg);
  border-right: 1px solid var(--gti-sidebar-borde);
  padding: 0.875rem 0.75rem;
  position: sticky;
  top: var(--gti-navbar-alto);
  align-self: flex-start;
  /* Altura fija y no `max-height`: ahora que la barra es una superficie propia
     y no del color del fondo, quedarse a la altura del último enlace dejaba un
     escalón a media pantalla. */
  height: calc(100vh - var(--gti-navbar-alto));
  overflow-y: auto;
  scrollbar-width: thin;
}

/* La barra lateral, como la isla de arriba: un panel de cristal que flota,
   despegado del borde y del pie de la ventana. El cristal está en «Barra
   lateral de cristal», más abajo. */

.gti-contenido {
  flex: 1 1 auto;
  min-width: 0;
  padding: 2rem 2.25rem 3.5rem;
}

#contenido:focus { outline: none; }

/* El contenido ocupa la ventana entera. Solo en monitores ultrapanorámicos se
   centra con un tope de 2400px, con el relleno lateral y no con `max-width` en
   cada hijo: así no se queda pegado a la izquierda dejando media pantalla vacía. */
.gti-contenido { padding-inline: max(2.25rem, calc((100% - 2400px) / 2)); }

/* ── Cabecera de página ──────────────────────────────────────────────────── */
.gti-encabezado h1 {
  font-size: clamp(1.4rem, 1.1rem + 0.9vw, 1.85rem);
  font-weight: 650;
  letter-spacing: -0.03em;
  line-height: 1.15;
}

/* ── Entrada escalonada ──────────────────────────────────────────────────────
   Al cargar la página los bloques suben y aparecen uno detrás de otro en vez
   de estar todos de golpe. `backwards` y no `both`: al terminar no se queda
   ningún `transform` puesto, que convertiría a los antepasados en bloque
   contenedor y descolocaría los modales y los `position: sticky` de dentro. */
@keyframes gti-entrar {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* Las tarjetas tienen su propia revelación al entrar en pantalla (app.js);
   aquí solo entra lo que no las lleva dentro: cabecera, pestañas, avisos. */
.gti-contenido > :not(.card):not(:has(.card)) {
  animation: gti-entrar 520ms var(--gti-curva) backwards;
}
.gti-contenido > :nth-child(2) { animation-delay: 40ms; }
.gti-contenido > :nth-child(3) { animation-delay: 80ms; }
.gti-contenido > :nth-child(n+4) { animation-delay: 110ms; }

/* Lo que llega por HTMX entra con un fundido corto (la clase la pone app.js). */
@keyframes gti-fundido { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.gti-aparecer { animation: gti-fundido 260ms var(--gti-curva) backwards; }

/* Esqueleto de carga, en lugar de la rueda: anticipa la forma de lo que viene. */
.gti-esqueleto {
  display: block;
  height: 0.75rem;
  border-radius: var(--gti-radio-xs);
  background: linear-gradient(90deg, var(--bs-tertiary-bg) 0%, var(--bs-secondary-bg) 50%, var(--bs-tertiary-bg) 100%);
  background-size: 200% 100%;
  animation: gti-brillo 1.3s ease-in-out infinite;
}
@keyframes gti-brillo { from { background-position: 100% 0; } to { background-position: -100% 0; } }

@media (max-width: 991.98px) {
  .gti-sidebar {
    position: fixed;
    inset: var(--gti-navbar-alto) auto 0 0;
    z-index: 1030;
    transform: translateX(-100%);
    transition: transform 0.22s cubic-bezier(0.32, 0.72, 0, 1);
    box-shadow: var(--gti-sombra-3);
  }
  .gti-sidebar.abierta { transform: translateX(0); }
  .gti-contenido { padding: 1.125rem 1rem 2.5rem; }
}

/* ── Barra superior: isla de cristal ────────────────────────────────────────
   Flota despegada del borde, redondeada, y deja ver lo que pasa por debajo
   desenfocado y algo más saturado. Lo que la hace parecer cristal y no un
   rectángulo semitransparente son tres detalles: un brillo especular en el filo
   (un degradado blanco solo en el borde, con máscara), un reflejo interior
   arriba y una sombra amplia y tenue. `--gti-navbar-alto` cuenta la isla más su
   margen, porque es lo que miden la barra lateral y el contenido. */
.gti-centinela { position: absolute; top: 0; left: 0; width: 1px; height: 12px; pointer-events: none; }

.gti-barra {
  position: sticky;
  top: 0;
  z-index: 1030;
  height: var(--gti-navbar-alto);
  padding: 0.625rem 0.875rem;
}

.gti-isla {
  --gti-cristal: rgba(255, 255, 255, 0.62);
  --gti-cristal-filo: rgba(255, 255, 255, 0.95);
  position: relative;
  height: 100%;
  padding: 0 0.375rem;
  border-radius: 1.375rem;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0) 60%),
    var(--gti-cristal);
  -webkit-backdrop-filter: blur(22px) saturate(190%);
  backdrop-filter: blur(22px) saturate(190%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -1px 0 rgba(255, 255, 255, 0.25),
    0 0 0 1px rgba(74, 36, 14, 0.07),
    0 12px 32px -14px rgba(74, 36, 14, 0.28),
    0 2px 6px -2px rgba(74, 36, 14, 0.06);
  transition: background-color 400ms var(--gti-curva), box-shadow 400ms var(--gti-curva);
}
/* Brillo especular del filo: más intenso arriba a la izquierda, donde «da la luz». */
.gti-isla::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  pointer-events: none;
  background: linear-gradient(135deg, var(--gti-cristal-filo), rgba(255, 255, 255, 0.15) 35%,
    rgba(255, 255, 255, 0) 60%, rgba(255, 255, 255, 0.5));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}
/* Al bajar por la página, algo más opaca y con más sombra: el contenido que
   pasa por debajo ya no compite con ella. */
.gti-barra.desplazada .gti-isla {
  --gti-cristal: rgba(255, 255, 255, 0.78);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -1px 0 rgba(255, 255, 255, 0.25),
    0 0 0 1px rgba(74, 36, 14, 0.08),
    0 18px 40px -16px rgba(74, 36, 14, 0.38),
    0 2px 6px -2px rgba(74, 36, 14, 0.08);
}
[data-bs-theme="dark"] .gti-isla {
  --gti-cristal: rgba(28, 31, 36, 0.55);
  --gti-cristal-filo: rgba(255, 255, 255, 0.28);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0) 60%),
    var(--gti-cristal);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 0 0 1px rgba(255, 255, 255, 0.06),
    0 16px 40px -16px rgba(0, 0, 0, 0.8);
}
[data-bs-theme="dark"] .gti-barra.desplazada .gti-isla { --gti-cristal: rgba(28, 31, 36, 0.78); }

/* Sin `backdrop-filter` el cristal no desenfoca: se queda opaco, que es lo
   correcto de reserva (nunca texto ilegible encima del contenido). */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .gti-isla { --gti-cristal: var(--gti-superficie) !important; }
}

/* Marca */
.gti-marca { display: inline-flex; align-items: center; gap: 0.625rem; padding: 0; }
/* El logotipo: la hoja en el color de la marca (claro u oscuro según el tema) y
   el punto con su degradado. Al pasar el ratón, el punto «late» un poco. */
.gti-logo { display: block; height: 1.375rem; width: auto; color: var(--gti-logo); overflow: visible; }
.gti-logo > circle { transition: transform 500ms var(--gti-curva-muelle); transform-box: fill-box; transform-origin: center; }
.gti-marca:hover .gti-logo > circle { transform: scale(1.18); }
.gti-marca-texto {
  font-size: 1.0625rem;
  font-weight: 450;
  letter-spacing: -0.02em;
  color: var(--bs-secondary-color);
  padding-left: 0.625rem;
  border-left: 1px solid var(--bs-border-color);
  line-height: 1;
}

/* Botones redondos de cristal (tema, avisos, menú) */
.gti-boton-cristal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.375rem;
  height: 2.375rem;
  border: 0;
  border-radius: 50%;
  font-size: 1rem;
  color: var(--bs-body-color);
  text-decoration: none;
  background: transparent;
  transition: background-color 250ms ease, transform 400ms var(--gti-curva-muelle), box-shadow 250ms ease;
}
.gti-boton-cristal:hover, .gti-boton-cristal[aria-expanded="true"] {
  color: var(--bs-emphasis-color);
  background: rgba(255, 255, 255, 0.65);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 0 0 1px rgba(74, 36, 14, 0.06), 0 4px 10px -4px rgba(74, 36, 14, 0.2);
}
[data-bs-theme="dark"] .gti-boton-cristal:hover, [data-bs-theme="dark"] .gti-boton-cristal[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.gti-boton-cristal:active { transform: scale(0.92); }
.gti-aviso-contador {
  position: absolute;
  top: 0.125rem;
  right: 0.125rem;
  min-width: 1.05rem;
  height: 1.05rem;
  padding: 0 0.3rem;
  border-radius: 50rem;
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 1.05rem;
  text-align: center;
  color: #fff;
  background: #e5484d;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9);
}

/* Píldora de la persona */
.gti-persona {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  height: 2.5rem;
  padding: 0.25rem 0.75rem 0.25rem 0.25rem;
  border: 0;
  border-radius: 50rem;
  background: transparent;
  color: var(--bs-body-color);
  transition: background-color 250ms ease, box-shadow 250ms ease, transform 400ms var(--gti-curva-muelle);
}
.gti-persona:hover, .gti-persona[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.65);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 0 0 1px rgba(74, 36, 14, 0.06), 0 4px 10px -4px rgba(74, 36, 14, 0.2);
}
[data-bs-theme="dark"] .gti-persona:hover, [data-bs-theme="dark"] .gti-persona[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.gti-persona:active { transform: scale(0.97); }
.gti-persona .gti-avatar { width: 2rem; height: 2rem; border-radius: 50%; }
.gti-persona-nombre { font-size: 0.8125rem; font-weight: 600; color: var(--bs-emphasis-color); }
.gti-persona-rol { font-size: 0.6875rem; color: var(--bs-secondary-color); margin-top: 0.125rem; }
.gti-persona-flecha { font-size: 0.6875rem; color: var(--bs-secondary-color); transition: transform 400ms var(--gti-curva-muelle); }
.gti-persona[aria-expanded="true"] .gti-persona-flecha { transform: rotate(180deg); }

/* Buscador: píldora de cristal hundida en la isla */
.gti-buscador {
  position: relative;
  align-items: center;
  max-width: 32rem;
  height: 2.5rem;
  padding: 0 0.5rem 0 0.875rem;
  border-radius: 50rem;
  background: rgba(255, 255, 255, 0.45);
  box-shadow: inset 0 1px 2px rgba(74, 36, 14, 0.08), inset 0 0 0 1px rgba(74, 36, 14, 0.07);
  transition: background-color 300ms ease, box-shadow 300ms var(--gti-curva);
}
.gti-buscador:focus-within {
  background: rgba(255, 255, 255, 0.85);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gti-acento) 45%, transparent),
    0 0 0 4px rgba(var(--gti-acento-rgb), 0.12);
}
[data-bs-theme="dark"] .gti-buscador { background: rgba(0, 0, 0, 0.22); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07); }
[data-bs-theme="dark"] .gti-buscador:focus-within {
  background: rgba(0, 0, 0, 0.35);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gti-acento) 50%, transparent), 0 0 0 4px rgba(var(--gti-acento-rgb), 0.15);
}
.gti-buscador-lupa { color: var(--bs-secondary-color); font-size: 0.9rem; }
.gti-buscador-campo {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  padding: 0 0.625rem;
  border: 0;
  outline: 0;
  font-size: 0.875rem;
  color: var(--bs-body-color);
  background: transparent;
}
.gti-buscador-campo::placeholder { color: var(--bs-secondary-color); opacity: 0.85; }
.gti-buscador-campo::-webkit-search-cancel-button { display: none; }
.gti-buscador-campo:focus-visible { outline: 0; }
.gti-atajo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.5rem;
  padding: 0 0.375rem;
  border-radius: 0.5rem;
  font: 600 0.75rem var(--bs-font-monospace);
  color: var(--bs-secondary-color);
  background: rgba(255, 255, 255, 0.7);
  box-shadow: inset 0 -1px 0 rgba(74, 36, 14, 0.12), 0 0 0 1px rgba(74, 36, 14, 0.08);
  transition: opacity 200ms ease;
}
[data-bs-theme="dark"] .gti-atajo { background: rgba(255, 255, 255, 0.06); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08); }
.gti-buscador:focus-within .gti-atajo { opacity: 0; }
.gti-buscador-resultados { position: absolute; top: calc(100% + 0.625rem); left: 0; z-index: 1040; }

/* ── Navegación lateral ─────────────────────────────────────────────────────
   El ítem activo no se marca solo con fondo: lleva además una barra de acento a
   la izquierda. Con fondo tenue a secas, en pantallas malas o con el brillo
   bajo, no se distingue de los demás. */
.gti-nav-seccion {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 650;
  color: var(--bs-secondary-color);
  padding: 0.875rem 0.75rem 0.3rem;
}

.gti-sidebar .nav-link {
  position: relative;
  border-radius: var(--gti-radio-sm);
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.0625rem;
  color: var(--bs-body-color);
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  transition: background-color var(--gti-rapido) ease, color var(--gti-rapido) ease;
}

.gti-sidebar .nav-link:hover { background: var(--bs-tertiary-bg); }

/* El icono se desplaza un poco al pasar por encima: pista de que es pulsable
   sin mover la etiqueta, que es lo que se lee. */
.gti-sidebar .nav-link i:first-child { transition: transform var(--gti-medio) var(--gti-curva-muelle); }
.gti-sidebar .nav-link:hover i:first-child { transform: translateX(2px) scale(1.06); }
.gti-sidebar .nav-link:active { transform: scale(0.985); }

.gti-sidebar .nav-link.activo {
  background: var(--gti-sidebar-activo);
  color: var(--gti-acento);
  font-weight: 600;
}

.gti-sidebar .nav-link.activo::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.45rem;
  bottom: 0.45rem;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--gti-acento);
  animation: gti-marca-activa var(--gti-medio) var(--gti-curva-muelle) backwards;
}

@keyframes gti-marca-activa { from { transform: scaleY(0); } to { transform: scaleY(1); } }

.gti-sidebar .nav-link i { width: 1.15rem; text-align: center; font-size: 1.02em; }
.gti-sidebar .nav-link.activo i { color: var(--gti-acento); }

/* ── Tarjetas ────────────────────────────────────────────────────────────── */
.card {
  --bs-card-bg: var(--gti-superficie);
  --bs-card-border-color: var(--bs-border-color);
  --bs-card-border-radius: var(--gti-radio);
  --bs-card-inner-border-radius: calc(var(--gti-radio) - 1px);
  --bs-card-cap-bg: transparent;
  --bs-card-border-color: color-mix(in srgb, var(--bs-border-color) 70%, transparent);
  box-shadow: var(--gti-sombra-2);
  transition: box-shadow var(--gti-medio) var(--gti-curva), transform var(--gti-medio) var(--gti-curva),
    border-color var(--gti-medio) ease;
}

/* Borde con foco de luz: un halo del acento que sigue al cursor por el borde
   de la tarjeta. app.js actualiza `--gti-x` / `--gti-y`; sin JS o en pantallas
   táctiles simplemente no aparece. La máscara deja visible solo el anillo de
   1px, así que el contenido no se tiñe. */
@media (hover: hover) and (pointer: fine) {
  .card::after {
    content: "";
    position: absolute;
    inset: -1px;
    border-radius: inherit;
    padding: 1px;
    pointer-events: none;
    background: radial-gradient(18rem circle at var(--gti-x, 50%) var(--gti-y, -40%),
      rgba(var(--gti-acento-rgb), 0.55), transparent 55%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    opacity: 0;
    transition: opacity var(--gti-medio) ease;
  }
  .card:hover::after { opacity: 1; }

  /* Las tarjetas que son un enlace entero se levantan un poco. */
  a.card:hover,
  .card:has(.stretched-link):hover,
  .gti-kpi:hover {
    transform: translateY(-2px);
    box-shadow: var(--gti-sombra-hover);
  }
}

/* ── Indicadores del panel ───────────────────────────────────────────────── */
.gti-kpi .card-body { padding: 1.125rem 1.25rem; }
.gti-kpi .gti-cifra { font-size: 1.9rem; }
.gti-kpi .gti-chip { transition: transform var(--gti-medio) var(--gti-curva-muelle); }
.gti-kpi:hover .gti-chip { transform: rotate(-6deg) scale(1.06); }

/* En el móvil van de dos en dos: icono arriba y cifra debajo. */
@media (max-width: 575.98px) {
  .gti-kpi .card-body { flex-direction: column; align-items: flex-start !important; gap: 0.625rem !important; padding: 0.875rem 1rem; }
  .gti-kpi .gti-cifra { font-size: 1.6rem; }
}

/* `.text-bg-light` trae blanco fijo: en oscuro quedaba una pastilla blanca. */
[data-bs-theme="dark"] .text-bg-light {
  background-color: var(--bs-tertiary-bg) !important;
  color: var(--bs-body-color) !important;
}

/* Rótulo pequeño sobre un grupo (el «Hoy» o «Próximos siete días» del panel).
   En minúsculas y con peso, no en mayúsculas espaciadas. */
.gti-sobretitulo {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--bs-secondary-color);
  margin-bottom: 0.5rem;
}

.card-header {
  border-bottom-color: var(--bs-border-color);
  font-weight: 600;
}

/* `.shadow-sm` está por toda la aplicación; se reengancha a la escala propia
   para que no conviva una sombra azulada de Bootstrap con las de aquí. */
.shadow-sm { box-shadow: var(--gti-sombra-2) !important; }
.shadow { box-shadow: var(--gti-sombra-3) !important; }

.dropdown-menu {
  --bs-dropdown-border-color: var(--bs-border-color);
  --bs-dropdown-border-radius: var(--gti-radio);
  --bs-dropdown-link-hover-bg: var(--bs-tertiary-bg);
  box-shadow: var(--gti-sombra-3);
}

.list-group { --bs-list-group-border-color: var(--bs-border-color); }

/* ── Tablas ──────────────────────────────────────────────────────────────── */
.table {
  --bs-table-border-color: var(--bs-border-color);
  margin-bottom: 0;
}

.table > thead th {
  background: var(--gti-tabla-cabecera);
  font-size: 0.75rem;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.045em;
  color: var(--bs-secondary-color);
  white-space: nowrap;
  border-bottom-color: var(--bs-border-color);
}

.table > tbody tr { transition: background-color 0.1s ease; }
.table-hover > tbody > tr:hover > * { background-color: var(--bs-tertiary-bg); }

/* Una tabla dentro de una tarjeta no necesita bordes laterales ni la última
   línea: ya la encuadra la propia tarjeta. */
.card > .table:last-child > tbody > tr:last-child > td,
.card > .gti-scroll-x:last-child > .table > tbody > tr:last-child > td {
  border-bottom-width: 0;
}

.gti-tabla-compacta th { background: var(--gti-tabla-cabecera); }
.gti-tabla-compacta td, .gti-tabla-compacta th { padding: 0.45rem 0.65rem; }

/* ── Formularios ─────────────────────────────────────────────────────────── */
.form-control, .form-select {
  border-radius: var(--gti-radio-sm);
  border-color: var(--bs-border-color);
  background-color: var(--gti-superficie);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.form-label {
  font-weight: 550;
  font-size: 0.8125rem;
  margin-bottom: 0.3rem;
  color: var(--bs-emphasis-color);
}

.form-text { font-size: 0.78rem; }

.input-group-text {
  background: var(--bs-tertiary-bg);
  border-color: var(--bs-border-color);
}

/* ── Botones y distintivos ───────────────────────────────────────────────── */
.btn {
  --bs-btn-border-radius: var(--gti-radio-sm);
  font-weight: 550;
  transition: background-color var(--gti-rapido) ease, border-color var(--gti-rapido) ease,
    color var(--gti-rapido) ease, box-shadow var(--gti-rapido) ease,
    transform var(--gti-rapido) var(--gti-curva-muelle);
}

/* Pulsación física: el botón cede un poco al apretarlo. */
.btn:not(:disabled):not(.disabled):active { transform: scale(0.97); }

.btn-primary:not(:disabled):hover {
  box-shadow: 0 4px 12px -4px rgba(var(--gti-acento-rgb), 0.35);
}

.btn-sm { --bs-btn-border-radius: var(--gti-radio-xs); }

.badge {
  font-weight: 600;
  letter-spacing: 0.01em;
  border-radius: var(--gti-radio-xs);
}

.badge.rounded-pill { border-radius: 50rem; }

.alert {
  --bs-alert-border-radius: var(--gti-radio-sm);
  border-color: var(--bs-border-color);
}

/* ── Utilidades ─────────────────────────────────────────────────────────── */
.gti-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 32%;
  /* Mismo criterio que lo seleccionado: iniciales oscuras sobre relleno claro.
     Lleva aro porque en claro el relleno y la barra superior blanca se parecen
     demasiado y el círculo se desdibujaba. */
  background: var(--gti-acento-relleno);
  color: var(--gti-acento-texto);
  box-shadow: inset 0 0 0 1px var(--gti-acento-relleno-borde);
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.02em;
  flex: 0 0 auto;
}

.gti-avatar-lg { width: 4.5rem; height: 4.5rem; font-size: 1.5rem; }

.gti-punto {
  display: inline-block;
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  vertical-align: baseline;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}

/* Pastilla de icono para las cifras del panel. El icono suelto a 1.75rem se
   perdía sobre el blanco; dentro de una pastilla tintada ancla la tarjeta. */
.gti-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--gti-radio-sm);
  font-size: 1.15rem;
  flex: 0 0 auto;
  background: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);
}

.gti-chip-acento { background: var(--gti-acento-suave); color: var(--gti-acento); }
.gti-chip-exito { background: rgba(25, 135, 84, 0.12); color: #198754; }
/* Violeta y no azul: con el acento en terracota, una pastilla azul vivo se
   confundía con él y las cuatro cifras del panel dejaban de distinguirse. */
.gti-chip-violeta { background: rgba(124, 58, 237, 0.11); color: #6d28d9; }
.gti-chip-aviso { background: rgba(255, 193, 7, 0.16); color: #997404; }

[data-bs-theme="dark"] .gti-chip-exito { color: #75d8a6; }
[data-bs-theme="dark"] .gti-chip-violeta { color: #c4b5fd; }
[data-bs-theme="dark"] .gti-chip-aviso { color: #ffda6a; }

/* La cifra grande de una tarjeta de indicador. */
.gti-cifra {
  font-size: 1.6rem;
  font-weight: 650;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--bs-emphasis-color);
}

.gti-rotulo {
  font-size: 0.78rem;
  line-height: 1.25;
  color: var(--bs-secondary-color);
}

.gti-truncar { max-width: 22rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Contador de avisos sin leer: dos latidos al cargar para que se vea, y quieto
   después, que un parpadeo continuo cansa. */
.gti-latido { animation: gti-latido 1.6s var(--gti-curva) 0.6s 2; }
@keyframes gti-latido {
  0% { box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.55); }
  70% { box-shadow: 0 0 0 7px rgba(220, 53, 69, 0); }
  100% { box-shadow: 0 0 0 0 rgba(220, 53, 69, 0); }
}

/* Indicador de carga de HTMX */
.htmx-indicator { opacity: 0; transition: opacity 0.2s; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

/* Tablas anchas: siempre desplazamiento propio, nunca del body */
.gti-scroll-x { overflow-x: auto; }

/* Foco visible accesible */
:focus-visible { outline: 2px solid var(--gti-acento); outline-offset: 2px; }

/* Quien haya pedido menos animación en el sistema no la recibe. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

@media print {
  .gti-sidebar, .navbar, .gti-sin-imprimir { display: none !important; }
  .gti-contenido { padding: 0; }
  body::after, .gti-progreso { display: none !important; }
  /* En papel, sombras y fondos tintados solo gastan tinta. */
  .card { box-shadow: none !important; border-color: #ccc !important; }
  body { background: #fff !important; }
}

/* Alpine: evita el destello de los bloques con x-show antes de inicializar */
[x-cloak] { display: none !important; }

/* ── Calendario de ausencias ─────────────────────────────────────────────── */
#calendario { --fc-border-color: var(--bs-border-color); --fc-page-bg-color: transparent; }
#calendario .fc-toolbar-title { font-size: 1.05rem; font-weight: 650; letter-spacing: -0.012em; }
#calendario .fc-button { font-size: .8125rem; padding: .25rem .6rem; border-radius: var(--gti-radio-xs); }
#calendario .fc-button-primary {
  background: var(--gti-superficie);
  border-color: var(--bs-border-color);
  color: var(--bs-body-color);
}
#calendario .fc-button-primary:not(:disabled):hover { background: var(--bs-tertiary-bg); border-color: var(--bs-border-color); color: var(--bs-body-color); }
#calendario .fc-button-primary:not(:disabled).fc-button-active,
#calendario .fc-button-primary:not(:disabled):active {
  background: var(--gti-acento-relleno);
  border-color: var(--gti-acento-relleno-borde);
  color: var(--gti-acento-texto);
}
#calendario .fc-event { font-size: .75rem; border-radius: var(--gti-radio-xs); cursor: pointer; }

/* FullCalendar pinta los números de día y las cabeceras de la semana como
   `<a>`, así que heredaban el color de enlace: una cuadrícula entera de cifras
   teal subrayadas tapaba las ausencias, que es lo que hay que mirar aquí. */
#calendario .fc-daygrid-day-number,
#calendario .fc-col-header-cell-cushion {
  color: var(--bs-body-color);
  text-decoration: none;
}
#calendario .fc-daygrid-day-number { font-size: .8125rem; }
#calendario .fc-col-header-cell-cushion {
  font-size: .75rem;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: .045em;
  color: var(--bs-secondary-color);
}
#calendario .fc-day-other .fc-daygrid-day-number { opacity: .45; }
#calendario .fc-day-today { background: var(--gti-acento-suave) !important; }
/* Pendiente: rayado tenue sobre su color y un aro hueco delante del nombre,
   el mismo símbolo que la leyenda. */
#calendario .gti-evento-pendiente {
  border-style: dashed !important;
  background-image: repeating-linear-gradient(-45deg, rgba(255, 255, 255, 0.28) 0 4px, transparent 4px 8px);
  opacity: 0.8;
}
#calendario .gti-evento-pendiente .fc-event-title::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin: 0 0.3rem 0 0.1rem;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  vertical-align: 0.02em;
}
#calendario .gti-evento-propio { font-weight: 600; box-shadow: inset 2px 0 0 rgba(0,0,0,.35); }
#calendario .fc-multimonth-title { font-size: .875rem; font-weight: 650; }

/* ── Comparativa tipo Gantt ──────────────────────────────────────────────── */
.gti-gantt { border-collapse: separate; border-spacing: 0; font-size: .75rem; }
.gti-gantt th, .gti-gantt td { border-bottom: 1px solid var(--bs-border-color); padding: 0; }
.gti-gantt thead th { position: sticky; top: 0; z-index: 3; background: var(--gti-tabla-cabecera); }
.gti-gantt .gti-col-persona {
  position: sticky; left: 0; z-index: 2;
  background: var(--gti-superficie); min-width: 11rem; max-width: 11rem;
  padding: .25rem .5rem; border-right: 1px solid var(--bs-border-color);
}
.gti-gantt thead .gti-col-persona { z-index: 4; background: var(--gti-tabla-cabecera); }
.gti-gantt .gti-celda { width: 1.35rem; height: 1.6rem; text-align: center; }
.gti-gantt .gti-celda-nolab { background: repeating-linear-gradient(45deg, transparent, transparent 3px, var(--bs-tertiary-bg) 3px, var(--bs-tertiary-bg) 6px); }
.gti-gantt .gti-celda-festivo { background: rgba(220, 53, 69, .12); }
.gti-gantt .gti-marca { display: block; width: 100%; height: 100%; }
.gti-gantt .gti-marca-pendiente { opacity: .55; }
.gti-gantt .gti-fin-semana { border-left: 1px solid var(--bs-border-color); }
.gti-leyenda-tipo { display: inline-flex; align-items: center; gap: .35rem; font-size: .75rem; }

/* ── Listas de opciones con casillas ─────────────────────────────────────────
   Sustituyen a los `<select multiple>`, que obligan a saber que se marca con
   Ctrl y que en varios navegadores se ven directamente mal. */
.gti-opciones .form-check { margin-bottom: 0.15rem; }
.gti-opciones .form-check-label { cursor: pointer; }
.gti-opciones-scroll { max-height: 14rem; overflow-y: auto; }

/* ── Panel de inicio ─────────────────────────────────────────────────────────
   Rejilla bento asimétrica de piezas con **doble bisel**: una bandeja exterior
   tenue con un filo de 1px y, dentro, el núcleo con su propio fondo y un brillo
   interior arriba, con radios concéntricos. Parece una pieza encajada en vez
   de un recuadro pegado al fondo.

   Todo el movimiento va por `transform` y `opacity`. La revelación al entrar
   en pantalla la hace app.js con IntersectionObserver, y sin JS (o con menos
   animación pedida) todo está visible desde el principio. */
.gti-panel {
  --gti-bisel-radio: 1.5rem;
  --gti-bisel-hueco: 0.375rem;
  display: grid;
  gap: 1.25rem;
}

/* El panel lleva su propia coreografía: la entrada genérica de la página
   sobra aquí y se sumaría a la de cada pieza. */
.gti-contenido > .gti-panel { animation: none; }

.gti-bisel {
  position: relative;
  padding: var(--gti-bisel-hueco);
  border-radius: var(--gti-bisel-radio);
  background: color-mix(in srgb, var(--gti-acento) 4%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gti-acento) 9%, transparent);
  transition: transform 600ms var(--gti-curva-muelle), box-shadow 400ms var(--gti-curva);
}

.gti-bisel-nucleo {
  position: relative;
  height: 100%;
  padding: 1.375rem 1.5rem;
  border-radius: calc(var(--gti-bisel-radio) - var(--gti-bisel-hueco));
  background: var(--gti-superficie);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 1px 2px rgba(74, 36, 14, 0.04),
    0 12px 32px -18px rgba(74, 36, 14, 0.18);
  overflow: hidden;
}

[data-bs-theme="dark"] .gti-bisel { background: rgba(255, 255, 255, 0.025); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06); }
[data-bs-theme="dark"] .gti-bisel-nucleo {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 16px 40px -20px rgba(0, 0, 0, 0.8);
}

/* El mismo foco de luz que las tarjetas: un halo que sigue al cursor. */
@media (hover: hover) and (pointer: fine) {
  .gti-bisel-nucleo::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: radial-gradient(22rem circle at var(--gti-x, 50%) var(--gti-y, -40%),
      rgba(var(--gti-acento-rgb), 0.07), transparent 60%);
    opacity: 0;
    transition: opacity 400ms var(--gti-curva);
  }
  .gti-bisel:hover .gti-bisel-nucleo::after { opacity: 1; }
}

/* ── Revelación al entrar en pantalla ──
   Con `translate` y `scale` sueltos, no con `transform`: así la revelación no
   pisa los efectos de pasar el ratón (elevar, inclinar), que usan `transform`.
   Al terminar quedan en `none`, sin bloque contenedor para modales ni sticky. */
.gti-js [data-gti-revelar] {
  opacity: 0;
  translate: 0 18px;
  scale: 0.985;
  transition: opacity 800ms var(--gti-curva), translate 900ms var(--gti-curva),
    scale 900ms var(--gti-curva), transform 500ms var(--gti-curva-muelle),
    box-shadow 400ms var(--gti-curva);
  transition-delay: var(--gti-retardo, 0ms);
}
.gti-js [data-gti-revelar].visible { opacity: 1; translate: none; scale: none; }

/* ── Portada ── */
.gti-hero { --gti-bisel-radio: 2rem; }
.gti-hero-nucleo {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 2rem;
  align-items: end;
  padding: clamp(1.5rem, 1rem + 2vw, 2.75rem);
  background:
    radial-gradient(40rem 20rem at 0% 0%, rgba(var(--gti-acento-rgb), 0.06), transparent 60%),
    var(--gti-superficie);
}

/* Orbe que deriva despacio detrás del saludo. Solo `transform`. */
.gti-hero-orbe {
  position: absolute;
  width: 26rem;
  height: 26rem;
  right: -6rem;
  top: -10rem;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(var(--gti-acento-rgb), 0.13), transparent 64%);
  pointer-events: none;
  animation: gti-deriva 18s var(--gti-curva-muelle) infinite alternate;
}
@keyframes gti-deriva {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to { transform: translate3d(-5rem, 4rem, 0) scale(1.15); }
}

.gti-hero-texto { position: relative; }

.gti-ceja {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.75rem;
  border-radius: 50rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
  background: color-mix(in srgb, var(--gti-acento) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gti-acento) 12%, transparent);
}
.gti-ceja-punto {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: #22a06b;
  box-shadow: 0 0 0 0 rgba(34, 160, 107, 0.5);
  animation: gti-pulso 2.4s var(--gti-curva) infinite;
}
@keyframes gti-pulso {
  0% { box-shadow: 0 0 0 0 rgba(34, 160, 107, 0.45); }
  70%, 100% { box-shadow: 0 0 0 6px rgba(34, 160, 107, 0); }
}

.gti-hero-titulo {
  margin: 1rem 0 0.75rem;
  font-size: clamp(2.1rem, 1.3rem + 3.2vw, 3.6rem);
  font-weight: 650;
  line-height: 1;
  letter-spacing: -0.045em;
  color: var(--bs-emphasis-color);
}
.gti-hero-nombre {
  background: linear-gradient(100deg, var(--bs-emphasis-color) 20%, var(--gti-acento) 80%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.gti-hero-resumen {
  max-width: 34rem;
  margin-bottom: 1.5rem;
  color: var(--bs-secondary-color);
}
.gti-hero-resumen a { font-weight: 600; text-decoration: none; }

.gti-hero-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem; }

/* ── Botón píldora con el icono en su propia isla ── */
.gti-pildora {
  display: inline-flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0.4rem 0.4rem 0.4rem 1.25rem;
  border: 0;
  border-radius: 50rem;
  font-weight: 600;
  font-size: 0.9375rem;
  text-decoration: none;
  color: var(--gti-acento-contraste);
  background: var(--gti-acento);
  box-shadow: 0 10px 24px -10px rgba(var(--gti-acento-rgb), 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.18);
  transition: transform 500ms var(--gti-curva-muelle), box-shadow 400ms var(--gti-curva);
}
.gti-pildora:hover { color: var(--gti-acento-contraste); box-shadow: 0 14px 30px -10px rgba(var(--gti-acento-rgb), 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.18); }
.gti-pildora:active { transform: scale(0.97); }
.gti-pildora-icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
  transition: transform 500ms var(--gti-curva-muelle);
}
.gti-pildora:hover .gti-pildora-icono { transform: translate(2px, -2px) scale(1.06); }
.gti-pildora-sm { font-size: 0.8125rem; padding-left: 1rem; }
.gti-pildora-sm .gti-pildora-icono { width: 1.75rem; height: 1.75rem; }

.gti-enlace-sutil {
  position: relative;
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--bs-body-color);
  text-decoration: none;
}
.gti-enlace-sutil::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0.3);
  transform-origin: left;
  opacity: 0.5;
  transition: transform 500ms var(--gti-curva);
}
.gti-enlace-sutil:hover::after { transform: scaleX(1); }

/* ── La semana ── */
.gti-semana {
  position: relative;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.gti-dia {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  min-height: 9.5rem;
  padding: 0.75rem 0.25rem;
  border-radius: 1rem;
  background: color-mix(in srgb, var(--bs-body-bg) 70%, transparent);
  box-shadow: inset 0 0 0 1px var(--bs-border-color-translucent);
  transition: transform 500ms var(--gti-curva-muelle), background-color 300ms ease;
}
.gti-dia:hover { transform: translateY(-4px); }
.gti-dia.es-finde { opacity: 0.55; }
.gti-dia.es-hoy {
  background: var(--gti-acento);
  color: var(--gti-acento-contraste);
  box-shadow: 0 14px 28px -14px rgba(var(--gti-acento-rgb), 0.9);
}
.gti-dia-nombre {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.7;
}
.gti-dia-numero {
  font-size: 1.5rem;
  font-weight: 650;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.gti-dia-gente { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; margin-top: 0.25rem; }

/* ── Un día que se infla ──────────────────────────────────────────────────────
   El panel de cada día existe siempre, ya maquetado y escondido con un recorte
   (`clip-path`) del tamaño exacto de su columna: app.js mide la columna y fija
   --l, --r y --t. Abrir es soltar el recorte hasta cubrir la franja entera, con
   un pequeño rebote; cerrar es volver a encogerlo sobre su columna. Así parece
   que el propio día crece, no que aparezca una ventana encima. */
.gti-semana-marco { position: relative; }
.gti-dia[data-gti-dia] { cursor: pointer; }
.gti-dia[data-gti-dia]:focus-visible { outline: 2px solid var(--gti-acento); outline-offset: 3px; }
.gti-dia[data-gti-dia]:hover .gti-mini-mas { transform: scale(1.12); background: var(--gti-acento); color: var(--gti-acento-contraste); }
.gti-mini-mas { transition: transform 400ms var(--gti-curva-muelle), background-color 250ms ease, color 250ms ease; }

.gti-dia-panel {
  --l: 0px;
  --r: 0px;
  --t: 0px;
  /* 3px de más por cada lado: tapa del todo las columnas, también en las
     esquinas redondeadas, donde asomaba la de hoy. */
  position: absolute;
  left: -3px;
  right: -3px;
  bottom: -3px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  min-height: calc(100% + 6px);
  max-height: 22rem;
  padding: 1rem 1.125rem 1.125rem;
  border-radius: 1.25rem;
  background: var(--gti-superficie);
  box-shadow: 0 0 0 1px var(--gti-bandeja-filo), 0 18px 40px -20px rgba(74, 36, 14, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  visibility: hidden;
  pointer-events: none;
  opacity: 0;
  clip-path: inset(var(--t) var(--r) 0 var(--l) round 1rem);
  will-change: clip-path, opacity;
  /* Cerrar: las fichas se apagan primero (ver más abajo) y luego el panel se
     recoge sobre su columna acelerando y frenando suave, sin tirón al final. */
  transition:
    clip-path 560ms cubic-bezier(0.65, 0, 0.35, 1) 90ms,
    opacity 260ms ease 390ms,
    visibility 0s linear 650ms;
}
[data-bs-theme="dark"] .gti-dia-panel {
  box-shadow: 0 0 0 1px var(--gti-bandeja-filo), 0 30px 60px -24px rgba(0, 0, 0, 0.9),
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.gti-dia-panel.abierto {
  visibility: visible;
  pointer-events: auto;
  opacity: 1;
  clip-path: inset(0 0 0 0 round 1.25rem);
  /* Abrir: arranca suave y frena largo, sin rebote, para que se vea crecer
     desde la columna en vez de aparecer de golpe; el fundido corto del
     principio quita el filo del recorte. */
  transition:
    clip-path 700ms cubic-bezier(0.45, 0, 0.1, 1),
    opacity 240ms ease,
    visibility 0s;
}

.gti-dia-panel-cabeza {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
}
.gti-dia-panel-fecha { display: inline-flex; align-items: baseline; gap: 0.5rem; }
.gti-dia-panel-fecha strong { font-size: 1.75rem; font-weight: 650; letter-spacing: -0.04em; line-height: 1; }
.gti-dia-panel-fecha span { font-size: 0.8125rem; font-weight: 600; color: var(--bs-secondary-color); }
.gti-dia-panel-total {
  padding: 0.2rem 0.6rem;
  border-radius: 50rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--gti-acento-contraste);
  background: var(--gti-acento);
}

.gti-dia-panel-gente {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: 0.375rem;
  margin: 0;
  padding: 0 0.125rem 0.25rem 0;
  list-style: none;
  overflow-y: auto;
  scrollbar-width: thin;
}
.gti-dia-panel-gente li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  padding: 0.3rem 0.5rem 0.3rem 0.3rem;
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--tono) 9%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tono) 18%, transparent);
  opacity: 0;
  translate: 0 6px;
  scale: 0.98;
  transition: opacity 140ms ease, translate 200ms ease, scale 200ms ease;
}
.gti-dia-panel.abierto .gti-dia-panel-gente li {
  opacity: 1;
  translate: none;
  scale: none;
  transition: opacity 480ms cubic-bezier(0.22, 1, 0.36, 1), translate 600ms cubic-bezier(0.22, 1, 0.36, 1),
    scale 600ms cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(260ms + min(var(--i), 14) * 28ms);
}
.gti-dia-panel-gente .gti-mini-avatar { box-shadow: none; }
.gti-dia-panel-texto { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.gti-dia-panel-texto strong, .gti-dia-panel-texto small {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.gti-dia-panel-texto strong { font-size: 0.8125rem; font-weight: 600; }
.gti-dia-panel-texto small { font-size: 0.6875rem; color: var(--bs-secondary-color); }

.gti-dia-panel-cabeza { opacity: 0; translate: 0 4px; transition: opacity 140ms ease, translate 200ms ease; }
.gti-dia-panel.abierto .gti-dia-panel-cabeza {
  opacity: 1;
  translate: none;
  transition: opacity 480ms cubic-bezier(0.22, 1, 0.36, 1) 140ms, translate 600ms cubic-bezier(0.22, 1, 0.36, 1) 140ms;
}

/* La mecha: al salir con el ratón se consume y, cuando se acaba, el día se
   desinfla. Volver a entrar la reenciende. */
.gti-dia-panel-mecha {
  position: absolute;
  left: 1.125rem;
  right: 1.125rem;
  bottom: 0.5rem;
  height: 2px;
  border-radius: 2px;
  background: var(--gti-acento);
  opacity: 0;
  transform-origin: left;
  transform: scaleX(1);
}
.gti-dia-panel.desinflando .gti-dia-panel-mecha {
  opacity: 0.55;
  transform: scaleX(0);
  transition: transform var(--gti-espera, 1400ms) linear, opacity 200ms ease;
}

@media (prefers-reduced-motion: reduce) {
  .gti-dia-panel, .gti-dia-panel.abierto { transition: none; }
  .gti-dia-panel-gente li, .gti-dia-panel-cabeza { transition: none !important; }
}

.gti-mini-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 32%;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #fff;
  /* Sin valor propio de `--tono`: así hereda el del contenedor (la ficha de
     persona lo fija según el tipo de ausencia) y solo cae al acento si nadie
     lo ha puesto. */
  background: var(--tono, var(--gti-acento));
  box-shadow: 0 0 0 2px var(--gti-superficie);
}
.gti-dia.es-hoy .gti-mini-avatar { box-shadow: 0 0 0 2px var(--gti-acento); }
.gti-mini-mas { background: var(--bs-secondary-bg); color: var(--bs-body-color); }

/* ── Bento ── */
.gti-bento {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-flow: dense;
  /* Cada pieza con su altura: con mucha gente fuera, «Quién está fuera» crece
     y estirar a su vecina dejaba un hueco vacío enorme. */
  align-items: start;
  gap: 1.25rem;
}
/* Mosaico de bloques: dos columnas explícitas, cada una apilando los suyos.
   Arrancan siempre a la misma altura (con `column-count` el navegador decidía
   dónde cortar y la segunda podía empezar descuadrada) y un bloque largo a un
   lado no deja vacío enfrente, porque la otra columna sigue apilando. */
.gti-mosaico {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: 1.25rem;
}
.gti-mosaico-columna { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
/* En una sola columna, los bloques se intercalan (izquierda, derecha,
   izquierda…) para no mandar «Mis solicitudes» al final de todo. */
@media (max-width: 1199.98px) {
  .gti-mosaico { display: flex; flex-direction: column; align-items: stretch; }
  .gti-mosaico-columna { display: contents; }
  .gti-mosaico-columna:first-child > :nth-child(1) { order: 1; }
  .gti-mosaico-columna:last-child > :nth-child(1) { order: 2; }
  .gti-mosaico-columna:first-child > :nth-child(2) { order: 3; }
  .gti-mosaico-columna:last-child > :nth-child(2) { order: 4; }
  .gti-mosaico-columna:first-child > :nth-child(3) { order: 5; }
  .gti-mosaico-columna:last-child > :nth-child(3) { order: 6; }
  .gti-mosaico-columna:first-child > :nth-child(4) { order: 7; }
  .gti-mosaico-columna:last-child > :nth-child(4) { order: 8; }
}

/* ── Quién está fuera, compacto ── */
.gti-fuera-hoy { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.gti-pila { display: flex; align-items: center; padding-left: 0.5rem; }
.gti-pila .gti-mini-avatar {
  width: 2.25rem;
  height: 2.25rem;
  margin-left: -0.45rem;
  border-radius: 50%;
  font-size: 0.6875rem;
  box-shadow: 0 0 0 3px var(--gti-superficie);
  transition: transform 450ms var(--gti-curva-muelle);
  position: relative;
  z-index: calc(10 - var(--i, 0));
}
.gti-pila .gti-mini-avatar:hover { transform: translateY(-4px) scale(1.08); z-index: 11; }
.gti-pila .gti-mini-mas { background: var(--bs-secondary-bg); color: var(--bs-body-color); }
.gti-reparto {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 1rem;
  margin: 0.875rem 0 0;
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
}
.gti-reparto > span { display: inline-flex; align-items: center; gap: 0.375rem; }
.gti-reparto b { color: var(--bs-emphasis-color); font-weight: 650; font-variant-numeric: tabular-nums; }
.gti-filas-compactas li { padding-top: 0.45rem; padding-bottom: 0.45rem; }
.gti-mas-enlace {
  display: inline-block;
  margin-top: 0.5rem;
  font-size: 0.78rem;
  font-weight: 600;
  text-decoration: none;
}

.gti-ancho-5 { grid-column: span 5; }
.gti-ancho-6 { grid-column: span 6; }
.gti-ancho-7 { grid-column: span 7; }

/* Indicadores: la de vacaciones, más ancha, y el resto a partes iguales, sean
   dos, tres o cuatro piezas según el rol. */
.gti-bento-kpi {
  align-items: stretch;
  grid-template-columns: minmax(0, 1.7fr);
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
}
.gti-kpi-tile .gti-bisel-nucleo { display: flex; flex-direction: column; gap: 0.25rem; padding: 1.25rem 1.375rem; }
.gti-kpi-vacaciones .gti-bisel-nucleo { flex-direction: row; align-items: center; gap: 1.25rem; }

/* Inclinación 3D al pasar el ratón (app.js fija --rx y --ry). */
@media (hover: hover) and (pointer: fine) {
  .gti-kpi-tile {
    transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  }
}

.gti-cifra-lg { font-size: 2.25rem; letter-spacing: -0.04em; margin-top: 0.75rem; }
.gti-cifra-xl { font-size: 3rem; letter-spacing: -0.05em; line-height: 1; }
.gti-rotulo-fino { font-size: 0.75rem; color: var(--bs-secondary-color); opacity: 0.8; margin-top: 0.25rem; }

/* Icono de trazo fino dentro de una isla tintada. */
.gti-icono-linea {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.75rem;
  font-size: 1rem;
  color: var(--bs-secondary-color);
  background: var(--bs-tertiary-bg);
  box-shadow: inset 0 0 0 1px var(--bs-border-color-translucent);
  transition: transform 500ms var(--gti-curva-muelle);
}
.gti-bisel:hover .gti-icono-linea { transform: rotate(-8deg) scale(1.06); }
.gti-tono-acento { color: var(--gti-acento); background: var(--gti-acento-suave); }
.gti-tono-violeta { color: #6d28d9; background: rgba(124, 58, 237, 0.1); }
.gti-tono-aviso { color: #997404; background: rgba(255, 193, 7, 0.16); }
.gti-tono-peligro { color: #b42318; background: rgba(220, 53, 69, 0.12); }
[data-bs-theme="dark"] .gti-tono-violeta { color: #c4b5fd; }
[data-bs-theme="dark"] .gti-tono-aviso { color: #ffda6a; }
[data-bs-theme="dark"] .gti-tono-peligro { color: #ff8a8a; }

/* Anillo de vacaciones: el trazo se dibuja hasta lo que queda. */
.gti-anillo { position: relative; flex: 0 0 auto; width: 6.5rem; height: 6.5rem; }
.gti-anillo svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.gti-anillo circle { fill: none; stroke-width: 9; stroke-linecap: round; }
.gti-anillo-pista { stroke: var(--bs-tertiary-bg); }
.gti-anillo-valor {
  stroke: var(--gti-acento);
  stroke-dasharray: 100;
  stroke-dashoffset: calc(100 - var(--valor, 0));
  transition: stroke-dashoffset 1400ms var(--gti-curva) 250ms;
}
.gti-js [data-gti-revelar]:not(.visible) .gti-anillo-valor { stroke-dashoffset: 100; }
.gti-anillo-centro {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 1.35rem;
  color: var(--gti-acento);
}

/* Barra de dedicación. */
.gti-medidor {
  height: 0.375rem;
  margin-top: 0.75rem;
  border-radius: 50rem;
  background: var(--bs-tertiary-bg);
  overflow: hidden;
}
.gti-medidor span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #7c3aed, #a78bfa);
  transform-origin: left;
  transform: scaleX(calc(min(var(--valor, 0), 100) / 100));
  transition: transform 1200ms var(--gti-curva) 300ms;
}
.gti-js [data-gti-revelar]:not(.visible) .gti-medidor span { transform: scaleX(0); }

/* ── Cabecera de bloque ── */
.gti-cabeza {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.125rem;
}
.gti-cabeza h2 {
  flex: 1 1 auto;
  margin: 0;
  font-size: 1rem;
  font-weight: 620;
  letter-spacing: -0.015em;
}
.gti-flecha {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.8125rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.gti-flecha i { transition: transform 450ms var(--gti-curva-muelle); }
.gti-flecha:hover i { transform: translateX(3px); }
.gti-contador {
  min-width: 1.5rem;
  padding: 0.1rem 0.45rem;
  border-radius: 50rem;
  font-size: 0.75rem;
  font-weight: 700;
  text-align: center;
  color: #fff;
  background: #dc3545;
}

.gti-aviso .gti-bisel-nucleo { box-shadow: inset 0 0 0 1px rgba(255, 193, 7, 0.35), 0 12px 32px -18px rgba(153, 116, 4, 0.3); }
.gti-peligro .gti-bisel-nucleo { box-shadow: inset 0 0 0 1px rgba(220, 53, 69, 0.3), 0 12px 32px -18px rgba(180, 35, 24, 0.3); }

/* ── Filas de lista ── */
.gti-filas { list-style: none; margin: 0; padding: 0; font-size: 0.875rem; }
.gti-filas li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.625rem 0.5rem;
  margin: 0 -0.5rem;
  border-radius: 0.75rem;
  transition: background-color 250ms ease, transform 450ms var(--gti-curva-muelle);
}
/* Separador recto pintado como fondo: con un borde o una sombra interior se
   curvaba en los extremos por el redondeo de la fila. */
.gti-filas li + li {
  background: linear-gradient(var(--bs-border-color-translucent), var(--bs-border-color-translucent))
    top center / calc(100% - 1rem) 1px no-repeat;
}
.gti-filas li:hover { background: var(--bs-tertiary-bg); transform: translateX(3px); }
.gti-filas li:hover + li { background-image: none; }
.gti-fecha {
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.gti-ficha-persona {
  --tono: var(--gti-acento);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.75rem 0.25rem 0.25rem;
  border-radius: 50rem;
  font-size: 0.8125rem;
  font-weight: 550;
  background: var(--bs-tertiary-bg);
  box-shadow: inset 0 0 0 1px var(--bs-border-color-translucent);
}
.gti-ficha-persona .gti-mini-avatar { box-shadow: none; }

/* ── Línea de tiempo de hitos ── */
.gti-linea-tiempo { position: relative; list-style: none; margin: 0; padding: 0; }
.gti-linea-tiempo::before {
  content: "";
  position: absolute;
  left: 1.375rem;
  top: 0.75rem;
  bottom: 0.75rem;
  width: 1px;
  background: linear-gradient(var(--bs-border-color), transparent);
}
.gti-linea-tiempo li {
  position: relative;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem 0;
  font-size: 0.875rem;
}
.gti-cuenta {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.875rem;
  line-height: 1;
  background: var(--gti-superficie);
  box-shadow: inset 0 0 0 1px var(--bs-border-color), 0 0 0 4px var(--gti-superficie);
}
.gti-cuenta strong { font-size: 1rem; font-variant-numeric: tabular-nums; }
.gti-cuenta small { font-size: 0.5625rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--bs-secondary-color); }
.gti-linea-texto { flex: 1 1 auto; min-width: 0; }
.es-cerca .gti-cuenta { box-shadow: inset 0 0 0 1px rgba(255, 193, 7, 0.6), 0 0 0 4px var(--gti-superficie); color: #997404; }
.es-urgente .gti-cuenta {
  color: #fff;
  background: #dc3545;
  box-shadow: 0 0 0 4px var(--gti-superficie), 0 8px 18px -8px rgba(220, 53, 69, 0.8);
}
.es-urgente .gti-cuenta small { color: rgba(255, 255, 255, 0.85); }
[data-bs-theme="dark"] .es-cerca .gti-cuenta { color: #ffda6a; }

.gti-wiki-espacios { display: grid; gap: 0.875rem; }

/* ── Responsive ── */
@media (max-width: 1199.98px) {
  .gti-hero-nucleo { grid-template-columns: 1fr; align-items: start; }
  .gti-ancho-5, .gti-ancho-6, .gti-ancho-7 { grid-column: span 12; }
  /* Por debajo de escritorio, flex: la de vacaciones en su propia fila y el
     resto repartiendo la siguiente, sin huecos sea cual sea el número. */
  .gti-bento-kpi { display: flex; flex-wrap: wrap; }
  .gti-kpi-tile { flex: 1 1 0; min-width: 9.5rem; }
  .gti-kpi-vacaciones { flex-basis: 100%; }
}
@media (max-width: 767.98px) {
  .gti-panel { --gti-bisel-radio: 1.25rem; gap: 1rem; }
  .gti-bento { gap: 1rem; }
  .gti-kpi-tile { min-width: calc(50% - 0.5rem); }
  .gti-semana { gap: 0.3rem; }
  .gti-dia { min-height: 7.5rem; padding: 0.5rem 0.1rem; border-radius: 0.75rem; }
  .gti-dia-numero { font-size: 1.15rem; }
  .gti-mini-avatar { width: 1.4rem; height: 1.4rem; font-size: 0.55rem; }
  .gti-cifra-xl { font-size: 2.4rem; }
  .gti-anillo { width: 5.25rem; height: 5.25rem; }
}
@media (prefers-reduced-motion: reduce) {
  .gti-hero-orbe, .gti-ceja-punto { animation: none; }
  .gti-js [data-gti-revelar] { opacity: 1; translate: none; scale: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   El lenguaje del panel, en todas las pantallas
   ───────────────────────────────────────────────────────────────────────────
   Las plantillas repiten unas pocas piezas de Bootstrap (`.card`, `.nav-pills`,
   `.btn`, `.table`, `.list-group`…), así que el estilo se aplica aquí, a esas
   piezas, y cada pantalla lo hereda sin tocar su HTML. Mismo criterio que el
   panel: doble bisel, radios generosos, cifras grandes y movimiento con inercia.
   ═══════════════════════════════════════════════════════════════════════════ */
/* La bandeja es opaca (mezclada con el fondo de página) a propósito: los dos
   anillos se pintan uno encima del otro, y si fueran translúcidos se sumarían
   y saldría un borde gris grueso en vez de un relleno tenue con su filo. */
:root {
  --gti-bandeja: color-mix(in srgb, var(--gti-acento) 3.5%, var(--bs-body-bg));
  --gti-bandeja-filo: color-mix(in srgb, var(--gti-acento) 10%, var(--bs-body-bg));
  --gti-tarjeta-radio: 1.25rem;
  --gti-tarjeta-hueco: 5px;
}
[data-bs-theme="dark"] {
  --gti-bandeja: color-mix(in srgb, #fff 2.5%, var(--bs-body-bg));
  --gti-bandeja-filo: color-mix(in srgb, #fff 7%, var(--bs-body-bg));
}

/* ── Tarjetas: doble bisel sin cambiar el HTML ──
   La bandeja exterior se dibuja con dos anillos de `box-shadow` (relleno tenue y
   filo de 1px) por fuera del borde; el núcleo es la propia tarjeta, con su brillo
   interior arriba. Los bordes de aviso (`border-warning-subtle`…) se conservan. */
.card {
  --bs-card-border-radius: var(--gti-tarjeta-radio);
  --bs-card-inner-border-radius: calc(var(--gti-tarjeta-radio) - 1px);
  --bs-card-spacer-y: 1.125rem;
  --bs-card-spacer-x: 1.375rem;
  --bs-card-cap-padding-y: 0.875rem;
  --bs-card-cap-padding-x: 1.375rem;
  box-shadow:
    0 0 0 var(--gti-tarjeta-hueco) var(--gti-bandeja),
    0 0 0 calc(var(--gti-tarjeta-hueco) + 1px) var(--gti-bandeja-filo),
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 18px 36px -22px rgba(74, 36, 14, 0.28);
}
[data-bs-theme="dark"] .card {
  box-shadow:
    0 0 0 var(--gti-tarjeta-hueco) var(--gti-bandeja),
    0 0 0 calc(var(--gti-tarjeta-hueco) + 1px) var(--gti-bandeja-filo),
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    0 18px 40px -22px rgba(0, 0, 0, 0.85);
}
.shadow-sm.card, .card.shadow-sm { box-shadow: inherit; }

/* La bandeja sobresale 6px por cada lado: los huecos entre tarjetas crecen
   lo justo para que no se toquen. */
.gti-contenido .row.g-3 { --bs-gutter-x: 1.75rem; --bs-gutter-y: 1.75rem; }
.gti-contenido .card.mb-3 { margin-bottom: 1.75rem !important; }
.gti-contenido .card.mt-3 { margin-top: 1.75rem !important; }
.gti-contenido .card + .card { margin-top: 1.75rem; }

.card-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--bs-border-color-translucent);
  font-size: 0.9375rem;
  font-weight: 620;
  letter-spacing: -0.012em;
  color: var(--bs-emphasis-color);
}
.card-header.small, .card-header .small.fw-semibold { font-size: 0.9375rem !important; }
.card-header.py-2 { padding-top: 0.875rem !important; padding-bottom: 0.875rem !important; }
/* El icono que abre la cabecera, en su isla tintada, como en el panel. */
.card-header > .bi:first-child,
.card-header > span:first-child > .bi:first-child {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.875rem;
  height: 1.875rem;
  margin-right: 0.25rem !important;
  border-radius: 0.625rem;
  font-size: 0.9rem;
  color: var(--gti-acento);
  background: var(--gti-acento-suave);
  transition: transform 500ms var(--gti-curva-muelle);
}
.card:hover .card-header > .bi:first-child,
.card:hover .card-header > span:first-child > .bi:first-child { transform: rotate(-8deg) scale(1.06); }
.card-header > a, .card-header .text-decoration-none { font-size: 0.8125rem; font-weight: 600; }
.card-header.d-flex > :last-child:not(:first-child) { margin-left: auto; }

.card-footer {
  background: transparent;
  border-top: 1px solid var(--bs-border-color-translucent);
}

/* Las tarjetas dentro de un modal o de otra tarjeta no llevan bandeja. */
.modal .card, .card .card { box-shadow: inset 0 0 0 1px var(--bs-border-color-translucent); }

/* ── Tablas dentro de tarjetas ── */
.card .table > thead th {
  background: transparent;
  border-bottom: 1px solid var(--bs-border-color-translucent);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  padding-top: 0.875rem;
  padding-bottom: 0.625rem;
}
.card .table > :not(caption) > * > :first-child { padding-left: 1.375rem; }
.card .table > :not(caption) > * > :last-child { padding-right: 1.375rem; }
.card .table > tbody > tr > * { border-bottom-color: var(--bs-border-color-translucent); }
.table > tbody > tr { transition: background-color 250ms ease; }
.table > tbody > tr:hover > * { background-color: color-mix(in srgb, var(--gti-acento) 3.5%, transparent); }

/* ── Listas ── */
.card .list-group { --bs-list-group-bg: transparent; }
.card .accordion { --bs-accordion-bg: transparent; --bs-accordion-btn-bg: transparent; --bs-accordion-border-color: var(--bs-border-color-translucent); }
.list-group-item {
  transition: background-color 250ms ease;
  border-color: var(--bs-border-color-translucent);
}
.card .list-group-flush > .list-group-item { padding-left: 1.375rem; padding-right: 1.375rem; }
.list-group-flush > .list-group-item:hover { background: color-mix(in srgb, var(--gti-acento) 3.5%, transparent); }

/* ── Cabecera de página ──
   Título grande y apretado, con una ceja encima que dice en qué área estás. */
.gti-encabezado { position: relative; margin-bottom: 2rem !important; }
.gti-encabezado::before {
  content: "";
  position: absolute;
  left: -4rem;
  top: -4rem;
  width: 28rem;
  height: 14rem;
  pointer-events: none;
  background: radial-gradient(closest-side, rgba(var(--gti-acento-rgb), 0.08), transparent);
  z-index: -1;
}
.gti-encabezado .gti-ceja { margin-bottom: 0.875rem; }
.gti-encabezado h1 {
  font-size: clamp(1.75rem, 1.2rem + 1.8vw, 2.6rem);
  font-weight: 650;
  letter-spacing: -0.04em;
  line-height: 1.05;
  color: var(--bs-emphasis-color);
}
.gti-encabezado h1 + p, .gti-encabezado h1 + .text-body-secondary { margin-top: 0.375rem; }

/* La acción principal de la página, como la píldora del panel. */
.gti-encabezado .btn {
  --bs-btn-padding-y: 0.5rem;
  --bs-btn-padding-x: 1.125rem;
  --bs-btn-font-size: 0.875rem;
}
.gti-encabezado .btn-primary {
  --bs-btn-color: var(--gti-acento-contraste);
  --bs-btn-bg: var(--gti-acento);
  --bs-btn-border-color: var(--gti-acento);
  --bs-btn-hover-color: var(--gti-acento-contraste);
  --bs-btn-hover-bg: var(--gti-acento-fuerte);
  --bs-btn-hover-border-color: var(--gti-acento-fuerte);
  --bs-btn-active-color: var(--gti-acento-contraste);
  --bs-btn-active-bg: var(--gti-acento-fuerte);
  --bs-btn-active-border-color: var(--gti-acento-fuerte);
  box-shadow: 0 10px 22px -12px rgba(var(--gti-acento-rgb), 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.16);
}
.gti-encabezado .btn-primary:hover { box-shadow: 0 14px 28px -12px rgba(var(--gti-acento-rgb), 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.16); }
.gti-encabezado .btn .bi { transition: transform 500ms var(--gti-curva-muelle); }
.gti-encabezado .btn:hover .bi { transform: translateX(1px) scale(1.1); }

/* ── Botones: píldoras ── */
.btn { --bs-btn-border-radius: 50rem; }
.btn-sm { --bs-btn-border-radius: 50rem; }
.input-group .btn, .btn-group .btn, .btn-group-vertical .btn { --bs-btn-border-radius: var(--gti-radio-sm); }
.btn-outline-secondary {
  --bs-btn-border-color: var(--bs-border-color);
  --bs-btn-hover-bg: var(--bs-tertiary-bg);
  --bs-btn-hover-color: var(--bs-emphasis-color);
  --bs-btn-hover-border-color: var(--bs-border-color);
  --bs-btn-active-bg: var(--bs-secondary-bg);
  --bs-btn-active-color: var(--bs-emphasis-color);
}

/* ── Pestañas de cada área: control segmentado ──
   Una bandeja con las pestañas dentro; la activa es una pieza elevada. */
.gti-contenido .nav-pills {
  display: inline-flex;
  flex-wrap: nowrap;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  gap: 0.25rem !important;
  padding: 0.3125rem;
  margin-bottom: 1.75rem !important;
  border-radius: 50rem;
  background: var(--gti-bandeja);
  box-shadow: inset 0 0 0 1px var(--gti-bandeja-filo);
}
.gti-contenido .nav-pills::-webkit-scrollbar { display: none; }
.gti-contenido .nav-pills .nav-link {
  white-space: nowrap;
  border-radius: 50rem;
  padding: 0.4375rem 1rem !important;
  font-weight: 550;
  color: var(--bs-secondary-color);
  transition: color 250ms ease, background-color 300ms var(--gti-curva), box-shadow 300ms var(--gti-curva),
    transform 450ms var(--gti-curva-muelle);
}
.gti-contenido .nav-pills .nav-link:hover { color: var(--bs-emphasis-color); }
.gti-contenido .nav-pills .nav-link:active { transform: scale(0.97); }
.gti-contenido .nav-pills .nav-link.active {
  color: var(--bs-emphasis-color);
  background: var(--gti-superficie);
  box-shadow: 0 1px 2px rgba(74, 36, 14, 0.08), 0 6px 14px -8px rgba(74, 36, 14, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.8);
}
[data-bs-theme="dark"] .gti-contenido .nav-pills .nav-link.active {
  background: rgba(255, 255, 255, 0.09);
  box-shadow: 0 6px 14px -8px rgba(0, 0, 0, 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.gti-contenido .nav-pills .nav-link.active .bi { color: var(--gti-acento); }

/* ── Formularios ── */
.form-control, .form-select {
  border-radius: 0.75rem;
  border-color: var(--bs-border-color);
  box-shadow: inset 0 1px 2px rgba(74, 36, 14, 0.04);
  transition: border-color 250ms ease, box-shadow 300ms var(--gti-curva), background-color 250ms ease;
}
.form-control:not(.form-control-sm):not(.form-control-lg), .form-select:not(.form-select-sm):not(.form-select-lg) {
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}
.form-control-sm, .form-select-sm { border-radius: 0.625rem; }
.form-control:hover, .form-select:hover { border-color: color-mix(in srgb, var(--gti-acento) 30%, var(--bs-border-color)); }
.form-control:focus, .form-select:focus {
  border-color: color-mix(in srgb, var(--gti-acento) 55%, transparent);
  box-shadow: 0 0 0 4px rgba(var(--gti-acento-rgb), 0.12), inset 0 1px 2px rgba(74, 36, 14, 0.04);
}
.form-check-input { transition: background-color 250ms ease, border-color 250ms ease, box-shadow 250ms ease; }
.input-group-text { border-radius: 0.75rem; }

/* ── Avisos ── */
.alert {
  --bs-alert-border-radius: 1rem;
  border-width: 1px;
  box-shadow: 0 10px 24px -18px rgba(74, 36, 14, 0.35);
}

/* ── Menús desplegables ── */
.dropdown-menu {
  --bs-dropdown-border-radius: 1rem;
  --bs-dropdown-padding-x: 0.375rem;
  --bs-dropdown-padding-y: 0.375rem;
  --bs-dropdown-item-border-radius: 0.625rem;
  border-color: var(--bs-border-color-translucent);
  box-shadow: 0 0 0 5px var(--gti-bandeja), 0 24px 48px -16px rgba(74, 36, 14, 0.3);
  animation: gti-menu 220ms var(--gti-curva);
}
/* Popper coloca el menú con `transform` en línea: la animación va por
   `translate` y `opacity` para no pisarlo. */
@keyframes gti-menu { from { opacity: 0; translate: 0 -4px; } to { opacity: 1; translate: none; } }
.dropdown-item { border-radius: var(--bs-dropdown-item-border-radius); transition: background-color 200ms ease; }

/* ── Modales ── */
.modal-content {
  --bs-modal-border-radius: 1.5rem;
  --bs-modal-inner-border-radius: calc(1.5rem - 1px);
  border-color: var(--bs-border-color-translucent);
  box-shadow: 0 0 0 6px var(--gti-bandeja), 0 0 0 7px var(--gti-bandeja-filo), 0 40px 80px -24px rgba(74, 36, 14, 0.45);
}
.modal-header, .modal-footer { border-color: var(--bs-border-color-translucent); }
.modal-title { font-weight: 650; letter-spacing: -0.02em; }
.modal.fade .modal-dialog { transition: transform 450ms var(--gti-curva), opacity 300ms ease; transform: translateY(16px) scale(0.98); }
.modal.show .modal-dialog { transform: none; }
.modal-backdrop.show { opacity: 0.4; }

/* ── Paginación ── */
.pagination { --bs-pagination-border-radius: 50rem; gap: 0.25rem; }
.pagination .page-link { border-radius: 50rem !important; min-width: 2.125rem; text-align: center; border-color: var(--bs-border-color-translucent); }

/* ── Estado vacío ── */
.gti-vacio { padding: 2rem 1rem; text-align: center; }
.gti-vacio-icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  margin-bottom: 0.875rem;
  border-radius: 1.125rem;
  font-size: 1.4rem;
  color: var(--gti-acento);
  background: var(--gti-acento-suave);
  box-shadow: 0 0 0 6px var(--gti-bandeja), 0 0 0 7px var(--gti-bandeja-filo);
  animation: gti-flotar 5s var(--gti-curva-muelle) infinite alternate;
}
@keyframes gti-flotar { from { transform: translateY(0); } to { transform: translateY(-4px); } }

/* ── Barra lateral de cristal ─────────────────────────────────────────────────
   El mismo cristal que la isla de arriba (desenfoque, brillo del filo, sombra
   amplia) en un panel alto. Dentro, dos piezas que mueve app.js:

   * el indicador: la pastilla de la sección activa. Al cambiar de página sale
     de la sección de la que vienes y se desliza hasta la nueva;
   * el brillo: una pastilla tenue que sigue al ratón de opción en opción.

   Ambas se mueven con `transform` y cambian de alto con `height` en una sola
   pieza pequeña; los enlaces no se tocan. Sin JS (`.con-indicador` ausente)
   el enlace activo conserva su propio fondo. */
.gti-sidebar .nav-link { border-radius: 0.875rem; position: relative; z-index: 1; }
.gti-sidebar .nav-link.activo {
  background: var(--gti-superficie);
  box-shadow: 0 0 0 1px var(--gti-bandeja-filo), 0 6px 16px -10px rgba(74, 36, 14, 0.35);
}
[data-bs-theme="dark"] .gti-sidebar .nav-link.activo { background: rgba(255, 255, 255, 0.06); }

.gti-sidebar {
  --gti-cristal: rgba(255, 255, 255, 0.55);
  --gti-cristal-filo: rgba(255, 255, 255, 0.95);
}
[data-bs-theme="dark"] .gti-sidebar {
  --gti-cristal: rgba(28, 31, 36, 0.55);
  --gti-cristal-filo: rgba(255, 255, 255, 0.24);
}

@media (min-width: 992px) {
  .gti-sidebar {
    top: var(--gti-navbar-alto);
    height: calc(100vh - var(--gti-navbar-alto) - 0.75rem);
    height: calc(100dvh - var(--gti-navbar-alto) - 0.75rem);
    margin: 0 0 0.75rem 0.875rem;
    flex-basis: calc(var(--gti-sidebar-ancho) - 0.875rem);
    width: calc(var(--gti-sidebar-ancho) - 0.875rem);
    padding: 0.625rem;
    border: 0;
    border-radius: 1.375rem;
  }
}
.gti-sidebar {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0) 40%),
    var(--gti-cristal);
  -webkit-backdrop-filter: blur(22px) saturate(190%);
  backdrop-filter: blur(22px) saturate(190%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 0 0 1px rgba(74, 36, 14, 0.07),
    0 18px 40px -20px rgba(74, 36, 14, 0.3);
}
[data-bs-theme="dark"] .gti-sidebar {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0) 40%),
    var(--gti-cristal);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 0 0 1px rgba(255, 255, 255, 0.06),
    0 18px 40px -20px rgba(0, 0, 0, 0.8);
}
.gti-sidebar::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  pointer-events: none;
  background: linear-gradient(160deg, var(--gti-cristal-filo), rgba(255, 255, 255, 0.1) 30%,
    rgba(255, 255, 255, 0) 70%, rgba(255, 255, 255, 0.35));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .gti-sidebar { --gti-cristal: var(--gti-superficie) !important; }
}
@media (max-width: 991.98px) {
  /* En móvil sale como un panel de cristal desde la izquierda, con las
     esquinas de la derecha redondeadas y algo más opaco. */
  .gti-sidebar {
    --gti-cristal: rgba(255, 255, 255, 0.82);
    inset: calc(var(--gti-navbar-alto) - 0.25rem) auto 0.75rem 0.75rem;
    border-radius: 1.375rem;
    transform: translateX(calc(-100% - 1rem));
    transition: transform 520ms var(--gti-curva);
  }
  [data-bs-theme="dark"] .gti-sidebar { --gti-cristal: rgba(28, 31, 36, 0.86); }
}

[data-gti-menu] { position: relative; }
.gti-menu-indicador, .gti-menu-brillo {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 0;
  list-style: none;
  pointer-events: none;
  border-radius: 0.875rem;
  opacity: 0;
}
/* El indicador: pastilla elevada de cristal más denso, con el acento a la izquierda. */
.gti-menu-indicador {
  background: rgba(255, 255, 255, 0.85);
  box-shadow: inset 0 1px 0 #fff, 0 0 0 1px rgba(74, 36, 14, 0.06), 0 8px 20px -10px rgba(74, 36, 14, 0.4);
  transition: transform 620ms cubic-bezier(0.22, 1, 0.36, 1), height 620ms cubic-bezier(0.22, 1, 0.36, 1),
    opacity 300ms ease;
}
.gti-menu-indicador::before {
  content: "";
  position: absolute;
  left: 0.3rem;
  top: 50%;
  width: 3px;
  height: 1.1rem;
  margin-top: -0.55rem;
  border-radius: 3px;
  background: var(--gti-acento);
  box-shadow: 0 0 10px rgba(var(--gti-acento-rgb), 0.6);
}
[data-bs-theme="dark"] .gti-menu-indicador {
  background: rgba(255, 255, 255, 0.09);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 8px 20px -10px rgba(0, 0, 0, 0.8);
}
/* El brillo: tenue, sigue al ratón con algo de inercia y se apaga al salir. */
.gti-menu-brillo {
  background: rgba(255, 255, 255, 0.5);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.6);
  transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1), height 420ms cubic-bezier(0.22, 1, 0.36, 1),
    opacity 250ms ease;
}
[data-bs-theme="dark"] .gti-menu-brillo { background: rgba(255, 255, 255, 0.05); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05); }
.gti-menu-indicador.listo { opacity: 1; }
[data-gti-menu].con-brillo .gti-menu-brillo { opacity: 1; }
.gti-menu-indicador.sin-transicion, .gti-menu-brillo.sin-transicion { transition: none; }

/* Con las piezas en marcha, los enlaces dejan su propio fondo. */
.gti-sidebar.con-indicador .nav-link,
.gti-sidebar.con-indicador .nav-link:hover,
.gti-sidebar.con-indicador .nav-link.activo { background: transparent; box-shadow: none; }
.gti-sidebar.con-indicador .nav-link.activo::before { display: none; }
.gti-sidebar .nav-link.activo { color: var(--bs-emphasis-color); }
.gti-sidebar .nav-link.activo i:first-child { color: var(--gti-acento); }
@media (prefers-reduced-motion: reduce) {
  .gti-menu-indicador, .gti-menu-brillo { transition: opacity 150ms ease; }
}

@media (max-width: 767.98px) {
  :root { --gti-tarjeta-radio: 1rem; --gti-tarjeta-hueco: 4px; }
  .gti-contenido .row.g-3 { --bs-gutter-x: 1.25rem; --bs-gutter-y: 1.25rem; }
  .gti-contenido .card.mb-3 { margin-bottom: 1.25rem !important; }
  .gti-encabezado::before { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .gti-vacio-icono, .dropdown-menu { animation: none; }
}
@media print {
  .card, .modal-content { box-shadow: none !important; }
  .gti-js [data-gti-revelar] { opacity: 1 !important; translate: none !important; scale: none !important; }
  .gti-encabezado::before { display: none; }
}


/* ── Convocatorias: valoración automática ── */
.gti-encaje {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.15rem 0.55rem;
  border-radius: 50rem;
  font-size: 0.72rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--bs-secondary-color);
  background: var(--bs-tertiary-bg);
  box-shadow: inset 0 0 0 1px var(--bs-border-color-translucent);
}
.gti-encaje.es-medio { color: var(--gti-acento); background: var(--gti-acento-suave); }
.gti-encaje.es-alto {
  color: var(--gti-acento-contraste);
  background: linear-gradient(135deg, color-mix(in srgb, var(--gti-acento) 80%, #fff), var(--gti-acento));
  box-shadow: 0 4px 10px -4px rgba(var(--gti-acento-rgb), 0.6);
}
.gti-ia-motivo {
  margin: 0.375rem 0 0;
  max-width: 62ch;
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── Borradores de solicitud ── */
.gti-borrador .card-body { padding: clamp(1.25rem, 1rem + 1.5vw, 2.5rem); }
.gti-borrador section + section { margin-top: 2rem; }
.gti-borrador h2 {
  font-size: 1.25rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  margin-bottom: 0.875rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--bs-border-color-translucent);
}
.gti-borrador h3 { font-size: 1.05rem; font-weight: 620; margin: 1.25rem 0 0.5rem; }
.gti-borrador h4 { font-size: 0.95rem; font-weight: 600; font-style: italic; margin: 1rem 0 0.4rem; }
.gti-borrador p, .gti-borrador li { max-width: 75ch; line-height: 1.65; }
.gti-borrador ul, .gti-borrador ol { padding-left: 1.25rem; }
.gti-borrador-aviso {
  font-size: 0.8125rem;
  color: var(--bs-secondary-color);
  padding: 0.625rem 0.875rem;
  border-radius: 0.75rem;
  background: var(--bs-tertiary-bg);
  margin-bottom: 1.75rem;
}
mark.gti-completar {
  padding: 0.05rem 0.3rem;
  border-radius: 0.3rem;
  font-weight: 600;
  color: #6b4e00;
  background: rgba(255, 193, 7, 0.32);
}
[data-bs-theme="dark"] mark.gti-completar { color: #ffe08a; background: rgba(255, 193, 7, 0.18); }

.gti-redactando { display: flex; align-items: center; gap: 1rem; }
.gti-redactando-icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 3rem;
  height: 3rem;
  border-radius: 1rem;
  font-size: 1.3rem;
  color: var(--gti-acento);
  background: var(--gti-acento-suave);
  animation: gti-latir 1.8s var(--gti-curva-muelle) infinite;
}
@keyframes gti-latir { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08) rotate(-6deg); } }
@media (prefers-reduced-motion: reduce) { .gti-redactando-icono { animation: none; } }


/* Interruptor (un enlace con aspecto de switch, ver convocatorias/lista.html). */
.gti-interruptor {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--bs-body-color);
  text-decoration: none;
  user-select: none;
}
.gti-interruptor:hover { color: var(--bs-emphasis-color); }
.gti-interruptor-pista {
  position: relative;
  display: inline-block;
  width: 2.5rem;
  height: 1.5rem;
  border-radius: 50rem;
  background: var(--bs-secondary-bg);
  box-shadow: inset 0 1px 2px rgba(74, 36, 14, 0.15);
  transition: background-color 300ms var(--gti-curva);
}
.gti-interruptor-bola {
  position: absolute;
  top: 0.1875rem;
  left: 0.1875rem;
  width: 1.125rem;
  height: 1.125rem;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(74, 36, 14, 0.35);
  transition: transform 400ms var(--gti-curva-muelle);
}
.gti-interruptor[aria-checked="true"] .gti-interruptor-pista { background: var(--gti-acento); }
.gti-interruptor[aria-checked="true"] .gti-interruptor-bola { transform: translateX(1rem); }
[data-bs-theme="dark"] .gti-interruptor[aria-checked="true"] .gti-interruptor-bola { background: var(--gti-acento-contraste); }


/* Utilidades que Bootstrap no trae. `min-w-0` deja que un hijo de un flex se
   encoja por debajo de su contenido: sin ella, `text-truncate` no corta nada y
   el texto largo se sale de la tarjeta. */
.min-w-0 { min-width: 0; }
.gti-dos-lineas {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}


/* ── Ideas de proyecto ── */
.gti-ideas { display: grid; grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
.gti-idea {
  display: flex;
  flex-direction: column;
  padding: 1.125rem 1.25rem;
  border-radius: 1rem;
  background: var(--bs-tertiary-bg);
  box-shadow: inset 0 0 0 1px var(--bs-border-color-translucent);
  transition: transform 450ms var(--gti-curva-muelle), box-shadow 300ms ease;
}
.gti-idea:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--gti-acento-borde), 0 12px 24px -16px rgba(74, 36, 14, 0.35); }
.gti-idea form { margin-top: auto; }
.gti-idea-titulo { font-size: 1rem; font-weight: 650; letter-spacing: -0.015em; margin: 0; overflow-wrap: anywhere; }
.gti-idea-acronimo {
  display: inline-block;
  margin-right: 0.375rem;
  padding: 0.05rem 0.45rem;
  border-radius: 0.4rem;
  font-size: 0.8rem;
  color: var(--gti-acento-contraste);
  background: var(--gti-acento);
}
.gti-idea ul:not(.gti-idea-datos) { padding-left: 1.1rem; }
.gti-idea-datos { padding-left: 0; display: grid; gap: 0.2rem; }
.gti-ideas-formulario { margin-top: 0.25rem; }


/* ── Búsqueda inversa: de una idea a las convocatorias ── */
.gti-buscador-idea { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: stretch; }
.gti-buscador-idea textarea { flex: 1 1 18rem; min-width: 0; resize: vertical; }
.gti-buscador-idea .btn { align-self: flex-end; }
.gti-busquedas-recientes { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.625rem; }
.gti-busquedas-recientes a {
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: 0.8rem;
  text-decoration: none;
  color: var(--bs-secondary-color);
  background: var(--bs-tertiary-bg);
  box-shadow: inset 0 0 0 1px var(--bs-border-color-translucent);
  transition: color 200ms ease, box-shadow 200ms ease;
}
.gti-busquedas-recientes a:hover { color: var(--bs-body-color); box-shadow: inset 0 0 0 1px var(--gti-acento-borde); }
.gti-busqueda-idea {
  display: flex;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-radius: 1rem;
  background: var(--bs-tertiary-bg);
  box-shadow: inset 0 0 0 1px var(--bs-border-color-translucent);
  overflow-wrap: anywhere;
}
.gti-busqueda-idea .bi { font-size: 1.5rem; line-height: 1; color: var(--gti-acento); }


/* ── Que nada se salga de su tarjeta ──
   Nombres de organismo, identificadores, URL, DOI o acrónimos sin espacios no
   tienen por dónde partir y empujan la tarjeta, o toda la página, hacia la
   derecha. `anywhere` (no `break-word`) cuenta también al calcular el ancho
   mínimo, así que las columnas flex y grid pueden estrecharse en vez de
   crecer. Las tablas no: se desplazan de lado dentro de `.gti-scroll-x`. */
.gti-contenido .card,
.gti-contenido .alert,
.gti-contenido .list-group-item,
.gti-idea,
.gti-busqueda-idea { overflow-wrap: anywhere; }
.gti-contenido .card table { overflow-wrap: normal; }
/* Los hijos de flex y grid no crecen más que su sitio por un texto largo. */
.gti-contenido .row > *,
.gti-ideas > *,
.gti-contenido .card .d-flex > :not(.btn):not(.badge):not(.flex-shrink-0):not(.gti-encaje):not(.text-nowrap):not(.gti-fecha) { min-width: 0; }
/* Las etiquetas largas (una región, un programa) parten línea en vez de salirse. */
.gti-contenido .card .badge,
.gti-idea .badge { max-width: 100%; white-space: normal; text-align: start; }
/* El título de la página: un nombre larguísimo parte en vez de ensanchar la página. */
.gti-encabezado > div:first-child { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
.gti-encabezado h1 { overflow-wrap: anywhere; }


/* ── Fotos en los avatares ──
   La foto llena el avatar con su misma forma. En los mini avatares del
   calendario el color dice el tipo de ausencia: con foto pasa al aro. */
.gti-avatar, .gti-mini-avatar { overflow: hidden; }
.gti-avatar > img, .gti-mini-avatar > img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gti-mini-avatar:has(> img) { box-shadow: 0 0 0 2px var(--tono, var(--gti-acento)); }
.gti-avatar:has(> img) { background: var(--bs-tertiary-bg); }

/* El campo de foto de «Mi perfil». */
.gti-foto-perfil { display: flex; align-items: center; gap: 1rem; }
.gti-foto-perfil input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.gti-foto-perfil .gti-avatar { transition: opacity 250ms ease, filter 250ms ease; }
.gti-foto-perfil.quitando .gti-avatar { opacity: 0.35; filter: grayscale(1); }


/* ── El pulso: avisos que llegan y novedades en la página ── */
.gti-aviso-contador[hidden], .badge[hidden] { display: none !important; }
.gti-toasts {
  position: fixed;
  top: 5rem;
  right: 1rem;
  z-index: 1090;
  display: grid;
  gap: 0.625rem;
  width: min(22rem, calc(100vw - 2rem));
  pointer-events: none;
}
.gti-toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border-radius: 1rem;
  color: var(--bs-body-color);
  text-decoration: none;
  background: color-mix(in srgb, var(--bs-body-bg) 82%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(1.6);
  backdrop-filter: blur(18px) saturate(1.6);
  box-shadow: inset 0 0 0 1px var(--bs-border-color-translucent), 0 18px 40px -18px rgba(0, 0, 0, 0.45);
  opacity: 0;
  translate: 1.5rem 0;
  scale: 0.98;
  transition: opacity 350ms var(--gti-curva), translate 500ms var(--gti-curva-muelle), scale 500ms var(--gti-curva-muelle);
}
.gti-toast.visible { opacity: 1; translate: none; scale: none; }
.gti-toast:hover { color: var(--bs-body-color); box-shadow: inset 0 0 0 1px var(--gti-acento-borde), 0 18px 40px -18px rgba(0, 0, 0, 0.5); }
.gti-toast > .bi { font-size: 1.1rem; line-height: 1.3; color: var(--gti-acento); }
.gti-toast.es-danger > .bi { color: var(--bs-danger); }
.gti-toast.es-warning > .bi { color: var(--bs-warning); }
.gti-toast.es-success > .bi { color: var(--bs-success); }
.gti-toast > div { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.gti-toast strong { display: block; font-size: 0.875rem; font-weight: 650; }
.gti-toast span { display: block; font-size: 0.8rem; color: var(--bs-secondary-color); margin-top: 0.125rem; }
.gti-toast .btn-close { flex: 0 0 auto; font-size: 0.6rem; margin-top: 0.25rem; }
.gti-novedades {
  position: fixed;
  left: 50%;
  bottom: 1.25rem;
  z-index: 1080;
  translate: -50% 0;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1.1rem;
  border: 0;
  border-radius: 50rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--gti-acento-contraste);
  background: var(--gti-acento);
  box-shadow: 0 14px 30px -12px rgba(var(--gti-acento-rgb), 0.85);
  animation: gti-novedades-entra 500ms var(--gti-curva-muelle);
}
@keyframes gti-novedades-entra { from { opacity: 0; translate: -50% 1rem; } }
@media (prefers-reduced-motion: reduce) {
  .gti-toast, .gti-novedades { transition: none; animation: none; }
}


/* ── Convocatorias: cómo puede entrar el grupo ──
   En el listado, una línea de texto (no píldoras): lo confirmado en color normal,
   lo que solo sale de la ficha más tenue y con subrayado punteado. */
.gti-conds {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.15rem 0.4rem;
  margin: 0.4rem 0 0; font-size: 0.78rem; font-weight: 500; color: var(--bs-body-color);
}
.gti-conds > .bi { color: var(--gti-acento); font-size: 0.85rem; margin-right: 0.1rem; }
.gti-conds .es-dudosa {
  color: var(--bs-secondary-color); font-weight: 400;
  text-decoration: underline dotted; text-decoration-color: var(--bs-border-color); text-underline-offset: 3px;
  cursor: help;
}
.gti-conds-sep { color: var(--bs-border-color); }
.gti-condiciones { display: grid; gap: 0.875rem; }
.gti-condicion { display: grid; grid-template-columns: minmax(9rem, 14rem) 1fr; gap: 0.25rem 1rem; }
.gti-condicion dt { font-size: 0.8rem; font-weight: 500; color: var(--bs-secondary-color); }
.gti-condicion dd { margin: 0; font-size: 0.875rem; min-width: 0; }
.gti-dudoso {
  display: inline-grid; place-items: center; width: 1.1rem; height: 1.1rem; margin-left: 0.25rem;
  border-radius: 50%; font-size: 0.7rem; font-weight: 700; color: var(--bs-warning-text-emphasis);
  background: var(--bs-warning-bg-subtle);
}
.gti-cita {
  margin: 0.35rem 0 0; padding: 0.4rem 0.65rem; border-left: 2px solid var(--gti-acento-relleno-borde);
  font-size: 0.78rem; color: var(--bs-secondary-color); background: var(--bs-tertiary-bg); border-radius: 0 0.5rem 0.5rem 0;
}
.gti-cita cite { display: block; margin-top: 0.2rem; font-style: normal; font-size: 0.7rem; opacity: 0.8; }
@media (max-width: 575.98px) { .gti-condicion { grid-template-columns: 1fr; } }


/* ── Círculo de uso de la IA (barra superior) ──
   El aro se llena con `--pct` (0–100); el color dice el estado. */
.gti-uso-ia { position: relative; }
.gti-uso-ia svg { position: absolute; inset: 2px; width: calc(100% - 4px); height: calc(100% - 4px); rotate: -90deg; }
.gti-uso-ia circle { fill: none; stroke-width: 3; }
.gti-uso-ia-pista { stroke: var(--bs-border-color); opacity: 0.6; }
.gti-uso-ia-valor {
  stroke: var(--gti-acento);
  stroke-linecap: round;
  stroke-dasharray: calc(var(--pct, 0) * 1) 100;
  transition: stroke-dasharray 800ms var(--gti-curva), stroke 300ms ease;
}
.gti-uso-ia .bi { position: relative; font-size: 0.85rem; }
.gti-uso-ia.es-medio .gti-uso-ia-valor { stroke: var(--bs-warning); }
.gti-uso-ia.es-alto .gti-uso-ia-valor { stroke: #f08c00; }
.gti-uso-ia.es-agotado .gti-uso-ia-valor { stroke: var(--bs-danger); }
.gti-uso-ia.es-agotado .bi { color: var(--bs-danger); }
.gti-uso-ia-menu { width: 17rem; padding: 1rem 1.1rem; }
.gti-uso-ia-fila { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.82rem; margin-top: 0.35rem; }
.gti-uso-ia-barra { height: 0.3rem; border-radius: 999px; background: var(--bs-tertiary-bg); overflow: hidden; margin-top: 0.25rem; }
.gti-uso-ia-barra span { display: block; height: 100%; border-radius: inherit; background: var(--gti-acento); }
.gti-uso-ia-nota { margin: 0.85rem 0 0; font-size: 0.72rem; color: var(--bs-secondary-color); line-height: 1.4; }
