@salesmind-ai/design-system 0.3.3 → 0.3.4

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 (215) hide show
  1. package/dist/{SectionShell-BfBw5q0Y.d.cts → SectionShell-GlglHCzz.d.cts} +1 -0
  2. package/dist/{SectionShell-BfBw5q0Y.d.ts → SectionShell-GlglHCzz.d.ts} +1 -0
  3. package/dist/StatsSection-B8iD9L-o.d.ts +68 -0
  4. package/dist/StatsSection-wgd8Vge1.d.cts +68 -0
  5. package/dist/admin/index.cjs +2928 -68
  6. package/dist/admin/index.cjs.map +1 -1
  7. package/dist/admin/index.js +2915 -5
  8. package/dist/admin/index.js.map +1 -1
  9. package/dist/blog/index.cjs +1064 -53
  10. package/dist/blog/index.cjs.map +1 -1
  11. package/dist/blog/index.d.cts +1 -1
  12. package/dist/blog/index.d.ts +1 -1
  13. package/dist/blog/index.js +1054 -8
  14. package/dist/blog/index.js.map +1 -1
  15. package/dist/charts/index.cjs +2694 -46
  16. package/dist/charts/index.cjs.map +1 -1
  17. package/dist/charts/index.js +2680 -3
  18. package/dist/charts/index.js.map +1 -1
  19. package/dist/core/index.cjs +4333 -807
  20. package/dist/core/index.cjs.map +1 -1
  21. package/dist/core/index.js +4130 -14
  22. package/dist/core/index.js.map +1 -1
  23. package/dist/i18n/index.cjs +558 -86
  24. package/dist/i18n/index.cjs.map +1 -1
  25. package/dist/i18n/index.js +544 -1
  26. package/dist/i18n/index.js.map +1 -1
  27. package/dist/index.cjs +17140 -1432
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.css +24 -13
  30. package/dist/index.css.map +1 -1
  31. package/dist/index.d.cts +2 -2
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.js +16785 -31
  34. package/dist/index.js.map +1 -1
  35. package/dist/marketing/index.cjs +3072 -142
  36. package/dist/marketing/index.cjs.map +1 -1
  37. package/dist/marketing/index.d.cts +1 -1
  38. package/dist/marketing/index.d.ts +1 -1
  39. package/dist/marketing/index.js +3042 -11
  40. package/dist/marketing/index.js.map +1 -1
  41. package/dist/motion/index.cjs +1222 -26
  42. package/dist/motion/index.cjs.map +1 -1
  43. package/dist/motion/index.js +1215 -2
  44. package/dist/motion/index.js.map +1 -1
  45. package/dist/nav/index.cjs +1518 -101
  46. package/dist/nav/index.cjs.map +1 -1
  47. package/dist/nav/index.css +24 -13
  48. package/dist/nav/index.css.map +1 -1
  49. package/dist/nav/index.js +1498 -4
  50. package/dist/nav/index.js.map +1 -1
  51. package/dist/report/index.cjs +2403 -171
  52. package/dist/report/index.cjs.map +1 -1
  53. package/dist/report/index.js +2363 -3
  54. package/dist/report/index.js.map +1 -1
  55. package/dist/sections/index.cjs +382 -28
  56. package/dist/sections/index.cjs.map +1 -1
  57. package/dist/sections/index.d.cts +15 -69
  58. package/dist/sections/index.d.ts +15 -69
  59. package/dist/sections/index.js +376 -4
  60. package/dist/sections/index.js.map +1 -1
  61. package/dist/social-proof/index.cjs +1250 -53
  62. package/dist/social-proof/index.cjs.map +1 -1
  63. package/dist/social-proof/index.d.cts +1 -1
  64. package/dist/social-proof/index.d.ts +1 -1
  65. package/dist/social-proof/index.js +1235 -6
  66. package/dist/social-proof/index.js.map +1 -1
  67. package/dist/theme/index.cjs +565 -38
  68. package/dist/theme/index.cjs.map +1 -1
  69. package/dist/theme/index.js +555 -2
  70. package/dist/theme/index.js.map +1 -1
  71. package/dist/web/client/index.cjs +491 -38
  72. package/dist/web/client/index.cjs.map +1 -1
  73. package/dist/web/client/index.js +483 -4
  74. package/dist/web/client/index.js.map +1 -1
  75. package/dist/web/index.cjs +1346 -158
  76. package/dist/web/index.cjs.map +1 -1
  77. package/dist/web/index.js +1305 -9
  78. package/dist/web/index.js.map +1 -1
  79. package/dist/web/server/index.cjs +563 -26
  80. package/dist/web/server/index.cjs.map +1 -1
  81. package/dist/web/server/index.js +560 -1
  82. package/dist/web/server/index.js.map +1 -1
  83. package/package.json +1 -1
  84. package/dist/chunk-2GARWEJK.js +0 -17
  85. package/dist/chunk-2GARWEJK.js.map +0 -1
  86. package/dist/chunk-3NKRFUAR.js +0 -37
  87. package/dist/chunk-3NKRFUAR.js.map +0 -1
  88. package/dist/chunk-3TGSIILM.cjs +0 -201
  89. package/dist/chunk-3TGSIILM.cjs.map +0 -1
  90. package/dist/chunk-4GM5BGBN.cjs +0 -801
  91. package/dist/chunk-4GM5BGBN.cjs.map +0 -1
  92. package/dist/chunk-5LGDEZWY.cjs +0 -2434
  93. package/dist/chunk-5LGDEZWY.cjs.map +0 -1
  94. package/dist/chunk-6H4DSTXR.js +0 -786
  95. package/dist/chunk-6H4DSTXR.js.map +0 -1
  96. package/dist/chunk-6UNG76Y2.js +0 -153
  97. package/dist/chunk-6UNG76Y2.js.map +0 -1
  98. package/dist/chunk-7PX2AZ6Y.js +0 -39
  99. package/dist/chunk-7PX2AZ6Y.js.map +0 -1
  100. package/dist/chunk-B6AVAX4F.js +0 -1415
  101. package/dist/chunk-B6AVAX4F.js.map +0 -1
  102. package/dist/chunk-BILT5KD3.js +0 -264
  103. package/dist/chunk-BILT5KD3.js.map +0 -1
  104. package/dist/chunk-C2BCDNAV.js +0 -24
  105. package/dist/chunk-C2BCDNAV.js.map +0 -1
  106. package/dist/chunk-CH42VPWE.cjs +0 -421
  107. package/dist/chunk-CH42VPWE.cjs.map +0 -1
  108. package/dist/chunk-CJ2MKVAF.cjs +0 -46
  109. package/dist/chunk-CJ2MKVAF.cjs.map +0 -1
  110. package/dist/chunk-DP74LUXG.cjs +0 -98
  111. package/dist/chunk-DP74LUXG.cjs.map +0 -1
  112. package/dist/chunk-E7D6EKJ4.cjs +0 -44
  113. package/dist/chunk-E7D6EKJ4.cjs.map +0 -1
  114. package/dist/chunk-ECXBTUH6.cjs +0 -584
  115. package/dist/chunk-ECXBTUH6.cjs.map +0 -1
  116. package/dist/chunk-EFRAP5ES.js +0 -157
  117. package/dist/chunk-EFRAP5ES.js.map +0 -1
  118. package/dist/chunk-F6YYWMME.js +0 -485
  119. package/dist/chunk-F6YYWMME.js.map +0 -1
  120. package/dist/chunk-FAFAP4L5.js +0 -183
  121. package/dist/chunk-FAFAP4L5.js.map +0 -1
  122. package/dist/chunk-GUZIMHWS.js +0 -1608
  123. package/dist/chunk-GUZIMHWS.js.map +0 -1
  124. package/dist/chunk-H2Y6BSTL.cjs +0 -69
  125. package/dist/chunk-H2Y6BSTL.cjs.map +0 -1
  126. package/dist/chunk-HN4PHABT.js +0 -126
  127. package/dist/chunk-HN4PHABT.js.map +0 -1
  128. package/dist/chunk-HRENHNDJ.js +0 -211
  129. package/dist/chunk-HRENHNDJ.js.map +0 -1
  130. package/dist/chunk-I75BFEYT.cjs +0 -2561
  131. package/dist/chunk-I75BFEYT.cjs.map +0 -1
  132. package/dist/chunk-IFRATNLU.js +0 -562
  133. package/dist/chunk-IFRATNLU.js.map +0 -1
  134. package/dist/chunk-IYPXJ6YC.cjs +0 -69
  135. package/dist/chunk-IYPXJ6YC.cjs.map +0 -1
  136. package/dist/chunk-JPJN4YBC.js +0 -409
  137. package/dist/chunk-JPJN4YBC.js.map +0 -1
  138. package/dist/chunk-KBA2LFBG.js +0 -62
  139. package/dist/chunk-KBA2LFBG.js.map +0 -1
  140. package/dist/chunk-KCKUSU2M.cjs +0 -166
  141. package/dist/chunk-KCKUSU2M.cjs.map +0 -1
  142. package/dist/chunk-KJ2OXQF4.js +0 -287
  143. package/dist/chunk-KJ2OXQF4.js.map +0 -1
  144. package/dist/chunk-KNQEIU7O.cjs +0 -1202
  145. package/dist/chunk-KNQEIU7O.cjs.map +0 -1
  146. package/dist/chunk-KVGSVGRK.cjs +0 -569
  147. package/dist/chunk-KVGSVGRK.cjs.map +0 -1
  148. package/dist/chunk-L352JRV6.cjs +0 -105
  149. package/dist/chunk-L352JRV6.cjs.map +0 -1
  150. package/dist/chunk-LJADZITX.cjs +0 -298
  151. package/dist/chunk-LJADZITX.cjs.map +0 -1
  152. package/dist/chunk-LMJPWXTZ.cjs +0 -194
  153. package/dist/chunk-LMJPWXTZ.cjs.map +0 -1
  154. package/dist/chunk-LOWEAQST.js +0 -701
  155. package/dist/chunk-LOWEAQST.js.map +0 -1
  156. package/dist/chunk-MDB2WCRQ.cjs +0 -137
  157. package/dist/chunk-MDB2WCRQ.cjs.map +0 -1
  158. package/dist/chunk-MQDEE7HC.cjs +0 -283
  159. package/dist/chunk-MQDEE7HC.cjs.map +0 -1
  160. package/dist/chunk-MQRB634A.cjs +0 -34
  161. package/dist/chunk-MQRB634A.cjs.map +0 -1
  162. package/dist/chunk-MTI27RDV.js +0 -185
  163. package/dist/chunk-MTI27RDV.js.map +0 -1
  164. package/dist/chunk-MU6GW5ZV.js +0 -2317
  165. package/dist/chunk-MU6GW5ZV.js.map +0 -1
  166. package/dist/chunk-NN3TUHIH.js +0 -28
  167. package/dist/chunk-NN3TUHIH.js.map +0 -1
  168. package/dist/chunk-NT4LBP7D.cjs +0 -111
  169. package/dist/chunk-NT4LBP7D.cjs.map +0 -1
  170. package/dist/chunk-OLV7OD3X.cjs +0 -502
  171. package/dist/chunk-OLV7OD3X.cjs.map +0 -1
  172. package/dist/chunk-OXNXEQY7.js +0 -2538
  173. package/dist/chunk-OXNXEQY7.js.map +0 -1
  174. package/dist/chunk-P5BOFE5A.js +0 -546
  175. package/dist/chunk-P5BOFE5A.js.map +0 -1
  176. package/dist/chunk-Q2MFGYTE.cjs +0 -1449
  177. package/dist/chunk-Q2MFGYTE.cjs.map +0 -1
  178. package/dist/chunk-Q75DBVDY.cjs +0 -68
  179. package/dist/chunk-Q75DBVDY.cjs.map +0 -1
  180. package/dist/chunk-REQ5Q6ZI.js +0 -1022
  181. package/dist/chunk-REQ5Q6ZI.js.map +0 -1
  182. package/dist/chunk-SICKWUWB.js +0 -62
  183. package/dist/chunk-SICKWUWB.js.map +0 -1
  184. package/dist/chunk-T343CCH5.js +0 -1190
  185. package/dist/chunk-T343CCH5.js.map +0 -1
  186. package/dist/chunk-TEC62D4A.cjs +0 -1624
  187. package/dist/chunk-TEC62D4A.cjs.map +0 -1
  188. package/dist/chunk-TW5JB35D.js +0 -2122
  189. package/dist/chunk-TW5JB35D.js.map +0 -1
  190. package/dist/chunk-VC5LMUVQ.cjs +0 -20
  191. package/dist/chunk-VC5LMUVQ.cjs.map +0 -1
  192. package/dist/chunk-VM7WFMKI.cjs +0 -76
  193. package/dist/chunk-VM7WFMKI.cjs.map +0 -1
  194. package/dist/chunk-W2WTP6HS.cjs +0 -233
  195. package/dist/chunk-W2WTP6HS.cjs.map +0 -1
  196. package/dist/chunk-WH7PYHZY.cjs +0 -35
  197. package/dist/chunk-WH7PYHZY.cjs.map +0 -1
  198. package/dist/chunk-XQZVY7JJ.cjs +0 -717
  199. package/dist/chunk-XQZVY7JJ.cjs.map +0 -1
  200. package/dist/chunk-XU3OMQ7V.js +0 -98
  201. package/dist/chunk-XU3OMQ7V.js.map +0 -1
  202. package/dist/chunk-XWPDRMZG.js +0 -62
  203. package/dist/chunk-XWPDRMZG.js.map +0 -1
  204. package/dist/chunk-Y3CPKNB7.js +0 -67
  205. package/dist/chunk-Y3CPKNB7.js.map +0 -1
  206. package/dist/chunk-YNVRDD2P.js +0 -98
  207. package/dist/chunk-YNVRDD2P.js.map +0 -1
  208. package/dist/chunk-YSYR54XR.js +0 -92
  209. package/dist/chunk-YSYR54XR.js.map +0 -1
  210. package/dist/chunk-YTYDQBVY.cjs +0 -162
  211. package/dist/chunk-YTYDQBVY.cjs.map +0 -1
  212. package/dist/chunk-ZDLOA2UT.cjs +0 -1042
  213. package/dist/chunk-ZDLOA2UT.cjs.map +0 -1
  214. package/dist/chunk-ZWUKRCOJ.cjs +0 -2162
  215. package/dist/chunk-ZWUKRCOJ.cjs.map +0 -1
