/* components.css — base y componentes de buscalicitaciones.com (Fase 2).
 *
 * Todo sale de tokens.css. Cada componente tiene su macro en app/templates/_componentes.html y su muestra en
 * /_estilo. Orden: 0 base · 1 utilidades · 2 iconos · 3 botones · 4 etiquetas · 5 pistas (popovers) · 6 importe ·
 * 7 KPI · 8 cabecera de entidad · 9 lista de las N primeras · 10 tabla adaptable · 11 tarjeta de resultado ·
 * 12 migas · 13 paginación · 14 estado vacío · 15 aviso · 16 procedencia · 17 gráficos · 18 cajón y hoja ·
 * 19 campos y combobox · 20 chips de filtros · 21 pestañas · 22 esqueleto de carga · 23 copiar y avisos vivos.
 */

/* ════════ 0. Base ════════════════════════════════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }

html {
    font-family: var(--fuente-sans);
    font-size: 16px;
    line-height: var(--lh-texto);
    color: var(--color-texto);
    background: var(--color-fondo);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    /* El destello al tocar (Android y iOS), suave y en el azul de la identidad: el gris azulado de serie tapaba la tarjeta */
    -webkit-tap-highlight-color: rgba(31, 64, 104, 0.12);
}

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--color-fondo);
    overflow-x: hidden;
}

h1, h2, h3, h4 { margin: 0; color: var(--color-texto-fuerte); }
h1, h2 { font-family: var(--fuente-serif); font-weight: var(--peso-normal); letter-spacing: -0.015em; line-height: var(--lh-titulo); }
h3, h4 { font-family: var(--fuente-sans); font-weight: var(--peso-fuerte); line-height: var(--lh-ajustada); }
p { margin: 0 0 var(--sp-3); }

a {
    color: var(--color-acento);
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
    text-underline-offset: 0.18em;
    text-decoration-thickness: 1px;
    transition: color var(--mov-rapido), text-decoration-color var(--mov-rapido);
}
a:hover { color: var(--color-acento-hover); text-decoration-color: currentColor; }

:focus-visible { outline: 2px solid var(--foco-color); outline-offset: 2px; border-radius: 2px; }
:focus:not(:focus-visible) { outline: none; }

::selection { background: #d6e2f0; color: var(--color-texto-fuerte); }

mark {
    background: var(--color-resalte);
    color: inherit;
    padding: 0 0.1em;
    border-radius: 2px;
    font-weight: var(--peso-medio);
}

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
img, svg { max-width: 100%; }
code, kbd { font-family: var(--fuente-mono); font-size: 0.92em; }
hr { border: 0; border-top: 1px solid var(--color-borde); margin: var(--sp-6) 0; }

/* ════════ 1. Utilidades ══════════════════════════════════════════════════════════════════════════════════ */
.solo-lectores {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0;
}

.contenedor {
    width: 100%;
    max-width: var(--ancho-pagina);
    margin: 0 auto;
    padding: 0 var(--margen-der) 0 var(--margen-izq);
}

.num, .cifra { font-variant-numeric: tabular-nums; }

/* Identificadores: la única monoespaciada de la web */
.ident {
    font-family: var(--fuente-mono);
    font-size: 0.9em;
    font-weight: var(--peso-normal);
    letter-spacing: 0;
    overflow-wrap: anywhere;
}

.rotulo {
    font-size: var(--rotulo-tam);
    font-weight: var(--rotulo-peso);
    letter-spacing: var(--rotulo-espaciado);
    text-transform: uppercase;
    color: var(--color-texto-2);
    line-height: var(--lh-ajustada);
}

.texto-2 { color: var(--color-texto-2); }
.texto-3 { color: var(--color-texto-3); }
.nota { font-size: var(--fs-13); color: var(--color-texto-2); line-height: var(--lh-texto); }

/* Sección con título en serif y el filete azul de la identidad */
.seccion { margin-top: var(--sp-12); }
.seccion-titulo {
    font-size: var(--fs-28);
    position: relative;
    padding-bottom: var(--sp-2);
    margin-bottom: var(--sp-4);
}
.seccion-titulo::after {
    content: "";
    position: absolute;
    left: 0; bottom: 0;
    width: 2.5rem; height: 2px;
    background: var(--color-acento);
}
.seccion-entradilla { color: var(--color-texto-2); font-size: var(--fs-14); max-width: 72ch; margin: 0 0 var(--sp-4); }
.subtitulo { font-size: var(--fs-18); margin: 0 0 var(--sp-3); }

@media (max-width: 640px) {
    .seccion { margin-top: var(--sp-10); }
    .seccion-titulo { font-size: var(--fs-22); }
}

/* Zonas que se pulsan: los enlaces de tablas, listas, tarjetas y pies miden al menos 24 px de alto (WCAG 2.5.8); en el
   texto corrido no hace falta (excepción de la norma) */
.tabla td a, .tabla th a, .lista-top-nombre a, .lista-contratos a, .tarjeta-titulo a, a.parte-nombre, .procedencia a,
.ficha-mas a, .filtro-limpiar, .enlace-origen, .datos dd a, .caja-ayuda a, .pagina-error-enlaces a,
.parte-tarjeta .parte-nombre a, .borme a {
    display: inline-block;
    min-height: var(--tactil-min);
    padding-block: 2px;
}
.tabla td a { min-width: var(--tactil-min); }
a.kpi-valor { min-height: var(--tactil-min); }
.filtro-limpiar { display: inline-flex; align-items: center; }

/* ════════ 2. Iconos (un solo sprite: /static/iconos.svg) ════════════════════════════════════════════════ */
.icono {
    width: 1.1em;
    height: 1.1em;
    flex-shrink: 0;
    display: inline-block;
    vertical-align: -0.18em;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    overflow: visible;
}
.icono-s { width: 0.95em; height: 0.95em; }
.icono-l { width: 1.4em; height: 1.4em; }

/* ════════ 3. Botones ═════════════════════════════════════════════════════════════════════════════════════ */
.boton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    min-height: 40px;
    padding: 0 var(--sp-4);
    border: 1px solid transparent;
    border-radius: var(--radio-m);
    font-size: var(--fs-14);
    font-weight: var(--peso-medio);
    line-height: 1.2;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--mov-rapido), border-color var(--mov-rapido), color var(--mov-rapido), box-shadow var(--mov-rapido);
}
.boton:hover { text-decoration: none; }
.boton:focus-visible { outline: 2px solid var(--foco-color); outline-offset: 2px; }
.boton[disabled], .boton[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }

.boton-primario { background: var(--color-acento); color: var(--color-sobre-acento); }
.boton-primario:hover { background: var(--color-acento-hover); color: var(--color-sobre-acento); }

.boton-secundario { background: var(--color-superficie); color: var(--color-acento); border-color: var(--color-borde-control); }
.boton-secundario:hover { background: var(--color-acento-suave); color: var(--color-acento); border-color: var(--color-acento); }

.boton-fantasma { background: transparent; color: var(--color-texto-2); }
.boton-fantasma:hover { background: var(--color-fondo-hundido); color: var(--color-texto-fuerte); }

.boton-peque { min-height: 32px; padding: 0 var(--sp-3); font-size: var(--fs-13); }
.boton-icono { width: 40px; padding: 0; }
.boton-peque.boton-icono { width: 32px; }

@media (pointer: coarse) {
    .boton, .boton-peque { min-height: var(--tactil); }
    .boton-icono, .boton-peque.boton-icono { width: var(--tactil); }
}

.acciones { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }

/* ════════ 4. Etiquetas ═══════════════════════════════════════════════════════════════════════════════════ */
.etiqueta {
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
    min-height: 24px;
    padding: 0 var(--sp-2);
    border: 1px solid var(--color-borde-fuerte);
    border-radius: var(--radio-pildora);
    background: var(--color-superficie);
    color: var(--color-texto-2);
    font-size: var(--fs-12);
    font-weight: var(--peso-medio);
    line-height: 1.3;
    white-space: nowrap;
    vertical-align: middle;
}
.etiqueta .icono { width: 1em; height: 1em; }

.etiqueta-neutra { background: var(--color-fondo-calido); border-color: var(--color-borde); color: var(--color-texto-2); }
.etiqueta-fuente { background: var(--color-acento-suave); border-color: var(--color-acento-borde); color: var(--color-acento); }
.etiqueta-pyme { background: var(--marca-pyme-fondo); border-color: var(--marca-pyme-borde); color: var(--marca-pyme); }
.etiqueta-menor { background: var(--marca-menor-fondo); border-color: var(--marca-menor-borde); color: var(--marca-menor); }
.etiqueta-excluido { background: var(--calidad-excluido-fondo); border-color: var(--calidad-excluido-borde); color: var(--calidad-excluido); }
.etiqueta-repetido { background: var(--calidad-repetido-fondo); border-color: var(--calidad-repetido-borde); color: var(--calidad-repetido); }
.etiqueta-corregido { background: var(--calidad-corregido-fondo); border-color: var(--calidad-corregido-borde); color: var(--calidad-corregido); }
.etiqueta-iva { background: var(--calidad-iva-fondo); border-color: var(--calidad-iva-borde); color: var(--calidad-iva); }
.etiqueta-sin-dato {
    background: var(--calidad-sin-dato-fondo);
    border-color: var(--calidad-sin-dato-borde);
    border-style: dashed;
    color: var(--calidad-sin-dato);
}
.etiqueta-persona { background: var(--color-fondo-hundido); border-color: var(--color-borde-fuerte); color: var(--color-texto-2); }
.etiqueta-apariciones { background: var(--marca-apariciones-fondo); border-color: var(--marca-apariciones-borde); color: var(--marca-apariciones); }
a.etiqueta-apariciones:hover { border-color: var(--marca-apariciones); color: var(--marca-apariciones); text-decoration: none; }
.etiqueta-bruto { background: var(--color-aviso-fondo); border-color: var(--color-aviso-borde); color: var(--color-aviso); text-transform: uppercase; letter-spacing: var(--rotulo-espaciado); }

