Restructure:
- FLEET NOW tiles + SLOs + Filters in a horizontal top band; full-width map
- Trip panel moved to a bottom dock that slides up; trips render as a
horizontally-scrollable card strip instead of a vertical right-panel list
Multi-select filter widgets:
- cost_centre + assigned_city are now dropdowns with an "All …" toggle
and per-option checkboxes
- cost_centre options carry a colour swatch matching the marker tint —
the filter doubles as a live colour legend
- Server-side filter still applies when exactly one option is picked;
multi-selection within a widget is narrowed client-side via setFilter
so the existing serve.fn_live_view contract is unchanged
Cost-centre tint always visible:
- circle-color now uses cost_centre_color unconditionally
- operational_state is shown via opacity (moving=1.0 / parked=0.7 /
offline=0.35), keeping colour as a stable identity cue
applyClientFilter() is a new exported helper called by the page after
each refresh to narrow markers by multi-selection state.
Click any vehicle on the map to open a 360px slide-in panel showing:
- reporting time (first ACC_ON of the day)
- day totals: trip count, distance, drive/idle/stop minutes
- per-trip rows with start/end/duration/distance/idling, click to
select; selected trip renders its polyline + animates a marker
along it over 10 seconds
- end-reason badge per trip (work stop, reporting silence, long gap,
day end) with colour-coded accent
- date picker (defaults to today EAT)
- CSV download button → /trips.csv?date=...
Map clicks query rendered features across circle/arrow/label layers and
take the topmost — single click handler, no per-layer duplicates. The
existing hover popup remains untouched.
Wraps #map in #map-container so the panel can absolute-position over
the right side without disturbing the existing left-aside grid layout.
authClient gets a getToken() helper so the CSV download path can attach
the Authorization header for a plain fetch (apiFetch returns JSON only).