diff --git a/src/index.html b/src/index.html index 69ca005..2124f1d 100644 --- a/src/index.html +++ b/src/index.html @@ -56,17 +56,15 @@
мощность - — - W - - + — + — +
каденс - — - rpm - - + — + — +
чсс diff --git a/src/main.js b/src/main.js index c853c17..282a888 100644 --- a/src/main.js +++ b/src/main.js @@ -153,11 +153,11 @@ listen("telemetry", (event) => { const t = event.payload.telemetry; if (t.Power) { actualWatts = t.Power.watts; - setMetric("power-value", actualWatts); + setMetric("power-value", `${actualWatts} W`); updatePowerDeviation(); } else if (t.Cadence) { actualCadence = Math.round(t.Cadence.rpm); - setMetric("cadence-value", actualCadence); + setMetric("cadence-value", `${actualCadence} rpm`); updateCadenceDeviation(); } else if (t.HeartRate) { setMetric("hr-value", t.HeartRate.bpm); @@ -224,30 +224,29 @@ function powerTolerance(target) { return Math.max(POWER_TOL_ABS, Math.round(target * POWER_TOL_PCT)); } -function updateDeviation(metricEl, targetEl, warnEl, actual, target, tolerance) { - targetEl.textContent = target != null ? `цель ${target}` : ""; +function updateDeviation(metricEl, targetEl, warnEl, actual, target, tolerance, unit) { + targetEl.textContent = target != null ? `цель ${target} ${unit}` : "—"; if (actual == null || target == null) { metricEl.classList.remove("metric--off"); - warnEl.hidden = true; + warnEl.textContent = ""; return; } const diff = actual - target; if (Math.abs(diff) > tolerance) { metricEl.classList.add("metric--off"); warnEl.textContent = diff > 0 ? "выше цели" : "ниже цели"; - warnEl.hidden = false; } else { metricEl.classList.remove("metric--off"); - warnEl.hidden = true; + warnEl.textContent = ""; } } function updatePowerDeviation() { - updateDeviation(powerMetric, powerTarget, powerWarn, actualWatts, targetWatts, powerTolerance(targetWatts ?? 0)); + updateDeviation(powerMetric, powerTarget, powerWarn, actualWatts, targetWatts, powerTolerance(targetWatts ?? 0), "W"); } function updateCadenceDeviation() { - updateDeviation(cadenceMetric, cadenceTarget, cadenceWarn, actualCadence, targetCadence, CADENCE_TOL_ABS); + updateDeviation(cadenceMetric, cadenceTarget, cadenceWarn, actualCadence, targetCadence, CADENCE_TOL_ABS, "rpm"); } function clearTargets() { diff --git a/src/styles.css b/src/styles.css index ec8c2eb..8dd92f2 100644 --- a/src/styles.css +++ b/src/styles.css @@ -316,36 +316,44 @@ body { } .metric__value { - font-size: var(--text-3xl); + font-size: var(--text-xl); font-weight: var(--fw-semibold); line-height: 1; font-variant-numeric: tabular-nums; } -.metric--cadence .metric__value, -.metric--hr .metric__value { - font-size: var(--text-xl); -} - .metric__unit { font-size: var(--text-sm); color: var(--c-text-muted); } +/* целевое значение — главное */ .metric__target { - font-size: var(--text-xs); + font-size: var(--text-2xl); + font-weight: var(--fw-semibold); + line-height: 1; + font-variant-numeric: tabular-nums; +} + +/* фактическое значение — вторичное, краснеет при отклонении */ +.metric__actual { + font-size: var(--text-base); color: var(--c-text-muted); font-variant-numeric: tabular-nums; } -.metric__warn { - font-size: var(--text-xs); - font-weight: var(--fw-medium); +.metric--off .metric__actual { color: var(--c-danger); + font-weight: var(--fw-semibold); } -.metric--off .metric__value { +/* предупреждение — резервируем строку, чтобы не прыгало */ +.metric__warn { + min-height: var(--text-base); + font-size: var(--text-xs); + font-weight: var(--fw-medium); color: var(--c-danger); + line-height: 1.2; } /* --- Управление --- */