/*
 * Temas de Linsoft.
 *
 * Los 24 temas heredados son hojas completas de jQuery UI, de 30 a 40 KB cada
 * una. Aqui cada tema es solo el juego de variables: unos pocos KB, y el
 * cambio no obliga a recargar hojas de estilo.
 */
:root,
[data-tema="linsoft"] {
    --fondo: #eef2f5;
    --superficie: #ffffff;
    --superficie-2: #e3e9ee;
    /* La celda que no aplica: lo de SUNAT en un documento que no sale allí (el #ccd0d6 del heredado). */
    --celda-apagada: #ccd0d6;
    --texto: #1d2733;
    --texto-2: #55636f;
    --borde: #c3ced8;
    --acento: #0e5c6b;
    --acento-texto: #ffffff;
    --sombra: 0 1px 2px rgba(29, 39, 51, .08);
    --grave-fondo: #fdeceb;
    --grave-borde: #d9756a;
    --grave-texto: #7a1f14;
    --aviso-fondo: #fdf5e3;
    --aviso-borde: #d9ab4e;
    --aviso-texto: #6b4a05;
    /* Lo que está bien: el verde de «Aceptado» (`situacion-sunat.js`). */
    --bien-fondo: #e4f0e8;
    --bien-texto: #2a6144;

    /*
     * Lo que faltaba, y es la mitad de que esto pareciera apilado en vez de
     * diseñado: **escalas**. Habia colores y nada mas, de modo que cada vista
     * elegia su propio 12px, su propio 10px de margen y su propio relleno. Al
     * contarlo salieron 795 `style=` dentro del HTML.
     *
     * Tres escalas y nada mas. Una interfaz densa de gestion no necesita
     * quince tamaños: necesita que los pocos que hay se repitan.
     */
    --e1: 4px;
    --e2: 6px;
    --e3: 8px;
    --e4: 12px;
    --e5: 16px;

    /*
     * **Lo que separa un widget del siguiente**, y lo que el panel deja por
     * encima del primero: un solo valor, para que no puedan separarse.
     *
     * Lo pidio el propietario el 21 de septiembre de 2026 con «Documentos de
     * venta» y «Filtros» uno encima de otro: arriba del primero habia 6 px y
     * entre los dos 12, o sea el doble. Y **el heredado usa 5**: sus paneles
     * llevan `style="margin-top: 5px"` escrito a mano, uno por uno, en
     * `documentos_salidas/index.php` y en `reportes/kardex/index.php`.
     */
    --sep-widget: var(--e2);
    --e6: 24px;

    /*
     * **Los tamaños son los del heredado, medidos en pantalla.**
     *
     * Alli casi todo lo que se lee mide **12 px**: la celda de la rejilla, su
     * cabecera, la caja del filtro, el paginador, el rotulo de un campo y el
     * propio campo. El `body` va a 11, pero eso apenas se ve: casi nada hereda
     * de el sin que otra regla lo pise.
     *
     * Aqui estaba en 14 y se veia notablemente mas grande —la misma cadena
     * ocupaba 205 px contra 161—. La rejilla y los campos ya coincidian; lo que
     * sobresalia era todo lo de alrededor: menu, pestañas, botones, cabeceras
     * de panel y el paginador.
     *
     * Que `s` y `m` valgan lo mismo no es un descuido: en el heredado tampoco
     * se distinguen. Se conservan los dos nombres porque significan cosas
     * distintas y el dia que uno cambie no tiene por que arrastrar al otro.
     */
    --txt-xs: 11px;
    --txt-s: 12px;
    --txt-m: 12px;
    --txt-l: 13px;
    --txt-xl: 16px;
    --txt-xxl: 21px;

    --radio: 3px;
    --radio-2: 6px;
    /*
     * El de los campos. **Pedido por el propietario el 21 de septiembre de
     * 2026**: «redondea un poco las esquinas de TODOS los campos en todo el
     * proyecto». Va como token y no como numero suelto para que sea eso, uno
     * en todo el proyecto: las cajas de texto, los desplegables, las areas de
     * texto y las celdas que se editan en la rejilla.
     */
    --radio-campo: 5px;

    /* La cabecera de una tabla y la franja alterna, que no son la tarjeta. */
    --superficie-3: #edf1f4;
    --realce: rgba(14, 92, 107, .06);

    /*
     * La linea bajo un campo de la ficha en modo consulta.
     *
     * No vale `--borde`: sobre `--superficie` da 1,3:1 en el tema oscuro y el
     * campo **parece no estar**. Se ve en la pantalla de Entidades, donde la
     * ficha de SUNAT salia como una lista de rotulos sueltos.
     */
    --linea-ficha: #a9b7c4;
}

[data-tema="oscuro"] {
    /*
     * El fondo baja y la superficie se queda: asi la tarjeta **se separa del
     * fondo**, que antes eran dos grises casi iguales y todo parecia una sola
     * plancha. Se baja el fondo en vez de subir la superficie a proposito,
     * porque el texto vive sobre la superficie y subirla le quitaria contraste.
     */
    --fondo: #0f141a;
    --superficie: #1d252d;
    --superficie-2: #273039;
    --celda-apagada: #3a434d;
    --texto: #e6ecf1;
    --texto-2: #aab6c0;
    --borde: #36424e;
    --acento: #5cbdce;
    --acento-texto: #10181e;
    --sombra: 0 1px 2px rgba(0, 0, 0, .35);
    --grave-fondo: #33201d;
    --grave-borde: #a8564c;
    --grave-texto: #f2b7ae;
    --aviso-fondo: #2f2a1c;
    --aviso-borde: #9c7c34;
    --aviso-texto: #e8cf92;
    --bien-fondo: #1c2e24;
    --bien-texto: #a9d8b8;

    --superficie-3: #222b34;
    --realce: rgba(92, 189, 206, .07);
    --linea-ficha: #52626f;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--fondo);
    color: var(--texto);
    /* 12 px, que es lo que mide el texto del heredado. Ver los tokens. */
    font: var(--txt-s)/1.5 "Segoe UI", system-ui, -apple-system, sans-serif;
}

/*
 * Los enlaces toman el acento del tema.
 *
 * Sin esta regla se quedaban con el #0000EE del navegador, que sobre el tema
 * oscuro da 1,65:1 y es ilegible. Solo se salvaban los que ya tenian color
 * propio —el menu, las pestañas, los avisos—, y esos son los menos: los de las
 * fichas, las tarjetas y las rejillas no lo tenian.
 */
a { color: var(--acento); }
a:hover { text-decoration: underline; }

/* --- Reticula de trabajo: lo que hoy hace jquery.layout, en CSS Grid --- */
.espacio-trabajo {
    display: grid;
    grid-template-columns: var(--ancho-oeste, 220px) 4px 1fr;
    grid-template-rows: auto 1fr auto;
    grid-template-areas:
        "norte  norte   norte"
        "oeste  tirador centro"
        "sur    sur     sur";
    height: 100vh;
}

.panel-norte  { grid-area: norte;  background: var(--superficie); border-bottom: 1px solid var(--borde); }
.panel-oeste  { grid-area: oeste;  background: var(--superficie); border-right: 1px solid var(--borde); overflow: auto; }
/*
 * El aire alrededor del modulo, **el mismo que hay entre los paneles**.
 *
 * Eran 16 px por los cuatro lados contra los 6 que separan un panel de otro, de
 * modo que el borde de la pantalla respiraba mas que el interior y el conjunto
 * se veia descentrado. Peticion del propietario: que midan igual.
 */
.panel-centro { grid-area: centro; overflow: auto; padding: var(--sep-widget); }
.panel-sur    { grid-area: sur;    background: var(--superficie); border-top: 1px solid var(--borde); padding: 4px 12px; color: var(--texto-2); font-size: 12px;
                /* Como el pie del heredado: saludo, fecha en el medio y «Powered by». */
                display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--e4); align-items: center; white-space: nowrap; }
.panel-sur > :first-child { overflow: hidden; text-overflow: ellipsis; }
.panel-sur > :last-child  { justify-self: end; }

/* El tirador que permite arrastrar la columna, como el de jquery.layout */
.tirador { grid-area: tirador; cursor: col-resize; background: var(--borde); position: relative; }
.tirador:hover, .tirador:focus-visible { background: var(--acento); outline: none; }
/*
 * **Y su botoncito, que esconde la columna entera**, como el de jquery.layout
 * en el heredado: otro clic la devuelve, y arrastrar sigue funcionando
 * (propietario, 11 de noviembre de 2026). Más ancho que el tirador para que
 * se pueda acertar, y por encima de los dos paneles.
 */
.plegar-oeste {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 2;
    width: 12px; height: 44px; padding: 0; margin: 0;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--borde); border-radius: 3px;
    background: var(--superficie); color: var(--texto-2);
    font-size: 11px; line-height: 1; cursor: pointer;
}
.plegar-oeste:hover, .plegar-oeste:focus-visible { background: var(--acento); color: var(--acento-texto); border-color: var(--acento); outline: none; }
.espacio-trabajo.oeste-oculto { grid-template-columns: 0 4px 1fr; }
.espacio-trabajo.oeste-oculto .panel-oeste { display: none; }

.barra { display: flex; align-items: center; gap: 14px; padding: 8px 14px; }
.barra .marca { font-weight: 700; letter-spacing: -.01em; display: inline-flex; align-items: center; gap: 7px; }
.barra .marca img { display: block; }

/*
 * El logotipo de la pantalla de acceso.
 *
 * Es el mismo archivo que usa el sistema heredado para el correo: lleva texto
 * oscuro sobre fondo transparente, de modo que sobre el tema oscuro se perderia.
 * Se le pone debajo una placa clara, que ademas es como se ve en el heredado.
 */
.acceso .logo {
    display: block;
    margin: 0 auto 10px;
    max-width: 200px;
    height: auto;
    background: #fff;
    border-radius: 4px;
    padding: 8px 12px;
}
.barra .separador { flex: 1; }
.barra form { display: inline; }
.barra button.enlace { background: none; color: var(--texto-2); font-weight: 400; padding: 0; margin: 0; text-decoration: underline; cursor: pointer; }
/* El año de la sesión, que se cambia desde la barra como en el heredado. */
.barra .form-anio { display: inline-flex; align-items: center; gap: var(--e1); margin: 0; }
.barra .form-anio select { width: auto; padding: 2px var(--e1); font-size: var(--txt-m); }
/* Sin el margen de la regla general de `label` (12 px arriba y 4 abajo), que la
   bajaba respecto a su desplegable. */
.barra .form-anio label { margin: 0; }
/* El tema, con un solo icono: la luna en el claro, el sol en el oscuro. */
.barra .boton-tema { background: none; border: 1px solid var(--linea-ficha); color: var(--texto-2); padding: var(--e1); margin: 0; line-height: 0; border-radius: var(--radio-campo); cursor: pointer; }
.barra .boton-tema:hover { color: var(--texto); background: var(--superficie-2); }
.barra .boton-tema .icono-sol { display: none; }
.barra .boton-tema[data-tema="oscuro"] .icono-sol { display: inline; }
.barra .boton-tema[data-tema="oscuro"] .icono-luna { display: none; }

/* --- Pestañas --- */
.pestanas { display: flex; gap: 2px; padding: 0 14px; flex-wrap: wrap; }

.pestana {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 0 4px 0 12px;
    border: 1px solid var(--borde);
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    background: var(--superficie-2);
    max-width: 230px;
}

.pestana > a {
    padding: 6px 4px 6px 0;
    color: var(--texto-2);
    text-decoration: none;
    font-size: var(--txt-s);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pestana.activa { background: var(--superficie); }
.pestana.activa > a { color: var(--texto); font-weight: 600; }

/* La cruz de cerrar, como en el heredado. La de Inicio no existe. */
.pestana > .cerrar {
    all: unset;
    cursor: pointer;
    width: 16px; height: 16px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 3px;
    color: var(--texto-2);
    font-size: var(--txt-l); line-height: 1;
    flex: none;
}

.pestana > .cerrar:hover { background: var(--borde); color: var(--texto); }
.pestana > .cerrar:focus-visible { outline: 2px solid var(--acento); outline-offset: 1px; }

/* --- Piezas sueltas --- */
.tarjeta {
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio-2);
    box-shadow: var(--sombra);
    padding: var(--e5) 18px;
}

/* Un titulo de tarjeta escrito con `<strong>` suelto, que es como estan casi
   todas, se lee ahora como titulo y no como negrita cualquiera. */
.tarjeta > strong:first-child { font-size: var(--txt-l); letter-spacing: -.01em; }

/*
 * Un parrafo dentro de una tarjeta no lleva el margen de 1em del navegador.
 *
 * Ese margen es de un documento de texto, no de una interfaz, y es la razon de
 * que hubiera `margin:10px 0 0`, `margin:4px 0 0` y `margin:0` escritos a mano
 * por todas partes: cada vista lo deshacia a su manera.
 */
.tarjeta p { margin: 0 0 var(--e3); }
.tarjeta p:last-child { margin-bottom: 0; }

/*
 * Tarjetas plegables: las «semiventanas» del sistema heredado. Se pulsa la
 * cabecera y queda solo ella, que es lo que devuelve pantalla cuando hay una
 * rejilla debajo. Lo que se deje en la cabecera se sigue viendo plegado.
 */
.tarjeta.plegable { padding: 0; }

.tarjeta.plegable > .cabecera {
    border-radius: var(--radio-2) var(--radio-2) 0 0;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 14px;
    cursor: pointer;
    user-select: none;
    background: var(--superficie-2);
    border-bottom: 1px solid var(--borde);
}

.tarjeta.plegable > .cabecera:hover { color: var(--acento); }
.tarjeta.plegable > .cabecera:focus-visible { outline: 2px solid var(--acento); outline-offset: -2px; }

/* El tirador va a la derecha del todo, como en el heredado. */
.tarjeta.plegable > .cabecera .plegar {
    margin-left: auto;
    width: 18px; height: 18px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--borde);
    border-radius: 3px;
    background: var(--superficie);
    font: 700 13px/1 monospace;
    color: var(--texto-2);
    flex: none;
}

.tarjeta.plegable > .cuerpo { padding: 14px; }
.tarjeta.plegable.plegada > .cuerpo { display: none; }
.tarjeta.plegable.plegada > .cabecera { border-bottom: 0; border-radius: var(--radio-2); }

