Spaces:
Sleeping
Sleeping
File size: 13,925 Bytes
5a0e691 627ac39 dc1f75e 627ac39 5a0e691 627ac39 2f67ecf 627ac39 5a0e691 627ac39 5a0e691 627ac39 2f67ecf 627ac39 5a0e691 627ac39 76fb273 627ac39 76fb273 627ac39 5a0e691 627ac39 5a0e691 627ac39 5a0e691 627ac39 76fb273 627ac39 76fb273 627ac39 5a0e691 627ac39 5a0e691 627ac39 76fb273 627ac39 76fb273 627ac39 2f67ecf 627ac39 76fb273 627ac39 76fb273 627ac39 2f67ecf 627ac39 5a0e691 627ac39 5a0e691 76fb273 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | 'use client';
import dynamic from 'next/dynamic';
import Link from 'next/link';
import { useRef } from 'react';
import { motion, useScroll, useTransform } from 'framer-motion';
import { ArrowRight, Database, Zap, Brain, ChevronDown } from 'lucide-react';
const DNAHelix = dynamic(
() => import('@/components/three/DNAHelix'),
{ ssr: false, loading: () => <div className="w-full h-full bg-void" /> }
);
const DATABASES = ['NCBI', 'UniProt', 'PDB', 'KEGG', 'Ensembl', 'STRING', 'EMBL', 'Pfam'];
const PIPELINE = [
{ step: '01', label: 'Sequence Input', sub: 'FASTA / accession ID' },
{ step: '02', label: 'BLAST Search', sub: 'EBI BLAST + NCBI' },
{ step: '03', label: 'UniProt Lookup', sub: 'Annotation & function' },
{ step: '04', label: 'Structure Prediction', sub: 'AlphaFold 3D viewer' },
{ step: '05', label: 'AI Interpretation', sub: 'Plain-language insight' },
];
const FEATURES = [
{
icon: Database,
color: '#00F5D4',
title: 'Unified Access',
body: 'NCBI, UniProt, PDB, KEGG, Ensembl — one plain-English query retrieves across every major database simultaneously.',
},
{
icon: Zap,
color: '#8B5CF6',
title: 'Pipeline Automation',
body: 'BLAST → UniProt → AlphaFold runs sequentially, hands-free. Real-time progress via SSE, results assembled automatically.',
},
{
icon: Brain,
color: '#F59E0B',
title: 'AI Interpretation',
body: 'Every result is narrated in plain language. Clinical relevance, evolutionary context, functional insights — streamed live.',
},
];
const fadeUp = {
hidden: { opacity: 0, y: 24 },
show: { opacity: 1, y: 0, transition: { duration: 0.6, ease: [0.25, 1, 0.5, 1] as const } },
};
const stagger = {
show: { transition: { staggerChildren: 0.1 } },
};
export default function LandingPage() {
const heroRef = useRef<HTMLDivElement>(null);
const { scrollYProgress } = useScroll({
target: heroRef,
offset: ['start start', 'end start'],
});
const helixY = useTransform(scrollYProgress, [0, 1], ['0%', '28%']);
const helixOpacity = useTransform(scrollYProgress, [0, 0.55], [1, 0]);
const textY = useTransform(scrollYProgress, [0, 1], ['0%', '18%']);
const textOpacity = useTransform(scrollYProgress, [0, 0.4], [1, 0]);
return (
<main className="relative bg-void text-text-primary overflow-x-hidden">
<nav
className="fixed top-0 inset-x-0 z-50 flex items-center justify-between px-8 py-5"
style={{ backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)' }}
>
<span className="font-display text-sm font-semibold tracking-widest uppercase">
Bio <span className="text-gradient">Nexus</span>
</span>
<div className="flex items-center gap-6">
<Link href="#features" className="hidden sm:block text-xs text-text-muted hover:text-text-primary transition-colors tracking-wide">
Features
</Link>
<Link href="#pipeline" className="hidden sm:block text-xs text-text-muted hover:text-text-primary transition-colors tracking-wide">
Pipeline
</Link>
<Link
href="/auth"
className="text-xs px-4 py-2 rounded-full border border-glass-border text-text-secondary hover:border-accent-cyan/40 hover:text-accent-cyan transition-all"
>
Sign in
</Link>
<Link href="/dashboard" className="btn-primary text-xs py-2 px-4">
Get started
</Link>
</div>
</nav>
<section
ref={heroRef}
className="relative h-screen flex items-center justify-center overflow-hidden"
>
<motion.div
style={{ y: helixY, opacity: helixOpacity }}
className="absolute inset-0 z-0"
>
<DNAHelix className="w-full h-full" />
</motion.div>
<div className="absolute inset-0 z-[1] bg-grid pointer-events-none opacity-40" />
<div className="absolute inset-0 z-[2] bg-vignette pointer-events-none" />
<div
className="absolute z-[1] w-[40vw] h-[40vw] rounded-full pointer-events-none"
style={{
top: '20%', left: '10%',
background: 'radial-gradient(circle, rgba(0,245,212,0.07) 0%, transparent 70%)',
filter: 'blur(40px)',
}}
/>
<div
className="absolute z-[1] w-[35vw] h-[35vw] rounded-full pointer-events-none"
style={{
bottom: '15%', right: '8%',
background: 'radial-gradient(circle, rgba(139,92,246,0.07) 0%, transparent 70%)',
filter: 'blur(40px)',
}}
/>
<motion.div
style={{ y: textY, opacity: textOpacity }}
className="relative z-10 text-center max-w-4xl px-6"
>
<motion.p
variants={fadeUp}
initial="hidden"
animate="show"
transition={{ delay: 0.2 }}
className="text-[10px] tracking-[0.35em] uppercase text-accent-cyan mb-7 font-mono"
>
Bioinformatics · Automated · AI-powered
</motion.p>
<motion.h1
variants={fadeUp}
initial="hidden"
animate="show"
transition={{ delay: 0.4 }}
className="font-display font-bold leading-[0.92] tracking-tight mb-8"
style={{ fontSize: 'clamp(3.2rem, 8.5vw, 7.5rem)' }}
>
One query.{' '}
<br className="hidden sm:block" />
<span className="text-gradient">Every database.</span>
</motion.h1>
<motion.p
variants={fadeUp}
initial="hidden"
animate="show"
transition={{ delay: 0.6 }}
className="text-text-secondary text-lg max-w-[520px] mx-auto mb-10 leading-relaxed"
>
BioNexus unifies NCBI, UniProt, PDB, and KEGG into a single plain-language
interface — with AI-interpreted visual results, instantly.
</motion.p>
<motion.div
variants={fadeUp}
initial="hidden"
animate="show"
transition={{ delay: 0.75 }}
className="flex flex-col sm:flex-row items-center justify-center gap-4"
>
<Link href="/dashboard" className="btn-primary">
Start analyzing
<ArrowRight size={15} />
</Link>
<Link href="#pipeline" className="btn-ghost">
See the pipeline
</Link>
</motion.div>
</motion.div>
<motion.div
className="absolute bottom-9 left-1/2 -translate-x-1/2 z-10 flex flex-col items-center gap-2 opacity-50"
animate={{ y: [0, 7, 0] }}
transition={{ repeat: Infinity, duration: 2, ease: 'easeInOut' }}
>
<ChevronDown size={14} className="text-text-muted" />
</motion.div>
</section>
<section className="relative py-14 border-y border-glass-border overflow-hidden">
<div className="absolute inset-0 bg-surface-0/60" />
<div className="relative z-10">
<p className="text-center text-[10px] tracking-[0.35em] uppercase text-text-muted font-mono mb-8">
Unified access to
</p>
<motion.div
variants={stagger}
initial="hidden"
whileInView="show"
viewport={{ once: true }}
className="flex flex-wrap items-center justify-center gap-x-10 gap-y-3 px-6"
>
{DATABASES.map((db) => (
<motion.span
key={db}
variants={fadeUp}
className="text-sm font-mono text-text-muted hover:text-accent-cyan transition-colors cursor-default select-none"
>
{db}
</motion.span>
))}
</motion.div>
</div>
</section>
<section id="pipeline" className="py-28 px-6 max-w-5xl mx-auto">
<motion.div
variants={fadeUp}
initial="hidden"
whileInView="show"
viewport={{ once: true }}
className="text-center mb-20"
>
<p className="text-[10px] tracking-[0.35em] uppercase text-accent-cyan font-mono mb-4">
How it works
</p>
<h2 className="font-display text-4xl font-bold tracking-tight">
From sequence to insight
</h2>
<p className="text-text-secondary mt-4 max-w-md mx-auto text-sm leading-relaxed">
Five automated stages, zero manual database switching.
</p>
</motion.div>
<div className="relative">
<div className="absolute top-10 left-0 right-0 h-px hidden md:block">
<div className="h-full bg-gradient-to-r from-transparent via-glass-border to-transparent mx-12" />
</div>
<motion.div
variants={stagger}
initial="hidden"
whileInView="show"
viewport={{ once: true, margin: '-60px' }}
className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-5 gap-5"
>
{PIPELINE.map(({ step, label, sub }) => (
<motion.div
key={step}
variants={fadeUp}
whileHover={{ y: -4, transition: { duration: 0.2 } }}
className="glass-card p-5 text-center relative cursor-default"
>
<div className="w-8 h-8 rounded-full bg-accent-cyan/10 border border-accent-cyan/25 flex items-center justify-center mx-auto mb-4">
<span className="text-accent-cyan text-[10px] font-mono font-semibold">{step}</span>
</div>
<p className="font-display text-[13px] font-semibold mb-1 text-text-primary">
{label}
</p>
<p className="text-[11px] text-text-muted font-mono">{sub}</p>
</motion.div>
))}
</motion.div>
</div>
</section>
<section id="features" className="py-28 px-6 max-w-5xl mx-auto">
<motion.div
variants={fadeUp}
initial="hidden"
whileInView="show"
viewport={{ once: true }}
className="text-center mb-20"
>
<p className="text-[10px] tracking-[0.35em] uppercase text-accent-purple font-mono mb-4">
Features
</p>
<h2 className="font-display text-4xl font-bold tracking-tight">
Everything you need
</h2>
</motion.div>
<motion.div
variants={stagger}
initial="hidden"
whileInView="show"
viewport={{ once: true, margin: '-60px' }}
className="grid grid-cols-1 md:grid-cols-3 gap-6"
>
{FEATURES.map((f) => {
const Icon = f.icon;
return (
<motion.div
key={f.title}
variants={fadeUp}
whileHover={{ y: -6, transition: { duration: 0.25 } }}
className="glass-card p-7 cursor-default"
>
<div
className="w-10 h-10 rounded-xl flex items-center justify-center mb-6"
style={{
background: `${f.color}12`,
border: `1px solid ${f.color}28`,
}}
>
<Icon size={18} style={{ color: f.color }} strokeWidth={1.8} />
</div>
<h3 className="font-display text-base font-semibold mb-2 text-text-primary">
{f.title}
</h3>
<p className="text-sm text-text-secondary leading-relaxed">
{f.body}
</p>
<div
className="mt-6 h-px rounded-full"
style={{
background: `linear-gradient(90deg, ${f.color}40 0%, transparent 100%)`,
}}
/>
</motion.div>
);
})}
</motion.div>
</section>
<section className="py-32 px-6 relative overflow-hidden">
<div
className="absolute inset-0 pointer-events-none"
style={{
background: 'radial-gradient(ellipse 60% 60% at 50% 50%, rgba(0,245,212,0.05) 0%, transparent 70%)',
}}
/>
<motion.div
variants={fadeUp}
initial="hidden"
whileInView="show"
viewport={{ once: true }}
className="relative z-10 text-center max-w-xl mx-auto"
>
<p className="text-[10px] tracking-[0.35em] uppercase text-accent-amber font-mono mb-6">
Get started
</p>
<h2 className="font-display text-4xl font-bold tracking-tight mb-5">
Ready to decode your sequences?
</h2>
<p className="text-text-secondary mb-10 leading-relaxed">
Free to start. No API keys required to run your first analysis.
</p>
<Link href="/dashboard" className="btn-primary text-base px-8 py-4">
Open Bio Nexus
<ArrowRight size={17} />
</Link>
</motion.div>
</section>
<footer className="border-t border-glass-border py-8 px-8 flex flex-col sm:flex-row items-center justify-between gap-4">
<span className="font-mono text-xs text-text-muted">
Bio Nexus · Built at Jamia Millia Islamia
</span>
<div className="flex items-center gap-6">
<Link href="/auth" className="text-xs text-text-muted hover:text-text-primary transition-colors">
Sign in
</Link>
<span className="text-xs text-text-muted">© 2026</span>
</div>
</footer>
</main>
);
}
|