@flamingo-stack/openframe-frontend-core 0.0.705 → 0.0.706-snapshot.20261006190707

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 (206) hide show
  1. package/dist/{chunk-4KX6OED2.cjs → chunk-2G7UYK35.cjs} +46 -46
  2. package/dist/{chunk-KOWVJD4V.cjs → chunk-2KXTOP6G.cjs} +70 -57
  3. package/dist/{chunk-A75QY6CD.cjs → chunk-2RNB5DTN.cjs} +21 -21
  4. package/dist/{chunk-PN2RKPDF.js → chunk-36BCTE7D.js} +10 -10
  5. package/dist/{chunk-ZSAGLQOD.cjs → chunk-3AHTOSXJ.cjs} +17 -17
  6. package/dist/{chunk-VR2ZLFCP.js → chunk-4IBPRIQH.js} +1 -1
  7. package/dist/{chunk-FCGC42TS.js → chunk-4L6XCMOU.js} +66 -62
  8. package/dist/{chunk-X5MQ7JRP.js → chunk-4UM2ETLM.js} +9 -9
  9. package/dist/{chunk-6NJKKO73.cjs → chunk-6I4ZAFO2.cjs} +15 -15
  10. package/dist/{chunk-RBDP4WDE.js → chunk-6IW7TWPV.js} +6 -6
  11. package/dist/{chunk-MMOODW57.cjs → chunk-6NTPY5QA.cjs} +1887 -94
  12. package/dist/{chunk-QFXRPRFT.js → chunk-6YKAT7NV.js} +3 -3
  13. package/dist/{chunk-HPWWNJE7.cjs → chunk-AOWDNSTM.cjs} +89 -89
  14. package/dist/{chunk-IHERL5V4.cjs → chunk-B73373AG.cjs} +34 -34
  15. package/dist/{chunk-DENB2XJC.js → chunk-CNWOMQQJ.js} +2 -2
  16. package/dist/{chunk-MP2C3LJ4.js → chunk-CUME3VTQ.js} +1 -1
  17. package/dist/{chunk-PDWVPI3S.js → chunk-CZ7Y7UG4.js} +4 -72
  18. package/dist/{chunk-YHM5AWTT.js → chunk-CZSZSDD4.js} +6 -6
  19. package/dist/{chunk-F6I6XZMN.js → chunk-DA5UDTLG.js} +5 -5
  20. package/dist/{chunk-MFFCUVWG.js → chunk-F57ECE2I.js} +1 -1
  21. package/dist/{chunk-CH5232HV.js → chunk-FI6GMDO7.js} +2455 -662
  22. package/dist/{chunk-NDESEPW5.js → chunk-FXJ3WWUB.js} +68 -0
  23. package/dist/{chunk-G5A3PSPV.js → chunk-HDOYSEOJ.js} +1080 -691
  24. package/dist/{chunk-VA5T32XA.js → chunk-I3ST4PLM.js} +2 -2
  25. package/dist/{chunk-5HBHO5TB.js → chunk-JPG7OHEG.js} +1 -1
  26. package/dist/{chunk-YFBM2K6X.cjs → chunk-JRU2CXLB.cjs} +4 -4
  27. package/dist/{chunk-MKXO4Q5P.js → chunk-KUC673HM.js} +383 -142
  28. package/dist/{chunk-JEZKGCZI.cjs → chunk-L6Y6OOKG.cjs} +26 -26
  29. package/dist/{chunk-F6AFPNDF.js → chunk-LFFB6EMB.js} +29 -16
  30. package/dist/{chunk-X72J4ACL.cjs → chunk-LLSUVPQC.cjs} +252 -8
  31. package/dist/{chunk-RKV5B7EU.cjs → chunk-LM7TXMLU.cjs} +72 -4
  32. package/dist/{chunk-6SEANMOU.js → chunk-LNW45N2C.js} +11 -11
  33. package/dist/{chunk-OUY3HHW6.cjs → chunk-LRQTJOF2.cjs} +928 -539
  34. package/dist/{chunk-DW7G4KG3.js → chunk-MR3A4MZV.js} +3 -3
  35. package/dist/{chunk-2YXVWZVF.js → chunk-N45D4ZXQ.js} +959 -715
  36. package/dist/{chunk-Z2VNQQ74.js → chunk-NCPTID44.js} +978 -942
  37. package/dist/{chunk-WA6GUYQ4.cjs → chunk-NSGXARGJ.cjs} +104 -104
  38. package/dist/{chunk-ABU3TGXA.cjs → chunk-OF6GEI5A.cjs} +3 -3
  39. package/dist/{chunk-IKTQ3ZAG.cjs → chunk-OJLR5MEO.cjs} +6 -6
  40. package/dist/{chunk-VESKITRQ.cjs → chunk-P42V6N34.cjs} +736 -732
  41. package/dist/{chunk-OHFS7VOU.cjs → chunk-PLYEKV3N.cjs} +2 -2
  42. package/dist/{chunk-7VVFKJY5.js → chunk-PO33GZVY.js} +1799 -3449
  43. package/dist/{chunk-7LS22BZU.cjs → chunk-QAOFMK2A.cjs} +14 -14
  44. package/dist/{chunk-VHCACDKP.cjs → chunk-RQRX4YC3.cjs} +39 -39
  45. package/dist/{chunk-3MX5S4CF.cjs → chunk-SEXWHIMS.cjs} +899 -2549
  46. package/dist/{chunk-AQWZNP6A.js → chunk-SS5MBHDP.js} +4 -4
  47. package/dist/{chunk-ZSAO2HBW.js → chunk-TDYIREDJ.js} +15 -15
  48. package/dist/{chunk-XOYH2YQE.cjs → chunk-UDFRUKLC.cjs} +2 -2
  49. package/dist/{chunk-TYWLNCNH.cjs → chunk-UVTD52MD.cjs} +14 -82
  50. package/dist/{chunk-N3COXDBH.cjs → chunk-VX4E6YSB.cjs} +41 -5
  51. package/dist/{chunk-2QEUFXNS.cjs → chunk-WCVZCGK5.cjs} +312 -71
  52. package/dist/{chunk-6XIF2Z7I.js → chunk-WMX26HB5.js} +3 -3
  53. package/dist/{chunk-D7BTSVMS.cjs → chunk-Y2GSOUCS.cjs} +2 -2
  54. package/dist/{chunk-4I45Y3DN.cjs → chunk-YBUT4AMG.cjs} +6 -6
  55. package/dist/components/case-studies/index.cjs +30 -32
  56. package/dist/components/case-studies/index.js +14 -16
  57. package/dist/components/chat/entity-cards/case-study-card.d.ts +11 -4
  58. package/dist/components/chat/entity-cards/case-study-card.d.ts.map +1 -1
  59. package/dist/components/chat/index.cjs +11 -11
  60. package/dist/components/chat/index.d.ts +1 -1
  61. package/dist/components/chat/index.d.ts.map +1 -1
  62. package/dist/components/chat/index.js +16 -16
  63. package/dist/components/chat/nav-link-anchor-via-runtime.d.ts +34 -5
  64. package/dist/components/chat/nav-link-anchor-via-runtime.d.ts.map +1 -1
  65. package/dist/components/chat/utils/icon-library.d.ts.map +1 -1
  66. package/dist/components/contact/index.cjs +12 -14
  67. package/dist/components/contact/index.js +11 -13
  68. package/dist/components/docs/index.cjs +15 -17
  69. package/dist/components/docs/index.js +14 -16
  70. package/dist/components/embeds/index.cjs +12 -14
  71. package/dist/components/embeds/index.js +11 -13
  72. package/dist/components/faq/index.cjs +13 -15
  73. package/dist/components/faq/index.js +12 -14
  74. package/dist/components/features/index.cjs +12 -14
  75. package/dist/components/features/index.js +21 -23
  76. package/dist/components/help-center-pages/index.cjs +118 -120
  77. package/dist/components/help-center-pages/index.js +33 -35
  78. package/dist/components/icons/index.cjs +3 -5
  79. package/dist/components/icons/index.js +9 -11
  80. package/dist/components/icons-v2-generated/index.cjs +3 -5
  81. package/dist/components/icons-v2-generated/index.js +2 -4
  82. package/dist/components/index.cjs +87 -158
  83. package/dist/components/index.d.ts +0 -2
  84. package/dist/components/index.d.ts.map +1 -1
  85. package/dist/components/index.js +331 -402
  86. package/dist/components/loading/page-layout-skeleton.d.ts +1 -1
  87. package/dist/components/meeting-scheduler/index.cjs +62 -64
  88. package/dist/components/meeting-scheduler/index.js +12 -14
  89. package/dist/components/navigation/index.cjs +28 -16
  90. package/dist/components/navigation/index.d.ts +14 -10
  91. package/dist/components/navigation/index.d.ts.map +1 -1
  92. package/dist/components/navigation/index.js +38 -26
  93. package/dist/components/navigation/mingo-ai-button.d.ts +38 -3
  94. package/dist/components/navigation/mingo-ai-button.d.ts.map +1 -1
  95. package/dist/components/navigation/mobile-nav-sheet-id.d.ts +3 -0
  96. package/dist/components/navigation/mobile-nav-sheet-id.d.ts.map +1 -0
  97. package/dist/components/navigation/mobile-nav-sheet.d.ts +48 -0
  98. package/dist/components/navigation/mobile-nav-sheet.d.ts.map +1 -0
  99. package/dist/components/navigation/nav-item-row.d.ts +27 -0
  100. package/dist/components/navigation/nav-item-row.d.ts.map +1 -0
  101. package/dist/components/navigation/nav-panel.d.ts +43 -0
  102. package/dist/components/navigation/nav-panel.d.ts.map +1 -0
  103. package/dist/components/navigation/navigation-sidebar-item.d.ts +1 -2
  104. package/dist/components/navigation/navigation-sidebar-item.d.ts.map +1 -1
  105. package/dist/components/navigation/site-footer.d.ts +28 -0
  106. package/dist/components/navigation/site-footer.d.ts.map +1 -0
  107. package/dist/components/navigation/site-header.d.ts +61 -0
  108. package/dist/components/navigation/site-header.d.ts.map +1 -0
  109. package/dist/components/navigation/site-nav-link.d.ts +26 -0
  110. package/dist/components/navigation/site-nav-link.d.ts.map +1 -0
  111. package/dist/components/navigation/top-navigation.d.ts +2 -2
  112. package/dist/components/navigation/top-navigation.d.ts.map +1 -1
  113. package/dist/components/onboarding-guides/index.cjs +15 -17
  114. package/dist/components/onboarding-guides/index.js +14 -16
  115. package/dist/components/platform/ToolBadge.d.ts +6 -0
  116. package/dist/components/platform/ToolBadge.d.ts.map +1 -1
  117. package/dist/components/related-content/index.cjs +10 -8
  118. package/dist/components/related-content/index.js +9 -7
  119. package/dist/components/tickets/index.cjs +16 -18
  120. package/dist/components/tickets/index.js +15 -17
  121. package/dist/components/ui/brand-association-card.d.ts +7 -0
  122. package/dist/components/ui/brand-association-card.d.ts.map +1 -1
  123. package/dist/components/ui/index.cjs +14 -14
  124. package/dist/components/ui/index.js +19 -19
  125. package/dist/hooks/index.cjs +19 -11
  126. package/dist/hooks/index.d.ts +1 -0
  127. package/dist/hooks/index.d.ts.map +1 -1
  128. package/dist/hooks/index.js +19 -11
  129. package/dist/hooks/ui/index.d.ts +3 -0
  130. package/dist/hooks/ui/index.d.ts.map +1 -1
  131. package/dist/hooks/ui/use-active-section.d.ts +10 -0
  132. package/dist/hooks/ui/use-active-section.d.ts.map +1 -0
  133. package/dist/hooks/ui/use-nav-menus.d.ts +48 -0
  134. package/dist/hooks/ui/use-nav-menus.d.ts.map +1 -0
  135. package/dist/hooks/ui/use-visitor-os.d.ts +15 -0
  136. package/dist/hooks/ui/use-visitor-os.d.ts.map +1 -0
  137. package/dist/hooks/use-location-hash.d.ts +9 -0
  138. package/dist/hooks/use-location-hash.d.ts.map +1 -0
  139. package/dist/index.cjs +56 -21
  140. package/dist/index.js +231 -196
  141. package/dist/types/case-study.d.ts +9 -0
  142. package/dist/types/case-study.d.ts.map +1 -1
  143. package/dist/types/navigation.d.ts +95 -65
  144. package/dist/types/navigation.d.ts.map +1 -1
  145. package/dist/utils/index.cjs +55 -0
  146. package/dist/utils/index.d.ts +1 -0
  147. package/dist/utils/index.d.ts.map +1 -1
  148. package/dist/utils/index.js +50 -1
  149. package/dist/utils/source-icons.d.ts.map +1 -1
  150. package/dist/utils/visitor-os.d.ts +45 -0
  151. package/dist/utils/visitor-os.d.ts.map +1 -0
  152. package/package.json +1 -1
  153. package/src/components/chat/entity-cards/case-study-card.tsx +115 -5
  154. package/src/components/chat/index.ts +7 -1
  155. package/src/components/chat/nav-link-anchor-via-runtime.tsx +62 -9
  156. package/src/components/chat/utils/icon-library.tsx +35 -1
  157. package/src/components/index.ts +0 -2
  158. package/src/components/loading/page-layout-skeleton.tsx +1 -1
  159. package/src/components/navigation/index.ts +21 -14
  160. package/src/components/navigation/mingo-ai-button.tsx +139 -63
  161. package/src/components/navigation/mobile-nav-sheet-id.ts +2 -0
  162. package/src/components/navigation/mobile-nav-sheet.tsx +241 -0
  163. package/src/components/navigation/nav-item-row.tsx +129 -0
  164. package/src/components/navigation/nav-panel.tsx +196 -0
  165. package/src/components/navigation/navigation-sidebar-item.tsx +1 -2
  166. package/src/components/navigation/site-footer.tsx +256 -0
  167. package/src/components/navigation/site-header.tsx +339 -0
  168. package/src/components/navigation/site-nav-link.tsx +41 -0
  169. package/src/components/navigation/ticket-alerts-button.tsx +2 -2
  170. package/src/components/navigation/top-navigation.tsx +2 -2
  171. package/src/components/platform/ToolBadge.tsx +18 -1
  172. package/src/components/ui/brand-association-card.tsx +25 -3
  173. package/src/hooks/index.ts +1 -0
  174. package/src/hooks/ui/index.ts +3 -0
  175. package/src/hooks/ui/use-active-section.ts +44 -0
  176. package/src/hooks/ui/use-nav-menus.ts +200 -0
  177. package/src/hooks/ui/use-visitor-os.ts +33 -0
  178. package/src/hooks/use-location-hash.ts +34 -0
  179. package/src/styles/chat-animations.css +57 -2
  180. package/src/types/case-study.ts +16 -0
  181. package/src/types/navigation.ts +80 -66
  182. package/src/utils/index.ts +1 -0
  183. package/src/utils/source-icons.ts +13 -0
  184. package/src/utils/visitor-os.ts +84 -0
  185. package/dist/chunk-LMBC5FFP.js +0 -43
  186. package/dist/chunk-O43V3EOS.js +0 -252
  187. package/dist/chunk-QZVSJF2K.cjs +0 -252
  188. package/dist/chunk-RALRPFDW.cjs +0 -43
  189. package/dist/components/footer-waitlist-button.d.ts +0 -29
  190. package/dist/components/footer-waitlist-button.d.ts.map +0 -1
  191. package/dist/components/footer.d.ts +0 -47
  192. package/dist/components/footer.d.ts.map +0 -1
  193. package/dist/components/navigation/client-only-header.d.ts +0 -8
  194. package/dist/components/navigation/client-only-header.d.ts.map +0 -1
  195. package/dist/components/navigation/header-skeleton.d.ts +0 -12
  196. package/dist/components/navigation/header-skeleton.d.ts.map +0 -1
  197. package/dist/components/navigation/header.d.ts +0 -9
  198. package/dist/components/navigation/header.d.ts.map +0 -1
  199. package/dist/components/navigation/mobile-nav-panel.d.ts +0 -10
  200. package/dist/components/navigation/mobile-nav-panel.d.ts.map +0 -1
  201. package/src/components/footer-waitlist-button.tsx +0 -53
  202. package/src/components/footer.tsx +0 -195
  203. package/src/components/navigation/client-only-header.tsx +0 -22
  204. package/src/components/navigation/header-skeleton.tsx +0 -74
  205. package/src/components/navigation/header.tsx +0 -429
  206. package/src/components/navigation/mobile-nav-panel.tsx +0 -155
@@ -1,38 +1,62 @@
1
1
  "use client";