/*
 * Un formulario de filtros plegable coloca sus campos como antes.
 *
 * El `:where()` deja la variante en especificidad cero. Sin el, esta regla y la
 * de plegar valen exactamente lo mismo —(0,4,0) las dos—, gana la ultima
 * escrita y la tarjeta de filtros no se pliega: justo la que mas falta hace
 * plegar, porque es la que tapa la rejilla. Cualquier variante nueva del
 * cuerpo debe escribirse igual.
 */
.tarjeta.plegable > .cuerpo:where(.filtros) {
    display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end;
}
/*
 * Los cuadros de la pantalla de inicio, en una reticula que se acomoda al
 * ancho: dos columnas en 1366 puntos, una sola en una pantalla estrecha. El
 * heredado los ponia en dos columnas fijas.
 */
.cuadros {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
    gap: 12px;
    margin-top: 14px;
    align-items: start;
}

/*
 * Se arrastra por la cabecera. `touch-action: none` es lo que impide que con
 * el dedo el gesto se lo lleve el desplazamiento de la pagina en vez de mover
 * la tarjeta.
 */
.cuadro > .cabecera { cursor: move; touch-action: none; }
.cuadro.llevando { opacity: .45; }

/*
 * Las cifras de la pantalla de inicio. El numero es el dato y el rotulo lo
 * explica: antes pesaban casi lo mismo y habia que leer los dos para saber
 * cual era cual.
 */
.cifras {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 1px; background: var(--borde);
    border: 1px solid var(--borde); border-radius: var(--radio-2);
    overflow: hidden;
    margin-top: var(--e4);
}
.cifra { background: var(--superficie); padding: var(--e4) var(--e5); }
.cifra b {
    display: block;
    font-size: var(--txt-xxl); font-weight: 700; line-height: 1.15;
    letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.cifra span { display: block; margin-top: var(--e1); color: var(--texto-2); font-size: var(--txt-s); }

/* Lo que corre prisa en la pantalla de inicio: plazo agotado o a punto. */
.aviso-grave { background: var(--grave-fondo); border-color: var(--grave-borde); color: var(--grave-texto); }
.aviso-aviso { background: var(--aviso-fondo); border-color: var(--aviso-borde); color: var(--aviso-texto); }
.aviso-grave a, .aviso-aviso a { color: inherit; }
/*
 * La lista del autocompletado. Va pegada al `body` y no dentro del campo,
 * porque dentro de una tarjeta con `overflow` se cortaria.
 */
.autocompletar {
    position: absolute;
    z-index: 60;
    margin: 2px 0 0;
    padding: 0;
    list-style: none;
    max-height: 260px;
    overflow-y: auto;
    background: var(--superficie);
    border: 1px solid var(--borde);
    box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
    border-radius: 3px;
    font-size: var(--txt-s);
}

.autocompletar li {
    padding: 5px 10px;
    cursor: pointer;
    white-space: nowrap;
}

.autocompletar li:hover,
.autocompletar li.marcada {
    background: var(--acento);
    color: var(--acento-texto);
}

/*
 * El desglose de totales es una lista de comprobacion, no una tabla de datos:
 * se lee de arriba abajo buscando una cifra. Con la linea de cada fila y el
 * relleno de una celda normal ocupaba tres pantallas de alto para diez
 * numeros. Aqui va apretado y sin rayas, que es como se lee.
 */
#totales {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 2px var(--e4);
    align-items: baseline;
    margin: var(--e3) 0 0;
}
#totales dt { color: var(--texto-2); font-size: var(--txt-xs); letter-spacing: .02em; }
#totales dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }

/* El valor de venta separa las operaciones de los impuestos. */
#totales .destacada { border-top: 1px solid var(--borde); padding-top: var(--e2); margin-top: var(--e1); color: var(--texto); }
#totales .total { border-top: 1px solid var(--borde); padding-top: var(--e2); margin-top: var(--e1); font-weight: 700; color: var(--texto); }
#totales dd.total { font-size: var(--txt-l); }

/*
 * El panel de la derecha del formulario de documento: el
 * `#tools_data_commercial` del heredado, que es la celda `width="15%"` de su
 * tabla. Ancho fijo y no proporcional, porque **ahi eso lo decide el
 * contenido**: una celda de tabla mide lo que mide su linea mas larga, y la
 * mas larga aqui es «VTA. EXONERADA». Medido en su pantalla: 157 px de
 * textarea.
 */
.panel-totales { width: 208px; align-self: start; }
.panel-totales textarea { width: 100%; min-height: 30px; padding: 2px 5px; resize: vertical; }
.panel-totales .nota, .panel-totales .nota-min { margin: var(--e2) 0 0; }
.panel-totales .nota-min:empty, .panel-totales .nota:empty { margin: 0; }
.panel-totales .aviso-rojo { margin: var(--e2) 0 0; font-size: var(--txt-xs); font-weight: 600; color: var(--malo, #c0392b); }
.panel-totales .aviso-rojo:empty { margin: 0; }
.acciones-totales {
    display: flex; gap: var(--e2); margin-top: var(--e4);
    padding-top: var(--e3); border-top: 1px solid var(--borde);
}
.acciones-totales > button { flex: 1; margin: 0; }

/*
 * Las solapas de dentro de una pantalla: «Datos» y «Recibos» del formulario de
 * documento. Son las pestañas que alli pone jQuery UI, sin la libreria.
 *
 * No se parecen a las del panel a proposito: aquellas abren un modulo y estas
 * reparten una pantalla, de modo que confundirlas seria peor que distinguirlas.
 */
.tira-solapas {
    display: flex; align-items: center; gap: var(--e1);
    margin: calc(var(--e4) * -1) calc(var(--e4) * -1) var(--e4);
    padding: 0 var(--e4);
    border-bottom: 1px solid var(--borde);
}
.tira-solapas > [data-solapa] {
    margin: 0; padding: var(--e3) var(--e4);
    border: 0; border-bottom: 2px solid transparent; border-radius: 0;
    background: none; color: var(--texto-2);
    font-size: var(--txt-m); font-weight: 600; cursor: pointer;
}
.tira-solapas > [data-solapa]:hover { color: var(--texto); }
.tira-solapas > [data-solapa].activa { color: var(--acento); border-bottom-color: var(--acento); }
.tira-solapas > .apunte { color: var(--texto-2); font-size: var(--txt-xs); white-space: nowrap; }

/*
 * La cabecera del documento, con la reticula de su `#cabecera`.
 *
 * **Su tabla son diez columnas, y todas sus filas las respetan.** Contado
 * celda por celda sobre `plantilla_documento.php`: las impares son etiquetas
 * y las pares controles, y las dos primeras filas juntan celdas con
 * `colspan`. Eso es lo que hace que «Crédito» y «Saldo», o «Moneda» y
 * «Vendedor», caigan **uno debajo del otro**.
 *
 * | col | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
 * |---|---|---|---|---|---|---|---|---|---|---|
 * | 1 | Movimiento | control ·3 | | | Documento | control ·5 | | | | |
 * | 2 | Cliente | control ·3 | | | Serie y número | control ·3 | | | Origen | control |
 * | 3 | R.U.C./D.N.I. | · | Crédito | · | Moneda | · | T.C. | · | Destino | · |
 * | 4 | Fecha | · | Saldo | · | Vendedor | · | Motivo | · | | |
 *
 * Aqui estuvo primero como doce columnas de `1fr` —que aplastaba el
 * desplegable de Moneda a 30 px— y despues como cuatro filas flex sueltas,
 * que no aplastan nada pero **no alinean**: cada fila empezaba donde le
 * tocaba. El propietario lo devolvio las dos veces. Una tabla hace las dos
 * cosas a la vez, y `subgrid` es lo que la reproduce: la fila hereda las
 * columnas de la cabecera en vez de inventarse las suyas.
 *
 * Las columnas van en `auto`, que es lo que hace una tabla: cada una mide lo
 * que mide su contenido mas ancho. La 2 se lleva el hueco que sobre, porque
 * es la del cliente y la del movimiento.
 */
/*
 * **Las dos mitades se reparten el ancho, no una sola columna.** Lo señalo el
 * propietario el 22 de septiembre de 2026 con su pantalla de 18 pulgadas: «las
 * 2 columnas principales no estan divididas al 50 % aproximadamente, es por eso
 * que cuando esta a 24" se ve bien pero en 18" se aplasta».
 *
 * Tenia razon, y se ve en los numeros. Iba `auto minmax(0, 1fr) repeat(8,
 * auto)`, de modo que **la columna 2 era la unica elastica**: a 1920 se llevaba
 * 415 px para un campo que no pasa de 294 —la mitad izquierda quedaba en el
 * 44 % y la derecha en el 33 %— y, lo que de verdad duele, **al encoger la
 * tarjeta todo el recorte caia sobre ella**. Por eso a 18 pulgadas el R.U.C.
 * salia cortado mientras sobraban 260 px a su derecha.
 *
 * Con las cuatro columnas de control elasticas, el sobrante —y el recorte— se
 * reparten entre las dos mitades. Los rotulos siguen midiendo su texto, que es
 * lo que hace una tabla.
 */
.reticula-cabecera {
    display: grid;
    grid-template-columns:
        auto minmax(0, 1fr)   /* mitad izquierda: rotulo y control, dos veces */
        auto minmax(0, 1fr)
        auto minmax(0, 1fr)   /* mitad derecha */
        auto minmax(0, 1fr)
        auto auto;            /* Origen y Destino, que caben su contenido */
    gap: var(--e1) var(--e4);
    align-items: center;
}

.fila-cabecera {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    align-items: center;
}

/*
 * El `.par` no ocupa celda: **la ocupan su etiqueta y su control**, cada uno
 * en su columna, que es lo que hace un `<td>`. Con `display: contents` el
 * envoltorio desaparece de la reticula y sus hijos entran en ella.
 *
 * `#caja-destino` se sigue escondiendo con `style.display = 'none'`, que gana
 * a esto; al volver a `''` vuelve a valer `contents`.
 */
.fila-cabecera > .par { display: contents; }
/* «Transferencia entre almacenes»: el formulario de venta sin cliente, crédito,
   saldo, vendedor ni recibos, como el modo `transf_almacen` del heredado. */
.formulario-documento.modo-transferencia .transf-almacen { display: none; }
.fila-cabecera > .par > label {
    margin: 0; white-space: nowrap;
    color: var(--texto-2); font-size: var(--txt-m);
}
/* Lo que la celda junta con `colspan`. */
.fila-cabecera > .par > :last-child { grid-column: span var(--cols, 1); }

/*
 * El ancho lo dice el campo, no la reticula. Sin esto todos valdrian lo
 * mismo, que es justo lo que hace que un RUC de once digitos flote en 400 px
 * y que una moneda de tres letras no quepa.
 *
 * **Y otra vez la cadena de `:not()`.** La regla base de la tarjeta lleva
 * `width: 100%` con (0,4,1), de modo que la primera version de esto —sin
 * `.tarjeta` y con `:is()`, que suma solo (0,2,1)— **no aplicaba ni un
 * ancho**: todos los controles seguian al 100 % y la descripcion del tipo de
 * documento se iba 107 px fuera de la ventana. Medido, no supuesto. Es la
 * quinta vez que esa cadena muerde en este archivo, y la leccion ya no es
 * «repite los `:not()`» sino **mide el ancho despues de escribir la regla**.
 */
/*
 * **Es un maximo, no un ancho.** Con `width` fijo, la columna no puede
 * encoger —su minimo es ese ancho— y en una tarjeta estrecha los campos se
 * montan unos sobre otros: medido en la pantalla de 18 pulgadas del
 * propietario, el R.U.C. se metia debajo de «Credito» y `Origen` se salia
 * **192 px** de la tarjeta. Con `max-width` la columna cede y el campo se
 * queda con lo que haya.
 */
.tarjeta .fila-cabecera .par > input:not([type=checkbox]):not([type=radio]):not([type=file]),
.tarjeta .fila-cabecera .par > select,
.tarjeta .fila-cabecera .par > textarea { width: 100%; max-width: var(--ancho, 120px); }

.tarjeta .fila-cabecera .par.crece > input:not([type=checkbox]):not([type=radio]):not([type=file]),
.tarjeta .fila-cabecera .par.crece > select { max-width: none; min-width: 0; }

/* Dos controles en la misma celda: el codigo y su descripcion. */
.fila-cabecera .par-dos { display: flex; align-items: center; gap: var(--e2); min-width: 0; }
.tarjeta .fila-cabecera .par-dos > input:not([type=checkbox]):not([type=radio]):not([type=file]),
.tarjeta .fila-cabecera .par-dos > select { width: var(--a, 120px); flex: 0 1 auto; min-width: 0; }
/*
 * **Y aqui hay que repetir la cadena de `:not()`, por septima vez.** Escrita a
 * secas, esta regla suma (0,5,0) y la base de arriba (0,6,1) —cada
 * `:not([type=…])` cuenta como una clase—, de modo que **ganaba la base**: el
 * `select` de Movimiento crecia, porque para el la base solo vale (0,3,1), y
 * la descripcion del documento se quedaba clavada en su `--a` sin que nada
 * fallara. Medido el 22 de septiembre de 2026: 52 px dentro de una celda de
 * 542.
 */
/*
 * Un desplegable que cerrado solo enseña el código —ver `select-codigo.js`—
 * lleva **ancho fijo**, no un tope. Al abrirlo se le ponen los textos largos, y
 * con un tope su columna crecería mientras la lista está abierta y empujaría a
 * las demas: la cabecera se moveria cada vez que se toca Origen.
 */
.tarjeta .fila-cabecera .par > select[data-solo-codigo] { width: var(--ancho, 70px); }

.tarjeta .fila-cabecera .par-dos.crece > :last-child:not([type=checkbox]):not([type=radio]):not([type=file]) {
    width: auto;
    flex: 1 1 0;
    min-width: 0;
    max-width: none;
}

/*
 * Y el relleno de los controles, que es de donde salian los 30 px.
 *
 * **Hay que repetir la cadena de `:not()` y añadir `.tarjeta` delante**, y lo
 * segundo se descubrio midiendo: con la cadena sola las dos reglas empatan a
 * (0,4,1) y gana **la que va despues en el archivo**, que es la base — esta
 * vive aqui arriba, con lo demas de la cabecera, de modo que perdia y el
 * relleno seguia en 6 px. Con `.tarjeta` suma (0,5,1) y el orden deja de
 * importar. Es la cuarta vez que esa cadena muerde en este archivo.
 */
.tarjeta .reticula-cabecera input:not([type=checkbox]):not([type=radio]):not([type=file]),
.tarjeta .reticula-cabecera select,
.tarjeta .reticula-cabecera textarea { padding: 2px 6px; }

/*
 * **Y el formulario entero, no solo su cabecera.** Sus tarjetas de SUNAT
 * —cargos, detraccion, guia, exportacion— seguian con el relleno de una ficha
 * normal, `6px 8px`, de modo que sus campos salian de **30 px** al lado de los
 * **22** de la cabecera, en la misma pantalla. Lo señalo el propietario el 21
 * de septiembre de 2026 con la tarjeta de cargos abierta: «esos campos son
 * enormes».
 *
 * Es la cadena de `:not()` por sexta vez: una regla para estos campos tiene
 * que repetirla entera o pierde contra la base de `.tarjeta`, que suma (0,4,1).
 */
.formulario-documento .tarjeta input:not([type=checkbox]):not([type=radio]):not([type=file]),
.formulario-documento .tarjeta select,
.formulario-documento .tarjeta textarea { padding: 2px 6px; }

/*
 * Un importe y un porcentaje no necesitan 280 px. `.campos` reparte columnas
 * de 200 px que el control llena al 100 %, y en una tarjeta de tres campos eso
 * da cajas del ancho de media pantalla para escribir «0.00». Los once campos
 * numericos de este formulario son importes, porcentajes, bultos y peso: el
 * mas largo cabe de sobra. La etiqueta se queda con su columna, que es lo que
 * hace la cabecera.
 */
.formulario-documento .campos input.num:not([type=checkbox]):not([type=radio]):not([type=file]) {
    max-width: 110px;
}

/*
 * La solapa «Recibos», que no es la cabecera y no se parte en diez columnas.
 *
 * Alli son **dos recuadros estrechos** dentro de una celda `width="50%"`:
 * `datos_recibo1` con el tipo y la condicion de pago, el vencimiento y la
 * cantidad, y `datos_recibo2` debajo con «Paga con» y «Vuelto». Con la
 * reticula de la cabecera, sus cinco primeros campos salian desparramados de
 * lado a lado de una pantalla de 1920, que es justo lo contrario de lo suyo.
 */
/*
 * El contenedor que miran las consultas de arriba: la solapa, que es lo que
 * de verdad encierra a la cabecera. `inline-size` limita la contencion al
 * ancho, que es lo unico que se pregunta.
 */
[data-panel-solapa] { container-type: inline-size; }

.recuadros-recibo { display: flex; flex-direction: column; gap: var(--e4); }
.reticula-recibo {
    display: grid;
    grid-template-columns: auto minmax(0, max-content);
    gap: var(--e1) var(--e4);
    align-items: center;
    width: fit-content;
    min-width: 320px;
}
.reticula-recibo > .par { display: contents; }
.reticula-recibo > .par > label {
    margin: 0; white-space: nowrap;
    color: var(--texto-2); font-size: var(--txt-m);
}
.tarjeta .reticula-recibo .par > input:not([type=checkbox]):not([type=radio]):not([type=file]),
.tarjeta .reticula-recibo .par > select { width: var(--ancho, 150px); }
.tarjeta .reticula-recibo input:not([type=checkbox]):not([type=radio]):not([type=file]),
.tarjeta .reticula-recibo select { padding: 2px 6px; }

/*
 * **Lo que decide cuantas columnas caben es la tarjeta, no la ventana.**
 *
 * Y esa es la correccion de fondo: con `@media` se miraba el ancho del
 * navegador, pero entre la ventana y esta cabecera estan el menu de la
 * izquierda —195 px— y el panel de totales de la derecha —208—, de modo que
 * en la pantalla de 18 pulgadas del propietario la ventana media 1303 y la
 * tarjeta **853**. La consulta de 1180 px no llegaba a dispararse nunca y los
 * campos se montaban unos sobre otros. Por eso va con `@container`, que
 * pregunta por lo que de verdad hay.
 *
 * Tres escalones, y el de en medio es el que faltaba:
 *
 * - **holgado**: las diez columnas de su tabla;
 * - **a partir de 866 px hacia abajo**: cuatro columnas, o sea dos parejas
 *   por renglon. Sigue alineado en columna, que es lo que se pidio, y cabe;
 * - **por debajo de 620**: una pareja por renglon.
 *
 * **Y el 944 esta medido, no elegido**, que es lo que fallaba antes. Iba en
 * 1040, un numero redondo, y la ventana del propietario da un panel de
 * **1042**: vivia a dos pixeles del salto, de modo que la misma pantalla salia
 * unas veces en diez columnas y otras en cuatro —«hay suficiente espacio
 * sobre todo en la segunda columna, pero T.C. colapsa y se baja», 22 de
 * septiembre de 2026, con las dos capturas delante—.
 *
 * Medido sin el umbral, bajando de cinco en cinco: a **947 px** de panel cabia
 * todo y a **942** el desplegable del motivo, «01 · Venta», perdia un pixel.
 *
 * **Y despues bajo a 866**, el 23 de septiembre de 2026, cuando Motivo y
 * Origen pasaron a enseñar solo el codigo con la lista cerrada, como los
 * comboboxes del heredado —ver `select-codigo.js`—. Con eso el que manda es
 * **Movimiento**, que necesita 253 px para «S0001 · VENTA FACTURA SERIE
 * F001»: a **867** de panel cabe y a **862** pierde tres pixeles. Medido igual,
 * de cinco en cinco.
 *
 * **La fila sigue siendo una fila en los tres.** Se intento dejandola en
 * `display: contents`, para que las parejas se colocaran solas de dos en dos,
 * y **eso desbarata el orden**: `Origen` acababa junto al R.U.C. y el tipo de
 * cambio junto a la fecha. Siendo `subgrid`, lo que no cabe **dobla dentro de
 * su propia fila** y cada grupo del heredado se queda junto, alineado con las
 * columnas de arriba. Lo unico que se anula son los `colspan`, que son del
 * reparto de diez.
 */
@container (max-width: 866px) {
    .reticula-cabecera { grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr); }
    .fila-cabecera > .par > :last-child { grid-column: auto; }
    /* Un poco de aire entre un grupo y el siguiente, que ahora ocupan varios
       renglones y sin el no se distinguen. */
    .reticula-cabecera { gap: var(--e3) var(--e4); }
}

@container (max-width: 620px) {
    .reticula-cabecera { grid-template-columns: auto minmax(0, 1fr); }
}

@media (max-width: 1180px) {
    .panel-totales { width: auto; }
}

.menu { list-style: none; margin: 0; padding: 0; }
.menu li a { display: block; padding: 4px 16px 4px 26px; color: var(--texto-2); text-decoration: none; font-size: var(--txt-s); }
.menu li a:hover { background: var(--superficie-2); color: var(--texto); }

/* El resumen va suelto arriba, sin grupo. */
.menu-suelto { padding: 8px 0; border-bottom: 1px solid var(--borde); }
.menu-suelto li a { padding-left: 16px; font-weight: 600; color: var(--texto); }

/*
 * Grupos plegables, como el acordeon del sistema heredado. Se abren con
 * <details>, de modo que funcionan sin JavaScript; lo unico que se guarda es
 * cual quedo abierto.
 */
.grupo { border-bottom: 1px solid var(--borde); }

.grupo > summary {
    padding: 9px 16px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--texto);
    cursor: pointer;
    user-select: none;
    list-style: none;              /* fuera el triangulo de serie */
    display: flex;
    align-items: center;
    gap: 8px;
}

