/* wwwroot/css/anb-theme.css */
:root {
    /* Estado: ESTABLE (Verde) */
    --anb-status-ok-bg-light: #e8f5e9;
    --anb-status-ok-text-light: #1b5e20;
    --anb-status-ok-bg-dark: #1b3a1b;
    --anb-status-ok-text-dark: #81c784;

    /* Estado: ADVERTENCIA (Amarillo) */
    --anb-status-warning-bg-light: #fff3e0;
    --anb-status-warning-text-light: #e65100;
    --anb-status-warning-bg-dark: #4a3a2a;
    --anb-status-warning-text-dark: #ffb74d;

    /* Estado: PELIGRO (Rojo) */
    --anb-status-danger-bg-light: #ffebee;
    --anb-status-danger-text-light: #b71c1c;
    --anb-status-danger-bg-dark: #3a1f1f;
    --anb-status-danger-text-dark: #ef5350;

	/* Variables Base - Light Mode */
    --anb-gauge-info-light: #3B82F6;    /* Azul fuerte */
    --anb-gauge-ok-light: #10B981;      /* Verde fuerte */
    --anb-gauge-warning-light: #F59E0B; /* Naranja/Amarillo fuerte */
    --anb-gauge-danger-light: #EF4444;  /* Rojo fuerte */
    --anb-gauge-text-light: #333333;    /* Texto oscuro */

    /* Variables Base - Dark Mode (ligeramente más claros/brillantes para resaltar en fondo negro) */
    --anb-gauge-info-dark: #60A5FA;
    --anb-gauge-ok-dark: #34D399;
    --anb-gauge-warning-dark: #FBBF24;
    --anb-gauge-danger-dark: #F87171;
    --anb-gauge-text-dark: #cccccc;     /* Texto claro */

    /* Variables Asignadas (Modo Claro por defecto) */
    --anb-status-ok-bg: var(--anb-status-ok-bg-light);
    --anb-status-ok-text: var(--anb-status-ok-text-light);
    --anb-status-warning-bg: var(--anb-status-warning-bg-light);
    --anb-status-warning-text: var(--anb-status-warning-text-light);
    --anb-status-danger-bg: var(--anb-status-danger-bg-light);
    --anb-status-danger-text: var(--anb-status-danger-text-light);
    --anb-gauge-text: var(--anb-gauge-text-light);
	--anb-gauge-info: var(--anb-gauge-info-light);
    --anb-gauge-ok: var(--anb-gauge-ok-light);
    --anb-gauge-warning: var(--anb-gauge-warning-light);
    --anb-gauge-danger: var(--anb-gauge-danger-light);
}

