35 Commits

Author SHA1 Message Date
29a417e0ff Bob AI: Populate the newly-created page at src/pages/PricingPage.tsx 2026-04-27 11:09:36 +03:00
3d36ee0578 Bob AI: Add pricing page 2026-04-27 11:08:14 +03:00
cdd6bc479b Bob AI: fix build errors (attempt 2) 2026-04-27 10:54:44 +03:00
4c6f5fc098 Bob AI: fix build errors (attempt 1) 2026-04-27 10:53:22 +03:00
edc3ec1792 Bob AI: Replace the current hero section with a new hero component t 2026-04-27 10:52:10 +03:00
83c167354b Bob AI: Replace the existing hero section with the 'HeroSplitImage' 2026-04-27 10:46:06 +03:00
a6c8c58c20 Bob AI: Replace hero with HeroBillboard in hero 2026-04-27 10:43:44 +03:00
eb390616cf Bob AI: Change the background color of all card elements across the 2026-04-27 10:43:08 +03:00
2e98cae445 Bob AI: Change the default color of all buttons across the site to b 2026-04-27 10:41:42 +03:00
9faabe0a8a Bob AI: fix build errors (attempt 2) 2026-04-27 01:44:38 +03:00
535dff6339 Bob AI: fix build errors (attempt 1) 2026-04-27 01:43:33 +03:00
c62596b255 Bob AI: Replace the current hero image with an ocean view image in t 2026-04-27 01:42:23 +03:00
9d7986f28a Bob AI: fix build errors (attempt 1) 2026-04-27 01:41:00 +03:00
772c3ed4b2 Bob AI: [SECTION ADD OPERATION]
You must create a COMPLETELY NEW sec
2026-04-27 01:39:48 +03:00
d9d242b074 Bob AI: Change the site's primary theme color to navy blue by updati 2026-04-27 01:37:50 +03:00
a389ba9b9a Bob AI: fix build errors (attempt 1) 2026-04-27 01:37:03 +03:00
8bc88549bc Bob AI: Change the hero section's headline text to 'Productivity for 2026-04-27 01:36:49 +03:00
d4e7be24e6 Bob AI: Replace the current hero image with a mountain landscape ima 2026-04-27 01:35:59 +03:00
3b428bf5ed Bob AI: [SECTION ADD OPERATION]
You must create a COMPLETELY NEW sec
2026-04-27 01:34:50 +03:00
5731a4e501 Bob AI: fix build errors (attempt 2) 2026-04-27 01:30:16 +03:00
d36c1de359 Bob AI: fix build errors (attempt 1) 2026-04-27 01:29:15 +03:00
d14219166e Bob AI: Replace the existing testimonials section with a testimonial 2026-04-27 01:28:09 +03:00
66bccb81e1 Bob AI: fix build errors (attempt 1) 2026-04-27 01:25:44 +03:00
e84d27b676 Bob AI: Replace the current hero image with an image of a cityscape 2026-04-27 01:24:38 +03:00
c49239c239 Bob AI: fix build errors (attempt 2) 2026-04-27 01:21:51 +03:00
8bd912afae Bob AI: fix build errors (attempt 1) 2026-04-27 01:20:47 +03:00
85897f2358 Bob AI: [SECTION ADD OPERATION]
You must create a COMPLETELY NEW sec
2026-04-27 01:19:51 +03:00
1a9c61038b test: revert App.tsx pollution for re-test 2026-04-27 01:12:50 +03:00
7c5c7dbc08 Bob AI: [SECTION ADD OPERATION]
You must create a COMPLETELY NEW sec
2026-04-27 01:11:40 +03:00
b574b9e929 test: revert stale section-add App.tsx pollution 2026-04-27 01:08:48 +03:00
814f09b59f Bob AI: [SECTION ADD OPERATION]
You must create a COMPLETELY NEW sec
2026-04-27 01:07:25 +03:00
71528728c4 Merge version_3_1777239806625 into main
Merge version_3_1777239806625 into main
2026-04-26 21:45:30 +00:00
7253fd0a06 Bob AI: create a landing page for a SaaS productivity tool 2026-04-27 00:45:23 +03:00
4223be332c Merge version_2_1777234094173 into main
Merge version_2_1777234094173 into main
2026-04-26 20:09:34 +00:00
7b523b2ffa Bob AI: Add a social proof element, such as a row of people avatars 2026-04-26 23:09:28 +03:00
16 changed files with 689 additions and 58 deletions

