UI performance and Mobile responsiveness

This commit is contained in:
root 2026-02-15 12:08:28 +05:00
parent c15b7d8ab7
commit 9d02c62292
13 changed files with 341 additions and 42 deletions

26
package-lock.json generated
View File

@ -24,6 +24,7 @@
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"dotenv": "^17.2.4", "dotenv": "^17.2.4",
"framer-motion": "^12.33.0", "framer-motion": "^12.33.0",
"lenis": "^1.3.17",
"lucide-react": "^0.563.0", "lucide-react": "^0.563.0",
"mammoth": "^1.11.0", "mammoth": "^1.11.0",
"next": "16.1.6", "next": "16.1.6",
@ -7328,6 +7329,31 @@
"node": ">=0.10" "node": ">=0.10"
} }
}, },
"node_modules/lenis": {
"version": "1.3.17",
"resolved": "https://registry.npmjs.org/lenis/-/lenis-1.3.17.tgz",
"integrity": "sha512-k9T9rgcxne49ggJOvXCraWn5dt7u2mO+BNkhyu6yxuEnm9c092kAW5Bus5SO211zUvx7aCCEtzy9UWr0RB+oJw==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/darkroomengineering"
},
"peerDependencies": {
"@nuxt/kit": ">=3.0.0",
"react": ">=17.0.0",
"vue": ">=3.0.0"
},
"peerDependenciesMeta": {
"@nuxt/kit": {
"optional": true
},
"react": {
"optional": true
},
"vue": {
"optional": true
}
}
},
"node_modules/levn": { "node_modules/levn": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",

View File

@ -26,6 +26,7 @@
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"dotenv": "^17.2.4", "dotenv": "^17.2.4",
"framer-motion": "^12.33.0", "framer-motion": "^12.33.0",
"lenis": "^1.3.17",
"lucide-react": "^0.563.0", "lucide-react": "^0.563.0",
"mammoth": "^1.11.0", "mammoth": "^1.11.0",
"next": "16.1.6", "next": "16.1.6",

View File

@ -67,7 +67,7 @@ export default function AboutPage() {
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
transition={{ delay: 0.2 }} transition={{ delay: 0.2 }}
className="max-w-3xl mx-auto text-xl text-slate-400 font-medium leading-relaxed" className="max-w-3xl mx-auto text-xl text-slate-300 font-medium leading-relaxed"
> >
We started JUNOHUB with a simple belief: the global supply chain is broken, and We started JUNOHUB with a simple belief: the global supply chain is broken, and
technology is the only way to fix it. We're building the infrastructure for a technology is the only way to fix it. We're building the infrastructure for a
@ -87,7 +87,7 @@ export default function AboutPage() {
transition={{ duration: 0.8 }} transition={{ duration: 0.8 }}
> >
<h2 className="text-4xl font-black text-white mb-8 tracking-tighter uppercase">Our Vision</h2> <h2 className="text-4xl font-black text-white mb-8 tracking-tighter uppercase">Our Vision</h2>
<div className="space-y-6 text-slate-400 font-medium text-lg leading-relaxed"> <div className="space-y-6 text-slate-300 font-medium text-lg leading-relaxed">
<p> <p>
Every day, millions of dollars are lost due to inefficient communication, Every day, millions of dollars are lost due to inefficient communication,
lost inventory data, and slow synchronization. lost inventory data, and slow synchronization.
@ -115,7 +115,7 @@ export default function AboutPage() {
<div key={item.label} className={`p-8 rounded-3xl bg-white/[0.03] border border-white/10 text-center ${i % 2 !== 0 ? 'mt-8' : ''}`}> <div key={item.label} className={`p-8 rounded-3xl bg-white/[0.03] border border-white/10 text-center ${i % 2 !== 0 ? 'mt-8' : ''}`}>
<item.icon className="w-8 h-8 text-indigo-400 mx-auto mb-4" /> <item.icon className="w-8 h-8 text-indigo-400 mx-auto mb-4" />
<div className="text-2xl font-black text-white">{item.value}</div> <div className="text-2xl font-black text-white">{item.value}</div>
<div className="text-[10px] font-bold text-slate-500 uppercase tracking-widest">{item.label}</div> <div className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{item.label}</div>
</div> </div>
))} ))}
</motion.div> </motion.div>
@ -141,7 +141,7 @@ export default function AboutPage() {
<v.icon className="w-7 h-7 text-white" /> <v.icon className="w-7 h-7 text-white" />
</div> </div>
<h3 className="text-xl font-black text-white mb-4 uppercase tracking-tight">{v.title}</h3> <h3 className="text-xl font-black text-white mb-4 uppercase tracking-tight">{v.title}</h3>
<p className="text-slate-400 text-sm font-medium leading-relaxed">{v.description}</p> <p className="text-slate-300 text-sm font-medium leading-relaxed">{v.description}</p>
</motion.div> </motion.div>
))} ))}
</div> </div>
@ -156,7 +156,7 @@ export default function AboutPage() {
viewport={{ once: true }} viewport={{ once: true }}
> >
<h2 className="text-5xl md:text-7xl font-black text-white mb-8 tracking-tighter uppercase">Join the Movement</h2> <h2 className="text-5xl md:text-7xl font-black text-white mb-8 tracking-tighter uppercase">Join the Movement</h2>
<p className="text-slate-400 font-medium mb-12 max-w-2xl mx-auto text-lg leading-relaxed"> <p className="text-slate-300 font-medium mb-12 max-w-2xl mx-auto text-lg leading-relaxed">
We&apos;re always looking for ambitious vendors and suppliers to join our We&apos;re always looking for ambitious vendors and suppliers to join our
expanding ecosystem. Let&apos;s build the future together. expanding ecosystem. Let&apos;s build the future together.
</p> </p>

View File

@ -24,6 +24,7 @@ export const viewport = {
import { Providers } from "@/components/providers"; import { Providers } from "@/components/providers";
import { ErrorBoundary } from "@/components/ErrorBoundary"; import { ErrorBoundary } from "@/components/ErrorBoundary";
import { SmoothScroll } from "@/components/SmoothScroll";
export default function RootLayout({ export default function RootLayout({
children, children,
@ -33,10 +34,14 @@ export default function RootLayout({
return ( return (
<html lang="en"> <html lang="en">
<body <body
className={`${geistSans.variable} ${geistMono.variable} antialiased`} className={`${geistSans.variable} ${geistMono.variable} antialiased selection:bg-indigo-500/30`}
> >
<ErrorBoundary> <ErrorBoundary>
<Providers>{children}</Providers> <Providers>
<SmoothScroll>
{children}
</SmoothScroll>
</Providers>
</ErrorBoundary> </ErrorBoundary>
</body> </body>
</html> </html>

View File

@ -1,21 +1,34 @@
import { auth } from "@/auth" "use client"
import { useMediaQuery } from "@/hooks/useMediaQuery"
import { LandingNavbar } from "@/components/landing/LandingNavbar" import { LandingNavbar } from "@/components/landing/LandingNavbar"
import { LandingHero } from "@/components/landing/LandingHero" import { LandingHero } from "@/components/landing/LandingHero"
import { LandingFeatures } from "@/components/landing/LandingFeatures" import { LandingFeatures } from "@/components/landing/LandingFeatures"
import { LandingSolutions } from "@/components/landing/LandingSolutions" import { LandingSolutions } from "@/components/landing/LandingSolutions"
import { LandingFooter } from "@/components/landing/LandingFooter" import { LandingFooter } from "@/components/landing/LandingFooter"
import { MobileHero } from "@/components/landing/mobile/MobileHero"
import { MobileFeatures } from "@/components/landing/mobile/MobileFeatures"
export default async function HomePage() { export default function HomePage() {
const session = await auth() const isMobile = useMediaQuery("(max-width: 768px)")
const isLoggedIn = !!session
return ( return (
<div className="min-h-screen bg-[#0a0e1a] selection:bg-indigo-500/30"> <div className="min-h-screen bg-[#0a0e1a] selection:bg-indigo-500/30">
<LandingNavbar isLoggedIn={isLoggedIn} /> <LandingNavbar isLoggedIn={false} />
<main> <main>
{isMobile ? (
<>
<MobileHero />
<MobileFeatures />
<LandingSolutions />
</>
) : (
<>
<LandingHero /> <LandingHero />
<LandingFeatures /> <LandingFeatures />
<LandingSolutions /> <LandingSolutions />
</>
)}
</main> </main>
<LandingFooter /> <LandingFooter />
</div> </div>

View File

@ -0,0 +1,32 @@
"use client"
import { useEffect } from 'react'
import Lenis from 'lenis'
export function SmoothScroll({ children }: { children: React.ReactNode }) {
useEffect(() => {
const lenis = new Lenis({
duration: 1.2,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
orientation: 'vertical',
gestureOrientation: 'vertical',
smoothWheel: true,
wheelMultiplier: 1,
touchMultiplier: 2,
infinite: false,
})
function raf(time: number) {
lenis.raf(time)
requestAnimationFrame(raf)
}
requestAnimationFrame(raf)
return () => {
lenis.destroy()
}
}, [])
return <>{children}</>
}

View File

@ -8,7 +8,7 @@ export function LandingFooter() {
return ( return (
<footer className="py-20 border-t border-white/5 relative overflow-hidden"> <footer className="py-20 border-t border-white/5 relative overflow-hidden">
{/* Background Glow */} {/* Background Glow */}
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-[800px] h-[300px] bg-indigo-600/10 blur-[120px] rounded-full -z-10" /> <div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-[800px] h-[300px] bg-indigo-600/10 blur-[120px] rounded-full -z-10 will-change-transform" />
<div className="container mx-auto px-6"> <div className="container mx-auto px-6">
<div className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-16"> <div className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-16">
@ -19,17 +19,17 @@ export function LandingFooter() {
</div> </div>
<span className="text-xl font-black tracking-tighter text-white">JUNOHUB</span> <span className="text-xl font-black tracking-tighter text-white">JUNOHUB</span>
</Link> </Link>
<p className="text-slate-500 font-medium mb-8"> <p className="text-slate-300 font-medium mb-8">
The next generation of supply chain connectivity. Secure, encrypted, and real-time. The next generation of supply chain connectivity. Secure, encrypted, and real-time.
</p> </p>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<a href="#" className="p-2 rounded-lg bg-white/5 border border-white/10 text-slate-400 hover:text-white hover:bg-white/10 transition-all"> <a href="#" aria-label="Follow us on Twitter" className="p-2 rounded-lg bg-white/5 border border-white/10 text-slate-300 hover:text-white hover:bg-white/10 transition-all">
<Twitter className="w-5 h-5" /> <Twitter className="w-5 h-5" />
</a> </a>
<a href="#" className="p-2 rounded-lg bg-white/5 border border-white/10 text-slate-400 hover:text-white hover:bg-white/10 transition-all"> <a href="#" aria-label="Connect on LinkedIn" className="p-2 rounded-lg bg-white/5 border border-white/10 text-slate-300 hover:text-white hover:bg-white/10 transition-all">
<Linkedin className="w-5 h-5" /> <Linkedin className="w-5 h-5" />
</a> </a>
<a href="#" className="p-2 rounded-lg bg-white/5 border border-white/10 text-slate-400 hover:text-white hover:bg-white/10 transition-all"> <a href="#" aria-label="View our GitHub" className="p-2 rounded-lg bg-white/5 border border-white/10 text-slate-300 hover:text-white hover:bg-white/10 transition-all">
<Github className="w-5 h-5" /> <Github className="w-5 h-5" />
</a> </a>
</div> </div>
@ -38,25 +38,25 @@ export function LandingFooter() {
<div> <div>
<h4 className="text-white font-black uppercase tracking-widest text-sm mb-6">Platform</h4> <h4 className="text-white font-black uppercase tracking-widest text-sm mb-6">Platform</h4>
<ul className="space-y-4"> <ul className="space-y-4">
<li><Link href="/platform" className="text-slate-500 hover:text-indigo-400 transition-colors font-medium">Features</Link></li> <li><Link href="/platform" className="text-slate-300 hover:text-indigo-400 transition-colors font-medium">Features</Link></li>
<li><Link href="/platform" className="text-slate-500 hover:text-indigo-400 transition-colors font-medium">Shopify Sync</Link></li> <li><Link href="/platform" className="text-slate-300 hover:text-indigo-400 transition-colors font-medium">Shopify Sync</Link></li>
<li><Link href="/platform" className="text-slate-500 hover:text-indigo-400 transition-colors font-medium">Security</Link></li> <li><Link href="/platform" className="text-slate-300 hover:text-indigo-400 transition-colors font-medium">Security</Link></li>
<li><Link href="/platform" className="text-slate-500 hover:text-indigo-400 transition-colors font-medium">API</Link></li> <li><Link href="/platform" className="text-slate-300 hover:text-indigo-400 transition-colors font-medium">API</Link></li>
</ul> </ul>
</div> </div>
<div> <div>
<h4 className="text-white font-black uppercase tracking-widest text-sm mb-6">Company</h4> <h4 className="text-white font-black uppercase tracking-widest text-sm mb-6">Company</h4>
<ul className="space-y-4"> <ul className="space-y-4">
<li><Link href="/about" className="text-slate-500 hover:text-indigo-400 transition-colors font-medium">About Us</Link></li> <li><Link href="/about" className="text-slate-300 hover:text-indigo-400 transition-colors font-medium">About Us</Link></li>
<li><Link href="/privacy-policy" className="text-slate-500 hover:text-indigo-400 transition-colors font-medium">Privacy Policy</Link></li> <li><Link href="/privacy-policy" className="text-slate-300 hover:text-indigo-400 transition-colors font-medium">Privacy Policy</Link></li>
<li><Link href="/terms-of-service" className="text-slate-500 hover:text-indigo-400 transition-colors font-medium">Terms of Service</Link></li> <li><Link href="/terms-of-service" className="text-slate-300 hover:text-indigo-400 transition-colors font-medium">Terms of Service</Link></li>
</ul> </ul>
</div> </div>
<div> <div>
<h4 className="text-white font-black uppercase tracking-widest text-sm mb-6">Newsletter</h4> <h4 className="text-white font-black uppercase tracking-widest text-sm mb-6">Newsletter</h4>
<p className="text-slate-500 font-medium mb-6">Stay updated with the latest in supply chain tech.</p> <p className="text-slate-300 font-medium mb-6">Stay updated with the latest in supply chain tech.</p>
{/* Status Message */} {/* Status Message */}
<form <form
@ -113,6 +113,7 @@ export function LandingFooter() {
/> />
<button <button
type="submit" type="submit"
aria-label="Subscribe to newsletter"
className="bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white p-3 rounded-xl transition-all active:scale-95 shadow-lg shadow-indigo-600/20" className="bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white p-3 rounded-xl transition-all active:scale-95 shadow-lg shadow-indigo-600/20"
> >
<Mail className="w-5 h-5" /> <Mail className="w-5 h-5" />
@ -124,13 +125,13 @@ export function LandingFooter() {
</div> </div>
<div className="pt-8 border-t border-white/5 flex flex-col md:flex-row items-center justify-between gap-4"> <div className="pt-8 border-t border-white/5 flex flex-col md:flex-row items-center justify-between gap-4">
<p className="text-sm text-slate-600 font-medium"> <p className="text-sm text-slate-400 font-medium">
© 2026 JUNOHUB. All rights reserved. © 2026 JUNOHUB. All rights reserved.
</p> </p>
<div className="flex items-center gap-6"> <div className="flex items-center gap-6">
<Link href="/terms-of-service" className="text-xs text-slate-600 hover:text-slate-400 font-bold uppercase tracking-widest">Terms</Link> <Link href="/terms-of-service" className="text-xs text-slate-400 hover:text-indigo-300 font-bold uppercase tracking-widest">Terms</Link>
<Link href="/privacy-policy" className="text-xs text-slate-600 hover:text-slate-400 font-bold uppercase tracking-widest">Privacy</Link> <Link href="/privacy-policy" className="text-xs text-slate-400 hover:text-indigo-300 font-bold uppercase tracking-widest">Privacy</Link>
<Link href="/cookies" className="text-xs text-slate-600 hover:text-slate-400 font-bold uppercase tracking-widest">Cookies</Link> <Link href="/cookies" className="text-xs text-slate-400 hover:text-indigo-300 font-bold uppercase tracking-widest">Cookies</Link>
</div> </div>
</div> </div>
</div> </div>

View File

@ -22,9 +22,9 @@ export function LandingHero() {
className="relative min-h-screen flex items-center justify-center pt-20 overflow-hidden" className="relative min-h-screen flex items-center justify-center pt-20 overflow-hidden"
> >
{/* Background Decorative Elements */} {/* Background Decorative Elements */}
<div className="absolute inset-0 z-0"> <div className="absolute inset-0 z-0 pointer-events-none">
<div className="absolute top-1/4 left-1/4 w-96 h-96 bg-indigo-600/20 blur-[120px] rounded-full animate-pulse" /> <div className="absolute top-1/4 left-1/4 w-96 h-96 bg-indigo-600/20 blur-[120px] rounded-full animate-pulse will-change-[transform,opacity]" />
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-purple-600/20 blur-[120px] rounded-full animate-pulse delay-700" /> <div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-purple-600/20 blur-[120px] rounded-full animate-pulse delay-700 will-change-[transform,opacity]" />
</div> </div>
{/* Grid Pattern */} {/* Grid Pattern */}
@ -54,9 +54,9 @@ export function LandingHero() {
{/* Main Heading */} {/* Main Heading */}
<motion.h1 <motion.h1
initial={{ opacity: 0, y: 30 }} initial={{ opacity: 1, y: 30 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.2 }} transition={{ duration: 0.8 }}
className="text-5xl md:text-8xl font-black tracking-tighter text-white mb-8 leading-[0.9]" className="text-5xl md:text-8xl font-black tracking-tighter text-white mb-8 leading-[0.9]"
> >
THE PULSE OF <br /> THE PULSE OF <br />
@ -67,8 +67,8 @@ export function LandingHero() {
<motion.p <motion.p
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
transition={{ duration: 1, delay: 0.4 }} transition={{ duration: 1, delay: 0.2 }}
className="max-w-2xl mx-auto text-lg md:text-xl text-slate-400 font-medium mb-12 leading-relaxed" className="max-w-2xl mx-auto text-lg md:text-xl text-slate-300 font-medium mb-12 leading-relaxed"
> >
Bridge the gap between vendors and suppliers with the world&apos;s most advanced Bridge the gap between vendors and suppliers with the world&apos;s most advanced
encrypted ecosystem. Sync Shopify, chat securely, and scale effortlessly. encrypted ecosystem. Sync Shopify, chat securely, and scale effortlessly.
@ -135,7 +135,7 @@ export function LandingHero() {
className="absolute top-0 left-0 w-full h-1/3 bg-indigo-500" className="absolute top-0 left-0 w-full h-1/3 bg-indigo-500"
/> />
</div> </div>
<span className="text-[10px] font-black uppercase tracking-[0.3em] text-slate-500">Scroll</span> <span className="text-[10px] font-black uppercase tracking-[0.3em] text-slate-400">Scroll</span>
</motion.div> </motion.div>
</section> </section>
) )

View File

@ -57,7 +57,7 @@ export function LandingNavbar({ isLoggedIn }: LandingNavbarProps) {
<Link <Link
key={link.name} key={link.name}
href={link.href} href={link.href}
className="text-sm font-bold text-slate-400 hover:text-white transition-colors" className="text-sm font-bold text-slate-300 hover:text-indigo-400 transition-colors"
> >
{link.name} {link.name}
</Link> </Link>
@ -84,6 +84,8 @@ export function LandingNavbar({ isLoggedIn }: LandingNavbarProps) {
<button <button
className="md:hidden text-white p-1" className="md:hidden text-white p-1"
onClick={() => setMobileMenuOpen(!mobileMenuOpen)} onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
aria-label={mobileMenuOpen ? "Close menu" : "Open menu"}
aria-expanded={mobileMenuOpen}
> >
{mobileMenuOpen ? <X /> : <Menu />} {mobileMenuOpen ? <X /> : <Menu />}
</button> </button>

View File

@ -57,7 +57,7 @@ export function LandingSolutions() {
{sol.title} {sol.title}
</h3> </h3>
<p className="text-slate-400 font-medium mb-8 text-lg"> <p className="text-slate-300 font-medium mb-8 text-lg">
{sol.description} {sol.description}
</p> </p>

View File

@ -0,0 +1,109 @@
"use client"
import { motion } from "framer-motion"
import {
Zap,
MessageSquare,
BarChart3,
ShieldCheck,
LayoutDashboard,
RefreshCcw,
ArrowRight
} from "lucide-react"
import Link from "next/link"
const features = [
{
title: "Shopify Sync",
icon: RefreshCcw,
color: "text-emerald-400",
bg: "bg-emerald-500/10",
size: "col-span-1"
},
{
title: "E2E Chat",
icon: MessageSquare,
color: "text-blue-400",
bg: "bg-blue-500/10",
size: "col-span-1"
},
{
title: "High Octane Analytics",
icon: BarChart3,
color: "text-purple-400",
bg: "bg-purple-500/10",
size: "col-span-2"
},
{
title: "Dashboard",
icon: LayoutDashboard,
color: "text-orange-400",
bg: "bg-orange-500/10",
size: "col-span-1"
},
{
title: "Security",
icon: ShieldCheck,
color: "text-red-400",
bg: "bg-red-500/10",
size: "col-span-1"
},
{
title: "Global Scalability",
icon: Zap,
color: "text-yellow-400",
bg: "bg-yellow-500/10",
size: "col-span-2"
}
]
export function MobileFeatures() {
return (
<section className="py-24 px-6 bg-[#0a0e1a] relative overflow-hidden">
{/* Decorative lines */}
<div className="absolute top-0 left-0 w-full h-[1px] bg-gradient-to-r from-transparent via-white/10 to-transparent" />
<div className="mb-16 text-center">
<motion.div
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
className="text-[10px] font-black text-indigo-400 uppercase tracking-[0.4em] mb-4"
>
Infrastructure
</motion.div>
<h2 className="text-4xl font-black text-white mb-6 tracking-tighter uppercase italic">Dominance.</h2>
<div className="w-12 h-1 bg-indigo-600 mx-auto rounded-full" />
</div>
<div className="grid grid-cols-2 gap-4">
{features.map((f, i) => (
<motion.div
key={f.title}
initial={{ opacity: 1, scale: 0.95 }}
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true }}
transition={{ delay: i * 0.05 }}
className={`${f.size} p-8 rounded-[2rem] border border-white/5 bg-white/[0.02] flex flex-col items-center justify-center text-center relative overflow-hidden group active:bg-white/5 transition-colors`}
>
{/* Glow */}
<div className={`absolute -top-4 -right-4 w-16 h-16 ${f.bg} blur-[30px] opacity-20`} />
<div className={`w-14 h-14 rounded-[1.25rem] ${f.bg} flex items-center justify-center mb-4 border border-white/5 shadow-inner`}>
<f.icon className={`w-7 h-7 ${f.color}`} />
</div>
<h3 className="text-xs font-black text-white uppercase tracking-widest">{f.title}</h3>
</motion.div>
))}
</div>
<div className="mt-20 p-8 rounded-[2.5rem] bg-gradient-to-br from-indigo-600 to-purple-600 text-center relative overflow-hidden">
<div className="absolute top-0 right-0 w-32 h-32 bg-white/10 blur-[40px] rounded-full" />
<h3 className="text-2xl font-black text-white mb-4 uppercase italic">Ready to sync?</h3>
<p className="text-indigo-100 text-sm font-medium mb-8 opacity-90">Join the thousands of vendors scaling with JUNOHUB.</p>
<Link href="/signup" className="inline-flex items-center gap-2 px-8 py-4 bg-white text-indigo-600 rounded-2xl font-black text-sm uppercase tracking-wider shadow-lg">
Get Started <ArrowRight className="w-4 h-4" />
</Link>
</div>
</section>
)
}

View File

@ -0,0 +1,91 @@
"use client"
import { motion } from "framer-motion"
import { ArrowRight, Play, ShieldCheck, Zap, Globe, MessageSquare } from "lucide-react"
import Link from "next/link"
const stats = [
{ label: "AES-250 READY", icon: ShieldCheck },
{ label: "SHOPIFY SYNC", icon: Zap },
{ label: "120+ COUNTRIES", icon: Globe },
{ label: "E2E CHAT", icon: MessageSquare },
]
export function MobileHero() {
return (
<section className="relative min-h-[95vh] flex flex-col items-center justify-between px-6 pb-12 pt-16 overflow-hidden bg-[#0a0e1a]">
{/* The Pulse Core - Central Visual */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full h-full z-0 pointer-events-none flex items-center justify-center">
<div className="w-64 h-64 bg-indigo-600/30 blur-[80px] rounded-full animate-pulse will-change-[transform,opacity]" />
<div className="absolute w-40 h-40 bg-purple-600/20 blur-[60px] rounded-full animate-pulse delay-700" />
<div className="absolute w-[300px] h-[1px] bg-gradient-to-r from-transparent via-indigo-500/20 to-transparent rotate-45" />
<div className="absolute w-[300px] h-[1px] bg-gradient-to-r from-transparent via-purple-500/20 to-transparent -rotate-45" />
</div>
<div className="relative z-10 text-center flex flex-col items-center w-full mt-12">
{/* Mobile-First Badge */}
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-white/5 border border-white/10 backdrop-blur-md mb-8"
>
<span className="flex h-1.5 w-1.5 rounded-full bg-indigo-500 animate-ping" />
<span className="text-[10px] font-black uppercase tracking-[0.2em] text-indigo-400">Next-Gen Engine</span>
</motion.div>
{/* Big, Punchy Mobile Header */}
<motion.h1
initial={{ opacity: 1, y: 0 }}
className="text-6xl font-black tracking-tighter text-white mb-6 leading-[0.85] uppercase italic"
>
THE <br />
<span className="text-transparent bg-clip-text bg-gradient-to-br from-indigo-400 via-white to-purple-400">PULSE.</span>
</motion.h1>
<motion.p
initial={{ opacity: 1 }}
className="text-slate-300 text-sm font-medium mb-12 max-w-[260px] leading-relaxed mx-auto"
>
Bridge the gap between vendors and suppliers with the world&apos;s most advanced
encrypted ecosystem.
</motion.p>
{/* Thumb-Zone CTAs */}
<div className="flex flex-col w-full gap-4 max-w-[300px]">
<Link
href="/signup"
className="w-full py-5 bg-indigo-600 rounded-2xl font-black text-white shadow-xl shadow-indigo-600/20 flex items-center justify-center gap-2 active:scale-95 transition-all text-sm uppercase tracking-wider"
>
GET STARTED NOW <ArrowRight className="w-4 h-4" />
</Link>
<button className="w-full py-5 rounded-2xl font-black text-white bg-white/5 border border-white/10 flex items-center justify-center gap-3 active:scale-95 transition-all text-sm uppercase tracking-wider backdrop-blur-sm">
<div className="w-8 h-8 rounded-full bg-white/10 flex items-center justify-center">
<Play className="w-3 h-3 fill-white ml-0.5" />
</div>
WATCH DEMO
</button>
</div>
</div>
{/* Infinite Marquee for Stats - Prevents Overlap */}
<div className="relative w-full z-10 mt-auto pt-12 overflow-hidden mb-4">
<div className="absolute inset-y-0 left-0 w-12 bg-gradient-to-r from-[#0a0e1a] to-transparent z-20" />
<div className="absolute inset-y-0 right-0 w-12 bg-gradient-to-l from-[#0a0e1a] to-transparent z-20" />
<motion.div
animate={{ x: [0, -1000] }}
transition={{ duration: 30, repeat: Infinity, ease: "linear" }}
className="flex whitespace-nowrap gap-8"
>
{[...stats, ...stats, ...stats, ...stats].map((s, i) => (
<div key={i} className="flex items-center gap-2 px-4 py-2 bg-white/5 rounded-full border border-white/10">
<s.icon className="w-3 h-3 text-indigo-400" />
<span className="text-[10px] font-black tracking-[0.1em] text-white uppercase whitespace-nowrap">{s.label}</span>
</div>
))}
</motion.div>
</div>
</section>
)
}

View File

@ -0,0 +1,19 @@
"use client"
import { useState, useEffect } from "react"
export function useMediaQuery(query: string) {
const [matches, setMatches] = useState(false)
useEffect(() => {
const media = window.matchMedia(query)
if (media.matches !== matches) {
setMatches(media.matches)
}
const listener = () => setMatches(media.matches)
window.addEventListener("resize", listener)
return () => window.removeEventListener("resize", listener)
}, [matches, query])
return matches
}