dark mode

This commit is contained in:
sasha-astiadi 2025-08-02 19:40:54 +02:00
parent d5fe77a5d4
commit 663fd167b7
13 changed files with 104 additions and 98 deletions

2
next-env.d.ts vendored
View File

@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
// NOTE: This file should not be edited // NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information. // see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.

9
package-lock.json generated
View File

@ -1853,9 +1853,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001625", "version": "1.0.30001731",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001625.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz",
"integrity": "sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w==", "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -1869,7 +1869,8 @@
"type": "github", "type": "github",
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
] ],
"license": "CC-BY-4.0"
}, },
"node_modules/chalk": { "node_modules/chalk": {
"version": "4.1.2", "version": "4.1.2",

View File

@ -25,8 +25,8 @@ export default function RootLayout({
children: React.ReactNode children: React.ReactNode
}) { }) {
return ( return (
<html lang="en" className={clsx('bg-white antialiased', inter.variable)}> <html lang="en" className={clsx('antialiased', inter.variable)} style={{ backgroundColor: '#121212' }}>
<body>{children}</body> <body style={{ backgroundColor: '#121212', color: '#ffffff' }}>{children}</body>
</html> </html>
) )
} }

View File

@ -8,78 +8,78 @@ import Benefits4 from '@/images/benefits/benefits4.jpg'
export default function Benefits() { export default function Benefits() {
return ( return (
<div className="bg-white py-12"> <div style={{ backgroundColor: '#121212' }} className="py-12">
<div className="mx-auto max-w-2xl px-6 lg:max-w-7xl lg:px-8"> <div className="mx-auto max-w-2xl px-6 lg:max-w-7xl lg:px-8">
<Container> <Container>
<div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-3xl"> <div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-3xl">
<h2 className="lg:text-4xl text-3xl font-medium tracking-tight text-gray-900"> <h2 className="lg:text-4xl text-3xl font-medium tracking-tight text-white">
Built Different. For a Change. Built Different. For a Change.
</h2> </h2>
<p className="mt-6 lg:text-lg text-base text-gray-600"> <p className="mt-6 lg:text-lg text-base text-gray-300">
EngageOS isnt just another tech platform its a digital infrastructure built from the ground up for purpose-driven organizations. From white-label sovereignty to field-ready resilience, every element of EngageOS is designed to meet the real-world challenges of civil society. EngageOS isn't just another tech platform — it's a digital infrastructure built from the ground up for purpose-driven organizations. From white-label sovereignty to field-ready resilience, every element of EngageOS is designed to meet the real-world challenges of civil society.
</p> </p>
</div> </div>
</Container> </Container>
<div className="mt-10 grid grid-cols-1 gap-4 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2"> <div className="mt-10 grid grid-cols-1 gap-4 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2">
<div className="flex p-px lg:col-span-4"> <div className="flex p-px lg:col-span-4">
<div className="overflow-hidden rounded-lg bg-white ring-1 ring-black/15 max-lg:rounded-t-4xl lg:rounded-tl-4xl"> <div className="overflow-hidden rounded-lg bg-gray-900 ring-1 ring-gray-700 max-lg:rounded-t-4xl lg:rounded-tl-4xl">
<Image <Image
alt="" alt=""
src={Benefits1} src={Benefits1}
className="h-80 object-cover object-left" className="h-80 object-cover object-left"
/> />
<div className="p-10"> <div className="p-10">
<h3 className="text-sm/4 font-semibold text-gray-900"> Built for Civil Society</h3> <h3 className="text-sm/4 font-semibold text-white"> Built for Civil Society</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-900">Purpose-First, Not Profit-First</p> <p className="mt-2 text-lg font-medium tracking-tight text-white">Purpose-First, Not Profit-First</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-600"> <p className="mt-2 max-w-lg text-sm/6 text-gray-300">
Unlike traditional SaaS built for commercial scale, EngageOS was born from the realities of NGOs, grassroots coalitions, and purpose-led institutions. Every module, flow, and metric is optimized to serve impact not ad revenue or venture capital. Unlike traditional SaaS built for commercial scale, EngageOS was born from the realities of NGOs, grassroots coalitions, and purpose-led institutions. Every module, flow, and metric is optimized to serve impact not ad revenue or venture capital.
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div className="flex p-px lg:col-span-2"> <div className="flex p-px lg:col-span-2">
<div className="overflow-hidden rounded-lg bg-white ring-1 ring-black/15 lg:rounded-tr-4xl"> <div className="overflow-hidden rounded-lg bg-gray-900 ring-1 ring-gray-700 lg:rounded-tr-4xl">
<Image <Image
alt="" alt=""
src={Benefits2} src={Benefits2}
className="h-80 object-cover" className="h-80 object-cover"
/> />
<div className="p-10"> <div className="p-10">
<h3 className="text-sm/4 font-semibold text-gray-900">White-Label, Zero-Code</h3> <h3 className="text-sm/4 font-semibold text-white">White-Label, Zero-Code</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-900">Your Brand, Your Movements</p> <p className="mt-2 text-lg font-medium tracking-tight text-white">Your Brand, Your Movements</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-600"> <p className="mt-2 max-w-lg text-sm/6 text-gray-300">
EngageOS empowers organizations to fully own their digital identity. From Red Cross OS to Montessori OS, each instance is custom-branded no tech team required. You launch a platform that looks and feels like you, not us. EngageOS empowers organizations to fully own their digital identity. From Red Cross OS to Montessori OS, each instance is custom-branded no tech team required. You launch a platform that looks and feels like you, not us.
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div className="flex p-px lg:col-span-2"> <div className="flex p-px lg:col-span-2">
<div className="overflow-hidden rounded-lg bg-white ring-1 ring-black/15 lg:rounded-bl-4xl"> <div className="overflow-hidden rounded-lg bg-gray-900 ring-1 ring-gray-700 lg:rounded-bl-4xl">
<Image <Image
alt="" alt=""
src={Benefits3} src={Benefits3}
className="h-80 object-cover" className="h-80 object-cover"
/> />
<div className="p-10"> <div className="p-10">
<h3 className="text-sm/4 font-semibold text-gray-900">Sovereign & Ethical Infrastructure</h3> <h3 className="text-sm/4 font-semibold text-white">Sovereign & Ethical Infrastructure</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-900">Own Your Data. Always.</p> <p className="mt-2 text-lg font-medium tracking-tight text-white">Own Your Data. Always.</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-600"> <p className="mt-2 max-w-lg text-sm/6 text-gray-300">
We dont mine or monetize user data. EngageOS runs on decentralized, privacy-respecting infrastructure built for trust, compliance, and sovereignty. You control where your data lives and who sees it. We don't mine or monetize user data. EngageOS runs on decentralized, privacy-respecting infrastructure built for trust, compliance, and sovereignty. You control where your data lives and who sees it.
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div className="flex p-px lg:col-span-4"> <div className="flex p-px lg:col-span-4">
<div className="overflow-hidden rounded-lg bg-white ring-1 ring-black/15 max-lg:rounded-b-4xl lg:rounded-br-4xl"> <div className="overflow-hidden rounded-lg bg-gray-900 ring-1 ring-gray-700 max-lg:rounded-b-4xl lg:rounded-br-4xl">
<Image <Image
alt="" alt=""
src={Benefits4} src={Benefits4}
className="h-80 object-cover object-left" className="h-80 object-cover object-left"
/> />
<div className="p-10"> <div className="p-10">
<h3 className="text-sm/4 font-semibold text-gray-900">Mutualized Model</h3> <h3 className="text-sm/4 font-semibold text-white">Mutualized Model</h3>
<p className="mt-2 text-lg font-medium tracking-tight text-gray-900">Share Infrastructure. Multiply Impact.</p> <p className="mt-2 text-lg font-medium tracking-tight text-white">Share Infrastructure. Multiply Impact.</p>
<p className="mt-2 max-w-lg text-sm/6 text-gray-600"> <p className="mt-2 max-w-lg text-sm/6 text-gray-300">
By pooling tech costs across aligned organizations, EngageOS offers enterprise-grade functionality at a fraction of the price. When one partner grows, the entire ecosystem benefits through shared modules, updates, and insights. By pooling tech costs across aligned organizations, EngageOS offers enterprise-grade functionality at a fraction of the price. When one partner grows, the entire ecosystem benefits through shared modules, updates, and insights.
</p> </p>
</div> </div>

View File

@ -1,6 +1,6 @@
export default function Cta() { export default function Cta() {
return ( return (
<div className="bg-white"> <div style={{ backgroundColor: '#121212' }}>
<div className="mx-auto max-w-7xl py-24 sm:px-6 sm:py-32 lg:px-8"> <div className="mx-auto max-w-7xl py-24 sm:px-6 sm:py-32 lg:px-8">
<div className="relative isolate overflow-hidden bg-gray-900 px-6 py-24 text-center shadow-2xl sm:rounded-3xl sm:px-16"> <div className="relative isolate overflow-hidden bg-gray-900 px-6 py-24 text-center shadow-2xl sm:rounded-3xl sm:px-16">
<h2 className="text-4xl font-semibold tracking-tight text-balance text-white sm:text-5xl"> <h2 className="text-4xl font-semibold tracking-tight text-balance text-white sm:text-5xl">
@ -30,9 +30,9 @@ export default function Cta() {
<circle r={512} cx={512} cy={512} fill="url(#engage-gradient)" fillOpacity="0.7" /> <circle r={512} cx={512} cy={512} fill="url(#engage-gradient)" fillOpacity="0.7" />
<defs> <defs>
<radialGradient id="engage-gradient"> <radialGradient id="engage-gradient">
<stop offset="0%" stop-color="#caa5f0" /> <stop offset="0%" stopColor="#caa5f0" />
<stop offset="50%" stop-color="#8f79f9" /> <stop offset="50%" stopColor="#8f79f9" />
<stop offset="100%" stop-color="#5d84e1" /> <stop offset="100%" stopColor="#5d84e1" />
</radialGradient> </radialGradient>
</defs> </defs>

View File

@ -22,11 +22,11 @@ function QrCodeBorder(props: React.ComponentPropsWithoutRef<'svg'>) {
export function Footer() { export function Footer() {
return ( return (
<footer className="border-t border-gray-200"> <footer className="border-t border-gray-700" style={{ backgroundColor: '#121212' }}>
<Container> <Container>
<div className="flex flex-col items-start justify-between gap-y-12 pt-16 pb-6 lg:flex-row lg:items-center lg:py-16"> <div className="flex flex-col items-start justify-between gap-y-12 pt-16 pb-6 lg:flex-row lg:items-center lg:py-16">
<div> <div>
<div className="flex items-center text-gray-900"> <div className="flex items-center text-white">
<Logomark className="h-10 w-10 flex-none fill-cyan-500" /> <Logomark className="h-10 w-10 flex-none fill-cyan-500" />
<div className="ml-4"> <div className="ml-4">
<p className="text-base font-semibold">EngageOS</p> <p className="text-base font-semibold">EngageOS</p>
@ -37,25 +37,25 @@ export function Footer() {
<NavLinks /> <NavLinks />
</nav> </nav>
</div> </div>
<div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-100 sm:self-auto sm:rounded-2xl lg:mx-0 lg:self-auto lg:p-6"> <div className="group relative -mx-4 flex items-center self-stretch p-4 transition-colors hover:bg-gray-800 sm:self-auto sm:rounded-2xl lg:mx-0 lg:self-auto lg:p-6">
<div className="relative flex h-24 w-24 flex-none items-center justify-center"> <div className="relative flex h-24 w-24 flex-none items-center justify-center">
<QrCodeBorder className="absolute inset-0 h-full w-full stroke-gray-300 transition-colors group-hover:stroke-cyan-500" /> <QrCodeBorder className="absolute inset-0 h-full w-full stroke-gray-600 transition-colors group-hover:stroke-cyan-500" />
<Image src={qrCode} alt="" unoptimized /> <Image src={qrCode} alt="" unoptimized />
</div> </div>
<div className="ml-8 lg:w-64"> <div className="ml-8 lg:w-64">
<p className="text-base font-semibold text-gray-900"> <p className="text-base font-semibold text-white">
<Link href="#"> <Link href="#">
<span className="absolute inset-0 sm:rounded-2xl" /> <span className="absolute inset-0 sm:rounded-2xl" />
Download the app Download the app
</Link> </Link>
</p> </p>
<p className="mt-1 text-sm text-gray-700"> <p className="mt-1 text-sm text-gray-300">
Scan the QR code to download the app from the App Store. Scan the QR code to download the app from the App Store.
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div className="flex flex-col items-center border-t border-gray-200 pt-8 pb-12 md:flex-row-reverse md:justify-between md:pt-6"> <div className="flex flex-col items-center border-t border-gray-700 pt-8 pb-12 md:flex-row-reverse md:justify-between md:pt-6">
<form className="flex w-full justify-center md:w-auto"> <form className="flex w-full justify-center md:w-auto">
<TextField <TextField
type="email" type="email"
@ -70,7 +70,7 @@ export function Footer() {
<span className="lg:hidden">Join newsletter</span> <span className="lg:hidden">Join newsletter</span>
</Button> </Button>
</form> </form>
<p className="mt-6 text-sm text-gray-500 md:mt-0"> <p className="mt-6 text-sm text-gray-400 md:mt-0">
&copy; Copyright {new Date().getFullYear()}. All rights reserved. &copy; Copyright {new Date().getFullYear()}. All rights reserved.
</p> </p>
</div> </div>

View File

@ -49,7 +49,7 @@ function MobileNavLink(
return ( return (
<PopoverButton <PopoverButton
as={Link} as={Link}
className="block text-base/7 tracking-tight text-gray-700" className="block text-base/7 tracking-tight text-gray-300"
{...props} {...props}
/> />
) )
@ -73,7 +73,7 @@ export function Header() {
{({ open }) => ( {({ open }) => (
<> <>
<PopoverButton <PopoverButton
className="relative z-10 -m-2 inline-flex items-center rounded-lg stroke-gray-900 p-2 hover:bg-gray-200/50 hover:stroke-gray-600 focus:not-data-focus:outline-hidden active:stroke-gray-900" className="relative z-10 -m-2 inline-flex items-center rounded-lg stroke-white p-2 hover:bg-gray-800/50 hover:stroke-gray-300 focus:not-data-focus:outline-hidden active:stroke-white"
aria-label="Toggle site navigation" aria-label="Toggle site navigation"
> >
{({ open }) => {({ open }) =>
@ -93,7 +93,7 @@ export function Header() {
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
exit={{ opacity: 0 }} exit={{ opacity: 0 }}
className="fixed inset-0 z-0 bg-gray-300/60 backdrop-blur-sm" className="fixed inset-0 z-0 bg-black/60 backdrop-blur-sm"
/> />
<PopoverPanel <PopoverPanel
static static
@ -105,7 +105,7 @@ export function Header() {
y: -32, y: -32,
transition: { duration: 0.2 }, transition: { duration: 0.2 },
}} }}
className="absolute inset-x-0 top-0 z-0 origin-top rounded-b-2xl bg-gray-50 px-6 pt-32 pb-6 shadow-2xl shadow-gray-900/20" className="absolute inset-x-0 top-0 z-0 origin-top rounded-b-2xl bg-gray-900 px-6 pt-32 pb-6 shadow-2xl shadow-black/20"
> >
<div className="space-y-4"> <div className="space-y-4">
<MobileNavLink href="/#features"> <MobileNavLink href="/#features">

View File

@ -14,14 +14,14 @@ const navigation = [
export default function HeroHome() { export default function HeroHome() {
return ( return (
<div className="bg-white"> <div style={{ backgroundColor: '#121212' }}>
<div className=""> <div className="">
<div className="mx-auto max-w-7xl px-8 lg:px-8"> <div className="mx-auto max-w-7xl px-8 lg:px-8">
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<h1 className="text-3xl font-medium tracking-tight text-gray-900 lg:text-5xl"> <h1 className="text-3xl font-medium tracking-tight text-white lg:text-5xl">
Empowering Purpose-Driven Organizations. Empowering Purpose-Driven Organizations.
</h1> </h1>
<p className="mt-8 lg:lg:text-lg text-base text-base text-gray-600"> <p className="mt-8 lg:lg:text-lg text-base text-base text-gray-300">
Welcome to <span className={`font-semibold ${gradientText}`}>EngageOS</span>: the first all-in-one, white-label engagement platform to mobilize communities, engage supporters, scale impact, and fundraiseat a fraction of the cost. Welcome to <span className={`font-semibold ${gradientText}`}>EngageOS</span>: the first all-in-one, white-label engagement platform to mobilize communities, engage supporters, scale impact, and fundraiseat a fraction of the cost.
</p> </p>
<div className="mt-12 flex items-center justify-center gap-x-6 relative z-10"> <div className="mt-12 flex items-center justify-center gap-x-6 relative z-10">

View File

@ -17,7 +17,7 @@ export function NavLinks() {
<Link <Link
key={label} key={label}
href={href} href={href}
className="relative -mx-3 -my-2 rounded-lg px-3 py-2 text-sm text-gray-700 transition-colors delay-150 hover:text-gray-900 hover:delay-0" className="relative -mx-3 -my-2 rounded-lg px-3 py-2 text-sm text-gray-300 transition-colors delay-150 hover:text-white hover:delay-0"
onMouseEnter={() => { onMouseEnter={() => {
if (timeoutRef.current) { if (timeoutRef.current) {
window.clearTimeout(timeoutRef.current) window.clearTimeout(timeoutRef.current)
@ -33,7 +33,7 @@ export function NavLinks() {
<AnimatePresence> <AnimatePresence>
{hoveredIndex === index && ( {hoveredIndex === index && (
<motion.span <motion.span
className="absolute inset-0 rounded-lg bg-gray-100" className="absolute inset-0 rounded-lg bg-gray-800"
layoutId="hoverBackground" layoutId="hoverBackground"
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1, transition: { duration: 0.15 } }} animate={{ opacity: 1, transition: { duration: 0.15 } }}

View File

@ -126,14 +126,14 @@ function Plan({
return ( return (
<section <section
className={clsx( className={clsx(
'flex flex-col overflow-hidden rounded-3xl p-6 shadow-lg shadow-gray-900/5', 'flex flex-col overflow-hidden rounded-3xl p-6 shadow-lg shadow-black/20',
featured ? 'order-first bg-gray-900 lg:order-none' : 'bg-white', featured ? 'order-first bg-cyan-600 lg:order-none' : 'bg-gray-900',
)} )}
> >
<h3 <h3
className={clsx( className={clsx(
'flex items-center text-sm font-semibold', 'flex items-center text-sm font-semibold',
featured ? 'text-white' : 'text-gray-900', featured ? 'text-white' : 'text-white',
)} )}
> >
<Logomark className={clsx('h-6 w-6 flex-none', logomarkClassName)} /> <Logomark className={clsx('h-6 w-6 flex-none', logomarkClassName)} />
@ -142,7 +142,7 @@ function Plan({
<p <p
className={clsx( className={clsx(
'relative mt-5 flex text-3xl tracking-tight', 'relative mt-5 flex text-3xl tracking-tight',
featured ? 'text-white' : 'text-gray-900', featured ? 'text-white' : 'text-white',
)} )}
> >
{price.Monthly === price.Annually ? ( {price.Monthly === price.Annually ? (
@ -175,7 +175,7 @@ function Plan({
<p <p
className={clsx( className={clsx(
'mt-3 text-sm', 'mt-3 text-sm',
featured ? 'text-gray-300' : 'text-gray-700', featured ? 'text-gray-100' : 'text-gray-300',
)} )}
> >
{description} {description}
@ -186,8 +186,8 @@ function Plan({
className={clsx( className={clsx(
'-my-2 divide-y text-sm', '-my-2 divide-y text-sm',
featured featured
? 'divide-gray-800 text-gray-300' ? 'divide-gray-700 text-gray-100'
: 'divide-gray-200 text-gray-700', : 'divide-gray-700 text-gray-300',
)} )}
> >
{features.map((feature) => ( {features.map((feature) => (
@ -195,7 +195,7 @@ function Plan({
<CheckIcon <CheckIcon
className={clsx( className={clsx(
'h-6 w-6 flex-none', 'h-6 w-6 flex-none',
featured ? 'text-white' : 'text-cyan-500', featured ? 'text-white' : 'text-cyan-400',
)} )}
/> />
<span className="ml-4">{feature}</span> <span className="ml-4">{feature}</span>
@ -205,7 +205,7 @@ function Plan({
</div> </div>
<Button <Button
href={button.href} href={button.href}
color={featured ? 'cyan' : 'gray'} color={featured ? 'white' : 'cyan'}
className="mt-6" className="mt-6"
aria-label={`Get started with the ${name} plan for ${price}`} aria-label={`Get started with the ${name} plan for ${price}`}
> >
@ -224,19 +224,20 @@ export function Pricing() {
<section <section
id="pricing" id="pricing"
aria-labelledby="pricing-title" aria-labelledby="pricing-title"
className="border-t border-gray-200 bg-white py-24" className="border-t border-gray-800 py-24"
style={{ backgroundColor: '#121212' }}
> >
<Container> <Container>
<div className="mx-auto max-w-2xl text-center"> <div className="mx-auto max-w-2xl text-center">
<h2 <h2
id="pricing-title" id="pricing-title"
className="text-3xl font-medium tracking-tight text-gray-900" className="text-3xl font-medium tracking-tight text-white"
> >
Flat pricing, no management fees. Flat pricing, no management fees.
</h2> </h2>
<p className="mt-2 lg:text-lg text-base text-gray-600"> <p className="mt-2 lg:text-lg text-base text-gray-300">
Whether youre one person trying to get ahead or a big firm trying Whether you're one person trying to get ahead or a big firm trying
to take over the world, weve got a plan for you. to take over the world, we've got a plan for you.
</p> </p>
</div> </div>
@ -252,7 +253,7 @@ export function Pricing() {
key={period} key={period}
value={period} value={period}
className={clsx( className={clsx(
'cursor-pointer border border-gray-300 px-[calc(--spacing(3)-1px)] py-[calc(--spacing(2)-1px)] text-sm text-gray-700 transition-colors hover:border-gray-400 data-focus:outline-2 data-focus:outline-offset-2', 'cursor-pointer border border-gray-600 px-[calc(--spacing(3)-1px)] py-[calc(--spacing(2)-1px)] text-sm text-gray-300 transition-colors hover:border-gray-500 data-focus:outline-2 data-focus:outline-offset-2 bg-gray-800',
period === 'Monthly' period === 'Monthly'
? 'rounded-l-lg' ? 'rounded-l-lg'
: '-ml-px rounded-r-lg', : '-ml-px rounded-r-lg',
@ -286,7 +287,7 @@ export function Pricing() {
</div> </div>
</div> </div>
<div className="mx-auto bg-white mt-16 grid max-w-2xl grid-cols-1 items-start gap-x-8 gap-y-10 sm:mt-20 lg:max-w-none lg:grid-cols-3"> <div className="mx-auto mt-16 grid max-w-2xl grid-cols-1 items-start gap-x-8 gap-y-10 sm:mt-20 lg:max-w-none lg:grid-cols-3">
{plans.map((plan) => ( {plans.map((plan) => (
<Plan key={plan.name} {...plan} activePeriod={activePeriod} /> <Plan key={plan.name} {...plan} activePeriod={activePeriod} />
))} ))}

View File

@ -16,13 +16,13 @@ interface Review {
const reviews: Array<Review> = [ const reviews: Array<Review> = [
{ {
title: 'A true game-changer for nonprofits.', title: 'A true game-changer for nonprofits.',
body: 'EngageOS allowed us to centralize our volunteer hub, training, and crowdfunding into one platform. Weve seen a 3x jump in community engagement.', body: 'EngageOS allowed us to centralize our volunteer hub, training, and crowdfunding into one platform. We have seen a 3x jump in community engagement.',
author: 'Sarah D., Program Director at WomenRise', author: 'Sarah D., Program Director at WomenRise',
rating: 5, rating: 5,
}, },
{ {
title: 'No tech team needed.', title: 'No tech team needed.',
body: 'Launching our own branded platform felt intimidating—until EngageOS. Its intuitive, scalable, and beautifully designed.', body: 'Launching our own branded platform felt intimidating—until EngageOS. It is intuitive, scalable, and beautifully designed.',
author: 'Ahmed K., Director at The Green Schools Alliance', author: 'Ahmed K., Director at The Green Schools Alliance',
rating: 5, rating: 5,
}, },
@ -52,7 +52,7 @@ const reviews: Array<Review> = [
}, },
{ {
title: 'Highly recommend for grassroots orgs.', title: 'Highly recommend for grassroots orgs.',
body: 'Even with limited staff, we launched a branded hub in 10 days. Its helping our community organize and train in ways we never imagined.', body: 'Even with limited staff, we launched a branded hub in 10 days. It is helping our community organize and train in ways we never imagined.',
author: 'Tania B., Founder of SpeakUp Brazil', author: 'Tania B., Founder of SpeakUp Brazil',
rating: 5, rating: 5,
}, },
@ -69,14 +69,13 @@ const reviews: Array<Review> = [
rating: 5, rating: 5,
}, },
{ {
title: 'This platform *is* our movement.', title: 'This platform is our movement.',
body: 'Before EngageOS, our digital presence was scattered. Now we have a true home where our supporters connect and take action.', body: 'Before EngageOS, our digital presence was scattered. Now we have a true home where our supporters connect and take action.',
author: 'Ravi P., Strategy Director at Clean Energy for All', author: 'Ravi P., Strategy Director at Clean Energy for All',
rating: 5, rating: 5,
}, },
] ]
function StarIcon(props: React.ComponentPropsWithoutRef<'svg'>) { function StarIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return ( return (
<svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <svg viewBox="0 0 20 20" aria-hidden="true" {...props}>
@ -119,21 +118,21 @@ function Review({
return ( return (
<figure <figure
className={clsx( className={clsx(
'animate-fade-in rounded-3xl bg-white p-6 opacity-0 shadow-md shadow-gray-900/5', 'animate-fade-in rounded-3xl bg-gray-900 p-6 opacity-0 shadow-md shadow-black/20',
className, className,
)} )}
style={{ animationDelay }} style={{ animationDelay }}
{...props} {...props}
> >
<blockquote className="text-gray-900"> <blockquote className="text-white">
<StarRating rating={rating} /> <StarRating rating={rating} />
<p className="mt-4 lg:text-lg text-base/6 font-semibold before:content-['“'] after:content-['”']"> <p className="mt-4 lg:text-lg text-base/6 font-semibold">
{title} "{title}"
</p> </p>
<p className="mt-3 text-base/7">{body}</p> <p className="mt-3 text-base/7">{body}</p>
</blockquote> </blockquote>
<figcaption className="mt-3 text-sm text-gray-600 before:content-['_']"> <figcaption className="mt-3 text-sm text-gray-300">
{author} {author}
</figcaption> </figcaption>
</figure> </figure>
) )
@ -241,8 +240,8 @@ function ReviewGrid() {
/> />
</> </>
)} )}
<div className="pointer-events-none absolute inset-x-0 top-0 h-32 bg-linear-to-b from-gray-50" /> <div className="pointer-events-none absolute inset-x-0 top-0 h-32 bg-gradient-to-b from-gray-950" />
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-32 bg-linear-to-t from-gray-50" /> <div className="pointer-events-none absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-gray-950" />
</div> </div>
) )
} }
@ -253,15 +252,16 @@ export function Reviews() {
id="reviews" id="reviews"
aria-labelledby="reviews-title" aria-labelledby="reviews-title"
className="pt-20 pb-16 sm:pt-32 sm:pb-24" className="pt-20 pb-16 sm:pt-32 sm:pb-24"
style={{ backgroundColor: '#121212' }}
> >
<Container> <Container>
<h2 <h2
id="reviews-title" id="reviews-title"
className="text-3xl font-medium tracking-tight text-gray-900 sm:text-center" className="text-3xl font-medium tracking-tight text-white sm:text-center"
> >
Everyone is changing their life with EngageOS. Everyone is changing their life with EngageOS.
</h2> </h2>
<p className="mt-2 lg:text-lg text-base text-gray-600 sm:text-center"> <p className="mt-2 lg:text-lg text-base text-gray-300 sm:text-center">
Thousands of people have doubled their net-worth in the last 30 days. Thousands of people have doubled their net-worth in the last 30 days.
</p> </p>
<ReviewGrid /> <ReviewGrid />

View File

@ -19,11 +19,11 @@ const stats = [
export default function Tractions() { export default function Tractions() {
return ( return (
<div className="relative bg-white py-12"> <div className="relative py-12" style={{ backgroundColor: '#121212' }}>
<div className="mx-auto grid max-w-7xl lg:grid-cols-2"> <div className="mx-auto grid max-w-7xl lg:grid-cols-2">
{/* LEFT IMAGE + LOGO */} {/* LEFT IMAGE + LOGO */}
<div className="flex flex-col items-center lg:items-start gap-8 px-6 pb-12 lg:px-8"> <div className="flex flex-col items-center lg:items-start gap-8 px-6 pb-12 lg:px-8">
<div className="w-full ring-1 ring-black/15 rounded-3xl overflow-hidden max-lg:rounded-t-4xl lg:rounded-tl-4xl"> <div className="w-full ring-1 ring-gray-700 rounded-3xl overflow-hidden max-lg:rounded-t-4xl lg:rounded-tl-4xl">
<Image <Image
alt="" alt=""
src={Traction} src={Traction}
@ -56,18 +56,18 @@ export default function Tractions() {
{/* RIGHT TEXT BLOCK */} {/* RIGHT TEXT BLOCK */}
<div className="px-6 lg:px-8"> <div className="px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:mr-0 lg:max-w-lg"> <div className="mx-auto max-w-2xl lg:mr-0 lg:max-w-lg">
<h2 className="text-base/8 font-semibold text-gray-900">Our track record</h2> <h2 className="text-base/8 font-semibold text-white">Our track record</h2>
<p className="mt-2 text-3xl font-medium tracking-tight text-gray-900 sm:text-4xl"> <p className="mt-2 text-3xl font-medium tracking-tight text-white sm:text-4xl">
Trusted by Changemakers worldwide Trusted by Changemakers worldwide
</p> </p>
<p className="mt-6 lg:text-lg text-base text-gray-600"> <p className="mt-6 lg:text-lg text-base text-gray-300">
EngageOS powers the digital headquarters for over 300,000 users across 50+ countries. From grassroots NGOs to global movements, our platform is built to scale impact, not just numbers. EngageOS powers the digital headquarters for over 300,000 users across 50+ countries. From grassroots NGOs to global movements, our platform is built to scale impact, not just numbers.
</p> </p>
<dl className="mt-16 grid max-w-xl grid-cols-1 gap-8 sm:mt-20 sm:grid-cols-2 xl:mt-16"> <dl className="mt-16 grid max-w-xl grid-cols-1 gap-8 sm:mt-20 sm:grid-cols-2 xl:mt-16">
{stats.map((stat) => ( {stats.map((stat) => (
<div key={stat.id} className="flex flex-col gap-y-3 border-l border-gray-900/10 pl-6"> <div key={stat.id} className="flex flex-col gap-y-3 border-l border-gray-600 pl-6">
<dt className="text-sm/6 text-gray-600">{stat.name}</dt> <dt className="text-sm/6 text-gray-300">{stat.name}</dt>
<dd className="order-first text-3xl font-semibold tracking-tight text-gray-900">{stat.value}</dd> <dd className="order-first text-3xl font-semibold tracking-tight text-white">{stat.value}</dd>
</div> </div>
))} ))}
</dl> </dl>

View File

@ -41,17 +41,21 @@
--radius-4xl: 2rem; --radius-4xl: 2rem;
--radius-5xl: 2.5rem; --radius-5xl: 2.5rem;
--color-gray-50: oklch(0.985 0 0); /* Dark mode color palette - inverted grays */
--color-gray-100: oklch(0.97 0 0); --color-gray-50: oklch(0.145 0 0);
--color-gray-200: oklch(0.922 0 0); --color-gray-100: oklch(0.205 0 0);
--color-gray-300: oklch(0.87 0 0); --color-gray-200: oklch(0.269 0 0);
--color-gray-400: oklch(0.708 0 0); --color-gray-300: oklch(0.371 0 0);
--color-gray-400: oklch(0.439 0 0);
--color-gray-500: oklch(0.556 0 0); --color-gray-500: oklch(0.556 0 0);
--color-gray-600: oklch(0.439 0 0); --color-gray-600: oklch(0.708 0 0);
--color-gray-700: oklch(0.371 0 0); --color-gray-700: oklch(0.87 0 0);
--color-gray-800: oklch(0.269 0 0); --color-gray-800: oklch(0.922 0 0);
--color-gray-900: oklch(0.205 0 0); --color-gray-900: oklch(0.97 0 0);
--color-gray-950: oklch(0.145 0 0); --color-gray-950: oklch(0.985 0 0);
/* Custom dark background */
--color-dark-bg: #121212;
--font-sans: var(--font-inter); --font-sans: var(--font-inter);