/* ════════ Conmutador de la vista: «Sin duplicados» | «Todas las fuentes» (paso 3b). Dos enlaces, sin JS ════════ */
.cuenta { display: inline-flex; border: 1px solid var(--color-borde-control); border-radius: var(--radio-pildora); overflow: hidden; background: var(--color-superficie); }
.cuenta-opcion { display: inline-flex; align-items: center; min-height: 32px; padding: 0 var(--sp-3); font-size: var(--fs-13); font-weight: var(--peso-medio); color: var(--color-texto-2); text-decoration: none; white-space: nowrap; }
.cuenta-opcion + .cuenta-opcion { border-left: 1px solid var(--color-borde-control); }
.cuenta-opcion:hover { color: var(--color-acento); background: var(--color-fondo-hundido); text-decoration: none; }
.cuenta-opcion[aria-current] { background: var(--color-acento); color: var(--color-sobre-acento); }
.cuenta-opcion:focus-visible { outline: 2px solid var(--color-acento); outline-offset: -2px; }
@media (pointer: coarse) { .cuenta-opcion { min-height: var(--tactil); } }
.cifras-cabeza { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); align-items: center; justify-content: space-between; margin-bottom: var(--sp-3); }
.cifras-cabeza .seccion-titulo, .cifras-cabeza h2, .cifras-cabeza h3 { margin: 0; }
.nota-cuenta { margin: var(--sp-3) 0 0; font-size: var(--fs-13); color: var(--color-texto-2); line-height: var(--lh-ajustada); }
.nota-cuenta strong { color: var(--color-texto); font-variant-numeric: tabular-nums; }
.franja-bruto { display: flex; gap: var(--sp-2); align-items: flex-start; margin: 0 0 var(--sp-3); padding: var(--sp-2) var(--sp-3); border: 1px solid var(--color-aviso-borde); border-radius: var(--radio-m); background: var(--color-aviso-fondo); color: var(--color-aviso); font-size: var(--fs-14); }
.franja-bruto .icono { flex: none; margin-top: 0.15em; }
.franja-bruto a { color: inherit; text-decoration: underline; }
.kpi-valor .etiqueta-bruto { margin-left: var(--sp-2); font-size: var(--fs-12); vertical-align: middle; }
/* La etiqueta «bruto» y la flecha de un KPI que enlaza, juntas: si no caben junto a la cifra, bajan a su línea, dentro de
   su celda. Antes la cifra, la etiqueta y la flecha iban en una línea que no se partía, y en la portada a 1.280 y 1.440 px
   la flecha de «27.355.531 BRUTO» caía en la columna siguiente, pegada a «1,78 billones €» (el propietario, 6-oct) */
a.kpi-valor { flex-wrap: wrap; row-gap: var(--sp-1); max-width: 100%; }
.kpi-cola { display: inline-flex; align-items: center; gap: var(--sp-2); }
.kpi-cola .etiqueta-bruto { margin-left: 0; }

.etiquetas { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }

/* ════════ 5. Pistas: explicaciones con clic, toque, foco y ratón (sustituyen a title) ═══════════════════ */
.pista-envoltorio { position: relative; display: inline-flex; vertical-align: middle; }

/* :where(): la base del botón no pesa; si es una etiqueta, mandan los colores de la etiqueta */
:where(.pista-boton) {
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-texto-3);
    font-size: inherit;
    line-height: 1.3;
    cursor: pointer;
    min-width: var(--tactil-min);
    min-height: var(--tactil-min);
    justify-content: center;
    border-radius: var(--radio-s);
}
:where(.pista-boton):hover { color: var(--color-acento); }
.pista-boton:focus-visible { outline: 2px solid var(--foco-color); outline-offset: 1px; }
.pista-boton .icono-pista { width: 1.05em; height: 1.05em; opacity: 0.85; }
/* La etiqueta que explica algo es el propio botón (una etiqueta con su icono de información) */
.pista-boton.etiqueta { padding: 0 var(--sp-2); justify-content: flex-start; cursor: pointer; font-size: var(--fs-12); }
.pista-boton.etiqueta:hover { box-shadow: 0 0 0 1px currentColor inset; }
.pista-boton.etiqueta .icono-pista { opacity: 0.75; }
.pista-boton[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--color-acento-borde); }

.pista {
    position: absolute;
    z-index: var(--z-popover);
    top: calc(100% + 6px);
    left: 0;
    width: max-content;
    max-width: min(22rem, calc(100vw - 2rem));
    padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--color-borde-fuerte);
    border-radius: var(--radio-m);
    background: var(--color-superficie);
    box-shadow: var(--sombra-2);
    color: var(--color-texto);
    font-family: var(--fuente-sans);
    font-size: var(--fs-13);
    font-weight: var(--peso-normal);
    letter-spacing: 0;
    text-transform: none;
    line-height: var(--lh-texto);
    text-align: left;
    white-space: normal;
    visibility: hidden;
    opacity: 0;
    transform: translateY(-2px);
    /* Al irse el ratón, un momento de gracia para poder llegar a la pista (WCAG 1.4.13: se puede pasar por encima) */
    transition: opacity var(--mov-rapido), transform var(--mov-rapido), visibility 0s linear 160ms;
    pointer-events: none;
}
.pista a { color: var(--color-acento); }
.pista strong { font-weight: var(--peso-fuerte); }
.pista p { margin: 0 0 var(--sp-2); }
.pista p:last-child { margin-bottom: 0; }

.pista-envoltorio:hover > .pista,
.pista-envoltorio:focus-within > .pista,
.pista-boton[aria-expanded="true"] + .pista {
    visibility: visible;
    opacity: 1;
    transform: none;
    transition-delay: 0s;
    pointer-events: auto;
}
/* Esc la cierra aunque el ratón o el foco sigan ahí (interfaz.js pone la clase) */
.pista-envoltorio.pista-cerrada > .pista { visibility: hidden; opacity: 0; pointer-events: none; transition: none; }
/* Con JS, la pista se coloca en la pantalla (position: fixed): no la recortan las tablas con desplazamiento */
.js .pista { position: fixed; top: 0; left: 0; }

/* ════════ 6. Importe: valor tal como se publicó, IVA y marca de calidad ═══════════════════════════════════ */
.importe { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.importe-rotulo { display: inline-flex; align-items: center; gap: 2px; font-size: var(--rotulo-tam); font-weight: var(--rotulo-peso); letter-spacing: var(--rotulo-espaciado); text-transform: uppercase; color: var(--color-texto-2); }
.importe-valor {
    font-variant-numeric: tabular-nums;
    font-weight: var(--peso-fuerte);
    color: var(--color-texto-fuerte);
    overflow-wrap: anywhere;
    line-height: 1.2;
}
.importe-marcas { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-2); align-items: center; }
.importe-nota { font-size: var(--fs-13); color: var(--color-texto-2); }
.importe .importe-sin-dato { color: var(--color-texto-2); font-weight: var(--peso-normal); }
.importe-nota strong { color: var(--color-texto-fuerte); font-variant-numeric: tabular-nums; }
/* El otro importe (con o sin IVA) de uno que no cuenta: en gris, como su nota (C5) */
.importe-nota-apagada, .importe-nota-apagada strong { color: var(--color-texto-3); font-weight: var(--peso-normal); }

.importe-s .importe-valor { font-size: var(--fs-16); }
.importe-m .importe-valor { font-size: var(--fs-22); }
.importe-l .importe-valor { font-family: var(--fuente-serif); font-weight: var(--peso-normal); font-size: var(--fs-40); letter-spacing: -0.02em; line-height: 1.05; }

.importe-excluido .importe-valor { color: var(--calidad-excluido); }
.importe-repetido .importe-valor { color: var(--calidad-repetido); }
.importe-corregido .importe-valor { color: var(--calidad-corregido); }

@media (max-width: 640px) {
    .importe-l .importe-valor { font-size: var(--fs-28); }
    .importe-m .importe-valor { font-size: var(--fs-18); }
}

/* Sello de auditoría de la ficha de contrato (Fase 5, mejora 5): qué ha hecho la web con el importe de adjudicación,
   con sus cifras. Ocupa todo el ancho del panel de importes, con el filete y los colores de su marca de calidad */
.importes-panel > .sello-auditoria { grid-column: 1 / -1; }
/* Con el sello, la nota corta bajo el importe («No cuenta en las sumas», «Cuenta como …») sobra: la dice el sello */
.importes-panel:has(> .sello-auditoria) .importe-nota:not(.importe-otro-iva) { display: none; }
.sello-auditoria {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-2) var(--sp-6);
    padding: var(--sp-4) var(--sp-5);
    border: 1px solid var(--calidad-excluido-borde);
    border-left: 4px solid var(--calidad-excluido);
    border-radius: var(--radio-m);
    background: var(--calidad-excluido-fondo);
    color: var(--color-texto);
    --sello-color: var(--calidad-excluido);
}
.sello-repetido { border-color: var(--calidad-repetido-borde); border-left-color: var(--calidad-repetido); background: var(--calidad-repetido-fondo); --sello-color: var(--calidad-repetido); }
.sello-corregido { flex-direction: column; border-color: var(--calidad-corregido-borde); border-left-color: var(--calidad-corregido); background: var(--calidad-corregido-fondo); --sello-color: var(--calidad-corregido); }
.sello-auditoria p { margin: 0; }
.sello-veces {
    font-family: var(--fuente-serif);
    font-size: clamp(2.25rem, 1.4rem + 2.2vw, 3.25rem);
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--sello-color);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.sello-cuerpo { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.sello-titulo { font-size: var(--rotulo-tam); font-weight: var(--rotulo-peso); letter-spacing: var(--rotulo-espaciado); text-transform: uppercase; color: var(--sello-color); }
.sello-texto { font-size: var(--fs-14); line-height: var(--lh-texto); max-width: 68ch; }
.sello-texto strong { font-weight: var(--peso-fuerte); color: var(--sello-color); font-variant-numeric: tabular-nums; }
/* Corregido: publicado → ÷1.000 → cuenta como */
.sello-flujo { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-2) var(--sp-4); }
.sello-paso { display: inline-flex; flex-direction: column; gap: 2px; min-width: 0; }
.sello-tramo { display: inline-flex; align-items: flex-end; gap: var(--sp-4); }
.sello-rotulo { font-size: var(--fs-12); color: var(--color-texto-2); }
.sello-publicado, .sello-divisor, .sello-cuenta { font-family: var(--fuente-serif); font-size: var(--fs-28); line-height: 1.1; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* El publicado, tachado en suave pero legible: sigue arriba tal cual, en grande */
.sello-publicado { color: var(--color-texto-2); text-decoration: line-through; text-decoration-thickness: 1px; text-decoration-color: color-mix(in srgb, var(--color-texto-2) 60%, transparent); }
.sello-divisor { color: var(--sello-color); }
.sello-cuenta { color: var(--color-texto-fuerte); font-size: clamp(var(--fs-28), 1.2rem + 1.6vw, var(--fs-40)); }
.sello-flecha { width: 1.25rem; height: 1.25rem; color: var(--sello-color); margin-bottom: 0.45rem; flex-shrink: 0; }
@media (max-width: 640px) {
    .sello-auditoria { flex-direction: column; padding: var(--sp-3) var(--sp-4); }
    .sello-publicado, .sello-divisor { font-size: var(--fs-22); }
    .sello-cuenta { font-size: var(--fs-28); }
}

/* ════════ 7. KPI con su definición ═══════════════════════════════════════════════════════════════════════ */
/* El filete entre celdas lo pinta cada celda, con una sombra a su izquierda y arriba (la de la primera columna y la
   primera fila queda fuera y se recorta). Antes era el fondo de la rejilla asomando por un hueco de 1 px, y una celda que
   faltaba en la última fila se pintaba como un bloque gris de 740×110 px en todas las fichas (Fase 5, mejora 2) */
.kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    background: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-l);
    overflow: hidden;
}
.kpi {
    display: flex;
    flex-direction: column;
    /* La cifra abajo: con un rótulo de dos líneas («IMPORTE / TOTAL» en el cajón a 375 px) las cifras de una fila
       siguen alineadas (C6) */
    justify-content: space-between;
    gap: var(--sp-1);
    min-width: 0;
    padding: var(--sp-4) var(--sp-5);
    background: var(--color-superficie);
    box-shadow: -1px 0 0 var(--color-borde), 0 -1px 0 var(--color-borde);
}
.kpi-cabeza { display: flex; align-items: center; gap: var(--sp-1); min-height: 24px; }
.kpi-rotulo { font-size: var(--rotulo-tam); font-weight: var(--rotulo-peso); letter-spacing: var(--rotulo-espaciado); text-transform: uppercase; color: var(--color-texto-2); }
/* La «i» de cada rótulo, más discreta: cinco por fila competían con las cifras */
.kpi-cabeza .pista-boton { color: var(--color-texto-3); }
.kpi-cabeza .pista-boton .icono-pista { width: 0.85em; height: 0.85em; }
/* Una cifra no se parte nunca (C6: a 768 px salía «27.369.1» / «57»): tamaño fluido y, si no cabe, la rejilla pasa a
   2×2 (abajo) */
