/* =====================================================================
   RYVAL · ui-v2.css — Rediseño UI-UX-01 (Fase 1: Inicio)
   Prototipo aprobado: ui-preview/ryval-v3.html

   REGLAS DE ESTE ARCHIVO (no negociables mientras dure la migración):
   1. styles.css NO SE TOCA. Esta hoja se carga DESPUÉS y solo sobrescribe.
      Una pantalla sin migrar queda byte-idéntica a como está hoy.
   2. TODO va bajo `body.ui-v2` (chrome común) o `body.pg-<pantalla>`
      (lo propio de una pantalla). Así revertir una fase no puede romper otra.
   3. ADITIVO: no se editan reglas ya desplegadas de fases anteriores.
      Cada fase agrega su bloque al final, bajo su propio `pg-`.

   Por qué se conservan .app-header / .header-right / .app-nav en el HTML:
   dos módulos compartidos los usan como punto de montaje y NO se tocan —
   notificaciones.js:21 busca `.header-right` para inyectar la campana, y
   empresa-activa.js:100 busca `.app-nav` para insertar la barra "Trabajando
   en". Aquí se re-visten: .app-nav pasa a ser el sidebar y .app-header la
   barra superior. Cero cambios en archivos compartidos por las 13 pantallas.
   ===================================================================== */

body.ui-v2 {
  /* Alias del prototipo mapeados a la paleta que ya existe en styles.css.
     No se inventa color nuevo: --navy/--orange/--verde/--rojo/--ambar son
     los corporativos vigentes. */
  --card: var(--blanco);
  --bg: var(--gris-bg);
  --linea: var(--gris-linea);
  --suave: var(--texto-suave);
  --info: #1F6FB2;
  --info-bg: #E7F1FA;
  --r: 12px;
  --r-lg: 16px;
  --sbw: 244px;
  --sombra-v2: 0 1px 3px rgba(0,31,63,.08), 0 8px 24px rgba(0,31,63,.06);

  padding-left: var(--sbw);
  background: var(--bg);
}

/* ===================== SIDEBAR (era .app-nav) ===================== */
body.ui-v2 .app-nav {
  position: fixed;
  left: 0; top: 0;
  width: var(--sbw);
  height: 100vh;
  background: linear-gradient(180deg, #001F3F, #0A3A5E);
  display: flex;
  flex-direction: column;
  /* nowrap es OBLIGATORIO: styles.css:291 declara flex-wrap:wrap para el nav
     horizontal original. Heredado aquí, con dirección columna y alto fijo,
     los ítems desbordaban a una SEGUNDA COLUMNA. */
  flex-wrap: nowrap;
  align-content: flex-start;
  gap: 4px;
  padding: 14px 12px;
  /* styles.css:294-295 centra el nav en 640px; en el sidebar sobra. */
  max-width: none;
  margin: 0;
  border: 0;
  overflow-y: auto;
  overflow-x: hidden;          /* nunca desborde lateral */
  z-index: 60;
}
/* Barra de scroll discreta: aparece solo si los ítems de verdad no caben
   (con perfil interno roles.js:135-227 inyecta hasta 12 destinos). */
body.ui-v2 .app-nav::-webkit-scrollbar { width: 6px; }
body.ui-v2 .app-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.18); border-radius: 999px; }
body.ui-v2 .app-nav::-webkit-scrollbar-track { background: transparent; }
/* ---- Cabecera de marca del sidebar (la re-parenta ui-shell.js) ----
   El logo NO necesita panel: necesita su versión para fondo oscuro.
   Medido decodificando el PNG embebido en el SVG y aplicando su máscara,
   el logo original son dos tintas — navy #183858 (~48%, contraste 1,1-1,4:1
   sobre el sidebar → invisible) y naranja de marca #e87818 (~27%, 5,62:1 →
   perfectamente visible). Es decir: solo desaparecía el texto, no la flecha.
   assets/logo-claro.svg (derivado, el original intacto) recolorea a blanco
   ÚNICAMENTE la tinta navy y conserva el naranja: contraste mínimo medido
   4,34:1, cero píxeles por debajo de 3:1. Así la marca vive directo sobre el
   navy, sin recuadro. */
body.ui-v2 .app-nav .brand {
  display: block;
  flex: 0 0 auto;                       /* nunca se estira ni se encoge */
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  padding: 2px 4px 14px;
  margin: 0 0 8px;
  border-bottom: 1px solid rgba(255,255,255,.11);
}
body.ui-v2 .app-nav .brand-logo {
  display: block;
  width: 100%;
  height: auto;                         /* anula el height:52px de styles.css:61 */
  max-width: 152px;
  margin: 0 auto;
}

body.ui-v2 .app-nav a {
  display: flex; align-items: center; gap: 12px;
  /* flex:0 0 auto anula el `flex:1 1 88px` de styles.css:298, que en columna
     hacía CRECER cada ítem hasta llenar el alto (el "espaciado enorme"). */
  flex: 0 0 auto;
  padding: 10px 12px;
  border-radius: 11px;
  color: #BCD2E3;
  font-weight: 600;
  font-size: 14px;
  line-height: 1.25;
  text-align: left;            /* styles.css:299 lo centraba */
  border: 0;
  background: transparent;
  white-space: nowrap;
}
body.ui-v2 .app-nav a:hover { background: rgba(255,255,255,.08); color: #fff; }
body.ui-v2 .app-nav a.actual {
  background: var(--orange);
  color: #3a1c00;
  box-shadow: 0 6px 16px rgba(255,133,27,.35);
}
/* Iconos por destino: sin tocar el HTML de ninguna pantalla */
body.ui-v2 .app-nav a::before {
  width: 22px; flex: none; text-align: center; font-size: 17px;
  content: "•";
}
body.ui-v2 .app-nav a[href^="inicio"]::before       { content: "🏠"; }
body.ui-v2 .app-nav a[href^="empresas"]::before     { content: "🏢"; }
body.ui-v2 .app-nav a[href^="index"]::before        { content: "⚙️"; }
body.ui-v2 .app-nav a[href^="ot."]::before          { content: "🧾"; }
body.ui-v2 .app-nav a[href^="intervencion"]::before { content: "🔧"; }
body.ui-v2 .app-nav a[href^="informe"]::before      { content: "📄"; }
body.ui-v2 .app-nav a[href^="hoja"]::before         { content: "📋"; }
body.ui-v2 .app-nav a[href^="inventario"]::before   { content: "📦"; }
body.ui-v2 .app-nav a[href^="finanzas"]::before     { content: "💰"; }
body.ui-v2 .app-nav a[href^="cartera"]::before      { content: "💳"; }
body.ui-v2 .app-nav a[href^="gerencia"]::before     { content: "📊"; }
body.ui-v2 .app-nav a[href^="trazabilidad"]::before { content: "🧭"; }

/* ===================== BARRA SUPERIOR (era .app-header) ===================== */
body.ui-v2 .app-header {
  position: sticky; top: 0;
  background: var(--card);
  border-bottom: 1px solid var(--linea);
  display: flex; align-items: center; gap: 10px;
  padding: 11px 20px;
  z-index: 15;
  box-shadow: none;
}
body.ui-v2 .app-header .brand { display: none; }   /* se movió al sidebar */
body.ui-v2 #uiTitulo {
  flex: 1; margin: 0;
  font-size: 18px; color: var(--navy);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.ui-v2 .header-right { display: flex; align-items: center; gap: 10px; }

/* Botones grandes de la barra (lupa, campana, salir) — tamaño guante */
body.ui-v2 .ui-ticon,
body.ui-v2 #notifBtn,
body.ui-v2 .btn-salir {
  width: 44px; height: 44px;
  min-width: 44px;
  padding: 0;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--card);
  color: var(--navy);
  display: grid; place-items: center;
  font-size: 18px; font-weight: 700;
  position: relative;
}
body.ui-v2 .ui-ticon:hover,
body.ui-v2 #notifBtn:hover,
body.ui-v2 .btn-salir:hover { background: var(--bg); }
body.ui-v2 .btn-salir { width: auto; padding: 0 14px; font-size: 14px; }

/* Pill de conexión: se reduce a un punto en la barra nueva */
body.ui-v2 .estado-pill { border-radius: 999px; font-size: 12px; padding: 6px 11px; }

/* ---- Campana inyectada por notificaciones.js ----
   Ese archivo pinta la campana con estilos EN LÍNEA (notificaciones.js:28-34,
   66-69). Por eso aquí hace falta !important: es la única forma de re-vestirla
   sin editar un archivo compartido por 24 HTMLs. Queda anotado como deuda:
   cuando toda la migración termine, esos inline styles deberían salir de
   notificaciones.js — pero NO durante el rediseño. */
body.ui-v2 #notifPanel {
  width: min(400px, calc(100vw - 24px)) !important;
  top: 125% !important;
  border: 1px solid var(--linea) !important;
  border-radius: var(--r-lg) !important;
  box-shadow: 0 12px 40px rgba(0,31,63,.18) !important;
  max-height: min(420px, 60vh) !important;
  overflow: hidden !important;
  display: flex; flex-direction: column;
}
body.ui-v2 #notifPanel > div:first-child {
  padding: 12px 14px !important;
  border-bottom: 1px solid var(--linea) !important;
  background: #FaFcFe;
}
body.ui-v2 #notifPanel > div:first-child strong { font-size: 14px !important; color: var(--navy); }
body.ui-v2 #notifLista { overflow: auto; max-height: min(370px, 52vh); }
body.ui-v2 #notifLista li {
  padding: 12px 14px !important;
  border-bottom: 1px solid var(--linea) !important;
  font-size: 13.5px;
}
body.ui-v2 #notifLista li[style*="eef5ff"] { background: var(--info-bg) !important; }
body.ui-v2 #notifBadge {
  top: -6px !important; right: -6px !important;
  min-width: 21px !important; height: 21px !important;
  border-radius: 999px !important;
  background: var(--rojo) !important;
  font-size: 11px !important; font-weight: 800 !important;
  display: grid !important; place-items: center;
  border: 2px solid #fff !important;
  padding: 0 5px !important;
}

/* Barra "Trabajando en" (empresa-activa.js), re-parentada a la barra superior */
body.ui-v2 .empresa-activa-bar {
  margin: 0; padding: 0;
  border: 0; background: transparent;
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--suave);
}
body.ui-v2 .ea-nombre { display: none; }           /* redundante junto al selector */
body.ui-v2 .ea-select {
  border: 1px solid var(--linea); border-radius: 10px;
  padding: 8px 9px; font-weight: 600; font-size: 13px;
  background: var(--card); color: var(--tinta);
}

/* ===================== LIENZO ===================== */
body.ui-v2 .contenido { padding: 20px; max-width: 1280px; margin: 0 auto; width: 100%; }
body.ui-v2 .aviso { border-radius: var(--r); margin-bottom: 14px; }

/* Sección = tarjeta blanca con título fuera (lenguaje del prototipo) */
body.ui-v2 .grupo {
  background: var(--card);
  border: 1px solid var(--linea);
  border-radius: var(--r-lg);
  box-shadow: var(--sombra-v2);
  padding: 16px;
  margin-bottom: 18px;
}
body.ui-v2 .grupo-titulo {
  font-size: 12px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--suave); font-weight: 800;
  margin: 0 0 12px; padding: 0; border: 0; background: transparent;
}
body.ui-v2 .ayuda { color: var(--suave); font-size: 13px; }

/* Accesos rápidos = botones grandes (guantes) */
body.ui-v2 .accesos { grid-template-columns: repeat(4, 1fr); gap: 10px; }
body.ui-v2 .acceso {
  flex-direction: row; align-items: center; justify-content: center; gap: 9px;
  padding: 16px 14px;
  border: 1px solid var(--linea); border-radius: 12px;
  font-weight: 700; font-size: 14.5px; color: var(--navy);
  background: var(--card);
  min-height: 56px;
}
body.ui-v2 .acceso:hover { background: var(--bg); }
body.ui-v2 .acceso .ico { font-size: 20px; }
/* La acción principal se distingue */
body.ui-v2 #accNuevaOT {
  background: var(--orange); border-color: var(--orange); color: #3a1c00;
}
body.ui-v2 #accNuevaOT:hover { background: var(--orange-600); }

/* KPIs con barra de color a la izquierda */
body.ui-v2 .kpis { grid-template-columns: repeat(4, 1fr); gap: 12px; }
body.ui-v2 .kpi {
  background: var(--card);
  border: 1px solid var(--linea);
  border-left: 4px solid var(--navy);
  border-radius: var(--r);
  box-shadow: none;
  padding: 14px 16px;
  text-align: left;
}
body.ui-v2 .kpi-num { font-size: 26px; font-weight: 800; color: var(--navy); }
body.ui-v2 .kpi--money { border-left-color: var(--verde); }
body.ui-v2 .kpi--money .kpi-num { font-size: 20px; }
body.ui-v2 .kpi--alerta { border-left-color: var(--rojo); }
body.ui-v2 .kpi-lbl {
  color: var(--suave); font-size: 12px; font-weight: 700;
  text-transform: none; letter-spacing: 0;
}

/* Listas */
body.ui-v2 .resultado { padding: 13px 4px; border-bottom: 1px solid var(--linea); }
body.ui-v2 .resultado-cod { color: var(--navy); font-weight: 800; }
body.ui-v2 .resultado-meta { color: var(--suave); font-size: 12.5px; }
body.ui-v2 .vacio { color: var(--suave); padding: 16px; text-align: center; }

/* ===================== SHELL NUEVO (inyecta ui-shell.js) ===================== */
body.ui-v2 .ui-hb { display: none; }               /* hamburguesa: solo móvil */
body.ui-v2 .ui-scrim { display: none; }

