Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/app/App.module.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
.appRoot {
--app-track-padding-top: clamp(72px, 14svh, 121px);
--app-track-padding-bottom: clamp(16px, 3svh, var(--space-24));
--app-panel-height: calc(100svh - var(--app-track-padding-top) - var(--app-track-padding-bottom));
width: 100vw;
min-height: 100svh;
overflow: hidden;
Expand Down Expand Up @@ -36,7 +39,7 @@

.horizontalScroller {
width: 100vw;
height: 100vh;
height: 100svh;
overflow-x: auto;
overflow-y: hidden;
display: flex;
Expand All @@ -58,12 +61,15 @@
width: max-content;
height: 100%;
min-height: 100%;
padding: 121px var(--space-24) var(--space-24) var(--space-24);
padding: var(--app-track-padding-top) var(--space-24) var(--app-track-padding-bottom)
var(--space-24);
}

/* Ensure sections match the panel styling */
.horizontalScroller :global(.panel) {
width: calc(100vw - calc(var(--space-24) * 2));
height: var(--app-panel-height);
min-height: var(--app-panel-height);
flex-shrink: 0;
scroll-snap-align: center;
border-radius: var(--radius-card);
Expand Down
30 changes: 20 additions & 10 deletions src/app/components/EventCard.module.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.eventCard {
display: grid;
gap: var(--space-16);
gap: clamp(10px, 1.8svh, var(--space-16));
align-content: start;
width: 100%;
min-height: 0;
padding: 20px;
padding: clamp(16px, 2.4svh, 20px);
appearance: none;
border-radius: 28px;
border: 1px solid rgba(126, 225, 218, 0.28);
Expand Down Expand Up @@ -35,46 +35,46 @@

.cardHeader {
display: grid;
gap: var(--space-8);
gap: clamp(6px, 1svh, var(--space-8));
}

.cardTitle {
margin: 0;
color: var(--c-text-light);
font: 600 24px/1.06 var(--font-display);
font: 600 clamp(20px, 3svh, 24px) / 1.06 var(--font-display);
text-wrap: balance;
}

.cardDescription {
margin: 0;
color: rgba(249, 250, 250, 0.82);
font: 400 15px/1.35 var(--font-body);
font: 400 clamp(13px, 1.8svh, 15px) / 1.35 var(--font-body);
}

.metaList {
display: grid;
gap: var(--space-8);
gap: clamp(6px, 1svh, var(--space-8));
margin: 0;
}

.metaRow {
display: grid;
grid-template-columns: 58px minmax(0, 1fr);
gap: var(--space-16);
grid-template-columns: clamp(46px, 6svh, 58px) minmax(0, 1fr);
gap: clamp(10px, 1.6svh, var(--space-16));
align-items: start;
}

.metaRow dt {
color: rgba(249, 250, 250, 0.54);
font: 600 12px/1.2 var(--font-body);
font: 600 clamp(11px, 1.5svh, 12px) / 1.2 var(--font-body);
text-transform: uppercase;
letter-spacing: 0.08em;
}

.metaRow dd {
margin: 0;
color: var(--c-text-light);
font: 500 14px/1.3 var(--font-body);
font: 500 clamp(13px, 1.7svh, 14px) / 1.3 var(--font-body);
}

@media (max-width: 720px) {
Expand All @@ -86,3 +86,13 @@
font-size: 22px;
}
}

@media (max-height: 760px) {
.eventCard {
gap: 10px;
}

.metaRow {
grid-template-columns: 46px minmax(0, 1fr);
}
}
52 changes: 38 additions & 14 deletions src/app/components/EventRail.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
display: grid;
grid-template-rows: auto auto;
align-content: start;
gap: 14px;
gap: clamp(10px, 1.8svh, 14px);
overflow: hidden;
padding-bottom: 12px;
min-height: 390px;
min-height: clamp(280px, 48svh, 390px);
}

.groupHeader {
display: grid;
gap: 0;
padding-right: 64px;
padding-right: clamp(24px, 4vw, 64px);
}

.groupTitle {
margin: 0;
color: var(--c-text-light);
font: 600 28px/1 var(--font-display);
font: 600 clamp(24px, 3.8svh, 28px) / 1 var(--font-display);
text-transform: lowercase;
}

Expand All @@ -26,28 +26,28 @@
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center;
gap: var(--space-16);
padding-right: 64px;
padding-right: clamp(24px, 4vw, 64px);
}

.emptyState {
display: grid;
place-items: center;
min-height: 276px;
padding-right: 64px;
min-height: clamp(200px, 32svh, 276px);
padding-right: clamp(24px, 4vw, 64px);
color: rgba(249, 250, 250, 0.8);
font: 500 20px/1.4 var(--font-body);
font: 500 clamp(18px, 2.8svh, 20px) / 1.4 var(--font-body);
letter-spacing: 0.01em;
text-align: center;
}

.controlButton {
width: 48px;
height: 48px;
width: clamp(42px, 6.2svh, 48px);
height: clamp(42px, 6.2svh, 48px);
border: 1px solid rgba(249, 250, 250, 0.28);
border-radius: 999px;
background: rgba(255, 255, 255, 0.08);
color: var(--c-text-light);
font: 700 22px/1 var(--font-display);
font: 700 clamp(20px, 3svh, 22px) / 1 var(--font-display);
backdrop-filter: blur(var(--glass-blur-soft));
transition:
background 180ms var(--ease-premium),
Expand Down Expand Up @@ -75,7 +75,7 @@
--right-edge-fade: 72px;
display: grid;
grid-auto-flow: column;
grid-auto-columns: minmax(320px, 440px);
grid-auto-columns: clamp(260px, 32vw, 440px);
gap: var(--space-24);
overflow-x: auto;
overflow-y: visible;
Expand All @@ -85,6 +85,9 @@
scroll-behavior: smooth;
scrollbar-width: none;
align-items: stretch;
outline: none;
overscroll-behavior-x: contain;
touch-action: pan-x pinch-zoom;
mask-image: linear-gradient(
90deg,
transparent 0,
Expand All @@ -101,6 +104,10 @@
);
}

