html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* Resaltado de la zona de arrastre (drag & drop) de subida de archivos.
   Lo activa/desactiva js/arrastre.js en el navegador (nunca el circuito de Blazor):
   al pasar un archivo por encima del recuadro, .vigia-arrastre-activa resalta el
   borde punteado y el fondo. Ver ZonaArrastreArchivo.razor y js/arrastre.js. */
.vigia-arrastre.vigia-arrastre-activa .vigia-arrastre-zona {
    border-color: var(--mud-palette-primary) !important;
    background-color: var(--mud-palette-action-default-hover);
}

a, .btn-link {
    color: #006bb7;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

/* TÁCTIL 2 — Tanda 1 (Artículos): vista de tarjetas apiladas en tablet/móvil.
   MudTable Breakpoint="Sm" (Articulos.razor) activa la clase nativa .mud-sm-table de
   MudBlazor en <=960px (tabla de escritorio en >960px intacta, esa clase no se aplica).
   Global y NO aislado a propósito: el aislamiento de CSS de Blazor (::deep) solo estampa
   el atributo de ámbito en el elemento raíz del componente hijo referenciado en el propio
   marcado (el <div class="mud-table ..."> que envuelve a MudTable), pero NUNCA en los
   descendientes que MudTable renderiza internamente (filas/celdas/botones) — verificado con
   bounding boxes de Playwright: un .razor.css con ::deep no llegaba a aplicarse. La clase
   "vigia-articulos-tabla" (Class= en el <MudTable>) es el ancla, igual que .vigia-arrastre
   arriba para el mismo tipo de caso (JS/CSS que necesita alcanzar dentro de un componente).

   INCIDENCIA CORREGIDA (detectada tras la Tanda 3, diagnóstico en
   docs/capturas/diagnostico_alineacion/, commit de capturas 3ca6a25): ".mud-sm-table" NO es
   una clase que MudBlazor añada/quite por JS según el ancho medido — es ESTÁTICA, siempre
   presente en el DOM en cuanto Breakpoint="Sm", confirmado leyendo MudBlazor.min.css 9.6.0
   empaquetado. El interruptor real de MudBlazor es "@media(max-width: 960px){ .mud-sm-table
   ... }" — sus PROPIAS reglas SÍ están dentro de esa media query. Las reglas de abajo NO lo
   estaban: se aplicaban también en escritorio, rompiendo el layout nativo de tabla
   (".mud-table-row{display:block}" convierte cada fila en una mini-tabla anónima
   independiente, con su propio cálculo de anchos — cabecera y celdas dejan de compartir
   columna, y "overflow:hidden" recorta silenciosamente lo que no cabe). Arreglo: envolver
   TODO este bloque en el mismo "@media (max-width: 960px)" que usa MudBlazor —el mismo
   umbral EXACTO, verificado en el CSS instalado, no 959.98px ni ninguna otra variante—. */
@media (max-width: 960px) {
    .vigia-articulos-tabla.mud-sm-table .mud-table-row {
        display: block;
        margin-bottom: 12px;
        border: 1px solid var(--mud-palette-table-lines);
        border-radius: 8px;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
        overflow: hidden;
    }

    /* Fila >= 48px (zona táctil, investigación §2) y tipografía de cuerpo algo mayor. */
    .vigia-articulos-tabla.mud-sm-table .mud-table-cell {
        min-height: 48px;
        font-size: 0.95rem;
    }

    .vigia-articulos-tabla.mud-sm-table .mud-table-cell:before {
        font-size: 0.85rem;
    }

    /* Botones de acción (Ver/Editar, Dar de baja/Reactivar): Size="Size.Small" se queda en
       ~24px; se agranda solo en tarjeta para cumplir el mínimo de 48px con guante/dedo. */
    .vigia-articulos-tabla.mud-sm-table .mud-icon-button {
        min-width: 48px;
        min-height: 48px;
        padding: 12px;
    }

    .vigia-articulos-tabla.mud-sm-table .mud-icon-button .mud-icon-root {
        font-size: 1.5rem;
    }
}

/* TÁCTIL 2 — Tanda 2 (Entrega de EPIs con firma, EntregaEpiDialog.razor): mismo patrón que
   Tanda 1 — reglas GLOBALES bajo clases ancla "vigia-epi-*" puestas en el propio marcado del
   diálogo, nunca ::deep en un .razor.css aislado (el aislamiento de Blazor no llega a los
   descendientes que MudBlazor renderiza internamente: el <input> de un MudSelect/MudDatePicker,
   el botón interno de un MudCheckBox, las filas de un MudSimpleTable...). Cero efecto en otros
   diálogos de la app: todo cuelga de estas clases, puestas solo aquí.

   REVISADO tras la incidencia de alineación de Artículos/Mantenimiento (arriba): estas reglas
   NO tienen el mismo defecto y NO se envuelven en "@media (max-width: 960px)". Motivo: aquí no
   hay ningún MudTable con Breakpoint ni clase ".mud-sm-table" de por medio —el mecanismo que
   causó el bug—; el paso 1 usa MudSimpleTable ("vigia-epi-tabla-seleccion"), que no tiene modo
   tarjeta nativo ni breakpoint alguno que gatear, y el resto son MudTextField/MudSelect/
   MudButton sueltos dentro de un diálogo, sin ningún "display:block" sobre filas de tabla que
   pueda romper una alineación columna-a-columna (no hay columnas que alinear: es un formulario,
   no una tabla). Que los campos/botones/filas de este diálogo midan ≥48-64px en TODOS los
   tamaños (incluido escritorio) es DELIBERADO, no un escape del bug: el usuario ya lo verificó
   visualmente en v66 (escritorio del diálogo intacto en lo que SÍ se prometió — el grid de las
   dos firmas lado a lado, controlado por el breakpoint md="6" de MudItem, un mecanismo distinto
   y correcto de MudBlazor, no una clase estática tipo ".mud-sm-table"); el compromiso de "TACTIL2_
   COMPATIBILIDAD_EPIS.md" nunca prometió botones/campos del mismo tamaño en escritorio, solo
   el layout de la firma. Conclusión: inocuo y deseado, no se toca. */

/* Cabecera del paso 1 (motivo/fecha/responsable): campo >= 48px de alto táctil. */
.vigia-epi-cabecera .mud-input-control {
    min-height: 48px;
}

/* Tabla de selección de EPIs (paso 1, MudSimpleTable — no tiene modo tarjeta nativo): fila y
   casilla de marcado >= 48px, texto algo mayor para legibilidad con sol/distancia. */
.vigia-epi-tabla-seleccion td {
    min-height: 48px;
    padding-top: 8px;
    padding-bottom: 8px;
}

.vigia-epi-tabla-seleccion .mud-checkbox .mud-icon-button {
    min-width: 48px;
    min-height: 48px;
}

.vigia-epi-tabla-seleccion .mud-checkbox .mud-icon-root {
    font-size: 1.4rem;
}

/* Botones primarios del diálogo (avanzar a firmar / confirmar la entrega): acción crítica
   ejecutada a veces con guante, en la zona baja del diálogo (DialogActions) — investigación
   §2, umbral de guante MIL-STD-1472 (~64px / ~20mm). */
.vigia-epi-boton-primario {
    min-height: 64px;
    min-width: 200px;
    font-size: 1.05rem;
    padding: 0 28px;
}

/* Resto de botones del diálogo (Cancelar/Atrás/Limpiar firma): >= 48px. */
.vigia-epi-boton-secundario,
.vigia-epi-boton-limpiar {
    min-height: 48px;
    padding: 0 16px;
}

/* Área de firma (paso 2): el <canvas> solo lleva width:100% (sin alto CSS fijo), así que el
   navegador respeta su proporción intrínseca 500:150 (atributos width/height del elemento,
   SIN TOCAR — mismo mecanismo de captura y mismo PNG de salida). Al pasar de 2 columnas
   (sm="6", activo ya en tablet) a 2 columnas solo desde escritorio (md="6", 960px) cada canvas
   ocupa el ancho completo del diálogo en tablet/móvil y, por esa proporción intrínseca, gana
   alto proporcionalmente (más caja de firma sin cambiar nada del JS). Este bloque solo
   redondea el aspecto visual, no el tamaño. */
.vigia-epi-canvas-firma {
    display: block;
}

/* TÁCTIL 2 — Tanda 3 (Mantenimiento, Mantenimiento.razor): mismo patrón que Tanda 1 — reglas
   GLOBALES bajo la clase ancla "vigia-mantenimiento-tabla" (Class= en el <MudTable>, junto con
   Breakpoint="Breakpoint.Sm"), nunca ::deep en un .razor.css aislado (misma lección: el
   aislamiento de Blazor no llega a los descendientes que MudTable renderiza internamente).

   INCIDENCIA CORREGIDA: mismo defecto y mismo arreglo que en el bloque de Artículos de arriba
   (ver ese comentario para la causa completa — ".mud-sm-table" es estática, el interruptor
   real es la media query, no la clase). Todo el bloque envuelto en "@media (max-width: 960px)"
   —el mismo umbral EXACTO de MudBlazor.min.css—, así que en escritorio (>960px) esta pantalla
   queda intacta: fila = table-row nativo, botones = 26x26 (Size.Small sin modificar). */
@media (max-width: 960px) {
    /* Fila >= 48px y tipografía de cuerpo algo mayor, igual que Artículos (Tanda 1). */
    .vigia-mantenimiento-tabla.mud-sm-table .mud-table-row {
        display: block;
        margin-bottom: 12px;
        border: 1px solid var(--mud-palette-table-lines);
        border-radius: 8px;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
        overflow: hidden;
    }

    .vigia-mantenimiento-tabla.mud-sm-table .mud-table-cell {
        min-height: 48px;
        font-size: 0.95rem;
    }

    .vigia-mantenimiento-tabla.mud-sm-table .mud-table-cell:before {
        font-size: 0.85rem;
    }

    /* Botones de acción por fila: Size="Size.Small" se queda en ~26px. En tarjeta, "Abrir
       ficha" (y cualquier otro icon-button sin la clase de abajo) sube al mínimo táctil de
       48px. */
    .vigia-mantenimiento-tabla.mud-sm-table .mud-icon-button {
        min-width: 48px;
        min-height: 48px;
        padding: 12px;
    }

    .vigia-mantenimiento-tabla.mud-sm-table .mud-icon-button .mud-icon-root {
        font-size: 1.5rem;
    }

    /* "Nuevo parte" es la acción PRIMARIA de esta pantalla: se ejecuta en campo, sobre la
       máquina real, a veces con guante — investigación §2, umbral de guante MIL-STD-1472
       (~64px/~20mm). Selector más específico que la regla general de arriba para poder
       sobrescribirla. */
    .vigia-mantenimiento-tabla.mud-sm-table .mud-icon-button.vigia-mantenimiento-boton-primario {
        min-width: 64px;
        min-height: 64px;
        padding: 16px;
    }
}

/* TÁCTIL 3 — robustez de reconexión SignalR (docs/TACTIL3_RECONEXION_SIGNALR.md §1.3/§4-B):
   UI de reconexión en español sobre el <div id="components-reconnect-modal"> de App.razor.
   GLOBAL a propósito (mismo motivo de siempre: no hay ::deep que valga sobre un elemento que no
   es un componente Razor). Ancla propia "vigia-reconexion-*", sin tocar ninguna otra pantalla.

   Nada de esto depende del ancho de viewport (a propósito, lección de la incidencia de v67: toda
   regla que dependa del tamaño de pantalla debe ir en un "@media" EXPLÍCITO, nunca fiarse de que
   una clase esté o no presente — aquí se evita el problema entero no metiendo ningún breakpoint:
   el overlay es igual de grande en escritorio y en tablet, que es justamente lo que pide el
   estándar táctil de la investigación para un mensaje crítico).

   Contrato de clases que BLAZOR añade/quita solo sobre #components-reconnect-modal (verificado
   contra el código fuente real de UserSpecifiedDisplay.ts, ASP.NET Core 10.0.9 — nunca se tocan
   desde aquí, solo se estilan):
     components-reconnect-show          → 1er intento, inmediato
     components-reconnect-retrying      → intentos 2+ (coexiste con "show", ver más abajo)
     components-reconnect-paused        → servidor dice "circuito desconocido", reanudando
     components-reconnect-failed        → reintentos agotados, circuito aún vivo (SIN salida hoy)
     components-reconnect-resume-failed → la reanudación también falló (SIN salida hoy)
     components-reconnect-rejected      → rechazo explícito (con UI propia, Blazor NO recarga solo)
   El botón "VOLVER A ENTRAR" vive en los TRES estados terminales (failed/resume-failed/rejected):
   nunca debe quedar la pantalla sin ninguna acción posible, el hallazgo central del diagnóstico
   previo (TACTIL3_RECONEXION_SIGNALR.md §1.3: "Failed to resume the session" sin ningún botón). */

/* OJO — hallazgo real durante la implementación, no anticipado por el diagnóstico previo:
   MudBlazor.min.css 9.6.0 trae SU PROPIO CSS de serie para "#components-reconnect-modal"
   (asumiendo que, si existe, se va a maquetar a su estilo con <h5>/<button>), con packages
   `z-index`/`background-color` en `!important` y estilos de `button` (padding, min-width,
   font-size, color, margin en `!important`) — confirmado leyendo el CSS empaquetado real, igual
   que el resto de este documento. Como `app.css` se enlaza ANTES que `MudBlazor.min.css` en
   `App.razor` (orden que NO se toca aquí: cambiarlo arriesgaría el cascade ya verificado de las
   Tandas 1-3), las reglas de abajo usan selectores algo MÁS ESPECÍFICOS que los de MudBlazor
   (prefijo "body", o anidar bajo el propio "#components-reconnect-modal") para ganar siempre,
   sin depender del orden de carga — y "!important" SOLO en las dos propiedades que MudBlazor
   también fuerza con "!important" (z-index, background, y el margin del botón), nunca más de lo
   necesario. */
body #components-reconnect-modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 10000 !important;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.6) !important;
}