/* --- Buscador global --- */
body.ui-v2 .ui-ov {
  position: fixed; inset: 0;
  background: rgba(0,31,63,.45);
  z-index: 90;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 8vh 14px 14px;
}
body.ui-v2 .ui-gs {
  width: min(680px, 100%);
  background: var(--card);
  border-radius: var(--r-lg);
  box-shadow: 0 20px 60px rgba(0,31,63,.3);
  overflow: hidden;
  display: flex; flex-direction: column;
  max-height: 82vh;
}
body.ui-v2 .ui-gh {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; border-bottom: 1px solid var(--linea);
}
body.ui-v2 .ui-gh input {
  flex: 1; border: 0; outline: 0; font: inherit; font-size: 17px;
  color: var(--tinta); background: transparent; padding: 0;
}
body.ui-v2 .ui-esc {
  border: 1px solid var(--linea); border-radius: 8px;
  padding: 4px 8px; font-size: 11px; color: var(--suave);
  font-weight: 700; background: var(--card);
}
body.ui-v2 .ui-gb { overflow: auto; padding: 6px 0; }
body.ui-v2 .ui-grp {
  padding: 10px 16px 4px;
  font-size: 11px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--suave); font-weight: 800;
  display: flex; align-items: center; gap: 7px;
}
body.ui-v2 .ui-grp .n {
  background: var(--azul-claro); color: var(--navy);
  border-radius: 999px; padding: 1px 7px; font-size: 10.5px;
}
body.ui-v2 .ui-res {
  display: flex; gap: 12px; align-items: center;
  padding: 11px 16px; cursor: pointer;
  border: 0; width: 100%; background: transparent; text-align: left;
}
body.ui-v2 .ui-res:hover { background: var(--azul-claro); }
body.ui-v2 .ui-res .ric {
  width: 36px; height: 36px; border-radius: 10px;
  display: grid; place-items: center; font-size: 17px; flex: none;
  background: var(--bg); border: 1px solid var(--linea);
}
body.ui-v2 .ui-res .rtx { flex: 1; min-width: 0; }
body.ui-v2 .ui-res .rtx b { display: block; color: var(--navy); font-size: 14px; }
body.ui-v2 .ui-res .rtx small {
  color: var(--suave); font-size: 12.5px; display: block;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.ui-v2 .ui-gf {
  padding: 11px 16px; border-top: 1px solid var(--linea);
  background: #FaFcFe; font-size: 12px; color: var(--suave);
  display: flex; justify-content: space-between; gap: 10px;
}
body.ui-v2 .ui-gvacio { padding: 26px 16px; text-align: center; color: var(--suave); font-size: 14px; }

body.ui-v2 .ui-bn { display: none; }               /* barra inferior: solo móvil */

/* ===================== PANTALLA: INICIO (pg-inicio) ===================== */
/* Bloque "Requiere tu atención" */
body.pg-inicio .notis { display: flex; flex-direction: column; gap: 10px; }
body.pg-inicio .noti {
  display: flex; gap: 12px; align-items: center;
  padding: 13px 15px;
  border: 1px solid var(--linea); border-radius: var(--r);
  background: var(--card);
  border-left: 4px solid var(--info);
  width: 100%; text-align: left; cursor: pointer;
}
body.pg-inicio .noti:hover { background: #FbFdFf; }
body.pg-inicio .noti .nic {
  width: 38px; height: 38px; border-radius: 10px;
  display: grid; place-items: center; font-size: 18px; flex: none;
  background: var(--info-bg);
}
body.pg-inicio .noti .ntx { flex: 1; min-width: 0; }
body.pg-inicio .noti .ntx b { display: block; color: var(--navy); font-size: 14px; font-weight: 700; }
body.pg-inicio .noti .ntx small { color: var(--suave); font-size: 12.5px; }
body.pg-inicio .noti .ngo { color: var(--suave); font-size: 18px; flex: none; }
body.pg-inicio .noti.rojo  { border-left-color: var(--rojo); }
body.pg-inicio .noti.rojo .nic  { background: var(--rojo-bg); }
body.pg-inicio .noti.ambar { border-left-color: var(--ambar); }
body.pg-inicio .noti.ambar .nic { background: var(--ambar-bg); }
body.pg-inicio .noti.verde { border-left-color: var(--verde); }
body.pg-inicio .noti.verde .nic { background: var(--verde-bg); }

/* Tarjetas de OT activas */
body.pg-inicio .otmini { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
body.pg-inicio .otcard {
  background: var(--card); border: 1px solid var(--linea);
  border-radius: var(--r-lg); box-shadow: var(--sombra-v2);
  padding: 14px 15px;
  display: flex; flex-direction: column; gap: 8px;
}
body.pg-inicio .otcard .eq { font-weight: 800; color: var(--navy); font-size: 15px; }
body.pg-inicio .otcard .mt {
  color: var(--suave); font-size: 12.5px;
  font-family: ui-monospace, Consolas, monospace;
}
body.pg-inicio .otcard .rowb {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
body.pg-inicio .otcard .btn-ir {
  border: 1px solid var(--navy); background: var(--navy); color: #fff;
  font-weight: 700; padding: 10px 14px; border-radius: 11px; font-size: 14px;
  white-space: nowrap;
}
body.pg-inicio .otcard .btn-ir:hover { background: #02294f; }

/* Badges de estado (pasa/no-pasa visual) */
body.pg-inicio .badge {
  display: inline-flex; gap: 6px; align-items: center;
  font-size: 12px; font-weight: 800;
  padding: 4px 10px; border-radius: 999px; white-space: nowrap;
}
body.pg-inicio .badge .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; }
body.pg-inicio .st-abierta   { background: var(--info-bg);   color: var(--info); }
body.pg-inicio .st-proceso,
body.pg-inicio .st-pct       { background: var(--ambar-bg);  color: var(--ambar); }
body.pg-inicio .st-devuelta  { background: var(--rojo-bg);   color: var(--rojo); }
body.pg-inicio .st-ctecnica  { background: var(--azul-claro); color: var(--navy); }
body.pg-inicio .st-ceco      { background: var(--verde-bg);  color: var(--verde); }
body.pg-inicio .st-otro      { background: var(--gris-bg);   color: var(--suave); }

/* ===================== TABLET ===================== */
@media (max-width: 1024px) {
  body.ui-v2 { --sbw: 72px; }
  body.ui-v2 .app-nav { padding: 14px 8px; }
  body.ui-v2 .app-nav a { justify-content: center; padding: 12px 0; font-size: 0; gap: 0; }
  body.ui-v2 .app-nav a::before { font-size: 19px; }
  /* Riel de 72px (ancho útil 56px): la marca se reduce a su mínima expresión
     legible, sin recuadro. Sigue leyéndose porque es tinta clara sobre navy. */
  body.ui-v2 .app-nav .brand { padding: 2px 0 10px; margin: 0 0 6px; }
  body.ui-v2 .app-nav .brand-logo { max-width: 100%; }
  body.ui-v2 .accesos { grid-template-columns: repeat(2, 1fr); }
  body.ui-v2 .kpis { grid-template-columns: repeat(2, 1fr); }
  body.pg-inicio .otmini { grid-template-columns: 1fr; }
}

/* ===================== MÓVIL ===================== */
@media (max-width: 767px) {
  body.ui-v2 { --sbw: 0px; padding-left: 0; }
  body.ui-v2 .app-nav {
    width: 250px;
    transform: translateX(-100%);
    transition: transform .22s ease;
    padding: 14px 12px;
  }
  body.ui-v2 .app-nav a { justify-content: flex-start; padding: 11px 12px; font-size: 14px; gap: 12px; }
  body.ui-v2 .app-nav a::before { font-size: 17px; }
  /* Drawer de 250px: la cabecera se contiene. En PC el logo ocupa 152 de 220px
     útiles (69%); repetir esa proporción aquí (226px útiles) lo hacía dominar
     el panel en pantalla pequeña. A 124px baja al 55% y el menú recupera peso,
     sin quedar olvidado. El aire y el separador se conservan. */
  body.ui-v2 .app-nav .brand { padding: 2px 4px 13px; margin: 0 0 8px; }
  body.ui-v2 .app-nav .brand-logo { max-width: 124px; }
  body.ui-v2.ui-menu .app-nav { transform: none; }
  body.ui-v2.ui-menu .ui-scrim {
    display: block; position: fixed; inset: 0;
    background: rgba(0,31,63,.45); z-index: 55;
  }
  body.ui-v2 .ui-hb { display: grid; }
  body.ui-v2 .app-header { padding: 10px 12px; gap: 8px; }
  /* La identidad de sesión NO va como franja en la cabecera: probada en campo,
     quedaba truncada ("Todas las empr…" · "Técnico 01 · Perfil…") y gastaba una
     fila entera en información ilegible. En su lugar, el AVATAR de la barra
     superior (#uiAvatar) identifica el perfil de un vistazo, y al tocarlo abre
     el drawer, donde la identidad completa sí cabe.
     La barra "Trabajando en" no se oculta: ui-shell.js la MUEVE al drawer en
     móvil (ubicarBarraEmpresa), bajo el encabezado de identidad. */
  body.ui-v2 .app-header .empresa-activa-bar { display: none; }
  /* "Salir" sale de la barra superior, pero AHORA sí existe en el menú lateral
     (ui-shell.js monta #uiSalir). Antes esta línea lo ocultaba sin alternativa:
     desde F1 no había forma de cerrar sesión desde el celular. */
  body.ui-v2 .btn-salir { display: none; }
  body.ui-v2 .estado-pill { display: none; }
  body.ui-v2 #uiTitulo { font-size: 16px; }
  body.ui-v2 .contenido { padding: 12px 12px 88px; }

  body.ui-v2 .accesos { grid-template-columns: 1fr 1fr; }
  body.ui-v2 .kpis { grid-template-columns: 1fr 1fr; }
  body.pg-inicio .otmini { grid-template-columns: 1fr; }

  /* ---- Densidad en móvil (ajuste de 2ª revisión) ----
     Al 100% de zoom el contenido se sentía amontonado. Se baja un punto la
     tipografía y los iconos del CONTENIDO y se recorta el padding entre
     tarjetas, para que respire como se veía alejado.
     LO QUE NO SE TOCA: los controles de acción siguen a tamaño guante
     (.acceso, .btn-ir, .ui-ticon, .ui-bn, y el botón de la campana). */
  body.ui-v2 .grupo { padding: 13px; margin-bottom: 11px; }
  body.ui-v2 .grupo-titulo { font-size: 11px; margin-bottom: 10px; }
  body.ui-v2 .ayuda { font-size: 12px; }
  body.ui-v2 .vacio { padding: 13px; font-size: 13px; }

  body.ui-v2 .kpi { padding: 11px 13px; }
  body.ui-v2 .kpi-num { font-size: 22px; }
  body.ui-v2 .kpi--money .kpi-num { font-size: 17px; }
  body.ui-v2 .kpi-lbl { font-size: 11.5px; }

  body.ui-v2 .resultado { padding: 11px 2px; }
  body.ui-v2 .resultado-cod { font-size: 14px; }
  body.ui-v2 .resultado-meta { font-size: 11.5px; }
  body.ui-v2 .barra-row { font-size: 12px; margin-bottom: 7px; }
  body.ui-v2 .barra-val { font-size: 11.5px; }

  body.pg-inicio .noti { padding: 11px 12px; gap: 10px; }
  body.pg-inicio .noti .nic { width: 33px; height: 33px; font-size: 16px; }
  body.pg-inicio .noti .ntx b { font-size: 13px; }
  body.pg-inicio .noti .ntx small { font-size: 11.5px; }

  body.pg-inicio .otcard { padding: 12px 13px; gap: 7px; }
  body.pg-inicio .otcard .eq { font-size: 14px; }
  body.pg-inicio .otcard .mt { font-size: 11.5px; }
  body.pg-inicio .badge { font-size: 11.5px; padding: 3px 9px; }

  /* Tamaño guante: intacto y explícito, para que ningún ajuste futuro lo pise */
  body.ui-v2 .acceso { min-height: 62px; font-size: 14px; }
  body.pg-inicio .otcard .btn-ir { padding: 14px; font-size: 15px; flex: 1; }

  /* Barra inferior */
  body.ui-v2 .ui-bn {
    display: flex; position: fixed; bottom: 0; left: 0; right: 0;
    z-index: 40; background: var(--card);
    border-top: 1px solid var(--linea);
    padding: 6px;
    box-shadow: 0 -2px 10px rgba(0,31,63,.06);
  }
  body.ui-v2 .ui-bn a {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
    font-size: 10.5px; color: var(--suave); font-weight: 700;
    padding: 5px; cursor: pointer; border: 0; background: transparent;
  }
  body.ui-v2 .ui-bn a .ic { font-size: 19px; }
  body.ui-v2 .ui-bn a.on { color: var(--orange); }
  body.ui-v2 .ui-bn a.plus { color: #3a1c00; }
  body.ui-v2 .ui-bn a.plus .ic {
    background: var(--orange); color: #3a1c00;
    width: 44px; height: 44px; border-radius: 50%;
    display: grid; place-items: center;
    margin-top: -22px;
    box-shadow: 0 6px 16px rgba(255,133,27,.4);
    font-size: 24px;
  }
  /* El panel de la campana ocupa el ancho útil */
  body.ui-v2 #notifPanel {
    position: fixed !important;
    left: 8px !important; right: 8px !important;
    top: 62px !important;
    width: auto !important;
  }
}

/* =====================================================================
   FASE 2 — LISTA DE OT (pg-ot).  Sección autónoma: no edita ni una regla
   de la Fase 1, según la disciplina aditiva declarada arriba.
   Prototipo: ui-preview/ryval-v3.html (pantalla "Órdenes de trabajo").
   ===================================================================== */

/* Filtros de la agenda */
body.pg-ot .fila { gap: 10px; }
body.pg-ot .campo label { font-size: 11px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--suave); font-weight: 800; }
body.pg-ot .ot-cab { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
body.pg-ot .agenda-toggle { display: flex; gap: 8px; }

/* Encabezado de cada grupo (bucket / empresa) */
body.pg-ot .lista-grupo { margin-bottom: 18px; }
body.pg-ot .grupo-cab {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;                   /* declarado, no heredado de styles.css:482 */
  background: var(--navy); border-radius: 10px 10px 0 0;
  padding: 9px 14px; margin: 0;
}
body.pg-ot .grupo-cab strong { color: #fff; font-size: 13px; }
body.pg-ot .grupo-cab small { color: #C8D4E4; font-size: 12px; font-weight: 700; }

/* ---- Cabecera de columnas (solo PC/tablet) ---- */
body.pg-ot .ot-thead {
  display: grid;
  grid-template-columns: 2.4fr 1.5fr 1fr 1.4fr .9fr 1.2fr;
  gap: 10px;
  padding: 10px 14px;
  background: #FaFcFe;
  border: 1px solid var(--linea);
  border-top: 0;
  font-size: 11px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--suave); font-weight: 800;
}
body.pg-ot .ot-thead > div:last-child { text-align: right; }

/* ---- La lista ---- */
body.pg-ot #otLista .resultados {
  list-style: none; margin: 0; padding: 0;
  background: var(--card);
  border: 1px solid var(--linea);
  border-top: 0;
  border-radius: 0 0 10px 10px;
  /* max-height:none es OBLIGATORIO. styles.css:352 declara max-height:340px +
     overflow-y:auto para las listas de resultados, y su único override
     (styles.css:488) aplica a `#lista`, NO a `#otLista`. Heredado aquí junto
     con overflow:hidden, recortaba las filas que pasaran de 340px: quedaban
     invisibles e inalcanzables, y con ellas moría el scrollIntoView del
     deep-link. La tabla nueva se muestra entera y scrollea la página. */
  max-height: none;
  overflow: visible;
}
/* La FILA. Sigue siendo li.resultado[data-ot] — el deep-link depende de eso. */
body.pg-ot #otLista .resultado {
  display: grid;
  grid-template-columns: 2.4fr 1.5fr 1fr 1.4fr .9fr 1.2fr;
  gap: 10px;
  align-items: center;
  width: 100%;                 /* declarado, no heredado de styles.css:365 */
  padding: 12px 14px;
  border-bottom: 1px solid var(--linea);
  background: transparent;
  /* transition propia: enfocarOT anima background y box-shadow en línea */
  transition: background .3s, box-shadow .3s;
}
body.pg-ot #otLista .resultado:last-child { border-bottom: 0; }
body.pg-ot #otLista .resultado:hover { background: #FbFdFf; }

body.pg-ot .c-eq { min-width: 0; }
body.pg-ot .c-eq b { display: block; color: var(--navy); font-weight: 800; font-size: 14.5px; line-height: 1.3; }
body.pg-ot .c-eq small { display: block; color: var(--suave); font-size: 12px; line-height: 1.4; }
body.pg-ot .c-ctx { margin-top: 1px; }
body.pg-ot .mono { font-family: ui-monospace, Consolas, monospace; font-variant-numeric: tabular-nums;
  font-size: 13px; color: var(--tinta); font-weight: 700; }
body.pg-ot .c-tipo { font-size: 13.5px; color: var(--tinta); }
body.pg-ot .c-est { display: flex; flex-wrap: wrap; gap: 4px; }
body.pg-ot .c-fec { font-size: 12.5px; }
body.pg-ot .c-acc { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
body.pg-ot .c-acc .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 9px 12px; font-size: 13px; font-weight: 700;
}
body.pg-ot .c-acc .btn-cambiar:hover { background: var(--bg); }
/* La etiqueta de columna solo se usa en móvil */
body.pg-ot .lbl { display: none; }

/* ---- Badges de estado: color semántico (pasa/no-pasa) ----
   Ganan a .badge--Alta/Media/Baja de styles.css por especificidad
   (body.pg-ot .badge = 0,2,1 vs .badge--X = 0,1,0) y por orden de carga. */
body.pg-ot .badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 800;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
body.pg-ot .st-abierta   { background: var(--info-bg);    color: var(--info); }
body.pg-ot .st-prog      { background: var(--azul-claro); color: var(--navy); }
body.pg-ot .st-proceso   { background: var(--ambar-bg);   color: var(--ambar); }
body.pg-ot .st-pct       { background: var(--ambar-bg);   color: var(--ambar); }
body.pg-ot .st-devuelta  { background: var(--rojo-bg);    color: var(--rojo); }
body.pg-ot .st-ctecnica  { background: var(--verde-bg);   color: var(--verde); }
body.pg-ot .st-cerrada   { background: var(--gris-bg);    color: var(--suave); }
body.pg-ot .st-cancelada { background: var(--gris-bg);    color: var(--suave); text-decoration: line-through; }
body.pg-ot .st-otro      { background: var(--gris-bg);    color: var(--suave); }

/* Calendario: solo encaje con el lienzo nuevo, sin rediseñarlo en F2 */
body.pg-ot .cal-grid { background: var(--card); border-radius: 10px; }

@media (max-width: 1024px) {
  body.pg-ot .ot-thead,
  body.pg-ot #otLista .resultado { grid-template-columns: 2.2fr 1.3fr 1.2fr .9fr 1.2fr; }
  /* En tablet el tipo se pliega dentro de la celda de equipo */
  body.pg-ot .ot-thead > div:nth-child(3) { display: none; }
  body.pg-ot .c-tipo { display: none; }
}

@media (max-width: 767px) {
  /* ---- TARJETAS ---- */
  body.pg-ot .ot-thead { display: none; }
  body.pg-ot #otLista .resultados {
    background: transparent; border: 0; border-radius: 0; overflow: visible;
  }
  body.pg-ot .grupo-cab { border-radius: 10px; margin-bottom: 10px; }
  body.pg-ot #otLista .resultado {
    grid-template-columns: 1fr 1fr;
    gap: 9px 12px;
    padding: 14px;
    margin-bottom: 11px;
    background: var(--card);
    border: 1px solid var(--linea);
    border-bottom: 1px solid var(--linea);
    border-radius: 14px;
    box-shadow: var(--sombra-v2);
    align-items: start;
  }
  body.pg-ot #otLista .resultado:last-child { border-bottom: 1px solid var(--linea); }
  /* etiquetas visibles: cada dato dice qué es */
  body.pg-ot .lbl {
    display: block; font-size: 10px; text-transform: uppercase; letter-spacing: .4px;
    color: var(--suave); font-weight: 800; margin-bottom: 3px;
  }
  body.pg-ot .c-eq { grid-column: 1 / -1; }
  body.pg-ot .c-eq b { font-size: 16.5px; }
  body.pg-ot .c-eq small { font-size: 12.5px; }
  body.pg-ot .c-tipo { display: block; }
  body.pg-ot .c-est { grid-column: 1 / -1; }
  body.pg-ot .mono { font-size: 13.5px; }
  /* acción a ancho completo y tamaño guante */
  body.pg-ot .c-acc { grid-column: 1 / -1; justify-content: stretch; gap: 8px; }
  body.pg-ot .c-acc .btn-cambiar { flex: 1 1 auto; padding: 14px 12px; font-size: 15px; }
}

/* =====================================================================
   FASE 3 — FICHA DE ACTIVO (pg-hoja). Sección autónoma: no edita ninguna
   regla de F1 ni F2. Prototipo: ui-preview/ryval-v3.html, pantalla
   "Ficha de activo" — todo en una vista, SIN tabs anidados.
   ===================================================================== */

/* Selector de activo (puerta de entrada).
   max-height:none por la MISMA razón que en F2: styles.css:352 capa las listas
   .resultados a 340px con scroll interno. Su único override (styles.css:488)
   apunta a `#lista .resultados`, que aquí SÍ coincide — pero se declara de
   todos modos para no depender de una regla ajena que puede moverse. */
body.pg-hoja #lista .resultados {
  max-height: none;
  overflow: visible;
  border: 1px solid var(--linea);
  border-top: 0;
  border-radius: 0 0 10px 10px;
  margin: 0; padding: 0; list-style: none;
}
body.pg-hoja .lista-grupo { margin-bottom: 16px; }
body.pg-hoja .grupo-cab {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--navy); border-radius: 10px 10px 0 0; padding: 9px 14px; margin: 0;
}
body.pg-hoja .grupo-cab strong { color: #fff; font-size: 13px; }
body.pg-hoja .grupo-cab small { color: #C8D4E4; font-size: 12px; font-weight: 700; }
body.pg-hoja #lista .resultado {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 14px; background: transparent;
  border: 0; border-bottom: 1px solid var(--linea);
  cursor: pointer;
}
body.pg-hoja #lista .resultado:last-child { border-bottom: 0; }
body.pg-hoja #lista .resultado:hover { background: #FbFdFf; }
body.pg-hoja .resultado-cod { color: var(--navy); font-weight: 800; }
body.pg-hoja .resultado-meta { color: var(--suave); font-size: 12.5px; }
body.pg-hoja .btn-ficha {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 9px 12px; font-size: 13px; font-weight: 700; white-space: nowrap;
}
body.pg-hoja .btn-ficha:hover { background: var(--bg); }

/* ---- Volver ---- */
body.pg-hoja .btn-volver {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 9px 14px; font-size: 13.5px; font-weight: 700;
  margin-bottom: 14px;
}
body.pg-hoja .btn-volver:hover { background: var(--bg); }

/* ---- Cabecera de la ficha: identidad + acciones ---- */
body.pg-hoja .f-cab {
  display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap;
  border-left: 5px solid var(--orange);
}
body.pg-hoja .f-id { flex: 1; min-width: 220px; }
body.pg-hoja .f-id h2 { margin: 0 0 4px; font-size: 22px; color: var(--navy); line-height: 1.25; }
body.pg-hoja .f-cod { font-size: 13px; color: var(--suave); }
body.pg-hoja .f-badges { margin-top: 9px; display: flex; gap: 8px; flex-wrap: wrap; }
body.pg-hoja .f-acc { display: flex; gap: 10px; flex-wrap: wrap; }
/* Botones tamaño guante */
body.pg-hoja .btn-xl {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 14px; padding: 17px 20px; font-size: 16px; font-weight: 800; white-space: nowrap;
}
body.pg-hoja .btn-xl:hover { background: var(--bg); }
body.pg-hoja .btn-naranja {
  background: var(--orange); border-color: var(--orange); color: #3a1c00;
}
body.pg-hoja .btn-naranja:hover { background: var(--orange-600); }

/* ---- Rejilla de datos ---- */
body.pg-hoja .f-datos {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; background: var(--linea);
  border: 1px solid var(--linea); border-radius: 10px; overflow: hidden;
}
body.pg-hoja .f-datos > div { background: var(--card); padding: 12px 14px; }
body.pg-hoja .f-datos .dl {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--suave); font-weight: 800;
}
body.pg-hoja .f-datos .dv { font-size: 14.5px; color: var(--navy); font-weight: 700; margin-top: 2px; }
body.pg-hoja .mono { font-family: ui-monospace, Consolas, monospace; font-variant-numeric: tabular-nums; }

