A responsive Shiraz Metro journey planner for Lines 1 and 2, built with semantic HTML, modern CSS, vanilla JavaScript, and an interactive Leaflet city map. The interface supports persistent English and Persian modes, complete RTL layout mirroring, and Persian numerals.
- Bilingual interface — persistent English/Persian switching, RTL support, Persian numerals, and Vazirmatn/Sahel typography.
- Line-aware hero — network summary, current line status, and route preview.
- Journey planner — metro line, origin, destination, device time, and an automatically selected calendar-based service type.
- Nearby stations — browser geolocation or a station-reference fallback, Haversine distance, walking estimates, and shortcuts to choose a starting station or show it on the map.
- Interactive city map — draggable OpenStreetMap geography, retina tiles, pinch/scroll zoom, SVG Line 1 and Line 2 overlays, selectable markers, bilingual station details, and route shortcuts.
- Journey result — selectable upcoming departures, estimated arrival, duration, route stops, and a countdown tied to the selected train. Departure selections survive language changes and device clock refreshes.
- From–To matrix — travel-time and next-arrival modes for the selected line.
- Station directory — service windows, operational status, planned stations, and interchange notes.
- Readable timetable — English and Persian PDF downloads, with Markdown references in the repository.
- Responsive navigation, clear station placeholders, full-width station fields, and a 44px-minimum swap button with equal spacing above and below in both LTR and RTL layouts.
- Selecting or reversing a valid route automatically scrolls to the journey result, with smooth scrolling unless reduced motion is preferred.
- Light/dark mode reveals outward from the theme button using CSS View Transitions. Older browsers use an expanding veil, and reduced-motion users get an instant change. The saved theme is applied before first paint.
- Scroll-linked section reveals and a reading-progress indicator, visible keyboard focus, active section links, styled native select controls, and support for pinch zoom.
- The map uses a locally vendored Leaflet runtime with high-density OpenStreetMap tiles, SVG transit geometry, Sahel controls and tooltips, keyboard-selectable station markers, and light/dark minimalist treatments.
- After a scheduled train departs, the journey card advances a live pulse toward each next stop. Line 1 uses two-minute station steps; Line 2 uses its published three-to-seven-minute station offsets.
- No application framework or build step. Playwright is a development-only dependency for browser regression checks.
- Full service across 20 stations.
- Working-day terminal departures:
- Shahid Dastgheyb → Ehsan: 06:10–22:10
- Ehsan → Shahid Dastgheyb: 06:05–22:05
- Weekend/holiday terminal departures:
- Shahid Dastgheyb → Ehsan: 07:10–21:10
- Ehsan → Shahid Dastgheyb: 07:05–21:05
- Scheduled interval: 15 minutes.
- Station offsets were reconstructed from the supplied 20-page timetable.
- Published operating section: Ghahremanan ↔ Imam Hossein, 5 stations.
- Operating station order: Ghahremanan → Shohada-ye Adelabad → Basij → Esteghlal → Imam Hossein.
- Working-day first departures:
- Ghahremanan → Imam Hossein: 06:00
- Imam Hossein → Ghahremanan: 06:20
- Scheduled interval: 40 minutes.
- Final terminal departures: 18:00 from Ghahremanan and 17:40 from Imam Hossein.
- Published end-to-end travel time: 16 minutes.
- Basij ↔ Esteghlal is supported in both directions as a 3-minute journey.
- No regular weekend/official-holiday service is published in the supplied timetable.
Line 1 is reconstructed from its supplied station timetable. Line 2 is reconstructed from the supplied 18-page working-day timetable, including its station-specific offsets and 40-minute departure sequence. Operational changes can still supersede these files, so station notices take precedence.
Station coordinates and map addresses were transcribed from Balad's Shiraz subway-station listings on 2026-09-22. They identify station points for proximity and map display; they do not represent live entrance accessibility or service status.
ShirazGo is an independent planning aid, not an official transit publication. Schedules can change without notice; confirm critical journeys using current station announcements or official operator channels.
Serve the folder so that local calendar JSON files can load:
python -m http.server 8080Then visit http://localhost:8080.
With Node.js 20 or newer:
npm ci
npx playwright install chromium
npm run check
npm testThe browser suite starts its own temporary local server. It checks the 24-station map dataset, Nearby ranking, styled selects, map markers, scroll progress, 40 viewport/language/line combinations from 320px to 1440px, swap-button geometry and behavior, route durations, matrix navigation, same-station validation, keyboard theme switching, reduced motion, circular reveals, fallback cleanup, preference persistence, and the Persian PDF download. To use an existing Chromium installation, set PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH to its executable.
index.html— semantic page structurestyles.css— responsive design system, Persian font stack, and RTL component rulesapp.js— multi-line timetable engine, bilingual content, localization, and interaction logicdata/shiraz-metro-stations.json— Balad-sourced station coordinates, addresses, line membership, and stable IDsassets/shiraz-subway-timetable.md— accessible timetable reference for Lines 1 and 2
Original site code and documentation are available under the
MIT License. Official timetable PDFs, transit data, operator names
and marks, and third-party fonts are not relicensed. See
THIRD_PARTY_NOTICES.md.