/* ============================================================
   RDSafety360 — theme.css (tokens de diseño)
   Color: paleta del panel Studio de Google NotebookLM.
   Estructura/interacción: inspirada en SafetyCulture (módulos
   separados, métricas grandes, checklists con estados claros,
   targets táctiles amplios para uso en campo con guantes).
   NUNCA mezclar: el color NO viene de SafetyCulture.
   ============================================================ */
:root {
  /* Tinta y superficies (NotebookLM: blanco, tinta casi negra, bordes sutiles) */
  --ink: #1F1F1F;
  --ink-soft: #5F6368;
  --bg: #FFFFFF;
  --surface: #F8F9FA;
  --border: #DADCE0;

  /* Pares fondo pastel / acento saturado (familia NotebookLM Studio) */
  --lavanda-bg: #ECE6F6; --lavanda: #6750A4;   /* liderazgo, reglas, comité */
  --verde-bg:   #E2F3E5; --verde:   #1E8E3E;   /* inspecciones, salud, estados OK */
  --ambar-bg:   #FBF3D9; --ambar:   #F2A600;   /* EPP, informes, advertencias */
  --rojo-bg:    #FBE4E1; --rojo:    #D93025;   /* incidentes, emergencias, crítico */
  --azul-bg:    #E3EEFB; --azul:    #1A73E8;   /* capacitación, formularios */
  --magenta-bg: #F6E6F5; --magenta: #9C27B0;   /* análisis, gráficas */
  --indigo-bg:  #E9EAF9; --indigo:  #5C6BC0;   /* tablas de datos, ingeniería */

  /* Semántica de estados (misma familia: verde/ámbar/rojo) */
  --ok: var(--verde);       --ok-bg: var(--verde-bg);
  --warn: var(--ambar);     --warn-bg: var(--ambar-bg);
  --danger: var(--rojo);    --danger-bg: var(--rojo-bg);

  /* Tipografía y forma */
  --font: 'Segoe UI', system-ui, -apple-system, Roboto, 'Helvetica Neue', sans-serif;
  --radius: 16px;
  --radius-sm: 10px;
  --shadow: 0 1px 3px rgba(31,31,31,.08), 0 4px 14px rgba(31,31,31,.06);
  --tap: 48px; /* target táctil mínimo (uso con guantes) */
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--surface); color: var(--ink);
  font-family: var(--font); font-size: 16px; line-height: 1.45;
}
h1, h2, h3 { line-height: 1.2; margin: 0 0 .5rem; }
h1 { font-size: 1.35rem; } h2 { font-size: 1.15rem; } h3 { font-size: 1rem; }
a { color: var(--azul); text-decoration: none; }
img { max-width: 100%; }

/* ---------- Barra superior ---------- */
.appbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: .6rem;
  background: var(--bg); border-bottom: 1px solid var(--border);
  padding: .5rem .8rem; min-height: 56px;
}
.appbar .tenant-logo { width: 34px; height: 34px; border-radius: 8px; object-fit: contain; background: var(--surface); }
.appbar .tenant-name { font-weight: 600; font-size: .95rem; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- Navegación inferior (mobile-first) ---------- */
.bottomnav {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 30;
  display: flex; background: var(--bg); border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
.bottomnav a {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: .45rem 0 .5rem; min-height: var(--tap);
  color: var(--ink-soft); font-size: .68rem; font-weight: 600;
}
.bottomnav a .icon { font-size: 1.25rem; line-height: 1; }
.bottomnav a.active { color: var(--azul); }

main.page { padding: .9rem .9rem 5.5rem; max-width: 780px; margin: 0 auto; }
@media (min-width: 900px) { main.page { max-width: 980px; } }

/* ---------- Tarjetas y métricas (estilo SafetyCulture) ---------- */
.card {
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1rem; box-shadow: var(--shadow);
  margin-bottom: .9rem;
}
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .6rem; margin-bottom: .9rem; }
.metric {
  border-radius: var(--radius); padding: .8rem .9rem; border: 1px solid var(--border);
  background: var(--bg);
}
.metric .value { font-size: 1.7rem; font-weight: 700; }
.metric .label { font-size: .78rem; color: var(--ink-soft); font-weight: 600; }
.metric.tone-ok    { background: var(--ok-bg);    border-color: transparent; } .metric.tone-ok .value    { color: var(--ok); }
.metric.tone-warn  { background: var(--warn-bg);  border-color: transparent; } .metric.tone-warn .value  { color: #9A6A00; }
.metric.tone-danger{ background: var(--danger-bg);border-color: transparent; } .metric.tone-danger .value{ color: var(--danger); }

/* ---------- Grilla de módulos (mapa de color por elemento del sistema) ---------- */
.modules-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .6rem; }
.module-card {
  border-radius: var(--radius); padding: .85rem; min-height: 96px; cursor: pointer;
  border: none; text-align: left; font-family: inherit; font-size: .85rem; font-weight: 600;
  display: flex; flex-direction: column; justify-content: space-between; gap: .4rem;
  color: var(--ink);
}
.module-card .mod-icon {
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255,255,255,.75); font-size: 1.05rem;
}
.module-card .mod-soon { font-size: .68rem; font-weight: 600; color: var(--ink-soft); }

/* ---------- Botones (alto contraste, targets amplios) ---------- */
/* Alto máximo de botón en TODA la app: 26px (pedido explícito del
   usuario, reemplaza el target táctil de 48px que traía --tap).
   Aplica solo a <button>/.btn reales — no a filas clicables
   (.list-row), navegación (.sidenav-item/.bottomnav) ni campos de
   formulario, que siguen usando --tap. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
  min-height: 26px; padding: .2rem .75rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg); color: var(--ink);
  font: 600 .8rem var(--font); cursor: pointer; touch-action: manipulation;
}
.btn-primary { background: var(--azul); border-color: var(--azul); color: #fff; }
/* Botones de borrado: texto AMARILLO sobre rojo (pedido explícito).
   Se usa amarillo puro y no el --amarillo de la paleta (#F2A600): ese
   sobre el rojo da 2.33:1 de contraste, ilegible. #FFFF00 sube a
   4.44:1, el máximo alcanzable en amarillo sobre este rojo. Queda a un
   pelo del 4.5:1 que pide WCAG AA; si hiciera falta cumplirlo, la
   salida es oscurecer el rojo del botón a #C62828 (5.24:1). */
.btn-danger  { background: var(--rojo); border-color: var(--rojo); color: #FFFF00; }
.btn-ok      { background: var(--verde); border-color: var(--verde); color: #fff; }
.btn-block { width: 100%; }
/* Botones de acción secundaria (cabecera de detalle: Reporte, Marcar
   obsoleto, Eliminar...) — mismo alto/forma de píldora que un badge
   en vez del target táctil grande de 48px. Usar solo donde el botón
   es una acción secundaria en escritorio, NO en botones primarios de
   captura de campo (esos deben seguir siendo grandes para uso con
   guantes, ver --tap). */
.btn-compact { min-height: 26px; padding: .18rem .65rem; font-size: .8rem; border-radius: 999px; gap: .3rem; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.fab {
  position: fixed; right: 1rem; bottom: 4.6rem; z-index: 25;
  width: 58px; height: 58px; border-radius: 50%; border: none;
  background: var(--azul); color: #fff; font-size: 1.7rem; box-shadow: var(--shadow); cursor: pointer;
}

/* ============ ESTÁNDAR DE VISUALIZACIÓN — base de controles ============
   Todo control de captura adopta el mismo aspecto, esté o no envuelto en un
   .field. Se usa :where() para que la especificidad sea la de un elemento
   simple: cualquier regla con clase (.cell-input, .jha-matrix, .matrix-field,
   label.field/div.field) la sobrescribe y conserva su tratamiento propio. Así
   los inputs "crudos" de cualquier pantalla quedan estandarizados sin romper
   las matrices ni las capturas en línea. Se excluyen checkbox/radio/file/etc. */
input:where(:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=range]):not([type=color]):not([type=submit]):not([type=button]):not([type=hidden])),
select,
textarea {
  min-height: var(--tap); padding: .5rem .7rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--ink); font: 400 1rem var(--font);
}
textarea:where(*) { min-height: 72px; resize: vertical; }

/* ---------- Formularios ---------- */
label.field { display: block; margin-bottom: .8rem; font-size: .82rem; font-weight: 600; color: var(--ink-soft); }
label.field > input, label.field > select, label.field > textarea {
  display: block; width: 100%; margin-top: .3rem;
  min-height: var(--tap); padding: .55rem .7rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg); color: var(--ink);
  font: 400 1rem var(--font);
}
label.field > textarea { min-height: 84px; resize: vertical; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--azul); outline-offset: 1px; border-color: var(--azul); }

/* ---------- Listas de registros ---------- */
.list-row {
  display: flex; align-items: center; gap: .7rem;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: .7rem .8rem; margin-bottom: .5rem; min-height: var(--tap);
}
.list-row .row-main { flex: 1; min-width: 0; }
.list-row .row-title { font-weight: 600; font-size: .92rem; }
.list-row .row-sub { font-size: .78rem; color: var(--ink-soft); }

/* ---------- Badges / semáforos ---------- */
.badge {
  display: inline-block; padding: .18rem .6rem; border-radius: 999px;
  font-size: .72rem; font-weight: 700;
}
.badge-ok     { background: var(--ok-bg); color: var(--ok); }
.badge-warn   { background: var(--warn-bg); color: #9A6A00; }
.badge-danger { background: var(--danger-bg); color: var(--danger); }
.badge-info   { background: var(--azul-bg); color: var(--azul); }
.badge-neutral{ background: var(--surface); color: var(--ink-soft); border: 1px solid var(--border); }

/* ---------- Checklist (estados visuales claros) ---------- */
.check-item { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .7rem; margin-bottom: .55rem; background: var(--bg); }
.check-item .ci-label { font-weight: 600; font-size: .92rem; margin-bottom: .5rem; }
.check-toggle { display: flex; gap: .5rem; }
.check-toggle button {
  flex: 1; min-height: 26px; padding: .2rem; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--bg); font: 700 .8rem var(--font); cursor: pointer; color: var(--ink-soft);
}
.check-toggle button.sel-ok  { background: var(--ok-bg);  border-color: var(--ok);  color: var(--ok); }
.check-toggle button.sel-bad { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); }

/* ---------- Matriz de selección peligro→riesgo→medida (JHA/AST) ----------
   ══ ESTO ESTABA EN .37rem — SEIS PÍXELES ══════════════════════════════════
   La intención era «ver todas las opciones de un vistazo», y el resultado fue
   que no se veía ninguna. El despacho lo dijo después de presentar la
   aplicación en público: «hay cinco, seis, siete opciones en el riesgo o el
   peligro de una actividad, y no se ven; ni siquiera yo podía verlas».
   Encoger la letra no es una forma de que quepan más cosas: es una forma de
   que no se lea nada. Ahora la cuadrícula usa columnas anchas y letra normal,
   y si hay muchas opciones se hace scroll — que es lo que se hace siempre. */
.pick-matrix {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: .4rem;
  max-height: 360px; overflow-y: auto; padding: .5rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg);
}
.pick-matrix label {
  display: flex; gap: .45rem; align-items: flex-start; font-size: .92rem; line-height: 1.4;
  padding: .4rem .5rem; border: 1px solid var(--border); border-radius: 5px; cursor: pointer; background: var(--surface);
}
.pick-matrix label:has(input:checked) { background: var(--azul-bg); border-color: var(--azul); font-weight: 600; }
.pick-matrix input[type="checkbox"] { width: 17px; height: 17px; flex: none; margin-top: .15rem; }

.pick-matrix-cols {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(205px, 1fr)); gap: .5rem;
  max-height: 420px; overflow-y: auto; padding: .4rem;
}
.pick-col { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .25rem; background: var(--bg); align-self: start; }
.pick-col-head {
  font-weight: 700; font-size: .78rem; letter-spacing: .02em; text-transform: uppercase;
  color: var(--ink-soft); border-bottom: 1px solid var(--border); padding-bottom: .15rem; margin-bottom: .2rem;
}
.pick-col label {
  display: flex; gap: .45rem; align-items: flex-start; font-size: .92rem; line-height: 1.4;
  margin: .3rem 0; cursor: pointer;
}
.pick-col label:has(input:checked) { color: var(--azul); font-weight: 600; }
.pick-col input[type="checkbox"] { width: 17px; height: 17px; flex: none; margin-top: .15rem; }

.pick-lock-hint {
  display: flex; align-items: center; gap: .5rem; font-size: .85rem; padding: .4rem .55rem;
  border-radius: var(--radius-sm); margin: .3rem 0; background: var(--ambar-bg); color: #8a6400;
}
.pick-lock-hint.done { background: var(--ok-bg); color: var(--ok); }
.pick-lock-hint button { margin-left: auto; }

/* Dentro de un modal (editar línea existente) estos mismos componentes
   se usan a tamaño normal, no al tamaño reducido de la fila de
   captura inline — ahí sí hay espacio de sobra. */
/* Dentro de un modal hay MÁS espacio, no menos: estas reglas existían para
   agrandar lo que en la fila de captura iba diminuto. Ahora que la base ya es
   legible, solo aflojan la cuadrícula — nunca encogen la letra. */
.modal .pick-matrix { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: .4rem; padding: .5rem; max-height: 320px; }
.modal .pick-matrix label { font-size: .95rem; padding: .45rem .55rem; gap: .45rem; }
.modal .pick-matrix input[type="checkbox"] { width: 18px; height: 18px; }
.modal .pick-matrix-cols { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: .6rem; padding: .3rem; max-height: 360px; }
.modal .pick-col { padding: .45rem; }
.modal .pick-col-head { font-size: .82rem; padding-bottom: .35rem; margin-bottom: .4rem; }
.modal .pick-col label { font-size: .82rem; gap: .35rem; margin: .3rem 0; }
.modal .pick-col input[type="checkbox"] { width: 18px; height: 18px; }
.modal .pick-lock-hint { font-size: .82rem; padding: .4rem .6rem; }

