Animation Added and Gif file updated
This commit is contained in:
@@ -5,7 +5,7 @@ import { motion } from "framer-motion";
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="relative z-10 mt-20 sm:mt-32 bg-gradient-to-b from-black via-zinc-950 to-black border-t border-white/5">
|
||||
<footer className="relative z-10 mt-20 sm:mt-32 border-t border-white/5">
|
||||
{/* Top decorative line */}
|
||||
<div className="absolute top-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-blue-500/50 to-transparent" />
|
||||
|
||||
|
||||
@@ -1,37 +1,27 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence, stagger } from "framer-motion";
|
||||
import { Menu, X, Activity, Brain, Mic, ShieldCheck, ChevronRight, Sparkles } from "lucide-react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { Menu, X, Activity, Home,Brain, Mic, ShieldCheck, ChevronDown, Sparkles } from "lucide-react";
|
||||
|
||||
const navItems = [
|
||||
{ name: "Home", icon: Home, href: "/" },
|
||||
{ name: "Devices", icon: Activity, href: "/devices" },
|
||||
{ name: "Voice-to-SOAP", icon: Mic, href: "/#voice-soap" },
|
||||
{ name: "AI Diagnosis", icon: Brain, href: "/#diagnosis" },
|
||||
{ name: "Apps & Security", icon: ShieldCheck, href: "/apps" },
|
||||
] as const;
|
||||
|
||||
const containerVariants = {
|
||||
hidden: { opacity: 0 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
transition: { staggerChildren: 0.07, delayChildren: 0.1 },
|
||||
},
|
||||
exit: { opacity: 0, transition: { staggerChildren: 0.05, staggerDirection: -1 } },
|
||||
};
|
||||
|
||||
const itemVariants = {
|
||||
hidden: { opacity: 0, x: 40, scale: 0.96 },
|
||||
visible: { opacity: 1, x: 0, scale: 1, transition: { type: "spring", damping: 22, stiffness: 140 } },
|
||||
exit: { opacity: 0, x: 20, scale: 0.95 },
|
||||
};
|
||||
|
||||
export default function Navbar() {
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
const [activeItem, setActiveItem] = useState<number | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => setIsScrolled(window.scrollY > 20);
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 20);
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
@@ -54,7 +44,7 @@ export default function Navbar() {
|
||||
: "bg-gradient-to-r from-white/5 via-white/10 to-white/5 backdrop-blur-lg border border-white/5"
|
||||
}`}
|
||||
>
|
||||
{/* Animated background gradient (unchanged) */}
|
||||
{/* Animated background gradient */}
|
||||
<div className="absolute inset-0 rounded-2xl lg:rounded-3xl overflow-hidden pointer-events-none">
|
||||
<motion.div
|
||||
animate={{
|
||||
@@ -69,45 +59,55 @@ export default function Navbar() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Logo (unchanged) */}
|
||||
{/* Logo */}
|
||||
<a href="/" className="flex items-center gap-2 sm:gap-3 group relative z-10">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 bg-blue-500/20 blur-xl rounded-full group-hover:bg-blue-500/30 transition-all" />
|
||||
<div className="absolute inset-0 bg-cyan-500/20 blur-xl rounded-full group-hover:bg-cyan-500/30 transition-all" />
|
||||
<Activity className="w-7 h-7 sm:w-9 sm:h-9 text-white relative z-10 transition-transform group-hover:scale-110 group-hover:rotate-180 duration-500" />
|
||||
</div>
|
||||
<span className="text-xl sm:text-2xl lg:text-3xl font-bold tracking-tight text-white relative">
|
||||
Skyheal
|
||||
<span className="absolute -top-1 -right-6 text-[8px] text-blue-400 font-semibold">AI</span>
|
||||
<span className="absolute -top-1 -right-6 text-[8px] text-cyan-400 font-semibold">AI</span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
{/* Desktop Menu (unchanged) */}
|
||||
{/* Desktop Menu */}
|
||||
<div className="hidden lg:flex items-center gap-1 xl:gap-2 relative z-10">
|
||||
{navItems.map((item, index) => (
|
||||
<motion.a
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
onHoverStart={() => setActiveItem(index)}
|
||||
onHoverEnd={() => setActiveItem(null)}
|
||||
className="relative px-4 py-2.5 rounded-xl text-sm font-semibold text-zinc-300 hover:text-white transition-colors group"
|
||||
>
|
||||
<span className="relative z-10 flex items-center gap-2">
|
||||
<item.icon className="w-4 h-4 transition-transform group-hover:scale-110" />
|
||||
{item.name}
|
||||
</span>
|
||||
{/* You can keep or remove the active indicator if not needed */}
|
||||
|
||||
{activeItem === index && (
|
||||
<motion.div
|
||||
layoutId="navbar-indicator"
|
||||
className="absolute inset-0 bg-white/10 backdrop-blur-sm rounded-xl border border-white/20 pointer-events-none"
|
||||
transition={{ type: "spring", bounce: 0.2, duration: 0.6 }}
|
||||
/>
|
||||
)}
|
||||
</motion.a>
|
||||
))}
|
||||
|
||||
{/* CTA Button */}
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="ml-4 relative group overflow-hidden bg-gradient-to-r from-blue-600 to-purple-600 text-white px-6 py-2.5 rounded-xl text-sm font-bold shadow-lg shadow-blue-500/25 hover:shadow-blue-500/40 transition-all"
|
||||
className="ml-4 relative group overflow-hidden bg-gradient-to-r from-cyan-600 to-cyan-200 text-white px-6 py-2.5 rounded-xl text-sm font-bold shadow-lg shadow-cyan-500/25 hover:shadow-cyan-500/40 transition-all"
|
||||
>
|
||||
<span className="relative z-10 flex items-center gap-2">
|
||||
<Sparkles className="w-4 h-4" />
|
||||
Get Started
|
||||
</span>
|
||||
<motion.div
|
||||
className="absolute inset-0 bg-gradient-to-r from-purple-600 to-blue-600"
|
||||
className="absolute inset-0 bg-gradient-to-r from-cyan-200 to-cyan-600"
|
||||
initial={{ x: "100%" }}
|
||||
whileHover={{ x: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
@@ -115,10 +115,10 @@ export default function Navbar() {
|
||||
</motion.button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Toggle – bigger touch target */}
|
||||
{/* Mobile Toggle */}
|
||||
<motion.button
|
||||
whileTap={{ scale: 0.92 }}
|
||||
className="lg:hidden relative z-10 text-white p-3 rounded-full hover:bg-white/10 transition-colors"
|
||||
whileTap={{ scale: 0.9 }}
|
||||
className="lg:hidden relative z-10 text-white p-2 rounded-lg hover:bg-white/10 transition-colors"
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
>
|
||||
<AnimatePresence mode="wait">
|
||||
@@ -128,19 +128,19 @@ export default function Navbar() {
|
||||
initial={{ rotate: -90, opacity: 0 }}
|
||||
animate={{ rotate: 0, opacity: 1 }}
|
||||
exit={{ rotate: 90, opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<X className="w-7 h-7" />
|
||||
<X className="w-6 h-6" />
|
||||
</motion.div>
|
||||
) : (
|
||||
<motion.div
|
||||
key="menu"
|
||||
initial={{ rotate: -90, opacity: 0 }}
|
||||
initial={{ rotate: 90, opacity: 0 }}
|
||||
animate={{ rotate: 0, opacity: 1 }}
|
||||
exit={{ rotate: 90, opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
exit={{ rotate: -90, opacity: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<Menu className="w-7 h-7" />
|
||||
<Menu className="w-6 h-6" />
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
@@ -149,87 +149,72 @@ export default function Navbar() {
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* Mobile Menu – Slide from right + better visuals */}
|
||||
{/* Mobile Menu Overlay */}
|
||||
<AnimatePresence>
|
||||
{isMobileMenuOpen && (
|
||||
<>
|
||||
{/* Backdrop with subtle vignette */}
|
||||
{/* Backdrop */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
className="fixed inset-0 bg-black/70 backdrop-blur-md z-40 lg:hidden"
|
||||
transition={{ duration: 0.3 }}
|
||||
className="fixed inset-0 bg-black/60 backdrop-blur-sm z-40 lg:hidden"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
/>
|
||||
|
||||
{/* Side sheet style menu */}
|
||||
{/* Mobile Menu Content */}
|
||||
<motion.div
|
||||
initial={{ x: "100%" }}
|
||||
animate={{ x: 0 }}
|
||||
exit={{ x: "100%" }}
|
||||
transition={{ type: "spring", damping: 30, stiffness: 200 }}
|
||||
className="fixed top-0 right-0 bottom-0 w-4/5 max-w-sm z-50 lg:hidden"
|
||||
initial={{ opacity: 0, y: -20, scale: 0.95 }}
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, y: -20, scale: 0.95 }}
|
||||
transition={{ duration: 0.3, ease: "easeOut" }}
|
||||
className="fixed top-20 sm:top-24 left-4 right-4 z-50 lg:hidden"
|
||||
>
|
||||
<div className="h-full bg-gradient-to-b from-black/95 via-black/97 to-black/95 backdrop-blur-2xl border-l border-white/10 shadow-2xl flex flex-col">
|
||||
{/* Header */}
|
||||
<div className="p-6 border-b border-white/10 flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<Activity className="w-8 h-8 text-blue-400" />
|
||||
<span className="text-xl font-bold text-white tracking-tight">Skyheal</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
className="p-2 rounded-full hover:bg-white/10 transition-colors"
|
||||
>
|
||||
<X className="w-6 h-6 text-zinc-300" />
|
||||
</button>
|
||||
<div className="bg-black/95 backdrop-blur-2xl rounded-2xl border border-white/10 shadow-2xl overflow-hidden">
|
||||
{/* Menu Header */}
|
||||
<div className="p-6 border-b border-white/10 bg-gradient-to-r from-cyan-500/10 to-purple-500/10">
|
||||
<h3 className="text-sm font-semibold text-zinc-400 uppercase tracking-wider">
|
||||
Navigation
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
{/* Menu Items */}
|
||||
<motion.div
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
exit="exit"
|
||||
className="flex-1 p-6 space-y-2 overflow-y-auto"
|
||||
>
|
||||
{navItems.map((item) => (
|
||||
<div className="p-4">
|
||||
{navItems.map((item, index) => (
|
||||
<motion.a
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
variants={itemVariants}
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: index * 0.1 }}
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
className="group flex items-center gap-4 p-4 rounded-2xl hover:bg-white/5 active:bg-white/8 transition-all duration-200"
|
||||
className="flex items-center gap-4 p-4 rounded-xl hover:bg-white/5 transition-all group mb-2"
|
||||
>
|
||||
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-blue-500/10 to-purple-500/10 flex items-center justify-center border border-white/10 group-hover:border-blue-500/40 group-hover:shadow-[0_0_16px_rgba(59,130,246,0.25)] transition-all duration-300">
|
||||
<item.icon className="w-6 h-6 text-blue-400 group-hover:scale-110 transition-transform" />
|
||||
<div className="w-10 h-10 rounded-lg bg-gradient-to-br from-white/10 to-white/5 flex items-center justify-center border border-white/10 group-hover:border-white/20 transition-all">
|
||||
<item.icon className="w-5 h-5 text-white group-hover:scale-110 transition-transform" />
|
||||
</div>
|
||||
<span className="text-lg font-medium text-white group-hover:text-blue-300 transition-colors">
|
||||
{item.name}
|
||||
</span>
|
||||
<ChevronRight className="ml-auto w-5 h-5 text-zinc-500 group-hover:text-blue-400 group-hover:translate-x-1 transition-all" />
|
||||
<div className="flex-1">
|
||||
<span className="text-base font-semibold text-white group-hover:text-cyan-400 transition-colors">
|
||||
{item.name}
|
||||
</span>
|
||||
</div>
|
||||
<ChevronDown className="w-4 h-4 text-zinc-500 -rotate-90 group-hover:translate-x-1 transition-transform" />
|
||||
</motion.a>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* CTA at bottom */}
|
||||
<div className="p-6 border-t border-white/10 mt-auto">
|
||||
{/* Mobile CTA */}
|
||||
<div className="p-4 border-t border-white/10">
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.03 }}
|
||||
whileTap={{ scale: 0.97 }}
|
||||
className="w-full relative overflow-hidden bg-gradient-to-r from-blue-600 to-purple-600 text-white py-4 rounded-2xl font-semibold text-base shadow-xl shadow-blue-600/30 hover:shadow-blue-600/50 transition-all group"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.4 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
className="w-full bg-gradient-to-r from-cyan-600 to-cyan-200 text-white py-4 rounded-xl font-bold text-base shadow-lg shadow-cyan-500/25 flex items-center justify-center gap-2 hover:shadow-cyan-500/40 transition-all"
|
||||
>
|
||||
<span className="relative z-10 flex items-center justify-center gap-2.5">
|
||||
<Sparkles className="w-5 h-5" />
|
||||
Get Started Free
|
||||
</span>
|
||||
<motion.div
|
||||
className="absolute inset-0 bg-gradient-to-r from-purple-600 via-blue-600 to-purple-600 bg-[length:200%_100%]"
|
||||
initial={{ x: "100%" }}
|
||||
whileHover={{ x: "-100%" }}
|
||||
transition={{ duration: 1.2, ease: "linear" }}
|
||||
/>
|
||||
<Sparkles className="w-5 h-5" />
|
||||
Get Started Free
|
||||
</motion.button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user