/* ═══════════════════════════════════════════════════════════════════════════════════════════
   INTEGRIS — LA CAPA COMUN.  «Una sola linea.»

   DE DONDE SALE ESTO
   La mesa de un jefe de operaciones a las siete de la manana, con luz de ventana. Una hoja
   de porcelana fria llena de renglones: quien entra, que se cotizo, que salio del almacen,
   quien firmo. Y un solo sello de tinta carmin en lo unico que hay que firmar hoy.
   De ahi salen las tres cosas de esta paleta: la porcelana (fondo, fria, azulada), la tinta
   de pizarra (texto) y el carmin (el acento, uno solo).

   LAS TRES REGLAS QUE GOBIERNAN TODO LO DEMAS

   1) EL ACENTO ES LA ACCION. El boton principal va carmin macizo, y hay UNO por pantalla.
      Todo lo demas es contorno o tinta. Esto es deliberadamente lo contrario de lo que
      regia antes aqui: no se orienta con color, se orienta con la posicion y el peso, y el
      carmin queda libre para significar «esto es lo que se hace hoy».

   2) NO HAY TARJETAS. La pantalla se compone de BANDAS separadas por reglas de 1px, no de
      cajas flotando sobre un fondo. La elevacion se reserva para lo que flota de verdad:
      un modal, un menu, un aviso. Un panel que no flota no lleva sombra.

   3) DOS VOCES. Manrope dice las palabras; DM Mono dice los datos. Todo lo que se coteja a
      ojo o se compara en columna (DNI, RUC, correlativos, importes, horas, fechas) y todo
      rotulo de seccion van en la monoespaciada. En un sistema donde media pantalla son
      cifras, la mono no es un adorno: es la mitad de la voz.

   COMO SE LEE ESTE FICHERO
   · Aqui arriba, SOLO tokens. Ningun componente.
   · Los colores se declaran ENTEROS en `:root`. Los dos bloques oscuros de mas abajo solo
     cambian el VALOR de esa misma lista: ningun color nace dentro de un `@media` ni dentro
     de un `[data-theme]`. Si naciera ahi, el otro tema se quedaria sin el y aparece el
     texto invisible.
   · Los nombres viejos (`--azul-oscuro`, `--gris-medio`, `--navy`, `--g1`…) SIGUEN
     EXISTIENDO y apuntan a la paleta nueva. Hay cientos de usos repartidos por hojas,
     plantillas y JavaScript: se cambia lo que valen, no como se llaman.

   La paleta se calculo en OKLCH —donde un mismo paso de luminosidad vale igual en cualquier
   tono— y se publica en hex, porque esto se abre tambien desde telefonos de campo viejos.
   Cada color de texto esta medido contra los tres planos en los dos temas: ninguno baja de
   4.5:1, y el minimo legible es la parada 600 de cada rampa.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ─── LAS CARAS ──────────────────────────────────────────────────────────────────────────────
   Manrope para el texto: humanista de eje geometrico, con la x alta, que es lo que sostiene
   la lectura a 13 px en una tabla de cien filas. DM Mono para el dato y para el rotulo.
   Las dos se sirven desde el propio proyecto y no desde Google: en obra no siempre hay red,
   y `font-src 'self'` ya lo permite sin tocar la CSP.

   Manrope es VARIABLE: un solo fichero por subconjunto cubre de 200 a 800. Por eso hay dos
   `@font-face` y no diez; el rango va declarado en `font-weight` para que el navegador
   interpole en vez de fingir la negrita. */
