/* Sistema de Mantenimiento Eléctrico — estilos base.
   Sin dependencias externas: todo funciona offline.

   Índice
   1. Tokens (color, espaciado, tipografía)
   2. Base y foco visible
   3. Cabecera y navegación
   4. Contenedores y tarjetas
   5. Formularios
   6. Tablas de datos (incluye columna y encabezado fijos)
   7. Utilidades
   8. Dashboard personalizable
   9. Árbol de ubicación
  10. Impresión (@media print)
  11. Pantallas angostas (salvaguarda) */

/* ---------------------------------------------------------------------
   1. Tokens
   --------------------------------------------------------------------- */
:root {
    --color-fondo: #f4f6f8;
    --color-superficie: #ffffff;
    --color-superficie-alt: #fafbfc;
    --color-borde: #d5dbe0;
    --color-texto: #1f2933;
    --color-texto-secundario: #52606d;
    --color-primario: #1c3d5a;
    --color-primario-hover: #16324a;
    --color-acento: #c0392b;
    --color-ok: #1e824c;
    --color-alerta: #b7791f;

    /* Fondos tenues para marcar filas y celdas sin perder legibilidad */
    --color-acento-tenue: #fdecea;
    --color-alerta-tenue: #fff8e6;
    --color-ok-tenue: #eaf6ef;
    --color-realce: #eef4f9;

    /* Escala de espaciado: evita valores sueltos repartidos por las páginas */
    --esp-1: 0.25rem;
    --esp-2: 0.5rem;
    --esp-3: 0.75rem;
    --esp-4: 1rem;
    --esp-5: 1.5rem;
    --esp-6: 2rem;

    /* Escala tipográfica */
    --txt-xs: 0.72rem;
    --txt-sm: 0.82rem;
    --txt-md: 0.9rem;
    --txt-base: 1rem;
    --txt-lg: 1.2rem;
    --txt-xl: 1.6rem;

    --radio: 6px;
    --sombra: 0 1px 2px rgba(31, 41, 51, 0.06);
    --ancho-lectura: 1100px;
    --ancho-tablas: 1600px;
}

* { box-sizing: border-box; }

/* El atributo nativo [hidden] es una regla del navegador con especificidad
   baja: cualquier clase que fije su propio "display" (.formulario-linea,
   .indicadores, etc.) lo gana y el elemento sigue visible. Se refuerza acá
   una sola vez en vez de acordarse de excluirlo clase por clase. */
[hidden] { display: none !important; }

/* ---------------------------------------------------------------------
   2. Base y foco visible
   --------------------------------------------------------------------- */
body {
    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
    background: var(--color-fondo);
    color: var(--color-texto);
    font-size: 15px;
    line-height: 1.5;
}

