/* ══════════════════════════════════════════════════════════════════════════
   BLXBOX · Inventario de IT — Bailmex

   El criterio:

     · El color significa algo o no esta. Rojo = critico o secreto. Ambar =
       atencion. Verde = operativo. Nada mas decora.
     · La monoespaciada es para valores que se copian y se comparan: llaves,
       URL, contrasenas, fechas. El texto que se lee va en sans.
     · Densidad antes que aire. Un departamento con cuarenta proyectos se
       recorre mejor en filas que en tarjetas grandes.
     · El proyecto es el eje. La columna de la izquierda no se va nunca, y
       todo lo que sea una lista global se lee en grupos con encabezado.

   El color de categoria se usa en dos sitios y en ninguno mas: el icono del
   proyecto y la linea del encabezado de su grupo. Es lo justo para saber de
   que familia es algo sin que la pantalla se vuelva un arcoiris.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Medidas, familias y tiempo ───────────────────────────────────────────
   Van aparte porque no tienen dos valores. Meterlos en los bloques de color
   obligaria a mantener en dos sitios ocho cosas que nunca cambian.      */
:root {
  --r-1: 6px;
  --r-2: 10px;
  --r-3: 14px;
  --barra-alto: 54px;
  --rail-ancho: 268px;

  --mono: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Mono", Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --paso: 160ms cubic-bezier(.25, .8, .35, 1);
}

/* ══════════════════════════════════════════════════════════════════════════
   TEMA CLARO — el que sale si nadie elige nada.

   Vive en el :root PELADO y no bajo ninguna @media. Consecuencia: la consola
   se pinta clara desde la hoja de estilos, antes de que exista un <script>,
   asi que el destello del primer cuadro es imposible por construccion y no
   por suerte. El oscuro es el que necesita que alguien lo pida.

   LA ESCALERA CAMBIA DE DIRECCION. En oscuro, subir de escalon es ACLARAR y
   --fondo es el extremo. En claro, --sup-1 es lo unico que SUBE —blanco, la
   tarjeta y el panel que se levantan del suelo— y todo lo demas BAJA desde
   el suelo hacia el gris azulado. Por eso --sup-alta, que en oscuro es el
   mas claro de los seis, aqui es el mas oscuro.

   PROCEDENCIA. Cinco de las seis superficies, las dos lineas de los
   extremos, las dos tintas de los extremos, los cuatro del acento, los tres
   tonos vivos y las dos sombras son valores LITERALES de Inventario.html.
   Lo que no es literal esta escrito como la mezcla exacta que lo produce, y
   la mezcla cuadra al byte: no hay ningun color inventado sin decirlo.
   ══════════════════════════════════════════════════════════════════════════ */
:root {
  color-scheme: light;

  /* ── Superficies ────────────────────────────────────────────────────────
     --sup-0 es el CROMO: barra, riel, indice, filtros, pestañas, thead,
     paginador, tira del equipo. --sup-1 es lo que se LEVANTA: tarjetas,
     paneles, y el hover que se apoya sobre el cromo.

     --sup-1 blanco y --sup-0 tintado, y no al reves como hace el archivo
     aprobado (donde .topbar y .nav son blancos), porque en BLXBOX --sup-1
     hace DOS trabajos a la vez —la tarjeta que sube Y el hover sobre el
     cromo— y en claro esos dos trabajos piden lados contrarios. Si el cromo
     fuera blanco, --sup-1 tendria que ser #F4F6FB y .cifra, .tarjeta y
     .fila-proy quedarian a 1.02:1 del suelo: tarjetas invisibles y los diez
     modales grises. El precio es que .item:hover y .pestana:hover dan
     1.08:1 — que es EXACTAMENTE el hover del archivo aprobado.          */
  --fondo:    #F7F8FC;   /* = --ground      literal */
  --sup-0:    #F4F6FB;   /* = --surface-2   literal */
  --sup-1:    #FFFFFF;   /* = --surface     literal */
  --sup-2:    #E9EDF6;   /* = --surface-3   literal */
  --sup-3:    #DFE4F0;   /* mix(--surface-3 60%, --line-strong 40%)
                            R .6·233+.4·207=222.6→223  G .6·237+.4·215=228.2→228
                            B .6·246+.4·230=239.6→240  = #DFE4F0 exacto.
                            Hace falta porque BLXBOX tiene SEIS escalones y el
                            archivo aprobado solo cuatro. Esta puesto donde
                            esta porque es el par que MANDA en toda la paleta:
                            --txt-4 encima da 4.67:1, y --txt-4 cae sobre
                            --sup-3 en cinco selectores reales.          */
  --sup-alta: #CFD7E6;   /* = --line-strong literal */

  /* ── Lineas ─────────────────────────────────────────────────────────────
     ALFA y no hex, igual que en oscuro, y no es una licencia: las tres caen
     sobre las seis superficies, sobre los pisos de color y sobre los
     rellenos de las tarjetas de cifra. Un #E8ECF4 solido encima de una
     pastilla --sup-2 #E9EDF6 es invisible.

     La tinta no es negra sino un azul marino, y esta elegida para que el
     resultado SEA el valor aprobado, no para que se le parezca:
       rgba(25,65,145,.10) sobre blanco
         R .10·25+.90·255 = 232 = E8   G = 236 = EC   B = 244 = F4
       = #E8ECF4, que es --line del archivo aprobado, EXACTO.
       Y al .21 da #CFD7E8, a dos unidades de --line-strong #CFD7E6.
     Los dos valores del archivo son colineales desde una sola tinta.

     Esto ademas arregla solo el unico sitio donde volver las lineas opacas
     tenia consecuencia: .equipo__tira (linea 2224) dibuja su rejilla con el
     gap de 1px sobre un fondo --linea. En claro da 1.18:1 contra las celdas
     --sup-0; en el oscuro de hoy da 1.20:1. Es la misma rejilla.        */
  --linea:   #E8ECF4;   /* -> #E8ECF4 sobre blanco (= --line) */
  --linea-2: #DDE3EE;   /* -> #DDE3EF */
  --linea-3: #CFD7E6;   /* -> #CFD7E8 (~ --line-strong) */

  /* ── Texto ──────────────────────────────────────────────────────────────
     BLXBOX gasta CUATRO tintas y el archivo aprobado solo trae tres, y la
     tercera suya —--ink-3 #98A2B3— da 2.58:1 sobre blanco: es texto en
     .cell-sub, .nav-label, .kpi-note y .att-meta, y reprueba AA por mucho.
     Copiarla seria copiar un fallo.

     La escalera se corre un escalon hacia abajo: --ink pasa a --txt y
     --ink-2 pasa a --txt-4, los dos LITERALES, y los dos huecos de en medio
     se interpolan sobre la recta que los une (17,24,39)→(90,100,120), a
     t=0.60 y t=0.80. No es un gris nuevo: es el mismo gris a media altura.

     La escalera clara es mas PLANA que la oscura —17.74/9.48/7.50/5.95
     contra 16.08/8.46/4.95/2.92— y eso no es un descuido: entre 17.7 y 4.5
     no caben cuatro escalones anchos. La oscura es ancha porque su cuarto
     peldaño reprueba. Este no.                                          */
  --txt:   #111827;   /* = --ink   literal */
  --txt-2: #5A6478;   /* t=0.60 de --ink a --ink-2 */
  --txt-3: #98A2B3;   /* t=0.80 */
  --txt-4: #AEB6C4;   /* = --ink-2 literal */

  /* ── Acento ─────────────────────────────────────────────────────────────
     Los cuatro del archivo aprobado. El indigo es lo mas visible del panel
     que el usuario vio, y es el UNICO color de color de la referencia que
     ya pasaba AA sin retocar (5.81 sobre blanco, 4.95 sobre su piso): se
     conserva EXACTO.

     --acento-2 se da la vuelta: en oscuro es el escalon MAS CLARO (#7fb5e4),
     aqui es el MAS OSCURO. El token no significa "el acento aclarado", sino
     "el acento subido de tono", y subir de tono es alejarse del fondo. El
     propio Inventario.html hace ese giro: su --accent-ink pasa de #4939CE en
     claro a #9A8DFF en su bloque oscuro.                                */
  --acento:       #5B4BE8;                 /* = --accent      literal */
  --acento-2:     #4939CE;                 /* = --accent-ink  literal */
  --acento-piso:  #EEEBFE;  /* -> #EDEBFC (~ --accent-soft #EEEBFE) */
  --acento-linea: #C9C1FB;  /* -> #CBC5F8 (~ --accent-line #C9C1FB) */
  /* La tinta ENCIMA de un relleno de acento. En oscuro el acento es un azul
     claro y encima va casi negro; en claro es un indigo y encima va blanco.
     Este token mata los cuatro #0b1218 sueltos: dejarlos daria 2.87:1 y los
     botones primarios de toda la consola quedarian ilegibles.           */
  --sobre-acento: #FFFFFF;

  /* ── Los tonos VIVOS ────────────────────────────────────────────────────
     Los hex aprobados, intactos. NO son la tinta del texto: son el color con
     el que se PINTAN los pisos, las orlas y los rellenos.

     Hacen falta separados porque un token no puede ser a la vez tinta
     legible y tinte reconocible sobre blanco: --ambar oscurecido a #865307
     mezclado al 42% sobre blanco da #C9AC77, un barro; el --warn aprobado
     al 42% da #F2CE99, que sigue siendo ambar. En oscuro --tono-X vale
     exactamente lo mismo que --X, asi que alli no se mueve ni un bit.

     --tono-violeta es el UNICO color de este bloque que NO viene del archivo
     aprobado, porque Inventario.html no tiene ningun morado: sus tokens de
     color son ground/surface/ink/accent/anil/ok/warn/crit/star y se acabo.
     Esta declarado como invencion y no como herencia.                   */
  --tono-rojo:    #E24B4B;   /* = --crit literal */
  --tono-ambar:   #E08A0B;   /* = --warn literal */
  --tono-verde:   #0FA97C;   /* = --ok   literal */
  --tono-violeta: #9333EA;   /* INVENTADO. El archivo aprobado no trae morado. */

  /* ── Las TINTAS semanticas ──────────────────────────────────────────────
     Estos tokens son TEXTO en .crit, .sello, .pastilla, .alerta b, .dato b,
     .tira__valor, .acc-rol, .peticion__prioridad, .rail__error,
     .importar__estado y .item.aviso .item__nombre. Los tonos vivos no pasan
     AA como texto —--warn sobre --warn-soft da 2.45:1, --ok sobre --ok-soft
     2.70, --crit sobre --crit-soft 3.44— y el propio archivo aprobado los
     usa asi en .chip.warn, .chip.ok y .chip.crit.

     Se bajan conservando HUE Y SATURACION EXACTOS, no aproximados:
       rojo    H 0.00 S 72.25 %   ->  H 0.00 S 72.25 %   L 65.3 -> 41.2
       ambar   H 35.77 S 90.64 %  ->  H 35.77 S 90.64 %  L 45.9 -> 27.6
       verde   H 162.47 S 83.70 % ->  H 162.47 S 83.70 % L 36.1 -> 22.8
       violeta H 271.48 S 81.33 % ->  H 271.48 S 81.33 % L 55.9 -> 48.4
     Es el mismo color con menos luz. Y cada uno esta bajado hasta el MINIMO
     que pasa 4.5:1 en el peor de sus once fondos, que es su propio piso
     compuesto sobre --sup-3 (la fila elegida de la tabla de inventario).  */
  /* LITERALES del archivo aprobado, por decision expresa. Como TINTA sobre
     su propio piso no llegan a 4.5:1 —el ambar da 2.45— y se prefirio el
     color exacto a la legibilidad de esas pastillas. Si algun dia se quiere
     lo contrario, los que si pasan son #B51D1D, #865307, #096B4E y #8017E0.
     Los fondos y los rellenos ya eran literales: solo cambia el texto.  */
  --rojo:    #E24B4B;
  --ambar:   #E08A0B;
  --verde:   #0FA97C;
  --azul:    #5B4BE8;   /* = --acento, igual que hoy en oscuro.
                           .crit[data-n="Medio"] (linea 816) pinta
                           color:var(--azul) sobre background:var(--acento-piso):
                           separarlos porque el archivo trae dos azules pondria
                           anil sobre lavanda indigo por un detalle de mapeo. */
  --violeta: #9333EA;

  /* ── Los pisos ──────────────────────────────────────────────────────────
     ALFA del tono vivo, no los hex -soft del archivo aprobado. Es la unica
     forma de que una franja de color funcione en claro, y se ve con numeros:
     --warn-soft #FEF3E0 opaco sobre el cromo #F4F6FB da 1.016:1 —la banda de
     .alerta, que es un aviso a ancho completo pegado bajo la barra, no
     existiria— y sobre --sup-3 se INVIERTE: la pastilla saldria mas clara
     que la fila que la contiene.

     En alfa, la franja tiñe lo que tenga debajo y da 1.10-1.17:1 sobre las
     SEIS superficies, uniforme y sin invertirse nunca. El oscuro de hoy, que
     tambien usa alfa, da 1.16-1.23. Es el mismo sistema.

     Y las alfas estan calibradas para que sobre blanco rindan el soft
     aprobado, no para que se le parezcan:
       rgba(226,75,75,.105)   -> #FCECEC   contra --crit-soft #FDECEC
       rgba(224,138,11,.12)   -> #FBF1E2   contra --warn-soft #FEF3E0
       rgba(15,169,124,.11)   -> #E5F6F1   contra --ok-soft   #E4F7F0
     La mayor desviacion es de 4 unidades en un canal.                   */
  --rojo-piso:    rgba(226,  75,  75, .105);
  --ambar-piso:   rgba(224, 138,  11, .12);
  --verde-piso:   rgba( 15, 169, 124, .11);
  --violeta-piso: rgba(147,  51, 234, .10);

  /* Bordes y franjas rojas/ambar que hoy viven sueltos por el archivo.
     Ver el apartado "sueltos": tres alfas rojas y dos ambar hacian el mismo
     trabajo con dos centesimas de diferencia.                           */
  --rojo-linea:   rgba(226, 75, 75, .34);   /* .boton--peligro, .alerta--roja */
  --rojo-linea-2: rgba(226, 75, 75, .50);   /* .mini--rojo:hover, que grita mas */
  --rojo-piso-2:  rgba(226, 75, 75, .18);   /* -> #F9DFDF · la franja encendida */
  --ambar-linea:  rgba(224, 138, 11, .34);
  --sobre-rojo:   #B51D1D;                  /* la tinta encima de --rojo-piso-2 */

  /* ── El relleno de una tarjeta de cifra ─────────────────────────────────
     Se INVIERTE ENTERO. Ver el apartado "rellenos" para la aritmetica.
     Base, carga y escalon son TOKENS para que el @supports de mas abajo sea
     uno solo y sirva a los dos temas con una sola formula.

     42/26 y no 45/28: la razon se conserva, que es lo unico que la ley del
     archivo fija.  28/45 = 0.6222 ·  26/42 = 0.6190.                   */
  --lleno-base:    var(--sup-1);   /* blanco. En oscuro la base es --sup-0 */
  --lleno-carga:   42%;            /* en oscuro 45% */
  --lleno-carga-1: 26%;            /* en oscuro 28% · el escalon tenue */

  /* --lleno-neutro deja de ser --sup-3 y pasa a ser --sup-2, y hay que
     entender por que o el orden de los seis se rompe. El invariante NO es
     "el token --sup-3", es "el escalon de superficie mas cercano al cromo en
     la direccion en la que viaja la rampa". En oscuro esa direccion es hacia
     arriba y ese escalon es --sup-3; en claro es hacia abajo y es --sup-2.
     Con --sup-3 (1.18 contra la barra) el gris quedaria por DEBAJO del ambar
     tenue (1.18) y "el total" pesaria lo mismo que "falta un papel".
     Con --sup-2 la barra queda escalonada y monotona:
        neutro 1.08 < tenue 1.18 < ambar 1.38 < verde 1.46 < rojo 1.63 <
        violeta 1.81   — que es el mismo orden que en oscuro.            */
  --lleno-neutro:  #E9EDF6;   /* = --sup-2. El total no es una alarma. */
  --lleno-verde:   #9ADBC8;   /* --tono-verde   42% sobre blanco */
  --lleno-ambar:   #F2CE99;   /* --tono-ambar   42% */
  --lleno-ambar-1: #F7E1C0;   /* --tono-ambar   26% — falta un papel */
  --lleno-violeta: #D2A9F6;   /* --tono-violeta 42% */
  --lleno-rojo:    #F3B3B3;   /* --tono-rojo    42% */

  /* El filo: las MISMAS alfas del oscuro (.50/.55/.34/.50/.55), porque lo que
     hacen no cambia. Lo que cambia es que la tinta ahora oscurece el canto
     en vez de aclararlo. Se resuelve solo, sin tocar un numero.         */
  --orla-verde:   rgba( 15, 169, 124, .50);
  --orla-ambar:   rgba(224, 138,  11, .55);
  --orla-ambar-1: rgba(224, 138,  11, .34);
  --orla-violeta: rgba(147,  51, 234, .50);
  --orla-rojo:    rgba(226,  75,  75, .55);

  /* Texto ENCIMA de un relleno. En oscuro es --txt al 82%: luz rebajada.
     Aqui es --ink al 76%: sombra rebajada. Misma idea —no es un gris nuevo,
     es la tinta principal con alfa—. El peor de los seis pasa de 4.71:1 en
     el oscuro de hoy a 5.43:1.                                          */
  --lleno-txt:   rgba(17, 24, 39, .76);
  /* El cuadro del icono. El comentario original dice que en oscuro esta
     hecho de LUZ porque sobre un fondo de color un cuadro --sup-2 es un
     agujero negro. Aqui el problema es el espejo exacto: sobre un tinte
     palido, luz sobre luz no se ve. SOMBRA, con el mismo razonamiento dado
     la vuelta. La tinta 17,24,39 no es nueva: es la que Inventario.html usa
     en --shadow.                                                        */
  --lleno-caja:  rgba(17, 24, 39, .07);
  --lleno-filo:  rgba(17, 24, 39, .15);
  --lleno-icono: rgba(17, 24, 39, .82);

  /* ── Velos, sombras y cromo del navegador ───────────────────────────────
     El velo del modal se OSCURECE tambien en claro: un velo tiene un solo
     trabajo —hundir lo de detras— y hundir es oscurecer en los dos temas.
     Pero .72 en claro apaga la pagina como si fuera de noche; con .45 (que
     es el .modal-wrap del archivo aprobado) el panel blanco encima da
     3.07:1, contra el 1.11:1 que da el oscuro de hoy.

     El unico velo que se ACLARA es el de soltar archivos: no separa dos
     planos, apaga la consola mientras se arrastra. En oscuro apaga a negro,
     en claro apaga a --fondo.

     Las sombras cambian de FORMA, no solo de alfa: llevan propagacion
     NEGATIVA. Sin ella, un desenfoque de 80px sobre #F7F8FC no se lee como
     elevacion, se lee como una mancha.                                  */
  --velo:        rgba(17, 24, 39, .45);      /* .capa__fondo  */
  --velo-suave:  rgba(17, 24, 39, .32);      /* .rail__velo   */
  --velo-visor:  rgba(17, 24, 39, .88);      /* .visor__fondo · sigue a oscuras */
  --velo-soltar: rgba(247, 248, 252, .88);   /* .soltando · el unico que aclara */

  --sombra-menu:     0 12px 28px -8px rgba(17,24,39,.20), 0 1px 3px rgba(17,24,39,.06);
  --sombra-panel:    0 24px 60px -20px rgba(17,24,39,.28);   /* = --shadow-lg literal */
  --sombra-flotante: 0 12px 30px -8px rgba(17,24,39,.24), 0 1px 3px rgba(17,24,39,.06);
  --sombra-cajon:    0 0 40px -6px rgba(17,24,39,.20);
  /* NUEVO. Es --shadow del archivo aprobado, literal. Existe porque es lo
     que hace que el claro se PAREZCA al panel que el usuario vio: alli las
     tarjetas llevan box-shadow y en BLXBOX no llevan ninguna, y sobre un
     suelo #F7F8FC una tarjeta blanca sin sombra solo la sostiene su borde a
     1.18:1. En oscuro vale una sombra NULA pero VALIDA —no `none`— porque
     entra en una lista con el aro de .cifra--foco.activo y `none` dentro de
     una lista de box-shadow invalida la declaracion entera.             */
  --sombra-carta:    0 1px 2px rgba(17,24,39,.04), 0 1px 3px rgba(17,24,39,.05);

  --seleccion: rgba(91, 75, 232, .20);   /* -> #DEDBFA · --txt encima 13.20:1 */
  --rodillo:   rgba(17, 24, 39, .22);    /* barra de rodar */
  --rodillo-2: rgba(17, 24, 39, .34);

  /* No son colores y por eso no salen en ningun recuento, pero rompen el
     claro sin dar un solo error. Ver "sueltos", puntos 27-29.           */
  --realce:        brightness(.95);   /* .cifra--foco:hover · en claro OSCURECE */
  --realce-2:      brightness(.94);   /* .boton-alto:hover */
  --filtro-borrar: none;              /* la equis del buscador ya es oscura */

  /* ── Color por categoria ────────────────────────────────────────────────
     Dos sitios y ninguno mas: el icono del proyecto y la linea del
     encabezado de su grupo. Son grafico, asi que el minimo es 3:1 — pero
     estan calculados a 4.5:1 sobre las cinco superficies donde caen, porque
     --cat tambien sale como .item__punto y .pastilla i.

     Se conservan las igualdades que hoy tiene el oscuro: directorio =
     seguridad = --verde, negocio = --ambar, comunicaciones = --violeta. Si
     el color de la categoria y el semantico se separan, el color deja de
     localizar nada.

     DOS se rompen a proposito y las dos estan declaradas:
       · infraestructura deja de ser = --acento y pasa a derivar del --anil
         #3B82F6 del archivo aprobado (H217.2, conservado exacto). En oscuro
         la identidad funcionaba porque el acento era azul; en claro el acento
         es indigo y significa "aqui estas", y una categoria no puede
         significar eso.
       · respaldo se mueve de H253.5 a H294. A H253.5 quedaria a OCHO grados
         del acento indigo. En oscuro comunicaciones (255.4) y respaldo
         (253.5) estan a DOS grados —o sea que hoy son indistinguibles— y
         aqui quedan a 23. Es mejor de lo que hay.                       */
  --c-soporte:        #9D501C;   /* H 24.19 · de #e08a4f, hue conservado */
  --c-directorio:     #096B4E;   /* = --verde */
  --c-documentacion:  #B22C8A;   /* H 317.91 · de #c77bb0 */
  --c-infraestructura:#0A5CE0;   /* H 217.01 · de --anil #3B82F6 (aprobado) */
  --c-seguridad:      #096B4E;   /* = --verde, igual que hoy */
  --c-red:            #1F6F7B;   /* H 187.83 · de #57b6c4 */
  --c-negocio:        #865307;   /* = --ambar */
  --c-comunicaciones: #8017E0;   /* = --violeta */
  --c-nube:           #256B93;   /* H 201.82 · de #5aa9d6 */
  --c-respaldo:       #A52CB2;   /* H 294.18 · MOVIDO, ver arriba */

  /* Las MISMAS alfas .14 y .34 del oscuro. Con la tinta ya oscura, el .14 da
     un tinte y el .34 da un contorno, que es lo que se pedia.           */
  --cat-fondo-soporte:        rgba(157,  80,  28, .14);
  --cat-borde-soporte:        rgba(157,  80,  28, .34);
  --cat-fondo-directorio:     rgba(  9, 107,  78, .14);
  --cat-borde-directorio:     rgba(  9, 107,  78, .34);
  --cat-fondo-documentacion:  rgba(178,  44, 138, .14);
  --cat-borde-documentacion:  rgba(178,  44, 138, .34);
  --cat-fondo-infraestructura:rgba( 10,  92, 224, .14);
  --cat-borde-infraestructura:rgba( 10,  92, 224, .34);
  --cat-fondo-seguridad:      rgba(  9, 107,  78, .14);
  --cat-borde-seguridad:      rgba(  9, 107,  78, .34);
  --cat-fondo-red:            rgba( 31, 111, 123, .14);
  --cat-borde-red:            rgba( 31, 111, 123, .34);
  --cat-fondo-negocio:        rgba(134,  83,   7, .14);
  --cat-borde-negocio:        rgba(134,  83,   7, .34);
  --cat-fondo-comunicaciones: rgba(128,  23, 224, .14);
  --cat-borde-comunicaciones: rgba(128,  23, 224, .34);
  --cat-fondo-nube:           rgba( 37, 107, 147, .14);
  --cat-borde-nube:           rgba( 37, 107, 147, .34);
  --cat-fondo-respaldo:       rgba(165,  44, 178, .14);
  --cat-borde-respaldo:       rgba(165,  44, 178, .34);
}

