/* ═══════════════════════════════════════════════════════════════════
   SEGUIMIENTO RH — sistema visual
   ═══════════════════════════════════════════════════════════════════
   Sin librerías de estilos: son cientos de KB para lo que aquí se
   resuelve en un archivo, y cada una es algo más que puede romperse en
   una actualización que nadie está vigilando.

   La paleta no es la de siempre a propósito. Todo el software de RH
   mexicano usa el mismo azul marino con cian —Worky, Factorial, Runa—
   y parecerse a ellos no distingue a nadie. Aquí el color viene del
   producto: azul petróleo profundo, que es serio sin ser corporativo
   genérico, y ámbar para lo que reclama atención. El ámbar no es
   decorativo: este sistema mide TIEMPO, y el ámbar es el color con el
   que un reloj avisa.

   Tres familias, cada una con su trabajo:
     Familjen Grotesk  títulos — geométrica, con carácter, poco vista
     Public Sans       texto — cívica, hecha para formularios oficiales
     IBM Plex Mono     horas, folios y cifras que se alinean en columna
   ═══════════════════════════════════════════════════════════════════ */

@import url('https://fonts.googleapis.com/css2?family=Familjen+Grotesk:wght@400;500;600;700&family=Public+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

:root {
  /* Fondo cálido, no clínico: el blanco puro cansa en pantallas que se
     miran ocho horas seguidas. */
  --papel:      #FAF7F2;
  --papel2:     #F4EFE6;
  --tarjeta:    #FFFFFF;
  --tarjeta2:   #F5F1E9;
  --linea:      #ECE5D9;
  --linea2:     #DCD2C0;

  --tinta:      #241F3D;
  --tinta2:     #4A4270;
  --tinta3:     #8B84A3;

  /* El azul del logotipo. `--marca` es el color EXACTO del logotipo y no se
     toca; `--primario` es medio tono más oscuro y es el que va en botones,
     enlaces y texto, porque el de la marca sobre blanco da 4.7 de contraste
     —pasa raspando— y éste da 5.9, que se lee cómodo a tamaño de botón. */
  --marca:      #241F3D;
  --primario:   #4A4270;
  --primario2:  #241F3D;
  --primario-f: #ECE9F3;
  /* Lo que va ENCIMA del primario y del acento. No es siempre blanco: en modo
     oscuro esos dos fondos se aclaran, y el blanco encima desaparece. Lo probé
     y el botón «Guardar como PDF» quedaba ilegible. */
  --sobre-primario: #FFFFFF;
  --sobre-acento:   #FFFFFF;

  /* Ámbar: atención, tiempo, lo que hay que mirar hoy. */
  /* El oro es el UNICO acento. Va en el boton primario, en el filtro
     activo, en la raya de las tarjetas de cifra y en el borde de «hoy».
     `--acento` es el tono de fondo; `--acento-t` es el mismo oro llevado a
     oscuro, que es el que se puede LEER sobre crema. */
  --acento:     #C9A15C;
  --acento2:    #B58C46;
  --acento-t:   #8A6A2E;
  --acento-f:   #F6EEDF;

  /* Los estados: fondo al 12-15% y letra en la version oscura del MISMO
     color, nunca letra negra sobre color. */
  --verde:      #4F6B4B;
  --verde-f:    #E9EFE7;
  --ambar:      #8A6A2E;
  --ambar-f:    #F6EEDF;
  --rojo:       #8F4832;
  --rojo-f:     #F6E8E2;
  --morado:     #4A4270;
  --morado-f:   #ECE9F3;

  /* Los tonos vivos, para graficas y rayas: los mismos de la paleta. */
  --verde-vivo: #6F8F6A;
  --rojo-vivo:  #B5654A;

  /* Las sombras van TEÑIDAS de indigo, nunca negras: una sombra negra sobre
     crema se ve sucia y despega la tarjeta del fondo. */
  --sombra:     0 1px 2px rgba(36,31,61,.05), 0 8px 24px rgba(36,31,61,.06);
  --sombra-alta:0 2px 8px rgba(36,31,61,.08), 0 24px 56px rgba(36,31,61,.14);
  --sombra-oro: 0 2px 6px rgba(138,106,46,.22), 0 8px 20px rgba(138,106,46,.18);
  --radio:      18px;
  --radio-s:    10px;
  --serif:      Lora, "Iowan Old Style", Georgia, "Times New Roman", serif;

  /* La barra lateral es la única zona oscura, y sus tonos no dependen del
     modo claro/oscuro: en los dos es índigo. Por eso van aparte. */
  --indigo:        #241F3D;
  --indigo-hover:  #322B54;
  --indigo-activo: #3B3363;
  --indigo-linea:  #3A3360;
  --sobre-indigo:  #F6F2EA;
  --sobre-indigo-2:#A9A2C4;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --papel:#1A1730; --papel2:#241F3D; --tarjeta:#241F3D; --tarjeta2:#2E2850;
    --linea:#39325C; --linea2:#4A4270;
    --tinta:#FAF7F2; --tinta2:#C9C3DC; --tinta3:#948DAE;
    --marca:#C9A15C; --primario:#C3B7E8; --primario2:#D8CFF3; --primario-f:#2E2850;
    --sobre-primario:#1A1730; --sobre-acento:#241F3D;
    --acento:#C9A15C; --acento2:#DDB877; --acento-t:#E3C48D; --acento-f:#3A2F1C;
    --verde:#9CC095; --verde-f:#22301F; --verde-vivo:#8FB489;
    --ambar:#DDB877; --ambar-f:#3A2F1C;
    --rojo:#DE9B84; --rojo-f:#3A241C; --rojo-vivo:#C87A5E;
    --morado:#C3B7E8; --morado-f:#2E2850;
    --sombra:0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.32);
    --sombra-alta:0 2px 8px rgba(0,0,0,.5), 0 24px 56px rgba(0,0,0,.45);
    --sombra-oro: 0 2px 6px rgba(0,0,0,.35), 0 8px 20px rgba(201,161,92,.16);
  }
}
:root[data-theme="dark"] {
  --papel:#1A1730; --papel2:#241F3D; --tarjeta:#241F3D; --tarjeta2:#2E2850;
  --linea:#39325C; --linea2:#4A4270;
  --tinta:#FAF7F2; --tinta2:#C9C3DC; --tinta3:#948DAE;
  --marca:#C9A15C; --primario:#C3B7E8; --primario2:#D8CFF3; --primario-f:#2E2850;
  --sobre-primario:#1A1730; --sobre-acento:#241F3D;
  --acento:#C9A15C; --acento2:#DDB877; --acento-t:#E3C48D; --acento-f:#3A2F1C;
  --verde:#9CC095; --verde-f:#22301F; --verde-vivo:#8FB489;
  --ambar:#DDB877; --ambar-f:#3A2F1C;
  --rojo:#DE9B84; --rojo-f:#3A241C; --rojo-vivo:#C87A5E;
  --morado:#C3B7E8; --morado-f:#2E2850;
  --sombra:0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.32);
  --sombra-alta:0 2px 8px rgba(0,0,0,.5), 0 24px 56px rgba(0,0,0,.45);
  --sombra-oro: 0 2px 6px rgba(0,0,0,.35), 0 8px 20px rgba(201,161,92,.16);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  /* Degradado vertical muy corto entre dos cremas, y dos manchas de color
     difuminadas en las esquinas. No se ven como manchas: se sienten como
     que la hoja tiene aire. Van fijas para que no viajen al hacer scroll. */
  background:
    radial-gradient(60rem 40rem at 100% 0%, color-mix(in srgb, var(--acento) 11%, transparent), transparent 62%),
    radial-gradient(52rem 38rem at 0% 100%, color-mix(in srgb, var(--primario) 9%, transparent), transparent 60%),
    linear-gradient(180deg, var(--papel) 0%, var(--papel2) 100%);
  background-attachment: fixed;
  color: var(--tinta);
  font-family: "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, .titular {
  font-family: "Familjen Grotesk", "Public Sans", system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: -.015em;
  text-wrap: balance;
  margin: 0;
}

/* La serif se reserva para tres cosas: el nombre de la marca, los títulos
   grandes de sección y los NÚMEROS protagonistas. En los botones, las tablas
   y los formularios manda la sans, que es la que se lee de un vistazo. */
.caja > h2, .titulo-vista h1, .cifra .val,
.agenda-mes-cabeza b, .agenda-num, .agenda-mini-dia {
  font-family: var(--serif);
}
.caja > h2 { font-weight: 600; letter-spacing: -.005em; }

/* El encabezado de cada pantalla, donde antes no había ninguno: sólo
   empezaban los filtros y no se sabía en dónde estaba uno cuando la barra
   está contraída. */
.titulo-vista { margin: 0 0 1.25rem; }
.titulo-vista .eyebrow { margin-bottom: .3rem; }
.titulo-vista h1 { font-size: 2rem; font-weight: 600; line-height: 1.1; letter-spacing: -.02em; }
/* El tope de ancho es para que un párrafo largo no se lea de pared a pared.
   Estaba en 56ch —482 px— y partía en dos renglones una descripción de una
   sola frase que cabía de sobra en los 919 px del contenedor. Se sube a lo
   que necesita la más larga, y se conserva el tope: sin él, en una pantalla
   ancha el renglón se estira tanto que el ojo pierde el principio. */
.titulo-vista p { margin: .3rem 0 0; color: var(--tinta2); font-size: .88rem; max-width: 84ch; }

a { color: var(--primario); text-decoration-color: color-mix(in srgb, var(--primario) 35%, transparent); }
a:hover { text-decoration-color: currentColor; }

:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; border-radius: 4px; }

/* Etiqueta pequeña en versalitas que encabeza una sección. */
.eyebrow {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: .7rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--primario); font-weight: 500;
}

/* ── Entrar ───────────────────────────────────────────────────────── */
.entrar-fondo {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 1.5rem;
  background:
    radial-gradient(60rem 32rem at 12% -10%, color-mix(in srgb, var(--primario) 13%, transparent), transparent 62%),
    radial-gradient(46rem 28rem at 92% 108%, color-mix(in srgb, var(--acento) 13%, transparent), transparent 62%),
    var(--papel);
}
.entrar-caja {
  width: 100%; max-width: 24rem; background: var(--tarjeta);
  border: 1px solid var(--linea); border-radius: var(--radio);
  box-shadow: var(--sombra-alta); padding: 2.2rem 2rem;
}
.entrar-caja h1 { font-size: 1.5rem; margin-bottom: .25rem; }
.entrar-caja .sub { color: var(--tinta3); font-size: .87rem; margin: 0 0 1.7rem; }

/* ── Campos ───────────────────────────────────────────────────────── */
label.campo { display: block; margin-bottom: 1rem; }
label.campo span {
  display: block; font-size: .78rem; color: var(--tinta2);
  margin-bottom: .35rem; font-weight: 600; letter-spacing: .01em;
}

input, select, button, textarea { font: inherit; }

input[type=text], input[type=email], input[type=password], input[type=date],
input[type=time], input[type=number], input[type=search], select, textarea {
  width: 100%; padding: .58rem .75rem;
  border: 1px solid var(--linea2); border-radius: var(--radio-s);
  background: var(--tarjeta); color: var(--tinta);
  transition: border-color .12s, box-shadow .12s;
}
input:hover, select:hover, textarea:hover { border-color: var(--tinta3); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--primario);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primario) 16%, transparent);
}
input::placeholder, textarea::placeholder { color: var(--tinta3); }
input[type=date], input[type=time] { font-variant-numeric: tabular-nums; }

/* ── Botones ──────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  padding: .52rem .95rem; border: 1px solid var(--linea2); border-radius: 99px;
  background: var(--tarjeta); color: var(--tinta); cursor: pointer;
  font-weight: 600; font-size: .855rem; white-space: nowrap;
  transition: background .12s, border-color .12s, transform .06s, box-shadow .12s;
}
.btn:hover { background: var(--tarjeta2); border-color: var(--tinta3); }
.btn:active { transform: translateY(1px); }
/* El primario lleva un degradado de DOS tonos del mismo oro —nunca de dos
   colores distintos— y su sombra teñida de ese oro. */
.btn.primario {
  background: linear-gradient(180deg, var(--acento) 0%, var(--acento2) 100%);
  border-color: var(--acento2); color: var(--indigo); font-weight: 600;
  box-shadow: var(--sombra-oro);
}
.btn.primario:hover { background: linear-gradient(180deg, var(--acento2) 0%, var(--acento2) 100%);
                      border-color: var(--acento2); }
.btn.acento {
  background: var(--acento); border-color: var(--acento); color: var(--sobre-acento);
  box-shadow: 0 1px 2px rgba(199,125,25,.3);
}
.btn.acento:hover { background: var(--acento2); border-color: var(--acento2); }
.btn.peligro { color: var(--rojo); border-color: color-mix(in srgb, var(--rojo) 40%, var(--linea2)); }
.btn.peligro:hover { background: var(--rojo-f); }
.btn.ancho { width: 100%; padding: .72rem; font-size: .95rem; border-radius: var(--radio-s); }
.btn.chico { padding: .3rem .62rem; font-size: .78rem; }
.btn:disabled { opacity: .5; cursor: default; transform: none; }

.aviso { border-radius: var(--radio-s); padding: .7rem .9rem; font-size: .86rem; margin-bottom: 1rem; }
.aviso.malo  { background: var(--rojo-f);  color: var(--rojo);  font-weight: 600; }
.aviso.bueno { background: var(--verde-f); color: var(--verde); font-weight: 600; }
.aviso.ojo   { background: var(--ambar-f); color: var(--ambar); font-weight: 600; }

/* ═══ ARMAZÓN: barra lateral + columna de contenido ══════════
   La navegación era una fila de pestañas arriba. Con nueve secciones ya no
   cabía y había que arrastrarla de lado para llegar a «Usuarios». Ahora es
   una columna que se contrae a 68px y deja el ancho para el contenido.

   La barra es la ÚNICA zona oscura de la aplicación: índigo profundo con la
   letra en crema. Todo lo demás vive sobre el crema. */
.armazon { display: flex; min-height: 100vh; align-items: stretch; }

.lateral {
  position: sticky; top: 0; z-index: 30; flex: none;
  /* min-width:0 no es adorno. El minimo de un elemento flexible es el ancho
     de su contenido, y con eso la barra se negaba a bajar de 248px por mas
     que la regla de abajo pidiera 68. */
  width: 248px; min-width: 0; height: 100vh;
  display: flex; flex-direction: column;
  background: var(--indigo); color: var(--sobre-indigo);
  padding: 1.15rem 14px 1rem;
  /* En modo claro la barra se separa sola por el contraste. En oscuro el
     fondo de la página también es índigo y se fundía con ella. */
  border-right: 1px solid var(--indigo-linea);
  transition: width .28s cubic-bezier(.4, 0, .2, 1);
}
/* El ancho es lo ÚNICO que se anima. El texto se desvanece aparte, para que
   no se vea aplastarse mientras la columna encoge. */
.lateral.plegada { width: 68px; }

/* ── La marca ── */
.lateral .marca-logo {
  display: flex; align-items: center; gap: .65rem;
  padding: .1rem 3px 1.15rem; margin-bottom: .5rem;
  border-bottom: 1px solid var(--indigo-linea);
  text-decoration: none; color: inherit; min-width: 0;
  /* Es un letrero, no un boton: ni cursor de mano ni texto que se
     seleccione al tocarlo dos veces en el telefono. */
  cursor: default; user-select: none; -webkit-user-select: none;
}
.lateral .marca-icono {
  width: 34px; height: 34px; flex: none; border-radius: 10px;
  background-color: color-mix(in srgb, var(--acento) 20%, transparent);
  background-size: contain; background-position: center; background-repeat: no-repeat;
}
.lateral .marca-texto { min-width: 0; }
.lateral .marca-logo b {
  display: block; font-family: var(--serif); font-weight: 600;
  font-size: 1.05rem; letter-spacing: -.01em; white-space: nowrap;
}
.lateral .marca-logo .empresa {
  display: block; font-style: normal; font-size: .72rem;
  color: var(--sobre-indigo-2); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}

/* ── El círculo dorado que contrae ── */
.lateral-tirador {
  position: absolute; top: 3rem; right: -13px; z-index: 2;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  border: 0; padding: 0;
  background: var(--acento); color: var(--indigo);
  box-shadow: var(--sombra-oro);
  transition: transform .28s cubic-bezier(.4, 0, .2, 1), background .15s;
}
.lateral-tirador svg { width: 15px; height: 15px; }
.lateral-tirador:hover { background: var(--acento2); }
.lateral.plegada .lateral-tirador { transform: rotate(180deg); }

/* ── Los renglones de navegación ── */
.pestanas {
  display: flex; flex-direction: column; gap: 2px;
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: .35rem 0; margin: 0;
}
/* El atributo hidden manda. Sin esto, el display de abajo lo pisaría y
   «Usuarios» y «Clientes» se verían aunque el usuario no tenga permiso. */
.pestanas button[hidden] { display: none !important; }
.pestanas button {
  position: relative; display: flex; align-items: center; gap: .8rem;
  width: 100%; border: 0; background: none; cursor: pointer;
  color: var(--sobre-indigo-2); font-family: inherit;
  font-weight: 500; font-size: .875rem; text-align: left;
  padding: .62rem 10px; border-radius: 10px;
  white-space: nowrap; overflow: hidden;
  transition: background .14s, color .14s;
}
.pest-icono { width: 20px; height: 20px; flex: none; }
.pest-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis;
            transition: opacity .15s ease; }
.pestanas button:hover { background: var(--indigo-hover); color: var(--sobre-indigo); }

/* La sección activa: fondo suave y la raya de oro pegada a la izquierda.
   La raya se queda puesta también con la barra contraída, que es cuando más
   falta hace saber en dónde está uno. */
.pestanas button.activa { background: var(--indigo-activo); color: var(--sobre-indigo); font-weight: 600; }
.pestanas button.activa::before {
  content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 3px; height: 62%; border-radius: 0 3px 3px 0; background: var(--acento);
}
.pestanas button.activa .pest-icono { color: var(--acento); }

/* ── Contraída ── */
/* El icono NO se mueve de sitio: el botón pasa a centrar y el relleno se
   iguala, así que queda en la misma columna en los dos estados. */
.lateral.plegada .pestanas button { justify-content: center; padding-left: 0; padding-right: 0; gap: 0; }
.lateral.plegada .pest-txt,
.lateral.plegada .marca-texto,
.lateral.plegada .quien,
.lateral.plegada .lateral-acciones { opacity: 0; }
/* `oculto` lo pone barra.js DESPUÉS de que la opacidad llegó a cero. Si se
   escondiera de golpe, el texto se vería encogerse con la columna. */
.lateral.plegada .pest-txt.oculto,
.lateral.plegada .marca-texto.oculto,
.lateral.plegada .lateral-acciones.oculto,
.lateral.plegada .quien.oculto { display: none; }
.lateral.plegada .marca-logo { justify-content: center; padding-left: 0; padding-right: 0; }
.lateral.plegada .lateral-acciones { align-items: center; }

