Add LazyMarkdownContent component that defers markdown rendering until
messages scroll into view. This significantly improves load times for
conversations with many messages (500+ messages would previously timeout).
Changes:
- New LazyMarkdownContent.svelte using IntersectionObserver
- ChatMessageAssistant uses lazy loading for completed messages,
eager rendering for streaming messages
- ChatMessageUser and ChatMessageSystem use lazy loading
- Short messages (<200 chars) render immediately for responsiveness
The component shows a lightweight text placeholder until the message
enters the viewport (with 200px margin for preloading), then renders
full markdown with syntax highlighting, KaTeX, etc.