Compare commits
32 Commits
version_3_
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 29a417e0ff | |||
| 3d36ee0578 | |||
| cdd6bc479b | |||
| 4c6f5fc098 | |||
| edc3ec1792 | |||
| 83c167354b | |||
| a6c8c58c20 | |||
| eb390616cf | |||
| 2e98cae445 | |||
| 9faabe0a8a | |||
| 535dff6339 | |||
| c62596b255 | |||
| 9d7986f28a | |||
| 772c3ed4b2 | |||
| d9d242b074 | |||
| a389ba9b9a | |||
| 8bc88549bc | |||
| d4e7be24e6 | |||
| 3b428bf5ed | |||
| 5731a4e501 | |||
| d36c1de359 | |||
| d14219166e | |||
| 66bccb81e1 | |||
| e84d27b676 | |||
| c49239c239 | |||
| 8bd912afae | |||
| 85897f2358 | |||
| 1a9c61038b | |||
| 7c5c7dbc08 | |||
| b574b9e929 | |||
| 814f09b59f | |||
| 71528728c4 |
@@ -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>
|
||||
);
|
||||
|
||||
@@ -15,7 +15,9 @@ export default function Layout() {
|
||||
{
|
||||
"name": "About",
|
||||
"href": "#about"
|
||||
}
|
||||
},
|
||||
{ name: "Pricing", href: "/pricing" },
|
||||
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
49
src/components/sections/blog/BlogSection.tsx
Normal file
49
src/components/sections/blog/BlogSection.tsx
Normal 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: "#",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
35
src/components/sections/contact/ContactFormSection.tsx
Normal file
35
src/components/sections/contact/ContactFormSection.tsx
Normal 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
|
||||
/>
|
||||
);
|
||||
}
|
||||
62
src/components/sections/hero/HeroCenteredMedia.tsx
Normal file
62
src/components/sections/hero/HeroCenteredMedia.tsx
Normal 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;
|
||||
61
src/components/sections/hero/HeroSplitImage.tsx
Normal file
61
src/components/sections/hero/HeroSplitImage.tsx
Normal 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;
|
||||
69
src/components/sections/metrics/MetricsSection.tsx
Normal file
69
src/components/sections/metrics/MetricsSection.tsx
Normal 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;
|
||||
43
src/components/sections/other/StatsSection.tsx
Normal file
43
src/components/sections/other/StatsSection.tsx
Normal 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;
|
||||
97
src/components/sections/team/TeamSection.tsx
Normal file
97
src/components/sections/team/TeamSection.tsx
Normal 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;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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%); }
|
||||
}
|
||||
@@ -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
72
src/pages/PricingPage.tsx
Normal 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;
|
||||
@@ -6,4 +6,5 @@ export interface Route {
|
||||
|
||||
export const routes: Route[] = [
|
||||
{ path: '/', label: 'Home', pageFile: 'HomePage' },
|
||||
{ path: '/pricing', label: 'Pricing', pageFile: 'PricingPage' },
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user