/* ── El pie: quién entró y sus botones ── */
.lateral .quien {
  padding: .8rem 3px .55rem; border-top: 1px solid var(--indigo-linea);
  line-height: 1.3; min-width: 0; transition: opacity .15s ease;
}
.lateral .quien b { display: block; font-size: .82rem; font-weight: 600;
                    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lateral .quien .empresa { display: block; font-style: normal; font-size: .72rem;
                           color: var(--sobre-indigo-2); white-space: nowrap;
                           overflow: hidden; text-overflow: ellipsis; }
.lateral-acciones { display: flex; flex-direction: column; gap: .3rem; padding: 0; }
.lateral-acciones .btn {
  width: 100%; justify-content: center; text-align: center;
  background: transparent; border-color: var(--indigo-linea); color: var(--sobre-indigo-2);
  transition: opacity .15s ease, background .14s, color .14s, border-color .14s;
}
.lateral-acciones .btn:hover { background: var(--indigo-hover); color: var(--sobre-indigo);
                               border-color: var(--indigo-hover); }
.lateral-acciones .btn.acento { background: var(--acento); border-color: var(--acento);
                                color: var(--indigo); font-weight: 600; }


/* ── La columna de contenido ── */
.principal { flex: 1; min-width: 0; }
.contenido { padding: 1.6rem 1.8rem 4rem; max-width: 1500px; margin: 0 auto; }

.filtros {
  display: flex; gap: .5rem; flex-wrap: wrap; align-items: center;
  margin-bottom: 1rem; padding: .8rem .9rem;
  background: var(--tarjeta); border: 1px solid var(--linea);
  border-radius: var(--radio); box-shadow: var(--sombra);
}
.filtros .etiqueta { font-size: .8rem; color: var(--tinta2); font-weight: 600; }
.filtros input[type=date] { width: 9.6rem; }
.filtros select { width: auto; min-width: 10.5rem; }
.filtros input.buscador { width: 19rem; }
.filtros .sep { width: 1px; align-self: stretch; background: var(--linea); margin: 0 .2rem; }

/* ── Cifras ───────────────────────────────────────────────────────── */
.cifras { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: .7rem; margin-bottom: 1.2rem; }
.cifra {
  background: var(--tarjeta); border: 1px solid var(--linea);
  border-radius: var(--radio); padding: 1rem 1.05rem; box-shadow: var(--sombra);
  position: relative; overflow: hidden;
  /* Centrado. La reja estira todas las tarjetas a la altura de la más alta, y
     sin esto el número quedaba pegado arriba con un hueco debajo: se veía
     desacomodado, que es exactamente lo que se notaba al ponerle el anillo a
     dos de ellas. */
  display: flex; flex-direction: column; justify-content: center;
  min-height: 5.6rem;
}
.cifra::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--acento); }
.cifra.v::before { background: var(--verde); }
.cifra.a::before { background: var(--ambar); }
.cifra.r::before { background: var(--rojo); }
.cifra.m::before { background: var(--morado); }
.cifra.p::before { background: var(--primario); }
/* Un poco mas grande: la tarjeta es alta porque a su lado hay anillos, y un
   numero chico en una tarjeta alta se ve perdido. */
.cifra .val { font-size: 2.2rem; font-weight: 500; line-height: 1.05; font-variant-numeric: tabular-nums; }
.cifra .lab { font-size: .74rem; color: var(--tinta3); margin-top: .25rem; font-weight: 500;
              letter-spacing: .01em; }

.caja {
  background: var(--tarjeta); border: 1px solid var(--linea);
  border-radius: var(--radio); box-shadow: var(--sombra);
  padding: 1.35rem 1.45rem; margin-bottom: 1.35rem;
}
.caja > h2 { font-size: 1.12rem; margin: 0 0 .9rem; display: flex; align-items: center; gap: .5rem; }

/* ── Tablas ───────────────────────────────────────────────────────── */
.tabla-envoltura { overflow-x: auto; margin: 0 -.35rem; padding: 0 .35rem; }
table.datos { width: 100%; border-collapse: collapse; font-size: .855rem; }
table.datos th {
  text-align: left; font-size: .69rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--tinta3); font-weight: 600; padding: .4rem .6rem .5rem;
  border-bottom: 1px solid var(--linea2); white-space: nowrap;
  position: sticky; top: 0; background: var(--tarjeta); z-index: 1;
}
table.datos td { padding: .52rem .6rem; border-bottom: 1px solid var(--linea); vertical-align: middle; }
table.datos tbody tr:hover { background: var(--tarjeta2); }
table.datos tfoot td { font-weight: 700; background: var(--tarjeta2); border-top: 2px solid var(--linea2); }
table.datos .num { text-align: right; font-variant-numeric: tabular-nums; font-family: "IBM Plex Mono", monospace; font-size: .82rem; }
.der { text-align: right; }
.cen { text-align: center; }
.apagado { opacity: .55; }
.mono { font-family: "IBM Plex Mono", monospace; font-variant-numeric: tabular-nums; }

/* ── Una tabla que se vuelve tarjetas cuando ya no cabe ───────────────
   El problema que resuelve: la tabla de Personal mide 1,100 px. En un
   teléfono de 390 eso es TRES pantallas de ancho — para leer un renglón hay
   que arrastrar de lado tres veces y ya se te olvidó de quién era. La
   envoltura con `overflow-x:auto` evitaba que se rompiera la página, pero no
   hacía legible nada.

   Aquí, por debajo de 62rem, cada renglón se vuelve una tarjeta: el nombre de
   cabeza y debajo cada dato con su rótulo. El rótulo sale del atributo
   `data-rotulo` de la celda, así que la tabla sigue siendo una tabla —el mismo
   HTML sirve para la pantalla grande, para la chica y para el PDF— y no hay
   una segunda versión que se quede atrás.

   SE MIDE EL ESPACIO DE LA TABLA, NO EL DE LA VENTANA. Una consulta por ancho
   de ventana se equivoca en los dos sentidos: en una pantalla de 1280 con la
   barra lateral abierta a la tabla le quedan 920 y no cabe, y en esa misma de
   1280 con la barra plegada le quedan 1180 y cabía de sobra. El ancho de la
   ventana no sabe nada de la barra; el del contenedor sí.

   VA EN `screen and` A PROPÓSITO: en impresión, `max-width` se mide contra la
   hoja, y una carta son 51rem. Sin `screen` los reportes en papel saldrían
   convertidos en tarjetas. */
@media screen {
  .tabla-envoltura:has(> table.apilable) { container-type: inline-size; }
}
/* Los botones del renglón, en una sola línea mientras sea una tabla: apilados
   uno sobre otro subían el renglón de 79 a 109 px, y con sesenta y siete
   personas eso son dos pantallas más de rueda. Cuando se vuelve tarjeta, la
   regla de más abajo los suelta otra vez. */
table.datos td.ap-acciones { white-space: nowrap; }

/* 66rem y no 64: con los botones en un renglón la tabla de Personal no baja de
   1,046 px, y a 64rem (1,024) quedaba una franja de veintidós píxeles en la
   que ni se apilaba ni cabía. El número sale de medir, no de redondear. */
@container (max-width: 66rem) {
  table.datos.apilable { display: block; font-size: .875rem; }
  table.datos.apilable thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  /* En tableta caben dos tarjetas; en teléfono, una. Lo decide el ancho
     disponible, no un salto más. */
  table.datos.apilable tbody { display: grid; grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); gap: .7rem; }
  table.datos.apilable tbody tr {
    display: block; background: var(--tarjeta2); border: 1px solid var(--linea);
    border-radius: var(--radio-s); padding: .7rem .85rem;
  }
  table.datos.apilable tbody tr:hover { background: var(--tarjeta2); }
  table.datos.apilable td {
    display: grid; grid-template-columns: 7.5rem 1fr; gap: .2rem .7rem;
    align-items: baseline; border: 0; padding: .2rem 0; text-align: left;
  }
  table.datos.apilable td::before {
    content: attr(data-rotulo); font-size: .66rem; text-transform: uppercase;
    letter-spacing: .09em; color: var(--tinta3); font-weight: 600; padding-top: .18rem;
  }
  /* Cada hijo de la celda es un cuadro de la rejilla por su cuenta, así que el
     SEGUNDO se acomodaba solo en el renglón de abajo… y en la columna del
     rótulo. El centro de trabajo aparecía alineado con «PUESTO Y CENTRO», como
     si fuera otro rótulo, y el «3 de 20 día(s)» debajo de «ASISTENCIA». Con
     esto todo lo que no es el rótulo se queda en la columna del dato. El texto
     suelto que va primero —el puesto, el horario— se acomoda solo en su lugar,
     que es el que le toca. */
  /* `justify-self` para que una etiqueta siga siendo una pastilla del tamaño de
     su texto: como cuadro de la rejilla se estiraba a toda la columna y «sin
     CURP» salía como una barra amarilla de lado a lado. */
  table.datos.apilable td > * { grid-column: 2; justify-self: start; }
  /* La celda del nombre es el encabezado de la tarjeta: sin rótulo, a todo lo
     ancho y separada por una línea, como el título de una ficha. */
  table.datos.apilable td.ap-titulo {
    display: block; font-size: 1rem; padding: 0 0 .5rem;
    margin-bottom: .45rem; border-bottom: 1px solid var(--linea);
  }
  table.datos.apilable td.ap-titulo::before { content: none; }
  /* Los botones, hasta abajo y a todo lo ancho: en un teléfono se tocan con el
     pulgar, y un botón de 60 px de ancho se falla. */
  table.datos.apilable td.ap-acciones {
    display: flex; flex-wrap: wrap; gap: .4rem; padding-top: .6rem;
    margin-top: .45rem; border-top: 1px solid var(--linea); white-space: normal;
  }
  table.datos.apilable td.ap-acciones::before { content: none; }
  table.datos.apilable td.ap-acciones .btn { flex: 1 1 auto; justify-content: center; }
  /* Una celda vacía no merece un renglón con su rótulo y un guión al lado. */
  table.datos.apilable td.ap-vacia { display: none; }
  table.datos.apilable tfoot { display: block; margin-top: .7rem; }
  table.datos.apilable tfoot tr { display: block; background: var(--tarjeta2);
    border: 1px solid var(--linea2); border-radius: var(--radio-s); padding: .7rem .85rem; }
  table.datos.apilable tfoot td { background: none; border: 0; }
}
/* Sin `:has` —navegadores viejos— la envoltura sigue con su barra de lado y no
   se rompe nada: sólo se pierde el que la tarjeta use todo el ancho. */

/* ── Resumen de lo que falta, por tipo ─────────────────────────────────
   No es una lista de personas: es una lista de PROBLEMAS con su cuenta, para
   poder atacar uno completo en vez de ir abriendo expediente por expediente. */
.faltantes { display: flex; flex-wrap: wrap; gap: .5rem; }
.faltantes button {
  display: inline-flex; align-items: baseline; gap: .45rem; cursor: pointer;
  font: inherit; font-size: .81rem; font-weight: 600; color: var(--tinta2);
  background: var(--tarjeta2); border: 1px solid var(--linea2);
  border-left: 3px solid var(--tinta3); border-radius: var(--radio-s);
  /* `margin: 0` NO es de relleno. El tono de cada grupo se usa como clase del
     botón, y `aviso` ya existe arriba como la caja de aviso de toda la
     aplicación, con `margin-bottom: 1rem`. Sin esta línea, los botones ámbar
     heredaban ese margen y los rojos no: en una fila flexible eso estiraba a
     los rojos 16 px de más, con el texto pegado arriba y una franja de color
     vacía debajo. */
  margin: 0; padding: .4rem .7rem; text-align: left;
}
.faltantes button:hover { background: var(--tarjeta); color: var(--tinta); }
.faltantes button.grave { border-left-color: var(--rojo); background: var(--rojo-f); color: var(--rojo); }
.faltantes button.aviso { border-left-color: var(--ambar); background: var(--ambar-f); color: var(--ambar); }
.faltantes button.activa { outline: 2px solid var(--primario); outline-offset: 1px; }
.faltantes .cuenta { font-size: 1.05rem; font-weight: 600; font-variant-numeric: tabular-nums; }

.etiq { display: inline-block; padding: .12rem .5rem; border-radius: 99px; font-size: .73rem; font-weight: 600; white-space: nowrap; }
.etiq.verde { background: var(--verde-f); color: var(--verde); }
.etiq.ambar { background: var(--ambar-f); color: var(--ambar); }
.etiq.rojo  { background: var(--rojo-f);  color: var(--rojo); }
.etiq.morado{ background: var(--morado-f);color: var(--morado); }
.etiq.gris  { background: var(--tarjeta2);color: var(--tinta3); }
.etiq.azul  { background: var(--primario-f); color: var(--primario); }

/* ── Avisos accionables ───────────────────────────────────────────── */
.atender { display: flex; flex-direction: column; gap: .5rem; }
.atender .fila {
  display: flex; align-items: center; gap: .85rem;
  background: var(--tarjeta2); border-left: 3px solid var(--tinta3);
  border-radius: var(--radio-s); padding: .65rem .85rem;
}
.atender .fila.grave { border-left-color: var(--rojo); background: var(--rojo-f); }
.atender .fila.aviso { border-left-color: var(--ambar); background: var(--ambar-f); }
.atender .fila .tit { font-weight: 700; font-size: .855rem; }
.atender .fila.grave .tit { color: var(--rojo); }
.atender .fila.aviso .tit { color: var(--ambar); }
.atender .fila .det { font-size: .81rem; color: var(--tinta2); }

/* ── Ley ──────────────────────────────────────────────────────────── */
.ley .fila {
  background: var(--ambar-f); border-left: 3px solid var(--ambar);
  border-radius: var(--radio-s); padding: .7rem .9rem; margin-bottom: .5rem;
}
.ley .fila.grave { border-left-color: var(--rojo); background: var(--rojo-f); }
.ley .cabeza { display: flex; justify-content: space-between; gap: .8rem; align-items: baseline; flex-wrap: wrap; }
.ley .quien { font-weight: 700; font-size: .87rem; }
/* EL ARTÍCULO SE PARTE CUANDO NO CABE. Antes llevaba `white-space: nowrap`
   para que «Art. 61» no se rompiera a la mitad en pantalla grande, pero las
   citas de verdad miden setenta y siete caracteres —«Art. 132 fracc. XXXIV,
   adicionada por el decreto del DOF del 1 de mayo de 2026»— y en un teléfono
   se salían de la tarjeta. `balance` reparte los renglones en vez de dejar
   uno suelto, y `anywhere` es el seguro: ninguna cadena larga puede volver a
   reventar una caja. */
.ley .art {
  font-family: "IBM Plex Mono", monospace; font-size: .72rem; font-weight: 600;
  color: var(--tinta2); overflow-wrap: anywhere; text-wrap: balance; min-width: 0;
}
.ley .cabeza .quien { min-width: 0; overflow-wrap: anywhere; }
.ley .det { font-size: .81rem; color: var(--tinta2); margin-top: .15rem; }
.ley .fundamento { font-size: .78rem; color: var(--tinta3); font-style: italic; margin-top: .25rem; }

/* ── Gráficas ─────────────────────────────────────────────────────── */
.grafica { background: var(--tarjeta2); border-radius: var(--radio-s); padding: .85rem .9rem .35rem; }
.leyenda { display: flex; gap: .9rem; flex-wrap: wrap; font-size: .78rem; color: var(--tinta2); margin-top: .4rem; }
.leyenda i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: .3rem; }
.barras .renglon { margin-bottom: .5rem; }
.barras .arriba { display: flex; justify-content: space-between; gap: .6rem; font-size: .82rem; }
.barras .riel { height: 6px; background: var(--linea); border-radius: 99px; overflow: hidden; margin-top: .2rem; }
.barras .relleno { height: 100%; border-radius: 99px; }
.columnas { display: flex; gap: 1.6rem; flex-wrap: wrap; }
.columnas > div { flex: 1; min-width: 16rem; }

/* ── Ventanas ─────────────────────────────────────────────────────── */
.velo {
  position: fixed; inset: 0; background: rgba(10,17,22,.5);
  backdrop-filter: blur(2px);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 2.2rem 1rem; z-index: 60; overflow: auto;
}
/* Un display propio le gana al atributo hidden, y la ventana aparecía
   abierta al cargar. Se dice explícito para que hidden vuelva a mandar. */