/* ═══════════════════════════════════════════════════════════════════════════
   ANB PALETTE — wrapper sobre la paleta completa de MudBlazor
   Las var(--mud-palette-*) ya cambian automáticamente en dark mode.
   Tener las var(--anb-palette-*) como punto de entrada propio permite
   sobreescribirlas independientemente si se necesita en el futuro.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
    /* ── Colores de marca ───────────────────────────────────────── */
    --anb-palette-primary:              var(--mud-palette-primary);
    --anb-palette-primary-rgb:          var(--mud-palette-primary-rgb);
    --anb-palette-primary-text:         var(--mud-palette-primary-text);
    --anb-palette-primary-darken:       var(--mud-palette-primary-darken);
    --anb-palette-primary-lighten:      var(--mud-palette-primary-lighten);
    --anb-palette-primary-hover:        var(--mud-palette-primary-hover);

    --anb-palette-secondary:            var(--mud-palette-secondary);
    --anb-palette-secondary-rgb:        var(--mud-palette-secondary-rgb);
    --anb-palette-secondary-text:       var(--mud-palette-secondary-text);
    --anb-palette-secondary-darken:     var(--mud-palette-secondary-darken);
    --anb-palette-secondary-lighten:    var(--mud-palette-secondary-lighten);
    --anb-palette-secondary-hover:      var(--mud-palette-secondary-hover);

    --anb-palette-tertiary:             var(--mud-palette-tertiary);
    --anb-palette-tertiary-rgb:         var(--mud-palette-tertiary-rgb);
    --anb-palette-tertiary-text:        var(--mud-palette-tertiary-text);
    --anb-palette-tertiary-darken:      var(--mud-palette-tertiary-darken);
    --anb-palette-tertiary-lighten:     var(--mud-palette-tertiary-lighten);
    --anb-palette-tertiary-hover:       var(--mud-palette-tertiary-hover);

    /* ── Colores semánticos ─────────────────────────────────────── */
    --anb-palette-info:                 var(--mud-palette-info);
    --anb-palette-info-text:            var(--mud-palette-info-text);
    --anb-palette-info-darken:          var(--mud-palette-info-darken);
    --anb-palette-info-lighten:         var(--mud-palette-info-lighten);

    --anb-palette-success:              var(--mud-palette-success);
    --anb-palette-success-text:         var(--mud-palette-success-text);
    --anb-palette-success-darken:       var(--mud-palette-success-darken);
    --anb-palette-success-lighten:      var(--mud-palette-success-lighten);

    --anb-palette-warning:              var(--mud-palette-warning);
    --anb-palette-warning-text:         var(--mud-palette-warning-text);
    --anb-palette-warning-darken:       var(--mud-palette-warning-darken);
    --anb-palette-warning-lighten:      var(--mud-palette-warning-lighten);

    --anb-palette-error:                var(--mud-palette-error);
    --anb-palette-error-text:           var(--mud-palette-error-text);
    --anb-palette-error-darken:         var(--mud-palette-error-darken);
    --anb-palette-error-lighten:        var(--mud-palette-error-lighten);

    --anb-palette-dark:                 var(--mud-palette-dark);
    --anb-palette-dark-text:            var(--mud-palette-dark-text);
    --anb-palette-dark-darken:          var(--mud-palette-dark-darken);
    --anb-palette-dark-lighten:         var(--mud-palette-dark-lighten);

    /* ── Texto & acciones ───────────────────────────────────────── */
    --anb-palette-text-primary:         var(--mud-palette-text-primary);
    --anb-palette-text-secondary:       var(--mud-palette-text-secondary);
    --anb-palette-text-disabled:        var(--mud-palette-text-disabled);
    --anb-palette-action-default:       var(--mud-palette-action-default);
    --anb-palette-action-hover:         var(--mud-palette-action-default-hover);
    --anb-palette-action-disabled:      var(--mud-palette-action-disabled);

    /* ── Superficies & fondos ───────────────────────────────────── */
    --anb-palette-surface:              var(--mud-palette-surface);
    --anb-palette-background:           var(--mud-palette-background);
    --anb-palette-background-gray:      var(--mud-palette-background-gray);

    /* ── Elementos UI ───────────────────────────────────────────── */
    --anb-palette-drawer-background:    var(--mud-palette-drawer-background);
    --anb-palette-drawer-text:          var(--mud-palette-drawer-text);
    --anb-palette-drawer-icon:          var(--mud-palette-drawer-icon);
    --anb-palette-appbar-background:    var(--mud-palette-appbar-background);
    --anb-palette-appbar-text:          var(--mud-palette-appbar-text);
    --anb-palette-divider:              var(--mud-palette-divider);
    --anb-palette-divider-light:        var(--mud-palette-divider-light);
    --anb-palette-lines-default:        var(--mud-palette-lines-default);
    --anb-palette-lines-inputs:         var(--mud-palette-lines-inputs);
    --anb-palette-table-lines:          var(--mud-palette-table-lines);
    --anb-palette-table-striped:        var(--mud-palette-table-striped);
    --anb-palette-table-hover:          var(--mud-palette-table-hover);
    --anb-palette-tooltip-background:   var(--mud-palette-tooltip-background);
    --anb-palette-overlay-dark:         var(--mud-palette-overlay-dark);
    --anb-palette-overlay-light:        var(--mud-palette-overlay-light);
}

/* MudBlazor inyecta esta clase cuando activas el Dark Mode */
.mud-palette-dark {
    /* ── Status & gauge (ya existentes) ─────────────────────────── */
    --anb-status-ok-bg: var(--anb-status-ok-bg-dark);
    --anb-status-ok-text: var(--anb-status-ok-text-dark);
    --anb-status-warning-bg: var(--anb-status-warning-bg-dark);
    --anb-status-warning-text: var(--anb-status-warning-text-dark);
    --anb-status-danger-bg: var(--anb-status-danger-bg-dark);
    --anb-status-danger-text: var(--anb-status-danger-text-dark);
    --anb-gauge-text: var(--anb-gauge-text-dark);
    --anb-gauge-info: var(--anb-gauge-info-dark);
    --anb-gauge-ok: var(--anb-gauge-ok-dark);
    --anb-gauge-warning: var(--anb-gauge-warning-dark);
    --anb-gauge-danger: var(--anb-gauge-danger-dark);

    /* ── ANB Palette override hook en dark mode ──────────────────
       Aquí las ANB apuntan a las mismas MudBlazor (que ya son dark).
       Si en el futuro se quiere un color ANB distinto al de MudBlazor
       en dark mode, basta con cambiar el valor aquí. */
    --anb-palette-primary:              var(--mud-palette-primary);
    --anb-palette-primary-rgb:          var(--mud-palette-primary-rgb);
    --anb-palette-primary-text:         var(--mud-palette-primary-text);
    --anb-palette-primary-darken:       var(--mud-palette-primary-darken);
    --anb-palette-primary-lighten:      var(--mud-palette-primary-lighten);
    --anb-palette-primary-hover:        var(--mud-palette-primary-hover);

    --anb-palette-secondary:            var(--mud-palette-secondary);
    --anb-palette-secondary-text:       var(--mud-palette-secondary-text);
    --anb-palette-secondary-darken:     var(--mud-palette-secondary-darken);
    --anb-palette-secondary-lighten:    var(--mud-palette-secondary-lighten);

    --anb-palette-tertiary:             var(--mud-palette-tertiary);
    --anb-palette-tertiary-text:        var(--mud-palette-tertiary-text);
    --anb-palette-tertiary-darken:      var(--mud-palette-tertiary-darken);
    --anb-palette-tertiary-lighten:     var(--mud-palette-tertiary-lighten);

    --anb-palette-info:                 var(--mud-palette-info);
    --anb-palette-info-text:            var(--mud-palette-info-text);
    --anb-palette-success:              var(--mud-palette-success);
    --anb-palette-success-text:         var(--mud-palette-success-text);
    --anb-palette-warning:              var(--mud-palette-warning);
    --anb-palette-warning-text:         var(--mud-palette-warning-text);
    --anb-palette-error:                var(--mud-palette-error);
    --anb-palette-error-text:           var(--mud-palette-error-text);
    --anb-palette-dark:                 var(--mud-palette-dark);
    --anb-palette-dark-text:            var(--mud-palette-dark-text);

    --anb-palette-text-primary:         var(--mud-palette-text-primary);
    --anb-palette-text-secondary:       var(--mud-palette-text-secondary);
    --anb-palette-text-disabled:        var(--mud-palette-text-disabled);
    --anb-palette-action-default:       var(--mud-palette-action-default);
    --anb-palette-action-hover:         var(--mud-palette-action-default-hover);

    --anb-palette-surface:              var(--mud-palette-surface);
    --anb-palette-background:           var(--mud-palette-background);
    --anb-palette-background-gray:      var(--mud-palette-background-gray);

    --anb-palette-drawer-background:    var(--mud-palette-drawer-background);
    --anb-palette-drawer-text:          var(--mud-palette-drawer-text);
    --anb-palette-drawer-icon:          var(--mud-palette-drawer-icon);
    --anb-palette-appbar-background:    var(--mud-palette-appbar-background);
    --anb-palette-divider:              var(--mud-palette-divider);
    --anb-palette-divider-light:        var(--mud-palette-divider-light);
    --anb-palette-lines-inputs:         var(--mud-palette-lines-inputs);
    --anb-palette-table-lines:          var(--mud-palette-table-lines);
    --anb-palette-table-hover:          var(--mud-palette-table-hover);
}


