SIGN IN SIGN UP

feat(richtext): mosaic↔slideshow toggle for multi-media blocks

Add a top-right glass toggle (left of "+") that switches an article-editor
multi-media block (items.count >= 2) between a mosaic grid (sent as
InstantPage .collage) and a swipeable slideshow carousel with paging dots
(sent as .slideshow). The InstantPage V2 slideshow renderer already existed;
the editor now produces it.

- New per-block displayMode (.mosaic default / .slideshow) on MediaBlock,
  mirrored by ChatInputMedia.displayMode; Codable back-compat (missing → .mosaic).
- Both forward converters (ChatInputContentInstantPage + InstantPageBuilder)
  branch on the mode; the reverse converter recovers it (shared item helper);
  the composer bridge maps it both ways.
- MediaBlockBox reserves slideshow height (tallest item fitted, capped);
  nodeSize/caret stay caption-derived.
- MediaItemNodeView renders the carousel via a HorizontalPagingScrollView +
  PageControlNode, reusing the pooled mosaic cells (no re-flash on toggle);
  hitTest keeps buttons/controls tappable and lets vertical scroll through.
- .toggleLayout control-seam case + one-undo-step toggleMediaDisplayMode op;
  provider seam threads displayMode; composer stays mosaic-only.

Article editor only. Full app build green; SwiftPM editor suites + TextFormat
round-trip tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
I
isaac committed
431b5bf02ce8c6f17df883f2414f4361fdd15c83
Parent: a45ea21