/* ===== Pantallas de arranque a pantalla completa =====
   Comparten clase el splash previo a Blazor (el <div id="app"> de cada index.html) y PantallaArranque,
   la pantalla del refresh transparente: las dos se ven igual. */
.app-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    font-family: 'Roboto', system-ui, sans-serif;
    /* Fondo propio: estas pantallas se pintan sin MudThemeProvider y sin él el body hereda el
       color-scheme del navegador (negro en modo oscuro del sistema). Las reservas apuntan al tema
       predeterminado, igual que theme-seed.css. */
    background-color: var(--mud-palette-background, #fafafa);
    color: var(--mud-palette-text-secondary, #6e6e6e);
}

    /* En una pantalla de arranque el indicador no sustituye a ningún contenido: la altura que reserva
       para evitar el salto de layout solo serviría aquí para descentrarlo. */
    .app-loading .gesta-puntos-bloque {
        height: auto;
        min-height: 0;
    }

/* ===== Indicador de carga de tres puntos (lo emite PuntosCarga, Components/Loading) =====
   Global y no CSS aislado a propósito: el splash de index.html pinta estos mismos puntos con HTML escrito
   a mano, antes de que exista Blazor, y ahí no llega el bundle de CSS isolation. Una sola definición cubre
   el splash, la pantalla de recarga y los usos del componente dentro de la app.

   height 100% centra el bloque en el hueco completo cuando el contenedor tiene alto definido (p. ej. el
   cuerpo scrollable de la ficha); si no lo tiene, se resuelve a auto y manda min-height. */
.gesta-puntos-bloque {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    height: 100%;
}

    /* Retardo: una carga más rápida que --gesta-puntos-retardo no llega a pintar los puntos, que en un parpadeo
       molestan más que ayudan. El bloque reserva su altura desde el primer instante: solo se ocultan sus hijos,
       y visibility los saca también del árbol de accesibilidad. Con animation: none (el árbol de la ficha la
       anula entera) salen sin retardo. Las pantallas de arranque no lo llevan: allí no hay carga rápida. */
    .gesta-puntos-bloque > * {
        animation: gesta-puntos-retardo var(--gesta-puntos-retardo, 400ms) steps(1, end);
    }

    .app-loading .gesta-puntos-bloque > * {
        animation: none;
    }

@keyframes gesta-puntos-retardo {
    from {
        visibility: hidden;
    }
}

.gesta-puntos {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--punto-gap);
}

