TransitLens - GTFS Transit Data Explorer
Explore, visualize and analyze GTFS transit feeds
v2.162.23
v2.162.23 - Route colors that are too light (like pale yellow) no longer wash out their own text across route badges, chips, and the Transit Map Diagram; the account menu now shows a Basic label for accounts on the free plan.
v2.162.22 - Shapes: a shape's name label now shows at every zoom level, for every shape kind, unless you turn its label off individually.
v2.162.21 - Shapes: dragging or reshaping a rectangle or polygon no longer loses the change when a click lands right as the drag ends, which could leave the shape stuck unselectable at its new spot. Fill opacity can now be set all the way to 100%.
v2.162.20 - The privacy policy now notes that we keep a record of which paid features your account uses, to operate and improve paid plans.
v2.162.19 - Signed-in accounts now show your name and email in PostHog and Clarity instead of just an opaque id, so a support conversation can be traced back to a session more easily. The privacy policy has been updated to say so, and turning analytics off in Settings still prevents all of it.
v2.162.18 - Browse Public Feeds: typing in search and rotating the globe no longer stall while feeds load, a new search stays snappy on its very first use, the results list correctly shows Static feeds alongside Realtime ones without shifting out of alignment, and a feed's Realtime status now appears above its Detected Features list instead of being buried below a long, now collapsible, pill list.
v2.162.17 - Fix a route hover/click crash on empty route bounds, show a clear reload prompt when the Leaflet map library fails to load, and stop retrying GTFS-Realtime endpoints that reject an API key so the same failure isn't reported over and over.
v2.162.16 - The footer's legal link is easier to read and now labeled Terms & License; the Terms of Use clarify that purchasing TransitLens Pro or Team is a permitted, authorized use.
v2.162.15 - Country flags in the Public Feed Catalog no longer show a broken-image icon if the flag fails to load. The country name stays visible either way.
v2.162.14 - Frees up browser storage left behind by older versions of the feed cache. Every time the cache format changed, the previous copy stayed on your device without ever being read again. Those leftovers are now cleared once, in the background, and the cache you are actually using is left alone.
v2.162.13 - Refreshing the page no longer empties a loaded feed's timetable. A feed that came back after a refresh kept its routes and stops but lost its stop times, so the Stop Inspector departures board showed nothing and Service Quality had no scheduled times to compare against until the feed was imported again. One note: the first refresh after this update still starts from a clean cache, so a feed open at that moment needs importing once more.
v2.162.12 - Fixed the Trips table rendering its last eight columns under the wrong headings, so trip counts and origin/destination now line up with their titles. Shapes and Measure switch to the Map workspace when picked from the left rail. The "Routes Not Drawn on Map" note now fades after 30 seconds and leaves a short line in the activity log instead of staying until dismissed. Long dashes are gone from app text.
v2.162.11 - Removed long dashes from app text. Feed Health route findings, the health filter labels, transfer-type descriptions, import and error messages, and time or date ranges now read as plain sentences and plain hyphens.
v2.162.10 - The service alerts badge in the header now shows a notification bell icon instead of a warning emoji.
v2.162.9 - Fixed the Distance and Area measuring tools: clicking on a stop, route, or existing shape while measuring no longer opens that item instead of placing a measurement point.
v2.162.8 - Save/Load Project now correctly restores your Routes, Stops, Time, and Area filters, plus any routes or stops you'd hidden - previously only two of those settings actually made it back after reloading a saved project.
v2.162.7 - Feed names during import (loading card, activity log, and completion summary) no longer show a raw catalog ID or URL slug like "mdb-437-202609040002" when a real agency name is available, and now switch to it as soon as agency data parses instead of waiting for the whole feed to finish.
v2.162.6 - Measure now opens with the Distance ruler already armed instead of an empty picker. Kept measurements can be selected and moved without opening Shapes mode, and reshaping one now keeps its length in sync in the Shapes list too.
v2.162.5 - The "Routes Not Drawn on Map" note no longer appears on top of the Inspector. It waits until you close the Inspector, since it is pointing at the map the panel is covering.
v2.162.4 - Mobile: measuring and adding shapes now respond to a tap. A finger that shifts a few pixels was being read as a map pan, so the tap never arrived. Shapes also moves to the bottom bar with Insights taking its place under More, and the Shapes icon matches the one in the app.
v2.162.3 - Shapes: the empty panel now names every format you can import, not just the two it listed before shapefile, GeoPackage and KMZ were added.
v2.162.2 - Shapes: a shape's edit handles now travel with it as you drag, so the circle radius line and vertex points no longer stay behind at the old spot until you let go.
v2.162.1 - Shapes fixes: a shape's label now travels with it as you drag or reshape it instead of staying where the shape started, and hovering an option in the add dial no longer turns that wedge transparent so the map showed through it.
v2.162.0 - Shapes (formerly Draw): undo and redo now cover every edit including moves, reshapes and restyles; each shape has its own map label switch; and shapes import and export as Shapefile, GeoPackage and KMZ alongside GeoJSON and KML. Also a rebuilt export panel, thin lines and circles that are far easier to click, and measurements that no longer become shapes without telling you.
v2.161.0 - Removed the in-app Support panel, its nav rail button, and the Pro launch waitlist signup, ahead of Account and Pro subscriptions launching.
v2.160.5 - Fixed the browser tab freezing for several seconds after a refresh while your feeds reloaded from cache - the map now stays responsive throughout.
v2.160.4 - The sign-in dialog now marks whichever sign-in method you used last on this device with a small "Used last" pill, so returning users can spot their usual option at a glance.
v2.160.3 - Fixed the Terms of Use and Privacy Policy links in the sign-in dialog opening behind the dialog itself. The sign-in dialog now offers Google, Microsoft and email as three matching "Continue with" buttons, with Google and Microsoft carrying their own brand icons.
v2.160.2 - The table toolbar buttons are bigger on phones, so Columns and Density are easier to tap.
v2.160.1 - Fixed several mobile layout bugs on phones: the Tables toolbar's search box overlapping its filters, the floating back-to-map button hiding part of the Tables and Calendar headers, Calendar's Export PDF and Print buttons being completely hidden and untappable, Timeline's day navigation splitting across two lines, and Timeline sometimes showing "No timeline data" after a feed finished loading until something unrelated triggered a refresh.
v2.160.0 - Product analytics now records when you open the inspector for a stop or a route, so we can tell how much of the map people actually work with. It is sampled rather than counted click by click: only the first, fifth and twenty-fifth of each kind, and the record never includes which stop or route you looked at. The privacy policy has been updated to say so, and turning analytics off in Settings still prevents all of it.
v2.159.0 - Import from URL now tells you straight away when a link looks wrong, instead of after the download. Paste a GTFS Realtime endpoint and it points you to the Realtime data field further down the same window; paste a web page and it asks for the .zip download link instead. Both are advice rather than a block, so you can still press Import if you know the link is good.
v2.158.0 - Refreshing the page no longer re-downloads and re-parses the feed you already had open. TransitLens now keeps the parsed feed for the tab you are working in, so a reload brings it straight back instead of importing it again. Opening a new tab, or coming back another day, still starts with a clean workspace, and a feed you removed stays removed after a refresh.
v2.157.0 - If a new version of TransitLens shipped while your tab was open, an import started in that tab would fail and the file had to be picked all over again. The import is now saved when this happens, and the loading card offers a "Reload and finish import" button that reloads onto the new version and completes the import on its own. Nothing resumes unless you press that button.
v2.155.2 - Fixed a case where a failed GTFS import (a very large feed timing out, or the parser crashing) could leave a half-loaded feed behind - it showed up in the sidebar and map with real route and stop counts but no shapes, calendar, or schedule data, right next to the "import failed" message. A failed import is now cleaned up automatically so nothing partial is left showing.
v2.155.1 - The Light Gray, Voyager and Dark Map backgrounds were drawing with an "API KEY REQUIRED" stamp across every tile. CARTO, who provide those three maps, began requiring a key for them, and tiles requested without one now arrive with that notice printed into the image itself. TransitLens sends a key with every request to them, so the three maps draw cleanly again at all zoom levels and in every label mode. The other four backgrounds were never affected.
v2.155.0 - TransitLens now asks before it uses analytics. On a first visit a notice explains what analytics and cookies are for and offers Accept or Decline, and nothing is loaded or sent until you choose. Settings gained a Product analytics switch so the choice can be changed at any time, which previously required editing browser storage by hand. Declining is remembered, and the question is put again after two weeks; switching analytics off in Settings is permanent until you change it back.
v2.153.8 - The privacy policy now describes the analytics the hosted app actually uses. PostHog, Microsoft Clarity session replay and Cloudflare Web Analytics are each named, along with what they collect, how long recordings are kept, where the data is processed, which cookies are set, and how to switch analytics off. The policy had said that no third-party analytics or tracking cookies were in use, which stopped being true when analytics were introduced in v2.75.1. The Terms, Notices and README were corrected to match, and the legal pages now render inline code and code blocks properly on phones as well as desktop.
v2.153.6 - Two Insights fixes. Opening a map analysis - Service Intensity Map, and the coverage and corridor overlays - while a route was open in the Inspector produced a result quietly restricted to that one route, because the Inspector's focus mode hides every other route and suspends these overlays outright; sometimes nothing appeared at all. Opening any of them now closes the Inspector first, so the analysis always covers the whole network. Separately, opening a second Insights surface while the Service Rhythm or Service Quality report was on screen appeared to do nothing: the new overlay, or the Transit Map Diagram, was switched on correctly but the previous report stayed layered over the top of it. Whichever report is open now steps aside as soon as another Insights surface is opened.
v2.153.5 - The live realtime summary now keeps all three of its columns on far narrower windows than before. Instead of the summary dropping the canceled count, and then the vehicle count, as the header ran out of room, the centred search field gives up width while the summary is actually on screen - untouched on wide displays where there is already room for both, never narrower than its own placeholder, and springing back to full size the moment realtime disconnects. Windows around 1520px and up now show the complete summary, where previously that took a 1800px display.
v2.153.4 - The live realtime summary in the header was presenting two different populations as though they shared one total: the vehicle count comes from the vehicle-positions feed, while the on-time share, late count and cancellations all come from the trip-updates feed. A reading like "140 live · 89% on time · 107 late" therefore looked self-contradictory when every figure was in fact correct. Each figure now sits beneath a caption naming exactly what it was measured against - "Vehicles live", "117 trips measured" - so a percentage can never be read against the wrong total, and clicking the LIVE badge opens a full breakdown with every number listed beside its own source, including how many trips were canceled out of how many updates. That breakdown is also what phones and tablets now show, where the header summary has never had room. The summary no longer paints over the search box on narrower windows, shedding a column at a time as space tightens, and the realtime status panel opens as a properly sized sheet on phones instead of stretching the full height of the screen.
v2.153.3 - Measurements in the map drawing tools now respect the "Distance & speed units" setting: the ruler was permanently metric no matter what Settings said, and it updates live when you change the setting mid-measurement. Keeping a measurement as a shape also keeps its reading visible on the map - distances and areas alike, previously the number disappeared the moment you kept it and only survived in the shape list. Kept readings are recomputed from the shape, so they stay correct after you reshape one and follow the unit setting afterwards. Also fixes labels being left behind on the map when several shapes were deleted at once.
v2.153.2 - The Timeline had two places showing what you had filtered: a plain value beside the title for the route or stop you were focused on, and the blue chips next to the search box for everything else. With a route named "1" and a search for "1" those looked like the same filter shown twice. The route or stop focus is now the first blue chip in that same row, labelled by what it is - "Route · 1", "Stop · Beaujoire" - so every active filter reads the same way, clears the same way, and lives in one place.
v2.153.1 - The map drawing tools moved to the top-left of the map, alongside the zoom controls, and now unfold on hover as well as on click, so reaching a tool no longer costs a click. Their launcher is a pen-tool icon rather than a pencil, which reads as drawing shapes rather than writing text. Once you pick a tool the rail stays put until you close it, so it can never disappear mid-drawing, and on phones it is unchanged.
v2.153.0 - Service Quality polish pass. The Trends charts finally carry a legend - the session trend, deviation histogram, and hour-of-day heatmap now each explain their own colors and shading, and the histogram's tint follows your actual punctuality thresholds instead of a hardcoded mapping that could silently disagree with them. The ⓘ methodology popovers open on hover as well as click, and no longer clip their last line. The toolbar's Presets, Goals, and Thresholds buttons now show their own live state - the applied preset's name, a goal count, and a "Custom" badge whenever thresholds aren't the defaults, since custom thresholds silently reclassify every number in the report. Presets lists saved views with a two-step delete instead of an unconfirmed ✕; Goals became a scorecard showing each target against the current session instead of a blind form; Thresholds gained a live band preview that redraws as you type. Long route names in the filter row now ellipsize cleanly instead of colliding with the dropdown arrow. And the Connect… button in the Layers panel - invisible in dark mode because it never set its own text color - is visible again.
v2.152.0 - Weekly Service Rhythm redesign. The report now opens as a set of layered cards over the app's grid-and-wave backdrop: the chart sits in its own panel with a soft accent glow, weekday bars carry the app accent while weekends are violet so the shape of the week reads at a glance, and the summary tiles became a responsive stat grid. Bars are slimmer, the weekday/weekend guides underneath now line up exactly with their bars at every window size, and the whole thing is polished equally in light and dark mode. Compare is no longer easy to miss - it moved to the left of the controls as a proper labelled switch with a caption explaining what it does. Picking what to compare is clearer too: transport types are now chosen inside the Compare panel instead of sending you to a different control, both pickers show how many of the four slots you have used, and once you reach the limit the remaining options visibly lock rather than silently refusing the click. Route rows are larger, show the route number and name separately, highlight when picked, and searching that matches nothing now says so. The scope buttons were restyled to match the other filter groups.
v2.151.0 - Share any view as a link. The address bar now keeps describing what you are looking at instead of clearing itself once a feed loads, so any view can finally be bookmarked, and one link can carry several feeds at once. A new Share button in the left nav rail - in the header on phones - opens a dialog where you choose exactly what the link includes: which feeds, plus the map position and the current filter state, with the link rebuilding live as you toggle and a one-tap Copy. Links stay legible rather than a wall of percent-encoding. Opening a shared link restores the sender's map position and filters, and when a link carries more feeds than your plan keeps loaded at once, the first ones load and the remainder are listed instead of interrupting you. A link whose feed URL has gone offline now says so plainly and offers the public feed catalog rather than failing silently.
v2.150.2 - Fixed a map crash from rapid route switching on feeds with no route geometry, made stale-deployment refresh messaging consistent across lazy-loaded panels, and stopped live-vehicle count badges from flickering during pan/zoom.
v2.150.1 - Timeline now honors the Settings time format (12/24-hour) everywhere times appear - the time axis, "now" indicator, peak insight, tooltips, stop-time labels, and the trip card - and reformats instantly when the setting changes.
v2.150.0 - Timeline vehicle blocks: a new "Blocks" toggle in the Timeline toolbar reveals same-vehicle connectors between trips sharing a block_id - hidden by default, with hover/selection lighting up that vehicle's entire day (arrowheads show the direction of travel) while every other chain fades back. Trip bars now always carry their headsign label, gracefully clipped when the bar is too narrow for the full name. Browse Public Feeds now opens in well under a second (previously up to ~8s): the globe paints from lightweight country geometry first and silently streams in full coastline detail, its assets pre-load before the modal opens, and clicking a country directly on the globe - previously broken - selects it again. Feeds with linked realtime data show green markers on the globe, matching the results list's "Realtime" badge.
v2.149.3 - All-new TransitLens brand mark: a magnifier reading a "TL" monogram built from actual roadway, with theme-paired artwork - in dark mode the lens inverts into a night map, so the light roads stay legible against deep navy glass instead of vanishing. The top-bar title is now live text rather than a baked image, so the wordmark and its GTFS eyebrow stay crisp at any resolution and re-colour with the theme automatically. Favicons, the iOS home-screen icon, and the PWA install icons were regenerated from the new mark (lens-centred so the monogram survives 16px), and the marketing site's five product screenshots - which had never actually been committed and were rendering as broken images in production - are restored.
v2.149.2 - Live-map vehicles get all-new realistic top-down artwork: every transport mode now has its own photoreal sprite with a distinct baked-in livery colour - orange bus, crimson train, yellow taxi, navy metro, green tram, white-and-blue airplane, and more - so modes read apart at a glance, with per-type sizes tuned to real vehicle proportions.
v2.149.0 - Browse Public Feeds globe overhaul: the discovery globe is far faster and smoother to spin (feed markers now render as a single instanced field instead of thousands of separate meshes) and gets a refined flat-vector look - cleaner country shapes with hairline borders, crisp anti-aliased city and region labels that finally render accents correctly, flat marker dots with soft halos, and a single clean ring for the selected country. The globe sits on a deep slate stage in both themes so it reads as a glowing marble, idles with a slow auto-rotation until you interact, and has smoother rotation inertia, hover tooltips, and cursor feedback; labels stay sharp all the way to close zoom. The modal chrome is aligned to the app's glass design tokens, adds a slide-over feed inspector on tablet widths, and shows a livelier globe loading animation.
v2.148.0 - Map Drawing & Annotation Toolkit: a new on-map tool drawer to draw polygons, rectangles, circles, lines, arrows, markers, and text labels; a ruler and area-measure tool with live geodesic readouts; per-shape styling (fill and border color via an HSV picker, width, dash style, opacity, and fill patterns) with select, reshape, move, rename, and delete editing; a Shapes list to manage every annotation; unified KML/GeoJSON import (points, lines, and polygons with holes) and export back to GeoJSON or KML, plus PNG, JPEG, and PDF map-image export. Feed sharing moves from the left nav rail to a per-feed Share button in the Layers panel.
v2.147.1 - Live-vehicle polish: vehicles now animate at the real pace their reports imply (no more sprint-then-crawl), rail vehicles ride full station-to-station segments instead of teleporting after a stop, and the stopped indicator (white dot, hover "stopped", "Stopped at…" card) only shows once the vehicle visually arrives - a moving vehicle now reads "Arriving at…" with its speed, and a stopped one never shows a stale speed.
v2.147.0 - GTFS-Realtime goes live: attach vehicle-position, trip-update, and alert endpoints to a loaded feed to see live vehicles on the map - animated along their route shape at real reported speed, dwelling at stops, with a hover card (route, mode, speed, heading arrow) and a click card; the Route Inspector tracks the live vehicle through the stops list (passed/current stops, live early/late vs schedule, schedule-expected marker when running late) and polls faster while a route is inspected; stop popovers show live predicted times with the scheduled time struck through, keep late-running buses in the "next departure" slot, and add a destination hint to distinguish same-named opposite-curb stops. Also new: Transit Map Diagram - auto-generated schematic (octilinear) transit maps with per-route styling, smart legend, print themes, optional faded geography backdrop, 2D/3D views, and JPEG/PNG/PDF/print export. Plus fixes: the Route Inspector always opens on Overview; today's-service totals are correct on routes whose trips start from multiple origins; and the stops list, realtime legend, and live-vehicle map filter no longer flicker or stick after closing the inspector.
v2.146.5 - Search results now show each stop's real transport-mode icon (matching the map) instead of a generic pin; add a Direction A/B label to the stops tray; stop a spurious dashed line from appearing on shaped trips opened from the Trips table; make Routes table pattern rows open the Route Inspector; and fix route-direction switching on shapeless routes leaving the map on the previous direction's line and colour.
v2.146.4 - Fix stop order number badges appearing on the route line instead of next to the stop icon: badges now anchor to the stop icon's upper-right corner and stay clearly associated with the stop marker regardless of route direction.
v2.146.3 - Fix route shape line not matching the selected trip: when a trip is opened from the Service panel, the map now isolates both the stop markers and the rendered route shape to that trip's exact stop sequence, hiding the longer direction-level geometry.
v2.146.2 - Fix map stop markers not matching the Stops tray on feeds where patterns carry no tripIds (e.g. IDFM/Paris): map focus now uses the trip's stop_times directly instead of pattern metadata, guaranteeing the marker set matches the tray on any GTFS feed.
v2.146.1 - Fix map stop markers not matching the Stops tray when a trip is clicked in the Route Inspector's Service panel: the map now pins to the trip's exact pattern (same stop set as the tray) instead of showing the direction's longest-pattern stop set.
v2.146.0 - Routes table: clicking any cell in a direction sub-row (Route ID, Short Name, Long Name, Route Type, Direction, Agency) now opens the Route Inspector at the correct direction; expand/collapse toggle moved from Direction column to Short Name column. Trips table: "Route" column renamed to "Short Name"; Route ID and Long Name columns added flanking Short Name, matching the Routes table layout.
v2.145.5 - Fix route shape rendering the hue-shifted (direction-B) color instead of the base color when opening a trip with no GTFS direction_id from the Trips table - the undirected pattern bucket now keeps the base route color, matching the inspector badge, with no need to toggle direction. Also moves the Trips table's Direction / Pattern / Trip column to sit between Route and Type.
v2.145.4 - Fix route direction A map color showing teal instead of green when opening from the Trips table: four falsy direction_id=0 guards in the polyline direction-filter logic now use != null checks so direction 0 is no longer treated as "no direction set".
v2.145.3 - Fix stops tray sizing to content height (not always maximum), lock height during drag so it no longer stretches, close the tray automatically when navigating to a stop via "View in Inspector", and fix the dashed fallback polyline for shapeless routes covering all stops in direction A (was truncated due to a falsy direction_id=0 bug).
v2.145.2 - Route Inspector polish for multi-pattern, circular, and demand-responsive routes: trips opened from the Trips table now show the correct direction and color with exactly one polyline per direction, matching map/list stop counts, and full-coverage direction arrows; picking a pattern variant in the Structure tab now isolates the map and stop list to that variant; circular routes show a "Circular route" notice, a working Stops list, and a combined loop badge (e.g. "1 ↻ 4"); and a route's stops are colored by the inspected route's transport mode inside the inspector.
v2.145.1 - Fix Trips table → Route Inspector: direction color now correctly reflects the trip's direction on the map, and focus mode stop markers are filtered to only the stops served by that trip's pattern.
v2.145.0 - Trips table in the TABLE workspace: hierarchical Route → Direction → Pattern → Trip view with health indicators, sortable columns (start time, duration, stop count, headsign, service, shape, block), and one-click navigation into the Route Inspector with the selected trip's stops on the map. Moves Share to the left nav rail (desktop) and fixes the floating search button appearing over the activity bar during feed import.
v2.144.0 - Public holidays overlay for the Calendar: gold star markers on holiday dates, a collapsible country list panel with auto-detection from the loaded feed, a searchable country picker (135 countries via Nager.Date + OpenHolidaysAPI enrichment + Hebcal for Israel), user-selectable holiday types (Public / Bank / School / Optional / Observance), and holiday details in cell tooltips, Day view banners, and PDF/Print exports. Also surfaces bikes_allowed and cars_allowed per-route rollups in the Route Inspector Data tab for feeds that include these GTFS fields.
v2.143.1 - Fix GTFS import timeouts on large feeds: the worker now emits keep-alive progress pings every 10 s during ZIP extraction and index serialisation, and the silence watchdog is extended from 30 s to 90 s so 500 MB+ archives and 900 k-trip networks complete reliably.
v2.143.0 - Schematic Map Studio quality overhaul: exports become true posters - the network is measured exactly (lines, stations, and every label) and centered inside a safe-margin poster so nothing can clip; stations use one consistent symbol system (discs, interchange capsules, terminal caps); labels place by priority with automatic density control; the header shows a clean agency-derived title; and new Label density and Line thickness options round out the styling controls.
v2.142.1 - Service Intensity Map polish: the custom time window now uses the same iOS-style wheel picker as the Inspector and follows the 12h/24h Settings format, the legend reads more clearly, route overlap insight now lives only in the Overlap tab (no longer duplicated across other tabs), and the route-picker popup no longer shows a double scrollbar.
v2.142.0 - Service Intensity Map: the coverage heatmap becomes a map-native analysis tool - Corridors / Stops / Compare modes with per-mode metrics (trips/hour, unique routes, route overlap, service span), a time-window & day-type control, an analytical legend, hover insight cards, and a ranked Top Insights panel, all in floating controls on the map.
v2.141.2 - Direction labels are now consistently "Direction A / Direction B" everywhere - routes table, frequency period chips, frequency timeline tooltips, and stop headsign variants no longer show raw direction IDs (0/1).
v2.141.1 - Route Inspector fixes: selecting a stop from the stop list right after opening no longer makes the route line vanish from the map; and Stops Order is now available as soon as the inspector opens - it numbers the shown stop list and the matching stops on the map (works with the direction's stop sequence, not just a selected trip).
v2.141.0 - A shared transport-mode filter now sits in the Calendar header and drives every scope: toggle Bus / Rail / Metro (and more) to re-scope the Year and Month heatmaps to those modes and filter the Day view's route list - multi-select, with an "All" reset.
v2.140.0 - Redesigned the Calendar Day view: per-route service now shows as clean cards with a dual-direction colour badge, one labelled hourly sparkline per direction (hover any hour for the time of day and trip count), transport-mode filter chips, and a richer summary - service span with next-day (+1/−1) markers and a mode count - all in a single scrolling list.
v2.139.0 - Stop card: headsign details move to a new in-card "Headsigns info" view (reached via a signpost button beside View in Inspector, with a back button), decluttering the service rows; the hub/parent-station marker border is now crisp instead of glowing; and the header Share and theme-toggle buttons keep a solid background on hover.
v2.138.3 - Map polygon labels now declutter automatically: overlapping neighborhood/area labels are nudged apart or hidden based on polygon prominence (largest first) so they no longer stack, with hidden labels revealed as you zoom in.
v2.138.2 - Mobile fixes: stop card routes now sort by soonest departure time; opening Add/More sheet closes any open side panel; search button correctly appears on the Map workspace and hides on other workspaces.
v2.138.1 - Stop the spurious "Background Task Failed" error toast (and silent-error report) triggered by browser extensions that fire reason-less promise rejections; these non-actionable rejections are now logged to the console for developers instead of surfacing to users.
v2.138.0 - Stop & Timeline polish: a new "Showing Routes Active Now" pill appears on the map whenever the Routes "Active now" filter is on, with an ✕ to clear it; the Stop info card now lists multiple headsigns separated by "/" (no more "N variants" pill) and falls back to a trip's terminus when GTFS has no headsign, shown as a quiet flag instead of a red warning; imminent departures (≤60 min) read green and later ones near-black across the stop card and popover; the Timeline now opens on a representative in-coverage day when the feed has no service today (coverage ended/not yet started) instead of an empty view; and the Shift-drag "zoom faster" hint no longer shows on touch devices.
v2.137.4 - Map: direction-flow arrows now follow each direction's stop sequence (first stop → last stop) instead of raw shape point order, so switching Direction A/B in the Route Inspector correctly flips the arrows even when a feed's two directions share or mirror their shape geometry.
v2.137.3 - Browse Public Feeds: fixed the loading globe animation clipping against its frame (now spins centred and fully visible), and aligned the two empty-state blocks ("Explore Public Feeds" / "Select a feed") to identical type styling.
v2.137.2 - Map: hub/parent stations now read as a fuchsia border around the station's own icon - its transport-type icon when it serves a single mode, or the multimodal icon when it serves two or more - instead of a separate "Hub" glyph. Expanded platforms keep their plain transport-type icons. The same treatment carries through to the Stop Inspector header.
v2.137.1 - Timeline: frequency-based service (frequencies.txt) now draws as one clean service band per rule - an "every N min" chip with zoom-aware headway ticks - instead of stacked per-departure bars; zoom −/+ moved into the top bar beside the date picker (now horizontal); removed the "Inspect any trip" coachmark; and refined the frequency band tick styling.
v2.137.0 - TransitLens goes mobile: a full phone & tablet experience with a bottom tab bar, bottom-sheet panels, a swipeable workspace strip, and a Maps-style stop/route inspector you can peek, expand, or collapse while the map stays interactive. Share any URL/catalog feed as an open-in-TransitLens deep link via your device's native share sheet, and install TransitLens to your home screen (PWA). Also: map popups stay readable over dark basemaps and several dark-theme contrast fixes. Desktop is unchanged.
v2.135.0 - Stop Inspector: explore departures by route. A new "By route" / "By transport" view groups upcoming times per line and direction (with one-click trip open), the Overview shows each route's next departures at a glance, and multi-modal hubs keep their hub icon at every zoom. Also: map data attribution now credits all basemap providers in the Notices/Terms, the on-map attribution adapts to dark theme, and the Route Inspector's "Next" now reads as hours and minutes (e.g. "11h 38m") for long waits.
v2.134.0 - Base map: moved the map-style switcher out of the Layers panel onto the map itself - a floating control showing the current map that opens a premium flyout (grouped Day/Night, thumbnails, usage notes, label density). The map now follows your app theme automatically, your manual choice is remembered, and a "Reset to automatic" action returns to theme-matched defaults.
v2.133.0 - Layers: premium Basemap UX - preview thumbnails, productized Day/Night grouping, refined selected state with a smooth crossfade between maps, per-basemap label-density modes (Standard / Reduced / No labels where supported), and subtle overlay-contrast tuning for better route/stop readability across map styles.
v2.132.0 - Layers: expanded the Basemap selector into a grouped Light/Dark catalog (OpenStreetMap Standard, Light Gray, Voyager, Dark Map, High Contrast) with provider names and descriptions, app-theme-aware defaults, and a "Reset to theme default" action.
v2.131.2 - Layers: added a Basemap selector - choose between OpenStreetMap Standard (light) and a Dark Map; the choice is remembered and only swaps the background map, leaving all transit data untouched.
v2.131.1 - Settings: date format selector redesigned - shows DD/MM/YYYY and MM/DD/YYYY format patterns directly, ISO option removed.
v2.131.0 - Stop headsigns + inspector convergence: stop_times.stop_headsign is now parsed and surfaced as a route → destination "Service" block on the stop map card and the Stop Inspector Overview (replacing the duplicated routes/departures/headsigns lists), with proofing flags for stop-level overrides, conflicting variants, and missing headsigns; the Stop Inspector header shows a live "Next" tile and a transport-type-coloured mode chip, the Service board drops its duplicate KPI strip, and the Data tab is realigned to the Route Data record-row design.
v2.130.2 - Map: multimodal stations now have their own marker - a steel "transfer arrows" icon - distinct from the fuchsia parent-station Hub marker (both keep a colour pip per mode).
v2.130.1 - Map: hub and multi-modal stations now stay collapsed as a single Hub marker at all zoom levels and only fan out to their per-mode icons when clicked (no more auto-expanding into overlapping markers at close zoom).
v2.130.0 - Stop Inspector: opening a multi-modal stop from one of its mode markers now scopes the whole inspector to that single mode - icon, transport chip, routes-served and departures (Overview + Service) all show only the selected mode.
v2.129.15 - Stop Inspector Overview: the "Next departures" rows now show the transport-mode pip on the route badge, matching the Service tab.
v2.129.14 - Map: hubs and multi-modal stops now collapse to the dedicated fuchsia Hub marker with a colour dot per transport type served, and expand (spiderfy) to the individual per-mode icons. Popup, "View in Inspector", tooltip, hub detection and mode filtering all preserved.
v2.129.13 - Stop Inspector: hub stations now show a neutral "Hub" pill beside the station name.
v2.129.12 - Stop Inspector: hub stations now use a dedicated fuchsia "Hub" icon (central node + three station spokes) beside the name, instead of the primary-mode-plus-pips marker.
v2.129.11 - Stop Inspector: removed the feed name from the title area (it lives in the Data tab) and moved the transport-type chips to their own wrapping row beneath the stop name.
v2.129.10 - Stop Inspector: headline now reads "Stop Inspector"; the "Stop" chip is replaced with transport-type chips (one per mode served, coloured like the Table); hubs show the multi-mode map hub icon (primary + mode pips) beside the name.
v2.129.9 - Top bar: removed the dot mesh (squares) from the wave backdrop on the Table, Timeline and Calendar workspaces (wave only); Map keeps both.
v2.129.8 - Removed the wave backdrop from the Table, Timeline and Calendar workspace headers, restoring their plain backgrounds.
v2.129.7 - Table, Timeline and Calendar headers: dropped the dot mesh (wave only); the Calendar header wave now fills the full header width.
v2.129.6 - Table, Timeline and Calendar workspaces: added the hi-tech grid/dot mesh and accent wave backdrop to their header bars so they match the rest of the app chrome.
v2.129.5 - Stop Inspector: enlarged the stop's transport-mode icon to match the Route Inspector badge size (44px).
v2.129.4 - Stop Inspector: added the stop's transport-mode icon (exact same shape and colour as its map marker) to the left of the stop name and feed.
v2.129.3 - Inspector: wove the hi-tech grid/dot mesh and accent wave backdrop into the Route and Stop inspectors so they match the launchpad and app chrome.
v2.129.2 - Launchpad: shortened the fourth card title from "Geometric Layers GeoJSON / KML" to "Geometric Layers".
v2.129.1 - Launchpad: replaced the Geometric Layers GeoJSON / KML line-art icon with a polished 3D folded-map illustration, color-matched to the other cards (cobalt in light, emerald in dark). All four cards now use the 3D illustration set.
v2.129.0 - Settings: added a "Show launchpad on startup" toggle under a new Startup section. It stays in sync with the launchpad's own "Show this screen on future visits" checkbox - changing either updates the other and the saved preference.
v2.128.6 - Launchpad: replaced the Web Hosted GTFS ZIP Link line-art icon with a polished 3D browser-window illustration (blue in light, emerald in dark).
v2.128.5 - Launchpad: renamed the "Web Hosted GTFS ZIP File" card to "Web Hosted GTFS ZIP Link".
v2.128.4 - Launchpad: replaced the Local GTFS ZIP File line-art icon with a polished 3D ZIP-folder illustration (blue in light, emerald in dark).
v2.128.3 - Launchpad: the catalog globe now uses an emerald-toned variant in dark theme to match the accent, swapping back to blue in light theme.
v2.128.2 - Launchpad: replaced the Public GTFS Feed Catalog line-art globe with a polished 3D globe illustration (transparent PNG, optimized).
v2.128.1 - Side panel: raised the background wave so it sits behind the panel title.
v2.128.0 - Extended the launchpad's high-tech texture into the app chrome: a subtle grid + dot mesh now backs the top bar, the left nav rail (collapsed and expanded), and the side panel, with soft wave lines on the top bar and panel. Tiles at a fixed size so it never distorts as the rails animate; light and dark themes both supported.
v2.127.5 - Data Launchpad: softened the background waves behind the cards/body so they're less dominant, while keeping the header wave at full strength.
v2.127.4 - Data Launchpad card text (eyebrow, title, description) is now horizontally centered within each of the four action cards.
v2.127.3 - Data Launchpad background waves enriched: more transit-line waves across the panel, each rendered as a tapered body + bright core so its weight swells and thins along the line for a richer high-tech feel.
v2.127.2 - Data Launchpad readability: the background grid, dots, and wave now fade softly around the header title (content-aware clearing) instead of running through the text, and the four action cards are fully opaque so the backdrop no longer shows through them in dark mode.
v2.127.1 - Data Launchpad polish: moved the "Show this screen on future visits" preference to the right of the footer, and extended the high-tech grid + dot pattern and a wave line up into the header band so the background reads as intentional across the whole panel (light and dark).
v2.127.0 - Data Launchpad refined to four equal, standardized action cards (Public Catalog, Web-hosted ZIP, Local ZIP, GeoJSON / KML) with restored "Add data to begin" copy and a unified line-art illustration system. Stronger light-theme depth (bolder modal/card borders, shadows, saturated blue buttons), a high-tech grid + transit-line background now visible in light mode too, and a new "Show this screen on future visits" preference checkbox.
v2.126.0 - Data Launchpad redesigned from scratch as a professional, technical workspace launch screen: a primary GTFS ZIP dropzone hero with expected-schema chip preview, a clearly secondary URL / public-catalog row, and a de-emphasized GeoJSON / KML utility link. Adds glass surfaces, layered transit-line + grid background pattern, soft accent glow, monospace metadata chips and corner tick marks for a product-native, GTFS-tooling feel.
v2.125.8 - Fix frequency-based service rendering: the IndexedDB cache now persists `frequencies.txt` data (was stripping it on every reload), and the Timeline / Stop Departures board / Calendar metrics no longer surface template trips as ghost departures at the template's 00:00 anchor. Frequency-only routes get synthesized Timeline rows so bands render even when no scheduled trip exists for the date.
v2.125.7 - Scope the Inspector More-popover right-edge anchor to the Route Inspector only. The Stop Inspector's More button sits near the panel's left edge, where the leftward-extending menu clipped against the inspector's left boundary. Stop Inspector reverts to the original left-edge anchor (rightward extension).
v2.125.6 - Fix inspector "⋯ More" popover getting truncated at the right edge of narrow inspector panels: the overflow menu now anchors to the More button's right edge and extends leftward into the panel, so Timeline / Routes table / Stops table stay fully visible.
v2.125.5 - Stops Order toggle now also controls the ordinals in the stops list (in addition to the map badges). Label renamed from "Stop Order" to "Stops Order". Numbers are hidden until the toggle is enabled, and the ordinal column keeps a fixed width so stop names never shift left/right as the toggle flips.
v2.125.4 - Inspector primary toolbar: removed the small leading SVG glyphs from the Focus / Stops list / Stop Order buttons (and the Focus button on the Stop Inspector) so the labels read cleaner in the inspector header. Secondary toolbar icons (Stops table, Routes table, Timeline) are unchanged.
v2.125.3 - Stop Order: Route Inspector stop list now numbers each row by its derived position within the selected trip (1-based, not raw GTFS stop_sequence). Stop Inspector Overview gains a "Position in selected trip" card showing the ordinal plus previous/next stop names, with multi-occurrence support for trips that revisit the same stop. A new Stop Order toolbar toggle paints small numbered badges over the trip's stops on the map; enabled only when a trip is selected and Stops Display is not Hide.
v2.125.2 - Stop Inspector Overview: "Next departures" badges now use direction-aware route colors, so each row matches the chip color in "Routes served" and the polyline color on the map for the same route + direction.
v2.125.1 - Fix multi-mode stop popup & hover: when a stop is split into per-mode markers (e.g. a Bus icon and a Rail icon at the same station), the Bus marker's popup departures and hover tooltip now filter to the mode the icon represents instead of surfacing sibling-mode trains.
v2.125.0 - Inspector V2 is now live: native Stop and Route inspectors with redesigned Overview, Service, Structure, and Data tabs. Header chrome carries a silver type-glyph (bullseye for stops, A→B arc for routes) so the inspector type reads at a glance, the route badge keeps its V1-style mode-icon pip, and the Route Data tab consolidates source identity, GTFS route fields, coverage counts, and color/contrast diagnostics into a single compact field table.
v2.124.13 - Ignore browser-extension-injected errors (fuckAdBlock collisions between two ad-blocker extensions, chrome-extension:// / moz-extension:// stack frames, opaque cross-origin "Script error.") in the global error handler so users no longer see a "Something went wrong" toast for issues outside the app. Also fixes a Route Inspector edge case where the trip-list could read empty while the day's trip count was non-zero - when the representative stop's board returned no departures but the day index had trips for the active direction (e.g. Saturday variants whose first stop differs from the weekday rep stop), Today's service now synthesizes the trip list from the day's trip index so the count and the list always agree.
v2.124.12 - Fix routes-served chip colors at terminus hubs: when a stop is served by the same route in both directions (e.g. Estació Intermodal serves 101 toward both Palma and Port d'Andratx), the popup and Stop Inspector now render one chip per direction with the destination appended, so the chip colors match the corresponding departure rows instead of conflicting with them.
v2.124.11 - Route Inspector Frequency Service is now direction-aware: stats (Effective departures, Template trips, Frequency rules, headway range, service span, Exact / Estimated) and Period rows reflect only the direction the A/B toggle is on. Routes with frequency service in just one direction show a quiet empty state on the other side.
v2.124.10 - Stop Inspector Departures now include departures derived from frequencies.txt: NEXT, NEXT 60 MIN and TODAY counters merge headway-based events with scheduled trips, and rows show a subtle Freq · exact / Freq · est badge so riders can tell them apart.
v2.124.9 - Public Feed Catalog: horizontally align the two empty-state messages - "Explore Public Feeds" (left column) and "Select a feed" (right column) now sit at the same vertical position so the icons + titles line up across the modal. Previously the left empty state was offset down by the filter area above the results list.
v2.124.8 - Public Feed Catalog loader: fix root cause - globe.gl wipes its container's children on init, removing the placeholder regardless of our dismiss logic. Now mount globe.gl in a child div (#bfGlobeMount) so the placeholder lives as a sibling that globe.gl can't touch. Combined with the 4.5s minimum visible floor, the loader finally stays visible through the entire globe-load window.
v2.124.7 - Public Feed Catalog loader: enforce a minimum 4.5-second visible time after the modal opens, on top of the data-readiness gates. Previous attempts tried to detect "globe is painted" via Three.js scene polling, but globe.gl adds mesh objects to the scene synchronously before they actually render - so the polling kept dismissing early. The minimum-time floor guarantees the loader covers globe.gl's mesh-build window even on slower CPUs.
v2.124.6 - Public Feed Catalog loader: switch from a fixed timer to actually polling the Three.js scene for built polygon meshes. Once globe.gl has the country data, Three.js tessellates 200+ polygons over a variable number of frames (slower CPUs took several seconds). Loader now waits for ≥50 polygon meshes to exist in the scene before adding a 700ms post-paint buffer - no more flash of empty blue sphere even on slower machines. 12s hard cap.
v2.124.5 - Public Feed Catalog loader: hold the loading state for ~1.1s AFTER all ready flags flip so country meshes finish tessellating and the polygon + marker fade-in animations complete behind it. Previous version dismissed when data was supplied to globe.gl, but Three.js still needed several frames to actually paint the polygons - leaving a brief blue-sphere flash between dismissal and first paint. Also extends the cross-fade to 600ms for a smoother handoff.
v2.124.4 - Public Feed Catalog: keep the loading state in front of the globe until country polygons and feed markers have actually rendered (was disappearing the instant globe.gl mounted, leaving users staring at a featureless blue sphere for several seconds). Includes a 7-second safety dismiss so an API failure with no cache still shows the globe.
v2.124.3 - Public Feed Catalog: replaced the nearly-invisible "Initializing globe…" placeholder with a polished animated loader - wireframe globe with rotating orbit grid, sweeping meridian highlight, pulsing feed pins, and a soft halo - so the first few seconds of opening the modal feel intentional instead of blank.
v2.124.2 - Add Data Launchpad spacing + depth polish: smaller, softer brand mark so it reads as a signature instead of a second header; tightened header spacing (6px / 8px / 18px); calmer hover with 2px lift and a subtle image clarity bump; stabilized button on hover; softer divider treatment.
v2.124.1 - Add Data Launchpad visual polish: tightened header copy, per-column eyebrows, unified single-accent illustration palette, layered modal/button shadows, and a calm-thunder hover with subtle preview parallax.
v2.124.0 - Add Data Launchpad: a premium, session-scoped onboarding modal now greets first-time visitors with four equal entry points - Public Feed Catalog, URL Address, Local ZIP File, and GeoJSON / KML - each routing directly into the existing Add Data flows. Appears once per browser session when no feed is loaded.
v2.123.5 - Heatmap: guard leaflet.heat's `_redraw` against null map and 0-sized canvas/container so workspace transitions and panel resizes while the heatmap is on no longer trigger an IndexSizeError or getSize-null crash.
v2.123.4 - URL import: recognise lowercase HTML doctypes so webpage URLs surface the actionable "paste the direct ZIP URL" message instead of the generic blocked-download fallback.
v2.123.3 - Fix ReferenceError in stop hover tooltip, stop inspector, and stop popup departure rendering.
v2.123.2 - Fix dark-mode Timeline time strip showing trip bars through its translucent background.
v2.123.1 - Timeline: enlarge and re-style the selected-stop marker (white ring + accent inner dot, lifted above the in-bar label) so it's clearly visible on any bar color.
v2.123.0 - Timeline: click any stop in the trip card to pin a marker at that stop's exact spot on the trip bar; click again or close the card to clear it.
v2.122.5 - Timeline: refresh the trip-selection hint copy and surface the + / − zoom shortcut alongside it.
v2.122.4 - Timeline: honour empty agency/mode filter selections - clearing every checkbox now correctly hides all trips instead of showing all.
v2.122.3 - Timeline: replace agency filter chip strip with a searchable dropdown so feeds with hundreds of agencies stay usable.
v2.122.2 - Timeline: wrap agency and mode filter chips onto multiple rows so they no longer overflow the viewport on feeds with many agencies.
v2.122.1 - Fix Route Inspector adaptive stop markers (including station hubs) staying as full icons after zoom, pan, or marker re-entry.
v2.122.0 - Public Feeds Catalog: globe reframed and refined (50m borders, crisper markers), more accurate feed placement, feeds over 500 MB hidden, a City/Agency grouping toggle with city search, and the inspector now shows the feed's real detected GTFS features.
v2.121.0 - Timeline view: filter by Agency with command-center pills.
v2.120.15 - Update "Routes Not Drawn on Map" notification copy.
v2.120.14 - Fix double scrollbar in the route selector popup.
v2.120.13 - Add dismiss button to Timeline stop times hint popup.
v2.120.12 - Add Type and Accessibility labels to stop and hub map popup cards.
v2.120.11 - Route Inspector: only list trips for the selected calendar day, excluding next-day post-midnight trips.
v2.120.10 - Removed the "Online features unavailable" status banner. Worker outages are now handled silently: the health state machine still probes the backend and gates online-only features, and a structured report is still sent to the silent-error endpoint - but there is no longer a user-facing banner or Activity Log notification for it.
v2.120.9 - Timeline rows with frequency service now reserve extra row height for the "every X min" hint, so the left-rail label no longer clips or overlaps the direction line.
v2.120.8 - Timeline frequency mini-bars are now opaque (a soft pastel tint of the route color with the diagonal-stripe pattern carrying the "frequency" identity), so the hairline connector no longer bleeds through and the embedded headsign reads cleanly. Connectors render behind the bars.
v2.120.7 - Timeline frequency mini-bars now share the exact sublane of their template trip (no separate row), suppress the duplicate instance that coincides with the trip bar's anchor time, and render the template's headsign inside each mini-bar so the row reads as "the same trip repeating every X min".
v2.120.6 - Routes table column filters tuned for the new frequency columns: Source Trips loses the per-column filter (raw trip count is rarely a useful filter axis), and Service Model gains a filter with five buckets (Scheduled / Frequency-based / Exact compressed / Mixed / No trips).
v2.120.5 - Timeline frequency bands redesigned: each generated frequency departure now renders as its own mini-bar sized to the template trip's duration, with hairline connectors between consecutive instances carrying the headway label. The left rail surfaces an "every X min" hint with a clock glyph on every frequency-service row. Routes table column headers (Source Trips, Effective Departures, Service Model, Headway) gain hover tooltips with full GTFS provenance and model-definition copy; data cells in those columns are now horizontally centered.
v2.120.4 - Timeline frequency bands: routes with frequencies.txt now render headway windows as translucent striped bands in the Timeline (one DOM node per rule, no per-departure explosion). Mixed routes show scheduled bars and bands together in the same row. Hover a band for a rich tooltip with route, direction, time range, headway, count, source, template trip, and service model; click to open the Route Inspector. At top zoom, exact_times=1 rules render generated tick marks (capped at 200 per band).
v2.120.3 - Layers feed-meta refinement: the frequency entry is now an inline item in the same dotted meta strip as Stops / Routes / Trips / Shapes / size, with a small emerald clock glyph as the only visual marker and a hover tooltip carrying the rules-across-routes breakdown and any import-time issues.
v2.120.2 - Frequencies operational UI: Route Inspector gains a "Frequency Service" section with effective-departure stats and period breakdown. Stop Inspector lists per-route headway windows shifted to the stop's stop_time offsets. Layers tree route rows and stop popups get a "Freq" badge; the Layers feed-meta strip surfaces frequency rule counts and any import warnings. The Routes table adds Source Trips, Effective Departures, Service Model, and Headway columns so Scheduled / Frequency-based / Mixed / Exact compressed routes are scannable at a glance.
v2.120.1 - Frequencies analytics integration: Calendar day counts and Service Rhythm hourly distributions now include effective departures from frequencies.txt (scheduled + estimated split). Calendar tooltip and route contributions reflect headway-based service; "Frequency service included" context notice appears on the Calendar workspace when the active feed has frequency rules.
v2.120.0 - GTFS frequencies.txt support: headway-based service is now parsed at import time. Frequency rules, per-trip stop offsets, and feed/route frequency stats are exposed on the data model. exact_times=1 rows are stored as exact scheduled departures; exact_times=0 (or empty) are stored as estimated/headway-based and labeled accordingly.
v2.119.4 - Route Inspector layout: "Stops on map" is now part of the Quick actions cluster (rendered as a compact segmented row directly beneath "Focus on map") and no longer a standalone strip inside the Stops section.
v2.119.3 - Direction flow overlay: also bypass the direction filter when the requested direction key doesn't match any polyline's _dirKey. Fixes unidirectional routes whose inspector reports dirKey '0' while polylines are tagged 'none'.
v2.119.2 - Direction flow overlay: render arrows on unidirectional routes (the implicit "none" direction no longer rejects every numbered polyline) and on routes whose only shape data is approximate/auto-generated (those polylines are now an accepted target for the arrow placement).
v2.119.1 - Adaptive stop markers: render full icons at the initial inspector zoom (only switch to dots/sparse when the user zooms out from that baseline), show the "Stops on map" control even on routes whose route-level stop ordering is empty, and fall back to pattern-level stop sequences for the density calculation.
v2.119.0 - Route Inspector: adaptive stop markers. While inspecting a route, stop icons now scale to small dots (or hide entirely) as the map zooms out so the route line stays readable instead of being covered by crowded bus icons. A new "Stops on map" control inside the inspector lets you override the auto behavior with Full, Compact, or Hide.
v2.118.4 - Timeline trip card head: carry-over trips now show the trip's true time range (e.g. 23:15 → 00:25⁺¹, 1h 10m) instead of just the visible carry-over portion of the bar (00:00 → 00:25, 25m). Preserves the raw GTFS min/max alongside the canvas-shifted values so the head and duration always reflect the full journey.
v2.118.3 - Timeline trip card: drop the -1 prev-day badge. Every stop is anchored to the trip's own service-day frame, so the first stop reads as today (no badge) regardless of whether the user is viewing the trip on its own day or on the carry-over copy, and only post-midnight stops carry the "+1".
v2.118.1 - Timeline trip card: stop times that cross midnight now wrap to a standard 00:00-23:59 clock instead of showing 24:00, 25:30 etc., with a subtle +1 badge in the top-right corner marking next-day arrivals.
v2.118.0 - Timeline workspace launches: a new full-day view of every trip on every route, with route search and pagination, mode toggles, day-stepper and calendar picker, click-to-pan, fluent block-chain connectors between same-vehicle trips, live trip indicators with stop-time table and "Same vehicle" jumps, and Open-in-Route-Inspector handoff. Pick it up from the workspace dock alongside Map, Table, and Calendar.
v2.117.93 - Activity log error stickiness + bar position fix: pending unacknowledged errors now own the 48px bar - subsequent info/success notifications (e.g., progress from a follow-up import) no longer overwrite an unread error. Also stopped the bar from shifting horizontally when the nav rail expands, so it stays aligned with the search bar above.
v2.117.92 - Fix activity log bar stuck on "Parsing…" / "Importing…" when import fails: errors now preempt the running bar scroll immediately, and the 220ms bar-expansion guard no longer clobbers an error that arrived in that window.
v2.117.90 - Fix activity log error row auto-scroll on expand: delay trigger 200ms to let the panel's opacity:0→1 transition complete before starting the WAAPI animation (Chrome suspends animation timers inside opacity:0 subtrees).
v2.117.88 - Activity log error rows now auto-scroll their message text when the log is expanded: dispatches a synthetic pointerenter on all unread (pending) error rows the moment the panel transitions to EXPANDED, so the marquee starts within 450ms of opening without requiring any hover.
v2.117.87 - Fix activity log error row dot misalignment and dim text: matched padding-left to normal rows (16px) so the dot x-position lines up, lifted title to pure white, and raised message text to rgba(255,255,255,0.80).
v2.117.86 - Fix activity log error row colours being invisible: the panel is always dark glass regardless of app theme, so removed the [data-theme="light"] overrides that were applying black text and near-transparent backgrounds on the dark surface. Increased background and border opacity for clear visibility.
v2.117.85 - Refine activity log error row styling: replaced heavy card treatment with compact inline emphasis - subtle red background, 1px border, 6px dot with soft glow, single-line layout, and light/dark mode support.
v2.117.84 - Activity log error rows redesigned as card-style entries: red left rail, icon badge replacing flat dot, vertical content layout, stronger title contrast, and top-aligned timestamp.
v2.117.83 - Activity log errors: detail text bumped to 12px for consistency; click-to-acknowledge removed in favour of hover-scroll-to-acknowledge - hovering the error row starts the marquee scroll and acknowledges automatically after one full read cycle.
v2.117.82 - Add detailed diagnostic reporting for "Online features unavailable" banner: captures probe timing, HTTP status, error type, network state, and downtime duration, then ships the report through the silent-error pipeline with sessionStorage queuing for retry on recovery.
v2.117.81 - Fix route shape disappearing when switching to Direction B: (1) inspector focus mode now keeps the active direction's shapes visible when the other direction has no GTFS shape data, instead of hiding everything; (2) pattern summary for inferred-direction routes (direction_id = null) no longer shows empty when switching to Direction B - patterns are now looked up under the correct 'none' key rather than '1'.
v2.117.80 - Fix the feed timezone override (Layers panel) having no visible effect on stop times: the inspectors had no listener for the timezone-changed event, and clock labels were never converted between source and override zones. Now the Stop Inspector departures, Route Inspector "Today's service", trip stops list, and stops tray all repaint immediately and shift clock labels into the chosen view tz (e.g. a feed with agency_timezone=UTC overridden to America/New_York now displays "11:10" for a stop time stored as 15:10).
v2.117.79 - Fix Today's service trip row badges showing Direction A's color when Direction B is selected on routes whose directions are inferred from stop sequences (no GTFS direction_id).
v2.117.78 - Fix stop popup showing "not served by any route" warning while simultaneously displaying departures: stop marker popup closures captured routesServingStop at render time (during the stops_ready phase when stopToRoutes is empty), while getStopDepartures was called dynamically at open time using the fully-populated stopDepartures index. Now re-computes routes lazily inside the popup factory so both the route list and the warning always reflect the current feed state.
v2.117.77 - Improve GTFS import error diagnostics when a feed produces no stops or routes: the error message now reports whether each file was missing from the archive, could not be parsed, or contained no valid data rows - turning a generic "no valid stops or routes" into an actionable per-file explanation.
v2.117.76 - Stop showing Chrome's opaque "Worker failed" string when the import worker is killed by the browser (transient OOM, tab throttle, or system memory pressure): the `worker.onerror` path now skips that uninformative generic message and surfaces the structured "the parser crashed unexpectedly - try again" fallback instead, with a size hint for files over 20 MB.
v2.117.75 - Fix truncated ZIP files hanging the import worker indefinitely: partial downloads whose fflate streaming entries never received a final data chunk would cause Promise.all to wait forever, resulting in a zombie worker eventually killed by the browser with the opaque "Worker failed" error. Now detects unsettled entries after stream exhaustion and rejects them with a specific "ZIP archive is truncated" message. Also adds a 30-second silence timeout as defence-in-depth, and fixes the import log showing "0.0 MB" for files smaller than ~100 KB (now correctly shown in KB).
v2.117.74 - Fix activity log marquee auto-scroll being interrupted by pointer events: the auto-scroll used the same 'initial' phase as hover-triggered scroll, so any pointer enter/leave on the message bar while the error text was scrolling would call _finishCycle() and abort it - onScrollDone() was never called, _barMarqueeRunning stayed true, and auto-hide never started. Fixed by introducing a dedicated 'auto' phase that pointer events ignore.
v2.117.73 - Fix URL import silently passing HTML error pages to the GTFS worker: when a URL returns an HTML page instead of a ZIP (e.g. user pasted an open data portal link), the ZIP magic-byte check correctly detected the non-ZIP response but a fragile string-match in the catch block swallowed the error and let the HTML reach the worker, which then failed with the misleading "no usable GTFS data files" error. Restructured to wrap only the async arrayBuffer() call in try/catch; HTML responses now surface a specific "This URL points to a web page, not a GTFS ZIP file" message with open data portal detection (ArcGIS, etc.).
v2.117.72 - Fix crash in heatmap layer teardown: leaflet.heat v0.2.0's `onRemove` sets `_map = null` but does not cancel its pending `requestAnimationFrame` for `_redraw`, so a map event arriving just before layer removal could schedule a redraw that fires after `_map` is null and crashes with "Cannot read properties of null (reading 'getSize')". Fixed by cancelling `_layer._frame` in `_safeRemoveLayer` before handing the layer to `map.removeLayer`.
v2.117.71 - Detect empty or near-empty GTFS ZIP files before spawning the import worker: files under 1 KB now receive a clear "file is empty or too small" error immediately instead of the cryptic "Worker failed" message that the ZIP parser would emit when handed an empty byte stream.
v2.117.70 - Fix stale "import in progress" lock that blocked subsequent feed imports for up to 3 minutes after a deep-link or catalog-triggered import completed: the worker watchdog set the guard but only modal-triggered imports cleared it. Moved guard cleanup into `doGTFSImport`'s own finally so every import path releases it. Also softened the IMPORT_BUSY notification copy - title is now "Import in progress" and the body explains why a single import is processed at a time instead of telling the user their request was "ignored".
v2.117.69 - Replace JSZip with fflate streaming for GTFS imports: large feeds (100-350 MB) that previously crashed the worker now import successfully. Decompression is 3-10× faster, the compressed archive is consumed via `File.stream()` so the full ZIP is never held in memory, and `trips.txt` / `stop_times.txt` are passed to PapaParse as Blobs (skipping a full ArrayBuffer copy of up to 1+ GB on huge feeds).
v2.117.68 - Fix double scrollbar in the "Select route" popup: replaced the inner div's magic-number max-height subtraction with a flex-column outer container, so the header stays fixed and only the route list scrolls - one scrollbar instead of two.
v2.117.67 - Improve error message when the GTFS worker crashes unexpectedly (e.g. browser OOM-kills it on large files): instead of the generic "Worker failed", users now see an actionable message with a size hint for files over 20 MB.
v2.117.66 - Worker crash diagnostics: on Android and mobile Chromium builds where ErrorEvent.message is empty, the onerror handler now captures filename, line/column, and the underlying Error object so crash reports are actionable. Added an unhandledrejection safety net in the GTFS worker so any rejection that escapes the main try-catch is routed back as a structured error message rather than silently falling through to the generic "Worker failed" fallback.
v2.117.65 - Smarter feed import: GTFS files wrapped in a single subfolder (e.g., `gtfs/stops.txt`) are now auto-detected and imported transparently. When the archive truly contains no GTFS data, the error message tells the user what was actually found instead - nested zip count, GTFS-Realtime/OSM/GeoJSON detection, or the top file extensions present - replacing the generic "no usable GTFS data files".
v2.117.64 - Long-lived tabs that survive a deploy now show an actionable error when an import fails because the bundled GTFS worker chunk no longer exists on the server. Instead of the cryptic "Worker failed", users see "TransitLens was updated since you opened this tab. Please refresh the page, then re-import the file." Detected by a flag that flips on the worker's first message - if onerror fires before any message, we know the worker script never loaded.
v2.117.63 - Fix uncaught ReferenceError when exporting/printing the Calendar Day-scope PDF: the `getRouteDisplayStyle` callback was not threaded from `exportCalendarPDF` into `_exportDayPDF`, so the active-routes section in the day PDF crashed at runtime in production builds.
v2.117.62 - Stop Inspector gains the same compact Trips temporal control already shipped on Route Inspector: a Now button + date chip + time chip row sits above the departures board. Picking a date/time updates the board, the summary strip (which switches from Next/60min/Today to First/Last/Total in selected mode), the route pill hover preview times, and the empty-state copy. Times render as flat clock-only in selected mode (no "X min" / no "Live" relative labels). Calendar Day → Stop handoff and feed-coverage auto-fallback work the same way as on Route Inspector. Live Settings sync (dateFormat / timeFormat / weekStart) and out-of-coverage Now-button disabling come along too. The temporal control was generalized so both inspectors share one implementation. Route pill click behavior unchanged.
v2.117.61 - Route Inspector temporal control: deleted orphan CSS that was forcing the date/time fields into a column layout (icon dropping below the text). Date and time pickers now render the formatted value and the picker glyph side-by-side in one row. Cleaned up unused chip / picker / btn rules from the earlier picker design.
v2.117.60 - Route Inspector temporal control polish: date and time fields now show app-formatted values (Settings 12h/24h respected for time) over a transparent native input, giving full clickability with a clean app-controlled label. Date field is wider so values like "Sun, Apr 26" never get truncated. The "Now" button is now solid emerald when active and a clean white outlined button otherwise - its button-ness is unmistakable.
v2.117.59 - Route Inspector temporal control redesign: date and time pickers are always visible (no more "Pick date & time" trigger or "Add time" placeholder), pre-filled with today's date and the current feed-local time, with a clear white-bg clickable look. Picking a date keeps the time chip's value; picking a time keeps the date chip's value - each field is independent. Date can be re-picked at any time. The route inspector identity row keeps the route name on the same line as the badge instead of wrapping below. The trip list's absolute-clock branch now also surfaces the subtle "+1" marker for post-midnight times. Fixed the Today's service header span and FIRST/LAST cells to both reflect the active direction (no more 00:13-23:58 vs 00:23-23:53 mismatch). TOTAL trip count now matches the paginated list (rep-stop-filtered) instead of the larger direction bucket.
v2.117.58 - Route Inspector gains a compact temporal control: inspect the route at "Now" or any chosen date & time. Date and time are now two independent inline chips (Google-Maps-style - each opens its own native picker and applies immediately). The Today's service section adapts its title and contents to the selected moment; for non-today contexts, "Live" / "Next" / "Next 60 min" semantics are dropped and trip times render as a flat clock-only timetable. Departing / Arriving / Inbound stop pills also suppress for non-today trips. Variant-headsign muting is suppressed in non-today views so the schedule reads flat. Picked dates outside feed coverage now apply the same same-DOW fallback that Now mode uses, so the data stays consistent. Post-midnight trip times now show a subtle "+1" marker so riders can see when a clock value crosses into the next service day. The Today's service header now wraps cleanly when crowded (no more "Feed coverage ended" overlapping the title). Also: the Feed Loaded post-load card and the centered notification console no longer get clipped by the expanded left nav.
v2.117.56 - Calendar Day view: make the direction arrows next to "to <headsign>" bold and full-opacity so they read clearly against the route-color background.
v2.117.55 - Calendar Day view route cards now show "to <headsign>" for each direction beneath the route name, positioned left/right so each direction lines up with its half of the route's color background.
v2.117.54 - Calendar Day view becomes a date-specific service hub: each active route now shows its trip count and service span (HH:MM-HH:MM) for the selected date, the list is sorted by day-level activity, and clicking a route opens the Route Inspector with the selected date carried through as context for deeper exploration. Adds a premium empty state for days with no scheduled service (with a hint when service was removed by calendar exceptions).
v2.117.53 - Fix Route Inspector shape vanishing when opening a route from the Stop Inspector's route chip on feeds that split each direction into a separate route_id: the pattern emphasis pass was dimming every polyline to the near-invisible "other-direction" style because the A/B toggle key ('0' or '1') didn't align with the route's own direction_id. When no polyline matches the requested direction, emphasis now treats every polyline as same-direction so the shape stays visible.
v2.117.52 - Fix Route Inspector shape not appearing for feeds where each direction is a separate route_id (e.g., Israeli MOT): the focus-mode direction filter was hiding all polylines when the trip's direction_id didn't match any shape's direction_id. Now, if no polyline matches the focused direction, all of the route's polylines are kept visible.
v2.117.51 - Fix two interaction bugs when opening the Route Inspector from a stop popup's departure row: (1) the route polyline no longer disappears - the viewport-diff pass that runs after the Inspector's fit-to-pattern animation was dropping the focused route when the bbox query happened to exclude it; it's now pinned in the visible set while focus mode is active; (2) the clicked stop is now highlighted inside the Route Inspector's stops tray and used to auto-select the pattern that contains it. The map popup departure rows now forward the stop_id through to the Route Inspector so the origin is preserved across the navigation.
v2.117.50 - Fix horizontal scroll on stop and route popup cards: popup content now clips overflow-x, and inner card widths respect the container boundary so no content bleeds past the popup edge. Also completes the route-highlight fix: all paths that open the Route Inspector (stop departure row, stop popup route chip, Inspector "Open in inspector") now auto-pan and highlight the route on the map if it was out of viewport.
v2.117.49 - Fix: opening a route in the Inspector from the Routes table (or any non-map source) now automatically pans and zooms the map to the route and applies the highlight. Previously, if the route wasn't already in the viewport, the polyline highlight silently failed and "Focus on map" had to be clicked manually.
v2.117.48 - Fix: Service Time "Active now" filter now correctly restricts routes (and stops) to trips that actually run today - not just trips whose time-of-day falls in the current hour on any day. The filter resolves "today" per-feed in the feed's own timezone and intersects with any selected dates/days, then pairs that with the [now, now+1h] window. Before, routes with no service today could still appear on the map (and in Layers counts) while their inspectors correctly reported "no trips for today".
v2.117.47 - Proper fix for the live-trip-from-Stop-Inspector flow: the trip tray now opens via a double-requestAnimationFrame, which guarantees it runs AFTER the direction-toggle and pattern auto-selects (both scheduled on inner single-rAFs). The user's trip choice is always the last thing to write to the stops tray, so it always wins. Also means manual pattern clicks correctly switch modes to pattern view again (v2.117.46's preservation rule removed, it was masking the real race).
v2.117.46 - Fix: clicking a live trip in the Stop Inspector's departures now correctly lands on that exact trip's stops in the Route Inspector - not the pattern's generic stop sequence. Pattern auto-selection still runs (to highlight the pattern row + emphasize the map shape) but no longer clobbers the tray when the already-open trip belongs to that pattern.
v2.117.45 - Clicking a pattern row in the Route Inspector now shows that pattern's correct stop sequence (no trip-specific arrival/departure times) and adds a median pattern runtime to the stops tray subtitle - e.g. "Primary · Mon-Fri · 26 stops · 38 min". Before, the tray kept the previously selected trip's stop times and never updated to the new pattern. Tray title also resets to the route label.
v2.117.44 - Stronger, consistent active-trip marker across both inspectors: the tint is now visibly saturated (and equally strong on past, live, and next rows - no more pale fade when the selected trip already departed). The Stop Inspector's departure list gets the same marker - clicking a trip highlights its row so it stays visually linked to the stops sequence on screen.
v2.117.43 - Fix: switching direction in the Route Inspector now also updates the open stops tray. When a trip's stops are on screen, the tray swaps to the first live-or-upcoming trip of the newly selected direction; when the tray is in direction-stops mode, it refreshes in place with the new direction's stop order. Before, the tray kept showing the old direction's trip and the stop sequence never changed.
v2.117.42 - Move the Stop Inspector tools block (Zoom to stop / Serving routes / View in table) from the top of the inspector to sit just above Location & access, so Departures lead the rider's view and the actions wait where they're needed.
v2.117.41 - Stop Inspector's action buttons now use the same premium "Quick actions / Data views" layout as the Route Inspector: a primary "Zoom to stop" button with icon, and a paired "Serving routes" / "View in table" group below. Both inspectors now share one consistent tools language.
v2.117.40 - Clicking a trip row in the Stop Inspector's Departures list now also auto-opens the Route Inspector's stops tray for that exact trip, mirroring the popup departure-row behavior. The route and the trip's stop sequence now land together in one click.
v2.117.39 - Route Inspector direction buttons now scroll with the rest of the content instead of sticking to the top, and the duplicate direction toggle that used to appear again below Service rhythm has been removed. Active-trip marker in Today's service now uses a stronger accent tint so the current row is easier to pick out.
v2.117.38 - Simplify the active-trip marker in Today's service: drop the left accent rail, keep only the subtle tinted background so the row reads as "currently open" without a second visual element competing with the Live pulse.
v2.117.37 - Route Inspector's Today's service trip list now marks the row whose stops list is currently open on screen - subtle accent-tinted background plus a left accent rail - so it's always clear which trip the visible stops belong to. The marker updates instantly when the stops tray opens, closes, or switches trips.
v2.117.36 - Fix Live misclassification for post-midnight trips whose service day started yesterday: trip end time is now compared in the same day-frame as the "now" clock, so late-night continuations correctly show as Past once they finish (no more 00:00 / 00:40 / 01:15 all flashing Live at once).
v2.117.35 - Today's service trip list now opens on the first LIVE trip (or first upcoming if none is live) instead of the first upcoming trip - live trips no longer hide on earlier pages. The pager's Now reset follows the same rule.
v2.117.34 - Stops list live states tuned to a 3-stage model: Arriving pill lights up 30s before a stop's scheduled time; Departing pill stays for 15s after; Inbound pill (neutral cool-gray, no pulse) fills the gap when the bus is en route between the two windows. All three states remain mutually exclusive.
v2.117.33 - Route Inspector now auto-opens the first LIVE trip of the active direction (trip en-route right now) instead of the next upcoming one. Falls back to the next upcoming trip when no trip is live. User-selected trips (popup departure-row click) still take precedence.
v2.117.32 - Route Inspector's Today's service now labels en-route trips "Live" (with the trip's start time in the sub-line) instead of "Now". Stop Inspector keeps "Now" because there it means "this bus is arriving at this stop right now" - two distinct rider-facing moments.
v2.117.31 - Fix live-trip row layout in Today's service (broken ::before grid child replaced with a pulsing ring on the badge - same row shape as any other trip). Stops list now shows an "Arriving" pill on the next upcoming stop and a "Departing" pill (warm amber) on the stop the bus is still at within 15s of its scheduled departure; the two states are mutually exclusive. GTFS worker now captures arrival_time separately when it differs from departure_time, and the stops list stacks arr / dep in feeds that model dwell.
v2.117.30 - Route Inspector now auto-opens the stops tray for the next upcoming trip; clicking a departure in a stop popup opens the inspector on that exact trip. Direction toggle moved above Today's service (headline dropped). Trips that are en-route are no longer marked "past" - the Today's service list shows a subtle pulsing live dot next to them. In trip-mode stops list, the currently-arriving stop gets a pulsing accent halo with an "Arriving" pill; passed stops dim; refresh every 30s.
v2.117.29 - Trip-mode stops tray header now includes the trip's pattern (Primary / Pattern N) and total run time (first-stop → last-stop duration). Tray title reads "<route> · <headsign>" with subtitle "<pattern> · <N> stops · <start>-<end> (<duration>)". Truncated stop names now show the full name on hover via native tooltip (applies to both direction mode and trip mode rows).
v2.117.28 - Clicking a trip row in Route Inspector's Today's service now opens the Stops Tray scoped to that trip, listing each stop with its scheduled clock time - route's origin and terminus highlighted. Keyboard (Enter/Space) activation supported.
v2.117.27 - Revert v2.117.26's pickup_type=1 filter in the worker stop index. Every scheduled stop visit (including terminal arrivals) is now back in the board, so a route's arriving trips at its terminal bay surface in popups the same way they surface at intermediate stops. Feed cache DB bumped to v3 so existing imports rebuild cleanly.
v2.117.26 - Terminal-stop departure boards no longer surface arriving trips as rider-facing departures. The worker's stop_times → departures index now honours GTFS pickup_type=1 (alighting-only), so a UBCO-terminal bay no longer lists an arriving UBCO-bound trip next to a departing Lake-Country trip (each in its own direction color). Feed cache DB bumped to v2 so existing imports rebuild cleanly.
v2.117.25 - Also fix the stop map HOVER tooltip departure badges (separate from the click popup) to use direction-aware colors via _dirColor, so hovering a stop shows the same direction-B badge color as the Route Inspector.
v2.117.24 - Stop map popup departure badges now use the direction-aware color (via _dirColor) so they match the Route Inspector badge for the same route+direction - previously a direction-B trip showed the base route color in the popup but a hue-shifted color in the inspector.
v2.117.23 - Fix Inspector opening mid-panel: the pattern auto-select runs a scrollIntoView on a pattern row near the bottom of the inspector, which overrode the earlier top reset. Added a post-RAF scroll reset at the end of openInspectorPanel so the inspector always lands on the identity header, even after the pattern click.
v2.117.22 - Inspector now always opens scrolled to the top so the identity header is the first thing the user sees after selecting a new route/stop; Today's service summary strip ("138 trips today · 00:18 - 23:53") centered as a composed pair under the status chip.
v2.117.21 - Route Inspector tools block now uses the app's main theme colors: cobalt in light (was teal) for the primary "Focus on map" fill, outlined-button hover, and focus ring; emerald in dark (unchanged). Brings the tools block into line with the pager, popup links, and About accents.
v2.117.20 - Route Inspector utility tools recast as a two-level block: a Quick actions group with a single medium-emphasis full-width "Focus on map" button, followed by a Data views pair ("Stops table", "Route table") in a 2-column outlined row. Readable sentence-case group headings replace the tiny uppercase kicker.
v2.117.19 - Route Inspector utility action row relocated below Today's service and redesigned as a premium tools cluster (Focus on map · Stops table · Route table) with small icons, a subtle "TOOLS" kicker, and outlined soft buttons that read clearly secondary to the bottom "View stops" CTA.
v2.117.18 - Route Inspector header band visual polish: hairline rule between the identity row and the meta row; facts cluster (ID · stops) anchored left with small-caps micro-labels and mono-numeric ID, source cluster (Feed · Agency) right-aligned in quiet secondary text; soft top highlight, deeper tonal surface, and a richer route badge.
v2.117.17 - Route Inspector top redesigned as a premium identity band: larger route badge with soft inner highlight, long-name and headsigns in primary type, mode chip on the right, and a compact meta row (Route ID · N stops · Feed · Agency) that replaces and removes the standalone Route overview section, recovering vertical space and lifting Today's service higher.
v2.117.16 - Pager now shows the "N-M of T" trip counter on top with the Now reset link directly beneath it for a clearer visual hierarchy.
v2.117.15 - Pager Now button drops its dot icon and stacks centered above the "N-M of T" indicator; Route and Stop info popups replace the thin → with a heavier ➔ arrow and inline the direction headsign on the same row as the route name (dedup'd against route_long_name).
v2.117.14 - Clicking a trip in the Stop map popup now opens the Route Inspector on that route, direction, and pattern; pager and Now controls redesigned as compact text-link buttons so the trip list itself stays the focus.
v2.117.13 - Route Inspector trip rows now match the Stop Inspector rhythm (route badge · headsign · time); pager buttons equal-width. Stop Inspector departures list converted to trip-level pagination so all of today's trips (e.g. 140 at a busy stop) are reachable via Prev / Next / Now.
v2.117.12 - Premium pager across Route & Stop Inspectors: solid cobalt buttons in light, emerald in dark, with a "Now" reset pill that jumps back to the current-trip page; past-trip rows no longer show a misleading "Now" label.
v2.117.11 - Fix Route Inspector not opening from the map popup ("View in Inspector" button) - stale reference to a removed constant threw at populate time.
v2.117.10 - Route Inspector Today's service now includes every direction trip (including variant headsigns like short-turns), renders each row's headsign when it differs from the direction's dominant, and the inspector title lists all of today's direction headsigns (collapsing to "+N more" with a tooltip when there are many).
v2.117.9 - Route info popup now lists each direction's headsign (falling back to last-stop name); "Show more" in Route Inspector and Stop Inspector departure lists replaced with Previous/Next pagination that pages through the full day of trips, past trips shown dimmed.
v2.117.8 - Today's service direction panel redesigned to match the Stop Inspector rhythm: drop the redundant destination heading (inspector title already carries it), add a Next · Next 60 min · Today summary strip, and present upcoming departures as a proper clock/relative time list.
v2.117.7 - Today's service now mirrors the Direction A/B control and shows only the selected direction's trips; route-picker popover prefers the direction's headsign before falling back to first▸last stop names.
v2.117.6 - Route Inspector title now shows the current direction's headsign (e.g. "11 Rutland" / "11 Downtown") and swaps on direction toggle; Direction A/B buttons and Today's service panels prefer the representative trip's headsign and fall back to last-stop name only when no headsign exists.
v2.117.5 - Remove the unused ROUTE_INSPECTOR_DEPARTURES feature flag now that its UI is fully absorbed into Today's service.
v2.117.4 - Route Inspector cleanup: remove the dead Upcoming Departures code path and stale CSS, lock the inspector order to identity → actions → overview → Today's service → Service rhythm → Direction → Pattern summary → Stops, and drop the direction-toggle handler that rebuilt the removed section.
v2.117.3 - Unify Route Inspector Trips into a single Today's service module: remove the duplicate Upcoming departures section, drop the redundant "next" cell from the summary strip so each direction panel carries its own next-trip hero.
v2.117.2 - Premium redesign of Route Inspector Today's service: inline summary strip, split-direction module with hero next departure, compact later-times row, and expandable chip grid; adds live service-status chip.
v2.117.1 - Add Today's service section to Route Inspector with direction-aware next trips, service span, and upcoming trips preview.
v2.117.0 - Departures preview in Stop Info Card and hover tooltip; Stop Inspector now shows a typical day-of-week schedule when feed coverage has ended or not started; trip-accurate direction & pattern selection when clicking a departure; fix direction toggle not updating the map for inferred-direction feeds; improve direction-toggle contrast.
v2.116.3 - Fix column filter dropdowns showing "No matches" when another filter removes all rows; fix horizontal scroll disappearing in the empty-state Routes Table.
v2.116.2 - Service Days filter with no days selected now shows only routes with zero trips (no service on any day), instead of showing all routes.
v2.116.1 - Fix Service Days filter chip showing raw DOW index instead of day name.
v2.116.0 - Fix Routes Table Rhythm column showing no bars (serviceDays missing due to worker ordering bug); add Service Days filter to Rhythm column header.
v2.115.0 - Clicking a departure row in the Stop Inspector now opens the Route Inspector for that route and direction, matching the behavior of Routes Served chips.
v2.114.51 - Fix departure badge colors in Stop Inspector not matching route direction colors: departure row badges now use direction-aware color (same as Routes Served chips and search results) instead of the base route color.
v2.114.49 - Fix progress bar lying on large feeds: don't mark rendering stage active in stops_ready (worker still has stop_times + shapes to parse), so the bar reflects real progress instead of jumping to 99% prematurely. Also skip verbose agency dump in DevTools for feeds with 50+ agencies.
v2.114.48 - Improve feed-load UX: show a smooth tile-load veil over the map after auto-zoom so users see a clean fade-in instead of grey canvas while OSM tiles fetch.
v2.114.47 - Enable clustering for co-located and multi-modal hub stops: colocatedLayer now uses the same dynamic cluster radius as stopsLayer so hub-adjacent and multi-type stops group into cluster bubbles when zoomed out.
v2.114.46 - Fix repeated "Something went wrong" toasts caused by leaflet.markercluster zoom-animation grid races: sync is now coalesced per frame, deferred during active zoom, and cluster grid errors are suppressed from the user-visible error toast.
v2.114.45 - Fix Stop Inspector showing fake departures for expired or not-yet-active feeds: the selector now requires an explicit active service on the current date instead of falling through as "no filter". Adds a clear coverage banner ("Feed coverage ended - Schedule valid X - Y") and a tailored empty-state message when today is outside the feed's calendar range.
v2.114.44 - Departures board no longer renders empty route pills for agencies that leave route_short_name blank (MBTA rail, NYC subway, etc.). Badges now fall back to initials of the long name (Red Line → RL) or a truncated route_id.
v2.114.43 - Hub markers on the map (metro stations, multi-modal stops) now also show upcoming departures on hover, filtered to the marker's transport mode when appropriate.
v2.114.42 - Hovering a stop marker on the map now reveals up to 3 upcoming departures (route badge, headsign, time) in addition to the stop name, and the tooltip is visible in browse mode (no longer gated to inspector-open).
v2.114.41 - Stop Inspector departure times now follow the Time format setting (Auto / 24-hour / 12-hour) and update immediately when the setting is toggled, including rows, summary strip, and route-pill hover popover.
v2.114.40 - Fix Stop Inspector departures "Show more routes" button: it now correctly flips to "Show less" when expanded and collapses the list when clicked again, rather than staying stale after the first click.
v2.114.39 - Show the departure platform for each route when the feed provides one (platform_code, stop_code, or a distinct child stop_name). Never fabricate platform numbers when the feed doesn't label them, to avoid misleading riders.
v2.114.38 - Stop Inspector departures: remove the upcoming-count chip from the header, sort routes by soonest departure (top = next), and surface the platform for each route (platform_code, stop_code, or a parent-relative name fallback) when inspecting a hub.
v2.114.37 - Center-align labels and values inside the Stop Inspector summary strip cells.
v2.114.36 - Rename the Stop Inspector summary cell from "Trips today" to "Today" and append a "trips" unit suffix to match the Next 60 min cell.
v2.114.35 - Stop Inspector summary strip now shows Next · Next 60 min · Trips today (total scheduled trips for the service day) instead of Routes soon.
v2.114.34 - Stop Inspector departures now show a single by-route grouped list sorted ascending by route number, auto-refreshing every 30s so stale departures drop off without reopening the inspector.
v2.114.33 - Preserve genuinely distinct departures in the Stop Inspector: only exact same-second collisions are treated as duplicates; trips within the same minute are kept as separate rows and their clock labels now include seconds (e.g. 14:59:30) for precise disambiguation.
v2.114.32 - Stop Inspector departures now collapse visually-identical rows (same route, direction, headsign, and minute) into one, eliminating remaining duplicates caused by feeds that model a single physical departure as multiple GTFS trips.
v2.114.31 - Fix duplicate departures at hub stations: a single trip with stop_times rows at multiple child platforms of the same station no longer appears 2-3 times in the Stop Inspector Departures board.
v2.114.30 - Premium redesign of the Stop Inspector departures module: refined header, live activity summary strip, stronger row hierarchy, smarter By-route grouping with inline upcoming times, platform awareness for hubs, tighter inspector spacing.
v2.114.29 - Stop Inspector now shows upcoming scheduled departures with a Board/By-route view and a premium hover preview on route pills.
v2.114.28 - Fix Inspector focus mode showing unrelated stops; fix pattern hover showing wrong-type stops, incorrectly dimming sibling patterns, and losing click emphasis on mouse-out.
v2.114.27 - Add crossorigin attribute to analytics scripts so cross-origin errors report real stack traces instead of "Script error.".
v2.114.26 - Fix stale APP_VERSION in error reports; add missing .catch() handlers on dynamic imports to prevent unhandled rejections.
v2.114.25 - Add crossorigin attribute to main script for full error stack traces in error reports.
v2.114.24 - Disable auto-restore of cached feeds on browser reload; feeds start fresh on each session.
v2.114.23 - Fix catalog feed contents not reflecting actual feed data; apply GTFS-mandatory defaults and lazy-fetch real features on selection.
v2.114.22 - Improve map responsiveness after feed load: batch SVG redraws, skip casings at far/mid zoom, cache RDP simplification, spatial hash for hub proximity, bulk stop marker insertion.
v2.114.21 - Three-phase loading with parallel shapes worker: show stops on map in ~5s instead of ~30s for large feeds; parse shapes.txt in a dedicated worker simultaneously with stop_times for ~30% faster total import.
v2.114.20 - Fix shapes processing stall: serialize shapes directly to Float64Array in worker (skip Object.fromEntries), pre-compute per-shape bboxes for O(shapes) route bbox indexing, add progress reporting for post-parse indexing step.
v2.114.19 - Reduce UI freezing during large feed import: faster Map/Set hydration, sampled driving-side detection, yielding between heavy operations.
v2.114.18 - Optimize import speed: transfer shapes via zero-copy ArrayBuffer; build stop grid and route bounding boxes in the worker to reduce main-thread blocking.
v2.114.17 - Optimize filter performance for large feeds: replace JSON.stringify comparisons with shallow equality, add route-service index and caching, eliminate redundant filter passes.
v2.114.16 - Fix out-of-memory crash when importing very large GTFS feeds; fix auto-zoom landing on wrong location (e.g. Mumbai instead of Australia) by filtering invalid stop coordinates.
v2.114.15 - Fix globe markers lost after page reload by persisting enriched markers to localStorage and merging instead of replacing on API refresh.
v2.114.14 - Fix catalog feed imports: fall back to proxy on HTTP 401/403; fix TDZ crash on feed replacement; add import guard and error notifications.
v2.114.12 - Fix misleading "URL not found" error for HTTP 401/403 import failures.
v2.114.11 - Remove redundant actions column from Routes table; fix Directions column width consistency with 220px fixed size and proper overflow handling.
v2.114.10 - Add headsign data to Routes table pattern rows with last-stop fallback; refactor Directions column with +/- expand toggles and indented hierarchy; improve direction and pattern sub-row text readability.
v2.114.9 - Fix transfer section: remove duplicates and self-transfers, show walking distance, display route chips per transfer stop; fix Layers shapes count; improve transfer map visibility; auto-select pattern on route open.
v2.114.8 - Improve stops tray subtitle: split into two lines, always show pattern name (default Primary), and include service days and trip stats.
v2.114.7 - Fix Inspector route focus mode showing stops from other transport types at multi-modal stop locations.
v2.114.6 - Fix loading card crash when duplicate imports race: reset card structure if completion state replaced the progress elements.
v2.114.5 - Fix MarkerClusterGroup "removeObject" errors during Inspector focus mode transitions by guarding cluster layer operations against internal grid race conditions.
v2.114.4 - Improved guidance for feeds without usable route shapes: persistent top-right "Routes Not Drawn on Map" coachmark (auto-hides while inspector is open, only the user can dismiss), matching calm amber "No route shapes" warnings in both Route and Stop Inspectors, and new "Zoom to route" / "Zoom to stop" actions as the leftmost button in each inspector. Selecting a route from Tables or Layers now pans and zooms the map to fit the full route in the available viewport - including shapeless routes via stop-sequence fallback.
v2.114.3 - Browse Public Feeds globe now paints the full per-country marker set on first load by enriching the country index with the durable per-country cache. The merged response is itself persisted to KV and refreshed by the cron, so it survives Cloudflare isolate churn and refreshing the modal no longer collapses the globe back to the sparse index subset.
v2.114.2 - Browse Public Feeds no longer silently substitutes the curated sample list when a country-scoped fetch fails, so a failing live API now surfaces as a real error state instead of pretending 23 hand-picked feeds are the answer.
v2.114.1 - Public Feeds Catalog now persists per-country results in durable cache and only replaces them on a verified-complete refresh, so feeds no longer disappear after several hours; upstream timeout raised so large countries like the United States load reliably.
v2.114.0 - Inspector mode adds a premium hover tooltip on map stop markers showing the stop name (and code, when present). The tooltip is gated to Inspector mode only - no extra noise during default browse - and is fully theme-aware.
v2.113.5 - Clicking a stop in the Stops Tray now centers the stop in the visible portion of the map (offsetting the Inspector + Stops Tray width) so the selected stop is no longer hidden behind the open panels.
v2.113.4 - Restore Inspector main panel to its original full height; Stops Tray keeps its dock-aware sizing.
v2.113.3 - Routes Inspector layout stabilized: "Stops in this pattern" and "View stops" pinned as a fixed footer above the dock, body content scrolls independently, and the Stops Tray now respects the floating dock and Show All pill clearance. Stops list is also pattern-aware - selecting a pattern dynamically updates the inspector count and refreshes the open Stops Tray with that pattern's ordered stops.
v2.113.2 - Routes Inspector "View stops" button is now a filled accent button so it always reads as the primary action; Stops Inspector action strip no longer overflows horizontally - buttons share the available width with elastic minmax cells.
v2.113.1 - Routes Inspector "View stops" CTA cleaned up: removed the chevron arrow and the inline stops preview, and made the button toggle the Stops Tray open and closed.
v2.113.0 - Stops Tray: the full route stop sequence now lives in a dedicated sliding panel beside the Routes Inspector. The inspector keeps a compact stops summary with a preview and a "View stops" CTA, freeing the inspector body from vertical pressure and giving the detailed stop list its own focused scroll surface.
v2.112.0 - Routes Inspector aligned to the Stops Inspector design language: editorial sentence-case sections, refined direction segmented-control, calmer pattern summary and stops list, and a Service Rhythm bar widget that shows the route's average trips per weekday at a glance (mirroring the Routes table column).
v2.111.3 - Stop Inspector "Focus map" action now also opens the stop info card on the map and centers the stop in the visible viewport (excluding the inspector panel), matching the behavior used by table-driven navigation.
v2.111.2 - Stop Inspector actions converted to a compact 28px segmented control: text-only segments, 2px gap, 8px container radius, 6px segment radius, subtle hover, no icons.
v2.111.1 - Fix Stop Inspector "Stops table" action so it correctly reveals and highlights the target stop in feeds with progressive loading (more than 1000 stops): the reveal now waits for the full row set to finish loading before giving up.
v2.111.0 - Stop Inspector premium visual redesign: hero header with confident typography, segmented action strip, sentence-case editorial section headers, transfers as a refined relationship list, Stop Structure rendered as a true hierarchy tree, status text instead of status pills, and a holistic typography + spacing pass for both themes.
v2.110.1 - Trim redundant "transfer" suffix from transfer row meta labels (Recommended, Timed, Min N min, In-seat) so the relationship reads cleaner under the Transfers section.
v2.110.0 - Stop Inspector layout refinement: 2-row action group, contained Routes Served empty state, restructured transfer relationship rows, neutralized Stop Structure summary, and a new transfer visualization on the map (click a transfer row to draw a connector to the partner stop while keeping the current inspector open).
v2.109.2 - Stop Inspector micro-polish: header metadata contrast tuning, no-routes warning integrated as a Routes Served empty state, sharper left labels, refined translation rows, more obviously clickable child structure chips, and crispened action buttons.
v2.109.1 - Stop Inspector premium polish: cleaner header hierarchy, stronger contrast on labels and section titles, refined action buttons, redesigned transfer rows with clearer status pills, and a natural-language summary line in the Stop Structure section.
v2.109.0 - Stop Inspector redesigned as a structured operational stop profile: enriched header with parent/hub relationships, Location & Access, Routes Served, Names & Translations, Transfers, and Stop Structure sections, with clickable parent/child/transfer navigation.
v2.108.8 - Stop info card now centers in the visible viewport on the first navigation from the Stops Table.
v2.108.7 - Stop Inspector centers the stop in the visible viewport, drops the redundant Focus on Map action, and the Show-in-Table icons are aligned across both inspectors.
v2.108.6 - Stronger row selection styling and a more visible reveal pulse when navigating from inspectors.
v2.108.5 - Stops-by-Route chip now prefixes the route name with "Route" so numeric short names are not misread as a stop count.
v2.108.4 - Show in Routes/Stops Table now switches to the correct page and scrolls to the row.
v2.108.3 - Fix Stops-by-Route scope showing only one stop when stops are nested under parent hubs.
v2.108.2 - Fix Show in Routes Table opening with Stops content; refine feed-scope status text size and contrast.
v2.108.1 - Stops-by-Route scope chip now shows "Short : Long" name, persists across tab switches, and stays scoped to the Stops table only.
v2.108.0 - Connected navigation between tables, map, and inspectors with relational drilldowns and action groups.
v2.107.11 - Warning summary panel in Tables is now interactive: click a severity to prioritize those rows at top.
v2.107.10 - Route zoom from Layers now centers in visible viewport, accounting for inspector overlay.
v2.107.9 - Add client-side catalog cache and retry logic to prevent empty globe after inactivity.
v2.107.8 - Hide Inspector and Show All pill when report viewport is open.
v2.107.7 - Lower Show All pill z-index to match Inspector; hide on non-map workspaces.
v2.107.6 - Align Show All pill horizontally with Activity Log, centered at viewport midpoint.
v2.107.5 - Center Show All pill in usable map area excluding Inspector width, using wrapper-based layout.
v2.107.4 - Micro-polish Exit Focus pill: subtle border and shadow refinement, tighter icon badge, slight position adjustment.
v2.107.3 - Polish Exit Focus pill: compact "Show All" label, expand-context icon with badge, tighter width, refined hierarchy.
v2.107.2 - Refine Exit Focus pill: larger size, layers icon, explicit label, right-shifted position, stronger glass styling.
v2.107.1 - Fix loading card overlapping expanded nav rail.
v2.107.0 - Add floating Exit Focus pill button at top-center of map to close Inspector and restore full map context.
v2.106.0 - Restructure Add Data panel, split GTFS import into separate URL and file modals, move loaded data management to Layers, replace chevron disclosure with +/− indicators.
v2.105.1 - Browse Public Feeds: align AVAILABLE indicators to the right edge in feed result rows.
v2.105.0 - Browse Public Feeds: hierarchical search with country and city priority, geographic result ranking, city/region metadata in feed details.
v2.104.3 - Browse Public Feeds: improved light theme text contrast and visual hierarchy across the entire modal.
v2.104.2 - Activity Log: error messages now start the marquee scroll animation immediately when the log opens from idle state.
v2.104.1 - Browse Feeds: sticky import footer, correct country feed counts, consistent loading states, stricter URL validation.
v2.104.0 - Enable Public Feed Catalog for production; rename "Transit Feeds" to "Import Feed" in nav.
v2.103.0 - Catalog improvements: keyboard typeahead in country dropdown, null-island coordinate fallback for feeds, search prefix matching for country names, and polished feed inspector formatting.
v2.102.9 - Rename left rail "Import" to "Add Data" with database+plus glyph; rename children to Transit Feeds, Public Feed Catalog, Polygons.
v2.102.8 - Remove onboarding spotlight hints; consolidate import modal to a single shared "Static GTFS ZIP feeds only" helper above the URL section.
v2.102.7 - Inspector now defaults to Direction A emphasis on the map when opening a bidirectional route without a pre-selected direction.
v2.102.6 - Fix inspector pattern direction key mismatch; stop count label now stays in sync when switching directions.
v2.102.5 - Unify inspector direction source and no-shape warning box formatting to use consistent margin treatment.
v2.102.4 - Add inline feed type guidance in the import UI; static GTFS zip hint shown in both URL and file import sections.
v2.102.3 - Detect and reject GTFS Realtime imports with clear user-facing guidance instead of confusing generic errors.
v2.102.2 - Redesign Compare control as a single integrated premium pill with icon, label, and On/Off badge; full light and dark mode token set.
v2.102.1 - Report polish: dark mode feed selector fix, smart date defaults, dock-close report, stable toolbar layout, improved chart labels, popover toggle reliability, Compare type persistence, Export always visible, Radar and Stacked Bar chart modes.
v2.102.0 - GTFS import pipeline hardening: partial-feed resilience for incomplete GTFS archives, structured error taxonomy with specific user-facing messages, feed capability detection, capability-aware empty states across tables, Compare UI jump fix, and Export button redesign matching Calendar style.
v2.101.4 - Compact viewport layout redesign for Weekly Service Rhythm: single-row control toolbar, floating popovers for route/type/compare selectors, compact header, reduced chart height - report fits within viewport without scrolling.
v2.101.3 - Report layout refinement: move Compare control inline with Scope row, remove redundant viewport title to reduce scrolling.
v2.101.2 - Final premium polish pass for Weekly Service Rhythm: Overlay (line chart) compare presentation mode, systematic motion polish with staggered entrances and chart fade, context-aware empty states, visual hierarchy refinements, and overlay export support in PNG and PDF.
v2.101.1 - Export quality correction pass: PNG dark mode theme parity, layout fidelity improvements, PDF spacing and classification guard, CSV blank-line cleanup and null safety, disabled export button in no-data branches.
v2.101.0 - Export Expansion for Weekly Service Rhythm: PNG, CSV, and PDF export directly from the report header, with full support for single-series, comparison, and drilldown modes.
v2.100.0 - Anomaly Detection for Weekly Service Rhythm: conservative plain-language findings surface unusual days, large service gaps, concentrated peaks, and exception-aware context from calendar data.
v2.99.0 - Day Drilldown for Weekly Service Rhythm: click any day bar to see hourly trip distribution, peak hour analysis, service gap detection, route contributions, and pattern notes. Comparison-aware drilldown with per-series hourly breakdown.
v2.98.0 - Comparison Mode for Weekly Service Rhythm: compare routes, transport types, or scoped selection vs full feed with grouped bar charts, multi-series tooltips, and comparison insight cards.
v2.97.0 - Rebuild Weekly Service Rhythm into premium interactive analysis module with scope controls, metric switching (Trips, Active Routes, Stops Served, Service Span), time basis selection, and extensible architecture.
v2.96.0 - Premium per-column filter system for Routes and Stops tables with funnel buttons, dropdown menus, active filter chips, and persistent per-table filter state.
v2.95.11 - Fix stop markers still appearing clustered in Inspector route focus mode.
v2.95.10 - INP performance optimizations, JS error visibility improvements, hover responsiveness tuning.
v2.95.9 - Warnings panel standby mode during progressive table loading.
v2.95.8 - Suspend heatmap/corridor visualizations during Inspector focus mode.
v2.95.7 - Service Density legend now only shows for Heatmap, not Corridor Intensity.
v2.95.6 - Auto-switch to Map view when opening Filters, Layers, or Analytics panels.
v2.95.5 - Disable stop clustering in Inspector route view at all zoom levels.
v2.95.4 - Move theme toggle to premium header button; fix Auto time format detection for 24h-locale systems.
v2.95.3 - Remove "Zoom into any area faster" from Guides menu.
v2.95.2 - Fix 7 map/filter issues: demand responsive icon, Inspector stop visibility, zoom-to-feed closes Inspector, Inspector far-zoom keeps colored icons, hub icons respect filter, stops panel scroll.
v2.95.1 - Fix extended route types showing Bus icon on map; add Air Service glyph; multi-type stops render separate markers per transport type.
v2.95.0 - Comprehensive Stops Health Taxonomy with 23 rules covering GTFS spec compliance, hierarchy validation, coordinate plausibility, text quality, and edit-safe suggested fixes.
v2.94.4 - Add dynamic locale columns to Routes table for translated route long names from translations.txt.
v2.94.3 - Add comprehensive extended GTFS route types (100-1799) with unique colors, names, and icon glyphs for European feeds.
v2.94.2 - Add Transfer Partners and Transfer Type columns to Stops table with full transfer detail from transfers.txt.
v2.94.1 - Stops table fixes: center-align columns, reorder expander, shorten Lat/Lon headers, hub arrow indicator, remove actions column.
v2.94.0 - Add Stops table to Tables workspace with hub hierarchy, translations, routes served, and health indicators.
v2.93.11 - Fix text selection in table cells, search nav inline layout, and make all columns toggleable.
v2.93.10 - Add shapes count and reorder feed data strip in Tables view to Stops, Routes, Shapes, Trips.
v2.93.9 - Premium coachmark redesign for Shift+drag zoom hint with keycap rendering and elegant entrance animation.
v2.93.7 - Remove all filter logic from Calendar view; calendar now shows unfiltered feed data.
v2.93.6 - Accept compact time input (e.g. "0900") in Service Time filter and auto-format to "09:00".
v2.93.5 - Fix hub popup route badges showing dark fallback color instead of golden angle palette.
v2.93.4 - Style inferred-direction warning as amber hint pill matching no-shapes warning.
v2.93.3 - Smooth graduated loading progress for large feeds with byte-based tracking and UI interpolation.
v2.93.2 - Scope map search bar to Map view only; hide in Calendar and all non-Map workspaces.
v2.93.1 - Stop Hub system: consolidate parent stations into single markers with multi-modal stacked icons, adaptive dot mode, direction-aware route chips, and hub-aware focus mode.
v2.92.4 - Zoom-dependent cluster radius for fewer, cleaner clusters at far and mid zooms.
v2.92.3 - Refine far-zoom stop cluster appearance with compact, low-opacity icons at region-level zoom.
v2.92.2 - Validate ?feed= deep link parameter and show error for empty or non-HTTP URLs.
v2.92.1 - Polish Quick Start CTA, add inspector hint, add 1.5s hint delay, and hint priority ordering.
v2.92.0 - Upgrade Learn to Guides with compass icon, progressive hint toasts, and Quick Start card polish.
v2.91.9 - Add GTFS Quick Start Guide as default contextual recommendation with "Start here" badge.
v2.91.8 - Change Shift-zoom lens label from "Zoom to View" to "Zoom to Area".
v2.91.7 - Add 5-minute re-suggestion for uninteracted guides; cancel on user dismiss or click.
v2.91.6 - Suppress contextual guides during loading; show with 2s delay after import completes.
v2.91.5 - Switch calendar to newly imported feed on Zoom to feed; show dock coverage dot without opening calendar first.
v2.91.4 - Refine coverage card messaging with exact dates, days-remaining, and singular/plural handling.
v2.91.3 - Redesign calendar coverage warning as premium status card with dock attention dot.
v2.91.2 - Show feed coverage expiry warning in calendar views with days-remaining countdown.
v2.91.1 - Add Auto time format detection from browser locale settings.
v2.91.0 - Add contextual Learn GTFS guide layer with in-app recommendations and nav panel.
v2.90.3 - Fix tripTimeRanges crash on partial feeds; improve INP with deferred filter render and cached layout rects.
v2.90.2 - Focus Lens visual polish: subtle dual-layer outer glow, refined 6px radius, 0.5px inner highlight, glass pill label, and global Shift-held text selection prevention.
v2.90.1 - Fix zoom control hover/active backgrounds becoming invisible due to low-opacity --accent-light token; replaced with opaque tinted values for both light and dark mode.
v2.90.0 - Focus Lens: custom precision zoom overlay (Shift+drag) with dual-layer border, fade animation, micro-label, drag threshold, and clean Escape/Shift-release cancellation.
v2.89.0 - Premium map navigation package: polished zoom controls, smooth animated transitions, Shift+drag box zoom, smart stop focus, and keyboard zoom support.
v2.88.38 - Show file size below stats panel in single-feed loading card completion state.
v2.88.37 - Center-align body text in post-load guidance card.
v2.88.36 - Center-align Zoom to feed and Dismiss buttons in post-load guidance card.
v2.88.35 - Fix: second feed import broken when loading card completion state persisted after 8s auto-dismiss; _resetLoadingCard now always called on new job start.
v2.88.34 - Enrich bug report debug log: add full activity log (all session notifications), full performance log (was capped at 20), and per-feed source type, URL, and file size.
v2.88.33 - Show loaded feed name in loading card completion state (e.g. "MBTA loaded").
v2.88.32 - Increase single-feed loading card completion hold from 6s to 8s.
v2.88.31 - Show stops, routes, trips, shapes, and file size after import: in loading card (8s hold for first feed), post-load guidance card (multi-feed), importer modal feed rows, and activity log.
v2.88.30 - Remove staggered wave delay from spotlight animation; all chips pulse simultaneously.
v2.88.29 - Add staggered wave delay (120ms per chip) to spotlight animation for fluid left-to-right effect.
v2.88.28 - Animate all route chips with spotlight halo, not just the first one.
v2.88.27 - Remove chevron from route chips; increase spotlight pulses to 3 (stop card) and 2 (inspector).
v2.88.26 - Replace chevron hint with spotlight halo animation on route chips for improved interaction discoverability.
v2.88.25 - Add chevron affordance and progressive hint to route chips in stop popups and inspector.
v2.88.24 - Render temporary dashed fallback polyline on map for shapeless routes in Inspector focus mode.
v2.88.23 - Support patterns for routes without shapes by grouping trips by stop sequence; fix focus mode hiding all stops for shapeless routes.
v2.88.22 - Add missing-shape indication in Route Inspector for routes without geometry.
v2.88.21 - Static zoom-adaptive direction chevron arrows with improved visibility, correct orientation, and robust zoom recomputation.
v2.88.20 - Replace direction system with premium soft-flow chevron arrows and terminal markers in Inspector focus mode.
v2.88.18 - Fix direction pulse invisible color by handling HSL color strings from route color map.
v2.88.17 - Improve direction pulse visibility with wider glow and stronger contrast.
v2.88.16 - Add animated directional flow overlay on active pattern in Inspector focus mode.
v2.88.15 - Fix route popup chip not updating focus mode: _openRouteInspector now sets selectedRouteKey before entering focus mode.
v2.88.6 - Optimize focus mode: hide/show stops via layer toggle (preserve markers); instant exit without full re-render.
v2.88.5 - Fix Inspector close: force full viewport re-render to restore all routes and stops cleanly.
v2.88.4 - Fix direction highlight with persistent selectedRouteDirKey; remove entire arrow rendering system (decorators, pane, tokens, CDN plugin).
v2.88.3 - Fix: highlightRoute now direction-aware even outside focus mode; restore hover delay to 75ms.
v2.88.2 - Fix duplicate click from overlapping casing+core: 100ms click debounce prevents double-firing.
v2.88.1 - Wider route hit area: casings now interactive with same handlers; hover enter delay reduced to 30ms.
v2.88.0 - Rewrite stop filtering: _refreshFocusedStops removes all stops and re-adds only allowed ones via standard pipeline. Eliminates duplicates and cross-direction leaks.
v2.87.14 - highlightRoute now respects focus mode direction filter: only styles/overlays the focused direction.
v2.87.13 - Fix direction switch stop filtering: preserve route-level hidden stops; use pattern store as primary stop source.
v2.87.12 - Fix fitBounds padding: use paddingTopLeft/paddingBottomRight instead of 4-value array (Leaflet expects 2-value Point).
v2.87.11 - Zoom to pattern/direction bounds on Inspector open; add _fitMapToFocusedRoute fallback.
v2.87.10 - Fix pattern zoom: use pattern store stop coordinates as primary bounds source for reliable fit.
v2.87.9 - Fix: clear highlight overlay on focus enter; add stop-coordinate fallback for pattern zoom; rename PLACES to LOCATIONS.
v2.87.8 - Fix zoom to use full pattern geometry; re-hide non-selected direction after viewport re-render.
v2.87.7 - Pattern selection zooms to pattern bounds with Inspector-aware padding.
v2.87.6 - Fix pattern switching flash (instant style change); use driving side detection for directional offset (LHD flips).
v2.87.5 - Fix focus mode map click: switch pattern in Inspector instead of re-selecting route; prevent other direction from reappearing.
v2.87.4 - Fix focus mode: capture dirKey before Inspector consumes it; skip route picker in focus mode for direct selection.
v2.87.3 - Fix stop filtering: viewport diff uses pattern-level stops when active; pattern switching preserves route-level hidden stops.
v2.87.2 - Remove pulse glow flash; add pattern store fallback for stop filtering; auto-select Primary pattern on direction switch with per-direction memory.
v2.87.1 - Fix stop filtering in focus mode: sync _vpRenderedStopKeys/_vpRenderedRouteKeys with hidden entries to prevent viewport diff conflicts.
v2.87.0 - Inspector focus: hide non-selected direction, filter stops to direction/pattern, fade Layers panel, hover-preview stops, direction switching.
v2.86.1 - Fix route picker showing same color for both directions; compute direction color inline if not in map.
v2.86.0 - Inspector route focus mode: hide all non-inspected routes and stops; show only focused route with pattern switching; exit via close/ESC/button.
v2.85.0 - Focus stop clustering on active pattern: only active pattern's stops shown in clusters when a pattern is selected.
v2.84.3 - Preserve pattern emphasis across viewport changes; prevent highlightRoute from overwriting active pattern selection.
v2.84.2 - Clear highlight overlay when pattern emphasis activates so per-pattern styling is visible on map.
v2.84.1 - Inspector opens with pattern context only when user arrived via specific pattern; no forced primary auto-select.
v2.84.0 - Pattern-aware Inspector rendering: active pattern always hero line with dark casing; auto-select primary on open.
v2.83.6 - Stop opening route info popup when clicking a pattern row in Inspector.
v2.83.5 - Fix selection to apply dark casing to all base polylines and sync offset on highlight overlays.
v2.83.4 - Direction-level hover: only the hovered direction gets highlighted, not both directions.
v2.83.3 - Fix hover to highlight both directions; add 75/120ms debounce; increase offsets to ±3/±4px.
v2.83.2 - Restore multi-pattern rendering when ROUTE_PATTERNS enabled; offset applies only to primary patterns.
v2.83.1 - Promote active route z-order so hovered/selected routes always render above other routes.
v2.83.0 - Directional offset rendering: 1 representative per direction, offset on hover/select for direction clarity.
v2.82.3 - Remove global route dimming on hover/selection; only the active route changes visually.
v2.82.2 - Fix hover to use dark casing on focused route only; remove white highlight glow; align dimming opacities.
v2.82.1 - Switch route casings to dark tone in both themes for better depth and separation.
v2.82.0 - Redesign route rendering with three-tier visual hierarchy: calm default, focused hover with dimming, hero selection state. Arrows only on focused route.
v2.81.5 - Switch route rendering from Canvas to SVG for Clarity and PostHog session recording compatibility.
v2.81.4 - Filter out synthetic/canonical patterns with no real calendar coverage from pattern derivation.
v2.81.3 - Fix patterns with synthetic service IDs showing as Unknown; inherit service days from primary pattern.
v2.81.2 - Remove feed attribution text from Layers panel to free space for action buttons.
v2.81.1 - Remove GTFS Stop ID field from Inspector stop details.
v2.81.0 - Group route patterns by service days in Inspector with adaptive percentage formatting.
v2.80.3 - Refine Inspector layout: remove main scroll, only stop list scrolls; compact metadata and pattern rows.
v2.80.2 - Show "No routes found for this stop in the current feed" hint for orphan stops in popup and inspector.
v2.80.1 - Move Patterns section above stop list in Inspector, rename stop list heading to "Stops in this pattern".
v2.80.0 - Pattern-aware inspector selection: clicking a pattern row moves the selection dot, updates the stop list to show that pattern's stops, and opening inspector from a specific polyline pre-selects the clicked pattern.
v2.79.3 - Add premium pulse glow animation when clicking pattern rows in the inspector.
v2.79.2 - Fit map viewport to clicked pattern in inspector for instant navigation to pattern geometry.
v2.79.1 - Refine pattern visualization with improved style hierarchy, overlap denoising, smooth emphasis transitions, and hover-to-map interaction from inspector pattern rows.
v2.79.0 - Pattern-aware route visualization with multi-pattern map rendering, pattern-responsive stop interactions, and detailed pattern info in route and stop cards.
v2.78.0 - Add direction-aware route pattern derivation layer (hidden, data-only).
v2.77.7 - Add "No route shapes nearby" hint to stop info card when associated routes lack nearby shape geometry.
v2.77.6 - Fix Inspector opening wrong direction tab when selecting a route from a stop info card.
v2.77.5 - Separate Layers from Filters: route type and agency filters no longer mutate Layers checkbox state.
v2.77.4 - Skip analytics initialization on localhost, local network, dev mode, and opt-out sessions.
v2.77.3 - Fix route pill text color to white for better contrast on dark route backgrounds.
v2.77.2 - Defer auto-zoom to feed completion for instant map rendering, fix UI freeze during feed replacement, and remove redundant example feed label on first visit.
v2.77.0 - Add 2-feed session limit with premium replacement modal for controlled multi-feed management.
v2.76.1 - Fix inspector stop dots to use direction-specific route colors, fix Activity Log detail marquee on hover, and fix example feed loading for large GTFS files.
v2.76.0 - Replace demo feed with MBTA Boston and Toronto TTC example feeds; add data attribution, deep-link support, and legal updates.
v2.75.2 - Enrich analytics events with context properties, add stops_filter_used, filters_cleared, and feedback intent tracking.
v2.75.1 - Add analytics tracking (Cloudflare Web Analytics, Clarity, PostHog) with first-wave product events.
v2.75.0 - Add ?demo=true URL parameter to auto-load demo feed from landing page.
v2.74.7 - Update Analytics & Reports title and description copy.
v2.74.6 - Switch calendar insights showcase to calendar screenshot and add Analytics & Reports showcase block.
v2.74.5 - Consolidate calendar insights into service patterns showcase and remove duplicate deep-dive section.
v2.74.4 - Refine landing page typography, capability strip alignment, copy tightening, and contrast hierarchy.
v2.74.3 - Polish landing page composition, add demo CTA, product screenshot frames, and copy tightening.
v2.74.2 - Replace landing page CSS mockups with real app screenshots for light and dark themes.
v2.74.1 - Correct open-source misrepresentation; update copyright to TransitLens proprietary wording.
v2.74.0 - Upgrade landing page with product showcase, deep-dive sections, and legal page routing fix.
v2.73.0 - Add public landing page for transit-lens.com with product overview, features, and CTA sections.
v2.72.10 - Restore feedback submission handler with Resend email integration for bug reports and feature requests.
v2.72.9 - Add legal protection clauses: Transit Data Disclaimer, Service Availability, No Affiliation, GTFS Data Usage, and strengthened Limitation of Liability.
v2.72.8 - Update legal section branding to TransitLens across Terms, Privacy, License, Notices, and Security files.
v2.72.5 - Make nav rail and side panel overlay the map so map tiles stay fixed when sidebar expands or collapses.
v2.72.4 - Service Rhythm polish: scaleY bar entrance animation, gradient bar depth, classification tooltips, day-type grouping indicator, weekly average baseline, report sidebar interaction fix, Back button removal.
v2.72.2 - Add service level bands, weekday vs weekend comparison, rhythm classification badge, and bar entrance animation to Service Rhythm report.
v2.72.1 - Fix heatmap Service Density legend showing on non-map workspaces; now hidden on Calendar, Timeline, Table, and Reports views.
v2.72.0 - Upgrade Service Rhythm report: premium CTA button, feed switcher, back navigation, insight summary cards, wider chart with hover effects, disabled state when no feeds loaded.
v2.71.1 - Refine Insights panels: auto-switch to MAP on overlay enable, move Service Rhythm to Reports as full viewport report, simplify card UI.
v2.71.0 - Reorganize sidebar: add Insights parent menu with Analytics and Reports submenus; extract Corridor Intensity as standalone analytics toggle.
v2.70.7 - Fix Calendar Day view route colors to match Filters Routes list pipeline, including bi-directional dual-color gradients.
v2.70.6 - Fix Activity Log row layout: replace pseudo-column structure with single fluid content area for natural text flow and better truncation.
v2.70.5 - Improve large feed import zoom: start at zoom 12 (close view) so routes don't appear to load gradually; expand threshold to include route count > 3,000.
v2.70.4 - Add staged analysis sweep animation and status label to calendar skeleton loading for a polished loading animation.
v2.70.3 - Keep existing feed visible during new import; allow switching between loaded feeds and importing feed via dropdown.
v2.70.2 - Show importing feed name in calendar skeleton header and auto-select newly imported feed on completion.
v2.70.1 - Fix calendar skeleton not appearing during feed import; show full skeleton on import start instead of only during synchronous render.
v2.70.0 - Add shimmer skeleton loading states for all calendar scopes (year, month, day) with scope-aware transitions.
v2.69.6 - Fix service-level classification to use baseline-relative thresholds; widen demo feed route spread (54 weekday, 35 Saturday, 20 Sunday) for clear heatmap differentiation.
v2.69.5 - Enhanced demo GTFS feed with realistic route-count variation by day of week: 52 weekday, 48 Saturday, 38 Sunday routes.
v2.69.4 - Fix tooltip baseline label: now shows "Routes vs weekday average" when Routes metric is active.
v2.69.3 - Exception delta display is now metric-aware: shows route counts when Routes metric is selected, trip counts when Trips is selected.
v2.69.2 - Fix missing Metro glyph in Calendar day view, equalize stat box sizes, use normalized SVG for transport icons.
v2.69.1 - Fix month view reset on theme toggle, add exception legend tooltips, fix HeatmapView monthFilter preservation on theme change.
v2.69.0 - Calendar UI/UX polish: metric toggle in year view, legend tooltips, coverage color update, exception trip delta display, service normalization fix.
v2.68.1 - Fix Layers stop dimming/counts to only reflect Filters → Stops tab filters; route-tab filters (search, selection, Service Time) no longer leak into stop Layers state.
v2.68.0 - Layers panel reflects active filter state: filtered-out routes and stops are visually dimmed, header counts update for all filter types, stops remain independent of route-group filters.
v2.67.0 - Enhanced demo GTFS feed: all 6 service levels, calendar exceptions on US holidays, extended date range (Feb 2026-May 2027), realistic route shapes and trip schedules.
v2.66.1 - Fix UI freeze and world-view zoom when importing a feed in Calendar view then switching to Map.
v2.66.0 - Calendar polish: polished back-navigation pills, Day view badge fix, dynamic Start of Week reactivity. Reports: Service Rhythm chart.
v2.65.0 - Calendar heatmap UX: percentile-based classification with Peak level, feed selector cleanup, inline no-results banner, coverage color update, tooltip refinements, larger exception indicators.
v2.64.0 - Calendar UI refinement: feed context redesign, transport-icon filter tags, weekend banding, clear-all action, heatmap polish.
v2.63.1 - Change Feed Coverage marker colors to Cyan/Coral.
v2.63.0 - Add single-feed Calendar scope with feed selector dropdown.
v2.62.6 - Today indicator: blue pill badge (no ring), feed-timezone-aware date computation.
v2.62.5 - Enhanced Today indicator with amber gold ring and day-number pill badge for better visibility.
v2.62.4 - Fix Month view Feed Coverage markers showing on first/last of month instead of actual feed boundaries.
v2.62.3 - Refactor Calendar filter strip to show individual removable tags per active filter value with summary tags and empty state.
v2.62.2 - Smooth viewport-center transitions to eliminate jitter when sidebar opens/closes, rename legend Coverage to Feed Coverage.
v2.62.1 - Viewport-anchor calendar content so it never shifts when the sidebar opens/closes, center-align navigation row, and align Table/Timeline placeholders to same position.
v2.62.0 - Calendar workspace cleanup: removed Service Rhythm and Add to Report, added Export PDF and Print with clean calendar layouts, metric simplified to Trips/Routes with Month-only toggle, filter tag prefixes removed, improved month cell typography.
v2.61.0 - Visual refinement for Calendar Heatmap: analytical teal/violet palette, denser year grid layout, refined micro-card cells, repositioned exception markers, polished legend with 3 groups, refined tooltips, SVG transport icons in day view.
v2.60.2 - Calendar Heatmap UI refinement: full-viewport year grid, clickable month labels for drill-down, back-to-year navigation, day-number cells, refined cell hover elevation, route-color backgrounds in day view, and legend spacing above dock.
v2.60.1 - Calendar unification: remove Classic Calendar mode, add Heatmap day drill-down with metric values in month cells, tighten year-grid for no-scroll fit, two-letter weekday labels, centered month names, and legend repositioned above dock.
v2.60.0 - Calendar Heatmap redesign: 12-panel small-multiples year view, 5-row header with active filter chips, multi-hue color palette, corner triangle exception markers, coverage boundary indicators, and polished tooltip/legend.
v2.59.1 - Calendar visual refinement: compress header from 5 rows to 3, widen heatmap/rhythm layouts, add proper 7-column month calendar grid, and increase Service Rhythm chart proportions.
v2.59.0 - Calendar workspace refactor: remove Month Grid, add secondary scope selectors (Year/Month/Day), 5-row header with navigation controls, Classic Calendar Month and Day views, info icons, and month-scoped Heatmap/Rhythm modes.
v2.58.0 - Add metric-aware service-level analysis, calendar_dates exception markers with two-row legend, and metric-responsive Service Rhythm chart.
v2.57.0 - Add service-level classification heatmap with baseline deviation tooltips and new Service Rhythm bar chart view for weekday service pattern analysis.
v2.56.2 - Heatmap view visual polish: wider canvas, improved cell geometry, stronger color ramp, refined month/weekday labels, legend alignment, and tooltip spacing.
v2.56.1 - Calendar aggregator: content-based hidden route cache key, fast-path service-level indexing for unfiltered aggregation.
v2.56.0 - Calendar heatmap engine: real GTFS calendar aggregation with quantile color scaling, exception tracking, today indicator, enhanced tooltips, and filtered-empty states.
v2.55.16 - Update empty-state message from "Notification log" to "Activity log".
v2.55.15 - Refine app footer: dark text on light map views, light text on dark non-map views, workspace-aware via body data attribute.
v2.55.14 - Fix app footer visibility on light map: use frosted-glass pill background in both themes.
v2.55.13 - Rename Notifications Log to Activity Log, hide VIEWS dock label, and fix footer visibility in light mode.
v2.55.12 - Fix feed import bug: modal overlay no longer blocks clicks during close animation, and auto-zoom defers when map is hidden.
v2.55.11 - Remove Calendar-local import ownership: import is now global-only via Import menu, progress surfaced through Notifications.
v2.55.10 - Add global import state and header indicator: preserve loading UI across workspace switches during feed imports.
v2.55.9 - Polish Calendar loading UX: fix Feed scope line during import, raise card position, and refine text hierarchy.
v2.55.8 - Add Feed Loading Card to Calendar: centered card with spinner for first-feed import, compact indicator for subsequent feeds.
v2.55.7 - Refine Calendar skeleton: view-aware layouts per mode, compact heatmap, distinct month grid blocks, classic calendar grid, and subtle opacity pulse.
v2.55.6 - Add skeleton loading states to Calendar workspace with mode-aware placeholders and subtle pulse animation.
v2.55.5 - Polish Calendar micro-details: disabled button contrast, tighter metric dropdown, and refined feed row typography.
v2.55.4 - Rebuild Calendar segmented control with locked geometry, direct active-state pill, and no sliding indicator.
v2.55.3 - Fix Calendar view selector overlap, add View label, and harden segment control flex layout.
v2.55.2 - Polish Calendar header alignment, segment control sizing, two-tone feed status, and empty state centering.
v2.55.1 - Refine Calendar UX: 3-row header layout, metric dropdown, Export/Report buttons, and improved empty state.
v2.55.0 - Add Calendar workspace with heatmap view, per-date trip/route/service aggregation, and filter-aware metrics.
Earlier releases omitted.
© 2026 TransitLens. All rights reserved.