feat: UI animation enhancements across all major pages
P1 - Critical UX feedback: - Add scale-in + slide-up-in entrance animations to profile popover and notification panel - Port SmoothedProgressBar to EcommercePage (4 generation tools: clone, detail, tryOn, productSet) - Add result-reveal stagger animation to ecommerce result grids - Add heart-pop spring animation to CommunityPage favorite toggle P2 - Visual polish: - Add scroll-entrance IntersectionObserver animations for HomePage feature sections and experience section - Add chat-message-in entrance animation to WorkbenchPage message rows - Fix prefers-reduced-motion accessibility in WelcomeSplash canvas (skip animation, instant entry) P3 - CSS consolidation: - Remove conflicting .page-motion definition from legacy-pages.css (keep translateY version from legacy-components.css) - Consolidate skeleton-shimmer: remove opacity-pulse keyframe from primitives.css, unify with gradient sweep - Wire up --ease-spring token for heart-pop animation - Add :active press states (scale 0.97) to topbar buttons, brand lockup Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -48,6 +48,9 @@
|
||||
background: var(--surface-elevated);
|
||||
box-shadow: var(--shadow-elevated);
|
||||
backdrop-filter: none;
|
||||
transform-origin: top right;
|
||||
animation: scale-in 150ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both,
|
||||
slide-up-in 150ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
||||
}
|
||||
|
||||
.profile-popover__head {
|
||||
|
||||
@@ -39,6 +39,78 @@
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
/* Popover / panel entrance utilities */
|
||||
.panel-enter {
|
||||
animation: scale-in 150ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both,
|
||||
slide-up-in 150ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
||||
}
|
||||
|
||||
.backdrop-enter {
|
||||
animation: backdrop-in 140ms ease both;
|
||||
}
|
||||
|
||||
/* Heart toggle spring animation */
|
||||
@keyframes heart-pop {
|
||||
0% { transform: scale(1); }
|
||||
40% { transform: scale(1.3); }
|
||||
70% { transform: scale(0.9); }
|
||||
100% { transform: scale(1); }
|
||||
}
|
||||
|
||||
.heart-animate {
|
||||
animation: heart-pop 420ms var(--ease-spring, cubic-bezier(0.34, 1.2, 0.64, 1)) both;
|
||||
}
|
||||
|
||||
/* Result reveal stagger for generation output grids */
|
||||
.result-reveal > * {
|
||||
opacity: 0;
|
||||
animation: slide-up-in 320ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
||||
}
|
||||
|
||||
.result-reveal > *:nth-child(1) { animation-delay: 0ms; }
|
||||
.result-reveal > *:nth-child(2) { animation-delay: 80ms; }
|
||||
.result-reveal > *:nth-child(3) { animation-delay: 160ms; }
|
||||
.result-reveal > *:nth-child(4) { animation-delay: 240ms; }
|
||||
.result-reveal > *:nth-child(5) { animation-delay: 320ms; }
|
||||
.result-reveal > *:nth-child(n+6) { animation-delay: 400ms; }
|
||||
|
||||
/* Scroll-triggered entrance: hidden until revealed by IntersectionObserver */
|
||||
.scroll-entrance {
|
||||
opacity: 0;
|
||||
transform: translateY(16px);
|
||||
transition: opacity 480ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)),
|
||||
transform 480ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
|
||||
}
|
||||
|
||||
.scroll-entrance.is-visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.scroll-entrance.is-visible > * {
|
||||
animation: slide-up-in 380ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
||||
}
|
||||
|
||||
.scroll-entrance.is-visible > *:nth-child(1) { animation-delay: 60ms; }
|
||||
.scroll-entrance.is-visible > *:nth-child(2) { animation-delay: 140ms; }
|
||||
.scroll-entrance.is-visible > *:nth-child(3) { animation-delay: 220ms; }
|
||||
|
||||
/* Chat message entrance animation */
|
||||
@keyframes chat-message-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.chat-message-enter {
|
||||
animation: chat-message-in 220ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
||||
}
|
||||
|
||||
/* Stagger utility: apply to parent, children get delayed entrance */
|
||||
.motion-stagger > * {
|
||||
animation: list-item-in 280ms var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
width: 40%;
|
||||
height: 24px;
|
||||
border-radius: 8px;
|
||||
background: var(--surface-elevated, #222);
|
||||
background: linear-gradient(90deg, rgba(255,255,255,0.04), rgba(255,255,255,0.1), rgba(255,255,255,0.04));
|
||||
background-size: 220% 100%;
|
||||
animation: skeleton-shimmer 1.4s ease infinite;
|
||||
}
|
||||
|
||||
@@ -42,7 +43,8 @@
|
||||
flex: 1;
|
||||
height: 140px;
|
||||
border-radius: 14px;
|
||||
background: var(--surface-elevated, #222);
|
||||
background: linear-gradient(90deg, rgba(255,255,255,0.04), rgba(255,255,255,0.1), rgba(255,255,255,0.04));
|
||||
background-size: 220% 100%;
|
||||
animation: skeleton-shimmer 1.4s ease infinite;
|
||||
animation-delay: 0.15s;
|
||||
}
|
||||
@@ -51,16 +53,12 @@
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
border-radius: 14px;
|
||||
background: var(--surface-elevated, #222);
|
||||
background: linear-gradient(90deg, rgba(255,255,255,0.04), rgba(255,255,255,0.1), rgba(255,255,255,0.04));
|
||||
background-size: 220% 100%;
|
||||
animation: skeleton-shimmer 1.4s ease infinite;
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
|
||||
@keyframes skeleton-shimmer {
|
||||
0%, 100% { opacity: 0.4; }
|
||||
50% { opacity: 0.7; }
|
||||
}
|
||||
|
||||
.page-transition-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
Reference in New Issue
Block a user