.grupo > summary::-webkit-details-marker { display: none; }

/* Un triangulo propio, que gira al abrir. */
.grupo > summary::before {
    content: "";
    width: 0; height: 0;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transition: transform .12s ease;
    flex: none;
    opacity: .55;
}

.grupo[open] > summary::before { transform: rotate(90deg); }
.grupo > summary:hover { background: var(--superficie-2); }
.grupo[open] > summary { color: var(--acento); }
.grupo > ul { padding-bottom: 8px; }

@media (prefers-reduced-motion: reduce) {
    .grupo > summary::before { transition: none; }
}

.acceso { display: grid; place-items: center; min-height: 100vh; }
.acceso form { background: var(--superficie); border: 1px solid var(--borde); box-shadow: var(--sombra); padding: 26px 28px; width: min(360px, 92vw); }
.acceso h1 { margin: 0 0 4px; font-size: 1.3rem; }
.acceso p.sub { margin: 0 0 8px; color: var(--texto-2); font-size: var(--txt-s); }
/*
 * El aviso de estas pantallas: «te hemos enviado un enlace», «contraseña
 * cambiada». No es un error, de modo que no puede salir en rojo, y tampoco un
 * rotulo tenue: es la respuesta a lo que se acaba de hacer.
 */
.acceso .aviso {
    margin: 10px 0 0;
    padding: 9px 11px;
    background: var(--realce);
    border-left: 3px solid var(--acento);
    color: var(--texto);
    font-size: var(--txt-s);
    line-height: 1.5;
}
/*
 * El enlace de debajo del botón («¿Olvidaste tu contraseña?», «Volver a
 * entrar»): con `margin: 0` le ganaba al `.sep-3` de la vista y quedaba
 * pegado al botón (propietario, 12 de noviembre de 2026).
 */
.acceso .nota { margin: var(--e5) 0 0; font-size: var(--txt-s); text-align: center; }

/*
 * El aviso de credenciales que faltan (`CredencialesSunat`): en el formulario
 * de venta va dentro de la retícula de la cabecera, y sin esto ocupaba una
 * celda y apretaba los campos de al lado. Ocupa la fila entera.
 */
#aviso-credenciales { grid-column: 1 / -1; margin-bottom: 8px; }
/*
 * «Ver como»: las empresas inactivas —suspendidas o vencidas— con un fondo
 * rojizo suave, sin quitarlas (propietario, 12 de noviembre de 2026). El
 * desplegable lo toma también cuando la elegida es una de ellas.
 */
#ver-como-empresa option.empresa-inactiva,
#ver-como-empresa.empresa-inactiva { background: var(--grave-fondo); color: var(--grave-texto); }
/* Y las activas con el certificado vigente, en verde suave. */
#ver-como-empresa option.empresa-certificada,
#ver-como-empresa.empresa-certificada { background: var(--bien-fondo); color: var(--bien-texto); }
#ver-como-empresa option:not(.empresa-inactiva):not(.empresa-certificada) { background: var(--superficie); color: var(--texto); }
/* La consulta pública (`consulta.blade.php`): cajas y desplegable del mismo ancho. */
#consulta select, #consulta input[type=text] { width: 100%; }
.acceso .nota a { color: var(--acento); }
label { display: block; margin: 12px 0 4px; font-size: var(--txt-s); color: var(--texto-2); }
/*
 * Cualquier campo de texto toma los colores del tema.
 *
 * Antes solo lo hacian el correo, la clave y los desplegables, de modo que una
 * caja de texto, un numero o una fecha salian con el blanco del navegador:
 * sobre el tema oscuro, una caja blanca en mitad de una tarjeta oscura. Tres
 * vistas lo venian poniendo a mano campo por campo.
 *
 * Aqui solo van los colores. El tamaño se deja como esta, que es lo que hace
 * que un filtro de cuatro caracteres siga midiendo cuatro caracteres.
 */
input:not([type=checkbox]):not([type=radio]):not([type=file]),
select,
textarea {
    border: 1px solid var(--borde);
    background: var(--fondo);
    color: var(--texto);
    border-radius: var(--radio-campo);
    font: inherit;
}

input:disabled, select:disabled, textarea:disabled {
    background: var(--superficie-2);
    color: var(--texto-2);
}

input[type=email], input[type=password] {
    width: 100%; padding: 8px 10px;
}

/*
 * En una ficha, el campo ocupa su columna: dejarlo a su ancho natural
 * desperdicia la pantalla, que es justo lo que hay que evitar.
 *
 * En una barra de filtros no, porque alli el ancho lo dice el `size`: un
 * filtro de tipo de documento son cuatro caracteres y estirarlo a la columna
 * lo hace ilegible.
 */
.tarjeta input:not([type=checkbox]):not([type=radio]):not([type=file]),
.tarjeta select,
.tarjeta textarea {
    width: 100%;
    padding: 6px 8px;
}

.tarjeta .filtros input,
.tarjeta .filtros select,
.tarjeta input[size],
.tarjeta select[size] {
    width: auto;
}

select { padding: 8px 10px; }

/*
 * El boton ya no trae margen.
 *
 * Lo traia —`margin-top: 18px`— y era la regla que mas se peleaba en todo el
 * proyecto: **21 vistas escribian `margin:0` encima** solo para deshacerla, y
 * una de cada dos barras de botones acababa descuadrada. El espacio lo pone
 * ahora quien coloca, con `.fila` o `.pila`, que es donde se decide.
 */
button {
    padding: 8px 15px; border: 1px solid transparent; border-radius: var(--radio);
    background: var(--acento); color: var(--acento-texto);
    font: inherit; font-weight: 600; line-height: 1.2; cursor: pointer;
}
button:hover { filter: brightness(1.08); }
button:active { filter: brightness(.94); }
button:disabled { opacity: .5; cursor: default; filter: none; }

/* El de acceder sigue separandose de la clave, que ahi no hay nada que lo ponga. */
.acceso form button { margin-top: var(--e5); width: 100%; }
.error { color: #9e3116; font-size: var(--txt-s); margin-top: 10px; }
[data-tema="oscuro"] .error { color: #e58a6e; }

/* Cada pestaña abierta conserva su contenido; solo se oculta la que no toca. */
.panel-pestana[hidden] { display: none; }

/*
 * El logotipo de la empresa detras de la rejilla de lineas, muy tenue.
 *
 * Es lo que el heredado hace con `run_watermark()`: un `div` al 5 % de opacidad
 * dentro del cuerpo de la rejilla. Aqui es un pseudo-elemento, que consigue lo
 * mismo sin meter un nodo entre las filas y sin heredar opacidad al contenido:
 * lo que se teclea sigue a plena tinta.
 *
 * La imagen llega en la variable `--logo` porque su URL la pone el servidor.
 * En el tema oscuro sube un poco: un logotipo oscuro al 5 % sobre fondo oscuro
 * no se ve, y el heredado tenia ese mismo problema con un solo valor.
 */
.tarjeta.con-logo { position: relative; }

.tarjeta.con-logo > * { position: relative; z-index: 1; }

.tarjeta.con-logo::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image: var(--logo);
    background-repeat: repeat;
    background-position: center;
    background-size: 240px auto;
    opacity: .05;
    pointer-events: none;   /* no roba ni un clic a la rejilla */
}

[data-tema="oscuro"] .tarjeta.con-logo::before { opacity: .09; }

@media (prefers-color-scheme: dark) {
    :root:not([data-tema="light"]) .tarjeta.con-logo::before { opacity: .09; }
}

/* =====================================================================
 * Capa de componentes
 *
 * Esto es lo que faltaba. Antes el aspecto vivia en **795 atributos
 * `style=` repartidos por 40 vistas**, de modo que cambiar el diseño
 * significaba editar 795 sitios y ninguna pantalla se parecia del todo a
 * otra: habia cuatro tamaños de letra secundaria, tres rellenos de celda y
 * dos maneras de alinear un numero.
 *
 * Las clases de aqui **salen de contar lo que ya se repetia**, no de un
 * gusto: `font-size:13px` aparecia 209 veces, `color:var(--texto-2)` 204,
 * `text-align:right` 86 y `font-variant-numeric:tabular-nums` 67. Cada una
 * de las de abajo es uno de esos grupos con nombre.
 * ===================================================================== */

/* --- Colocacion: lo que sustituye a los margin-top sueltos --- */

/*
 * `margin-top:12px` aparecia 101 veces, casi siempre para separar una
 * tarjeta de la anterior. Una pila lo dice una vez.
 */
.pila { display: flex; flex-direction: column; gap: var(--e4); }
.pila-ancha { display: flex; flex-direction: column; gap: var(--e6); }

/* Una fila de cosas que van juntas: botones, filtros, un dato y su unidad. */
.fila { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e3); }
.fila-fin { align-items: flex-end; }
.fila-sep { justify-content: space-between; }
.fila > .empuja { margin-left: auto; }