@font-face { font-family: "Manrope"; font-style: normal; font-weight: 200 800; font-display: swap;
    src: url("/static/fonts/manrope-var-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Manrope"; font-style: normal; font-weight: 200 800; font-display: swap;
    src: url("/static/fonts/manrope-var-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 400; font-display: swap;
    src: url("/static/fonts/dmmono-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 400; font-display: swap;
    src: url("/static/fonts/dmmono-400-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 500; font-display: swap;
    src: url("/static/fonts/dmmono-500-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 500; font-display: swap;
    src: url("/static/fonts/dmmono-500-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }

:root {
    color-scheme: light;

    /* ── LOS PLANOS ──────────────────────────────────────────────────────────────────────
       Porcelana fria, sesgada a azul (tono 250 en OKLCH). No es papel: los cinco sistemas
       vecinos de esta casa usan un blanco roto CALIDO, y esto se distingue de todos ellos
       en el primer vistazo justamente por la temperatura. */
    --lienzo:         #EDF0F4;   /* el fondo de la hoja */
    --panel:          #FBFDFE;   /* la superficie donde se escribe */
    --hueco:          #E2E7EC;   /* lo hundido: campos, celdas de cabecera */
    --acero:          #EDF0F4;   /* nombre viejo del lienzo, vivo por compatibilidad */
    --acero-hueco:    #E2E7EC;   /* nombre viejo del hueco */

    /* ── LA TINTA ────────────────────────────────────────────────────────────────────────
       Pizarra fria. Rampa por distancia al fondo. La parada 500 NO es color de texto
       (2.9:1 contra el hueco): es la de los bordes y los iconos. El minimo legible es 600. */
    --n100:           #F5F7F9;
    --n200:           #E4E8ED;
    --n300:           #D0D7DE;
    --n400:           #AAB2BB;
    --n500:           #7E8792;
    --n600:           #5B6672;
    --n700:           #414B5A;
    --n800:           #26303E;
    --n900:           #101827;

    /* ── EL CARMIN ───────────────────────────────────────────────────────────────────────
       El unico acento, y aqui SI tine el boton principal: es la accion. Un solo boton
       carmin macizo por pantalla; en cuanto hay dos, ninguno significa nada. */
    --a100:           #FDEFF7;
    --a200:           #F8D3E9;
    --a300:           #F0A9D5;
    --a400:           #D061AB;
    --a500:           #B3318D;
    --a600:           #951F74;
    --a700:           #77165C;
    --a800:           #551041;
    --a900:           #390A2B;

    /* ── ESTADO ──────────────────────────────────────────────────────────────────────────
       Tonos elegidos LEJOS del carmin en el circulo (28, 152 y 72 contra 342) para que un
       error nunca se confunda con la accion del dia. Los nombres son los del criterio
       comun de la casa, en `~/apps/CRITERIO-DE-INTERFAZ.md`. */
    --peligro:        #A91D1A;
    --peligro-alto:   #860A0B;
    --peligro-piso:   #FFEDEA;
    --peligro-linea:  #FCCCC5;
    --exito:          #216B3C;
    --exito-alto:     #10542B;
    --exito-piso:     #E9F6EC;
    --exito-linea:    #C6E4CC;
    --aviso:          #8C5700;
    --aviso-alto:     #724400;
    --aviso-piso:     #FFEFDC;
    --aviso-linea:    #F8D4A8;

    --sobre-tinta:    #FBFDFE;
    --sobre-acento:   #FBFDFE;
    --sobre-peligro:  #FBFDFE;
    --sobre-exito:    #FBFDFE;
    --sobre-aviso:    #FBFDFE;

    /* ── LA SERIE DE DATOS ───────────────────────────────────────────────────────────────
       Un dato no orienta: informa. El carmin dice «esto es lo que se hace»; si ademas
       tine la barra de un indicador o la ficha de un modulo, deja de decirlo. Por eso los
       quince modulos del portal, los estados del expediente y las series de las graficas
       tienen su propia lista, repartida por el circulo a luminosidad constante.
       Cada uno mide >=4.5:1 contra `--sobre-serie` en los dos temas (el peor, 5.5:1). */
    --serie-1:  #2454B3;
    --serie-2:  #006D92;
    --serie-3:  #00746F;
    --serie-4:  #00714C;
    --serie-5:  #1C6D26;
    --serie-6:  #556300;
    --serie-7:  #725800;
    --serie-8:  #864B00;
    --serie-9:  #9E3000;
    --serie-10: #A12628;
    --serie-11: #9E244F;
    --serie-12: #922A73;
    --serie-13: #7E3593;
    --serie-14: #6441A9;
    --serie-15: #4A4AB2;
    --serie-16: #0061AA;
    --sobre-serie: #FBFDFE;

    /* Los siete papeles con nombre de la serie: lo que significan, no que numero son. */
    --dato-hito:     var(--serie-1);
    --dato-proceso:  var(--serie-16);
    --dato-alta:     var(--serie-13);
    --dato-mal:      var(--serie-10);
    --dato-bien:     var(--serie-5);
    --dato-espera:   var(--serie-8);
    --dato-dinero:   var(--serie-7);
    --dato-neutro:   var(--n600);
    --dato-apagado:  var(--n400);

    /* ── EL VELO Y EL VIDRIO ─────────────────────────────────────────────────────────── */
    --velo:           rgba(16, 24, 39, 0.42);
    --velo-denso:     rgba(16, 24, 39, 0.88);
    --vidrio-1:       rgba(16, 24, 39, 0.035);
    --vidrio-2:       rgba(16, 24, 39, 0.06);
    --vidrio-3:       rgba(16, 24, 39, 0.10);
    --vidrio-4:       rgba(16, 24, 39, 0.16);
    --vidrio-alto:    rgba(251, 253, 254, 0.72);

    /* ── EL INDICE LATERAL ───────────────────────────────────────────────────────────────
       Aqui esta el cambio estructural mas visible: el menu lateral DEJA DE SER una chapa
       oscura. Es la misma porcelana que el resto, separada solo por una regla de 1px, y
       lo que marca donde estas es el peso de la letra y un filo carmin, no un relleno.
       En oscuro si baja a tinta, porque ahi el contraste lo pide. */
    --chapa:          #FBFDFE;
    --chapa-alta:     #E4E8ED;
    --sobre-chapa:    #101827;
    --sobre-chapa-tenue: #5B6672;

    /* ── RELIEVE ─────────────────────────────────────────────────────────────────────────
       Casi nada. Lo que separa una banda de la siguiente es una regla, no una sombra.
       La sombra solo aparece en lo que flota de verdad. */
    --sombra:         0 1px 0 rgba(16, 24, 39, 0.05);
    --sombra-alta:    0 2px 4px rgba(16, 24, 39, 0.06), 0 8px 20px rgba(16, 24, 39, 0.09);
    --sombra-hover:   var(--sombra-alta);
    --sombra-modal:   0 24px 60px rgba(16, 24, 39, 0.24);
    --sombra-hundida: inset 0 1px 2px rgba(16, 24, 39, 0.07);
    --foco:           0 0 0 3px rgba(149, 31, 116, 0.30);
    --foco-peligro:   0 0 0 3px rgba(169, 29, 26, 0.28);
    --borde:          1px solid var(--n300);

    /* Papel y tinta de la zona de firma: no cambian con el tema, una firma es una firma. */
    --papel-firma:    #FFFFFF;
    --tinta-firma:    #101827;

    /* Marcas ajenas, con su color de verdad. */
    --marca-whatsapp:    #1EA362;
    --marca-peru-rojo:   #C8102E;
    --marca-peru-blanco: #FFFFFF;

    /* ── LAS FORMAS ──────────────────────────────────────────────────────────────────────
       Sistema de radios propio: la pastilla completa para lo que se PULSA, el filo casi
       recto para lo que se LEE, y solo lo que flota de verdad se redondea de verdad.
       Un boton con forma de pastilla junto a un campo casi rectangular no es un descuido:
       es como se distingue, de un vistazo y sin color, lo que es accion de lo que es dato. */
    --radio-sm:       4px;    /* etiquetas pequenas, celdas */
    --radio:          6px;    /* campos, paneles, bandas */
    --radio-lg:       12px;   /* lo que flota: modal, menu, aviso */
    --radio-pastilla: 999px;  /* botones, chips, contadores */

    /* ── LA ESCALA TIPOGRAFICA ───────────────────────────────────────────────────────────
       Razon ~1.22. El cuerpo baja a 14.5 px y las tablas a 12.5: es un sistema de
       inventario y planilla, no un articulo, y la densidad es una prestacion.
       La jerarquia la hace el PESO (500/600/700/800), no el tamano. */
    --t-xs:   0.72rem;   /* 10.8px — rotulo mono en versalitas */
    --t-sm:   0.833rem;  /* 12.5px — tabla, pie, ayuda */
    --t-base: 0.967rem;  /* 14.5px — cuerpo */
    --t-md:   1.067rem;  /* 16px   — h3 */
    --t-lg:   1.267rem;  /* 19px   — h2 */
    --t-xl:   1.6rem;    /* 24px   — h1 */
    --t-2xl:  2rem;      /* 30px   — la cifra que manda en la pantalla */

    --sans: "Manrope", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", sans-serif;
    --mono: "DM Mono", ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;
    --font: var(--sans);

    /* ── EL RITMO ────────────────────────────────────────────────────────────────────────
       Base 4. La banda respira (24-32) aunque la fila apriete (6-10): esa diferencia entre
       el aire de fuera y el de dentro es lo que hace legible una pantalla densa. */
    --e1: 4px;  --e2: 8px;  --e3: 12px; --e4: 16px; --e5: 20px;
    --e6: 24px; --e8: 32px; --e10: 40px;
    --sal: var(--e4);

    --transition: 160ms cubic-bezier(0.23, 1, 0.32, 1);
    --t-rapida:   110ms cubic-bezier(0.23, 1, 0.32, 1);

    /* ── LOS NOMBRES DE SIEMPRE ──────────────────────────────────────────────────────────
       Cientos de usos repartidos por hojas, plantillas y JavaScript siguen pidiendo estos
       nombres. Se les cambia lo que valen, no como se llaman. */
    --azul-oscuro:   var(--n900);
    --azul-medio:    var(--a600);
    --azul-claro:    var(--a200);
    --azul-hover:    var(--a700);
    --verde:         var(--exito);
    --verde-claro:   var(--exito-piso);
    --rojo:          var(--peligro);
    --rojo-claro:    var(--peligro-piso);
    --naranja:       var(--aviso);
    --naranja-claro: var(--aviso-piso);
    --gris-oscuro:   var(--n800);
    --gris-medio:    var(--n600);
    --gris-claro:    var(--lienzo);
    --gris-borde:    var(--n300);
    --blanco:        var(--panel);
    --navy:          var(--n900);
    --azul:          var(--a600);
    --azul2:         var(--a500);
    --blue:          var(--serie-1);
    --green:         var(--exito);
    --red:           var(--peligro);
    --amber:         var(--aviso);
    --gris:          var(--n600);
    --g1:            var(--n100);
    --g2:            var(--n200);
    --g3:            var(--n300);
    --scale-factor:  1;
}

/* ─── EL TEMA OSCURO, EN SUS DOS ESTADOS ─────────────────────────────────────────────────────
   1) El de abajo: lo que el sistema operativo pide, salvo que el usuario haya elegido claro
      a mano (de ahi el `:not([data-theme="light"])`).
   2) Mas abajo: la eleccion explicita, que gana en las dos direcciones.
   Los dos cuerpos son IDENTICOS y salen del mismo sitio.

   No es el claro dado la vuelta. Es la misma mesa a las once de la noche: la porcelana se
   apaga hasta pizarra, la tinta se vuelve luz, y el carmin sube de luminosidad (de #951F74
   a #E98FC8) porque en su tono de dia sobre negro no se lee. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --lienzo:         #13171E;
        --panel:          #1F242B;
        --hueco:          #0C1015;
        --acero:          #13171E;
        --acero-hueco:    #0C1015;

        --n100:           #1A1E25;
        --n200:           #292E36;
        --n300:           #393F48;
        --n400:           #545B66;
        --n500:           #78818E;
        --n600:           #9BA4B0;
        --n700:           #B7BEC8;
        --n800:           #D4D9E1;
        --n900:           #EEF2F7;

        --a100:           #2D1D27;
        --a200:           #47263B;
        --a300:           #74315E;
        --a400:           #AE498E;
        --a500:           #D56FB2;
        --a600:           #E98FC8;
        --a700:           #F6B2DC;
        --a800:           #FDD1EB;
        --a900:           #FFE9F6;

        --peligro:        #F0736A;
        --peligro-alto:   #FA958C;
        --peligro-piso:   #331714;
        --peligro-linea:  #5E2621;
        --exito:          #66BC7E;
        --exito-alto:     #8BD09B;
        --exito-piso:     #11291A;
        --exito-linea:    #1D482C;
        --aviso:          #E2A94F;
        --aviso-alto:     #F2C179;
        --aviso-piso:     #2E2210;
        --aviso-linea:    #543C11;

        --sobre-tinta:    #0C1015;
        --sobre-acento:   #0C1015;
        --sobre-peligro:  #0C1015;
        --sobre-exito:    #0C1015;
        --sobre-aviso:    #0C1015;

        --serie-1:  #74A7FF;
        --serie-2:  #00BFE4;
        --serie-3:  #00C6BE;
        --serie-4:  #3EC399;
        --serie-5:  #72BF75;
        --serie-6:  #A2B44D;
        --serie-7:  #C3A839;
        --serie-8:  #DB9B40;
        --serie-9:  #F58753;
        --serie-10: #F98078;
        --serie-11: #F67D9C;
        --serie-12: #E880C4;
        --serie-13: #D089E6;
        --serie-14: #B194FD;
        --serie-15: #949EFF;
        --serie-16: #37B4FD;
        --sobre-serie: #0C1015;

        --velo:           rgba(4, 6, 10, 0.66);
        --velo-denso:     rgba(4, 6, 10, 0.93);
        --vidrio-1:       rgba(238, 242, 247, 0.04);
        --vidrio-2:       rgba(238, 242, 247, 0.07);
        --vidrio-3:       rgba(238, 242, 247, 0.11);
        --vidrio-4:       rgba(238, 242, 247, 0.17);
        --vidrio-alto:    rgba(31, 36, 43, 0.78);

        --chapa:          #0C1015;
        --chapa-alta:     #292E36;
        --sobre-chapa:    #EEF2F7;
        --sobre-chapa-tenue: #9BA4B0;

        --sombra:         0 1px 0 rgba(0, 0, 0, 0.45);
        --sombra-alta:    0 2px 4px rgba(0, 0, 0, 0.42), 0 8px 20px rgba(0, 0, 0, 0.44);
        --sombra-hover:   var(--sombra-alta);
        --sombra-modal:   0 24px 60px rgba(0, 0, 0, 0.62);
        --sombra-hundida: inset 0 1px 2px rgba(0, 0, 0, 0.5);
        --foco:           0 0 0 3px rgba(233, 143, 200, 0.34);
        --foco-peligro:   0 0 0 3px rgba(240, 115, 106, 0.30);

        --gris-claro:     var(--lienzo);
        --blanco:         var(--panel);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --lienzo:         #13171E;
    --panel:          #1F242B;
    --hueco:          #0C1015;
    --acero:          #13171E;
    --acero-hueco:    #0C1015;

    --n100:           #1A1E25;
    --n200:           #292E36;
    --n300:           #393F48;
    --n400:           #545B66;
    --n500:           #78818E;
    --n600:           #9BA4B0;
    --n700:           #B7BEC8;
    --n800:           #D4D9E1;
    --n900:           #EEF2F7;

    --a100:           #2D1D27;
    --a200:           #47263B;
    --a300:           #74315E;
    --a400:           #AE498E;
    --a500:           #D56FB2;
    --a600:           #E98FC8;
    --a700:           #F6B2DC;
    --a800:           #FDD1EB;
    --a900:           #FFE9F6;

    --peligro:        #F0736A;
    --peligro-alto:   #FA958C;
    --peligro-piso:   #331714;
    --peligro-linea:  #5E2621;
    --exito:          #66BC7E;
    --exito-alto:     #8BD09B;
    --exito-piso:     #11291A;
    --exito-linea:    #1D482C;
    --aviso:          #E2A94F;
    --aviso-alto:     #F2C179;
    --aviso-piso:     #2E2210;
    --aviso-linea:    #543C11;

    --sobre-tinta:    #0C1015;
    --sobre-acento:   #0C1015;
    --sobre-peligro:  #0C1015;
    --sobre-exito:    #0C1015;
    --sobre-aviso:    #0C1015;

    --serie-1:  #74A7FF;
    --serie-2:  #00BFE4;
    --serie-3:  #00C6BE;
    --serie-4:  #3EC399;
    --serie-5:  #72BF75;
    --serie-6:  #A2B44D;
    --serie-7:  #C3A839;
    --serie-8:  #DB9B40;
    --serie-9:  #F58753;
    --serie-10: #F98078;
    --serie-11: #F67D9C;
    --serie-12: #E880C4;
    --serie-13: #D089E6;
    --serie-14: #B194FD;
    --serie-15: #949EFF;
    --serie-16: #37B4FD;
    --sobre-serie: #0C1015;

    --velo:           rgba(4, 6, 10, 0.66);
    --velo-denso:     rgba(4, 6, 10, 0.93);
    --vidrio-1:       rgba(238, 242, 247, 0.04);
    --vidrio-2:       rgba(238, 242, 247, 0.07);
    --vidrio-3:       rgba(238, 242, 247, 0.11);
    --vidrio-4:       rgba(238, 242, 247, 0.17);
    --vidrio-alto:    rgba(31, 36, 43, 0.78);

    --chapa:          #0C1015;
    --chapa-alta:     #292E36;
    --sobre-chapa:    #EEF2F7;
    --sobre-chapa-tenue: #9BA4B0;

    --sombra:         0 1px 0 rgba(0, 0, 0, 0.45);
    --sombra-alta:    0 2px 4px rgba(0, 0, 0, 0.42), 0 8px 20px rgba(0, 0, 0, 0.44);
    --sombra-hover:   var(--sombra-alta);
    --sombra-modal:   0 24px 60px rgba(0, 0, 0, 0.62);
    --sombra-hundida: inset 0 1px 2px rgba(0, 0, 0, 0.5);
    --foco:           0 0 0 3px rgba(233, 143, 200, 0.34);
    --foco-peligro:   0 0 0 3px rgba(240, 115, 106, 0.30);

    --gris-claro:     var(--lienzo);
    --blanco:         var(--panel);
}

:root[data-theme="light"] { color-scheme: light; }

/* ─── EL SUELO ───────────────────────────────────────────────────────────────────────────────
   Nada de aqui coloca nada: solo fija como se comporta el texto y la superficie. */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
    /* 15px, no 16. Es la palanca que sostiene las mas de mil medidas heredadas en rem:
       cambiarla reescala el sistema entero, asi que la densidad se ajusta en los tokens
       de tamano y de ritmo, no aqui. */
    font-size: 15px;
    -webkit-text-size-adjust: 100%;
}

body {
    font-family: var(--sans);
    font-size: var(--t-base);
    color: var(--n800);
    background: var(--lienzo);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Manrope trae cifras proporcionales de serie y en una tabla eso baila. Aqui van
       tabulares para TODO el sistema: importes, DNI, horas y cantidades quedan en columna. */
    font-variant-numeric: tabular-nums;
}

/* ─── TIPOGRAFIA ─────────────────────────────────────────────────────────────────────────────
   La jerarquia se hace con PESO antes que con tamano: 800 para el titulo de pantalla, 700
   para el de banda, 600 para lo que solo destaca. Los titulos van apretados de interlinea
   (1.15) y de letra (-0.02em); el cuerpo, suelto. */
h1, h2, h3, h4, h5 {
    color: var(--n900);
    line-height: 1.15;
    text-wrap: balance;
}
h1 { font-size: var(--t-xl); font-weight: 800; letter-spacing: -0.025em; }
h2 { font-size: var(--t-lg); font-weight: 700; letter-spacing: -0.019em; }
h3 { font-size: var(--t-md); font-weight: 700; letter-spacing: -0.014em; }
h4, h5 { font-size: var(--t-base); font-weight: 600; letter-spacing: -0.008em; }
p { text-wrap: pretty; }

a { color: var(--a600); text-decoration: none; }
a:hover { color: var(--a700); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }

/* La segunda voz. Todo lo que se COTEJA a ojo (un DNI, un RUC, un correlativo, una placa,
   un importe) va aqui. Es donde un cero y una o se confunden. */
.mono, .dni, .ruc, .codigo, code, kbd, samp {
    font-family: var(--mono);
    font-size: 0.92em;   /* DM Mono pinta grande al lado de Manrope */
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}

/* El rotulo: la pieza que mas se repite en el sistema y la que mas lo identifica.
   Mono, versalitas, muy separada, en tinta media. Sustituye al titulillo en negrita. */
.rotulo, .titulo-seccion {
    font-family: var(--mono);
    font-size: var(--t-xs);
    font-weight: 500;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: var(--n600);
}

/* ─── EL FOCO, UNA SOLA VEZ Y PARA TODO ──────────────────────────────────────────────────────
   Quien navega con teclado NUNCA ve el `:hover`. El anillo es el mismo en todo el sistema. */
:focus-visible {
    outline: 2px solid var(--a600);
    outline-offset: 2px;
    border-radius: var(--radio-sm);
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--a200); color: var(--n900); }

/* La barra de scroll, del color de la hoja y no del sistema operativo: en oscuro una barra
   blanca de fabrica es lo primero que delata un tema a medias. */
* { scrollbar-color: var(--n400) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--n400); border-radius: 99px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--n500); background-clip: content-box; }

/* ─── QUIEN PIDE MENOS MOVIMIENTO, RECIBE MENOS ──────────────────────────────────────────────
   No se apaga del todo: una transicion de color ayuda a entender que algo cambio. Lo que
   se apaga es lo que se DESPLAZA, que es lo que marea. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}


/* ─── LA MARCA EN LOS DOS TEMAS ──────────────────────────────────────────────────────────────
   El logotipo es un PNG con fondo TRANSPARENTE, no una teja: en oscuro, una teja de porcelana
   se ve como una pegatina pegada encima. Y como la tinta de las letras no puede seguir a la
   rampa (es un mapa de bits), hay dos ficheros y el tema elige. El `.jpg` se queda intacto
   para el PDF y el correo, donde no hay tema que valga. */
.sidebar-logo, .header-logo, .logo-img { background: transparent; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .sidebar-logo,
    :root:not([data-theme="light"]) .header-logo,
    :root:not([data-theme="light"]) .logo-img { content: url("/static/img/logo_integris_oscuro.png"); }
}
:root[data-theme="dark"] .sidebar-logo,
:root[data-theme="dark"] .header-logo,
:root[data-theme="dark"] .logo-img { content: url("/static/img/logo_integris_oscuro.png"); }

/* ─── LAYOUT APP ─────────────────────────────────────────────── */
.app-body { display: flex; min-height: 100vh; }

/* ─── SIDEBAR ────────────────────────────────────────────────── */
.sidebar {
    /* Mas estrecha que antes (240 -> 216): el indice es una lista de lectura, no un panel.
       El sitio que se le quita se lo queda la tabla, que es donde esta el trabajo. */
    width: 216px;
    min-height: 100vh;
    background: var(--chapa);
    color: var(--sobre-chapa);
    border-right: 1px solid var(--n300);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0; left: 0;
    z-index: 200;
    transition: width var(--transition), transform var(--transition);
}
.sidebar.collapsed { width: 60px; }
.sidebar.collapsed .sidebar-header span,
.sidebar.collapsed .nav-item span,
.sidebar.collapsed .sidebar-sistema { display: none; }

.sidebar-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: var(--e5) var(--e5) var(--e4);
    border-bottom: 1px solid var(--n200);
}
.sidebar-logo { width: 36px; height: 36px; object-fit: contain; border-radius: 4px;
    background: var(--panel); }   /* el respaldo del logotipo: es un JPG con fondo blanco,
       asi que la cama tiene que ser blanca tambien en oscuro o se ve el recorte. */
.sidebar-sistema {
    font-family: var(--mono);
    font-size: var(--t-xs);
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--n600);
    white-space: nowrap;
    overflow: hidden;
}

.sidebar-nav { flex: 1; padding: var(--e4) 0; overflow-y: auto; }
.nav-item {
    /* El indice es TIPOGRAFICO: lo que dice donde estas es el peso de la letra y un filo
       carmin de 2px, no una pastilla de color ni un relleno. El filo va de 2px a proposito;
       una barra gruesa de color al costado de una lista es decoracion, no informacion. */
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 7px 16px 7px 18px;
    font-size: var(--t-sm);
    font-weight: 500;
    color: var(--n600);
    cursor: pointer;
    transition: color var(--t-rapida), border-color var(--t-rapida);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    border-left: 2px solid transparent;
    /* Y01-D — `overflow:hidden` + `nowrap` cortaba la etiqueta larga SIN AVISO: en Logística ›
       «Requerimientos por cotizar» el ítem ACTIVO (que además pasa a font-weight:700 y gana ancho)
       perdía los últimos 6 px y no había forma de leer el texto completo. Con los puntos suspensivos
       el usuario ve que hay más, y el `min-width:0` deja que la etiqueta encoja de verdad dentro del flex. */
    text-overflow: ellipsis;
}
.nav-item > span, .nav-item .nav-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
.nav-item:hover { color: var(--n900); border-left-color: var(--n300); }
.nav-item.active { color: var(--a600); font-weight: 700; border-left-color: var(--a600); }
.nav-item i { width: 15px; text-align: center; flex-shrink: 0; font-size: 0.86em; color: var(--n500); }
.nav-item.active i { color: var(--a600); }
.nav-item:hover i { color: var(--n700); }

/* El bloque que forzaba TODO el texto del indice a blanco con `!important` se retira: existia
   porque la barra era una chapa oscura en los dos temas. Ahora la barra es la misma porcelana
   que la hoja, asi que el texto hereda la tinta y el tema oscuro se encarga solo. Dejar aquel
   `color: ... !important` habria pintado el indice de blanco sobre blanco. */
.sidebar .nav-item svg { fill: currentColor; }

/* El rotulo que agrupa el indice: mono, versalitas, y una regla por encima. Sustituye a la
   division por color de fondo, que es lo que hacia que esto pareciera un menu y no un indice. */
.sidebar .nav-grupo {
    font-family: var(--mono);
    font-size: var(--t-xs);
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--n500);
    padding: var(--e5) 18px var(--e2);
    margin-top: var(--e2);
    border-top: 1px solid var(--n200);
}
.sidebar .nav-grupo:first-child { border-top: none; margin-top: 0; padding-top: var(--e1); }

