@flamingo-stack/openframe-frontend-core 0.0.775 → 0.0.777

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 (83) hide show
  1. package/dist/case-study-card-FMH622O5.cjs +25 -0
  2. package/dist/{chunk-F67SEXCW.cjs → chunk-3PCSEZNZ.cjs} +53 -53
  3. package/dist/{chunk-R3JX4MXD.cjs → chunk-3ZLPYEL5.cjs} +10 -10
  4. package/dist/{chunk-SWEPHSIP.cjs → chunk-4JZDJ34E.cjs} +17 -17
  5. package/dist/{chunk-DGFDBPO7.cjs → chunk-5GJM7VRR.cjs} +1 -94
  6. package/dist/{chunk-E64HPPRH.cjs → chunk-5PK22JP7.cjs} +50 -50
  7. package/dist/{chunk-57B5RUYD.cjs → chunk-64KBI5MI.cjs} +2 -2
  8. package/dist/{chunk-PMX6QNNN.cjs → chunk-7LJSGOWS.cjs} +18 -16
  9. package/dist/{chunk-ASMNNSUQ.cjs → chunk-7PNRXJX2.cjs} +3 -3
  10. package/dist/{chunk-VAGZJRYV.cjs → chunk-ALA4KHTE.cjs} +6 -6
  11. package/dist/{chunk-VFZFCRAL.cjs → chunk-AQXKXZWB.cjs} +4 -4
  12. package/dist/{chunk-4LFB4YY3.cjs → chunk-BDDOC425.cjs} +8 -8
  13. package/dist/{chunk-VFUMM6JC.cjs → chunk-BEMGJDXI.cjs} +2 -2
  14. package/dist/{chunk-HY6BCZH7.cjs → chunk-BNUZKBNV.cjs} +3 -3
  15. package/dist/{chunk-Y3EBUFX4.cjs → chunk-CGQ7CL62.cjs} +213 -1647
  16. package/dist/{chunk-ODF3KCRK.cjs → chunk-DOM5CUEY.cjs} +33 -31
  17. package/dist/{chunk-36GYLB3Z.cjs → chunk-G2N7INFT.cjs} +28 -28
  18. package/dist/{chunk-42JGOJCB.cjs → chunk-HXLOCZMG.cjs} +595 -591
  19. package/dist/{chunk-CZIMISAR.cjs → chunk-JB2SEF6Q.cjs} +7 -7
  20. package/dist/{chunk-6SJYFUGD.cjs → chunk-JMFF3L3T.cjs} +28 -26
  21. package/dist/{chunk-LJT2KRE2.cjs → chunk-KLTUTZBO.cjs} +24 -24
  22. package/dist/{chunk-EHJE3UWZ.cjs → chunk-LBGAHB6X.cjs} +20 -20
  23. package/dist/{chunk-TUXPFF4P.cjs → chunk-LGNJTSKB.cjs} +37 -35
  24. package/dist/{chunk-FHTTRWAK.cjs → chunk-LU2DGST4.cjs} +97 -95
  25. package/dist/chunk-MQPTOJMF.cjs +1504 -0
  26. package/dist/{chunk-XXJL5GY3.cjs → chunk-OJZBZH56.cjs} +3 -3
  27. package/dist/{chunk-TF2XYDH3.cjs → chunk-QIATO42V.cjs} +3 -3
  28. package/dist/{chunk-RB7VLVMD.cjs → chunk-R6BKQKIF.cjs} +9 -7
  29. package/dist/{chunk-BTVO676B.cjs → chunk-S3YDUX2I.cjs} +114 -112
  30. package/dist/{chunk-VISK6LKE.cjs → chunk-SDZG7VV7.cjs} +5 -5
  31. package/dist/{chunk-V3W56L2D.cjs → chunk-SIDDZZKL.cjs} +38 -38
  32. package/dist/chunk-SZHDXXMK.cjs +102 -0
  33. package/dist/{chunk-5YJWT5ZQ.cjs → chunk-T47VAUYR.cjs} +91 -89
  34. package/dist/{chunk-IQQ3SLUK.cjs → chunk-T7NDPPLF.cjs} +23 -21
  35. package/dist/{chunk-5P4TDV7V.cjs → chunk-TUAATMUE.cjs} +5 -93
  36. package/dist/{chunk-KWZ62LPZ.cjs → chunk-TZP7PSPG.cjs} +249 -243
  37. package/dist/{chunk-USMR73ND.cjs → chunk-U5VQFKRZ.cjs} +6 -6
  38. package/dist/{chunk-L5CKY5WA.cjs → chunk-UW6AOF42.cjs} +22 -22
  39. package/dist/chunk-V4FXUIMH.cjs +92 -0
  40. package/dist/{chunk-2JRSYWFP.cjs → chunk-VXAKQRV7.cjs} +5 -5
  41. package/dist/{chunk-3XLDYEQD.cjs → chunk-VY3NGJRH.cjs} +53 -51
  42. package/dist/{chunk-TOPGBOCN.cjs → chunk-WCSWWVPF.cjs} +2 -2
  43. package/dist/{chunk-EQBJHJS7.cjs → chunk-WMZIBRTR.cjs} +2 -2
  44. package/dist/{chunk-5QP3K2CE.cjs → chunk-XEYL6AFZ.cjs} +9 -9
  45. package/dist/{chunk-VDXBACD3.cjs → chunk-XVAVQ4BK.cjs} +116 -82
  46. package/dist/{chunk-5AOKXXHV.cjs → chunk-Y6MQBLTZ.cjs} +4 -4
  47. package/dist/{cloud-tenants-ISGAMTJD.cjs → cloud-tenants-EUH42CCL.cjs} +27 -24
  48. package/dist/components/case-studies/index.cjs +45 -41
  49. package/dist/components/chat/index.cjs +21 -17
  50. package/dist/components/contact/index.cjs +28 -25
  51. package/dist/components/docs/index.cjs +31 -28
  52. package/dist/components/embeds/index.cjs +28 -25
  53. package/dist/components/faq/index.cjs +29 -26
  54. package/dist/components/features/index.cjs +28 -24
  55. package/dist/components/features/use-file-playback.d.ts +6 -4
  56. package/dist/components/features/use-file-playback.d.ts.map +1 -1
  57. package/dist/components/features/use-file-playback.js +16 -7
  58. package/dist/components/help-center-pages/index.cjs +131 -127
  59. package/dist/components/index.cjs +94 -90
  60. package/dist/components/meeting-scheduler/index.cjs +95 -92
  61. package/dist/components/navigation/index.cjs +30 -27
  62. package/dist/components/navigation/nav-panel.d.ts.map +1 -1
  63. package/dist/components/navigation/nav-panel.js +47 -13
  64. package/dist/components/onboarding-guides/index.cjs +30 -27
  65. package/dist/components/product-demo/index.cjs +38 -35
  66. package/dist/components/related-content/index.cjs +15 -12
  67. package/dist/components/tickets/index.cjs +33 -30
  68. package/dist/components/ui/index.cjs +28 -24
  69. package/dist/{devices-AHJX6ACJ.cjs → devices-WL3I23EE.cjs} +28 -25
  70. package/dist/{embeddable-chat-DI7ZZTBP.cjs → embeddable-chat-KEWUGQIF.cjs} +99 -95
  71. package/dist/hooks/index.cjs +12 -10
  72. package/dist/index.cjs +36 -30
  73. package/dist/{knowledge-FH5GVRVP.cjs → knowledge-O3PXUX73.cjs} +28 -25
  74. package/dist/{logs-JBIHHLUQ.cjs → logs-XODCXWYI.cjs} +35 -32
  75. package/dist/{policies-XLJ2ABY5.cjs → policies-CQACBIKK.cjs} +31 -28
  76. package/dist/{remote-session-TC3BZDBZ.cjs → remote-session-TGM2OTTV.cjs} +12 -10
  77. package/dist/{scripts-CQLXM7PP.cjs → scripts-QMM6SEB5.cjs} +34 -31
  78. package/dist/{software-update-7NYZ7L76.cjs → software-update-CCCKS4ZE.cjs} +31 -28
  79. package/dist/{tickets-board-YT25IX3O.cjs → tickets-board-FB5AGLJD.cjs} +16 -14
  80. package/dist/{video-file-player-4TXA7BZF.cjs → video-file-player-SIJW5UWU.cjs} +19 -9
  81. package/package.json +1 -1
  82. package/src/components/features/use-file-playback.ts +33 -14
  83. package/src/components/navigation/nav-panel.tsx +74 -14
