/**
 * Tema "neón" de la consulta pública (index.php).
 *
 * El fondo de index.php es el cielo estrellado de estrellas.css, y sobre él la
 * tarjeta blanca de escaner.css se recortaba como un folio pegado. Esta hoja la
 * reviste del mismo vidrio translucido que usa el login (glass.css) y le anade
 * los acentos de neon propios del escaneo.
 *
 * No toca escaner.css a propósito: esa hoja la comparte el escáner del panel
 * (pages/escaner.php), que vive sobre fondo claro y debe seguir igual. Todo
 * aquí cuelga de un modificador, así que sin él esta hoja no cambia nada:
 *   .scan-card.scan-card--neon      tarjeta de pestañas + visor
 *   .results-container--neon        resultado de la consulta y "no encontrado"
 *
 * Ademas de la tarjeta, viste la barra superior, el modal de info con el badge
 * de GitHub y el aviso de administrador: todo lo propio de esta pantalla.
 *
 * Debe cargarse DESPUES de escaner.css.
 */

:root {
    --neon-azul: #3b82f6;
    --neon-azul-hondo: #1d4ed8;
    /* Mismos valores de vidrio que glass.css, para que esta pantalla y el
       login se vean de la misma familia sobre el fondo de estrellas. */
    --neon-vidrio: rgba(255, 255, 255, 0.08);
    --neon-borde: rgba(255, 255, 255, 0.18);
    --neon-texto: rgba(255, 255, 255, 0.85);
    --neon-tenue: rgba(255, 255, 255, 0.55);
}

/* --- Barra superior pública --- */
/* Las reglas que había para esto vivían en el <style> inline de index.php y
   se apoyaban en !important; se trajeron aquí para que la barra y la tarjeta
   compartan un solo sitio y los mismos tokens. */

.navbar.navbar--neon {
    position: relative;
    background: rgba(9, 14, 28, 0.55);
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 10px 30px -18px rgba(0, 0, 0, 0.9);
    backdrop-filter: blur(18px) saturate(140%);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
}

/* El mismo filamento que remata la tarjeta, aquí en el borde de abajo. */
.navbar--neon::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(59, 130, 246, 0.55), transparent);
}

.navbar--neon .navbar-brand {
    /* El nombre viene de la configuracion y puede ser largo: se recorta con
       puntos suspensivos en vez de empujar al resto de la barra. */
    max-width: min(62vw, 40rem);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    vertical-align: middle;
    font-size: 1.35rem;
    font-weight: 700;
    color: #fff;
    letter-spacing: 0.01em;
}

.navbar--neon .navbar-brand:hover {
    color: #fff;
}

/* El logo sale de Configuracion y puede ser cualquier imagen: se fija el alto
   y se deja el ancho libre, asi entran tanto un icono cuadrado como un
   logotipo alargado sin deformarse ni cambiar el alto de la barra. */
.navbar--neon .navbar-brand img {
    height: 32px;
    width: auto;
    max-width: 140px;
    object-fit: contain;
    border-radius: 6px;
    vertical-align: -0.4em;
}

/* Respaldo cuando no hay logo cargado: generarLogoSistema() devuelve el icono
   QR, y ese si se tine con el azul del tema. */
.navbar--neon .navbar-brand i {
    color: var(--neon-azul);
    text-shadow: 0 0 14px rgba(59, 130, 246, 0.7);
}

.navbar--neon .nav-link {
    position: relative;
    padding: 0.5rem 0.9rem;
    border-radius: 8px;
    color: rgba(255, 255, 255, 0.65);
    font-weight: 500;
    transition: color 0.2s ease, background-color 0.2s ease;
}

.navbar--neon .nav-link:hover,
.navbar--neon .nav-link:focus-visible {
    color: #fff;
    background: rgba(255, 255, 255, 0.06);
}

.navbar--neon .nav-link.active {
    color: #fff;
}

/* Subrayado igual al de las pestañas de la tarjeta, para que la barra y el
   contenido se lean como la misma pieza. */
