Redesign landing page with all features: 6 discovery modes, 8 tools, taste match

This commit is contained in:
root
2026-04-03 21:18:14 -05:00
parent f2b8dadbf8
commit dcff90289c

View File

@@ -1,29 +1,49 @@
import { Link } from 'react-router-dom'
import { Disc3, Sparkles, ListMusic, Heart, ArrowRight } from 'lucide-react'
import { Disc3, Sparkles, ListMusic, Heart, ArrowRight, Compass, Users, Shuffle, Music, Repeat, Clock, TrendingUp, Lightbulb, ArrowDownCircle, Calendar, Share2, Fingerprint } from 'lucide-react'
const features = [
const howItWorks = [
{
icon: ListMusic,
title: 'Import Your Music',
description: 'Import your playlists from YouTube Music, Last.fm, or paste your songs to build your taste profile.',
description: 'Paste a YouTube Music playlist, import from Last.fm, or just type in songs you love. No Spotify required.',
},
{
icon: Sparkles,
title: 'AI-Powered Discovery',
description: 'Our AI analyzes your taste and finds hidden gems you\'ll actually love.',
title: 'AI Analyzes Your Taste',
description: 'Our AI builds a deep profile of your musical DNA — genres, energy, mood, and the qualities that make you hit repeat.',
},
{
icon: Heart,
title: 'Understand Why',
description: 'Every recommendation comes with a personal explanation of why it fits your taste.',
title: 'Discover & Understand',
description: 'Get personalized recommendations with explanations of exactly WHY you\'ll love each track. Every song links to YouTube Music.',
},
]
const discoveryModes = [
{ icon: Compass, title: 'Discover', description: 'AI-curated picks based on your taste' },
{ icon: Users, title: 'Sonic Twin', description: 'Underground artists who sound like your favorites' },
{ icon: Clock, title: 'Era Bridge', description: 'Classic artists who inspired what you love now' },
{ icon: Disc3, title: 'Deep Cuts', description: 'B-sides and rarities from artists you know' },
{ icon: TrendingUp, title: 'Rising', description: 'Under 50K listeners who fit your profile' },
{ icon: Shuffle, title: 'Surprise Me', description: 'One button. AI picks a wild creative angle.' },
]
const features = [
{ icon: ArrowDownCircle, title: 'Rabbit Hole', description: 'Follow a chain of connected songs — each one leads to the next through a shared quality.' },
{ icon: Music, title: 'Crate Digger', description: 'Swipe through discoveries like Tinder for music. Save or pass — build your taste profile faster.' },
{ icon: Lightbulb, title: 'Why Do I Like This?', description: 'Paste any song. AI explains what draws you to it, then finds more with the same qualities.' },
{ icon: ListMusic, title: 'Playlist Generator', description: 'Describe a vibe — "rainy day reading" — and AI builds a full 25-song playlist.' },
{ icon: Repeat, title: 'Fix My Playlist', description: 'AI finds tracks that don\'t fit your playlist vibe and suggests better replacements.' },
{ icon: Calendar, title: 'Concert Finder', description: 'See upcoming tour dates for any recommended artist, with links to tickets.' },
{ icon: Fingerprint, title: 'Music DNA Profile', description: 'Visual breakdown of your taste — genre bars, mood meters, listening personality label.' },
{ icon: Share2, title: 'Share Discoveries', description: 'Share any recommendation or your full taste profile via a public link.' },
]
export default function Landing() {
return (
<div className="min-h-screen bg-cream">
{/* Header */}
<header className="px-6 py-5">
<header className="px-4 sm:px-6 py-5">
<div className="max-w-6xl mx-auto flex items-center justify-between">
<div className="flex items-center gap-2">
<Disc3 className="w-8 h-8 text-purple" strokeWidth={2.5} />
@@ -47,14 +67,13 @@ export default function Landing() {
</header>
{/* Hero */}
<section className="px-6 pt-16 pb-24 md:pt-24 md:pb-32">
<section className="px-4 sm:px-6 pt-12 pb-20 md:pt-20 md:pb-28">
<div className="max-w-4xl mx-auto text-center">
{/* Decorative vinyl */}
<div className="mb-8 inline-flex items-center justify-center w-24 h-24 rounded-full bg-gradient-to-br from-purple to-purple-dark shadow-lg shadow-purple/25">
<Disc3 className="w-14 h-14 text-white animate-[spin_8s_linear_infinite]" />
</div>
<h1 className="text-5xl md:text-7xl font-extrabold text-charcoal leading-tight tracking-tight mb-6">
<h1 className="text-4xl sm:text-5xl md:text-7xl font-extrabold text-charcoal leading-tight tracking-tight mb-6">
Dig deeper.
<br />
<span className="text-purple">Discover more.</span>
@@ -62,8 +81,8 @@ export default function Landing() {
<p className="text-lg md:text-xl text-charcoal-muted max-w-2xl mx-auto mb-10 leading-relaxed">
Vynl uses AI to understand your unique music taste and uncover tracks
you never knew you needed. Like a friend with impeccable taste who
always knows what to play next.
you never knew you needed. Every recommendation comes with a reason WHY
and a link to listen instantly.
</p>
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
@@ -83,38 +102,34 @@ export default function Landing() {
</div>
<p className="mt-6 text-sm text-charcoal-muted">
Free tier includes 10 recommendations per day
Free tier: 5 discoveries per week. No credit card required.
</p>
</div>
</section>
{/* Features */}
<section className="px-6 py-20 bg-white/50">
{/* How It Works */}
<section className="px-4 sm:px-6 py-16 bg-white/50">
<div className="max-w-5xl mx-auto">
<h2 className="text-3xl md:text-4xl font-bold text-charcoal text-center mb-4">
How it works
</h2>
<p className="text-charcoal-muted text-center mb-14 max-w-xl mx-auto">
Three simple steps to your next favorite song
<p className="text-charcoal-muted text-center mb-12 max-w-xl mx-auto">
Three steps to your next favorite song
</p>
<div className="grid md:grid-cols-3 gap-8">
{features.map((feature, i) => {
const Icon = feature.icon
<div className="grid md:grid-cols-3 gap-6">
{howItWorks.map((item, i) => {
const Icon = item.icon
return (
<div
key={i}
className="bg-white rounded-2xl p-8 border border-purple-100 shadow-sm hover:shadow-md transition-shadow"
className="bg-white rounded-2xl p-7 border border-purple-100 shadow-sm hover:shadow-md transition-shadow"
>
<div className="w-12 h-12 rounded-xl bg-purple-50 flex items-center justify-center mb-5">
<Icon className="w-6 h-6 text-purple" />
</div>
<h3 className="text-lg font-semibold text-charcoal mb-2">
{feature.title}
</h3>
<p className="text-charcoal-muted text-sm leading-relaxed">
{feature.description}
</p>
<h3 className="text-lg font-semibold text-charcoal mb-2">{item.title}</h3>
<p className="text-charcoal-muted text-sm leading-relaxed">{item.description}</p>
</div>
)
})}
@@ -122,14 +137,97 @@ export default function Landing() {
</div>
</section>
{/* Discovery Modes */}
<section className="px-4 sm:px-6 py-16">
<div className="max-w-5xl mx-auto">
<h2 className="text-3xl md:text-4xl font-bold text-charcoal text-center mb-4">
6 ways to discover
</h2>
<p className="text-charcoal-muted text-center mb-12 max-w-xl mx-auto">
Choose how adventurous you want to go
</p>
<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
{discoveryModes.map((mode, i) => {
const Icon = mode.icon
return (
<div
key={i}
className="flex items-start gap-4 bg-white rounded-xl p-5 border border-purple-100 hover:border-purple/30 transition-colors"
>
<div className="w-10 h-10 rounded-lg bg-purple-50 flex items-center justify-center flex-shrink-0">
<Icon className="w-5 h-5 text-purple" />
</div>
<div>
<h3 className="font-semibold text-charcoal text-sm mb-1">{mode.title}</h3>
<p className="text-charcoal-muted text-xs leading-relaxed">{mode.description}</p>
</div>
</div>
)
})}
</div>
</div>
</section>
{/* All Features */}
<section className="px-4 sm:px-6 py-16 bg-white/50">
<div className="max-w-5xl mx-auto">
<h2 className="text-3xl md:text-4xl font-bold text-charcoal text-center mb-4">
Everything you get
</h2>
<p className="text-charcoal-muted text-center mb-12 max-w-xl mx-auto">
More than just recommendations
</p>
<div className="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
{features.map((feature, i) => {
const Icon = feature.icon
return (
<div
key={i}
className="bg-white rounded-xl p-5 border border-purple-100 hover:shadow-md transition-shadow"
>
<Icon className="w-6 h-6 text-purple mb-3" />
<h3 className="font-semibold text-charcoal text-sm mb-1.5">{feature.title}</h3>
<p className="text-charcoal-muted text-xs leading-relaxed">{feature.description}</p>
</div>
)
})}
</div>
</div>
</section>
{/* Taste Compatibility */}
<section className="px-4 sm:px-6 py-16">
<div className="max-w-4xl mx-auto">
<div className="bg-gradient-to-br from-charcoal to-charcoal-light rounded-3xl p-8 md:p-12 text-center">
<Users className="w-12 h-12 text-purple-300 mx-auto mb-4" />
<h2 className="text-2xl md:text-3xl font-bold text-white mb-3">
Compare your taste with friends
</h2>
<p className="text-purple-200/80 mb-6 max-w-lg mx-auto">
Enter a friend's email and get a compatibility score, see what genres you share,
and discover songs you'd both love.
</p>
<Link
to="/register"
className="inline-flex items-center gap-2 px-6 py-3 bg-purple text-white font-semibold rounded-full hover:bg-purple-dark transition-colors no-underline text-sm"
>
Try Taste Match
<ArrowRight className="w-4 h-4" />
</Link>
</div>
</div>
</section>
{/* CTA */}
<section className="px-6 py-24">
<div className="max-w-3xl mx-auto text-center bg-gradient-to-br from-purple to-purple-dark rounded-3xl p-12 md:p-16 shadow-xl shadow-purple/20">
<section className="px-4 sm:px-6 py-20">
<div className="max-w-3xl mx-auto text-center bg-gradient-to-br from-purple to-purple-dark rounded-3xl p-10 md:p-16 shadow-xl shadow-purple/20">
<h2 className="text-3xl md:text-4xl font-bold text-white mb-4">
Ready to find your next favorite song?
</h2>
<p className="text-purple-200 mb-8 text-lg">
Join Vynl today and let AI be your personal music curator.
Join thousands of music lovers discovering new artists every day.
</p>
<Link
to="/register"
@@ -142,8 +240,8 @@ export default function Landing() {
</section>
{/* Footer */}
<footer className="px-6 py-8 border-t border-purple-100">
<div className="max-w-6xl mx-auto flex items-center justify-between">
<footer className="px-4 sm:px-6 py-8 border-t border-purple-100">
<div className="max-w-6xl mx-auto flex flex-col sm:flex-row items-center justify-between gap-4">
<div className="flex items-center gap-2 text-charcoal-muted">
<Disc3 className="w-5 h-5" />
<span className="text-sm font-medium">Vynl</span>