/* ════════════════════════════════════════════════════════════════════
   LA REJA DE RRHH — Novedades del Mes (/hr/novedades) y Cierre del Mes
   (/hr/mes/{año}/{mes}).

   ⚠ ESTA HOJA REQUIERE css/dialog-system.css, CARGADA ANTES.
   Lo genérico —el campo, el grupo de campos, la rejilla de 12, los botones,
   las teclas <kbd>, la barra de pie y la PALETA— lo pone el sistema. Acá vive
   sólo lo que ningún diálogo tiene: la rejilla de 8 columnas, la fila de 52px,
   la columna de marcas, el renglón del pie y la tipografía de la plata.

   POR QUÉ ESTA HOJA ES UNA HERMANA DE journal-entry.css Y NO UN REFACTOR DE
   ELLA. El patrón —lista de filas de alto fijo + un editor expandido por vez,
   con el cursor movido y pintado por el navegador— es EL MISMO que el
   comprobante ya tiene probado con 171 líneas. Extraer un núcleo compartido
   obligaría a tocar journal-entry.css y je-grid.js, que sirven a la pantalla
   portada del prototipo aprobado, en la misma tanda en que se estrena otra
   reja, a cambio de ahorrar unas doscientas líneas. Se paga la duplicación a
   conciencia y queda anotado el disparador: cuando exista una TERCERA reja se
   extrae el núcleo, ya con dos pantallas aprobadas de red de seguridad.

   LOS --nov-* SON ALIAS DE LOS --dlg-*, igual que los --je-*: ni un
   hexadecimal crudo, todo sale de la paleta de MudBlazor por el sistema de
   diálogo, así el tema claro y el oscuro siguen funcionando solos.

   UNA SOLA HOJA PARA LAS DOS PANTALLAS, y a propósito: la reja de Cierre del
   Mes es la MISMA reja en modo lectura. Se distingue con el modificador
   `.mes`, que lo único que hace es redefinir el ancho de las 8 columnas y
   agregar el semáforo. Duplicar la hoja para cambiar ocho anchos habría sido
   la tercera copia del mismo archivo.
   ════════════════════════════════════════════════════════════════════ */

/* ─── LA REJILLA COMPARTIDA ───────────────────────────────────────────
   Un solo lugar define el ancho de las columnas. Encabezado, filas y el
   renglón del pie usan esta misma variable, así los totales no se pueden
   correr de su columna. El pie NO es descendiente de .nov (es hermano), por
   eso las variables se declaran para los dos. */
.nov,
.nov-pie {
    --nov-mono: var(--dlg-mono);
    --nov-primary: var(--dlg-primary);
    --nov-surf: var(--dlg-surf);
    --nov-surf2: var(--dlg-surf2);
    --nov-lines: var(--dlg-lines);
    --nov-lines2: var(--dlg-lines2);
    --nov-txt: var(--dlg-txt);
    --nov-dim: var(--dlg-dim);
    --nov-dim2: var(--dlg-dim2);
    --nov-verde: var(--dlg-verde);
    --nov-verde-bg: var(--dlg-verde-bg);
    --nov-rojo: var(--dlg-rojo);
    --nov-rojo-bg: var(--dlg-rojo-bg);
    --nov-ambar: var(--dlg-ambar);
    --nov-ambar-bg: var(--dlg-ambar-bg);
    --nov-ambar-bd: var(--dlg-ambar-bd);

    --nov-sel: var(--mud-palette-primary-hover);

    /* El MISMO 52px del comprobante, y por la MISMA razón, no por copiar el
       número: es el alto que deja entrar dos renglones en una celda. Acá la
       celda de trabajador (ficha + nombre) y la de concepto (código + nombre
       impreso) necesitan exactamente eso. */
    --nov-fila-h: 52px;

    /* Ancho de la barra de desplazamiento del scroller. El renglón del pie vive
       FUERA del scroller: sin descontarlo, los totales quedan corridos respecto
       de su columna. Lo mide nov-grid.js. */
    --nov-sbw: 0px;

    /* Columna de marcas. Los MISMOS 132px del comprobante: es el ancho en que
       entran dos insignias cortas en dos renglones sin mover la fila. */
    --nov-marc: 132px;

    /*  #   trabajador          concepto            cant   valor  monto  marcas       acc */
    --nov-grid: 44px minmax(140px, 1.15fr) minmax(160px, 1.5fr) 96px 116px 128px var(--nov-marc) 34px;
}