.gesta-punto {
    width: var(--punto-d);
    height: var(--punto-d);
    border-radius: 50%;
    /* Reserva literal (el TextSecondary del tema predeterminado): en las pantallas de arranque aún no hay
       MudThemeProvider montado, el token resolvería a vacío y los puntos saldrían invisibles. */
    background-color: var(--mud-palette-text-secondary, #6e6e6e);
    opacity: .28;
    /* El salto viaja en transform, no en margin/top: se compone en GPU y no refluye la fila. */
    animation: gesta-puntos-pulso 1.4s ease-in-out infinite;
    will-change: transform, opacity;
}

    .gesta-punto:nth-child(2) {
        animation-delay: .16s;
    }

    .gesta-punto:nth-child(3) {
        animation-delay: .32s;
    }

/* Rótulo bajo los puntos; solo lo pinta PuntosCarga con MostrarTexto. Misma reserva de color. */
.gesta-puntos-texto {
    margin: 0;
    font-family: 'Roboto', system-ui, sans-serif;
    font-size: .875rem;
    color: var(--mud-palette-text-secondary, #6e6e6e);
}

/* Opacidad y salto comparten el pico al 40 % del ciclo: un solo gesto, no dos ritmos. */
@keyframes gesta-puntos-pulso {
    0%, 80%, 100% {
        opacity: .28;
        transform: translateY(0);
    }

    40% {
        opacity: 1;
        transform: translateY(calc(-1 * var(--punto-salto)));
    }
}

/* min-height reserva el hueco del contenido que va a sustituir: evita el salto al resolverse. */
.gesta-puntos-s {
    --punto-d: 6px;
    --punto-gap: 6px;
    --punto-salto: 4px;
    min-height: 96px;
}

.gesta-puntos-m {
    --punto-d: 8px;
    --punto-gap: 8px;
    --punto-salto: 5px;
    min-height: 200px;
}

.gesta-puntos-l {
    --punto-d: 10px;
    --punto-gap: 10px;
    --punto-salto: 6px;
    min-height: 320px;
}

@media (prefers-reduced-motion: reduce) {
    .gesta-punto {
        animation: none;
        opacity: .5;
        transform: none;
    }
}

#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 0.75rem 1.25rem;
    background: #ffefef;
    border-top: 1px solid #f5c2c7;
    color: #842029;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        float: right;
    }

/* Accesibilidad */
.skip-link {
    position: absolute;
    top: -40px;
    left: 0;
    background: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    padding: 8px;
    text-decoration: none;
    z-index: 9999;
}

    .skip-link:focus {
        top: 0;
    }

/* Destino del skip-link: un punto de partida para el Tab, sin anillo de foco y sin quedar bajo el AppBar fijo
   al desplazar. */
.gesta-destino-salto {
    display: block;
    scroll-margin-top: var(--mud-appbar-height);
}

    .gesta-destino-salto:focus {
        outline: none;
    }

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ===== Menú lateral / sidebar (temable por las variables --gesta-sidebar-*) =====
   La clase gesta-sidebar va en el MudDrawer del MainLayout; el color del sidebar es propio (distinto del
   DrawerBackground del tema). Las cabeceras de sección y el ítem activo se resaltan con el primary del tema. */
.gesta-sidebar {
    background-color: var(--gesta-sidebar-bg);
    overflow-x: hidden;
    scrollbar-width: thin;
    scrollbar-color: var(--gesta-sidebar-scrollbar) var(--gesta-sidebar-bg);
}

    .gesta-sidebar .mud-nav-link .mud-nav-link-text {
        color: var(--gesta-sidebar-text);
        font-weight: 700;
        white-space: nowrap;
    }

    /* Iconos del menú (ítem, cabecera de grupo y flecha de expandir): MudBlazor los tiñe con
       --mud-palette-drawer-icon, que sigue al tema. Aquí van con el mismo tono que el rótulo
       (--gesta-sidebar-text, casi negro en los cinco temas) para que icono y texto no desentonen. El primer
       selector replica el de MudBlazor (.mud-nav-link-icon-default, que solo está cuando el icono no lleva
       IconColor propio) y le suma .gesta-sidebar para ganarle en especificidad; el estado deshabilitado se
       deja como viene. */
    .gesta-sidebar .mud-nav-link:not(.mud-nav-link-disabled) .mud-nav-link-icon.mud-nav-link-icon-default,
    .gesta-sidebar .mud-nav-link .mud-nav-link-expand-icon {
        color: var(--gesta-sidebar-text);
    }

    .gesta-sidebar::-webkit-scrollbar {
        width: 5px;
        background: var(--gesta-sidebar-bg);
    }

    .gesta-sidebar::-webkit-scrollbar-thumb {
        background: var(--gesta-sidebar-scrollbar);
        border-radius: 2px;
    }

    .gesta-sidebar::-webkit-scrollbar-track {
        background: var(--gesta-sidebar-bg);
    }

    /* Cabecera de cada grupo (sección del menú): fondo de color + borde superior con el primary del tema. */
    .gesta-sidebar .mud-nav-group > .mud-nav-link {
        background-color: var(--gesta-sidebar-group-bg);
        border-top: 2px solid var(--mud-palette-primary);
        font-weight: 700;
    }

    /* Ítem activo, resaltado por ruta (NavLinkMatch): fondo destacado + barra lateral con el primary. */
    .gesta-sidebar .mud-nav-link.active {
        background-color: var(--gesta-sidebar-active-bg);
        border-right: 4px solid var(--mud-palette-primary);
    }

    /* En el rail compacto (drawer mini cerrado) la flecha de expandir/contraer no aporta:
   ocultarla; solo se muestra con el menú desplegado. */
    .gesta-sidebar.mud-drawer--closed .mud-nav-link-expand-icon {
        display: none;
    }

/* Respeta la preferencia de movimiento reducido (prefers-reduced-motion). */
@media (prefers-reduced-motion: reduce) {
    .gesta-sidebar,
    .gesta-sidebar * {
        transition: none !important;
    }
}

/* ===== Menú de usuario (AppBar): flecha del submenú =====
   El submenú "Tema" del menú ⋮ se despliega hacia la IZQUIERDA (el ⋮ está pegado al borde derecho de la
   barra). MudBlazor pinta la flecha del submenú (.mud-menu-submenu-icon) siempre hacia la derecha en LTR
   (solo la invierte en RightToLeft, que giraría toda la UI). Espejamos únicamente ese icono, acotado al
   popover de este menú (PopoverClass="gesta-menu-usuario"), para que apunte hacia donde de verdad abre. */
.gesta-menu-usuario .mud-menu-submenu-icon {
    transform: scaleX(-1);
}

/* ===== Logo de la barra superior (BrandingOptions.LogoUrl / LogoUrlMini) =====
   Va en el <img> que sustituye al título en la AppBar del MainLayout. Encaja la imagen dentro de la barra
   estándar manteniendo la proporción (ancho automático) y acota el ancho máximo para logos muy anchos. El
   alternado de visibilidad full/mini lo hacen las utilidades d-* de MudBlazor (con !important), que ganan
   a este display base. */
.gesta-appbar-logo {
    display: block;
    height: 36px;
    width: auto;
    max-width: 220px;
    object-fit: contain;
}
