:root {
    --fade-in-duration: 1.75s;
    --grow-duration: 1.75s;
    --shake-speed: 1.25s;
    --dot-cycle-duration: 1.5s; /* Total time for one complete cycle of all dots */
    --dots-shake-type: shake-dots;
    --shake-intensity: 1; /* Base intensity (1 = normal, 2 = double, 0.5 = half, etc.) */
    --shake-intensity-dots: 1;


    /* PRE-CALCULATED SHAKE VALUES */
    /* For dots (intensity = .5) */
    --shake-dots-2px: -1px;  /* -2px * 0.5 */
    --shake-dots-3px: -1.5px;  /* -3px * 0.5 */
    --shake-dots-2px-pos: 1px;  /* 2px * 0.5 */
    --shake-dots-3px-pos: 1.5px;  /* 3px * 0.5 */
    --shake-dots-0-8deg: -0.4deg;  /* -0.8deg * 0.5 */
    --shake-dots-1-2deg: 0.6deg;   /* 1.2deg * 0.5 */
    --shake-dots-0-8deg-pos: 0.4deg;  /* 0.8deg * 0.5 */


    /* Number of dots-- do not change this unless you add/remove dots */
    --dots-total: 3;
    --bubble-animation-duration: calc((var(--fade-in-duration)*var(--dots-total)) + var(--grow-duration));
    --dot-delay-interval: calc(var(--dot-cycle-duration) / var(--dots-total));
    
    --small-dot-delay: calc(var(--dot-delay-interval) * 0);
    --medium-dot-delay: calc(var(--dot-delay-interval) * 1);
    --large-dot-delay: calc(var(--dot-delay-interval) * 2);

    /* now we calculate the delay for the bubble growing animation */
    --chat-bubble-grow-delay: calc(var(--dot-delay-interval) * 1.82);
    --name-text-delay: calc(var(--dot-delay-interval) * 3);

    /* --shake-delay: calc(var(--chat-bubble-grow-delay)); */
    --shake-delay: 0s;

    /* --chat-bubble-shrink-delay: calc(calc(var(--bubble-animation-duration) - var(--grow-duration)) + 10); */

    --final-cycle-duration: 1s;
    --farewell-stagger: 1s;
}

/* Keyframes */

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes fadeOut {
    from { opacity: 1; }
    to { opacity: 0; }
}


@keyframes fadeInHalf {
    from { opacity: 0; }
    to { opacity: 0.5; }
}

@keyframes fadeOutHalf {
    from { opacity: 0.5; }
    to { opacity: 0; }
}

@keyframes chatboxGrow {
    0% { width: 0%; min-height: 0rem; padding: 0; transform: scale(1); opacity: 0; }
    50% { width: 5%; min-height: 4.5rem; padding: 0px 25px 0px 25px; opacity: .85; }
    70% { width: 100%; min-height: 5rem; padding: 15px 25px 15px 25px; opacity: 1; }
    85% { min-height: 5.2rem; transform: scaleX(1.015); }
    95% { min-height: 4.9rem; transform: scaleX(0.98); }
    100% { width: 100%; min-height: 5rem; padding: 15px 25px 15px 25px; transform: scale(1);
            opacity: 1; }
}

@keyframes nametagMarginGrow {  
    0% { 
        margin-right: 0%; 
        width: 0%; 
        transform: translateY(27px) rotate(-6deg); 
        opacity: 0;
    }
    55% {
        width: 0%; 
        opacity: 0; 
        margin-right: 0%;
    }
    70% { 
        width: 6.3rem; 
        font-size: 1.4rem; 
        opacity: 1;
        margin-right: var(--bubble-width); /* Full width minus nametag width */
    }
    80% { 
        transform: translateY(27px) rotate(-6deg) scaleX(1.015);
    }
    95% { 
        transform: translateY(27px) rotate(-6deg) scaleX(0.98);
    }
    100% { 
        margin-right: var(--bubble-width);
        transform: translateY(27px) rotate(-6deg) scale(1);
        width: 6.3rem; 
        font-size: 1.4rem; 
        opacity: 1; 
    }
}

/* maybe have it so it just collapses after bouncing and doesnt margin shrink */
@keyframes nametagMarginShrink {
    /* 0% { } */
    0% {width: 0; font-size: 0; opacity: 0; margin-right: calc(var(--bubble-width) * 0.84);}
    /* 50% { width: 0; font-size: 0; opacity: 0;} */
    70% { transform: translateY(27px) rotate(-6deg) scaleX(0.2); margin-right: calc(var(--bubble-width) * 0.99);}
    95% { transform: translateY(27px) rotate(-6deg) scaleX(1.05);}
    100% { margin-right: calc(var(--bubble-width) * 0.99); transform: translateY(27px) rotate(-6deg) scale(1);
            width: 6.3rem; font-size: 1.4rem; opacity: 1; }
}