.sidebar-footer { border-top: 1px solid var(--n200); padding: var(--e3) 0; }

/* ─── MAIN ────────────────────────────────────────────────────── */
.app-main {
    flex: 1;
    min-width: 0;   /* A07 (corrida S) — permite que el flex item ENCOJA bajo el min-content de su
                       contenido (los flex items son min-width:auto por defecto); sin esto, un elemento
                       ancho —p. ej. una grilla en Logística— empujaba .app-main más allá del viewport y
                       causaba scroll horizontal de PÁGINA a 1280px. Las tablas ya scrollean DENTRO de su
                       .table-responsive, así que esto no las afecta. */
    margin-left: 216px;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    transition: margin-left var(--transition);
}
.app-main.expanded { margin-left: 60px; }

/* ─── TOPBAR ─────────────────────────────────────────────────── */
.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;   /* V6: título a la izq, grupo derecho al extremo */
    gap: var(--e4);
    padding: 0 var(--e6);
    height: 52px;
    background: var(--panel);
    border-bottom: 1px solid var(--n300);
    position: sticky;
    top: 0;
    z-index: 100;
    pointer-events: auto;
}
.btn-sidebar-toggle {
    background: none;
    border: none;
    font-size: 1.2rem;
    color: var(--n700);
    cursor: pointer;
    padding: 4px 8px;
    border-radius: var(--radio-sm);
}
.btn-sidebar-toggle:hover { background: var(--n200); }
.topbar-title { font-weight: 700; color: var(--n900); font-size: var(--t-md); letter-spacing: -0.016em; flex: 1; }
/* V6 (P1): el grupo derecho (usuario + rol + campana) SIEMPRE pegado a la derecha */
.topbar-right { display: flex; align-items: center; gap: 12px; margin-left: auto; flex-shrink: 0; }
.btn-notif, .notif-btn, .campana, button.bell, .topbar-right [id*="otif"] { flex-shrink: 0; }
/* V8 FIX 1: la campana SIEMPRE es el último elemento del topbar (orden flex) */
.btn-notif, .notif-btn, .notif-wrapper, .bell-btn, button.campana { order: 999 !important; flex-shrink: 0 !important; }
/* V95 — íconos de la barra superior: "← volver al portal" y "⎋ salir". Clase compartida por todos los
   módulos; visibles también en móvil (van fuera de .user-info-desktop); target táctil ≥40px. */
.topbar-icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
    min-width: 40px; min-height: 40px; padding: 0; border: none; background: none; border-radius: 8px;
    color: var(--n700); cursor: pointer; text-decoration: none; font-size: 1.15rem; line-height: 1;
    flex-shrink: 0; -webkit-tap-highlight-color: transparent; }
.topbar-icon-btn:hover { background: var(--n200); }
.topbar-icon-btn:active { background: var(--n300); }
.topbar-icon-btn.salir { color: var(--peligro); }
.topbar-icon-btn.salir:hover { background: var(--peligro-piso); }
/* A-2.1 — chip de identidad (Nombre Apellido · Cargo) en el topbar de todas las pantallas */
.topbar-ident { display: inline-flex; flex-direction: column; line-height: 1.15; min-width: 0;
    max-width: 46vw; overflow: hidden; }
.topbar-ident .tb-nom { font-size: var(--t-sm); font-weight: 700; color: var(--n900);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-ident .tb-car { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--n600); white-space: nowrap; overflow: hidden;
    text-overflow: ellipsis; }
@media (max-width: 480px){ .topbar-ident { max-width: 40vw; } .topbar-ident .tb-car { font-size: .66rem; } }
.user-info { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; color: var(--gris-medio); }

/* ─── CONTENT AREA ───────────────────────────────────────────── */
.content-area { flex: 1; padding: var(--e6); }
.content-section { display: none; }
.content-section.active { display: block; }

/* ─── CARDS ──────────────────────────────────────────────────── */
/* La BANDA. Ya no es una tarjeta flotando sobre un fondo: es una franja de hoja con una
   regla arriba y otra abajo. Sin sombra a proposito (un panel que no flota no proyecta) y
   con mas aire alrededor, porque lo que separa una banda de la siguiente es el hueco y la
   regla, no el relieve. La sombra queda reservada para lo que si flota: modal, menu, aviso. */
.card {
    background: var(--panel);
    border: 1px solid var(--n300);
    border-radius: var(--radio);
    box-shadow: none;
    margin-bottom: var(--e6);
    overflow: hidden;
}
.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--e4) var(--e5) var(--e3);
    background: transparent;
    color: var(--n900);
    border-bottom: 1px solid var(--n200);
    font-weight: 700;
    font-size: var(--t-base);
    letter-spacing: -0.014em;
    gap: var(--e3);
}
/* El rotulo de la tarjeta ya no es una banda oscura, asi que lo que va dentro tampoco
   puede seguir pintandose de blanco «porque el fondo era oscuro». */
.card-header h1, .card-header h2, .card-header h3, .card-header h4 { color: inherit; }
.card-header .btn-icon { color: var(--n600); }
.card-body { padding: var(--e5); }


/* El icono que a veces acompana a un titulo de banda o de pantalla: separado de la
   palabra y en tinta de borde, para que se lea como una marca al margen y no como parte
   del texto. Iba pegado a la primera letra. */
.section-title > i:first-child,
.subsection-title > i:first-child,
.card-header > i:first-child { margin-right: 0.5em; color: var(--n500); font-size: 0.82em; }

/* ─── LA BANDA DE CIFRAS ─────────────────────────────────────────────────────────────────────
   Es la pieza que abre casi todas las pantallas del sistema, y era el mosaico de cuatro
   tarjetas con un filo de color de 4 px arriba: cuatro cajas iguales, cada una con su sombra
   y su barra de color, que competian entre si y con el titulo. Aqui es UNA sola banda partida
   por reglas verticales de 1 px. La cifra manda (peso 800, tabular), el rotulo va debajo en
   mono, y el color de estado tine LA CIFRA -que es lo que significa algo- y nunca un filo
   decorativo. Sin sombra: no flota.

   Cualquier modulo puede usarla: <div class="cifras"><div class="cifra-celda">
   <span class="cifra-num">12</span><span class="cifra-lbl">Personal activo</span></div>…
   Y las clases viejas por modulo (.kpi-card, .pendiente-card…) se le enganchan encima. */
.cifras {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    background: var(--panel);
    border: 1px solid var(--n300);
    border-radius: var(--radio);
    margin-bottom: var(--e6);
    overflow: hidden;
}
.cifra-celda {
    padding: var(--e4) var(--e5);
    border-left: 1px solid var(--n200);
    display: flex;
    flex-direction: column;
    gap: var(--e1);
    min-width: 0;
}
.cifra-celda:first-child { border-left: none; }
.cifra-num {
    font-size: var(--t-2xl);
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 1;
    color: var(--n900);
    font-variant-numeric: tabular-nums;
}
.cifra-lbl {
    font-family: var(--mono);
    font-size: var(--t-xs);
    font-weight: 500;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--n600);
}
.cifra-pie { font-size: var(--t-xs); color: var(--n600); }
/* El estado tine la CIFRA, no un filo. */
.cifra-celda.mal    .cifra-num { color: var(--peligro); }
.cifra-celda.aviso  .cifra-num { color: var(--aviso); }
.cifra-celda.bien   .cifra-num { color: var(--exito); }
.cifra-celda.dinero .cifra-num { color: var(--n900); }
@media (max-width: 700px) {
    .cifras { grid-template-columns: 1fr 1fr; }
    .cifra-celda:nth-child(odd) { border-left: none; }
    .cifra-celda:nth-child(n+3) { border-top: 1px solid var(--n200); }
}