/* ---- Resumen ---- */
body.pg-hoja .kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
body.pg-hoja .kpi {
  background: var(--card); border: 1px solid var(--linea);
  border-left: 4px solid var(--navy); border-radius: var(--r);
  box-shadow: none; padding: 14px 16px; text-align: left;
}
body.pg-hoja .kpi-num { font-size: 26px; font-weight: 800; color: var(--navy); }
body.pg-hoja .kpi--money { border-left-color: var(--verde); }
body.pg-hoja .kpi--money .kpi-num { font-size: 19px; }
body.pg-hoja .kpi--alerta { border-left-color: var(--ambar); }
body.pg-hoja .kpi--alerta .kpi-num { color: var(--navy); }
body.pg-hoja .kpi-lbl { color: var(--suave); font-size: 12px; font-weight: 700; text-transform: none; letter-spacing: 0; }

/* ---- Historial unificado (una sola línea de tiempo, sin tabs) ---- */
body.pg-hoja .f-hist { display: flex; flex-direction: column; }
body.pg-hoja .h-row {
  display: grid; grid-template-columns: 132px 1fr auto;
  gap: 14px; align-items: center;
  padding: 13px 4px; border-bottom: 1px solid var(--linea);
}
body.pg-hoja .h-row:last-child { border-bottom: 0; }
body.pg-hoja .h-row:hover { background: #FbFdFf; }
body.pg-hoja .h-fecha { font-size: 12.5px; color: var(--suave); font-weight: 700; }
body.pg-hoja .h-tipo {
  display: block; font-size: 10px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--navy); background: var(--azul-claro);
  border-radius: 999px; padding: 1px 8px; margin-top: 4px; width: fit-content;
}
body.pg-hoja .h-txt { min-width: 0; }
body.pg-hoja .h-txt b { display: block; color: var(--navy); font-size: 14.5px; }
body.pg-hoja .h-txt small { display: block; color: var(--suave); font-size: 12.5px; }
body.pg-hoja .h-act {
  margin-top: 3px; overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
body.pg-hoja .h-acc { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
body.pg-hoja .btn-hist {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 9px 12px; font-size: 13px; font-weight: 700; white-space: nowrap;
}
body.pg-hoja .btn-hist:hover { background: var(--bg); }

/* ---- Badges: pasa / no-pasa ---- */
body.pg-hoja .badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 800; padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
body.pg-hoja .ok { background: var(--verde-bg); color: var(--verde); }
body.pg-hoja .warn { background: var(--ambar-bg); color: var(--ambar); }
body.pg-hoja .no { background: var(--rojo-bg); color: var(--rojo); }
body.pg-hoja .st-abierta { background: var(--info-bg); color: var(--info); }
body.pg-hoja .st-prog { background: var(--azul-claro); color: var(--navy); }
body.pg-hoja .st-proceso, body.pg-hoja .st-pct { background: var(--ambar-bg); color: var(--ambar); }
body.pg-hoja .st-devuelta { background: var(--rojo-bg); color: var(--rojo); }
body.pg-hoja .st-ctecnica { background: var(--verde-bg); color: var(--verde); }
body.pg-hoja .st-ceco { background: var(--verde-bg); color: var(--verde); }
body.pg-hoja .st-cerrada { background: var(--gris-bg); color: var(--suave); }
body.pg-hoja .st-cancelada { background: var(--gris-bg); color: var(--suave); text-decoration: line-through; }
body.pg-hoja .st-otro { background: var(--gris-bg); color: var(--suave); }

@media (max-width: 1024px) {
  body.pg-hoja .f-datos { grid-template-columns: repeat(2, 1fr); }
  body.pg-hoja .kpis { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 767px) {
  body.pg-hoja .f-datos { grid-template-columns: 1fr 1fr; }
  body.pg-hoja .f-datos > div { padding: 10px 12px; }
  body.pg-hoja .f-datos .dv { font-size: 13.5px; }
  body.pg-hoja .kpis { grid-template-columns: 1fr 1fr; }
  body.pg-hoja .kpi { padding: 11px 13px; }
  body.pg-hoja .kpi-num { font-size: 22px; }
  body.pg-hoja .kpi--money .kpi-num { font-size: 16px; }
  body.pg-hoja .f-id h2 { font-size: 19px; }
  /* Acciones a ancho completo, tamaño guante intacto */
  body.pg-hoja .f-acc { width: 100%; }
  body.pg-hoja .f-acc .btn-xl { flex: 1 1 auto; padding: 16px 14px; font-size: 15px; }
  /* Historial en tarjeta */
  body.pg-hoja .h-row { grid-template-columns: 1fr; gap: 8px; padding: 14px; }
  body.pg-hoja .h-fecha { display: flex; align-items: center; gap: 8px; }
  body.pg-hoja .h-tipo { margin-top: 0; }
  body.pg-hoja .h-acc { justify-content: flex-start; }
  body.pg-hoja .h-acc .btn-hist { flex: 1; padding: 13px 12px; font-size: 14.5px; }
  body.pg-hoja .h-txt b { font-size: 15.5px; }
  body.pg-hoja #lista .resultado { flex-wrap: wrap; }
  body.pg-hoja .btn-ficha { width: 100%; padding: 13px; font-size: 14.5px; }
}

/* F3: el nombre del equipo en la lista de OT abre su ficha */
body.pg-ot .eq-link { cursor: pointer; }
body.pg-ot .eq-link:hover { color: var(--info); text-decoration: underline; }

/* ---- Documentos del activo: RESERVA VISUAL de DOC-01 ----
   Sin backend. El estado vacío explica qué vivirá aquí y el botón va
   deshabilitado con marca "pronto": nada en esta sección promete una acción
   que el sistema todavía no puede cumplir (R1: nada silencioso, nada falso). */
body.pg-hoja .doc-vacio {
  border: 1.5px dashed var(--linea);
  border-radius: var(--r);
  background: #FaFcFe;
  padding: 26px 20px;
  text-align: center;
}
body.pg-hoja .doc-ico { font-size: 34px; line-height: 1; margin-bottom: 8px; }
body.pg-hoja .doc-vacio b { display: block; color: var(--navy); font-size: 15px; margin-bottom: 5px; }
body.pg-hoja .doc-vacio p {
  margin: 0 auto 15px; max-width: 460px;
  color: var(--suave); font-size: 13px; line-height: 1.5;
}
body.pg-hoja .doc-tipos {
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-bottom: 16px;
}
body.pg-hoja .doc-chip {
  border: 1px solid var(--linea); background: var(--card); color: var(--suave);
  border-radius: 999px; padding: 6px 13px; font-size: 12.5px; font-weight: 700;
}
body.pg-hoja .doc-btn[disabled] {
  opacity: .55; cursor: not-allowed;
  display: inline-flex; align-items: center; gap: 9px;
}
body.pg-hoja .doc-pronto {
  background: var(--azul-claro); color: var(--navy);
  border-radius: 999px; padding: 2px 9px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .5px; text-transform: uppercase;
}

@media (max-width: 767px) {
  body.pg-hoja .doc-vacio { padding: 20px 14px; }
  body.pg-hoja .doc-ico { font-size: 30px; }
  body.pg-hoja .doc-vacio p { font-size: 12.5px; }
  body.pg-hoja .doc-chip { font-size: 11.5px; padding: 5px 11px; }
  body.pg-hoja .doc-btn[disabled] { width: 100%; justify-content: center; padding: 15px 14px; font-size: 15px; }
}

/* =====================================================================
   FASE 4 — LOGIN (pg-login). Cierra la migración visual. Sección autónoma:
   no edita ninguna regla de F1, F2 ni F3. SOLO presentación: login.js no se
   toca (autenticación, redirecciones y manejo de sesión intactos).
   ===================================================================== */

/* body.ui-v2 aporta las variables del diseño, pero también reserva el ancho
   del sidebar (padding-left: var(--sbw) = 244px). El login NO tiene sidebar:
   sin esta anulación la tarjeta aparecería desplazada a la derecha. */
body.pg-login {
  padding-left: 0;
  background: linear-gradient(160deg, #001F3F 0%, #0A3A5E 55%, #07314f 100%);
}

body.pg-login .login-wrap {
  min-height: 100vh;
  /* dvh sigue al viewport real: cuando el teclado del móvil se abre, el alto
     se reduce y la tarjeta NO queda con el botón "Entrar" debajo del teclado.
     Se declara después de 100vh como mejora progresiva. */
  min-height: 100dvh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: transparent;   /* el degradado lo pone el body */
}

body.pg-login .login-card {
  width: 100%; max-width: 400px;
  background: var(--card);
  border: 1px solid rgba(255,255,255,.10);
  border-top: 4px solid var(--orange);
  border-radius: var(--r-lg);
  box-shadow: 0 18px 50px rgba(0,0,0,.28);
  padding: 30px 26px 26px;
  text-align: center;
}

/* Marca: el logo va sobre la tarjeta BLANCA, así que es el logo ORIGINAL.
   (logo-claro.svg existe para el sidebar navy; aquí sería invisible.) */
body.pg-login .login-logo { height: 58px; width: auto; margin: 2px auto 10px; display: block; }
body.pg-login .login-marca {
  margin: 0 0 18px;
  font-size: 11px; letter-spacing: 1.2px; text-transform: uppercase;
  color: var(--suave); font-weight: 700;
}
body.pg-login .login-title {
  margin: 0 0 20px; font-size: 19px; color: var(--navy); font-weight: 800;
}

/* ---- Campos ----
   styles.css:143 estiliza text/date/number/select/textarea pero NO
   input[type=password]: hoy el campo de contraseña se ve con el estilo por
   defecto del navegador mientras el de usuario sí está estilizado. Aquí se
   igualan los dos, con ámbito pg-login. */
body.pg-login .login-card form { text-align: left; }
body.pg-login .campo { margin-bottom: 16px; }
body.pg-login .campo label {
  font-size: 12px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--suave); font-weight: 800; margin-bottom: 7px;
}
body.pg-login input[type="text"],
body.pg-login input[type="password"] {
  width: 100%;
  font: inherit;
  font-size: 16px;            /* 16px evita que iOS haga zoom al enfocar */
  color: var(--tinta);
  background: var(--card);
  border: 1px solid var(--linea);
  border-radius: 11px;
  padding: 14px 14px;
  outline: none;
  -webkit-appearance: none; appearance: none;
  transition: border-color .15s, box-shadow .15s;
}
body.pg-login input[type="text"]:focus,
body.pg-login input[type="password"]:focus {
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(255,133,27,.18);
}
body.pg-login input::placeholder { color: #9AA7BC; }

/* ---- Error: tiene que verse, es la única señal de que algo falló ---- */
body.pg-login .login-error {
  display: flex; align-items: flex-start; gap: 8px;
  margin: 0 0 14px; padding: 12px 13px;
  border-radius: var(--r);
  background: var(--rojo-bg); color: var(--rojo);
  border: 1px solid #F3C0BB;
  font-size: 13.5px; font-weight: 600; text-align: left;
}
body.pg-login .login-error::before { content: "⚠"; flex: none; font-size: 15px; line-height: 1.2; }

/* ---- Botón: tamaño guante ---- */
body.pg-login .btn-guardar {
  width: 100%;                /* el HTML ya no lleva style="width:100%" */
  flex: none;
  padding: 16px 18px;
  font-size: 16px; font-weight: 800;
  border-radius: 12px;
  color: #3a1c00;
  background: var(--orange);
  border: 1px solid var(--orange);
  margin-top: 2px;
}
body.pg-login .btn-guardar:hover { background: var(--orange-600); }
body.pg-login .btn-guardar:disabled { opacity: .6; cursor: progress; }

body.pg-login .login-hint {
  margin: 18px 0 0; font-size: 12px; color: var(--suave); text-align: center; line-height: 1.5;
}

@media (max-width: 767px) {
  /* En pantalla pequeña la tarjeta se alinea arriba: al abrirse el teclado,
     centrar verticalmente empujaría el botón fuera de la vista. */
  body.pg-login .login-wrap { align-items: flex-start; padding: 28px 16px 24px; }
  body.pg-login .login-card { padding: 26px 20px 22px; max-width: 100%; }
  body.pg-login .login-logo { height: 50px; }
  body.pg-login .login-title { font-size: 18px; margin-bottom: 18px; }
  body.pg-login .btn-guardar { padding: 17px 18px; font-size: 16.5px; }
}

/* =====================================================================
   AJUSTE post-F1 — IDENTIDAD DE SESIÓN EN EL MENÚ LATERAL
   Hallazgo de campo (19-jul-2026): en móvil no se veía con quién estabas
   dentro. Dos frentes: (1) la franja compacta bajo la cabecera, corregida
   en el bloque móvil de F1; (2) este bloque, que da al menú lateral su
   propio encabezado de identidad y —crítico— el botón de cerrar sesión,
   que desde F1 no existía en móvil.
   Chrome común: va bajo body.ui-v2, aplica a las 4 pantallas migradas.
   ===================================================================== */

body.ui-v2 .ui-ident {
  display: flex; align-items: center; gap: 10px;
  flex: 0 0 auto;
  margin: 0 0 10px;
  padding: 9px 10px;
  background: rgba(255,255,255,.07);
  border: 1px solid rgba(255,255,255,.10);
  border-radius: 11px;
  min-width: 0;
}
body.ui-v2 .ui-ident-av {
  width: 32px; height: 32px; flex: none;
  border-radius: 50%;
  background: var(--orange); color: #3a1c00;
  display: grid; place-items: center;
  font-weight: 800; font-size: 14px;
}
body.ui-v2 .ui-ident-tx { min-width: 0; line-height: 1.25; }
body.ui-v2 .ui-ident-tx b {
  display: block; color: #fff; font-size: 13.5px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.ui-v2 .ui-ident-tx small {
  display: block; color: #BCD2E3; font-size: 11.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Cerrar sesión: al final del menú, separado de la navegación para que no
   se toque por error con guantes. */
body.ui-v2 .ui-salir {
  flex: 0 0 auto;
  margin-top: auto;            /* se pega abajo del sidebar */
  padding: 12px 12px;
  border: 1px solid rgba(255,255,255,.16);
  border-radius: 11px;
  background: transparent;
  color: #E6B3AD;
  font-size: 13.5px; font-weight: 700;
  text-align: left;
  white-space: nowrap;
}
body.ui-v2 .ui-salir::before { content: "⎋"; margin-right: 9px; font-size: 15px; }
body.ui-v2 .ui-salir:hover { background: rgba(180,35,24,.22); color: #fff; }

/* Riel de tablet (72px): solo avatar y solo el icono de salir. */
@media (max-width: 1024px) {
  body.ui-v2 .ui-ident { justify-content: center; padding: 8px 4px; gap: 0; }
  body.ui-v2 .ui-ident-tx { display: none; }
  body.ui-v2 .ui-salir { text-align: center; font-size: 0; padding: 12px 0; }
  body.ui-v2 .ui-salir::before { margin-right: 0; font-size: 18px; }
}

/* Drawer móvil (250px): identidad completa y salir con etiqueta. */
@media (max-width: 767px) {
  body.ui-v2 .ui-ident { justify-content: flex-start; padding: 10px; gap: 10px; }
  body.ui-v2 .ui-ident-tx { display: block; }
  body.ui-v2 .ui-salir { text-align: left; font-size: 14px; padding: 14px 12px; }
  body.ui-v2 .ui-salir::before { margin-right: 9px; font-size: 16px; }
}

/* ---- Avatar de sesión en la barra superior (reemplaza la franja) ----
   La franja permanente se probó en campo y quedaba truncada. Este avatar dice
   el PERFIL de un vistazo (inicial + color) sin texto que se corte, y al
   tocarlo abre el drawer con la identidad completa. Solo móvil: en anchos
   mayores el sidebar ya muestra esa información de forma permanente. */
body.ui-v2 .ui-av { display: none; }

body.ui-v2 .ui-av {
  font-size: 15px; font-weight: 800;
  color: #fff;
  background: var(--navy);
  border-color: var(--navy);
}
body.ui-v2 .ui-av:hover { background: #02294f; }
/* Color por perfil: se distinguen sin leer la letra. */
body.ui-v2 .ui-av[data-perfil="técnico"],
body.ui-v2 .ui-av[data-perfil="tecnico"]      { background: var(--orange);  border-color: var(--orange);  color: #3a1c00; }
body.ui-v2 .ui-av[data-perfil="supervisor"]   { background: var(--info);    border-color: var(--info); }
body.ui-v2 .ui-av[data-perfil="gerencia"]     { background: var(--navy);    border-color: var(--navy); }
body.ui-v2 .ui-av[data-perfil="finanzas"]     { background: var(--verde);   border-color: var(--verde); }
body.ui-v2 .ui-av[data-perfil="cartera"]      { background: var(--ambar);   border-color: var(--ambar); }
body.ui-v2 .ui-av[data-perfil="desarrollador"]{ background: #5B3FA8;        border-color: #5B3FA8; }

@media (max-width: 767px) {
  body.ui-v2 .ui-av { display: grid; }

  /* La barra "Trabajando en" vive DENTRO del drawer en móvil
     (ui-shell.js la mueve con ubicarBarraEmpresa). Aquí se re-viste para el
     fondo oscuro: etiqueta visible y selector a ancho completo, sin truncar. */
  body.ui-v2 .app-nav .empresa-activa-bar {
    display: block;
    flex: 0 0 auto;
    margin: 0 0 10px;
    padding: 10px;
    background: rgba(255,255,255,.05);
    border: 1px solid rgba(255,255,255,.10);
    border-radius: 11px;
  }
  body.ui-v2 .app-nav .ea-label {
    display: block;
    font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
    color: #9FB6CC; font-weight: 800; margin-bottom: 6px;
  }
  body.ui-v2 .app-nav .ea-nombre { display: none; }   /* redundante con el selector */
  body.ui-v2 .app-nav .ea-select {
    display: block; width: 100%; max-width: none;
    font-size: 14px; padding: 11px 10px;
    border-radius: 9px;
    background: var(--card); color: var(--tinta);
    border: 1px solid var(--linea);
  }
  /* El indicador de perfil de roles.js viaja con la barra: en el drawer sobra,
     porque el encabezado de identidad ya dice nombre y perfil. */
  body.ui-v2 .app-nav #perfilActivo { display: none; }
}

/* =====================================================================
   ORDEN DEL SIDEBAR ANCLADO POR LAYOUT (corrección de campo, 19-jul-2026)
   Dos defectos venían de confiar en el ORDEN DE INSERCIÓN en el DOM:
     · "Cerrar sesión" quedaba encima de Inventario, porque ui-shell.js lo
       monta al arrancar y roles.js:135-227 inyecta sus enlaces DESPUÉS.
     · "Trabajando en" salía antes del logo, porque al reubicarla el nodo
       #uiIdent aún no existía y caía en nav.firstChild.
   La solución NO es reordenar tras la inyección (volvería a depender de
   quién corre primero), sino fijar el orden con `order` de flexbox: el
   .app-nav es display:flex/column, así que el orden visual queda garantizado
   pase lo que pase con el DOM. Todo hijo sin `order` explícito vale 0, por eso
   cada pieza declara el suyo.
   ===================================================================== */
body.ui-v2 .app-nav .ui-top             { order: 1; }
body.ui-v2 .app-nav .empresa-activa-bar { order: 2; }
body.ui-v2 .app-nav a                   { order: 3; }   /* incluidos los que inyecta roles.js */
body.ui-v2 .app-nav .ui-salir           { order: 999; } /* SIEMPRE al fondo */

/* ---- Cabecera fija: marca + identidad quedan arriba mientras el menú
        scrollea (mismo patrón sticky que la barra superior).
        Necesita fondo opaco propio: el degradado del sidebar no se mueve con
        el contenido, y en su punto más alto es exactamente #001F3F. ---- */
body.ui-v2 .ui-top {
  position: sticky;
  top: 0;
  z-index: 3;
  flex: 0 0 auto;
  background: #001F3F;
  margin: -14px -12px 8px;      /* compensa el padding del nav para cubrir de borde a borde */
  padding: 14px 12px 0;
}
body.ui-v2 .ui-top .brand { margin-bottom: 8px; }
body.ui-v2 .ui-top .ui-ident { margin-bottom: 10px; }

@media (max-width: 1024px) {
  body.ui-v2 .ui-top { margin: -14px -8px 6px; padding: 14px 8px 0; }
}
@media (max-width: 767px) {
  body.ui-v2 .ui-top { margin: -14px -12px 8px; padding: 14px 12px 0; }
}

/* =====================================================================
   B1.1 — INFORMES (pg-informe). Bloque 1 (campo). Sección autónoma: no
   edita ninguna regla de F1-F4 ni del ajuste de chrome.

   CORRECCIÓN al inventario del plan: dije que Informes NO usaba
   `.resultados`. SÍ lo usa — informe.js:359 genera <ul class="resultados">
   desde JS, y mi inventario solo miró el HTML. Por eso necesita el
   max-height:none igual que OT y Fichas (styles.css:352 capa a 340px).
   ===================================================================== */

body.pg-informe #lista .resultados {
  max-height: none;               /* la trampa de styles.css:352, otra vez */
  overflow: visible;
  list-style: none; margin: 0; padding: 0;
  background: var(--card);
  border: 1px solid var(--linea);
  border-top: 0;
  border-radius: 0 0 10px 10px;
}
body.pg-informe .lista-grupo { margin-bottom: 16px; }
body.pg-informe .grupo-cab {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--navy); border-radius: 10px 10px 0 0; padding: 9px 14px; margin: 0;
}
body.pg-informe .grupo-cab strong { color: #fff; font-size: 13px; }
body.pg-informe .grupo-cab small { color: #C8D4E4; font-size: 12px; font-weight: 700; }

body.pg-informe #lista .resultado {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px;
  width: 100%;
  padding: 13px 14px;
  background: transparent;
  border: 0; border-bottom: 1px solid var(--linea);
}
body.pg-informe #lista .resultado:last-child { border-bottom: 0; }
body.pg-informe #lista .resultado:hover { background: #FbFdFf; }
body.pg-informe .resultado-cod { color: var(--navy); font-weight: 800; font-size: 14.5px; }
body.pg-informe .resultado-meta { color: var(--suave); font-size: 12.5px; }
body.pg-informe #lista .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 10px 13px; font-size: 13.5px; font-weight: 700;
}
body.pg-informe #lista .btn-cambiar:hover { background: var(--bg); }
body.pg-informe #lista .btn-cambiar[disabled] { opacity: .5; }

/* Panel de acceso denegado (cartera): que se lea como decisión, no como error */
body.pg-informe #informeSinAcceso {
  border-radius: var(--r-lg); padding: 20px; font-size: 14.5px; font-weight: 600;
}

/* ---- Visor del informe ----
   informe.html lo trae con estilos EN LÍNEA (líneas 56-66): para re-vestirlo
   sin tocar ese marcado hace falta !important, igual que con la campana. */
body.pg-informe #infPreview {
  background: rgba(0,31,63,.5) !important;
  padding: 4vh 14px !important;
  align-items: flex-start !important;
}
body.pg-informe #infPreview > div {
  border-radius: var(--r-lg) !important;
  box-shadow: 0 20px 60px rgba(0,31,63,.32) !important;
  max-width: 820px !important;
}
body.pg-informe #infPreview > div > div:first-child {
  padding: 14px 18px !important;
  border-bottom: 1px solid var(--linea) !important;
  background: #FaFcFe;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
body.pg-informe #infPreviewTitulo { font-size: 15.5px !important; }
body.pg-informe #infPreview .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 9px 13px; font-size: 13.5px; font-weight: 700;
}
body.pg-informe #infPreviewPDF {
  background: var(--orange); border-color: var(--orange); color: #3a1c00;
}
body.pg-informe #infPreviewBody { padding: 18px !important; }

/* ---- Firmas táctiles ----
   CONTRATO DURO: los dos canvas conservan touch-action:none (viene en línea
   desde el HTML) para que se pueda firmar con el dedo sin que la página
   haga scroll. Aquí SOLO se les da presencia; NADA toca ese comportamiento. */
body.pg-informe #infFirmaBloque { border-top: 1px solid var(--linea) !important; padding: 16px 18px !important; }
body.pg-informe #infFRyvalCanvas,
body.pg-informe #infFCliCanvas {
  border: 1.5px dashed var(--linea) !important;
  border-radius: var(--r) !important;
  background: #FdFeFf !important;
}
body.pg-informe #infFirmaBloque input[type="text"],
body.pg-informe #infFirmaBloque input[type="date"] {
  border: 1px solid var(--linea); border-radius: 9px;
  padding: 9px 10px !important; font-size: 13.5px !important;
  color: var(--tinta); background: var(--card);
}
body.pg-informe #infFirmaBloque > div > div {
  border: 1px solid var(--linea) !important;
  border-radius: var(--r) !important;
  padding: 14px !important;
}