.navbar--neon .nav-link:not(.nav-acceso)::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 0.15rem;
    width: 0;
    height: 2px;
    transform: translateX(-50%);
    background: linear-gradient(90deg, var(--neon-azul-hondo), var(--neon-azul));
    box-shadow: 0 0 10px rgba(59, 130, 246, 0.8);
    transition: width 0.25s ease;
}

.navbar--neon .nav-link:not(.nav-acceso):hover::after,
.navbar--neon .nav-link.active::after {
    width: calc(100% - 1.8rem);
}

/* Iniciar sesión: es la única acción de la barra, así que se saca de la fila
   de enlaces y se pinta como botón. */
.navbar--neon .nav-acceso {
    padding: 0.45rem 1.1rem;
    border: 1px solid rgba(59, 130, 246, 0.45);
    border-radius: 999px;
    background: rgba(59, 130, 246, 0.1);
    color: #fff;
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    box-shadow: 0 0 22px -8px rgba(59, 130, 246, 0.9);
}

.navbar--neon .nav-acceso:hover,
.navbar--neon .nav-acceso:focus-visible {
    border-color: rgba(59, 130, 246, 0.8);
    background: rgba(59, 130, 246, 0.2);
    color: #fff;
    box-shadow: 0 0 26px -6px rgba(59, 130, 246, 1);
}

/* --- Botón del menú en móvil --- */

.navbar--neon .navbar-toggler {
    padding: 0.35rem 0.6rem;
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.06);
    /* Bootstrap pinta el icono con esta variable, así que basta recolorear el
       SVG en vez de sobrescribir background-image. */
    --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2859, 130, 246,0.9%29' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

.navbar--neon .navbar-toggler:focus {
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
}

/* Desplegado en móvil, los enlaces quedarían sueltos sobre las estrellas: se
   les pone debajo el mismo vidrio de la tarjeta. */
@media (max-width: 991.98px) {
    .navbar--neon .navbar-collapse {
        margin-top: 0.75rem;
        padding: 0.5rem;
        border: 1px solid rgba(255, 255, 255, 0.12);
        border-radius: 14px;
        background: rgba(9, 14, 28, 0.75);
        backdrop-filter: blur(18px) saturate(140%);
        -webkit-backdrop-filter: blur(18px) saturate(140%);
    }

    /* Sin este tope, un nombre largo manda el boton del menu a una segunda
       linea y la barra crece al doble. */
    .navbar--neon .navbar-brand {
        max-width: calc(100% - 4.5rem);
        font-size: 1.05rem;
    }

    .navbar--neon .navbar-brand img {
        height: 26px;
        vertical-align: -0.35em;
    }

    .navbar--neon .nav-acceso {
        display: inline-block;
        margin-top: 0.35rem;
        text-align: center;
    }

    /* Apilados, los enlaces ocupan todo el ancho y el subrayado parecia un
       separador: se cambia por una marca lateral. */
    .navbar--neon .nav-link:not(.nav-acceso) {
        padding-left: 1rem;
    }

    .navbar--neon .nav-link:not(.nav-acceso)::after {
        top: 50%;
        right: auto;
        bottom: auto;
        left: 0;
        width: 3px;
        height: 0;
        transform: translateY(-50%);
        border-radius: 3px;
        background: linear-gradient(180deg, var(--neon-azul-hondo), var(--neon-azul));
        transition: height 0.25s ease;
    }

    .navbar--neon .nav-link:not(.nav-acceso):hover::after,
    .navbar--neon .nav-link.active::after {
        width: 3px;
        height: 60%;
    }
}

/* --- Menú de usuario autenticado --- */

.navbar--neon .dropdown-menu {
    padding: 0.4rem;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 14px;
    background: rgba(13, 21, 41, 0.92);
    box-shadow: 0 20px 45px -20px rgba(0, 0, 0, 0.95);
    backdrop-filter: blur(18px) saturate(140%);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
}

