Improve web landing page design and UX

- Add FAQ section with accordion-style questions
- Enhance hero with stronger copy and App Store badge
- Add hover animations to features and phone mockups
- Add pricing display (£4.99/month) to Pro section
- Add step icons to How It Works section
- Improve accessibility with focus states and reduced-motion
- Add exit animation to mobile navigation menu

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
jjbrunton committed 2026-01-06 18:43:07 +00:00
1 parent e52430f0a8
commit 1f0201ec5f
8 files changed
+328 -70

No files matched your search

+57
View File
@@ -158,3 +158,60 @@ body {
.animate-pulse-glow { .animate-pulse-glow {
animation: pulse-glow 4s ease-in-out infinite; animation: pulse-glow 4s ease-in-out infinite;
} }
/* Focus states for accessibility */
.btn-primary:focus-visible,
.btn-secondary:focus-visible {
outline: none;
ring: 2px;
ring-offset: 2px;
ring-color: rgba(233, 69, 96, 0.8);
box-shadow: 0 0 0 2px var(--background), 0 0 0 4px var(--primary);
}
a:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
border-radius: 4px;
}
button:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
.animate-float,
.animate-pulse-glow {
animation: none;
}
}
/* Card tilt effect */
.card-tilt {
transition: transform 0.3s ease;
transform-style: preserve-3d;
}
.card-tilt:hover {
transform: perspective(1000px) rotateX(2deg) rotateY(-2deg) translateY(-4px);
}
/* Phone tilt effect */
.phone-tilt {
transition: transform 0.4s ease;
transform-style: preserve-3d;
}
.phone-tilt:hover {
transform: perspective(1000px) rotateY(-8deg) rotateX(4deg) scale(1.02);
}
+2
View File
@@ -3,6 +3,7 @@ import Hero from '@/components/Hero'
import Features from '@/components/Features' import Features from '@/components/Features'
import HowItWorks from '@/components/HowItWorks' import HowItWorks from '@/components/HowItWorks'
import Pricing from '@/components/Pricing' import Pricing from '@/components/Pricing'
import FAQ from '@/components/FAQ'
import CTA from '@/components/CTA' import CTA from '@/components/CTA'
import Footer from '@/components/Footer' import Footer from '@/components/Footer'
@@ -14,6 +15,7 @@ export default function Home() {
<Features /> <Features />
<HowItWorks /> <HowItWorks />
<Pricing /> <Pricing />
<FAQ />
<CTA /> <CTA />
<Footer /> <Footer />
</main> </main>
+122
View File
@@ -0,0 +1,122 @@
'use client'
import { useState } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { ChevronDown } from 'lucide-react'
const faqs = [
{
question: 'How does matching work?',
answer:
"When you and your partner both answer positively to the same question (yes or maybe), it's a match! You'll both be notified and a private chat thread opens for that question. Your individual answers remain private until there's a match.",
},
{
question: 'Are my answers private?',
answer:
"Absolutely. Your individual answers are never revealed to your partner. They only see questions where you've both answered positively. If you say no to something, your partner will never know.",
},
{
question: 'What happens if my partner says no to a question?',
answer:
"Nothing! They won't know you were interested, and you won't know they said no. The question simply doesn't become a match. This creates a safe space to be honest about your desires.",
},
{
question: 'Do both partners need Pro?',
answer:
"No! When one partner upgrades to Pro, both partners automatically get full access to all premium packs. One subscription covers your entire relationship.",
},
{
question: 'Is my data secure?',
answer:
'Yes. All chat messages are end-to-end encrypted, meaning only you and your partner can read them. We take your privacy seriously and never share your data with third parties.',
},
]
function FAQItem({
question,
answer,
isOpen,
onClick,
}: {
question: string
answer: string
isOpen: boolean
onClick: () => void
}) {
return (
<div className="glass overflow-hidden">
<button
onClick={onClick}
className="w-full px-6 py-5 flex items-center justify-between text-left hover:bg-white/5 transition-colors"
aria-expanded={isOpen}
>
<span className="font-semibold text-lg pr-4">{question}</span>
<motion.div
animate={{ rotate: isOpen ? 180 : 0 }}
transition={{ duration: 0.2 }}
className="flex-shrink-0"
>
<ChevronDown className="w-5 h-5 text-white/60" />
</motion.div>
</button>
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ height: 0, opacity: 0 }}
animate={{ height: 'auto', opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.3 }}
>
<div className="px-6 pb-5 text-white/70 leading-relaxed">{answer}</div>
</motion.div>
)}
</AnimatePresence>
</div>
)
}
export default function FAQ() {
const [openIndex, setOpenIndex] = useState<number | null>(null)
return (
<section id="faq" className="relative py-24 overflow-hidden">
{/* Background */}
<div className="absolute inset-0 bg-gradient-to-b from-background to-background-light" />
<div className="relative z-10 max-w-3xl mx-auto px-6">
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
className="text-center mb-12"
>
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-bold mb-4">
Frequently Asked <span className="gradient-text">Questions</span>
</h2>
<p className="text-lg text-white/70 max-w-2xl mx-auto">
Everything you need to know about Sauci.
</p>
</motion.div>
<div className="space-y-4">
{faqs.map((faq, index) => (
<motion.div
key={faq.question}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: index * 0.1 }}
>
<FAQItem
question={faq.question}
answer={faq.answer}
isOpen={openIndex === index}
onClick={() => setOpenIndex(openIndex === index ? null : index)}
/>
</motion.div>
))}
</div>
</div>
</section>
)
}
+7 -5
View File
@@ -78,13 +78,15 @@ export default function Features() {
whileInView={{ opacity: 1, y: 0 }} whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }} viewport={{ once: true }}
transition={{ delay: index * 0.1 }} transition={{ delay: index * 0.1 }}
className="glass p-6 hover:border-white/20 transition-all duration-300 group" className={`glass p-6 hover:border-white/20 transition-all duration-300 group card-tilt ${
index < 2 ? 'md:col-span-1 lg:p-8' : ''
}`}
> >
<div className={`w-14 h-14 rounded-2xl ${feature.bgColor} flex items-center justify-center mb-4 group-hover:scale-110 transition-transform`}> <div className={`${index < 2 ? 'w-16 h-16' : 'w-14 h-14'} rounded-2xl ${feature.bgColor} flex items-center justify-center mb-4 group-hover:scale-110 group-hover:rotate-3 transition-all duration-300`}>
<feature.icon className={`w-7 h-7 ${feature.color}`} /> <feature.icon className={`${index < 2 ? 'w-8 h-8' : 'w-7 h-7'} ${feature.color} group-hover:scale-110 transition-transform duration-300`} />
</div> </div>
<h3 className="text-xl font-semibold mb-2">{feature.title}</h3> <h3 className={`${index < 2 ? 'text-2xl' : 'text-xl'} font-semibold mb-2`}>{feature.title}</h3>
<p className="text-white/60">{feature.description}</p> <p className="text-white/70">{feature.description}</p>
</motion.div> </motion.div>
))} ))}
</div> </div>
+52 -18
View File
@@ -1,10 +1,21 @@
'use client' 'use client'
import { useEffect, useState } from 'react'
import Image from 'next/image' import Image from 'next/image'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { Sparkles } from 'lucide-react' import { Sparkles } from 'lucide-react'
export default function Hero() { export default function Hero() {
const [hasScrolled, setHasScrolled] = useState(false)
useEffect(() => {
const handleScroll = () => {
setHasScrolled(window.scrollY > 100)
}
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, [])
return ( return (
<section className="relative min-h-screen flex items-center justify-center overflow-hidden pt-20"> <section className="relative min-h-screen flex items-center justify-center overflow-hidden pt-20">
{/* Background Effects */} {/* Background Effects */}
@@ -29,33 +40,56 @@ export default function Hero() {
className="inline-flex items-center gap-2 glass px-4 py-2 mb-6" className="inline-flex items-center gap-2 glass px-4 py-2 mb-6"
> >
<Sparkles className="w-4 h-4 text-primary" /> <Sparkles className="w-4 h-4 text-primary" />
<span className="text-sm text-white/80">Discover What You Both Desire</span> <span className="text-sm text-white/80">Your First Match in Minutes</span>
</motion.div> </motion.div>
<h1 className="text-4xl sm:text-5xl lg:text-6xl xl:text-7xl font-bold leading-tight mb-6"> <h1 className="text-4xl sm:text-5xl lg:text-6xl xl:text-7xl font-bold leading-tight mb-6">
Ignite Your{' '} Discover What You{' '}
<span className="gradient-text">Connection</span> <span className="gradient-text">Both Desire</span>
</h1> </h1>
<p className="text-lg sm:text-xl text-white/60 max-w-xl mx-auto lg:mx-0 mb-8"> <p className="text-lg sm:text-xl text-white/70 max-w-xl mx-auto lg:mx-0 mb-8">
Sauci helps couples explore their desires through playful questions. Swipe on intimate questions with your partner. When you both say yes,
Swipe, match, and unlock deeper conversations with your partner. it&apos;s a match. Start conversations you&apos;ve always wanted to have.
</p> </p>
<div className="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-4"> <div className="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-4">
{/* Official App Store Badge */}
<a <a
href="https://apps.apple.com/app/sauci" href="https://apps.apple.com/app/sauci"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="btn-primary flex items-center gap-2 w-full sm:w-auto justify-center" className="transition-transform hover:scale-105 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-xl"
aria-label="Download on the App Store"
> >
<svg viewBox="0 0 24 24" className="w-5 h-5" fill="currentColor"> <svg
<path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/> viewBox="0 0 120 40"
className="h-[50px] w-auto"
fill="currentColor"
role="img"
aria-hidden="true"
>
<path d="M110.135 0H9.535c-.367 0-.73 0-1.095.002-.306.002-.61.008-.919.013A13.215 13.215 0 0 0 5.517.19a6.665 6.665 0 0 0-1.9.627 6.438 6.438 0 0 0-1.62 1.18A6.258 6.258 0 0 0 .82 3.617 6.601 6.601 0 0 0 .195 5.52a12.993 12.993 0 0 0-.179 2.002c-.01.307-.01.615-.015.921V31.56c.005.31.006.61.015.921a12.992 12.992 0 0 0 .18 2.002 6.588 6.588 0 0 0 .624 1.905A6.208 6.208 0 0 0 1.998 38a6.274 6.274 0 0 0 1.618 1.179 6.7 6.7 0 0 0 1.901.63 13.455 13.455 0 0 0 2.004.177c.31.007.613.011.919.011.366.002.728.002 1.095.002h100.6c.36 0 .724 0 1.084-.002.304 0 .617-.004.922-.01a13.279 13.279 0 0 0 2-.178 6.804 6.804 0 0 0 1.908-.63A6.277 6.277 0 0 0 117.666 38a6.395 6.395 0 0 0 1.182-1.614 6.604 6.604 0 0 0 .619-1.905 13.506 13.506 0 0 0 .185-2.002c.004-.31.004-.61.004-.921.008-.364.008-.725.008-1.094V9.536c0-.366 0-.73-.008-1.092 0-.306 0-.614-.004-.92a13.507 13.507 0 0 0-.185-2.003 6.618 6.618 0 0 0-.62-1.903 6.466 6.466 0 0 0-2.798-2.8 6.768 6.768 0 0 0-1.908-.627 13.044 13.044 0 0 0-2-.176c-.305-.005-.618-.011-.922-.013-.36-.002-.725-.002-1.084-.002Z" />
<path
d="M8.445 39.125c-.305 0-.602-.004-.904-.01a12.687 12.687 0 0 1-1.87-.164 5.884 5.884 0 0 1-1.656-.548 5.406 5.406 0 0 1-1.397-1.016 5.32 5.32 0 0 1-1.02-1.397 5.722 5.722 0 0 1-.544-1.657 12.414 12.414 0 0 1-.166-1.875c-.007-.21-.015-.913-.015-.913v-23.1s.009-.692.015-.895a12.37 12.37 0 0 1 .165-1.872 5.755 5.755 0 0 1 .544-1.662 5.373 5.373 0 0 1 1.015-1.398 5.565 5.565 0 0 1 1.402-1.023 5.823 5.823 0 0 1 1.653-.544A12.586 12.586 0 0 1 7.543.887l.902-.012h102.769l.913.013a12.385 12.385 0 0 1 1.858.162 5.938 5.938 0 0 1 1.671.548 5.594 5.594 0 0 1 2.415 2.42 5.763 5.763 0 0 1 .535 1.649 12.995 12.995 0 0 1 .174 1.887c.003.283.003.588.003.89.008.375.008.732.008 1.092v20.929c0 .363 0 .718-.008 1.075 0 .325 0 .623-.004.93a12.731 12.731 0 0 1-.17 1.853 5.739 5.739 0 0 1-.54 1.67 5.48 5.48 0 0 1-1.016 1.386 5.413 5.413 0 0 1-1.4 1.022 5.862 5.862 0 0 1-1.668.55 12.542 12.542 0 0 1-1.869.163c-.293.007-.6.011-.897.011l-1.084.002Z"
fill="#000"
/>
<path
d="m24.769 20.3-.022-.024a4.486 4.486 0 0 1 2.164-3.765 4.596 4.596 0 0 0-3.625-1.96c-1.525-.16-3.01.914-3.79.914-.79 0-1.987-.9-3.27-.874a4.812 4.812 0 0 0-4.056 2.472c-1.75 3.027-.447 7.483 1.235 9.933.838 1.199 1.822 2.538 3.105 2.49 1.255-.05 1.727-.8 3.243-.8 1.506 0 1.948.8 3.254.77 1.347-.022 2.197-1.207 3.012-2.418a10.002 10.002 0 0 0 1.372-2.8 4.336 4.336 0 0 1-2.622-3.938ZM22.315 12.84a4.415 4.415 0 0 0 1.012-3.166 4.498 4.498 0 0 0-2.91 1.506 4.212 4.212 0 0 0-1.04 3.052 3.72 3.72 0 0 0 2.938-1.392Z"
fill="#fff"
/>
<path
d="M42.302 27.14H37.57l-1.137 3.356h-2.005l4.484-12.418h2.083l4.483 12.418h-2.039Zm-4.243-1.55h3.752l-1.85-5.446h-.051ZM55.16 25.97c0 2.813-1.506 4.62-3.779 4.62a3.073 3.073 0 0 1-2.848-1.583h-.043v4.484h-1.86V21.442h1.8v1.506h.034a3.212 3.212 0 0 1 2.883-1.6c2.298 0 3.813 1.816 3.813 4.622Zm-1.91 0c0-1.833-.947-3.038-2.393-3.038-1.42 0-2.375 1.23-2.375 3.038 0 1.824.955 3.046 2.375 3.046 1.446 0 2.393-1.197 2.393-3.046ZM65.125 25.97c0 2.813-1.506 4.62-3.779 4.62a3.073 3.073 0 0 1-2.848-1.583h-.043v4.484h-1.859V21.442h1.799v1.506h.034a3.212 3.212 0 0 1 2.883-1.6c2.298 0 3.813 1.816 3.813 4.622Zm-1.91 0c0-1.833-.947-3.038-2.393-3.038-1.42 0-2.375 1.23-2.375 3.038 0 1.824.955 3.046 2.375 3.046 1.446 0 2.393-1.197 2.393-3.046ZM71.71 27.036c.138 1.232 1.335 2.04 2.97 2.04 1.566 0 2.693-.808 2.693-1.919 0-.964-.68-1.54-2.29-1.936l-1.609-.388c-2.28-.55-3.339-1.617-3.339-3.348 0-2.142 1.867-3.614 4.519-3.614 2.624 0 4.423 1.472 4.483 3.614h-1.876c-.112-1.239-1.137-1.987-2.634-1.987s-2.521.757-2.521 1.858c0 .878.654 1.395 2.255 1.79l1.368.336c2.548.603 3.606 1.626 3.606 3.443 0 2.323-1.85 3.778-4.793 3.778-2.754 0-4.614-1.42-4.734-3.667ZM83.346 19.3v2.142h1.722v1.472h-1.722v4.991c0 .776.345 1.137 1.102 1.137.204-.004.408-.018.611-.043v1.463a5.104 5.104 0 0 1-1.032.086c-1.833 0-2.548-.689-2.548-2.444v-5.19h-1.316v-1.472h1.316V19.3ZM86.065 25.97c0-2.849 1.678-4.639 4.294-4.639 2.625 0 4.295 1.79 4.295 4.639 0 2.856-1.661 4.638-4.295 4.638-2.633 0-4.294-1.782-4.294-4.638Zm6.695 0c0-1.954-.895-3.108-2.401-3.108s-2.401 1.162-2.401 3.108c0 1.962.895 3.106 2.401 3.106s2.401-1.144 2.401-3.106ZM96.186 21.442h1.773v1.541h.043a2.16 2.16 0 0 1 2.178-1.635 2.866 2.866 0 0 1 .637.069v1.738a2.598 2.598 0 0 0-.835-.112 1.873 1.873 0 0 0-1.937 2.083v5.37h-1.859ZM109.384 27.837c-.25 1.643-1.85 2.771-3.898 2.771-2.634 0-4.269-1.764-4.269-4.595 0-2.84 1.644-4.682 4.191-4.682 2.505 0 4.08 1.72 4.08 4.466v.637h-6.395v.112a2.353 2.353 0 0 0 2.436 2.564 2.048 2.048 0 0 0 2.09-1.273Zm-6.282-2.702h4.526a2.177 2.177 0 0 0-2.22-2.298 2.292 2.292 0 0 0-2.306 2.298Z"
fill="#fff"
/>
<path
d="M37.826 8.731a2.64 2.64 0 0 1 2.808 2.965c0 1.906-1.03 3.002-2.808 3.002h-2.155V8.73Zm-1.228 5.123h1.125a1.876 1.876 0 0 0 1.967-2.146 1.881 1.881 0 0 0-1.967-2.134h-1.125ZM41.68 12.444a2.133 2.133 0 1 1 4.248 0 2.134 2.134 0 1 1-4.247 0Zm3.334 0c0-.976-.439-1.547-1.208-1.547-.773 0-1.207.571-1.207 1.547 0 .984.434 1.55 1.207 1.55.77 0 1.208-.57 1.208-1.55ZM51.573 14.698h-.922l-.93-3.317h-.07l-.927 3.317h-.913l-1.242-4.503h.902l.806 3.436h.067l.925-3.436h.852l.926 3.436h.07l.803-3.436h.889ZM53.854 10.195h.855v.715h.066a1.348 1.348 0 0 1 1.344-.802 1.465 1.465 0 0 1 1.559 1.675v2.915h-.889v-2.692c0-.724-.314-1.084-.972-1.084a1.033 1.033 0 0 0-1.075 1.141v2.635h-.888ZM59.094 8.437h.888v6.26h-.888ZM61.218 12.444a2.133 2.133 0 1 1 4.247 0 2.134 2.134 0 1 1-4.247 0Zm3.333 0c0-.976-.439-1.547-1.208-1.547-.773 0-1.207.571-1.207 1.547 0 .984.435 1.55 1.207 1.55.77 0 1.208-.57 1.208-1.55ZM66.4 13.424c0-.81.604-1.278 1.676-1.344l1.22-.07v-.389c0-.476-.315-.744-.922-.744-.497 0-.84.182-.939.5h-.86c.09-.773.818-1.27 1.84-1.27 1.128 0 1.765.563 1.765 1.514v3.077h-.855v-.633h-.07a1.515 1.515 0 0 1-1.353.707 1.36 1.36 0 0 1-1.501-1.348Zm2.895-.384v-.377l-1.1.07c-.62.042-.9.253-.9.65 0 .405.351.64.834.64a1.062 1.062 0 0 0 1.166-.983ZM71.348 12.444c0-1.423.732-2.324 1.87-2.324a1.484 1.484 0 0 1 1.38.79h.067V8.437h.888v6.26h-.851v-.71h-.07a1.563 1.563 0 0 1-1.415.785c-1.145 0-1.869-.901-1.869-2.328Zm.918 0c0 .955.45 1.53 1.203 1.53.75 0 1.212-.583 1.212-1.526 0-.938-.468-1.53-1.212-1.53-.748 0-1.203.58-1.203 1.526ZM79.23 12.444a2.133 2.133 0 1 1 4.247 0 2.134 2.134 0 1 1-4.248 0Zm3.333 0c0-.976-.439-1.547-1.208-1.547-.773 0-1.207.571-1.207 1.547 0 .984.435 1.55 1.207 1.55.77 0 1.208-.57 1.208-1.55ZM84.67 10.195h.855v.715h.066a1.348 1.348 0 0 1 1.344-.802 1.465 1.465 0 0 1 1.559 1.675v2.915h-.889v-2.692c0-.724-.314-1.084-.972-1.084a1.033 1.033 0 0 0-1.075 1.141v2.635h-.888ZM93.515 9.074v1.141h.976v.749h-.976v2.315c0 .472.195.678.637.678.113 0 .226-.007.339-.02v.74a2.95 2.95 0 0 1-.484.046c-.988 0-1.381-.348-1.381-1.216v-2.543h-.715v-.749h.715V9.074ZM95.705 8.437h.88v2.481h.07a1.386 1.386 0 0 1 1.374-.806 1.483 1.483 0 0 1 1.55 1.679v2.907h-.889V12.01c0-.72-.335-1.084-.963-1.084a1.052 1.052 0 0 0-1.134 1.142v2.63h-.888ZM104.761 13.482a1.828 1.828 0 0 1-1.95 1.303 2.045 2.045 0 0 1-2.081-2.325 2.077 2.077 0 0 1 2.076-2.352c1.253 0 2.009.856 2.009 2.27v.31h-3.18v.05a1.19 1.19 0 0 0 1.2 1.29 1.08 1.08 0 0 0 1.07-.546Zm-3.126-1.451h2.275a1.086 1.086 0 0 0-1.109-1.167 1.152 1.152 0 0 0-1.166 1.167Z"
fill="#fff"
/>
</svg> </svg>
Download for iOS
</a> </a>
<a href="#how-it-works" className="btn-secondary flex items-center gap-2 w-full sm:w-auto justify-center"> <a href="#how-it-works" className="btn-secondary flex items-center gap-2 w-full sm:w-auto justify-center">
Learn More See How It Works
</a> </a>
</div> </div>
</motion.div> </motion.div>
@@ -76,7 +110,7 @@ export default function Hero() {
initial={{ opacity: 0, x: 60, rotate: 12 }} initial={{ opacity: 0, x: 60, rotate: 12 }}
animate={{ opacity: 1, x: 60, rotate: 12 }} animate={{ opacity: 1, x: 60, rotate: 12 }}
transition={{ duration: 0.8, delay: 0.6 }} transition={{ duration: 0.8, delay: 0.6 }}
className="absolute -right-4 sm:right-0" className="absolute -right-4 sm:right-0 phone-tilt"
> >
<PhoneMockup <PhoneMockup
screenshot="/screenshots/packs.png" screenshot="/screenshots/packs.png"
@@ -90,7 +124,7 @@ export default function Hero() {
initial={{ opacity: 0, x: -60, rotate: -12 }} initial={{ opacity: 0, x: -60, rotate: -12 }}
animate={{ opacity: 1, x: -60, rotate: -12 }} animate={{ opacity: 1, x: -60, rotate: -12 }}
transition={{ duration: 0.8, delay: 0.5 }} transition={{ duration: 0.8, delay: 0.5 }}
className="absolute -left-4 sm:left-0" className="absolute -left-4 sm:left-0 phone-tilt"
> >
<PhoneMockup <PhoneMockup
screenshot="/screenshots/swipe.png" screenshot="/screenshots/swipe.png"
@@ -104,7 +138,7 @@ export default function Hero() {
initial={{ opacity: 0, y: 30 }} initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.4 }} transition={{ duration: 0.8, delay: 0.4 }}
className="relative z-10 animate-float" className="relative z-10 animate-float phone-tilt"
> >
<PhoneMockup <PhoneMockup
screenshot="/screenshots/home.png" screenshot="/screenshots/home.png"
@@ -117,12 +151,12 @@ export default function Hero() {
</motion.div> </motion.div>
</div> </div>
{/* Scroll Indicator */} {/* Scroll Indicator - fades out on scroll */}
<motion.div <motion.div
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: hasScrolled ? 0 : 1 }}
transition={{ delay: 1.5 }} transition={{ duration: 0.3 }}
className="absolute bottom-8 left-1/2 -translate-x-1/2" className="absolute bottom-8 left-1/2 -translate-x-1/2 pointer-events-none"
> >
<div className="w-6 h-10 rounded-full border-2 border-white/20 flex justify-center pt-2"> <div className="w-6 h-10 rounded-full border-2 border-white/20 flex justify-center pt-2">
<motion.div <motion.div
+25 -5
View File
@@ -1,27 +1,42 @@
'use client' 'use client'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { UserPlus, Layers, Hand, Heart, type LucideIcon } from 'lucide-react'
const steps = [ const steps: Array<{
number: string
title: string
description: string
icon: LucideIcon
color: string
}> = [
{ {
number: '01', number: '01',
title: 'Connect with Your Partner', title: 'Connect with Your Partner',
description: 'Create your account and invite your partner using a unique code. Your journey begins together.', description: 'Create your account and invite your partner using a unique code. Your journey begins together.',
icon: UserPlus,
color: 'text-primary',
}, },
{ {
number: '02', number: '02',
title: 'Browse Question Packs', title: 'Browse Question Packs',
description: 'Choose from curated packs ranging from romantic to adventurous. Each pack contains thoughtful questions.', description: 'Choose from curated packs ranging from romantic to adventurous. Each pack contains thoughtful questions.',
icon: Layers,
color: 'text-secondary',
}, },
{ {
number: '03', number: '03',
title: 'Swipe on Questions', title: 'Swipe on Questions',
description: 'Answer each question honestly. Swipe right for yes, left for no, or up for maybe. Your answers stay private.', description: 'Answer each question honestly. Swipe right for yes, left for no, or up for maybe. Your answers stay private.',
icon: Hand,
color: 'text-orange-400',
}, },
{ {
number: '04', number: '04',
title: 'Discover Your Matches', title: 'Discover Your Matches',
description: 'When both partners answer positively, it\'s a match! Explore your shared desires through private chats.', description: 'When both partners answer positively, it\'s a match! Explore your shared desires through private chats.',
icon: Heart,
color: 'text-pink-400',
}, },
] ]
@@ -64,12 +79,17 @@ export default function HowItWorks() {
<div className="hidden lg:block absolute top-12 left-[60%] w-full h-0.5 bg-gradient-to-r from-primary/50 to-transparent" /> <div className="hidden lg:block absolute top-12 left-[60%] w-full h-0.5 bg-gradient-to-r from-primary/50 to-transparent" />
)} )}
<div className="glass p-6 h-full"> <div className="glass p-6 h-full group hover:border-white/20 transition-colors">
<div className="text-5xl font-bold gradient-text mb-4 opacity-50"> <div className="flex items-center gap-3 mb-4">
{step.number} <div className="text-4xl font-bold gradient-text opacity-50">
{step.number}
</div>
<div className={`w-10 h-10 rounded-xl bg-white/5 flex items-center justify-center group-hover:scale-110 transition-transform`}>
<step.icon className={`w-5 h-5 ${step.color}`} />
</div>
</div> </div>
<h3 className="text-xl font-semibold mb-2">{step.title}</h3> <h3 className="text-xl font-semibold mb-2">{step.title}</h3>
<p className="text-white/60">{step.description}</p> <p className="text-white/70">{step.description}</p>
</div> </div>
</motion.div> </motion.div>
))} ))}
+54 -40
View File
@@ -3,7 +3,7 @@
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import Link from 'next/link' import Link from 'next/link'
import Image from 'next/image' import Image from 'next/image'
import { motion } from 'framer-motion' import { motion, AnimatePresence } from 'framer-motion'
import { Menu, X } from 'lucide-react' import { Menu, X } from 'lucide-react'
export default function Navbar() { export default function Navbar() {
@@ -49,6 +49,9 @@ export default function Navbar() {
<a href="#pricing" className="text-white/70 hover:text-white transition-colors"> <a href="#pricing" className="text-white/70 hover:text-white transition-colors">
Pro Pro
</a> </a>
<a href="#faq" className="text-white/70 hover:text-white transition-colors">
FAQ
</a>
<a <a
href="https://apps.apple.com/app/sauci" href="https://apps.apple.com/app/sauci"
target="_blank" target="_blank"
@@ -69,45 +72,56 @@ export default function Navbar() {
</div> </div>
{/* Mobile Menu */} {/* Mobile Menu */}
{isMobileMenuOpen && ( <AnimatePresence>
<motion.div {isMobileMenuOpen && (
initial={{ opacity: 0, y: -20 }} <motion.div
animate={{ opacity: 1, y: 0 }} initial={{ opacity: 0, y: -20 }}
className="md:hidden glass mt-4 mx-6 p-6" animate={{ opacity: 1, y: 0 }}
> exit={{ opacity: 0, y: -20 }}
<div className="flex flex-col gap-4"> transition={{ duration: 0.2 }}
<a className="md:hidden glass mt-4 mx-6 p-6"
href="#features" >
className="text-white/70 hover:text-white transition-colors" <div className="flex flex-col gap-4">
onClick={() => setIsMobileMenuOpen(false)} <a
> href="#features"
Features className="text-white/70 hover:text-white transition-colors"
</a> onClick={() => setIsMobileMenuOpen(false)}
<a >
href="#how-it-works" Features
className="text-white/70 hover:text-white transition-colors" </a>
onClick={() => setIsMobileMenuOpen(false)} <a
> href="#how-it-works"
How It Works className="text-white/70 hover:text-white transition-colors"
</a> onClick={() => setIsMobileMenuOpen(false)}
<a >
href="#pricing" How It Works
className="text-white/70 hover:text-white transition-colors" </a>
onClick={() => setIsMobileMenuOpen(false)} <a
> href="#pricing"
Pro className="text-white/70 hover:text-white transition-colors"
</a> onClick={() => setIsMobileMenuOpen(false)}
<a >
href="https://apps.apple.com/app/sauci" Pro
target="_blank" </a>
rel="noopener noreferrer" <a
className="btn-primary text-sm py-3 px-6 text-center" href="#faq"
> className="text-white/70 hover:text-white transition-colors"
Download App onClick={() => setIsMobileMenuOpen(false)}
</a> >
</div> FAQ
</motion.div> </a>
)} <a
href="https://apps.apple.com/app/sauci"
target="_blank"
rel="noopener noreferrer"
className="btn-primary text-sm py-3 px-6 text-center"
>
Download App
</a>
</div>
</motion.div>
)}
</AnimatePresence>
</motion.nav> </motion.nav>
) )
} }
+9 -2
View File
@@ -66,9 +66,16 @@ export default function Pricing() {
</div> </div>
<h3 className="text-2xl font-bold text-center mb-2">One Subscription, Both Partners</h3> <h3 className="text-2xl font-bold text-center mb-2">One Subscription, Both Partners</h3>
<p className="text-white/60 text-center mb-6">
{/* Pricing Display */}
<div className="text-center mb-4">
<span className="text-4xl font-bold gradient-text">From £4.99</span>
<span className="text-white/60 text-lg">/month</span>
</div>
<p className="text-white/70 text-center mb-6">
When you upgrade to Pro, your partner automatically gets full access too. When you upgrade to Pro, your partner automatically gets full access too.
No separate purchases needed - you're in this together. No separate purchases needed - you&apos;re in this together.
</p> </p>
{/* Feature List */} {/* Feature List */}