/* ===========================================
   R4P – AMBIENT PARTICLES
   Lifecycle: Fade-In → Drift → Fade-Out → Loop
   =========================================== */

.parallax-field {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
    overflow: hidden;
    /* sanfter Einblendung des gesamten Feldes – kein abruptes Erscheinen beim Laden */
    opacity: 0;
    animation: pf-field-in 1.6s var(--ease-out, ease-out) 0.2s forwards;
}

@keyframes pf-field-in {
    to { opacity: 1; }
}

.parallax-field__dot {
    position: absolute;
    width: var(--size, 4px);
    height: var(--size, 4px);
    border-radius: 50%;
    opacity: 0;
    will-change: transform, opacity;
    animation: pf-life var(--duration, 10s) linear var(--delay, 0s) infinite;
}

/* Vier Farb-Varianten – alle dezent gehalten */
.parallax-field__dot.pf-v0 {
    background: var(--c-accent);
}
.parallax-field__dot.pf-v1 {
    background: rgba(255, 255, 255, 0.55);
}
.parallax-field__dot.pf-v2 {
    background: var(--c-orange);
}
.parallax-field__dot.pf-v3 {
    background: transparent;
    border: 1px solid var(--c-accent);
}

/* Lifecycle – glockenförmiger Opacity-Verlauf mit Buffer an beiden Enden.
   Buffer-Zonen (0-8% und 92-100%) sind komplett unsichtbar, damit
   Iteration-Boundaries niemals sichtbare Sprünge erzeugen können.
*/
@keyframes pf-life {
    0%, 8% {
        opacity: 0;
        transform: translate3d(0, 0, 0);
    }
    50% {
        opacity: var(--opacity, 0.25);
        transform: translate3d(
            calc(var(--dx, 16px) * 0.5),
            calc(var(--dy, -16px) * 0.5),
            0
        );
    }
    92%, 100% {
        opacity: 0;
        transform: translate3d(var(--dx, 16px), var(--dy, -16px), 0);
    }
}

/* Reduced Motion: ausblenden */
@media (prefers-reduced-motion: reduce) {
    .parallax-field { display: none !important; }
}