.navbar--neon .dropdown-item {
    border-radius: 10px;
    color: rgba(255, 255, 255, 0.8);
}

.navbar--neon .dropdown-item:hover,
.navbar--neon .dropdown-item:focus {
    background: rgba(59, 130, 246, 0.14);
    color: #fff;
}

.navbar--neon .dropdown-divider {
    border-color: rgba(255, 255, 255, 0.12);
}


/* --- Tarjeta de consulta --- */

.scan-card.scan-card--neon {
    position: relative;
    /* El degradado simula la luz que entra por el borde superior. */
    background:
        linear-gradient(160deg, rgba(59, 130, 246, 0.12), transparent 45%),
        var(--neon-vidrio);
    border: 1px solid var(--neon-borde);
    border-radius: 20px;
    /* La sombra exterior no la recorta el overflow:hidden de la propia
       tarjeta, así que además de profundidad hace de halo. */
    box-shadow:
        0 8px 32px rgba(0, 0, 0, 0.45),
        0 0 80px -26px rgba(59, 130, 246, 0.45),
        inset 0 1px 0 rgba(255, 255, 255, 0.12);
    backdrop-filter: blur(20px) saturate(140%);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
}

/* Filamento de luz sobre el borde superior. */
.scan-card--neon::before {
    content: "";
    position: absolute;
    top: 0;
    left: 14%;
    right: 14%;
    height: 1px;
    z-index: 1;
    background: linear-gradient(90deg, transparent, var(--neon-azul), transparent);
}

/* --- Pestañas --- */

.scan-card--neon .scan-tabs {
    background: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.scan-card--neon .scan-tab {
    position: relative;
    color: var(--neon-tenue);
    letter-spacing: 0.02em;
    /* escaner.css reserva 3px de borde inferior para que el contenido no
       salte al cambiar de pestaña; aquí se deja transparente y la marca de
       activa la pinta ::after, que sí puede llevar brillo. */
    border-bottom-color: transparent;
}

.scan-card--neon .scan-tab:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.05);
}

.scan-card--neon .scan-tab.active {
    color: #fff;
    background: linear-gradient(180deg, rgba(59, 130, 246, 0.14), transparent);
}

.scan-card--neon .scan-tab::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -1px;
    width: 0;
    height: 2px;
    transform: translateX(-50%);
    background: linear-gradient(90deg, var(--neon-azul-hondo), var(--neon-azul));
    box-shadow: 0 0 12px rgba(59, 130, 246, 0.8);
    transition: width 0.28s ease;
}

.scan-card--neon .scan-tab.active::after {
    width: 62%;
}

/* --- Textos --- */

.scan-card--neon .scan-titulo {
    color: #fff;
    background: linear-gradient(92deg, #ffffff, #bfdbfe);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    letter-spacing: 0.01em;
}

.scan-card--neon .scan-subtitulo {
    color: var(--neon-tenue);
}

/* --- Campo del número de serie --- */

.scan-card--neon .scan-input {
    /* Hundido y mas oscuro que el vidrio: el campo se lee como una ranura
       donde se teclea, no como otra capa de tarjeta. */
    background: rgba(7, 13, 26, 0.45);
    border: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.45);
    border-radius: 12px;
    color: #fff;
    /* Monoespaciada: el número de serie se coteja carácter a carácter contra
       la etiqueta del equipo, y así no se confunden 0/O ni 1/l. */
    font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
    letter-spacing: 0.12em;
}

.scan-card--neon .scan-input::placeholder {
    color: rgba(255, 255, 255, 0.5);
    letter-spacing: 0.08em;
}

.scan-card--neon .scan-input:focus {
    background: rgba(7, 13, 26, 0.6);
    border-color: rgba(59, 130, 246, 0.75);
    box-shadow:
        inset 0 2px 6px rgba(0, 0, 0, 0.45),
        0 0 0 4px rgba(59, 130, 246, 0.16),
        0 0 22px -6px rgba(59, 130, 246, 0.7);
    color: #fff;
}

/* --- Botones de acción --- */

