diff --git a/docs/ui-redesign/README.md b/docs/ui-redesign/README.md index 686331c..dee99a9 100644 --- a/docs/ui-redesign/README.md +++ b/docs/ui-redesign/README.md @@ -27,6 +27,7 @@ v3 held to. | [UI-06](UI-06-plan-and-route-planning.md) | Plan & Route Planning redesign | M | UI-01, UI-03 | Not started | | [UI-07](UI-07-rides-history.md) | Rides History redesign | M | UI-01, UI-03 | Not started | | [UI-08](UI-08-theme-modern-professional-dark.md) | Theme migration to Modern Professional Dark | S | — | Not started | +| [UI-09](UI-09-monochrome-dark-map-tiles.md) | Monochrome dark map tiles | S | — | Not started | ## Dependencies @@ -38,8 +39,11 @@ UI-01 ──┬──► UI-02 UI-08 ──► UI-03 ──┬──► UI-04 ──► UI-05 ├──► UI-06 └──► UI-07 +UI-09 ──┬──► UI-05 + ├──► UI-06 + └──► UI-07 -no dependencies: UI-01 · UI-08 +no dependencies: UI-01 · UI-08 · UI-09 ``` ## Suggested order @@ -49,15 +53,17 @@ no dependencies: UI-01 · UI-08 2. **UI-08** — theme. Every screen ticket after this needs the palette settled once, not patched per-screen. Supersedes V3-16's safety-orange direction — see that ticket's note. -3. **UI-02** — skeleton map. Small, and exercises the background-map plumbing UI-01 just +3. **UI-09** — dark map tiles. Small, no dependencies, and every screen with a map looks + wrong without it regardless of how correct the HUD chrome on top is. +4. **UI-02** — skeleton map. Small, and exercises the background-map plumbing UI-01 just built while it's fresh. -4. **UI-03** — the component kit (`GlassPanel`, `FloatingPill`, `PulsingLocationMarker`). +5. **UI-03** — the component kit (`GlassPanel`, `FloatingPill`, `PulsingLocationMarker`). Build once, consumed by every screen ticket. -5. **UI-04** — the customizable HUD widget system (drag/resize/persist layout, a +6. **UI-04** — the customizable HUD widget system (drag/resize/persist layout, a visibility toggle in Settings). This is its own ticket, not folded into UI-05, because drag-and-resize-with-persisted-layout is a genuinely separate piece of engineering from "redesign the record screen" — a small widget-layout editor in miniature. -6. **UI-05 / UI-06 / UI-07** — the three screen redesigns, in any order once everything +7. **UI-05 / UI-06 / UI-07** — the three screen redesigns, in any order once everything above is done. Each is independently shippable. ## Things named explicitly by the person who commissioned this, not inferred from the mockups @@ -77,6 +83,10 @@ no dependencies: UI-01 · UI-08 mockup's tap-to-expand interaction is a fixed layout with one temporary focus state; this goes further — the rider chooses the layout and which stats exist on screen at all, and it persists. +- **The map itself is monochrome dark** (UI-09) — today's default OSM tan/cream tiles are + nothing like the mockups regardless of how correct the HUD chrome on top is. A real + tile-provider decision, not a color filter thrown on as an afterthought — see that + ticket for the trade-off against just filtering OSM's existing tiles. ## The Map screen is the design north star diff --git a/docs/ui-redesign/UI-09-monochrome-dark-map-tiles.md b/docs/ui-redesign/UI-09-monochrome-dark-map-tiles.md new file mode 100644 index 0000000..937dd31 --- /dev/null +++ b/docs/ui-redesign/UI-09-monochrome-dark-map-tiles.md @@ -0,0 +1,98 @@ +# UI-09 — Monochrome dark map tiles + +**Depends on** nothing · **Size** S · **Status** Not started + +## Goal +Replace the tan/cream default OpenStreetMap raster style with a monochrome dark map, so +the map actually looks like it belongs in a dark-mode HUD instead of a light basemap +punched through a dark overlay. + +## Context +`RideMap`, the Plan/Route Planning canvas, and every Stitch mockup all assume a dark or +near-monochrome map underneath the HUD. Today's `TileLayer` (`ride_map.dart`) points at +`tile.openstreetmap.org`, OSM's standard light/tan default style — the actual on-device +result is nothing like the mockups, regardless of how dark the chrome on top of it is. + +This affects every screen that shows a map (Map HUD, Plan, Route Planning, and UI-01's +dimmed background on every other tab), so it's worth settling once, early, rather than +each screen ticket discovering the same mismatch independently. + +## Design +Two real options, not one obvious answer: + +**Option A — switch tile provider to CARTO's "Dark Matter" basemap.** +`https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png` (subdomains a-d, retina +`{r}` variant available, max native zoom 20). Purpose-built dark, desaturated/monochrome +cartography — closest to the mockups with the least engineering. Free for reasonable +usage same as OSM's own tiles, but it's a **different third party with its own usage +policy and attribution requirement** ("© OpenStreetMap contributors © CARTO", not just +OSM's own attribution) — a real dependency to add, not a style tweak. + +**Option B — keep OSM tiles, apply a color filter client-side.** Wrap `TileLayer` in a +`ColorFiltered` widget using a `ColorFilter.matrix` that desaturates and inverts/darkens +the tan basemap into a monochrome dark look. No new third party, no new attribution, and +V3-11's offline tile cache keeps working against the exact tiles it already knows about +— but the result is a filtered light map, not tiles actually designed for dark +presentation, and will read as slightly "off" next to CARTO's purpose-built version +(road/building contrast tuned for light backgrounds doesn't always invert cleanly). + +**Recommendation: Option A.** The mockups' whole aesthetic depends on the map itself +being dark, not just tinted dark, and CARTO's dark tiles are a well-established, free, +no-API-key option already widely used in the Flutter/Leaflet ecosystem for exactly this. +The added attribution line and a second host to trust are a small, one-time cost. + +**V3-11 interaction:** the offline tile cache (`FileTileCache`/`CachedTileProvider`) is +already keyed by `TileKey(z, x, y)` with no provider-specific data baked in — but that +means a cache built against OSM tiles and a cache built against CARTO tiles are +**indistinguishable to the cache** despite being visually different. Switching providers +without a plan here would silently serve stale, wrong-looking cached OSM tiles once +CARTO's URL is live. This needs a cache-busting or provider-tagging fix as part of this +ticket, not a separate one — see Implementation. + +## Implementation +1. Add a `provider`-qualified cache key (or a cache-version bump that invalidates + existing V3-11 cache contents wholesale) so switching tile sources can't silently + mix cached tiles from two visually different sources. +2. Update `RideMap`'s `TileLayer` (and the Route Planner's separate `TileLayer` instance + — see `route_planner_screen.dart`) to CARTO's dark tile URL template, correct + `subdomains`, and `maxNativeZoom: 20`. +3. Update the attribution requirement — check whether `flutter_map`'s + `RichAttributionWidget`/`AttributionWidget` is in use anywhere already, or add one; + OSM-only attribution is no longer sufficient once CARTO tiles are in the mix. +4. Update `tileUserAgent`/any OSM-specific comments in `ride_map.dart` that assumed OSM's + tile servers specifically (the "respect OSM's usage policy" reasoning still applies in + spirit to CARTO's own policy, but the specific server being addressed changes). +5. Re-verify V3-11's tile math/download flow still works end-to-end against the new URL + template (tile enumeration and caching are provider-agnostic already; only the fetch + URL construction needs updating). + +## Acceptance criteria +- [ ] The map renders in a dark, desaturated/monochrome style matching the Stitch + mockups, not OSM's default tan basemap +- [ ] Correct attribution for both OpenStreetMap and CARTO is shown wherever the map is + shown +- [ ] Switching tile providers does not silently serve stale, visually-mismatched + cached tiles from before the switch (V3-11's cache is invalidated or + provider-tagged) +- [ ] Both `RideMap` and the Route Planner's independent `TileLayer` are updated + consistently — one dark style everywhere, not just on the screens that happened to + get touched first + +## Tests +- Existing `ride_map`/route-planner widget tests updated for the new tile URL and still + passing +- Unit: cache-key/versioning change is exercised the same way V3-11's eviction tests + are — a cache built under the old scheme does not get served for the new provider + +## Risks +- **A second third-party tile host is a real dependency, not a free color swap** — its + own usage policy, its own risk of being blocked if misused, and its own attribution + obligation. Treat it with the same care V3-11 already applies to OSM (rate-limit + respecting, no bulk prefetch, real user agent). +- If CARTO's free tier ever proves insufficient or is discontinued, Option B (a color + filter over OSM tiles) is the fallback with no new third-party dependency — worth + keeping in mind as a documented Plan B, not re-deriving from scratch later. + +## Out of scope +A fully custom/self-hosted vector tile style — much larger scope, and not needed to hit +"looks like the mockups" today.