@bobfrankston/rmfmail 1.1.157 → 1.1.158

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2585,6 +2585,21 @@ body.calendar-sidebar-on .calendar-sidebar { display: flex; }
2585
2585
  the threshold (the indicator line) and release to fire a sync — same
2586
2586
  action as F5 / btn-sync. The indicator translates with the pull and
2587
2587
  rotates the chevron when you cross the threshold. */
2588
+ /* Pull-to-refresh indicator. Two visual states:
2589
+ *
2590
+ * 1. DRAGGING (user is pulling down):
2591
+ * Full 60-px banner with chevron + "Pull to refresh" / "Release to
2592
+ * refresh". This is fine — it only exists during the gesture, which
2593
+ * the user initiated; it'll be gone in a second.
2594
+ *
2595
+ * 2. REFRESHING (sync in flight):
2596
+ * A thin 3-px indeterminate progress bar at the top edge — no
2597
+ * content shift, no text overlap. Auto-sync also runs in the
2598
+ * background (60 s on Android, IDLE on desktop) so the banner is
2599
+ * mostly redundant confirmation; the thin bar carries enough signal
2600
+ * ("yes, your gesture fired a sync") without taking 60 px of the
2601
+ * list. Bob 2026-05-26: "I still want a less intrusive refreshing".
2602
+ */
2588
2603
  .ptr-indicator {
2589
2604
  position: absolute;
2590
2605
  top: 0; left: 0; right: 0;
@@ -2601,12 +2616,35 @@ body.calendar-sidebar-on .calendar-sidebar { display: flex; }
2601
2616
  }
2602
2617
  .ptr-indicator.dragging { transition: none; }
2603
2618
  .ptr-indicator.armed .ptr-chev { transform: rotate(180deg); }
2604
- /* While refreshing, push the message list down so the 60-px indicator
2605
- * sits ABOVE the first rows instead of overlapping them (Bob 2026-05-25
2606
- * "refreshing on the top covering text"). 120 ms ease matches the
2607
- * indicator's own slide so the two move together. */
2608
- .ptr-indicator.refreshing + #ml-body { margin-top: 60px; transition: margin-top 120ms ease-out; }
2609
- #ml-body { transition: margin-top 120ms ease-out; }
2619
+ /* Refreshing state: collapse the banner to a 3-px progress bar. No
2620
+ * background, no banner height just a thin indeterminate stripe so the
2621
+ * message list stays in place. transform override beats the inline
2622
+ * `translateY(calc(-100% + 60px))` the JS sets when armed; we keep top:0
2623
+ * by overriding to translateY(0). */
2624
+ .ptr-indicator.refreshing {
2625
+ height: 3px;
2626
+ transform: translateY(0) !important;
2627
+ background: transparent;
2628
+ overflow: hidden;
2629
+ }
2630
+ .ptr-indicator.refreshing .ptr-chev,
2631
+ .ptr-indicator.refreshing .ptr-label { display: none; }
2632
+ .ptr-indicator.refreshing::after {
2633
+ content: "";
2634
+ position: absolute;
2635
+ inset: 0;
2636
+ background: linear-gradient(90deg,
2637
+ transparent 0%,
2638
+ var(--color-brand-dark, #2563eb) 50%,
2639
+ transparent 100%);
2640
+ background-size: 40% 100%;
2641
+ background-repeat: no-repeat;
2642
+ animation: ptr-indeterminate 1.1s linear infinite;
2643
+ }
2644
+ @keyframes ptr-indeterminate {
2645
+ 0% { background-position: -40% 0; }
2646
+ 100% { background-position: 140% 0; }
2647
+ }
2610
2648
  .ptr-indicator.refreshing .ptr-chev {
2611
2649
  border-top-color: var(--color-brand-dark);
2612
2650
  border-radius: 50%;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/rmfmail",
3
- "version": "1.1.157",
3
+ "version": "1.1.158",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",