.scan-card--neon .btn-primary,
.scan-card--neon .btn-success {
    position: relative;
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 12px;
    background: #0a0a0a;
    color: #fff;
    font-weight: 700;
    letter-spacing: 0.02em;
    box-shadow:
        0 12px 30px -14px rgba(0, 0, 0, 1),
        inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

.scan-card--neon .btn-primary:hover,
.scan-card--neon .btn-success:hover {
    transform: translateY(-2px);
    border-color: rgba(255, 255, 255, 0.6);
    background: #000;
    box-shadow:
        0 16px 34px -12px rgba(0, 0, 0, 1),
        inset 0 1px 0 rgba(255, 255, 255, 0.16);
}

/* Destello blanco que cruza el boton al pasar el raton. */
.scan-card--neon .btn-primary::after,
.scan-card--neon .btn-success::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -60%;
    width: 45%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.28), transparent);
    transform: skewX(-20deg);
    transition: left 0.55s ease;
}

.scan-card--neon .btn-primary:hover::after,
.scan-card--neon .btn-success:hover::after {
    left: 120%;
}

/* "Detener escáner": secundario, no debe competir con el de arranque. */
.scan-card--neon .btn-dark {
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.06);
    color: var(--neon-texto);
}

.scan-card--neon .btn-dark:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.4);
    color: #fff;
}

/* --- Visor de la cámara --- */

.scan-card--neon .scan-visor {
    /* El visor es cuadrado, asi que a lo ancho de la tarjeta la pestana de QR
       crecia tanto que el boton de iniciar se salia de la ventana. Limitando el
       ancho se limita tambien el alto, y la tarjeta entera cabe en pantalla.
       El 45vh cubre las pantallas bajas, donde 340px seguirian sobrando. */
    max-width: min(320px, 38vh);
    margin: 0 auto;
    background: rgba(7, 13, 26, 0.6);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 16px;
}

/* Escuadras de encuadre: ocho degradados planos, uno por trazo, colocados de
   dos en dos en cada esquina. */
.scan-card--neon .scan-visor::before {
    content: "";
    position: absolute;
    inset: 12px;
    z-index: 3;
    pointer-events: none;
    opacity: 0.75;
    background-repeat: no-repeat;
    background-image:
        linear-gradient(var(--neon-azul), var(--neon-azul)),
        linear-gradient(var(--neon-azul), var(--neon-azul)),
        linear-gradient(var(--neon-azul), var(--neon-azul)),
        linear-gradient(var(--neon-azul), var(--neon-azul)),
        linear-gradient(var(--neon-azul), var(--neon-azul)),
        linear-gradient(var(--neon-azul), var(--neon-azul)),
        linear-gradient(var(--neon-azul), var(--neon-azul)),
        linear-gradient(var(--neon-azul), var(--neon-azul));
    background-size:
        24px 2px, 2px 24px,
        24px 2px, 2px 24px,
        24px 2px, 2px 24px,
        24px 2px, 2px 24px;
    background-position:
        0 0, 0 0,
        100% 0, 100% 0,
        0 100%, 0 100%,
        100% 100%, 100% 100%;
}

/* Línea de barrido. Va por debajo de .scan-estado, así que solo manda cuando
   la cámara está encendida y el aviso se oculta. */
.scan-card--neon .scan-visor::after {
    content: "";
    position: absolute;
    left: 8%;
    right: 8%;
    top: 8%;
    height: 2px;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(90deg, transparent, var(--neon-azul), transparent);
    box-shadow: 0 0 18px 2px rgba(59, 130, 246, 0.55);
    animation: neonBarrido 2.8s ease-in-out infinite;
}

@keyframes neonBarrido {
    0%, 100% { top: 8%;  opacity: 0.25; }
    50%      { top: 88%; opacity: 0.9; }
}

/* Aviso translúcido en vez de opaco: deja entrever las escuadras y el barrido,
   de modo que el visor apagado ya se lee como un escáner en reposo. */
