diff --git a/public/LoginSteps/LoginStep1.svg b/public/LoginSteps/LoginStep1.svg
new file mode 100644
index 0000000..de87ea8
--- /dev/null
+++ b/public/LoginSteps/LoginStep1.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/LoginSteps/LoginStep2.svg b/public/LoginSteps/LoginStep2.svg
new file mode 100644
index 0000000..86889f5
--- /dev/null
+++ b/public/LoginSteps/LoginStep2.svg
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/LoginSteps/LoginStep3.svg b/public/LoginSteps/LoginStep3.svg
new file mode 100644
index 0000000..61137fc
--- /dev/null
+++ b/public/LoginSteps/LoginStep3.svg
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/LoginSteps/LoginStep4.svg b/public/LoginSteps/LoginStep4.svg
new file mode 100644
index 0000000..e7768f8
--- /dev/null
+++ b/public/LoginSteps/LoginStep4.svg
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/LoginSteps/LoginStep5.svg b/public/LoginSteps/LoginStep5.svg
new file mode 100644
index 0000000..cb1d5e2
--- /dev/null
+++ b/public/LoginSteps/LoginStep5.svg
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/LoginSteps/LoginStep6.svg b/public/LoginSteps/LoginStep6.svg
new file mode 100644
index 0000000..c28ce3b
--- /dev/null
+++ b/public/LoginSteps/LoginStep6.svg
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/SignupSteps/SignupStep1.svg b/public/SignupSteps/SignupStep1.svg
new file mode 100644
index 0000000..9f106ec
--- /dev/null
+++ b/public/SignupSteps/SignupStep1.svg
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/SignupSteps/SignupStep2.svg b/public/SignupSteps/SignupStep2.svg
new file mode 100644
index 0000000..abd00b4
--- /dev/null
+++ b/public/SignupSteps/SignupStep2.svg
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/SignupSteps/SignupStep3.svg b/public/SignupSteps/SignupStep3.svg
new file mode 100644
index 0000000..fd3b720
--- /dev/null
+++ b/public/SignupSteps/SignupStep3.svg
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/SignupSteps/SignupStep4.svg b/public/SignupSteps/SignupStep4.svg
new file mode 100644
index 0000000..5b2548c
--- /dev/null
+++ b/public/SignupSteps/SignupStep4.svg
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/SignupSteps/SignupStep5.svg b/public/SignupSteps/SignupStep5.svg
new file mode 100644
index 0000000..c3f05aa
--- /dev/null
+++ b/public/SignupSteps/SignupStep5.svg
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/SignupSteps/SignupStep6.svg b/public/SignupSteps/SignupStep6.svg
new file mode 100644
index 0000000..bf7b657
--- /dev/null
+++ b/public/SignupSteps/SignupStep6.svg
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/logo.svg b/public/logo.svg
new file mode 100644
index 0000000..624ad8e
--- /dev/null
+++ b/public/logo.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/app/globals.css b/src/app/globals.css
index 2fdbe6b..98ac33e 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -3,10 +3,54 @@
@custom-variant dark (&:is(.dark *));
@theme inline {
+ /* Background and Foreground */
+ --color-background: #ffffff; /* White */
+ --color-foreground-primary: #0353f0; /* Light Blue */
+ --color-foreground-secondary: #000b21; /* Dark Blue */
+ --color-foreground-neutral: #121212; /* Very Dark Blue */
+
+ /* Primary Colors */
+ --color-primary-50: #edf7ff;
+ --color-primary-100: #d6ecff;
+ --color-primary-200: #b6e0ff;
+ --color-primary-300: #84cdff;
+ --color-primary-400: #44b1ff;
+ --color-primary-500: #218bff;
+ --color-primary-600: #096cff;
+ --color-primary-700: #0355f0;
+ --color-primary-800: #0443c3;
+ --color-primary-900: #0f3d99;
+ --color-primary-950: #0f265c;
+
+ /* Secondary Colors */
+ --color-secondary-50: #e9f7ff;
+ --color-secondary-100: #ceedff;
+ --color-secondary-200: #a7e1ff;
+ --color-secondary-300: #6bd2ff;
+ --color-secondary-400: #26b6ff;
+ --color-secondary-500: #008bff;
+ --color-secondary-600: #0061ff;
+ --color-secondary-700: #0046ff;
+ --color-secondary-800: #003be6;
+ --color-secondary-900: #0033b3;
+ --color-secondary-950: #000821;
+
+ /* Neutral Colors */
+ --color-neutral-50: #f6f6f6;
+ --color-neutral-100: #e7e7e7;
+ --color-neutral-200: #d1d1d1;
+ --color-neutral-300: #b0b0b0;
+ --color-neutral-400: #888888;
+ --color-neutral-500: #6d6d6d;
+ --color-neutral-600: #5d5d5d;
+ --color-neutral-700: #4f4f4f;
+ --color-neutral-800: #454545;
+ --color-neutral-900: #3d3d3d;
+ --color-neutral-950: #121212;
+
+ /* Additional colors */
--color-background: var(--background);
--color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
@@ -36,10 +80,102 @@
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
+
+ /* Font Family */
+ --font-sans: var(--font-geist-sans);
+ --font-mono: var(--font-geist-mono);
+
+ /* DIsplay TextSizes */
+ --text-display-large: 57px;
+ --text-display-large--line-height: 64px;
+ --text-display-large--letter-spacing: -0.25px;
+ --text-display-medium: 45px;
+ --text-display-medium--line-height: 52px;
+ --text-display-medium--letter-spacing: 0px;
+ --text-display-small: 32px;
+ --text-display-small--line-height: 44px;
+ --text-display-small--letter-spacing: 0px;
+
+ /* Heading TextSizes */
+ --text-headline-xl-large: 44px;
+ --text-headline-xl-large--line-height: 100%;
+ --text-headline-xl-large--letter-spacing: 0px;
+ --text-headline-x-large: 40px;
+ --text-headline-x-large--line-height: 100%;
+ --text-headline-x-large--letter-spacing: 0px;
+ --text-headline-large: 32px;
+ --text-headline-large--line-height: 40px;
+ --text-headline-large--letter-spacing: 0px;
+ --text-headline-medium: 28px;
+ --text-headline-medium--line-height: 36px;
+ --text-headline-medium--letter-spacing: 0px;
+ --text-headline-small: 24px;
+ --text-headline-small--line-height: 32px;
+ --text-headline-small--letter-spacing: 0px;
+
+ /* Title TextSizes */
+ --text-title-large: 22px;
+ --text-title-large--line-height: 28px;
+ --text-title-large--letter-spacing: 0px;
+ --text-title-medium: 16px;
+ --text-title-medium--line-height: 20px;
+ --text-title-medium--letter-spacing: 0.15px;
+ --text-title-small: 14px;
+ --text-title-small--line-height: 20px;
+ --text-title-small--letter-spacing: 0.1px;
+
+ /* Logo TextSizes */
+ --text-logo: 20.5px;
+ --text-logo--line-height: 26px;
+ --text-logo--letter-spacing: 0px;
+
+ /* Body TextSizes */
+ --text-body-large: 16px;
+ --text-body-large--line-height: 24px;
+ --text-body-large--letter-spacing: 0px;
+ --text-body-medium: 14px;
+ --text-body-medium--line-height: 18px;
+ --text-body-medium--letter-spacing: 0.25px;
+ --text-body-small: 12px;
+ --text-body-small--line-height: 16px;
+ --text-body-small--letter-spacing: 0.4px;
+ --text-body-18px-large: 18px;
+ --text-body-18px-large--line-height: 26px;
+ --text-body-18px-large--letter-spacing: 0px;
+
+ /* Label TextSizes */
+ --text-label-large: 14px;
+ --text-label-large--line-height: 100%;
+ --text-label-large--letter-spacing: 0px;
+ --text-label-medium: 14px;
+ --text-label-medium--line-height: 20px;
+ --text-label-medium--letter-spacing: 0.1px;
+ --text-label-small: 11px;
+ --text-label-small--line-height: 16px;
+ --text-label-small--letter-spacing: 0.5px;
+ --text-label-xs: 9px;
+ --text-label-xs--line-height: 12px;
+ --text-label-xs--letter-spacing: 0.8px;
+
+ /* Font Weights */
+ --font-weight-light: 400;
+ --font-weight-medium: 500;
+ --font-weight-bold: 700;
+
+ /* Radius */
+ --radius-x-large: 28px;
+ --radius-large: 16px;
+ --radius-base: 12px;
+ --radius-small: 8px;
+ --radius-x-small: 4px;
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
+
+ /* Shadow */
+ --shadow-large: 0px 20px 16px 0px #00000014;
+ --shadow-base: 0px 12px 16px 0px #0000000a;
}
:root {
@@ -75,6 +211,10 @@
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
+
+ * {
+ /* outline: 1px solid black; */
+ }
}
.dark {
@@ -120,6 +260,34 @@
}
}
+* {
+ @apply border-border outline-ring/50;
+}
+
+body {
+ @apply bg-background text-foreground;
+}
+
+html::-webkit-scrollbar {
+ display: none;
+ width: 0px;
+}
+
+html {
+ scrollbar-width: none;
+}
+
+html {
+ -ms-overflow-style: none;
+}
+
+html {
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scroll-behavior: smooth;
+ -webkit-overflow-scrolling: touch;
+}
+
.splide__pagination {
margin-top: 20px !important;
justify-content: center;
@@ -138,24 +306,6 @@
background: #b0b0b0 !important;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@media (max-width: 1024px) {
.splide__pagination__page {
width: 20px !important;
@@ -173,3 +323,8 @@
gap: 10px;
}
}
+
+button,
+a {
+ cursor: pointer;
+}
diff --git a/src/app/how-it-works/_components/AnimatedContent.tsx b/src/app/how-it-works/_components/AnimatedContent.tsx
new file mode 100644
index 0000000..0ac56a7
--- /dev/null
+++ b/src/app/how-it-works/_components/AnimatedContent.tsx
@@ -0,0 +1,21 @@
+import { IOnboardStepContentProps } from "./types";
+
+export function AnimatedStepContent({ header, handleClick, message, index, length }: IOnboardStepContentProps) {
+
+ return (
+
handleClick(index)} className="cursor-pointer grid grid-cols-[2.5rem_auto] gap-6 lg:gap-10 place-content-start place-items-start max-w-md">
+
+
{index + 1}
+ {index + 1 < length &&
}
+
+
+
+ {header}
+
+
+ {message}
+
+
+
+ )
+}
diff --git a/src/app/how-it-works/_components/AnimatedImage.tsx b/src/app/how-it-works/_components/AnimatedImage.tsx
new file mode 100644
index 0000000..e12889d
--- /dev/null
+++ b/src/app/how-it-works/_components/AnimatedImage.tsx
@@ -0,0 +1,18 @@
+import Image from "next/image";
+import { IOnboardStepImageProps } from "./types";
+
+export function AnimatedStepImage({ className = "", ImageSrc, handleClick, alt, step, index }: IOnboardStepImageProps) {
+ const isActive = step === index;
+
+ return (
+ handleClick(index)} className={`cursor-pointer ${className} absolute inset-0 flex items-center justify-center sm:justify-end transition-[transform_opacity] duration-1000 ease-in-out`}
+ style={{ transform: `rotate(${isActive ? 0 : 45}deg) scale(${isActive ? 1 : 0})`, opacity: `${isActive ? 100 : 0}%` }}
+ >
+
+
+
+
+
+ )
+}
diff --git a/src/app/how-it-works/_components/Button.tsx b/src/app/how-it-works/_components/Button.tsx
new file mode 100644
index 0000000..9fbaabc
--- /dev/null
+++ b/src/app/how-it-works/_components/Button.tsx
@@ -0,0 +1,15 @@
+import Link from "next/link";
+import { ReactNode } from "react";
+
+function Button({ children, href, className }: { className: string, children: ReactNode, href: string }) {
+ return (
+
+ {children}
+
+ )
+}
+
+
+
+export default Button;
+
diff --git a/src/app/how-it-works/_components/FaqSection.tsx b/src/app/how-it-works/_components/FaqSection.tsx
new file mode 100644
index 0000000..996c9b6
--- /dev/null
+++ b/src/app/how-it-works/_components/FaqSection.tsx
@@ -0,0 +1,76 @@
+"use client"
+
+import { Dispatch, SetStateAction, useState } from "react";
+import { BiMinusCircle, BiPlusCircle } from "react-icons/bi";
+
+const faqItems = [
+ {
+ question: "How to create an account on ChaineLib",
+ answer: "Get a unique NFT-powered author profile with your bio, genres, and publishing rights.\n\nGet a unique NFT-powered author profile with your bio, genres, and publishing rights."
+ },
+ {
+ question: "How to create an account on ChaineLib",
+ answer: "Get a unique NFT-powered author profile with your bio, genres, and publishing rights.\n\nGet a unique NFT-powered author profile with your bio, genres, and publishing rights."
+ },
+ {
+ question: "How to create an account on ChaineLib",
+ answer: "Get a unique NFT-powered author profile with your bio, genres, and publishing rights.\n\nGet a unique NFT-powered author profile with your bio, genres, and publishing rights."
+ },
+ {
+ question: "How to create an account on ChaineLib",
+ answer: "Get a unique NFT-powered author profile with your bio, genres, and publishing rights.\n\nGet a unique NFT-powered author profile with your bio, genres, and publishing rights."
+ },
+ {
+ question: "How to create an account on ChaineLib",
+ answer: "Get a unique NFT-powered author profile with your bio, genres, and publishing rights.\n\nGet a unique NFT-powered author profile with your bio, genres, and publishing rights."
+ },
+];
+
+export default function FaqSection() {
+ const [clicked, setClicked] = useState(1);
+
+ return (
+
+
+ You Got Questions?
+
+
+
+ {faqItems.map((item, index) => (
+
+ ))}
+
+
+ )
+}
+
+
+function FaqItem({ question, answer, index, setClicked, clicked }: { question: string, answer: string, index: number, setClicked: Dispatch>, clicked: number }) {
+ function handleClick() {
+ if (index === clicked) { setClicked(0) }
+ else { setClicked(index) }
+ }
+
+ return (
+
+
+
+ {question}
+
+
+ {clicked === index ? : }
+
+
+
+ {answer}
+
+
+ )
+}
diff --git a/src/app/how-it-works/_components/Footer.tsx b/src/app/how-it-works/_components/Footer.tsx
new file mode 100644
index 0000000..672f0c6
--- /dev/null
+++ b/src/app/how-it-works/_components/Footer.tsx
@@ -0,0 +1,68 @@
+import Link from "next/link";
+import { BiLogoLinkedin, BiLogoTelegram } from "react-icons/bi";
+import { FaXTwitter } from "react-icons/fa6";
+import Logo from "./Logo";
+
+export interface IFooterLinks {
+ link: string;
+ href: string;
+}
+
+const FooterLink: IFooterLinks[] = [
+ { link: "Explore", href: "/explore" },
+ { link: "Home", href: "/" },
+ { link: "Books", href: "/books" },
+ { link: "How It Works", href: "/how-it-works" },
+ { link: "About", href: "/about-us" },
+ { link: "Legal", href: "/legal" },
+ { link: "Privacy Policy", href: "/privacy-policy" },
+ { link: "Terms Of Service", href: "/terms-of-service" },
+];
+
+
+export default function Footer() {
+ const currentYear = new Date().getFullYear();
+
+ return (
+
+
+
+
+
+ © {currentYear} {" "}ChainLib. All rights reserved
+
+
+
+
+ {FooterLink.map(({ link, href }, index) => {link})}
+
+
+
+
+
+ 2025 {" "}ChainLib. All rights reserved
+
+
+
+ )
+}
diff --git a/src/app/how-it-works/_components/LoginStep.tsx b/src/app/how-it-works/_components/LoginStep.tsx
new file mode 100644
index 0000000..7aa6995
--- /dev/null
+++ b/src/app/how-it-works/_components/LoginStep.tsx
@@ -0,0 +1,79 @@
+"use client"
+
+import { Ref, useState } from 'react';
+import { AnimatedStepContent } from './AnimatedContent';
+import { AnimatedStepImage } from './AnimatedImage';
+import { IOnboardStepProps } from './types';
+
+const loginSteps: IOnboardStepProps[] = [
+ {
+ message: "Sign up quickly with your wallet and start exploring.",
+ alt: "Sign up and connect wallet image",
+ header: "Join & Connect Wallet",
+ ImageSrc: "./LoginSteps/LoginStep1.svg",
+ },
+ {
+ message:
+ "Choose your favorite genre, set reading goals and follow your favorite author",
+ alt: "Sign up and connect wallet image",
+ header: "Personalize Your Profile",
+ ImageSrc: "./LoginSteps/LoginStep2.svg",
+ },
+ {
+ message:
+ "Browse trending titles, new releases, and exclusive collections curated for you",
+ alt: "Sign up and connect wallet image",
+ header: "Discover Content",
+ ImageSrc: "./LoginSteps/LoginStep3.svg",
+ },
+ {
+ message:
+ "Read online , offline, or own a special edition NFT of your favorite book",
+ alt: "Sign up and connect wallet image",
+ header: "Read or Collect",
+ ImageSrc: "./LoginSteps/LoginStep4.svg",
+ },
+ {
+ message:
+ "Leave reviews, earn achievements, join book clubs, and climb the reader ranks",
+ alt: "Sign up and connect wallet image",
+ header: "Engage & Level Up",
+ ImageSrc: "./LoginSteps/LoginStep5.svg",
+ },
+ {
+ message: "Support Authors Directly",
+ alt: "Sign up and connect wallet image",
+ header:
+ "Every read and purchase supports the creator. Collect, recommend, and enjoy the community",
+ ImageSrc: "./LoginSteps/LoginStep6.svg",
+ },
+];
+
+export default function LoginStep({ readerRef }: { readerRef: Ref }) {
+ // The first step is at 0, same with the index
+ const [step, setStep] = useState(0)
+
+ const handleClick = (index: number) => {
+ if (loginSteps.length > index + 1) {
+ setStep(() => index + 1)
+ } else {
+ setStep(() => 0)
+ }
+ }
+
+ return (
+
+
+ {loginSteps.map(({ ImageSrc, alt }, index) => (
))}
+
+
+
+
+ {loginSteps.map(({ message, header }, index) => (
))}
+
+
+
+ )
+}
diff --git a/src/app/how-it-works/_components/Logo.tsx b/src/app/how-it-works/_components/Logo.tsx
new file mode 100644
index 0000000..7ba0f03
--- /dev/null
+++ b/src/app/how-it-works/_components/Logo.tsx
@@ -0,0 +1,14 @@
+import { cn } from "@/lib/utils";
+import Image from "next/image";
+import Link from "next/link";
+
+export default function Logo({ className = "" }: { className?: string }) {
+ return (
+
+
+
+
+ ChainLib
+
+ )
+}
diff --git a/src/app/how-it-works/_components/NavLink.tsx b/src/app/how-it-works/_components/NavLink.tsx
new file mode 100644
index 0000000..8facfd2
--- /dev/null
+++ b/src/app/how-it-works/_components/NavLink.tsx
@@ -0,0 +1,12 @@
+"use client"
+
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import { ReactNode } from "react";
+
+export default function NavLink({ children, href }: { children: ReactNode, href: string }) {
+ const pathname = usePathname()
+ return (
+ {children}
+ )
+}
diff --git a/src/app/how-it-works/_components/NavMenu.tsx b/src/app/how-it-works/_components/NavMenu.tsx
new file mode 100644
index 0000000..d8a6f69
--- /dev/null
+++ b/src/app/how-it-works/_components/NavMenu.tsx
@@ -0,0 +1,54 @@
+import { motion, Variants } from "framer-motion";
+import Link from "next/link";
+import { ILink } from "./types";
+
+const animateFn = (variants: Variants, custom: number | null = null) => {
+ return {
+ initial: "initial",
+ animate: "enter",
+ exit: "exit",
+ custom,
+ variants,
+ };
+};
+
+const links: ILink[] = [
+ { link: "Home", href: "/" },
+ { link: "Books", href: "/books/bookId" },
+ { link: "How It Works", href: "/how-it-works" },
+ { link: "About ChainLib", href: "/about-us" },
+];
+
+export default function NavMenu() {
+ const opacity = {
+ initial: {
+ y: "100%",
+ },
+ animate: (i: number) => ({
+ y: "0%",
+ transition: { duration: 0.5, delay: 0.01 * i + 0.3 },
+ }),
+ exit: {
+ y: "100%",
+ transition: { duration: 0.2 },
+ },
+ };
+
+ return (
+
+
+ {links.map(({ link, href }, index) =>
+ (
+ {link}
+ )
+ )}
+
+
+ )
+}
diff --git a/src/app/how-it-works/_components/NavMenuButton.tsx b/src/app/how-it-works/_components/NavMenuButton.tsx
new file mode 100644
index 0000000..df1a75a
--- /dev/null
+++ b/src/app/how-it-works/_components/NavMenuButton.tsx
@@ -0,0 +1,26 @@
+"use client"
+
+import { AnimatePresence } from "framer-motion"
+import { useState } from "react"
+import NavMenu from "./NavMenu"
+
+export default function NavMenuButton() {
+ const [openMenu, setOpenMenu] = useState(false)
+
+ function handleMenuClick() {
+ setOpenMenu(t => !t)
+ }
+ return (
+ <>
+
+
+
+
+
+
+
+ {openMenu && }
+
+ >
+ )
+}
diff --git a/src/app/how-it-works/_components/NavSearchBar.tsx b/src/app/how-it-works/_components/NavSearchBar.tsx
new file mode 100644
index 0000000..50be45b
--- /dev/null
+++ b/src/app/how-it-works/_components/NavSearchBar.tsx
@@ -0,0 +1,44 @@
+"use client"
+
+import { cn } from "@/lib/utils"
+import { FormEvent, useEffect, useRef, useState } from "react"
+import { BiSolidSearch } from "react-icons/bi"
+
+function NavSearchBar() {
+ const [active, setActive] = useState(false)
+
+ const searchRef = useRef(null)
+
+ useEffect(() => {
+ function handleClickOutside(event: MouseEvent) {
+ if (searchRef.current && !(searchRef.current).contains(event.target as Node)) {
+ setActive(false)
+ }
+ }
+
+ document.addEventListener("mousedown", handleClickOutside)
+ return () => document.removeEventListener("mousedown", handleClickOutside)
+ }, [])
+
+ const handleSubmit = (e: FormEvent) => {
+ e.preventDefault()
+ setActive(false)
+ }
+
+ return (
+
+ )
+}
+
+export default NavSearchBar
\ No newline at end of file
diff --git a/src/app/how-it-works/_components/Navbar.tsx b/src/app/how-it-works/_components/Navbar.tsx
new file mode 100644
index 0000000..724f248
--- /dev/null
+++ b/src/app/how-it-works/_components/Navbar.tsx
@@ -0,0 +1,42 @@
+
+import Button from "./Button";
+import Logo from "./Logo";
+import NavLink from "./NavLink";
+import NavMenuButton from "./NavMenuButton";
+import NavSearchBar from "./NavSearchBar";
+
+interface ILink {
+ link: string;
+ href: string;
+}
+
+const links: ILink[] = [
+ { link: "Home", href: "/" },
+ { link: "Books", href: "/books/bookId" },
+ { link: "How It Works", href: "/how-it-works" },
+ { link: "About ChainLib", href: "/about-us" },
+];
+
+function Navbar() {
+ return (
+
+
+
+
+
+ {links.map(({ link, href }: ILink, index: number) => ({link} ))}
+
+
+
+
+ Login
+ SignUp
+
+
+
+
+
+ )
+}
+
+export default Navbar
\ No newline at end of file
diff --git a/src/app/how-it-works/_components/SelectChoiceButton.tsx b/src/app/how-it-works/_components/SelectChoiceButton.tsx
new file mode 100644
index 0000000..229db84
--- /dev/null
+++ b/src/app/how-it-works/_components/SelectChoiceButton.tsx
@@ -0,0 +1,13 @@
+export default function SelectChoiceButton({ writerIsActive, scrollToSection }: { writerIsActive: boolean, scrollToSection: (value: string) => void }) {
+
+ return (
+
+ scrollToSection("writer")} className={`${writerIsActive ? "bg-primary-300" : "bg-primary-50"} text-body-medium font-light rounded-x-large px-6 flex justify-center cursor-pointer items-center py-3`} type="button">
+ For Writers
+
+ scrollToSection("reader")} className={`${!writerIsActive ? "bg-primary-300" : "bg-primary-50"} text-body-medium font-light rounded-x-large px-6 cursor-pointer flex justify-center items-center py-3`} type="button">
+ Readers
+
+
+ )
+}
diff --git a/src/app/how-it-works/_components/SignupStep.tsx b/src/app/how-it-works/_components/SignupStep.tsx
new file mode 100644
index 0000000..eabeb54
--- /dev/null
+++ b/src/app/how-it-works/_components/SignupStep.tsx
@@ -0,0 +1,84 @@
+"use client"
+
+import { Ref, useState } from 'react';
+import { AnimatedStepContent } from './AnimatedContent';
+import { AnimatedStepImage } from './AnimatedImage';
+import { IOnboardStepProps } from './types';
+
+const signupSteps: IOnboardStepProps[] = [
+ {
+ alt: "Sign up and connect wallet image",
+ header: "Sign Up & Connect Wallet",
+ message:
+ "Join ChainLib as a writer by connecting your StarkNet wallet(e.g., Braavos or Argent).",
+ ImageSrc: "./SignupSteps/SignUpStep1.svg",
+ },
+ {
+ message:
+ "Get a Unique NFT-powered author profile with your bio, genres, and publishing rights",
+ alt: "Sign up and connect wallet image",
+ header: "Create Your Author Identity",
+ ImageSrc: "./SignupSteps/SignUpStep2.svg",
+ },
+ {
+ message:
+ "Sign a smart contract that outlines ownership rights and revenue sharing.",
+ alt: "Sign up and connect wallet image",
+ header: "Agree To Terms",
+ ImageSrc: "./SignupSteps/SignUpStep3.svg",
+ },
+ {
+ message:
+ "Access your personal dashboard to manage books, track earnings and engage with readers.",
+ alt: "Sign up and connect wallet image",
+ header: "Set Up Your Dashboard",
+ ImageSrc: "./SignupSteps/SignUpStep4.svg",
+ },
+ {
+ message:
+ "Upload your book, add metadata(title, genre, price), and mint it as a content NFT.",
+ alt: "Sign up and connect wallet image",
+ header: "Publish your Books",
+ ImageSrc: "./SignupSteps/SignUpStep5.svg",
+ },
+ {
+ message:
+ "Earn instantly from purchases or subscriptions no middleman, full transparency",
+ alt: "Sign up and connect wallet image",
+ header: "Get Paid Directly",
+ ImageSrc: "./SignupSteps/SignUpStep6.svg",
+ },
+];
+
+export default function SignupStep({ writerRef }: { writerRef: Ref }) {
+ // The first step is at 0, same with the index
+ const [step, setStep] = useState(0)
+
+ const handleClick = (index: number) => {
+ if (signupSteps.length > index + 1) {
+ setStep(() => index + 1)
+ } else {
+ setStep(() => 0)
+ }
+ }
+
+ return (
+
+
+
+ {signupSteps.map(({ message, header }, index) => (
))}
+
+
+
+
+ {signupSteps.map(({ ImageSrc, alt }, index) => (
))}
+
+
+ )
+}
+
+
+
+
diff --git a/src/app/how-it-works/_components/StepByStepSection.tsx b/src/app/how-it-works/_components/StepByStepSection.tsx
new file mode 100644
index 0000000..bc7462d
--- /dev/null
+++ b/src/app/how-it-works/_components/StepByStepSection.tsx
@@ -0,0 +1,36 @@
+"use client"
+
+import { useRef, useState } from "react";
+import LoginStep from "./LoginStep";
+import SelectChoiceButton from "./SelectChoiceButton";
+import SignupStep from "./SignupStep";
+
+export default function StepByStepSection() {
+ const [writerIsActive, setWriterIsActive] = useState(true)
+ const writerRef = useRef(null)
+ const readerRef = useRef(null)
+
+ const scrollToSection = (section: string) => {
+ if (section === "writer") {
+ writerRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
+ setWriterIsActive(() => true)
+ } else {
+ readerRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" });
+ setWriterIsActive(() => false)
+ }
+ };
+
+ return (
+
+
+
+
+ {/* Signup steps */}
+
+
+
+ {/* Login Steps */}
+
+
+ )
+}
diff --git a/src/app/how-it-works/_components/types.ts b/src/app/how-it-works/_components/types.ts
new file mode 100644
index 0000000..8cfb226
--- /dev/null
+++ b/src/app/how-it-works/_components/types.ts
@@ -0,0 +1,34 @@
+export interface ILink {
+ link: string;
+ href: string;
+}
+
+export interface IFooterLinks {
+ link: string;
+ href: string;
+}
+
+export interface IOnboardStepContentProps {
+ header: string;
+ message: string;
+ index: number;
+ handleClick: (index: number) => void;
+ length: number;
+}
+
+export interface IOnboardStepImageProps {
+ alt: string;
+ className?: string;
+ ImageSrc: string;
+ index: number;
+ handleClick: (index: number) => void;
+ length: number;
+ step: number;
+}
+
+export interface IOnboardStepProps {
+ alt: string;
+ ImageSrc: string;
+ header: string;
+ message: string;
+}
diff --git a/src/app/how-it-works/page.tsx b/src/app/how-it-works/page.tsx
new file mode 100644
index 0000000..1e7b819
--- /dev/null
+++ b/src/app/how-it-works/page.tsx
@@ -0,0 +1,30 @@
+import FaqSection from "./_components/FaqSection";
+import Footer from "./_components/Footer";
+import Navbar from "./_components/Navbar";
+import StepByStepSection from "./_components/StepByStepSection";
+
+export default function Page() {
+
+ return (
+ <>
+
+
+
+
+ Building More
+
+ Than an e-Library
+
+ A decentralized world where stories live on-chain and creators stay in control. Powered by StarkNet, our platform gives writers the freedom to publish without intermediaries and gives readers direct access to original, verifiable content they can truly own.
+
+
+
+
+
+
+
+ >
+ )
+}