/*
 * La reticula de campos de una ficha. Se acomoda al ancho en lugar de fijar
 * columnas: en 1366 puntos salen tres o cuatro, y en una pantalla estrecha
 * una. El `gap` vertical es cero porque cada campo ya trae su margen abajo.
 */
.campos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--e4) var(--e5);
    align-items: start;
}
.campos-anchos { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.campos-estrechos { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/*
 * El ritmo vertical lo pone la reticula, no la etiqueta.
 *
 * Antes lo ponia el `margin: 12px 0 4px` de `label`, y por eso una ficha con
 * un campo sin etiqueta se descuadraba. Con el hueco en la reticula, la
 * primera etiqueta de cada celda ya no necesita el suyo.
 */
.campos > * > label:first-child, .campos > label { margin-top: 0; }

/*
 * Un campo es su etiqueta y su control, y nada mas. Sustituye al
 * `display:flex;flex-direction:column;gap:4px;font-size:13px` que estaba
 * escrito 39 veces, unas como `<div>` con la etiqueta dentro y otras como una
 * `<label>` que envuelve a su campo. Funciona de las dos maneras.
 */
.campo { display: flex; flex-direction: column; gap: var(--e1); margin: 0; font-size: var(--txt-m); }
.campo > label, label.campo { margin: 0; font-size: var(--txt-m); }
.campo > label { color: var(--texto-2); }
.campo > .nota { margin: 0; }

/*
 * Tres utilidades, y solo tres. No es una biblioteca de utilidades: son los
 * tres margenes que aparecian sueltos cientos de veces —`margin-top:12px`
 * salia 73 veces con el mismo sentido, separar una tarjeta de la anterior— y
 * que no justifican un componente.
 */
.sep-1 { margin-top: var(--e1); }
.sep-2 { margin-top: var(--e3); }
/*
 * `.sep-3` **ya no es el tercer escalon de la escalera**: es la separacion
 * entre widgets, que es lo que significan sus 99 usos —«tarjeta sep-3»,
 * «tarjeta plegable sep-3», «tablero sep-3»— en 41 vistas. Por eso vale menos
 * que `.sep-2`, y por eso sale del mismo token que el relleno del panel.
 */
.sep-3 { margin-top: var(--sep-widget); }
.sep-4 { margin-top: var(--e5); }
.sep-6 { margin-top: var(--e6); }
.sin-margen { margin: 0; }
.ancho-auto { width: auto; }
/*
 * No hay clase para esconder, y es a proposito.
 *
 * El barrido convirtio `style="display:none"` en una clase y **rompio el
 * formulario de venta**: las tarjetas de traslado, detraccion, percepcion y
 * exportacion las enseña un guion poniendo `style.display = ''`, y contra una
 * clase con `display:none` eso no gana. El recorrido con navegador lo vio; la
 * suite no, porque el HTML era correcto.
 *
 * El estado inicial de algo que se enseña y se esconde es **comportamiento**,
 * no estilo, y vive donde el guion lo va a tocar.
 */
.sin-relleno { padding: 0; }
.sin-relleno-lados { padding-left: 0; padding-right: 0; }
.relleno-lados { padding-left: var(--e2); padding-right: var(--e2); }
.sin-corte { white-space: nowrap; }
.bloque { display: block; }

/* Un recuadro dentro de una tarjeta: el resultado de una consulta, una nota
   destacada, el resumen de lo que se va a hacer antes de confirmarlo. */
.recuadro { padding: var(--e4); background: var(--superficie-2); border-radius: var(--radio); }

/* El control estrecho de una celda de rejilla, que no puede llevar el relleno
   de un campo de ficha o la fila crece el doble. */
/*
 * El control apretado de las rejillas de linea.
 *
 * **Su relleno no se aplicaba nunca.** `.control-fino` suma (0,1,0) y la
 * regla base de una tarjeta, `.tarjeta input:not([type=checkbox])…`, suma
 * (0,4,1): dentro de una tarjeta —que es donde se usa, las dos rejillas de
 * linea— ganaba la base y los controles salian con **6 px de relleno y 32 de
 * alto**, contra los 22 de la rejilla del heredado. Medido el 21 de
 * septiembre de 2026, cuando el propietario dijo que el formulario estaba
 * enorme. Con la cadena repetida suma (0,4,1) y, al ir despues en el archivo,
 * gana.
 */
input.control-fino:not([type=checkbox]):not([type=radio]):not([type=file]),
select.control-fino,
textarea.control-fino { width: 100%; padding: 2px 5px; }

.cifras-fijas { font-variant-numeric: tabular-nums; }
.centrado { text-align: center; }
.ancho-total { width: 100%; }
.peso-fuerte { font-weight: 600; }
.peso-normal { font-weight: 400; }
.sep-abajo { margin-bottom: var(--e3); }
.grave { color: var(--grave-texto); font-weight: 600; }
.recuadro-borde { border: 1px solid var(--borde); border-radius: var(--radio-2); padding: var(--e4) 14px; }
.flotar-fin { float: right; }
.sangria-izq { margin-left: var(--e4); }
.centrado-propio { align-self: center; }

/* --- Texto --- */

/*
 * Lo secundario: la explicacion, la unidad, el «de 388 540». Un solo tamaño
 * y un solo color, donde antes habia 13px, 12px y 11px mezclados.
 *
 * Lleva ancho maximo de lectura: una linea que cruza 1300 puntos no se lee,
 * y estas vistas explican bastante.
 */
.nota { font-size: var(--txt-m); color: var(--texto-2); max-width: 78ch; }
.nota-min { font-size: var(--txt-s); color: var(--texto-2); max-width: 78ch; }
.nota-ancha { max-width: none; }

/* El color secundario sin tocar el tamaño, y el tamaño sin tocar el color:
   estaban escritos por separado 17 y 16 veces. */
.tenue { color: var(--texto-2); }
.txt-m { font-size: var(--txt-m); }
.txt-s { font-size: var(--txt-s); }

/* El rotulo de una columna o de un bloque: pequeño, en versales. */
.etiqueta {
    font-size: var(--txt-xs); font-weight: 700; text-transform: uppercase;
    letter-spacing: .06em; color: var(--texto-2);
}

/* El titulo de una tarjeta o de un bloque dentro de ella. */
.titulo { font-size: var(--txt-l); font-weight: 700; letter-spacing: -.01em; }
.titulo-menor { font-size: var(--txt-m); font-weight: 700; }

.seccion { margin: var(--e6) 0 var(--e4); }
.seccion > .nota { margin-top: var(--e1); }
/*
 * **Dentro de una pestaña, la ultima seccion no deja margen abajo.**
 *
 * Ese margen es para separar una seccion de la siguiente, y entre hermanas lo
 * sigue haciendo el margen superior de la de abajo, que es mayor. Al final de
 * la pestaña, en cambio, son 12 px de nada justo donde el propietario pide
 * altura: «te falta ocupar un poco mas el 100 % del vertical disponible». La
 * rejilla los toma sola, porque `ajustar()` mide lo que hay debajo.
 */
.panel-pestana > .seccion { margin-bottom: 0; }
/*
 * **Y la primera empieza arriba del todo**, que es lo que pidio el propietario:
 * «on top significa que siempre se alinee desde arriba».
 *
 * Ese margen superior de 24 px separa una seccion de la anterior, y la primera
 * no tiene ninguna encima: dentro de una pestaña son 24 px de nada entre las
 * solapas y la barra de acciones. Con los 12 de abajo son **36 px** que la
 * rejilla se lleva.
 */
/*
 * **No vale `:first-child`, y es lo que fallaba.** Un fragmento de modulo
 * puede empezar con sus `<script>` —el formulario de venta lleva dos— y
 * entonces la seccion deja de ser el primer hijo aunque siga siendo lo
 * primero que se ve. La regla no llegaba y la tarjeta arrancaba **24 px por
 * debajo** del panel; medido el 21 de septiembre de 2026 en «Nuevo
 * documento», con las otras tres pantallas en su sitio.
 *
 * Por eso el margen se quita siempre y **vuelve solo cuando delante hay algo
 * que pinta**. Un `<script>`, un `<style>`, un `<template>` o un `<link>` no
 * cuentan: separar de lo de arriba no significa nada si lo de arriba no
 * ocupa sitio.
 */
.panel-pestana > .seccion { margin-top: 0; }
.panel-pestana > :not(script, style, template, link) ~ .seccion { margin-top: var(--e6); }

/*
 * **Y el primer widget tampoco, por lo mismo.** Ese margen separa un widget del
 * anterior, y el primero no tiene ninguno encima: el hueco de arriba lo pone
 * ya el relleno del panel, que sale del mismo token. Sin esta regla, la
 * pantalla que empieza con su tarjeta de filtros —el kardex, la venta
 * detallada— salia con **el doble de hueco arriba** que la que empieza con un
 * titulo. Medido: 12 px contra 6.
 */
.panel-pestana > .sep-3 { margin-top: 0; }
.panel-pestana > :not(script, style, template, link) ~ .sep-3 { margin-top: var(--sep-widget); }

/*
 * **Y un nivel mas adentro, porque el margen se escapa.** `.seccion` es un
 * envoltorio sin relleno arriba, de modo que el margen de lo primero que
 * lleva dentro **colapsa hacia fuera** y baja la pestaña entera: no lo mueve
 * dentro de la seccion, mueve la seccion. Medido el 21 de septiembre de 2026
 * en Familias, que empieza con un `tablero sep-3`: 6 px de nada arriba, con
 * la seccion marcando `margin-top: 0` — de ahi que mirar solo su margen no
 * explicara nada.
 *
 * Para la segunda seccion de una pestaña esto no quita ningun hueco: el suyo
 * lo pone su propio margen de 24 px, que es mayor y con el que colapsaba.
 */
.panel-pestana > .seccion > .sep-3 { margin-top: 0; }
.panel-pestana > .seccion > :not(script, style, template, link) ~ .sep-3 { margin-top: var(--sep-widget); }


/*
 * Un numero se alinea a la derecha y con cifras de ancho fijo, siempre. Era
 * `text-align:right` 86 veces y `tabular-nums` 67: no coincidian, de modo que
 * habia columnas alineadas y sin cifras fijas, que bailan al actualizarse.
 */
.num { text-align: right; font-variant-numeric: tabular-nums; }

/* --- Tablas --- */

/*
 * Estaban escritas a mano una por una: `border-collapse` 19 veces, el
 * `border-bottom` de celda 55, y tres rellenos distintos.
 *
 * La envoltura es la que desplaza en horizontal. Tiene que ser ella y no la
 * tarjeta: el cuerpo de la pagina no debe desplazarse nunca en horizontal, y
 * una tabla ancha dentro de una tarjeta con `overflow` recorta ademas la
 * lista del autocompletado.
 */
.tabla-envoltura { overflow-x: auto; }

.tabla { border-collapse: collapse; width: 100%; font-size: var(--txt-m); }

.tabla th {
    text-align: left;
    padding: var(--e2) var(--e4);
    background: var(--superficie-3);
    border-bottom: 1px solid var(--borde);
    font-size: var(--txt-xs); font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em;
    color: var(--texto-2);
    white-space: nowrap;
}

.tabla td { padding: var(--e2) var(--e4); border-bottom: 1px solid var(--borde); }
.tabla tbody tr:last-child td { border-bottom: 0; }
.tabla tbody tr:hover td { background: var(--realce); }
.tabla-compacta th, .tabla-compacta td { padding: var(--e1) var(--e3); }
/*
 * Las notas de version de «Actualizaciones de librerias»: las escribe un
 * tercero y algunas son largas, de modo que se desplazan dentro de su tarjeta
 * en vez de alargar la pagina. Los titulos del Markdown bajan a texto normal.
 */
.notas-de-version { max-height: 28rem; overflow: auto; font-size: var(--txt-s); }
.notas-de-version :is(h1, h2, h3, h4) { font-size: var(--txt-m); margin: var(--e2) 0 var(--e1); }
.notas-de-version :is(ul, ol) { margin: var(--e1) 0; padding-left: var(--e4); }
.notas-de-version code { overflow-wrap: anywhere; }

/*
 * La rejilla de lineas de los tres formularios de documento —venta, compra y
 * nota—, con la densidad de la suya: `MODIFICACIONES.md` anota que la de
 * jqGrid va con **filas de 22 y cabeceras de 22**. Aqui salian de 45 y 33.
 */
.tabla.tabla-lineas th, .tabla.tabla-lineas td { padding: 2px 6px; }

/* La fila que ya no cuenta, con la misma señal que la rejilla heredada. */
.tabla tr.rowanulado td { background: var(--grave-fondo); color: var(--grave-texto); }

/*
 * Una linea con decimales en un articulo que no se vende fraccionado.
 *
 * **Clase propia y no `rowanulado`**, aunque se vean igual: las dos marcas se
 * ponen y se quitan desde funciones distintas —el precio minimo y la fraccion—
 * y compartir clase las haria pisarse, apagando una al comprobar la otra. Cual
 * de las dos es lo dice el `title` de la celda.
 */
.tabla tr.sin-fraccion td { background: var(--grave-fondo); color: var(--grave-texto); }
.tabla tr.rowitem td { background: var(--superficie-2); }

/* --- Botones --- */

.boton-sec { background: var(--superficie); color: var(--texto); border-color: var(--borde); }
.boton-sec:hover { background: var(--superficie-2); filter: none; }

.boton-peligro { background: var(--superficie); color: var(--grave-texto); border-color: var(--grave-borde); }
.boton-peligro:hover { background: var(--grave-fondo); filter: none; }
[data-tema="oscuro"] .boton-peligro { color: var(--aviso-texto); }

/* El que parece un enlace: cerrar un aviso, deshacer un filtro. */
.boton-plano {
    background: none; border-color: transparent; color: var(--acento);
    font-weight: 600; padding: var(--e1) var(--e2);
}
.boton-plano:hover { background: var(--superficie-2); filter: none; }

.boton-min { padding: var(--e1) var(--e3); font-size: var(--txt-s); }

/* --- Marcas --- */

/*
 * La insignia que dice que un campo viaja en el comprobante. El formulario de
 * venta mezcla campos que se declaran con campos que solo son de Linsoft, y un
 * error no cuesta lo mismo en unos que en otros.
 */
.insignia {
    display: inline-block;
    padding: 1px var(--e2);
    border: 1px solid var(--borde);
    border-radius: 999px;
    background: var(--superficie-2);
    font-size: var(--txt-xs); font-weight: 700; letter-spacing: .04em;
    color: var(--texto-2);
    vertical-align: middle;
}

.insignia-sunat { border-color: var(--acento); color: var(--acento); background: transparent; }

/* --- Foco, que antes lo ponia el navegador y sobre el tema oscuro no se veia --- */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--acento);
    outline-offset: 1px;
    border-radius: var(--radio);
}