.scan-card--neon .scan-estado {
    z-index: 4;
    background: rgba(7, 13, 26, 0.72);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.scan-card--neon .scan-estado__icono {
    color: rgba(255, 255, 255, 0.45);
}

.scan-card--neon .scan-estado__texto {
    color: var(--neon-texto);
}

.scan-card--neon .scan-estado__accion {
    color: var(--neon-azul);
}

.scan-card--neon .scan-estado.is-error .scan-estado__icono,
.scan-card--neon .scan-estado.is-error .scan-estado__texto {
    color: #ff8896;
}

/* escaner.css marca la deteccion de un QR con un pulso verde; aqui la paleta es
   blanco, negro y azul, asi que se repone en blanco. Solo para esta pantalla:
   el escaner del panel conserva el suyo. */
@keyframes neonPulsoDeteccion {
    0%   { box-shadow: inset 0 0 0 0 rgba(255, 255, 255, 0.9); }
    70%  { box-shadow: inset 0 0 0 12px rgba(255, 255, 255, 0); }
    100% { box-shadow: inset 0 0 0 0 rgba(255, 255, 255, 0); }
}

.scan-card--neon .scan-visor #qr-reader.scanning {
    animation: neonPulsoDeteccion 1s ease-out;
}

/* --- Resultado de la consulta y "no encontrado" --- */

/* Doble clase a proposito: el <style> inline de index.php declara
   .results-container despues de este <link>, y a igualdad de especificidad
   ganaria el ultimo. */
.results-container.results-container--neon {
    background: var(--neon-vidrio);
    border: 1px solid var(--neon-borde);
    border-radius: 20px;
    color: var(--neon-texto);
    box-shadow:
        0 8px 32px rgba(0, 0, 0, 0.45),
        inset 0 1px 0 rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(20px) saturate(140%);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
}

.results-container--neon .text-primary { color: #93c5fd !important; }
.results-container--neon .text-muted   { color: var(--neon-tenue) !important; }
.results-container--neon .text-warning { color: #bfdbfe !important; }
/* formatearImporteHTML() pinta el importe con text-success y la advertencia de
   "sin moneda" con bg-warning. En el panel eso esta bien; aqui la paleta es
   blanco, negro y azul, asi que se neutralizan. */
.results-container--neon .text-success { color: #fff !important; }

.results-container--neon .bg-warning {
    background: rgba(255, 255, 255, 0.12) !important;
    color: #fff !important;
}

.results-container--neon .equipment-table {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    box-shadow: none;
}

.results-container--neon .table {
    color: var(--neon-texto);
    margin-bottom: 0;
}

.results-container--neon .table th {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.22), rgba(29, 78, 216, 0.22));
    color: #fff;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

/* El rayado de Bootstrap pinta filas claras que sobre el vidrio ciegan: se
   anula y se repone en oscuro. La regla de las impares pesa más que la lisa
   de arriba, así que el orden entre ambas da igual. */
.results-container--neon .table > tbody > tr > td {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.08);
    color: var(--neon-texto);
}

.results-container--neon .table > tbody > tr:nth-of-type(odd) > td {
    background: rgba(255, 255, 255, 0.04);
}

.results-container--neon .table > tbody > tr:hover > td {
    background: rgba(59, 130, 246, 0.09);
}

/* Los estados llevan su nombre escrito y aqui solo se muestra un equipo a la
   vez, asi que el color no anade informacion: se unifican en un chip neutro y
   la paleta se queda en blanco, negro y azul. */
.results-container--neon .status-badge {
    border: 1px solid rgba(255, 255, 255, 0.2);
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    font-weight: 600;
}

.results-container--neon .btn-secondary {
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: var(--neon-texto);
}

.results-container--neon .btn-secondary:hover {
    background: rgba(255, 255, 255, 0.16);
    color: #fff;
}

.results-container--neon .btn-primary {
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 12px;
    background: #0a0a0a;
    font-weight: 700;
    box-shadow: 0 12px 30px -14px rgba(0, 0, 0, 1);
}

/* --- Aviso de administrador --- */
/* Solo lo ve quien ha iniciado sesion, pero comparte pantalla con la tarjeta:
   sin esto se quedaba con el azul y el boton verde del estilo anterior. */

.alert.alert--neon {
    border: 1px solid var(--neon-borde);
    border-radius: 16px;
    background: var(--neon-vidrio);
    color: var(--neon-texto);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(18px) saturate(140%);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
}

.alert--neon .alert-heading {
    color: #fff;
}

.alert--neon .fa-info-circle {
    color: var(--neon-azul);
    text-shadow: 0 0 14px rgba(59, 130, 246, 0.6);
}

.alert--neon .btn-primary {
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 10px;
    background: #0a0a0a;
    font-weight: 700;
    box-shadow: 0 10px 26px -14px rgba(0, 0, 0, 1);
}

/* --- Botón de info flotante --- */
/* Abre el modal con la ficha del autor. Va anclado al pie de la ventana, no a
   la barra: así queda a mano con el pulgar en el móvil y no compite con la
   tarjeta de consulta, que es lo que la gente viene a usar.
   El z-index queda por debajo del modal de Bootstrap (1055) para que no se
   cuele por encima de su fondo oscuro al abrirse. */

.info-flotante {
    position: fixed;
    left: 50%;
    bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
    z-index: 1030;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.7rem 1.35rem;
    border: 1px solid rgba(29, 78, 216, 0.55);
    border-radius: 999px;
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.2), rgba(29, 78, 216, 0.28));
    color: #fff;
    font-weight: 600;
    font-size: 0.95rem;
    line-height: 1.4;
    box-shadow:
        0 10px 30px -10px rgba(0, 0, 0, 0.9),
        0 0 22px -6px rgba(29, 78, 216, 0.9);
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}