View File

@@ -2,11 +2,13 @@ import { Routes, Route } from 'react-router-dom';
import Layout from './components/Layout';
import HomePage from './pages/HomePage';
import PricingPage from "@/pages/PricingPage";
export default function App() {
return (
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<HomePage />} />
<Route path="/pricing" element={<PricingPage />} />
</Route>
</Routes>
);

View File

@@ -15,7 +15,9 @@ export default function Layout() {
{
"name": "About",
"href": "#about"
}
},
{ name: "Pricing", href: "/pricing" },
];
return (

View File

@@ -0,0 +1,39 @@
import Button from "@/components/ui/Button";
export default function Navbar() {
return (
<nav className="fixed top-4 left-1/2 -translate-x-1/2 z-50 rounded-full shadow-lg px-8 py-3 backdrop-blur-xl bg-white/70 border border-white/40 w-[min(92vw,56rem)]">
<div className="flex items-center gap-8 justify-between">
<a href="/" className="text-lg font-bold text-foreground flex-shrink-0">
SaaSFlow
</a>
<div className="hidden md:flex items-center gap-8 flex-1 justify-center">
<a
href="#about"
className="text-sm text-foreground hover:text-foreground/70 transition-colors"
>
About
</a>
<a
href="#features"
className="text-sm text-foreground hover:text-foreground/70 transition-colors"
>
Features
</a>
<a
href="#pricing"
className="text-sm text-foreground hover:text-foreground/70 transition-colors"
>
Pricing
</a>
</div>
<Button
text="Get Started"
href="#contact"
variant="primary"
className="flex-shrink-0"
/>
</div>
</nav>
);
}

View File

@@ -0,0 +1,49 @@
"use client";
import BlogSimpleCards from '@/components/sections/blog/BlogSimpleCards';
export default function BlogSection() {
return (
<BlogSimpleCards
tag="Latest Insights"
title="Our Blog"
description="Stay updated with the latest in emotional intelligence and neuroscience."
items={[
{
category: "Neuroscience",
title: "The Science Behind Emotional Licensing",
excerpt: "Explore how our advanced resonance technology interfaces with neural pathways to deliver curated emotional states.",
authorName: "Dr. Sarah Chen",
authorImageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973635-8ab8b67f.png",
date: "October 26, 2023",
imageSrc: "https://images.unsplash.com/photo-1581092910302-f37479369928?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
href: "#",
},
{
category: "Technology",
title: "Building the Future of Feelings: Our Tech Stack",
excerpt: "A deep dive into the innovative technologies powering Emotify's seamless emotional integration.",
authorName: "James Wilson",
authorImageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973383-4f4896d8.png",
date: "October 19, 2023",
imageSrc: "https://images.unsplash.com/photo-1518770660439-4636190af367?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
href: "#",
},
{
category: "Well-being",
title: "The Impact of Curated Emotions on Daily Life",
excerpt: "Discover how precise emotional states can enhance productivity, creativity, and overall mental health.",
authorName: "Elena Rodriguez",
authorImageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233974133-d4570acb.png",
date: "October 12, 2023",
imageSrc: "https://images.unsplash.com/photo-1506126613403-4e2bd4dfd149?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
href: "#",
},
]}
primaryButton={{
text: "Read All Posts",
href: "#",
}}
/>
);
}

View File

@@ -0,0 +1,35 @@
"use client";
import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
export default function ContactFormSection() {
return (
<ContactSplitForm
tag="Get in Touch"
title="Have Questions?"
description="We're here to help! Send us a message and we'll get back to you as soon as possible."
inputs={[
{
name: "name",
type: "text",
placeholder: "Your Name",
required: true,
},
{
name: "email",
type: "email",
placeholder: "Your Email",
required: true,
},
]}
textarea={{
name: "message",
placeholder: "Your Message",
rows: 5,
required: true,
}}
buttonText="Send Message"
imageSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/a-futuristic-secure-contact-input-field--1777233972960-0d92d59b.png" // Reusing an existing image
/>
);
}

View File

@@ -0,0 +1,62 @@
import { motion } from "motion/react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
type HeroCenteredMediaProps = {
tag: string;
title: string;
description: string;
primaryButton: { text: string; href: string };
secondaryButton: { text: string; href: string };
} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
const HeroCenteredMedia = ({
tag,
title,
description,
primaryButton,
secondaryButton,
imageSrc,
videoSrc,
}: HeroCenteredMediaProps) => {
return (
<section aria-label="Hero section" className="pt-25 pb-20 md:py-30">
<div className="flex flex-col gap-10 md:gap-13 w-content-width mx-auto">
<div className="flex flex-col items-center gap-3 text-center">
<span className="px-3 py-1 mb-1 text-sm card rounded">{tag}</span>
<TextAnimation
text={title}
variant="slide-up"
tag="h1"
className="text-6xl font-medium text-balance"
/>
<TextAnimation
text={description}
variant="slide-up"
tag="p"
className="text-base md:text-lg leading-tight text-balance max-w-2xl"
/>
<div className="flex flex-wrap justify-center gap-3 mt-2">
<Button text={primaryButton.text} href={primaryButton.href} variant="primary" animate />
<Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" animate delay={0.1} />
</div>
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, ease: "easeOut", delay: 0.2 }}
className="w-full p-3 md:p-5 card rounded overflow-hidden"
>
<ImageOrVideo imageSrc={imageSrc} videoSrc={videoSrc} className="aspect-4/5 md:aspect-video" />
</motion.div>
</div>
</section>
);
};
export default HeroCenteredMedia;

