/* ==========================================================================
   Timetable Animations — keyframes and transitions
   ========================================================================== */

/* --------------------------------------------------------------------------
   @keyframes — deduplicated
   (where a name was defined twice the last definition's semantics are kept,
    matching the effective behaviour of the original single-file stylesheet)
   -------------------------------------------------------------------------- */

/* Subtle opacity pulse — used by .tip-icon, .conflict-indicator, .course-preview-block */
@keyframes pulse {
    0%, 100% { opacity: 0.3; }
    50%       { opacity: 0.5; }
}

/* Warning pulse for removal-ready course blocks */
@keyframes pulse-warning {
    0%, 100% {
        transform: scale(1);
        opacity: 1;
    }
    50% {
        transform: scale(1.02);
        opacity: 0.9;
    }
}

/* Fade-out for removing-confirmed course blocks (ends fully transparent —
   it used to park at 0.3, which made removed blocks look stuck) */
@keyframes fade-out {
    0%   { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(0.96); }
}

/* Context menu entrance */
@keyframes context-menu-appear {
    0%   { opacity: 0; transform: scale(0.95) translateY(-5px); }
    100% { opacity: 1; transform: scale(1) translateY(0); }
}

/* Loading shimmer for skeleton screens */
@keyframes shimmer {
    0%   { background-position: -468px 0; }
    100% { background-position: 468px 0; }
}

/* Favorites list item slide-in */
@keyframes slideInFavorite {
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

/* Empty-state fade-up */
@keyframes fadeInUp {
    from { opacity: 0; transform: translateY(20px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Empty-state icon float */
@keyframes float {
    0%, 100% { transform: translateY(0px); }
    50%       { transform: translateY(-10px); }
}

/* Feature-icon bounce-in */
@keyframes bounceIn {
    0%   { opacity: 0; transform: scale(0.3) translateY(20px); }
    50%  { opacity: 1; transform: scale(1.05) translateY(-10px); }
    70%  { transform: scale(0.9) translateY(5px); }
    100% { opacity: 1; transform: scale(1) translateY(0); }
}

/* AI button ping ring */
@keyframes aiPulse {
    0%, 100% { opacity: 0.3; transform: scale(1); }
    50%       { opacity: 0.1; transform: scale(1.1); }
}

/* AI button entrance from bottom */
@keyframes slideInFromBottom {
    from { opacity: 0; transform: translateY(100px) scale(0.8); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Filter card slide-up entrance */
@keyframes slideInUp {
    from { opacity: 0; transform: translateY(30px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Filter card shimmer sweep */
@keyframes shimmer-filter {
    0%   { left: -100%; }
    100% { left: 100%; }
}

/* Conflict/confirm dialog fade-in */
@keyframes fadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Conflict dialog slide-in */
@keyframes slideIn {
    from { transform: translateY(-50px); opacity: 0; }
    to   { transform: translateY(0); opacity: 1; }
}

/* Conflict shake */
@keyframes conflict-shake {
    0%, 100%                        { transform: translateX(0); }
    10%, 30%, 50%, 70%, 90%         { transform: translateX(-3px); }
    20%, 40%, 60%, 80%              { transform: translateX(3px); }
}