@media (max-width: 767px) {
  body.pg-informe .grupo-cab { border-radius: 10px; margin-bottom: 10px; }
  body.pg-informe #lista .resultados {
    background: transparent; border: 0; border-radius: 0;
  }
  body.pg-informe #lista .resultado {
    background: var(--card); border: 1px solid var(--linea);
    border-radius: 14px; box-shadow: var(--sombra-v2);
    margin-bottom: 11px; padding: 14px;
  }
  body.pg-informe #lista .resultado:last-child { border-bottom: 1px solid var(--linea); }
  body.pg-informe .resultado-cod { font-size: 15.5px; }
  /* Acción a ancho completo y tamaño guante */
  body.pg-informe #lista .btn-cambiar { width: 100%; padding: 14px 12px; font-size: 15px; }

  /* El visor a pantalla casi completa: en el celular es donde se firma. */
  body.pg-informe #infPreview { padding: 0 !important; }
  body.pg-informe #infPreview > div { border-radius: 0 !important; min-height: 100dvh; }
  body.pg-informe #infPreviewBody { padding: 14px !important; }
  body.pg-informe #infFirmaBloque { padding: 14px !important; }
  /* Los canvas más altos: firmar con el dedo necesita espacio. */
  body.pg-informe #infFRyvalCanvas,
  body.pg-informe #infFCliCanvas { height: 170px !important; }
  body.pg-informe #infFirmaBloque .btn-cambiar { flex: 1; padding: 13px 10px; font-size: 14px; }
}

