Redesign landing page with all features: 6 discovery modes, 8 tools, taste match
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user