@flamingo-stack/openframe-frontend-core 0.0.733 → 0.0.735

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 (89) hide show
  1. package/dist/build/export-map.json +1 -1
  2. package/dist/{chunk-3KGICRH7.cjs → chunk-36CCUJOE.cjs} +406 -353
  3. package/dist/{chunk-TIMCHP4X.cjs → chunk-3FZZPR76.cjs} +42 -42
  4. package/dist/{chunk-CJVAA7KL.cjs → chunk-3JP2OVH3.cjs} +30 -30
  5. package/dist/{chunk-HSWHOCZ3.cjs → chunk-3X4N3IT7.cjs} +18 -18
  6. package/dist/{chunk-ATMBJBOI.cjs → chunk-4F7V2MAC.cjs} +12 -12
  7. package/dist/{chunk-U4T5NLZD.cjs → chunk-6TTAILSV.cjs} +3 -3
  8. package/dist/{chunk-XDWY6HAW.cjs → chunk-7HT3VHLJ.cjs} +17 -17
  9. package/dist/{chunk-AV5533DH.cjs → chunk-EQ7OOK4B.cjs} +11 -11
  10. package/dist/{chunk-XY632BCH.cjs → chunk-EQH7BUNS.cjs} +4 -4
  11. package/dist/{chunk-3UTPZW36.cjs → chunk-F7STMHT7.cjs} +65 -65
  12. package/dist/{chunk-EMG3T55N.cjs → chunk-HLBFTDUL.cjs} +2 -2
  13. package/dist/{chunk-YIXKH2JO.cjs → chunk-JDXQ6T5P.cjs} +128 -112
  14. package/dist/{chunk-GB3CHAW7.cjs → chunk-MRVZ56GT.cjs} +79 -79
  15. package/dist/{chunk-FNRMDDVN.cjs → chunk-NVCSVGNI.cjs} +33 -33
  16. package/dist/{chunk-P3R23TOE.cjs → chunk-RH3AKULV.cjs} +21 -11
  17. package/dist/{chunk-J7JKPTGO.cjs → chunk-SHQZN5LF.cjs} +6 -6
  18. package/dist/{chunk-ZBNA6TCW.cjs → chunk-SZRZBCWC.cjs} +67 -67
  19. package/dist/{chunk-E26I4XH6.cjs → chunk-T323E2Y6.cjs} +4 -4
  20. package/dist/{chunk-IC4FT3A6.cjs → chunk-TUMUT7CV.cjs} +15 -15
  21. package/dist/{chunk-BP6R5WDW.cjs → chunk-VA7OMDZO.cjs} +41 -23
  22. package/dist/{chunk-EQORT7NK.cjs → chunk-W6E7XCBI.cjs} +38 -38
  23. package/dist/{cloud-tenants-3GOGR3EN.cjs → cloud-tenants-H5D57P4U.cjs} +7 -7
  24. package/dist/components/case-studies/index.cjs +19 -19
  25. package/dist/components/chat/entity-cards/program-card.d.ts.map +1 -1
  26. package/dist/components/chat/entity-cards/program-card.js +6 -6
  27. package/dist/components/chat/index.cjs +5 -5
  28. package/dist/components/contact/index.cjs +8 -8
  29. package/dist/components/docs/index.cjs +11 -11
  30. package/dist/components/embeds/index.cjs +8 -8
  31. package/dist/components/faq/index.cjs +8 -8
  32. package/dist/components/features/cards-strip.d.ts.map +1 -1
  33. package/dist/components/features/cards-strip.js +6 -2
  34. package/dist/components/features/index.cjs +7 -7
  35. package/dist/components/features/video-bites-strip.d.ts +6 -1
  36. package/dist/components/features/video-bites-strip.d.ts.map +1 -1
  37. package/dist/components/features/video-bites-strip.js +15 -3
  38. package/dist/components/help-center-pages/index.cjs +106 -106
  39. package/dist/components/index.cjs +61 -55
  40. package/dist/components/layout/page-heading.d.ts +9 -1
  41. package/dist/components/layout/page-heading.d.ts.map +1 -1
  42. package/dist/components/layout/page-heading.js +15 -5
  43. package/dist/components/meeting-scheduler/index.cjs +29 -29
  44. package/dist/components/navigation/index.cjs +10 -10
  45. package/dist/components/onboarding-guides/index.cjs +10 -10
  46. package/dist/components/product-demo/index.cjs +6 -6
  47. package/dist/components/related-content/index.cjs +4 -4
  48. package/dist/components/tickets/index.cjs +11 -11
  49. package/dist/components/ui/fade-preview.d.ts +5 -1
  50. package/dist/components/ui/fade-preview.d.ts.map +1 -1
  51. package/dist/components/ui/fade-preview.js +18 -1
  52. package/dist/components/ui/index.cjs +13 -7
  53. package/dist/components/ui/index.d.ts +1 -0
  54. package/dist/components/ui/index.d.ts.map +1 -1
  55. package/dist/components/ui/index.js +1 -0
  56. package/dist/components/ui/layout-hold.d.ts +31 -0
  57. package/dist/components/ui/layout-hold.d.ts.map +1 -0
  58. package/dist/components/ui/layout-hold.js +25 -0
  59. package/dist/components/ui/snap-carousel.d.ts.map +1 -1
  60. package/dist/components/ui/snap-carousel.js +28 -15
  61. package/dist/{devices-POZXTP7X.cjs → devices-SQTEXY2H.cjs} +8 -8
  62. package/dist/{embeddable-chat-I3Y5GCCR.cjs → embeddable-chat-S5ODWE3L.cjs} +71 -71
  63. package/dist/hooks/index.cjs +4 -2
  64. package/dist/hooks/ui/index.d.ts +1 -0
  65. package/dist/hooks/ui/index.d.ts.map +1 -1
  66. package/dist/hooks/ui/index.js +1 -0
  67. package/dist/hooks/ui/use-resumable-timeout.d.ts +22 -0
  68. package/dist/hooks/ui/use-resumable-timeout.d.ts.map +1 -0
  69. package/dist/hooks/ui/use-resumable-timeout.js +26 -0
  70. package/dist/hooks/use-scenario-player.d.ts +4 -3
  71. package/dist/hooks/use-scenario-player.d.ts.map +1 -1
  72. package/dist/hooks/use-scenario-player.js +17 -23
  73. package/dist/index.cjs +19 -11
  74. package/dist/{knowledge-AP34IMXN.cjs → knowledge-FO3TPLFO.cjs} +8 -8
  75. package/dist/{logs-CEVMIOPW.cjs → logs-Y4WQB2YR.cjs} +15 -15
  76. package/dist/{policies-AMBMRCGB.cjs → policies-D6VY2ODF.cjs} +11 -11
  77. package/dist/{software-update-Z3MWMSHI.cjs → software-update-7XN6U7HC.cjs} +10 -10
  78. package/package.json +1 -1
  79. package/src/components/chat/entity-cards/program-card.tsx +9 -8
  80. package/src/components/features/cards-strip.tsx +11 -2
  81. package/src/components/features/video-bites-strip.tsx +22 -3
  82. package/src/components/layout/page-heading.tsx +37 -7
  83. package/src/components/ui/fade-preview.tsx +30 -1
  84. package/src/components/ui/index.ts +1 -0
  85. package/src/components/ui/layout-hold.tsx +55 -0
  86. package/src/components/ui/snap-carousel.tsx +36 -20
  87. package/src/hooks/ui/index.ts +1 -0
  88. package/src/hooks/ui/use-resumable-timeout.ts +55 -0
  89. package/src/hooks/use-scenario-player.ts +28 -32