/* ---- B1.1: FIRMA A PANTALLA COMPLETA ----
   Motivo de campo: clientes de edad batallan con el rectángulo pequeño.
   El lienzo grande mantiene la MISMA relación 4:1 del pad (1600x400 vs
   600x150) para que el trazo vuelva sin deformarse. touch-action:none igual
   que en los pads: se firma con el dedo y la página no se mueve. */
body.pg-informe #infFirmaFull {
  position: fixed; inset: 0; z-index: 3000;
  background: var(--card);
  display: flex; flex-direction: column;
  padding: 14px;
  gap: 12px;
}
body.pg-informe .ff-cab {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
body.pg-informe .ff-cab strong { color: var(--navy); font-size: 16px; }
body.pg-informe .ff-hint { color: var(--suave); font-size: 12.5px; }
body.pg-informe #infFirmaFullCanvas {
  flex: 1; width: 100%; min-height: 0;
  touch-action: none;                 /* el contrato táctil, igual que los pads */
  background: #FdFeFf;
  border: 2px dashed var(--linea);
  border-radius: var(--r-lg);
  /* La firma es 4:1; se deja que el alto lo ponga el flex y el navegador
     escale el lienzo. El trazo se calcula con getBoundingClientRect, así que
     el escalado no descuadra las coordenadas. */
}
body.pg-informe .ff-acc { display: flex; gap: 10px; flex-wrap: wrap; }
body.pg-informe .ff-acc .btn-cambiar {
  flex: 1; min-width: 120px;
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 12px; padding: 16px 14px; font-size: 15px; font-weight: 800;
}
body.pg-informe .ff-acc .ff-ok {
  background: var(--verde); border-color: var(--verde); color: #fff; flex: 2;
}
body.pg-informe .btn-ampliar {
  background: var(--azul-claro); border-color: #C5D6EC; color: var(--navy); font-weight: 800;
}

@media (max-width: 767px) {
  body.pg-informe #infFirmaFull { padding: 10px; gap: 10px; }
  body.pg-informe .ff-cab strong { font-size: 15px; }
  body.pg-informe .ff-acc .btn-cambiar { padding: 17px 12px; font-size: 15.5px; }
  body.pg-informe .btn-ampliar { width: 100%; }
}

/* =====================================================================
   B1.1 — CORRECCIONES DE CAMPO (validación en celular, 19-jul-2026)
   ===================================================================== */

/* ---- 1. BUG: la cabecera del visor se desbordaba en móvil y había que
        alejar el zoom para alcanzar la X. informe.html:58 la trae con
        estilos EN LÍNEA (display:flex; justify-content:space-between), por
        eso hace falta !important para poder envolverla. ---- */
body.pg-informe #infPreview > div > div:first-child {
  flex-wrap: wrap !important;
  gap: 10px;
  position: relative;
}
/* La X se ancla arriba a la derecha y NUNCA se va del ancho visible. */
body.pg-informe #infPreviewCerrar {
  position: absolute; top: 10px; right: 12px;
  width: 40px; height: 40px; min-width: 40px;
  padding: 0 !important;
  display: grid; place-items: center;
  font-size: 17px; font-weight: 800;
  z-index: 2;
}
/* El título deja sitio a la X para no pasar por debajo. */
body.pg-informe #infPreviewTitulo { padding-right: 52px; display: block; }
/* El grupo de acciones baja a su propia línea y reparte el ancho. */
body.pg-informe #infPreview > div > div:first-child > span {
  flex-wrap: wrap;
  width: 100%;
  gap: 8px !important;
}
body.pg-informe #infFirmaToggle,
body.pg-informe #infPreviewPDF { flex: 1 1 auto; white-space: nowrap; }

/* ---- 3. PULIDO: el chip de estado se partía en dos renglones.
        Inquebrantable: un solo renglón siempre. ---- */
body.pg-informe #lista .badge,
body.pg-informe .badge {
  white-space: nowrap !important;
  display: inline-flex; align-items: center;
  max-width: 100%;
  overflow: hidden; text-overflow: ellipsis;
}

/* ---- 2. La captura sin deformar: el lienzo grande se MUESTRA con la misma
        relación 4:1 que su búfer (1600x400). Antes se estiraba a la forma de
        la pantalla, así que pos() escalaba X e Y con factores distintos y el
        trazo se capturaba deformado. Con la proporción fijada, lo que se
        dibuja es exactamente lo que se guarda. ---- */
body.pg-informe #infFirmaFullCanvas {
  flex: 0 1 auto;
  aspect-ratio: 4 / 1;
  width: 100%;
  height: auto;
  max-height: 100%;
  margin: auto 0;
}

@media (max-width: 767px) {
  body.pg-informe #infPreview > div > div:first-child { padding: 12px 14px !important; }
  body.pg-informe #infPreviewTitulo { font-size: 14.5px !important; padding-right: 48px; }
  body.pg-informe #infFirmaToggle,
  body.pg-informe #infPreviewPDF { padding: 12px 10px; font-size: 13.5px; flex: 1 1 45%; }
  body.pg-informe #infPreviewCerrar { top: 8px; right: 10px; }
  /* El chip, más pequeño antes que partido */
  body.pg-informe #lista .badge { font-size: 10px !important; padding: 3px 7px; }
}

/* =====================================================================
   B1.1 — CORRECCIONES DE LA 3ª PASADA EN CAMPO (19-jul-2026)
   ===================================================================== */

/* ---- 1. LA MISMA CAUSA RAÍZ, ahora en el PAD PEQUEÑO ----
   informe.html declara los canvas con búfer 600x150 (4:1) pero los MUESTRA
   con `width:100%; height:150px` EN LÍNEA. En un celular el visor deja ~310px
   de ancho → display 310x150 = 2.07:1, muy lejos del 4:1 del búfer. pos()
   escala entonces X por 1.94 y Y por 1.00: el trazo se comprime a lo ancho y
   se estira a lo alto. Es exactamente lo reportado.
   Y mi propio CSS lo había EMPEORADO poniendo height:170px en móvil (1.82:1).

   Regla, ahora en los DOS pads y en TODAS las orientaciones: la forma visible
   = la forma del búfer. Se paga en tamaño —en vertical el pad queda bajito—,
   y ese es precisamente el trabajo del botón "Firmar en grande".
   Fidelidad antes que tamaño: lo que se dibuja es lo que queda. */
body.pg-informe #infFRyvalCanvas,
body.pg-informe #infFCliCanvas {
  aspect-ratio: 4 / 1;          /* = 600/150, el búfer */
  height: auto !important;      /* anula el height:150px en línea */
  width: 100%;
  max-width: 600px;
}

/* ---- 2. LA X CON EL MÁXIMO DE BOTONES (caso supervisor: 3 informes) ----
   La X va absoluta arriba a la derecha; el fallo era que la PRIMERA fila
   (el título) podía ser más baja que la X, y entonces la fila de botones
   subía hasta quedar debajo de ella. Se reserva su banda dándole al título
   la misma altura mínima que la X: así los botones SIEMPRE empiezan debajo. */
body.pg-informe #infPreview > div > div:first-child { padding: 12px 14px !important; }
body.pg-informe #infPreviewTitulo {
  min-height: 40px;             /* == alto de la X: reserva su banda */
  display: flex; align-items: center;
  padding-right: 54px;          /* y no pasa por debajo de ella */
  flex: 1 1 100%;
}
body.pg-informe #infPreviewCerrar { top: 12px; right: 14px; }
/* Con 3 botones la fila envuelve sola; cada uno mantiene ancho legible. */
body.pg-informe #infFirmaToggle,
body.pg-informe #infPreviewPDF { flex: 1 1 auto; min-width: 132px; }

/* ---- 3. Ver intervención (antes el lápiz sin etiqueta) ---- */
body.pg-informe .btn-ver-interv { white-space: nowrap; }

@media (max-width: 767px) {
  /* Se retira el height:170px que yo mismo había puesto: rompía la proporción. */
  body.pg-informe #infFRyvalCanvas,
  body.pg-informe #infFCliCanvas { height: auto !important; }
  body.pg-informe #infFirmaToggle,
  body.pg-informe #infPreviewPDF { min-width: 0; flex: 1 1 46%; }
  body.pg-informe .btn-ver-interv { width: 100%; }
}

/* =====================================================================
   B1.1 — 4ª PASADA EN CAMPO (19-jul-2026)
   ===================================================================== */

