/* ═══════════════════════════════════════════════════════════════════
   CICOM · Sistema de diseño
   Lenguaje visual: sala de control + cajetín de plano isométrico.
   Sin frameworks. Todo el color y la tipografía sale de estos tokens.
   ═══════════════════════════════════════════════════════════════════ */

/* Las tipografías se piden a Google Fonts. Si el equipo de obra no tiene
   salida a internet, o la red de planta la bloquea, NO fallan las páginas:
   se usa la tipografía del sistema indicada en --f-ui y --f-tx. Para no
   depender de internet, ver docs/TIPOGRAFIAS.md */
/* ═══ TIPOGRAFÍAS ════════════════════════════════════════════════
   Servidas desde este mismo servidor, no desde Google Fonts. En la
   tablet de obra sin señal aquella petición fallaba en cada carga y
   el texto aparecía con la letra del sistema; además, cada visita se
   anunciaba a un tercero.

   Los tres tipos son SIL Open Font License 1.1 (licencias completas en
   assets/fonts/LICENCIAS.txt). El navegador solo se baja el trozo que
   necesita: con texto en español basta el «latin», unos 24 KB por peso.
   ══════════════════════════════════════════════════════════════ */

@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/barlow-semi-condensed-latin-500-normal.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/barlow-semi-condensed-latin-ext-500-normal.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:600;font-display:swap;src:url('../fonts/barlow-semi-condensed-latin-600-normal.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:600;font-display:swap;src:url('../fonts/barlow-semi-condensed-latin-ext-600-normal.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/barlow-semi-condensed-latin-700-normal.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/barlow-semi-condensed-latin-ext-700-normal.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/inter-latin-400-normal.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/inter-latin-ext-400-normal.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/inter-latin-500-normal.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/inter-latin-ext-500-normal.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('../fonts/inter-latin-600-normal.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('../fonts/inter-latin-ext-600-normal.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/jetbrains-mono-latin-ext-400-normal.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/jetbrains-mono-latin-500-normal.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/jetbrains-mono-latin-ext-500-normal.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/jetbrains-mono-latin-700-normal.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/jetbrains-mono-latin-ext-700-normal.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

:root{
  /* ── Superficies ───────────────────────────────────────────────── */
  /* Los dos colores del logotipo mandan sobre el resto de la paleta */
  --marca-fondo:#1E3A5F;  /* azul CICOM */
  --marca-naranja:#D97A2B;/* naranja de la línea del logotipo */

  --ink:#1E3A5F;          /* azul de marca: menú lateral y bandas de titular */
  --ink-2:#16304F;        /* un paso más oscuro: bordes y cabeceras */
  --ink-3:#2A4A72;        /* un paso más claro: superficies dentro del menú */
  /* Los neutros se separaron un escalón: con los valores de antes
     (canvas #F4F6F8, paper-2 #FAFBFC, line #E6E9EE, line-2 #D7DCE3,
     linea-suave #F1F3F6) el separador entre filas daba 1,11 de contraste
     contra el papel y una tarjeta sobre el fondo, 1,08. A esa distancia el
     ojo no distingue un borde de un no-borde: la lista de registros se
     mimetizaba y había que contar filas con el dedo. Ahora el separador da
     1,35, el borde de tarjeta 1,46 y el de un control 1,74. */
  --canvas:#E4E9EF;       /* hormigón frío: fondo de trabajo */
  --paper:#FFFFFF;
  --paper-2:#F1F4F8;      /* fila alterna y superficies apenas hundidas */
  --line:#CFD6E0;         /* separador dentro de una tarjeta */
  --line-2:#BCC5D3;       /* borde de un control */
  --linea-suave:#D8DEE6;  /* separador entre filas de una tabla */
  /* Con la fila alterna ya visible, el azul de selección (--brand-l) se
     confundía con ella al pasar el ratón. La fila señalada tiene su propio
     tono, un paso por delante de las dos. */
  --fila-hover:#DCE6F3;
  --pista:#EEF1F5;        /* fondo de una barra de avance */
  --seg:#EDEFF3;          /* carril de un grupo segmentado */

  /* ── Texto ─────────────────────────────────────────────────────── */
  /* --t3 y --t4 se oscurecieron tras la auditoría de contraste: con los
     valores anteriores (#77808D y #9AA3AF) los rótulos pequeños no llegaban
     a 4,5:1 y a pleno sol en obra no se leían. Ahora dan 5,9:1 y 4,9:1. */
  --t1:#141A21;  --t2:#4B5563;  --t3:#5F6773;  --t4:#6B7380;

  /* ── Marca ─────────────────────────────────────────────────────────
     El azul del logotipo es también el color de acción: botones, enlaces
     y estados activos. Blanco sobre él da 11,5:1, de sobra para leer. */
  --brand:#1E3A5F;
  --brand-d:#16304F;      /* al pasar el ratón y al pulsar */
  --brand-l:#EAEFF6;      /* tinte suave: fondos de selección */
  --brand-m:#B7C6DA;      /* bordes de esa selección */

  /* Naranja del logotipo. Se reserva para señalar dónde estás y para la
     marca: como fondo con texto blanco no llega al contraste mínimo, así
     que para texto pequeño sobre claro se usa --acento-txt. */
  --acento:#D97A2B;
  --acento-d:#B9631D;
  --acento-l:#FDF1E6;
  --acento-txt:#9A5216;   /* 5,85:1 sobre blanco */

  /* ── Semántica de calidad (nunca se usa como decoración) ───────── */
  --ok:#17754A;   --ok-bg:#E4F2EA;   --ok-br:#B4DCC5;
  --warn:#B87200; --warn-bg:#FDF3E0; --warn-br:#EBD5A6;
  --warn-tx:#8A5600;  /* el ámbar como texto pequeño: sobre --warn-bg da 5,9:1 */
  --stop:#B32B23; --stop-bg:#FBEAE9; --stop-br:#EFC0BC;
  --hold:#5B46A8; --hold-bg:#EEEBF8; --hold-br:#CBC1EC;  /* en circuito de firma */
  --idle:#6B7280; --idle-bg:#EEF0F3; --idle-br:#D3D8DF;
  --idle-tx:#4B5563;  /* texto de la insignia neutra: 6,9:1 sobre --idle-bg */

  /* ── Tipografía ────────────────────────────────────────────────── */
  --f-ui:'Barlow Semi Condensed','Segoe UI',system-ui,-apple-system,sans-serif;
  --f-tx:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  --f-mo:'JetBrains Mono','SFMono-Regular',Consolas,monospace;

  /* ── Métrica ───────────────────────────────────────────────────── */
  --rail:230px; --top:52px;
  --rail-fs:12.5px;       /* cuerpo de los enlaces del menú */

  /* Escala de radio: cuatro valores para todo el sistema. Lo que no esté
     aquí no se usa (antes había doce, y cada pantalla parecía de otro sitio). */
  --r:6px;                /* controles: botón, campo, insignia cuadrada */
  --r-lg:10px;            /* tarjetas y paneles */
  --r-xl:14px;            /* diálogos */
  --r-pill:999px;         /* píldoras de estado y barras */

  /* Elevación: lo que está SOBRE la página tiene sombra; lo que es la
     página, solo borde. */
  /* Dos capas, no una: la sombra de un solo píxel se perdía contra el fondo
     y las tarjetas parecían recortes pegados a la página. */
  --sh-1:0 1px 2px rgba(16,24,40,.06), 0 3px 10px rgba(16,24,40,.07);  /* tarjeta */
  --sh-2:0 8px 24px rgba(16,24,40,.10);   /* menú desplegable */
  --sh-3:0 24px 64px rgba(16,24,40,.20);  /* diálogo */

  /* Movimiento: dos duraciones y una curva. */
  --mov:120ms cubic-bezier(.2,0,.2,1);    /* color, fondo, borde */
  --mov-2:200ms cubic-bezier(.2,0,.2,1);  /* aparecer, plegar */
  --foco:0 0 0 3px rgba(30,58,95,.18);    /* el mismo anillo en todo lo enfocable */

  /* Alias: nombres que usan algunas pantallas y que no estaban definidos,
     así que esos estilos caían al valor por defecto del navegador. */
  --bg-2:var(--paper-2); --r-s:var(--r);
  --tx:var(--t1); --tx-2:var(--t2); --tx-3:var(--t3);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* «hidden» siempre oculta: sin esto, .aviso o .btns (display:flex) lo anulaban */
[hidden]{display:none!important}
html{font-size:15px;-webkit-text-size-adjust:100%}
body{
  font-family:var(--f-tx);background:var(--canvas);color:var(--t1);
  line-height:1.5;-webkit-font-smoothing:antialiased;min-height:100vh;
}
a{color:var(--brand);text-decoration:none}
a:hover{color:var(--brand-d);text-decoration:underline}
img{max-width:100%;display:block}
input,select,textarea,button{font:inherit;color:inherit}
/* Un solo anillo de foco para toda la aplicación: botones, campos, filas,
   pestañas y enlaces. Antes cada componente resolvía el suyo, o ninguno. */
:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:var(--r)}
.btn:focus-visible,.bandeja:focus-visible,.tab:focus-visible,
.in:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:none;border-color:var(--brand);box-shadow:var(--foco);
}
::selection{background:var(--brand-m)}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:var(--r)}
::-webkit-scrollbar-thumb:hover{background:var(--t4)}
.ic{flex:none;vertical-align:-2px}

