@flamingo-stack/openframe-frontend-core 0.0.285 → 0.0.286

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 (211) hide show
  1. package/dist/chunk-3MCHAFHB.js +89 -0
  2. package/dist/chunk-3MCHAFHB.js.map +1 -0
  3. package/dist/{chunk-IMNGGLKL.js → chunk-3ZXUQQL4.js} +2 -2
  4. package/dist/{chunk-44ZFLMYC.cjs → chunk-4WACBTZU.cjs} +30 -30
  5. package/dist/{chunk-44ZFLMYC.cjs.map → chunk-4WACBTZU.cjs.map} +1 -1
  6. package/dist/{chunk-23UOJUDF.js → chunk-5BTZOVDQ.js} +4 -4
  7. package/dist/chunk-5KD3S25X.cjs +312 -0
  8. package/dist/chunk-5KD3S25X.cjs.map +1 -0
  9. package/dist/chunk-6N26CURS.cjs +2417 -0
  10. package/dist/chunk-6N26CURS.cjs.map +1 -0
  11. package/dist/{chunk-XX7P4IL2.js → chunk-7NM7DEUK.js} +4 -143
  12. package/dist/chunk-7NM7DEUK.js.map +1 -0
  13. package/dist/chunk-BBZ7AX5H.cjs +290 -0
  14. package/dist/chunk-BBZ7AX5H.cjs.map +1 -0
  15. package/dist/chunk-C6SCWXDP.js +290 -0
  16. package/dist/chunk-C6SCWXDP.js.map +1 -0
  17. package/dist/{chunk-GVSTRN36.cjs → chunk-D3LEFMOA.cjs} +3 -3
  18. package/dist/{chunk-GVSTRN36.cjs.map → chunk-D3LEFMOA.cjs.map} +1 -1
  19. package/dist/{chunk-P45Q4QCU.cjs → chunk-D5YY5U6J.cjs} +19 -15
  20. package/dist/chunk-D5YY5U6J.cjs.map +1 -0
  21. package/dist/chunk-DDAT4RKX.js +2417 -0
  22. package/dist/chunk-DDAT4RKX.js.map +1 -0
  23. package/dist/{chunk-PVXCVPJD.cjs → chunk-EI4WALN2.cjs} +67 -1626
  24. package/dist/chunk-EI4WALN2.cjs.map +1 -0
  25. package/dist/{chunk-ZIODAAFY.cjs → chunk-EL5GCMPU.cjs} +20 -159
  26. package/dist/chunk-EL5GCMPU.cjs.map +1 -0
  27. package/dist/{chunk-VQW7CEGS.js → chunk-FSBDVT6R.js} +1831 -3672
  28. package/dist/chunk-FSBDVT6R.js.map +1 -0
  29. package/dist/{chunk-DPKUSBQH.cjs → chunk-GDF2R2ER.cjs} +1073 -2914
  30. package/dist/chunk-GDF2R2ER.cjs.map +1 -0
  31. package/dist/chunk-HLQW7MWJ.cjs +1594 -0
  32. package/dist/chunk-HLQW7MWJ.cjs.map +1 -0
  33. package/dist/chunk-I6ZPGKZ2.cjs +151 -0
  34. package/dist/chunk-I6ZPGKZ2.cjs.map +1 -0
  35. package/dist/{chunk-J66U3LPZ.cjs → chunk-KBKZYJRI.cjs} +33 -332
  36. package/dist/chunk-KBKZYJRI.cjs.map +1 -0
  37. package/dist/{chunk-USPATRSC.js → chunk-N6ZM5PYZ.js} +45 -344
  38. package/dist/chunk-N6ZM5PYZ.js.map +1 -0
  39. package/dist/{chunk-RGALV4UX.js → chunk-POKKCWKF.js} +3 -82
  40. package/dist/chunk-POKKCWKF.js.map +1 -0
  41. package/dist/{chunk-XDI5JSWB.cjs → chunk-QCKN37OP.cjs} +45 -41
  42. package/dist/chunk-QCKN37OP.cjs.map +1 -0
  43. package/dist/{chunk-KNCDUWY2.js → chunk-QF2X6PTD.js} +10 -6
  44. package/dist/{chunk-KNCDUWY2.js.map → chunk-QF2X6PTD.js.map} +1 -1
  45. package/dist/{chunk-Z3V2SGQZ.js → chunk-R2KT5GDD.js} +324 -1883
  46. package/dist/chunk-R2KT5GDD.js.map +1 -0
  47. package/dist/{chunk-RJUGNL2A.cjs → chunk-RQ6RTBKF.cjs} +16 -12
  48. package/dist/chunk-RQ6RTBKF.cjs.map +1 -0
  49. package/dist/chunk-TFSYSWPS.cjs +89 -0
  50. package/dist/chunk-TFSYSWPS.cjs.map +1 -0
  51. package/dist/chunk-TYZEMPPH.js +312 -0
  52. package/dist/chunk-TYZEMPPH.js.map +1 -0
  53. package/dist/{chunk-O5N57CRV.js → chunk-VCQ3CTYK.js} +12 -8
  54. package/dist/{chunk-O5N57CRV.js.map → chunk-VCQ3CTYK.js.map} +1 -1
  55. package/dist/chunk-VRSXJ5QJ.js +1599 -0
  56. package/dist/chunk-VRSXJ5QJ.js.map +1 -0
  57. package/dist/{chunk-53CFL7PH.js → chunk-XQL4WDML.js} +11 -7
  58. package/dist/{chunk-53CFL7PH.js.map → chunk-XQL4WDML.js.map} +1 -1
  59. package/dist/chunk-Y4JNA4W6.cjs +1599 -0
  60. package/dist/chunk-Y4JNA4W6.cjs.map +1 -0
  61. package/dist/{chunk-ZSUNQJRO.cjs → chunk-YETA25JW.cjs} +2 -81
  62. package/dist/chunk-YETA25JW.cjs.map +1 -0
  63. package/dist/chunk-YVB3VDIQ.js +1594 -0
  64. package/dist/chunk-YVB3VDIQ.js.map +1 -0
  65. package/dist/chunk-ZLN6SM2U.js +151 -0
  66. package/dist/chunk-ZLN6SM2U.js.map +1 -0
  67. package/dist/components/chat/chat-attachment-bar.d.ts.map +1 -1
  68. package/dist/components/chat/index.cjs +12 -6
  69. package/dist/components/chat/index.cjs.map +1 -1
  70. package/dist/components/chat/index.js +45 -39
  71. package/dist/components/contact/index.cjs +11 -7
  72. package/dist/components/contact/index.cjs.map +1 -1
  73. package/dist/components/contact/index.js +10 -6
  74. package/dist/components/docs/doc-navigation-context.d.ts +39 -0
  75. package/dist/components/docs/doc-navigation-context.d.ts.map +1 -0
  76. package/dist/components/docs/doc-viewer.d.ts +66 -0
  77. package/dist/components/docs/doc-viewer.d.ts.map +1 -0
  78. package/dist/components/docs/index.cjs +34 -0
  79. package/dist/components/docs/index.cjs.map +1 -0
  80. package/dist/components/docs/index.d.ts +8 -0
  81. package/dist/components/docs/index.d.ts.map +1 -0
  82. package/dist/components/docs/index.js +34 -0
  83. package/dist/components/docs/index.js.map +1 -0
  84. package/dist/components/docs/use-document-tree.d.ts +41 -0
  85. package/dist/components/docs/use-document-tree.d.ts.map +1 -0
  86. package/dist/components/docs/use-scroll-spy.d.ts +16 -0
  87. package/dist/components/docs/use-scroll-spy.d.ts.map +1 -0
  88. package/dist/components/embeds/embed-iframe.d.ts +29 -0
  89. package/dist/components/embeds/embed-iframe.d.ts.map +1 -0
  90. package/dist/components/embeds/figma-embed.d.ts +27 -0
  91. package/dist/components/embeds/figma-embed.d.ts.map +1 -0
  92. package/dist/components/embeds/google-sheets-viewer.d.ts +8 -0
  93. package/dist/components/embeds/google-sheets-viewer.d.ts.map +1 -0
  94. package/dist/components/embeds/index.cjs +37 -0
  95. package/dist/components/embeds/index.cjs.map +1 -0
  96. package/dist/components/embeds/index.d.ts +9 -0
  97. package/dist/components/embeds/index.d.ts.map +1 -0
  98. package/dist/components/embeds/index.js +37 -0
  99. package/dist/components/embeds/index.js.map +1 -0
  100. package/dist/components/embeds/pdf-viewer.d.ts +10 -0
  101. package/dist/components/embeds/pdf-viewer.d.ts.map +1 -0
  102. package/dist/components/faq/index.cjs +12 -8
  103. package/dist/components/faq/index.cjs.map +1 -1
  104. package/dist/components/faq/index.js +11 -7
  105. package/dist/components/features/index.cjs +10 -6
  106. package/dist/components/features/index.cjs.map +1 -1
  107. package/dist/components/features/index.js +9 -5
  108. package/dist/components/index.cjs +247 -1120
  109. package/dist/components/index.cjs.map +1 -1
  110. package/dist/components/index.d.ts +2 -0
  111. package/dist/components/index.d.ts.map +1 -1
  112. package/dist/components/index.js +645 -1518
  113. package/dist/components/index.js.map +1 -1
  114. package/dist/components/navigation/index.cjs +15 -6
  115. package/dist/components/navigation/index.cjs.map +1 -1
  116. package/dist/components/navigation/index.d.ts +2 -0
  117. package/dist/components/navigation/index.d.ts.map +1 -1
  118. package/dist/components/navigation/index.js +15 -6
  119. package/dist/components/navigation/multi-level-navigation.d.ts +28 -0
  120. package/dist/components/navigation/multi-level-navigation.d.ts.map +1 -0
  121. package/dist/components/onboarding-guides/index.cjs +34 -29
  122. package/dist/components/onboarding-guides/index.cjs.map +1 -1
  123. package/dist/components/onboarding-guides/index.js +13 -8
  124. package/dist/components/onboarding-guides/index.js.map +1 -1
  125. package/dist/components/related-content/index.cjs +12 -8
  126. package/dist/components/related-content/index.cjs.map +1 -1
  127. package/dist/components/related-content/index.js +11 -7
  128. package/dist/components/tickets/index.cjs +75 -70
  129. package/dist/components/tickets/index.cjs.map +1 -1
  130. package/dist/components/tickets/index.js +16 -11
  131. package/dist/components/tickets/index.js.map +1 -1
  132. package/dist/components/ui/index.cjs +12 -6
  133. package/dist/components/ui/index.cjs.map +1 -1
  134. package/dist/components/ui/index.js +65 -59
  135. package/dist/embed-shims/index.cjs +3 -3
  136. package/dist/embed-shims/index.cjs.map +1 -1
  137. package/dist/embed-shims/index.js +8 -8
  138. package/dist/hooks/index.cjs +6 -3
  139. package/dist/hooks/index.cjs.map +1 -1
  140. package/dist/hooks/index.js +7 -4
  141. package/dist/index.cjs +62 -6
  142. package/dist/index.cjs.map +1 -1
  143. package/dist/index.js +257 -201
  144. package/dist/types/doc-source.cjs +4 -0
  145. package/dist/types/doc-source.cjs.map +1 -0
  146. package/dist/types/doc-source.d.ts +86 -0
  147. package/dist/types/doc-source.d.ts.map +1 -0
  148. package/dist/types/doc-source.js +3 -0
  149. package/dist/types/doc-source.js.map +1 -0
  150. package/dist/types/index.d.ts +1 -0
  151. package/dist/types/index.d.ts.map +1 -1
  152. package/dist/utils/doc-path-utils.d.ts +24 -0
  153. package/dist/utils/doc-path-utils.d.ts.map +1 -0
  154. package/dist/utils/doc-tree-nav.d.ts +35 -0
  155. package/dist/utils/doc-tree-nav.d.ts.map +1 -0
  156. package/dist/utils/embed-url-converters.d.ts +16 -0
  157. package/dist/utils/embed-url-converters.d.ts.map +1 -0
  158. package/dist/utils/format.d.ts +9 -0
  159. package/dist/utils/format.d.ts.map +1 -1
  160. package/dist/utils/index.cjs +297 -0
  161. package/dist/utils/index.cjs.map +1 -1
  162. package/dist/utils/index.d.ts +7 -1
  163. package/dist/utils/index.d.ts.map +1 -1
  164. package/dist/utils/index.js +276 -1
  165. package/dist/utils/index.js.map +1 -1
  166. package/dist/utils/markdown-section-extractor.d.ts +23 -0
  167. package/dist/utils/markdown-section-extractor.d.ts.map +1 -0
  168. package/dist/utils/markdown-to-plain.d.ts +32 -0
  169. package/dist/utils/markdown-to-plain.d.ts.map +1 -0
  170. package/dist/utils/tree-builder.d.ts +30 -0
  171. package/dist/utils/tree-builder.d.ts.map +1 -0
  172. package/package.json +19 -1
  173. package/src/components/chat/chat-attachment-bar.tsx +6 -11
  174. package/src/components/docs/doc-navigation-context.tsx +123 -0
  175. package/src/components/docs/doc-viewer.tsx +345 -0
  176. package/src/components/docs/index.ts +12 -0
  177. package/src/components/docs/use-document-tree.ts +427 -0
  178. package/src/components/docs/use-scroll-spy.ts +93 -0
  179. package/src/components/embeds/embed-iframe.tsx +103 -0
  180. package/src/components/embeds/figma-embed.tsx +147 -0
  181. package/src/components/embeds/google-sheets-viewer.tsx +54 -0
  182. package/src/components/embeds/index.ts +11 -0
  183. package/src/components/embeds/pdf-viewer.tsx +64 -0
  184. package/src/components/index.ts +2 -0
  185. package/src/components/navigation/index.ts +5 -0
  186. package/src/components/navigation/multi-level-navigation.tsx +358 -0
  187. package/src/types/doc-source.ts +88 -0
  188. package/src/types/index.ts +4 -0
  189. package/src/utils/doc-path-utils.ts +47 -0
  190. package/src/utils/doc-tree-nav.ts +111 -0
  191. package/src/utils/embed-url-converters.ts +77 -0
  192. package/src/utils/format.ts +16 -0
  193. package/src/utils/index.ts +11 -0
  194. package/src/utils/markdown-section-extractor.ts +106 -0
  195. package/src/utils/markdown-to-plain.ts +69 -0
  196. package/src/utils/tree-builder.ts +114 -0
  197. package/dist/chunk-DPKUSBQH.cjs.map +0 -1
  198. package/dist/chunk-J66U3LPZ.cjs.map +0 -1
  199. package/dist/chunk-P45Q4QCU.cjs.map +0 -1
  200. package/dist/chunk-PVXCVPJD.cjs.map +0 -1
  201. package/dist/chunk-RGALV4UX.js.map +0 -1
  202. package/dist/chunk-RJUGNL2A.cjs.map +0 -1
  203. package/dist/chunk-USPATRSC.js.map +0 -1
  204. package/dist/chunk-VQW7CEGS.js.map +0 -1
  205. package/dist/chunk-XDI5JSWB.cjs.map +0 -1
  206. package/dist/chunk-XX7P4IL2.js.map +0 -1
  207. package/dist/chunk-Z3V2SGQZ.js.map +0 -1
  208. package/dist/chunk-ZIODAAFY.cjs.map +0 -1
  209. package/dist/chunk-ZSUNQJRO.cjs.map +0 -1
  210. /package/dist/{chunk-IMNGGLKL.js.map → chunk-3ZXUQQL4.js.map} +0 -0
  211. /package/dist/{chunk-23UOJUDF.js.map → chunk-5BTZOVDQ.js.map} +0 -0
