.ivx-animations(){
    .setAnimationClass(); //standard 500ms animations
    .addAnimationDelayClass();



    @animations:
    fade-in ~'0%{ opacity:0; %s} 1%{ opacity:0; %s} 100%{ opacity:1; %s}' add,
    fade-in-left ~'0%{ opacity:0; transform: translate3d(-100%, 0, 0); %s} 1%{ opacity:0; transform: translate3d(-100%, 0, 0); %s} 100%{ opacity:1; transform: translate3d(0, 0, 0); %s}' add,
    fade-in-right ~'0%{ opacity:0; transform: translate3d(100%, 0, 0); %s} 1%{ opacity:0; transform: translate3d(100%, 0, 0); %s} 100%{ opacity:1; transform: translate3d(0, 0, 0); %s}' add,
    fade-out ~"0%{ opacity:1; %s} 99%{ opacity:0; %s} 100%{ opacity:0; %s}" remove,
    fade-out-grow ~"0%{ opacity:1; transform: scale(0, 0, 0); %s} 99%{ opacity:0; transform: scale(1.5, 1.5); %s} 100%{ opacity:0; transform: scale(1.5, 1.5); %s}" remove,
    fade-out-left ~"0%{ opacity:1; transform: translate3d(0, 0, 0); %s} 99%{ opacity:0; transform: translate3d(-100%, 0, 0); %s} 100%{ opacity:0; transform: translate3d(-100%, 0, 0); %s}" remove,
    fade-out-right ~"0%{ opacity:1; transform: translate3d(0, 0, 0); %s} 99%{ opacity:0; transform: translate3d(100%, 0, 0); %s} 100%{ opacity:0; transform: translate3d(100%, 0, 0); %s}" remove,
    fade-out-up ~"0%{ opacity:1; transform: translate3d(0, 0, 0); %s} 99%{ opacity:0; transform: translate3d(0, -100%, 0); %s} 100%{ opacity:0; transform: translate3d(0, -100%, 0); %s}" remove,
    fade-out-down ~"0%{ opacity:1; transform: translate3d(0, 0, 0); %s} 99%{ opacity:0; transform: translate3d(0, 100%, 0); %s} 100%{ opacity:0; transform: translate3d(0, 100%, 0); %s}" remove;

    .ivx-animation-hide{
        opacity: 0;
        max-height: 0px;
    }

    .ivx-animation-show{
        opacity: 1;
        max-height: 100vh;
    }

    .createAnimations(@animations);

    .createAnimations(@animations, @index : 1) when (@index <= length(@animations)) {
        .createAnimations(@animations, @index + 1);
        .createAnimation(extract(@animations, @index));
    }

    ._getAnimationTypeProperties(@type){
        @animationTypeProperties: "" "" "";
    }

    ._getAnimationTypeProperties(@type) when (@type = remove){
        @animationTypeProperties: "max-height: 100vh;" "max-height: 100vh;" "max-height: 0px; visibility: hidden;";
    }

    ._getAnimationTypeProperties(@type) when (@type = add){
        @animationTypeProperties: "max-height: 0px;" "max-height: 100vh;" "max-height: 100vh;";
    }

    .createAnimation(@animationInfo){
        @type : extract(@animationInfo, 1);
        @keyframe: extract(@animationInfo, 2);
        @animationType: extract(@animationInfo, 3);

        ._getAnimationTypeProperties(@animationType);
        @keyframeWithProperties: %(@keyframe, extract(@animationTypeProperties, 1), extract(@animationTypeProperties, 2), extract(@animationTypeProperties, 3));

        .keyframes(@type@keyframeWithProperties);

        .ivx-animation-@{type}{
            content: @animationType;
            .animation-name(@type);
        }
    }

    @easingFunctions: linear linear, ease-in ease-in, ease-out ease-out,ease-in-out ease-in-out, step-start step-start,  step-end  step-end;
    ._createTimingFunctions(@easingFunctions);


    .setAnimationClass(@type : default, @customAnimationSettings :{.animation-fill-mode(both); .animation-duration(500);}) when (@type = default){
        .ivx-animation{
            @customAnimationSettings();
        }
    }

    .setAnimationClass(@type, @customAnimationSettings) when not (@type = default){
        .ivx-animation-@{type}{
          @customAnimationSettings();
        }
    }

    ._createTimingFunctions(@easingFunctions, @index:1) when (@index <= length(@easingFunctions)){
        ._createTimingFunctions(@easingFunctions, @index + 1);

        @animationInfo: extract(@easingFunctions, @index);

        .addAnimationTimingFunction(@animationInfo);
    }

    .addAnimationTimingFunction(@animationInfo){
        @animationType: extract(@animationInfo, 1);
        @animationTimingFunction: extract(@animationInfo, 2);
        .ivx-animation-timing-@{animationType}{
            .animation-timing-function(@animationTimingFunction);
        }
    }

    .addAnimationDurationClass(@animationDurationType, @duration, @easing: linear) when (@easing = linear){
        .ivx-animation-duration-@{animationDurationType}{
            .animation-duration(@duration);
            .animation-timing-function(@easing);
        }
    }

    .addAnimationDurationClass(@animationDurationType, @duration, @easing) when not (@easing = linear){
        .ivx-animation-duration-@{animationDurationType}{
            .animation-duration(@duration);
            .animation-timing-function(@easing);
        }
    }

    .addAnimationDelayClass(@animationDelayType: default, @delay:500ms) when (@animationDelayType = default){
        .ivx-animation-delay{
            .animation-delay(@delay);
        }
    }

    .addAnimationDelayClass(@animationDelayType: default, @delay: 500ms) when not (@animationDelayType = default){
        .ivx-animation-delay-@{animationDelayType}{
            .animation-delay(@delay);
        }
    }
}