/* ---- 1. FIRMA CAPTURADA = INTOCABLE ----
   En campo la mano roza el lienzo todo el tiempo: con la firma ya aceptada,
   pasar la mano por encima la rayaba. Ahora el pad se BLOQUEA al capturar y
   solo se reabre con acción explícita ("Editar firma" o "Limpiar").
   El bloqueo real está en JS (los handlers de pointer salen temprano); esto
   es la señal visible de que está cerrado. */
body.pg-informe .firma-bloqueada {
  border-style: solid !important;
  border-color: var(--verde) !important;
  background: #F4FBF6 !important;
  cursor: not-allowed;
  position: relative;
}
body.pg-informe .btn-editar-firma {
  background: var(--azul-claro); border-color: #C5D6EC; color: var(--navy); font-weight: 800;
}

/* ---- 2. EL OJO, DENTRO DEL GRUPO ----
   Antes quedaba suelto: los botones de informe traían margin-right en línea y
   el ojo colgaba aparte. Ahora todos comparten una fila con gap uniforme y el
   mismo estilo; el ojo cierra el grupo. */
body.pg-informe .inf-acciones {
  display: flex; flex-wrap: wrap; gap: 8px;
  width: 100%; margin-top: 8px;
}
body.pg-informe .inf-acciones .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 10px 13px; font-size: 13.5px; font-weight: 700;
  white-space: nowrap; text-decoration: none;
  display: inline-flex; align-items: center; gap: 6px;
}
body.pg-informe .inf-acciones .btn-cambiar:hover { background: var(--bg); }
/* El ojo se distingue por ser consulta, sin romper la alineación. */
body.pg-informe .inf-acciones .btn-ver-interv { color: var(--suave); }

@media (max-width: 767px) {
  /* En móvil cada acción a ancho completo: dedo con guante, sin ambigüedad. */
  body.pg-informe .inf-acciones .btn-cambiar {
    flex: 1 1 100%; justify-content: center; padding: 14px 12px; font-size: 15px;
  }
  body.pg-informe .btn-editar-firma { width: 100%; }
}

/* =====================================================================
   B1.2 — ACTIVOS (pg-activos). Bloque 1 (campo). Sección autónoma: no edita
   ninguna regla anterior. Es la pantalla de CAPTURA: formulario largo con
   foto de placa, que el técnico usa de pie frente al equipo.
   ===================================================================== */

/* Lista de activos — la trampa de siempre: styles.css:352 capa .resultados a
   340px con scroll interno, y aquí el contenedor es #listaActivos, que NO
   coincide con el override de styles.css:488 (ese es para #lista). */
body.pg-activos #listaActivos {
  max-height: none;
  overflow: visible;
  list-style: none; margin: 0; padding: 0;
  background: var(--card);
  border: 1px solid var(--linea);
  border-radius: var(--r);
}
body.pg-activos #listaActivos .resultado {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 14px; background: transparent;
  border: 0; border-bottom: 1px solid var(--linea);
  cursor: pointer; text-align: left;
}
body.pg-activos #listaActivos .resultado:last-child { border-bottom: 0; }
body.pg-activos #listaActivos .resultado:hover { background: #FbFdFf; }
body.pg-activos .resultado-cod { color: var(--navy); font-weight: 800; }
body.pg-activos .resultado-meta { color: var(--suave); font-size: 12.5px; }
body.pg-activos .resultados-cab { color: var(--suave); font-size: 12px; font-weight: 700; margin-bottom: 8px; }

/* Formulario */
body.pg-activos .campo { margin-bottom: 15px; }
body.pg-activos .campo label {
  font-size: 12px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--suave); font-weight: 800; margin-bottom: 6px;
}
body.pg-activos .fila { display: flex; gap: 12px; }
body.pg-activos .fila .campo { flex: 1; }
body.pg-activos input[type="text"],
body.pg-activos input[type="number"],
body.pg-activos input[type="date"],
body.pg-activos select,
body.pg-activos textarea {
  border: 1px solid var(--linea); border-radius: 11px;
  padding: 13px 13px; font-size: 16px;      /* 16px: iOS no hace zoom al enfocar */
  background: var(--card); color: var(--tinta);
}
body.pg-activos input:focus, body.pg-activos select:focus, body.pg-activos textarea:focus {
  border-color: var(--orange); box-shadow: 0 0 0 3px rgba(255,133,27,.18); outline: 0;
}
body.pg-activos .invalido { border-color: var(--rojo) !important; }
/* El código autogenerado: se lee como dato del sistema, no como campo editable */
body.pg-activos .codigo-auto {
  font-family: ui-monospace, Consolas, monospace;
  background: var(--azul-claro) !important; color: var(--navy);
  font-weight: 800; letter-spacing: .5px;
}

/* Banner de edición */
body.pg-activos .edit-banner {
  background: var(--ambar-bg); border: 1px solid #EBD9A6;
  border-left: 4px solid var(--ambar);
  border-radius: var(--r); padding: 12px 14px; margin-bottom: 14px;
  color: var(--navy); font-size: 13.5px;
}

/* Foto de la placa — botón grande: se toma de pie, con guantes */
body.pg-activos .foto-boton {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  border: 2px dashed var(--linea); border-radius: var(--r-lg);
  background: #FaFcFe; color: var(--navy);
  padding: 20px 16px; font-size: 15.5px; font-weight: 700;
  cursor: pointer; width: 100%;
}
body.pg-activos .foto-boton:hover { background: var(--bg); border-color: var(--orange); }
body.pg-activos .foto-preview img { border-radius: var(--r); border: 1px solid var(--linea); }
body.pg-activos .foto-quitar {
  border: 1px solid var(--linea); background: var(--card); color: var(--rojo);
  border-radius: 10px; padding: 9px 13px; font-size: 13px; font-weight: 700;
}

/* R1 — el fallo de subida, con sus tres salidas */
body.pg-activos .foto-fallo-acc { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
body.pg-activos .foto-fallo-acc .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 12px 14px; font-size: 14px; font-weight: 700;
}
body.pg-activos #fotoReintentar { background: var(--orange); border-color: var(--orange); color: #3a1c00; }
body.pg-activos #fotoCancelar { color: var(--rojo); }

/* ---- Barra de guardado ----
   Se CONSERVA `position: fixed` como en styles.css:233 (es lo correcto en un
   formulario largo: Guardar siempre alcanzable). Tres cosas que el chequeo de
   cascada destapó y que hay que respetar:
   1. styles.css declara `left:0; right:0`. Con el sidebar del diseño nuevo la
      barra pasaría POR DEBAJO de él → left: var(--sbw).
   2. El padding inferior original lleva env(safe-area-inset-bottom). Perderlo
      dejaría el botón bajo el indicador de inicio del iPhone → se conserva.
   3. La barra inferior móvil (.ui-bn) es fixed bottom:0 con z-index 40: la de
      guardar quedaba DEBAJO. En móvil se sube por encima de ella. */
body.pg-activos .barra-guardar {
  position: fixed;
  bottom: 0;
  left: var(--sbw);            /* no invade el sidebar */
  right: 0;
  z-index: 20;
  display: flex; gap: 12px; align-items: center;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom));
  margin: 0;
  background: var(--card);
  border-top: 1px solid var(--linea);
  box-shadow: 0 -2px 12px rgba(0,31,63,.07);
}
/* Para que el final del formulario no quede tapado por la barra */
body.pg-activos .contenido { padding-bottom: 96px; }
body.pg-activos .btn-guardar {
  flex: 1; border: 1px solid var(--orange); background: var(--orange); color: #3a1c00;
  border-radius: 12px; padding: 16px 18px; font-size: 16px; font-weight: 800;
}
body.pg-activos .btn-guardar:hover { background: var(--orange-600); }
body.pg-activos .btn-guardar:disabled { opacity: .6; cursor: progress; }
body.pg-activos .contador { color: var(--suave); font-size: 12.5px; font-weight: 700; white-space: nowrap; }

@media (max-width: 767px) {
  body.pg-activos .fila { flex-direction: column; gap: 0; }
  body.pg-activos .grupo { padding: 13px; margin-bottom: 11px; }
  body.pg-activos .grupo-titulo { font-size: 11px; margin-bottom: 10px; }
  body.pg-activos .foto-boton { padding: 24px 14px; font-size: 15px; }
  /* El sidebar es off-canvas → la barra ocupa todo el ancho. Y sube por encima
     de .ui-bn (fixed, bottom:0, alto ~60px): si no, quedaba tapada por ella. */
  body.pg-activos .barra-guardar {
    left: 0;
    bottom: calc(60px + env(safe-area-inset-bottom));
    padding: 11px 14px;
  }
  /* Hueco para las DOS barras: la de guardar y la de navegación. */
  body.pg-activos .contenido { padding-bottom: 150px; }
  body.pg-activos .btn-guardar { padding: 17px 16px; }
  body.pg-activos .contador { display: none; }   /* el ancho es para el botón */
  body.pg-activos .foto-fallo-acc .btn-cambiar { flex: 1 1 100%; padding: 14px; font-size: 15px; }
  body.pg-activos #listaActivos .resultado { flex-wrap: wrap; padding: 14px; }
}

/* =====================================================================
   B1.3 — INTERVENCIONES (pg-interv). Bloque 1 (campo). Sección autónoma:
   no edita ninguna regla anterior.

   Es la pantalla más cargada del sistema: el técnico la usa DE PIE, frente
   al equipo, con guantes y a veces con mala señal. Reúne cuatro cosas que
   en las demás pantallas viven separadas: un selector de activo, una tabla
   de trazabilidad con scroll horizontal, un formulario largo y DOS canales
   de adjuntos (evidencia técnica + soportes para Finanzas).

   MIGRACIÓN VISUAL PURA. Las tres deudas de flujo detectadas (FIRMA-OT-01,
   TRAZA-EDIT-01, REASIG-TEC-01) NO se tocan aquí: van cada una en su R9.
   ===================================================================== */

/* ---- Paso 1: selección de activo ----
   La trampa de siempre, aquí por partida DOBLE: styles.css:352 capa
   .resultados a 340px con scroll interno, y el único override (styles.css:488)
   apunta a #lista, que no existe en esta pantalla. Son DOS listas:
   #enProceso (trabajos a continuar) y #resultados (buscador de activos).
   Las dos quedan sin tope: el TOPE de render ya es 100 (intervencion.js:34),
   así que la página scrollea entera en vez de anidar dos scrolls. */
body.pg-interv #enProceso,
body.pg-interv #resultados {
  max-height: none;
  overflow: visible;
  list-style: none; margin: 0; padding: 0;
  background: var(--card);
  border: 1px solid var(--linea);
  border-radius: var(--r);
}
body.pg-interv #enProceso:empty,
body.pg-interv #resultados:empty { display: none; }
body.pg-interv #enProceso .resultado,
body.pg-interv #resultados .resultado {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 14px; background: transparent;
  border: 0; border-bottom: 1px solid var(--linea);
  cursor: pointer; text-align: left;
}
body.pg-interv #enProceso .resultado:last-child,
body.pg-interv #resultados .resultado:last-child { border-bottom: 0; }
body.pg-interv #enProceso .resultado:hover,
body.pg-interv #resultados .resultado:hover { background: #FbFdFf; }
body.pg-interv .resultado-cod { color: var(--navy); font-weight: 800; }
body.pg-interv .resultado-meta { color: var(--suave); font-size: 12.5px; }
body.pg-interv .resultados-cab { color: var(--suave); font-size: 12px; font-weight: 700; margin-bottom: 8px; }
body.pg-interv .vacio { padding: 14px; color: var(--suave); font-size: 13.5px; list-style: none; }

/* "En proceso" pide continuidad, no es una búsqueda: se distingue en ámbar. */
body.pg-interv #enProcesoWrap { margin-bottom: 14px; }
body.pg-interv #enProceso { border-color: #EBD9A6; background: var(--ambar-bg); }
body.pg-interv #enProceso .resultado { border-bottom-color: #EBD9A6; }
body.pg-interv #enProceso .resultado:hover { background: #FFF6E0; }

/* Activo seleccionado: es el ancla de contexto de toda la pantalla. */
body.pg-interv .activo-sel {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 14px; border: 1.5px solid var(--navy);
  background: var(--azul-claro); border-radius: var(--r);
}
body.pg-interv .activo-sel-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
body.pg-interv .activo-sel-info strong { color: var(--navy); font-weight: 800; }
body.pg-interv .activo-sel-info small { color: var(--suave); font-size: 12px; }

/* ---- Contexto de la OT ----
   Lo que el supervisor PIDIÓ. Va antes del formulario y se lee como cita,
   no como campo editable: es la instrucción que el técnico debe cumplir. */
body.pg-interv #otContexto {
  border-left: 4px solid var(--orange);
  background: var(--acento-bg);
  border-radius: var(--r);
}
body.pg-interv #otContextoBody { font-size: 14px; line-height: 1.6; color: var(--tinta); }

/* ---- Banners de estado ----
   Solo lectura es la señal más importante de la pantalla: si el técnico no
   la ve, escribe un rato y descubre al final que no podía guardar. */
body.pg-interv #soloLecturaBanner {
  background: var(--azul-claro); border: 1px solid #C5D6F2;
  border-left: 4px solid var(--navy);
  border-radius: var(--r); padding: 12px 14px;
  color: var(--navy); font-size: 13.5px; font-weight: 700;
}
body.pg-interv .edit-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--ambar-bg); border: 1px solid #EBD9A6;
  border-left: 4px solid var(--ambar);
  border-radius: var(--r); padding: 12px 14px; margin-bottom: 14px;
  color: var(--navy); font-size: 13.5px;
}

/* ---- Formulario (mismo lenguaje que B1.2) ---- */
body.pg-interv .campo { margin-bottom: 15px; }
body.pg-interv .campo label {
  font-size: 12px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--suave); font-weight: 800; margin-bottom: 6px;
}
body.pg-interv .fila { display: flex; gap: 12px; }
body.pg-interv .fila .campo { flex: 1; }
body.pg-interv input[type="text"],
body.pg-interv input[type="number"],
body.pg-interv input[type="date"],
body.pg-interv input[type="search"],
body.pg-interv select,
body.pg-interv textarea {
  border: 1px solid var(--linea); border-radius: 11px;
  padding: 13px 13px; font-size: 16px;      /* 16px: iOS no hace zoom al enfocar */
  background: var(--card); color: var(--tinta);
}
body.pg-interv input:focus, body.pg-interv select:focus, body.pg-interv textarea:focus {
  border-color: var(--orange); box-shadow: 0 0 0 3px rgba(255,133,27,.18); outline: 0;
}
body.pg-interv .invalido { border-color: var(--rojo) !important; }
body.pg-interv .codigo-auto {
  font-family: ui-monospace, Consolas, monospace;
  background: var(--azul-claro) !important; color: var(--navy);
  font-weight: 800; letter-spacing: .5px;
}
body.pg-interv .ayuda { color: var(--suave); font-size: 12.5px; line-height: 1.5; }