/* Cierre del Mes: la misma reja, otras ocho columnas.
      #   trabajador          días  haberes descuentos líquido  semáforo    acc  */
.nov.mes,
.nov-pie.mes {
    --nov-grid: 44px minmax(170px, 1.6fr) 70px 128px 128px 138px var(--nov-marc) 34px;
}

.nov-grid {
    display: grid;
    grid-template-columns: var(--nov-grid);
    align-items: stretch;
    min-width: 0;
}

.nov {
    display: flex;
    flex-direction: column;
    min-width: 0;
    font-size: 13px;
    color: var(--nov-txt);
    background: var(--nov-surf);
    border: 1px solid var(--nov-lines);
    border-radius: 12px;
    /* El redondeo sólo sirve si algo recorta: sin esto el encabezado pegajoso
       pinta sus esquinas cuadradas por encima del borde. */
    overflow: hidden;
}

/* ═══ 1 · CINTILLO DE ESTADO DEL PERÍODO ═══
   Una línea, ANTES de la reja y nunca fuera de pantalla. La lección ya escrita
   en docs/PENDIENTE-PAGINADOR-Y-PERIODO-CERRADO.md: un formulario que te deja
   escribir veinte líneas y recién al guardar te dice que no se podía es peor
   que uno bloqueado. Acá el aviso llega ANTES de tocar nada. */
.nov-cintillo {
    flex: 0 0 auto;
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 8px 14px;
    border-bottom: 1px solid var(--nov-lines);
    background: var(--nov-surf2);
    color: var(--nov-dim);
    font-size: 12.5px;
    line-height: 1.45;
}

.nov-cintillo .ico {
    font-size: 14px;
    line-height: 1.3;
    flex-shrink: 0;
}

.nov-cintillo b {
    color: var(--nov-txt);
}

/* Mes cerrado: ámbar. No es un error del usuario, es el estado del período. */
.nov-cintillo.cerrado {
    background: var(--nov-ambar-bg);
    border-bottom-color: var(--nov-ambar-bd);
    color: var(--nov-ambar);
}

.nov-cintillo.cerrado b {
    color: var(--nov-ambar);
}

/* Sin nómina creada todavía: informativo, no advertencia. Cargar novedades
   antes de que exista la nómina es lo NORMAL —el encargado junta los datos
   durante el mes— así que no puede pintarse como un problema. */
.nov-cintillo.aviso {
    background: color-mix(in srgb, var(--nov-primary) 6%, var(--nov-surf));
    border-bottom-color: color-mix(in srgb, var(--nov-primary) 24%, var(--nov-lines));
}

.nov-cintillo a {
    color: var(--nov-primary);
    font-weight: 600;
}

/* ═══ 2 · BARRA DE LA REJA — fuera del scroller ═══ */
.nov-barra {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px 6px 10px;
    border-bottom: 1px solid var(--nov-lines2);
    background: var(--nov-surf);
}

.nov-barra .tit {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--nov-primary);
}

.nov-barra .cuenta {
    font-size: 11.5px;
    color: var(--nov-dim);
    font-variant-numeric: tabular-nums;
}

.nov-barra .der {
    margin-left: auto;
    display: flex;
    gap: 6px;
    align-items: center;
}

/* ═══ 3 · CAJA DE FILAS — EL ÚNICO SCROLL DE LA PANTALLA ═══
   Acá SÍ se usa `vh`, al revés que en el comprobante, y por la misma razón por
   la que allá está prohibido: el alto de esta reja no lo manda ninguna ventana
   flotante, lo manda la pantalla. Con el tope en vh la reja nunca empuja el pie
   fuera de la vista, y el pie además va pegajoso (ver .nov-pie). */
