diff --git a/frontend/dashboard.css b/frontend/dashboard.css
index e5ff135..279501c 100644
--- a/frontend/dashboard.css
+++ b/frontend/dashboard.css
@@ -1061,3 +1061,47 @@ textarea { resize: vertical; min-height: 120px; }
.obi { width:14px; height:14px; background: url('data:image/svg+xml;utf8,') center/contain no-repeat; display:inline-block; }
.footer { padding: 12px; text-align: center; color:#4e6b8a; font-size:12px; }
@keyframes fadein { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
+/* One-handed live-data recovery on the mobile Home surface. */
+.mobile-pull-refresh {
+ display: none;
+}
+
+@media (max-width: 600px) {
+ .mobile-pull-refresh {
+ position: sticky;
+ top: calc(3.25rem + env(safe-area-inset-top));
+ z-index: 8;
+ display: block;
+ width: max-content;
+ max-width: calc(100vw - 2rem);
+ margin: 0 auto -2rem;
+ padding: .45rem .8rem;
+ border: 1px solid rgba(125, 211, 252, .45);
+ border-radius: 999px;
+ background: rgba(11, 18, 32, .96);
+ color: #dbeafe;
+ font-size: .78rem;
+ box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .28);
+ transform: translateY(.5rem);
+ pointer-events: none;
+ }
+
+ .mobile-pull-refresh[hidden] {
+ display: none;
+ }
+
+ .mobile-pull-refresh[data-state="ready"],
+ .mobile-pull-refresh[data-state="success"] {
+ border-color: rgba(52, 211, 153, .7);
+ }
+
+ .mobile-pull-refresh[data-state="error"] {
+ border-color: rgba(251, 113, 133, .75);
+ }
+}
+
+@media (max-width: 600px) and (prefers-reduced-motion: no-preference) {
+ .mobile-pull-refresh {
+ transition: transform 120ms ease, border-color 120ms ease;
+ }
+}
diff --git a/frontend/dashboard.js b/frontend/dashboard.js
index 73707bf..36b919c 100644
--- a/frontend/dashboard.js
+++ b/frontend/dashboard.js
@@ -7183,6 +7183,7 @@
intervalMs: 8000,
});
function load() { return contextPoller.refresh({ force: true }); }
+ createMobilePullRefresh({refresh:load}).start();
const liveDataStatusSheet = qs('#live-data-status-sheet');
const liveDataStatusTrigger = qs('#open-live-data-status');
let latestLiveFreshness = {};
diff --git a/frontend/index.html b/frontend/index.html
index 899f6ac..d16c9c6 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -124,6 +124,7 @@
+