Skip to content
Merged
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
.codex
121 changes: 121 additions & 0 deletions src/app/components/GivethSupportCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
const GIVETH_URL = 'https://qf.giveth.io/project/the-red-guild';
const ARTICLE_URL = 'https://blog.theredguild.org/support-the-red-guild-in-the-ethereum-security-funding-round/';

interface GivethSupportCardProps {
variant?: 'banner' | 'supporters';
className?: string;
onClose?: () => void;
}

const GivethSupportCard = ({
variant = 'supporters',
className = '',
onClose,
}: GivethSupportCardProps) => {
const isPopup = variant === 'banner';

return (
<section
className={`relative w-full overflow-hidden rounded-[24px] border border-[#F7392F]/30 ${
isPopup
? 'bg-[linear-gradient(145deg,rgba(247,57,47,0.22),rgba(0,0,0,0.92)_48%,rgba(247,57,47,0.1))] px-5 py-6 shadow-[0_30px_90px_rgba(0,0,0,0.55)] sm:rounded-[28px] sm:px-7 sm:py-7'
: 'bg-[linear-gradient(145deg,rgba(247,57,47,0.16),rgba(0,0,0,0.92)_44%,rgba(255,255,255,0.02))] p-5 sm:rounded-[28px] sm:p-6 md:p-7'
} ${className}`}
>
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(247,57,47,0.26),transparent_34%),radial-gradient(circle_at_bottom_right,rgba(255,255,255,0.08),transparent_24%)]" />
{onClose ? (
<button
type="button"
onClick={onClose}
aria-label="Close support popup"
className="absolute right-3 top-3 z-20 flex h-9 w-9 items-center justify-center rounded-full border border-white/16 bg-black/45 text-white/80 transition-colors hover:border-white/28 hover:text-white sm:right-4 sm:top-4"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="h-4 w-4"
>
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</button>
) : null}
{isPopup ? (
<div className="relative z-10 mx-auto flex max-w-[38rem] flex-col items-center text-center">
<h2 className="mt-3 text-xl font-spartan-title leading-tight text-white sm:text-2xl md:text-[2rem]">
Fund public good security
</h2>
<p className="mt-3 max-w-[34rem] font-spartan-subtitle text-sm leading-relaxed text-white/82 sm:text-base">
Support The Red Guild in the Ethereum Security QF Round
</p>
<p className="mt-3 max-w-[34rem] font-spartan-body text-sm leading-relaxed text-white/75 sm:text-[15px]">
We do security research, education, and advocacy for Ethereum as a public good.
Your support helps keep this work open and accessible to the whole ecosystem.
</p>
<div className="mt-6 flex w-full flex-col items-center gap-3 sm:mt-7 sm:flex-row sm:justify-center">
<a
href={GIVETH_URL}
target="_blank"
rel="noopener noreferrer"
className="inline-flex min-w-[12rem] items-center justify-center rounded-full bg-[#F7392F] px-6 py-3 text-sm font-spartan-subtitle text-white transition-colors hover:bg-[#ff564d]"
>
Support on Giveth
</a>
<a
href={ARTICLE_URL}
target="_blank"
rel="noopener noreferrer"
className="inline-flex min-w-[10rem] items-center justify-center rounded-full border border-white/18 bg-white/6 px-5 py-3 text-sm font-spartan-subtitle text-white/88 transition-colors hover:bg-white/10 hover:text-white"
>
Read why
</a>
</div>
</div>
) : (
<div className="relative z-10 grid gap-6 lg:grid-cols-[1.3fr_0.9fr] lg:items-end">
<div className="max-w-2xl">
<h2 className="mt-2.5 text-[1.7rem] font-spartan-title leading-tight text-white sm:mt-3 sm:text-3xl">
Fund public good security
</h2>
<p className="mt-3 font-spartan-subtitle text-sm leading-relaxed text-white/82 sm:text-base">
Support The Red Guild in the Ethereum Security QF Round
</p>
<p className="mt-3 font-spartan-body text-sm leading-relaxed text-white/75 sm:text-base">
We do security research, education, and advocacy for Ethereum as a public good.
Your support helps keep this work open and accessible to the whole ecosystem.
</p>
</div>

<div className="relative z-10 w-full rounded-2xl border border-white/12 bg-black/35 p-4 sm:p-5">
<div className="flex flex-col gap-3 sm:flex-row">
<a
href={GIVETH_URL}
target="_blank"
rel="noopener noreferrer"
className="inline-flex w-full items-center justify-center text-center rounded-full bg-[#F7392F] px-4 py-3 text-sm font-spartan-subtitle text-white transition-colors hover:bg-[#ff564d] sm:w-auto sm:px-5 sm:py-2.5"
>
Support on Giveth
</a>
<a
href={ARTICLE_URL}
target="_blank"
rel="noopener noreferrer"
className="inline-flex w-full items-center justify-center text-center rounded-full border border-white/18 bg-white/6 px-4 py-3 text-sm font-spartan-subtitle text-white/88 transition-colors hover:bg-white/10 hover:text-white sm:w-auto sm:px-5 sm:py-2.5"
>
Read why
</a>
</div>
</div>
</div>
)}
</section>
);
};

export default GivethSupportCard;
7 changes: 5 additions & 2 deletions src/app/components/MainContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ function lerpColor(
};
}