@@ -8,23 +8,23 @@ var _chunkII4QMH26cjs = require('./chunk-II4QMH26.cjs');
8
8
  var _chunkKHXZFLINcjs = require('./chunk-KHXZFLIN.cjs');
9
9
 
10
10
 
11
- var _chunk3KGICRH7cjs = require('./chunk-3KGICRH7.cjs');
11
+ var _chunk36CCUJOEcjs = require('./chunk-36CCUJOE.cjs');
12
12
  require('./chunk-ZJNYWNCB.cjs');
13
13
  require('./chunk-3HPB4H4C.cjs');
14
14
  require('./chunk-L4ZNR5V7.cjs');
15
15
  require('./chunk-HQQE74RO.cjs');
16
16
  require('./chunk-DEY6XXGO.cjs');
17
- require('./chunk-BP6R5WDW.cjs');
17
+ require('./chunk-VA7OMDZO.cjs');
18
18
  require('./chunk-AAFW4STC.cjs');
19
19
  require('./chunk-24I6RFVU.cjs');
20
20
  require('./chunk-A6P6DHEZ.cjs');
21
21
  require('./chunk-MZ4KBSH7.cjs');
22
22
  require('./chunk-OXJ57643.cjs');
23
23
  require('./chunk-YUMFVQIN.cjs');
24
- require('./chunk-3UTPZW36.cjs');
24
+ require('./chunk-F7STMHT7.cjs');
25
25
 
26
26
 
27
- var _chunkYIXKH2JOcjs = require('./chunk-YIXKH2JO.cjs');
27
+ var _chunkJDXQ6T5Pcjs = require('./chunk-JDXQ6T5P.cjs');
28
28
  require('./chunk-ZRYKDN2J.cjs');
29
29
  require('./chunk-HZJRERJW.cjs');
30
30
  require('./chunk-DUXLZPMJ.cjs');
@@ -1825,8 +1825,8 @@ require('./chunk-7DNL734S.cjs');
1825
1825
  require('./chunk-WWUSFOJ7.cjs');
1826
1826
  require('./chunk-SKI6NKOE.cjs');
1827
1827
  require('./chunk-EWPR7662.cjs');
1828
- require('./chunk-J7JKPTGO.cjs');
1829
- require('./chunk-P3R23TOE.cjs');
1828
+ require('./chunk-SHQZN5LF.cjs');
1829
+ require('./chunk-RH3AKULV.cjs');
1830
1830
  require('./chunk-FCGLSWKR.cjs');
1831
1831
  require('./chunk-YADG5Q7C.cjs');
1832
1832
  require('./chunk-MYBTNOS6.cjs');
@@ -1905,10 +1905,10 @@ function KnowledgeScreen(_props) {
1905
1905
  const cast = _chunkII4QMH26cjs.useProductDemoCast.call(void 0, );
1906
1906
  const fixture = _react.useMemo.call(void 0, () => buildKnowledgeFixture(cast), [cast]);
1907
1907
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full bg-ods-bg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1908
- _chunk3KGICRH7cjs.KnowledgeBaseArticleView,
1908
+ _chunk36CCUJOEcjs.KnowledgeBaseArticleView,
1909
1909
  {
1910
1910
  ...fixture.article,
1911
- content: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkYIXKH2JOcjs.SimpleMarkdownRenderer, { content: fixture.content, textSize: "compact" })
1911
+ content: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDXQ6T5Pcjs.SimpleMarkdownRenderer, { content: fixture.content, textSize: "compact" })
1912
1912
  }
1913
1913
  ) });
1914
1914
  }
@@ -16,13 +16,13 @@ var _chunkKHXZFLINcjs = require('./chunk-KHXZFLIN.cjs');
16
16
 
