// Wander — Tour detail screen function DetailScreen({ tourId, onBack, onStart, onPaywall, dense }) { const { TOURS, stopsForTour } = window.WANDER_DATA; const tour = TOURS.find(t => t.id===tourId) || TOURS[0]; const STOPS = stopsForTour(tour.id); const isPro = tour.tier==='pro'; return (
{tour.formats.map(f => ( {formatIcon(f,12,'var(--w-slate)')} {f.toUpperCase()} ))}

{tour.title}

{tour.subtitle}
· By Local Storytellers

{tour.blurb}

👩‍🎨
Narrated by Mei Ling Ho
Singapore-based historian · 23 tours
{/* Audio player preview if narration is uploaded */} {tour.audio_url && (
Audio preview
)}
Stops on this walk
{STOPS.map((s,i) => (
{i+1}
{s.name}
{s.dist} · {s.duration}
{s.blurb &&
{s.blurb}
}
))}
{isPro && (
Pro tour includes
The full story, not the postcard.
    {['Narration by a local historian','Hidden side-stops only locals know','AR overlays at key landmarks','Offline download for the whole route'].map(t => (
  • {t}
  • ))}
)}
{isPro ? : }
); } function Stat({ label, value }) { return (
{value}
{label}
); } // Download-for-offline control. Caches the app + this tour over Wi-Fi so it // plays with no signal on-site. Narration is on-device, so downloads are tiny. function OfflineDownloadCard({ tour }) { const off = window.WanderOffline; const ok = off && off.supported(); const [state, setState] = React.useState(() => (ok && off.has(tour.id)) ? 'done' : 'idle'); const [pct, setPct] = React.useState(0); if (!ok) return null; const start = async () => { setState('downloading'); setPct(0); try { await off.download(tour.id, p => setPct(p)); setState('done'); } catch { setState('idle'); } }; const undo = async () => { await off.remove(tour.id); setState('idle'); setPct(0); }; const base = { marginTop:18, padding:14, borderRadius:18, display:'flex', alignItems:'center', gap:12 }; if (state === 'done') { return (
Available offline
Plays without signal on-site.
); } if (state === 'downloading') { return (
Downloading for offline…{Math.round(pct*100)}%
); } return ( ); } Object.assign(window, { DetailScreen });