/* ─── EL PARRAFO DE ENTRADA ──────────────────────────────────────────────────────────────────
   La frase que explica de que va la pantalla. No es un aviso: no lleva caja ni color. Se
   distingue por medida corta y por la tinta, como en cualquier documento bien puesto. */
.entradilla {
    max-width: 68ch;
    color: var(--n700);
    font-size: var(--t-base);
    line-height: 1.55;
    margin-bottom: var(--e6);
    text-wrap: pretty;
}

/* ─── SECTION HEADERS ────────────────────────────────────────── */
/* El titulo de pantalla lleva una REGLA DOBLE debajo: gruesa en tinta, fina en gris. Es la
   marca de cabecera de documento del sistema, y lo unico que se repite en las quince
   pantallas para decir «aqui empieza». */
.section-title {
    font-size: var(--t-xl);
    font-weight: 800;
    letter-spacing: -0.025em;
    margin-bottom: var(--e5);
    padding-bottom: var(--e3);
    border-bottom: 2px solid var(--n900);
    box-shadow: 0 3px 0 -2px var(--n300);
}
.section-header { display: flex; align-items: center; justify-content: space-between; gap: var(--e4); margin-bottom: var(--e6); flex-wrap: wrap; }
.subsection-title {
    font-family: var(--mono);
    font-size: var(--t-xs);
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    margin: var(--e8) 0 var(--e3);
    padding-bottom: var(--e2);
    border-bottom: 1px solid var(--n200);
    color: var(--n600);
}

/* ─── TABLAS ─────────────────────────────────────────────────── */
.table-responsive { 
    overflow-x: auto; 
    -webkit-overflow-scrolling: touch; 
    display: block;
    width: 100%;
}
/* Suelo para CUALQUIER tabla del sistema, tenga clase o no. `.tabla` lo refina más abajo. */
table th, table td { padding: 10px 14px; }
/* excepción: las tablas que se usan para MAQUETAR (celdas de una sola línea dentro de un aviso o
   de una ficha) no quieren ese aire; se marcan y se respetan. */
table.sin-aire th, table.sin-aire td, .sin-aire table th, .sin-aire table td { padding: 2px 4px; }

.tabla {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--t-sm);
    min-width: 500px;
}
/* ══ EL AIRE DE LA CELDA — 24-ago ═══════════════════════════════════════════════════════════
   el auditor: «el texto de las celdas empieza justo en el borde, sin aire», visto en Administrador ›
   SharePoint, «y es el mismo problema de los botones aplicado a las tablas». Estaba en 9/12; se
   sube a 11/16, que es el mismo aire lateral que tiene un botón (16). Una tabla densa se lee
   mejor con margen que con filas pegadas.
   ⚠️ Y LA REGLA BASE DE MÁS ABAJO cubre las tablas que NO usan `.tabla` —`sk-table`, `rq-table`,
   `items-table`, `inf-t`, `cx-tabla`, `cfg-table` y la que va sin clase—: 24 tablas del sistema
   que se pintaban con el relleno POR DEFECTO DEL NAVEGADOR, que es 1 px. Ese es el «texto contra
   el borde» de verdad. */
.tabla th {
    /* La cabecera ya no es una banda de color: es un rotulo mono en versalitas colgado de
       una regla en tinta. Es la misma pieza que titula las bandas y los campos, y es lo que
       hace que una tabla de este sistema se reconozca a distancia. */
    background: transparent;
    color: var(--n600);
    padding: var(--e2) var(--e4) 7px;
    text-align: left;
    font-family: var(--mono);
    font-weight: 500;
    font-size: var(--t-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    border-bottom: 1.5px solid var(--n800);
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    position: sticky;   /* la cabecera se queda al desplazar una tabla larga */
    top: 0;
    z-index: 1;
}
.tabla th:hover { color: var(--n900); }
.tabla td { padding: 8px var(--e4); border-bottom: 1px solid var(--n200); vertical-align: middle; color: var(--n800); }
/* Se retira el rayado de cebra: con el aire de celda que ya tiene la tabla, la banda
   alterna solo mete ruido, y en oscuro se convierte en un damero. La fila se distingue
   por su linea y, cuando importa, por el paso del raton. */
.tabla tr:hover td { background: var(--a100); transition: background var(--t-rapida); }
/* La primera columna es casi siempre el identificador. Va en mono y en tinta plena: es lo
   que el usuario busca con el dedo cuando recorre cien filas. Una tabla que no empiece por
   un identificador se marca con `.sin-clave` y vuelve a la sans. */
.tabla td:first-child { font-family: var(--mono); font-size: 0.94em; color: var(--n900); letter-spacing: -0.02em; }
/* …salvo la fila que ocupa toda la tabla, que NO es un identificador sino una frase:
   «Sin cotizaciones registradas» salia en monoespaciada, como si fuera un codigo. */
.tabla td[colspan]:first-child { font-family: var(--sans); font-size: inherit; letter-spacing: normal; color: var(--n600); }
.tabla.sin-clave td:first-child { font-family: var(--sans); font-size: inherit; letter-spacing: 0; }
.tabla tr:last-child td { border-bottom: none; }
.table-toolbar { display: flex; gap: 10px; margin-bottom: 14px; align-items: center; flex-wrap: wrap; }

/* ─── ESTÁNDAR VISUAL P01 — contenedor de tabla con bordes redondeados ────────── */
/* Envuelve una <table class="tabla"> para que la cabecera navy respete el radio.  */
.tabla-card {
    border: 1px solid var(--n300);
    border-radius: var(--radio);
    overflow: hidden;               /* recorta las esquinas de la cabecera */
    background: var(--panel);
    box-shadow: none;
    padding: 0 var(--e2) var(--e2);
}
.tabla-card > .table-responsive,
.tabla-card > .tabla { border-radius: inherit; }
.tabla-card .tabla { min-width: 0; }
.tabla-card .tabla th { border-bottom: none; }
/* Celdas numéricas: a la derecha con cifras tabulares (nada de números pegados). */
.tabla td.num, .tabla th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabla td.center, .tabla th.center { text-align: center; }
/* Celda vacía: guion medio gris y centrado (nunca vacío ni "null"). */
.celda-vacia { color: var(--n500); }
.tabla td .celda-vacia { display: inline-block; }
/* Nombre largo truncado con tooltip (usar junto a title="…"). */
.txt-trunc { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
/* Lista vertical de personas dentro de una celda (nunca muro de texto corrido). */
.lista-personas { margin: 0; padding-left: 16px; }
.lista-personas li { line-height: 1.4; }
/* Estado vacío de tabla: mensaje centrado, no cabecera sola. */
.tabla-vacia { text-align: center; color: var(--n600); padding: var(--e8) var(--e3); }

/* ── PUNTO 8 · EX TRABAJADOR (personal.activo=FALSE) ────────────────────────────
   El nombre se muestra IGUAL que el de un activo; sólo se le añade este chip GRIS
   (neutro: no es un error ni una alerta). Lo emite window.integrisNombrePersona(). */
.chip-baja {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 8px;
    border-radius: 20px;
    background: var(--n200);
    color: var(--n700);
    border: 1px solid var(--n300);
    font-size: 0.70rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    vertical-align: middle;
}
/* La fila de un ex trabajador se atenúa un punto, sin perder legibilidad. */
.tabla tr.fila-baja td { color: var(--n600); }

/* ─── FORMULARIOS ────────────────────────────────────────────── */
.form-group { margin-bottom: var(--e5); }
/* La etiqueta del campo es la MISMA pieza que el rotulo de la tabla y el de la banda: mono,
   versalitas, tinta media. Un sistema se reconoce por repetir una pieza, no por tener muchas. */
.form-group label {
    display: block;
    font-family: var(--mono);
    font-weight: 500;
    font-size: var(--t-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin-bottom: 6px;
    color: var(--n600);
}
.form-control {
    width: 100%;
    padding: 8px 11px;
    border: 1px solid var(--n400);
    border-radius: var(--radio);
    font-family: var(--sans);
    font-size: var(--t-base);
    color: var(--n900);
    background: var(--panel);
    transition: border-color var(--t-rapida), box-shadow var(--t-rapida);
}
/* 16px de fuente en el movil: por debajo de eso Safari hace zoom al enfocar el campo y
   descoloca la pantalla entera. En escritorio se queda en el cuerpo normal. */
@media (max-width: 768px) { .form-control { font-size: 16px; } }
.form-control:focus {
    outline: none;
    border-color: var(--a600);
    box-shadow: var(--foco);
}
/* El marcador de posicion tambien tiene que llegar a 4.5:1. El `var(--n600)` de antes daba 2.3:1
   sobre blanco: se leia como un campo deshabilitado, no como una pista. */
.form-control::placeholder { color: var(--n600); opacity: 1; }
.form-control:disabled, .form-control[readonly] {
    background: var(--acero-hueco); color: var(--n600); cursor: not-allowed;
}
/* Un campo en error se marca por BORDE, no tinendo el texto de rojo: el rojo del texto se
   confunde con el propio dato cuando el dato es una cifra. */
.form-control.error, .form-control[aria-invalid="true"] {
    border-color: var(--peligro);
    box-shadow: 0 0 0 3px var(--peligro-linea);
}
select.form-control { appearance: none; padding-right: 30px;
    background-image: linear-gradient(45deg, transparent 50%, var(--n600) 50%),
                      linear-gradient(135deg, var(--n600) 50%, transparent 50%);
    background-position: calc(100% - 16px) 51%, calc(100% - 11px) 51%;
    background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.form-group-check { display: flex; align-items: center; }
.req { color: var(--rojo); }
.input-row { display: flex; gap: 10px; align-items: center; }
.input-group { display: flex; }
.input-group .form-control { border-radius: var(--radio-sm) 0 0 var(--radio-sm); }
.input-group .btn-toggle-pin {
    padding: 9px 12px;
    border: 1px solid var(--gris-borde);
    border-left: none;
    border-radius: 0 var(--radio-sm) var(--radio-sm) 0;
    background: var(--n200);
    cursor: pointer;
    color: var(--n600);
}

/* ─── EL OJO DEL PIN, DENTRO DEL CAMPO ────────────────────────────────────────────────────────
   Se caía a una línea nueva y era lo PRIMERO que veía todo el mundo al entrar.
   La causa, medida en el navegador: `.form-group > .input-group` lleva `flex-wrap: wrap` (línea
   ~508). El campo es `width:100%`, ocupa el ancho entero de la fila, y el botón de 40 px no cabe
   detrás: al haber `wrap`, salta abajo. El CSS de arriba (botón PEGADO al lado, estilo «grupo de
   entrada») nunca podía funcionar dentro de un contenedor que envuelve.
   Se resuelve sacando el botón del flujo: el ojo va DENTRO del campo, en absoluta.
   ⚠️ Clase propia (.input-clave) a propósito: `.input-group` es genérica y la usan otras
   pantallas: cambiar su comportamiento aquí las movería a todas sin querer. */
.input-group.input-clave {
    position: relative;               /* el marco contra el que se posiciona el ojo */
    display: block;                   /* fuera del flex: ya no hay nada que envolver */
}
.input-group.input-clave .form-control {
    width: 100%;
    padding-right: 42px;              /* el hueco del ojo: el PIN no se le monta encima */
    border-radius: var(--radio-sm);   /* vuelve a ser un campo entero, no medio grupo */
}
.input-group.input-clave .btn-toggle-pin {
    position: absolute;
    top: 50%;
    right: 1px;                       /* 1px = respeta el borde del campo */
    transform: translateY(-50%);      /* centrado vertical REAL, sea cual sea el alto */
    height: calc(100% - 2px);
    width: 40px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;                     /* dentro del campo no pinta un segundo marco */
    border-radius: 0 var(--radio-sm) var(--radio-sm) 0;
    background: transparent;
    color: var(--gris-medio);
    cursor: pointer;
    z-index: 2;                       /* por encima del campo, para que reciba el clic */
}
.input-group.input-clave .btn-toggle-pin:hover { color: var(--azul-medio); }
.input-group.input-clave .btn-toggle-pin:focus-visible {
    outline: 2px solid var(--azul-medio);
    outline-offset: -2px;
}

/* ─── CHECKBOXES ─────────────────────────────────────────────── */
.checkbox-label { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.9rem; }
.checkbox-label input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--a600); }
input[type="radio"], input[type="range"] { accent-color: var(--a600); }

/* ─── BOTONES ────────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 16px;
    border: none;
    /* LOTE M · 8 — 8 px, no 4. El estándar de los botones estaba en `--radio-sm`, que es el radio
       de los CAMPOS DE TEXTO: 4 px se lee como una esquina recta, y eso es lo que el auditor venía
       viendo. Se cambia AQUÍ, en la definición del botón, y no con una regla al final del fichero:
       intentarlo por abajo obliga a pelear con la especificidad de admin.css y responsive.css, que
       cargan después. Se cambia donde se declara y se acabó la discusión. */
    /* PASTILLA COMPLETA. Es la decision de forma que mas distingue a este sistema: lo que
       se PULSA es redondo del todo, lo que se LEE es casi recto (6 px). Puesto uno al lado
       del otro, un boton y un campo ya no se parecen, y eso se nota antes que el color. */
    border-radius: var(--radio-pastilla);
    font-family: var(--font);
    font-size: var(--t-sm);
    font-weight: 700;
    cursor: pointer;
    transition: background var(--t-rapida), border-color var(--t-rapida),
                color var(--t-rapida), transform var(--t-rapida);
    text-decoration: none;
    white-space: nowrap;
    letter-spacing: 0;
}
/* Un boton apagado se apaga con COLOR, no con opacidad. Con `opacity` el grafito
   quedaba en 3.62:1 contra su propia letra —y el primero que ve cualquiera es el
   «Ingresar» del acceso, apagado hasta que se teclea el DNI— y ademas se difuminaba
   el anillo de foco, que es justo lo que nunca debe perderse. */
.btn:disabled, .cd-btn:disabled {
    background: var(--n200);
    color: var(--n700);
    border-color: var(--n300);
    box-shadow: none;
    cursor: not-allowed;
}
.btn:disabled:active, .cd-btn:disabled:active { transform: none; }
/* EL ACENTO ES LA ACCION. El boton principal va carmin macizo. La regla que lo acompana no
   esta escrita en CSS y hay que sostenerla al montar cada pantalla: UN solo `.btn-primary`
   por pantalla. En cuanto hay dos, ninguno de los dos significa nada. */
.btn-primary { background: var(--a600); color: var(--sobre-acento); }
.btn-primary:hover:not(:disabled) { background: var(--a700); }
.btn-secondary { background: transparent; color: var(--n800); border: 1px solid var(--n400); }
.btn-secondary:hover:not(:disabled) { background: var(--n100); border-color: var(--n600); color: var(--n900); }
.btn-danger { background: var(--peligro); color: var(--sobre-peligro); }
.btn-danger:hover:not(:disabled) { background: var(--peligro-alto); }
/* `.btn-success` NO es un segundo boton principal. Decia «Guardar» en verde
   mientras `.btn-primary` decia «Guardar» en grafito: dos primarios en la misma
   pantalla y ninguno de los dos significando nada. El de guardar es el grafito.
   La clase se queda viva —la nombran 24 sitios— apuntando a la misma receta. */
.btn-success { background: var(--a600); color: var(--sobre-acento); }
.btn-success:hover:not(:disabled) { background: var(--a700); }
.btn-outline { background: transparent; color: var(--a600); border: 1px solid var(--a400); }
.btn-outline:hover:not(:disabled) { background: var(--a100); border-color: var(--a600); }
.btn-text { background: none; border: none; color: var(--a600); cursor: pointer; font-size: var(--t-sm); }
.btn-text:hover { text-decoration: underline; text-underline-offset: 2px; }
.btn-icon { background: none; border: none; cursor: pointer; color: var(--n600); font-size: 1rem; padding: 6px; border-radius: var(--radio-pastilla); }
.btn-icon:hover { color: var(--n900); background: var(--n200); }
/* Un boton que se pulsa tiene que ACUSAR el golpe. 0.97 es suficiente: se nota con el dedo
   y no llama la atencion a la quincuagesima vez. Solo transform, que no repinta nada. */
.btn:active:not(:disabled), .cd-btn:active:not(:disabled) { transform: scale(0.97); }
.btn-block { width: 100%; justify-content: center; }
/* ══ LA RECETA DEL BOTÓN PEQUEÑO — 24-ago-2026 ═══════════════════════════════════════════════
   ⚠️ AQUÍ ESTABA EL BOTÓN APRETADO DE TODO EL SISTEMA. Medido con el navegador, no leído: de los
   1.106 botones visibles del sistema, **635 llevaban `.btn-sm`** y todos salían con
   `padding: 5px 10px`. el auditor: «el texto está pegado al borde, el botón le aprieta al texto y se
   ve minúsculo y descuidado», y «en la misma pantalla hay botones que están bien» — los que usan
   `.btn` a secas, que es 9px 16px. O sea: el sistema ya sabía hacerlo bien, y esta línea era la
   que lo hacía mal, en un solo sitio, 635 veces.

   EL CRITERIO, que es el que pidió: no que todos midan igual, sino que **la proporción sea la
   misma**. `.btn` es 9/16 (ratio 1:1,8). El pequeño mantiene ese ratio a escala 0,8: **7/14**.
   Es un 40 % más de aire que antes y sigue leyéndose como el hermano pequeño de `.btn`, no como
   otro botón de otro sistema.

   Y `min-height`: había botones de 21 px de alto. Con 30 el dedo lo encuentra y el ojo lo lee. */
.btn-sm {
    padding: 7px 14px;
    font-size: 0.8rem;
    min-height: 30px;
    gap: 5px;
}

/* El botón NORMAL tiene su suelo también: un `.btn` con solo un icono dentro se quedaba en 28 px.
   No cambia el aire —9/16 es el que el auditor dio por bueno—, solo pone el mínimo. */
.btn { min-height: 36px; }

/* ⚠️ Y LAS EXCEPCIONES QUE PISABAN LA RECETA, TRAÍDAS AQUÍ. Cada pantalla que quería sus botones
   de acciones más compactos se escribía su propio `padding` en su `<style>`, y volvíamos a tener
   el criterio decidido en varios sitios. Se declara UNA vez, para las tablas de acciones de
   cualquier módulo, y con aire: 6/10 y 34 px de alto es compacto SIN apretar. */
/* Los botones de una columna de acciones son PEQUEÑOS, no APRETADOS: se les da la receta del
   `.btn-sm` (7/14) y un cuadrado mínimo de 34 px para los que solo llevan icono. Puse 6/10 en el
   primer intento y al medirlo seguían saliendo con 10 px de aire lateral — que es justo el número
   del que se queja el auditor. La proporción manda sobre el ahorro de píxeles. */
.tabla td.acciones .btn,
.tabla td.td-acciones .btn,
td.acciones .btn,
td.td-acciones .btn {
    padding: 7px 14px;
    min-width: 34px;
    min-height: 34px;
    gap: 5px;
}
/* y si el botón SOLO lleva un icono, no necesita el aire lateral del texto: se cuadra */
.tabla td.acciones .btn.solo-icono,
td.acciones .btn.solo-icono { padding: 7px; }

/* ══ `.cd-btn` — LA MISMA RECETA QUE `.btn`, Y AQUÍ PARA QUE LA VEAN LOS QUINCE MÓDULOS ══════
   Vivía en `coordinador.css` y la usan tres JS de OTROS módulos (`flujo_hoja`, `gastos_fijos`,
   `casos_gestion`). Donde no se carga ese fichero, el botón salía sin ningún estilo.
   Se le da el mismo aire que `.btn` —9/16— para que no haya dos criterios: un botón es un botón,
   se llame como se llame. */
.cd-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    padding: 9px 16px;
    min-height: 36px;
    border: none;
    border-radius: var(--radio-pastilla);
    font-family: var(--font);
    font-size: var(--t-sm);
    font-weight: 700;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--transition), box-shadow var(--transition), opacity var(--transition);
}
.cd-btn.primary { background: var(--a600);   color: var(--sobre-acento); }
.cd-btn.verde   { background: var(--exito);  color: var(--sobre-exito); }
.cd-btn.rojo    { background: var(--peligro); color: var(--sobre-peligro); }
.cd-btn.gris    { background: transparent; color: var(--n800); border: 1px solid var(--n400); }
.cd-btn.grande  { width: 100%; padding: 13px 18px; font-size: 1rem; min-height: 46px; }
.cd-btn.sm      { padding: 7px 14px; font-size: 0.8rem; min-height: 30px; }
.cd-btn:disabled { opacity: .6; cursor: not-allowed; }

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   LA RECETA GANA AL `style=` EN LÍNEA — 24-ago-2026
   ══════════════════════════════════════════════════════════════════════════════════════════════
   ⚠️ HAY 82 BOTONES CON EL RELLENO ESCRITO A MANO en su etiqueta, con doce valores distintos:
   `padding:5px 10px`, `2px 8px`, `4px 8px`, `8px 6px`… Un estilo en línea gana a cualquier hoja
   de estilos, así que la receta única no les llegaba: por eso seguían saliendo apretados después
   de arreglar `.btn-sm`.
   el auditor: «si lo arreglas botón por botón, en un mes estamos igual». Tocar 82 etiquetas es
   exactamente eso, y además no impide el número 83. Se hace al contrario: la CLASE manda, y lo
   escrito a mano en la etiqueta deja de decidir el aire de un botón.
   Se fuerza SOLO el relleno. Todo lo demás que traiga el `style=` —color de fondo, margen,
   anchura, opacidad— se respeta tal cual: hay 301 botones que llevan ahí su color y no se toca
   ninguno.
   Si algún día un botón necesita de verdad otro relleno, se le pone una CLASE, no un `style=`. */