17
17
 
18
18
 
19
- var _chunk3KGICRH7cjs = require('./chunk-3KGICRH7.cjs');
19
+ var _chunk36CCUJOEcjs = require('./chunk-36CCUJOE.cjs');
20
20
  require('./chunk-ZJNYWNCB.cjs');
21
21
  require('./chunk-3HPB4H4C.cjs');
22
22
  require('./chunk-L4ZNR5V7.cjs');
23
23
  require('./chunk-HQQE74RO.cjs');
24
24
  require('./chunk-DEY6XXGO.cjs');
25
- require('./chunk-BP6R5WDW.cjs');
25
+ require('./chunk-VA7OMDZO.cjs');
26
26
  require('./chunk-AAFW4STC.cjs');
27
27
  require('./chunk-24I6RFVU.cjs');
28
28
  require('./chunk-A6P6DHEZ.cjs');
@@ -31,8 +31,8 @@ require('./chunk-OXJ57643.cjs');
31
31
  require('./chunk-YUMFVQIN.cjs');
32
32
 
33
33
 
34
- var _chunk3UTPZW36cjs = require('./chunk-3UTPZW36.cjs');
35
- require('./chunk-YIXKH2JO.cjs');
34
+ var _chunkF7STMHT7cjs = require('./chunk-F7STMHT7.cjs');
35
+ require('./chunk-JDXQ6T5P.cjs');
36
36
  require('./chunk-ZRYKDN2J.cjs');
37
37
  require('./chunk-HZJRERJW.cjs');
38
38
  require('./chunk-DUXLZPMJ.cjs');
@@ -1833,8 +1833,8 @@ require('./chunk-7DNL734S.cjs');
1833
1833
  require('./chunk-WWUSFOJ7.cjs');
1834
1834
  require('./chunk-SKI6NKOE.cjs');
1835
1835
  require('./chunk-EWPR7662.cjs');
1836
- require('./chunk-J7JKPTGO.cjs');
1837
- require('./chunk-P3R23TOE.cjs');
1836
+ require('./chunk-SHQZN5LF.cjs');
1837
+ require('./chunk-RH3AKULV.cjs');
1838
1838
  require('./chunk-FCGLSWKR.cjs');
1839
1839
  require('./chunk-YADG5Q7C.cjs');
1840
1840
  require('./chunk-MYBTNOS6.cjs');
@@ -1886,7 +1886,7 @@ function entry(logId, minutesAgo, severity, toolType, device2, summary) {
1886
1886
  id: logId,
1887
1887
  logId,
1888
1888
  timestamp: displayTime(_chunkKHXZFLINcjs.demoMinutesAgo.call(void 0, minutesAgo)),
1889
- status: { label: severity, variant: _chunk3KGICRH7cjs.logSeverityVariant.call(void 0, severity) },
1889
+ status: { label: severity, variant: _chunk36CCUJOEcjs.logSeverityVariant.call(void 0, severity) },
1890
1890
  source: { name: toolType, toolType },
1891
1891
  device: device2,
1892
1892
  description: { title: summary }
@@ -1958,13 +1958,13 @@ var NO_FILTERS = {};
1958
1958
  var ACTION_COLUMNS = ["copy", "quickView", "open"];
1959
1959
  var BESIDE_DRAWER_HIDDEN = [...ACTION_COLUMNS, "tool", "source"];
1960
1960
  var logHref = () => "#";
1961
- var copyAction = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3KGICRH7cjs.LogCopyIconButton, {});
1961
+ var copyAction = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.LogCopyIconButton, {});
1962
1962
  function LogsScreen({ compact = false }) {
1963
1963
  const [dock, setDock] = _react.useState.call(void 0, null);
1964
1964
  const selected = LOGS_FIXTURE_SELECTED;
1965
1965
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full bg-ods-bg", children: [
1966
1966
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-w-0 flex-1 overflow-clip", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1967
- _chunk3KGICRH7cjs.LogsPageView,
1967
+ _chunk36CCUJOEcjs.LogsPageView,
1968
1968
  {
1969
1969
  showHeader: false,
1970
1970
  className: "p-[var(--spacing-system-l)]",
@@ -1972,7 +1972,7 @@ function LogsScreen({ compact = false }) {
1972
1972
  onSearchChange: noop,
1973
1973
  onOpenFilters: noop,
1974
1974
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1975
- _chunk3KGICRH7cjs.LogsTableView,
1975
+ _chunk36CCUJOEcjs.LogsTableView,
1976
1976
  {
1977
1977
  logs: LOGS_FIXTURE_ENTRIES,
1978
1978
  facets: LOGS_FIXTURE_FACETS,
@@ -1986,8 +1986,8 @@ function LogsScreen({ compact = false }) {
1986
1986
  )
1987
1987
  }
1988
1988
  ) }),