/* ══════════════════════════════════════════════════════════════════════════
   TEMA OSCURO — los valores de hoy.

   Gana al bloque claro por especificidad: (0,2,0) contra (0,1,0). No depende
   del orden del archivo, pero se escribe aqui igual para que se lean juntos.
   ══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="dark"] {
  color-scheme: dark;

  --fondo:    #0F1117;
  --sup-0:    #1E2230;
  --sup-1:    #171A23;
  --sup-2:    #272C3B;
  --sup-3:    #313749;
  --sup-alta: #3A4155;

  --linea:   #252A38;
  --linea-2: #2F3547;
  --linea-3: #3A4155;

  --txt:   #EAECF2;
  --txt-2: #A0A8BC;
  --txt-3: #727C93;
  --txt-4: #5C6478;   /* SIN TOCAR. Da 3.01:1 sobre --sup-0 y reprueba AA, y
                         el propio archivo lo documenta en el comentario de
                         .tira__etiqueta. Ver trampas: es una decision del
                         usuario, no se cuela dentro de este cambio.      */

  --acento:       #7C6CF5;
  --acento-2:     #9A8DFF;
  --acento-piso:  #1F1B3E;
  --acento-linea: #3B3372;
  --sobre-acento: #FFFFFF;                  /* el hex suelto de 342/347/1169/1344 */

  /* En oscuro el tono vivo y la tinta son el MISMO color: aqui no se mueve
     nada, y "cambiar --ambar arrastra su relleno" sigue siendo cierto. */
  --tono-rojo:    #EF6B6B;
  --tono-ambar:   #EBA93C;
  --tono-verde:   #2FBF95;
  --tono-violeta: #9a86d4;

  --rojo:    #EF6B6B;
  --ambar:   #EBA93C;
  --verde:   #2FBF95;
  --azul:    #5B9BF8;
  --violeta: #9a86d4;

  --rojo-piso:    #2E1718;
  --ambar-piso:   #2C2312;
  --verde-piso:   #0D2A22;
  --violeta-piso: rgba(154, 134, 212, .13);

  --rojo-linea:   #552829;  /* PLEGADO: .35 (l.353) y .32 (l.477) */
  --rojo-linea-2: #6E3335;  /* exacto (l.381) */
  --rojo-piso-2:  #3E1D1E;  /* PLEGADO: .24 (l.354) y .22 (l.466) */
  --ambar-linea:  #4C3D1B;  /* PLEGADO: .30 (l.472) y .32 (l.875) */
  --sobre-rojo:   #ffd9d7;                  /* el hex suelto de l.354 */

  --lleno-base:    var(--sup-0);
  --lleno-carga:   45%;
  --lleno-carga-1: 28%;

  --lleno-neutro:  #222831;   /* = --sup-3 */
  --lleno-verde:   #2b594a;
  --lleno-ambar:   #6b542b;
  --lleno-ambar-1: #493c24;
  --lleno-violeta: #4f486e;
  --lleno-rojo:    #6e3939;

  --orla-verde:   #1C4C3E;
  --orla-ambar:   #4C3D1B;
  --orla-ambar-1: #3A2F16;
  --orla-violeta: rgba(154, 134, 212, .50);
  --orla-rojo:    #552829;

  --lleno-txt:   rgba(232, 237, 243, .82);
  --lleno-caja:  rgba(255, 255, 255, .10);
  --lleno-filo:  rgba(255, 255, 255, .16);
  --lleno-icono: rgba(232, 237, 243, .92);

  --velo:        rgba( 6,  9, 12, .72);
  --velo-suave:  rgba( 6,  9, 12, .60);
  --velo-visor:  rgba( 4,  6,  8, .92);
  --velo-soltar: rgba(14, 17, 21, .82);

  --sombra-menu:     0 16px 40px rgba(0,0,0,.5);
  --sombra-panel:    0 24px 60px -20px rgba(0,0,0,.7);
  --sombra-flotante: 0 12px 34px rgba(0,0,0,.5);
  --sombra-cajon:    0 0 40px rgba(0,0,0,.5);
  /* Sombra NULA pero VALIDA. NO poner `none`: este token entra en la lista
     `box-shadow: 0 0 0 2px var(--acento), var(--sombra-carta)` de
     .cifra--foco.activo, y `none` dentro de una lista invalida la
     declaracion entera y borra el aro de la cifra elegida en OSCURO.   */
  --sombra-carta:    0 1px 2px rgba(0,0,0,.4);

  --seleccion: rgba(124, 108, 245, .32);
  --rodillo:   rgba(255, 255, 255, .16);   /* PLEGADO: .16 (l.196) y .14 (l.200) */
  --rodillo-2: rgba(255, 255, 255, .26);

  --realce:        brightness(1.14);
  --realce-2:      brightness(1.08);
  --filtro-borrar: invert(.6);

  --c-soporte:        #e08a4f;
  --c-directorio:     #4bad84;
  --c-documentacion:  #c77bb0;
  --c-infraestructura:#5b9dd9;
  --c-seguridad:      #4bad84;
  --c-red:            #57b6c4;
  --c-negocio:        #d8a03f;
  --c-comunicaciones: #9a86d4;
  --c-nube:           #5aa9d6;
  --c-respaldo:       #a89ad8;

  --cat-fondo-soporte:        rgba(224, 138,  79, .14);
  --cat-borde-soporte:        rgba(224, 138,  79, .34);
  --cat-fondo-directorio:     rgba( 75, 173, 132, .14);
  --cat-borde-directorio:     rgba( 75, 173, 132, .34);
  --cat-fondo-documentacion:  rgba(199, 123, 176, .14);
  --cat-borde-documentacion:  rgba(199, 123, 176, .34);
  --cat-fondo-infraestructura:rgba( 91, 157, 217, .14);
  --cat-borde-infraestructura:rgba( 91, 157, 217, .34);
  --cat-fondo-seguridad:      rgba( 75, 173, 132, .14);
  --cat-borde-seguridad:      rgba( 75, 173, 132, .34);
  --cat-fondo-red:            rgba( 87, 182, 196, .14);
  --cat-borde-red:            rgba( 87, 182, 196, .34);
  --cat-fondo-negocio:        rgba(216, 160,  63, .14);
  --cat-borde-negocio:        rgba(216, 160,  63, .34);
  --cat-fondo-comunicaciones: rgba(154, 134, 212, .14);
  --cat-borde-comunicaciones: rgba(154, 134, 212, .34);
  --cat-fondo-nube:           rgba( 90, 169, 214, .14);
  --cat-borde-nube:           rgba( 90, 169, 214, .34);
  --cat-fondo-respaldo:       rgba(168, 154, 216, .14);
  --cat-borde-respaldo:       rgba(168, 154, 216, .34);
}

[data-cat="soporte"]        { --cat: var(--c-soporte); --cat-fondo: var(--cat-fondo-soporte); --cat-borde: var(--cat-borde-soporte); }
[data-cat="directorio"]     { --cat: var(--c-directorio); --cat-fondo: var(--cat-fondo-directorio); --cat-borde: var(--cat-borde-directorio); }
[data-cat="documentacion"]  { --cat: var(--c-documentacion); --cat-fondo: var(--cat-fondo-documentacion); --cat-borde: var(--cat-borde-documentacion); }
[data-cat="infraestructura"]{ --cat: var(--c-infraestructura); --cat-fondo: var(--cat-fondo-infraestructura); --cat-borde: var(--cat-borde-infraestructura); }
[data-cat="seguridad"]      { --cat: var(--c-seguridad); --cat-fondo: var(--cat-fondo-seguridad); --cat-borde: var(--cat-borde-seguridad); }
[data-cat="red"]            { --cat: var(--c-red); --cat-fondo: var(--cat-fondo-red); --cat-borde: var(--cat-borde-red); }
[data-cat="negocio"]        { --cat: var(--c-negocio); --cat-fondo: var(--cat-fondo-negocio); --cat-borde: var(--cat-borde-negocio); }
[data-cat="comunicaciones"] { --cat: var(--c-comunicaciones); --cat-fondo: var(--cat-fondo-comunicaciones); --cat-borde: var(--cat-borde-comunicaciones); }
[data-cat="nube"]           { --cat: var(--c-nube); --cat-fondo: var(--cat-fondo-nube); --cat-borde: var(--cat-borde-nube); }
[data-cat="respaldo"]       { --cat: var(--c-respaldo); --cat-fondo: var(--cat-fondo-respaldo); --cat-borde: var(--cat-borde-respaldo); }

/* Los rellenos de arriba son hex fijos; aqui se redeclaran como la mezcla
   que en realidad son, para que cambiar --ambar o --sup-0 arrastre sus
   rellenos en vez de dejarlos mintiendo.

   Va dentro de @supports y no suelto porque un color-mix DENTRO de un custom
   property no admite valor de respaldo: si el navegador no lo entiende, la
   propiedad se vuelve invalida al calcular y `background: var(--lleno)` no
   degrada, se queda TRANSPARENTE y la tarjeta desaparece. Con el @supports,
   el navegador que no lo soporta ni entra y se queda con los hex.

   `in srgb` mezcla canal a canal, que es como se calcularon los hex: las dos
   ramas pintan el mismo pixel. Si algun dia cambian --ambar, --verde, --rojo,
   --violeta o --sup-0, esta rama se recalcula sola pero los hex NO: hay que
   rehacerlos a mano.                                                     */
/* Los rellenos de los dos bloques son hex fijos; aqui se redeclaran como la
   mezcla que en realidad son. Lo que cambia entre claro y oscuro no es la
   formula: son la tinta (--tono-*), la base (--lleno-base) y la carga
   (--lleno-carga). Una sola formula para los dos temas.

   LA LISTA DE SELECTORES ES OBLIGATORIA Y HAY QUE ENTENDER POR QUE. Este
   bloque tiene que ganarle tambien a :root[data-theme="dark"], que lleva
   (0,2,0). Con `:root` a secas llevaria (0,1,0), en oscuro perderia, y los
   hex del bloque oscuro —que son los buenos— seguirian mandando... hasta el
   dia que alguien cambiara --tono-ambar y solo se moviera el claro. No daria
   ningun error.

   Va dentro de @supports por la razon de siempre: un color-mix DENTRO de un
   custom property no admite valor de respaldo. Si el navegador no lo
   entiende, la propiedad se vuelve invalida al calcular y
   `background: var(--lleno)` no degrada, se queda TRANSPARENTE y la tarjeta
   desaparece. Con el @supports, el que no lo soporta ni entra.

   `in srgb` mezcla canal a canal, que es como se calcularon los hex de los
   dos bloques: las dos ramas pintan el mismo pixel. Si algun dia cambian
   --tono-*, --lleno-base o --lleno-carga, esta rama se recalcula sola y los
   hex NO: hay que rehacerlos a mano. Las ORLAS no estan aqui y tampoco lo
   estaban antes: si cambia un tono, las cinco orlas de cada bloque tambien
   se rehacen a mano.                                                     */
@supports (background: color-mix(in srgb, red 45%, blue)) {
  :root,
  :root[data-theme="dark"] {
    --lleno-verde:   color-mix(in srgb, var(--tono-verde)   var(--lleno-carga),   var(--lleno-base));
    --lleno-ambar:   color-mix(in srgb, var(--tono-ambar)   var(--lleno-carga),   var(--lleno-base));
    --lleno-ambar-1: color-mix(in srgb, var(--tono-ambar)   var(--lleno-carga-1), var(--lleno-base));
    --lleno-violeta: color-mix(in srgb, var(--tono-violeta) var(--lleno-carga),   var(--lleno-base));
    --lleno-rojo:    color-mix(in srgb, var(--tono-rojo)    var(--lleno-carga),   var(--lleno-base));
  }
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }

body {
  background: var(--fondo);
  color: var(--txt);
  font-family: var(--sans);
  font-size: 13.5px;
  line-height: 1.55;
  overflow: auto;
  -webkit-font-smoothing: antialiased;
}

.oculto { display: none !important; }
::selection { background: var(--seleccion); }

:where(button, input, select, textarea):focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 1px;
}

* { scrollbar-width: thin; scrollbar-color: var(--rodillo) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--rodillo);
  border-radius: 99px;
  border: 3px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--rodillo-2); background-clip: content-box; }

/* ══ MARCA ═══════════════════════════════════════════════════════════════ */
/* ══ LOGOTIPO ════════════════════════════════════════════════════════════
   La marca de Bailmex, no un dibujo de la consola. Son sus dos colores y no
   se retocan: naranja #E63F0E y azul #013459.

   Y por eso lleva PLACA en oscuro. Ese azul queda a 1.47:1 del fondo oscuro
   —o sea, invisible— y la salida facil seria aclararlo, que es exactamente lo
   que no se hace con un logotipo. La placa es el fondo claro sobre el que la
   marca esta pensada, y ahi el mismo azul da 12.8:1.                       */
.logotipo { display: flex; align-items: center; gap: 9px; flex-shrink: 0; }
.logotipo__marca {
  width: 26px; height: 26px; flex: none;
  object-fit: contain;
  border-radius: var(--r-1);
}
.logotipo__nombre {
  font-size: 14px; font-weight: 600;
  letter-spacing: .13em;
  color: var(--txt);
}
.logotipo--grande { flex-direction: column; gap: 12px; }
.logotipo--grande .logotipo__marca { width: 52px; height: 52px; border-radius: var(--r-2); }
.logotipo--grande .logotipo__nombre { font-size: 19px; letter-spacing: .22em; }

/* Solo [data-theme] y sin @media: el script de arriba resuelve "auto" antes
   del primer pintado y siempre deja escrito light u dark. */
:root[data-theme="dark"] .logotipo__marca {
  background: #FFFFFF;
  padding: 3px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .10);
}

/* ══ CARGANDO ════════════════════════════════════════════════════════════ */
.cargando-pantalla {
  position: fixed; inset: 0; z-index: 80;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 26px;
  background: var(--fondo);
  transition: opacity 260ms ease;
}
.cargando-pantalla.saliendo { opacity: 0; pointer-events: none; }

.cargando-barra {
  width: 160px; height: 2px;
  border-radius: 2px;
  background: var(--linea-2);
  overflow: hidden;
}
.cargando-barra span {
  display: block; width: 40%; height: 100%;
  border-radius: 2px;
  background: var(--acento);
  animation: correr 1.1s ease-in-out infinite;
}
@keyframes correr {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(350%); }
}

/* ══ ENTRADA ═════════════════════════════════════════════════════════════ */
.entrada {
  position: fixed; inset: 0; z-index: 70;
  display: grid; place-items: center;
  padding: 20px;
  background: var(--fondo);
  animation: aparecer 240ms ease both;
}
@keyframes aparecer { from { opacity: 0; } to { opacity: 1; } }

.entrada__panel {
  box-shadow: var(--sombra-carta);
  width: min(360px, 94vw);
  padding: 40px 32px 28px;
  border-radius: var(--r-3);
  border: 1px solid var(--linea);
  background: var(--sup-1);
  text-align: center;
}
.entrada__panel .logotipo { margin-bottom: 32px; }
.entrada__boton { display: flex; justify-content: center; min-height: 44px; }
.entrada__nota { margin: 26px 0 0; font-size: 12px; color: var(--txt-3); line-height: 1.55; }
.entrada__nota b { color: var(--txt-2); font-weight: 500; }
.entrada__error { min-height: 18px; margin: 14px 0 0; font-size: 12.5px; color: var(--rojo); }

/* ══ ARMAZON ═════════════════════════════════════════════════════════════
   Tres franjas: barra, avisos y el marco. El marco a su vez son dos
   columnas: los proyectos y lo que se este mirando de ellos.             */
.app {
  height: 100%;
  display: grid;
  grid-template-rows: var(--barra-alto) auto minmax(0, 1fr);
}

.barra {
  display: flex; align-items: center; gap: 14px;
  padding: 0 14px;
  border-bottom: 1px solid var(--linea);
  background: var(--sup-0);
}

/* Deja de ser solo de movil: en escritorio pliega la columna. */
.barra__menu { display: inline-flex; }

.buscador {
  display: flex; align-items: center; gap: 8px;
  flex: 1;
  max-width: 620px;
  height: 34px;
  padding: 0 11px;
  margin-left: 8px;
  border-radius: var(--r-2);
  border: 1px solid var(--linea-2);
  background: var(--sup-1);
  color: var(--txt-4);
  transition: border-color var(--paso);
}
.buscador:focus-within { border-color: var(--acento-linea); }
.buscador input {
  flex: 1; min-width: 0;
  border: 0; background: transparent; outline: none;
  color: var(--txt); font-family: var(--sans); font-size: 13px;
}
.buscador input::placeholder { color: var(--txt-4); }
.buscador input::-webkit-search-cancel-button { filter: var(--filtro-borrar); }
.buscador kbd {
  flex-shrink: 0;
  padding: 1px 5px;
  border-radius: 4px;
  border: 1px solid var(--linea-2);
  font-family: var(--mono); font-size: 10.5px;
  color: var(--txt-4);
}

.barra__acciones { display: flex; align-items: center; gap: 8px; flex-shrink: 0; margin-left: auto; }

/* ══ BOTONES ═════════════════════════════════════════════════════════════ */
.boton {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 12px;
  border-radius: var(--r-1);
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--txt-2);
  font-family: var(--sans); font-size: 12.5px; font-weight: 500;
  cursor: pointer; white-space: nowrap;
  transition: background var(--paso), border-color var(--paso), color var(--paso);
}
.boton:hover { background: var(--sup-3); border-color: var(--linea-3); color: var(--txt); }
.boton:disabled { opacity: .45; cursor: not-allowed; }

