/* =========================================================
   Estrellas de fondo — compartido por el sitio y el panel

   Vive en su propio archivo porque lo necesitan los dos: el sitio para el
   fondo (`.con-estrellas`) y el panel para la muestra en vivo de los controles
   (`.estrellas-demo`). El panel carga `admin.css` y el sitio `style.css`, así
   que dejarlo en cualquiera de los dos obligaba a duplicar los degradados — y
   dos copias de lo mismo terminan divergiendo.
   ========================================================= */

/* ---------- Estrellas de fondo (solo modo oscuro) ----------
   Dos capas de puntos hechas con degradados, desplazándose a distinta velocidad
   para dar sensación de profundidad. Es CSS puro, sin canvas ni JavaScript.

   ATENCIÓN: "sin JavaScript" NO quiere decir "gratis". La versión anterior de
   este archivo lo daba por sentado y por eso el sitio scrolleaba lento en el
   celular. Lo que decide el costo es **qué propiedad se anima**:

   - `transform` y `opacity` las mueve el compositor en la GPU: la capa se pinta
     una sola vez y después solo se reubica. Casi gratis.
   - Todo lo demás —y `background-position` es lo que se usaba acá— obliga a
     **repintar la capa entera en cada cuadro**. Eran catorce degradados
     rasterizados a pantalla completa sesenta veces por segundo, sobre una capa
     `position: fixed`, que además rompe el camino rápido del scroll del celular.
     De ahí el síntoma: no "la animación va a tirones", sino "tarda en scrollear".

   Por eso ahora se anima `transform`. **Si algún día hay que tocar el
   movimiento, tiene que seguir siendo `transform` u `opacity`.**

   Cómo cierra el bucle sin salto, que es lo delicado: cada capa tiene **un solo
   mosaico** (`--e-mosaico`) para todos sus degradados, sobresale exactamente ese
   mosaico por arriba, y se desplaza exactamente ese mosaico hacia abajo. Al
   terminar, el dibujo es idéntico al del arranque. No hay una lista de valores
   que se pueda desalinear: el mismo `var(--e-mosaico)` gobierna el tamaño del
   dibujo, el alto de la capa y el desplazamiento.

   Los tamaños y las posiciones NO están elegidos a mano: los sortea
   `scripts/estrellas.py`, y el resultado quedó escrito acá. El sorteo corre una
   vez y se congela a propósito: si el azar corriera en cada carga, las estrellas
   cambiarían de lugar en cada recarga, que se ve peor que un cielo fijo. Para
   rehacerlo: `python scripts/estrellas.py --semilla <otra>`. */

.con-estrellas,
.estrellas-demo {
    /* Los tres controles del panel, de 0 a 1. Los valores de acá son el respaldo
       por si el <body> no los trae. */
    --estrellas-nivel: .6;
    /* intensidad */
    --estrellas-tam: .5;
    /* tamaño */
    --estrellas-vel: .4;
    /* velocidad */

    /* Multiplica el radio de cada punto. El techo tiene que dejar a la estrella
       más grande **por debajo de 4 px**: más que eso deja de parecer una estrella
       y parece un copo de nieve. Hay un test que hace la multiplicación. */
    --e-tam: calc(.6 + var(--estrellas-tam) * 1.1);
    --e-luz: calc(.15 + var(--estrellas-nivel) * .85);
    /* Al revés que los otros dos: más velocidad = menos duración. Se expresa como
       multiplicación y no como división porque `calc(80s / var(--x))` depende de
       que el navegador soporte dividir por una variable, y no hace falta. */
    --e-lento: calc(4.25 - var(--estrellas-vel) * 3.25);
    --e-dur: calc(80s * var(--e-lento));
}

.con-estrellas::before,
.con-estrellas::after,
.estrellas-demo::before,
.estrellas-demo::after {
    content: "";
    pointer-events: none;
    background-repeat: repeat;
    background-size: var(--e-mosaico) var(--e-mosaico);
    opacity: var(--e-luz);
    /* Sobresale un mosaico por arriba, que es lo que después se desplaza. Sin
       esto, al moverse aparecería una franja vacía en el borde de la pantalla. */
    top: calc(-1 * var(--e-mosaico));
    height: calc(100% + var(--e-mosaico));
    left: 0;
    right: 0;
    animation: estrellas-caen var(--e-dur) linear infinite;
}

/* Capa lejana — mosaico de 640 px, 11 estrellas chicas y apagadas.
   Sorteado con `python scripts/estrellas.py --semilla 20260812`. */