@@ -0,0 +1,1504 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
+
3
+
4
+
5
+
6
+ var _chunk3ZLPYEL5cjs = require('./chunk-3ZLPYEL5.cjs');
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+ var _chunkSETFUCZAcjs = require('./chunk-SETFUCZA.cjs');
16
+
17
+
18
+
19
+ var _chunk3LW5TD54cjs = require('./chunk-3LW5TD54.cjs');
20
+
21
+
22
+
23
+ var _chunkNTPX5GXIcjs = require('./chunk-NTPX5GXI.cjs');
24
+
25
+
26
+ var _chunkTUAATMUEcjs = require('./chunk-TUAATMUE.cjs');
27
+
28
+
29
+
30
+ var _chunkE76ONBKFcjs = require('./chunk-E76ONBKF.cjs');
31
+
32
+
33
+ var _chunkUJ7AXHRZcjs = require('./chunk-UJ7AXHRZ.cjs');
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+ var _chunkXFRBEXQNcjs = require('./chunk-XFRBEXQN.cjs');
43
+
44
+
45
+ var _chunkTF5D5MNOcjs = require('./chunk-TF5D5MNO.cjs');
46
+
47
+
48
+ var _chunkV45KLJQPcjs = require('./chunk-V45KLJQP.cjs');
49
+
50
+
51
+ var _chunk65VVJSQZcjs = require('./chunk-65VVJSQZ.cjs');
52
+
53
+ // src/components/chat/entity-cards/case-study-card.tsx
54
+ var _react = require('react');
55
+
56
+ // src/components/features/video-bites-shared.ts
57
+ var DEFAULT_VIDEO_BITES_TITLE = "Key Moments";
58
+ function toStripProfile(p, fallbackSubtitle) {
59
+ if (!_optionalChain([p, 'optionalAccess', _ => _.full_name])) return null;
60
+ return {
61
+ name: p.full_name,
62
+ avatarUrl: _nullishCoalesce(p.avatar_url, () => ( null)),
63
+ subtitle: _nullishCoalesce(_nullishCoalesce(p.job_title, () => ( fallbackSubtitle)), () => ( null))
64
+ };
65
+ }
66
+ function sortBitesByCreatedAtDesc(a, b) {
67
+ if (!a.created_at && !b.created_at) return 0;
68
+ if (!a.created_at) return 1;
69
+ if (!b.created_at) return -1;
70
+ return new Date(b.created_at).getTime() - new Date(a.created_at).getTime();
71
+ }
72
+ function sortBitesByFeaturedAtDesc(a, b) {
73
+ if (!a.featured_at && !b.featured_at) return 0;
74
+ if (!a.featured_at) return 1;
75
+ if (!b.featured_at) return -1;
76
+ return new Date(b.featured_at).getTime() - new Date(a.featured_at).getTime();
77
+ }
78
+ function programItemToStripProfile(item) {
79
+ const fromAuthor = toStripProfile(item.author);
80
+ if (fromAuthor) return fromAuthor;
81
+ const host = _nullishCoalesce(_optionalChain([item, 'access', _2 => _2.hosts, 'optionalAccess', _3 => _3[0]]), () => ( null));
82
+ if (!_optionalChain([host, 'optionalAccess', _4 => _4.name])) return null;
83
+ return toStripProfile({ full_name: host.name, avatar_url: _nullishCoalesce(host.avatar_url, () => ( null)) });
84
+ }
85
+
86
+ // src/components/features/video-hover-preview.tsx
87
+
88
+
89
+ // src/components/chat/entity-cards/use-cover-image-fallback.ts
90
+
91
+ function useCoverImageFallback(imageUrl, placeholderUrl) {
92
+ const [failed, setFailed] = _react.useState.call(void 0, () => /* @__PURE__ */ new Set());
93
+ const src = imageUrl && !failed.has(imageUrl) ? imageUrl : placeholderUrl && !failed.has(placeholderUrl) ? placeholderUrl : null;
94
+ const onError = _react.useCallback.call(void 0, () => {
95
+ if (!src) return;
96
+ setFailed((prev) => new Set(prev).add(src));
97
+ }, [src]);
98
+ return { src, onError };
99
+ }
100
+ var hideOnError = (e) => {
101
+ const img = e.currentTarget;
102
+ img.style.display = "none";
103
+ };
104
+
105
+ // src/components/features/video.tsx
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+ var _jsxruntime = require('react/jsx-runtime');
117
+ var filePlayer = null;
118
+ var filePlayerLoad = null;
119
+ var filePlayerListeners = /* @__PURE__ */ new Set();
120
+ function loadFilePlayer() {
121
+ if (filePlayer || filePlayerLoad) return;
122
+ filePlayerLoad = Promise.resolve().then(() => _interopRequireWildcard(require("./video-file-player-SIJW5UWU.cjs"))).then((module) => {
123
+ filePlayer = module.default;
124
+ for (const listener of filePlayerListeners) listener();
125
+ }).catch(() => void 0).finally(() => {
126
+ filePlayerLoad = null;
127
+ });
128
+ }
129
+ function subscribeToFilePlayer(listener) {
130
+ filePlayerListeners.add(listener);
131
+ loadFilePlayer();
132
+ return () => {
133
+ filePlayerListeners.delete(listener);
134
+ };
135
+ }
136
+ var loadedFilePlayer = () => filePlayer;
137
+ var noFilePlayer = () => null;
138
+ var PosterBox = _react.forwardRef.call(void 0, function PosterBoxView({ poster, className, priority, fill }, ref) {
139
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
140
+ "div",
141
+ {
142
+ ref,
143
+ "aria-hidden": "true",
144
+ className: _chunk65VVJSQZcjs.cn.call(void 0, "relative overflow-hidden", className),
145
+ style: fill ? { width: "100%", height: "100%" } : void 0,
146
+ children: poster ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkE76ONBKFcjs.next_image_default, { src: poster, alt: "", fill: true, sizes: "100vw", priority, unoptimized: true, className: "object-cover" }) : null
147
+ }
148
+ );
149
+ });
150
+ function FilePlayerFallback({
151
+ poster,
152
+ className,
153
+ priority
154
+ }) {
155
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PosterBox, { poster, className, priority, fill: true });
156
+ }
157
+ function waitsForPlay(props) {
158
+ return !props.autoPlay && !props.autoPlayUnmuted && !props.playOnHover && props.playWhenHovered === void 0 && props.startTime === void 0 && !props.playerHandleRef && !props.chromeless;
159
+ }
160
+ function FilePlayer({
161
+ title,
162
+ priority,
163
+ ...props
164
+ }) {
165
+ const [facade] = _react.useState.call(void 0, () => waitsForPlay(props));
166
+ const [pressed, setPressed] = _react.useState.call(void 0, false);
167
+ if (facade && !pressed) {
168
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunk65VVJSQZcjs.cn.call(void 0, "relative", props.className), style: { width: "100%", height: "100%" }, children: [
169
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FilePlayerFallback, { poster: props.poster, className: "absolute inset-0", priority }),
170
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
171
+ _chunkTF5D5MNOcjs.Button,
172
+ {
173
+ type: "button",
174
+ variant: "glyph",
175
+ size: "wrap",
176
+ "aria-label": title ? `Play: ${title}` : "Play video",
177
+ onPointerEnter: loadFilePlayer,
178
+ onFocus: loadFilePlayer,
179
+ onTouchStart: loadFilePlayer,
180
+ onClick: () => {
181
+ loadFilePlayer();
182
+ setPressed(true);
183
+ },
184
+ className: "group absolute inset-0 rounded-none",
185
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
186
+ _chunkSETFUCZAcjs.VideoPlayBadge,
187
+ {
188
+ size: "lg",
189
+ className: "transition-transform duration-200 group-hover:scale-110 group-hover:text-ods-accent"
190
+ }
191
+ )
192
+ }
193
+ )
194
+ ] });
195
+ }
196
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LoadedFilePlayer, { ...props, priority, ...facade ? { autoPlayUnmuted: true } : {} });
197
+ }
198
+ function LoadedFilePlayer({ priority, ...props }) {
199
+ const arrived = _react.useSyncExternalStore.call(void 0, subscribeToFilePlayer, loadedFilePlayer, noFilePlayer);
200
+ if (arrived) return _react.createElement.call(void 0, arrived, props);
201
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FilePlayerFallback, { poster: props.poster, className: props.className, priority });
202
+ }
203
+ var YT_HOSTS = /* @__PURE__ */ new Set([
204
+ "youtube.com",
205
+ "www.youtube.com",
206
+ "m.youtube.com",
207
+ "youtu.be",
208
+ "youtube-nocookie.com",
209
+ "www.youtube-nocookie.com"
210
+ ]);
211
+ function isYouTubeUrl(url) {
212
+ try {
213
+ return YT_HOSTS.has(new URL(url, "http://placeholder.local").hostname.toLowerCase());
214
+ } catch (e2) {
215
+ return false;
216
+ }
217
+ }
218
+ var YT_PATH_RE = /^\/(?:embed|v|shorts)\/([^/]+)\/?$/;
219
+ var BARE_YT_ID_RE = /^[A-Za-z0-9_-]{11}$/;
220
+ function extractYouTubeId(url) {
221
+ if (!url) return null;
222
+ if (BARE_YT_ID_RE.test(url)) return url;
223
+ let u;
224
+ try {
225
+ u = new URL(url, "http://placeholder.local");
226
+ } catch (e3) {
227
+ return null;
228
+ }
229
+ if (!YT_HOSTS.has(u.hostname.toLowerCase())) return null;
230
+ if (u.hostname.toLowerCase().endsWith("youtu.be")) {
231
+ return _nullishCoalesce(u.pathname.split("/").filter(Boolean)[0], () => ( null));
232
+ }
233
+ const v = u.searchParams.get("v");
234
+ if (v) return v;
235
+ const m = u.pathname.match(YT_PATH_RE);
236
+ return m ? m[1] : null;
237
+ }
238
+ function Video(props) {
239
+ const { ref: nearRef, isNear } = _chunkNTPX5GXIcjs.useNearViewport.call(void 0, );
240
+ const loading = _chunkXFRBEXQNcjs.useLoadingScope.call(void 0, );
241
+ const url = props.url;
242
+ const layout = _nullishCoalesce(props.layout, () => ( "native"));
243
+ if (loading && !url) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, VideoSkeleton, { layout, className: props.className });
244
+ if (!url) return null;
245
+ const effectiveKind = resolveKind(props, url);
246
+ if ((_nullishCoalesce(props.lazy, () => ( true))) && !isNear) {
247
+ return wrapWithLayout(
248
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
249
+ PosterBox,
250
+ {
251
+ ref: nearRef,
252
+ poster: props.poster,
253
+ className: props.className,
254
+ priority: "priority" in props ? props.priority : void 0
255
+ }
256
+ ),
257
+ layout
258
+ );
259
+ }
260
+ const inner = effectiveKind === "youtube" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
261
+ YouTubeFacade,
262
+ {
263
+ url,
264
+ title: props.title,
265
+ priority: props.priority,
266
+ className: props.className,
267
+ minimalControls: props.minimalControls,
268
+ muted: props.muted,
269
+ ..._chunkSETFUCZAcjs.pickYouTube.call(void 0, props)
270
+ }
271
+ ) : "firstFrameOnly" in props && props.firstFrameOnly ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
272
+ FirstFramePreview,
273
+ {
274
+ url,
275
+ poster: props.poster,
276
+ fit: "fit" in props ? props.fit : void 0,
277
+ className: props.className
278
+ }
279
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
280
+ FilePlayer,
281
+ {
282
+ url,
283
+ poster: props.poster,
284
+ title: props.title,
285
+ priority: props.priority,
286
+ muted: props.muted,
287
+ ..._chunkSETFUCZAcjs.pickFilePlayback.call(void 0, props),
288
+ className: props.className
289
+ }
290
+ );
291
+ return wrapWithLayout(inner, layout);
292
+ }
293
+ function resolveKind(props, url) {
294
+ if ("kind" in props) {
295
+ if (props.kind === "youtube") return "youtube";
296
+ if (props.kind === "file") return "file";
297
+ }
298
+ if (BARE_YT_ID_RE.test(url)) return "youtube";
299
+ return isYouTubeUrl(url) ? "youtube" : "file";
300
+ }
301
+ function VideoSkeleton({ layout = "native", className }) {
302
+ return wrapWithLayout(/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.UnifiedSkeleton, { variant: "rectangular", className: _chunk65VVJSQZcjs.cn.call(void 0, "h-full w-full", className) }), layout);
303
+ }
304
+ function wrapWithLayout(inner, layout) {
305
+ switch (layout) {
306
+ case "centered":
307
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex w-full justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "aspect-video w-full max-w-3xl overflow-hidden rounded-lg border border-ods-border", children: inner }) });
308
+ case "fill":
309
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 h-full w-full", children: inner });
310
+ case "wide":
311
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "aspect-video w-full overflow-hidden rounded-lg bg-ods-bg", children: inner });
312
+ case "native":
313
+ default:
314
+ return inner;
315
+ }
316
+ }
317
+ function FirstFramePreview({
318
+ url,
319
+ poster,
320
+ fit,
321
+ className
322
+ }) {
323
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
324
+ "div",
325
+ {
326
+ "aria-hidden": true,
327
+ className: "h-full w-full",
328
+ style: { "--media-background-color": "transparent" },
329
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FilePlayer, { url: `${url}#t=0.1`, poster, fit, muted: true, chromeless: true, className })
330
+ }
331
+ );
332
+ }
333
+ function YouTubeFacade({
334
+ url,
335
+ title = "YouTube Video",
336
+ priority,
337
+ className,
338
+ minimalControls,
339
+ muted,
340
+ // `...facade` rather than naming each one: this hop is invisible to the
341
+ // build-time forwarding proof, so a prop added to VideoYouTubeFacadeProps
342
+ // would reach here and silently stop before Inner.
343
+ ...facade
344
+ }) {
345
+ const videoId = extractYouTubeId(url);
346
+ if (!videoId) return null;
347
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
348
+ YouTubeFacadeInner,
349
+ {
350
+ videoId,
351
+ title,
352
+ priority,
353
+ className,
354
+ minimalControls,
355
+ muted,
356
+ ...facade
357
+ }
358
+ );
359
+ }
360
+ var YT_NOCOOKIE_ORIGIN = "https://www.youtube-nocookie.com";
361
+ var YT_POSTER_TIERS = ["maxresdefault", "mqdefault"];
362
+ var YT_STATE_ENDED = 0;
363
+ var YT_STATE_PLAYING = 1;
364
+ var YT_PLAYING_BLUR_DELAY_MS = 1e3;
365
+ function toYouTubeMessage(parsed) {
366
+ if (typeof parsed !== "object" || parsed === null) return null;
367
+ const event = "event" in parsed ? parsed.event : void 0;
368
+ const info = "info" in parsed ? parsed.info : void 0;
369
+ const playerState = typeof info === "object" && info !== null && "playerState" in info ? info.playerState : void 0;
370
+ return {
371
+ event: typeof event === "string" ? event : void 0,
372
+ info: { playerState: typeof playerState === "number" ? playerState : void 0 },
373
+ errorCode: typeof info === "number" ? info : void 0
374
+ };
375
+ }
376
+ function YouTubeFacadeInner({
377
+ videoId,
378
+ title,
379
+ priority,
380
+ className,
381
+ minimalControls,
382
+ muted,
383
+ autoActivate,
384
+ suspended
385
+ }) {
386
+ const [activated, setActivated] = _react.useState.call(void 0, Boolean(autoActivate));
387
+ const [prevAutoActivate, setPrevAutoActivate] = _react.useState.call(void 0, Boolean(autoActivate));
388
+ if (Boolean(autoActivate) !== prevAutoActivate) {
389
+ setPrevAutoActivate(Boolean(autoActivate));
390
+ if (autoActivate) setActivated(true);
391
+ }
392
+ const [failed, setFailed] = _react.useState.call(void 0, false);
393
+ const [reloadNonce, setReloadNonce] = _react.useState.call(void 0, 0);
394
+ const iframeRef = _react.useRef.call(void 0, null);
395
+ const retry = _react.useCallback.call(void 0, () => {
396
+ setFailed(false);
397
+ setReloadNonce((n) => n + 1);
398
+ }, []);
399
+ const embedUrl = _react.useMemo.call(void 0, () => {
400
+ const params = new URLSearchParams({
401
+ autoplay: "1",
402
+ rel: "0",
403
+ modestbranding: "1",
404
+ playsinline: "1",
405
+ enablejsapi: "1"
406
+ });
407
+ if (muted) params.set("mute", "1");
408
+ if (typeof window !== "undefined") {
409
+ params.set("origin", window.location.origin);
410
+ }
411
+ if (minimalControls) {
412
+ params.set("controls", "0");
413
+ params.set("fs", "0");
414
+ params.set("iv_load_policy", "3");
415
+ params.set("cc_load_policy", "0");
416
+ params.set("disablekb", "1");
417
+ }
418
+ return `${YT_NOCOOKIE_ORIGIN}/embed/${videoId}?${params.toString()}`;
419
+ }, [videoId, minimalControls, muted]);
420
+ const [posterTier, setPosterTier] = _react.useState.call(void 0, 0);
421
+ const [posterTierFor, setPosterTierFor] = _react.useState.call(void 0, videoId);
422
+ if (posterTierFor !== videoId) {
423
+ setPosterTierFor(videoId);
424
+ setPosterTier(0);
425
+ }
426
+ const posterQuality = YT_POSTER_TIERS[posterTier];
427
+ const posterJpg = `https://i.ytimg.com/vi/${videoId}/${posterQuality}.jpg`;
428
+ const posterWebp = `https://i.ytimg.com/vi_webp/${videoId}/${posterQuality}.webp`;
429
+ const handlePosterError = () => setPosterTier((tier) => Math.min(tier + 1, YT_POSTER_TIERS.length - 1));
430
+ _react.useEffect.call(void 0, () => {
431
+ if (!activated || failed) return void 0;
432
+ const iframe = iframeRef.current;
433
+ if (!iframe) return void 0;
434
+ function subscribe() {
435
+ _optionalChain([iframe, 'optionalAccess', _5 => _5.contentWindow, 'optionalAccess', _6 => _6.postMessage, 'call', _7 => _7('{"event":"listening"}', YT_NOCOOKIE_ORIGIN)]);
436
+ }
437
+ iframe.addEventListener("load", subscribe);
438
+ subscribe();
439
+ let blurTimer = null;
440
+ function handleMessage(event) {
441
+ if (event.origin !== YT_NOCOOKIE_ORIGIN) return;
442
+ if (typeof event.data !== "string") return;
443
+ let payload = null;
444
+ try {
445
+ payload = toYouTubeMessage(JSON.parse(event.data));
446
+ } catch (e4) {
447
+ return;
448
+ }
449
+ if (!payload) return;
450
+ if (payload.event === "onError") {
451
+ setFailed(true);
452
+ _chunkSETFUCZAcjs.reportPlaybackFailure.call(void 0, { kind: "youtube", src: videoId, reason: "error", errorCode: payload.errorCode });
453
+ return;
454
+ }
455
+ if (payload.event !== "infoDelivery") return;
456
+ const state = _optionalChain([payload, 'access', _8 => _8.info, 'optionalAccess', _9 => _9.playerState]);
457
+ if (typeof state !== "number") return;
458
+ if (state === YT_STATE_PLAYING) {
459
+ if (blurTimer !== null) return;
460
+ blurTimer = setTimeout(() => {
461
+ blurTimer = null;
462
+ _optionalChain([iframeRef, 'access', _10 => _10.current, 'optionalAccess', _11 => _11.blur, 'call', _12 => _12()]);
463
+ }, YT_PLAYING_BLUR_DELAY_MS);
464
+ return;
465
+ }
466
+ if (state === YT_STATE_ENDED) {
467
+ setActivated(false);
468
+ }
469
+ }
470
+ window.addEventListener("message", handleMessage);
471
+ return () => {
472
+ iframe.removeEventListener("load", subscribe);
473
+ window.removeEventListener("message", handleMessage);
474
+ if (blurTimer !== null) clearTimeout(blurTimer);
475
+ };
476
+ }, [activated, failed, reloadNonce, videoId]);
477
+ const prevSuspendedRef = _react.useRef.call(void 0, false);
478
+ _react.useEffect.call(void 0, () => {
479
+ const wasSuspended = prevSuspendedRef.current;
480
+ prevSuspendedRef.current = Boolean(suspended);
481
+ if (!activated || Boolean(suspended) === wasSuspended) return;
482
+ _optionalChain([iframeRef, 'access', _13 => _13.current, 'optionalAccess', _14 => _14.contentWindow, 'optionalAccess', _15 => _15.postMessage, 'call', _16 => _16(
483
+ `{"event":"command","func":"${suspended ? "pauseVideo" : "playVideo"}","args":[]}`,
484
+ YT_NOCOOKIE_ORIGIN
485
+ )]);
486
+ }, [suspended, activated]);
487
+ const wrapperClass = `relative w-full ${_nullishCoalesce(className, () => ( ""))}`;
488
+ const wrapperStyle = { paddingBottom: "56.25%" };
489
+ if (activated && failed) {
490
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: wrapperClass, style: wrapperStyle, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSETFUCZAcjs.VideoErrorOverlay, { onRetry: retry, watchOnYouTubeId: videoId }) });
491
+ }
492
+ if (activated) {
493
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: wrapperClass, style: wrapperStyle, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
494
+ "iframe",
495
+ {
496
+ ref: iframeRef,
497
+ src: embedUrl,
498
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",
499
+ allowFullScreen: true,
500
+ referrerPolicy: "strict-origin-when-cross-origin",
501
+ title,
502
+ className: "absolute inset-0 h-full w-full rounded-lg border-0"
503
+ },
504
+ reloadNonce
505
+ ) });
506
+ }
507
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: wrapperClass, style: wrapperStyle, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
508
+ "button",
509
+ {
510
+ type: "button",
511
+ "aria-label": `Play: ${title}`,
512
+ onClick: () => setActivated(true),
513
+ className: "group absolute inset-0 m-0 cursor-pointer overflow-hidden rounded-lg border border-ods-border bg-ods-card p-0",
514
+ children: [
515
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "picture", { children: [
516
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "source", { type: "image/webp", srcSet: posterWebp }),
517
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
518
+ "img",
519
+ {
520
+ src: posterJpg,
521
+ alt: title,
522
+ width: 1280,
523
+ height: 720,
524
+ loading: "lazy",
525
+ onError: handlePosterError,
526
+ ..._chunkE76ONBKFcjs.fetchPriorityProp.call(void 0, priority),
527
+ decoding: priority ? "sync" : "async",
528
+ className: "absolute inset-0 h-full w-full object-cover"
529
+ }
530
+ )
531
+ ] }),
532
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 flex items-center justify-center bg-ods-bg bg-opacity-20 transition-opacity duration-200 group-hover:bg-opacity-30", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
533
+ _chunkSETFUCZAcjs.VideoPlayBadge,
534
+ {
535
+ size: "lg",
536
+ className: "transition-transform duration-200 group-hover:scale-110 group-hover:text-ods-accent"
537
+ }
538
+ ) })
539
+ ]
540
+ }
541
+ ) });
542
+ }
543
+
544
+ // src/components/features/video-hover-preview.tsx
545
+
546
+ function VideoHoverPreviewSurface({
547
+ url,
548
+ posterUrl = null,
549
+ active,
550
+ playerMounted,
551
+ isClone = false,
552
+ badge = "play",
553
+ fit,
554
+ posterSizes = "234px",
555
+ posterInView = false,
556
+ preload,
557
+ hideMutedBadge,
558
+ onMutedFallbackChange,
559
+ previewHandleRef,
560
+ mutedIntent = false,
561
+ continuation = false,
562
+ startTime,
563
+ autoPlay = false,
564
+ startMuted = false,
565
+ onEnded,
566
+ className
567
+ }) {
568
+ const previewUrl = _chunkSETFUCZAcjs.toMuxPreviewUrl.call(void 0, url);
569
+ const gateControlled = playerMounted !== void 0;
570
+ const rootElRef = _react.useRef.call(void 0, null);
571
+ const [isNear, setIsNear] = _react.useState.call(void 0, false);
572
+ _react.useEffect.call(void 0, () => {
573
+ if (gateControlled) return void 0;
574
+ const el = rootElRef.current;
575
+ if (!el || typeof IntersectionObserver === "undefined") return void 0;
576
+ const io = new IntersectionObserver((entries) => setIsNear(_nullishCoalesce(_optionalChain([entries, 'access', _17 => _17[0], 'optionalAccess', _18 => _18.isIntersecting]), () => ( false))), {
577
+ rootMargin: _chunkNTPX5GXIcjs.NEAR_VIEWPORT_ROOT_MARGIN
578
+ });
579
+ io.observe(el);
580
+ return () => io.disconnect();
581
+ }, [gateControlled]);
582
+ const showMedia = continuation || (gateControlled ? playerMounted : isNear);
583
+ const [engaged, setEngaged] = _react.useState.call(void 0, false);
584
+ if ((active || continuation) && !engaged) setEngaged(true);
585
+ const showPlayer = continuation || engaged;
586
+ const { src: posterSrc, onError: onPosterError } = useCoverImageFallback(posterUrl);
587
+ const facadeSkipped = preload === "none" && !posterSrc;
588
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: rootElRef, className: _chunk65VVJSQZcjs.cn.call(void 0, "absolute inset-0", className), inert: isClone || void 0, children: showMedia ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
589
+ posterSrc ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
590
+ _chunkE76ONBKFcjs.next_image_default,
591
+ {
592
+ src: posterSrc,
593
+ alt: "",
594
+ fill: true,
595
+ sizes: posterSizes,
596
+ loading: posterInView ? "eager" : "lazy",
597
+ unoptimized: true,
598
+ onError: onPosterError,
599
+ className: "object-cover"
600
+ }
601
+ ) : facadeSkipped ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 bg-ods-card" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Video, { kind: "file", url: previewUrl, firstFrameOnly: true, layout: "fill", fit }),
602
+ badge === "play" && !active && !continuation && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSETFUCZAcjs.VideoPlayBadge, { className: "absolute inset-0 z-10 m-auto" }),
603
+ showPlayer ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
604
+ "div",
605
+ {
606
+ className: "absolute inset-0",
607
+ style: { "--media-background-color": "transparent" },
608
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
609
+ Video,
610
+ {
611
+ kind: "file",
612
+ url: previewUrl,
613
+ poster: posterUrl,
614
+ ...continuation ? {
615
+ startTime,
616
+ autoPlay: autoPlay && startMuted,
617
+ startMuted,
618
+ autoPlayUnmuted: autoPlay && !startMuted
619
+ } : { playWhenHovered: active },
620
+ chromeless: true,
621
+ layout: "fill",
622
+ fit,
623
+ preload,
624
+ mutedIntent,
625
+ hideMutedBadge,
626
+ onMutedFallbackChange,
627
+ onEnded,
628
+ playerHandleRef: previewHandleRef
629
+ },
630
+ continuation ? "continuation" : "preview"
631
+ )
632
+ }
633
+ ) : null
634
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 bg-ods-card" }) });
635
+ }
636
+
637
+ // src/components/icon-display.tsx
638
+
639
+ function EntityIcon({
640
+ icon,
641
+ size = 20,
642
+ className
643
+ }) {
644
+ const identity = _chunk3ZLPYEL5cjs.useAgentIdentityIcon.call(void 0, _optionalChain([icon, 'optionalAccess', _19 => _19.url]) ? null : _optionalChain([icon, 'optionalAccess', _20 => _20.name]));
645
+ const held = _chunkXFRBEXQNcjs.useLoadingScope.call(void 0, );
646
+ if (held) {
647
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
648
+ _chunkXFRBEXQNcjs.UnifiedSkeleton,
649
+ {
650
+ as: "span",
651
+ width: size,
652
+ height: size,
653
+ className: _chunk65VVJSQZcjs.cn.call(void 0, "inline-block shrink-0 rounded-md", className)
654
+ }
655
+ );
656
+ }
657
+ if (!_optionalChain([icon, 'optionalAccess', _21 => _21.url]) && _optionalChain([identity, 'optionalAccess', _22 => _22.url])) {
658
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
659
+ _chunkE76ONBKFcjs.next_image_default,
660
+ {
661
+ src: identity.url,
662
+ alt: "",
663
+ width: size,
664
+ height: size,
665
+ className: _chunk65VVJSQZcjs.cn.call(void 0, _chunk3ZLPYEL5cjs.AGENT_PICTURE_CLASS, className),
666
+ unoptimized: true
667
+ }
668
+ );
669
+ }
670
+ if (_optionalChain([icon, 'optionalAccess', _23 => _23.url])) {
671
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
672
+ _chunkE76ONBKFcjs.next_image_default,
673
+ {
674
+ src: icon.url,
675
+ alt: "",
676
+ width: size,
677
+ height: size,
678
+ className,
679
+ style: { objectFit: "contain" },
680
+ unoptimized: true
681
+ }
682
+ );
683
+ }
684
+ const Glyph = _chunkTUAATMUEcjs.resolveIcon.call(void 0, _nullishCoalesce(_nullishCoalesce(_optionalChain([identity, 'optionalAccess', _24 => _24.name]), () => ( _optionalChain([icon, 'optionalAccess', _25 => _25.name]))), () => ( void 0)));
685
+ const agentColor = identity ? { color: _chunk3ZLPYEL5cjs.AGENT_GLYPH_COLOR } : {};
686
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Glyph, { size, className, ...agentColor, ..._nullishCoalesce(_optionalChain([identity, 'optionalAccess', _26 => _26.props]), () => ( {})), ..._nullishCoalesce(_optionalChain([icon, 'optionalAccess', _27 => _27.props]), () => ( {})) });
687
+ }
688
+
689
+ // src/components/ui/card.tsx
690
+
691
+
692
+ var CARD_VARIANT_CLASS = {
693
+ default: "rounded-lg bg-card text-card-foreground shadow-sm",
694
+ panel: "rounded-md bg-ods-card text-ods-text-primary"
695
+ };
696
+ var Card = _react.forwardRef.call(void 0,
697
+ ({ className, variant = "default", ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
698
+ "div",
699
+ {
700
+ ref,
701
+ className: _chunk65VVJSQZcjs.cn.call(void 0,
702
+ // `border` with NO color token resolves to `currentColor` — on a dark card
703
+ // with light text that paints a WHITE outline. Every ODS surface borders
704
+ // on `--color-border`; say so.
705
+ "border border-ods-border",
706
+ CARD_VARIANT_CLASS[variant],
707
+ className
708
+ ),
709
+ ...props
710
+ }
711
+ )
712
+ );
713
+ Card.displayName = "Card";
714
+ var CardHeader = _react.forwardRef.call(void 0, ({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref, className: _chunk65VVJSQZcjs.cn.call(void 0, "flex flex-col space-y-1.5 p-6", className), ...props }));
715
+ CardHeader.displayName = "CardHeader";
716
+ var CardTitle = _react.forwardRef.call(void 0, ({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref, className: _chunk65VVJSQZcjs.cn.call(void 0, "text-h2", className), ...props }));
717
+ CardTitle.displayName = "CardTitle";
718
+ var CardDescription = _react.forwardRef.call(void 0, ({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref, className: _chunk65VVJSQZcjs.cn.call(void 0, "text-muted-foreground text-h6", className), ...props }));
719
+ CardDescription.displayName = "CardDescription";
720
+ var CardContent = _react.forwardRef.call(void 0, ({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref, className: _chunk65VVJSQZcjs.cn.call(void 0, "p-6 pt-0", className), ...props }));
721
+ CardContent.displayName = "CardContent";
722
+ var CardFooter = _react.forwardRef.call(void 0, ({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref, className: _chunk65VVJSQZcjs.cn.call(void 0, "flex items-center p-6 pt-0", className), ...props }));
723
+ CardFooter.displayName = "CardFooter";
724
+ function CardHorizontal({ icon, title, description, className = "", borderLeft = true }) {
725
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
726
+ "div",
727
+ {
728
+ className: _chunk65VVJSQZcjs.cn.call(void 0,
729
+ "flex min-h-[80px] w-full flex-row items-center gap-3 bg-ods-card p-4 content-md:gap-4 content-md:p-6",
730
+ borderLeft ? "border-l border-ods-border" : "",
731
+ className
732
+ ),
733
+ children: [
734
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-5 w-5 flex-shrink-0", children: icon }),
735
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-w-0 flex-col", children: [
736
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mb-0.5 text-left text-ods-text-primary text-h6", children: title }),
737
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-left text-ods-text-secondary text-h6", children: description })
738
+ ] })
739
+ ]
740
+ }
741
+ );
742
+ }
743
+
744
+ // src/utils/url-safety.ts
745
+ var UNSAFE_URL_CHARS = /[\u0000-\u001f\u007f\u200b-\u200d\u2028\u2029\ufeff]/;
746
+ var SAME_ORIGIN_PROBE = "https://_sameorigin_.invalid";
747
+ function isSameOriginPath(candidate) {
748
+ try {
749
+ return new URL(candidate, SAME_ORIGIN_PROBE).origin === SAME_ORIGIN_PROBE;
750
+ } catch (e5) {
751
+ return false;
752
+ }
753
+ }
754
+
755
+ // src/components/chat/utils/compact-card-classes.ts
756
+ var COMPACT_CARD_OUTER = "my-1.5 flex items-start gap-3 w-full p-2 rounded-lg border border-ods-border bg-ods-card no-underline transition-colors hover:border-ods-text-secondary/40";
757
+ var COMPACT_CARD_OUTER_STATIC = "my-1.5 flex items-start gap-3 w-full p-2 rounded-lg border border-ods-border bg-ods-card no-underline cursor-default";
758
+ var COMPACT_CARD_SKELETON_OUTER = "my-1.5 flex w-full items-start gap-3 rounded-lg border border-ods-border bg-ods-card p-2";
759
+ var COMPACT_CARD_IMAGE_SLOT = "relative block shrink-0 self-start w-14 h-14 aspect-square overflow-hidden rounded-md bg-ods-bg";
760
+ var COMPACT_CARD_SKELETON_IMAGE_SLOT = `block ${_chunkXFRBEXQNcjs.TILE_SIZE.thumb} ${_chunkXFRBEXQNcjs.MEDIA_ASPECT.square} shrink-0 self-start rounded-md`;
761
+ var COMPACT_CARD_ICON_SLOT = "flex h-14 w-14 aspect-square shrink-0 self-start items-center justify-center rounded-md bg-ods-bg text-ods-accent";
762
+ var COMPACT_CARD_TEXT_COL = "flex min-w-0 flex-1 flex-col gap-0.5 min-h-14";
763
+ var COMPACT_CARD_TITLE_ROW = "flex items-center min-w-0 h-5";
764
+ var COMPACT_CARD_META_ROW_BOX = "flex items-center min-w-0 h-4";
765
+ var COMPACT_CARD_TITLE_TYPE = "text-sm font-semibold leading-5";
766
+ var COMPACT_CARD_TITLE = `truncate ${COMPACT_CARD_TITLE_TYPE} text-ods-text-primary`;
767
+ var COMPACT_CARD_TITLE_WRAP_ROW = "flex min-w-0 flex-wrap items-center gap-1.5";
768
+ var COMPACT_CARD_TRAILING_ICON = "flex h-5 shrink-0 items-center self-start text-ods-text-secondary";
769
+ var COMPACT_CARD_SUBTITLE = "truncate text-h6 text-ods-text-secondary";
770
+ var COMPACT_CARD_SUMMARY = "truncate text-h6 text-ods-text-secondary/80";
771
+ var COMPACT_CARD_META_ROW = "flex items-center gap-1.5 min-w-0 text-h6 text-ods-text-secondary";
772
+ var COMPACT_CARD_ROW_FILLER = "\xA0";
773
+ var SAFE_URL_SCHEMES = ["http:", "https:", "mailto:"];
774
+ function safeHref(url) {
775
+ if (!url) return null;
776
+ if (UNSAFE_URL_CHARS.test(url)) return null;
777
+ const trimmed = url.trim();
778
+ if (!trimmed) return null;
779
+ if (trimmed.startsWith("/")) return isSameOriginPath(trimmed) ? trimmed : null;
780
+ if (trimmed.startsWith("#")) return trimmed;
781
+ if (/^[a-z][a-z0-9+.-]*:$/i.test(trimmed)) return null;
782
+ try {
783
+ const parsed = new URL(trimmed, "https://_safehref_base.invalid");
784
+ if (!SAFE_URL_SCHEMES.includes(parsed.protocol)) return null;
785
+ if ((parsed.protocol === "https:" || parsed.protocol === "http:") && !parsed.hostname) return null;
786
+ return trimmed;
787
+ } catch (e6) {
788
+ return null;
789
+ }
790
+ }
791
+
792
+ // src/components/chat/utils/compact-card-skeleton.tsx
793
+ var _lucidereact = require('lucide-react');
794
+
795
+ // src/components/ui/status-badge.tsx
796
+ var _classvarianceauthority = require('class-variance-authority');
797
+
798
+ var statusBadgeVariants = _classvarianceauthority.cva.call(void 0, "inline-flex items-center justify-center rounded", {
799
+ variants: {
800
+ // Two densities, not one style at two paddings. Both are the ODS h5
801
+ // label treatment (Azeret Mono 500, uppercase, -0.02em); they differ in
802
+ // scale. Putting BOTH on `text-h5` is what regressed the stamp: at
803
+ // 14/20 on desktop every inline badge grew ~40% and its box doubled,
804
+ // because the caption line-height replaced `leading-none`.
805
+ variant: {
806
+ // Standalone badge — the ODS caption composite, unmodified.
807
+ card: "px-3 py-1.5 text-h5",
808
+ // Dense inline stamp. Family, weight and casing come from the SAME h5
809
+ // tokens as `card`; only the scale is set here, because ODS has no
810
+ // step below the 12/14px caption and this stamp is 10px by design.
811
+ button: "px-2 py-0.5 font-[family-name:var(--font-h5-family)] font-[number:var(--font-h5-weight)] uppercase tracking-[-0.02em] text-badge"
812
+ },
813
+ colorScheme: {
814
+ cyan: "bg-ods-flamingo-cyan text-ods-text-on-accent",
815
+ pink: "bg-ods-flamingo-pink text-ods-text-on-accent",
816
+ yellow: "border border-ods-border bg-ods-accent text-ods-text-on-accent",
817
+ green: "bg-ods-success text-ods-text-on-accent",
818
+ purple: "bg-ods-flamingo-pink text-ods-text-on-accent",
819
+ // Solid and soft ODS palette fills (`BADGE_PALETTE`): tokens only, no hex.
820
+ cyanSoft: "bg-ods-flamingo-cyan-secondary text-ods-flamingo-cyan",
821
+ pinkSoft: "bg-ods-flamingo-pink-secondary text-ods-flamingo-pink",
822
+ openYellow: "bg-ods-open-yellow text-ods-text-on-accent",
823
+ red: "bg-ods-error text-ods-text-on-accent",
824
+ success: "bg-ods-success-secondary text-ods-success",
825
+ error: "bg-ods-error-secondary text-ods-error",
826
+ warning: "bg-ods-warning-secondary text-ods-warning",
827
+ default: "bg-ods-bg-surface text-ods-text-primary",
828
+ // Border-only variants (no background) - for task type badges
829
+ accentBorder: "border-2 border-ods-accent bg-transparent text-ods-accent",
830
+ errorBorder: "border-2 border-ods-error bg-transparent text-ods-error",
831
+ whiteBorder: "border-2 border-ods-text-primary bg-transparent text-ods-text-primary"
832
+ }
833
+ },
834
+ defaultVariants: {
835
+ variant: "card",
836
+ colorScheme: "default"
837
+ }
838
+ });
839
+ function genBadgeBgOpacity(gen) {
840
+ if (gen <= 1) return 10;
841
+ if (gen === 2) return 7;
842
+ return Math.max(4 - (gen - 3), 2);
843
+ }
844
+ function generationTierFromLabel(label) {
845
+ const m = /(\d+)/.exec(_nullishCoalesce(label, () => ( "")));
846
+ const n = m ? parseInt(m[1], 10) : 1;
847
+ return Number.isFinite(n) && n > 0 ? n : 1;
848
+ }
849
+ function StatusBadgeSkeleton({ variant, className }) {
850
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
851
+ _chunkXFRBEXQNcjs.UnifiedSkeleton,
852
+ {
853
+ as: "span",
854
+ className: _chunk65VVJSQZcjs.cn.call(void 0,
855
+ statusBadgeVariants({ variant, colorScheme: null }),
856
+ "box-content h-[1lh] w-12 border-transparent",
857
+ className
858
+ )
859
+ }
860
+ );
861
+ }
862
+ function StatusBadge({ text, variant, colorScheme, className, singleLine, gen, style, ...props }) {
863
+ const loading = _chunkXFRBEXQNcjs.useLoadingScope.call(void 0, );
864
+ if (loading) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatusBadgeSkeleton, { variant, className });
865
+ const genStyle = gen != null ? {
866
+ textTransform: "none",
867
+ color: "var(--ods-accent)",
868
+ backgroundColor: `color-mix(in srgb, var(--ods-accent) ${genBadgeBgOpacity(gen)}%, transparent)`
869
+ } : void 0;
870
+ const renderText = () => {
871
+ if (singleLine) return text;
872
+ if (variant === "button" && text.includes(" ")) {
873
+ const words = text.split(" ");
874
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex flex-col items-center justify-center gap-0 text-center", children: words.map((word, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "block", children: word }, index)) });
875
+ }
876
+ return text;
877
+ };
878
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
879
+ "span",
880
+ {
881
+ className: _chunk65VVJSQZcjs.cn.call(void 0, statusBadgeVariants({ variant, colorScheme: gen != null ? void 0 : colorScheme }), className),
882
+ style: genStyle ? { ...genStyle, ...style } : style,
883
+ ...props,
884
+ children: renderText()
885
+ }
886
+ );
887
+ }
888
+
889
+ // src/components/chat/utils/compact-card-skeleton.tsx
890
+
891
+ var DEFAULT_ROWS = [{ width: "w-2/5" }, { width: "w-11/12" }];
892
+ function CompactCardSkeleton({
893
+ slot = true,
894
+ slotClassName,
895
+ titleWidth = "w-3/5",
896
+ titleBadges = [],
897
+ rows = DEFAULT_ROWS,
898
+ trailingIcon = false,
899
+ className
900
+ }) {
901
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunk65VVJSQZcjs.cn.call(void 0, COMPACT_CARD_SKELETON_OUTER, className), "aria-hidden": true, children: [
902
+ slot && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.UnifiedSkeleton, { as: "span", className: _nullishCoalesce(slotClassName, () => ( COMPACT_CARD_SKELETON_IMAGE_SLOT)) }),
903
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: COMPACT_CARD_TEXT_COL, children: [
904
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: titleBadges.length > 0 ? COMPACT_CARD_TITLE_WRAP_ROW : COMPACT_CARD_TITLE_ROW, children: [
905
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { as: "span", type: "inherit", className: _chunk65VVJSQZcjs.cn.call(void 0, COMPACT_CARD_TITLE_TYPE, titleWidth) }),
906
+ titleBadges.map((width, i) => (
907
+ // The compact cards' title badges are `StatusBadge variant="button"` stamps: their own skeleton.
908
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatusBadgeSkeleton, { variant: "button", className: _chunk65VVJSQZcjs.cn.call(void 0, "shrink-0", width) }, i)
909
+ ))
910
+ ] }),
911
+ rows.map(
912
+ (row, i) => (_nullishCoalesce(row.lines, () => ( 1))) > 1 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { as: "span", type: "h6", lines: row.lines, className: row.width }, i) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunk65VVJSQZcjs.cn.call(void 0, COMPACT_CARD_META_ROW_BOX, row.after ? "gap-2" : void 0), children: [
913
+ row.width && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { as: "span", type: "h6", className: row.width }),
914
+ row.after
915
+ ] }, i)
916
+ )
917
+ ] }),
918
+ trailingIcon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_TRAILING_ICON, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ExternalLink, { className: "h-3.5 w-3.5" }) })
919
+ ] });
920
+ }
921
+ function ActivityRowSkeleton({
922
+ lead,
923
+ trailingWidths,
924
+ className
925
+ }) {
926
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunk65VVJSQZcjs.cn.call(void 0, "flex min-w-0 items-center gap-3", className), children: [
927
+ lead,
928
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.UnifiedSkeleton, { className: "h-3 w-2/3 flex-1 rounded" }),
929
+ trailingWidths.map((width, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.UnifiedSkeleton, { className: _chunk65VVJSQZcjs.cn.call(void 0, "h-3 shrink-0 rounded", width) }, i))
930
+ ] });
931
+ }
932
+
933
+ // src/components/chat/entity-cards/content-card-frame.tsx
934
+
935
+ var CONTENT_CARD_FRAME_CLASS = _chunk65VVJSQZcjs.cn.call(void 0,
936
+ "group isolate overflow-hidden rounded-2xl",
937
+ "border border-ods-border bg-transparent",
938
+ "transition-[border-color,box-shadow] duration-300 ease-out",
939
+ "hover:border-ods-accent hover:shadow-lg hover:shadow-ods-accent/[0.08]"
940
+ );
941
+ var CONTENT_CARD_SKELETON_FRAME_CLASS = "overflow-hidden rounded-2xl border border-ods-border bg-transparent";
942
+ function ContentCardFrame({ as: Tag = "article", className, children, ...rest }) {
943
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Tag, { className: _chunk65VVJSQZcjs.cn.call(void 0, CONTENT_CARD_FRAME_CLASS, Tag === "a" && "no-underline", className), ...rest, children });
944
+ }
945
+
946
+ // src/components/chat/entity-cards/entity-portrait-card.tsx
947
+
948
+
949
+ var MIN_WIDE_RATIO = 1.3;
950
+ var PORTRAIT_BODY = "flex h-full flex-col gap-6 p-6";
951
+ var PORTRAIT_MEDIA = "relative flex aspect-[1200/630] w-full shrink-0 items-center justify-center overflow-hidden rounded-sm";
952
+ var PORTRAIT_TITLE_ZONE = "flex h-[72px] shrink-0 flex-col justify-center gap-1.5";
953
+ var PORTRAIT_TITLE_LEADING = "leading-6";
954
+ var PORTRAIT_TITLE = _chunk65VVJSQZcjs.cn.call(void 0, "break-words text-ods-text-primary text-h4", PORTRAIT_TITLE_LEADING);
955
+ var PORTRAIT_FOOTER = "flex h-[60px] shrink-0 items-center";
956
+ var PORTRAIT_PERSON_ROW = "flex w-full min-w-0 items-center gap-3";
957
+ var PORTRAIT_PERSON_TEXT = "flex min-w-0 flex-col";
958
+ function EntityPortraitCard({
959
+ href,
960
+ target,
961
+ rel,
962
+ typeLabel,
963
+ imageUrl,
964
+ placeholderUrl,
965
+ imageAlt,
966
+ title,
967
+ titleClassName,
968
+ person,
969
+ priority,
970
+ className
971
+ }) {
972
+ const loading = _chunkXFRBEXQNcjs.useLoadingScope.call(void 0, );
973
+ const { src, onError: onMediaError } = useCoverImageFallback(imageUrl, placeholderUrl);
974
+ const [measured, setMeasured] = _react.useState.call(void 0, null);
975
+ const isWide = _optionalChain([measured, 'optionalAccess', _28 => _28.src]) === src ? measured.isWide : null;
976
+ const onMediaLoad = (e) => {
977
+ const img = e.currentTarget;
978
+ if (img.naturalWidth > 0 && img.naturalHeight > 0) {
979
+ setMeasured({ src, isWide: img.naturalWidth / img.naturalHeight >= MIN_WIDE_RATIO });
980
+ }
981
+ };
982
+ const edgeColor = _chunk3LW5TD54cjs.useImageEdgeColor.call(void 0, isWide === false ? src : null, "var(--color-bg-surface)");
983
+ if (loading) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EntityPortraitCardSkeleton, { typeLabel, className });
984
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV45KLJQPcjs.next_link_default, { href, target, rel, className: _chunk65VVJSQZcjs.cn.call(void 0, "block h-full", className), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Card, { className: _chunk65VVJSQZcjs.cn.call(void 0, CONTENT_CARD_FRAME_CLASS, PORTRAIT_BODY), children: [
985
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
986
+ "div",
987
+ {
988
+ className: _chunk65VVJSQZcjs.cn.call(void 0, PORTRAIT_MEDIA, "bg-ods-bg transition-colors duration-300"),
989
+ style: isWide === false ? { backgroundColor: edgeColor } : void 0,
990
+ children: src && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
991
+ _chunkE76ONBKFcjs.next_image_default,
992
+ {
993
+ src,
994
+ alt: imageAlt,
995
+ className: _chunk65VVJSQZcjs.cn.call(void 0, "h-full w-full", isWide === false ? "object-contain" : "object-cover"),
996
+ sizes: "(min-width: 800px) 400px, 100vw",
997
+ fill: true,
998
+ priority,
999
+ unoptimized: true,
1000
+ onLoad: onMediaLoad,
1001
+ onError: onMediaError
1002
+ }
1003
+ )
1004
+ }
1005
+ ),
1006
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: PORTRAIT_TITLE_ZONE, children: [
1007
+ typeLabel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1008
+ StatusBadge,
1009
+ {
1010
+ variant: "button",
1011
+ colorScheme: "accentBorder",
1012
+ singleLine: true,
1013
+ text: typeLabel,
1014
+ className: "self-start"
1015
+ }
1016
+ ),
1017
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: _chunk65VVJSQZcjs.cn.call(void 0, PORTRAIT_TITLE, typeLabel ? "line-clamp-2" : "line-clamp-3", titleClassName), children: title })
1018
+ ] }),
1019
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: PORTRAIT_FOOTER, children: person && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: PORTRAIT_PERSON_ROW, children: [
1020
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative h-12 w-12 shrink-0", children: [
1021
+ person.avatarUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1022
+ _chunkE76ONBKFcjs.next_image_default,
1023
+ {
1024
+ src: person.avatarUrl,
1025
+ alt: person.name,
1026
+ className: "h-12 w-12 rounded-full border border-ods-border bg-ods-bg object-cover",
1027
+ width: 48,
1028
+ height: 48,
1029
+ unoptimized: true
1030
+ }
1031
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-12 w-12 items-center justify-center rounded-full border border-ods-border bg-ods-bg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-ods-text-secondary text-h4", children: person.name.charAt(0).toUpperCase() }) }),
1032
+ person.iconOverlayUrl && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute -bottom-1 -right-1 flex h-6 w-6 items-center justify-center overflow-hidden rounded-full bg-ods-text-primary ring-1 ring-ods-bg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1033
+ _chunkE76ONBKFcjs.next_image_default,
1034
+ {
1035
+ src: person.iconOverlayUrl,
1036
+ alt: "",
1037
+ className: "h-full w-full object-cover",
1038
+ width: 24,
1039
+ height: 24,
1040
+ unoptimized: true
1041
+ }
1042
+ ) })
1043
+ ] }),
1044
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: PORTRAIT_PERSON_TEXT, children: [
1045
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate font-bold text-ods-text-primary text-h6", children: person.name }),
1046
+ person.subtitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate text-ods-text-secondary text-h6", children: person.subtitle })
1047
+ ] })
1048
+ ] }) })
1049
+ ] }) });
1050
+ }
1051
+ function EntityPortraitCardSkeleton({ typeLabel, className }) {
1052
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunk65VVJSQZcjs.cn.call(void 0, "block h-full", className), "aria-hidden": true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Card, { className: _chunk65VVJSQZcjs.cn.call(void 0, CONTENT_CARD_SKELETON_FRAME_CLASS, PORTRAIT_BODY), children: [
1053
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.UnifiedSkeleton, { className: _chunk65VVJSQZcjs.cn.call(void 0, PORTRAIT_MEDIA, "rounded-sm") }),
1054
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: PORTRAIT_TITLE_ZONE, children: [
1055
+ typeLabel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1056
+ StatusBadge,
1057
+ {
1058
+ variant: "button",
1059
+ colorScheme: "accentBorder",
1060
+ singleLine: true,
1061
+ text: typeLabel,
1062
+ className: "self-start"
1063
+ }
1064
+ ),
1065
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h4", lines: typeLabel ? 2 : 3, className: _chunk65VVJSQZcjs.cn.call(void 0, "w-full", PORTRAIT_TITLE_LEADING) })
1066
+ ] }),
1067
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: PORTRAIT_FOOTER, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: PORTRAIT_PERSON_ROW, children: [
1068
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.MediaSkeleton.Avatar, { size: "md", className: "shrink-0" }),
1069
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunk65VVJSQZcjs.cn.call(void 0, PORTRAIT_PERSON_TEXT, "gap-0"), children: [
1070
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h6", className: "w-32" }),
1071
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h6", className: "w-24" })
1072
+ ] })
1073
+ ] }) })
1074
+ ] }) });
1075
+ }
1076
+
1077
+ // src/components/chat/entity-cards/use-entity-card-link.ts
1078
+
1079
+
1080
+ // src/components/chat/utils/is-cross-origin-url.ts
1081
+ function isCrossOriginUrl(url) {
1082
+ if (!url) return false;
1083
+ if (url.startsWith("#") || url.startsWith("?")) return false;
1084
+ if (url.startsWith("/") && !url.startsWith("//")) return false;
1085
+ return true;
1086
+ }
1087
+
1088
+ // src/components/chat/utils/decide-new-tab.ts
1089
+ function decideNewTab(input) {
1090
+ const { href, targetPlatform, openIn, alwaysNewTab, runtimeMode, currentSource } = input;
1091
+ if (runtimeMode === "embed") return true;
1092
+ if (openIn === "new-tab") return true;
1093
+ if (alwaysNewTab === true) return true;
1094
+ if (openIn === "same-tab") return false;
1095
+ if (targetPlatform !== void 0 && targetPlatform !== null && currentSource) {
1096
+ return targetPlatform !== currentSource;
1097
+ }
1098
+ if (!href) return false;
1099
+ return isCrossOriginUrl(href);
1100
+ }
1101
+
1102
+ // src/components/chat/utils/nav-anchor-props.ts
1103
+ function isSameOriginAbsoluteHref(href) {
1104
+ if (typeof window === "undefined") return false;
1105
+ if (!/^https?:\/\//i.test(href)) return false;
1106
+ try {
1107
+ return new URL(href).origin === new URL(window.location.href).origin;
1108
+ } catch (e7) {
1109
+ return false;
1110
+ }
1111
+ }
1112
+ function computeIsNewTab(runtime, href, targetPlatform) {
1113
+ if (!href) return false;
1114
+ if (runtime.navigation.mode === "embed") return !isSameOriginAbsoluteHref(href);
1115
+ return _nullishCoalesce(_optionalChain([runtime, 'access', _29 => _29.navigation, 'access', _30 => _30.decideNewTab, 'optionalCall', _31 => _31({ href, targetPlatform })]), () => ( decideNewTab({
1116
+ href,
1117
+ targetPlatform,
1118
+ currentSource: _nullishCoalesce(runtime.source, () => ( ""))
1119
+ })));
1120
+ }
1121
+ function newTabAnchorAttrs(isNewTab) {
1122
+ return isNewTab ? { target: "_blank", rel: "noopener noreferrer" } : {};
1123
+ }
1124
+ function buildAnchorProps(href, isNewTab) {
1125
+ return href ? { href, ...newTabAnchorAttrs(isNewTab) } : void 0;
1126
+ }
1127
+
1128
+ // src/components/chat/entity-cards/use-entity-card-link.ts
1129
+ function useEntityCardLink({ href, targetPlatform, target, rel }) {
1130
+ const runtime = _chunkUJ7AXHRZcjs.useChatRuntime.call(void 0, );
1131
+ return _react.useMemo.call(void 0, () => {
1132
+ if (target !== void 0 || rel !== void 0) {
1133
+ const safeRel = _nullishCoalesce(rel, () => ( (target === "_blank" ? "noopener noreferrer" : void 0)));
1134
+ return { target, rel: safeRel };
1135
+ }
1136
+ const newTab = runtime ? computeIsNewTab(runtime, href, _nullishCoalesce(targetPlatform, () => ( null))) : false;
1137
+ return newTab ? { target: "_blank", rel: "noopener noreferrer" } : { target: void 0, rel: void 0 };
1138
+ }, [target, rel, href, targetPlatform, runtime]);
1139
+ }
1140
+
1141
+ // src/components/chat/entity-cards/use-entity-card-placeholder.ts
1142
+ function useEntityCardPlaceholder({
1143
+ title,
1144
+ placeholderUrl,
1145
+ siteName = "",
1146
+ aspect = "wide"
1147
+ }) {
1148
+ const derived = _chunk3LW5TD54cjs.useOgPlaceholderUrl.call(void 0, { title, siteName, aspect });
1149
+ return placeholderUrl !== void 0 ? placeholderUrl : derived;
1150
+ }
1151
+
1152
+ // src/components/chat/entity-cards/case-study-card.tsx
1153
+
1154
+ var CASE_STUDY_RESULT_STACK = "flex h-full flex-col gap-5 p-6";
1155
+ var CASE_STUDY_RESULT_METRIC_BOX = "flex h-[112px] shrink-0 flex-col justify-start gap-1 overflow-hidden";
1156
+ var CASE_STUDY_RESULT_FOOTER_BOX = "mt-auto flex h-[60px] shrink-0 items-center justify-between gap-3 border-t border-ods-border pt-4";
1157
+ var CASE_STUDY_DEFAULT_BODY = "flex flex-col gap-6 p-6";
1158
+ var CASE_STUDY_COVER = `relative ${_chunkXFRBEXQNcjs.MEDIA_ASPECT.og} w-full shrink-0 overflow-hidden rounded-sm`;
1159
+ var CASE_STUDY_TITLE_ZONE = "flex h-[72px] shrink-0 items-center";
1160
+ var CASE_STUDY_PERSON_ZONE = "flex h-[60px] shrink-0 items-center";
1161
+ var CASE_STUDY_PERSON_ROW = "flex w-full min-w-0 items-center gap-3";
1162
+ var CASE_STUDY_PERSON_TEXT = "min-w-0 flex-1";
1163
+ var CASE_STUDY_MENU_FRAME = "group/card group flex min-w-0 flex-col gap-[var(--spacing-system-sf)] rounded-xl border border-ods-border bg-ods-bg p-[var(--spacing-system-mf)] text-ods-text-primary transition-colors hover:bg-ods-bg-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ods-accent";
1164
+ var CASE_STUDY_MENU_SKELETON_FRAME = "flex min-w-0 flex-col gap-[var(--spacing-system-sf)] rounded-xl border border-ods-border bg-ods-bg p-[var(--spacing-system-mf)]";
1165
+ var CASE_STUDY_MENU_MEDIA = `relative block ${_chunkXFRBEXQNcjs.MEDIA_ASPECT.video} w-full shrink-0 overflow-hidden rounded-md`;
1166
+ var CASE_STUDY_MENU_MSP_ROW = "flex items-center gap-[var(--spacing-system-xsf)] text-ods-text-secondary text-h6";
1167
+ var MSP_ICON_PX = 20;
1168
+ var MSP_ICON_CLASS = `${_chunkXFRBEXQNcjs.ICON_SIZE.md} shrink-0 rounded`;
1169
+ var CASE_STUDY_TYPE_LABEL = "Case Study";
1170
+ function headlineMetric(study) {
1171
+ const metric = _optionalChain([study, 'access', _32 => _32.metrics, 'optionalAccess', _33 => _33[0]]);
1172
+ return _optionalChain([metric, 'optionalAccess', _34 => _34.value]) && metric.label ? metric : null;
1173
+ }
1174
+ function CaseStudyPersonRow({ study }) {
1175
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: CASE_STUDY_PERSON_ZONE, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: CASE_STUDY_PERSON_ROW, children: [
1176
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative h-12 w-12 shrink-0", children: [
1177
+ _optionalChain([study, 'access', _35 => _35.user, 'optionalAccess', _36 => _36.avatar_url]) ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1178
+ _chunkE76ONBKFcjs.next_image_default,
1179
+ {
1180
+ src: study.user.avatar_url,
1181
+ alt: _optionalChain([study, 'access', _37 => _37.user, 'optionalAccess', _38 => _38.full_name]) || "User",
1182
+ className: "h-12 w-12 rounded-full border border-ods-border bg-ods-bg object-cover",
1183
+ width: 48,
1184
+ height: 48,
1185
+ unoptimized: true
1186
+ }
1187
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-12 w-12 items-center justify-center rounded-full border border-ods-border bg-ods-bg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-ods-text-secondary text-h4", children: (_optionalChain([study, 'access', _39 => _39.user, 'optionalAccess', _40 => _40.full_name]) || "A").charAt(0).toUpperCase() }) }),
1188
+ _optionalChain([study, 'access', _41 => _41.msp, 'optionalAccess', _42 => _42.icon_url]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute -bottom-1 -right-1 flex h-6 w-6 items-center justify-center overflow-hidden rounded-full bg-ods-text-primary ring-1 ring-ods-bg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1189
+ _chunkE76ONBKFcjs.next_image_default,
1190
+ {
1191
+ src: study.msp.icon_url,
1192
+ alt: study.msp.name || "MSP",
1193
+ className: "h-full w-full object-cover",
1194
+ width: 24,
1195
+ height: 24,
1196
+ unoptimized: true
1197
+ }
1198
+ ) })
1199
+ ] }),
1200
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: CASE_STUDY_PERSON_TEXT, children: [
1201
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "truncate text-ods-text-primary text-h6", children: [
1202
+ _optionalChain([study, 'access', _43 => _43.user, 'optionalAccess', _44 => _44.full_name]) || "Anonymous",
1203
+ _optionalChain([study, 'access', _45 => _45.msp, 'optionalAccess', _46 => _46.name]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-ods-text-secondary", children: [
1204
+ " \u2022 ",
1205
+ study.msp.name
1206
+ ] })
1207
+ ] }),
1208
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "truncate text-ods-text-secondary text-h6", children: _optionalChain([study, 'access', _47 => _47.user, 'optionalAccess', _48 => _48.job_title]) || "\xA0" })
1209
+ ] })
1210
+ ] }) });
1211
+ }
1212
+ function CaseStudyPersonRowSkeleton() {
1213
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: CASE_STUDY_PERSON_ZONE, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: CASE_STUDY_PERSON_ROW, children: [
1214
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.MediaSkeleton.Avatar, { size: "md", className: "shrink-0" }),
1215
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: CASE_STUDY_PERSON_TEXT, children: [
1216
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h6", className: "w-2/3" }),
1217
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h6", className: "w-1/2" })
1218
+ ] })
1219
+ ] }) });
1220
+ }
1221
+ function CaseStudyCardSkeleton({
1222
+ size = "default",
1223
+ showTypeBadge = true,
1224
+ className
1225
+ }) {
1226
+ if (size === "portrait") {
1227
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EntityPortraitCardSkeleton, { typeLabel: showTypeBadge ? CASE_STUDY_TYPE_LABEL : void 0, className });
1228
+ }
1229
+ if (size === "result") {
1230
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunk65VVJSQZcjs.cn.call(void 0, CONTENT_CARD_SKELETON_FRAME_CLASS, CASE_STUDY_RESULT_STACK, className), "aria-hidden": true, children: [
1231
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CaseStudyPersonRowSkeleton, {}),
1232
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: CASE_STUDY_RESULT_METRIC_BOX, "data-testid": "case-study-result-skeleton-metric", children: [
1233
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h1", className: "w-1/3" }),
1234
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h4", lines: 2, className: "w-3/4" })
1235
+ ] }),
1236
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: CASE_STUDY_RESULT_FOOTER_BOX, children: [
1237
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h6", lines: 2, className: "w-2/3" }),
1238
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "shrink-0 text-ods-accent text-h6", children: "Read" })
1239
+ ] })
1240
+ ] });
1241
+ }
1242
+ if (size === "menu") {
1243
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunk65VVJSQZcjs.cn.call(void 0, CASE_STUDY_MENU_SKELETON_FRAME, className), "aria-hidden": true, children: [
1244
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.UnifiedSkeleton, { className: CASE_STUDY_MENU_MEDIA }),
1245
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: CASE_STUDY_MENU_MSP_ROW, children: [
1246
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.UnifiedSkeleton, { className: MSP_ICON_CLASS }),
1247
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h6", className: "w-28" })
1248
+ ] }),
1249
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h6", lines: 2, className: "w-full" }),
1250
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h6", className: "w-3/4" }),
1251
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h6", className: "mt-auto w-28" })
1252
+ ] });
1253
+ }
1254
+ if (size === "sm") {
1255
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CompactCardSkeleton, { rows: [{ width: "w-1/2" }, { width: "w-11/12" }], className });
1256
+ }
1257
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunk65VVJSQZcjs.cn.call(void 0, "block h-full", className), "aria-hidden": true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Card, { className: _chunk65VVJSQZcjs.cn.call(void 0, CONTENT_CARD_SKELETON_FRAME_CLASS, CASE_STUDY_DEFAULT_BODY), children: [
1258
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.UnifiedSkeleton, { className: _chunk65VVJSQZcjs.cn.call(void 0, CASE_STUDY_COVER, "rounded-sm") }),
1259
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: CASE_STUDY_TITLE_ZONE, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXFRBEXQNcjs.TextLineSkeleton, { type: "h4", lines: 3, className: "w-full" }) }),
1260
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CaseStudyPersonRowSkeleton, {})
1261
+ ] }) });
1262
+ }
1263
+ function caseStudyHighlight(study) {
1264
+ if (study.highlight_video_url) {
1265
+ return { url: study.highlight_video_url, posterUrl: _nullishCoalesce(study.highlight_video_thumbnail, () => ( null)) };
1266
+ }
1267
+ const bite = (_nullishCoalesce(study.video_bites, () => ( []))).filter((candidate) => candidate.featured === true && candidate.url).sort(sortBitesByFeaturedAtDesc)[0];
1268
+ return bite ? { url: bite.url, posterUrl: _nullishCoalesce(bite.thumbnail_url, () => ( null)) } : null;
1269
+ }
1270
+ function CaseStudyCard(props) {
1271
+ const inScope = _chunkXFRBEXQNcjs.useLoadingScope.call(void 0, );
1272
+ if (inScope || props.loading) {
1273
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CaseStudyCardSkeleton, { size: props.size, showTypeBadge: props.showTypeBadge, className: props.className });
1274
+ }
1275
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LoadedCaseStudyCard, { ...props });
1276
+ }
1277
+ function LoadedCaseStudyCard({
1278
+ study,
1279
+ href,
1280
+ target: targetProp,
1281
+ rel: relProp,
1282
+ targetPlatform,
1283
+ placeholderUrl: placeholderUrlProp,
1284
+ size = "default",
1285
+ showTypeBadge = true,
1286
+ accentClassName = "text-ods-accent",
1287
+ mediaMounted,
1288
+ onNavigate,
1289
+ className
1290
+ }) {
1291
+ const [hovered, setHovered] = _react.useState.call(void 0, false);
1292
+ const { target, rel } = useEntityCardLink({
1293
+ href,
1294
+ targetPlatform,
1295
+ target: targetProp,
1296
+ rel: relProp
1297
+ });
1298
+ const placeholderUrl = useEntityCardPlaceholder({
1299
+ title: study.title,
1300
+ placeholderUrl: placeholderUrlProp,
1301
+ aspect: size === "sm" ? "square" : "wide"
1302
+ });
1303
+ const coverImage = study.featured_image || placeholderUrl || null;
1304
+ if (size === "sm") {
1305
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkV45KLJQPcjs.next_link_default, { href, target, rel, className: _chunk65VVJSQZcjs.cn.call(void 0, COMPACT_CARD_OUTER, className), children: [
1306
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_IMAGE_SLOT, children: coverImage ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1307
+ _chunkE76ONBKFcjs.next_image_default,
1308
+ {
1309
+ src: coverImage,
1310
+ alt: `${_optionalChain([study, 'access', _49 => _49.msp, 'optionalAccess', _50 => _50.name]) || study.title} cover`,
1311
+ className: "object-contain",
1312
+ fill: true,
1313
+ sizes: "56px",
1314
+ unoptimized: true,
1315
+ onError: hideOnError
1316
+ }
1317
+ ) : null }),
1318
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: COMPACT_CARD_TEXT_COL, children: [
1319
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_TITLE_ROW, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_TITLE, children: study.title }) }),
1320
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_SUBTITLE, children: [_optionalChain([study, 'access', _51 => _51.msp, 'optionalAccess', _52 => _52.name]), _optionalChain([study, 'access', _53 => _53.user, 'optionalAccess', _54 => _54.full_name])].filter(Boolean).join(" \xB7 ") || "Case study" }) }),
1321
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_SUMMARY, children: study.summary || COMPACT_CARD_ROW_FILLER }) })
1322
+ ] })
1323
+ ] });
1324
+ }
1325
+ if (size === "menu") {
1326
+ const preview = caseStudyHighlight(study);
1327
+ const videoUrl = _nullishCoalesce(_optionalChain([preview, 'optionalAccess', _55 => _55.url]), () => ( null));
1328
+ const hasAnyVideo = !!(videoUrl || study.main_video_url);
1329
+ const poster = study.main_video_thumbnail || study.featured_image || _optionalChain([preview, 'optionalAccess', _56 => _56.posterUrl]) || null;
1330
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1331
+ _chunkV45KLJQPcjs.next_link_default,
1332
+ {
1333
+ href,
1334
+ target,
1335
+ rel,
1336
+ onClick: onNavigate,
1337
+ onPointerEnter: () => setHovered(true),
1338
+ onPointerLeave: () => setHovered(false),
1339
+ onFocus: () => setHovered(true),
1340
+ onBlur: () => setHovered(false),
1341
+ className: _chunk65VVJSQZcjs.cn.call(void 0, CASE_STUDY_MENU_FRAME, className),
1342
+ children: [
1343
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunk65VVJSQZcjs.cn.call(void 0, "pointer-events-none bg-ods-bg", CASE_STUDY_MENU_MEDIA), children: videoUrl ? (
1344
+ // The shared hover surface, filled the way the walkthrough card fills
1345
+ // its own 16:9 slot (`cover`): an upright cut is cropped to the slot,
1346
+ // never letterboxed. Sound on hover, muted when the browser blocks it.
1347
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1348
+ VideoHoverPreviewSurface,
1349
+ {
1350
+ url: videoUrl,
1351
+ posterUrl: poster,
1352
+ active: hovered,
1353
+ playerMounted: mediaMounted,
1354
+ fit: "cover",
1355
+ posterSizes: "360px"
1356
+ }
1357
+ )
1358
+ ) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1359
+ (_nullishCoalesce(poster, () => ( placeholderUrl))) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1360
+ _chunkE76ONBKFcjs.next_image_default,
1361
+ {
1362
+ src: _nullishCoalesce(_nullishCoalesce(poster, () => ( placeholderUrl)), () => ( "")),
1363
+ alt: "",
1364
+ className: "object-cover",
1365
+ fill: true,
1366
+ sizes: "360px",
1367
+ unoptimized: true,
1368
+ onError: hideOnError
1369
+ }
1370
+ ),
1371
+ hasAnyVideo && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSETFUCZAcjs.CardHoverPlay, { size: "md" })
1372
+ ] }) }),
1373
+ _optionalChain([study, 'access', _57 => _57.msp, 'optionalAccess', _58 => _58.name]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: CASE_STUDY_MENU_MSP_ROW, children: [
1374
+ study.msp.icon_url && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1375
+ EntityIcon,
1376
+ {
1377
+ icon: { url: study.msp.icon_url },
1378
+ size: MSP_ICON_PX,
1379
+ className: _chunk65VVJSQZcjs.cn.call(void 0, MSP_ICON_CLASS, "object-contain")
1380
+ }
1381
+ ),
1382
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "min-w-0 truncate", children: study.msp.name })
1383
+ ] }),
1384
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "line-clamp-2 text-h6", children: study.title }),
1385
+ _optionalChain([study, 'access', _59 => _59.user, 'optionalAccess', _60 => _60.full_name]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate text-ods-text-muted text-h6", children: study.user.job_title ? `${study.user.full_name}, ${study.user.job_title}` : study.user.full_name }),
1386
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mt-auto text-ods-accent text-h6", children: hasAnyVideo ? "Watch the story" : "Read the story" })
1387
+ ]
1388
+ }
1389
+ );
1390
+ }
1391
+ if (size === "result") {
1392
+ const metric = headlineMetric(study);
1393
+ if (!metric) return null;
1394
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV45KLJQPcjs.next_link_default, { href, target, rel, className: _chunk65VVJSQZcjs.cn.call(void 0, "block h-full", className), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Card, { className: _chunk65VVJSQZcjs.cn.call(void 0, CONTENT_CARD_FRAME_CLASS, CASE_STUDY_RESULT_STACK), children: [
1395
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CaseStudyPersonRow, { study }),
1396
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: CASE_STUDY_RESULT_METRIC_BOX, "data-testid": "case-study-metric", children: [
1397
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunk65VVJSQZcjs.cn.call(void 0, "truncate text-h1", accentClassName), children: metric.value }),
1398
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "line-clamp-2 text-ods-text-secondary text-h4", children: metric.label })
1399
+ ] }),
1400
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: CASE_STUDY_RESULT_FOOTER_BOX, children: [
1401
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "line-clamp-2 min-w-0 text-ods-text-secondary text-h6", children: study.title }),
1402
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunk65VVJSQZcjs.cn.call(void 0, "shrink-0 text-h6", accentClassName), children: "Read" })
1403
+ ] })
1404
+ ] }) });
1405
+ }
1406
+ if (size === "portrait") {
1407
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1408
+ EntityPortraitCard,
1409
+ {
1410
+ href,
1411
+ target,
1412
+ rel,
1413
+ typeLabel: showTypeBadge ? CASE_STUDY_TYPE_LABEL : void 0,
1414
+ imageUrl: study.featured_image,
1415
+ placeholderUrl,
1416
+ imageAlt: _optionalChain([study, 'access', _61 => _61.msp, 'optionalAccess', _62 => _62.name]) || study.title,
1417
+ title: study.title,
1418
+ person: {
1419
+ name: _optionalChain([study, 'access', _63 => _63.user, 'optionalAccess', _64 => _64.full_name]) || "Anonymous",
1420
+ avatarUrl: _optionalChain([study, 'access', _65 => _65.user, 'optionalAccess', _66 => _66.avatar_url]),
1421
+ subtitle: _nullishCoalesce(_optionalChain([study, 'access', _67 => _67.msp, 'optionalAccess', _68 => _68.name]), () => ( null)),
1422
+ iconOverlayUrl: _nullishCoalesce(_optionalChain([study, 'access', _69 => _69.msp, 'optionalAccess', _70 => _70.icon_url]), () => ( null))
1423
+ },
1424
+ className
1425
+ }
1426
+ );
1427
+ }
1428
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV45KLJQPcjs.next_link_default, { href, target, rel, className: _chunk65VVJSQZcjs.cn.call(void 0, "block h-full", className), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Card, { className: _chunk65VVJSQZcjs.cn.call(void 0, CONTENT_CARD_FRAME_CLASS, CASE_STUDY_DEFAULT_BODY), children: [
1429
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunk65VVJSQZcjs.cn.call(void 0, CASE_STUDY_COVER, "bg-ods-bg"), children: coverImage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1430
+ _chunkE76ONBKFcjs.next_image_default,
1431
+ {
1432
+ src: coverImage,
1433
+ alt: _optionalChain([study, 'access', _71 => _71.msp, 'optionalAccess', _72 => _72.name]) || study.title,
1434
+ className: "h-full w-full object-cover",
1435
+ sizes: "(min-width: 1545px) 515px, (min-width: 1280px) 33vw, (min-width: 800px) 50vw, 100vw",
1436
+ fill: true,
1437
+ unoptimized: true,
1438
+ onError: hideOnError
1439
+ }
1440
+ ) }),
1441
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: CASE_STUDY_TITLE_ZONE, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "line-clamp-3 break-words text-ods-text-primary text-h4", children: study.title }) }),
1442
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CaseStudyPersonRow, { study })
1443
+ ] }) });
1444
+ }
1445
+
1446
+
1447
+
1448
+
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+
1456
+
1457
+
1458
+
1459
+
1460
+
1461
+
1462
+
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+
1482
+
1483
+
1484
+
1485
+
1486
+
1487
+
1488
+
1489
+
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
1503
+
1504
+ exports.Card = Card; exports.CardHeader = CardHeader; exports.CardTitle = CardTitle; exports.CardDescription = CardDescription; exports.CardContent = CardContent; exports.CardFooter = CardFooter; exports.CardHorizontal = CardHorizontal; exports.extractYouTubeId = extractYouTubeId; exports.Video = Video; exports.VideoSkeleton = VideoSkeleton; exports.statusBadgeVariants = statusBadgeVariants; exports.genBadgeBgOpacity = genBadgeBgOpacity; exports.generationTierFromLabel = generationTierFromLabel; exports.StatusBadgeSkeleton = StatusBadgeSkeleton; exports.StatusBadge = StatusBadge; exports.EntityIcon = EntityIcon; exports.isCrossOriginUrl = isCrossOriginUrl; exports.decideNewTab = decideNewTab; exports.isSameOriginAbsoluteHref = isSameOriginAbsoluteHref; exports.computeIsNewTab = computeIsNewTab; exports.newTabAnchorAttrs = newTabAnchorAttrs; exports.buildAnchorProps = buildAnchorProps; exports.CONTENT_CARD_FRAME_CLASS = CONTENT_CARD_FRAME_CLASS; exports.CONTENT_CARD_SKELETON_FRAME_CLASS = CONTENT_CARD_SKELETON_FRAME_CLASS; exports.ContentCardFrame = ContentCardFrame; exports.useCoverImageFallback = useCoverImageFallback; exports.hideOnError = hideOnError; exports.EntityPortraitCard = EntityPortraitCard; exports.EntityPortraitCardSkeleton = EntityPortraitCardSkeleton; exports.DEFAULT_VIDEO_BITES_TITLE = DEFAULT_VIDEO_BITES_TITLE; exports.toStripProfile = toStripProfile; exports.sortBitesByCreatedAtDesc = sortBitesByCreatedAtDesc; exports.sortBitesByFeaturedAtDesc = sortBitesByFeaturedAtDesc; exports.programItemToStripProfile = programItemToStripProfile; exports.VideoHoverPreviewSurface = VideoHoverPreviewSurface; exports.UNSAFE_URL_CHARS = UNSAFE_URL_CHARS; exports.COMPACT_CARD_OUTER = COMPACT_CARD_OUTER; exports.COMPACT_CARD_OUTER_STATIC = COMPACT_CARD_OUTER_STATIC; exports.COMPACT_CARD_SKELETON_OUTER = COMPACT_CARD_SKELETON_OUTER; exports.COMPACT_CARD_IMAGE_SLOT = COMPACT_CARD_IMAGE_SLOT; exports.COMPACT_CARD_SKELETON_IMAGE_SLOT = COMPACT_CARD_SKELETON_IMAGE_SLOT; exports.COMPACT_CARD_ICON_SLOT = COMPACT_CARD_ICON_SLOT; exports.COMPACT_CARD_TEXT_COL = COMPACT_CARD_TEXT_COL; exports.COMPACT_CARD_TITLE_ROW = COMPACT_CARD_TITLE_ROW; exports.COMPACT_CARD_META_ROW_BOX = COMPACT_CARD_META_ROW_BOX; exports.COMPACT_CARD_TITLE = COMPACT_CARD_TITLE; exports.COMPACT_CARD_SUBTITLE = COMPACT_CARD_SUBTITLE; exports.COMPACT_CARD_SUMMARY = COMPACT_CARD_SUMMARY; exports.COMPACT_CARD_META_ROW = COMPACT_CARD_META_ROW; exports.COMPACT_CARD_ROW_FILLER = COMPACT_CARD_ROW_FILLER; exports.safeHref = safeHref; exports.CompactCardSkeleton = CompactCardSkeleton; exports.ActivityRowSkeleton = ActivityRowSkeleton; exports.useEntityCardLink = useEntityCardLink; exports.useEntityCardPlaceholder = useEntityCardPlaceholder; exports.CaseStudyCardSkeleton = CaseStudyCardSkeleton; exports.CaseStudyCard = CaseStudyCard;