@flamingo-stack/openframe-frontend-core 0.0.703 → 0.0.704-snapshot.20261006133653

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 (336) hide show
  1. package/dist/{chunk-3L7KCOGO.cjs → chunk-2QEUFXNS.cjs} +30 -30
  2. package/dist/{chunk-BMJUKS6S.cjs → chunk-3256UJXS.cjs} +47 -47
  3. package/dist/{chunk-GZYLZ4MB.js → chunk-4S7TJYRQ.js} +3 -3
  4. package/dist/{chunk-ENGBNKUJ.js → chunk-5EFZO5EB.js} +675 -569
  5. package/dist/{chunk-TCZCMD5Q.js → chunk-5HBHO5TB.js} +1 -1
  6. package/dist/{chunk-BOUPNYUV.js → chunk-64HOMVYC.js} +5 -5
  7. package/dist/{chunk-YR6JPJF4.js → chunk-6XIF2Z7I.js} +4 -4
  8. package/dist/{chunk-NU724ZVN.cjs → chunk-7GHB2IK6.cjs} +121 -121
  9. package/dist/{chunk-GX3OUTFO.cjs → chunk-7ZYIC7NA.cjs} +69 -55
  10. package/dist/{chunk-53AC23ZN.js → chunk-A6WVQKOZ.js} +24 -24
  11. package/dist/{chunk-4OGAXAEG.cjs → chunk-ABU3TGXA.cjs} +3 -3
  12. package/dist/{chunk-RTXTGLGB.cjs → chunk-ACV4DFQ3.cjs} +4 -4
  13. package/dist/{chunk-RLDAYA2A.cjs → chunk-BH6PJP66.cjs} +29 -29
  14. package/dist/{chunk-BRXOGCH3.cjs → chunk-BIZNSF3U.cjs} +3 -3
  15. package/dist/{chunk-2A4XES7R.cjs → chunk-BM5MVGH3.cjs} +3 -3
  16. package/dist/{chunk-6YCXA7CN.js → chunk-CH5232HV.js} +20 -19
  17. package/dist/{chunk-UIBSSVON.cjs → chunk-D7BTSVMS.cjs} +2 -2
  18. package/dist/{chunk-YBGEPKC2.cjs → chunk-F7Y2ZS5U.cjs} +6 -6
  19. package/dist/{chunk-5V6O73EH.js → chunk-FLKJYMVB.js} +3 -3
  20. package/dist/{chunk-NMGX2ZTU.js → chunk-IFUQVZF4.js} +17 -17
  21. package/dist/{chunk-2NE3DNXY.js → chunk-IKCQK67U.js} +2 -2
  22. package/dist/{chunk-KFDP3DUL.cjs → chunk-IXPUM3AW.cjs} +98 -98
  23. package/dist/{chunk-QGTDWFT6.js → chunk-IZHZMBIX.js} +2469 -1928
  24. package/dist/{chunk-67CXGPTW.cjs → chunk-JKEEFQOX.cjs} +505 -72
  25. package/dist/{chunk-NYSYSKSH.cjs → chunk-M6HTJTFH.cjs} +15 -15
  26. package/dist/{chunk-OGLCD3UL.js → chunk-MFFCUVWG.js} +6 -6
  27. package/dist/{chunk-KJ5LWATV.js → chunk-MKXO4Q5P.js} +7 -7
  28. package/dist/{chunk-EMCQGFXD.cjs → chunk-MMOODW57.cjs} +28 -27
  29. package/dist/{chunk-Q76ZTHNV.js → chunk-MP2C3LJ4.js} +1 -1
  30. package/dist/{chunk-J4K5JOLI.js → chunk-MV4HYG3B.js} +25 -11
  31. package/dist/{chunk-2T6QWNXU.js → chunk-NDESEPW5.js} +99 -11
  32. package/dist/{chunk-HHFPQNP3.js → chunk-NJDHFC55.js} +15 -15
  33. package/dist/{chunk-HUOLB7ZN.cjs → chunk-OHFS7VOU.cjs} +9 -9
  34. package/dist/{chunk-7632TNE7.js → chunk-OSNIZNVH.js} +7 -7
  35. package/dist/{chunk-UTW4SQDI.js → chunk-OUHMD6EU.js} +10 -10
  36. package/dist/{chunk-MXHJROXJ.cjs → chunk-P23CRLU4.cjs} +1245 -1139
  37. package/dist/{chunk-64O4L7WN.js → chunk-PDWVPI3S.js} +11 -55
  38. package/dist/{chunk-DAW6TDZB.js → chunk-PFC2HWQA.js} +30 -16
  39. package/dist/{chunk-G55W76S6.js → chunk-POZ7F77D.js} +12 -13
  40. package/dist/{chunk-PJP5SMOU.js → chunk-PPEZGUL7.js} +500 -67
  41. package/dist/{chunk-SFGXIFYO.cjs → chunk-QC7Q3XCE.cjs} +24 -24
  42. package/dist/{chunk-MDBHZBW7.cjs → chunk-RKV5B7EU.cjs} +92 -4
  43. package/dist/{chunk-5VPIC5MD.cjs → chunk-SAAZEWUR.cjs} +12 -12
  44. package/dist/{chunk-IIMICN7L.cjs → chunk-TYWLNCNH.cjs} +4 -48
  45. package/dist/{chunk-HYLIQMZH.cjs → chunk-UBP5RNGK.cjs} +33 -33
  46. package/dist/{chunk-HUMWQMCU.js → chunk-UT4YHQZW.js} +3 -3
  47. package/dist/{chunk-BSEIEWM5.cjs → chunk-V3H26CNS.cjs} +28 -14
  48. package/dist/{chunk-NGJCWEYX.cjs → chunk-VHCACDKP.cjs} +46 -46
  49. package/dist/{chunk-SL2FOFT2.js → chunk-VMAZCLX4.js} +7 -7
  50. package/dist/{chunk-5FFNNJM7.js → chunk-VR2ZLFCP.js} +1 -1
  51. package/dist/{chunk-NCTYD7HL.js → chunk-VYWMEL5F.js} +14 -14
  52. package/dist/{chunk-HY5YL3U5.cjs → chunk-XBWE423R.cjs} +1994 -1453
  53. package/dist/{chunk-XCIFHW4E.cjs → chunk-XOYH2YQE.cjs} +2 -2
  54. package/dist/{chunk-S6V7A5FS.cjs → chunk-ZQZFIE2K.cjs} +32 -33
  55. package/dist/components/case-studies/index.cjs +24 -24
  56. package/dist/components/case-studies/index.js +10 -10
  57. package/dist/components/chat/chat-archive-page.d.ts +3 -3
  58. package/dist/components/chat/chat-archive-page.d.ts.map +1 -1
  59. package/dist/components/chat/chat-input.d.ts.map +1 -1
  60. package/dist/components/chat/chat-nav-sidebar.d.ts +4 -0
  61. package/dist/components/chat/chat-nav-sidebar.d.ts.map +1 -1
  62. package/dist/components/chat/chat-panel-header.d.ts +3 -2
  63. package/dist/components/chat/chat-panel-header.d.ts.map +1 -1
  64. package/dist/components/chat/embeddable-chat.d.ts +36 -2
  65. package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
  66. package/dist/components/chat/index.cjs +14 -6
  67. package/dist/components/chat/index.d.ts +4 -1
  68. package/dist/components/chat/index.d.ts.map +1 -1
  69. package/dist/components/chat/index.js +13 -5
  70. package/dist/components/chat/mingo-archive-list.d.ts +17 -0
  71. package/dist/components/chat/mingo-archive-list.d.ts.map +1 -0
  72. package/dist/components/chat/mingo-chat-header.d.ts +31 -0
  73. package/dist/components/chat/mingo-chat-header.d.ts.map +1 -0
  74. package/dist/components/chat/mingo-chat-rail.d.ts +54 -0
  75. package/dist/components/chat/mingo-chat-rail.d.ts.map +1 -0
  76. package/dist/components/chat/model-display.d.ts.map +1 -1
  77. package/dist/components/contact/contact-form.d.ts.map +1 -1
  78. package/dist/components/contact/index.cjs +11 -11
  79. package/dist/components/contact/index.js +10 -10
  80. package/dist/components/content-loading-container.d.ts +1 -1
  81. package/dist/components/content-loading-container.d.ts.map +1 -1
  82. package/dist/components/docs/index.cjs +14 -14
  83. package/dist/components/docs/index.js +13 -13
  84. package/dist/components/docs/skeletons.d.ts.map +1 -1
  85. package/dist/components/embeds/index.cjs +11 -11
  86. package/dist/components/embeds/index.js +10 -10
  87. package/dist/components/faq/index.cjs +12 -12
  88. package/dist/components/faq/index.js +11 -11
  89. package/dist/components/features/figma-prototype-viewer.d.ts.map +1 -1
  90. package/dist/components/features/index.cjs +10 -10
  91. package/dist/components/features/index.js +9 -9
  92. package/dist/components/features/media-gallery-manager.d.ts.map +1 -1
  93. package/dist/components/features/parallax-image-showcase.d.ts.map +1 -1
  94. package/dist/components/features/policy-configuration-panel.d.ts.map +1 -1
  95. package/dist/components/features/section-selector.d.ts.map +1 -1
  96. package/dist/components/help-center-pages/index.cjs +119 -119
  97. package/dist/components/help-center-pages/index.js +39 -39
  98. package/dist/components/help-center-pages/trust-center-sections.d.ts +2 -2
  99. package/dist/components/help-center-pages/trust-center-sections.d.ts.map +1 -1
  100. package/dist/components/index.cjs +94 -86
  101. package/dist/components/index.js +32 -24
  102. package/dist/components/layout/article-detail-layout.d.ts +1 -1
  103. package/dist/components/layout/article-detail-layout.d.ts.map +1 -1
  104. package/dist/components/layout/page-container.d.ts.map +1 -1
  105. package/dist/components/layout/title-block.d.ts +2 -2
  106. package/dist/components/layout/title-block.d.ts.map +1 -1
  107. package/dist/components/loading/page-layout-skeleton.d.ts.map +1 -1
  108. package/dist/components/loading/unified-skeleton.d.ts.map +1 -1
  109. package/dist/components/meeting-scheduler/booking-form.d.ts +4 -4
  110. package/dist/components/meeting-scheduler/booking-form.d.ts.map +1 -1
  111. package/dist/components/meeting-scheduler/context-panel.d.ts.map +1 -1
  112. package/dist/components/meeting-scheduler/index.cjs +127 -127
  113. package/dist/components/meeting-scheduler/index.d.ts +2 -2
  114. package/dist/components/meeting-scheduler/index.d.ts.map +1 -1
  115. package/dist/components/meeting-scheduler/index.js +50 -50
  116. package/dist/components/navigation/app-header.d.ts +4 -0
  117. package/dist/components/navigation/app-header.d.ts.map +1 -1
  118. package/dist/components/navigation/app-layout-side-panel.d.ts +142 -0
  119. package/dist/components/navigation/app-layout-side-panel.d.ts.map +1 -0
  120. package/dist/components/navigation/app-layout.d.ts +11 -1
  121. package/dist/components/navigation/app-layout.d.ts.map +1 -1
  122. package/dist/components/navigation/header-mingo-button.d.ts +4 -1
  123. package/dist/components/navigation/header-mingo-button.d.ts.map +1 -1
  124. package/dist/components/navigation/index.cjs +13 -13
  125. package/dist/components/navigation/index.d.ts +1 -0
  126. package/dist/components/navigation/index.d.ts.map +1 -1
  127. package/dist/components/navigation/index.js +12 -12
  128. package/dist/components/navigation/navigation-sidebar.d.ts +8 -1
  129. package/dist/components/navigation/navigation-sidebar.d.ts.map +1 -1
  130. package/dist/components/navigation/sliding-sidebar.d.ts.map +1 -1
  131. package/dist/components/onboarding-guides/index.cjs +14 -14
  132. package/dist/components/onboarding-guides/index.js +13 -13
  133. package/dist/components/persistent-filter-controls.d.ts.map +1 -1
  134. package/dist/components/related-content/index.cjs +7 -7
  135. package/dist/components/related-content/index.js +6 -6
  136. package/dist/components/shared/detail-page-skeleton.d.ts.map +1 -1
  137. package/dist/components/tickets/help-center-create-form.d.ts +4 -4
  138. package/dist/components/tickets/index.cjs +15 -15
  139. package/dist/components/tickets/index.js +14 -14
  140. package/dist/components/ui/announcement-bar-view.d.ts.map +1 -1
  141. package/dist/components/ui/breadcrumb.d.ts.map +1 -1
  142. package/dist/components/ui/checkbox-block.d.ts.map +1 -1
  143. package/dist/components/ui/dashboard-info-card.d.ts +1 -1
  144. package/dist/components/ui/dashboard-info-card.d.ts.map +1 -1
  145. package/dist/components/ui/data-table/data-table-body.d.ts +2 -2
  146. package/dist/components/ui/data-table/data-table-skeleton.d.ts +2 -2
  147. package/dist/components/ui/data-table/data-table-skeleton.d.ts.map +1 -1
  148. package/dist/components/ui/data-table/utils.d.ts +2 -2
  149. package/dist/components/ui/dialog.d.ts.map +1 -1
  150. package/dist/components/ui/drawer.d.ts.map +1 -1
  151. package/dist/components/ui/entity-image.d.ts +2 -2
  152. package/dist/components/ui/file-manager/index.cjs +36 -36
  153. package/dist/components/ui/file-manager/index.js +3 -3
  154. package/dist/components/ui/filter-modal.d.ts.map +1 -1
  155. package/dist/components/ui/index.cjs +18 -10
  156. package/dist/components/ui/index.js +17 -9
  157. package/dist/components/ui/info-card-row.d.ts.map +1 -1
  158. package/dist/components/ui/menubar.d.ts +1 -1
  159. package/dist/components/ui/menubar.d.ts.map +1 -1
  160. package/dist/components/ui/modal-v2.d.ts.map +1 -1
  161. package/dist/components/ui/modal.d.ts.map +1 -1
  162. package/dist/components/ui/no-data/no-data-actions.d.ts.map +1 -1
  163. package/dist/components/ui/no-data/no-data-styles.d.ts +1 -1
  164. package/dist/components/ui/no-data/no-data-styles.d.ts.map +1 -1
  165. package/dist/components/ui/page-actions.d.ts.map +1 -1
  166. package/dist/components/ui/sheet.d.ts.map +1 -1
  167. package/dist/components/ui/table/table-skeleton.d.ts +1 -1
  168. package/dist/components/ui/table/table-skeleton.d.ts.map +1 -1
  169. package/dist/hooks/index.cjs +23 -9
  170. package/dist/hooks/index.js +24 -10
  171. package/dist/hooks/ui/index.d.ts +1 -0
  172. package/dist/hooks/ui/index.d.ts.map +1 -1
  173. package/dist/hooks/ui/use-content-breakpoint.d.ts +32 -0
  174. package/dist/hooks/ui/use-content-breakpoint.d.ts.map +1 -0
  175. package/dist/hooks/ui/use-isomorphic-layout-effect.d.ts +2 -2
  176. package/dist/hooks/ui/use-isomorphic-layout-effect.d.ts.map +1 -1
  177. package/dist/hooks/ui/use-media-query.d.ts.map +1 -1
  178. package/dist/index.cjs +39 -17
  179. package/dist/index.js +41 -19
  180. package/dist/styles/layout-steps.d.ts +30 -0
  181. package/dist/styles/layout-steps.d.ts.map +1 -0
  182. package/dist/tailwind.config.cjs +36 -11
  183. package/dist/tailwind.config.js +36 -11
  184. package/eslint-config/README.md +9 -0
  185. package/eslint-config/base.js +17 -1
  186. package/eslint-config/layout-variants.js +57 -0
  187. package/package.json +3 -1
  188. package/src/ODS_TOKEN_RULES.md +40 -0
  189. package/src/components/chat/chat-archive-page.tsx +9 -7
  190. package/src/components/chat/chat-input.tsx +5 -1
  191. package/src/components/chat/chat-nav-sidebar.tsx +10 -4
  192. package/src/components/chat/chat-panel-header.tsx +8 -5
  193. package/src/components/chat/embeddable-chat.tsx +675 -485
  194. package/src/components/chat/index.ts +4 -0
  195. package/src/components/chat/mingo-archive-list.tsx +108 -0
  196. package/src/components/chat/mingo-chat-header.tsx +104 -0
  197. package/src/components/chat/mingo-chat-rail.tsx +361 -0
  198. package/src/components/chat/model-display.tsx +8 -1
  199. package/src/components/contact/contact-form.tsx +11 -9
  200. package/src/components/content-loading-container.tsx +4 -2
  201. package/src/components/docs/doc-viewer.tsx +7 -7
  202. package/src/components/docs/skeletons.tsx +7 -4
  203. package/src/components/dynamic-skeleton.tsx +1 -1
  204. package/src/components/embeds/claude-embed.tsx +1 -1
  205. package/src/components/embeds/embed-viewer-frame.tsx +4 -4
  206. package/src/components/embeds/figma-embed.tsx +2 -2
  207. package/src/components/embeds/google-sheets-viewer.tsx +1 -1
  208. package/src/components/embeds/pdf-viewer.tsx +3 -3
  209. package/src/components/empty-state.tsx +6 -6
  210. package/src/components/faq/faq-section.tsx +2 -2
  211. package/src/components/faq-accordion.tsx +1 -1
  212. package/src/components/features/board/board-column-header.tsx +1 -1
  213. package/src/components/features/command-box.tsx +3 -3
  214. package/src/components/features/entity-video-section.tsx +2 -2
  215. package/src/components/features/figma-prototype-viewer.tsx +4 -1
  216. package/src/components/features/media-gallery-manager.tsx +3 -1
  217. package/src/components/features/parallax-image-showcase.tsx +9 -6
  218. package/src/components/features/policy-configuration-panel.tsx +9 -7
  219. package/src/components/features/provider-button.tsx +1 -1
  220. package/src/components/features/section-selector.tsx +11 -6
  221. package/src/components/features/select-button.tsx +4 -4
  222. package/src/components/features/seo-editor-preview.tsx +2 -2
  223. package/src/components/features/video-ratio-tabs.tsx +3 -3
  224. package/src/components/features/waitlist-form.tsx +1 -1
  225. package/src/components/help-center-pages/trust-center-page.tsx +1 -1
  226. package/src/components/help-center-pages/trust-center-sections.tsx +14 -14
  227. package/src/components/icon-display.tsx +1 -1
  228. package/src/components/layout/article-detail-layout.tsx +4 -2
  229. package/src/components/layout/list-page-layout.tsx +2 -2
  230. package/src/components/layout/page-container.tsx +26 -14
  231. package/src/components/layout/page-heading.tsx +1 -1
  232. package/src/components/layout/page-layout.tsx +1 -1
  233. package/src/components/layout/title-block.tsx +13 -13
  234. package/src/components/loading/card-skeleton.tsx +11 -11
  235. package/src/components/loading/category-vendor-selector-skeleton.tsx +1 -1
  236. package/src/components/loading/content-skeleton.tsx +6 -6
  237. package/src/components/loading/device-card-skeleton.tsx +1 -1
  238. package/src/components/loading/margin-report-skeleton.tsx +7 -7
  239. package/src/components/loading/msp-profile-form-skeleton.tsx +3 -3
  240. package/src/components/loading/organization-card-skeleton.tsx +2 -2
  241. package/src/components/loading/page-layout-skeleton.tsx +80 -68
  242. package/src/components/loading/unified-skeleton.tsx +16 -6
  243. package/src/components/media-carousel.tsx +3 -3
  244. package/src/components/meeting-scheduler/booking-form.tsx +9 -8
  245. package/src/components/meeting-scheduler/context-panel.tsx +8 -6
  246. package/src/components/meeting-scheduler/directory.tsx +4 -4
  247. package/src/components/meeting-scheduler/index.tsx +15 -15
  248. package/src/components/meeting-scheduler/slot-picker.tsx +12 -12
  249. package/src/components/navigation/app-header.tsx +6 -0
  250. package/src/components/navigation/app-layout-side-panel.tsx +594 -0
  251. package/src/components/navigation/app-layout.tsx +69 -4
  252. package/src/components/navigation/header-mingo-button.tsx +13 -3
  253. package/src/components/navigation/index.ts +5 -0
  254. package/src/components/navigation/navigation-sidebar.tsx +17 -3
  255. package/src/components/navigation/sliding-sidebar.tsx +2 -1
  256. package/src/components/pagination.tsx +3 -3
  257. package/src/components/persistent-filter-controls.tsx +6 -2
  258. package/src/components/platform/ScriptArguments.tsx +1 -1
  259. package/src/components/platform/ScriptInfoSection.tsx +4 -4
  260. package/src/components/platform/SoftwareSourceBadge.tsx +1 -1
  261. package/src/components/shared/article-author-byline.tsx +1 -1
  262. package/src/components/shared/delivery/delivery-lists.tsx +2 -2
  263. package/src/components/shared/delivery/delivery-row.tsx +7 -7
  264. package/src/components/shared/delivery/delivery-table.tsx +3 -3
  265. package/src/components/shared/detail-page-skeleton.tsx +11 -5
  266. package/src/components/shared/dev-section/dev-card-row.tsx +6 -6
  267. package/src/components/shared/dev-section/dev-section-view.tsx +1 -1
  268. package/src/components/shared/product-release/product-release-card-skeleton.tsx +8 -8
  269. package/src/components/shared/product-release/product-release-card.tsx +9 -9
  270. package/src/components/shared/product-release/product-releases-view.tsx +1 -1
  271. package/src/components/shared/product-release/release-detail-page.tsx +5 -5
  272. package/src/components/shared/roadmap/roadmap-grid-skeleton.tsx +1 -1
  273. package/src/components/shared/roadmap/roadmap-grid.tsx +3 -3
  274. package/src/components/tickets/help-center-card.tsx +1 -1
  275. package/src/components/tickets/help-center-create-form.tsx +12 -12
  276. package/src/components/ui/announcement-bar-view.tsx +2 -10
  277. package/src/components/ui/benefit-card.tsx +18 -18
  278. package/src/components/ui/brand-association-grid.tsx +4 -4
  279. package/src/components/ui/breadcrumb.tsx +4 -1
  280. package/src/components/ui/card.tsx +1 -1
  281. package/src/components/ui/checkbox-block.tsx +9 -7
  282. package/src/components/ui/content-loader.tsx +3 -3
  283. package/src/components/ui/cursor-pagination.tsx +3 -3
  284. package/src/components/ui/dashboard-info-card.tsx +13 -9
  285. package/src/components/ui/data-attribution.tsx +2 -2
  286. package/src/components/ui/data-table/data-table-body.tsx +2 -2
  287. package/src/components/ui/data-table/data-table-header.tsx +15 -15
  288. package/src/components/ui/data-table/data-table-skeleton.tsx +6 -6
  289. package/src/components/ui/data-table/utils.ts +5 -5
  290. package/src/components/ui/dialog.tsx +4 -1
  291. package/src/components/ui/drawer.tsx +2 -1
  292. package/src/components/ui/duration-input.tsx +1 -1
  293. package/src/components/ui/entity-image.tsx +3 -3
  294. package/src/components/ui/feature-card.tsx +10 -10
  295. package/src/components/ui/file-manager/file-manager-action-bar.tsx +1 -1
  296. package/src/components/ui/file-manager/file-manager.tsx +1 -1
  297. package/src/components/ui/filter-modal.tsx +8 -1
  298. package/src/components/ui/highlight-card.tsx +7 -7
  299. package/src/components/ui/info-card-row.tsx +10 -6
  300. package/src/components/ui/modal-v2.tsx +7 -2
  301. package/src/components/ui/modal.tsx +3 -2
  302. package/src/components/ui/no-data/no-data-actions.tsx +10 -4
  303. package/src/components/ui/no-data/no-data-styles.ts +1 -1
  304. package/src/components/ui/no-data/no-data.tsx +1 -1
  305. package/src/components/ui/organization-card.tsx +1 -1
  306. package/src/components/ui/page-actions.tsx +34 -5
  307. package/src/components/ui/progress-bar.tsx +2 -2
  308. package/src/components/ui/query-report-table/query-report-table.tsx +1 -1
  309. package/src/components/ui/search-input.tsx +2 -2
  310. package/src/components/ui/service-card.tsx +2 -2
  311. package/src/components/ui/sheet.tsx +2 -1
  312. package/src/components/ui/skeleton.tsx +3 -3
  313. package/src/components/ui/stacked-rows-panel.tsx +4 -4
  314. package/src/components/ui/tab-navigation.tsx +2 -2
  315. package/src/components/ui/tab-selector.tsx +2 -2
  316. package/src/components/ui/table/table-header.tsx +3 -3
  317. package/src/components/ui/table/table-skeleton.tsx +3 -3
  318. package/src/components/ui/table/utils.ts +5 -5
  319. package/src/components/ui/tag-search-input.tsx +3 -3
  320. package/src/components/ui/tags-manager.tsx +5 -5
  321. package/src/components/ui/test-run.tsx +2 -2
  322. package/src/components/ui/ticket-info-section.tsx +1 -1
  323. package/src/components/ui/ticket-notes-section.tsx +1 -1
  324. package/src/components/ui/ticket-status-config-row.tsx +15 -15
  325. package/src/hooks/ui/index.ts +1 -0
  326. package/src/hooks/ui/use-content-breakpoint.ts +58 -0
  327. package/src/hooks/ui/use-media-query.ts +3 -2
  328. package/src/styles/app-globals.css +13 -0
  329. package/src/styles/index.css +2 -0
  330. package/src/styles/layout-steps.ts +14 -0
  331. package/src/styles/ods-colors.css +15 -0
  332. package/src/styles/ods-content-area-tokens.css +27 -0
  333. package/src/styles/ods-content-area.css +31 -0
  334. package/src/styles/ods-effects.css +4 -2
  335. package/src/styles/ods-responsive-tokens.css +14 -4
  336. package/tailwind.config.ts +42 -7
