Match the Figma 4206-6509 card layout for /browse: every bubble now
renders a bottom row with the publish timestamp on the left and the
action buttons on the right. Image, album, video, text and link cards
show only the FavoriteButton; file-document cards show the
FavoriteButton plus a new BubbleAttachmentDownloadButton sized to
match. Removes the absolute-positioned favorite from the default
variant, drops the right-aligned timestamp block, and strips the inline
per-row download button from FileDocBubble's default variant since the
download now lives in the footer. The 'latest' masonry variant is
untouched so the home page continues to use LatestFileCard's existing
internal footer.
- Update desktop header actions to match Figma: remove the standalone desktop favorites button and style the wallet connect pill with the wallet icon while allowing localized labels to expand.
- Replace favorite action with the Figma bookmark SVG and hover state; replace download cloud with the provided Figma SVG.
- Align official recommendation cards with the Figma card structure, colors, and bottom action row.
- Rework popular rows to the Figma desktop rhythm with 90px rows, wide thumbnails, rank area, and right-side action buttons.
- Add a dedicated desktop LatestUpdateCard for Figma-style latest-update masonry cards with flexible text-driven heights instead of fixed card heights.
- Matches Figma design (file uHDZkVHjAp7BXDKQKB0PM4, node 4367-11405).
- Mobile keeps the existing 5-post single column unchanged.
- Desktop (md+) renders all 12 latest posts in a CSS-columns masonry
with break-inside-avoid so each card's height stays content-driven.
- Adds an optional 'fluid' prop to MessageBubble that drops the
standalone-feed max-widths so bubbles fill the masonry column. The
/browse stream keeps the default non-fluid widths.
Adds the front-end side of the link-preview feature so the back-end
team has a fixed contract to implement against.
- docs/link-preview.md: full spec for the `/api/link-preview` proxy
and the preferred inline-on-Post integration. Covers caching, SSRF
guards, metadata-extraction precedence, provider quirks, and the
front-end rendering rules. Scope is the first URL only.
- types/post.ts: new `LinkPreview` type and optional `linkPreview`
field on `Post`.
- LinkPreviewCard: clickable card with a themeColor accent bar,
siteName / title / description (line-clamped), and an optional
1.91:1 thumbnail. Whole card is an `<a target="_blank">` to the
canonical URL.
- MessageBubble: render the card between the bubble body and the
timestamp, with padding that matches visual vs. text-only bubbles.
- mockPosts: example `linkPreview` payloads on p-005 and p-010 so
the visual works when running with VITE_USE_MOCK_POSTS=true,
and so the back-end has concrete reference values.
- Home: lock category carousel height to the tallest page so the
Official Recommendations section below does not jump up when
swiping to a page with fewer categories.
- CollapsibleText: raise default threshold to 25 lines and tighten
the spacing between the expand-all button and the timestamp
(drop the fixed h-8 and use mt-1 instead of mt-1.5).
- formatTime: always render dates as yyyy/m/d HH:mm regardless of
locale, matching the requested timestamp format.
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>