/* --- Titulos, que no tenian escala --- */

h1, h2, h3 { margin: 0 0 var(--e2); line-height: 1.25; letter-spacing: -.015em; }
h1 { font-size: var(--txt-xxl); }
h2 { font-size: var(--txt-xl); }
h3 { font-size: var(--txt-l); }

/*
 * Los avisos de la pantalla de inicio comparten la forma de la tarjeta, y
 * ademas marcan su lado izquierdo: es lo que hace que un plazo agotado se
 * distinga de un mensaje de bienvenida sin tener que leerlos.
 */
.aviso-grave, .aviso-aviso { border-left-width: 4px; }

/* ==========================================================================
 * La ficha junto a la rejilla
 *
 * El modo de trabajar del heredado, que se habia perdido al portar: la rejilla
 * no ocupa el ancho entero —tiene cinco columnas y estirarla no enseña un dato
 * mas— y lo que sobra a la derecha lo llena la ficha, que esta siempre puesta.
 * Seleccionar una fila la rellena; «Editar» habilita los campos en el sitio.
 *
 * Vive aqui y no en cada vista porque lo comparten trece pantallas. Ver
 * SISTEMA_NUEVO.md, «La ficha junto a la rejilla».
 * ========================================================================== */

/*
 * El hueco entre contenedores va **un 30 % por debajo** del general, a peticion
 * del propietario: 12 px entre la barra y el primer panel pasan a 8, y los 8
 * de separacion entre paneles a 6. Los dos caen en pasos que ya existen en la
 * escala, de modo que no se inventa una medida nueva.
 *
 * Va aqui y no en `--e3` y `--e4`, que son la escala de toda la aplicacion:
 * lo que el propietario señalo es el aire de estas pantallas, no el de un
 * formulario o el de la pagina de acceso.
 */
.tablero {
    display: grid;
    gap: var(--e2);
    grid-template-columns: minmax(0, var(--col-rejilla, 52fr))
                           minmax(0, var(--col-centro, 26fr))
                           minmax(0, var(--col-fin, 22fr));
    grid-template-rows: auto 1fr;
}
/*
 * Lo que separa dos widgets **es el mismo hueco en todo el sistema**, y por
 * eso sale del mismo token: dentro de una zona iba con `--e3` —8 px— mientras
 * el resto de la pantalla usaba 6. Lo señalo el propietario el 21 de
 * septiembre de 2026 con la rejilla de lineas delante: «el espacio entre
 * widgets, que sea menor, como te pedi antes».
 */
.tablero > .zona { display: flex; flex-direction: column; min-width: 0; gap: var(--sep-widget); }
.zona-rejilla   { grid-area: 1 / 1 / 2 / 2; }
.zona-principal { grid-area: 2 / 1 / 3 / 2; }
.zona-centro    { grid-area: 1 / 2 / 3 / 3; }
.zona-fin       { grid-area: 1 / 3 / 3 / 4; }

/*
 * Las dos columnas de la derecha caben su contenido, y la rejilla se queda el
 * resto.
 *
 * **Es lo que hace el heredado** y por eso a el no le pasa: su panel de la
 * derecha es una celda de tabla, o sea tan ancha como su linea mas larga, y la
 * rejilla ocupa lo que sobre. Aqui las columnas eran una **proporcion fija**
 * del ancho —52/26/22— y eso se rompe en cuanto la ventana encoge: el rotulo
 * mas largo pasa de caber a partirse sin que nada cambie en la pantalla.
 *
 * Medido el 21 de septiembre de 2026 en la ficha de movimientos. «Impedir
 * Registrar Documentos Retroactivamente» mide **295 px** de texto:
 *
 * | Ventana | `zona-fin` | ¿cabe? |
 * |---|---|---|
 * | 1920 | 368 px | si |
 * | 1600 | 297 px | **no** |
 * | 1366 | 246 px | **no** |
 *
 * O sea que a 1920 —donde se diseño— no se veia, y en cuanto el propietario
 * abrio la ventana mas pequeña salio partido en dos. Con `auto` cada columna
 * pide su `max-content` y el reparto deja de depender del tamaño de la
 * ventana; por debajo de 1180 px el tablero se apila igual que antes.
 */
.tablero.derecha-ajustada {
    /*
     * **Dos columnas**: la rejilla con su ficha debajo, y los recuadros
     * apilados a la derecha. Es como estan en el heredado —sus
     * `datos_movimiento1`, `3` y `4` van uno debajo de otro— y lo pidio el
     * propietario el 21 de septiembre de 2026.
     */
    grid-template-columns: minmax(0, 1fr) auto;
}

/*
 * Dos zonas, para las fichas cortas.
 *
 * Los ocho catalogos son un codigo, una descripcion y poco mas, de modo que
 * con el reparto de tres columnas quedarian dos casi vacias.
 *
 * **La ficha se mide por lo que tiene dentro, no por un porcentaje.** Estuvo
 * un rato como `68fr / 32fr` y a 1920 eso son 530 px para dos campos: un
 * rectangulo vacio del tamaño de media pantalla. Se ve mirando Familias, que
 * tiene cinco filas — a esa resolucion la pantalla quedaba vacia en un 85 %—.
 * Con un ancho fijo, la rejilla se queda con todo lo demas y la ficha parece
 * puesta a proposito en vez de sobrada.
 */
.tablero.dos-zonas {
    grid-template-columns: minmax(0, var(--col-rejilla, 74fr))
                           minmax(0, var(--col-centro, 26fr));
    grid-template-rows: 1fr;
}
.tablero.dos-zonas > .zona-rejilla   { grid-area: 1 / 1 / 2 / 2; }
.tablero.dos-zonas > .zona-principal { grid-area: 1 / 2 / 2 / 3; }

/*
 * Y sin ficha, una sola zona: la rejilla se lleva la pantalla. Es lo que usan
 * los siete catalogos que se editan en su propia lista.
 */
.tablero.una-zona { grid-template-columns: minmax(0, 1fr); grid-template-rows: 1fr; }
.tablero.una-zona > .zona-rejilla { grid-area: 1 / 1 / 2 / 2; }

/*
 * Por debajo de esto el reparto no cabe y las zonas se apilan. El diseño es
 * para 1920, que es donde se trabaja, pero apilarse es lo unico razonable en
 * una pantalla estrecha.
 */
@media (max-width: 1180px) {
    .tablero { grid-template-columns: 1fr; grid-template-rows: none; }
    .tablero > .zona { grid-area: auto; }
}

/*
 * La caja que envuelve la rejilla en la vista.
 *
 * **La rejilla nunca enseña barra horizontal**, por peticion del propietario;
 * la vertical, solo si hace falta. Quien reparte el ancho es `fitColumns`, que
 * encoge las columnas al ancho disponible en vez de desbordarlo.
 *
 * Estuvo escrita a mano como `style="overflow-x:auto"` en siete pantallas y
 * **era la que sacaba la barra**: esconderla en el cuerpo de la rejilla no
 * bastaba, porque la de la envoltura es otra. Costo verlo porque la
 * comprobacion medía el cuerpo y respondia que no habia ninguna.
 */
.caja-rejilla { overflow-x: hidden; }

/* --- El panel: la caja de cada zona --- */