.kpi-valor {
    font-family: var(--fuente-serif);
    font-size: clamp(var(--fs-22), 1.2rem + 1.2vw, var(--fs-28));
    line-height: 1.1;
    letter-spacing: -0.015em;
    color: var(--color-texto-fuerte);
    font-variant-numeric: tabular-nums;
    overflow-wrap: normal;
    white-space: nowrap;
}
/* Un KPI que lleva a su vista parece un enlace (y solo ese) */
a.kpi-valor { display: inline-flex; align-items: baseline; gap: var(--sp-2); color: var(--color-acento); text-decoration: none; align-self: flex-start; }
a.kpi-valor .icono { width: 0.6em; height: 0.6em; align-self: center; opacity: 0.6; transition: transform var(--mov-rapido), opacity var(--mov-rapido); }
a.kpi-valor:hover { color: var(--color-acento-hover); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.12em; }
a.kpi-valor:hover .icono { opacity: 1; transform: translateX(2px); }
.kpi-nota { font-size: var(--fs-13); color: var(--color-texto-2); line-height: var(--lh-ajustada); }

/* Los números, protagonistas (Fase 5, mejora 6): la portada hasta 3,5 rem y las fichas a 2,5 rem, en serif */
/* En la portada, la cifra se mide con el ancho de su celda (cinco por fila con la 3b): «1,76 billones €» ocupa unas 5
   veces su cuerpo, así que 19 cqi cabe siempre; las cifras cortas llegan al tope de 3 rem */
.kpis-l .kpi { container-type: inline-size; }
.kpis-l .kpi-valor { font-size: clamp(var(--fs-28), 19cqi, var(--fs-48)); }
/* La ficha no crece con la ventana (1.040 px como mucho): su cifra se mide con el ancho de la rejilla, no con el de la
   ventana (a 1.920 px, «1.910.000 €» se salía de su celda) */
.ficha-kpis { container-type: inline-size; }
.ficha-kpis .kpi-valor { font-size: clamp(var(--fs-22), 3.5cqi, var(--fs-40)); }
/* Una fila con todas las cifras de la ficha desde 1.000 px (cinco en las de empresa y órgano): con «auto-fit» cabían
   cuatro y «Periodo» se quedaba sola en la segunda fila */
@media (min-width: 1000px) {
    /* Tres filas: las de cada celda con subgrid (O1 del QA de clics 5); en columnas, cada celda en la suya */
    .ficha-kpis .kpis { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); grid-template-rows: repeat(3, auto); }
}
.kpis-compactos .kpi { padding: var(--sp-3) var(--sp-4); }
.kpis-compactos .kpi-valor { font-family: var(--fuente-sans); font-weight: var(--peso-fuerte); font-size: var(--fs-18); letter-spacing: 0; }
/* La franja de cifras del explorador, con la misma cifra serif que las fichas (las compactas quedan para el cajón) */
.franja-cifras .kpis-compactos .kpi-valor { font-family: var(--fuente-serif); font-weight: var(--peso-normal); font-size: clamp(var(--fs-22), 1rem + 1.1vw, 2rem); letter-spacing: -0.015em; }
/* O1 del QA de clics 5: una celda con nota («con NIF de empresa» en la franja del explorador, «Última adjudicación» en
   «Periodo» de las fichas) subía su cifra 22 px sobre las demás (la celda reparte el sitio entre rótulo, cifra y nota). Con
   subgrid, las celdas de una fila comparten tres filas (rótulo, cifra y nota): las cifras quedan en la misma línea aunque
   un rótulo ocupe dos líneas o una celda no lleve nota */
@supports (grid-template-rows: subgrid) {
    .franja-cifras .kpis, .ficha-kpis .kpis { row-gap: 0; }
    .franja-cifras .kpis > .kpi, .ficha-kpis .kpis > .kpi { display: grid; grid-row: span 3; grid-template-rows: subgrid; row-gap: var(--sp-1); }
    .franja-cifras .kpis > .kpi > .kpi-cabeza, .ficha-kpis .kpis > .kpi > .kpi-cabeza { align-self: start; }
    .franja-cifras .kpis > .kpi > .kpi-valor, .ficha-kpis .kpis > .kpi > .kpi-valor { align-self: end; justify-self: start; }
    .franja-cifras .kpis > .kpi > .kpi-nota, .ficha-kpis .kpis > .kpi > .kpi-nota { align-self: start; }
}

@media (max-width: 900px) {
    .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ficha-kpis .kpi-valor { font-size: clamp(var(--fs-22), 5cqi, var(--fs-40)); }
    .kpis > .kpi:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (max-width: 640px) {
    .kpi { padding: var(--sp-3) var(--sp-4); }
    .kpi-valor, .kpis-l .kpi-valor, .ficha-kpis .kpi-valor { font-size: var(--fs-22); }
}
/* A 360-400 px, «IMPORTE TOTAL» y su «i» no cabían en media rejilla y el rótulo se partía en dos líneas (web-movil) */
@media (max-width: 400px) {
    .kpi { padding: var(--sp-3); }
    .kpi-rotulo { letter-spacing: 0.03em; }
}

/* ════════ 8. Cabecera de entidad (empresa, órgano, contrato) ═════════════════════════════════════════════ */
.entidad { display: flex; flex-direction: column; gap: var(--sp-3); }
.entidad-tipo { display: inline-flex; align-items: center; gap: var(--sp-2); margin: 0; font-size: var(--rotulo-tam); font-weight: var(--rotulo-peso); letter-spacing: var(--rotulo-espaciado); text-transform: uppercase; color: var(--color-texto-2); }
.entidad-tipo .icono { width: 1.3em; height: 1.3em; color: var(--color-acento); }
.entidad-nombre { font-size: var(--fs-40); line-height: var(--lh-titulo); overflow-wrap: anywhere; max-width: 32ch; }
.entidad-nombre-largo { font-size: var(--fs-28); max-width: 60ch; }
.entidad-meta { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); align-items: center; }
.entidad-nif { display: inline-flex; align-items: center; gap: var(--sp-1); font-family: var(--fuente-mono); font-size: var(--fs-14); color: var(--color-texto); background: var(--color-acento-suave); border: 1px solid var(--color-acento-borde); border-radius: var(--radio-s); padding: 0 0 0 var(--sp-2); min-height: 28px; }
.entidad-nif .boton-copiar { min-height: 28px; min-width: 28px; }
.entidad-nota { font-size: var(--fs-14); color: var(--color-texto-2); margin: 0; max-width: 72ch; }
@media (max-width: 640px) {
    .entidad-nombre { font-size: var(--fs-28); }
    .entidad-nombre-largo { font-size: var(--fs-22); }
}

/* Frase-resumen bajo el nombre de las fichas (Fase 5, mejora 9): la entradilla de datos, en serif. Las cifras en negro;
   lo que se pulsa (sus contratos y la entidad de la primera fila), en azul marino y subrayado, como todo enlace */
.entidad-resumen {
    margin: 0;
    max-width: 44ch;
    font-family: var(--fuente-serif);
    font-size: 1.5rem;
    line-height: 1.3;
    color: var(--color-texto-2);
    text-wrap: pretty;
}
.entidad-resumen strong { font-weight: var(--peso-normal); color: var(--color-texto-fuerte); font-variant-numeric: tabular-nums; }
.entidad-resumen a { color: var(--color-acento); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.14em; text-decoration-color: var(--color-acento-borde); font-variant-numeric: tabular-nums; }
.entidad-resumen a:hover { color: var(--color-acento-hover); text-decoration-color: currentColor; }
.entidad-resumen-compacto { font-size: var(--fs-18); max-width: none; }
@media (max-width: 640px) {
    .entidad-resumen { font-size: 1.25rem; }
    .entidad-resumen-compacto { font-size: var(--fs-16); }
}

/* ════════ 9. Lista de las N primeras, con valores ════════════════════════════════════════════════════════ */
.lista-top { list-style: none; margin: 0; padding: 0; }
.lista-top-fila {
    display: grid;
    grid-template-columns: 1.75rem minmax(0, 1fr) auto;
    grid-template-areas: "pos nombre cifras" "pos barra cifras";
    column-gap: var(--sp-3);
    row-gap: var(--sp-1);
    align-items: center;
    padding: var(--sp-3) 0;
    border-bottom: 1px solid var(--color-borde);
}
.lista-top-fila:last-child { border-bottom: 0; }
.lista-top-pos { grid-area: pos; align-self: start; font-variant-numeric: tabular-nums; font-size: var(--fs-13); color: var(--color-texto-3); padding-top: 0.1em; }
.lista-top-nombre { grid-area: nombre; min-width: 0; font-size: var(--fs-14); line-height: var(--lh-ajustada); overflow-wrap: anywhere; }
.lista-top-nombre a { font-weight: var(--peso-medio); }
.lista-top-barra { grid-area: barra; }
.lista-top-cifras { grid-area: cifras; display: flex; flex-direction: column; align-items: flex-end; text-align: right; }
.lista-top-valor { font-variant-numeric: tabular-nums; font-weight: var(--peso-fuerte); font-size: var(--fs-14); color: var(--color-texto-fuerte); white-space: nowrap; }
.lista-top-sub { font-variant-numeric: tabular-nums; font-size: var(--fs-12); color: var(--color-texto-2); white-space: nowrap; }
.lista-top-vacia { color: var(--color-texto-2); font-size: var(--fs-14); margin: 0; }
@media (max-width: 480px) {
    .lista-top-fila { grid-template-columns: 1.5rem minmax(0, 1fr); grid-template-areas: "pos nombre" "pos barra" "pos cifras"; }
    .lista-top-cifras { flex-direction: row; gap: var(--sp-2); align-items: baseline; justify-content: flex-start; }
}