/* "Mejorar redacción" (redaccion.js) y "+ Agregar repuesto" comparten clase.
   Son acciones secundarias: no deben competir con Guardar. */
body.pg-interv .btn-mejorar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 10px 13px; font-size: 13px; font-weight: 700;
  cursor: pointer; margin-top: 8px;
}
body.pg-interv .btn-mejorar:hover { background: var(--bg); border-color: var(--orange); }
body.pg-interv .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 10px 13px; font-size: 13px; font-weight: 700;
  cursor: pointer; white-space: nowrap;
}
body.pg-interv .btn-cambiar:hover { background: var(--bg); }

/* ---- Tabla de repuestos ----
   Es un grid de 4 columnas (styles.css: 1fr 46px 84px 30px). El perfil sin
   permiso económico ya recibe .sin-precio y pierde la columna Precio; eso
   NO se toca, solo se reviste. */
body.pg-interv .mat-tabla {
  border: 1px solid var(--linea); border-radius: var(--r); overflow: hidden;
  background: var(--card);
}
body.pg-interv .mat-head {
  background: var(--azul-claro); color: var(--navy);
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .3px;
  padding: 9px 10px;
}
body.pg-interv .mat-row { border-top: 1px solid var(--linea); padding: 8px 10px; }
body.pg-interv .mat-row input { padding: 9px 9px; font-size: 15px; border-radius: 8px; }

/* ---- Adjuntos: evidencia técnica y soportes de Finanzas ----
   Son DOS canales distintos y el técnico no debe confundirlos: la evidencia
   va al informe, el soporte va a Finanzas. */
body.pg-interv .foto-boton {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  border: 2px dashed var(--linea); border-radius: var(--r-lg);
  background: #FaFcFe; color: var(--navy);
  padding: 20px 16px; font-size: 15.5px; font-weight: 700;
  cursor: pointer; width: 100%;
}
body.pg-interv .foto-boton:hover { background: var(--bg); border-color: var(--orange); }
body.pg-interv #seccionSoportesFin { border-left: 4px solid #1B7F4B; }

body.pg-interv .fotos-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px; margin-top: 12px;
}
/* CASCADA: styles.css declara .foto-thumb con aspect-ratio 1/1 + overflow
   hidden. Sirve para la evidencia (imagen cuadrada), pero renderSoportes()
   mete DENTRO del thumb una leyenda con el tipo y la observación del soporte
   ("Factura · Relé instalado"), y con la caja cuadrada esa leyenda quedaba
   RECORTADA: el usuario no veía qué era cada soporte. Los soportes usan caja
   propia, con alto libre para su leyenda. */
body.pg-interv .fotos-grid .foto-thumb {
  border-radius: var(--r); border: 1px solid var(--linea); overflow: hidden;
}
body.pg-interv #sopGrid .foto-thumb {
  aspect-ratio: auto;
  overflow: visible;
  border: 0;
  display: flex; flex-direction: column; gap: 4px;
}
body.pg-interv #sopGrid .foto-thumb > a {
  border-radius: var(--r); border: 1px solid var(--linea); overflow: hidden;
  width: 100% !important; height: auto !important; aspect-ratio: 1 / 1;
}
body.pg-interv #sopGrid .foto-thumb img { width: 100%; height: 100%; object-fit: cover; }
body.pg-interv .foto-quitar {
  border: 1px solid var(--linea); background: var(--card); color: var(--rojo);
  border-radius: 9px; font-weight: 800;
}

/* ---- R1: el fallo de subida de fotos, con sus tres salidas ----
   Aquí son VARIAS fotos, así que el reintento es por lote: solo las que
   fallaron. Misma gramática que B1.2. */
body.pg-interv .foto-fallo-acc { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
body.pg-interv .foto-fallo-acc .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 12px 14px; font-size: 14px; font-weight: 700;
}
body.pg-interv #fotosReintentar { background: var(--orange); border-color: var(--orange); color: #3a1c00; }
body.pg-interv #fotosCancelar { color: var(--rojo); }

/* ---- Trazabilidad ----
   La tabla declara min-width:980px y scrollea en horizontal. Con el sidebar
   de 244px el área útil se estrecha, así que el contenedor de scroll debe
   estar acotado al ancho disponible o desborda la página entera. */
body.pg-interv .traza-scroll {
  border: 1px solid var(--linea); border-radius: var(--r);
  max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch;
}
body.pg-interv #trazaTabla thead th {
  background: var(--azul-claro); color: var(--navy);
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .3px;
  padding: 10px 11px; border-bottom: 1px solid var(--linea);
}
body.pg-interv #trazaTabla tbody td {
  padding: 10px 11px; border-bottom: 1px solid var(--linea); font-size: 12.5px;
}
body.pg-interv #trazaTabla tbody tr:hover { background: #FbFdFf; }

/* ---- Barra de guardado ----
   Idéntica a B1.2 por las mismas tres razones que destapó el chequeo de
   cascada: left:var(--sbw) para no pasar bajo el sidebar, safe-area-inset
   conservado, y en móvil por encima de .ui-bn (fixed, bottom:0, z-index 40).
   OJO: aquí la barra nace con [hidden] (solo modo ejecución/edición), así
   que la regla display:flex no debe resucitarla. */
body.pg-interv .barra-guardar {
  position: fixed;
  bottom: 0;
  left: var(--sbw);
  right: 0;
  z-index: 20;
  display: flex; gap: 12px; align-items: center;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom));
  margin: 0;
  background: var(--card);
  border-top: 1px solid var(--linea);
  box-shadow: 0 -2px 12px rgba(0,31,63,.07);
}
body.pg-interv .barra-guardar[hidden] { display: none; }
body.pg-interv .contenido { padding-bottom: 96px; }
body.pg-interv .btn-guardar {
  flex: 1; border: 1px solid var(--orange); background: var(--orange); color: #3a1c00;
  border-radius: 12px; padding: 16px 18px; font-size: 16px; font-weight: 800;
}
body.pg-interv .btn-guardar:hover { background: var(--orange-600); }
body.pg-interv .btn-guardar:disabled { opacity: .6; cursor: not-allowed; }
body.pg-interv .contador { color: var(--suave); font-size: 12.5px; font-weight: 700; white-space: nowrap; }

/* ---- Visor de evidencias ----
   El contenedor trae estilos EN LÍNEA (z-index 1000, por encima de todo el
   chrome nuevo: correcto). Solo se reviste lo que no está en línea. */
body.pg-interv #evidVisor .btn-cambiar { flex: 0 0 auto; }
body.pg-interv #evidGrid img { border-radius: var(--r); border: 1px solid var(--linea); }

@media (max-width: 767px) {
  body.pg-interv .fila { flex-direction: column; gap: 0; }
  body.pg-interv .grupo { padding: 13px; margin-bottom: 11px; }
  body.pg-interv .grupo-titulo { font-size: 11px; margin-bottom: 10px; }
  body.pg-interv .foto-boton { padding: 24px 14px; font-size: 15px; }
  body.pg-interv .barra-guardar {
    left: 0;
    bottom: calc(60px + env(safe-area-inset-bottom));
    padding: 11px 14px;
  }
  body.pg-interv .contenido { padding-bottom: 150px; }
  body.pg-interv .btn-guardar { padding: 17px 16px; }
  body.pg-interv .contador { display: none; }
  body.pg-interv .foto-fallo-acc .btn-cambiar { flex: 1 1 100%; padding: 14px; font-size: 15px; }
  body.pg-interv #enProceso .resultado,
  body.pg-interv #resultados .resultado { flex-wrap: wrap; padding: 14px; }
  /* La tabla de repuestos en 4 columnas se estrangula en un teléfono: la
     descripción queda en dos caracteres. Se le da su propio renglón. */
  body.pg-interv .mat-head { display: none; }
  body.pg-interv .mat-row {
    grid-template-columns: 1fr 62px 34px;
    grid-template-areas: "desc desc desc" "cant precio quitar";
    gap: 8px; padding: 12px 10px;
  }
  body.pg-interv .mat-row > *:nth-child(1) { grid-area: desc; }
  body.pg-interv .mat-row > *:nth-child(2) { grid-area: cant; }
  body.pg-interv .mat-row > *:nth-child(3) { grid-area: precio; }
  body.pg-interv .mat-row > *:nth-child(4) { grid-area: quitar; }
  body.pg-interv .mat-tabla.sin-precio .mat-row {
    grid-template-columns: 1fr 62px 34px;
    grid-template-areas: "desc desc desc" "cant cant quitar";
  }
}

/* =====================================================================
   B1.3 — AJUSTE DE DENSIDAD MÓVIL en Intervenciones e Informes
   (validación de campo, 20-jul-2026)

   Origen del defecto: la lección de F1 fue "no amontonar", y la apliqué
   subiendo la tipografía en móvil. Las reglas @media de estas dos pantallas
   escalan hacia ARRIBA respecto al escritorio (.resultado-cod 14.5 → 15.5,
   los .btn-cambiar de acción 13.5 → 15). En un teléfono al 100 % eso obliga
   a alejar la pantalla para abarcar el formulario.

   Criterio: el CONTENIDO baja un punto; la ZONA TÁCTIL no se toca. Los
   botones conservan su padding, así que siguen midiendo ~50 px de alto —
   se lee más texto por pantalla sin perder puntería con guante.

   REGLA QUE NO SE TOCA: los campos de formulario se quedan en 16px. Por
   debajo de eso iOS hace zoom automático al enfocar y descoloca el layout;
   ese 16px es funcional, no estético.
   ===================================================================== */
@media (max-width: 767px) {

  /* ---- Intervenciones ---- */
  body.pg-interv .btn-guardar { font-size: 15px; }          /* padding intacto → mismo alto táctil */
  body.pg-interv .foto-fallo-acc .btn-cambiar { font-size: 14px; }
  body.pg-interv .btn-cambiar,
  body.pg-interv .btn-mejorar { font-size: 13px; }
  body.pg-interv .resultado-cod { font-size: 14px; }
  body.pg-interv .resultado-meta { font-size: 12px; }
  body.pg-interv .grupo-titulo { font-size: 10.5px; }
  body.pg-interv .ayuda { font-size: 12px; }
  body.pg-interv .campo label { font-size: 11px; }
  body.pg-interv .activo-sel-info strong { font-size: 14px; }
  body.pg-interv .activo-sel-info small { font-size: 11.5px; }
  body.pg-interv #otContextoBody { font-size: 13px; line-height: 1.55; }
  body.pg-interv #soloLecturaBanner,
  body.pg-interv .edit-banner { font-size: 12.5px; }
  body.pg-interv #trazaTabla tbody td { font-size: 12px; }
  body.pg-interv .mat-row input { font-size: 16px; }        /* iOS: no bajar */
  body.pg-interv .foto-boton { font-size: 14px; padding: 20px 14px; }

  /* ---- Informes ---- */
  body.pg-informe .resultado-cod { font-size: 14px; }
  body.pg-informe .resultado-meta { font-size: 12px; }
  body.pg-informe #lista .btn-cambiar { font-size: 14px; }  /* de 15; padding 14px intacto */
  body.pg-informe .inf-acciones .btn-cambiar { font-size: 14px; }
  body.pg-informe .grupo-cab strong { font-size: 12.5px; }
  body.pg-informe .grupo-cab small { font-size: 11.5px; }
  body.pg-informe .ff-cab strong { font-size: 14.5px; }
  body.pg-informe .ff-hint { font-size: 12px; }
  body.pg-informe #infPreviewTitulo { font-size: 14.5px !important; }
  body.pg-informe #infFirmaBloque .btn-cambiar { font-size: 13px; }
}

/* =====================================================================
   B2.1 — EMPRESAS (pg-empresas). Arranca el BLOQUE 2 (oficina). Sección
   autónoma: no edita ninguna regla anterior.

   Es la pantalla más pequeña del sistema (154 líneas de HTML) y la primera
   que no se usa en campo: se trabaja sentado, en escritorio, aunque el
   supervisor también la abre desde el teléfono.

   Dos cambios que no son puramente cosméticos y quedan justificados abajo:
   la barra de guardado fija y la reserva visual del RUT.
   ===================================================================== */

/* ---- Lista de empresas ----
   La trampa de siempre, cuarta vez: styles.css:352 capa .resultados a 340px
   y su único override apunta a #lista, que aquí tampoco existe. */
body.pg-empresas #empLista {
  max-height: none;
  overflow: visible;
  list-style: none; margin: 0; padding: 0;
  background: var(--card);
  border: 1px solid var(--linea);
  border-radius: var(--r);
}
body.pg-empresas #empLista:empty { display: none; }
body.pg-empresas #empLista .resultado {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 13px 14px; background: transparent;
  border: 0; border-bottom: 1px solid var(--linea);
  text-align: left; flex-wrap: wrap;
}
body.pg-empresas #empLista .resultado:last-child { border-bottom: 0; }
body.pg-empresas #empLista .resultado:hover { background: #FbFdFf; }
body.pg-empresas .resultado-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
body.pg-empresas .resultado-cod { color: var(--navy); font-weight: 800; font-size: 14.5px; }
body.pg-empresas .resultado-meta { color: var(--suave); font-size: 12.5px; }
body.pg-empresas .resultados-cab { color: var(--suave); font-size: 12px; font-weight: 700; margin-bottom: 8px; }
body.pg-empresas .vacio { padding: 14px; color: var(--suave); font-size: 13.5px; list-style: none; }

/* Las acciones de la fila. Solo existen para quien puede gestionar: el
   render las omite por completo, no las deshabilita. */
body.pg-empresas #empLista .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 9px 12px; font-size: 12.5px; font-weight: 700;
  white-space: nowrap; text-decoration: none;
}
body.pg-empresas #empLista .btn-cambiar:hover { background: var(--bg); border-color: var(--orange); }
/* El enlace al RUT se distingue: es un documento, no una acción sobre la fila. */
body.pg-empresas .btn-emp-rut { color: var(--suave); }

/* ---- Formulario ---- */
body.pg-empresas .campo { margin-bottom: 15px; }
body.pg-empresas .campo label {
  font-size: 12px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--suave); font-weight: 800; margin-bottom: 6px;
}
body.pg-empresas .fila { display: flex; gap: 12px; }
body.pg-empresas .fila .campo { flex: 1; }
body.pg-empresas input[type="text"],
body.pg-empresas input[type="email"],
body.pg-empresas input[type="search"],
body.pg-empresas select,
body.pg-empresas textarea {
  border: 1px solid var(--linea); border-radius: 11px;
  padding: 13px 13px; font-size: 16px;      /* 16px: iOS no hace zoom al enfocar */
  background: var(--card); color: var(--tinta);
}
body.pg-empresas input:focus, body.pg-empresas select:focus, body.pg-empresas textarea:focus {
  border-color: var(--orange); box-shadow: 0 0 0 3px rgba(255,133,27,.18); outline: 0;
}
/* La sigla NO es un campo editable: es la llave de los códigos GTC 62 de todos
   los activos de la empresa. Se lee como dato del sistema. */
