Skip to content

Commit 5a8b3b5

Browse files
Mattclaude
andcommitted
Update sponsors page layout and formatting
- Add dynamic tier ordering with known tier priority - Change to flowing desktop layout (tiers side-by-side) - Update tier titles to badge-style labels - Add collapsible bio toggle to SponsorCard - Remove tier badge from individual sponsor cards - Simplify CSS with flexible grid system Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b1b32cc commit 5a8b3b5

2 files changed

Lines changed: 115 additions & 128 deletions

File tree

src/lib/components/SponsorCard.svelte

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script lang="ts">
22
interface Sponsor {
3-
id: number;
3+
id: number | string;
44
name: string;
55
tier: string;
66
logo: string;
@@ -13,9 +13,15 @@
1313
}
1414
1515
let { sponsor }: Props = $props();
16+
17+
let expanded = $state(false);
18+
19+
function toggleBio() {
20+
expanded = !expanded;
21+
}
1622
</script>
1723

18-
<article class="sponsor-card sponsor-card--{sponsor.tier}">
24+
<article class="sponsor-card">
1925
<div class="sponsor-logo-wrapper">
2026
<img
2127
src={sponsor.logo}
@@ -26,12 +32,33 @@
2632
</div>
2733

2834
<div class="sponsor-content">
29-
<div class="sponsor-header">
30-
<h3 class="sponsor-name">{sponsor.name}</h3>
31-
<span class="sponsor-tier">{sponsor.tier}</span>
32-
</div>
33-
34-
<p class="sponsor-bio">{sponsor.bio}</p>
35+
<h3 class="sponsor-name">{sponsor.name}</h3>
36+
37+
{#if sponsor.bio}
38+
<button
39+
class="bio-toggle"
40+
onclick={toggleBio}
41+
aria-expanded={expanded}
42+
aria-controls="bio-{sponsor.id}"
43+
>
44+
{expanded ? 'Hide bio' : 'Read bio'}
45+
<svg
46+
class="chevron"
47+
class:rotated={expanded}
48+
width="16"
49+
height="16"
50+
viewBox="0 0 16 16"
51+
fill="none"
52+
aria-hidden="true"
53+
>
54+
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
55+
</svg>
56+
</button>
57+
58+
{#if expanded}
59+
<p id="bio-{sponsor.id}" class="sponsor-bio">{sponsor.bio}</p>
60+
{/if}
61+
{/if}
3562

3663
<a
3764
href={sponsor.website}
@@ -85,55 +112,44 @@
85112
padding: var(--space-lg);
86113
}
87114
88-
.sponsor-header {
89-
display: flex;
90-
align-items: center;
91-
justify-content: space-between;
92-
gap: var(--space-sm);
93-
margin-bottom: var(--space-sm);
94-
}
95-
96115
.sponsor-name {
97116
font-size: var(--text-lg);
98117
font-weight: 600;
99118
color: var(--color-text);
119+
margin-bottom: var(--space-sm);
100120
}
101121
102-
.sponsor-tier {
103-
padding: var(--space-xs) var(--space-sm);
104-
border-radius: var(--radius-full);
105-
font-size: var(--text-xs);
106-
font-weight: 600;
107-
text-transform: uppercase;
108-
letter-spacing: 0.05em;
109-
}
110-
111-
.sponsor-card--platinum .sponsor-tier {
112-
background: linear-gradient(135deg, #E5E4E2, #A8A9AD);
113-
color: #1a1a1a;
122+
.bio-toggle {
123+
display: flex;
124+
align-items: center;
125+
gap: var(--space-xs);
126+
padding: var(--space-xs) 0;
127+
font-size: var(--text-sm);
128+
font-weight: 500;
129+
color: var(--color-primary);
130+
margin-bottom: var(--space-sm);
114131
}
115132
116-
.sponsor-card--gold .sponsor-tier {
117-
background: linear-gradient(135deg, #FFD700, #FFA500);
118-
color: #1a1a1a;
133+
.bio-toggle:hover,
134+
.bio-toggle:focus-visible {
135+
text-decoration: underline;
119136
}
120137
121-
.sponsor-card--silver .sponsor-tier {
122-
background: linear-gradient(135deg, #C0C0C0, #A8A8A8);
123-
color: #1a1a1a;
138+
.chevron {
139+
transition: transform var(--transition-fast);
124140
}
125141
126-
.sponsor-card--bronze .sponsor-tier {
127-
background: linear-gradient(135deg, #CD7F32, #A0522D);
128-
color: var(--color-text-light);
142+
.chevron.rotated {
143+
transform: rotate(180deg);
129144
}
130145
131146
.sponsor-bio {
132-
flex: 1;
133147
font-size: var(--text-sm);
134148
line-height: 1.6;
135149
color: var(--color-gray-600);
136150
margin-bottom: var(--space-md);
151+
padding-top: var(--space-sm);
152+
border-top: 1px solid var(--color-gray-200);
137153
}
138154
139155
.sponsor-link {
@@ -144,6 +160,7 @@
144160
font-weight: 500;
145161
font-size: var(--text-sm);
146162
transition: gap var(--transition-fast);
163+
margin-top: auto;
147164
}
148165
149166
.sponsor-link:hover,

src/routes/sponsors/+page.svelte

Lines changed: 60 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,42 @@
1313
1414
let { data } = $props();
1515
16-
const tierOrder = ['platinum', 'gold', 'silver', 'bronze', 'community-partner'];
16+
const knownTierOrder = ['platinum', 'track', 'recruitment-sponsor', 'video-sponsor', 'delegate-lounge-sponsor', 'gold', 'silver', 'bronze', 'community-partner'];
1717
1818
let sponsors: Sponsor[] = data.sponsors;
1919
2020
function groupByTier(sponsorList: Sponsor[]): Map<string, Sponsor[]> {
2121
const grouped = new Map<string, Sponsor[]>();
2222
23-
for (const tier of tierOrder) {
24-
const tierSponsors = sponsorList.filter((s) => s.tier === tier);
25-
if (tierSponsors.length > 0) {
26-
grouped.set(tier, tierSponsors);
23+
for (const sponsor of sponsorList) {
24+
const tier = sponsor.tier;
25+
if (!grouped.has(tier)) {
26+
grouped.set(tier, []);
2727
}
28+
grouped.get(tier)!.push(sponsor);
2829
}
2930
3031
return grouped;
3132
}
3233
3334
let sponsorsByTier = $derived(groupByTier(sponsors));
3435
36+
let tierOrder = $derived.by(() => {
37+
const tiers = [...sponsorsByTier.keys()];
38+
return tiers.sort((a, b) => {
39+
const aIndex = knownTierOrder.indexOf(a.toLowerCase());
40+
const bIndex = knownTierOrder.indexOf(b.toLowerCase());
41+
if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;
42+
if (aIndex !== -1) return -1;
43+
if (bIndex !== -1) return 1;
44+
return a.localeCompare(b);
45+
});
46+
});
47+
3548
function formatTierTitle(tier: string): string {
3649
if (tier === 'community-partner') return 'Community Partners';
37-
return tier.charAt(0).toUpperCase() + tier.slice(1) + ' Sponsors';
50+
const label = tier.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
51+
return label + ' Sponsors';
3852
}
3953
</script>
4054

@@ -52,12 +66,13 @@
5266

5367
<div class="sponsors-content">
5468
{#each tierOrder as tier}
69+
{@const tierId = tier.replace(/\s+/g, '-')}
5570
{#if sponsorsByTier.has(tier)}
56-
<section class="tier-section" aria-labelledby="tier-{tier}">
57-
<h2 id="tier-{tier}" class="tier-title tier-title--{tier}">
71+
<section class="tier-section" aria-labelledby="tier-{tierId}">
72+
<h2 id="tier-{tierId}" class="tier-title">
5873
{formatTierTitle(tier)}
5974
</h2>
60-
<div class="sponsors-grid sponsors-grid--{tier}">
75+
<div class="sponsors-grid">
6176
{#each sponsorsByTier.get(tier) || [] as sponsor (sponsor.id)}
6277
<SponsorCard {sponsor} />
6378
{/each}
@@ -98,86 +113,42 @@
98113
99114
.sponsors-content {
100115
padding: var(--space-lg);
101-
max-width: 1200px;
116+
max-width: 1400px;
102117
margin: 0 auto;
103118
}
104119
105120
.tier-section {
106-
margin-bottom: var(--space-2xl);
121+
margin-bottom: var(--space-xl);
107122
}
108123
109124
.tier-title {
110-
font-size: var(--text-lg);
111-
font-weight: 600;
112-
margin-bottom: var(--space-lg);
113-
padding-bottom: var(--space-sm);
114-
border-bottom: 3px solid;
115-
}
116-
117-
.tier-title--platinum {
118-
border-color: #A8A9AD;
119-
}
120-
121-
.tier-title--gold {
122-
border-color: #FFD700;
123-
}
124-
125-
.tier-title--silver {
126-
border-color: #C0C0C0;
127-
}
128-
129-
.tier-title--bronze {
130-
border-color: #CD7F32;
131-
}
132-
133-
.tier-title--community-partner {
134-
border-color: #018AFC;
125+
font-size: var(--text-xs);
126+
font-weight: 700;
127+
text-transform: uppercase;
128+
letter-spacing: 0.05em;
129+
margin-bottom: var(--space-md);
130+
padding: var(--space-xs) var(--space-sm);
131+
border-radius: var(--radius-sm);
132+
display: inline-block;
133+
background: var(--color-gray-200);
134+
color: var(--color-text);
135135
}
136136
137137
.sponsors-grid {
138-
display: grid;
139-
gap: var(--space-lg);
140-
}
141-
142-
.sponsors-grid--platinum {
143-
grid-template-columns: 1fr;
144-
}
145-
146-
.sponsors-grid--gold {
147-
grid-template-columns: 1fr;
138+
display: flex;
139+
flex-wrap: wrap;
140+
gap: var(--space-md);
148141
}
149142
150-
.sponsors-grid--silver {
151-
grid-template-columns: 1fr;
152-
}
153-
154-
.sponsors-grid--bronze {
155-
grid-template-columns: 1fr;
156-
}
157-
158-
.sponsors-grid--community-partner {
159-
grid-template-columns: 1fr;
143+
.sponsors-grid > :global(*) {
144+
flex: 1 1 100%;
145+
min-width: 0;
160146
}
161147
162148
@media (min-width: 640px) {
163-
.sponsors-grid--platinum {
164-
grid-template-columns: repeat(2, 1fr);
165-
}
166-
167-
.sponsors-grid--gold {
168-
grid-template-columns: repeat(2, 1fr);
169-
}
170-
171-
.sponsors-grid--silver {
172-
grid-template-columns: repeat(2, 1fr);
173-
}
174-
175-
.sponsors-grid--bronze {
176-
grid-template-columns: repeat(2, 1fr);
177-
}
178-
179-
.sponsors-grid--community-partner {
180-
grid-template-columns: repeat(2, 1fr);
149+
.sponsors-grid > :global(*) {
150+
flex: 1 1 calc(50% - var(--space-md));
151+
max-width: calc(50% - var(--space-md) / 2);
181152
}
182153
}
183154
@@ -193,31 +164,30 @@
193164
.sponsors-content {
194165
padding: var(--space-xl);
195166
}
196-
197-
.tier-title {
198-
font-size: var(--text-xl);
199-
}
200167
}
201168
202169
@media (min-width: 1024px) {
203-
.sponsors-grid--platinum {
204-
grid-template-columns: repeat(3, 1fr);
205-
}
206-
207-
.sponsors-grid--gold {
208-
grid-template-columns: repeat(3, 1fr);
170+
.sponsors-content {
171+
display: flex;
172+
flex-wrap: wrap;
173+
gap: var(--space-lg);
174+
align-items: flex-start;
175+
justify-content: center;
176+
max-width: 1200px;
209177
}
210178
211-
.sponsors-grid--silver {
212-
grid-template-columns: repeat(3, 1fr);
179+
.tier-section {
180+
flex: 0 0 auto;
181+
margin-bottom: 0;
213182
}
214183
215-
.sponsors-grid--bronze {
216-
grid-template-columns: repeat(3, 1fr);
184+
.sponsors-grid {
185+
max-width: calc(320px * 3 + var(--space-md) * 2);
217186
}
218187
219-
.sponsors-grid--community-partner {
220-
grid-template-columns: repeat(3, 1fr);
188+
.sponsors-grid > :global(*) {
189+
flex: 0 0 280px;
190+
max-width: 320px;
221191
}
222192
}
223193
</style>

0 commit comments

Comments
 (0)