@@ -72,9 +72,9 @@ const BODY_TEXT = 'text-h6 text-ods-text-secondary';
72
72
  * beside the section rail.
73
73
  */
74
74
  export const TRUST_STATUS_ROW_CLASS =
75
- 'flex flex-col gap-[var(--spacing-system-xs)] md:flex-row md:items-center md:justify-between';
75
+ 'flex flex-col gap-[var(--spacing-system-xs)] content-md:flex-row content-md:items-center content-md:justify-between';
76
76
  export const TRUST_BODY_GRID_CLASS =
77
- 'grid grid-cols-1 gap-[var(--spacing-system-xl)] lg:grid-cols-[minmax(0,1fr)_12rem]';
77
+ 'grid grid-cols-1 gap-[var(--spacing-system-xl)] content-lg:grid-cols-[minmax(0,1fr)_12rem]';
78
78
  export const TRUST_SECTIONS_COLUMN_CLASS = 'flex min-w-0 flex-col gap-[var(--spacing-system-xxl)]';
79
79
 
80
80
  /** Each section's one-line lead under its heading (the page and its skeleton read the same copy). */
@@ -89,7 +89,7 @@ export const TRUST_SECTION_LEADS: Partial<Record<TrustCenterSectionId, string>>
89
89
  * The right-hand action / status column: ONE width from tablet up, so every
