Two UX fixes for the peek preview:
1. Black flash on first peek — the preview VC now depends on SDWebImage
directly (same version pinned by expo-image) and reads from
`SDImageCache.shared`. On open it paints the fullsize synchronously if it's
cached (common, since onPressIn prefetches), otherwise paints the thumb as a
placeholder while the fullsize loads and swaps in. Also switches the image
view to autoresizingMask so the dismiss animation interpolates cleanly
without AutoLayout relayout mid-animation.
2. Two-stage dismiss animation on aspect-mismatched thumbnails — drop the
explicit `previewForDismissingMenuWithConfiguration` override. With only
the highlight provider implemented iOS reverses it end-to-end, which
interpolates size and position together instead of snapping back to the
preview's original size before translating.
https://claude.ai/code/session_015REmux3R9uuEMMJUHxTyQT
RN/Expo already owns a borderRadius property on UIView (as a style prop),
so declaring `private var borderRadius` on ExpoView was rejected by Swift
("cannot override with a stored property"). Rename the bridge prop and Swift
property to `previewCornerRadius`; the public Trigger/ImageContextMenu API
keeps `borderRadius` and Root translates it at the bridge layer.
Also tighten `var start` to `let` in the SVG parser.
https://claude.ai/code/session_015REmux3R9uuEMMJUHxTyQT
Introduces expo-bluesky-context-menu, a compositional Root/Trigger/Menu/MenuItem
wrapper around UIContextMenuInteraction. The preview ViewController is sized to
the image's true aspect ratio so tall/panorama previews don't stretch mid-lift,
and menu icons are rasterized from the app's SVG icon set on the native side.
The preview prop is a discriminated union (image today; video and externalCard
reserved) so the same module can back those embeds in follow-ups.
https://claude.ai/code/session_015REmux3R9uuEMMJUHxTyQT