--- status: approved --- # 002 — The voyage app (v1) Status: approved by user 2026-10-30 (direction approval; the user's standing rule: carry an approved design through spec → plan → execution without review stops). Design record: `docs/design/002-voyage-app.md`. Content source: `docs/specs/003-content-mount.md`. ## Intent Turn the approved mockup direction (17) into the real site at `/`: the whole album (9 sagas, 40 songs) as a stylised 3D sea voyage with the frieze as the curtain call between scenes, three landing sublevels, a persistent side panel, and a bottom timeline of motif threads, using the real audio, synced lyrics and the Odyssey text from the mounted content folder. ## Goals 1. **Routes.** The app is served at `/`. The mockup gallery moves to `/mockups/` (mockups stay at `/mockups/NN-slug/`). Every page keeps the fan notice and credit. 2. **Data for the whole album.** `src/data/` describes 9 sagas and 40 songs in album order (titles and track numbers as in the content folder) with: story time (years after Troy + a label), the Odyssey reference as a **book number and passage keywords** (Butler's prose has no line numbers), singers, motifs per song (and per part where known), facts, and video links. A curated motif set (musical motifs and character themes) with stable colours. Anything not certain is marked `// TODO(verify)`. Fan works: a typed, credited list (title, creator, type, URL, licence/permission note), **empty in v1** — no invented works. 3. **The voyage.** One 3D world: a route past nine places (Troy, the Cyclops' island, the open sea/storm, Aeaea, the Underworld, Scylla/the thunder sea, Olympus/the wisdom sea, Charybdis/vengeance, Ithaca). Each song is a stop on the route; selecting a song sails the ship there. Stylised per the design record. 4. **Curtain call.** Entering a saga (from the previous saga or by jumping) drops that saga's frieze band (black-figure on terracotta, the saga's name and its song titles as inscriptions), which then lifts into the sea with the horizon on the frieze's ground line. Within a saga, songs change without the curtain. Jumps across several sagas fade through the curtain colour. 5. **Three landings.** Cyclops' cave, the God Games arena (Athena), Ithaca's hall. Each is entered from its saga's frieze ("Go ashore") or automatically when its song is chosen (Survive; God Games; the Ithaca songs from The Challenge on — exact song→landing mapping in the plan), and left with "Back to sea". 6. **Side panel** with About, Listen & lyrics (player + synced lyrics + Watch), Paths (motif detail + strip when the timeline is hidden + chart of the nine places), Fan works (list or empty state). Collapsible; header play button. 7. **Bottom timeline** for 40 songs: all sagas visible as groups; the current saga expanded with titles, other sagas compact; you-are-here; motif threads for the current song's motifs across the whole album. Hideable (strip moves into Paths). "Threads on the sea" toggle. 8. **Navigation and state.** Previous/next song (buttons, ←/→), click any stop, Play voyage (steps through songs, silent), deep links (`?song=`, `?tab=`, `?motif=`, `?timeline=`, `?ribbons=`), browser back/forward restore state. Esc closes the reading view / leaves a landing. 9. **Robustness.** Works without the content folder (no audio/lyrics, a clear note). Works without WebGL (the frieze and panel still navigate; a note explains). Respects `prefers-reduced-motion` (crossfades). Keyboard reachable with visible focus. Desktop first (1280–1920 wide); below 900px the panel becomes a bottom sheet and the timeline compact — usable, not polished. ## Non-goals (v1) - Bespoke frieze art for every song; per-saga friezes may reuse a shared figure kit. - Time-aligning parts and motifs to the recordings (needs a content mapping file; see 17's report). - Collecting real fan works; mobile polish; i18n; removing the mockups. ## Acceptance criteria - `bun test` covers: the dataset (40 songs matching the content folder's titles and order, every motif used and defined, story times non-decreasing in album order, every song in exactly one saga), the route/stop geometry (one stop per song, ordered along the route), URL state round-trip, timeline layout (40 stops, no title overlaps in the expanded saga), and the `/` and `/mockups/` routes. - With the content folder mounted, at 1440×900: every saga's frieze, each landing, the panel tabs, playback with synced lyrics, and the timeline/ribbons render correctly in headless screenshots that were looked at; without it, the fallback renders. - `bun run typecheck`, `bun run build` pass; the preview container serves the app at `/`. - Docs: ARCHITECTURE, DECISIONS, DESIGN.md (the chosen direction as tokens and rules), AGENTS.md, TODO.