Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# CHANGELOG

## 2026-11-10 - Main screen, second pass (Phase 3, session 2, draft)

- One clock on the main screen: the map explorer no longer repeats "Fetched X min ago" under Latest reports. The header already shows the fetch time, and stale, offline and fallback states still show the explorer's own notice with its clock. Recorded history still shows the observation clock.
- Footer: the separate "Source" and "Refresh rate: Regular schedule" tiles are folded into one "Source:" line inside How Border Pulse works. "Regular schedule" said nothing the paragraph above did not. EN/ES.
- Phones (390px) are 153px shorter. No horizontal overflow at 390 or 1280.
- Checks: full `npm test` passes after a prerendered build. Entry bundle 61.97 KB gzip. Before/after 390px screenshots shared in chat.
- Decided from Umami data (see DECISIONS.md 2026-11-10): keep all three filters and Popular border crossings.

## 2026-11-09 - Main screen, first pass (Phase 3, session 1, draft)

- Phones (under 900px): the crossing results list now comes before the map, so the first thing after the controls is a wait. A starred crossing is already sorted first, so returning visitors see their own crossing's wait first. Desktop layout unchanged.
Expand Down
6 changes: 6 additions & 0 deletions DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -559,3 +559,9 @@ The raw `bwtpublicmod` feed saved 2026-11-02 contains both port numbers for Ysle
## 2026-11-09 · Backup data reads the collector feed through a same-origin rewrite

The bundled `/data/crossings.json` only refreshes on Vercel deploys, so as a fallback it could be most of a day old. `vercel.json` rewrites `/data/latest/crossings.json` to the collector's committed file on GitHub `main`, and the client keeps whichever valid backup is newer. Same origin, so no CORS and no new client-side host; GitHub already hosts the code and the Pages rollback. If GitHub is unreachable the bundled copy still serves. "Nothing loaded" is a separate `unavailable` state, never labeled as saved data.

## 2026-11-10 - Keep all three home filters and Popular border crossings (Umami, last 30 days)

