- Replace native date inputs with always-open custom calendar; return
journeys show two months side-by-side with Airbnb-style range selection
- Add min-connection filter (30/40/50/60 min) for the inbound leg of
return journeys, separate from the outbound connection filter
- Fix total journey time: naive datetime subtraction across CET/BST was
1 h too long outbound and 1 h too short inbound
- Filter inbound circle line suggestions when connection ≥ 40 min: only
show services arriving ≥ 5 min before GWR departure at Paddington
- Add Std / SP labels to Eurostar fare lines so users can distinguish
Standard from Standard Premier
- Row selection with a fixed summary bar showing NR + Eurostar + circle
totals; selection is preserved in the URL
- Load walk-on fares sequentially, outbound section first
- Mobile: card-grid table layout, hide headcode/platform on small screens
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Disable the return date input until Return journey type is selected.
Clicking anywhere in the return date group auto-selects Return and
enables the field. The return date min is kept in sync with the
outbound date, bumping the value forward if it would otherwise fall
before the outbound date.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Redesign results table from 8 columns to 4 (National Rail, Transfer,
Eurostar, Total), making GWR and Eurostar legs consistent with each other
- Move CET label next to Paris arrival time; show duration · train number
on one line below
- Move "Too early" label into the National Rail column for unreachable rows
- Remove horizontal scrollbar (drop card-scroll / overflow-x: auto)
- Add DEFAULT_MIN_CONNECTION / DEFAULT_MAX_CONNECTION to config/default.py
(70 / 150 min); remove all hardcoded fallback values from app.py and
templates
- Redirect to clean URL when both connection params equal their defaults;
omit params from all generated links when at default values
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Support any station with direct trains to Paddington; station CRS code
is now part of the URL (/results/<crs>/<slug>/<date>)
- Load station list from data/direct_to_paddington.tsv; show dropdown on
index page; 404 for unknown station codes
- Fetch live GWR walk-on fares via api.gwr.com for all stations (SSS/SVS/SDS
with restrictions already applied per train); cache 30 days
- Scrape Paddington arrival platform numbers from RTT
- Show unreachable morning Eurostars (before first reachable service only)
- Circle line: show actual KX St Pancras arrival times (not check-in estimate)
and add a second backup service in the transfer column
- Widen page max-width to 1100px for longer station names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract repeated inline styles from templates into named CSS classes in
base.html: layout helpers, buttons, form groups, alert boxes, results table
rules, row highlight classes, typography utilities, and empty-state styles.
Remove the per-page <style> block from results.html.
Update README to reflect current destinations, GraphQL data source, Circle
Line timetable, configurable connection range, and GWR fare table.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Index page connection time dropdowns now iterate over valid_min_connections
and valid_max_connections passed from the view, so any change to the sets
in app.py is reflected automatically (also adds the missing 45 min option).
Add ⚠️ next to transfer times under 80 minutes in the results table;
store connection_minutes in each trip dict to support the comparison.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>