.boton--fuerte,
.boton-solido {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 12px;
  border-radius: var(--r-1);
  background: var(--acento); border: 1px solid var(--acento);
  color: var(--sobre-acento); font-family: var(--sans); font-size: 12.5px; font-weight: 600;
  cursor: pointer; white-space: nowrap;
  transition: background var(--paso), border-color var(--paso);
}
.boton--fuerte:hover,
.boton-solido:hover { background: var(--acento-2); border-color: var(--acento-2); color: var(--sobre-acento); }
.boton-solido:disabled { opacity: .45; cursor: not-allowed; }

.boton--sutil { background: transparent; }
.boton--sutil:hover { background: var(--sup-2); }

.boton--peligro { color: var(--rojo); border-color: var(--rojo-linea); background: var(--rojo-piso); }
.boton--peligro:hover { background: var(--rojo-piso-2); border-color: var(--rojo); color: var(--sobre-rojo); }

.icono-boton {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: var(--r-1);
  border: 1px solid transparent;
  background: transparent;
  color: var(--txt-3);
  cursor: pointer;
  transition: background var(--paso), color var(--paso);
}
.icono-boton:hover { background: var(--sup-2); color: var(--txt); }

/* ══ EL TEMA ═════════════════════════════════════════════════════════════
   La FORMA es la del control que el usuario ya aprobo (Inventario.html,
   linea 413): pista hundida con borde de 1px, radio 9px, padding 3px, tres
   pastillas de radio 7px. La pista es --sup-2 y no --sup-0 porque en el
   archivo aprobado el .topbar es blanco y su pista es --surface-2, o sea "un
   escalon por debajo de la barra"; en BLXBOX la barra ya es --sup-0, asi que
   el escalon de por debajo es --sup-2. Se conserva la RELACION, que es lo
   que se ve, y no el nombre del token.

   Lo ELEGIDO no se marca con un escalon de superficie —el archivo aprobado
   usa una pastilla blanca sobre la pista, y eso solo funciona en claro:
   en oscuro --sup-1 es MAS OSCURO que --sup-2 y la pastilla se hundiria en
   vez de levantarse—. Se marca con la receta que BLXBOX ya tiene para "esto
   es lo elegido" y que funciona igual en los dos temas: piso de acento, filo
   de acento por dentro, tinta de acento. Es literalmente .mini--fuerte y
   .pestana.activo b. Cero reglas especificas de tema.                   */
.tema {
  display: flex; align-items: center; gap: 3px;
  padding: 3px;
  border: 1px solid var(--linea);
  border-radius: 9px;
  background: var(--sup-2);
  flex-shrink: 0;
}
.tema__op {
  display: grid; place-items: center;
  width: 30px; height: 26px;
  padding: 0;
  border: 0; border-radius: 7px;
  background: transparent;
  color: var(--txt-3);
  cursor: pointer;
  transition: background var(--paso), color var(--paso), box-shadow var(--paso);
}
/* Sin esto el e.target del clic es el <path> y no el boton. closest() lo
   resolveria igual, pero es una llamada menos y un fallo menos. */
.tema__op svg { width: 16px; height: 16px; pointer-events: none; }
.tema__op:hover { background: var(--sup-1); color: var(--txt); }
.tema__op[aria-pressed="true"] {
  background: var(--acento-piso);
  box-shadow: inset 0 0 0 1px var(--acento-linea);
  color: var(--acento-2);
}
.tema__op:focus-visible { outline: 2px solid var(--acento); outline-offset: 1px; }

.mini {
  padding: 3px 8px;
  border-radius: 5px;
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--txt-3);
  font-family: var(--sans); font-size: 11.5px;
  cursor: pointer; white-space: nowrap;
  transition: background var(--paso), color var(--paso), border-color var(--paso);
}
.mini:hover { background: var(--sup-3); color: var(--txt); border-color: var(--linea-3); }
.mini--ver { color: var(--acento); border-color: var(--acento-linea); }
.mini--fuerte { background: var(--acento-piso); border-color: var(--acento-linea); color: var(--acento-2); }
.mini--rojo:hover { background: var(--rojo-piso); border-color: var(--rojo-linea-2); color: var(--rojo); }

.cerrar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: var(--r-1);
  border: 1px solid var(--linea-2);
  background: transparent;
  color: var(--txt-3);
  cursor: pointer;
  transition: background var(--paso), color var(--paso);
}
.cerrar:hover { background: var(--rojo-piso); color: var(--rojo); }

/* ══ USUARIO ═════════════════════════════════════════════════════════════ */
.usuario { position: relative; }
.usuario__boton {
  display: flex; align-items: center; gap: 8px;
  height: 34px; padding: 0 9px 0 5px;
  border-radius: var(--r-2);
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  transition: background var(--paso);
}
.usuario__boton:hover { background: var(--sup-2); }
.usuario__inicial {
  display: grid; place-items: center;
  width: 25px; height: 25px;
  border-radius: 50%;
  background: var(--acento-piso);
  border: 1px solid var(--acento-linea);
  color: var(--acento-2);
  font-size: 12px; font-weight: 600; text-transform: uppercase;
}
.usuario__datos { text-align: left; line-height: 1.2; }
.usuario__datos b {
  display: block; font-size: 12px; font-weight: 500; color: var(--txt);
  max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.usuario__datos i { display: block; font-style: normal; font-size: 10.5px; color: var(--txt-4); }

.usuario__menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  width: 232px; padding: 6px;
  border-radius: var(--r-2);
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  box-shadow: var(--sombra-menu);
}
.usuario__menu p {
  margin: 0 0 6px;
  padding: 7px 9px;
  border-bottom: 1px solid var(--linea);
  font-family: var(--mono); font-size: 11px; color: var(--txt-4);
  word-break: break-all;
}
.usuario__menu button {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%;
  padding: 7px 9px;
  border: 0; border-radius: var(--r-1);
  background: transparent;
  color: var(--txt-2);
  font-family: var(--sans); font-size: 12.5px; text-align: left;
  cursor: pointer;
  transition: background var(--paso), color var(--paso);
}
.usuario__menu button:hover { background: var(--sup-3); color: var(--txt); }
.usuario__menu button b {
  font-family: var(--mono); font-size: 11px; font-weight: 500; color: var(--txt-4);
}
.usuario__menu-titulo {
  display: block;
  margin-top: 6px; padding: 8px 9px 4px;
  border-top: 1px solid var(--linea);
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--txt-4);
}
.usuario__salir {
  margin-top: 6px !important;
  border-top: 1px solid var(--linea) !important;
  border-radius: 0 0 var(--r-1) var(--r-1) !important;
  color: var(--rojo) !important;
}
.usuario__salir:hover { background: var(--rojo-piso-2) !important; }

/* ══ AVISOS ══════════════════════════════════════════════════════════════ */
.avisos:empty { display: none; }
.alerta {
  padding: 9px 16px;
  border-bottom: 1px solid var(--ambar-linea);
  background: var(--ambar-piso);
  font-size: 12.5px; color: var(--txt-2);
}
.alerta b { color: var(--ambar); font-weight: 600; }
.alerta--roja { border-bottom-color: var(--rojo-linea); background: var(--rojo-piso); }
.alerta--roja b { color: var(--rojo); }

/* ══ EL MARCO: COLUMNA + CONTENIDO ═══════════════════════════════════════ */
.marco {
  display: grid;
  grid-template-columns: var(--rail-ancho) minmax(0, 1fr);
  min-height: 0;
  position: relative;
}

/* ── La columna de proyectos ──────────────────────────────────────────────
   Es el indice del inventario y no se va nunca. Cada renglon dice, sin
   abrirlo, cuantas llaves guarda el proyecto y que tan critico es.       */
.rail {
  display: flex; flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--linea);
  background: var(--sup-0);
}

.rail__lugares { padding: 10px 8px 8px; display: grid; gap: 2px; }
.rail__lugares button {
  display: flex; align-items: center; gap: 9px;
  width: 100%; height: 32px; padding: 0 9px;
  border: 0; border-radius: var(--r-1);
  background: transparent;
  color: var(--txt-3);
  font-family: var(--sans); font-size: 12.5px; font-weight: 500; text-align: left;
  cursor: pointer;
  transition: background var(--paso), color var(--paso);
}
.rail__lugares button:hover { background: var(--sup-2); color: var(--txt-2); }
.rail__lugares button.activo { background: var(--sup-3); color: var(--txt); }
.rail__lugares button svg { width: 15px; height: 15px; flex-shrink: 0; }
.rail__lugares button.activo svg { color: var(--acento); }
.rail__lugares button span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail__lugares button b {
  font-family: var(--mono); font-size: 10.5px; font-weight: 500; color: var(--txt-4);
}
.rail__lugares button b:empty { display: none; }

.rail__titulo {
  display: flex; align-items: center; justify-content: space-between;
  margin: 4px 0 2px;
  padding: 10px 17px 6px;
  border-top: 1px solid var(--linea);
  font-size: 10px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--txt-4);
}
.rail__titulo b { font-family: var(--mono); font-weight: 500; letter-spacing: 0; }

.rail__lista { flex: 1; min-height: 0; overflow-y: auto; padding: 0 8px 8px; }
.rail__vacio, .rail__error { padding: 18px 10px; font-size: 12px; color: var(--txt-4); text-align: center; }
.rail__error { color: var(--rojo); }

.rail__grupo { margin-bottom: 10px; }
.rail__categoria {
  display: flex; align-items: center; gap: 6px;
  margin: 0 0 3px; padding: 6px 9px;
  border: 1px solid var(--cat-borde, var(--linea));
  border-radius: var(--r-1);
  background: var(--cat-fondo, var(--sup-1));
  font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--txt);
}
.rail__categoria-icono { display: inline-flex; color: var(--cat, var(--txt-4)); }
.rail__categoria-icono svg { width: 12px; height: 12px; }

.proyecto {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) auto 6px;
  align-items: center; gap: 8px;
  width: 100%; height: 31px; padding: 0 9px;
  border: 0; border-radius: var(--r-1);
  background: transparent;
  color: var(--txt-2);
  font-family: var(--sans); font-size: 12.5px; text-align: left;
  cursor: pointer;
  transition: background var(--paso), color var(--paso);
}
.proyecto:hover { background: var(--sup-2); color: var(--txt); }
.proyecto.activo { background: var(--sup-3); color: var(--txt); box-shadow: inset 2px 0 0 var(--cat, var(--acento)); }
.proyecto__icono { display: inline-flex; color: var(--cat, var(--txt-4)); }
.proyecto__icono svg { width: 15px; height: 15px; }
.proyecto__nombre { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proyecto__cuenta {
  font-family: var(--mono); font-size: 10.5px; color: var(--txt-3);
}
.proyecto__cuenta--cero { color: var(--txt-4); }

.crit-punto {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--txt-4); opacity: .5;
}
.crit-punto[data-n="Critico"] { background: var(--rojo); opacity: 1; }
.crit-punto[data-n="Alto"]    { background: var(--ambar); opacity: 1; }
.crit-punto[data-n="Medio"]   { background: var(--azul); opacity: .8; }

.rail__pie { padding: 8px; border-top: 1px solid var(--linea); }
.rail__nuevo {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; height: 30px;
  border-radius: var(--r-1);
  border: 1px dashed var(--linea-3);
  background: transparent;
  color: var(--txt-3);
  font-family: var(--sans); font-size: 12px; font-weight: 500;
  cursor: pointer;
  transition: border-color var(--paso), color var(--paso), background var(--paso);
}
.rail__nuevo:hover { border-color: var(--acento); color: var(--acento); background: var(--acento-piso); }

.rail__velo { display: none; }

/* ── Plegar la columna en escritorio ──────────────────────────────────────
   No se va: se encoge. Un riel que desaparece del todo regala ancho y cobra
   un clic cada vez que hay que cambiar de sitio; uno de 52px deja los seis
   apartados y todos los proyectos a un clic, que es justo lo que el encargo
   no permite perder.

   Todo cuelga de una clase en <body> y de la variable que YA mandaba en el
   ancho: `body.plegado` declara --rail-ancho sobre un ancestro mas cercano
   que :root, asi que gana incluso bajo la media query de 1360px, y la rejilla
   de .marco no se entera de nada. Nada de position:absolute: .rail tiene que
   seguir siendo grid item o .principal se auto-coloca en la columna 1 y la
   consola entera se aplasta a 52px.

   `not all and (max-width:1000px)` y no `min-width:1001px`: es el complemento
   EXACTO de la consulta del cajon, sin el hueco de los anchos fraccionarios
   entre 1000 y 1001 donde no aplicaria ninguna de las dos. Debajo de eso la
   columna es un cajon y esta clase no significa nada.                     */
@media not all and (max-width: 1000px) {
  body.plegado { --rail-ancho: 52px; }

  /* Lo que se va: todo lo que es texto. Lo que se queda: los iconos. */
  .plegado .rail__lugares button span,
  .plegado .rail__lugares button b,
  .plegado .rail__titulo span,
  .plegado .rail__titulo b,
  .plegado .rail__categoria-nombre,
  .plegado .proyecto__nombre,
  .plegado .proyecto__cuenta,
  .plegado .rail__nuevo span,
  .plegado .rail__vacio,
  .plegado .rail__error { display: none; }

  .plegado .rail__lugares { padding: 10px 8px 8px; }
  .plegado .rail__lugares button,
  .plegado .rail__nuevo { justify-content: center; gap: 0; padding: 0; }

  /* El titulo se queda vacio A PROPOSITO: su border-top es el unico separador
     entre los seis apartados y la lista de proyectos, y sin el los dos
     bloques se pegan. Ocultarlo entero se llevaba la linea. */
  .plegado .rail__titulo { padding: 9px 0 5px; }

  /* .proyecto es un GRID, no un flex: justify-content no tendria nada que
     distribuir con una sola pista de 1fr y el icono quedaria pegado a la
     izquierda mientras los seis apartados —esos si flex— quedan centrados.
     Lo que centra un grid item es justify-items. */
  .plegado .rail__lista { padding: 0 4px 8px; }
  .plegado .proyecto {
    position: relative;
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 0; padding: 0;
  }
  /* El punto de criticidad NO se va: es lo unico del renglon que sigue
     contestando algo sin el nombre —si arde—. Se sube a la esquina, que es
     donde cabe; absoluto, asi que sale del flujo de la rejilla. */
  .plegado .crit-punto { position: absolute; top: 4px; right: 4px; }

  .plegado .rail__categoria { justify-content: center; padding: 6px 0; }
  .plegado .rail__pie { padding: 8px 4px; }

  /* El acento del borde izquierdo es lo unico que dice cual esta abierto:
     plegado, tiene que verse mas. */
  .plegado .proyecto.activo { box-shadow: inset 3px 0 0 var(--cat, var(--acento)); }
}


/* ── El area de contenido ─────────────────────────────────────────────── */
.principal { display: flex; flex-direction: column; min-height: 0; min-width: 0; overflow: hidden; }
.vista { position: relative; display: flex; flex-direction: column; min-height: 0; flex: 1; overflow: hidden; }

.lienzo { flex: 1; min-height: 0; overflow-y: auto; padding: 20px 24px 40px; }
/* Alineados a la izquierda, no centrados: el titulo y lo que viene debajo
   empiezan en el mismo borde, y el ojo no tiene que saltar. */
.lienzo__ancho { max-width: 1180px; }
.lienzo__medio { max-width: 940px; }

/* ══ EL PANEL ════════════════════════════════════════════════════════════
   Lo primero que se ve al entrar. Es la unica pantalla que no se parte en
   dos columnas —no hay nada que elegir, es un resumen— pero habla el mismo
   idioma que las demas: renglones densos, la cifra en monoespaciada y el
   color solo donde significa algo.                                       */
.titular { margin-bottom: 20px; }
.titular h1 { margin: 0 0 5px; font-size: 19px; font-weight: 600; letter-spacing: -.015em; }
.titular p { margin: 0; max-width: 640px; font-size: 12.5px; color: var(--txt-3); line-height: 1.6; }

.cifras {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 8px; margin-bottom: 26px; max-width: 860px;
}
.cifra {
  box-shadow: var(--sombra-carta);
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
  gap: 2px 8px;
  padding: 10px 13px;
  border-radius: var(--r-2);
  border: 1px solid var(--linea);
  background: var(--sup-1);
  cursor: pointer; text-align: left;
  transition: border-color var(--paso), background var(--paso);
}
.cifra:hover:not(:disabled) { border-color: var(--linea-3); background: var(--sup-2); }
.cifra:disabled { cursor: default; }
.cifra__icono { grid-column: 2; grid-row: 1 / span 2; display: inline-flex; color: var(--txt-4); }
.cifra__icono svg { width: 16px; height: 16px; }
.cifra b { font-family: var(--mono); font-size: 20px; font-weight: 600; color: var(--txt); line-height: 1.15; }
.cifra__nombre { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--txt-4); }

.tablero__bloque { margin-bottom: 28px; }
.tablero__bloque > h2 {
  display: flex; align-items: center; gap: 9px;
  margin: 0 0 10px;
  font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  color: var(--txt-3);
}
.tablero__bloque > h2 b {
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: 0; color: var(--txt-4);
  padding: 1px 6px; border-radius: 4px; background: var(--sup-2);
}

/* Cada aviso lleva a donde se arregla: constatar el problema y dejar a quien
   lo lee buscando la pantalla a mano no es avisar, es quejarse. */
.revisar { display: grid; gap: 6px; max-width: 1000px; }
.revisar__fila {
  box-shadow: var(--sombra-carta);
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  width: 100%;
  padding: 10px 13px;
  border: 1px solid var(--linea);
  border-left: 3px solid var(--txt-4);
  border-radius: var(--r-2);
  background: var(--sup-1);
  color: inherit; font-family: var(--sans); text-align: left;
  cursor: pointer;
  transition: background var(--paso), border-color var(--paso);
}
.revisar__fila:hover { background: var(--sup-2); border-color: var(--linea-2); }
.revisar__fila[data-tono="rojo"]  { border-left-color: var(--rojo); }
.revisar__fila[data-tono="ambar"] { border-left-color: var(--ambar); }
.revisar__fila[data-tono="azul"]  { border-left-color: var(--azul); }
.revisar__texto { min-width: 0; }
.revisar__texto b { display: block; font-size: 13px; font-weight: 600; color: var(--txt); }
.revisar__texto span { display: block; margin-top: 1px; font-size: 12px; color: var(--txt-3); }
.revisar__accion {
  display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0;
  font-size: 11.5px; color: var(--txt-4);
  transition: color var(--paso);
}
.revisar__fila:hover .revisar__accion { color: var(--acento); }

.grupo-titulo {
  display: flex; align-items: center; gap: 7px;
  margin: 16px 0 6px; padding: 6px 10px;
  border: 1px solid var(--cat-borde, var(--linea));
  border-radius: var(--r-1);
  background: var(--cat-fondo, var(--sup-1));
  font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt);
}
.grupo-titulo:first-child { margin-top: 0; }
.grupo-titulo svg { width: 13px; height: 13px; color: var(--cat, var(--txt-4)); }
.grupo-titulo b {
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: 0; color: var(--txt-4);
}

/* Renglones y no tarjetas: en tarjeta, comparar dos proyectos obliga a
   saltar la vista de una a otra para leer el mismo numero dos veces. En
   columna se lee de arriba abajo y se ve solo quien guarda mucho. */
.filas-proy { display: grid; gap: 3px; max-width: 1000px; }
.fila-proy {
  box-shadow: var(--sombra-carta);
  display: grid;
  grid-template-columns: 28px minmax(120px, 1fr) minmax(0, 1.5fr) auto 62px;
  align-items: center; gap: 12px;
  padding: 7px 10px;
  border: 1px solid transparent;
  border-radius: var(--r-1);
  background: var(--sup-1);
  color: var(--txt-2);
  font-family: var(--sans); font-size: 13px; text-align: left;
  cursor: pointer;
  transition: background var(--paso), border-color var(--paso);
}
.fila-proy:hover { background: var(--sup-2); border-color: var(--linea); }
.fila-proy__icono {
  display: grid; place-items: center;
  width: 28px; height: 28px;
  border-radius: 7px;
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--cat, var(--txt-3));
}
.fila-proy__icono svg { width: 15px; height: 15px; }
.fila-proy__nombre {
  display: flex; align-items: center; gap: 7px; min-width: 0;
  font-size: 13px; font-weight: 600; color: var(--txt);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fila-proy__sub {
  font-size: 12px; color: var(--txt-4);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fila-proy__cuentas {
  display: flex; gap: 11px;
  font-family: var(--mono); font-size: 11px; color: var(--txt-4);
}
.fila-proy__cuentas span { display: inline-flex; align-items: center; gap: 4px; }
.fila-proy__cuentas svg { width: 12px; height: 12px; opacity: .8; }
.fila-proy__cuentas .llena { color: var(--txt-2); }
.fila-proy .crit { justify-self: end; }

.punto {
  display: inline-block; flex-shrink: 0;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--txt-4);
}
.punto--op { background: var(--verde); }

.crit {
  padding: 2px 7px;
  border-radius: 4px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--txt-4);
}
.crit[data-n="Critico"] { color: var(--rojo);  background: var(--rojo-piso); }
.crit[data-n="Alto"]    { color: var(--ambar); background: var(--ambar-piso); }
.crit[data-n="Medio"]   { color: var(--acento-2);  background: var(--acento-piso); }
.crit[data-n="Bajo"]    { color: var(--txt-4); background: transparent; }

