From b31f8e8a8949c8297796aaf717ba11589b088e30 Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 May 2026 23:15:27 -0400 Subject: [PATCH] feat(navigate): GPS-aware empty state, route info CSS refactor, user location marker on map - Add GPS warning banner with enable-location link when GPS unavailable - Refactor route info cards from inline styles to CSS classes - Update empty state messaging based on GPS availability - Show user location marker with accuracy circle on nav map when GPS available - Hide map container when no GPS (show only empty state + search) --- static/index.html | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/static/index.html b/static/index.html index 888f013..a08cf3c 100644 --- a/static/index.html +++ b/static/index.html @@ -365,6 +365,73 @@ animation: spin 0.7s linear infinite; } + /* ═══════════════════════════════════════════════════════════════════════ + PULL-TO-REFRESH (mobile touch) + ═══════════════════════════════════════════════════════════════════════ */ + .ptr-container { + overflow-y: auto; + -webkit-overflow-scrolling: touch; + } + .ptr-indicator { + display: flex; align-items: center; justify-content: center; + gap: 8px; height: 0; overflow: hidden; + transition: height 0.2s ease; + font-size: 13px; color: var(--text2); + } + .ptr-indicator.pulling { height: 52px; } + .ptr-indicator.refreshing { height: 52px; } + .ptr-spinner { + width: 20px; height: 20px; border: 2px solid var(--border); + border-top-color: var(--accent); border-radius: 50%; + transition: transform 0.2s ease; + } + .ptr-indicator.pulling .ptr-spinner { transform: rotate(0deg); } + .ptr-indicator.ready .ptr-spinner { transform: rotate(180deg); } + .ptr-indicator.refreshing .ptr-spinner { + animation: spin 0.7s linear infinite; + } + .ptr-icon { font-size: 18px; transition: transform 0.2s ease; } + .ptr-indicator.ready .ptr-icon { transform: rotate(180deg); } + + /* ═══════════════════════════════════════════════════════════════════════ + SWIPE-TO-DELETE (mobile touch) + ═══════════════════════════════════════════════════════════════════════ */ + .asset-item-swipe-wrap { + position: relative; overflow: hidden; + border-bottom: 1px solid rgba(255,255,255,0.04); + } + .swipe-delete-bg { + position: absolute; inset: 0; display: flex; align-items: center; + justify-content: flex-end; padding: 0 16px; + background: var(--red); z-index: 0; pointer-events: none; + font-size: 13px; font-weight: 600; color: #fff; + } + .swipe-delete-bg span { opacity: 0; transition: opacity 0.1s; } + .swipe-delete-bg.revealed span { opacity: 1; } + .asset-item.swipeable { + position: relative; z-index: 1; background: var(--bg); + transition: transform 0.2s ease; will-change: transform; + } + .asset-item.swiped { transform: translateX(-80px); } + .asset-item.swipe-to-delete { + position: relative; z-index: 1; + } + + /* ═══════════════════════════════════════════════════════════════════════ + DESKTOP-ONLY REFRESH BUTTON + ═══════════════════════════════════════════════════════════════════════ */ + .desktop-refresh-btn { + display: none; /* hidden by default, shown on non-touch */ + margin-left: auto; padding: 6px 14px; + font-size: 13px; border: 1px solid var(--border); + border-radius: var(--radius-sm); background: var(--card); + color: var(--text2); cursor: pointer; + transition: all 0.15s; + -webkit-tap-highlight-color: transparent; + } + .desktop-refresh-btn:hover { background: var(--card2); color: var(--text); } + body.has-mouse .desktop-refresh-btn { display: inline-flex; align-items: center; gap: 6px; } + /* ═══════════════════════════════════════════════════════════════════════ EMPTY STATE ═══════════════════════════════════════════════════════════════════════ */ @@ -1752,6 +1819,12 @@
+ +
+
+ + Pull to refresh +