Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 0 additions & 31 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@import "tailwindcss";
@custom-variant dark (&:is(.dark *));

@layer base {
:root {
Expand Down Expand Up @@ -79,33 +78,3 @@
::-webkit-scrollbar-thumb:hover {
background: hsl(var(--muted-foreground));
}

/* Hero Badge Shimmer */
@keyframes badge-shimmer {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}

.badge-shimmer {
background-image: linear-gradient(
110deg,
transparent 25%,
rgba(59, 130, 246, 0.12) 37%,
transparent 50%
);
background-size: 200% 100%;
animation: badge-shimmer 4s ease-in-out infinite;
}

.dark .badge-shimmer {
background-image: linear-gradient(
110deg,
transparent 25%,
rgba(96, 165, 250, 0.08) 37%,
transparent 50%
);
}
176 changes: 53 additions & 123 deletions components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import Link from "next/link";
import Image from "next/image";
import { useState, useEffect, useRef } from "react";
import { useState, useEffect } from "react";
import { Menu, X, Sun, Moon } from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
import { useTheme } from "next-themes";
import { useRouter, usePathname } from "next/navigation";
import { useRouter } from "next/navigation";

const navLinks = [
{
Expand All @@ -33,9 +33,6 @@ export default function Navbar() {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
const router = useRouter();
const pathname = usePathname();
const [activeSection, setActiveSection] = useState<string>("/#Home");
const isClickScrolling = useRef(false);

useEffect(() => {
const timer = setTimeout(() => {
Expand All @@ -44,34 +41,9 @@ export default function Navbar() {

const handleScroll = () => {
setScrolled(window.scrollY > 20);

if (!isClickScrolling.current) {
const sections = navLinks
.filter((link) => link.href.startsWith("/#"))
.map((link) => link.href.substring(2));

let current = "";
for (const section of sections) {
const element = document.getElementById(section);
if (element) {
const rect = element.getBoundingClientRect();
if (rect.top <= 120 && rect.bottom >= 120) {
current = section;
break;
}
}
}

if (current) {
setActiveSection(`/#${current}`);
} else if (window.scrollY < 100) {
setActiveSection("/#Home");
}
}
};

window.addEventListener("scroll", handleScroll, { passive: true });
handleScroll();

return () => {
clearTimeout(timer);
Expand All @@ -90,27 +62,16 @@ export default function Navbar() {
const element = document.getElementById(targetId);

if (element) {
isClickScrolling.current = true;
setActiveSection(href);
element.scrollIntoView({ behavior: "smooth", block: "start" });
// Close mobile menu if open
setIsOpen(false);

setTimeout(() => {
isClickScrolling.current = false;
}, 800);
} else {
// If element not found, navigate to home and then scroll
router.push("/");
setTimeout(() => {
const el = document.getElementById(targetId);
if (el) {
isClickScrolling.current = true;
setActiveSection(href);
el.scrollIntoView({ behavior: "smooth", block: "start" });
setTimeout(() => {
isClickScrolling.current = false;
}, 800);
}
}, 100);
}
Expand All @@ -119,99 +80,80 @@ export default function Navbar() {

return (
<header
className={`sticky top-0 z-50 transition-all duration-500 ${
className={`sticky top-0 z-50 transition-all duration-300 ${
scrolled
? "border-b border-border/50 dark:border-white/5 bg-background/85 dark:bg-[#0B1528]/85 shadow-sm backdrop-blur-md supports-[backdrop-filter]:bg-background/70 dark:supports-[backdrop-filter]:bg-[#0B1528]/70"
: "bg-background dark:bg-gradient-to-r dark:from-[#0B1528] dark:to-[#0A101D] border-b border-border/50 dark:border-white/5"
? "border-b border-[#00008B]/20 bg-[#00008B]/95 shadow-md backdrop-blur-xl supports-[backdrop-filter]:bg-[#00008B]/80"
: "bg-[#00008B] border-transparent"
}`}
>
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="flex h-16 md:h-[72px] items-center justify-between">
<div className="flex h-20 items-center justify-between">
{/* Logo */}
<Link
href="/"
className="group flex items-center gap-3.5 transition-opacity duration-300 hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background dark:focus-visible:ring-offset-[#0B1528] rounded-lg"
className="flex items-center gap-3 transition-opacity duration-200 hover:opacity-90"
>
<div className="relative h-10 w-10 md:h-11 md:w-11 flex-shrink-0 transition-transform duration-300 group-hover:scale-[1.02]">
<div className="relative h-12 w-12 flex-shrink-0">
<Image
src="/hl-logo.png"
alt="Hyper Learning Official Logo"
width={44}
height={44}
width={48}
height={48}
className="object-contain"
priority
/>
</div>

<div className="flex flex-col justify-center">
<span className="block text-lg md:text-[20px] font-extrabold tracking-tighter text-foreground dark:text-[#F4F5F7]">
<div>
<span className="block text-xl font-bold text-[#F4F5F7]">
Hyper Learning
</span>
<p className="text-[11px] md:text-xs font-medium text-muted-foreground dark:text-[#94A3B8] mt-0.5">

<p className="text-xs text-[#AFC8FF]">
AI-Powered Learning Platform
</p>
</div>
</Link>

{/* Desktop Navigation */}
<nav className="hidden items-center gap-2 md:flex">
{navLinks.map((link) => {
const isActive =
(pathname === "/" &&
link.href.startsWith("/#") &&
activeSection === link.href) ||
(pathname === link.href && !link.href.startsWith("/#"));

return (
<Link
key={link.label}
href={link.href}
onClick={(e) => handleNavClick(e, link.href)}
className={`relative px-3 py-1.5 text-[14px] font-medium tracking-[0.02em] transition-colors duration-200 rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50 ${
isActive
? "text-foreground dark:text-white"
: "text-muted-foreground hover:text-foreground dark:text-[#AFC8FF] dark:hover:text-white after:absolute after:bottom-[4px] after:left-3 after:right-3 after:h-[1px] after:bg-foreground/60 dark:after:bg-white/60 after:scale-x-0 after:origin-right hover:after:origin-left hover:after:scale-x-100 after:transition-transform after:duration-300 after:ease-out"
}`}
>
{isActive && (
<motion.div
className="absolute inset-0 rounded-full bg-black/[0.04] border border-black/10 dark:bg-white/[0.06] dark:border-white/10"
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.25, ease: "easeOut" }}
/>
)}
<span className="relative z-10">{link.label}</span>
</Link>
);
})}
<nav className="hidden items-center gap-8 md:flex">
{navLinks.map((link) => (
<Link
key={link.label}
href={link.href}
onClick={(e) => handleNavClick(e, link.href)}
className="text-[15px] font-medium text-[#AFC8FF] transition-all duration-200 hover:text-white"
>
{link.label}
</Link>
))}
</nav>

{/* Desktop Actions */}
<div className="hidden items-center gap-3 md:flex">
<button
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
aria-label="Toggle theme"
className="relative flex h-10 w-10 items-center justify-center rounded-full text-foreground/80 transition-colors duration-200 hover:bg-black/5 hover:text-foreground dark:text-white/90 dark:hover:bg-white/10 dark:hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50"
className="relative flex h-10 w-10 items-center justify-center text-white transition-all duration-200 hover:scale-110 hover:text-[#AFC8FF]"
>
{mounted &&
(theme === "dark" ? (
<Sun className="h-[18px] w-[18px]" />
<Sun className="h-5 w-5" />
) : (
<Moon className="h-[18px] w-[18px]" />
<Moon className="h-5 w-5" />
))}
</button>

<Link
href="/sign-in"
className="rounded-xl border border-border px-5 py-2 text-[14px] font-medium text-foreground transition-all duration-300 hover:border-border/80 hover:bg-muted dark:border-white/15 dark:text-[#F4F5F7] dark:hover:border-white/25 dark:hover:bg-white/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50"
className="rounded-xl border border-white/20 px-4 py-2 text-sm font-medium text-[#F4F5F7] transition-all duration-200 hover:border-white/40 hover:bg-white/10"
>
Sign In
</Link>

<Link
href="/subjects"
className="rounded-xl bg-[#1D4ED8] px-5 py-2 text-[14px] font-semibold text-white shadow-sm transition-all duration-300 hover:bg-[#1E40AF] hover:scale-[1.01] hover:shadow dark:bg-white dark:text-[#0B1528] dark:hover:bg-[#F4F5F7] active:scale-[0.99] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50"
className="rounded-xl bg-white px-5 py-2 text-sm font-semibold text-[#00008B] shadow-sm transition-all duration-200 hover:bg-slate-100"
>
Start Learning
</Link>
Expand All @@ -223,7 +165,7 @@ export default function Navbar() {
aria-expanded={isOpen}
aria-controls="mobile-menu"
aria-label={isOpen ? "Close menu" : "Open menu"}
className="rounded-xl p-2 text-foreground dark:text-white transition-colors hover:bg-black/5 dark:hover:bg-white/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50 md:hidden"
className="rounded-lg p-2 text-white transition-colors hover:bg-white/10 md:hidden"
>
{isOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />}
</button>
Expand All @@ -240,64 +182,52 @@ export default function Navbar() {
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: "auto" }}
exit={{ opacity: 0, height: 0 }}
transition={{ duration: 0.25, ease: "easeInOut" }}
className="overflow-hidden border-t border-border/50 dark:border-white/10 bg-background/95 dark:bg-[#0B1528]/95 backdrop-blur-md md:hidden"
transition={{ duration: 0.25 }}
className="overflow-hidden border-t border-white/10 bg-[#00008B]/95 backdrop-blur-xl md:hidden"
>
<div className="space-y-1 px-6 py-6">
{navLinks.map((link) => {
const isActive =
(pathname === "/" &&
link.href.startsWith("/#") &&
activeSection === link.href) ||
(pathname === link.href && !link.href.startsWith("/#"));

return (
<Link
key={link.label}
href={link.href}
onClick={(e) => {
handleNavClick(e, link.href);
setIsOpen(false);
}}
className={`block rounded-xl px-4 py-3 text-[15px] font-medium tracking-[0.02em] transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50 ${
isActive
? "text-foreground bg-black/5 dark:text-white dark:bg-white/5"
: "text-muted-foreground hover:bg-black/5 hover:text-foreground dark:text-[#AFC8FF] dark:hover:bg-white/5 dark:hover:text-white"
}`}
>
{link.label}
</Link>
);
})}
<div className="space-y-2 px-6 py-6">
{navLinks.map((link) => (
<Link
key={link.label}
href={link.href}
onClick={(e) => {
handleNavClick(e, link.href);
setIsOpen(false);
}}
className="block rounded-xl px-4 py-3 text-[#AFC8FF] transition-all duration-200 hover:bg-white/10 hover:text-white"
>
{link.label}
</Link>
))}

<div className="mt-6 flex flex-col gap-3 border-t border-border/50 dark:border-white/10 pt-6">
<div className="mt-4 flex flex-col gap-3">
<button
onClick={() => {
setTheme(theme === "dark" ? "light" : "dark");
setIsOpen(false);
}}
className="flex w-full items-center justify-center rounded-xl border border-border px-4 py-3 text-foreground/90 transition-all duration-200 hover:bg-black/5 hover:text-foreground dark:border-white/15 dark:text-white/90 dark:hover:bg-white/5 dark:hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50"
className="flex items-center justify-center rounded-xl border border-white/20 px-4 py-3 text-[#F4F5F7] transition-all duration-200 hover:bg-white/10"
>
{mounted &&
(theme === "dark" ? (
<Sun className="h-[18px] w-[18px]" />
<Sun className="h-5 w-5" />
) : (
<Moon className="h-[18px] w-[18px]" />
<Moon className="h-5 w-5" />
))}
</button>

<Link
href="/sign-in"
onClick={() => setIsOpen(false)}
className="w-full rounded-xl border border-border px-4 py-3 text-center text-[15px] font-medium text-foreground transition-all duration-200 hover:bg-muted dark:border-white/15 dark:text-[#F4F5F7] dark:hover:bg-white/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50"
className="rounded-xl border border-white/20 px-4 py-3 text-center text-[#F4F5F7]"
>
Sign In
</Link>

<Link
href="/subjects"
onClick={() => setIsOpen(false)}
className="w-full rounded-xl bg-[#1D4ED8] px-4 py-3 text-center text-[15px] font-semibold text-white shadow-sm transition-all duration-250 hover:bg-[#1E40AF] active:scale-[0.98] dark:bg-white dark:text-[#0B1528] dark:hover:bg-[#F4F5F7] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1D4ED8]/50 dark:focus-visible:ring-white/50"
className="rounded-xl bg-white px-4 py-3 text-center font-semibold text-[#00008B]"
>
Start Learning
</Link>
Expand Down
Loading
Loading