/* ==========================================================================
   OSVENTOS · Sistema de diseño del Portal del Empleado
   Marca (manual de identidad): Pantone 5555C salvia #5C7F71 + 5855C dorado #C0BB87.
   Reglas del logo: no recolorear; sobre fondo oscuro va la versión invertida (blanca).
   ========================================================================== */

/* CONTRASTE. Los colores de texto están medidos contra el PEOR fondo sobre el que caen
   —no contra el blanco— y cumplen el 4,5:1 que pide WCAG 2.2 AA.

   Medir contra blanco fue el error de la primera pasada, y costó dos correcciones: el
   texto de este portal cae sobre el gris de la aplicación, sobre el degradado de la barra
   lateral y sobre los tintes de los avisos, que son más oscuros que el blanco. Ahí es
   donde hay que medir. Dieciocho pares se quedaban entre 4,05 y 4,49 midiendo bien. Varios se quedaban a un pelo —el verde de
   marca daba 4,44:1— y «a un pelo» no lo es: quien no distingue ese texto no lo
   distingue igual por 0,06. El Pantone 5555C del manual sigue siendo el color de la
   identidad y del logo; lo que se oscurece un 3% es el tono con el que se pinta TEXTO
   y botones, que es donde la norma aplica. A ojo no se aprecia la diferencia.  */