/* ═══════════════════════════════════════════════════════════════════════════
   CLASES PARA REGISTROS (formularios, diálogos)
   ═══════════════════════════════════════════════════════════════════════════ */

.anb-registro-paper {
    background-color: var(--anb-palette-surface);
    border: 1px solid var(--anb-palette-divider);
    border-radius: 8px;
    padding: 12px;
}

.anb-registro-paper-primary {
    background-color: var(--anb-palette-surface);
    border: 1px solid var(--anb-palette-primary);
    border-radius: 8px;
    padding: 12px;
}

.anb-label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--anb-palette-text-secondary);
    margin-bottom: 2px;
    letter-spacing: 0.02em;
}

/* Header del diálogo con fondo primario */
.anb-registro-header {
    background-color: var(--anb-palette-primary);
    color: var(--anb-palette-primary-text);
    padding: 8px 16px;
    border-radius: 4px 4px 0 0;
}

.anb-registro-header * {
    color: var(--anb-palette-primary-text) !important;
}

/* Footer del diálogo con fondo secundario */
.anb-registro-footer {
    background-color: var(--anb-palette-secondary);
    color: var(--anb-palette-secondary-text);
    padding: 8px 16px;
    border-radius: 0 0 4px 4px;
}

.anb-registro-footer * {
    color: var(--anb-palette-secondary-text) !important;
}

.anb-input-outline.e-input-group,
.anb-input-outline.e-control-wrapper {
    border: 1px solid var(--anb-palette-lines-inputs) !important;
    border-radius: 4px !important;
    background-color: var(--anb-palette-surface) !important;
}
.anb-input-outline.e-input-group:hover,
.anb-input-outline.e-control-wrapper:hover {
    border-color: var(--anb-palette-primary) !important;
}
.anb-input-outline.e-input-group.e-input-focus,
.anb-input-outline.e-control-wrapper.e-input-focus {
    border-color: var(--anb-palette-primary) !important;
    box-shadow: 0 0 0 2px var(--anb-palette-primary-hover) !important;
}

/* Misma clase, ahora también para MudAutocomplete/MudTextField Variant.Outlined (los antiguos
   SfDropDownList migrados, ver .claude/memory/patron-dropdown-mudautocomplete.md) — un formulario
   con Sf y Mud mezclados no debe sentirse inconsistente. Selectores confirmados por reflexión del
   DLL/CSS real de MudBlazor 9.2.0 instalado (MudBlazor.min.css), no adivinados:
   - `.mud-input-outlined` (el wrapper) NO trae background por diseño (Outlined de Material es solo
     borde) — se le agrega aquí, sin !important porque MudBlazor no define nada ahí (nada que ganar).
   - `.mud-input-outlined-border` sí trae color de borde propio (`--mud-palette-lines-inputs`, sin
     themear en esta app → cae al default de MudBlazor, muy tenue) — se sobreescribe SIN !important:
     nuestra regla (2 clases) ya es más específica que la base de MudBlazor (1 clase), pero SIGUE
     perdiendo a propósito contra los estados hover/focus/disabled/error de MudBlazor (3-4+ clases
     cada uno) — si esto llevara !important, el campo "Operador secundario" (que se deshabilita
     condicionalmente) dejaría de verse gris al estar disabled.
   - Alto/tipografía: mismos valores YA confirmados por chun para igualar el alto de Syncfusion en
     `.barra-grid-busqueda-size-small`/`.filtro-fechas-grid-size-small` (ver esas reglas arriba) —
     PRIMER INTENTO sin poder medir en vivo (sesión sin navegador), pendiente que chun confirme con
     captura si el alto ya calza con los SfTextBox/SfNumericTextBox vecinos. */