.btn[style], a.btn[style], button.btn[style] { padding: 9px 16px !important; }
.btn.btn-sm[style], a.btn.btn-sm[style], button.btn.btn-sm[style] { padding: 7px 14px !important; }
.cd-btn[style], button.cd-btn[style], a.cd-btn[style] { padding: 9px 16px !important; }
.cd-btn.sm[style], button.cd-btn.sm[style] { padding: 7px 14px !important; }
.cd-btn.grande[style], button.cd-btn.grande[style] { padding: 13px 18px !important; }
/* la columna de acciones conserva su medida compacta, también contra el `style=` */
.tabla td.acciones .btn[style], td.acciones .btn[style],
.tabla td.td-acciones .btn[style], td.td-acciones .btn[style] { padding: 7px 14px !important; }
/* los `.btn-icon` y los botones que solo llevan un icono no quieren aire lateral: se cuadran */
.btn-icon[style] { padding: 6px !important; }

/* ══ LOS AVISOS DE VALIDACIÓN NUNCA QUITAN SITIO A OTRO CAMPO — 24-ago ══════════════════════
   el auditor lo vio en el teléfono del portal: el aviso se añadía DENTRO de la fila flex del campo
   —[selector de país][número]— y al ser un tercer elemento flex **comprimía el selector** hasta
   dejarlo ilegible. No lo tapaba: le quitaba el sitio.
   Esta regla vale para cualquier aviso que caiga dentro de una fila: se lleva el ancho completo y
   baja a su propia línea. Si el contenedor no permite envolver, se le dice que envuelva. */
.aviso-bajo-campo, .aviso-campo, .campo-aviso, small.error-campo {
    display: block;
    flex: 1 0 100%;
    width: 100%;
    order: 99;
    margin-top: 4px;
    color: var(--rojo);
    font-size: 0.78rem;
    line-height: 1.35;
    overflow-wrap: anywhere;
}
/* que la fila del campo pueda envolver: sin esto el aviso a 100 % desborda en vez de bajar */
.perfil-input-group > div, .form-group > .input-group, .campo-fila { flex-wrap: wrap; }

/* ══ EL SITIO PARA FIRMAR — UN SOLO CRITERIO, 24-ago ════════════════════════════════════════
   el auditor: «el recuadro es diminuto; desde el ordenador, con ratón, no se puede firmar bien: sale
   un garabato. Ya lo comenté en su día y sigue igual.»
   Medidos los cinco sitios donde se firma en el sistema, y no había criterio ninguno:
     · SSOMA · entrega de EPP          420 × **150**   ← el más pequeño de todos
     · Visita Técnica · conformidad    100 % × **170**
     · Portal · mi firma digital       508 × 300
     · Portal · ausencias              460 × 340
   Una firma con ratón necesita recorrido: en 150 px de alto no cabe un trazo, cabe un garabato.
   Se pone un SUELO para todos —220 px, y 280 en pantalla ancha— y se les da el ancho de su caja.
   No se igualan a la fuerza: el que ya tenía 340 se queda con 340; lo que se sube es el suelo. */
canvas[id*="irma" i], canvas[class*="irma" i], canvas.vt-sign, canvas[id*="ign" i] {
    width: 100%;
    min-height: 220px;
    box-sizing: border-box;
    cursor: crosshair;
    touch-action: none;                 /* con el dedo se firma, no se hace scroll */
}
@media (min-width: 900px) {
    canvas[id*="irma" i], canvas[class*="irma" i], canvas.vt-sign, canvas[id*="ign" i] {
        min-height: 280px;
    }
}

