/* General base for animated elements */
.anim {
    opacity: 0;
    will-change: opacity, transform;
}

/* Fade-only (small movement) */
.fade, .fade-up, .fade-down, .fade-left, .fade-right {
    opacity: 0;
    transform: translateZ(0);
}

/* Fade offsets (small subtle movement) */
.fade-up {
    transform: translateY(60px);
}

.fade-down {
    transform: translateY(-60px);
}

.fade-left {
    transform: translateX(60px);
}

.fade-right {
    transform: translateX(-60px);
}

/* Slide variants (bigger movement than fade, for 'slide in' feel) */
.slide-up {
    transform: translateY(140px);
}

.slide-down {
    transform: translateY(-140px);
}

.slide-left {
    transform: translateX(140px);
}

.slide-right {
    transform: translateX(-140px);
}

/* Zoom/scale */
.scroll-fade {
    transform: scale(1.15);
}

/* small zoom out → in */
.scroll-fade-zoom {
    transform: scale(0.8);
}

/* zoomed out starting state */

/* Rotate / bounce presets */
.rotate-fade {
    transform: translateY(30px) rotate(10deg);
}

.scale-bounce {
    transform: scale(0.6);
}

/* Parallax (no opacity change by default) */
.parallax-up {
    transform: translateY(100px);
}

.parallax-down {
    transform: translateY(-100px);
}

.parallax-left {
    transform: translateX(100px);
}

.parallax-right {
    transform: translateX(-200px);
}

/* Mask (clip-path) reveal */
.mask-slide {
    clip-path: inset(0 100% 0 0);
}

/* Text letter effects */
.text-reveal, .text-wave {
    display: inline-block;
    overflow: hidden;
    vertical-align: bottom;
}

.text-reveal .letter, .text-wave .letter {
    display: inline-block;
    opacity: 0;
    transform: translateY(20px);
}

/* Optional: class to mark fully visible / finished (useful if you want pure CSS fallback) */
.in-view {
    opacity: 1 !important;
    transform: none !important;
    transition: transform 0.45s cubic-bezier(.22, .9, .32, 1), opacity 0.35s ease;
}