#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-retrying,
#components-reconnect-modal.components-reconnect-paused,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-resume-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
}

.vigia-reconexion-dialog {
    background: #fff;
    color: #1a1a1a;
    width: min(90vw, 26rem);
    padding: 2rem 1.75rem;
    border-radius: 0.75rem;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
    font-size: 1.15rem;
    line-height: 1.4;
}

.vigia-reconexion-spinner {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border: 5px solid #d8e6f5;
    border-top-color: #1b6ec2;
    animation: vigia-reconexion-girar 0.9s linear infinite;
}

/* En el estado terminal ya no se está reintentando nada: ocultar el spinner para no dar a
   entender que la app sigue trabajando cuando en realidad ya se ha rendido. */
#components-reconnect-modal.components-reconnect-failed .vigia-reconexion-spinner,
#components-reconnect-modal.components-reconnect-resume-failed .vigia-reconexion-spinner,
#components-reconnect-modal.components-reconnect-rejected .vigia-reconexion-spinner {
    display: none;
}

@keyframes vigia-reconexion-girar {
    to { transform: rotate(360deg); }
}

/* Mensajes: ocultos por defecto, cada uno se muestra solo bajo la clase que le corresponde.
   "show" y "retrying" pueden coexistir (Blazor añade "retrying" sin quitar "show" al pasar del
   1er al 2º intento) — con :not() no hace falta depender del orden de las reglas en la hoja. */
