feat: add threaded reply rendering with collapse and indent caps (#146)
* feat(web): update types and constants for comment threading
Add maxReplyDepth to CommunitySettings and PublicSettings interfaces,
childCount to Reply, create threading constants, update getReplies to
accept depth param, shift mock data depths to 1-based convention, and
update DEPTH_INDENT map to match new convention.
* feat(web): add reply tree builder utility
Implements buildReplyTree() to reconstruct a tree from flat API response,
and flattenReplyTree() for depth-first traversal. Handles orphan
promotion (parent not in array) and preserves input order.
* feat(web): rewrite reply thread with tree rendering
Replace flat list rendering with recursive tree structure using nested
ol/li elements. Create ReplyBranch component for recursive rendering,
remove DEPTH_INDENT map from ReplyCard (indentation is now structural),
add topicUri prop to ReplyThread, and update all tests for tree
structure including aria-level attributes and depth-first post numbering.
* feat(web): add clickable thread lines for collapse/expand
Create ThreadLine button component with aria-expanded, 44px tap target,
2px visual line, and hover feedback. Integrate into ReplyBranch with
local collapse state management. Collapsed threads show hidden reply
count with aria-live.
* feat(web): add reply-to badges for depth-capped replies
Create ReplyToBadge component with ArrowBendDownRight icon and link to
parent post. Integrate into ReplyBranch to show badges when a reply's
parent differs from its structural tree parent (orphan or depth-capped).
Pass topicUri and allReplies map through for parent lookup.
* feat(web): add responsive visual indent caps
Create useMediaQuery (SSR-safe via useSyncExternalStore) and
useVisualIndentCap hooks returning desktop=4, tablet=3, mobile=2.
ReplyBranch stops nesting at the cap and renders deeper replies flat
with reply-to badges. Add matchMedia mock to test setup for jsdom.
* feat(web): add thread collapse behavior
Auto-collapse depth 3+ threads by default, limit 5+ siblings at depth 2+
to first 3 with ShowMoreReplies button. Direct replies never auto-collapsed.
* feat(web): add max reply depth to admin settings form
Number input (1-9999) with help text explaining the threading spectrum.
Included in save payload to persist via API.
* style(web): fix formatting on dynamic-favicon.tsx after merge
authored by