/* Barra proporcional (SVG sin estilos en línea: la anchura es un atributo) */
.barra { display: block; width: 100%; height: 6px; }
.barra-fondo { fill: var(--color-fondo-hundido); }
.barra-valor { fill: var(--color-acento); opacity: 0.8; }

/* ════════ 10. Tabla adaptable (tarjetas en móvil) ════════════════════════════════════════════════════════ */
.tabla-marco {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-l);
    background: var(--color-superficie);
}
.tabla { width: 100%; border-collapse: collapse; font-size: var(--fs-14); }
.tabla caption { text-align: left; }
.tabla th, .tabla td { padding: var(--sp-3) var(--sp-4); text-align: left; vertical-align: middle; border-bottom: 1px solid var(--color-borde); }
.tabla thead th {
    background: var(--color-fondo-calido);
    font-size: var(--rotulo-tam);
    font-weight: var(--rotulo-peso);
    letter-spacing: var(--rotulo-espaciado);
    text-transform: uppercase;
    color: var(--color-texto-2);
    border-bottom-color: var(--color-borde-fuerte);
    white-space: nowrap;
}
.tabla tbody tr:last-child > * { border-bottom: 0; }
.tabla tbody tr { transition: background var(--mov-rapido); }
.tabla tbody tr:hover { background: var(--color-fondo-calido); }
.tabla .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabla .celda-nombre { min-width: 14rem; }
.tabla .celda-nombre a { font-weight: var(--peso-medio); }
.tabla .celda-sub { display: block; margin-top: 2px; font-size: var(--fs-12); color: var(--color-texto-2); }

/* Cabecera que ordena */
.orden { display: inline-flex; align-items: center; gap: var(--sp-1); color: inherit; text-decoration: none; min-height: 24px; }
.orden:hover { color: var(--color-acento); text-decoration: underline; }
.orden .icono { width: 1em; height: 1em; }
.orden-activo { color: var(--color-acento); }
th[aria-sort] { color: var(--color-acento); }

/* Filas que abren un detalle: todo el ancho es la zona que se pulsa, y lo dice */
.fila-abre { cursor: pointer; }
.fila-abre:focus-visible { outline: 2px solid var(--foco-color); outline-offset: -2px; background: var(--color-acento-suave); }
.fila-abre.is-cargando { opacity: 0.6; }
.fila-abre.is-cargando > :first-child { box-shadow: inset 3px 0 0 var(--color-acento); }

@media (max-width: 720px) {
    .tabla-tarjetas thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
    .tabla-tarjetas, .tabla-tarjetas tbody { display: block; }
    /* Interlineado ajustado y 12 px arriba y abajo (web-movil): con el 1,55 del texto corrido, cada tarjeta medía un
       15-20 % más (la cobertura por fuente de la metodología, 4.600 px) */
    .tabla-tarjetas tr {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--sp-2) var(--sp-4);
        padding: var(--sp-3) var(--sp-4);
        border-bottom: 1px solid var(--color-borde);
        line-height: var(--lh-ajustada);
    }
    .tabla-tarjetas tr:last-child { border-bottom: 0; }
    .tabla-tarjetas td { display: block; padding: 0; border: 0; text-align: left; min-width: 0; }
    .tabla-tarjetas td.num { text-align: left; white-space: normal; }
    .tabla-tarjetas td[data-etiqueta]::before {
        content: attr(data-etiqueta);
        display: block;
        font-size: var(--fs-12);
        font-weight: var(--peso-medio);
        color: var(--color-texto-2);
        text-transform: none;
        letter-spacing: 0;
        line-height: 1.3;
        margin-bottom: 2px;
    }
    .tabla-tarjetas .celda-nombre { grid-column: 1 / -1; min-width: 0; font-size: var(--fs-16); }
    .tabla-tarjetas .celda-ancha { grid-column: 1 / -1; }
    /* Una etiqueta larga («IVA: depende del contrato») se parte dentro de su celda y no tapa la de al lado (C6) */
    .tabla-tarjetas .etiqueta { white-space: normal; max-width: 100%; height: auto; }
    .tabla-tarjetas .celda-oculta-movil { display: none; }
    .tabla-marco:has(.tabla-tarjetas) { overflow: visible; }
}

/* ════════ 11. Tarjeta de resultado (buscador) ════════════════════════════════════════════════════════════ */
.tarjeta {
    background: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-l);
    box-shadow: var(--sombra-1);
}
.tarjeta-resultado {
    position: relative;
    padding: var(--sp-5) var(--sp-6);
    transition: border-color var(--mov-rapido), box-shadow var(--mov-rapido);
}
.tarjeta-resultado:hover { border-color: var(--color-borde-fuerte); box-shadow: var(--sombra-2); }
.tarjeta-titulo { margin: 0 0 var(--sp-3); font-family: var(--fuente-sans); font-size: var(--fs-16); font-weight: var(--peso-fuerte); line-height: var(--lh-ajustada); color: var(--color-texto-fuerte); overflow-wrap: anywhere; }
/* El título lleva a la ficha y lo parece: azul marino, subrayado al pasar */
.tarjeta-titulo a { color: var(--color-acento); text-decoration: none; }
.tarjeta-titulo a:hover { color: var(--color-acento-hover); text-decoration: underline; }
.tarjeta-partes {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-3) var(--sp-6);
    padding: var(--sp-3) 0;
    border-top: 1px solid var(--color-borde);
    border-bottom: 1px solid var(--color-borde);
    margin-bottom: var(--sp-3);
}
.parte { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.parte-rol { font-size: var(--rotulo-tam); font-weight: var(--rotulo-peso); letter-spacing: var(--rotulo-espaciado); text-transform: uppercase; color: var(--color-texto-2); }
.tarjeta-resultado .parte-rol .icono { display: none; }
.parte-nombre { font-size: var(--fs-14); font-weight: var(--peso-medio); color: var(--color-texto-fuerte); overflow-wrap: anywhere; line-height: var(--lh-ajustada); }
.parte-nombre-sin-dato { color: var(--color-texto-2); font-weight: var(--peso-normal); }
.parte-nif { font-family: var(--fuente-mono); font-size: var(--fs-12); color: var(--color-texto-2); min-width: 0; overflow-wrap: anywhere; }
.tarjeta-cifras { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-8); align-items: flex-start; margin-bottom: var(--sp-3); }
.dato { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dato-rotulo { font-size: var(--rotulo-tam); font-weight: var(--rotulo-peso); letter-spacing: var(--rotulo-espaciado); text-transform: uppercase; color: var(--color-texto-2); }
.dato-valor { font-size: var(--fs-14); font-variant-numeric: tabular-nums; color: var(--color-texto-fuerte); }
.dato-nota { font-size: var(--fs-12); font-variant-numeric: tabular-nums; color: var(--color-texto-2); }
.tarjeta-pie { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; font-size: var(--fs-13); color: var(--color-texto-2); }
.tarjeta-pie .ident { font-size: var(--fs-12); color: var(--color-texto-2); }
.tarjeta-pie .enlace-origen { margin-left: auto; }
.enlace-origen { display: inline-flex; align-items: center; gap: var(--sp-1); min-height: 24px; font-size: var(--fs-13); }
/* Tarjeta compacta en el móvil (D; I3 de la revisión): unos 440 px por tarjeta, menos de dos por pantalla. Ahora: el
   título en dos líneas como mucho; empresa y órgano en una línea cada uno, con su icono por rótulo; importe, marcas y
   fecha en una fila; el tipo y el procedimiento, texto gris. La licitación, el CPV y el expediente están en la ficha */
@media (max-width: 640px) {
    .tarjeta-resultado { padding: var(--sp-3) var(--sp-4); }
    /* max-height: en Chrome 151 -webkit-line-clamp no recorta (display:-webkit-box pasa a flow-root): dos líneas justas.
       El recorte va en el enlace (bloque), no en el título: así la caja del enlace es la que se ve, y un clic en su centro
       cae en él y no en lo que hay debajo de las líneas ocultas (la batería del fundido lo pulsa así) */
    .tarjeta-titulo { margin-bottom: var(--sp-2); }
    .tarjeta-titulo > a { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; max-height: calc(2 * var(--lh-ajustada) * 1em); padding-block: 0; }
    .tarjeta-partes { grid-template-columns: 1fr; gap: var(--sp-1); padding: 0; border: 0; margin-bottom: var(--sp-2); }
    .tarjeta-resultado .parte { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: var(--sp-2); }
    .tarjeta-resultado .parte-rol { display: inline-flex; }
    .tarjeta-resultado .parte-rol .icono { display: inline-block; width: 1.15em; height: 1.15em; color: var(--color-texto-3); }
    .tarjeta-resultado .parte-rol-texto, .tarjeta-resultado .importe-rotulo, .tarjeta-resultado .dato-rotulo {
        position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
    }
    .tarjeta-resultado .parte-nombre { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; overflow-wrap: normal; }
    .tarjeta-cifras { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-3); margin-bottom: var(--sp-2); }
    .tarjeta-cifras > .importe { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-2); }
    .tarjeta-resultado .dato-licitacion, .tarjeta-resultado .dato-cpv, .tarjeta-pie .tarjeta-exp { display: none; }
    .tarjeta-resultado .dato-fecha .dato-valor { font-size: var(--fs-13); color: var(--color-texto-2); }
    .tarjeta-pie { gap: var(--sp-1) var(--sp-2); }
    .tarjeta-pie .etiqueta-neutra, .tarjeta-pie .etiqueta-menor { border: 0; background: none; padding: 0; min-height: 0; }
    .tarjeta-pie .enlace-origen { margin-left: 0; }
}

/* Con el dedo, toda la tarjeta lleva a la ficha del contrato (web-movil): un toque en un hueco de la tarjeta no hacía
   nada, y una tarjeta con borde parece un botón. El enlace del título se estira sobre la tarjeta con un ::after (sin
   z-index); los demás enlaces y botones de la tarjeta van posicionados y después en el orden del documento, así que
   quedan encima y siguen haciendo lo suyo (empresa, órgano, «También en…», la fuente y las pistas). Con ratón, no: la
   tarjeta se puede seleccionar y copiar */
@media (hover: none) and (pointer: coarse) {
    .tarjeta-resultado .tarjeta-titulo > a::after { content: ""; position: absolute; inset: 0; border-radius: var(--radio-l); }
    .tarjeta-resultado a:not(.tarjeta-titulo > a), .tarjeta-resultado button, .tarjeta-resultado .pista-envoltorio { position: relative; }
    .tarjeta-resultado:has(.tarjeta-titulo > a:active) { border-color: var(--color-acento-borde); background: var(--color-fondo-calido); }
}

