- header Sync button now has a paired autosync toggle to its right —
reads as one button with no inner seam (outer border only). Dot inside
pulses once per actual sync (bursts on every backgroundSync /
triggerSync / collab pollOnce via a new sync.pulse hook) so the user
can see polls happen. Dot + data-autosync attribute persist the
enabled state in localStorage; paused state stops both the
CalDAV/relay background timer and the collab poll via a broadcast
autosync.changed hook.
- hover polish: Sync regains a full accent border (the missing inner
edge re-appears only on its hover); the toggle fills with solid
accent as hover treatment so the pair never shows a half-outline.
- sync interval moved out of hardcode into a settings field under
Settings → Relay: number input, 5s..3600s, default 15s (was 45s on
caldav / 30s on collab). Changes broadcast via sync.interval.changed
and restart both timers without reload.
- session cookie lifetime raised to 30 days with matching gc_maxlifetime
and SameSite=Lax (was 0 / Strict — some users got kicked to login on
every reload when gc cleaned up the /tmp/sess file or a cross-link
return blocked the cookie).
- search button's kbd element was pushing the button ~3px taller than
Sync; leading-none + tighter padding puts them on the same height.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>