@flamingo-stack/openframe-frontend-core 0.0.748 → 0.0.749

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 (546) hide show
  1. package/dist/build/export-map.json +1 -1
  2. package/dist/{chunk-7Y3VMMJB.cjs → chunk-2J2OBP4N.cjs} +26 -18
  3. package/dist/chunk-2YXOD2KL.cjs +137 -0
  4. package/dist/{chunk-BEC43GHL.cjs → chunk-34TWK3JE.cjs} +3 -3
  5. package/dist/{chunk-BBM2ICOY.cjs → chunk-3TELPOVH.cjs} +2 -2
  6. package/dist/{chunk-G2ELX3DG.cjs → chunk-45YRDD7W.cjs} +22 -19
  7. package/dist/{chunk-U6XWGK53.cjs → chunk-ALPRQ3ZX.cjs} +56 -46
  8. package/dist/{chunk-YKJQM2O6.cjs → chunk-BN6NA5RM.cjs} +56 -53
  9. package/dist/{chunk-HNLI4OU5.cjs → chunk-C6LPOYDM.cjs} +24 -24
  10. package/dist/{chunk-4MGZYY6U.cjs → chunk-CLAJIQ7E.cjs} +26 -18
  11. package/dist/{chunk-H34A2765.cjs → chunk-CXV7VBSI.cjs} +104 -118
  12. package/dist/{chunk-QPSQ5WLG.cjs → chunk-DGEB5GUZ.cjs} +2 -2
  13. package/dist/{chunk-OZUJYBQ2.cjs → chunk-E3KFEOFA.cjs} +9 -6
  14. package/dist/{chunk-PSSGIZXZ.cjs → chunk-FHT7SMA7.cjs} +49 -46
  15. package/dist/{chunk-46EIXJFC.cjs → chunk-GOFEOCQN.cjs} +44 -27
  16. package/dist/{chunk-UNR74CAC.cjs → chunk-HOEVD6EN.cjs} +4 -4
  17. package/dist/{chunk-EH3LOWGY.cjs → chunk-KRAQEZPB.cjs} +48 -40
  18. package/dist/{chunk-AKTPO2DN.cjs → chunk-L4UI63K6.cjs} +2 -2
  19. package/dist/{chunk-D4XZL27V.cjs → chunk-LQT2ITMG.cjs} +6 -6
  20. package/dist/{chunk-PSIKUDUV.cjs → chunk-LVO7FALW.cjs} +5 -5
  21. package/dist/{chunk-L2RMTGOK.cjs → chunk-MGF3FUKD.cjs} +7 -7
  22. package/dist/{chunk-P7KTAXXE.cjs → chunk-OFO75R2O.cjs} +169 -175
  23. package/dist/{chunk-JNBOQ7F2.cjs → chunk-OZLIKBKC.cjs} +24 -24
  24. package/dist/{chunk-B27QEHYR.cjs → chunk-P6F6PHVK.cjs} +9 -9
  25. package/dist/chunk-RB6BSE3O.cjs +21 -0
  26. package/dist/{chunk-6XP6RNFD.cjs → chunk-SECT4H34.cjs} +1780 -2076
  27. package/dist/{chunk-GE4PCDNZ.cjs → chunk-SGL47BS2.cjs} +12 -12
  28. package/dist/{chunk-4AZHFLOM.cjs → chunk-SOPVUD2Y.cjs} +3 -3
  29. package/dist/chunk-UGCRLRCT.cjs +25 -0
  30. package/dist/{chunk-BBTSJYTR.cjs → chunk-V3UJ6NDR.cjs} +243 -429
  31. package/dist/{chunk-JOPFX3PJ.cjs → chunk-VEVIMDNK.cjs} +137 -122
  32. package/dist/{chunk-ZNUSYMH7.cjs → chunk-WZX26ODJ.cjs} +121 -121
  33. package/dist/{chunk-YIRX6C7V.cjs → chunk-XJ3J4UIS.cjs} +57 -22
  34. package/dist/{chunk-TRXCQADV.cjs → chunk-ZLF55RDR.cjs} +103 -98
  35. package/dist/{cloud-tenants-V5727B7F.cjs → cloud-tenants-2MYFHEYY.cjs} +16 -14
  36. package/dist/components/case-studies/index.cjs +29 -27
  37. package/dist/components/categories-cart.d.ts.map +1 -1
  38. package/dist/components/categories-cart.js +2 -7
  39. package/dist/components/chat/chat-container.js +4 -4
  40. package/dist/components/chat/chat-context-picker.d.ts.map +1 -1
  41. package/dist/components/chat/chat-context-picker.js +2 -1
  42. package/dist/components/chat/chat-message-row.d.ts.map +1 -1
  43. package/dist/components/chat/chat-message-row.js +6 -5
  44. package/dist/components/chat/chat-message-skeleton.d.ts +3 -1
  45. package/dist/components/chat/chat-message-skeleton.d.ts.map +1 -1
  46. package/dist/components/chat/chat-message-skeleton.js +8 -5
  47. package/dist/components/chat/chat-sidebar-skeleton.d.ts.map +1 -1
  48. package/dist/components/chat/chat-sidebar-skeleton.js +4 -3
  49. package/dist/components/chat/chat-top-navigation.js +4 -4
  50. package/dist/components/chat/context-items-list.d.ts.map +1 -1
  51. package/dist/components/chat/context-items-list.js +5 -3
  52. package/dist/components/chat/entity-cards/admin-content-card-grid.d.ts +24 -1
  53. package/dist/components/chat/entity-cards/admin-content-card-grid.d.ts.map +1 -1
  54. package/dist/components/chat/entity-cards/admin-content-card-grid.js +46 -15
  55. package/dist/components/chat/entity-cards/admin-content-card.d.ts.map +1 -1
  56. package/dist/components/chat/entity-cards/admin-content-card.js +2 -1
  57. package/dist/components/chat/entity-cards/blog-card.d.ts.map +1 -1
  58. package/dist/components/chat/entity-cards/blog-card.js +13 -12
  59. package/dist/components/chat/entity-cards/campaign-card-admin.d.ts.map +1 -1
  60. package/dist/components/chat/entity-cards/campaign-card-admin.js +5 -4
  61. package/dist/components/chat/entity-cards/case-study-card.d.ts.map +1 -1
  62. package/dist/components/chat/entity-cards/case-study-card.js +19 -18
  63. package/dist/components/chat/entity-cards/chat-ticket-item.js +5 -5
  64. package/dist/components/chat/entity-cards/customer-interview-card.d.ts.map +1 -1
  65. package/dist/components/chat/entity-cards/customer-interview-card.js +15 -14
  66. package/dist/components/chat/entity-cards/data-room-doc-card.d.ts.map +1 -1
  67. package/dist/components/chat/entity-cards/data-room-doc-card.js +7 -6
  68. package/dist/components/chat/entity-cards/design-doc-card.d.ts.map +1 -1
  69. package/dist/components/chat/entity-cards/design-doc-card.js +0 -2
  70. package/dist/components/chat/entity-cards/generic-entity-card.d.ts.map +1 -1
  71. package/dist/components/chat/entity-cards/generic-entity-card.js +8 -7
  72. package/dist/components/chat/entity-cards/github-activity-card.d.ts.map +1 -1
  73. package/dist/components/chat/entity-cards/github-activity-card.js +11 -10
  74. package/dist/components/chat/entity-cards/hubspot-ticket-card.d.ts.map +1 -1
  75. package/dist/components/chat/entity-cards/hubspot-ticket-card.js +16 -15
  76. package/dist/components/chat/entity-cards/index.d.ts +1 -1
  77. package/dist/components/chat/entity-cards/index.d.ts.map +1 -1
  78. package/dist/components/chat/entity-cards/index.js +2 -0
  79. package/dist/components/chat/entity-cards/investor-update-card.d.ts.map +1 -1
  80. package/dist/components/chat/entity-cards/investor-update-card.js +12 -11
  81. package/dist/components/chat/entity-cards/onboarding-guide-card.d.ts.map +1 -1
  82. package/dist/components/chat/entity-cards/onboarding-guide-card.js +25 -30
  83. package/dist/components/chat/entity-cards/program-card.d.ts.map +1 -1
  84. package/dist/components/chat/entity-cards/program-card.js +29 -28
  85. package/dist/components/chat/entity-cards/roadmap-card.d.ts.map +1 -1
  86. package/dist/components/chat/entity-cards/roadmap-card.js +37 -39
  87. package/dist/components/chat/entity-cards/slack-message-card.d.ts.map +1 -1
  88. package/dist/components/chat/entity-cards/slack-message-card.js +12 -11
  89. package/dist/components/chat/guide-welcome.js +2 -2
  90. package/dist/components/chat/index.cjs +13 -9
  91. package/dist/components/chat/mingo-archive-list.d.ts.map +1 -1
  92. package/dist/components/chat/mingo-archive-list.js +2 -1
  93. package/dist/components/chat/mingo-chat-history.d.ts +4 -2
  94. package/dist/components/chat/mingo-chat-history.d.ts.map +1 -1
  95. package/dist/components/chat/mingo-chat-history.js +11 -5
  96. package/dist/components/chat/mingo-chat-rail.d.ts.map +1 -1
  97. package/dist/components/chat/mingo-chat-rail.js +2 -1
  98. package/dist/components/chat/mingo-info-card.d.ts.map +1 -1
  99. package/dist/components/chat/mingo-info-card.js +6 -5
  100. package/dist/components/chat/mingo-onboarding-card-skeleton.d.ts +3 -1
  101. package/dist/components/chat/mingo-onboarding-card-skeleton.d.ts.map +1 -1
  102. package/dist/components/chat/mingo-onboarding-card-skeleton.js +12 -12
  103. package/dist/components/chat/model-display.js +4 -4
  104. package/dist/components/chat/msp-organization-card-skeleton.js +5 -5
  105. package/dist/components/chat/quick-action-chip.d.ts +3 -3
  106. package/dist/components/chat/quick-action-chip.d.ts.map +1 -1
  107. package/dist/components/chat/quick-action-chip.js +12 -6
  108. package/dist/components/chat/utils/compact-card-classes.d.ts +4 -4
  109. package/dist/components/chat/utils/compact-card-classes.d.ts.map +1 -1
  110. package/dist/components/chat/utils/compact-card-classes.js +2 -2
  111. package/dist/components/contact/index.cjs +17 -15
  112. package/dist/components/content-loading-container.d.ts +1 -1
  113. package/dist/components/content-loading-container.d.ts.map +1 -1
  114. package/dist/components/content-loading-container.js +6 -7
  115. package/dist/components/docs/doc-viewer.d.ts.map +1 -1
  116. package/dist/components/docs/doc-viewer.js +3 -2
  117. package/dist/components/docs/index.cjs +20 -18
  118. package/dist/components/docs/skeletons.d.ts +7 -8
  119. package/dist/components/docs/skeletons.d.ts.map +1 -1
  120. package/dist/components/docs/skeletons.js +62 -61
  121. package/dist/components/embeds/embed-iframe.d.ts +6 -6
  122. package/dist/components/embeds/embed-iframe.d.ts.map +1 -1
  123. package/dist/components/embeds/embed-iframe.js +9 -4
  124. package/dist/components/embeds/index.cjs +19 -15
  125. package/dist/components/embeds/index.d.ts +2 -2
  126. package/dist/components/embeds/index.d.ts.map +1 -1
  127. package/dist/components/embeds/index.js +2 -1
  128. package/dist/components/embeds/linkedin-embed-client.d.ts.map +1 -1
  129. package/dist/components/embeds/linkedin-embed-client.js +7 -6
  130. package/dist/components/embeds/markdown-image.d.ts.map +1 -1
  131. package/dist/components/embeds/markdown-image.js +5 -3
  132. package/dist/components/embeds/og-link-preview.d.ts +19 -18
  133. package/dist/components/embeds/og-link-preview.d.ts.map +1 -1
  134. package/dist/components/embeds/og-link-preview.js +143 -88
  135. package/dist/components/embeds/reddit-embed-client.d.ts.map +1 -1
  136. package/dist/components/embeds/reddit-embed-client.js +10 -9
  137. package/dist/components/embeds/twitter-embed-client.d.ts.map +1 -1
  138. package/dist/components/embeds/twitter-embed-client.js +10 -9
  139. package/dist/components/faq/faq-section.d.ts.map +1 -1
  140. package/dist/components/faq/faq-section.js +9 -5
  141. package/dist/components/faq/index.cjs +18 -16
  142. package/dist/components/features/board/ticket-card-skeleton.js +8 -8
  143. package/dist/components/features/capability-explorer.d.ts +3 -1
  144. package/dist/components/features/capability-explorer.d.ts.map +1 -1
  145. package/dist/components/features/capability-explorer.js +27 -24
  146. package/dist/components/features/devices/device-selector/device-selector-skeleton.d.ts +5 -2
  147. package/dist/components/features/devices/device-selector/device-selector-skeleton.d.ts.map +1 -1
  148. package/dist/components/features/devices/device-selector/device-selector-skeleton.js +2 -2
  149. package/dist/components/features/devices/device-selector/device-selector.d.ts +1 -1
  150. package/dist/components/features/devices/device-selector/device-selector.d.ts.map +1 -1
  151. package/dist/components/features/devices/device-selector/device-selector.js +2 -0
  152. package/dist/components/features/devices/device-selector/device-selector.types.d.ts +2 -0
  153. package/dist/components/features/devices/device-selector/device-selector.types.d.ts.map +1 -1
  154. package/dist/components/features/devices/devices-grid.d.ts +3 -1
  155. package/dist/components/features/devices/devices-grid.d.ts.map +1 -1
  156. package/dist/components/features/devices/devices-grid.js +3 -2
  157. package/dist/components/features/devices/devices-panel-view.d.ts +6 -1
  158. package/dist/components/features/devices/devices-panel-view.d.ts.map +1 -1
  159. package/dist/components/features/devices/devices-panel-view.js +4 -1
  160. package/dist/components/features/devices/devices-table-columns.d.ts +3 -1
  161. package/dist/components/features/devices/devices-table-columns.d.ts.map +1 -1
  162. package/dist/components/features/devices/devices-table-columns.js +2 -0
  163. package/dist/components/features/index.cjs +18 -14
  164. package/dist/components/features/logs/logs-table-view.d.ts +3 -1
  165. package/dist/components/features/logs/logs-table-view.d.ts.map +1 -1
  166. package/dist/components/features/logs/logs-table-view.js +2 -2
  167. package/dist/components/features/model-token-rates.d.ts +4 -1
  168. package/dist/components/features/model-token-rates.d.ts.map +1 -1
  169. package/dist/components/features/model-token-rates.js +18 -23
  170. package/dist/components/features/notifications/index.d.ts +2 -2
  171. package/dist/components/features/notifications/index.d.ts.map +1 -1
  172. package/dist/components/features/notifications/index.js +2 -1
  173. package/dist/components/features/notifications/notification-drawer.d.ts.map +1 -1
  174. package/dist/components/features/notifications/notification-drawer.js +9 -16
  175. package/dist/components/features/notifications/notification-tile.d.ts +14 -0
  176. package/dist/components/features/notifications/notification-tile.d.ts.map +1 -1
  177. package/dist/components/features/notifications/notification-tile.js +36 -1
  178. package/dist/components/features/policies/policy-summary-cards.js +2 -2
  179. package/dist/components/features/push-button-selector.d.ts.map +1 -1
  180. package/dist/components/features/push-button-selector.js +12 -7
  181. package/dist/components/features/remote-session/remote-desktop-view.d.ts +4 -1
  182. package/dist/components/features/remote-session/remote-desktop-view.d.ts.map +1 -1
  183. package/dist/components/features/remote-session/remote-desktop-view.js +14 -10
  184. package/dist/components/features/waitlist-form.d.ts.map +1 -1
  185. package/dist/components/features/waitlist-form.js +6 -5
  186. package/dist/components/help-center-pages/download-apps-page.d.ts.map +1 -1
  187. package/dist/components/help-center-pages/download-apps-page.js +2 -1
  188. package/dist/components/help-center-pages/index.cjs +127 -119
  189. package/dist/components/help-center-pages/trust-center-page.d.ts +4 -1
  190. package/dist/components/help-center-pages/trust-center-page.d.ts.map +1 -1
  191. package/dist/components/help-center-pages/trust-center-page.js +3 -2
  192. package/dist/components/help-center-pages/trust-center-sections.d.ts +4 -1
  193. package/dist/components/help-center-pages/trust-center-sections.d.ts.map +1 -1
  194. package/dist/components/help-center-pages/trust-center-sections.js +5 -2
  195. package/dist/components/index.cjs +70 -112
  196. package/dist/components/index.d.ts +0 -2
  197. package/dist/components/index.d.ts.map +1 -1
  198. package/dist/components/index.js +0 -2
  199. package/dist/components/layout/title-block.d.ts.map +1 -1
  200. package/dist/components/layout/title-block.js +18 -11
  201. package/dist/components/loading/card-skeleton.d.ts +6 -3
  202. package/dist/components/loading/card-skeleton.d.ts.map +1 -1
  203. package/dist/components/loading/card-skeleton.js +7 -27
  204. package/dist/components/loading/category-card-skeleton.d.ts.map +1 -1
  205. package/dist/components/loading/category-card-skeleton.js +2 -4
  206. package/dist/components/loading/category-vendor-selector-skeleton.d.ts +3 -1
  207. package/dist/components/loading/category-vendor-selector-skeleton.d.ts.map +1 -1
  208. package/dist/components/loading/category-vendor-selector-skeleton.js +9 -4
  209. package/dist/components/loading/device-card-skeleton.d.ts +18 -9
  210. package/dist/components/loading/device-card-skeleton.d.ts.map +1 -1
  211. package/dist/components/loading/device-card-skeleton.js +30 -21
  212. package/dist/components/loading/index.d.ts +3 -4
  213. package/dist/components/loading/index.d.ts.map +1 -1
  214. package/dist/components/loading/index.js +6 -29
  215. package/dist/components/loading/loading-region.d.ts +33 -0
  216. package/dist/components/loading/loading-region.d.ts.map +1 -0
  217. package/dist/components/loading/loading-region.js +22 -0
  218. package/dist/components/loading/margin-report-skeleton.d.ts +3 -1
  219. package/dist/components/loading/margin-report-skeleton.d.ts.map +1 -1
  220. package/dist/components/loading/margin-report-skeleton.js +70 -61
  221. package/dist/components/loading/msp-profile-form-skeleton.d.ts +3 -1
  222. package/dist/components/loading/msp-profile-form-skeleton.d.ts.map +1 -1
  223. package/dist/components/loading/msp-profile-form-skeleton.js +6 -5
  224. package/dist/components/loading/organization-card-skeleton.d.ts +3 -1
  225. package/dist/components/loading/organization-card-skeleton.d.ts.map +1 -1
  226. package/dist/components/loading/organization-card-skeleton.js +5 -5
  227. package/dist/components/loading/organization-icon-skeleton.d.ts.map +1 -1
  228. package/dist/components/loading/organization-icon-skeleton.js +2 -1
  229. package/dist/components/loading/page-layout-skeleton.d.ts +21 -6
  230. package/dist/components/loading/page-layout-skeleton.d.ts.map +1 -1
  231. package/dist/components/loading/page-layout-skeleton.js +283 -266
  232. package/dist/components/loading/settings-form-skeleton.d.ts +17 -0
  233. package/dist/components/loading/settings-form-skeleton.d.ts.map +1 -0
  234. package/dist/components/loading/settings-form-skeleton.js +42 -0
  235. package/dist/components/loading/unified-skeleton.d.ts +11 -4
  236. package/dist/components/loading/unified-skeleton.d.ts.map +1 -1
  237. package/dist/components/loading/unified-skeleton.js +14 -89
  238. package/dist/components/loading/wizard-layout-skeleton.d.ts +3 -1
  239. package/dist/components/loading/wizard-layout-skeleton.d.ts.map +1 -1
  240. package/dist/components/loading/wizard-layout-skeleton.js +3 -2
  241. package/dist/components/media-carousel.d.ts.map +1 -1
  242. package/dist/components/media-carousel.js +2 -1
  243. package/dist/components/meeting-scheduler/booking-form.d.ts.map +1 -1
  244. package/dist/components/meeting-scheduler/booking-form.js +14 -8
  245. package/dist/components/meeting-scheduler/context-panel.d.ts.map +1 -1
  246. package/dist/components/meeting-scheduler/context-panel.js +8 -7
  247. package/dist/components/meeting-scheduler/directory.d.ts.map +1 -1
  248. package/dist/components/meeting-scheduler/directory.js +10 -9
  249. package/dist/components/meeting-scheduler/index.cjs +85 -75
  250. package/dist/components/meeting-scheduler/index.d.ts.map +1 -1
  251. package/dist/components/meeting-scheduler/index.js +3 -2
  252. package/dist/components/meeting-scheduler/modal-header.d.ts.map +1 -1
  253. package/dist/components/meeting-scheduler/modal-header.js +8 -7
  254. package/dist/components/meeting-scheduler/slot-picker.d.ts.map +1 -1
  255. package/dist/components/meeting-scheduler/slot-picker.js +4 -3
  256. package/dist/components/navigation/app-header.d.ts.map +1 -1
  257. package/dist/components/navigation/app-header.js +8 -7
  258. package/dist/components/navigation/index.cjs +19 -17
  259. package/dist/components/navigation/multi-level-navigation.d.ts.map +1 -1
  260. package/dist/components/navigation/multi-level-navigation.js +3 -2
  261. package/dist/components/navigation/navigation-sidebar-item.d.ts.map +1 -1
  262. package/dist/components/navigation/navigation-sidebar-item.js +3 -2
  263. package/dist/components/onboarding-guides/index.cjs +19 -17
  264. package/dist/components/onboarding-guides/onboarding-guides-catalog-skeleton.d.ts +4 -1
  265. package/dist/components/onboarding-guides/onboarding-guides-catalog-skeleton.d.ts.map +1 -1
  266. package/dist/components/onboarding-guides/onboarding-guides-catalog-skeleton.js +12 -8
  267. package/dist/components/product-demo/index.cjs +16 -15
  268. package/dist/components/product-demo/product-screen.d.ts.map +1 -1
  269. package/dist/components/product-demo/product-screen.js +4 -4
  270. package/dist/components/profile/ProfileLoadingSkeleton.d.ts +3 -1
  271. package/dist/components/profile/ProfileLoadingSkeleton.d.ts.map +1 -1
  272. package/dist/components/profile/ProfileLoadingSkeleton.js +10 -8
  273. package/dist/components/related-content/index.cjs +7 -5
  274. package/dist/components/related-content/related-content-section.d.ts.map +1 -1
  275. package/dist/components/related-content/related-content-section.js +3 -2
  276. package/dist/components/shared/delivery/delivery-table.d.ts.map +1 -1
  277. package/dist/components/shared/delivery/delivery-table.js +8 -7
  278. package/dist/components/shared/detail-page-skeleton.d.ts +5 -1
  279. package/dist/components/shared/detail-page-skeleton.d.ts.map +1 -1
  280. package/dist/components/shared/detail-page-skeleton.js +18 -14
  281. package/dist/components/shared/dev-section/dev-card-row.d.ts +3 -1
  282. package/dist/components/shared/dev-section/dev-card-row.d.ts.map +1 -1
  283. package/dist/components/shared/dev-section/dev-card-row.js +22 -9
  284. package/dist/components/shared/legal-document/legal-document-page.d.ts.map +1 -1
  285. package/dist/components/shared/legal-document/legal-document-page.js +8 -7
  286. package/dist/components/shared/onboarding/onboarding-step-card.d.ts.map +1 -1
  287. package/dist/components/shared/onboarding/onboarding-step-card.js +3 -2
  288. package/dist/components/shared/onboarding/onboarding-walkthrough.d.ts.map +1 -1
  289. package/dist/components/shared/onboarding/onboarding-walkthrough.js +2 -1
  290. package/dist/components/shared/product-release/index.d.ts +0 -1
  291. package/dist/components/shared/product-release/index.d.ts.map +1 -1
  292. package/dist/components/shared/product-release/index.js +1 -3
  293. package/dist/components/shared/product-release/product-release-card-skeleton.d.ts.map +1 -1
  294. package/dist/components/shared/product-release/product-release-card-skeleton.js +21 -20
  295. package/dist/components/shared/product-release/product-releases-view.d.ts.map +1 -1
  296. package/dist/components/shared/product-release/product-releases-view.js +2 -1
  297. package/dist/components/shared/roadmap/roadmap-grid-skeleton.d.ts +6 -13
  298. package/dist/components/shared/roadmap/roadmap-grid-skeleton.d.ts.map +1 -1
  299. package/dist/components/shared/roadmap/roadmap-grid-skeleton.js +13 -25
  300. package/dist/components/tickets/help-center-create-form.d.ts +4 -1
  301. package/dist/components/tickets/help-center-create-form.d.ts.map +1 -1
  302. package/dist/components/tickets/help-center-create-form.js +38 -26
  303. package/dist/components/tickets/index.cjs +22 -20
  304. package/dist/components/tickets/ticket-center.d.ts.map +1 -1
  305. package/dist/components/tickets/ticket-center.js +13 -10
  306. package/dist/components/tickets/ticket-detail-drawer.d.ts.map +1 -1
  307. package/dist/components/tickets/ticket-detail-drawer.js +2 -1
  308. package/dist/components/ui/admin-form-drawer.d.ts.map +1 -1
  309. package/dist/components/ui/admin-form-drawer.js +6 -8
  310. package/dist/components/ui/admin-form-modal.d.ts.map +1 -1
  311. package/dist/components/ui/admin-form-modal.js +12 -11
  312. package/dist/components/ui/analyzing-state.d.ts +1 -1
  313. package/dist/components/ui/analyzing-state.d.ts.map +1 -1
  314. package/dist/components/ui/analyzing-state.js +4 -10
  315. package/dist/components/ui/content-loader.d.ts +5 -1
  316. package/dist/components/ui/content-loader.d.ts.map +1 -1
  317. package/dist/components/ui/content-loader.js +27 -23
  318. package/dist/components/ui/dashboard-info-card.d.ts +17 -3
  319. package/dist/components/ui/dashboard-info-card.d.ts.map +1 -1
  320. package/dist/components/ui/dashboard-info-card.js +30 -10
  321. package/dist/components/ui/data-attribution.d.ts +6 -0
  322. package/dist/components/ui/data-attribution.d.ts.map +1 -1
  323. package/dist/components/ui/data-attribution.js +12 -1
  324. package/dist/components/ui/data-table/data-table-body.d.ts +6 -1
  325. package/dist/components/ui/data-table/data-table-body.d.ts.map +1 -1
  326. package/dist/components/ui/data-table/data-table-body.js +3 -1
  327. package/dist/components/ui/data-table/data-table-infinite-footer.d.ts.map +1 -1
  328. package/dist/components/ui/data-table/data-table-infinite-footer.js +3 -1
  329. package/dist/components/ui/data-table/data-table-skeleton.d.ts.map +1 -1
  330. package/dist/components/ui/data-table/data-table-skeleton.js +7 -5
  331. package/dist/components/ui/feature-card.d.ts.map +1 -1
  332. package/dist/components/ui/feature-card.js +7 -9
  333. package/dist/components/ui/file-manager/file-manager-skeleton.d.ts +3 -1
  334. package/dist/components/ui/file-manager/file-manager-skeleton.d.ts.map +1 -1
  335. package/dist/components/ui/file-manager/file-manager-skeleton.js +27 -21
  336. package/dist/components/ui/file-manager/file-manager-table.js +10 -10
  337. package/dist/components/ui/file-manager/index.cjs +45 -36
  338. package/dist/components/ui/filter-modal.d.ts.map +1 -1
  339. package/dist/components/ui/filter-modal.js +5 -5
  340. package/dist/components/ui/filter-pill-row.d.ts +10 -0
  341. package/dist/components/ui/filter-pill-row.d.ts.map +1 -1
  342. package/dist/components/ui/filter-pill-row.js +8 -1
  343. package/dist/components/ui/index.cjs +19 -28
  344. package/dist/components/ui/index.d.ts +0 -1
  345. package/dist/components/ui/index.d.ts.map +1 -1
  346. package/dist/components/ui/index.js +0 -1
  347. package/dist/components/ui/layout-hold.d.ts +5 -4
  348. package/dist/components/ui/layout-hold.d.ts.map +1 -1
  349. package/dist/components/ui/layout-hold.js +20 -29
  350. package/dist/components/ui/markdown/base-components.js +1 -1
  351. package/dist/components/ui/page-actions.d.ts.map +1 -1
  352. package/dist/components/ui/page-actions.js +6 -8
  353. package/dist/components/ui/photo-wall.d.ts.map +1 -1
  354. package/dist/components/ui/photo-wall.js +11 -18
  355. package/dist/components/ui/query-report-table/query-report-table-skeleton.d.ts +1 -1
  356. package/dist/components/ui/query-report-table/query-report-table-skeleton.d.ts.map +1 -1
  357. package/dist/components/ui/query-report-table/query-report-table-skeleton.js +28 -18
  358. package/dist/components/ui/query-report-table/query-report-table.d.ts +1 -1
  359. package/dist/components/ui/query-report-table/query-report-table.d.ts.map +1 -1
  360. package/dist/components/ui/query-report-table/query-report-table.js +3 -1
  361. package/dist/components/ui/query-report-table/types.d.ts +4 -0
  362. package/dist/components/ui/query-report-table/types.d.ts.map +1 -1
  363. package/dist/components/ui/skeleton-surface.d.ts +7 -0
  364. package/dist/components/ui/skeleton-surface.d.ts.map +1 -0
  365. package/dist/components/ui/skeleton-surface.js +5 -0
  366. package/dist/components/ui/table/table-skeleton.d.ts.map +1 -1
  367. package/dist/components/ui/table/table-skeleton.js +11 -13
  368. package/dist/components/ui/test-run.d.ts +6 -4
  369. package/dist/components/ui/test-run.d.ts.map +1 -1
  370. package/dist/components/ui/test-run.js +9 -5
  371. package/dist/{devices-WWMXIIHI.cjs → devices-FVXAGKVX.cjs} +17 -15
  372. package/dist/{embeddable-chat-IJHCGQ24.cjs → embeddable-chat-SNYQSMS7.cjs} +79 -77
  373. package/dist/index.cjs +24 -31
  374. package/dist/{knowledge-JZP4RIXB.cjs → knowledge-ZL3ZHBSL.cjs} +17 -15
  375. package/dist/{logs-WIRYFNUC.cjs → logs-KQCWDIOB.cjs} +24 -22
  376. package/dist/{policies-X7OJYA7G.cjs → policies-ARDCZ3CT.cjs} +20 -18
  377. package/dist/{remote-session-IYT4LWJC.cjs → remote-session-ZKP2W3IS.cjs} +9 -7
  378. package/dist/{scripts-GRMT2NGW.cjs → scripts-ZAMVWCY4.cjs} +23 -21
  379. package/dist/{software-update-G3QOB7RT.cjs → software-update-6F7BIYS3.cjs} +20 -18
  380. package/dist/{tickets-board-4MT6ZB4F.cjs → tickets-board-BNW4AYFL.cjs} +11 -10
  381. package/package.json +1 -1
  382. package/src/components/categories-cart.tsx +2 -4
  383. package/src/components/chat/chat-container.tsx +4 -4
  384. package/src/components/chat/chat-context-picker.tsx +3 -2
  385. package/src/components/chat/chat-message-row.tsx +6 -7
  386. package/src/components/chat/chat-message-skeleton.tsx +11 -6
  387. package/src/components/chat/chat-sidebar-skeleton.tsx +4 -3
  388. package/src/components/chat/chat-top-navigation.tsx +4 -4
  389. package/src/components/chat/context-items-list.tsx +9 -3
  390. package/src/components/chat/entity-cards/admin-content-card-grid.tsx +65 -18
  391. package/src/components/chat/entity-cards/admin-content-card.tsx +2 -1
  392. package/src/components/chat/entity-cards/blog-card.tsx +13 -12
  393. package/src/components/chat/entity-cards/campaign-card-admin.tsx +5 -4
  394. package/src/components/chat/entity-cards/case-study-card.tsx +19 -18
  395. package/src/components/chat/entity-cards/chat-ticket-item.tsx +5 -5
  396. package/src/components/chat/entity-cards/customer-interview-card.tsx +15 -14
  397. package/src/components/chat/entity-cards/data-room-doc-card.tsx +7 -6
  398. package/src/components/chat/entity-cards/design-doc-card.tsx +0 -2
  399. package/src/components/chat/entity-cards/generic-entity-card.tsx +8 -7
  400. package/src/components/chat/entity-cards/github-activity-card.tsx +11 -10
  401. package/src/components/chat/entity-cards/hubspot-ticket-card.tsx +16 -15
  402. package/src/components/chat/entity-cards/index.ts +2 -0
  403. package/src/components/chat/entity-cards/investor-update-card.tsx +12 -11
  404. package/src/components/chat/entity-cards/onboarding-guide-card.tsx +21 -22
  405. package/src/components/chat/entity-cards/program-card.tsx +29 -28
  406. package/src/components/chat/entity-cards/roadmap-card.tsx +22 -23
  407. package/src/components/chat/entity-cards/slack-message-card.tsx +12 -11
  408. package/src/components/chat/guide-welcome.tsx +2 -2
  409. package/src/components/chat/mingo-archive-list.tsx +2 -1
  410. package/src/components/chat/mingo-chat-history.tsx +18 -9
  411. package/src/components/chat/mingo-chat-rail.tsx +2 -1
  412. package/src/components/chat/mingo-info-card.tsx +6 -5
  413. package/src/components/chat/mingo-onboarding-card-skeleton.tsx +15 -13
  414. package/src/components/chat/model-display.tsx +4 -4
  415. package/src/components/chat/msp-organization-card-skeleton.tsx +5 -5
  416. package/src/components/chat/quick-action-chip.tsx +17 -14
  417. package/src/components/chat/utils/compact-card-classes.ts +4 -5
  418. package/src/components/content-loading-container.tsx +7 -8
  419. package/src/components/docs/doc-viewer.tsx +3 -2
  420. package/src/components/docs/skeletons.tsx +64 -63
  421. package/src/components/embeds/embed-iframe.tsx +16 -9
  422. package/src/components/embeds/index.ts +2 -2
  423. package/src/components/embeds/linkedin-embed-client.tsx +7 -6
  424. package/src/components/embeds/markdown-image.tsx +5 -3
  425. package/src/components/embeds/og-link-preview.tsx +162 -79
  426. package/src/components/embeds/reddit-embed-client.tsx +10 -9
  427. package/src/components/embeds/twitter-embed-client.tsx +10 -9
  428. package/src/components/faq/faq-section.tsx +13 -6
  429. package/src/components/features/board/ticket-card-skeleton.tsx +8 -8
  430. package/src/components/features/capability-explorer.tsx +61 -30
  431. package/src/components/features/devices/device-selector/device-selector-skeleton.tsx +9 -3
  432. package/src/components/features/devices/device-selector/device-selector.tsx +2 -0
  433. package/src/components/features/devices/device-selector/device-selector.types.ts +2 -0
  434. package/src/components/features/devices/devices-grid.tsx +4 -1
  435. package/src/components/features/devices/devices-panel-view.tsx +9 -1
  436. package/src/components/features/devices/devices-table-columns.tsx +4 -0
  437. package/src/components/features/logs/logs-table-view.tsx +4 -2
  438. package/src/components/features/model-token-rates.tsx +27 -24
  439. package/src/components/features/notifications/index.ts +2 -2
  440. package/src/components/features/notifications/notification-drawer.tsx +7 -10
  441. package/src/components/features/notifications/notification-tile.tsx +57 -0
  442. package/src/components/features/policies/policy-summary-cards.tsx +2 -2
  443. package/src/components/features/push-button-selector.tsx +20 -11
  444. package/src/components/features/remote-session/remote-desktop-view.tsx +26 -16
  445. package/src/components/features/waitlist-form.tsx +6 -5
  446. package/src/components/help-center-pages/download-apps-page.tsx +3 -2
  447. package/src/components/help-center-pages/trust-center-page.tsx +6 -2
  448. package/src/components/help-center-pages/trust-center-sections.tsx +9 -3
  449. package/src/components/index.ts +0 -2
  450. package/src/components/layout/title-block.tsx +17 -15
  451. package/src/components/loading/card-skeleton.tsx +14 -46
  452. package/src/components/loading/category-card-skeleton.tsx +2 -4
  453. package/src/components/loading/category-vendor-selector-skeleton.tsx +12 -5
  454. package/src/components/loading/device-card-skeleton.tsx +58 -51
  455. package/src/components/loading/index.ts +5 -19
  456. package/src/components/loading/loading-region.tsx +60 -0
  457. package/src/components/loading/margin-report-skeleton.tsx +45 -34
  458. package/src/components/loading/msp-profile-form-skeleton.tsx +9 -6
  459. package/src/components/loading/organization-card-skeleton.tsx +8 -6
  460. package/src/components/loading/organization-icon-skeleton.tsx +3 -2
  461. package/src/components/loading/page-layout-skeleton.tsx +162 -133
  462. package/src/components/loading/settings-form-skeleton.tsx +52 -0
  463. package/src/components/loading/unified-skeleton.tsx +26 -71
  464. package/src/components/loading/wizard-layout-skeleton.tsx +6 -3
  465. package/src/components/media-carousel.tsx +2 -1
  466. package/src/components/meeting-scheduler/booking-form.tsx +10 -7
  467. package/src/components/meeting-scheduler/context-panel.tsx +8 -7
  468. package/src/components/meeting-scheduler/directory.tsx +10 -9
  469. package/src/components/meeting-scheduler/index.tsx +5 -4
  470. package/src/components/meeting-scheduler/modal-header.tsx +8 -7
  471. package/src/components/meeting-scheduler/slot-picker.tsx +4 -3
  472. package/src/components/navigation/app-header.tsx +8 -7
  473. package/src/components/navigation/multi-level-navigation.tsx +3 -2
  474. package/src/components/navigation/navigation-sidebar-item.tsx +3 -2
  475. package/src/components/onboarding-guides/onboarding-guides-catalog-skeleton.tsx +17 -10
  476. package/src/components/product-demo/product-screen.tsx +4 -4
  477. package/src/components/profile/ProfileLoadingSkeleton.tsx +13 -9
  478. package/src/components/related-content/related-content-section.tsx +5 -4
  479. package/src/components/shared/delivery/delivery-table.tsx +8 -7
  480. package/src/components/shared/detail-page-skeleton.tsx +22 -14
  481. package/src/components/shared/dev-section/dev-card-row.tsx +23 -10
  482. package/src/components/shared/legal-document/legal-document-page.tsx +8 -7
  483. package/src/components/shared/onboarding/onboarding-step-card.tsx +3 -2
  484. package/src/components/shared/onboarding/onboarding-walkthrough.tsx +2 -1
  485. package/src/components/shared/product-release/index.ts +0 -1
  486. package/src/components/shared/product-release/product-release-card-skeleton.tsx +23 -25
  487. package/src/components/shared/product-release/product-releases-view.tsx +3 -2
  488. package/src/components/shared/roadmap/roadmap-grid-skeleton.tsx +14 -56
  489. package/src/components/tickets/help-center-create-form.tsx +23 -12
  490. package/src/components/tickets/ticket-center.tsx +17 -11
  491. package/src/components/tickets/ticket-detail-drawer.tsx +3 -2
  492. package/src/components/ui/admin-form-drawer.tsx +7 -7
  493. package/src/components/ui/admin-form-modal.tsx +9 -8
  494. package/src/components/ui/analyzing-state.tsx +5 -8
  495. package/src/components/ui/content-loader.tsx +31 -23
  496. package/src/components/ui/dashboard-info-card.tsx +81 -20
  497. package/src/components/ui/data-attribution.tsx +18 -0
  498. package/src/components/ui/data-table/data-table-body.tsx +9 -2
  499. package/src/components/ui/data-table/data-table-infinite-footer.tsx +4 -2
  500. package/src/components/ui/data-table/data-table-skeleton.tsx +8 -5
  501. package/src/components/ui/feature-card.tsx +27 -11
  502. package/src/components/ui/file-manager/file-manager-skeleton.tsx +30 -22
  503. package/src/components/ui/file-manager/file-manager-table.tsx +10 -10
  504. package/src/components/ui/filter-modal.tsx +5 -5
  505. package/src/components/ui/filter-pill-row.tsx +19 -0
  506. package/src/components/ui/index.ts +0 -1
  507. package/src/components/ui/layout-hold.tsx +30 -38
  508. package/src/components/ui/markdown/base-components.tsx +1 -1
  509. package/src/components/ui/page-actions.tsx +10 -8
  510. package/src/components/ui/photo-wall.tsx +4 -7
  511. package/src/components/ui/query-report-table/query-report-table-skeleton.tsx +13 -7
  512. package/src/components/ui/query-report-table/query-report-table.tsx +2 -0
  513. package/src/components/ui/query-report-table/types.ts +4 -0
  514. package/src/components/ui/skeleton-surface.ts +6 -0
  515. package/src/components/ui/table/table-skeleton.tsx +11 -13
  516. package/src/components/ui/test-run.tsx +30 -22
  517. package/src/styles/ods-colors.css +2 -2
  518. package/dist/chunk-5M5C6UV4.cjs +0 -125
  519. package/dist/components/dynamic-skeleton.d.ts +0 -108
  520. package/dist/components/dynamic-skeleton.d.ts.map +0 -1
  521. package/dist/components/dynamic-skeleton.js +0 -221
  522. package/dist/components/loading/content-skeleton.d.ts +0 -73
  523. package/dist/components/loading/content-skeleton.d.ts.map +0 -1
  524. package/dist/components/loading/content-skeleton.js +0 -217
  525. package/dist/components/loading/users-grid-skeleton.d.ts +0 -7
  526. package/dist/components/loading/users-grid-skeleton.d.ts.map +0 -1
  527. package/dist/components/loading/users-grid-skeleton.js +0 -13
  528. package/dist/components/shared/product-release/release-detail-skeleton.d.ts +0 -2
  529. package/dist/components/shared/product-release/release-detail-skeleton.d.ts.map +0 -1
  530. package/dist/components/shared/product-release/release-detail-skeleton.js +0 -9
  531. package/dist/components/skeleton.d.ts +0 -4
  532. package/dist/components/skeleton.d.ts.map +0 -1
  533. package/dist/components/skeleton.js +0 -9
  534. package/dist/components/ui/skeleton.d.ts +0 -44
  535. package/dist/components/ui/skeleton.d.ts.map +0 -1
  536. package/dist/components/ui/skeleton.js +0 -103
  537. package/dist/components/vendor-page-skeleton.d.ts +0 -2
  538. package/dist/components/vendor-page-skeleton.d.ts.map +0 -1
  539. package/dist/components/vendor-page-skeleton.js +0 -9
  540. package/src/components/dynamic-skeleton.tsx +0 -365
  541. package/src/components/loading/content-skeleton.tsx +0 -374
  542. package/src/components/loading/users-grid-skeleton.tsx +0 -36
  543. package/src/components/shared/product-release/release-detail-skeleton.tsx +0 -7
  544. package/src/components/skeleton.tsx +0 -8
  545. package/src/components/ui/skeleton.tsx +0 -173
  546. package/src/components/vendor-page-skeleton.tsx +0 -7
