M1b: mobile app-bar clock — Design's resting clock + STALE reaction (Hybrid)

Design's mobile app bar shows a wall clock, no SYNC/STALE readout. Building it
literally would drop the Ship-A staleness signal on the device most users are
on. Kev's ruling: Hybrid — the wall clock is the RESTING state (the stillness),
STALE/amber is the REACTION (the punctuation), driven by the SAME real signal
as desktop (refreshed_at vs expected_interval_s, thresholds 1.5×/3×). Never
silently stale on mobile. Design drew the happy path; we keep the failure state.

- web/src/lib/freshness.js — extracted the freshness tier as ONE shared source
  (CommonJS, unit-tested); desktop HeartbeatBar + mobile clock both key off it,
  so mobile can't silently disagree with desktop about staleness.
- LiveLayer: <768px hides SIGNAL LIVE + EKG + graded + the SYNC label and shows
  a single right-aligned clock — ticking wall clock when calm, amber SYNC / red
  STALE when the tier reacts. Resting dot is static (the clock is the pulse).
- Test-lock: freshness.test.js (tier thresholds, absent≠false-stale, no negative
  age) + vyndrParityQA (mobile clock wired, one shared freshness source).

Built to Design's mobile spec, VISUALLY UNVERIFIED at 390px. NEXT shell
increments (still M1b): merge the clock into the logo row (Design's single-row
app bar), the breadth strip (EDGES/AVG CLV/GAMES — replaces the graded count
mobile lost here), and relocate the wire to the bottom of the board.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-07-16 11:26:00 -04:00
parent c4d4617fab
commit 7c7ab24be5
5 changed files with 145 additions and 24 deletions
+10 -6
View File
@@ -1372,18 +1372,22 @@ html[data-font="readable"] .wm::after { opacity: 0.45 !important; }
VISUALLY UNVERIFIED at 390px (WSL2↔Chrome unreachable — Chrome audit is eyes).
============================================================ */
/* Header EKG drop <768px — Design's mobile has no EKG (app bar carries only
logo + sync clock). Interim step until the full app-bar recomposition in
M1b; keeps the heartbeat from reading as the audit's stacked 110px zone. */
/* Mobile app-bar clock (M1b) — Design's mobile drops SIGNAL LIVE + EKG + graded
+ the SYNC label and shows a single right-aligned clock that RESTS as a wall
clock and REACTS to amber/STALE off the real freshness tier (Hybrid: clock =
stillness, STALE = punctuation; never silently stale on mobile). Full app-bar
recomposition (merge into the logo row + breadth strip + bottom wire) is the
next M1b shell increment. */
@media (max-width: 767px) {
.hb-ekg { display: none !important; }
.hb-ekg,
.hb-desktop { display: none !important; }
.hb-mobile-clock { display: inline-flex !important; }
.heartbeat-bar {
height: 28px !important;
gap: 10px !important;
padding: 0 12px !important;
justify-content: flex-end;
}
/* The status line is one line by contract — never let it wrap into the
"stacked" state the audit flagged. */
.heartbeat-bar > span { white-space: nowrap; }
}