.anb-input-outline .mud-input-outlined {
    background-color: var(--anb-palette-surface);
    border-radius: 4px;
}
.anb-input-outline .mud-input-outlined-border {
    border-color: var(--anb-palette-lines-inputs);
}
.anb-input-outline .mud-input-root-margin-dense {
    padding-top: 6px !important;
    padding-bottom: 6px !important;
    font-size: .875rem;
}


/* ═══════════════════════════════════════════════════════════════
   MudDialog — clase anb-registro-dialog
   Uso: <MudDialog Class="anb-registro-dialog" Style="max-width:min(NNNpx,95vw)" ...>
   El ancho NO va aquí (cada diálogo trae el suyo, calcado de su SfDialog Width
   original) — esta clase solo estiliza el header (primario) y footer
   (secundario) usando los hooks internos de MudBlazor (.mud-dialog-title,
   .mud-dialog-actions) y las variables ANB del anb-theme.css.
   ═══════════════════════════════════════════════════════════════ */
.anb-registro-dialog.mud-dialog {
    width: 100%;
}

.anb-registro-dialog .mud-dialog-title {
	min-height: 50px;
    background-color: color-mix(in srgb, var(--anb-palette-primary) 75%, rgb(5, 58, 32));
    color: var(--anb-palette-primary-text);
}

.anb-registro-dialog .mud-dialog-title *,
.anb-registro-dialog .mud-dialog-title .mud-icon-button {
    color: var(--anb-palette-primary-text) !important;
}

.anb-registro-dialog .mud-dialog-content {
    background-color: color-mix(in srgb, var(--anb-palette-primary) 5%, transparent);
}

.anb-registro-dialog .mud-dialog-actions {
	min-height: 50px;
    background-color: color-mix(in srgb, var(--anb-palette-secondary) 20%, transparent);
    color: var(--anb-palette-primary-text);
}

.anb-registro-dialog .mud-dialog-actions * {
    color: var(--anb-palette-primary-text) !important;
}
/* ─────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════
   MudMenu — anb-appbar-menu
   Pinta el dropdown del menú de usuario con el color del AppBar/NavMenu.
   Uso: <MudMenu PopoverClass="anb-appbar-menu">
   ═══════════════════════════════════════════════════════════════ */