View File

@@ -0,0 +1,61 @@
import { motion } from "motion/react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
type HeroSplitImageProps = {
title: string;
description: string;
primaryCtaText?: string;
secondaryCtaText?: string;
imageSrc?: string;
imageAlt?: string;
};
const HeroSplitImage = ({
title,
description,
primaryCtaText,
secondaryCtaText,
imageSrc,
}: HeroSplitImageProps) => {
return (
<section aria-label="Hero section" className="pt-25 pb-20 md:py-30">
<div className="mx-auto w-content-width grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
<div className="flex flex-col gap-6 items-start">
<TextAnimation
text={title}
variant="slide-up"
tag="h1"
className="text-6xl font-medium text-balance"
/>
<TextAnimation
text={description}
variant="slide-up"
tag="p"
className="text-base md:text-lg leading-tight text-balance"
/>
{(primaryCtaText || secondaryCtaText) && (
<div className="flex flex-wrap gap-4 mt-2">
{primaryCtaText && <Button text={primaryCtaText} href="#contact" variant="primary" animate />}
{secondaryCtaText && <Button text={secondaryCtaText} href="#about" variant="secondary" animate delay={0.1} />}
</div>
)}
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, ease: "easeOut", delay: 0.2 }}
className="w-full p-3 md:p-5 card rounded overflow-hidden"
>
<ImageOrVideo imageSrc={imageSrc} className="aspect-4/5 md:aspect-square rounded-lg shadow-lg" />
</motion.div>
</div>
</section>
);
};
export default HeroSplitImage;

View File