/* Tarjeta «libro de cuentas» en escritorio (Fase 5c, mejora 7 de la revisión estética 2): el contrato a la izquierda
   (título, empresa y órgano en una línea cada uno, con su icono por rótulo, y las etiquetas) y una columna de cifras a la
   derecha, con un filete: el importe a 22 px tabular, su IVA y su marca debajo, y la fecha. Las reglas compactas del
   móvil (4b); la licitación, el CPV y el expediente están en la ficha. Unos 165 px por tarjeta (antes, unos 300).
   Desde 641 px (web-movil): entre 641 y 899 (un teléfono en horizontal, una tableta) quedaba la tarjeta antigua, de 290 px
   en una pantalla de 390 de alto */
@media (min-width: 641px) {
    .tarjeta-resultado {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 15rem;
        grid-template-areas: "titulo cifras" "partes cifras" "pie cifras";
        grid-template-rows: auto auto 1fr;
        column-gap: var(--sp-6);
        padding: var(--sp-4) var(--sp-5);
    }
    .tarjeta-resultado .tarjeta-titulo { grid-area: titulo; margin-bottom: var(--sp-2); }
    .tarjeta-resultado .tarjeta-titulo > a { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; max-height: calc(2 * var(--lh-ajustada) * 1em); padding-block: 0; }
    .tarjeta-resultado .tarjeta-partes { grid-area: partes; grid-template-columns: 1fr; gap: 2px; padding: 0; border: 0; margin-bottom: var(--sp-3); }
    .tarjeta-resultado .parte { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: var(--sp-2); }
    .tarjeta-resultado .parte-rol { display: inline-flex; }
    .tarjeta-resultado .parte-rol .icono { display: inline-block; width: 1.1em; height: 1.1em; color: var(--color-texto-3); }
    .tarjeta-resultado .parte-rol-texto, .tarjeta-resultado .importe-rotulo, .tarjeta-resultado .dato-rotulo {
        position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
    }
    .tarjeta-resultado .parte-nombre { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; overflow-wrap: normal; min-height: var(--tactil-min); padding-block: 2px; }
    .tarjeta-resultado .parte-nif { text-align: right; white-space: nowrap; max-width: 16rem; overflow: hidden; text-overflow: ellipsis; }
    .tarjeta-resultado .tarjeta-cifras {
        grid-area: cifras;
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        justify-content: center;
        gap: var(--sp-1);
        margin: 0;
        padding-left: var(--sp-5);
        border-left: 1px solid var(--color-borde);
        text-align: right;
    }
    .tarjeta-resultado .tarjeta-cifras > .importe { align-items: flex-end; }
    .tarjeta-resultado .importe-s .importe-valor { font-size: var(--fs-22); letter-spacing: -0.01em; white-space: nowrap; }
    .tarjeta-resultado .importe-marcas { justify-content: flex-end; }
    .tarjeta-resultado .dato-licitacion, .tarjeta-resultado .dato-cpv, .tarjeta-pie .tarjeta-exp { display: none; }
    .tarjeta-resultado .dato-fecha .dato-valor { font-size: var(--fs-13); color: var(--color-texto-2); }
    .tarjeta-resultado .tarjeta-nota-copia { margin: 0; }
    .tarjeta-resultado .tarjeta-pie { grid-area: pie; align-self: end; gap: var(--sp-1) var(--sp-2); }
    .tarjeta-pie .etiqueta-neutra, .tarjeta-pie .etiqueta-menor { border: 0; background: none; padding: 0; min-height: 0; }
}

/* ════════ 12. Migas de pan ═══════════════════════════════════════════════════════════════════════════════ */
.migas ol { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--sp-1); list-style: none; margin: 0; padding: 0; font-size: var(--fs-14); color: var(--color-texto-2); }
.migas li { display: inline-flex; align-items: center; gap: var(--sp-1); min-width: 0; }
.migas a { color: var(--color-texto-2); display: inline-flex; align-items: center; min-height: 24px; }
.migas a:hover { color: var(--color-acento); }
.migas .icono { width: 0.9em; height: 0.9em; color: var(--color-texto-3); }
.migas [aria-current="page"] { color: var(--color-texto); max-width: 40ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ════════ 13. Paginación ═════════════════════════════════════════════════════════════════════════════════ */
.paginacion { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--sp-1); margin-top: var(--sp-8); }
.paginacion > a, .paginacion > span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-1);
    min-width: 40px;
    min-height: 40px;
    padding: 0 var(--sp-3);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-m);
    background: var(--color-superficie);
    color: var(--color-texto-2);
    font-size: var(--fs-14);
    font-variant-numeric: tabular-nums;
    text-decoration: none;
}
.paginacion a:hover { border-color: var(--color-acento); color: var(--color-acento); }
.paginacion .pag-actual { background: var(--color-acento); border-color: var(--color-acento); color: var(--color-sobre-acento); font-weight: var(--peso-fuerte); }
.paginacion .pag-inactiva { background: var(--color-fondo-calido); color: var(--color-texto-3); cursor: default; }
.paginacion .pag-hueco { border: 0; background: none; min-width: 1.5rem; padding: 0; }
@media (pointer: coarse) { .paginacion > a, .paginacion > span:not(.pag-hueco) { min-width: var(--tactil); min-height: var(--tactil); } }
@media (max-width: 480px) {
    .paginacion .pag-texto { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
}
/* B3 de la QA 4: con más resultados de los que se pueden recorrer, el paginador lo dice debajo */
.paginacion-tope { max-width: 62ch; margin: var(--sp-3) auto 0; text-align: center; text-wrap: pretty; }

/* ════════ 14. Estado vacío ═══════════════════════════════════════════════════════════════════════════════ */
.vacio { text-align: center; padding: var(--sp-12) var(--sp-4); color: var(--color-texto-2); }
.vacio-icono { width: 44px; height: 44px; color: var(--color-texto-3); margin: 0 auto var(--sp-3); display: block; stroke-width: 1.4; }
.vacio-titulo { font-family: var(--fuente-serif); font-weight: var(--peso-normal); font-size: var(--fs-22); color: var(--color-texto-fuerte); margin: 0 0 var(--sp-2); }
.vacio-cuerpo { max-width: 46ch; margin: 0 auto; font-size: var(--fs-14); }
.vacio-cuerpo .acciones { justify-content: center; margin-top: var(--sp-4); }
/* H1 de la QA 4: sin resultados con todas las palabras, la búsqueda con una menos (enlaces con su cifra) */
.vacio-cuerpo .con-una-menos-titulo { margin-top: var(--sp-4); color: var(--color-texto); font-weight: var(--peso-fuerte); }
.vacio-cuerpo .con-una-menos { list-style: none; margin: var(--sp-2) 0 0; padding: 0; display: grid; gap: var(--sp-2); }
.vacio-cuerpo .con-una-menos a { overflow-wrap: anywhere; }

/* ════════ 15. Aviso destacado ════════════════════════════════════════════════════════════════════════════ */
.aviso {
    display: flex;
    gap: var(--sp-3);
    align-items: flex-start;
    padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--color-acento-borde);
    border-left-width: 3px;
    border-radius: var(--radio-m);
    background: var(--color-acento-suave);
    color: var(--color-texto);
    font-size: var(--fs-14);
    line-height: var(--lh-texto);
}
.aviso > .icono { color: var(--color-acento); width: 1.25em; height: 1.25em; margin-top: 0.15em; }
.aviso-cuerpo { min-width: 0; }
.aviso-cuerpo > :last-child { margin-bottom: 0; }
.aviso-titulo { font-weight: var(--peso-fuerte); color: var(--color-texto-fuerte); margin: 0 0 var(--sp-1); }
.aviso-atencion { background: var(--color-aviso-fondo); border-color: var(--color-aviso-borde); }
.aviso-atencion > .icono { color: var(--color-aviso); }
.aviso-calidad { background: var(--calidad-excluido-fondo); border-color: var(--calidad-excluido-borde); }
.aviso-calidad > .icono { color: var(--calidad-excluido); }
.aviso-neutro { background: var(--color-fondo-calido); border-color: var(--color-borde-fuerte); }
.aviso-neutro > .icono { color: var(--color-texto-2); }
/* Fallo de red (vista.js) y parámetros ignorados (C2 y C3 de la revisión estética) */
.aviso-red { margin: 0 0 var(--sp-4); }
.aviso-red .acciones { margin: var(--sp-2) 0 0; }
.aviso-red.reintentando { opacity: 0.7; }
.fragmento-error { min-height: 0; }
.lista-avisos { margin: 0; padding-left: 1.1em; }
.lista-avisos li + li { margin-top: var(--sp-1); }
.resultados-avisos, .explorador-avisos { margin: 0 0 var(--sp-4); }
/* Aviso plegable (details): el título es el resumen */
details.aviso { display: block; }
details.aviso > summary { display: flex; gap: var(--sp-3); align-items: center; cursor: pointer; list-style: none; font-weight: var(--peso-medio); min-height: 24px; }
details.aviso > summary::-webkit-details-marker { display: none; }
details.aviso > summary .icono-plegar { margin-left: auto; transition: transform var(--mov-rapido); color: var(--color-texto-2); }
details.aviso[open] > summary .icono-plegar { transform: rotate(180deg); }
details.aviso > .aviso-cuerpo { margin-top: var(--sp-2); padding-left: calc(1.25em + var(--sp-3)); }

/* ════════ 16. Pie de procedencia ═════════════════════════════════════════════════════════════════════════ */
.procedencia {
    border-top: 1px solid var(--color-borde);
    padding-top: var(--sp-5);
    margin-top: var(--sp-8);
    font-size: var(--fs-13);
    color: var(--color-texto-2);
}
.procedencia-titulo { display: flex; align-items: center; gap: var(--sp-2); font-family: var(--fuente-sans); font-size: var(--rotulo-tam); font-weight: var(--rotulo-peso); letter-spacing: var(--rotulo-espaciado); text-transform: uppercase; color: var(--color-texto-2); margin: 0 0 var(--sp-3); }
.procedencia-datos { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: var(--sp-3) var(--sp-6); margin: 0; }
.procedencia-datos > div { min-width: 0; }
.procedencia-datos dt { font-size: var(--fs-12); color: var(--color-texto-2); }
.procedencia-datos dd { margin: 0; color: var(--color-texto); overflow-wrap: anywhere; }
.procedencia-pie { margin: var(--sp-4) 0 0; }