@@ -1,485 +0,0 @@
1
- import { useMessage } from './chunk-P5BOFE5A.js';
2
- import { useAnalytics } from './chunk-2GARWEJK.js';
3
- import { Avatar, AvatarImage, AvatarFallback } from './chunk-Y3CPKNB7.js';
4
- import { SectionShell, SectionHeader } from './chunk-KBA2LFBG.js';
5
- import { OutboundLink } from './chunk-KJ2OXQF4.js';
6
- import React9, { forwardRef, useState, useEffect, useRef } from 'react';
7
- import clsx9 from 'clsx';
8
- import { FileText, Clock, ArrowRight } from 'lucide-react';
9
- import { jsxs, jsx } from 'react/jsx-runtime';
10
-
11
- var ArticleCard = forwardRef(
12
- ({
13
- href,
14
- title,
15
- excerpt,
16
- imageUrl,
17
- imageAlt = "",
18
- category,
19
- date,
20
- readingTime,
21
- author,
22
- variant = "vertical",
23
- className,
24
- onClick,
25
- ...props
26
- }, ref) => {
27
- const { track } = useAnalytics();
28
- const handleClick = (e) => {
29
- track("article_click", { url: href, title, category });
30
- if (onClick) onClick(e);
31
- };
32
- return /* @__PURE__ */ jsxs(
33
- OutboundLink,
34
- {
35
- ref,
36
- href,
37
- context: "article-card",
38
- className: clsx9(
39
- "ds-article-card",
40
- `ds-article-card--${variant}`,
41
- !imageUrl && "ds-article-card--no-image",
42
- className
43
- ),
44
- onClick: handleClick,
45
- ...props,
46
- children: [
47
- imageUrl ? /* @__PURE__ */ jsxs("div", { className: "ds-article-card__image-wrapper", children: [
48
- /* @__PURE__ */ jsx(
49
- "img",
50
- {
51
- src: imageUrl,
52
- alt: imageAlt,
53
- className: "ds-article-card__image",
54
- loading: "lazy"
55
- }
56
- ),
57
- category && /* @__PURE__ */ jsx("span", { className: "ds-article-card__category-badge", children: category })
58
- ] }) : /* @__PURE__ */ jsxs("div", { className: "ds-article-card__placeholder", children: [
59
- /* @__PURE__ */ jsx(FileText, { className: "ds-article-card__placeholder-icon", "aria-hidden": "true" }),
60
- category && /* @__PURE__ */ jsx("span", { className: "ds-article-card__category-badge", children: category })
61
- ] }),
62
- /* @__PURE__ */ jsxs("div", { className: "ds-article-card__content", children: [
63
- /* @__PURE__ */ jsx("h3", { className: "ds-article-card__title", children: title }),
64
- /* @__PURE__ */ jsx("p", { className: "ds-article-card__excerpt", children: excerpt }),
65
- /* @__PURE__ */ jsxs("div", { className: "ds-article-card__meta", children: [
66
- (date || author) && /* @__PURE__ */ jsxs("div", { className: "ds-article-card__meta-primary", children: [
67
- author && /* @__PURE__ */ jsx("span", { className: "ds-article-card__author", children: author }),
68
- author && date && /* @__PURE__ */ jsx("span", { className: "ds-article-card__dot", "aria-hidden": "true", children: "\u2022" }),
69
- date && /* @__PURE__ */ jsx("time", { dateTime: date, className: "ds-article-card__date", children: date })
70
- ] }),
71
- readingTime && /* @__PURE__ */ jsxs("div", { className: "ds-article-card__meta-secondary", children: [
72
- /* @__PURE__ */ jsx(Clock, { size: 14, "aria-hidden": "true" }),
73
- /* @__PURE__ */ jsxs("span", { children: [
74
- readingTime,
75
- " min read"
76
- ] })
77
- ] })
78
- ] }),
79
- /* @__PURE__ */ jsx("div", { className: "ds-article-card__footer", children: /* @__PURE__ */ jsxs("span", { className: "ds-article-card__read-more", children: [
80
- "Read article",
81
- /* @__PURE__ */ jsx(ArrowRight, { size: 16, className: "ds-article-card__arrow" })
82
- ] }) })
83
- ] })
84
- ]
85
- }
86
- );
87
- }
88
- );
89
- ArticleCard.displayName = "ArticleCard";
90
- var ArticleLayout = forwardRef(
91
- ({
92
- children,
93
- title,
94
- author,
95
- date,
96
- heroImage,
97
- sidebar,
98
- className,
99
- ...props
100
- }, ref) => {
101
- const { track } = useAnalytics();
102
- React9.useEffect(() => {
103
- let maxScroll = 0;
104
- const handleScroll = () => {
105
- const docHeight = document.documentElement.scrollHeight - window.innerHeight;
106
- if (docHeight > 0) {
107
- const scrollPercent = Math.round(window.scrollY / docHeight * 100);
108
- if (scrollPercent > maxScroll) {
109
- maxScroll = scrollPercent;
110
- if (maxScroll === 25) track("article_scroll", { milestone: 25 });
111
- if (maxScroll === 50) track("article_scroll", { milestone: 50 });
112
- if (maxScroll === 75) track("article_scroll", { milestone: 75 });
113
- if (maxScroll === 100) track("article_scroll", { milestone: 100 });
114
- }
115
- }
116
- };
117
- window.addEventListener("scroll", handleScroll, { passive: true });
118
- return () => window.removeEventListener("scroll", handleScroll);
119
- }, [track]);
120
- return /* @__PURE__ */ jsxs(
121
- "article",
122
- {
123
- ref,
124
- className: clsx9("ds-article-layout", className),
125
- ...props,
126
- children: [
127
- /* @__PURE__ */ jsxs("header", { className: "ds-article-layout__header", children: [
128
- /* @__PURE__ */ jsx("h1", { className: "ds-article-layout__title", children: title }),
129
- (author || date) && /* @__PURE__ */ jsxs("div", { className: "ds-article-layout__meta", children: [
130
- author && /* @__PURE__ */ jsx("div", { className: "ds-article-layout__author", children: author }),
131
- author && date && /* @__PURE__ */ jsx("span", { className: "ds-article-layout__dot", "aria-hidden": "true", children: "\u2022" }),
132
- date && /* @__PURE__ */ jsx("time", { className: "ds-article-layout__date", children: date })
133
- ] })
134
- ] }),
135
- heroImage && /* @__PURE__ */ jsx("div", { className: "ds-article-layout__hero", children: /* @__PURE__ */ jsx("img", { src: heroImage, alt: "", "aria-hidden": "true" }) }),
136
- /* @__PURE__ */ jsxs("div", { className: clsx9(
137
- "ds-article-layout__body",
138
- sidebar && "ds-article-layout__body--with-sidebar"
139
- ), children: [
140
- /* @__PURE__ */ jsx("div", { className: "ds-article-layout__content ds-prose", children }),
141
- sidebar && /* @__PURE__ */ jsx("aside", { className: "ds-article-layout__sidebar", children: /* @__PURE__ */ jsx("div", { className: "ds-article-layout__sidebar-inner", children: sidebar }) })
142
- ] })
143
- ]
144
- }
145
- );
146
- }
147
- );
148
- ArticleLayout.displayName = "ArticleLayout";
149
- var AuthorBio = forwardRef(
150
- ({
151
- name,
152
- role,
153
- avatar,
154
- bio,
155
- links,
156
- variant = "card",
157
- className,
158
- ...props
159
- }, ref) => {
160
- const initials = name.split(" ").map((n) => n[0]).join("").slice(0, 2);
161
- return /* @__PURE__ */ jsxs(
162
- "div",
163
- {
164
- ref,
165
- className: clsx9("ds-author-bio", `ds-author-bio--${variant}`, className),
166
- ...props,
167
- children: [
168
- /* @__PURE__ */ jsxs(Avatar, { size: variant === "compact" ? "sm" : variant === "longform" ? "lg" : "md", className: "ds-author-bio__avatar", children: [
169
- avatar && /* @__PURE__ */ jsx(AvatarImage, { src: avatar, alt: name }),
170
- /* @__PURE__ */ jsx(AvatarFallback, { children: initials })
171
- ] }),
172
- /* @__PURE__ */ jsxs("div", { className: "ds-author-bio__info", children: [
173
- /* @__PURE__ */ jsx("span", { className: "ds-author-bio__name", children: name }),
174
- role && /* @__PURE__ */ jsx("span", { className: "ds-author-bio__role", children: role }),
175
- bio && variant !== "compact" && /* @__PURE__ */ jsx("p", { className: "ds-author-bio__bio", children: bio }),
176
- links && links.length > 0 && variant !== "compact" && /* @__PURE__ */ jsx("div", { className: "ds-author-bio__links", children: links.map((link, i) => /* @__PURE__ */ jsxs(
177
- OutboundLink,
178
- {
179
- href: link.href,
180
- context: "author-bio-link",
181
- className: "ds-author-bio__link",
182
- children: [
183
- link.icon && /* @__PURE__ */ jsx("span", { className: "ds-author-bio__link-icon", children: link.icon }),
184
- link.label
185
- ]
186
- },
187
- i
188
- )) })
189
- ] })
190
- ]
191
- }
192
- );
193
- }
194
- );
195
- AuthorBio.displayName = "AuthorBio";
196
- var TableOfContents = forwardRef(
197
- ({
198
- items,
199
- activeId: controlledActiveId,
200
- position = "sidebar",
201
- label,
202
- onItemClick,
203
- className,
204
- ...props
205
- }, ref) => {
206
- const t = useMessage();
207
- const defaultLabel = t({ id: "ds.toc.label", defaultMessage: "On this page" });
208
- const finalLabel = label || defaultLabel;
209
- const [observedActiveId, setObservedActiveId] = useState("");
210
- const activeId = controlledActiveId ?? observedActiveId;
211
- useEffect(() => {
212
- if (controlledActiveId !== void 0) return;
213
- if (items.length === 0) return;
214
- const handleScroll = () => {
215
- const headingElements = items.map((item) => ({
216
- id: item.id,
217
- el: document.getElementById(item.id)
218
- })).filter((h) => !!h.el);
219
- if (headingElements.length === 0) return;
220
- const topOffset = 120;
221
- const firstBelowIndex = headingElements.findIndex((h) => {
222
- const rect = h.el.getBoundingClientRect();
223
- return rect.top > topOffset;
224
- });
225
- let newActiveId = "";
226
- if (firstBelowIndex === -1) {
227
- newActiveId = headingElements[headingElements.length - 1].id;
228
- } else if (firstBelowIndex === 0) {
229
- newActiveId = "";
230
- } else {
231
- newActiveId = headingElements[firstBelowIndex - 1].id;
232
- }
233
- setObservedActiveId(newActiveId);
234
- };
235
- window.addEventListener("scroll", handleScroll, { passive: true });
236
- handleScroll();
237
- return () => window.removeEventListener("scroll", handleScroll);
238
- }, [items, controlledActiveId]);
239
- const handleClick = (id) => {
240
- const el = document.getElementById(id);
241
- if (el) {
242
- el.scrollIntoView({ behavior: "smooth", block: "start" });
243
- }
244
- if (onItemClick) onItemClick(id);
245
- };
246
- if (items.length === 0) return null;
247
- return /* @__PURE__ */ jsxs(
248
- "nav",
249
- {
250
- ref,
251
- className: clsx9("ds-toc", `ds-toc--${position}`, className),
252
- "aria-label": finalLabel,
253
- ...props,
254
- children: [
255
- /* @__PURE__ */ jsx("span", { className: "ds-toc__label", children: finalLabel }),
256
- /* @__PURE__ */ jsx("ul", { className: "ds-toc__list", children: items.map((item) => /* @__PURE__ */ jsx("li", { className: "ds-toc__item", style: { paddingLeft: `${(item.level - 2) * 12}px` }, children: /* @__PURE__ */ jsx(
257
- "button",
258
- {
259
- type: "button",
260
- className: clsx9(
261
- "ds-toc__link",
262
- activeId === item.id && "ds-toc__link--active"
263
- ),
264
- onClick: () => handleClick(item.id),
265
- children: item.title
266
- }
267
- ) }, item.id)) })
268
- ]
269
- }
270
- );
271
- }
272
- );
273
- TableOfContents.displayName = "TableOfContents";
274
- var RelatedContent = forwardRef(
275
- ({
276
- eyebrow,
277
- title = "Related Articles",
278
- items,
279
- maxVisible,
280
- className,
281
- ...props
282
- }, ref) => {
283
- const visibleItems = maxVisible ? items.slice(0, maxVisible) : items;
284
- if (visibleItems.length === 0) return null;
285
- return /* @__PURE__ */ jsxs(
286
- SectionShell,
287
- {
288
- ref,
289
- className: clsx9("ds-related-content", className),
290
- background: "muted",
291
- ...props,
292
- children: [
293
- /* @__PURE__ */ jsx(SectionHeader, { eyebrow, title }),
294
- /* @__PURE__ */ jsx("div", { className: "ds-related-content__grid", children: visibleItems.map((item, i) => /* @__PURE__ */ jsx(ArticleCard, { ...item }, i)) })
295
- ]
296
- }
297
- );
298
- }
299
- );
300
- RelatedContent.displayName = "RelatedContent";
301
- var LongFormLayout = React9.forwardRef(
302
- ({ children, sidebar, className, ...props }, ref) => {
303
- return /* @__PURE__ */ jsxs("div", { ref, className: clsx9("ds-longform-layout", className), ...props, children: [
304
- /* @__PURE__ */ jsx("article", { className: "ds-longform-layout__main", children }),
305
- sidebar && /* @__PURE__ */ jsx("aside", { className: "ds-longform-layout__sidebar", children: sidebar })
306
- ] });
307
- }
308
- );
309
- LongFormLayout.displayName = "LongFormLayout";
310
- var InsightCallout = React9.forwardRef(
311
- ({ children, icon, title, className, ...props }, ref) => {
312
- return /* @__PURE__ */ jsxs("aside", { ref, className: clsx9("ds-insight-callout", className), ...props, children: [
313
- icon && /* @__PURE__ */ jsx("div", { className: "ds-insight-callout__icon", children: icon }),
314
- /* @__PURE__ */ jsxs("div", { className: "ds-insight-callout__content", children: [
315
- title && /* @__PURE__ */ jsx("h5", { className: "ds-insight-callout__title", children: title }),
316
- children
317
- ] })
318
- ] });
319
- }
320
- );
321
- InsightCallout.displayName = "InsightCallout";
322
- var DataHighlight = React9.forwardRef(
323
- ({ stat, label, children, className, ...props }, ref) => {
324
- return /* @__PURE__ */ jsxs("figure", { ref, className: clsx9("ds-data-highlight", className), ...props, children: [
325
- /* @__PURE__ */ jsxs("div", { className: "ds-data-highlight__stat-group", children: [
326
- /* @__PURE__ */ jsx("span", { className: "ds-data-highlight__stat", children: stat }),
327
- /* @__PURE__ */ jsx("span", { className: "ds-data-highlight__label", children: label })
328
- ] }),
329
- children && /* @__PURE__ */ jsx("figcaption", { className: "ds-data-highlight__caption", children })
330
- ] });
331
- }
332
- );
333
- DataHighlight.displayName = "DataHighlight";
334
- var ReadingProgress = React9.forwardRef(
335
- ({ targetRef, className, ...props }, ref) => {
336
- const [progress, setProgress] = useState(0);
337
- const frameRef = useRef(null);
338
- useEffect(() => {
339
- const handleScroll = () => {
340
- if (frameRef.current) cancelAnimationFrame(frameRef.current);
341
- frameRef.current = requestAnimationFrame(() => {
342
- let percentage = 0;
343
- if (targetRef && targetRef.current) {
344
- const el = targetRef.current;
345
- const rect = el.getBoundingClientRect();
346
- const viewportHeight = window.innerHeight;
347
- if (rect.top > viewportHeight) {
348
- percentage = 0;
349
- } else if (rect.bottom < 0) {
350
- percentage = 100;
351
- } else {
352
- const scrollableDistance = rect.height - viewportHeight;
353
- if (scrollableDistance <= 0) {
354
- percentage = 100;
355
- } else {
356
- const scrolled = viewportHeight - rect.top;
357
- percentage = Math.max(0, Math.min(100, scrolled / scrollableDistance * 100));
358
- }
359
- }
360
- } else {
361
- const scrollPosition = window.scrollY;
362
- const scrollHeight = document.body.scrollHeight - window.innerHeight;
363
- percentage = scrollHeight > 0 ? scrollPosition / scrollHeight * 100 : 0;
364
- percentage = Math.max(0, Math.min(100, percentage));
365
- }
366
- setProgress(percentage);
367
- });
368
- };
369
- window.addEventListener("scroll", handleScroll, { passive: true });
370
- window.addEventListener("resize", handleScroll, { passive: true });
371
- handleScroll();
372
- return () => {
373
- if (frameRef.current) cancelAnimationFrame(frameRef.current);
374
- window.removeEventListener("scroll", handleScroll);
375
- window.removeEventListener("resize", handleScroll);
376
- };
377
- }, [targetRef]);
378
- return /* @__PURE__ */ jsx(
379
- "div",
380
- {
381
- ref,
382
- className: clsx9("ds-reading-progress", className),
383
- ...props,
384
- children: /* @__PURE__ */ jsx(
385
- "div",
386
- {
387
- className: "ds-reading-progress__bar",
388
- style: { transform: `scaleX(${progress / 100})` }
389
- }
390
- )
391
- }
392
- );
393
- }
394
- );
395
- ReadingProgress.displayName = "ReadingProgress";
396
- var VersionedUpgradeAlert = React9.forwardRef(
397
- ({ seriesName, viewedYear, latestYear, latestUrl, deltaSummary, className, ...props }, ref) => {
398
- const [dismissed, setDismissed] = useState(false);
399
- if (dismissed) return null;
400
- return /* @__PURE__ */ jsxs(
401
- "div",
402
- {
403
- ref,
404
- className: clsx9("ds-versioned-alert", className),
405
- role: "alert",
406
- ...props,
407
- children: [
408
- /* @__PURE__ */ jsxs("div", { className: "ds-versioned-alert__content", children: [
409
- /* @__PURE__ */ jsx("span", { className: "ds-versioned-alert__icon", children: "\u26A0\uFE0F" }),
410
- /* @__PURE__ */ jsxs("div", { className: "ds-versioned-alert__text", children: [
411
- /* @__PURE__ */ jsx("strong", { children: "Outdated Edition:" }),
412
- " You are viewing the ",
413
- viewedYear,
414
- " edition of ",
415
- seriesName,
416
- ". The ",
417
- /* @__PURE__ */ jsxs("strong", { children: [
418
- latestYear,
419
- " edition"
420
- ] }),
421
- " is now available.",
422
- deltaSummary && /* @__PURE__ */ jsxs("span", { className: "ds-versioned-alert__delta", children: [
423
- " ",
424
- deltaSummary
425
- ] })
426
- ] })
427
- ] }),
428
- /* @__PURE__ */ jsxs("div", { className: "ds-versioned-alert__actions", children: [
429
- /* @__PURE__ */ jsxs(OutboundLink, { href: latestUrl, context: "versioned-alert-view-latest", className: "ds-versioned-alert__button ds-button ds-button--primary ds-button--sm", openInNewTab: false, children: [
430
- "View ",
431
- latestYear,
432
- " Edition"
433
- ] }),
434
- /* @__PURE__ */ jsx(
435
- "button",
436
- {
437
- className: "ds-versioned-alert__close",
438
- onClick: () => setDismissed(true),
439
- "aria-label": "Dismiss alert",
440
- children: "\xD7"
441
- }
442
- )
443
- ] })
444
- ]
445
- }
446
- );
447
- }
448
- );
449
- VersionedUpgradeAlert.displayName = "VersionedUpgradeAlert";
450
- var VersionedSeriesNavigator = React9.forwardRef(
451
- ({ seriesName, hubUrl, editions, className, ...props }, ref) => {
452
- const sortedEditions = [...editions].sort((a, b) => a.year - b.year);
453
- return /* @__PURE__ */ jsxs("div", { ref, className: clsx9("ds-versioned-navigator", className), ...props, children: [
454
- /* @__PURE__ */ jsxs("div", { className: "ds-versioned-navigator__header", children: [
455
- /* @__PURE__ */ jsx("span", { className: "ds-versioned-navigator__label", children: "Series" }),
456
- /* @__PURE__ */ jsxs(OutboundLink, { href: hubUrl, context: "versioned-navigator-hub", className: "ds-versioned-navigator__title", openInNewTab: false, children: [
457
- seriesName,
458
- " Hub"
459
- ] })
460
- ] }),
461
- /* @__PURE__ */ jsx("div", { className: "ds-versioned-navigator__timeline", children: sortedEditions.map((edition, idx) => /* @__PURE__ */ jsxs(React9.Fragment, { children: [
462
- idx > 0 && /* @__PURE__ */ jsx("div", { className: "ds-versioned-navigator__connector" }),
463
- /* @__PURE__ */ jsx(
464
- OutboundLink,
465
- {
466
- href: edition.url,
467
- context: "versioned-navigator-edition",
468
- className: clsx9(
469
- "ds-versioned-navigator__node",
470
- edition.isCurrent && "ds-versioned-navigator__node--active"
471
- ),
472
- "aria-current": edition.isCurrent ? "page" : void 0,
473
- openInNewTab: false,
474
- children: edition.year
475
- }
476
- )
477
- ] }, edition.year)) })
478
- ] });
479
- }
480
- );
481
- VersionedSeriesNavigator.displayName = "VersionedSeriesNavigator";
482
-
483
- export { ArticleCard, ArticleLayout, AuthorBio, DataHighlight, InsightCallout, LongFormLayout, ReadingProgress, RelatedContent, TableOfContents, VersionedSeriesNavigator, VersionedUpgradeAlert };
484
- //# sourceMappingURL=out.js.map
485
- //# sourceMappingURL=chunk-F6YYWMME.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/ArticleCard/ArticleCard.tsx","../src/components/ArticleLayout/ArticleLayout.tsx","../src/components/AuthorBio/AuthorBio.tsx","../src/components/TableOfContents/TableOfContents.tsx","../src/components/RelatedContent/RelatedContent.tsx","../src/components/LongFormLayout/LongFormLayout.tsx","../src/components/LongFormComponents/LongFormComponents.tsx","../src/components/ReadingProgress/ReadingProgress.tsx","../src/components/VersionedContent/VersionedContent.tsx"],"names":["React","forwardRef","clsx","jsx","jsxs","useEffect","useState"],"mappings":"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","sourcesContent":["import React, { forwardRef } from 'react';\nimport clsx from 'clsx';\nimport { useAnalytics } from '../../web/analytics/use-analytics';\nimport { ArrowRight, Clock, FileText } from 'lucide-react';\nimport { OutboundLink } from '../OutboundLink/OutboundLink';\nimport './ArticleCard.css';\n\nexport interface ArticleCardProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n /** Target URL */\n href: string;\n /** Article title */\n title: string;\n /** Short excerpt or description */\n excerpt: string;\n /** Image URL for the thumbnail */\n imageUrl?: string;\n /** Image alt text */\n imageAlt?: string;\n /** Category or tag label */\n category?: string;\n /** Publication date */\n date?: string;\n /** Reading time in minutes */\n readingTime?: number;\n /** Author name */\n author?: string;\n /** Variant for different grid layouts */\n variant?: 'vertical' | 'horizontal' | 'featured';\n}\n\n/**\n * Standardized card for blog posts, resources, and case studies.\n * Acts as a block-level link.\n */\nexport const ArticleCard = forwardRef<HTMLAnchorElement, ArticleCardProps>(\n (\n {\n href,\n title,\n excerpt,\n imageUrl,\n imageAlt = '',\n category,\n date,\n readingTime,\n author,\n variant = 'vertical',\n className,\n onClick,\n ...props\n },\n ref\n ) => {\n const { track } = useAnalytics();\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n track('article_click', { url: href, title, category });\n if (onClick) onClick(e);\n };\n\n return (\n <OutboundLink\n ref={ref}\n href={href}\n context=\"article-card\"\n className={clsx(\n 'ds-article-card',\n `ds-article-card--${variant}`,\n !imageUrl && 'ds-article-card--no-image',\n className\n )}\n onClick={handleClick}\n {...props}\n >\n {imageUrl ? (\n <div className=\"ds-article-card__image-wrapper\">\n <img \n src={imageUrl} \n alt={imageAlt} \n className=\"ds-article-card__image\" \n loading=\"lazy\" \n />\n {category && (\n <span className=\"ds-article-card__category-badge\">{category}</span>\n )}\n </div>\n ) : (\n <div className=\"ds-article-card__placeholder\">\n <FileText className=\"ds-article-card__placeholder-icon\" aria-hidden=\"true\" />\n {category && (\n <span className=\"ds-article-card__category-badge\">{category}</span>\n )}\n </div>\n )}\n \n <div className=\"ds-article-card__content\">\n \n <h3 className=\"ds-article-card__title\">{title}</h3>\n <p className=\"ds-article-card__excerpt\">{excerpt}</p>\n \n <div className=\"ds-article-card__meta\">\n {(date || author) && (\n <div className=\"ds-article-card__meta-primary\">\n {author && <span className=\"ds-article-card__author\">{author}</span>}\n {author && date && <span className=\"ds-article-card__dot\" aria-hidden=\"true\">•</span>}\n {date && <time dateTime={date} className=\"ds-article-card__date\">{date}</time>}\n </div>\n )}\n \n {readingTime && (\n <div className=\"ds-article-card__meta-secondary\">\n <Clock size={14} aria-hidden=\"true\" />\n <span>{readingTime} min read</span>\n </div>\n )}\n </div>\n \n <div className=\"ds-article-card__footer\">\n <span className=\"ds-article-card__read-more\">\n Read article\n <ArrowRight size={16} className=\"ds-article-card__arrow\" />\n </span>\n </div>\n </div>\n </OutboundLink>\n );\n }\n);\n\nArticleCard.displayName = 'ArticleCard';\n","import React, { forwardRef } from 'react';\nimport clsx from 'clsx';\nimport { useAnalytics } from '../../web/analytics/use-analytics';\nimport './ArticleLayout.css';\n\nexport interface ArticleLayoutProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The main content of the article */\n children: React.ReactNode;\n /** Article title */\n title: string;\n /** Author name */\n author?: React.ReactNode;\n /** Publish date */\n date?: React.ReactNode;\n /** Main hero image */\n heroImage?: string;\n /** Sidebar content (like TOC or related articles) */\n sidebar?: React.ReactNode;\n}\n\n/**\n * Standardized layout for long-form content (blog posts, resources, case studies).\n * Handles responsive wrapping, prose width constraints, and sidebar positioning.\n */\nexport const ArticleLayout = forwardRef<HTMLDivElement, ArticleLayoutProps>(\n (\n {\n children,\n title,\n author,\n date,\n heroImage,\n sidebar,\n className,\n ...props\n },\n ref\n ) => {\n // Add scroll tracking\n const { track } = useAnalytics();\n \n React.useEffect(() => {\n let maxScroll = 0;\n \n const handleScroll = () => {\n const docHeight = document.documentElement.scrollHeight - window.innerHeight;\n if (docHeight > 0) {\n const scrollPercent = Math.round((window.scrollY / docHeight) * 100);\n \n if (scrollPercent > maxScroll) {\n maxScroll = scrollPercent;\n \n // Track milestones\n if (maxScroll === 25) track('article_scroll', { milestone: 25 });\n if (maxScroll === 50) track('article_scroll', { milestone: 50 });\n if (maxScroll === 75) track('article_scroll', { milestone: 75 });\n if (maxScroll === 100) track('article_scroll', { milestone: 100 });\n }\n }\n };\n\n window.addEventListener('scroll', handleScroll, { passive: true });\n return () => window.removeEventListener('scroll', handleScroll);\n }, [track]);\n\n return (\n <article\n ref={ref}\n className={clsx('ds-article-layout', className)}\n {...props}\n >\n <header className=\"ds-article-layout__header\">\n <h1 className=\"ds-article-layout__title\">{title}</h1>\n \n {(author || date) && (\n <div className=\"ds-article-layout__meta\">\n {author && <div className=\"ds-article-layout__author\">{author}</div>}\n {author && date && <span className=\"ds-article-layout__dot\" aria-hidden=\"true\">•</span>}\n {date && <time className=\"ds-article-layout__date\">{date}</time>}\n </div>\n )}\n </header>\n\n {heroImage && (\n <div className=\"ds-article-layout__hero\">\n <img src={heroImage} alt=\"\" aria-hidden=\"true\" />\n </div>\n )}\n\n <div className={clsx(\n 'ds-article-layout__body',\n sidebar && 'ds-article-layout__body--with-sidebar'\n )}>\n <div className=\"ds-article-layout__content ds-prose\">\n {children}\n </div>\n \n {sidebar && (\n <aside className=\"ds-article-layout__sidebar\">\n <div className=\"ds-article-layout__sidebar-inner\">\n {sidebar}\n </div>\n </aside>\n )}\n </div>\n </article>\n );\n }\n);\n\nArticleLayout.displayName = 'ArticleLayout';\n","import React, { forwardRef } from 'react';\nimport clsx from 'clsx';\nimport { Avatar, AvatarImage, AvatarFallback } from '../Avatar/Avatar';\nimport { OutboundLink } from '../OutboundLink/OutboundLink';\nimport './AuthorBio.css';\n\n/* ============================================================================\n AUTHOR BIO\n ============================================================================\n Author biography card for blog posts and articles.\n\n Strategic objective: Authority (expert credibility signal)\n ============================================================================ */\n\n/** Social/external link */\nexport interface AuthorLink {\n /** Link label (e.g., \"Twitter\", \"LinkedIn\") */\n label: string;\n /** Link URL */\n href: string;\n /** Optional icon */\n icon?: React.ReactNode;\n}\n\nexport interface AuthorBioProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Author name */\n name: string;\n /** Author role or title */\n role?: string;\n /** Avatar image URL */\n avatar?: string;\n /** Biography text */\n bio?: string;\n /** External links */\n links?: AuthorLink[];\n /** Layout variant */\n variant?: 'inline' | 'card' | 'compact' | 'longform';\n}\n\n/**\n * Author biography card.\n *\n * @example\n * ```tsx\n * <AuthorBio\n * name=\"Alex Chen\"\n * role=\"Head of Growth at SalesMind AI\"\n * avatar=\"/team/alex.jpg\"\n * bio=\"Alex has 10+ years of experience in B2B growth...\"\n * links={[{ label: 'LinkedIn', href: 'https://linkedin.com/in/alexchen' }]}\n * variant=\"card\"\n * />\n * ```\n */\nexport const AuthorBio = forwardRef<HTMLDivElement, AuthorBioProps>(\n (\n {\n name,\n role,\n avatar,\n bio,\n links,\n variant = 'card',\n className,\n ...props\n },\n ref,\n ) => {\n const initials = name\n .split(' ')\n .map((n) => n[0])\n .join('')\n .slice(0, 2);\n\n return (\n <div\n ref={ref}\n className={clsx('ds-author-bio', `ds-author-bio--${variant}`, className)}\n {...props}\n >\n <Avatar size={variant === 'compact' ? 'sm' : variant === 'longform' ? 'lg' : 'md'} className=\"ds-author-bio__avatar\">\n {avatar && <AvatarImage src={avatar} alt={name} />}\n <AvatarFallback>{initials}</AvatarFallback>\n </Avatar>\n\n <div className=\"ds-author-bio__info\">\n <span className=\"ds-author-bio__name\">{name}</span>\n {role && <span className=\"ds-author-bio__role\">{role}</span>}\n {bio && variant !== 'compact' && (\n <p className=\"ds-author-bio__bio\">{bio}</p>\n )}\n {links && links.length > 0 && variant !== 'compact' && (\n <div className=\"ds-author-bio__links\">\n {links.map((link, i) => (\n <OutboundLink\n key={i}\n href={link.href}\n context=\"author-bio-link\"\n className=\"ds-author-bio__link\"\n >\n {link.icon && <span className=\"ds-author-bio__link-icon\">{link.icon}</span>}\n {link.label}\n </OutboundLink>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n },\n);\n\nAuthorBio.displayName = 'AuthorBio';\n","import React, { forwardRef, useState, useEffect } from 'react';\nimport clsx from 'clsx';\nimport { useMessage } from '../../i18n';\nimport './TableOfContents.css';\n\n/* ============================================================================\n TABLE OF CONTENTS\n ============================================================================\n Sticky article TOC with active heading detection via IntersectionObserver.\n\n Strategic objective: Distribution (increases article dwell time)\n ============================================================================ */\n\n/** A TOC item mapping to a heading */\nexport interface TOCItem {\n /** Heading element ID */\n id: string;\n /** Heading text */\n title: string;\n /** Heading level (2 = h2, 3 = h3, etc.) */\n level: number;\n}\n\nexport interface TableOfContentsProps extends React.HTMLAttributes<HTMLElement> {\n /** TOC items (typically extracted from article headings) */\n items: TOCItem[];\n /** Currently active heading ID (controlled) */\n activeId?: string;\n /** Position variant */\n position?: 'sidebar' | 'inline' | 'floating';\n /** Label text */\n label?: string;\n /** Callback when an item is clicked */\n onItemClick?: (id: string) => void;\n}\n\n/**\n * Sticky table of contents with active heading tracking.\n *\n * @example\n * ```tsx\n * <TableOfContents\n * items={[\n * { id: 'intro', title: 'Introduction', level: 2 },\n * { id: 'setup', title: 'Getting Started', level: 2 },\n * { id: 'config', title: 'Configuration', level: 3 },\n * ]}\n * position=\"sidebar\"\n * />\n * ```\n */\nexport const TableOfContents = forwardRef<HTMLElement, TableOfContentsProps>(\n (\n {\n items,\n activeId: controlledActiveId,\n position = 'sidebar',\n label,\n onItemClick,\n className,\n ...props\n },\n ref,\n ) => {\n const t = useMessage();\n const defaultLabel = t({ id: 'ds.toc.label', defaultMessage: 'On this page' });\n const finalLabel = label || defaultLabel;\n\n const [observedActiveId, setObservedActiveId] = useState<string>('');\n const activeId = controlledActiveId ?? observedActiveId;\n\n // Auto-detect active heading via Scroll Listener (more robust than IO for long sections)\n useEffect(() => {\n if (controlledActiveId !== undefined) return;\n if (items.length === 0) return;\n\n const handleScroll = () => {\n const headingElements = items\n .map((item) => ({\n id: item.id,\n el: document.getElementById(item.id),\n }))\n .filter((h): h is { id: string; el: HTMLElement } => !!h.el);\n\n if (headingElements.length === 0) return;\n\n // Offset for sticky header\n const topOffset = 120; \n\n // Find the first heading that is clearly below the top offset\n const firstBelowIndex = headingElements.findIndex((h) => {\n const rect = h.el.getBoundingClientRect();\n return rect.top > topOffset;\n });\n\n let newActiveId = '';\n if (firstBelowIndex === -1) {\n // All headings are above the offset -> last one is active\n newActiveId = headingElements[headingElements.length - 1].id;\n } else if (firstBelowIndex === 0) {\n // First heading is below offset -> none active (or first if we want to be generous)\n newActiveId = ''; // Or headingElements[0].id\n } else {\n // The heading immediately before the one that is below is the active one\n newActiveId = headingElements[firstBelowIndex - 1].id;\n }\n\n setObservedActiveId(newActiveId);\n };\n\n window.addEventListener('scroll', handleScroll, { passive: true });\n // Initial check\n handleScroll();\n\n return () => window.removeEventListener('scroll', handleScroll);\n }, [items, controlledActiveId]);\n\n const handleClick = (id: string) => {\n const el = document.getElementById(id);\n if (el) {\n el.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n if (onItemClick) onItemClick(id);\n };\n\n if (items.length === 0) return null;\n\n return (\n <nav\n ref={ref}\n className={clsx('ds-toc', `ds-toc--${position}`, className)}\n aria-label={finalLabel}\n {...props}\n >\n <span className=\"ds-toc__label\">{finalLabel}</span>\n <ul className=\"ds-toc__list\">\n {items.map((item) => (\n <li key={item.id} className=\"ds-toc__item\" style={{ paddingLeft: `${(item.level - 2) * 12}px` }}>\n <button\n type=\"button\"\n className={clsx(\n 'ds-toc__link',\n activeId === item.id && 'ds-toc__link--active',\n )}\n onClick={() => handleClick(item.id)}\n >\n {item.title}\n </button>\n </li>\n ))}\n </ul>\n </nav>\n );\n },\n);\n\nTableOfContents.displayName = 'TableOfContents';\n","import React, { forwardRef } from 'react';\nimport clsx from 'clsx';\nimport { SectionShell, type SectionShellProps } from '../SectionShell/SectionShell';\nimport { SectionHeader } from '../SectionShell/SectionShell';\nimport { ArticleCard, type ArticleCardProps } from '../ArticleCard/ArticleCard';\nimport './RelatedContent.css';\n\n/* ============================================================================\n RELATED CONTENT\n ============================================================================\n Related articles/resources section. Drives internal linking and increases\n session duration.\n\n Strategic objective: Distribution (internal linking + session depth)\n ============================================================================ */\n\nexport interface RelatedContentProps extends Omit<SectionShellProps, 'title'> {\n /** Section eyebrow */\n eyebrow?: React.ReactNode;\n /** Section title */\n title?: React.ReactNode;\n /** Related article items (uses ArticleCard props) */\n items: ArticleCardProps[];\n /** Max items to display */\n maxVisible?: number;\n}\n\n/**\n * Related articles section using ArticleCard grid.\n *\n * @example\n * ```tsx\n * <RelatedContent\n * title=\"Related Articles\"\n * items={[\n * { title: 'AI Outreach Guide', href: '/blog/ai-outreach', ... },\n * { title: 'Pipeline Automation', href: '/blog/pipeline', ... },\n * ]}\n * background=\"muted\"\n * />\n * ```\n */\nexport const RelatedContent = forwardRef<HTMLDivElement, RelatedContentProps>(\n (\n {\n eyebrow,\n title = 'Related Articles',\n items,\n maxVisible,\n className,\n ...props\n },\n ref,\n ) => {\n const visibleItems = maxVisible ? items.slice(0, maxVisible) : items;\n\n if (visibleItems.length === 0) return null;\n\n return (\n <SectionShell\n ref={ref}\n className={clsx('ds-related-content', className)}\n background=\"muted\"\n {...props}\n >\n <SectionHeader eyebrow={eyebrow} title={title} />\n\n <div className=\"ds-related-content__grid\">\n {visibleItems.map((item, i) => (\n <ArticleCard key={i} {...item} />\n ))}\n </div>\n </SectionShell>\n );\n },\n);\n\nRelatedContent.displayName = 'RelatedContent';\n","import React from 'react';\nimport clsx from 'clsx';\nimport './LongFormLayout.css';\n\nexport interface LongFormLayoutProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Pass the TOC element here to render as a sticky sidebar on desktop */\n sidebar?: React.ReactNode;\n}\n\n/**\n * A layout primitive designed specifically for long-form content (e.g., blog posts, documentation).\n * Enforces maximum reading widths and manages the relationship between the main content and an optional sticky sidebar.\n */\nexport const LongFormLayout = React.forwardRef<HTMLDivElement, LongFormLayoutProps>(\n ({ children, sidebar, className, ...props }, ref) => {\n return (\n <div ref={ref} className={clsx('ds-longform-layout', className)} {...props}>\n <article className=\"ds-longform-layout__main\">{children}</article>\n {sidebar && <aside className=\"ds-longform-layout__sidebar\">{sidebar}</aside>}\n </div>\n );\n }\n);\n\nLongFormLayout.displayName = 'LongFormLayout';\n","import React from 'react';\nimport clsx from 'clsx';\nimport './LongFormComponents.css';\n\nexport interface InsightCalloutProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n icon?: React.ReactNode;\n title?: string;\n}\n\nexport const InsightCallout = React.forwardRef<HTMLDivElement, InsightCalloutProps>(\n ({ children, icon, title, className, ...props }, ref) => {\n return (\n <aside ref={ref} className={clsx('ds-insight-callout', className)} {...props}>\n {icon && <div className=\"ds-insight-callout__icon\">{icon}</div>}\n <div className=\"ds-insight-callout__content\">\n {title && <h5 className=\"ds-insight-callout__title\">{title}</h5>}\n {children}\n </div>\n </aside>\n );\n }\n);\nInsightCallout.displayName = 'InsightCallout';\n\nexport interface DataHighlightProps extends React.HTMLAttributes<HTMLDivElement> {\n stat: string;\n label: string;\n children?: React.ReactNode;\n}\n\nexport const DataHighlight = React.forwardRef<HTMLDivElement, DataHighlightProps>(\n ({ stat, label, children, className, ...props }, ref) => {\n return (\n <figure ref={ref} className={clsx('ds-data-highlight', className)} {...props}>\n <div className=\"ds-data-highlight__stat-group\">\n <span className=\"ds-data-highlight__stat\">{stat}</span>\n <span className=\"ds-data-highlight__label\">{label}</span>\n </div>\n {children && <figcaption className=\"ds-data-highlight__caption\">{children}</figcaption>}\n </figure>\n );\n }\n);\nDataHighlight.displayName = 'DataHighlight';\n","import React, { useEffect, useState, useRef } from 'react';\nimport clsx from 'clsx';\nimport './ReadingProgress.css';\n\nexport interface ReadingProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Reference to the container element whose scroll progress we're tracking */\n targetRef?: React.RefObject<HTMLElement | null>;\n}\n\nexport const ReadingProgress = React.forwardRef<HTMLDivElement, ReadingProgressProps>(\n ({ targetRef, className, ...props }, ref) => {\n const [progress, setProgress] = useState(0);\n const frameRef = useRef<number | null>(null);\n\n useEffect(() => {\n const handleScroll = () => {\n if (frameRef.current) cancelAnimationFrame(frameRef.current);\n\n frameRef.current = requestAnimationFrame(() => {\n let percentage = 0;\n\n if (targetRef && targetRef.current) {\n // Calculate progress relative to the specific container\n const el = targetRef.current;\n const rect = el.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n \n // If top is below viewport, 0%. If bottom is above viewport, 100%.\n if (rect.top > viewportHeight) {\n percentage = 0;\n } else if (rect.bottom < 0) {\n percentage = 100;\n } else {\n const scrollableDistance = rect.height - viewportHeight;\n if (scrollableDistance <= 0) {\n percentage = 100; // Fits entirely on screen\n } else {\n const scrolled = viewportHeight - rect.top;\n percentage = Math.max(0, Math.min(100, (scrolled / scrollableDistance) * 100));\n }\n }\n } else {\n // Fallback to full page scroll\n const scrollPosition = window.scrollY;\n const scrollHeight = document.body.scrollHeight - window.innerHeight;\n percentage = scrollHeight > 0 ? (scrollPosition / scrollHeight) * 100 : 0;\n percentage = Math.max(0, Math.min(100, percentage));\n }\n\n setProgress(percentage);\n });\n };\n\n window.addEventListener('scroll', handleScroll, { passive: true });\n window.addEventListener('resize', handleScroll, { passive: true });\n \n // Initial calculation\n handleScroll();\n\n return () => {\n if (frameRef.current) cancelAnimationFrame(frameRef.current);\n window.removeEventListener('scroll', handleScroll);\n window.removeEventListener('resize', handleScroll);\n };\n }, [targetRef]);\n\n return (\n <div \n ref={ref} \n className={clsx('ds-reading-progress', className)} \n {...props}\n >\n <div \n className=\"ds-reading-progress__bar\" \n style={{ transform: `scaleX(${progress / 100})` }} \n />\n </div>\n );\n }\n);\nReadingProgress.displayName = 'ReadingProgress';\n","import React, { useState } from 'react';\nimport clsx from 'clsx';\nimport { OutboundLink } from '../OutboundLink/OutboundLink';\nimport './VersionedContent.css';\n\n// ============================================================================\n// VersionedUpgradeAlert\n// =============================================================================\n\nexport interface VersionedUpgradeAlertProps extends React.HTMLAttributes<HTMLDivElement> {\n seriesName: string;\n viewedYear: number;\n latestYear: number;\n latestUrl: string;\n deltaSummary?: string;\n}\n\nexport const VersionedUpgradeAlert = React.forwardRef<HTMLDivElement, VersionedUpgradeAlertProps>(\n ({ seriesName, viewedYear, latestYear, latestUrl, deltaSummary, className, ...props }, ref) => {\n const [dismissed, setDismissed] = useState(false);\n\n if (dismissed) return null;\n\n return (\n <div \n ref={ref} \n className={clsx('ds-versioned-alert', className)} \n role=\"alert\"\n {...props}\n >\n <div className=\"ds-versioned-alert__content\">\n <span className=\"ds-versioned-alert__icon\">⚠️</span>\n <div className=\"ds-versioned-alert__text\">\n <strong>Outdated Edition:</strong> You are viewing the {viewedYear} edition of {seriesName}. \n The <strong>{latestYear} edition</strong> is now available.\n {deltaSummary && <span className=\"ds-versioned-alert__delta\"> {deltaSummary}</span>}\n </div>\n </div>\n <div className=\"ds-versioned-alert__actions\">\n <OutboundLink href={latestUrl} context=\"versioned-alert-view-latest\" className=\"ds-versioned-alert__button ds-button ds-button--primary ds-button--sm\" openInNewTab={false}>\n View {latestYear} Edition\n </OutboundLink>\n <button \n className=\"ds-versioned-alert__close\" \n onClick={() => setDismissed(true)}\n aria-label=\"Dismiss alert\"\n >\n ×\n </button>\n </div>\n </div>\n );\n }\n);\nVersionedUpgradeAlert.displayName = 'VersionedUpgradeAlert';\n\n// ============================================================================\n// VersionedSeriesNavigator\n// =============================================================================\n\nexport interface SeriesEdition {\n year: number;\n url: string;\n isCurrent: boolean;\n}\n\nexport interface VersionedSeriesNavigatorProps extends React.HTMLAttributes<HTMLDivElement> {\n seriesName: string;\n hubUrl: string;\n editions: SeriesEdition[];\n}\n\nexport const VersionedSeriesNavigator = React.forwardRef<HTMLDivElement, VersionedSeriesNavigatorProps>(\n ({ seriesName, hubUrl, editions, className, ...props }, ref) => {\n const sortedEditions = [...editions].sort((a, b) => a.year - b.year);\n \n return (\n <div ref={ref} className={clsx('ds-versioned-navigator', className)} {...props}>\n <div className=\"ds-versioned-navigator__header\">\n <span className=\"ds-versioned-navigator__label\">Series</span>\n <OutboundLink href={hubUrl} context=\"versioned-navigator-hub\" className=\"ds-versioned-navigator__title\" openInNewTab={false}>{seriesName} Hub</OutboundLink>\n </div>\n \n <div className=\"ds-versioned-navigator__timeline\">\n {sortedEditions.map((edition, idx) => (\n <React.Fragment key={edition.year}>\n {idx > 0 && <div className=\"ds-versioned-navigator__connector\" />}\n <OutboundLink\n href={edition.url}\n context=\"versioned-navigator-edition\"\n className={clsx(\n 'ds-versioned-navigator__node',\n edition.isCurrent && 'ds-versioned-navigator__node--active'\n )}\n aria-current={edition.isCurrent ? 'page' : undefined}\n openInNewTab={false}\n >\n {edition.year}\n </OutboundLink>\n </React.Fragment>\n ))}\n </div>\n </div>\n );\n }\n);\nVersionedSeriesNavigator.displayName = 'VersionedSeriesNavigator';\n"]}