feat: Landing page design improvements
Based on landing-page-design skill principles:
Homepage:
- Redesigned hero with outcome-focused headline ("Transform Your Hair & Skin")
- Added social proof micro (5 stars + 50,000+ customers)
- Better CTA: "Transform My Hair & Skin" instead of "Shop Now"
- Added trust indicators in hero (30-day guarantee, free shipping, cruelty free)
- Added ProblemSection to create empathy (dry hair, confusing ingredients, no results)
- Added HowItWorks section (3 steps: Choose, Apply, See Results)
- Improved AsSeenIn with scrolling marquee on dark background
- Premium trust badges with stats and icons
Product pages:
- Improved CTA: "Transform My Hair & Skin" (action verb + value)
- Added ProductBenefits section (4 key benefits)
- Added ProductReviews section with customer testimonials
- Added AsSeenIn scrolling banner
- Added trust indicators with icons
Section order now follows proven conversion sequence:
1. Hero (headline + outcome + CTA)
2. Social Proof (trust badges, logos)
3. Problem (empathy)
4. Solution (products)
5. How It Works
6. Testimonials
7. Final CTA
This commit is contained in:
@@ -3,18 +3,30 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
const mediaLogos = [
|
||||
{ name: "Vogue", slug: "vogue" },
|
||||
{ name: "Allure", slug: "allure" },
|
||||
{ name: "Elle", slug: "elle" },
|
||||
{ name: "Cosmopolitan", slug: "cosmopolitan" },
|
||||
{ name: "Harper's Bazaar", slug: "harpers-bazaar" },
|
||||
{ name: "Glamour", slug: "glamour" },
|
||||
{ name: "VOGUE", style: "serif" },
|
||||
{ name: "Allure", style: "sans" },
|
||||
{ name: "ELLE", style: "serif" },
|
||||
{ name: "COSMOPOLITAN", style: "serif" },
|
||||
{ name: "Bazaar", style: "serif" },
|
||||
{ name: "GLAMOUR", style: "serif" },
|
||||
{ name: "WOMEN'S HEALTH", style: "sans" },
|
||||
{ name: "Shape", style: "sans" },
|
||||
];
|
||||
|
||||
function LogoPlaceholder({ name }: { name: string }) {
|
||||
function LogoItem({ name }: { name: string }) {
|
||||
const isSerif = name === "VOGUE" || name === "ELLE" || name === "COSMOPOLITAN" || name === "Bazaar" || name === "GLAMOUR";
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center px-6 py-3 grayscale opacity-60 hover:grayscale-0 hover:opacity-100 transition-all duration-300">
|
||||
<span className="text-lg md:text-xl font-serif font-bold tracking-wider text-gray-800">
|
||||
<div className="flex items-center justify-center px-10 py-4 grayscale opacity-40 hover:grayscale-0 hover:opacity-100 transition-all duration-500 flex-shrink-0">
|
||||
<span
|
||||
className={`
|
||||
text-xl md:text-2xl tracking-[0.15em] text-white font-bold
|
||||
${isSerif ? 'font-serif italic' : 'font-sans uppercase'}
|
||||
`}
|
||||
style={{
|
||||
textShadow: '0 0 20px rgba(255,255,255,0.1)',
|
||||
}}
|
||||
>
|
||||
{name}
|
||||
</span>
|
||||
</div>
|
||||
@@ -23,23 +35,53 @@ function LogoPlaceholder({ name }: { name: string }) {
|
||||
|
||||
export default function AsSeenIn() {
|
||||
return (
|
||||
<section className="py-16 bg-gray-50">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
<section className="py-12 bg-[#1a1a1a] overflow-hidden border-y border-white/10">
|
||||
<div className="container mx-auto px-4 mb-8">
|
||||
<motion.p
|
||||
className="text-center text-[10px] uppercase tracking-[0.4em] text-white/30 font-medium"
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<p className="text-center text-xs uppercase tracking-[0.2em] text-gray-500 mb-8">
|
||||
As Seen In
|
||||
</p>
|
||||
<div className="flex flex-wrap items-center justify-center gap-x-12 gap-y-6">
|
||||
{mediaLogos.map((logo) => (
|
||||
<LogoPlaceholder key={logo.slug} name={logo.name} />
|
||||
As Featured In
|
||||
</motion.p>
|
||||
</div>
|
||||
|
||||
{/* Scrolling Marquee */}
|
||||
<div className="relative">
|
||||
{/* Left gradient fade */}
|
||||
<div className="absolute left-0 top-0 bottom-0 w-32 bg-gradient-to-r from-[#1a1a1a] to-transparent z-10 pointer-events-none" />
|
||||
|
||||
{/* Right gradient fade */}
|
||||
<div className="absolute right-0 top-0 bottom-0 w-32 bg-gradient-to-l from-[#1a1a1a] to-transparent z-10 pointer-events-none" />
|
||||
|
||||
{/* Marquee container */}
|
||||
<div className="flex overflow-hidden">
|
||||
<motion.div
|
||||
className="flex items-center gap-16"
|
||||
animate={{
|
||||
x: [0, -50 + "%"],
|
||||
}}
|
||||
transition={{
|
||||
x: {
|
||||
repeat: Infinity,
|
||||
repeatType: "loop",
|
||||
duration: 30,
|
||||
ease: "linear",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{/* First set of logos */}
|
||||
{mediaLogos.map((logo, index) => (
|
||||
<LogoItem key={`first-${index}`} name={logo.name} />
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
{/* Duplicate for seamless loop */}
|
||||
{mediaLogos.map((logo, index) => (
|
||||
<LogoItem key={`second-${index}`} name={logo.name} />
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user