.nov-lineas {
    flex: 1 1 auto;
    max-height: 58vh;
    /* 148px = encabezado fijo + dos filas. Es el mínimo con el que la pantalla
       sigue diciendo la verdad en una ventana aplastada. */
    min-height: 148px;
    min-width: 0;
    overflow: auto;
    overflow-x: hidden;
    scrollbar-gutter: stable;
    outline: none;
    background: var(--nov-surf);
    /* Para que el offsetTop de las filas se mida contra la caja: es lo que usa
       nov-grid.js para desplazar sin meter la fila debajo del encabezado fijo. */
    position: relative;
}

.nov-head {
    position: sticky;
    top: 0;
    z-index: 6;
    background: var(--nov-surf2);
    border-bottom: 1px solid var(--nov-lines);
    box-shadow: 0 1px 0 var(--nov-lines);
}

.nov-head .h {
    padding: 7px 8px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--nov-dim);
    white-space: nowrap;
    overflow: hidden;
    display: flex;
    align-items: center;
}

.nov-head .h.num {
    justify-content: flex-end;
}

/* ─── FILA COLAPSADA ───
   ALTO FIJO, no min-height: ninguna fila puede crecer por su contenido. Con
   alto fijo el scroll es predecible y ni un error de validación ni tres marcas
   mueven nada de lo de abajo. */
.nov-row {
    height: var(--nov-fila-h);
    border-bottom: 1px solid var(--nov-lines2);
    cursor: default;
    position: relative;
    background: var(--nov-surf);
}

.nov-row:hover {
    background: var(--nov-surf2);
}

/* La selección la pinta el JS con un atributo propio (data-sel) y no con una
   clase: así Blazor nunca la pisa al re-renderizar la fila, y moverse con las
   flechas no cuesta un solo viaje al servidor. */
.nov-row[data-sel="1"] {
    background: var(--nov-sel);
}

.nov-row.abierta {
    background: var(--nov-sel);
}

/* El riel de 3px es del ERROR y SÓLO del error. El ÁMBAR no lleva riel a
   propósito, por lo mismo que ya se midió en el comprobante: un riel por
   advertencia deja una pared de color de punta a punta que nadie mira. El
   ámbar se dice donde importa, en la insignia de la columna de marcas. */
.nov-row.err {
    box-shadow: inset 3px 0 0 var(--nov-rojo);
}

/* Fila DERIVADA: no se teclea, la calcula el motor con otras dos filas. Se
   distingue por el fondo rayado y por su insignia, nunca sólo por el color. */
.nov-row.derivada {
    /* El rayado se mezcla con el PRIMARIO y no con el gris del tema: alternar
       surf/surf2 daba una cebra fuertísima en oscuro, donde esos dos tonos están
       lejos. Mezclando contra el fondo el rayado pesa lo mismo en claro y en
       oscuro, y sigue leyéndose sin ser el color lo único que lo distingue —al
       lado va siempre la insignia «derivado». */
    background: repeating-linear-gradient(
        135deg,
        var(--nov-surf),
        var(--nov-surf) 7px,
        color-mix(in srgb, var(--nov-primary) 7%, var(--nov-surf)) 7px,
        color-mix(in srgb, var(--nov-primary) 7%, var(--nov-surf)) 14px);
    cursor: default;
}

.nov .c {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 3px 8px;
    min-width: 0;
    overflow: hidden;
}

.nov .c.num {
    align-items: flex-end;
}

.nov .c.ctr {
    align-items: center;
}

/* # de fila */
.nov .c-n {
    align-items: flex-end;
    justify-content: center;
    font-family: var(--nov-mono);
    font-size: 11px;
    color: var(--nov-dim2);
    font-variant-numeric: tabular-nums;
    padding-right: 9px;
}

/* display:block en TODAS las celdas de texto. En un <span> inline el
   overflow:hidden y el text-overflow:ellipsis NO se aplican: el texto se sale y
   lo corta el padre a hachazos, sin puntos suspensivos. */
.nov .c-trab .nom,
.nov .c-trab .ficha,
.nov .c-con .cod,
.nov .c-con .nom {
    display: block;
}

