Skip to content

Commit 5cc6ac1

Browse files
committed
Merge origin/main into feature branch
Resolve conflicts: keep direct <a> links from main, preserve lowercase "Apply to join" text and Sponsor button removal from our branch. Made-with: Cursor
2 parents e217867 + 02f02c1 commit 5cc6ac1

9 files changed

Lines changed: 1436 additions & 310 deletions

File tree

App.tsx

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import React, { useEffect, useRef, useState } from "react";
1+
import React, { useEffect, useRef } from "react";
22
import Navigation from "./components/Navigation";
33
import Hero from "./components/Hero";
44
import CinematicTransition from "./components/CinematicTransition";
55
import EventContent from "./components/EventContent";
6+
import CollisionSection from "./components/CollisionSection";
67
import EventPage from "./pages/EventPage";
7-
import LumaModal from "./components/LumaModal";
88
import gsap from "gsap";
99

1010
const App: React.FC = () => {
1111
const markerRefs = useRef<Array<HTMLDivElement | null>>([]);
12-
const [lumaOpen, setLumaOpen] = useState(false);
1312
const isEventPage = window.location.pathname === "/event";
1413

1514
useEffect(() => {
@@ -66,6 +65,8 @@ const App: React.FC = () => {
6665
backgroundSize: "200px",
6766
pointerEvents: "none",
6867
zIndex: 9999,
68+
willChange: "transform",
69+
contain: "strict",
6970
}}
7071
/>
7172
{/* Global vignette */}
@@ -77,6 +78,8 @@ const App: React.FC = () => {
7778
"radial-gradient(ellipse 85% 85% at center, transparent 45%, rgba(5,5,5,0.55) 100%)",
7879
pointerEvents: "none",
7980
zIndex: 100,
81+
willChange: "transform",
82+
contain: "strict",
8083
}}
8184
/>
8285
{/* Cinematic registration corner marks */}
@@ -119,17 +122,111 @@ const App: React.FC = () => {
119122
height: 32,
120123
pointerEvents: "none",
121124
zIndex: 9998,
125+
willChange: "transform",
122126
...style,
123127
}}
124128
/>
125129
))}
126-
<Navigation onOpenWaitlist={() => setLumaOpen(true)} />
130+
<Navigation />
127131
<main>
128132
<Hero onApply={() => setLumaOpen(true)} />
129133
<CinematicTransition />
130-
<EventContent onOpenLuma={() => setLumaOpen(true)} />
134+
<EventContent />
135+
<CollisionSection />
131136
</main>
132-
<LumaModal isOpen={lumaOpen} onClose={() => setLumaOpen(false)} />
137+
<footer
138+
style={{
139+
position: "relative",
140+
padding: "3.5rem 2rem 2.5rem",
141+
display: "flex",
142+
flexDirection: "column",
143+
alignItems: "center",
144+
textAlign: "center",
145+
gap: "1rem",
146+
background: "#050505",
147+
borderTop: "1px solid rgba(198,153,58,0.12)",
148+
}}
149+
>
150+
<div
151+
style={{
152+
fontFamily: "'IBM Plex Mono', monospace",
153+
fontSize: "0.65rem",
154+
color: "rgba(198,153,58,0.4)",
155+
letterSpacing: "0.25em",
156+
textTransform: "uppercase",
157+
marginBottom: "-0.25rem",
158+
}}
159+
>
160+
Presented by
161+
</div>
162+
<div
163+
style={{
164+
fontFamily: "'IBM Plex Serif', serif",
165+
fontSize: "1.35rem",
166+
fontWeight: 600,
167+
color: "rgba(224,213,192,0.85)",
168+
letterSpacing: "0.02em",
169+
}}
170+
>
171+
<a
172+
href="https://giveago.co"
173+
target="_blank"
174+
rel="noopener noreferrer"
175+
style={{
176+
color: "inherit",
177+
textDecoration: "none",
178+
transition: "color 0.2s ease",
179+
}}
180+
onMouseEnter={(e) => {
181+
(e.currentTarget as HTMLElement).style.color = "rgba(198,153,58,1)";
182+
}}
183+
onMouseLeave={(e) => {
184+
(e.currentTarget as HTMLElement).style.color = "rgba(224,213,192,0.85)";
185+
}}
186+
>
187+
Give(a)Go
188+
</a>
189+
<span style={{ color: "rgba(198,153,58,0.35)", margin: "0 0.4em" }}>
190+
×
191+
</span>
192+
<a
193+
href="https://napkin.io"
194+
target="_blank"
195+
rel="noopener noreferrer"
196+
style={{
197+
color: "inherit",
198+
textDecoration: "none",
199+
transition: "color 0.2s ease",
200+
}}
201+
onMouseEnter={(e) => {
202+
(e.currentTarget as HTMLElement).style.color = "rgba(198,153,58,1)";
203+
}}
204+
onMouseLeave={(e) => {
205+
(e.currentTarget as HTMLElement).style.color = "rgba(224,213,192,0.85)";
206+
}}
207+
>
208+
Napkin
209+
</a>
210+
</div>
211+
<div
212+
style={{
213+
width: 40,
214+
height: 1,
215+
background: "linear-gradient(90deg, transparent, rgba(198,153,58,0.2), transparent)",
216+
margin: "0.5rem 0",
217+
}}
218+
/>
219+
<div
220+
style={{
221+
fontFamily: "'IBM Plex Mono', monospace",
222+
fontSize: "0.5rem",
223+
color: "rgba(198,153,58,0.18)",
224+
letterSpacing: "0.15em",
225+
}}
226+
>
227+
&copy; {new Date().getFullYear()} Give(a)Go
228+
</div>
229+
</footer>
133230
</div>
134231
);
135232
};

