Skip to content

Commit 0c0a9fc

Browse files
authored
Add sponsors (#4)
1 parent e7cf77a commit 0c0a9fc

6 files changed

Lines changed: 164 additions & 17 deletions

File tree

public/sponsors/rerun.png

117 KB
Loading

public/sponsors/rerun.svg

Lines changed: 11 additions & 0 deletions
Loading
27 KB
Loading

src/app/globals.css

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ html {
4242
}
4343

4444
body {
45-
min-height: 100%;
45+
min-height: 100vh;
46+
margin: 0;
47+
display: flex;
48+
flex-direction: column;
4649
}
4750

4851
body {
@@ -93,9 +96,14 @@ body {
9396
content: none;
9497
}
9598

99+
.site-main {
100+
flex: 1 0 auto;
101+
}
102+
96103
.site-footer {
97104
position: relative;
98105
z-index: 0; /* create context so ::before can sit behind */
106+
flex-shrink: 0;
99107
}
100108

101109
/* Remove external fade overlay to avoid covering preceding content */

src/app/globals.scss

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ html {
4343
}
4444

4545
body {
46-
min-height: 100%;
46+
min-height: 100vh;
47+
margin: 0;
48+
display: flex;
49+
flex-direction: column;
4750
}
4851

4952
body {
@@ -89,9 +92,14 @@ body {
8992
content: none;
9093
}
9194

95+
.site-main {
96+
flex: 1 0 auto;
97+
}
98+
9299
.site-footer {
93100
position: relative;
94101
z-index: 0; /* create context so ::before can sit behind */
102+
flex-shrink: 0;
95103
}
96104

97105
/* Remove external fade overlay to avoid covering preceding content */
@@ -806,6 +814,16 @@ body {
806814
border-bottom: none;
807815
}
808816

817+
.sponsor-entry {
818+
padding-bottom: 2rem;
819+
border-bottom: 1px solid rgba(96, 165, 250, 0.15);
820+
}
821+
822+
.sponsor-entry:last-child {
823+
border-bottom: none;
824+
padding-bottom: 0;
825+
}
826+
809827
.pub-grid {
810828
display: grid;
811829
gap: 1rem;

src/app/sponsors/page.tsx

Lines changed: 125 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,147 @@
11
import type { Metadata } from "next";
2+
import Image from "next/image";
3+
import Link from "next/link";
24

35
export const metadata: Metadata = {
46
title: "Sponsors — Team whIRLwind",
57
description: "Our generous sponsors.",
68
};
79

8-
const sponsors = new Array(8).fill(0).map((_, i) => ({
9-
id: i + 1,
10-
name: `Sponsor ${String.fromCharCode(65 + i)}`,
11-
}));
10+
type Sponsor = {
11+
name: string;
12+
website?: string;
13+
contribution?: string;
14+
notes?: string;
15+
logo?: string;
16+
logoAlt?: string;
17+
logoWidth?: number;
18+
logoHeight?: number;
19+
};
20+
21+
// TODO: replace placeholder data with the team's actual sponsors when ready.
22+
const sponsors: Sponsor[] = [
23+
{
24+
name: "Rerun",
25+
website: "https://rerun.io",
26+
logo: "/sponsors/rerun.svg",
27+
logoAlt: "Rerun logo",
28+
logoWidth: 94,
29+
logoHeight: 28,
30+
},
31+
{
32+
name: "StartUp Village",
33+
website: "https://startupvillage.nl",
34+
logo: "/sponsors/startup_village.webp",
35+
logoAlt: "StartUp Village logo",
36+
logoWidth: 1500,
37+
logoHeight: 756,
38+
},
39+
];
40+
41+
function formatWebsite(url?: string): string | null {
42+
if (!url) return null;
43+
return url.replace(/^https?:\/\//, "").replace(/\/$/, "");
44+
}
1245

1346
export default function SponsorsPage() {
1447
return (
1548
<section className="page">
1649
<div className="container">
1750
<h1>Sponsors</h1>
1851
<p className="lead">
19-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
20-
bibendum, eros non ultricies aliquet, lorem arcu tempor lorem, vitae
21-
dictum arcu mi non eros.
52+
These partners keep our robots rolling and make it possible to share
53+
the work beyond the lab.
2254
</p>
2355

24-
<div className="grid">
25-
{sponsors.map((s) => (
26-
<div key={s.id} className="panel px-4 py-8 text-center">
56+
<div className="space-y-12">
57+
{sponsors.map((sponsor) => {
58+
const isRerun = sponsor.name === "Rerun";
59+
const imageStyle = {
60+
width: "auto" as const,
61+
maxWidth: isRerun ? "420px" : "240px",
62+
height: isRerun ? "96px" : "80px",
63+
};
64+
const hasDetails = Boolean(
65+
sponsor.contribution || sponsor.notes,
66+
);
67+
const captionClass = [
68+
"flex flex-col items-center text-center",
69+
isRerun ? "gap-2" : "gap-3",
70+
].join(" ");
71+
const logoWrapperClass = [
72+
"flex shrink-0 items-center justify-center rounded-xl",
73+
isRerun
74+
? "px-4 pt-2 pb-1"
75+
: "px-4 py-4 bg-white shadow-sm border border-[rgba(255,255,255,0.12)]",
76+
].join(" ");
77+
78+
return (
2779
<div
28-
className="grid h-[90px] w-full place-items-center rounded-xl border border-dashed border-[rgba(251,146,60,0.35)] bg-[linear-gradient(180deg,rgba(27,39,66,0.3),rgba(27,39,66,0.1))]"
29-
aria-label={`${s.name} placeholder`}
80+
key={sponsor.name}
81+
className="sponsor-entry space-y-6"
3082
>
31-
<span className="font-bold text-(--ink-dim)">{s.name}</span>
83+
<div
84+
className={[
85+
"flex flex-col gap-6 sm:gap-10",
86+
hasDetails ? "sm:flex-row sm:items-start" : "items-start",
87+
].join(" ")}
88+
>
89+
<div className={captionClass}>
90+
{sponsor.logo &&
91+
sponsor.logoWidth &&
92+
sponsor.logoHeight && (
93+
<div className={logoWrapperClass}>
94+
<Image
95+
src={sponsor.logo}
96+
alt={sponsor.logoAlt ?? `${sponsor.name} logo`}
97+
width={sponsor.logoWidth ?? 200}
98+
height={sponsor.logoHeight ?? 80}
99+
sizes="(min-width: 640px) 280px, 60vw"
100+
className="object-contain"
101+
style={imageStyle}
102+
/>
103+
</div>
104+
)}
105+
106+
{formatWebsite(sponsor.website) && sponsor.website && (
107+
<Link
108+
href={sponsor.website}
109+
target={
110+
sponsor.website.startsWith("http")
111+
? "_blank"
112+
: undefined
113+
}
114+
rel={
115+
sponsor.website.startsWith("http")
116+
? "noopener noreferrer"
117+
: undefined
118+
}
119+
className="text-[0.85rem] uppercase tracking-wide text-(--ink-muted) transition-colors duration-200 hover:text-(--orange-400)"
120+
>
121+
{formatWebsite(sponsor.website)}
122+
</Link>
123+
)}
124+
</div>
125+
126+
{hasDetails && (
127+
<div className="space-y-3 sm:flex-1">
128+
{sponsor.contribution && (
129+
<p className="max-w-3xl text-[0.95rem] text-(--ink-dim)">
130+
{sponsor.contribution}
131+
</p>
132+
)}
133+
134+
{sponsor.notes && (
135+
<p className="text-[0.9rem] text-(--ink-muted)">
136+
{sponsor.notes}
137+
</p>
138+
)}
139+
</div>
140+
)}
141+
</div>
32142
</div>
33-
</div>
34-
))}
143+
);
144+
})}
35145
</div>
36146
</div>
37147
</section>

0 commit comments

Comments
 (0)