/* Trabajador — ficha arriba (es lo que se busca), nombre abajo. */
.nov .c-trab .ficha {
    font-family: var(--nov-mono);
    font-size: 11.5px;
    font-weight: 650;
    color: var(--nov-dim);
    font-variant-numeric: tabular-nums;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nov .c-trab .nom {
    font-size: 12.5px;
    line-height: 1.3;
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nov .c-trab .sin,
.nov .c-con .sin {
    font-size: 12px;
    color: var(--nov-dim2);
    font-style: italic;
}

/* Concepto — código arriba, nombre IMPRESO abajo: el nombre impreso es el que
   el trabajador va a leer en su liquidación, así que es el que hay que ver. */
.nov .c-con .cod {
    font-family: var(--nov-mono);
    font-size: 12.5px;
    font-weight: 650;
    letter-spacing: -.02em;
    white-space: nowrap;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nov .c-con .nom {
    font-size: 10.5px;
    color: var(--nov-dim);
    line-height: 1.3;
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Fila corrida: MISMO trabajador que la de arriba. El dato sigue legible, sólo
   baja de énfasis y aparece el riel de continuidad. Es lo que deja leer de un
   vistazo «estas cuatro filas son de la misma persona». */
.nov-row.corrida .c-trab .nom {
    opacity: .5;
}

.nov-row.corrida .c-trab .ficha {
    opacity: .5;
}

.nov-row.corrida .c-trab::before {
    content: "";
    position: absolute;
    left: 2px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--nov-lines);
    opacity: .8;
}

/* Números — tipografía de libro contable, la misma de la plata del comprobante. */
.nov .c-num {
    align-items: flex-end;
    justify-content: center;
}

.nov .c-num .n {
    font-family: var(--nov-mono);
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.01em;
    white-space: nowrap;
}

/* El monto es lo que más se mira: un punto más y más peso. */
.nov .c-monto .n {
    font-size: 13.5px;
    font-weight: 700;
}

.nov .c-monto {
    background: color-mix(in srgb, var(--nov-primary) 3.5%, transparent);
}

/* Un descuento se lee restando aunque se teclee en positivo: el signo lo pone
   la pantalla según el TIPO del concepto, para que nadie tenga que teclear un
   menos y para que un descuento no se confunda con un haber. */
.nov .c-monto .n.resta {
    color: var(--nov-rojo);
}

.nov .c-num .vacio {
    font-size: 11px;
    color: var(--nov-dim2);
    font-style: italic;
}

/* Marcas: la MISMA columna de 132px del comprobante y las mismas insignias. */
.nov .c-marc {
    flex-direction: row;
    align-items: center;
    align-content: center;
    gap: 3px 4px;
    flex-wrap: wrap;
    max-height: 100%;
}

.nov .c-marc:empty {
    padding: 0;
}

.nov .marca {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 10px;
    font-weight: 650;
    letter-spacing: .02em;
    padding: 1px 5px;
    border-radius: 4px;
    white-space: nowrap;
    background: var(--nov-surf2);
    border: 1px solid var(--nov-lines);
    color: var(--nov-dim);
}

/* Dato pendiente o estado del período: ámbar. No es culpa de nadie. */
.nov .marca.falta {
    background: var(--nov-ambar-bg);
    border-color: var(--nov-ambar-bd);
    color: var(--nov-ambar);
}

/* Error de verdad: la fila no se puede guardar así. */
.nov .marca.mala {
    background: var(--nov-rojo-bg);
    border-color: color-mix(in srgb, var(--nov-rojo) 40%, transparent);
    color: var(--nov-rojo);
}

/* Informativa: no es problema, es cómo va a comportarse el cálculo. */
.nov .marca.info {
    background: color-mix(in srgb, var(--nov-primary) 9%, var(--nov-surf));
    border-color: color-mix(in srgb, var(--nov-primary) 34%, var(--nov-lines));
    color: color-mix(in srgb, var(--nov-primary) 78%, var(--nov-txt));
}

.nov .marca.ok {
    background: var(--nov-verde-bg);
    border-color: color-mix(in srgb, var(--nov-verde) 35%, transparent);
    color: var(--nov-verde);
}

/* Acción / chevron */
.nov .c-act {
    align-items: center;
    justify-content: center;
    padding: 0;
    color: var(--nov-dim2);
    font-size: 12px;
    cursor: pointer;
}

.nov .c-act .chev {
    display: inline-block;
    transition: transform .16s;
}

.nov-row.abierta .c-act .chev {
    transform: rotate(90deg);
    color: var(--nov-primary);
}

/* Punto de problema sobre la celda culpable: absoluto, NO empuja nada. */
.nov .c.malo::after,
.nov .c.dudoso::after {
    content: "";
    position: absolute;
    top: 4px;
    right: 3px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
}

.nov .c.malo::after { background: var(--nov-rojo); }
.nov .c.dudoso::after { background: var(--nov-ambar); }

/* ═══ 4 · ESTADO VACÍO — con su salida a la vista ═══
   Tres vacíos distintos y cada uno con lo que hay que hacer AHÍ MISMO, no en
   un texto que remite a otra pantalla sin llevar a ella. */
.nov-vacio {
    padding: 34px 24px 38px;
    text-align: center;
    color: var(--nov-dim);
    font-size: 13px;
    line-height: 1.6;
}

.nov-vacio .tit {
    display: block;
    font-size: 14.5px;
    font-weight: 700;
    color: var(--nov-txt);
    margin-bottom: 4px;
}

.nov-vacio .acciones {
    display: flex;
    gap: 9px;
    justify-content: center;
    margin-top: 14px;
    flex-wrap: wrap;
}

/* ═══ 5 · EDITOR EXPANDIDO (acordeón) ═══
   NO ES UN MODAL, ES UN CURSOR. Se abre en el sitio empujando las de abajo, y
   ↑/↓ lo mueven de fila en fila cayendo en el MISMO campo: cargar cuarenta
   anticipos seguidos no obliga a abrir ni a cerrar nada. */
.nov-exp {
    border-bottom: 1px solid var(--nov-lines);
    background: var(--nov-surf2);
    box-shadow: inset 3px 0 0 var(--nov-primary), inset 0 1px 0 var(--nov-lines2);
    padding: 14px 16px 16px 18px;
    animation: nov-exp-in .16s ease-out;
}

@keyframes nov-exp-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .nov-exp { animation: none; }
}

.nov-exp .exp-tit {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 12px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--nov-primary);
}

.nov-exp .exp-tit .n {
    font-family: var(--nov-mono);
    background: var(--nov-primary);
    color: var(--mud-palette-primary-text);
    padding: 2px 7px;
    border-radius: 5px;
    letter-spacing: 0;
}

.nov-exp .exp-tit .der {
    margin-left: auto;
    display: flex;
    gap: 6px;
}

.nov-exp .exp-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 10px 12px;
    align-items: end;
}