- Filters: region tabs logged 83 uses and the crossing-area dropdown 77, out of about 2.35k visits. Both are used at similar rates, so neither is cut. Search use is not tracked (no free text is sent), so there is no evidence either way for it. Revisit only with a no-text search-use count.
- Popular border crossings stays: 3 of the 20 most recent `crossing-open` events came from it, and 98% of visitors arrive from search engines, so its internal links matter more than the repetition costs.
- Context for priorities: the home page is 25% of visitors. The prescription-medication blog post is 41% and crossing pages most of the rest. Main-screen polish reaches a minority of visitors; crossing pages and the blog-to-waits path reach the majority (blog-to-waits: 7 events against 617 post visitors).
2 changes: 1 addition & 1 deletion public/data/aggregates/andrade.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/data/aggregates/brownsville-b-and-m.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/data/aggregates/brownsville-gateway.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/data/aggregates/brownsville-los-indios.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/data/aggregates/calexico-east.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/data/aggregates/calexico-west.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/data/aggregates/columbus.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/data/aggregates/del-rio.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/data/aggregates/douglas-raul-hector-castro.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/data/aggregates/eagle-pass-bridge-i.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"port_number":"230301","name":"Eagle Pass - Bridge I","state":"TX","timezone":"America/Chicago","lookback_days":30,"sample_count":72,"overall_median":30,"overall_best_hour":10,"overall_best_median":20,"by_hour":[{"day":1,"hour":5,"median":30,"samples":1,"window_hours":2,"raw_samples":0},{"day":1,"hour":6,"median":60,"samples":3,"window_hours":2,"raw_samples":0},{"day":1,"hour":7,"median":45,"samples":4,"window_hours":2,"raw_samples":1},{"day":1,"hour":8,"median":30,"samples":5,"window_hours":2,"raw_samples":2},{"day":1,"hour":9,"median":45,"samples":8,"window_hours":2,"raw_samples":1},{"day":1,"hour":10,"median":38,"samples":8,"window_hours":2,"raw_samples":1},{"day":1,"hour":11,"median":30,"samples":9,"window_hours":2,"raw_samples":3},{"day":1,"hour":12,"median":45,"samples":7,"window_hours":1,"raw_samples":1},{"day":1,"hour":13,"median":45,"samples":7,"window_hours":1,"raw_samples":3},{"day":1,"hour":14,"median":45,"samples":6,"window_hours":1,"raw_samples":3},{"day":1,"hour":15,"median":45,"samples":6,"window_hours":2,"raw_samples":0},{"day":1,"hour":16,"median":45,"samples":3,"window_hours":2,"raw_samples":0},{"day":2,"hour":5,"median":30,"samples":1,"window_hours":2,"raw_samples":0},{"day":2,"hour":6,"median":30,"samples":2,"window_hours":2,"raw_samples":0},{"day":2,"hour":7,"median":30,"samples":3,"window_hours":2,"raw_samples":1},{"day":2,"hour":8,"median":30,"samples":5,"window_hours":2,"raw_samples":1},{"day":2,"hour":9,"median":30,"samples":7,"window_hours":2,"raw_samples":1},{"day":2,"hour":10,"median":20,"samples":8,"window_hours":2,"raw_samples":2},{"day":2,"hour":11,"median":25,"samples":6,"window_hours":1,"raw_samples":2},{"day":2,"hour":12,"median":53,"samples":8,"window_hours":1,"raw_samples":2},{"day":2,"hour":13,"median":60,"samples":9,"window_hours":1,"raw_samples":4},{"day":2,"hour":14,"median":60,"samples":8,"window_hours":1,"raw_samples":3},{"day":2,"hour":15,"median":60,"samples":8,"window_hours":2,"raw_samples":1},{"day":2,"hour":16,"median":60,"samples":4,"window_hours":2,"raw_samples":0},{"day":2,"hour":17,"median":120,"samples":1,"window_hours":2,"raw_samples":0},{"day":3,"hour":5,"median":30,"samples":1,"window_hours":2,"raw_samples":0},{"day":3,"hour":6,"median":30,"samples":3,"window_hours":2,"raw_samples":0},{"day":3,"hour":7,"median":30,"samples":6,"window_hours":2,"raw_samples":1},{"day":3,"hour":8,"median":30,"samples":6,"window_hours":1,"raw_samples":2},{"day":3,"hour":9,"median":20,"samples":8,"window_hours":1,"raw_samples":3},{"day":3,"hour":10,"median":20,"samples":10,"window_hours":1,"raw_samples":3},{"day":3,"hour":11,"median":25,"samples":10,"window_hours":1,"raw_samples":4},{"day":3,"hour":12,"median":30,"samples":10,"window_hours":1,"raw_samples":3},{"day":3,"hour":13,"median":45,"samples":10,"window_hours":1,"raw_samples":3},{"day":3,"hour":14,"median":60,"samples":7,"window_hours":1,"raw_samples":4},{"day":3,"hour":15,"median":60,"samples":7,"window_hours":2,"raw_samples":0},{"day":3,"hour":16,"median":60,"samples":4,"window_hours":2,"raw_samples":0},{"day":4,"hour":6,"median":30,"samples":1,"window_hours":2,"raw_samples":0},{"day":4,"hour":7,"median":30,"samples":2,"window_hours":2,"raw_samples":0},{"day":4,"hour":8,"median":30,"samples":3,"window_hours":2,"raw_samples":1},{"day":4,"hour":9,"median":30,"samples":3,"window_hours":2,"raw_samples":1},{"day":4,"hour":10,"median":45,"samples":4,"window_hours":2,"raw_samples":1},{"day":4,"hour":11,"median":60,"samples":4,"window_hours":2,"raw_samples":0},{"day":4,"hour":12,"median":60,"samples":3,"window_hours":2,"raw_samples":1},{"day":4,"hour":13,"median":90,"samples":3,"window_hours":2,"raw_samples":1},{"day":4,"hour":14,"median":90,"samples":3,"window_hours":2,"raw_samples":0},{"day":4,"hour":15,"median":90,"samples":3,"window_hours":2,"raw_samples":1},{"day":4,"hour":16,"median":90,"samples":2,"window_hours":2,"raw_samples":0},{"day":4,"hour":17,"median":90,"samples":2,"window_hours":2,"raw_samples":1},{"day":4,"hour":18,"median":90,"samples":1,"window_hours":2,"raw_samples":0},{"day":4,"hour":19,"median":90,"samples":1,"window_hours":2,"raw_samples":0},{"day":5,"hour":6,"median":20,"samples":1,"window_hours":2,"raw_samples":0},{"day":5,"hour":7,"median":25,"samples":2,"window_hours":2,"raw_samples":0},{"day":5,"hour":8,"median":20,"samples":3,"window_hours":2,"raw_samples":1},{"day":5,"hour":9,"median":13,"samples":4,"window_hours":2,"raw_samples":1},{"day":5,"hour":10,"median":5,"samples":5,"window_hours":2,"raw_samples":1},{"day":5,"hour":11,"median":5,"samples":5,"window_hours":2,"raw_samples":1},{"day":5,"hour":12,"median":5,"samples":6,"window_hours":2,"raw_samples":1},{"day":5,"hour":13,"median":8,"samples":6,"window_hours":2,"raw_samples":1},{"day":5,"hour":14,"median":10,"samples":5,"window_hours":2,"raw_samples":2},{"day":5,"hour":15,"median":15,"samples":4,"window_hours":2,"raw_samples":1},{"day":5,"hour":16,"median":20,"samples":3,"window_hours":2,"raw_samples":0},{"day":5,"hour":17,"median":20,"samples":1,"window_hours":2,"raw_samples":0},{"day":6,"hour":18,"median":180,"samples":1,"window_hours":2,"raw_samples":0},{"day":6,"hour":19,"median":180,"samples":1,"window_hours":2,"raw_samples":0},{"day":6,"hour":20,"median":180,"samples":1,"window_hours":2,"raw_samples":1},{"day":6,"hour":21,"median":180,"samples":1,"window_hours":2,"raw_samples":0},{"day":6,"hour":22,"median":180,"samples":1,"window_hours":2,"raw_samples":0}],"generated_at":"2026-08-20T17:22:35.143Z"}
{"port_number":"230301","name":"Eagle Pass - Bridge I","state":"TX","timezone":"America/Chicago","lookback_days":30,"sample_count":252,"overall_median":60,"overall_best_hour":7,"overall_best_median":30,"by_hour":[{"day":1,"hour":5,"median":30,"samples":6,"window_hours":2,"raw_samples":0},{"day":1,"hour":6,"median":30,"samples":6,"window_hours":1,"raw_samples":0},{"day":1,"hour":7,"median":30,"samples":6,"window_hours":0,"raw_samples":6},{"day":1,"hour":8,"median":38,"samples":8,"window_hours":0,"raw_samples":8},{"day":1,"hour":9,"median":60,"samples":10,"window_hours":0,"raw_samples":10},{"day":1,"hour":10,"median":60,"samples":8,"window_hours":0,"raw_samples":8},{"day":1,"hour":11,"median":90,"samples":8,"window_hours":0,"raw_samples":8},{"day":1,"hour":12,"median":105,"samples":8,"window_hours":0,"raw_samples":8},{"day":1,"hour":13,"median":120,"samples":8,"window_hours":0,"raw_samples":8},{"day":1,"hour":14,"median":120,"samples":10,"window_hours":0,"raw_samples":10},{"day":1,"hour":15,"median":120,"samples":14,"window_hours":1,"raw_samples":4},{"day":1,"hour":16,"median":120,"samples":14,"window_hours":2,"raw_samples":0},{"day":1,"hour":17,"median":120,"samples":4,"window_hours":2,"raw_samples":0},{"day":2,"hour":5,"median":30,"samples":7,"window_hours":2,"raw_samples":0},{"day":2,"hour":6,"median":30,"samples":7,"window_hours":1,"raw_samples":0},{"day":2,"hour":7,"median":30,"samples":7,"window_hours":0,"raw_samples":7},{"day":2,"hour":8,"median":30,"samples":11,"window_hours":0,"raw_samples":11},{"day":2,"hour":9,"median":30,"samples":9,"window_hours":0,"raw_samples":9},{"day":2,"hour":10,"median":45,"samples":13,"window_hours":0,"raw_samples":13},{"day":2,"hour":11,"median":75,"samples":8,"window_hours":0,"raw_samples":8},{"day":2,"hour":12,"median":105,"samples":6,"window_hours":0,"raw_samples":6},{"day":2,"hour":13,"median":120,"samples":7,"window_hours":0,"raw_samples":7},{"day":2,"hour":14,"median":120,"samples":11,"window_hours":1,"raw_samples":4},{"day":2,"hour":15,"median":120,"samples":11,"window_hours":2,"raw_samples":0},{"day":2,"hour":16,"median":180,"samples":4,"window_hours":2,"raw_samples":0},{"day":3,"hour":5,"median":30,"samples":7,"window_hours":2,"raw_samples":0},{"day":3,"hour":6,"median":30,"samples":7,"window_hours":1,"raw_samples":0},{"day":3,"hour":7,"median":30,"samples":7,"window_hours":0,"raw_samples":7},{"day":3,"hour":8,"median":45,"samples":15,"window_hours":1,"raw_samples":4},{"day":3,"hour":9,"median":45,"samples":13,"window_hours":1,"raw_samples":4},{"day":3,"hour":10,"median":45,"samples":13,"window_hours":1,"raw_samples":5},{"day":3,"hour":11,"median":45,"samples":13,"window_hours":1,"raw_samples":4},{"day":3,"hour":12,"median":45,"samples":12,"window_hours":1,"raw_samples":4},{"day":3,"hour":13,"median":45,"samples":12,"window_hours":1,"raw_samples":4},{"day":3,"hour":14,"median":45,"samples":8,"window_hours":1,"raw_samples":4},{"day":3,"hour":15,"median":45,"samples":8,"window_hours":2,"raw_samples":0},{"day":3,"hour":16,"median":45,"samples":4,"window_hours":2,"raw_samples":0},{"day":4,"hour":5,"median":30,"samples":3,"window_hours":2,"raw_samples":0},{"day":4,"hour":6,"median":30,"samples":7,"window_hours":2,"raw_samples":0},{"day":4,"hour":7,"median":30,"samples":7,"window_hours":1,"raw_samples":3},{"day":4,"hour":8,"median":30,"samples":12,"window_hours":1,"raw_samples":4},{"day":4,"hour":9,"median":30,"samples":13,"window_hours":1,"raw_samples":5},{"day":4,"hour":10,"median":45,"samples":13,"window_hours":1,"raw_samples":4},{"day":4,"hour":11,"median":45,"samples":12,"window_hours":1,"raw_samples":4},{"day":4,"hour":12,"median":60,"samples":13,"window_hours":1,"raw_samples":4},{"day":4,"hour":13,"median":60,"samples":14,"window_hours":1,"raw_samples":5},{"day":4,"hour":14,"median":60,"samples":11,"window_hours":1,"raw_samples":5},{"day":4,"hour":15,"median":60,"samples":6,"window_hours":1,"raw_samples":1},{"day":4,"hour":16,"median":60,"samples":6,"window_hours":2,"raw_samples":0},{"day":4,"hour":17,"median":60,"samples":1,"window_hours":2,"raw_samples":0},{"day":5,"hour":5,"median":30,"samples":3,"window_hours":2,"raw_samples":0},{"day":5,"hour":6,"median":45,"samples":7,"window_hours":2,"raw_samples":0},{"day":5,"hour":7,"median":45,"samples":7,"window_hours":1,"raw_samples":3},{"day":5,"hour":8,"median":45,"samples":11,"window_hours":1,"raw_samples":4},{"day":5,"hour":9,"median":90,"samples":12,"window_hours":1,"raw_samples":4},{"day":5,"hour":10,"median":90,"samples":12,"window_hours":1,"raw_samples":4},{"day":5,"hour":11,"median":90,"samples":17,"window_hours":1,"raw_samples":4},{"day":5,"hour":12,"median":90,"samples":9,"window_hours":0,"raw_samples":9},{"day":5,"hour":13,"median":45,"samples":8,"window_hours":0,"raw_samples":8},{"day":5,"hour":14,"median":45,"samples":9,"window_hours":0,"raw_samples":9},{"day":5,"hour":15,"median":45,"samples":10,"window_hours":1,"raw_samples":1},{"day":5,"hour":16,"median":45,"samples":10,"window_hours":2,"raw_samples":0},{"day":5,"hour":17,"median":45,"samples":1,"window_hours":2,"raw_samples":0}],"generated_at":"2026-11-10T18:33:06.031Z"}
Loading
Loading