components/CinematicTransition.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,25 +149,35 @@ const CinematicTransition: React.FC = () => {
149149
return { dx, dy, dist };
150150
};
151151

152+
let cachedVh = window.innerHeight;
153+
let cachedVw = window.innerWidth;
154+
const onResizeCt = () => { cachedVh = window.innerHeight; cachedVw = window.innerWidth; };
155+
window.addEventListener("resize", onResizeCt);
156+
152157
const tick = () => {
153158
raf = requestAnimationFrame(tick);
154-
const vh = window.innerHeight;
155-
const vw = window.innerWidth;
159+
const vh = cachedVh;
160+
const vw = cachedVw;
156161
const isMobile = vw <= 768;
157162
const sectionRect = sectionRef.current?.getBoundingClientRect();
163+
164+
// Skip all work if section is far from viewport
165+
if (sectionRect && (sectionRect.bottom < -vh || sectionRect.top > vh * 3)) {
166+
if (rootRef.current && rootRef.current.style.opacity !== "0") {
167+
rootRef.current.style.opacity = "0";
168+
}
169+
return;
170+
}
171+
158172
const PRE_ENTRY_VH = 1.32;
159173
const entryStart = vh * PRE_ENTRY_VH;
160-
// End timeline when next content is about to enter viewport
161-
// (i.e. when this section has only 1 viewport height remaining).
162174
const activeScrollRange = sectionRect
163175
? Math.max(1, sectionRect.height - vh)
164176
: 1;
165177
const totalRange = entryStart + activeScrollRange;
166178
const p = sectionRect
167179
? clamp((entryStart - sectionRect.top) / totalRange, 0, 1)
168180
: 0;
169-
// Pre-roll the cinematic timeline so clapboard is already entering
170-
// as soon as users scroll into this section (avoids initial dead-black beat).
171181
const TIMELINE_DELAY = 0.02;
172182
const timelineP = clamp((p - TIMELINE_DELAY) / (1 - TIMELINE_DELAY), 0, 1);
173183
const endFade = 1 - phase(p, 0.88, 1.0);
@@ -405,6 +415,7 @@ const CinematicTransition: React.FC = () => {
405415
raf = requestAnimationFrame(tick);
406416
return () => {
407417
cancelAnimationFrame(raf);
418+
window.removeEventListener("resize", onResizeCt);
408419
void clapAudioCtxRef.current?.close();
409420
clapAudioCtxRef.current = null;
410421
};

0 commit comments

Comments
 (0)