/*
 * KHORRECTOR — estética «Crudo» (docs/identidad-visual.md).
 *
 * Negro sobre hueso, monoespaciada para todo el dato, Archivo negra para los
 * titulares, bordes de 2px y ningún adorno. El amarillo es señal, no
 * decoración: si hay amarillo en pantalla, hay algo que revisar.
 *
 * Un solo fichero, a mano, sin build. Versionado por VersionadoDeAssets.
 */

:root {
    --tinta: #111111;
    --hueso: #efede6;
    --hueso-2: #e6e3da;
    --senal: #f3e600;
    --gris: #777777;
    --gris-2: #b8b5ac;
    --error: #d1261a;
    --borde: 2px;
    --borde-fino: 1px;
    --mono: 'JetBrains Mono', Menlo, Consolas, monospace;
    --display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
}

/* ------------------------------------------------------------- Base */

*, *::before, *::after { box-sizing: border-box; }

html { background: var(--hueso); }

body {
    margin: 0;
    font-family: var(--mono);
    font-size: .8125rem;
    line-height: 1.45;
    color: var(--tinta);
    background: var(--hueso);
    font-variant-numeric: tabular-nums;
}

h1, h2, h3 { margin: 0; }

h1 {
    font-family: var(--display);
    font-weight: 900;
    font-size: 40px;
    line-height: .95;
    letter-spacing: -.02em;
    text-transform: uppercase;
}

p { margin: 0; }

code { font-family: var(--mono); font-size: inherit; }

a { color: var(--tinta); text-decoration: none; }
a:hover { text-decoration: underline; text-decoration-thickness: 2px; text-decoration-color: var(--senal); }

a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
    outline: 2px solid var(--senal);
    outline-offset: 2px;
}

.kh-lab {
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    font-weight: 500;
}

