/* =====================================================================
   LA HOJA DE LAS TRES PANTALLAS.

   Vive en un solo archivo y no dentro de cada HTML. Antes eran ~250 líneas
   copiadas tres veces: un cambio de color había que hacerlo tres veces, y
   bastaba olvidar una para que las pantallas se separaran. Aquí se cambia una
   vez.

   EL LENGUAJE ES EL DE LA GUÍA (`diseñoguia`): documento administrativo, no
   panel de aplicación. Eso quiere decir cuatro cosas, y de ellas sale todo lo
   demás:

     1. NADA DE ESQUINAS REDONDEADAS. Radio cero en todo —tarjetas, cajas,
        botones, píldoras—. Es lo que separa una hoja de trámite de una app.
     2. NADA DE SOMBRAS. Los planos se separan con un filete de 1px y con el
        fondo gris de la página; una sombra suave los haría flotar.
     3. CADA TARJETA LLEVA SU FILETE OSCURO ARRIBA (2px de --tinta). Es la
        marca del documento: dice dónde empieza cada bloque sin necesidad de
        un título más grande.
     4. LOS NÚMEROS SIEMPRE EN MONOESPACIADA. Fechas, folios, horas y totales.

   Va DESPUÉS de Bootstrap y lo pisa por variables donde se puede
   —`--bs-primary`, `--bs-body-bg`, `--bs-border-radius`—, para que los
   componentes que ninguna pantalla toca a mano salgan ya con esta paleta y no
   con la de fábrica.
   ===================================================================== */

/* ------------------------------- PALETA ------------------------------
   Los nombres son los de siempre a propósito: las tres pantallas y sus hojas
   locales ya piden --tinta, --acento, --linea. Cambia el valor, no el nombre,
   y el rediseño entra sin tocar el resto. */
