////
///
/// Bounce Keyframes Mixins Module
/// ===========================================================================
///
/// Defines keyframes for bounce animations including simple bounce, extended
/// bounce with squash/stretch, rotating bounce, and multi-directional bounce.
/// These keyframes create playful jumping effects for UI elements.
///
/// @group Keyframes
/// @author Scape Agency
/// @link https://move.gl
/// @since 0.1.0 initial release
/// @access public
///
////


// ============================================================================
// Use
// ============================================================================

@use "../../../variables" as *;
@use "../_base" as *;


// ============================================================================
// Basic Bounce Keyframes
// ============================================================================

///
/// Standard bounce animation keyframes.
///
/// @param {Length} $bounce_height [$animate_bounce_height] - Height of the bounce
///
@mixin keyframes_bounce($bounce_height: $animate_bounce_height) {
    @include keyframes(animate_bounce) {
        0%, 100% {
            transform: translateY(0);
        }
        50% {
            transform: translateY($bounce_height);
        }
    }
}

///
/// Bounce animation with CSS custom property support.
///
@mixin keyframes_animate_bounce($bounce_height: $animate_translate_bounce) {
    @include keyframes(animate_bounce) {
        0%, 100% {
            transform: translateY(0);
        }
        50% {
            transform: translateY(var(--animate-bounce-height, #{$bounce_height}));
        }
    }
}


// ============================================================================
// Extended Bounce Keyframes
// ============================================================================

///
/// Extended bounce with squash and stretch effects.
///
/// @param {Number} $start_scale_x [$animate_bounce_start_scale_x] - Initial squash scale X
/// @param {Number} $start_scale_y [$animate_bounce_start_scale_y] - Initial squash scale Y
/// @param {Number} $jump_scale_x [$animate_bounce_jump_scale_x] - Jump stretch scale X
/// @param {Number} $jump_scale_y [$animate_bounce_jump_scale_y] - Jump stretch scale Y
/// @param {Length} $bounce_height [$animate_bounce_height_extended] - Main bounce height
/// @param {Number} $land_scale_x [$animate_bounce_land_scale_x] - Landing squash scale X
/// @param {Number} $land_scale_y [$animate_bounce_land_scale_y] - Landing squash scale Y
/// @param {Length} $rebound_height [$animate_bounce_rebound] - Secondary bounce height
///
@mixin keyframes_bounce_extended(
    $start_scale_x: $animate_bounce_start_scale_x,
    $start_scale_y: $animate_bounce_start_scale_y,
    $jump_scale_x: $animate_bounce_jump_scale_x,
    $jump_scale_y: $animate_bounce_jump_scale_y,
    $bounce_height: $animate_bounce_height_extended,
    $land_scale_x: $animate_bounce_land_scale_x,
    $land_scale_y: $animate_bounce_land_scale_y,
    $rebound_height: $animate_bounce_rebound
) {
    @include keyframes(animate_bounce_extended) {
        0% {
            transform: scale(1, 1) translateY(0);
        }
        10% {
            transform: scale($start_scale_x, $start_scale_y) translateY(0);
        }
        30% {
            transform: scale($jump_scale_x, $jump_scale_y) translateY($bounce_height);
        }
        50% {
            transform: scale($land_scale_x, $land_scale_y) translateY(0);
        }
        57% {
            transform: scale(1, 1) translateY($rebound_height);
        }
        64% {
            transform: scale(1, 1) translateY(0);
        }
        100% {
            transform: scale(1, 1) translateY(0);
        }
    }
}


// ============================================================================
// Bounce with Rotation Keyframes
// ============================================================================

///
/// Bounce animation combined with rotation.
///
/// @param {Angle} $rotation_angle [360deg] - Rotation angle during bounce
/// @param {Length} $bounce_height [-20%] - Height of the bounce
///
@mixin keyframes_bounce_rotate($rotation_angle: $animate_angle_full, $bounce_height: $animate_bounce_height) {
    @include keyframes(animate_bounce_rotate) {
        0%, 100% {
            transform: translateY(0) rotate(0);
        }
        50% {
            transform: translateY($bounce_height) rotate($rotation_angle);
        }
    }
}


// ============================================================================
// Multi-Directional Bounce Keyframes
// ============================================================================

///
/// Bounce in both X and Y directions.
///
/// @param {Length} $bounce_x [-10%] - Horizontal bounce distance
/// @param {Length} $bounce_y [-20%] - Vertical bounce distance
///
@mixin keyframes_bounce_multi($bounce_x: $animate_bounce_multi_x, $bounce_y: $animate_bounce_multi_y) {
    @include keyframes(animate_bounce_multi) {
        0%, 100% {
            transform: translate(0, 0);
        }
        25% {
            transform: translate($bounce_x, 0);
        }
        50% {
            transform: translate(0, $bounce_y);
        }
        75% {
            transform: translate($bounce_x, 0);
        }
    }
}


// ============================================================================
// Elastic Bounce Keyframes
// ============================================================================

///
/// Elastic bounce with overshoot effect.
///
/// @param {Length} $bounce_height [-30%] - Main bounce height
///
@mixin keyframes_bounce_elastic($bounce_height: $animate_bounce_elastic_height) {
    @include keyframes(animate_bounce_elastic) {
        0%, 100% {
            transform: translateY(0);
        }
        40% {
            transform: translateY($bounce_height);
        }
        50% {
            transform: translateY($bounce_height * 0.3);
        }
        60% {
            transform: translateY($bounce_height * 0.7);
        }
        80% {
            transform: translateY($bounce_height * 0.15);
        }
    }
}


// ============================================================================
// Entrance/Exit Bounce Keyframes
// ============================================================================

///
/// Bounce in from bottom.
///
/// @param {Length} $distance [100%] - Starting distance
///
@mixin keyframes_bounce_in_up($distance: 100%) {
    @include keyframes(animate_bounce_in_up) {
        0% {
            opacity: 0;
            transform: translateY($distance);
        }
        60% {
            opacity: 1;
            transform: translateY(-20px);
        }
        80% {
            transform: translateY(10px);
        }
        100% {
            transform: translateY(0);
        }
    }
}

///
/// Bounce in from top.
///
/// @param {Length} $distance [-100%] - Starting distance
///
@mixin keyframes_bounce_in_down($distance: -100%) {
    @include keyframes(animate_bounce_in_down) {
        0% {
            opacity: 0;
            transform: translateY($distance);
        }
        60% {
            opacity: 1;
            transform: translateY(20px);
        }
        80% {
            transform: translateY(-10px);
        }
        100% {
            transform: translateY(0);
        }
    }
}

///
/// Bounce in from left.
///
/// @param {Length} $distance [-100%] - Starting distance
///
@mixin keyframes_bounce_in_left($distance: -100%) {
    @include keyframes(animate_bounce_in_left) {
        0% {
            opacity: 0;
            transform: translateX($distance);
        }
        60% {
            opacity: 1;
            transform: translateX(20px);
        }
        80% {
            transform: translateX(-10px);
        }
        100% {
            transform: translateX(0);
        }
    }
}

///
/// Bounce in from right.
///
/// @param {Length} $distance [100%] - Starting distance
///
@mixin keyframes_bounce_in_right($distance: 100%) {
    @include keyframes(animate_bounce_in_right) {
        0% {
            opacity: 0;
            transform: translateX($distance);
        }
        60% {
            opacity: 1;
            transform: translateX(-20px);
        }
        80% {
            transform: translateX(10px);
        }
        100% {
            transform: translateX(0);
        }
    }
}
