UI redesign: 8 tickets from the Stitch export analysis
Same shape as docs/v3/: Goal/Context/Design/Implementation/Acceptance/Tests/Risks/Out-of-scope, written before implementing. UI-01: persistent 4-tab shell (StatefulShellRoute) replacing the current push/pop stack rooted at Record, with a single shared background map dimmed behind every tab and no header anywhere. UI-02: animated skeleton map for the no-cache/no-network case, since the map is now a permanent background presence rather than opt-in per screen. UI-03: shared GlassPanel/FloatingPill/PulsingLocationMarker component kit. UI-04: draggable, resizable HUD telemetry widgets with a Settings visibility toggle -- split out from the screen redesign itself since it's a genuinely separate piece of engineering (a small widget-layout system, not a reskin). UI-05: Map HUD/Record screen redesign -- the design north star every other screen ticket restyles toward. UI-06: Plan & Route Planning -- correct in principle, explicitly restyled toward UI-05 rather than copying the Stitch export's drifted styling. UI-07: Rides History -- live dimmed map background (not the mockup's static image), search/filter, real per-ride map thumbnails, and real distinct summary stats (fixing the export's 4-identical-cards generation artifact). UI-08: theme migration to Modern Professional Dark, superseding V3-16's safety-orange direction. README documents the dependency order, and two categories worth keeping separate: what was named explicitly by the person commissioning this (map-on-every-tab, no header, offline skeleton, customizable HUD) versus what the mockups themselves got inconsistent (nav icon count, duplicate summary cards, wrong active-tab highlight) and should not be copied as intentional.
This commit is contained in:
72
docs/ui-redesign/UI-03-glass-component-kit.md
Normal file
72
docs/ui-redesign/UI-03-glass-component-kit.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# UI-03 — Shared floating-glass component kit
|
||||
|
||||
**Depends on** UI-08 (theme tokens) · **Size** M · **Status** Not started
|
||||
|
||||
## Goal
|
||||
Build once, use everywhere: the small set of visual primitives every Stitch screen
|
||||
reuses, so UI-04/05/06/07 compose them instead of each reinventing blur-panel styling.
|
||||
|
||||
## Context
|
||||
All four Stitch exports lean on the same handful of visual patterns repeatedly:
|
||||
glassmorphic panels (`bg-surface/80 backdrop-blur-xl border border-white/10`), a floating
|
||||
centered pill for a compact stat summary, and a pulsing/radar-style location marker.
|
||||
Building these once means every consuming screen ticket is "compose these," not
|
||||
"reimplement blur and border styling a fourth time."
|
||||
|
||||
## Design
|
||||
Three widgets, all pure presentation (no data-fetching, no business logic):
|
||||
|
||||
**`GlassPanel`** — the workhorse. `BackdropFilter` + `ImageFilter.blur` inside a
|
||||
`ClipRRect`, a translucent surface-color fill, a 1px low-opacity border. Takes a `child`
|
||||
and behaves like a styled `Container`. Every floating card, tooltip, and control in the
|
||||
redesign is one of these underneath.
|
||||
|
||||
**`FloatingPill`** — a `GlassPanel` shaped as a horizontally-centered, rounded-full
|
||||
capsule holding a row of labeled stat columns (see Route Planning's Distance/Est. Time/
|
||||
Pins header). Takes a list of `(label, value)` pairs and lays them out with vertical
|
||||
dividers between them, matching the Stitch export exactly.
|
||||
|
||||
**`PulsingLocationMarker`** — the expanding-ring-plus-glow-dot from the Plan/Route
|
||||
Planning exports. A `CustomPainter` or layered `AnimatedContainer`s driving an
|
||||
`AnimationController` in a loop (scale 0.8→1.0, opacity 0.8→0, repeating) — respect
|
||||
`MediaQuery.disableAnimations`/`prefers-reduced-motion` equivalent by falling back to a
|
||||
static dot when animations are disabled system-wide.
|
||||
|
||||
## Implementation
|
||||
1. `lib/src/ui/components/glass_panel.dart` — `GlassPanel`, with blur radius, fill
|
||||
opacity, and border opacity as named constants (not magic numbers scattered per call
|
||||
site), sourced from UI-08's theme tokens.
|
||||
2. `lib/src/ui/components/floating_pill.dart` — `FloatingPill`, built on `GlassPanel`.
|
||||
3. `lib/src/ui/components/pulsing_location_marker.dart` — `PulsingLocationMarker`,
|
||||
wrapping its `AnimationController` lifecycle correctly (dispose on unmount, same
|
||||
discipline as `RideMap`'s existing lifecycle observer from V3-04).
|
||||
4. Widget tests render each in isolation against both themes (if UI-08 keeps a light
|
||||
variant) to catch a black-on-black-style contrast regression early, the same
|
||||
discipline V3-16 established.
|
||||
|
||||
## Acceptance criteria
|
||||
- [ ] `GlassPanel` renders a blurred, bordered, translucent container matching the
|
||||
Stitch reference visually
|
||||
- [ ] `FloatingPill` renders an arbitrary number of stat columns with dividers between
|
||||
them, not hardcoded to exactly three
|
||||
- [ ] `PulsingLocationMarker` animates continuously without leaking its
|
||||
`AnimationController` across widget rebuilds or disposal
|
||||
- [ ] Reduced-motion setting is respected by `PulsingLocationMarker`
|
||||
|
||||
## Tests
|
||||
- Widget: each component renders with representative content and takes a screenshot-
|
||||
comparable snapshot of its structure (no golden files per V3-16's precedent — assert
|
||||
structure/color, not pixels)
|
||||
- Widget: `PulsingLocationMarker`'s animation controller is disposed when the widget is
|
||||
removed from the tree (a `flutter_test` pending-timer/ticker check, mirroring the
|
||||
Drift stream-query keep-alive pattern already documented in `widget_test.dart`)
|
||||
|
||||
## Risks
|
||||
- `BackdropFilter` is one of the more expensive Flutter widgets to composite; stacking
|
||||
several `GlassPanel`s over a live, animating map (per UI-01/UI-02) could visibly cost
|
||||
frame time on lower-end devices. Worth a real-device check once UI-05 assembles them
|
||||
together, not just in isolation.
|
||||
|
||||
## Out of scope
|
||||
The customizable drag/resize telemetry widgets (UI-04) — those consume `GlassPanel` as
|
||||
their visual shell but the interaction logic is a separate, larger ticket.
|
||||
Reference in New Issue
Block a user