.info-flotante i {
    color: var(--neon-azul);
}

/* El desplazamiento del hover va sobre el translateX que ya centra el botón:
   si se escribiera solo translateY, se perdería el centrado. */
.info-flotante:hover,
.info-flotante:focus-visible {
    border-color: rgba(59, 130, 246, 0.9);
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.32), rgba(29, 78, 216, 0.4));
    color: #fff;
    box-shadow:
        0 14px 34px -10px rgba(0, 0, 0, 0.95),
        0 0 30px -4px rgba(59, 130, 246, 0.95);
    transform: translateX(-50%) translateY(-3px);
}

/* Latido muy lento: llama la atención cada pocos segundos y el resto del
   tiempo se deja ignorar. */
@keyframes neonLatido {
    0%, 92%, 100% {
        box-shadow:
            0 10px 30px -10px rgba(0, 0, 0, 0.9),
            0 0 22px -6px rgba(29, 78, 216, 0.9);
    }
    96% {
        box-shadow:
            0 10px 30px -10px rgba(0, 0, 0, 0.9),
            0 0 32px -2px rgba(59, 130, 246, 0.95);
    }
}

.info-flotante {
    animation: neonLatido 6s ease-in-out infinite;
}

.info-flotante:hover {
    animation: none;
}

/* Con un modal abierto el boton queda detras del fondo oscuro, pero se
   transparenta y su latido distrae. Bootstrap marca <body> con .modal-open, asi
   que basta apagarlo mientras dure. */
body.modal-open .info-flotante {
    opacity: 0;
    pointer-events: none;
}

@media (max-width: 575.98px) {
    .info-flotante {
        bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
        padding: 0.6rem 1.15rem;
        font-size: 0.9rem;
    }
}

/* --- Modal de info --- */
/* Solo este modal: los de imágenes siguen con su cabecera de color y su fondo
   claro, que es donde se ven las fotos de los equipos. */

.modal--neon .modal-content {
    border: 1px solid var(--neon-borde);
    border-radius: 18px;
    background: rgba(13, 21, 41, 0.92);
    color: var(--neon-texto);
    box-shadow:
        0 30px 70px -25px rgba(0, 0, 0, 0.95),
        inset 0 1px 0 rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(20px) saturate(140%);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
}