.velo[hidden], [hidden] { display: none !important; }
.ventana {
  background: var(--tarjeta); border: 1px solid var(--linea);
  border-radius: var(--radio); box-shadow: var(--sombra-alta);
  width: 100%; max-width: 62rem; padding: 1.3rem 1.4rem;
}
.ventana .cabeza { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.ventana h2 { margin: 0; font-size: 1.1rem; flex: 1; }
.cerrar { border: 0; background: none; font-size: 1.25rem; cursor: pointer; color: var(--tinta3); line-height: 1; padding: .2rem .4rem; border-radius: 6px; }
.cerrar:hover { background: var(--tarjeta2); color: var(--tinta); }

.vacio { text-align: center; color: var(--tinta3); padding: 2.8rem 1rem; font-size: .9rem; }
.nota { font-size: .78rem; color: var(--tinta3); margin-top: .6rem; line-height: 1.5; }
.cargando { color: var(--tinta3); font-size: .85rem; padding: 1.8rem; text-align: center; }

/* Rejilla de formulario, para las fichas de captura. */
.rejilla { display: grid; grid-template-columns: repeat(auto-fit, minmax(13.5rem, 1fr)); gap: 0 1rem; }
.rejilla.dos { grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   PANTALLAS ANGOSTAS
   ═══════════════════════════════════════════════════════════════════
   Esto no existía, y se notaba: en un teléfono el encabezado se partía
   en tres renglones, el nombre de la empresa se encimaba con el del
   usuario y los filtros salían uno por línea. Una pantalla que se usa
   de pie en un pasillo tiene que caber en una mano. */

/* Lo que sólo aparece cuando la pantalla es angosta. */
.solo-angosto { display: none; }

@media (max-width: 46rem) {
  .contenido { padding: .9rem .8rem 3rem; }

  /* El encabezado: arriba la marca y los botones; abajo, en chiquito,
     empresa · usuario · papel. El nombre de la empresa se quita de junto
     al de la marca porque juntos no caben y partían el renglón en tres. */
  /* Arriba sólo la marca y los botones; abajo, en un renglón propio y
     completo, quién es la empresa y quién entró. Apretados en el mismo
     renglón se partían en tres: «Colegio / de / Prueba». */
  .barra { padding: .45rem .8rem .35rem; gap: .4rem .5rem; flex-wrap: wrap; }
  .marca-logo { gap: .45rem; }
  .marca-logo b { white-space: nowrap; font-size: .92rem; }
  .marca-logo em.empresa { display: none; }
  .marca-icono { width: 28px; height: 28px; }
  .barra .crece { display: none; }
  .barra .btn.chico { padding: .26rem .55rem; font-size: .73rem; margin-left: auto; }
  .barra .btn.chico + .btn.chico { margin-left: 0; }

  .barra .quien {
    order: 10; flex-basis: 100%; text-align: left;
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 .35rem;
    font-size: .7rem; line-height: 1.35; min-width: 0;
    padding-top: .1rem; border-top: 1px solid var(--linea);
  }
  .barra .quien b { font-size: .7rem; font-weight: 600; color: var(--tinta2); }
  .barra .quien em { display: inline; font-size: .7rem; }
  .barra .quien .solo-angosto { display: inline; color: var(--tinta); font-weight: 600; }
  /* Un punto medio separa los datos sin necesidad de más elementos. */
  .barra .quien > * + *::before { content: "· "; color: var(--tinta3); }

  /* Las pestañas dejan de ir pegadas arriba: su distancia al techo estaba
     calculada para una barra de un solo renglón, y en el teléfono la barra
     es más alta, así que se encimaban con el contenido. */
  /* En el teléfono no hay ancho para una columna de 248px. La barra pasa a
     ser una tira arriba: la marca y el usuario en un renglón, y los iconos
     con su texto en otro que se desliza de lado. */
  .armazon { flex-direction: column; }
  .lateral {
    width: auto !important; height: auto; position: sticky; top: 0;
    padding: .55rem .8rem .35rem; gap: .4rem;
  }
  .lateral .marca-logo { padding: 0 0 .5rem; margin: 0; }
  .lateral .marca-logo b { font-size: .95rem; }
  .lateral-tirador { display: none; }
  .pestanas {
    flex-direction: row; overflow-x: auto; overflow-y: hidden;
    gap: .2rem; padding: .1rem 0 .35rem; margin: 0;
    scrollbar-width: none;
  }
  .pestanas::-webkit-scrollbar { display: none; }
  .pestanas button { width: auto; flex: none; padding: .45rem .7rem; gap: .45rem; }
  .pestanas button.activa::before { top: auto; bottom: 0; transform: none;
                                    width: 60%; height: 2.5px; left: 20%; border-radius: 3px 3px 0 0; }
  .lateral .quien { border-top: 0; border-bottom: 0; padding: 0 0 .35rem;
                    display: flex; gap: .4rem; align-items: baseline; flex-wrap: wrap; }
  .lateral .quien b, .lateral .quien .empresa { display: inline; }
  .lateral-acciones { flex-direction: row; padding: 0 0 .3rem; gap: .35rem; }
  .lateral-acciones .btn { width: auto; }
  .contenido { padding: 1.1rem .85rem 3rem; }
  .titulo-vista h1 { font-size: 1.5rem; }

  /* Los filtros: las fechas de dos en dos, y lo demás a todo lo ancho. */
  .filtros { padding: .6rem .65rem; gap: .4rem; border-radius: 11px; }
  .filtros .sep { display: none; }
  .filtros input[type=date] { width: calc(50% - .55rem); min-width: 8rem; }
  .filtros select, .filtros input.buscador { width: 100%; min-width: 0; }
  .filtros .btn { padding: .3rem .62rem; font-size: .76rem; }
  .filtros .crece { display: none; }

  .cifras { grid-template-columns: repeat(auto-fit, minmax(7.4rem, 1fr)); gap: .5rem; }
  .cifra { padding: .7rem .75rem; }
  .cifra .val { font-size: 1.35rem; }

  .caja { padding: .9rem .8rem; border-radius: 11px; }
  .columnas { gap: 1.1rem; }

  /* Las ventanas ocupan casi toda la pantalla: en un teléfono, una ventana
     con margen alrededor deja el formulario en una rendija. */
  .velo { padding: .5rem .45rem; }
  .ventana { padding: .9rem .85rem; border-radius: 12px; }
  #velo-ficha .ventana .cabeza { top: -.9rem; margin: -.9rem -.85rem .8rem;
                                 padding: .8rem .85rem .6rem; }
  .ventana .cabeza h2 { font-size: .98rem; }
  .rejilla, .rejilla.dos { grid-template-columns: 1fr; }
  .sub-pestanas { gap: .15rem; }
  .sub-pestanas button { padding: .3rem .6rem; font-size: .78rem; }
  .pie-ventana { position: sticky; bottom: -.9rem; background: var(--tarjeta);
                 margin: 1rem -.85rem -.9rem; padding: .8rem .85rem; }

  .mapa { height: 15rem; }
  .plantel { gap: .6rem; }
  .plantel .acciones { width: 100%; }
  .plantel .acciones .btn { flex: 1; }

  /* Que se note que la tabla se desliza, en vez de parecer cortada. */
  .tabla-envoltura { margin: 0 -.8rem; padding: 0 .8rem; }
}

@media (max-width: 30rem) {
  .filtros input[type=date] { width: 100%; }
  .cifras { grid-template-columns: 1fr 1fr; }
  .linea-agregar { flex-direction: column; align-items: stretch; }
  .linea-agregar .btn { width: 100%; }

  /* LOS CAMPOS DE CAPTURA, A TODO LO ANCHO. Un `<label>Rige desde<br><input>`
     dentro de una columna deja la etiqueta estirada y el campo con su ancho de
     fábrica —unos 130px para una fecha—, y el resultado es una fila de cajitas
     angostas que no se puede enseñar a un cliente. Aquí cada campo ocupa su
     renglón completo, que es como se captura con el pulgar. */
  .linea-agregar > label { display: block; width: 100%; text-align: left; }
  .linea-agregar > label input,
  .linea-agregar > label select,
  .linea-agregar > label textarea { width: 100%; box-sizing: border-box; }
  .linea-agregar select, .linea-agregar input[type=text],
  .linea-agregar input[type=date], .linea-agregar input[type=time] { width: 100%; }
  .filtros select, .filtros input.buscador { width: 100%; min-width: 0; }

  /* Ningún encabezado ni texto largo puede reventar su tarjeta. */
  .caja > h2, .titulo-vista h1 { overflow-wrap: anywhere; }
  .aviso, .nota, .fundamento, .pista-celda { overflow-wrap: anywhere; }

  /* Las tarjetas, con menos aire: en 375px el relleno de escritorio se come
     una quinta parte del ancho útil. */
  .caja { padding: 1rem .85rem; }
}

/* ── El calendario del año (Panorama) ─────────────────────────────────
   Un mes en grande a la izquierda con los doce del año debajo, y a la
   derecha el día que se elija y lo que viene. En el teléfono la columna
   de la derecha se va abajo y los doce meses pasan de cuatro columnas a
   dos: la reja de un mes con seis columnas de ancho no cabe en 375px sin
   que los números se encimen. */
.agenda .agenda-cuerpo { display: grid; grid-template-columns: minmax(0, 1fr) 19rem; gap: 1rem; align-items: start; }
.agenda-izq { min-width: 0; display: flex; flex-direction: column; gap: .8rem; }
.agenda-der { display: flex; flex-direction: column; gap: .7rem; min-width: 0; }

.agenda-mes-cabeza { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .6rem; }
.agenda-mes-cabeza > div { text-align: center; line-height: 1.15; }
.agenda-mes-cabeza b { font-size: 1.45rem; font-weight: 500; display: block; color: var(--tinta2); }
.agenda-mes-cabeza span { font-size: .78rem; color: var(--tinta3); }

/* Las divisiones del calendario: casi imperceptibles. Una reja con líneas
   fuertes convierte el mes en una hoja de cálculo. */
.agenda-rejilla { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.agenda-dow { text-align: center; font-size: .68rem; font-weight: 700; color: var(--tinta3);
              text-transform: uppercase; letter-spacing: .05em; padding: .2rem 0; }
.agenda-hueco { min-height: 1px; }

.agenda-celda {
  appearance: none; text-align: left; cursor: pointer; font: inherit;
  background: color-mix(in srgb, var(--tarjeta2) 62%, transparent);
  border: 1.5px solid transparent; border-radius: 12px;
  min-height: 4.3rem; padding: .3rem .35rem; display: flex; flex-direction: column; gap: 3px;
  overflow: hidden; transition: border-color .12s, background .12s;
}
.agenda-celda:hover { border-color: var(--linea2); background: var(--tarjeta2); }
.agenda-celda.futuro { background: transparent; border-color: var(--linea); }
.agenda-celda.cerrado { background: color-mix(in srgb, var(--verde-vivo) 10%, var(--tarjeta2)); }
/* El día de hoy: fondo suave de oro y borde de 2px del mismo oro. Es el
   único sitio del calendario donde el acento aparece. */
.agenda-celda.hoy { border-width: 2px; border-color: var(--acento); background: var(--acento-f); }
.agenda-celda.elegido { border-color: var(--primario); box-shadow: 0 0 0 3px var(--primario-f); }
.agenda-num { align-self: flex-end; font-size: .95rem; font-weight: 500; font-variant-numeric: tabular-nums;
              color: var(--tinta2); line-height: 1; padding: .1rem .12rem 0; }
.agenda-celda.hoy .agenda-num { color: var(--acento-t); font-weight: 600; }
.agenda-chips { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Cápsula: fondo del color al 13% y letra en la versión oscura del MISMO
   color. Nunca letra negra sobre color, ni color macizo con letra blanca:
   a este tamaño el blanco sobre color se vuelve ilegible. */
.agenda-chip {
  display: block; font-size: .62rem; font-weight: 600; line-height: 1.5;
  border: 0; border-radius: 5px; padding: 0 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.agenda-mas { font-size: .6rem; font-weight: 700; color: var(--tinta3); }

.agenda-barra { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
                border-top: 1px solid var(--linea); padding-top: .7rem; }
.agenda-anio-nav { display: flex; align-items: center; gap: .35rem; }
.agenda-anio-nav b { font-size: .95rem; min-width: 3rem; text-align: center; font-variant-numeric: tabular-nums; }
.agenda-leyenda { margin-top: 0; }

.agenda-anio { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .55rem; }
.agenda-mini { border: 1px solid var(--linea); border-radius: var(--radio-s); padding: .4rem; min-width: 0; }
.agenda-mini.activo { border-color: var(--acento); box-shadow: 0 0 0 1px var(--acento); }
.agenda-mini-tit {
  appearance: none; width: 100%; cursor: pointer; font: inherit; font-size: .68rem; font-weight: 600;
  background: transparent; color: var(--tinta3); border: 0; border-radius: 6px;
  padding: .2rem; margin-bottom: .3rem; text-align: center;
  text-transform: uppercase; letter-spacing: .1em;
}
.agenda-mini-tit:hover { background: var(--tarjeta2); color: var(--tinta2); }
.agenda-mini.activo .agenda-mini-tit { background: var(--acento-f); color: var(--acento-t); }
.agenda-mini-rejilla { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 1px; text-align: center; }
.agenda-mini-dow { font-size: .52rem; font-weight: 700; color: var(--tinta3); line-height: 1.5; }
.agenda-mini-dia {
  appearance: none; cursor: pointer; font: inherit; font-size: .58rem; line-height: 1.5;
  background: none; color: var(--tinta2); border: 1px solid transparent; border-radius: 3px;
  padding: 0; font-variant-numeric: tabular-nums; font-weight: 600;
}
.agenda-mini-dia:hover { background: var(--tarjeta2); }
.agenda-mini-dia.hoy { outline: 1.5px solid var(--acento); outline-offset: -1px; }
.agenda-mini-dia.elegido { background: var(--primario); color: var(--sobre-primario); border-color: var(--primario); }

.agenda-panel { border: 1px solid var(--linea); border-radius: var(--radio-s); padding: .75rem .8rem; background: var(--tarjeta2); }
.agenda-panel h3 { font-family: var(--serif); font-size: 1rem; font-weight: 600;
                   color: var(--tinta); margin-bottom: .5rem; }
.agenda-prox { max-height: 24rem; overflow-y: auto; }
.agenda-prox h3 { font-size: .7rem; text-transform: uppercase; letter-spacing: .07em; color: var(--tinta3); }
.agenda-nada { font-size: .8rem; color: var(--tinta3); }
.agenda-pie { font-size: .75rem; color: var(--tinta3); margin-top: .6rem; border-top: 1px solid var(--linea); padding-top: .45rem; }

.agenda-marcas { display: flex; flex-direction: column; gap: .3rem; margin-bottom: .6rem; }
.agenda-marca { display: flex; gap: .4rem; align-items: flex-start; font-size: .78rem; color: var(--tinta2); }
.agenda-marca i, .agenda-prox-fila i, .agenda-grupo h4 i {
  display: inline-block; width: 9px; height: 9px; border: 1px solid; border-radius: 2px; flex: none; margin-top: .28rem;
}

.agenda-grupo { margin-bottom: .6rem; }
.agenda-grupo h4 { display: flex; align-items: center; gap: .35rem; font-size: .78rem;
                   font-weight: 700; color: var(--tinta2); margin: 0 0 .3rem; }
.agenda-grupo h4 i { margin-top: 0; }
.agenda-quien, .agenda-prox-fila {
  appearance: none; width: 100%; text-align: left; cursor: pointer; font: inherit;
  background: var(--tarjeta); border: 1px solid var(--linea); border-radius: 6px;
  padding: .3rem .45rem; margin-bottom: .25rem; display: flex; gap: .4rem; align-items: flex-start;
}
.agenda-quien:hover, .agenda-prox-fila:hover { border-color: var(--primario); }
.agenda-quien b, .agenda-prox-fila b { display: block; font-size: .8rem; line-height: 1.25; }
.agenda-quien em, .agenda-prox-fila em { display: block; font-style: normal; font-size: .7rem;
                                         color: var(--tinta3); line-height: 1.3; }
.agenda-prox-fila span { min-width: 0; }

@media (max-width: 900px) {
  .agenda .agenda-cuerpo { grid-template-columns: minmax(0, 1fr); }
  .agenda-prox { max-height: none; }
}
@media (max-width: 560px) {
  .agenda-anio { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .agenda-celda { min-height: 3.2rem; }
  .agenda-chip { font-size: .55rem; }
  .agenda-rejilla { gap: 2px; }
}

/* ── Espacios de cliente (sólo el proveedor) ──────────────────────────── */
.caja.cliente { padding: .9rem 1rem; }
.caja.cliente.apagado { opacity: .62; }
.cliente-cabeza { display: flex; gap: .7rem; align-items: flex-start; }
.cliente-color { width: 6px; align-self: stretch; min-height: 2.2rem; border-radius: 3px; flex: none; }
.cliente-datos { font-size: .78rem; color: var(--tinta3); margin-top: .15rem; }
.cliente-cuentas { display: flex; gap: 1.4rem; flex-wrap: wrap; margin-top: .7rem;
                   padding-top: .6rem; border-top: 1px solid var(--linea); }
.cliente-cuentas > div { display: flex; flex-direction: column; }
.cliente-cuentas b { font-family: "Familjen Grotesk", sans-serif; font-size: 1.05rem; line-height: 1.1; }
.cliente-cuentas span { font-size: .7rem; color: var(--tinta3); }
.cliente-acciones { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .7rem; }
.cliente-puerta { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
                  margin-top: .55rem; font-size: .78rem; }
.cliente-puerta > span { color: var(--tinta3); font-weight: 600;
                        text-transform: uppercase; letter-spacing: .08em; font-size: .66rem; }
.cliente-puerta code { font-family: "IBM Plex Mono", ui-monospace, monospace;
                      background: var(--tarjeta2); border: 1px solid var(--linea);
                      border-radius: 6px; padding: .15rem .45rem; color: var(--tinta2); }
@media (max-width: 560px) {
  .cliente-cuentas { gap: .9rem; }
  .cliente-acciones .btn { flex: 1 1 auto; }
}

/* ── El aviso de privacidad, como página pública ──────────────────────
   Se abre sin contraseña: la ley pide ponerlo «a disposición» del titular, y
   un aviso que exige iniciar sesión no está a disposición de nadie. */
.hoja-legal { padding: 2.5rem 1.2rem 5rem; }
.hoja-legal main { max-width: 46rem; margin: 0 auto; }
.hoja-legal .aviso-logo { display: block; max-height: 96px; max-width: 200px;
                          object-fit: contain; margin-bottom: 1.4rem; }
.hoja-legal h1 { font-family: var(--serif); font-size: clamp(1.9rem, 4vw, 2.5rem);
                 font-weight: 600; line-height: 1.1; margin: .3rem 0 .8rem; }
.hoja-legal h2 { display: flex; align-items: baseline; gap: .6rem;
                 font-size: 1.08rem; margin: 2.4rem 0 .7rem; padding-top: 1rem;
                 border-top: 1px solid var(--linea); }
.hoja-legal h2 .n { font-family: "IBM Plex Mono", ui-monospace, monospace;
                    font-size: .8rem; color: var(--acento-t); font-weight: 600; }
.hoja-legal p { margin: 0 0 .9rem; line-height: 1.65; color: var(--tinta2); }
.hoja-legal .quien { background: var(--tarjeta); border: 1px solid var(--linea);
                     border-left: 4px solid var(--acento); border-radius: var(--radio-s);
                     padding: .9rem 1rem; color: var(--tinta); }
.hoja-legal .intro { font-size: 1.02rem; color: var(--tinta); }
.hoja-legal .pie { margin-top: 2.5rem; padding-top: 1rem; border-top: 1px solid var(--linea);
                   font-size: .82rem; color: var(--tinta3); }

/* Los dos pasos para que el navegador guarde el PDF en vez de imprimirlo. */

/* El logotipo del cliente en su propia puerta. */
/* El logotipo de un cliente puede ser alargado (un texto) o cuadrado (un
   escudo). Se le deja alto de sobra y se contiene, para que ninguno de los dos
   salga aplastado. */
.entrar-logo { display: block; max-width: 190px; max-height: 118px; margin: 0 auto 1.1rem;
               object-fit: contain; }

/* ── Estás dentro del espacio de otro ─────────────────────────────────
   Cuando el proveedor entra a atender a un cliente, la pantalla lo dice con
   todas sus letras y no se quita. Trabajar en los datos de otro creyendo que
   son los propios es como se corrigen checadas que no eran. */
.aviso-suplantando {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  padding: .55rem 1.1rem; font-size: .84rem; font-weight: 600;
  background: var(--acento); color: var(--indigo);
  border-bottom: 1px solid var(--acento2);
}
.aviso-suplantando .crece { flex: 1; }
.aviso-suplantando .btn { background: var(--indigo); color: var(--sobre-indigo);
                          border-color: var(--indigo); }
.aviso-suplantando .btn:hover { background: var(--indigo-hover); border-color: var(--indigo-hover); }

/* ── Las muestras de paleta ───────────────────────────────────────────
   Cada una enseña sus seis tonos. Se ve la paleta, no su nombre: nadie elige
   «Bosque y Musgo» de memoria, se elige la que se ve bien. */
.paletas { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
           gap: .5rem; margin-bottom: 1rem; }
.paleta {
  appearance: none; cursor: pointer; font: inherit; text-align: left;
  background: var(--tarjeta); border: 1.5px solid var(--linea);
  border-radius: 12px; padding: .5rem .55rem;
  display: flex; flex-direction: column; gap: .4rem;
  transition: border-color .12s, box-shadow .12s;
}
.paleta:hover { border-color: var(--linea2); }
.paleta.elegida { border-color: var(--acento); box-shadow: 0 0 0 2px var(--acento-f); }
.paleta-tonos { display: flex; gap: 3px; }
.paleta-tonos i {
  flex: 1; height: 22px; border-radius: 4px; display: block;
  border: 1px solid rgba(0, 0, 0, .07);
}
.paleta-nombre { font-size: .74rem; font-weight: 600; color: var(--tinta2); }
.paleta.elegida .paleta-nombre { color: var(--acento-t); }

/* ── Qué módulos contrata un cliente ──────────────────────────────────
   Se ve como una tarjeta que se prende, y no como una casilla suelta con
   texto al lado: cada una apaga o enciende una parte entera del producto,
   y merece decir con todas sus letras qué es lo que se lleva. */
.modulos-elegir { display: grid; gap: .5rem; margin-bottom: 1rem; }
.modulo {
  display: flex; align-items: flex-start; gap: .6rem; cursor: pointer;
  background: var(--tarjeta); border: 1.5px solid var(--linea);
  border-radius: 12px; padding: .6rem .7rem;
  transition: border-color .12s, box-shadow .12s;
}
.modulo:hover { border-color: var(--linea2); }
.modulo:has(input:checked) { border-color: var(--acento); box-shadow: 0 0 0 2px var(--acento-f); }
.modulo input { margin-top: .18rem; width: 1rem; height: 1rem; flex: none; accent-color: var(--acento); }
.modulo span { display: flex; flex-direction: column; gap: .12rem; min-width: 0; }
.modulo b { font-size: .84rem; }
.modulo i { font-style: normal; font-size: .74rem; color: var(--tinta2); line-height: 1.35; }

/* ── El botón de claro y oscuro ───────────────────────────────────────
   Hasta ahora la aplicación seguía al sistema operativo y no había forma de
   elegir. Quien trabaja de noche con la computadora en claro no tenía botón
   que tocar. */
.tema-grupo { display: flex; gap: 2px; padding: 2px; border-radius: 99px;
              background: var(--indigo-hover); }
.tema-grupo button {
  flex: 1; appearance: none; border: 0; cursor: pointer; font: inherit;
  font-size: .72rem; font-weight: 600; padding: .3rem .2rem; border-radius: 99px;
  background: none; color: var(--sobre-indigo-2);
  display: flex; align-items: center; justify-content: center; gap: .25rem;
}
.tema-grupo button svg { width: 14px; height: 14px; }
.tema-grupo button:hover { color: var(--sobre-indigo); }
.tema-grupo button.activa { background: var(--acento); color: var(--indigo); }
.lateral.plegada .tema-grupo { flex-direction: column; }
.lateral.plegada .tema-grupo button span { display: none; }

/* ═══ LAS PALETAS ══════════════════════════════════════════════
   Cada una se elige desde «Marca y diseño» y se guarda por cliente, así que
   la universidad puede verse distinta de la escuela sin tocar código.

   De cada paleta sólo se deciden SEIS tonos —fondo, profundo, medio, acento,
   alerta y éxito—; las demás variables salen de mezclarlos. Están escritas
   como hexadecimal fijo y no como color-mix() para que se impriman igual en
   cualquier navegador. Se generan con pruebas/paletas.js: si hay que tocar un
   tono, se toca ahí y se vuelve a generar, no se edita este bloque a mano.

   La paleta por omisión —sin atributo— es Oro e Índigo, y vive arriba en
   :root. Aquí van las cinco explícitas, incluida ésa, para poder elegirla de
   vuelta después de haber probado otra. */

/* ── Oro e Indigo ── */
:root[data-paleta="oro-indigo"] {
  --papel: #FAF7F2;
  --papel2: #EFECE9;
  --tarjeta: #FFFFFF;
  --tarjeta2: #EBE8E5;
  --linea: #E7E4E2;
  --linea2: #CBC7CA;
  --tinta: #241F3D;
  --tinta2: #4A4270;
  --tinta3: #9993AA;
  --marca: #241F3D;
  --primario: #4A4270;
  --primario2: #241F3D;
  --primario-f: #E3DFE1;
  --sobre-primario: #FFFFFF;
  --sobre-acento: #241F3D;
  --acento: #C9A15C;
  --acento2: #A5844B;
  --acento-t: #7D6439;
  --acento-f: #F3EBDD;
  --verde: #455942;
  --verde-f: #E7E8DF;
  --verde-vivo: #6F8F6A;
  --ambar: #7D6439;
  --ambar-f: #F3EBDD;
  --rojo: #703F2E;
  --rojo-f: #F0E3DA;
  --rojo-vivo: #B5654A;
  --morado: #4A4270;
  --morado-f: #E3DFE1;
  --indigo: #241F3D;
  --indigo-hover: #39354F;
  --indigo-activo: #443F58;
  --indigo-linea: #3E3953;
  --sobre-indigo: #FBF9F5;
  --sobre-indigo-2: #A9A5AD;
}
@media (prefers-color-scheme: dark) {
  :root[data-paleta="oro-indigo"]:not([data-theme="light"]) {
    --papel: #090810;
    --papel2: #0E0C18;
    --tarjeta: #332F4B;
    --tarjeta2: #47435C;
    --linea: #545068;
    --linea2: #6E6B7F;
    --tinta: #FBF8F4;
    --tinta2: #B7B2C1;
    --tinta3: #8D87A1;
    --marca: #C9A15C;
    --primario: #B0ABBB;
    --primario2: #CECAD2;
    --primario-f: #1F1C31;
    --sobre-primario: #090810;
    --sobre-acento: #241F3D;
    --acento: #C9A15C;
    --acento2: #D4B47D;
    --acento-t: #DCC295;
    --acento-f: #372D22;
    --verde: #A4B79E;
    --verde-f: #1F2624;
    --verde-vivo: #88A282;
    --ambar: #D9BD8C;
    --ambar-f: #332A21;
    --rojo: #CF9C8A;
    --rojo-f: #2F1C1D;
    --rojo-vivo: #C3826C;
    --morado: #A6A0B4;
    --morado-f: #1F1C31;
    --indigo: #241F3D;
    --indigo-hover: #39354F;
    --indigo-activo: #443F58;
    --indigo-linea: #3E3953;
    --sobre-indigo: #FBF9F5;
    --sobre-indigo-2: #A9A5AD;
}
}
:root[data-paleta="oro-indigo"][data-theme="dark"] {
  --papel: #090810;
  --papel2: #0E0C18;
  --tarjeta: #332F4B;
  --tarjeta2: #47435C;
  --linea: #545068;
  --linea2: #6E6B7F;
  --tinta: #FBF8F4;
  --tinta2: #B7B2C1;
  --tinta3: #8D87A1;
  --marca: #C9A15C;
  --primario: #B0ABBB;
  --primario2: #CECAD2;
  --primario-f: #1F1C31;
  --sobre-primario: #090810;
  --sobre-acento: #241F3D;
  --acento: #C9A15C;
  --acento2: #D4B47D;
  --acento-t: #DCC295;
  --acento-f: #372D22;
  --verde: #A4B79E;
  --verde-f: #1F2624;
  --verde-vivo: #88A282;
  --ambar: #D9BD8C;
  --ambar-f: #332A21;
  --rojo: #CF9C8A;
  --rojo-f: #2F1C1D;
  --rojo-vivo: #C3826C;
  --morado: #A6A0B4;
  --morado-f: #1F1C31;
  --indigo: #241F3D;
  --indigo-hover: #39354F;
  --indigo-activo: #443F58;
  --indigo-linea: #3E3953;
  --sobre-indigo: #FBF9F5;
  --sobre-indigo-2: #A9A5AD;
}

/* ── Vino y Arena ── */
:root[data-paleta="vino-arena"] {
  --papel: #F8F3ED;
  --papel2: #F0E9E4;
  --tarjeta: #FFFFFF;
  --tarjeta2: #EDE5E0;
  --linea: #EAE1DC;
  --linea2: #D6C7C4;
  --tinta: #5C2A32;
  --tinta2: #8C4A50;
  --tinta3: #BD9697;
  --marca: #5C2A32;
  --primario: #8C4A50;
  --primario2: #5C2A32;
  --primario-f: #EADDD9;
  --sobre-primario: #FFFFFF;
  --sobre-acento: #5C2A32;
  --acento: #C97954;
  --acento2: #A56345;
  --acento-t: #7D4B34;
  --acento-f: #F1E2D8;
  --verde: #4C563A;
  --verde-f: #E6E4D9;
  --verde-vivo: #7A8B5E;
  --ambar: #7D4B34;
  --ambar-f: #F1E2D8;
  --rojo: #815644;
  --rojo-f: #F2E4DB;
  --rojo-vivo: #D08A6E;
  --morado: #8C4A50;
  --morado-f: #EADDD9;
  --indigo: #5C2A32;
  --indigo-hover: #6C3E45;
  --indigo-activo: #73484E;
  --indigo-linea: #6F4248;
  --sobre-indigo: #F9F5F1;
  --sobre-indigo-2: #BDA7A6;
}
@media (prefers-color-scheme: dark) {
  :root[data-paleta="vino-arena"]:not([data-theme="light"]) {
    --papel: #180B0D;
    --papel2: #251114;
    --tarjeta: #673940;
    --tarjeta2: #764C53;
    --linea: #80595F;
    --linea2: #937278;
    --tinta: #F9F5F0;
    --tinta2: #CFB3B1;
    --tinta3: #B58A8C;
    --marca: #C97954;
    --primario: #CBACAB;
    --primario2: #DDC9C6;
    --primario-f: #3F2024;
    --sobre-primario: #180B0D;
    --sobre-acento: #5C2A32;
    --acento: #C97954;
    --acento2: #D39476;
    --acento-t: #DBA78E;
    --acento-f: #42251E;
    --verde: #AAB394;
    --verde-f: #2E271F;
    --verde-vivo: #919E78;
    --ambar: #D8A085;
    --ambar-f: #3F231D;
    --rojo: #DFB29E;
    --rojo-f: #402722;
    --rojo-vivo: #D89F87;
    --morado: #C4A2A2;
    --morado-f: #3F2024;
    --indigo: #5C2A32;
    --indigo-hover: #6C3E45;
    --indigo-activo: #73484E;
    --indigo-linea: #6F4248;
    --sobre-indigo: #F9F5F1;
    --sobre-indigo-2: #BDA7A6;
}
}
:root[data-paleta="vino-arena"][data-theme="dark"] {
  --papel: #180B0D;
  --papel2: #251114;
  --tarjeta: #673940;
  --tarjeta2: #764C53;
  --linea: #80595F;
  --linea2: #937278;
  --tinta: #F9F5F0;
  --tinta2: #CFB3B1;
  --tinta3: #B58A8C;
  --marca: #C97954;
  --primario: #CBACAB;
  --primario2: #DDC9C6;
  --primario-f: #3F2024;
  --sobre-primario: #180B0D;
  --sobre-acento: #5C2A32;
  --acento: #C97954;
  --acento2: #D39476;
  --acento-t: #DBA78E;
  --acento-f: #42251E;
  --verde: #AAB394;
  --verde-f: #2E271F;
  --verde-vivo: #919E78;
  --ambar: #D8A085;
  --ambar-f: #3F231D;
  --rojo: #DFB29E;
  --rojo-f: #402722;
  --rojo-vivo: #D89F87;
  --morado: #C4A2A2;
  --morado-f: #3F2024;
  --indigo: #5C2A32;
  --indigo-hover: #6C3E45;
  --indigo-activo: #73484E;
  --indigo-linea: #6F4248;
  --sobre-indigo: #F9F5F1;
  --sobre-indigo-2: #BDA7A6;
}

/* ── Bosque y Musgo ── */
:root[data-paleta="bosque-musgo"] {
  --papel: #F5F3EA;
  --papel2: #EAE9E0;
  --tarjeta: #FFFFFF;
  --tarjeta2: #E6E5DC;
  --linea: #E2E1D8;
  --linea2: #C6C8BE;
  --tinta: #1F2E23;
  --tinta2: #3F5B44;
  --tinta3: #919F8F;
  --marca: #1F2E23;
  --primario: #3F5B44;
  --primario2: #1F2E23;
  --primario-f: #DDDFD4;
  --sobre-primario: #FFFFFF;
  --sobre-acento: #1F2E23;
  --acento: #C6A15B;
  --acento2: #A2844B;
  --acento-t: #7B6438;
  --acento-f: #EEE8D6;
  --verde: #4F634C;
  --verde-f: #E4E7DA;
  --verde-vivo: #7FA07A;
  --ambar: #7B6438;
  --ambar-f: #EEE8D6;
  --rojo: #703F2E;
  --rojo-f: #ECDFD4;
  --rojo-vivo: #B5654A;
  --morado: #3F5B44;
  --morado-f: #DDDFD4;
  --indigo: #1F2E23;
  --indigo-hover: #344237;
  --indigo-activo: #3F4C41;
  --indigo-linea: #39463B;
  --sobre-indigo: #F7F5EE;
  --sobre-indigo-2: #A4A89E;
}
@media (prefers-color-scheme: dark) {
  :root[data-paleta="bosque-musgo"]:not([data-theme="light"]) {
    --papel: #080C09;
    --papel2: #0C120E;
    --tarjeta: #2F3D32;
    --tarjeta2: #434F46;
    --linea: #505C53;
    --linea2: #6B756E;
    --tinta: #F6F5ED;
    --tinta2: #B0B9AB;
    --tinta3: #849583;
    --marca: #C6A15B;
    --primario: #A9B3A4;
    --primario2: #C8CDC0;
    --primario-f: #1B271D;
    --sobre-primario: #080C09;
    --sobre-acento: #1F2E23;
    --acento: #C6A15B;
    --acento2: #D0B37A;
    --acento-t: #D8C091;
    --acento-f: #36301D;
    --verde: #ACC0A5;
    --verde-f: #222D22;
    --verde-vivo: #94AF8E;
    --ambar: #D5BB89;
    --ambar-f: #322D1B;
    --rojo: #CD9B87;
    --rojo-f: #2E2017;
    --rojo-vivo: #C2816A;
    --morado: #9EAA9A;
    --morado-f: #1B271D;
    --indigo: #1F2E23;
    --indigo-hover: #344237;
    --indigo-activo: #3F4C41;
    --indigo-linea: #39463B;
    --sobre-indigo: #F7F5EE;
    --sobre-indigo-2: #A4A89E;
}
}
:root[data-paleta="bosque-musgo"][data-theme="dark"] {
  --papel: #080C09;
  --papel2: #0C120E;
  --tarjeta: #2F3D32;
  --tarjeta2: #434F46;
  --linea: #505C53;
  --linea2: #6B756E;
  --tinta: #F6F5ED;
  --tinta2: #B0B9AB;
  --tinta3: #849583;
  --marca: #C6A15B;
  --primario: #A9B3A4;
  --primario2: #C8CDC0;
  --primario-f: #1B271D;
  --sobre-primario: #080C09;
  --sobre-acento: #1F2E23;
  --acento: #C6A15B;
  --acento2: #D0B37A;
  --acento-t: #D8C091;
  --acento-f: #36301D;
  --verde: #ACC0A5;
  --verde-f: #222D22;
  --verde-vivo: #94AF8E;
  --ambar: #D5BB89;
  --ambar-f: #322D1B;
  --rojo: #CD9B87;
  --rojo-f: #2E2017;
  --rojo-vivo: #C2816A;
  --morado: #9EAA9A;
  --morado-f: #1B271D;
  --indigo: #1F2E23;
  --indigo-hover: #344237;
  --indigo-activo: #3F4C41;
  --indigo-linea: #39463B;
  --sobre-indigo: #F7F5EE;
  --sobre-indigo-2: #A4A89E;
}

/* ── Grafito y Plata ── */
:root[data-paleta="grafito-plata"] {
  --papel: #F7F7F8;
  --papel2: #ECECED;
  --tarjeta: #FFFFFF;
  --tarjeta2: #E8E8E9;
  --linea: #E3E3E5;
  --linea2: #C7C7C9;
  --tinta: #1C1D22;
  --tinta2: #585D68;
  --tinta3: #A0A2A9;
  --marca: #1C1D22;
  --primario: #585D68;
  --primario2: #1C1D22;
  --primario-f: #E2E3E5;
  --sobre-primario: #FFFFFF;
  --sobre-acento: #1C1D22;
  --acento: #3B58D8;
  --acento2: #3048B1;
  --acento-t: #253786;
  --acento-f: #DDE1F4;
  --verde: #1D6238;
  --verde-f: #DBEBE2;
  --verde-vivo: #2F9E5B;
  --ambar: #253786;
  --ambar-f: #DDE1F4;
  --rojo: #77231B;
  --rojo-f: #EFDCDB;
  --rojo-vivo: #C0392B;
  --morado: #585D68;
  --morado-f: #E2E3E5;
  --indigo: #1C1D22;
  --indigo-hover: #323337;
  --indigo-activo: #3D3E42;
  --indigo-linea: #36373C;
  --sobre-indigo: #F9F9F9;
  --sobre-indigo-2: #A4A4A7;
}
@media (prefers-color-scheme: dark) {
  :root[data-paleta="grafito-plata"]:not([data-theme="light"]) {
    --papel: #070809;
    --papel2: #0B0C0E;
    --tarjeta: #2C2D31;
    --tarjeta2: #404145;
    --linea: #4E4F53;
    --linea2: #696A6D;
    --tinta: #F8F8F9;
    --tinta2: #BBBCC1;
    --tinta3: #94989F;
    --marca: #3B58D8;
    --primario: #B4B6BC;
    --primario2: #CFD0D4;
    --primario-f: #232529;
    --sobre-primario: #070809;
    --sobre-acento: #1C1D22;
    --acento: #3B58D8;
    --acento2: #647BDF;
    --acento-t: #8294E4;
    --acento-f: #131B3B;
    --verde: #7BC097;
    --verde-f: #10291B;
    --verde-vivo: #53AE77;
    --ambar: #778BE2;
    --ambar-f: #121A37;
    --rojo: #D58179;
    --rojo-f: #301310;
    --rojo-vivo: #CB5F54;
    --morado: #ABADB3;
    --morado-f: #232529;
    --indigo: #1C1D22;
    --indigo-hover: #323337;
    --indigo-activo: #3D3E42;
    --indigo-linea: #36373C;
    --sobre-indigo: #F9F9F9;
    --sobre-indigo-2: #A4A4A7;
}
}
:root[data-paleta="grafito-plata"][data-theme="dark"] {
  --papel: #070809;
  --papel2: #0B0C0E;
  --tarjeta: #2C2D31;
  --tarjeta2: #404145;
  --linea: #4E4F53;
  --linea2: #696A6D;
  --tinta: #F8F8F9;
  --tinta2: #BBBCC1;
  --tinta3: #94989F;
  --marca: #3B58D8;
  --primario: #B4B6BC;
  --primario2: #CFD0D4;
  --primario-f: #232529;
  --sobre-primario: #070809;
  --sobre-acento: #1C1D22;
  --acento: #3B58D8;
  --acento2: #647BDF;
  --acento-t: #8294E4;
  --acento-f: #131B3B;
  --verde: #7BC097;
  --verde-f: #10291B;
  --verde-vivo: #53AE77;
  --ambar: #778BE2;
  --ambar-f: #121A37;
  --rojo: #D58179;
  --rojo-f: #301310;
  --rojo-vivo: #CB5F54;
  --morado: #ABADB3;
  --morado-f: #232529;
  --indigo: #1C1D22;
  --indigo-hover: #323337;
  --indigo-activo: #3D3E42;
  --indigo-linea: #36373C;
  --sobre-indigo: #F9F9F9;
  --sobre-indigo-2: #A4A4A7;
}

/* ── Marino y Cobre ── */
:root[data-paleta="marino-cobre"] {
  --papel: #F5F6F4;
  --papel2: #EAECEB;
  --tarjeta: #FFFFFF;
  --tarjeta2: #E6E8E7;
  --linea: #E1E4E3;
  --linea2: #C5C9CB;
  --tinta: #1B2A3A;
  --tinta2: #3E5A72;
  --tinta3: #90A0AC;
  --marca: #1B2A3A;
  --primario: #3E5A72;
  --primario2: #1B2A3A;
  --primario-f: #DDE2E3;
  --sobre-primario: #FFFFFF;
  --sobre-acento: #1B2A3A;
  --acento: #BD7A46;
  --acento2: #9B6439;
  --acento-t: #754C2B;
  --acento-f: #EDE5DC;
  --verde: #315954;
  --verde-f: #DEE8E5;
  --verde-vivo: #4F9088;
  --ambar: #754C2B;
  --ambar-f: #EDE5DC;
  --rojo: #703F2E;
  --rojo-f: #ECE2DC;
  --rojo-vivo: #B5654A;
  --morado: #3E5A72;
  --morado-f: #DDE2E3;
  --indigo: #1B2A3A;
  --indigo-hover: #313E4D;
  --indigo-activo: #3C4956;
  --indigo-linea: #354250;
  --sobre-indigo: #F7F8F6;
  --sobre-indigo-2: #A2A8AD;
}
@media (prefers-color-scheme: dark) {
  :root[data-paleta="marino-cobre"]:not([data-theme="light"]) {
    --papel: #070B0F;
    --papel2: #0B1117;
    --tarjeta: #2B3948;
    --tarjeta2: #3F4C5A;
    --linea: #4D5965;
    --linea2: #69727D;
    --tinta: #F6F7F6;
    --tinta2: #AFBBC3;
    --tinta3: #8495A3;
    --marca: #BD7A46;
    --primario: #A8B4BD;
    --primario2: #C7CFD4;
    --primario-f: #1A2631;
    --sobre-primario: #070B0F;
    --sobre-acento: #1B2A3A;
    --acento: #BD7A46;
    --acento2: #C9956C;
    --acento-t: #D2A988;
    --acento-f: #33261C;
    --verde: #8EB7B1;
    --verde-f: #17282A;
    --verde-vivo: #6DA29B;
    --ambar: #CFA27E;
    --ambar-f: #2F231B;
    --rojo: #CD9C8B;
    --rojo-f: #2D1F1C;
    --rojo-vivo: #C2826C;
    --morado: #9DABB6;
    --morado-f: #1A2631;
    --indigo: #1B2A3A;
    --indigo-hover: #313E4D;
    --indigo-activo: #3C4956;
    --indigo-linea: #354250;
    --sobre-indigo: #F7F8F6;
    --sobre-indigo-2: #A2A8AD;
}
}
:root[data-paleta="marino-cobre"][data-theme="dark"] {
  --papel: #070B0F;
  --papel2: #0B1117;
  --tarjeta: #2B3948;
  --tarjeta2: #3F4C5A;
  --linea: #4D5965;
  --linea2: #69727D;
  --tinta: #F6F7F6;
  --tinta2: #AFBBC3;
  --tinta3: #8495A3;
  --marca: #BD7A46;
  --primario: #A8B4BD;
  --primario2: #C7CFD4;
  --primario-f: #1A2631;
  --sobre-primario: #070B0F;
  --sobre-acento: #1B2A3A;
  --acento: #BD7A46;
  --acento2: #C9956C;
  --acento-t: #D2A988;
  --acento-f: #33261C;
  --verde: #8EB7B1;
  --verde-f: #17282A;
  --verde-vivo: #6DA29B;
  --ambar: #CFA27E;
  --ambar-f: #2F231B;
  --rojo: #CD9C8B;
  --rojo-f: #2D1F1C;
  --rojo-vivo: #C2826C;
  --morado: #9DABB6;
  --morado-f: #1A2631;
  --indigo: #1B2A3A;
  --indigo-hover: #313E4D;
  --indigo-activo: #3C4956;
  --indigo-linea: #354250;
  --sobre-indigo: #F7F8F6;
  --sobre-indigo-2: #A2A8AD;
}

/* ── Guinda y Oro ── */
:root[data-paleta="guinda-oro"] {
  --papel: #FAF4EF;
  --papel2: #F1E9E5;
  --tarjeta: #FFFFFF;
  --tarjeta2: #EEE4E0;
  --linea: #EADFDC;
  --linea2: #D3C2C1;
  --tinta: #4A0F1E;
  --tinta2: #8A2338;
  --tinta3: #BC818A;
  --marca: #4A0F1E;
  --primario: #8A2338;
  --primario2: #4A0F1E;
  --primario-f: #EBD9D7;
  --sobre-primario: #FFFFFF;
  --sobre-acento: #4A0F1E;
  --acento: #C9A227;
  --acento2: #A58520;
  --acento-t: #7D6418;
  --acento-f: #F3E9D3;
  --verde: #3B4F38;
  --verde-f: #E4E4DA;
  --verde-vivo: #5F7F5A;
  --ambar: #7D6418;
  --ambar-f: #F3E9D3;
  --rojo: #77231B;
  --rojo-f: #F2DAD4;
  --rojo-vivo: #C0392B;
  --morado: #8A2338;
  --morado-f: #EBD9D7;
  --indigo: #4A0F1E;
  --indigo-hover: #5C2633;
  --indigo-activo: #64313D;
  --indigo-linea: #5F2A37;
  --sobre-indigo: #FBF6F2;
  --sobre-indigo-2: #B79DA0;
}
@media (prefers-color-scheme: dark) {
  :root[data-paleta="guinda-oro"]:not([data-theme="light"]) {
    --papel: #130408;
    --papel2: #1E060C;
    --tarjeta: #57202E;
    --tarjeta2: #673542;
    --linea: #724450;
    --linea2: #88616A;
    --tinta: #FBF6F1;
    --tinta2: #CFA5A9;
    --tinta3: #B5727E;
    --marca: #C9A227;
    --primario: #CB9CA2;
    --primario2: #DEC0C1;
    --primario-f: #3B0F18;
    --sobre-primario: #130408;
    --sobre-acento: #4A0F1E;
    --acento: #C9A227;
    --acento2: #D4B453;
    --acento-t: #DCC173;
    --acento-f: #3F2A0F;
    --verde: #9AAB93;
    --verde-f: #241F1A;
    --verde-vivo: #7B9475;
    --ambar: #D9BC67;
    --ambar-f: #3B270F;
    --rojo: #D68075;
    --rojo-f: #391010;
    --rojo-vivo: #CC5E52;
    --morado: #C49097;
    --morado-f: #3B0F18;
    --indigo: #4A0F1E;
    --indigo-hover: #5C2633;
    --indigo-activo: #64313D;
    --indigo-linea: #5F2A37;
    --sobre-indigo: #FBF6F2;
    --sobre-indigo-2: #B79DA0;
}
}
:root[data-paleta="guinda-oro"][data-theme="dark"] {
  --papel: #130408;
  --papel2: #1E060C;
  --tarjeta: #57202E;
  --tarjeta2: #673542;
  --linea: #724450;
  --linea2: #88616A;
  --tinta: #FBF6F1;
  --tinta2: #CFA5A9;
  --tinta3: #B5727E;
  --marca: #C9A227;
  --primario: #CB9CA2;
  --primario2: #DEC0C1;
  --primario-f: #3B0F18;
  --sobre-primario: #130408;
  --sobre-acento: #4A0F1E;
  --acento: #C9A227;
  --acento2: #D4B453;
  --acento-t: #DCC173;
  --acento-f: #3F2A0F;
  --verde: #9AAB93;
  --verde-f: #241F1A;
  --verde-vivo: #7B9475;
  --ambar: #D9BC67;
  --ambar-f: #3B270F;
  --rojo: #D68075;
  --rojo-f: #391010;
  --rojo-vivo: #CC5E52;
  --morado: #C49097;
  --morado-f: #3B0F18;
  --indigo: #4A0F1E;
  --indigo-hover: #5C2633;
  --indigo-activo: #64313D;
  --indigo-linea: #5F2A37;
  --sobre-indigo: #FBF6F2;
  --sobre-indigo-2: #B79DA0;
}


/* ── PUENTE DE COLOR ──────────────────────────────────────────────────
   Seis colores del calendario y cuatro de las gráficas están escritos como
   hex DENTRO del JavaScript (AG_TIPOS en agenda.js, y las series de
   panel.js). Ahí no se toca nada: se traducen desde aquí.

   Las cápsulas y los cuadritos de leyenda llevan el color en un atributo
   `style`, que sólo se le gana con !important. Los rectángulos de las
   gráficas lo llevan en el atributo `fill`, que la hoja de estilos gana sin
   necesidad de forzar nada.

   Cuando estos diez valores se cambien en el JavaScript, este bloque se
   puede borrar entero. */

/* Falta — terracota */
.agenda-chip[style*="#A32F32"] { background: var(--rojo-f) !important; color: var(--rojo); }
.leyenda i[style*="#A32F32"]   { background: var(--rojo-vivo) !important; border-color: var(--rojo-vivo) !important; }
.grafica svg rect[fill="#A32F32"] { fill: #B5654A; }

/* Retardo — oro */
.agenda-chip[style*="#97650F"] { background: var(--ambar-f) !important; color: var(--ambar); }
.leyenda i[style*="#97650F"]   { background: var(--acento) !important; border-color: var(--acento) !important; }
.grafica svg rect[fill="#97650F"] { fill: #C9A15C; }

/* Incidencia / justificada — índigo medio */
.agenda-chip[style*="#5A4B8C"] { background: var(--morado-f) !important; color: var(--morado); }
.leyenda i[style*="#5A4B8C"]   { background: var(--morado) !important; border-color: var(--morado) !important; }
.grafica svg rect[fill="#5A4B8C"] { fill: #4A4270; }

/* A tiempo / cierre — verde salvia */
.agenda-chip[style*="#2F7A5B"] { background: var(--verde-f) !important; color: var(--verde); }
.leyenda i[style*="#2F7A5B"]   { background: var(--verde-vivo) !important; border-color: var(--verde-vivo) !important; }
.grafica svg rect[fill="#2F7A5B"] { fill: #6F8F6A; }

/* Día festivo — índigo profundo */
.agenda-chip[style*="#0E6A9E"] { background: var(--primario-f) !important; color: var(--primario); }
.leyenda i[style*="#0E6A9E"]   { background: var(--primario) !important; border-color: var(--primario) !important; }

/* Día de pago — oro oscuro */
.agenda-chip[style*="#C77D19"] { background: var(--acento-f) !important; color: var(--acento-t); }
.leyenda i[style*="#C77D19"]   { background: var(--acento2) !important; border-color: var(--acento2) !important; }

/* Los puntitos de los doce meses y las rayas del detalle del día llevan el
   color en `color`/`border-color`, no en el fondo: ahí basta con recolorear. */
.agenda-mini-dia[style*="#A32F32"] { color: var(--rojo) !important; border-color: var(--rojo) !important; }
.agenda-mini-dia[style*="#97650F"] { color: var(--acento-t) !important; border-color: var(--acento) !important; }
.agenda-mini-dia[style*="#5A4B8C"] { color: var(--morado) !important; border-color: var(--morado) !important; }
.agenda-mini-dia[style*="#2F7A5B"] { color: var(--verde) !important; border-color: var(--verde) !important; }
.agenda-mini-dia[style*="#0E6A9E"] { color: var(--primario) !important; border-color: var(--primario) !important; }
.agenda-mini-dia[style*="#C77D19"] { color: var(--acento-t) !important; border-color: var(--acento2) !important; }

.agenda-marca i[style*="#A32F32"], .agenda-prox-fila i[style*="#A32F32"], .agenda-grupo h4 i[style*="#A32F32"] { background: var(--rojo-vivo) !important; border-color: var(--rojo-vivo) !important; }
.agenda-marca i[style*="#97650F"], .agenda-prox-fila i[style*="#97650F"], .agenda-grupo h4 i[style*="#97650F"] { background: var(--acento) !important; border-color: var(--acento) !important; }
.agenda-marca i[style*="#5A4B8C"], .agenda-prox-fila i[style*="#5A4B8C"], .agenda-grupo h4 i[style*="#5A4B8C"] { background: var(--morado) !important; border-color: var(--morado) !important; }
.agenda-marca i[style*="#2F7A5B"], .agenda-prox-fila i[style*="#2F7A5B"], .agenda-grupo h4 i[style*="#2F7A5B"] { background: var(--verde-vivo) !important; border-color: var(--verde-vivo) !important; }
.agenda-marca i[style*="#0E6A9E"], .agenda-prox-fila i[style*="#0E6A9E"], .agenda-grupo h4 i[style*="#0E6A9E"] { background: var(--primario) !important; border-color: var(--primario) !important; }
.agenda-marca i[style*="#C77D19"], .agenda-prox-fila i[style*="#C77D19"], .agenda-grupo h4 i[style*="#C77D19"] { background: var(--acento2) !important; border-color: var(--acento2) !important; }

/* La raya de las nueve horas extra y las barras de los rankings. */
.grafica svg line[stroke="#A32F32"] { stroke: #B5654A; }

/* ═══════════════════════════════════════════════════════════════════
   IMPRESIÓN — es como salen los PDF
   ═══════════════════════════════════════════════════════════════════
   Un reporte de asistencia es un documento que puede acabar en una
   revisión o en un juicio. El artículo 804 obliga al patrón a conservar
   y EXHIBIR los controles: lo que se exhibe tiene que decir de quién es,
   qué periodo abarca, cuándo se emitió y quién lo emitió. Sin eso es una
   captura de pantalla con números.

   El logotipo del membrete va como <img> y no como fondo: los
   navegadores traen apagada la impresión de fondos, así que un logotipo
   puesto con background-image sale en pantalla y no sale en el papel. */

@page { size: letter; margin: 13mm 11mm 12mm; }

.membrete, .membrete-pie { display: none; }

@media print {
  /* ── EL PAPEL SIEMPRE ES CLARO ─────────────────────────────────────
     Esto NO es cosmético. La hoja forzaba `background: #fff` al imprimir
     pero dejaba los colores del tema: quien tuviera el teléfono o la
     computadora en modo oscuro sacaba el PDF con papel blanco y la letra
     en #E9EEF1 —o sea, blanco sobre blanco—. El reporte salía en
     blanco y no había forma de darse cuenta hasta abrir el archivo.

     Por eso la paleta clara se vuelve a declarar aquí, y se declara con
     `!important` para ganarle a `:root[data-theme="dark"]`, que tiene la
     misma especificidad y va después en el archivo. Vale para las tres
     formas de acabar en oscuro: la del sistema, la elegida a mano, y la
     que hereda una ventana abierta. */
  :root, :root[data-theme="dark"] {
    --papel:#FFFFFF !important; --papel2:#FFFFFF !important; --tarjeta:#FFFFFF !important;
    --tarjeta2:#F5F1E9 !important;
    --linea:#ECE5D9 !important; --linea2:#DCD2C0 !important;
    --tinta:#241F3D !important; --tinta2:#4A4270 !important; --tinta3:#7E7797 !important;
    --marca:#241F3D !important; --primario:#4A4270 !important; --primario2:#241F3D !important;
    --primario-f:#ECE9F3 !important; --sobre-primario:#FFFFFF !important; --sobre-acento:#241F3D !important;
    --acento:#8A6A2E !important; --acento2:#8A6A2E !important; --acento-t:#8A6A2E !important;
    --acento-f:#F6EEDF !important;
    --verde:#3F5A3B !important; --verde-f:#E9EFE7 !important; --verde-vivo:#4F6B4B !important;
    --ambar:#7A5C24 !important; --ambar-f:#F6EEDF !important;
    --rojo:#7E3D2A !important; --rojo-f:#F6E8E2 !important; --rojo-vivo:#8F4832 !important;
    --morado:#4A4270 !important; --morado-f:#ECE9F3 !important;
    --sombra:none !important; --sombra-alta:none !important; --sombra-oro:none !important;
  }
  /* El fondo del papel es blanco liso: las manchas de color y el degradado
     son para la pantalla, y en una impresora sólo gastarían tinta. */
  body { color: #241F3D; background: #fff !important; }

  /* Fuera todo lo que se toca: en papel no sirve y roba espacio. */
  .lateral, .barra, .pestanas, .filtros, .btn, .cerrar, .no-imprimir,
  .sub-pestanas, .linea-agregar, .mapa, .titulo-vista { display: none !important; }
  /* El armazón deja de ser dos columnas: en papel no hay barra que poner al
     lado, y sin esto el contenido salía con el ancho de la columna derecha. */
  .armazon { display: block; }
  .principal { width: 100%; }

  html, body { background: #fff !important; }
  body { font-size: 10.5pt; line-height: 1.4; }
  .contenido { padding: 0; max-width: none; }

  /* ── El membrete ── */
  .membrete {
    display: flex; align-items: flex-start; gap: .8rem;
    padding-bottom: 8pt; margin-bottom: 12pt;
    border-bottom: 1.5pt solid #241F3D;
  }
  .membrete-logo { width: 46px; height: 46px; flex: none; }
  .membrete-quien { flex: 1; min-width: 0; }
  .membrete-quien b { display: block; font-family: Lora, Georgia, serif;
                      font-size: 13pt; line-height: 1.2; }
  .membrete-quien span { font-size: 8pt; color: #4A4270; }
  .membrete-doc { text-align: right; flex: none; max-width: 45%; }
  .membrete-doc b { display: block; font-size: 10.5pt; }
  .membrete-doc span { display: block; font-size: 8pt; color: #4A4270; }

  .membrete-pie {
    display: flex; justify-content: space-between; gap: 1rem;
    margin-top: 14pt; padding-top: 6pt; border-top: .75pt solid #CFCCC3;
    font-size: 7.5pt; color: #838D96;
  }

  /* ── Las cajas ── */
  .caja { box-shadow: none; border: .75pt solid #D8D5CE; border-radius: 4pt;
          padding: 8pt 9pt; margin-bottom: 9pt; break-inside: avoid; }
  .caja > h2 { font-size: 10.5pt; margin-bottom: 6pt; }
  .cifra { box-shadow: none; border: .75pt solid #D8D5CE; border-radius: 4pt; padding: 6pt 8pt; }
  .cifras { grid-template-columns: repeat(6, 1fr); gap: 5pt; margin-bottom: 10pt; }
  .cifra .val { font-size: 13pt; }
  .cifra .lab { font-size: 7pt; }

  /* ── Las tablas ── */
  /* Que el encabezado de columnas se repita en cada hoja: sin esto, de la
     segunda página en adelante hay columnas de números sin título y no se
     sabe cuál es cuál. */
  .tabla-envoltura { overflow: visible !important; margin: 0; padding: 0; }
  table.datos { font-size: 8.5pt; width: 100%; }
  table.datos thead { display: table-header-group; }
  table.datos tfoot { display: table-footer-group; }
  table.datos tr { break-inside: avoid; }
  table.datos th { font-size: 6.8pt; padding: 3pt 4pt; position: static;
                   border-bottom: .75pt solid #838D96; }
  table.datos td { padding: 3pt 4pt; border-bottom: .5pt solid #E2E0DA; }
  table.datos .num, table.datos .der { text-align: right; }

  /* ── EL COLOR EN EL PAPEL ──────────────────────────────────────────
     En blanco y negro, «A tiempo» y «Falta» se ven igual, y eso es justo lo
     que no puede pasar en un reporte de asistencia.

     El problema: los navegadores NO imprimen los fondos de color. Traen esa
     opción apagada, y en el iPhone ni siquiera se puede encender. Así que
     todo lo que dependía de `background` —las etiquetas de estado, los
     cuadritos de la leyenda, la raya de color de cada cifra, las barras de
     los rankings— salía en blanco. Se pedía con print-color-adjust y aun así
     no salía.

     La solución no es pedir el ajuste: es NO DEPENDER DEL FONDO. El texto y
     los BORDES sí se imprimen siempre. Por eso cada color se dibuja aquí con
     borde y con un cuadrito hecho de texto (■), que se pinta del color de la
     letra. Se pide el ajuste igual, por si acaso está encendido: entonces se
     ve el fondo además del borde. */
  .etiq, .cifra::before, .atender .fila, .ley .fila, .leyenda i, .barras .relleno {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }

  /* Las etiquetas de estado: cuadrito de color + borde + letra en negritas.
     El cuadrito es el carácter ■, que toma el color de la letra, y la letra
     ya viene del color que le toca a cada estado. */
  .etiq {
    border: .75pt solid currentColor; border-radius: 2pt;
    padding: .5pt 3pt; font-weight: 700; font-size: 7.5pt;
  }
  /* El cuadrito se hace con BORDE y no con el carácter ■: así no depende de
     que la fuente de impresión traiga ese símbolo, y toma el color de la
     letra, que es el del estado. */
  .etiq::before {
    content: ""; display: inline-block; vertical-align: middle;
    width: 0; height: 0; border: 2.75pt solid currentColor; border-radius: 1pt;
    margin-right: 3pt; position: relative; top: -.5pt;
  }

  /* La raya de color de cada tarjeta de cifra pasa a ser un borde. */
  .cifra { border-left-width: 2.5pt; border-left-style: solid; }
  .cifra::before { display: none; }
  .cifra.v { border-left-color: #4F6B4B; }
  .cifra.a { border-left-color: #8A6A2E; }
  .cifra.r { border-left-color: #8F4832; }
  .cifra.m { border-left-color: #4A4270; }
  .cifra.p { border-left-color: #241F3D; }

  /* Los cuadritos de la leyenda: una caja sin tamaño, hecha toda de borde.
     El color del borde se lo pone panel.js junto al del fondo. */
  .leyenda { font-size: 7.5pt; gap: .7rem; }
  .leyenda i { width: 0; height: 0; border-style: solid; border-width: 3.5pt;
               border-radius: 1pt; margin-right: 3pt; }

  /* Las barras de los rankings, lo mismo: la barra se dibuja con el borde. */
  .barras .riel { height: 0; border-top: 2.5pt solid #E2E0DA; overflow: visible; }
  .barras .relleno { height: 0; border-top: 2.5pt solid; background: none !important; }
  .barras .arriba { font-size: 8pt; }

  /* ── La ley y los avisos ── */
  .ley .fila, .atender .fila { break-inside: avoid; padding: 5pt 7pt; margin-bottom: 4pt; }
  .ley .art { font-size: 7pt; }
  .ley .det, .ley .fundamento { font-size: 8pt; }
  .nota { font-size: 7.5pt; }

  .grafica { padding: 4pt; break-inside: avoid; }
  .grafica svg { max-height: 120pt; }

  /* ── Cuando hay una ventana abierta se imprime SÓLO la ventana ── */
  /* El expediente de una persona vive en una ventana encima del panel. Sin
     esto, «Guardar como PDF» desde ahí sacaba las dos cosas encimadas y con
     el velo gris de fondo pintado sobre todo. */
  body.imprimiendo-ventana .contenido > section { display: none !important; }
  body.imprimiendo-ventana .velo[hidden] { display: none !important; }
  body.imprimiendo-ventana .velo {
    position: static !important; background: none !important; backdrop-filter: none !important;
    padding: 0 !important; display: block !important; overflow: visible !important;
  }
  body.imprimiendo-ventana .ventana {
    max-width: none !important; border: 0 !important; box-shadow: none !important;
    padding: 0 !important; background: #fff !important;
  }
  /* La cabecera de la ventana no se imprime: el membrete de arriba ya dice
     de quién es el expediente, y salía dos veces el mismo título. */
  body.imprimiendo-ventana .ventana .cabeza { display: none !important; }
  /* Las hojas de la ficha que están escondidas siguen escondidas: imprimir
     las siete pestañas de golpe daría catorce hojas que nadie pidió. */
  body.imprimiendo-ventana [data-hoja][hidden] { display: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   PIEZAS DE LA PANTALLA DE PERSONAL
   ═══════════════════════════════════════════════════════════════════ */

/* La marca en la barra: logotipo + nombre + empresa, todo en un enlace. */
.marca-logo { display: flex; align-items: center; gap: .6rem; text-decoration: none; color: inherit; }

/* El logotipo va como IMAGEN DE FONDO de un cuadro, no como <img>, para poder
   cambiarlo entre claro y oscuro sólo con CSS. Hacen falta las dos versiones:
   la huella del logotipo es NEGRA, así que sobre un fondo oscuro desaparecería;
   la otra la trae en blanco. El <a> que lo envuelve ya lleva su aria-label, por
   eso el cuadro va marcado como decorativo. */
.marca-icono {
  /* 34 px y no 30: el logotipo lleva las crestas de una huella, que a menos
     de eso se juntan y se ven como una mancha. Comprobado dibujándolo a 16,
     24, 30, 48 y 64 px, uno junto a otro. */
  flex: none; display: block; width: 34px; height: 34px;
  background: url('/marca.png') center / contain no-repeat;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .marca-icono { background-image: url('/marca-oscuro.png'); }
}
:root[data-theme="dark"] .marca-icono { background-image: url('/marca-oscuro.png'); }
.marca-logo b { display: block; font-family: "Familjen Grotesk", sans-serif; font-size: 1rem;
                font-weight: 700; letter-spacing: -.02em; line-height: 1.15; }
.marca-logo em { font-style: normal; }
.barra .quien { text-align: right; line-height: 1.25; }
.barra .quien b { font-size: .84rem; font-weight: 600; }
.barra .quien em { font-style: normal; display: block; }

/* Grupo de botones que se comportan como pestañas pequeñas: Activos /
   Histórico / Todos. Se lee como un solo control, no como tres botones. */
.grupo { display: inline-flex; border: 1px solid var(--linea2); border-radius: 99px; overflow: hidden; }
.grupo button {
  border: 0; background: var(--tarjeta); color: var(--tinta2); cursor: pointer;
  font: inherit; font-size: .82rem; font-weight: 600; padding: .34rem .8rem;
  border-right: 1px solid var(--linea);
}
.grupo button:last-child { border-right: 0; }
.grupo button:hover { background: var(--tarjeta2); color: var(--tinta); }
.grupo button.activa { background: var(--primario); color: var(--sobre-primario); }

/* Segundo renglón dentro de una celda: la CURP bajo el nombre, el número de
   empleado bajo el puesto. Va apagado para que no compita con el dato. */
.sub-celda { font-size: .72rem; color: var(--tinta3); margin-top: .1rem; }
.sub-titulo { font-family: "Familjen Grotesk", sans-serif; font-size: .92rem; font-weight: 600;
              margin: 1.4rem 0 .6rem; padding-bottom: .3rem; border-bottom: 1px solid var(--linea); }

/* Pestañas de dentro de la ficha. Se distinguen de las de arriba a propósito:
   son de otro nivel, y hacerlas iguales confunde sobre dónde está uno. */
.sub-pestanas {
  display: flex; gap: .25rem; flex-wrap: wrap;
  background: var(--tarjeta2); padding: .28rem; border-radius: 99px; margin-bottom: 1.1rem;
}
.sub-pestanas button {
  border: 0; background: none; color: var(--tinta2); cursor: pointer; font: inherit;
  font-size: .83rem; font-weight: 600; padding: .34rem .85rem; border-radius: 99px;
  transition: background .12s, color .12s;
}
.sub-pestanas button:hover { color: var(--tinta); }
.sub-pestanas button.activa { background: var(--tarjeta); color: var(--primario); box-shadow: var(--sombra); }

/* Aclaración pequeña junto al nombre de un campo: "18 caracteres", "sólo si es
   determinado". Cabe en la etiqueta y evita una nota más abajo. */
.pista { font-style: normal; font-weight: 400; color: var(--tinta3); font-size: .72rem; }

/* Casilla con su texto, alineados por el centro. Sirve igual suelta en un
   formulario que en la lista de documentos. */
.marca-linea {
  display: inline-flex; align-items: center; gap: .45rem; cursor: pointer;
  font-size: .85rem; color: var(--tinta2); margin: .2rem .9rem .2rem 0;
}
.marca-linea input[type=checkbox] { width: 15px; height: 15px; accent-color: var(--primario); flex: none; margin: 0; }
.marca-linea span { user-select: none; }

/* Los 15 documentos del artículo 804. Ya no son sólo casillas: cada uno lleva
   su archivo escaneado, así que el renglón necesita sitio para los adjuntos y
   para el botón de subir. Se deja en UNA columna a propósito —antes eran dos—:
   con los archivos dentro, dos columnas parten los nombres de archivo por la
   mitad y el renglón deja de leerse. */
.lista-docs { display: flex; flex-direction: column; gap: .15rem; }
.doc-fila {
  display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
  padding: .35rem .5rem; border-radius: var(--radio-s);
  border: 1px solid transparent;
}
.doc-fila:hover { background: var(--tarjeta2); }
.doc-fila .marca-linea { display: flex; flex: 1 1 15rem; min-width: 0; margin: 0; padding: 0; }
/* El que ya tiene archivo se distingue de un vistazo: la pregunta de esta
   pantalla es «qué falta», y lo que falta tiene que saltar. */
.doc-fila.con-archivo { background: color-mix(in srgb, var(--verde) 7%, transparent); }
.doc-fila.con-archivo .marca-linea span { color: var(--tinta); }
.doc-fila.con-archivo:hover { background: color-mix(in srgb, var(--verde) 11%, transparent); }

.doc-archivos { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.doc-chip {
  display: inline-flex; align-items: center; gap: .25rem;
  background: var(--tarjeta2); border: 1px solid var(--linea2);
  border-radius: 999px; padding: .1rem .2rem .1rem .55rem; font-size: .76rem;
  max-width: 28rem; gap: .35rem;
}
.doc-chip .doc-nombre {
  color: var(--tinta2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* «Ver» abre el archivo en otra pestaña. Es el paso que faltaba para poder
   comprobar que se subió el documento correcto: hasta ahora había que fiarse
   del nombre, y un nombre no dice qué trae adentro un escaneo. */
.doc-ver {
  flex: none; font-size: .72rem; font-weight: 600; text-decoration: none;
  color: var(--primario); padding: .1rem .4rem; border-radius: 999px;
  border: 1px solid var(--linea2); background: var(--tarjeta);
}
.doc-ver:hover { background: var(--primario); color: var(--tarjeta); border-color: var(--primario); }
.doc-quitar {
  border: 0; background: none; cursor: pointer; color: var(--tinta3);
  font-size: .8rem; line-height: 1; padding: .2rem .35rem; border-radius: 999px;
}
.doc-quitar:hover { color: var(--rojo); background: color-mix(in srgb, var(--rojo) 12%, transparent); }
/* El botón de subir es una etiqueta con el campo de archivo escondido dentro:
   el campo de archivo del navegador no se puede vestir, y sale distinto en cada
   uno. Así se ve como los demás botones de la aplicación. */
.doc-subir { cursor: pointer; }

/* Cuántos de los quince constan. Un número solo no dice si vas bien; la barra
   sí, y es lo primero que se mira al abrir el expediente. */
.docs-resumen { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
                font-size: .82rem; color: var(--tinta2); margin-bottom: .9rem; }
.docs-medida { flex: 1 1 12rem; max-width: 20rem; }
.docs-medida .riel { height: 7px; background: var(--tarjeta2); border: 1px solid var(--linea2);
                     border-radius: 999px; overflow: hidden; }
/* El color va de fondo Y de borde: los navegadores no imprimen fondos, y en el
   PDF del expediente esta barra tiene que seguir diciendo algo. */
.docs-medida .relleno { height: 100%; background: var(--verde); border: 1px solid var(--verde);
                        border-radius: 999px; transition: width .25s ease; }

/* Renglón para agregar algo al final de una lista. */
.linea-agregar { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap;
                 margin-top: .9rem; padding-top: .8rem; border-top: 1px dashed var(--linea2); }
.linea-agregar input[type=date], .linea-agregar select { width: auto; }

/* Pie de ventana: los botones siempre a la derecha y en el mismo orden —
   cancelar primero, la acción después. */
.pie-ventana { display: flex; gap: .5rem; justify-content: flex-end; margin-top: 1.2rem;
               padding-top: .9rem; border-top: 1px solid var(--linea); }
.entrada-ventana { font-size: .88rem; color: var(--tinta2); margin: 0 0 1rem; line-height: 1.55; }

/* La tabla del horario tiene que caber ENTERA en la ventana: si el boton de
   "copiar a los demas dias" se va al desplazamiento horizontal, nadie lo
   encuentra y hay que capturar siete veces lo mismo, que es donde se cuelan
   los dedazos que despues salen como retardos que nadie tuvo. */
.horario-tabla { table-layout: fixed; }
/* La hora se lee ENTERA o no sirve. En español el campo dice «10:30 a. m.», y
   con la columna estrecha se cortaba justo en el a. m. / p. m. —que es lo único
   que distingue entrar a las diez de la mañana de entrar a las diez de la
   noche—. Medido en el navegador: el campo pedia 116 px y tenia 96. */
.horario-tabla input[type=time] { width: 100%; min-width: 7.7rem; padding: .45rem .4rem; }
.horario-tabla td { padding: .3rem .25rem; }
/* La primera columna no necesita mas que «Miércoles»: se le fija el ancho para
   que lo que sobra se reparta entre las cuatro columnas de hora, en vez de
   repartirse a partes iguales con ellas. */
.horario-tabla th:first-child, .horario-tabla td:first-child {
  white-space: nowrap; width: 6.2rem; padding-right: .5rem;
}

/* La ficha es alta: la cabecera se queda fija para que el botón de guardar no
   se pierda al bajar por los sesenta campos. */
#velo-ficha .ventana .cabeza {
  position: sticky; top: -1.3rem; z-index: 2; margin: -1.3rem -1.4rem 1rem;
  padding: 1.1rem 1.4rem .8rem; background: var(--tarjeta);
  border-bottom: 1px solid var(--linea); border-radius: var(--radio) var(--radio) 0 0;
}

/* ═══════════════════════════════════════════════════════════════════
   EL MAPA DE LOS PLANTELES
   ═══════════════════════════════════════════════════════════════════
   El punto elegido es siempre el centro de la ventana, marcado con el
   alfiler. No hay nada que arrastrar más que el mapa mismo: un alfiler
   arrastrable en una pantalla táctil se confunde con el gesto de mover
   el mapa, y así se cambia el lugar del plantel sin querer. */
.mapa {
  position: relative; height: 20rem; border-radius: var(--radio-s);
  border: 1px solid var(--linea2); overflow: hidden;
  background: var(--tarjeta2); cursor: grab; touch-action: none;
  user-select: none;
}
.mapa.arrastrando { cursor: grabbing; }
.mapa-lienzo { position: absolute; inset: 0; }
.mapa-lienzo img { position: absolute; width: 256px; height: 256px; pointer-events: none; }
/* La zona permitida, dibujada a escala real sobre el mapa: se ve si el radio
   cubre el patio o si se está comiendo la calle de enfrente. */
.mapa-zona {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  border: 2px solid var(--acento);
  background: color-mix(in srgb, var(--acento) 16%, transparent);
  border-radius: 50%; pointer-events: none;
}
.mapa-cruz {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -100%);
  pointer-events: none; filter: drop-shadow(0 2px 3px rgba(0,0,0,.35));
}
.mapa-mandos { position: absolute; right: .5rem; top: .5rem; display: flex; flex-direction: column; gap: .25rem; }
.mapa-mandos button {
  width: 1.9rem; height: 1.9rem; border-radius: 7px; border: 1px solid var(--linea2);
  background: var(--tarjeta); color: var(--tinta); font-size: 1.1rem; font-weight: 600;
  line-height: 1; cursor: pointer; box-shadow: var(--sombra);
}
.mapa-mandos button:hover { background: var(--tarjeta2); }
.mapa-credito {
  position: absolute; right: 0; bottom: 0; font-size: .62rem; color: var(--tinta2);
  background: color-mix(in srgb, var(--tarjeta) 82%, transparent);
  padding: .1rem .35rem; border-radius: 5px 0 0 0;
}
.mapa-aviso {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  max-width: 22rem; text-align: center; font-size: .82rem; color: var(--tinta2);
  background: var(--tarjeta); border: 1px solid var(--linea2);
  border-radius: var(--radio-s); padding: .7rem .9rem; box-shadow: var(--sombra);
}

/* Ficha de un plantel dentro de la lista */
.plantel { display: flex; gap: 1rem; align-items: flex-start; padding: .85rem 0;
           border-bottom: 1px solid var(--linea); flex-wrap: wrap; }
.plantel:last-of-type { border-bottom: 0; }
.plantel .datos-plantel { flex: 1; min-width: 14rem; }
.plantel .nom { font-weight: 700; font-size: .93rem; }
.plantel .gente { font-size: .78rem; color: var(--tinta2); margin-top: .3rem; }
.plantel .acciones { display: flex; gap: .4rem; flex-wrap: wrap; }

/* ═══════════════════════════════════════════════════════════════════
   LA COMPARACIÓN ENTRE CENTROS DE TRABAJO
   ═══════════════════════════════════════════════════════════════════
   Una tabla contesta «cuánto»; esto contesta «cuál está peor», que es la
   pregunta con la que uno entra a esta pantalla. Por eso cada barra lleva
   encima la raya del promedio de la empresa: sin ella, cada porcentaje es
   un número suelto y hay que hacer la resta de cabeza para todos. */
.comparar { display: flex; flex-direction: column; gap: .45rem; margin: .2rem 0 1rem; }
.comparar-fila { display: flex; align-items: center; gap: .7rem; }
.comparar-fila.elegido { background: var(--tarjeta2); border-radius: var(--radio-s);
                         margin: 0 -.4rem; padding: .2rem .4rem; }
.comparar-nombre { flex: 0 0 11rem; min-width: 0; display: flex; align-items: baseline; gap: .4rem;
                   font-size: .82rem; }
.comparar-nombre a { color: var(--tinta); text-decoration: none; overflow: hidden;
                     text-overflow: ellipsis; white-space: nowrap; }
.comparar-nombre a:hover { color: var(--primario); text-decoration: underline; }
.comparar-nombre .cuantos { font-size: .72rem; color: var(--tinta3); flex: none; }
.comparar .riel { position: relative; flex: 1 1 auto; height: 15px; background: var(--tarjeta2);
                  border: 1px solid var(--linea2); border-radius: var(--radio-s); overflow: hidden; }
/* El color va de fondo Y de borde: los navegadores no imprimen fondos, y esta
   comparación es justo lo que se lleva impreso a una junta de directores. */
.comparar .relleno { height: 100%; border: 1px solid transparent; border-radius: var(--radio-s) 0 0 var(--radio-s); }
.comparar .relleno.bien  { background: var(--verde); border-color: var(--verde); }
.comparar .relleno.flojo { background: var(--ambar); border-color: var(--ambar); }
.comparar .relleno.mal   { background: var(--rojo);  border-color: var(--rojo); }
.comparar .raya-media { position: absolute; top: -2px; bottom: -2px; width: 0;
                        border-left: 2px dashed var(--tinta2); opacity: .85; }
.comparar-cifra { flex: 0 0 5.6rem; text-align: right; font-size: .84rem; font-weight: 700;
                  font-variant-numeric: tabular-nums; }
.comparar-cifra.bien  { color: var(--verde); }
.comparar-cifra.flojo { color: var(--ambar); }
.comparar-cifra.mal   { color: var(--rojo); }
.comparar-pie { font-size: .76rem; color: var(--tinta3); margin-top: .2rem; }

/* La diferencia contra el promedio. Va pegada al número, chiquita y en su
   color: el número dice cuánto, ésta dice si eso es bueno. */
.dif { font-size: .72rem; font-weight: 600; margin-left: .28rem; opacity: .9;
       font-variant-numeric: tabular-nums; }
.dif.bien { color: var(--verde); }
.dif.mal  { color: var(--rojo); }

/* El centro que se está viendo, señalado en la tabla de arriba. */
table.datos tr.resaltado > td { background: var(--tarjeta2); }
.caja.destacada { border-color: var(--primario); }

@media (max-width: 42rem) {
  .comparar-fila { flex-wrap: wrap; }
  .comparar-nombre { flex: 1 1 100%; }
  .comparar-cifra { flex: 0 0 4.6rem; }
}

/* Una aclaración chiquita dentro de una celda: «del horario» debajo de los
   minutos de comida. Sin ella, un descuento que nadie midió se ve igual que uno
   medido — y son cosas muy distintas cuando alguien reclama su pago. */
.pista-celda { font-size: .68rem; color: var(--tinta3); font-weight: 400; line-height: 1.2; }


/* ═══════════════════════════════════════════════════════════════════
   LAS GRÁFICAS
   ═══════════════════════════════════════════════════════════════════
   Se dibujan a la medida REAL de su caja, no en un lienzo inventado que
   luego se estira: estirar deforma el texto, y unos números anchos y
   aplastados se ven hechos a la carrera. Por eso aquí no hay ni un
   `preserveAspectRatio`.

   Los colores salen de las variables del tema, así que la gráfica sigue
   la paleta de cada cliente y el modo oscuro sin que nadie la toque. */
.grafica-caja { width: 100%; min-height: 230px; }
.grafica-svg { display: block; overflow: visible; }
/* Cuando no cabe —un celular con treinta días—, la gráfica se dibuja a su ancho
   y se desliza de lado, en vez de esconder las cifras. */
.grafica-caja.desliza { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; }
.g-desliza { font-size: .72rem; color: var(--tinta3); margin: .2rem 0 .1rem; }
@media print { .grafica-caja.desliza { overflow: visible; } .g-desliza { display: none; } }

/* La reja: horizontal, punteada y tenue. Es una referencia para leer una
   altura, no un dibujo. Las verticales sólo ensucian. */
.g-reja { stroke: var(--linea2); stroke-width: 1; stroke-dasharray: 2 4; opacity: .7; }
.g-base { stroke: var(--linea); stroke-width: 1.2; }
.g-eje { font-size: 9.5px; fill: var(--tinta3); font-variant-numeric: tabular-nums;
         letter-spacing: .01em; }
.g-eje-y { text-anchor: end; }
.g-eje-x { text-anchor: middle; }

/* La línea, fina y con las esquinas redondeadas. Gruesa taparía sus propios
   puntos, y los puntos son los que llevan el dato. */
.g-linea { fill: none; stroke-width: 2.2; stroke-linejoin: round; stroke-linecap: round; }
/* El halo: una copia borrosa debajo. Es lo que le da profundidad sin agregar
   un solo elemento más que leer. */
.g-halo-sombra { fill: none; stroke-width: 5; stroke-linejoin: round; stroke-linecap: round; }
.g-halo { display: none; }
.g-punto { stroke: var(--tarjeta); stroke-width: 1.8; }

/* La cifra, en una pastilla del color del papel: así se lee aunque caiga
   encima de la línea. Sin esto había que adivinar cuántos son de cada cosa. */
.g-chip-fondo { fill: var(--tarjeta); stroke-width: 1; opacity: .96; }
.g-chip-txt { font-size: 9.5px; font-weight: 700; text-anchor: middle;
              font-variant-numeric: tabular-nums; }

/* Las barras de pastilla: redondeadas por completo, como el ejemplo que pidió.
   Con pocas columnas se ven finas; con treinta serían un peine, y por eso las
   series largas van de línea. */
.g-pastilla { transition: opacity .15s ease; }
.g-pastilla:hover { opacity: .82; }
.g-raya-tope { stroke: var(--rojo); stroke-width: 1.2; stroke-dasharray: 5 4; opacity: .8; }
.g-raya-txt { font-size: 9px; fill: var(--rojo); text-anchor: start; }

/* El anillo que acompaña a una tarjeta. El fondo del anillo TIENE que verse:
   sin él no se sabe cuánto falta, y entonces el anillo no dice más que el
   número solo. */
/* El anillo va a la medida de la tarjeta, no al revés. Antes crecía hasta 190
   px y hacía la tarjeta el triple de alta que las de número. */
.grafica-anillo { display: flex; justify-content: center; }
.cifra.con-anillo { padding: .8rem .6rem; }
.cifra.con-anillo .grafica-anillo { width: 100%; }
.g-anillo-fondo { fill: none; stroke: var(--linea2); stroke-width: 9; opacity: .55; }
.g-anillo { fill: none; stroke-width: 9; stroke-linecap: round;
            transition: stroke-dasharray .5s cubic-bezier(.4, 0, .2, 1); }
.g-anillo-num { text-anchor: middle; font-size: 26px; font-weight: 700; fill: var(--tinta);
                font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.g-anillo-lab { text-anchor: middle; font-size: 9px; fill: var(--tinta3);
                text-transform: uppercase; letter-spacing: .1em; }

/* La leyenda lleva el TOTAL de cada serie: aunque las cifras del dibujo no
   quepan, «Faltas 12» siempre está a la vista. */
.leyenda .g-lab { display: inline-flex; align-items: center; gap: .3rem; }
.leyenda .g-lab b { font-variant-numeric: tabular-nums; }

/* Una tarjeta con su anillo al lado: la cifra grande a la izquierda y el
   anillo a la derecha, que es lo que la vuelve legible de un vistazo. */
.cifra-anillo { display: flex; align-items: center; gap: .9rem; }
.cifra-anillo .grafica-anillo { flex: none; width: 84px; }

@media print {
  /* En papel no hay fondo: la pastilla de la cifra se queda sin su relleno y
     se encimaría con la línea. Se le quita y se baja el tamaño. */
  .g-chip-fondo { display: none; }
  .g-chip-txt { font-size: 8.5px; }
  .g-halo-sombra { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   EL SALUDO Y LA CAMPANA
   ═══════════════════════════════════════════════════════════════════
   Quien entra quiere saber dos cosas antes que nada: que el sistema lo
   reconoció, y qué tiene que atender hoy. Lo segundo ya se calculaba y
   vivía al fondo de la pantalla, donde nadie baja a buscarlo un lunes a
   las siete de la mañana. */
.saludo { display: flex; align-items: flex-start; justify-content: space-between;
          gap: 1rem; margin-bottom: .2rem; }
.saludo-txt h1 { margin: 0; font-size: 1.5rem; letter-spacing: -.02em; }
.saludo-txt p { margin: .15rem 0 0; font-size: .84rem; color: var(--tinta3); }

.campana-caja { position: relative; flex: none; }
.campana {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--linea2); background: var(--tarjeta); color: var(--tinta2);
  cursor: pointer; transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.campana svg { width: 19px; height: 19px; }
.campana:hover { background: var(--tarjeta2); color: var(--tinta); border-color: var(--linea); }
/* El punto con el número. Rojo sólo cuando hay algo GRAVE: si todo se pinta de
   rojo, el rojo deja de querer decir algo. */
.campana-punto {
  position: absolute; top: -3px; right: -3px; min-width: 17px; height: 17px;
  padding: 0 4px; border-radius: 999px; background: var(--ambar); color: #fff;
  font-size: .64rem; font-weight: 700; line-height: 17px; text-align: center;
  border: 2px solid var(--papel); font-variant-numeric: tabular-nums;
}
.campana.con-grave .campana-punto { background: var(--rojo); }

.campana-panel {
  position: absolute; right: 0; top: 46px; z-index: 30; width: min(26rem, 84vw);
  background: var(--tarjeta); border: 1px solid var(--linea2);
  border-radius: var(--radio); box-shadow: var(--sombra-alta, 0 12px 32px rgba(36, 31, 61, .16));
  overflow: hidden;
}
.campana-cabeza { font-size: .7rem; text-transform: uppercase; letter-spacing: .1em;
                  color: var(--tinta3); padding: .7rem .9rem .45rem; }
.campana-fila {
  display: block; width: 100%; text-align: left; border: 0; background: none; cursor: pointer;
  padding: .55rem .9rem .6rem; border-top: 1px solid var(--linea);
  border-left: 3px solid var(--ambar);
}
.campana-fila.grave { border-left-color: var(--rojo); }
.campana-fila:hover { background: var(--tarjeta2); }
.campana-fila .tit { display: block; font-size: .84rem; font-weight: 600; color: var(--tinta); }
.campana-fila .det { display: block; font-size: .76rem; color: var(--tinta3); margin-top: .1rem; }
.campana-vacia { padding: .3rem .9rem 1rem; font-size: .82rem; color: var(--verde); }

@media (max-width: 34rem) {
  .campana-panel { position: fixed; left: .6rem; right: .6rem; width: auto; top: auto; }
}

/* Un aviso ya revisado: sigue a la vista pero apagado, y no cuenta en la
   campana. No se borra a propósito — que desaparezca al tocarlo haría dudar
   de si de verdad se atendió o si se perdió. */
.campana-fila.revisado { opacity: .55; }
.campana-fila.revisado .tit em { font-style: normal; font-weight: 400; color: var(--tinta3);
                                 font-size: .74rem; }

/* ── Importar personal desde una hoja ─────────────────────────────────
   La zona donde se suelta el archivo. Se ve como un hueco que pide algo,
   no como un botón más: la acción es arrastrar, y eso hay que insinuarlo
   con la forma, no explicarlo con una instrucción. */
.soltar { border: 2px dashed var(--linea2); border-radius: var(--radio); padding: 1.6rem 1rem;
          text-align: center; background: var(--tarjeta2); transition: border-color .15s, background .15s; }
.soltar.encima { border-color: var(--acento2); background: var(--acento-f); }
.soltar p { margin: .2rem 0; }
.titulo-bloque { font-family: var(--serif); font-size: 1rem; font-weight: 600;
                 margin: 1.1rem 0 .3rem; }
/* El renglón que no va a entrar se marca con COLOR Y CON TEXTO. Sólo con
   color, quien no distingue rojo de verde no ve cuál es el problema — y
   además el color no sobrevive a una impresión. */
.imp-fila.rechazado { background: var(--rojo-f); }
.imp-fila.actualizar { background: var(--ambar-f); }
.imp-por-que { font-size: .74rem; color: var(--rojo); }
.imp-aviso   { font-size: .74rem; color: var(--ambar); }

/* ── Selección de personal ────────────────────────────────────────────
   El embudo, las tarjetas de vacante, los renglones de estudios y
   empleos, y la lista de papeles del candidato. */

/* Dos cajas lado a lado que se apilan solas en pantalla angosta. */
.rejilla2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); gap: .8rem; }

/* El embudo. Barras proporcionales al paso más grande, no a la suma: lo que
   se quiere ver de un vistazo es DÓNDE se atoran los candidatos. */
.sel-embudo { display: flex; flex-direction: column; gap: .35rem; }
.sel-paso { display: flex; align-items: center; gap: .6rem; }
.sel-paso-nom { flex: 0 0 10.5rem; font-size: .82rem; color: var(--tinta2); }
.sel-paso-barra { flex: 1; height: 18px; background: var(--tarjeta2); border-radius: 5px; overflow: hidden; }
.sel-paso-barra i { display: block; height: 100%; border-radius: 5px; min-width: 2px; transition: width .25s; }
.sel-paso-barra i.gris   { background: var(--tinta3); }
.sel-paso-barra i.azul   { background: var(--primario); }
.sel-paso-barra i.morado { background: var(--morado); }
.sel-paso-barra i.ambar  { background: var(--ambar); }
.sel-paso-barra i.verde  { background: var(--verde); }
.sel-paso-barra i.rojo   { background: var(--rojo); }
.sel-paso-n { flex: 0 0 2.4rem; text-align: right; font-variant-numeric: tabular-nums; }
@media (max-width: 640px) { .sel-paso-nom { flex-basis: 7rem; font-size: .74rem; } }

.sel-vacante h2 { font-size: 1.02rem; }

/* Un estudio o un empleo. Se pinta como bloque y no como renglón de tabla
   porque en el celular una tabla de siete columnas no se lee. */
.sel-renglon {
  border: 1px solid var(--linea); border-radius: 10px;
  padding: .6rem .7rem; margin-bottom: .5rem; background: var(--tarjeta2);
}
.sel-renglon .rejilla { margin-bottom: .4rem; }

/* Los papeles del candidato. */
.sel-doc {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .5rem 0; border-bottom: 1px solid var(--linea);
}
.sel-doc-nom { flex: 0 0 15rem; font-size: .85rem; font-weight: 600; }
.sel-doc-lista { flex: 1; display: flex; gap: .4rem; flex-wrap: wrap; min-width: 8rem; }
.sel-archivo {
  display: inline-flex; align-items: center; gap: .25rem;
  background: var(--tarjeta2); border-radius: 99px; padding: .1rem .3rem .1rem .6rem;
  font-size: .76rem; max-width: 100%;
}
.sel-archivo a { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 12rem; }
@media (max-width: 640px) { .sel-doc-nom { flex-basis: 100%; } }

/* Las notas de una entrevista. */
.sel-nota {
  margin-top: .5rem; padding: .5rem .65rem; border-radius: 8px;
  background: var(--tarjeta2); font-size: .82rem; line-height: 1.45;
}

/* Las competencias que pide un puesto. */
.sel-comps { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: .4rem; }
.sel-comp {
  display: flex; align-items: center; gap: .5rem; cursor: pointer;
  border: 1px solid var(--linea); border-radius: 9px; padding: .4rem .55rem;
  background: var(--tarjeta);
}
.sel-comp:has(input:checked) { border-color: var(--acento); }
.sel-comp span { flex: 1; font-size: .82rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.sel-comp select { flex: 0 0 6.2rem; font-size: .76rem; }
.sel-comp input { accent-color: var(--acento); }

/* ── Contestar una prueba psicométrica ────────────────────────────────
   Ciento ochenta y siete preguntas se contestan bien o se contestan mal
   según cómo estén puestas en la pantalla: renglones anchos, número a la
   izquierda siempre visible, y las opciones donde caiga el pulgar. */
.psi-ventana { max-width: 62rem; width: 100%; }

.psi-reloj {
  font-family: "IBM Plex Mono", monospace; font-size: 1.15rem; font-weight: 700;
  background: var(--tarjeta2); border-radius: 8px; padding: .25rem .6rem;
  font-variant-numeric: tabular-nums;
}
.psi-reloj.apurado { background: var(--rojo-f); color: var(--rojo); }

.psi-lista { display: flex; flex-direction: column; gap: .1rem; }
.psi-item {
  display: flex; gap: .7rem; padding: .7rem .2rem;
  border-bottom: 1px solid var(--linea);
}
.psi-item:hover { background: var(--tarjeta2); }
.psi-item.psi-falta { background: var(--rojo-f); border-radius: 8px; }
.psi-n {
  flex: 0 0 2rem; text-align: right; font-variant-numeric: tabular-nums;
  color: var(--tinta3); font-size: .8rem; padding-top: .1rem;
}
.psi-cuerpo-item { flex: 1; min-width: 0; }
.psi-texto { font-size: .88rem; line-height: 1.45; margin-bottom: .4rem; }
.psi-texto:empty { display: none; }

.psi-ops { display: flex; gap: .4rem; flex-wrap: wrap; }
.psi-ops-col { flex-direction: column; gap: .25rem; }
.psi-op {
  display: flex; align-items: center; gap: .4rem; cursor: pointer;
  border: 1px solid var(--linea); border-radius: 8px; padding: .3rem .55rem;
  font-size: .82rem; background: var(--tarjeta);
}
.psi-op:hover { border-color: var(--linea2); }
.psi-op:has(input:checked) { border-color: var(--acento); background: var(--acento-f); }
.psi-op input { accent-color: var(--acento); flex: none; }
.psi-mono { font-family: "IBM Plex Mono", monospace; }
.psi-img { max-width: 100%; border-radius: 8px; margin-bottom: .4rem; }
.psi-abierta { max-width: 16rem; }
.psi-dos { display: flex; gap: .5rem; }
.psi-orden { display: flex; gap: .4rem; flex-wrap: wrap; }
.campo.chico { max-width: 9rem; }
.campo.chico input { padding: .25rem .4rem; font-size: .82rem; }

/* Las fichas de dominó: tarjetas, no renglones. */
.psi-rejilla-domino { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: .7rem; }
.psi-domino {
  border: 1px solid var(--linea); border-radius: 12px; padding: .6rem; background: var(--tarjeta);
}
.psi-domino img { width: 100%; border-radius: 8px; background: #fff; }
.psi-domino .psi-n { text-align: left; }

/* Cleaver: cuatro columnas de seis grupos. */
.psi-cleaver { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: .8rem; }
.psi-cl-titulo { font-weight: 700; font-size: .82rem; margin-bottom: .3rem; color: var(--tinta2); }
.psi-cl-grupo {
  border: 1px solid var(--linea); border-radius: 10px; padding: .4rem .5rem; margin-bottom: .5rem;
  background: var(--tarjeta);
}
.psi-cl-grupo.psi-falta { border-color: var(--rojo); background: var(--rojo-f); }
.psi-cl-fila { display: flex; align-items: center; gap: .35rem; padding: .12rem 0; }
.psi-cl-marca { display: flex; align-items: center; gap: .15rem; cursor: pointer; font-size: .7rem;
                color: var(--tinta3); }
.psi-cl-marca input { accent-color: var(--acento); margin: 0; }
.psi-cl-palabra { font-size: .82rem; flex: 1; }

/* Los que se ordenan por jerarquía: LIFO, Spranger, Hermann, ZAVIC. */
.psi-bloque {
  border: 1px solid var(--linea); border-radius: 12px; padding: .7rem .8rem; margin-bottom: .6rem;
  background: var(--tarjeta);
}
.psi-bloque.psi-falta { border-color: var(--rojo); }
.psi-bloque-titulo { font-weight: 600; font-size: .86rem; margin-bottom: .4rem; }
.psi-jer { display: flex; align-items: center; gap: .5rem; padding: .18rem 0; font-size: .84rem; }
.psi-jer select { flex: 0 0 4.2rem; }

.psi-cuenta {
  margin-right: auto; font-size: .82rem; color: var(--tinta3);
  font-variant-numeric: tabular-nums;
}
.psi-cuenta.completo { color: var(--verde); font-weight: 600; }

/* El resultado: barras comparables entre sí, con su etiqueta. */
.psi-barras { display: flex; flex-direction: column; gap: .3rem; }
.psi-barra { display: flex; align-items: center; gap: .5rem; font-size: .82rem; }
.psi-barra-nom { flex: 0 0 12rem; color: var(--tinta2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.psi-barra-caja { flex: 1; height: 14px; background: var(--tarjeta2); border-radius: 4px; overflow: hidden; min-width: 3rem; }
.psi-barra-caja i { display: block; height: 100%; background: var(--acento); border-radius: 4px; }
.psi-barra-n { flex: 0 0 3rem; text-align: right; font-variant-numeric: tabular-nums; }
.psi-barra-etq { flex: 0 0 9rem; font-size: .74rem; color: var(--tinta3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 700px) {
  .psi-barra-nom { flex-basis: 7rem; }
  .psi-barra-etq { display: none; }
  .psi-n { flex-basis: 1.6rem; }
}

/* Los párrafos de un informe psicométrico traen saltos de línea propios del
   instrumento; se respetan, que para eso los escribió quien lo redactó. */
.psi-parrafo { white-space: pre-wrap; font-size: .84rem; line-height: 1.5; margin: .2rem 0 0; }

/* ── La pantalla del candidato ────────────────────────────────────────
   Se abre casi siempre en un teléfono, con una liga, por alguien que no
   conoce la plataforma. Todo lo que se pueda quitar, se quita: no hay barra
   lateral, ni pestañas, ni nada que tocar por error. */
body.hoja-prueba {
  background: var(--fondo); color: var(--tinta);
  display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh;
}
.pr-cabeza {
  display: flex; align-items: center; gap: .7rem;
  padding: .7rem 1rem; background: var(--tarjeta);
  border-bottom: 1px solid var(--linea); position: sticky; top: 0; z-index: 5;
}
.pr-logo { height: 34px; width: auto; border-radius: 6px; }
.pr-quien { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.pr-quien b { font-size: .92rem; }
.pr-quien span { font-size: .76rem; color: var(--tinta3); }
.pr-hoja { flex: 1; width: 100%; max-width: 46rem; margin: 0 auto; padding: 1rem 1rem 6rem; }
.pr-intro h2 { margin-top: 0; }
.pr-centro { text-align: center; padding: 2rem 1.2rem; }
.pr-centro h2 { margin-top: 0; }
.pr-pie {
  position: sticky; bottom: 0; display: flex; align-items: center; gap: .7rem;
  padding: .7rem 1rem calc(.7rem + env(safe-area-inset-bottom));
  background: var(--tarjeta); border-top: 1px solid var(--linea);
}
.pr-guardado { font-size: .74rem; color: var(--tinta3); }
.pr-codigo {
  font-family: "IBM Plex Mono", monospace; font-size: 1.9rem; font-weight: 700;
  letter-spacing: .18em; margin: .6rem 0; color: var(--acento);
}
.btn.grande { font-size: 1rem; padding: .6rem 1.4rem; margin-top: .8rem; }

/* El código corto de una prueba, dentro del panel. */
.psi-codigo-chico {
  font-family: "IBM Plex Mono", monospace; font-size: 1.4rem; font-weight: 700;
  letter-spacing: .14em; margin: 0 0 .2rem;
}

/* Un bloque donde se repitió un número. Se marca mientras se contesta, no al
   final: corregirlo con la pregunta a la vista cuesta un segundo; encontrarlo
   después, entre setenta y dos renglones, es donde la gente se rinde. */
.psi-bloque.psi-repetido { border-color: var(--ambar); background: var(--ambar-f); }
.psi-bloque.psi-repetido .psi-bloque-titulo::after {
  content: " · hay un número repetido"; color: var(--ambar); font-weight: 600;
}

/* Wonderlic: acomodar palabras con flechas, y el peso de las de dinero. */
.psi-orden { display: flex; flex-wrap: wrap; gap: .35rem; }
.psi-palabra {
  display: inline-flex; align-items: center; gap: .1rem;
  background: var(--tarjeta2); border: 1px solid var(--linea);
  border-radius: 8px; padding: .18rem .3rem; font-size: .84rem;
}
.psi-flecha {
  border: 0; background: none; cursor: pointer; padding: 0 .15rem;
  color: var(--acento); font-size: .9rem; line-height: 1;
}
.psi-flecha[disabled] { color: var(--linea2); cursor: default; }
.psi-dinero { display: flex; align-items: center; gap: .3rem; }
.psi-dinero span { font-weight: 700; }
.psi-dinero input { max-width: 9rem; }

/* ── El informe de una prueba psicométrica ───────────────────────────── */
/* Lo mismo que enseña la aplicación de escritorio: cifras, perfil, y el
   texto que explica cada puntaje. El texto es lo que el cliente lee. */
.psi-informe-titulo { font-size: 1rem; margin: 0 0 .6rem; }
.psi-fila { padding: .5rem 0; border-bottom: 1px solid var(--linea); }
.psi-fila:last-child { border-bottom: 0; }
.psi-fila-suelta { border-bottom: 0; padding-top: .2rem; }
.psi-fila-cab { display: flex; align-items: baseline; gap: .6rem; }
.psi-fila-nom { flex: 1; font-weight: 600; font-size: .86rem; }
.psi-fila-cifra { font-size: 1rem; color: var(--acento); white-space: nowrap; font-variant-numeric: tabular-nums; }
.psi-fila .psi-barra-caja { display: block; margin-top: .3rem; height: 8px; }
.psi-nivel {
  display: inline-block; margin-top: .35rem; padding: .1rem .45rem;
  border: 1px solid var(--linea2); border-radius: 999px;
  font-size: .72rem; color: var(--tinta2); background: var(--tarjeta2);
}
.psi-sub {
  display: flex; justify-content: space-between; gap: .8rem;
  font-size: .78rem; color: var(--tinta2);
  padding: .12rem 0 .12rem .7rem; border-left: 2px solid var(--linea2); margin-top: .2rem;
}
.psi-pie { margin-top: .6rem; }

/* La gráfica de perfil. Se dibuja a mano —sin librerías— con la misma serie,
   el mismo eje y la misma banda de promedio que la aplicación. */
.psi-grafica { display: block; width: 100%; height: auto; margin-top: .4rem; }
.psi-g-linea { stroke: var(--linea2); stroke-width: 1; }
.psi-g-banda { fill: var(--verde); opacity: .18; }
.psi-g-linea-datos { fill: none; stroke: var(--tinta); stroke-width: 2; }
.psi-g-punto { fill: var(--acento); stroke: var(--tinta); stroke-width: 1.5; }
.psi-g-eje { font-size: 10px; fill: var(--tinta3); }
.psi-g-etq { font-size: 11px; font-weight: 600; fill: var(--tinta2); }

/* ── Cleaver: sus tres gráficas lado a lado, y lo que se elige ───────── */
.psi-cab-accion { display: flex; justify-content: space-between; align-items: center; gap: .6rem; flex-wrap: wrap; }
.psi-cab-accion h2 { margin: 0; }
.psi-graficas-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: .6rem; margin-top: .4rem; }
.psi-graficas-3 .caja { margin: 0; box-shadow: none; }
.psi-mm { align-items: center; margin-bottom: .5rem; }
.psi-mm select { width: auto; min-width: 4.2rem; }
.psi-adjetivos { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: .8rem; }

/* ── La grabación de una entrevista ───────────────────────────────────
   Una sola caja con lo que toca según cómo vaya: grabar o subir, escuchar,
   y cómo va la transcripción. Los colores salen de las variables de la
   paleta, así que siguen la marca de cada cliente y el modo oscuro. */
.aud-caja { border-top: 1px solid var(--linea); margin-top: 1rem; padding-top: .4rem; }
.aud-acciones { display: flex; gap: .45rem; flex-wrap: wrap; align-items: center; margin: .5rem 0; }
.aud-estado { font-size: .78rem; color: var(--tinta3); flex: 1; min-width: 12rem; }
.aud-linea { font-size: .84rem; color: var(--tinta2); margin: .35rem 0; }
.aud-linea.bueno { color: var(--verde); font-weight: 600; }
.aud-consentimiento { display: flex; gap: .5rem; align-items: flex-start; font-size: .86rem; margin: .4rem 0 .5rem; cursor: pointer; }
.aud-consentimiento input { margin-top: .2rem; accent-color: var(--acento); flex: none; }
.aud-modos { display: flex; gap: .4rem 1.1rem; flex-wrap: wrap; font-size: .82rem; margin-bottom: .3rem; }
.aud-modos label { display: flex; gap: .35rem; align-items: center; cursor: pointer; }
.aud-grabando { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; font-size: .9rem; margin: .5rem 0; font-variant-numeric: tabular-nums; }
.aud-grabando strong { font-family: "IBM Plex Mono", monospace; font-size: 1.05rem; }
.aud-punto { width: .7rem; height: .7rem; border-radius: 50%; background: var(--rojo); flex: none; animation: aud-latido 1.2s ease-in-out infinite; }
@keyframes aud-latido { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .aud-punto { animation: none; } }
.aud-barra { height: .45rem; border-radius: 99px; background: var(--tarjeta2); border: 1px solid var(--linea); overflow: hidden; margin: .35rem 0 .2rem; }
.aud-barra > div { height: 100%; background: var(--acento); border-radius: 99px; transition: width .4s ease; }
.aud-reproductor { width: 100%; max-width: 100%; margin: .4rem 0 .15rem; }
.aud-meta { font-size: .76rem; color: var(--tinta3); overflow-wrap: anywhere; }
.aud-trans { margin: .5rem 0; }
/* Los avisos de «ya quedó», abajo a la izquierda: en el hueco junto a la
   ventana abierta, nunca encima de sus botones (lo acomoda audAcomodarAvisos). */
.aud-avisos { position: fixed; left: 1rem; bottom: 1rem; z-index: 1000; display: flex; flex-direction: column; gap: .5rem; max-width: min(22rem, calc(100vw - 2rem)); }
.aud-avisos[hidden] { display: none; }
.aud-aviso-flotante { display: flex; align-items: center; gap: .6rem; background: var(--tarjeta); border: 1px solid var(--linea); border-left: 4px solid var(--verde); border-radius: var(--radio-s); padding: .6rem .7rem; box-shadow: 0 8px 24px rgba(0, 0, 0, .14); }
.aud-aviso-flotante.malo { border-left-color: var(--rojo); }
.aud-aviso-texto { flex: 1; min-width: 0; font-size: .82rem; }
.aud-aviso-texto strong { display: block; font-size: .86rem; }
.aud-aviso-texto span { display: block; color: var(--tinta3); overflow-wrap: anywhere; }
/* En la lista del prospecto: el texto largo va plegado. */
.aud-plegable { margin-top: .5rem; }
.aud-plegable summary { cursor: pointer; font-size: .82rem; font-weight: 600; color: var(--tinta2); }
.aud-plegable .sel-nota { white-space: pre-wrap; max-height: 22rem; overflow: auto; }
@media print { .aud-avisos, .aud-acciones, .aud-reproductor { display: none; } .aud-plegable .sel-nota { max-height: none; } }

/* ── Manuales de procesos y procedimientos (publico/manuales.js) ─────── */
.mnl-area { font-size: .92rem; margin: 1.1rem 0 .45rem; display: flex; align-items: center; gap: .5rem; }
.mnl-filtro { margin-bottom: .2rem; }
.mnl-acciones { white-space: nowrap; text-align: right; }
#mnl-caja td.num { white-space: nowrap; }
.mnl-acciones .btn + .btn { margin-left: .35rem; }
.mnl-opcion { display: flex; align-items: center; gap: .55rem; margin: .5rem 0; font-size: .9rem; cursor: pointer; }
.mnl-b-lista { width: 100%; margin: .15rem 0 0; }
/* El visor ocupa casi toda la pantalla y su barra se queda arriba al bajar. */
/* La barra de desplazamiento del visor va SIEMPRE: si aparece hasta que se
   arman las hojas, el ancho que se midió para «ajustar» ya no es el real y la
   hoja se sale unos píxeles. Y la ventana NO lleva overflow:hidden: con él, la
   barra de controles deja de quedarse fija y se va con la primera hoja
   (lo destapó revisar con clics, 15-sep-2026). */
.mnl-velo-visor { padding: .8rem; overflow-y: scroll; }
.ventana.mnl-visor { max-width: none; padding: 0; background: var(--tarjeta2); }
/* top negativo del mismo tamaño que el relleno del velo: pegada al borde, sin
   que se asome por encima una franja de la hoja anterior. */
.mnl-visor-cabeza { position: sticky; top: -.8rem; z-index: 2; margin: 0; padding: .6rem .9rem; flex-wrap: wrap; gap: .5rem .8rem;
  background: var(--tarjeta); border-bottom: 1px solid var(--linea); border-radius: var(--radio) var(--radio) 0 0; }
.mnl-visor-cabeza h2 { min-width: 10rem; overflow-wrap: anywhere; }
.mnl-visor-controles { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.mnl-v-hoja { font-size: .82rem; color: var(--tinta3); display: inline-flex; align-items: center; gap: .3rem; margin: 0 .3rem; }
.mnl-v-hoja input { width: 4.4rem; padding: .2rem .35rem; }
#mnl-v-aviso .aviso { margin: .9rem; }
/* Una hoja más ancha que la pantalla se desliza de lado sin cortarse por la
   izquierda: por eso margen automático y no «centrar» del contenedor. */
.mnl-hojas { display: flex; flex-direction: column; align-items: flex-start; gap: .8rem; padding: .9rem .6rem 1.6rem; overflow-x: auto; }
.mnl-hoja { position: relative; flex: none; margin-inline: auto;
  background: #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, .18); }
.mnl-hoja canvas { display: block; }
.mnl-hoja-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: #8a949a; font-size: .9rem; padding: 1rem; text-align: center; }
.mnl-hoja[data-mnl-dibujada] .mnl-hoja-num { display: none; }
.mnl-hoja-mal { color: var(--rojo); }
@media (max-width: 40rem) {
  .mnl-velo-visor { padding: 0; }
  .ventana.mnl-visor { border-radius: 0; min-height: 100%; }
  /* En el celular la barra va en dos renglones —título y ✕ arriba, controles
     abajo—: medida a 375 px, sin esto se partía en cuatro y tapaba 166 px de
     pantalla. El selector lleva .ventana para ganarle a «.ventana .cabeza». */
  .ventana .mnl-visor-cabeza { display: grid; grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "titulo cerrar" "controles controles"; gap: .35rem .5rem;
    padding: .45rem .6rem; top: 0; border-radius: 0; }
  .ventana .mnl-visor-cabeza h2 { grid-area: titulo; min-width: 0; font-size: .95rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .mnl-visor-cabeza #mnl-v-cerrar { grid-area: cerrar; }
  .mnl-visor-controles { grid-area: controles; gap: .3rem; }
  /* Medido a 375 px: a «Descargar…» (92 px) le faltaban 20 px para caber en
     el mismo renglón que los demás controles. */
  .mnl-visor-controles .btn.chico { padding-inline: .5rem; }
  .mnl-v-hoja { margin: 0; gap: .25rem; }
  .mnl-v-hoja input { width: 2.9rem; }
  .mnl-hojas { padding: .6rem .3rem 1.2rem; }
}
@media print { .mnl-acciones, #mnl-nuevo, .mnl-filtro { display: none; } }

/* ── La página pública de una vacante (postulaciones.js) ──────────────
   La abre quien vio la vacante compartida, casi siempre en su teléfono. Usa
   la cabecera de la liga de la prueba (.pr-*) y los campos del panel (.campo). */
.pv-hoja { padding-bottom: 3rem; }
.pv-vacante h1 { font-family: var(--serif); font-size: clamp(1.6rem, 5vw, 2.2rem); line-height: 1.15;
  margin: .6rem 0 .9rem; }
.pv-vacante section h2 { font-size: 1rem; margin: 1.2rem 0 .4rem; }
.pv-vacante p { margin: 0 0 .7rem; line-height: 1.6; color: var(--tinta2); overflow-wrap: anywhere; }
.pv-datos { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: .5rem; margin: 0 0 .6rem; }
.pv-datos div { background: var(--tarjeta); border: 1px solid var(--linea); border-radius: var(--radio-s);
  padding: .45rem .7rem; }
.pv-datos dt { font-size: .7rem; color: var(--tinta3); text-transform: uppercase; letter-spacing: .04em; }
.pv-datos dd { margin: .1rem 0 0; font-weight: 600; font-size: .9rem; overflow-wrap: anywhere; }
.pv-form, .pv-cerrada, .pv-listo { margin-top: 1.4rem; }
.pv-form h2 { margin-top: 0; }
.pv-cerrada { text-align: center; }
/* La trampa para robots: fuera de la vista, sin robarle el foco a nadie. */
.pv-trampa { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.pv-casilla { display: flex; gap: .55rem; align-items: flex-start; font-size: .88rem; line-height: 1.45;
  margin: .75rem 0; cursor: pointer; }
.pv-casilla input { margin-top: .2rem; width: 1.1rem; height: 1.1rem; flex: none; }
.pv-extra { align-items: end; }
.pv-mal input, .pv-mal select, .pv-mal textarea { border-color: var(--rojo); box-shadow: 0 0 0 3px var(--rojo-f); }
.pv-casilla.pv-mal { color: var(--rojo); }
/* Los campos de la página pública, medidos a 375 px con clics. El teléfono y los
   meses no estaban entre los que viste la hoja general. Van a 16 px: con menos, el
   iPhone agranda la página al tocar un campo y no la regresa. Y ninguno —tampoco
   el de archivo, que el navegador no deja encoger y ensanchaba su columna— se sale
   de la pantalla. Todo con .hoja-vacante delante: el panel no cambia. */
.hoja-vacante input[type=tel], .hoja-vacante input[type=month] {
  width: 100%; padding: .58rem .75rem; border: 1px solid var(--linea2); border-radius: var(--radio-s);
  background: var(--tarjeta); color: var(--tinta); }
.hoja-vacante .pv-form input:not([type=checkbox]):not([type=file]), .hoja-vacante .pv-form select,
.hoja-vacante .pv-form textarea { font-size: 16px; max-width: 100%; }
.hoja-vacante .pv-form .rejilla > * { min-width: 0; }
.hoja-vacante .pv-form input[type=file] { display: block; width: 100%; max-width: 100%; font-size: .85rem; }
.pv-progreso { height: .5rem; border-radius: 99px; background: var(--tarjeta2); overflow: hidden; margin: .8rem 0 .4rem; }
.pv-progreso i { display: block; height: 100%; width: 0; background: var(--acento); transition: width .2s; }

/* ── Publicar vacantes y revisar postulaciones, dentro del panel ─────── */
[data-vista="sel-prospectos"] { position: relative; }
.pest-cuenta { position: absolute; top: .2rem; right: .3rem; min-width: 1.15rem; height: 1.15rem; padding: 0 .3rem;
  border-radius: 99px; background: var(--rojo); color: #fff; font-size: .66rem; font-weight: 700;
  line-height: 1.15rem; text-align: center; pointer-events: none; }
.cuenta-chica { display: inline-block; margin-left: .3rem; min-width: 1.1rem; padding: 0 .35rem; border-radius: 99px;
  background: var(--rojo); color: #fff; font-size: .68rem; font-weight: 700; line-height: 1.1rem; }
.pos-estado { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-bottom: .8rem; }
.pos-requisitos { list-style: none; padding: 0; margin: 0 0 1rem; display: grid; gap: .4rem; }
.pos-requisitos li { display: flex; gap: .5rem; align-items: flex-start; font-size: .86rem; line-height: 1.45; }
.pos-requisitos .marca { flex: none; width: 1.2rem; text-align: center; font-weight: 700; }
.pos-requisitos .si .marca { color: var(--verde); }
.pos-requisitos .no .marca { color: var(--rojo); }
.pos-requisitos .ojo .marca { color: var(--ambar); }
.pos-liga { display: flex; gap: .4rem; flex-wrap: wrap; margin: .3rem 0 1rem; }
.pos-liga input { flex: 1 1 16rem; min-width: 0; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: .8rem; }
.pos-compartir { display: flex; flex-wrap: wrap; gap: .4rem; margin: .3rem 0 .6rem; }
.pos-qr { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; margin: .3rem 0 1rem; }
/* El QR va siempre negro sobre blanco, también con el tema oscuro: al revés,
   muchos lectores no lo leen. */
.pos-qr canvas { width: 9.5rem; height: 9.5rem; image-rendering: pixelated; border: 1px solid var(--linea);
  border-radius: 6px; background: #fff; }
.pos-qr > div { flex: 1 1 12rem; }
.pos-bolsa textarea { width: 100%; font-size: .82rem; min-height: 9rem; }
.pos-acciones { display: flex; gap: .5rem; flex-wrap: wrap; border-top: 1px solid var(--linea);
  padding-top: .8rem; margin-top: .8rem; }
.pos-ficha { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: .45rem 1.2rem; margin: 0 0 1rem; }
.pos-ficha div { font-size: .86rem; line-height: 1.45; min-width: 0; }
.pos-ficha dt { font-size: .7rem; color: var(--tinta3); text-transform: uppercase; letter-spacing: .04em; }
.pos-ficha dd { margin: 0; overflow-wrap: anywhere; }
.pos-mensaje { white-space: pre-wrap; background: var(--tarjeta2); border-radius: var(--radio-s);
  padding: .6rem .8rem; font-size: .86rem; margin: 0 0 1rem; overflow-wrap: anywhere; }
.pos-coincide { border: 1px solid color-mix(in srgb, var(--ambar) 45%, var(--linea)); background: var(--ambar-f);
  border-radius: var(--radio-s); padding: .7rem .9rem; margin: 0 0 1rem; }
.pos-coincide h3 { margin: 0 0 .3rem; font-size: .95rem; color: var(--ambar); }
.pos-persona { display: flex; gap: .55rem; align-items: flex-start; padding: .5rem 0; font-size: .86rem; line-height: 1.5;
  border-top: 1px dashed color-mix(in srgb, var(--ambar) 35%, transparent); cursor: pointer; }
.pos-persona input { margin-top: .3rem; flex: none; }
.pos-decisiones { display: grid; grid-template-columns: repeat(auto-fit, minmax(12.5rem, 1fr)); gap: .6rem; margin-top: .6rem; }
.pos-decision { border: 1px solid var(--linea); border-radius: var(--radio-s); padding: .7rem;
  display: flex; flex-direction: column; gap: .45rem; }
.pos-decision p { margin: 0; font-size: .8rem; color: var(--tinta2); line-height: 1.45; }
.pos-decision.bloqueada p { color: var(--tinta3); }
.pos-papeles { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: .35rem; }
.pos-papeles li { font-size: .86rem; overflow-wrap: anywhere; }


/* ══ EL TELÉFONO, AL FINAL A PROPÓSITO ═══════════════════════════════
   Esto va hasta abajo porque en CSS, a igualdad de peso, gana la última
   regla escrita. Más arriba hay `.linea-agregar input[type=date] { width:
   auto }` para que en escritorio una fecha no ocupe media fila; esa regla
   está bien y no se toca. Pero ganaba también en el teléfono, y ahí dejaba
   el campo de fecha en 146 px al lado de otros de 303: una fila de cajitas
   desiguales que no se le puede enseñar a un cliente.

   Y la otra causa: los formularios de captura llevan `align-items:flex-end`
   escrito en el propio elemento, y un estilo en línea le gana a la hoja.
   Por eso los campos se veían empujados a la derecha. */
@media (max-width: 30rem) {
  .linea-agregar {
    flex-direction: column !important;
    align-items: stretch !important;
  }
  /* ── LA BASE DE UN FLEX CAMBIA DE EJE AL VOLTEAR EL CONTENEDOR ────
     Los campos traen escrito en la propia etiqueta `flex:1 1 20rem`. En una
     FILA ese 20rem es un ancho mínimo, que es para lo que se puso. Pero al
     voltear el contenedor a COLUMNA pasa a ser el eje principal, y ese mismo
     20rem se convierte en un ALTO de 320 px con el texto arriba y el resto
     vacío. Los cuatro campos del acuerdo y de la comisión dejaban huecos
     blancos de 320, 256, 224 y 192 px.
     Se anula la base para que cada campo mida lo que mide su contenido. Va
     con !important porque el `flex` está escrito en el elemento. */
  .linea-agregar > * { flex: 0 0 auto !important; }
  .linea-agregar > label,
  .linea-agregar > .campo { display: block; width: 100%; text-align: left; }
  .linea-agregar input,
  .linea-agregar select,
  .linea-agregar textarea,
  .linea-agregar input[type=date],
  .linea-agregar input[type=time] { width: 100%; box-sizing: border-box; }
  /* El botón de la acción, del ancho del pulgar y al final de la columna. */
  .linea-agregar .btn { width: 100%; margin-top: .2rem; }
}


/* Los grupos de botones en pastilla —«En proceso · No contratados ·
   Portafolio de CV · Archivados»— miden más de 600 px y en un teléfono se
   salían 250. Se parten en dos renglones en vez de cortarse: un botón que no
   se ve no se puede tocar. Se les quita el redondeo de pastilla porque con
   dos renglones queda torcido. */
@media (max-width: 30rem) {
  .grupo {
    display: flex; flex-wrap: wrap; border-radius: var(--radio-s);
    width: 100%; overflow: visible;
  }
  .grupo button { flex: 1 1 8rem; border-radius: 0; border-bottom: 1px solid var(--linea); }
  .grupo button:last-child { border-right: 0; border-bottom: 0; }
}