/* ══ FILA DE DATOS ═══════════════════════════════════════════════════════
   El resumen de arriba de la bitacora: cuatro cifras en una linea.      */
.datos-fila {
  display: flex; flex-wrap: wrap; gap: 22px;
  padding: 11px 24px;
  border-bottom: 1px solid var(--linea);
  background: var(--sup-0);
}
.dato { display: flex; flex-direction: column; gap: 1px; }
.dato span { font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase; color: var(--txt-4); }
.dato b { font-size: 12.5px; font-weight: 500; color: var(--txt); }
.dato[data-crit="Critico"] b { color: var(--rojo); }
.dato[data-crit="Alto"] b    { color: var(--ambar); }
.dato[data-estado="Operativo"] b { color: var(--verde); }

/* ══ CONTENIDO DE LOS PANELES ════════════════════════════════════════════
   Lo que se pinta dentro de los modales: la induccion, el editor, quien
   entra, las categorias y la bitacora.                                  */
.bloque { margin-bottom: 24px; }
.bloque:last-child { margin-bottom: 0; }
.bloque > h3,
.bloque__titulo {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 10px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  color: var(--txt-3);
}
.bloque__icono { display: inline-flex; color: var(--acento); }
.bloque__icono svg { width: 14px; height: 14px; }
.bloque__titulo b {
  padding: 1px 6px; border-radius: 4px; background: var(--sup-2);
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: 0; color: var(--txt-4);
}
.bloque p { margin: 0 0 9px; color: var(--txt-2); font-size: 13.5px; line-height: 1.62; }
.bloque p:last-child { margin-bottom: 0; }

.tarjeta {
  box-shadow: var(--sombra-carta);
  margin-bottom: 9px;
  border-radius: var(--r-2);
  border: 1px solid var(--linea);
  background: var(--sup-1);
  overflow: hidden;
}
.tarjeta:last-child { margin-bottom: 0; }
.tarjeta > h4 { margin: 0; padding: 11px 14px; font-size: 13px; font-weight: 600; border-bottom: 1px solid var(--linea); }
.tarjeta > .pasos, .tarjeta > .checklist { padding: 6px 14px 10px; }
.tarjeta > p { margin: 0; padding: 12px 14px; }

.nota-info, .nota-seg {
  display: flex; gap: 9px;
  margin-bottom: 14px; padding: 10px 13px;
  border-radius: var(--r-2);
  font-size: 12.5px; line-height: 1.55;
}
.nota-info { border: 1px solid var(--acento-linea); background: var(--acento-piso); }
.nota-seg  { border: 1px solid var(--ambar-linea); background: var(--ambar-piso); }
.nota-info svg, .nota-seg svg { flex-shrink: 0; width: 16px; height: 16px; margin-top: 1px; }
.nota-info svg { color: var(--acento); }
.nota-seg svg  { color: var(--ambar); }
.nota-info p, .nota-seg p { margin: 0; color: var(--txt-2); }
.nota-info b { color: var(--acento-2); font-weight: 600; }
.nota-seg b  { color: var(--ambar); font-weight: 600; }

.sello {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 4px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .04em;
  white-space: nowrap;
}
.sello--secreta { color: var(--rojo);  background: var(--rojo-piso); }
.sello--publica { color: var(--verde); background: var(--verde-piso); }
.sello--alerta  { color: var(--ambar); background: var(--ambar-piso); }

/* ── Listas de pasos ─────────────────────────────────────────────────────── */
.pasos { list-style: none; margin: 0; padding: 0; counter-reset: paso; }
.pasos li {
  position: relative;
  padding: 8px 0 8px 30px;
  border-bottom: 1px solid var(--linea);
  font-size: 13px; color: var(--txt-2); line-height: 1.6;
  counter-increment: paso;
}
.pasos li:last-child { border-bottom: 0; }
.pasos li::before {
  content: counter(paso);
  position: absolute; left: 0; top: 9px;
  display: grid; place-items: center;
  width: 19px; height: 19px;
  border-radius: 50%;
  background: var(--sup-3);
  font-family: var(--mono); font-size: 10px; color: var(--txt-3);
}

.checklist { list-style: none; margin: 0; padding: 0; }
.checklist li {
  position: relative;
  padding: 7px 0 7px 24px;
  border-bottom: 1px solid var(--linea);
  font-size: 13px; color: var(--txt-2);
}
.checklist li:last-child { border-bottom: 0; }
.checklist li::before {
  content: ''; position: absolute; left: 3px; top: 13px;
  width: 6px; height: 6px; border-radius: 2px;
  background: var(--acento);
}

.tabla { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.tabla th {
  padding: 8px 10px;
  border-bottom: 1px solid var(--linea-2);
  text-align: left;
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-4);
}
.tabla td { padding: 9px 10px; border-bottom: 1px solid var(--linea); color: var(--txt-2); }
.tabla tr:last-child td { border-bottom: 0; }
.tabla td:first-child { color: var(--txt); }
.tabla select {
  padding: 3px 6px;
  border-radius: 5px;
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--txt-2);
  font-family: var(--sans); font-size: 11.5px;
}
.tabla .fila-inactiva td { opacity: .75; }
.tabla .fila-delicada td { color: var(--rojo); }
.tabla--fija { table-layout: fixed; }
.tabla--fija td { word-break: break-word; }

.etiquetas { display: flex; flex-wrap: wrap; gap: 5px; }
.etiqueta {
  padding: 2px 8px;
  border-radius: 99px;
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  font-size: 11.5px; color: var(--txt-3);
}

.enlace { color: var(--acento); text-decoration: none; }
.enlace:hover { text-decoration: underline; }
.pista { margin-top: 9px; font-size: 12px; color: var(--txt-4); }
.cargando { padding: 28px; text-align: center; color: var(--txt-4); font-size: 12.5px; }
.vacio-linea { color: var(--txt-4); font-style: italic; }

.vacio-caja {
  padding: 34px 22px;
  border-radius: var(--r-2);
  border: 1px dashed var(--linea-2);
  text-align: center;
}
.vacio-caja p { margin: 0 0 5px; font-size: 13.5px; color: var(--txt-2); }
.vacio-caja small { display: block; max-width: 460px; margin: 0 auto; font-size: 12px; color: var(--txt-4); line-height: 1.6; }

/* ══ INDUCCION ═══════════════════════════════════════════════════════════ */
.ruta { list-style: none; margin: 0 0 20px; padding: 0; }
.ruta li { display: flex; gap: 13px; padding: 11px 0; border-bottom: 1px solid var(--linea); }
.ruta li:last-child { border-bottom: 0; }
.ruta__n {
  flex-shrink: 0;
  display: grid; place-items: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 1px solid var(--acento-linea);
  background: var(--acento-piso);
  font-family: var(--mono); font-size: 11px; color: var(--acento);
}
.ruta h4 { margin: 3px 0 2px; font-size: 13px; font-weight: 600; }
.ruta p { margin: 0; font-size: 12.5px; color: var(--txt-3); }

.reglas { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.reglas li {
  padding: 9px 12px;
  border-radius: var(--r-1);
  border-left: 2px solid var(--acento-linea);
  background: var(--sup-1);
  font-size: 12.5px; color: var(--txt-2);
}


/* ══ FILTROS Y PAGINADOR ═════════════════════════════════════════════════ */
.filtros {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 11px 24px;
  border-bottom: 1px solid var(--linea);
  background: var(--sup-0);
  flex-shrink: 0;
}
.filtros__select {
  height: 27px;
  padding: 0 8px;
  border-radius: var(--r-1);
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--txt-2);
  font-family: var(--sans); font-size: 12px;
  cursor: pointer; max-width: 220px;
}
.filtros__select:disabled { opacity: .4; cursor: not-allowed; }
.filtros__select--corto { max-width: 140px; }

/* La bitacora tiene su propia caja de buscar: vive dentro de un modal, y la
   de la barra de arriba busca en la pantalla de atras. */
.filtros__buscar {
  display: flex; align-items: center; gap: 7px;
  flex: 1; min-width: 180px; max-width: 340px;
  height: 27px; padding: 0 10px;
  border-radius: var(--r-1);
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--txt-4);
  transition: border-color var(--paso);
}
.filtros__buscar:focus-within { border-color: var(--acento-linea); }
.filtros__buscar input {
  flex: 1; min-width: 0;
  border: 0; background: transparent; outline: none;
  color: var(--txt); font-family: var(--sans); font-size: 12.5px;
}
.filtros__buscar input::placeholder { color: var(--txt-4); }

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  height: 27px; padding: 0 10px;
  border-radius: 99px;
  border: 1px solid var(--linea-2);
  background: transparent;
  color: var(--txt-3);
  font-family: var(--sans); font-size: 12px;
  cursor: pointer; white-space: nowrap;
  transition: border-color var(--paso), color var(--paso), background var(--paso);
}
.chip:hover { border-color: var(--linea-3); color: var(--txt-2); }
.chip.activo { background: var(--sup-alta); border-color: var(--linea-3); color: var(--txt); }
.chip b {
  font-family: var(--mono); font-size: 10.5px; font-weight: 500; color: var(--txt-4);
}
.chip.activo b { color: var(--txt-2); }

.paginador {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px;
  padding: 11px 24px;
  border-top: 1px solid var(--linea);
  background: var(--sup-0);
  flex-shrink: 0;
}
.paginador:empty { display: none; }
.paginador__cuenta { font-size: 12px; color: var(--txt-4); }
.paginador__cuenta b { color: var(--txt-2); font-weight: 600; }
.paginador__botones { display: flex; align-items: center; gap: 3px; flex-wrap: wrap; }
.paginador__botones .mini:disabled { opacity: .35; cursor: not-allowed; }
.paginador__salto { color: var(--txt-4); padding: 0 3px; }

.bit-icono { display: inline-block; width: 15px; opacity: .55; margin-right: 4px; }

/* ══ LISTA Y DETALLE ═════════════════════════════════════════════════════
   El armazon de las cuatro pantallas: a la izquierda el indice —una linea
   por cosa, todo a la vista— y a la derecha lo que guarda la elegida.

   Antes cada renglon era una rejilla de seis columnas: icono, nombre,
   proyecto, usuario, pastilla del MFA, estado del secreto y dos botones.
   Dos de esas columnas decian casi siempre lo mismo, y para leer una fila
   habia que atravesar las otras trece. Lo que se repite se dice una vez en
   el encabezado del grupo; lo que solo importa de una, se dice entero a la
   derecha, con sitio de sobra.

   El indice mide 420px porque es lo que cabe del nombre mas largo del
   inventario sin cortarlo. Mas ancho le quita sitio al panel; mas angosto
   convierte la lista en una columna de puntos suspensivos.               */
.division {
  display: grid;
  grid-template-columns: 420px minmax(0, 1fr);
  flex: 1; min-height: 0;
}

.lista {
  display: flex; flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--linea);
  background: var(--sup-0);
}

/* ── La cabecera del proyecto, encima de su indice ─────────────────────── */
.lista__proyecto {
  display: flex; align-items: center; gap: 4px;
  padding: 8px 10px 8px 8px;
  border-bottom: 1px solid var(--linea);
  flex-shrink: 0;
}
.lista__proyecto-btn {
  display: flex; align-items: center; gap: 10px;
  flex: 1; min-width: 0;
  padding: 4px 6px;
  border: 0; border-radius: var(--r-1);
  background: transparent; color: inherit;
  font-family: var(--sans); text-align: left;
  cursor: pointer;
  transition: background var(--paso);
}
.lista__proyecto-btn:hover { background: var(--sup-2); }
.lista__proyecto-btn.activo { background: var(--sup-3); }
.lista__proyecto-icono {
  display: grid; place-items: center;
  width: 30px; height: 30px; flex-shrink: 0;
  border-radius: 8px;
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--cat, var(--acento));
}
.lista__proyecto-icono svg { width: 16px; height: 16px; }
.lista__proyecto-id { min-width: 0; }
.lista__proyecto-id b {
  display: block; font-size: 14px; font-weight: 600; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lista__proyecto-id i {
  display: block; font-style: normal; font-size: 11.5px; color: var(--txt-4);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lista__proyecto-acciones { display: flex; gap: 2px; flex-shrink: 0; }

/* ── La cabecera de un apartado suelto ─────────────────────────────────────
   Las cuentas de usuario y las redes WiFi se dan de alta aqui y no desde el
   editor de un proyecto, porque no cuelgan de ninguno. El boton vive pegado
   a la lista que modifica: es donde se busca cuando hace falta, y no en la
   barra de arriba, que es de toda la consola. */
.lista__barra {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 11px 12px 10px;
  border-bottom: 1px solid var(--linea);
  flex-shrink: 0;
}
.lista__barra > b {
  font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  font-weight: 600; color: var(--txt-4);
}
.lista__nuevo {
  display: inline-flex; align-items: center; gap: 6px;
  height: 27px; padding: 0 10px;
  border: 1px solid var(--acento-linea); border-radius: var(--r-1);
  background: var(--acento-piso);
  color: var(--acento);
  font-family: var(--sans); font-size: 12px; font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--paso), border-color var(--paso), color var(--paso);
}
.lista__nuevo:hover { background: var(--acento); border-color: var(--acento); color: var(--sobre-acento); }

/* ── Los filtros del indice ────────────────────────────────────────────── */
.lista__filtro {
  display: flex; flex-direction: column; gap: 7px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--linea);
  flex-shrink: 0;
}
.lista__filtro:empty { display: none; }

/* Se acomodan en varias lineas en vez de irse de largo: un chip cortado a
   la mitad se lee como un error, y una barra que hay que arrastrar esconde
   justo lo que estos chips vienen a enseñar — cuantos hay de cada cosa. */
.chips { display: flex; flex-wrap: wrap; gap: 4px; }

.lista__filtro-fila { display: flex; align-items: center; gap: 6px; }
.lista__filtro > .mini { align-self: flex-start; }
.lista__filtro-fila .filtros__select { flex: 1; min-width: 0; }
.lista__cuenta {
  font-family: var(--mono); font-size: 11px; color: var(--txt-4);
  margin-left: auto; white-space: nowrap;
}

.lista__cuerpo { flex: 1; min-height: 0; overflow-y: auto; padding: 2px 8px 16px; }
.lista__vacio { padding: 14px 4px; }

.lista__pie {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px;
  padding: 8px 12px;
  border-top: 1px solid var(--linea);
  background: var(--sup-0);
  flex-shrink: 0;
}
.lista__pie:empty { display: none; }
.lista__pie .paginador__cuenta { font-size: 11.5px; }

/* El encabezado se queda pegado arriba mientras se recorre el grupo:
   siempre se sabe de que servicio, o de que proyecto, es lo que se lee. */
.lista__grupo {
  position: sticky; top: 0; z-index: 4;
  display: flex; align-items: center; gap: 7px;
  margin: 0; padding: 12px 8px 5px;
  background: var(--sup-0);
  font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-4);
}
.lista__grupo-icono { display: inline-flex; color: var(--cat, var(--txt-4)); }
.lista__grupo-icono svg { width: 13px; height: 13px; }
.lista__grupo b {
  font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0;
  color: var(--txt-4);
}
/* Lo que dicen todas las filas del grupo se dice aqui una vez. */
.lista__grupo-nota { margin-left: auto; color: var(--txt-4); text-transform: none; letter-spacing: 0; }

/* ── Un renglon ────────────────────────────────────────────────────────── */
.item {
  display: grid; grid-template-columns: 15px minmax(0, 1fr) auto;
  align-items: center; gap: 9px;
  width: 100%; height: 34px; padding: 0 8px;
  border: 0; border-radius: var(--r-1);
  background: transparent;
  color: var(--txt-2);
  font-family: var(--sans); font-size: 12.5px; text-align: left;
  cursor: pointer;
  transition: background var(--paso), color var(--paso);
}
.item:hover { background: var(--sup-1); color: var(--txt); }
.item.activo { background: var(--sup-3); color: var(--txt); box-shadow: inset 2px 0 0 var(--acento); }
.item__icono { display: inline-flex; color: var(--txt-4); }
.item__icono svg { width: 15px; height: 15px; }
.item.activo .item__icono { color: var(--acento); }
.item__nombre { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item__nombre.mono { font-family: var(--mono); font-size: 11.5px; }
.item__apunte {
  font-style: normal; font-size: 11px; color: var(--txt-4);
  max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.item__punto { width: 7px; height: 7px; border-radius: 50%; background: var(--cat, var(--txt-4)); }

/* El nombre en ambar quiere decir que hay algo que revisar ahi. El punto
   sigue significando UNA cosa —de que proyecto es— porque el naranja de una
   categoria y el ambar de una alerta son casi el mismo color, y un punto
   que significa dos cosas no significa ninguna. */
.item.aviso .item__nombre { color: var(--ambar); }
.item.aviso .item__icono  { color: var(--ambar); opacity: .75; }

/* ══ EL PANEL DE LA DERECHA ══════════════════════════════════════════════ */
.detalle { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }

.detalle__cabecera {
  display: flex; align-items: flex-start; gap: 13px;
  padding: 20px 26px 16px;
  border-bottom: 1px solid var(--linea);
  flex-shrink: 0;
}
.detalle__volver { display: none; }
.detalle__icono {
  display: grid; place-items: center;
  width: 40px; height: 40px; flex-shrink: 0;
  border-radius: var(--r-2);
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--cat, var(--acento));
}
.detalle__icono svg { width: 20px; height: 20px; }
.detalle__id { flex: 1; min-width: 0; }
.detalle__sobre {
  margin: 0 0 2px;
  font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--txt-4);
}
.detalle__id h2 {
  margin: 0; font-size: 19px; font-weight: 600; letter-spacing: -.015em;
  word-break: break-word;
}
.detalle__id h2.mono { font-family: var(--mono); font-size: 16px; letter-spacing: 0; }
.detalle__chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.detalle__botones { display: flex; align-items: center; gap: 6px; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }

.pastilla {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px;
  border-radius: 99px;
  border: 1px solid transparent;
  background: var(--sup-2);
  color: var(--txt-3);
  font-family: var(--sans); font-size: 12px;
}
.pastilla i { width: 6px; height: 6px; border-radius: 50%; background: var(--cat, var(--txt-4)); }
.pastilla--enlace { cursor: pointer; transition: color var(--paso), border-color var(--paso); }
.pastilla--enlace:hover { color: var(--txt); border-color: var(--linea-3); }
.pastilla--aviso { background: var(--ambar-piso); color: var(--ambar); }
/* Alguien esta esperando. Es el violeta de su tarjeta de cifra: si el color
   de arriba y el de abajo no son el mismo, el color no localiza nada. */
.pastilla--pet   { background: var(--violeta-piso); color: var(--violeta); }
.pastilla--roja  { background: var(--rojo-piso); color: var(--rojo); }
.pastilla--verde { background: var(--verde-piso); color: var(--verde); }
.pastilla[data-crit="Critico"] { background: var(--rojo-piso); color: var(--rojo); }
.pastilla[data-crit="Alto"]    { background: var(--ambar-piso); color: var(--ambar); }

.detalle__cuerpo { flex: 1; min-height: 0; overflow-y: auto; padding: 2px 26px 32px; }

.detalle__dato { padding: 13px 0; border-bottom: 1px solid var(--linea); }
.detalle__dato:last-child { border-bottom: 0; }
.detalle__etiqueta {
  display: block; margin-bottom: 5px;
  font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--txt-4);
}
.detalle__linea { display: flex; align-items: center; gap: 10px; }
.detalle__linea > .mini,
.detalle__linea > .boton-alto,
.detalle__linea > a.mini { flex-shrink: 0; }
.detalle__valor {
  flex: 1; min-width: 0;
  font-family: var(--mono); font-size: 12.5px; color: var(--txt-2);
  word-break: break-word;
}
.detalle__valor a { color: var(--acento); text-decoration: none; }
.detalle__valor a:hover { text-decoration: underline; }
.detalle__valor--texto { font-family: var(--sans); font-size: 13px; line-height: 1.6; color: var(--txt-2); }
.detalle__valor--vacio { font-family: var(--sans); font-size: 12.5px; color: var(--txt-4); }
/* Tapado. Al revelarlo, enlazarRevelar quita esta clase y el valor se lee
   como cualquier otro dato monoespaciado. */
.detalle__valor.secreto { letter-spacing: .18em; color: var(--txt-4); }

/* Donde falta algo, el panel ofrece el arreglo en vez de solo constatar
   el hueco. */
.boton-alto {
  display: inline-flex; align-items: center; gap: 7px;
  height: 32px; padding: 0 13px;
  border: 0; border-radius: var(--r-1);
  background: var(--acento);
  color: var(--sobre-acento);
  font-family: var(--sans); font-size: 12.5px; font-weight: 600;
  cursor: pointer;
  transition: filter var(--paso);
}
.boton-alto:hover { filter: var(--realce-2); }

