reorganize components into home directory, add FadeInOnView animation component, and update Hero layout with staggered fade-in effects

This commit is contained in:
2025-12-05 16:17:09 +01:00
parent 1f55c48a67
commit 726382e041
12 changed files with 604 additions and 29 deletions

View File

@@ -1,13 +1,14 @@
import { CallToAction } from '@/components/CallToAction'
import { Faqs } from '@/components/Faqs'
import { Footer } from '@/components/Footer'
import { HomeAbout } from '@/components/HomeAbout'
import { Hero } from '@/components/Hero'
import { HomePrinciples } from '@/components/HomePrinciples'
import { HomeMilestones } from '@/components/HomeMilestones'
import { HomeVentures } from '@/components/HomeVentures'
import { HomeAbout } from '@/components/home/HomeAbout'
import { Hero } from '@/components/home/Hero'
import { HomePrinciples } from '@/components/home/HomePrinciples'
import { HomeMilestones } from '@/components/home/HomeMilestones'
import { HomeVentures } from '@/components/home/HomeVentures'
import { Quote } from '@/components/Quote'
import { HomeStickyHeader } from '@/components/HomeStickyHeader'
import { HomeStickyHeader } from '@/components/home/HomeStickyHeader'
import { FadeInOnView } from '@/components/UI/FadeInOnView'
export default function Home() {
return (
@@ -17,13 +18,34 @@ export default function Home() {
<section className="relative min-h-screen">
<Hero className="-mt-20" />
</section>
<HomeAbout />
<HomePrinciples />
<HomeMilestones />
<HomeVentures />
<Quote />
<CallToAction />
<Faqs />
<FadeInOnView>
<HomeAbout />
</FadeInOnView>
<FadeInOnView delayMs={100}>
<HomePrinciples />
</FadeInOnView>
<FadeInOnView delayMs={200}>
<HomeMilestones />
</FadeInOnView>
<FadeInOnView delayMs={300}>
<HomeVentures />
</FadeInOnView>
<FadeInOnView delayMs={400}>
<Quote />
</FadeInOnView>
<FadeInOnView delayMs={500}>
<CallToAction />
</FadeInOnView>
<FadeInOnView delayMs={600}>
<Faqs />
</FadeInOnView>
</main>
<Footer />
</>

View File

@@ -3,9 +3,9 @@ import clsx from 'clsx'
const baseStyles = {
solid:
'group inline-flex items-center justify-center rounded-full py-2 px-6 text-sm font-semibold focus-visible:outline-2 focus-visible:outline-offset-2',
'group inline-flex items-center justify-center rounded-sm py-2 px-6 text-sm font-semibold focus-visible:outline-2 focus-visible:outline-offset-2',
outline:
'group inline-flex ring-1 items-center justify-center rounded-full py-2 px-6 text-sm',
'group inline-flex ring-1 items-center justify-center rounded-sm py-2 px-6 text-sm',
}
const variantStyles = {
@@ -24,7 +24,7 @@ const variantStyles = {
slate:
'ring-slate-200 text-slate-700 hover:text-slate-900 hover:ring-slate-300 active:bg-slate-100 active:text-slate-600 focus-visible:outline-blue-600 focus-visible:ring-slate-300',
white:
'ring-slate-700 text-white hover:ring-slate-500 active:ring-slate-700 active:text-slate-400 focus-visible:outline-white',
'ring-white text-white hover:ring-slate-500 active:ring-slate-900 active:text-slate-400 focus-visible:outline-white',
},
}

View File

@@ -22,7 +22,7 @@ function NavLinkDark({
return (
<Link
href={href}
className="inline-block rounded-lg px-2 tracking-wider py-1 text-sm text-white hover:bg-white/10 hover:text-white"
className="inline-block rounded-lg px-2 tracking-widest py-1 text-sm text-white hover:bg-white/10 hover:text-white"
>
{children}
</Link>

View File

@@ -5,6 +5,7 @@ import { Button } from '@/components/Button'
import { Container } from '@/components/Container'
import { Logo_hero } from '@/components/Logo_hero'
import { H1, P } from '@/components/UI/Texts'
import { FadeInOnView } from '@/components/UI/FadeInOnView'
type HeroProps = {
@@ -30,18 +31,29 @@ export function Hero({ className }: HeroProps) {
{/* Content */}
<Container className="relative z-20 pt-24 pb-12 text-center lg:pt-32">
<H1 className="mx-auto lg:mt-6 mt-4 max-w-2xl text-xl lg:text-2xl tracking-tight font-medium text-white/90">
Shaping the future of Augmented Collective Intelligence
</H1>
<P className="mx-auto mt-6 max-w-2xl text-lg lg:text-xl tracking-tight text-white/90">
At OurWorld, we are building the required infrastructures and tools to enable an Augmented Collective Intelligence ; creating a sovereign, sustainable, and autonomous future for all.
</P>
<div className="mt-10 flex justify-center">
<Button href="/about" color="white">Learn More</Button>
</div>
<Container className="relative z-20 pt-12 pb-12 lg:pt-32">
<FadeInOnView>
<H1 className="max-w-3xl text-left text-white">
Shaping the future of Augmented Collective Intelligence
</H1>
</FadeInOnView>
</Container>
<FadeInOnView delayMs={150} className="my-12 hidden md:flex justify-center">
<div className="h-[2px] w-full max-w-7xl bg-white/90 animate-draw-line" />
</FadeInOnView>
<FadeInOnView
delayMs={300}
className="mx-auto md:mx-0 md:ml-auto md:w-[60%] space-y-6 flex flex-col items-center md:items-start"
>
<P className="max-w-xl text-lg lg:text-xl tracking-tight text-white/90">
At <span className="font-semibold">OurWorld</span>, we are building the required ventures, infrastructures and tools to enable an Augmented Collective Intelligence; creating a sovereign, sustainable, and autonomous future for all.
</P>
<Button href="/about" color="white" className="w-full md:w-auto mt-4">
Learn More
</Button>
</FadeInOnView>
</Container>
</div>
)
}

View File

@@ -0,0 +1,57 @@
'use client'
import React, { useEffect, useRef, useState } from 'react'
import { cn } from '@/lib/utils'
interface FadeInOnViewProps extends React.HTMLAttributes<HTMLDivElement> {
delayMs?: number
}
export function FadeInOnView({
delayMs = 0,
className,
children,
...props
}: FadeInOnViewProps) {
const ref = useRef<HTMLDivElement | null>(null)
const [visible, setVisible] = useState(false)
useEffect(() => {
if (!ref.current) return
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setVisible(true)
observer.disconnect()
}
})
},
{
threshold: 0.2,
},
)
observer.observe(ref.current)
return () => observer.disconnect()
}, [])
return (
<div
ref={ref}
className={cn(
'transition-all duration-700 ease-out',
visible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4',
className,
)}
style={{
transitionDelay: `${delayMs}ms`,
}}
{...props}
>
{children}
</div>
)
}

View File

@@ -0,0 +1,59 @@
import Image from 'next/image'
import clsx from 'clsx'
import { Button } from '@/components/Button'
import { Container } from '@/components/Container'
import { Logo_hero } from '@/components/Logo_hero'
import { H1, P } from '@/components/UI/Texts'
import { FadeInOnView } from '@/components/UI/FadeInOnView'
type HeroProps = {
className?: string
}
export function Hero({ className }: HeroProps) {
return (
<div className={clsx('relative overflow-hidden min-h-screen', className)}>
{/* Video Background */}
<video
autoPlay
muted
loop
playsInline
className="absolute inset-0 w-full h-full object-cover z-0"
>
<source src="/videos/ourworld.mp4" type="video/mp4" />
</video>
{/* Overlay for better text readability */}
<div className="absolute inset-0 bg-black/20 z-10"></div>
{/* Content */}
<Container className="relative z-20 pt-12 pb-12 lg:pt-32">
<FadeInOnView>
<H1 className="max-w-3xl text-left text-white">
Shaping the future of Augmented Collective Intelligence
</H1>
</FadeInOnView>
<FadeInOnView delayMs={150} className="my-12 hidden md:flex justify-center">
<div className="h-[2px] w-full max-w-7xl bg-white/90 animate-draw-line" />
</FadeInOnView>
<FadeInOnView
delayMs={300}
className="mx-auto md:mx-0 md:ml-auto md:w-[60%] space-y-6 flex flex-col items-center md:items-start"
>
<P className="max-w-2xl text-lg lg:text-xl tracking-tight text-white/90">
At OurWorld, we are building the required infrastructures and tools to enable an Augmented Collective Intelligence ; creating a sovereign, sustainable, and autonomous future for all.
</P>
<Button href="/about" variant="outline" color="white" className="w-full md:w-auto mt-4">
Learn More
</Button>
</FadeInOnView>
</Container>
</div>
)
}

View File

@@ -0,0 +1,104 @@
import { ArrowPathIcon, CircleStackIcon, InboxIcon, RocketLaunchIcon, ScaleIcon, TrashIcon, UsersIcon } from '@heroicons/react/24/outline'
const features = [
{
name: 'A Funding Platform',
description:
'Access capital for projects building on decentralized infrastructure, with a focus on ventures that contribute to digital sovereignty for people and sustainable technology for the planet.',
href: '#',
icon: CircleStackIcon,
},
{
name: 'Legal & Financial Autonomy',
description:
'Operate through our free zone with optimized legal and financial structures designed for global teams. Startups benefit from transparent, innovation-friendly structures designed for streamlined borderless operations.',
href: '#',
icon: ScaleIcon,
},
{
name: 'Technological Empowerment',
description:
'Build on our interconnected stack of decentralized cloud infrastructure, sovereign data centers, and agentic AI frameworks, giving your startup the tools for complete digital autonomy.',
href: '#',
icon: RocketLaunchIcon,
},
{
name: 'Collaborative Ecosystem',
description:
'Join a network of ventures building interconnected solutions for digital sovereignty. Share resources, infrastructure, and knowledge across projects working toward a decentralized future.',
href: '#',
icon: ArrowPathIcon,
},
]
export function HomeAbout() {
return (
<div className="relative bg-black py-24 sm:py-32 overflow-hidden">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div
aria-hidden="true"
className="absolute inset-0 -z-10 overflow-hidden"
>
<div
style={{
background: 'linear-gradient(135deg, #ff80b5 0%, #9089fc 100%)',
width: '800px',
height: '600px',
borderRadius: '50%',
filter: 'blur(100px)',
opacity: 0.3,
position: 'absolute',
top: '20%',
right: '10%'
}}
/>
<div
style={{
background: 'linear-gradient(225deg, #9089fc 0%, #ff80b5 100%)',
width: '600px',
height: '400px',
borderRadius: '50%',
filter: 'blur(80px)',
opacity: 0.2,
position: 'absolute',
bottom: '20%',
left: '10%'
}}
/>
</div>
<div className="mx-auto max-w-4xl lg:mx-0">
<p className="subtitle text-white">ABOUT</p>
<h2 className="mt-2 h2-default text-white">
Enabling an Interconnected Ecosystem to Enhance Collective Intelligence Through Collaboration.
</h2>
</div>
<div className="lg:mx-0 max-w-2xl mt-6">
<p className="p-default text-gray-300">
OurWorld is a venture creator providing startups with decentralized infrastructure, legal frameworks, and technological capacity to build without traditional constraints.
</p>
</div>
<div className="mx-auto mt-16 max-w-2xl lg:mt-16 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-2">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-xl/7 font-semibold text-white">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-white">
<feature.icon aria-hidden="true" className="size-6 text-black" />
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7 text-gray-300">
<p className="flex-auto">{feature.description}</p>
<p className="mt-6">
</p>
</dd>
</div>
))}
</dl>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,77 @@
const timeline = [
{
name: 'Core Infrastructure',
description:
'✓ Our decentralized, autonomous edge computing technology came alive, serving as the backbone of the OurWorld ecosystem.',
date: 'Phase 1',
description2:
'✓ OurWorld helped secure $50M in investment from our community of investors.',
},
{
name: 'Zanzibar Digital Free Zone',
description:
'✓ Partnered with Government of Zanzibar through ZICTA to establish the Zanzibar Digital Free Zone with financial and other incentives for ventures.',
description2:
'✓ Developed an alpha version of integrated platforms within the Free Zone to onboard new ventures into the ecosystem.',
date: 'Phase 2',
},
{
name: 'Commercial Expansion',
description:
'◯ $50M raise underway to expand core infrastructure and invest in new ventures with a focus on interdependent projects that strengthen the ecosystem collectively.',
description2:
'◯ Advancing the Geomind program with the phased rollout of Tier H and Tier S datacenters.',
date: 'Current Phase',
},
{
name: 'Scalable Impact',
description:
'◯ Deploy 1 million nodes and onboard 10 million users to empower the OurWorld ecosystem.',
description2:
'◯ Transition startups in our venture creator to community ownerships and ensure a successful exits for investors.',
date: 'Phase 4',
},
]
export function HomeMilestones() {
return (
<div className="bg-black py-24 sm:py-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-4xl lg:mx-0">
<p className="subtitle text-white">MILESTONES</p>
<h2 className="mt-2 h2-default text-white">
Our Development Journey
</h2>
<div className="lg:mx-0 max-w-2xl mt-6">
<p className="p-default text-gray-300">
Transform the future join a revolutionary journey towards a decentralized digital world driven by collaboration and collective intelligence.
</p>
</div>
</div>
<div className="mx-auto grid max-w-2xl mt-12 grid-cols-1 gap-8 overflow-hidden lg:mx-0 lg:max-w-none lg:grid-cols-4">
{timeline.map((item) => {
const isCurrent = item.date === 'Current Phase'
return (
<div key={item.name} className={`${isCurrent ? 'bg-white/5 ' : ''}`}>
<time className={`flex items-center text-sm/6 font-semibold ${isCurrent ? 'text:white' : 'text-white'}`}>
<svg viewBox="0 0 4 4" aria-hidden="true" className="mr-4 size-1 flex-none">
<circle r={2} cx={2} cy={2} fill="currentColor" />
</svg>
{item.date}
{isCurrent && <span className="ml-2 text-xs bg-white text-black px-2 py-1 rounded-full">ACTIVE</span>}
<div
aria-hidden="true"
className="absolute -ml-2 h-px w-screen -translate-x-full bg-white/20 sm:-ml-4 lg:static lg:-mr-6 lg:ml-8 lg:w-auto lg:flex-auto lg:translate-x-0"
/>
</time>
<p className={`mt-6 text-lg/8 font-semibold tracking-tight ${isCurrent ? 'text:white' : 'text-white'}`}>{item.name}</p>
<p className="mt-1 text-sm/7 text-gray-300 leading-relaxed">{item.description}</p>
<p className="mt-4 text-sm/7 text-gray-300 leading-relaxed">{item.description2}</p>
</div>
)
})}
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,116 @@
import {
GlobeAltIcon,
UsersIcon,
CommandLineIcon,
ShieldCheckIcon,
SparklesIcon,
} from '@heroicons/react/24/outline'
const foundations = [
{
id: 1,
title: 'Planet First',
description:
'We act with respect for the Earth. Each initiative supports regeneration and uses natural resources responsibly. Every venture should leave the planet better than it found it.',
icon: GlobeAltIcon,
},
{
id: 2,
title: 'People First',
description:
'Empowering people to own their digital lives through shared ownership, inclusive governance, and lifelong learning so everyone can grow and take part.',
icon: UsersIcon,
},
]
const tools = [
{
id: 3,
title: 'Open Source',
description:
'Everything we build is open source. Anyone can use it, improve it, and connect to the ecosystem. Transparency keeps innovation honest.',
icon: CommandLineIcon,
},
{
id: 4,
title: 'Simplicity',
description:
'Complex systems slow progress. We design modular, autonomous tools that remove unnecessary layers.',
icon: SparklesIcon,
},
{
id: 5,
title: 'Authenticity',
description:
'We are restoring trust online. Sovereign digital tools verify people and information, building a culture of transparency and accountability.',
icon: ShieldCheckIcon,
},
]
export function HomePrinciples() {
return (
<div className="bg-white py-24 sm:py-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:max-w-none">
<div className="text-center">
<h2 className="h2-default text-gray-900 ">
The Foundation of Every Venture
</h2>
<p className="mt-4 p-default text-gray-600">
We start every project with two essentials: protect the planet and empower people. Everything else follows from there.
</p>
</div>
<div className="mt-12 space-y-12">
<section>
<h3 className="text-sm font-semibold uppercase tracking-wide text-gray-500">Foundational Commitments</h3>
<dl className="mt-8 grid grid-cols-1 gap-4 lg:grid-cols-2">
{foundations.map((item) => {
const Icon = item.icon
return (
<div
key={item.id}
className="flex items-start gap-4 rounded-2xl border border-gray-200/70 bg-white/90 p-5 shadow-sm transition-all hover:-translate-y-0.5 hover:shadow-lg"
>
<div className="flex size-11 shrink-0 items-center justify-center rounded-full bg-gray-100 ring-1 ring-inset ring-gray-200">
<Icon aria-hidden="true" className="size-6 text-gray-900" />
</div>
<div className="space-y-2">
<h4 className="text-xl/7 font-semibold tracking-tight text-gray-900">{item.title}</h4>
<p className="text-base/7 text-gray-500">{item.description}</p>
</div>
</div>
)
})}
</dl>
</section>
<section>
<h3 className="text-sm font-semibold uppercase tracking-wide text-gray-500">Tools We Deploy</h3>
<p className="mt-3 p-default text-gray-600">
With people and planet at the core, these are the principles that shape how we build and operate.
</p>
<dl className="mt-8 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
{tools.map((item) => {
const Icon = item.icon
return (
<div
key={item.id}
className="flex flex-col items-center rounded-2xl border border-gray-200/70 bg-white/90 p-5 text-center shadow-sm transition-all hover:-translate-y-0.5 hover:shadow-lg"
>
<div className="flex size-11 items-center justify-center rounded-full bg-gray-100 ring-1 ring-inset ring-gray-200">
<Icon aria-hidden="true" className="size-6 text-gray-900" />
</div>
<h4 className="mt-4 text-xl/7 font-semibold tracking-tight text-gray-900">{item.title}</h4>
<p className="mt-2 text-base/7 text-gray-500">{item.description}</p>
</div>
)
})}
</dl>
</section>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,33 @@
"use client"
import { useEffect, useState } from "react"
import clsx from "clsx"
import { Header_darkbg } from "@/components/Header_darkbg"
export function HomeStickyHeader() {
const [scrolled, setScrolled] = useState(false)
useEffect(() => {
const handleScroll = () => {
const heroThreshold = window.innerHeight * 0.8
setScrolled(window.scrollY > heroThreshold)
}
handleScroll()
window.addEventListener("scroll", handleScroll)
return () => window.removeEventListener("scroll", handleScroll)
}, [])
return (
<div
className={clsx(
"sticky top-0 z-30 transition-all duration-300",
scrolled && "bg-black/40 backdrop-blur-md",
)}
>
<Header_darkbg />
</div>
)
}

View File

@@ -0,0 +1,81 @@
'use client'
import { Button } from '@/components/Button'
export function HomeVentures() {
return (
<div className="bg-white">
<div className="relative isolate">
<div className="overflow-hidden">
<div className="mx-auto max-w-7xl px-6 pt-24 pb-24 lg:px-8 lg:pt-24">
<div className="mx-auto max-w-2xl gap-x-14 lg:mx-0 lg:flex lg:max-w-none lg:items-center">
<div className="relative w-full lg:max-w-xl lg:shrink-0 xl:max-w-2xl">
<p className="subtitle text-gray-900">
VENTURES
</p>
<h2 className="h2-default text-gray-900">
Where Innovation Meets Independence
</h2>
<p className="mt-8 p-default text-gray-500 lg:max-w-none">
All ventures within the OurWorld ecosystem are connected through our shared principles, values, and the aim to bring forward a new era of digital autonomy and self-empowerment. Explore the ventures shaping our future.
</p>
<div className="mt-10 flex items-center">
<Button href="/ventures" color="black">Explore Ventures</Button>
</div>
</div>
<div className="mt-14 flex justify-end gap-8 sm:-mt-44 sm:justify-start sm:pl-20 lg:mt-0 lg:pl-0">
<div className="ml-auto w-44 flex-none space-y-8 pt-32 sm:ml-0 sm:pt-80 lg:order-last lg:pt-36 xl:order-0 xl:pt-80">
<div className="relative">
<img
alt=""
src="https://images.unsplash.com/photo-1557804506-669a67965ba0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&h=528&q=80"
className="aspect-2/3 w-full rounded-xl bg-gray-900/5 object-cover shadow-lg"
/>
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-gray-900/10 ring-inset" />
</div>
</div>
<div className="mr-auto w-44 flex-none space-y-8 sm:mr-0 sm:pt-52 lg:pt-36">
<div className="relative">
<img
alt=""
src="https://images.unsplash.com/photo-1485217988980-11786ced9454?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&h=528&q=80"
className="aspect-2/3 w-full rounded-xl bg-gray-900/5 object-cover shadow-lg"
/>
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-gray-900/10 ring-inset" />
</div>
<div className="relative">
<img
alt=""
src="https://images.unsplash.com/photo-1559136555-9303baea8ebd?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&crop=focalpoint&fp-x=.4&w=396&h=528&q=80"
className="aspect-2/3 w-full rounded-xl bg-gray-900/5 object-cover shadow-lg"
/>
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-gray-900/10 ring-inset" />
</div>
</div>
<div className="w-44 flex-none space-y-8 pt-32 sm:pt-0">
<div className="relative">
<img
alt=""
src="https://images.unsplash.com/photo-1670272504528-790c24957dda?ixlib=rb-4.0.3&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&crop=left&w=400&h=528&q=80"
className="aspect-2/3 w-full rounded-xl bg-gray-900/5 object-cover shadow-lg"
/>
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-gray-900/10 ring-inset" />
</div>
<div className="relative">
<img
alt=""
src="https://images.unsplash.com/photo-1670272505284-8faba1c31f7d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&h=528&q=80"
className="aspect-2/3 w-full rounded-xl bg-gray-900/5 object-cover shadow-lg"
/>
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-gray-900/10 ring-inset" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -93,4 +93,18 @@
font-family: 'Source Sans 3', var(--font-sans);
font-weight: 300;
}
@keyframes draw-line {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
.animate-draw-line {
animation: draw-line 4s ease-out forwards;
transform-origin: left;
}
}