style: improve meteor effects with glowing head, gradient trail, and smoother animation
Docker Build / Build and Push Docker Image (push) Successful in 4m24s

This commit is contained in:
2026-06-15 01:16:29 +08:00
parent 73e701e49a
commit c450214d78
+71 -21
View File
@@ -174,6 +174,7 @@ export function Hero(props: HeroProps) {
<div className='meteor meteor-3' />
<div className='meteor meteor-4' />
<div className='meteor meteor-5' />
<div className='meteor meteor-6' />
</div>
{/* Section navigation dots (desktop only) */}
@@ -414,43 +415,92 @@ export function Hero(props: HeroProps) {
/* ── Shooting stars / meteors ── */
.meteor {
position: absolute;
width: 2px;
width: 1.5px;
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;
will-change: transform, opacity, height;
}
.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 {
.meteor::before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 3px;
height: 3px;
border-radius: 50%;
background: oklch(0.85 0.12 210 / 0.9);
box-shadow:
0 0 4px 1px oklch(0.78 0.15 210 / 0.5),
0 0 12px 3px oklch(0.78 0.15 210 / 0.2);
}
.dark .meteor::before {
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);
background: oklch(0.90 0.15 210 / 0.95);
box-shadow:
0 0 6px 2px oklch(0.78 0.15 210 / 0.6),
0 0 20px 6px oklch(0.78 0.15 210 / 0.25),
0 0 40px 10px oklch(0.78 0.15 210 / 0.08);
}
.meteor::after {
content: '';
position: absolute;
top: 3px;
left: 0;
width: 100%;
border-radius: 999px;
background: linear-gradient(
to bottom,
oklch(0.78 0.15 210 / 0.6) 0%,
oklch(0.78 0.15 210 / 0.3) 20%,
oklch(0.78 0.15 210 / 0.08) 60%,
transparent 100%
);
}
.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);
background: linear-gradient(
to bottom,
oklch(0.78 0.15 210 / 0.7) 0%,
oklch(0.78 0.15 210 / 0.35) 15%,
oklch(0.78 0.15 210 / 0.1) 50%,
transparent 100%
);
}
.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; }
.meteor-1 { left: 8%; top: -2%; animation-duration: 1.8s; animation-delay: 1s; }
.meteor-2 { left: 30%; top: -2%; animation-duration: 1.5s; animation-delay: 5s; }
.meteor-3 { left: 52%; top: -2%; animation-duration: 2.0s; animation-delay: 9s; }
.meteor-4 { left: 75%; top: -2%; animation-duration: 1.6s; animation-delay: 14s; }
.meteor-5 { left: 20%; top: -2%; animation-duration: 1.9s; animation-delay: 19s; }
.meteor-6 { left: 65%; top: -2%; animation-duration: 1.7s; animation-delay: 24s; }
@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); }
0% {
height: 0;
opacity: 0;
transform: translateY(0) translateX(0) rotate(220deg);
}
8% {
opacity: 1;
}
20% {
height: 100px;
opacity: 0.9;
}
50% {
height: 160px;
opacity: 0.5;
}
80% {
height: 60px;
opacity: 0.15;
}
100% {
height: 0;
opacity: 0;
transform: translateY(700px) translateX(-200px) rotate(220deg);
}
}
@media (prefers-reduced-motion: reduce) {