From 6e4862ffc6596f4fb354fbde7bf952ae6e074071 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Wed, 24 Jun 2026 08:38:42 -0400 Subject: [PATCH] Add video support --- .impeccable/briefs/reshape-sticky-rail.md | 157 ++++++++ .impeccable/design.json | 196 ++++++++++ .impeccable/live/config.json | 6 + DESIGN.md | 342 ++++++++++++++++++ PRODUCT.md | 97 +++++ package.json | 2 + pnpm-lock.yaml | 11 + src/components/EpisodeCta.tsx | 132 +++++++ src/components/EpisodeList.astro | 2 + src/components/FullPlayButton.tsx | 2 + src/components/MobileNav.tsx | 262 ++++++++++++++ src/components/Player.tsx | 200 ++++++++-- src/components/player/ForwardButton/index.tsx | 2 +- src/components/player/PlayButton.tsx | 2 +- src/components/player/PlaybackRateButton.tsx | 2 +- src/components/player/RewindButton/index.tsx | 2 +- src/components/player/Slider/index.tsx | 2 +- src/components/state.ts | 13 +- src/layouts/Layout.astro | 74 +++- src/lib/cta.ts | 30 ++ src/lib/navLinks.ts | 20 + src/lib/rss.ts | 72 +++- src/pages/[episode].astro | 103 ++++-- src/styles/global.css | 58 +++ src/utils/config.ts | 16 + tests/unit/Player.test.tsx | 68 +++- 26 files changed, 1802 insertions(+), 71 deletions(-) create mode 100644 .impeccable/briefs/reshape-sticky-rail.md create mode 100644 .impeccable/design.json create mode 100644 .impeccable/live/config.json create mode 100644 DESIGN.md create mode 100644 PRODUCT.md create mode 100644 src/components/EpisodeCta.tsx create mode 100644 src/components/MobileNav.tsx create mode 100644 src/lib/cta.ts create mode 100644 src/lib/navLinks.ts diff --git a/.impeccable/briefs/reshape-sticky-rail.md b/.impeccable/briefs/reshape-sticky-rail.md new file mode 100644 index 00000000..01e2ba05 --- /dev/null +++ b/.impeccable/briefs/reshape-sticky-rail.md @@ -0,0 +1,157 @@ +# Design Brief — Starpod Reshape: "Sticky Rail + Mobile App-Bar" + +> Status: awaiting confirmation. Scope: full-site restructure. Register: brand. +> Anchors: PRODUCT.md ("The Quiet Stage"), DESIGN.md (OKLCH, Iris/Aqua rationed, +> Inter, tonal-first, refined-but-playful). Selected from a 4-direction +> multi-agent comparison (this direction ranked #1, 7.3 avg). + +## 1. Feature Summary + +A full-site restructure of the Starpod podcast template that keeps the brand, +OKLCH tokens, and component vocabulary intact but reworks layout and navigation +so that: (a) video is co-equal with audio with native controls in an intentional +spot, (b) mobile navigation is reachable without scrolling past episodes, (c) a +configurable CTA is a first-class affordance, and (d) episode artwork appears on +the episode page. It serves both first-time visitors (find + play in seconds, on +any device) and the podcasters who adopt the template (clean, adaptable defaults). + +## 2. Primary User Action + +**Start an episode — listening or watching — within seconds, from any device, +without hunting.** Navigation, subscribing (CTA), and search are always one tap +away; they support that action, never compete with it. + +## 3. Design Direction + +- **Color strategy:** Restrained (project default). One rationed accent — Iris + (light) / Aqua (dark) — appears only on interaction and on the single CTA pill. + The show's artwork stays the most saturated element ("Artwork-Is-Loudest"). +- **Scene sentence:** A listener on their phone, half-distracted on a couch or + commute, glancing at a podcast someone just shared — they should see what the + show is, hit play, and optionally watch, without thinking. (Forces: calm, + content-first, dark-mode co-equal, zero-friction.) +- **Anchor references:** the current whiskey.fm rail identity (preserve its + artwork-forward calm); Apple Podcasts / Pocket Casts (familiar, native media + affordances); a frosted sticky mobile app-bar as in well-built reading apps + (always-reachable chrome). Not a reference: SaaS marketing landing pages. +- **Winning direction vs others:** chosen over Featured-Hero (its hero risks the + rejected SaaS-landing pattern and demotes identity), Top Bar + Stage and + Watch/Listen Dual Shell (both retire the always-on artwork rail and bet on + unproven cross-island video relocation). This direction refines rather than + reimagines, so it preserves brand presence and minimizes regression risk. + +## 4. Scope + +- **Fidelity:** production-ready (explore → then build). +- **Breadth:** whole surface — shell/nav (desktop rail + mobile app-bar), home, + episode page, and the persistent player. +- **Interactivity:** shipped-quality components (focus-trapped slide-over, native + video theater, expandable dock). +- **Time intent:** polish until it ships. + +## 5. Layout Strategy + +**Desktop** — preserve the two-column composition, but promote the left rail from +a passive identity panel to a **sticky navigation spine** with a deliberate +vertical order: + +1. Sticky utility row (never scrolls away inside the rail): search trigger + + configurable CTA pill. +2. Show artwork (Atropos tilt retained) — loudest element. +3. Show title + blurb. +4. Listen platform links. +5. Primary nav links (About / Contact / Store / Sponsor) — promoted out of the + buried footer. +6. Hosts. + +The right content well is unchanged in spirit (gradient + Dots wash, episode list +on home, episode body on detail). **Nothing moves to a footer anymore** — that's +the core structural fix. The CTA pill is the one persistent accented element in +the chrome (justified: a single rationed action, not a fill). + +**Mobile** — the rail does not collapse into a footer. It becomes a **compact +frosted sticky top app-bar** (uses the sanctioned player-bar blur), always visible +at first paint and pinned on scroll: `[artwork chip + show title] [search] [CTA] [≡]`. +The `≡` opens a right-side **slide-over** containing the full rail content (larger +artwork, blurb, Listen links, nav links, Hosts) in the same vertical order as +desktop. An optional compact identity strip (artwork + title + blurb) shows once +at the top of the content for first-paint context, then the episode list, then the +full-width docked player. + +## 6. Key States + +- **Home / default:** rail or app-bar + "Latest Episodes" list. +- **Episode page:** breadcrumbs → episode artwork block → date → H1 → description → + (video episodes) inline theater OR (audio) FullPlayButton → guests → sponsors → + show notes → transcript. +- **Audio-only episode:** episode art renders as a tilt-enabled cover; no video + theater, **no audio/video toggle shown** (omit, don't disable — a greyed tab + reads as broken). +- **Video episode:** episode art is the **poster**; on play it becomes the inline + 16:9 native-controls theater. +- **Empty (no episodes):** existing UFO illustration empty state, preserved. +- **Mobile menu open:** focus-trapped, scrim-backed slide-over; Escape + scrim + dismiss; focus restored to `≡` on close. +- **Player expanded (video):** centered aspect-correct theater pinned above the + player bar (replaces the crude `w-44` box). +- **CTA unconfigured:** falls back to "Subscribe" → primary platform link / RSS. +- **Reduced motion:** slide-over opens instantly; artwork tilt and any reveal + motion fall back to fade/none. + +## 7. Interaction Model + +- **Video (co-equal, native):** use native HTML5 `controls` on the `