/* =========================================================================
   Tema. Todo el color del validador sale de aquí: cambiar la identidad
   visual es tocar este bloque y nada más. Los pasos de --azul van de 900
   (más oscuro) a 050 (más claro), como en las escalas de Tailwind/Material.
   ========================================================================= */
:root{
  /* ----- Marca (azul) -----
     Rampa hue 199° muestreada del banner de referencia (#036391 = paso 700).
     Todos los pares texto/fondo cumplen contraste WCAG AA. */
  --azul-900:#083145;   /* tinta oscura (títulos h1)            */
  --azul-800:#064765;   /* head de card oscuro                  */
  --azul-750:#0a5578;   /* separador dentro del sidebar         */
  --azul-700:#036491;   /* MARCA: botones, .head, toggle activo */
  --azul-600:#0774a6;   /* head de las tarjetas por nodo        */
  --azul-500:#0b6d97;   /* acentos sobre blanco (.tag, .cat)    */
  --azul-450:#0774a6;   /* enlaces de <summary> y buscador      */
  --azul-400:#49a8d4;   /* borde del item activo / anillo foco  */
  --azul-350:#075f88;   /* hover del icono de tooltip           */
  --azul-200:#c0deed;   /* halo de foco                         */
  --azul-100:#e0eef5;   /* fondo de .tag                        */
  --azul-050:#f0f7fa;   /* hover de fila, zona de arrastre      */

  /* ----- Sidebar (azul vivo de la marca) ----- */
  --sb-bg:#036491;      /* fondo del menú lateral               */
  --sb-hover:#05587f;   /* hover de un enlace                   */
  --sb-activo:#05496a;  /* item activo (más hundido)            */
  --sb-borde:#0a5578;   /* borde inferior del logo              */
  --azul-tx:#dbe9f2;    /* texto del sidebar                    */
  --azul-tx2:#b0cadb;   /* texto secundario del sidebar         */

  /* ----- Neutros ----- */
  --papel:#fff;
  --fondo:#eef1f4;
  --tinta:#33475b;
  --texto:#222;
  --texto-2:#333;
  --texto-3:#444;
  --texto-4:#555;
  --texto-5:#666;
  --texto-alt:#4a5568;
  --tenue:#8893a0;      /* textos de apoyo (11-12px)            */
  --tenue-2:#888;       /* encabezados de columna               */
  --tenue-3:#999;       /* valores ausentes                     */
  --linea:#eceff1;
  --linea-2:#e3e8ee;
  --linea-3:#d6dde4;
  --linea-4:#dbe3ea;
  --sombra:0 1px 4px rgba(0,0,0,.12);
  --radio:8px;

  /* ----- Semánticos: NO comparten familia con la marca a propósito.
     El azul es cromo; el rojo/verde/ámbar es información. ----- */
  --ok:#1e7a44;      --ok-bg:#eafaf0;  --ok-bd:#bce8ce;
  --ok-ic:#1f8a4c;   --ok-fuerte:#27ae60;
  --err:#c0392b;     --err-bg:#fdecea; --err-bd:#f5c2bb;
  --err-fuerte:#e74c3c; --err-oscuro:#a93226; --err-tx:#9b2c20;
  --adv:#b8740c;     --adv-bg:#fef5ea; --adv-bd:#f6dab0;
  --adv-fuerte:#e67e22; --adv-tx:#9c6410;

  /* ----- Granate del PAC propio -----
     Es MARCA (el rojo del logo de Quadrum), no semántica: no comparte token con
     --err ni se usa en ningún veredicto. Se distingue del rojo de error porque
     aquél siempre va como texto sobre fondo claro y con ✗; éste sólo aparece
     como bloque sólido con texto blanco, y nunca afirma nada del comprobante. */
  --pac-bg:#8a1c23; --pac-pal:#f7ecec;
}

 body{font-family:system-ui,Segoe UI,Arial,sans-serif;background:var(--fondo);margin:0;color:var(--texto)}
 .layout{display:flex;min-height:100vh}
 .sidebar{width:230px;background:var(--sb-bg);color:var(--azul-tx);flex-shrink:0;padding:0;position:sticky;top:0;height:100vh;
        transition:width .15s ease}
 .sidebar .logo{display:flex;align-items:center;gap:10px;padding:14px 14px 14px 16px;font-size:16px;font-weight:700;color:var(--papel);border-bottom:1px solid var(--sb-borde)}
 /* Botón de plegar. Hereda de `button` (azul relleno), que aquí sobra: sobre el
    azul del menú se vería un recuadro dentro de otro. */
 .menu-btn{flex-shrink:0;background:transparent;color:var(--azul-tx);border:0;
        padding:6px;border-radius:6px;line-height:0;cursor:pointer}
 .menu-btn svg{width:18px;height:18px;display:block}
 .menu-btn:hover{background:var(--sb-hover);color:var(--papel)}
 .sidebar .logo small{display:block;font-size:11px;font-weight:400;color:var(--azul-tx2);margin-top:2px}
 .sidebar a{display:flex;align-items:center;gap:10px;padding:13px 20px;color:var(--azul-tx);text-decoration:none;font-size:14px;border-left:3px solid transparent}
 /* El icono distingue la ACCIÓN: hoja = validar un XML (offline), lupa =
    consultar al SAT (en línea). Sustituye a los encabezados de grupo. */
 .sidebar .ico{width:16px;height:16px;flex-shrink:0;opacity:.7}
 .sidebar a:hover .ico,.sidebar a.activo .ico{opacity:1}
 .sidebar a:hover{background:var(--sb-hover)}
 .sidebar a.activo{background:var(--sb-activo);border-left-color:var(--azul-400);color:var(--papel);font-weight:600}
 /* position para el aviso de versión, que se ancla a SU esquina y no a la del
    navegador: fijo al viewport se quedaría flotando sobre el contenido al bajar. */
 .content{flex:1;padding:0;min-width:0;position:relative}
 /* ----- Menú plegado -----
    Se encoge a una franja de iconos en vez de desaparecer: así el sitio a donde
    se quiere ir sigue estando a un clic, que es lo que se pierde escondiéndolo
    del todo. La etiqueta pasa a ser el `title` del enlace (lo pone el JS de
    _menu.html). El estado se guarda en localStorage porque cada sección es una
    carga de página nueva: sin eso el menú se volvería a abrir en cada clic. */
 .menu-plegado .sidebar{width:56px}
 .menu-plegado .sidebar .tx,
 .menu-plegado .sidebar .logo-tx,
 .menu-plegado .sesion-quien,
 .menu-plegado .sesion form{display:none}
 .menu-plegado .sidebar .logo{padding:14px 0;justify-content:center}
 .menu-plegado .sidebar a{justify-content:center;padding:13px 0;
        border-left-width:0;border-right:3px solid transparent}
 .menu-plegado .sidebar a.activo{border-right-color:var(--azul-400)}
 .menu-plegado .sesion{padding:14px 0;text-align:center}
 .menu-plegado .sesion-entrar{justify-content:center}
 .wrap{max-width:960px;margin:24px auto;padding:0 16px}
 /* Ancho para las pantallas que muestran DATOS y no formularios: el árbol del
    comprobante y sus tablas de atributos. A 960px la columna de valores parte
    los base64 y las rutas de nodo en cuatro renglones; el formulario de arriba
    no se estira con ellas porque leer un campo de 1500px de ancho es peor. */
 .wrap.ancho{max-width:1500px}
 .wrap.ancho .cargador:not(.zona),.wrap.ancho .panel{max-width:960px;margin-left:auto;margin-right:auto}
 h1{font-size:20px;color:var(--azul-900)}
 /* Encabezado: solo el logo de marca, centrado en el ancho del contenido */
 .encabezado{display:flex;justify-content:center;margin:13px 0}
 .logo-marca{height:130px;width:auto;max-width:100%}
 /* Información de contexto —dónde estás y a dónde volver—, no una alerta: por eso
    va en gris y arrinconado, y no como franja de color cruzando la página. */
 .aviso-version{position:absolute;top:20px;right:24px;z-index:2;
        width:490px;box-sizing:border-box;text-align:left;font-size:12.5px;line-height:1.5;
        color:var(--texto-2);background:var(--papel);border:1px solid var(--linea-3);
        border-left:3px solid var(--azul-500);border-radius:var(--radio);
        padding:12px 15px;display:flex;flex-direction:column;gap:8px}
 .aviso-version p{margin:0}
 .aviso-version b{color:var(--tinta);font-weight:600}
 .aviso-version a{color:var(--azul-500);text-decoration:none;font-weight:600;
        margin-top:4px;align-self:flex-start}
 .aviso-version a:hover{text-decoration:underline}
 /* Dónde deja de caber. El logo mide 302 px de ancho (395x170 a 130 px de alto) y
    va centrado, así que su borde derecho está en content/2 + 151; el aviso empieza
    en content - 24 - 490. Que no se toquen pide content >= 1330, y con la barra
    lateral de 230 px eso es una ventana de 1560. Por debajo vuelve al flujo, arriba
    del todo: taparle el logo a la marca es peor que mover el aviso.

    Si se cambia el ancho del aviso, este número se recalcula:
        ventana = 350 + 2*ancho + 230 */
 @media (max-width:1560px){
   .aviso-version{position:static;width:auto;max-width:560px;margin:18px auto 0}
 }
 .card{background:var(--papel);border-radius:var(--radio);box-shadow:var(--sombra)}
 .card.sep{margin-top:18px}
 .head{background:var(--azul-700);color:var(--papel);padding:14px 18px;font-size:18px;display:flex;justify-content:space-between;border-radius:var(--radio) var(--radio) 0 0}
 .head.falta{background:var(--err-oscuro)}
 .head-sum{font-size:13px}
 /* Lado derecho de la cabecera cuando además del dato hay una acción. */
 .head-acc{display:flex;align-items:center;gap:12px}
 /* Botón sobre el azul de la cabecera: contorno, no relleno, para que no compita
    con el botón de enviar del formulario, que sí es la acción principal. */
 .btn-copiar{background:transparent;border:1px solid rgba(255,255,255,.55);
        color:var(--papel);padding:4px 12px;border-radius:5px;font-size:13px;
        line-height:1.4;min-width:104px}
 .btn-copiar:hover{background:rgba(255,255,255,.14)}
 /* Nota al pie de una tarjeta: explica cómo leer la columna de estatus sin
    meter la explicación en cada renglón. */
 .pie-nota{padding:10px 18px;font-size:12px;color:var(--tenue);
        border-top:1px solid var(--linea);line-height:1.5}
 /* Tabla de namespaces: las dos columnas son URI largas, así que la primera no
    puede ser la etiqueta angosta de 230px del resto de las tablas. */
 .t-ns td.lbl{width:45%;font-family:ui-monospace,Consolas,monospace;
        font-weight:400;font-size:12.5px;word-break:break-all}
 .t-ns td.val{font-size:12.5px}
 /* Segunda línea de una celda: el dato de apoyo (descripción, domicilio) que
    confirma que la clave consultada es la que se buscaba. */
 .sub-val{margin-top:3px;font-family:system-ui,Segoe UI,Arial,sans-serif;
        font-size:12.5px;color:var(--tenue)}
 table{width:100%;border-collapse:collapse}
 td{padding:9px 14px;border-bottom:1px solid var(--linea);vertical-align:top;font-size:14px}
 td.lbl{width:230px;color:var(--texto-3);font-weight:600}
 td.val{font-family:ui-monospace,Consolas,monospace;word-break:break-all;color:var(--texto-2)}
 .scrollbox{max-height:88px;overflow:auto;display:block;background:#fafbfc;border:1px solid var(--linea-2);border-radius:4px;padding:6px 8px;white-space:pre-wrap;word-break:break-all;font-size:11.5px;line-height:1.45}
 /* La cadena original es el único valor que se lee entero (se compara contra
    otra), no de un vistazo: se le da más alto antes de que aparezca el scroll. */
 .scrollbox.alto{max-height:340px;font-size:12.5px}
 td.st{width:60px;text-align:center;font-size:18px}
/* Recuadro punteado para soltar un archivo. En el validador ya no se usa (la
   zona de arrastre es la ventana entera), pero sigue vivo en el panel lateral de
   "Árbol de CFDI", que carga sus XML ahí. */
 .drop{position:relative;border:2px dashed #9bb;border-radius:var(--radio);
        padding:28px;text-align:center;background:var(--papel);margin-bottom:18px;
        transition:border-color .15s,background .15s}
 .drop.dragging{border-color:var(--azul-700);background:var(--azul-050)}
/* ----- Barra de carga -----
   Era un recuadro punteado de 28px de alto que sólo decía "arrastra aquí".
   Ahora la zona de arrastre es la ventana entera (ver la capa .soltar), así que
   aquí sólo quedan las acciones y la barra puede ser una franja delgada. */
 /* La caja abraza a los botones en vez de cruzar la pantalla: llena de blanco
    los 1000px de ancho, lo que se veía era el vacío de los lados y no las
    acciones. `fit-content` la deja del tamaño de lo que lleva dentro. */
 .cargador{position:relative;width:fit-content;max-width:100%;
        background:var(--papel);border-radius:14px;box-shadow:var(--sombra);
        padding:10px 14px;margin:0 auto 18px;text-align:center}
 /* La de "Estado del CFDI" lleva dentro la rejilla de UUID/RFC/Total: ésa sí
    necesita el ancho completo. */
 .cargador.ancha{width:auto;border-radius:var(--radio);padding:14px 18px}
 /* ----- Zona de carga grande -----
    Sólo mientras no hay resultado en pantalla. Es la invitación a empezar, así
    que aquí sí conviene ocupar sitio: el botón manda y el recuadro de arrastre
    enseña la otra forma de hacerlo. En cuanto hay algo que leer, esta cara
    desaparece y queda la franja (ver el macro `carga` de pagina.html). */
 .cargador.zona{width:auto;max-width:620px;border-radius:var(--radio);
        padding:0 0 16px}
 .zona-tit{padding:13px 18px;margin-bottom:22px;text-align:left;font-size:16px;
        font-weight:600;color:var(--azul-900);border-bottom:1px solid var(--linea)}
 .cargador.zona .cargador-int{margin:0 18px 18px}
 .btn-cargar{display:inline-flex;align-items:center;gap:9px;cursor:pointer;
        background:var(--azul-700);color:var(--papel);border-radius:8px;
        padding:11px 22px;font-size:15px;font-weight:600}
 .btn-cargar:hover{background:var(--azul-800)}
 .btn-cargar .ico{width:17px;height:17px;flex-shrink:0}
 .zona-soltar{margin:22px 18px 0;padding:24px 12px;border:2px dashed var(--linea-3);
        border-radius:10px;color:var(--tenue-3)}
 .zona-soltar svg{width:42px;height:42px;display:block;margin:0 auto 6px}
 .zona-soltar-tx{font-size:15px;color:var(--tenue)}
 .zona-acc{display:flex;align-items:center;gap:12px;margin:18px 18px 0}
 /* La barra ocupa el hueco sobrante y empuja las acciones a la derecha; cuando
    no se está enviando, el hueco lo ocupa igual (flex:1 sobre un elemento
    oculto no reserva nada, así que los botones se quedan a la derecha). */
 .zona-acc .progreso{flex:1}
 .zona-acc .btn-sec{margin-left:auto}
 /* ----- Barra de progreso -----
    Indeterminada a propósito: el servidor no informa el avance, sólo tarda. Lo
    que comunica es "sigue trabajando", que es justo lo que faltaba mientras el
    WS del SAT se toma sus segundos. */
 .progreso{display:none;height:6px;border-radius:99px;background:var(--linea-2);
        overflow:hidden}
 .cargador:not(.zona) .progreso{margin-top:9px}
 .enviando .progreso{display:block}
 .progreso span{display:block;width:38%;height:100%;border-radius:99px;
        background:var(--azul-700);animation:progresoVa 1.15s ease-in-out infinite}
 @keyframes progresoVa{0%{transform:translateX(-105%)}100%{transform:translateX(300%)}}
 @media (prefers-reduced-motion:reduce){.progreso span{animation:none;width:100%;opacity:.5}}
 .cargador-int{font-size:14px;color:var(--texto-3);margin-bottom:10px}
 .cargador-fila{display:flex;flex-wrap:wrap;align-items:center;
        justify-content:center;gap:8px}
 /* Botones un punto más chicos que los de un formulario: aquí son una franja de
    acciones, no el cuerpo de la pantalla. */
 .cargador-fila button,.cargador-fila .btn-sec{padding:8px 16px;font-size:14px;
        border-radius:999px}
 /* Rayita entre acciones. Va como elemento y no como ::before de cada botón:
    un pseudo-elemento se dibujaría DENTRO del botón, no entre dos. */
 .cargador-sep{width:1px;height:20px;background:var(--linea-3);flex-shrink:0}
 /* La del indicador sí es un ::before suyo, porque tiene que desaparecer con él
    cuando aún no se ha validado y no hay entorno que mostrar. */
 .cargador .env-ind{position:static;font-size:12px}
 .cargador .env-ind:empty{display:none}
 .cargador .env-ind:not(:empty)::before{content:"";width:1px;height:22px;
        background:var(--linea-3);margin-right:4px}
 /* El input real no se ve pero SÍ se renderiza: con display:none el navegador no
    puede enseñar su aviso de "campo obligatorio" y lo reporta como error. */
 .archivo-oculto{position:absolute;width:1px;height:1px;opacity:0;
        pointer-events:none;left:50%;bottom:0}
 /* Es un <label>, no un <button>: hay que devolverle la pinta de botón. */
 /* El icono le dice de un vistazo que ahí se sube un archivo; sin él los tres
    botones se leen como tres acciones intercambiables. */
 .cargador .btn-elegir{margin-left:0;cursor:pointer;line-height:normal;
        display:inline-flex;align-items:center;gap:7px}
 .cargador .btn-elegir .ico{width:15px;height:15px;flex-shrink:0;opacity:.8}
 /* Un solo renglón bajo los botones: la pista mientras no hay archivo, el
    nombre cuando sí, y el aviso si se intenta enviar en vacío. Sin `min-height`
    ni reserva: en las secciones donde nace vacío, no ocupa nada. */
 .cargador .fname{margin-top:8px;font-size:13px;color:var(--ok);font-weight:600;
        padding:0 6px}
 .cargador .fname:empty{display:none}
 .cargador .fname.pista{font-size:12px;color:var(--tenue);font-weight:400}
 .cargador .fname.falta{color:var(--err);font-weight:600}
 .env-ind{position:absolute;top:10px;right:14px;display:flex;align-items:center;gap:8px;font-size:12px}
 .env-on{display:inline-flex;align-items:center;gap:5px;font-weight:700;color:var(--tinta)}
 .env-on::before{content:"";width:8px;height:8px;border-radius:50%;background:#28a745;display:inline-block}
 .env-off{color:#9aa5b1}
 .env-sep{color:#cbd3db}
 .cargador .hint,.panel .hint{font-size:12px;color:var(--tenue);margin-top:10px}
/* ----- Capa de "suelta aquí" -----
   Aparece sobre todo lo demás mientras se arrastra un archivo. Es la que hace
   visible que la página entera recibe el XML. */
 .soltar{position:fixed;inset:0;z-index:200;display:none;align-items:center;
        justify-content:center;background:rgba(3,100,145,.16);
        backdrop-filter:blur(1.5px)}
 .soltar.ver{display:flex}
 .soltar-caja{display:flex;flex-direction:column;align-items:center;gap:12px;
        background:var(--papel);color:var(--azul-700);border:2.5px dashed var(--azul-400);
        border-radius:16px;padding:38px 54px;box-shadow:0 12px 40px rgba(0,0,0,.18)}
 .soltar-caja svg{width:52px;height:52px}
 .soltar-tx{font-size:17px;font-weight:600;color:var(--azul-900)}
 /* Formulario que NO acepta arrastrar: mismo bloque que .drop pero con borde
    sólido, para no prometer una zona de soltado que no existe. */
 .panel{border:1px solid var(--linea-3);border-radius:var(--radio);padding:24px 28px;
        background:var(--papel);margin-bottom:18px}
 /* Lo único centrado del formulario del CSD son los botones. */
 .csd-acciones{margin-top:16px;text-align:center}
 /* ----- Sello digital: crear y validar, lado a lado -----
    Dos operaciones inversas que se leen juntas. En pantalla angosta se apilan:
    forzar dos columnas dejaría las cadenas originales ilegibles. */
 .sello-cols{display:grid;grid-template-columns:1fr 1fr;gap:18px;align-items:start}
 @media (max-width:1000px){ .sello-cols{grid-template-columns:1fr} }
 .panel-tit{margin:-24px -28px 16px;padding:11px 20px;background:var(--azul-700);
        color:var(--papel);font-size:15px;font-weight:600;
        border-radius:var(--radio) var(--radio) 0 0}
 .panel-int{font-size:13.5px;color:var(--texto-4);margin-bottom:14px}
 .campo{display:flex;flex-direction:column;gap:4px;font-size:12px;
        color:var(--tenue);margin-bottom:12px}
 .campo textarea{padding:9px 11px;border:1px solid var(--linea-3);border-radius:6px;
        font-family:ui-monospace,Consolas,monospace;font-size:12.5px;line-height:1.5;
        color:var(--tinta);background:var(--papel);resize:vertical;
        width:100%;box-sizing:border-box}
 .campo textarea:focus{outline:none;border-color:var(--azul-700);
        box-shadow:0 0 0 2px var(--azul-200)}
 /* El resultado vive dentro del panel: quitarle el margen exterior que traen
    .estr-card y .card cuando van sueltos en la página. */
 .panel .estr-card{margin-top:16px}
 .panel .card{margin-bottom:0}
 input[type=file]{margin:10px}
 /* Consulta SAT: captura manual de los 4 datos del comprobante */
 .sat-sep{margin:14px 0 10px;font-size:12px;color:var(--tenue)}
 .sat-campos{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px;text-align:left}
 .sat-campos label{display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--tenue)}
 .sat-campos input{padding:8px 10px;border:1px solid var(--linea-3);border-radius:6px;font-size:14px;color:var(--tinta);background:var(--papel);
        box-sizing:border-box;width:100%;min-height:38px}
 /* El margen de input[type=file] lo pide el recuadro de carga grande (.drop),
    donde el control va suelto y centrado. Dentro de la rejilla estorba: corre
    el selector 10px respecto del campo de texto de al lado y los descuadra. */
 .sat-campos input[type=file]{margin:0}
 .sat-campos input:focus{outline:none;border-color:var(--azul-700)}
 button{background:var(--azul-700);color:var(--papel);border:0;padding:10px 22px;border-radius:6px;font-size:15px;cursor:pointer}
 /* Botón inhabilitado: lo usan la cuenta atrás del acceso y la espera entre
    validaciones, que hasta ahora se veían igual que uno activo. */
 button:disabled{opacity:.55;cursor:not-allowed}
 .btn-sec{display:inline-block;margin-left:10px;background:var(--fondo);color:var(--tinta);border:1px solid var(--linea-3);padding:10px 18px;border-radius:6px;font-size:14px;text-decoration:none}
 .btn-sec:hover{background:#e2e8ef}
 .tag{display:inline-block;background:var(--azul-100);color:var(--azul-500);border-radius:4px;padding:2px 8px;font-size:12px;margin-left:8px}
/* =========================================================================
   Resultado de una validación: solapas + un panel.
   Antes esto era una pila (banner, tablas por nodo, árbol y reporte, uno
   debajo de otro) y el resultado se leía scrolleando. La barra de solapas
   reusa el azul de .head a propósito: es la misma cabecera de tarjeta de
   siempre, sólo que ahora además sirve para elegir qué se ve.
   ========================================================================= */
/* Distintivo de PAC: quién timbró el comprobante. Es un recuadro más al final
   de la fila, pero NO una solapa: no se selecciona, no abre panel y no lleva
   insignia de veredicto. Quién timbró no dice nada de si el CFDI está bien.

   Comparte la caja de las solapas para que se lea como parte del mismo juego, y
   se distingue por lo que NO hace: sin resaltado al pasar el ratón y sin cursor
   de mano, que son las dos señales de que algo se puede pulsar.

   El granate del PAC de la casa entra como acento —el filo, el disco del sello
   y el nombre— y nunca como fondo: lo más saturado de la pantalla tienen que
   seguir siendo los recuadros del veredicto. */
 .res-pac{flex:1 1 250px;max-width:340px;display:flex;align-items:center;gap:12px;
        background:var(--papel);border:1.5px solid var(--linea-3);
        border-left:4px solid var(--linea-3);border-radius:8px;padding:11px 14px;
        cursor:default}
 .pac-disco{position:relative;width:34px;height:34px;flex-shrink:0;border-radius:50%;
        display:flex;align-items:center;justify-content:center;background:var(--fondo)}
 .res-pac .ico{width:19px;height:19px;flex-shrink:0;color:var(--tenue)}
 .pac-tx{min-width:0}
 /* Antetítulo: deja que el nombre del PAC sea lo primero que se lee, en vez de
    gastar el renglón fuerte en "Timbrado por:". */
 .pac-et{font-size:9.5px;font-weight:700;letter-spacing:.09em;
        text-transform:uppercase;color:var(--tenue);margin-bottom:2px}
 /* La razón social es larga (hay PACs de 80 caracteres): se parte en varios
    renglones en vez de recortarse con puntos suspensivos; un nombre a medias no
    identifica a nadie. El recuadro crece de alto, no de ancho. */
 .pac-tit{font-size:12.5px;font-weight:700;color:var(--tinta);line-height:1.25}
 .pac-sub{font-size:11.5px;color:var(--tenue);margin-top:2px;
        font-variant-numeric:tabular-nums}
 /* PAC de la casa: mismo recuadro, teñido con el granate de la marca. */
 .res-pac.propio{border-left-color:var(--pac-bg)}
 .res-pac.propio .pac-disco{background:var(--pac-pal)}
 .res-pac.propio .ico{color:var(--pac-bg)}
 .res-pac.propio .pac-tit{color:var(--pac-bg)}
 /* Se estampa una sola vez cuando aparece el resultado: la prensa baja, aprieta
    y se retira, y lo que queda en el disco es la marca. El marcado se manda de
    cero en cada validación, así que la animación arranca sola al pintarse y no
    hace falta ni una línea de JS.

    La prensa es el gesto, no el estado final: antes se quedaba ella misma
    estampada en el recuadro, que es como dejar el sello de goma encima del
    papel. Ahora se va y descubre la marca al levantarse.

    Por eso vive entera dentro de `no-preference` y por omisión ni se pinta: sin
    movimiento no hay nada que posicionar, y el recuadro se lee igual con sólo la
    marca. Quien pidió menos movimiento en su sistema ve el resultado, no el
    gesto. */
 .pac-prensa{display:none}
 /* La marca va un pelo más grande que los iconos y NO lleva grosor de trazo
    aquí: el suyo lo pone cada trazo del dibujo (ver _sello_tinta en webapp.py),
    que usa cuatro distintos para que el bloque de renglones parezca texto. Un
    stroke-width en esta regla los aplanaría todos a uno. */
 .res-pac .marca{width:22px;height:22px}
 @media (prefers-reduced-motion:no-preference){
   .pac-prensa{display:block;position:absolute;left:50%;top:50%;
        margin:-9.5px 0 0 -9.5px;transform-origin:50% 100%;pointer-events:none;
        animation:pac-prensa .78s cubic-bezier(.2,.75,.3,1) both}
   /* La marca no está hasta que la prensa la deja. `:not(.pac-prensa)` porque
      la prensa también es un `.ico` y tiene su propia animación. */
   .pac-disco>.ico:not(.pac-prensa){animation:pac-marca .42s ease-out .29s both}
   /* El anillo de tinta: sale del sello justo cuando toca el papel y se abre
      hacia afuera. Es un pseudo-elemento para no ensuciar el marcado. */
   .pac-disco::after{content:"";position:absolute;inset:0;border-radius:50%;
        border:2px solid currentColor;color:var(--tenue);
        animation:pac-tinta .58s ease-out .29s both;pointer-events:none}
   .res-pac.propio .pac-disco::after{color:var(--pac-bg)}
 }
 /* Baja, se planta un instante (el apretón) y se levanta. El reposo entre 38% y
    52% es lo que hace que se lea como presión y no como un rebote. */
 @keyframes pac-prensa{
   0%{transform:translateY(-13px) scale(1.15);opacity:0}
   20%{opacity:1}
   38%{transform:translateY(0) scale(1);opacity:1}
   52%{transform:translateY(0) scale(1);opacity:1}
   100%{transform:translateY(-16px) scale(1.1);opacity:0}
 }
 @keyframes pac-marca{
   0%{opacity:0;transform:scale(1.14)}
   45%{opacity:1}
   100%{opacity:1;transform:none}
 }
 @keyframes pac-tinta{
   0%{transform:scale(.45);opacity:0}
   22%{opacity:.6}
   100%{transform:scale(1.85);opacity:0}
 }

 .res{overflow:hidden}   /* que la rejilla respete el radio de la tarjeta */
 /* Nombre del XML que produjo este resultado. Encabeza la tarjeta como el título
    encabeza la de carga, así que validar varios seguidos no deja dudas de cuál
    se está leyendo. */
 .res-arch{display:flex;align-items:center;gap:8px;padding:11px 16px;
        border-bottom:1px solid var(--linea);font-size:13px;color:var(--tinta);
        font-weight:600}
 .res-arch .ico{width:15px;height:15px;flex-shrink:0;color:var(--azul-500);opacity:.9}
 .res-arch span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
 /* Rejilla de recuadros, uno por comprobación. Separados y sobre fondo gris (no
    pegados en una barra) para que se lean como cuatro cosas que se eligen, y no
    como una cabecera partida en trozos. */
 /* La cabecera del resultado. Antes era el propio tablist; ahora lo envuelve,
    porque al lado de las solapas va el recuadro del PAC y ése NO es una solapa:
    en un `role="tablist"` sólo caben solapas. */
 .res-cab{display:flex;flex-wrap:wrap;gap:10px;padding:12px;background:#f7f9fb;
        border-bottom:1px solid var(--linea-2)}
 .res-tabs{display:flex;flex-wrap:wrap;gap:10px;flex:1 1 460px}
 /* Hereda de `button` (azul relleno), que aquí sobra por completo. */
 .res-tab{position:relative;flex:1 1 0;min-width:130px;display:flex;
        flex-direction:column;align-items:center;justify-content:center;gap:9px;
        background:var(--papel);border:1.5px solid var(--linea-3);border-radius:8px;
        padding:18px 12px 15px;font-family:inherit;font-size:14px;
        transition:border-color .12s ease,background .12s ease}
 /* El icono toma el color del veredicto; la etiqueta NO: en rojo se leería como
    parte del error en vez de como el nombre de la comprobación. */
 .res-tab .ico{width:26px;height:26px}
 .res-lbl{color:var(--tinta);font-size:12.5px;line-height:1.3;text-align:center;
        max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
 .res-badge{position:absolute;top:8px;right:8px;line-height:0}
 .res-badge .ico{width:15px;height:15px}
 .res-tab.v-ok{color:var(--ok-ic)}
 .res-tab.v-adv{color:var(--adv-fuerte)}
 .res-tab.v-err{color:var(--err)}
 .res-tab:hover{border-color:var(--azul-400)}
 /* El recuadro elegido se tiñe del color de SU veredicto: así el que estás
    viendo y cómo salió son el mismo dato y no dos. */
 .res-tab.act{font-weight:600}
 .res-tab.v-ok.act{background:var(--ok-bg);border-color:var(--ok-ic)}
 .res-tab.v-adv.act{background:var(--adv-bg);border-color:var(--adv-fuerte)}
 .res-tab.v-err.act{background:var(--err-bg);border-color:var(--err)}
 /* En pantalla angosta se acomodan de dos en dos antes que encogerse hasta ser
    ilegibles. */
 @media (max-width:640px){.res-tab{flex:1 1 40%;padding:14px 8px 12px}}
 .oculto{display:none}
 /* El banner del veredicto va DENTRO del panel, así que necesita su propio
    margen: suelto en la página lo traía de .estr-card. */
 .res-det>.estr-card{margin:14px 18px}
 /* Sin JS no hay a quién hacerle clic: los paneles se quedan uno tras otro, que
    es exactamente la vista de antes. */
 html.no-js .oculto{display:block}
 /* Texto sólo para lector de pantalla (el veredicto de cada solapa, que en la
    pantalla lo dice el punto de color). */
 .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
        overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
 /* ----- Árbol visual (amigable para clientes) ----- */
 .arbol{padding:16px 20px}
 .leyenda{display:flex;gap:16px;flex-wrap:wrap;padding:10px 20px;background:#f7f9fb;border-bottom:1px solid var(--linea);font-size:12.5px;color:var(--texto-4)}
 .leyenda span{display:inline-flex;align-items:center;gap:6px}
 .leyenda-nota{color:var(--tenue-3)}
 .dot{width:11px;height:11px;border-radius:50%;display:inline-block}
 .d-ok{background:var(--ok-fuerte)} .d-err{background:var(--err-fuerte)} .d-adv{background:var(--adv-fuerte)}
 .rama{margin-left:18px;border-left:2px solid var(--linea-2);padding-left:14px}
 .nodo{display:flex;align-items:center;gap:8px;padding:3px 6px;flex-wrap:wrap}
 /* ----- Nodo plegable -----
    El triángulo se dibuja a mano y se esconde el marcador nativo de <summary>:
    el nativo no se puede alinear con un summary en flex, y en Safari se pinta
    con otra forma. */
 details.nw{margin:1px 0}
 summary.nodo{cursor:pointer;list-style:none;border-radius:6px}
 summary.nodo::-webkit-details-marker{display:none}
 summary.nodo:hover{background:var(--azul-050)}
 .caret{display:inline-block;vertical-align:middle;flex-shrink:0;width:0;height:0;
        border-left:5px solid var(--tenue);
        border-top:4px solid transparent;border-bottom:4px solid transparent;
        transition:transform .12s ease}
 details.nw[open]>summary.nodo>.caret{transform:rotate(90deg)}
 /* Hoja sin nada dentro: no lleva triángulo, pero sí la misma sangría, para que
    los chips de todos los hermanos queden en la misma columna. */
 .nodo-hoja{padding-left:19px}
 .nodo-cuerpo{margin-left:14px}
 /* Enlace del renglón a la ficha del nodo, que va abajo. Discreto: el árbol es
    el mapa y no debe competir con los chips de estatus. */
 .ir-detalle{font-size:11.5px;color:var(--azul-450);text-decoration:none;
        border-bottom:1px dotted currentColor}
 .ir-detalle:hover{color:var(--azul-350)}
 .chip{display:inline-flex;align-items:center;gap:7px;padding:4px 11px;border-radius:16px;font-size:13px;font-weight:600;border:1px solid}
 .c-ok{background:var(--ok-bg);border-color:var(--ok-bd);color:var(--ok)}
 .c-err{background:var(--err-bg);border-color:var(--err-bd);color:var(--err)}
 .c-adv{background:var(--adv-bg);border-color:var(--adv-bd);color:var(--adv)}
 .pill{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.4px;padding:1px 7px;border-radius:10px}
 .p-ok{background:var(--ok-fuerte);color:var(--papel)} .p-err{background:var(--err-fuerte);color:var(--papel)} .p-adv{background:var(--adv-fuerte);color:var(--papel)}
 .p-hint{background:var(--linea);color:#667} .p-falta{background:var(--err);color:var(--papel);margin-left:8px}
 .c-falta{background:#fbeeee;border-color:#e0a59f;color:var(--err-oscuro);border-style:dashed}
 .callout{margin:4px 0 6px 8px;padding:8px 12px;border-radius:6px;font-size:12.5px;background:var(--err-bg);border-left:3px solid var(--err-fuerte);color:var(--err-tx)}
 .callout.adv{background:var(--adv-bg);border-left-color:var(--adv-fuerte);color:var(--adv-tx)}
 .callout.principal{position:relative;overflow:visible;border:1.5px solid var(--adv-fuerte);border-left-width:3px}
 /* Versión del árbol: marca el campo que falla sin robarle sitio a la rama, que
    es lo que se está leyendo. La explicación larga va en la ficha del nodo. */
 .callout.compacto{margin:3px 0 5px;padding:5px 10px;font-size:12px;
        max-width:90ch}
 /* Error PRINCIPAL (el que reporta el WS del SAT): sólo el fondo ámbar del
    renglón. Las flechas animadas que lo señalaban desde fuera de la tabla
    quedaban cortadas por el recuadro y no se alcanzaban a ver. */
 tr.fila-principal>td{background:#fff4ea;box-shadow:inset 0 0 0 1px #f0c58e}
 .callout b{font-family:ui-monospace,Consolas,monospace}
 .msg.tip{text-decoration:underline dotted;text-underline-offset:2px}
 .tipwrap{position:relative}
 .tipicon{cursor:pointer;user-select:none;color:var(--azul-500);font-weight:700;margin-left:2px}
 .tipicon:hover{color:var(--azul-350)}
 .tipbox{display:none;position:absolute;left:0;top:calc(100% + 5px);z-index:50;width:330px;max-width:82vw;background:var(--papel);color:#3b3b3b;border:1px solid #d9c2bd;border-radius:var(--radio);box-shadow:0 6px 20px rgba(0,0,0,.18);padding:10px 12px;font-size:12px;line-height:1.55;font-weight:400;white-space:normal;text-decoration:none}
 .tipbox::before{content:"";position:absolute;top:-6px;left:14px;width:10px;height:10px;background:var(--papel);border-left:1px solid #d9c2bd;border-top:1px solid #d9c2bd;transform:rotate(45deg)}
 .tipbox.show{display:block}
 .sumas{margin-top:6px}
 .sumas summary{cursor:pointer;font-weight:600;color:#7a241b;font-size:12px;user-select:none}
 .sumas pre{margin:6px 0 2px;padding:8px 10px;background:var(--papel);border:1px solid #f0c9c2;border-radius:5px;font-family:ui-monospace,Consolas,monospace;font-size:11.5px;color:var(--texto-2);white-space:pre-wrap;overflow-x:auto}
 .ayuda-cp{margin-top:8px}
 .ayuda-cp>summary{cursor:pointer;font-weight:600;color:var(--azul-450);font-size:12.5px;user-select:none}
 .acp-t{font-size:12px;color:var(--texto-4);margin:8px 0 4px}
 table.tbl-cp{width:auto;min-width:260px;border:1px solid var(--linea-4);border-radius:5px;overflow:hidden;font-size:12px}
 table.tbl-cp th{background:#eef3f8;color:var(--tinta);text-align:left;padding:5px 10px;font-weight:600;border-bottom:1px solid var(--linea-4)}
 table.tbl-cp td{padding:4px 10px;border-bottom:1px solid var(--fondo);font-family:ui-monospace,Consolas,monospace}
 .acp-col{max-height:180px;overflow:auto;border:1px solid var(--fondo);border-radius:5px;margin-top:2px}
 .acp-col table.tbl-cp{border:0}
 .toggle{display:flex;gap:8px;align-items:center;padding:10px 20px;border-bottom:1px solid var(--linea)}
 .toggle button{background:var(--fondo);color:var(--tinta);border:1px solid var(--linea-3);padding:5px 12px;border-radius:6px;font-size:12.5px;cursor:pointer}
 .toggle button.activo{background:var(--azul-700);color:var(--papel);border-color:var(--azul-700)}
 .toggle-lbl{font-size:12.5px;color:var(--texto-5)}
 /* Resumen del árbol ("3 campo(s) con error"): vivía en la cabecera de la
    tarjeta, que desapareció al meter el árbol en un panel. */
 .toggle-sum{margin-left:auto;font-size:12.5px;color:var(--texto-4)}
 .linea{font-size:11px;color:var(--tenue);font-weight:400}
 /* ----- Banner de resultado de estructura -----
    El color va en el contenedor; el icono y el título lo heredan. */
 .estr-card{margin-top:18px;border-radius:var(--radio);border-left:6px solid;padding:16px 20px;box-shadow:var(--sombra);display:flex;gap:14px;align-items:flex-start}
 .estr-card.e-ok{border-left-color:var(--ok);background:var(--ok-bg);color:var(--ok)}
 .estr-card.e-err{border-left-color:var(--err);background:var(--err-bg);color:var(--err)}
 .estr-card.e-adv{border-left-color:var(--adv);background:var(--adv-bg);color:var(--adv)}
 .estr-card.compacta{padding:9px 14px;margin-bottom:10px}
 .estr-ic{font-size:26px;line-height:1.1}
 .estr-tit{font-size:16px;font-weight:700;margin-bottom:4px}
 .estr-cod{display:inline-block;background:var(--papel);border:1px solid currentColor;border-radius:4px;padding:1px 8px;font-size:12px;font-family:ui-monospace,Consolas,monospace;margin-right:8px;font-weight:700}
 .estr-msg{font-size:13.5px;color:var(--texto-3)}
 /* Origen del resultado: WS (Web Service del SAT) o LC (validación local). */
 .fuente-tag{display:inline-block;margin-left:6px;padding:0 5px;border-radius:7px;font-size:8.5px;font-weight:700;letter-spacing:.4px;vertical-align:middle;border:1px solid;font-family:ui-monospace,Consolas,monospace}
 .fuente-tag.f-ws{color:var(--azul-600);border-color:var(--azul-200);background:var(--azul-050)}
 .fuente-tag.f-rl{color:var(--tenue);border-color:var(--linea-2);background:#f7f9fb}
 .estr-lista{font-size:12.5px;color:var(--texto-alt)}
 .estr-lista ul{margin:4px 0 0;padding-left:18px}
 /* ----- Iconos de estatus -----
    .b-* = columna de estatus del reporte; .s-* = tablas por nodo. */
 .b-ok{color:var(--ok-ic)}
 .b-err{color:var(--err)}
 .b-adv{color:var(--adv-fuerte)}
 .b-info{display:inline-block;width:20px;height:20px;line-height:20px;border-radius:50%;background:var(--ok-ic);color:var(--papel);font-weight:700;font-size:13px}
 .s-ok{color:var(--ok-ic)}
 .s-err{color:var(--err)}
 .s-adv{color:var(--adv-fuerte)}
 .s-aus{color:var(--tenue-3)}
 /* ----- Tablas por nodo ----- */
 .nodocard{margin-top:16px}
 .nodocard .head{background:var(--azul-600);font-size:15px}
 .ruta{font-size:11px;opacity:.8;font-weight:400}
 /* ----- Fichas de los nodos a corregir -----
    Van debajo del árbol y sólo existen para los nodos con problema. Cada una es
    un <details> cuya cabecera es la misma .head azul de las demás tarjetas. */
 .det-nodos{margin-top:26px}
 .det-tit{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
        margin:0 0 12px;font-size:20px;font-weight:600;color:var(--azul-900)}
 .det-acc{margin-left:auto;display:flex;gap:8px}
 .det-acc button{background:var(--fondo);color:var(--tinta);
        border:1px solid var(--linea-3);padding:5px 12px;border-radius:6px;
        font-size:12.5px}
 .det-vacio{background:var(--papel);border-radius:var(--radio);
        box-shadow:var(--sombra);color:var(--ok);font-size:14px;padding:16px 20px}
 details.nodocard>summary{cursor:pointer;list-style:none;align-items:center}
 details.nodocard>summary::-webkit-details-marker{display:none}
 details.nodocard>summary:hover{background:var(--azul-600)}
 details.nodocard>summary.falta:hover{background:var(--err)}
 /* El triángulo de la ficha va sobre el azul de la cabecera, así que hereda el
    color del texto en vez del gris que usa el del árbol. */
 details.nodocard>summary .caret{border-left:7px solid currentColor;
        border-top-width:5px;border-bottom-width:5px;margin-right:10px}
 details.nodocard[open]>summary .caret{transform:rotate(90deg)}
 details.nodocard>summary .pill{flex-shrink:0}
 .desc{padding:8px 14px;background:#f7f9fb;color:var(--texto-4);font-size:12.5px;border-bottom:1px solid var(--linea)}
 td.uso{width:110px;font-size:12px;color:var(--texto-5)}
 td.nom{width:210px;font-weight:600;color:var(--tinta)}
 .th-col{color:var(--tenue-2)}
 .sub-esperados{margin:8px 0 0 14px;font-size:12.5px;color:var(--texto-4)}
 .cat{display:inline-block;background:#eef3f8;color:var(--azul-500);border-radius:3px;padding:0 5px;font-size:11px;margin-top:3px}
 .req{color:#b3402f;font-weight:600} .cond{color:#b8860b} .opc{color:var(--tenue-2)}
 .msg{color:var(--err);font-size:12px}
 .ausente{color:var(--tenue-3);font-style:italic}
 /* ----- Buscador de catálogo (c_ClaveProdServCP) ----- */
 .buscar-cat{margin-top:8px}
 .buscar-cat>summary{cursor:pointer;font-weight:600;color:var(--azul-450);font-size:12.5px;user-select:none}
 .bc-box{margin-top:6px}
 .bc-input{width:100%;max-width:420px;box-sizing:border-box;padding:7px 10px;border:1px solid #cdd6df;border-radius:6px;font-size:13px}
 .bc-input:focus{outline:none;border-color:var(--azul-700);box-shadow:0 0 0 2px var(--azul-200)}
 .bc-hint{font-size:11.5px;color:var(--tenue);margin:4px 0}
 .bc-res{max-height:230px;overflow:auto;border:1px solid var(--fondo);border-radius:6px;margin-top:4px;display:none}
 .bc-res.show{display:block}
 .bc-row{display:flex;gap:10px;align-items:baseline;padding:6px 10px;border-bottom:1px solid #f1f4f7;cursor:pointer}
 .bc-row:hover{background:var(--azul-050)}
 .bc-row:last-child{border-bottom:0}
 .bc-clave{font-family:ui-monospace,Consolas,monospace;font-weight:700;color:var(--azul-450);font-size:12.5px;flex-shrink:0}
 .bc-desc{font-size:12.5px;color:var(--texto-3)}
 .bc-empty{padding:8px 10px;font-size:12px;color:var(--tenue)}
 .bc-copiado{color:var(--ok);font-weight:600}
 .bc-error{color:var(--err)}
 /* ----- Pantalla de acceso (login.html) ----- */
 /* La página no lleva menú lateral: el panel se centra en la ventana. */
 .login-body{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:24px}
 .login-caja{width:100%;max-width:420px}
 .login-marca{display:block;height:110px;width:auto;max-width:100%;margin:0 auto 18px}
 .login-panel{margin:0}
 .login-campos{display:grid;gap:12px}
 .login-campos label{display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--tenue)}
 .login-campos input{padding:9px 10px;border:1px solid var(--linea-3);border-radius:6px;
   font-size:14px;color:var(--tinta);background:var(--papel)}
 .login-campos input:focus{outline:none;border-color:var(--azul-700);box-shadow:0 0 0 2px var(--azul-200)}
 .login-acciones{margin-top:18px}
 .login-acciones button{width:100%}
 /* Salida de la pantalla de acceso cuando entrar es OPCIONAL (validador abierto).
    Separada del botón por una línea: son dos caminos distintos, no dos botones
    del mismo formulario. */
 .login-volver{margin-top:16px;padding-top:14px;border-top:1px solid var(--linea);
   text-align:center}
 .login-volver a{color:var(--azul-450);font-size:13px;text-decoration:none}
 .login-volver a:hover{text-decoration:underline}
 .login-nota{color:var(--tenue);font-size:11.5px;line-height:1.5;margin-top:6px}
 .login-error{background:var(--err-bg);border:1px solid var(--err-bd);color:var(--err-tx);
   border-radius:6px;padding:9px 12px;font-size:13px;margin-bottom:14px}
 /* Al agotarse la cuenta atrás el mismo recuadro pasa a verde: el rojo estaría
    diciendo que algo sigue mal cuando ya se puede volver a intentar. */
 .login-libre{background:var(--ok-bg);border:1px solid var(--ok-bd);color:var(--ok);
   border-radius:6px;padding:9px 12px;font-size:13px;margin-bottom:14px}
 /* ----- Sesión abierta: pie del menú lateral ----- */
 /* Va abajo del todo (margin-top:auto) para que no compita con la navegación;
    el .sidebar pasa a ser columna flexible para poder empujarlo hasta ahí. */
 .sidebar{display:flex;flex-direction:column}
 .sesion{margin-top:auto;padding:14px 20px;border-top:1px solid var(--sb-borde);font-size:12.5px}
 .sesion-quien{color:var(--papel);font-weight:600;overflow-wrap:anywhere}
 .sesion-quien small{display:block;font-weight:400;color:var(--azul-tx2);font-size:11px;margin-top:2px}
 .sesion form{margin:6px 0 0}
 .sesion button{background:transparent;color:var(--azul-tx);border:1px solid var(--sb-borde);
   padding:6px 12px;border-radius:6px;font-size:12.5px;cursor:pointer;width:100%}
 .sesion button:hover{background:var(--sb-hover);color:var(--papel)}
 /* ----- Sin sesión: la puerta del equipo, con el acceso apagado -----
    Ocupa el mismo pie que la sesión abierta, así que el menú no salta de alto
    según quién esté mirando. Se pinta como los enlaces del menú y no como un
    botón: no es la acción principal de la pantalla, es una puerta de servicio. */
 .sesion-entrar{display:flex;align-items:center;gap:10px;color:var(--azul-tx);
   text-decoration:none;font-size:13px;font-weight:600}
 .sesion-entrar:hover{color:var(--papel)}
 .sesion-entrar .ico{width:16px;height:16px;flex-shrink:0;opacity:.75}
 .sesion-entrar:hover .ico{opacity:1}
