feat: premium polish pass — typing effect, animated counters, ambient orbs, input glow, show/hide password, redesigned settings, Reveal animations
- Add TypewriterText component for hero heading animation - Add AnimatedCounter with scroll-triggered count-up - Add AmbientOrbs with floating gradient orbs in hero - Add input-glow focus effect, btn-shine hover effect CSS - Add show/hide password toggle on login, register, and home login forms - Redesign settings page with premium gradient cards and icon headers - Polish /me dashboard with Reveal animations, btn-shine, input-glow - Add animate-count CSS keyframe
This commit is contained in:
1 parent
5fa342018d
commit
b37b6bc2b9
10 files changed
+569
-150
No files matched your search
@@ -0,0 +1,66 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface Orb {
|
||||
id: number;
|
||||
x: number;
|
||||
y: number;
|
||||
size: number;
|
||||
delay: number;
|
||||
duration: number;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export function AmbientOrbs() {
|
||||
const [orbs, setOrbs] = useState<Orb[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const colors = [
|
||||
"var(--color-primary)",
|
||||
"var(--color-accent)",
|
||||
"color-mix(in srgb, var(--color-primary) 60%, var(--color-accent))",
|
||||
];
|
||||
const items: Orb[] = Array.from({ length: 3 }, (_, i) => ({
|
||||
id: i,
|
||||
x: 15 + Math.random() * 70,
|
||||
y: 10 + Math.random() * 70,
|
||||
size: 120 + Math.random() * 180,
|
||||
delay: Math.random() * 3,
|
||||
duration: 8 + Math.random() * 6,
|
||||
color: colors[i],
|
||||
}));
|
||||
setOrbs(items);
|
||||
}, []);
|
||||
|
||||
if (orbs.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div className="absolute inset-0 overflow-hidden pointer-events-none" style={{ zIndex: 1 }}>
|
||||
{orbs.map((orb) => (
|
||||
<div
|
||||
key={orb.id}
|
||||
className="absolute rounded-full"
|
||||
style={{
|
||||
left: `${orb.x}%`,
|
||||
top: `${orb.y}%`,
|
||||
width: orb.size,
|
||||
height: orb.size,
|
||||
background: `radial-gradient(circle, ${orb.color} 0%, transparent 70%)`,
|
||||
opacity: 0.12,
|
||||
animation: `ambient-drift-${orb.id} ${orb.duration}s ease-in-out ${orb.delay}s infinite alternate`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<style>{`
|
||||
${orbs.map((orb) => `
|
||||
@keyframes ambient-drift-${orb.id} {
|
||||
0% { transform: translate(0, 0) scale(1); }
|
||||
33% { transform: translate(${(Math.random() > 0.5 ? "" : "-") + (20 + Math.random() * 30)}px, ${(Math.random() > 0.5 ? "" : "-") + (20 + Math.random() * 30)}px) scale(${0.8 + Math.random() * 0.4}); }
|
||||
66% { transform: translate(${(Math.random() > 0.5 ? "" : "-") + (10 + Math.random() * 40)}px, ${(Math.random() > 0.5 ? "" : "-") + (15 + Math.random() * 35)}px) scale(${0.9 + Math.random() * 0.3}); }
|
||||
100% { transform: translate(0, 0) scale(1); }
|
||||
}`).join("\n")}
|
||||
`}</style>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user