.detalle__previa {
  display: block; width: 100%;
  margin: 16px 0 2px; padding: 0;
  border: 1px solid var(--linea);
  border-radius: var(--r-2);
  background: var(--sup-0);
  cursor: pointer; overflow: hidden;
}
/* Una imagen chica no se estira: se queda de su tamaño, centrada. */
.detalle__previa img { display: block; max-width: 100%; max-height: 320px; margin: 0 auto; }

.detalle__nota {
  margin: 18px 0 0; padding: 11px 13px;
  border-radius: var(--r-2);
  border: 1px solid var(--linea);
  background: var(--sup-1);
  font-size: 12.5px; color: var(--txt-3); line-height: 1.6;
}
.detalle__nota b { color: var(--txt-2); font-weight: 600; }

/* Sin nada elegido no se dice "vacío": se dice para que sirve la columna. */
.detalle__nada {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 9px;
  height: 100%; padding: 30px;
  text-align: center;
}
.detalle__nada svg { width: 34px; height: 34px; color: var(--txt-4); opacity: .45; }
.detalle__nada b { font-size: 14px; font-weight: 600; color: var(--txt-2); }
.detalle__nada span { max-width: 400px; font-size: 12.5px; color: var(--txt-4); line-height: 1.65; }

/* ── Soltar archivos encima del proyecto ───────────────────────────────────
   Sustituye al cuadro punteado que ocupaba pantalla todo el tiempo para una
   accion que se hace una vez al mes: solo aparece mientras se arrastra. */
.soltando {
  /* Fija y no absoluta: vive al nivel de la consola, no dentro de la pantalla
     del proyecto, porque tambien se sube desde el archivero.

     Y transparente al raton: como ya no esta DENTRO de la pantalla del
     proyecto, si atrapara el puntero se quedaria con el `drop` y los archivos
     que alguien suelta encima no llegarian a subirse — el aviso de "suelta
     aqui" impidiendo justo eso. */
  pointer-events: none;
  position: fixed; inset: 0; z-index: 55;
  display: grid; place-items: center;
  background: var(--velo-soltar);
}
.soltando p {
  margin: 0; padding: 18px 26px;
  border-radius: var(--r-3);
  border: 1px dashed var(--acento-linea);
  background: var(--acento-piso);
  color: var(--acento-2);
  font-size: 13.5px; font-weight: 500;
}

/* ══ CAPAS Y PANELES ═════════════════════════════════════════════════════ */
.capa { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 24px; }
/* La ficha del equipo es el unico modal desde el que se abre OTRO modal:
   Editar y Levantar peticion abren #ficha. Dos .capa con el mismo z-index
   las ordena quien aparezca antes en el HTML, y eso deja de ser cierto el
   dia que alguien mueve un bloque. Un 58 explicito no depende de nada, y
   por id (1,0,0) contra clase (0,1,0) tampoco del orden del archivo.
   58 esta libre: .soltando 55, .capa 60, .entrada 70, .visor 75. */
#equipo,
/* Los tres catalogos de admin tienen el mismo problema y por eso la misma
   receta: desde cada uno se abre la ficha de una fila, que es #ficha. Los dos
   son .capa con z-index 60, asi que sin esto mandaria el ORDEN DEL HTML — y
   #accesos y #categorias van DESPUES de #ficha, o sea que la ficha se abriria
   detras del modal que la abrio. Se ve como que "no pasa nada al pulsar
   editar". */
#accesos,
#categorias,
#servicios { z-index: 58; }
.capa__fondo {
  position: absolute; inset: 0;
  background: var(--velo);
  backdrop-filter: blur(2px);
}

.panel {
  position: relative;
  display: flex; flex-direction: column;
  width: min(880px, 100%);
  max-height: min(90vh, 860px);
  border-radius: var(--r-3);
  border: 1px solid var(--linea-2);
  background: var(--sup-1);
  box-shadow: var(--sombra-panel);
  overflow: hidden;
  animation: subir 200ms cubic-bezier(.2,.9,.3,1) both;
}
@keyframes subir { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.panel--ancho  { width: min(1160px, 100%); max-height: min(92vh, 900px); }
.panel--angosto{ width: min(600px, 100%); }

.panel__cabecera {
  display: flex; align-items: flex-start; gap: 13px;
  padding: 16px 20px 14px;
  border-bottom: 1px solid var(--linea);
}
.panel__icono {
  display: grid; place-items: center;
  width: 38px; height: 38px; flex-shrink: 0;
  border-radius: var(--r-2);
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--acento);
}
.panel__icono svg { width: 20px; height: 20px; }
.panel__id { flex: 1; min-width: 0; }
.panel__sobretitulo {
  margin: 0 0 1px;
  font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--txt-4);
}
.panel__id h2 { margin: 0; font-size: 17px; font-weight: 600; letter-spacing: -.01em; }
.panel__sub { margin: 2px 0 0; font-size: 12.5px; color: var(--txt-3); }
.panel__botones { display: flex; align-items: center; gap: 7px; flex-shrink: 0; }

.panel__contenido { padding: 20px; overflow-y: auto; flex: 1; min-height: 0; }

.panel__pie {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 20px;
  border-top: 1px solid var(--linea);
  background: var(--sup-0);
}
.estado-linea, .editor__estado { flex: 1; font-size: 12px; color: var(--txt-3); }
.estado-linea.error, .editor__estado.error { color: var(--rojo); }
.estado-linea.ok, .editor__estado.ok { color: var(--verde); }

/* ══ VISTA PREVIA DE UN .env ═════════════════════════════════════════════ */
.previa {
  border-radius: var(--r-1);
  border: 1px solid var(--linea);
  overflow: hidden;
}
.previa__fila {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1.2fr);
  align-items: center; gap: 10px;
  padding: 6px 11px;
  border-bottom: 1px solid var(--linea);
  background: var(--sup-1);
}
.previa__fila:last-child { border-bottom: 0; }
.previa__fila code {
  font-family: var(--mono); font-size: 11.5px; color: var(--txt);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.previa__valor {
  font-family: var(--mono); font-size: 11.5px; color: var(--txt-4);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.previa__valor i { font-style: normal; opacity: .7; }

/* ══ EDITOR ══════════════════════════════════════════════════════════════ */
.campos { display: grid; grid-template-columns: repeat(2, 1fr); gap: 11px; margin-bottom: 11px; }
/* ── El selector de iconos ────────────────────────────────────────────────
   Se abarca de un vistazo o no sirve: veintiocho cuadros de 34px caben en
   cuatro renglones en la ficha angosta y en dos a lo ancho del editor. Por
   eso envuelve con flex-wrap y no con un numero fijo de columnas: con
   columnas fijas, una de las dos quedaria apretada o con celdas vacias. */
.iconos {
  display: flex; flex-wrap: wrap; gap: 4px;
  padding: 6px;
  border: 1px solid var(--linea); border-radius: var(--r-1);
  background: var(--sup-1);
}
.iconos__op {
  display: grid; place-items: center;
  width: 34px; height: 32px;
  border: 1px solid transparent; border-radius: var(--r-1);
  background: transparent; color: var(--txt-3);
  cursor: pointer;
  transition: background var(--paso), color var(--paso), border-color var(--paso);
}
/* Sin esto, el e.target del clic es el <path> y no el boton. closest() lo
   resolveria igual, pero es una llamada menos y un fallo menos. */
.iconos__op svg { width: 17px; height: 17px; pointer-events: none; }
.iconos__op:hover { background: var(--sup-3); color: var(--txt); }

/* El elegido es el UNICO con color. Veintiocho iconos de acento serian
   veintiocho cosas importantes, que es lo mismo que ninguna. */
.iconos__op.activo {
  background: var(--acento-piso);
  border-color: var(--acento-linea);
  color: var(--acento);
}
.iconos__op:focus-visible { outline: 2px solid var(--acento); outline-offset: 1px; }

.iconos__pie b { font-family: var(--mono); font-weight: 500; color: var(--txt-2); }

/* Un campo que ocupa las dos columnas de .campos: la rejilla no cabe en
   media, y un campo de 120px de alto junto a un <input> de 32 parte el
   renglon en dos alturas distintas. */
.campo-form--ancho { grid-column: 1 / -1; }

.campo-form { display: flex; flex-direction: column; gap: 4px; }
.campo-form > label {
  font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--txt-4);
}
.campo-form input,
.campo-form select,
.campo-form textarea {
  width: 100%;
  padding: 7px 10px;
  border-radius: var(--r-1);
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--txt);
  font-family: var(--sans); font-size: 13px;
  outline: none;
  transition: border-color var(--paso);
}
.campo-form textarea { min-height: 74px; line-height: 1.6; }
.campo-form input:focus, .campo-form select:focus, .campo-form textarea:focus { border-color: var(--acento-linea); }
.campo-form small { font-size: 11.5px; color: var(--txt-4); line-height: 1.5; }
.campo-form input.mono, .campo-form textarea.mono, input.mono, textarea.mono { font-family: var(--mono); font-size: 12.5px; }
.campo-form textarea.soltando { border-color: var(--acento); background: var(--acento-piso); }

.grupo {
  margin-bottom: 22px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--linea);
}
.grupo:last-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }
.grupo > h3 {
  margin: 0 0 11px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  color: var(--txt-3);
}
.grupo__nota { margin: -6px 0 12px; font-size: 12px; color: var(--txt-4); line-height: 1.55; }
.grupo__nota b { color: var(--txt-3); }

.fila {
  position: relative;
  margin-bottom: 10px; padding: 13px;
  border-radius: var(--r-2);
  border: 1px solid var(--linea);
  background: var(--sup-0);
}
.fila__quitar {
  position: absolute; top: 9px; right: 9px;
  display: grid; place-items: center;
  width: 22px; height: 22px;
  border-radius: 5px;
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--txt-4);
  cursor: pointer;
  transition: background var(--paso), color var(--paso);
}
.fila__quitar:hover { background: var(--rojo-piso); color: var(--rojo); }
.fila--cargada { border-color: var(--acento-linea); }

.agregar {
  width: 100%;
  padding: 9px;
  border-radius: var(--r-1);
  border: 1px dashed var(--linea-3);
  background: transparent;
  color: var(--txt-3);
  font-family: var(--sans); font-size: 12.5px;
  cursor: pointer;
  transition: border-color var(--paso), color var(--paso);
}
.agregar:hover { border-color: var(--acento); color: var(--acento); }

.marca {
  display: flex; align-items: center; gap: 7px;
  margin-top: 6px;
  font-size: 12px; color: var(--txt-3);
  cursor: pointer;
}
.marca input { width: auto; accent-color: var(--acento); cursor: pointer; }
.marca:hover { color: var(--txt-2); }
.marca b { color: var(--txt-2); font-weight: 500; }

.importar {
  display: flex; align-items: center; gap: 11px;
  margin-bottom: 12px; padding: 11px 13px;
  border-radius: var(--r-2);
  border: 1px dashed var(--linea-3);
  background: var(--sup-0);
  cursor: pointer;
  transition: border-color var(--paso), background var(--paso);
}
.importar:hover, .importar--activa { border-color: var(--acento); background: var(--acento-piso); }
.importar > svg { width: 20px; height: 20px; flex-shrink: 0; color: var(--txt-3); }
.importar__texto { flex: 1; min-width: 0; }
.importar__texto b { display: block; font-size: 12.5px; font-weight: 500; color: var(--txt); }
.importar__texto small { display: block; font-size: 11.5px; color: var(--txt-4); }
.importar__texto code {
  padding: 0 3px; border-radius: 3px;
  background: var(--sup-3);
  font-family: var(--mono); font-size: 11px;
}
.importar__estado { flex-shrink: 0; font-size: 11.5px; color: var(--txt-4); text-align: right; }
.importar__estado.ok { color: var(--verde); }
.importar__estado.error { color: var(--rojo); }

.acc-alta { display: grid; grid-template-columns: 2fr 1.4fr 1fr auto; gap: 9px; align-items: end; }
.acc-rol {
  display: inline-block;
  padding: 1px 6px; border-radius: 4px;
  background: var(--sup-2);
  font-family: var(--mono); font-size: 10.5px;
  /* Una etiqueta de dos palabras partida en dos renglones descuadra la fila
     entera. "De fábrica" es una sola cosa: se lee de un tiron o no se lee. */
  white-space: nowrap;
}
.acc-rol[data-r="admin"]  { color: var(--rojo); }
.acc-rol[data-r="editor"] { color: var(--ambar); }
.acc-rol[data-r="lector"] { color: var(--txt-4); }

/* ══ VISOR ═══════════════════════════════════════════════════════════════ */
.visor { position: fixed; inset: 0; z-index: 75; display: grid; place-items: center; padding: 26px; }
.visor__fondo { position: absolute; inset: 0; background: var(--velo-visor); }