90
90
  * panel's rows line up; on phones it hugs its content so the title keeps the room.
91
91
  */
92
- const ACTION_COLUMN = 'shrink-0 md:w-36';
92
+ const ACTION_COLUMN = 'shrink-0 content-md:w-36';
93
93
 
94
94
  // ---------------------------------------------------------------------------
95
95
  // Section frame
@@ -202,7 +202,7 @@ export function ComplianceSection({ frameworks }: { frameworks: TrustCenterFrame
202
202
  * so the list box shows exactly 5 of them and scrolls for
203
203
  * the rest.
204
204
  */
205
- const CONTROL_ROW_CLASS = 'h-14 md:h-20 overflow-hidden';
205
+ const CONTROL_ROW_CLASS = 'h-14 content-md:h-20 overflow-hidden';
206
206
 
207
207
  /** ONE row renderer for the controls list: fixed-height rows, one line each for name and description. */
208
208
  function controlRows(controls: TrustCenterControl[]): PanelRow[] {
@@ -229,7 +229,7 @@ function countLabel(n: number, noun: string): string {
229
229
  * md) plus their 1px separators and the panel's border. Controls, loading,
230
230
  * empty and error all fill this same box, so nothing below it moves.
231
231
  */
232
- const CONTROLS_LIST_HEIGHT = 'h-[calc(5*3.5rem+7px)] md:h-[calc(5*5rem+7px)]';
232
+ const CONTROLS_LIST_HEIGHT = 'h-[calc(5*3.5rem+7px)] content-md:h-[calc(5*5rem+7px)]';
233
233
 
234
234
  /** Skeleton rows shown in the list box while the server's answer is on its way: exactly the box's visible rows. */
235
235
  const CONTROLS_SKELETON_ROWS = 5;
@@ -332,11 +332,11 @@ export function ControlsSection({ endpoint, seed }: { endpoint: string; seed: Tr
332
332
  setDomain(categories.find(category => controlsTabId(category.domain) === tabId)?.domain ?? null)
333
333
  }
334
334
  />
335
- <div className="flex flex-col gap-[var(--spacing-system-s)] md:flex-row md:items-center md:justify-between">
335
+ <div className="flex flex-col gap-[var(--spacing-system-s)] content-md:flex-row content-md:items-center content-md:justify-between">
336
336
  <p className={BODY_TEXT} aria-live="polite">
337
337
  {summary}
338
338
  </p>
339
- <div className="w-full md:w-80">
339
+ <div className="w-full content-md:w-80">
340
340
  <SearchInput
341
341
  placeholder="Search controls"
342
342
  value={typed}
@@ -598,7 +598,7 @@ function skeletonRows(count: number, shape: { mark: 'logo' | 'glyph'; action: 'b
598
598
  className={shape.mark === 'logo' ? 'size-10 shrink-0 rounded-full' : 'size-6 shrink-0 rounded'}
599
599
  />
600
600
  <div className="flex min-w-0 flex-1 flex-col gap-[var(--spacing-system-xxs)]">
601
- <UnifiedSkeleton variant="text" className="h-5 w-1/3 md:h-6" />
601
+ <UnifiedSkeleton variant="text" className="h-5 w-1/3 content-md:h-6" />
602
602
  <TextSkeleton.Body className="w-1/2" />
603
603
  </div>
604
604
  </div>
@@ -612,7 +612,7 @@ function skeletonRows(count: number, shape: { mark: 'logo' | 'glyph'; action: 'b
612
612
  shape.action === 'badge' ? (
613
613
  <UnifiedSkeleton className="h-4 w-28 rounded" />
614
614
  ) : (
615
- <UnifiedSkeleton className="h-6 w-16 rounded md:h-8" />
615
+ <UnifiedSkeleton className="h-6 w-16 rounded content-md:h-8" />
616
616
  ),
617
617
  },
618
618
  ],
@@ -626,13 +626,13 @@ function ControlsSectionSkeleton() {
626
626
  <div className="flex items-center gap-[var(--spacing-system-xxs)] overflow-hidden">
627
627
  {[0, 1, 2, 3].map(index => (
628
628
  <div key={index} className="shrink-0 p-[var(--spacing-system-m)]">
629
- <UnifiedSkeleton variant="text" className="h-5 w-36 md:h-6" />
629
+ <UnifiedSkeleton variant="text" className="h-5 w-36 content-md:h-6" />
630
630
  </div>
631
631
  ))}
632
632
  </div>
633
- <div className="flex flex-col gap-[var(--spacing-system-s)] md:flex-row md:items-center md:justify-between">
633
+ <div className="flex flex-col gap-[var(--spacing-system-s)] content-md:flex-row content-md:items-center content-md:justify-between">
634
634
  <TextSkeleton.Body className="w-48" />
635
- <UnifiedSkeleton className="h-11 w-full rounded-[6px] md:h-12 md:w-80" />
635
+ <UnifiedSkeleton className="h-11 w-full rounded-[6px] content-md:h-12 content-md:w-80" />
636
636
  </div>
637
637
  <div className={CONTROLS_LIST_HEIGHT}>
638
638
  <ControlsListSkeleton />
@@ -675,7 +675,7 @@ export function TrustCenterSkeleton() {
675
675
  <TextSkeleton.Body className="w-44" />
676
676
  </div>
677
677
  {/* `DataAttribution`'s own layout: two lines below `sm`, one row above it. */}
678
- <div className="flex shrink-0 flex-col gap-[var(--spacing-system-xxs)] sm:flex-row sm:items-center sm:gap-[var(--spacing-system-sf)]">
678
+ <div className="flex shrink-0 flex-col gap-[var(--spacing-system-xxs)] content-sm:flex-row content-sm:items-center content-sm:gap-[var(--spacing-system-sf)]">
679
679
  <div className="flex items-center gap-[var(--spacing-system-xsf)]">
680
680
  <UnifiedSkeleton className="size-4 rounded" />
681
681
  <TextSkeleton.Body className="w-36" />
@@ -695,7 +695,7 @@ export function TrustCenterSkeleton() {
695
695
  <StackedRowsPanel rows={skeletonRows(2, { mark: 'glyph', action: 'button' })} />
696
696
  </SkeletonSection>
697
697
  </div>
698
- <aside className="hidden lg:block" aria-hidden="true">
698
+ <aside className="hidden content-lg:block" aria-hidden="true">
699
699
  <SectionRailSkeleton />
700
700
  </aside>
701
701
  </div>
@@ -52,7 +52,7 @@ export function EntityIcon({
52
52
  }
53
53
  if (icon?.name && BRAND_MARK_NAMES.has(icon.name)) {
54
54
  // Size via `className` when provided (so responsive Tailwind sizing like
55
- // `w-6 md:w-8` works); fall back to a fixed `size` px box ONLY when no
55
+ // `w-6 content-md:w-8` works); fall back to a fixed `size` px box ONLY when no
56
56
  // className is given — an inline `style` would otherwise override the class.
57
57
  return (
58
58
  <span
@@ -52,7 +52,7 @@ export function PageShell({ children, schemas, contentClassName }: LayoutProps)
52
52
  /**
53
53
  * Constrained layout for article/detail pages (max-w-[1280px]) — readable
54
54
  * content width for blog posts, release notes, case studies, investor updates.
55
- * Fixed hub padding (`px-6 md:px-20 py-6 md:py-10`); pass `contentClassName` to
55
+ * Fixed hub padding (`px-6 content-md:px-20 py-6 content-md:py-10`); pass `contentClassName` to
56
56
  * override per instance. (PageShell's `--page-shell-*` var system does NOT apply
57
57
  * here — this layout keeps its own fixed spacing.)
58
58
  */
@@ -60,7 +60,9 @@ export function ArticleDetailLayout({ children, schemas, contentClassName }: Lay
60
60
  return (
61
61
  <main className="bg-ods-bg">
62
62
  {schemas}
63
- <div className={cn('mx-auto max-w-[1280px] px-6 py-6 md:px-20 md:py-10', contentClassName)}>{children}</div>
63
+ <div className={cn('mx-auto max-w-[1280px] px-6 py-6 content-md:px-20 content-md:py-10', contentClassName)}>
64
+ {children}
65
+ </div>
64
66
  </main>
65
67
  );
66
68
  }
@@ -165,7 +165,7 @@ export function ListPageLayout({
165
165
  onChange={e => setLocalSearchValue(e.target.value)}
166
166
  value={localSearchValue}
167
167
  className="flex-1"
168
- startAdornment={<SearchIcon className="h-4 w-4 md:h-6 md:w-6" />}
168
+ startAdornment={<SearchIcon className="h-4 w-4 content-md:h-6 content-md:w-6" />}
169
169
  />
170
170
 
171
171
  {/* Mobile Filter Button - only visible on mobile when filter is enabled */}
@@ -173,7 +173,7 @@ export function ListPageLayout({
173
173
  <Button
174
174
  variant="outline"
175
175
  size="icon"
176
- className="md:hidden"
176
+ className="content-md:hidden"
177
177
  onClick={() => setMobileFilterOpen(true)}
178
178
  aria-label="Open filters"
179
179
  >
@@ -232,11 +232,15 @@ function renderAdvancedPageContainer({
232
232
 
233
233
  if (variant === 'detail') {
234
234
  return (
235
- <div className="flex items-end justify-between gap-4 md:flex-col md:items-start md:justify-start lg:flex-row lg:items-end lg:justify-between">
235
+ <div className="flex items-end justify-between gap-4 content-md:flex-col content-md:items-start content-md:justify-start content-lg:flex-row content-lg:items-end content-lg:justify-between">
236
236
  <div className="flex min-w-0 flex-1 flex-col gap-2">
237
237
  {/* Back Button */}
238
238
  {backButton && (
239
- <BackButton onClick={backButton.onClick} label={backButton.label} className="hidden md:inline-flex" />
239
+ <BackButton
240
+ onClick={backButton.onClick}
241
+ label={backButton.label}
242
+ className="hidden content-md:inline-flex"
243
+ />
240
244
  )}
241
245
 
242
246
  {/* Title */}
@@ -259,11 +263,15 @@ function renderAdvancedPageContainer({
259
263
 
260
264
  if (variant === 'list') {
261
265
  return (
262
- <div className="flex items-center justify-between gap-4 md:flex-col md:items-start md:justify-start lg:flex-row lg:items-center lg:justify-between">
266
+ <div className="flex items-center justify-between gap-4 content-md:flex-col content-md:items-start content-md:justify-start content-lg:flex-row content-lg:items-center content-lg:justify-between">
263
267
  <div className="flex min-w-0 flex-1 flex-col gap-1">
264
268
  {/* Back Button */}
265
269
  {backButton && (
266
- <BackButton onClick={backButton.onClick} label={backButton.label} className="hidden md:inline-flex" />
270
+ <BackButton
271
+ onClick={backButton.onClick}
272
+ label={backButton.label}
273
+ className="hidden content-md:inline-flex"
274
+ />
267
275
  )}
268
276
 
269
277
  {title && <h1 className="text-ods-text-primary text-h2">{accentSentenceMarks(title)}</h1>}
@@ -283,11 +291,15 @@ function renderAdvancedPageContainer({
283
291
 
284
292
  if (variant === 'form') {
285
293
  return (
286
- <div className="flex items-end justify-between gap-4 md:flex-col md:items-start md:justify-start lg:flex-row lg:items-end lg:justify-between">
294
+ <div className="flex items-end justify-between gap-4 content-md:flex-col content-md:items-start content-md:justify-start content-lg:flex-row content-lg:items-end content-lg:justify-between">
287
295
  <div className="flex min-w-0 flex-1 flex-col gap-2">
288
296
  {/* Back Button */}
289
297
  {backButton && (
290
- <BackButton onClick={backButton.onClick} label={backButton.label} className="hidden md:inline-flex" />
298
+ <BackButton
299
+ onClick={backButton.onClick}
300
+ label={backButton.label}
301
+ className="hidden content-md:inline-flex"
302
+ />
291
303
  )}
292
304
 
293
305
  {title && <h1 className="text-ods-text-primary text-h2">{accentSentenceMarks(title)}</h1>}
@@ -306,7 +318,7 @@ function renderAdvancedPageContainer({
306
318
 
307
319
  // Default content header
308
320
  return (
309
- <div className="flex items-center justify-between gap-4 md:flex-col md:items-start md:justify-start lg:flex-row lg:items-center lg:justify-between">
321
+ <div className="flex items-center justify-between gap-4 content-md:flex-col content-md:items-start content-md:justify-start content-lg:flex-row content-lg:items-center content-lg:justify-between">
310
322
  {(title || subtitle) && (
311
323
  <div className="flex min-w-0 flex-1 flex-col gap-1">
312
324
  {title && <h1 className="text-ods-text-primary text-h2">{accentSentenceMarks(title)}</h1>}
@@ -329,28 +341,28 @@ function renderAdvancedPageContainer({
329
341
 
330
342
  switch (variant) {
331
343
  case 'list':
332
- return cn(baseClasses, 'gap-4 md:gap-6', className);
344
+ return cn(baseClasses, 'gap-4 content-md:gap-6', className);
333
345
  case 'detail':
334
- return cn(baseClasses, 'gap-4 md:gap-6', className);
346
+ return cn(baseClasses, 'gap-4 content-md:gap-6', className);
335
347
  case 'form':
336
- return cn(baseClasses, 'gap-6 md:gap-10', className);
348
+ return cn(baseClasses, 'gap-6 content-md:gap-10', className);
337
349
  case 'content':
338
350
  default:
339
- return cn(baseClasses, 'gap-4 md:gap-6', className);
351
+ return cn(baseClasses, 'gap-4 content-md:gap-6', className);
340
352
  }
341
353
  };
342
354
 
343
355
  const getContentClasses = () => {
344
356
  // Add bottom padding on mobile when using primary-buttons variant (fixed bottom bar)
345
- const mobilePadding = needsBottomPadding ? 'pb-28 md:pb-0' : '';
357
+ const mobilePadding = needsBottomPadding ? 'pb-28 content-md:pb-0' : '';
346
358
 
347
359
  switch (variant) {
348
360
  case 'detail':
349
361
  return cn('flex-1 overflow-auto', mobilePadding, contentClassName);
350
362
  case 'list':
351
- return cn('flex flex-col gap-4 md:gap-6', mobilePadding, contentClassName);
363
+ return cn('flex flex-col gap-4 content-md:gap-6', mobilePadding, contentClassName);
352
364
  case 'form':
353
- return cn('flex flex-col gap-4 md:gap-10', mobilePadding, contentClassName);
365
+ return cn('flex flex-col gap-4 content-md:gap-10', mobilePadding, contentClassName);
354
366
  case 'content':
355
367
  default:
356
368
  return cn('flex-1', mobilePadding, contentClassName);
@@ -23,7 +23,7 @@ export const PAGE_HEADING_CLASS = 'text-h1 text-ods-text-primary';
23
23
  export const SECTION_HEADING_CLASS = 'text-h2 text-ods-text-primary';
24
24
 
25
25
  const DESCRIPTION_CLASS =
26
- 'mt-6 max-w-[640px] font-body text-[16px] md:text-[18px] leading-[24px] md:leading-[28px] text-ods-text-secondary';
26
+ 'mt-6 max-w-[640px] font-body text-[16px] content-md:text-[18px] leading-[24px] content-md:leading-[28px] text-ods-text-secondary';
27
27
 
28
28
  export interface PageHeadingProps {
29
29
  /** Heading content — plain text or nodes (e.g. an accent <span>). */
@@ -141,7 +141,7 @@ export function PageLayout({
141
141
  <div
142
142
  className={cn(
143
143
  'flex flex-1 flex-col gap-[var(--spacing-system-l)]',
144
- needsBottomPadding && 'pb-28 md:pb-0',
144
+ needsBottomPadding && 'pb-28 content-md:pb-0',
145
145
  contentClassName,
146
146
  )}
147
147
  >
@@ -59,10 +59,10 @@
59
59
  * responsive action layout on md+. This one intentionally CHANGES the baseline
60
60
  * for every caller, per the approved design (Figma open-design-system node
61
61
  * 2200-7452): instead of tablet always stacking actions below the title
62
- * (`md:flex-col`) and desktop always keeping one row (long titles clipped),
62
+ * (`content-md:flex-col`) and desktop always keeping one row (long titles clipped),
63
63
  * md+ is a single `flex-wrap` row — actions stay inline with a short title on
64
64
  * BOTH tablet and desktop, and wrap to a second row only when the title is
65
- * long enough to overflow. The title column is `md:flex-none md:max-w-full`
65
+ * long enough to overflow. The title column is `content-md:flex-none content-md:max-w-full`
66
66
  * so its natural width drives the wrap while `truncate` still clamps a title
67
67
  * that alone exceeds the container. The mobile (base) layout is untouched.
68
68
  * This is the new frozen baseline; do NOT re-introduce breakpoint stacking.
@@ -93,13 +93,13 @@ import { BackButton } from './back-button';
93
93
  /**
94
94
  * Minimum height of the title block's content column, matched to the action
95
95
  * button height: the icon button on mobile (`h-11` → 44px) and the default
96
- * button on desktop (`md:h-12` → 48px). Applied to the inner title column (which
96
+ * button on desktop (`content-md:h-12` → 48px). Applied to the inner title column (which
97
97
  * has no padding) rather than the root — the root's `pt`/`mb` are box-sizing
98
98
  * border-box and would otherwise absorb the floor. Keeps the header a consistent
99
99
  * height across pages whether or not they render action buttons, so the content
100
100
  * below starts at the same baseline. Exported so other page chrome can reuse it.
101
101
  */
102
- export const TITLE_BLOCK_MIN_HEIGHT = 'min-h-11 md:min-h-12';
102
+ export const TITLE_BLOCK_MIN_HEIGHT = 'min-h-11 content-md:min-h-12';
103
103
 
104
104
  export interface TitleBlockProps {
105
105
  title?: string;
@@ -186,8 +186,8 @@ function TitleTextSkeleton({ widthClass, heightClass }: { widthClass: string; he
186
186
  * see `TitleTextSkeleton` for why that is what keeps the header height honest.
187
187
  */
188
188
  const TITLE_SKELETON_SIZE = {
189
- h1: { width: 'w-56 md:w-80 lg:w-96', height: 'h-7 md:h-8 lg:h-9' },
190
- h2: { width: 'w-48 md:w-72', height: 'h-4 md:h-6' },
189
+ h1: { width: 'w-56 content-md:w-80 content-lg:w-96', height: 'h-7 content-md:h-8 content-lg:h-9' },
190
+ h2: { width: 'w-48 content-md:w-72', height: 'h-4 content-md:h-6' },
191
191
  } as const;
192
192
 
193
193
  export function TitleBlock({
@@ -236,15 +236,15 @@ export function TitleBlock({
236
236
  'flex items-end justify-between gap-[var(--spacing-system-m)]',
237
237
  // md+: one wrapping row — actions stay inline with a short title and
238
238
  // wrap to a second row only when the title overflows (ClickUp 86ahd6uy5).
239
- 'md:flex-wrap md:content-end',
239
+ 'content-md:flex-wrap content-md:content-end',
240
240
  'pt-[var(--spacing-system-l)]',
241
241
  variant === 'card'
242
242
  ? cn(
243
243
  'border-b border-ods-border bg-ods-card',
244
244
  'px-[var(--spacing-system-l)] pb-[var(--spacing-system-l)]',
245
- 'md:border-b-0 md:bg-transparent',
246
- 'md:px-0 md:pb-0',
247
- 'md:mb-[var(--spacing-system-l)]',
245
+ 'content-md:border-b-0 content-md:bg-transparent',
246
+ 'content-md:px-0 content-md:pb-0',
247
+ 'content-md:mb-[var(--spacing-system-l)]',
248
248
  )
249
249
  : 'mb-[var(--spacing-system-l)]',
250
250
  className,
@@ -255,12 +255,12 @@ export function TitleBlock({
255
255
  wrap line; a short title leaves them inline. Base (mobile) keeps flex-1. */}
256
256
  <div
257
257
  className={cn(
258
- 'flex min-w-0 flex-1 flex-col justify-center gap-[var(--spacing-system-xs)] md:max-w-full md:flex-none',
258
+ 'flex min-w-0 flex-1 flex-col justify-center gap-[var(--spacing-system-xs)] content-md:max-w-full content-md:flex-none',
259
259
  TITLE_BLOCK_MIN_HEIGHT,
260
260
  )}
261
261
  >
262
262
  {backButton && (
263
- <BackButton onClick={backButton.onClick} label={backButton.label} className="hidden md:inline-flex" />
263
+ <BackButton onClick={backButton.onClick} label={backButton.label} className="hidden content-md:inline-flex" />
264
264
  )}
265
265
  {image || hasSubtitleRow || loading ? (
266
266
  <div className="flex w-full min-w-0 items-center gap-[var(--spacing-system-m)]">
@@ -306,7 +306,7 @@ export function TitleBlock({
306
306
  aria-hidden={!loading && !subtitle ? true : undefined}
307
307
  >
308
308
  {loading ? (
309
- <TitleTextSkeleton widthClass="w-28 md:w-36" heightClass="h-2.5 md:h-3" />
309
+ <TitleTextSkeleton widthClass="w-28 content-md:w-36" heightClass="h-2.5 content-md:h-3" />
310
310
  ) : (
311
311
  subtitle || '\u00A0'
312
312
  )}
@@ -96,7 +96,7 @@ function VendorCardContent({ showMetadata }: { showMetadata: boolean }) {
96
96
  {showMetadata && (
97
97
  <div className="flex w-full min-w-0 items-center justify-between gap-2">
98
98
  {/* Stats Container - Flexible width, no overflow */}
99
- <div className="flex min-w-0 flex-shrink items-center gap-3 md:gap-4">
99
+ <div className="flex min-w-0 flex-shrink items-center gap-3 content-md:gap-4">
100
100
  {/* OpenMSP Score skeleton */}
101
101
  <div className="flex flex-shrink-0 items-center gap-1">
102
102
  <MediaSkeleton.Icon size="sm" className="h-5 w-5" />
@@ -139,7 +139,7 @@ function BlogCardContent({ showActions, showMetadata }: { showActions: boolean;
139
139
  {/* Content - Fixed height structure to match BlogCard */}
140
140
  <div className="flex flex-grow flex-col p-4">
141
141
  {/* Title Section - Fixed 2 lines with vertical centering */}
142
- <div className="mb-3 flex min-h-[50.4px] items-center md:min-h-[56px] lg:min-h-[61.6px]">
142
+ <div className="mb-3 flex min-h-[50.4px] items-center content-md:min-h-[56px] content-lg:min-h-[61.6px]">
143
143
  <div className="w-full space-y-1">
144
144
  <TextSkeleton.Subheading className="w-full" />
145
145
  <TextSkeleton.Subheading className="w-3/4" />
@@ -153,7 +153,7 @@ function BlogCardContent({ showActions, showMetadata }: { showActions: boolean;
153
153
  </div>
154
154
 
155
155
  {/* Description Section - Fixed 2 lines with vertical centering */}
156
- <div className="mb-3 flex min-h-[42px] items-center md:min-h-[45px] lg:min-h-[48px]">
156
+ <div className="mb-3 flex min-h-[42px] items-center content-md:min-h-[45px] content-lg:min-h-[48px]">
157
157
  <div className="w-full space-y-1">
158
158
  <TextSkeleton.Body className="w-full" />
159
159
  <TextSkeleton.Body className="w-1/2" />
@@ -197,9 +197,9 @@ function BlogCardContent({ showActions, showMetadata }: { showActions: boolean;
197
197
  */
198
198
  function CategoryCardContent() {
199
199
  return (
200
- <div className="space-y-4 p-4 md:p-6">
200
+ <div className="space-y-4 p-4 content-md:p-6">
201
201
  {/* Icon grid */}
202
- <div className="flex gap-2 md:gap-3">
202
+ <div className="flex gap-2 content-md:gap-3">
203
203
  {Array.from({ length: 6 }).map((_, index) => (
204
204
  <MediaSkeleton.Icon key={index} size="lg" className="flex-shrink-0" />
205
205
  ))}
@@ -212,13 +212,13 @@ function CategoryCardContent() {
212
212
  <TextSkeleton.Caption className="w-1/2" />
213
213
  </div>
214
214
 
215
- <div className="flex items-start justify-between gap-4 md:items-end md:gap-6">
215
+ <div className="flex items-start justify-between gap-4 content-md:items-end content-md:gap-6">
216
216
  <div className="flex-1 space-y-2">
217
217
  <TextSkeleton.Body className="w-full" />
218
218
  <TextSkeleton.Body className="w-2/3" />
219
219
  </div>
220
220
 
221
- <InteractiveSkeleton.Button className="h-10 w-10 flex-shrink-0 md:h-12 md:w-12" />
221
+ <InteractiveSkeleton.Button className="h-10 w-10 flex-shrink-0 content-md:h-12 content-md:w-12" />
222
222
  </div>
223
223
  </div>
224
224
  </div>
@@ -272,11 +272,11 @@ export function CardSkeletonGrid({
272
272
  return (
273
273
  <div
274
274
  className={cn(
275
- 'grid gap-4 md:gap-6',
275
+ 'grid gap-4 content-md:gap-6',
276
276
  // Responsive grid based on card type
277
- variant === 'vendor' && 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
278
- variant === 'blog' && 'grid-cols-1 md:grid-cols-2',
279
- variant === 'category' && 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',
277
+ variant === 'vendor' && 'grid-cols-1 content-md:grid-cols-2 content-lg:grid-cols-3',
278
+ variant === 'blog' && 'grid-cols-1 content-md:grid-cols-2',
279
+ variant === 'category' && 'grid-cols-1 content-md:grid-cols-2 content-lg:grid-cols-4',
280
280
  variant === 'alternative' && 'grid-cols-1',
281
281
  className,
282
282
  )}
@@ -27,7 +27,7 @@ export function CategoryVendorSelectorSkeleton({ subcategories = 3, className }:
27
27
  {/* Subcategory title */}
28
28
  <TextSkeleton.Subheading className="w-1/3" />
29
29
  {/* Vendor slots container */}
30
- <div className="grid grid-cols-2 gap-4 md:grid-cols-3">
30
+ <div className="grid grid-cols-2 gap-4 content-md:grid-cols-3">
31
31
  {Array.from({ length: 2 }).map((__, j) => (
32
32
  <UnifiedSkeleton key={j} className="h-20 rounded-lg" />
33
33
  ))}
@@ -39,7 +39,7 @@ export function ListSkeleton({
39
39
  <div key={index} className="flex items-center justify-between">
40
40
  <div className="flex items-center gap-3">
41
41
  {showIcons && <MediaSkeleton.Icon size="sm" />}
42
- <TextSkeleton.Body className="w-32 md:w-48" />
42
+ <TextSkeleton.Body className="w-32 content-md:w-48" />
43
43
  </div>
44
44
  {showActions && (
45
45
  <div className="flex items-center gap-2">
@@ -126,12 +126,12 @@ export function NavigationSkeleton({
126
126
  }) {
127
127
  return (
128
128
  <nav
129
- className={cn('flex gap-4 md:gap-6', !horizontal && 'flex-col', className)}
129
+ className={cn('flex gap-4 content-md:gap-6', !horizontal && 'flex-col', className)}
130
130
  role="status"
131
131
  aria-label="Loading navigation"
132
132
  >
133
133
  {Array.from({ length: items }).map((_, index) => (
134
- <TextSkeleton.Body key={index} className="w-16 md:w-20" />
134
+ <TextSkeleton.Body key={index} className="w-16 content-md:w-20" />
135
135
  ))}
136
136
  </nav>
137
137
  );
@@ -336,9 +336,9 @@ export function PricingSkeleton({ className, plans = 3 }: ContentSkeletonProps &
336
336
  <div
337
337
  className={cn(
338
338
  'grid gap-6',
339
- plans === 2 && 'grid-cols-1 md:grid-cols-2',
340
- plans === 3 && 'grid-cols-1 md:grid-cols-3',
341
- plans === 4 && 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',
339
+ plans === 2 && 'grid-cols-1 content-md:grid-cols-2',
340
+ plans === 3 && 'grid-cols-1 content-md:grid-cols-3',
341
+ plans === 4 && 'grid-cols-1 content-md:grid-cols-2 content-lg:grid-cols-4',
342
342
  className,
343
343
  )}
344
344
  >
@@ -81,7 +81,7 @@ export function DeviceCardSkeleton({ className }: DeviceCardSkeletonProps) {
81
81
  export function DeviceCardSkeletonGrid({ count = 12, className }: { count?: number; className?: string }) {
82
82
  return (
83
83
  <div
84
- className={cn('grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4', className)}
84
+ className={cn('grid grid-cols-1 gap-4 content-md:grid-cols-2 content-lg:grid-cols-4', className)}
85
85
  role="status"
86
86
  aria-label={`Loading ${count} device cards`}
87
87
  >
@@ -12,7 +12,7 @@ interface MarginReportSkeletonProps {
12
12
  export function MarginReportSkeleton({ animate = true, description, overlayContent }: MarginReportSkeletonProps) {
13
13
  return (
14
14
  <main className={`bg-ods-bg ${animate ? 'animate-pulse' : ''} relative min-h-screen`}>
15
- <div className="mx-auto max-w-[1920px] space-y-10 px-6 py-6 md:px-20 md:py-10">
15
+ <div className="mx-auto max-w-[1920px] space-y-10 px-6 py-6 content-md:px-20 content-md:py-10">
16
16
  {/* Header */}
17
17
  <div className="space-y-3">
18
18
  <div className="h-10 w-72 rounded bg-ods-skeleton" />
@@ -20,14 +20,14 @@ export function MarginReportSkeleton({ animate = true, description, overlayConte
20
20
  </div>
21
21
 
22
22
  {/* Summary cards */}
23
- <div className="grid grid-cols-1 gap-6 md:grid-cols-3">
23
+ <div className="grid grid-cols-1 gap-6 content-md:grid-cols-3">
24
24
  {Array.from({ length: 3 }).map((_, i) => (
25
25
  <div key={i} className="h-32 rounded border border-ods-border bg-ods-card" />
26
26
  ))}
27
27
  </div>
28
28
 
29
29
  {/* MSP Profile & Report Info cards */}
30
- <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
30
+ <div className="grid grid-cols-1 gap-6 content-md:grid-cols-2">
31
31
  {/* MSP profile skeleton */}
32
32
  <div className="flex animate-pulse items-center gap-4 rounded-lg border border-ods-border bg-ods-card p-6">
33
33
  <div className="h-14 w-14 rounded-lg bg-ods-skeleton" />
@@ -54,7 +54,7 @@ export function MarginReportSkeleton({ animate = true, description, overlayConte
54
54
  </div>
55
55
 
56
56
  {/* Vendor solution lists (Commercial & Open-Source) */}
57
- <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
57
+ <div className="grid grid-cols-1 gap-6 content-md:grid-cols-2">
58
58
  {['Commercial Stack', 'Open-Source Stack'].map((label, idx) => (
59
59
  <div
60
60
  key={idx}
@@ -81,7 +81,7 @@ export function MarginReportSkeleton({ animate = true, description, overlayConte
81
81
  <div className="h-12 w-12 flex-shrink-0 rounded-lg bg-ods-skeleton" />
82
82
  <div className="flex min-w-0 flex-col">
83
83
  <div className="h-4 w-32 rounded bg-ods-skeleton" />
84
- <div className="mt-1 hidden h-3 w-24 rounded bg-ods-skeleton md:block" />
84
+ <div className="mt-1 hidden h-3 w-24 rounded bg-ods-skeleton content-md:block" />
85
85
  </div>
86
86
  </div>
87
87
  {/* right addon: cost text */}
@@ -100,7 +100,7 @@ export function MarginReportSkeleton({ animate = true, description, overlayConte
100
100
  <div className="h-6 w-60 rounded bg-ods-skeleton" />
101
101
 
102
102
  {/* Recommendations grid */}
103
- <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
103
+ <div className="grid grid-cols-1 gap-6 content-md:grid-cols-2 content-lg:grid-cols-3">
104
104
  {Array.from({ length: 3 }).map((_, i) => (
105
105
  <div key={i} className="h-48 rounded border border-ods-border bg-ods-card" />
106
106
  ))}
@@ -119,7 +119,7 @@ export function MarginReportSkeleton({ animate = true, description, overlayConte
119
119
  </div>
120
120
 
121
121
  {/* Value cards grid */}
122
- <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
122
+ <div className="grid grid-cols-1 gap-6 content-md:grid-cols-2 content-lg:grid-cols-3">
123
123
  {Array.from({ length: 3 }).map((_, i) => (
124
124
  <div key={i} className="h-32 rounded border border-ods-border bg-ods-card" />
125
125
  ))}
@@ -26,7 +26,7 @@ interface SkeletonProps {
26
26
  export function MspProfileFormSkeleton({ className, fields = 4 }: SkeletonProps) {
27
27
  return (
28
28
  <div
29
- className={cn('grid grid-cols-1 items-stretch gap-6 md:grid-cols-2', className)}
29
+ className={cn('grid grid-cols-1 items-stretch gap-6 content-md:grid-cols-2', className)}
30
30
  role="status"
31
31
  aria-label="Loading MSP profile form"
32
32
  >
@@ -34,13 +34,13 @@ export function MspProfileFormSkeleton({ className, fields = 4 }: SkeletonProps)
34
34
  <div className="flex h-full flex-col space-y-2">
35
35
  {/* Label skeleton */}
36
36
  <TextSkeleton.Body className="w-28" />
37
- <div className="min-h-[180px] flex-1 md:min-h-full">
37
+ <div className="min-h-[180px] flex-1 content-md:min-h-full">
38
38
  <UnifiedSkeleton className="h-full w-full rounded-lg" aria-label="Loading company logo" />
39
39
  </div>
40
40
  </div>
41
41
 
42
42
  {/* Right – Input fields grid (mirrors form) */}
43
- <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
43
+ <div className="grid grid-cols-1 gap-4 content-md:grid-cols-2">
44
44
  {Array.from({ length: fields }).map((_, idx) => (
45
45
  <div key={idx} className="flex flex-col space-y-2">
46
46
  <TextSkeleton.Body className="w-40" />
@@ -84,7 +84,7 @@ export function OrganizationCardSkeleton({
84
84
  {showFooter && (
85
85
  <div className="flex w-full min-w-0 items-center justify-between gap-2">
86
86
  {/* Stats Container */}
87
- <div className="flex min-w-0 flex-shrink items-center gap-3 md:gap-4">
87
+ <div className="flex min-w-0 flex-shrink items-center gap-3 content-md:gap-4">
88
88
  {/* Stat 1 */}
89
89
  <div className="flex flex-shrink-0 items-center gap-1">
90
90
  <MediaSkeleton.Icon size="sm" className="h-5 w-5" />
@@ -137,7 +137,7 @@ export function OrganizationCardSkeletonGrid({
137
137
  }) {
138
138
  return (
139
139
  <div
140
- className={cn('grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-6 lg:grid-cols-3', className)}
140
+ className={cn('grid grid-cols-1 gap-4 content-md:grid-cols-2 content-md:gap-6 content-lg:grid-cols-3', className)}
141
141
  role="status"
142
142
  aria-label={`Loading ${count} organization cards`}
143
143
  >