Skip to content

Commit f308a24

Browse files
committed
Merge branch 'source' into new-conf-design--speakers
2 parents 84ab9f6 + f192c30 commit f308a24

36 files changed

+314
-1302
lines changed

src/app/conf/2025/components/call-for-proposals.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ export function CallForProposals() {
382382
>
383383
{tabsInOrder.map((tab, i) => (
384384
<TabButton
385+
key={tab}
385386
tab={tab}
386387
tabIndex={i === 0 ? 0 : -1}
387388
activeTab={activeTab}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration"
2+
3+
import logoMask from "./logo-mask.webp"
4+
5+
export interface CtaCardSectionProps extends React.HTMLAttributes<HTMLElement> {
6+
title: string
7+
description: string
8+
children: React.ReactNode
9+
}
10+
11+
export function CtaCardSection({
12+
className,
13+
title: heading,
14+
description,
15+
children,
16+
...rest
17+
}: CtaCardSectionProps) {
18+
return (
19+
<div className="gql-conf-section">
20+
<section
21+
className="relative overflow-hidden bg-gradient-to-r from-pri-dark to-pri-base p-6 dark:from-pri-darker dark:to-pri-dark sm:p-16"
22+
{...rest}
23+
>
24+
<div className="relative z-10 flex flex-col gap-10 sm:items-start [@media(max-width:420px)]:text-center">
25+
<div className="flex flex-col gap-6">
26+
<h2 className="text-neu-0 typography-d1 dark:text-neu-900">
27+
{heading}
28+
</h2>
29+
<p className="max-w-[555px] text-pretty text-neu-50 typography-body-lg dark:text-neu-800">
30+
{description}
31+
</p>
32+
</div>
33+
34+
{children}
35+
</div>
36+
37+
<div
38+
role="presentation"
39+
// prettier-ignore
40+
className="
41+
pointer-events-none absolute
42+
sm:bottom-[-277px] inset-0 sm:left-1/3 xl:left-1/2 sm:top-[-107px] xl:right-[-391px]
43+
[--start:hsl(var(--color-sec-base))]
44+
[--end:hsl(var(--color-sec-lighter))]
45+
dark:[--start:hsl(var(--color-sec-dark))]
46+
dark:[--end:hsl(var(--color-sec-base))]
47+
48+
[mask-size:cover]
49+
max-sm:[mask-position:center] max-sm:opacity-50
50+
sm:[mask-size:1117px]
51+
"
52+
style={{
53+
maskImage: `url(${logoMask.src})`,
54+
maskRepeat: "no-repeat",
55+
}}
56+
>
57+
<StripesDecoration
58+
thin
59+
oddClassName="bg-[linear-gradient(180deg,var(--start)_0%,var(--end)_100%)]"
60+
/>
61+
</div>
62+
</section>
63+
</div>
64+
)
65+
}
Binary file not shown.

src/app/conf/2025/components/footer/index.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ export function Footer({
2323
return (
2424
<footer className="gql-all-anchors-focusable relative !bg-neu-100 text-neu-900 typography-menu dark:!bg-neu-0 max-md:px-0 max-md:pt-0">
2525
<Stripes />
26-
<div className="flex flex-wrap justify-between gap-4 px-6 py-4 max-md:w-full lg:py-10">
26+
<div className="flex flex-wrap justify-between gap-4 p-4 max-md:w-full md:px-6 lg:py-10 2xl:px-10">
2727
{logo}
28-
<div className="flex gap-x-4 gap-y-2 typography-body-lg">
29-
<p className="flex items-center gap-2">
28+
<div className="flex gap-x-4 typography-body-lg max-sm:grid max-sm:grid-cols-2 max-sm:items-start max-sm:text-lg sm:gap-y-2">
29+
<p className="flex items-center whitespace-pre">
3030
<time dateTime="2025-09-08">September 08</time>
3131
<span>-</span>
32-
<time dateTime="2025-09-10">10, 2025</time>
32+
<time dateTime="2025-09-10">
33+
10<span className="max-sm:hidden">, 2025</span>
34+
</time>
3335
</p>
3436
<address className="not-italic">Amsterdam, Netherlands</address>
3537
</div>
@@ -41,7 +43,7 @@ export function Footer({
4143
</li>
4244
))}
4345
</ul>
44-
<div className="relative flex justify-between gap-10 px-6 py-4 text-sm max-lg:flex-col">
46+
<div className="relative flex justify-between gap-10 p-4 text-sm max-lg:flex-col md:px-6 2xl:px-10">
4547
<div className="flex flex-col font-light max-md:gap-5">
4648
<p>
4749
Copyright © {new Date().getFullYear()} The GraphQL Foundation. All
@@ -139,7 +141,7 @@ function FooterBox({ box }: { box: FooterLink | FooterLink[] }) {
139141
href={href}
140142
title={disabled ? "Coming soon" : undefined}
141143
className={clsx(
142-
"gql-focus-visible relative block h-full p-6",
144+
"gql-focus-visible relative block h-full p-4 pb-8 md:p-6 2xl:px-10",
143145
disabled ? "pointer-events-none" : "underline-offset-4 hover:underline",
144146
)}
145147
tabIndex={disabled ? -1 : undefined}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import image2023_1 from "./2023/1.webp"
2+
import image2023_2 from "./2023/2.webp"
3+
import image2023_3 from "./2023/3.webp"
4+
import image2023_4 from "./2023/4.webp"
5+
import image2023_5 from "./2023/5.webp"
6+
import image2023_6 from "./2023/6.webp"
7+
import image2023_7 from "./2023/7.webp"
8+
import image2023_8 from "./2023/8.webp"
9+
import image2023_9 from "./2023/9.webp"
10+
import image2023_10 from "./2023/10.webp"
11+
import image2023_11 from "./2023/11.webp"
12+
import image2023_12 from "./2023/12.webp"
13+
import image2023_13 from "./2023/13.webp"
14+
15+
import image2024_1 from "./2024/1.webp"
16+
import image2024_2 from "./2024/2.webp"
17+
import image2024_3 from "./2024/3.webp"
18+
import image2024_4 from "./2024/4.webp"
19+
import image2024_6 from "./2024/6.webp"
20+
import image2024_7 from "./2024/7.webp"
21+
import image2024_8 from "./2024/8.webp"
22+
import image2024_9 from "./2024/9.webp"
23+
import image2024_11 from "./2024/11.webp"
24+
import image2024_12 from "./2024/12.webp"
25+
import image2024_13 from "./2024/13.webp"
26+
27+
export const imagesByYear = {
28+
"2023": [
29+
image2023_8,
30+
image2023_11,
31+
image2023_3,
32+
image2023_1,
33+
image2023_13,
34+
image2023_6,
35+
image2023_9,
36+
image2023_4,
37+
image2023_12,
38+
image2023_2,
39+
image2023_10,
40+
image2023_7,
41+
image2023_5,
42+
],
43+
"2024": [
44+
image2024_2,
45+
image2024_3,
46+
image2024_12,
47+
image2024_7,
48+
image2024_9,
49+
image2024_6,
50+
image2024_13,
51+
image2024_11,
52+
image2024_8,
53+
image2024_4,
54+
image2024_1,
55+
],
56+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"use client"
2+
3+
import { useState } from "react"
4+
import { clsx } from "clsx"
5+
import Image from "next-image-export-optimizer"
6+
import type { StaticImageData } from "next/image"
7+
8+
import { Marquee } from "@/app/conf/_design-system/marquee"
9+
10+
import { imagesByYear } from "./images"
11+
12+
const YEARS = ["2024", "2023"] as const
13+
type Year = (typeof YEARS)[number]
14+
15+
export interface GalleryStripProps extends React.HTMLAttributes<HTMLElement> {}
16+
17+
export function GalleryStrip({ className, ...rest }: GalleryStripProps) {
18+
const [selectedYear, setSelectedYear] = useState<Year>("2024")
19+
20+
return (
21+
<section
22+
role="presentation"
23+
className={clsx("py-8 md:py-16", className)}
24+
{...rest}
25+
>
26+
<div className="flex gap-3.5 px-4 max-md:items-center md:px-24">
27+
{YEARS.map(year => (
28+
<button
29+
key={year}
30+
onClick={() => setSelectedYear(year)}
31+
className={clsx(
32+
"gql-focus-visible p-1 typography-menu",
33+
selectedYear === year
34+
? "bg-sec-light text-neu-900 dark:text-neu-0"
35+
: "text-neu-800",
36+
)}
37+
>
38+
{year}
39+
</button>
40+
))}
41+
</div>
42+
43+
<div className="mt-6 w-full md:mt-10">
44+
<Marquee
45+
gap={8}
46+
speed={35}
47+
drag
48+
reverse
49+
className="cursor-[var(--cursor-grabbing,grab)] touch-pan-y"
50+
>
51+
{imagesByYear[selectedYear].map((image, i) => {
52+
const key = `${selectedYear}-${i}`
53+
54+
return <GalleryStripImage key={key} image={image} index={i} />
55+
})}
56+
</Marquee>
57+
</div>
58+
</section>
59+
)
60+
}
61+
62+
function GalleryStripImage({
63+
image,
64+
index,
65+
}: {
66+
image: StaticImageData
67+
index: number
68+
}) {
69+
return (
70+
<div className="relative md:px-2">
71+
<Image
72+
data-index={index}
73+
src={image}
74+
alt=""
75+
role="presentation"
76+
// intrinsic 799x533
77+
height={320}
78+
width={index % 4 === 2 ? 256 : index % 3 === 2 ? 420 : 480}
79+
className="pointer-events-none h-[320px] object-cover"
80+
/>
81+
</div>
82+
)
83+
}

src/app/conf/2025/components/navbar.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Badge } from "../../_components/badge"
1010
import MenuIcon from "../pixelarticons/menu.svg?svgr"
1111
import CloseIcon from "../pixelarticons/close.svg?svgr"
1212
import { GraphQLConfLogoLink } from "./graphql-conf-logo-link"
13+
import { Anchor } from "../../_design-system/anchor"
1314

1415
export interface NavbarProps {
1516
links: { href: string; children: React.ReactNode; "aria-disabled"?: true }[]
@@ -31,6 +32,15 @@ export function Navbar({ links, year }: NavbarProps): ReactElement {
3132

3233
useEffect(() => {
3334
document.body.style.overflow = mobileDrawerOpen ? "hidden" : "auto"
35+
if (mobileDrawerOpen) {
36+
const closeOnEscape = (event: KeyboardEvent) => {
37+
if (event.key === "Escape") setMobileDrawerOpen(false)
38+
}
39+
document.addEventListener("keydown", closeOnEscape)
40+
return () => {
41+
document.removeEventListener("keydown", closeOnEscape)
42+
}
43+
}
3444
}, [mobileDrawerOpen])
3545

3646
return (
@@ -49,7 +59,7 @@ export function Navbar({ links, year }: NavbarProps): ReactElement {
4959
)}
5060
>
5161
<BackdropBlur />
52-
<div className="flex h-[var(--navbar-h)] items-center justify-between gap-5 px-4 lg:px-10">
62+
<div className="flex h-[var(--navbar-h)] items-center justify-between gap-5 px-4 md:px-6 2xl:px-10">
5363
<GraphQLConfLogoLink year={year} />
5464

5565
<div className="mr-auto flex h-full flex-col justify-center whitespace-pre border-x border-blk/60 px-4 typography-menu dark:border-white/80 max-xl:hidden">
@@ -80,27 +90,27 @@ export function Navbar({ links, year }: NavbarProps): ReactElement {
8090
<div className="flex w-full flex-col lg:mt-0 lg:block">
8191
{links.map(
8292
({ "aria-disabled": isDisabled, children, ...link }) => (
83-
<NextLink
93+
<Anchor
8494
aria-disabled={isDisabled}
8595
key={link.href}
8696
{...link}
87-
// if external link, open in new tab
88-
{...(link.href.startsWith("https") && {
89-
target: "_blank",
90-
rel: "noopener noreferrer",
91-
})}
9297
className={clsx(
9398
"p-5 underline-offset-4 hover:underline aria-disabled:pointer-events-none max-lg:text-base",
9499
pathname === link.href && "underline",
95100
)}
101+
onClick={() => {
102+
if (mobileDrawerOpen) {
103+
setMobileDrawerOpen(false)
104+
}
105+
}}
96106
>
97107
{children}
98108
{isDisabled && (
99109
<sup className="ml-2">
100110
<Badge className="text-white">Soon</Badge>
101111
</sup>
102112
)}
103-
</NextLink>
113+
</Anchor>
104114
),
105115
)}
106116
</div>

src/app/conf/2025/page.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import { RegisterSection } from "./components/register-section"
1212
import { Sponsors } from "./components/sponsors"
1313
import { GraphQLFoundationCard } from "./components/graphql-foundation-card"
1414
import { MarqueeRows } from "./components/marquee-rows"
15+
import { CtaCardSection } from "./components/cta-card-section"
16+
import { Button } from "../_design-system/button"
17+
import { GET_TICKETS_LINK } from "./links"
18+
import { GalleryStrip } from "./components/gallery-strip"
1519

1620
export const metadata: Metadata = {
1721
title: "GraphQLConf 2025 — Sept 08-10",
@@ -73,8 +77,17 @@ export default function Page() {
7377
className="my-8 xl:mb-16 xl:mt-10 2xl:mb-24"
7478
/>
7579
<Venue />
80+
<GalleryStrip />
7681
<GraphQLFoundationCard />
7782
<FAQ />
83+
<CtaCardSection
84+
title="Get your ticket"
85+
description="Join three transformative days of expert insights and innovation to shape the next decade of APIs!"
86+
>
87+
<Button variant="primary" href={GET_TICKETS_LINK}>
88+
Get tickets
89+
</Button>
90+
</CtaCardSection>
7891
<MarqueeRows
7992
variant="secondary"
8093
items={HERO_MARQUEE_ITEMS}

0 commit comments

Comments
 (0)