@@ -5,6 +5,9 @@ import { useState, useEffect, Component, type ReactNode } from 'react';
5
5
  import Image from '../../embed-shims/next-image';
6
6
  import Link from '../../embed-shims/next-link';
7
7
  import { useImageEdgeColor } from '../../hooks';
8
+ import { useOgPlaceholderUrl } from '../../hooks/use-og-placeholder-url';
9
+ import { UnifiedSkeleton } from '../loading/unified-skeleton';
10
+ import { TruncateText } from '../ui/truncate-text';
8
11
 
9
12
  /**
10
13
  * Open-Graph metadata returned by the consumer's scrape endpoint.
@@ -65,17 +68,6 @@ export class OGLinkErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoun
65
68
  }
66
69
  }
67
70
 
68
- /**
69
- * Builds a placeholder image URL when the scrape returns no image. Hub passes
70
- * its own `buildOgPlaceholderUrl` (which hits `/api/og-placeholder?…&platform=`;
71
- * the route resolves the platform's brand colors server-side); other embedders
72
- * can omit the prop to disable the placeholder entirely.
73
- *
74
- * Receives the post-scrape `title` and `siteName` so the placeholder can echo
75
- * the actual card content, not a generic graphic.
76
- */
77
- export type BuildPlaceholderUrl = (title: string, siteName: string) => string | null;
78
-
79
71
  export interface OGLinkPreviewProps {
80
72
  /** The external URL to preview. */
81
73
  url: string;
@@ -92,10 +84,6 @@ export interface OGLinkPreviewProps {
92
84
  * `'/api/og-scraper'` matches the hub's route. Override if the
93
85
  * embedder serves the same `OGData` shape from a different path. */
94
86
  ogEndpointPath?: string;
95
- /** Optional placeholder-builder. Omit to disable the placeholder image
96
- * (the card then degrades to a favicon+title chip when no scraped image
97
- * is available). The hub injects its `buildOgPlaceholderUrl` here. */
98
- buildPlaceholderUrl?: BuildPlaceholderUrl;
99
87
  /** CURATED title — our own copy for this link (e.g. a CMS-managed press
100
88
  * row). Wins over the scrape; see the precedence rule on the component. */
101
89
  curatedTitle?: string;
@@ -111,13 +99,28 @@ export interface OGLinkPreviewProps {
111
99
  publicationLogo?: string;
112
100
  /** Card variant. `compact` = horizontal layout (~120px tall) suited for
113
101
  * in-doc placements; `default` = larger vertical layout for press / hero
114
- * positions. */
115
- variant?: 'default' | 'compact';
116
- /** Disable the synthesized placeholder image even when `buildPlaceholderUrl`
117
- * is provided — used by the markdown renderer to keep doc cards lighter. */
102
+ * positions; `tile` = a text-first press tile (favicon, outlet and `meta`,
103
+ * `kicker`, headline, excerpt) drawn from the props alone, with NO image and
104
+ * NO scrape, for uniform press walls where outlet imagery is unreliable. */
105
+ variant?: 'default' | 'compact' | 'tile';
106
+ /** The runtime's og-placeholder image (`useOgPlaceholderUrl`) when no image
107
+ * resolves. Default true; the markdown renderer turns it off to keep doc
108
+ * cards lighter. */
118
109
  enablePlaceholder?: boolean;
110
+ /** Extra footer-line content (a date, a topic tag) after the site name, on
111
+ * the `default` and `tile` cards: the sanctioned way to add caller text. */
112
+ meta?: ReactNode;
113
+ /** A one-line label ABOVE the `tile` headline that says WHY the item is shown
114
+ * (e.g. a news theme). */
115
+ kicker?: ReactNode;
119
116
  }
120
117
 
118
+ const lineClamp = (lines: number): React.CSSProperties => ({
119
+ display: '-webkit-box',
120
+ WebkitLineClamp: lines,
121
+ WebkitBoxOrient: 'vertical',
122
+ });
123
+
121
124
  function getDomain(urlStr: string): string {
122
125
  try {
123
126
  return new URL(urlStr).hostname.replace('www.', '');
@@ -166,6 +169,26 @@ const Favicon = ({ src, size = 'w-6 h-6' }: { src: string; size?: string }) => (
166
169
  />
167
170
  );
168
171
 
172
+ /**
173
+ * The `tile` card while its list loads: the tile's exact geometry (the `p-3`
174
+ * card, the source row with a favicon dot, two headline lines, the excerpt
175
+ * line), owned here so the tile and its loading state cannot drift apart.
176
+ */
177
+ export function OGLinkTileSkeleton() {
178
+ return (
179
+ <div className="flex min-w-0 flex-col gap-1.5 rounded-lg border border-ods-border bg-ods-card p-3">
180
+ <div className="flex items-center gap-1.5">
181
+ <UnifiedSkeleton className="h-4 w-4 flex-shrink-0 rounded" />
182
+ <UnifiedSkeleton className="h-3 w-20 rounded" />
183
+ <UnifiedSkeleton className="ml-auto h-3 w-9 rounded" />
184
+ </div>
185
+ <UnifiedSkeleton className="h-3.5 w-full rounded" />
186
+ <UnifiedSkeleton className="h-3.5 w-3/4 rounded" />
187
+ <UnifiedSkeleton className="h-3 w-5/6 rounded" />
188
+ </div>
189
+ );
190
+ }
191
+
169
192
  /**
170
193
  * Rich Open-Graph link preview card with skeleton, fallback, and image-edge
171
194
  * background detection.
@@ -200,7 +223,6 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
200
223
  url,
201
224
  apiBaseUrl,
202
225
  ogEndpointPath = '/api/og-scraper',
203
- buildPlaceholderUrl,
204
226
  curatedTitle,
205
227
  curatedDescription,
206
228
  curatedImage,
@@ -208,6 +230,8 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
208
230
  publicationLogo,
209
231
  variant = 'default',
210
232
  enablePlaceholder = true,
233
+ meta,
234
+ kicker,
211
235
  }) => {
212
236
  const [ogData, setOgData] = useState<OGData | null>(null);
213
237
  const [loading, setLoading] = useState(true);
@@ -236,8 +260,11 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
236
260
  isValidUrl = false;
237
261
  }
238
262
 
263
+ const isTile = variant === 'tile';
264
+
239
265
  useEffect(() => {
240
- if (!isValidUrl || isLocalhost) return undefined;
266
+ // A tile is drawn from its props alone: no scrape.
267
+ if (!isValidUrl || isLocalhost || isTile) return undefined;
241
268
 
242
269
  // A `url` change starts a second fetch while the first is still in flight.
243
270
  // Without this guard the SUPERSEDED response can land last and paint the
@@ -296,14 +323,20 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
296
323
  return () => {
297
324
  cancelled = true;
298
325
  };
299
- }, [url, isValidUrl, isLocalhost, apiBaseUrl, ogEndpointPath]);
326
+ }, [url, isValidUrl, isLocalhost, isTile, apiBaseUrl, ogEndpointPath]);
300
327
 
301
328
  const isCompact = variant === 'compact';
302
329
  const domain = getDomain(url);
303
330
 
331
+ // When the scrape fails, the card is built from the props, so one render
332
+ // path serves both. The same props-built card also paints IMMEDIATELY while
333
+ // the scrape is in flight whenever the caller curated a title: the card is at
334
+ // its final size from the first paint and the scrape only refines it, so a
335
+ // slow scrape cannot hold one card of a row in a skeleton and then jump the
336
+ // row's height. The skeleton is only for a caller with nothing but a URL.
304
337
  const effectiveData: OGData | null =
305
338
  ogData ??
306
- (error
339
+ (error || (loading && curatedTitle)
307
340
  ? {
308
341
  title: curatedTitle || domainToTitle(domain),
309
342
  description: curatedDescription || domain,
@@ -315,12 +348,12 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
315
348
  }
316
349
  : null);
317
350
 
318
- // Hub-injected placeholder builder — fires only when the post-scrape image
319
- // chain is empty AND `enablePlaceholder` is true. `null` when unprovided.
320
- const placeholderImageUrl =
321
- enablePlaceholder && buildPlaceholderUrl && effectiveData?.title
322
- ? buildPlaceholderUrl(effectiveData.title, effectiveData.siteName || domain)
323
- : null;
351
+ // The runtime's branded placeholder, last in the image chain below.
352
+ const placeholderImageUrl = useOgPlaceholderUrl({
353
+ title: effectiveData?.title,
354
+ siteName: effectiveData?.siteName || domain,
355
+ enabled: enablePlaceholder && !isTile,
356
+ });
324
357
 
325
358
  // THE precedence rule, in one place (see the component doc). Each candidate
326
359
  // carries its SLOT, so the winner is identified by where it came from and
@@ -346,40 +379,40 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
346
379
  isCompact ? (
347
380
  <div className="my-4">
348
381
  <div className="flex h-[120px] flex-row overflow-hidden rounded-lg border border-ods-border bg-ods-card">
349
- <div className="h-full w-[200px] flex-shrink-0 animate-pulse bg-ods-border" />
382
+ <UnifiedSkeleton className="h-full w-[200px] flex-shrink-0" />
350
383
  <div className="flex flex-1 flex-col justify-center p-3">
351
- <div className="mb-2 h-4 w-3/4 animate-pulse rounded bg-ods-border" />
352
- <div className="mb-1 h-3 w-full animate-pulse rounded bg-ods-border" />
353
- <div className="mb-2 h-3 w-2/3 animate-pulse rounded bg-ods-border" />
354
- <div className="h-3 w-1/3 animate-pulse rounded bg-ods-border" />
384
+ <UnifiedSkeleton className="mb-2 h-4 w-3/4 rounded" />
385
+ <UnifiedSkeleton className="mb-1 h-3 w-full rounded" />
386
+ <UnifiedSkeleton className="mb-2 h-3 w-2/3 rounded" />
387
+ <UnifiedSkeleton className="h-3 w-1/3 rounded" />
355
388
  </div>
356
389
  </div>
357
390
  </div>
358
391
  ) : (
359
392
  <div className="my-6">
360
393
  <div className="block overflow-hidden rounded-lg border border-ods-border bg-ods-card">
361
- <div className="relative aspect-video w-full animate-pulse overflow-hidden bg-ods-border" />
394
+ <UnifiedSkeleton className="relative aspect-video w-full overflow-hidden rounded-none" />
362
395
  <div className="p-4">
363
396
  <div className="flex items-start gap-3">
364
- <div className="mt-0.5 h-6 w-6 flex-shrink-0 animate-pulse rounded bg-ods-border" />
397
+ <UnifiedSkeleton className="mt-0.5 h-6 w-6 flex-shrink-0 rounded" />
365
398
  <div className="min-w-0 flex-1">
366
- <div className="mb-2 h-[2.5rem] overflow-hidden leading-[1.25rem]">
367
- <div
368
- className="animate-pulse rounded bg-ods-border"
369
- style={{ height: '1.25rem', marginBottom: '0.25rem' }}
370
- />
371
- <div className="w-3/4 animate-pulse rounded bg-ods-border" style={{ height: '1.25rem' }} />
372
- </div>
373
- <div className="mb-2 h-[2.5rem] overflow-hidden leading-[1.25rem]">
374
- <div
375
- className="animate-pulse rounded bg-ods-border"
376
- style={{ height: '1.25rem', marginBottom: '0.25rem' }}
377
- />
378
- <div className="w-5/6 animate-pulse rounded bg-ods-border" style={{ height: '1.25rem' }} />
379
- </div>
380
- <div className="flex items-center gap-2">
381
- <div className="animate-pulse rounded bg-ods-border" style={{ height: '0.75rem', width: '6rem' }} />
382
- <div className="animate-pulse rounded bg-ods-border" style={{ height: '0.75rem', width: '5rem' }} />
399
+ {/* Two rows of exactly one h4 line each (the bar centred inside), the
400
+ height of the loaded card's two-line title and description. */}
401
+ {[
402
+ ['w-full', 'w-3/4'],
403
+ ['w-full', 'w-5/6'],
404
+ ].map(widths => (
405
+ <div key={widths[1]} className="mb-2">
406
+ {widths.map(width => (
407
+ <div key={width} className="flex h-[var(--font-line-space-h4-body)] items-center">
408
+ <UnifiedSkeleton className={`h-4 ${width} rounded`} />
409
+ </div>
410
+ ))}
411
+ </div>
412
+ ))}
413
+ <div className="flex min-h-[var(--font-line-space-h4-body)] items-center gap-2">
414
+ <UnifiedSkeleton width="6rem" height="0.75rem" className="rounded" />
415
+ <UnifiedSkeleton width="5rem" height="0.75rem" className="rounded" />
383
416
  </div>
384
417
  </div>
385
418
  </div>
@@ -388,6 +421,48 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
388
421
  </div>
389
422
  );
390
423
 
424
+ if (isTile) {
425
+ const name = publicationName || domainToTitle(domain);
426
+ return (
427
+ <Link
428
+ href={url}
429
+ target="_blank"
430
+ rel="noopener noreferrer"
431
+ className="group flex min-w-0 flex-col gap-1.5 rounded-lg border border-ods-border bg-ods-card p-3 transition-colors hover:border-ods-accent"
432
+ >
433
+ <div className="flex min-w-0 items-center gap-1.5 text-xs">
434
+ <Favicon src={`https://www.google.com/s2/favicons?domain=${domain}&sz=32`} size="w-4 h-4" />
435
+ <TruncateText as="span" className="font-sans text-xs font-medium">
436
+ {name}
437
+ </TruncateText>
438
+ {meta != null && (
439
+ <span className="ml-auto flex flex-none items-center gap-1.5 text-ods-text-secondary">{meta}</span>
440
+ )}
441
+ </div>
442
+ {kicker != null && (
443
+ <div
444
+ className="overflow-hidden font-sans text-xs font-bold uppercase tracking-wide text-ods-accent"
445
+ style={lineClamp(1)}
446
+ >
447
+ {kicker}
448
+ </div>
449
+ )}
450
+ <TruncateText
451
+ lines={2}
452
+ className="font-sans text-[15px] font-semibold leading-snug transition-colors group-hover:text-ods-accent"
453
+ triggerClassName="-mt-0.5"
454
+ >
455
+ {curatedTitle || domainToTitle(domain)}
456
+ </TruncateText>
457
+ {curatedDescription && (
458
+ <TruncateText lines={2} tone="secondary" className="font-sans text-xs leading-normal">
459
+ {curatedDescription}
460
+ </TruncateText>
461
+ )}
462
+ </Link>
463
+ );
464
+ }
465
+
391
466
  if (!url || typeof url !== 'string' || !isValidUrl) return renderSkeleton();
392
467
 
393
468
  if (isLocalhost) {
@@ -406,7 +481,7 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
406
481
  );
407
482
  }
408
483
 
409
- if (loading) return renderSkeleton();
484
+ // A skeleton only when there is no props-built card to paint (see `effectiveData`).
410
485
  if (!effectiveData) return renderSkeleton();
411
486
 
412
487
  const title = curatedTitle || effectiveData.title;
@@ -520,21 +595,19 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
520
595
 
521
596
  if (!hasImage) {
522
597
  return (
523
- <div className="my-6">
598
+ <div className="my-6 flex flex-1 flex-col">
524
599
  <Link
525
600
  href={effectiveData.url}
526
601
  target="_blank"
527
602
  rel="noopener noreferrer"
528
- className="group flex items-center gap-3 overflow-hidden rounded-lg border border-ods-border bg-ods-card px-4 py-3 transition-all duration-200 hover:border-ods-accent"
603
+ className="group flex flex-1 items-center gap-3 overflow-hidden rounded-lg border border-ods-border bg-ods-card px-4 py-3 transition-all duration-200 hover:border-ods-accent"
529
604
  >
530
605
  <div className="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-ods-bg-surface">
531
606
  <Favicon src={faviconSrc} />
532
607
  </div>
533
608
  <div className="min-w-0 flex-1">
534
- <h3 className="truncate font-semibold text-ods-text-primary transition-colors text-h6 group-hover:text-ods-accent">
535
- {title}
536
- </h3>
537
- {description && <p className="truncate text-ods-text-secondary text-h6">{description}</p>}
609
+ <TruncateText className="font-semibold transition-colors group-hover:text-ods-accent">{title}</TruncateText>
610
+ {description && <TruncateText tone="secondary">{description}</TruncateText>}
538
611
  </div>
539
612
  <ExternalLinkIcon />
540
613
  </Link>
@@ -543,20 +616,22 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
543
616
  }
544
617
 
545
618
  return (
546
- <div className="my-6">
619
+ // `flex-1` lets the card stretch when the caller places it in a flex column
620
+ // inside a stretching grid (equal row heights); inert in block flow.
621
+ <div className="my-6 flex flex-1 flex-col">
547
622
  <Link
548
623
  href={effectiveData.url}
549
624
  target="_blank"
550
625
  rel="noopener noreferrer"
551
- className="group block overflow-hidden rounded-lg border border-ods-border bg-ods-card transition-colors hover:border-ods-accent"
626
+ className="group flex flex-1 flex-col overflow-hidden rounded-lg border border-ods-border bg-ods-card transition-colors hover:border-ods-accent"
552
627
  >
553
628
  <div
554
- className="relative flex aspect-video w-full items-center justify-center overflow-hidden rounded-lg transition-colors duration-300"
629
+ className="relative flex aspect-video w-full flex-none items-center justify-center overflow-hidden rounded-lg transition-colors duration-300"
555
630
  style={{ backgroundColor: bgColor }}
556
631
  >
557
632
  {renderImage()}
558
633
  </div>
559
- <div className="p-4">
634
+ <div className="flex-1 p-4">
560
635
  <div className="flex items-start gap-3">
561
636
  <Image
562
637
  src={logoSrc}
@@ -571,24 +646,32 @@ export const OGLinkPreview: React.FC<OGLinkPreviewProps> = ({
571
646
  }}
572
647
  />
573
648
  <div className="min-w-0 flex-1">
574
- <h3
575
- className="mb-2 h-[2.5rem] overflow-hidden font-semibold text-ods-text-primary transition-colors text-h6 group-hover:text-ods-accent"
576
- style={{ display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical' }}
649
+ {/* Title and description each RESERVE two h4 lines, so every card in a
650
+ grid is one height, and the clamp shows two whole lines. */}
651
+ <TruncateText
652
+ lines={2}
653
+ className="min-h-[calc(var(--font-line-space-h4-body)*2)] font-semibold transition-colors group-hover:text-ods-accent"
654
+ triggerClassName="mb-2"
577
655
  >
578
656
  {title}
579
- </h3>
580
- {description && (
581
- <p
582
- className="mb-2 h-[2.5rem] overflow-hidden text-ods-text-secondary text-h6"
583
- style={{ display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical' }}
584
- >
585
- {description}
586
- </p>
587
- )}
588
- <div className="flex items-center gap-2 text-ods-text-secondary text-h6">
589
- <span>{effectiveData.siteName}</span>
657
+ </TruncateText>
658
+ <TruncateText
659
+ lines={2}
660
+ tone="secondary"
661
+ className="min-h-[calc(var(--font-line-space-h4-body)*2)]"
662
+ triggerClassName="mb-2"
663
+ >
664
+ {description}
665
+ </TruncateText>
666
+ <div className="flex min-w-0 items-center gap-2 text-xs text-ods-text-secondary">
667
+ <TruncateText as="span" className="text-xs font-medium text-current">
668
+ {effectiveData.siteName}
669
+ </TruncateText>
590
670
  <span>•</span>
591
- <span className="truncate">{ogDomain}</span>
671
+ <TruncateText as="span" className="text-xs text-current">
672
+ {ogDomain}
673
+ </TruncateText>
674
+ {meta}
592
675
  </div>
593
676
  </div>
594
677
  </div>
@@ -6,6 +6,7 @@ import { formatLargeNumber } from '../../utils/format';
6
6
  import { renderedLinkRel } from '../../utils/markdown-link';
7
7
  import type { MediaItem as CarouselMediaItem } from '../../utils/media-carousel-utils-stub';
8
8
  import { socialCache } from '../../utils/social-embed-cache';
9
+ import { UnifiedSkeleton } from '../loading/unified-skeleton';
9
10
  import { MediaCarousel } from '../media-carousel';
10
11
  import { RedditContainer } from './embed-container';
11
12
  import { useRichMarkdownRuntime } from './rich-markdown-runtime';
@@ -226,22 +227,22 @@ export function RedditEmbedClient({ url, maxWidth = 700, rel }: RedditEmbedProps
226
227
  if (loading) {
227
228
  return (
228
229
  <RedditContainer>
229
- <div className="animate-pulse rounded-lg border border-ods-border bg-ods-card p-6">
230
+ <div className="rounded-lg border border-ods-border bg-ods-card p-6">
230
231
  <div className="mb-4 flex items-center space-x-3">
231
- <div className="h-12 w-12 rounded-full bg-ods-border"></div>
232
+ <UnifiedSkeleton className="h-12 w-12 rounded-full" />
232
233
  <div>
233
- <div className="mb-2 h-4 w-32 rounded bg-ods-border"></div>
234
- <div className="h-3 w-24 rounded bg-ods-border"></div>
234
+ <UnifiedSkeleton className="mb-2 h-4 w-32 rounded" />
235
+ <UnifiedSkeleton className="h-3 w-24 rounded" />
235
236
  </div>
236
237
  </div>
237
238
  <div className="mb-4 space-y-2">
238
- <div className="h-4 w-full rounded bg-ods-border"></div>
239
- <div className="h-4 w-3/4 rounded bg-ods-border"></div>
239
+ <UnifiedSkeleton className="h-4 w-full rounded" />
240
+ <UnifiedSkeleton className="h-4 w-3/4 rounded" />
240
241
  </div>
241
242
  <div className="flex items-center space-x-4">
242
- <div className="h-4 w-16 rounded bg-ods-border"></div>
243
- <div className="h-4 w-16 rounded bg-ods-border"></div>
244
- <div className="h-4 w-16 rounded bg-ods-border"></div>
243
+ <UnifiedSkeleton className="h-4 w-16 rounded" />
244
+ <UnifiedSkeleton className="h-4 w-16 rounded" />
245
+ <UnifiedSkeleton className="h-4 w-16 rounded" />
245
246
  </div>
246
247
  </div>
247
248
  </RedditContainer>
@@ -6,6 +6,7 @@ import Link from '../../embed-shims/next-link';
6
6
  import { renderedLinkRel } from '../../utils/markdown-link';
7
7
  import { socialCache } from '../../utils/social-embed-cache';
8
8
  import { XLogoIcon } from '../icons-v2-generated/brand-logos/x-logo-icon';
9
+ import { UnifiedSkeleton } from '../loading/unified-skeleton';
9
10
  import { TwitterContainer } from './embed-container';
10
11
  import { useRichMarkdownRuntime } from './rich-markdown-runtime';
11
12
 
@@ -145,22 +146,22 @@ export function TwitterEmbedClient({ url, tweetId, maxWidth = 700, rel }: Twitte
145
146
  if (loading) {
146
147
  return (
147
148
  <TwitterContainer>
148
- <div className="animate-pulse rounded-lg border border-ods-border bg-ods-card p-6">
149
+ <div className="rounded-lg border border-ods-border bg-ods-card p-6">
149
150
  <div className="mb-4 flex items-center space-x-3">
150
- <div className="h-12 w-12 rounded-full bg-ods-border"></div>
151
+ <UnifiedSkeleton className="h-12 w-12 rounded-full" />
151
152
  <div>
152
- <div className="mb-2 h-4 w-32 rounded bg-ods-border"></div>
153
- <div className="h-3 w-24 rounded bg-ods-border"></div>
153
+ <UnifiedSkeleton className="mb-2 h-4 w-32 rounded" />
154
+ <UnifiedSkeleton className="h-3 w-24 rounded" />
154
155
  </div>
155
156
  </div>
156
157
  <div className="mb-4 space-y-2">
157
- <div className="h-4 w-full rounded bg-ods-border"></div>
158
- <div className="h-4 w-3/4 rounded bg-ods-border"></div>
158
+ <UnifiedSkeleton className="h-4 w-full rounded" />
159
+ <UnifiedSkeleton className="h-4 w-3/4 rounded" />
159
160
  </div>
160
161
  <div className="flex items-center space-x-4">
161
- <div className="h-4 w-16 rounded bg-ods-border"></div>
162
- <div className="h-4 w-16 rounded bg-ods-border"></div>
163
- <div className="h-4 w-16 rounded bg-ods-border"></div>
162
+ <UnifiedSkeleton className="h-4 w-16 rounded" />
163
+ <UnifiedSkeleton className="h-4 w-16 rounded" />
164
+ <UnifiedSkeleton className="h-4 w-16 rounded" />
164
165
  </div>
165
166
  </div>
166
167
  </TwitterContainer>
@@ -14,6 +14,8 @@ import { navigateSamePageHash, STICKY_HEADER_OFFSET_PX } from '../../utils/same-
14
14
  import { buildSuggestionUrl } from '../../utils/suggestion-url';
15
15
  import { FaqAccordion, type FaqItem } from '../faq-accordion';
16
16
  import { SECTION_HEADING_CLASS } from '../layout/page-heading';
17
+ import { LoadingRegion } from '../loading/loading-region';
18
+ import { UnifiedSkeleton } from '../loading/unified-skeleton';
17
19
  import { FaqAskCard, faqAskCardShown, type FaqAskOptions } from './faq-ask-card';
18
20
  import { buildFaqJsonLdFromFaqs, type FaqSchemaOptions } from './json-ld';
19
21
 
@@ -412,19 +414,24 @@ function GroupedFaqList({
412
414
  );
413
415
  }
414
416
 
415
- function FaqSkeleton() {
417
+ function FaqSkeleton({
418
+ region = true,
419
+ }: {
420
+ /** The loading state announces itself (`LoadingRegion`). `false` inside another loading region. Default `true`. */
421
+ region?: boolean;
422
+ } = {}) {
416
423
  return (
417
- <div className="animate-pulse space-y-8">
418
- <div className="h-12 w-2/3 rounded bg-ods-border content-md:h-14" />
424
+ <LoadingRegion label="Loading questions" announce={region} className="space-y-8">
425
+ <UnifiedSkeleton className="h-12 w-2/3 rounded content-md:h-14" />
419
426
  <div className="w-full divide-y divide-ods-border overflow-hidden rounded-md border border-ods-border bg-transparent">
420
427
  {Array.from({ length: 8 }).map((_, idx) => (
421
428
  <div key={idx} className="flex items-center justify-between gap-6 px-6 py-4 content-md:gap-10">
422
- <div className="h-6 w-5/6 rounded bg-ods-border" />
423
- <div className="size-6 rounded bg-ods-border" />
429
+ <UnifiedSkeleton className="h-6 w-5/6 rounded" />
430
+ <UnifiedSkeleton className="size-6 rounded" />
424
431
  </div>
425
432
  ))}
426
433
  </div>
427
- </div>
434
+ </LoadingRegion>
428
435
  );
429
436
  }
430
437
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { type HTMLAttributes, forwardRef } from 'react';
4
4
  import { cn } from '../../../utils/cn';
5
- import { Skeleton } from '../../ui/skeleton';
5
+ import { UnifiedSkeleton } from '../../loading/unified-skeleton';
6
6
 
7
7
  export interface TicketCardSkeletonProps extends HTMLAttributes<HTMLDivElement> {}
8
8
 
@@ -19,21 +19,21 @@ export const TicketCardSkeleton = forwardRef<HTMLDivElement, TicketCardSkeletonP
19
19
  <div className="flex items-start gap-[var(--spacing-system-sf)]">
20
20
  <div className="flex min-w-0 flex-1 flex-col gap-[var(--spacing-system-xxs)]">
21
21
  <div className="flex items-center text-h3">
22
- <Skeleton className="h-4 w-3/4" />
22
+ <UnifiedSkeleton className="h-4 w-3/4" />
23
23
  </div>
24
24
  <div className="flex items-center gap-[var(--spacing-system-xxs)] text-h6">
25
- <Skeleton className="size-4 shrink-0 rounded-sm" />
26
- <Skeleton className="h-3 w-1/2" />
25
+ <UnifiedSkeleton className="size-4 shrink-0 rounded-sm" />
26
+ <UnifiedSkeleton className="h-3 w-1/2" />
27
27
  </div>
28
28
  </div>
29
29
  <div className="flex shrink-0 items-center gap-[var(--spacing-system-xsf)]">
30
- <Skeleton className="size-4 rounded-sm" />
31
- <Skeleton className="size-8 rounded-full" />
30
+ <UnifiedSkeleton className="size-4 rounded-sm" />
31
+ <UnifiedSkeleton className="size-8 rounded-full" />
32
32
  </div>
33
33
  </div>
34
34
  <div className="flex h-8 items-center gap-[var(--spacing-system-xxs)]">
35
- <Skeleton className="h-8 w-16 rounded-md" />
36
- <Skeleton className="h-8 w-12 rounded-md" />
35
+ <UnifiedSkeleton className="h-8 w-16 rounded-md" />
36
+ <UnifiedSkeleton className="h-8 w-12 rounded-md" />
37
37
  </div>
38
38
  </div>
39
39
  ),