:root {
  --tinta:      #1D2C36;  /* barra lateral, filete superior de las tarjetas */
  --tinta-alta: #16222B;  /* el fondo de la marca, un punto más hondo */
  --tinta-baja: #2C3D48;  /* separadores dentro de la barra */
  --texto:      #101A22;  /* titulares y cifras: el negro de la hoja */
  --fondo:      #E9ECEF;  /* el gris de la página; las tarjetas son las blancas */
  --fondo-2:    #FAFBFC;  /* zebra de tabla y fondos de sub-bloque */
  --banda:      #F5F7F9;  /* las bandas de pie y de filtros */
  --acento:     #1B4F72;  /* azul de expediente: lo que guarda y el total */
  --acento-2:   #164160;  /* su hover */
  --gris:       #66757F;  /* rótulos en versalitas */
  --gris-2:     #5F6E79;  /* texto secundario que sí hay que leer */
  --gris-3:     #96A2AC;  /* signos, conteos, lo que casi no se lee */
  --estado:     #2E6A4E;  /* verde de «disponible», apagado */
  --alerta:     #8A6A1C;  /* ámbar: excepción, en trámite */
  --mal:        #9E2B2B;  /* rojo: deuda, error, negativo */
  --linea:      #D0D7DE;  /* el hairline que dibuja las cajas */
  --linea-2:    #EDF0F3;  /* el hairline entre renglones de una tabla */
  --borde-caja: #C4CBD3;  /* el borde de un campo: más marcado que el hairline */

  --bs-body-bg: var(--fondo);
  --bs-body-color: #1C2630;
  --bs-secondary-color: var(--gris);
  --bs-border-color: var(--linea);
  --bs-primary: var(--acento);
  --bs-primary-rgb: 27, 79, 114;
  --bs-link-color: var(--acento);
  --bs-link-hover-color: var(--acento-2);
  /* Radio cero en TODO Bootstrap de una sola vez: los componentes que ninguna
     pantalla estiliza a mano —list-group, alert, dropdown— salen cuadrados sin
     que haya que ir a buscarlos uno por uno. */
  --bs-border-radius: 0;
  --bs-border-radius-sm: 0;
  --bs-border-radius-lg: 0;
  --bs-border-radius-xl: 0;
  --bs-border-radius-pill: 0;
  --bs-body-font-family: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --bs-body-font-size: .875rem;

  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

body {
  background: var(--fondo);
  font-family: var(--bs-body-font-family);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* La regla que hace cuadrado lo que Bootstrap no lee de sus variables y lo que
   traigan las hojas locales de cada pantalla. Va una sola vez y con
   `!important` porque su trabajo es justamente ganarle a lo que venga después:
   sin ella habría que ir cazando `border-radius` por los tres HTML. */
*, *::before, *::after { border-radius: 0 !important; }

/* CIFRAS DE ANCHO FIJO EN TODA LA APLICACIÓN.
   Sin esto un «1» ocupa menos que un «8» y las columnas de horas bailan de
   renglón en renglón: en un sistema que es casi todo números, es lo primero
   que se nota y lo último que se explica. */
.n, .num, table, .form-control, .cifra { font-variant-numeric: tabular-nums; }

a { color: var(--acento); text-decoration: none; }
a:hover { color: var(--acento-2); text-decoration: underline; }
::placeholder { color: #9AA5B0; }

/* ---------------------------- COMPONENTES ----------------------------
   Los botones son etiquetas de trámite: versalitas espaciadas, cuadradas y sin
   sombra. El primario es el azul de expediente. */
.btn {
  font-size: .75rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  padding: .625rem 1.125rem;
}
.btn-sm { font-size: .6875rem; letter-spacing: .09em; padding: .4375rem .75rem; }
.btn-primary {
  --bs-btn-bg: var(--acento);
  --bs-btn-border-color: var(--acento-2);
  --bs-btn-hover-bg: var(--acento-2);
  --bs-btn-hover-border-color: var(--acento-2);
  --bs-btn-active-bg: #123448;
  --bs-btn-active-border-color: #123448;
  --bs-btn-disabled-bg: var(--acento);
  --bs-btn-disabled-border-color: var(--acento-2);
}
.btn-outline-secondary {
  --bs-btn-color: var(--gris-2);
  --bs-btn-bg: #fff;
  --bs-btn-border-color: var(--borde-caja);
  --bs-btn-hover-bg: #fff;
  --bs-btn-hover-color: var(--texto);
  --bs-btn-hover-border-color: #8A959F;
  --bs-btn-active-bg: #fff;
  --bs-btn-active-color: var(--texto);
  --bs-btn-active-border-color: var(--texto);
}
.btn-peligro {
  --bs-btn-color: var(--mal);
  --bs-btn-bg: #fff;
  --bs-btn-border-color: var(--borde-caja);
  --bs-btn-hover-bg: #F7ECEC;
  --bs-btn-hover-color: var(--mal);
  --bs-btn-hover-border-color: var(--mal);
}
.btn:focus-visible { box-shadow: 0 0 0 2px rgba(27,79,114,.25); }

/* Los campos: 36px de alto, borde marcado y foco por filete interior en vez de
   halo. Un halo difuso alrededor de una caja cuadrada la vuelve a redondear a
   ojo; el filete interior no. */
/* El fondo blanco va escrito: Bootstrap pinta los campos con `--bs-body-bg`, y
   como ese es el gris de la página, sin esta línea las cajas salen del color
   del fondo y desaparecen dentro de la tarjeta. */
.form-control, .form-select {
  background-color: #fff;
  border-color: var(--borde-caja);
  min-height: 36px;
  font-size: .8125rem;
}
.form-control-sm, .form-select-sm { min-height: 32px; font-size: .78125rem; }
.form-control:focus, .form-select:focus {
  border-color: var(--acento);
  box-shadow: inset 0 0 0 1px var(--acento);
}
.form-control[readonly] {
  background: #F4F6F8; color: #1C2630;
  font-family: var(--mono); font-weight: 600; letter-spacing: .04em;
}
.form-check-input { border-color: var(--borde-caja); }
.form-check-input:checked { background-color: var(--acento); border-color: var(--acento); }
.form-check-input:focus { border-color: var(--acento); box-shadow: inset 0 0 0 1px var(--acento); }
/* Fechas, horas y cantidades en monoespaciada también dentro del campo: se
   capturan comparándolas con lo que ya está en la tabla de al lado. */
input[type="date"], input[type="time"], input[type="number"] { font-family: var(--mono); }

/* =====================================================================
   ARMAZÓN: barra lateral fija + marco de contenido.
   ===================================================================== */
.app { display: flex; min-height: 100vh; background: var(--fondo); }

.barra {
  width: 236px;
  flex: 0 0 236px;
  background: var(--tinta);
  color: #E6EBEF;
  display: flex;
  flex-direction: column;
  position: sticky; top: 0; align-self: flex-start;
  height: 100vh;
  transition: width .18s ease, flex-basis .18s ease;
}
/* Colapsada queda un riel de 62px, no desaparece: el botón que la vuelve a
   abrir vive dentro de ella, y una barra que se esconde entera se lleva puesto
   el botón. Es la misma regla en móvil, para no mantener dos comportamientos
   distintos. */
body.menu-compacto .barra { width: 62px; flex-basis: 62px; }
body.menu-compacto .barra .texto { display: none; }

/* La marca. Es lo primero que se ve al abrir y lo que dice de qué sistema es
   esta pantalla; sin ella la barra es una lista de tres enlaces sueltos. */
.marca {
  display: flex; align-items: center; gap: 11px;
  padding: 0 16px;
  min-height: 60px;
  background: var(--tinta-alta);
  border-bottom: 1px solid var(--tinta-baja);
}
/* La sigla va cuadrada y en monoespaciada: es un código de módulo, no un
   logotipo. */
.marca .sigla {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  background: var(--acento); color: #fff;
  font-family: var(--mono);
  font-size: .625rem; font-weight: 600; letter-spacing: .04em;
}
.marca .texto { display: flex; flex-direction: column; gap: 2px; line-height: 1.2; min-width: 0; }
.marca .texto b {
  font-size: .75rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: #fff; white-space: nowrap;
}
.marca .texto small {
  font-size: .5625rem; letter-spacing: .13em; text-transform: uppercase;
  color: #78909F; white-space: nowrap;
}

.barra nav { display: flex; flex-direction: column; padding: 20px 0 0; }
.barra nav a {
  color: #BCCAD4; text-decoration: none;
  padding: 12px 20px; font-size: .84375rem; font-weight: 400;
  white-space: nowrap; overflow: hidden;
  border-left: 3px solid transparent;
  transition: background .12s, color .12s;
}
.barra nav a:hover { background: #24343F; color: #fff; text-decoration: none; }
.barra nav a[aria-current] {
  color: #fff; font-weight: 600;
  background: #263945;
  border-left-color: #7FA9C9;
}
.barra .salir {
  margin-top: auto; color: #BCCAD4; text-decoration: none;
  padding: 16px 20px; font-size: .78125rem;
  border-top: 1px solid var(--tinta-baja);
  white-space: nowrap; overflow: hidden;
}
.barra .salir:hover { color: #fff; background: #24343F; text-decoration: none; }

/* La hamburguesa: tres barras dibujadas y no el carácter «☰», que cambia de
   peso y de alto en cada sistema y en una barra estrecha eso se ve. El «☰» del
   HTML se apaga con `font-size: 0` —el nombre del botón sale de su aria-label,
   no del carácter—, así que ninguna pantalla tiene que tocar su marcado. */
.hamburguesa {
  background: none; border: 0; cursor: pointer;
  margin-left: auto; padding: 8px 4px;
  display: flex; flex-direction: column; justify-content: center; gap: 4px;
  font-size: 0; line-height: 0; color: transparent;
}
.hamburguesa::before, .hamburguesa::after {
  content: ''; display: block; width: 18px; height: 2px; background: #9FB1BD;
}
/* Tres barras con dos pseudo-elementos: la de en medio es la sombra dura de la
   primera. */
.hamburguesa::before { box-shadow: 0 6px 0 #9FB1BD; margin-bottom: 4px; }
.hamburguesa:hover::before, .hamburguesa:hover::after { background: #fff; }
.hamburguesa:hover::before { box-shadow: 0 6px 0 #fff; }
/* Colapsada, la marca cede su sitio al botón: el riel de 62px no da para el
   logotipo y el botón a la vez, y el que tiene que seguir ahí es el que la
   vuelve a abrir. */
body.menu-compacto .marca { justify-content: center; padding: 0; }
body.menu-compacto .marca .sigla { display: none; }
body.menu-compacto .hamburguesa { margin: 0; }

/* En el riel cada enlace se queda con su inicial, en monoespaciada como los
   números de módulo de la guía. Sin ella el menú colapsado son tres franjas en
   blanco: se sabe que hay tres cosas, no cuáles. */
.barra nav a .inicial { display: none; }
body.menu-compacto .barra nav a {
  padding: 12px 0; text-align: center; border-left-width: 3px;
}
body.menu-compacto .barra nav a .inicial {
  display: block; font-family: var(--mono);
  font-size: .75rem; font-weight: 600; letter-spacing: .04em;
}
body.menu-compacto .barra .salir { text-align: center; padding-left: 0; padding-right: 0; }

.marco { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

/* =====================================================================
   ENCABEZADO DE PANTALLA

   Una banda blanca con el nombre de la sección a la izquierda y los datos que
   sitúan lo que se está viendo a la derecha —la ventana de fechas, el día
   simulado—. Es lo que hace que cada pantalla se lea como un documento y no
   como una página suelta, y es también el único sitio donde se dice de qué
   días habla todo lo de abajo, en vez de repetirlo panel por panel.
   ===================================================================== */
.encabezado {
  background: #fff;
  border-bottom: 1px solid var(--linea);
  padding: 16px 28px;
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}
.encabezado .rotulo {
  display: block;
  font-size: .5625rem; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--gris);
  margin-bottom: 6px;
}
.encabezado h1 {
  font-size: 1.25rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase;
  margin: 0; color: var(--texto);
}
.encabezado .contexto {
  display: flex; align-items: center; gap: 22px; flex-wrap: wrap;
  font-size: .78125rem; color: var(--gris-2);
}
.encabezado .contexto:empty { display: none; }
/* Un dato del encabezado: rótulo arriba, valor abajo. Es la forma de meter
   cifras en la banda sin que compitan con el título. */
.dato { display: flex; flex-direction: column; gap: 3px; line-height: 1.2; }
.dato .k {
  font-size: .5625rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--gris);
}
.dato .v {
  font-family: var(--mono);
  font-size: .78125rem; font-weight: 500; color: #1C2630;
}

.contenido { padding: 16px 20px 32px; }

/* =============================== TARJETAS ============================
   Blanca, filete de 1px alrededor y filete oscuro de 2px arriba. Ese filete es
   la firma del sistema: sin él, sobre el fondo gris, una tarjeta y un hueco se
   parecen demasiado. */
/* Sin `overflow: hidden`: existía para recortar las esquinas redondeadas de lo
   que iba dentro —una tabla a ras del borde—, y con radio cero no hay nada que
   recortar. Quitarlo es lo que deja salir de la tarjeta al desplegable de
   sugerencias del buscador, que antes se cortaba contra el borde de abajo. */
.tarjeta {
  background: #fff;
  border: 1px solid var(--linea);
  border-top: 2px solid var(--tinta);
  box-shadow: none;
}
.tarjeta .cabecera {
  padding: 11px 16px;
  border-bottom: 1px solid var(--linea-2);
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.tarjeta .cabecera h2 {
  font-size: .84375rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase;
  margin: 0; color: var(--texto);
}
.tarjeta .cuerpo { padding: 12px 16px 14px; }
.tarjeta .pie {
  padding: 8px 16px; border-top: 1px solid var(--linea); background: var(--banda);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  font-size: .65625rem; color: var(--gris-2);
}

/* ============================== PESTAÑAS =============================
   Botones que se ven como pestañas de expediente, dentro de la cabecera de
   una tarjeta (que entonces va con `p-0`). Son los lados de UNA misma
   pantalla: sirven para saber de un vistazo en cuál se está, no para navegar
   a otra parte. Viven aquí porque las usan dos pantallas: los universos de
   excepciones y las consultas de tiempo extra. */
.universos { display: flex; gap: 0; flex-wrap: wrap; }
.universo {
  background: none; border: 0; cursor: pointer;
  padding: 13px 20px; font: inherit;
  font-size: .6875rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--gris-2);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.universo:hover { color: var(--texto); background: var(--fondo-2); }
.universo[aria-pressed="true"] {
  color: var(--acento); border-bottom-color: var(--acento); background: #fff;
}
/* Apagadas mientras no hay a quién consultar: se ven, para que la pantalla no
   cambie de forma al elegir persona, pero no responden. */
.universo:disabled { color: var(--linea); cursor: default; }
.universo:disabled:hover { background: none; color: var(--linea); }

/* La etiqueta de la derecha de una cabecera: la ventana, el conteo, el total.
   Va en versalitas para que se lea como un dato del documento y no como una
   segunda línea del título. */
.etiqueta {
  color: var(--gris-2); font-size: .625rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
}
.etiqueta.der { margin-left: auto; }

label, .form-label {
  color: var(--gris); font-size: .59375rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
  margin-bottom: 7px;
}

/* =============================== TABLAS ==============================
   Encabezado gris en versalitas espaciadas, renglones alternados, hairlines en
   vez de rejilla y números a la derecha. La tabla es el documento: casi todo
   lo que hace esta aplicación acaba siendo una de éstas, y es donde se gana o
   se pierde la impresión de que el sistema es serio. */
.tabla-scroll { overflow: auto; }
/* Un renglón más de lo que cabía antes: con 420 la última fila quedaba
   partida a media altura y parecía que la tabla se había cortado sola. */
.tabla-scroll.alta { max-height: 461px; }
.tabla-scroll table {
  margin: 0; border-collapse: collapse; font-size: .8125rem;
  /* La tabla se ciñe a lo que dice y no se estira para llenar la tarjeta: con
     siete columnas, repartir el hueco sobrante las separa tanto que el renglón
     deja de leerse como uno solo. Si no cabe, el contenedor ya tiene scroll. */
  width: max-content; max-width: 100%;
}
.tabla-scroll thead th {
  position: sticky; top: 0; z-index: 1; background: #EDF1F4;
  color: #47555F; font-weight: 600; font-size: .59375rem;
  text-transform: uppercase; letter-spacing: .09em;
  padding: 7px 10px; border-bottom: 1px solid var(--borde-caja);
  white-space: nowrap; text-align: left;
}
.tabla-scroll td {
  padding: 6px 10px; line-height: 1.35;
  border-bottom: 1px solid var(--linea-2); vertical-align: top;
}
/* La zebra. En una tabla de siete columnas de números el ojo pierde el renglón
   a mitad de camino, y una franja tenue lo sostiene mejor que una rejilla. */
.tabla-scroll tbody tr:nth-child(even) > td { background: var(--fondo-2); }
.tabla-scroll tbody tr:hover > td { background: #F4F7F9; }
.tabla-scroll .num, .tabla-scroll th.num { text-align: right; }
.tabla-scroll .centro, .tabla-scroll th.centro { text-align: center; }
/* Los números y la primera columna, en monoespaciada: son las que se comparan
   de renglón en renglón y las que tienen que quedar alineadas. */
.tabla-scroll .num, .tabla-scroll tbody td:first-child {
  font-family: var(--mono); font-size: .78125rem;
}
/* La primera columna es la que identifica el renglón —la fecha, el folio, el
   empleado—: pesa un punto más que las demás. */
.tabla-scroll tbody td:first-child { font-weight: 500; color: #1C2630; }

.negativo { color: var(--mal); }
.positivo { color: var(--acento); }
.tenue { color: var(--gris-3); }
.folio, .mono { font-family: var(--mono); font-size: .75rem; letter-spacing: -.01em; }

/* Píldora de estado. Cuadrada, delineada y con un cuadrito de color a la
   izquierda: en una tabla con un renglón por día, siete rellenos de color
   seguidos pesan más que los números, y el cuadrito da el color sin gritar. */
.pildora {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 8px;
  font-size: .59375rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .11em; white-space: nowrap;
  border: 1px solid #A9C6B4; color: var(--estado); background: #ECF3EE;
}
.pildora::before {
  content: ''; width: 5px; height: 5px; flex: 0 0 auto; background: currentColor;
}
.pildora.pagado, .pildora.gris {
  border-color: var(--borde-caja); color: #6B7A85; background: #F1F3F5;
}
.pildora.excepcion, .pildora.ambar {
  border-color: #D4C58E; color: var(--alerta); background: #F7F2E4;
}
.pildora.mala, .pildora.roja {
  border-color: #D9AEAE; color: var(--mal); background: #F7ECEC;
}
/* Día festivo. Azul de expediente y no ámbar: el ámbar ya es «excepción», y en
   la bandeja de excepciones los dos se pintan en el mismo renglón —un festivo
   aprobado lleva las dos—. Con el mismo color no se distinguiría cuál dice por
   qué el día está en la lista y cuál dice que ya se firmó. */
.pildora.festivo, .pildora.azul {
  border-color: #A9BDD0; color: var(--acento); background: #E8EFF5;
}

/* Estados de una zona de contenido. `.vacio` es el "no hay nada", y va
   centrado y tenue para que se lea como un estado y no como un error. */
.vacio {
  color: var(--gris-3); padding: 34px 16px; text-align: center;
  font-size: .8125rem;
}
.error {
  color: var(--mal); padding: 14px 20px; font-size: .8125rem;
  background: #F7ECEC; border-top: 1px solid #D9AEAE;
}
.aviso {
  padding: 10px 20px; font-size: .78125rem; color: var(--gris-2);
  border-top: 1px solid var(--linea); background: var(--banda);
}
/* Mismo par que `.mensaje` / `.mensaje.mal`: el aviso que no es informativo
   sino un «algo está mal». Antes iba en un `style=` dentro del módulo que lo
   pinta, y eso obligaba a abrirle la mano a la política de contenido. */
.aviso.mal { color: var(--mal); }

/* El pie de un formulario: el mensaje de "guardando", "listo" o el error. */
.mensaje { font-size: .78125rem; color: var(--gris-2); }
.mensaje.mal { color: var(--mal); }
.mensaje.bien { color: var(--estado); }

/* =====================================================================
   LA CARGA: lo que se ve mientras el servidor contesta.

   Es la única parte de la pantalla que se mueve, así que se mueve poco y
   siempre igual. EL GESTO ES UNO SOLO —el filete—: una línea de 2px que se
   dibuja de izquierda a derecha hasta llenar su hueco y luego se recoge por
   el mismo lado. Es el filete superior de la tarjeta trazándose solo, y por
   eso encaja donde encaja: nada gira, nada rebota, nada flota. Una rueda
   girando en una hoja donde no hay una sola esquina redondeada se ve pegada
   de otra aplicación.

   Cuatro sitios, el mismo gesto:
     · Bajo el encabezado, cuando hay CUALQUIER petición en vuelo. Lo pone y
       lo quita `comun/http.js`, así que ninguna pantalla se tiene que
       acordar de encenderlo.
     · En el hueco de un panel que todavía no tiene datos (`.cargando`), con
       su rótulo debajo en versalitas.
     · Al pie del botón que está guardando (`.btn.trabajando`).
     · En el borde superior de una tarjeta que se está repintando
       (`.tarjeta.trabajando`).

   Y `.esqueleto`, que no es el filete: es el dibujo en gris de la tabla que
   viene. Se usa donde ya se sabe qué forma va a tener lo que llega, porque
   entonces la pantalla no da el salto de alto que da un texto centrado
   cuando lo sustituye una tabla de doce renglones.

   NADA DE VELOS NI DE PANTALLAS COMPLETAS EN BLANCO. Lo que se está
   consultando se marca donde está; el resto del documento se sigue leyendo.
   ===================================================================== */

/* El filete se dibuja y se recoge. Va con `left`/`right` y no con
   `transform` a propósito: así nunca se sale de su hueco, y no hace falta
   recortar con `overflow` lo que sobresale —que en la tarjeta del buscador
   se llevaría por delante el desplegable de sugerencias—. */
@keyframes carga-filete {
  0%   { left: 0;    right: 100%; }
  46%  { left: 0;    right: 0;    }
  54%  { left: 0;    right: 0;    }
  100% { left: 100%; right: 0;    }
}

/* Aparece con retraso, y ese retraso es media razón de ser del componente:
   una petición que contesta en 150 ms no debe encender nada. Sin esto,
   moverse por una pantalla rápida es ver parpadear una línea azul en cada
   clic, que es justo lo que hace que un sistema se sienta inestable. */
@keyframes carga-aparece { to { opacity: 1; } }

/* El gris del esqueleto respira. Muy poco: es un relleno provisional, no
   algo que haya que mirar. */
@keyframes carga-respira { 0%, 100% { opacity: 1; } 50% { opacity: .48; } }

/* ---------------------- 1. EL FILETE DEL ENCABEZADO ------------------
   El indicador general del sistema. Vive en el borde de abajo de la banda
   blanca —donde ya hay un hairline—, así que al encenderse no empuja nada
   ni abre un hueco: la línea que ya estaba ahí se pone azul y camina.
   ------------------------------------------------------------------- */
.encabezado { position: relative; }
.encabezado::after {
  content: '';
  position: absolute; bottom: -1px; left: 0; right: 100%;
  height: 2px; background: var(--acento);
  opacity: 0; pointer-events: none;
}
body.trabajando .encabezado::after {
  animation: carga-filete 1.4s ease-in-out .2s infinite,
             carga-aparece 1ms linear .2s forwards;
}

/* ------------------- 2. EL HUECO DE UN PANEL SIN DATOS ---------------
   Sustituye al «Cargando…» gris de antes. Mismo sitio y mismo alto que
   `.vacio` —los dos son estados de una zona de contenido y se turnan en el
   mismo hueco—, pero el rótulo va en versalitas como los demás rótulos del
   documento y encima lleva su filete.
   ------------------------------------------------------------------- */
.cargando {
  display: flex; flex-direction: column; align-items: center; gap: 13px;
  padding: 34px 16px;
  color: var(--gris);
  font-size: .625rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
}
/* Angosto y centrado: es una marca de estado, no una barra de progreso que
   prometa saber cuánto falta. No lo sabe. */
.cargando .filete {
  position: relative;
  width: 132px; height: 2px; flex: 0 0 auto;
  background: var(--linea);
}
.cargando .filete::after {
  content: '';
  position: absolute; top: 0; bottom: 0; left: 0; right: 100%;
  background: var(--acento);
  animation: carga-filete 1.4s ease-in-out infinite;
}
/* Dentro de un hueco chico —el detalle desplegado de una persona— el bloque
   se encoge: 34px de alto abren la fila de más y la tabla que llega luego
   la vuelve a cerrar. */
.cargando.corta { padding: 18px 16px; gap: 10px; }
.cargando.corta .filete { width: 96px; }

/* ------------------------- 3. EL BOTÓN QUE GUARDA --------------------
   El filete al pie del botón, en el color de su propia letra. El botón se
   sigue apagando con `disabled` —eso es lo que impide el segundo envío—;
   esto sólo dice por qué está apagado, que es lo que antes había que
   deducir del mensaje de al lado.
   ------------------------------------------------------------------- */
.btn.trabajando { position: relative; cursor: progress; }
.btn.trabajando::after {
  content: '';
  position: absolute; bottom: 0; left: 0; right: 100%;
  height: 2px; background: currentColor; opacity: .6;
  animation: carga-filete 1.4s ease-in-out infinite;
}

/* --------------------- 4. LA TARJETA QUE SE REPINTA ------------------
   Cuando lo que se renueva es la tarjeta entera y sus cifras siguen en
   pantalla. El filete oscuro de arriba hace de carril y el azul lo recorre:
   la tarjeta no se vacía —los números de antes se siguen leyendo— pero dice
   que está a media actualización.
   ------------------------------------------------------------------- */
.tarjeta.trabajando { position: relative; }
.tarjeta.trabajando::before {
  content: '';
  position: absolute; top: -2px; left: 0; right: 100%;
  height: 2px; background: var(--acento);
  animation: carga-filete 1.4s ease-in-out .2s infinite;
}

/* ---------------------------- EL ESQUELETO ---------------------------
   La tabla que viene, dibujada en gris: mismo encabezado, mismos hairlines
   entre renglones y misma zebra que `.tabla-scroll`. No es decoración; es
   lo que hace que al llegar los datos la pantalla no pegue el salto de
   pasar de un renglón de texto a una tabla de doce.
   ------------------------------------------------------------------- */
.esqueleto .renglon {
  display: flex; align-items: center; gap: 20px;
  padding: 9px 10px;
  border-bottom: 1px solid var(--linea-2);
}
/* El primer renglón es la cabecera de la tabla: el mismo gris y el mismo
   borde marcado que llevan los <th> de verdad. */
.esqueleto .renglon:first-child {
  background: #EDF1F4;
  padding: 8px 10px;
  border-bottom: 1px solid var(--borde-caja);
}
.esqueleto .renglon:nth-child(odd):not(:first-child) { background: var(--fondo-2); }
.esqueleto .renglon:last-child { border-bottom: 0; }

.esqueleto .celda {
  height: 8px; flex: 1 1 0; min-width: 0;
  background: var(--linea);
  animation: carga-respira 1.6s ease-in-out infinite;
}
.esqueleto .renglon:first-child .celda { height: 6px; background: var(--borde-caja); }
/* La primera columna es la que identifica el renglón —la fecha, el folio—:
   más corta y sin estirarse, igual que en la tabla de verdad. */
.esqueleto .celda.corta { flex: 0 0 62px; }
/* Cada columna respira un instante después que la anterior. Es lo que hace
   que el bloque se lea como un renglón escribiéndose y no como doce cuadros
   parpadeando a la vez. */
.esqueleto .celda:nth-child(2) { animation-delay: .08s; }
.esqueleto .celda:nth-child(3) { animation-delay: .16s; }
.esqueleto .celda:nth-child(4) { animation-delay: .24s; }
.esqueleto .celda:nth-child(5) { animation-delay: .32s; }
.esqueleto .celda:nth-child(6) { animation-delay: .40s; }
.esqueleto .celda:nth-child(7) { animation-delay: .48s; }

/* QUIEN PIDIÓ QUE NADA SE MUEVA, QUE NO VEA NADA MOVERSE.
   No es cortesía: hay gente a la que una animación en bucle le da vértigo, y
   este sistema se mira ocho horas seguidas. Se quedan las marcas —el filete
   azul puesto entero, el gris del esqueleto— porque el estado sigue siendo
   el mismo; lo que se va es el movimiento. */
@media (prefers-reduced-motion: reduce) {
  .encabezado::after,
  .cargando .filete::after,
  .btn.trabajando::after,
  .tarjeta.trabajando::before,
  .esqueleto .celda {
    animation: none;
  }
  body.trabajando .encabezado::after,
  .cargando .filete::after,
  .btn.trabajando::after,
  .tarjeta.trabajando::before {
    right: 0; opacity: 1;
  }
  .btn.trabajando::after { opacity: .6; }
}

@media (max-width: 991.98px) {
  .encabezado { padding: 14px 16px; }
  .contenido { padding: 16px 16px 40px; }
}