.modal--neon .modal-header,
.modal--neon .modal-footer {
    border-color: rgba(255, 255, 255, 0.1);
}

.modal--neon .modal-title {
    color: #fff;
    font-weight: 600;
}

.modal--neon .modal-title i {
    color: var(--neon-azul);
}

.modal--neon .btn-secondary {
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.08);
    color: var(--neon-texto);
}

.modal--neon .btn-secondary:hover {
    background: rgba(255, 255, 255, 0.16);
    color: #fff;
}

.info-pie {
    margin: 1.25rem 0 0;
    color: var(--neon-tenue);
    font-size: 0.875rem;
    line-height: 1.8;
}

.info-pie strong {
    color: #fff;
}

.info-pie a {
    color: var(--neon-azul);
    font-weight: 600;
    text-decoration: none;
}

.info-pie a:hover {
    text-decoration: underline;
}

/* --- Badge de GitHub --- */
/* Enlace de bloque: se pulse donde se pulse, lleva al perfil. */

.gh-badge {
    display: block;
    padding: 1rem 1.125rem;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.05);
    color: inherit;
    text-decoration: none;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

.gh-badge:hover,
.gh-badge:focus-visible {
    border-color: rgba(59, 130, 246, 0.5);
    background: rgba(59, 130, 246, 0.08);
    color: inherit;
}

.gh-badge__cabecera {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.gh-badge__avatar {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    border: 2px solid rgba(59, 130, 246, 0.45);
}

/* min-width:0 para que un nombre largo se recorte en vez de empujar el icono
   de GitHub fuera de la tarjeta. */
.gh-badge__id {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.gh-badge__nombre {
    color: #fff;
    font-size: 1rem;
    line-height: 1.25;
}

.gh-badge__login {
    color: var(--neon-tenue);
    font-size: 0.85rem;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
}

.gh-badge__marca {
    font-size: 1.5rem;
    color: rgba(255, 255, 255, 0.75);
    transition: color 0.2s ease;
}

.gh-badge:hover .gh-badge__marca {
    color: var(--neon-azul);
}

.gh-badge__bio {
    margin: 0.75rem 0 0;
    color: var(--neon-texto);
    font-size: 0.875rem;
}

.gh-badge__cifras {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
    margin-top: 0.875rem;
    padding-top: 0.875rem;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.gh-badge__cifra {
    padding: 0.625rem 0.35rem;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.08);
    color: var(--neon-tenue);
    font-size: 0.8125rem;
    text-align: center;
}

.gh-badge__cifra strong {
    display: block;
    color: #fff;
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.15;
}

.gh-badge__pie {
    margin: 0.75rem 0 0;
    color: rgba(255, 255, 255, 0.5);
    font-size: 0.78rem;
    text-align: center;
}

/* --- Modal de imagenes del equipo --- */

.modal--neon .card {
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.05);
    color: var(--neon-texto);
}

/* Lo que se sube de un equipo suelen ser etiquetas y codigos QR: con "cover"
   se recortaban justo por donde importa, asi que se muestran enteras sobre un
   fondo oscuro. */
.modal--neon .card-img-top {
    height: 200px;
    padding: 0.5rem;
    object-fit: contain;
    background: rgba(7, 13, 26, 0.6);
}

.modal--neon .card-body,
.modal--neon .card-footer {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.1);
}

.modal--neon .card .text-muted {
    color: var(--neon-tenue) !important;
}

.modal--neon .modal-body img.img-fluid {
    border-radius: 12px;
}

/* El .btn-primary del <style> de la pagina fija un padding de 0.7rem 2rem que
   pisa el de .btn-sm, y por eso los botones de "ver" y "descargar" salian
   enormes dentro de su tarjeta. */
.btn-sm.btn-primary,
.btn-sm.btn-success,
.btn-sm.btn-secondary {
    padding: 0.35rem 0.7rem;
    border-radius: 10px;
    font-size: 0.8125rem;
}