1989
- !compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: setDock, className: "relative w-[calc(400px+var(--spacing-system-m))] shrink-0", children: dock && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3KGICRH7cjs.AppLayoutDrawerContainerContext.Provider, { value: dock, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1990
- _chunk3KGICRH7cjs.LogDrawer,
1989
+ !compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: setDock, className: "relative w-[calc(400px+var(--spacing-system-m))] shrink-0", children: dock && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.AppLayoutDrawerContainerContext.Provider, { value: dock, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1990
+ _chunk36CCUJOEcjs.LogDrawer,
1991
1991
  {
1992
1992
  docked: true,
1993
1993
  isOpen: true,
@@ -1999,12 +1999,12 @@ function LogsScreen({ compact = false }) {
1999
1999
  { label: "Log ID", value: selected.logId },
2000
2000
  {
2001
2001
  label: "Source",
2002
- value: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3KGICRH7cjs.ToolBadge, { toolType: _chunk3UTPZW36cjs.normalizeToolTypeWithFallback.call(void 0, selected.source.toolType) })
2002
+ value: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.ToolBadge, { toolType: _chunkF7STMHT7cjs.normalizeToolTypeWithFallback.call(void 0, selected.source.toolType) })
2003
2003
  },
2004
- { label: "Device", value: _chunk3KGICRH7cjs.logSourceLabels.call(void 0, selected.device).deviceName }
2004
+ { label: "Device", value: _chunk36CCUJOEcjs.logSourceLabels.call(void 0, selected.device).deviceName }
2005
2005
  ],
2006
2006
  deviceCard: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2007
- _chunk3KGICRH7cjs.DeviceCard,
2007
+ _chunk36CCUJOEcjs.DeviceCard,
2008
2008
  {
2009
2009
  ...LOGS_FIXTURE_DEVICE,
2010
2010
  actions: {
@@ -10,21 +10,21 @@ var _chunkKHXZFLINcjs = require('./chunk-KHXZFLIN.cjs');
10
10
 
11
11
 
12
12
 
13
- var _chunk3KGICRH7cjs = require('./chunk-3KGICRH7.cjs');
13
+ var _chunk36CCUJOEcjs = require('./chunk-36CCUJOE.cjs');
14
14
  require('./chunk-ZJNYWNCB.cjs');
15
15
  require('./chunk-3HPB4H4C.cjs');
16
16
  require('./chunk-L4ZNR5V7.cjs');
17
17
  require('./chunk-HQQE74RO.cjs');
18
18
  require('./chunk-DEY6XXGO.cjs');
19
- require('./chunk-BP6R5WDW.cjs');
19
+ require('./chunk-VA7OMDZO.cjs');
20
20
  require('./chunk-AAFW4STC.cjs');
21
21
  require('./chunk-24I6RFVU.cjs');
22
22
  require('./chunk-A6P6DHEZ.cjs');
23
23
  require('./chunk-MZ4KBSH7.cjs');
24
24
  require('./chunk-OXJ57643.cjs');
25
25
  require('./chunk-YUMFVQIN.cjs');
26
- require('./chunk-3UTPZW36.cjs');
27
- require('./chunk-YIXKH2JO.cjs');
26
+ require('./chunk-F7STMHT7.cjs');
27
+ require('./chunk-JDXQ6T5P.cjs');
28
28
  require('./chunk-ZRYKDN2J.cjs');
29
29
  require('./chunk-HZJRERJW.cjs');
30
30
  require('./chunk-DUXLZPMJ.cjs');
@@ -1825,8 +1825,8 @@ require('./chunk-7DNL734S.cjs');
1825
1825
  require('./chunk-WWUSFOJ7.cjs');
1826
1826
  require('./chunk-SKI6NKOE.cjs');
1827
1827
  require('./chunk-EWPR7662.cjs');
1828
- require('./chunk-J7JKPTGO.cjs');
1829
- require('./chunk-P3R23TOE.cjs');
1828
+ require('./chunk-SHQZN5LF.cjs');
1829
+ require('./chunk-RH3AKULV.cjs');
1830
1830
  require('./chunk-FCGLSWKR.cjs');
1831
1831
  require('./chunk-YADG5Q7C.cjs');
1832
1832
  require('./chunk-MYBTNOS6.cjs');
@@ -1891,14 +1891,14 @@ var POLICIES = [
1891
1891
  policy("policy-local-admins", "No local admins", "No everyday account is a local administrator.", false, 0)
1892
1892
  ];
1893
1893
  var POLICIES_FIXTURE = {
1894
- summary: _chunk3KGICRH7cjs.computePolicySummary.call(void 0, POLICIES),
1894
+ summary: _chunk36CCUJOEcjs.computePolicySummary.call(void 0, POLICIES),
1895
1895
  rows: POLICIES.map((item) => ({
1896
1896
  id: item.id,
1897
1897
  name: item.name,
1898
1898
  description: item.description,
1899
1899
  critical: item.critical,
1900
1900
  severityLabel: item.critical ? "Critical" : "Low",
1901
- status: _chunk3KGICRH7cjs.getPolicyTableStatus.call(void 0, item),
1901
+ status: _chunk36CCUJOEcjs.getPolicyTableStatus.call(void 0, item),
1902
1902
  actions: [
1903
1903
  { label: "Policy Details", onClick: noop },
1904
1904
  { label: "Delete Policy", onClick: noop }
@@ -1912,16 +1912,16 @@ var POLICIES_FIXTURE = {
1912
1912
  var _jsxruntime = require('react/jsx-runtime');
1913
1913
  function PoliciesScreen({ compact = false }) {
1914
1914
  const table = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1915
- _chunk3KGICRH7cjs.PoliciesTable,
1915
+ _chunk36CCUJOEcjs.PoliciesTable,
1916
1916
  {
1917
1917
  rows: POLICIES_FIXTURE.rows,
1918
1918
  rowAsLink: true,
1919
- rightSlot: compact ? void 0 : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3KGICRH7cjs.DataTable.RowCount, {}),
1919
+ rightSlot: compact ? void 0 : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.DataTable.RowCount, {}),
1920
1920
  emptyMessage: "No policies found."
1921
1921
  }
1922
1922
  );
1923
1923
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col gap-[var(--spacing-system-l)] bg-ods-bg p-[var(--spacing-system-l)]", children: [
1924
- !compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3KGICRH7cjs.PolicySummaryCards, { summary: POLICIES_FIXTURE.summary, now: POLICIES_FIXTURE.now }),
1924
+ !compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.PolicySummaryCards, { summary: POLICIES_FIXTURE.summary, now: POLICIES_FIXTURE.now }),
1925
1925
  table
1926
1926
  ] });
1927
1927
  }
@@ -15,7 +15,7 @@ var _chunkKHXZFLINcjs = require('./chunk-KHXZFLIN.cjs');
15
15
 
16
16
 
17
17
 
18
- var _chunk3KGICRH7cjs = require('./chunk-3KGICRH7.cjs');
18
+ var _chunk36CCUJOEcjs = require('./chunk-36CCUJOE.cjs');
19
19
  require('./chunk-ZJNYWNCB.cjs');
20
20
  require('./chunk-3HPB4H4C.cjs');
21
21
 
@@ -23,15 +23,15 @@ require('./chunk-3HPB4H4C.cjs');
23
23
  var _chunkL4ZNR5V7cjs = require('./chunk-L4ZNR5V7.cjs');
24
24
  require('./chunk-HQQE74RO.cjs');
25
25
  require('./chunk-DEY6XXGO.cjs');
26
- require('./chunk-BP6R5WDW.cjs');
26
+ require('./chunk-VA7OMDZO.cjs');
27
27
  require('./chunk-AAFW4STC.cjs');
28
28
  require('./chunk-24I6RFVU.cjs');
29
29
  require('./chunk-A6P6DHEZ.cjs');
30
30
  require('./chunk-MZ4KBSH7.cjs');
31
31
  require('./chunk-OXJ57643.cjs');
32
32
  require('./chunk-YUMFVQIN.cjs');
33
- require('./chunk-3UTPZW36.cjs');
34
- require('./chunk-YIXKH2JO.cjs');
33
+ require('./chunk-F7STMHT7.cjs');
34
+ require('./chunk-JDXQ6T5P.cjs');
35
35
  require('./chunk-ZRYKDN2J.cjs');
36
36
  require('./chunk-HZJRERJW.cjs');
37
37
  require('./chunk-DUXLZPMJ.cjs');
@@ -1832,8 +1832,8 @@ require('./chunk-7DNL734S.cjs');
1832
1832
  require('./chunk-WWUSFOJ7.cjs');
1833
1833
  require('./chunk-SKI6NKOE.cjs');
1834
1834
  require('./chunk-EWPR7662.cjs');
1835
- require('./chunk-J7JKPTGO.cjs');
1836
- require('./chunk-P3R23TOE.cjs');
1835
+ require('./chunk-SHQZN5LF.cjs');
1836
+ require('./chunk-RH3AKULV.cjs');
1837
1837
  require('./chunk-FCGLSWKR.cjs');
1838
1838
  require('./chunk-YADG5Q7C.cjs');
1839
1839
  require('./chunk-MYBTNOS6.cjs');
@@ -1926,12 +1926,12 @@ function StaticPackageField({ value }) {
1926
1926
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1927
1927
  _chunkL4ZNR5V7cjs.Autocomplete,
1928
1928
  {
1929
- label: _chunk3KGICRH7cjs.PACKAGE_SEARCH_LABEL,
1929
+ label: _chunk36CCUJOEcjs.PACKAGE_SEARCH_LABEL,
1930
1930
  labelVariant: "large",
1931
1931
  options: value ? [{ value: value.id, label: value.name, description: _nullishCoalesce(value.description, () => ( void 0)) }] : [],
1932
1932
  value: _nullishCoalesce(_optionalChain([value, 'optionalAccess', _ => _.id]), () => ( null)),
1933
1933
  onChange: noop,
1934
- placeholder: _chunk3KGICRH7cjs.PACKAGE_SEARCH_PLACEHOLDER
1934
+ placeholder: _chunk36CCUJOEcjs.PACKAGE_SEARCH_PLACEHOLDER
1935
1935
  }
1936
1936
  );
1937
1937
  }