.vigia-reconexion-msg { display: none; }

#components-reconnect-modal.components-reconnect-show:not(.components-reconnect-retrying)
    .vigia-reconexion-msg-reconectando {
    display: block;
}

#components-reconnect-modal.components-reconnect-retrying .vigia-reconexion-msg-reintentando,
#components-reconnect-modal.components-reconnect-paused .vigia-reconexion-msg-reintentando {
    display: block;
}

#components-reconnect-modal.components-reconnect-failed .vigia-reconexion-msg-terminal,
#components-reconnect-modal.components-reconnect-resume-failed .vigia-reconexion-msg-terminal,
#components-reconnect-modal.components-reconnect-rejected .vigia-reconexion-msg-terminal {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

.vigia-reconexion-contador {
    display: block;
    margin-top: 0.5rem;
    font-size: 0.95rem;
    color: #555;
}

/* Acción crítica del estado sin salida: SIEMPRE grande (≥64px, guante/sol — mismo estándar
   MIL-STD-1472 que el resto de la fase táctil), SIEMPRE visible en los tres estados terminales.
   Selector anidado bajo "#components-reconnect-modal" (no solo la clase) para ganar en
   especificidad a "#components-reconnect-modal button" de MudBlazor.min.css (mismo motivo que el
   comentario de arriba) — así no hace falta "!important" salvo en "margin", la única propiedad
   que MudBlazor también fuerza con "!important" ahí. */
#components-reconnect-modal .vigia-reconexion-boton-volver {
    min-height: 64px;
    min-width: 240px;
    padding: 0 32px;
    margin: 0 !important;
    font-size: 1.1rem;
    font-weight: 600;
    text-transform: none;
    letter-spacing: normal;
    color: #fff;
    background-color: #1b6ec2;
    border: 0;
    border-radius: 0.5rem;
    cursor: pointer;
}

#components-reconnect-modal .vigia-reconexion-boton-volver:hover,
#components-reconnect-modal .vigia-reconexion-boton-volver:focus-visible {
    background-color: #15579c;
}
