Skip to content
Open
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
108 changes: 74 additions & 34 deletions frontend/src/pages/LandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const steps = [

export default function LandingPage() {
return (
<div className="min-h-screen bg-[#050e18] text-slate-200 relative">
<div className="min-h-screen bg-[#050e18] text-slate-200 relative overflow-x-clip">
{/* ── CSS ─────────────────────────────────────────────── */}
<style>{`
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,500;1,600&display=swap');
Expand Down Expand Up @@ -129,10 +129,48 @@ export default function LandingPage() {
transparent 12px
);
}

/* Mobile composition */
@media (max-width: 419px) {
.landing-actions {
flex-direction: column;
}
.landing-actions > a {
width: 100%;
justify-content: center;
}
}

@media (max-width: 379px) {
.nav-sign-in { display: none; }

.landing-tool-card {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
column-gap: 1rem;
align-items: center;
}
.landing-tool-card .tool-icon {
margin-bottom: 0;
}
}

@media (prefers-reduced-motion: reduce) {
.anim-reveal,
.anim-fade,
.prism::before,
.prism::after {
animation: none !important;
}
.tool-card,
.landing-actions > a {
transition-duration: .01ms !important;
}
}
`}</style>

{/* ── Ambient glow ───────────────────────────────────── */}
<div className="fixed inset-0 pointer-events-none overflow-hidden" aria-hidden>
<div className="absolute inset-0 pointer-events-none overflow-hidden" aria-hidden>
<div className="absolute -top-[30%] left-1/2 -translate-x-1/2 w-[900px] h-[900px] rounded-full"
style={{ background: 'radial-gradient(circle, rgba(45,98,255,.1) 0%, transparent 65%)' }} />
<div className="absolute top-[55%] -right-[10%] w-[500px] h-[500px] rounded-full"
Expand All @@ -142,50 +180,50 @@ export default function LandingPage() {
{/* ── Nav ────────────────────────────────────────────── */}
<nav className="sticky top-0 z-50 backdrop-blur-xl border-b border-white/[.04]"
style={{ background: 'rgba(5,14,24,.75)' }}>
<div className="max-w-6xl mx-auto flex items-center justify-between px-6 h-16">
<Link to="/" className="flex items-center gap-2.5 group">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-brand-500 to-blue-400 flex items-center justify-center
<div className="max-w-6xl mx-auto flex items-center justify-between gap-3 px-4 sm:px-6 h-16">
<Link to="/" className="flex min-w-0 items-center gap-2 sm:gap-2.5 group">
<div className="w-7 h-7 sm:w-8 sm:h-8 shrink-0 rounded-lg bg-gradient-to-br from-brand-500 to-blue-400 flex items-center justify-center
shadow-lg shadow-brand-500/20 group-hover:shadow-brand-500/40 transition-shadow">
<Gem size={14} className="text-white" />
</div>
<span className="font-display text-lg font-semibold tracking-tight text-white">
<span className="font-display text-base sm:text-lg font-semibold tracking-tight text-white whitespace-nowrap">
Crystal<span className="text-blue-400">PDF</span>
</span>
</Link>
<div className="flex items-center gap-2">
<div className="flex shrink-0 items-center gap-1 sm:gap-2">
<Link to="/login"
className="text-sm text-slate-400 hover:text-white px-4 py-2 transition-colors">
className="nav-sign-in text-sm text-slate-400 hover:text-white px-2 sm:px-4 py-2 transition-colors whitespace-nowrap">
Sign in
</Link>
<Link to="/register"
className="text-sm font-medium text-blue-300 bg-brand-500/15 hover:bg-brand-500/25
border border-brand-500/25 hover:border-brand-500/40
px-4 py-2 rounded-lg transition-all">
px-3 sm:px-4 py-2 rounded-lg transition-all whitespace-nowrap">
Get started
</Link>
</div>
</div>
</nav>

{/* ── Hero ───────────────────────────────────────────── */}
<section className="relative z-10 max-w-6xl mx-auto px-6
pt-20 pb-24 md:pt-32 md:pb-36
<section className="relative z-10 max-w-6xl mx-auto px-4 sm:px-6
pt-14 pb-20 sm:pt-20 sm:pb-24 md:pt-32 md:pb-36
grid md:grid-cols-[1fr,auto] items-center gap-12">
{/* Text column */}
<div className="max-w-2xl">
<div className="max-w-2xl min-w-0">
<h1 className="font-display font-semibold tracking-tight leading-[1.1]
text-[clamp(2.2rem,5.5vw,4.8rem)] text-white anim-reveal">
text-[clamp(2.35rem,11vw,4.8rem)] text-white anim-reveal">
Every<br className="hidden sm:block" /> PDF tool<br className="hidden sm:block" /> you'll ever{' '}
<em className="not-italic text-blue-400">need.</em>
</h1>

<p className="mt-7 text-[clamp(1rem,1.8vw,1.2rem)] leading-relaxed
<p className="mt-6 sm:mt-7 text-[clamp(1rem,1.8vw,1.2rem)] leading-relaxed
text-slate-400 max-w-md anim-reveal anim-d2">
Merge, split, compress, protect, convert, and annotate&nbsp;&mdash;
from one elegant workspace. No subscriptions, no upload limits.
</p>

<div className="mt-10 flex flex-wrap gap-3 anim-reveal anim-d3">
<div className="landing-actions mt-8 sm:mt-10 flex flex-wrap gap-3 anim-reveal anim-d3">
<Link to="/register"
className="inline-flex items-center gap-2 px-6 py-3.5 rounded-xl text-[15px] font-medium
text-white bg-gradient-to-b from-brand-500 to-brand-600
Expand Down Expand Up @@ -216,9 +254,9 @@ export default function LandingPage() {

{/* ── Tools grid ─────────────────────────────────────── */}
<section className="relative z-10 dot-grid">
<div className="max-w-6xl mx-auto px-6 py-24 md:py-32">
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-20 sm:py-24 md:py-32">
{/* Section header */}
<div className="max-w-lg mb-14">
<div className="max-w-lg mb-10 sm:mb-14">
<p className="text-xs font-medium tracking-[.15em] uppercase text-brand-400 mb-4">
Toolkit
</p>
Expand All @@ -232,21 +270,23 @@ export default function LandingPage() {
</div>

{/* Grid */}
<div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
<div className="grid grid-cols-1 min-[380px]:grid-cols-2 sm:grid-cols-4 gap-3">
{tools.map((t) => (
<div key={t.name} className="tool-card rounded-2xl p-5 cursor-default group">
<div className="w-10 h-10 rounded-xl bg-blue-400/[.08] border border-blue-400/[.12]
flex items-center justify-center mb-4
<div key={t.name} className="tool-card landing-tool-card rounded-2xl p-4 sm:p-5 cursor-default group">
<div className="tool-icon w-10 h-10 rounded-xl bg-blue-400/[.08] border border-blue-400/[.12]
flex items-center justify-center mb-4 shrink-0
group-hover:bg-blue-400/[.12] group-hover:border-blue-400/[.2]
transition-colors">
<t.icon size={18} className="text-blue-400" strokeWidth={1.8} />
</div>
<p className="text-[15px] font-semibold text-white tracking-tight mb-1">
{t.name}
</p>
<p className="text-[13px] text-slate-500 leading-snug">
{t.desc}
</p>
<div className="min-w-0">
<p className="text-[15px] font-semibold text-white tracking-tight mb-1">
{t.name}
</p>
<p className="text-[13px] text-slate-500 leading-snug">
{t.desc}
</p>
</div>
</div>
))}
</div>
Expand All @@ -255,8 +295,8 @@ export default function LandingPage() {

{/* ── How it works ───────────────────────────────────── */}
<section className="relative z-10 border-t border-white/[.04]">
<div className="max-w-3xl mx-auto px-6 py-24 md:py-32">
<div className="text-center max-w-lg mx-auto mb-16">
<div className="max-w-3xl mx-auto px-4 sm:px-6 py-20 sm:py-24 md:py-32">
<div className="text-center max-w-lg mx-auto mb-12 sm:mb-16">
<p className="text-xs font-medium tracking-[.15em] uppercase text-brand-400 mb-4">
How it works
</p>
Expand Down Expand Up @@ -309,7 +349,7 @@ export default function LandingPage() {

{/* ── CTA ────────────────────────────────────────────── */}
<section className="relative z-10 border-t border-white/[.04]">
<div className="max-w-6xl mx-auto px-6 py-28 md:py-36 text-center">
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-20 sm:py-28 md:py-36 text-center">
{/* Soft top glow */}
<div className="absolute inset-x-0 top-0 h-64 pointer-events-none"
style={{ background: 'radial-gradient(ellipse 50% 100% at 50% 0%, rgba(45,98,255,.06), transparent)' }} />
Expand All @@ -319,10 +359,10 @@ export default function LandingPage() {
</p>
<h2 className="font-display text-[clamp(2.4rem,5.5vw,4.5rem)] font-semibold
tracking-tight leading-[.95] text-white mb-10 relative">
Start working with<br />
Start working with<br className="hidden sm:block" />{' '}
your PDFs today.
</h2>
<div className="relative flex flex-wrap justify-center gap-3">
<div className="landing-actions relative flex flex-wrap justify-center gap-3 max-w-md mx-auto">
<Link to="/register"
className="inline-flex items-center gap-2 px-7 py-3.5 rounded-xl text-[15px] font-medium
text-white bg-gradient-to-b from-brand-500 to-brand-600
Expand All @@ -342,11 +382,11 @@ export default function LandingPage() {

{/* ── Footer ─────────────────────────────────────────── */}
<footer className="relative z-10 border-t border-white/[.04]">
<div className="max-w-6xl mx-auto px-6 py-8 flex items-center justify-between flex-wrap gap-4">
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-6 sm:py-8 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 sm:gap-4">
<span className="font-display text-sm font-semibold text-slate-600">
Crystal<span className="text-blue-400/50">PDF</span>
</span>
<p className="text-xs text-slate-700">
<p className="text-xs text-slate-700 leading-relaxed max-w-sm sm:text-right">
Secure, server-side processing. Your files never leave your account.
</p>
</div>
Expand Down