.panel {
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.panel.crece { flex: 1; }
/*
 * La barra de titulo del panel, «Resultado de búsqueda».
 *
 * 22 px de alto y peso 700, que es lo que mide la del heredado
 * —`.ui-jqgrid-titlebar`—. Estaba en 28 con la linea a 1,6.
 */
.panel > .cabecera {
    display: flex; justify-content: space-between; align-items: baseline; gap: var(--e3);
    padding: 2px var(--e3);
    background: var(--superficie-3);
    border-bottom: 1px solid var(--borde);
    font-size: var(--txt-s); font-weight: 700; line-height: 1.4;
    color: var(--texto-2);
}
.panel > .cabecera .apunte { font-weight: 400; font-size: var(--txt-xs); white-space: nowrap; }
/*
 * **`min-height: 0` no es adorno.** Un elemento flexible no baja de su
 * contenido por omision (`min-height: auto`), de modo que sin esto el cuerpo se
 * queda con el alto de lo que lleva dentro y **empuja hacia abajo**: lo que
 * crece —la imagen del articulo— no puede encogerse para caber, y la pagina
 * saca una barra de desplazamiento. Con esto, el cuerpo mide lo que le deja el
 * panel y lo que sobra se reparte dentro.
 */
.panel > .cuerpo {
    padding: var(--e2) var(--e3) var(--e3);
    flex: 1; min-height: 0;
    display: flex; flex-direction: column;
}

/* --- El campo compacto: la etiqueta a la IZQUIERDA, en su columna ---
 *
 * Es la mitad de la densidad. Con la etiqueta encima, cada campo son unos
 * 64 px —`label` con su margen mas la caja con su relleno—; al lado, 25.
 * Con una ficha de 38 campos eso es 2 400 px de formulario contra 950.
 */
.campo {
    display: grid;
    grid-template-columns: var(--col-etiqueta, 116px) 1fr;
    align-items: center;
    gap: 0 var(--e3);
    min-height: 25px;
}
.campo > label {
    display: block; margin: 0;
    font-size: var(--txt-s); color: var(--texto-2);
    text-align: right; line-height: 1.2;
}
.campo > .control { min-width: 0; }
/*
 * La cadena de `:not()` no es adorno: la regla general de este archivo es
 * `input:not([type=checkbox]):not([type=radio]):not([type=file])`, que suma
 * (0,3,1). Sin repetirla, `.campo :is(input, select, textarea)` se queda en
 * (0,1,1) y **pierde**: los campos de la ficha salian como cajas con borde en
 * vez de como una ficha. Se vio abriendo la pantalla, no en ninguna prueba.
 */
.campo :is(input, select, textarea):not([type=checkbox]):not([type=radio]):not([type=file]) {
    width: 100%;
    padding: 2px 5px;
    font-size: var(--txt-s);
    line-height: 1.4;
    border: 1px solid transparent;
    border-radius: var(--radio-campo);
    background: transparent;
    color: var(--texto);
}

/*
 * Deshabilitado es **la ficha**, no un campo roto: se lee, no se toca, y se
 * nota sin gritar. Por eso no se usa el gris de `input:disabled` general.
 */
/*
 * **La cadena de `:not()` va tambien aqui**, y por segunda vez en este archivo.
 * La regla de arriba suma (0,4,1) y un `.campo :is(...):disabled` se queda en
 * (0,2,1): pierde, de modo que el borde transparente de la base ganaba y **la
 * linea de puntos no se pintaba nunca**. Los campos parecian rotulos sueltos
 * sin sitio donde escribir; se vio abriendo la pantalla en el tema oscuro.
 */
.campo :is(input, select, textarea):not([type=checkbox]):not([type=radio]):not([type=file]):disabled {
    background: transparent;
    color: var(--texto);
    opacity: 1;
    /* Los cuatro lados, no solo el de abajo: la regla general pone un borde
       completo y dejar tres puestos devuelve la caja que se quiere quitar. */
    border: 1px solid transparent;
    border-bottom: 1px dotted var(--linea-ficha);
    border-radius: 0;
}
.campo :is(input, select, textarea):not([type=checkbox]):not([type=radio]):not([type=file]):not(:disabled) {
    background: var(--fondo);
    border: 1px solid var(--borde);
    border-radius: var(--radio-campo);
}
.campo select:disabled { appearance: none; }

/*
 * La casilla de un campo.
 *
 * Es la primera de una ficha: las once banderas de Movimientos son
 * desplegables «No/Sí». **No la toca la regla base de los campos**, que empieza
 * excluyendo `[type=checkbox]`, de modo que aqui hay que decirlo todo.
 *
 * Se le pone el tamaño del texto de la ficha —por omision el navegador la
 * dibuja a 13 px sea cual sea la letra— y el acento del tema, que es lo que la
 * hace visible en el oscuro. Y **en consulta se apaga sin borrarla**: `opacity`
 * a la mitad diria «aqui no hay nada», y lo que dice es «esto no se toca
 * ahora».
 */
.campo .control input[type=checkbox] {
    width: 15px; height: 15px;
    margin: 2px 0;
    accent-color: var(--acento);
    vertical-align: middle;
}
.campo .control input[type=checkbox]:disabled {
    opacity: .85;
    cursor: default;
}

/*
 * Una bandera se lee «☐ Texto», no «Texto ☐».
 *
 * El `.campo` normal pone el rotulo a la izquierda en su columna y el control
 * a la derecha, que para una caja de texto es lo denso. Para un booleano no:
 * deja el texto pegado al borde y la casilla sola al otro lado del panel, a
 * 200 px de la palabra que explica lo que marca. **El heredado los pinta
 * seguidos**, y es lo que el propietario pidio conservar.
 *
 * La casilla va primera en el HTML, de modo que aqui no hace falta reordenar
 * nada: solo estrechar su columna y devolver el rotulo a la izquierda.
 */
.campo.casilla {
    grid-template-columns: 16px 1fr;
    gap: 0 var(--e2);
}
.campo.casilla > label {
    text-align: left;
    color: var(--texto);
}

/*
 * Lo que cuelga de la casilla de encima, con la sangria del heredado.
 *
 * Y `.apagado` es lo que se ve cuando su condicion no se cumple. Media
 * opacidad y no esconderlo: **esconder una opcion la hace desaparecer del
 * mapa** y quien la busque no sabra que existe ni de que depende; apagada se
 * lee, y su `title` dice por que no se puede tocar.
 */
.subordinado { padding-left: var(--e4); }
.subordinado.sangria-2 { padding-left: calc(var(--e4) * 2); }
.apagado { opacity: .5; }

/*
 * La marca de los campos que viajan en el XML de SUNAT.
 *
 * **Estaba escrita dentro de `documento-formulario.blade.php`** y la usan
 * cuatro vistas, de modo que en las otras tres salia como texto pelado pegado
 * al rotulo: en la ficha de movimientos se leia «T/Op. Sunat SEESUNAT». Es el
 * mismo vicio de siempre aqui —lo que comparten dos pantallas no vive dentro
 * de una—, y ademas no daba ningun error.
 */
/* La de Contasis es la misma pieza: en los campos que también usa «Traer de Contasis». */
.marca-sunat, .marca-contasis {
    font-size: 9px; font-weight: 700; letter-spacing: .08em;
    vertical-align: middle; margin-left: 5px; padding: 1px 4px;
    border: 1px solid var(--borde); border-radius: 3px;
    color: var(--texto-2); background: var(--superficie-2);
    white-space: nowrap;
}
label[title], input[title], select[title], .marca-sunat[title], .marca-contasis[title] { cursor: help; }
/* Los botones de Contasis, en su propia línea dentro de los filtros. */
/* Un `fieldset` que solo sirve para deshabilitar de una vez lo de dentro. */
fieldset.sin-marco { border: 0; margin: 0; padding: 0; min-width: 0; }
.contasis-acciones { flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: var(--e3, 8px); }
.contasis-acciones .marca-contasis { margin-left: 0; }
/* Lo que el motivo o la modalidad de ahora vuelven obligatorio. */
.marca-obligatorio { color: var(--malo, #c0392b); font-weight: 600; font-size: 11px; }
/* Una observacion no tumba el comprobante: se avisa en ambar. */
.marca-observado { color: var(--aviso, #b8860b); font-weight: 600; font-size: 11px; }

/*
 * La caja que enseña de que es el codigo que se acaba de elegir.
 *
 * Va al lado de su campo, como en el heredado —«CADEL001 · CANTO DELGADO
 * ABEDUL»—, y **no se teclea**: la rellena el autocompletado. Se ve apagada
 * para que nadie lo intente, y no lleva `name`, de modo que no viaja ni en la
 * peticion ni en el CSV.
 */
/*
 * La caja larga de un par «codigo + descripcion».
 *
 * **No es de solo lectura**, y eso es lo que se corrigio el 21 de septiembre
 * de 2026: «el autocompletado es independiente». Las dos buscan —la corta por
 * codigo, la larga por descripcion— y elegir en cualquiera rellena las dos,
 * que es lo que hacen los cuatro `load_autocomplete1` del heredado. Estaba
 * gris y bloqueada, como si fuera el rotulo de la otra.
 */
.descripcion-filtro { min-width: 0; }

/*
 * Los filtros del kardex y los de la venta detallada, con la reticula de su
 * pantalla.
 *
 * Su `<table>` son **cuatro filas y dos columnas**, y se lee bajando por la
 * izquierda y despues por la derecha. Lo devolvio el propietario el 21 de
 * septiembre de 2026 —«no tomaste en cuenta como estaban alineadas ni
 * ordenadas»— cuando estaban en una fila que se doblaba sola, y otra vez con
 * la venta detallada: «todos mis filtros no estan y tampoco estan aplicados,
 * menos alineados ni en orden». **Las dos pantallas son la misma reticula**,
 * de modo que la clase no lleva el nombre de ninguna.
 *
 * El ancho de la etiqueta es **uno para las dos columnas**, de modo que los
 * ocho campos empiezan en la misma posicion de su mitad. Sale de la mas larga,
 * «R.U.C. / D.N.I.».
 */
.filtros-dos-columnas {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--e2) var(--e4);
    align-items: center;
    /*
     * 118 px es **el ancho del texto mas largo**, «Tipo de documento», medido
     * con un `Range` y no a ojo: con 108 se partia en dos lineas y su fila
     * salia 11 px mas alta que las demas.
     */
    --col-etiqueta: 118px;
    --col-etiqueta-2: 44px;
    /* Moneda no se estira hasta los radios: alli ocupa 15 % y «Tipo» 24 %. */
    --reparto-a: minmax(0, 200px);
    --reparto-b: auto;
}

/* Codigo y descripcion, como alli: caja corta con el numero a la derecha. */
.filtros-dos-columnas .par-codigo {
    display: grid;
    grid-template-columns: 88px minmax(0, 1fr);
    gap: var(--e2);
    align-items: center;
}
.filtros-dos-columnas .par-codigo > input:first-child { text-align: right; }

/*
 * Los tres radios de «Tipo», en una sola linea.
 *
 * A 1366 se partian en dos —«Bien Servicio» y «Ambos» debajo— y esa fila
 * salia 11 px mas alta que las otras tres, que es justo lo que se estaba
 * corrigiendo. Con `nowrap` la columna de los radios pide su ancho entero y
 * la de Moneda, que tiene el minimo en cero, encoge lo que haga falta.
 */
.filtros-dos-columnas .fila-radios { flex-wrap: nowrap; white-space: nowrap; }

/* Los botones, debajo y a lo ancho de las dos columnas. */
.acciones-filtros {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: var(--e3);
    margin-top: var(--e2);
}

/* En una pantalla estrecha no caben dos columnas de campo. */
@media (max-width: 1100px) {
    .filtros-dos-columnas { grid-template-columns: 1fr; }
}

/* Los radios de una fila, con su texto al lado. */
.fila-radios {
    display: flex; flex-wrap: wrap;
    gap: 0 var(--e3);
    align-items: center;
    min-height: 25px;
    font-size: var(--txt-s);
    color: var(--texto-2);
}
.fila-radios > label {
    display: inline-flex; align-items: center; gap: var(--e1);
    margin: 0; font-size: var(--txt-s); font-weight: normal;
}
.fila-radios input[type=radio] { margin: 0; accent-color: var(--acento); }

/*
 * El control que el servidor rechazo.
 *
 * Va **en el control y no en el campo**, porque un `.campo.pareja` lleva dos:
 * marcando el campo se encenderian los dos y el error se pintaria debajo del
 * que no es.
 *
 * **Y la cadena de `:not()` por tercera vez en este archivo.** Sin ella la
 * regla suma (0,3,1) y pierde contra
 * `.campo :is(...):not():not():not():not(:disabled)`, que vale (0,5,1) y
 * escribe el borde y el fondo normales: **el campo rechazado no se marcaba**,
 * solo salia el texto rojo debajo. Medido en la ficha de entidad, con el
 * borde en `--borde` y el fondo en `--fondo` teniendo la clase puesta.
 */
.campo .control.marcado :is(input, select, textarea):not([type=checkbox]):not([type=radio]):not([type=file]) {
    border: 1px solid var(--grave-borde);
    background: var(--grave-fondo);
}
/* El error cuelga del control, asi que no es un elemento de la reticula del
   campo y no necesita decir en que columna va. */
.campo .error {
    margin: 0; padding: 1px 0 2px;
    font-size: var(--txt-xs); color: var(--grave-texto);
}

/*
 * Dos campos en la misma fila.
 *
 * **No todo campo merece una fila propia.** El numero de documento y su tipo,
 * el limite de credito y su descuento, la familia y la subfamilia son la misma
 * cosa contada en dos columnas: separarlos alarga la ficha sin decir nada mas.
 * Es lo que hace el heredado, que los mete en la misma `<tr>`. Lo pidio el
 * propietario el 5 de septiembre de 2026.
 *
 * **Solo en la zona ancha**, y eso esta medido: el control mide 727 px a
 * 1920 y 439 a 1366. En los paneles estrechos baja a 149, y partir eso en dos
 * deja dos cajas donde no cabe nada.
 *
 * El reparto se desiguala desde la vista, igual que `--col-etiqueta`:
 * `style="--reparto-a: 2fr"` para el que necesite mas sitio. **Uno desigual
 * rompe la alineacion de su fila**, de modo que solo se usa cuando el campo no
 * cabe de otra manera.
 *
 * `--col-etiqueta-2` fija la segunda columna de rotulos. Sin ella es `auto`,
 * que la ajusta **a cada fila por separado** y deja los campos de la derecha
 * empezando cada uno en un sitio: medido en el articulo, cinco filas y cinco
 * posiciones —603, 622, 635, 636 y 677—. Lo señalo el propietario: «los campos
 * de la derecha que tengan alineacion en lo que se pueda».
 */
.campo.pareja {
    grid-template-columns:
        var(--col-etiqueta, 116px) var(--reparto-a, 1fr)
        var(--col-etiqueta-2, auto) var(--reparto-b, 1fr);
}

/* Un area que crece hasta llenar lo que le deje su columna. */
/*
 * Un area que se lleva **todo el alto que le sobre a su panel**.
 *
 * Deja de ser una rejilla de etiqueta y campo: con dos filas automaticas, el
 * espacio de mas se repartia entre las dos y el area quedaba flotando en
 * mitad del panel, con un hueco encima. En columna, la etiqueta ocupa lo suyo
 * y el area se queda con el resto, que es lo que se le pide a una observacion.
 */
.campo.alto {
    display: flex;
    flex-direction: column;
    /* `.campo` alinea al centro, y en columna eso **centra horizontalmente**:
       el area salia estrecha y en mitad del panel en vez de llenarlo. */
    align-items: stretch;
    flex: 1;
    min-height: 90px;
    gap: var(--e1);
}
.campo.alto > label { text-align: left; padding-top: 0; }
.campo.alto > .control { display: flex; flex: 1; min-height: 0; }
.campo.alto textarea { resize: none; flex: 1; height: 100%; padding-top: 3px; }

/*
 * Un area grande y deshabilitada no puede ser transparente del todo: sin nada
 * escrito no se ve que este ahi, y quien entra no sabe que hay donde escribir.
 * Lleva el punteado a los cuatro lados en vez de solo abajo.
 */
.campo.alto textarea:not([type=checkbox]):not([type=radio]):not([type=file]):disabled { border: 1px dotted var(--linea-ficha); border-radius: var(--radio-campo); }
.campo.ancho { grid-template-columns: 1fr; }
.campo.ancho > label { text-align: left; margin-bottom: var(--e1); }

/* Un rotulo dentro del panel: «Contacto 1», «Contacto 2». */
.subgrupo {
    margin: var(--e3) 0 0; padding: var(--e2) 0;
    border-top: 1px solid var(--superficie-2);
    font-size: var(--txt-xs); font-weight: 600; letter-spacing: .1em;
    text-transform: uppercase; color: var(--texto-2);
}

/*
 * La imagen del articulo, dentro de la ficha.
 *
 * El heredado la enseña a la derecha con su «Cambiar Imagen», y aqui se subia
 * sin verse en ninguna parte. Va fuera de la reticula de campos porque **no
 * viaja con el resto de la ficha**: es un archivo y se manda aparte.
 */
/*
 * **Se estira con lo que le sobra al panel. Nada más.**
 *
 * El marco medía 110 px fijos y debajo quedaban 485 de nada: la ficha de SUNAT
 * es corta y el panel corre a toda altura. Con `flex: 1` se estira.
 *
 * **El heredado no hace ninguna de las dos cosas**: tiene una caja fija de
 * 182 × 182 con una miniatura dentro. Aquí se aprovecha el sitio que allí se
 * desperdicia.
 *
 * **Aquí hubo un techo escrito a mano, `calc(100vh - 494px)`, y estaba mal.**
 * El 494 salía de sumar lo que había encima y debajo del marco a 1920 × 1080,
 * de modo que el marco decidía el alto del panel y el conjunto **acababa
 * justo** en el borde de la ventana: 36 px de margen en la medida. Cualquier
 * cosa que sumara esos 36 —una barra de desplazamiento de verdad, que ocupa
 * 15, o una fuente que en Windows corre distinta— tiraba la cuenta y sacaba la
 * barra vertical. Lo dijo el propietario con su pantalla delante.
 *
 * Ahora **no hay ninguna cuenta**: el panel manda, el cuerpo puede encogerse
 * —ver `min-height: 0` allí arriba— y el marco toma lo que quede después del
 * selector de archivo y el botón. No puede desbordar porque no decide nada.
 *
 * El `min-height` es el suelo: antes que un marco de nada, que el panel
 * recorte —lo hace con su `overflow: hidden`, sin mover la página—.
 */
.imagen-ficha {
    text-align: center;
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}
.imagen-ficha .marco {
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    background: var(--fondo);
    flex: 1;
    min-height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--e2);
    margin-bottom: var(--e2);
    overflow: hidden;
    /* El bloque contenedor de la foto, que va fuera del flujo: ver abajo. */
    position: relative;
}
/*
 * **La foto va fuera del flujo, y esa es la única forma de que no empuje.**
 *
 * Con la imagen en el flujo, su `max-height: 100%` **no tiene contra qué
 * resolverse**: el alto del marco sale de `flex: 1` sobre un contenedor cuyo
 * alto es a su vez el de su contenido, de modo que el porcentaje es
 * indefinido, el navegador lo ignora y **una foto alta estira el marco, el
 * panel y la página**. Lo vio el propietario: «la imagen sigue creciendo en la
 * vertical cuando hay una imagen larga». Es la misma trampa que ya costó una
 * vuelta con `grid` y `place-items`, y ponerle un techo en `vh` fue el parche
 * que hubo que quitar después.
 *
 * En posición absoluta el bloque contenedor es el marco, cuyo alto usado **sí**
 * está resuelto, así que el `100 %` significa algo; y sobre todo la foto **no
 * aporta alto**, de modo que no puede empujar a nadie. Lo que decide el tamaño
 * del marco es lo que le sobra al panel, y solo eso.
 *
 * No se agranda más allá de su tamaño: estirarla la dejaría borrosa.
 */
.imagen-ficha .marco img {
    position: absolute;
    /*
     * `inset: 0` con `margin: auto` la centra en los dos ejes sin `transform`,
     * que a medio pixel la deja borrosa. Y el techo descuenta el relleno: para
     * un elemento posicionado el `100 %` es el **cuadro de relleno**, de modo
     * que sin restarlo la foto llegaria hasta el borde.
     */
    inset: 0;
    margin: auto;
    width: auto;
    height: auto;
    max-width: calc(100% - var(--e2) * 2);
    max-height: calc(100% - var(--e2) * 2);
}
.imagen-ficha input[type=file] { width: 100%; font-size: var(--txt-xs); }
.imagen-ficha button { width: 100%; }

/*
 * El visor: la imagen en grande, centrada sobre la pantalla.
 *
 * Es lo que hace el heredado con fancybox. El fondo va oscuro en los dos temas
 * a proposito —lo que se mira es la foto— y la imagen no pasa del 90 % de la
 * ventana para que se vea entera sin desplazar.
 */
.visor-imagen {
    position: fixed;
    inset: 0;
    z-index: 90;
    background: rgba(0, 0, 0, .72);
    display: grid;
    place-items: center;
    padding: var(--e5);
}
.visor-imagen .marco { position: relative; }
.visor-imagen img {
    display: block;
    max-width: 90vw;
    max-height: 90vh;
    border-radius: var(--radio);
    box-shadow: 0 10px 40px rgba(0, 0, 0, .5);
    background: #fff;
}
.visor-imagen .cerrar {
    position: absolute;
    top: -12px; right: -12px;
    width: 28px; height: 28px;
    padding: 0;
    border-radius: 50%;
    font-size: var(--txt-m);
    line-height: 1;
    background: var(--superficie);
    color: var(--texto);
    border: 1px solid var(--borde);
    box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
}

/* La imagen que se puede abrir en grande lo dice con el cursor. */
img[data-visor] { cursor: zoom-in; }

/* Un rotulo que solo leen los lectores de pantalla. */
.sr-solo {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; border: 0;
}

/*
 * Campos que hoy no tiene ni una fila.
 *
 * Estan, se guardan y se editan como los demas: que nadie los use dice por
 * donde empezar, no que se puedan dejar fuera (ver WORKFLOW.md). La marca solo
 * lo hace visible, y la casilla de la barra la enciende y la apaga.
 */
/*
 * En una pareja la marca no puede ir en el campo —son dos y solo uno lo es—,
 * asi que va **en la etiqueta**. Entonces se resalta la etiqueta y no la fila,
 * que es lo unico que distingue a uno de su compañero.
 */
.campo.sinuso > label::after,
.campo > label.sinuso::after {
    content: "°";
    /*
     * El texto del aviso y no su borde: la marca se lee, y con el borde daba
     * 2,12:1 en el tema claro y 3,95:1 en el oscuro. Medido con ventana el 9
     * de noviembre de 2026 (`medir-fichas-con-ventana.js`).
     */
    color: var(--aviso-texto); font-weight: 700;
    margin-left: 2px; vertical-align: super; font-size: 9px;
}
.resaltar-sinuso .campo.sinuso { background: var(--aviso-fondo); border-radius: 2px; }
.resaltar-sinuso .campo.sinuso > label,
.resaltar-sinuso .campo > label.sinuso { color: var(--aviso-texto); }
.resaltar-sinuso .campo > label.sinuso {
    background: var(--aviso-fondo); border-radius: 2px;
}
.resaltar-sinuso .campo.sinuso.alto { background: none; }
.resaltar-sinuso .campo.sinuso.alto textarea { border-left: 3px solid var(--aviso-borde); }

.leyenda-ficha {
    margin: var(--e3) 0 0; padding-top: var(--e2);
    border-top: 1px solid var(--superficie-2);
    font-size: var(--txt-xs); color: var(--texto-2);
}
.leyenda-ficha .marca { color: var(--aviso-texto); font-weight: 700; }   /* la misma que la de la etiqueta */

/* --- La barra de acciones --- */

.acciones { display: flex; flex-wrap: wrap; gap: var(--e2); align-items: center; }
.acciones .separa { flex: 1; }
/*
 * Lo de la derecha de la barra —el enlace al formulario suelto, la casilla y el
 * rotulo de modo— son cosas distintas entre si, y con el hueco de los botones
 * quedaban pegadas. Un poco mas de aire solo ahi.
 */
.acciones .separa ~ * { margin-left: var(--e3); }
/*
 * Los botones, a la altura del rotulo de modo.
 *
 * El boton general lleva `padding: 8px 15px`; en una barra compacta eso se ve,
 * y **el del heredado mide 22,8 px**. Se iguala por el relleno vertical —3 px,
 * que con la linea de 14,4 y el borde dan 22,4— y no con una altura fija, para
 * que siga creciendo si alguien cambia la fuente.
 *
 * Solo aqui: el boton de acceder o el de un formulario no tienen por que
 * encogerse por esto.
 */
.acciones button { padding-top: 3px; padding-bottom: 3px; }
/*
 * Y un desplegable de la barra, a la misma altura que ellos.
 *
 * `select` lleva `padding: 8px 10px`, de modo que el de «Tipo de movimiento»
 * salia mas alto que los botones que tiene al lado y cantaba. Se iguala por el
 * mismo sitio —el relleno vertical— y por el mismo motivo: con una altura fija
 * dejaria de acompañar si alguien cambia la fuente.
 *
 * **Y con el relleno solo no basta**: medido, quedaban 24 px contra 22,4. Lo
 * que sobra es la interlinea —el boton la lleva en 1,2 y un `select` la trae
 * en `normal`, que a 12 px son 16— y **`line-height` no sirve para
 * arreglarlo**: Chrome la ignora en un `<select>`, probado y medido, sigue
 * dando 24.
 *
 * Asi que va por altura, pero **en `em` y no en pixeles**, que es lo que la
 * deja seguir a la fuente: `1.2em` es la interlinea del boton y los 8 px son
 * sus 3 y 3 de relleno mas el borde, porque la caja es `border-box`. A 12 px
 * salen los mismos 22,4 que ellos.
 */
.acciones select {
    padding-top: 3px; padding-bottom: 3px;
    height: calc(1.2em + 8px);
}
.acciones button:disabled {
    opacity: .45;
    cursor: default;
    background: var(--superficie-2);
    color: var(--texto-2);
    border-color: var(--borde);
}
.acciones label { display: inline-flex; align-items: center; gap: var(--e2); margin: 0; cursor: pointer; }
.acciones label input { margin: 0; width: auto; accent-color: var(--aviso-borde); }

/*
 * En que modo esta la ficha. No es decoracion: editando, la pantalla deja de
 * responder a la seleccion de filas, y hay que poder verlo sin probarlo.
 */
.modo-ficha {
    padding: 5px 9px; border-radius: var(--radio);
    border: 1px solid transparent; white-space: nowrap;
    font-size: var(--txt-xs); font-weight: 600;
    letter-spacing: .08em; text-transform: uppercase;
}
.modo-ficha[data-modo="ver"]    { color: var(--texto-2); }
.modo-ficha[data-modo="editar"] { color: var(--aviso-texto); background: var(--aviso-fondo); border-color: var(--aviso-borde); }
.modo-ficha[data-modo="nuevo"]  { color: var(--acento); background: var(--realce); border-color: var(--acento); }

/* ==========================================================================
 * Tabulator
 *
 * La rejilla de los catalogos, que es la primera que dejo jqGrid. Todo lo que
 * la viste con los colores y la densidad de Linsoft esta **aqui**: la libreria
 * se vendoriza sin una sola modificacion, que es justo lo contrario de lo que
 * pasa con jqGrid —28 reglas dentro de su CSS que hay que recordar al
 * actualizar, ver `MODIFICACIONES.md`—.
 *
 * Son las mismas decisiones de siempre: filas de 22 px, tipografia compacta y
 * los dos temas por variables.
 * ========================================================================== */

/*
 * **`body` delante no es un capricho.** La hoja de Tabulator la inyecta el
 * cargador de modulos *despues* de esta, de modo que con la misma
 * especificidad ganaba la suya: el titulo salia claro sobre su `#e6e6e6` y no
 * se leia nada en el tema oscuro. Un elemento delante basta para ordenarlo sin
 * tocar la libreria.
 */
body .tabulator {
    background: var(--superficie);
    border: none;
    font-family: inherit;
    /*
     * **Las medidas son las de jqGrid, medidas en pantalla**: fila de 22 px,
     * texto de 12 y relleno de celda `0 2px`. Tabulator trae 23, 13 y `2px 6px`,
     * que parece poco y en una lista de veinticinco lineas se nota.
     */
    font-size: var(--txt-s);
    color: var(--texto);
}

body .tabulator .tabulator-header {
    background: var(--superficie-2);
    color: var(--texto);
    border-bottom: 1px solid var(--borde);
    font-weight: 700;
}
body .tabulator .tabulator-header .tabulator-col {
    background: var(--superficie-2);
    border-right: 1px solid var(--borde);
    color: var(--texto);
}
body .tabulator .tabulator-header .tabulator-col .tabulator-col-content { padding: 2px var(--e1); }
body .tabulator .tabulator-header .tabulator-col .tabulator-header-filter { padding: 1px 2px 2px; }
body .tabulator .tabulator-header .tabulator-col .tabulator-col-title {
    /*
     * **12 px, como la celda**, que es lo que mide en el heredado; estaba en
     * 13 y se notaba. Lo que la distingue es el peso y el fondo de la
     * cabecera, no el tamaño.
     */
    font-size: var(--txt-s);
    font-weight: 700;
    /* Su CSS le pone un color propio y sobre el tema oscuro no se leia. */
    color: var(--texto);
}
/* La flecha de ordenar, que por omision es un triangulo gris casi invisible. */
body .tabulator .tabulator-header .tabulator-col .tabulator-col-sorter .tabulator-arrow { border-bottom-color: var(--texto-2); }
body .tabulator .tabulator-header .tabulator-col[aria-sort="ascending"] .tabulator-arrow,
body .tabulator .tabulator-header .tabulator-col[aria-sort="descending"] .tabulator-arrow { border-bottom-color: var(--acento); }

/* La fila de filtros, que es el `filterToolbar` del heredado. */
body .tabulator .tabulator-header .tabulator-col .tabulator-header-filter input {
    font: inherit;
    font-size: var(--txt-s);
    /*
     * 20 px y sin relleno, que es lo que mide la caja de filtro en jqGrid.
     *
     * **`!important` aqui esta justificado**, y es el unico de este archivo:
     * Tabulator le escribe `padding: 4px` en el atributo `style` del propio
     * input, y contra un estilo en linea no gana ninguna hoja. La alternativa
     * era escribir un filtro propio para no usar el suyo, que es mucho por
     * cuatro pixeles.
     */
    padding: 0 2px !important;
    /* 16 px, medido en el heredado. Estaba en 20. */
    height: 16px;
    width: 100%;
    font-weight: 400;
    color: var(--texto);
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
}

/*
 * Los tres iconos de «Situacion» en Envios a SUNAT. En color lo que se puede
 * abrir, en gris lo que no hay — que es lo que hace el heredado. Ver
 * `situacion-sunat.js`.
 */
.iconos-sunat { display: inline-flex; gap: 3px; align-items: center; }
.icono-sunat { display: inline-flex; line-height: 0; border-radius: 3px; padding: 1px; }
/* El sitio del check de validez cuando no lo hay: los demás iconos no se mueven. */
.icono-sunat.hueco { width: 20px; height: 20px; }
a.icono-sunat:hover { background: var(--superficie-2); }
/* El gris no invita a pulsar cuando no lleva a ninguna parte. */
.icono-sunat.apagado { cursor: default; }
/*
 * Pero un gris **con algo que hacer** si: en el heredado el icono apagado no
 * informa, actua. Se distingue por el cursor y por el realce al pasar.
 */
.icono-sunat.pulsable { cursor: pointer; }
.icono-sunat.pulsable:hover { background: var(--superficie-2); }

body .tabulator .tabulator-tableholder {
    background: var(--superficie);
    /*
     * **El hueco de la barra vertical se reserva siempre.**
     *
     * Sin esto, `fitColumns` reparte el ancho *antes* de que aparezca la barra
     * vertical, esta le quita 15 px al hueco y lo que sobra se convierte en una
     * **barra horizontal de exactamente esos 15 px**. Es la unica forma en que
     * una rejilla con `fitColumns` puede desbordar, porque el reparto no puede
     * pasarse del ancho por si solo.
     *
     * Con `stable`, el hueco mide lo mismo haya barra o no, de modo que el
     * reparto se hace contra el ancho definitivo y no hay delta que sobre.
     *
     * **Ojo al comprobarlo con el navegador sin ventana**: alli las barras son
     * superpuestas y miden **0 px**, asi que este fallo no se puede ver en
     * `revisar-interfaz.js`. Medido: `offsetWidth - clientWidth` da 0 sin
     * ventana y 15 con ella.
     */
    scrollbar-gutter: stable;
}
/*
 * **La tabla de dentro tambien.** Tabulator le escribe `background: #fff` a
 * `.tabulator-table`, y eso es un rectangulo blanco debajo de las filas: no se
 * ve mientras las filas lo tapan, y asoma en cuanto la rejilla es mas alta que
 * su contenido —o mientras carga—. En el tema oscuro es un fogonazo.
 */
body .tabulator .tabulator-tableholder .tabulator-table {
    background: var(--superficie);
    color: var(--texto);
}
body .tabulator .tabulator-tableholder:focus-visible { outline: 2px solid var(--acento); outline-offset: -2px; }

body .tabulator .tabulator-row {
    background: var(--superficie);
    color: var(--texto);
    border-bottom: 1px solid var(--borde);
    min-height: 22px;
    height: 22px;
}
body .tabulator .tabulator-row.tabulator-row-even { background: var(--superficie); }
body .tabulator .tabulator-row:hover { background: var(--superficie-2); }
body .tabulator .tabulator-row.tabulator-selected,
body .tabulator .tabulator-row.tabulator-selected:hover {
    background: var(--acento);
    color: var(--acento-texto);
}
body .tabulator .tabulator-row .tabulator-cell {
    border-right: 1px solid var(--borde);
    padding: 0 2px;
    /* 21 y el borde de abajo suman los 22 de jqGrid: el borde cuenta. */
    height: 21px;
    line-height: 21px;
}
body .tabulator .tabulator-row .tabulator-cell.numero-fila { color: var(--texto-2); font-variant-numeric: tabular-nums; }
/*
 * **En la fila seleccionada, el numero se lee como el resto.**
 *
 * El gris de `--texto-2` sobre el acento da **1,23:1**, o sea invisible: la
 * fila seleccionada es la que se esta mirando y su numero es justamente el que
 * sirve para decir «la tercera». La fila ya cambia su `color` al seleccionarse
 * y esta regla lo pisaba, porque es mas especifica.
 */
body .tabulator .tabulator-row.tabulator-selected .tabulator-cell.numero-fila { color: inherit; }
body .tabulator .tabulator-row .tabulator-cell.num { font-variant-numeric: tabular-nums; }

/* La celda abierta para teclear: es lo que hacen los siete catalogos cortos. */
body .tabulator .tabulator-row .tabulator-cell.tabulator-editing {
    border: 1px solid var(--acento);
    padding: 1px 5px;
    border-radius: var(--radio-campo);
}
body .tabulator .tabulator-row .tabulator-cell.tabulator-editing input,
body .tabulator .tabulator-row .tabulator-cell.tabulator-editing select {
    font: inherit;
    color: var(--texto);
    background: var(--superficie);
    /* El mismo radio que cualquier otro campo del proyecto. */
    border-radius: var(--radio-campo);
}
body .tabulator .tabulator-row .tabulator-cell.tabulator-validation-fail {
    border: 1px solid var(--grave-borde);
    background: var(--grave-fondo);
}

body .tabulator .tabulator-footer {
    background: var(--superficie-2);
    border-top: 1px solid var(--borde);
    color: var(--texto-2);
    font-size: var(--txt-s);
    /*
     * **26 px de alto, como el paginador del heredado.** Estaba en 37, que en
     * una pantalla que se quiere compacta son once pixeles de nada debajo de
     * cada rejilla. Se aprieta por el relleno y por el de sus botones, no con
     * una altura fija, para que siga creciendo si cambia la fuente.
     */
    padding: 0 var(--e2);
    font-weight: 400;
}
/*
 * El relleno de verdad esta aqui: Tabulator le pone `5px 10px` a la caja de
 * dentro, y es la que mandaba. Con el pie a cero seguian saliendo 31 px.
 */
body .tabulator .tabulator-footer .tabulator-footer-contents { padding: 2px 0; margin: 0; }
body .tabulator .tabulator-footer .tabulator-page {
    font: inherit;
    padding: 0 var(--e2);
    margin: 0 1px;
    background: var(--superficie);
    color: var(--texto);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
}
body .tabulator .tabulator-footer .tabulator-page.active {
    background: var(--acento);
    color: var(--acento-texto);
    border-color: var(--acento);
}
body .tabulator .tabulator-footer .tabulator-page:disabled { opacity: .45; }
body .tabulator .tabulator-footer .tabulator-paginator label { color: var(--texto-2); }

/*
 * **El desplegable de filas por pagina: sin rotulo y al final, como alli.**
 *
 * En el heredado el pie es `|◀ ◀◀ Página 1 de 2 ▶▶ ▶| [50]`: el combo va **el
 * ultimo y sin nombre**. Peticion del propietario, 19 de septiembre de 2026.
 *
 * Y ademas arregla lo que su `<label>` rompia. Tabulator lo pinta delante de
 * los botones con `margin: 12px 0 4px`, y ese margen desigual hacia dos cosas
 * a la vez —medido, no deducido—:
 *
 * - **bajaba el rotulo 4 px** respecto a todo lo demas del pie, porque
 *   `align-items: center` centra la caja **con sus margenes**, no el texto;
 * - y **estiraba el paginador a 34 px** (18 + 12 + 4), con lo que el pie
 *   pasaba de los **26 px** que este proyecto aprieta a proposito —«como el
 *   paginador del heredado»— a 39.
 *
 * Sin rotulo no hay margen que compensar. El nombre se conserva en el `title`
 * del propio desplegable, que lo pone `ponerBotones()`.
 */
/*
 * **El pie va en tres zonas, como el del heredado**: los botones a la
 * izquierda, el paginador **al centro** y el recuento a la derecha. Lo señalo
 * el propietario —«sigue alineado a la izquierda, en el heredado está en el
 * centro»— y es lo que hace jqGrid, que reparte su pie en tres celdas.
 *
 * **Con flex no salia, y conviene saber por que**: Tabulator le da al
 * paginador todo el hueco que sobra, de modo que sus botones se quedan
 * pegados al recuento aunque el bloque ocupe media pantalla. Medido: el
 * paginador iba de 202 a 1234 y su centro caia en 718, con el del pie en 620.
 * Con una reticula de `1fr auto 1fr` el centro es el centro, midan lo que
 * midan los lados.
 */
body .tabulator .tabulator-footer .tabulator-footer-contents {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
}
/*
 * **La fila se fija tambien, no solo la columna.** Sin ella, la colocacion
 * automatica va de izquierda a derecha y **no vuelve atras**: el contador
 * llega antes en el HTML y ocupa la columna 3, de modo que el paginador, que
 * pide la 2, se iba a **una segunda fila** y el pie pasaba de 25 px a 45.
 */
body .tabulator .tabulator-footer .acciones-rejilla { grid-area: 1 / 1; justify-self: start; }
body .tabulator .tabulator-footer .tabulator-page-counter { grid-area: 1 / 3; justify-self: end; }
body .tabulator .tabulator-footer .tabulator-paginator {
    grid-area: 1 / 2;
    justify-self: center;
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}
body .tabulator .tabulator-footer .tabulator-paginator label { display: none; }
body .tabulator .tabulator-footer .tabulator-page-size {
    /* `order` lo manda al final, detras de los botones: es donde va alli. */
    order: 1;
    font: inherit;
    margin: 0 0 0 var(--e3);
    padding: 0 var(--e1);
    background: var(--superficie);
    color: var(--texto);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
}

/*
 * Los dos botones de abajo a la izquierda, **los mismos que traia el heredado**:
 * `navGrid` con `{search: true, refresh: true}`. Se dibujan con los mismos
 * glifos que usaba jqGrid —« ‹ › » ⌕ ↻— y no con un sprite, porque asi toman
 * el color del tema.
 */
.acciones-rejilla { display: flex; gap: var(--e1); }
.acciones-rejilla button {
    font: inherit;
    font-size: 13px;
    line-height: 1;
    width: 20px;
    height: 20px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--superficie);
    color: var(--texto-2);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    cursor: pointer;
}
.acciones-rejilla button:hover { color: var(--acento); border-color: var(--acento); }

/*
 * Las dos clases con significado de negocio, que vienen del CSS heredado y no
 * son cosmetica: `.rowanulado` señala un documento anulado y `.rowitem` una
 * banda alterna. Ver `MODIFICACIONES.md`.
 */
body .tabulator .tabulator-row.rowanulado,
body .tabulator .tabulator-row.rowanulado:hover {
    background: var(--grave-fondo);
    color: var(--grave-texto);
    opacity: .7;
}
body .tabulator .tabulator-row.rowitem,
body .tabulator .tabulator-row.rowitem:hover { background: var(--realce); }
/*
 * **Lo que no aplica, apagado**, como el heredado: en ventas, la fecha de
 * envío, la situación y la observación de un documento que no sale a SUNAT
 * —su serie no empieza por F, B o T—.
 */
body .tabulator .tabulator-row .tabulator-cell.celda-sin-sunat { background: var(--celda-apagada); }

/*
 * El aviso de una celda.
 *
 * Su hoja lo deja **sin color**: `.tabulator-tooltip` trae el radio, el relleno
 * y el tamaño de letra, y nada mas, de modo que sin esto sale con lo que herede
 * y en el tema oscuro no se lee. Va con `body` delante como todo lo suyo.
 *
 * Se pinta al reves que la pagina —tinta de fondo, papel de letra—, que es lo
 * que hace que se lea encima de una rejilla llena sin tener que ponerle borde.
 */
/*
 * La casilla del estado, en la rejilla.
 *
 * Va apagada —ahi se mira, y se cambia en la ficha— y aun asi tiene que
 * leerse: sin `accent-color` el navegador la pinta gris sobre gris en el tema
 * oscuro. `body` delante por lo de siempre: la hoja de Tabulator entra
 * despues.
 */
body .tabulator .casilla {
    width: 13px; height: 13px;
    margin: 0;
    accent-color: var(--acento);
    opacity: .9;
    /* El clic es de la celda, no suyo: donde no hay ficha, pulsar la casilla
       con la fila en edicion es lo que la cambia, y un `input` apagado se lo
       tragaria sin hacer nada. */
    pointer-events: none;
    vertical-align: middle;
}

body .tabulator-tooltip {
    background: var(--texto);
    color: var(--superficie);
    border: 1px solid var(--texto);
    font-size: var(--txt-xs);
    line-height: 1.45;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .28);
    max-width: 460px;
}

/*
 * La cabecera de un grupo, como la banda del heredado.
 *
 * Va con `body` delante como todo lo de Tabulator: su hoja la inyecta el
 * cargador de modulos **despues** de esta, y con la misma especificidad
 * ganaria la suya.
 *
 * El segundo nivel se sangra, que es lo que hace jqGrid: la familia manda y la
 * subfamilia cuelga de ella.
 */
body .tabulator .tabulator-group {
    background: var(--superficie-3);
    border-bottom: 1px solid var(--borde);
    border-top: 1px solid var(--borde);
    color: var(--texto);
    font-size: var(--txt-s);
    font-weight: 400;
    padding: 2px var(--e2);
    min-height: 22px;
    line-height: 1.5;
}
body .tabulator .tabulator-group:hover { background: var(--realce); }
body .tabulator .tabulator-group.tabulator-group-level-1 { padding-left: 26px; }
body .tabulator .tabulator-group.tabulator-group-level-2 { padding-left: 46px; }
body .tabulator .tabulator-group .tabulator-arrow {
    border-left-color: var(--texto-2);
    border-right-color: transparent;
    margin-right: var(--e2);
}
body .tabulator .tabulator-group.tabulator-group-visible .tabulator-arrow {
    border-top-color: var(--texto-2);
    border-left-color: transparent;
    border-right-color: transparent;
}

/*
 * Una lista corta que no necesita rejilla.
 *
 * La usa la ficha de empresa: son siete filas y dos columnas, de modo que
 * montar una rejilla entera para eso seria absurdo. Toma su forma para que las
 * dos pantallas se parezcan.
 */
table.rejilla-lista { border-collapse: collapse; width: 100%; font-size: var(--txt-s); }
table.rejilla-lista th {
    background: var(--superficie-3); text-align: left; font-weight: 600;
    color: var(--texto-2); padding: 3px var(--e2);
    border-bottom: 1px solid var(--borde); white-space: nowrap;
}
table.rejilla-lista td { padding: 3px var(--e2); border-bottom: 1px solid var(--superficie-2); }
table.rejilla-lista td.num, table.rejilla-lista th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.rejilla-lista tr:hover { background: var(--realce); }
table.rejilla-lista tr.activa { background: var(--realce); box-shadow: inset 3px 0 0 var(--acento); }
table.rejilla-lista tr.activa a { font-weight: 600; }
table.rejilla-lista a { color: inherit; text-decoration: none; display: block; }
table.rejilla-lista a:hover { color: var(--acento); }

/*
 * El desplegable con su buscador al lado.
 *
 * Lo pone `select-buscable.js` alrededor de cada `<select data-buscable>`, de
 * modo que la vista solo marca el campo. Sirve para los catalogos largos: las
 * unidades de medida son 1 093 codigos.
 *
 * El buscador va **detras** del `<select>` en el DOM a proposito: asi
 * `select:disabled ~ .buscador-select` puede esconderlo con la ficha en modo
 * consulta, que es lo unico que CSS sabe hacer —no hay selector de hermano
 * anterior—.
 */
.con-buscador { display: flex; align-items: center; gap: var(--e1); min-width: 0; }
/* `flex-basis: 0` y no `auto`: dentro de una tarjeta el `select` lleva
   `width: 100%` y con la base automatica se comeria el sitio del buscador. */
.con-buscador > select { flex: 1 1 0; min-width: 0; }
/*
 * **La cadena de `:not()`, por tercera vez en este archivo.** La regla base es
 * `input:not([type=checkbox]):not([type=radio]):not([type=file])` y, dentro de
 * una tarjeta, `.tarjeta input:not(...)` suma (0,4,1) con `width: 100%`: sin
 * repetirla, el buscador saldria tan ancho como el desplegable.
 */
.con-buscador input.buscador-select:not([type=checkbox]):not([type=radio]):not([type=file]) {
    flex: 0 0 66px; width: 66px;
    padding: 2px 5px;
    font-size: var(--txt-xs);
}
.con-buscador > select:disabled ~ .buscador-select { display: none; }

/*
 * Un bloque de comandos para copiar.
 *
 * Se desplaza en horizontal por su cuenta —una linea de `systemctl` es larga y
 * partirla convierte un comando en dos que no funcionan— y **conserva los
 * saltos**, que es lo que lo hace pegable.
 */
.bloque-codigo {
    overflow-x: auto;
    background: var(--superficie-2);
    border: 1px solid var(--borde);
    border-radius: 4px;
    padding: 8px 10px;
    margin: 0;
    font-size: 12px;
    line-height: 1.5;
    white-space: pre;
    -moz-tab-size: 4;
    tab-size: 4;
}

.bloque-codigo code { background: none; padding: 0; font-size: inherit; color: inherit; }

/* Los permisos de una cuenta (`usuario-permisos`): cada letra del menú del
   heredado con sus entradas debajo. */
.grupo-permisos { margin-top: var(--e3); }
.titulo-grupo-permisos { display: block; font-weight: 600; }
.entrada-permisos { display: block; margin: var(--e1) 0 0 22px; }

/* El resultado de Contasis en Documentos de venta: una línea, y el detalle
   plegado con tope de alto, para no comerse la rejilla de debajo. */
.contasis-linea { display: flex; align-items: center; gap: var(--e3); }
.contasis-detalle { margin-top: var(--e1); }
.contasis-detalle > summary { cursor: pointer; font-size: var(--txt-s, 13px); }
.contasis-detalle-tabla { max-height: 35vh; overflow: auto; }

/* «Ver como»: los dos desplegables del superusuario en la barra, y la franja
   que recuerda que lo que se hace, se hace como otra cuenta. */
.ver-como select { max-width: 200px; }
.franja-ver-como {
    display: flex; align-items: center; gap: var(--e3); flex-wrap: wrap;
    padding: var(--e1) var(--e3);
    background: var(--aviso-fondo, #fff4d6); color: var(--aviso-texto, #5c4400);
    border-bottom: 1px solid var(--aviso-borde, #e0b84c);
    font-size: 13px;
}