@@ -0,0 +1,69 @@
import { motion } from "motion/react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import GridOrCarousel from "@/components/ui/GridOrCarousel";
type MetricsSectionProps = {
tag: string;
title: string;
description: string;
primaryButton?: { text: string; href: string };
secondaryButton?: { text: string; href: string };
metrics: { value: string; description: string }[];
};
const MetricsSection = ({
tag,
title,
description,
primaryButton,
secondaryButton,
metrics,
}: MetricsSectionProps) => (
<section aria-label="Metrics section" className="py-20">
<div className="flex flex-col gap-8">
<div className="flex flex-col items-center w-content-width mx-auto gap-3 md:gap-2">
<span className="px-3 py-1 text-sm card rounded">{tag}</span>
<TextAnimation
text={title}
variant="slide-up"
tag="h2"
className="text-6xl font-medium text-center text-balance"
/>
<TextAnimation
text={description}
variant="slide-up"
tag="p"
className="md:max-w-6/10 text-lg leading-tight text-center"
/>
{(primaryButton || secondaryButton) && (
<div className="flex flex-wrap justify-center gap-3 mt-1 md:mt-2">
{primaryButton && <Button text={primaryButton.text} href={primaryButton.href} variant="primary" animate />}
{secondaryButton && <Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" animate delay={0.1} />}
</div>
)}
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-15%" }}
transition={{ duration: 0.6, ease: "easeOut" }}
>
<GridOrCarousel>
{metrics.map((metric, index) => (
<div key={index} className="flex flex-col items-center justify-center gap-3 p-8 h-full card rounded text-center">
<span className="text-6xl font-medium text-primary-cta">{metric.value}</span>
<span className="text-lg">{metric.description}</span>
</div>
))}
</GridOrCarousel>
</motion.div>
</div>
</section>
);
export default MetricsSection;

View File

@@ -0,0 +1,43 @@
import TextAnimation from "@/components/ui/TextAnimation";
const StatsSection = () => {
const metrics = [
{ value: "10M+", label: "Emotions Licensed" },
{ value: "99.9%", label: "Neural Uptime" },
{ value: "50k+", label: "Active Users" },
{ value: "4.9/5", label: "Average Rating" },
];
return (
<section aria-label="Stats section" className="py-20">
<div className="flex flex-col gap-8 mx-auto w-content-width">
<div className="flex flex-col items-center gap-3 md:gap-2">
<span className="px-3 py-1 text-sm card rounded">Platform Scale</span>
<TextAnimation
text="Numbers That Speak"
variant="slide-up"
tag="h2"
className="text-6xl font-medium text-center text-balance"
/>
<TextAnimation
text="Join millions of users who have already transformed their emotional well-being."
variant="slide-up"
tag="p"
className="md:max-w-6/10 text-lg leading-tight text-center"
/>
</div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-5">
{metrics.map((metric, index) => (
<div key={index} className="flex flex-col items-center justify-center p-8 card rounded text-center gap-2 hover:-translate-y-1 transition-transform duration-300">
<span className="text-5xl font-medium">{metric.value}</span>
<span className="text-base">{metric.label}</span>
</div>
))}
</div>
</div>
</section>
);
};
export default StatsSection;

View File

@@ -0,0 +1,97 @@
import { motion } from "motion/react";
import type { LucideIcon } from "lucide-react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import GridOrCarousel from "@/components/ui/GridOrCarousel";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import { resolveIcon } from "@/utils/resolve-icon";
type TeamMember = {
name: string;
role: string;
description: string;
socialLinks: { icon: string | LucideIcon; url: string }[];
} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
type TeamSectionProps = {
tag: string;
title: string;
description: string;
primaryButton?: { text: string; href: string };
secondaryButton?: { text: string; href: string };
members: TeamMember[];
};
const TeamSection = ({
tag,
title,
description,
primaryButton,
secondaryButton,
members,
}: TeamSectionProps) => {
return (
<section aria-label="Team section" className="py-20">
<div className="flex flex-col gap-8">
<div className="flex flex-col items-center w-content-width mx-auto gap-3 md:gap-2">
<span className="px-3 py-1 text-sm card rounded">{tag}</span>
<TextAnimation
text={title}
variant="slide-up"
tag="h2"
className="text-6xl font-medium text-center text-balance"
/>
<TextAnimation
text={description}
variant="slide-up"
tag="p"
className="md:max-w-6/10 text-lg leading-tight text-center"
/>
{(primaryButton || secondaryButton) && (
<div className="flex flex-wrap justify-center gap-3 mt-1 md:mt-2">
{primaryButton && <Button text={primaryButton.text} href={primaryButton.href} variant="primary" animate />}
{secondaryButton && <Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" animate delay={0.1} />}
</div>
)}
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-15%" }}
transition={{ duration: 0.6, ease: "easeOut" }}
>
<GridOrCarousel>
{members.map((member) => (
<div key={member.name} className="flex flex-col gap-5 p-5 h-full card rounded">
<div className="w-full aspect-square rounded overflow-hidden">
<ImageOrVideo imageSrc={member.imageSrc} videoSrc={member.videoSrc} className="w-full h-full object-cover" />
</div>
<div className="flex flex-col gap-2">
<h3 className="text-2xl font-medium">{member.name}</h3>
<span className="text-sm text-primary-cta">{member.role}</span>
<p className="text-base leading-tight">{member.description}</p>
</div>
<div className="flex items-center gap-3 mt-auto pt-4">
{member.socialLinks.map((link, idx) => {
const Icon = resolveIcon(link.icon);
return (
<a key={idx} href={link.url} target="_blank" rel="noopener noreferrer" className="text-foreground/60 hover:text-foreground transition-colors">
<Icon className="size-5" />
</a>
);
})}
</div>
</div>
))}
</GridOrCarousel>
</motion.div>
</div>
</section>
);
};
export default TeamSection;

View File

@@ -0,0 +1,39 @@
import { cls } from "@/lib/utils";
import ImageOrVideo from "./ImageOrVideo";
interface Avatar {
src: string;
alt: string;
}
interface AvatarGroupProps {
avatars: Avatar[];
totalCount: number;
className?: string;
}
const AvatarGroup = ({ avatars, totalCount, className = "" }: AvatarGroupProps) => {
const remainingCount = totalCount - avatars.length;
return (
<div className={cls("flex items-center gap-3", className)}>
<div className="flex -space-x-2">
{avatars.map((avatar, index) => (
<div key={index} className="w-10 h-10 rounded-full border-2 border-background overflow-hidden shrink-0 relative">
<ImageOrVideo imageSrc={avatar.src} alt={avatar.alt} className="w-full h-full object-cover" />
</div>
))}
{remainingCount > 0 && (
<div className="flex items-center justify-center w-10 h-10 rounded-full bg-accent text-sm font-medium text-foreground border-2 border-background shrink-0 relative z-10">
+{remainingCount > 999 ? `${Math.floor(remainingCount / 1000)}k` : remainingCount}
</div>
)}
</div>
<span className="text-sm font-medium text-foreground">
Join {totalCount.toLocaleString()}+ happy users
</span>
</div>
);
};
export default AvatarGroup;

View File

@@ -1,28 +1,33 @@
import type { LucideIcon } from "lucide-react";
import { resolveIcon } from "@/utils/resolve-icon";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
type Item = { icon: string | LucideIcon; label: string; value: string };
const InfoCardMarquee = ({ items }: { items: Item[] }) => {
const duplicated = [...items, ...items, ...items, ...items];
interface InfoCardMarqueeProps {
items: {
image: string;
name: string;
title: string;
quote: string;
}[];
}
export default function InfoCardMarquee({ items }: InfoCardMarqueeProps) {
return (
<div className="h-full overflow-hidden mask-fade-y">
<div className="flex flex-col animate-marquee-vertical">
{duplicated.map((item, i) => (
<div key={i} className="flex items-center justify-between gap-4 p-3 mb-4 card rounded">
<div className="flex items-center gap-3">
<div className="flex items-center justify-center h-10 w-10 secondary-button rounded">
{(() => { const Icon = resolveIcon(item.icon); return <Icon className="h-4 w-4 text-secondary-cta-text" strokeWidth={1.5} />; })()}
<section aria-label="Testimonials section" className="py-20 overflow-hidden">
<div className="flex w-max animate-[marquee_30s_linear_infinite] hover:[animation-play-state:paused]">
{[...items, ...items].map((item, index) => (
<div key={index} className="flex flex-col gap-4 w-80 md:w-96 p-6 mx-4 card rounded shrink-0">
<p className="text-lg italic text-foreground/90">"{item.quote}"</p>
<div className="flex items-center gap-4 mt-auto pt-4 border-t border-foreground/10">
<div className="size-12 rounded-full overflow-hidden shrink-0 border border-foreground/10">
<ImageOrVideo imageSrc={item.image} />
</div>
<div className="flex flex-col">
<span className="font-medium text-foreground">{item.name}</span>
<span className="text-sm text-foreground/70">{item.title}</span>
</div>
<p className="text-base truncate">{item.label}</p>
</div>
<p className="text-base">{item.value}</p>
</div>
))}
</div>
</div>
</section>
);
};
export default InfoCardMarquee;
}

View File

@@ -6,14 +6,14 @@
:root {
/* @colorThemes/lightTheme/grayBlueAccent */
--background: #ffffff;
--card: #f9f9f9;
--card: #ffffff;
--foreground: #000612e6;
--primary-cta: #106EFB;
--primary-cta: #2563eb;
--primary-cta-text: #ffffff;
--secondary-cta: #f9f9f9;
--secondary-cta-text: #000612e6;
--accent: #e2e2e2;
--background-accent: #106EFB;
--background-accent: #2563eb;
/* @layout/border-radius/rounded */
--radius: 0.5rem;
@@ -177,3 +177,8 @@ h6 {
var(--color-secondary-cta);
box-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 10%, transparent);
}
@keyframes marquee {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}

View File

@@ -2,16 +2,20 @@ import AboutMediaOverlay from '@/components/sections/about/AboutMediaOverlay';
import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
import FaqSplitMedia from '@/components/sections/faq/FaqSplitMedia';
import FeaturesDetailedSteps from '@/components/sections/features/FeaturesDetailedSteps';
import HeroBillboard from '@/components/sections/hero/HeroBillboard';
import HeroCenteredMedia from '@/components/sections/hero/HeroCenteredMedia';
import PricingMediaCards from '@/components/sections/pricing/PricingMediaCards';
import ProductVariantCards from '@/components/sections/product/ProductVariantCards';
import TestimonialAvatarCard from '@/components/sections/testimonial/TestimonialAvatarCard';
import InfoCardMarquee from '@/components/ui/InfoCardMarquee';
import TeamSection from '@/components/sections/team/TeamSection';
import StatsSection from '@/components/sections/other/StatsSection';
import BlogSection from '@/components/sections/blog/BlogSection';
import ContactFormSection from '@/components/sections/contact/ContactFormSection';
export default function HomePage() {
return (
<>
<div id="hero" data-section="hero">
<HeroBillboard
<HeroCenteredMedia
tag="Revolutionize Your Being"
title="Curated Emotions for a Better You"
description="Unlock, license, and experience hand-crafted emotional states. The world's first platform designed to help you feel exactly what you need, when you need it."
@@ -23,7 +27,7 @@ export default function HomePage() {
text: "Learn How",
href: "#about",
}}
imageSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/a-futuristic-software-dashboard-interfac-1777233974191-14cce2a9.png"
imageSrc="https://images.unsplash.com/photo-1477959858617-67f85cf4f1df?q=80&w=2000&auto=format&fit=crop"
/>
</div>
@@ -169,36 +173,40 @@ export default function HomePage() {
</div>
<div id="testimonials" data-section="testimonials">
<TestimonialAvatarCard
tag="User Voices"
title="Millions Feeling Better"
primaryButton={{
text: "Join Community",
href: "#contact",
}}
avatars={[
{
name: "Alex R.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973635-8ab8b67f.png",
},
{
name: "Sarah K.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973383-4f4896d8.png",
},
{
name: "Marcus L.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233974133-d4570acb.png",
},
{
name: "Elena P.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233974854-3a6df7d9.png",
},
{
name: "David W.",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973806-d447861d.png",
},
]}
/>
<InfoCardMarquee
items={[
{
image: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973635-8ab8b67f.png",
name: "Alex R.",
title: "CEO, Company A",
quote: "This product is amazing! It completely changed how I manage my emotional states."
},
{
image: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973383-4f4896d8.png",
name: "Sarah K.",
title: "Founder, Startup B",
quote: "Transformed our workflow. The creative spark package is a game changer."
},
{
image: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233974133-d4570acb.png",
name: "Marcus L.",
title: "Software Engineer",
quote: "Deep flow helps me code for hours without distraction. Highly recommended."
},
{
image: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233974854-3a6df7d9.png",
name: "Elena P.",
title: "Creative Director",
quote: "The best investment I've made for my mental well-being this year."
},
{
image: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973806-d447861d.png",
name: "David W.",
title: "Product Manager",
quote: "Incredible technology. The instant integration is seamless and effective."
}
]}
/>
</div>
<div id="faq" data-section="faq">
@@ -256,6 +264,48 @@ export default function HomePage() {
imageSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/a-futuristic-secure-contact-input-field--1777233972960-0d92d59b.png"
/>
</div>
<div id="team" data-section="team">
<TeamSection
tag="Our Experts"
title="Meet the Minds Behind Emotify"
description="Our team of neuroscientists, engineers, and designers are dedicated to revolutionizing emotional well-being."
members={[
{
name: "Dr. Sarah Chen",
title: "Chief Neuroscientist",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973635-8ab8b67f.png"
},
{
name: "James Wilson",
title: "Lead Engineer",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233973383-4f4896d8.png"
},
{
name: "Elena Rodriguez",
title: "Head of Design",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233974133-d4570acb.png"
},
{
name: "David Kim",
title: "Product Manager",
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3A2kdHi1NSExmmN97qC0PBBxl6G/professional-headshot-of-a-happy-custome-1777233974854-3a6df7d9.png"
}
]}
/>
</div>
<div id="stats" data-section="stats">
<StatsSection />
</div>
<div id="blog" data-section="blog">
<BlogSection />
</div>
<div id="contact-form" data-section="contact-form">
<ContactFormSection />
</div>
</>
);
}
}

72
src/pages/PricingPage.tsx Normal file
View File

@@ -0,0 +1,72 @@
import React from "react";
import { routes } from "@/routes";
import NavbarCentered from "@/components/ui/NavbarCentered";
import PricingSimpleCards from "@/components/sections/pricing/PricingSimpleCards";
import FooterSimple from "@/components/sections/footer/FooterSimple";
const PricingPage: React.FC = () => {
return (
<div className="flex min-h-screen flex-col bg-background text-foreground">
<NavbarCentered
logo="Emotify"
navItems={routes.map((r) => ({ name: r.label, href: r.path }))}
ctaButton={{ text: "Get Started", href: "/#contact" }}
/>
<main className="flex-grow pt-24">
<PricingSimpleCards
tag="Pricing"
title="Simple & Transparent Pricing"
description="Choose the plan that best fits your emotional needs. No hidden fees, no surprises."
plans={[
{
tag: "Basic",
price: "$19/mo",
description: "Perfect for individuals starting their emotional journey.",
features: ["5 Emotional States", "Standard Resolution", "Basic Analytics", "Community Support"],
},
{
tag: "Pro",
price: "$49/mo",
description: "Ideal for professionals seeking deeper focus and flow.",
features: ["20 Emotional States", "HD Fidelity States", "Advanced Analytics", "Priority Support"],
},
{
tag: "Enterprise",
price: "$199/mo",
description: "For teams and power users requiring unlimited access.",
features: ["Unlimited Access", "4K Resolution States", "Private Cloud Storage", "24/7 Premium Support"],
},
]}
/>
</main>
<FooterSimple
brand="Emotify"
columns={[
{
title: "Product",
items: [
{ label: "Features", href: "/#features" },
{ label: "Pricing", href: "/pricing" },
{ label: "Catalog", href: "/#product" },
],
},
{
title: "Company",
items: [
{ label: "About Us", href: "/#about" },
{ label: "Team", href: "/#team" },
{ label: "Contact", href: "/#contact" },
],
},
]}
links={[
{ label: "Privacy Policy", href: "#" },
{ label: "Terms of Service", href: "#" },
]}
copyright="© 2024 Emotify. All rights reserved."
/>
</div>
);
};
export default PricingPage;

View File

@@ -6,4 +6,5 @@ export interface Route {
export const routes: Route[] = [
{ path: '/', label: 'Home', pageFile: 'HomePage' },
{ path: '/pricing', label: 'Pricing', pageFile: 'PricingPage' },
];