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

+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 }}
viewport={{ once: true }}
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`}>
<feature.icon className={`w-7 h-7 ${feature.color}`} />
<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={`${index < 2 ? 'w-8 h-8' : 'w-7 h-7'} ${feature.color} group-hover:scale-110 transition-transform duration-300`} />
</div>
<h3 className="text-xl font-semibold mb-2">{feature.title}</h3>
<p className="text-white/60">{feature.description}</p>
<h3 className={`${index < 2 ? 'text-2xl' : 'text-xl'} font-semibold mb-2`}>{feature.title}</h3>
<p className="text-white/70">{feature.description}</p>
</motion.div>
))}
</div>
+52 -18
View File
@@ -1,10 +1,21 @@
'use client'
import { useEffect, useState } from 'react'
import Image from 'next/image'
import { motion } from 'framer-motion'
import { Sparkles } from 'lucide-react'
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 (
<section className="relative min-h-screen flex items-center justify-center overflow-hidden pt-20">
{/* Background Effects */}
@@ -29,33 +40,56 @@ export default function Hero() {
className="inline-flex items-center gap-2 glass px-4 py-2 mb-6"
>
<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>
<h1 className="text-4xl sm:text-5xl lg:text-6xl xl:text-7xl font-bold leading-tight mb-6">
Ignite Your{' '}
<span className="gradient-text">Connection</span>
Discover What You{' '}
<span className="gradient-text">Both Desire</span>
</h1>
<p className="text-lg sm:text-xl text-white/60 max-w-xl mx-auto lg:mx-0 mb-8">
Sauci helps couples explore their desires through playful questions.
Swipe, match, and unlock deeper conversations with your partner.
<p className="text-lg sm:text-xl text-white/70 max-w-xl mx-auto lg:mx-0 mb-8">
Swipe on intimate questions with your partner. When you both say yes,
it&apos;s a match. Start conversations you&apos;ve always wanted to have.
</p>
<div className="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-4">
{/* Official App Store Badge */}
<a
href="https://apps.apple.com/app/sauci"
target="_blank"
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">
<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"/>
<svg
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>
Download for iOS
</a>
<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>
</div>
</motion.div>
@@ -76,7 +110,7 @@ export default function Hero() {
initial={{ opacity: 0, x: 60, rotate: 12 }}
animate={{ opacity: 1, x: 60, rotate: 12 }}
transition={{ duration: 0.8, delay: 0.6 }}
className="absolute -right-4 sm:right-0"
className="absolute -right-4 sm:right-0 phone-tilt"
>
<PhoneMockup
screenshot="/screenshots/packs.png"
@@ -90,7 +124,7 @@ export default function Hero() {
initial={{ opacity: 0, x: -60, rotate: -12 }}
animate={{ opacity: 1, x: -60, rotate: -12 }}
transition={{ duration: 0.8, delay: 0.5 }}
className="absolute -left-4 sm:left-0"
className="absolute -left-4 sm:left-0 phone-tilt"
>
<PhoneMockup
screenshot="/screenshots/swipe.png"
@@ -104,7 +138,7 @@ export default function Hero() {
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.4 }}
className="relative z-10 animate-float"
className="relative z-10 animate-float phone-tilt"
>
<PhoneMockup
screenshot="/screenshots/home.png"
@@ -117,12 +151,12 @@ export default function Hero() {
</motion.div>
</div>
{/* Scroll Indicator */}
{/* Scroll Indicator - fades out on scroll */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 1.5 }}
className="absolute bottom-8 left-1/2 -translate-x-1/2"
animate={{ opacity: hasScrolled ? 0 : 1 }}
transition={{ duration: 0.3 }}
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">
<motion.div
+25 -5
View File
@@ -1,27 +1,42 @@
'use client'
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',
title: 'Connect with Your Partner',
description: 'Create your account and invite your partner using a unique code. Your journey begins together.',
icon: UserPlus,
color: 'text-primary',
},
{
number: '02',
title: 'Browse Question Packs',
description: 'Choose from curated packs ranging from romantic to adventurous. Each pack contains thoughtful questions.',
icon: Layers,
color: 'text-secondary',
},
{
number: '03',
title: 'Swipe on Questions',
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',
title: 'Discover Your Matches',
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="glass p-6 h-full">
<div className="text-5xl font-bold gradient-text mb-4 opacity-50">
{step.number}
<div className="glass p-6 h-full group hover:border-white/20 transition-colors">
<div className="flex items-center gap-3 mb-4">
<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>
<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>
</motion.div>
))}
+54 -40
View File
@@ -3,7 +3,7 @@
import { useState, useEffect } from 'react'
import Link from 'next/link'
import Image from 'next/image'
import { motion } from 'framer-motion'
import { motion, AnimatePresence } from 'framer-motion'
import { Menu, X } from 'lucide-react'
export default function Navbar() {
@@ -49,6 +49,9 @@ export default function Navbar() {
<a href="#pricing" className="text-white/70 hover:text-white transition-colors">
Pro
</a>
<a href="#faq" className="text-white/70 hover:text-white transition-colors">
FAQ
</a>
<a
href="https://apps.apple.com/app/sauci"
target="_blank"
@@ -69,45 +72,56 @@ export default function Navbar() {
</div>
{/* Mobile Menu */}
{isMobileMenuOpen && (
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
className="md:hidden glass mt-4 mx-6 p-6"
>
<div className="flex flex-col gap-4">
<a
href="#features"
className="text-white/70 hover:text-white transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Features
</a>
<a
href="#how-it-works"
className="text-white/70 hover:text-white transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
How It Works
</a>
<a
href="#pricing"
className="text-white/70 hover:text-white transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Pro
</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>
{isMobileMenuOpen && (
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.2 }}
className="md:hidden glass mt-4 mx-6 p-6"
>
<div className="flex flex-col gap-4">
<a
href="#features"
className="text-white/70 hover:text-white transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Features
</a>
<a
href="#how-it-works"
className="text-white/70 hover:text-white transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
How It Works
</a>
<a
href="#pricing"
className="text-white/70 hover:text-white transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
Pro
</a>
<a
href="#faq"
className="text-white/70 hover:text-white transition-colors"
onClick={() => setIsMobileMenuOpen(false)}
>
FAQ
</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>
)
}
+9 -2
View File
@@ -66,9 +66,16 @@ export default function Pricing() {
</div>
<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.
No separate purchases needed - you're in this together.
No separate purchases needed - you&apos;re in this together.
</p>
{/* Feature List */}