/* ══ SUGERENCIAS DE DIRECCIÓN — legibles y elegibles, 24-ago ════════════════════════════════
   el auditor: «las sugerencias salen por debajo, en una lista que no se lee bien, y no se pueden
   elegir con comodidad: hay que apuntar con el ratón y cuesta». Eran renglones de 9 px de aire.
   Ahora: 12/14 de relleno, la parte principal en negrita y el detalle debajo en gris, y la fila
   marcada se ve —con el ratón por encima o con las flechas—. */
.dir-sug {
    padding: 12px 14px;
    cursor: pointer;
    border-bottom: 1px solid var(--n100);
    font-size: 0.9rem;
    line-height: 1.35;
}
.dir-sug:last-child { border-bottom: none; }
.dir-sug:hover, .dir-sug.sel { background: var(--azul-claro); }
.dir-sug.sel { box-shadow: inset 3px 0 0 var(--azul-medio); }

/* ══ LAS CLASES DE BOTÓN DEL PORTAL, QUE NO TENÍAN DUEÑO — 24-ago ══════════════════════════
   ⚠️ ES EL BOTÓN QUE PRUEBA7 SEÑALÓ PRIMERO: «Asistencia · Mi perfil → + Agregar teléfono
   adicional». Su clase es `btn-tel-extra`, y **no estaba definida en ningún fichero del
   sistema** — ni en el portal, ni en main.css, ni en ninguna hoja de módulo. Igual que
   `cd-btn`: se renderizaba como un `<button>` desnudo, con el texto contra el borde.
   Lo mismo `btn-tel-quitar` y `btn-lic-pdf`.
   ⚠️ Y SE ME HABÍAN ESCAPADO AL BARRER, por un fallo mío: el censo abría las secciones
   pinchando los enlaces del menú lateral, y el portal del trabajador no tiene ese menú. Salió
   con «0 secciones» y lo di por medido. Un barrido que no llega a una pantalla no la ha barrido:
   solo no la ha visto. */
.btn-tel-extra, .btn-lic-pdf {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    padding: 9px 16px;
    min-height: 36px;
    border: 1px solid var(--azul-medio);
    border-radius: var(--radio);
    background: var(--panel);
    color: var(--azul-medio);
    font-family: var(--font);
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
}
.btn-tel-extra:hover, .btn-lic-pdf:hover { background: var(--azul-claro); }
/* el de quitar es un icono: cuadrado, sin aire lateral de texto, pero con tamaño para el dedo */
.btn-tel-quitar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; min-width: 36px;
    padding: 0;
    border: none;
    border-radius: var(--radio);
    background: var(--peligro);
    color: var(--sobre-peligro);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
}
.btn-tel-quitar:hover { background: var(--peligro-alto); }

/* ─── BADGES Y ESTADOS ───────────────────────────────────────── */
/* La insignia es la tercera aparicion de la mono: estado en versalitas dentro de una
   pastilla. Sin relleno de color solido, solo el piso lavado y su linea. */
.badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    border-radius: var(--radio-pastilla);
    font-family: var(--mono);
    font-size: var(--t-xs);
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    line-height: 1.6;
}
.badge { border: 1px solid transparent; }
.badge-success { background: var(--exito-piso);   color: var(--exito-alto);   border-color: var(--exito-linea); }
.badge-danger  { background: var(--peligro-piso); color: var(--peligro-alto); border-color: var(--peligro-linea); }
.badge-warning { background: var(--aviso-piso);   color: var(--aviso-alto);   border-color: var(--aviso-linea); }
.badge-info    { background: var(--a100);         color: var(--a700);         border-color: var(--a300); }
.badge-gris    { background: var(--n200);         color: var(--n700);         border-color: var(--n300); }

/* ─── ALERTS ─────────────────────────────────────────────────── */
.alert {
    padding: var(--e3) var(--e4);
    border-radius: var(--radio);
    font-size: var(--t-sm);
    margin-bottom: var(--e4);
    display: flex;
    align-items: flex-start;
    gap: var(--e2);
}
.alert-error   { background: var(--peligro-piso); color: var(--peligro-alto); border: 1px solid var(--peligro-linea); }
.alert-success { background: var(--exito-piso);   color: var(--exito-alto);   border: 1px solid var(--exito-linea); }
.alert-warning { background: var(--aviso-piso);   color: var(--aviso-alto);   border: 1px solid var(--aviso-linea); }
.alert-info    { background: var(--a100);         color: var(--a700);         border: 1px solid var(--a300); }

/* ─── MODALES ────────────────────────────────────────────────── */
.modal {
    display: none;        /* Oculto por defecto — NO usar display:flex aquí */
    position: fixed;
    inset: 0;
    z-index: 1000;
    align-items: center;
    justify-content: center;
}
.modal.modal-open {
    display: flex;        /* Solo visible cuando JS agrega esta clase */
}
.modal-backdrop { position: absolute; inset: 0; background: var(--velo); backdrop-filter: blur(1.5px); }
.modal-dialog {
    position: relative;
    background: var(--panel);
    border: 1px solid var(--n300);
    border-radius: var(--radio-lg);
    box-shadow: var(--sombra-modal);
    width: 90%;
    max-width: 520px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    animation: modalIn 0.2s ease;
}
.modal-lg { max-width: 800px; }
@keyframes modalIn { from { opacity:0; transform:scale(0.97) translateY(6px); } to { opacity:1; transform:none; } }
.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--e5) var(--e6) var(--e4);
    border-bottom: 1px solid var(--n200);
    background: transparent;
    color: var(--n900);
    border-radius: var(--radio-lg) var(--radio-lg) 0 0;
}
.modal-header h3 { color: var(--n900); font-size: var(--t-md); font-weight: 700; letter-spacing: -0.016em; }
.modal-body { padding: var(--e5) var(--e6); overflow-y: auto; flex: 1; }
.modal-footer { display: flex; justify-content: flex-end; gap: var(--e3); padding: var(--e4) var(--e6) var(--e5);
    border-top: 1px solid var(--n200); background: transparent;
    border-radius: 0 0 var(--radio-lg) var(--radio-lg); }

/* ─── NOTIFICACIONES ─────────────────────────────────────────── */
.btn-notif { position: relative; background: none; border: none; cursor: pointer; padding: 6px; font-size: 1.1rem; color: var(--n600); border-radius: var(--radio-pastilla); }
.btn-notif:hover { color: var(--n900); background: var(--n200); }
.notif-badge {
    position: absolute;
    top: 0; right: 0;
    background: var(--peligro);
    color: var(--sobre-peligro);
    border-radius: 50%;
    width: 18px; height: 18px;
    font-size: 0.7rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
}
.notif-panel {
    position: fixed;
    top: 52px; right: 0;
    width: 360px;
    max-height: calc(100vh - 52px);
    background: var(--panel);
    border-left: 1px solid var(--n300);
    border-bottom: 1px solid var(--n300);
    border-radius: 0 0 0 var(--radio-lg);
    box-shadow: var(--sombra-alta);
    z-index: 500;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.notif-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: var(--e4) var(--e5);
    background: transparent;
    color: var(--n900);
    border-bottom: 1px solid var(--n200);
    font-weight: 700;
}
.notif-header .btn-text { color: var(--a600); }
.notif-header .btn-icon { color: var(--n600); margin-left: auto; }
.notif-list { flex: 1; overflow-y: auto; }
.notif-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 499;
    pointer-events: none;   /* Nunca bloquea eventos cuando está oculto */
}
.notif-overlay.visible {
    display: block;
    pointer-events: auto;
}
.notif-item {
    display: flex;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--gris-borde);
    cursor: pointer;
    transition: background var(--transition);
}
.notif-item:hover { background: var(--gris-claro); }
.notif-item.leida { opacity: 0.6; }
.notif-tipo { font-size: 1.1rem; margin-top: 2px; }
.tipo-urgente .notif-tipo { color: var(--rojo); }
.tipo-pendiente .notif-tipo { color: var(--naranja); }
.tipo-info .notif-tipo { color: var(--dato-proceso); }
.notif-content strong { display: block; font-size: 0.85rem; }
.notif-content p { font-size: 0.8rem; color: var(--gris-medio); margin: 2px 0; }
.notif-content small { font-size: 0.75rem; color: var(--n600); }
.notif-empty { padding: 24px; text-align: center; color: var(--gris-medio); }

/* ─── TOAST ──────────────────────────────────────────────────── */
.toast-container { position: fixed; bottom: 20px; right: 20px; z-index: 2000; display: flex; flex-direction: column; gap: 10px; }
.toast {
    background: var(--blanco);
    border-radius: var(--radio);
    box-shadow: var(--sombra-hover);
    padding: 12px 18px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.875rem;
    border-left: 4px solid var(--n500);
    min-width: 280px;
    animation: slideIn 0.3s ease;
}
.toast.success { border-left-color: var(--exito); }
.toast.error   { border-left-color: var(--peligro); }
.toast.warning { border-color: var(--naranja); }
@keyframes slideIn { from { opacity:0; transform:translateX(100%); } to { opacity:1; transform:translateX(0); } }

/* ─── AC01 · EL AVISO TIENE QUE VERSE, ESTÉ DONDE ESTÉ ────────────────────────────────────────
   Dos defectos medidos, los dos reportados como «el aviso sale recortado y tapado por el modal»:

   1) TAPADO. Cada plantilla monta su propio `#toastContainer` con el z-index en línea: 4000 en las
      nueve de arriba-derecha (Coordinador, RR.HH., SSOMA, Contabilidad, Gerente, Visitas, Supervisor,
      Técnicos, Requerimientos), 6000 en Evidencias, 2000 vía `.toast-container` en Admin y Logística.
      Los modales del sistema llegan a 9500-12000, así que el aviso se pintaba DEBAJO del velo.
   2) RECORTADO DE VERDAD. Medido a 1366 px: el aviso ocupaba de 1350 a 1661 en una pantalla de 1366
      — 295 px fuera. El contenedor en línea lleva `right:16px` pero sin ancho ni tope, y `.toast`
      tiene `min-width:280px`: el contenido desborda por la derecha en vez de crecer hacia la izquierda.

   Se corrige aquí, en la hoja compartida, y NO se unifican los cuatro sistemas de aviso (arriba y
   abajo conviven a propósito: es un lote aparte). Hace falta `!important` porque los estilos en línea
   de las plantillas ganan al CSS externo.
   Va por ENCIMA del calendario (12901) para que un error de fecha se lea con el calendario abierto. */
#toastContainer, .toast-container {
    z-index: 13000 !important;
    max-width: calc(100vw - 32px) !important;
    width: max-content !important;
    box-sizing: border-box !important;
    /* ══ LOTE U · L-09 — EL AVISO Y EL BOTÓN FLOTANTE VIVÍAN EN LA MISMA ESQUINA ═══════════
       Medido a 1366×768: el aviso ocupaba de Y=567 a 609 y el botón flotante de Y=561 a 609.
       Se pisaban exactamente. El aviso queda POR ENCIMA (z-index 13000 contra 500), así que lo
       que se perdía era la parte del texto que el botón tapaba — justo el final, que es donde
       dice qué hacer. Se sube el aviso por encima del botón (48 px de alto + su hueco). El
       recorte por el borde derecho ya se había arreglado antes y sigue bien (R=1346 de 1366). */
    bottom: 84px !important;
}
#toastContainer .toast, .toast-container .toast,
#toastContainer > div, .toast-container > div {
    max-width: 100% !important;
    min-width: 0 !important;
    box-sizing: border-box !important;
    overflow-wrap: anywhere;
}

/* AC01 — `.campo-invalido` la pone el componente de fecha/hora desde Z01-b, pero su CSS estaba
   definido en UN SOLO archivo de todo el repo (templates/onboarding/formulario.html): en las otras
   14 pantallas la clase se ponía y NO pintaba nada, así que un campo mal escrito se veía igual que
   uno correcto. Se trae a la hoja compartida. Rojo de la paleta oficial. */
.campo-invalido {
    border-color: var(--peligro) !important;
    box-shadow:var(--foco-peligro);
}

/* ─── PAGINACION ─────────────────────────────────────────────── */
.pagination { display: flex; gap: 4px; margin-top: 14px; justify-content: center; align-items: center; }
.pagination button {
    padding: 6px 12px;
    border: 1px solid var(--gris-borde);
    background: var(--blanco);
    cursor: pointer;
    border-radius: var(--radio);
    font-size: 0.85rem;
    transition: background var(--transition);
}
.pagination button.active { background: var(--a600); color: var(--sobre-acento); border-color: var(--a600); }
.pagination button:hover:not(.active) { background: var(--a100); }