.carousel:focus-visible {
box-shadow: inset 0 0 0 1px rgba(249, 250, 250, 0.28);
}

.carousel[data-can-scroll-back='false'] {
--left-edge-fade: 0px;
}
Expand All @@ -113,8 +120,11 @@
display: none;
}

.carousel:global(.is-dragging) {
cursor: grabbing;
@supports (-webkit-touch-callout: none) {
.carousel {
mask-image: none;
-webkit-mask-image: none;
}
}

@media (max-width: 1200px) {
Expand Down Expand Up @@ -157,3 +167,17 @@
font-size: 18px;
}
}

@media (max-height: 760px) {
.groupHeader,
.railShell,
.emptyState {
padding-right: 24px;
}

.carousel {
--left-edge-fade: 36px;
--right-edge-fade: 36px;
grid-auto-columns: clamp(240px, 30vw, 360px);
}
}
35 changes: 35 additions & 0 deletions src/app/components/EventRail.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useEffect, useState, useRef } from 'react'
import type { KeyboardEvent } from 'react'
import type { AppEvent } from '@/app/data/events'
import { useSafariHorizontalRailFallback } from '@/shared/hooks/useSafariHorizontalRailFallback'
import { EventCard } from './EventCard'
import styles from './EventRail.module.css'

Expand All @@ -21,6 +23,8 @@ export function EventRail({ title, events, carouselLabel, onEventSelect }: Event
const [canScrollForward, setCanScrollForward] = useState(false)
const hasEvents = events.length > 0

useSafariHorizontalRailFallback(railRef)

useEffect(() => {
const rail = railRef.current
if (!rail) return
Expand Down Expand Up @@ -57,6 +61,34 @@ export function EventRail({ title, events, carouselLabel, onEventSelect }: Event
})
}

const onRailKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
if (event.key === 'ArrowRight') {
event.preventDefault()
scrollRail('forward')
return
}

if (event.key === 'ArrowLeft') {
event.preventDefault()
scrollRail('back')
return
}

if (event.key === 'Home') {
event.preventDefault()
railRef.current?.scrollTo({ left: 0, behavior: 'smooth' })
return
}

if (event.key === 'End') {
const rail = railRef.current
if (!rail) return

event.preventDefault()
rail.scrollTo({ left: rail.scrollWidth - rail.clientWidth, behavior: 'smooth' })
}
}

return (
<section className={styles.eventGroup} aria-labelledby={headingId}>
<div className={styles.groupHeader}>
Expand All @@ -81,9 +113,12 @@ export function EventRail({ title, events, carouselLabel, onEventSelect }: Event
ref={railRef}
className={styles.carousel}
data-reveal-scroller
data-native-horizontal-scroll
aria-label={carouselLabel}
tabIndex={0}
data-can-scroll-back={canScrollBack}
data-can-scroll-forward={canScrollForward}
onKeyDown={onRailKeyDown}
>
{events.map((event) => (
<EventCard key={getEventKey(event)} event={event} onSelect={onEventSelect} />
Expand Down
30 changes: 20 additions & 10 deletions src/app/components/OrgCard.module.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.orgCard {
display: grid;
gap: var(--space-16);
gap: clamp(10px, 1.8svh, var(--space-16));
align-content: start;
width: 100%;
min-height: 0;
padding: 20px;
padding: clamp(16px, 2.4svh, 20px);
appearance: none;
border-radius: 28px;
border: 1px solid rgba(126, 225, 218, 0.28);
Expand Down Expand Up @@ -35,46 +35,46 @@

.cardHeader {
display: grid;
gap: var(--space-8);
gap: clamp(6px, 1svh, var(--space-8));
}

.cardTitle {
margin: 0;
color: var(--c-text-light);
font: 600 24px/1.06 var(--font-display);
font: 600 clamp(20px, 3svh, 24px) / 1.06 var(--font-display);
text-wrap: balance;
}

.cardDescription {
margin: 0;
color: rgba(249, 250, 250, 0.82);
font: 400 15px/1.35 var(--font-body);
font: 400 clamp(13px, 1.8svh, 15px) / 1.35 var(--font-body);
}

.metaList {
display: grid;
gap: var(--space-8);
gap: clamp(6px, 1svh, var(--space-8));
margin: 0;
}

.metaRow {
display: grid;
grid-template-columns: 58px minmax(0, 1fr);
gap: var(--space-16);
grid-template-columns: clamp(46px, 6svh, 58px) minmax(0, 1fr);
gap: clamp(10px, 1.6svh, var(--space-16));
align-items: start;
}

.metaRow dt {
color: rgba(249, 250, 250, 0.54);
font: 600 12px/1.2 var(--font-body);
font: 600 clamp(11px, 1.5svh, 12px) / 1.2 var(--font-body);
text-transform: uppercase;
letter-spacing: 0.08em;
}

.metaRow dd {
margin: 0;
color: var(--c-text-light);
font: 500 14px/1.3 var(--font-body);
font: 500 clamp(13px, 1.7svh, 14px) / 1.3 var(--font-body);
}

@media (max-width: 720px) {
Expand All @@ -86,3 +86,13 @@
font-size: 22px;
}
}

@media (max-height: 760px) {
.orgCard {
gap: 10px;
}

.metaRow {
grid-template-columns: 46px minmax(0, 1fr);
}
}
Loading
Loading