/* Cielo — fondo permanente. No desaparece al entrar en la carta: queda detrás. Las estrellas las genera js/cielo.js y las escribe en --estrellas-lejanas / --estrellas-cercanas. */ .cielo { position: fixed; inset: 0; overflow: hidden; z-index: 0; background: var(--fondo-velo-bajo), var(--fondo-velo-alto), var(--fondo-velo-rosa), var(--fondo-umbral); } /* Las cintas de js/aurora.js: entre el degradado del fondo (que pone .cielo) y las estrellas, que van después en el DOM y por eso quedan encima. Se dibujan con blending aditivo en su propio lienzo, así que acá no hace falta ningún `mix-blend-mode`: ya salen sumadas al fondo. */ .cielo__aurora { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } .cielo__capa { position: absolute; top: 0; left: 0; border-radius: var(--r-circulo); transition: filter var(--t-lento) var(--curva-calma); } .cielo__capa--lejana { width: var(--cielo-estrella-lejana); height: var(--cielo-estrella-lejana); box-shadow: var(--estrellas-lejanas, none); animation: gira-fondo var(--cielo-deriva) linear infinite alternate; } .cielo__capa--cercana { width: var(--cielo-estrella-cercana); height: var(--cielo-estrella-cercana); box-shadow: var(--estrellas-cercanas, none); animation: parpadeo var(--t-parpadeo) var(--curva-calma) infinite, gira-cerca var(--cielo-deriva-cercanas) linear infinite alternate; } @keyframes parpadeo { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } } /* Destellos: capa aparte porque cada estrella necesita su propio ritmo de brillo (duración y retraso propios) — algo que un solo box-shadow, al ser una sola propiedad compartida, no puede darle a estrellas individuales. */ .cielo__capa--destellos { width: 100%; height: 100%; animation: gira-cerca var(--cielo-deriva-cercanas) linear infinite alternate; } .destello { position: absolute; width: var(--cielo-estrella-destello); height: var(--cielo-estrella-destello); border-radius: var(--r-circulo); background: rgb(var(--c-estrella)); /* El resplandor queda fijo (no se anima): así el destello solo mueve opacity/transform, que van por GPU sin repintar nada en cada fotograma. */ box-shadow: 0 0 var(--cielo-destello-resplandor) rgb(var(--c-estrella) / 0.9); opacity: 0; transform: scale(1); will-change: opacity, transform; } /* Se agrega y se saca esta clase desde el JS, una vez por destello (no es un loop): así cada uno es un evento propio, no un ciclo que se repite. */ .destello--activo { animation: destello var(--cielo-destello-duracion) cubic-bezier(0.16, 1, 0.3, 1); } @keyframes destello { 0% { opacity: 0; transform: scale(0.6); } 18% { opacity: 0.85; transform: scale(1.5); } 55% { opacity: 0.6; transform: scale(1.1); } 100% { opacity: 0; transform: scale(1); } } /* El giro de la bóveda. El eje está fuera de la pantalla, por debajo, así que lo que se ve es un arco lento y no un desplazamiento recto. Va en `alternate` (ida y vuelta) para que no haya salto al reiniciar el ciclo. */ .cielo__capa { transform-origin: var(--cielo-eje-x) var(--cielo-eje-y); } @keyframes gira-fondo { from { transform: rotate(calc(var(--cielo-giro) * -1)); } to { transform: rotate(var(--cielo-giro)); } } @keyframes gira-cerca { from { transform: rotate(var(--cielo-giro-cercanas)); } to { transform: rotate(calc(var(--cielo-giro-cercanas) * -1)); } } .cielo__horizonte { position: absolute; left: 0; right: 0; bottom: 0; height: var(--cielo-horizonte-alto); background: var(--cielo-horizonte); } /* Durante el aplicar el cielo se aviva un poco. Sutil, no espectacular. */ .app[data-fase="aplicando"] .cielo__capa { filter: brightness(var(--aplicando-cielo-intensidad)); }