.visor__panel {
  position: relative;
  display: flex; flex-direction: column;
  width: min(1200px, 100%); height: min(92vh, 940px);
  border-radius: var(--r-3);
  border: 1px solid var(--linea-2);
  background: var(--sup-1);
  overflow: hidden;
  box-shadow: var(--sombra-panel);
}
.visor__barra {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--linea);
  background: var(--sup-0);
}
.visor__id { min-width: 0; }
.visor__id b { display: block; font-size: 13px; font-weight: 500; word-break: break-word; }
.visor__id span { display: block; font-size: 11.5px; color: var(--txt-4); }
.visor__acciones { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.visor__cuenta { font-family: var(--mono); font-size: 11.5px; color: var(--txt-4); white-space: nowrap; }

.visor__cuerpo {
  flex: 1; min-height: 0;
  display: grid; place-items: center;
  padding: 16px;
  overflow: auto;
  background: var(--fondo);
}
.visor__imagen { max-width: 100%; max-height: 100%; border-radius: var(--r-1); }
.visor__pdf { width: 100%; height: 100%; border: 0; border-radius: var(--r-1); /* El papel de un PDF es blanco en los dos temas. No es un token. */
  background: #fff; }
.visor__texto {
  width: 100%; height: 100%; margin: 0;
  padding: 16px;
  overflow: auto;
  align-self: stretch;
  border-radius: var(--r-1);
  background: var(--sup-0);
  font-family: var(--mono); font-size: 12px; color: var(--txt-2);
  white-space: pre-wrap; word-break: break-word;
}

/* ══ NOTIFICACION ════════════════════════════════════════════════════════ */
.notificacion {
  position: fixed; left: 50%; bottom: 26px; z-index: 90;
  transform: translate(-50%, 14px);
  padding: 9px 16px;
  border-radius: 99px;
  border: 1px solid var(--linea-2);
  background: var(--sup-alta);
  color: var(--txt);
  font-size: 12.5px;
  box-shadow: var(--sombra-flotante);
  opacity: 0; pointer-events: none;
  transition: opacity var(--paso), transform var(--paso);
}
.notificacion.visible { opacity: 1; transform: translate(-50%, 0); }


/* ══ PETICIONES SOBRE UN EQUIPO ══════════════════════════════════════════
   Van dentro de la ficha del equipo, no en una pantalla aparte: la pregunta
   que contestan es "¿que le han hecho a ESTE?", y esa se contesta mirando el
   equipo. Cada una es una tarjeta chica, para que se distingan del resto de
   los datos de la ficha sin gritarlo.                                    */


.peticiones { display: flex; flex-direction: column; gap: 8px; }

.peticion {
  padding: 11px 13px;
  border-radius: var(--r-2);
  border: 1px solid var(--linea);
  background: var(--sup-2);
}
.peticion__cabecera { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 6px; }
.peticion__cabecera code {
  font-family: var(--mono); font-size: 11px; letter-spacing: .04em;
  color: var(--txt-3);
}

/* La prioridad se dice con color porque es lo que ordena la cola de trabajo */
.peticion__prioridad {
  margin-left: auto;
  font-size: 11px; font-weight: 500;
  color: var(--txt-4);
}
.peticion__prioridad[data-p="Urgente"] { color: var(--rojo); }
.peticion__prioridad[data-p="Alta"]    { color: var(--ambar); }

.peticion b { display: block; font-size: 13px; font-weight: 500; color: var(--txt); }
.peticion p { margin: 4px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--txt-2); }
.peticion small { display: block; margin-top: 6px; font-size: 11px; color: var(--txt-4); }
.peticion em {
  display: block; margin-top: 8px; padding-top: 8px;
  border-top: 1px solid var(--linea);
  font-style: normal; font-size: 12.5px; color: var(--verde);
}
.peticion .mini { margin-top: 9px; }

/* ══ RESPONSIVO ══════════════════════════════════════════════════════════
   Tres columnas caben en un monitor de escritorio y en ningun otro sitio.
   Se van cayendo en este orden: primero se estrecha el indice, luego se
   guarda la columna de proyectos, y al final el panel de la derecha pasa a
   ser una segunda pantalla con boton de volver.                          */
@media (max-width: 1360px) {
  :root { --rail-ancho: 240px; }
  .division { grid-template-columns: 360px minmax(0, 1fr); }
  .detalle__cabecera { padding: 18px 20px 14px; }
  .detalle__cuerpo { padding: 2px 20px 28px; }
  .lienzo { padding: 18px 18px 36px; }
  .datos-fila, .filtros, .paginador { padding-left: 18px; padding-right: 18px; }
}

/* La columna de proyectos se sale de la pantalla y se abre con el boton de
   la barra. En pantalla chica no caben las tres, pero seguir teniendo los
   proyectos a un toque es justo lo que no se puede perder.               */
@media (max-width: 1000px) {
  .marco { grid-template-columns: minmax(0, 1fr); }

  .rail {
    position: absolute; inset: 0 auto 0 0; z-index: 30;
    width: 280px;
    transform: translateX(-100%);
    transition: transform var(--paso);
    box-shadow: var(--sombra-cajon);
  }
  .rail--abierto { transform: none; }

  .rail__velo {
    display: block;
    position: absolute; inset: 0; z-index: 25;
    background: var(--velo-suave);
  }
}

/* Debajo de esto el indice ocupa la pantalla entera y elegir algo trae el
   panel encima. El boton de volver aparece solo aqui: en escritorio no hay
   a donde volver, las dos columnas estan a la vista.                     */
@media (max-width: 760px) {
  .division { grid-template-columns: minmax(0, 1fr); }
  .detalle { display: none; }
  .division--detalle .lista { display: none; }
  .division--detalle .detalle { display: flex; }

  .detalle__volver {
    display: grid; place-items: center;
    width: 30px; height: 30px; flex-shrink: 0;
    border: 1px solid var(--linea-2); border-radius: var(--r-1);
    background: var(--sup-2);
    color: var(--txt-3);
    cursor: pointer;
  }
  .detalle__volver:hover { color: var(--txt); border-color: var(--linea-3); }
}

@media (max-width: 700px) {
  body { font-size: 13px; }
  .tema { padding: 2px; gap: 2px; }
  .tema__op { width: 26px; height: 24px; }
  .barra { gap: 8px; padding: 0 10px; }
  .logotipo__nombre { display: none; }
  .usuario__datos { display: none; }
  .buscador { margin-left: 0; }
  .barra__acciones .boton--fuerte span { display: none; }
  .alerta { padding: 8px 12px; }

  .lienzo { padding: 14px 12px 30px; }
  .datos-fila, .filtros, .paginador { padding-left: 12px; padding-right: 12px; }

  .cifras { grid-template-columns: repeat(2, 1fr); }
  .fila-proy { grid-template-columns: 28px minmax(0, 1fr) auto; }
  .fila-proy__sub, .fila-proy .crit { display: none; }

  .detalle__cabecera { padding: 14px 14px 12px; gap: 10px; }
  .detalle__cuerpo { padding: 2px 14px 26px; }
  .detalle__id h2 { font-size: 17px; }
  .detalle__linea { flex-wrap: wrap; }

  .previa__fila { grid-template-columns: minmax(0, 1fr) auto; }
  .previa__valor { display: none; }

  .filtros { flex-wrap: nowrap; overflow-x: auto; }

  .capa { padding: 0; }
  .panel { max-height: 100vh; height: 100%; width: 100%; border-radius: 0; border: 0; }
  .campos { grid-template-columns: 1fr; }
  .acc-alta { grid-template-columns: 1fr; }

  .panel__contenido { padding: 16px 12px; }
  .panel__cabecera { padding-left: 14px; padding-right: 14px; }
  .panel__contenido .tabla { display: block; overflow-x: auto; white-space: nowrap; }
  .paginador { justify-content: center; }
  .paginador__cuenta { flex-basis: 100%; text-align: center; }
  .visor { padding: 0; }
  .visor__panel { width: 100%; height: 100%; border-radius: 0; border: 0; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}


/* ══ INVENTARIO ══════════════════════════════════════════════════════════
   El unico apartado que no se parte en indice y panel: la tabla ocupa el
   ancho entero y la ficha del equipo elegido va anclada al pie, no en el
   flujo. Con ciento y pico de filas, una tarjeta que se pinta al final de
   la tabla obliga a rodar mil pixeles para leer lo que se acaba de elegir.

   El naranja de la app que se imita se traduce a var(--acento). En BLXBOX
   ese azul ya significa "aqui estas / esto es lo elegido" —.item.activo,
   .chip.activo, el riel— y el naranja significa otra cosa: --c-soporte es
   el color de una categoria de proyectos, no un acento de estado.

   ESTE BLOQUE VA AL FINAL DEL ARCHIVO. Dos reglas dependen de eso:
   .cifras--barra tiene que ganarle a la rejilla de dos columnas de la media
   query de 700px, y .cifra--foco:hover:not(:disabled) tiene que ganarle a
   .cifra:hover:not(:disabled), que EMPATA en especificidad (0,3,0) y solo
   se desempata por orden: si alguien sube este bloque, el relleno de las
   tarjetas parpadea a gris al pasar el raton y no da ningun error.       */

/* ── La barra de arriba ──────────────────────────────────────────────── */
/* Es el .lista__barra de los otros cinco apartados. Aqui no vive dentro de
   una .lista, asi que hay que decirle su fondo y su sangrado. */
.lista__barra--inv { padding: 9px 24px; background: var(--sup-0); }
.inv__acciones { display: flex; align-items: center; gap: 7px; flex-shrink: 0; }

/* ── La tira de clases ───────────────────────────────────────────────── */
/* No son .chip: un chip filtra, y una pestaña cambia QUE columnas se ven.
   Cosas distintas, formas distintas. */
.pestanas {
  display: flex; align-items: stretch; gap: 2px;
  padding: 0 24px;
  border-bottom: 1px solid var(--linea);
  background: var(--sup-0);
  flex-shrink: 0;
  overflow-x: auto;          /* una tira en dos renglones deja de leerse como tira */
}
.pestana {
  display: inline-flex; align-items: center; gap: 7px;
  height: 38px; padding: 0 12px;
  border: 0; border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--txt-3);
  font-family: var(--sans); font-size: 12.5px; white-space: nowrap;
  cursor: pointer;
  transition: color var(--paso), background var(--paso), border-color var(--paso);
}
.pestana svg { width: 15px; height: 15px; opacity: .85; }
/* El contador con la receta de .tablero__bloque > h2 b: un contador se ve
   igual en toda la consola. */
.pestana b {
  font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0;
  color: var(--txt-4);
  padding: 1px 6px; border-radius: 4px; background: var(--sup-2);
}
.pestana:hover:not(:disabled) { color: var(--txt-2); background: var(--sup-1); }
.pestana.activo { color: var(--txt); background: var(--sup-2); border-bottom-color: var(--acento); }
.pestana.activo b { background: var(--acento-piso); color: var(--acento-2); }
.pestana:disabled { opacity: .4; cursor: default; }

/* ── Las cifras: el fondo ES el dato ──────────────────────────────────────
   Antes el color era un detalle que habia que ir a buscar —una barrita de
   3px en el canto, el cuadro del icono teñido, el numero teñido—. Ahora se
   rellena el recuadro entero, y el relleno contesta UNA pregunta:
   ¿esto pide que alguien haga algo?

     gris      CONSTATA   el total, "en resguardo", y CUALQUIER cifra cuyo
                          numero sea cero
     verde     EN REGLA   asignados, operativas, licencia original
     ambar 28% FALTA      un papel o un dato: cartas pendientes, sin IP
     ambar 45% PIDE       la maquina esta mal: requieren atencion
     rojo  45% PIDE       licencia irregular
     violeta   ESPERA     peticiones abiertas: no es un estado del hardware,
                          es una persona

   Esto no esquiva la ley del archivo, se apoya en ella: el escalon no lo
   elige el diseño, lo elige el tono, y el tono ya lo reparte la ley —rojo =
   critico, ambar = atencion, verde = operativo—. Y lo que remata el arcoiris
   ya estaba en el JS: pintarKpis solo pone data-tono si n>0, asi que una
   barra sin nada pendiente sale casi entera en gris y los bloques de color
   son EXACTAMENTE los que tienen algo dentro.

   Se va la barrita de 3px del canto: con el fondo lleno era el mismo dato
   dicho dos veces, y era literalmente el "detalle de su color". Se va tambien
   el numero teñido: --ambar sobre el relleno ambar da 3.08:1, o sea que
   teñirlo lo APAGA. El color ya lo pone el fondo.                        */
.cifras--barra {
  margin: 0; max-width: none;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  padding: 11px 24px;
  border-bottom: 1px solid var(--linea);
  background: var(--sup-0);
  flex-shrink: 0;
}
.cifras--barra:empty { display: none; }

/* TODO pasa por --lleno y --orla. Ninguna regla de tono vuelve a tocar
   `background` ni `border-color`, asi que el hover y la puesta cambian de
   escalon en vez de pelearle la especificidad al tono. */
.cifra--foco {
  --lleno: var(--lleno-neutro);
  --orla:  var(--linea-2);
  grid-template-columns: auto minmax(0, 1fr);
  gap: 1px 11px;
  background: var(--lleno);
  border-color: var(--orla);
  transition: filter var(--paso), box-shadow var(--paso),
              background var(--paso), border-color var(--paso);
}
/* OBLIGATORIA, y por eso este bloque va al final del archivo: empata en
   especificidad (0,3,0) con .cifra:hover:not(:disabled) y solo la desempata
   el orden. Sin esta regla el relleno parpadea a gris al pasar el raton, y
   no da ningun error. */
.cifra--foco:hover:not(:disabled) {
  background: var(--lleno);
  border-color: var(--orla);
  filter: var(--realce);
}

/* El cuadro del icono, hecho de luz y no de sombra. */
.cifra--foco .cifra__icono {
  grid-column: 1; grid-row: 1 / span 2;
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: 8px;
  border: 1px solid var(--lleno-filo);
  background: var(--lleno-caja);
  color: var(--lleno-icono);
}
.cifra--foco .cifra__icono svg { width: 15px; height: 15px; }
.cifra--foco .cifra__nombre { grid-column: 2; color: var(--lleno-txt); }
.cifra--foco b { grid-column: 2; color: var(--txt); }

/* El "de 67" de CARTAS PENDIENTES 5 de 67. */
.cifra__de {
  margin-left: 6px;
  font-family: var(--mono); font-size: 11px; font-weight: 500; font-style: normal;
  color: var(--txt-4);
}
.cifra--foco .cifra__de { color: var(--lleno-txt); }

/* Los escalones. data-nivel="1" es el tenue y solo lo llevan las cifras de
   "falta un papel o un dato": es (0,3,0) contra (0,2,0), asi que gana sin
   depender del orden. */
.cifra--foco[data-tono="verde"]   { --lleno: var(--lleno-verde);   --orla: var(--orla-verde); }
.cifra--foco[data-tono="ambar"]   { --lleno: var(--lleno-ambar);   --orla: var(--orla-ambar); }
.cifra--foco[data-tono="rojo"]    { --lleno: var(--lleno-rojo);    --orla: var(--orla-rojo); }
.cifra--foco[data-tono="violeta"] { --lleno: var(--lleno-violeta); --orla: var(--orla-violeta); }
.cifra--foco[data-tono="ambar"][data-nivel="1"] { --lleno: var(--lleno-ambar-1); --orla: var(--orla-ambar-1); }

/* La cifra puesta como filtro. Ya no puede decirse con el fondo —el fondo es
   del tono— asi que se dice con un aro de acento POR FUERA, que cae sobre la
   barra (--sup-0) y ahi da 6.34:1. Un aro por dentro caeria sobre el relleno
   ambar y daria 2.48:1, que no llega ni al 3:1 de un indicador. El relleno
   de tono se conserva: hace falta seguir viendo POR QUE criterio se filtra,
   no solo que se filtra. Cabe en el gap de 8px de .cifras. El segundo
   selector existe porque :hover lleva (0,3,0) y le ganaria el border-color a
   .activo, que lleva (0,2,0).                                           */
.cifra--foco.activo,
.cifra--foco.activo:hover:not(:disabled) {
  border-color: var(--acento);
  box-shadow: 0 0 0 2px var(--acento), var(--sombra-carta);
}
.cifra--foco:focus-visible { outline: 2px solid var(--acento); outline-offset: 3px; }

/* ── La fila de filtros ──────────────────────────────────────────────── */
.filtros--inv { gap: 7px; }
.filtros--inv:empty { display: none; }

/* La unica caja de buscar esta arriba. Esto NO es otra caja: es un letrero
   que lleva a ella, y el borde punteado lo dice antes de que nadie lo
   intente. Con texto puesto se vuelve solido y enseña el termino. */
.filtros__pista {
  display: flex; align-items: center; gap: 7px;
  flex: 1; min-width: 190px; max-width: 420px;
  height: 27px; padding: 0 10px;
  border: 1px dashed var(--linea-2); border-radius: var(--r-1);
  background: transparent;
  color: var(--txt-4);
  font-family: var(--sans); font-size: 12.5px; text-align: left;
  cursor: text;
  transition: border-color var(--paso), color var(--paso), background var(--paso);
}
.filtros__pista svg { width: 14px; height: 14px; flex-shrink: 0; }
.filtros__pista span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filtros__pista kbd {
  flex-shrink: 0; padding: 1px 5px;
  border-radius: 4px; border: 1px solid var(--linea-2);
  font-family: var(--mono); font-size: 10.5px; color: var(--txt-4);
}
.filtros__pista:hover { border-color: var(--linea-3); color: var(--txt-3); }
.filtros__pista.activo {
  border-style: solid; border-color: var(--acento-linea);
  background: var(--acento-piso); color: var(--txt-2);
}
.filtros__pista.activo span { font-family: var(--mono); color: var(--txt); }
.filtros__equis { flex-shrink: 0; font-style: normal; color: var(--txt-3); cursor: pointer; }
.filtros__equis:hover { color: var(--txt); }

/* ── La tabla ────────────────────────────────────────────────────────── */
.inv__tabla { flex: 1 1 auto; min-height: 96px; overflow-y: auto; position: relative; }
.inv__vacio { padding: 26px 24px 34px; }

.tabla--inv { table-layout: auto; }
/* El encabezado pegado tiene que ser opaco, y --sup-0 es el fondo del cromo
   en toda la consola. Con border-collapse el borde de una celda sticky se
   pierde: se dibuja con box-shadow. */
.tabla--inv thead th {
  position: sticky; top: 0; z-index: 3;
  background: var(--sup-0);
  border-bottom: 0;
  box-shadow: inset 0 -1px 0 var(--linea-2);
}
/* Mas denso que .tabla td: la primera celda ya trae dos renglones. */
.tabla--inv td { padding: 7px 10px; vertical-align: middle; }
.tabla--inv tbody tr { cursor: pointer; transition: background var(--paso); scroll-margin: 34px 0 10px; }
.tabla--inv tbody tr:hover { background: var(--sup-1); }
/* Receta calcada de .item.activo: lo elegido se ve igual en toda la app.
   Es el "borde izquierdo naranja" de la captura, en azul. */
.tabla--inv tbody tr.activo { background: var(--sup-3); }
.tabla--inv tbody tr.activo td { color: var(--txt); }
.tabla--inv tbody tr.activo td:first-child { box-shadow: inset 2px 0 0 var(--acento); }
/* Misma regla que .item.aviso: ambar = hay algo que revisar (baja, estado
   que preocupa, o peticion pendiente). */
.tabla--inv tbody tr.aviso .persona__nombre { color: var(--ambar); }
.tabla--inv tbody tr:focus-visible { outline: 2px solid var(--acento); outline-offset: -2px; }

/* El corte por sucursal: .lista__grupo trasplantado a un <tr>. Por eso NO
   hay columna de sucursal —lo que se repite se dice una vez—. No es sticky
   a proposito: con el thead ya pegado, dos niveles pegajosos son una guerra
   de z-index para resolver lo que la segunda linea de cada fila ya dice. */
.tabla__grupo td {
  padding: 12px 10px 5px;
  border-bottom: 1px solid var(--linea);
  background: var(--sup-0);
  font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-4);
}
.tabla__grupo svg { width: 13px; height: 13px; vertical-align: -2px; margin-right: 7px; }
.tabla__grupo b {
  margin-left: 8px;
  font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0;
  color: var(--txt-4);
}
.tabla--inv tbody tr.tabla__grupo { cursor: default; }
.tabla--inv tbody tr.tabla__grupo:hover { background: var(--sup-0); }

/* Lo que se copia y se compara. Mismo par familia/tamaño que .item__nombre.mono */
.tabla--inv .pastilla { white-space: nowrap; }
.tabla__mono { font-family: var(--mono); font-size: 11.5px; color: var(--txt-2); }
/* En una columna con encabezado el guion NO es mudo: la cabecera dice que
   falta. La frase entera se dice en la ficha, que es donde se arregla. */
.tabla__hueco { color: var(--txt-4); }

/* ── La celda de empleado ────────────────────────────────────────────── */
.persona { display: flex; align-items: center; gap: 9px; min-width: 0; }
/* Monocromo. Un color por hash del nombre no significa nada que el nombre
   no diga tres milimetros a la derecha, y en esta tabla el ambar ya quiere
   decir "revisa esto": un avatar ambar porque el nombre suma 7 seria una
   alarma falsa cada pocos renglones. */
.persona__avatar {
  display: grid; place-items: center;
  width: 26px; height: 26px; flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--txt-3);
  font-family: var(--mono); font-size: 10.5px;
}
.persona__avatar svg { width: 14px; height: 14px; }
/* Sin dueño: el hueco se dibuja como hueco, y el icono de la clase dice lo
   que las iniciales no dirian. */
.persona--libre .persona__avatar { border-style: dashed; color: var(--txt-4); }
.persona--libre .persona__nombre { font-weight: 500; color: var(--txt-3); }
.persona__id { min-width: 0; }
.persona__nombre {
  display: block; font-size: 12.5px; font-weight: 600; color: var(--txt);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.persona__sub {
  display: block; font-style: normal; font-size: 11px; color: var(--txt-4);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Las peticiones abiertas no son un dato del equipo —cambian solas— asi que
   no llevan columna: viajan pegadas al nombre y sobreviven a que las
   columnas se caigan en pantalla angosta. */
.persona__pet {
  flex-shrink: 0; min-width: 18px; padding: 0 5px;
  border-radius: 99px;
  background: var(--violeta-piso); color: var(--violeta);
  font-family: var(--mono); font-size: 10.5px; font-style: normal; text-align: center;
}
.tabla--inv tbody tr.activo .persona__avatar { border-color: var(--acento-linea); color: var(--acento); }

/* ── Las pastillas de estado ─────────────────────────────────────────── */
/* Misma convencion data-* que .dato[data-estado]. verde = operativo ·
   azul = existe y esta libre, ni bueno ni malo · ambar = hay que atenderlo
   · rojo = esta mal. */
.pastilla[data-estado="Operativo"]         { background: var(--verde-piso); color: var(--verde); }
.pastilla[data-estado="Disponible"]        { background: var(--acento-piso); color: var(--acento-2); }
.pastilla[data-estado="En revisión"]       { background: var(--ambar-piso); color: var(--ambar); }
.pastilla[data-estado="Requiere atención"] { background: var(--ambar-piso); color: var(--ambar); }
.pastilla[data-estado="Fuera de servicio"] { background: var(--rojo-piso); color: var(--rojo); }

/* ── La ficha del equipo, ahora un modal ──────────────────────────────────
   Era un panel anclado con suelo de 34vh y techo de 400px, y se comia esos
   400px de una tabla de ciento cinco filas: abrir un equipo tapaba justo las
   filas que se estaban comparando, y la ficha tecnica se leia por una
   rendija. Ahora es un .capa/.panel de los de siempre.

   Tres zonas, y la del medio es la unica decision de verdad: la TIRA vive
   FUERA de .panel__contenido, o sea que no rueda nunca. Los numeros no
   ruedan; la prosa si. No se promete que todo quepa —con una computadora de
   siete especificaciones y tres peticiones, en un portatil de 768px de alto
   hay que rodar— se decide QUE es lo que jamas puede quedar debajo del
   pliegue: que equipo es, con que serie, si firmo, que se le debe y cuando
   se toco. Nunca hace falta rodar para DESCUBRIR un dato; solo para leer el
   texto de una peticion que ya sabias que existia porque la tira te dio el
   numero.                                                                */

/* La cabecera lleva el avatar de la persona, no el .panel__icono cuadrado:
   es la misma pieza de su fila, en grande, y ata lo que se toco con lo que
   se abrio. */
.equipo__avatar {
  display: grid; place-items: center;
  width: 38px; height: 38px; flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--linea-2);
  background: var(--sup-2);
  color: var(--txt-2);
  font-family: var(--mono); font-size: 13px; font-weight: 600;
}
.equipo__avatar svg { width: 19px; height: 19px; color: var(--txt-3); }
.equipo__avatar--libre { border-style: dashed; color: var(--txt-4); }
.panel--equipo .detalle__chips:empty { display: none; }
/* El foco inicial va aqui a proposito: es un contenedor, no un control, y no
   tiene que dibujar anillo. */
#eqPanel:focus { outline: none; }

/* ── La tira: lo que no rueda ────────────────────────────────────────────
   --sup-0 es el fondo del cromo en toda la consola —.pestanas, .panel__pie,
   el thead pegado—, asi que la tira se lee como cromo y no como contenido.
   Las lineas de 1px entre celdas salen del gap sobre un fondo --linea. */
.equipo__tira {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--linea);
  background: var(--linea);
}
.tira__dato {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0; padding: 9px 20px 10px;
  border: 0;
  background: var(--sup-0);
  font-family: var(--sans); text-align: left;
}
/* --txt-3, no --txt-4: sobre --sup-0, --txt-4 da 3.01:1 y no pasa AA para
   texto chico. --txt-3 da 4.95:1. */
