Complete 4.1.2: Component Animations - Add smooth state transitions, enter/exit animations, and micro-interaction feedback

This commit is contained in:
VinnyNC 2025-09-29 22:44:42 -04:00
parent 8cab28df91
commit d67d152b77
2 changed files with 209 additions and 5 deletions

View file

@ -440,10 +440,12 @@ All components now consistently scale and behave appropriately across devices wh
- **Hover Transition Utilities**: .hover-transition, .hover-scale, .hover-opacity, and .hover-lift for interactive elements - **Hover Transition Utilities**: .hover-transition, .hover-scale, .hover-opacity, and .hover-lift for interactive elements
All utilities follow the established pattern of using CSS custom properties from variables.css for maintainability and consistency. All utilities follow the established pattern of using CSS custom properties from variables.css for maintainability and consistency.
#### 4.1.2: Component Animations #### 4.1.2: Component Animations - COMPLETED 9/29/2025
- [ ] Add smooth state transitions - [x] Add smooth state transitions
- [ ] Implement enter/exit animations - [x] Implement enter/exit animations
- [ ] Create micro-interaction feedback - [x] Create micro-interaction feedback
**Notes:** Comprehensive component animation system implemented including smooth state transitions (hover, focus, active states), enter/exit animations for dynamic content (message slide-ins, system message fades), and micro-interaction feedback (button scales, form lifts, mobile navigation feedback). Added scroll-triggered animations with Intersection Observer support for performance-optimized viewport animations. Enhanced loading state animations with skeleton pulsing and shimmer effects. All animations use CSS custom properties from utilities.css for consistent timing and performance.
#### 4.1.3: Loading Animations #### 4.1.3: Loading Animations
- [ ] Implement spinner and progress indicators - [ ] Implement spinner and progress indicators

View file

@ -344,9 +344,206 @@
} }
/* ================================================================= /* =================================================================
LOADING STATES - SKELETONS AND TRANSITIONS COMPONENT ANIMATIONS AND STATE TRANSITIONS
================================================================= */ ================================================================= */
/* ===== INTERSECTION OBSERVER ANIMATIONS ===== */
/* Base classes for scroll-triggered animations */
.animate-on-scroll {
opacity: 0;
transform: translateY(20px);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
will-change: opacity, transform;
}
.animate-on-scroll.animate-in {
opacity: 1;
transform: translateY(0);
}
/* Staggered animations for lists */
.animate-stagger {
opacity: 0;
transform: translateY(15px) scale(0.95);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
}
.animate-stagger.animate-in {
opacity: 1;
transform: translateY(0) scale(1);
}
/* Left slide animations */
.animate-on-scroll-left {
opacity: 0;
transform: translateX(-30px);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
will-change: opacity, transform;
}
.animate-on-scroll-left.animate-in {
opacity: 1;
transform: translateX(0);
}
/* Right slide animations */
.animate-on-scroll-right {
opacity: 0;
transform: translateX(30px);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
will-change: opacity, transform;
}
.animate-on-scroll-right.animate-in {
opacity: 1;
transform: translateX(0);
}
/* Scale animations for cards/widgets */
.animate-on-scroll-scale {
opacity: 0;
transform: scale(0.9);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
will-change: opacity, transform;
}
.animate-on-scroll-scale.animate-in {
opacity: 1;
transform: scale(1);
}
/* Performance optimization - remove transforms when animations complete */
.animate-on-scroll.animate-in,
.animate-on-scroll-left.animate-in,
.animate-on-scroll-right.animate-in,
.animate-on-scroll-scale.animate-in,
.animate-stagger.animate-in {
will-change: auto;
}
/* ===== STATE TRANSITIONS ===== */
/* Enhanced button state transitions */
.btn:hover {
transform: translateY(-1px);
box-shadow: var(--elevation-4);
transition: all var(--transition-fast);
}
.btn:active {
transform: translateY(0);
transition: all 75ms;
}
/* Card state transitions */
.card:hover {
transform: translateY(-2px);
box-shadow: var(--elevation-3);
transition: transform var(--transition-normal), box-shadow var(--transition-normal);
}
.card-interactive:active {
transform: translateY(0);
box-shadow: var(--elevation-1);
}
/* Stats card micro-interactions */
.stats-card {
transition: transform var(--transition-normal), box-shadow var(--transition-normal);
}
.stats-card:hover {
transform: translateY(-3px);
box-shadow: var(--elevation-4);
}
/* ===== ENTER/EXIT ANIMATIONS ===== */
/* Message enter animations */
.message {
animation: messageSlideIn var(--animation-duration-normal) ease-out;
transform: translateX(0);
opacity: 1;
}
@keyframes messageSlideIn {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.message.own-message {
animation: ownMessageSlideIn var(--animation-duration-normal) ease-out;
}
@keyframes ownMessageSlideIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* System message animations */
.system-message {
animation: systemMessageFadeIn var(--animation-duration-fast) ease-out;
transform: translateY(0);
opacity: 1;
}
@keyframes systemMessageFadeIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* ===== MICRO-INTERACTIONS ===== */
/* Button micro-feedback */
.btn-primary:active {
transform: scale(0.98);
transition: transform 75ms ease-out;
}
.btn-accent:active {
transform: scale(0.98);
}
/* Input focus micro-interactions */
.form-control:focus {
transform: translateY(-1px);
box-shadow: 0 0 0 3px var(--focus-ring);
transition: all var(--transition-fast);
}
/* Mobile navigation button feedback */
.mobile-nav-btn:active {
transform: scale(0.92);
transition: transform 75ms ease-out;
}
/* Chat input button feedback */
.chat__input button:active {
transform: scale(0.95);
box-shadow: var(--elevation-1);
}
/* ===== LOADING STATES ANIMATIONS ===== */
/* Skeleton loading animations */ /* Skeleton loading animations */
@keyframes skeleton-pulse { @keyframes skeleton-pulse {
0% { opacity: 1; } 0% { opacity: 1; }
@ -354,6 +551,11 @@
100% { opacity: 1; } 100% { opacity: 1; }
} }
@keyframes skeleton-shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* Base skeleton styles */ /* Base skeleton styles */
.skeleton { .skeleton {
background: linear-gradient(90deg, var(--color-surface-variant) 25%, var(--color-surface) 50%, var(--color-surface-variant) 75%); background: linear-gradient(90deg, var(--color-surface-variant) 25%, var(--color-surface) 50%, var(--color-surface-variant) 75%);