@@ -0,0 +1,1594 @@
1
+ "use client";
2
+ import {
3
+ DocSearchBar,
4
+ useDocSearch
5
+ } from "./chunk-7NM7DEUK.js";
6
+ import {
7
+ DEFAULT_FOLDER_INDEX_FILE,
8
+ MobileNavigationDropdown,
9
+ MultiLevelNavigation,
10
+ StickySectionNav,
11
+ findDocNodeByPath,
12
+ getDocAncestorNodeIds,
13
+ scrollElementIntoView,
14
+ stripFolderIndexFromPath
15
+ } from "./chunk-DDAT4RKX.js";
16
+ import {
17
+ PageHeading
18
+ } from "./chunk-VRSXJ5QJ.js";
19
+ import {
20
+ cn,
21
+ init_cn
22
+ } from "./chunk-XTCBRQN2.js";
23
+
24
+ // src/components/docs/doc-viewer.tsx
25
+ import { useMemo as useMemo2 } from "react";
26
+
27
+ // src/components/persistent-filter-controls.tsx
28
+ init_cn();
29
+ import { jsx, jsxs } from "react/jsx-runtime";
30
+ function PersistentFilterControls({
31
+ isLoading,
32
+ children,
33
+ className,
34
+ disabledOpacity = 0.6,
35
+ transitionDuration = 300,
36
+ preventInteraction = true
37
+ }) {
38
+ return /* @__PURE__ */ jsxs(
39
+ "div",
40
+ {
41
+ className: cn(
42
+ "relative transition-all ease-in-out",
43
+ isLoading && preventInteraction && "pointer-events-none",
44
+ className
45
+ ),
46
+ style: {
47
+ opacity: isLoading ? disabledOpacity : 1,
48
+ transitionDuration: `${transitionDuration}ms`
49
+ },
50
+ role: "region",
51
+ "aria-label": "Filter controls",
52
+ "aria-busy": isLoading,
53
+ "data-loading": isLoading,
54
+ children: [
55
+ isLoading && /* @__PURE__ */ jsx(
56
+ "div",
57
+ {
58
+ className: "sr-only",
59
+ role: "status",
60
+ "aria-live": "polite",
61
+ children: "Filters temporarily disabled while loading content"
62
+ }
63
+ ),
64
+ /* @__PURE__ */ jsx(
65
+ "div",
66
+ {
67
+ className: cn(
68
+ "transition-all ease-in-out",
69
+ isLoading && "cursor-not-allowed"
70
+ ),
71
+ style: {
72
+ transitionDuration: `${transitionDuration}ms`
73
+ },
74
+ children
75
+ }
76
+ ),
77
+ isLoading && /* @__PURE__ */ jsx(
78
+ "div",
79
+ {
80
+ className: "absolute top-2 right-2 z-10",
81
+ role: "status",
82
+ "aria-label": "Loading filters",
83
+ children: /* @__PURE__ */ jsx("div", { className: "w-4 h-4 border-2 border-ods-border border-t-[#FFC008] rounded-full animate-spin" })
84
+ }
85
+ )
86
+ ]
87
+ }
88
+ );
89
+ }
90
+ function PersistentSearchContainer({
91
+ isLoading,
92
+ children,
93
+ className
94
+ }) {
95
+ return /* @__PURE__ */ jsx(
96
+ PersistentFilterControls,
97
+ {
98
+ isLoading,
99
+ preventInteraction: false,
100
+ className,
101
+ children
102
+ }
103
+ );
104
+ }
105
+ function PersistentSidebar({
106
+ isLoading,
107
+ children,
108
+ className
109
+ }) {
110
+ return /* @__PURE__ */ jsx(
111
+ PersistentFilterControls,
112
+ {
113
+ isLoading,
114
+ disabledOpacity: 0.5,
115
+ className: cn("lg:sticky lg:top-20", className),
116
+ children
117
+ }
118
+ );
119
+ }
120
+ function PersistentMobileDropdown({
121
+ isLoading,
122
+ children,
123
+ className
124
+ }) {
125
+ return /* @__PURE__ */ jsx(
126
+ PersistentFilterControls,
127
+ {
128
+ isLoading,
129
+ disabledOpacity: 0.7,
130
+ className: cn("lg:hidden", className),
131
+ children
132
+ }
133
+ );
134
+ }
135
+
136
+ // src/components/loading/page-layout-skeleton.tsx
137
+ init_cn();
138
+
139
+ // src/components/loading/unified-skeleton.tsx
140
+ init_cn();
141
+ import { jsx as jsx2 } from "react/jsx-runtime";
142
+ function UnifiedSkeleton({
143
+ className,
144
+ variant = "default",
145
+ width,
146
+ height,
147
+ animate = true,
148
+ "aria-label": ariaLabel,
149
+ ...props
150
+ }) {
151
+ const baseClasses = "bg-[#2A2A2A]";
152
+ const variantClasses = {
153
+ default: "rounded-md",
154
+ text: "rounded-sm",
155
+ circular: "rounded-full",
156
+ rectangular: "rounded-none"
157
+ };
158
+ const defaultHeights = {
159
+ default: "h-4",
160
+ text: "h-4",
161
+ circular: "h-12 w-12",
162
+ rectangular: "h-4"
163
+ };
164
+ const animationClasses = animate ? "animate-pulse motion-reduce:animate-none" : "";
165
+ const style = {
166
+ width,
167
+ height
168
+ };
169
+ return /* @__PURE__ */ jsx2(
170
+ "div",
171
+ {
172
+ className: cn(
173
+ baseClasses,
174
+ variantClasses[variant],
175
+ !height && !style.height && defaultHeights[variant],
176
+ !width && !style.width && variant !== "circular" && "w-full",
177
+ animationClasses,
178
+ className
179
+ ),
180
+ style,
181
+ role: "status",
182
+ "aria-label": ariaLabel || "Loading content",
183
+ ...props
184
+ }
185
+ );
186
+ }
187
+ var TextSkeleton = {
188
+ /**
189
+ * Large heading skeleton (h1, h2)
190
+ */
191
+ Heading: ({ className, ...props }) => /* @__PURE__ */ jsx2(
192
+ UnifiedSkeleton,
193
+ {
194
+ variant: "text",
195
+ className: cn("h-8 md:h-10 lg:h-12", className),
196
+ "aria-label": "Loading heading",
197
+ ...props
198
+ }
199
+ ),
200
+ /**
201
+ * Medium heading skeleton (h3, h4)
202
+ */
203
+ Subheading: ({ className, ...props }) => /* @__PURE__ */ jsx2(
204
+ UnifiedSkeleton,
205
+ {
206
+ variant: "text",
207
+ className: cn("h-6 md:h-7 lg:h-8", className),
208
+ "aria-label": "Loading subheading",
209
+ ...props
210
+ }
211
+ ),
212
+ /**
213
+ * Body text skeleton
214
+ */
215
+ Body: ({ className, ...props }) => /* @__PURE__ */ jsx2(
216
+ UnifiedSkeleton,
217
+ {
218
+ variant: "text",
219
+ className: cn("h-4 md:h-5", className),
220
+ "aria-label": "Loading text",
221
+ ...props
222
+ }
223
+ ),
224
+ /**
225
+ * Small text skeleton (captions, metadata)
226
+ */
227
+ Caption: ({ className, ...props }) => /* @__PURE__ */ jsx2(
228
+ UnifiedSkeleton,
229
+ {
230
+ variant: "text",
231
+ className: cn("h-3 md:h-4", className),
232
+ "aria-label": "Loading caption",
233
+ ...props
234
+ }
235
+ )
236
+ };
237
+ var InteractiveSkeleton = {
238
+ /**
239
+ * Button skeleton with proper touch targets
240
+ */
241
+ Button: ({ className, ...props }) => /* @__PURE__ */ jsx2(
242
+ UnifiedSkeleton,
243
+ {
244
+ variant: "default",
245
+ className: cn("h-10 md:h-12 w-32 md:w-40", className),
246
+ "aria-label": "Loading button",
247
+ ...props
248
+ }
249
+ ),
250
+ /**
251
+ * Input field skeleton
252
+ */
253
+ Input: ({ className, ...props }) => /* @__PURE__ */ jsx2(
254
+ UnifiedSkeleton,
255
+ {
256
+ variant: "default",
257
+ className: cn("h-10 md:h-12 w-full", className),
258
+ "aria-label": "Loading input field",
259
+ ...props
260
+ }
261
+ ),
262
+ /**
263
+ * Filter chip skeleton
264
+ */
265
+ Chip: ({ className, ...props }) => /* @__PURE__ */ jsx2(
266
+ UnifiedSkeleton,
267
+ {
268
+ variant: "default",
269
+ className: cn("h-8 w-20 rounded-full", className),
270
+ "aria-label": "Loading filter",
271
+ ...props
272
+ }
273
+ )
274
+ };
275
+ var MediaSkeleton = {
276
+ /**
277
+ * Avatar/profile image skeleton
278
+ */
279
+ Avatar: ({ size = "md", className, ...props }) => {
280
+ const sizeClasses = {
281
+ sm: "h-8 w-8",
282
+ md: "h-12 w-12",
283
+ lg: "h-16 w-16"
284
+ };
285
+ return /* @__PURE__ */ jsx2(
286
+ UnifiedSkeleton,
287
+ {
288
+ variant: "circular",
289
+ className: cn(sizeClasses[size], className),
290
+ "aria-label": "Loading profile image",
291
+ ...props
292
+ }
293
+ );
294
+ },
295
+ /**
296
+ * Card image skeleton (1200×630 OG aspect — matches entity-cards default
297
+ * so loading state never causes a height shift when card data arrives)
298
+ */
299
+ CardImage: ({ className, ...props }) => /* @__PURE__ */ jsx2(
300
+ UnifiedSkeleton,
301
+ {
302
+ variant: "default",
303
+ className: cn("aspect-[1200/630] w-full", className),
304
+ "aria-label": "Loading image",
305
+ ...props
306
+ }
307
+ ),
308
+ /**
309
+ * Icon skeleton
310
+ */
311
+ Icon: ({ size = "md", className, ...props }) => {
312
+ const sizeClasses = {
313
+ sm: "h-4 w-4",
314
+ md: "h-6 w-6",
315
+ lg: "h-8 w-8"
316
+ };
317
+ return /* @__PURE__ */ jsx2(
318
+ UnifiedSkeleton,
319
+ {
320
+ variant: "default",
321
+ className: cn(sizeClasses[size], className),
322
+ "aria-label": "Loading icon",
323
+ ...props
324
+ }
325
+ );
326
+ }
327
+ };
328
+
329
+ // src/components/loading/card-skeleton.tsx
330
+ init_cn();
331
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
332
+ function CardSkeleton({
333
+ className,
334
+ containerClassName,
335
+ variant = "vendor",
336
+ showActions = true,
337
+ showMetadata = true,
338
+ ...props
339
+ }) {
340
+ const cardContent = {
341
+ vendor: /* @__PURE__ */ jsx3(VendorCardContent, { showActions, showMetadata }),
342
+ blog: /* @__PURE__ */ jsx3(BlogCardContent, { showActions, showMetadata }),
343
+ category: /* @__PURE__ */ jsx3(CategoryCardContent, {}),
344
+ alternative: /* @__PURE__ */ jsx3(AlternativeCardContent, { showActions })
345
+ };
346
+ return /* @__PURE__ */ jsx3(
347
+ "div",
348
+ {
349
+ className: cn(
350
+ containerClassName || "bg-ods-card border border-ods-border",
351
+ "rounded-lg overflow-hidden",
352
+ // Flex layouts for certain variants
353
+ variant === "blog" && "h-full flex flex-col",
354
+ variant === "vendor" && "h-full flex flex-col",
355
+ className
356
+ ),
357
+ role: "status",
358
+ "aria-label": `Loading ${variant} card`,
359
+ ...props,
360
+ children: cardContent[variant]
361
+ }
362
+ );
363
+ }
364
+ function VendorCardContent({ showActions, showMetadata }) {
365
+ return /* @__PURE__ */ jsxs2("div", { className: "p-4 gap-3 flex flex-col", children: [
366
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-start gap-3 w-full", children: [
367
+ /* @__PURE__ */ jsx3("div", { className: "w-[60px] h-[60px] bg-ods-bg border border-ods-border rounded-lg p-2 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx3(MediaSkeleton.Avatar, { size: "sm", className: "w-11 h-11" }) }),
368
+ /* @__PURE__ */ jsxs2("div", { className: "flex-1 flex flex-col justify-center py-2 min-w-0 space-y-1", children: [
369
+ /* @__PURE__ */ jsx3(TextSkeleton.Subheading, { className: "w-3/4" }),
370
+ /* @__PURE__ */ jsx3(TextSkeleton.Caption, { className: "w-1/2" })
371
+ ] })
372
+ ] }),
373
+ /* @__PURE__ */ jsx3("div", { className: "w-full h-12 overflow-hidden flex items-center", children: /* @__PURE__ */ jsxs2("div", { className: "space-y-1 w-full", children: [
374
+ /* @__PURE__ */ jsx3(TextSkeleton.Body, { className: "w-full" }),
375
+ /* @__PURE__ */ jsx3(TextSkeleton.Body, { className: "w-2/3" })
376
+ ] }) }),
377
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-2 w-full min-w-0", children: [
378
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3 md:gap-4 min-w-0 flex-shrink", children: [
379
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1 flex-shrink-0", children: [
380
+ /* @__PURE__ */ jsx3(MediaSkeleton.Icon, { size: "sm", className: "w-5 h-5" }),
381
+ /* @__PURE__ */ jsx3(TextSkeleton.Caption, { className: "w-8" })
382
+ ] }),
383
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1 flex-shrink-0", children: [
384
+ /* @__PURE__ */ jsx3(MediaSkeleton.Icon, { size: "sm", className: "w-5 h-5" }),
385
+ /* @__PURE__ */ jsx3(TextSkeleton.Caption, { className: "w-10" })
386
+ ] })
387
+ ] }),
388
+ /* @__PURE__ */ jsx3("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1.5 bg-ods-bg border border-ods-border rounded px-2.5 py-1.5", children: [
389
+ /* @__PURE__ */ jsx3("div", { className: "w-4 h-4 bg-ods-border rounded-sm flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx3(MediaSkeleton.Icon, { size: "sm", className: "w-2.5 h-2.5" }) }),
390
+ /* @__PURE__ */ jsx3(TextSkeleton.Caption, { className: "w-16" })
391
+ ] }) })
392
+ ] })
393
+ ] });
394
+ }
395
+ function BlogCardContent({ showActions, showMetadata }) {
396
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
397
+ /* @__PURE__ */ jsx3("div", { className: "blog-card-image-container relative w-full aspect-[1200/630] overflow-hidden bg-ods-bg", children: /* @__PURE__ */ jsx3(MediaSkeleton.CardImage, {}) }),
398
+ /* @__PURE__ */ jsxs2("div", { className: "p-4 flex flex-col flex-grow", children: [
399
+ /* @__PURE__ */ jsx3("div", { className: "mb-3 flex items-center min-h-[50.4px] md:min-h-[56px] lg:min-h-[61.6px]", children: /* @__PURE__ */ jsxs2("div", { className: "space-y-1 w-full", children: [
400
+ /* @__PURE__ */ jsx3(TextSkeleton.Subheading, { className: "w-full" }),
401
+ /* @__PURE__ */ jsx3(TextSkeleton.Subheading, { className: "w-3/4" })
402
+ ] }) }),
403
+ /* @__PURE__ */ jsxs2("div", { className: "mb-3 flex gap-2 h-[28px] items-center", children: [
404
+ /* @__PURE__ */ jsx3(InteractiveSkeleton.Chip, { className: "w-16" }),
405
+ /* @__PURE__ */ jsx3(InteractiveSkeleton.Chip, { className: "w-12" })
406
+ ] }),
407
+ /* @__PURE__ */ jsx3("div", { className: "mb-3 flex items-center min-h-[42px] md:min-h-[45px] lg:min-h-[48px]", children: /* @__PURE__ */ jsxs2("div", { className: "space-y-1 w-full", children: [
408
+ /* @__PURE__ */ jsx3(TextSkeleton.Body, { className: "w-full" }),
409
+ /* @__PURE__ */ jsx3(TextSkeleton.Body, { className: "w-1/2" })
410
+ ] }) }),
411
+ showActions && /* @__PURE__ */ jsx3("div", { className: "pt-2", children: /* @__PURE__ */ jsx3(InteractiveSkeleton.Button, { className: "w-24 h-8" }) }),
412
+ showMetadata && /* @__PURE__ */ jsx3("div", { className: "mt-auto", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-4 pt-4 border-t border-ods-border", children: [
413
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [
414
+ /* @__PURE__ */ jsx3(MediaSkeleton.Avatar, { size: "sm" }),
415
+ /* @__PURE__ */ jsx3(TextSkeleton.Caption, { className: "w-16" })
416
+ ] }),
417
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3 text-[#767676] shrink-0", children: [
418
+ /* @__PURE__ */ jsx3(TextSkeleton.Caption, { className: "w-12" }),
419
+ /* @__PURE__ */ jsx3("div", { className: "w-1 h-1 bg-[#767676] rounded-full" }),
420
+ /* @__PURE__ */ jsx3(TextSkeleton.Caption, { className: "w-16" })
421
+ ] })
422
+ ] }) })
423
+ ] })
424
+ ] });
425
+ }
426
+ function CategoryCardContent() {
427
+ return /* @__PURE__ */ jsxs2("div", { className: "p-4 md:p-6 space-y-4", children: [
428
+ /* @__PURE__ */ jsx3("div", { className: "flex gap-2 md:gap-3", children: Array.from({ length: 6 }).map((_, index) => /* @__PURE__ */ jsx3(
429
+ MediaSkeleton.Icon,
430
+ {
431
+ size: "lg",
432
+ className: "flex-shrink-0"
433
+ },
434
+ index
435
+ )) }),
436
+ /* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
437
+ /* @__PURE__ */ jsxs2("div", { className: "space-y-1", children: [
438
+ /* @__PURE__ */ jsx3(TextSkeleton.Subheading, { className: "w-3/4" }),
439
+ /* @__PURE__ */ jsx3(TextSkeleton.Caption, { className: "w-1/2" })
440
+ ] }),
441
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-start md:items-end justify-between gap-4 md:gap-6", children: [
442
+ /* @__PURE__ */ jsxs2("div", { className: "flex-1 space-y-2", children: [
443
+ /* @__PURE__ */ jsx3(TextSkeleton.Body, { className: "w-full" }),
444
+ /* @__PURE__ */ jsx3(TextSkeleton.Body, { className: "w-2/3" })
445
+ ] }),
446
+ /* @__PURE__ */ jsx3(InteractiveSkeleton.Button, { className: "w-10 h-10 md:w-12 md:h-12 flex-shrink-0" })
447
+ ] })
448
+ ] })
449
+ ] });
450
+ }
451
+ function AlternativeCardContent({ showActions }) {
452
+ return /* @__PURE__ */ jsxs2("div", { className: "flex items-start gap-4 p-4", children: [
453
+ /* @__PURE__ */ jsx3(MediaSkeleton.Avatar, { size: "md", className: "flex-shrink-0" }),
454
+ /* @__PURE__ */ jsxs2("div", { className: "flex-1 space-y-2", children: [
455
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between", children: [
456
+ /* @__PURE__ */ jsx3(TextSkeleton.Subheading, { className: "w-1/3" }),
457
+ /* @__PURE__ */ jsx3(TextSkeleton.Caption, { className: "w-16" })
458
+ ] }),
459
+ /* @__PURE__ */ jsxs2("div", { className: "space-y-1", children: [
460
+ /* @__PURE__ */ jsx3(TextSkeleton.Body, { className: "w-full" }),
461
+ /* @__PURE__ */ jsx3(TextSkeleton.Body, { className: "w-5/6" })
462
+ ] }),
463
+ showActions && /* @__PURE__ */ jsx3("div", { className: "pt-2", children: /* @__PURE__ */ jsx3(InteractiveSkeleton.Button, { className: "w-20 h-8" }) })
464
+ ] })
465
+ ] });
466
+ }
467
+ function CardSkeletonGrid({
468
+ count = 6,
469
+ variant = "vendor",
470
+ className,
471
+ containerClassName,
472
+ ...props
473
+ }) {
474
+ return /* @__PURE__ */ jsx3(
475
+ "div",
476
+ {
477
+ className: cn(
478
+ "grid gap-4 md:gap-6",
479
+ // Responsive grid based on card type
480
+ variant === "vendor" && "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
481
+ variant === "blog" && "grid-cols-1 md:grid-cols-2",
482
+ variant === "category" && "grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
483
+ variant === "alternative" && "grid-cols-1",
484
+ className
485
+ ),
486
+ role: "status",
487
+ "aria-label": `Loading ${count} ${variant} cards`,
488
+ children: Array.from({ length: count }, (_, index) => /* @__PURE__ */ jsx3(
489
+ CardSkeleton,
490
+ {
491
+ variant,
492
+ containerClassName,
493
+ ...props
494
+ },
495
+ index
496
+ ))
497
+ }
498
+ );
499
+ }
500
+
501
+ // src/components/loading/page-layout-skeleton.tsx
502
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
503
+ function AnnouncementBarSkeleton() {
504
+ return /* @__PURE__ */ jsx4("div", { className: "bg-[#2A2A2A] relative w-full animate-pulse", children: /* @__PURE__ */ jsx4("div", { className: "flex flex-row items-center relative w-full", children: /* @__PURE__ */ jsxs3("div", { className: "box-border flex flex-row gap-4 md:gap-6 items-center justify-start pl-4 md:pl-6 pr-12 md:pr-16 py-3 md:py-4 relative w-full", children: [
505
+ /* @__PURE__ */ jsx4("div", { className: "relative shrink-0 w-6 h-6 md:w-8 md:h-8 bg-ods-border rounded" }),
506
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0 space-y-1 md:space-y-2", children: [
507
+ /* @__PURE__ */ jsx4("div", { className: "h-[14px] md:h-[18px] bg-ods-border rounded w-3/4 max-w-md" }),
508
+ /* @__PURE__ */ jsx4("div", { className: "h-[12px] md:h-[18px] bg-ods-border rounded w-full max-w-lg hidden md:block" })
509
+ ] }),
510
+ /* @__PURE__ */ jsx4("div", { className: "absolute right-2 top-2 w-6 h-6 bg-ods-border rounded" })
511
+ ] }) }) });
512
+ }
513
+ function HeroSkeleton() {
514
+ return /* @__PURE__ */ jsxs3(
515
+ "section",
516
+ {
517
+ className: "w-full flex flex-col items-center justify-center py-12 px-4 md:py-20 md:px-8 text-center animate-pulse",
518
+ style: {
519
+ background: "radial-gradient(circle at 50% 0%, #242323 0%, #1A1A1A 100%)"
520
+ },
521
+ children: [
522
+ /* @__PURE__ */ jsx4(TextSkeleton.Heading, { className: "h-12 md:h-20 lg:h-24 mb-4 md:mb-6 max-w-4xl w-full" }),
523
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-3 mb-8 md:mb-10 max-w-4xl w-full px-2", children: [
524
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "h-5 md:h-7" }),
525
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "h-5 md:h-7 w-3/4 mx-auto" })
526
+ ] }),
527
+ /* @__PURE__ */ jsx4(InteractiveSkeleton.Button, { className: "w-full md:w-64 h-12" })
528
+ ]
529
+ }
530
+ );
531
+ }
532
+ function SearchContainerSkeleton({
533
+ className,
534
+ showFilters = true
535
+ }) {
536
+ return /* @__PURE__ */ jsxs3("div", { className: cn("space-y-4", className || ""), children: [
537
+ /* @__PURE__ */ jsxs3("div", { className: "flex gap-2 md:gap-4", children: [
538
+ /* @__PURE__ */ jsx4(InteractiveSkeleton.Input, { className: "flex-1" }),
539
+ /* @__PURE__ */ jsx4(InteractiveSkeleton.Button, { className: "w-32 md:w-40" })
540
+ ] }),
541
+ showFilters && /* @__PURE__ */ jsxs3("div", { className: "flex gap-2 flex-wrap", children: [
542
+ /* @__PURE__ */ jsx4(InteractiveSkeleton.Chip, {}),
543
+ /* @__PURE__ */ jsx4(InteractiveSkeleton.Chip, { className: "w-24" }),
544
+ /* @__PURE__ */ jsx4(InteractiveSkeleton.Chip, { className: "w-16" }),
545
+ /* @__PURE__ */ jsx4(InteractiveSkeleton.Chip, { className: "w-20" })
546
+ ] })
547
+ ] });
548
+ }
549
+ function CategorySidebarSkeleton({ className }) {
550
+ const items = [
551
+ { type: "file", width: "w-20", hasBadge: false },
552
+ { type: "folder", width: "w-24", hasBadge: true },
553
+ { type: "folder", width: "w-20", hasBadge: true },
554
+ { type: "folder", width: "w-24", hasBadge: true },
555
+ { type: "folder", width: "w-16", hasBadge: true },
556
+ { type: "folder", width: "w-20", hasBadge: true },
557
+ { type: "folder", width: "w-28", hasBadge: true },
558
+ { type: "folder", width: "w-16", hasBadge: true },
559
+ { type: "folder", width: "w-24", hasBadge: true },
560
+ { type: "file", width: "w-28" },
561
+ { type: "file", width: "w-36" }
562
+ ];
563
+ return /* @__PURE__ */ jsxs3("div", { className: cn("w-full lg:w-[320px]", className), children: [
564
+ /* @__PURE__ */ jsx4(UnifiedSkeleton, { className: "h-[14px] w-24 rounded mb-4" }),
565
+ /* @__PURE__ */ jsx4("div", { className: "space-y-1.5", children: items.map((item, index) => /* @__PURE__ */ jsxs3(
566
+ "div",
567
+ {
568
+ className: cn(
569
+ "flex items-center justify-between py-4 px-4 rounded-lg border border-ods-border min-h-[50px]",
570
+ index === 0 ? "bg-ods-accent/20" : "bg-ods-card"
571
+ ),
572
+ children: [
573
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2.5", children: [
574
+ /* @__PURE__ */ jsx4(UnifiedSkeleton, { className: "w-4 h-4 shrink-0 rounded" }),
575
+ /* @__PURE__ */ jsx4(UnifiedSkeleton, { className: `h-[14px] ${item.width} rounded` })
576
+ ] }),
577
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 h-[18px]", children: [
578
+ item.hasBadge && /* @__PURE__ */ jsx4(UnifiedSkeleton, { className: "h-[18px] w-14 rounded" }),
579
+ item.type === "folder" && /* @__PURE__ */ jsx4(UnifiedSkeleton, { className: "w-4 h-4 rounded" })
580
+ ] })
581
+ ]
582
+ },
583
+ index
584
+ )) })
585
+ ] });
586
+ }
587
+ function BreadcrumbSkeleton({ className }) {
588
+ return /* @__PURE__ */ jsxs3("div", { className: cn("flex items-center space-x-1 mb-6", className), children: [
589
+ /* @__PURE__ */ jsx4(TextSkeleton.Caption, { className: "w-16" }),
590
+ /* @__PURE__ */ jsx4(UnifiedSkeleton, { variant: "default", className: "w-4 h-4 rounded-full" }),
591
+ /* @__PURE__ */ jsx4(TextSkeleton.Caption, { className: "w-24" }),
592
+ /* @__PURE__ */ jsx4(UnifiedSkeleton, { variant: "default", className: "w-4 h-4 rounded-full" }),
593
+ /* @__PURE__ */ jsx4(TextSkeleton.Caption, { className: "w-32" }),
594
+ /* @__PURE__ */ jsx4(UnifiedSkeleton, { variant: "default", className: "w-4 h-4 rounded-full" }),
595
+ /* @__PURE__ */ jsx4(TextSkeleton.Caption, { className: "w-24" })
596
+ ] });
597
+ }
598
+ function ResultsHeaderSkeleton({ className }) {
599
+ return /* @__PURE__ */ jsx4("div", { className: cn("flex flex-col md:flex-row justify-between items-start md:items-center gap-4 mb-6", className), children: /* @__PURE__ */ jsx4("div", { className: "space-y-1", children: /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "w-48" }) }) });
600
+ }
601
+ function TwoColumnLayoutSkeleton({
602
+ className,
603
+ sidebarContent,
604
+ mainContent,
605
+ sidebarPosition = "left"
606
+ }) {
607
+ const sidebar = sidebarContent || /* @__PURE__ */ jsx4(CategorySidebarSkeleton, {});
608
+ const main = mainContent || /* @__PURE__ */ jsx4(CardSkeletonGrid, { count: 6 });
609
+ return /* @__PURE__ */ jsx4("div", { className: cn(
610
+ "grid grid-cols-1 lg:grid-cols-[320px_1fr] gap-6 lg:gap-8",
611
+ sidebarPosition === "right" && "lg:grid-cols-[1fr_320px]",
612
+ className
613
+ ), children: sidebarPosition === "left" ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
614
+ /* @__PURE__ */ jsx4("aside", { className: "order-2 lg:order-1", children: sidebar }),
615
+ /* @__PURE__ */ jsx4("main", { className: "order-1 lg:order-2", children: main })
616
+ ] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
617
+ /* @__PURE__ */ jsx4("main", { className: "order-1", children: main }),
618
+ /* @__PURE__ */ jsx4("aside", { className: "order-2", children: sidebar })
619
+ ] }) });
620
+ }
621
+ function ArticleLayoutSkeleton({ className }) {
622
+ return /* @__PURE__ */ jsxs3("article", { className: cn("max-w-4xl mx-auto", className), children: [
623
+ /* @__PURE__ */ jsxs3("header", { className: "mb-8 md:mb-12 space-y-4 md:space-y-6", children: [
624
+ /* @__PURE__ */ jsxs3("div", { className: "flex gap-2", children: [
625
+ /* @__PURE__ */ jsx4(InteractiveSkeleton.Chip, {}),
626
+ /* @__PURE__ */ jsx4(InteractiveSkeleton.Chip, { className: "w-16" })
627
+ ] }),
628
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-3", children: [
629
+ /* @__PURE__ */ jsx4(TextSkeleton.Heading, { className: "w-full" }),
630
+ /* @__PURE__ */ jsx4(TextSkeleton.Heading, { className: "w-3/4" })
631
+ ] }),
632
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-4 pt-4 border-t border-ods-divider", children: [
633
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
634
+ /* @__PURE__ */ jsx4(MediaSkeleton.Avatar, { size: "sm" }),
635
+ /* @__PURE__ */ jsx4(TextSkeleton.Caption, { className: "w-24" })
636
+ ] }),
637
+ /* @__PURE__ */ jsx4(TextSkeleton.Caption, { className: "w-20" }),
638
+ /* @__PURE__ */ jsx4(TextSkeleton.Caption, { className: "w-16" })
639
+ ] })
640
+ ] }),
641
+ /* @__PURE__ */ jsx4("div", { className: "mb-8 md:mb-12", children: /* @__PURE__ */ jsx4(MediaSkeleton.CardImage, { className: "w-full h-64 md:h-96" }) }),
642
+ /* @__PURE__ */ jsxs3("div", { className: "prose prose-invert max-w-none space-y-6", children: [
643
+ Array.from({ length: 12 }).map((_, index) => /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
644
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "w-full" }),
645
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "w-full" }),
646
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "w-5/6" }),
647
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "w-3/4" })
648
+ ] }, index)),
649
+ /* @__PURE__ */ jsxs3("div", { className: "py-4", children: [
650
+ /* @__PURE__ */ jsx4(TextSkeleton.Subheading, { className: "w-2/3 mb-4" }),
651
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
652
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "w-full" }),
653
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "w-4/5" })
654
+ ] })
655
+ ] })
656
+ ] })
657
+ ] });
658
+ }
659
+ function VendorDetailLayoutSkeleton({ className }) {
660
+ return /* @__PURE__ */ jsx4("main", { className: cn("bg-ods-bg min-h-screen", className), children: /* @__PURE__ */ jsxs3("div", { className: "max-w-[1920px] mx-auto px-6 md:px-20 py-6 md:py-10", children: [
661
+ /* @__PURE__ */ jsx4(BreadcrumbSkeleton, { className: "mb-6" }),
662
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col lg:flex-row lg:gap-10", children: [
663
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0", children: [
664
+ /* @__PURE__ */ jsxs3("div", { className: "mb-10", children: [
665
+ /* @__PURE__ */ jsxs3("div", { className: "flex gap-6 mb-6", children: [
666
+ /* @__PURE__ */ jsx4("div", { className: "w-20 h-20 bg-ods-card border border-ods-border rounded-lg animate-pulse flex-shrink-0" }),
667
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-3", children: [
668
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
669
+ /* @__PURE__ */ jsx4("div", { className: "h-12 md:h-16 lg:h-20 bg-[#2A2A2A] rounded animate-pulse w-80 max-w-full" }),
670
+ /* @__PURE__ */ jsx4("div", { className: "h-5 md:h-6 bg-[#2A2A2A] rounded animate-pulse w-32" })
671
+ ] }),
672
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
673
+ /* @__PURE__ */ jsx4("div", { className: "h-8 bg-[#2A2A2A] rounded animate-pulse w-20" }),
674
+ /* @__PURE__ */ jsx4("div", { className: "h-8 bg-[#2A2A2A] rounded animate-pulse w-16" })
675
+ ] })
676
+ ] })
677
+ ] }),
678
+ /* @__PURE__ */ jsx4("div", { className: "w-full h-[300px] md:h-[400px] lg:h-[500px] bg-ods-card border border-ods-border rounded-lg animate-pulse mb-2" }),
679
+ /* @__PURE__ */ jsx4("div", { className: "text-center", children: /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-24 mx-auto" }) })
680
+ ] }),
681
+ /* @__PURE__ */ jsx4("div", { className: "lg:hidden mb-10", children: /* @__PURE__ */ jsxs3("div", { className: "space-y-4", children: [
682
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" }),
683
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
684
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" }),
685
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" })
686
+ ] }),
687
+ /* @__PURE__ */ jsxs3("div", { className: "border border-ods-border rounded-lg overflow-hidden", children: [
688
+ /* @__PURE__ */ jsxs3("div", { className: "bg-ods-card p-4 flex items-center gap-3", children: [
689
+ /* @__PURE__ */ jsx4("div", { className: "w-8 h-8 bg-[#2A2A2A] rounded animate-pulse" }),
690
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
691
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-20" }),
692
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse w-12" })
693
+ ] })
694
+ ] }),
695
+ /* @__PURE__ */ jsx4("div", { className: "p-4 space-y-3", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3", children: [
696
+ /* @__PURE__ */ jsx4("div", { className: "w-6 h-6 bg-[#2A2A2A] rounded animate-pulse" }),
697
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-end gap-1", children: [
698
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-12" }),
699
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded animate-pulse w-8" })
700
+ ] })
701
+ ] }, i)) })
702
+ ] }),
703
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-3", children: [
704
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" }),
705
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" }),
706
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" })
707
+ ] })
708
+ ] }) }),
709
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-6 mb-20", children: [
710
+ /* @__PURE__ */ jsx4("div", { className: "h-8 md:h-10 bg-[#2A2A2A] rounded animate-pulse w-48" }),
711
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-4", children: [
712
+ /* @__PURE__ */ jsx4("div", { className: "h-5 bg-[#2A2A2A] rounded animate-pulse w-48" }),
713
+ /* @__PURE__ */ jsx4("div", { className: "flex flex-wrap gap-2", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx4("div", { className: "h-10 bg-ods-card border border-ods-border rounded-lg animate-pulse w-24" }, i)) })
714
+ ] }),
715
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-4", children: [
716
+ /* @__PURE__ */ jsx4("div", { className: "h-5 bg-[#2A2A2A] rounded animate-pulse w-52" }),
717
+ /* @__PURE__ */ jsx4("div", { className: "flex flex-wrap gap-2", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx4("div", { className: "h-10 bg-ods-card border border-ods-border rounded-lg animate-pulse w-28" }, i)) })
718
+ ] })
719
+ ] }),
720
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-6 mb-20", children: [
721
+ /* @__PURE__ */ jsx4("div", { className: "h-8 md:h-10 bg-[#2A2A2A] rounded animate-pulse w-64" }),
722
+ /* @__PURE__ */ jsx4("div", { className: "bg-ods-card border border-ods-border rounded-lg p-6 md:p-8", children: /* @__PURE__ */ jsxs3("div", { className: "space-y-4", children: [
723
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse" }),
724
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse" }),
725
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse w-5/6" }),
726
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse w-4/5" })
727
+ ] }) })
728
+ ] }),
729
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-6 mb-20", children: [
730
+ /* @__PURE__ */ jsx4("div", { className: "h-8 md:h-10 bg-[#2A2A2A] rounded animate-pulse w-72" }),
731
+ /* @__PURE__ */ jsx4("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "bg-ods-card border border-ods-border rounded-lg p-4 flex gap-4", children: [
732
+ /* @__PURE__ */ jsx4("div", { className: "w-12 h-12 bg-[#2A2A2A] rounded flex-shrink-0 animate-pulse" }),
733
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 space-y-2", children: [
734
+ /* @__PURE__ */ jsx4("div", { className: "h-5 bg-[#2A2A2A] rounded animate-pulse w-3/4" }),
735
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse" })
736
+ ] })
737
+ ] }, i)) })
738
+ ] }),
739
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-6 mb-20", children: [
740
+ /* @__PURE__ */ jsx4("div", { className: "h-8 md:h-10 bg-[#2A2A2A] rounded animate-pulse w-80" }),
741
+ /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
742
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-6", children: [
743
+ /* @__PURE__ */ jsx4("div", { className: "h-5 bg-[#2A2A2A] rounded animate-pulse w-16" }),
744
+ Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "bg-ods-card border border-ods-border rounded-lg p-4 flex gap-3", children: [
745
+ /* @__PURE__ */ jsx4("div", { className: "w-12 h-12 bg-ods-bg border border-ods-border rounded flex-shrink-0 animate-pulse" }),
746
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 space-y-2", children: [
747
+ /* @__PURE__ */ jsx4("div", { className: "h-5 bg-[#2A2A2A] rounded animate-pulse w-2/3" }),
748
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse" })
749
+ ] })
750
+ ] }, i))
751
+ ] }),
752
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-6", children: [
753
+ /* @__PURE__ */ jsx4("div", { className: "h-5 bg-[#2A2A2A] rounded animate-pulse w-16" }),
754
+ Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "bg-ods-card border border-ods-border rounded-lg p-4 flex gap-3", children: [
755
+ /* @__PURE__ */ jsx4("div", { className: "w-12 h-12 bg-ods-bg border border-ods-border rounded flex-shrink-0 animate-pulse" }),
756
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 space-y-2", children: [
757
+ /* @__PURE__ */ jsx4("div", { className: "h-5 bg-[#2A2A2A] rounded animate-pulse w-2/3" }),
758
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse" })
759
+ ] })
760
+ ] }, i))
761
+ ] })
762
+ ] })
763
+ ] }),
764
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-6 mb-20", children: [
765
+ /* @__PURE__ */ jsx4("div", { className: "h-8 md:h-10 bg-[#2A2A2A] rounded animate-pulse w-72" }),
766
+ /* @__PURE__ */ jsx4("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "bg-ods-card border border-ods-border rounded-lg p-6 space-y-4", children: [
767
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-start gap-4", children: [
768
+ /* @__PURE__ */ jsx4("div", { className: "w-16 h-16 bg-ods-bg border border-ods-border rounded-lg animate-pulse flex-shrink-0" }),
769
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 space-y-2", children: [
770
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse w-3/4" }),
771
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-1/2" })
772
+ ] }),
773
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse w-20" })
774
+ ] }),
775
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
776
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse" }),
777
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-5/6" }),
778
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-4/5" })
779
+ ] }),
780
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between pt-2 border-t border-ods-border", children: [
781
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-16" }),
782
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-20" })
783
+ ] })
784
+ ] }, i)) }),
785
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-[#2A2A2A] rounded-md animate-pulse" })
786
+ ] }),
787
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-6 mb-20", children: [
788
+ /* @__PURE__ */ jsx4("div", { className: "h-8 md:h-10 bg-[#2A2A2A] rounded animate-pulse w-64" }),
789
+ /* @__PURE__ */ jsx4("div", { className: "space-y-3", children: /* @__PURE__ */ jsxs3("div", { className: "flex gap-3", children: [
790
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 bg-ods-bg border border-ods-border rounded-lg overflow-hidden", children: [
791
+ /* @__PURE__ */ jsxs3("div", { className: "border-b border-ods-border p-3", children: [
792
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded animate-pulse w-8 mb-2" }),
793
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse w-full" })
794
+ ] }),
795
+ /* @__PURE__ */ jsxs3("div", { className: "p-3", children: [
796
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded animate-pulse w-16 mb-2" }),
797
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
798
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-full" }),
799
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-3/4" }),
800
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-1/2" })
801
+ ] })
802
+ ] })
803
+ ] }),
804
+ /* @__PURE__ */ jsx4("div", { className: "flex items-stretch", children: /* @__PURE__ */ jsx4("div", { className: "h-[120px] w-20 bg-[#2A2A2A] rounded-lg animate-pulse" }) })
805
+ ] }) }),
806
+ /* @__PURE__ */ jsx4("div", { className: "space-y-4", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "bg-ods-card border border-ods-border rounded-lg p-4", children: [
807
+ /* @__PURE__ */ jsx4("div", { className: "flex flex-col gap-3 mb-3 min-[420px]:flex-row min-[420px]:items-center min-[420px]:justify-between min-[420px]:gap-2", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
808
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 bg-ods-card border border-ods-border rounded-lg py-2 px-3", children: [
809
+ /* @__PURE__ */ jsx4("div", { className: "w-8 h-8 bg-[#2A2A2A] rounded-lg animate-pulse" }),
810
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-20" })
811
+ ] }),
812
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-12" })
813
+ ] }) }),
814
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
815
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse w-2/3" }),
816
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-1", children: [
817
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-full" }),
818
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-4/5" }),
819
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-3/5" })
820
+ ] })
821
+ ] })
822
+ ] }, i)) })
823
+ ] })
824
+ ] }),
825
+ /* @__PURE__ */ jsx4("div", { className: "hidden lg:block w-[290px] flex-shrink-0", children: /* @__PURE__ */ jsxs3("div", { className: "space-y-4", children: [
826
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" }),
827
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
828
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" }),
829
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" })
830
+ ] }),
831
+ /* @__PURE__ */ jsxs3("div", { className: "border border-ods-border rounded-lg overflow-hidden", children: [
832
+ /* @__PURE__ */ jsxs3("div", { className: "bg-ods-card p-4 flex items-center gap-3", children: [
833
+ /* @__PURE__ */ jsx4("div", { className: "w-8 h-8 bg-[#2A2A2A] rounded animate-pulse" }),
834
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
835
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-20" }),
836
+ /* @__PURE__ */ jsx4("div", { className: "h-6 bg-[#2A2A2A] rounded animate-pulse w-12" })
837
+ ] })
838
+ ] }),
839
+ /* @__PURE__ */ jsx4("div", { className: "p-4 space-y-3", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3", children: [
840
+ /* @__PURE__ */ jsx4("div", { className: "w-6 h-6 bg-[#2A2A2A] rounded animate-pulse" }),
841
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-end gap-1", children: [
842
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded animate-pulse w-12" }),
843
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded animate-pulse w-8" })
844
+ ] })
845
+ ] }, i)) })
846
+ ] }),
847
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-3", children: [
848
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" }),
849
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" }),
850
+ /* @__PURE__ */ jsx4("div", { className: "h-12 bg-ods-card border border-ods-border rounded-lg animate-pulse" })
851
+ ] })
852
+ ] }) })
853
+ ] })
854
+ ] }) });
855
+ }
856
+ function StatsSectionSkeleton({
857
+ className,
858
+ columns = 3
859
+ }) {
860
+ return /* @__PURE__ */ jsx4("div", { className: cn(
861
+ "grid gap-6 mb-12 md:mb-16",
862
+ columns === 3 && "grid-cols-1 md:grid-cols-3",
863
+ columns === 4 && "grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
864
+ className
865
+ ), children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsx4("div", { className: "bg-ods-card border border-ods-border rounded-lg p-6", children: /* @__PURE__ */ jsxs3("div", { className: "space-y-4", children: [
866
+ /* @__PURE__ */ jsx4(MediaSkeleton.Icon, { size: "lg" }),
867
+ /* @__PURE__ */ jsx4(TextSkeleton.Subheading, { className: "w-3/4" }),
868
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
869
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "w-full" }),
870
+ /* @__PURE__ */ jsx4(TextSkeleton.Body, { className: "w-3/4" })
871
+ ] })
872
+ ] }) }, i)) });
873
+ }
874
+ function BlogCardGridSkeleton({ className }) {
875
+ return /* @__PURE__ */ jsx4("div", { className: cn("space-y-6", className), children: /* @__PURE__ */ jsx4(
876
+ CardSkeletonGrid,
877
+ {
878
+ count: 4,
879
+ variant: "blog",
880
+ className: "grid-cols-1 md:grid-cols-2"
881
+ }
882
+ ) });
883
+ }
884
+ function VendorGridSkeleton({ className }) {
885
+ return /* @__PURE__ */ jsx4("div", { className: cn("space-y-6", className), children: /* @__PURE__ */ jsx4(
886
+ CardSkeletonGrid,
887
+ {
888
+ count: 12,
889
+ variant: "vendor",
890
+ className: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
891
+ }
892
+ ) });
893
+ }
894
+ function SlackCommunitySkeleton() {
895
+ return /* @__PURE__ */ jsx4(
896
+ "section",
897
+ {
898
+ className: "w-full bg-ods-bg px-4 md:px-20 lg:px-20 py-12 md:py-20",
899
+ "aria-label": "Slack Community Loading",
900
+ children: /* @__PURE__ */ jsxs3("div", { className: "w-full flex flex-col gap-4 md:gap-6", children: [
901
+ /* @__PURE__ */ jsx4("div", { className: "w-full", children: /* @__PURE__ */ jsx4("div", { className: "h-8 md:h-12 lg:h-14 bg-[#2A2A2A] rounded-lg animate-pulse max-w-md" }) }),
902
+ /* @__PURE__ */ jsxs3("div", { className: "w-full flex flex-col lg:flex-row lg:justify-end lg:items-start gap-4 md:gap-6 min-w-0", children: [
903
+ /* @__PURE__ */ jsx4("div", { className: "w-full lg:w-[290px] lg:max-w-[290px] bg-ods-bg border border-ods-border rounded flex flex-col flex-shrink-0 overflow-hidden animate-pulse", children: /* @__PURE__ */ jsxs3("div", { className: "p-4 space-y-4", children: [
904
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
905
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
906
+ /* @__PURE__ */ jsx4("div", { className: "h-4 bg-[#2A2A2A] rounded w-24" }),
907
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-16" })
908
+ ] }),
909
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-32" })
910
+ ] }),
911
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
912
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-16 mb-2" }),
913
+ Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 px-2 py-3 min-h-[48px]", children: [
914
+ /* @__PURE__ */ jsx4("div", { className: "w-4 h-4 bg-[#2A2A2A] rounded" }),
915
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1", children: [
916
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-24 mb-1" }),
917
+ /* @__PURE__ */ jsx4("div", { className: "h-2 bg-[#2A2A2A] rounded w-16" })
918
+ ] })
919
+ ] }, i))
920
+ ] }),
921
+ /* @__PURE__ */ jsx4("div", { className: "border-t border-ods-border pt-3 mt-2", children: /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
922
+ /* @__PURE__ */ jsxs3("div", { className: "flex justify-between", children: [
923
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-16" }),
924
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-8" })
925
+ ] }),
926
+ /* @__PURE__ */ jsxs3("div", { className: "flex justify-between", children: [
927
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-20" }),
928
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-8" })
929
+ ] })
930
+ ] }) })
931
+ ] }) }),
932
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-h-[450px] h-[450px] md:min-h-[500px] md:h-[500px] lg:min-h-[600px] lg:h-[600px] bg-ods-card border border-ods-border rounded-lg flex flex-col min-w-0 animate-pulse", children: [
933
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between p-4 md:p-6 border-b border-ods-border bg-ods-bg h-[56px] md:h-[60px] flex-shrink-0", children: [
934
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
935
+ /* @__PURE__ */ jsx4("div", { className: "h-3 md:h-4 bg-[#2A2A2A] rounded w-3 md:w-4" }),
936
+ /* @__PURE__ */ jsx4("div", { className: "h-3 md:h-4 bg-[#2A2A2A] rounded w-24 md:w-32" })
937
+ ] }),
938
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-12 md:w-16" })
939
+ ] }),
940
+ /* @__PURE__ */ jsx4("div", { className: "flex-1 bg-ods-bg p-4 md:p-6 space-y-3 md:space-y-4 overflow-hidden min-h-[280px] md:min-h-[320px] lg:min-h-[420px]", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "flex gap-2 md:gap-3", children: [
941
+ /* @__PURE__ */ jsx4("div", { className: "w-10 h-10 md:w-12 md:h-12 bg-[#2A2A2A] rounded-lg flex-shrink-0" }),
942
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1", children: [
943
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 mb-1", children: [
944
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-16 md:w-20" }),
945
+ /* @__PURE__ */ jsx4("div", { className: "h-3 bg-[#2A2A2A] rounded w-12 md:w-16" })
946
+ ] }),
947
+ /* @__PURE__ */ jsx4("div", { className: "h-3 md:h-4 bg-[#2A2A2A] rounded w-full" })
948
+ ] })
949
+ ] }, i)) }),
950
+ /* @__PURE__ */ jsx4("div", { className: "p-4 md:p-6 border-t border-ods-border bg-ods-card h-[72px] md:h-[80px] flex-shrink-0", children: /* @__PURE__ */ jsx4("div", { className: "flex items-end gap-3 justify-center md:justify-end", children: /* @__PURE__ */ jsx4("div", { className: "h-10 md:h-12 bg-[#2A2A2A] rounded-lg w-28 md:w-32" }) }) })
951
+ ] })
952
+ ] })
953
+ ] })
954
+ }
955
+ );
956
+ }
957
+
958
+ // src/components/docs/use-document-tree.ts
959
+ import { useState, useEffect, useCallback as useCallback2, useRef as useRef2 } from "react";
960
+
961
+ // src/components/docs/doc-navigation-context.tsx
962
+ import React, { createContext, useCallback, useContext, useRef } from "react";
963
+ import { jsx as jsx5 } from "react/jsx-runtime";
964
+ var DocNavigationContext = createContext(null);
965
+ function DocNavigationProvider({ children }) {
966
+ const navMap = useRef(/* @__PURE__ */ new Map());
967
+ const register = useCallback((nav) => {
968
+ const existing = navMap.current.get(nav.baseRoute);
969
+ if (existing && existing !== nav) {
970
+ console.warn(
971
+ `[DocNavigationContext] duplicate registration for ${nav.baseRoute}; replacing`
972
+ );
973
+ }
974
+ navMap.current.set(nav.baseRoute, nav);
975
+ return () => {
976
+ if (navMap.current.get(nav.baseRoute) === nav) {
977
+ navMap.current.delete(nav.baseRoute);
978
+ }
979
+ };
980
+ }, []);
981
+ const findOwningNavigator = useCallback((path) => {
982
+ const baseRoutes = Array.from(navMap.current.keys()).sort((a, b) => b.length - a.length);
983
+ for (const baseRoute of baseRoutes) {
984
+ if (path === baseRoute || path.startsWith(`${baseRoute}/`)) {
985
+ return navMap.current.get(baseRoute) ?? null;
986
+ }
987
+ }
988
+ if (navMap.current.size === 1) {
989
+ return navMap.current.values().next().value ?? null;
990
+ }
991
+ return null;
992
+ }, []);
993
+ const navigate = useCallback(
994
+ (path) => {
995
+ const nav = findOwningNavigator(path);
996
+ if (!nav) return false;
997
+ const node = nav.findNodeByPath(path);
998
+ if (!node) return false;
999
+ nav.selectNode(node);
1000
+ return true;
1001
+ },
1002
+ [findOwningNavigator]
1003
+ );
1004
+ const isAvailable = useCallback(() => navMap.current.size > 0, []);
1005
+ const value = React.useMemo(
1006
+ () => ({ register, navigate, isAvailable }),
1007
+ [register, navigate, isAvailable]
1008
+ );
1009
+ return /* @__PURE__ */ jsx5(DocNavigationContext.Provider, { value, children });
1010
+ }
1011
+ function useDocNavigation() {
1012
+ const ctx = useContext(DocNavigationContext);
1013
+ if (!ctx) {
1014
+ return {
1015
+ register: () => () => {
1016
+ },
1017
+ navigate: () => false,
1018
+ isAvailable: () => false
1019
+ };
1020
+ }
1021
+ return ctx;
1022
+ }
1023
+
1024
+ // src/components/docs/use-document-tree.ts
1025
+ function scrollToContent() {
1026
+ const article = document.querySelector("article");
1027
+ if (article) {
1028
+ scrollElementIntoView(article, { headerOffset: 80 });
1029
+ } else {
1030
+ window.scrollTo({ top: 0, behavior: "smooth" });
1031
+ }
1032
+ }
1033
+ function useDocumentTree(config, initialPath) {
1034
+ const { structureEndpoint, contentEndpoint, baseRoute } = config;
1035
+ const folderIndexFile = config.folderIndexFile ?? DEFAULT_FOLDER_INDEX_FILE;
1036
+ const cleanInitialPath = stripFolderIndexFromPath(
1037
+ initialPath?.replace(/\/$/, "") || "",
1038
+ folderIndexFile
1039
+ );
1040
+ const [structure, setStructure] = useState([]);
1041
+ const [selectedPath, setSelectedPath] = useState(cleanInitialPath);
1042
+ const [content, setContent] = useState(null);
1043
+ const [isLoadingStructure, setIsLoadingStructure] = useState(true);
1044
+ const [isLoadingContent, setIsLoadingContent] = useState(false);
1045
+ const [error, setError] = useState(null);
1046
+ const [expandedNodes, setExpandedNodes] = useState(/* @__PURE__ */ new Set());
1047
+ const [isInitialized, setIsInitialized] = useState(false);
1048
+ const lastFetchedPath = useRef2(null);
1049
+ const normalizedBaseRoute = baseRoute.replace(/\/$/, "");
1050
+ const selectedPathRef = useRef2(selectedPath);
1051
+ selectedPathRef.current = selectedPath;
1052
+ const docNavigation = useDocNavigation();
1053
+ useEffect(() => {
1054
+ const handlePopState = () => {
1055
+ const pathname = window.location.pathname;
1056
+ let pathFromUrl = "";
1057
+ if (pathname === normalizedBaseRoute || pathname === `${normalizedBaseRoute}/`) {
1058
+ pathFromUrl = "";
1059
+ } else if (pathname.startsWith(`${normalizedBaseRoute}/`)) {
1060
+ pathFromUrl = pathname.substring(`${normalizedBaseRoute}/`.length);
1061
+ }
1062
+ pathFromUrl = stripFolderIndexFromPath(pathFromUrl, folderIndexFile);
1063
+ if (pathFromUrl !== selectedPathRef.current) {
1064
+ setSelectedPath(pathFromUrl);
1065
+ if (pathFromUrl) {
1066
+ const parentPath = pathFromUrl.includes("/") ? pathFromUrl.substring(0, pathFromUrl.lastIndexOf("/")) : pathFromUrl;
1067
+ setExpandedNodes(new Set(getDocAncestorNodeIds(parentPath)));
1068
+ }
1069
+ setTimeout(() => {
1070
+ scrollToContent();
1071
+ }, 150);
1072
+ }
1073
+ };
1074
+ window.addEventListener("popstate", handlePopState);
1075
+ return () => window.removeEventListener("popstate", handlePopState);
1076
+ }, [normalizedBaseRoute, folderIndexFile]);
1077
+ useEffect(() => {
1078
+ if (!isInitialized) {
1079
+ const speculativeContentPath = cleanInitialPath || folderIndexFile;
1080
+ lastFetchedPath.current = speculativeContentPath;
1081
+ fetchContent(speculativeContentPath);
1082
+ fetchStructure();
1083
+ setIsInitialized(true);
1084
+ }
1085
+ }, [isInitialized]);
1086
+ useEffect(() => {
1087
+ if (selectedPath === null || selectedPath === void 0) return;
1088
+ if (!structure || structure.length === 0) return;
1089
+ let pathToFetch = null;
1090
+ if (selectedPath === "") {
1091
+ pathToFetch = folderIndexFile;
1092
+ } else {
1093
+ const node = findDocNodeByPath(selectedPath, structure);
1094
+ if (node && node.type === "folder" && !node.hasReadme) {
1095
+ return;
1096
+ }
1097
+ pathToFetch = selectedPath;
1098
+ if (node && node.type === "folder" && node.hasReadme) {
1099
+ pathToFetch = `${selectedPath}/${folderIndexFile}`;
1100
+ }
1101
+ }
1102
+ if (pathToFetch === lastFetchedPath.current) {
1103
+ return;
1104
+ }
1105
+ if (pathToFetch) {
1106
+ lastFetchedPath.current = pathToFetch;
1107
+ fetchContent(pathToFetch);
1108
+ }
1109
+ }, [selectedPath, structure, folderIndexFile]);
1110
+ const fetchStructure = async () => {
1111
+ try {
1112
+ setIsLoadingStructure(true);
1113
+ setError(null);
1114
+ const response = await fetch(structureEndpoint);
1115
+ if (!response.ok) {
1116
+ throw new Error("Failed to load documentation structure");
1117
+ }
1118
+ const result = await response.json();
1119
+ if (result.success && result.data) {
1120
+ setStructure(result.data);
1121
+ if (cleanInitialPath) {
1122
+ const pathForExpansion = cleanInitialPath.includes(".") ? cleanInitialPath.substring(0, cleanInitialPath.lastIndexOf("/")) : cleanInitialPath;
1123
+ if (pathForExpansion) {
1124
+ setExpandedNodes(new Set(getDocAncestorNodeIds(pathForExpansion)));
1125
+ }
1126
+ } else if (result.data.length > 0) {
1127
+ const hasRootReadme = result.data.some(
1128
+ (node) => node.type === "file" && node.path === folderIndexFile
1129
+ );
1130
+ if (!hasRootReadme) {
1131
+ const firstNode = result.data[0];
1132
+ if (firstNode.type === "folder") {
1133
+ setExpandedNodes(/* @__PURE__ */ new Set([firstNode.id]));
1134
+ if (firstNode.hasReadme) {
1135
+ setSelectedPath(firstNode.path);
1136
+ window.history.replaceState({}, "", `${normalizedBaseRoute}/${firstNode.path}`);
1137
+ }
1138
+ }
1139
+ }
1140
+ }
1141
+ } else {
1142
+ setError("Failed to load documentation structure");
1143
+ }
1144
+ } catch (err) {
1145
+ console.error("Error fetching documentation structure:", err);
1146
+ setError(err instanceof Error ? err.message : "Failed to load documentation");
1147
+ } finally {
1148
+ setIsLoadingStructure(false);
1149
+ }
1150
+ };
1151
+ const fetchContent = async (path) => {
1152
+ try {
1153
+ setIsLoadingContent(true);
1154
+ const response = await fetch(`${contentEndpoint}?path=${encodeURIComponent(path)}`);
1155
+ if (path !== lastFetchedPath.current) return;
1156
+ if (!response.ok) {
1157
+ if (response.status === 404) {
1158
+ const result2 = await response.json().catch(() => ({}));
1159
+ if (path !== lastFetchedPath.current) return;
1160
+ if (path === folderIndexFile && selectedPath === "") {
1161
+ setError(null);
1162
+ setContent(null);
1163
+ return;
1164
+ }
1165
+ setError(result2.error || "Documentation file not found");
1166
+ setContent(null);
1167
+ return;
1168
+ }
1169
+ throw new Error("Failed to load documentation content");
1170
+ }
1171
+ const result = await response.json();
1172
+ if (path !== lastFetchedPath.current) return;
1173
+ setError(null);
1174
+ if (result.success && result.data) {
1175
+ if (result.redirect && result.correctPath !== void 0) {
1176
+ const correctedPath = result.correctPath;
1177
+ setSelectedPath(correctedPath);
1178
+ window.history.replaceState({}, "", `${normalizedBaseRoute}/${correctedPath}`);
1179
+ setContent(result.data);
1180
+ } else {
1181
+ setContent(result.data);
1182
+ }
1183
+ } else {
1184
+ setError(result.error || "Failed to load content");
1185
+ setContent(null);
1186
+ }
1187
+ } catch (err) {
1188
+ if (path !== lastFetchedPath.current) return;
1189
+ console.error("Error fetching documentation content:", err);
1190
+ setError(err instanceof Error ? err.message : "Failed to load content");
1191
+ setContent(null);
1192
+ } finally {
1193
+ if (path === lastFetchedPath.current) setIsLoadingContent(false);
1194
+ }
1195
+ };
1196
+ const toggleNode = useCallback2((nodeId) => {
1197
+ setExpandedNodes((prev) => {
1198
+ const next = new Set(prev);
1199
+ if (next.has(nodeId)) {
1200
+ next.delete(nodeId);
1201
+ } else {
1202
+ next.add(nodeId);
1203
+ }
1204
+ return next;
1205
+ });
1206
+ }, []);
1207
+ const selectNode = useCallback2((node) => {
1208
+ if (node.type === "folder") {
1209
+ setExpandedNodes((prev) => {
1210
+ if (prev.has(node.id)) {
1211
+ const ancestorIds = getDocAncestorNodeIds(node.path);
1212
+ ancestorIds.pop();
1213
+ return new Set(ancestorIds);
1214
+ } else {
1215
+ return new Set(getDocAncestorNodeIds(node.path));
1216
+ }
1217
+ });
1218
+ if (node.hasReadme) {
1219
+ lastFetchedPath.current = null;
1220
+ setSelectedPath(node.path);
1221
+ window.history.pushState({}, "", `${normalizedBaseRoute}/${node.path}`);
1222
+ setTimeout(() => {
1223
+ scrollToContent();
1224
+ }, 150);
1225
+ } else {
1226
+ setSelectedPath(node.path);
1227
+ }
1228
+ } else {
1229
+ const lastSlash = node.path.lastIndexOf("/");
1230
+ if (lastSlash > 0) {
1231
+ const parentPath = node.path.substring(0, lastSlash);
1232
+ setExpandedNodes(new Set(getDocAncestorNodeIds(parentPath)));
1233
+ }
1234
+ lastFetchedPath.current = null;
1235
+ setSelectedPath(node.path);
1236
+ window.history.pushState({}, "", `${normalizedBaseRoute}/${node.path}`);
1237
+ setTimeout(() => {
1238
+ scrollToContent();
1239
+ }, 150);
1240
+ }
1241
+ }, [normalizedBaseRoute]);
1242
+ const navigateToDoc = useCallback2((path, options) => {
1243
+ const hashIndex = path.indexOf("#");
1244
+ const anchor = hashIndex !== -1 ? path.substring(hashIndex) : "";
1245
+ const cleanPath = path.replace(/\/$/, "").split("#")[0];
1246
+ const scrollAfterNav = () => {
1247
+ if (anchor) {
1248
+ setTimeout(() => {
1249
+ const el = document.getElementById(anchor.substring(1));
1250
+ if (el) {
1251
+ scrollElementIntoView(el, { headerOffset: 80 });
1252
+ } else {
1253
+ scrollToContent();
1254
+ }
1255
+ }, 300);
1256
+ } else {
1257
+ setTimeout(() => {
1258
+ scrollToContent();
1259
+ }, 150);
1260
+ }
1261
+ };
1262
+ if (options?.expandFolder) {
1263
+ lastFetchedPath.current = null;
1264
+ setSelectedPath(cleanPath);
1265
+ window.history.pushState({}, "", `${normalizedBaseRoute}/${cleanPath}${anchor}`);
1266
+ const pathParts2 = cleanPath.split("/");
1267
+ const nodeIdsToExpand = [];
1268
+ let currentPath2 = "";
1269
+ for (const part of pathParts2) {
1270
+ currentPath2 = currentPath2 ? `${currentPath2}-${part}` : part;
1271
+ nodeIdsToExpand.push(currentPath2.toLowerCase());
1272
+ }
1273
+ setExpandedNodes(new Set(nodeIdsToExpand));
1274
+ if (options?.fromInternalLink) {
1275
+ scrollAfterNav();
1276
+ }
1277
+ setError(null);
1278
+ return;
1279
+ }
1280
+ const pathForSelection = stripFolderIndexFromPath(cleanPath, folderIndexFile);
1281
+ const urlPath = pathForSelection;
1282
+ lastFetchedPath.current = null;
1283
+ setSelectedPath(pathForSelection);
1284
+ window.history.pushState({}, "", `${normalizedBaseRoute}/${urlPath}${anchor}`);
1285
+ if (options?.fromInternalLink) {
1286
+ scrollAfterNav();
1287
+ }
1288
+ const pathParts = cleanPath.split("/");
1289
+ const parentIds = [];
1290
+ let currentPath = "";
1291
+ const partsToProcess = cleanPath.includes(".") ? pathParts.slice(0, -1) : pathParts;
1292
+ for (const part of partsToProcess) {
1293
+ currentPath = currentPath ? `${currentPath}-${part}` : part;
1294
+ parentIds.push(currentPath.toLowerCase());
1295
+ }
1296
+ if (parentIds.length > 0) {
1297
+ setExpandedNodes(new Set(parentIds));
1298
+ }
1299
+ }, [structure, normalizedBaseRoute, folderIndexFile]);
1300
+ useEffect(() => {
1301
+ return docNavigation.register({
1302
+ baseRoute: normalizedBaseRoute,
1303
+ findNodeByPath: (path) => {
1304
+ const clean = stripFolderIndexFromPath(path.replace(/\/$/, "").split("#")[0], folderIndexFile);
1305
+ return findDocNodeByPath(clean, structure) ?? null;
1306
+ },
1307
+ selectNode
1308
+ });
1309
+ }, [docNavigation, normalizedBaseRoute, structure, selectNode, folderIndexFile]);
1310
+ return {
1311
+ structure,
1312
+ selectedPath,
1313
+ setSelectedPath,
1314
+ content,
1315
+ isLoadingStructure,
1316
+ isLoadingContent,
1317
+ error,
1318
+ expandedNodes,
1319
+ toggleNode,
1320
+ selectNode,
1321
+ navigateToDoc,
1322
+ refetch: fetchStructure,
1323
+ setExpandedNodes
1324
+ };
1325
+ }
1326
+
1327
+ // src/components/docs/use-scroll-spy.ts
1328
+ import { useState as useState2, useRef as useRef3, useCallback as useCallback3, useEffect as useEffect2, useMemo } from "react";
1329
+ var SCROLL_OFFSET = 100;
1330
+ function useScrollSpy(sections) {
1331
+ const [activeSection, setActiveSection] = useState2("");
1332
+ const isScrollingFromClick = useRef3(false);
1333
+ const sectionIds = useMemo(
1334
+ () => sections?.map((s) => s.id).join(",") ?? "",
1335
+ [sections]
1336
+ );
1337
+ const stableSections = useRef3(sections);
1338
+ if (sectionIds !== (stableSections.current?.map((s) => s.id).join(",") ?? "")) {
1339
+ stableSections.current = sections;
1340
+ }
1341
+ const handleSectionClick = useCallback3((sectionId) => {
1342
+ const targetElement = document.getElementById(sectionId);
1343
+ if (!targetElement) return;
1344
+ isScrollingFromClick.current = true;
1345
+ setActiveSection(sectionId);
1346
+ scrollElementIntoView(targetElement, { headerOffset: SCROLL_OFFSET });
1347
+ setTimeout(() => {
1348
+ isScrollingFromClick.current = false;
1349
+ }, 800);
1350
+ }, []);
1351
+ useEffect2(() => {
1352
+ const currentSections = stableSections.current;
1353
+ if (!currentSections || currentSections.length === 0) return;
1354
+ const handleScroll = () => {
1355
+ if (isScrollingFromClick.current) return;
1356
+ const scrollPosition = window.scrollY + SCROLL_OFFSET;
1357
+ let currentSection = currentSections[0]?.id || "";
1358
+ for (let i = currentSections.length - 1; i >= 0; i--) {
1359
+ const element = document.getElementById(currentSections[i].id);
1360
+ if (element && scrollPosition >= element.offsetTop) {
1361
+ currentSection = currentSections[i].id;
1362
+ break;
1363
+ }
1364
+ }
1365
+ setActiveSection((prev) => prev !== currentSection ? currentSection : prev);
1366
+ };
1367
+ let scrollTimer;
1368
+ const throttledScroll = () => {
1369
+ clearTimeout(scrollTimer);
1370
+ scrollTimer = setTimeout(handleScroll, 100);
1371
+ };
1372
+ window.addEventListener("scroll", throttledScroll);
1373
+ handleScroll();
1374
+ return () => {
1375
+ window.removeEventListener("scroll", throttledScroll);
1376
+ clearTimeout(scrollTimer);
1377
+ };
1378
+ }, [sectionIds]);
1379
+ return { activeSection, handleSectionClick };
1380
+ }
1381
+
1382
+ // src/components/docs/doc-viewer.tsx
1383
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1384
+ var DEFAULT_DOC_VIEWER_PALETTE = {
1385
+ background: "bg-ods-bg",
1386
+ containerBackground: "transparent",
1387
+ headerText: "text-ods-text-primary",
1388
+ primaryText: "text-ods-text-primary",
1389
+ secondaryText: "text-ods-text-secondary",
1390
+ accent: "var(--ods-accent)",
1391
+ border: "border-ods-border",
1392
+ cardBackground: "bg-ods-card"
1393
+ };
1394
+ function DocViewer(props) {
1395
+ return /* @__PURE__ */ jsx6(DocViewerContent, { ...props });
1396
+ }
1397
+ function DocViewerContent({
1398
+ sourceId,
1399
+ renderContent,
1400
+ renderSkeleton,
1401
+ chatSource,
1402
+ title,
1403
+ colorPalette = DEFAULT_DOC_VIEWER_PALETTE,
1404
+ className = "",
1405
+ docPath,
1406
+ sidebarLabel = "DOCUMENTATION",
1407
+ structureEndpoint,
1408
+ contentEndpoint,
1409
+ baseRoute,
1410
+ emptyStateText,
1411
+ showAIChat = false,
1412
+ folderIndexFile
1413
+ }) {
1414
+ const resolvedStructureEndpoint = structureEndpoint ?? `/api/docs/sources/${sourceId}/structure`;
1415
+ const resolvedContentEndpoint = contentEndpoint ?? `/api/docs/sources/${sourceId}/content`;
1416
+ const {
1417
+ structure,
1418
+ selectedPath,
1419
+ content,
1420
+ isLoadingStructure,
1421
+ isLoadingContent,
1422
+ error,
1423
+ expandedNodes,
1424
+ selectNode,
1425
+ toggleNode,
1426
+ navigateToDoc
1427
+ } = useDocumentTree(
1428
+ {
1429
+ structureEndpoint: resolvedStructureEndpoint,
1430
+ contentEndpoint: resolvedContentEndpoint,
1431
+ baseRoute,
1432
+ folderIndexFile
1433
+ },
1434
+ docPath
1435
+ );
1436
+ const { activeSection, handleSectionClick } = useScrollSpy(content?.sections);
1437
+ const docNav = useDocNavigation();
1438
+ const docSearch = useDocSearch({
1439
+ source: chatSource,
1440
+ baseRoute,
1441
+ onNavigate: (path) => navigateToDoc(path, { fromInternalLink: true }),
1442
+ onInPageSwap: (path) => docNav.navigate(path)
1443
+ });
1444
+ const renderedContent = useMemo2(() => {
1445
+ if (!content) return null;
1446
+ return renderContent(content, {
1447
+ onInternalLinkClick: navigateToDoc,
1448
+ currentPath: selectedPath,
1449
+ sourceId
1450
+ });
1451
+ }, [content, selectedPath, renderContent, navigateToDoc, sourceId]);
1452
+ const selectedNodeDocType = selectedPath && structure.length > 0 ? findDocNodeByPath(selectedPath, structure)?.documentType : void 0;
1453
+ const activeDocType = content?.documentType ?? selectedNodeDocType;
1454
+ const isMarkdownContent = !activeDocType || activeDocType === "markdown";
1455
+ const showStickyNav = isMarkdownContent;
1456
+ const stickyNavSections = content?.sections?.map((s) => ({ id: s.id, label: s.title })) ?? [];
1457
+ const isColorValue = colorPalette.background.startsWith("#") || colorPalette.background.startsWith("rgb") || colorPalette.background.startsWith("var(");
1458
+ const bgStyle = isColorValue ? { backgroundColor: colorPalette.background } : {};
1459
+ const bgClass = !isColorValue ? colorPalette.background : "";
1460
+ const containerBgStyle = colorPalette.containerBackground !== "transparent" ? { backgroundColor: colorPalette.containerBackground } : {};
1461
+ const defaultEmptyText = structure.length > 0 ? "Select a document from the sidebar to view" : "No documents yet. Add content from the admin panel.";
1462
+ const resolvedEmptyText = emptyStateText || defaultEmptyText;
1463
+ return /* @__PURE__ */ jsx6("section", { className: `${bgClass} ${className}`, style: bgStyle, children: /* @__PURE__ */ jsx6(
1464
+ "div",
1465
+ {
1466
+ className: "max-w-[1920px] px-6 md:px-20 py-6 md:py-10 mx-auto",
1467
+ style: containerBgStyle,
1468
+ children: /* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-6", children: [
1469
+ /* @__PURE__ */ jsx6("div", { className: "flex flex-col gap-4", children: typeof title === "string" ? /* @__PURE__ */ jsx6(PageHeading, { children: title }) : title }),
1470
+ showAIChat && /* @__PURE__ */ jsx6(
1471
+ DocSearchBar,
1472
+ {
1473
+ placeholder: `Search ${sidebarLabel?.toLowerCase() || "documents"}...`,
1474
+ query: docSearch.query,
1475
+ onQueryChange: docSearch.setQuery,
1476
+ results: docSearch.results,
1477
+ isLoading: docSearch.isLoading,
1478
+ onResultSelect: docSearch.handleResultSelect,
1479
+ showDropdown: docSearch.keepDropdownOpen
1480
+ }
1481
+ ),
1482
+ error && /* @__PURE__ */ jsx6("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border bg-ods-card p-8 text-center max-w-md border-ods-border", children: [
1483
+ /* @__PURE__ */ jsx6("h2", { className: "text-xl font-semibold text-ods-text-primary", children: "Error Loading Documents" }),
1484
+ /* @__PURE__ */ jsxs4("p", { className: "mt-2 text-ods-text-secondary", children: [
1485
+ error,
1486
+ ". Please try again later."
1487
+ ] })
1488
+ ] }) }),
1489
+ !error && /* @__PURE__ */ jsxs4("div", { className: "flex flex-col lg:flex-row gap-6 lg:gap-10 items-start flex-1", children: [
1490
+ /* @__PURE__ */ jsx6("div", { className: "w-full lg:w-[320px] lg:shrink-0", children: /* @__PURE__ */ jsx6("div", { className: "lg:sticky lg:top-20", children: isLoadingStructure ? /* @__PURE__ */ jsx6(CategorySidebarSkeleton, {}) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
1491
+ /* @__PURE__ */ jsx6(PersistentMobileDropdown, { isLoading: false, children: /* @__PURE__ */ jsx6(
1492
+ MobileNavigationDropdown,
1493
+ {
1494
+ nodes: structure,
1495
+ selectedPath,
1496
+ expandedNodes,
1497
+ onNodeClick: selectNode,
1498
+ onToggleExpand: toggleNode,
1499
+ isLoading: false,
1500
+ folderIndexFile
1501
+ }
1502
+ ) }),
1503
+ /* @__PURE__ */ jsx6(PersistentSidebar, { isLoading: false, children: /* @__PURE__ */ jsx6("div", { className: "hidden lg:block", children: /* @__PURE__ */ jsxs4("div", { className: "space-y-4", children: [
1504
+ /* @__PURE__ */ jsx6("h3", { className: "text-[14px] font-['Azeret_Mono'] font-semibold uppercase text-ods-text-secondary tracking-[-0.02em] leading-[1.43em]", children: sidebarLabel }),
1505
+ /* @__PURE__ */ jsx6(
1506
+ MultiLevelNavigation,
1507
+ {
1508
+ nodes: structure,
1509
+ selectedPath,
1510
+ expandedNodes,
1511
+ onNodeClick: selectNode,
1512
+ onToggleExpand: toggleNode,
1513
+ isLoading: false,
1514
+ folderIndexFile
1515
+ }
1516
+ )
1517
+ ] }) }) })
1518
+ ] }) }) }),
1519
+ /* @__PURE__ */ jsx6("div", { className: "flex-1 min-w-0 w-full", children: /* @__PURE__ */ jsxs4(
1520
+ "div",
1521
+ {
1522
+ className: `grid grid-cols-1 ${showStickyNav && stickyNavSections.length > 0 || isLoadingContent || isLoadingStructure ? "lg:grid-cols-[1fr_280px]" : ""} gap-8`,
1523
+ children: [
1524
+ /* @__PURE__ */ jsx6("div", { className: `w-full ${isMarkdownContent ? "max-w-4xl mx-auto" : ""}`, children: /* @__PURE__ */ jsx6("article", { className: "space-y-2", children: isLoadingContent || isLoadingStructure ? renderSkeleton(selectedNodeDocType) : !content ? /* @__PURE__ */ jsx6("div", { className: "text-center py-16", children: /* @__PURE__ */ jsx6("p", { className: "text-xl text-ods-text-secondary", children: resolvedEmptyText }) }) : renderedContent }) }),
1525
+ (isLoadingContent || isLoadingStructure) && /* @__PURE__ */ jsx6("div", { className: "hidden lg:block", children: /* @__PURE__ */ jsxs4("div", { className: "sticky top-24", children: [
1526
+ /* @__PURE__ */ jsx6("div", { className: "h-[14px] w-28 bg-ods-border rounded animate-pulse mb-5" }),
1527
+ /* @__PURE__ */ jsx6("div", { className: "space-y-0", children: [130, 170, 190, 220, 110, 200, 80, 100, 120, 140, 90].map((w, i) => /* @__PURE__ */ jsx6(
1528
+ "div",
1529
+ {
1530
+ className: `py-[13px] pl-3 border-l-2 ${i === 0 ? "border-ods-accent" : "border-transparent"}`,
1531
+ children: /* @__PURE__ */ jsx6(
1532
+ "div",
1533
+ {
1534
+ className: "h-[13px] bg-ods-border rounded animate-pulse",
1535
+ style: { width: w }
1536
+ }
1537
+ )
1538
+ },
1539
+ i
1540
+ )) })
1541
+ ] }) }),
1542
+ showStickyNav && content && stickyNavSections.length > 0 && !isLoadingContent && /* @__PURE__ */ jsx6("div", { className: "hidden lg:block", children: /* @__PURE__ */ jsxs4("div", { className: "sticky top-24", children: [
1543
+ /* @__PURE__ */ jsx6("h3", { className: "text-[14px] font-['Azeret_Mono'] font-semibold uppercase text-ods-text-secondary tracking-[-0.02em] leading-[1.43em] mb-4", children: "ON THIS PAGE" }),
1544
+ /* @__PURE__ */ jsx6(
1545
+ StickySectionNav,
1546
+ {
1547
+ sections: stickyNavSections,
1548
+ activeSection,
1549
+ onSectionClick: handleSectionClick,
1550
+ ribbonPosition: "left",
1551
+ ribbonColor: "var(--ods-accent)"
1552
+ }
1553
+ )
1554
+ ] }) })
1555
+ ]
1556
+ }
1557
+ ) })
1558
+ ] })
1559
+ ] })
1560
+ }
1561
+ ) });
1562
+ }
1563
+
1564
+ export {
1565
+ PersistentFilterControls,
1566
+ PersistentSearchContainer,
1567
+ PersistentSidebar,
1568
+ PersistentMobileDropdown,
1569
+ UnifiedSkeleton,
1570
+ TextSkeleton,
1571
+ InteractiveSkeleton,
1572
+ MediaSkeleton,
1573
+ CardSkeleton,
1574
+ CardSkeletonGrid,
1575
+ AnnouncementBarSkeleton,
1576
+ HeroSkeleton,
1577
+ SearchContainerSkeleton,
1578
+ CategorySidebarSkeleton,
1579
+ BreadcrumbSkeleton,
1580
+ ResultsHeaderSkeleton,
1581
+ TwoColumnLayoutSkeleton,
1582
+ ArticleLayoutSkeleton,
1583
+ VendorDetailLayoutSkeleton,
1584
+ StatsSectionSkeleton,
1585
+ BlogCardGridSkeleton,
1586
+ VendorGridSkeleton,
1587
+ SlackCommunitySkeleton,
1588
+ DocNavigationProvider,
1589
+ useDocNavigation,
1590
+ useDocumentTree,
1591
+ useScrollSpy,
1592
+ DocViewer
1593
+ };
1594
+ //# sourceMappingURL=chunk-YVB3VDIQ.js.map