diff --git a/app/(landing)/about/layout.tsx b/app/(landing)/about/layout.tsx
new file mode 100644
index 000000000..cdf88c395
--- /dev/null
+++ b/app/(landing)/about/layout.tsx
@@ -0,0 +1,17 @@
+// components/DashboardLayout.tsx
+import BeamBackground from '@/components/landing-page/BeamBackground';
+import React, { ReactNode } from 'react';
+type AboutLayoutProps = {
+ children: ReactNode;
+};
+
+const AboutLayout = ({ children }: AboutLayoutProps) => {
+ return (
+
+ );
+};
+
+export default AboutLayout;
diff --git a/app/(landing)/about/page.tsx b/app/(landing)/about/page.tsx
index c29498bbf..0ff1e782f 100644
--- a/app/(landing)/about/page.tsx
+++ b/app/(landing)/about/page.tsx
@@ -1,6 +1,10 @@
import React from 'react';
import { Metadata } from 'next';
import { generatePageMetadata } from '@/lib/metadata';
+
+import Timeline from '@/components/landing-page/about/timeline/Timeline';
+import AboutLayout from './layout';
+
import TestimonialsSection from '@/components/testimonials/TestimonialsSection';
import { testimonials } from '@/components/testimonials/data/testimonial';
import OurTeam from './OurTeam';
@@ -10,13 +14,19 @@ export const metadata: Metadata = generatePageMetadata('about');
const AboutPage = () => {
return (
-
-
-
-
-
+
+ {/* Hero Section */}
+ {/* Boundless Difference */}
+
+
+
-
+
);
};
diff --git a/app/globals.css b/app/globals.css
index cb10f508f..581291a80 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -368,3 +368,36 @@ input[type='number'] {
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
+
+/* About Timeline Card's Background gradient for images */
+.my-gradient-box {
+ background: radial-gradient(circle, #ffffff7a, #ffffff14);
+}
+
+/* Background Images for the three Timeline Cards */
+.time-card-background-image-one {
+ background-image: url('/landing/about/Abstract_01.png');
+}
+.time-card-background-image-two {
+ background-image: url('/landing/about/Abstract_02.png');
+}
+.time-card-background-image-three {
+ background-image: url('/landing/about/Abstract_03.png');
+}
+
+.time-card-general-background-positioning {
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: bottom right;
+}
+@media (min-width: 768px) {
+ .time-card-background-image-one {
+ background-image: url('/landing/about/Abstract_01md.png');
+ }
+ .time-card-background-image-two {
+ background-image: url('/landing/about/Abstract_02md.png');
+ }
+ .time-card-background-image-three {
+ background-image: url('/landing/about/Abstract_03md.png');
+ }
+}
diff --git a/components/landing-page/about/timeline/ImageSlider.tsx b/components/landing-page/about/timeline/ImageSlider.tsx
new file mode 100644
index 000000000..122c765f5
--- /dev/null
+++ b/components/landing-page/about/timeline/ImageSlider.tsx
@@ -0,0 +1,138 @@
+'use client';
+import React, { useState } from 'react';
+import { aboutTimelineData } from '@/constants';
+import { motion } from 'framer-motion';
+import TimelineCard from './TimelineCard';
+import { ChevronLeft, ChevronRight } from 'lucide-react';
+import ProgressiveeBarSvg from './ProgressiveeBarSvg';
+
+const ImageSlider = () => {
+ const [currentIndex, setCurrentIndex] = useState(0);
+ const totalItems = aboutTimelineData.length;
+
+ const next = () => {
+ setCurrentIndex(prevIndex => (prevIndex + 1) % totalItems);
+ };
+
+ const prev = () => {
+ setCurrentIndex(prevIndex => (prevIndex - 1 + totalItems) % totalItems);
+ };
+
+ const getPosition = (
+ index: number
+ ): 'center' | 'left' | 'right' | 'hidden' => {
+ const diff = (index - currentIndex + totalItems) % totalItems;
+
+ if (diff === 0) return 'center';
+ if (diff === 1 || diff === totalItems - 1) {
+ return diff === 1 ? 'right' : 'left';
+ }
+ return 'hidden';
+ };
+
+ const imageVariants = {
+ center: {
+ x: '0%',
+ scale: 1,
+ zIndex: 5,
+ opacity: 1,
+ rotateY: 0,
+ },
+ left: {
+ x: '-40%',
+ scale: 0.8,
+ zIndex: 2,
+ opacity: 0.7,
+ rotateY: 15,
+ },
+ right: {
+ x: '40%',
+ scale: 0.8,
+ zIndex: 2,
+ opacity: 0.7,
+ rotateY: -15,
+ },
+ hidden: {
+ x: '0%',
+ scale: 0.5,
+ zIndex: 1,
+ opacity: 0,
+ },
+ };
+
+ return (
+
+
+ {aboutTimelineData.map((item, index) => {
+ const position = getPosition(index);
+ const { img, year, title, subTitle, backgroundImage } = item;
+ return (
+
+
+
+ );
+ })}
+
+
+ {/* Left and Right button */}
+
+
+
+
+ {/* Progress Bar and Number */}
+
+ {aboutTimelineData.map((_, index) => (
+
+
+
+ {index < aboutTimelineData.length - 1 && (
+
+ )}
+
+ ))}
+
+
+ );
+};
+
+export default ImageSlider;
diff --git a/components/landing-page/about/timeline/ProgressiveeBarSvg.tsx b/components/landing-page/about/timeline/ProgressiveeBarSvg.tsx
new file mode 100644
index 000000000..446a75a3c
--- /dev/null
+++ b/components/landing-page/about/timeline/ProgressiveeBarSvg.tsx
@@ -0,0 +1,268 @@
+import React from 'react';
+
+const ProgressiveeBarSvg = () => {
+ return (
+
+ );
+};
+
+export default ProgressiveeBarSvg;
diff --git a/components/landing-page/about/timeline/Timeline.tsx b/components/landing-page/about/timeline/Timeline.tsx
new file mode 100644
index 000000000..ff2915b67
--- /dev/null
+++ b/components/landing-page/about/timeline/Timeline.tsx
@@ -0,0 +1,97 @@
+'use client';
+import TimelineLayout from './TimelineLayout';
+import { aboutTimelineData } from '@/constants';
+import React, { useEffect, useRef } from 'react';
+import TimelineCard from './TimelineCard';
+import ImageSlider from './ImageSlider';
+import { gsap } from 'gsap';
+import TopRightSvg from './backgroundSvgs/TopRightSvg';
+import MiddleLeftSvg from './backgroundSvgs/MiddleLeftSvg';
+import MiddleRightSvg from './backgroundSvgs/MiddleRightSvg';
+import BottomLeftSvg from './backgroundSvgs/BottomLeftSvg';
+
+const Timeline = () => {
+ const svgRefs = useRef<(SVGPathElement | null)[]>([]);
+
+ useEffect(() => {
+ svgRefs.current.forEach((path, i) => {
+ if (path) {
+ const length = path.getTotalLength();
+
+ // set initial hidden state
+ gsap.set(path, {
+ strokeDasharray: length,
+ strokeDashoffset: length,
+ opacity: 0,
+ });
+
+ // continuous animation
+ gsap.to(path, {
+ strokeDashoffset: 0,
+ opacity: 1,
+ duration: 2,
+ ease: 'power2.inOut',
+ delay: 0.3 * i, // stagger by index
+ repeat: -1, // infinite loop
+ yoyo: true, // reverse back
+ });
+ }
+ });
+ }, []);
+
+ return (
+
+ {/* Heading with Top Right SVG */}
+
+
+
+ Timeline
+
+
+ Our Journey
+
+
+
+ {/* Top Right SVG */}
+
+
+
+ {/* Cards mobile */}
+
+ {aboutTimelineData.map((item, index) => {
+ const { img, year, title, subTitle, backgroundImage } = item;
+ return (
+
+ );
+ })}
+
+
+ {/* Carousel with Middle SVGs */}
+
+
+
+
+
+ {/* Left Middle SVG */}
+
+
+ {/* Right Middle SVG */}
+
+
+
+ {/* Bottom SVG */}
+
+
+
+
+ );
+};
+
+export default Timeline;
diff --git a/components/landing-page/about/timeline/TimelineCard.tsx b/components/landing-page/about/timeline/TimelineCard.tsx
new file mode 100644
index 000000000..44dd2eb3d
--- /dev/null
+++ b/components/landing-page/about/timeline/TimelineCard.tsx
@@ -0,0 +1,50 @@
+import Image from 'next/image';
+import React from 'react';
+
+interface props {
+ img: string;
+ year: string;
+ title: string;
+ subTitle: string;
+ backgroundImage: string;
+}
+
+const TimelineCard = ({
+ img,
+ year,
+ title,
+ subTitle,
+ backgroundImage,
+}: props) => {
+ return (
+
+
+
+
+ {title}
+
+
+ {subTitle}
+
+
+
+ );
+};
+
+export default TimelineCard;
diff --git a/components/landing-page/about/timeline/TimelineLayout.tsx b/components/landing-page/about/timeline/TimelineLayout.tsx
new file mode 100644
index 000000000..463180a7c
--- /dev/null
+++ b/components/landing-page/about/timeline/TimelineLayout.tsx
@@ -0,0 +1,15 @@
+// components/DashboardLayout.tsx
+import React, { ReactNode } from 'react';
+type TimelineLayoutProps = {
+ children: ReactNode;
+};
+
+const TimelineLayout = ({ children }: TimelineLayoutProps) => {
+ return (
+
+ {children}
+
+ );
+};
+
+export default TimelineLayout;
diff --git a/components/landing-page/about/timeline/backgroundSvgs/BottomLeftSvg.tsx b/components/landing-page/about/timeline/backgroundSvgs/BottomLeftSvg.tsx
new file mode 100644
index 000000000..27818e50d
--- /dev/null
+++ b/components/landing-page/about/timeline/backgroundSvgs/BottomLeftSvg.tsx
@@ -0,0 +1,134 @@
+import React from 'react';
+
+interface BottomLeftSvgProps {
+ svgRefs: React.MutableRefObject<(SVGPathElement | null)[]>;
+}
+
+const BottomLeftSvg: React.FC
= ({ svgRefs }) => {
+ return (
+
+
+
+ );
+};
+
+export default BottomLeftSvg;
diff --git a/components/landing-page/about/timeline/backgroundSvgs/MiddleLeftSvg.tsx b/components/landing-page/about/timeline/backgroundSvgs/MiddleLeftSvg.tsx
new file mode 100644
index 000000000..70339c508
--- /dev/null
+++ b/components/landing-page/about/timeline/backgroundSvgs/MiddleLeftSvg.tsx
@@ -0,0 +1,47 @@
+import React from 'react';
+
+interface MiddleLeftSvgProps {
+ svgRefs: React.MutableRefObject<(SVGPathElement | null)[]>;
+}
+
+const MiddleLeftSvg: React.FC = ({ svgRefs }) => {
+ return (
+
+
+
+ );
+};
+
+export default MiddleLeftSvg;
diff --git a/components/landing-page/about/timeline/backgroundSvgs/MiddleRightSvg.tsx b/components/landing-page/about/timeline/backgroundSvgs/MiddleRightSvg.tsx
new file mode 100644
index 000000000..af5ff8991
--- /dev/null
+++ b/components/landing-page/about/timeline/backgroundSvgs/MiddleRightSvg.tsx
@@ -0,0 +1,76 @@
+import React from 'react';
+
+interface MiddleRightSvgProps {
+ svgRefs: React.MutableRefObject<(SVGPathElement | null)[]>;
+}
+
+const MiddleRightSvg: React.FC = ({ svgRefs }) => {
+ return (
+
+
+
+ );
+};
+
+export default MiddleRightSvg;
diff --git a/components/landing-page/about/timeline/backgroundSvgs/TopRightSvg.tsx b/components/landing-page/about/timeline/backgroundSvgs/TopRightSvg.tsx
new file mode 100644
index 000000000..19b9a0b0f
--- /dev/null
+++ b/components/landing-page/about/timeline/backgroundSvgs/TopRightSvg.tsx
@@ -0,0 +1,90 @@
+import React from 'react';
+
+interface TopRightSvgProps {
+ svgRefs: React.MutableRefObject<(SVGPathElement | null)[]>;
+}
+
+const TopRightSvg: React.FC = ({ svgRefs }) => {
+ return (
+
+
+
+ );
+};
+
+export default TopRightSvg;
diff --git a/constants/index.ts b/constants/index.ts
new file mode 100644
index 000000000..ac9e57810
--- /dev/null
+++ b/constants/index.ts
@@ -0,0 +1,26 @@
+export const aboutTimelineData = [
+ {
+ img: '/landing/about/emoji_objects.svg',
+ year: '2024',
+ title: 'Idea Inception',
+ subTitle:
+ 'Boundless was born from the need to validate and fund ideas fairly in Web3.',
+ backgroundImage: 'time-card-background-image-one',
+ },
+ {
+ img: '/landing/about/rocket_launch.svg',
+ year: '2025',
+ title: 'MVP Launch on Stellar (Soroban)',
+ subTitle:
+ 'The first version of Boundless, enabling milestone-based crowdfunding, grants, and hackathons.',
+ backgroundImage: 'time-card-background-image-two',
+ },
+ {
+ img: '/landing/about/globe_asia.svg',
+ year: 'Future',
+ title: 'Scaling Across Ecosystems',
+ subTitle:
+ 'Expanding Boundless beyond Stellar to support global innovators wherever they are.',
+ backgroundImage: 'time-card-background-image-three',
+ },
+];
diff --git a/public/landing/about/Abstract_01.png b/public/landing/about/Abstract_01.png
new file mode 100644
index 000000000..ac1d230dc
Binary files /dev/null and b/public/landing/about/Abstract_01.png differ
diff --git a/public/landing/about/Abstract_01md.png b/public/landing/about/Abstract_01md.png
new file mode 100644
index 000000000..221a6470b
Binary files /dev/null and b/public/landing/about/Abstract_01md.png differ
diff --git a/public/landing/about/Abstract_02.png b/public/landing/about/Abstract_02.png
new file mode 100644
index 000000000..87f0ab2bf
Binary files /dev/null and b/public/landing/about/Abstract_02.png differ
diff --git a/public/landing/about/Abstract_02md.png b/public/landing/about/Abstract_02md.png
new file mode 100644
index 000000000..f3816cac8
Binary files /dev/null and b/public/landing/about/Abstract_02md.png differ
diff --git a/public/landing/about/Abstract_03.png b/public/landing/about/Abstract_03.png
new file mode 100644
index 000000000..540abe55a
Binary files /dev/null and b/public/landing/about/Abstract_03.png differ
diff --git a/public/landing/about/Abstract_03md.png b/public/landing/about/Abstract_03md.png
new file mode 100644
index 000000000..11edeac71
Binary files /dev/null and b/public/landing/about/Abstract_03md.png differ
diff --git a/public/landing/about/emoji_objects.svg b/public/landing/about/emoji_objects.svg
new file mode 100644
index 000000000..a2a443aaa
--- /dev/null
+++ b/public/landing/about/emoji_objects.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/landing/about/globe_asia.svg b/public/landing/about/globe_asia.svg
new file mode 100644
index 000000000..30496683e
--- /dev/null
+++ b/public/landing/about/globe_asia.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/landing/about/progressive-bar.svg b/public/landing/about/progressive-bar.svg
new file mode 100644
index 000000000..24c894894
--- /dev/null
+++ b/public/landing/about/progressive-bar.svg
@@ -0,0 +1,94 @@
+
diff --git a/public/landing/about/rocket_launch.svg b/public/landing/about/rocket_launch.svg
new file mode 100644
index 000000000..74430fd3b
--- /dev/null
+++ b/public/landing/about/rocket_launch.svg
@@ -0,0 +1,3 @@
+