Previously the file bubble wrapped JS middle-ellipsis in CSS truncate,
so narrow containers silently clipped the tail+extension, leaving
e.g. "25cb264a-e06…." instead of "25cb264a-e06…811a.jpg".
Split the displayed name into a shrinking head (with CSS truncate)
and a non-shrinking tail (last 4 base chars + extension). The browser
now decides how much head to clip while the suffix is always visible.
Use object-fill for compact preview thumbnails so rank-list covers and
file previews fill their fixed boxes without cropping or black bars. This
keeps the list layout stable while matching the desired compressed-ratio
thumbnail treatment.
Successful downloads no longer pop a 'downloadOk' toast across all
the download sites (PopularRankList, RecommendedCard, FileDocBubble,
ImageLightbox). The browser's native download UI already confirms
the action, and the toast was redundant noise. Failure toasts and
the spinner state remain so users still see errors.
Render the 52x52 preview with an empty alt and an onError handler, so a
broken thumbnail no longer shows the browser's broken-image box (which
leaked the raw filename) — it falls back to the file-type icon instead.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Use thumbnailUrl/posterUrl (and the image url itself for image-type
attachments) inside the 52x52 box of the file/document bubble, falling
back to the file-type icon when no preview is available.
Also tune the deep-link scroll-mt offset (82px / 98px) so a targeted
bubble lands just below the sticky header.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Recommended cards already routed to /browse#post-<id>, but the stream had
no logic to scroll to the target bubble — and the post might not be paged
in yet. MessageStream now resolves the #post-<id> hash, auto-loads more
pages until the bubble renders, scrolls to it, and gives it a brief gold
highlight. Bubbles get scroll-mt so they clear the sticky header.
Also adds a global floating back-to-top button (BackToTop) mounted in
PublicLayout, shown after scrolling past 400px.
Bundles related staging UI work already present in the working tree.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>