/* ---------- Matriz de captura de JHA/AST (misma disposición del
   reporte impreso: cada línea se llena de una vez, por columnas).
   Letras a la mitad del tamaño original (pedido del usuario). ---------- */
/* Ya no hay nada que desplazar: la tabla se ajusta al contenedor. Se deja
   `auto` por si un módulo mete una tabla más ancha, pero en la práctica no
   aparece barra. */
.jha-matrix-wrap { overflow-x: auto; max-width: 100%; border: 1px solid var(--border); border-radius: var(--radius-sm); }
/* ══ TAMAÑO DE LA MATRIZ DE CAPTURA ═══════════════════════════════════════
   Historia de este número, porque ha subido dos veces: empezó en .39rem
   (≈6px, ilegible), se subió a .8rem alineándola con .btn-compact — «son
   acciones densas de escritorio»— y el despacho volvió a decir que no se
   lee: «actividad, paso, peligro, riesgo, impacto, medida de control están
   muy pequeñas, tiene que buscar una visión normal».
   Ahora va a .95rem con padding de verdad. La densidad no vale nada si hay
   que acercarse a la pantalla para elegir un control: quien llena un AST lo
   hace leyendo frases largas, no cifras.
   ══ CERO SCROLL LATERAL ══════════════════════════════════════════════════
   El `min-width` existía para que, al no caber, la tabla se desplazara en
   horizontal en vez de aplastar las columnas. Al subir la letra lo elevé a
   1100px y eso forzó la barra lateral en pantallas normales — el despacho lo
   cortó en seco: «no puede salirse de la pantalla, cero scroll lateral».
   Se quita: la tabla se ajusta al ancho disponible y el texto de cada celda
   se parte en varias líneas, que es lo que hace un formulario de papel. El
   alto crece un poco; el ancho nunca se sale. */
table.jha-matrix { width: 100%; border-collapse: collapse; font-size: .95rem; }
/* ══ «Rie / sg / o» ═══════════════════════════════════════════════════════════════════
   Esto iba en `anywhere`, que parte por CUALQUIER carácter: en la pantalla de un JHA las
   cabeceras salían troceadas —«Rie/sg/o», «Nive/l», «Jerar/quía»— y costaba entender de
   qué columna se hablaba. Y hay una causa más de fondo: `anywhere` deja que el ancho
   mínimo de la columna baje hasta UN carácter, así que el navegador la estruja sin
   piedad para dar sitio a las columnas de texto largo.
   `break-word` parte una palabra solo si no cabe ella sola, y calcula el ancho mínimo
   por la palabra más larga. Las cabeceras dejan de trocearse y las columnas recuperan un
   ancho razonable. Si aun así la tabla no cabe, se desplaza DENTRO de `.jha-matrix-wrap`
   (que ya tiene `overflow-x: auto`); la página en sí nunca se desplaza de lado. */
table.jha-matrix td, table.jha-matrix th { overflow-wrap: break-word; }
/* Las cabeceras cortas no bajan de aquí: es lo que impide que «Riesgo» o «Nivel» queden
   convertidos en una columna de dos letras cuando la tabla va apretada. */
table.jha-matrix th { min-width: 4.5rem; }
table.jha-matrix th, table.jha-matrix td { border: 1px solid var(--border); padding: .4rem .5rem; text-align: left; vertical-align: top; }
/* SIN `white-space: nowrap`. Era lo que forzaba la barra lateral: una cabecera
   como «Medidas preventivas / controles» reclamaba su ancho completo en una sola
   línea y estiraba la tabla por encima del contenedor. Partida en dos renglones
   ocupa dos centímetros de alto y ahorra el scroll entero. */
table.jha-matrix th { background: var(--surface); font-size: .85rem; line-height: 1.25; }
/* El badge de nivel de riesgo se alinea con la letra de la tabla; el
   padding se recorta para que no engorde la fila más que un campo. */
table.jha-matrix .badge { font-size: .82rem; padding: .2rem .5rem; }
/* La fila de captura (nueva línea y edición en sitio) va al doble de
   alto que una fila guardada: es donde se teclea, y con una sola línea
   el texto queda apretado contra el borde. Las filas ya guardadas
   siguen compactas para que la matriz se lea densa. Aplica a los
   cuatro módulos que comparten esta tabla: JHA/AST, hallazgos de
   inspección y hallazgos de auditoría.
   El `height` de un <td> se comporta como mínimo, así que la fila
   sigue creciendo si un campo auto-extensible se pasa de ese alto.
   Medido sobre el CSS anterior, las filas de captura iban desiguales
   entre módulos (41px en JHA, 36px en hallazgos, 25px al editar). Se
   fijaron todas en 82px; al subir la letra a .95rem se suben a 104px
   para que el texto no vuelva a quedar apretado contra el borde. */
table.jha-matrix tr.draft-row td { background: var(--azul-bg); height: 104px; }
/* ══ CUANDO LA CAPTURA ES UNA REJILLA, NO UNA FILA DE COLUMNAS ══════════════
   El alto fijo y los mínimos de arriba son para el formato viejo —un campo por
   columna—. En los módulos ya convertidos, la fila es UNA celda con la rejilla
   rotulada dentro: ahí el alto lo pone el contenido, y forzarlo dejaría un hueco
   debajo cuando los campos caben en dos líneas. */
table.jha-matrix tr.draft-row td:has(.prm-capture-grid) { height: auto; padding: .7rem .8rem; }
table.jha-matrix tr.draft-row .prm-capture-grid { gap: .7rem; }
table.jha-matrix tr.draft-row .prm-capture-title { margin-bottom: .6rem; }
/* Solo se estiran los campos que son el único control de su celda.
   Las celdas que apilan dos (peligro+libre, tipo+categoría,
   causa+plan, riesgo+chip, foto+carga) ya suman ese alto entre los
   dos; si se les forzara el mínimo a cada uno, la fila se iría al
   doble otra vez y quedaría descuadrada respecto de las demás. */
table.jha-matrix tr.draft-row td > input[type="text"]:only-child,
table.jha-matrix tr.draft-row td > select:only-child,
table.jha-matrix tr.draft-row td > textarea:only-child,
table.jha-matrix tr.draft-row td > .cell-picker:only-child > .cell-picker-btn { min-height: 96px; }
table.jha-matrix tr.saved-row { cursor: pointer; }
table.jha-matrix tr.saved-row:hover td { background: var(--surface); }
/* Los campos de la matriz siguen exentos del --tap de 48px (son de
   escritorio, no captura con guantes), pero 26px era demasiado poco: en
   una celda donde se elige «Sustituir la sustancia por una de menor
   toxicidad» el campo tiene que poder mostrarlo. Se suben a 38px y .95rem,
   en línea con el resto de la tabla. */
.jha-matrix input[type="text"], .jha-matrix select, .jha-matrix textarea {
  width: 100%; border: 1px solid var(--border); border-radius: 6px;
  min-height: 38px; padding: .4rem .55rem;
  font: 400 .95rem var(--font); background: var(--bg);
}
/* Auto-extensible: arranca en una línea y el alto lo fija autoTextarea()
   (ui.js) sobre scrollHeight a medida que se escribe. `resize: none`
   porque el tirador manual pelearía con ese alto calculado; overflow
   oculto para que no aparezca la barra interna antes de crecer. */
.jha-matrix textarea {
  resize: none; overflow: hidden; line-height: 1.3;
}
/* Columna de Firma en la matriz de firmas de trabajadores: algo más
   ancha que una celda normal para que la imagen de la firma se lea,
   pero sin comerse la tabla. Al bajar este mínimo, el ancho sobrante
   lo reparten solas las demás columnas (la tabla es width:100% con
   layout automático), así que no hace falta fijarlas. */
table.jha-matrix .sig-col, table.jha-matrix th.sig-col { min-width: 110px; text-align: center; }

/* Factores de falla / Referencias (fila de acciones, crear y editar):
   mismo look que un encabezado de la matriz (fondo gris, letra
   chica) pegado arriba del campo, con el alto compacto de una celda
   de la matriz — pero más ancho que una celda normal para que quepa
   texto libre cómodo. */
.matrix-field { display: inline-flex; flex-direction: column; }
.matrix-field-label {
  background: var(--surface); border: 1px solid var(--border); border-bottom: none;
  border-radius: 4px 4px 0 0; font-size: .88rem; font-weight: 700; color: var(--ink-soft);
  padding: .25rem .5rem; white-space: nowrap;
}
.matrix-field input[type="text"], .matrix-field textarea { border-radius: 0 0 4px 4px; min-height: 38px; margin: 0; }

/* Captura de línea de la Matriz de Riesgos por Puesto. Esa línea tiene
   ~20 campos contra 11 columnas visibles: repartirlos por columna
   obligaría a encoger la letra. En su lugar la fila ocupa un colspan y
   los campos bajan a varias líneas en esta rejilla, conservando el
   .8rem del resto de formularios. */
.prm-capture-group { margin-bottom: .7rem; }
.prm-capture-group:last-child { margin-bottom: 0; }
.prm-capture-title {
  font-size: .88rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  color: var(--ink-soft); border-bottom: 1px solid var(--border);
  padding-bottom: .2rem; margin-bottom: .4rem;
}
.prm-capture-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: .6rem; }
/* En un contenedor angosto (la app Lite, dentro de su propia tabla ancha
   con scroll horizontal — jha-matrix-wrap) el `auto-fit` calcula contra el
   ancho de LA TABLA, no el de la pantalla, y termina poniendo 2 columnas
   que sacan campos completos (Tipo, Responsable) fuera de la vista sin
   ningún indicio salvo una barra de scroll. Se vio en Autoreporte (Lite):
   una sola columna, a 100% del ancho real, siempre en pantallas angostas. */
@media (max-width: 480px) { .prm-capture-grid { grid-template-columns: 1fr; } }
/* Los .matrix-field de la rejilla se estiran a la celda: en inline-flex
   (su valor por defecto) cada uno se encogería a su contenido y las
   columnas quedarían desalineadas entre sí. */
.prm-capture-grid .matrix-field { display: flex; width: 100%; }
.prm-capture-grid .matrix-field > input,
.prm-capture-grid .matrix-field > select,
.prm-capture-grid .matrix-field > textarea { width: 100%; font: 400 .95rem var(--font); min-height: 38px; }
/* El div envoltorio de un campo con datalist no debe romper el ancho. */
.prm-capture-grid .matrix-field > div { width: 100%; }
.prm-capture-grid .matrix-field > div > input,
.prm-capture-grid .matrix-field > div > select { width: 100%; font: 400 .8rem var(--font); min-height: 26px; }

/* Tarjeta de captura en línea (inlineCapture.js): el borde de acento la
   distingue de las tarjetas de solo lectura sin sacar al usuario de la
   página, que es justo lo que hacía el modal que sustituye. */
/* Doble clase a propósito: el bloque Fiori redefine `.card` con el
   atajo `border`, más abajo en este mismo archivo, y con specificity
   igual ganaría por orden y borraría este acento. */
.card.capture-card { border-left: 3px solid var(--azul); }
.capture-actions { display: flex; gap: .5rem; justify-content: flex-end; flex-wrap: wrap; margin-top: .6rem; }

/* Los pickers de celda (riesgo, impacto, nivel, medida) comparten el
   alto/letra de los campos de texto de la matriz; el texto envuelve en
   varias líneas y el botón crece igual que un campo auto-extensible. */
.cell-picker-btn {
  width: 100%; min-height: 38px; font-size: .95rem; padding: .4rem .55rem; border: 1px solid var(--border);
  border-radius: 6px; background: var(--bg); cursor: pointer; text-align: left; color: var(--ink);
  white-space: normal; overflow-wrap: anywhere; line-height: 1.3;
}
.cell-picker-btn.filled { background: var(--bg); border-color: var(--azul); color: var(--azul); font-weight: 700; }
/* position:fixed + coordenadas calculadas por JS (cellPicker() en
   jha.js), no absolute anclado al botón — ver la nota extensa ahí
   sobre por qué (el contenedor de la tabla recorta cualquier hijo
   absolute que se abra hacia abajo desde la última fila). Vive como
   hijo directo de <body>; max-height NO se fija aquí porque esa
   misma función lo inyecta inline en cada apertura contra el espacio
   real disponible (y abre hacia arriba si no cabe hacia abajo) —
   cualquier valor puesto acá quedaría siempre pisado. */
.cell-picker-panel {
  position: fixed; z-index: 60; background: var(--bg); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--shadow); padding: .6rem; overflow-y: auto;
  /* ══ ANCHO DE VERDAD, NO UNA COLUMNA ══════════════════════════════════
     Iba fijo a 250px y el despacho lo señaló: «cuando un botón de lista
     contenga información, al presionarlo tiene que ampliarse a todo el
     ancho, no una columna». En 250px una medida de control como «Sustituir
     la sustancia por una de menor toxicidad» se parte en cuatro renglones y
     hay que scrollear para comparar dos opciones — que es exactamente lo
     que se hace al elegir un control.
     Ahora crece con su contenido hasta 620px, topado en 94vw para que en
     móvil no se salga. El position() de cellPicker() ya reubica el panel
     según su ancho real, así que ensancharlo no lo saca de la pantalla. */
  /* ══ ANCHO PARA CINCO COLUMNAS ═══════════════════════════════════════════
     El despacho lo pidió así: «cabe más al ancho de la pantalla, pon cinco en
     lugar de tres, que se use todo el ancho y así hay menos espacio vertical».
     1180px con opciones de 210px mínimo da exactamente CINCO columnas
     (5×210 + 4 huecos = 1072, y seis no caben). En pantallas menores el
     `auto-fill` va bajando a cuatro, tres, dos y una sin tocar nada, y el 96vw
     impide que se salga en un portátil o en el teléfono. */
     Al subir la página a 1520px el panel se quedó corto en 1180 y volvía a cuatro columnas,
     así que acompaña: 1520 con mínimos de 280px sigue dando CINCO, pero cada opción respira
     ~300px en vez de 230 y las frases largas dejan de partirse. */
  width: max-content; min-width: min(320px, 92vw); max-width: min(94vw, 1520px);
}
.cell-picker-panel label, .cell-picker-panel .pick-item {
  font-size: .95rem; line-height: 1.45;
}
.cell-picker-panel .pick-matrix, .cell-picker-panel .pick-matrix-cols { max-height: 150px; border: none; padding: 0; }
/* .37rem eran ≈6px: el campo de texto libre del selector era ilegible.
   Va al mismo tamaño que el resto del panel. */