/* ─── GRIDS ──────────────────────────────────────────────────── */
.row-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.row-3col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; }

/* ─── UTILIDADES ─────────────────────────────────────────────── */
.mt-3 { margin-top: 12px; }
.mt-4 { margin-top: 20px; }
.mb-4 { margin-bottom: 20px; }
.text-center { text-align: center; }
.text-right  { text-align: right; }
.text-muted  { color: var(--gris-medio); }
.font-bold   { font-weight: 700; }
.loading-inline { display: flex; align-items: center; justify-content: center; padding: 30px; gap: 10px; color: var(--gris-medio); }

/* ─── SEARCH INPUT ───────────────────────────────────────────── */
.search-input { max-width: 300px; }

/* ─── FILTROS ────────────────────────────────────────────────── */
.filters-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* ─── CONFIRMACION ───────────────────────────────────────────── */
.confirm-modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 2000;
    align-items: center;
    justify-content: center;
}
.confirm-modal.modal-open {
    display: flex;
}
.confirm-box {
    background: var(--panel);
    border-radius: var(--radio);
    padding: 28px;
    max-width: 400px;
    width: 90%;
    box-shadow:var(--sombra-alta);
    text-align: center;
}
.confirm-box h3 { margin-bottom: 12px; }
.confirm-box p { color: var(--gris-medio); margin-bottom: 20px; }
.confirm-btns { display: flex; gap: 10px; justify-content: center; }

/* ─── RESPONSIVE ─────────────────────────────────────────────── */
@media (max-width: 768px) {
    .sidebar {
        transform: translateX(-100%);
        width: 240px !important;
        pointer-events: none;  /* No bloquea cuando está fuera de pantalla */
    }
    .sidebar.open {
        transform: translateX(0);
        pointer-events: auto;  /* Solo activo cuando está abierto */
    }
    .app-main { margin-left: 0 !important; }
    .form-row { grid-template-columns: 1fr; }
    .row-2col, .row-3col { grid-template-columns: 1fr; }
    .notif-panel { width: 100%; }
    .search-input { max-width: 100%; }
    .tabla { font-size: 0.8rem; }
    .tabla td, .tabla th { padding: 7px 8px; }
}

@media (max-width: 480px) {
    .content-area { padding: 14px; }
    .card-body { padding: 14px; }
    .btn { padding: 8px 12px; font-size: 0.82rem; }
    /* Asegurar inputs legibles en móvil */
    .form-control {
        background-color: var(--panel) !important;
        color: var(--n800) !important;
        font-size: 16px;
        padding: 12px;
    }
    .form-control::placeholder { color: var(--n600); }
}

/* ═══ FIXES ADICIONALES ══════════════════════════════════════════ */

/* Error 10: topbar móvil — ocultar nombre, mostrar solo badge */
.user-info-desktop {
    display: flex;
    align-items: center;
    gap: 8px;
}
.role-badge {
    background: var(--n200);
    color: var(--n700);
    border: 1px solid var(--n300);
    padding: 3px 10px;
    border-radius: 20px;
    font-size: 0.78rem;
    font-weight: 700;
    white-space: nowrap;
}

/* Error 9: columnas ocultas en móvil/tablet */
@media (max-width: 600px) {
    .col-hide-sm { display: none !important; }
    .user-info-desktop { display: none; }
    .filters-row { flex-direction: column; align-items: stretch; }
    .filters-row .form-control { max-width: 100% !important; }
    .btn-label { display: none; }
    .input-row { flex-direction: column; }
    .input-row .form-control { width: 100%; }
}
@media (max-width: 900px) {
    .col-hide-md { display: none !important; }
    .user-info-desktop { display: none; }
}

/* Sidebar overlay para móvil — definido abajo en los fixes */

/* Modal XL para permisos */
.modal-xl { max-width: 960px; }

/* Acordeón de permisos por sistema */
.permiso-sistema {
    border: 1px solid var(--gris-borde);
    border-radius: var(--radio);
    margin-bottom: 10px;
    overflow: hidden;
}
.permiso-sistema-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    background: var(--n100);
    color: var(--n900);
    border-bottom: 1px solid var(--n300);
    cursor: pointer;
    user-select: none;
    gap: 12px;
}
.permiso-sistema-header:hover { background: var(--n200); }
.permiso-sistema-header .ps-titulo { font-weight: 700; font-size: 0.95rem; display: flex; align-items: center; gap: 10px; }
.permiso-sistema-header .ps-toggle { transition: transform 0.2s; }
.permiso-sistema-header.open .ps-toggle { transform: rotate(180deg); }
.permiso-sistema-body { display: none; padding: 0; }
.permiso-sistema-body.open { display: block; }
.permiso-sistema-body table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.permiso-sistema-body th {
    background: var(--gris-claro);
    color: var(--azul-oscuro);
    padding: 8px 12px;
    text-align: center;
    font-weight: 700;
    border-bottom: 2px solid var(--azul-claro);
}
.permiso-sistema-body th:first-child { text-align: left; }
.permiso-sistema-body td { padding: 8px 12px; border-bottom: 1px solid var(--gris-borde); text-align: center; vertical-align: middle; }
.permiso-sistema-body td:first-child { text-align: left; color: var(--gris-oscuro); }
.permiso-sistema-body tr:last-child td { border-bottom: none; }
.permiso-sistema-body tr:nth-child(even) td { background: var(--gris-claro); }
.permiso-sistema-body tr:hover td { background: var(--azul-claro); }
.permiso-sistema-body input[type=checkbox] { width: 17px; height: 17px; accent-color: var(--azul-medio); cursor: pointer; }

/* Seleccionar todo por sistema */
.ps-acciones { display: flex; gap: 8px; align-items: center; }
.ps-check-all { font-size: 0.78rem; color: var(--a600); cursor: pointer; text-decoration: underline; }
.ps-check-all:hover { color: var(--a700); }


/* ─── SHOW/HIDE helpers ─────────────────────────────────── */
.hide-on-mobile  { display: block; }
.show-on-mobile  { display: none;  }

@media (max-width: 600px) {
    .hide-on-mobile { display: none !important; }
    .show-on-mobile { display: block !important; }
}

/* ─── Sistemas en tarjetas ───────────────────────────────── */
.sistemas-cards-mobile { display: flex; flex-direction: column; gap: 20px; }
.sistema-card-mobile {
    background: var(--panel);
    border: 1px solid var(--n300);
    border-radius: var(--radio);
    padding: 18px;
    box-shadow:var(--sombra-alta);
    /* BUG 1: separación visible entre tarjetas aunque el contenedor pierda el
       display:flex (gap) por estilos inline; el margen siempre aplica. */
    margin-bottom: 16px;
}
.sistema-card-mobile:last-child { margin-bottom: 0; }
.sistema-card-mobile.inactivo { border-left-color: var(--naranja); }
.scm-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.scm-nombre { font-weight: 700; font-size: 0.98rem; color: var(--azul-oscuro); display: flex; align-items: center; gap: 8px; }
.scm-input { width: 100%; margin-bottom: 12px; }
.scm-btns  { display: flex; gap: 8px; }
/* ⚠️ 24-ago · ESTABA EN `8px 6px`: 6 px de aire lateral, la mitad de lo que ya se veía mal.
   Estos botones reparten el ancho a partes iguales (`flex:1`), así que no hacía falta apretarlos:
   con `padding` lateral generoso el botón crece a lo ancho igual, y el texto respira. */
.scm-btns .btn { flex: 1; justify-content: center; font-size: 0.82rem; padding: 8px 14px; }

/* ─── Overlay del sidebar — creado/eliminado del DOM por JS, nunca queda "fantasma" ─── */
.sidebar-overlay-active {
    position: fixed;
    inset: 0;
    background: var(--velo);
    z-index: 199;
    cursor: pointer;
}

/* ═══════════════════════════════════════════════════════════════
   RESPONSIVE MEJORADO — USUARIOS, BACKUPS, LOGS
   ══════════════════════════════════════════════════════════════ */

/* Botones de acción en fila */
.acciones {
    display: flex;
    gap: 4px;
    align-items: center;
    flex-wrap: nowrap;
}

/* Tabla: siempre scrolleable horizontalmente */
.table-responsive {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    display: block;
    width: 100%;
}
.tabla { min-width: 500px; }

/* ── MÓVIL PEQUEÑO (< 600px) ─────────────────────────────────── */
@media (max-width: 600px) {
    /* Tabla: sin min-width para que entre */
    .tabla { min-width: 0 !important; font-size: 0.78rem; width: 100%; }
    .tabla td, .tabla th { padding: 6px 6px; }

    /* Ocultar columnas secundarias */
    .col-hide-sm { display: none !important; }
    .col-hide-md { display: none !important; }
    .col-backup-archivo { display: none !important; }
    .col-backup-extra { display: none !important; }

    /* Botones acciones: solo icono, muy compactos */
    .acciones { gap: 3px; }
    .acciones .btn {
        padding: 5px 6px !important;
        font-size: 0.72rem !important;
        min-width: 30px;
    }
    .acciones .btn i { font-size: 0.72rem; }

    /* Badges compactos */
    .badge { font-size: 0.65rem !important; padding: 3px 6px !important; }

    /* Card sin padding para que la tabla aproveche todo el espacio */
    .card-body { padding: 0 !important; }
    .table-responsive { border-radius: 0; }

    /* Buscador: ancho completo */
    .search-input { max-width: 100% !important; width: 100% !important; }
    .table-toolbar { padding: 10px 10px 0; }

    /* Sección header: en columna */
    .section-header {
        flex-direction: column !important;
        align-items: stretch !important;
        gap: 10px;
        padding: 0 0 10px;
    }
    .section-header .btn { width: 100%; justify-content: center; }

    /* Notificaciones panel: ancho completo */
    .notif-panel {
        width: 100vw !important;
        right: 0 !important;
        left: 0 !important;
        border-radius: 0 !important;
    }

    /* Filters row en columna */
    .filters-row {
        flex-direction: column !important;
        gap: 8px !important;
        padding: 10px !important;
    }
    .filters-row .form-control,
    .filters-row .btn { width: 100% !important; max-width: 100% !important; }
}

/* ── TABLET (600px - 768px) ──────────────────────────────────── */
@media (min-width: 601px) and (max-width: 768px) {
    .tabla { font-size: 0.82rem; }
    .tabla td, .tabla th { padding: 7px 8px; }
    .col-hide-md { display: none !important; }
    .col-backup-extra { display: none !important; }
    .acciones .btn { padding: 5px 8px; font-size: 0.78rem; }

    /* Modal: ancho completo */
    .modal-xl { max-width: 96% !important; margin: 10px auto !important; }
    .modal-dialog { margin: 10px auto !important; }

    /* Filters en columna */
    .filters-row { flex-direction: column; gap: 8px; }
    .filters-row .form-control, .filters-row .btn { width: 100%; max-width: 100%; }
}

/* ── GENERAL: modales responsive ────────────────────────────── */
@media (max-width: 768px) {
    .modal-xl { max-width: 98% !important; margin: 6px auto !important; }
    .modal-dialog { margin: 6px !important; }
    .modal-content { border-radius: 8px; }
    .permisos-grid { grid-template-columns: 1fr !important; }
}

/* Tabla backups: nombre de archivo recortado en escritorio */
.col-backup-archivo code {
    display: block;
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.75rem;
}

/* Semáforo de sistemas en móvil: dos columnas */
@media (max-width: 480px) {
    #sistemasStatus {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 6px;
    }
}



/* ─── Item 8: responsive móvil (375px) — acciones y tablas ───────────── */
/* BUG 4 / BUG 8: los botones de acciones nunca se comprimen ni se solapan en
   ningún viewport; alto mínimo táctil de 44px y alineados verticalmente. */