.badge-imagenes {
    border: 1px solid rgba(255, 255, 255, 0.25);
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    font-weight: 600;
}

/* --- Credito del desarrollador --- */

.credito {
    position: fixed;
    right: 1rem;
    bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
    z-index: 1020;
    margin: 0;
    color: rgba(255, 255, 255, 0.4);
    font-size: 0.75rem;
    /* Es un rotulo, no un control: que no se coma clics de lo que tenga debajo. */
    pointer-events: none;
}

.credito strong {
    color: rgba(255, 255, 255, 0.7);
    font-weight: 600;
}

body.modal-open .credito {
    opacity: 0;
}

/* --- Pantallas estrechas --- */

@media (max-width: 575.98px) {
    .scan-card.scan-card--neon {
        border-radius: 16px;
    }

    .scan-card--neon .scan-tab {
        font-size: 0.9rem;
        padding-left: 0.25rem;
        padding-right: 0.25rem;
    }

    /* La ficha del equipo es una tabla de dos columnas: en un movil la columna
       de la etiqueta estrangula la del valor y todo acaba partido en varias
       lineas. Aqui cada fila pasa a ser un bloque, con la etiqueta encima y el
       dato debajo a todo el ancho. */
    .results-container--neon .table,
    .results-container--neon .table > tbody,
    .results-container--neon .table > tbody > tr,
    .results-container--neon .table > tbody > tr > td {
        display: block;
        width: 100%;
    }

    /* "Campo / Informacion" no dice nada cuando las filas van apiladas. */
    .results-container--neon .table > thead {
        display: none;
    }

    .results-container--neon .table > tbody > tr {
        padding: 0.7rem 0.9rem;
        border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    }

    .results-container--neon .table > tbody > tr:last-child {
        border-bottom: 0;
    }

    .results-container--neon .table > tbody > tr:nth-of-type(odd) {
        background: rgba(255, 255, 255, 0.04);
    }

    .results-container--neon .table > tbody > tr > td,
    .results-container--neon .table > tbody > tr:nth-of-type(odd) > td,
    .results-container--neon .table > tbody > tr:hover > td {
        padding: 0;
        border: 0;
        background: transparent;
    }

    /* La primera celda de cada fila es el nombre del campo. */
    .results-container--neon .table > tbody > tr > td:first-child {
        margin-bottom: 0.15rem;
        color: var(--neon-tenue);
        font-size: 0.78rem;
    }

    .results-container--neon .table > tbody > tr > td:first-child strong {
        font-weight: 600;
    }

    .results-container--neon .table > tbody > tr > td:last-child {
        color: #fff;
    }

    .results-container.results-container--neon {
        padding: 1rem;
    }

    /* Fijo y a la derecha chocaria con el boton de info, que va centrado: en
       movil baja al final de la pagina. */
    .credito {
        position: static;
        margin: 0 0 4.5rem;
        text-align: center;
    }
}

/* --- Movimiento reducido --- */

@media (prefers-reduced-motion: reduce) {
    .scan-card--neon .scan-visor #qr-reader.scanning {
        animation: none;
    }

    .scan-card--neon .scan-visor::after {
        animation: none;
        top: 50%;
        opacity: 0.45;
    }

    .info-flotante,
    .gh-badge,
    .gh-badge__marca,
    .scan-card--neon .scan-tab::after,
    .navbar--neon .nav-link,
    .navbar--neon .nav-link::after,
    .scan-card--neon .btn-primary,
    .scan-card--neon .btn-success,
    .scan-card--neon .btn-primary::after,
    .scan-card--neon .btn-success::after {
        transition: none;
    }

    .info-flotante {
        animation: none;
    }

    .scan-card--neon .btn-primary:hover,
    .scan-card--neon .btn-success:hover {
        transform: none;
    }

    /* Aqui no vale transform:none: ese translateX es lo que centra el boton. */
    .info-flotante:hover {
        transform: translateX(-50%);
    }
}