:root{
  color-scheme: light;
  /* marca */
  --brand:#517063; --brand-deep:#3c574b; --brand-ink:#2a3d34;
  --gold:#c0bb87; --gold-deep:#6b653c; --gold-soft:#f2efdd;
  --brand-soft:#e8efeb; --brand-tint:#f0f4f2;
  /* neutros con sesgo salvia */
  --bg:#eef2f0; --surface:#ffffff; --surface-2:#f6f8f6;
  --border:#dde5e0; --border-strong:#c6d1ca;
  /* El contorno de un campo o de un botón es información, no adorno: WCAG 1.4.11 le
     pide 3:1. `--border-strong` daba 1,57:1 y el campo se perdía sobre el blanco. */
  --border-control:#7e8c85;
  /* Tres niveles de gris para el texto. El tercero ya no puede ser más claro que esto
     sin bajar del 4,5:1, así que la jerarquía entre `muted` y `faint` la marcan sobre
     todo el tamaño y el peso, no el color. */
  --ink:#22302a; --muted:#5e6d66; --faint:#606c64;
  /* semánticos */
  --ok:#26764d; --ok-bg:#e4f3ea;
  --warn:#a54b08; --warn-bg:#f8ecdc;
  --bad:#b4432e; --bad-bg:#f8e6e1;
  --info:#3e6f88; --info-bg:#e6eef2;
  --shadow:0 1px 2px rgba(30,45,38,.05), 0 6px 20px rgba(30,45,38,.06);
  --radius:14px; --radius-sm:9px;
  /* Escala de espaciado. El relleno de una tarjeta es `--pad`, y lo que necesite más
     aire usa un múltiplo suyo, no un número elegido aparte: así el que venga detrás
     sabe de dónde sale cada distancia. */
  --pad:1rem; --pad-lg:2rem; --pad-sm:.5rem;
  --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
/* La marca Osventos es luminosa: el portal va siempre en claro,
   sin seguir el modo oscuro del sistema. */

*,*::before,*::after{box-sizing:border-box}
html,body{margin:0}
body{font-family:var(--font); color:var(--ink); background:var(--bg);
  font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased; min-height:100vh}
h1,h2,h3{margin:0; text-wrap:balance; letter-spacing:-.01em}
h1{font-size:1.4rem}
a{color:var(--brand); font-weight:600; text-decoration:none}
a:hover{text-decoration:underline}
.tnum{font-variant-numeric:tabular-nums}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
p.intro{color:var(--muted); font-size:.92rem}

/* ---------- logo ---------- */
.s-gold{fill:#bfbb87}
.s-sage{fill:#597f72}
.logo-rev .s-sage{fill:#ffffff}   /* versión invertida (fondo oscuro) */
.logo-rev .s-gold{fill:#a7b3ab}

/* ---------- layout centrado (login, formularios, páginas simples) ---------- */
.contenedor{margin:0 auto; padding:2.5rem 1.25rem}
.tarjeta{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:var(--pad-lg)}   /* el doble: es una pantalla de una sola tarea */
.marca{text-align:center; margin-bottom:1.5rem}
.marca img,.marca svg{height:34px; width:auto}
.marca h1{font-size:1.15rem; margin:.5rem 0 0}
.marca p{margin:.15rem 0 0; color:var(--muted); font-size:.85rem}
.enlaces{margin-top:1rem; text-align:center; font-size:.9rem}
/* La tabla que se sale de la pantalla se desplaza; para poder hacerlo con teclado hay
   que poder llegar a ella, y para saber que se ha llegado hay que verlo. El `tabindex`
   lo pone `tabla.js`, y solo cuando de verdad hay algo que desplazar. */
/* Etiqueta que solo existe para quien no ve la pantalla. No se usa `display:none` ni
   `hidden`, que la sacarían también del árbol de accesibilidad: se saca de la vista
   dejándola donde el lector la encuentra. */
.visualmente-oculto{position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0}
/* `position:relative` no es decoración: sin él, un elemento `position:absolute` de
   dentro —una etiqueta oculta a la vista, por ejemplo— toma como referencia el bloque
   inicial y NO lo recorta este contenedor. Se escapa a la derecha del todo y ensancha
   la página entera; medido, 280 px de más en el listado de empleados. */
.overflow{overflow-x:auto; position:relative}
.overflow:focus-visible{outline:2px solid var(--brand); outline-offset:2px; border-radius:6px}

/* barra de cabecera de página (listados) */
.barra{display:flex; justify-content:space-between; align-items:center; gap:1rem;
  margin-bottom:1.25rem; flex-wrap:wrap}
.barra h1{margin:0}

/* ---------- formularios ---------- */
label{display:block; font-size:.85rem; font-weight:600; margin:1rem 0 .35rem}
input[type=email],input[type=password],input[type=text],input[type=search],input[type=tel],
input[type=date],input[type=month],input[type=number],select,textarea{
  width:100%; padding:.7rem .8rem; border:1px solid var(--border-control);
  border-radius:var(--radius-sm); font-size:1rem; background:var(--surface); color:var(--ink)}
input:focus,select:focus,textarea:focus{outline:2px solid var(--brand); border-color:var(--brand)}
/* El foco se veía solo en los campos: quien navega con teclado se perdía en cuanto
   llegaba a un botón o a un enlace. */
a:focus-visible,button:focus-visible,summary:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--brand); outline-offset:2px; border-radius:4px}
/* Sobre el verde oscuro de la barra lateral, ese mismo anillo daba 2,18:1 y no se veía:
   quien navega con teclado perdía el rastro justo en el menú. Allí va en dorado (4,9:1). */
.side a:focus-visible,.side button:focus-visible,.side [tabindex]:focus-visible{
  outline-color:var(--gold)}

/* SALTAR AL CONTENIDO. Sin esto, con teclado o con lector de pantalla hay que recorrer
   los treinta y tantos enlaces del menú en CADA página antes de llegar a lo que se
   venía a hacer. Solo se ve cuando recibe el foco. */
.saltar{position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--surface); color:var(--brand-deep); font-weight:700; font-size:.9rem;
  padding:.6rem .9rem; border-radius:0 0 var(--radius-sm) 0; box-shadow:var(--shadow)}
.saltar:focus{left:0; text-decoration:none}
.checkbox{display:flex; gap:.6rem; align-items:flex-start; margin-top:1.25rem; font-size:.9rem}
.checkbox input{margin-top:.2rem; width:auto}

/* ALTURA ÚNICA. Un <a class="btn"> medía 47px y un <button class="btn"> 42: el botón no
   hereda la altura de línea del texto y el enlace sí. Puestos uno al lado del otro —el
   verde suele ser un <button> y el blanco un enlace, o al revés— no casaban. La altura
   la fija ahora `min-height`, y la línea es la misma para los dos. */
button,.btn{display:inline-flex; align-items:center; justify-content:center; gap:.45rem;
  border:1px solid transparent; border-radius:var(--radius-sm); font-family:inherit; font-size:.95rem; font-weight:600;
  line-height:1.25; min-height:2.5rem; cursor:pointer; background:var(--brand); color:#fff; padding:.5rem 1rem}
button:hover,.btn:hover{background:var(--brand-deep); text-decoration:none}
form > button[type=submit]{width:100%; margin-top:1.5rem; padding:.8rem}
.btn.ghost{background:var(--surface); border-color:var(--border-control); color:var(--ink)}
.btn.ghost:hover{border-color:var(--brand); color:var(--brand); background:var(--surface)}
.btn.sec,.boton-sec{display:inline-flex; align-items:center; min-height:2rem; padding:.3rem .9rem; border-radius:var(--radius-sm);
  background:var(--brand); color:#fff; font-weight:600; font-size:.9rem; line-height:1.25}
.boton-sec:hover{background:var(--brand-deep); text-decoration:none}
/* WCAG 2.2 (2.5.8): ninguna diana por debajo de 24x24. Los enlaces sueltos bajo un
   formulario medían 19 px de alto y en móvil se fallan con el dedo. */
.enlaces a,.form-actions .cancel{display:inline-flex; align-items:center; min-height:24px}
.accion-inline{display:inline}
.accion-inline button{width:auto; margin:0; padding:.35rem .7rem; font-size:.82rem;
  background:none; color:var(--brand); font-weight:600}
.accion-inline button:hover{text-decoration:underline; background:none}

/* ---------- avisos ---------- */
.aviso{padding:.7rem .85rem; border-radius:var(--radius-sm); font-size:.9rem;
  border:1px solid transparent}
.aviso.error{background:var(--bad-bg); color:var(--bad); border-color:color-mix(in srgb,var(--bad) 25%,transparent)}
.aviso.exito{background:var(--ok-bg); color:var(--ok); border-color:color-mix(in srgb,var(--ok) 25%,transparent)}
/* Ni error ni éxito: la operación salió, pero con una reserva que conviene leer. */
.aviso.aviso-ojo{background:var(--warn-bg); color:var(--warn); border-color:color-mix(in srgb,var(--warn) 25%,transparent)}

/* ---------- tablas ---------- */
table{width:100%; border-collapse:collapse}
th,td{text-align:left; padding:.6rem .5rem; border-bottom:1px solid var(--border); font-size:.9rem}
th{color:var(--muted); font-weight:600; font-size:.74rem; text-transform:uppercase; letter-spacing:.03em}
tbody tr:hover{background:var(--surface-2)}
/* Una fila que ya no está en vigor. Se atenúa, pero no se esconde: el histórico de quién
   coordinó qué es lo que explica quién pudo ver la jornada de quién. Y no se marca SOLO
   con el gris —eso sería información por color— sino con su etiqueta de estado al lado. */
tr.fila-pasada td{color:var(--muted)}
td .sub{color:var(--faint); font-size:.78rem}
/* listados con anchos de columna estables (no bailan al ordenar/paginar) */
/* ANCHO MÍNIMO. `table-layout:fixed` con `width:100%` hace que la tabla se encoja hasta
   caber en su contenedor en vez de desbordarlo: las columnas se comprimen por debajo de
   su contenido y el texto se pinta encima de la vecina. Como la tabla nunca excede el
   contenedor, el desplazamiento horizontal que ya existe NO llega a activarse nunca.

   `width:max-content` le da a la tabla lo que de verdad necesita —1256px Empleados,
   1362px Convenios— y `min-width:100%` evita que se quede corta cuando sobra sitio. No
   hay número fijo que valga: cada listado pide lo suyo. Medido: sin esto, 34 celdas se
   salían de su caja en Empleados a 1152px y los encabezados se pisaban en siete
   pantallas a 375px. Un ancho mínimo fijo tampoco servía: con 960, «Nombre» y «Correo»
   se quedaban en 61px y la fila se partía en siete líneas —ya no desbordaba, seguía
   siendo ilegible. */
.tabla-lista{table-layout:fixed}
.overflow .tabla-lista{width:max-content; min-width:100%}
.tabla-lista td{word-break:break-word; vertical-align:top}
/* acciones por fila como iconos */
.rowact{display:inline-flex; gap:.15rem; align-items:center; justify-content:flex-end}
.iconbtn{display:inline-flex; align-items:center; justify-content:center; width:30px; height:30px; margin:0;
  padding:0; border:1px solid transparent; border-radius:8px; background:none; cursor:pointer; color:var(--muted)}
.iconbtn:hover{color:var(--brand); background:var(--surface-2); text-decoration:none}
.iconbtn svg{width:16px; height:16px}
.iconbtn.on{color:var(--ok)}
.iconbtn.on:hover{color:var(--warn)}
.iconbtn.off{color:var(--faint)}
.iconbtn.off:hover{color:var(--ok)}

/* cabecera: nombre ordena, icono de embudo abre el filtro */
.colmenu{position:relative; display:inline-flex; align-items:center; gap:.3rem}
.colsort{display:inline-flex; align-items:center; gap:.3rem; color:var(--muted); font-weight:600;
  font-size:.74rem; text-transform:uppercase; letter-spacing:.03em; cursor:pointer}
.colsort:hover{color:var(--ink); text-decoration:none}
.colsort.act{color:var(--ink)}
.colsort .ord{color:var(--brand); font-size:.9em}
.colbtn{display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px;
  padding:0; margin:0; background:none; border:0; border-radius:6px; cursor:pointer; color:var(--faint)}
.colbtn:hover{color:var(--ink); background:var(--surface-2)}
.colbtn.act{color:var(--gold-deep)}
.colbtn .fic{width:13px; height:13px}
.colpanel{position:fixed; display:none; z-index:1000; min-width:214px; flex-direction:column; gap:.5rem;
  background:var(--surface); border:1px solid var(--border-strong); border-radius:11px;
  box-shadow:0 10px 30px rgba(30,45,38,.18); padding:.6rem; text-transform:none; letter-spacing:normal; font-weight:400}
.colmenu.open .colpanel{display:flex}
.colpanel .sortrow{display:flex; gap:.4rem}
.colpanel .sortrow a{flex:1; text-align:center; padding:.35rem .4rem; border:1px solid var(--border);
  border-radius:7px; font-size:.8rem; color:var(--ink); font-weight:600}
.colpanel .sortrow a:hover{border-color:var(--brand); text-decoration:none}
.colpanel .sortrow a.on{background:var(--brand-soft); border-color:var(--brand); color:var(--brand-deep)}
.colpanel input,.colpanel select{width:100%; padding:.42rem .55rem; font-size:.85rem; border-radius:7px}
.colpanel .panelacts{display:flex; align-items:center; gap:.7rem}
.colpanel .panelacts a{font-size:.8rem; color:var(--muted)}

/* ---------- etiquetas / pills ---------- */
.pill{display:inline-flex; align-items:center; gap:.35rem; padding:.12rem .55rem; border-radius:999px;
  font-size:.74rem; font-weight:700}
.pill::before{content:""; width:6px; height:6px; border-radius:50%; background:currentColor}
.pill.num{padding:.12rem .5rem; font-variant-numeric:tabular-nums; min-width:1.9rem;
  justify-content:center}
.pill.num::before{display:none}   /* un número no necesita el punto delante */
.pill.ok{color:var(--ok); background:var(--ok-bg)}
.pill.warn{color:var(--warn); background:var(--warn-bg)}
.pill.bad{color:var(--bad); background:var(--bad-bg)}
.pill.info{color:var(--info); background:var(--info-bg)}
.pill.mut{color:var(--muted); background:var(--surface-2)}
.pill.portal{color:var(--brand-deep); background:var(--brand-soft)}
.pill.ext{color:var(--muted); background:var(--surface-2)}

/* selección en lote */
.selcol{text-align:center; padding-left:.4rem; padding-right:.4rem}
.selall,.selrow{width:auto; margin:0; cursor:pointer; accent-color:var(--brand)}
.bulkbar{position:fixed; bottom:1.2rem; left:240px; right:0; z-index:50; display:none; justify-content:center; pointer-events:none}
.bulkbar.activa{display:flex}
.bulkbar .bulkinner{display:flex; align-items:center; gap:1rem; flex-wrap:wrap; pointer-events:auto;
  padding:.7rem .9rem .7rem 1.1rem; border:1px solid var(--brand); border-radius:14px;
  background:var(--surface); box-shadow:0 12px 34px rgba(30,45,38,.22)}
.bulkbar .bulkinfo{font-size:.9rem; color:var(--muted)}
.bulkbar .bulkinfo .bulkcount{color:var(--brand-deep); font-size:1.1rem}
.bulkbar .bulklabel{font-size:.85rem; color:var(--muted); font-weight:600; margin-left:.3rem}
.bulkbar .btn{width:auto; margin:0}
.bulkbar .btn:disabled{opacity:.5; cursor:not-allowed}
@media (max-width:860px){ .bulkbar{left:0} }

/* ==========================================================================
   APP SHELL (base_app): barra lateral + barra superior + contenido
   ========================================================================== */
/* 240px, lo mismo que en estilos.css: con 248 aquí y 240 allí, el menú daba un salto al
   pasar de una pantalla antigua a una nueva mientras dure la migración. */
.app{display:grid; grid-template-columns:240px 1fr; min-height:100vh}
.side{background:linear-gradient(180deg,var(--brand-deep),var(--brand-ink)); color:#d7e0db;
  padding:1.1rem .8rem; display:flex; flex-direction:column; gap:1.3rem; position:sticky; top:0; height:100vh}
.side .brand{display:flex; align-items:center; gap:.5rem; padding:.3rem .5rem}
.side .brand svg{height:25px; width:auto; flex:none}
.side .brand .name{font-weight:800; font-size:1.02rem; letter-spacing:-.02em; color:#fff}
.side .brand .sub{font-size:.62rem; letter-spacing:.14em; text-transform:uppercase; color:#bccbc2}
.nav{display:flex; flex-direction:column; gap:.12rem; overflow-y:auto}
.nav .grp{font-size:10.5px; letter-spacing:.12em; text-transform:uppercase; color:#bccbc2;
  font-weight:600; border-top:1px solid rgba(255,255,255,.1);
  margin:12px 4px 4px; padding:10px 6px 0}
/* El primero no lleva raya: separaría del logo, no de nada. */
.nav .grp:first-child{border-top:none; margin-top:4px; padding-top:0}
/* Secciones plegables: el rótulo es el <summary>, con un chevrón que gira. Sin la
   marca nativa del navegador, que no casa con la barra. */
.nav details.sec{display:flex; flex-direction:column; gap:.12rem}
.nav details.sec>summary.grp{display:flex; align-items:center; justify-content:space-between;
  cursor:pointer; list-style:none; user-select:none}
.nav details.sec>summary.grp::-webkit-details-marker{display:none}
.nav details.sec>summary.grp:hover{color:#e6ede9}
.nav details.sec>summary.grp .chev{width:14px; height:14px; flex:none; opacity:.7; transition:transform .15s}
.nav details.sec[open]>summary.grp .chev{transform:rotate(180deg)}
/* Un rótulo más largo que la barra le añadía a ESTA una barra de desplazamiento
   horizontal, y el texto salía cortado a medias sin puntos suspensivos. Se recorta el
   enlace, no la barra: el nombre completo sigue estando para el lector. */
.nav{overflow-x:hidden}
.nav a{display:flex; align-items:center; gap:.6rem; padding:.5rem .6rem; border-radius:9px;
  white-space:nowrap;
  color:#cad8d1; font-size:.9rem; font-weight:500}
.nav a:hover{background:rgba(255,255,255,.06); text-decoration:none}
.nav a.on{background:rgba(192,187,135,.18); color:#fff; font-weight:600; box-shadow:inset 2px 0 0 var(--gold)}
.nav a .ic{width:18px; height:18px; flex:none; opacity:.85}
.nav a .cnt{margin-left:auto; font-size:.72rem; background:rgba(255,255,255,.12); padding:.05rem .4rem; border-radius:999px}
.side .foot{margin-top:auto; display:flex; align-items:center; gap:.55rem; padding:.5rem;
  border-top:1px solid rgba(255,255,255,.1)}
.side .foot .avatar{width:30px; height:30px; border-radius:50%; background:#47665a; color:#fff;
  display:grid; place-items:center; font-size:.76rem; font-weight:700; flex:none}
.side .foot .who{font-size:.8rem; line-height:1.25; min-width:0}
.side .foot .who b{color:#fff; font-weight:600; font-size:.86rem; display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.side .foot .who span{color:#bccbc2}
.side .foot .salir{margin-left:auto; color:#bccbc2}

.appmain{display:flex; flex-direction:column; min-width:0}
.top{display:flex; align-items:center; gap:1rem; padding:.8rem 1.4rem;
  border-bottom:1px solid var(--border); background:var(--surface); position:sticky; top:0; z-index:10}
.top .crumb{font-size:.82rem; color:var(--muted)}
.top .crumb b{color:var(--ink)}
.top .grow{margin-left:auto}
.lang{display:inline-flex; border:1px solid var(--border); border-radius:999px; overflow:hidden;
  font-size:.74rem; font-weight:700}
.lang a{padding:.3rem .55rem; color:var(--muted)}
.lang a.on{background:var(--brand); color:#fff}
.content{padding:1.5rem 1.4rem 2.5rem}

/* RITMO VERTICAL. Una sola distancia entre los bloques de primer nivel, de la misma
   escala que el relleno. Antes se la ponía cada pantalla a mano —cinco valores
   distintos— y allí donde el elemento no traía la suya, las cosas se tocaban: bastaba
   con que el siguiente bloque no fuese una tarjeta para que el hueco desapareciera. */
.content > * + *{margin-top:var(--pad)}
.content > .pagehead{margin-bottom:0}
/* Tras el título de la página, algo más de aire: separa el encabezado del contenido. */
.content > .pagehead + *{margin-top:calc(var(--pad) * 1.5)}

/* LONGITUD DE LÍNEA. El contenido ocupa toda la página —tablas y calendarios lo
   necesitan— pero el TEXTO no: en una pantalla ancha, un párrafo a todo lo largo salía
   a 222 caracteres por línea, y al saltar de renglón el ojo no encuentra dónde seguir.
   La medida cómoda de lectura son 45-75 caracteres; a partir de 90 ya cuesta.

   Se limita la línea, no la maquetación: son cosas distintas y solo una molesta. */
.pagehead p,
.cobertura p,
.nota,
.pie-tabla,
.vacio,
p.sub{max-width:80ch}
.content .tarjeta{max-width:720px}          /* páginas simples dentro del shell */
/* La miga de pan medía 17 px de alto. Va en una línea de texto, así que la regla de
   los 24 px le da margen, pero llegar no cuesta nada y quita la duda. */
.top .crumb a{color:var(--brand); font-weight:600; display:inline-flex; align-items:center; min-height:24px}
/* En el móvil la miga de pan va en una línea, recortada: «Bandeja · Solicitud #743 ·
   Contrato» se partía en cinco renglones y la barra superior crecía hasta tapar media
   pantalla. Se recorta con puntos suspensivos: la página en la que se está ya es el título. */
@media (max-width:640px){
  .top .crumb{flex:1 1 auto; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
  .top .crumb a{display:inline}
}
/* Un enlace suelto que es una llamada a la acción —«Descargar plantilla», «Abrir el
   documento»— no es texto corrido y no se acoge a esa excepción. Un párrafo cuyo único
   contenido es un enlace es exactamente eso: una acción, no una frase. */
.nota a,.cols a,.pie-tabla a,p > a:only-child,td > a:only-child{display:inline-flex; align-items:center; min-height:24px}

/* ---------- formularios de producto ---------- */
.formulario{max-width:100%}
.form-head{margin-bottom:1.1rem}
.form-head h1{font-size:1.45rem}
.form-head p{color:var(--muted); font-size:.9rem; margin:.25rem 0 0}
.form-sec{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:1.1rem 1.2rem 1.25rem; margin-bottom:var(--pad)}
.form-sec > .sh{font-size:.72rem; text-transform:uppercase; letter-spacing:.05em; color:var(--brand-deep);
  font-weight:700; margin:0}
.form-sec > .shd{color:var(--muted); font-size:.82rem; margin:.15rem 0 0}
.form-sec > .sh + .form-grid, .form-sec > .shd + .form-grid, .form-sec > .sh + .field{margin-top:.7rem}
.form-grid{display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:.35rem 1.1rem}
.form-grid .full{grid-column:1 / -1}
.field{display:flex; flex-direction:column}
.field > label{margin:.55rem 0 .32rem; font-size:.82rem}
.field .hint{font-size:.78rem; color:var(--faint); margin-top:.3rem}

/* CAMPO EN FALTA. El aviso de arriba dice que algo falta; esto dice CUÁL. El borde no
   es lo único que lo marca —sería información solo por color— y por eso además lleva
   su mensaje debajo y `aria-invalid`. */
[aria-invalid="true"]{border-color:var(--bad); box-shadow:0 0 0 1px var(--bad)}
.campo-falta{font-size:.78rem; color:var(--bad); font-weight:600; margin:.3rem 0 0}
/* Que un campo sea obligatorio solo se descubría al enviar. El navegador ya se lo dice
   al lector de pantalla por el atributo `required`; esto es la mitad visible. */
.field:has(> :required) > label::after,
label:has(+ input:required)::after,
label:has(+ select:required)::after,
label:has(+ textarea:required)::after{content:" *"; color:var(--bad); font-weight:700}
.field.check{margin-top:.4rem}
.field.check label.checkbox{margin-top:0}
.form-actions{display:flex; justify-content:flex-end; align-items:center; gap:1rem; margin-top:.2rem}
/* Dentro de un bloque de formulario, el botón se separa de los campos: con .2rem se
   quedaba pegado al último (Mi cuenta: la contraseña nueva y el PIN de la tablet). */
.form-sec > .form-actions{margin-top:var(--pad)}
.form-sec > .form-actions button[type=submit]{width:auto; margin:0}
/* Una pastilla suelta en la cabecera de una tarjeta va al extremo derecho. */
.card > .hd > .pill{margin-left:auto}
.form-actions .btn{width:auto; margin:0}
/* `.cancel` se pensó para un ENLACE, que no trae fondo. Puesto en un <button>, que sí
   lo trae, dejaba texto gris sobre el verde de marca: 1,00:1, un botón invisible. Pasa
   en la pantalla de firmar, donde el control que se pierde es «Borrar y repetir». */
.form-actions .cancel{color:var(--muted); font-weight:600}
button.cancel{background:none; border:0; padding:.45rem .2rem; font-size:.95rem}
button.cancel:hover{background:none; text-decoration:underline; color:var(--ink)}
@media (max-width:640px){ .form-grid{grid-template-columns:1fr} }

/* ---------- páginas de acción (importar / cargar / vincular / derivar) ---------- */
.nota{background:var(--brand-tint); border:1px solid var(--border); border-radius:10px;
  padding:.7rem .8rem; font-size:.85rem; color:var(--muted)}
.cols{display:flex; flex-wrap:wrap; gap:.4rem; margin-top:.2rem}
.cols code{background:var(--surface-2); border:1px solid var(--border); border-radius:6px;
  padding:.15rem .5rem; font-size:.8rem; color:var(--brand-deep); font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
input[type=file]{width:100%; padding:.65rem .75rem; border:1.5px dashed var(--border-control);
  border-radius:10px; background:var(--surface-2); font-size:.88rem; cursor:pointer; color:var(--muted)}
input[type=file]::file-selector-button{margin-right:.8rem; padding:.45rem .85rem; border:0; border-radius:7px;
  background:var(--brand); color:#fff; font-weight:600; cursor:pointer}
.resumen{margin-top:1.1rem; margin-bottom:1.4rem}
.resumen .cifras{display:flex; gap:1.8rem; flex-wrap:wrap; align-items:flex-end}
/* En la bandeja de nóminas la tira de cifras va en una tarjeta sin .bd: sin este relleno los
   números salían pegados al borde. Y cada cifra es número encima de etiqueta, no en línea. */
.card.resumen > .cifras{padding:1.4rem var(--pad); gap:2.6rem}
.resumen .cifra{display:flex; flex-direction:column; align-items:flex-start}
.resumen .cifra .n{font-size:1.75rem; font-weight:800; color:var(--brand-deep); line-height:1; font-variant-numeric:tabular-nums}
.resumen .cifra .l{font-size:.72rem; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); font-weight:600; margin-top:.25rem}
.resumen .ok-msg{color:var(--ok); font-weight:600; margin:.7rem 0 0}
.resumen .warn-msg{color:var(--warn); font-weight:600; margin:.7rem 0 .1rem}
ul.errores{margin:.5rem 0 0; padding-left:1.1rem; color:var(--bad); font-size:.84rem}
ul.errores li{margin:.1rem 0}
.pagehead{display:flex; align-items:flex-end; gap:1rem; margin-bottom:1.3rem; flex-wrap:wrap}
.pagehead h1{font-size:1.5rem}
.pagehead p{margin:.25rem 0 0; color:var(--muted); font-size:.9rem}
/* `align-items` por defecto estira: en cuanto un control de la fila es más alto que
   otro —una tira de navegación junto a un botón—, el botón crece hasta igualarla y se
   lee como una caja vacía flotando. Se alinean por el centro. */
.pagehead .actions{margin-left:auto; display:flex; gap:.5rem; flex-wrap:wrap; align-items:center}
/* Un formulario de un solo botón en la cabecera («Marcar todas como leídas»). Sin esto,
   `form > button[type=submit]` —pensado para el login— lo estiraba a todo el ancho. */
.pagehead .actions form{margin:0}
.pagehead .actions form > button[type=submit]{width:auto; margin:0; padding:.5rem 1rem}
/* El selector de meses del cuadro económico: dos campos y un botón, en una línea a la
   derecha del título. Sin esto los .field heredan el margen del formulario largo, se
   apilan y empujan el título hacia abajo. */
.pagehead .periodo{margin-left:auto; display:flex; gap:.6rem; align-items:flex-end; flex-wrap:wrap}
.pagehead .periodo .field{margin:0}
.pagehead .periodo .field > label{margin:0 0 .3rem}
.pagehead .periodo input[type=month]{width:10.5rem; min-height:38px; font-family:inherit}
.pagehead .periodo .btn{width:auto; margin:0; min-height:38px; flex:0 0 auto}

/* MENÚ PLEGADO A ICONOS, igual que en estilos.css y con el mismo botón y la misma
   preferencia (`lateral.js`). Tiene que estar en las dos hojas: si solo lo entendieran las
   pantallas nuevas, el menú se abriría y se plegaría solo al pasar de unas a otras. */
button.plegar{display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; min-height:0;
  padding:0; border:0; border-radius:var(--radius-sm); background:none; color:var(--muted); flex:none}
button.plegar:hover{background:var(--surface-2); color:var(--ink)}
.plegar svg{width:18px; height:18px; transition:transform .15s}
.lateral-plegado .plegar svg{transform:scaleX(-1)}
.lateral-plegado .app{grid-template-columns:64px 1fr}
.lateral-plegado .side{padding-left:.5rem; padding-right:.5rem}
.lateral-plegado .side .brand > div,
.lateral-plegado .side .foot .who,
.lateral-plegado .nav details.sec > summary.grp > span{display:none}
.lateral-plegado .side .brand,.lateral-plegado .side .foot{justify-content:center; padding-left:0; padding-right:0}
.lateral-plegado .side .foot{flex-direction:column}
.lateral-plegado .side .foot .salir{margin-left:0}
.lateral-plegado .nav a{font-size:0; justify-content:center; padding:.5rem 0; gap:0; position:relative}
.lateral-plegado .nav a .ic{width:20px; height:20px}
.lateral-plegado .nav a .cnt,.lateral-plegado .nav a .pill{position:absolute; top:0; right:2px; font-size:.625rem; padding:0 4px; min-width:0}
.lateral-plegado .nav a .pill::before{display:none}
.lateral-plegado .nav details.sec > summary.grp{justify-content:center; margin:.5rem 0 .25rem; padding:.5rem 0 0}
.lateral-plegado .nav details.sec > summary.grp .chev{width:12px; height:12px}
.lateral-plegado .bulkbar{left:64px}

/* menú móvil (checkbox hack, sin JS) */
.navtoggle{display:none}
.navmask{display:none}   /* solo se muestra en móvil; en escritorio no debe ocupar celda de la rejilla */
.burger{display:none}

/* ---------- KPIs y tarjetas de contenido ---------- */
.grid2{display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:1rem}
.card{background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow)}
.card .hd{display:flex; align-items:center; gap:.6rem; padding:.9rem var(--pad); border-bottom:1px solid var(--border)}
.card .hd h3{font-size:.98rem}
.card .hd .more{margin-left:auto; font-size:.8rem}
.card .bd{padding:.4rem var(--pad) var(--pad)}

/* TÍTULO DE SECCIÓN. `.sh` solo tenía estilo dentro de `.form-sec`, y la ficha del
   expediente no usa esa envoltura: sus nueve títulos salían a 15px y peso 400, es
   decir, idénticos al texto que ordenan. La página entera tenía un solo nivel
   tipográfico y por eso no se distinguía una sección de la siguiente.

   Va aquí y no en la plantilla porque el fallo es del sistema: la clase existía, el
   estilo no llegaba. */
.card > .sh,
.card > .cardhead > .sh{
  font-size:1rem; font-weight:700; color:var(--ink); letter-spacing:-.005em;
  padding:.95rem var(--pad) .75rem; border-bottom:1px solid var(--border)}
.card > .sh + *{margin-top:.9rem}
.card > .sh + .datos{padding:0 var(--pad)}

/* Título de tarjeta con su acción al lado. Antes se reutilizaba `.pagehead`, que está
   pensada para la cabecera de una PÁGINA: alineaba el botón abajo y lo hacía pesar más
   que el titulo al que pertenece. */
.card > .cardhead{display:flex; align-items:center; gap:.9rem; flex-wrap:wrap;
  padding:.55rem var(--pad); border-bottom:1px solid var(--border)}
.card > .cardhead > .sh{padding:.4rem 0; border-bottom:0; margin-right:auto}
.card > .cardhead .btn{margin:0}

/* NAVEGACION, NO ACCIONES. Las partes de un expediente son sitios a los que se va, no
   cosas que se hacen; con aspecto de botón competían con «Editar» y con «Cerrar
   expediente», que es irreversible y se leía igual que una pestaña. */
.subnav{display:flex; flex-wrap:wrap; gap:.3rem; align-items:center}
.subnav a{display:inline-flex; align-items:center; min-height:34px; padding:.35rem .7rem;
  border-radius:9px; font-size:.88rem; font-weight:600; color:var(--brand-deep);
  background:var(--brand-tint); border:1px solid transparent}
.subnav a:hover{background:var(--brand-soft); text-decoration:none}
.subnav a.on{background:var(--brand-soft); border-color:var(--brand)}
/* Lo irreversible se separa y se dice en rojo: no puede parecer una pestaña mas. */
.accion-final button{background:none; border:1px solid var(--border-control);
  color:var(--bad); font-weight:600; padding:.45rem .8rem}
.accion-final button:hover{background:var(--bad-bg); border-color:var(--bad)}

/* Las tarjetas NO traen relleno propio: se lo ponen `.hd` y `.bd`. Lo que se cuelga
   directamente de una tarjeta —un título, la línea de filtros, la nota al pie— se
   quedaba pegado al borde, y dos tarjetas seguidas se tocaban. Se ve sobre todo en
   las pantallas del jurídico, que apilan varias.

   Se arregla aquí y no en cada plantilla porque es del sistema, no de una pantalla. */
.card > h2,
.card > .filtros-activos,
.card > .pie-tabla,
.card > p{padding-left:var(--pad); padding-right:var(--pad)}

/* `.nota` y `.avisos` NO son texto: son recuadros con su fondo, su borde y sus
   esquinas. Necesitan MARGEN, no relleno — con relleno seguían midiendo el ancho
   entero de la tarjeta y se leían como una franja de canto a canto en vez de como un
   recuadro dentro. */
.card > .nota,
.card > .avisos{margin-left:var(--pad); margin-right:var(--pad)}
.card > h2{padding-top:1rem}
.card > .filtros-activos{padding-top:1rem}
.card > .pie-tabla{padding-bottom:1rem}

/* El contenido de una tarjeta se separa del borde, TODO él y por igual. Antes solo lo
   hacían los elementos sueltos: las tablas —que son el grueso— se quedaban a los 8px
   de la celda y el texto salía pegado al canto. Alineando la primera y la última
   columna con el resto, la tarjeta se lee como un bloque y no como un recorte. */
/* Relleno COMPLETO, no solo a los lados: con `padding: 0 var(--pad)` el formulario
   tocaba el borde de la tarjeta por arriba y por abajo, y los desplegables quedaban
   pegados al canto. Las acciones no repiten el de arriba: ya lo pone la rejilla. */
.card > .form-grid{padding:var(--pad)}
.card > .form-actions{padding:0 var(--pad) var(--pad)}
/* La celda puede ser densa por dentro, pero la PRIMERA columna empieza donde empieza
   todo lo demás. Es lo que más se nota sin saber por qué: con el título a 16, la tabla
   a 8 y la nota a 28, el ojo ve desorden aunque cada pieza esté bien. */
.card .tabla-lista th:first-child,
.card .tabla-lista td:first-child{padding-left:var(--pad)}
.card .tabla-lista th:last-child,
.card .tabla-lista td:last-child{padding-right:var(--pad)}
/* Y un poco de aire arriba y abajo cuando la tabla es lo primero o lo último. */
.card > .overflow:first-child .tabla-lista tr:first-child > *{padding-top:1rem}
.card > .overflow:last-child .tabla-lista tr:last-child > *{padding-bottom:1rem}

.feed{display:flex; flex-direction:column}
.feed .it{display:flex; gap:.7rem; padding:.65rem 0; border-bottom:1px solid var(--border); align-items:center}
.feed .it:last-child{border-bottom:0}
.feed .it .ic{width:30px; height:30px; border-radius:8px; display:grid; place-items:center; flex:none; font-size:.9rem;
  background:var(--brand-soft); color:var(--brand)}
.feed .it .t{font-size:.86rem}
.feed .it .m{font-size:.76rem; color:var(--muted)}
.feed .it time{margin-left:auto; font-size:.74rem; color:var(--faint); white-space:nowrap}
.tiles{display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:1rem}
.tile{display:flex; align-items:center; gap:.8rem; background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:var(--shadow); padding:1rem 1.1rem; color:var(--ink); font-weight:600}
.tile:hover{border-color:var(--brand); text-decoration:none}
.tile .ic{width:38px; height:38px; border-radius:10px; background:var(--brand-soft); color:var(--brand);
  display:grid; place-items:center; flex:none}
.tile .m{font-size:.78rem; color:var(--muted); font-weight:500}

/* ---------- filtros y paginación ---------- */
.filters{display:flex; gap:.6rem; align-items:end; margin-bottom:1rem; flex-wrap:wrap}
.filters .campo{display:flex; flex-direction:column; gap:.2rem}
.filters label{margin:0; font-size:.78rem; color:var(--muted); font-weight:600}
.filters input,.filters select{padding:.5rem .7rem}
.conteo{margin-left:auto; color:var(--muted); font-size:.84rem; align-self:center}
.paginacion{display:flex; justify-content:center; align-items:center; gap:.25rem; margin-top:1.1rem; flex-wrap:wrap}
.paginacion .pg{min-width:32px; height:32px; padding:0 .5rem; display:inline-flex; align-items:center;
  justify-content:center; border:1px solid var(--border); border-radius:8px; font-size:.85rem; color:var(--ink); font-weight:600}
.paginacion .pg:hover{border-color:var(--brand); text-decoration:none}
.paginacion .pg.num{font-variant-numeric:tabular-nums}
.paginacion .pg.on{background:var(--brand); border-color:var(--brand); color:#fff}
.paginacion .pg.off{opacity:.4; pointer-events:none}
.paginacion .dots{color:var(--faint); padding:0 .2rem}
.pagina-info{text-align:center; color:var(--muted); font-size:.8rem; margin-top:.4rem}

@media (max-width:860px){
  .app,.lateral-plegado .app{grid-template-columns:1fr}
  button.plegar{display:none}
  .side{position:fixed; z-index:40; width:240px; left:-252px; transition:left .2s; height:100vh}
  .navtoggle:checked ~ .side{left:0}
  /* La casilla que abre el menu estaba en display:none, y eso la saca tambien del
     recorrido del tabulador: con teclado el menu no habia forma de abrirlo. Aqui se
     esconde a la vista pero se deja enfocable, y el foco se pinta sobre la hamburguesa,
     que es lo que la persona ve. */
  .navtoggle{display:block; position:absolute; width:1px; height:1px; margin:-1px;
    padding:0; border:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap}
  .burger{display:inline-flex; cursor:pointer; padding:.3rem; margin-right:.3rem; border-radius:8px}
  .navtoggle:focus-visible ~ .appmain .burger{outline:2px solid var(--brand); outline-offset:2px}
  .navmask{display:none}
  .navtoggle:checked ~ .navmask{display:block; position:fixed; inset:0; background:rgba(0,0,0,.35); z-index:30}
}

/* ---------- jurídico ---------- */
/* Los avisos del expediente no son errores: son cosas que conviene mirar
   (falta la papeleta, no hay provincia del órgano y el cómputo se queda corto). */
.avisos{border-left:3px solid var(--warn); background:var(--warn-bg)}
.avisos ul{margin:0; padding-left:1.1rem; color:var(--warn); font-size:.87rem}
.avisos li + li{margin-top:.35rem}
/* Variante roja: no es «revísalo», es «esto se cae si nadie lo coge». */
.avisos-mal{border-left-color:var(--bad); background:var(--bad-bg)}
.avisos-mal ul, .avisos-mal b{color:var(--bad)}

/* Fichas de datos en dos columnas: etiqueta arriba en móvil, al lado en escritorio. */
.datos{display:grid; grid-template-columns:minmax(170px,auto) 1fr; gap:.4rem 1.2rem; margin:.2rem 0 0}
.datos dt{color:var(--muted); font-size:.74rem; text-transform:uppercase; letter-spacing:.03em; font-weight:600; align-self:center}
.datos dd{margin:0; font-size:.9rem}
@media (max-width:640px){ .datos{grid-template-columns:1fr; gap:.1rem} .datos dd{margin-bottom:.55rem} }

.pill.riesgo-bajo{color:var(--ok); background:var(--ok-bg)}
.pill.riesgo-medio{color:var(--warn); background:var(--warn-bg)}
.pill.riesgo-alto{color:var(--bad); background:var(--bad-bg)}

/* Semáforo de plazos. Rojo a tres días; los que precluyen avisan a quince,
   porque cuando se pasan no hay arreglo posible. */
.semaforo{display:inline-flex; align-items:center; gap:.35rem; padding:.14rem .6rem; border-radius:999px;
  font-size:.78rem; font-weight:700; white-space:nowrap}
.semaforo::before{content:""; width:7px; height:7px; border-radius:50%; background:currentColor}
.sem-verde{color:var(--ok); background:var(--ok-bg)}
.sem-ambar{color:var(--warn); background:var(--warn-bg)}
.sem-rojo{color:var(--bad); background:var(--bad-bg)}
.sem-vencido{color:#fff; background:var(--bad)}
.sem-cumplido{color:var(--muted); background:var(--surface-2)}
.sem-anulado{color:var(--faint); background:var(--surface-2); text-decoration:line-through}

/* Pantalla de plazos. La fila de acciones va pegada a la suya y sin borde propio:
   son dos filas de la misma cosa, no dos registros. */
.fila-acciones > td{padding-top:0; border-top:none}
.fila-acciones .form-inline:first-child{margin-top:.2rem; padding-top:.6rem}
.pasos{margin:.5rem 0 0; padding-left:1.1rem; color:var(--muted); font-size:.82rem}
.pasos li + li{margin-top:.25rem}
details > summary{cursor:pointer; color:var(--brand); font-size:.85rem}

/* Contadores de la bandeja de plazos: cuatro números que se pulsan para filtrar.
   No cambian con los filtros de la vista — si cambiaran, dejarían de avisar. */
/* Los contadores NO van dentro de una tarjeta: cada uno ES una tarjeta, y se apoyan
   directamente en el fondo de la página. Metidos en un `.card` quedaban cajas casi
   blancas dentro de otra caja blanca — se veía turbio y sin separación. */
.contadores{display:grid; grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));
  gap:.8rem}
.cont{display:flex; flex-direction:column; gap:.15rem; padding:.8rem .9rem; text-decoration:none;
      border:1px solid var(--border); border-radius:var(--radius-sm);
      background:var(--surface); box-shadow:var(--shadow); color:inherit}
.cont:hover{border-color:var(--brand)}
/* La barra de acento venía de `.kpi`, que se ha fundido aquí: era lo único que esa
   primitiva tenía y esta no. */
.cont{position:relative; overflow:hidden}
.cont-barra::before{content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--brand)}
.cont-barra.cont-oro::before{background:var(--gold)}
.cont .sub{font-size:.76rem; color:var(--muted)}
.cont b{font-size:1.6rem; line-height:1.1; font-variant-numeric:tabular-nums}
.cont span{font-size:.8rem; color:var(--muted)}
.cont-mal{background:var(--bad-bg); border-color:color-mix(in srgb,var(--bad) 25%,transparent)}
.cont-mal b{color:var(--bad)}
.cont-ojo{background:var(--warn-bg); border-color:color-mix(in srgb,var(--warn) 25%,transparent)}
.cont-ojo b{color:var(--warn)}
.filtros-activos{display:flex; align-items:center; flex-wrap:wrap; gap:.45rem;
  margin-bottom:.8rem; font-size:.85rem; color:var(--muted)}

/* Chip de filtro activo. Existe para que se vea QUÉ está filtrando sin abrir los
   embudos uno a uno: una tabla con pocos resultados y los filtros escondidos se lee
   como «no hay nada», que es distinto de «no hay nada con esto puesto». */
.chip{display:inline-flex; align-items:center; gap:.35rem; padding:2px 9px;
  border:1px solid var(--border-strong); border-radius:999px;
  background:var(--brand-soft); color:var(--brand-deep);
  font-size:12px; font-weight:600; text-decoration:none; white-space:nowrap}
.chip:hover{text-decoration:none; border-color:var(--brand)}
.chip .x{font-size:13px; line-height:1; opacity:.65}
.chip:hover .x{opacity:1}
/* La ventana de fechas va en dorado: no es un filtro más, es el alcance. */
.chip-alcance{background:var(--gold-soft); color:var(--gold-deep); border-color:var(--gold)}

/* Contador pulsado. El borde y el fondo dicen cuál está aplicado; sin esto se pulsa
   un contador, cambia la tabla y no queda rastro de por qué. */
.cont[aria-pressed="true"]{border-color:var(--brand); box-shadow:inset 0 0 0 1px var(--brand)}
.cont-mal[aria-pressed="true"]{border-color:var(--bad); box-shadow:inset 0 0 0 1px var(--bad)}
.cont-ojo[aria-pressed="true"]{border-color:var(--warn); box-shadow:inset 0 0 0 1px var(--warn)}

/* Grupo segmentado: las ventanas de la agenda son una sola decisión, no cuatro
   botones sueltos, y pegados se lee así. */
.segmentado{display:inline-flex; border:1px solid var(--border-strong); border-radius:999px;
  background:var(--surface); overflow:hidden}
.segmentado a{padding:.4rem .85rem; font-size:.85rem; font-weight:600; color:var(--muted);
  white-space:nowrap; text-decoration:none; border-left:1px solid var(--border)}
.segmentado a:first-child{border-left:none}
.segmentado a:hover{background:var(--brand-tint); text-decoration:none}
.segmentado a.on{background:var(--brand); color:#fff}

/* Aviso pegado a la cabecera del día: la coincidencia se ve donde ocurre, no solo
   en el bloque de arriba. */
.badge-choque{display:inline-flex; align-items:center; gap:.3rem; padding:1px 8px;
  border-radius:999px; background:var(--warn-bg); color:var(--warn);
  font-size:11px; font-weight:700; white-space:nowrap}


.tabla-lista td.num,.tabla-lista th.num{text-align:right; font-variant-numeric:tabular-nums}
.pie-tabla{margin:.7rem 0 0; font-size:.8rem; color:var(--faint)}

@media (max-width:980px){.contadores{grid-template-columns:repeat(2,1fr)}}
@media (max-width:760px){.filtros-linea .form-grid{flex-wrap:wrap}}

/* Diario del expediente: lo último arriba, con la fecha a la izquierda y una línea
   que las une, para que se lea como lo que es — una cronología. */
.cronologia{list-style:none; margin:0; padding:0}
.cronologia li{display:grid; grid-template-columns:6.5rem 1fr; gap:1rem; padding:.9rem 0;
               border-top:1px solid var(--border)}
.cronologia li:first-child{border-top:none; padding-top:0}
.crono-fecha{color:var(--muted); font-size:.85rem; font-variant-numeric:tabular-nums; white-space:nowrap}
.crono-cab{display:flex; align-items:center; gap:.5rem; flex-wrap:wrap}
.crono-cuerpo p{margin:.35rem 0 0; color:var(--muted); font-size:.88rem}
@media (max-width:600px){.cronologia li{grid-template-columns:1fr; gap:.25rem}}

/* Agenda: cada día es un bloque con su cabecera, para que se lea de un vistazo
   cuántas vistas caen juntas. */
.dia + .dia{margin-top:1.4rem}
.dia-cab{display:flex; align-items:baseline; gap:.6rem; padding-bottom:.4rem; margin-bottom:.3rem;
         border-bottom:2px solid var(--border)}
.filtros-linea .form-actions{margin-top:.8rem; padding-top:0; border-top:none}
a.semaforo{text-decoration:none}
a.semaforo:hover{text-decoration:underline}

/* Formulario embebido en una tarjeta (asignar abogado desde la ficha). */
.form-inline{margin-top:1.1rem; padding-top:1.1rem; border-top:1px solid var(--border)}
.form-inline .form-actions{margin-top:.7rem; padding-top:0; border-top:none}

/* Explicación del cálculo de un plazo: pasos cortos, se leen de un vistazo. */
.explicacion{margin:0; padding-left:1.05rem; color:var(--muted); font-size:.82rem}
.explicacion li + li{margin-top:.15rem}

/* Buscador sobre un desplegable largo. Va encima del select, discreto: solo filtra
   lo que ya está, no cambia el dato. */
.buscador{margin-bottom:.35rem; font-size:.85rem; padding:.4rem .6rem}
.buscador::placeholder{color:var(--faint)}

/* Buscador sobre desplegables largos (proyectos, centros, plantilla). El <select>
   original sigue ahí, oculto: sin JavaScript se ve y funciona. */
.combo{position:relative}
.combo-oculto{position:absolute; width:1px; height:1px; opacity:0; pointer-events:none}
.combo-campo{width:100%}
.combo-lista{position:absolute; z-index:30; left:0; right:0; top:100%; margin:.25rem 0 0;
  padding:.25rem; list-style:none; max-height:16rem; overflow-y:auto;
  background:var(--surface); border:1px solid var(--border-strong); border-radius:var(--radius-sm);
  box-shadow:var(--shadow)}
.combo-opcion{padding:.4rem .55rem; border-radius:6px; font-size:.88rem; cursor:pointer}
.combo-opcion:hover,.combo-opcion.on{background:var(--brand-soft); color:var(--brand-ink)}
.combo-mas{padding:.4rem .55rem; font-size:.8rem; color:var(--muted)}

/* ==========================================================================
   Calendario anual
   Vivía dentro de la plantilla, con los colores escritos a mano y un token
   inventado —`--linea`, que nunca existió— cuyo respaldo `#e3e3dc` se usaba
   siempre. Un gris a un paso del `--border` real: suficiente para que la
   pantalla pareciera de otra aplicación sin que se supiera por qué.
   ========================================================================== */
.cal-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); gap:.9rem}
.cal-mes{border:1px solid var(--border); border-radius:var(--radius-sm);
  padding:.6rem; background:var(--surface); box-shadow:var(--shadow)}
.cal-mes h3{margin:0 0 .5rem; font-size:.82rem; text-transform:uppercase;
  letter-spacing:.04em; color:var(--muted)}
.cal-dias{display:grid; grid-template-columns:repeat(7,1fr); gap:2px}
.cal-dias .dow{font-size:.62rem; text-align:center; color:var(--faint); padding-bottom:2px}
.cal-d{aspect-ratio:1; display:flex; align-items:center; justify-content:center;
  font-size:.74rem; border-radius:5px; color:var(--ink); text-decoration:none}
.cal-d.vacio{visibility:hidden}
.cal-d.finde{color:var(--faint)}
.cal-d:hover{outline:1px solid var(--border-strong)}

/* Los tres ámbitos, con los colores de la marca y no con sus valores copiados:
   nacional en salvia, autonómico en dorado, local en dorado claro. */
.cal-d.amb-nacional{background:var(--brand); color:#fff; font-weight:600}
.cal-d.amb-autonomico{background:var(--gold); color:var(--ink); font-weight:600}
.cal-d.amb-local{background:var(--gold-soft); color:var(--ink); font-weight:600}

.leyenda{display:flex; gap:.9rem; flex-wrap:wrap; align-items:center; font-size:.8rem}
.leyenda i{display:inline-block; width:12px; height:12px; border-radius:3px;
  margin-right:5px; vertical-align:-1px}
.leyenda i.amb-nacional{background:var(--brand)}
.leyenda i.amb-autonomico{background:var(--gold)}
.leyenda i.amb-local{background:var(--gold-soft); border:1px solid var(--border)}

/* «Calendario incompleto» es un aviso, y se pinta como los demás avisos. */
.cobertura{border-left:3px solid var(--gold); background:var(--gold-soft);
  padding:.7rem var(--pad); border-radius:var(--radius-sm)}
.cobertura h4{margin:0 0 .25rem; font-size:.86rem}
.cobertura p{margin:.15rem 0; font-size:.82rem; color:var(--muted)}

/* Fila de filtros: los campos se alinean por abajo para que el botón quede a la altura
   de los desplegables, no flotando arriba. Era un `style=` repetido en cada pantalla. */
.form-grid.form-filtros{align-items:end}

/* El estado vacío. Estaba escrito 26 veces como `style="color:var(--muted)"`, que es
   un color, no un estado: por eso ninguna de esas filas tenía aire ni se distinguía de
   un dato de verdad en gris. Una lista vacía es una respuesta, y se lee como tal. */
.vacio{color:var(--muted); font-size:.9rem}
.tabla-lista td.vacio{padding-top:1.4rem; padding-bottom:1.4rem; text-align:center}

/* Cláusula de la invitación. Vivía en la plantilla y usaba `var(--gris)`, otro token
   que nunca existió — y sin respaldo, así que el recuadro se quedaba sin fondo. */
.clausula{background:var(--surface-2); border:1px solid var(--border);
  border-radius:var(--radius-sm); padding:var(--pad); font-size:.85rem;
  color:var(--muted); margin-top:1.25rem; max-height:160px; overflow-y:auto}

/* ---------- horarios ---------- */

/* La semana de un vistazo. En un listado de horarios lo que se compara de una fila a
   otra no son las horas, es la forma: quién trabaja de lunes a viernes y quién los
   siete días. Siete iniciales dicen eso más rápido que cualquier texto.

   Se llama `tira-` y no `semana` porque `fichar.css` ya tiene una `.semana` —el total
   semanal de la PWA— y las dos hojas se cargan juntas en /fichar. */
.tira-semana{display:flex; gap:.2rem}
.tira-dia{display:grid; place-items:center; width:1.55rem; height:1.55rem; border-radius:var(--radius-sm);
  font-size:.72rem; font-weight:700; text-transform:uppercase; cursor:default}
.tira-dia.on{background:var(--brand-soft); color:var(--brand-deep)}
.tira-dia.off{background:var(--surface-2); color:var(--faint)}

/* La semana como se rellena: una fila por día y dos tramos, para la jornada partida.
   Los días libres se dejan en blanco, así que la tabla se lee por lo que tiene puesto. */
.tabla-semana th[scope="row"]{white-space:nowrap; font-weight:600; color:var(--muted)}
.tramo{display:flex; align-items:center; gap:.4rem}
.tramo input[type="time"]{width:auto; min-width:6.5rem; margin:0}
.tramo span{color:var(--faint)}

/* ---------- mi jornada (el mes del empleado) ---------- */

/* Navegador de mes. Es el hermano de escritorio del `.dnav` de la PWA de fichar: la
   misma idea —‹ mes ›— pero con enlaces en vez de botones, porque aquí el mes va en
   la URL y la página la pinta el servidor. */
/* Envuelve: en 275px útiles no caben las dos flechas, el rótulo del mes y «Mes
   actual». Antes no se notaba porque el botón salía recortado a 32px; al devolverle su
   ancho, el desborde que el recorte tapaba se hizo visible. */
.mesnav{display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; justify-content:flex-end}
/* Ancho FIJO y no mínimo: con `min-width`, «Septiembre 2026» ensanchaba el selector y
   movía lo que tuviera al lado cada vez que se cambiaba de mes. */
.mesnav .cual{width:11.5rem; max-width:100%}   /* no min(…,100%): es circular y el mes se salía */
/* `:not(.btn)`: la regla del círculo de 32px estaba alcanzando también a «Mes actual»,
   que es un enlace con clase de boton, y le recortaba el texto a la mitad. */
.mesnav a:not(.btn),.mesnav span.tope{width:32px; height:32px; flex:none; border-radius:999px;
  border:1px solid var(--border); background:var(--surface); color:var(--brand-deep);
  font-size:1.15rem; line-height:1; display:grid; place-items:center; font-weight:600}
.mesnav a:not(.btn):hover{border-color:var(--brand); text-decoration:none}
.mesnav span.tope{opacity:.35}   /* no hay mes siguiente que enseñar */
.mesnav .cual{text-align:center; font-weight:700; color:var(--brand-deep);
  font-size:.86rem; text-transform:uppercase; letter-spacing:.05em}
.mesnav .btn{margin-left:.2rem; flex:none; white-space:nowrap}
/* EN UNA FILA. Con el selector de mes al lado del título, las acciones se quedaban con
   400px: el mes iba arriba, «Mes actual» debajo y el PDF flotando entre los dos. El mes,
   «Mes actual» y el PDF son una sola cosa —qué mes miro y qué hago con él— y van en una
   línea; lo que cede es el título, cuyo párrafo se parte en más renglones. Si ni así
   caben, la fila entera baja debajo del título, pero sigue siendo una fila. En el móvil
   sí se parte: no hay ancho para otra cosa. */
.pagehead:has(.mesnav) > div:first-child{flex:1 1 18rem; min-width:0}
.pagehead .actions:has(> .mesnav),.pagehead .mesnav{flex-wrap:nowrap}
/* El mes no cede: encogido, «Septiembre 2026» se partía en dos renglones. */
.pagehead .mesnav .cual{flex:none}
/* En el móvil, el selector ocupa su línea y los botones caen juntos debajo, a la izquierda. */
@media (max-width:640px){
  .pagehead .actions:has(> .mesnav){flex-wrap:wrap; margin-left:0; justify-content:flex-start}
  .pagehead .actions > .mesnav{flex-basis:100%; justify-content:flex-start}
}

/* El ritmo vertical de la página sale del layout, no de márgenes sueltos por bloque:
   los avisos aparecen y desaparecen según el mes, y con márgenes propios el hueco se
   duplicaría o se quedaría corto según lo que hubiera ese día. */
.jornada{display:flex; flex-direction:column; gap:var(--pad)}
.jornada .procedencia{margin:0}

/* El día en la tabla del mes. El fin de semana y el festivo se distinguen del resto
   por el fondo, no por el texto: si hubiera que leer cada fila para saber cuáles no
   contaban, la tabla no serviría para lo que sirve, que es mirarla por encima. */
.tabla-mes td.dia-fecha{white-space:nowrap}
.tabla-mes .dsem{color:var(--muted); font-size:.78rem; text-transform:uppercase; margin-left:.35rem}
.tabla-mes tr.descanso{background:var(--surface-2)}
/* Tablero de Campo: se está trabajando una parada que no es la primera de la columna. */
.campo-fuera{margin:.2rem 0 -.2rem; color:var(--gold-deep); font-weight:600}
/* El día al que se llega con un ancla, a la vista y sin que lo tape la cabecera. */
.tabla-mes tr:target{outline:2px solid var(--gold); outline-offset:-2px; scroll-margin-top:6rem}
.tabla-mes tr.festivo{background:var(--gold-soft)}
.tabla-mes tr.festivo .motivo{color:var(--gold-deep); font-size:.76rem}
/* Los tramos del día. Se apilan en vez de ponerse en fila: quien tiene jornada
   partida o entra y sale tres veces necesita verlos uno debajo de otro, y así la
   columna no crece a lo ancho hasta romper la tabla. */
.tabla-mes .tramos{display:flex; flex-direction:column; gap:.1rem}
.tabla-mes .tramo-h{white-space:nowrap}
.tabla-mes .abierto{color:var(--warn); font-weight:600}

.tabla-mes .falta{color:var(--bad); font-variant-numeric:tabular-nums}
.tabla-mes .sobra{color:var(--ok); font-variant-numeric:tabular-nums}

/* Detalle de las marcas de un día (registro de RRHH). Va plegado con <details>: un
   mes son doscientas marcas y nadie las lee todas, se abre el día del que se discute.
   Sin JavaScript — el navegador ya sabe hacer esto. */
.marcas summary{cursor:pointer; font-size:.82rem; color:var(--brand-deep); font-weight:600;
  white-space:nowrap; list-style-position:inside}
.marcas summary:hover{text-decoration:underline}
.marcas-lista{list-style:none; margin:.4rem 0 0; padding:0; display:flex; flex-direction:column; gap:.2rem}
.marcas-lista li{display:flex; align-items:center; gap:.45rem; flex-wrap:wrap; font-size:.82rem}
.marcas-lista .hora{font-weight:700; color:var(--ink)}
.marcas-lista .que{color:var(--muted)}
/* Las coordenadas son un dato de apoyo, no la fila: se leen si se buscan. */
.marcas-lista .ubi{font-size:.74rem; color:var(--faint); font-variant-numeric:tabular-nums; display:inline-flex; align-items:baseline; gap:.4rem; flex-wrap:wrap}
/* La dirección es lo que se lee; la coordenada, lo que vale. Van las dos, y en ese orden. */
.marcas-lista .ubi .dir{font-size:.8rem; color:var(--ink)}
.marcas-lista .ubi .coord{color:inherit; text-decoration:underline; text-decoration-style:dotted; text-underline-offset:2px}
.marcas-lista .ubi .coord:hover,.marcas-lista .ubi .coord:focus-visible{color:var(--ink)}

/* Anotar a mano la marca que falta. Va plegado y solo en el día que lo necesita: un
   formulario abierto en las treinta filas es una invitación a tocar lo que no
   está roto. */
.anotar{margin-top:.4rem}
.anotar summary{cursor:pointer; font-size:.8rem; color:var(--warn); font-weight:600}
.anotar form{display:flex; flex-wrap:wrap; align-items:flex-end; gap:.5rem;
  margin-top:.5rem; padding:.6rem; background:var(--warn-bg); border-radius:var(--radius-sm)}
.anotar label{display:flex; flex-direction:column; gap:.15rem; font-size:.76rem; color:var(--muted)}
.anotar input{margin:0; width:auto}
.anotar input[type="text"]{min-width:14rem}
.anotar .btn{width:auto; margin:0}

/* Marca anotada por una persona, no fichada. Va en dorado —el color de acento de la
   marca— porque no es un error ni un aviso: es un dato de otra procedencia. */
.pill.oro{background:var(--gold-soft); color:var(--gold-deep)}

/* Responder a un informe: comentario y las dos salidas, en una línea. Validar y
   devolver son el mismo gesto con distinto signo, así que van juntos y no en dos
   sitios de la pantalla. */
.responder{display:flex; flex-wrap:wrap; align-items:flex-end; gap:.5rem; margin-top:.8rem}
.responder label{display:flex; flex-direction:column; gap:.15rem; flex:1; min-width:16rem;
  font-size:.76rem; color:var(--muted)}
.responder input{margin:0}
.responder .btn{width:auto; margin:0}

/* Lienzo de firma. `touch-action:none` no es un detalle: sin eso, arrastrar el dedo
   para firmar hace scroll en el móvil, que es justo donde se va a firmar. */
.firma-lienzo{display:block; width:100%; height:180px; touch-action:none; cursor:crosshair;
  background:var(--surface); border:2px dashed var(--border-strong); border-radius:var(--radius-sm)}
.firma-lienzo:focus-visible{outline:2px solid var(--brand); outline-offset:2px}

/* Un mes cerrado sin un solo fichaje. No es un error —cerrarlo es legítimo— pero casi
   siempre significa que se cerró el mes equivocado, así que se dice en ámbar. */
.aviso-cero{color:var(--warn)}


/* ---------- agenda: la lista de vistas ----------
   Era una tabla de una fila y sin un solo encabezado: se anunciaba como «tabla, cinco
   columnas» y se leían cinco celdas sueltas. Como lista, cada dato lleva su rótulo
   escrito y además cabe en un móvil sin desplazar, cosa que cinco columnas no hacen. */
.vista-lista{list-style:none; margin:0; padding:0}
.vista-lista > li{display:grid; grid-template-columns:5.5rem 1fr auto; gap:.2rem 1rem;
  align-items:start; padding:.85rem var(--pad); border-top:1px solid var(--border)}
.vista-lista > li:first-child{border-top:0}
.vista-hora{font-size:1.15rem; font-weight:700; font-variant-numeric:tabular-nums;
  color:var(--brand-deep); line-height:1.2}
.vista-hora .sub{font-size:.78rem; font-weight:600; color:var(--faint); display:block}
.vista-que{font-weight:600}
.vista-datos{display:flex; flex-wrap:wrap; gap:.15rem 1.1rem; margin-top:.3rem;
  font-size:.84rem; color:var(--muted)}
.vista-datos b{color:var(--ink); font-weight:600}
.vista-avisos{display:flex; flex-direction:column; gap:.3rem; align-items:flex-end}
/* En móvil no hay tres columnas que valgan: la hora manda y lo demás va debajo. */
@media (max-width:640px){
  .vista-lista > li{grid-template-columns:1fr; gap:.35rem}
  .vista-avisos{align-items:flex-start}
}

/* ---------- dianas de 24x24 (WCAG 2.2, 2.5.8) ----------
   «Cerrar sesion» medían 18x24 y el enlace de ordenar una columna se quedaba corto de
   alto. No se agranda el icono: se agranda la zona que responde al dedo. */
.side .foot .salir{display:inline-flex; align-items:center; justify-content:center;
  min-width:24px; min-height:24px; padding:2px}
.colsort{min-height:24px; min-width:24px}
/* Los enlaces de la agenda y los semáforos de estado son destinos sueltos, no texto
   dentro de una frase: les toca la medida entera. */
.vista-datos a,.vista-avisos a,a.semaforo{display:inline-flex; align-items:center; min-height:24px}
/* En una tabla de datos un enlace no es texto dentro de una frase: es un destino, y le
   toca la medida entera. La fila crece unos pocos píxeles y se lee igual de densa. */
td a{display:inline-flex; align-items:center; min-height:24px}

/* Los cuatro grupos del cierre de un servicio. El encabezado tiene que pesar más que el
   de cada hito, o los nueve hitos se leen como una lista plana otra vez. */
.sh-grupo{font-size:1.05rem;font-weight:700;color:var(--brand);margin:1.6rem 0 .15rem;
    padding-bottom:.3rem;border-bottom:2px solid var(--gold)}
.sh-grupo:first-of-type{margin-top:.6rem}
.sub-grupo{margin:0 0 .7rem;color:var(--muted)}

/* El resultado de tomar la posición. Va debajo del botón y se lee en voz alta al cambiar,
   así que también tiene que distinguirse sin depender solo del color. */
.accion-suelta{margin-top:.9rem}
.estado-posicion{margin:.5rem 0 0}
.estado-posicion.bien{color:var(--ok)}
.estado-posicion.ojo{color:var(--gold-deep)}
.estado-posicion.malo{color:var(--bad)}

/* Una opción con su explicación debajo. En línea, el nombre y la ayuda se leen como una
   sola frase y hay que releer para saber cuál es cuál. */
.checkbox .opcion{display:block}
.checkbox .opcion .sub{display:block;margin-top:.15rem}

/* El aviso de días sin cerrar, en la pantalla de fichar. Va antes del botón y con peso
   propio: quien lo arrastra es el único que sabe a qué hora se fue, y hasta ahora era el
   único al que nadie se lo decía. */
.dias-abiertos{margin:1rem auto 0; max-width:26rem; padding:1rem 1.1rem;
    background:var(--warn-bg); border:1px solid var(--warn); border-radius:var(--radius)}
.dias-abiertos h2{margin:0; font-size:1.05rem; color:var(--warn)}
.dias-abiertos .sub{margin:.35rem 0 0}
.dia-abierto{margin-top:.9rem; padding-top:.9rem; border-top:1px solid var(--warn)}
.dia-abierto:first-of-type{border-top:0; padding-top:.4rem}
.dia-cab{display:flex; gap:.6rem; align-items:baseline; flex-wrap:wrap}
.dia-cierre{display:flex; gap:.6rem; align-items:end; flex-wrap:wrap; margin-top:.5rem}
.dia-cierre label{display:block; font-size:.85rem; font-weight:600}
.dia-cierre input[type=time]{min-height:44px; padding:.5rem .6rem;
    border:1px solid var(--border-control); border-radius:var(--radius-sm)}
.dia-cierre .btn{min-height:44px}
.nota-manual{margin:.55rem 0 0; font-size:.82rem}

/* ---------- campo: el tablero de reparto ----------
   Una columna por técnico más la de "sin asignar". Se usa de pie y con una mano
   —quien reparte lo hace desde la furgoneta—, así que las columnas se apilan
   solas y todo lo que se pulsa tiene tamaño de dedo. */
/* Una fila que se desplaza a lo ancho, no una rejilla que parte las columnas en dos
   filas: con tres técnicos y la pantalla justa, la tercera columna caía debajo de la
   primera y dejaba dos cosas distintas en el mismo sitio. Una cola por técnico se lee
   en horizontal o no se lee. */
.campo-cols{display:flex; gap:1rem; align-items:flex-start; overflow-x:auto; padding-bottom:.4rem}
.campo-col{flex:1 0 280px; max-width:460px;
    background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
    box-shadow:var(--shadow); padding:.85rem}
/* En el móvil se apilan, que es como se reparte desde la furgoneta. */
@media (max-width:720px){
    .campo-cols{display:block; overflow-x:visible}
    .campo-col{max-width:none; margin-bottom:1rem}
}
.campo-colcab{display:flex; align-items:center; gap:.5rem; margin-bottom:.7rem}
.campo-colcab h2{margin:0; font-size:.95rem; overflow-wrap:anywhere}
.campo-colcab .pill{margin-left:auto; flex:none}

.campo-tarea{border:1px solid var(--border); border-radius:var(--radius-sm); background:var(--surface-2);
    padding:.6rem .7rem; margin-bottom:.6rem}
.campo-tarea:last-child{margin-bottom:0}
.campo-tarea h3{margin:.35rem 0 .2rem; font-size:.95rem; overflow-wrap:anywhere}
.campo-tarea h3 a{color:inherit; text-decoration:none}
.campo-tarea h3 a:hover{color:var(--brand); text-decoration:underline}
.campo-tarea .sub{margin:0; font-size:.8rem}
.campo-tarea-cab{display:flex; align-items:center; gap:.35rem; flex-wrap:wrap}
.campo-limite{margin-left:auto; font-size:.8rem; font-weight:700; color:var(--muted)}
/* Que el encargo entrara por WhatsApp no es un detalle de color: es el dato del que
   sale el informe de por dónde llega el trabajo. Se ve sin tener que abrir nada. */
.campo-origen{color:var(--gold-deep); font-weight:600}
.campo-motivo{color:var(--bad); font-weight:600}

.campo-acciones{display:flex; align-items:center; gap:.2rem; margin-top:.45rem}
/* `.accion-inline button` ya dice `margin:0`, pero pierde por especificidad contra
   `form > button[type=submit]`, que mete 1.5rem de separación por arriba. Aquí eso
   abría un hueco vacío en cada tarjeta. Se acota a Campo a propósito: la regla de
   base afecta a doce pantallas más y arreglarla ahí es otra conversación. */
.campo-acciones .accion-inline button{margin:0}
.campo-acciones .iconbtn{width:44px; height:44px}
.campo-acciones .iconbtn svg{width:20px; height:20px}
.campo-quien{margin-left:auto; font-size:.75rem}

/* Asignar y cancelar piden escribir, así que van plegados: con seis tarjetas en
   pantalla, desplegados dejarían la cola ilegible. */
.campo-plegable{margin-top:.4rem; border-top:1px solid var(--border); padding-top:.4rem}
.campo-plegable summary{cursor:pointer; font-size:.82rem; font-weight:600; color:var(--brand-deep);
    padding:.3rem 0; min-height:24px}
.campo-plegable summary:hover{color:var(--brand)}
.campo-plegable form{display:flex; flex-direction:column; gap:.4rem; margin-top:.4rem}
.campo-plegable select,.campo-plegable input[type=text]{min-height:44px}
.campo-plegable .btn{min-height:44px; width:100%}
.campo-plegable small{color:var(--muted); font-size:.75rem; margin:-.2rem 0 0}

/* Los datos sueltos del alta, plegados en su sección: casi nunca hacen falta, y el alta
   tiene que seguir cabiendo en una pantalla de móvil. Cada fila es un dato. */
.campo-extra > summary{list-style:none}
.campo-extra > summary::-webkit-details-marker{display:none}
.campo-extra > summary::before{content:"+ "}
.campo-extra[open] > summary::before{content:"− "}
.campo-extra-fila + .campo-extra-fila{margin-top:.7rem; padding-top:.2rem; border-top:1px dashed var(--border)}
.campo-extra-fila .field.check{justify-content:flex-end; margin-top:0; padding-bottom:.55rem}

/* El informe de por dónde entra el trabajo: una barra por canal. Lo que entra por fuera
   va en dorado, el acento, porque es lo que se viene a mirar. */
.campo-pct{display:flex; align-items:center; gap:.6rem}
.campo-barra{display:block; flex:1; max-width:14rem; height:8px; border-radius:4px; background:var(--surface-2);
    border:1px solid var(--border); overflow:hidden}
.campo-barra > span{display:block; height:100%; background:var(--brand)}
.campo-barra.oro > span{background:var(--gold)}

/* Las fechas del archivo, en la cabecera de la página. */
.campo-fechas{align-items:center; flex-wrap:wrap; gap:.5rem}
.campo-fechas label{display:inline-flex; align-items:center; gap:.4rem; font-size:.82rem; color:var(--muted)}
.campo-fechas input[type=date]{width:auto; min-height:38px}

/* Campo · arqueos: lo declarado en la máquina y lo contado en la oficina, lado a lado. */
.arqueo .arqueo-declarado{margin:.5rem 0 .7rem; padding:.5rem .7rem; background:var(--surface); border-radius:var(--radius-sm)}
.arqueo-form .form-grid{margin-top:0}
.arqueo-form .btn{min-height:44px; margin-top:.4rem}

/* Campo · registro de activos: la carga por Excel plegada arriba, y la cola viva en la ficha. */
.campo-carga > summary{cursor:pointer; padding:.8rem 1rem; font-weight:600; color:var(--brand-deep); list-style:none}
.campo-carga > summary::-webkit-details-marker{display:none}
.campo-carga > summary::before{content:"+ "}
.campo-carga[open] > summary::before{content:"− "}
.campo-carga > .bd{padding:0 1rem 1rem}
.campo-carga-form{display:flex; gap:.6rem; align-items:center; flex-wrap:wrap}
.campo-carga-form .btn{margin:0}
.activo-pendientes{margin:.4rem 0 0; padding-left:1.1rem}
.activo-pendientes li{margin:.2rem 0}

/* Campo · enviar un parte desde el archivo: el sobre despliega el formulario en la fila. */
.campo-enviar{position:relative}
.campo-enviar > summary{list-style:none; cursor:pointer}
.campo-enviar > summary::-webkit-details-marker{display:none}
.campo-enviar-form{margin-top:.4rem; min-width:16rem; padding:.7rem .8rem;
    background:var(--surface-2); border:1px solid var(--border); border-radius:var(--radius-sm);
    display:flex; flex-direction:column; gap:.5rem; text-align:left}
/* En bloque y no flotando: la tabla va dentro de un contenedor con overflow, y un
   desplegable en absoluto quedaría recortado. La fila crece; es lo que toca. */
.campo-enviar{display:block}
.campo-enviar-form label{display:flex; flex-direction:column; gap:.2rem; font-size:.8rem; font-weight:600; color:var(--muted)}
.campo-enviar-form input,.campo-enviar-form textarea{font-weight:400; min-height:38px}
.campo-enviar-form .btn{margin:0; min-height:40px}

/* Firma con el nombre: el texto exacto al que se da conformidad, y los bloques que alterna firma-metodo.js. */
.conformidad{margin:.6rem 0 .8rem; padding:.7rem .8rem; border-left:3px solid var(--brand); background:var(--surface-2); font-size:.95rem; line-height:1.45}
fieldset.form-sec > legend.sh{padding:0; float:left; width:100%; margin-bottom:.5rem}
fieldset.form-sec > .checkbox{display:flex; align-items:center; gap:.5rem; min-height:40px}

/* Avisos: el timbre de la cabecera y la bandeja. */
.campana{position:relative; display:inline-flex; align-items:center; justify-content:center; width:40px; height:40px;
    border-radius:50%; color:var(--muted); text-decoration:none; flex:none}
.campana:hover{background:var(--brand-soft); color:var(--brand-deep); text-decoration:none}
.campana.con-avisos{color:var(--brand-deep)}
.campana-n{position:absolute; top:2px; right:0; min-width:18px; height:18px; padding:0 5px; border-radius:9px;
    background:var(--warn); color:#fff; font-size:.7rem; font-weight:700; line-height:18px; text-align:center}
.avisos-lista{list-style:none; margin:0; padding:0}
.avisos-lista li + li{border-top:1px solid var(--border)}
.avisos-lista a{display:flex; align-items:flex-start; gap:.7rem; padding:.75rem 1rem; color:inherit; text-decoration:none}
.avisos-lista a:hover{background:var(--surface-2); text-decoration:none}
.avisos-punto{flex:none; width:9px; height:9px; margin-top:.45rem; border-radius:50%; background:var(--warn)}
.avisos-lista li.leido .avisos-punto{background:transparent; border:1px solid var(--border)}
.avisos-lista li.leido b{font-weight:500; color:var(--muted)}
.avisos-texto{flex:1; min-width:0; display:flex; flex-direction:column; gap:.15rem}
.avisos-texto b{overflow-wrap:anywhere}
.avisos-lista time{flex:none; font-size:.78rem}

/* --- Solicitudes (14/09/2026): lo poco que el formulario de alta y su ficha necesitan
   y no había. El asterisco de obligatorio, la fila de botones de RRHH, la lista de
   adjuntos y el hilo. Todo lo demás son las clases de formulario de siempre. --- */
.req{color:var(--bad); margin-left:.15rem}
.acciones-fila{display:flex; flex-wrap:wrap; gap:.5rem; margin:.4rem 0 .8rem}
.lista-adjuntos{margin:.3rem 0 .8rem; padding-left:1.1rem}
.lista-adjuntos li{margin:.2rem 0}
.hilo{margin:.3rem 0 .8rem; padding-left:1.1rem}
.hilo li{margin:.35rem 0; font-size:.9rem}