.kh-visualmente-oculto {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* Salto al contenido: invisible hasta que recibe el foco. */
.kh-salto {
    position: absolute; left: -999px; top: 8px; z-index: 100;
    padding: 8px 12px; background: var(--tinta); color: var(--senal);
}
.kh-salto:focus { left: 8px; }

/* ------------------------------------------ Lateral y miga de pan */

/* La estructura es la de PostaMail, la consola con la que Javi trabaja a
   diario: secciones a la izquierda, usuario arriba y una miga sobre el
   contenido. Lo que se copia es la estructura, no la estética: esto sigue
   siendo «Crudo». */

.kh-app { display: grid; grid-template-columns: 240px minmax(0, 1fr); min-height: 100vh; }

/* Fijo de verdad: la lista de secciones no se va con el scroll de una tabla de
   cinco mil filas, que es la mitad de las pantallas de esta aplicación. */
.kh-lateral {
    display: flex; flex-direction: column;
    position: sticky; top: 0; height: 100vh; overflow-y: auto;
    background: var(--tinta); color: var(--hueso);
}

.kh-lateral-cabeza { display: flex; align-items: stretch; min-height: 48px; }
.kh-lateral-cuerpo { display: flex; flex-direction: column; flex: 1 1 auto; }

.kh-marca-lateral {
    display: flex; align-items: center; flex: 1 1 auto;
    padding: 0 20px;
    color: var(--hueso);
    font-family: var(--display); font-weight: 900; font-size: 18px; letter-spacing: .06em;
}
.kh-marca-lateral:hover { text-decoration: none; color: var(--senal); }

/* Quién está dentro, antes que las secciones: es el dato que hay que mirar
   cuando se suplanta a alguien o cuando dos personas comparten el puesto. */
.kh-usuario {
    display: flex; flex-direction: column; gap: 4px;
    padding: 14px 20px;
    border-top: var(--borde-fino) solid var(--gris);
    border-bottom: var(--borde-fino) solid var(--gris);
}
.kh-usuario-nombre { font-weight: 700; overflow-wrap: anywhere; }
.kh-usuario-rol { color: var(--gris-2); }
.kh-usuario a { color: var(--hueso); }

.kh-nav { display: flex; flex-direction: column; flex: 1 1 auto; }
.kh-nav > a {
    display: flex; align-items: center; min-height: 44px;
    padding: 0 20px;
    color: var(--hueso);
    border-bottom: var(--borde-fino) solid var(--gris);
}
/* Invertir sobre negro es el mismo gesto que hacen los filtros dentro de una
   cabecera de caja: fondo hueso y tinta encima. */
.kh-nav > a:hover { text-decoration: none; background: var(--hueso); color: var(--tinta); }
.kh-nav > a.activa { background: var(--senal); color: var(--tinta); font-weight: 700; }
/* «Salir» al fondo del lateral, separado del resto: no es una sección. */
.kh-nav-salir { margin-top: auto; border-top: var(--borde-fino) solid var(--gris); border-bottom: 0; }

.kh-principal { display: flex; flex-direction: column; min-width: 0; }

/* Franja fina sobre el contenido. Sin mayúsculas: aquí va el nombre del
   fichero del usuario y «ORIGINAL.xlsx» no es lo mismo que «original.xlsx». */
.kh-miga {
    display: flex; align-items: center; min-height: 48px;
    padding: 8px 24px;
    border-bottom: var(--borde) solid var(--tinta);
}
.kh-miga ol {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px;
    list-style: none; margin: 0; padding: 0;
    font-size: 11px; letter-spacing: .08em;
}
.kh-miga li { display: flex; align-items: center; gap: 8px; color: var(--gris); }
.kh-miga li + li::before { content: '/'; color: var(--gris-2); }
.kh-miga a { color: var(--gris); }
.kh-miga li:last-child span { color: var(--tinta); font-weight: 700; }

/* Los tipos de columna en que actúa una regla, cuando no es solo dirección:
   una nota al lado del nombre, no un aviso. */
.kh-regla-ambito { color: var(--gris); margin-left: 8px; }

/* Pestañas de columna del paso 3: mismo lenguaje que los filtros, con la
   actual invertida. Son <a>, así que funcionan sin JavaScript. */
.kh-pestanas { display: flex; flex-wrap: wrap; gap: 0; border-bottom: var(--borde) solid var(--tinta); margin-bottom: 20px; }
.kh-pestana { padding: 8px 16px; border: var(--borde-fino) solid var(--tinta); border-bottom: 0; color: var(--gris); }
.kh-pestana + .kh-pestana { border-left: 0; }
.kh-pestana:hover { text-decoration: none; background: var(--hueso-2); color: var(--tinta); }
.kh-pestana-actual { background: var(--tinta); color: var(--hueso); font-weight: 700; }

/* Celda escrita a mano: gris, no amarillo. No es una duda ni una decisión de
   una regla, es del usuario, y lo que hay que saber es de dónde viene. */
.kh-chip-manual { border-color: var(--gris); color: var(--gris); }
/* El campo de edición ocupa el ancho entero de la columna «Corregida» y los
   botones bajan debajo. Al lado, el campo se quedaba en un hueco de dos dedos
   justo cuando lo que se escribe es una dirección larga —que es para lo que se
   edita a mano—: no se veía lo que se estaba escribiendo. Es un `flex-wrap`,
   así que en móvil sale igual sin nada más. */
.kh-edicion { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 6px; }
.kh-edicion-campo { flex: 1 0 100%; min-width: 0; }
.kh-oculto-visualmente {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.kh-menu-boton { display: none; }

.kh-suplantacion {
    display: flex; justify-content: space-between; gap: 16px;
    padding: 8px 20px;
    background: var(--senal);
    border-bottom: var(--borde) solid var(--tinta);
}

/* ----------------------------------------------------- Barra de pasos */

.kh-pasos {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    border-bottom: var(--borde) solid var(--tinta);
}
.kh-paso {
    padding: 10px 20px;
    border-right: var(--borde-fino) solid var(--tinta);
    color: var(--gris);
}
.kh-paso:last-child { border-right: 0; }
.kh-paso-actual { background: var(--tinta); color: var(--senal); font-weight: 700; }

/* Un paso por el que ya se pasó es un enlace y se comporta como cualquier otro
   del panel: el subrayado amarillo al pasar por encima y el foco de siempre,
   que vienen de la regla general de `a`. Los que quedan por delante no lo son,
   y se dicen en el gris más claro, sin cursor de enlace. */
a.kh-paso { display: block; }
.kh-paso-lejano { color: var(--gris-2); cursor: default; }
.kh-paso-numero { font-weight: 700; }
.kh-paso-actual .kh-paso-numero { color: var(--senal); }

/* El paso 5 es opcional: borde discontinuo mientras no se entre en él, que es
   la forma de decir «esto puede no hacerse» sin gastar amarillo. */
.kh-paso-opcional { border-left: var(--borde-fino) dashed var(--tinta); }
.kh-paso-opcional:not(.kh-paso-actual):not(.kh-paso-hecho) { border-top: var(--borde-fino) dashed var(--tinta); border-bottom: var(--borde-fino) dashed var(--tinta); }

/* --------------------------------------------------------- Contenido */

/* El contenido ocupa todo el ancho de la ventana, con 24px de margen a los
   lados y nada de `max-width`. Aquí no se lee prosa: se miran tablas de miles
   de filas con la dirección original y la corregida una al lado de la otra, y
   cada pixel que se recorta es una dirección que se parte en dos líneas o una
   columna que se va al scroll horizontal. Lo que sí lleva medida de lectura es
   el titular, que ese sí es prosa. */
.kh-contenido {
    padding: 28px 24px 48px;
    display: flex; flex-direction: column; gap: 24px;
}

.kh-titular {
    display: flex; align-items: flex-end; justify-content: space-between; gap: 40px;
}
.kh-titular > div:first-child { display: flex; flex-direction: column; gap: 10px; max-width: 760px; }
.kh-sub { font-size: 12px; }

.kh-botonera { display: flex; }

/* ------------------------------------------------------------ Botones */

.kh-btn {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 44px;
    padding: 0 18px;
    border: var(--borde) solid var(--tinta);
    background: transparent; color: var(--tinta);
    font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; font-weight: 500;
    cursor: pointer;
    transition: background-color 120ms, color 120ms;
}
.kh-btn:hover { text-decoration: none; background: var(--tinta); color: var(--hueso); }
.kh-btn-primario { background: var(--tinta); color: var(--senal); font-weight: 700; }
.kh-btn-primario:hover { background: var(--senal); color: var(--tinta); }
.kh-btn-peligro { border-color: var(--error); color: var(--error); }
.kh-btn-peligro:hover { background: var(--error); color: var(--hueso); }
.kh-btn-inactivo { opacity: .35; cursor: not-allowed; }
/* Lo apagado no reacciona al ratón: invertirlo al pasar por encima hace que
   parezca pulsable justo lo que no lo es. */
.kh-btn-inactivo:hover { background: transparent; color: var(--tinta); text-decoration: none; }
.kh-btn-menudo { min-height: 32px; padding: 0 10px; }
.kh-botonera .kh-btn + .kh-btn { border-left: 0; }

/* --------------------------------------------------------------- KPIs */

.kh-rejilla-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; }
.kh-kpis { border: var(--borde) solid var(--tinta); }
.kh-kpi {
    display: flex; flex-direction: column; gap: 8px;
    padding: 16px 18px;
    border-right: var(--borde) solid var(--tinta);
}
.kh-kpi:last-child { border-right: 0; }
.kh-kpi-senal { background: var(--senal); }
.kh-cifra {
    font-family: var(--display); font-weight: 900; font-size: 44px; line-height: 1; letter-spacing: -.03em;
}
.kh-cifra-texto { font-size: 28px; }
.kh-cifra-apagada { color: var(--gris); }

/* --------------------------------------------------------------- Cajas */

.kh-caja { border: var(--borde) solid var(--tinta); display: flex; flex-direction: column; }
.kh-caja-titulo {
    padding: 8px 12px;
    background: var(--tinta); color: var(--hueso);
    font-family: var(--mono); font-size: 11px; font-weight: 500;
}
.kh-vacio { padding: 16px 12px; color: var(--gris); }

.kh-zona-peligro { border: var(--borde) solid var(--error); padding: 16px; display: flex; gap: 20px; align-items: center; justify-content: space-between; }

/* Paso 4: la salida para quien no va a hacer cartas. En gris y sin caja, a
   propósito: terminar ya no es lo que toca en esta pantalla —eso está al final
   del paso 5— y no puede competir con las descargas. */
.kh-terminar-suelto { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; }
.kh-terminar-form { margin: 0; }
.kh-terminar-suelto .kh-ayuda { flex: 1 1 320px; }

/* Una cabecera de caja con controles a la derecha (filtros del resumen). */
.kh-caja-titulo { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }

/* Paso 3: «Ajustar ↗» al lado de cada regla que ha actuado, para volver al
   paso 2 a apagarla sin buscarla entre ~140. Gris y menudo: no es la acción
   principal de la celda, que es filtrar por ella. */
.kh-ir-a-regla { color: var(--gris); margin-left: 10px; white-space: nowrap; }

/* Paso 2: cada categoría es un <details>. La cabecera negra de siempre, pero
   pulsable: el nombre a la izquierda, «N activas de M» a la derecha y el
   indicador ▸/▾ delante. Se pliega sin JavaScript, que es lo que hace
   <details> de serie. */
.kh-categoria { display: block; }
.kh-categoria-cabeza { cursor: pointer; list-style: none; }
.kh-categoria-cabeza::-webkit-details-marker { display: none; }
.kh-categoria-cabeza::before { content: '▸'; margin-right: 10px; }
.kh-categoria[open] > .kh-categoria-cabeza::before { content: '▾'; }
.kh-categoria-cabeza:hover { background: var(--tinta); color: var(--senal); }
.kh-categoria-nombre { margin: 0; font-family: var(--mono); font-weight: 500; flex: 1 1 auto; }
.kh-categoria-cuenta { color: var(--gris-2); }
.kh-categoria[open] > .kh-categoria-cabeza { border-bottom: var(--borde) solid var(--tinta); }

/* «Desplegar todo» / «Plegar todo»: botones que se leen como enlaces, porque
   no navegan a ninguna parte. Solo salen con JavaScript. */
.kh-pliegues { display: flex; gap: 16px; }
.kh-enlace {
    padding: 0; border: 0; background: none; color: var(--gris);
    font-family: var(--mono); cursor: pointer;
}
.kh-enlace:hover { text-decoration: underline; text-decoration-thickness: 2px; text-decoration-color: var(--senal); color: var(--tinta); }

/* Paso 2: la lista de interruptores. Una regla por línea, chip a la izquierda. */
.kh-reglas { list-style: none; margin: 0; padding: 0; }
.kh-regla { display: flex; align-items: baseline; gap: 10px; padding: 8px 12px; border-bottom: var(--borde-fino) solid var(--tinta); }
.kh-regla:last-child { border-bottom: 0; }
.kh-regla input { width: 18px; height: 18px; accent-color: var(--tinta); flex: 0 0 auto; }
.kh-regla label { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; cursor: pointer; }
.kh-regla-apagada { color: var(--gris-2); }
.kh-regla-apagada .kh-chip { border-color: var(--gris-2); }
.kh-regla-apagada label { cursor: default; }
.kh-regla-nota { color: var(--gris); }

/* Reglas que se excluyen entre sí: se elige una. Mismo lenguaje que los
   interruptores de al lado, cambiando la casilla por un radio. */
.kh-regla-opciones { flex-direction: column; align-items: flex-start; gap: 8px; }
.kh-opciones { display: flex; flex-wrap: wrap; gap: 0 20px; }
.kh-opcion { display: flex; align-items: baseline; gap: 10px; }
.kh-opcion input { width: 18px; height: 18px; accent-color: var(--tinta); flex: 0 0 auto; }
.kh-opcion label { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; cursor: pointer; }

/* Grupo de casillas con su título: paso 1, columnas a conservar. Sin caja
   propia —ya está dentro de una— pero con el título como etiqueta del grupo. */
.kh-grupo { margin: 12px 0 0; padding: 0; border: 0; min-width: 0; }
.kh-grupo > legend { padding: 0; margin-bottom: 6px; }
.kh-grupo .kh-reglas { border: var(--borde-fino) solid var(--tinta); }

/* Botones y formularios menudos apretados en una celda de tabla: /reglas
   tiene hasta cuatro por fila (subir, bajar, editar, borrar). */
.kh-acciones { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.kh-acciones form { margin: 0; }

/* Una casilla suelta dentro de un formulario, con el mismo aire que las del
   paso 2 pero sin la lista alrededor. */
.kh-regla-suelta { border-bottom: 0; padding: 12px 0 0; }

/* Un aviso pegado a su campo, no a la pantalla entera. */
.kh-aviso-campo { padding: 8px 10px; font-size: 12px; }

/* Un párrafo de ayuda suelto entre bloques, fuera de una caja. */
.kh-ayuda-suelta { margin: 0 0 4px; }

.kh-chips { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-left: 8px; }

.kh-error-campo { color: var(--error); font-size: 12px; }
.kh-ajustes-nota { flex: 1 1 240px; }

/* Paso 3: reglas encima de la tabla, y las dos cajas separadas por ser de
   distinta naturaleza (docs/identidad-visual.md). */
.kh-resumen { display: flex; flex-direction: column; gap: 20px; }

/* Paso 4: la explicación a la izquierda y el botón a la derecha. */
.kh-exportacion { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px; padding: 16px 12px; }
.kh-exportacion > div { display: flex; flex-direction: column; gap: 8px; flex: 1 1 420px; }
.kh-zona-peligro > div { display: flex; flex-direction: column; gap: 8px; }
.kh-zona-peligro .kh-lab { color: var(--error); }

/* Orden de las cartas: las tres opciones, cada una con su explicación debajo.
   Cajas pegadas compartiendo borde, como todo lo demás, y la elegida con el
   fondo invertido para que se vea de un vistazo cuál manda. */
.kh-ordenes { display: flex; flex-wrap: wrap; gap: 0; }
.kh-orden {
    flex: 1 1 260px;
    display: flex; flex-direction: column; gap: 6px;
    border: var(--borde) solid var(--tinta); border-right: 0;
    padding: 12px 14px; cursor: pointer;
}
.kh-orden:last-of-type { border-right: var(--borde) solid var(--tinta); }
.kh-orden-cabeza { display: flex; align-items: center; gap: 8px; }
.kh-orden input { width: 18px; height: 18px; accent-color: var(--tinta); }
.kh-orden-actual { background: var(--hueso-2); }
.kh-orden-actual .kh-ayuda { color: var(--tinta); }

/* Clasificación postal (paso 4 y paso 5): la casilla y el recuento por tramo.
   El recuento son cajas pegadas compartiendo borde, como los KPI, porque es lo
   mismo que son: cuántas cartas van a cada sitio. «Sin tramo» en amarillo solo
   cuando hay alguna, que es la regla de oro del sistema. */
.kh-clasificacion-cuerpo { display: flex; flex-direction: column; gap: 12px; padding: 16px 12px; }
.kh-clasificacion-form { display: flex; align-items: center; gap: 10px; }
.kh-check { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.kh-check input { width: 18px; height: 18px; accent-color: var(--tinta); }

.kh-tramos { display: flex; flex-wrap: wrap; gap: 0; }
.kh-tramo {
    display: flex; align-items: baseline; gap: 8px;
    border: var(--borde) solid var(--tinta); border-right: 0;
    padding: 8px 14px;
}
.kh-tramo:last-child { border-right: var(--borde) solid var(--tinta); }
.kh-tramo strong { font-family: var(--display); font-size: 22px; line-height: 1; }
.kh-tramo-senal { background: var(--senal); }
.kh-tramo a { font-size: 11px; }

/* Un aviso dentro de la ayuda: el amarillo se gasta aquí porque es «esto que
   estás a punto de hacer no es lo que crees». */
.kh-ayuda-senal { background: var(--senal); color: var(--tinta); padding: 8px 10px; }

/* Paso 5: el patrón de la marca postal y el lote, uno al lado del otro. */
.kh-marca { display: flex; flex-direction: column; gap: 8px; padding: 0 12px 12px; }
.kh-marca-campos { display: flex; flex-wrap: wrap; gap: 12px; }
.kh-marca-campos > div { display: flex; flex-direction: column; gap: 4px; }
.kh-marca-campos > div:first-child { flex: 2 1 320px; }
.kh-marca-campos > div:last-child { flex: 1 1 120px; }
.kh-marca-campos input { width: 100%; }

/* Paso 5: la botonera dentro de una caja comparte su borde inferior en vez
   de flotar, como el resto de controles de caja. */
.kh-botonera-caja { padding: 0 12px 16px; }

/* Paso 5: la vista previa de la primera carta. Mismo tratamiento que las
   celdas del paso 3 —monoespaciada y con el valor en peso 700— porque es lo
   mismo que se está mirando: el dato que va a salir. */
.kh-previa { margin: 0; padding: 12px; display: grid; grid-template-columns: minmax(0, 220px) minmax(0, 1fr); gap: 8px 16px; }
.kh-previa dt { color: var(--gris); align-self: baseline; }
.kh-previa-valor { margin: 0; font-weight: 700; white-space: pre-wrap; overflow-wrap: anywhere; }
.kh-previa-vacia { font-weight: 400; color: var(--gris-2); }

.kh-filtros { display: flex; flex-wrap: wrap; }
.kh-filtro {
    padding: 4px 10px;
    border: var(--borde-fino) solid var(--hueso);
    color: var(--hueso);
    transition: background-color 120ms, color 120ms;
}
.kh-filtro + .kh-filtro { border-left: 0; }
.kh-filtro:hover { text-decoration: none; background: var(--hueso); color: var(--tinta); }
.kh-filtro-activo { background: var(--hueso); color: var(--tinta); font-weight: 700; }
.kh-filtro-senal { background: var(--senal); color: var(--tinta); border-color: var(--senal); }
.kh-fila-elegida td { background: var(--hueso-2); }

/* Fila que el usuario ha dejado fuera: no se difumina entera —hay que poder
   leerla y volver a encenderla—, solo la corregida se apaga para decir «esto
   no se va a aplicar». Sin amarillo: es una decisión, no una duda. */
.kh-fila-inactiva .kh-corregida { color: var(--gris-2); text-decoration: line-through; text-decoration-thickness: 1px; }
.kh-fila-inactiva .kh-chip { border-color: var(--gris-2); color: var(--gris-2); }
.kh-fila-inactiva .kh-chip-duda { border-color: var(--tinta); color: var(--tinta); }
.kh-btn-apagado { border-color: var(--gris-2); color: var(--gris); }
.kh-fila-form { margin: 0; }

.kh-kpi-nota { color: var(--gris); }

.kh-paginacion { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; padding: 12px; border-top: var(--borde-fino) solid var(--tinta); }
.kh-paginacion .kh-lab { color: var(--gris); }

/* -------------------------------------------------------------- Tablas */

.kh-tabla-scroll { overflow-x: auto; }
.kh-tabla { border-collapse: collapse; width: 100%; }
.kh-tabla th {
    text-align: left; padding: 8px 12px;
    background: var(--tinta); color: var(--hueso);
    font-size: 11px; letter-spacing: .12em; text-transform: uppercase; font-weight: 500;
    border-bottom: var(--borde) solid var(--tinta);
}
.kh-tabla td { text-align: left; padding: 10px 12px; border-bottom: var(--borde-fino) solid var(--tinta); vertical-align: top; }
.kh-tabla .kh-ancha { min-width: 260px; }
.kh-tabla .kh-estrecha { white-space: nowrap; }
.kh-tabla tr:last-child td { border-bottom: 0; }
.kh-fila-dudosa td { background: var(--senal); }
.kh-fila-apagada td { color: var(--gris); }
.kh-original { color: var(--gris); }
.kh-corregida { font-weight: 700; }

.kh-chip {
    display: inline-block; padding: 1px 6px; font-size: 11px;
    border: var(--borde-fino) solid var(--tinta);
    margin: 0 4px 4px 0;
}
.kh-chip-duda { background: var(--senal); font-weight: 700; }
.kh-chip-igual { border-style: dashed; color: var(--gris); }

/* --------------------------------------------------------- Formularios */

.kh-form { display: flex; flex-direction: column; gap: 6px; }
.kh-form label { margin-top: 12px; }
.kh-form input[type="text"], .kh-form input[type="password"], .kh-form input[type="file"], .kh-form select, .kh-form textarea {
    font-family: var(--mono); font-size: 13px;
    padding: 10px 12px; min-height: 44px;
    border: var(--borde) solid var(--tinta); border-radius: 0;
    background: var(--hueso); color: var(--tinta);
}
.kh-form .kh-btn { margin-top: 20px; align-self: flex-start; }
.kh-form-caja { padding: 16px 12px 20px; }
.kh-form textarea { resize: vertical; min-height: 44px; }
.kh-form input[readonly], .kh-form textarea[readonly], .kh-form select:disabled { color: var(--gris); background: var(--hueso-2); }
.kh-form .kh-botonera { margin-top: 20px; }
.kh-form .kh-botonera .kh-btn { margin-top: 0; }
.kh-ayuda { font-size: 12px; color: var(--gris); }
.kh-ayuda-caja { padding: 12px; border-top: var(--borde-fino) solid var(--gris-2); }

/* Las casillas del paso 1 son las mismas que las de las reglas: cuadradas y
   en tinta. Sin esto salen en el azul del navegador, y con todas marcadas de
   fábrica son diez manchas de un color que no es de la casa. */
#columnas input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--tinta); }

/* Paso 1: «Marcar todas» y «Desmarcar todas» encima de la tabla de columnas.
   Dos botones menudos pegados, no una botonera de pantalla: no deciden nada,
   solo ahorran treinta clics. */
.kh-botonera-columnas { align-self: flex-start; }

/* Paso 1: ajustes de lectura en una fila que comparte borde con la caja. */
.kh-columna { display: flex; flex-direction: column; gap: 20px; }
.kh-ajustes { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 20px; padding: 16px 12px; }
.kh-ajustes .kh-btn { margin-left: auto; }
.kh-dato { display: flex; flex-direction: column; gap: 4px; }
.kh-dato .kh-lab { color: var(--gris); }
.kh-dato select {
    font-family: var(--mono); font-size: 13px;
    padding: 8px 10px; min-height: 44px;
    border: var(--borde) solid var(--tinta); border-radius: 0;
    background: var(--hueso); color: var(--tinta);
}

/* ------------------------------------------------------------- Avisos */

.kh-aviso { padding: 12px 16px; border: var(--borde) solid var(--tinta); }
.kh-aviso-error { border-color: var(--error); color: var(--error); }
.kh-aviso-aviso { background: var(--senal); }
/* El aviso al lado de una casilla: «Es un email: normalizarlo lo puede estropear». */
.kh-aviso-en-linea { display: block; margin-top: 4px; padding: 2px 6px; background: var(--senal); font-size: 12px; max-width: 22ch; }
.kh-aviso-exito::before { content: '✓ '; }

/* Paso 5 · lo que no cabe (fase 6b). El aviso entero es amarillo porque
   todo él es algo que revisar. Arriba, siempre a la vista, el «Resolver con»
   y «Aplicar cambios»; debajo, la lista plegada como las categorías del paso 2
   (▸/▾ delante), con una fila corta por carta. «Sin resolver» se invierte en
   el resumen para que se vea sin desplegar. */
.kh-desbordes { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
.kh-desbordes-mando { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.kh-desbordes-mando .kh-dato { min-width: 220px; }
/* Una opción por campo, debajo de la general: un selector por campo que no cabe. */
.kh-desbordes-por-campo { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px 20px; }
.kh-desbordes-por-campo .kh-dato { min-width: 220px; max-width: 340px; }
.kh-desbordes-por-campo .kh-error-campo { margin: 4px 0 0; }
.kh-desbordes-cabeza { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; padding: 6px 0; }
.kh-desbordes-cabeza:hover { background: none; color: inherit; text-decoration: underline; text-decoration-thickness: 2px; }
.kh-desbordes-titulo { font-size: 14px; font-weight: 700; display: inline; }
.kh-desbordes-resumen { font-size: 12px; }
.kh-desbordes-sin-senal { background: var(--tinta); color: var(--senal); padding: 1px 6px; font-weight: 700; }
.kh-desbordes-filtro { display: flex; flex-wrap: wrap; gap: 14px; margin: 8px 0; }
.kh-desbordes-filtro [aria-pressed="true"] { color: var(--tinta); font-weight: 700; text-decoration: underline; text-decoration-thickness: 2px; }
.kh-tabla-densa { background: var(--hueso); font-size: 12px; }
.kh-tabla-densa th { padding: 5px 8px; }
/* Una o dos líneas por carta: nada se parte salvo el destinatario y lo que no
   cabe, que pueden ir en dos. Las columnas se cuentan desde el final porque
   delante puede ir la del fichero; cada una con su selector, para que ninguna
   regla le gane a otra por especificidad —«Sale» se partía así: «reduc/ir»—.
   En una carta sin resolver, el motivo va en su propio bloque, que sí se
   parte, y la palabra de «Sale» se queda entera. */
.kh-tabla-densa td { padding: 3px 8px; vertical-align: middle; white-space: nowrap; }
.kh-tabla-densa[data-editable] td:nth-last-child(6),
.kh-tabla-densa[data-editable] td:nth-last-child(5),
.kh-tabla-densa:not([data-editable]) td:nth-last-child(5),
.kh-tabla-densa:not([data-editable]) td:nth-last-child(4) { white-space: normal; overflow-wrap: anywhere; }
.kh-desborde-motivo { display: block; white-space: normal; max-width: 30ch; font-size: 11px; font-weight: 400; }
.kh-desborde-sin { font-weight: 700; }
.kh-gris { color: var(--gris); }
table[data-filtro="sin"] tr[data-estado]:not([data-estado="sin"]),
table[data-filtro="salto"] tr[data-estado]:not([data-estado="salto"]),
table[data-filtro="reducir"] tr[data-estado]:not([data-estado="reducir"]),
table[data-filtro="tal-cual"] tr[data-estado]:not([data-estado="tal-cual"]) { display: none; }
.kh-desbordes-elecciones { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 8px 0; }
.kh-lista-compacta { margin: 4px 0 8px; padding-left: 18px; }
.kh-lista-plegada > summary { cursor: pointer; text-decoration: underline; text-decoration-thickness: 2px; margin: 4px 0; }
/* «Más información»: lo que no hace falta leer para usar la pantalla, plegado
   de fábrica con el mismo aire que las listas plegadas. Una línea de ayuda a la
   vista por bloque como mucho; el resto, aquí (1 nov 2026). */
.kh-mas { margin: 6px 0; font-size: 13px; }
.kh-mas > summary { cursor: pointer; color: var(--gris); text-decoration: underline; text-decoration-thickness: 2px; width: fit-content; }
.kh-mas[open] > summary { margin-bottom: 6px; }
.kh-mas > :not(summary) { margin: 0 0 6px; }
.kh-casilla { display: flex; align-items: center; gap: 8px; margin-top: 4px; font-weight: 700; }
.kh-casilla input { width: 18px; height: 18px; accent-color: var(--tinta); }
/* Una casilla de un formulario: la caja y su texto en la misma línea, sin
   recuadro que la haga pasar por botón, y debajo, en gris, a qué afecta. */
.kh-form .kh-casilla { flex-wrap: wrap; margin: 6px 0 0; }
.kh-form .kh-casilla label { margin-top: 0; cursor: pointer; }
.kh-casilla-nota { flex: 1 0 100%; padding-left: 26px; font-weight: 400; font-size: 13px; }
/* Paso 5 · la cabecera del informe de postalización: tres campos en fila. */
.kh-informe-campos { display: flex; flex-wrap: wrap; gap: 12px; }
.kh-informe-campos .kh-dato { flex: 1 1 160px; }
.kh-informe-campos .kh-dato-ancho { flex: 2 1 260px; }
.kh-informe-campos input { font-family: var(--mono); font-size: 13px; padding: 8px 10px; min-height: 40px; border: var(--borde) solid var(--tinta); background: var(--hueso); }
.kh-ficheros { list-style: none; margin: 8px 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.kh-ficheros .kh-btn { margin-right: 8px; }
.kh-generar { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }

/* -------------------------------------------------------------- Login */

.kh-login { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; }
.kh-login-caja {
    width: 100%; max-width: 420px;
    border: var(--borde) solid var(--tinta);
    padding: 0 0 28px;
    display: flex; flex-direction: column;
}
.kh-login-marca {
    padding: 14px 20px;
    background: var(--tinta); color: var(--hueso);
    font-family: var(--display); font-weight: 900; font-size: 18px; letter-spacing: .06em;
}
.kh-login-titulo { font-size: 28px; padding: 24px 20px 0; }
.kh-login .kh-form { padding: 0 20px; }
.kh-login .kh-aviso { margin: 20px 20px 0; }

/* --------------------------------------------------------- Responsive */

@media (max-width: 1199px) {
    .kh-app { grid-template-columns: 200px minmax(0, 1fr); }
    .kh-marca-lateral, .kh-usuario, .kh-nav > a { padding-left: 14px; padding-right: 14px; }
    .kh-titular { flex-direction: column; align-items: flex-start; gap: 16px; }
}

@media (max-width: 767px) {
    h1 { font-size: 28px; }

    /* En una pantalla de 360px, 24px por lado son 48px menos de dirección. */
    .kh-contenido { padding: 20px 16px 40px; }
    .kh-cifra { font-size: 32px; }
    .kh-cifra-texto { font-size: 22px; }

    /* El lateral se pliega en una barra superior: marca a la izquierda, botón
       «Menú» invertido a la derecha y las secciones apiladas debajo. Sin
       JavaScript no hay botón y el lateral se queda desplegado, que es la
       única forma de que un fallo del script no deje la navegación
       inalcanzable en el teléfono. */
    .kh-app { display: block; }
    .kh-lateral { position: static; height: auto; overflow: visible; border-bottom: var(--borde) solid var(--tinta); }
    .kh-menu-boton {
        display: flex; align-items: center;
        padding: 0 16px;
        border: 0; border-left: var(--borde-fino) solid var(--gris);
        background: var(--tinta); color: var(--hueso);
        font-family: var(--mono); cursor: pointer;
    }
    .kh-con-js .kh-lateral-cuerpo { display: none; }
    .kh-con-js .kh-menu-abierto .kh-lateral-cuerpo { display: flex; }
    .kh-nav-salir { margin-top: 0; }

    .kh-miga { padding: 8px 16px; }

    .kh-pasos { grid-template-columns: 1fr; }
    .kh-paso:not(.kh-paso-actual) { display: none; }

    .kh-rejilla-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .kh-kpi:nth-child(2) { border-right: 0; }
    .kh-kpi:nth-child(-n+2) { border-bottom: var(--borde) solid var(--tinta); }

    .kh-caja-titulo { align-items: flex-start; }
    .kh-filtros { width: 100%; }
    .kh-filtro { flex: 1 1 auto; text-align: center; min-height: 34px; display: flex; align-items: center; justify-content: center; }

    .kh-exportacion, .kh-zona-peligro { flex-direction: column; align-items: stretch; }

    .kh-previa { grid-template-columns: 1fr; gap: 2px; }
    .kh-previa dd + dt { margin-top: 10px; }

    .kh-ajustes { flex-direction: column; align-items: stretch; }
    .kh-ajustes .kh-btn { margin-left: 0; }

    .kh-botonera { flex-direction: column; width: 100%; }
    .kh-botonera .kh-btn + .kh-btn { border-left: var(--borde) solid var(--tinta); border-top: 0; }

    /* Tabla → tarjeta, un solo patrón para toda la app. */
    .kh-tabla thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
    .kh-tabla, .kh-tabla tbody, .kh-tabla tr, .kh-tabla td { display: block; }
    .kh-tabla-scroll { padding: 12px; }
    .kh-tabla tr { border: var(--borde) solid var(--tinta); margin: 0 0 12px; padding: 8px 0; }
    .kh-tabla tr:last-child { margin-bottom: 0; }
    .kh-tabla td { border-bottom: 0; padding: 4px 12px; }
    .kh-tabla td[data-etiqueta]::before { content: attr(data-etiqueta) ' · '; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--gris); }
    .kh-tabla td:first-child { font-weight: 700; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { transition: none !important; animation: none !important; }
}