2
2
  import {
3
3
  useOptionalTicketLive
4
- } from "./chunk-QFXRPRFT.js";
4
+ } from "./chunk-6YKAT7NV.js";
5
5
  import {
6
6
  AppLayoutDrawerContainerContext,
7
7
  AppLayoutDrawerCoordinationContext,
8
8
  HUBSPOT_DO_NOT_COLLECT_FORM_PROPS,
9
9
  HeaderButton,
10
10
  NotificationDrawer,
11
+ SocialIconRow,
11
12
  TimeTrackerHeaderButton,
12
13
  UnreadCountBadge,
13
14
  UnreadDot,
14
15
  buildTicketOpenHref,
15
16
  useOptionalNotifications
16
- } from "./chunk-FCGC42TS.js";
17
+ } from "./chunk-4L6XCMOU.js";
17
18
  import {
19
+ resolveActiveSection,
20
+ shortcutLabel,
21
+ useActiveSection,
18
22
  useFocusTrap,
19
- useLocalStorage
20
- } from "./chunk-MKXO4Q5P.js";
23
+ useLocalStorage,
24
+ useNavMenus,
25
+ useVisitorOs,
26
+ usesCommandKey
27
+ } from "./chunk-KUC673HM.js";
21
28
  import {
22
29
  OVERLAY_BACKDROP_CLASS,
23
30
  useIsHydrated
24
- } from "./chunk-7VVFKJY5.js";
31
+ } from "./chunk-PO33GZVY.js";
25
32
  import {
26
33
  useHeaderHeight
27
- } from "./chunk-PDWVPI3S.js";
34
+ } from "./chunk-CZ7Y7UG4.js";
35
+ import {
36
+ CaseStudyCard,
37
+ EntityIcon,
38
+ SquareAvatar,
39
+ Tag
40
+ } from "./chunk-FI6GMDO7.js";
41
+ import {
42
+ ContentAreaWidthContext,
43
+ breakpoints,
44
+ useIsomorphicLayoutEffect,
45
+ useLgUp,
46
+ useMdUp,
47
+ useMediaQuery
48
+ } from "./chunk-FXJ3WWUB.js";
28
49
  import {
29
50
  LogOutIcon,
30
51
  MingoIcon,
52
+ OpenFrameLogo,
31
53
  OpenFrameText,
32
54
  UserIcon
33
- } from "./chunk-2YXVWZVF.js";
55
+ } from "./chunk-N45D4ZXQ.js";
34
56
  import {
35
57
  BellIcon,
58
+ Chevron02DownIcon,
59
+ Chevron02RightIcon,
36
60
  Chevrons03LeftIcon,
37
61
  Filter02Icon,
38
62
  LifeBuoyIcon,
@@ -41,22 +65,7 @@ import {
41
65
  PenEditIcon,
42
66
  UserSearchIcon,
43
67
  XmarkIcon
44
- } from "./chunk-Z2VNQQ74.js";
45
- import {
46
- SquareAvatar,
47
- Tag
48
- } from "./chunk-CH5232HV.js";
49
- import {
50
- ContentAreaWidthContext,
51
- breakpoints,
52
- useIsomorphicLayoutEffect,
53
- useLgUp,
54
- useMdUp,
55
- useMediaQuery
56
- } from "./chunk-NDESEPW5.js";
57
- import {
58
- OpenFrameLogo
59
- } from "./chunk-O43V3EOS.js";
68
+ } from "./chunk-NCPTID44.js";
60
69
  import {
61
70
  DropdownMenu,
62
71
  DropdownMenuContent,
@@ -76,207 +85,331 @@ import {
76
85
  cn
77
86
  } from "./chunk-7RXWKTAP.js";
78
87
 
79
- // src/components/navigation/header.tsx
80
- import React, { useEffect, useRef as useRef2, useState } from "react";
88
+ // src/components/navigation/site-header.tsx
89
+ import { useEffect as useEffect2, useRef, useState } from "react";
81
90
 
82
91
  // src/components/navigation/mingo-ai-button.tsx
83
- import { jsx, jsxs } from "react/jsx-runtime";
92
+ import { useEffect } from "react";
93
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
84
94
  var MINGO_ACCENT = "var(--ods-flamingo-cyan-base)";
85
- function MingoAiButton({ source, icon, label = "Mingo AI", className, onClick, ...props }) {
86
- return /* @__PURE__ */ jsx(
87
- "button",
95
+ var ASK_AI_OPEN_EVENT = "ask-ai:open";
96
+ function openAskAi(source) {
97
+ window.dispatchEvent(new CustomEvent(ASK_AI_OPEN_EVENT, { detail: { source: source ?? "" } }));
98
+ }
99
+ function MingoAiButton({
100
+ source,
101
+ icon,
102
+ label = "Mingo AI",
103
+ shortcutHint = false,
104
+ variant = "inline",
105
+ className,
106
+ onClick,
107
+ ...props
108
+ }) {
109
+ const visitor = useVisitorOs();
110
+ const field = variant === "field";
111
+ const commandKey = visitor.known && usesCommandKey(visitor.os);
112
+ useEffect(() => {
113
+ if (!shortcutHint) return void 0;
114
+ const onKeyDown = (event) => {
115
+ if (event.defaultPrevented || event.altKey || event.shiftKey) return;
116
+ const modifier = commandKey ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
117
+ if (event.key.toLowerCase() !== "k" || !modifier) return;
118
+ event.preventDefault();
119
+ openAskAi(source);
120
+ };
121
+ window.addEventListener("keydown", onKeyDown);
122
+ return () => window.removeEventListener("keydown", onKeyDown);
123
+ }, [shortcutHint, source, commandKey]);
124
+ return /* @__PURE__ */ jsxs(
125
+ Button,
88
126
  {
89
127
  ...props,
90
128
  type: "button",
129
+ variant: field ? "glyph" : "transparent",
130
+ size: "wrap",
131
+ font: "regular",
91
132
  "aria-label": label,
133
+ "aria-keyshortcuts": shortcutHint && visitor.known ? commandKey ? "Meta+K" : "Control+K" : void 0,
92
134
  onClick: (e) => {
93
- window.dispatchEvent(new CustomEvent("ask-ai:open", { detail: { source: source ?? "" } }));
135
+ openAskAi(source);
94
136
  onClick?.(e);
95
137
  },
96
138
  className: cn(
97
- // Unified ODS top-navigation cell (Figma 2797-6808 desktop /
98
- // 2797-7275 mobile): full-height cell with a leading divider,
99
- // transparent at rest so it inherits the bar's background.
100
- // No hover background on the cell: the animated ring + shimmer are
101
- // the ONLY hover treatment (a bg flip on top read as a double
102
- // animation).
103
- "group/mingo relative flex h-full shrink-0 items-center border-l border-ods-border bg-transparent px-[var(--spacing-system-m)] focus:outline-none focus-visible:ring-2 focus-visible:ring-ods-accent",
139
+ "group/mingo flex shrink-0 justify-start focus-visible:ring-ods-accent",
140
+ field ? (
141
+ // A row of the mobile menu like the groups under it: same height,
142
+ // type and divider, no surface and no ring of its own.
143
+ "min-h-14 w-full gap-[var(--spacing-system-sf)] rounded-none border-b border-ods-border text-left text-h4 [&_svg]:h-6 [&_svg]:w-6"
144
+ ) : (
145
+ // Transparent at rest so it inherits the bar's background; the hover
146
+ // wash is the menu items' own.
147
+ "h-10 gap-[var(--spacing-system-xsf)] rounded-md pl-[var(--spacing-system-xsf)] pr-2.5 text-ods-text-secondary hover:text-ods-text-primary"
148
+ ),
104
149
  className
105
150
  ),
106
- children: /* @__PURE__ */ jsxs("span", { className: "relative flex h-11 items-center gap-[var(--spacing-system-xsf)] rounded-md px-[var(--spacing-system-m)] md:h-12", children: [
107
- /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "mingo-edge-frame pointer-events-none absolute inset-0 rounded-md", children: /* @__PURE__ */ jsx("span", { className: "mingo-edge" }) }),
108
- /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 overflow-hidden rounded-md", children: /* @__PURE__ */ jsx(
151
+ children: [
152
+ !field && /* @__PURE__ */ jsxs(Fragment, { children: [
153
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "mingo-edge-frame pointer-events-none absolute inset-0 rounded-md", children: /* @__PURE__ */ jsx("span", { className: "mingo-edge" }) }),
154
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 overflow-hidden rounded-md", children: /* @__PURE__ */ jsx(
155
+ "span",
156
+ {
157
+ className: "mingo-shimmer absolute inset-y-0 left-0 w-1/2",
158
+ style: {
159
+ background: "linear-gradient(105deg, transparent, color-mix(in srgb, var(--ods-system-greys-white) 12%, transparent), transparent)"
160
+ }
161
+ }
162
+ ) })
163
+ ] }),
164
+ icon ? /* @__PURE__ */ jsx(
109
165
  "span",
110
166
  {
111
- className: "mingo-shimmer absolute inset-y-0 left-0 w-1/2",
112
- style: {
113
- background: "linear-gradient(105deg, transparent, color-mix(in srgb, var(--ods-system-greys-white) 12%, transparent), transparent)"
114
- }
167
+ className: cn(
168
+ "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full",
169
+ field ? "size-6" : "size-5"
170
+ ),
171
+ children: icon
115
172
  }
116
- ) }),
117
- icon ? /* @__PURE__ */ jsx("span", { className: "relative inline-flex size-6 shrink-0 items-center justify-center", children: icon }) : /* @__PURE__ */ jsx(
173
+ ) : /* @__PURE__ */ jsx(
118
174
  MingoIcon,
119
175
  {
120
176
  color: "currentColor",
121
177
  eyesColor: MINGO_ACCENT,
122
178
  cornerColor: MINGO_ACCENT,
123
- className: "relative h-6 w-6 shrink-0 text-ods-text-primary"
179
+ className: cn("relative shrink-0 text-ods-text-primary", field ? "size-6" : "size-5")
124
180
  }
125
181
  ),
126
- /* @__PURE__ */ jsx("span", { className: "relative hidden whitespace-nowrap text-ods-text-primary text-h3 md:inline", children: label })
127
- ] })
182
+ /* @__PURE__ */ jsx(
183
+ "span",
184
+ {
185
+ className: cn("relative whitespace-nowrap", field ? "min-w-0 flex-1 truncate" : "hidden text-h6 lg:inline"),
186
+ children: label
187
+ }
188
+ ),
189
+ shortcutHint && !field && // A key cap in the label's own type (never smaller: a hint nobody can
190
+ // read is decoration) and the label's colour, which clears 4.5:1 on
191
+ // the bar. It keeps its width before the platform is known.
192
+ /* @__PURE__ */ jsx("kbd", { className: "relative hidden h-6 min-w-9 items-center justify-center rounded border border-ods-border px-[var(--spacing-system-xxs)] text-h6 lg:inline-flex", children: visitor.known ? shortcutLabel(visitor.os, "K") : "" })
193
+ ]
128
194
  }
129
195
  );
130
196
  }
131
197
 
132
- // src/components/navigation/mobile-nav-panel.tsx
133
- import { usePreventScroll } from "@react-aria/overlays";
134
- import { X } from "lucide-react";
135
- import { useRef } from "react";
136
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
137
- var MOBILE_NAV_PANEL_ID = "mobile-nav-panel";
138
- function MobileNavPanel({ isOpen, config }) {
139
- const panelRef = useRef(null);
140
- usePreventScroll({ isDisabled: !isOpen });
141
- useFocusTrap(panelRef, isOpen, { onEscape: config.onClose });
142
- const headerHeight = useHeaderHeight(64, { enabled: isOpen });
143
- if (!isOpen) return null;
144
- const renderNavigationItem = (item) => {
145
- if (item.element) {
146
- return /* @__PURE__ */ jsx2("div", { children: item.element }, item.id);
147
- }
148
- const handleClick = () => {
149
- if (item.onClick) {
150
- item.onClick();
151
- }
152
- config.onClose?.();
153
- };
154
- if (item.href) {
155
- return /* @__PURE__ */ jsx2(
156
- Button,
157
- {
158
- variant: "outline",
159
- size: "small-legacy",
160
- href: item.href,
161
- onClick: handleClick,
162
- leftIcon: item.icon,
163
- rightIcon: item.badge,
164
- className: cn(
165
- "h-12 justify-start gap-3 rounded-md border-none bg-transparent px-4 text-ods-text-primary transition-colors hover:bg-ods-bg-hover",
166
- item.isActive ? "bg-ods-bg-hover" : ""
167
- ),
168
- children: item.label
169
- },
170
- item.id
171
- );
172
- }
173
- return /* @__PURE__ */ jsxs2(
174
- Button,
198
+ // src/components/navigation/mobile-nav-sheet-id.ts
199
+ var MOBILE_NAV_SHEET_ID = "mobile-nav-sheet";
200
+
201
+ // src/components/navigation/nav-panel.tsx
202
+ import { forwardRef } from "react";
203
+
204
+ // src/components/navigation/site-nav-link.tsx
205
+ import { jsx as jsx2 } from "react/jsx-runtime";
206
+ var defaultRenderSiteNavLink = ({ link, children, ...rest }) => link.external ? /* @__PURE__ */ jsx2(next_link_default, { href: link.href, target: "_blank", rel: "noopener noreferrer", ...rest, children }) : /* @__PURE__ */ jsx2(next_link_default, { href: link.href, ...rest, children });
207
+ function navLinkLabel(link) {
208
+ return link.count === void 0 ? link.label : link.label.replace("{count}", String(link.count));
209
+ }
210
+ var NAV_FOCUS_CLASS = "outline-none focus-visible:ring-2 focus-visible:ring-ods-accent";
211
+
212
+ // src/components/navigation/nav-item-row.tsx
213
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
214
+ var ROW_CLASSES = {
215
+ panel: "flex items-start gap-[var(--spacing-system-sf)] rounded-lg p-[var(--spacing-system-sf)] text-ods-text-primary transition-colors hover:bg-ods-bg-hover",
216
+ sheet: "flex min-h-[52px] items-center gap-[var(--spacing-system-sf)] py-1.5 text-ods-text-primary",
217
+ side: "flex items-center gap-[var(--spacing-system-xsf)] rounded-md px-[var(--spacing-system-sf)] py-2.5 text-ods-text-secondary transition-colors text-h6 hover:bg-ods-bg-hover hover:text-ods-text-primary",
218
+ label: "inline-flex items-center gap-[var(--spacing-system-xsf)] text-ods-text-secondary transition-colors text-h6 hover:text-ods-text-primary"
219
+ };
220
+ function RowGlyph({ link, box, glyph }) {
221
+ if (link.icon) {
222
+ return /* @__PURE__ */ jsx3(
223
+ "span",
175
224
  {
176
- variant: "outline",
177
- size: "small-legacy",
178
- onClick: handleClick,
179
- leftIcon: item.icon,
180
- className: cn(
181
- "h-12 justify-start gap-3 rounded-md border-none bg-transparent px-4 text-ods-text-primary transition-colors hover:bg-ods-bg-hover",
182
- item.isActive ? "bg-ods-bg-hover" : ""
183
- ),
184
- children: [
185
- /* @__PURE__ */ jsx2("span", { className: "flex-1 text-left", children: item.label }),
186
- item.badge !== void 0 && /* @__PURE__ */ jsx2("span", { className: "ml-auto", children: item.badge })
187
- ]
188
- },
189
- item.id
225
+ "aria-hidden": "true",
226
+ className: cn("flex shrink-0 items-center justify-center overflow-hidden rounded-full", box),
227
+ children: /* @__PURE__ */ jsx3(EntityIcon, { icon: link.icon, className: "h-full w-full" })
228
+ }
190
229
  );
191
- };
192
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
193
- /* @__PURE__ */ jsx2("div", { className: cn("fixed inset-0 z-[9998]", OVERLAY_BACKDROP_CLASS), onClick: config.onClose }),
194
- /* @__PURE__ */ jsxs2(
230
+ }
231
+ if (!link.iconName) return null;
232
+ return /* @__PURE__ */ jsx3(
233
+ "span",
234
+ {
235
+ "aria-hidden": "true",
236
+ className: cn(
237
+ "flex shrink-0 items-center justify-center rounded-lg border border-ods-border bg-ods-bg text-ods-text-primary",
238
+ box
239
+ ),
240
+ children: /* @__PURE__ */ jsx3(EntityIcon, { icon: { name: link.iconName }, size: glyph })
241
+ }
242
+ );
243
+ }
244
+ function NavItemRow({
245
+ link,
246
+ variant = "panel",
247
+ renderLink = defaultRenderSiteNavLink,
248
+ badge,
249
+ onNavigate,
250
+ className
251
+ }) {
252
+ const label = navLinkLabel(link);
253
+ const counter = badge ? /* @__PURE__ */ jsx3(UnreadCountBadge, { count: badge, className: "static shrink-0" }) : null;
254
+ const singleLine = !link.description && !link.builtOn;
255
+ const rowClassName = cn(
256
+ ROW_CLASSES[variant],
257
+ variant === "panel" && singleLine && "items-center",
258
+ NAV_FOCUS_CLASS,
259
+ className
260
+ );
261
+ const onClick = onNavigate ? () => onNavigate() : void 0;
262
+ let children;
263
+ if (variant === "label") {
264
+ children = /* @__PURE__ */ jsxs2(Fragment2, { children: [
265
+ label,
266
+ counter
267
+ ] });
268
+ } else if (variant === "side") {
269
+ children = /* @__PURE__ */ jsxs2(Fragment2, { children: [
270
+ link.iconName && /* @__PURE__ */ jsx3("span", { "aria-hidden": "true", className: "flex shrink-0", children: /* @__PURE__ */ jsx3(EntityIcon, { icon: { name: link.iconName }, size: 18 }) }),
271
+ /* @__PURE__ */ jsx3("span", { className: "min-w-0 flex-1", children: label }),
272
+ counter
273
+ ] });
274
+ } else {
275
+ const sheet = variant === "sheet";
276
+ children = /* @__PURE__ */ jsxs2(Fragment2, { children: [
277
+ /* @__PURE__ */ jsx3(RowGlyph, { link, box: sheet ? "h-8 w-8" : "h-9 w-9", glyph: sheet ? 18 : 20 }),
278
+ /* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 flex-1 flex-col", children: [
279
+ /* @__PURE__ */ jsxs2("span", { className: "flex items-center gap-[var(--spacing-system-xsf)] text-h6", children: [
280
+ /* @__PURE__ */ jsx3("span", { className: "min-w-0", children: label }),
281
+ counter
282
+ ] }),
283
+ link.description && /* @__PURE__ */ jsx3("span", { className: "text-ods-text-muted text-h6", children: link.description }),
284
+ link.builtOn && /* @__PURE__ */ jsxs2("span", { className: "text-ods-text-muted text-h6", children: [
285
+ "Built on ",
286
+ link.builtOn
287
+ ] })
288
+ ] })
289
+ ] });
290
+ }
291
+ return /* @__PURE__ */ jsx3(Fragment2, { children: renderLink({ link, className: rowClassName, children, onClick }) });
292
+ }
293
+
294
+ // src/components/navigation/nav-panel.tsx
295
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
296
+ var TWO_COLUMN_OVER = 4;
297
+ function isMegaMenu(menu) {
298
+ return (menu.columns?.length ?? 0) > 1 || !!menu.features?.length || !!menu.sideLinks?.length;
299
+ }
300
+ var HEADING_CLASS = "mb-[var(--spacing-system-xsf)] ml-[var(--spacing-system-sf)] text-ods-text-muted text-h5";
301
+ function Column({
302
+ group,
303
+ wide,
304
+ rowProps
305
+ }) {
306
+ const twoColumns = wide && group.links.length > TWO_COLUMN_OVER;
307
+ return /* @__PURE__ */ jsxs3("div", { className: cn("flex min-w-0 flex-col", wide && (twoColumns ? "flex-[2]" : "flex-1")), children: [
308
+ group.title && /* @__PURE__ */ jsx4("div", { className: HEADING_CLASS, children: group.title }),
309
+ /* @__PURE__ */ jsx4(
195
310
  "div",
196
311
  {
197
- ref: panelRef,
198
- id: MOBILE_NAV_PANEL_ID,
199
- role: "dialog",
200
- "aria-modal": "true",
201
- "aria-label": "Navigation menu",
202
- tabIndex: -1,
203
- style: { "--mobile-nav-top": `${headerHeight + 16}px` },
204
- className: cn(
205
- "fixed z-[9999] rounded-lg shadow-xl",
206
- config.className ? "" : "border border-ods-border bg-ods-card",
207
- // Responsive positioning and sizing — LEFT-anchored from md, flush
208
- // under the burger cell at the left edge of the unified
209
- // top-navigation (a larger inset read as a stray gap between the
210
- // burger and its panel).
211
- "left-2 right-2 md:right-auto",
212
- "md:left-2 md:w-[400px] md:max-w-[calc(100vw-1rem)]",
213
- // Small-viewport (svh) sizing anchored below the measured header —
214
- // 100vh overflowed under mobile browser chrome, leaving the bottom
215
- // entries and footer unreachable while the body was scroll-locked.
216
- "top-[var(--mobile-nav-top)]",
217
- "max-h-[calc(100svh-var(--mobile-nav-top)-50px)] md:max-h-[calc(100svh-var(--mobile-nav-top)-8px)]",
218
- "flex flex-col",
219
- config.className || ""
220
- ),
221
- onClick: (e) => e.stopPropagation(),
222
- children: [
223
- /* @__PURE__ */ jsx2("div", { className: "flex flex-shrink-0 justify-end border-b border-ods-border p-2", children: /* @__PURE__ */ jsx2(
224
- Button,
225
- {
226
- "aria-label": "Close menu",
227
- size: "icon",
228
- variant: "transparent",
229
- leftIcon: /* @__PURE__ */ jsx2(X, { className: "h-4 w-4 text-ods-text-primary" }),
230
- onClick: config.onClose,
231
- className: "hover:bg-ods-bg-hover"
232
- }
233
- ) }),
234
- /* @__PURE__ */ jsx2("div", { className: "flex-1 overflow-y-auto overflow-x-hidden overscroll-contain px-2 py-2", children: /* @__PURE__ */ jsx2("div", { className: "flex flex-col space-y-1", children: config.sections.map((section, index) => /* @__PURE__ */ jsxs2("div", { children: [
235
- section.title && /* @__PURE__ */ jsx2("div", { className: "px-4 pb-1 pt-2 font-semibold uppercase text-ods-text-secondary text-h6", children: section.title }),
236
- /* @__PURE__ */ jsx2("div", { className: "flex flex-col gap-1", children: section.items.map(renderNavigationItem) })
237
- ] }, index)) }) }),
238
- config.footer && /* @__PURE__ */ jsx2("div", { className: "flex-shrink-0 border-t border-ods-border p-4 pb-[max(1rem,env(safe-area-inset-bottom))]", children: config.footer })
239
- ]
312
+ className: twoColumns ? "grid grid-cols-2 gap-x-[var(--spacing-system-mf)] gap-y-[var(--spacing-system-xxs)]" : "flex flex-col gap-[var(--spacing-system-xxs)]",
313
+ children: group.links.map((link) => /* @__PURE__ */ jsx4(
314
+ NavItemRow,
315
+ {
316
+ link,
317
+ renderLink: rowProps.renderLink,
318
+ onNavigate: rowProps.onNavigate,
319
+ badge: link.badgeKey ? rowProps.badges?.[link.badgeKey] : void 0
320
+ },
321
+ link.id
322
+ ))
240
323
  }
241
324
  )
242
325
  ] });
243
326
  }
