collab per-card unread, detail stale banner, image sync race fix

- per-card unread dot on board (collab-buckets): backend tracks
  last_seen_at per card, poll exposes unread_cards, frontend decorates
  matching board cards; cleared on any open path via detail.opened hook
- detail.opened + cards.reloaded hooks on the hyprcrd event bus
- stale banner in detail view with manual Reload when the currently
  viewed card got updated by a peer — no content swap under the user
- collab image sync: push attachments BEFORE card (race fix) + pull-side
  self-heal scans every collab card for missing uploads each poll
- relay user deletion now purges chat_messages sent by deleted user so
  ghost threads stop appearing for their peers
- calendar header nav buttons styled as square bordered buttons that
  honor --ui-radius-button; title bar widened to 280px so font variants
  don't wrap
- .toolbar-btn now uses var(--ui-radius-button) instead of hardcoded 3px

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.6 committed 2026-04-14 22:39:32 +02:00
1 parent 39e94b8015
commit 26f95ba079
10 files changed
+324 -35

No files matched your search

@@ -359,3 +359,21 @@ body.anim-slow .bucket-tab.bucket-tab-collab.pulsing {
.collab-conflict-toast.collab-lock-toast b {
color: var(--t-accent2);
}
/* ── Per-card unread indicator ──
Mirror of the bucket-tab red dot: a card with a foreign edit we haven't
opened yet gets a small glowing dot pinned to the top-right corner. */
.board-card.collab-card-unread { position: relative; }
.board-card.collab-card-unread .collab-card-dot {
position: absolute;
top: -3px;
right: -3px;
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--t-danger);
border: 1px solid var(--t-bg);
box-shadow: 0 0 6px color-mix(in srgb, var(--t-danger) 60%, transparent);
pointer-events: none;
z-index: 3;
}