/* El monto: la tipografía de la plata. Es lo que más se mira de esta pantalla. */
.nov-exp .campo.plata .mud-input input {
    font-family: var(--nov-mono);
    font-size: 19px !important;
    font-weight: 700;
    text-align: right;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.01em;
}

.nov-exp .campo.plata .mud-input.mud-input-outlined > input {
    height: 38px;
}

/* Opción del desplegable de trabajador / concepto. Vive FUERA de .nov
   (MudBlazor manda sus popover al final del <body>), así que acá no hay
   variables --nov-* que heredar: se leen las de MudBlazor directo. */
.nov-op {
    display: flex;
    align-items: baseline;
    gap: 9px;
    min-width: 0;
    width: 100%;
}

.nov-op .cod {
    font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    font-weight: 650;
    flex-shrink: 0;
    color: var(--mud-palette-primary);
}

.nov-op .nom {
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nov-op .tipo {
    margin-left: auto;
    font-size: 10.5px;
    color: var(--mud-palette-text-secondary);
    flex-shrink: 0;
}

/* ═══ 6 · PIE FIJO — el efecto, el estado y los botones ═══
   El efecto sobre la nómina está SIEMPRE a la vista y no detrás de un botón
   «previsualizar»: un botón de previsualizar es un paso que la gente se salta.
   Es el mismo problema que el comprobante resolvió con su pie en dos niveles.

   Pegajoso al fondo de la ventana: con la reja topada en 58vh el pie ya entra
   solo, pero en una pantalla baja o con el navegador achicado `sticky` es lo
   que garantiza que los números y los botones no se pierdan de vista. */
.nov-pie {
    position: sticky;
    bottom: 0;
    z-index: 7;
    flex-shrink: 0;
    width: 100%;
    background: var(--nov-surf2);
    border-top: 2px solid var(--nov-lines);
    color: var(--nov-txt);
    font-size: 13px;
}

/* El renglón del efecto cae bajo las MISMAS columnas de la reja. */
.nov-tot {
    border-bottom: 1px solid var(--nov-lines2);
    padding-right: var(--nov-sbw);
}

.nov-tot .t {
    padding: 8px;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: center;
    white-space: nowrap;
    overflow: hidden;
}

.nov-tot .t .rot2 {
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--nov-dim);
}

