feat: add shooting star meteors and drifting nebula cloud effects to homepage
Docker Build / Build and Push Docker Image (push) Failing after 4m36s
Docker Build / Build and Push Docker Image (push) Failing after 4m36s
This commit is contained in:
+114
-1
@@ -160,6 +160,22 @@ export function Hero(props: HeroProps) {
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Drifting nebula clouds */}
|
||||
<div aria-hidden className='pointer-events-none absolute inset-0 overflow-hidden'>
|
||||
<div className='nebula-cloud nebula-cloud-1' />
|
||||
<div className='nebula-cloud nebula-cloud-2' />
|
||||
<div className='nebula-cloud nebula-cloud-3' />
|
||||
</div>
|
||||
|
||||
{/* Shooting stars / meteors */}
|
||||
<div aria-hidden className='pointer-events-none absolute inset-0 overflow-hidden'>
|
||||
<div className='meteor meteor-1' />
|
||||
<div className='meteor meteor-2' />
|
||||
<div className='meteor meteor-3' />
|
||||
<div className='meteor meteor-4' />
|
||||
<div className='meteor meteor-5' />
|
||||
</div>
|
||||
|
||||
{/* Section navigation dots (desktop only) */}
|
||||
<div className='fixed right-6 top-1/2 z-30 hidden -translate-y-1/2 flex-col gap-3 lg:flex'>
|
||||
{[0, 1].map((i) => (
|
||||
@@ -340,12 +356,109 @@ export function Hero(props: HeroProps) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Marquee keyframes */}
|
||||
{/* Keyframes */}
|
||||
<style>{`
|
||||
@keyframes marquee {
|
||||
from { transform: translateX(0); }
|
||||
to { transform: translateX(-50%); }
|
||||
}
|
||||
|
||||
/* ── Nebula cloud drift ── */
|
||||
.nebula-cloud {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
filter: blur(80px);
|
||||
opacity: 0;
|
||||
animation: nebula-drift 20s ease-in-out infinite;
|
||||
}
|
||||
.dark .nebula-cloud {
|
||||
filter: blur(100px);
|
||||
}
|
||||
.nebula-cloud-1 {
|
||||
width: 500px; height: 500px;
|
||||
top: -10%; left: -5%;
|
||||
background: radial-gradient(circle, oklch(0.78 0.15 210 / 0.07) 0%, transparent 70%);
|
||||
animation-duration: 25s;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
.dark .nebula-cloud-1 {
|
||||
background: radial-gradient(circle, oklch(0.78 0.15 210 / 0.10) 0%, transparent 70%);
|
||||
}
|
||||
.nebula-cloud-2 {
|
||||
width: 400px; height: 400px;
|
||||
top: 20%; right: -8%;
|
||||
background: radial-gradient(circle, oklch(0.70 0.12 260 / 0.05) 0%, transparent 70%);
|
||||
animation-duration: 30s;
|
||||
animation-delay: -8s;
|
||||
}
|
||||
.dark .nebula-cloud-2 {
|
||||
background: radial-gradient(circle, oklch(0.70 0.12 260 / 0.08) 0%, transparent 70%);
|
||||
}
|
||||
.nebula-cloud-3 {
|
||||
width: 350px; height: 350px;
|
||||
bottom: 10%; left: 30%;
|
||||
background: radial-gradient(circle, oklch(0.65 0.10 180 / 0.04) 0%, transparent 70%);
|
||||
animation-duration: 22s;
|
||||
animation-delay: -14s;
|
||||
}
|
||||
.dark .nebula-cloud-3 {
|
||||
background: radial-gradient(circle, oklch(0.65 0.10 180 / 0.07) 0%, transparent 70%);
|
||||
}
|
||||
@keyframes nebula-drift {
|
||||
0%, 100% { opacity: 0.3; transform: translate(0, 0) scale(1); }
|
||||
25% { opacity: 0.7; transform: translate(40px, -20px) scale(1.05); }
|
||||
50% { opacity: 0.5; transform: translate(-20px, 30px) scale(0.95); }
|
||||
75% { opacity: 0.8; transform: translate(20px, 10px) scale(1.02); }
|
||||
}
|
||||
|
||||
/* ── Shooting stars / meteors ── */
|
||||
.meteor {
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
height: 0;
|
||||
background: linear-gradient(to bottom, transparent, oklch(0.78 0.15 210 / 0.8), transparent);
|
||||
border-radius: 999px;
|
||||
animation: meteor-fall linear infinite;
|
||||
opacity: 0;
|
||||
}
|
||||
.dark .meteor {
|
||||
background: linear-gradient(to bottom, transparent, oklch(0.78 0.15 210 / 0.9), oklch(0.85 0.10 210 / 0.3), transparent);
|
||||
}
|
||||
.meteor::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: oklch(0.78 0.15 210 / 0.6);
|
||||
box-shadow: 0 0 6px 2px oklch(0.78 0.15 210 / 0.3);
|
||||
}
|
||||
.dark .meteor::after {
|
||||
background: oklch(0.85 0.15 210 / 0.8);
|
||||
box-shadow: 0 0 8px 3px oklch(0.78 0.15 210 / 0.4);
|
||||
}
|
||||
.meteor-1 { left: 12%; top: -5%; animation-duration: 3.2s; animation-delay: 0.5s; }
|
||||
.meteor-2 { left: 35%; top: -5%; animation-duration: 2.8s; animation-delay: 4s; }
|
||||
.meteor-3 { left: 58%; top: -5%; animation-duration: 3.5s; animation-delay: 8s; }
|
||||
.meteor-4 { left: 78%; top: -5%; animation-duration: 2.5s; animation-delay: 12s; }
|
||||
.meteor-5 { left: 25%; top: -5%; animation-duration: 3.0s; animation-delay: 17s; }
|
||||
@keyframes meteor-fall {
|
||||
0% { height: 0; opacity: 0; transform: translateY(0) rotate(215deg); }
|
||||
5% { opacity: 1; }
|
||||
30% { height: 80px; opacity: 1; }
|
||||
70% { height: 120px; opacity: 0.6; }
|
||||
100% { height: 0; opacity: 0; transform: translateY(600px) rotate(215deg); }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.nebula-cloud, .meteor {
|
||||
animation: none !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
</section>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user