Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import type { Metadata } from "next";
import "@rainbow-me/rainbowkit/styles.css";
import "./globals.css";

import { Providers } from "./providers";
import { atypFont, garamondFont, utsahaFont } from "../lib/fonts";
import { Providers } from "@/providers/providers";
import { atypFont, garamondFont, utsahaFont } from "@/lib/fonts";

export const metadata: Metadata = {
title: "Decentralized Identity Token",
Expand Down
12 changes: 8 additions & 4 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { HowItWorks } from "@/components/HowItWorks";
import { Hero } from "@/components/Hero";
import { FeatureSection } from "@/components/FeatureSection";
import CTASection from "@/components/CTASection";
import {
Navbar,
Hero,
HowItWorks,
FeatureSection,
CTASection,
} from "@/components";

export default function Home() {
return (
<main className="relative min-h-screen w-full bg-landing-bg dark:bg-landing-bg-dark">
<Navbar />
<Hero />
<HowItWorks />
<FeatureSection />
Expand Down
37 changes: 30 additions & 7 deletions components/CTASection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import Image from "next/image";
import React from "react";
import { SOCIAL_LINKS } from "@/lib/constants";

Check warning on line 5 in components/CTASection.tsx

View workflow job for this annotation

GitHub Actions / CI Checks (lint → format → build)

'SOCIAL_LINKS' is defined but never used

const CTASection = () => {
return (
<section className="flex w-full justify-center bg-dark-bg px-4 py-10 md:py-20 dark:bg-landing-bg">
{/* Gradient Box */}
<div className="gradient-cta relative flex h-auto min-h-[300px] w-full max-w-[1264px] flex-col items-center overflow-hidden rounded-[30px] text-center shadow-2xl md:h-[510px] md:rounded-[57px]">
{/* --- Main Content Area --- */}
{/* --- Background Noise --- */}
<div
className="absolute inset-0 opacity-30"
style={{
Expand All @@ -17,12 +17,11 @@
mixBlendMode: "overlay",
}}
/>
{/* Headline */}

<h2 className="mx-auto mt-8 max-w-[90%] px-4 font-utsaha text-2xl tracking-tight text-black md:mt-[72px] md:max-w-[768px] md:px-0 md:text-6xl">
By Stability Nexus, For Everyone
</h2>

{/* Subheadline */}
<p className="mt-5 px-4 font-utsaha text-lg text-black md:mt-[24px] md:text-2xl">
Mint your Decentralized ID today
</p>
Expand All @@ -31,7 +30,6 @@
<div className="mt-auto flex w-full flex-row items-center justify-between px-6 pb-8 md:px-20 md:pb-16">
<div className="flex items-center gap-2 md:gap-3">
<span className="relative h-6 w-6 md:h-12 md:w-12">
{/* Logo Icon */}
<Image
src="/assets/logo.svg"
alt="DIT Logo"
Expand All @@ -45,13 +43,12 @@
className="hidden h-6 w-6 object-contain md:h-12 md:w-12 dark:block"
/>
</span>
{/* Logo Text with Custom Font */}
<span className="font-atyp text-xl tracking-tighter text-dark-bg md:text-4xl dark:text-white/85">
dit
</span>
</div>

{/* Right: Social Icons */}
{/* Social Icons mapped from constants */}
<div className="flex items-center gap-3 md:gap-4">
<a
href="https://stability.nexus/"
Expand Down Expand Up @@ -118,4 +115,30 @@
);
};

// Small local sub-component for cleanliness
const SocialIcon = ({

Check warning on line 119 in components/CTASection.tsx

View workflow job for this annotation

GitHub Actions / CI Checks (lint → format → build)

'SocialIcon' is assigned a value but never used
href,
src,
alt,
}: {
href: string;
src: string;
alt: string;
}) => (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className="transform transition-transform hover:scale-110"
>
<Image
src={src}
alt={alt}
width={40}
height={40}
className="h-6 w-6 object-contain md:h-10 md:w-10"
/>
</a>
);

export default CTASection;
57 changes: 8 additions & 49 deletions components/FeatureSection.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,22 @@
"use client";
import React, { useRef } from "react";
import FeatureCard from "./cards/FeatureCard";

interface FeatureData {
image: string;
title: string;
}
import FeatureCard from "@/components/cards/FeatureCard";
import { FEATURES_DATA } from "@/lib/constants";

export const FeatureSection: React.FC = () => {
const scrollContainerRef = useRef<HTMLDivElement>(null);

const features: FeatureData[] = [
{
image: "/cards/FeatureCard1.png",
title: "Build and Earn Reputation from Endorsements",
},
{
image: "/cards/FeatureCard2.png",
title: "Showcase your on-chain reputation instantly.",
},
{
image: "/cards/FeatureCard3.png",
title: "Level up your credibility with every endorsement.",
},
{
image: "/cards/FeatureCard4.png",
title: "Your Identity travels with you across wallets!",
},
{
image: "/cards/FeatureCard5.png",
title: "You own the lock, You own the key Recover your identity",
},
{
image: "/cards/FeatureCard6.png",
title: "Mint your Identity Join the community.",
},
];

const getScrollAmount = () => {
if (typeof window === "undefined") return 466 + 42;
const isMobile = window.innerWidth < 768;
return isMobile ? window.innerWidth * 0.85 + 16 : 466 + 42;
};

const scrollLeft = () => {
if (scrollContainerRef.current) {
scrollContainerRef.current.scrollBy({
left: -getScrollAmount(),
behavior: "smooth",
});
}
};

const scrollRight = () => {
const scroll = (direction: "left" | "right") => {
if (scrollContainerRef.current) {
const amount = getScrollAmount();
scrollContainerRef.current.scrollBy({
left: getScrollAmount(),
left: direction === "left" ? -amount : amount,
behavior: "smooth",
});
}
Expand All @@ -78,7 +39,7 @@ export const FeatureSection: React.FC = () => {
{/* Navigation Arrows */}
<div className="absolute right-0 bottom-2 hidden gap-4 md:flex">
<button
onClick={scrollLeft}
onClick={() => scroll("left")}
aria-label="Scroll left"
className="group flex h-12 w-12 items-center justify-center rounded-full bg-brand-blue transition-colors hover:bg-brand-blue-hover"
>
Expand All @@ -99,7 +60,7 @@ export const FeatureSection: React.FC = () => {
</svg>
</button>
<button
onClick={scrollRight}
onClick={() => scroll("right")}
aria-label="Scroll Right"
className="group flex h-12 w-12 items-center justify-center rounded-full bg-brand-blue transition-colors hover:bg-brand-blue-hover"
>
Expand Down Expand Up @@ -128,7 +89,7 @@ export const FeatureSection: React.FC = () => {
className="scrollbar-hide flex snap-x snap-mandatory items-center overflow-x-auto pb-10"
>
<div className="flex gap-4 md:gap-[42px]">
{features.map((item, index) => (
{FEATURES_DATA.map((item, index) => (
<div key={index} className="shrink-0 snap-center">
<FeatureCard
bgImage={item.image}
Expand All @@ -148,5 +109,3 @@ export const FeatureSection: React.FC = () => {
</section>
);
};

export default FeatureSection;
101 changes: 5 additions & 96 deletions components/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,106 +1,14 @@
// components/Hero.tsx
"use client";

import Image from "next/image";
import Link from "next/link";
import { useEffect, useState, useRef } from "react";
import { motion, useScroll, useMotionValueEvent } from "framer-motion";
import ToggleButton from "./ToggleButton";
import { ConnectButton } from "@rainbow-me/rainbowkit";
import { useTypewriter } from "@/hooks/useTypewriter";
import { HERO_WORDS } from "@/lib/constants";

const TYPING_SPEED = 150;
const DELETING_SPEED = 100;
const PAUSE_DURATION = 2000;
const WORDS = ["Earned", "Decentralized", "Sovereign", "Yours..."];

export function Hero() {
const [displayedText, setDisplayedText] = useState("");
const [wordIndex, setWordIndex] = useState(0);
const [isDeleting, setIsDeleting] = useState(false);
const [isNavVisible, setIsNavVisible] = useState(true);

const { scrollY } = useScroll();
const lastScrollY = useRef(0);

useMotionValueEvent(scrollY, "change", (latest) => {
const currentScrollY = latest;
if (currentScrollY > lastScrollY.current && currentScrollY > 50) {
setIsNavVisible(false);
} else {
setIsNavVisible(true);
}
lastScrollY.current = currentScrollY;
});

useEffect(() => {
const currentWord = WORDS[wordIndex];
let timer: NodeJS.Timeout;

if (isDeleting) {
if (displayedText.length > 0) {
timer = setTimeout(() => {
setDisplayedText(displayedText.slice(0, -1));
}, DELETING_SPEED);
} else {
timer = setTimeout(() => {
setIsDeleting(false);
setWordIndex((prev) => (prev + 1) % WORDS.length);
}, 0);
}
} else {
if (displayedText.length < currentWord.length) {
timer = setTimeout(() => {
setDisplayedText(currentWord.slice(0, displayedText.length + 1));
}, TYPING_SPEED);
} else {
timer = setTimeout(() => {
setIsDeleting(true);
}, PAUSE_DURATION);
}
}

return () => clearTimeout(timer);
}, [displayedText, isDeleting, wordIndex]);
export default function Hero() {
const displayedText = useTypewriter(HERO_WORDS);

return (
<section className="relative flex min-h-screen w-full flex-col items-center bg-landing-bg dark:bg-landing-bg-dark">
<motion.div
className="fixed top-0 right-0 left-0 z-50 w-full bg-landing-bg dark:bg-landing-bg-dark"
initial={{ y: 0 }}
animate={{ y: isNavVisible ? 0 : -100 }}
transition={{ duration: 0.3 }}
>
<div className="mx-auto flex h-16 w-full max-w-[1512px] items-center justify-between px-4 md:h-[80px] md:px-[56px]">
<Link href="/" className="flex items-center gap-2 md:gap-[17px]">
<div className="relative h-8 w-8 md:h-10 md:w-10">
{/* Light mode logo */}
<Image
src="/assets/logo.svg"
alt="DIT Logo"
fill
className="object-contain dark:hidden"
/>

{/* Dark mode logo */}
<Image
src="/assets/dark-logo.svg"
alt="DIT Logo Dark"
fill
className="hidden object-contain dark:block"
/>
</div>
<span className="pt-1 font-atyp text-2xl leading-none text-black md:pt-2 md:text-[40px] dark:text-white">
dit
</span>
</Link>
<div className="flex items-center gap-3 md:gap-4">
<ToggleButton />

<ConnectButton />
</div>
</div>
</motion.div>

{/* Spacer for Fixed Navbar */}
<div className="h-16 w-full flex-shrink-0 md:h-[80px]" />

Expand Down Expand Up @@ -132,6 +40,7 @@ export function Hero() {
</p>
</div>

{/* Right Content: Image */}
<div className="relative hidden h-full w-full flex-1 items-center justify-center md:flex">
<div className="relative flex h-full w-full items-center justify-center">
<Image
Expand Down
Loading