frontend polish: add reduced-motion support, dynamic copyright, missing animation keyframes
Deploy to route.crispygoat.com / deploy (push) Successful in 4m1s
Deploy to route.crispygoat.com / deploy (push) Successful in 4m1s
- LandingPageWrapper: Use dynamic year for copyright - HeroSection: Add float-slow/float-slow-delayed keyframes, add prefers-reduced-motion media query - TuxedoVideoHero: Add reduced-motion JS guard and CSS media query for accessibility
This commit is contained in:
@@ -998,6 +998,25 @@ export default function HeroSection() {
|
|||||||
66% { transform: translate(10px, -10px); }
|
66% { transform: translate(10px, -10px); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes float-slow {
|
||||||
|
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||||
|
50% { transform: translate(25px, -30px) scale(1.02); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float-slow-delayed {
|
||||||
|
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||||
|
50% { transform: translate(-30px, 20px) scale(1.03); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.parallax-float,
|
||||||
|
.parallax-float *,
|
||||||
|
[class*="animate-"] {
|
||||||
|
animation: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes draw-route {
|
@keyframes draw-route {
|
||||||
to { stroke-dashoffset: 0; }
|
to { stroke-dashoffset: 0; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ export function Footer({ className = "" }: FooterProps) {
|
|||||||
color: "#b5b0a8",
|
color: "#b5b0a8",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
© 2025
|
© {new Date().getFullYear()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ export default function TuxedoVideoHero({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof window === "undefined" || !sectionRef.current) return;
|
if (typeof window === "undefined" || !sectionRef.current) return;
|
||||||
|
|
||||||
|
// Respect reduced motion preference
|
||||||
|
const prefersReducedMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches === true;
|
||||||
|
if (prefersReducedMotion) return;
|
||||||
|
|
||||||
const ctx = gsap.context(() => {
|
const ctx = gsap.context(() => {
|
||||||
// Scroll progress tracking
|
// Scroll progress tracking
|
||||||
ScrollTrigger.create({
|
ScrollTrigger.create({
|
||||||
@@ -466,7 +470,6 @@ export default function TuxedoVideoHero({
|
|||||||
animation: bounce 1.5s ease-in-out infinite;
|
animation: bounce 1.5s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Performance optimizations */
|
|
||||||
.parallax-float {
|
.parallax-float {
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
}
|
}
|
||||||
@@ -475,11 +478,21 @@ export default function TuxedoVideoHero({
|
|||||||
will-change: opacity, transform;
|
will-change: opacity, transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Smooth transitions */
|
|
||||||
button, a {
|
button, a {
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.parallax-float, .animate-bounce, .hero-reveal {
|
||||||
|
animation: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
.hero-reveal {
|
||||||
|
opacity: 1 !important;
|
||||||
|
transform: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user