@keyframes shake {
    0% { transform: var(--base-transform) translate(0, 0) rotate(0deg); }
    10% { transform: var(--base-transform) translate(calc(-0.5px * var(--shake-intensity)), calc(-0.5px * var(--shake-intensity))) rotate(calc(-0.2deg * var(--shake-intensity))); }
    20% { transform: var(--base-transform) translate(calc(-1px * var(--shake-intensity)), calc(0px * var(--shake-intensity))) rotate(calc(0.3deg * var(--shake-intensity))); }
    30% { transform: var(--base-transform) translate(calc(1px * var(--shake-intensity)), calc(0.5px * var(--shake-intensity))) rotate(calc(0deg * var(--shake-intensity))); }
    40% { transform: var(--base-transform) translate(calc(0.5px * var(--shake-intensity)), calc(-0.5px * var(--shake-intensity))) rotate(calc(0.2deg * var(--shake-intensity))); }
    50% { transform: var(--base-transform) translate(calc(-0.5px * var(--shake-intensity)), calc(1px * var(--shake-intensity))) rotate(calc(-0.3deg * var(--shake-intensity))); }
    60% { transform: var(--base-transform) translate(calc(-1px * var(--shake-intensity)), calc(0.5px * var(--shake-intensity))) rotate(calc(0deg * var(--shake-intensity))); }
    70% { transform: var(--base-transform) translate(calc(1px * var(--shake-intensity)), calc(0.5px * var(--shake-intensity))) rotate(calc(-0.2deg * var(--shake-intensity))); }
    80% { transform: var(--base-transform) translate(calc(-0.5px * var(--shake-intensity)), calc(-0.5px * var(--shake-intensity))) rotate(calc(0.2deg * var(--shake-intensity))); }
    90% { transform: var(--base-transform) translate(calc(0.5px * var(--shake-intensity)), calc(1px * var(--shake-intensity))) rotate(calc(0deg * var(--shake-intensity))); }
    100% { transform: var(--base-transform) translate(0, 0) rotate(0deg); }
}

/* @keyframes shake-dots {
    0% { transform: var(--base-transform) translate(0, 0) rotate(0deg); }
    10% { transform: var(--base-transform) translate(calc(-2px * var(--shake-intensity-dots)), calc(-2px * var(--shake-intensity-dots))) rotate(calc(-0.8deg * var(--shake-intensity-dots))); }
    20% { transform: var(--base-transform) translate(calc(-3px * var(--shake-intensity-dots)), calc(0px * var(--shake-intensity-dots))) rotate(calc(1.2deg * var(--shake-intensity-dots))); }
    30% { transform: var(--base-transform) translate(calc(3px * var(--shake-intensity-dots)), calc(2px * var(--shake-intensity-dots))) rotate(calc(0deg * var(--shake-intensity-dots))); }
    40% { transform: var(--base-transform) translate(calc(2px * var(--shake-intensity-dots)), calc(-2px * var(--shake-intensity-dots))) rotate(calc(0.8deg * var(--shake-intensity-dots))); }
    50% { transform: var(--base-transform) translate(calc(-2px * var(--shake-intensity-dots)), calc(3px * var(--shake-intensity-dots))) rotate(calc(-1.2deg * var(--shake-intensity-dots))); }
    60% { transform: var(--base-transform) translate(calc(-3px * var(--shake-intensity-dots)), calc(2px * var(--shake-intensity-dots))) rotate(calc(0deg * var(--shake-intensity-dots))); }
    70% { transform: var(--base-transform) translate(calc(3px * var(--shake-intensity-dots)), calc(2px * var(--shake-intensity-dots))) rotate(calc(-0.8deg * var(--shake-intensity-dots))); }
    80% { transform: var(--base-transform) translate(calc(-2px * var(--shake-intensity-dots)), calc(-2px * var(--shake-intensity-dots))) rotate(calc(0.8deg * var(--shake-intensity-dots))); }
    90% { transform: var(--base-transform) translate(calc(2px * var(--shake-intensity-dots)), calc(3px * var(--shake-intensity-dots))) rotate(calc(0deg * var(--shake-intensity-dots))); }
    100% { transform: var(--base-transform) translate(0, 0) rotate(0deg); }
} */
@keyframes fadeShakeDots {
    /* Fade in while shaking */
    0% { 
        opacity: 0; 
        transform: var(--base-transform) translate(0, 0) rotate(0deg); 
    }
    5% { 
        opacity: 0.2; 
        transform: var(--base-transform) translate(var(--shake-dots-2px), var(--shake-dots-2px)) rotate(var(--shake-dots-0-8deg)); 
    }
    10% { 
        opacity: 0.4; 
        transform: var(--base-transform) translate(var(--shake-dots-3px), 0px) rotate(var(--shake-dots-1-2deg)); 
    }
    15% { 
        opacity: 0.6; 
        transform: var(--base-transform) translate(var(--shake-dots-3px-pos), var(--shake-dots-2px-pos)) rotate(0deg); 
    }
    20% { 
        opacity: 0.8; 
        transform: var(--base-transform) translate(var(--shake-dots-2px-pos), var(--shake-dots-2px)) rotate(var(--shake-dots-0-8deg-pos)); 
    }
    25% { 
        opacity: 1; 
        transform: var(--base-transform) translate(var(--shake-dots-2px), var(--shake-dots-3px-pos)) rotate(var(--shake-dots-1-2deg)); 
    }
    /* Stay at full opacity while shaking */
    30% { transform: var(--base-transform) translate(var(--shake-dots-3px), var(--shake-dots-2px-pos)) rotate(0deg); }
    35% { transform: var(--base-transform) translate(var(--shake-dots-3px-pos), var(--shake-dots-2px-pos)) rotate(var(--shake-dots-0-8deg)); }
    40% { transform: var(--base-transform) translate(var(--shake-dots-2px), var(--shake-dots-2px)) rotate(var(--shake-dots-0-8deg-pos)); }
    45% { transform: var(--base-transform) translate(var(--shake-dots-2px-pos), var(--shake-dots-3px-pos)) rotate(0deg); }
    50% { transform: var(--base-transform) translate(0, 0) rotate(0deg); }
    /* Fade out while shaking */
    55% { 
        opacity: 0.8; 
        transform: var(--base-transform) translate(var(--shake-dots-2px), var(--shake-dots-2px)) rotate(var(--shake-dots-0-8deg)); 
    }
    60% { 
        opacity: 0.6; 
        transform: var(--base-transform) translate(var(--shake-dots-3px), 0px) rotate(var(--shake-dots-1-2deg)); 
    }
    65% { 
        opacity: 0.4; 
        transform: var(--base-transform) translate(var(--shake-dots-3px-pos), var(--shake-dots-2px-pos)) rotate(0deg); 
    }
    70% { 
        opacity: 0.2; 
        transform: var(--base-transform) translate(var(--shake-dots-2px-pos), var(--shake-dots-2px)) rotate(var(--shake-dots-0-8deg-pos)); 
    }
    100% { 
        opacity: 0; 
        transform: var(--base-transform) translate(0, 0) rotate(0deg); 
    }
}


