@flamingo-stack/openframe-frontend-core 0.0.496 → 0.0.498-1506.3998.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/dist/chat-protocol/decode.d.ts +58 -0
  2. package/dist/chat-protocol/decode.d.ts.map +1 -0
  3. package/dist/chat-protocol/encode.d.ts +44 -0
  4. package/dist/chat-protocol/encode.d.ts.map +1 -0
  5. package/dist/chat-protocol/env-flag.d.ts +35 -0
  6. package/dist/chat-protocol/env-flag.d.ts.map +1 -0
  7. package/dist/chat-protocol/events.d.ts +207 -0
  8. package/dist/chat-protocol/events.d.ts.map +1 -0
  9. package/dist/chat-protocol/frames.d.ts +213 -0
  10. package/dist/chat-protocol/frames.d.ts.map +1 -0
  11. package/dist/chat-protocol/index.cjs +500 -0
  12. package/dist/chat-protocol/index.cjs.map +1 -0
  13. package/dist/chat-protocol/index.d.ts +18 -0
  14. package/dist/chat-protocol/index.d.ts.map +1 -0
  15. package/dist/chat-protocol/index.js +484 -0
  16. package/dist/chat-protocol/index.js.map +1 -0
  17. package/dist/chat-protocol/ip-normalize.d.ts +44 -0
  18. package/dist/chat-protocol/ip-normalize.d.ts.map +1 -0
  19. package/dist/chat-protocol/nats-decoder.d.ts +26 -0
  20. package/dist/chat-protocol/nats-decoder.d.ts.map +1 -0
  21. package/dist/{chunk-DZU3FCOQ.js → chunk-2PSS74KN.js} +2 -2
  22. package/dist/{chunk-QRHAIJMG.cjs → chunk-2TO6XJPE.cjs} +7 -7
  23. package/dist/{chunk-QRHAIJMG.cjs.map → chunk-2TO6XJPE.cjs.map} +1 -1
  24. package/dist/{chunk-J6MC4SY7.cjs → chunk-2ULVF4SH.cjs} +37 -37
  25. package/dist/{chunk-J6MC4SY7.cjs.map → chunk-2ULVF4SH.cjs.map} +1 -1
  26. package/dist/{chunk-7M24CJRH.cjs → chunk-3RDAHDTQ.cjs} +15 -15
  27. package/dist/{chunk-7M24CJRH.cjs.map → chunk-3RDAHDTQ.cjs.map} +1 -1
  28. package/dist/{chunk-GANUPKHV.js → chunk-4FP227A7.js} +2 -2
  29. package/dist/{chunk-L5GMHETR.cjs → chunk-5GJCNFKG.cjs} +28 -27
  30. package/dist/chunk-5GJCNFKG.cjs.map +1 -0
  31. package/dist/{chunk-P77L6MPJ.cjs → chunk-5H4A3WOX.cjs} +11 -11
  32. package/dist/{chunk-P77L6MPJ.cjs.map → chunk-5H4A3WOX.cjs.map} +1 -1
  33. package/dist/{chunk-KDPQGHQ2.js → chunk-5IZXBK72.js} +2 -2
  34. package/dist/{chunk-KXOSLXL2.js → chunk-D3PFBPP4.js} +12033 -9849
  35. package/dist/chunk-D3PFBPP4.js.map +1 -0
  36. package/dist/{chunk-ZP4QMJX4.js → chunk-DKJDQXW7.js} +2 -2
  37. package/dist/{chunk-QHGGQZFK.cjs → chunk-ELGQYD5K.cjs} +62 -62
  38. package/dist/{chunk-QHGGQZFK.cjs.map → chunk-ELGQYD5K.cjs.map} +1 -1
  39. package/dist/{chunk-VCHK2B6W.js → chunk-IW47IIT7.js} +2 -2
  40. package/dist/{chunk-OQFXEWW2.js → chunk-JQ3W4WDW.js} +2 -2
  41. package/dist/{chunk-FFL3D5LX.cjs → chunk-JSAAX632.cjs} +26 -26
  42. package/dist/{chunk-FFL3D5LX.cjs.map → chunk-JSAAX632.cjs.map} +1 -1
  43. package/dist/{chunk-UCZHGV4E.cjs → chunk-NJ6PGOZI.cjs} +6971 -4787
  44. package/dist/chunk-NJ6PGOZI.cjs.map +1 -0
  45. package/dist/{chunk-CDRNCBLS.cjs → chunk-OCVTIY7C.cjs} +60 -60
  46. package/dist/chunk-OCVTIY7C.cjs.map +1 -0
  47. package/dist/{chunk-E5AIN5SS.cjs → chunk-OYQYRRZO.cjs} +31 -31
  48. package/dist/{chunk-E5AIN5SS.cjs.map → chunk-OYQYRRZO.cjs.map} +1 -1
  49. package/dist/{chunk-PBAFZETL.js → chunk-QHUOOY3T.js} +2 -2
  50. package/dist/{chunk-VUUIYBIH.js → chunk-RYSZLEUP.js} +10 -10
  51. package/dist/chunk-RYSZLEUP.js.map +1 -0
  52. package/dist/{chunk-FP62TQ3A.cjs → chunk-UGN44PVB.cjs} +9 -9
  53. package/dist/{chunk-FP62TQ3A.cjs.map → chunk-UGN44PVB.cjs.map} +1 -1
  54. package/dist/{chunk-WUM5BTDY.js → chunk-UMK5KRV6.js} +6 -5
  55. package/dist/chunk-UMK5KRV6.js.map +1 -0
  56. package/dist/{chunk-4BGDD6CU.js → chunk-VDC3WCOG.js} +4 -4
  57. package/dist/{chunk-ZVCODNW7.cjs → chunk-YNG2HYLT.cjs} +5 -5
  58. package/dist/{chunk-ZVCODNW7.cjs.map → chunk-YNG2HYLT.cjs.map} +1 -1
  59. package/dist/{chunk-YQ4B7LCE.js → chunk-ZSEM7ZCF.js} +4 -4
  60. package/dist/components/case-studies/index.cjs +8 -8
  61. package/dist/components/case-studies/index.js +2 -2
  62. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  63. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  64. package/dist/components/chat/hooks/index.d.ts +0 -1
  65. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  66. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  67. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +15 -48
  68. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  69. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +10 -57
  70. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  71. package/dist/components/chat/index.cjs +10 -2
  72. package/dist/components/chat/index.cjs.map +1 -1
  73. package/dist/components/chat/index.d.ts +1 -0
  74. package/dist/components/chat/index.d.ts.map +1 -1
  75. package/dist/components/chat/index.js +21 -13
  76. package/dist/components/chat/stream/chat-dialog-store.d.ts +184 -0
  77. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +1 -0
  78. package/dist/components/chat/stream/chat-stream-reducer.d.ts +367 -0
  79. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -0
  80. package/dist/components/chat/stream/delta-batcher.d.ts +51 -0
  81. package/dist/components/chat/stream/delta-batcher.d.ts.map +1 -0
  82. package/dist/components/chat/stream/index.d.ts +17 -0
  83. package/dist/components/chat/stream/index.d.ts.map +1 -0
  84. package/dist/components/chat/stream/message-mutations.d.ts +77 -0
  85. package/dist/components/chat/stream/message-mutations.d.ts.map +1 -0
  86. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +22 -0
  87. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +1 -0
  88. package/dist/components/chat/types/api.types.d.ts +1 -81
  89. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  90. package/dist/components/chat/types/processing.types.d.ts +2 -93
  91. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  92. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +34 -6
  93. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  94. package/dist/components/chat/utils/index.d.ts +2 -3
  95. package/dist/components/chat/utils/index.d.ts.map +1 -1
  96. package/dist/components/chat/utils/process-historical-messages.d.ts +59 -11
  97. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  98. package/dist/components/contact/index.cjs +3 -3
  99. package/dist/components/contact/index.js +2 -2
  100. package/dist/components/docs/index.cjs +5 -5
  101. package/dist/components/docs/index.js +4 -4
  102. package/dist/components/embeds/index.cjs +3 -3
  103. package/dist/components/embeds/index.js +2 -2
  104. package/dist/components/faq/index.cjs +3 -3
  105. package/dist/components/faq/index.js +2 -2
  106. package/dist/components/features/floating-walkthrough-video.d.ts +5 -1
  107. package/dist/components/features/floating-walkthrough-video.d.ts.map +1 -1
  108. package/dist/components/features/index.cjs +2 -2
  109. package/dist/components/features/index.js +1 -1
  110. package/dist/components/help-center-pages/index.cjs +20 -20
  111. package/dist/components/help-center-pages/index.js +11 -11
  112. package/dist/components/index.cjs +172 -130
  113. package/dist/components/index.cjs.map +1 -1
  114. package/dist/components/index.js +63 -21
  115. package/dist/components/index.js.map +1 -1
  116. package/dist/components/navigation/index.cjs +2 -2
  117. package/dist/components/navigation/index.js +1 -1
  118. package/dist/components/onboarding-guides/index.cjs +5 -5
  119. package/dist/components/onboarding-guides/index.js +4 -4
  120. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  121. package/dist/components/related-content/index.cjs +3 -3
  122. package/dist/components/related-content/index.js +2 -2
  123. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  124. package/dist/components/tickets/index.cjs +5 -5
  125. package/dist/components/tickets/index.js +4 -4
  126. package/dist/components/ui/index.cjs +44 -2
  127. package/dist/components/ui/index.cjs.map +1 -1
  128. package/dist/components/ui/index.d.ts +1 -2
  129. package/dist/components/ui/index.d.ts.map +1 -1
  130. package/dist/components/ui/index.js +55 -13
  131. package/dist/components/ui/markdown/base-components.d.ts +51 -0
  132. package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
  133. package/dist/components/ui/markdown/engine.d.ts +99 -0
  134. package/dist/components/ui/markdown/engine.d.ts.map +1 -0
  135. package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
  136. package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
  137. package/dist/components/ui/markdown/index.d.ts +18 -0
  138. package/dist/components/ui/markdown/index.d.ts.map +1 -0
  139. package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
  140. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
  141. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
  142. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
  143. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
  144. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
  145. package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
  146. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
  147. package/dist/components/ui/markdown/sanitize.d.ts +153 -0
  148. package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
  149. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
  150. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
  151. package/dist/components/ui/markdown/streaming.d.ts +78 -0
  152. package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
  153. package/dist/components/ui/markdown/text-size.d.ts +34 -0
  154. package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
  155. package/dist/index.cjs +60 -2
  156. package/dist/index.cjs.map +1 -1
  157. package/dist/index.js +71 -13
  158. package/dist/types/supabase.d.ts +3 -0
  159. package/dist/types/supabase.d.ts.map +1 -1
  160. package/dist/utils/index.cjs +169 -40
  161. package/dist/utils/index.cjs.map +1 -1
  162. package/dist/utils/index.d.ts +1 -0
  163. package/dist/utils/index.d.ts.map +1 -1
  164. package/dist/utils/index.js +162 -41
  165. package/dist/utils/index.js.map +1 -1
  166. package/dist/utils/markdown-fences.d.ts +42 -0
  167. package/dist/utils/markdown-fences.d.ts.map +1 -0
  168. package/dist/utils/markdown-heading-id.d.ts +85 -0
  169. package/dist/utils/markdown-heading-id.d.ts.map +1 -0
  170. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  171. package/package.json +7 -1
  172. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +317 -0
  173. package/src/chat-protocol/__tests__/chat-protocol.test.ts +516 -0
  174. package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
  175. package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
  176. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +232 -0
  177. package/src/chat-protocol/decode.ts +278 -0
  178. package/src/chat-protocol/encode.ts +71 -0
  179. package/src/chat-protocol/env-flag.ts +39 -0
  180. package/src/chat-protocol/events.ts +245 -0
  181. package/src/chat-protocol/frames.ts +245 -0
  182. package/src/chat-protocol/index.ts +21 -0
  183. package/src/chat-protocol/ip-normalize.ts +146 -0
  184. package/src/chat-protocol/nats-decoder.ts +258 -0
  185. package/src/components/chat/__tests__/chat-message-list.test.tsx +293 -5
  186. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
  187. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +230 -0
  188. package/src/components/chat/chat-message-enhanced.tsx +122 -20
  189. package/src/components/chat/chat-message-list.tsx +358 -109
  190. package/src/components/chat/embeddable-chat.tsx +6 -0
  191. package/src/components/chat/hooks/.index.md +30 -33
  192. package/src/components/chat/hooks/.use-nats-chat-adapter.md +36 -55
  193. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +37 -0
  194. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  195. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +438 -0
  196. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
  197. package/src/components/chat/hooks/index.ts +0 -1
  198. package/src/components/chat/hooks/use-chat.ts +8 -0
  199. package/src/components/chat/hooks/use-nats-chat-adapter.ts +243 -825
  200. package/src/components/chat/hooks/use-sse-chat-adapter.ts +380 -684
  201. package/src/components/chat/index.ts +5 -0
  202. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +940 -0
  203. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +756 -0
  204. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +460 -0
  205. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +973 -0
  206. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
  207. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +98 -0
  208. package/src/components/chat/stream/chat-dialog-store.ts +536 -0
  209. package/src/components/chat/stream/chat-stream-reducer.ts +1808 -0
  210. package/src/components/chat/stream/delta-batcher.ts +168 -0
  211. package/src/components/chat/stream/index.ts +55 -0
  212. package/src/components/chat/stream/message-mutations.ts +340 -0
  213. package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
  214. package/src/components/chat/thinking-display.tsx +1 -1
  215. package/src/components/chat/types/.api.types.md +39 -49
  216. package/src/components/chat/types/.processing.types.md +29 -58
  217. package/src/components/chat/types/api.types.ts +6 -73
  218. package/src/components/chat/types/processing.types.ts +11 -53
  219. package/src/components/chat/utils/.index.md +31 -40
  220. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +420 -0
  221. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +605 -0
  222. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +394 -0
  223. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
  224. package/src/components/chat/utils/extract-incomplete-message-state.ts +63 -5
  225. package/src/components/chat/utils/index.ts +5 -8
  226. package/src/components/chat/utils/process-historical-messages.ts +358 -386
  227. package/src/components/features/floating-walkthrough-video.tsx +13 -2
  228. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
  229. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  230. package/src/components/shared/product-release/release-detail-page.tsx +19 -4
  231. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
  232. package/src/components/ui/__tests__/markdown-parity.test.tsx +2528 -0
  233. package/src/components/ui/index.ts +1 -2
  234. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +115 -0
  235. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +95 -0
  236. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +309 -0
  237. package/src/components/ui/markdown/__tests__/streaming.test.tsx +388 -0
  238. package/src/components/ui/markdown/base-components.tsx +360 -0
  239. package/src/components/ui/markdown/engine.tsx +315 -0
  240. package/src/components/ui/markdown/heading-ids.ts +239 -0
  241. package/src/components/ui/markdown/index.ts +49 -0
  242. package/src/components/ui/markdown/mermaid-diagram.tsx +291 -0
  243. package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
  244. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
  245. package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
  246. package/src/components/ui/markdown/sanitize.ts +3499 -0
  247. package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
  248. package/src/components/ui/markdown/streaming.ts +362 -0
  249. package/src/components/ui/markdown/text-size.ts +106 -0
  250. package/src/components/ui/release-changelog-section.tsx +1 -1
  251. package/src/components/ui/ticket-info-section.tsx +1 -1
  252. package/src/types/supabase.ts +3 -0
  253. package/src/utils/index.ts +1 -0
  254. package/src/utils/markdown-fences.ts +127 -0
  255. package/src/utils/markdown-heading-id.ts +348 -0
  256. package/src/utils/markdown-section-extractor.ts +41 -56
  257. package/dist/chunk-CDRNCBLS.cjs.map +0 -1
  258. package/dist/chunk-KXOSLXL2.js.map +0 -1
  259. package/dist/chunk-L5GMHETR.cjs.map +0 -1
  260. package/dist/chunk-UCZHGV4E.cjs.map +0 -1
  261. package/dist/chunk-VUUIYBIH.js.map +0 -1
  262. package/dist/chunk-WUM5BTDY.js.map +0 -1
  263. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
  264. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
  265. package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
  266. package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
  267. package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
  268. package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
  269. package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
  270. package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
  271. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -77
  272. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -489
  273. package/src/components/chat/utils/.chunk-parser.md +0 -62
  274. package/src/components/chat/utils/chunk-parser.ts +0 -262
  275. package/src/components/ui/.simple-markdown-renderer.md +0 -52
  276. package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
  277. package/src/components/ui/simple-markdown-renderer.tsx +0 -964
  278. /package/dist/{chunk-DZU3FCOQ.js.map → chunk-2PSS74KN.js.map} +0 -0
  279. /package/dist/{chunk-GANUPKHV.js.map → chunk-4FP227A7.js.map} +0 -0
  280. /package/dist/{chunk-KDPQGHQ2.js.map → chunk-5IZXBK72.js.map} +0 -0
  281. /package/dist/{chunk-ZP4QMJX4.js.map → chunk-DKJDQXW7.js.map} +0 -0
  282. /package/dist/{chunk-VCHK2B6W.js.map → chunk-IW47IIT7.js.map} +0 -0
  283. /package/dist/{chunk-OQFXEWW2.js.map → chunk-JQ3W4WDW.js.map} +0 -0
  284. /package/dist/{chunk-PBAFZETL.js.map → chunk-QHUOOY3T.js.map} +0 -0
  285. /package/dist/{chunk-4BGDD6CU.js.map → chunk-VDC3WCOG.js.map} +0 -0
  286. /package/dist/{chunk-YQ4B7LCE.js.map → chunk-ZSEM7ZCF.js.map} +0 -0