.tira__etiqueta {
  font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--txt-3);
}
.tira__linea { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tira__linea .mini { flex-shrink: 0; }
.tira__valor {
  min-width: 0;
  font-size: 13px; font-weight: 600; color: var(--txt);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* La monoespaciada es para lo que se copia y se compara. */
.tira__valor--mono { font-family: var(--mono); font-size: 12px; font-weight: 500; letter-spacing: .02em; }
.tira__valor--vacio { font-weight: 500; color: var(--txt-3); }
.tira__pie { font-style: normal; font-size: 11px; color: var(--txt-3); }

/* Misma convencion data-tono que en toda la consola. Sobre --sup-0: verde
   6.64, ambar 7.87, rojo 5.37, violeta 5.88. Todos pasan AA. */
.tira__dato[data-tono="verde"]   .tira__valor { color: var(--verde); }
.tira__dato[data-tono="ambar"]   .tira__valor { color: var(--ambar); }
.tira__dato[data-tono="rojo"]    .tira__valor { color: var(--rojo); }
.tira__dato[data-tono="violeta"] .tira__valor { color: var(--violeta); }

.tira__dato--enlace { cursor: pointer; transition: background var(--paso); }
.tira__dato--enlace:hover { background: var(--sup-1); }

/* ── El cuerpo: dos carriles ─────────────────────────────────────────────
   En una sola columna, la ficha tecnica empujaria las peticiones fuera de la
   pantalla, que es exactamente lo que este cambio venia a arreglar. En dos
   carriles las dos cosas estan a la vista a la vez, y el que crece —el de
   las peticiones— es el estrecho.                                       */
.equipo__cuerpo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 330px;
  gap: 0 24px;
  align-items: start;
  padding: 18px 20px 22px;
}
.equipo__col { min-width: 0; }
.equipo__lado {
  min-width: 0;
  padding-left: 24px;
  border-left: 1px solid var(--linea);
}
.equipo__cuerpo .bloque { margin-bottom: 18px; }
.equipo__cuerpo .bloque:last-child { margin-bottom: 0; }
/* .detalle__nota es --sup-1, que es el fondo del panel: dentro se perderia. */
.equipo__cuerpo .detalle__nota { margin-top: 0; background: var(--sup-0); }
.equipo__lado .peticion { background: var(--sup-1); border-color: var(--linea-2); }

/* Densidad antes que aire: de 13px a 9px por dato son ~9 renglones ahorrados
   en un equipo de diecinueve campos, y eso decide cuanto hay que rodar. Y el
   subrayado se le devuelve al ultimo: en una rejilla, :last-child es UNO
   solo de la fila de abajo, asi que la regla de .detalle__dato:last-child
   deja el bloque descuadrado por abajo. */
.equipo__cuerpo .detalle__dato { padding: 9px 0; }
.equipo__cuerpo .detalle__dato:last-child { border-bottom: 1px solid var(--linea); }

/* De cuatro columnas a TRES. Cuatro cabian cuando la ficha ocupaba el ancho
   de la PANTALLA; dentro del carril izquierdo de 764px, a cuatro cada
   columna queda en 176 y una serie en monoespaciada con su boton .mini al
   lado no cabe en la linea. A tres, cada columna mide 241 y entran holgadas. */
.detalle__rejilla {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 20px;
}

/* Los otros equipos de la misma persona. Es un renglon por equipo, no una
   tarjeta: lo que se hace con ellos es escoger. */
.equipo__otros { display: grid; gap: 5px; }
.equipo__otro {
  display: grid; grid-template-columns: 24px minmax(0, 1fr) auto;
  align-items: center; gap: 10px;
  width: 100%; padding: 7px 9px;
  border: 1px solid var(--linea); border-radius: var(--r-1);
  background: var(--sup-2); color: var(--txt-2);
  font-family: var(--sans); font-size: 12.5px; text-align: left;
  cursor: pointer;
  transition: background var(--paso), border-color var(--paso);
}
.equipo__otro:hover { background: var(--sup-3); border-color: var(--linea-3); }
.equipo__otro svg { width: 15px; height: 15px; color: var(--txt-3); }
.equipo__otro span { min-width: 0; }
.equipo__otro b {
  display: block; font-size: 12.5px; font-weight: 600; color: var(--txt);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.equipo__otro i {
  display: block; font-style: normal; font-size: 11px; color: var(--txt-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* La banda de "Observaciones". Ambar porque es una nota que condiciona como
   se usa el equipo. El motivo de la baja usa la misma pieza en rojo. */
.detalle__aviso {
  margin: 14px 0 0; padding: 10px 12px;
  border-radius: var(--r-2);
  border-left: 3px solid var(--ambar);
  background: var(--ambar-piso);
  font-size: 12.5px; line-height: 1.55; color: var(--txt-2);
}
.detalle__aviso b {
  display: block; margin-bottom: 2px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ambar);
}
.detalle__aviso--baja { border-left-color: var(--rojo); background: var(--rojo-piso); }
.detalle__aviso--baja b { color: var(--rojo); }

/* ── Una seccion dentro del formulario ───────────────────────────────── */
/* El <h3> cae como hijo directo de .grupo y .grupo > h3 ya le da
   tipografia. Lo unico que se añade es la barrita de la captura. */
h3.campo-seccion { padding-left: 9px; border-left: 2px solid var(--acento); }
h3.campo-seccion:not(:first-child) { margin-top: 20px; }
/* Un .campo-form suelto no tenia ningun margen y quedaba pegado al de abajo. */
.grupo > .campo-form { margin-bottom: 11px; }

/* ── Pantalla angosta ────────────────────────────────────────────────── */
/* Ocho columnas en 360px no se resuelven con scroll: se resuelven decidiendo
   cuales tres contestan la pregunta —quien lo trae, que es, como esta—.

   Los cortes de la ficha ya NO son del viewport: el modal esta topado en
   1160px, asi que sus dos carriles se apilan a los 1100 aunque la pantalla
   sea mas ancha. */
@media (max-width: 1360px) {
  .lista__barra--inv, .pestanas, .cifras--barra,
  .inv__vacio { padding-left: 18px; padding-right: 18px; }
}

@media (max-width: 1100px) {
  /* Los dos carriles se apilan y el separador vertical pasa a horizontal.
     Aqui el modal SI rueda, y es lo correcto: en 1100px no cabe nada mas sin
     partir palabras. */
  .equipo__cuerpo { grid-template-columns: minmax(0, 1fr); }
  .equipo__lado {
    padding-left: 0; padding-top: 16px; margin-top: 4px;
    border-left: 0; border-top: 1px solid var(--linea);
  }
}

@media (max-width: 1000px) {
  .tabla--inv [data-col="extra"] { display: none; }
  .cifras--barra { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .detalle__rejilla { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
  .lista__barra--inv, .pestanas, .cifras--barra,
  .inv__vacio { padding-left: 12px; padding-right: 12px; }

  .inv__acciones .boton span { display: none; }   /* mismo truco que .barra__acciones */
  .cifras--barra { grid-template-columns: repeat(2, 1fr); }
  .tabla--inv [data-col="media"] { display: none; }
  /* ORDEN OBLIGATORIO: apagar el sticky ANTES de dar overflow-x. Un
     contenedor con overflow en un eje rompe el position:sticky del otro, y
     el encabezado se despega sin dar ningun error. */
  .tabla--inv thead th { position: static; }
  .inv__tabla { overflow-x: auto; }

  /* El .panel ya se hace pantalla completa con la regla que existe arriba en
     el bloque de 700px. Aqui solo se aprieta lo de dentro. */
  .equipo__tira { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tira__dato { padding: 9px 14px 10px; }
  .equipo__cuerpo { padding: 14px 14px 20px; }
  .detalle__rejilla { grid-template-columns: minmax(0, 1fr); }
  .panel__pie { flex-wrap: wrap; }
}


/* ══ INVENTARIO · EL DISEÑO NUEVO ════════════════════════════════════════
   Todo lo que sigue viene de Inventario.html y vive acotado bajo .inv2.

   El acotado no es manía: el archivo trae .panel, .main, .app, .toast y
   .tema, y esos cinco nombres ya significan otra cosa en BLXBOX —.panel es
   el cuerpo de los diez modales, .tema es el interruptor de la barra—. Sin
   acotar, meter esta pantalla rompia cinco cosas que no tienen nada que ver
   con el inventario.

   Y sus tokens son ALIAS de los de BLXBOX, no una segunda paleta. Los
   colores ya son los mismos; lo que esto añade es que el interruptor
   claro/oscuro mande también aquí, con un solo juego de valores que
   mantener.                                                              */
.inv2 {
  --ground:      var(--fondo);
  --surface:     var(--sup-1);
  --surface-2:   var(--sup-0);
  --surface-3:   var(--sup-2);
  --line:        var(--linea);
  --line-strong: var(--sup-alta);

  --ink:   var(--txt);
  --ink-2: var(--txt-2);
  --ink-3: var(--txt-3);

  --accent:      var(--acento);
  --accent-ink:  var(--acento-2);
  --accent-soft: var(--acento-piso);
  --accent-line: var(--acento-linea);

  --ok:   var(--verde);  --ok-soft:   var(--verde-piso);  --ok-line:   var(--orla-verde);
  --warn: var(--ambar);  --warn-soft: var(--ambar-piso);  --warn-line: var(--orla-ambar);
  --crit: var(--rojo);   --crit-soft: var(--rojo-piso);   --crit-line: var(--orla-rojo);

  /* Los cuatro que BLXBOX no tenia. El anil es el azul de "informativo" que
     el archivo usa aparte del indigo del acento; la estrella es el ambar de
     una calificacion, que no es el ambar de "atiende esto". */
  --anil:      #3B82F6;
  --anil-soft: var(--acento-piso);
  --star:      var(--ambar);
  --star-off:  var(--sup-alta);

  --muro:     var(--sup-1);
  --muro-ink: var(--txt);
  --muro-dim: var(--txt-3);
  --topbar:   var(--sup-1);

  --shadow:    var(--sombra-carta);
  --shadow-lg: var(--sombra-panel);
  --r:    var(--r-2);
  --r-sm: var(--r-1);

  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
}


/* ===========================================================================
   BAILMEX · INVENTARIO — Diseño 4
   Panel de administración claro: barra lateral blanca, acento índigo,
   tarjetas suaves con pastilla de color, gráficas de área y dona.
   =========================================================================== */





.inv2 h1, .inv2 h2, .inv2 h3, .inv2 h4 {font-family:inherit; margin:0; text-wrap:balance; font-weight:700; letter-spacing:-.02em}
.inv2 .mono, .inv2 .cell-tag, .inv2 .cell-sub, .inv2 .att-num, .inv2 .tl-date {font-family:"DM Mono",ui-monospace,Menlo,monospace; font-variant-numeric:tabular-nums}
.inv2 .kpi-value, .inv2 .donut-num, .inv2 .anillo-pct, .inv2 .countdown .num, .inv2 .bar-num {font-variant-numeric:tabular-nums}
.inv2 button {font:inherit; color:inherit; cursor:pointer}
.inv2 :focus-visible {outline:2px solid var(--accent); outline-offset:2px; border-radius:6px}

/* ======================= Las clases compartidas =======================
   BLXBOX ya tenia .chip, .filtros y .panel, y el archivo tambien. Acotar bajo
   .inv2 hace que gane la del archivo en todo lo que ESA declara —y solo en
   eso—: cada propiedad que el archivo no menciona se la queda la de BLXBOX.
   Asi es como el recuadro de la ficha salia con esquinas redondeadas y
   recortado a 810px cuando en el archivo va de arriba abajo.

   Estas reglas devuelven esas propiedades sueltas a lo que valen en el
   archivo. Van ANTES de su CSS a proposito: tienen la misma fuerza, asi que
   lo que el archivo declare despues sigue mandando y esto solo rellena los
   huecos.                                                                 */
.inv2 .chip    { height: auto; border: 0; background: none; color: inherit; }
.inv2 .filtros { border-bottom: 0; background: none; flex-shrink: 1; }
.inv2 .panel   { height: auto; max-height: none; border: 0; border-radius: 0; overflow: visible; }

/* ============================ Estructura ============================ */
/* El archivo era una pagina entera y median contra la ventana. Aqui viven
   dentro de una .vista de BLXBOX, que ya tiene su alto y su overflow:hidden:
   un min-height de 100vh forzaria una pagina mas alta que la ventana y el
   scroll acabaria en el sitio equivocado. Miden contra su hueco y el que
   rueda es el carril de contenido. */
.inv2 { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.inv2 .inv2-marco {
  display: grid; grid-template-columns: 232px 1fr;
  flex: 1; min-height: 0; overflow: hidden;
}
.inv2 .main {overflow: hidden}
.inv2 .content {flex: 1; min-height: 0; overflow-y: auto}

/* Y las tarjetas NO se encogen.
   .content es una columna flex, y en el archivo suelto crece con la pagina.
   Aqui tiene un alto fijo —el hueco de la vista— y por defecto un hijo de
   flex se encoge hasta caber: la tabla de 105 renglones se aplastaba a la
   altura del hueco y lo que sobraba lo recortaba el overflow:hidden de la
   propia tarjeta. No es que la rueda no funcionara: es que no habia nada
   que rodar, porque no habia desbordamiento. */
.inv2 .content > * {flex: none}
.inv2 .nav {
  background:var(--muro); color:var(--muro-ink); border-right:1px solid var(--line);
  display:flex; flex-direction:column; height:100%; min-height:0; overflow-y:auto; padding:0 12px;
}
.inv2 .brand {display:flex; align-items:center; gap:11px; padding:20px 10px 18px}
.inv2 .brand-iso {width:36px; height:36px; flex:none; object-fit:contain}
.inv2 .brand-name {font-weight:700; font-size:16px; line-height:1.2; color:var(--ink); letter-spacing:-.02em; white-space:nowrap}
.inv2 .brand-sub {font-size:11.5px; color:var(--ink-3); margin-top:1px; white-space:nowrap}

.inv2 .nav-label {padding:16px 12px 7px; font-size:10.5px; letter-spacing:.09em; text-transform:uppercase; color:var(--ink-3); font-weight:600}
.inv2 .nav-list {display:flex; flex-direction:column; gap:2px}
.inv2 .nav-item {
  display:flex; align-items:center; gap:11px; width:100%; text-align:left;
  padding:10px 12px; border:0; background:none; border-radius:9px; color:var(--ink-2);
  font-size:13.5px; font-weight:500; transition:background .13s, color .13s;
}
.inv2 .nav-item:hover {background:var(--surface-2); color:var(--ink)}
.inv2 .nav-item[aria-current="true"] {background:var(--accent); color:#fff; font-weight:600}
.inv2 .nav-item svg {width:17px; height:17px; flex:none; opacity:.9}
.inv2 .nav-count {
  margin-left:auto; font-size:11px; font-weight:600; color:var(--ink-3);
  background:var(--surface-2); padding:1px 7px; border-radius:100px; min-width:23px; text-align:center;
}
.inv2 .nav-item[aria-current="true"] .nav-count {background:rgba(255,255,255,.22); color:#fff}
.inv2 .nav-foot {
  margin-top:auto; margin-bottom:14px; padding:11px 12px; display:flex; align-items:center; gap:10px;
  border:1px solid var(--line); border-radius:10px;
}
.inv2 .avatar {
  width:34px; height:34px; border-radius:50%; background:var(--accent); color:#fff;
  display:grid; place-items:center; font-size:11.5px; font-weight:700; flex:none;
}
.inv2 .nav-foot-name {font-size:13px; font-weight:600; line-height:1.2}
.inv2 .nav-foot-rol {font-size:11px; color:var(--ink-3); margin-top:1px}

.inv2 .main {min-width:0; display:flex; flex-direction:column}
.inv2 .topbar {
  display:flex; align-items:center; gap:14px; padding:14px 26px;
  background:var(--topbar); border-bottom:1px solid var(--line);
  position:sticky; top:0; z-index:20;
}
.inv2 .topbar h1 {font-size:20px}
.inv2 .topbar-sub {font-size:12.5px; color:var(--ink-3); margin-top:1px}
.inv2 .search {
  margin-left:auto; display:flex; align-items:center; gap:9px; background:var(--surface-2);
  border:1px solid var(--line); border-radius:9px; padding:9px 14px; min-width:280px;
}
.inv2 .search:focus-within {border-color:var(--accent-line); background:var(--surface)}
.inv2 .search input {border:0; background:none; outline:0; color:var(--ink); font:inherit; font-size:13px; width:100%}
.inv2 .search input::placeholder {color:var(--ink-3)}
.inv2 .search svg {width:16px;height:16px;color:var(--ink-3);flex:none}
.inv2 .content {padding:22px 26px 60px; display:flex; flex-direction:column; gap:18px}

/* ============================ Indicadores ============================ */
.inv2 .kpis {display:grid; grid-template-columns:repeat(auto-fit,minmax(206px,1fr)); gap:16px}
.inv2 .kpi {
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r);
  padding:18px; box-shadow:var(--shadow);
  display:flex; flex-direction:column; gap:3px; position:relative;
}
.inv2 .kpi-ico {
  position:absolute; top:16px; right:16px; width:42px; height:42px; border-radius:11px;
  display:grid; place-items:center; background:var(--accent-soft); color:var(--accent);
}
.inv2 .kpi-ico svg {width:20px; height:20px}
.inv2 .kpi.is-ok .kpi-ico {background:var(--ok-soft); color:var(--ok)}
.inv2 .kpi.is-warn .kpi-ico {background:var(--warn-soft); color:var(--warn)}
.inv2 .kpi.is-crit .kpi-ico {background:var(--crit-soft); color:var(--crit)}
.inv2 .kpi-label {font-size:12.5px; color:var(--ink-2); font-weight:500; padding-right:52px}
.inv2 .kpi-value {font-size:29px; font-weight:700; line-height:1.15; letter-spacing:-.03em; margin-top:3px}
.inv2 .kpi-note {font-size:12px; color:var(--ink-3)}
.inv2 .kpi-note b {color:var(--ok); font-weight:600}
.inv2 .kpi.is-crit .kpi-note b, .inv2 .kpi.is-warn .kpi-note b {color:var(--ink-2)}

/* ============================ Tarjetas ============================ */
.inv2 .card {background:var(--surface); border:1px solid var(--line); border-radius:var(--r); box-shadow:var(--shadow); overflow:hidden}
.inv2 .card-head {display:flex; align-items:center; gap:12px; padding:17px 20px 13px}
.inv2 .card-head h2 {font-size:15.5px; font-weight:600}
.inv2 .card-head .hint {font-size:12.5px; color:var(--accent); margin-left:auto; font-weight:500}
.inv2 .split {display:grid; grid-template-columns:1.35fr 1fr; gap:18px; align-items:start}

/* ============================ Tabla ============================
   La tabla se acomoda al ANCHO QUE TIENE, no al de la ventana. Son cosas
   distintas: el mismo navegador maximizado deja a la tabla con 940 px o con
   1200 segun este abierto el menu lateral, y con media queries la tabla no se
   entera de eso. Por eso .table-wrap se declara contenedor y las reglas de
   abajo preguntan por SU ancho.

   Cuando ya no cabe, en vez de empujar columnas fuera de la pantalla se van
   plegando de la menos importante a la mas, y lo que se pliega reaparece
   dentro de otra celda: nada de la fila se pierde, solo cambia de sitio. El
   overflow-x se queda como ultimo recurso.                                  */
.inv2 .table-wrap {overflow-x:auto; container-type:inline-size}
.inv2 table {width:100%; border-collapse:collapse; font-size:13px}
.inv2 thead th {
  text-align:left; padding:10px 20px; font-size:11.5px; color:var(--ink-3); font-weight:500;
  background:var(--surface-2); border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  white-space:nowrap;
}

/* Lo que solo aparece cuando su columna se plego. */
.inv2 .si-angosto {display:none}

@container (max-width: 1180px) {
  .inv2 thead th, .inv2 td {padding-left:14px; padding-right:14px}
  .inv2 .col-suc {display:none}
  .inv2 .col-user .si-angosto {display:block; margin-top:2px}
}
@container (max-width: 980px) {
  .inv2 .col-mant {display:none}
  .inv2 .col-estado .si-angosto {display:block; margin-top:5px}
}
@container (max-width: 820px) {
  .inv2 thead th, .inv2 td {padding-left:11px; padding-right:11px}
  .inv2 .col-cond {display:none}
  .inv2 .col-equipo .si-angosto {display:block; margin-top:5px}
}
@container (max-width: 660px) {
  .inv2 .col-carta {display:none}
  .inv2 .col-equipo .si-angosto-carta {display:inline-flex; margin-top:5px}
  /* Sin la barra lateral, el numero de inventario y el equipo bastan para
     reconocer la fila; lo demas ya viaja dentro de esas dos celdas. */
  .inv2 .col-user {display:none}
  .inv2 .col-equipo .si-angosto-user {display:block; margin-top:2px}
}
.inv2 tbody tr {border-bottom:1px solid var(--line); cursor:pointer; transition:background .12s}
.inv2 tbody tr:last-child {border-bottom:0}
.inv2 tbody tr:hover {background:var(--surface-2)}
.inv2 td {padding:13px 20px; vertical-align:middle}
.inv2 .cell-tag {font-size:12px; font-weight:500; color:var(--accent); white-space:nowrap}
.inv2 .cell-main {font-weight:600; color:var(--ink)}
.inv2 .cell-sub {font-size:11px; color:var(--ink-3); margin-top:1px}
.inv2 .cell-quiet {color:var(--ink-2)}
.inv2 .cell-none {color:var(--ink-3); font-style:italic}

/* ============================ Etiquetas ============================ */
.inv2 .chip {
  display:inline-flex; align-items:center; gap:6px; padding:3px 10px; border-radius:7px;
  font-size:11.5px; font-weight:600; white-space:nowrap;
}
.inv2 .chip.ok {background:var(--ok-soft); color:var(--ok)}
.inv2 .chip.warn {background:var(--warn-soft); color:var(--warn)}
.inv2 .chip.crit {background:var(--crit-soft); color:var(--crit)}
.inv2 .chip.neutral {background:var(--surface-3); color:var(--ink-2)}
.inv2 .chip.accent {background:var(--accent-soft); color:var(--accent)}
.inv2 .dot {width:6px; height:6px; border-radius:50%; background:currentColor; flex:none}

.inv2 .stars {display:inline-flex; gap:2px; align-items:center}
.inv2 .stars svg {width:13px; height:13px}
.inv2 .star-on {fill:var(--star)} .star-off{fill:var(--star-off)}
.inv2 .star-pick {display:inline-flex; gap:5px}
.inv2 .star-pick button {background:none; border:0; padding:2px; line-height:0; border-radius:6px}
.inv2 .star-pick svg {width:27px; height:27px}

/* ============================ Botones ============================ */
.inv2 .btn {
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:9px 15px; border-radius:9px; border:1px solid var(--line-strong);
  background:var(--surface); font-size:13px; font-weight:600; transition:all .13s;
}
.inv2 .btn:hover {background:var(--surface-2); border-color:var(--ink-3)}
.inv2 .btn svg {width:15px; height:15px}
.inv2 .btn.primary {background:var(--accent); border-color:var(--accent); color:#fff}
.inv2 .btn.primary:hover {background:var(--accent-ink); border-color:var(--accent-ink)}
.inv2 .btn.ghost {border-color:transparent; background:none; color:var(--ink-2)}
.inv2 .btn.ghost:hover {background:var(--surface-2); color:var(--ink)}
.inv2 .btn.danger {color:var(--crit); border-color:var(--crit-line)}
.inv2 .btn.danger:hover {background:var(--crit-soft)}
/* El archivo solo tenia .danger para botones de contorno. El boton que da de
   baja un equipo es la accion principal de su cuadro y ademas es la que no se
   deshace: sin esto salia con el violeta del acento y la letra roja encima. */
.inv2 .btn.primary.danger {background:var(--crit); border-color:var(--crit); color:#fff}
.inv2 .btn.primary.danger:hover {background:var(--crit); filter:var(--realce)}
.inv2 .btn.sm {padding:6px 12px; font-size:12px}

/* ============================ Listas ============================ */
.inv2 .att {display:flex; flex-direction:column; padding:0 8px 10px}
.inv2 .att-row {display:flex; align-items:center; gap:12px; padding:11px 12px; border-radius:9px; cursor:pointer}
.inv2 .att-row:hover {background:var(--surface-2)}
.inv2 .att-body {min-width:0; flex:1}
.inv2 .att-title {font-size:13.5px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.inv2 .att-meta {font-size:11.5px; color:var(--ink-3)}
.inv2 .att-num {font-size:11px; color:var(--ink-3)}

.inv2 .bars {padding:8px 20px 20px; display:flex; flex-direction:column; gap:13px}
.inv2 .bar-row {display:grid; grid-template-columns:108px 1fr 56px; align-items:center; gap:12px; font-size:12.5px}
.inv2 .bar-track {height:8px; border-radius:100px; background:var(--surface-3); overflow:hidden}
.inv2 .bar-fill {height:100%; border-radius:100px; background:var(--accent)}
.inv2 .bar-num {text-align:right; font-size:12.5px; color:var(--ink-2); font-weight:600}

.inv2 .anillos {display:grid; grid-template-columns:repeat(auto-fit,minmax(148px,1fr)); gap:8px; padding:6px 16px 20px}
.inv2 .anillo {display:flex; flex-direction:column; align-items:center; gap:9px; text-align:center; padding:10px}
.inv2 .anillo-svg {position:relative; width:104px; height:104px}
.inv2 .anillo-svg svg {width:104px; height:104px; display:block}
.inv2 .anillo-mid {position:absolute; inset:0; display:grid; place-content:center}
.inv2 .anillo-pct {font-size:21px; font-weight:700; letter-spacing:-.02em}
.inv2 .anillo-t {font-size:12px; font-weight:600; color:var(--ink-2)}
.inv2 .anillo-s {font-size:11px; color:var(--ink-3)}

.inv2 .area {padding:8px 18px 18px}
.inv2 .area svg {width:100%; height:196px; display:block; overflow:visible}
.inv2 .area-x {display:flex; justify-content:space-between; margin-top:9px; font-size:11px; color:var(--ink-3)}

.inv2 .seg {display:flex; gap:4px; flex-wrap:wrap; padding:4px; background:var(--surface); border:1px solid var(--line); border-radius:10px; align-self:flex-start; max-width:100%; box-shadow:var(--shadow)}
.inv2 .seg-b {display:inline-flex; align-items:center; gap:7px; border:0; background:none; padding:8px 14px; border-radius:7px; font-size:12.5px; font-weight:600; color:var(--ink-2)}
.inv2 .seg-b:hover {background:var(--surface-2); color:var(--ink)}
.inv2 .seg-b[aria-current="true"] {background:var(--accent); color:#fff}
.inv2 .seg-n {font-size:11px; opacity:.75}

.inv2 .donut-wrap {display:flex; align-items:center; gap:20px; padding:6px 20px 22px}
.inv2 .donut {position:relative; width:150px; height:150px; flex:none}
.inv2 .donut svg {width:150px; height:150px; display:block}
.inv2 .donut-mid {position:absolute; inset:0; display:grid; place-content:center; text-align:center}
.inv2 .donut-num {font-size:26px; font-weight:700; line-height:1; display:block; letter-spacing:-.02em}
.inv2 .donut-lbl {font-size:11px; color:var(--ink-3); margin-top:3px}
.inv2 .leyenda {list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:10px; flex:1; min-width:0}
.inv2 .leyenda li {display:flex; align-items:center; gap:10px; font-size:12.5px}
.inv2 .leyenda .lg-t {color:var(--ink-2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.inv2 .leyenda .lg-v {margin-left:auto; font-size:12.5px; color:var(--ink); font-weight:700}

/* ============================ Catálogos y filtros ============================ */
.inv2 .cat-grid {display:grid; grid-template-columns:repeat(auto-fit,minmax(286px,1fr)); gap:18px; align-items:start}
.inv2 .cat-add {display:flex; gap:8px; padding:0 20px 14px}
.inv2 .cat-add input {flex:1; min-width:0; font:inherit; font-size:13px; color:var(--ink); background:var(--surface-2); border:1px solid var(--line); border-radius:8px; padding:9px 13px; outline:0}
.inv2 .cat-list {list-style:none; margin:0; padding:0 10px 10px; max-height:336px; overflow-y:auto}
.inv2 .cat-list li {display:flex; align-items:center; gap:10px; padding:9px 11px; border-radius:8px}
.inv2 .cat-list li:hover {background:var(--surface-2)}
.inv2 .cat-nom {font-size:13px; flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:500}
.inv2 .cat-uso {font-size:11px; color:var(--ink-3); font-style:italic; white-space:nowrap}
.inv2 .cat-uso.on {font-style:normal; font-weight:600; color:var(--accent); background:var(--accent-soft); border-radius:100px; padding:2px 9px}
.inv2 .cat-del {border:0; background:none; padding:6px; border-radius:7px; color:var(--ink-3); line-height:0; flex:none}
.inv2 .cat-del svg {width:15px; height:15px}
.inv2 .cat-del:hover:not(:disabled) {background:var(--crit-soft); color:var(--crit)}
.inv2 .cat-del:disabled {opacity:.25; cursor:not-allowed}

.inv2 .filtros {display:flex; align-items:center; gap:9px; flex-wrap:wrap; padding:0 20px 15px}
.inv2 .filtros-lbl {font-size:12px; color:var(--ink-3); font-weight:500}
.inv2 .filtros select {width:auto; min-width:148px; padding:7px 12px; font-size:12.5px; font-weight:500; background:var(--surface-2); border:1px solid var(--line); border-radius:8px; color:var(--ink-2)}
.inv2 .filtros select.on {border-color:var(--accent-line); color:var(--accent); background:var(--accent-soft); font-weight:600}

/* ============================ Ficha lateral ============================ */
.inv2 .scrim {position:fixed; inset:0; background:rgba(17,24,39,.35); opacity:0; pointer-events:none; transition:opacity .2s; z-index:40; backdrop-filter:blur(2px)}
.inv2 .scrim.open {opacity:1; pointer-events:auto}
/* animation:none NO es de adorno. La .panel de BLXBOX —el cuerpo de los diez
   modales— lleva `animation: subir … both`, y el fotograma final de subir es
   `transform: none`. Una animacion con relleno both GANA sobre la propiedad,
   asi que sin apagarla el translateX(102%) que esconde esta ficha no se
   aplica: la ficha sale abierta y tapando media pantalla, sin dar ningun
   error. Es el precio de que el archivo y BLXBOX llamen .panel a dos cosas
   distintas, y por eso todo esto va acotado bajo .inv2. */
.inv2 .panel {
  animation: none;
  position:fixed; top:0; right:0; bottom:0; width:min(500px,100%); background:var(--surface);
  border-left:1px solid var(--line); box-shadow:var(--shadow-lg); z-index:45;
  transform:translateX(102%); transition:transform .26s cubic-bezier(.32,.72,0,1);
  display:flex; flex-direction:column;
}
.inv2 .panel.open {transform:translateX(0)}
.inv2 .panel-head {padding:22px 24px 16px; border-bottom:1px solid var(--line)}
.inv2 .panel-tag {display:flex; align-items:center; gap:10px; margin-bottom:8px}
.inv2 .panel-head h2 {font-size:20px; margin-bottom:3px}
.inv2 .panel-head .sub {font-size:12px; color:var(--ink-3)}
.inv2 .panel-chips {display:flex; flex-wrap:wrap; gap:7px; margin-top:13px}
.inv2 .tabs {display:flex; gap:3px; padding:12px 16px 0; border-bottom:1px solid var(--line)}
.inv2 .tab {border:0; background:none; padding:9px 13px; font-size:12.5px; font-weight:600; color:var(--ink-3); border-radius:8px 8px 0 0; border-bottom:2px solid transparent; margin-bottom:-1px}
.inv2 .tab:hover {color:var(--ink)}
.inv2 .tab[aria-selected="true"] {color:var(--accent); border-bottom-color:var(--accent)}
.inv2 .panel-body {padding:20px 24px 26px; overflow-y:auto; flex:1; display:flex; flex-direction:column; gap:20px}
.inv2 .panel-foot {padding:14px 24px; border-top:1px solid var(--line); display:flex; gap:9px; flex-wrap:wrap; background:var(--surface-2)}
.inv2 .close-x {position:absolute; top:20px; right:20px; border:0; background:var(--surface-2); padding:7px; border-radius:8px; color:var(--ink-3); line-height:0; z-index:2}
.inv2 .close-x:hover {background:var(--surface-3); color:var(--ink)}
.inv2 .close-x svg {width:16px;height:16px}

.inv2 .field-grid {display:grid; grid-template-columns:1fr 1fr; gap:9px}
.inv2 .field {background:var(--surface-2); border-radius:9px; padding:10px 13px}
.inv2 .field.wide {grid-column:1/-1}
.inv2 .field dt {font-size:11px; color:var(--ink-3); font-weight:500; margin-bottom:3px}
.inv2 .field dd {margin:0; font-size:13px; color:var(--ink); font-weight:500}
.inv2 .sect-title {font-size:12.5px; color:var(--ink); font-weight:700}

.inv2 .note {background:var(--accent-soft); border-radius:9px; padding:12px 14px; font-size:12.5px; color:var(--ink-2); line-height:1.55}
.inv2 .motivo-list {display:flex; flex-wrap:wrap; gap:7px}

.inv2 .timeline {display:flex; flex-direction:column; position:relative; padding-left:22px}
.inv2 .timeline::before {content:""; position:absolute; left:5px; top:10px; bottom:10px; width:2px; background:var(--line)}
.inv2 .tl {position:relative; padding:9px 0}
.inv2 .tl::before {content:""; position:absolute; left:-22px; top:15px; width:12px; height:12px; border-radius:50%; background:var(--surface); border:3px solid var(--line-strong)}
.inv2 .tl.is-accent::before {border-color:var(--accent); background:var(--accent)}
.inv2 .tl-date {font-size:11px; color:var(--ink-3)}
.inv2 .tl-text {font-size:13px; margin-top:1px}

.inv2 .countdown {display:flex; align-items:baseline; gap:12px; padding:18px; border-radius:11px; background:var(--surface-2)}
.inv2 .countdown .num {font-size:38px; font-weight:700; line-height:1; letter-spacing:-.03em}
.inv2 .countdown .lbl {font-size:12.5px; color:var(--ink-3); line-height:1.4}
.inv2 .countdown.vencido {background:var(--crit-soft)} .countdown.vencido .num{color:var(--crit)}
.inv2 .countdown.pronto {background:var(--warn-soft)} .countdown.pronto .num{color:var(--warn)}
.inv2 .countdown.bien {background:var(--ok-soft)} .countdown.bien .num{color:var(--ok)}

/* ============================ Diálogos ============================ */
.inv2 .modal-wrap {position:fixed; inset:0; z-index:60; display:grid; place-items:center; padding:22px; background:rgba(17,24,39,.45); opacity:0; pointer-events:none; transition:opacity .18s; backdrop-filter:blur(2px)}
.inv2 .modal-wrap.open {opacity:1; pointer-events:auto}
.inv2 .modal {background:var(--surface); border-radius:14px; box-shadow:var(--shadow-lg); width:min(580px,100%); max-height:88vh; display:flex; flex-direction:column; transform:translateY(8px); transition:transform .18s}
.inv2 .modal-wrap.open .modal {transform:none}
.inv2 .modal-wide {width:min(760px,100%)}

/* El visor de la carta. Ancho y alto generosos: se abre para LEER un papel
   firmado, no para mirarlo de lejos. El cuerpo va sin relleno para que el
   documento llegue a los bordes.

   El alto se fija en el MODAL y el documento rellena lo que sobre. Darselo al
   documento no funciona: entre el alto del marco, la cabecera y el pie se
   pasaba del max-height del modal, y como el modal va centrado en una rejilla
   lo que sobraba se salia por arriba de la pantalla.

   Y el nombre NO puede ser .visor: BLXBOX ya tiene esa clase para una capa a
   pantalla completa —position:fixed, inset:0— y el marco heredaba el alto de
   la ventana entera, que el modal recortaba sin que se notara. */
.inv2 .modal-visor {width:min(980px,100%); height:88vh}
.inv2 .modal-visor .modal-body {padding:0; gap:0; flex:1; min-height:0; overflow:hidden}
.inv2 .carta-marco {
  width:100%; height:100%; border:0; display:block; background:var(--surface-2);
}
.inv2 .carta-imagen {
  width:100%; height:100%; object-fit:contain;
  display:block; background:var(--surface-2);
}
/* Descargar es un enlace, no un boton: se le quita el subrayado y se le da la
   misma altura que a los botones de al lado. */
.inv2 .modal-visor .modal-foot a.btn {text-decoration:none}
.inv2 .modal-head {padding:20px 24px 14px; border-bottom:1px solid var(--line)}
.inv2 .modal-head h3 {font-size:18px}
.inv2 .modal-head p {margin:4px 0 0; font-size:12.5px; color:var(--ink-3)}
.inv2 .modal-body {padding:20px 24px; overflow-y:auto; display:flex; flex-direction:column; gap:18px}
.inv2 .modal-foot {padding:14px 24px; border-top:1px solid var(--line); display:flex; gap:9px; justify-content:flex-end; align-items:center; background:var(--surface-2)}

.inv2 .motivos {display:flex; flex-direction:column; gap:2px; max-height:238px; overflow-y:auto; padding:4px; background:var(--surface-2); border-radius:10px}
.inv2 .motivo {display:flex; align-items:center; gap:12px; padding:9px 12px; border-radius:7px; cursor:pointer; font-size:13px}
.inv2 .motivo:hover {background:var(--surface)}
.inv2 .motivo input {accent-color:var(--accent); width:15px; height:15px; flex:none}
.inv2 .motivo .m-txt {flex:1}
.inv2 .motivo .m-star {font-size:11.5px; color:var(--ink-3); white-space:nowrap; font-weight:600}
.inv2 .motivo.crit .m-star {color:var(--crit)}

.inv2 .sug {display:flex; align-items:center; gap:12px; padding:13px 15px; border-radius:10px; background:var(--accent-soft); font-size:13px; color:var(--accent); font-weight:500}
.inv2 textarea, .inv2 input[type="date"], .inv2 select {width:100%; font:inherit; font-size:13px; color:var(--ink); background:var(--surface-2); border:1px solid var(--line); border-radius:8px; padding:9px 12px; resize:vertical}
.inv2 textarea:focus, .inv2 input:focus, .inv2 select:focus {outline:0; border-color:var(--accent-line)}
.inv2 label.lbl {font-size:11.5px; color:var(--ink-3); font-weight:500; display:block; margin-bottom:6px}

.inv2 .fgrid {display:grid; grid-template-columns:repeat(auto-fit,minmax(205px,1fr)); gap:13px}
.inv2 .fcampo input {width:100%; font:inherit; font-size:13px; color:var(--ink); background:var(--surface-2); border:1px solid var(--line); border-radius:8px; padding:9px 12px}
.inv2 .fcampo input:disabled {opacity:.45; cursor:not-allowed}
.inv2 .req {color:var(--crit)}
.inv2 .opc {font-size:10px; color:var(--ink-3); font-weight:400}
.inv2 .form-hint {margin:11px 0 0; font-size:12.5px; color:var(--ink-3); background:var(--surface-2); border-radius:9px; padding:11px 13px; line-height:1.55}
.inv2 .form-hint b {color:var(--ink-2); font-weight:600}
.inv2 .form-aviso {margin-right:auto; font-size:12.5px; color:var(--crit); font-weight:600}

.inv2 .coment-lista {display:flex; flex-direction:column; gap:8px; margin-top:10px}
.inv2 .coment {background:var(--surface-2); border-radius:9px; padding:10px 13px; font-size:13px; border-left:3px solid var(--accent-line); line-height:1.5}
.inv2 .coment-meta {font-size:11px; color:var(--ink-3); margin-bottom:3px}
.inv2 .coment-acciones {display:flex; gap:8px; justify-content:flex-end; margin-top:10px}
.inv2 .coment-nuevo {display:flex; gap:8px; margin-top:11px; align-items:flex-start}
.inv2 .coment-nuevo textarea {flex:1; min-height:44px}
.inv2 .coment-nuevo .btn {flex:none}

.inv2 .check {display:flex; align-items:center; gap:9px; margin-top:12px; font-size:13px; color:var(--ink-2); cursor:pointer; user-select:none}
.inv2 .check input {accent-color:var(--accent); width:16px; height:16px; flex:none}

.inv2 .avatar-tabla {width:34px; height:34px; border-radius:50%; background:var(--accent-soft); color:var(--accent); display:grid; place-items:center; font-size:11.5px; font-weight:700; flex:none}
.inv2 .sel-rol {width:auto; min-width:148px; padding:6px 11px; font-size:12.5px; font-weight:500; border-radius:8px}
.inv2 .fila-usuario {cursor:default}
.inv2 .fila-usuario:hover {background:transparent}
.inv2 .roles {list-style:none; margin:0; padding:6px 20px 18px; display:flex; flex-direction:column; gap:11px}
.inv2 .roles li {display:flex; align-items:center; gap:13px; font-size:13px}
.inv2 .rol-desc {color:var(--ink-2); flex:1; min-width:0}
.inv2 .rol-n {font-weight:700; font-size:12.5px; color:var(--ink-2); background:var(--surface-2); border-radius:100px; padding:2px 11px}
.inv2 .btn.ghost.danger {color:var(--crit)}
.inv2 .btn.ghost.danger:hover {background:var(--crit-soft)}

.inv2 .pag {display:flex; align-items:center; gap:14px; flex-wrap:wrap; padding:13px 20px; border-top:1px solid var(--line)}
.inv2 .pag-info {font-size:12.5px; color:var(--ink-3)}
.inv2 .pag-btns {display:flex; gap:5px; margin-left:auto; flex-wrap:wrap}
.inv2 .pag-b {min-width:33px; height:33px; padding:0 10px; border:1px solid var(--line); background:var(--surface); border-radius:8px; font-size:12.5px; font-weight:600; color:var(--ink-2); display:inline-flex; align-items:center; justify-content:center}
.inv2 .pag-b:hover:not(:disabled) {background:var(--surface-2); color:var(--ink)}
.inv2 .pag-b[aria-current="true"] {background:var(--accent); border-color:var(--accent); color:#fff}
.inv2 .pag-b:disabled {opacity:.35; cursor:not-allowed}
.inv2 .pag-sep {color:var(--ink-3); padding:0 2px; align-self:center; font-size:12.5px}

.inv2 .mail {border:1px solid var(--line); border-radius:11px; overflow:hidden}
.inv2 .mail-head {padding:11px 14px; background:var(--surface-2); border-bottom:1px solid var(--line); font-size:12px; color:var(--ink-3); display:flex; flex-direction:column; gap:3px}
.inv2 .mail-head b {color:var(--ink-2); font-weight:600}
.inv2 .mail-body {padding:15px 16px; font-size:13px; display:flex; flex-direction:column; gap:10px; line-height:1.65}
.inv2 .mail-body .tag-line {display:inline-block; font-family:"DM Mono",monospace; font-size:12px; background:var(--accent-soft); border-radius:8px; padding:9px 12px; color:var(--accent)}

.inv2 .tema {display:flex; gap:3px; padding:3px; background:var(--surface-2); border:1px solid var(--line); border-radius:9px; flex:none}
.inv2 .tema button {border:0; background:none; padding:7px 9px; border-radius:7px; color:var(--ink-3); line-height:0}
.inv2 .tema button:hover {background:var(--surface); color:var(--ink)}
.inv2 .tema button[aria-current="true"] {background:var(--surface); color:var(--accent); box-shadow:var(--shadow)}
.inv2 .tema svg {width:16px; height:16px}

.inv2 .usuario {
  display:flex; align-items:center; gap:10px; flex:none;
  padding-left:14px; border-left:1px solid var(--line);
}
.inv2 .usuario-nom {font-size:13px; font-weight:600; line-height:1.2; white-space:nowrap}
.inv2 .usuario-rol {font-size:11px; color:var(--ink-3); margin-top:1px; white-space:nowrap}
@media (max-width:1150px){ .usuario-txt{display:none} .usuario{padding-left:10px} }

.inv2 .toast {position:fixed; bottom:24px; left:50%; transform:translate(-50%,14px); z-index:80; background:var(--ink); color:var(--surface); padding:12px 19px; border-radius:10px; font-size:13px; font-weight:600; box-shadow:var(--shadow-lg); opacity:0; pointer-events:none; transition:opacity .2s, transform .2s; display:flex; align-items:center; gap:9px}
.inv2 .toast.show {opacity:1; transform:translate(-50%,0)}
.inv2 .toast svg {width:15px;height:15px;color:var(--accent-line)}

.inv2 .empty {padding:46px 22px; text-align:center; color:var(--ink-3)}
.inv2 .empty h3 {font-size:15px; color:var(--ink-2); margin-bottom:5px}

@media (max-width:900px){
  .inv2 .inv2-marco {grid-template-columns:1fr; grid-template-rows:auto minmax(0,1fr)}
  .inv2 .nav {height:auto; flex:none; flex-direction:row; align-items:center; overflow-x:auto; padding:0 10px; border-right:0; border-bottom:1px solid var(--line)}
  .inv2 .nav-label, .inv2 .nav-foot {display:none}
  .inv2 .nav-list {flex-direction:row; gap:4px; padding:9px 0}
  .inv2 .nav-item {white-space:nowrap}
  .inv2 .brand {padding:12px 8px}
  .inv2 .split {grid-template-columns:1fr}
  .inv2 .content, .inv2 .topbar {padding-left:16px; padding-right:16px}
  .inv2 .panel {width:100%}
}