body.pg-empresas .codigo-auto {
  font-family: ui-monospace, Consolas, monospace;
  background: var(--azul-claro) !important; color: var(--navy);
  font-weight: 800; letter-spacing: .5px;
}
body.pg-empresas .ayuda { color: var(--suave); font-size: 12.5px; line-height: 1.5; }
body.pg-empresas .edit-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--ambar-bg); border: 1px solid #EBD9A6;
  border-left: 4px solid var(--ambar);
  border-radius: var(--r); padding: 12px 14px; margin-bottom: 14px;
  color: var(--navy); font-size: 13.5px;
}
body.pg-empresas #empSinAcceso {
  background: var(--azul-claro); border: 1px solid #C5D6F2;
  border-left: 4px solid var(--navy);
  border-radius: var(--r); padding: 14px 16px;
  color: var(--navy); font-size: 13.5px;
}

/* ---- RESERVA VISUAL de IA-CAPTURA-01 ----
   Mismo patrón que "Documentos del activo" en F3: el botón deshabilitado y
   marcado "pronto". Las reglas de allá están acotadas a body.pg-hoja, así que
   se declaran aquí en vez de ampliar su ámbito — cada pantalla es autónoma.
   Nada en esta sección promete una acción que el sistema no pueda cumplir. */
body.pg-empresas .doc-vacio {
  border: 1.5px dashed var(--linea);
  border-radius: var(--r);
  background: #FaFcFe;
  padding: 24px 20px;
  text-align: center;
  margin-top: 6px;
}
body.pg-empresas .doc-ico { font-size: 32px; line-height: 1; margin-bottom: 8px; }
body.pg-empresas .doc-vacio b { display: block; color: var(--navy); font-size: 15px; margin-bottom: 5px; }
body.pg-empresas .doc-vacio p {
  margin: 0 auto 15px; max-width: 460px;
  color: var(--suave); font-size: 13px; line-height: 1.5;
}
body.pg-empresas .doc-tipos {
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-bottom: 16px;
}
body.pg-empresas .doc-chip {
  border: 1px solid var(--linea); background: var(--card); color: var(--suave);
  border-radius: 999px; padding: 6px 13px; font-size: 12.5px; font-weight: 700;
}
body.pg-empresas .btn-xl {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 14px; padding: 16px 20px; font-size: 15.5px; font-weight: 800; white-space: nowrap;
}
body.pg-empresas .doc-btn[disabled] {
  opacity: .55; cursor: not-allowed;
  display: inline-flex; align-items: center; gap: 9px;
}
body.pg-empresas .doc-pronto {
  background: var(--azul-claro); color: var(--navy);
  border-radius: 999px; padding: 2px 9px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .5px; text-transform: uppercase;
}

/* ---- Barra de guardado ----
   NUEVA en esta pantalla: antes los botones iban sueltos al final de un
   formulario de 13 campos, así que en móvil había que bajar hasta el fondo
   para guardar. Se adopta el patrón ya validado en Activos e Intervenciones,
   con sus mismas tres cautelas: left var(--sbw) para no pasar bajo el sidebar,
   safe-area-inset conservado, y en móvil por encima de .ui-bn (fixed, bottom:0,
   z-index 40). Nace [hidden] y solo aparece con el formulario. */
body.pg-empresas .barra-guardar {
  position: fixed;
  bottom: 0;
  left: var(--sbw);
  right: 0;
  z-index: 20;
  display: flex; gap: 12px; align-items: center; justify-content: flex-end;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom));
  margin: 0;
  background: var(--card);
  border-top: 1px solid var(--linea);
  box-shadow: 0 -2px 12px rgba(0,31,63,.07);
}
body.pg-empresas .barra-guardar[hidden] { display: none; }
body.pg-empresas .barra-guardar .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 12px; padding: 15px 18px; font-size: 14.5px; font-weight: 700;
}
body.pg-empresas .btn-guardar {
  border: 1px solid var(--orange); background: var(--orange); color: #3a1c00;
  border-radius: 12px; padding: 15px 22px; font-size: 15.5px; font-weight: 800;
}
body.pg-empresas .btn-guardar:hover { background: var(--orange-600); }
body.pg-empresas .btn-guardar:disabled { opacity: .6; cursor: progress; }
/* Hueco para que el final del formulario no quede tapado por la barra. */
body.pg-empresas .contenido { padding-bottom: 96px; }

@media (max-width: 767px) {
  body.pg-empresas .fila { flex-direction: column; gap: 0; }
  body.pg-empresas .grupo { padding: 13px; margin-bottom: 11px; }
  body.pg-empresas .grupo-titulo { font-size: 11px; margin-bottom: 10px; }
  /* Escala de contenido un punto abajo, como la corrección de B1.3. La zona
     táctil no se toca: el padding de los botones se conserva. */
  body.pg-empresas .resultado-cod { font-size: 14px; }
  body.pg-empresas .resultado-meta { font-size: 12px; }
  body.pg-empresas .campo label { font-size: 11px; }
  body.pg-empresas .ayuda { font-size: 12px; }
  body.pg-empresas .doc-vacio { padding: 20px 14px; }
  body.pg-empresas .doc-vacio p { font-size: 12.5px; }
  body.pg-empresas .btn-xl { font-size: 14.5px; padding: 16px 16px; white-space: normal; }
  /* Las acciones de cada empresa a renglón completo: con guante, sin ambigüedad. */
  body.pg-empresas #empLista .resultado { padding: 14px; }
  /* El nombre de la empresa ocupa su PROPIO renglón. Sin esto, .resultado-info
     es flex:1 con min-width:0 y los tres botones (RUT/Editar/Inactivar) le comen
     el ancho: medido en 375px, el nombre quedaba en 19px de ancho y 101 de alto
     — una letra por línea. El wrap del contenedor no lo salvaba porque un ítem
     que puede encogerse a cero nunca fuerza el salto. */
  body.pg-empresas #empLista .resultado-info { flex: 1 1 100%; margin-bottom: 4px; }
  body.pg-empresas #empLista .btn-cambiar { flex: 1 1 auto; text-align: center; padding: 12px 10px; font-size: 13px; }
  body.pg-empresas .barra-guardar {
    left: 0;
    bottom: calc(60px + env(safe-area-inset-bottom));
    padding: 11px 14px;
  }
  body.pg-empresas .barra-guardar .btn-cambiar { flex: 0 0 auto; }
  body.pg-empresas .btn-guardar { flex: 1; padding: 16px 16px; font-size: 15px; }
  /* Hueco para las DOS barras: la de guardar y la de navegación. */
  body.pg-empresas .contenido { padding-bottom: 150px; }
}

/* =====================================================================
   B2.3 — GERENCIA (pg-gerencia). Bloque 2 (oficina). Migración VISUAL PURA
   del tablero de trazabilidad OT. Sección autónoma: no edita ninguna regla
   anterior. No se toca styles.css ni gerencia.js.

   La gestión de usuarios (editar nombre, crear cuentas) NO entra aquí: es
   USR-01, un frente propio. Esto es solo el revestido del tablero.

   Particularidades frente a lo ya migrado:
   · No usa .resultados sino .ger-tabla (una <table> real, 14 columnas, con
     min-width:1120px que scrollea en horizontal). La trampa de los 340px NO
     aplica; sí hay que respetar ese scroll.
   · KPIs, píldoras e hitos de la línea de tiempo llevan colores SEMÁNTICOS en
     línea (verde/ámbar/rojo por estado). Se CONSERVAN: no son decoración.
   · El gate sigue en gerencia.js con perfilReal() (estricto, sin fallback): no
     se toca, por eso no sube a roles.js como el de Empresas.
   ===================================================================== */

/* El tablero es ancho: el área útil ya la acota el sidebar. Se deja que la
   tabla scrollee dentro de su wrap en vez de empujar la página. */
body.pg-gerencia .ger-main { max-width: none; }

/* ---- Filtros ---- */
body.pg-gerencia .campo { margin-bottom: 13px; }
body.pg-gerencia .campo label {
  font-size: 12px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--suave); font-weight: 800; margin-bottom: 6px;
}
body.pg-gerencia .fila { display: flex; gap: 12px; }
body.pg-gerencia .fila .campo { flex: 1; }
body.pg-gerencia input[type="date"],
body.pg-gerencia input[type="search"],
body.pg-gerencia select {
  border: 1px solid var(--linea); border-radius: 11px;
  padding: 12px 12px; font-size: 16px;      /* 16px: iOS no hace zoom al enfocar */
  background: var(--card); color: var(--tinta); width: 100%;
}
body.pg-gerencia input:focus, body.pg-gerencia select:focus {
  border-color: var(--orange); box-shadow: 0 0 0 3px rgba(255,133,27,.18); outline: 0;
}
body.pg-gerencia .resultados-cab {
  color: var(--suave); font-size: 12px; font-weight: 700; margin: 6px 0 8px;
}

/* ---- Indicadores (KPIs) ----
   Las tarjetas traen su color de fondo por estado desde el JS (semántico): se
   conserva. Solo se afina el contenedor y la tipografía del número/etiqueta,
   que NO están fijadas en línea con color de marca. */
body.pg-gerencia #gerIndicadores { gap: 10px; margin-bottom: 14px; }
body.pg-gerencia #gerIndicadores > div {
  border: 1px solid rgba(0,31,63,.06);
  box-shadow: 0 1px 3px rgba(0,31,63,.04);
}
body.pg-gerencia #gerIndicadores > div > div:first-child { color: var(--navy); }

/* ---- La tabla ----
   styles.css declara .ger-tabla min-width:1120 + nowrap + thead bg #f7f8fa, y
   .ger-tabla-wrap el scroll horizontal. Todo eso se respeta; solo se reviste. */
body.pg-gerencia .ger-tabla-wrap {
  border: 1px solid var(--linea); border-radius: var(--r);
  background: var(--card);
  /* ENCABEZADOS PEGAJOSOS (validación de campo, 20-jul-2026).
     Restricción real: styles.css da overflow-x:auto al wrap para el scroll
     horizontal (13 columnas, min-width 1120). Por el modelo de CSS, un eje con
     overflow != visible fuerza al otro a 'auto', así que el wrap ES un contenedor
     de scroll en AMBOS ejes → un sticky por scroll de VIEWPORT no dispararía.
     La única forma de tener sticky vertical Y scroll horizontal es acotar el
     alto del panel: el scroll ocurre DENTRO, el thead se fija a su borde superior
     y —al ser parte de la misma tabla— se desplaza en lockstep con las columnas
     al ir de lado, sin desalinearse. max-height (no height): pocas filas = panel
     corto; muchas = se topa y scrollea. */
  max-height: calc(100vh - 250px);
  overflow: auto;
}
body.pg-gerencia .ger-tabla { font-size: 12.5px; }
/* Cabecera navy, como la tabla de trazabilidad de Intervenciones. El color del
   texto se fija en el TH (gana al color:#666 heredado del <tr> en línea, sin
   necesidad de !important). El fondo gana al de styles.css por especificidad. */
body.pg-gerencia .ger-tabla thead th {
  background: var(--azul-claro);   /* opaco: las filas no se transparentan bajo el thead fijo */
  color: var(--navy) !important;   /* el <tr> pone color:#666 EN LÍNEA → se necesita !important */
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .3px;
  padding: 11px 10px !important;   /* el TH pone padding EN LÍNEA */
  /* Sticky vertical dentro del panel acotado (ver .ger-tabla-wrap). El borde
     inferior va por box-shadow, no por border: un border-bottom en un th sticky
     se "despega" al scrollear en varios navegadores; el inset shadow no. */
  position: sticky; top: 0; z-index: 3;
  border-bottom: 0 !important;
  box-shadow: inset 0 -1px 0 var(--linea);
}
body.pg-gerencia .ger-tabla tbody td {
  padding: 11px 10px !important;   /* cada TD pone padding:6px 4px EN LÍNEA */
  border-bottom: 1px solid var(--linea);
  color: var(--tinta);
}
body.pg-gerencia .ger-tabla tbody tr:last-child td { border-bottom: 0; }
body.pg-gerencia .ger-tabla tbody tr:hover td { background: #FbFdFf; }
/* El botón "Ver" de cada fila abre la línea de tiempo. */
body.pg-gerencia .ger-ver {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 9px; padding: 7px 12px; font-size: 12px; font-weight: 700; white-space: nowrap;
}
body.pg-gerencia .ger-ver:hover { background: var(--bg); border-color: var(--orange); }

/* ---- Aviso de acceso restringido ---- */
body.pg-gerencia #gerSinAcceso {
  background: var(--azul-claro); border: 1px solid #C5D6F2;
  border-left: 4px solid var(--navy);
  border-radius: var(--r); padding: 14px 16px;
  color: var(--navy); font-size: 13.5px;
}

/* ---- Modal de línea de tiempo ----
   Trae su posicionamiento EN LÍNEA (fixed, inset:0, z-index 2000): correcto,
   por encima del chrome nuevo. Solo se reviste la tarjeta interior y sus hitos,
   sin tocar el overlay. El botón Cerrar hereda .btn-cambiar. */
body.pg-gerencia #gerTimeline > div {
  border-radius: var(--r-lg) !important;   /* la tarjeta pone radius EN LÍNEA */
  border: 1px solid var(--linea);
}
body.pg-gerencia #gerTimeline h3 { color: var(--navy); }
body.pg-gerencia #gerTimeline .btn-cambiar {
  border: 1px solid var(--linea); background: var(--card); color: var(--navy);
  border-radius: 10px; padding: 9px 14px; font-size: 13px; font-weight: 700;
}
body.pg-gerencia #gerTimeline .btn-cambiar:hover { background: var(--bg); }

@media (max-width: 767px) {
  body.pg-gerencia .fila { flex-direction: column; gap: 0; }
  body.pg-gerencia .grupo { padding: 13px; margin-bottom: 11px; }
  body.pg-gerencia .grupo-titulo { font-size: 12px; margin-bottom: 10px; }
  /* Contenido un punto abajo, zona táctil intacta (lección de B1.3). */
  body.pg-gerencia .campo label { font-size: 11px; }
  body.pg-gerencia #gerIndicadores > div > div:first-child { font-size: 18px; }
  /* Los KPIs en dos por fila en vez de estrujarse en una sola línea. */
  body.pg-gerencia #gerIndicadores > div { flex: 1 1 calc(50% - 10px); min-width: 0; }
  body.pg-gerencia .ger-ver { padding: 9px 14px; font-size: 13px; }
}