244
-
245
- // src/components/navigation/ticket-alerts-button.tsx
246
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
247
- function TicketAlertsButton({ href, onNavigate, disabled, className }) {
248
- const live = useOptionalTicketLive();
249
- if (!live || !live.authed || live.unreadTotal === 0) return null;
250
- const targetId = live.nextUnreadTicketId;
251
- const target = targetId ? buildTicketOpenHref(href, targetId) : href;
252
- const handleClick = () => {
253
- if (onNavigate) onNavigate(target);
254
- else window.location.assign(target);
255
- };
256
- return /* @__PURE__ */ jsx3(
257
- HeaderButton,
327
+ var NavPanel = forwardRef(function NavPanelImpl({
328
+ menu,
329
+ open,
330
+ renderLink = defaultRenderSiteNavLink,
331
+ badges,
332
+ social,
333
+ onNavigate,
334
+ motion: motion2 = "open",
335
+ handoff = false,
336
+ className,
337
+ ...panelProps
338
+ }, ref) {
339
+ const columns = menu.columns ?? [];
340
+ const mega = isMegaMenu(menu);
341
+ const rowProps = { renderLink, badges, onNavigate };
342
+ const socialRow = menu.showSocial && social ? social : null;
343
+ return /* @__PURE__ */ jsx4(
344
+ "div",
258
345
  {
259
- icon: (
260
- // Glyph inherits HeaderButton's standard cell coloring (secondary at
261
- // rest, primary on active) — SAME treatment as the notifications
262
- // bell and time-tracker cells. The indication is carried by the
263
- // count pill (sidebar count-pill precedent) and by the cell only
264
- // existing while updates are unread — never by tinting the glyph.
265
- /* @__PURE__ */ jsxs3("span", { className: "relative inline-flex", children: [
266
- /* @__PURE__ */ jsx3(LifeBuoyIcon, { className: "h-6 w-6" }),
267
- /* @__PURE__ */ jsx3(UnreadCountBadge, { count: live.unreadTotal })
268
- ] })
346
+ inert: !open,
347
+ "data-state": open ? "open" : "closed",
348
+ ...panelProps,
349
+ ref,
350
+ className: cn(
351
+ "absolute top-full z-[60]",
352
+ // Between two mega menus the surface is handed over in one frame (same
353
+ // place, same size, same colour) and only the content moves; a fade
354
+ // here would let the page show through both for its whole length.
355
+ mega && (open ? motion2 !== "open" : handoff) ? "transition-none" : "transition-opacity duration-150",
356
+ mega ? "left-0 right-0 border-b border-ods-border bg-ods-card shadow-xl" : "left-0 mt-[var(--spacing-system-xxs)] min-w-[260px] rounded-lg border border-ods-border bg-ods-card p-[var(--spacing-system-xsf)] shadow-xl",
357
+ open ? "visible opacity-100" : "pointer-events-none invisible opacity-0",
358
+ className
269
359
  ),
270
- "aria-label": `Support tickets \u2014 ${live.unreadTotal} unread ${live.unreadTotal === 1 ? "update" : "updates"}`,
271
- onClick: handleClick,
272
- disabled,
273
- className: cn(className)
360
+ children: mega ? (
361
+ // ONE height for every mega menu, so moving between menus (and a
362
+ // card's cover loading) never resizes the panel under the pointer.
363
+ /* @__PURE__ */ jsxs3(
364
+ "div",
365
+ {
366
+ "data-motion": open ? motion2 : void 0,
367
+ className: "nav-panel-content flex h-[400px] max-h-[calc(100svh-var(--top-nav-height,72px))] flex-col gap-[var(--spacing-system-mf)] overflow-y-auto px-[var(--spacing-system-lf)] pb-[var(--spacing-system-xlf)] pt-8",
368
+ children: [
369
+ /* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 flex-1 gap-[var(--spacing-system-xlf)]", children: [
370
+ columns.map((group) => /* @__PURE__ */ jsx4(Column, { group, wide: true, rowProps }, group.id)),
371
+ !!menu.features?.length && // One row of cards, as many as the bar's width holds: a card that
372
+ // would wrap lands on a zero-height row, where its cell clips it.
373
+ /* @__PURE__ */ jsx4("div", { className: "grid min-w-0 flex-[3] auto-rows-[0px] grid-cols-[repeat(auto-fit,minmax(240px,1fr))] grid-rows-[minmax(0,1fr)] gap-x-[var(--spacing-system-mf)]", children: menu.features.map((feature) => /* @__PURE__ */ jsx4("div", { className: "min-h-0 min-w-0 overflow-hidden", children: /* @__PURE__ */ jsx4(
374
+ CaseStudyCard,
375
+ {
376
+ size: "menu",
377
+ study: feature.study,
378
+ href: feature.href,
379
+ mediaMounted: open,
380
+ onNavigate,
381
+ className: "h-full"
382
+ }
383
+ ) }, feature.id)) }),
384
+ !!menu.sideLinks?.length && /* @__PURE__ */ jsxs3("div", { className: "flex w-[260px] shrink-0 flex-col gap-0.5 border-l border-ods-border pl-8 pt-5", children: [
385
+ menu.sideTitle && /* @__PURE__ */ jsx4("div", { className: HEADING_CLASS, children: menu.sideTitle }),
386
+ menu.sideLinks.map((link) => /* @__PURE__ */ jsx4(
387
+ NavItemRow,
388
+ {
389
+ link,
390
+ variant: "side",
391
+ ...rowProps,
392
+ badge: link.badgeKey ? badges?.[link.badgeKey] : void 0
393
+ },
394
+ link.id
395
+ ))
396
+ ] })
397
+ ] }),
398
+ socialRow && /* @__PURE__ */ jsx4("div", { className: "border-t border-ods-border px-[var(--spacing-system-sf)] pt-[var(--spacing-system-mf)]", children: socialRow })
399
+ ]
400
+ }
401
+ )
402
+ ) : /* @__PURE__ */ jsxs3(Fragment3, { children: [
403
+ columns.map((group) => /* @__PURE__ */ jsx4(Column, { group, wide: false, rowProps }, group.id)),
404
+ socialRow && /* @__PURE__ */ jsx4("div", { className: "mt-[var(--spacing-system-xsf)] border-t border-ods-border px-[var(--spacing-system-sf)] pt-[var(--spacing-system-sf)]", children: socialRow })
405
+ ] })
274
406
  }
275
407
  );
276
- }
408
+ });
409
+ NavPanel.displayName = "NavPanel";
277
410
 
278
411
  // src/components/navigation/top-navigation.tsx