.nov-tot .t .n {
    font-family: var(--nov-mono);
    font-size: 15px;
    font-weight: 750;
    font-variant-numeric: tabular-nums;
}

.nov-tot .t .n.mas { color: var(--nov-verde); }
.nov-tot .t .n.menos { color: var(--nov-rojo); }
.nov-tot .t .n.neto { color: var(--nov-txt); }

.nov-tot .rot {
    align-items: flex-start;
    justify-content: center;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--nov-dim);
    padding-left: 14px;
}

/* La aclaración de lo que el número NO incluye. Va pegada al número y no en
   una ayuda escondida: un total honesto tiene que decir de qué es total. */
.nov-nota {
    padding: 6px 14px;
    border-bottom: 1px solid var(--nov-lines2);
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--nov-dim);
}

.nov-acciones {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 14px;
    flex-wrap: wrap;
}

.nov-acciones .der {
    margin-left: auto;
    display: flex;
    gap: 9px;
    align-items: center;
}

.nov-acciones .contadores {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12px;
    color: var(--nov-dim);
}

.nov-acciones .prob {
    font: inherit;
    font-size: 11.5px;
    font-weight: 650;
    color: var(--nov-rojo);
    cursor: pointer;
    border: 1px solid color-mix(in srgb, var(--nov-rojo) 35%, transparent);
    background: var(--nov-rojo-bg);
    border-radius: 6px;
    padding: 3px 9px;
}

.nov-acciones .sin-guardar {
    font-size: 12px;
    color: var(--nov-ambar);
    font-weight: 650;
}

/* ═══ 7 · EL SEMÁFORO POR TRABAJADOR (Cierre del Mes) ═══
   Por trabajador y CON CAUSA: es lo que hace que el operador sepa POR QUÉ no
   puede cerrar el mes. Nunca es sólo el color —al lado va siempre la palabra—
   para quien no distingue los colores. */
.nov .sem {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    font-weight: 650;
    white-space: nowrap;
}

.nov .sem .pt {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
}

.nov .sem.rojo { color: var(--nov-rojo); }
.nov .sem.rojo .pt { background: var(--nov-rojo); }
.nov .sem.ambar { color: var(--nov-ambar); }
.nov .sem.ambar .pt { background: var(--nov-ambar); }
.nov .sem.verde { color: var(--nov-verde); }
.nov .sem.verde .pt { background: var(--nov-verde); }

/* ─── El detalle de las observaciones del motor ───
   Cada una con SU TEXTO, no con un código, y CADA UNA con su salida: no sirve
   decirle a alguien que falta un dato sin decirle dónde se carga. */
.nov-obs {
    border-bottom: 1px solid var(--nov-lines);
    background: var(--nov-surf2);
    box-shadow: inset 3px 0 0 var(--nov-primary), inset 0 1px 0 var(--nov-lines2);
    padding: 12px 16px 14px 18px;
    animation: nov-exp-in .16s ease-out;
}

@media (prefers-reduced-motion: reduce) {
    .nov-obs { animation: none; }
}

.nov-obs .obs-tit {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 10px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--nov-primary);
}

.nov-obs .obs {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 8px 0;
    border-top: 1px solid var(--nov-lines2);
    font-size: 12.5px;
    line-height: 1.5;
}

.nov-obs .obs:first-of-type {
    border-top: 0;
}

.nov-obs .obs .pt {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
    margin-top: 5px;
}

.nov-obs .obs.rojo .pt { background: var(--nov-rojo); }
.nov-obs .obs.ambar .pt { background: var(--nov-ambar); }

