Colour effort by zone, and read distance in the rider's units
A watt is a fact; a zone is what it costs you. The biggest number on the ride screen was the same shade of white at 90 W and at 400 W, which is a thing no training app has done in fifteen years. Zones, with two rules: - **No reference, no zone.** An unset FTP draws the plain number. A zone measured against a guessed threshold would paint every ride with a confident lie. - **Colour never carries it alone.** "Z4" renders beside the swatch, so the meaning survives a colour-blind rider, a phone in direct sun and a black-and-white screenshot. Read off the rolling average, not the instantaneous watts: at 4 Hz the raw figure crosses two boundaries every pedal stroke, and a colour that strobes is worse than no colour. Not pedalling is not zone 1. Units are a display preference applied at the last step before the glass. Everything computed, stored and recorded stays SI, so a FIT file never depends on what the screen was set to. `format.ts` takes the unit system as an argument rather than reading a module-level setting — pure functions are what let every readout redraw the moment it changes. The `km` helper is gone rather than left beside `dist`, so there is no second way to format a distance that ignores the preference. Rust's block labels lose their baked-in kilometres. The block already carries start_x and end_x and the frontend renders that span in the rider's units; a kilometre in the text sat inside a sentence saying miles everywhere else. Also on the ride screen: - The gradient gets a wedge beside the number. A signed decimal has to be read; a slope is seen. Exaggerated and clamped, because a true-scale 6% is indistinguishable from 3% at 40 px wide. - What is coming, from the profile's own block list — "2.1 km at 12% in 460 m". The chart says where the rider is; what is about to happen is what decides whether to shift now. The data was already computed Rust-side and thrown away here. Close in, the small unit reads better than a fraction of the big one. - Mode and target merge into one chip. They are a single fact, and splitting them spent a chip of header width repeating the word "target". - The pod chip no longer reports a missing `+` pod while the `−` pod is connected. The `−` pod relays its twin, so that is the intended configuration — the ride screen was calling it a fault, contradicting the device screen two keystrokes away. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -333,13 +333,17 @@ fn block_label(block: &Block) -> String {
|
||||
amplitude,
|
||||
repeats
|
||||
),
|
||||
// No distance in the label. The block already carries `start_x` and
|
||||
// `end_x`, and the frontend renders that span in the rider's own units
|
||||
// (FR-7.5a) — a kilometre baked into the text here would sit inside a
|
||||
// sentence that says miles everywhere else.
|
||||
Block::Segments { segments } => {
|
||||
let d: f64 = segments.iter().map(|s| s.distance_m).sum();
|
||||
format!("{} segments · {:.1} km", segments.len(), d / 1000.0)
|
||||
}
|
||||
Block::Terrain { points } => {
|
||||
let d = points.last().map(|p| p.distance_m).unwrap_or(0.0);
|
||||
format!("terrain · {:.1} km", d / 1000.0)
|
||||
format!(
|
||||
"{} segment{}",
|
||||
segments.len(),
|
||||
if segments.len() == 1 { "" } else { "s" }
|
||||
)
|
||||
}
|
||||
Block::Terrain { .. } => "terrain".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user