/* ═══ RAIL LATERAL ═══════════════════════════════════════════════ */
.rail{
  position:fixed;inset:0 auto 0 0;width:var(--rail);background:var(--ink);
  display:flex;flex-direction:column;z-index:60;overflow-y:auto;
  scrollbar-width:thin;scrollbar-color:#333B47 transparent;
}
.rail::-webkit-scrollbar{width:6px}
.rail::-webkit-scrollbar-thumb{background:#333B47}
.rail-top{padding:14px 16px 12px;border-bottom:1px solid rgba(255,255,255,.07)}
/* ── Marca ──────────────────────────────────────────────────────────
   El logotipo trae su propio fondo azul, así que el bloque adopta ese
   mismo azul y la pieza se lee como una sola, no como una imagen pegada
   sobre otro color. El lema va bajo la línea naranja, en su naranja. */
.rail-mark{display:block;text-decoration:none;background:var(--marca-fondo);
  border-radius:var(--r);padding:10px 12px 9px}
.rail-mark:hover{filter:brightness(1.08)}

/* La figura mide exactamente lo que el logotipo, para que el pie pueda
   colocarse en porcentaje de esa anchura y no en píxeles: así la alineación
   se mantiene aunque el logotipo se muestre a otro tamaño. */
.marca-fig{display:block;width:100%;max-width:150px}
.marca-fig img{display:block;width:100%;height:auto}

/* La línea naranja del logotipo arranca en el 5,981 % de su anchura.
   El pie arranca justo ahí, de modo que la G queda bajo el inicio de la
   línea. El valor sale de medir la propia imagen, no de tantear. */
.marca-fig small{display:block;margin-top:6px;margin-left:5.981%;
  color:#F29A4F;white-space:nowrap;
  font:600 10px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase}
/* El naranja exacto del logotipo sobre el azul se queda en 3,7:1 y el lema es
   diminuto: se aclara un paso (5,2:1) sin dejar de leerse como el naranja. */

.rail-mark.grande .marca-fig{max-width:230px}
.rail-mark.grande .marca-fig small{margin-top:9px;font-size:11px}
.rail-proj{
  margin-top:12px;padding:8px 10px;border-radius:var(--r);
  background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.07);
}
.rail-proj .k{font:600 9px/1 var(--f-ui);letter-spacing:.1em;color:#9DB2CC;text-transform:uppercase}
.rail-proj .v{font:500 12px/1.35 var(--f-tx);color:#DDE3EA;margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rail-proj a{font:500 10.5px/1 var(--f-tx);color:#EDB77F;display:inline-block;margin-top:5px}

.rail-grp{padding:12px 8px 0}
.rail-grp>h6{
  font:600 9.5px/1 var(--f-ui);letter-spacing:.12em;color:#9DB2CC;
  text-transform:uppercase;padding:0 10px;margin-bottom:5px;
}
.rail-a{
  display:flex;align-items:center;gap:9px;padding:6.5px 11px 6.5px 13px;border-radius:var(--r);
  color:#BFD0E2;font:500 var(--rail-fs)/1.25 var(--f-tx);text-decoration:none;margin-bottom:1px;
  transition:background var(--mov),color var(--mov);position:relative;
}
.rail-a:hover{background:rgba(255,255,255,.06);color:#fff;text-decoration:none}
/* Sobre un menú azul, un activo azul no se distingue: lo señala el
   naranja de la marca, que además es donde el ojo va primero. */
.rail-a.on{background:rgba(255,255,255,.10);color:#fff}
.rail-a.on::before{content:'';position:absolute;left:0;top:6px;bottom:6px;width:3px;
  border-radius:0 3px 3px 0;background:var(--acento)}
.rail-a .ic{opacity:.72;width:15px;height:15px;flex:none}
.rail-a.on .ic{opacity:1}
.rail-a .n{
  margin-left:auto;font:600 9.5px/1 var(--f-mo);background:rgba(255,255,255,.13);
  padding:2.5px 6px;border-radius:var(--r-pill);
}
.rail-a .dot{width:7px;height:7px;border-radius:50%;flex:none}
/* El pie del menú —quién eres, tu perfil, salir y la versión— se queda
   clavado abajo mientras el resto del menú se desplaza por debajo.

   No es comodidad: el menú de una obra mide 1120 px —seguimiento, las
   disciplinas, las siete del Welding Book y configuración—, así que en una
   pantalla de portátil de 950 el pie quedaba FUERA DE LA VISTA y había que
   desplazar la barra para encontrar el botón de salir o el acceso al perfil.
   Nadie busca ahí lo que siempre está a la vista en cualquier otro sistema.

   `margin-top:auto` se queda para cuando el menú sí cabe: entonces no hay nada
   que desplazar y el pie se apoya abajo igual. El fondo es obligatorio —si no,
   las entradas del menú se ven pasar por debajo— y el z-index lo pone por
   encima de ellas.

   El fondo va con `inherit`, NO con un color ni con un testigo escrito a mano:
   así es SIEMPRE el de la barra, le pongan el que le pongan. La barra fue azul
   de marca y hoy es blanca; con `var(--ink)` el pie salía azul oscuro sobre una
   barra blanca, una franja que no era de este sistema. Con `inherit` no hay nada
   que acordarse de cambiar el día que el color cambie otra vez. */
.rail-foot{
  margin-top:auto;padding:12px 14px;border-top:1px solid rgba(255,255,255,.07);
  position:sticky;bottom:0;z-index:2;background-color:inherit;
}
.rail-user{display:flex;align-items:center;gap:9px}
/* Versión desplegada, al pie del menú. */
.rail-ver{margin-top:9px;text-align:center;font:600 10px/1.4 var(--f-ui);letter-spacing:.06em;color:#8FA6C0}
.rail-user .av{
  width:29px;height:29px;border-radius:var(--r);background:var(--brand);flex:none;
  display:grid;place-items:center;font:700 11px/1 var(--f-mo);color:#fff;
}
.rail-user .nm{font:500 12px/1.2 var(--f-tx);color:#E4E9EE;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rail-user .rl{font:600 9px/1.4 var(--f-ui);letter-spacing:.1em;color:#9DB2CC;text-transform:uppercase}
.rail-user a{color:#9DB2CC;margin-left:auto}
.rail-user a:hover{color:#fff}

/* ═══ ESTRUCTURA ═════════════════════════════════════════════════ */
.shell{margin-left:var(--rail);min-height:100vh;display:flex;flex-direction:column;
  transition:margin-left var(--mov-2)}

/* ── Menú lateral recogido ──────────────────────────────────────────
   El botón de la barra lo esconde y devuelve sus 230 px al contenido. Hace
   falta sobre todo en el editor de plantillas y en las tablas anchas: un
   protocolo apaisado se mira mejor con la pantalla entera, y el menú no se
   usa mientras se trabaja un formato.
   Se recuerda por navegador, y se aplica antes de pintar (hay un guion de dos
   líneas en la cabecera del documento) para que la página no empiece con el
   menú puesto y lo pierda a la vista. */
.rail{transition:transform var(--mov-2)}
.sin-rail .rail{transform:translateX(-100%)}
.sin-rail .shell{margin-left:0}
.topbar{
  height:var(--top);background:var(--paper);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:14px;padding:0 20px;position:sticky;top:0;z-index:50;
}
/* El título no cede mientras haya cajetín que recortar; sin cajetín (≤1024)
   sí cede, para que la búsqueda y la campana no se salgan de la pantalla. */
.topbar h1{font:600 16px/1.2 var(--f-ui);letter-spacing:.01em;flex:0 0 auto;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.topbar .crumb{font:500 11px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t4)}
.topbar .sp{flex:1}
/* En móvil abre el menú sobre el contenido; en escritorio lo recoge y lo
   devuelve. Es el mismo botón y el mismo sitio en los dos casos: el extremo
   izquierdo de la barra, pegado al menú que gobierna. */
.burger{display:inline-flex;background:none;border:none;color:var(--t2);cursor:pointer;padding:0;
  width:44px;height:44px;margin-left:-8px;align-items:center;justify-content:center;border-radius:var(--r);flex:none}
.burger:hover{background:var(--paper-2);color:var(--t1)}
/* El contenido llena la pantalla hasta un tope generoso y, a partir de ahí,
   se centra. Con el tope anterior —1560px— en un monitor de 1920 quedaban 150
   píxeles muertos a la derecha, y en uno de 2560 casi ochocientos: parecía un
   fallo de maquetación más que una decisión.

   El tope no desaparece porque sin él, en una pantalla muy ancha, una tabla de
   cuatro columnas se estira hasta que leer una fila obliga a recorrer medio
   metro con la vista. Centrado, el espacio sobrante se reparte a los dos lados
   y se lee como un margen, no como un hueco. */
/* El hueco de abajo es para la mascota: sin él, la última fila de una tabla
   larga queda debajo de ella y no se puede pulsar. */
.main{padding:20px 22px 104px;flex:1;width:100%;max-width:2100px;margin:0 auto}

/* ═══ CAJETÍN — el elemento firma del sistema ════════════════════
   Réplica del title block de un plano: celdas con hairline, rótulo
   condensado diminuto arriba y valor monoespaciado abajo. Es el mismo
   componente en pantalla y en papel, para que lo que se ve sea
   exactamente lo que se firma.                                      */
.cajetin{
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);
  border:1px solid var(--line);border-radius:var(--r-lg);background:var(--paper);
  box-shadow:var(--sh-1);overflow:hidden;
}
.cajetin.auto{grid-auto-columns:auto}
.cajetin>div{
  padding:11px 16px;border-right:1px solid var(--linea-suave);min-width:0;position:relative;
}
.cajetin>div:last-child{border-right:0}
.cajetin .k{
  font:400 11px/1.3 var(--f-tx);letter-spacing:0;text-transform:none;color:var(--t3);
  display:block;margin-bottom:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.cajetin .v{
  font:500 12.5px/1.3 var(--f-mo);color:var(--t1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.cajetin .v.tx{font-family:var(--f-tx);font-size:12.5px}
/* marcas de esquina: guiño al marco del plano, solo en la primera celda */
.cajetin>div:first-child::before,
.cajetin>div:first-child::after{
  content:'';position:absolute;width:5px;height:5px;border-color:var(--brand);border-style:solid;
}
.cajetin>div:first-child::before{top:2px;left:2px;border-width:1px 0 0 1px}
.cajetin>div:first-child::after{bottom:2px;left:2px;border-width:0 0 1px 1px}
/* Cada columna ocupa lo que su contenido y cede cuando falta sitio: con
   columnas iguales, un cliente de nombre largo se montaba sobre la fecha y
   los rótulos se pisaban entre sí. */
.topbar .cajetin{border:0;box-shadow:none;border-radius:0;background:none;
  flex:0 100 auto;min-width:0;max-width:760px;overflow:hidden;
  grid-auto-columns:minmax(0,max-content)}
/* Aquí el cajetín no es un documento, es el contexto de la obra: el rótulo
   («Cliente») sobra cuando el dato ya se entiende solo. */
.topbar .cajetin .k{display:none}
/* Las marcas de esquina son del documento, no de la barra */
.topbar .cajetin>div:first-child::before,
.topbar .cajetin>div:first-child::after{display:none}
.topbar .cajetin .v{font:400 12px/1.3 var(--f-tx);color:var(--t2)}
.topbar .cajetin .v.mono,.topbar .cajetin .c-proyecto .v{font-family:var(--f-mo);font-size:11.5px}
/* En bloque: sobre un <span> en línea el recorte con puntos suspensivos no
   actúa y el texto largo se montaba sobre la celda de al lado. */
.topbar .cajetin .v{display:block;max-width:260px}
.topbar .cajetin>div{padding:0 14px;border-right:1px solid var(--line);display:flex;align-items:center}

/* ═══ TARJETAS ═══════════════════════════════════════════════════ */
.card{
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh-1);overflow:hidden;
}
.card+.card{margin-top:16px}
/* La cabecera ya no es una banda gris con el título en mayúsculas: el título
   se lee en caja normal y, debajo, una línea que explica de dónde sale el dato. */
.card-h{
  display:flex;align-items:center;gap:12px;padding:15px 18px 12px;
}
.card-h h2,.card-h h3{font:600 15px/1.25 var(--f-ui);letter-spacing:.01em;color:var(--t1)}
.card-h .sub{display:block;font:400 11.5px/1.4 var(--f-tx);letter-spacing:0;color:var(--t3);margin-top:2px}
.card-h .sp{flex:1}
.card-b{padding:6px 18px 18px}
.card-b.flush{padding:0}
.card-h+.card-b.flush{border-top:1px solid var(--linea-suave)}
.card.edge{border-left:3px solid var(--brand)}
/* La misma marca al costado, en ámbar, para la tarjeta que avisa de algo que
   hay que resolver —una jornada descuadrada— y no solo informa. */
.card.edge-warn{border-left:3px solid var(--warn)}
/* Lista de renglones con una etiqueta al final. Donde una tabla de dos
   columnas se corta contra el borde del teléfono, aquí la etiqueta baja sola:
   lo que se pierde es una línea, no el final de la frase. */
.lista-fila{list-style:none;margin:0;padding:0}
.lista-fila li{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:4px 12px;padding:10px 2px;border-top:1px solid var(--linea-suave);
}
.lista-fila li:first-child{border-top:0}
.lista-fila li>div{flex:1 1 200px;min-width:0}

/* Fila que lleva a su junta: la del parte diario. La primera casilla, la de
   marcar, se queda con el cursor normal — ahí no se navega, se elige. */
.tbl tr.j-ir{cursor:pointer}
.tbl tr.j-ir .j-marca{cursor:auto}

/* Barra de marcado y búsqueda de la jornada. Se parte en dos líneas en el
   teléfono en vez de empujar la búsqueda fuera de la pantalla. */
.pd-barra{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;
  padding:10px 18px;border-bottom:1px solid var(--linea-suave);background:var(--paper-2);
}
.pd-barra .sp{flex:1;min-width:0}
.pd-barra .btn.on{background:var(--brand-l);border-color:var(--brand-m);color:var(--brand-d)}
@media (max-width:640px){ .pd-barra input[type=search]{max-width:100%!important;flex:1 1 100%} }

/* Casilla que se corrige desde la lista: se parece a un dato, no a un botón,
   hasta que se pasa por encima. El hueco va en ámbar, como iba antes. */
.celda-fix{
  background:none;border:0;padding:0;font:inherit;color:inherit;text-align:left;
  border-bottom:1px dashed var(--line-2);cursor:pointer;
}
.celda-fix:hover,.celda-fix:focus-visible{color:var(--brand-d);border-bottom-color:var(--brand)}
.celda-fix.vacia{color:var(--warn-tx);border-bottom-color:var(--warn)}

/* ═══ CURVA DE AVANCE SEMANAL ════════════════════════════════════
   Una barra por semana, con la cifra encima y la fecha debajo. Se desplaza a
   lo ancho en vez de encogerse: con veintiséis semanas, barras de tres píxeles
   no dicen nada, y en un teléfono se arrastra como cualquier tabla. */
.curva{
  display:flex;align-items:flex-end;gap:6px;height:150px;
  overflow-x:auto;overflow-y:hidden;padding:18px 2px 0;
}
/* La barra no crece para llenar el hueco: con dos semanas, repartir el ancho
   entre dos daba dos bloques enormes que parecían otra cosa. Ancho fijo, y lo
   que sobre queda en blanco a la derecha, que es lo honesto. */
.curva-sem{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;
  width:52px;flex:0 0 52px;height:100%;cursor:default}
.curva-sem i{
  display:block;width:100%;background:var(--brand);border-radius:3px 3px 0 0;
  min-height:2px;transition:background .15s;
}
.curva-sem:hover i{background:var(--brand-d)}
.curva-v{line-height:1.2;color:var(--t2);margin-bottom:3px}
.curva-x{line-height:1.2;margin-top:4px;white-space:nowrap}

/* Los dos botones del final de una fila —editar y borrar—. Juntos y sin
   separación extra: ocupan la última columna, que es estrecha a propósito. */
.btns-fila{display:inline-flex;gap:2px;white-space:nowrap}
.btns-fila .btn{padding:3px 6px}

/* Una fila apagada: sigue ahí, con sus registros, pero ya no se ofrece para lo
   nuevo. Se atenúa sin esconderla, que es justo la diferencia con borrarla. */
tr.apagada > td{opacity:.55}
tr.apagada:hover > td{opacity:.8}

/* En el teléfono, lo primero que se sale por la derecha de una tabla son las
   últimas columnas, y ahí es donde están los botones de editar y borrar: la
   tabla cabía, pero lo que se venía a hacer quedaba fuera de la pantalla.
   Las columnas marcadas como «opt» son las informativas —el área, la cuenta
   de subsistemas, el tipo de ubicación—: se esconden y el dato se enseña
   debajo del nombre, donde sí cabe. */
.col-estrecha{display:none}
@media (max-width:760px){
  .tbl .opt{display:none}
  .col-estrecha{display:inline-block;margin-left:6px}
}

/* Cabecera que ordena. La flecha dice por cuál se está ordenando. */
th.orden{cursor:pointer;user-select:none}
th.orden:hover{color:var(--brand-d)}
th.orden.on{color:var(--brand-d)}
/* Pie de tarjeta: la acción que cierra lo que la tarjeta enseña —generar el
   parte del día—, separada del contenido y siempre en el mismo sitio. */
/* Se parte en dos líneas cuando no cabe: en un teléfono, el pie con una frase
   y dos botones sacaba el último fuera de la tarjeta. Sin envolver, el botón
   que se sale es siempre el de la derecha, que es el que cierra la acción. */
.card-f{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:12px 18px;
  background:var(--paper-2);border-top:1px solid var(--linea-suave)}
.card-f .sp{flex:1}

/* ═══ CALENDARIO DE JORNADAS ═════════════════════════════════════ */
/* Un mes de un vistazo: qué días se soldó, cuántas juntas, y si su parte está
   hecho. El color va en el día, no en el marco, como en el resto del sistema. */
.cal{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
.cal-dow{font:600 10px/1 var(--f-ui);text-align:center;color:var(--t3);padding:2px 0 4px}
.cal-d{display:flex;flex-direction:column;align-items:center;justify-content:center;
  aspect-ratio:1;border-radius:6px;font:600 12px/1 var(--f-ui);text-decoration:none;
  border:1px solid transparent}
.cal-d.vacio{color:var(--t3);font-weight:400;opacity:.45}
.cal-d i{font:600 9px/1 var(--f-ui);font-style:normal;opacity:.8;margin-top:2px}
.cal-d.falta{background:var(--warn-bg);border-color:var(--warn-br);color:var(--warn-tx)}
/* El morado del circuito de firma, el mismo que usan las insignias. */
.cal-d.curso{background:var(--hold-bg);border-color:var(--hold-br);color:var(--hold)}
.cal-d.ok{background:var(--ok-bg);border-color:var(--ok-br);color:var(--ok)}
/* El día abierto, marcado por el borde y no por el relleno: así no se pierde
   la información de en qué estado está su parte. */
.cal-d.hoy{outline:2px solid var(--brand);outline-offset:1px}
.cal-leyenda{display:flex;flex-wrap:wrap;gap:10px;margin-top:10px}
.cal-leyenda span{display:inline-flex;align-items:center;gap:5px}
.cal-leyenda i{width:10px;height:10px;border-radius:3px;display:inline-block;border:1px solid}
.cal-leyenda i.falta{background:var(--warn-bg);border-color:var(--warn-br)}
.cal-leyenda i.curso{background:var(--hold-bg);border-color:var(--hold-br)}
.cal-leyenda i.ok{background:var(--ok-bg);border-color:var(--ok-br)}

/* La hoja del parte antes de emitirla, al pie de la pantalla. A lo ancho de la
   tarjeta y no en una ventana flotante: son veintiocho columnas, y en un modal
   hay que pelearse con ellas. */
/* La lupa de la vista previa: los tres controles juntos, separados del resto
   de la cabecera, para que no se lean como botones sueltos. */
.pv-zoom{display:inline-flex;align-items:center;gap:2px;padding:0 6px;
  border-left:1px solid var(--line);border-right:1px solid var(--line)}
.pv-zoom #pvEsc{min-width:44px;text-align:center;color:var(--t3)}

.pv-hoja{overflow-x:auto;background:var(--paper-2);padding:14px;border-radius:8px}
.pv-hoja table{background:#fff}

/* Partes diarios: la lista de jornadas a un lado y las juntas del día al otro.
   Antes esto usaba `.f-row`, que es la rejilla de DOCE columnas de los
   formularios: las dos tarjetas caían en una columna cada una —110 px— y el
   texto salía a palabra por renglón. Una rejilla de formulario no es una
   maqueta de página. */
.pd-cols{display:grid;gap:16px;grid-template-columns:320px minmax(0,1fr);align-items:start}
@media (max-width:900px){.pd-cols{grid-template-columns:minmax(0,1fr)}}

/* ═══ MOSAICO DE INDICADORES ═════════════════════════════════════ */
/* Todos los indicadores son la MISMA tarjeta. El color vive en el dato, no en
   el marco: antes uno iba relleno de azul y los demás llevaban un filo de
   color arriba, y la pantalla parecía hecha por tres personas distintas. */
.kpis{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin-bottom:16px}
.kpi{
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:16px 18px;box-shadow:var(--sh-1);
}
/* El indicador lleva su estado en el canto izquierdo, como las filas. */
.kpi{border-left:3px solid var(--line-2)}
.kpi.ok{border-left-color:var(--ok)}      .kpi.warn{border-left-color:var(--warn)}
.kpi.stop{border-left-color:var(--stop)}  .kpi.hold{border-left-color:var(--hold)}
.kpi.brand{border-left-color:var(--brand)}
.kpi .k{display:flex;align-items:center;gap:7px;font:400 12.5px/1.3 var(--f-tx);letter-spacing:0;text-transform:none;color:var(--t3)}
.kpi .v{font:500 34px/1.1 var(--f-ui);margin:4px 0 8px;letter-spacing:.01em;color:var(--t1)}
.kpi .v small,.kpi .v .u{font-size:19px;font-weight:500;color:var(--t3)}
.kpi .s{font:400 11.5px/1.4 var(--f-tx);color:var(--t3)}
.kpi .bar{margin-bottom:8px}
.kpi.ok .v{color:var(--ok)}
.kpi.warn .v{color:var(--warn)}
.kpi.stop .v{color:var(--stop)}
.kpi.hold .v{color:var(--hold)}
/* El indicador principal ya no se rellena de azul: se distingue por el dato */
.kpi.brand .v{color:var(--brand)}
@keyframes rise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ═══ TABLAS ═════════════════════════════════════════════════════ */
.tbl-wrap{overflow-x:auto}
table.tbl{width:100%;border-collapse:collapse;font-size:13px}
/* La cabecera es de las dos únicas zonas donde se conservan las mayúsculas
   (la otra es el rótulo de grupo del menú). Sin fondo gris: basta la línea. */
/* La cabecera se asienta sobre el fondo de trabajo y cierra con una línea de
   dos píxeles: blanca sobre blanco, al desplazar una lista larga la cabecera
   pegajosa se mezclaba con la primera fila. */
table.tbl th{
  font:600 11px/1.2 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t3);
  text-align:left;padding:11px 14px;background:var(--canvas);
  border-bottom:2px solid var(--line-2);white-space:nowrap;position:sticky;top:0;z-index:2;
}
/* Filas altas (se leen en tablet) y separador casi invisible: la rejilla
   completa de antes competía con los datos. */
table.tbl td{padding:12px 14px;border-bottom:1px solid var(--linea-suave);vertical-align:middle}
table.tbl tbody tr:nth-child(even){background:var(--paper-2)}
table.tbl tbody tr:hover{background:var(--fila-hover)}
/* El estado, en el canto de la fila.
   No es adorno: el color es el mismo de la insignia que la fila ya lleva, de
   modo que en una lista de cincuenta registros se ve qué está aprobado y qué
   está devuelto sin leer una palabra. Se apoya en :has(); donde no exista, la
   fila sale con el canto neutro y todo lo demás sigue igual. */
table.tbl tbody td:first-child{box-shadow:inset 3px 0 0 var(--idle-br)}
table.tbl tbody tr:has(.badge-ok)    td:first-child{box-shadow:inset 3px 0 0 var(--ok)}
table.tbl tbody tr:has(.badge-warn)  td:first-child{box-shadow:inset 3px 0 0 var(--warn)}
table.tbl tbody tr:has(.badge-stop)  td:first-child{box-shadow:inset 3px 0 0 var(--stop)}
table.tbl tbody tr:has(.badge-hold)  td:first-child{box-shadow:inset 3px 0 0 var(--hold)}
table.tbl tbody tr:has(.badge-brand) td:first-child{box-shadow:inset 3px 0 0 var(--brand)}
table.tbl tbody tr:last-child td{border-bottom:0}
table.tbl .mono{font:500 12px/1.3 var(--f-mo)}
table.tbl .c{text-align:center}
table.tbl .r{text-align:right;font-family:var(--f-mo)}
table.tbl .w1{width:1%;white-space:nowrap}
.empty{padding:44px 20px;text-align:center;color:var(--t3)}
.empty b{display:block;font:600 15px/1.3 var(--f-ui);letter-spacing:.03em;color:var(--t2);margin-bottom:6px}
.empty p{font-size:13px;max-width:400px;margin:0 auto 14px}

/* ═══ INSIGNIAS Y ESTADOS ════════════════════════════════════════ */
/* Una sola familia de píldoras: fondo tintado, texto del mismo tono y sin
   borde. El punto de color hace el trabajo que antes hacían cinco marcos. */
.badge{
  display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:var(--r-pill);
  font:600 11px/1.45 var(--f-tx);letter-spacing:0;text-transform:none;
  background:var(--idle-bg);color:var(--idle-tx);border:0;white-space:nowrap;
}
.badge::before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.85;flex:none}
.badge.sin-punto::before{display:none}
.badge-ok{background:var(--ok-bg);color:var(--ok)}
.badge-warn{background:var(--warn-bg);color:var(--warn-tx)}
.badge-stop{background:var(--stop-bg);color:var(--stop)}
.badge-hold{background:var(--hold-bg);color:var(--hold)}
.badge-brand{background:var(--brand-l);color:var(--brand-d)}
.chip{
  display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:var(--r-pill);
  font:600 10px/1.7 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;
  border:1px solid currentColor;background:transparent;
}
.dot{width:7px;height:7px;border-radius:50%;display:inline-block;flex:none}

/* ═══ BARRA DE AVANCE ════════════════════════════════════════════ */
.bar{height:6px;border-radius:var(--r-pill);background:var(--pista);overflow:hidden;min-width:60px}
.bar>i{display:block;height:100%;background:var(--brand);border-radius:var(--r-pill);transition:width var(--mov-2)}
.bar.ok>i{background:var(--ok)} .bar.warn>i{background:var(--warn)} .bar.stop>i{background:var(--stop)}
.pct{font:600 11px/1 var(--f-mo);color:var(--t2);min-width:38px;display:inline-block;text-align:right}

/* ═══ BOTONES ════════════════════════════════════════════════════ */
/* Una altura, un radio y tres pesos: relleno (la acción principal), con borde
   (la secundaria) y plano (la terciaria). Sin mayúsculas: en un botón largo
   («Enviar lo llenado en campo») costaban de leer. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  height:36px;padding:0 15px;border-radius:var(--r);border:1px solid transparent;cursor:pointer;
  font:600 13px/1.2 var(--f-tx);letter-spacing:0;text-transform:none;
  background:var(--brand);color:#fff;transition:background var(--mov),border-color var(--mov),color var(--mov);
  text-decoration:none;white-space:nowrap;
}
.btn:hover{background:var(--brand-d);color:#fff;text-decoration:none}
.btn:disabled,.btn[aria-disabled=true]{opacity:.5;cursor:not-allowed}
.btn-ghost{background:var(--paper);color:var(--t1);border-color:var(--line-2)}
.btn-ghost:hover{background:var(--paper-2);color:var(--t1);border-color:var(--t4)}
/* Terciario: sin fondo ni borde hasta que se pasa el ratón */
.btn-plano{background:transparent;color:var(--t2);border-color:transparent}
.btn-plano:hover{background:var(--paper-2);color:var(--t1);border-color:var(--line)}
.btn-ok{background:var(--ok)}    .btn-ok:hover{background:#125C3A}
.btn-stop{background:var(--stop)}.btn-stop:hover{background:#8F211B}
/* Blanco sobre el naranja de marca da 3,1:1: no se lee. Se conserva el naranja
   y se escribe en tinta oscura (5,6:1), también al pasar el ratón. */
.btn-acento{background:var(--acento);border-color:var(--acento);color:var(--t1)}
.btn-acento:hover{background:#C96E22;border-color:#C96E22;color:var(--t1)}
.btn-warn{background:var(--warn)}.btn-warn:hover{background:#945B00}
.btn-sm{height:32px;padding:0 12px;font-size:12.5px}
.btn-xs{height:28px;padding:0 10px;font-size:12px;letter-spacing:0}
.btn-lg{height:42px;padding:0 20px;font-size:14px}
.btn-block{width:100%}
.btn-icon{width:36px;height:36px;padding:0;border-radius:var(--r)}
.btn-sm.btn-icon{width:32px;height:32px}
.btn-xs.btn-icon{width:28px;height:28px}
.btns{display:flex;gap:8px;flex-wrap:wrap;align-items:center}

/* ═══ FORMULARIOS BASE ═══════════════════════════════════════════ */
.f-row{display:grid;gap:12px;grid-template-columns:repeat(12,1fr)}
.f-g{display:flex;flex-direction:column;gap:5px}
/* La etiqueta de un campo se lee, no se grita: en caja normal cabe más y se
   distingue del dato por el color, no por el tamaño de letra. */
.f-g label,.fs-lbl{
  font:500 11.5px/1.35 var(--f-tx);letter-spacing:0;text-transform:none;color:var(--t2);
}
.f-g label .req,.fs-lbl .req{color:var(--stop);font-style:normal;margin-left:3px}
.in,.fs-in{
  width:100%;padding:8px 10px;border:1px solid var(--line-2);border-radius:var(--r);
  background:var(--paper);font:400 13.5px/1.4 var(--f-tx);transition:border-color var(--mov),box-shadow var(--mov);
}
/* El halo usa el azul de marca a buena intensidad: el anterior, verdoso al 12 %,
   casi no se veía y con teclado no se sabía en qué campo se estaba. */
.in:focus,.fs-in:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-m)}
.in:disabled,.fs-in:disabled{background:var(--paper-2);color:var(--t3);cursor:not-allowed}
select.in,select.fs-in{cursor:pointer;appearance:none;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2377808D' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 8px center;background-size:15px;padding-right:28px}
textarea.in,textarea.fs-in{resize:vertical;min-height:64px}
.hint,.fs-hint{font:400 11px/1.4 var(--f-tx);color:var(--t3)}
.fs-hint.fs-crit{color:var(--brand-d)}

/* ═══ FILTROS ════════════════════════════════════════════════════ */
.filtros{
  display:flex;gap:9px;flex-wrap:wrap;align-items:flex-end;
  padding:12px 16px;background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r-lg);margin-bottom:14px;
}
.filtros .f-g{min-width:140px}
.filtros .in{padding:6px 9px;font-size:13px}
.buscar{position:relative;flex:1;min-width:180px}
.buscar .ic{position:absolute;left:9px;top:50%;transform:translateY(-50%);color:var(--t4)}
.buscar .in{padding-left:31px}

/* ═══ MOTOR DE FORMULARIOS (FormSchema) ══════════════════════════ */
.fs-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:13px 12px}
.fs-col{display:flex;flex-direction:column;gap:5px;min-width:0}
.fs-w1{grid-column:span 1}.fs-w2{grid-column:span 2}.fs-w3{grid-column:span 3}
.fs-w4{grid-column:span 4}.fs-w5{grid-column:span 5}.fs-w6{grid-column:span 6}
.fs-w7{grid-column:span 7}.fs-w8{grid-column:span 8}.fs-w9{grid-column:span 9}
.fs-w10{grid-column:span 10}.fs-w11{grid-column:span 11}.fs-w12{grid-column:span 12}

/* El rótulo de una sección del formato: pequeño, apagado y con una línea
   que llega hasta el borde. Antes era un titular negro con un cuadrado azul
   delante, y competía con los datos que anuncia. */
.fs-seccion{
  margin-top:14px;padding:0 0 8px;border-bottom:0;
  font:600 11px/1.2 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t3);
  display:flex;flex-direction:row;align-items:center;gap:12px;
}
.fs-seccion::after{content:'';flex:1;height:1px;background:var(--line)}
.fs-subtitulo{font:600 11px/1.3 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t2);margin-top:4px}
.fs-sep{border-top:1px dashed var(--line-2);margin:4px 0}
.fs-nota{
  background:var(--paper-2);border-left:3px solid var(--line-2);padding:9px 12px;
  border-radius:0 var(--r) var(--r) 0;font-size:12.5px;color:var(--t2);
}
.fs-criterio{
  background:var(--brand-l);border-left:3px solid var(--brand);padding:9px 12px;
  border-radius:0 var(--r) var(--r) 0;font-size:12.5px;color:var(--brand-d);
}
.fs-criterio b{display:block;font:600 9px/1.4 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;margin-bottom:2px}
.fs-unidad{display:flex;align-items:stretch}
.fs-unidad .fs-in{border-radius:var(--r) 0 0 var(--r)}
.fs-u{
  display:grid;place-items:center;padding:0 9px;background:var(--paper-2);
  border:1px solid var(--line-2);border-left:0;border-radius:0 var(--r) var(--r) 0;
  font:500 11px/1 var(--f-mo);color:var(--t3);white-space:nowrap;
}
.fs-check,.fs-radio{display:inline-flex;align-items:center;gap:7px;font-size:13.5px;cursor:pointer;padding:6px 0}
.fs-radios{display:flex;gap:14px;flex-wrap:wrap}

/* Conformidad: segmentos que se pintan al elegir */
/* Conforme / No conforme / No aplica: el mismo grupo segmentado que las
   bandejas y las pestañas. Sin rejilla interna, y la elegida se rellena. */
.fs-conf{display:inline-flex;gap:3px;padding:3px;background:var(--seg);border-radius:var(--r-pill)}
.fs-conf-op{position:relative;cursor:pointer;user-select:none}
.fs-conf-op input{position:absolute;opacity:0;inset:0;cursor:pointer}
.fs-conf-op span{
  display:block;min-width:36px;text-align:center;padding:5px 12px;border-radius:var(--r-pill);
  font:600 11.5px/1.2 var(--f-tx);letter-spacing:0;color:var(--t2);
  transition:background var(--mov),color var(--mov);
}
.fs-conf-op:hover span{background:rgba(255,255,255,.7);color:var(--t1)}
.fs-conf-op.ok.on span{background:var(--ok);color:#fff}
.fs-conf-op.no.on span{background:var(--stop);color:#fff}
.fs-conf-op.na.on span{background:var(--idle);color:#fff}
.fs-conf-op input:focus-visible+span{box-shadow:var(--foco)}
.fs-conf.sm .fs-conf-op span{min-width:30px;padding:4px 9px;font-size:11px}

/* Recuento de la lista de verificación: una tarjeta, cuatro cifras y una
   barra de avance. Antes eran cuatro tarjetas y ocupaban media pantalla. */
.recuento{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh-1);padding:14px 18px 16px;margin-bottom:16px}
.recuento .r-cab{display:flex;align-items:center;gap:10px;font:600 13px/1.3 var(--f-ui);color:var(--t1)}
.recuento .r-cab .sp{flex:1}
.recuento .r-de{font:400 11.5px/1.3 var(--f-tx);color:var(--t3)}
.recuento .r-nums{display:flex;flex-wrap:wrap;gap:8px 26px;margin:10px 0 12px}
.recuento .r-nums>div{display:flex;flex-direction:column;gap:2px;min-width:78px}
.recuento .r-nums b{font:500 28px/1 var(--f-ui);color:var(--t4)}
.recuento .r-nums b.ok{color:var(--ok)} .recuento .r-nums b.stop{color:var(--stop)}
.recuento .r-nums b.warn{color:var(--warn)}
.recuento .r-nums span{font:400 11.5px/1.3 var(--f-tx);color:var(--t3)}

/* Tablas dentro del formulario */
.fs-tabla-wrap{gap:7px}
.fs-tabla-scroll{overflow-x:auto;border:1px solid var(--line-2);border-radius:var(--r)}
table.fs-tabla{width:100%;border-collapse:collapse;font-size:12.5px;background:var(--paper)}
table.fs-tabla th{
  font:600 9px/1.3 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t3);
  background:var(--paper-2);padding:7px 8px;text-align:left;border-bottom:1px solid var(--line-2);
  border-right:1px solid var(--line);white-space:nowrap;
}
table.fs-tabla th em{font-style:normal;font-family:var(--f-mo);text-transform:none;letter-spacing:0}
table.fs-tabla td{padding:3px 5px;border-bottom:1px solid var(--line);border-right:1px solid var(--line)}
table.fs-tabla th:last-child,table.fs-tabla td:last-child{border-right:0}
table.fs-tabla td.n,table.fs-tabla th.n{width:34px;text-align:center;font:500 11px/1 var(--f-mo);color:var(--t4);background:var(--paper-2)}
table.fs-tabla td.txt{padding:7px 9px;font-size:12.5px}
table.fs-tabla td.cc,table.fs-tabla th.cc{text-align:center;width:1%;white-space:nowrap}
table.fs-tabla input[type=text],table.fs-tabla input[type=number],
table.fs-tabla input[type=date],table.fs-tabla select{
  width:100%;min-width:74px;border:1px solid transparent;background:transparent;
  padding:5px 6px;border-radius:var(--r);font:400 12.5px/1.3 var(--f-tx);
}
table.fs-tabla input:focus,table.fs-tabla select:focus{
  outline:none;border-color:var(--brand);background:var(--paper);box-shadow:0 0 0 2px rgba(18,101,127,.1)
}
table.fs-tabla input[type=number]{font-family:var(--f-mo);text-align:right}
table.fs-tabla tr.critico td.txt{border-left:3px solid var(--warn)}
table.fs-tabla .ref{font:500 10px/1 var(--f-mo);color:var(--t4);margin-left:5px}
.fs-delrow{
  border:none;background:none;color:var(--t4);cursor:pointer;font-size:18px;line-height:1;
  padding:0 6px;border-radius:var(--r);
}
.fs-delrow:hover{color:var(--stop);background:var(--stop-bg)}
.fs-addrow{align-self:flex-start}
select.conf-ok{color:var(--ok);font-weight:600}
select.conf-no{color:var(--stop);font-weight:600}

/* Evidencia fotográfica */
.fs-drop{
  border:1.5px dashed var(--line-2);border-radius:var(--r);padding:14px;
  display:flex;flex-direction:column;gap:9px;align-items:flex-start;background:var(--paper-2);
}
.fs-drop.over{border-color:var(--brand);background:var(--brand-l)}
.fs-thumbs{display:flex;gap:8px;flex-wrap:wrap;width:100%}
.fs-thumb{
  position:relative;width:84px;height:84px;border-radius:var(--r);overflow:hidden;
  border:1px solid var(--line-2);background:var(--paper);
}
.fs-thumb img{width:100%;height:100%;object-fit:cover}
.fs-thumb>a{display:block;width:100%;height:100%}
.fs-doc{display:flex;align-items:center;justify-content:center;width:100%;height:100%;font:700 13px/1 var(--f-ui);color:var(--stop);background:var(--stop-bg)}
.fs-thumb button{
  position:absolute;top:2px;right:2px;width:19px;height:19px;border-radius:50%;
  border:none;background:rgba(13,17,23,.78);color:#fff;cursor:pointer;font-size:12px;line-height:1;
}

/* ═══ CIRCUITO DE FIRMAS ═════════════════════════════════════════ */
.firmas{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
.firma{border:1px solid var(--line-2);border-radius:var(--r);background:var(--paper);overflow:hidden}
.firma-h{
  padding:6px 10px;background:var(--paper-2);border-bottom:1px solid var(--line);
  font:600 9.5px/1.4 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t2);
  display:flex;align-items:center;gap:7px;
}
.firma-b{padding:10px;min-height:96px;display:flex;flex-direction:column;justify-content:flex-end;gap:5px}
.firma-img{height:48px;object-fit:contain;object-position:left bottom;align-self:flex-start}
.firma-line{border-top:1px solid var(--t1);padding-top:5px;margin-top:auto}
.firma-nm{font:500 12px/1.3 var(--f-tx);color:var(--t1)}
.firma-mt{font:400 10.5px/1.4 var(--f-mo);color:var(--t3)}
.firma.pend .firma-b{background:repeating-linear-gradient(45deg,transparent,transparent 7px,var(--paper-2) 7px,var(--paper-2) 14px)}
.firma.firmado{border-color:var(--ok-br)}
.firma.observado{border-color:var(--warn-br)}
.firma.rechazado{border-color:var(--stop-br)}

/* Lienzo de firma manuscrita */
.pad{border:1px solid var(--line-2);border-radius:var(--r);background:var(--paper);touch-action:none;width:100%;height:170px;cursor:crosshair}

/* ═══ PESTAÑAS ═══════════════════════════════════════════════════ */
/* Pestañas: el mismo grupo segmentado que las bandejas, para que dentro de
   una hoja y dentro de una lista se maneje igual. */
.tabs{display:inline-flex;gap:4px;margin-bottom:16px;overflow-x:auto;padding:4px;background:var(--seg);border-radius:var(--r-lg)}
.tab{
  padding:7px 14px;border:1px solid transparent;background:none;cursor:pointer;white-space:nowrap;border-radius:var(--r);
  font:500 12.5px/1.2 var(--f-tx);letter-spacing:0;text-transform:none;color:var(--t2);
  transition:background var(--mov),color var(--mov);
}
.tab:hover{color:var(--t1);background:rgba(255,255,255,.6)}
.tab.on{color:var(--t1);font-weight:600;background:var(--paper);box-shadow:0 1px 2px rgba(16,24,40,.06)}

/* ═══ MODAL ══════════════════════════════════════════════════════ */
.ov{position:fixed;inset:0;background:rgba(13,17,23,.5);z-index:90;display:none;
  align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(2px)}
.ov.on{display:flex}
.modal{
  background:var(--paper);border-radius:var(--r-lg);box-shadow:var(--sh-3);
  width:100%;max-width:620px;max-height:90vh;display:flex;flex-direction:column;
}
.modal.w{max-width:920px} .modal.xl{max-width:1200px}
.modal-h{display:flex;align-items:center;gap:12px;padding:13px 18px;border-bottom:1px solid var(--line)}
.modal-h h3{font:600 14px/1.2 var(--f-ui);letter-spacing:.1em;text-transform:uppercase}
.modal-h .x{margin-left:auto;border:none;background:none;cursor:pointer;color:var(--t3);padding:4px}
.modal-h .x:hover{color:var(--stop)}
.modal-b{padding:18px;overflow-y:auto;flex:1}
.modal-f{padding:12px 18px;border-top:1px solid var(--line);display:flex;gap:8px;justify-content:flex-end;background:var(--paper-2)}

/* ═══ AVISOS ═════════════════════════════════════════════════════ */
.aviso{
  padding:11px 14px;border-radius:var(--r);border:1px solid var(--brand-m);
  background:var(--brand-l);color:var(--brand-d);font-size:13px;margin-bottom:14px;
  display:flex;gap:9px;align-items:flex-start;
}
.aviso.ok{background:var(--ok-bg);border-color:var(--ok-br);color:var(--ok)}
.aviso.warn{background:var(--warn-bg);border-color:var(--warn-br);color:var(--warn-tx)}
.aviso.stop{background:var(--stop-bg);border-color:var(--stop-br);color:var(--stop)}
.aviso ul{margin:5px 0 0 17px}

.toast{
  position:fixed;bottom:20px;right:20px;z-index:120;display:flex;flex-direction:column;gap:8px;
}
.toast>div{
  background:var(--ink);color:#fff;padding:11px 16px;border-radius:var(--r);
  box-shadow:var(--sh-3);font-size:13px;max-width:380px;animation:rise .22s ease both;
  border-left:3px solid var(--brand);
}
.toast>div.ok{border-left-color:var(--ok)}
.toast>div.stop{border-left-color:var(--stop)}

/* ═══ INICIO DE SESIÓN ═══════════════════════════════════════════ */
.login-wrap{min-height:100vh;display:grid;grid-template-columns:1.05fr .95fr}
.login-art{
  background:var(--ink);color:#fff;padding:52px 46px;display:flex;flex-direction:column;
  justify-content:space-between;position:relative;overflow:hidden;
}
/* trama de plano: retícula fina sobre grafito */
.login-art::before{
  content:'';position:absolute;inset:0;opacity:.16;
  background-image:linear-gradient(rgba(95,182,208,.35) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(95,182,208,.35) 1px,transparent 1px);
  background-size:34px 34px;
  mask-image:radial-gradient(ellipse at 30% 40%,#000 20%,transparent 72%);
}
.login-art>*{position:relative}
.login-marca{margin-bottom:44px}   /* en teléfono se recoge: ver el tramo ≤980px */
.login-art h1{font:700 40px/1.05 var(--f-ui);letter-spacing:-.01em;max-width:9em}
.login-art h1 em{font-style:normal;color:var(--marca-naranja)}
.login-art p{color:#8B95A2;font-size:14px;max-width:34em;margin-top:16px}
.login-art .cajetin{border-color:#2A333F;background:transparent;margin-top:34px;max-width:520px}
.login-art .cajetin>div{border-right-color:#2A333F;padding:7px 11px}
.login-art .cajetin .k{color:#9DB2CC}
.login-art .cajetin .v{color:#C3CBD4}
.login-form{display:grid;place-items:center;padding:40px 24px;background:var(--paper)}
.login-form form{width:100%;max-width:340px;display:flex;flex-direction:column;gap:14px}
.login-form h2{font:600 21px/1.2 var(--f-ui);letter-spacing:.01em}
/* Sin margen negativo: el formulario ya separa sus bloques con «gap», y el
   reset general pone los márgenes a cero, así que ese -8px no compensaba
   nada —restaba de más y montaba el subtítulo sobre el título—. */
.login-form .sub{font-size:13px;color:var(--t3);margin-top:2px}

/* ═══ LISTA DE PROYECTOS ═════════════════════════════════════════ */
.proj-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(290px,1fr))}
.proj{
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;transition:border-color var(--mov),box-shadow var(--mov);display:flex;flex-direction:column;
}
.proj:hover{border-color:var(--brand);box-shadow:var(--sh-2);text-decoration:none}
.proj-top{padding:13px 15px;border-bottom:1px solid var(--line);border-left:4px solid var(--brand)}
.proj-top .cd{font:600 10px/1 var(--f-mo);color:var(--t4);letter-spacing:.08em}
.proj-top h3{font:600 15px/1.3 var(--f-ui);letter-spacing:.02em;color:var(--t1);margin-top:5px}
.proj-b{padding:11px 15px;display:grid;gap:6px;font-size:12.5px;color:var(--t2);flex:1}
.proj-b .l{display:flex;gap:8px}
.proj-b .l b{font:600 8.5px/1.7 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t4);min-width:74px}
/* El pie tiene que poder saltar de línea: al añadir «Desactivar» ya no caben
   las dos etiquetas y los dos botones en una tarjeta de 290px, y lo que
   sobraba se salía por el borde en vez de bajar. */
.proj-f{padding:9px 15px;background:var(--paper-2);border-top:1px solid var(--line);
  display:flex;align-items:center;gap:6px 8px;flex-wrap:wrap}
.proj-f .sp{flex:1 1 auto;min-width:0}
.proj-f .btn{flex:none}
/* Las etiquetas ceden antes que los botones: son informativas, no accionables */
.proj-f .badge{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}

/* ═══ EDITOR DE PLANTILLAS ═══════════════════════════════════════ */
.ed{display:grid;grid-template-columns:212px 1fr 292px;gap:14px;align-items:start}
.ed-pal{position:sticky;top:calc(var(--top) + 16px)}
.ed-pal h6,.ed-props h6{
  font:600 9px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t3);
  padding:12px 12px 6px;
}
.ed-item{
  display:flex;align-items:center;gap:8px;padding:7px 12px;cursor:grab;font-size:12.5px;
  border-bottom:1px solid var(--line);color:var(--t2);transition:background var(--mov);
}
.ed-item:hover{background:var(--brand-l);color:var(--brand-d)}
.ed-item:active{cursor:grabbing}
.ed-canvas{min-height:420px;padding:16px;background:var(--paper);
  border:1px solid var(--line);border-radius:var(--r-lg)}
.ed-drop{
  border:1.5px dashed var(--line-2);border-radius:var(--r);padding:26px;text-align:center;
  color:var(--t3);font-size:13px;
}
.ed-drop.over{border-color:var(--brand);background:var(--brand-l)}
.ed-campo{position:relative;border:1px solid transparent;border-radius:var(--r);padding:4px}
.ed-campo:hover{border-color:var(--brand-m);background:var(--brand-l)}
.ed-campo.sel{border-color:var(--brand);background:var(--brand-l)}
.ed-campo .ed-tools{
  position:absolute;top:2px;right:2px;display:none;gap:2px;background:var(--paper);
  border:1px solid var(--line-2);border-radius:var(--r);padding:1px;
}
.ed-campo:hover .ed-tools,.ed-campo.sel .ed-tools{display:flex}
.ed-tools button{border:none;background:none;cursor:pointer;padding:3px 5px;color:var(--t3);font-size:11px;border-radius:var(--r)}
.ed-tools button:hover{background:var(--paper-2);color:var(--brand)}
.ed-props{position:sticky;top:calc(var(--top) + 16px);max-height:calc(100vh - var(--top) - 34px);overflow-y:auto}

/* Vista previa del archivo importado */
.prev-grid{overflow:auto;max-height:460px;border:1px solid var(--line-2);border-radius:var(--r)}
table.prev{border-collapse:collapse;font:400 11.5px/1.35 var(--f-mo);white-space:nowrap}
table.prev td{border:1px solid var(--line);padding:3px 7px;max-width:280px;overflow:hidden;text-overflow:ellipsis}
table.prev td.rn{background:var(--paper-2);color:var(--t4);text-align:right;position:sticky;left:0;font-size:10px}

/* ═══ UTILIDADES ═════════════════════════════════════════════════ */
.mono{font-family:var(--f-mo)}
.up{font-family:var(--f-ui);text-transform:uppercase;letter-spacing:.1em}
.muted{color:var(--t3)}
.small{font-size:12px}
.tiny{font-size:11px}
.strong{font-weight:600}
.nowrap{white-space:nowrap}
.right{text-align:right} .center{text-align:center}
.flex{display:flex;gap:10px;align-items:center} .wrap{flex-wrap:wrap}
.sp{flex:1}
.grid2{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.mt0{margin-top:0}.mt1{margin-top:8px}.mt2{margin-top:16px}.mt3{margin-top:24px}
.mb1{margin-bottom:8px}.mb2{margin-bottom:16px}
.hide{display:none!important}

/* ═══ RESPONSIVE ═════════════════════════════════════════════════ */
@media (max-width:1180px){
  .ed{grid-template-columns:1fr}
  .ed-pal,.ed-props{position:static;max-height:none}
  .ed-pal .ed-item{display:inline-flex;border:1px solid var(--line);border-radius:var(--r);margin:0 4px 4px 0}
}
@media (max-width:980px){
  .login-wrap{grid-template-columns:1fr;grid-template-rows:auto 1fr}
  .login-art{padding:30px 24px}
  .login-art h1{font-size:29px}
}
@media (max-width:860px){
  .rail{transform:translateX(-100%);transition:transform var(--mov-2)}
  .rail.open{transform:none;box-shadow:var(--sh-3)}
  .shell{margin-left:0}
  .burger{display:inline-flex}
  .topbar .cajetin{display:none}
  .main{padding:14px}
  .fs-col[class*=fs-w]{grid-column:span 12}
  .cajetin{grid-auto-flow:row;grid-auto-columns:auto}
  .cajetin>div{border-right:0;border-bottom:1px solid var(--line-2)}
  .cajetin>div:last-child{border-bottom:0}
}

/* ═══════════════════════════════════════════════════════════════════
   IMPRESIÓN — el registro en papel A4
   ═══════════════════════════════════════════════════════════════════ */
@media print{
  @page{size:A4 portrait;margin:11mm 10mm 13mm}
  .rail,.topbar,.filtros,.btns,.btn,.tabs,.ov,.toast,.no-print{display:none!important}
  body{background:#fff;font-size:10pt}
  .shell{margin:0}
  .main{padding:0;max-width:none}
  .card{border:none;box-shadow:none;border-radius:0}
  .card-h{background:none;border-bottom:1px solid #000;padding:0 0 4px}
  .card-b{padding:0}
  .hoja{page-break-after:always}
  .hoja:last-child{page-break-after:auto}
  .firmas,.pr-tabla tr,.fs-tabla tr{page-break-inside:avoid}
}
/* El documento no impone su ancho: llena el papel que lo contiene, que ya
   sabe si es vertical o apaisado y tiene su propio margen. Fijarle 297mm dentro
   de una hoja de 297mm con 10mm de relleno lo hacía sobresalir 20mm por la
   derecha, que es el desajuste que se veía entre el borde blanco y la tabla. */
/* El documento llena el papel que lo contiene, sin tope propio: el papel ya
   sabe si es vertical o apaisado y reserva su margen. Un «max-width» aquí
   sobra —el papel apaisado mide justo eso— y en cuanto el papel cambie de
   medida dejaría un hueco a la derecha, que es lo que se veía. */
.hoja.landscape{width:100%}
@page landscape{size:A4 landscape}

/* Bloque imprimible del registro */
.pr-doc{background:#fff;color:#000;font-family:var(--f-tx)}
/* La cabecera ocupaba casi una cuarta parte del alto de la hoja: el cajetín
   apilaba cada rótulo sobre su valor —CÓDIGO arriba, el código debajo— y eso
   son cinco filas de doble altura. Puestos en la misma línea, como en un
   cajetín de plano de verdad, la franja baja de 147 a unos 95 px y el formato
   gana una docena de filas útiles. */
.pr-cab{display:flex;border:1px solid #000;border-bottom:0}
.pr-cab .logo{width:112px;padding:4px;border-right:1px solid #000;display:grid;place-items:center}
.pr-cab .logo img{max-height:38px;max-width:100px;width:auto}
.pr-cab .logo .marca{font:700 10.5pt/1.15 var(--f-ui);letter-spacing:.09em;color:var(--ink);text-align:center}
.pr-cab .tit{flex:1;display:flex;flex-direction:column;min-width:0}
.pr-cab .tit .fase{background:#FDF3E0;border-bottom:1px solid #000;padding:3px 8px;text-align:center;
  font:700 8pt/1.2 var(--f-ui);letter-spacing:.18em;text-transform:uppercase;color:#7A4A00}
.pr-cab .tit h1{flex:1;display:flex;align-items:center;justify-content:center;text-align:center;
  padding:4px 12px;font:700 12pt/1.2 var(--f-ui);letter-spacing:.04em;text-transform:uppercase;color:#111}
.pr-cab .tit small{border-top:1px solid #BBB;padding:2px 8px;text-align:center;
  font:500 7pt/1.3 var(--f-mo);color:#555}
.pr-cab .meta{width:172px;border-left:1px solid #000}
.pr-cab .meta div{padding:1.5px 7px;border-bottom:1px solid #000;display:flex;gap:6px;align-items:baseline;
  font:500 7.5pt/1.3 var(--f-mo);color:#000;word-break:break-word}
.pr-cab .meta div:last-child{border-bottom:0}
.pr-cab .meta b{flex:0 0 64px;font:600 6.2pt/1.3 var(--f-ui);letter-spacing:.1em;
  color:#555;text-transform:uppercase}

/* ── Separación entre secciones ────────────────────────────────────────
   Cabecera, identificación, cuerpo, observaciones y firmas se leen como
   bloques, y cada uno se cierra con su línea; antes no había nada que cerrara
   la hoja por abajo ni que marcara dónde acaba el cajetín y empieza el
   formato.

   El trazo es el MISMO que el de las celdas. Lo que separa es que la línea
   esté, no que se note más: en un protocolo de treinta columnas, una línea de
   otro grosor cada pocas filas se lee como un error de impresión.

   El `margin-top` negativo es lo que de verdad lo consigue. Cuando encima hay
   una fila de celdas, esa fila ya pinta su borde inferior de 1 px y el de la
   sección caía justo debajo: dos líneas de 1 px pegadas, o sea una de 2 px.
   Pasaba en dos de las cuatro separaciones —identificación/cuerpo y
   observaciones/firmas— y no en las otras dos, así que la hoja salía con
   líneas de dos grosores sin un criterio que lo explicara. Subiendo la
   sección un píxel, las dos se superponen y queda una sola.
   (El trazo se declaró un tiempo en 1,6 px para que se notara más: no servía
   de nada, porque el navegador redondea el ancho de un borde a píxeles
   enteros y lo pintaba igual a 1 px. La diferencia que se veía era esta.) */
.pr-sec{border-top:1px solid #000;margin-top:-1px}
.pr-sec:first-child{border-top:0;margin-top:0}

/* ── Filas de campos: etiqueta sombreada a la izquierda, valor al lado ──
   Se maquetan con tabla, no con CSS Grid: los generadores de PDF suelen no
   soportar grid y la hoja se desarma. Además la tabla iguala la altura de
   todas las celdas de una fila, que es como se lee un formato en papel. */
table.pr-fila{width:100%;border-collapse:collapse;table-layout:fixed;
  border-left:1px solid #000;border-right:1px solid #000}
table.pr-fila td{border-bottom:1px solid #000;border-right:1px solid #000;
  vertical-align:top;word-break:break-word;padding:3.5px 6px}
table.pr-fila td:last-child{border-right:0}
table.pr-fila td.k{background:#EDEFF2;font:600 6.8pt/1.32 var(--f-ui);
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink)}
table.pr-fila td.v{font:500 9pt/1.42 var(--f-mo);color:#000;height:16pt}
table.pr-fila td.k.alto,table.pr-fila td.v.alto{height:42pt}
table.pr-fila td.v.alto{font-family:var(--f-tx);font-size:8.5pt}

/* Hoja llenable en pantalla: dentro de las celdas del papel van los controles
   del formulario. La etiqueta del control se oculta porque ya la pone la celda
   de su izquierda, y el envoltorio de columna se neutraliza para que no imponga
   el ancho de la rejilla dentro de la tabla. */
.pr-doc .pr-fila td.v .fs-lbl{display:none}
.pr-doc .pr-fila td.v .fs-col{width:auto!important;max-width:none!important;
  padding:0!important;margin:0!important;height:auto!important}
.pr-doc .pr-fila td.v .fs-in{width:100%;font-size:8.5pt;padding:1px 3px}
.pr-doc .pr-fila td.v .fs-unidad{display:flex;gap:4px;align-items:center}
.pr-doc .pr-fila td.v .fs-conf{margin:0}

/* Menú del botón derecho del editor de plantillas: las mismas acciones que la
   barra, donde está el cursor. */
.pe-menu{position:fixed;z-index:60;min-width:240px;padding:5px;background:#fff;
  border:1px solid var(--lin);border-radius:10px;box-shadow:0 12px 32px rgba(16,32,48,.18);
  font:500 13.5px/1 var(--f-ui)}
.pe-menu[hidden]{display:none}
.pe-menu button{display:flex;align-items:center;justify-content:space-between;gap:18px;
  width:100%;padding:7px 10px;border:0;border-radius:7px;background:none;
  font:inherit;color:var(--ink);text-align:left;cursor:pointer}
.pe-menu button:hover{background:var(--bg-2,#F1F4F8)}
.pe-menu button span{color:var(--mut);font-size:11.5px}
.pe-menu .sep{height:1px;margin:5px 8px;background:var(--lin)}

/* Conformidad: se lee de un vistazo, sin depender solo del color */
table.pr-fila td.v.cf{font-weight:700;text-align:center;letter-spacing:.06em}
table.pr-fila td.v.cf.ok{color:#0A5C36}
table.pr-fila td.v.cf.no{color:#9E1F17}
table.pr-fila td.v.cf.na{color:#555}

/* ── Bandas de sección ─────────────────────────────────────────────── */
.pr-banda{border:1px solid #000;border-top:0;margin-top:-1px;background:var(--ink);color:#fff;
  padding:4px 9px;font:700 8.5pt/1.3 var(--f-ui);letter-spacing:.14em;text-transform:uppercase}
.pr-banda.sub{background:#DDE1E7;color:var(--ink);font-size:8pt;letter-spacing:.1em;
  text-align:center;border-bottom:0}
.pr-nota{border:1px solid #000;border-top:0;padding:4px 9px;
  font:400 8pt/1.45 var(--f-tx);color:#222;background:#FCFCFD}
.pr-nota b{font-weight:700}

/* ── Tablas: listas de verificación, mediciones, matriz de ensayos ─── */
table.pr-tabla{width:100%;border-collapse:collapse;border:1px solid #000;border-top:0}
table.pr-tabla th{background:#EDEFF2;border:1px solid #000;padding:4px 5px;
  font:700 7pt/1.25 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink);text-align:center}
table.pr-tabla th small{display:block;font-weight:500;letter-spacing:0;color:#555}
table.pr-tabla td{border:1px solid #000;padding:3px 5px;text-align:center;
  font:500 8pt/1.35 var(--f-mo);color:#000;min-height:13pt}
table.pr-tabla td.n{width:26px;font-weight:700}
table.pr-tabla td.d,table.pr-tabla th.d{text-align:left;font-family:var(--f-tx);font-size:8.5pt}
table.pr-tabla td.o,table.pr-tabla th.o{text-align:left;font-family:var(--f-tx);font-size:8pt;width:22%}
table.pr-tabla th.r,table.pr-tabla td.r{width:78px}
table.pr-tabla td.cf{font-weight:700;font-size:9.5pt}
table.pr-tabla td.cf.ok{color:#0A5C36} table.pr-tabla td.cf.no{color:#9E1F17} table.pr-tabla td.cf.na{color:#666;font-size:7.5pt}
table.pr-tabla small.ref{color:#666;font-family:var(--f-mo);font-size:7pt}
table.pr-tabla tbody tr:nth-child(even) td{background:#FAFBFC}
.pr-firmas{border:1px solid #000;font-size:0;display:table;width:100%;table-layout:fixed}
.pr-firma{display:table-cell;vertical-align:bottom;padding:6px 9px 5px;
  border-right:1px solid #999;height:74px;font-size:medium}
.pr-firma:last-child{border-right:0}
.pr-firma .rol{font:600 6.5pt/1.3 var(--f-ui);letter-spacing:.14em;text-transform:uppercase;color:#555}
.pr-firma .sp{min-height:30px;padding-bottom:2px}
.pr-firma img{max-height:34px;width:auto}
.pr-firma .ln{border-top:1px solid #000;padding-top:2px;font:500 7.5pt/1.35 var(--f-mo)}
.pr-pie{
  display:flex;justify-content:space-between;font:500 6.5pt/1.4 var(--f-mo);color:#666;
  padding:3px 2px;border-top:1px solid #999;margin-top:4px;
}

/* ═════════════════════════════════════════════════════════════════
   AÑADIDOS: rejillas de dos columnas, minigráfico de barras,
   matriz del plan de calidad y variantes de KPI
   ═════════════════════════════════════════════════════════════════ */

.cols2{display:grid;grid-template-columns:1.55fr 1fr;gap:16px;align-items:start}
.cols3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;align-items:start}
/* Sin esto una columna no baja de lo que mide su contenido más ancho (una
   tabla, un campo largo) y en el teléfono empuja la página hacia la derecha. */
.cols2>*,.cols3>*{min-width:0}
@media (max-width:1080px){.cols2,.cols3{grid-template-columns:1fr}}

/* Minigráfico de barras: avance diario, tendencias cortas */
.spark{display:flex;align-items:flex-end;gap:3px;height:74px;
  padding:6px 0;border-bottom:1px solid var(--line)}
.spark-b{flex:1;min-width:5px;background:var(--brand);border-radius:2px 2px 0 0;
  opacity:.85;transition:opacity var(--mov)}
.spark-b:hover{opacity:1;background:var(--brand-d)}

/* El indicador principal es la misma tarjeta que los demás: se distingue por
   el dato, no por el relleno. Antes iba con un degradado azul oscuro y hacía
   que las cuatro tarjetas de la fila parecieran de sistemas distintos. */
.kpi.brand .v{color:var(--brand)}
.kpi.brand .bar>i{background:var(--brand)}

/* Matriz del plan: cabeceras verticales y primera columna fija */
.tbl.matriz th.vert{height:120px;vertical-align:bottom;padding:6px 2px;width:34px;min-width:34px}
.tbl.matriz th.vert span{display:block;writing-mode:vertical-rl;transform:rotate(180deg);
  font:600 10px/1 var(--f-mo);letter-spacing:.06em;white-space:nowrap;color:var(--t3)}
.tbl.matriz td{padding:5px 4px}
.tbl.matriz input[type=checkbox]{width:15px;height:15px;accent-color:var(--brand);cursor:pointer}
.tbl.matriz tbody tr:hover td{background:var(--paper-2)}

/* Fichas de junta soldada: estado a golpe de vista */
/* El estado de una junta es la misma píldora que el estado de un registro:
   un solo lenguaje de estados en todo el sistema. */
.j-estado{display:inline-flex;align-items:center;gap:6px;font:600 11px/1.45 var(--f-tx);
  letter-spacing:0;text-transform:none;padding:4px 10px;border-radius:var(--r-pill);
  border:0;background:var(--idle-bg);color:var(--idle-tx);white-space:nowrap}
.j-estado::before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.85;flex:none}
.j-estado.ARMADO{background:var(--idle-bg);color:var(--idle-tx)}
.j-estado.SOLDADO{background:var(--warn-bg);color:var(--warn-tx)}
.j-estado.EN_END{background:var(--hold-bg);color:var(--hold)}
.j-estado.APROBADA{background:var(--ok-bg);color:var(--ok)}
.j-estado.RECHAZADA,.j-estado.CORTADA{background:var(--stop-bg);color:var(--stop)}
.j-estado.REPARADA{background:var(--warn-bg);color:var(--warn-tx)}

/* Celdas de resultado de ensayo dentro de la tabla de juntas */
.end-c{display:inline-block;width:28px;text-align:center;font:600 10px/18px var(--f-mo);
  border-radius:var(--r);border:1px solid var(--line-2);color:var(--t3)}
.end-c.ACEPTABLE{background:color-mix(in srgb,var(--ok) 14%,transparent);border-color:var(--ok);color:var(--ok)}
.end-c.RECHAZADO{background:color-mix(in srgb,var(--stop) 14%,transparent);border-color:var(--stop);color:var(--stop)}
.end-c.PENDIENTE{background:color-mix(in srgb,var(--hold) 12%,transparent);border-color:var(--hold);color:var(--hold)}
.end-c.NA{opacity:.4}

/* ═════════════════════════════════════════════════════════════════
   MAQUETA FIEL · la tabla del documento original
   Se usa igual en pantalla, al llenar y al imprimir: lo que el
   inspector ve es exactamente lo que se firma en papel.
   ═════════════════════════════════════════════════════════════════ */

.xt-wrap{overflow-x:auto;background:#fff;border:1px solid var(--line-2);border-radius:var(--r);padding:10px}
table.xt{width:100%;border-collapse:collapse;table-layout:fixed;
  font:400 9pt/1.35 var(--f-tx);color:#111;background:#fff}
table.xt td,table.xt th{border:1px solid #000;padding:3px 5px;
  vertical-align:middle;word-break:break-word;overflow-wrap:anywhere;min-height:15pt}
/* Imágenes dentro de la tabla: logos y sellos. Nunca desbordan su celda. */
table.xt img{max-width:100%;height:auto;vertical-align:middle;display:inline-block}
table.xt td.lbl{background:#EDEFF2;font:600 8pt/1.3 var(--f-ui);
  letter-spacing:.04em;color:var(--ink)}

/* Celdas de dato: se ven llenables sin gritar */
table.xt td.inp{background:#FBFCFE;font-family:var(--f-mo);font-size:8.5pt}
table.xt td.inp.lleno{background:#fff;color:#000}
table.xt td.inp[contenteditable="true"]{cursor:text;background:#F4F8FB;
  box-shadow:inset 0 0 0 1px var(--brand-m)}
table.xt td.inp[contenteditable="true"]:hover{background:#EAF2F7}
table.xt td.inp[contenteditable="true"]:focus{outline:2px solid var(--brand);
  outline-offset:-2px;background:#FFFDF0}
table.xt td.inp.lleno[contenteditable="true"]{background:#fff}

@media print{
  .xt-wrap{overflow:visible;border:0;padding:0;background:none}
  table.xt{font-size:8pt}
  table.xt td,table.xt th{border:1px solid #000;padding:2.5px 4px}
  table.xt td.inp{background:transparent!important;box-shadow:none!important}
  table.xt tr{page-break-inside:avoid}
  table.xt img{max-width:100%;height:auto}
}
table.xt tr.aire td{height:5pt;padding:0;background:#fff;border-left:1px solid #000;border-right:1px solid #000}

/* ═════════════════════════════════════════════════════════════════
   EDITOR DE PLANTILLAS · panel de herramientas + lienzo WYSIWYG
   Se edita la propia tabla del formato: lo que ves aquí es lo que
   se imprime y lo que el inspector llenará en obra.
   ═════════════════════════════════════════════════════════════════ */

.pe{display:flex;gap:0;height:calc(100vh - var(--top) - 28px);
  border:1px solid var(--line-2);border-radius:var(--r);overflow:hidden;background:var(--paper)}

.pe-panel{width:296px;flex:none;overflow-y:auto;padding:12px 13px 30px;
  background:var(--paper-2);border-right:1px solid var(--line-2)}
.pe-panel h6{font:700 9.5px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;
  color:var(--t3);margin:0 0 7px}
.pe-panel hr{border:0;border-top:1px solid var(--line);margin:13px 0 11px}
.pe-g{margin-bottom:7px}
.pe-g label{display:block;font:600 9.5px/1.3 var(--f-ui);letter-spacing:.08em;
  text-transform:uppercase;color:var(--t3);margin-bottom:2px}
.pe-g .in{height:27px;font-size:12px;padding:3px 6px}
.pe-g textarea.in{height:auto}
.pe-2{display:grid;grid-template-columns:1fr 1fr;gap:7px}
.pe-3{display:grid;grid-template-columns:1fr 1fr 42px;gap:4px;margin-bottom:6px}
.pe-3 .in{height:26px;font-size:11px;padding:2px 4px}
.pe-t{display:block;font:600 9.5px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;
  color:var(--t3);margin:11px 0 4px}
.pe-fila{display:flex;align-items:center;gap:4px;flex-wrap:wrap}

.pe-grp{display:flex;gap:3px;margin-bottom:5px;flex-wrap:wrap}
.pe-b{flex:1 1 auto;min-width:30px;min-height:27px;padding:4px 6px;cursor:pointer;
  font:600 11px/1.1 var(--f-ui);border:1px solid var(--line-2);border-radius:var(--r);
  background:var(--paper);color:var(--t2);transition:background var(--mov),border-color var(--mov),color var(--mov)}
.pe-b:hover:not(:disabled){background:var(--brand-l);border-color:var(--brand-m);color:var(--brand-d)}
.pe-b:disabled{opacity:.4;cursor:default}
.pe-b.w{flex:1 1 100%;margin-bottom:5px}
.pe-b.on{background:var(--brand);border-color:var(--brand);color:#fff}
.pe-b.dg:hover{background:var(--stop-bg);border-color:var(--stop-br);color:var(--stop)}
.pe-b.sw{flex:1 1 0;min-width:0;font-size:10px;color:var(--t3)}

.pe-info{font:500 10.5px/1.45 var(--f-tx);color:var(--t2);background:var(--paper);
  border:1px solid var(--line);border-radius:var(--r);padding:5px 7px;margin:7px 0}
.pe-firma{display:flex;gap:3px;margin-bottom:4px}
.pe-firma .in{height:26px;font-size:11.5px;padding:3px 6px}
.pe-firma .pe-b{flex:0 0 28px;min-width:28px}

.pe-lienzo{flex:1;display:flex;flex-direction:column;min-width:0;background:var(--canvas);position:relative}
.pe-barra{display:flex;align-items:center;gap:7px;padding:7px 12px;
  background:var(--paper);border-bottom:1px solid var(--line-2);flex:none}

/* Fila de formato del editor. Va integrada debajo de la barra de la plantilla,
   en su propia franja: flotando por encima tapaba «Vista de impresión» y
   «Guardar», que es justo lo que se pulsa al terminar de armar el formato. */
.pe-flota{display:flex;align-items:center;gap:4px;padding:5px 10px;
  overflow-x:auto;flex:none;
  background:var(--paper);border-bottom:1px solid var(--line-2)}
.pe-flota .pe-b{min-width:26px;padding:3px 6px;font-size:11px}
.pe-flota select.in{height:26px;font-size:11.5px;padding:2px 4px;width:auto}
.pe-flota input[type=color]{width:30px;height:26px;padding:1px;border:1px solid var(--line);
  border-radius:6px;background:var(--paper);cursor:pointer}
.pe-fl-l{display:flex;align-items:center;gap:4px;font:600 10px/1 var(--f-ui);color:var(--t3)}
.pe-fl-sep{width:1px;height:20px;background:var(--line);flex:none}
.pe-fl-celda{font:600 10.5px/1 monospace;color:var(--t2);min-width:36px;text-align:center}
.pe-scroll{flex:1;overflow:auto;padding:18px}
.pe-zoom{display:flex;align-items:center;gap:5px;font:600 10px/1 var(--f-ui);
  letter-spacing:.1em;text-transform:uppercase;color:var(--t3)}
.pe-zoom select{height:26px;font-size:11.5px;padding:2px 4px}
.pe-hoja-wrap{transform-origin:top center;transition:transform var(--mov-2)}
/* La hoja es A4 y no se mueve de ahí. Si el formato importado trae muchas
   columnas, es la tabla la que se ajusta: el papel no crece. */
.pe-hoja{width:210mm;max-width:100%;margin:0 auto;background:#fff;box-shadow:var(--sh-2);
  border-radius:var(--r);padding:10mm;min-height:260mm;box-sizing:border-box}
.pe-hoja.apaisada{width:297mm;min-height:180mm}
/* La tabla se reparte el ancho útil de la hoja, sin mínimos que la desborden */
.pe-hoja table.xt{width:100%;min-width:0;max-width:100%;table-layout:fixed}

/* Celdas del lienzo: la selección se ve, el foco de escritura también */
.pe-hoja table.xt td,.pe-hoja table.xt th{outline:none}
.pe-hoja table.xt td.sel,.pe-hoja table.xt th.sel{
  box-shadow:inset 0 0 0 2px var(--brand);background:var(--brand-l)!important}
.pe-hoja table.xt td.inp{background:#F4F8FB}
.pe-hoja table.xt td.inp::after{content:'';display:inline-block}
.pe-hoja table.xt td:focus{background:#FFFDF0!important}
.pe-hoja table.xt td.sel img{outline:2px solid var(--brand);outline-offset:1px}

/* El panel se estrecha antes de renunciar a tener el lienzo al lado: con el
   rail lateral ocupando 230px, apilar a 980px dejaba la hoja debajo en
   pantallas de portátil perfectamente normales. */
@media (max-width:1240px){ .pe-panel{width:262px;padding:10px 10px 26px} }
@media (max-width:1080px){
  .pe-panel{width:236px}
  .pe-b{font-size:10.5px;padding:4px 4px;min-width:26px}
  .pe-scroll{padding:12px}
}
/* Solo en pantallas de verdad estrechas (tabletas y móviles) se apila */
@media (max-width:720px){
  .pe{flex-direction:column;height:auto}
  .pe-panel{width:auto;border-right:0;border-bottom:1px solid var(--line-2)}
  .pe-hoja{padding:6mm;min-height:0}
}

/* ═════════════════════════════════════════════════════════════════
   DIÁLOGOS · avisos y confirmaciones del sistema
   Sustituyen a los del navegador: se leen en el móvil, se ven como
   parte del sistema y dejan claro qué se está confirmando.
   ═════════════════════════════════════════════════════════════════ */

.dlg-ov{position:fixed;inset:0;z-index:120;display:flex;align-items:center;justify-content:center;
  padding:20px;background:rgba(13,17,23,.52);backdrop-filter:blur(2px);
  opacity:0;pointer-events:none;transition:opacity var(--mov)}
.dlg-ov.on{opacity:1;pointer-events:auto}

.dlg{display:grid;grid-template-columns:auto 1fr;gap:0 14px;width:100%;max-width:452px;
  background:var(--paper);border-radius:var(--r-lg);box-shadow:0 18px 48px rgba(13,17,23,.3);
  padding:20px 22px 16px;transform:translateY(6px) scale(.985);transition:transform var(--mov-2)}
.dlg-ov.on .dlg{transform:none}

.dlg-i{grid-row:1;display:grid;place-items:center;width:38px;height:38px;border-radius:50%;
  background:var(--brand-l);color:var(--brand-d)}
.dlg-peligro .dlg-i{background:var(--stop-bg);color:var(--stop)}
.dlg-ok      .dlg-i{background:var(--ok-bg);color:var(--ok)}
.dlg-aviso   .dlg-i{background:var(--warn-bg);color:var(--warn)}

.dlg-c{grid-row:1;min-width:0}
.dlg-c h3{font:600 15.5px/1.35 var(--f-ui);letter-spacing:.01em;color:var(--t1);margin:5px 0 0}
.dlg-c p{font:400 13.5px/1.55 var(--f-tx);color:var(--t2);margin:6px 0 0;white-space:pre-line}
.dlg-in{margin-top:11px;width:100%}
.dlg-e{margin-top:6px;font:500 12px/1.4 var(--f-tx);color:var(--stop)}

.dlg-b{grid-column:1/-1;display:flex;justify-content:flex-end;gap:7px;margin-top:17px}

@media (max-width:520px){
  .dlg{grid-template-columns:1fr;gap:10px;max-width:none;padding:18px}
  .dlg-i{grid-row:auto}
  .dlg-c{grid-row:auto}
  .dlg-b{flex-direction:column-reverse}
  .dlg-b .btn{width:100%;justify-content:center}
}

/* Firmas escritas dentro del cuadro que trae el propio formato */
table.xt .fv{font-family:var(--f-mo);font-weight:500}
table.xt img.fx{max-height:44px;width:auto;vertical-align:bottom;display:inline-block}
@media print{ table.xt img.fx{max-height:40px} }

/* ═════════════════════════════════════════════════════════════════
   CAMPANA DE ALERTAS
   Un solo sitio donde mirar qué está detenido: lo que le toca a uno,
   y dónde se ha parado el circuito aunque le toque a otro.
   ═════════════════════════════════════════════════════════════════ */

.campana-wrap{position:relative;flex:none}
.campana{position:relative;display:grid;place-items:center;width:36px;height:36px;
  border:1px solid var(--line-2);border-radius:var(--r-lg);background:var(--paper);
  color:var(--t2);cursor:pointer;transition:background var(--mov),color var(--mov),border-color var(--mov)}
.campana:hover{background:var(--paper-2);color:var(--t1)}
.campana[aria-expanded="true"]{background:var(--brand-l);border-color:var(--brand-m);color:var(--brand-d)}
.campana .n{position:absolute;top:-6px;right:-6px;min-width:18px;height:18px;padding:0 4px;
  display:grid;place-items:center;border-radius:var(--r-lg);background:var(--t3);color:#fff;
  font:700 10px/1 var(--f-mo);border:2px solid var(--paper)}
.campana.urge .n{background:var(--stop)}
.campana.urge{border-color:var(--stop-br);color:var(--stop)}

.alertas{position:absolute;top:calc(100% + 8px);right:0;width:394px;max-width:calc(100vw - 24px);
  max-height:min(70vh,560px);overflow-y:auto;z-index:90;
  background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r-lg);
  box-shadow:0 14px 40px rgba(13,17,23,.18)}
.alertas[hidden]{display:none}
.alertas-h{position:sticky;top:0;display:flex;align-items:center;gap:8px;
  padding:11px 14px;background:var(--paper);border-bottom:1px solid var(--line);
  font:600 13px/1 var(--f-ui);color:var(--t1);z-index:1}

.alertas-v{padding:30px 20px;text-align:center;color:var(--t3)}
.alertas-v p{margin-top:8px;font:400 13px/1.5 var(--f-tx)}

.alertas-g{border-bottom:1px solid var(--line)}
.alertas-g:last-child{border-bottom:0}
.alertas-g .g-h{display:flex;align-items:center;gap:7px;padding:10px 14px 2px;
  font:600 11.5px/1 var(--f-ui);letter-spacing:.04em;color:var(--t1)}
.alertas-g .g-h .n{margin-left:auto;min-width:20px;padding:2px 6px;border-radius:var(--r-pill);
  background:var(--paper-2);color:var(--t2);font:700 10.5px/1.4 var(--f-mo)}
.alertas-g .g-a{padding:0 14px 7px;font:400 11px/1.45 var(--f-tx);color:var(--t3)}

.alertas-g .g-i{display:block;padding:7px 14px;text-decoration:none;
  border-left:3px solid transparent;transition:background var(--mov),border-color var(--mov)}
.alertas-g .g-i:hover{background:var(--paper-2);border-left-color:var(--brand)}
.alertas-g .g-i .c{display:inline-block;font:600 11px/1.3 var(--f-mo);color:var(--brand-d)}
.alertas-g .g-i .t{display:block;font:500 12px/1.4 var(--f-tx);color:var(--t1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.alertas-g .g-i .d{display:block;font:400 10.5px/1.4 var(--f-tx);color:var(--t3)}
.alertas-g .g-v{display:block;padding:8px 14px;text-align:center;text-decoration:none;
  font:600 11px/1 var(--f-ui);color:var(--brand-d);background:var(--paper-2)}
.alertas-g .g-v:hover{background:var(--brand-l)}

.dot-stop{background:var(--stop)} .dot-warn{background:var(--warn)}
.dot-hold{background:var(--hold)} .dot-ok{background:var(--ok)}

@media (max-width:560px){
  .alertas{position:fixed;top:calc(var(--top) + 6px);right:8px;left:8px;width:auto}
}

/* ═════════════════════════════════════════════════════════════════
   BUSCADOR GENERAL
   Una sola caja para llegar a cualquier cosa del proyecto por su
   código, que es lo que la gente tiene delante en el papel.
   ═════════════════════════════════════════════════════════════════ */

.buscador{position:relative;display:flex;align-items:center;gap:7px;flex:none;
  width:min(340px,32vw);height:36px;padding:0 9px;
  border:1px solid var(--line-2);border-radius:var(--r-lg);background:var(--paper);
  color:var(--t3);transition:border-color var(--mov),box-shadow var(--mov)}
.buscador:focus-within{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-l)}
.buscador input{flex:1;min-width:0;border:0;outline:0;background:none;
  font:400 13px/1 var(--f-tx);color:var(--t1)}
.buscador input::placeholder{color:var(--t3)}
.buscador input::-webkit-search-cancel-button{display:none}
.buscador kbd{flex:none;padding:2px 6px;border:1px solid var(--line-2);border-radius:var(--r);
  background:var(--paper-2);font:600 10px/1.3 var(--f-mo);color:var(--t3)}
.buscador:focus-within kbd{display:none}

.buscador-r{position:absolute;top:calc(100% + 7px);left:0;right:0;min-width:340px;
  max-height:min(66vh,520px);overflow-y:auto;z-index:95;
  background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r-lg);
  box-shadow:0 14px 40px rgba(13,17,23,.18)}
.buscador-r[hidden]{display:none}

.buscador-r .b-g{padding:8px 13px 3px;font:700 9.5px/1 var(--f-ui);letter-spacing:.14em;
  text-transform:uppercase;color:var(--t3);display:flex;align-items:center;gap:6px;
  border-top:1px solid var(--line)}
.buscador-r .b-g:first-child{border-top:0}
.buscador-r a{display:block;padding:7px 13px;text-decoration:none;
  border-left:3px solid transparent}
.buscador-r a:hover,.buscador-r a.sel{background:var(--paper-2);border-left-color:var(--brand)}
.buscador-r a .t{display:block;font:600 12.5px/1.35 var(--f-mo);color:var(--brand-d)}
.buscador-r a .s{display:block;font:400 12px/1.4 var(--f-tx);color:var(--t1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.buscador-r a .e{display:block;font:400 10.5px/1.4 var(--f-tx);color:var(--t3)}
.buscador-r a mark{background:var(--warn-bg);color:inherit;padding:0 1px;border-radius:var(--r)}
.buscador-r .b-v{padding:16px 14px;text-align:center;font:400 12.5px/1.5 var(--f-tx);color:var(--t3)}

@media (max-width:1100px){ .buscador{width:210px} .buscador kbd{display:none} }
@media (max-width:760px){
  .buscador{width:38px;padding:0 8px}
  .buscador input{width:0;padding:0}
  .buscador:focus-within{width:min(300px,60vw);padding:0 9px}
  .buscador:focus-within input{width:auto}
  .buscador-r{right:auto;left:0;width:min(340px,84vw)}
}

/* ═════════════════════════════════════════════════════════════════
   PIPER · la mascota
   Las poses se cruzan con un fundido entre capas superpuestas. Cambiar
   el src de una sola imagen dejaría un parpadeo en blanco mientras
   carga la siguiente, y con ocho poses se nota.
   ═════════════════════════════════════════════════════════════════ */

/* Por debajo de los modales (.ov está en 90): la mascota salía encima del
   diálogo de firma y tapaba sus botones.

   Apoyada en el borde de abajo, no flotando. El dibujo ya trae 8 px
   transparentes bajo los pies —unos 5 una vez escalado a la caja—, así que con
   los 12 px de antes las botas quedaban a 17 del canto y Piper parecía
   suspendido en el aire en vez de de pie en la esquina. Todo lo suyo —el globo
   y el panel del chat— va posicionado DENTRO de esta caja, así que baja con
   ella sin tocar nada más. */
.ia{position:fixed;right:14px;bottom:0;z-index:80;display:flex;align-items:flex-end}
.ia[hidden]{display:none}

/* Pestaña lateral cuando está oculta: asoma media cabeza */
.ia-tab{position:fixed;right:0;bottom:74px;width:46px;height:52px;padding:0 0 0 4px;
  display:none;place-items:center;cursor:pointer;
  border:1px solid var(--line-2);border-right:0;border-radius:10px 0 0 10px;
  background:var(--paper);box-shadow:-2px 2px 12px rgba(13,17,23,.14);
  transition:width var(--mov-2),background var(--mov)}
.ia-tab img{width:38px;height:38px;object-fit:contain}
.ia-tab:hover{width:54px;background:var(--brand-l)}
.ia[data-estado="oculto"] .ia-tab{display:grid}
.ia[data-estado="oculto"] .ia-fab,
.ia[data-estado="oculto"] .ia-panel,
.ia[data-estado="oculto"] .ia-globo{display:none}

/* La mascota. Más pequeña que antes (118 px) porque su caja es un botón: lo
   que quedaba debajo no solo se tapaba, tampoco se podía pulsar, y en las
   pantallas de tabla caía justo sobre las últimas filas.

   La caja sigue la proporción del dibujo. El pingüino mide 234×229 —casi
   cuadrado— donde la figura anterior medía 205×340. Con la caja alta de antes,
   `object-fit:contain` no lo deformaba pero lo dejaba flotando en el centro de
   un hueco vertical: ocupaba el mismo sitio en la pantalla y se veía más
   pequeño, y la burbuja y el panel quedaban descolgados de su cabeza. */
/* Tamaño: 140×138. Piper se pidió «un 30 o 40 % más grande» que los 104×102
   con los que entró, que eran los de la figura anterior traducidos a su
   proporción. Es también el tamaño con el que vive en Precom. */
.ia-fab{position:relative;width:140px;height:138px;padding:0;border:0;background:none;cursor:pointer;
  filter:drop-shadow(0 6px 14px rgba(13,17,23,.28))}
.ia-fab:hover{transform:translateY(-2px)}
.ia-fab{transition:transform var(--mov-2)}
.ia-stage{position:absolute;top:0;right:0;bottom:0;left:0;display:block}
.ia-capa{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:contain;
  pointer-events:none;user-select:none;transition:opacity .45s ease-in-out}
.ia-capa.on{opacity:1}
/* El parpadeo y el gesto no se funden: son fotogramas, se cambian en seco.
   Y mientras corren, tampoco se funde la pose que hay debajo: si no, se ve
   asomar a medio desvanecer y parece que la mascota destella. */
.ia-blink,.ia-gesto{transition:none}
.ia-stage.ia-fotogramas .ia-capa{transition:none}

.ia-badge{position:absolute;top:4px;right:6px;min-width:20px;height:20px;padding:0 5px;
  display:grid;place-items:center;border-radius:var(--r-lg);background:var(--stop);color:#fff;
  font:700 11px/1 var(--f-mo);border:2px solid var(--paper)}
.ia-badge[hidden]{display:none}

/* Burbuja */
/* El globo se coloca contra el BORDE IZQUIERDO de la mascota, no a tantos
   píxeles del derecho. Medido desde la derecha, la caja absoluta solo podía
   crecer hasta el ancho que le quedaba dentro del contenedor —que mide lo que
   la figura— y se quedaba en 70 px: «Hola, Quique. Soy Piper.» salía en cuatro
   renglones de dos palabras. Con `right:100%` el globo empieza donde acaba el
   contenedor y crece hacia la izquierda, que es sitio libre. */
.ia-globo{position:absolute;right:calc(100% - 8px);bottom:86px;
  width:max-content;max-width:230px;padding:9px 12px;
  background:var(--paper);border:1px solid var(--line-2);border-radius:12px 12px 2px 12px;
  box-shadow:var(--sh-2);font:400 12.5px/1.45 var(--f-tx);color:var(--t1);
  animation:iaGlobo .25s ease-out}
.ia-globo[hidden]{display:none}
@keyframes iaGlobo{from{opacity:0;transform:translateY(6px) scale(.96)}to{opacity:1;transform:none}}

/* Panel */
/* Baja con la mascota, pero no se apoya en el canto como ella: con el panel a
   ras, el campo de escribir y el botón de enviar quedaban pegados al borde de
   la ventana y la sombra se cortaba. Ocho píxeles bastan. */
.ia-panel{position:absolute;right:154px;bottom:8px;width:378px;max-width:calc(100vw - 30px);
  height:min(560px,calc(100vh - 90px));display:flex;flex-direction:column;overflow:hidden;
  background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r-lg);
  box-shadow:0 16px 46px rgba(13,17,23,.24)}
.ia-panel[hidden]{display:none}

.ia-cab{display:flex;align-items:center;gap:10px;padding:9px 11px;flex:none;
  background:var(--ink);color:#fff}
.ia-cab img{width:36px;height:36px;object-fit:contain;flex:none}
.ia-cab .ia-t b{display:block;font:600 13.5px/1.15 var(--f-ui);letter-spacing:.02em}
.ia-cab .ia-t small{display:block;margin-top:2px;font:400 10.5px/1.3 var(--f-tx);color:#A9BBD1}
.ia-x{width:25px;height:25px;flex:none;border:0;border-radius:50%;cursor:pointer;
  background:rgba(255,255,255,.14);color:#fff;font-size:12px;line-height:1}
.ia-x:hover{background:rgba(255,255,255,.26)}

/* Nota al pie de una burbuja: hoy, el aviso de que eso lo contestó la IA y
   no los datos del proyecto. Va dentro de la burbuja y no suelta al final del
   hilo, para que no se despegue del texto al que acompaña. */
.ia-nota{display:block;margin-top:7px;padding-top:6px;border-top:1px solid var(--line);
  font:400 10.5px/1.4 var(--f-tx);color:var(--t3)}

.ia-msgs{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:9px;
  background:var(--paper-2)}
.ia-b{max-width:88%;padding:8px 11px;border-radius:var(--r-lg);font:400 12.5px/1.5 var(--f-tx);
  white-space:pre-line;overflow-wrap:anywhere}
.ia-b.bot{align-self:flex-start;background:var(--paper);border:1px solid var(--line);
  color:var(--t1);border-bottom-left-radius:3px}
.ia-b.yo{align-self:flex-end;background:var(--brand);color:#fff;border-bottom-right-radius:3px}
.ia-b b{font-weight:600}
.ia-b.pensando{color:var(--t3)}

.ia-item{display:block;padding:7px 10px;margin-top:5px;text-decoration:none;
  background:var(--paper);border:1px solid var(--line);border-left:3px solid var(--brand);
  border-radius:var(--r)}
.ia-item:hover{background:var(--brand-l)}
.ia-item .c{display:block;font:600 11.5px/1.3 var(--f-mo);color:var(--brand-d)}
.ia-item .s{display:block;font:400 11.5px/1.35 var(--f-tx);color:var(--t1)}
.ia-item .e{display:block;font:400 10px/1.3 var(--f-tx);color:var(--t3)}

.ia-sug{display:flex;flex-wrap:wrap;gap:5px;padding:8px 11px;flex:none;
  border-top:1px solid var(--line);background:var(--paper);max-height:96px;overflow-y:auto}
.ia-sug button{padding:5px 9px;border:1px solid var(--line-2);border-radius:var(--r-pill);cursor:pointer;
  background:var(--paper);color:var(--t2);font:500 11px/1.2 var(--f-tx)}
.ia-sug button:hover{background:var(--brand-l);border-color:var(--brand-m);color:var(--brand-d)}

.ia-input{display:flex;gap:7px;padding:9px 11px;flex:none;border-top:1px solid var(--line)}
.ia-input input{flex:1;min-width:0;height:34px;padding:0 12px;border:1px solid var(--line-2);
  border-radius:var(--r-pill);font:400 12.5px/1 var(--f-tx);outline:0}
.ia-input input:focus{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-l)}
.ia-env{width:34px;height:34px;flex:none;border:0;border-radius:50%;cursor:pointer;
  background:var(--brand);color:#fff;font-size:13px}
.ia-env:hover{background:var(--brand-d)}
.ia-env:disabled{opacity:.5;cursor:default}

/* En pantallas pequeñas la mascota estorba: se queda solo la pestaña */
@media (max-width:720px){
  .ia-fab{width:124px;height:122px}
  .ia-panel{right:0;bottom:104px;width:calc(100vw - 24px)}
  .ia-globo{display:none!important}
}

/* Quien pide menos movimiento no recibe ni parpadeo ni gestos: la mascota
   sigue funcionando, simplemente se queda quieta. */
@media (prefers-reduced-motion:reduce){
  .ia-capa{transition:none}
  .ia-fab:hover{transform:none}
  .ia-globo{animation:none}
}

/* ═════════════════════════════════════════════════════════════════
   ADAPTACIÓN A PANTALLAS
   Cuatro tramos, por cómo se usa el sistema y no por el catálogo de
   dispositivos: escritorio, portátil, tableta y teléfono. En obra el
   teléfono es lo normal, así que ahí no vale con encoger: hay que
   cambiar la disposición.
   ═════════════════════════════════════════════════════════════════ */

/* ── Portátiles y monitores pequeños ──────────────────────────── */
@media (max-width:1280px){
  .main{padding:16px}
  .kpis{grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
}

/* ── Tabletas apaisadas ───────────────────────────────────────── */
@media (max-width:1024px){
  :root{--rail:200px}
  .main{padding:14px}
  .kpi .v{font-size:26px}
  .cols2,.cols3{grid-template-columns:1fr}
  .modal{max-width:calc(100vw - 28px)}
}

/* ── Tabletas verticales y por debajo ─────────────────────────── */
@media (max-width:860px){
  /* Las tablas de obra tienen hasta veinte columnas. En vez de
     apretarlas hasta lo ilegible, la tarjeta se desplaza a lo ancho y
     la tabla conserva su tamaño. */
  .card-b{overflow-x:auto;-webkit-overflow-scrolling:touch}

  /* La tabla deja de encogerse hasta lo ilegible: crece con su contenido
     y es la tarjeta la que se desplaza. Sin esto, una columna de título
     acaba partiendo el texto palabra por palabra, una por línea. */
  .tbl{font-size:12px;width:auto;min-width:100%}
  .tbl th,.tbl td{padding:7px 9px;white-space:nowrap}
  .tbl td .small,.tbl td .tiny{white-space:nowrap;
    max-width:230px;overflow:hidden;text-overflow:ellipsis;display:block}

  /* La última columna, cuando lo que lleva son los botones de la fila, se
     queda clavada al borde derecho mientras el resto se desplaza.
     Una tabla de veinte columnas que se desplaza es una decisión; que lo
     primero en salirse por la derecha sean «editar» y «borrar» no lo es: en
     un teléfono la pantalla no se leía peor, es que no se podía usar. Se
     distingue con :has() para no clavar una columna que lleve datos. */
  .tbl tbody tr{background:var(--paper)}
  .tbl tbody tr:nth-child(even){background:var(--paper-2)}
  .tbl tbody td:last-child:has(.btn,button,a){
    position:sticky;right:0;z-index:1;background:inherit;
    box-shadow:-7px 0 7px -7px rgba(16,32,52,.22);
  }
  /* La casilla de arriba de esa columna va vacía: se clava con ella para que
     no quede un hueco por el que asome la cabecera al desplazar. */
  .tbl thead th:last-child:empty{position:sticky;right:0;z-index:3;background:var(--canvas)}

  /* Un campo a media fila en un teléfono no cabe. Se fuerza porque el
     ancho va escrito en el propio elemento, no en la hoja. */
  .f-row>.f-g{grid-column:span 12!important}

  .filtros{padding:10px 12px}
  .filtros .f-g{min-width:0;flex:1 1 140px}
  .card-h{flex-wrap:wrap;row-gap:6px}
  .card-h h2,.card-h h3{width:100%}
  .btns{width:100%}
}

/* ── Teléfonos ────────────────────────────────────────────────── */
@media (max-width:600px){
  .main{padding:10px}
  .card{margin-bottom:12px}
  .card-h{padding:10px 12px}
  .card-b{padding:12px}
  .kpis{grid-template-columns:repeat(2,1fr);gap:8px}
  .kpi{padding:11px 12px}
  .kpi .v{font-size:23px}
  .kpi .k{font-size:10.5px}

  /* Los botones a lo ancho: en el pulgar, un botón pequeño se falla */
  .modal-f{flex-direction:column-reverse;gap:7px}
  .modal-f .btn{width:100%;justify-content:center}
  /* Con «column-reverse» el orden se da la vuelta, y lo que el pie dice de lo
     elegido —«PR-CIV-010 · 27 campos»— acababa DEBAJO de los botones, leído
     después de decidir. Va arriba, que es donde se lee antes de pulsar. */
  .modal-f .hint{order:99;text-align:center}
  .modal-f .sp{display:none}
  .btn{min-height:38px}
  .btn-xs,.btn-sm{min-height:32px}

  /* Un modal de dos paneles, en un teléfono, va de uno en uno.
     «Importar de la biblioteca» salía en 390 px con la lista en 260 px y la
     vista previa estrujada a 42: ilegible la una e inservible la otra. Lleva
     «!important» a propósito —la rejilla va escrita en el propio elemento con
     «style=», y una regla de hoja no le gana— y es general: vale para
     cualquier modal que se arme en dos columnas. */
  .modal .cols2,
  .modal .cols3{grid-template-columns:1fr!important;gap:10px!important}

  /* Y una vez apilados, ningún panel se desplaza por su cuenta: manda el
     cuerpo del modal. Dos cajas que se desplazan, una dentro de otra, bajo un
     pulgar compiten, y la de dentro se traga el gesto de la de fuera. */
  .modal .cols2>*,
  .modal .cols3>*{max-height:none!important;overflow:visible!important}

  /* Una tabla con su propio desplazamiento vertical, dentro de una página que
     también se desplaza, es una trampa en un teléfono: la página parece
     terminada —queda hueco en blanco debajo de la tarjeta— y las últimas filas
     están dentro de una caja que hay que descubrir. En «Juntas» se recortaban
     las tres últimas de catorce.

     Manda la página. El desplazamiento a lo ANCHO se queda: ese es deliberado
     y ya tiene su columna de botones clavada. Lleva «!important» porque el
     alto va escrito en el propio elemento, con «style=». */
  .tbl-wrap{max-height:none!important}

  /* Apilada debajo de la lista, la vista previa vacía se come una pantalla
     entera para decir «elige una plantilla». No sale hasta que hay algo, y
     cuando sale va ARRIBA: debajo de una lista de veinte formatos hay que
     recorrerla entera para ver lo que se acaba de elegir. */
  #previaBiblio:not(.con-eleccion){display:none}
  #previaBiblio.con-eleccion{order:-1;max-height:46vh!important;overflow:auto!important}

  /* El título cede sitio: con «flex:none» uno largo empujaba la campana
     fuera de la pantalla y la página entera se desplazaba a lo ancho. */
  .topbar{gap:8px;padding:0 10px}
  .topbar h1{font-size:14px;flex:1 1 auto;min-width:0}
  .tabs{overflow-x:auto;flex-wrap:nowrap}
  .tabs .tab{flex:none}

  /* La hoja impresa no se encoge: se desplaza, para que el formato se
     siga viendo como es. */
  .xt-wrap{overflow-x:auto}
  .pe-hoja{padding:5mm}
}

/* ── Teléfonos estrechos ──────────────────────────────────────── */
@media (max-width:380px){
  .kpis{grid-template-columns:1fr}
  .main{padding:8px}
}

/* ── Pantallas muy anchas ─────────────────────────────────────── */
@media (min-width:1800px){
  /* Aquí había un segundo tope de 1720px que pisaba al de arriba justo en las
     pantallas grandes, que es donde más se notaba el hueco. Dos topes para lo
     mismo, y el más restrictivo ganaba: el contenido se quedaba corto por la
     derecha en cualquier monitor de 1900 o más. El ancho lo decide una sola
     regla; aquí solo se aprovecha el sitio para caber más indicadores. */
  .kpis{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
}

/* ── Táctil: nada depende de pasar el ratón por encima ─────────── */
@media (hover:none){
  .tbl tr[onclick]{cursor:pointer}
  .buscador kbd{display:none}
  /* El área de toque mínima recomendada es 44px; los iconos sueltos
     se quedaban muy por debajo. */
  .rail-a{padding-top:9px;padding-bottom:9px}
  .f-b,.pe-b,.ia-x{min-width:34px;min-height:34px}
}

/* ── Impresión: fuera todo lo que no es el documento ───────────── */
@media print{
  .rail,.topbar,.ia,.buscador,.campana-wrap,.toast,.btns,.filtros{display:none!important}
  .shell,.main{margin:0!important;padding:0!important;max-width:none!important}
  .card{border:0!important;box-shadow:none!important}
}

/* ═════════════════════════════════════════════════════════════════
   ASISTENTE DE IMPORTACIÓN DE ISOMÉTRICOS
   ═════════════════════════════════════════════════════════════════ */

.pasos{display:flex;align-items:center;gap:0;list-style:none;margin:0 0 16px;padding:0;flex-wrap:wrap}
.pasos>*{display:flex;align-items:center;gap:7px;padding:7px 13px;
  font:500 11.5px/1 var(--f-ui);color:var(--t3);white-space:nowrap}
.pasos>*+*::before{content:'→';margin-right:11px;color:var(--line-2)}
.pasos>* span{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;
  border:2px solid var(--line-2);background:var(--paper);font:700 10px/1 var(--f-mo);color:var(--t3)}
.pasos>*.on{color:var(--brand-d);font-weight:600}
.pasos>*.on span{border-color:var(--brand);background:var(--brand);color:#fff}
.pasos>*.hecho{color:var(--ok)}
.pasos>*.hecho span{border-color:var(--ok);background:var(--ok);color:#fff}

.soltar{display:grid;place-items:center;gap:8px;padding:34px 20px;text-align:center;
  border:2px dashed var(--line-2);border-radius:var(--r-lg);background:var(--paper-2);
  color:var(--t3);transition:background var(--mov),border-color var(--mov)}
.soltar.sobre{border-color:var(--brand);background:var(--brand-l)}
.soltar b{font:600 14px/1.3 var(--f-ui);color:var(--t1)}
.soltar p{max-width:420px;font:400 12px/1.5 var(--f-tx);color:var(--t3);margin:0}

/* Lo importado y el plano, uno al lado del otro */
/* El reparto lo define la regla del divisor, más abajo */
.rev{gap:14px}
.visor{display:flex;flex-direction:column;min-height:380px;
  border:1px solid var(--line-2);border-radius:var(--r);overflow:hidden;background:var(--canvas)}
.visor-h{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:7px 11px;background:var(--paper);border-bottom:1px solid var(--line);
  font:600 10px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t3)}
.visor-h a{font:500 10.5px/1 var(--f-tx);color:var(--brand-d);text-transform:none;letter-spacing:0}
.visor iframe,.visor embed{flex:1;width:100%;border:0;min-height:340px;background:#fff}

.rapido{padding:11px 13px;background:var(--brand-l);border-radius:var(--r)}
.rapido b{font:600 11px/1 var(--f-ui);color:var(--brand-d)}

@media (max-width:1024px){
  .rev{grid-template-columns:1fr}
  .visor{min-height:300px}
}
/* Dato leído del plano, en la pantalla de verificación */
.dato{padding:6px 9px;min-height:32px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--paper-2);font:500 12.5px/1.35 var(--f-tx);color:var(--t1);
  overflow-wrap:anywhere}
.dato.vacio{color:var(--t3);font-style:italic;font-weight:400}

/* ═════════════════════════════════════════════════════════════════
   VISOR DE PLANOS con marcas de junta
   ═════════════════════════════════════════════════════════════════ */

.plano{display:flex;flex-direction:column;min-height:0;
  border:1px solid var(--line-2);border-radius:var(--r);overflow:hidden;background:var(--canvas)}
.pl-barra{display:flex;align-items:center;gap:5px;padding:6px 9px;flex:none;
  background:var(--paper);border-bottom:1px solid var(--line)}
.pl-barra button{min-width:28px;height:26px;padding:0 8px;cursor:pointer;
  border:1px solid var(--line-2);border-radius:var(--r);background:var(--paper);
  color:var(--t2);font:600 12px/1 var(--f-ui)}
.pl-barra button:hover{background:var(--brand-l);border-color:var(--brand-m);color:var(--brand-d)}
.pl-zoom,.pl-pag{font:600 10.5px/1 var(--f-mo);color:var(--t3);min-width:56px;text-align:center}

.pl-scroll{flex:1;overflow:auto;position:relative;background:#EDEFF2;padding:12px;min-height:0}
.pl-hoja{position:relative;display:inline-block;background:#fff;box-shadow:var(--sh-2)}
.pl-hoja canvas{display:block}
.pl-marcas{position:absolute;top:0;left:0}
.pl-msg{position:absolute;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;
  background:#EDEFF2;color:var(--t3);font:400 13px/1.5 var(--f-tx)}

/* La marca es un punto pequeño que crece al pasar por encima: sobre un plano
   lleno de líneas, una marca grande tapa justo lo que se quiere leer. */
.pl-marca{position:absolute;transform:translate(-50%,-50%);width:17px;height:17px;padding:0;
  display:grid;place-items:center;cursor:pointer;border-radius:50%;
  border:2px solid #fff;background:var(--brand);color:#fff;
  box-shadow:0 0 0 1px rgba(0,0,0,.4),0 1px 3px rgba(0,0,0,.35);
  font:700 9px/1 var(--f-mo);transition:width var(--mov-2),height var(--mov-2),background var(--mov)}
.pl-marca span{pointer-events:none}
.pl-marca:hover{width:24px;height:24px;font-size:11px;z-index:9}
.pl-marca.on{background:var(--acento);width:26px;height:26px;font-size:11px;z-index:10;
  box-shadow:0 0 0 3px rgba(217,122,43,.35),0 1px 4px rgba(0,0,0,.4)}

/* Fila de junta señalada desde el plano */
.tbl tr.destacada td{background:var(--acento-l)}

/* El asistente ocupa la pantalla: con un recuadro pequeño no se verifica nada */
.modal.pleno{max-width:none;width:calc(100vw - 28px);height:calc(100vh - 28px);max-height:none}
.modal.pleno .modal-b{display:flex;flex-direction:column;min-height:0;overflow:hidden}
.modal.pleno .modal-b>section{flex:1;min-height:0;display:flex;flex-direction:column}
/* El área de revisión ocupa todo el alto disponible: si se dejara a la altura
   de su contenido, el plano quedaba en un recuadro pequeño con media pantalla
   vacía debajo, que es justo lo que no sirve para verificar. */
.modal.pleno .rev{flex:1;min-height:0;height:auto;align-items:stretch}
.modal.pleno .rev>div{min-height:0;overflow:auto}
.modal.pleno .rev>.plano{overflow:hidden;height:100%}

@media (max-width:1024px){
  .modal.pleno{width:calc(100vw - 12px);height:calc(100vh - 12px)}
  .modal.pleno .rev{display:block;height:auto}
  .modal.pleno .plano{height:60vh;margin-top:12px}
}

/* Diagnóstico de la lectura del plano */
.diag{border:1px solid var(--line-2);border-radius:var(--r);background:var(--paper-2)}
.diag>summary{padding:8px 12px;cursor:pointer;font:600 11.5px/1 var(--f-ui);color:var(--t2)}
.diag>summary:hover{color:var(--brand-d)}
.diag>div{padding:0 12px 10px}
.diag-lista{display:flex;flex-wrap:wrap;gap:4px;max-height:210px;overflow-y:auto}
.diag-t{display:inline-flex;align-items:center;gap:5px;padding:2px 7px;border-radius:var(--r-pill);
  background:var(--paper);border:1px solid var(--line);font:400 11px/1.5 var(--f-mo);color:var(--t2)}
.diag-t.cls{border-color:var(--brand-m);background:var(--brand-l);color:var(--brand-d)}
.diag-t i{font-style:normal;font-size:9px;color:var(--t3);min-width:18px;text-align:right}
.diag-t b{font:600 9px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;
  padding:2px 5px;border-radius:var(--r);background:rgba(0,0,0,.06)}

/* Etiqueta con el nombre de la junta, al lado de su punto */
.pl-marca .pl-etq{position:absolute;left:calc(100% + 5px);top:50%;transform:translateY(-50%);
  padding:1px 5px;border-radius:var(--r);background:rgba(13,17,23,.88);color:#fff;
  font:600 9.5px/1.6 var(--f-mo);white-space:nowrap;pointer-events:none;opacity:.92}
.pl-marca.on .pl-etq{background:var(--acento-d);opacity:1;font-size:10.5px}
.pl-marca:hover .pl-etq{opacity:1}

/* Al ubicar una junta, el plano avisa de que el siguiente clic coloca el punto */
.plano.ubicando .pl-hoja{cursor:crosshair}
.plano.ubicando .pl-scroll{box-shadow:inset 0 0 0 3px var(--acento)}
.plano.ubicando .pl-barra::after{content:'Pulsa sobre el plano para colocar la junta';
  margin-left:8px;font:600 10.5px/1 var(--f-ui);color:var(--acento-d)}

/* Botón de ubicación en cada fila de junta */
.f-ubi{width:26px;height:26px;flex:none;border:1px solid var(--line-2);border-radius:var(--r);
  background:var(--paper);color:var(--t3);cursor:pointer;font-size:12px;line-height:1}
.f-ubi:hover{background:var(--brand-l);border-color:var(--brand-m);color:var(--brand-d)}
.f-ubi.sin{color:var(--warn);border-color:var(--warn-br);background:var(--warn-bg)}
.f-ubi.on{background:var(--acento);border-color:var(--acento);color:#fff}

/* Marcas que se pueden arrastrar. `touch-action:none` es lo que impide que
   el dedo desplace el plano en vez de mover la junta. */
.pl-marca{touch-action:none}
.pl-marca:active{cursor:grabbing}
.pl-marca.moviendo{width:26px;height:26px;background:var(--acento);z-index:12;
  box-shadow:0 0 0 4px rgba(217,122,43,.3),0 2px 6px rgba(0,0,0,.45)}
.pl-marca.moviendo .pl-etq{background:var(--acento-d);opacity:1}
.plano.arrastrando .pl-scroll{cursor:grabbing}
.plano.arrastrando .pl-marca:not(.moviendo){opacity:.45}

/* Filas que abren un detalle: se nota que se puede pulsar */
.tbl tr.fila-iso{cursor:pointer}
.tbl tr.fila-iso:hover{background:var(--brand-l)}

/* ═════════════════════════════════════════════════════════════════
   PLANO CON SEGUIMIENTO POR ESTADO
   El plano ocupa el ancho y el panel de juntas va al lado. Debajo de
   la tabla, no a su derecha: un isométrico se lee a lo ancho.
   ═════════════════════════════════════════════════════════════════ */

.plano-fila{display:grid;grid-template-columns:1fr 268px;gap:0;height:min(72vh,760px);min-height:420px}
.plano-fila .plano{border:0;border-right:1px solid var(--line-2);border-radius:0;min-height:0}

.estado-juntas{display:flex;flex-direction:column;min-height:0;background:var(--paper)}
.ej-h{padding:10px 13px 6px;font:700 9.5px/1 var(--f-ui);letter-spacing:.14em;
  text-transform:uppercase;color:var(--t3)}
.ej-barra{display:flex;height:7px;margin:0 13px;border-radius:var(--r);overflow:hidden;background:var(--line)}
.ej-barra i{display:block;height:100%}
.ej-total{padding:6px 13px 0;font:600 12px/1 var(--f-ui);color:var(--t1)}
.ej-leyenda{display:flex;flex-wrap:wrap;gap:4px 10px;padding:7px 13px 9px;
  border-bottom:1px solid var(--line)}
.ej-leyenda span{display:inline-flex;align-items:center;gap:4px;font:400 10px/1.4 var(--f-tx);color:var(--t3)}
.ej-leyenda i{width:8px;height:8px;border-radius:50%;flex:none}
.ej-leyenda b{font-weight:600;color:var(--t2)}
/* La leyenda filtra: se parece a la de antes hasta que se pasa por encima. */
.ej-f{
  display:inline-flex;align-items:center;gap:4px;padding:2px 6px;margin:-2px -6px;
  font:400 10px/1.4 var(--f-tx);color:var(--t3);
  background:none;border:1px solid transparent;border-radius:var(--r-pill);cursor:pointer;
}
.ej-f:hover,.ej-f:focus-visible{border-color:var(--line-2);color:var(--t2)}
.ej-f.on{background:var(--brand-l);border-color:var(--brand-m);color:var(--brand-d)}
.ej-f.on b{color:var(--brand-d)}
/* Sin marca en el plano: el hueco se dibuja hueco. */
.ej-f.sin-marca i{background:transparent;border:1px dashed var(--t3)}

.ej-lista{flex:1;overflow-y:auto;padding:7px}
.ej-j{display:flex;align-items:center;gap:8px;width:100%;margin-bottom:4px;padding:6px 8px;
  cursor:pointer;text-align:left;background:var(--paper);border:1px solid var(--line);
  border-left:3px solid var(--line-2);border-radius:var(--r)}
.ej-j:hover{background:var(--paper-2)}
.ej-j.on{background:var(--acento-l);border-color:var(--acento);box-shadow:0 0 0 2px rgba(217,122,43,.18)}
.ej-j .n{flex:none;display:grid;place-items:center;width:22px;height:22px;border-radius:50%;
  color:#fff;font:700 9.5px/1 var(--f-mo)}
.ej-j .d{flex:1;min-width:0}
.ej-j .d b{display:block;font:600 11.5px/1.3 var(--f-mo);color:var(--t1)}
.ej-j .d small{display:block;font:400 9.5px/1.3 var(--f-tx);color:var(--t3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ej-j .e{flex:none;font:600 8.5px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t3)}

/* Punto de estado junto al nombre de la junta en la tabla */
.tbl .pt{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;
  vertical-align:middle}

@media (max-width:900px){
  .plano-fila{grid-template-columns:1fr;height:auto}
  .plano-fila .plano{height:56vh;border-right:0;border-bottom:1px solid var(--line-2)}
  .ej-lista{max-height:300px}
}

/* ═════════════════════════════════════════════════════════════════
   TRAZABILIDAD DE LA JUNTA
   El recorrido en ciclos: soldadura, ensayos, reparación, corte.
   ═════════════════════════════════════════════════════════════════ */

.tbl tr.j-fila{cursor:pointer}
.tbl tr.j-fila:hover{background:var(--paper-2)}
.tbl tr.j-fila.abierta{background:var(--brand-l)}
.tbl tr.j-fila.abierta td{border-bottom-color:var(--brand-m)}
.tbl tr.j-hist td{padding:0;background:var(--paper-2)}
.hist-caja{padding:12px 16px 14px}

.ciclos{list-style:none;margin:0;padding:0 0 0 20px;position:relative}
.ciclos::before{content:'';position:absolute;left:6px;top:6px;bottom:10px;width:2px;background:var(--line-2)}
.ciclo{position:relative;margin-bottom:11px}
.ciclo::before{content:'';position:absolute;left:-18px;top:5px;width:10px;height:10px;
  border-radius:50%;background:var(--brand);border:2px solid var(--paper)}
.ciclo.reparacion::before{background:var(--acento)}
.ciclo.corte::before{background:var(--stop)}

.ciclo .c-h{display:flex;align-items:baseline;gap:8px;font:600 12px/1.3 var(--f-ui);color:var(--t1)}
.ciclo .c-f{font:400 10.5px/1 var(--f-mo);color:var(--t3)}
.ciclo .c-d{font:400 11.5px/1.5 var(--f-tx);color:var(--t2);margin-top:1px}
.ciclo .c-u{margin-left:7px;font-size:10px;color:var(--t3)}

.ciclo .c-e{display:inline-flex;align-items:center;gap:7px;margin:4px 5px 0 0;padding:3px 9px;
  border:1px solid var(--line);border-left:3px solid var(--t3);border-radius:var(--r);background:var(--paper)}
.ciclo .c-e.aceptable{border-left-color:var(--ok)}
.ciclo .c-e.rechazado{border-left-color:var(--stop);background:var(--stop-bg)}
.ciclo .c-e.pendiente{border-left-color:var(--warn)}
.ciclo .c-e .t{font:700 10px/1 var(--f-mo);color:var(--t1)}
.ciclo .c-e .r{font:600 9.5px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t2)}
.ciclo .c-e .n,.ciclo .c-e .f{font:400 10px/1 var(--f-mo);color:var(--t3)}

.ciclo .c-corte{margin-top:5px;padding:5px 9px;border-radius:var(--r);
  background:var(--stop-bg);color:var(--stop);font:500 11.5px/1.4 var(--f-tx)}

/* Recorrido de la junta dentro del panel del plano */
.ej-traza{padding:9px 12px;border-bottom:1px solid var(--line);background:var(--paper-2);
  max-height:38%;overflow-y:auto}
.ej-traza[hidden]{display:none}
.ej-traza>b{display:block;margin-bottom:6px;font:600 12px/1 var(--f-mo);color:var(--t1)}
.ej-traza .ciclos{padding-left:16px}
.ej-traza .ciclo{margin-bottom:8px}
.ej-traza .ciclo::before{left:-14px;width:8px;height:8px}

/* ═════════════════════════════════════════════════════════════════
   AJUSTAR ANCHOS Y ALTOS EN EL EDITOR
   Los tiradores viven en una capa sobre la hoja: dentro de las celdas
   estorbarían justo al escribir y al seleccionar.
   ═════════════════════════════════════════════════════════════════ */

.pe-hoja{position:relative}
.pe-reglas{position:absolute;top:0;left:0;right:0;bottom:0;pointer-events:none;z-index:5}
.pe-rg-cols,.pe-rg-filas{position:absolute;top:0;left:0;right:0;bottom:0}

.pe-h-col{position:absolute;top:0;bottom:0;width:9px;margin-left:-4px;
  cursor:col-resize;pointer-events:auto}
.pe-h-fila{position:absolute;left:0;right:0;height:9px;margin-top:-4px;
  cursor:row-resize;pointer-events:auto}

/* La línea solo aparece al acercarse: si estuviera siempre, la hoja
   parecería cuadriculada de más y costaría ver el formato real. */
.pe-h-col::after{content:'';position:absolute;top:0;bottom:0;left:3px;width:2px;
  background:var(--brand);opacity:0;transition:opacity var(--mov)}
.pe-h-fila::after{content:'';position:absolute;left:0;right:0;top:3px;height:2px;
  background:var(--brand);opacity:0;transition:opacity var(--mov)}
.pe-h-col:hover::after,.pe-h-fila:hover::after{opacity:.55}
.pe-h-col.activo::after,.pe-h-fila.activo::after{opacity:1;background:var(--acento)}

/* Etiquetas de las reglas: la letra de cada columna (A, B, C…) y el número de
   cada fila (1, 2, 3…). Van dentro del margen blanco de la hoja, que es el
   único sitio donde no estorban al escribir ni al seleccionar. Y SÍ reciben
   clics: pulsar el número de una fila o la letra de una columna la selecciona
   entera, que es lo que todo el mundo intenta hacer —viene de la hoja de
   cálculo— y es la única manera cómoda de marcar varias para borrarlas. */
.pe-rg-etq{position:absolute;display:grid;place-items:center;cursor:pointer;pointer-events:auto;
  font:600 8.5px/1 var(--f-ui);color:var(--t3);background:var(--paper);
  border:1px solid var(--line);border-radius:3px;user-select:none}
.pe-rg-etq:hover{color:var(--brand);border-color:var(--brand)}
.pe-rg-etq-c{top:-16px;width:18px;height:13px;margin-left:-9px}
.pe-rg-etq-f{left:-23px;width:16px;height:13px;margin-top:-6.5px}
.pe-rg-etq.sel{color:var(--paper);background:var(--brand);border-color:var(--brand)}

/* Mientras se arrastra, el cursor no cambia aunque se salga del tirador */
body.ajustando-col,body.ajustando-col *{cursor:col-resize!important;user-select:none}
body.ajustando-fila,body.ajustando-fila *{cursor:row-resize!important;user-select:none}

/* ═════════════════════════════════════════════════════════════════
   VISTA DE IMPRESIÓN DE LA PLANTILLA
   Se enseña una hoja A4 igual que la del editor. Con la tabla suelta
   dentro del modal, más estrecho que un A4, las columnas se comprimían
   y la vista no se parecía al papel, que es a lo que viene esta pantalla.
   ═════════════════════════════════════════════════════════════════ */

/* El modal se ajusta a la hoja: ni pantalla completa ni una caja estrecha.
   Antes reutilizaba el modal a pantalla completa, y sus reglas —pensadas para
   el asistente de importación— le imponían «overflow:hidden» y estiraban el
   contenido, así que la hoja perdía su ancho y no se podía desplazar. */
/* Ancho explícito: con «auto» el modal se encoge a lo que ocupe el contenido
   y acababa más estrecho que la propia hoja. */
.modal.previa{width:min(94vw, 236mm);max-width:none;max-height:92vh;
  display:flex;flex-direction:column}
/* Un formato apaisado mide 297 mm, no 210: en la caja de arriba no cabía y
   había que desplazarlo a lo ancho para leer la mitad derecha, justo en la
   pantalla cuyo trabajo es enseñar la hoja entera de un vistazo. Los 26 mm de
   más son el marco del diálogo, los mismos que en vertical. */
.modal.previa.apaisada{width:min(94vw, 323mm)}
.modal.previa .modal-h{flex:none}
.modal.previa .modal-b{flex:1;min-height:0}
/* El botón de imprimir, pegado al título y antes de la escala */
.modal.previa .modal-h .btn{flex:none}

/* ── Hoja A4, un solo componente ───────────────────────────────────
   Lo usan el editor, la vista de impresión y la pantalla de llenado del
   registro. Tener tres copias de esto llevaría a que un día se vieran
   distinto sin que nadie supiera por qué. */
/* La hoja no se reduce por debajo de un tamaño en que se pueda tocar una
   celda (ver QMS.ajustarHoja): lo que no cabe se desplaza a lo ancho dentro
   del fondo, no en la página. El centrado va con márgenes automáticos y no con
   «justify-content:center», que al desbordar dejaba la parte izquierda de la
   hoja fuera de alcance del desplazamiento. */
.hoja-fondo{background:var(--canvas);padding:16px 10px;overflow-x:auto;-webkit-overflow-scrolling:touch}
.hoja-lienzo{display:flex;justify-content:flex-start;align-items:flex-start}
.hoja-caja{flex:none;overflow:hidden;margin:0 auto}
.hoja-a4{width:210mm;flex:none;padding:10mm;min-height:260mm;box-sizing:border-box;
  background:#fff;border-radius:var(--r);box-shadow:var(--sh-2);transform-origin:top left}
/* Desde la esquina y no desde el centro: la caja que envuelve la hoja se
   reduce a su ancho ya escalado, y al escalar desde el centro el contenido se
   corría hacia la izquierda y la caja le cortaba las últimas columnas. */
.hoja-a4.apaisada{width:297mm}
.hoja-a4 table.xt{width:100%;table-layout:fixed;border-collapse:collapse}
.hoja-a4 .doc-cab,.hoja-a4 .doc-firmas{max-width:100%}

.previa-b{overflow:auto}

/* ═════════════════════════════════════════════════════════════════
   SELLO DE INTEGRIDAD CON CÓDIGO QR
   ═════════════════════════════════════════════════════════════════ */

/* Con el código más pequeño, el recuadro también encoge: si mantuviera el
   aire de antes, el ahorro de espacio se lo comería el propio marco. */
.pr-sello{display:flex;align-items:center;gap:8px;margin-top:6px;padding:5px 8px;
  border:1px solid #000;border-radius:var(--r);background:#fff}
.pr-qr{flex:none;line-height:0}
.pr-qr svg{display:block}
.pr-sello-t{flex:1;min-width:0}
.pr-sello-t b{display:block;font:700 8pt/1.3 var(--f-ui);color:#000}
.pr-sello-t .mono{font:600 7pt/1.45 var(--f-mo);letter-spacing:.05em;color:#000;word-break:break-all}
.pr-sello-t p{margin:1px 0 0;font:400 6.4pt/1.3 var(--f-tx);color:#333}

@media print{
  .pr-sello{break-inside:avoid;page-break-inside:avoid}
}

/* Aviso de copia no controlada, dentro del recuadro del sello.
   Va en vertical y en el borde derecho: ocupa un dedo de ancho, no roba
   altura a la hoja, y sigue leyéndose de lejos por el color y el marco. */
.pr-aviso{flex:none;align-self:stretch;width:104px;display:flex;align-items:center;
  justify-content:center;padding:4px 6px;border-left:2px solid var(--warn);
  /* En 7 pt el ámbar de marca no llega al contraste AA: se usa el de texto */
  background:var(--warn-bg);color:var(--warn-tx);font:700 7pt/1.3 var(--f-ui);
  letter-spacing:.1em;text-transform:uppercase;text-align:center}

@media print{
  .pr-aviso{-webkit-print-color-adjust:exact;print-color-adjust:exact}
}

/* Marca de agua para los registros que aún no están aprobados.
   Muy tenue y detrás del contenido: se ve al mirar la hoja entera, pero no
   estorba para leer ni para rellenar a mano. */
.pr-doc{position:relative}
/* Sin flex y sin «inset»: los motores de impresión antiguos no centran bien
   un elemento absoluto con flex, y una marca de agua que no se dibuja no
   avisa de nada. Con top/left y centrado por texto sale en todos. */
/* Va POR ENCIMA del contenido, no detrás: la maqueta es una tabla con fondo
   propio en casi todas sus celdas, así que una marca de agua por debajo
   quedaría tapada y no se vería en ninguna impresión. */
.pr-agua{position:absolute;top:40%;left:0;right:0;text-align:center;
  pointer-events:none;z-index:5}
.pr-agua span{display:inline-block;font:700 34pt/1 var(--f-ui);letter-spacing:.14em;
  text-transform:uppercase;color:var(--warn);opacity:.07;
  transform:rotate(-32deg);white-space:nowrap}
.pr-doc>*:not(.pr-agua){position:relative;z-index:1}
/* La marca queda encima, pero tan tenue que no estorba para leer ni escribir. */

@media print{
  .pr-agua span{-webkit-print-color-adjust:exact;print-color-adjust:exact;opacity:.09}
}

/* Un documento anulado no es lo mismo que uno pendiente de firma: el primero
   ya no vale, el segundo todavía no. En rojo, para que no se confundan. */
.pr-aviso.pr-t-anulado{border-left-color:var(--stop);background:var(--stop-bg);color:var(--stop-tx,var(--stop))}
.pr-agua.pr-t-anulado span{color:var(--stop);opacity:.10}

@media print{
  .pr-agua.pr-t-anulado span{opacity:.13}
}

/* Barra para marcar en bloque el tipo de varias juntas */
.sel-barra{display:flex;align-items:center;gap:10px;padding:7px 11px;border-radius:var(--r);
  background:var(--brand-l);border:1px solid var(--brand-m)}
.sel-barra[hidden]{display:none}
.sel-barra b{font:600 12px/1 var(--f-ui);color:var(--brand-d)}
.sel-barra label{display:flex;align-items:center;gap:5px;color:var(--t2)}
.in-sm{height:28px;padding:2px 7px;font-size:12px}

/* ═════════════════════════════════════════════════════════════════
   GRÁFICOS DE BARRAS DEL WELDING BOOK
   Barras dibujadas con CSS: se imprimen bien, no dependen de ninguna
   biblioteca y funcionan sin internet, que es lo que hay en obra.
   ═════════════════════════════════════════════════════════════════ */

/* ── Dos tarjetas que deben leerse en paralelo ─────────────────────
   «alineadas» las pone a la misma altura y con la cabecera del mismo alto.
   Sin esto, basta con que una cabecera lleve una etiqueta o un total al lado
   para que su contenido arranque un renglón más abajo que el de la otra, y
   dos tablas que se comparan entre sí no deben empezar a distinta altura. */
.cols2.alineadas{align-items:stretch}
.cols2.alineadas>.card{display:flex;flex-direction:column;margin:0}
.cols2.alineadas>.card>.card-h{min-height:45px;align-items:center;flex:none;
  padding-top:0;padding-bottom:0}
.cols2.alineadas>.card>.card-b:last-child{flex:1}

/* «iguales» reparte además el ancho mitad y mitad. El reparto normal de
   «.cols2» —1,55 a 1— está pensado para contenido principal más lateral, y
   dos gráficos del mismo peso no son eso. */
.cols2.iguales{grid-template-columns:1fr 1fr}
.cols2.iguales>.card>.card-b{display:flex;flex-direction:column}

@media (max-width:1080px){ .cols2.iguales{grid-template-columns:1fr} }

.graf{display:flex;flex-direction:column;gap:5px;flex:1}
.g-fila{display:flex;align-items:center;gap:9px}
.g-par{margin-top:6px}
.g-et{flex:none;width:104px;text-align:right;font:600 10.5px/1.3 var(--f-ui);color:var(--t2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.g-fila .g-et.mono{font:600 9.5px/1.3 var(--f-mo)}
.g-barra{position:relative;flex:1;height:13px;border-radius:var(--r);background:var(--line);overflow:hidden}
.g-barra i{position:absolute;top:0;left:0;height:100%;border-radius:var(--r)}
.g-prev{background:var(--t4,#B8BFC7)}
.g-ejec{background:var(--ok)}
.g-val{flex:none;width:52px;font:400 10.5px/1.3 var(--f-mo);color:var(--t3)}
.g-val b{color:var(--t1)}

.g-leyenda{display:flex;justify-content:center;gap:16px;margin-top:auto;padding-top:9px}
.g-leyenda span{display:inline-flex;align-items:center;gap:5px;
  font:600 9px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--t3)}
.g-leyenda i{width:9px;height:9px;border-radius:var(--r)}

@media print{ .g-barra i{-webkit-print-color-adjust:exact;print-color-adjust:exact} }

/* Tabla de permisos afinados por persona */
.tbl-permisos td,.tbl-permisos th{padding:6px 10px}
.tbl-permisos .in-sm{width:100%}

/* Atajos de permisos, con el estado actual marcado */
.presets{display:flex;align-items:center;gap:7px}
.preset,.preset-lib{padding:5px 12px;border-radius:var(--r-pill);border:1px solid var(--line-2);
  background:var(--paper);color:var(--t2);cursor:pointer;
  font:600 11px/1.3 var(--f-ui);letter-spacing:.02em}
.preset:hover{border-color:var(--brand-m);color:var(--brand-d);background:var(--brand-l)}
.preset.on,.preset-lib.on{background:var(--brand);border-color:var(--brand);color:#fff}
/* «A medida» no es un botón: solo dice dónde estás cuando no hay atajo que valga */
.preset-lib{cursor:default;opacity:.5}
.preset-lib.on{opacity:1;background:var(--acento);border-color:var(--acento)}

/* ═════════════════════════════════════════════════════════════════
   DIVISOR ARRASTRABLE — reparte el espacio entre los datos y el plano
   ═════════════════════════════════════════════════════════════════ */

/* El ancho de la columna izquierda lo decide una variable: así el arrastre
   cambia un solo valor y el reparto sobrevive a que se repinte el contenido. */
.rev{grid-template-columns:var(--rev-izq,1.25fr) 9px 1fr}

.divisor{
  position:relative;cursor:col-resize;border-radius:var(--r);
  background:var(--line);transition:background var(--mov);
  touch-action:none;user-select:none;align-self:stretch
}
/* La zona sensible es más ancha que la línea: nueve píxeles se fallan */
.divisor::before{content:'';position:absolute;top:0;bottom:0;left:-6px;right:-6px}
/* Dos rayitas al centro, la señal de «esto se arrastra» */
.divisor::after{
  content:'';position:absolute;top:50%;left:50%;width:3px;height:26px;
  transform:translate(-50%,-50%);border-radius:var(--r);
  background:linear-gradient(var(--t4,#B8BFC7) 0 100%);opacity:.9
}
.divisor:hover,.divisor:focus-visible{background:var(--brand-m);outline:none}
.divisor:focus-visible{box-shadow:0 0 0 2px var(--brand-l)}
.rev.ajustando .divisor{background:var(--brand)}
/* Mientras se arrastra, nada de seleccionar texto ni de cambiar el cursor */
.rev.ajustando{cursor:col-resize;user-select:none}

/* En pantalla estrecha las columnas se apilan y el divisor no pinta nada.
   El punto de corte es el mismo que ya usaba el asistente (1024px): al estar
   esta regla después en el archivo, si eligiera otro se comería el apilado
   que ya existía entre uno y otro. */
@media (max-width:1024px){
  .rev{grid-template-columns:1fr}
  .divisor{display:none}
}


/* Plantilla venida de una hoja de cálculo: no se parten las palabras.
   El editor parte por cualquier letra, que va bien para una tabla ancha; en
   una hoja de Excel, con veinte o treinta columnas estrechas, convertía cada
   rótulo en una columna de caracteres, uno debajo de otro. Ahora la palabra
   se mantiene entera y, si no cabe, se desborda como haría Excel. */
table.xt.xt-hoja td, table.xt.xt-hoja th{word-break:normal;overflow-wrap:normal}

/* Plantilla que trae los bordes del original: el editor no pone los suyos.
   En Excel la mayoría de las celdas no tienen borde —un cuadro es un
   rectángulo con línea alrededor y nada dentro—, así que sumar la rejilla del
   editor convertía cualquier formato en papel cuadriculado. */
table.xt.xt-fiel td, table.xt.xt-fiel th{
  border:0;
  padding:1px 3px;
  line-height:1.15;
  /* Recortado, no desbordado: Excel deja que un rótulo invada las celdas
     vacías de al lado, pero lo corta en cuanto topa con una que tiene algo.
     Dejarlo desbordar montaba «PROYECTO:» encima de su propio valor. Lo que
     sí cabe se resuelve antes, extendiendo la celda sobre las vacías. */
  overflow:hidden
}
table.xt.xt-fiel tr.aire td{border:0}

/* Elegir plantilla de la biblioteca: lista a la izquierda, hoja a la derecha */
.bib-it{
  padding:9px 11px;border:1px solid var(--line);border-radius:var(--r-s);
  margin-bottom:7px;cursor:pointer;background:#fff;transition:border-color var(--mov),background var(--mov)
}
.bib-it:hover{border-color:var(--brand-m);background:var(--bg-2)}
.bib-it.on{border-color:var(--brand);box-shadow:inset 3px 0 0 var(--brand);background:var(--bg-2)}
/* Lo ya adoptado se atenúa, pero se deja elegir: puede querer otra versión.
   La atenuación va en el marco y en la insignia, no en todo el bloque: al
   bajarle la opacidad entera, el texto pequeño se quedaba en 2,5:1. */
.bib-it.ya{background:var(--bg-2);border-style:dashed}
.bib-it.ya .muted{color:var(--t2)}
/* De una disciplina que esta obra no lleva: se enseña —el catálogo es común—
   pero con el canto ámbar del aviso, no atenuada: lo que hay que leer ahí es
   justamente la línea que dice por qué todavía no se puede adoptar. */
.bib-it.ajena{box-shadow:inset 3px 0 0 var(--warn)}

/* ═════════════════════════════════════════════════════════════════
   BOTONES DE ACCIÓN EN UNA FILA DE TABLA
   La celda de acciones se encoge al mínimo (`w1`), y un contenedor que
   admite salto de línea dentro de una celda encogida acaba poniendo cada
   botón en su propio renglón: seis botones, seis renglones, y la fila del
   listado ocupando media pantalla.

   Se le da un ancho pensado para que quepan tres por renglón: dos filas de
   botones, alineadas a la derecha, sin estirar la tabla.
   ═════════════════════════════════════════════════════════════════ */
table.tbl td .btns{
  /* Tres columnas de ancho fijo: las seis acciones caben en dos renglones y
     quedan alineadas, que se lee mejor que un flujo irregular donde cada
     botón empieza donde acabó el anterior.

     Se resuelve con ancho fijo y no con rejilla porque así se comporta igual
     en cualquier navegador, incluidos los de las tabletas de obra. */
  display:block;
  width:273px;
  text-align:right;
  /* La celda de acciones lleva «no partir», que sirve para que no se corten
     los textos cortos de las otras columnas; aquí impedía que los botones
     saltaran de renglón y se salían de la tabla. */
  white-space:normal;
  font-size:0            /* quita el hueco entre elementos en línea */
}
table.tbl td .btns .btn{
  display:inline-block;
  width:87px;
  margin:0 0 4px 4px;
  vertical-align:top;
  font-size:11px;        /* se restablece el tamaño dentro del botón */
  /* El botón hereda el «alinear a la derecha» de la celda, que sirve para
     pegar la columna de botones al borde pero deja su texto descentrado. Al
     pasar de «inline-flex» a «inline-block» se perdió el centrado que traía
     de serie, así que se devuelve aquí. */
  text-align:center
}
/* En una fila de listado no hacen falta botones de altura de formulario */
/* Relleno ajustado: con 8px a cada lado, «DESPUBLICAR» no entraba en el ancho
   de columna y se cortaba. Ensanchar la columna era peor: se lo quitaba a los
   nombres de plantilla, que son lo que se lee. */
table.tbl td .btns .btn-xs{min-height:26px;padding:3px 4px;letter-spacing:.02em}
/* El de duplicar es solo un icono: que no ocupe como uno con texto */
table.tbl td .btns .btn-xs.btn-icono{padding:3px 6px}

@media (max-width:860px){
  /* En pantalla estrecha los botones se repartían en un solo renglón cada uno y
   una fila de la tabla ocupaba media pantalla. Se colocan en rejilla de dos
   columnas: la misma información en un tercio del alto. */
table.tbl td .btns{width:182px;display:block;text-align:right;white-space:normal;font-size:0}
table.tbl td .btns .btn{
  display:inline-block;width:87px;margin:0 0 4px 4px;font-size:11px;text-align:center
}
}

/* Fila recién registrada: se señala unos segundos para no tener que buscarla
   entre las demás después de guardar. El color se apaga solo. */
tr.j-fila.recien > td{
  background:var(--brand-l);
  box-shadow:inset 3px 0 0 var(--brand);
  transition:background 1.2s ease-out, box-shadow 1.2s ease-out
}

/* Hojas de un mismo registro: una pastilla por hoja, la actual resaltada.
   Cada hoja es un registro aparte, así que sin esto habría que volver a la
   lista para pasar de una a otra. */
.hojas-nav{display:inline-flex;gap:3px;vertical-align:middle}
.hoja-p{
  min-width:20px;padding:1px 5px;border:1px solid var(--line);border-radius:var(--r);
  font:600 11px/1.5 var(--f-mo);color:var(--tx-2);text-decoration:none;text-align:center
}
.hoja-p:hover{border-color:var(--brand-m);color:var(--brand)}
.hoja-p.on{background:var(--brand);border-color:var(--brand);color:#fff}

/* Visor del anexo dentro de la pantalla de llenado: se abre bajo la lista para
   comprobar el documento sin salir del registro. */
.visor-cab{
  display:flex;gap:8px;align-items:center;padding:6px 9px;
  border:1px solid var(--line);border-bottom:0;border-radius:var(--r-s) var(--r-s) 0 0;
  background:var(--bg-2);font-size:12px
}
.visor-pdf{
  width:100%;height:60vh;min-height:340px;display:block;
  border:1px solid var(--line);border-radius:0 0 var(--r-s) var(--r-s)
}

/* Anexos en PDF: van detrás del registro, cada uno en su hoja. No entran en la
   numeración del formato porque son documentos de terceros que lo acompañan. */
.anexo-cab{
  display:flex;gap:12px;align-items:baseline;border:1px solid #000;
  padding:5px 8px;font:600 10pt/1.3 var(--f-ui)
}
.anexo-cab span{font-weight:400;font-size:9pt;color:#333}
.anexo-cab .mono{margin-left:auto;font-family:var(--f-mo);font-size:8.5pt}
@media print{
  .anexo-pdf{page-break-before:always}

  /* El plano del anexo va al papel con sus marcas. Se le quita la altura de
     pantalla y los controles del visor: en papel no hay nada que pulsar, y el
     dibujo tiene que ocupar la hoja. */
  .anx-plano{height:auto!important;min-height:0!important;border:0!important;overflow:visible!important}
  .anx-plano .pl-barra{display:none!important}
  .anx-plano .pl-scroll{overflow:visible!important;height:auto!important}
  .anx-plano canvas{max-width:100%!important;height:auto!important}
  .visor-cab{border:1px solid #000;background:none}
}

/* Lista de anexos del registro: se numeran solos, para que el número que se ve
   sea el orden en que se imprimen detrás. */
ol.anexos{list-style:none;margin:0;padding:0;counter-reset:anexo}
ol.anexos li{
  counter-increment:anexo;display:flex;gap:8px;align-items:center;
  padding:7px 9px;border:1px solid var(--line);border-radius:var(--r-s);margin-bottom:6px
}
ol.anexos .an-n::before{
  content:counter(anexo);display:inline-block;min-width:20px;text-align:center;
  font:600 11px/1.6 var(--f-mo);color:#fff;background:var(--brand);border-radius:var(--r)
}
ol.anexos .an-nom{font-weight:600;text-decoration:none;color:var(--tx)}
ol.anexos .an-nom:hover{color:var(--brand)}

/* El plano de un anexo necesita alto propio: el visor dibuja dentro de su
   contenedor y, sin una altura declarada, el contenedor mide cero y no se ve
   nada. Los isométricos la reciben de su rejilla; aquí va suelto en la página. */
.anx-plano{height:min(70vh,720px);min-height:380px}
@media (max-width:860px){ .anx-plano{height:60vh;min-height:300px} }
/* Lo de imprimir está más abajo, junto al resto de reglas de papel: tenerlo
   en dos sitios hacía que la última ganara sin querer. */

/* Anotaciones sobre un plano adjunto: el PDF debajo y las marcas encima, en su
   propia capa. No se pueden meter dentro del PDF —lo dibuja el navegador— así
   que se guardan por su posición relativa sobre la hoja. */
.anx-lienzo{position:relative}
.anx-capa{position:absolute;inset:0;pointer-events:none}
/* Solo mientras se anota la capa recibe los clics: el resto del tiempo deja
   pasar el ratón al PDF, para poder desplazarlo y hacer zoom. */
.anx-lienzo.anotando .anx-capa{pointer-events:auto;cursor:crosshair;background:rgba(30,58,95,.05)}
.anx-nota{
  position:absolute;transform:translate(-50%,-50%);display:flex;gap:5px;align-items:center;
  pointer-events:auto;cursor:pointer
}
.anx-pin{
  min-width:19px;height:19px;border-radius:50%;background:var(--stop);color:#fff;
  font:700 11px/19px var(--f-mo);text-align:center;box-shadow:0 1px 4px rgba(0,0,0,.4);flex:none
}
.anx-txt{
  background:#fff;border:1px solid var(--stop);border-radius:var(--r);padding:2px 6px;
  font:500 11px/1.35 var(--f-ui);max-width:220px;box-shadow:0 1px 4px rgba(0,0,0,.25)
}

/* Anotaciones con flecha: la línea va en una capa de dibujo por debajo, y el
   texto al otro extremo. Sirve para señalar algo sin taparlo, que es lo que
   pasa con una marca puntual sobre un detalle pequeño del plano. */
.pl-flechas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.pl-etq-suelta{
  position:absolute;transform:translate(-50%,-50%);pointer-events:none;
  background:#fff;border:1px solid currentColor;border-radius:var(--r);padding:2px 6px;
  font:600 11px/1.35 var(--f-ui);white-space:nowrap;max-width:240px;
  overflow:hidden;text-overflow:ellipsis;box-shadow:0 1px 4px rgba(0,0,0,.25)
}
/* La marca de una flecha es solo el punto: su texto ya está al otro extremo */
.pl-marca.con-flecha .pl-etq{display:none}

/* Resaltado: la marca va pequeña en la esquina de la zona, para poder pulsarla
   sin tapar lo que se acaba de resaltar. */
.pl-marca.es-resalte{
  width:13px;height:13px;transform:translate(-50%,-50%);
  border-width:1.5px;font-size:0
}
.pl-marca.es-resalte .pl-etq{font-size:11px}

/* Paleta de colores de la anotación: pastillas pequeñas, la activa con anillo.
   El color es lo que permite leer un plano de un vistazo sin abrir cada nota. */
.colores{display:inline-flex;gap:3px;vertical-align:middle}
.color-p{
  width:15px;height:15px;border-radius:50%;border:1.5px solid #fff;padding:0;cursor:pointer;
  box-shadow:0 0 0 1px var(--line)
}
.color-p.on{box-shadow:0 0 0 2px var(--tx)}
.color-p:hover{transform:scale(1.15)}

/* El rectángulo que se ve mientras se arrastra para resaltar. Sin él se
   marcaría a ciegas y habría que deshacer a menudo. */
.pl-zona-viva{
  position:absolute;pointer-events:none;
  border:1.5px dashed var(--brand);background:var(--brand);opacity:.28
}
/* Mientras se resalta, el puntero lo dice; y no se selecciona texto al
   arrastrar, que es lo que hace el navegador por su cuenta. */
.pl-cont.marcando-zona .pl-hoja,
.plano.marcando-zona .pl-hoja{cursor:crosshair;user-select:none}

/* La hoja de un anexo: en pantalla se comporta como el papel del registro, pero
   al imprimir ocupa la página entera. Un plano metido en el papel del formato
   sale con media hoja en blanco, que es justo lo que no sirve en obra. */
.hoja-anexo{
  max-width:297mm;margin:16px auto;background:#fff;padding:10mm;box-shadow:var(--sh-2)
}
/* En papel no va: el anexo se entrega como PDF aparte, generado del original y
   con sus marcas dentro. Meter el plano en la hoja del registro lo escalaba a
   capricho del navegador y perdía definición. */
@media print{ .hoja-anexo{display:none!important} }

/* Matriz de trazabilidad: una fila por TAG y una columna por protocolo. La
   tabla es ancha por naturaleza —doce o quince formatos— así que se desplaza
   en horizontal con las dos primeras columnas fijas: sin eso, al llegar a la
   derecha ya no se sabe de qué equipo es la fila. */
.mx-wrap{overflow:auto;max-height:72vh}
table.mx{border-collapse:separate;border-spacing:0;font-size:12px;width:auto;min-width:100%}
table.mx th,table.mx td{border-bottom:1px solid var(--line);border-right:1px solid var(--line-2);padding:5px 7px}
table.mx thead th{
  position:sticky;top:0;z-index:3;background:var(--bg-2);
  font:600 10px/1.2 var(--f-ui);text-transform:uppercase;letter-spacing:.1em;vertical-align:bottom
}
/* El código del protocolo, en vertical: en horizontal la tabla no cabría */
.mx-col{height:120px;padding:4px 2px!important}
.mx-col span{
  writing-mode:vertical-rl;transform:rotate(180deg);
  white-space:nowrap;font-family:var(--f-mo);font-size:10px;letter-spacing:0
}
.mx-fija,.mx-fija2{position:sticky;background:var(--paper);z-index:2;text-align:left}
.mx-fija{left:0;min-width:132px;font-family:var(--f-mo);font-size:11px}
.mx-fija2{left:132px;min-width:190px;color:var(--tx-2)}
thead .mx-fija,thead .mx-fija2{z-index:4}
.mx-fija span{display:block;font-family:var(--f-ui)}

/* El cruce: un signo por estado. El color lleva la lectura de un vistazo,
   pero el signo va siempre, para quien no distinga bien los colores y para
   cuando se imprime en blanco y negro. */
.mx-c{text-align:center;font-size:13px;line-height:1;min-width:30px}
.mx-c a{text-decoration:none;display:block}
.mx-ok    {background:#e8f6ec;color:#1e7a3c}
.mx-firma {background:#e9f0fb;color:#1f5fa8}
.mx-hecho {background:#eef4fb;color:#2c6bb0}
.mx-obs   {background:#fff4e0;color:#a86a10}
.mx-stop  {background:#fdecec;color:#b02a2a}
.mx-nulo  {background:var(--bg-2);color:var(--tx-3)}
.mx-curso {background:#f4f6f8;color:var(--tx-2)}
.mx-plan  {background:transparent;color:var(--tx-3)}
.mx-vacio {background:repeating-linear-gradient(45deg,transparent,transparent 4px,var(--line-2) 4px,var(--line-2) 5px)}

.mx-tot{background:var(--bg-2);font-weight:600;min-width:52px}
.mx-pc{font-family:var(--f-mo);font-size:11px}
.mx-avance{display:flex;flex-direction:column;line-height:1.2}
.mx-avance b{font:700 22px/1 var(--f-ui);color:var(--brand)}

.mx-lg{
  display:inline-block;min-width:17px;height:17px;line-height:17px;text-align:center;
  border:1px solid var(--line);border-radius:var(--r);font-size:11px;vertical-align:middle
}


/* ═══════════════════════════════════════════════════════════════════
   Bandejas de trabajo, flujo del panel, siguiente paso y menú «Más»
   ═══════════════════════════════════════════════════════════════════ */

/* Bandejas: un solo grupo segmentado sobre la lista de registros, en vez de
   ocho cajas con borde propio. La seleccionada es la que va en blanco. */
.bandejas{display:inline-flex;gap:4px;flex-wrap:wrap;margin:0 0 12px;padding:4px;background:var(--seg);border-radius:var(--r-lg)}
.bandeja{
  display:inline-flex;align-items:center;gap:7px;padding:7px 13px;
  background:transparent;border:1px solid transparent;border-radius:var(--r);
  color:var(--t2);font:500 12.5px/1.15 var(--f-tx);letter-spacing:0;text-transform:none;
  transition:background var(--mov),color var(--mov)
}
.bandeja:hover{text-decoration:none;background:rgba(255,255,255,.6);color:var(--t1)}
.bandeja .b-n{
  font:500 11px/1 var(--f-mo);min-width:0;text-align:center;padding:0;border-radius:0;
  background:none;color:var(--t3)
}
.bandeja.warn .b-n{color:var(--warn-tx)}
.bandeja.brand .b-n{color:var(--brand-d)}
.bandeja.stop .b-n{color:var(--stop)}
.bandeja.hold .b-n{color:var(--hold)}
.bandeja.ok   .b-n{color:var(--ok)}
.bandeja.on{background:var(--paper);color:var(--t1);font-weight:600;box-shadow:0 1px 2px rgba(16,24,40,.06)}
/* Atenuada con color, no con opacidad: al 80 % el contador no llegaba a 4,5:1 */
.bandeja.menor{color:var(--t3)}
.bandejas .sp{flex:1}

.tbl-reg td.vencido{color:var(--stop)}
.tbl tr.fila-nula td{color:var(--t4)}
.tbl tr.fila-nula .strong a{color:var(--t3);text-decoration:line-through}

/* Flujo: el circuito de un registro con cuántos hay en cada tramo */
.flujo{display:grid;grid-template-columns:repeat(5,1fr);gap:0;margin-bottom:16px;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;
  box-shadow:var(--sh-1)}
.flujo-p{position:relative;display:block;padding:14px 18px;color:var(--t1);
  border-right:1px solid var(--linea-suave);transition:background var(--mov)}
.flujo-p:last-child{border-right:0}
.flujo-p:hover{background:var(--brand-l);text-decoration:none}
/* Sin la flecha entre tramos: el orden ya lo dicen los números y la lectura
   de izquierda a derecha, y esos triángulos partían la línea de la tarjeta. */
.flujo-p .k{font:400 12.5px/1.3 var(--f-tx);letter-spacing:0;text-transform:none;color:var(--t2)}
.flujo-p .v{font:500 26px/1.1 var(--f-ui);margin-top:2px;color:var(--t4)}
.flujo-p .s{font-size:11px;color:var(--t3);margin-top:2px}
.flujo-p.warn .v{color:var(--warn)} .flujo-p.hold .v{color:var(--hold)}
.flujo-p.ok .v{color:var(--ok)}     .flujo-p.stop .v{color:var(--stop)}
.flujo-p .alerta{display:inline-block;margin-top:4px;font:600 10.5px/1.2 var(--f-tx);color:var(--stop)}
.flujo-pie{display:flex;gap:16px;flex-wrap:wrap;font-size:12px;color:var(--t3);margin:-8px 2px 16px}
@media (max-width:860px){
  .flujo{grid-template-columns:1fr 1fr}
  .flujo-p{border-bottom:1px solid var(--line)}
  .flujo-p::after{display:none}
}

/* Bandeja personal del panel: lo que le toca a esta persona */
.mis{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));margin-bottom:16px}
/* Las tarjetas de «Tu trabajo» son tarjetas normales: sin filo de color
   arriba. Lo que distingue a la que tiene trabajo es el número, en su color. */
.mis-g{background:var(--paper);border:1px solid var(--line);box-shadow:var(--sh-1);
  border-radius:var(--r-lg);display:flex;flex-direction:column;min-height:0}
.mis-h{display:flex;align-items:baseline;gap:8px;padding:15px 18px 4px}
.mis-h b{font:600 15px/1.25 var(--f-ui);letter-spacing:.01em}
.mis-h .n{margin-left:auto;font:500 19px/1 var(--f-ui);color:var(--t4)}
.mis-g.stop .mis-h .n{color:var(--stop)} .mis-g.hold .mis-h .n{color:var(--hold)}
.mis-g.warn .mis-h .n{color:var(--warn)} .mis-g.ok .mis-h .n{color:var(--ok)}
.mis-a{padding:2px 18px 10px;font-size:11.5px;color:var(--t3)}
.mis-i{display:block;padding:9px 18px;border-top:1px solid var(--linea-suave);color:var(--t1);
  transition:background var(--mov)}
.mis-i:hover{background:var(--brand-l);text-decoration:none}
.mis-i .c{font:500 12px/1.3 var(--f-mo)}
.mis-i .t{display:block;font-size:11.5px;color:var(--t3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mis-v{margin-top:auto;display:block;padding:10px 18px;border-top:1px solid var(--linea-suave);
  font:600 12.5px/1 var(--f-tx);letter-spacing:0;text-transform:none}
.mis-vacio{padding:6px 18px 16px;font-size:12.5px;color:var(--t3);display:flex;align-items:center;gap:8px}

/* Siguiente paso: qué hay que hacer con este registro, dicho en una línea */
.paso{display:flex;align-items:center;gap:12px;padding:10px 14px;margin-bottom:14px;
  border:1px solid var(--line);border-left:4px solid var(--idle);border-radius:var(--r);background:var(--paper)}
.paso .p-t{font:600 13px/1.3 var(--f-ui);letter-spacing:.03em}
.paso .p-d{font-size:12.5px;color:var(--t2)}
.paso .sp{flex:1}
.paso.warn{border-left-color:var(--warn);background:var(--warn-bg)}
.paso.hold{border-left-color:var(--hold);background:var(--hold-bg)}
.paso.stop{border-left-color:var(--stop);background:var(--stop-bg)}
.paso.ok{border-left-color:var(--ok);background:var(--ok-bg)}

/* Menú «Más»: acciones poco frecuentes o destructivas, fuera de la vista */
.mas{position:relative;display:inline-block}
.mas>summary{list-style:none;cursor:pointer}
.mas>summary::-webkit-details-marker{display:none}
.mas-m{position:absolute;right:0;top:calc(100% + 4px);z-index:40;min-width:220px;padding:5px;
  background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r);box-shadow:var(--sh-2)}
.mas-m button,.mas-m a{display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;border:0;background:none;
  text-align:left;font-size:13px;color:var(--t1);border-radius:var(--r);cursor:pointer}
.mas-m button:hover,.mas-m a:hover{background:var(--paper-2);text-decoration:none}
.mas-m .peligro{color:var(--stop)}
.mas-m hr{border:0;border-top:1px solid var(--line);margin:4px 0}
.mas-m small{display:block;color:var(--t3);font-size:11px;line-height:1.3}

/* Cajetín del registro: datos que se pueden asignar sin salir de la hoja */
.cajetin .v.editable{cursor:pointer;border-bottom:1px dashed var(--brand-m)}
.cajetin .v.editable:hover{color:var(--brand)}
.cajetin .v.editable.vacio{color:var(--acento-txt)}

/* Llenado sobre la maqueta: las celdas por llenar se ven, sin importar el
   fondo que traiga el Excel. Solo en pantalla: la impresión usa otro modo. */
/* El amarillo anterior (#FFFBEF) apenas se distinguía del blanco (1,03:1): no
   se sabía qué faltaba. Ahora la celda vacía lleva un tono claro y un filete. */
#maqueta td.inp[contenteditable="true"]:not(.lleno){background-color:#FFF1C9 !important;box-shadow:inset 0 0 0 1px #D9A640}
#maqueta td.inp[contenteditable="true"]:not(.lleno):hover{background-color:#FFE7A6 !important}
#maqueta td.inp[contenteditable="true"]:focus{background-color:#FFFDF0 !important;
  outline:2px solid var(--brand);outline-offset:-2px}
.llenado-info{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px;font-size:12.5px;color:var(--t2)}
.llenado-info .bar{width:160px}
.llenado-info .mk{display:inline-block;width:14px;height:10px;background:#FFF1C9;border:1px solid #D9A640;vertical-align:middle;margin-right:4px}

/* Panel: disciplinas sin registros, plegadas en una línea */
.tbl tr.plegadas td{font-size:12px;color:var(--t3);background:var(--paper-2)}

@media print{ .bandejas,.paso,.mas,.llenado-info{display:none!important} }

/* Menú lateral: disciplinas sin registros, plegadas */
/* Atenuado con color y no con opacidad: al 70 % el rótulo no llegaba al
   contraste mínimo sobre el azul del menú. */
.rail-mas>summary{list-style:none;cursor:pointer;color:#9DB2CC}
.rail-mas>summary::-webkit-details-marker{display:none}
.rail-mas>summary:hover{color:#fff}

/* Valores medidos: el que no cumple el criterio se ve sin leer la columna */
.tbl tr.fila-fuera td{background:var(--stop-bg)}
.tbl tr.fila-fuera td.strong{color:var(--stop)}
.toast>div.warn{border-left-color:var(--warn)}

/* ── Valores medidos: criterio y gráfico de distribución ─────────── */
.criterio{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:10px 14px;margin-bottom:16px;
  background:var(--paper);border:1px solid var(--line);border-left:4px solid var(--line-2);border-radius:var(--r);font-size:13px}
.criterio.guardado{border-left-color:var(--ok)}
.criterio.distinto{border-left-color:var(--warn)}
.criterio .sp{flex:1}
.graf-val{margin-bottom:16px}
.graf-val .card-b{position:relative}
.graf-val svg{width:100%;height:auto;display:block;overflow:visible}
.graf-val .g-rej{stroke:#EDEFF2;stroke-width:1}
.graf-val .g-eje{fill:var(--t3);font:11px var(--f-mo)}
.graf-val .g-banda{fill:#2E6DB4;fill-opacity:.08}
.graf-val .g-lim{stroke:var(--t3);stroke-width:1}
.graf-val .g-lim-t{fill:var(--t2);font:600 11px var(--f-ui);letter-spacing:.04em}
.graf-val .p-ok{fill:#2E6DB4;stroke:#fff;stroke-width:2}
.graf-val .p-no{fill:#B32B23;stroke:#fff;stroke-width:2}
.graf-val .p-hit{fill:transparent;cursor:pointer}
.graf-val a:focus-visible .p-hit{stroke:var(--brand);stroke-width:2}
.graf-val .g-tip{position:absolute;z-index:5;pointer-events:none;padding:5px 9px;border-radius:var(--r);
  background:var(--ink);color:#fff;font:500 12px/1.3 var(--f-tx);white-space:nowrap;box-shadow:var(--sh-2)}
.graf-ley{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--t2)}
.graf-ley i{display:inline-block;width:10px;height:10px;margin-left:8px}
.graf-ley i.p-ok{background:#2E6DB4;border-radius:50%}
.graf-ley i.p-no{background:#B32B23;transform:rotate(45deg) scale(.85)}
@media print{ .graf-val .g-tip{display:none} }

/* ── Trabajo en campo: indicador de la barra superior ─────────────── */
.campo-est{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 11px;margin-right:8px;border-radius:var(--r-xl);
  border:1px solid var(--line-2);background:var(--paper);color:var(--t2);font:600 11.5px/1 var(--f-ui);letter-spacing:.04em;white-space:nowrap}
.campo-est::before{content:'';width:7px;height:7px;border-radius:50%;background:var(--ok)}
.campo-est:hover{text-decoration:none;border-color:var(--t4)}
.campo-est.pendiente{border-color:var(--warn-br);background:var(--warn-bg);color:var(--warn-tx)}
.campo-est.pendiente::before{background:var(--warn)}
.campo-est.retenido{border-color:var(--stop-br);background:var(--stop-bg);color:var(--stop)}
.campo-est.retenido::before{background:var(--stop)}
.campo-est.sin-red{border-color:var(--ink);background:var(--ink);color:#fff}
.campo-est.sin-red::before{background:var(--acento)}
@media print{.campo-est{display:none!important}}

/* ── Super Administración (CICOM) ────────────────────────────────────
   Réplica de la cabecera y la organización del sistema anterior, para que el
   superadministrador reconozca la pantalla: banda azul con filete naranja,
   pestañas Proyectos · Empresas · Usuarios, proyectos agrupados por empresa. */
.sa-cab{position:relative;overflow:hidden;margin:0;padding:18px 24px;border-radius:var(--r-lg) var(--r-lg) 0 0;color:#fff;
  background:linear-gradient(135deg,#244a75 0%,#1E3A5F 55%,#142943 100%);border-bottom:3px solid #d97e33;
  box-shadow:0 8px 22px -10px rgba(20,41,63,.5);display:flex;align-items:center;gap:14px}
.sa-cab::after{content:'';position:absolute;right:-30px;top:-40px;width:170px;height:170px;border-radius:50%;
  background:rgba(255,255,255,.08);pointer-events:none}
.sa-cab .ico{width:36px;height:36px;border-radius:var(--r);background:var(--acento);display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}
.sa-cab h1{font:700 19px/1.2 var(--f-ui);letter-spacing:.01em;color:#fff}
.sa-cab small{font:400 12px/1.4 var(--f-tx);opacity:.85}
.sa-cab .sp{flex:1}
.sa-cab .quien{position:relative;z-index:1;font-size:12px;opacity:.9;display:flex;align-items:center;gap:8px}
.sa-cab .quien .badge{background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.32);color:#fff}
.sa-nav{display:flex;gap:0;margin:0 0 20px;padding:0 16px;background:var(--paper);border:1px solid var(--line);border-top:0;border-radius:0 0 12px 12px;overflow-x:auto}
.sa-nav a{display:inline-flex;align-items:center;gap:7px;padding:12px 18px;font:500 13px/1 var(--f-ui);letter-spacing:.02em;
  color:var(--t3);border-bottom:2px solid transparent;white-space:nowrap;text-decoration:none}
.sa-nav a:hover{color:var(--t1);background:var(--paper-2);text-decoration:none}
.sa-nav a.on{color:var(--brand);border-bottom-color:var(--brand);font-weight:600}
.sa-cont{max-width:1180px;margin:0 auto}
.sa-tit{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:16px}
.sa-tit h3{display:flex;align-items:center;gap:10px;font:700 16px/1.3 var(--f-ui);letter-spacing:.02em}
.sa-tit h3 .ico{width:30px;height:30px;border-radius:var(--r-lg);background:var(--brand-l);color:var(--brand);display:inline-flex;align-items:center;justify-content:center}
.sa-tit .sp{flex:1}
.sa-res{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin-bottom:18px}
.sa-res .b{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);padding:16px 18px;box-shadow:var(--sh-1)}
.sa-res .b .k{font:400 12.5px/1.3 var(--f-tx);letter-spacing:0;text-transform:none;color:var(--t3)}
.sa-res .b .v{font:500 32px/1.1 var(--f-ui);margin-top:2px;color:var(--brand)}
.sa-grupo{margin-bottom:26px}
.sa-grupo-h{display:flex;align-items:center;gap:10px;padding:0 2px 10px;margin-bottom:14px;background:none;
  border:0;border-bottom:1px solid var(--line);border-radius:0;box-shadow:none}
.sa-grupo-h .ico{width:26px;height:26px;border-radius:var(--r);background:var(--brand-l);color:var(--brand);display:inline-flex;align-items:center;justify-content:center}
.sa-grupo-h h4{font:700 14px/1.2 var(--f-ui);letter-spacing:.02em}
.sa-grupo-h img{height:22px;width:auto;max-width:80px;object-fit:contain}
.sa-grupo-h.sin .ico{background:var(--idle-bg);color:var(--t3)}
.sa-grupo-h.inactiva{opacity:.75}
.sa-cards{display:grid;gap:18px;grid-template-columns:repeat(2,minmax(0,1fr))}
@media (max-width:900px){.sa-cards{grid-template-columns:1fr}}
.sa-card{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;
  box-shadow:0 2px 8px rgba(15,23,42,.04);transition:box-shadow var(--mov);display:flex;flex-direction:column}
.sa-card:hover{box-shadow:var(--sh-2)}
.sa-card-h{background:var(--paper);color:var(--t1);padding:15px 18px 12px;display:flex;align-items:center;gap:10px}
.sa-card-h h5{font:600 15px/1.25 var(--f-ui);letter-spacing:.01em;flex:1;color:var(--t1)}
.sa-card-h .badge.act{background:var(--ok-bg);color:var(--ok)}
.sa-card-b{padding:2px 18px 14px;font-size:13px;color:var(--t2);display:grid;gap:5px;flex:1;border-top:1px solid var(--linea-suave)}
.sa-card-b b{color:var(--t1);font-weight:600}
.sa-card-b code{font:500 12px/1 var(--f-mo);background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r);padding:2px 6px}
.sa-card-f{display:flex;gap:8px;flex-wrap:wrap;padding:12px 18px;background:var(--paper-2);border-top:1px solid var(--linea-suave)}
.sa-card-f .sp{flex:1}
.sa-logo{width:64px;height:40px;display:flex;align-items:center;justify-content:center;border:1px solid var(--line);border-radius:var(--r);background:#fff;overflow:hidden}
.sa-logo img{max-width:100%;max-height:100%;object-fit:contain}
.sa-logo.vacio{color:var(--t4)}
.sa-toggle{cursor:pointer;border:0}
.sa-preview{display:flex;align-items:center;gap:12px}
@media (max-width:720px){.sa-cab{padding:14px 16px}.sa-cab .quien{display:none}.sa-cab h1{font-size:17px}.sa-nav a{padding:11px 12px}}
.sa-preview .sa-logo{width:120px;height:64px}

/* ═════════════════════════════════════════════════════════════════
   ACCESIBILIDAD Y USO EN CAMPO
   Correcciones de la auditoría de interfaz: contraste, áreas de toque,
   teclado, teléfono. Van al final para imponerse a los tramos anteriores
   sin tener que reescribirlos.
   ═════════════════════════════════════════════════════════════════ */

/* Rótulos del cajetín: en pantalla a tamaño legible. En papel se quedan como
   estaban, porque el cajetín impreso tiene su medida contada. */
@media screen{
  .cajetin .k{font-size:11px;letter-spacing:0}
}

/* ── En el teléfono ──────────────────────────────────────────────
   Dos cosas se salían de la pantalla: el grupo de bandejas (ocho, en una
   fila) y el cajetín del registro (seis columnas). El primero pasa a
   deslizarse de lado; el segundo, a dos columnas. */
@media (max-width:860px){
  .bandejas{display:flex;flex-wrap:nowrap;max-width:100%;overflow-x:auto;
    -webkit-overflow-scrolling:touch;scrollbar-width:none}
  .bandejas::-webkit-scrollbar{display:none}
  .bandeja{flex:none}
  .cajetin{grid-auto-flow:row;grid-template-columns:repeat(2,minmax(0,1fr))}
  .cajetin>div{border-right:1px solid var(--linea-suave);border-bottom:1px solid var(--linea-suave)}
  .cajetin>div:nth-child(2n){border-right:0}
  .tabs{max-width:100%}
}

/* Enlaces dentro de un párrafo: el color solo no basta para distinguirlos
   del texto (y quien no distingue colores no los ve). */
.aviso a,.hint a,.crumb a,.empty p a,p.small a{text-decoration:underline;text-underline-offset:2px}

/* ── Saltar al contenido ─────────────────────────────────────────
   Sin él, con teclado había que pasar por los catorce enlaces del menú
   antes de llegar al primer campo de la página. */
.saltar{position:fixed;left:10px;top:-60px;z-index:200;padding:10px 16px;border-radius:var(--r);
  background:var(--brand);color:#fff;font:600 13px/1.2 var(--f-ui);letter-spacing:.04em;
  transition:top var(--mov-2)}
.saltar:focus{top:10px;color:#fff;text-decoration:none;box-shadow:var(--sh-3)}
.main:focus{outline:none}

/* ── Barra superior: el cajetín cede antes que la búsqueda y la campana ── */
@media (max-width:1280px){ .topbar .cajetin .c-sector,.topbar .cajetin .c-fecha{display:none} }
@media (max-width:1024px){ .topbar .cajetin{display:none} .topbar h1{flex:0 1 auto} }

/* ── Menú lateral en teléfono y tableta ──────────────────────────── */
.rail-velo{position:fixed;inset:0;z-index:55;background:rgba(13,17,23,.45)}
@media (max-width:860px){
  /* Cerrado no solo se aparta: deja de existir para el teclado y el lector
     de pantalla, que antes recorrían un menú invisible. */
  .rail{visibility:hidden;transition:transform var(--mov-2),visibility var(--mov-2) linear var(--mov)}
  .rail.open{visibility:visible;transition:transform var(--mov-2)}
}
@media (min-width:861px){ .rail-velo{display:none!important} }
/* Con el menú abierto la mascota no asoma por encima del velo */
body:has(#rail.open) .ia{display:none}

/* ── Avisos flotantes ────────────────────────────────────────────── */
.toast>div{display:flex;align-items:flex-start;gap:10px}
.toast>div>span{flex:1;min-width:0}
.toast .t-x{flex:none;margin:-4px -8px -4px 0;width:30px;height:30px;border:0;border-radius:50%;
  background:rgba(255,255,255,.12);color:#fff;cursor:pointer;font-size:13px;line-height:1}
.toast .t-x:hover{background:rgba(255,255,255,.26)}
/* Con la mascota a la vista, el aviso sale a su izquierda y no debajo de ella */
body:has(#ia:not([hidden])[data-estado="visible"]) .toast{right:150px}
@media (max-width:600px){
  /* En el teléfono, arriba: abajo lo tapa el pulgar y ahí vive la mascota */
  .toast,body:has(#ia:not([hidden])[data-estado="visible"]) .toast{
    top:calc(var(--top) + 8px);bottom:auto;left:10px;right:10px}
  .toast>div{max-width:none}
}

/* ── Mascota ─────────────────────────────────────────────────────────
   Deja sitio al final de la página para que lo último no quede debajo. */
/* La reserva sigue a la mascota: es su alto (138) más lo que la separa del
   canto. Al apoyarla en el borde, ese hueco de 12 px dejó de existir y la
   reserva baja con ella; si no, quedaba un espacio en blanco al final de cada
   página que ya no tapaba nadie. */
body:has(#ia:not([hidden])[data-estado="visible"]) .main{padding-bottom:174px}
body:has(#ia:not([hidden])[data-estado="oculto"]) .main{padding-bottom:72px}
@media (max-width:860px){
  .ia-fab{width:97px;height:95px}
  .ia-panel{right:0;bottom:78px;width:calc(100vw - 24px)}
  body:has(#ia:not([hidden])[data-estado="visible"]) .main{padding-bottom:109px}
  /* La pestaña baja a la esquina, donde queda el hueco reservado */
  .ia-tab{bottom:12px}
}

/* ── Registros: bandejas y lista en el teléfono ──────────────────── */
@media (max-width:600px){
  /* Una sola fila que se desplaza: en cuatro filas, las bandejas se comían
     170 px antes de ver el primer registro. */
  .bandejas{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;
    scrollbar-width:thin;padding-bottom:4px;margin-left:-2px;margin-right:-2px}
  .bandejas .bandeja{flex:none}
  .bandejas .sp{display:none}

  /* Cada registro como tarjeta: arriba qué es y en qué estado está, abajo
     plazo, firmas y avance. En tabla solo se veían dos de las ocho columnas. */
  .tbl-reg,.tbl-reg tbody{display:block;width:100%;min-width:0}
  .tbl-reg thead{display:none}
  .tbl-reg tr{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:5px 12px;
    align-items:center;padding:11px 12px;border-bottom:1px solid var(--line)}
  .tbl-reg tbody tr:last-child{border-bottom:0}
  /* El canto de estado, en el borde de la TARJETA y no en la celda.
     En tabla la celda tiene 14 px de relleno y el canto cabe dentro; aquí la
     celda no tiene ninguno, así que la franja se dibujaba encima del código
     del registro —«PR-CIV-005-0004» con una barra morada atravesando la P—.
     En la tarjeta es un borde de verdad: ocupa su sitio y nada se le monta
     encima. */
  /* El `:has(td)` no filtra nada: está para pesar más que las reglas de canto
     de la sección de tablas, que llevan `:has(.badge-…)` y, sin esto, ganaban
     por especificidad aunque estén más arriba en el archivo. Sin él la franja
     se seguía dibujando sobre el texto por mucho que la tarjeta ya tuviera su
     borde. */
  table.tbl.tbl-reg tbody tr:has(td) td:first-child{box-shadow:none}
  .tbl-reg tbody tr{border-left:3px solid var(--idle-br)}
  .tbl-reg tbody tr:has(.badge-ok){border-left-color:var(--ok)}
  .tbl-reg tbody tr:has(.badge-warn){border-left-color:var(--warn)}
  .tbl-reg tbody tr:has(.badge-stop){border-left-color:var(--stop)}
  .tbl-reg tbody tr:has(.badge-hold){border-left-color:var(--hold)}
  .tbl-reg tbody tr:has(.badge-brand){border-left-color:var(--brand)}
  /* «table.tbl» en el selector: tiene que ganarle a table.tbl td (relleno y filete) */
  table.tbl.tbl-reg td{display:block;padding:0;border:0;white-space:normal;min-width:0}
  .tbl-reg td .tiny{max-width:none}
  .tbl-reg .c-reg{grid-column:1;grid-row:1}
  .tbl-reg .c-est{grid-column:2;grid-row:1;align-self:start}
  .tbl-reg .c-tag{grid-column:1;grid-row:2}
  .tbl-reg .c-firm{grid-column:2;grid-row:2;text-align:right}
  .tbl-reg .c-fecha{grid-column:1;grid-row:3}
  .tbl-reg .c-av{grid-column:2;grid-row:3;width:130px}
  .tbl-reg .c-resp{grid-column:1 / -1;grid-row:4}
  table.tbl.tbl-reg .c-disc{display:none}
  .tbl-reg td[data-l]::before{content:attr(data-l) ' ';font:600 10.5px/1 var(--f-ui);
    letter-spacing:.1em;text-transform:uppercase;color:var(--t3)}
}

/* ── Tablas con acciones por fila ────────────────────────────────────
   Con cuatro botones en fila la última columna se salía de la tarjeta
   (usuarios del sistema, a 1366 px). En dos columnas caben sin desplazar. */
.tbl td.w1>.btns{flex-wrap:wrap;justify-content:flex-end;width:max-content;max-width:190px;margin-left:auto}
/* Y las cabeceras pueden partirse en dos líneas cuando falta ancho: en
   mayúsculas espaciadas, «ÚLTIMO ACCESO» o «PROYECTOS» sobre una columna de un
   dígito ensanchaban la tabla más que los propios datos. En tableta y teléfono
   la tabla se desplaza y la cabecera sigue en una línea (tramo ≤860px). */
@media (min-width:861px){ table.tbl th{white-space:normal} }

/* Región desplazable enfocable: se señala al recibir el foco del teclado */
.tbl-wrap[tabindex]:focus-visible,.card-b[tabindex]:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}

/* ── Inicio de sesión en teléfono y tableta: el formulario, a la vista ── */
@media (max-width:980px){
  .login-art{padding:18px 20px 16px;justify-content:flex-start}
  .login-art .login-marca{margin-bottom:10px}
  .login-art .rail-mark.grande .marca-fig{max-width:170px}
  .login-art h1{font-size:20px;max-width:none}
  .login-art p,.login-art .cajetin{display:none}
  .login-form{padding:24px 20px 32px;place-items:start center}
}

/* ── Pantallas táctiles: áreas de toque de 44 px ─────────────────────
   «pointer:coarse» y no «hover:none»: algunos teléfonos declaran hover y
   la regla anterior no llegaba a aplicarse. */
@media (pointer:coarse){
  .btn,.btn-sm,.bandeja,.tab,.rail-a,.campana,.burger{min-height:44px}
  .campana{min-width:44px}
  .rail-a{padding-top:10px;padding-bottom:10px}
  input[type=checkbox],input[type=radio]{width:22px;height:22px;flex:none}
  .fs-check{min-height:44px;align-items:center}
}

/* Panel: en pantallas estrechas «Tu trabajo» va primero (ver index.php) */
.panel-orden{display:flex;flex-direction:column}
@media (max-width:860px){ .panel-orden > .tu-trabajo{order:-1;margin-bottom:12px} }

/* ── Versión Laravel ─────────────────────────────────────────────── */
/* Cerrar sesión es un formulario (POST, con token), no un enlace: se pinta igual que el lápiz de al lado. */
.rail-salir{background:none;border:0;padding:0;cursor:pointer;color:#9DB2CC;display:inline-flex;align-items:center;justify-content:center;min-width:32px;min-height:32px}
.rail-salir:hover,.rail-salir:focus-visible{color:#fff}
.etapa{border:1px dashed var(--line-2);border-radius:var(--r-lg);padding:14px 16px;background:var(--paper)}
.etapa h4{margin:0 0 4px;font:600 13px/1.3 var(--f-ui)}
.etapa ul{margin:6px 0 0 18px;padding:0}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.pag{display:flex;gap:6px;align-items:center;justify-content:flex-end;padding:10px 16px;flex-wrap:wrap}
/* Texto solo para lectores de pantalla */
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.rail-user > div:nth-child(2){flex:1;min-width:0}
.rail-user .rl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chips .badge{white-space:normal;text-align:left;max-width:100%}

/* ═══════════════════════════════════════════════════════════════════
   CICOM-UI-001-QA Rev. 0 · IDENTIDAD VISUAL DEL SISTEMA DE CALIDAD
   ═══════════════════════════════════════════════════════════════════
   Tres sistemas CICOM comparten servidor en subdominios distintos
   (4D azul, QA verde azulado, PC terracota). Quien abre una pestaña
   tiene que saber en cuál está ANTES de escribir su contraseña, y
   seguir sabiéndolo después. Lo resuelven dos cosas: la sigla y el
   color.

   Va al final del archivo a propósito: todo lo de este bloque es
   presentación y nada de arriba se ha borrado, así que quitar la
   identidad es borrar desde esta línea. Lo que cambia es el MARCO
   —login, barra lateral, encabezado—; el contenido de las pantallas
   sigue con la paleta de calidad, porque el verde del sistema no es
   un estado y no debe confundirse con «conforme».
   ═══════════════════════════════════════════════════════════════════ */

:root{
  --sis-color:#1F7A6E;    /* encabezado, sigla, botón de acceso */
  --sis-oscuro:#145B52;   /* el mismo color como texto sobre claro: 6,4:1 */
  --sis-tinte:#DFF0EC;    /* panel del login, bloque de la barra, ítem activo */
  --sis-borde:#B3DACF;    /* borde sobre el tinte */
  --sis-linea:#E1E5EB;    /* borde de la barra blanca y de sus cajas */
  --tinta:#14243A;        /* títulos */

  /* La barra ya no es azul oscuro: el encabezado crece para que el
     título quepa en Barlow 22 y la sigla respire. Las posiciones
     pegajosas del sistema se calculan con esta variable, así que
     cambiarla aquí las mueve todas. */
  --top:60px;
}

/* ── La sigla de fondo ───────────────────────────────────────────────
   Va en «content», no en el marcado: así no existe como texto, no la
   lee ningún lector de pantalla, no se selecciona al arrastrar y no
   aparece como un texto de contraste 1,1:1 en la auditoría —que es lo
   que pasó cuando era un <span> con aria-hidden—. */
.login-art::before,
.rail-mark::before{
  content:'QA';position:absolute;z-index:0;
  font:700 420px/1 var(--f-ui);color:var(--sis-color);opacity:.09;
  background:none;mask-image:none;pointer-events:none;
}

/* ═══ INICIO DE SESIÓN · variante E ══════════════════════════════ */
/* 53 / 47, no «760 px y lo que sobre»: a 1440 da los 760 px de la maqueta,
   pero en un monitor de 1920 el panel de identidad crece con la pantalla en
   vez de dejar mil píxeles de blanco alrededor del formulario. */
.login-wrap{grid-template-columns:53fr 47fr}
.login-art{
  background:var(--sis-tinte);color:var(--t2);
  padding:72px 64px 56px;
}
/* La trama de plano era del fondo oscuro; ese mismo pseudo-elemento
   pasa a ser la sigla. */
.login-art::before{inset:auto;right:-40px;bottom:60px;opacity:.09}

.qa-ident{display:flex;align-items:center;gap:20px;position:relative;margin-bottom:88px}
.qa-sigla{
  width:88px;height:88px;flex:none;background:var(--sis-color);border-radius:18px;
  display:grid;place-items:center;color:#fff;font:700 44px/1 var(--f-ui);
}
.qa-ident-t{display:flex;flex-direction:column;min-width:0}
.qa-nombre{display:block;font:700 34px/1 var(--f-ui);color:var(--tinta)}
.qa-sol{display:flex;align-items:center;gap:8px;margin-top:6px;font-size:13px;color:var(--t3)}
.qa-sol img{height:26px;width:auto;display:block}

.login-art h1{color:var(--tinta);font-size:52px;line-height:1.08;max-width:11em}
.login-art h1 em{color:var(--sis-color)}
.login-art p{color:var(--t2);font-size:17px;line-height:1.6;max-width:580px;margin-top:24px}

/* La franja de datos es el cajetín del sistema sobre fondo claro. Aquí
   —y solo aquí— el rótulo va en mayúsculas monoespaciadas: es la franja
   de un plano, no una tarjeta de pantalla. */
.login-art .cajetin{
  border-color:var(--sis-borde);background:rgba(255,255,255,.55);
  box-shadow:none;border-radius:4px;margin-top:0;align-self:flex-start;max-width:none;
}
.login-art .cajetin>div{border-right-color:var(--sis-borde);padding:10px 16px}
.login-art .cajetin>div:first-child::before,
.login-art .cajetin>div:first-child::after{border-color:var(--sis-color)}
.login-art .cajetin .k{
  font:500 10px/1.3 var(--f-mo);letter-spacing:.12em;text-transform:uppercase;
  color:var(--sis-oscuro);margin-bottom:4px;
}
.login-art .cajetin .v{font:600 13px/1.3 var(--f-mo);color:var(--tinta)}

/* El acceso va dos tallas por debajo de la maqueta. A 1440 —y más aún en un
   monitor ancho— el bloque de 420 px con texto de 15-17 px se comía el panel:
   al lado de una frase de 52 px, un formulario grande no se lee como
   importante, se lee como desbordado. A 340 px, con el cuerpo en la medida
   del resto del sistema y los rótulos espaciados en vez de gruesos, el peso
   visual vuelve al lado izquierdo, que es el que identifica el sistema.
   Entrar son dos campos: no necesita ocupar media pantalla para entenderse. */
.login-form{position:relative;padding:40px 24px}
.login-form::before{content:'';position:absolute;top:0;left:0;right:0;height:6px;background:var(--sis-color)}
.login-form form{max-width:340px;gap:13px}

.qa-cab{display:flex;flex-direction:column;gap:7px;margin-bottom:2px}
.qa-pil{
  align-self:flex-start;display:inline-flex;align-items:center;gap:6px;
  background:var(--sis-tinte);color:var(--sis-oscuro);border-radius:var(--r-pill);
  padding:3px 10px 3px 4px;font:600 11.5px/1 var(--f-tx);
}
.qa-pil b{
  width:18px;height:18px;flex:none;border-radius:5px;background:var(--sis-color);
  color:#fff;display:grid;place-items:center;font:700 10px/1 var(--f-ui);
}
/* Condensada y en mayúsculas, el aire entre letras hace el trabajo que
   antes hacía el tamaño. */
.login-form h2{
  font:700 21px/1.15 var(--f-ui);letter-spacing:.07em;text-transform:uppercase;color:var(--tinta);
}
.login-form .sub{font-size:12.5px;line-height:1.55;color:var(--t3);margin-top:0}
.login-form .sub b{color:var(--tinta);font-weight:600}

.login-form .f-g{gap:4px}
.login-form .f-g label{
  font:600 10px/1.35 var(--f-tx);letter-spacing:.11em;text-transform:uppercase;color:var(--t3);
}
.login-form .in{padding:9px 12px;font-size:14px;background:var(--canvas);border-color:var(--line-2);border-radius:4px}
.login-form .in::placeholder{color:var(--t4)}
.login-form .in:focus{border-color:var(--sis-color);box-shadow:0 0 0 3px var(--sis-borde)}

/* El botón de acceso lleva el color del sistema y su nombre: es la
   última oportunidad de darse cuenta de que este no es su sistema. */
.qa-entrar{
  background:var(--sis-color);border-radius:4px;height:auto;padding:11px;margin-top:2px;
  font:700 14px/1 var(--f-ui);letter-spacing:.07em;text-transform:uppercase;
}
.qa-entrar:hover{background:var(--sis-oscuro)}
.qa-entrar:focus-visible{box-shadow:0 0 0 3px rgba(31,122,110,.35)}

.qa-prot{
  padding:9px 12px;background:var(--linea-suave);border-left:3px solid var(--sis-color);
  border-radius:4px;font-size:11.5px;line-height:1.55;color:var(--t2);
}
.qa-pie{
  padding-top:13px;border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:6px;font-size:11.5px;line-height:1.5;color:var(--t3);
}
.qa-pie a{font-weight:600;color:var(--sis-oscuro)}
.qa-pie a:hover{color:var(--sis-color)}

/* ── Pantalla angosta (§4.4) ─────────────────────────────────────────
   El panel pasa arriba como franja: queda la identidad —sigla y
   nombre—, que es lo único imprescindible, y se van la frase, la
   descripción y la franja de datos. El acceso ocupa el ancho. */
@media (max-width:900px){
  .login-wrap{grid-template-columns:1fr;grid-template-rows:auto 1fr}
  .login-art{
    min-height:200px;padding:28px 24px;justify-content:center;
  }
  .login-art h1,.login-art p,.login-art .cajetin{display:none}
  .login-art::before{font-size:200px;right:-20px;bottom:-30px}
  .qa-ident{margin-bottom:0;gap:14px}
  .qa-sigla{width:58px;height:58px;border-radius:12px;font-size:30px}
  .qa-nombre{font-size:25px}
  .qa-sol img{height:20px}
  .login-form{padding:24px}
  .login-form form{max-width:none}
  .login-form h2{font-size:21px}
  /* En el teléfono los campos vuelven a 16 px: por debajo de esa medida,
     Safari de iOS amplía la página al tocar el campo y deja el formulario
     descuadrado. En el escritorio esa regla no existe y 14 px se lee mejor. */
  .login-form .in{font-size:16px;padding:11px 12px}
}

/* ═══ BARRA LATERAL BLANCA ═══════════════════════════════════════ */
.rail{background:var(--paper);border-right:1px solid var(--sis-linea);scrollbar-color:var(--line-2) transparent}
.rail::-webkit-scrollbar-thumb{background:var(--line-2)}
.rail-top{padding:0;border-bottom:0}

/* El bloque superior sustituye al logotipo suelto: cuadro con la sigla,
   nombre del sistema y, debajo, de quién es el sistema. De un vistazo
   contesta «¿dónde estoy?» sin leer el menú. */
.rail-mark{
  display:flex;align-items:center;gap:14px;background:var(--sis-tinte);
  border-radius:0;padding:22px 20px;position:relative;overflow:hidden;
}
.rail-mark:hover{filter:none;background:#D6EBE6}
.rail-mark::before{right:-10px;top:-18px;font-size:120px}
.rail-mark .qa-sigla{
  width:52px;height:52px;border-radius:12px;font-size:26px;position:relative;
}
.rail-marca-t{position:relative;display:flex;flex-direction:column;gap:4px;min-width:0}
/* La barra mide 230 px: a 21 px el nombre parte en dos y queda pegado a la
   sigla de fondo. A 19 px y condensada cabe «Sistema de» + «Calidad» holgado. */
.rail-sis{font:700 19px/1.05 var(--f-ui);color:var(--tinta)}
.rail-marca-t img{height:20px;width:auto;align-self:flex-start;display:block}

.rail-proj{
  margin:16px;padding:12px 14px;background:var(--canvas);
  border:1px solid var(--sis-linea);border-radius:var(--r);
}
.rail-proj .k{font:500 10px/1.3 var(--f-mo);letter-spacing:.12em;color:var(--sis-oscuro)}
.rail-proj .v{font:600 14px/1.35 var(--f-tx);color:var(--tinta);margin-top:2px}
.rail-proj .tiny{color:var(--t3)!important}
.rail-proj a{font:500 12px/1 var(--f-tx);color:var(--sis-oscuro);margin-top:4px}
.rail-proj a:hover{color:var(--sis-color)}

.rail-grp>h6{font:500 10px/1 var(--f-mo);letter-spacing:.14em;color:var(--t4)}
.rail-a{color:var(--t2);font-weight:400}
.rail-a:hover{background:var(--canvas);color:var(--t1)}
/* El activo ya no se marca con una pestaña naranja sobre azul: sobre
   blanco basta el tinte del sistema, que además lo liga al encabezado. */
.rail-a.on{background:var(--sis-tinte);color:var(--sis-oscuro);font-weight:600}
.rail-a.on::before{display:none}
.rail-a .ic{opacity:.6}
.rail-a.on .ic{opacity:1}
.rail-a .n{background:var(--idle-bg);color:var(--idle-tx)}
.rail-a.on .n{background:rgba(20,91,82,.12);color:var(--sis-oscuro)}
.rail-mas>summary{color:var(--t3)}
.rail-mas>summary:hover{color:var(--t1)}

.rail-foot{border-top:1px solid var(--sis-linea)}
.rail-user .av{background:var(--sis-color);border-radius:50%;font:600 12px/1 var(--f-tx)}
.rail-user .nm{color:var(--tinta)}
.rail-user .rl{color:var(--t3)}
.rail-ver{color:var(--t3)}
.rail-user a,.rail-salir{color:var(--t3)}
.rail-user a:hover,.rail-salir:hover,.rail-salir:focus-visible{color:var(--sis-oscuro)}

/* ═══ ENCABEZADO EN EL COLOR DEL SISTEMA ═════════════════════════
   Es la banda que se ve en toda pantalla del sistema. Por eso lleva el
   color: no decora, identifica. Todo lo que vive dentro pasa a blanco. */
.topbar{background:var(--sis-color);border-bottom:0;color:#fff;gap:18px;padding:0 24px}
.topbar h1{font:700 22px/1.2 var(--f-ui);letter-spacing:0;color:#fff}
.topbar .crumb{color:rgba(255,255,255,.8)}
/* Sobre el verde, el blanco al 85 % se queda en 4,2:1 (medido con axe en el
   cajetín de la barra). Al 95 % da 4,8:1 y la jerarquía la sigue marcando el
   tamaño: 22 px condensada el título, 12 px el dato. */
.topbar .cajetin .v,.topbar .cajetin .v.tx{color:rgba(255,255,255,.95)}
.topbar .cajetin>div{border-right-color:rgba(255,255,255,.22)}

/* El buscador se hunde en vez de aclararse. La maqueta lo pedía con fondo
   blanco al 16 %, pero sobre ese tono ni el texto blanco (3,8:1) ni el
   marcador llegan al 4,5:1 que exige el propio documento, y este campo se
   usa a pleno sol. Oscurecido un 16 %, el texto da 6,8:1 y el marcador al
   75 % que pide la maqueta, 4,6:1. El borde claro lo sigue dibujando. */
.topbar .buscador{
  background:rgba(0,0,0,.16);border-color:rgba(255,255,255,.34);
  color:#fff;border-radius:var(--r);
}
.topbar .buscador:focus-within{
  background:rgba(0,0,0,.22);border-color:#fff;box-shadow:0 0 0 3px rgba(255,255,255,.3);
}
.topbar .buscador input{color:#fff}
.topbar .buscador input::placeholder{color:rgba(255,255,255,.75)}
.topbar .buscador .ic{color:#fff;opacity:.9}
.topbar .buscador kbd{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.34);color:#fff}
/* El panel de resultados cuelga del encabezado pero es una superficie de
   página: vuelve al blanco con texto oscuro. */
.topbar .buscador-r{color:var(--t1)}

.topbar .campana{border-color:rgba(255,255,255,.3);color:#fff;background:rgba(255,255,255,.1)}
.topbar .campana:hover{background:rgba(255,255,255,.2);color:#fff}
.topbar .campana[aria-expanded="true"]{background:#fff;border-color:#fff;color:var(--sis-oscuro)}
.topbar .campana.urge{border-color:rgba(255,255,255,.55)}
.topbar .campana.urge .n{background:#fff;color:var(--stop)}
.topbar .alertas{color:var(--t1)}

.topbar .burger{color:#fff}
.topbar .burger:hover{background:rgba(255,255,255,.16);color:#fff}

/* El estado de campo es un aviso, no identidad: conserva su semántica,
   solo se le da un borde que se vea sobre el color. */
.topbar .campo-est{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.34);color:#fff}
.topbar .campo-est:hover{border-color:#fff}

/* El dominio, a la derecha: dice en qué sistema estás incluso en una
   captura de pantalla recortada. */
.qa-dom{
  flex:none;font:400 13px/1 var(--f-tx);color:rgba(255,255,255,.95);white-space:nowrap;
}
@media (max-width:1180px){ .qa-dom{display:none} }

/* La vuelta a CICOM, para quien entró desde el Núcleo. Sobre el verde del
   encabezado, así que va con el mismo tratamiento que lo demás de ahí: blanco
   translúcido, no el azul de acción, que en el marco no pinta nada. */
.qa-nucleo{
  flex:none;display:inline-flex;align-items:center;gap:6px;
  padding:5px 10px;border-radius:999px;text-decoration:none;white-space:nowrap;
  font:600 12px/1 var(--f-ui);letter-spacing:.04em;
  color:#fff;background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.28);
  transition:background var(--mov);
}
.qa-nucleo:hover{background:rgba(255,255,255,.26);text-decoration:none;color:#fff}

/* El anillo de foco general es azul; sobre el verde no se vería. */
.topbar a:focus-visible,.topbar button:focus-visible,.topbar input:focus-visible{
  box-shadow:0 0 0 3px rgba(255,255,255,.45);border-color:#fff;
}

@media (max-width:860px){
  .topbar{padding:0 14px;gap:10px}
  .topbar h1{font-size:19px}
  .rail{border-right:0}
  .rail.open{box-shadow:var(--sh-3)}
}

/* Impresión: el encabezado y la barra ya se ocultan; el papel no lleva
   el color del sistema porque el cajetín firmado manda. */
@media print{ .qa-fondo,.qa-dom{display:none!important} }

/* ── El resto del sistema que todavía era azul y naranja ─────────────
   La identidad no puede quedarse en el login y el encabezado: cualquier
   pantalla que vuelva a pintar la marca con el azul y el naranja de
   antes delata que el cambio está a medias. Lo que sigue es el
   inventario completo de esos sitios.

   Lo que NO cambia, y a propósito: el azul de marca (--brand) sigue
   siendo el color de ACCIÓN dentro del contenido —botón, enlace, barra
   de avance, fila señalada— y la paleta de calidad sigue siendo la de
   los ESTADOS. El verde del sistema identifica; no decide nada. */

/* Banda de Super Administración: era azul con filete naranja. */
.sa-cab{
  background:linear-gradient(135deg,#2A8F81 0%,var(--sis-color) 55%,var(--sis-oscuro) 100%);
  border-bottom:3px solid var(--sis-borde);
  box-shadow:0 8px 22px -10px rgba(20,91,82,.5);
}
.sa-cab .ico{background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.3)}
.sa-nav a.on{color:var(--sis-oscuro);border-bottom-color:var(--sis-color)}
.sa-tit h3 .ico,.sa-grupo-h .ico{background:var(--sis-tinte);color:var(--sis-oscuro)}

/* «Nuevo proyecto», «Nueva empresa», «Crear proyecto»: el naranja marcaba
   cuál era LA acción de la pantalla. Lo sigue marcando el color del
   sistema, que además ya no obliga a escribir en tinta oscura: blanco
   sobre el verde da 5,2:1, mientras que sobre el naranja se quedaba en
   3,1:1 y había que pintarlo de gris oscuro. */
.btn-acento{background:var(--sis-color);border-color:var(--sis-color);color:#fff}
.btn-acento:hover{background:var(--sis-oscuro);border-color:var(--sis-oscuro);color:#fff}

/* Cabecera del panel de la mascota: vuelve al azul marino de marca.
   Se pintó del verde del sistema cuando todo lo demás pasó a verde, y el
   resultado es un panel verde que se abre sobre una pantalla verde: deja de
   leerse como una pieza aparte y se confunde con el fondo. En azul se separa
   del sistema, y es además el azul del casco de Piper.
   El pie («Asistente del proyecto») recupera su gris azulado, que es el que
   se eligió para este azul; el blanco al 95 % era un parche para el verde. */
.ia-cab{background:var(--ink)}
.ia-tab:hover{background:var(--sis-tinte)}

/* Estado del trabajo en campo. Sobre el verde del encabezado, las tres
   variantes perdían su color al heredar el fondo translúcido: lo que
   avisa de que hay algo sin enviar no puede verse igual que lo normal.
   Cada una recupera su fondo claro, que además resalta sobre el verde. */
.topbar .campo-est.pendiente{background:var(--warn-bg);border-color:var(--warn-br);color:var(--warn-tx)}
.topbar .campo-est.pendiente::before{background:var(--warn)}
.topbar .campo-est.retenido{background:var(--stop-bg);border-color:var(--stop-br);color:var(--stop)}
.topbar .campo-est.retenido::before{background:var(--stop)}
.topbar .campo-est.sin-red{background:#fff;border-color:#fff;color:var(--sis-oscuro)}
.topbar .campo-est.sin-red::before{background:var(--sis-color)}

/* El salto al contenido (solo con teclado) también llevaba el azul. */
.saltar{background:var(--sis-color)}

/* ═══ CONECTOR DEL NÚCLEO · página de error ══════════════════════
   Quien la ve no eligió venir: pulsó «entrar a Calidad» en cuenta.cicom.app y
   el pase no sirvió. Una sola caja centrada, con la identidad del sistema para
   que sepa dónde está, y una salida clara de vuelta al Núcleo. */
.int-err{min-height:100vh;display:grid;place-items:center;padding:24px;background:var(--canvas)}
.int-err-caja{
  width:100%;max-width:460px;background:var(--paper);border:1px solid var(--sis-linea);
  border-radius:var(--r-lg);box-shadow:var(--sh-2);padding:30px 28px;text-align:center;
}
.int-err-caja .qa-ident{justify-content:center;margin-bottom:22px}
.int-err-caja h1{font:600 21px/1.25 var(--f-ui);color:var(--tinta);margin-bottom:16px}
/* El aviso vuelve a la izquierda: un párrafo centrado de tres renglones se lee peor */
.int-err-caja .aviso{text-align:left;margin-bottom:20px}
.int-err-caja .btn{width:100%;justify-content:center}
.int-err-pie{margin-top:16px;font:400 12.5px/1.5 var(--f-tx);color:var(--t3)}
.int-err-pie a{color:var(--sis-oscuro)}