@keyframes fadenInOut {
    0% { opacity: 0; }
    50% { opacity: 1; }
    100% { opacity: 0; }
}


/* Animation styles */

.chat-bubble-grow {
    will-change: transform, opacity;
    transform: translate3d(0, 0, 0); 
    animation: chatboxGrow var(--grow-duration) ease-in-out forwards;
    animation-fill-mode: forwards;
    animation-delay: var(--chat-bubble-grow-delay);
}
.chat-bubble-shrink {
    animation: chatboxGrow var(--grow-duration) ease-in-out reverse;
    animation-fill-mode: backwards;
}

.name-tag-text-fade-in {
    animation: fadeIn var(--grow-duration) forwards; 
    animation-delay: var(--name-text-delay);
}

.name-tag-text-fade-out {
    animation: fadeOut var(--grow-duration) forwards; 
}

.name-tag-grow{
    animation: nametagMarginGrow var(--grow-duration) ease-in-out forwards;
    animation-fill-mode: forwards;
    animation-delay: var(--chat-bubble-grow-delay);
}
.name-tag-shrink {
    animation: nametagMarginGrow var(--grow-duration) ease-in-out reverse; 
    animation-fill-mode: backwards;
}

.chat-bubble-container-shake {
    animation: shake var(--shake-speed) ease-in-out infinite;
    animation-delay: var(--shake-delay);
}

/* .fade-n-shake {
    animation: fadenInOut var(--fade-in-duration) infinite, var(--dots-shake-type) var(--shake-speed) ease-in-out infinite;
    animation-delay: var(--fade-delay), calc(var(--fade-delay) + var(--shake-delay));
} */
.fade-n-shake {
    animation: fadeShakeDots var(--fade-in-duration) ease-in-out infinite;
    animation-delay: var(--fade-delay);
    /* Force GPU layer */
    transform: translate3d(0, 0, 0); 
}


.fade-out-content {
    animation: fadeOut 0.5s ease-in-out forwards;
}



.final-fade-cycle {
    animation: finalFadeOut var(--final-cycle-duration) ease-in-out forwards, shake var(--shake-speed), ease-in-out infinite;
}

.farewell-large {
    animation-delay: 0s, calc(var(--fade-delay) + var(--shake-delay));
}

.farewell-medium {
    animation-delay: var(--farewell-stagger), calc(var(--fade-delay) + var(--shake-delay));
}

.farewell-small {
    animation-delay: calc(var(--farewell-stagger) * 2), calc(var(--fade-delay) + var(--shake-delay));
}

@keyframes finalFadeOut {
    0% { opacity: 0; }
    50% { opacity: 1; }
    100% { opacity: 0; }
}


@keyframes progress {
    0% {
        transform: translate(0, 0);
    }
    100% {
        transform: translate(-50px, 66.86px);
    }
}