@@ -2,7 +2,8 @@
2
2
 
3
3
  /**
4
4
  * <FloatingWalkthroughVideo> — THE generic, embeddable per-platform demo-video
5
- * widget. A collapsed card pinned bottom-left (bite-identical hover grammar via
5
+ * widget. A collapsed card pinned to a bottom corner — left unless the video
6
+ * data says `position: 'right'` — (bite-identical hover grammar via
6
7
  * <VideoHoverPreviewSurface>) that opens a large in-page theater (Radix Dialog
7
8
  * primitives, NOT native fullscreen) showing ONLY the video: a bare 16:9 stage
8
9
  * with the player's own controls + captions. No card chrome, no summary.
@@ -71,6 +72,9 @@ export interface WalkthroughVideoData {
71
72
  captionsUrl?: string | null;
72
73
  title?: string | null;
73
74
  presenterAvatarUrl?: string | null;
75
+ /** Which bottom corner the collapsed card pins to. Admin-controlled per
76
+ * video; anything other than 'right' (including absent) means left. */
77
+ position?: 'left' | 'right' | null;
74
78
  }
75
79
 
76
80
  export interface FloatingWalkthroughVideoProps {
@@ -816,7 +820,14 @@ export function FloatingWalkthroughVideo({
816
820
  return (
817
821
  <>
818
822
  {showCard && (
819
- <div className={cn('pointer-events-none fixed bottom-0 left-0 p-[var(--spacing-system-mf)]', WALKTHROUGH_Z)} style={{ paddingBottom: 'max(var(--spacing-system-mf), env(safe-area-inset-bottom))' }}>
823
+ <div
824
+ className={cn(
825
+ 'pointer-events-none fixed bottom-0 p-[var(--spacing-system-mf)]',
826
+ video.position === 'right' ? 'right-0' : 'left-0',
827
+ WALKTHROUGH_Z,
828
+ )}
829
+ style={{ paddingBottom: 'max(var(--spacing-system-mf), env(safe-area-inset-bottom))' }}
830
+ >
820
831
  {collapsed}
821
832
  </div>
822
833
  )}
@@ -15,7 +15,7 @@
15
15
  * renderer with extra plugins.
16
16
  */
17
17
 
18
- import { type ComponentType, type ReactNode } from 'react'
18
+ import { Fragment, type ComponentType, type ReactNode } from 'react'
19
19
  import { PageLayout } from '../layout/page-layout'
20
20
 
21
21
  import { useRouter } from '../../embed-shims'
@@ -30,7 +30,7 @@ import { VideoBitesStrip } from '../features/video-bites-strip'
30
30
  import { toStripProfile } from '../features/video-bites-shared'
31
31
  import { useVideoWarmup } from '../features/use-video-warmup'
32
32
  import { getCaptionsUrl } from '../features/captions-url'
33
- import { RichMarkdownRenderer } from '../ui/rich-markdown-renderer'
33
+ import { RichMarkdownRenderer } from '../ui/markdown'
34
34
  import { EntityTagBadges } from '../features/entity-tag-badges'
35
35
  import { LoadError } from '../ui/error-state'
36
36
  import { ArticleAuthorByline } from '../shared/article-author-byline'
@@ -244,8 +244,26 @@ export function OnboardingGuideDetailView({
244
244
  </div>
245
245
  )}
246
246
 
247
- {/* Host slot — cross-type related-content / FAQ rail. */}
248
- {relatedContent}
247
+ {/*
248
+ * Host slot — cross-type related-content / FAQ rail.
249
+ *
250
+ * KEYED DELIBERATELY. This is one member of PageLayout's static children
251
+ * array, and the only member whose element may be created in a SERVER
252
+ * component and crossed over the RSC boundary. Static JSX children are
253
+ * normally exempt from the key warning because `jsxs` runs
254
+ * `validateChildKeys` and stamps `_store.validated = 1` on each element —
255
+ * but a slot arriving over the wire is referenced as a lazy chunk wrapper,
256
+ * so validation marks the WRAPPER and the fulfilled path never copies the
257
+ * flag onto the revived element. It reaches the reconciler with
258
+ * `validated: 0, key: null` and warns, blaming PageLayout (the owner of the
259
+ * enclosing element) rather than anything actually at fault.
260
+ *
261
+ * A keyed Fragment emits no DOM, so rendered output is byte-identical.
262
+ * Do NOT "fix" this in PageLayout via `React.Children.toArray` — that would
263
+ * auto-key every consumer's children and change reconciliation identity for
264
+ * all of them, and that file carries an explicit FROZEN contract.
265
+ */}
266
+ <Fragment key="related-content">{relatedContent}</Fragment>
249
267
  </PageLayout>
250
268
  )
251
269
  }
@@ -19,7 +19,7 @@
19
19
 
20
20
  import type { ComponentType } from 'react';
21
21
  import { PageShell, PageLayout } from '../../ui';
22
- import { RichMarkdownRenderer } from '../../ui/rich-markdown-renderer';
22
+ import { RichMarkdownRenderer } from '../../ui/markdown';
23
23
  import { useRouter } from '../../../embed-shims/next-navigation';
24
24
  import { useLegalDocs, type LegalDocument } from './use-legal-docs';
25
25
  import { formatLegalDate } from '../../../utils/format';
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { useState, useEffect, ComponentType, type ReactNode } from 'react';
3
+ import { useState, useEffect, Fragment, ComponentType, type ReactNode } from 'react';
4
4
  import Link from '../../../embed-shims/next-link';
5
5
  import { useRouter } from '../../../embed-shims/next-navigation';
6
6
  import { Card, CardContent } from '../../ui/card';
@@ -11,7 +11,7 @@ import { PageShell } from '../../layout/article-detail-layout';
11
11
  import { PageLayout } from '../../layout/page-layout';
12
12
  import { FadePreview } from '../../ui/fade-preview';
13
13
  import { ReleaseChangelogSection } from '../../ui/release-changelog-section';
14
- import { RichMarkdownRenderer } from '../../ui/rich-markdown-renderer';
14
+ import { RichMarkdownRenderer } from '../../ui/markdown';
15
15
  import { EntityTagBadges } from '../../features/entity-tag-badges';
16
16
  import { EntityMetadataAuthorCell } from '../../chat/entity-cards/entity-author-card';
17
17
  import type { EntityAuthor } from '../../../types/entity-author';
@@ -582,8 +582,23 @@ export function ReleaseDetailPage({
582
582
  )}
583
583
  </div>
584
584
 
585
- {/* Host slot — end-of-article byline + related-content / FAQ rail. */}
586
- {relatedContent}
585
+ {/*
586
+ * Host slot — end-of-article byline + related-content / FAQ rail.
587
+ *
588
+ * KEYED for the same reason as `onboarding-guide-detail-view.tsx`: this is a
589
+ * member of PageLayout's static children array, and a slot element built in a
590
+ * SERVER component crosses the RSC boundary as a lazy chunk wrapper, so
591
+ * `validateChildKeys` marks the wrapper and the fulfilled path never copies
592
+ * `_store.validated` onto the revived element — it reaches the reconciler
593
+ * unvalidated and warns.
594
+ *
595
+ * Today the hub's only consumer of this view is a `'use client'` wrapper that
596
+ * builds the slot locally, so no element actually crosses the boundary and
597
+ * this is pre-emptive. It is kept because the trap is invisible from here: a
598
+ * future server-built slot would warn with no clue pointing at this line.
599
+ * A keyed Fragment emits no DOM, so output is byte-identical either way.
600
+ */}
601
+ <Fragment key="related-content">{relatedContent}</Fragment>
587
602
  </PageLayout>
588
603
  );
589
604
  }