/* ════════ 17. Gráficos (SVG y CSS, sin librerías) ════════════════════════════════════════════════════════ */
/* Evolución anual: una barra por año; cada barra lleva a los contratos de ese año, y la tabla de datos (con los años
   enlazados) es el control equivalente. En el móvil, los 10 últimos años: así cada barra mide 24 px o más de ancho
   también a 320 px, sin desplazar el gráfico.
   Fase 5 (mejora 8): 200 px de alto; etiquetas directas sobre el máximo y el último año completo; el dato de la barra
   señalada sale sobre ella; las barras crecen al aparecer (interfaz.js añade .grafico-espera, luego .grafico-crece, que
   quita al acabar, y nada de eso con prefers-reduced-motion); y la nota de cobertura en la leyenda. Los textos son SVG con su posición en
   % (la altura de su barra) como atributo: sin estilos en línea */
.grafico-anual { margin: 0; position: relative; }
.grafico-anual-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.grafico-anual-fondo { flood-color: var(--color-acento); }
.grafico-anual-barras {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 200px;
    list-style: none;
    /* Sitio arriba para las dos líneas de la etiqueta del máximo */
    margin: 2.75rem 0 0;
    padding: 0 0 var(--sp-1);
    border-bottom: 1px solid var(--color-borde-fuerte);
}
.grafico-anual-barras li { flex: 1 1 0; min-width: 0; height: 100%; display: flex; position: relative; }
/* La etiqueta y el dato pueden salirse de su barra: encima de las vecinas */
.grafico-anual-barras li.con-etiqueta { z-index: 1; }
.grafico-anual-barras li:hover, .grafico-anual-barras li:focus-within { z-index: 2; }
.grafico-anual-ejes.ejes-recientes, .solo-movil { display: none; }
@media (max-width: 560px) {
    .grafico-anual-barras { height: 160px; }
    .grafico-anual-barras li:nth-last-child(n+11) { display: none; }
    .grafico-anual-barras li { min-width: 24px; }
    .grafico-anual-ejes.con-recientes { display: none; }
    .grafico-anual-ejes.ejes-recientes { display: flex; }
    .solo-movil { display: inline; }
}
.grafico-anual-barras a, .grafico-anual-barras .barra-anio {
    flex: 1;
    display: flex;
    align-items: flex-end;
    height: 100%;
    min-width: 0;
    border-radius: 2px 2px 0 0;
    text-decoration: none;
    color: inherit;
}
.grafico-anual-barras svg { display: block; width: 100%; height: 100%; overflow: visible; }
.grafico-anual-barra {
    fill: var(--color-acento);
    opacity: 0.72;
    transition: opacity var(--mov-rapido);
    /* Crece desde su base */
    transform-box: fill-box;
    transform-origin: 50% 100%;
}
.grafico-anual-barras .barra-vacia .grafico-anual-barra { fill: var(--color-borde-fuerte); }
/* El año en curso: barra parcial, más clara y con borde discontinuo (no es una caída del gasto) */
.grafico-anual-barras .barra-parcial .grafico-anual-barra { opacity: 0.32; stroke: var(--color-acento); stroke-width: 1px; stroke-dasharray: 3 2; }
.grafico-anual-barras a.barra-parcial:hover .grafico-anual-barra, .grafico-anual-barras a.barra-parcial:focus-visible .grafico-anual-barra { opacity: 0.55; }
.grafico-anual-barras a:hover .grafico-anual-barra, .grafico-anual-barras a:focus-visible .grafico-anual-barra { opacity: 1; }
.grafico-anual-barras a:focus-visible { outline: 2px solid var(--foco-color); outline-offset: 1px; }
/* Etiqueta directa: el año, en gris, y el valor, en azul marino; con un halo del fondo por si pisa una barra vecina */
.grafico-anual-etiqueta {
    font-family: var(--fuente-sans);
    font-size: var(--fs-13);
    font-weight: var(--peso-fuerte);
    font-variant-numeric: tabular-nums;
    fill: var(--color-acento);
    paint-order: stroke;
    stroke: var(--color-fondo);
    stroke-width: 3px;
    stroke-linejoin: round;
}
.grafico-anual-etiqueta .etiqueta-anio { font-size: var(--fs-12); font-weight: var(--peso-normal); fill: var(--color-texto-2); }
/* El dato de la barra señalada (ratón o foco), sobre ella: texto blanco sobre azul marino (el filtro pinta la caja) */
.grafico-anual-dato {
    font-family: var(--fuente-sans);
    font-size: var(--fs-12);
    font-variant-numeric: tabular-nums;
    fill: #fff;
    /* display y no visibility: con visibility: hidden, Chrome pintaba igual la caja del filtro */
    display: none;
    pointer-events: none;
}
.grafico-anual-dato .dato-anio { font-weight: var(--peso-fuerte); }
.grafico-anual-barras li:hover .grafico-anual-dato, .grafico-anual-barras li:focus-within .grafico-anual-dato { display: inline; }
/* El ancla de cada texto en cada ancho del gráfico (componentes.anclas_grafico): donde cabe; «oculta», una etiqueta que no
   cabe junto a la del máximo (la dice la leyenda) */
.grafico-anual-barras .ancho-inicio { text-anchor: start; }
.grafico-anual-barras .ancho-medio { text-anchor: middle; }
.grafico-anual-barras .ancho-fin { text-anchor: end; }
.grafico-anual-barras .grafico-anual-etiqueta.ancho-oculta { display: none; }
@media (max-width: 560px) {
    .grafico-anual-barras .estrecho-inicio { text-anchor: start; }
    .grafico-anual-barras .estrecho-medio { text-anchor: middle; }
    .grafico-anual-barras .estrecho-fin { text-anchor: end; }
    .grafico-anual-barras .grafico-anual-etiqueta.ancho-oculta { display: inline; }
    .grafico-anual-barras .grafico-anual-etiqueta.estrecho-oculta { display: none; }
}
.grafico-anual-barras li:hover .grafico-anual-etiqueta, .grafico-anual-barras li:focus-within .grafico-anual-etiqueta { visibility: hidden; }
.grafico-anual-ejes { display: flex; justify-content: space-between; font-size: var(--fs-12); color: var(--color-texto-2); margin-top: var(--sp-1); font-variant-numeric: tabular-nums; }
.grafico-leyenda { font-size: var(--fs-13); color: var(--color-texto-2); margin: var(--sp-2) 0 0; }
.grafico-anual-explica { display: block; }
/* La nota de cobertura: las subidas de los primeros años son sobre todo fuentes que se incorporan */
.grafico-anual-nota { display: flex; gap: var(--sp-2); align-items: flex-start; margin-top: var(--sp-2); padding: var(--sp-2) var(--sp-3); border-left: 2px solid var(--color-acento-borde); background: var(--color-fondo-calido); color: var(--color-texto); }
.grafico-anual-nota .icono { flex-shrink: 0; width: 1.1em; height: 1.1em; margin-top: 0.15em; color: var(--color-acento); }
.grafico-anual-nota a { white-space: nowrap; }
/* Las barras crecen al aparecer (450 ms, escalonadas 15 ms) y las etiquetas llegan después. Solo si el sistema no pide
   menos movimiento; sin JS no se esconde nada */
