You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Epic #126 — Festival phases. PRD: docs/prd/festival-phases/2-live-phase.md.
What to build
When the edition is Live (useFestivalPhase() === "live", from #136), adapt the experience for someone standing in the field: they want what's on now and next, not a voting list. Live is an emphasis shift, not a different app — voting stays fully available and nothing from Planning is removed.
New pure now/next classifier — (sets, now) → classification (now-playing / next / later-past), festival-tz, now injected. Mirrors the pure/injectable shape of getFestivalPhase. Reuses set timing already loaded for the Schedule and the timeUtils festival-tz helpers.
now-playing: time_start <= now < time_end (exactly at time_end ⇒ no longer now-playing).
next: the nearest upcoming set(s) after now; ties and multi-stage concurrency handled deterministically.
Schedule-tab "Now / Next" section — when Live, lead with a section built from the classifier, above the existing full views (Timeline/List, or Multi-mode Schedule tab UX for days/stages reveal levels #47's progressive views below full). Now-playing marked as current; the next block shows immediately upcoming sets. Reuse the existing masked set row (MobileSetCard/set-row) so voting, set-detail links, and self-hiding stage/time badges come for free.
Compact Live banner — reuse the shared phase-banner component with Live copy ("the festival is on"). One line.
Sub-full reveal fallback — "Now / Next" needs time_start/time_end (only present at reveal level full). If Live is reached below full, skip the Now/Next section and show whatever the reveal level renders plus the Live banner. Never fabricate or leak hidden times.
No live ticker — computed per render/navigation; no background timer.
Acceptance criteria
When the edition is Live, the app lands on the Schedule tab by default.
The now/next classifier marks a set now-playing for now in [time_start, time_end) and not at exactly time_end; selects nearest upcoming set(s) as "next"; handles ties / multi-stage concurrency deterministically; excludes missing/masked-time sets without error.
Classifier is a standalone pure function unit-tested with now injected in a non-UTC festival timezone (incl. a viewer-vs-festival calendar-day mismatch); no clock/DOM/React mocking.
The Schedule tab, when Live, leads with a Now / Next section above the full schedule, using the shared masked set row; the full schedule remains reachable.
Compact Live banner shown, reusing the shared phase-banner component.
Below reveal level full, the Now/Next section is skipped gracefully (banner still shown, no leaked times).
Parent
Epic #126 — Festival phases. PRD:
docs/prd/festival-phases/2-live-phase.md.What to build
When the edition is Live (
useFestivalPhase() === "live", from #136), adapt the experience for someone standing in the field: they want what's on now and next, not a voting list. Live is an emphasis shift, not a different app — voting stays fully available and nothing from Planning is removed.(sets, now) → classification(now-playing / next / later-past), festival-tz,nowinjected. Mirrors the pure/injectable shape ofgetFestivalPhase. Reuses set timing already loaded for the Schedule and thetimeUtilsfestival-tz helpers.time_start <= now < time_end(exactly attime_end⇒ no longer now-playing).now; ties and multi-stage concurrency handled deterministically.full). Now-playing marked as current; the next block shows immediately upcoming sets. Reuse the existing masked set row (MobileSetCard/set-row) so voting, set-detail links, and self-hiding stage/time badges come for free.fullreveal fallback — "Now / Next" needstime_start/time_end(only present at reveal levelfull). If Live is reached belowfull, skip the Now/Next section and show whatever the reveal level renders plus the Live banner. Never fabricate or leak hidden times.Acceptance criteria
nowin[time_start, time_end)and not at exactlytime_end; selects nearest upcoming set(s) as "next"; handles ties / multi-stage concurrency deterministically; excludes missing/masked-time sets without error.nowinjected in a non-UTC festival timezone (incl. a viewer-vs-festival calendar-day mismatch); no clock/DOM/React mocking.full, the Now/Next section is skipped gracefully (banner still shown, no leaked times).Blocked by