From 886f9f18477ca5b81e08ab026a552756edf18277 Mon Sep 17 00:00:00 2001 From: Chris Parsons Date: Wed, 22 Apr 2026 22:17:57 -0700 Subject: [PATCH] Fix brackets on homepage. --- app/components/marketing/LandingPage.tsx | 246 ++++++++++++----------- 1 file changed, 132 insertions(+), 114 deletions(-) diff --git a/app/components/marketing/LandingPage.tsx b/app/components/marketing/LandingPage.tsx index fe3abe1..9e5984b 100644 --- a/app/components/marketing/LandingPage.tsx +++ b/app/components/marketing/LandingPage.tsx @@ -31,7 +31,7 @@ function getInterval(tick: number): number { } function SlotMachineHeadline() { - const [text, setText] = useState("\u00A0"); + const [text, setText] = useState(SPORTS[0]); const [landed, setLanded] = useState(false); const [animKey, setAnimKey] = useState(0); const tickRef = useRef(0); @@ -82,129 +82,130 @@ function SlotMachineHeadline() { // ─── Bracket Decoration ────────────────────────────────────────────────────── -const LIME = "#adf661"; -const LIME_DIM = "rgba(173,246,97,0.07)"; -const LIME_DIM_BORDER = "rgba(173,246,97,0.25)"; -const LIME_CHAMP = "rgba(173,246,97,0.12)"; -const LIME_CHAMP_BORDER = "rgba(173,246,97,0.8)"; -const SLOT_BG = "rgba(32,33,36,0.95)"; -const SLOT_BORDER = "rgba(255,255,255,0.10)"; -const LINE_COLOR_R1 = "rgba(255,255,255,0.15)"; -const LINE_COLOR_R2 = "rgba(255,255,255,0.28)"; +function BracketDecor({ flip = false, mobileTall = false }: { flip?: boolean; mobileTall?: boolean }) { + const base = flip ? "r" : "l"; + const id = mobileTall ? `${base}-m` : base; + const W = 399; + const H = mobileTall ? 2000 : 560; -// SVG coordinate-space layout constants -const SW = 80; -const SH = 20; -const GAP = 10; -const PAIR_H = SH * 2 + GAP; -const R1_X = 10; -const R2_X = 120; -const R3_X = 210; -const BRACKET_W = 300; -const BRACKET_H = 360; -const R1_TOP = 50; -const PAIR_GAP = 20; + const pad = 36; + const spacing = (H - 2 * pad) / 7; + const r1Ys = Array.from({ length: 8 }, (_, i) => pad + i * spacing); + const r2Ys = [0, 1, 2, 3].map((i) => (r1Ys[i * 2] + r1Ys[i * 2 + 1]) / 2); + const r3Ys = [0, 1].map((i) => (r2Ys[i * 2] + r2Ys[i * 2 + 1]) / 2); + const champY = (r3Ys[0] + r3Ys[1]) / 2; -type SlotDef = { - x: number; y: number; w: number; h: number; - winner?: boolean; champ?: boolean; -}; + const x0 = 4; + const x1 = 77; + const x2 = 161; + const x3 = 252; -function BracketSlot({ x, y, w, h, winner, champ }: SlotDef) { - const bg = champ ? LIME_CHAMP : winner ? LIME_DIM : SLOT_BG; - const border = champ ? LIME_CHAMP_BORDER : winner ? LIME_DIM_BORDER : SLOT_BORDER; - const bw = champ ? 1.5 : 1; - return ( - - - {(winner || champ) && ( - - )} - {champ && ( - - CHAMP - - )} - - ); -} + const gradId = `grad-${id}`; + const glowId = `glow-${id}`; + const finalsGlowId = `finals-glow-${id}`; + const finalsHaloId = `finals-halo-${id}`; + const finalsFadeMaskGradId = `finals-fade-mask-grad-${id}`; + const finalsFadeMaskId = `finals-fade-mask-${id}`; + const finalsLineGlowId = `finals-line-glow-${id}`; -function hLine(x1: number, y1: number, x2: number, color: string) { - return ; -} - -function connector(ax: number, ay: number, bx: number, by: number, cx: number, color: string) { - const midY = (ay + by) / 2; - return ( - - ); -} - -function BracketDecor({ flip = false }: { flip?: boolean }) { - const r1Pairs: [SlotDef, SlotDef][] = Array.from({ length: 4 }, (_, i) => { - const pairY = R1_TOP + i * (PAIR_H + PAIR_GAP); - const winner = i % 3 !== 1; - return [ - { x: R1_X, y: pairY, w: SW, h: SH, winner: winner && i % 2 === 0 }, - { x: R1_X, y: pairY + SH + GAP, w: SW, h: SH, winner: winner && i % 2 !== 0 }, - ]; - }); - - const r2Slots: SlotDef[] = [0, 1].map((i) => { - const top1Y = R1_TOP + (i * 2) * (PAIR_H + PAIR_GAP); - const bot2Y = R1_TOP + (i * 2 + 1) * (PAIR_H + PAIR_GAP) + SH + GAP; - const midY = (top1Y + bot2Y) / 2 - SH / 2; - return { x: R2_X, y: midY, w: SW, h: SH, winner: i === 0 }; - }); - - const r3Y = (r2Slots[0].y + r2Slots[1].y + SH) / 2 - SH / 2; - const r3Slot: SlotDef = { x: R3_X, y: r3Y, w: SW, h: SH + 4, champ: true }; return ( - {r1Pairs.map(([a, b], i) => ( - - - - {connector( - R1_X + SW, a.y + SH / 2, - r2Slots[Math.floor(i / 2)].x, r2Slots[Math.floor(i / 2)].y + SH / 2, - R1_X + SW + 14, - LINE_COLOR_R1 - )} - {hLine(R1_X + SW + 14, (a.y + SH / 2 + b.y + SH / 2) / 2, R2_X, LINE_COLOR_R1)} - - ))} - - {r2Slots.map((s, ri) => ( - - - {connector( - R2_X + SW, r2Slots[0].y + SH / 2, - r3Slot.x, r3Slot.y + (r3Slot.h ?? SH) / 2, - R2_X + SW + 14, - LINE_COLOR_R2 - )} - {ri === 1 && hLine(R2_X + SW + 14, (r2Slots[0].y + SH / 2 + r2Slots[1].y + SH / 2) / 2, R3_X, LINE_COLOR_R2)} - - ))} - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {r3Ys.map((midY) => ( + + ))} + + + + {r3Ys.map((midY) => ( + + ))} + + + + {r1Ys.map((y) => ( + + + + + ))} + {r2Ys.map((midY, i) => ( + + + + + + ))} + {r3Ys.map((midY, i) => ( + + + + + + ))} + + + + ); } @@ -303,6 +304,7 @@ const FOOTER_LINKS = [ { label: "Home", to: "/" }, { label: "Rules", to: "/rules" }, { label: "How to Play", to: "/how-to-play" }, + { label: "Support", to: "/support" }, { label: "Privacy Policy", to: "/privacy-policy" }, ]; @@ -345,7 +347,23 @@ export function LandingPage() { className="relative flex flex-col items-center justify-center overflow-hidden px-8" style={{ minHeight: "calc(100vh - var(--navbar-height))" }} > - {/* Bracket decorations — lg+ only */} + {/* Dot-grid texture */} +
+ + {/* Bracket decorations */} +
+ + +
@@ -354,7 +372,7 @@ export function LandingPage() { {/* Center content */} -
+

- Draft teams across every sport — NHL, NBA, NFL, EPL, World Cup, and more. - Compete with your friends in a league all season long. + Draft teams across every league and sport, like the NFL, NHL, EPL, F1, and more. + Compete against your friends in a season-long league.