.anb-appbar-menu {
    background-color: var(--mud-palette-appbar-background) !important;
    color: var(--mud-palette-appbar-text) !important;
}
.anb-appbar-menu * {
    color: var(--mud-palette-appbar-text) !important;
}
.anb-appbar-menu .mud-list-item:hover {
    background-color: rgba(255,255,255,0.12) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LAYOUT TELEMETRÍA — gráfica + grid (Snapshots, Records, Histórico)
   En landscape mobile: side-by-side. Portrait/desktop: vertical.
   ═══════════════════════════════════════════════════════════════════════════ */
.anb-snap-grafica-col,
.anb-rec-grafica-col,
.anb-hist-grafica-col { width: 100%; }

.anb-snap-grid-col,
.anb-rec-grid-col,
.anb-hist-grid-col    { width: 100%; }

@media (orientation: landscape) and (max-height: 530px) {
    .anb-snap-wrapper,
    .anb-rec-wrapper,
    .anb-hist-wrapper {
        display: flex;
        height: calc(100vh - 56px);
        overflow: hidden;
    }

    .anb-snap-grafica-col,
    .anb-rec-grafica-col,
    .anb-hist-grafica-col {
        width: 45%;
        height: 100%;
        flex-shrink: 0;
    }

    .anb-snap-grafica-col > div,
    .anb-rec-grafica-col  > div,
    .anb-hist-grafica-col > div {
        height: 100%;
        margin: 0 !important;
    }

    .anb-snap-grafica-col .mud-paper,
    .anb-rec-grafica-col  .mud-paper,
    .anb-hist-grafica-col .mud-paper {
        height: 100% !important;
    }

    .anb-snap-grid-col,
    .anb-rec-grid-col,
    .anb-hist-grid-col {
        flex: 1;
        height: 100%;
        min-width: 0;
        overflow: hidden;
    }

    .anb-snap-grid-col > .mud-paper,
    .anb-rec-grid-col  > .mud-paper,
    .anb-hist-grid-col > .mud-paper {
        height: 100% !important;
        margin-top: 0 !important;
    }
}

/* Tooltip de ayuda en FormField */
.anb-help-tooltip.e-tooltip-wrap {
    max-width: 320px !important;
}
.anb-help-tooltip.e-tooltip-wrap .e-tip-content {
    white-space: normal !important;
    word-break: normal !important;
    line-height: 1.5 !important;
}

/* ===========================================================================
   Patrón de grid homologado (BarraGrid/EncabezadosGrid/FiltrosGrid<T>), portado
   de plantilladotnet — Fase 6 del Plan A. */

/* MudBlazor por defecto QUITA el border-bottom de la última fila de CUALQUIER
   MudTable (regla propia del paquete: `.mud-table-root>.mud-table-body:last-child>
   .mud-table-row:last-child>.mud-table-cell{border-bottom:none}`, confirmada leyendo
   MudBlazor.min.css 9.2.0). Syncfusion sí dibujaba esa línea, por eso el cuerpo de la
   tabla se veía "cortado" al final. Se restaura para TODOS los MudTable de la app
   (no solo los del grid homologado), con la misma variable de color que usa el resto
   de líneas de la tabla para que quede consistente. */
.mud-table-root > .mud-table-body:last-child > .mud-table-row:last-child > .mud-table-cell {
    border-bottom: 1px solid var(--mud-palette-table-lines);
}

.barra-grid {
    display: grid;
    /* minmax(0,1fr): sin el 0, la zona con contenido ancho (p. ej. el botón "Nuevo") no
       puede encogerse por debajo de su contenido y empuja la búsqueda fuera del centro. */
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: .75rem;
}
.barra-grid-zona {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
}
.barra-grid-der {
    justify-content: flex-end;
}
.barra-grid-busqueda {
    min-width: 280px;
    max-width: 380px;
}

/* Overlay de la búsqueda colapsada en móvil (BarraGrid.razor, `_isMobile && _busquedaExpandida`):
   CORRECCIÓN 2026-07-09 — el primer intento usaba `position:absolute; inset:0` confiando en que
   el `MudPaper` (que ya es `position:relative` por defecto) fuera el contenedor de referencia;
   en la práctica terminó cubriendo una caja mucho más alta que la barra (chun: "no seguiste la
   misma forma... donde al darle click solo sale el input cubriendo solo el espacio de la barra").
   Se volvió al patrón YA probado de `ToolbarBusqueda.razor` (Syncfusion): medir el rect real de
   `.barra-grid` con IJSRuntime y pintar el overlay con `position:fixed` + top/height EXACTOS (ver
   `_overlayStyle` en BarraGrid.razor) — cero ambigüedad de contenedor. Esta clase solo pone lo que
   NO cambia (layout interno); la posición/tamaño va inline porque depende de la medición. */
.barra-grid-busqueda-overlay {
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: 0 .75rem;
    background: var(--mud-palette-surface);
    box-shadow: 0 2px 6px rgba(0, 0, 0, .25);
}

@media (max-width: 960px) {
    /* CORRECCIÓN 2026-07-09: forzar `grid-template-columns: 1fr` apilaba las 3 zonas SIEMPRE,
       aunque cupieran perfectamente en una sola línea con la búsqueda ya colapsada a ícono
       (chun: "en modo celular hace salto para los botones... si no llegasen entrar que si haya
       salto de línea, pero si entran no deberían estar uno sobre otro"). Flex+wrap da justo eso:
       una sola línea si alcanza, salto de línea SOLO si no alcanza, nunca superpuestos. Se pierde
       el centrado perfecto de grid en este punto, pero ya no hace falta — en móvil la búsqueda es
       un ícono chico, no la caja de texto que necesitaba quedar clavada al centro. */
    .barra-grid {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
    }
    /* CORRECCIÓN 2026-07-09 (LogActividades, primer grid con varios botones a la izquierda):
       sin flex-shrink:0, el flex de afuera podía comprimir una zona por debajo del ancho de su
       propio contenido — y esa zona, ya apretada, terminaba partiendo SUS PROPIOS botones en
       otra línea (el ícono de fecha quedaba solo, lejos de la lupa). Con flex-shrink:0 + nowrap,
       cada zona es una unidad atómica: o cabe completa en la línea, o salta ENTERA a la
       siguiente — nunca se parte sola por dentro. */
    .barra-grid-zona {
        flex-wrap: nowrap;
        flex-shrink: 0;
    }
    .barra-grid-busqueda {
        max-width: none;
    }
    .barra-grid-der {
        justify-content: flex-start;
    }
}

/* Trunca automáticamente TODA celda del CUERPO de la tabla (no el encabezado) a una sola línea
   con "…" cuando el ancho de columna no alcanza — CORREGIDO 2026-07-10 (chun: "por qué cada
   columna le pones grid-celda-truncada, no debería ser una configuración general del MudTable...
   quiero que toda la tabla en sí pueda tener su función o clase general"). Ya NO hace falta
   ningún <span class="grid-celda-truncada"> por columna en el RowTemplate: basta con que el
   <MudTable> tenga la clase `grid-compacto` (ya estándar en todos los grids migrados) para que
   CUALQUIER celda de texto libre trunque sola. Sin ningún ancho real en esa columna (ni `Ancho`
   de `ColumnaGrid<T>` ni resize a mano), este `overflow:hidden` no tiene nada que recortar — la
   columna sigue creciendo para caber en una línea, como siempre ("siempre compacto", nunca salto
   de línea). Necesario también para que TODAS las filas midan lo mismo cuando el MudTable usa
   Virtualize (asume una altura fija por fila vía ItemSize; con texto libre que se envuelve en 2-3
   líneas o un JSON largo sin acortar, la altura real varía fila a fila y la virtualización
   "brinca"). Equivalente a ClipMode.EllipsisWithTooltip de Syncfusion, que sí traían las páginas
   migradas de ahí. Alcance a `.mud-table-body` a propósito (no `.mud-table-head`): el encabezado
   trae su propio ícono de filtro/menú, forzar overflow:hidden ahí podría tapar ese ícono en
   columnas angostas. */
.grid-compacto .mud-table-body .mud-table-cell {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Fila seleccionada (MudTable.SelectedItem + RowClassFunc en la página, ver Astronics.razor):
   MudTable NO resalta nada solo cuando seleccionas una fila — confirmado en el código fuente de
   MudTr, la selección solo cambia el modelo, el estilo hay que pintarlo a mano. Franja a la
   izquierda + fondo tenue del color primario, mismo espíritu visual que Syncfusion. */
.grid-fila-seleccionada > td {
    background-color: color-mix(in srgb, var(--mud-palette-primary) 12%, transparent) !important;
    box-shadow: inset 3px 0 0 0 var(--mud-palette-primary);
}

/* Grid a TODO el alto disponible, con scroll propio (vertical Y horizontal) contenido a la
   tabla — copiado de plantilladotnet (Plantilla.blazorwasm/wwwroot/css/app.css), que llega a
   esto con un `calc(100vh - Xpx)` DIRECTO en `.mud-table-container`, sin pasar por ningún
   ancestro con height:100%/flex (eso fue justo lo que falló: PageGridContainer + Height="100%"
   necesitaban que el alto se resolviera en cada nivel intermedio, y no se resolvía — de ahí el
   doble scroll que reportó chun, la página entera se movía junto con la barra).
   CONFIGURABLE POR PÁGINA (chun, 2026-07-09: "no es modificable como yo lo tenía en
   PageGridContainer.razor, qué mal") — la variable CSS `--grid-alto-offset` reemplaza al
   parámetro `Offset` que tenía `PageGridContainer`, con el MISMO espíritu (cada página pone su
   propio número sin tocar este archivo), pero sin volver al mecanismo que causaba el doble-scroll
   (el problema nunca fue "que fuera configurable", fue CÓMO se resolvía el alto — por flex/%
   en vez de un calc() directo aquí). Se usa así en cada página:
     <MudTable Class="grid-lleno ..." Style="--grid-alto-offset: 130px;">
   Sin la variable, cae al default (130px). Depende de: alto del MudAppBar (64px default) +
   padding de MudMainContent + alto de BarraGrid (varía con su Tamano) + márgenes — por eso NO hay
   un número universal, cada página lo mide/ajusta según su propio BarraGrid (Tamano, si trae
   FiltroFecha, etc.), igual que ya advertía la plantilla sobre su propio 230px. */
.grid-lleno .mud-table-container {
    height: calc(100vh - var(--grid-alto-offset, 130px));
    height: calc(100dvh - var(--grid-alto-offset, 130px));
    min-height: 240px;
}

/* CORRECCIÓN 2026-07-09 #9 — el encabezado (filtros de columna) seguía sin quedarse fijo con
   FixedHeader="true" pese a que MudBlazor debería resolverlo solo, incluso QUITANDO Virtualize
   (se probó y descartó como causa). Un motivo clásico de que `position:sticky` en un <th> no
   funcione: `border-collapse:collapse` en la tabla (Bootstrap lo pone globalmente en TODO
   <table> — `table{border-collapse:collapse}` en bootstrap.min.css, cargado antes que
   MudBlazor). MudBlazor SÍ trae su propia regla para contrarrestarlo
   (`.mud-table-sticky-header * table{border-collapse:separate}`), pero se refuerza aquí con
   !important para blindarlo de cualquier otra hoja de estilos que se cargue después, y se repite
   position:sticky+top:0+z-index+fondo opaco por si acaso — sin fondo opaco, un header "sticky"
   se ve transparente y las filas se alcanzan a ver detrás, dando la impresión de que no está
   fijo aunque técnicamente sí lo esté. */
.grid-lleno .mud-table-container table {
    border-collapse: separate !important;
}
.grid-lleno .mud-table-head .mud-table-cell {
    position: sticky !important;
    top: 0 !important;
    z-index: 3 !important;
    background-color: var(--mud-palette-surface) !important;
}

/* Filtro de fechas de escritorio (FiltroFechasGrid), junto al buscador en el slot FiltroFecha de
   BarraGrid. CORRECCIÓN 2026-07-09 #2: no bastaba con quitar el Label — sin las clases de Tamano
   quedaba "gordo" (más alto) que el buscador y sin tope de ancho. MISMOS selectores y valores que
   `.barra-grid-busqueda-size-*` de arriba, porque `MudRangeInput` (lo que usa MudDateRangePicker
   por dentro) comparte el mismo `MudInputCssHelper` que un MudTextField normal — confirmado en el
   código fuente de MudBlazor, no adivinado. */
.filtro-fechas-grid {
    max-width: 300px;
    flex-shrink: 1;
}
.filtro-fechas-grid-size-small .mud-input-root-margin-dense {
    padding-top: 6px !important;
    padding-bottom: 6px !important;
    font-size: .8125rem;
}
.filtro-fechas-grid-size-small .mud-input-adornment-start .mud-icon-root {
    font-size: 1.25rem;
}
.filtro-fechas-grid-size-medium .mud-input-adornment-start .mud-icon-root {
    font-size: 1.5rem;
}
.filtro-fechas-grid-size-large .mud-input-root-margin-dense {
    padding-top: 15px !important;
    padding-bottom: 15px !important;
    font-size: 1rem;
}
.filtro-fechas-grid-size-large .mud-input-adornment-start .mud-icon-root {
    font-size: 1.875rem;
}

/* Calendario móvil de FiltroFechasGrid — CORRECCIÓN 2026-07-09 #6: reemplaza el intento con
   MudMenu (nunca mostró nada en la prueba real, ver el comentario del .razor). Modal simple,
   centrado en pantalla, sin medir nada — el fondo oscuro cierra al tocar fuera. */
.filtro-fechas-fondo {
    position: fixed;
    inset: 0;
    z-index: 1999;
    background: rgba(0, 0, 0, .5);
}
.filtro-fechas-overlay {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 2000;
    background: var(--mud-palette-surface);
    border-radius: var(--mud-default-borderradius);
    box-shadow: 0 4px 16px rgba(0, 0, 0, .35);
    padding: .5rem;
}

/* Filtro embebido en el encabezado de columna (FiltroColumna): campo de texto + chevron con
   los valores distintos. Compacto, tipografía de encabezado y sin ensanchar la columna más
   allá de su contenido. */
.filtro-columna {
    display: flex;
    align-items: center;
    gap: 2px;
    min-width: 90px;
}
.filtro-columna .filtro-columna-texto {
    margin-top: 0;
    flex: 1 1 auto;
}
.filtro-columna .mud-input {
    font-size: .875rem;
    font-weight: 500;
}

/* Encabezados de columna en MODO LIMPIO (parámetro Limpio de FiltroColumna/FiltroColumnaFecha/
   EncabezadosGrid): el título va en versalitas y el filtro vive en el desplegable. */
.filtro-limpio-titulo {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    font-size: .72rem;
    font-weight: 700;
    white-space: nowrap;
    cursor: pointer;
}
.filtro-limpio-titulo .mud-icon-root {
    opacity: .4;
}
.filtro-limpio-activo {
    color: var(--mud-palette-primary);
}
.filtro-limpio-activo .mud-icon-root {
    opacity: 1;
}
.filtro-limpio-plano {
    cursor: default;
}

/* Asa de redimensionado de columnas (la instala wwwroot/js/estado-grid.js en los th[data-col]):
   franja invisible en el borde derecho del encabezado con cursor col-resize.
   CORRECCIÓN 2026-07-10 (LogActividades: "las columnas no se pueden cambiar el tamaño"): el fix
   del header fijo (anb-theme.css, `.grid-lleno .mud-table-head .mud-table-cell{z-index:3
   !important}`) hace que TODOS los <th> compartan ese mismo z-index — en ese empate, el <th>
   SIGUIENTE en el DOM pinta encima del anterior, tapando la franja de 6px del borde derecho
   (justo donde vive esta asa) y el mouse ya no le llega. z-index más alto que el del <th> para
   que la asa SIEMPRE reciba el click, sin importar el <th> vecino. */
.grid-redim {
    position: absolute;
    top: 0;
    right: 0;
    width: 6px;
    height: 100%;
    cursor: col-resize;
    user-select: none;
    z-index: 10;
}
.grid-redim:hover {
    background: var(--mud-palette-primary);
    opacity: .35;
}

/* ===========================================================================
   TAMAÑO del grid homologado — pedido por chun (2026-07-08): un solo `Size`
   (parámetro `Tamano` de BarraGrid) gobierna botones agrupados, ícono de
   búsqueda Y el alto del input de búsqueda, para que los tres queden
   consistentes entre sí (antes el input tenía su propio "modo compacto"
   desconectado de los botones, y no cuadraba con ellos).
   - Size.Medium (default) = tamaño "cómodo" original de la plantilla, sin
     ninguna clase de aquí abajo — el desarrollador que no toque `Tamano` no
     pierde nada.
   - Size.Small = tamaño que tenía la barra de Syncfusion.
   - Size.Large disponible por completitud (poco usado hoy).
   `.grid-compacto` es aparte (va en el `Class` del propio `MudTable`, no de
   BarraGrid) porque afecta las FILAS de la tabla, no la barra — una página
   puede combinar cualquier tamaño de barra con filas compactas o no.
   Si el resultado gusta, esto es candidato a cosecharse a plantilladotnet como
   una variante oficial del patrón (ver Paso 5 de la skill cerrar-slice).
   =========================================================================== */

/* Parte 1: la BARRA en Size.Small/Large — menos/más aire entre zonas
   (Size.Medium no agrega clase, se queda con el gap de .barra-grid-zona de arriba). */
.barra-grid-size-small {
    gap: .4rem;
}
.barra-grid-size-small .barra-grid-zona {
    gap: .25rem;
}
.barra-grid-size-large {
    gap: 1rem;
}
.barra-grid-size-large .barra-grid-zona {
    gap: .75rem;
}

/* Parte 2: la CAJA DE BÚSQUEDA — el ANCHO se queda igual siempre
   (.barra-grid-busqueda, arriba); lo que cambia por tamaño es el ALTO del
   input (padding vertical) y el tamaño del ícono/texto, para calzar con el
   alto real de los botones Small/Medium/Large de MudBlazor en esa fila.
   Selectores confirmados contra MudBlazor.min.css instalado (variant=Outlined
   + Margin.Dense), no adivinados. */
.barra-grid-busqueda-size-small .mud-input-root-margin-dense {
    padding-top: 6px !important;
    padding-bottom: 6px !important;
    font-size: .8125rem;
}
.barra-grid-busqueda-size-small .mud-input-adornment-start .mud-icon-root {
    font-size: 1.25rem;
}

.barra-grid-busqueda-size-medium .mud-input-adornment-start .mud-icon-root {
    font-size: 1.5rem;
}
/* Size.Medium no toca el padding del input — es el alto "cómodo" que ya trae
   Margin.Dense de por sí; solo se homologa el tamaño del ícono. */

.barra-grid-busqueda-size-large .mud-input-root-margin-dense {
    padding-top: 15px !important;
    padding-bottom: 15px !important;
    font-size: 1rem;
}
.barra-grid-busqueda-size-large .mud-input-adornment-start .mud-icon-root {
    font-size: 1.875rem;
}

/* Parte 3: las FILAS de la tabla (`<MudTable Class="grid-compacto">`, independiente
   del Tamano de la barra). Va MÁS allá del `Dense` propio de MudBlazor: encoge
   también el padding vertical de encabezados y celdas.
   OJO especificidad: MudBlazor ya trae `.mud-table-dense * .mud-table-row .mud-table-cell`
   (3 clases) para el padding en modo Dense; `.grid-compacto .mud-table-cell` (2 clases)
   pierde ese empate SIEMPRE, sin importar el orden de los <link> — hay que igualar o superar
   las 3 clases agregando `.mud-table-row` a la cadena (confirmado con el inspector, la regla
   de 2 clases queda tachada). */
.grid-compacto .mud-table-row .mud-table-cell {
    padding-top: 2px;
    padding-bottom: 2px;
    font-size: .8125rem;
}
.grid-compacto .mud-table-toolbar {
    padding-top: 2px;
    padding-bottom: 2px;
    min-height: 0;
}

/* ── Tablero Kanban de reportes de bug (Fase 6, portado de plantilladotnet 2026-07-14) ──────
   Columnas coloreadas por estatus (el color se inyecta por variable --kanban-col*, puesta
   inline por columna en ReportesBugPage.razor), tarjetas con franja de prioridad y hover
   elevado. Primer uso de MudDropContainer/MudDropZone en ANBMonitor. */
.kanban-col {
    flex: 1 1 260px;
    min-width: 260px;
    overflow: hidden;
    background-color: var(--kanban-col-suave);
}
.kanban-cabecera {
    border-top: 4px solid var(--kanban-col);
    background-color: var(--kanban-col-media);
}
.kanban-zona {
    /* Mismo criterio de offset medido que .grid-lleno (ver patron-grid-mudtable.md §2) —
       RE-MIDE al clonar o cambiar el chrome de la barra/appbar. */
    min-height: calc(100vh - 230px);
    min-height: calc(100dvh - 230px);
    transition: background-color 0.15s ease;
}
.kanban-destino {
    background-color: var(--kanban-col-media);
    outline: 2px dashed var(--kanban-col);
    outline-offset: -6px;
}
.kanban-vacia::after {
    content: "Sin tarjetas";
    display: block;
    text-align: center;
    padding: 28px 0;
    opacity: 0.45;
    font-size: 0.8rem;
}
.kanban-tarjeta {
    border-left: 3px solid var(--kanban-prio, transparent);
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease;
    background-color: var(--mud-palette-surface);
}
.kanban-tarjeta:hover {
    transform: translateY(-2px);
    box-shadow: var(--mud-elevation-4);
}
.kanban-miniatura {
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: 4px;
    border: 1px solid #00000022;
    flex-shrink: 0;
}

/* Columna colapsada: se angosta a una franja vertical con el título rotado y el contador. */
.kanban-col-colapsada {
    flex: 0 0 48px;
    min-width: 48px;
    max-width: 48px;
    cursor: pointer;
}
.kanban-cabecera-vertical {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 6px 0 14px;
    height: 100%;
    min-height: 220px;
}
.kanban-titulo-vertical {
    writing-mode: vertical-rl;
    font-weight: 600;
    font-size: 0.85rem;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