.acciones { display: flex; gap: 6px; flex-wrap: nowrap; white-space: nowrap; align-items: center; }
.acciones .btn {
    flex-shrink: 0;
    white-space: nowrap;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.tabla td.acciones { width: 1%; }
.table-responsive { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
.table-responsive > table { min-width: 520px; }

@media (max-width: 480px) {
    .section-header { flex-wrap: wrap; gap: 8px; }
    .section-header .btn-label { display: none; }   /* solo iconos en móvil */
    .stats-row { grid-template-columns: repeat(2, 1fr); }
    .btn { padding: 8px 10px; }
    .acciones .btn { padding: 6px 8px; }
    .config-item { flex-wrap: wrap; }
    .editor-box, .empresa-box { width: 96vw; max-width: 96vw; }
    .editor-tabs { overflow-x: auto; flex-wrap: nowrap; }
    .editor-tab { flex-shrink: 0; }
}

/* ═══ V5 (P5): PANEL DE NOTIFICACIONES — estilo consistente en todos los módulos ═══ */
.notif-panel {
    border: 1px solid var(--n200);
    border-radius: 12px;
    box-shadow:var(--sombra-alta);
    overflow: hidden;
    background: var(--panel);
    min-width: 300px;
    max-width: 380px;
}
.notif-header {
    padding: 12px 16px;
    border-bottom: 1px solid var(--n200);
    background: var(--n100);
    font-weight: 600;
    color: var(--n900);
}
.notif-item {
    padding: 12px 16px;
    border-bottom: 1px solid var(--n200);
}
.notif-item:last-child { border-bottom: none; }

/* ═══ V127: BOTÓN FLOTANTE ÚNICO (flecha) — despliega Ayuda + Reportar problema ═══
   Reemplaza los dos FAB sueltos: .bug-report-fab (V5) y #_ayudaFab (V120/V122).
   z-index 500 = sobre el contenido, DEBAJO de toasts (2000) y modales. */
.integris-fab {
    position: fixed; bottom: 20px; right: 16px; z-index: 500;
    display: flex; align-items: center; gap: 10px;
}
.integris-fab-toggle {
    width: 48px; height: 48px; border: none; border-radius: 50%;
    background: var(--n900); color: var(--sobre-tinta); font-size: 18px; font-weight: 800;
    cursor: pointer; box-shadow: var(--sombra-alta);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0; transition: transform 0.15s;
}
.integris-fab-toggle:hover { transform: scale(1.08); }
.integris-fab-acciones {
    display: flex; align-items: center; gap: 8px;
    opacity: 0; visibility: hidden; transform: translateX(12px);
    transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
}
.integris-fab.open .integris-fab-acciones { opacity: 1; visibility: visible; transform: translateX(0); }
.integris-fab-accion {
    border: none; border-radius: var(--radio-pastilla); padding: 10px 16px;
    background: var(--n800); color: var(--sobre-tinta); font-size: var(--t-sm); font-weight: 700;
    cursor: pointer; white-space: nowrap; box-shadow: var(--sombra-alta);
}
.integris-fab-accion:hover { filter: brightness(1.08); }
/* Pantallas angostas: los accesos no caben en fila → se apilan sobre la flecha */
@media (max-width: 600px) {
    .integris-fab { flex-direction: column; align-items: flex-end; gap: 8px; }
    .integris-fab-acciones { flex-direction: column; align-items: flex-end; transform: translateY(12px); }
    .integris-fab.open .integris-fab-acciones { transform: translateY(0); }
}
/* T-2.1 — el auditor: el FAB de Ayuda/Reportar estorba en teléfono y tablet (tapa botones, roba espacio).
   Se OCULTA en móvil/tablet (≤820px) para que NUNCA tape botones (MARCAR, acciones de la VT, etc.).
   En escritorio (≥821px) se conserva: ahí no hay solapamiento y Ayuda/Reportar siguen disponibles. */
@media (max-width: 820px) {
    .integris-fab { display: none !important; }
}

/* ═══ V7 (T5): EMPTY STATES — centrado absoluto en todo el sistema (sin media query) ═══ */
.empty-state, .no-data, .sin-datos,
[class*="sin-registros"], [class*="sin-datos"], [class*="no-hay"],
td.empty, td[colspan] {
    text-align: center !important;
    width: 100% !important;
    padding: var(--e10) var(--e5) !important;
    color: var(--n600) !important;
    font-style: normal !important;
    font-size: var(--t-base) !important;
    line-height: 1.6 !important;
    box-sizing: border-box !important;
}
/* td[colspan] dentro de tabla NO debe ser display:block (rompe el layout de fila) */
table td[colspan] { display: table-cell !important; }

/* ── V33: Botón X de cierre de modales — global (aplica a .modal-close y .modal-close-btn) ── */
.modal-close-btn, .modal-close, .modal-header .modal-close {
    width: 32px; height: 32px; border-radius: 50%;
    border: none; background: transparent; color: var(--n600);
    font-size: 18px; font-weight: 300; line-height: 1; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0; transition: background .2s, transform .15s; padding: 0;
}
.modal-close-btn:hover, .modal-close:hover, .modal-header .modal-close:hover {
    background: var(--n200); color: var(--n900);
}
.modal-close-btn:active, .modal-close:active, .modal-header .modal-close:active { transform: scale(0.95); }
/* Variante para modales con encabezado claro */
.modal-close-btn.dark { background: var(--velo); color: var(--n800); }
.modal-close-btn.dark:hover { background: var(--velo); }

/* ═══ Barra de progreso reusable (LOTE Presupuestos/Barra) — paleta INTEGRIS ═══ */
.integris-prog { width: 100%; }
.integris-prog-label { font-size: .9rem; color: var(--n900); font-weight: 600; margin-bottom: 8px; text-align: center; }
.integris-prog-track { width: 100%; height: 14px; background: var(--a200); border-radius: 8px; overflow: hidden; box-shadow:var(--sombra-hundida); }
.integris-prog-fill { height: 100%; width: 0; background: linear-gradient(90deg,var(--n900),var(--a600)); border-radius: 8px; transition: width .28s ease; }
.integris-prog-pct { margin-top: 6px; text-align: center; font-size: .82rem; color: var(--a600); font-weight: 700; letter-spacing: .02em; }
.integris-prog-ov { position: fixed; inset: 0; background: var(--velo); z-index: 3000; display: flex; align-items: center; justify-content: center; padding: 20px; }
.integris-prog-card { background: var(--panel); border-radius: 12px; padding: 24px 28px; min-width: 280px; max-width: 92vw; box-shadow:var(--sombra-alta); }

/* ── Y01-D · FullCalendar: el título del evento se cortaba a secas ──────────────────────────────
   `.fc-event-title` viene de la librería con `overflow:hidden` y sin `text-overflow`, así que en la
   agenda del Coordinador (Equipo › Calendario) los nombres largos perdían hasta 111 px SIN NINGUNA
   señal: el usuario leía "PRUEBA13 PRUEBA43 PER" y creía que ese era el texto completo. Con los puntos
   suspensivos se ve que hay más (y el evento sigue abriéndose al hacer clic). Solo presentación. */
.fc-event-title, .fc-event-title-container { text-overflow: ellipsis; }

/* ── Y09 · CONTADOR DEL MENÚ LATERAL ────────────────────────────────────────────────────────────
   Los badges del sidebar (Alertas de SSOMA, Plan de Visitas, Programación del Coordinador) tenían su
   estilo dentro del <style> del dashboard de cada sistema, así que al montar la MISMA barra en otra
   página —Evidencias— el contador se quedaba sin CSS y sin dato. La clase vive aquí, en el CSS que
   cargan todas las pantallas, para que el menú se vea igual esté donde esté. */
.nav-badge {
    display: none;                     /* lo enciende integrisBadgesMenu() solo si hay algo que contar */
    min-width: 18px;
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 10px;
    background: var(--peligro);
    color: var(--sobre-peligro);
    font-size: 11px;
    font-weight: 700;
    line-height: 1.5;
    text-align: center;
    flex-shrink: 0;
}

/* ── UN BOTÓN QUE ESTÁ TRABAJANDO NO SE PUEDE VOLVER A PULSAR (18-ago-2026) ────────────────────
   El bloqueo real lo hace `main.js` (marca el botón mientras su petición de escritura está en
   vuelo). Esto es solo lo que se VE: que se note que está ocupado y que el ratón no invite a
   volver a pulsar. Vale igual para <button> (que sí acepta `disabled`) y para <a class="btn">
   (que no lo acepta, y por eso hace falta `pointer-events`).                                    */
.integris-en-vuelo,
.integris-en-vuelo:hover {
    opacity: .55;
    cursor: progress !important;
    pointer-events: none !important;   /* imprescindible para los <a class="btn"> */
    filter: grayscale(.35);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   LOTE M · 8 — TODOS LOS BOTONES CON EL MISMO ASPECTO
   ═══════════════════════════════════════════════════════════════════════════════════════════════
   el auditor: «estás agregando muchos botones mal hechos: todo de frente, todo de corrido,
   rectangulares, sin las esquinas redondeadas que usa el resto del sistema. […] Que un botón de una
   pantalla nueva se vea IGUAL que uno de las 52 secciones que ya di por cerradas. El sistema tiene
   un estilo. Que no se note dónde tocaste y dónde no.»

   MEDIDO EN PANTALLA, no leído en el CSS: recorriendo los 13 módulos con la cuenta de cada rol
   salieron decenas de botones a 0 px y a 4 px conviviendo con los de 8 px. El motivo es que el
   estándar `.btn` usaba `--radio-sm` (4 px, casi recto) y muchos botones nacidos en JavaScript ni
   siquiera llevaban clase, así que se quedaban en el 0 px del navegador.

   ESTO VA AL FINAL DEL FICHERO A PROPÓSITO: en CSS, a igualdad de peso gana el último. Así una
   pantalla nueva hereda el estilo sin que nadie tenga que acordarse de ponerlo.

   ⚠️ LO QUE NO SE TOCA, y por qué: las PÍLDORAS (chips, badges, el botón flotante) son redondas a
   propósito y se ven así en todo el sistema. Aplastarlas a 8 px sería «unificar» rompiendo algo que
   ya estaba bien. Se excluyen por nombre, no por casualidad. */
button,
.btn,
a.btn,
.vt-btn,
.cd-btn,
.sk-table button,
[role="button"] {
    border-radius: var(--radio);          /* 8 px — el redondeo del sistema */
}

/* Las píldoras y los redondos de siempre, que se quedan como estaban. */
.chip, .chip-baja, .badge, .badge-estado, .role-badge, .nav-badge,
.integris-fab, .integris-fab-accion, .integris-fab-btn,
.sbfec-btn, .btn-circulo, .btn-icono-redondo,
button.pill, .btn.pill, [class*="pill"], [class*="chip"], [class*="badge"] {
    border-radius: 999px;
}

/* Los cuadraditos de acción de las tablas (34×34) siguen siendo cuadrados, pero redondeados. */
.td-acciones button, .td-acciones a.btn, .tabla .btn-sm { border-radius: var(--radio); }

/* «QUE NO SALGAN PEGADOS UNOS A OTROS DE CORRIDO».
   Dos botones hermanos, pegados, se leen como un solo bloque. Se les da aire SIEMPRE, sin depender
   de que quien escribió la pantalla se acordara de poner el `gap`. */
.btn + .btn,
.vt-btn + .vt-btn,
.cd-btn + .cd-btn,
button + button,
.btn + a.btn,
a.btn + .btn,
a.btn + a.btn { margin-left: 8px; }

/* …salvo dentro de un contenedor que YA reparte el espacio él mismo: ahí el margen sobraría y
   descuadraría la fila. */
.d-flex > .btn + .btn, [style*="gap"] > .btn + .btn,
.page-header-actions > .btn + .btn, .rh-toolbar > .btn + .btn,
.td-acciones > button + button, .td-acciones > .btn + .btn,
.sk-h > .btn + .btn, .vt-acciones > .vt-btn + .vt-btn { margin-left: 0; }

/* LOTE M · 8 — los botones de FullCalendar (biblioteca de terceros) también.
   Salen en el calendario del Coordinador con SU propio estilo —«today», «month», «week», «list»— y
   se ven rectos al lado de los nuestros. No se toca la biblioteca: se le pone nuestro redondeo. */
.fc .fc-button, .fc-button, .fc-button-group > .fc-button { border-radius: var(--radio) !important; }
/* ⚠️ `.config-tab` NO se arregla desde aquí: vive en admin.css, que carga DESPUÉS de este
   fichero y gana siempre. Se cambió allí, en su sitio. Pelear con la especificidad desde el
   fichero equivocado es cómo nacen los `!important` que luego nadie entiende. */
.fc-button-group > .fc-button:not(:first-child) { margin-left: 4px; }

/* Y las cruces de cerrar de los modales, que son cuadraditos: redondas, como el resto. */
.modal-close, .sk-box-h button, .vt-ov-h button, [onclick*="cerrar"].btn-x { border-radius: 8px; }


/* ── El selector de tema cuando no hay barra donde colgarlo (acceso, error) ──────────────────
   Lo coloca `tema.js`. Arriba a la derecha, porque abajo vive el boton flotante de ayuda. */
.integris-tema-suelto {
    position: fixed;
    top: 14px;
    right: 14px;
    z-index: 400;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--n300);
    border-radius: var(--radio);
    background: var(--panel);
    color: var(--n700);
    font-size: 1rem;
    cursor: pointer;
    box-shadow: var(--sombra);
    transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.integris-tema-suelto:hover { background: var(--n200); border-color: var(--n500); color: var(--n900); }