.cell-picker-panel textarea { margin-top: .4rem; font-size: .95rem; min-height: 60px; }
.cell-picker-panel .risk-matrix { overflow: auto; }
/* El panel del selector "Nivel" (el único que contiene una
   .risk-matrix) necesita más ancho que los de riesgo/impacto/medida
   para mostrar todas las columnas de la grilla sin scroll horizontal
   interno — se amplía solo para ESE panel, el resto queda en 250px. */
/* Los 420 px de tope venían de cuando la página entera se topaba en 1120: la matriz P×S
   cabía, pero con celdas de 13 px en las que no se leía si un riesgo era Alto o Crítico.
   Es el panel donde SE DECIDE el nivel de riesgo, así que es el que más tiene que leerse.
   Sigue creciendo con su contenido y topado en 94vw, que es lo que evita el scroll lateral
   en el teléfono. */
.cell-picker-panel:has(.risk-matrix) { width: max-content; min-width: 300px; max-width: min(94vw, 720px); }
/* Selector de MEDIDAS de control: el triple de ancho (250 → 750px).
   Sus opciones son frases largas ("Sustituir la sustancia por una de
   menor toxicidad…") que en 250px ocupaban cuatro renglones cada una.
   Se topa en 94vw para que en móvil no se salga de la pantalla; el
   position() de cellPicker() ya reubica el panel según su ancho real. */
/* El «wide» era el parche para el selector de medidas, cuyas frases son largas. Ahora que
   TODOS los paneles son anchos, solo le da algo más de sitio; nunca encoge. */
/* El «wide» era el parche para el selector de medidas, cuyas frases son largas. Ahora que
   TODOS los paneles son anchos, solo le da algo más de sitio; nunca encoge. */
.cell-picker-panel--wide { width: min(96vw, 1520px); }
.cell-picker-panel--wide .pick-matrix { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.cell-picker-panel--wide .pick-matrix-cols { grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }

/* Matriz de riesgo (P×S) dentro del selector "Nivel" del JHA/AST. NO
   toca .risk-matrix a secas — esa clase se usa también en la pantalla
   dedicada de Matriz de Riesgo y otros módulos, donde el tamaño
   normal es el correcto. */
.cell-picker-panel .risk-matrix table { border-spacing: 2px; }
.cell-picker-panel .risk-matrix th {
  font-size: .84rem; padding: .3rem .4rem; max-width: 110px; line-height: 1.25; overflow-wrap: break-word;
}
/* La celda de la esquina ("Probabilidad ↓ / Severidad →" en 2 líneas)
   necesita más ancho que las demás cabeceras — con solo 45px el texto
   se salía hacia la columna siguiente. */
.cell-picker-panel .risk-matrix tr:first-child th:first-child {
  max-width: none; width: 62px; white-space: normal;
}
/* OJO: NUNCA display:flex en un <td> de esta tabla — rompe el layout
   de tabla (las celdas de una fila dejan de alinearse en columnas y
   se apilan todas bajo la primera; así se vio el bug reportado). El
   centrado se logra con text-align + vertical-align, que sí respeta
   la estructura de tabla. */
.cell-picker-panel .risk-matrix td.cell {
  min-width: 60px; height: 58px; border-radius: 4px; font-size: .92rem; padding: .3rem .35rem; line-height: 1.15;
  text-align: center; vertical-align: middle;
}
/* Mismo tamaño que el rótulo (pedido explícito) — ya sin decimales
   (".00" quitado en riskMatrix.js) hay espacio de sobra en la celda. */
.cell-picker-panel .risk-matrix .cell-score { font-size: .92rem; }

/* ---------- Matriz de riesgo (grilla coloreada reutilizable) ---------- */
.risk-matrix { overflow-x: auto; }
.risk-matrix table { border-collapse: separate; border-spacing: 3px; }
.risk-matrix th { font-size: .68rem; color: var(--ink-soft); font-weight: 600; padding: .2rem .35rem; text-align: center; max-width: 90px; }
.risk-matrix th.axis-y { text-align: right; }
.risk-matrix td.cell {
  min-width: 52px; height: 46px; border-radius: 8px; text-align: center;
  color: #fff; font-weight: 700; font-size: .78rem; cursor: pointer; padding: .15rem .3rem;
}
.risk-matrix td.cell.selected { outline: 3px solid var(--ink); outline-offset: 1px; }
.risk-matrix .cell-score { font-size: .65rem; font-weight: 600; opacity: .9; }

/* ---------- Firma ---------- */
/* 160px eran pocos: con el dedo, en un teléfono, la firma no cabía y salía un garabato
   apretado que luego no se parece a la del carnet. Se sube a 220px con el ratón y a 300px
   cuando se apunta con el dedo, que es como se firma de verdad en obra. El `touch-action:
   none` es imprescindible: sin él, arrastrar el dedo hace scroll en vez de dibujar. */
.signature-pad canvas {
  width: 100%; height: 220px; border: 1px dashed var(--border);
  border-radius: var(--radius-sm); background: var(--bg); touch-action: none;
}
@media (pointer: coarse) {
  .signature-pad canvas { height: 300px; }
}

/* ---------- Modal ---------- */
/* POR ENCIMA DEL VISOR DE REPORTES. Estaba en 50 y `.report-overlay` en 100: cualquier
   diálogo abierto DESDE un reporte se dibujaba DEBAJO del reporte —invisible y sin poder
   pulsarse—, y como el modal sí existía en la página, la pantalla quedaba muerta: los
   clics caían en el fondo del diálogo, que no se veía. Se descubrió al añadir el diálogo
   de envío por correo, que se abre precisamente desde la barra del visor. Es el mismo
   modo de fallar que ya dejó una capa de reporte comiéndose veinte protocolos: una capa
   que tapa y que nadie ve. */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 120; background: rgba(31,31,31,.45);
  display: flex; align-items: flex-end; justify-content: center;
}
/* EL MODAL SE ADAPTA A SU CONTENIDO. Antes tenía un tope fijo de 640 px, decidido sin
   mirar lo que iba dentro: una ficha de dos campos y una tabla de siete columnas recibían
   el mismo ancho. El resultado era que la tabla se estrujaba —«Reinstalar conos y cinta de
   delimitación» partido en seis renglones de dos palabras— y encima aparecía scroll
   lateral. Leer así cuesta el triple, y en una pantalla de hallazgos es donde menos
   conviene: es la que se mira con prisa.

   `width: fit-content` pide el ancho que el contenido necesita. Los dos límites son los
   que evitan los dos excesos:
     · `min-width` mantiene los 640 px de siempre para lo estrecho, para que una ficha de
       dos campos no salga como una tirilla, y para que el texto largo siga envolviendo en
       renglones de lectura cómoda en vez de estirarse a una sola línea kilométrica;
     · `max-width: 96vw` impide que se salga de la pantalla. Si aun así el contenido no
       cabe —una matriz de veinte columnas—, el scroll se queda DENTRO de `.tabla-wrap`,
       que es donde debe estar, y no en el modal entero. */
.modal {
  background: var(--bg); border-radius: var(--radius) var(--radius) 0 0;
  width: fit-content; min-width: min(100%, 640px); max-width: 96vw;
  max-height: 92dvh; overflow-y: auto; padding: 1rem 1rem 1.4rem;
}
/* Con `fit-content`, quien pide el ancho es el hijo más ancho — y un párrafo, si se le
   deja, pide TODA su longitud en una sola línea. Medido: un modal de dos campos se iba a
   991 px con renglones de 160 caracteres, ilegibles. Acotando la prosa a una medida de
   lectura, el ancho del modal vuelve a decidirlo la tabla, que es lo que se quería. */
.modal > p, .modal > .muted, .modal > ul, .modal > ol { max-width: 72ch; }
@media (min-width: 700px) {
  .modal-backdrop { align-items: center; }
  .modal { border-radius: var(--radius); }
}
.modal .modal-title { display: flex; justify-content: space-between; align-items: center; margin-bottom: .8rem; }

/* ---------- Toast y estado de conexión ---------- */
.toast {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 5.4rem; z-index: 60;
  background: var(--ink); color: #fff; padding: .6rem 1rem; border-radius: 999px;
  font-size: .85rem; box-shadow: var(--shadow); max-width: 90vw;
}
/* Un fallo no se dice igual que un «guardado». Un aviso rojo, más ancho y con más tiempo
   en pantalla: se lee de reojo en el frente y no se confunde con una confirmación. */