@keyframes barra-crecer { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@media (prefers-reduced-motion: no-preference) {
    .grafico-anual.grafico-espera .grafico-anual-barra { transform: scaleY(0); }
    .grafico-anual.grafico-espera .grafico-anual-etiqueta { opacity: 0; }
    .grafico-anual.grafico-crece .grafico-anual-barra { animation: barra-crecer 450ms var(--mov-curva) both; }
    .grafico-anual.grafico-crece .grafico-anual-etiqueta { animation: aparecer 200ms ease 750ms both; }
    .grafico-anual.grafico-crece li:nth-child(2) .grafico-anual-barra { animation-delay: 15ms; }
    .grafico-anual.grafico-crece li:nth-child(3) .grafico-anual-barra { animation-delay: 30ms; }
    .grafico-anual.grafico-crece li:nth-child(4) .grafico-anual-barra { animation-delay: 45ms; }
    .grafico-anual.grafico-crece li:nth-child(5) .grafico-anual-barra { animation-delay: 60ms; }
    .grafico-anual.grafico-crece li:nth-child(6) .grafico-anual-barra { animation-delay: 75ms; }
    .grafico-anual.grafico-crece li:nth-child(7) .grafico-anual-barra { animation-delay: 90ms; }
    .grafico-anual.grafico-crece li:nth-child(8) .grafico-anual-barra { animation-delay: 105ms; }
    .grafico-anual.grafico-crece li:nth-child(9) .grafico-anual-barra { animation-delay: 120ms; }
    .grafico-anual.grafico-crece li:nth-child(10) .grafico-anual-barra { animation-delay: 135ms; }
    .grafico-anual.grafico-crece li:nth-child(11) .grafico-anual-barra { animation-delay: 150ms; }
    .grafico-anual.grafico-crece li:nth-child(12) .grafico-anual-barra { animation-delay: 165ms; }
    .grafico-anual.grafico-crece li:nth-child(13) .grafico-anual-barra { animation-delay: 180ms; }
    .grafico-anual.grafico-crece li:nth-child(14) .grafico-anual-barra { animation-delay: 195ms; }
    .grafico-anual.grafico-crece li:nth-child(15) .grafico-anual-barra { animation-delay: 210ms; }
    .grafico-anual.grafico-crece li:nth-child(16) .grafico-anual-barra { animation-delay: 225ms; }
    .grafico-anual.grafico-crece li:nth-child(17) .grafico-anual-barra { animation-delay: 240ms; }
    .grafico-anual.grafico-crece li:nth-child(18) .grafico-anual-barra { animation-delay: 255ms; }
    .grafico-anual.grafico-crece li:nth-child(19) .grafico-anual-barra { animation-delay: 270ms; }
    .grafico-anual.grafico-crece li:nth-child(20) .grafico-anual-barra { animation-delay: 285ms; }
    .grafico-anual.grafico-crece li:nth-child(21) .grafico-anual-barra { animation-delay: 300ms; }
    .grafico-anual.grafico-crece li:nth-child(22) .grafico-anual-barra { animation-delay: 315ms; }
    .grafico-anual.grafico-crece li:nth-child(23) .grafico-anual-barra { animation-delay: 330ms; }
    .grafico-anual.grafico-crece li:nth-child(24) .grafico-anual-barra { animation-delay: 345ms; }
    .grafico-anual.grafico-crece li:nth-child(25) .grafico-anual-barra { animation-delay: 360ms; }
    .grafico-anual.grafico-crece li:nth-child(26) .grafico-anual-barra { animation-delay: 375ms; }
    .grafico-anual.grafico-crece li:nth-child(27) .grafico-anual-barra { animation-delay: 390ms; }
    .grafico-anual.grafico-crece li:nth-child(28) .grafico-anual-barra { animation-delay: 405ms; }
    .grafico-anual.grafico-crece li:nth-child(29) .grafico-anual-barra { animation-delay: 420ms; }
    .grafico-anual.grafico-crece li:nth-child(30) .grafico-anual-barra { animation-delay: 435ms; }
    .grafico-anual.grafico-crece li:nth-child(31) .grafico-anual-barra { animation-delay: 450ms; }
}
.grafico-datos { margin-top: var(--sp-3); font-size: var(--fs-13); }
.grafico-datos summary { cursor: pointer; color: var(--color-acento); min-height: 24px; display: inline-flex; align-items: center; }
.grafico-datos .tabla { font-size: var(--fs-13); margin-top: var(--sp-2); }
.grafico-datos .tabla th, .grafico-datos .tabla td { padding: var(--sp-1) var(--sp-3); }

/* Reparto (barra apilada al 100 %): cuánto se lleva cada uno de los primeros y el resto */
.reparto { margin: 0 0 var(--sp-4); }
.reparto-barra { display: block; width: 100%; height: 14px; border-radius: 3px; overflow: hidden; }
.reparto-barra rect { stroke: var(--color-superficie); stroke-width: 2px; vector-effect: non-scaling-stroke; }
.reparto-leyenda { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); list-style: none; margin: var(--sp-2) 0 0; padding: 0; font-size: var(--fs-12); color: var(--color-texto-2); }
.reparto-leyenda li { display: inline-flex; align-items: center; gap: var(--sp-1); }
.reparto-leyenda svg { width: 10px; height: 10px; flex-shrink: 0; }
.reparto-1 { fill: #1f4068; } .reparto-2 { fill: #2c5a8e; } .reparto-3 { fill: #4f79a8; }
.reparto-4 { fill: #7c9cc2; } .reparto-5 { fill: #a9bfd9; } .reparto-resto { fill: #e3e0d7; }

/* ════════ 18. Cajón (panel lateral) y hoja inferior ══════════════════════════════════════════════════════ */
.cajon { position: fixed; inset: 0; z-index: var(--z-cajon); pointer-events: none; }
.cajon-velo { position: absolute; inset: 0; background: var(--color-velo); pointer-events: auto; animation: aparecer var(--mov-medio) ease both; }
.cajon-panel {
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: min(480px, 100%);
    display: flex;
    flex-direction: column;
    background: var(--color-superficie);
    box-shadow: var(--sombra-3);
    pointer-events: auto;
    animation: entrarDerecha var(--mov-medio) var(--mov-curva) both;
}
.cajon-panel:focus { outline: none; }
.cajon-cabeza {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: calc(var(--sp-3) + env(safe-area-inset-top, 0px)) max(var(--sp-3), env(safe-area-inset-right, 0px)) var(--sp-3) var(--sp-5);
    border-bottom: 1px solid var(--color-borde);
    background: var(--color-fondo-calido);
}
.cajon-cuerpo { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: var(--sp-5) max(var(--sp-5), env(safe-area-inset-right, 0px)) var(--sp-5) var(--sp-5); }
.cajon-pie { padding: var(--sp-3) max(var(--sp-5), env(safe-area-inset-right, 0px)) calc(var(--sp-3) + var(--seguro-abajo)) var(--sp-5); border-top: 1px solid var(--color-borde); background: var(--color-fondo-calido); }
.boton-cerrar { width: 40px; height: 40px; padding: 0; justify-content: center; }
@media (pointer: coarse) { .boton-cerrar { width: var(--tactil); height: var(--tactil); } }
/* Contenido del cajón: el mismo detalle que la ficha, compacto */
.cajon .entidad { gap: var(--sp-2); }
.cajon .entidad-nombre { font-size: var(--fs-28); }
.cajon-kpis { margin-top: var(--sp-4); }
.cajon .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cajon .kpis > .kpi:last-child:nth-child(odd) { grid-column: 1 / -1; }   /* sin celda vacía con 3 KPI */
.cajon-seccion { margin-top: var(--sp-6); }
.cajon-seccion-titulo {
    font-family: var(--fuente-sans);
    font-size: var(--rotulo-tam);
    font-weight: var(--rotulo-peso);
    letter-spacing: var(--rotulo-espaciado);
    text-transform: uppercase;
    color: var(--color-texto-2);
    padding-bottom: var(--sp-2);
    border-bottom: 1px solid var(--color-borde);
    margin: 0 0 var(--sp-1);
}
.cajon .lista-top-fila { padding: var(--sp-2) 0; }
.cajon .datos { grid-template-columns: minmax(8rem, max-content) minmax(0, 1fr); font-size: var(--fs-13); gap: var(--sp-2) var(--sp-4); }
.cajon-pie.acciones { justify-content: flex-start; }
.cajon-pie.acciones .boton { flex: 1 1 auto; }
.cajon .borme-consulta { font-size: var(--fs-12); }
@media (max-width: 480px) { .cajon .datos { grid-template-columns: 1fr; gap: 0; } .cajon .datos dt { margin-top: var(--sp-2); } }
@keyframes aparecer { from { opacity: 0; } to { opacity: 1; } }
@keyframes entrarDerecha { from { transform: translateX(100%); } to { transform: none; } }
@keyframes entrarAbajo { from { transform: translateY(100%); } to { transform: none; } }
body.con-cajon { overflow: hidden; }

/* Hoja inferior: el panel de filtros en el móvil (interfaz.js la abre y le da el foco) */
.hoja-velo { display: none; }
@media (max-width: 979px) {
    .hoja { display: none; }
    .hoja.esta-abierta {
        display: flex;
        flex-direction: column;
        position: fixed;
        left: 0; right: 0; bottom: 0;
        z-index: var(--z-cajon);
        max-height: 88vh;
        max-height: 88dvh;
        background: var(--color-superficie);
        border-radius: var(--radio-l) var(--radio-l) 0 0;
        box-shadow: var(--sombra-3);
        animation: entrarAbajo var(--mov-medio) var(--mov-curva) both;
    }
    .hoja.esta-abierta ~ .hoja-velo, .hoja-velo.esta-abierta {
        display: block;
        position: fixed;
        inset: 0;
        z-index: calc(var(--z-cajon) - 1);
        background: var(--color-velo);
        animation: aparecer var(--mov-medio) ease both;
    }
    .hoja-cabeza { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-2) max(var(--sp-2), env(safe-area-inset-right, 0px)) var(--sp-2) max(var(--sp-5), env(safe-area-inset-left, 0px)); border-bottom: 1px solid var(--color-borde); }
    .hoja-cabeza::before { content: ""; position: absolute; top: 6px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 2px; background: var(--color-borde-fuerte); }
    .hoja-titulo { font-family: var(--fuente-sans); font-size: var(--fs-16); font-weight: var(--peso-fuerte); }
    .hoja-titulo:focus { outline: none; }   /* recibe el foco por programa al abrir la hoja: sin marco */
    .hoja-cuerpo { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: var(--sp-2) max(var(--sp-5), env(safe-area-inset-right, 0px)) var(--sp-4) max(var(--sp-5), env(safe-area-inset-left, 0px)); }
    .hoja-pie { display: flex; gap: var(--sp-2); padding: var(--sp-3) max(var(--sp-5), env(safe-area-inset-right, 0px)) calc(var(--sp-3) + var(--seguro-abajo)) max(var(--sp-5), env(safe-area-inset-left, 0px)); border-top: 1px solid var(--color-borde); background: var(--color-fondo-calido); }
    .hoja-pie .boton { flex: 1; }
    body.con-hoja { overflow: hidden; }
}
/* El buscador y el explorador no anclan el desplazamiento (M2 del QA 4). htmx pone la zona nueva (resultados, tabla,
   franja) delante de la vieja y luego quita la vieja; Chrome, para que no se mueva lo que se veía, bajaba la vista lo que
   mide la zona nueva. Con la hoja de filtros cerrada antes de que llegue la respuesta, en el móvil, la vista acababa al pie
   de la página: de 385 a 9.300 px en el explorador, y de 400 a 7.565 en el buscador si se había desplazado. Sin anclaje,
   la vista se queda donde estaba, con los resultados nuevos en su sitio */
body.ancho-datos { overflow-anchor: none; }
@media (min-width: 980px) {
    .hoja-pie { display: none; }
    .boton-filtros { display: none; }
}

/* ════════ 19. Campos y combobox (autocompletado accesible) ═══════════════════════════════════════════════ */
.campo { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.campo-rotulo { font-size: var(--fs-13); font-weight: var(--peso-medio); color: var(--color-texto-2); }
.control {
    width: 100%;
    min-height: 40px;
    padding: 0 var(--sp-3);
    border: 1px solid var(--color-borde-control);
    border-radius: var(--radio-m);
    background: var(--color-superficie);
    color: var(--color-texto);
    font-size: var(--fs-14);
    transition: border-color var(--mov-rapido), box-shadow var(--mov-rapido);
}
.control:hover { border-color: var(--color-texto-2); }
.control:focus { outline: none; border-color: var(--color-acento); box-shadow: var(--foco-anillo); }
.control::placeholder { color: var(--color-texto-3); }
select.control {
    appearance: none;
    padding-right: 2rem;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23595959' stroke-width='2' stroke-linecap='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.7rem center;
    cursor: pointer;
}
@media (pointer: coarse) { .control { min-height: var(--tactil); font-size: var(--fs-16); } }

.rango { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: var(--sp-2); align-items: center; }
.rango-sep { color: var(--color-texto-3); }

.casilla { display: flex; align-items: center; gap: var(--sp-2); min-height: 32px; padding: 2px var(--sp-2); margin: 0 calc(var(--sp-2) * -1); border-radius: var(--radio-s); cursor: pointer; font-size: var(--fs-14); line-height: var(--lh-ajustada); }
.casilla:hover { background: var(--color-fondo-hundido); }
.casilla input { width: 18px; height: 18px; margin: 0; accent-color: var(--color-acento); flex-shrink: 0; }
.casilla-texto { flex: 1; min-width: 0; }
.casilla-cuenta { font-size: var(--fs-12); color: var(--color-texto-2); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.casilla-vacia .casilla-texto { color: var(--color-texto-2); }
.casilla.activa .casilla-texto { color: var(--color-acento); font-weight: var(--peso-medio); }
@media (pointer: coarse) { .casilla { min-height: var(--tactil); } }

.combobox { position: relative; }
.combobox-lista {
    position: absolute;
    top: calc(100% + 6px);
    left: 0; right: 0;
    z-index: var(--z-menu);
    max-height: min(28rem, 70vh);
    overflow-y: auto;
    margin: 0;
    padding: var(--sp-1);
    list-style: none;
    background: var(--color-superficie);
    border: 1px solid var(--color-borde-fuerte);
    border-radius: var(--radio-m);
    box-shadow: var(--sombra-2);
}
.combobox-lista:empty, .combobox-lista[hidden] { display: none; }
.combobox-opcion {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--radio-s);
    cursor: pointer;
    min-height: var(--tactil);
    justify-content: center;
}
.combobox-opcion:hover, .combobox-opcion[aria-selected="true"] { background: var(--color-acento-suave); }
.combobox-opcion[aria-selected="true"] { box-shadow: inset 3px 0 0 var(--color-acento); }
.combobox-nombre { font-weight: var(--peso-medio); color: var(--color-texto-fuerte); line-height: var(--lh-ajustada); overflow-wrap: anywhere; }
.combobox-meta { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); font-size: var(--fs-12); color: var(--color-texto-2); }
.combobox-vacio { padding: var(--sp-3); color: var(--color-texto-2); font-size: var(--fs-14); text-align: center; }
.combobox-todo { border-top: 1px solid var(--color-borde); margin-top: var(--sp-1); border-radius: 0 0 var(--radio-s) var(--radio-s); }
.combobox-todo .combobox-nombre { color: var(--color-acento); }
/* Fase 5c (mejora 20): grupos (Empresas y Órganos en «Todo el contrato»), una barra proporcional a los contratos de cada
   sugerencia dentro de su grupo y las grafías con menos del 1 % plegadas. La lista, sin barra de desplazamiento suelta */
.combobox-lista { max-height: min(34rem, 72vh); scrollbar-width: thin; scrollbar-color: transparent transparent; }
.combobox-lista:hover { scrollbar-color: var(--color-borde-fuerte) transparent; }
.combobox-lista .combobox-opcion { padding-block: 6px; gap: 1px; }
.combobox-grupo { list-style: none; }
.combobox-grupo + .combobox-grupo { margin-top: var(--sp-1); padding-top: var(--sp-1); border-top: 1px solid var(--color-borde); }
.combobox-grupo-titulo { display: block; padding: var(--sp-2) var(--sp-3) var(--sp-1); font-size: var(--rotulo-tam); font-weight: var(--rotulo-peso); letter-spacing: var(--rotulo-espaciado); text-transform: uppercase; color: var(--color-texto-2); }
.combobox-grupo-lista { list-style: none; margin: 0; padding: 0; }
.combobox-cifra { font-variant-numeric: tabular-nums; color: var(--color-texto); font-weight: var(--peso-medio); }
.combobox-barra { display: block; width: 100%; height: 3px; margin-top: 3px; }
.combobox-barra rect { fill: var(--color-acento); opacity: 0.55; }
.combobox-menor .combobox-nombre { font-weight: var(--peso-normal); color: var(--color-texto-2); }
.combobox-mas { min-height: 0; }
.combobox-mas .combobox-nombre { color: var(--color-acento); font-size: var(--fs-14); }
.combobox-opcion[hidden] { display: none; }

/* ════════ 20. Chips de filtros activos ═══════════════════════════════════════════════════════════════════ */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin: 0; padding: 0; list-style: none; }
.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    min-height: 32px;
    padding: 0 var(--sp-2) 0 var(--sp-3);
    border: 1px solid var(--color-acento-borde);
    border-radius: var(--radio-pildora);
    background: var(--color-acento-suave);
    color: var(--color-texto-fuerte);
    font-size: var(--fs-13);
    text-decoration: none;
}
.chip-rotulo { color: var(--color-texto-2); }
.chip .icono { width: 1em; height: 1em; color: var(--color-acento); }
.chip:hover { border-color: var(--color-peligro-borde); background: var(--color-peligro-fondo); color: var(--color-peligro); text-decoration: none; }
.chip:hover .icono { color: var(--color-peligro); }
@media (pointer: coarse) { .chip { min-height: var(--tactil); } }