@@ -1945,7 +1945,7 @@ function SoftwareUpdateScreen({ compact = false }) {
1945
1945
  [fixture.devices, fixture.selectedIds]
1946
1946
  );
1947
1947
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full bg-ods-bg pt-[var(--spacing-system-l)]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1948
- _chunk3KGICRH7cjs.SoftwareActionForm,
1948
+ _chunk36CCUJOEcjs.SoftwareActionForm,
1949
1949
  {
1950
1950
  action: fixture.action,
1951
1951
  showHeader: false,
@@ -1957,7 +1957,7 @@ function SoftwareUpdateScreen({ compact = false }) {
1957
1957
  initialValues: fixture.initialValues,
1958
1958
  renderPackageSearch,
1959
1959
  renderDevicePicker: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1960
- _chunk3KGICRH7cjs.DeviceSelector,
1960
+ _chunk36CCUJOEcjs.DeviceSelector,
1961
1961
  {
1962
1962
  devices: selected,
1963
1963
  loading: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flamingo-stack/openframe-frontend-core",
3
- "version": "0.0.733",
3
+ "version": "0.0.735",
4
4
  "description": "Shared design system and components for all Flamingo platforms",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -83,8 +83,8 @@ const EDITORIAL_META_ROW =
83
83
  const EDITORIAL_PERSON_ROW = 'flex h-8 min-w-0 items-center gap-[var(--spacing-system-s)]';
84
84
 
85
85
  // The default card's boxes, shared by the card and its skeleton: a large SQUARE cover
86
- // (the picture fills it), a display title, the date and meta row (stacked on a phone,
87
- // one line from md), a three-line description, a tag row, the gallery and the action,
86
+ // (the picture fills it), a two-line display title, the date and meta row (stacked up to
87
+ // lg, where the text column is wide enough for one line), a three-line description, a tag row, the gallery and the action,
88
88
  // so a card is one height whatever its copy and cover.
89
89
  const DEFAULT_BODY =
90
90
  'flex flex-col gap-[var(--spacing-system-lf)] p-[var(--spacing-system-lf)] md:p-[var(--spacing-system-xlf)]';
@@ -92,9 +92,9 @@ const DEFAULT_HEADER = 'flex flex-col gap-[var(--spacing-system-lf)] md:flex-row
92
92
  const DEFAULT_COVER_FRAME =
93
93
  'relative aspect-square w-full flex-shrink-0 overflow-hidden rounded-lg md:w-[240px] lg:w-[320px] xl:w-[400px]';
94
94
  const DEFAULT_TEXT = 'flex min-w-0 flex-1 flex-col gap-[var(--spacing-system-mf)]';
95
- const DEFAULT_TITLE = 'line-clamp-2 text-ods-text-primary text-h1';
95
+ const DEFAULT_TITLE = 'line-clamp-2 min-h-[2lh] text-ods-text-primary text-h1';
96
96
  const DEFAULT_META_ROW =
97
- 'flex min-h-[calc(2lh+0.5rem)] flex-col gap-2 text-h4 md:min-h-[1lh] md:flex-row md:items-center md:gap-4';
97
+ 'flex min-h-[calc(2lh+0.5rem)] flex-col gap-2 text-h4 lg:min-h-[1lh] lg:flex-row lg:items-center lg:gap-4';
98
98
  const DEFAULT_DESCRIPTION = 'line-clamp-3 min-h-[3lh] text-ods-text-secondary text-h4';
99
99
  const DEFAULT_TAG_ROW = 'flex flex-wrap gap-[var(--spacing-system-xsf)]';
100
100
  const DEFAULT_GALLERY_ROW = 'flex gap-[var(--spacing-system-mf)]';
@@ -177,7 +177,7 @@ export function ProgramCardSkeleton({
177
177
  <div className={`${DEFAULT_COVER_FRAME} bg-ods-border`} />
178
178
  <div className={DEFAULT_TEXT}>
179
179
  <div className={DEFAULT_TITLE}>
180
- <span className="block h-[1lh] w-3/4 rounded bg-ods-border" />
180
+ <span className="block h-[2lh] w-3/4 rounded bg-ods-border" />
181
181
  </div>
182
182
  <div className={DEFAULT_META_ROW}>
183
183
  <span className="block h-[1lh] w-32 rounded bg-ods-border" />
@@ -202,7 +202,8 @@ export function ProgramCardSkeleton({
202
202
  </div>
203
203
  )}
204
204
  <div className={DEFAULT_FOOTER}>
205
- <div className="h-10 w-40 rounded bg-ods-border" />
205
+ {/* The action button's own height (44px, 48px from md). */}
206
+ <div className="h-11 w-40 rounded bg-ods-border md:h-12" />
206
207
  </div>
207
208
  </div>
208
209
  );
@@ -632,13 +633,13 @@ export function ProgramCard<T extends BaseProgramItem>({
632
633
  <span style={{ color: accentColor }}>{dateLabel}</span>
633
634
  {renderMeta ? (
634
635
  <>
635
- <span className="hidden text-ods-text-secondary md:inline">•</span>
636
+ <span className="hidden text-ods-text-secondary lg:inline">•</span>
636
637
  {renderMeta(item)}
637
638
  </>
638
639
  ) : (
639
640
  defaultRenderMeta() && (
640
641
  <>
641
- <span className="hidden text-ods-text-secondary md:inline">•</span>
642
+ <span className="hidden text-ods-text-secondary lg:inline">•</span>
642
643
  <div className="flex items-center gap-2">{defaultRenderMeta()}</div>
643
644
  </>
644
645
  )
@@ -259,8 +259,17 @@ function ManagedCell({
259
259
  const cloneRef = useSuppressCloneFocus(ctx.isClone);
260
260
  return (
261
261
  <div
262
- className="shrink-0 self-stretch"
263
- style={{ width: ctx.isMobile ? cardWidthMobile : desktopWidth, maxWidth: STRIP_CELL_MAX_WIDTH }}
262
+ // The width is CSS's (the engine's own 767px line), never a script's: the
263
+ // first paint is the cell's final width, so a phone's strip never resizes
264
+ // when the page hydrates.
265
+ className="w-[var(--strip-cell-mobile)] shrink-0 self-stretch min-[768px]:w-[var(--strip-cell-desktop)]"
266
+ style={
267
+ {
268
+ '--strip-cell-mobile': `${cardWidthMobile}px`,
269
+ '--strip-cell-desktop': `${desktopWidth}px`,
270
+ maxWidth: STRIP_CELL_MAX_WIDTH,
271
+ } as React.CSSProperties
272
+ }
264
273
  data-strip-card-key={ctx.cardKey}
265
274
  onPointerEnter={ctx.isTouch ? undefined : () => ctx.onActivate(ctx.cardKey)}
266
275
  onPointerLeave={ctx.isTouch ? undefined : () => ctx.onDeactivate(ctx.cardKey)}
@@ -147,7 +147,8 @@ export function VideoBitesStrip({
147
147
  cardKey={ctx.cardKey}
148
148
  isClone={ctx.isClone}
149
149
  isTouch={ctx.isTouch}
150
- height={ctx.isMobile ? cardHeightMobile : cardHeightDesktop}
150
+ height={cardHeightDesktop}
151
+ heightMobile={cardHeightMobile}
151
152
  active={ctx.active}
152
153
  onActivate={ctx.onActivate}
153
154
  onDeactivate={ctx.onDeactivate}
@@ -178,6 +179,11 @@ export interface VideoBiteCardProps {
178
179
  /** Fixed card height (strip). Omit → width-driven: card fills its grid
179
180
  * cell and the aspect-ratio derives the height (editor grids). */
180
181
  height?: number;
182
+ /** With `height`: the height under the strip's 768px line. The switch is CSS's,
183
+ * so the first paint is the card's final size on a phone too. OPTIONAL and
184
+ * additive: omitted, `height` applies at every width, exactly as before this
185
+ * prop existed (a caller that resolves the height itself keeps working). */
186
+ heightMobile?: number;
181
187
  /** Controlled hover-activation (strip). Omit → the card manages its own
182
188
  * hover/focus state. */
183
189
  active?: boolean;
@@ -211,6 +217,7 @@ export function VideoBiteCard({
211
217
  sectionHref,
212
218
  onBiteNavigate,
213
219
  height,
220
+ heightMobile,
214
221
  active,
215
222
  onActivate,
216
223
  onDeactivate,
@@ -356,10 +363,22 @@ export function VideoBiteCard({
356
363
 
357
364
  const media = (
358
365
  <div
359
- className="relative w-full"
366
+ className={cn(
367
+ 'relative w-full',
368
+ height !== undefined && 'h-[var(--bite-height-mobile)] min-[768px]:h-[var(--bite-height)]',
369
+ )}
360
370
  // Strip mode: fixed height + aspect drive the width (capped at 90vw,
361
371
  // same as the old single-box layout). Editor mode: width-driven.
362
- style={{ aspectRatio: cssAspect, ...(height !== undefined ? { height, maxWidth: STRIP_CELL_MAX_WIDTH } : {}) }}
372
+ style={{
373
+ aspectRatio: cssAspect,
374
+ ...(height !== undefined
375
+ ? {
376
+ '--bite-height': `${height}px`,
377
+ '--bite-height-mobile': `${heightMobile ?? height}px`,
378
+ maxWidth: STRIP_CELL_MAX_WIDTH,
379
+ }
380
+ : {}),
381
+ }}
363
382
  >
364
383
  {/* THE shared hover-preview media zone (poster → facade → badge →
365
384
  controlled hover playback + near-viewport mount gate). The bite strip
@@ -154,7 +154,15 @@ const SECTION_HEADING_LAYOUT = {
154
154
  } as const;
155
155
 
156
156
  export interface SectionHeadingProps {
157
- /** The small label above the heading (Azeret Mono, uppercase, accent colour). */
157
+ /**
158
+ * The small label above the heading (Azeret Mono, uppercase, accent colour).
159
+ * On a page heading (`level="page"`) it is part of the `<h1>`: a hero's
160
+ * eyebrow names what the page is about ("Endpoint management software") above
161
+ * its positioning line, so the page's heading, and its accessible name, say
162
+ * both. The element takes no box of its own, so the eyebrow and the title keep
163
+ * their two places in the stack. On a section heading it stays a label beside
164
+ * the `<h2>`, whose accessible name is its title alone.
165
+ */
158
166
  eyebrow?: ReactNode;
159
167
  /** The heading text; a node when part of it is highlighted. Every sentence mark in it is drawn in the accent colour. */
160
168
  title: ReactNode;
@@ -204,14 +212,36 @@ export function SectionHeading({
204
212
  const accentClassName = headingAccentClass(platform, tone);
205
213
  const layout = SECTION_HEADING_LAYOUT[level];
206
214
  const Tag = presentational ? 'div' : level === 'page' ? 'h1' : 'h2';
215
+ const eyebrowNode = eyebrow ? <span className={`text-h5 ${accentClassName}`}>{eyebrow}</span> : null;
216
+ const headingText = (
217
+ <>
218
+ {accentSentenceMarks(title, platform, tone)}
219
+ {punctuation ? <span className={accentClassName}>{punctuation}</span> : null}
220
+ </>
221
+ );
207
222
  const stack = (
208
223
  <div className={layout.stack}>
209
- {eyebrow ? <span className={`text-h5 ${accentClassName}`}>{eyebrow}</span> : null}
210
- <Tag className={layout.heading} data-section-heading>
211
- {accentSentenceMarks(title, platform, tone)}
212
- {punctuation ? <span className={accentClassName}>{punctuation}</span> : null}
213
- </Tag>
214
- {intro ? <div className={layout.intro}>{intro}</div> : null}
224
+ {eyebrowNode && level === 'page' ? (
225
+ // `contents`: the element names the heading and draws no box, so the stack lays its two children out as before.
226
+ <Tag className="contents">
227
+ {eyebrowNode}
228
+ <span className={`block ${layout.heading}`} data-section-heading>
229
+ {headingText}
230
+ </span>
231
+ </Tag>
232
+ ) : (
233
+ <>
234
+ {eyebrowNode}
235
+ <Tag className={layout.heading} data-section-heading>
236
+ {headingText}
237
+ </Tag>
238
+ </>
239
+ )}
240
+ {intro ? (
241
+ <div className={layout.intro} data-section-intro>
242
+ {intro}
243
+ </div>
244
+ ) : null}
215
245
  </div>
216
246
  );
217
247
  if (!action) return className ? <div className={className}>{stack}</div> : stack;
@@ -56,7 +56,9 @@ export interface FadePreviewProps {
56
56
  * MEASURED to the bottom of item N (at every width). Implies `fixedHeight`, so
57
57
  * the block keeps that height loading or loaded, and "Show N more" counts the
58
58
  * items past N unless `hiddenCount` says otherwise. Until the list holds N
59
- * items, `collapsedHeight` (or the height last measured) is kept.
59
+ * items, `collapsedHeight` (or the height last measured) is kept. The first
60
+ * paint (before any measure) is held for N up to 12; add rows to
61
+ * `UNMEASURED_ITEMS_CLASSES` for a longer preview.
60
62
  */
61
63
  visibleItems?: number;
62
64
  /**
@@ -80,6 +82,32 @@ const FILL_CLASSES: Record<string, string> = {
80
82
  lg: 'lg:absolute lg:inset-0',
81
83
  };
82
84
 
85
+ /**
86
+ * Item mode before the first measure (the server's markup, and the page until it
87
+ * hydrates): the items past the first N are hidden by CSS, so the block is its
88
+ * collapsed height in the very first paint. Without it the whole list showed and
89
+ * the measure then cut it, which moved everything under it. Spelled out per N
90
+ * (Tailwind only emits classes it can read, and a `<style>` element is not
91
+ * allowed here: each rewrite relayouts the document), so it covers N up to
92
+ * `FADE_PREVIEW_MAX_UNMEASURED_ITEMS`; a larger N is clipped at the measure, as before.
93
+ */
94
+ const UNMEASURED_ITEMS_CLASSES: Record<number, string> = {
95
+ 1: '[&>*>*:nth-child(n+2)]:hidden',
96
+ 2: '[&>*>*:nth-child(n+3)]:hidden',
97
+ 3: '[&>*>*:nth-child(n+4)]:hidden',
98
+ 4: '[&>*>*:nth-child(n+5)]:hidden',
99
+ 5: '[&>*>*:nth-child(n+6)]:hidden',
100
+ 6: '[&>*>*:nth-child(n+7)]:hidden',
101
+ 7: '[&>*>*:nth-child(n+8)]:hidden',
102
+ 8: '[&>*>*:nth-child(n+9)]:hidden',
103
+ 9: '[&>*>*:nth-child(n+10)]:hidden',
104
+ 10: '[&>*>*:nth-child(n+11)]:hidden',
105
+ 11: '[&>*>*:nth-child(n+12)]:hidden',
106
+ 12: '[&>*>*:nth-child(n+13)]:hidden',
107
+ };
108
+ /** The largest `visibleItems` the first paint is held for (the table above). */
109
+ export const FADE_PREVIEW_MAX_UNMEASURED_ITEMS = 12;
110
+
83
111
  const cssLength = (value: number | string) => (typeof value === 'number' ? `${value}px` : value);
84
112
 
85
113
  export function FadePreview({
@@ -198,6 +226,7 @@ export function FadePreview({
198
226
  className={cn(
199
227
  'overflow-hidden transition-[max-height,height] duration-500',
200
228
  fill && FILL_CLASSES[String(fill)],
229
+ itemMode && itemsHeight == null && !expanded && UNMEASURED_ITEMS_CLASSES[visible],
201
230
  )}
202
231
  style={{
203
232
  transitionTimingFunction: 'cubic-bezier(0.33, 1, 0.68, 1)',
@@ -64,6 +64,7 @@ export * from './alert';
64
64
  export * from './badge';
65
65
  export * from './ai-generated-badge';
66
66
  export * from './fade-preview';
67
+ export * from './layout-hold';
67
68
  export * from './progress';
68
69
  export * from './release-changelog-section';
69
70
  export * from './stacked-rows-panel';
@@ -0,0 +1,55 @@
1
+ import type { ReactNode } from 'react';
2
+ import { cn } from '../../utils/cn';
3
+
4
+ /**
5
+ * Holding a layout while its content is read, the two ways that are right at
6
+ * EVERY width. A placeholder of a guessed size (a `w-40` bar, a `h-[120px]`
7
+ * box) is only right at the widths it was tuned at: text wraps where the words
8
+ * make it wrap, so the placeholder has to be made of the words, or of the real
9
+ * layout, to wrap where the content will.
10
+ *
11
+ * - `TextHold`: an inline stand-in exactly as wide as the words it is given
12
+ * (same font, same letter spacing, because it IS those words, not shown).
13
+ * `bar` draws it as a pulsing grey bar; `blank` only keeps its space.
14
+ * - `LayoutHold`: a block as tall as the real layout rendered inside it, kept
15
+ * invisible and inert: the layout's own height, at any width.
16
+ *
17
+ * Neither is shown or read out; both are removed for assistive technology.
18
+ */
19
+ export interface TextHoldProps {
20
+ /** The words whose width is held (the content's own, or a stand-in of its length). */
21
+ children: ReactNode;
22
+ /** `bar`: a pulsing grey bar of that width. `blank`: the width only. */
23
+ variant?: 'bar' | 'blank';
24
+ className?: string;
25
+ }
26
+
27
+ export function TextHold({ children, variant = 'bar', className }: TextHoldProps) {
28
+ return (
29
+ <span
30
+ aria-hidden
31
+ className={cn(
32
+ variant === 'bar' ? 'animate-pulse rounded bg-ods-border text-transparent' : 'invisible',
33
+ // A hold is never selectable or clickable, whatever it wraps.
34
+ 'pointer-events-none select-none',
35
+ className,
36
+ )}
37
+ >
38
+ {children}
39
+ </span>
40
+ );
41
+ }
42
+
43
+ export interface LayoutHoldProps {
44
+ /** The real layout, rendered with the data at hand. */
45
+ children: ReactNode;
46
+ className?: string;
47
+ }
48
+
49
+ export function LayoutHold({ children, className }: LayoutHoldProps) {
50
+ return (
51
+ <div aria-hidden inert className={cn('invisible', className)}>
52
+ {children}
53
+ </div>
54
+ );
55
+ }