279
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
412
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
280
413
  var SIZE_CLASSES = {
281
414
  small: "h-14 [--top-nav-cell:3.5rem]",
282
415
  big: "h-[72px] [--top-nav-cell:4.5rem]"
@@ -320,7 +453,7 @@ function TopNavigation({
320
453
  ...props,
321
454
  children: [
322
455
  leading,
323
- hasContent(logo) && /* @__PURE__ */ jsx4(
456
+ hasContent(logo) && /* @__PURE__ */ jsx5(
324
457
  "div",
325
458
  {
326
459
  className: cn(
@@ -332,7 +465,7 @@ function TopNavigation({
332
465
  children: logo
333
466
  }
334
467
  ),
335
- /* @__PURE__ */ jsx4(
468
+ /* @__PURE__ */ jsx5(
336
469
  "div",
337
470
  {
338
471
  className: cn(
@@ -343,7 +476,7 @@ function TopNavigation({
343
476
  children: center
344
477
  }
345
478
  ),
346
- hasContent(cta) && /* @__PURE__ */ jsx4("div", { className: cn("flex h-full shrink-0 items-center px-[var(--spacing-system-m)]", ctaClassName), children: cta }),
479
+ hasContent(cta) && /* @__PURE__ */ jsx5("div", { className: cn("flex h-full shrink-0 items-center px-[var(--spacing-system-m)]", ctaClassName), children: cta }),
347
480
  sideActions,
348
481
  children
349
482
  ]
@@ -351,352 +484,568 @@ function TopNavigation({
351
484
  );
352
485
  }
353
486
 
354
- // src/components/navigation/header.tsx
355
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
356
- var NAV_ITEM_CLASSES = "text-h6 [&_svg]:h-6 [&_svg]:w-6";
357
- function Header({ config }) {
487
+ // src/components/navigation/site-header.tsx
488
+ import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
489
+ var TOP_ITEM_CLASS = "relative inline-flex h-10 items-center gap-1.5 whitespace-nowrap rounded-md px-3.5 text-ods-text-secondary transition-colors text-h6 hover:bg-ods-bg-hover hover:text-ods-text-primary";
490
+ var TOP_ITEM_CURRENT_CLASS = "rounded-b-none bg-gradient-to-b from-transparent to-ods-accent/10 text-ods-text-primary after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:bg-ods-accent";
491
+ var menuIcon = (menu) => menu.iconName ? /* @__PURE__ */ jsx6(EntityIcon, { icon: { name: menu.iconName }, size: 20, className: "size-5 shrink-0" }) : null;
492
+ function SiteHeader({
493
+ nav,
494
+ pathname,
495
+ logo,
496
+ logoHref,
497
+ renderLink = defaultRenderSiteNavLink,
498
+ leading,
499
+ actions,
500
+ cta,
501
+ sideActions,
502
+ mingo,
503
+ mobile,
504
+ badges,
505
+ social,
506
+ autoHide = false,
507
+ backgroundClassName,
508
+ className,
509
+ style,
510
+ skipToContentId = "main-content"
511
+ }) {
358
512
  const [show, setShow] = useState(true);
359
- const lastScrollY = useRef2(0);
360
- const [openDropdowns, setOpenDropdowns] = useState({});
361
- const dropdownRefs = useRef2({});
362
- const triggerRefs = useRef2({});
363
- useEffect(() => {
364
- const handleClickOutside = (event) => {
365
- const target = event.target;
366
- if (!target) return;
367
- const isOutsideAllDropdowns = Object.keys(openDropdowns).every((id) => {
368
- const dropdown = dropdownRefs.current[id];
369
- const trigger = triggerRefs.current[id];
370
- if (!dropdown || !trigger) return true;
371
- return !dropdown.contains(target) && !trigger.contains(target);
372
- });
373
- if (isOutsideAllDropdowns) {
374
- setOpenDropdowns({});
375
- }
376
- };
377
- const handleEscapeKey = (event) => {
378
- if (event.key === "Escape") {
379
- setOpenDropdowns({});
380
- }
381
- };
382
- const hasOpenDropdowns = Object.values(openDropdowns).some(Boolean);
383
- if (hasOpenDropdowns) {
384
- document.addEventListener("mousedown", handleClickOutside);
385
- document.addEventListener("keydown", handleEscapeKey);
386
- }
387
- return () => {
388
- document.removeEventListener("mousedown", handleClickOutside);
389
- document.removeEventListener("keydown", handleEscapeKey);
390
- };
391
- }, [openDropdowns]);
392
- useEffect(() => {
393
- return () => {
394
- setOpenDropdowns({});
395
- dropdownRefs.current = {};
396
- triggerRefs.current = {};
397
- };
398
- }, []);
399
- useEffect(() => {
400
- if (!config.autoHide) return void 0;
513
+ const lastScrollY = useRef(0);
514
+ const activeId = useActiveSection(nav.menus, pathname);
515
+ const { openId, close, getTriggerProps, getPanelProps } = useNavMenus({ pathname });
516
+ const [trail, setTrail] = useState({ id: null, from: null });
517
+ if (trail.id !== openId) setTrail({ id: openId, from: trail.id });
518
+ const previousId = trail.id === openId ? trail.from : trail.id;
519
+ const megaIds = nav.menus.filter(isMegaMenu).map((menu) => menu.id);
520
+ const openMegaIndex = openId === null ? -1 : megaIds.indexOf(openId);
521
+ const previousMegaIndex = previousId === null ? -1 : megaIds.indexOf(previousId);
522
+ const megaMotion = openMegaIndex < 0 || previousMegaIndex < 0 ? "open" : openMegaIndex > previousMegaIndex ? "from-end" : "from-start";
523
+ useEffect2(() => {
524
+ if (!autoHide) return void 0;
401
525
  const handleScroll = () => {
402
526
  const currentScrollY = window.scrollY;
403
527
  const prevScrollY = lastScrollY.current;
404
528
  lastScrollY.current = currentScrollY;
405
- const shouldHide = currentScrollY > prevScrollY && currentScrollY > 50;
406
- const shouldShow = currentScrollY < prevScrollY || currentScrollY <= 10;
407
- if (shouldHide) {
408
- setShow(false);
409
- } else if (shouldShow) {
410
- setShow(true);
411
- }
529
+ if (currentScrollY > prevScrollY && currentScrollY > 50) setShow(false);
530
+ else if (currentScrollY < prevScrollY || currentScrollY <= 10) setShow(true);
412
531
  };
413
532
  window.addEventListener("scroll", handleScroll, { passive: true });
414
- return () => {
415
- window.removeEventListener("scroll", handleScroll);
416
- };
417
- }, [config.autoHide]);
418
- const renderNavigationItem = (item) => {
419
- if (item.element) {
420
- return /* @__PURE__ */ jsx5(React.Fragment, { children: item.element }, item.id);
533
+ return () => window.removeEventListener("scroll", handleScroll);
534
+ }, [autoHide]);
535
+ const headerShown = !autoHide || show || openId !== null;
536
+ const renderMenu = (menu) => {
537
+ const current = menu.id === activeId;
538
+ const hasPanel = !!menu.columns?.length || !!menu.features?.length || !!menu.sideLinks?.length;
539
+ if (!hasPanel) {
540
+ if (!menu.href) return null;
541
+ return /* @__PURE__ */ jsx6("div", { className: "flex", children: /* @__PURE__ */ jsx6(
542
+ Button,
543
+ {
544
+ asChild: true,
545
+ variant: "transparent",
546
+ size: "wrap",
547
+ font: "regular",
548
+ className: cn(TOP_ITEM_CLASS, NAV_FOCUS_CLASS, current && TOP_ITEM_CURRENT_CLASS),
549
+ children: renderLink({
550
+ link: { href: menu.href },
551
+ "aria-current": current ? "page" : void 0,
552
+ children: /* @__PURE__ */ jsxs5(Fragment4, { children: [
553
+ menuIcon(menu),
554
+ menu.label
555
+ ] })
556
+ })
557
+ }
558
+ ) }, menu.id);
421
559
  }
422
- if (item.children && item.children.length > 0) {
423
- const isOpen = openDropdowns[item.id] || false;
424
- return /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
425
- /* @__PURE__ */ jsx5(
560
+ const open = openId === menu.id;
561
+ return (
562
+ // A dropdown is anchored to its trigger (`relative`); a mega menu to the
563
+ // bar itself, so its wrapper stays unpositioned.
564
+ /* @__PURE__ */ jsxs5("div", { className: cn("flex", !isMegaMenu(menu) && "relative"), children: [
565
+ /* @__PURE__ */ jsxs5(
426
566
  Button,
427
567
  {
428
- ref: (el) => {
429
- triggerRefs.current[item.id] = el;
430
- },
568
+ type: "button",
431
569
  variant: "transparent",
432
- leftIcon: item.icon,
433
- rightIcon: item.badge,
434
- onClick: () => {
435
- setOpenDropdowns((prev) => ({
436
- [item.id]: !prev[item.id]
437
- }));
438
- },
439
- size: "default",
570
+ size: "wrap",
440
571
  font: "regular",
572
+ ...getTriggerProps(menu.id),
573
+ "aria-current": current ? "page" : void 0,
441
574
  className: cn(
442
- // Top-level nav links (Figma 2936-6815): compact h6 label
443
- // (DM Sans 500, 14/20) with 24px icons — overrides the
444
- // font="regular" h4 step and the button's 20px svg cap.
445
- NAV_ITEM_CLASSES,
446
- item.isActive && "bg-ods-bg-hover",
447
- // Active items get subtle gray background
448
- isOpen && "bg-ods-bg-hover",
449
- // Open dropdowns get gray background
450
- item.className
575
+ TOP_ITEM_CLASS,
576
+ NAV_FOCUS_CLASS,
577
+ open && "bg-ods-bg-hover text-ods-text-primary",
578
+ current && TOP_ITEM_CURRENT_CLASS
451
579
  ),
452
- children: item.label
580
+ children: [
581
+ menuIcon(menu),
582
+ menu.label,
583
+ /* @__PURE__ */ jsx6(
584
+ Chevron02DownIcon,
585
+ {
586
+ "aria-hidden": "true",
587
+ className: cn("!h-4 !w-4 transition-transform duration-150", open && "rotate-180")
588
+ }
589
+ )
590
+ ]
453
591
  }
454
592
  ),
455
- /* @__PURE__ */ jsxs5(
456
- "div",
593
+ /* @__PURE__ */ jsx6(
594
+ NavPanel,
457
595
  {
458
- ref: (el) => {
459
- dropdownRefs.current[item.id] = el;
460
- },
461
- inert: !isOpen,
596
+ ...getPanelProps(menu.id),
597
+ menu,
598
+ open,
599
+ motion: open ? megaMotion : void 0,
600
+ handoff: openMegaIndex >= 0,
601
+ renderLink,
602
+ badges,
603
+ social,
604
+ onNavigate: close
605
+ }
606
+ )
607
+ ] }, menu.id)
608
+ );
609
+ };
610
+ const primaryCta = typeof nav.primaryCta === "object" ? /* @__PURE__ */ jsx6(Button, { variant: "accent", href: nav.primaryCta.href, children: nav.primaryCta.label }) : nav.primaryCta === "none" ? null : cta ?? null;
611
+ const hasRight = !!mingo || !!nav.signIn || !!actions || !!primaryCta;
612
+ return /* @__PURE__ */ jsxs5(
613
+ "div",
614
+ {
615
+ "data-site-header": "",
616
+ className: "sticky top-0 z-[50] w-full transition-transform duration-300 ease-in-out",
617
+ style: { transform: headerShown ? "translateY(0)" : "translateY(-100%)" },
618
+ children: [
619
+ /* @__PURE__ */ jsx6(
620
+ next_link_default,
621
+ {
622
+ href: `#${skipToContentId}`,
462
623
  className: cn(
463
- "absolute left-0 top-full mt-1",
464
- item.dropdownClassName ? "" : "border border-ods-border bg-ods-card",
465
- "z-[9999] rounded-lg shadow-xl",
466
- item.id === "community" ? "min-w-[240px]" : "min-w-[220px]",
467
- "transition-opacity duration-150",
468
- isOpen ? "pointer-events-auto visible opacity-100" : "pointer-events-none invisible opacity-0",
469
- item.dropdownClassName || ""
624
+ "sr-only left-[var(--spacing-system-lf)] top-3 z-[70] rounded-md bg-ods-text-primary px-[var(--spacing-system-mf)] py-[var(--spacing-system-xsf)] text-ods-bg text-h6 focus:not-sr-only focus:absolute",
625
+ NAV_FOCUS_CLASS
470
626
  ),
471
- children: [
472
- /* @__PURE__ */ jsx5("div", { className: "p-2", children: item.children.map((child, index) => /* @__PURE__ */ jsx5(
627
+ children: "Skip to content"
628
+ }
629
+ ),
630
+ /* @__PURE__ */ jsx6(
631
+ TopNavigation,
632
+ {
633
+ className: cn("relative", className),
634
+ style,
635
+ backgroundClassName,
636
+ centerBreakpoint: "lg",
637
+ size: "big",
638
+ leading: /* @__PURE__ */ jsxs5(Fragment4, { children: [
639
+ leading,
640
+ mobile && /* @__PURE__ */ jsx6(
641
+ HeaderButton,
642
+ {
643
+ className: "border-r border-ods-border lg:hidden",
644
+ onClick: mobile.onToggle,
645
+ isActive: mobile.isOpen,
646
+ "aria-label": mobile.isOpen ? "Close menu" : "Open menu",
647
+ "aria-expanded": mobile.isOpen,
648
+ "aria-controls": mobile.isOpen ? mobile.controlsId ?? MOBILE_NAV_SHEET_ID : void 0,
649
+ icon: mobile.isOpen ? /* @__PURE__ */ jsx6(XmarkIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx6(Menu01Icon, { className: "h-6 w-6" })
650
+ }
651
+ )
652
+ ] }),
653
+ logo: logoHref ? renderLink({
654
+ link: { href: logoHref },
655
+ className: cn(
656
+ "flex min-w-0 items-center rounded-md transition-opacity duration-200 hover:opacity-80",
657
+ NAV_FOCUS_CLASS
658
+ ),
659
+ "aria-label": nav.brand.name,
660
+ children: logo
661
+ }) : logo,
662
+ logoClassName: "shrink pl-[var(--spacing-system-lf)] md:pl-[var(--spacing-system-lf)] lg:pl-[var(--spacing-system-lf)]",
663
+ center: nav.menus.length > 0 ? /* @__PURE__ */ jsx6("nav", { "aria-label": "Main", className: "flex items-center gap-[var(--spacing-system-xxs)]", children: nav.menus.map(renderMenu) }) : void 0,
664
+ centerClassName: "justify-start pl-[var(--spacing-system-xlf)]",
665
+ cta: hasRight ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
666
+ mingo && /* @__PURE__ */ jsx6(
667
+ MingoAiButton,
668
+ {
669
+ source: mingo.source,
670
+ icon: mingo.icon,
671
+ label: mingo.label,
672
+ shortcutHint: mingo.shortcutHint
673
+ }
674
+ ),
675
+ nav.signIn && /* @__PURE__ */ jsx6("div", { className: "hidden lg:flex", children: /* @__PURE__ */ jsx6(
473
676
  Button,
474
677
  {
678
+ asChild: true,
475
679
  variant: "transparent",
476
- size: "small-legacy",
477
- href: child.href,
478
- leftIcon: child.icon,
479
- rightIcon: child.badge,
480
- onClick: () => {
481
- setOpenDropdowns((prev) => ({ ...prev, [item.id]: false }));
482
- if (child.onClick) {
483
- child.onClick();
484
- }
485
- },
486
- className: cn(
487
- "flex w-full justify-start",
488
- // Same caption step as the top-level nav links (designer:
489
- // dropdowns follow the h6 caption size/weight too). The
490
- // explicit font-medium beats small-legacy's font-bold via
491
- // tailwind-merge instead of stylesheet order.
492
- "font-medium text-h6",
493
- index < (item.children?.length ?? 0) - 1 && "mb-1",
494
- "text-ods-text-primary",
495
- // All dropdown items use primary text color
496
- child.isActive && "bg-ods-bg-hover"
497
- // Active dropdown items get gray background
498
- ),
499
- ...child.isExternal && { isExternal: true },
500
- children: child.label
501
- },
502
- child.id
503
- )) }),
504
- item.dropdownContent && /* @__PURE__ */ jsxs5(Fragment2, { children: [
505
- item.showDropdownDivider !== false && /* @__PURE__ */ jsx5("div", { className: "mx-2 my-2 h-px bg-ods-border" }),
506
- /* @__PURE__ */ jsx5("div", { className: "px-2 pb-2", children: item.dropdownContent })
507
- ] })
508
- ]
680
+ size: "wrap",
681
+ font: "regular",
682
+ className: cn(TOP_ITEM_CLASS, NAV_FOCUS_CLASS),
683
+ children: renderLink({ link: nav.signIn, children: nav.signIn.label })
684
+ }
685
+ ) }),
686
+ actions,
687
+ primaryCta
688
+ ] }) : void 0,
689
+ ctaClassName: "gap-[var(--spacing-system-xsf)]",
690
+ sideActions
509
691
  }
510
692
  )
511
- ] }, item.id);
693
+ ]
512
694
  }
513
- if (item.href || item.onClick) {
514
- return /* @__PURE__ */ jsx5(
515
- Button,
516
- {
517
- variant: "transparent",
518
- href: item.href,
519
- onClick: item.onClick,
520
- leftIcon: item.icon,
521
- rightIcon: item.badge,
522
- size: "default",
523
- font: "regular",
524
- className: cn(
525
- NAV_ITEM_CLASSES,
526
- "hover:bg-ods-bg-hover focus:bg-ods-bg-hover",
527
- "whitespace-nowrap",
528
- "text-ods-text-primary",
529
- // All items use primary text color
530
- item.isActive && "bg-ods-bg-hover",
531
- // Active items get subtle gray background
532
- item.className
695
+ );
696
+ }
697
+
698
+ // src/components/navigation/mobile-nav-sheet.tsx
699
+ import { usePreventScroll } from "@react-aria/overlays";
700
+ import { useRef as useRef2, useState as useState2 } from "react";
701
+ import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
702
+ function siteNavHasMobileMenus(nav) {
703
+ return (nav.mobileMenus ?? nav.menus).length > 0;
704
+ }
705
+ var GROUP_ROW_CLASS = "flex min-h-14 w-full items-center justify-between gap-[var(--spacing-system-sf)] text-left text-ods-text-primary text-h4";
706
+ var menuLinks = (menu) => [
707
+ ...(menu.columns ?? []).flatMap((group) => group.links),
708
+ ...menu.sideLinks ?? []
709
+ ];
710
+ function MobileNavSheet(props) {
711
+ if (!props.isOpen) return null;
712
+ return /* @__PURE__ */ jsx7(MobileNavSheetBody, { ...props });
713
+ }
714
+ function MobileNavSheetBody({
715
+ nav,
716
+ onClose,
717
+ pathname,
718
+ logo,
719
+ renderLink = defaultRenderSiteNavLink,
720
+ cta,
721
+ actions,
722
+ askAI,
723
+ extraMenus,
724
+ badges,
725
+ social,
726
+ backgroundClassName
727
+ }) {
728
+ const sheetRef = useRef2(null);
729
+ const menus = [...nav.mobileMenus ?? nav.menus, ...extraMenus ?? []];
730
+ usePreventScroll();
731
+ useFocusTrap(sheetRef, true, { onEscape: onClose });
732
+ const [openGroups, setOpenGroups] = useState2(() => {
733
+ const active = resolveActiveSection(menus, pathname);
734
+ return active ? { [active]: true } : {};
735
+ });
736
+ const primaryCta = typeof nav.primaryCta === "object" ? /* @__PURE__ */ jsx7(Button, { variant: "accent", href: nav.primaryCta.href, onClick: onClose, className: "w-full", children: nav.primaryCta.label }) : nav.primaryCta === "none" ? null : cta ?? null;
737
+ const hasFooter = !!actions || !!primaryCta || !!nav.signIn;
738
+ return /* @__PURE__ */ jsxs6(
739
+ "div",
740
+ {
741
+ ref: sheetRef,
742
+ id: MOBILE_NAV_SHEET_ID,
743
+ role: "dialog",
744
+ "aria-modal": "true",
745
+ "aria-label": "Navigation menu",
746
+ tabIndex: -1,
747
+ className: cn(
748
+ "fixed inset-0 z-[9999] flex h-[100svh] flex-col text-ods-text-primary outline-none",
749
+ backgroundClassName ?? "bg-ods-bg"
750
+ ),
751
+ children: [
752
+ /* @__PURE__ */ jsxs6("div", { className: "flex h-14 shrink-0 items-center justify-between border-b border-ods-border pl-5 pr-[var(--spacing-system-xsf)]", children: [
753
+ /* @__PURE__ */ jsx7("div", { className: "flex min-w-0 items-center", children: logo }),
754
+ /* @__PURE__ */ jsx7(
755
+ Button,
756
+ {
757
+ type: "button",
758
+ variant: "transparent",
759
+ size: "icon",
760
+ "aria-label": "Close menu",
761
+ onClick: onClose,
762
+ className: cn("h-11 w-11 shrink-0 md:h-11 md:w-11", NAV_FOCUS_CLASS),
763
+ children: /* @__PURE__ */ jsx7(XmarkIcon, { "aria-hidden": "true", className: "!h-6 !w-6" })
764
+ }
765
+ )
766
+ ] }),
767
+ /* @__PURE__ */ jsxs6("div", { className: "min-h-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-contain px-5", children: [
768
+ askAI && /* @__PURE__ */ jsx7(
769
+ MingoAiButton,
770
+ {
771
+ variant: "field",
772
+ source: askAI.source,
773
+ icon: askAI.icon,
774
+ label: askAI.label,
775
+ onClick: onClose
776
+ }
533
777
  ),
534
- ...item.isExternal && { isExternal: true },
535
- children: item.label
536
- },
537
- item.id
538
- );
778
+ /* @__PURE__ */ jsx7("nav", { "aria-label": "Main", children: menus.map((menu) => {
779
+ const links = menuLinks(menu);
780
+ if (links.length === 0) {
781
+ if (!menu.href) return null;
782
+ return /* @__PURE__ */ jsx7("div", { className: "border-b border-ods-border", children: renderLink({
783
+ link: { href: menu.href },
784
+ className: cn(GROUP_ROW_CLASS, NAV_FOCUS_CLASS),
785
+ onClick: onClose,
786
+ children: /* @__PURE__ */ jsxs6(Fragment5, { children: [
787
+ menu.label,
788
+ /* @__PURE__ */ jsx7(Chevron02RightIcon, { "aria-hidden": "true", className: "h-5 w-5 shrink-0 text-ods-text-muted" })
789
+ ] })
790
+ }) }, menu.id);
791
+ }
792
+ const open = !!openGroups[menu.id];
793
+ const listId = `${MOBILE_NAV_SHEET_ID}-${menu.id}`;
794
+ return /* @__PURE__ */ jsxs6("div", { className: "border-b border-ods-border", children: [
795
+ /* @__PURE__ */ jsxs6(
796
+ Button,
797
+ {
798
+ type: "button",
799
+ variant: "glyph",
800
+ size: "wrap",
801
+ font: "regular",
802
+ "aria-expanded": open,
803
+ "aria-controls": open ? listId : void 0,
804
+ onClick: () => setOpenGroups((prev) => ({ ...prev, [menu.id]: !prev[menu.id] })),
805
+ className: cn(GROUP_ROW_CLASS, NAV_FOCUS_CLASS),
806
+ children: [
807
+ menu.label,
808
+ /* @__PURE__ */ jsx7(
809
+ Chevron02DownIcon,
810
+ {
811
+ "aria-hidden": "true",
812
+ className: cn(
813
+ "h-5 w-5 shrink-0 text-ods-text-muted transition-transform duration-150",
814
+ open && "rotate-180"
815
+ )
816
+ }
817
+ )
818
+ ]
819
+ }
820
+ ),
821
+ open && /* @__PURE__ */ jsxs6("div", { id: listId, className: "flex flex-col pb-[var(--spacing-system-sf)]", children: [
822
+ links.map((link) => /* @__PURE__ */ jsx7(
823
+ NavItemRow,
824
+ {
825
+ link,
826
+ variant: "sheet",
827
+ renderLink,
828
+ badge: link.badgeKey ? badges?.[link.badgeKey] : void 0,
829
+ onNavigate: onClose
830
+ },
831
+ link.id
832
+ )),
833
+ menu.showSocial && social && /* @__PURE__ */ jsx7("div", { className: "pt-[var(--spacing-system-xsf)]", children: social })
834
+ ] })
835
+ ] }, menu.id);
836
+ }) })
837
+ ] }),
838
+ hasFooter && /* @__PURE__ */ jsxs6("div", { className: "flex shrink-0 flex-col gap-[var(--spacing-system-xxs)] border-t border-ods-border px-5 pb-[max(1.75rem,env(safe-area-inset-bottom))] pt-[var(--spacing-system-mf)] [&_a]:w-full [&_button]:w-full", children: [
839
+ actions,
840
+ primaryCta,
841
+ nav.signIn && renderLink({
842
+ link: nav.signIn,
843
+ className: cn(
844
+ "flex h-12 items-center justify-center rounded-md text-ods-text-primary text-h4",
845
+ NAV_FOCUS_CLASS
846
+ ),
847
+ onClick: onClose,
848
+ children: nav.signIn.label
849
+ })
850
+ ] })
851
+ ]
539
852
  }
540
- return /* @__PURE__ */ jsx5(
541
- Button,
542
- {
543
- variant: "transparent",
544
- onClick: item.onClick,
545
- leftIcon: item.icon,
546
- rightIcon: item.badge,
547
- size: "default",
548
- font: "regular",
549
- className: cn(
550
- NAV_ITEM_CLASSES,
551
- "hover:bg-ods-bg-hover focus:bg-ods-bg-hover",
552
- "whitespace-nowrap",
553
- "text-ods-text-primary",
554
- // All items use primary text color
555
- item.isActive && "bg-ods-bg-hover",
556
- // Active items get gray background
557
- item.className
558
- ),
559
- children: item.label
560
- },
561
- item.id
562
- );
563
- };
564
- const headerShown = !config.autoHide || show;
565
- const hasNav = !!config.navigation && config.navigation.items.length > 0;
566
- const hasCta = !!config.actions?.right?.length || !!(config.actions?.persistent && config.actions.persistent.length > 0);
567
- return /* @__PURE__ */ jsx5(
853
+ );
854
+ }
855
+
856
+ // src/components/navigation/site-footer.tsx
857
+ import { useState as useState3 } from "react";
858
+ import { Fragment as Fragment6, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
859
+ var ACCORDION_OVER = 2;
860
+ var DESKTOP_COLUMNS = {
861
+ 1: "md:grid-cols-1",
862
+ 2: "md:grid-cols-2",
863
+ 3: "md:grid-cols-3",
864
+ 4: "md:grid-cols-3 lg:grid-cols-4",
865
+ 5: "md:grid-cols-3 lg:grid-cols-5",
866
+ 6: "md:grid-cols-3 lg:grid-cols-6"
867
+ };
868
+ var HEADING_CLASS2 = "text-ods-text-muted text-h5";
869
+ function FooterColumn({
870
+ group,
871
+ accordion,
872
+ renderLink
873
+ }) {
874
+ const [open, setOpen] = useState3(false);
875
+ const listId = `site-footer-${group.id}`;
876
+ const links = group.links.map((link) => /* @__PURE__ */ jsx8("li", { children: /* @__PURE__ */ jsx8(NavItemRow, { link, variant: "label", renderLink }) }, link.id));
877
+ return /* @__PURE__ */ jsxs7(
568
878
  "div",
569
879
  {
570
- className: cn("sticky top-0 z-[50] w-full transition-transform duration-300 ease-in-out"),
571
- style: {
572
- transform: !headerShown ? "translateY(-100%)" : "translateY(0)"
573
- },
574
- children: /* @__PURE__ */ jsx5(
575
- TopNavigation,
576
- {
577
- className: cn("relative", config.className),
578
- style: config.style,
579
- backgroundClassName: config.backgroundColor,
580
- centerBreakpoint: "lg",
581
- size: "big",
582
- leading: /* @__PURE__ */ jsxs5(Fragment2, { children: [
583
- !!config.actions?.left?.length && /* @__PURE__ */ jsx5("div", { className: "flex h-full items-center border-r border-ods-border", children: config.actions.left }),
584
- config.mobile?.enabled && /* @__PURE__ */ jsx5(
585
- HeaderButton,
586
- {
587
- className: "border-r border-ods-border lg:hidden",
588
- onClick: () => {
589
- config.mobile?.onToggle?.();
590
- },
591
- isActive: config.mobile?.isOpen ?? false,
592
- "aria-label": config.mobile?.isOpen ? "Close menu" : "Open menu",
593
- "aria-expanded": config.mobile?.isOpen ?? false,
594
- "aria-controls": config.mobile?.isOpen ? MOBILE_NAV_PANEL_ID : void 0,
595
- icon: config.mobile?.isOpen ? config.mobile?.closeIcon || /* @__PURE__ */ jsx5(XmarkIcon, { className: "h-6 w-6" }) : config.mobile?.menuIcon || /* @__PURE__ */ jsx5(Menu01Icon, { className: "h-6 w-6" })
596
- }
597
- )
598
- ] }),
599
- logo: config.logo.href ? /* @__PURE__ */ jsx5(next_link_default, { href: config.logo.href, className: "transition-opacity duration-200 hover:opacity-80", children: config.logo.element }) : config.logo.element,
600
- logoClassName: "pl-[var(--spacing-system-lf)] md:pl-[var(--spacing-system-lf)] lg:pl-[var(--spacing-system-lf)]",
601
- center: hasNav ? /* @__PURE__ */ jsx5(
602
- "nav",
880
+ className: cn(
881
+ "flex min-w-0 flex-col md:gap-[var(--spacing-system-mf)]",
882
+ accordion ? "border-b border-ods-border md:border-b-0" : "gap-[var(--spacing-system-mf)]"
883
+ ),
884
+ children: [
885
+ group.title && (accordion ? /* @__PURE__ */ jsxs7(Fragment6, { children: [
886
+ /* @__PURE__ */ jsx8("h3", { className: "md:hidden", children: /* @__PURE__ */ jsxs7(
887
+ Button,
603
888
  {
889
+ type: "button",
890
+ variant: "glyph",
891
+ size: "wrap",
892
+ font: "regular",
893
+ "aria-expanded": open,
894
+ "aria-controls": listId,
895
+ onClick: () => setOpen((prev) => !prev),
604
896
  className: cn(
605
- "flex items-center gap-2",
606
- // True centering relative to the bar (not the leftover flex
607
- // space) — same treatment the pre-unification header had.
608
- config.navigation?.position === "center" && "absolute left-1/2 -translate-x-1/2"
897
+ "flex min-h-14 w-full items-center justify-between gap-[var(--spacing-system-sf)] text-left",
898
+ HEADING_CLASS2,
899
+ NAV_FOCUS_CLASS
609
900
  ),
610
- role: "navigation",
611
- "aria-label": "Main navigation",
612
- children: config.navigation?.items.map(renderNavigationItem)
901
+ children: [
902
+ group.title,
903
+ /* @__PURE__ */ jsx8(
904
+ Chevron02DownIcon,
905
+ {
906
+ "aria-hidden": "true",
907
+ className: cn("h-5 w-5 shrink-0 transition-transform duration-150", open && "rotate-180")
908
+ }
909
+ )
910
+ ]
613
911
  }
614
- ) : void 0,
615
- centerClassName: cn(
616
- config.navigation?.position === "left" && "justify-start",
617
- config.navigation?.position === "right" && "justify-end pr-[var(--spacing-system-m)]"
618
- ),
619
- cta: hasCta ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
620
- !!config.actions?.right?.length && /* @__PURE__ */ jsx5("div", { className: "hidden items-center gap-3 lg:flex", children: config.actions.right }),
621
- config.actions?.persistent && config.actions.persistent.length > 0 && /* @__PURE__ */ jsx5("div", { className: "flex items-center", children: config.actions.persistent })
622
- ] }) : void 0,
623
- ctaClassName: "gap-3",
624
- sideActions: config.tickets || config.mingo?.enabled ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
625
- config.tickets && /* @__PURE__ */ jsx5(
626
- TicketAlertsButton,
627
- {
628
- href: config.tickets.href,
629
- onNavigate: config.tickets.onClick,
630
- className: "border-l border-ods-border"
631
- }
912
+ ) }),
913
+ /* @__PURE__ */ jsx8("h3", { className: cn("hidden md:block", HEADING_CLASS2), children: group.title })
914
+ ] }) : /* @__PURE__ */ jsx8("h3", { className: HEADING_CLASS2, children: group.title })),
915
+ /* @__PURE__ */ jsx8(
916
+ "ul",
917
+ {
918
+ id: listId,
919
+ className: cn(
920
+ "flex-col md:flex md:gap-[var(--spacing-system-sf)] md:pb-0",
921
+ accordion ? open ? "flex gap-[var(--spacing-system-sf)] pb-[var(--spacing-system-mf)]" : "hidden" : "flex gap-[var(--spacing-system-sf)]"
632
922
  ),
633
- config.mingo?.enabled && /* @__PURE__ */ jsx5(
634
- MingoAiButton,
635
- {
636
- source: config.mingo.source,
637
- icon: config.mingo.icon,
638
- label: config.mingo.label,
639
- className: config.mingo.className
640
- }
641
- )
642
- ] }) : void 0
643
- }
644
- )
923
+ children: links
924
+ }
925
+ )
926
+ ]
645
927
  }
646
928
  );
647
929
  }
648
-
649
- // src/components/navigation/header-skeleton.tsx
650
- import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
651
- function HeaderSkeleton({ config }) {
652
- const showNavigation = config?.navigation && config.navigation.items.length > 0;
653
- const showActions = config?.actions?.right && config.actions.right.length > 0;
654
- const showMobileMenu = config?.mobile?.enabled;
655
- const showLeftActions = !!config?.actions?.left;
656
- return /* @__PURE__ */ jsx6("div", { className: "sticky top-0 z-[50] w-full", children: /* @__PURE__ */ jsxs6(
657
- "header",
930
+ function SiteFooter({
931
+ nav,
932
+ logo,
933
+ name,
934
+ renderLink = defaultRenderSiteNavLink,
935
+ cta,
936
+ social,
937
+ brandExtra,
938
+ backgroundClassName,
939
+ year = (/* @__PURE__ */ new Date()).getFullYear()
940
+ }) {
941
+ const band = nav.closingBand;
942
+ const bandPrimary = typeof nav.primaryCta === "object" ? /* @__PURE__ */ jsx8(Button, { variant: "accent", href: nav.primaryCta.href, children: nav.primaryCta.label }) : nav.primaryCta === "none" ? null : cta ?? null;
943
+ const columns = nav.footerColumns;
944
+ const accordion = columns.length > ACCORDION_OVER;
945
+ const socialRow = social ?? (nav.brand.social.length > 0 ? /* @__PURE__ */ jsx8(
946
+ SocialIconRow,
947
+ {
948
+ compact: true,
949
+ links: nav.brand.social.map((link) => ({
950
+ platform: link.iconName ?? link.id,
951
+ href: link.href,
952
+ label: link.label
953
+ }))
954
+ }
955
+ ) : null);
956
+ return /* @__PURE__ */ jsxs7(
957
+ "footer",
658
958
  {
659
959
  className: cn(
660
- "flex h-[72px] w-full items-center border-b border-t border-ods-border md:border-t-0",
661
- config?.backgroundColor || "bg-ods-card",
662
- config?.className
960
+ "relative z-[44] w-full border-t border-ods-border px-[var(--spacing-system-lf)] text-ods-text-primary",
961
+ backgroundClassName ?? "bg-ods-bg"
663
962
  ),
664
963
  children: [
665
- showLeftActions && /* @__PURE__ */ jsx6("div", { className: "flex h-full w-[72px] items-center justify-center border-r border-ods-border", children: /* @__PURE__ */ jsx6("div", { className: "h-6 w-6 animate-pulse rounded bg-ods-border" }) }),
666
- showMobileMenu && /* @__PURE__ */ jsx6("div", { className: "flex h-full w-[72px] items-center justify-center border-r border-ods-border lg:hidden", children: /* @__PURE__ */ jsx6("div", { className: "h-6 w-6 animate-pulse rounded bg-ods-border" }) }),
667
- /* @__PURE__ */ jsxs6("div", { className: "flex h-full flex-1 items-center gap-2 p-[var(--spacing-system-m)] md:pl-[var(--spacing-system-l)] lg:flex-none lg:pl-[var(--spacing-system-xxl)]", children: [
668
- /* @__PURE__ */ jsx6("div", { className: "h-6 w-6 animate-pulse rounded bg-ods-border" }),
669
- /* @__PURE__ */ jsx6("div", { className: "h-5 w-24 animate-pulse rounded bg-ods-border" })
964
+ band && /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-[var(--spacing-system-lf)] border-b border-ods-border py-[var(--spacing-system-xlf)] md:flex-row md:items-center md:justify-between md:gap-[var(--spacing-system-xlf)] md:py-14", children: [
965
+ /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-col gap-[var(--spacing-system-xsf)]", children: [
966
+ /* @__PURE__ */ jsx8("h2", { className: "text-h2", children: band.heading }),
967
+ /* @__PURE__ */ jsx8("p", { className: "text-ods-text-secondary text-h4", children: band.subheading })
968
+ ] }),
969
+ /* @__PURE__ */ jsxs7("div", { className: "flex shrink-0 flex-col gap-[var(--spacing-system-sf)] md:flex-row", children: [
970
+ bandPrimary,
971
+ band.secondary && /* @__PURE__ */ jsx8(Button, { variant: "outline", href: band.secondary.href, openInNewTab: band.secondary.external, children: navLinkLabel(band.secondary) })
972
+ ] })
670
973
  ] }),
671
- /* @__PURE__ */ jsx6("div", { className: "hidden h-full min-w-0 flex-1 items-center justify-center gap-2 lg:flex", children: showNavigation && /* @__PURE__ */ jsxs6(Fragment3, { children: [
672
- /* @__PURE__ */ jsx6("div", { className: "h-8 w-20 animate-pulse rounded bg-ods-border" }),
673
- /* @__PURE__ */ jsx6("div", { className: "h-8 w-28 animate-pulse rounded bg-ods-border" }),
674
- /* @__PURE__ */ jsx6("div", { className: "h-8 w-24 animate-pulse rounded bg-ods-border" })
675
- ] }) }),
676
- showActions && /* @__PURE__ */ jsx6("div", { className: "hidden h-full items-center px-[var(--spacing-system-m)] lg:flex", children: /* @__PURE__ */ jsx6("div", { className: "h-8 w-24 animate-pulse rounded bg-ods-border" }) }),
677
- config?.mingo?.enabled && /* @__PURE__ */ jsx6("div", { className: "flex h-full items-center border-l border-ods-border px-[var(--spacing-system-l)]", children: /* @__PURE__ */ jsx6("div", { className: "h-8 w-8 animate-pulse rounded bg-ods-border md:w-28" }) })
974
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-8 py-[var(--spacing-system-xlf)] lg:flex-row lg:gap-16 lg:py-14", children: [
975
+ /* @__PURE__ */ jsxs7("div", { className: "flex w-full shrink-0 flex-col items-start gap-[var(--spacing-system-mf)] lg:w-60", children: [
976
+ /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-[var(--spacing-system-xsf)]", children: [
977
+ logo,
978
+ typeof name === "string" ? /* @__PURE__ */ jsx8("span", { className: "whitespace-nowrap text-ods-text-primary text-wordmark", children: name }) : name
979
+ ] }),
980
+ /* @__PURE__ */ jsx8("p", { className: "text-ods-text-secondary text-h6", children: nav.brand.tagline }),
981
+ socialRow,
982
+ nav.brand.statusUrl && renderLink({
983
+ link: { href: nav.brand.statusUrl, external: true },
984
+ className: cn(
985
+ "inline-flex items-center gap-[var(--spacing-system-xsf)] text-ods-text-secondary transition-colors text-h6 hover:text-ods-text-primary",
986
+ NAV_FOCUS_CLASS
987
+ ),
988
+ children: /* @__PURE__ */ jsxs7(Fragment6, { children: [
989
+ /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "h-2 w-2 rounded-full bg-ods-success" }),
990
+ "System status"
991
+ ] })
992
+ }),
993
+ brandExtra
994
+ ] }),
995
+ columns.length > 0 && /* @__PURE__ */ jsx8(
996
+ "nav",
997
+ {
998
+ "aria-label": "Footer",
999
+ className: cn(
1000
+ "grid min-w-0 flex-1 md:gap-7",
1001
+ accordion ? "grid-cols-1" : "grid-cols-2 gap-7",
1002
+ DESKTOP_COLUMNS[Math.min(columns.length, 6)]
1003
+ ),
1004
+ children: columns.map((group) => /* @__PURE__ */ jsx8(FooterColumn, { group, accordion, renderLink }, group.id))
1005
+ }
1006
+ )
1007
+ ] }),
1008
+ /* @__PURE__ */ jsxs7(
1009
+ "div",
1010
+ {
1011
+ className: cn(
1012
+ "flex flex-col gap-[var(--spacing-system-xxs)] border-t border-ods-border pb-[var(--spacing-system-xlf)] pt-[var(--spacing-system-lf)] text-ods-text-muted text-h6 md:flex-row md:items-center md:justify-between md:gap-[var(--spacing-system-lf)]"
1013
+ ),
1014
+ children: [
1015
+ /* @__PURE__ */ jsxs7("span", { children: [
1016
+ "\xA9 ",
1017
+ year,
1018
+ " ",
1019
+ nav.legal.company
1020
+ ] }),
1021
+ /* @__PURE__ */ jsxs7("span", { className: "flex flex-wrap items-center gap-x-[var(--spacing-system-mf)] gap-y-[var(--spacing-system-xxs)]", children: [
1022
+ nav.legal.notes.length > 0 && /* @__PURE__ */ jsx8("span", { children: nav.legal.notes.join(" \xB7 ") }),
1023
+ nav.legal.links.map((link) => /* @__PURE__ */ jsx8(
1024
+ NavItemRow,
1025
+ {
1026
+ link,
1027
+ variant: "label",
1028
+ renderLink,
1029
+ className: "text-ods-accent hover:text-ods-accent hover:underline"
1030
+ },
1031
+ link.id
1032
+ ))
1033
+ ] })
1034
+ ]
1035
+ }
1036
+ )
678
1037
  ]
679
1038
  }
680
- ) });
681
- }
682
-
683
- // src/components/navigation/client-only-header.tsx
684
- import { jsx as jsx7 } from "react/jsx-runtime";
685
- function ClientOnlyHeader({ config, skeleton }) {
686
- const isClient = useIsHydrated();
687
- if (!isClient) {
688
- return skeleton || /* @__PURE__ */ jsx7(HeaderSkeleton, { config });
689
- }
690
- return /* @__PURE__ */ jsx7(Header, { config });
1039
+ );
691
1040
  }