/* ════════ 21. Pestañas (enlaces entre vistas) ════════════════════════════════════════════════════════════ */
.pestanas { display: flex; gap: var(--sp-1); border-bottom: 1px solid var(--color-borde); overflow-x: auto; scrollbar-width: none; }
.pestanas::-webkit-scrollbar { display: none; }
.pestana {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    min-height: var(--tactil);
    padding: 0 var(--sp-4);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    color: var(--color-texto-2);
    font-size: var(--fs-14);
    font-weight: var(--peso-medio);
    text-decoration: none;
    white-space: nowrap;
}
.pestana:hover { color: var(--color-acento); text-decoration: none; background: var(--color-fondo-hundido); }
.pestana[aria-current="page"] { color: var(--color-acento); border-bottom-color: var(--color-acento); font-weight: var(--peso-fuerte); }
.pestana .icono { width: 1.1em; height: 1.1em; }

/* ════════ 22. Esqueleto de carga ═════════════════════════════════════════════════════════════════════════ */
.esqueleto {
    background: linear-gradient(90deg, var(--color-fondo-calido) 0%, var(--color-fondo-hundido) 50%, var(--color-fondo-calido) 100%);
    background-size: 200% 100%;
    animation: brillo 1.2s ease-in-out infinite;
    border-radius: var(--radio-s);
    height: 0.9rem;
    margin: var(--sp-3) 0;
}
.esqueleto-titulo { height: 1.6rem; width: 70%; }
.esqueleto-linea { width: 100%; }
.esqueleto-linea.corta { width: 55%; }
.esqueleto-bloque { height: 4rem; }
.esqueleto-kpis { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); margin: var(--sp-4) 0; }
.esqueleto-kpis .esqueleto { height: 3.2rem; margin: 0; }
@keyframes brillo { to { background-position: -200% 0; } }
.cargando-texto { font-size: var(--fs-13); color: var(--color-texto-2); }

/* ════════ 23. Copiar y avisos vivos ══════════════════════════════════════════════════════════════════════ */
.boton-copiar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-1);
    min-width: var(--tactil-min);
    min-height: var(--tactil-min);
    padding: 0 var(--sp-1);
    border: 0;
    border-radius: var(--radio-s);
    background: none;
    color: var(--color-texto-2);
    font-size: var(--fs-13);
}
.boton-copiar:hover { color: var(--color-acento); background: var(--color-fondo-hundido); }
.boton-copiar.copiado { color: var(--color-exito); }

/* ════════ Zonas táctiles en el móvil (web-movil, 6-oct) ════════════════════════════════════════════════════════
   Con el dedo (pointer: coarse), 44×44 px en lo que se pulsa a menudo. Los desplegables «Ver los datos», «Ver N más» y
   «Cómo leer los importes» y el «Copiar» con texto crecen de verdad. Los botones de solo icono (copiar un identificador,
   la «i» de una cifra) no cambian de tamaño, que descuadraría su línea: su zona se amplía con un ::after invisible hasta
   44 px, solo donde lo que hay alrededor es texto (nunca en las cabeceras de tabla, donde taparía el enlace que ordena) */
@media (pointer: coarse) {
    .grafico-datos summary, .filtro-mas summary, details.aviso > summary { min-height: var(--tactil); }
    /* El aviso plegable: su resumen ya mide 44 px, sin el relleno de arriba y abajo de la caja (salían 70 px) */
    details.aviso { padding-block: 0; }
    details.aviso[open] { padding-bottom: var(--sp-3); }
    details.aviso > .aviso-cuerpo { margin-top: 0; }
    .boton-copiar:has(> span) { min-height: var(--tactil); }
    .boton-copiar:not(:has(> span)), .kpi-cabeza .pista-boton, .importe-rotulo .pista-boton,
    .entidad-meta .pista-boton:not(.etiqueta) { position: relative; }
    /* Las etiquetas que explican algo («con IVA», «sin NIF»): 28 px y 8 px más por arriba y por abajo, que caben en el
       hueco con la línea de al lado. En la tarjeta del buscador importa más: un toque que se queda corto abre la ficha */
    .pista-boton.etiqueta { min-height: 28px; position: relative; }
    .pista-boton.etiqueta::after { content: ""; position: absolute; inset: -9px -4px; }   /* desde el relleno: 26 + 18 = 44 */
    .boton-copiar:not(:has(> span))::after, .kpi-cabeza .pista-boton::after, .importe-rotulo .pista-boton::after,
    .entidad-meta .pista-boton:not(.etiqueta)::after {
        content: "";
        position: absolute;
        left: 50%; top: 50%;
        width: max(100%, var(--tactil)); height: max(100%, var(--tactil));
        transform: translate(-50%, -50%);
    }
}
.aviso-vivo {
    position: fixed;
    left: 50%;
    bottom: calc(var(--sp-6) + var(--seguro-abajo));
    z-index: var(--z-salto);
    transform: translate(-50%, 8px);
    padding: var(--sp-2) var(--sp-4);
    border-radius: var(--radio-pildora);
    background: var(--color-texto-fuerte);
    color: #fff;
    font-size: var(--fs-14);
    box-shadow: var(--sombra-2);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--mov-medio), transform var(--mov-medio);
}
.aviso-vivo.visible { opacity: 1; transform: translate(-50%, 0); }

/* Estado de carga de htmx: la zona que se recarga lo dice sin taparse */
.htmx-request.zona-carga, .zona-carga.htmx-request { opacity: 0.6; transition: opacity var(--mov-medio); }
.indicador-carga { display: none; align-items: center; gap: var(--sp-2); font-size: var(--fs-13); color: var(--color-acento); }
.htmx-request .indicador-carga, .htmx-request.indicador-carga { display: inline-flex; }
.indicador-carga::before {
    content: "";
    width: 12px; height: 12px;
    border: 2px solid var(--color-acento-borde);
    border-top-color: var(--color-acento);
    border-radius: 50%;
    animation: girar 0.8s linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }

/* Salto al contenido: visible solo con el teclado */
.salto {
    position: absolute;
    left: var(--sp-3);
    top: -4rem;
    z-index: var(--z-salto);
    padding: var(--sp-2) var(--sp-4);
    border-radius: var(--radio-m);
    background: var(--color-acento);
    color: var(--color-sobre-acento);
    text-decoration: none;
}
.salto:focus { top: var(--sp-3); color: var(--color-sobre-acento); }

/* ════════ Fase 5: transiciones y destello de las cifras que cambian (vista.js, §4) ════════════════════════════════
   La zona que cambia con htmx (resultados del buscador, tabla del explorador: [data-entrando]) entra en 160 ms desde el
   0,6 de opacidad que tiene mientras carga (.zona-carga.htmx-request), y una cifra total que ha cambiado da un destello
   de 600 ms. Nada de contadores animados: enseñarían cifras intermedias que no existen.
   Sin View Transitions (N1 del QA de clics 2): mientras duraban, los clics y toques iban a <html> y se perdían aunque
   ::view-transition llevara pointer-events: none. La opacidad no cambia a dónde va un clic */
@keyframes entrar { from { opacity: 0.6; } to { opacity: 1; } }
[data-entrando] { animation: entrar 160ms ease-out; }
@keyframes destello { from { background-color: var(--color-resalte); } to { background-color: transparent; } }
.destello { animation: destello 600ms ease-out; border-radius: 3px; }
@media (prefers-reduced-motion: reduce) {
    [data-entrando] { animation: none; }
    .destello { animation: none; }
}
