Redesign the station listing and move the Best Value controls

Two columns split by a 1pt hairline: identity on the left at a fixed 52%
share so rows line up when scrolling, price and savings on the right,
leading-aligned on one axis with the price dominant. The favourites star
sits under the station logo, freeing the width the pounds-and-pence price
needs to render in full rather than scaled or truncated.

Badges stay tinted rather than filled — BEST VALUE green, CHEAPEST blue,
none for nearest — and the verdict capsule is one shared view across the
listing, the detail sheet and the compact summary, so wording and colour
cannot drift between them.

Best Value's minimum saving moves from Alerts to Settings, Fuel Savings,
beside the fill size and MPG that produce the saving; the Alerts tab reads
it back instead of offering it twice. Its options are now 50p steps to £5
(was 50p/£1/£2/£5), so £2.50 and £3 are reachable, with a test pinning the
step, the ceiling and the store's string round-trip.

The verdict capsule scales to 0.7 before truncating. Measured on a 393pt
screen its copy is handed ~69pt while "Closest station" needs ~90pt, so the
old 0.8 floor could not reach it and rows showed "Closest stati..." instead.

Verified: Debug build clean, swift test 249/249.
This commit is contained in:
FuelBoard Contributor
2026-10-16 13:38:11 +01:00
parent e960ef85c6
commit ff8a1e18d0
11 changed files with 522 additions and 148 deletions
+10 -1
View File
@@ -711,7 +711,16 @@ struct FuelStore {
saveString(mode.rawValue, service: alertsModeKey)
}
static let bestValueAlertThresholdOptionsGBP: [Double] = [0.5, 1.0, 2.0, 5.0]
/// The Best Value gate's options, in 50p steps from 50p to £5. The gate is
/// the same figure for the listing's BEST VALUE badges and for the alert, so
/// its granularity decides how finely the two can be tuned: the old four
/// values (50p, £1, £2, £5) made £2.50 and £3 unreachable, and a whole extra
/// detour's worth of saving sat between £1 and £2. Multiples of 0.5 are
/// exactly representable, so the stored value and the picker's tags cannot
/// drift apart.
static let bestValueAlertThresholdOptionsGBP: [Double] = [
0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0
]
static func loadAlertsBestValueThresholdGBP() -> Double {
if let raw = loadString(service: alertsBestValueThresholdKey),