.nl-hero-carousel {
    width: 100%;
    aspect-ratio: 16/9;
    background: #000;
}

.nl-hero-carousel .splide__track, 
.nl-hero-carousel .splide__list, 
.nl-hero-carousel .splide__slide {
    height: 100%;
}

/* Treat the slide as a flex container for your text blocks */
.nl-hero-carousel .splide__slide {
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
}

/* If you use Cover Image blocks in Gutenberg, they will naturally fill this space.
  Otherwise, style your inner HTML content here. 
*/
.nl-hero-carousel .wp-block-cover,
.nl-hero-carousel .wp-block-group {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
}

/* Other CSS remains the same, update only these two blocks: */

/* 1. The Initial Hidden State */
.nl-hero-carousel .splide__slide .wp-block-cover__inner-container {
    opacity: 0;
    transform: translateY(20px); /* Pushing it down slightly makes the fade feel organic */
    will-change: opacity, transform;
}

/* 2. The Trigger Engine */
.nl-hero-carousel .splide__slide.is-active .wp-block-cover__inner-container {
    /* Format: animation-name | duration (fixed) | delay (variable) | fill-mode | timing-function
       This guarantees a crisp 0.8s fade, no matter how long the background zooms.
    */
    animation: nlFadeInUp 0.8s var(--z-del, 1s) forwards ease-out;
}

/* 3. The Clean Keyframes */
@keyframes nlFadeInUp {
    0% {
        opacity: 0;
        transform: translateY(20px);
    }
    100% {
        opacity: 1;
        transform: translateY(0);
    }
}