.con-estrellas::before,
.estrellas-demo::before {
    --e-mosaico: 640px;
    background-image:
        radial-gradient(calc(1px * var(--e-tam)) calc(1px * var(--e-tam)) at 84% 81%, rgba(255, 255, 255, 0.19), transparent),
        radial-gradient(calc(1.5px * var(--e-tam)) calc(1.5px * var(--e-tam)) at 41% 33%, rgba(255, 226, 190, 0.22), transparent),
        radial-gradient(calc(1px * var(--e-tam)) calc(1px * var(--e-tam)) at 78% 48%, rgba(255, 255, 255, 0.14), transparent),
        radial-gradient(calc(1px * var(--e-tam)) calc(1px * var(--e-tam)) at 37% 93%, rgba(255, 255, 255, 0.14), transparent),
        radial-gradient(calc(1px * var(--e-tam)) calc(1px * var(--e-tam)) at 62% 79%, rgba(255, 255, 255, 0.17), transparent),
        radial-gradient(calc(1.5px * var(--e-tam)) calc(1.5px * var(--e-tam)) at 32% 46%, rgba(255, 255, 255, 0.29), transparent),
        radial-gradient(calc(1px * var(--e-tam)) calc(1px * var(--e-tam)) at 48% 45%, rgba(255, 255, 255, 0.13), transparent),
        radial-gradient(calc(1.5px * var(--e-tam)) calc(1.5px * var(--e-tam)) at 96% 88%, rgba(255, 255, 255, 0.31), transparent),
        radial-gradient(calc(1.5px * var(--e-tam)) calc(1.5px * var(--e-tam)) at 92% 26%, rgba(255, 255, 255, 0.26), transparent),
        radial-gradient(calc(2px * var(--e-tam)) calc(2px * var(--e-tam)) at 50% 60%, rgba(255, 255, 255, 0.38), transparent),
        radial-gradient(calc(1px * var(--e-tam)) calc(1px * var(--e-tam)) at 47% 50%, rgba(255, 255, 255, 0.16), transparent);
}

/* Capa cercana — mosaico de 460 px, 7 estrellas grandes y brillantes.
   Va más rápido que la lejana: es lo que da la sensación de profundidad. Al
   revés se vería mal, porque en la vida lo cercano es lo que pasa más rápido. */
.con-estrellas::after,
.estrellas-demo::after {
    --e-mosaico: 460px;
    animation-duration: calc(var(--e-dur) * .62);
    background-image:
        radial-gradient(calc(2.5px * var(--e-tam)) calc(2.5px * var(--e-tam)) at 69% 15%, rgba(255, 255, 255, 0.46), transparent),
        radial-gradient(calc(2px * var(--e-tam)) calc(2px * var(--e-tam)) at 37% 56%, rgba(255, 255, 255, 0.35), transparent),
        radial-gradient(calc(2px * var(--e-tam)) calc(2px * var(--e-tam)) at 66% 59%, rgba(255, 255, 255, 0.39), transparent),
        radial-gradient(calc(2.5px * var(--e-tam)) calc(2.5px * var(--e-tam)) at 80% 47%, rgba(56, 220, 242, 0.52), transparent),
        radial-gradient(calc(1.5px * var(--e-tam)) calc(1.5px * var(--e-tam)) at 81% 35%, rgba(255, 255, 255, 0.31), transparent),
        radial-gradient(calc(1.5px * var(--e-tam)) calc(1.5px * var(--e-tam)) at 62% 9%, rgba(255, 255, 255, 0.3), transparent),
        radial-gradient(calc(2.5px * var(--e-tam)) calc(2.5px * var(--e-tam)) at 36% 40%, rgba(56, 220, 242, 0.5), transparent);
}

.con-estrellas::before,
.con-estrellas::after {
    position: fixed;
    z-index: -1;
}

/* Modo "quietas": el cielo se ve igual, no se desplaza. Es la opción segura —
   un fondo quieto se pinta una vez y de ahí en más no cuesta nada— y por eso es
   la que viene puesta de fábrica. */
.con-estrellas--quietas::before,
.con-estrellas--quietas::after,
.estrellas-demo--quietas::before,
.estrellas-demo--quietas::after {
    animation: none;
}

@keyframes estrellas-caen {
    from {
        transform: translate3d(0, 0, 0);
    }

    to {
        transform: translate3d(0, var(--e-mosaico), 0);
    }
}

/* En modo claro no se ven y además ensucian: se apagan.
   La muestra del panel queda afuera a propósito: tiene fondo oscuro propio, y si
   no, quien administra con tema claro no podría ver lo que está regulando. */
:root[data-theme="light"] .con-estrellas::before,
:root[data-theme="light"] .con-estrellas::after {
    display: none;
}

/* ---------- Muestra de estrellas en el panel ---------- */
.estrellas-demo {
    position: relative;
    overflow: hidden;
    height: 150px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: #0a0f1e;
    margin: .75rem 0;
}

.estrellas-demo::before,
.estrellas-demo::after {
    position: absolute;
}

/* "Reducir movimiento": las estrellas quedan quietas, no desaparecen. Se frena el
   desplazamiento; el fondo se sigue viendo igual. Es la misma decisión que el modo
   "quietas", solo que la pide el sistema y no el panel — y por eso va con
   `!important`: la elección de accesibilidad gana sobre la del panel. */
@media (prefers-reduced-motion: reduce) {

    .con-estrellas::before,
    .con-estrellas::after,
    .estrellas-demo::before,
    .estrellas-demo::after {
        animation: none !important;
    }
}