692
1041
 
693
1042
  // src/components/navigation/sliding-sidebar.tsx
694
1043
  import { usePreventScroll as usePreventScroll2 } from "@react-aria/overlays";
695
1044
  import { motion, AnimatePresence, useReducedMotion } from "framer-motion";
696
- import { useState as useState2, useRef as useRef3 } from "react";
697
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1045
+ import { useState as useState4, useRef as useRef3 } from "react";
1046
+ import { Fragment as Fragment7, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
698
1047
  function SlidingSidebar({ config }) {
699
- const [expandedItems, setExpandedItems] = useState2(/* @__PURE__ */ new Set());
1048
+ const [expandedItems, setExpandedItems] = useState4(/* @__PURE__ */ new Set());
700
1049
  const mounted = useIsHydrated();
701
1050
  const headerHeight = useHeaderHeight();
702
1051
  const asideRef = useRef3(null);
@@ -714,24 +1063,24 @@ function SlidingSidebar({ config }) {
714
1063
  };
715
1064
  const renderMenuItem = (item, level = 0) => {
716
1065
  if (item.element) {
717
- return /* @__PURE__ */ jsx8("div", { children: item.element }, item.id);
1066
+ return /* @__PURE__ */ jsx9("div", { children: item.element }, item.id);
718
1067
  }
719
1068
  const children = item.children ?? [];
720
1069
  const hasChildren = children.length > 0;
721
1070
  const isExpanded = expandedItems.has(item.id);
722
1071
  if (hasChildren) {
723
- const chevronIcon = /* @__PURE__ */ jsx8(
1072
+ const chevronIcon = /* @__PURE__ */ jsx9(
724
1073
  "svg",
725
1074
  {
726
1075
  className: cn("h-4 w-4 transition-transform", isExpanded && "rotate-90"),
727
1076
  fill: "none",
728
1077
  stroke: "currentColor",
729
1078
  viewBox: "0 0 24 24",
730
- children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
1079
+ children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
731
1080
  }
732
1081
  );
733
- return /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
734
- /* @__PURE__ */ jsxs7(
1082
+ return /* @__PURE__ */ jsxs8("div", { className: "space-y-1", children: [
1083
+ /* @__PURE__ */ jsxs8(
735
1084
  Button,
736
1085
  {
737
1086
  variant: "transparent",
@@ -745,12 +1094,12 @@ function SlidingSidebar({ config }) {
745
1094
  item.isActive ? "bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent/90" : "text-ods-text-primary hover:bg-ods-border"
746
1095
  ),
747
1096
  children: [
748
- /* @__PURE__ */ jsx8("span", { className: "truncate", children: item.label }),
749
- item.badge !== void 0 && /* @__PURE__ */ jsx8("span", { className: "ml-auto mr-2 flex-shrink-0", children: item.badge })
1097
+ /* @__PURE__ */ jsx9("span", { className: "truncate", children: item.label }),
1098
+ item.badge !== void 0 && /* @__PURE__ */ jsx9("span", { className: "ml-auto mr-2 flex-shrink-0", children: item.badge })
750
1099
  ]
751
1100
  }
752
1101
  ),
753
- /* @__PURE__ */ jsx8(AnimatePresence, { children: isExpanded && /* @__PURE__ */ jsx8(
1102
+ /* @__PURE__ */ jsx9(AnimatePresence, { children: isExpanded && /* @__PURE__ */ jsx9(
754
1103
  motion.div,
755
1104
  {
756
1105
  initial: { height: 0, opacity: 0 },
@@ -763,13 +1112,13 @@ function SlidingSidebar({ config }) {
763
1112
  opacity: { duration: 0.1 }
764
1113
  },
765
1114
  className: "overflow-hidden",
766
- children: /* @__PURE__ */ jsx8("div", { className: "space-y-1 pl-4", children: children.map((child) => renderMenuItem(child, level + 1)) })
1115
+ children: /* @__PURE__ */ jsx9("div", { className: "space-y-1 pl-4", children: children.map((child) => renderMenuItem(child, level + 1)) })
767
1116
  }
768
1117
  ) })
769
1118
  ] }, item.id);
770
1119
  }
771
1120
  if (item.href) {
772
- return /* @__PURE__ */ jsxs7(
1121
+ return /* @__PURE__ */ jsxs8(
773
1122
  Button,
774
1123
  {
775
1124
  variant: "transparent",
@@ -785,14 +1134,14 @@ function SlidingSidebar({ config }) {
785
1134
  item.isActive ? "bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent/90" : "text-ods-text-primary hover:bg-ods-border"
786
1135
  ),
787
1136
  children: [
788
- /* @__PURE__ */ jsx8("span", { className: "truncate", children: item.label }),
789
- item.badge !== void 0 && /* @__PURE__ */ jsx8("span", { className: "ml-auto flex-shrink-0", children: item.badge })
1137
+ /* @__PURE__ */ jsx9("span", { className: "truncate", children: item.label }),
1138
+ item.badge !== void 0 && /* @__PURE__ */ jsx9("span", { className: "ml-auto flex-shrink-0", children: item.badge })
790
1139
  ]
791
1140
  },
792
1141
  item.id
793
1142
  );
794
1143
  }
795
- return /* @__PURE__ */ jsxs7(
1144
+ return /* @__PURE__ */ jsxs8(
796
1145
  Button,
797
1146
  {
798
1147
  variant: "transparent",
@@ -808,8 +1157,8 @@ function SlidingSidebar({ config }) {
808
1157
  item.isActive ? "bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent/90" : "text-ods-text-primary hover:bg-ods-border"
809
1158
  ),
810
1159
  children: [
811
- /* @__PURE__ */ jsx8("span", { className: "truncate", children: item.label }),
812
- item.badge !== void 0 && /* @__PURE__ */ jsx8("span", { className: "ml-auto flex-shrink-0", children: item.badge })
1160
+ /* @__PURE__ */ jsx9("span", { className: "truncate", children: item.label }),
1161
+ item.badge !== void 0 && /* @__PURE__ */ jsx9("span", { className: "ml-auto flex-shrink-0", children: item.badge })
813
1162
  ]
814
1163
  },
815
1164
  item.id
@@ -818,8 +1167,8 @@ function SlidingSidebar({ config }) {
818
1167
  if (!mounted) {
819
1168
  return null;
820
1169
  }
821
- return /* @__PURE__ */ jsxs7(Fragment4, { children: [
822
- /* @__PURE__ */ jsx8(AnimatePresence, { children: config.isOpen && /* @__PURE__ */ jsx8(
1170
+ return /* @__PURE__ */ jsxs8(Fragment7, { children: [
1171
+ /* @__PURE__ */ jsx9(AnimatePresence, { children: config.isOpen && /* @__PURE__ */ jsx9(
823
1172
  motion.div,
824
1173
  {
825
1174
  initial: { opacity: 0 },
@@ -833,7 +1182,7 @@ function SlidingSidebar({ config }) {
833
1182
  onClick: () => config.onClose()
834
1183
  }
835
1184
  ) }),
836
- /* @__PURE__ */ jsxs7(
1185
+ /* @__PURE__ */ jsxs8(
837
1186
  motion.aside,
838
1187
  {
839
1188
  ref: asideRef,
@@ -860,9 +1209,9 @@ function SlidingSidebar({ config }) {
860
1209
  config.className
861
1210
  ),
862
1211
  children: [
863
- /* @__PURE__ */ jsx8("div", { className: "flex-shrink-0", style: { height: `${headerHeight}px` } }),
864
- /* @__PURE__ */ jsx8("nav", { className: "flex-1 space-y-2 overflow-y-auto overscroll-contain p-4", children: config.items.map((item) => renderMenuItem(item)) }),
865
- config.footer && /* @__PURE__ */ jsx8("div", { className: "border-t border-ods-border p-4 pb-[max(1rem,env(safe-area-inset-bottom))]", children: config.footer })
1212
+ /* @__PURE__ */ jsx9("div", { className: "flex-shrink-0", style: { height: `${headerHeight}px` } }),
1213
+ /* @__PURE__ */ jsx9("nav", { className: "flex-1 space-y-2 overflow-y-auto overscroll-contain p-4", children: config.items.map((item) => renderMenuItem(item)) }),
1214
+ config.footer && /* @__PURE__ */ jsx9("div", { className: "border-t border-ods-border p-4 pb-[max(1rem,env(safe-area-inset-bottom))]", children: config.footer })
866
1215
  ]
867
1216
  }
868
1217
  )
@@ -870,13 +1219,13 @@ function SlidingSidebar({ config }) {
870
1219
  }
871
1220
 
872
1221
  // src/components/navigation/navigation-sidebar.tsx
873
- import { useCallback, useEffect as useEffect2, useMemo, useState as useState3 } from "react";
1222
+ import { useCallback, useEffect as useEffect3, useMemo, useState as useState5 } from "react";
874
1223
 
875
1224
  // src/components/navigation/navigation-sidebar-header.tsx
876
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1225
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
877
1226
  function NavigationSidebarHeader({ minimized }) {
878
- return /* @__PURE__ */ jsxs8("div", { className: "flex h-14 items-center justify-start border-b border-ods-border p-[var(--spacing-system-m)]", children: [
879
- /* @__PURE__ */ jsx9("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx9(
1227
+ return /* @__PURE__ */ jsxs9("div", { className: "flex h-14 items-center justify-start border-b border-ods-border p-[var(--spacing-system-m)]", children: [
1228
+ /* @__PURE__ */ jsx10("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx10(
880
1229
  OpenFrameLogo,
881
1230
  {
882
1231
  className: "h-6 w-6",
@@ -884,7 +1233,7 @@ function NavigationSidebarHeader({ minimized }) {
884
1233
  lowerPathColor: "var(--color-accent-primary)"
885
1234
  }
886
1235
  ) }),
887
- /* @__PURE__ */ jsx9(
1236
+ /* @__PURE__ */ jsx10(
888
1237
  "div",
889
1238
  {
890
1239
  className: cn(
@@ -892,7 +1241,7 @@ function NavigationSidebarHeader({ minimized }) {
892
1241
  minimized ? "ml-0 opacity-0" : "ml-[var(--spacing-system-xs)] opacity-100"
893
1242
  ),
894
1243
  "aria-hidden": minimized,
895
- children: /* @__PURE__ */ jsx9(OpenFrameText, { textColor: "var(--color-text-primary)" })
1244
+ children: /* @__PURE__ */ jsx10(OpenFrameText, { textColor: "var(--color-text-primary)" })
896
1245
  }
897
1246
  )
898
1247
  ] });
@@ -902,9 +1251,9 @@ function NavigationSidebarHeader({ minimized }) {
902
1251
  import { cloneElement, memo } from "react";
903
1252
 
904
1253
  // src/components/navigation/navigation-item-badge.tsx
905
- import { jsx as jsx10 } from "react/jsx-runtime";
1254
+ import { jsx as jsx11 } from "react/jsx-runtime";
906
1255
  function NavigationItemBadge({ label, compact = false, className, ...rest }) {
907
- return /* @__PURE__ */ jsx10(
1256
+ return /* @__PURE__ */ jsx11(
908
1257
  Tag,
909
1258
  {
910
1259
  as: "span",
@@ -918,7 +1267,7 @@ function NavigationItemBadge({ label, compact = false, className, ...rest }) {
918
1267
  }
919
1268
 
920
1269
  // src/components/navigation/navigation-sidebar-item.tsx
921
- import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1270
+ import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
922
1271
  var NavigationSidebarItemButton = memo(function NavigationSidebarItemButtonImpl({
923
1272
  item,
924
1273
  isActive,
@@ -965,14 +1314,14 @@ var NavigationSidebarItemButton = memo(function NavigationSidebarItemButtonImpl(
965
1314
  isActive && disabled && "text-ods-text-secondary [&_svg]:fill-ods-text-secondary",
966
1315
  disabled && "cursor-not-allowed opacity-50"
967
1316
  );
968
- const content = /* @__PURE__ */ jsxs9(Fragment5, { children: [
969
- /* @__PURE__ */ jsxs9("div", { className: "relative flex flex-shrink-0 items-center justify-center", children: [
1317
+ const content = /* @__PURE__ */ jsxs10(Fragment8, { children: [
1318
+ /* @__PURE__ */ jsxs10("div", { className: "relative flex flex-shrink-0 items-center justify-center", children: [
970
1319
  cloneElement(item.icon, {
971
1320
  color: isActive && !disabled ? "text-ods-accent" : "text-ods-text-secondary"
972
1321
  }),
973
- hasUnread && !showLabel && /* @__PURE__ */ jsx11(UnreadDot, { size: "fixed" })
1322
+ hasUnread && !showLabel && /* @__PURE__ */ jsx12(UnreadDot, { size: "fixed" })
974
1323
  ] }),
975
- /* @__PURE__ */ jsxs9(
1324
+ /* @__PURE__ */ jsxs10(
976
1325
  "span",
977
1326
  {
978
1327
  className: cn(
@@ -981,12 +1330,12 @@ var NavigationSidebarItemButton = memo(function NavigationSidebarItemButtonImpl(
981
1330
  ),
982
1331
  "aria-hidden": !showLabel,
983
1332
  children: [
984
- /* @__PURE__ */ jsx11("span", { className: "min-w-0 truncate text-h4", children: item.label }),
985
- item.badge && /* @__PURE__ */ jsx11(NavigationItemBadge, { label: item.badge, className: "ml-[var(--spacing-system-xs)] shrink-0" })
1333
+ /* @__PURE__ */ jsx12("span", { className: "min-w-0 truncate text-h4", children: item.label }),
1334
+ item.badge && /* @__PURE__ */ jsx12(NavigationItemBadge, { label: item.badge, className: "ml-[var(--spacing-system-xs)] shrink-0" })
986
1335
  ]
987
1336
  }
988
1337
  ),
989
- hasUnread && showLabel && /* @__PURE__ */ jsx11("span", { className: "ml-[var(--spacing-system-xs)] flex size-6 flex-shrink-0 items-center justify-center rounded-md bg-ods-accent p-2", children: /* @__PURE__ */ jsx11("span", { className: "text-ods-text-on-accent text-h5", children: unreadCount > 99 ? "99+" : unreadCount }) })
1338
+ hasUnread && showLabel && /* @__PURE__ */ jsx12("span", { className: "ml-[var(--spacing-system-xs)] flex size-6 flex-shrink-0 items-center justify-center rounded-md bg-ods-accent p-2", children: /* @__PURE__ */ jsx12("span", { className: "text-ods-text-on-accent text-h5", children: unreadCount > 99 ? "99+" : unreadCount }) })
990
1339
  ] });
991
1340
  const shared = {
992
1341
  className,
@@ -995,21 +1344,21 @@ var NavigationSidebarItemButton = memo(function NavigationSidebarItemButtonImpl(
995
1344
  "aria-current": isActive ? "page" : void 0
996
1345
  };
997
1346
  if (disabled || !item.path || item.onClick) {
998
- return /* @__PURE__ */ jsx11("button", { type: "button", onClick: (event) => onClick(item, event), disabled, ...shared, children: content });
1347
+ return /* @__PURE__ */ jsx12("button", { type: "button", onClick: (event) => onClick(item, event), disabled, ...shared, children: content });
999
1348
  }
1000
- return /* @__PURE__ */ jsx11(next_link_default, { href: item.path, onClick: (event) => onClick(item, event), ...shared, children: content });
1349
+ return /* @__PURE__ */ jsx12(next_link_default, { href: item.path, onClick: (event) => onClick(item, event), ...shared, children: content });
1001
1350
  });
1002
1351
  function NavigationSidebarItemSkeleton({ showLabel }) {
1003
- return /* @__PURE__ */ jsxs9("div", { className: "flex h-14 w-full items-center justify-start p-[var(--spacing-system-m)]", "aria-hidden": "true", children: [
1004
- /* @__PURE__ */ jsx11("div", { className: "relative flex flex-shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx11("div", { className: "h-6 w-6 animate-pulse rounded bg-ods-border" }) }),
1005
- showLabel && /* @__PURE__ */ jsx11("div", { className: "ml-[var(--spacing-system-xs)] h-4 flex-1 animate-pulse rounded bg-ods-border" })
1352
+ return /* @__PURE__ */ jsxs10("div", { className: "flex h-14 w-full items-center justify-start p-[var(--spacing-system-m)]", "aria-hidden": "true", children: [
1353
+ /* @__PURE__ */ jsx12("div", { className: "relative flex flex-shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx12("div", { className: "h-6 w-6 animate-pulse rounded bg-ods-border" }) }),
1354
+ showLabel && /* @__PURE__ */ jsx12("div", { className: "ml-[var(--spacing-system-xs)] h-4 flex-1 animate-pulse rounded bg-ods-border" })
1006
1355
  ] });
1007
1356
  }
1008
1357
 
1009
1358
  // src/components/navigation/navigation-sidebar-toggle.tsx
1010
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1359
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1011
1360
  function NavigationSidebarToggle({ minimized, showLabel, onToggle }) {
1012
- return /* @__PURE__ */ jsx12("div", { className: "border-t border-ods-border", children: /* @__PURE__ */ jsxs10(
1361
+ return /* @__PURE__ */ jsx13("div", { className: "border-t border-ods-border", children: /* @__PURE__ */ jsxs11(
1013
1362
  "button",
1014
1363
  {
1015
1364
  onClick: onToggle,
@@ -1023,8 +1372,8 @@ function NavigationSidebarToggle({ minimized, showLabel, onToggle }) {
1023
1372
  title: minimized ? "Hide Menu" : void 0,
1024
1373
  "aria-label": "Hide Menu",
1025
1374
  children: [
1026
- /* @__PURE__ */ jsx12("div", { className: "flex flex-shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx12(Chevrons03LeftIcon, { className: "h-6 w-6 rotate-180 text-ods-text-secondary transition-transform duration-300 @[140px]/of-nav-sidebar:rotate-0" }) }),
1027
- /* @__PURE__ */ jsx12(
1375
+ /* @__PURE__ */ jsx13("div", { className: "flex flex-shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx13(Chevrons03LeftIcon, { className: "h-6 w-6 rotate-180 text-ods-text-secondary transition-transform duration-300 @[140px]/of-nav-sidebar:rotate-0" }) }),
1376
+ /* @__PURE__ */ jsx13(
1028
1377
  "span",
1029
1378
  {
1030
1379
  className: cn(
@@ -1041,7 +1390,7 @@ function NavigationSidebarToggle({ minimized, showLabel, onToggle }) {
1041
1390
  }
1042
1391
 
1043
1392
  // src/components/navigation/navigation-sidebar.tsx
1044
- import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1393
+ import { Fragment as Fragment9, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1045
1394
  var MINIMIZED_WIDTH = 56;
1046
1395
  var EXPANDED_WIDTH = 224;
1047
1396
  var STORAGE_KEY = "of.navigationSidebar.minimized";
@@ -1065,15 +1414,15 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1065
1414
  const isLgUp = useLgUp() ?? false;
1066
1415
  const isTablet = isMdUp && !isLgUp;
1067
1416
  const [desktopMinimized, setDesktopMinimized] = useLocalStorage(STORAGE_KEY, config.minimized ?? false);
1068
- const [tabletMinimized, setTabletMinimized] = useState3(true);
1069
- const [tabletFor, setTabletFor] = useState3(isTablet);
1417
+ const [tabletMinimized, setTabletMinimized] = useState5(true);
1418
+ const [tabletFor, setTabletFor] = useState5(isTablet);
1070
1419
  if (tabletFor !== isTablet) {
1071
1420
  setTabletFor(isTablet);
1072
1421
  if (isTablet) setTabletMinimized(true);
1073
1422
  }
1074
1423
  const hydrated = useIsHydrated();
1075
1424
  const minimized = hydrated ? isTablet ? tabletMinimized : desktopMinimized : config.minimized ?? false;
1076
- const [transitionsEnabled, setTransitionsEnabled] = useState3(false);
1425
+ const [transitionsEnabled, setTransitionsEnabled] = useState5(false);
1077
1426
  const isOverlayOpen = isTablet && !minimized;
1078
1427
  const showLabel = !minimized;
1079
1428
  const handleToggle = useCallback(() => {
@@ -1087,7 +1436,7 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1087
1436
  const closeOverlay = useCallback(() => {
1088
1437
  setTabletMinimized(true);
1089
1438
  }, []);
1090
- useEffect2(() => {
1439
+ useEffect3(() => {
1091
1440
  if (!isOverlayOpen) return void 0;
1092
1441
  const handleKeyDown = (e) => {
1093
1442
  if (e.key === "Escape") closeOverlay();
@@ -1095,9 +1444,9 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1095
1444
  document.addEventListener("keydown", handleKeyDown);
1096
1445
  return () => document.removeEventListener("keydown", handleKeyDown);
1097
1446
  }, [isOverlayOpen, closeOverlay]);
1098
- const [pendingItemId, setPendingItemId] = useState3(null);
1447
+ const [pendingItemId, setPendingItemId] = useState5(null);
1099
1448
  const committedActiveId = useMemo(() => config.items.find((item) => item.isActive)?.id ?? null, [config.items]);
1100
- const [pendingClearedFor, setPendingClearedFor] = useState3(committedActiveId);
1449
+ const [pendingClearedFor, setPendingClearedFor] = useState5(committedActiveId);
1101
1450
  if (pendingClearedFor !== committedActiveId) {
1102
1451
  setPendingClearedFor(committedActiveId);
1103
1452
  setPendingItemId(null);
@@ -1148,8 +1497,8 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1148
1497
  });
1149
1498
  return () => cancelAnimationFrame(id);
1150
1499
  }, [transitionsEnabled]);
1151
- return /* @__PURE__ */ jsxs11(Fragment6, { children: [
1152
- /* @__PURE__ */ jsx13(
1500
+ return /* @__PURE__ */ jsxs12(Fragment9, { children: [
1501
+ /* @__PURE__ */ jsx14(
1153
1502
  "div",
1154
1503
  {
1155
1504
  className: cn(
@@ -1162,7 +1511,7 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1162
1511
  "aria-hidden": "true"
1163
1512
  }
1164
1513
  ),
1165
- /* @__PURE__ */ jsx13(
1514
+ /* @__PURE__ */ jsx14(
1166
1515
  "div",
1167
1516
  {
1168
1517
  className: cn(
@@ -1173,7 +1522,7 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1173
1522
  "aria-hidden": "true"
1174
1523
  }
1175
1524
  ),
1176
- /* @__PURE__ */ jsxs11(
1525
+ /* @__PURE__ */ jsxs12(
1177
1526
  "aside",
1178
1527
  {
1179
1528
  className: cn(
@@ -1190,11 +1539,11 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1190
1539
  ),
1191
1540
  "aria-label": "Main navigation sidebar",
1192
1541
  children: [
1193
- /* @__PURE__ */ jsx13(NavigationSidebarHeader, { minimized }),
1194
- /* @__PURE__ */ jsxs11("div", { className: "flex flex-1 flex-col justify-between overflow-y-auto py-4", children: [
1195
- /* @__PURE__ */ jsxs11("div", { className: "flex flex-col", children: [
1542
+ /* @__PURE__ */ jsx14(NavigationSidebarHeader, { minimized }),
1543
+ /* @__PURE__ */ jsxs12("div", { className: "flex flex-1 flex-col justify-between overflow-y-auto py-4", children: [
1544
+ /* @__PURE__ */ jsxs12("div", { className: "flex flex-col", children: [
1196
1545
  config.topSlot?.({ minimized }),
1197
- /* @__PURE__ */ jsx13("nav", { className: "flex flex-col", "aria-label": "Primary navigation", "aria-busy": !!loadingRows, children: loadingRows ? loadingRows.primary.map((key) => /* @__PURE__ */ jsx13(NavigationSidebarItemSkeleton, { showLabel }, key)) : primaryItems.map((item) => /* @__PURE__ */ jsx13(
1546
+ /* @__PURE__ */ jsx14("nav", { className: "flex flex-col", "aria-label": "Primary navigation", "aria-busy": !!loadingRows, children: loadingRows ? loadingRows.primary.map((key) => /* @__PURE__ */ jsx14(NavigationSidebarItemSkeleton, { showLabel }, key)) : primaryItems.map((item) => /* @__PURE__ */ jsx14(
1198
1547
  NavigationSidebarItemButton,
1199
1548
  {
1200
1549
  item,
@@ -1207,7 +1556,7 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1207
1556
  item.id
1208
1557
  )) })
1209
1558
  ] }),
1210
- (loadingRows ? loadingRows.secondary.length > 0 : secondaryItems.length > 0) && /* @__PURE__ */ jsx13("nav", { className: "flex flex-col", "aria-label": "Secondary navigation", "aria-busy": !!loadingRows, children: loadingRows ? loadingRows.secondary.map((key) => /* @__PURE__ */ jsx13(NavigationSidebarItemSkeleton, { showLabel }, key)) : secondaryItems.map((item) => /* @__PURE__ */ jsx13(
1559
+ (loadingRows ? loadingRows.secondary.length > 0 : secondaryItems.length > 0) && /* @__PURE__ */ jsx14("nav", { className: "flex flex-col", "aria-label": "Secondary navigation", "aria-busy": !!loadingRows, children: loadingRows ? loadingRows.secondary.map((key) => /* @__PURE__ */ jsx14(NavigationSidebarItemSkeleton, { showLabel }, key)) : secondaryItems.map((item) => /* @__PURE__ */ jsx14(
1211
1560
  NavigationSidebarItemButton,
1212
1561
  {
1213
1562
  item,
@@ -1220,7 +1569,7 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1220
1569
  item.id
1221
1570
  )) })
1222
1571
  ] }),
1223
- /* @__PURE__ */ jsx13(NavigationSidebarToggle, { minimized, showLabel, onToggle: handleToggle })
1572
+ /* @__PURE__ */ jsx14(NavigationSidebarToggle, { minimized, showLabel, onToggle: handleToggle })
1224
1573
  ]
1225
1574
  }
1226
1575
  )
@@ -1228,11 +1577,11 @@ function NavigationSidebar({ config, disabled = false, pushOnTablet = false }) {
1228
1577
  }
1229
1578
 
1230
1579
  // src/components/navigation/app-header.tsx
1231
- import React3 from "react";
1580
+ import React2 from "react";
1232
1581
 
1233
1582
  // src/components/navigation/header-global-search.tsx
1234
- import React2 from "react";
1235
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1583
+ import React from "react";
1584
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1236
1585
  function HeaderGlobalSearch({
1237
1586
  value = "",
1238
1587
  onChange,
@@ -1240,7 +1589,7 @@ function HeaderGlobalSearch({
1240
1589
  placeholder = "Global Search",
1241
1590
  className
1242
1591
  }) {
1243
- const [internalValue, setInternalValue] = React2.useState(value);
1592
+ const [internalValue, setInternalValue] = React.useState(value);
1244
1593
  const currentValue = onChange ? value : internalValue;
1245
1594
  const handleChange = (e) => {
1246
1595
  const newValue = e.target.value;
@@ -1259,7 +1608,7 @@ function HeaderGlobalSearch({
1259
1608
  onSubmit?.(currentValue);
1260
1609
  }
1261
1610
  };
1262
- return /* @__PURE__ */ jsxs12(
1611
+ return /* @__PURE__ */ jsxs13(
1263
1612
  "form",
1264
1613
  {
1265
1614
  onSubmit: handleSubmit,
@@ -1272,8 +1621,8 @@ function HeaderGlobalSearch({
1272
1621
  className
1273
1622
  ),
1274
1623
  children: [
1275
- /* @__PURE__ */ jsx14(SearchIcon, { className: "h-6 w-6 shrink-0 text-ods-text-secondary" }),
1276
- /* @__PURE__ */ jsx14(
1624
+ /* @__PURE__ */ jsx15(SearchIcon, { className: "h-6 w-6 shrink-0 text-ods-text-secondary" }),
1625
+ /* @__PURE__ */ jsx15(
1277
1626
  "input",
1278
1627
  {
1279
1628
  type: "text",
@@ -1295,7 +1644,7 @@ function HeaderGlobalSearch({
1295
1644
  }
1296
1645
 
1297
1646
  // src/components/navigation/header-mingo-button.tsx
1298
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1647
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1299
1648
  function HeaderMingoButton({
1300
1649
  isActive = false,
1301
1650
  iconOnly = false,
@@ -1304,7 +1653,7 @@ function HeaderMingoButton({
1304
1653
  ...props
1305
1654
  }) {
1306
1655
  const showClose = isActive && (iconOnly || closeWhenActive);
1307
- return /* @__PURE__ */ jsxs13(
1656
+ return /* @__PURE__ */ jsxs14(
1308
1657
  "button",
1309
1658
  {
1310
1659
  type: "button",
@@ -1330,11 +1679,11 @@ function HeaderMingoButton({
1330
1679
  // Mobile, drawer open: the icon-only button doubles as the close
1331
1680
  // affordance, so swap the Mingo logo for an X. Match the other header
1332
1681
  // icons (e.g. notifications): secondary color, w-4 h-4 → md:w-6 h-6.
1333
- /* @__PURE__ */ jsx15(XmarkIcon, { className: "h-6 w-6 shrink-0 text-ods-text-secondary" })
1682
+ /* @__PURE__ */ jsx16(XmarkIcon, { className: "h-6 w-6 shrink-0 text-ods-text-secondary" })
1334
1683
  ) : (
1335
1684
  // Outer frame follows the button's text color (currentColor); the eyes
1336
1685
  // and corner block are ODS cyan.
1337
- /* @__PURE__ */ jsx15(
1686
+ /* @__PURE__ */ jsx16(
1338
1687
  MingoIcon,
1339
1688
  {
1340
1689
  color: "currentColor",
@@ -1344,14 +1693,14 @@ function HeaderMingoButton({
1344
1693
  }
1345
1694
  )
1346
1695
  ),
1347
- !iconOnly && /* @__PURE__ */ jsx15("span", { className: "whitespace-nowrap font-bold tracking-[-0.36px] text-h3", children: "Mingo AI" })
1696
+ !iconOnly && /* @__PURE__ */ jsx16("span", { className: "whitespace-nowrap font-bold tracking-[-0.36px] text-h3", children: "Mingo AI" })
1348
1697
  ]
1349
1698
  }
1350
1699
  );
1351
1700
  }
1352
1701
 
1353
1702
  // src/components/navigation/header-organization-filter.tsx
1354
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1703
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1355
1704
  function HeaderOrganizationFilter({
1356
1705
  organizations = [],
1357
1706
  selectedOrgId,
@@ -1362,8 +1711,8 @@ function HeaderOrganizationFilter({
1362
1711
  const selectedOrg = organizations.find((o) => o.id === selectedOrgId);
1363
1712
  const displayName = selectedOrg?.name || "All Organizations";
1364
1713
  const deviceCount = selectedOrg?.deviceCount ?? totalDeviceCount;
1365
- return /* @__PURE__ */ jsxs14(DropdownMenu, { children: [
1366
- /* @__PURE__ */ jsx16(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs14(
1714
+ return /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
1715
+ /* @__PURE__ */ jsx17(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs15(
1367
1716
  "button",
1368
1717
  {
1369
1718
  className: cn(
@@ -1375,10 +1724,10 @@ function HeaderOrganizationFilter({
1375
1724
  className
1376
1725
  ),
1377
1726
  children: [
1378
- /* @__PURE__ */ jsx16(Filter02Icon, { className: "h-4 w-4 shrink-0 text-ods-text-secondary" }),
1379
- /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-col items-start justify-center", children: [
1380
- /* @__PURE__ */ jsx16("span", { className: "truncate text-ods-text-primary text-h5", title: displayName, children: displayName }),
1381
- deviceCount !== void 0 && /* @__PURE__ */ jsxs14("span", { className: "truncate text-ods-text-secondary text-h6", children: [
1727
+ /* @__PURE__ */ jsx17(Filter02Icon, { className: "h-4 w-4 shrink-0 text-ods-text-secondary" }),
1728
+ /* @__PURE__ */ jsxs15("div", { className: "flex min-w-0 flex-col items-start justify-center", children: [
1729
+ /* @__PURE__ */ jsx17("span", { className: "truncate text-ods-text-primary text-h5", title: displayName, children: displayName }),
1730
+ deviceCount !== void 0 && /* @__PURE__ */ jsxs15("span", { className: "truncate text-ods-text-secondary text-h6", children: [
1382
1731
  deviceCount.toLocaleString(),
1383
1732
  " Devices"
1384
1733
  ] })
@@ -1386,16 +1735,49 @@ function HeaderOrganizationFilter({
1386
1735
  ]
1387
1736
  }
1388
1737
  ) }),
1389
- /* @__PURE__ */ jsxs14(DropdownMenuContent, { align: "end", className: "min-w-[240px]", children: [
1390
- /* @__PURE__ */ jsx16(DropdownMenuItem, { onClick: () => onOrgChange?.(""), children: "All Organizations" }),
1391
- organizations.map((org) => /* @__PURE__ */ jsx16(DropdownMenuItem, { onClick: () => onOrgChange?.(org.id), children: org.name }, org.id))
1738
+ /* @__PURE__ */ jsxs15(DropdownMenuContent, { align: "end", className: "min-w-[240px]", children: [
1739
+ /* @__PURE__ */ jsx17(DropdownMenuItem, { onClick: () => onOrgChange?.(""), children: "All Organizations" }),
1740
+ organizations.map((org) => /* @__PURE__ */ jsx17(DropdownMenuItem, { onClick: () => onOrgChange?.(org.id), children: org.name }, org.id))
1392
1741
  ] })
1393
1742
  ] });
1394
1743
  }
1395
1744
 
1745
+ // src/components/navigation/ticket-alerts-button.tsx
1746
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
1747
+ function TicketAlertsButton({ href, onNavigate, disabled, className }) {
1748
+ const live = useOptionalTicketLive();
1749
+ if (!live || !live.authed || live.unreadTotal === 0) return null;
1750
+ const targetId = live.nextUnreadTicketId;
1751
+ const target = targetId ? buildTicketOpenHref(href, targetId) : href;
1752
+ const handleClick = () => {
1753
+ if (onNavigate) onNavigate(target);
1754
+ else window.location.assign(target);
1755
+ };
1756
+ return /* @__PURE__ */ jsx18(
1757
+ HeaderButton,
1758
+ {
1759
+ icon: (
1760
+ // Glyph inherits HeaderButton's standard cell coloring (secondary at
1761
+ // rest, primary on active) — SAME treatment as the notifications
1762
+ // bell and time-tracker cells. The indication is carried by the
1763
+ // count pill (sidebar count-pill precedent) and by the cell only
1764
+ // existing while updates are unread — never by tinting the glyph.
1765
+ /* @__PURE__ */ jsxs16("span", { className: "relative inline-flex", children: [
1766
+ /* @__PURE__ */ jsx18(LifeBuoyIcon, { className: "h-6 w-6" }),
1767
+ /* @__PURE__ */ jsx18(UnreadCountBadge, { count: live.unreadTotal })
1768
+ ] })
1769
+ ),
1770
+ "aria-label": `Support tickets \u2014 ${live.unreadTotal} unread ${live.unreadTotal === 1 ? "update" : "updates"}`,
1771
+ onClick: handleClick,
1772
+ disabled,
1773
+ className: cn(className)
1774
+ }
1775
+ );
1776
+ }
1777
+
1396
1778
  // src/components/navigation/app-header.tsx
1397
- import { Fragment as Fragment7, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1398
- var AppHeader = React3.memo(function AppHeaderImpl({
1779
+ import { Fragment as Fragment10, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
1780
+ var AppHeader = React2.memo(function AppHeaderImpl({
1399
1781
  showSearch,
1400
1782
  onSearch,
1401
1783
  showOrganizations,
@@ -1427,7 +1809,7 @@ var AppHeader = React3.memo(function AppHeaderImpl({
1427
1809
  }) {
1428
1810
  const isMdUp = useMdUp() ?? false;
1429
1811
  if (loading) {
1430
- return /* @__PURE__ */ jsx17(
1812
+ return /* @__PURE__ */ jsx19(
1431
1813
  AppHeaderSkeleton,
1432
1814
  {
1433
1815
  showSearch,
@@ -1450,27 +1832,27 @@ var AppHeader = React3.memo(function AppHeaderImpl({
1450
1832
  }
1451
1833
  const dimmedClass = disabled ? "pointer-events-none opacity-50" : "";
1452
1834
  const cellDivider = "border-l border-ods-border";
1453
- return /* @__PURE__ */ jsx17(
1835
+ return /* @__PURE__ */ jsx19(
1454
1836
  TopNavigation,
1455
1837
  {
1456
1838
  className: cn("sticky top-0 z-40", className),
1457
1839
  centerBreakpoint: "md",
1458
1840
  leading: (
1459
1841
  // Mobile: Burger Menu Button
1460
- !isMdUp && /* @__PURE__ */ jsx17(
1842
+ !isMdUp && /* @__PURE__ */ jsx19(
1461
1843
  HeaderButton,
1462
1844
  {
1463
1845
  onClick: onToggleMobileMenu,
1464
1846
  isActive: isMobileMenuOpen,
1465
- icon: isMobileMenuOpen ? /* @__PURE__ */ jsx17(XmarkIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx17(Menu01Icon, { className: "h-6 w-6" }),
1847
+ icon: isMobileMenuOpen ? /* @__PURE__ */ jsx19(XmarkIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx19(Menu01Icon, { className: "h-6 w-6" }),
1466
1848
  "aria-label": isMobileMenuOpen ? "Close menu" : "Open menu",
1467
1849
  "aria-expanded": isMobileMenuOpen,
1468
1850
  className: "border-r border-ods-border"
1469
1851
  }
1470
1852
  )
1471
1853
  ),
1472
- logo: !isMdUp && /* @__PURE__ */ jsxs15(Fragment7, { children: [
1473
- /* @__PURE__ */ jsx17(
1854
+ logo: !isMdUp && /* @__PURE__ */ jsxs17(Fragment10, { children: [
1855
+ /* @__PURE__ */ jsx19(
1474
1856
  OpenFrameLogo,
1475
1857
  {
1476
1858
  className: "h-6 w-6 shrink-0",
@@ -1478,21 +1860,21 @@ var AppHeader = React3.memo(function AppHeaderImpl({
1478
1860
  lowerPathColor: "var(--color-accent-primary)"
1479
1861
  }
1480
1862
  ),
1481
- /* @__PURE__ */ jsx17(OpenFrameText, { textColor: "var(--color-text-primary)", className: "h-4" })
1863
+ /* @__PURE__ */ jsx19(OpenFrameText, { textColor: "var(--color-text-primary)", className: "h-4" })
1482
1864
  ] }),
1483
1865
  logoClassName: "gap-2",
1484
- center: showSearch ? /* @__PURE__ */ jsx17(HeaderGlobalSearch, { onSubmit: onSearch, className: cn("w-full", dimmedClass) }) : void 0,
1485
- sideActions: /* @__PURE__ */ jsxs15(Fragment7, { children: [
1486
- showSearch && /* @__PURE__ */ jsx17(
1866
+ center: showSearch ? /* @__PURE__ */ jsx19(HeaderGlobalSearch, { onSubmit: onSearch, className: cn("w-full", dimmedClass) }) : void 0,
1867
+ sideActions: /* @__PURE__ */ jsxs17(Fragment10, { children: [
1868
+ showSearch && /* @__PURE__ */ jsx19(
1487
1869
  HeaderButton,
1488
1870
  {
1489
- icon: /* @__PURE__ */ jsx17(SearchIcon, { className: "h-6 w-6" }),
1871
+ icon: /* @__PURE__ */ jsx19(SearchIcon, { className: "h-6 w-6" }),
1490
1872
  "aria-label": "Search",
1491
1873
  className: cn("md:hidden", cellDivider, dimmedClass),
1492
1874
  disabled
1493
1875
  }
1494
1876
  ),
1495
- showOrganizations && /* @__PURE__ */ jsx17(
1877
+ showOrganizations && /* @__PURE__ */ jsx19(
1496
1878
  HeaderOrganizationFilter,
1497
1879
  {
1498
1880
  organizations,
@@ -1501,8 +1883,8 @@ var AppHeader = React3.memo(function AppHeaderImpl({
1501
1883
  className: cn("hidden lg:flex", dimmedClass)
1502
1884
  }
1503
1885
  ),
1504
- showTimeTracker && /* @__PURE__ */ jsx17(TimeTrackerHeaderButton, { disabled, className: cn(cellDivider, dimmedClass) }),
1505
- showNotifications && /* @__PURE__ */ jsx17(
1886
+ showTimeTracker && /* @__PURE__ */ jsx19(TimeTrackerHeaderButton, { disabled, className: cn(cellDivider, dimmedClass) }),
1887
+ showNotifications && /* @__PURE__ */ jsx19(
1506
1888
  NotificationsHeaderButton,
1507
1889
  {
1508
1890
  fallbackUnreadCount: unreadCount,
@@ -1510,7 +1892,7 @@ var AppHeader = React3.memo(function AppHeaderImpl({
1510
1892
  dimmedClass: cn(cellDivider, dimmedClass)
1511
1893
  }
1512
1894
  ),
1513
- showTicketAlerts && /* @__PURE__ */ jsx17(
1895
+ showTicketAlerts && /* @__PURE__ */ jsx19(
1514
1896
  TicketAlertsButton,
1515
1897
  {
1516
1898
  href: ticketAlertsHref ?? "/tickets",
@@ -1519,11 +1901,11 @@ var AppHeader = React3.memo(function AppHeaderImpl({
1519
1901
  className: cn(cellDivider, dimmedClass)
1520
1902
  }
1521
1903
  ),
1522
- isMdUp && showUser && /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
1523
- /* @__PURE__ */ jsx17(DropdownMenuTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsx17(
1904
+ isMdUp && showUser && /* @__PURE__ */ jsxs17(DropdownMenu, { children: [
1905
+ /* @__PURE__ */ jsx19(DropdownMenuTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsx19(
1524
1906
  HeaderButton,
1525
1907
  {
1526
- icon: /* @__PURE__ */ jsx17(
1908
+ icon: /* @__PURE__ */ jsx19(
1527
1909
  SquareAvatar,
1528
1910
  {
1529
1911
  src: userAvatarUrl || void 0,
@@ -1542,14 +1924,14 @@ var AppHeader = React3.memo(function AppHeaderImpl({
1542
1924
  )
1543
1925
  }
1544
1926
  ) }),
1545
- /* @__PURE__ */ jsxs15(
1927
+ /* @__PURE__ */ jsxs17(
1546
1928
  DropdownMenuContent,
1547
1929
  {
1548
1930
  align: "end",
1549
1931
  className: "z-[104] w-[280px] overflow-hidden rounded-[6px] border-ods-border bg-ods-bg p-0",
1550
1932
  children: [
1551
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 border-b border-ods-border bg-ods-card p-3", children: [
1552
- /* @__PURE__ */ jsx17(
1933
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2 border-b border-ods-border bg-ods-card p-3", children: [
1934
+ /* @__PURE__ */ jsx19(
1553
1935
  SquareAvatar,
1554
1936
  {
1555
1937
  src: userAvatarUrl || void 0,
@@ -1559,30 +1941,30 @@ var AppHeader = React3.memo(function AppHeaderImpl({
1559
1941
  className: "shrink-0"
1560
1942
  }
1561
1943
  ),
1562
- /* @__PURE__ */ jsxs15("div", { className: "min-w-0 flex-1", children: [
1563
- userName && /* @__PURE__ */ jsx17("div", { className: "truncate text-ods-text-primary text-h4", children: userName }),
1564
- userEmail && /* @__PURE__ */ jsx17("div", { className: "truncate text-ods-text-secondary text-h6", children: userEmail })
1944
+ /* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1", children: [
1945
+ userName && /* @__PURE__ */ jsx19("div", { className: "truncate text-ods-text-primary text-h4", children: userName }),
1946
+ userEmail && /* @__PURE__ */ jsx19("div", { className: "truncate text-ods-text-secondary text-h6", children: userEmail })
1565
1947
  ] })
1566
1948
  ] }),
1567
- /* @__PURE__ */ jsx17(
1949
+ /* @__PURE__ */ jsx19(
1568
1950
  DropdownMenuItem,
1569
1951
  {
1570
1952
  onClick: onProfile,
1571
1953
  className: "cursor-pointer rounded-none border-b border-ods-border bg-ods-card px-3 py-3 hover:bg-ods-card/80 focus:bg-ods-card/80",
1572
- children: /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
1573
- /* @__PURE__ */ jsx17(UserIcon, { className: "h-6 w-6 shrink-0 text-ods-text-primary" }),
1574
- /* @__PURE__ */ jsx17("span", { className: "text-ods-text-primary text-h4", children: "Profile Settings" })
1954
+ children: /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
1955
+ /* @__PURE__ */ jsx19(UserIcon, { className: "h-6 w-6 shrink-0 text-ods-text-primary" }),
1956
+ /* @__PURE__ */ jsx19("span", { className: "text-ods-text-primary text-h4", children: "Profile Settings" })
1575
1957
  ] })
1576
1958
  }
1577
1959
  ),
1578
- /* @__PURE__ */ jsx17(
1960
+ /* @__PURE__ */ jsx19(
1579
1961
  DropdownMenuItem,
1580
1962
  {
1581
1963
  onClick: onLogout,
1582
1964
  className: "cursor-pointer rounded-none bg-ods-card px-3 py-3 hover:bg-ods-card/80 focus:bg-ods-card/80",
1583
- children: /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
1584
- /* @__PURE__ */ jsx17(LogOutIcon, { className: "shrink-0 text-ods-error", size: 24 }),
1585
- /* @__PURE__ */ jsx17("span", { className: "text-ods-text-primary text-h4", children: "Log Out" })
1965
+ children: /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
1966
+ /* @__PURE__ */ jsx19(LogOutIcon, { className: "shrink-0 text-ods-error", size: 24 }),
1967
+ /* @__PURE__ */ jsx19("span", { className: "text-ods-text-primary text-h4", children: "Log Out" })
1586
1968
  ] })
1587
1969
  }
1588
1970
  )
@@ -1590,7 +1972,7 @@ var AppHeader = React3.memo(function AppHeaderImpl({
1590
1972
  }
1591
1973
  )
1592
1974
  ] }),
1593
- showMingoAI && /* @__PURE__ */ jsx17(
1975
+ showMingoAI && /* @__PURE__ */ jsx19(
1594
1976
  HeaderMingoButton,
1595
1977
  {
1596
1978
  onClick: onMingoAI,
@@ -1610,10 +1992,10 @@ function NotificationsHeaderButton({ fallbackUnreadCount, disabled, dimmedClass
1610
1992
  const hasUnread = (ctx?.unreadCount ?? fallbackUnreadCount) > 0;
1611
1993
  const isActive = ctx?.isOpen ?? false;
1612
1994
  const onClick = ctx?.toggle;
1613
- return /* @__PURE__ */ jsx17(
1995
+ return /* @__PURE__ */ jsx19(
1614
1996
  HeaderButton,
1615
1997
  {
1616
- icon: isActive ? /* @__PURE__ */ jsx17(XmarkIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx17(BellIcon, { className: "h-6 w-6" }),
1998
+ icon: isActive ? /* @__PURE__ */ jsx19(XmarkIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx19(BellIcon, { className: "h-6 w-6" }),
1617
1999
  showUnreadDot: !isActive && hasUnread,
1618
2000
  "aria-label": isActive ? "Close notifications" : "Notifications",
1619
2001
  onClick,
@@ -1629,12 +2011,12 @@ var CELL_VISIBILITY = {
1629
2011
  "icon-lg": "hidden lg:flex"
1630
2012
  };
1631
2013
  function HeaderCellSkeleton({ className }) {
1632
- return /* @__PURE__ */ jsx17("div", { className: cn("flex h-full w-14 shrink-0 items-center justify-center border-l border-ods-border", className), children: /* @__PURE__ */ jsx17("div", { className: "h-6 w-6 animate-pulse rounded bg-ods-border" }) });
2014
+ return /* @__PURE__ */ jsx19("div", { className: cn("flex h-full w-14 shrink-0 items-center justify-center border-l border-ods-border", className), children: /* @__PURE__ */ jsx19("div", { className: "h-6 w-6 animate-pulse rounded bg-ods-border" }) });
1633
2015
  }
1634
2016
  function HeaderWideCellSkeleton() {
1635
- return /* @__PURE__ */ jsxs15("div", { className: "flex h-full w-14 shrink-0 items-center justify-center gap-2 border-l border-ods-border md:w-[140px] md:px-4", children: [
1636
- /* @__PURE__ */ jsx17("div", { className: "h-6 w-6 shrink-0 animate-pulse rounded bg-ods-border" }),
1637
- /* @__PURE__ */ jsx17("div", { className: "hidden h-5 animate-pulse rounded bg-ods-border md:block md:w-[72px]" })
2017
+ return /* @__PURE__ */ jsxs17("div", { className: "flex h-full w-14 shrink-0 items-center justify-center gap-2 border-l border-ods-border md:w-[140px] md:px-4", children: [
2018
+ /* @__PURE__ */ jsx19("div", { className: "h-6 w-6 shrink-0 animate-pulse rounded bg-ods-border" }),
2019
+ /* @__PURE__ */ jsx19("div", { className: "hidden h-5 animate-pulse rounded bg-ods-border md:block md:w-[72px]" })
1638
2020
  ] });
1639
2021
  }
1640
2022
  function AppHeaderSkeleton({
@@ -1643,7 +2025,7 @@ function AppHeaderSkeleton({
1643
2025
  className
1644
2026
  }) {
1645
2027
  const cells = typeof actionCells === "number" ? Array.from({ length: Math.max(0, actionCells) }, () => "icon") : actionCells;
1646
- return /* @__PURE__ */ jsx17(
2028
+ return /* @__PURE__ */ jsx19(
1647
2029
  TopNavigation,
1648
2030
  {
1649
2031
  className: cn("sticky top-0 z-40", className),
@@ -1651,18 +2033,18 @@ function AppHeaderSkeleton({
1651
2033
  "aria-busy": "true",
1652
2034
  leading: (
1653
2035
  // Burger cell: mobile only, in CSS.
1654
- /* @__PURE__ */ jsx17("div", { className: "flex h-full w-14 shrink-0 items-center justify-center border-r border-ods-border md:hidden", children: /* @__PURE__ */ jsx17("div", { className: "h-6 w-6 animate-pulse rounded bg-ods-border" }) })
2036
+ /* @__PURE__ */ jsx19("div", { className: "flex h-full w-14 shrink-0 items-center justify-center border-r border-ods-border md:hidden", children: /* @__PURE__ */ jsx19("div", { className: "h-6 w-6 animate-pulse rounded bg-ods-border" }) })
1655
2037
  ),
1656
- logo: /* @__PURE__ */ jsxs15(Fragment7, { children: [
1657
- /* @__PURE__ */ jsx17("div", { className: "h-6 w-6 shrink-0 animate-pulse rounded bg-ods-border" }),
1658
- /* @__PURE__ */ jsx17("div", { className: "h-4 w-24 animate-pulse rounded bg-ods-border" })
2038
+ logo: /* @__PURE__ */ jsxs17(Fragment10, { children: [
2039
+ /* @__PURE__ */ jsx19("div", { className: "h-6 w-6 shrink-0 animate-pulse rounded bg-ods-border" }),
2040
+ /* @__PURE__ */ jsx19("div", { className: "h-4 w-24 animate-pulse rounded bg-ods-border" })
1659
2041
  ] }),
1660
2042
  logoClassName: "gap-2 md:hidden",
1661
- center: showSearch ? /* @__PURE__ */ jsx17("div", { className: "h-10 w-full animate-pulse rounded-md bg-ods-border" }) : void 0,
1662
- sideActions: /* @__PURE__ */ jsxs15(Fragment7, { children: [
1663
- showSearch && /* @__PURE__ */ jsx17(HeaderCellSkeleton, { className: "md:hidden" }),
2043
+ center: showSearch ? /* @__PURE__ */ jsx19("div", { className: "h-10 w-full animate-pulse rounded-md bg-ods-border" }) : void 0,
2044
+ sideActions: /* @__PURE__ */ jsxs17(Fragment10, { children: [
2045
+ showSearch && /* @__PURE__ */ jsx19(HeaderCellSkeleton, { className: "md:hidden" }),
1664
2046
  cells.map(
1665
- (cell, i) => cell === "wide" ? /* @__PURE__ */ jsx17(HeaderWideCellSkeleton, {}, i) : /* @__PURE__ */ jsx17(HeaderCellSkeleton, { className: CELL_VISIBILITY[cell] }, i)
2047
+ (cell, i) => cell === "wide" ? /* @__PURE__ */ jsx19(HeaderWideCellSkeleton, {}, i) : /* @__PURE__ */ jsx19(HeaderCellSkeleton, { className: CELL_VISIBILITY[cell] }, i)
1666
2048
  )
1667
2049
  ] })
1668
2050
  }
@@ -1670,17 +2052,17 @@ function AppHeaderSkeleton({
1670
2052
  }
1671
2053
 
1672
2054
  // src/components/navigation/app-layout.tsx
1673
- import { useCallback as useCallback3, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef6, useState as useState5 } from "react";
2055
+ import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo2, useRef as useRef6, useState as useState7 } from "react";
1674
2056
 
1675
2057
  // src/components/navigation/app-layout-side-panel.tsx
1676
2058
  import {
1677
- useEffect as useEffect3,
2059
+ useEffect as useEffect4,
1678
2060
  useId,
1679
2061
  useRef as useRef4,
1680
- useState as useState4,
2062
+ useState as useState6,
1681
2063
  useSyncExternalStore
1682
2064
  } from "react";
1683
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
2065
+ import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
1684
2066
  var SIDE_PANEL_INSET = 16;
1685
2067
  var SIDE_PANEL_FRAME_WIDTH = 2;
1686
2068
  var MOBILE_QUERY = `not all and ${breakpoints.md}`;
@@ -1741,7 +2123,7 @@ function useStoredSize(storageKey, fallback) {
1741
2123
  },
1742
2124
  () => null
1743
2125
  );
1744
- const [sessionSize, setSessionSize] = useState4(null);
2126
+ const [sessionSize, setSessionSize] = useState6(null);
1745
2127
  const size = (storageKey ? parseSize(raw) : sessionSize) ?? fallback;
1746
2128
  const setSize = (next) => {
1747
2129
  if (!storageKey) {
@@ -1764,7 +2146,7 @@ function useAppLayoutSidePanel(config, row) {
1764
2146
  const collapsed = config?.collapsed ?? false;
1765
2147
  const minimum = { width: minWidth, expanded: false };
1766
2148
  const defaultWidth = Math.max(minWidth, config?.defaultWidth ?? minWidth);
1767
- const [rowWidth, setRowWidth] = useState4(0);
2149
+ const [rowWidth, setRowWidth] = useState6(0);
1768
2150
  useIsomorphicLayoutEffect(() => {
1769
2151
  if (!enabled || !row) return void 0;
1770
2152
  const update = () => setRowWidth(row.clientWidth);
@@ -1775,18 +2157,18 @@ function useAppLayoutSidePanel(config, row) {
1775
2157
  }, [enabled, row]);
1776
2158
  const isMobile = useMediaQuery(MOBILE_QUERY) === true;
1777
2159
  const reduceMotion = useMediaQuery(REDUCED_MOTION_QUERY) === true;
1778
- const [morph, setMorph] = useState4(null);
1779
- const [liveWidth, setLiveWidth] = useState4(null);
2160
+ const [morph, setMorph] = useState6(null);
2161
+ const [liveWidth, setLiveWidth] = useState6(null);
1780
2162
  const [storedSize, setStoredSize] = useStoredSize(config?.storageKey, { width: defaultWidth, expanded: false });
1781
- const [ownIsOpen, setOwnIsOpen] = useState4(false);
2163
+ const [ownIsOpen, setOwnIsOpen] = useState6(false);
1782
2164
  const isOpen = config?.open ?? ownIsOpen;
1783
2165
  const onOpenChange = config?.onOpenChange;
1784
2166
  const setIsOpen = (next) => {
1785
2167
  if (config?.open === void 0) setOwnIsOpen(next);
1786
2168
  onOpenChange?.(next);
1787
2169
  };
1788
- const [collapsedSize, setCollapsedSize] = useState4(null);
1789
- const [prevCollapsed, setPrevCollapsed] = useState4(collapsed);
2170
+ const [collapsedSize, setCollapsedSize] = useState6(null);
2171
+ const [prevCollapsed, setPrevCollapsed] = useState6(collapsed);
1790
2172
  if (collapsed !== prevCollapsed) {
1791
2173
  setPrevCollapsed(collapsed);
1792
2174
  setCollapsedSize(null);
@@ -1794,13 +2176,13 @@ function useAppLayoutSidePanel(config, row) {
1794
2176
  const size = collapsed ? collapsedSize ?? minimum : storedSize;
1795
2177
  const setSize = collapsed ? setCollapsedSize : setStoredSize;
1796
2178
  const layout = resolveSidePanelLayout({ rowWidth, isMobile, isOpen, size, minWidth, minContentWidth });
1797
- const [prevCanDock, setPrevCanDock] = useState4(layout.canDock);
2179
+ const [prevCanDock, setPrevCanDock] = useState6(layout.canDock);
1798
2180
  if (layout.canDock !== prevCanDock) {
1799
2181
  setPrevCanDock(layout.canDock);
1800
2182
  setOwnIsOpen(false);
1801
2183
  }
1802
2184
  const prevCanDockRef = useRef4(layout.canDock);
1803
- useEffect3(() => {
2185
+ useEffect4(() => {
1804
2186
  const couldDock = prevCanDockRef.current;
1805
2187
  prevCanDockRef.current = layout.canDock;
1806
2188
  if (!couldDock && layout.canDock && config?.open) onOpenChange?.(false);
@@ -1883,7 +2265,7 @@ function SidePanelResizeHandle({ state, label, controls }) {
1883
2265
  const pendingRef = useRef4(null);
1884
2266
  const measured = Number.isFinite(maxDockedWidth);
1885
2267
  const current = peekWidth ?? (mode === "full" && measured ? maxDockedWidth + 1 : width);
1886
- useEffect3(
2268
+ useEffect4(
1887
2269
  () => () => {
1888
2270
  if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);
1889
2271
  },
@@ -1940,7 +2322,7 @@ function SidePanelResizeHandle({ state, label, controls }) {
1940
2322
  event.preventDefault();
1941
2323
  resize(next);
1942
2324
  };
1943
- return /* @__PURE__ */ jsx18(
2325
+ return /* @__PURE__ */ jsx20(
1944
2326
  "div",
1945
2327
  {
1946
2328
  role: "separator",
@@ -1958,12 +2340,12 @@ function SidePanelResizeHandle({ state, label, controls }) {
1958
2340
  onPointerCancel: endDrag,
1959
2341
  onKeyDown: handleKeyDown,
1960
2342
  className: "group absolute inset-y-0 left-0 z-10 flex w-4 -translate-x-1/2 cursor-col-resize touch-none select-none items-center justify-center outline-none",
1961
- children: /* @__PURE__ */ jsx18(
2343
+ children: /* @__PURE__ */ jsx20(
1962
2344
  "span",
1963
2345
  {
1964
2346
  "aria-hidden": true,
1965
2347
  className: "flex h-8 w-4 items-center justify-center rounded-sm border border-ods-border bg-ods-card text-ods-text-secondary transition-colors group-hover:border-ods-border-hover group-focus-visible:border-ods-accent group-focus-visible:text-ods-accent",
1966
- children: /* @__PURE__ */ jsx18(Menu01Icon, { size: 12 })
2348
+ children: /* @__PURE__ */ jsx20(Menu01Icon, { size: 12 })
1967
2349
  }
1968
2350
  )
1969
2351
  }
@@ -1972,7 +2354,7 @@ function SidePanelResizeHandle({ state, label, controls }) {
1972
2354
  function AppLayoutSidePanel({ config, state }) {
1973
2355
  const panelId = useId();
1974
2356
  const { mode, width, dockedWidth, canDock, isOpen, close, morph, endMorph, peekWidth } = state;
1975
- useEffect3(() => {
2357
+ useEffect4(() => {
1976
2358
  if (!morph) return void 0;
1977
2359
  const timer = window.setTimeout(endMorph, MORPH_MS * 3);
1978
2360
  return () => window.clearTimeout(timer);
@@ -1985,7 +2367,7 @@ function AppLayoutSidePanel({ config, state }) {
1985
2367
  event.preventDefault();
1986
2368
  close();
1987
2369
  };
1988
- return /* @__PURE__ */ jsx18(
2370
+ return /* @__PURE__ */ jsx20(
1989
2371
  "aside",
1990
2372
  {
1991
2373
  id: panelId,
@@ -2003,7 +2385,7 @@ function AppLayoutSidePanel({ config, state }) {
2003
2385
  mode === "overlay" && "absolute inset-0 z-[99] bg-ods-bg"
2004
2386
  ),
2005
2387
  style: mode !== "overlay" && inColumn ? { width: dockedWidth + SIDE_PANEL_INSET } : void 0,
2006
- children: /* @__PURE__ */ jsxs16(
2388
+ children: /* @__PURE__ */ jsxs18(
2007
2389
  "div",
2008
2390
  {
2009
2391
  onTransitionEnd: (event) => {
@@ -2019,8 +2401,8 @@ function AppLayoutSidePanel({ config, state }) {
2019
2401
  ),
2020
2402
  style: mode === "overlay" ? void 0 : { width: peekWidth ?? width },
2021
2403
  children: [
2022
- canDock && /* @__PURE__ */ jsx18(SidePanelResizeHandle, { state, label: `Resize ${label}`, controls: panelId }),
2023
- /* @__PURE__ */ jsx18(
2404
+ canDock && /* @__PURE__ */ jsx20(SidePanelResizeHandle, { state, label: `Resize ${label}`, controls: panelId }),
2405
+ /* @__PURE__ */ jsx20(
2024
2406
  "div",
2025
2407
  {
2026
2408
  className: cn(
@@ -2048,10 +2430,10 @@ function AppLayoutSidePanel({ config, state }) {
2048
2430
 
2049
2431
  // src/components/navigation/mobile-burger-menu.tsx
2050
2432
  import { usePreventScroll as usePreventScroll3 } from "@react-aria/overlays";
2051
- import React4, { useCallback as useCallback2, useRef as useRef5 } from "react";
2052
- import { Fragment as Fragment8, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
2433
+ import React3, { useCallback as useCallback2, useRef as useRef5 } from "react";
2434
+ import { Fragment as Fragment11, jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
2053
2435
  var HEADER_HEIGHT = 56;
2054
- var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2436
+ var MobileBurgerMenu = React3.memo(function MobileBurgerMenuImpl({
2055
2437
  isOpen,
2056
2438
  onClose,
2057
2439
  config,
@@ -2079,7 +2461,7 @@ var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2079
2461
  const secondaryItems = config.items.filter((item) => item.section === "secondary");
2080
2462
  const renderNavigationItem = (item, isGridItem = false) => {
2081
2463
  const isActive = item.isActive ?? false;
2082
- return /* @__PURE__ */ jsxs17(
2464
+ return /* @__PURE__ */ jsxs19(
2083
2465
  "button",
2084
2466
  {
2085
2467
  onClick: () => handleItemClick(item),
@@ -2099,12 +2481,12 @@ var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2099
2481
  "aria-current": isActive ? "page" : void 0,
2100
2482
  "aria-label": item.badge ? `${item.label} (${item.badge})` : void 0,
2101
2483
  children: [
2102
- item.icon && /* @__PURE__ */ jsx19("div", { className: "flex size-4 flex-shrink-0 items-center justify-center", children: React4.cloneElement(item.icon, {
2484
+ item.icon && /* @__PURE__ */ jsx21("div", { className: "flex size-4 flex-shrink-0 items-center justify-center", children: React3.cloneElement(item.icon, {
2103
2485
  size: 16,
2104
2486
  color: isActive && !disabled ? "var(--color-accent-primary)" : "var(--color-text-secondary)"
2105
2487
  }) }),
2106
- /* @__PURE__ */ jsxs17("span", { className: "flex min-w-0 flex-1 items-center gap-[var(--spacing-system-xxs)]", children: [
2107
- /* @__PURE__ */ jsx19(
2488
+ /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 flex-1 items-center gap-[var(--spacing-system-xxs)]", children: [
2489
+ /* @__PURE__ */ jsx21(
2108
2490
  "span",
2109
2491
  {
2110
2492
  className: cn(
@@ -2114,16 +2496,16 @@ var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2114
2496
  children: item.label
2115
2497
  }
2116
2498
  ),
2117
- item.badge && /* @__PURE__ */ jsx19(NavigationItemBadge, { compact: true, label: item.badge })
2499
+ item.badge && /* @__PURE__ */ jsx21(NavigationItemBadge, { compact: true, label: item.badge })
2118
2500
  ] })
2119
2501
  ]
2120
2502
  },
2121
2503
  item.id
2122
2504
  );
2123
2505
  };
2124
- const renderNavigationGrid = (items) => /* @__PURE__ */ jsx19("div", { className: "grid grid-cols-2 gap-3", children: items.map((item) => /* @__PURE__ */ jsx19(React4.Fragment, { children: renderNavigationItem(item, true) }, item.id)) });
2125
- return /* @__PURE__ */ jsxs17(Fragment8, { children: [
2126
- /* @__PURE__ */ jsx19(
2506
+ const renderNavigationGrid = (items) => /* @__PURE__ */ jsx21("div", { className: "grid grid-cols-2 gap-3", children: items.map((item) => /* @__PURE__ */ jsx21(React3.Fragment, { children: renderNavigationItem(item, true) }, item.id)) });
2507
+ return /* @__PURE__ */ jsxs19(Fragment11, { children: [
2508
+ /* @__PURE__ */ jsx21(
2127
2509
  "div",
2128
2510
  {
2129
2511
  className: cn(
@@ -2137,7 +2519,7 @@ var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2137
2519
  "aria-hidden": "true"
2138
2520
  }
2139
2521
  ),
2140
- /* @__PURE__ */ jsx19(
2522
+ /* @__PURE__ */ jsx21(
2141
2523
  "div",
2142
2524
  {
2143
2525
  ref: panelRef,
@@ -2158,8 +2540,8 @@ var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2158
2540
  "aria-label": "Mobile navigation menu",
2159
2541
  tabIndex: -1,
2160
2542
  inert: !isOpen || void 0,
2161
- children: /* @__PURE__ */ jsxs17("div", { className: "flex flex-1 flex-col gap-4 overflow-y-auto overflow-x-hidden overscroll-contain p-4", children: [
2162
- user && /* @__PURE__ */ jsxs17(
2543
+ children: /* @__PURE__ */ jsxs19("div", { className: "flex flex-1 flex-col gap-4 overflow-y-auto overflow-x-hidden overscroll-contain p-4", children: [
2544
+ user && /* @__PURE__ */ jsxs19(
2163
2545
  "div",
2164
2546
  {
2165
2547
  className: cn(
@@ -2168,7 +2550,7 @@ var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2168
2550
  ),
2169
2551
  "aria-disabled": disabled || void 0,
2170
2552
  children: [
2171
- /* @__PURE__ */ jsx19(
2553
+ /* @__PURE__ */ jsx21(
2172
2554
  SquareAvatar,
2173
2555
  {
2174
2556
  src: user.userAvatarUrl || void 0,
@@ -2179,24 +2561,24 @@ var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2179
2561
  className: "h-14 w-14 shrink-0"
2180
2562
  }
2181
2563
  ),
2182
- /* @__PURE__ */ jsxs17("div", { className: "flex min-w-0 flex-1 flex-col", children: [
2183
- /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
2184
- /* @__PURE__ */ jsx19("span", { className: "truncate text-ods-text-primary text-h6", children: user.userName || "User" }),
2185
- user.userRole && /* @__PURE__ */ jsx19("span", { className: "shrink-0 rounded-md border border-ods-border bg-ods-card px-2 py-0.5 uppercase text-ods-text-primary text-h6", children: user.userRole })
2564
+ /* @__PURE__ */ jsxs19("div", { className: "flex min-w-0 flex-1 flex-col", children: [
2565
+ /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
2566
+ /* @__PURE__ */ jsx21("span", { className: "truncate text-ods-text-primary text-h6", children: user.userName || "User" }),
2567
+ user.userRole && /* @__PURE__ */ jsx21("span", { className: "shrink-0 rounded-md border border-ods-border bg-ods-card px-2 py-0.5 uppercase text-ods-text-primary text-h6", children: user.userRole })
2186
2568
  ] }),
2187
- user.userEmail && /* @__PURE__ */ jsx19("span", { className: "truncate text-ods-text-secondary text-h6", children: user.userEmail })
2569
+ user.userEmail && /* @__PURE__ */ jsx21("span", { className: "truncate text-ods-text-secondary text-h6", children: user.userEmail })
2188
2570
  ] }),
2189
- /* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-2", children: [
2190
- onSearchUser && /* @__PURE__ */ jsx19(Button, { size: "icon", onClick: onSearchUser, variant: "outline", "aria-label": "Search users", children: /* @__PURE__ */ jsx19(UserSearchIcon, { className: "size-4 text-ods-text-primary" }) }),
2191
- onEditProfile && /* @__PURE__ */ jsx19(Button, { size: "icon", onClick: onEditProfile, variant: "outline", "aria-label": "Edit profile", children: /* @__PURE__ */ jsx19(PenEditIcon, { className: "size-4 text-ods-text-primary" }) })
2571
+ /* @__PURE__ */ jsxs19("div", { className: "flex shrink-0 items-center gap-2", children: [
2572
+ onSearchUser && /* @__PURE__ */ jsx21(Button, { size: "icon", onClick: onSearchUser, variant: "outline", "aria-label": "Search users", children: /* @__PURE__ */ jsx21(UserSearchIcon, { className: "size-4 text-ods-text-primary" }) }),
2573
+ onEditProfile && /* @__PURE__ */ jsx21(Button, { size: "icon", onClick: onEditProfile, variant: "outline", "aria-label": "Edit profile", children: /* @__PURE__ */ jsx21(PenEditIcon, { className: "size-4 text-ods-text-primary" }) })
2192
2574
  ] })
2193
2575
  ]
2194
2576
  }
2195
2577
  ),
2196
2578
  config.topSlot?.({ minimized: false }),
2197
- /* @__PURE__ */ jsx19("nav", { "aria-label": "Primary navigation", children: renderNavigationGrid(primaryItems) }),
2198
- secondaryItems.length > 0 && /* @__PURE__ */ jsx19("nav", { "aria-label": "Secondary navigation", className: "flex flex-col gap-3", children: secondaryItems.map((item) => /* @__PURE__ */ jsx19(React4.Fragment, { children: renderNavigationItem(item, false) }, item.id)) }),
2199
- onLogout && /* @__PURE__ */ jsxs17(
2579
+ /* @__PURE__ */ jsx21("nav", { "aria-label": "Primary navigation", children: renderNavigationGrid(primaryItems) }),
2580
+ secondaryItems.length > 0 && /* @__PURE__ */ jsx21("nav", { "aria-label": "Secondary navigation", className: "flex flex-col gap-3", children: secondaryItems.map((item) => /* @__PURE__ */ jsx21(React3.Fragment, { children: renderNavigationItem(item, false) }, item.id)) }),
2581
+ onLogout && /* @__PURE__ */ jsxs19(
2200
2582
  "button",
2201
2583
  {
2202
2584
  onClick: onLogout,
@@ -2207,8 +2589,8 @@ var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2207
2589
  disabled && "cursor-not-allowed opacity-50"
2208
2590
  ),
2209
2591
  children: [
2210
- /* @__PURE__ */ jsx19(Logout02Icon, { className: "size-4 text-ods-error" }),
2211
- /* @__PURE__ */ jsx19("span", { className: "flex-1 text-left text-ods-text-primary text-h6", children: "Log Out" })
2592
+ /* @__PURE__ */ jsx21(Logout02Icon, { className: "size-4 text-ods-error" }),
2593
+ /* @__PURE__ */ jsx21("span", { className: "flex-1 text-left text-ods-text-primary text-h6", children: "Log Out" })
2212
2594
  ]
2213
2595
  }
2214
2596
  )
@@ -2219,7 +2601,7 @@ var MobileBurgerMenu = React4.memo(function MobileBurgerMenuImpl({
2219
2601
  });
2220
2602
 
2221
2603
  // src/components/navigation/app-layout.tsx
2222
- import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
2604
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
2223
2605
  function AppLayout({
2224
2606
  children,
2225
2607
  sidebarConfig,
@@ -2232,10 +2614,10 @@ function AppLayout({
2232
2614
  topBar,
2233
2615
  sidePanel
2234
2616
  }) {
2235
- const [mobileMenuOpen, setMobileMenuOpen] = useState5(false);
2236
- const [drawerContainer, setDrawerContainer] = useState5(null);
2237
- const [mainElement, setMainElement] = useState5(null);
2238
- const [contentWidth, setContentWidth] = useState5(null);
2617
+ const [mobileMenuOpen, setMobileMenuOpen] = useState7(false);
2618
+ const [drawerContainer, setDrawerContainer] = useState7(null);
2619
+ const [mainElement, setMainElement] = useState7(null);
2620
+ const [contentWidth, setContentWidth] = useState7(null);
2239
2621
  const hasSidePanel = sidePanel !== void 0;
2240
2622
  const sidePanelState = useAppLayoutSidePanel(sidePanel, drawerContainer);
2241
2623
  useIsomorphicLayoutEffect(() => {
@@ -2255,7 +2637,7 @@ function AppLayout({
2255
2637
  };
2256
2638
  const contentCovered = sidePanelState?.coversContent === true;
2257
2639
  const mobileMenuOpenRef = useRef6(mobileMenuOpen);
2258
- useEffect4(() => {
2640
+ useEffect5(() => {
2259
2641
  mobileMenuOpenRef.current = mobileMenuOpen;
2260
2642
  });
2261
2643
  const drawerHandlesRef = useRef6(/* @__PURE__ */ new Set());
@@ -2284,11 +2666,11 @@ function AppLayout({
2284
2666
  }),
2285
2667
  []
2286
2668
  );
2287
- return /* @__PURE__ */ jsx20(AppLayoutDrawerContainerContext.Provider, { value: drawerContainer, children: /* @__PURE__ */ jsx20(AppLayoutDrawerCoordinationContext.Provider, { value: drawerCoordination, children: /* @__PURE__ */ jsxs18("div", { className: cn("flex h-screen flex-col bg-ods-bg", className), children: [
2669
+ return /* @__PURE__ */ jsx22(AppLayoutDrawerContainerContext.Provider, { value: drawerContainer, children: /* @__PURE__ */ jsx22(AppLayoutDrawerCoordinationContext.Provider, { value: drawerCoordination, children: /* @__PURE__ */ jsxs20("div", { className: cn("flex h-screen flex-col bg-ods-bg", className), children: [
2288
2670
  topBar,
2289
- /* @__PURE__ */ jsxs18("div", { className: "relative flex min-h-0 flex-1", children: [
2290
- /* @__PURE__ */ jsx20(NavigationSidebar, { config: sidebarConfig, disabled, pushOnTablet: hasSidePanel }),
2291
- /* @__PURE__ */ jsx20(
2671
+ /* @__PURE__ */ jsxs20("div", { className: "relative flex min-h-0 flex-1", children: [
2672
+ /* @__PURE__ */ jsx22(NavigationSidebar, { config: sidebarConfig, disabled, pushOnTablet: hasSidePanel }),
2673
+ /* @__PURE__ */ jsx22(
2292
2674
  MobileBurgerMenu,
2293
2675
  {
2294
2676
  ...mobileBurgerMenuProps,
@@ -2298,8 +2680,8 @@ function AppLayout({
2298
2680
  disabled
2299
2681
  }
2300
2682
  ),
2301
- /* @__PURE__ */ jsxs18("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
2302
- /* @__PURE__ */ jsx20(
2683
+ /* @__PURE__ */ jsxs20("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
2684
+ /* @__PURE__ */ jsx22(
2303
2685
  AppHeader,
2304
2686
  {
2305
2687
  ...resolvedHeaderProps,
@@ -2308,8 +2690,8 @@ function AppLayout({
2308
2690
  disabled
2309
2691
  }
2310
2692
  ),
2311
- /* @__PURE__ */ jsx20(NotificationDrawer, {}),
2312
- /* @__PURE__ */ jsxs18(
2693
+ /* @__PURE__ */ jsx22(NotificationDrawer, {}),
2694
+ /* @__PURE__ */ jsxs20(
2313
2695
  "div",
2314
2696
  {
2315
2697
  ref: setDrawerContainer,
@@ -2318,7 +2700,7 @@ function AppLayout({
2318
2700
  sidePanel ? (
2319
2701
  // `hidden` while the panel covers the area: the page stays
2320
2702
  // mounted, it just takes no room.
2321
- /* @__PURE__ */ jsx20(
2703
+ /* @__PURE__ */ jsx22(
2322
2704
  "main",
2323
2705
  {
2324
2706
  ref: setMainElement,
@@ -2330,11 +2712,11 @@ function AppLayout({
2330
2712
  sidePanelState?.overlapsContent && "isolate",
2331
2713
  mainClassName
2332
2714
  ),
2333
- children: /* @__PURE__ */ jsx20(ContentAreaWidthContext.Provider, { value: contentWidth, children: /* @__PURE__ */ jsx20("div", { className: "ods-content-scope", children }) })
2715
+ children: /* @__PURE__ */ jsx22(ContentAreaWidthContext.Provider, { value: contentWidth, children: /* @__PURE__ */ jsx22("div", { className: "ods-content-scope", children }) })
2334
2716
  }
2335
2717
  )
2336
- ) : /* @__PURE__ */ jsx20("main", { className: cn("flex-1 overflow-y-auto", mainClassName), children }),
2337
- sidePanel && sidePanelState && /* @__PURE__ */ jsx20(AppLayoutSidePanel, { config: sidePanel, state: sidePanelState }),
2718
+ ) : /* @__PURE__ */ jsx22("main", { className: cn("flex-1 overflow-y-auto", mainClassName), children }),
2719
+ sidePanel && sidePanelState && /* @__PURE__ */ jsx22(AppLayoutSidePanel, { config: sidePanel, state: sidePanelState }),
2338
2720
  drawer
2339
2721
  ]
2340
2722
  }
@@ -2345,14 +2727,20 @@ function AppLayout({
2345
2727
  }
2346
2728
 
2347
2729
  export {
2730
+ ASK_AI_OPEN_EVENT,
2731
+ openAskAi,
2348
2732
  MingoAiButton,
2349
- MOBILE_NAV_PANEL_ID,
2350
- MobileNavPanel,
2351
- TicketAlertsButton,
2733
+ MOBILE_NAV_SHEET_ID,
2734
+ defaultRenderSiteNavLink,
2735
+ navLinkLabel,
2736
+ NavItemRow,
2737
+ isMegaMenu,
2738
+ NavPanel,
2352
2739
  TopNavigation,
2353
- Header,
2354
- HeaderSkeleton,
2355
- ClientOnlyHeader,
2740
+ SiteHeader,
2741
+ siteNavHasMobileMenus,
2742
+ MobileNavSheet,
2743
+ SiteFooter,
2356
2744
  SlidingSidebar,
2357
2745
  NavigationItemBadge,
2358
2746
  NAVIGATION_SIDEBAR_WIDTH_VAR,
@@ -2360,6 +2748,7 @@ export {
2360
2748
  HeaderGlobalSearch,
2361
2749
  HeaderMingoButton,
2362
2750
  HeaderOrganizationFilter,
2751
+ TicketAlertsButton,
2363
2752
  AppHeader,
2364
2753
  SIDE_PANEL_FRAME_WIDTH,
2365
2754
  MobileBurgerMenu,