const MainContent = ({ onSectionEnd, transitioning: parentTransitioning }: { onSectionEnd: () => void; transitioning?: boolean }) => {
const MainContent = ({
onSectionEnd,
transitioning: parentTransitioning,
}: { onSectionEnd: () => void; transitioning?: boolean }) => {
const [progress, setProgress] = useState(0);
const [transitioning, setTransitioning] = useState(false);
const [blockScroll, setBlockScroll] = useState(false);
Expand Down Expand Up @@ -82,7 +85,7 @@ const MainContent = ({ onSectionEnd, transitioning: parentTransitioning }: { onS
pointerEvents: (transitioning || parentTransitioning) ? 'none' : 'auto',
}}
>
<div className="flex flex-col items-center gap-6 w-full max-w-[800px]">
<div className="flex flex-col items-center gap-6 w-full max-w-[920px] px-4 sm:px-6">
<div className="w-[169px] h-[169px] relative flex-shrink-0 [&>*]:!opacity-100 [&>*]:!transition-none">
<Image
src="/assets/trg-logo.svg"
Expand Down
3 changes: 3 additions & 0 deletions src/app/components/SupportersCollaborators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import React from 'react';
import Image from 'next/image';
import GivethSupportCard from './GivethSupportCard';

const SupportersCollaborators: React.FC = () => {
return (
Expand Down Expand Up @@ -36,6 +37,8 @@ const SupportersCollaborators: React.FC = () => {
</div>
</div>

<GivethSupportCard variant="supporters" className="mt-6 w-full max-w-4xl" />

<div className="grid grid-cols-1 sm:grid-cols-3 gap-10 sm:gap-12 md:gap-20 items-center mt-8 mb-6">
<a
href="https://ethereum.foundation/"
Expand Down
28 changes: 18 additions & 10 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import BackgroundClouds from "./components/BackgroundClouds";
import LoadingScreen from './components/LoadingScreen';
import Indicators from './components/Indicators';
import ParticlesDOM from './components/ParticlesDOM';
import GivethSupportCard from "./components/GivethSupportCard";

export default function Home() {
const [showLoading, setShowLoading] = useState(false);
Expand All @@ -16,8 +17,8 @@ export default function Home() {
const [transitioning, setTransitioning] = useState(false);
const [blockScroll, setBlockScroll] = useState(false);
const [unmountScene, setUnmountScene] = useState(false);
const [showSupportPopup, setShowSupportPopup] = useState(true);

// When MainContent animation ends (Section1) - Fade to Scene
const handleSection1End = () => {
setTransitioning(true);
setBlockScroll(true);
Expand All @@ -26,12 +27,11 @@ export default function Home() {
setShowSection2(true);
setTransitioning(false);
setBlockScroll(false);
setUnmountScene(false); // Ensures Scene is mounted
setUnmountScene(false);
window.scrollTo({ top: 0, behavior: 'auto' });
}, 500); // Match fade duration
}, 500);
};

// Return from Scene (Section2) to MainContent (Section1) - Fade back
const handleBackToSection1 = () => {
setTransitioning(true);
setBlockScroll(true);
Expand All @@ -40,34 +40,42 @@ export default function Home() {
setShowSection1(true);
setTransitioning(false);
setBlockScroll(false);
setUnmountScene(true); // Unmounts Scene after fade-out
setUnmountScene(true);
window.scrollTo({ top: 0, behavior: 'auto' });
}, 500); // Match fade duration
}, 500);
};

React.useEffect(() => {
document.body.style.overflow = transitioning || blockScroll ? 'hidden' : '';
document.body.style.overflow = transitioning || blockScroll || (showSection1 && showSupportPopup) ? 'hidden' : '';
return () => {
document.body.style.overflow = '';
};
}, [transitioning, blockScroll]);
}, [transitioning, blockScroll, showSection1, showSupportPopup]);

return (
<div className="bg-black relative min-h-[100dvh]">
<div style={{ position: 'fixed', inset: 0, zIndex: 0, pointerEvents: 'none' }}>
<BackgroundClouds onlyInScene={showSection2} />
</div>
{/* Global particles that persist across all sections */}
<ParticlesDOM countMobile={12} countDesktop={24} zIndexClass="z-[25]" />
<Navbar />
<Indicators inMain={showSection1} inScene={showSection2} />
<main className="relative min-h-[100dvh] z-10">
<main className={`relative min-h-[100dvh] ${showSection1 && showSupportPopup ? 'z-[80]' : 'z-10'}`}>
<LoadingScreen enabled={showLoading} onLoadingComplete={() => setShowLoading(false)} />
{showSection1 && <MainContent onSectionEnd={handleSection1End} transitioning={transitioning} />}
{(showSection2 || (!unmountScene && transitioning)) && (
<Scene show={showSection2} transitioning={transitioning} onBack={handleBackToSection1} />
)}
</main>
{showSection1 && showSupportPopup ? (
<div className="fixed inset-0 z-[90] flex items-center justify-center overflow-y-auto bg-black/55 px-3 py-4 backdrop-blur-[3px] sm:px-4 sm:py-6">
<GivethSupportCard
variant="banner"
onClose={() => setShowSupportPopup(false)}
className="max-w-[44rem] max-h-[calc(100dvh-1.5rem)] overflow-y-auto sm:max-h-[calc(100dvh-3rem)]"
/>
</div>
) : null}
</div>
);
}
1 change: 0 additions & 1 deletion src/app/supporters/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export default function SupportersPage() {
<ParticlesDOM countMobile={12} countDesktop={24} />
<Navbar />
<main className="container mx-auto px-4 pt-32 pb-16 relative z-30 w-full">
{/* Supporters & Collaborators Section */}
<SupportersCollaborators />
</main>
</div>
Expand Down
Loading