.toast-error { background: var(--rojo, #D93025); font-weight: 600; border-radius: 14px; padding: .7rem 1.1rem; }
.toast-warn  { background: #B87900; font-weight: 600; border-radius: 14px; padding: .7rem 1.1rem; }
.toast-ok    { background: #1E8E3E; }

.offline-banner {
  background: var(--warn-bg); color: #9A6A00; font-size: .78rem; font-weight: 700;
  text-align: center; padding: .3rem .6rem;
}
.sync-chip { font-size: .72rem; font-weight: 700; color: var(--ambar); }

/* ---------- Login / splash (marca de plataforma Mandalay) ---------- */
.login-wrap { min-height: 100dvh; display: grid; place-items: center; padding: 1.2rem; background: var(--bg); }
.login-card { width: 100%; max-width: 380px; text-align: center; }
.login-card .platform-logo { width: 130px; margin: 0 auto 1rem; display: block; }
.powered-by { margin-top: 1.4rem; font-size: .72rem; color: var(--ink-soft); }
.powered-by img { width: 90px; display: block; margin: .3rem auto 0; opacity: .85; }

/* ---------- Reportes imprimibles (JHA, inspecciones) ---------- */
/* POR ENCIMA DE LOS MODALES, y a propósito.
   El visor de impresión suele ABRIRSE DESDE un modal —la ficha del incidente, la del
   permiso— y es lo último que se pide: quien pulsa «Informe» quiere ver el informe, no la
   ficha de la que salió. Estaba en 100 contra los 120 del modal, así que el informe se
   abría DETRÁS y quedaba medio tapado; se vio grabando la pieza de cerrar una acción.
   El 130 lo pone encima del modal (120) sin pisar el aviso de sin conexión ni el lápiz de
   grabación, que viven más arriba. */
.report-overlay {
  position: fixed; inset: 0; z-index: 130; background: var(--bg);
  overflow-y: auto;
}
.report-toolbar {
  position: sticky; top: 0; z-index: 5; display: flex; justify-content: space-between; align-items: center;
  gap: .6rem; padding: .6rem .9rem; background: var(--surface); border-bottom: 1px solid var(--border);
}
.report-page { max-width: 1000px; margin: 0 auto; padding: 1rem 1.2rem 2rem; }
.report-header {
  display: grid; grid-template-columns: auto 1fr auto; gap: .8rem; align-items: center;
  border-bottom: 2px solid var(--ink); padding-bottom: .6rem; margin-bottom: .9rem;
}
.report-header img { width: 58px; height: 58px; object-fit: contain; }
.report-title { font-size: 1.15rem; font-weight: 800; margin: .3rem 0 .1rem; }
.report-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: .2rem .9rem; font-size: .82rem; margin: .5rem 0 .8rem; }
.report-meta b { color: var(--ink-soft); font-weight: 600; }
table.report-table { width: 100%; border-collapse: collapse; font-size: .76rem; margin: .5rem 0 1rem; }
table.report-table th, table.report-table td {
  border: 1px solid var(--border); padding: .35rem .45rem; text-align: left; vertical-align: top;
}
table.report-table th { background: var(--surface); font-size: .7rem; }
.report-activity {
  background: var(--indigo-bg); font-weight: 700; font-size: .8rem; padding: .35rem .5rem;
}
.risk-chip-print { display: inline-block; padding: .1rem .45rem; border-radius: 6px; color: #fff; font-weight: 700; font-size: .72rem; }
.report-photo { width: 110px; height: 82px; object-fit: cover; border-radius: 6px; }

/* ============================================================
   ESTÁNDAR DE INFORME (referencia: informe de presupuesto)
   Toda tabla dentro de un reporte hereda este aspecto sin que el
   módulo tenga que repetir estilos: cabecera azul institucional,
   bandas de agrupación, fila de totales en negativo y códigos de
   documento en Courier azul papermate. Un módulo solo añade clases
   cuando necesita algo que no está aquí.
   ============================================================ */
.report-page table { width: 100%; border-collapse: collapse; margin: .5rem 0 .9rem; }
.report-page table th,
.report-page table td { border: 1px solid #aeb3bd; padding: 3px 5px; font-size: .74rem; vertical-align: top; }
/* ══ CABECERA CLARA, BARRA OSCURA ═══════════════════════════════════════════════════
 *
 * El despacho fijó el 5-ago-2026 el visor de formatos como el estándar de TODOS los
 * informes: «así deberían ser los informes». Ahí la jerarquía es al revés de como estaba —
 * la BARRA DE SECCIÓN es la que va en azul marino, y la cabecera de tabla va clara con
 * texto azul. Teniendo las dos en marino, el documento se lee como una mancha oscura y
 * ninguna de las dos destaca. */
.report-page table th { background: #eef2f8; color: #16306e; text-align: center; font-weight: 600; letter-spacing: .02em; }

/* La barra de sección: es lo que faltaba para que un informe se lea como un documento y
   no como una sucesión de tablas. `reportSection()` ya envuelve cada bloque con su `h2`,
   así que los treinta módulos la heredan sin tocar ni una línea de su código. */
/* Cualquier encabezado del informe, esté donde esté en el árbol. Empecé acotándolo a
   `.report-section > h2` y a dos niveles sueltos, y se quedaban fuera los que cada módulo
   anida dentro de sus propias tarjetas — en el informe de investigación, una de seis. Las
   excepciones van justo debajo. */
.report-page h2, .report-page h3 {
  background: #132a63; color: #fff; font-weight: 600; font-size: .82rem;
  padding: .22rem .55rem; letter-spacing: .04em; text-transform: uppercase;
  margin: .75rem 0 .35rem; border-radius: 0;
}
/* Solo once de los treinta informes usan `reportSection()`; el resto emite su `h2`/`h3`
   suelto. Los selectores de arriba los alcanzan también, para que el estándar no dependa
   de qué helper usó cada módulo.
   Se excluyen los TÍTULOS DE DOCUMENTO —el del PSST, el del procedimiento, el del
   presupuesto—: son la portada del papel, no una sección dentro de él, y ponerlos en
   barra los degradaría a un apartado más. */
.report-page .report-doc-title h2,
.report-page .report-doc-title h3,
.report-page .sop-title h2 {
  background: none; color: inherit; padding: 0; text-transform: none;
  letter-spacing: normal; font-size: 1.05rem; margin: 0;
}
.report-page table td:first-child, .report-page table th:first-child { text-align: left; }
.report-page table tbody tr:nth-child(even) td { background: #fafbfe; }

/* Fila que agrupa (categoría, elemento, área) y fila de cierre con el total.
   Llevan `!important` porque la franja alterna —`tbody tr:nth-child(even) td`— gana por
   especificidad: la pseudoclase cuenta como clase. El resultado era que un total que caía
   en fila par perdía su fondo y se leía como una línea más del detalle. */
.report-page tr.cat-row td { background: #e9eaf9 !important; font-weight: 700; color: #16306e; }
.report-page tr.gran-row td { background: #132a63 !important; color: #fff; font-weight: 700; }
/* Celdas numéricas y de importe */
.report-page td.n, .report-page th.n { text-align: right; font-variant-numeric: tabular-nums; }
.report-page td.concepto { padding-left: 1rem; }

/* Las tablas propias del SOP heredan el estándar: alternancia de fila y
   cabecera azul, sin renunciar a su formato de documento controlado. */
.report-page table.report-table tbody tr:nth-child(even) td { background: #fafbfe; }
.report-page .report-doc-title .sop-kind { font-size: .68rem; letter-spacing: .18em; color: #1A73E8; }
.report-page .report-doc-title h2 { margin: 0; }

/* Listado de anexos a dos columnas con línea separadora (sin bordes) */
.report-page ul.anx-cols { column-count: 2; column-gap: 1.6rem; column-rule: 1px solid #c9cfda;
  margin: .3rem 0 0; padding-left: 1.1rem; }
.report-page ul.anx-cols li { font-size: .72rem; line-height: 1.35; margin-bottom: .18rem;
  break-inside: avoid; padding-right: .5rem; }
.report-page .anx-intro { font-size: .78rem; margin: 0 0 .2rem; }

/* Código de documento: monoespaciado y azul papermate, en todo informe */
.report-page .code { font-family: 'Courier New', Courier, monospace; color: #1F3F8F; font-weight: 700; letter-spacing: .02em; }

/* Título del documento con su código al extremo derecho, en la misma línea */
.report-page .report-doc-title {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  border-bottom: 2px solid #1A73E8; padding-bottom: .25rem; margin: .2rem 0 .5rem;
}
.report-page .report-doc-title h2 { margin: 0; font-size: 1rem; color: #0b1f4d; font-weight: 700; }
.report-page .report-doc-title .code { font-size: .88rem; white-space: nowrap; }

/* Ficha de datos del documento, bajo el título */
.report-page .report-meta { display: flex; flex-wrap: wrap; gap: .2rem 1.1rem; font-size: .78rem; margin: .2rem 0 .6rem; }
.report-page .report-meta b { color: #16306e; }

/* Bloque de firmas: tres columnas con línea, igual en todos los informes */
.report-page .firmas { display: flex; gap: 1.6rem; margin-top: 1.4rem; }
.report-page .firmas > div { flex: 1; text-align: center; font-size: .78rem; }
.report-page .firmas .ln { border-top: 1px solid #333; margin: 2.2rem .6rem .2rem; }
.report-page .firmas .rol { color: var(--ink-soft); }

/* Nota al pie del informe (alcance, base legal, advertencias) */
.report-page .nota { font-size: .72rem; color: #555; text-align: justify; margin-top: .5rem; }

@media print {
  /* Encabezado de tabla repetido en cada hoja y filas que no se parten:
     es lo que separa un informe presentable de uno ilegible al imprimir. */
  .report-page table thead { display: table-header-group; }
  .report-page table tr { break-inside: avoid; page-break-inside: avoid; }
  .report-page .firmas { break-inside: avoid; }
}

.report-footer { margin-top: 1.4rem; text-align: center; font-size: .72rem; color: var(--ink-soft); border-top: 1px solid var(--border); padding-top: .5rem; }
.report-sign { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-top: 1.6rem; }
.report-sign > div { border-top: 1px solid var(--ink); padding-top: .3rem; font-size: .76rem; text-align: center; }

/* ------------------------------------------------------------------
   Marca de agua de cuenta en prueba.
   Se aplica a TODO documento generado por una empresa con status
   "prueba": el papel queda identificado como salido de una cuenta no
   contratada. La capa va detrás del contenido (z-index negativo sobre
   un contenedor posicionado) para no estorbar la lectura.
   ------------------------------------------------------------------ */
.report-trial .report-page { position: relative; }
.report-watermark {
  position: absolute; inset: 0; z-index: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .8rem; pointer-events: none; user-select: none;
}
.report-watermark img { width: 46%; max-width: 420px; opacity: .10; }
.report-watermark span {
  font-family: var(--font-display, inherit); font-weight: 800;
  font-size: clamp(1.6rem, 4.5vw, 3rem); letter-spacing: .28em;
  color: var(--ink, #1F1F1F); opacity: .12; transform: rotate(-18deg);
}
/* El contenido del reporte se eleva por encima de la marca de agua */
.report-trial .report-header,
.report-trial .report-title,
.report-trial .report-meta,
.report-trial .report-footer,
.report-trial .report-page > *:not(.report-watermark) { position: relative; z-index: 1; }

@media print {
  body.has-report > :not(.report-overlay) { display: none !important; }
  .report-overlay { position: static !important; overflow: visible !important; }
  .no-print { display: none !important; }
  .report-page { max-width: none; padding: 0; }

  /* En impresión la marca de agua se fija al viewport de página para
     que el navegador la repita en TODAS las hojas, no solo en la
     primera. Requiere print-color-adjust para que no la omita. */
  .report-trial .report-watermark {
    position: fixed; inset: 0;
    -webkit-print-color-adjust: exact; print-color-adjust: exact; color-adjust: exact;
  }
  .report-trial .report-watermark img { width: 52%; max-width: none; opacity: .12; }
  .report-trial .report-watermark span { opacity: .14; }
  /* Por defecto el navegador omite colores de fondo al imprimir (ahorro
     de tinta) — así se pierde el color de nivel de riesgo (JHA/AST,
     matriz, badges) aunque las imágenes (como el logo) sí impriman
     bien, porque a ellas esta regla no las afecta. */
  .report-page, .report-page * {
    -webkit-print-color-adjust: exact; print-color-adjust: exact; color-adjust: exact;
  }
  @page { margin: 12mm; }

  /* No partir una sección entre dos páginas: título y detalle deben
     quedar juntos.
     OJO: NO usar un selector genérico tipo "div:has(> h2)" — la
     mayoría de los reportes ponen VARIOS encabezados (h2/h3/h4) como
     hermanos sueltos dentro de UN SOLO div contenedor de todo el
     reporte (ver reports.js). Ese selector terminaba marcando ese
     div GIGANTE entero como "no partible", lo que el navegador
     resuelve empujando todo el bloque a la página siguiente (hoja 1
     casi en blanco) y de todas formas partiendo en un punto
     impredecible más abajo. Por eso cada sección debe envolverse
     explícitamente en <div class="report-section"> (ver
     reportOverlay.js → reportSection()) y solo ESA clase se marca
     como no partible. */
  .report-page h2, .report-page h3, .report-page h4 { break-after: avoid-page; }
  .report-section { break-inside: avoid-page; }
  table.report-table tr { break-inside: avoid-page; }
  table.report-table tr:has(> td[colspan]) { break-after: avoid-page; }
}

.muted { color: var(--ink-soft); font-size: .82rem; }
.section-title { display: flex; align-items: center; justify-content: space-between; margin: 1.1rem 0 .6rem; }
.hidden { display: none !important; }

/* ============================================================
   CAPA SAP S/4HANA FIORI (Horizon) — estructura e interacción
   estilo SAP EHS Workplace Safety, con la paleta NotebookLM.
   Sobrescribe/refina los componentes base definidos arriba.
   ============================================================ */
:root {
  --fiori-shell-bg: #FFFFFF;
  --fiori-bg: #F5F6F7;            /* fondo del launchpad Fiori */
  --fiori-tile: #FFFFFF;
  --fiori-border: #D9D9D9;
  --fiori-line: #E5E5E5;
  --fiori-ink: #1D2D3E;          /* tinta SAP (azul-gris muy oscuro) */
  --fiori-ink-soft: #556B82;
  --fiori-accent: #1A73E8;       /* acento (azul de la paleta actual) */
  --fiori-radius: 0.75rem;
  --fiori-radius-sm: 0.5rem;
  --fiori-shadow: 0 0.125rem 0.5rem rgba(29,45,62,.08), 0 0 0.0625rem rgba(29,45,62,.10);
  --fiori-shadow-hover: 0 0.5rem 1rem rgba(29,45,62,.14);
}

body { background: var(--fiori-bg); color: var(--fiori-ink); font-size: 15px; }
.muted { color: var(--fiori-ink-soft); }

/* ---------- Shell bar (barra superior SAP) ---------- */
.appbar.shell {
  background: var(--fiori-shell-bg);
  border-bottom: 1px solid var(--fiori-border);
  box-shadow: 0 0.0625rem 0 rgba(29,45,62,.04);
  min-height: 2.75rem; padding: .35rem .9rem; gap: .55rem;
}
.shell .shell-brand { display: flex; flex-direction: column; line-height: 1.05; min-width: 0; }
.shell .shell-brand .brand-name { font-weight: 700; font-size: .92rem; color: var(--fiori-ink); letter-spacing: .01em; }
.shell .shell-brand .brand-tenant { font-size: .68rem; color: var(--fiori-ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shell .tenant-logo { width: 30px; height: 30px; border-radius: 6px; }
.shell .spacer { flex: 1; }
.shell .shell-actions { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.shell .shell-actions .btn { min-height: 34px; border-radius: 999px; border-color: var(--fiori-border); background: var(--fiori-shell-bg); }
/* ══ LA BARRA SUPERIOR SACABA SCROLL LATERAL EN EL TELÉFONO ═══════════════════════════
   En 375px pedía 474: el selector de proyecto ocupaba 170px fijos y ni él ni los botones
   encogían, así que la página entera se desplazaba de lado. Y como esta barra está en
   TODAS las pantallas, el «cero scroll lateral» se rompía en toda la aplicación, no en un
   módulo. Se ve solo abriendo la app en un teléfono: en el escritorio sobra sitio y no
   asoma nunca.
   El selector pasa a encoger (`min-width:0` es lo que de verdad deja encoger a un hijo
   flex; sin él el ancho del contenido actúa de suelo) y los botones aprietan su relleno.
   Se conserva el área táctil de 34px de alto, que es lo que se usa con guantes. */
@media (max-width: 640px) {
  .shell .shell-actions select { min-width: 0; flex: 0 1 auto; }
  .shell .shell-actions .btn { padding-left: .45rem; padding-right: .45rem; }
  .appbar.shell { padding-left: .5rem; padding-right: .5rem; gap: .35rem; }
}
.shell select { border-radius: 999px !important; border-color: var(--fiori-border) !important; background: #fff !important; color: var(--fiori-ink) !important; }

/* ---------- Launchpad ---------- */
main.page { background: var(--fiori-bg); }
.lp-greeting { margin: .2rem 0 1rem; }
.lp-greeting h1 { font-size: 1.35rem; font-weight: 700; color: var(--fiori-ink); margin: 0; }
.lp-greeting p { margin: .2rem 0 0; color: var(--fiori-ink-soft); font-size: .85rem; }
.lp-group { margin-bottom: 1.4rem; }
.lp-group-title { font-size: .95rem; font-weight: 700; color: var(--fiori-ink); margin: 0 0 .6rem; letter-spacing: .01em; }
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr)); gap: .7rem; }
@media (min-width: 600px) { .tiles { grid-template-columns: repeat(auto-fill, 11rem); } }

.tile {
  background: var(--fiori-tile); border: 1px solid var(--fiori-line); border-radius: var(--fiori-radius);
  box-shadow: var(--fiori-shadow); padding: .85rem .9rem; min-height: 8.5rem; cursor: pointer;
  display: flex; flex-direction: column; gap: .5rem; text-align: left; font-family: inherit;
  transition: box-shadow .15s ease, transform .15s ease; color: var(--fiori-ink); position: relative;
}
.tile:hover { box-shadow: var(--fiori-shadow-hover); transform: translateY(-1px); }
.tile:active { transform: translateY(0); }
.tile .tile-icon { width: 2.4rem; height: 2.4rem; border-radius: .6rem; display: grid; place-items: center; font-size: 1.25rem; }
.tile .tile-title { font-weight: 600; font-size: .92rem; line-height: 1.2; }
.tile .tile-sub { font-size: .74rem; color: var(--fiori-ink-soft); line-height: 1.25; margin-top: -.2rem; }
.tile .tile-foot { margin-top: auto; display: flex; align-items: flex-end; justify-content: space-between; gap: .3rem; }
.tile .tile-kpi { font-size: 2rem; font-weight: 700; line-height: 1; }
.tile .tile-kpi-unit { font-size: .72rem; color: var(--fiori-ink-soft); font-weight: 600; }
.tile.kpi-ok .tile-kpi { color: var(--verde); }
.tile.kpi-warn .tile-kpi { color: #9A6A00; }
.tile.kpi-danger .tile-kpi { color: var(--rojo); }
.tile .tile-trend { font-size: .7rem; font-weight: 700; }

/* ---------- Object page (cabecera de detalle estilo Fiori) ---------- */
.card {
  background: #fff; border: 1px solid var(--fiori-line); border-radius: var(--fiori-radius);
  box-shadow: var(--fiori-shadow); padding: 1rem 1.1rem;
}
.card > h1 { font-size: 1.2rem; }
.card > h2 { font-size: 1.02rem; color: var(--fiori-ink); }
.card > h3 { font-size: .9rem; color: var(--fiori-ink); }

/* ---------- KPI cards (métricas) estilo Fiori numeric ---------- */
.metrics { gap: .7rem; }
.metric {
  background: #fff; border: 1px solid var(--fiori-line); border-radius: var(--fiori-radius);
  box-shadow: var(--fiori-shadow); padding: .85rem .95rem;
}
.metric .value { font-size: 1.9rem; font-weight: 700; color: var(--fiori-ink); }
.metric .label { font-size: .74rem; color: var(--fiori-ink-soft); font-weight: 600; text-transform: none; }
.metric.tone-ok { background: #fff; border-color: var(--fiori-line); } .metric.tone-ok .value { color: var(--verde); }
.metric.tone-warn { background: #fff; border-color: var(--fiori-line); } .metric.tone-warn .value { color: #9A6A00; }
.metric.tone-danger { background: #fff; border-color: var(--fiori-line); } .metric.tone-danger .value { color: var(--rojo); }
.metric { border-left: 4px solid var(--fiori-border); }
.metric.tone-ok { border-left-color: var(--verde); }
.metric.tone-warn { border-left-color: var(--ambar); }
.metric.tone-danger { border-left-color: var(--rojo); }

/* ---------- List items (Fiori responsive list) ---------- */
.list-row {
  border: none; border-bottom: 1px solid var(--fiori-line); border-radius: 0;
  background: #fff; padding: .7rem .35rem; margin: 0;
}
.card > div > .list-row:last-child, .card .list-row:last-child { border-bottom: none; }
.list-row:hover { background: #F5F8FE; }
.list-row .row-title { color: var(--fiori-ink); font-weight: 600; }
.list-row .row-sub { color: var(--fiori-ink-soft); }

/* ---------- Section title (encabezado de sección Fiori) ---------- */
.section-title { border-bottom: none; align-items: center; }
.section-title h1, .section-title h2, .section-title h3 { color: var(--fiori-ink); }

/* ---------- Botones estilo Fiori ---------- */
.btn { border-radius: var(--fiori-radius-sm); border-color: var(--fiori-border); font-weight: 600; color: var(--fiori-accent); background: #fff; }
.btn:hover { background: #F0F5FF; }
.btn-primary { background: var(--fiori-accent); border-color: var(--fiori-accent); color: #fff; }
.btn-primary:hover { background: #1662C4; }
.btn-ok { background: var(--verde); border-color: var(--verde); color: #fff; }
/* El color va repetido aquí a propósito: `.btn` (arriba en este mismo
   bloque Fiori) fija color con la misma specificity y, por orden,
   ganaría al .btn-danger de la sección base. */
.btn-danger { background: var(--rojo); border-color: var(--rojo); color: #FFFF00; }
.fab { background: var(--fiori-accent); border-radius: 999px; box-shadow: var(--fiori-shadow-hover); bottom: 1.4rem; }
.toast { bottom: 1.6rem; }

/* ---------- Object status (badges Fiori: texto + fondo tenue) ---------- */
.badge { border-radius: .4rem; font-weight: 600; padding: .2rem .55rem; }

/* ---------- Tablas Fiori ---------- */
table.report-table th { background: #F5F6F7; color: var(--fiori-ink-soft); font-weight: 700; border-color: var(--fiori-line); }
table.report-table td { border-color: var(--fiori-line); }

/* ---------- Bottom nav: oculta (se usa navegación lateral) ---------- */
.bottomnav { display: none !important; }

/* ---------- Navegación lateral (patrón SAP escritorio) ---------- */
.app-body { display: flex; align-items: stretch; min-height: calc(100dvh - 2.75rem); }
.sidenav {
  flex: 0 0 15rem; width: 15rem; background: #fff; border-right: 1px solid var(--fiori-border);
  padding: .6rem .5rem 2rem; overflow-y: auto; position: sticky; top: 2.75rem;
  height: calc(100dvh - 2.75rem);
}
/* Encabezado de grupo: píldora con color de contraste, para que se lea como
   separador de bloque y no como un ítem más de la lista. */
/* MENÚ COMPACTO — pedido del usuario: no tener que desplazarse para encontrar una
   opción. Con más de veinte módulos del sistema no cabe todo en una pantalla baja por mucho
   que se apriete, así que aquí se hace lo que sí se puede: bajar la altura de cada
   entrada de 40 px a 28 y encoger los rótulos de grupo, con lo que entra casi el doble
   de menú en el mismo alto. El desplazamiento queda como último recurso, no como la
   forma normal de usarlo. `min-height` sube a 34 px en pantallas táctiles (ver más
   abajo): en campo se pulsa con guantes y ahí el dedo manda sobre la densidad. */
.sidenav-section {
  display: inline-flex; align-items: center;
  font-size: .68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--fiori-accent); background: #E9F1FE; border: 1px solid #C3D9F8;
  border-radius: 999px; padding: .18rem .6rem; margin: .5rem 0 .2rem .25rem;
}
.sidenav-section:first-child { margin-top: .15rem; }

/* ---------- Grupos plegables del menú ----------
   El rótulo de grupo dejó de ser un separador muerto y pasó a ser el control que abre y
   cierra su bloque: con 52 pantallas, el menú plano obligaba a recorrer la lista entera
   con la vista para encontrar una. Se usa <details>/<summary> nativo — el teclado, el
   foco y el lector de pantalla ya funcionan sin escribir nada. */
.sidenav-group { margin: 0; }
.sidenav-group > summary {
  cursor: pointer; list-style: none; user-select: none;
  display: flex; align-items: center; gap: .35rem; width: calc(100% - .5rem);
}
/* El triángulo por omisión de <summary> se quita en los dos motores y se dibuja uno
   propio, que gira al abrir: el nativo se sale de la píldora y rompe el redondeo. */
.sidenav-group > summary::-webkit-details-marker { display: none; }
.sidenav-group > summary::marker { content: ''; }
.sidenav-group > summary::after {
  content: '▸'; margin-left: auto; font-size: .7rem; line-height: 1;
  transition: transform .15s ease; transform-origin: center;
}
.sidenav-group[open] > summary::after { transform: rotate(90deg); }
.sidenav-group > summary:hover { background: #DCEAFB; }
.sidenav-group > summary:focus-visible { outline: 2px solid var(--fiori-accent); outline-offset: 1px; }
.sidenav-group-items { padding-left: .2rem; }
/* Un grupo cerrado que CONTIENE la pantalla abierta no existe: `renderRoute()` lo abre.
   Esta regla es solo para que el rótulo del grupo abierto se lea como tal. */
.sidenav-group[open] > summary { background: #DCEAFB; }
.sidenav-item {
  display: flex; align-items: center; gap: .5rem; padding: .3rem .6rem; border-radius: var(--fiori-radius-sm);
  color: var(--fiori-ink); font-size: .8rem; font-weight: 600; min-height: 28px; margin: 0;
  border-left: 3px solid transparent; line-height: 1.2;
}
.sidenav-item:hover { background: #F0F5FF; }
.sidenav-item.active { background: #E9F1FE; color: var(--fiori-accent); border-left-color: var(--fiori-accent); }
.sidenav-item .sidenav-icon { font-size: 1rem; width: 1.2rem; text-align: center; flex: none; }
/* En pantalla táctil se recupera el tamaño de dedo: la densidad es para el escritorio,
   donde se apunta con el ratón, no para el técnico que registra con guantes puestos. */
@media (pointer: coarse) {
  .sidenav-item { min-height: 36px; padding: .45rem .6rem; font-size: .84rem; }
  .sidenav-item .sidenav-icon { font-size: 1.1rem; width: 1.35rem; }
}
.sidenav-item .sidenav-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* El tope de ancho estaba en 1120 px, una medida pensada para textos largos. Pero aquí casi
   todo son matrices y rejillas de captura, y en una pantalla de 1920 —la del proyector con la
   que se presenta— sobraban 615 px vacíos mientras la rejilla se apretaba a cuatro columnas.
   Con 1520 px caben cinco o seis columnas y se gana justo lo que se pidió: menos filas y menos
   desplazamiento vertical. Sigue habiendo tope: sin él, a 2560 px las líneas se vuelven
   ilegibles de tan largas. */
main.page { flex: 1 1 auto; min-width: 0; padding: 1.1rem 1.3rem 3rem; max-width: 1520px; }
.nav-toggle { display: none; min-height: 34px; padding: 0 .6rem; font-size: 1.1rem; }
.nav-scrim { display: none; }

/* Escritorio: sidenav siempre visible. Móvil/tablet: drawer con toggle. */
@media (max-width: 900px) {
  .nav-toggle { display: inline-flex; }
  .sidenav {
    position: fixed; top: 2.75rem; left: 0; z-index: 40; height: calc(100dvh - 2.75rem);
    transform: translateX(-100%); transition: transform .2s ease; box-shadow: var(--fiori-shadow-hover);
  }
  body.nav-open .sidenav { transform: translateX(0); }
  body.nav-open .nav-scrim {
    display: block; position: fixed; inset: 2.75rem 0 0 0; z-index: 35; background: rgba(29,45,62,.35);
  }
  main.page { padding: 1rem .9rem 3rem; }
}

/* ---------- Barra de acciones inferior (footer toolbar Fiori) ---------- */
.footer-bar {
  position: sticky; bottom: 0; display: flex; gap: .5rem; justify-content: flex-end;
  background: #fff; border-top: 1px solid var(--fiori-border); padding: .6rem .8rem;
  margin: 1rem -.9rem -5.5rem; box-shadow: 0 -0.125rem 0.5rem rgba(29,45,62,.06);
}

/* ---------- Modales estilo Fiori dialog ---------- */
.modal { border-radius: var(--fiori-radius) var(--fiori-radius) 0 0; }
@media (min-width: 700px) { .modal { border-radius: var(--fiori-radius); } }
.modal .modal-title h2 { color: var(--fiori-ink); font-size: 1.05rem; }

/* ---------- Combo de matrices (queda como acción de shell secundaria) ---------- */
select[aria-label="Matrices de este elemento"] {
  background: #EEF3FC !important; border-color: #C6D6F5 !important; color: var(--fiori-accent) !important;
  border-radius: 999px !important;
}

/* ============================================================
   Auditoría: ejecución del protocolo y captura de evidencias
   (mig. 040). Los tokens salen de la paleta NotebookLM ya
   definida arriba; aquí no se introduce ningún color nuevo.
   ============================================================ */

/* ---------- Avance del protocolo ---------- */
.progress-track {
  height: .4rem; border-radius: 999px; background: var(--fiori-border);
  overflow: hidden; margin: .6rem 0 .2rem;
}
.progress-fill {
  height: 100%; background: var(--fiori-accent); border-radius: 999px;
  transition: width .3s ease;
}

/* ---------- Secciones e ítems ---------- */
.audit-section-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; cursor: pointer; list-style: none;
}
.audit-section-head::-webkit-details-marker { display: none; }
.audit-section-head .section-title { margin: 0; }
.audit-item { margin: .6rem 0; }
.audit-criteria summary { cursor: pointer; font-size: .82rem; }
.audit-criteria p { font-size: .84rem; margin: .35rem 0; }

/* ---------- Selector de conformidad ---------- */
.conformity-picker {
  display: flex; flex-wrap: wrap; gap: .4rem; margin: .5rem 0;
}
/* Targets amplios: se usa en campo, con guantes y a una mano. */
.conformity-btn { min-height: 2.5rem; flex: 1 1 8rem; }
.conformity-btn.is-active { font-weight: 600; box-shadow: inset 0 0 0 2px currentColor; }

/* ---------- Evidencias ---------- */
.evidence-block { margin: .6rem 0; }
.evidence-req { margin-left: .4rem; }
.evidence-gallery {
  display: grid; gap: .6rem; margin: .4rem 0;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
}
.evidence-card {
  margin: 0; border: 1px solid var(--fiori-border); border-radius: var(--fiori-radius);
  overflow: hidden; background: #fff;
}
.evidence-thumb {
  width: 100%; height: 7rem; object-fit: cover; display: block; background: #F3F5F8;
}
.evidence-thumb-doc {
  display: flex; align-items: center; justify-content: center; font-size: 2.2rem;
}
.evidence-cap { padding: .45rem .5rem; font-size: .78rem; }
.evidence-name { display: block; word-break: break-word; }
.evidence-desc, .evidence-gps { margin-top: .2rem; }
.evidence-del { margin-top: .35rem; width: 100%; }
.evidence-controls {
  display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin-top: .4rem;
}
.evidence-controls input[type="text"] { flex: 1 1 14rem; }
.evidence-gps-opt { display: flex; align-items: center; gap: .3rem; font-size: .82rem; }
.evidence-hint { font-size: .76rem; margin-top: .3rem; }

@media print {
  /* En el informe la evidencia se imprime más compacta y nunca se
     parte una figura entre dos páginas. */
  .report-gallery { grid-template-columns: repeat(3, 1fr); gap: .4rem; }
  .report-gallery .evidence-thumb { height: 5rem; }
  .evidence-card { break-inside: avoid; page-break-inside: avoid; }
  .evidence-controls, .evidence-del, .evidence-hint { display: none !important; }
}

/* ============================================================
   Procedimientos (SOP), firma y QR de verificación — mig. 041/042
   ============================================================ */

/* ---------- Captura de firma ---------- */
.sigcap-canvas {
  width: 100%; max-width: 30rem; height: 10rem; touch-action: none;
  border: 1px dashed var(--fiori-border); border-radius: var(--fiori-radius);
  background: #fff; display: block;
}
/* Damero: deja ver que el PNG tiene fondo transparente de verdad. */
.sigcap-checker {
  background-image:
    linear-gradient(45deg, #E8EAED 25%, transparent 25%, transparent 75%, #E8EAED 75%),
    linear-gradient(45deg, #E8EAED 25%, transparent 25%, transparent 75%, #E8EAED 75%);
  background-size: 16px 16px; background-position: 0 0, 8px 8px;
  border: 1px solid var(--fiori-border); border-radius: var(--fiori-radius);
  padding: .5rem; display: inline-block; margin-top: .3rem;
}
.sigcap-img { max-height: 6rem; max-width: 100%; display: block; }

/* ---------- Firma estampada + QR ----------
   REQUISITO: el QR nunca supera media pulgada cuadrada y va JUNTO a la
   firma, nunca encima. Por eso es un flex de dos columnas con `gap`:
   son cajas hermanas, no superpuestas, y el ancho del QR está fijado en
   pulgadas para que la restricción se cumpla en papel, que es donde
   importa (in es una unidad absoluta en CSS de impresión).          */
.sig-stamp { display: flex; align-items: flex-end; gap: .25rem; }
.sig-img {
  max-height: 3rem; max-width: 12rem; object-fit: contain;
  display: block; background: transparent;
}
.sig-qr {
  width: .5in; height: .5in; max-width: .5in; max-height: .5in;
  flex: 0 0 .5in;            /* no se estira ni se encoge */
  display: block; image-rendering: pixelated;  /* nítido al imprimir */
}

/* ---------- Documento controlado ---------- */
.sop-header { width: 100%; border-collapse: collapse; margin-bottom: .5rem; font-size: .78rem; }
.sop-header th, .sop-header td { border: 1px solid var(--fiori-border); padding: .3rem .5rem; text-align: left; }
.sop-header th { background: #F3F5F8; font-weight: 700; width: 15%; white-space: nowrap; }
.sop-legend { font-size: .72rem; border: 1px solid var(--fiori-border); padding: .4rem .6rem; margin-bottom: .8rem; }
.sop-legend p { margin: .15rem 0; }
.sop-title { text-align: center; margin: 1rem 0; }
.sop-kind { font-size: .8rem; letter-spacing: .12em; color: var(--ink-soft); }
.sop-sec { margin: 1rem 0; }
.sop-sec h3 { font-size: .92rem; margin: 0 0 .35rem; text-transform: uppercase; }
.sop-sec h4 { font-size: .86rem; margin: 0 0 .3rem; }
.sop-sec p { white-space: pre-wrap; }
.sop-participants td { vertical-align: middle; }
.sop-foot { font-size: .72rem; margin-top: 1.2rem; }

/* Constancia de impresión: en pantalla es una nota; en papel es la
   prueba de quién imprimió y cuándo. */
.sop-print-stamp {
  margin-top: 1rem; border-top: 1px solid var(--fiori-border);
  padding-top: .5rem; font-size: .72rem; color: var(--ink-soft);
}

@media print {
  .sop-break { break-before: page; page-break-before: always; }
  .sop-sec, .sig-stamp { break-inside: avoid; page-break-inside: avoid; }
  .sop-header th { background: #F3F5F8 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .sop-print-stamp { break-inside: avoid; }
}

/* ---------- Enlaces a procedimientos desde cada elemento del sistema ---------- */
.proc-links { display: flex; flex-direction: column; gap: .3rem; }
.proc-link {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  padding: .45rem .6rem; border: 1px solid var(--fiori-border);
  border-radius: var(--fiori-radius); text-decoration: none; color: inherit;
  background: #fff; min-height: 2.4rem;
}
.proc-link:hover { background: #EEF3FC; border-color: #C6D6F5; }
.proc-code { font-weight: 700; font-family: ui-monospace, "Cascadia Mono", monospace; font-size: .82rem; color: var(--fiori-accent); }
.proc-name { flex: 1 1 12rem; }
.proc-rev { font-size: .76rem; white-space: nowrap; }

/* ---------- Marca de agua "COPIA NO CONTROLADA" ----------
   Solo al imprimir: en pantalla el usuario está viendo la copia
   controlada y vigente; el papel es el que puede quedar desactualizado.
   `position: fixed` hace que el navegador la repita en TODAS las
   páginas del documento impreso, no solo en la primera.            */
.sop-watermark { display: none; }

@media print {
  .sop-watermark {
    display: flex;
    position: fixed;
    inset: 0;
    align-items: center;
    justify-content: center;
    transform: rotate(-35deg);
    font-size: 3.6rem;
    font-weight: 800;
    letter-spacing: .12em;
    color: #D93025;
    opacity: .13;
    white-space: nowrap;
    pointer-events: none;
    z-index: 9999;
    /* Sin esto los navegadores omiten el color de fondo al imprimir */
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

/* ============================================================
   Protocolos (mig. 043/044) — protocols.js
   Formularios que la plataforma reparte y que se responden EN CAMPO,
   con guantes y sin señal: todo control interactivo respeta --tap
   (48px) y las rejillas colapsan a una columna en móvil, que es donde
   de verdad se usa esto (Safety360 Lite).
   Colores: azul de la paleta NotebookLM, que es el par asignado a
   cuestionarios/formularios. No se introduce ningún color nuevo.
   ============================================================ */

/* Texto auxiliar (ayuda de campo, unidades, contadores). Se combina con
   .muted, que aporta el color; esto solo el tamaño. */
.small { font-size: .82rem; }

/* ---------- Listado de protocolos disponibles ---------- */
.card-grid {
  display: grid; gap: .7rem;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.card.protocolo-card {
  border-left: 3px solid var(--azul);
  cursor: pointer; transition: box-shadow .15s, transform .15s;
}
.card.protocolo-card:hover { box-shadow: var(--fiori-shadow-hover); transform: translateY(-1px); }
.card.protocolo-card:active { transform: none; }

/* ---------- Estructura del formulario ---------- */
.form-seccion {
  margin: 0 0 1rem; padding: .8rem;
  background: #fff; border: 1px solid var(--fiori-line);
  border-radius: var(--fiori-radius);
}
.form-seccion > h3 { margin: 0 0 .6rem; color: var(--fiori-ink); }

/* Campo de solo presentación (tipo "titulo"): separa visualmente sin
   parecer un control que se pueda rellenar. */
.form-titulo {
  margin: .5rem 0 .3rem; padding-bottom: .3rem;
  border-bottom: 1px solid var(--fiori-line);
  color: var(--fiori-ink); font-size: .95rem;
}
.form-titulo > b { display: block; }

/* Rejilla de campos. Las columnas que pide el diseñador solo se
   aplican con sitio de sobra: en un teléfono, dos columnas dejan
   controles demasiado estrechos para el pulgar. */
.grid-campos { display: grid; gap: .1rem; grid-template-columns: 1fr; }
@media (min-width: 700px) {
  .grid-campos.cols-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-campos.cols-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-campos.cols-4 { grid-template-columns: repeat(4, 1fr); }
}

/* Campo individual (div.field — distinto de label.field, que ya existe
   arriba para los formularios de captura del escritorio). */
div.field { margin-bottom: .8rem; }
div.field > .field-label {
  display: block; margin-bottom: .3rem;
  font-size: .82rem; font-weight: 600; color: var(--ink-soft);
}
div.field > input, div.field > select, div.field > textarea {
  display: block; width: 100%;
  min-height: var(--tap); padding: .55rem .7rem;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--bg); color: var(--ink); font: 400 1rem var(--font);
}
div.field > textarea { min-height: 84px; resize: vertical; }

/* Mensaje de ayuda bajo la etiqueta: dice qué se espera en el campo. Va entre
   la etiqueta y el control, en tono suave para no competir con el dato. */
div.field > .field-hint {
  display: block; margin: -.05rem 0 .35rem;
  font-size: .74rem; font-weight: 400; line-height: 1.3;
  color: var(--ink-soft);
}
/* Campo obligatorio aún sin valor: se marca para que salte a la vista qué
   impide emitir, sin gritarlo. */
div.field.falta > input, div.field.falta > select, div.field.falta > textarea {
  border-color: var(--danger); background: var(--danger-bg);
}
div.field.falta > .field-label::after { content: ' *'; color: var(--danger); }

/* ---------- Opciones tipo chip ---------- */
.radio-row { display: flex; flex-wrap: wrap; gap: .4rem; }
.radio-chip {
  display: inline-flex; align-items: center; gap: .4rem;
  min-height: var(--tap); padding: .4rem .8rem;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--bg); color: var(--ink);
  font-size: .9rem; cursor: pointer;
  touch-action: manipulation; user-select: none;
}
.radio-chip input { width: 20px; height: 20px; margin: 0; accent-color: var(--azul); }
/* Marcar el chip entero, no solo el punto: a un metro y con guantes, el
   input nativo es demasiado pequeño para leer el estado de un vistazo. */
.radio-chip:has(input:checked) {
  background: var(--azul-bg); border-color: var(--azul); font-weight: 600;
}

/* ---------- Interruptor sí/no ---------- */
.switch-row {
  display: flex; align-items: center; gap: .6rem;
  min-height: var(--tap); padding: .3rem 0;
  cursor: pointer; touch-action: manipulation;
}
.switch-row input { width: 22px; height: 22px; margin: 0; accent-color: var(--azul); }

/* ---------- Captura de GPS ---------- */
.gps-row { display: flex; align-items: center; flex-wrap: wrap; gap: .6rem; }
.gps-row > span { font-size: .82rem; color: var(--ink-soft); }

/* ---------- Botón secundario ---------- */
.btn-sec {
  display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
  min-height: var(--tap); padding: .5rem 1rem;
  border: 1px solid var(--fiori-border); border-radius: var(--fiori-radius-sm);
  background: #fff; color: var(--fiori-accent);
  font: 600 .9rem var(--font); cursor: pointer; touch-action: manipulation;
}
.btn-sec:hover { background: #F0F5FF; }
.btn-sec:disabled { opacity: .5; cursor: not-allowed; }

/* ---------- Barra de acciones ---------- */
.row-actions {
  display: flex; flex-wrap: wrap; gap: .5rem;
  margin-top: 1rem; padding-top: .8rem;
  border-top: 1px solid var(--fiori-line);
}
.row-actions > .btn, .row-actions > .btn-sec { flex: 1 1 auto; min-width: 120px; }

/* ---------- Tabla de respuestas ---------- */
.tabla-wrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--fiori-line); border-radius: var(--fiori-radius-sm);
}
.tabla { width: 100%; border-collapse: collapse; font-size: .85rem; }
.tabla th, .tabla td {
  padding: .5rem .6rem; text-align: left;
  border-bottom: 1px solid var(--fiori-line);
}
.tabla th {
  background: var(--surface); color: var(--ink-soft);
  font-size: .78rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .03em;
}
.tabla tr:last-child td { border-bottom: 0; }

/* ============ ESTÁNDAR DE VISUALIZACIÓN ============
   Look profesional por defecto para las tablas de datos (table.grid) y los
   controles de captura en línea (.cell-input). Cualquier pantalla que use estas
   clases adopta el mismo estándar sin cambiar su markup: es el estándar de
   visualización del software, no un estilo por módulo. */
table.grid {
  width: 100%; border-collapse: collapse; font-size: .85rem; background: #fff;
}
table.grid th, table.grid td {
  padding: .5rem .6rem; text-align: left; vertical-align: middle;
  border-bottom: 1px solid var(--fiori-line);
}
/* Cabecera de columna del ESTÁNDAR DE VISUALIZACIÓN: fondo índigo con texto
   blanco, la misma en TODA la aplicación. Se aplica a las clases de tabla de
   datos que usan los módulos —grid, tabla, report-table— para que cualquier
   pantalla tenga la misma cabecera sin tocar su markup. */
table.grid th,
.tabla th,
table.report-table th {
  background: #5C6BC0; color: #fff;
  font-size: .76rem; font-weight: 600; text-transform: none;
  letter-spacing: .02em; white-space: nowrap; text-align: left;
}
table.grid tbody tr:hover { background: var(--surface); }
/* Los DOCUMENTOS IMPRESOS conservan su propia cabecera, y van después para ganar por
   orden de origen. El 5-ago-2026 pasaron de azul marino a CLARA con texto azul: el marino
   se reservó para la barra de sección, siguiendo el visor de formatos que el despacho
   fijó como estándar de todos los informes. Con las dos en marino el documento se leía
   como una mancha oscura y no destacaba ninguna. */
.report-page table th { background: #eef2f8; color: #16306e; text-align: center; }
.report-page table.report-table th { background: #eef2f8; color: #16306e; }
table.grid tr:last-child td { border-bottom: 0; }
table.grid tr.draft-row { background: var(--azul-bg); }
/* Envoltorio con scroll para tablas anchas en pantallas estrechas. */
.tabla-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Captura en línea sobre la celda: control discreto que no rompe la tabla. */
.cell-input {
  width: 100%; min-height: var(--tap); padding: .45rem .6rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--ink); font: 400 .95rem var(--font);
}
.cell-input:focus {
  outline: 2px solid var(--azul); outline-offset: -1px; border-color: var(--azul);
}

/* ---------- Indicadores (KPI) de los informes del cubo ---------- */
.kpi-row {
  display: grid; gap: .7rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.kpi-tile {
  padding: .8rem; text-align: center;
  background: var(--azul-bg); border-radius: var(--fiori-radius);
}
/* La cifra manda: es lo que se lee de un vistazo en una reunión. */
.kpi-valor {
  font-size: 1.9rem; font-weight: 700; line-height: 1.1;
  color: var(--azul); font-variant-numeric: tabular-nums;
}
.kpi-etiqueta {
  margin-top: .25rem; font-size: .8rem; color: var(--ink-soft);
}

/* ---------- Informes maestro-detalle (mig. 048) ---------- */
.tabla-seleccionable tbody tr { cursor: pointer; }
.tabla-seleccionable tbody tr:hover { background: var(--surface); }
.tabla-seleccionable tbody tr:focus-visible { outline: 2px solid var(--azul); outline-offset: -2px; }
/* La fila elegida se marca con fondo Y con una barra a la izquierda: el
   color solo no basta para quien no lo distingue. */
.tabla-seleccionable tbody tr.fila-elegida {
  background: var(--azul-bg); font-weight: 600;
  box-shadow: inset 3px 0 0 var(--azul);
}

/* Ficha: un registro por tarjeta, campos en vertical. */
.ficha {
  padding: .7rem .8rem; margin-bottom: .6rem;
  background: #fff; border: 1px solid var(--fiori-line);
  border-left: 3px solid var(--azul); border-radius: var(--fiori-radius-sm);
}
.ficha:last-child { margin-bottom: 0; }
.ficha-n { font-size: .72rem; color: var(--ink-soft); margin-bottom: .4rem; }
.ficha-campo { margin-bottom: .45rem; }
.ficha-campo:last-child { margin-bottom: 0; }
.ficha-etiqueta {
  font-size: .74rem; font-weight: 600; color: var(--ink-soft);
  text-transform: uppercase; letter-spacing: .03em;
}

/* ============================================================
   Informe de Desempeño — presentación tipo revista.
   Vive dentro del visor de reportes (.report-page), así que hereda
   su ancho de página y su CSS de impresión; lo que se define aquí es
   el ritmo editorial: portada, entradillas, tarjetas de indicador,
   tablas finas y bloques de nota.
   ============================================================ */
.mag { font-size: .9rem; }
.mag-cover {
  background: linear-gradient(150deg, #0B3B77 0%, #10458C 55%, #1A73E8 130%);
  color: #fff; border-radius: 10px; padding: 1.6rem 1.5rem 1.4rem; margin-bottom: 1.4rem;
}
.mag-cover-kicker {
  font-size: .7rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: #9FC2EF; margin-bottom: .5rem;
}
.mag-cover-title { font-size: 2.3rem; line-height: 1.04; font-weight: 800; letter-spacing: -.02em; margin: 0; color: #fff; }
.mag-cover-period { font-size: 1rem; color: #CFE0F7; margin-top: .6rem; font-weight: 600; }
.mag-cover-empresa { font-size: .82rem; color: #9FC2EF; letter-spacing: .05em; text-transform: uppercase; margin-top: .15rem; }
.mag-cover-idx {
  display: flex; align-items: center; gap: .9rem; margin-top: 1.1rem;
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.28);
  border-radius: 8px; padding: .7rem .9rem;
}
.mag-cover-idx-num { font-size: 2.1rem; font-weight: 800; line-height: 1; letter-spacing: -.03em;
  background: #fff; border-radius: 8px; padding: .35rem .6rem; }
.mag-cover-idx-sub { font-size: .78rem; color: #CFE0F7; margin-top: .1rem; }

.mag-h2 {
  font-size: 1.18rem; color: var(--azul, #0B3B77); font-weight: 800; letter-spacing: -.01em;
  border-bottom: 2px solid #1A73E8; padding-bottom: .25rem; margin: 1.5rem 0 .7rem;
}
.mag-h3 { font-size: .92rem; color: #1A73E8; font-weight: 700; margin: .7rem 0 .35rem; }
.mag-lead { font-size: 1rem; line-height: 1.55; color: #1F2430; font-weight: 500; margin-bottom: .8rem; }
.mag-p { font-size: .87rem; line-height: 1.55; text-align: justify; margin-bottom: .6rem; }
.mag-sub { font-size: .74rem; color: #55636F; line-height: 1.3; }

.mag-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; align-items: start; }
@media (max-width: 760px) { .mag-2col { grid-template-columns: 1fr; } }

.mag-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: .7rem; margin: .8rem 0 .4rem; }
.mag-kpi { border: 1px solid #D5DDE6; border-radius: 8px; padding: .7rem .8rem; position: relative; background: #fff; }
.mag-kpi-dot { position: absolute; top: .7rem; right: .7rem; width: 10px; height: 10px; border-radius: 50%; }
.mag-kpi-val { font-size: 1.8rem; font-weight: 800; color: #0B3B77; line-height: 1; letter-spacing: -.02em; }
.mag-kpi-etq { font-size: .82rem; font-weight: 700; margin-top: .25rem; }
.mag-kpi-sub { font-size: .72rem; color: #55636F; line-height: 1.3; margin-top: .15rem; }

.mag-table { width: 100%; border-collapse: collapse; font-size: .82rem; margin: .5rem 0 .8rem; }
.mag-table th {
  text-align: left; font-weight: 700; color: #0B3B77; background: #F3F7FD;
  border-bottom: 1.5px solid #1A73E8; padding: .35rem .45rem; font-size: .76rem;
  text-transform: uppercase; letter-spacing: .04em;
}
.mag-table td { border-bottom: 1px solid #E7ECF2; padding: .38rem .45rem; vertical-align: top; }
.mag-table tr:last-child td { border-bottom: none; }
.mag-table-tight td, .mag-table-tight th { padding: .26rem .4rem; font-size: .78rem; }

.mag-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; vertical-align: middle; }
.mag-pill {
  display: inline-block; font-size: .68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; border: 1px solid; border-radius: 999px; padding: .05rem .4rem;
}
.mag-leyenda { list-style: none; margin: .4rem 0 0; padding: 0; font-size: .78rem; }
.mag-leyenda li { display: flex; align-items: center; gap: .4rem; margin-bottom: .2rem; }

.mag-nota, .mag-aviso, .mag-alerta {
  font-size: .78rem; line-height: 1.5; background: #F6F8FB;
  border-left: 3px solid #1A73E8; border-radius: 0 6px 6px 0; padding: .55rem .7rem; margin: .8rem 0;
}
.mag-alerta { border-left-color: #D93025; background: #FBE4E1; }
.mag-aviso { border-left-color: #F2A600; background: #FBF3D9; }

/* Instrucciones replicables del PSST: bloque largo de texto que se copia
   entero, así que se muestra monoespaciado, con scroll propio y sin que
   la página crezca sin control. */
.playbook-texto {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: .78rem; line-height: 1.55; white-space: pre-wrap; word-break: break-word;
  background: #FAFBFD; border: 1px solid var(--fiori-border); border-radius: var(--fiori-radius-sm);
  padding: .8rem .9rem; max-height: 60vh; overflow: auto; margin: 0;
}

/* Tarjetas de indicador que abren su detalle: se ven pulsables y marcan
   cuál está desplegada, para que no haya que adivinar de dónde salió la
   tabla que apareció debajo. */
.metric-clic { cursor: pointer; position: relative; transition: box-shadow .15s ease, border-color .15s ease; }
.metric-clic:hover { box-shadow: var(--fiori-shadow-hover, 0 2px 10px rgba(0,0,0,.10)); }
.metric-clic:focus-visible { outline: 2px solid var(--fiori-accent); outline-offset: 2px; }
.metric-pista {
  font-size: .66rem; color: var(--fiori-ink-soft); letter-spacing: .04em;
  text-transform: uppercase; margin-top: .25rem; opacity: 0; transition: opacity .15s ease;
}
.metric-clic:hover .metric-pista, .metric-abierta .metric-pista { opacity: 1; }
.metric-abierta { border-color: var(--fiori-accent) !important; background: #F3F8FF; }
.detalle-metrica { border-left: 3px solid var(--fiori-accent); }

/* Acerca de — ficha del producto al pie de Inicio. Tono sobrio: es la
   pantalla que alguien abre para saber con quién está tratando. */
.about-card { border-top: 3px solid var(--fiori-accent); margin-top: 1.4rem; }
.about-head { display: flex; align-items: center; gap: .9rem; margin-bottom: .5rem; }
.about-logo { height: 48px; width: auto; flex: none; }
.about-lede { font-size: .9rem; line-height: 1.55; margin: .2rem 0 .8rem; }
.about-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: .35rem .9rem; }
.about-dato { display: flex; gap: .5rem; font-size: .84rem; padding: .22rem 0; border-bottom: 1px solid var(--fiori-border); }
.about-k { color: var(--fiori-ink-soft); font-weight: 600; flex: 0 0 40%; }
.about-v { flex: 1; }
.about-links { display: flex; gap: .5rem; flex-wrap: wrap; margin: .9rem 0 .3rem; }
.about-legal { font-size: .76rem; line-height: 1.5; color: var(--fiori-ink-soft); margin: .6rem 0 .3rem; }
.about-copy { font-size: .74rem; color: var(--fiori-ink-soft); margin: 0; }

/* Botón flotante a la infografía del módulo. Fijo en la esquina, para no competir con
   la barra superior ni con la navegación inferior de móvil — y del mismo tamaño que el
   target táctil mínimo del resto de la app (uso en campo, con guantes).

   VA 70 px POR ENCIMA DEL BOTÓN DE CREAR, y no es un ajuste estético.

   Los dos son `position: fixed` en la misma esquina y con el MISMO `z-index: 25`. Cuando
   dos elementos empatan en z-index gana el último del DOM, que es este — así que la
   infografía cubría 4 de los 9 puntos del botón «+», **incluido el centro**. Quien
   apuntaba al medio del botón de crear, que es lo natural, abría la infografía.

   Afectaba a la acción principal de media aplicación: nueva minuta, reportar incidente,
   nuevo AST, nueva investigación, nuevo permiso. Se detectó porque un clic automatizado
   caducaba, que es exactamente la misma condición que sufre un dedo. */
.fab-infografia {
  position: fixed; right: 16px; bottom: calc(86px + env(safe-area-inset-bottom));
  width: var(--tap); height: var(--tap); border-radius: 50%;
  background: var(--bg); border: 1px solid var(--border); box-shadow: var(--shadow);
  display: flex; align-items: center; justify-content: center; font-size: 1.3rem;
  z-index: 25; text-decoration: none;
}
@media (min-width: 900px) { .fab-infografia { bottom: 86px; } }
.fab-infografia:hover { border-color: var(--azul); }
.fab-infografia.hidden { display: none; }

/* ── Asistente de campo: dictado y GPS sobre el campo enfocado ──────────────────
   Barra pequeña y flotante que aparece pegada al campo en el que está el cursor.
   Va en el tema, y no en un módulo, porque la sirven las 55 pantallas. */
.af-barra {
  position: fixed; z-index: 60; display: flex; gap: 4px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  padding: 3px; box-shadow: 0 2px 10px rgb(0 0 0 / 14%);
}
.af-btn {
  border: 0; background: var(--surface); border-radius: 6px; cursor: pointer;
  /* 30px de lado: se pulsa con el pulgar y con guantes, que es como se usa en obra. */
  min-width: 30px; height: 30px; font-size: 15px; line-height: 1; padding: 0 7px;
}
.af-btn:hover { background: var(--indigo-bg); }
.af-btn:disabled { opacity: .55; cursor: default; }
/* Grabando: rojo y latiendo. Que se vea SIEMPRE que el micrófono está abierto no es
   adorno — un micrófono encendido sin avisar es lo que hace desconfiar del sistema. */
.af-btn.af-grabando { background: var(--rojo-bg); color: var(--rojo); animation: af-late 1.1s infinite; }
@keyframes af-late { 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .af-btn.af-grabando { animation: none; } }

/* ══ EL PROCEDIMIENTO EN UN TELÉFONO ══════════════════════════════════════════════════
 *
 * La versión Lite del trabajador abre el documento controlado completo —el mismo que se
 * imprime— para que lea el procedimiento de su tarea (5-ago-2026). Medido a 390 px, ese
 * documento desbordaba 125 px: cinco de sus seis tablas eran más anchas que la pantalla
 * (hasta 515 px) y había que arrastrar de lado para leer una instrucción de trabajo.
 *
 * Aquí NO se reformatea el documento: sigue siendo el mismo, con su encabezado, sus firmas
 * y su historial. Lo que se hace es dejar que las celdas partan palabras largas y bajar el
 * tipo lo justo, de modo que el ancho lo fije la pantalla y no el contenido.
 *
 * Solo en `screen`: la impresión y el PDF no se tocan, que es donde el formato importa
 * para el documento controlado. */
@media screen and (max-width: 640px) {
  .sop-doc { font-size: .82rem; }
  .sop-doc table th, .sop-doc table td { padding: .3rem .35rem; font-size: .72rem; }
  /* Solo se parten las palabras que no caben SOLAS (una URL, un código largo). Sin este
     matiz, `break-word` en toda la celda repartia el texto letra por letra. */
  .sop-doc table th, .sop-doc table td { overflow-wrap: break-word; }
  /* Cada tabla se desplaza POR SI MISMA; la pagina nunca se mueve de lado. Arrastrar el
     documento entero pierde el sitio donde se iba leyendo.
     NADA de `table-layout: fixed` ni de forzar `width: 100%`: probado en un telefono de
     390 px, aplastaba la columna de valores del bloque de control y el codigo del
     documento salia partido en vertical, una letra por linea. */
  .sop-doc table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .sop-doc table > * { min-width: max-content; }

  /* El bloque de control (codigo / revision / fechas / alcance) se APILA: en cuatro
     columnas sobre 390 px la columna del valor quedaba en 45 px y el codigo del documento
     salia partido en tres lineas. Apilado, cada dato ocupa su renglon y se lee de un
     vistazo. Es metadato del documento, no su contenido: apilarlo no altera lo que dice.
     La impresion no se toca — esto vive dentro de `@media screen`. */
  .sop-doc .sop-header,
  .sop-doc .sop-header tbody,
  .sop-doc .sop-header tr { display: block; width: 100%; overflow: visible; }
  .sop-doc .sop-header th,
  .sop-doc .sop-header td { display: block; width: auto; text-align: left; }
  /* Y se libra del `min-width: max-content` de la regla general: apilado ya no necesita
     desplazarse, y heredarlo lo dejaba en 575 px sobre una pantalla de 386. */
  .sop-doc .sop-header > * { min-width: 0; }
  .sop-doc .sop-header th { border-bottom: 0; }
  .sop-doc .sop-header td { margin-bottom: .2rem; }
}

/* ══ CONSTANCIA DE UN PROTOCOLO ═══════════════════════════════════════════════════════
 *
 * Misma maquetación que el visor de formatos (`/form-designs/:code/print`), que es el
 * estándar de impresión del sistema y el que el despacho señaló como el que se ve
 * profesional. Antes la constancia pintaba cada sección como una tabla de dos columnas al
 * 42%, así que la fecha, la cédula y un párrafo de observaciones salían todos del mismo
 * ancho: parecía papel cuadriculado.
 *
 * Lo que lo arregla es el reparto: la ETIQUETA es estrecha (16%) y el VALOR ancho (34%), y
 * caben DOS pares por fila. Un párrafo se lleva la fila entera. */
.prot-doc .bar {
  background: #132a63; color: #fff; font-weight: 600; font-size: .78rem;
  padding: .2rem .5rem; letter-spacing: .04em; text-transform: uppercase; margin-top: .7rem;
}
.prot-doc table.pf { width: 100%; border-collapse: collapse; }
.prot-doc table.pf th, .prot-doc table.pf td {
  border: 1px solid #aeb3bd; padding: .22rem .4rem; font-size: .8rem; vertical-align: middle;
  overflow-wrap: break-word;
}
.prot-doc table.pf th { background: #eef2f8; text-align: left; font-weight: 600; color: #16306e; }
.prot-doc table.pf tr:nth-child(even) td { background: #fafbfe; }
.prot-doc table.pf.datos th { width: 16%; } .prot-doc table.pf.datos td { width: 34%; }
/* La lista de verificación: número estrecho, el aspecto ancho y una columna angosta por
   opción. La marca va centrada y grande — es lo único que se busca al hojear el documento. */
.prot-doc table.pf.chk td.num, .prot-doc table.pf.chk th.num { width: 4%; text-align: center; color: #6b6b6b; }
.prot-doc table.pf.chk td.mk, .prot-doc table.pf.chk th.mk {
  width: 9%; text-align: center; font-size: 1rem; line-height: 1; font-weight: 700;
}
.prot-doc .firmas { display: flex; gap: 1.2rem; margin-top: .9rem; flex-wrap: wrap; }
.prot-doc .firmas > div { flex: 1; min-width: 180px; text-align: center; font-size: .78rem; color: #333; }
.prot-doc .firmas img { max-height: 70px; max-width: 100%; object-fit: contain; }
.prot-doc .firmas .ln { border-top: 1px solid #333; margin: .2rem .4rem .2rem; }

/* En el teléfono la rejilla de cuatro columnas no cabe: cada par pasa a su renglón. Se
   conserva el marco y las franjas, así que sigue leyéndose como el mismo documento. */
@media screen and (max-width: 640px) {
  .prot-doc table.pf.datos,
  .prot-doc table.pf.datos tbody,
  .prot-doc table.pf.datos tr { display: block; width: 100%; }
  .prot-doc table.pf.datos th,
  .prot-doc table.pf.datos td { display: block; width: auto; }
  .prot-doc table.pf.chk { display: block; overflow-x: auto; }
}

/* ── LISTA DE ASISTENCIA Y FIRMAS ────────────────────────────────────────────────────
   El anexo de firmas que comparten todos los módulos (AST, charla, Comité, capacitación).
   Se dimensiona para TABLETA CON LÁPIZ, que es donde se usa: el recuadro de firma de cada
   renglón tiene que ser lo bastante alto para firmar sin encogerse, y los renglones lo
   bastante separados para que el dedo no toque el de al lado al pasar el dispositivo. */
.bloque-asistencia { margin: .4rem 0 .8rem; }
.acciones-asistencia { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-bottom: .6rem; }

.tabla-asistencia { width: 100%; border-collapse: collapse; font-size: .86rem; }
.tabla-asistencia th, .tabla-asistencia td {
  border: 1px solid var(--borde, #DADCE0); padding: .35rem .5rem; vertical-align: middle;
}
.tabla-asistencia thead th { background: #E9EAF9; color: #1F1F1F; font-size: .78rem; text-align: left; }
.tabla-asistencia td.num { text-align: center; color: #5f6368; }
.tabla-asistencia tr.fila-visitante { background: #FBF3D9; }
.tabla-asistencia .badge.visitante {
  margin-left: .4rem; font-size: .68rem; background: #F2A600; color: #fff;
  border-radius: 999px; padding: .05rem .45rem;
}
/* La miniatura de la firma en su renglón: sin ella, saber quién firmó obliga a abrir uno
   por uno, y con quince asistentes eso no lo hace nadie. */
/* La miniatura, ya con la firma recortada a su tinta, puede permitirse ser alta: es lo
   que permite ver de un vistazo quién firmó y quién no, que es para lo que está. */
.tabla-asistencia .firma-mini {
  height: 52px; max-width: 100%; cursor: pointer; display: block; margin: 0 auto;
}
.tabla-asistencia td.celda-firma { text-align: center; }

.firma-fila-marco { border: 2px dashed #90A4AE; border-radius: 8px; background: #fff; }
.firma-fila-canvas { width: 100%; height: 220px; display: block; touch-action: none; }

.selector-asistentes .lista-personal {
  max-height: 46vh; overflow: auto; border: 1px solid var(--borde, #DADCE0);
  border-radius: 8px; margin-top: .5rem;
}
/* Objetivo táctil amplio: esto se marca de pie, en obra, con guantes o con lápiz. */
.selector-asistentes .fila-personal {
  display: flex; align-items: center; gap: .6rem; padding: .55rem .7rem;
  border-bottom: 1px solid #EEE; cursor: pointer; min-height: 2.6rem;
}
.selector-asistentes .fila-personal:last-child { border-bottom: none; }
.selector-asistentes .fila-personal input[type=checkbox] { width: 1.15rem; height: 1.15rem; }
.selector-asistentes .fila-personal .nom { font-weight: 600; flex: 1; }

/* La misma tabla, ya impresa detrás del formulario del que es anexo. */
.hoja-asistencia { width: 100%; border-collapse: collapse; font-size: 9.5pt; margin-top: .3rem; }
.hoja-asistencia th, .hoja-asistencia td { border: 1px solid #999; padding: .2rem .35rem; }
.hoja-asistencia thead th { background: #EEE; text-align: left; }
.hoja-asistencia td.celda-firma-hoja { height: 2.2rem; text-align: center; }
.hoja-asistencia td.celda-firma-hoja img { height: 2rem; }
.hoja-asistencia tr { page-break-inside: avoid; }

/* ══ EL CAMPO QUE FALTA, SEÑALADO ════════════════════════════════════════════════════
   Un formulario de campo tiene veinte preguntas y el aviso de «faltan obligatorios» vive
   al pie; sin marcar CUÁLES, hay que recorrerlo entero adivinando. La franja roja se ve
   de reojo mientras se desplaza. */
.campo-falta {
  border-left: 3px solid var(--rojo, #D93025);
  background: #FBE4E1;
  padding-left: .5rem; border-radius: 6px;
}
.campo-falta > .field-label, .campo-falta > span:first-child { color: #B3261E; font-weight: 700; }

/* La hoja del F066 ya rellena. Vive en DOS sitios: pegada detrás del formulario del que
   cuelga (`.anexos-impresos`) y suelta, cuando se imprime la lista en el momento de tomar
   las firmas. Por eso el estilo cuelga de `.anexo-hoja` y NO del contenedor: estaba
   escrito como `.anexos-impresos .anexo-titulo`, así que la hoja suelta salía sin título
   en negrita, sin la barra azul y sin bordes en la tabla — cualquier cosa menos el
   estándar de visualización del sistema.
   Lo ÚNICO que sigue siendo del contenedor es el salto de página: una hoja suelta que
   empieza en página nueva imprime una primera hoja en blanco. */
.anexos-impresos .anexo-hoja { page-break-before: always; margin-top: 1.2rem; }
.anexo-titulo {
  font-weight: 800; font-size: 11pt; text-transform: uppercase;
  border-bottom: 2px solid #1F1F1F; margin-bottom: .5rem; padding-bottom: .2rem;
}
.anexo-contenido p { white-space: pre-wrap; margin: .3rem 0 .6rem; }
.anexo-constancia {
  font-size: 8.5pt; color: #333; border-top: 1px solid #999;
  margin-top: .8rem; padding-top: .4rem;
}
/* Estándar de visualización, versión IMPRESA: barra azul marino #132a63 — NO el índigo de
   pantalla— y la tabla de datos con su reparto etiqueta estrecha / valor ancho. Es el
   mismo juego que usa `.prot-doc`; aquí se repite para la hoja suelta, que no está dentro
   de un `.prot-doc`. */
.anexo-hoja .bar {
  background: #132a63; color: #fff; font-weight: 600; font-size: .78rem;
  padding: .2rem .5rem; letter-spacing: .04em; text-transform: uppercase; margin-top: .7rem;
}
.anexo-hoja table.pf { width: 100%; border-collapse: collapse; }
.anexo-hoja table.pf th, .anexo-hoja table.pf td {
  border: 1px solid #aeb3bd; padding: .22rem .4rem; font-size: .8rem; vertical-align: middle;
  overflow-wrap: break-word;
}
.anexo-hoja table.pf th { background: #eef2f8; text-align: left; font-weight: 600; color: #16306e; }
.anexo-hoja table.pf.datos th { width: 26%; }
.anexo-hoja table.pf tr:nth-child(even) td { background: #fafbfe; }

/* ══ BIENVENIDA CON EL LOGO DEL CLIENTE ═══════════════════════════════════════════════
   Se pinta una vez, al entrar, encima de la aplicación ya montada. A todo lo ancho: es la
   señal de que se está en la instalación en vivo del cliente y no en un entorno de prueba.
   Se va sola a los 3 s; mientras tanto no bloquea nada porque desaparece al primer toque. */
.bienvenida {
  position: fixed; inset: 0; z-index: 400;
  display: flex; align-items: center; justify-content: center;
  background: var(--fondo, #fff);
  opacity: 0; transition: opacity .3s ease;
  cursor: pointer;
}
.bienvenida.visible { opacity: 1; }
.bienvenida-caja { text-align: center; padding: 1rem; width: 100%; }
.bienvenida-caja img {
  /* Ni ancho ni alto impuestos: solo topes. Forzando el ancho y limitando la altura, el
     logotipo de la CMAM salía recortado por abajo y se perdía la línea «MINERA Y AGREGADOS
     MAIMÓN, SAS». Con dos máximos conserva su proporción y no se corta nunca: ocupa todo el
     ancho disponible salvo que sea la altura la que mande. */
  display: block; margin: 0 auto;
  width: min(92vw, 1100px); height: auto;
}
/* En pantallas bajas manda la altura y el ancho se deduce, para que nunca se corte.
   No se usa `object-fit`: con el ancho impuesto y la altura topada, el logotipo salía
   recortado por abajo. Dos reglas excluyentes no dejan margen a esa pelea. */
@media (max-height: 780px) {
  .bienvenida-caja img { width: auto; max-width: 92vw; max-height: 62vh; }
}
.bienvenida-nombre {
  margin: 1.2rem 0 0; font-size: clamp(1rem, 2.6vw, 1.6rem); font-weight: 700;
  color: var(--tinta, #1F1F1F); letter-spacing: .01em;
}
@media (prefers-reduced-motion: reduce) { .bienvenida { transition: none; } }

/* ---------- Quién está dentro, en la barra ----------
   Va pegado al nombre de la empresa a 5 CARACTERES de distancia (`ch`, no píxeles): así la
   separación se mantiene proporcional si el dispositivo agranda la letra, que en una tableta
   de obra pasa a menudo. Se recorta con puntos suspensivos en vez de empujar la barra: un
   nombre largo no puede desplazar el selector de proyecto ni el botón de salir. */
.barra-usuario {
  margin-left: 5ch;
  font-weight: 600;
  opacity: .85;
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: inline-block;
  vertical-align: bottom;
}
@media (max-width: 480px) {
  /* En un teléfono no caben los dos nombres enteros: manda el de la empresa y el del
     usuario se recorta antes, pero NO se esconde — es el dato que evita firmar como otro. */
  .barra-usuario { margin-left: 2ch; max-width: 12ch; }
}