a { color: var(--color-primario); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Los formularios de pruebas se llenan con Tab: sin un foco visible se pierde
   la posición del cursor. :focus-visible no molesta al usar el ratón. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--color-primario);
    outline-offset: 2px;
    border-radius: 3px;
}
.app-sidebar a:focus-visible { outline-color: #fff; }

/* El campo activo también se resalta por fondo: en una grilla de 40 campos
   el contorno solo no basta para ubicarse de un vistazo. */
input:focus,
select:focus,
textarea:focus { background: #fdfdf7; border-color: var(--color-primario); }

/* Salto directo al contenido, para no tabular por todo el menú */
.salto-contenido {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--color-superficie);
    color: var(--color-primario);
    padding: var(--esp-2) var(--esp-3);
    z-index: 10;
}
.salto-contenido:focus { left: var(--esp-2); top: var(--esp-2); }

/* Panel de la aplicación: menú fijo a la izquierda, contenido a la derecha. */
.app-shell {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
}

/* Ancho del menú: una variable para que el plegado sea un solo cambio y la
   transición sea continua. Plegado deja sólo los iconos. */
:root { --ancho-menu: 220px; }
:root[data-menu="plegado"] { --ancho-menu: 62px; }

.app-sidebar {
    flex: 0 0 var(--ancho-menu);
    width: var(--ancho-menu);
    background: var(--color-primario);
    color: #fff;
    display: flex;
    flex-direction: column;
    padding: 0.7rem 0.75rem 1rem;
    position: sticky;
    top: 0;
    align-self: flex-start;
    height: 100vh;
    overflow-y: auto;
    overflow-x: hidden;
    transition: flex-basis 0.15s ease, width 0.15s ease;
}
@media (prefers-reduced-motion: reduce) {
    .app-sidebar { transition: none; }
}

/* Botón de plegar: mismo tratamiento que un enlace del menú. */
.menu-toggle {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    background: transparent;
    border: none;
    color: #cddcea;
    font: inherit;
    font-size: 0.82rem;
    text-align: left;
    padding: 0.5rem 0.6rem;
    margin-bottom: 0.6rem;
    border-radius: var(--radio);
    cursor: pointer;
}
.menu-toggle:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.menu-toggle .nav-simbolo { opacity: 1; }

.app-content {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* Marca: el logo del prestador arriba y el nombre del sistema debajo. */
.app-header__brand { margin-bottom: 1.3rem; }
.app-header__brand a {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
    color: #fff;
    font-weight: bold;
    font-size: 1.05rem;
}
.app-header__brand a:hover { text-decoration: none; }
.app-header__brand a:hover .app-header__nombre { text-decoration: underline; }
.app-header__nombre { line-height: 1.25; }

/* Usuario con sesión iniciada, al pie del menú lateral. */
.app-header__sesion {
    margin-top: auto;
    padding-top: var(--esp-3);
    border-top: 1px solid rgba(255,255,255,0.18);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.3rem;
    font-size: 0.82rem;
    color: #cddcea;
}
.app-header__sesion a {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: #cddcea;
    padding: 0.35rem 0.6rem;
    border-radius: var(--radio);
}
.app-header__sesion a:hover { color: #fff; background: rgba(255, 255, 255, 0.12); text-decoration: none; }
.app-header__usuario {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: #fff;
    font-weight: bold;
    padding: 0 0.6rem 0.2rem;
}
.app-header__rol {
    font-weight: normal;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: rgba(255,255,255,0.15);
    border-radius: 3px;
    padding: 0.1rem 0.4rem;
}

/* ---- Menú plegado: sólo iconos ----
   El texto se oculta pero los enlaces conservan su title, así cada sección
   sigue siendo identificable al pasar el cursor. */
:root[data-menu="plegado"] .app-header__nombre,
:root[data-menu="plegado"] .menu-toggle__etiqueta,
:root[data-menu="plegado"] .app-nav a > span,
:root[data-menu="plegado"] .app-header__sesion a > span,
:root[data-menu="plegado"] .app-header__usuario { display: none; }

:root[data-menu="plegado"] .menu-toggle,
:root[data-menu="plegado"] .app-nav a,
:root[data-menu="plegado"] .app-header__sesion a {
    justify-content: center;
    gap: 0;
    padding-left: 0;
    padding-right: 0;
}
:root[data-menu="plegado"] .app-header__brand { margin-bottom: 0.9rem; }
:root[data-menu="plegado"] .app-header__brand a { align-items: center; }

/* Logo de ELECTRA en el menú: ya trae el nombre dibujado, así que no lleva
   texto aparte. El SVG tiene su propio fondo oscuro, por eso no necesita la
   base blanca que sí le hacía falta al logo del contratista.
   Plegado usa un segundo archivo (el isotipo cuadrado, sin el nombre
   dibujado) en vez de recortar el logo completo por CSS: a 38px el nombre
   no se leería igual, y un recorte por posición es frágil ante cualquier
   cambio futuro del arte. */
.logo-electra-menu {
    display: block;
    border-radius: var(--radio);
}
.logo-electra-menu--completo { width: 100%; max-width: 168px; height: auto; }
.logo-electra-menu--icono { display: none; width: 38px; height: 38px; }

:root[data-menu="plegado"] .logo-electra-menu--completo { display: none; }
:root[data-menu="plegado"] .logo-electra-menu--icono { display: block; }

.app-nav {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.app-nav a {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: #e6edf3;
    font-size: 0.92rem;
    padding: 0.55rem 0.6rem;
    border-radius: var(--radio);
}
.app-nav a:hover { color: #fff; background: rgba(255, 255, 255, 0.12); text-decoration: none; }

/* Los símbolos del menú van sobre el azul del encabezado, donde los colores
   de módulo no tendrían contraste: aquí heredan el color del texto y el color
   propio se reserva para la sección activa. */
.nav-simbolo {
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    opacity: 0.85;
}
.app-nav a:hover .nav-simbolo,
.app-nav a[aria-current="page"] .nav-simbolo { opacity: 1; }

/* Sección actual: se marca con fondo, negrita y una guía a la izquierda del
   color del módulo, el mismo de su tarjeta en la portada. No depende sólo
   del color, para que se distinga también en pantallas de bajo contraste. */
.app-nav a[aria-current="page"] {
    color: #fff;
    font-weight: bold;
    background: rgba(255, 255, 255, 0.16);
    box-shadow: inset 3px 0 0 var(--color-modulo, #fff);
}

/* Color de cada sección, en tonos claros para que se lean sobre el azul. */
.app-nav .nav-inicio       { --color-modulo: #9fb8cc; }
.app-nav .nav-ubicacion    { --color-modulo: #9fb8cc; }
.app-nav .nav-equipos      { --color-modulo: #5eead4; }
.app-nav .nav-mantenciones { --color-modulo: #fdba74; }
.app-nav .nav-busqueda     { --color-modulo: #c4b5fd; }
.app-nav .nav-historico    { --color-modulo: #86efac; }
.app-nav .nav-dashboard    { --color-modulo: #fca5a5; }
.app-nav .nav-empresas     { --color-modulo: #93c5fd; }
.app-nav .nav-personas     { --color-modulo: #fcd34d; }
.app-nav .nav-manual       { --color-modulo: #cbd5e1; }
.app-nav .nav-instrumentos { --color-modulo: #7dd3fc; }
.app-nav .nav-usuarios     { --color-modulo: #f0abfc; }

/* width:100% es necesario, no redundante: .app-content es un contenedor flex
   en columna, y ahí un hijo con "margin: … auto" deja de estirarse y se
   encoge al tamaño de su contenido. Sin esto la portada quedaba angosta al
   centro mientras las tablas, más anchas, sí ocupaban la pantalla. */
.app-main {
    width: 100%;
    max-width: var(--ancho-lectura);
    margin: var(--esp-5) auto;
    padding: 0 1.25rem var(--esp-6);
}
/* Vistas de tabla ancha (histórico, búsqueda, listados): en PC de oficina
   conviene usar el ancho disponible antes que forzar scroll horizontal. */
.app-main--ancho { max-width: var(--ancho-tablas); }

.app-footer {
    text-align: center;
    color: var(--color-texto-secundario);
    font-size: 0.8rem;
    padding: var(--esp-4);
}

/* Migas de pan: ubican el equipo dentro de la jerarquía de la planta */
.migas {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--esp-2);
    margin-bottom: var(--esp-4);
    font-size: var(--txt-sm);
    color: var(--color-texto-secundario);
}
.migas ol {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--esp-2);
    list-style: none;
    margin: 0;
    padding: 0;
}
.migas li { display: flex; align-items: baseline; gap: var(--esp-2); }
.migas li + li::before { content: "›"; color: var(--color-borde); }
.migas .miga-nivel {
    font-size: var(--txt-xs);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-texto-secundario);
}
.migas [aria-current="page"] { color: var(--color-texto); font-weight: bold; }

/* Encabezado de página: título + acciones a la derecha */
.encabezado-pagina {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--esp-3);
    margin-bottom: var(--esp-4);
}
.encabezado-pagina h1 { margin: 0; font-size: 1.45rem; color: var(--color-primario); }
.encabezado-pagina .acciones { margin-left: auto; display: flex; gap: var(--esp-2); }

.tarjeta {
    background: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
    padding: 1rem 1.25rem;
    margin-bottom: 1rem;
}

.grid-modulos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1rem;
}

/* Tarjetas del inicio. Cada módulo lleva su símbolo del unifilar y un color
   propio, para reconocerlo sin leer el título. El color se declara una vez por
   módulo y lo heredan el icono, el borde y el título. */
.modulo {
    --color-modulo: var(--color-primario);
    display: flex;
    align-items: flex-start;
    gap: var(--esp-3);
    background: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-left: 4px solid var(--color-modulo);
    border-radius: var(--radio);
    padding: 1rem;
    color: var(--color-texto);
    transition: border-color 0.12s ease, box-shadow 0.12s ease, transform 0.12s ease;
}
.modulo:hover {
    border-color: var(--color-modulo);
    box-shadow: 0 2px 8px rgba(31, 41, 51, 0.12);
    transform: translateY(-1px);
    text-decoration: none;
}
.modulo:focus-visible { outline-color: var(--color-modulo); }

.modulo__icono {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    border-radius: var(--radio);
    color: var(--color-modulo);
    /* color-mix da el mismo tono del módulo, muy diluido, sin definir un
       segundo color por cada uno. */
    background: color-mix(in srgb, var(--color-modulo) 10%, #fff);
}
.modulo__icono svg { width: 28px; height: 28px; }
.modulo__texto { min-width: 0; }

.modulo h3 { margin: 0 0 0.35rem; color: var(--color-modulo); font-size: 1.02rem; }
.modulo p { margin: 0; color: var(--color-texto-secundario); font-size: 0.88rem; }

/* Un color por módulo. Tonos oscuros para que el texto del título mantenga
   contraste suficiente sobre el fondo blanco de la tarjeta. */
.modulo--ubicacion    { --color-modulo: #1c3d5a; }
.modulo--equipos      { --color-modulo: #0f766e; }
.modulo--mantenciones { --color-modulo: #b45309; }
.modulo--busqueda     { --color-modulo: #6d28d9; }
.modulo--historico    { --color-modulo: #15803d; }
.modulo--dashboard    { --color-modulo: #b91c1c; }
.modulo--empresas     { --color-modulo: #1e40af; }
.modulo--personas     { --color-modulo: #92400e; }
.modulo--instrumentos { --color-modulo: #0369a1; }
.modulo--manual       { --color-modulo: #334155; }

/* Sin color-mix (navegadores antiguos): fondo gris claro en vez del tinte. */
@supports not (background: color-mix(in srgb, red 10%, white)) {
    .modulo__icono { background: var(--color-superficie-alt); }
}

/* Identidad del sistema en la portada: nombre propio y a qué se dedica,
   antes de los indicadores. Un solo acento de color, sin recargar. */
.portada-titulo {
    margin-bottom: 1.75rem;
}
.portada-titulo h1 {
    margin: 0;
    font-size: 2.1rem;
    letter-spacing: 0.03em;
    color: var(--color-primario);
    position: relative;
    display: inline-block;
    padding-bottom: 0.5rem;
}
.portada-titulo h1::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 3.2rem;
    height: 4px;
    border-radius: 2px;
    background: var(--color-alerta);
}
.portada-titulo p {
    margin: 0.6rem 0 0;
    font-size: 1rem;
    color: var(--color-texto-secundario);
}

.indicadores {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}
.indicador {
    background: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
    padding: 0.9rem 1rem;
    text-align: center;
}
.indicador .valor { font-size: 1.6rem; font-weight: bold; color: var(--color-primario); }
.indicador .etiqueta { font-size: 0.8rem; color: var(--color-texto-secundario); }

.formulario-linea {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1rem;
}
.formulario-linea label {
    display: flex;
    flex-direction: column;
    font-size: 0.85rem;
    color: var(--color-texto-secundario);
    flex: 1 1 180px;
}
select, input, textarea, button {
    font-family: inherit;
    font-size: 0.92rem;
    padding: 0.45rem 0.5rem;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
    margin-top: 0.25rem;
}

/* Buscador de equipo con autocompletado (mantenciones/nuevo.php): reemplaza
   un <select> de cientos de opciones por un campo de texto + lista filtrada. */
.buscador-equipo { position: relative; margin-top: 0.25rem; }
.buscador-equipo input[type="text"] { width: 100%; margin-top: 0; }
.buscador-equipo__lista {
    position: absolute;
    z-index: 20;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    margin: 0;
    padding: 0.25rem;
    list-style: none;
    background: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
    box-shadow: 0 6px 16px rgba(31, 41, 51, 0.16);
    max-height: 320px;
    overflow-y: auto;
}
.buscador-equipo__lista li {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.4rem 0.55rem;
    border-radius: calc(var(--radio) - 2px);
    cursor: pointer;
}
.buscador-equipo__lista li:hover,
.buscador-equipo__lista li.activo { background: var(--color-realce); }
.buscador-equipo__tag { font-weight: bold; font-size: 0.92rem; color: var(--color-texto); }
.buscador-equipo__detalle { font-size: 0.78rem; color: var(--color-texto-secundario); }

/* Campos de "Observaciones": son los únicos label hijos directos de .tarjeta.
   Ocupan el ancho completo para que el texto largo (hallazgos, notas de
   anomalías) se lea sin cortarse. */
.tarjeta > label {
    display: flex;
    flex-direction: column;
    font-size: 0.85rem;
    color: var(--color-texto-secundario);
}
textarea {
    width: 100%;
    /* Dos líneas visibles: 2 x line-height + padding vertical. */
    min-height: calc(2 * 1.5em + 0.9rem);
    resize: vertical;
}
button {
    background: var(--color-primario);
    color: #fff;
    border: none;
    cursor: pointer;
}
button:hover { background: var(--color-primario-hover); }

.aviso {
    background: #fff8e6;
    border: 1px solid var(--color-alerta);
    color: #6b4d0f;
    border-radius: var(--radio);
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
    font-size: 0.9rem;
}

/* Confirmación de una acción que salió bien (guardado, alta creada) */
.aviso-ok {
    background: var(--color-ok-tenue);
    border-color: var(--color-ok);
    color: var(--color-ok);
    font-weight: bold;
}

/* ---------------------------------------------------------------------
   Dashboard personalizable (dashboard/index.php)
   Cada módulo se puede reordenar (arrastrando el asa o con los botones),
   ocultar y restaurar. La preferencia se guarda en el navegador.
   --------------------------------------------------------------------- */
.panel-modulos {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.modulo-panel {
    background: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
    /* Ancla para el borde de destino durante el arrastre. */
    position: relative;
}

.modulo-panel__barra {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 0.9rem;
    border-bottom: 1px solid var(--color-borde);
    background: #fafbfc;
    border-radius: var(--radio) var(--radio) 0 0;
}

.modulo-panel__titulo {
    margin: 0;
    font-size: 1rem;
    color: var(--color-primario);
}

/* El asa es lo único arrastrable: el resto del módulo queda seleccionable. */
.modulo-panel__asa {
    cursor: grab;
    color: var(--color-texto-secundario);
    font-size: 1.1rem;
    line-height: 1;
    padding: 0.15rem 0.3rem;
    border-radius: 3px;
    user-select: none;
}
.modulo-panel__asa:hover { background: #e6edf3; color: var(--color-primario); }
.modulo-panel__asa:active { cursor: grabbing; }

.modulo-panel__acciones {
    margin-left: auto;
    display: flex;
    gap: 0.25rem;
}
.modulo-panel__acciones button {
    background: transparent;
    color: var(--color-texto-secundario);
    border: 1px solid var(--color-borde);
    padding: 0.2rem 0.45rem;
    font-size: 0.8rem;
    margin-top: 0;
    line-height: 1.3;
}
.modulo-panel__acciones button:hover:not(:disabled) {
    background: var(--color-primario);
    border-color: var(--color-primario);
    color: #fff;
}
.modulo-panel__acciones button:disabled { opacity: 0.35; cursor: not-allowed; }

.modulo-panel__cuerpo { padding: 0.9rem 1rem 1rem; }
.modulo-panel__nota {
    margin: 0 0 0.75rem;
    font-size: 0.85rem;
    color: var(--color-texto-secundario);
}

.modulo-panel.arrastrando { opacity: 0.45; }
.modulo-panel.destino { outline: 2px dashed var(--color-primario); outline-offset: 2px; }

/* Bandeja de módulos ocultos */
.bandeja-ocultos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1rem;
    padding: 0.6rem 0.9rem;
    background: #f0f4f8;
    border: 1px dashed var(--color-borde);
    border-radius: var(--radio);
    font-size: 0.85rem;
}
.bandeja-ocultos button {
    background: var(--color-superficie);
    color: var(--color-primario);
    border: 1px solid var(--color-borde);
    padding: 0.2rem 0.55rem;
    font-size: 0.82rem;
    margin-top: 0;
}
.bandeja-ocultos button:hover { background: var(--color-primario); color: #fff; }

.barra-vista {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    margin-bottom: 1rem;
}
.barra-vista label {
    display: flex;
    flex-direction: column;
    font-size: 0.85rem;
    color: var(--color-texto-secundario);
}
.barra-vista .acciones-vista { margin-left: auto; display: flex; gap: 0.5rem; align-items: flex-end; }
.barra-vista .boton-secundario {
    background: transparent;
    color: var(--color-primario);
    border: 1px solid var(--color-borde);
}
.barra-vista .boton-secundario:hover { background: #e6edf3; }

.aviso-guardado {
    font-size: 0.82rem;
    color: var(--color-ok);
    margin: 0 0 1rem;
}

/* ---------------------------------------------------------------------
   6. Tablas de datos
   Una sola clase para todas las tablas del sistema. Antes cada página
   repetía el mismo padding y borde celda por celda con style="...".
   --------------------------------------------------------------------- */
.tabla-datos { width: 100%; border-collapse: collapse; font-size: var(--txt-md); }
.tabla-datos th,
.tabla-datos td { padding: 0.45rem 0.5rem; text-align: left; border-bottom: 1px solid var(--color-borde); }
/* Sin text-transform: uppercase. Los encabezados llevan unidades y símbolos
   donde la caja cambia el significado — "mΩ" (miliohm) se convertiría en "MΩ"
   (megaohm, 10⁹ veces mayor), "mA" en "MA" y "R 30 s" en "R 30 S" (siemens).
   La jerarquía visual se logra con color y peso. */
.tabla-datos th {
    color: var(--color-texto-secundario);
    font-size: 0.8rem;
    letter-spacing: 0.02em;
    font-weight: bold;
    white-space: nowrap;
}
.tabla-datos tbody tr:hover { background: #f7fafc; }
.tabla-datos caption {
    caption-side: top;
    text-align: left;
    font-size: var(--txt-sm);
    color: var(--color-texto-secundario);
    padding-bottom: var(--esp-2);
}

/* Densidad compacta: se activa poniendo data-densidad="compacta" en <html>
   (ver assets/js/preferencias.js). Ayuda con tablas de muchas filas. */
[data-densidad="compacta"] .tabla-datos { font-size: var(--txt-sm); }
[data-densidad="compacta"] .tabla-datos th,
[data-densidad="compacta"] .tabla-datos td { padding: 0.22rem 0.4rem; }

/* Contenedor con scroll horizontal. El histórico llega a 20 columnas: sin
   esto la página entera se desplaza y se pierde la referencia. */
.tabla-scroll { overflow-x: auto; }

/* Encabezado fijo al desplazarse: requiere altura máxima en el contenedor. */
.tabla-scroll--alta { max-height: 70vh; overflow-y: auto; }
.tabla-scroll--alta .tabla-datos thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--color-superficie-alt);
    /* border-bottom no se pinta en celdas sticky: se simula con la sombra. */
    box-shadow: inset 0 -1px 0 var(--color-borde);
}

/* Primera columna fija (el Tag): al desplazarse a la derecha se mantiene la
   referencia de qué equipo se está leyendo. */
.tabla-datos--col-fija th:first-child,
.tabla-datos--col-fija td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--color-superficie);
    box-shadow: 1px 0 0 var(--color-borde);
}
.tabla-datos--col-fija tbody tr:hover td:first-child { background: #f7fafc; }
.tabla-scroll--alta .tabla-datos--col-fija thead th:first-child {
    z-index: 3;
    background: var(--color-superficie-alt);
}

/* Estados de valor medido */
.estado-vencido { color: var(--color-acento); font-weight: bold; }
.estado-porvencer { color: var(--color-alerta); font-weight: bold; }
.estado-ok { color: var(--color-ok); }

/* Celdas de medición fuera de criterio. El fondo tenue además del color de
   texto permite localizarlas recorriendo la tabla con la vista. */
.valor-excede { color: var(--color-acento); font-weight: bold; background: var(--color-acento-tenue); }
.valor-atencion { color: var(--color-alerta); font-weight: bold; background: var(--color-alerta-tenue); }
.valor-conforme { color: var(--color-ok); }
.fila-excede td { background: var(--color-acento-tenue); }

/* ---------------------------------------------------------------------
   7. Utilidades
   Reemplazan los style="..." que estaban repartidos por las páginas.
   --------------------------------------------------------------------- */
.txt-secundario { color: var(--color-texto-secundario); }
.txt-sm { font-size: var(--txt-sm); }
.txt-xs { font-size: var(--txt-xs); }
.txt-nota { color: var(--color-texto-secundario); font-size: var(--txt-sm); }
.txt-alerta { color: var(--color-alerta); }
.txt-acento { color: var(--color-acento); }
.txt-ok { color: var(--color-ok); }
.txt-fuerte { font-weight: bold; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.centrado { text-align: center; }
.sin-margen { margin: 0; }
.sin-margen-arriba { margin-top: 0; }
.sin-margen-abajo { margin-bottom: 0; }
.abajo { align-self: flex-end; }
.nowrap { white-space: nowrap; }

/* ---------------------------------------------------------------------
   Acciones de fila con icono
   En las tablas anchas, las columnas «Editar» / «Ver detalle» gastaban en
   texto un espacio que necesitan los datos. El icono conserva el destino
   pero ocupa una fracción: el nombre de la acción sigue disponible en el
   title (cursor) y en aria-label (lector de pantalla), nunca se pierde.
   --------------------------------------------------------------------- */
.acciones-celda {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    justify-content: flex-end;
}
.boton-icono {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex: none;
    padding: 0;
    margin: 0;
    border: 1px solid transparent;
    border-radius: var(--radio);
    background: transparent;
    color: var(--color-texto-secundario);
    cursor: pointer;
    line-height: 1;
}
.boton-icono:hover {
    background: var(--color-realce);
    border-color: var(--color-borde);
    color: var(--color-primario);
    text-decoration: none;
}
/* Acción destructiva: sólo se tiñe al apuntarla, para que no grite en reposo
   pero quede claro antes de hacer clic. */
.boton-icono--peligro:hover {
    color: var(--color-acento);
    background: var(--color-acento-tenue);
    border-color: var(--color-acento);
}
.icono-accion {
    width: 17px;
    height: 17px;
    display: block;
}
/* La columna de acciones no aporta nada en papel */
@media print {
    .acciones-celda, th.col-acciones { display: none; }
}
.txt-primario { color: var(--color-primario); }
.txt-base { font-size: var(--txt-base); }
.sep-izq { margin-left: var(--esp-3); }
.borde-arriba { border-top: 2px solid var(--color-borde); }
/* Fila del registro que se está viendo, dentro de un listado */
.fila-actual td { background: var(--color-realce); }
/* Campo de formulario que necesita más ancho que sus vecinos */
.campo-ancho { flex: 2 1 260px; }
/* Casilla con su etiqueta al costado, en vez de encima */
.campo-inline { flex-direction: row; align-items: center; gap: var(--esp-1); }

/* Listas de detalle dentro de tarjetas */
.lista-compacta { margin: 0.4rem 0; padding-left: 1.2rem; }
.lista-compacta li { margin-bottom: var(--esp-1); }

/* Pasos numerados del manual: cada paso separado por una línea, como una
   secuencia de trabajo real (no una lista decorativa). */
.lista-pasos { list-style: none; counter-reset: paso; margin: 0; padding: 0; }
.lista-pasos li {
    counter-increment: paso;
    position: relative;
    padding: var(--esp-3) 0 var(--esp-3) 2.6rem;
    border-top: 1px solid var(--color-borde);
}
.lista-pasos li:first-child { border-top: none; padding-top: 0; }
.lista-pasos li::before {
    content: counter(paso);
    position: absolute;
    left: 0;
    top: var(--esp-3);
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 50%;
    background: var(--color-primario);
    color: #fff;
    font-weight: bold;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
}
.lista-pasos li:first-child::before { top: 0; }
.lista-pasos li p { margin: 0.3rem 0 0; color: var(--color-texto-secundario); font-size: 0.92rem; }

/* Preguntas frecuentes: acordeón simple reutilizando <details> nativo */
.pregunta-frecuente {
    border-top: 1px solid var(--color-borde);
    padding: var(--esp-2) 0;
}
.pregunta-frecuente:first-of-type { border-top: none; }
.pregunta-frecuente summary { cursor: pointer; font-weight: bold; }
.pregunta-frecuente p { margin: var(--esp-2) 0 0; color: var(--color-texto-secundario); }

/* Etiqueta redonda para marcar estado o tipo */
.chip {
    display: inline-block;
    font-size: var(--txt-xs);
    border: 1px solid var(--color-borde);
    border-radius: 999px;
    padding: 0 0.45rem;
    color: var(--color-texto-secundario);
}
.chip--ok { border-color: var(--color-ok); color: var(--color-ok); background: var(--color-ok-tenue); }
.chip--alerta { border-color: var(--color-alerta); color: var(--color-alerta); background: var(--color-alerta-tenue); }
.chip--acento { border-color: var(--color-acento); color: var(--color-acento); background: var(--color-acento-tenue); }

/* Logos de empresa. Los archivos vienen con proporciones dispares, así que
   siempre se fija la altura y el ancho se ajusta con object-fit. */
.logo-miniatura {
    height: 28px;
    width: auto;
    max-width: 110px;
    object-fit: contain;
    display: block;
}
/* Firmas escaneadas: fondo casi siempre blanco, así que se deja un borde
   sutil para que no se pierdan sobre el fondo de la tarjeta. */
.miniatura-firma {
    height: 28px;
    width: auto;
    max-width: 90px;
    object-fit: contain;
    display: block;
    background: #fff;
    border: 1px solid var(--color-borde, #ddd);
    border-radius: 4px;
    padding: 2px 4px;
}
.firma-grande {
    max-height: 90px;
    max-width: 220px;
    object-fit: contain;
    display: block;
    background: #fff;
    border: 1px solid var(--color-borde, #ddd);
    border-radius: 6px;
    padding: 8px 12px;
}
.logo-empresa-arbol {
    height: 20px;
    width: auto;
    max-width: 80px;
    object-fit: contain;
    vertical-align: middle;
}
.logo-vista-previa {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Cuadros claro y oscuro: revela halos blancos en logos sin transparencia */
    background: repeating-conic-gradient(#f0f0f0 0% 25%, #ffffff 0% 50%) 50% / 16px 16px;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
    padding: var(--esp-3);
    margin-bottom: var(--esp-2);
}
.logo-vista-previa img { max-height: 90px; max-width: 260px; object-fit: contain; display: block; }

/* Estado vacío: mismo trato en todo el sistema en vez de un <p> suelto */
.estado-vacio {
    text-align: center;
    color: var(--color-texto-secundario);
    padding: var(--esp-5) var(--esp-4);
    border: 1px dashed var(--color-borde);
    border-radius: var(--radio);
    background: var(--color-superficie-alt);
}
.estado-vacio p { margin: 0 0 var(--esp-2); }
.estado-vacio p:last-child { margin-bottom: 0; }

/* Barra de herramientas de una vista (filtros + acciones) */
.barra-herramientas {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--esp-3);
    margin-bottom: var(--esp-4);
}
.barra-herramientas .a-la-derecha { margin-left: auto; display: flex; gap: var(--esp-2); align-items: flex-end; }

.boton-secundario {
    background: transparent;
    color: var(--color-primario);
    border: 1px solid var(--color-borde);
}
.boton-secundario:hover { background: var(--color-realce); }

/* Grupo de botones tipo pestaña (ej. subir firma vs. dibujarla) */
.grupo-botones { display: flex; gap: var(--esp-2); margin: var(--esp-3) 0; }
.grupo-botones [aria-pressed="true"] {
    background: var(--color-primario);
    color: #fff;
    border-color: var(--color-primario);
}

/* Lienzo para dibujar la firma a mano */
.lienzo-firma {
    display: block;
    width: 100%;
    max-width: 500px;
    height: 160px;
    background: #fff;
    border: 1px dashed var(--color-borde);
    border-radius: var(--radio);
    cursor: crosshair;
    touch-action: none;
}

/* Control de densidad de las vistas de tabla */
.barra-densidad { display: flex; justify-content: flex-end; margin-bottom: var(--esp-2); }
.barra-densidad button { font-size: var(--txt-sm); padding: 0.2rem 0.5rem; margin-top: 0; }

/* ---------------------------------------------------------------------
   Gráficos del dashboard. Todos con CSS puro: sin librerías, para que el
   sistema siga funcionando sin conexión.
   --------------------------------------------------------------------- */

/* Barras de composición: estado y cobertura por empresa */
.barras-estado { display: flex; flex-direction: column; gap: var(--esp-2); }
.barras-estado__fila { display: flex; align-items: center; gap: var(--esp-2); font-size: var(--txt-md); }
.barras-estado__etiqueta { flex: 0 0 10rem; color: var(--color-texto-secundario); }
.barras-estado__pista {
    flex: 1 1 auto;
    display: flex;
    height: 1.1rem;
    background: #eef2f6;
    border-radius: 3px;
    overflow: hidden;
}
.barras-estado__seg { height: 100%; }
.barras-estado__numero { flex: 0 0 3.5rem; text-align: right; font-weight: bold; font-variant-numeric: tabular-nums; }
.barras-estado__detalle { flex: 0 0 6.5rem; font-size: var(--txt-sm); }

.leyenda {
    display: flex;
    flex-wrap: wrap;
    gap: var(--esp-4);
    margin-top: var(--esp-3);
    padding-top: var(--esp-2);
    border-top: 1px solid var(--color-borde);
    font-size: var(--txt-sm);
    color: var(--color-texto-secundario);
}
.leyenda__item i {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 2px;
    margin-right: 0.35rem;
    vertical-align: -1px;
}
.leyenda__hoy {
    width: 0 !important;
    border-left: 2px dashed var(--color-alerta);
    height: 12px !important;
    border-radius: 0 !important;
}

/* Guía de qué escribir en cada nivel de ubicación (ubicacion/nuevo.php).
   Se apoya en el borde izquierdo para leerse como una nota al margen del
   formulario, no como otro bloque de campos. */
.guia-nivel {
    border-left: 3px solid var(--color-primario);
    background: var(--color-realce);
    border-radius: 0 var(--radio) var(--radio) 0;
    padding: var(--esp-3) var(--esp-4);
    margin-bottom: var(--esp-4);
    font-size: var(--txt-sm);
}
.guia-nivel__que-es {
    margin: 0 0 var(--esp-3);
    font-weight: bold;
    color: var(--color-primario);
}
.guia-nivel__campos { margin: 0; }
.guia-nivel__campos dt {
    font-weight: bold;
    color: var(--color-texto);
    margin-top: var(--esp-2);
}
.guia-nivel__campos dt:first-child { margin-top: 0; }
.guia-nivel__campos dd {
    margin: 0.15rem 0 0;
    color: var(--color-texto-secundario);
}
.guia-nivel__ejemplos { display: block; margin-top: 0.25rem; }
.guia-nivel__ejemplos code {
    background: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: 3px;
    padding: 0.05rem 0.35rem;
    margin-right: 0.25rem;
    font-size: 0.95em;
}

/* Selección de instrumentos usados en una mantención: casillas en columna,
   cada una con la identificación completa y el estado de su calibración. */
.lista-instrumentos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--esp-2);
    margin-bottom: var(--esp-3);
}
.instrumento-opcion {
    display: flex;
    align-items: flex-start;
    gap: var(--esp-2);
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
    font-size: var(--txt-sm);
    cursor: pointer;
}
.instrumento-opcion:hover { background: var(--color-realce); }
.instrumento-opcion input { margin-top: 0.15rem; flex: none; }
.instrumento-opcion > span { display: flex; flex-direction: column; gap: 0.15rem; }
.instrumento-opcion .chip { align-self: flex-start; }

/* Lista de chips con conteo (ej. licencias de conducir por clase) */
.chips-conteo {
    display: flex;
    flex-wrap: wrap;
    gap: var(--esp-2);
}

/* Carta Gantt: una fila por equipo, de la mantención a su vencimiento */
.gantt { font-size: var(--txt-sm); }
.gantt__fila, .gantt__eje { display: flex; align-items: center; gap: var(--esp-2); }
.gantt__fila { margin-bottom: 0.3rem; }
.gantt__eje {
    margin-bottom: var(--esp-2);
    padding-bottom: var(--esp-1);
    border-bottom: 1px solid var(--color-borde);
    color: var(--color-texto-secundario);
    font-size: var(--txt-xs);
}
.gantt__etiqueta {
    flex: 0 0 11rem;
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--color-texto);
}
.gantt__pista {
    position: relative;
    flex: 1 1 auto;
    height: 1.1rem;
    background: var(--color-superficie-alt);
    border-radius: 3px;
}
.gantt__eje .gantt__pista { background: none; height: 1rem; }
.gantt__marca { position: absolute; transform: translateX(-50%); white-space: nowrap; }
.gantt__barra {
    position: absolute;
    top: 0.15rem;
    height: 0.8rem;
    border-radius: 3px;
    min-width: 3px;
    display: block;
}
.gantt__barra:hover { filter: brightness(1.15); }
.gantt__barra--vigente { background: var(--color-ok); }
.gantt__barra--vencido { background: var(--color-acento); }
/* Línea de "hoy": referencia para leer si la barra ya quedó atrás */
.gantt__hoy {
    position: absolute;
    top: -0.15rem;
    bottom: -0.15rem;
    border-left: 2px dashed var(--color-alerta);
    pointer-events: none;
}
.gantt__fecha {
    flex: 0 0 5.5rem;
    text-align: right;
    color: var(--color-texto-secundario);
    font-variant-numeric: tabular-nums;
}

/* Calendario de vencimientos: intensidad según la carga del mes */
.calendario__celda { font-weight: bold; }

/* Tabla colapsable: sólo las primeras filas visibles, con un botón que
   despliega el resto sin salir del módulo. Las filas extra las oculta el JS
   (dashboard.js) agregando .fila-colapsada; en papel se muestran siempre. */
.fila-colapsada { display: none; }
.boton-ver-mas { margin-top: var(--esp-2); }
@media print {
    .fila-colapsada { display: table-row !important; }
}

/* Mini gráfico de barras horizontales, sin librerías */
.barras { display: flex; flex-direction: column; gap: 0.35rem; }
.barras__fila { display: flex; align-items: center; gap: 0.6rem; font-size: 0.88rem; }
.barras__etiqueta { flex: 0 0 8.5rem; color: var(--color-texto-secundario); }
.barras__pista { flex: 1 1 auto; background: #eef2f6; border-radius: 3px; height: 0.9rem; }
.barras__valor { background: var(--color-primario); height: 100%; border-radius: 3px; }
.barras__numero { flex: 0 0 3rem; text-align: right; font-weight: bold; }

.vacio-modulo { color: var(--color-texto-secundario); font-size: 0.9rem; margin: 0; }

/* ---------------------------------------------------------------------
   Árbol de ubicación (ubicacion/selector.php)
   Usa <details>/<summary> nativos: expandir/colapsar sin JavaScript.
   --------------------------------------------------------------------- */
.arbol, .arbol ul {
    list-style: none;
    margin: 0;
    padding: 0;
}
.arbol ul {
    /* Sangría con guía vertical para seguir la jerarquía */
    margin-left: 0.65rem;
    padding-left: 0.9rem;
    border-left: 1px solid var(--color-borde);
}
.arbol li { margin: 0.15rem 0; }

.arbol summary {
    cursor: pointer;
    padding: 0.3rem 0.4rem;
    border-radius: var(--radio);
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
}
.arbol summary:hover { background: #eef4f9; }
.arbol details[open] > summary { font-weight: bold; }

.nodo-nivel {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-texto-secundario);
    font-weight: normal;
    flex: 0 0 auto;
}
.nodo-nombre { color: var(--color-texto); }

.nodo-conteo {
    font-size: 0.78rem;
    color: var(--color-texto-secundario);
    font-weight: normal;
}
.nodo-vacio {
    font-size: 0.78rem;
    color: var(--color-alerta);
    font-weight: normal;
}

/* Hoja del árbol: un equipo concreto */
.arbol .equipo {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.3rem 0.4rem 0.3rem 1.5rem;
    font-size: 0.9rem;
}
.arbol .equipo:hover { background: #f7fafc; }
.arbol .equipo .etiqueta-tipo {
    font-size: 0.72rem;
    color: var(--color-texto-secundario);
    border: 1px solid var(--color-borde);
    border-radius: 999px;
    padding: 0 0.45rem;
}
.arbol .equipo .acciones { margin-left: auto; font-size: 0.82rem; }
.arbol .equipo .acciones a { margin-left: 0.6rem; }

/* Resalta el nodo/equipo que coincide con la búsqueda */
.coincide > summary > .nodo-nombre,
.equipo.coincide .tag-equipo { background: #fff3cd; border-radius: 3px; padding: 0 0.15rem; }

/* ---------------------------------------------------------------------
   9b. Protocolo imprimible (mantenciones/imprimir.php)
   Se ve como una hoja de protocolo tanto en pantalla como en papel.
   --------------------------------------------------------------------- */
.protocolo {
    background: var(--color-superficie);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio);
    padding: var(--esp-5);
    max-width: 1000px;
    margin: 0 auto;
}

.protocolo__cabecera {
    display: flex;
    flex-wrap: wrap;
    gap: var(--esp-4);
    align-items: flex-start;
    justify-content: space-between;
    border-bottom: 2px solid var(--color-primario);
    padding-bottom: var(--esp-3);
    margin-bottom: var(--esp-4);
}
.protocolo__titulo { flex: 1 1 260px; }

/* Logos del encabezado. Vienen con proporciones muy distintas (unos
   cuadrados, otros apaisados), así que se limita la altura y se deja que el
   ancho se ajuste: así todos ocupan el mismo espacio vertical. */
.protocolo__logos {
    display: flex;
    align-items: center;
    gap: var(--esp-4);
    flex: 0 0 auto;
}
.logo-protocolo {
    height: 46px;
    width: auto;
    max-width: 170px;
    object-fit: contain;
}
.protocolo__cabecera h1 {
    margin: 0;
    font-size: 1.3rem;
    color: var(--color-primario);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.protocolo__subtitulo {
    margin: var(--esp-1) 0 0;
    font-size: var(--txt-md);
    color: var(--color-texto-secundario);
    letter-spacing: 0.05em;
}

.protocolo__meta { border-collapse: collapse; font-size: var(--txt-sm); }
.protocolo__meta th,
.protocolo__meta td { border: 1px solid var(--color-borde); padding: 0.2rem 0.5rem; text-align: left; }
.protocolo__meta th { background: var(--color-superficie-alt); color: var(--color-texto-secundario); font-weight: normal; }

.protocolo__seccion { margin-bottom: var(--esp-5); break-inside: avoid; }
.protocolo__seccion h2 {
    font-size: var(--txt-base);
    color: var(--color-primario);
    margin: 0 0 var(--esp-2);
    padding-bottom: var(--esp-1);
    border-bottom: 1px solid var(--color-borde);
}

/* Criterio de aceptación citado del protocolo original */
.protocolo__criterio {
    margin: 0 0 var(--esp-2);
    font-size: var(--txt-sm);
    color: var(--color-texto-secundario);
    font-style: italic;
}
.protocolo__obs {
    margin: var(--esp-2) 0 0;
    font-size: var(--txt-sm);
    color: var(--color-texto-secundario);
}

/* Tabla de pares etiqueta/valor (descripción y datos de placa) */
.tabla-pares th {
    background: var(--color-superficie-alt);
    font-weight: normal;
    text-transform: none;
    letter-spacing: 0;
    font-size: var(--txt-sm);
    width: 1%;
    white-space: nowrap;
}
.tabla-pares th,
.tabla-pares td { border: 1px solid var(--color-borde); }

/* Bloque de firmas: tres columnas con línea para firmar */
.protocolo__firmas {
    display: flex;
    flex-wrap: wrap;
    gap: var(--esp-5);
    margin-top: var(--esp-6);
    break-inside: avoid;
}
.firma { flex: 1 1 180px; text-align: center; }
.firma__linea { border-top: 1px solid var(--color-texto); margin-bottom: var(--esp-1); }
/* Firma escaneada: reemplaza la línea en blanco cuando la persona tiene una
   cargada. Altura fija para que las tres columnas queden parejas aunque las
   imágenes originales tengan proporciones distintas. */
.firma__imagen {
    display: block;
    height: 60px;
    width: auto;
    max-width: 100%;
    object-fit: contain;
    margin: 0 auto var(--esp-1);
}
.firma__nombre { font-size: var(--txt-md); min-height: 1.4em; }
/* El cargo se muestra tal como está registrado, sin forzar mayúsculas: así
   coincide con lo que dice el protocolo en papel. */
.firma__rol { font-size: var(--txt-xs); color: var(--color-texto-secundario); letter-spacing: 0.03em; }

/* ---------------------------------------------------------------------
   10. Impresión
   Los protocolos se imprimen y se firman. En papel no sirven el menú, los
   botones ni los fondos de color, y conviene que las tablas no se corten
   entre páginas.
   --------------------------------------------------------------------- */
@media print {
    /* Negro sobre blanco: ahorra tóner y mantiene legible el gris claro. */
    :root {
        --color-fondo: #fff;
        --color-superficie: #fff;
        --color-superficie-alt: #fff;
        --color-texto: #000;
        --color-texto-secundario: #333;
        --color-primario: #000;
        --color-borde: #999;
        --color-acento-tenue: transparent;
        --color-alerta-tenue: transparent;
        --color-ok-tenue: transparent;
    }

    body { background: #fff; color: #000; font-size: 10.5pt; }

    /* Cromo de pantalla que no va al papel */
    .app-sidebar,
    .app-footer,
    .app-nav,
    .salto-contenido,
    .barra-herramientas,
    .barra-vista,
    .bandeja-ocultos,
    .modulo-panel__asa,
    .modulo-panel__acciones,
    .aviso-guardado,
    .no-imprimir,
    button,
    form.barra-vista { display: none !important; }

    .app-shell { display: block; min-height: 0; }
    .app-content { display: block; }

    .app-main {
        max-width: none;
        margin: 0;
        padding: 0;
    }

    /* Las tarjetas pierden el relieve pero conservan la separación lógica */
    .tarjeta,
    .modulo-panel {
        border: 1px solid #999;
        box-shadow: none;
        break-inside: avoid;
        page-break-inside: avoid;
        margin-bottom: 0.5rem;
    }

    /* Una fila de medición partida entre dos hojas es ilegible */
    .tabla-datos { font-size: 9.5pt; }
    .tabla-datos tr,
    .tabla-datos thead { break-inside: avoid; page-break-inside: avoid; }
    /* El encabezado se repite en cada hoja de una tabla larga */
    .tabla-datos thead { display: table-header-group; }
    .tabla-datos tfoot { display: table-footer-group; }

    /* En papel no hay scroll ni celdas fijas */
    .tabla-scroll,
    .tabla-scroll--alta { overflow: visible !important; max-height: none !important; }
    .tabla-datos--col-fija th:first-child,
    .tabla-datos--col-fija td:first-child,
    .tabla-scroll--alta .tabla-datos thead th {
        position: static !important;
        box-shadow: none;
    }

    /* Los valores fuera de criterio se distinguen sin depender del color */
    .valor-excede,
    .estado-vencido { font-weight: bold; text-decoration: underline; }

    /* Mostrar la dirección de los enlaces no aporta en un protocolo interno */
    a { color: #000; text-decoration: none; }

    /* El árbol de ubicación se imprime desplegado */
    details { display: block; }
    details > summary { list-style: none; }

    .salto-pagina { break-before: page; page-break-before: always; }
    .solo-impresion { display: block !important; }

    /* El protocolo ocupa la hoja completa, sin marco ni relleno de tarjeta */
    .protocolo {
        border: none;
        padding: 0;
        max-width: none;
        margin: 0;
    }
    .protocolo__cabecera { border-bottom: 2px solid #000; }
    /* Los logos sí van al papel: identifican al cliente y al prestador.
       Sin esta regla el navegador puede omitir imágenes al imprimir. */
    .protocolo__logos { display: flex !important; }
    .logo-protocolo {
        height: 15mm;
        max-width: 45mm;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
    .protocolo__seccion h2 { border-bottom: 1px solid #000; }
    /* Las firmas no deben quedar solas al final de una hoja */
    .protocolo__firmas { margin-top: 1.5cm; }
    .firma__linea { border-top: 1px solid #000; }
    /* Sin fondos grises: en papel restan legibilidad al texto pequeño */
    .tabla-pares th,
    .protocolo__meta th { background: transparent; }
    .protocolo__meta th,
    .protocolo__meta td,
    .tabla-pares th,
    .tabla-pares td { border-color: #666; }
}

@page {
    /* Margen de la hoja: deja espacio para archivar el protocolo perforado */
    margin: 1.5cm 1.2cm;
}

/* Bloques que existen únicamente en el papel (encabezado de protocolo, firmas) */
.solo-impresion { display: none; }

/* ---------------------------------------------------------------------
   11. Pantallas angostas
   El sistema se usa en PC de oficina; esto es una salvaguarda para que
   nada quede inalcanzable si se abre en un equipo chico.
   --------------------------------------------------------------------- */
@media (max-width: 720px) {
    /* La barra lateral no cabe fija en una pantalla angosta: pasa a ser un
       bloque normal arriba del contenido, con el menú en fila. Aquí el
       plegado a iconos no aplica — el ancho ya no es el problema. */
    .app-shell { flex-direction: column; }
    .app-sidebar,
    :root[data-menu="plegado"] .app-sidebar {
        position: static;
        height: auto;
        width: auto;
        flex: 0 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--esp-2);
    }
    .menu-toggle { display: none; }
    .app-header__brand,
    :root[data-menu="plegado"] .app-header__brand { margin-bottom: 0; }
    .app-nav { flex-direction: row; flex-wrap: wrap; gap: var(--esp-1); }
    .app-header__sesion { margin-top: 0; padding-top: 0; border-top: none; flex-direction: row; flex-wrap: wrap; }
    /* Con el menú en fila, el texto vuelve aunque quedara la preferencia de plegado. */
    :root[data-menu="plegado"] .app-header__nombre,
    :root[data-menu="plegado"] .app-nav a > span,
    :root[data-menu="plegado"] .app-header__sesion a > span { display: inline; }
    :root[data-menu="plegado"] .app-header__usuario { display: flex; }
    :root[data-menu="plegado"] .app-nav a,
    :root[data-menu="plegado"] .app-header__sesion a { gap: 0.6rem; padding: 0.35rem 0.6rem; }
    /* En fila el ancho ya no es el problema: siempre el logo completo. */
    .logo-electra-menu--completo,
    :root[data-menu="plegado"] .logo-electra-menu--completo { display: block; max-width: 130px; }
    .logo-electra-menu--icono,
    :root[data-menu="plegado"] .logo-electra-menu--icono { display: none; }
    .app-main { padding: 0 var(--esp-3) var(--esp-5); }
    .formulario-linea label { flex-basis: 100%; }
    .barra-herramientas .a-la-derecha { margin-left: 0; width: 100%; }
    .indicadores { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
    .barras__etiqueta { flex-basis: 6rem; }
    /* Con poco ancho la columna fija ocuparía casi toda la pantalla */
    .tabla-datos--col-fija th:first-child,
    .tabla-datos--col-fija td:first-child { position: static; box-shadow: none; }
}