.nov-obs .obs .col { flex: 1; min-width: 0; }

/* El código del motor, chiquito y AL LADO del texto — nunca en vez del texto.
   Va también en el diálogo de cierre (.dlg .codigo), que es el último lugar donde
   alguien decide si congela el mes: ahí «OPERANDO_FALTANTE» a secas no le dice
   nada a quien tiene que decidir, y la lista de atrás ya lo hacía bien. */
.nov-obs .obs .codigo,
.dlg .codigo {
    font-family: var(--nov-mono);
    font-size: 10.5px;
    color: var(--nov-dim2);
    letter-spacing: .03em;
}

/* Dentro del diálogo la regla de arriba se hereda por .dlg, pero los tokens
   --nov-* nacen en .nov / .nov-pie. Acá se los damos a .dlg apuntando al sistema,
   sin repetir ningún valor: si cambia dialog-system.css, esto cambia con él. */
.dlg {
    --nov-mono: var(--dlg-mono);
    --nov-dim2: var(--dlg-dim2);
}

.dlg .codigo { margin-left: 6px; }

.nov-obs .obs .salida {
    margin-left: auto;
    flex-shrink: 0;
}

/* ═══ 8 · LA ESCALERA DEL MES ═══
   No se reusa .wip-escalera del sistema: aquélla es un globo flotante anclado a
   una pastilla del pie del comprobante (position:absolute, bottom:calc(100%)),
   y esta escalera va PLANTADA en la pantalla, de lado a lado. Comparte el
   vocabulario visual —peldaño, .actual, .nom, .marca, .nota— y nada más. */
.mes-escalera {
    display: flex;
    align-items: stretch;
    gap: 0;
    overflow-x: auto;
    padding: 2px;
}

.mes-escalera .peldano {
    flex: 1 1 0;
    /* ⚠ `min-width: 0` es lo que permite que un hijo de flex se ENCOJA. Sin él, el ancho mínimo
       de un ítem flex es el de su contenido, así que una marca larga —«creada el 19/08 por
       e2d95fe9-…»— empujaba el peldaño más allá de su columna y el texto se montaba sobre el de
       al lado. El `min-width: 130px` de antes fijaba un piso pero no impedía el desborde. */
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px 14px;
    border-top: 3px solid var(--mud-palette-lines-default);
    opacity: .5;
}

.mes-escalera .peldano.pasado {
    opacity: .85;
    border-top-color: color-mix(in srgb, var(--mud-palette-primary) 45%, transparent);
}

.mes-escalera .peldano.actual {
    opacity: 1;
    border-top-color: var(--mud-palette-primary);
}

.mes-escalera .peldano .nom {
    font-size: 13px;
    font-weight: 700;
    color: var(--mud-palette-text-primary);
}

.mes-escalera .peldano.actual .nom {
    font-weight: 800;
    color: var(--mud-palette-primary);
}

.mes-escalera .peldano .marca {
    font-size: 11px;
    color: var(--mud-palette-text-secondary);
    line-height: 1.45;
    /* La marca ENVUELVE en vez de desbordarse. `anywhere` además parte una palabra que no cabe
       —un correo largo, un identificador— en lugar de dejarla sobresalir entera. */
    overflow-wrap: anywhere;
    min-width: 0;
}

.mes-escalera .peldano .nom,
.mes-escalera .peldano .nota {
    overflow-wrap: anywhere;
    min-width: 0;
}

/* El peldaño que TODAVÍA NO EXISTE en el sistema se dibuja punteado. Es la
   misma regla visual que el sistema de diálogo ya usa para el trabajo sin
   guardar: lo que no existe va punteado, lo que existe va sólido. */
.mes-escalera .peldano.futuro {
    border-top-style: dashed;
}

/* La nota del peldaño dice cosas que hay que poder leer —«este estado todavía no
   existe», «reabierto el 05/08 por…»— así que va en el gris SECUNDARIO y no en el
   de deshabilitado: en tema oscuro, `text-disabled` la dejaba invisible. */
.mes-escalera .peldano .nota {
    font-size: 10.5px;
    color: var(--mud-palette-text-secondary);
    line-height: 1.4;
}
