@arbidocs/blocks 0.3.118 → 0.3.120

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.
package/dist/index.cjs CHANGED
@@ -1,16 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var zustand = require('zustand');
4
- var middleware = require('zustand/middleware');
3
+ var chunkAHWIZJ4M_cjs = require('./chunk-AHWIZJ4M.cjs');
5
4
  var react$1 = require('react');
6
- var lucideReact = require('lucide-react');
7
5
  var react = require('@arbidocs/react');
8
6
  var jsxRuntime = require('react/jsx-runtime');
9
7
  var reactQuery = require('@tanstack/react-query');
10
8
  var agGridReact = require('ag-grid-react');
11
9
  var agGridCommunity = require('ag-grid-community');
10
+ var lucideReact = require('lucide-react');
12
11
  var reactRouterDom = require('react-router-dom');
13
12
  var puck = require('@measured/puck');
13
+ var zustand = require('zustand');
14
+ var middleware = require('zustand/middleware');
14
15
 
15
16
  // src/prompts.ts
16
17
  function matterToContext(m) {
@@ -193,380 +194,23 @@ Lead with why the firm is the right choice, reference relevant experience at a t
193
194
  ];
194
195
  return { prompts, WORKFLOW_ACTIONS };
195
196
  }
196
-
197
- // src/theme/tokens.ts
198
- var THEME_STYLE_ID = "arbi-theme-vars";
199
- var TRIPLET_RE = /^-?\d+(?:\.\d+)?\s+-?\d+(?:\.\d+)?%\s+-?\d+(?:\.\d+)?%$/;
200
- function parseRgb(color) {
201
- if (color.startsWith("#")) {
202
- let hex = color.slice(1);
203
- if (hex.length === 3) {
204
- hex = hex.split("").map((ch) => ch + ch).join("");
205
- }
206
- if (hex.length === 6 && /^[0-9a-fA-F]{6}$/.test(hex)) {
207
- return {
208
- r: parseInt(hex.slice(0, 2), 16),
209
- g: parseInt(hex.slice(2, 4), 16),
210
- b: parseInt(hex.slice(4, 6), 16)
211
- };
212
- }
197
+ var ConnectionContext = react$1.createContext(null);
198
+ var WORKSPACE_STORAGE_PREFIX = "arbi:selectedWorkspace";
199
+ var workspaceStorageKey = (apiUrl) => `${WORKSPACE_STORAGE_PREFIX}:${apiUrl || "demo"}`;
200
+ function readPersistedWorkspace(apiUrl) {
201
+ try {
202
+ return window.localStorage.getItem(workspaceStorageKey(apiUrl));
203
+ } catch {
213
204
  return null;
214
205
  }
215
- const m = color.match(/^rgba?\(\s*([\d.]+)[\s,]+([\d.]+)[\s,]+([\d.]+)/i);
216
- if (m) return { r: Number(m[1]), g: Number(m[2]), b: Number(m[3]) };
217
- return null;
218
- }
219
- function rgbToHslTriplet(r, g, b) {
220
- const rn = r / 255;
221
- const gn = g / 255;
222
- const bn = b / 255;
223
- const max = Math.max(rn, gn, bn);
224
- const min = Math.min(rn, gn, bn);
225
- const l = (max + min) / 2;
226
- const d = max - min;
227
- let h = 0;
228
- let s = 0;
229
- if (d !== 0) {
230
- s = d / (1 - Math.abs(2 * l - 1));
231
- switch (max) {
232
- case rn:
233
- h = 60 * ((gn - bn) / d % 6);
234
- break;
235
- case gn:
236
- h = 60 * ((bn - rn) / d + 2);
237
- break;
238
- default:
239
- h = 60 * ((rn - gn) / d + 4);
240
- break;
241
- }
242
- }
243
- if (h < 0) h += 360;
244
- return `${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
245
- }
246
- function toHslTriplet(color) {
247
- const c = color.trim();
248
- if (TRIPLET_RE.test(c)) return c;
249
- const rgb = parseRgb(c);
250
- if (!rgb) return c;
251
- return rgbToHslTriplet(rgb.r, rgb.g, rgb.b);
252
- }
253
- function renderTripletBlock(colors) {
254
- return Object.entries(colors).map(([key, value]) => ` --${key}: ${toHslTriplet(value)};`).join("\n");
255
- }
256
- function emitCssVars(theme, dark) {
257
- if (typeof document === "undefined") return;
258
- const meta = [
259
- ` --font-display: ${theme.fonts.display};`,
260
- ` --font-sans: ${theme.fonts.sans};`,
261
- ` --radius: ${theme.radius}rem;`
262
- ].join("\n");
263
- let css = `:root {
264
- ${renderTripletBlock(theme.colors)}
265
- ${meta}
266
- }`;
267
- if (dark) {
268
- css += `
269
- :root.dark {
270
- ${renderTripletBlock(dark)}
271
- }`;
272
- }
273
- let style = document.getElementById(THEME_STYLE_ID);
274
- if (!style) {
275
- style = document.createElement("style");
276
- style.id = THEME_STYLE_ID;
277
- document.head.appendChild(style);
278
- }
279
- style.textContent = css;
280
- }
281
- function removeCssVars() {
282
- if (typeof document === "undefined") return;
283
- document.getElementById(THEME_STYLE_ID)?.remove();
284
- }
285
- function normalizeOptions(optionsOrRoot) {
286
- if (typeof HTMLElement !== "undefined" && optionsOrRoot instanceof HTMLElement) {
287
- return { root: optionsOrRoot };
288
- }
289
- return optionsOrRoot;
290
- }
291
- function applyThemeVars(theme, optionsOrRoot = {}) {
292
- const { mode = "flat", dark, root = document.documentElement } = normalizeOptions(optionsOrRoot);
293
- if (mode === "cssVars") {
294
- emitCssVars(theme, dark);
295
- return;
296
- }
297
- for (const [key, value] of Object.entries(theme.colors)) {
298
- root.style.setProperty(`--color-${key}`, value);
299
- }
300
- root.style.setProperty("--font-display", theme.fonts.display);
301
- root.style.setProperty("--font-sans", theme.fonts.sans);
302
- root.style.setProperty("--radius", `${theme.radius}rem`);
303
- }
304
- function clearThemeVars(theme, optionsOrRoot = {}) {
305
- const { mode = "flat", root = document.documentElement } = normalizeOptions(optionsOrRoot);
306
- if (mode === "cssVars") {
307
- removeCssVars();
308
- return;
309
- }
310
- for (const key of Object.keys(theme.colors)) {
311
- root.style.removeProperty(`--color-${key}`);
312
- }
313
- root.style.removeProperty("--font-display");
314
- root.style.removeProperty("--font-sans");
315
- root.style.removeProperty("--radius");
316
206
  }
317
- function createThemeStore(config) {
318
- const { defaultTheme, presets, storageKey } = config;
319
- const useStore = zustand.create()(
320
- middleware.persist(
321
- (set, get) => ({
322
- ...defaultTheme,
323
- activePresetId: presets[0]?.id ?? null,
324
- setColor: (key, value) => set((s) => ({ colors: { ...s.colors, [key]: value }, activePresetId: null })),
325
- setFont: (which, value) => set((s) => ({ fonts: { ...s.fonts, [which]: value }, activePresetId: null })),
326
- setRadius: (radius) => set({ radius, activePresetId: null }),
327
- applyPreset: (presetId) => {
328
- const preset = presets.find((p) => p.id === presetId);
329
- if (!preset) return;
330
- set({
331
- colors: { ...preset.tokens.colors },
332
- fonts: { ...preset.tokens.fonts },
333
- radius: preset.tokens.radius,
334
- activePresetId: presetId
335
- });
336
- },
337
- reset: () => set({
338
- colors: { ...defaultTheme.colors },
339
- fonts: { ...defaultTheme.fonts },
340
- radius: defaultTheme.radius,
341
- activePresetId: presets[0]?.id ?? null
342
- }),
343
- snapshot: () => {
344
- const { colors, fonts, radius } = get();
345
- return { colors, fonts, radius };
346
- }
347
- }),
348
- { name: storageKey }
349
- )
350
- );
351
- return { ...config, useStore };
352
- }
353
- function applyStoredTheme(bundle) {
354
- const { colors, fonts, radius } = bundle.useStore.getState();
355
- applyThemeVars({ colors, fonts, radius }, { mode: bundle.mode, dark: bundle.darkColors });
356
- }
357
- function ThemeEditor({
358
- bundle,
359
- variant = "panel",
360
- preview,
361
- onSave,
362
- testIdPrefix = "theme"
363
- }) {
364
- const { useStore, tokens, presets, groupLabels, mode, darkColors } = bundle;
365
- const colors = useStore((s) => s.colors);
366
- const fonts = useStore((s) => s.fonts);
367
- const radius = useStore((s) => s.radius);
368
- const activePresetId = useStore((s) => s.activePresetId);
369
- const setColor = useStore((s) => s.setColor);
370
- const setFont = useStore((s) => s.setFont);
371
- const setRadius = useStore((s) => s.setRadius);
372
- const applyPreset = useStore((s) => s.applyPreset);
373
- const reset = useStore((s) => s.reset);
374
- const [saving, setSaving] = react$1.useState(false);
375
- const [savedVia, setSavedVia] = react$1.useState(null);
376
- react$1.useEffect(() => {
377
- applyThemeVars({ colors, fonts, radius }, { mode, dark: darkColors });
378
- }, [colors, fonts, radius, mode, darkColors]);
379
- const tid2 = (suffix) => `${testIdPrefix}-${suffix}`;
380
- const groups = [...new Set(tokens.map((t) => t.group))];
381
- const save = async () => {
382
- if (!onSave) return;
383
- setSaving(true);
384
- const via = await onSave();
385
- setSavedVia(typeof via === "string" ? via : "saved");
386
- setSaving(false);
387
- };
388
- const Presets = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
389
- presets.map((p) => /* @__PURE__ */ jsxRuntime.jsx(
390
- "button",
391
- {
392
- type: "button",
393
- onClick: () => applyPreset(p.id),
394
- className: `rounded-full border px-3 py-1 text-xs font-medium transition-colors ${activePresetId === p.id ? "border-primary bg-primary text-primary-foreground" : "border-border text-foreground hover:border-primary"}`,
395
- "data-testid": tid2(`preset-${p.id}`),
396
- children: p.label
397
- },
398
- p.id
399
- )),
400
- /* @__PURE__ */ jsxRuntime.jsxs(
401
- "button",
402
- {
403
- type: "button",
404
- onClick: reset,
405
- className: "ml-auto inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground hover:text-foreground",
406
- "data-testid": tid2("reset"),
407
- children: [
408
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "size-3" }),
409
- " Reset"
410
- ]
411
- }
412
- )
413
- ] });
414
- const colorRow = (k, label) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
415
- /* @__PURE__ */ jsxRuntime.jsx(
416
- "input",
417
- {
418
- type: "color",
419
- value: colors[k] ?? "#000000",
420
- onChange: (e) => setColor(k, e.target.value),
421
- className: "size-9 shrink-0 cursor-pointer rounded-md border border-border bg-transparent",
422
- "aria-label": label,
423
- "data-testid": tid2(`color-${k}`)
424
- }
425
- ),
426
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
427
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-muted-foreground", children: label }),
428
- /* @__PURE__ */ jsxRuntime.jsx(
429
- react.Input,
430
- {
431
- value: colors[k] ?? "",
432
- onChange: (e) => setColor(k, e.target.value),
433
- className: "bg-card placeholder:text-muted-foreground/70 focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring/50 h-7 font-mono text-xs",
434
- "data-testid": tid2(`hex-${k}`)
435
- }
436
- )
437
- ] })
438
- ] }, k);
439
- const Typography = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
440
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
441
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-muted-foreground", children: "Display font stack" }),
442
- /* @__PURE__ */ jsxRuntime.jsx(
443
- react.Input,
444
- {
445
- value: fonts.display,
446
- onChange: (e) => setFont("display", e.target.value),
447
- className: "bg-card placeholder:text-muted-foreground/70 focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring/50 mt-1 font-mono text-xs",
448
- "data-testid": tid2("font-display")
449
- }
450
- )
451
- ] }),
452
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
453
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-muted-foreground", children: "Body font stack" }),
454
- /* @__PURE__ */ jsxRuntime.jsx(
455
- react.Input,
456
- {
457
- value: fonts.sans,
458
- onChange: (e) => setFont("sans", e.target.value),
459
- className: "bg-card placeholder:text-muted-foreground/70 focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring/50 mt-1 font-mono text-xs",
460
- "data-testid": tid2("font-sans")
461
- }
462
- )
463
- ] }),
464
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
465
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "block text-xs text-muted-foreground", children: [
466
- "Base radius \u2014 ",
467
- radius,
468
- "rem"
469
- ] }),
470
- /* @__PURE__ */ jsxRuntime.jsx(
471
- "input",
472
- {
473
- type: "range",
474
- min: 0,
475
- max: 1.5,
476
- step: 0.125,
477
- value: radius,
478
- onChange: (e) => setRadius(Number(e.target.value)),
479
- className: "mt-2 w-full accent-[color:var(--color-primary)]",
480
- "data-testid": tid2("radius")
481
- }
482
- )
483
- ] })
484
- ] });
485
- const Preview = /* @__PURE__ */ jsxRuntime.jsxs(react.Card, { variant: "elevated", className: "rounded-xl", "data-testid": tid2("preview"), children: [
486
- /* @__PURE__ */ jsxRuntime.jsx(react.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(react.CardTitle, { className: "text-base", children: "Live preview" }) }),
487
- /* @__PURE__ */ jsxRuntime.jsxs(react.CardContent, { className: "space-y-3", children: [
488
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-[var(--radius)] bg-primary p-4 text-primary-foreground", children: [
489
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-display text-lg font-semibold", children: preview?.title ?? "Preview" }),
490
- preview?.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-80", children: preview.subtitle })
491
- ] }),
492
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-6 gap-1.5", children: tokens.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
493
- "div",
494
- {
495
- title: t.label,
496
- className: "aspect-square rounded-md border border-border",
497
- style: { background: `var(--color-${t.key})` }
498
- },
499
- t.key
500
- )) }),
501
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-[var(--radius)] border border-border bg-[color:var(--color-ai-accent-soft,var(--color-accent))] p-3", children: [
502
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-[color:var(--color-ai-accent,var(--color-primary))]", children: "AI action surface" }),
503
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Themed by the AI-kit accent tokens." })
504
- ] })
505
- ] })
506
- ] });
507
- const SaveBar = onSave && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex items-center gap-3", children: [
508
- /* @__PURE__ */ jsxRuntime.jsxs(
509
- "button",
510
- {
511
- type: "button",
512
- onClick: () => void save(),
513
- disabled: saving,
514
- className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:opacity-90 disabled:opacity-60",
515
- "data-testid": tid2("save"),
516
- children: [
517
- savedVia ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Save, { className: "size-4" }),
518
- saving ? "Saving\u2026" : savedVia ? "Saved" : "Save theme"
519
- ]
520
- }
521
- ),
522
- savedVia && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", "data-testid": tid2("via"), children: [
523
- "stored via ",
524
- savedVia
525
- ] })
526
- ] });
527
- if (variant === "drawer") {
528
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-y-auto bg-card p-5", "data-testid": testIdPrefix, children: [
529
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-display text-lg font-semibold text-foreground", children: "Theme" }) }),
530
- Presets,
531
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-5 mb-2 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Colours" }),
532
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: tokens.map((t) => colorRow(t.key, t.label)) }),
533
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-6 mb-2 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Typography & shape" }),
534
- Typography,
535
- SaveBar
536
- ] });
207
+ function persistWorkspace(apiUrl, id) {
208
+ try {
209
+ if (id) window.localStorage.setItem(workspaceStorageKey(apiUrl), id);
210
+ else window.localStorage.removeItem(workspaceStorageKey(apiUrl));
211
+ } catch {
537
212
  }
538
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 lg:grid-cols-[1fr_320px]", "data-testid": testIdPrefix, children: [
539
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
540
- /* @__PURE__ */ jsxRuntime.jsxs(react.Card, { variant: "elevated", className: "rounded-xl", children: [
541
- /* @__PURE__ */ jsxRuntime.jsx(react.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(react.CardTitle, { className: "flex items-center gap-2 text-base", children: [
542
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Palette, { className: "size-4 text-[color:var(--color-primary)]" }),
543
- " Presets"
544
- ] }) }),
545
- /* @__PURE__ */ jsxRuntime.jsx(react.CardContent, { children: Presets })
546
- ] }),
547
- groups.map((group) => /* @__PURE__ */ jsxRuntime.jsxs(
548
- react.Card,
549
- {
550
- variant: "elevated",
551
- className: "rounded-xl",
552
- "data-testid": tid2(`group-${group}`),
553
- children: [
554
- /* @__PURE__ */ jsxRuntime.jsx(react.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(react.CardTitle, { className: "text-base", children: groupLabels[group] ?? group }) }),
555
- /* @__PURE__ */ jsxRuntime.jsx(react.CardContent, { className: "grid gap-3 sm:grid-cols-2", children: tokens.filter((t) => t.group === group).map((t) => colorRow(t.key, t.label)) })
556
- ]
557
- },
558
- group
559
- )),
560
- /* @__PURE__ */ jsxRuntime.jsxs(react.Card, { variant: "elevated", className: "rounded-xl", children: [
561
- /* @__PURE__ */ jsxRuntime.jsx(react.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(react.CardTitle, { className: "text-base", children: "Typography & shape" }) }),
562
- /* @__PURE__ */ jsxRuntime.jsx(react.CardContent, { children: Typography })
563
- ] }),
564
- SaveBar
565
- ] }),
566
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:sticky lg:top-4 lg:self-start", children: Preview })
567
- ] });
568
213
  }
569
- var ConnectionContext = react$1.createContext(null);
570
214
  function ConnectionProvider({
571
215
  config,
572
216
  children
@@ -599,10 +243,12 @@ function ConnectionProvider({
599
243
  await arbi.login(email, password);
600
244
  const workspaces = await arbi.workspaces.list();
601
245
  if (workspaces?.length) {
602
- const preferred = config.workspaceId;
246
+ const persisted = readPersistedWorkspace(config.apiUrl);
247
+ const preferred = persisted ?? config.workspaceId;
603
248
  const target = (preferred ? workspaces.find((w) => w.external_id === preferred) : void 0) ?? workspaces[0];
604
249
  await arbi.selectWorkspace(target.external_id);
605
250
  setWorkspaceId(target.external_id);
251
+ persistWorkspace(config.apiUrl, target.external_id);
606
252
  }
607
253
  let resolved = { name: email.split("@")[0], email };
608
254
  try {
@@ -629,7 +275,7 @@ function ConnectionProvider({
629
275
  setStatus("error");
630
276
  }
631
277
  },
632
- [arbi, enterDemo, isLiveConfigured, config.workspaceId]
278
+ [arbi, enterDemo, isLiveConfigured, config.workspaceId, config.apiUrl]
633
279
  );
634
280
  const logout = react$1.useCallback(() => {
635
281
  if (mode === "live") {
@@ -637,10 +283,25 @@ function ConnectionProvider({
637
283
  }
638
284
  setUser(null);
639
285
  setWorkspaceId(null);
286
+ persistWorkspace(config.apiUrl, null);
640
287
  setStatus("disconnected");
641
288
  setError(null);
642
- }, [arbi, mode]);
643
- const setWorkspace = react$1.useCallback((id) => setWorkspaceId(id), []);
289
+ }, [arbi, mode, config.apiUrl]);
290
+ const setWorkspace = react$1.useCallback(
291
+ async (id) => {
292
+ if (mode === "live" && arbi.isLoggedIn) {
293
+ await arbi.selectWorkspace(id);
294
+ }
295
+ setWorkspaceId(id);
296
+ persistWorkspace(config.apiUrl, id);
297
+ },
298
+ [arbi, mode, config.apiUrl]
299
+ );
300
+ const ensureWorkspaceOpen = react$1.useCallback(async () => {
301
+ if (mode !== "live" || !arbi.isLoggedIn) return;
302
+ const id = workspaceId ?? readPersistedWorkspace(config.apiUrl) ?? config.workspaceId;
303
+ if (id) await arbi.selectWorkspace(id);
304
+ }, [arbi, mode, workspaceId, config.apiUrl, config.workspaceId]);
644
305
  const value = react$1.useMemo(
645
306
  () => ({
646
307
  mode,
@@ -655,7 +316,8 @@ function ConnectionProvider({
655
316
  login,
656
317
  enterDemo,
657
318
  logout,
658
- setWorkspace
319
+ setWorkspace,
320
+ ensureWorkspaceOpen
659
321
  }),
660
322
  [
661
323
  mode,
@@ -670,7 +332,8 @@ function ConnectionProvider({
670
332
  login,
671
333
  enterDemo,
672
334
  logout,
673
- setWorkspace
335
+ setWorkspace,
336
+ ensureWorkspaceOpen
674
337
  ]
675
338
  );
676
339
  return /* @__PURE__ */ jsxRuntime.jsx(ConnectionContext.Provider, { value, children });
@@ -715,100 +378,6 @@ function useSemanticSearch() {
715
378
  const { docIds } = useWorkspaceDocs();
716
379
  return react.useSemanticSearch(docIds);
717
380
  }
718
-
719
- // src/lib/testid.ts
720
- function tid(...parts) {
721
- return parts.filter((p) => p !== void 0 && p !== false && p !== "").map(
722
- (p) => String(p).trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "")
723
- ).join("-");
724
- }
725
-
726
- // src/lib/format.ts
727
- function gbp(value, compact = false) {
728
- return new Intl.NumberFormat("en-GB", {
729
- style: "currency",
730
- currency: "GBP",
731
- maximumFractionDigits: compact && Math.abs(value) >= 1e3 ? 1 : 0,
732
- notation: compact ? "compact" : "standard"
733
- }).format(value);
734
- }
735
- function initials(name) {
736
- const parts = name.trim().split(/\s+/);
737
- if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
738
- return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
739
- }
740
- function parseIso(iso) {
741
- const dateOnly = /^\d{4}-\d{2}-\d{2}$/.test(iso);
742
- const d = new Date(dateOnly ? `${iso}T00:00:00` : iso);
743
- if (Number.isNaN(d.getTime())) throw new Error(`Invalid ISO date: ${iso}`);
744
- return d;
745
- }
746
- function fmtDate(iso) {
747
- try {
748
- return new Intl.DateTimeFormat("en-GB", {
749
- day: "numeric",
750
- month: "short",
751
- year: "numeric"
752
- }).format(parseIso(iso));
753
- } catch {
754
- return iso;
755
- }
756
- }
757
- function fmtDateTime(iso) {
758
- try {
759
- return new Intl.DateTimeFormat("en-GB", {
760
- day: "numeric",
761
- month: "short",
762
- year: "numeric",
763
- hour: "2-digit",
764
- minute: "2-digit",
765
- hour12: false
766
- }).format(parseIso(iso));
767
- } catch {
768
- return iso;
769
- }
770
- }
771
- var RELATIVE_UNITS = [
772
- ["year", 31536e3],
773
- ["month", 2592e3],
774
- ["week", 604800],
775
- ["day", 86400],
776
- ["hour", 3600],
777
- ["minute", 60],
778
- ["second", 1]
779
- ];
780
- function fromNow(iso, from = /* @__PURE__ */ new Date()) {
781
- try {
782
- const diffSeconds = (parseIso(iso).getTime() - from.getTime()) / 1e3;
783
- const abs = Math.abs(diffSeconds);
784
- const rtf = new Intl.RelativeTimeFormat("en-GB", { numeric: "always" });
785
- for (const [unit, secs] of RELATIVE_UNITS) {
786
- if (abs >= secs || unit === "second") {
787
- const value = Math.round(diffSeconds / secs);
788
- return rtf.format(value, unit);
789
- }
790
- }
791
- return rtf.format(0, "second");
792
- } catch {
793
- return iso;
794
- }
795
- }
796
- function daysUntil(iso, from = /* @__PURE__ */ new Date()) {
797
- try {
798
- const target = parseIso(iso);
799
- const a = Date.UTC(target.getFullYear(), target.getMonth(), target.getDate());
800
- const b = Date.UTC(from.getFullYear(), from.getMonth(), from.getDate());
801
- return Math.round((a - b) / 864e5);
802
- } catch {
803
- return 0;
804
- }
805
- }
806
- function hrs(n) {
807
- return `${n.toFixed(1)}h`;
808
- }
809
- function pct(n) {
810
- return `${Math.round(n)}%`;
811
- }
812
381
  function EmptyState({
813
382
  icon: Icon,
814
383
  title,
@@ -846,9 +415,9 @@ function DataTable({
846
415
  className
847
416
  }) {
848
417
  if (rows.length === 0) {
849
- return /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { title: emptyTitle, description: emptyDescription, testId: tid(area, "empty") });
418
+ return /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { title: emptyTitle, description: emptyDescription, testId: chunkAHWIZJ4M_cjs.tid(area, "empty") });
850
419
  }
851
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: react.cn("rounded-xl border border-border bg-card", className), children: /* @__PURE__ */ jsxRuntime.jsxs(react.Table, { "data-testid": tid(area, "table"), children: [
420
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: react.cn("rounded-xl border border-border bg-card", className), children: /* @__PURE__ */ jsxRuntime.jsxs(react.Table, { "data-testid": chunkAHWIZJ4M_cjs.tid(area, "table"), children: [
852
421
  /* @__PURE__ */ jsxRuntime.jsx(react.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(react.TableRow, { className: "hover:bg-transparent", children: columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx(
853
422
  react.TableHead,
854
423
  {
@@ -862,7 +431,7 @@ function DataTable({
862
431
  return /* @__PURE__ */ jsxRuntime.jsx(
863
432
  react.TableRow,
864
433
  {
865
- "data-testid": tid(area, "row", id),
434
+ "data-testid": chunkAHWIZJ4M_cjs.tid(area, "row", id),
866
435
  onClick: onRowClick ? () => onRowClick(row) : void 0,
867
436
  className: react.cn(onRowClick && "cursor-pointer"),
868
437
  children: columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -1305,6 +874,84 @@ function GridView({
1305
874
  }
1306
875
  ) });
1307
876
  }
877
+ function UploadDropzone({
878
+ onFiles,
879
+ accept,
880
+ multiple = true,
881
+ disabled = false,
882
+ uploading = false,
883
+ title = "Drag files here",
884
+ description = "or click to browse",
885
+ hint,
886
+ uploadingLabel = "Uploading\u2026",
887
+ icon: Icon = lucideReact.UploadCloud,
888
+ testId,
889
+ className
890
+ }) {
891
+ const inputRef = react$1.useRef(null);
892
+ const [dragOver, setDragOver] = react$1.useState(false);
893
+ const inert = disabled || uploading;
894
+ const pick = (files) => {
895
+ if (!files?.length) return;
896
+ onFiles(Array.from(files));
897
+ };
898
+ const onDrop = (e) => {
899
+ e.preventDefault();
900
+ setDragOver(false);
901
+ if (inert) return;
902
+ pick(e.dataTransfer.files);
903
+ };
904
+ const onDragOver = (e) => {
905
+ e.preventDefault();
906
+ if (!inert) setDragOver(true);
907
+ };
908
+ return /* @__PURE__ */ jsxRuntime.jsxs(
909
+ "button",
910
+ {
911
+ type: "button",
912
+ onClick: () => !inert && inputRef.current?.click(),
913
+ onDrop,
914
+ onDragOver,
915
+ onDragLeave: () => setDragOver(false),
916
+ disabled: inert,
917
+ "data-testid": testId,
918
+ className: react.cn(
919
+ "flex w-full flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed border-border bg-muted/30 px-6 py-12 text-center transition-colors",
920
+ "hover:border-primary/50 hover:bg-muted/50",
921
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
922
+ dragOver && "border-primary bg-primary/5",
923
+ inert && "cursor-not-allowed opacity-60 hover:border-border hover:bg-muted/30",
924
+ className
925
+ ),
926
+ children: [
927
+ /* @__PURE__ */ jsxRuntime.jsx(
928
+ "input",
929
+ {
930
+ ref: inputRef,
931
+ type: "file",
932
+ accept,
933
+ multiple,
934
+ className: "hidden",
935
+ onChange: (e) => {
936
+ pick(e.target.files);
937
+ if (inputRef.current) inputRef.current.value = "";
938
+ },
939
+ "data-testid": testId ? `${testId}-input` : void 0
940
+ }
941
+ ),
942
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-12 items-center justify-center rounded-full bg-primary/10 text-primary", children: uploading ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-6 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "size-6" }) }),
943
+ uploading ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-foreground", children: uploadingLabel }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
944
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm font-medium text-foreground", children: [
945
+ title,
946
+ " ",
947
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: description })
948
+ ] }),
949
+ hint && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: hint })
950
+ ] })
951
+ ]
952
+ }
953
+ );
954
+ }
1308
955
  function PageHeader({
1309
956
  title,
1310
957
  eyebrow,
@@ -1329,48 +976,6 @@ function PageHeader({
1329
976
  }
1330
977
  );
1331
978
  }
1332
- function SectionHeading({
1333
- eyebrow,
1334
- title,
1335
- lead,
1336
- align = "left",
1337
- className,
1338
- invert,
1339
- eyebrowClassName
1340
- }) {
1341
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: react.cn("max-w-3xl", align === "center" && "mx-auto text-center", className), children: [
1342
- eyebrow && /* @__PURE__ */ jsxRuntime.jsx(
1343
- "p",
1344
- {
1345
- className: react.cn(
1346
- "mb-3 text-xs font-semibold uppercase tracking-wider",
1347
- eyebrowClassName ?? (invert ? "text-background/60" : "text-muted-foreground")
1348
- ),
1349
- children: eyebrow
1350
- }
1351
- ),
1352
- /* @__PURE__ */ jsxRuntime.jsx(
1353
- "h2",
1354
- {
1355
- className: react.cn(
1356
- "font-display text-3xl font-semibold tracking-tight text-balance sm:text-4xl",
1357
- invert ? "text-background" : "text-foreground"
1358
- ),
1359
- children: title
1360
- }
1361
- ),
1362
- lead && /* @__PURE__ */ jsxRuntime.jsx(
1363
- "p",
1364
- {
1365
- className: react.cn(
1366
- "mt-4 text-lg leading-relaxed",
1367
- invert ? "text-background/70" : "text-muted-foreground"
1368
- ),
1369
- children: lead
1370
- }
1371
- )
1372
- ] });
1373
- }
1374
979
  function Toolbar({
1375
980
  search,
1376
981
  onSearch,
@@ -1451,870 +1056,103 @@ function MetricCard({
1451
1056
  hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: hint })
1452
1057
  ] })
1453
1058
  ] });
1454
- }
1455
- var ASSET_REF_PREFIX = "asset:";
1456
- function asAssetRef(docId) {
1457
- return `${ASSET_REF_PREFIX}${docId}`;
1458
- }
1459
- function assetRefId(src) {
1460
- return src.slice(ASSET_REF_PREFIX.length);
1461
- }
1462
- var AssetResolverContext = react$1.createContext(false);
1463
- function AssetResolverProvider({ children }) {
1464
- return /* @__PURE__ */ jsxRuntime.jsx(AssetResolverContext.Provider, { value: true, children });
1465
- }
1466
- function useAssetResolverActive() {
1467
- return react$1.useContext(AssetResolverContext);
1468
- }
1469
- function isAssetRef(src) {
1470
- return !!src && src.startsWith(ASSET_REF_PREFIX);
1471
- }
1472
- function useAssetImage(docId) {
1473
- const arbi = react.useArbi();
1474
- const { data: thumbs } = react.useThumbnails([docId]);
1475
- const thumb = thumbs?.[docId];
1476
- const { data: objectUrl } = reactQuery.useQuery({
1477
- queryKey: ["arbi", "asset-image", docId],
1478
- queryFn: async () => {
1479
- const res = await arbi.documents.download(docId);
1480
- const blob = await res.blob();
1481
- return URL.createObjectURL(blob);
1482
- },
1483
- // Only download when the thumbnail is genuinely absent (not merely loading).
1484
- enabled: !!docId && thumbs != null && !thumb && arbi.hasWorkspace,
1485
- staleTime: 10 * 6e4
1486
- });
1487
- react$1.useEffect(() => {
1488
- return () => {
1489
- if (objectUrl) URL.revokeObjectURL(objectUrl);
1490
- };
1491
- }, [objectUrl]);
1492
- return thumb ?? objectUrl;
1493
- }
1494
- function AssetThumb({
1495
- docId,
1496
- alt,
1497
- className,
1498
- testId
1499
- }) {
1500
- const src = useAssetImage(docId);
1501
- return /* @__PURE__ */ jsxRuntime.jsx("img", { src: src ?? void 0, alt: alt ?? "", className, "data-testid": testId });
1502
- }
1503
- var ASPECT = {
1504
- "16:9": "aspect-video",
1505
- "4:3": "aspect-[4/3]",
1506
- "1:1": "aspect-square",
1507
- "21:9": "aspect-[21/9]",
1508
- "4:5": "aspect-[4/5]"
1509
- };
1510
- var ROUNDED = {
1511
- none: "rounded-none",
1512
- md: "rounded-md",
1513
- lg: "rounded-xl",
1514
- full: "rounded-full"
1515
- };
1516
- function BlockImage({
1517
- src,
1518
- alt = "",
1519
- aspect = "16:9",
1520
- rounded = "lg",
1521
- framed,
1522
- className,
1523
- testId
1524
- }) {
1525
- const shape = react.cn(
1526
- ASPECT[aspect] ?? ASPECT["16:9"],
1527
- ROUNDED[rounded] ?? ROUNDED.lg,
1528
- framed && "ring-1 ring-border shadow-xl"
1529
- );
1530
- const canResolve = useAssetResolverActive();
1531
- if (canResolve && isAssetRef(src)) {
1532
- return /* @__PURE__ */ jsxRuntime.jsx(
1533
- AssetThumb,
1534
- {
1535
- docId: assetRefId(src),
1536
- alt,
1537
- className: react.cn("w-full object-cover", shape, className),
1538
- testId
1539
- }
1540
- );
1541
- }
1542
- if (src && !isAssetRef(src)) {
1543
- return /* @__PURE__ */ jsxRuntime.jsx(
1544
- "img",
1545
- {
1546
- src,
1547
- alt,
1548
- className: react.cn("w-full object-cover", shape, className),
1549
- "data-testid": testId
1550
- }
1551
- );
1552
- }
1553
- return /* @__PURE__ */ jsxRuntime.jsx(
1554
- "div",
1555
- {
1556
- className: react.cn(
1557
- "flex w-full items-center justify-center overflow-hidden border border-border",
1558
- "bg-gradient-to-br from-muted via-card to-accent text-muted-foreground",
1559
- shape,
1560
- className
1561
- ),
1562
- "data-testid": testId,
1563
- "aria-label": alt || "Image placeholder",
1564
- role: "img",
1565
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ImageIcon, { className: "size-8 opacity-60" })
1566
- }
1567
- );
1568
- }
1569
- var TONE_SURFACE = {
1570
- default: "bg-background text-foreground",
1571
- muted: "bg-muted text-foreground",
1572
- ink: "bg-foreground text-background"
1573
- };
1574
- function renderTitle(title, emphasis) {
1575
- if (!emphasis || !title.includes(emphasis)) return title;
1576
- const parts = title.split(emphasis);
1577
- return parts.map((part, i) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1578
- part,
1579
- i < parts.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: emphasis })
1580
- ] }, i));
1581
- }
1582
- function Hero({
1583
- eyebrow,
1584
- title,
1585
- emphasis,
1586
- subtitle,
1587
- primaryCta,
1588
- secondaryCta,
1589
- align = "left",
1590
- tone = "default",
1591
- imageUrl,
1592
- backgroundImage,
1593
- overlay = true,
1594
- eyebrowClassName,
1595
- testId
1596
- }) {
1597
- const onDark = Boolean(backgroundImage) || tone === "ink";
1598
- const subtle = onDark ? "text-background/70" : "text-muted-foreground";
1599
- const eyebrowClass = eyebrowClassName ?? (onDark ? "text-background/60" : "text-muted-foreground");
1600
- const centered = align === "center" || Boolean(backgroundImage);
1601
- const heading = renderTitle(title, emphasis);
1602
- const copy = /* @__PURE__ */ jsxRuntime.jsxs(
1603
- "div",
1604
- {
1605
- className: react.cn(
1606
- "max-w-2xl",
1607
- centered && "mx-auto text-center",
1608
- backgroundImage && "text-background"
1609
- ),
1610
- children: [
1611
- eyebrow && /* @__PURE__ */ jsxRuntime.jsx("p", { className: react.cn("mb-4 text-sm font-semibold uppercase tracking-wider", eyebrowClass), children: eyebrow }),
1612
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl font-semibold tracking-tight text-balance sm:text-5xl", children: heading }),
1613
- subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: react.cn("mt-6 text-lg leading-relaxed", subtle), children: subtitle }),
1614
- (primaryCta?.label || secondaryCta?.label) && /* @__PURE__ */ jsxRuntime.jsxs(
1615
- "div",
1616
- {
1617
- className: react.cn("mt-8 flex flex-col gap-3 sm:flex-row", centered && "sm:justify-center"),
1618
- children: [
1619
- primaryCta?.label && /* @__PURE__ */ jsxRuntime.jsx(react.Button, { asChild: true, size: "lg", children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: primaryCta.href || "#", children: [
1620
- primaryCta.label,
1621
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "size-4" })
1622
- ] }) }),
1623
- secondaryCta?.label && /* @__PURE__ */ jsxRuntime.jsx(react.Button, { asChild: true, size: "lg", variant: "outline", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: secondaryCta.href || "#", children: secondaryCta.label }) })
1624
- ]
1625
- }
1626
- )
1627
- ]
1628
- }
1629
- );
1630
- if (backgroundImage) {
1631
- const bgStyle = {
1632
- backgroundImage: `url("${backgroundImage}")`,
1633
- backgroundSize: "cover",
1634
- backgroundPosition: "center"
1635
- };
1636
- return /* @__PURE__ */ jsxRuntime.jsxs(
1637
- "section",
1638
- {
1639
- className: "relative isolate overflow-hidden",
1640
- style: bgStyle,
1641
- "data-testid": testId,
1642
- "data-bg": testId && `${testId}-bg`,
1643
- children: [
1644
- overlay && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-black/55", "aria-hidden": true }),
1645
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative mx-auto max-w-7xl px-5 py-28 lg:px-8 lg:py-36", children: copy })
1646
- ]
1647
- }
1648
- );
1649
- }
1650
- return /* @__PURE__ */ jsxRuntime.jsx("section", { className: react.cn(TONE_SURFACE[tone] ?? TONE_SURFACE.default), "data-testid": testId, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-7xl px-5 py-20 lg:px-8 lg:py-28", children: centered ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-12", children: [
1651
- copy,
1652
- imageUrl && /* @__PURE__ */ jsxRuntime.jsx(
1653
- BlockImage,
1654
- {
1655
- src: imageUrl,
1656
- aspect: "16:9",
1657
- rounded: "lg",
1658
- className: "w-full max-w-4xl",
1659
- testId: testId && `${testId}-image`
1660
- }
1661
- )
1662
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid items-center gap-12 lg:grid-cols-2", children: [
1663
- copy,
1664
- /* @__PURE__ */ jsxRuntime.jsx(
1665
- BlockImage,
1666
- {
1667
- src: imageUrl,
1668
- aspect: "4:5",
1669
- rounded: "lg",
1670
- testId: testId && `${testId}-image`
1671
- }
1672
- )
1673
- ] }) }) });
1674
- }
1675
- var COLS = {
1676
- "2": "sm:grid-cols-2",
1677
- "3": "sm:grid-cols-2 lg:grid-cols-3"
1678
- };
1679
- function FeatureGrid({ columns = "3", items, testId }) {
1680
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: react.cn("grid gap-5", COLS[columns] ?? COLS["3"]), "data-testid": testId, children: (items ?? []).map((item, i) => {
1681
- const Icon = item.icon;
1682
- return /* @__PURE__ */ jsxRuntime.jsxs(
1683
- react.Card,
1684
- {
1685
- variant: "outline",
1686
- className: "h-full p-6",
1687
- "data-testid": testId && `${testId}-item-${i}`,
1688
- children: [
1689
- Icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-4 inline-flex size-10 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "size-5" }) }),
1690
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold tracking-tight", children: item.title }),
1691
- item.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm leading-relaxed text-muted-foreground", children: item.description })
1692
- ]
1693
- },
1694
- i
1695
- );
1696
- }) });
1697
- }
1698
- var GRID = {
1699
- 1: "grid-cols-1",
1700
- 2: "grid-cols-2",
1701
- 3: "grid-cols-2 sm:grid-cols-3",
1702
- 4: "grid-cols-2 lg:grid-cols-4"
1703
- };
1704
- function StatGroup({ items, testId }) {
1705
- const list = items ?? [];
1706
- const cols = GRID[Math.min(list.length, 4)] ?? GRID[4];
1707
- return /* @__PURE__ */ jsxRuntime.jsx("dl", { className: react.cn("grid gap-8", cols), "data-testid": testId, children: list.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", "data-testid": testId && `${testId}-item-${i}`, children: [
1708
- /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "sr-only", children: item.label }),
1709
- /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "text-4xl font-semibold tracking-tight sm:text-5xl", children: item.value }),
1710
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: item.label })
1711
- ] }, i)) });
1712
- }
1713
- function Testimonial({ quote, author, role, avatarUrl, testId }) {
1714
- return /* @__PURE__ */ jsxRuntime.jsxs(react.Card, { variant: "outline", className: "mx-auto max-w-3xl p-8 text-center", "data-testid": testId, children: [
1715
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Quote, { className: "mx-auto size-8 text-primary/40", "aria-hidden": true }),
1716
- /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: "mt-4 text-xl font-medium leading-relaxed text-balance", children: quote }),
1717
- (author || avatarUrl) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex items-center justify-center gap-3", children: [
1718
- (avatarUrl || author) && /* @__PURE__ */ jsxRuntime.jsxs(react.Avatar, { children: [
1719
- avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(react.AvatarImage, { src: avatarUrl, alt: author ?? "" }),
1720
- /* @__PURE__ */ jsxRuntime.jsx(react.AvatarFallback, { children: initials(author || "?") })
1721
- ] }),
1722
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-left", children: [
1723
- author && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold", children: author }),
1724
- role && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: role })
1725
- ] })
1726
- ] })
1727
- ] });
1728
- }
1729
- var TONE_SURFACE2 = {
1730
- default: "bg-primary text-primary-foreground",
1731
- muted: "bg-muted text-foreground",
1732
- ink: "bg-foreground text-background"
1733
- };
1734
- function CTABanner({
1735
- title,
1736
- subtitle,
1737
- cta,
1738
- tone = "default",
1739
- backgroundImage,
1740
- overlay = true,
1741
- testId
1742
- }) {
1743
- const onImage = Boolean(backgroundImage);
1744
- const subtle = onImage ? "text-white/80" : tone === "default" ? "text-primary-foreground/80" : tone === "ink" ? "text-background/70" : "text-muted-foreground";
1745
- const bgStyle = backgroundImage ? {
1746
- backgroundImage: `url("${backgroundImage}")`,
1747
- backgroundSize: "cover",
1748
- backgroundPosition: "center"
1749
- } : void 0;
1750
- return /* @__PURE__ */ jsxRuntime.jsxs(
1751
- "div",
1752
- {
1753
- className: react.cn(
1754
- "relative isolate overflow-hidden rounded-2xl px-8 py-14 text-center",
1755
- onImage ? "text-white" : TONE_SURFACE2[tone] ?? TONE_SURFACE2.default
1756
- ),
1757
- style: bgStyle,
1758
- "data-testid": testId,
1759
- children: [
1760
- onImage && overlay && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-black/55", "aria-hidden": true }),
1761
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1762
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl font-semibold tracking-tight text-balance sm:text-4xl", children: title }),
1763
- subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: react.cn("mx-auto mt-4 max-w-2xl text-lg", subtle), children: subtitle }),
1764
- cta?.label && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8", children: /* @__PURE__ */ jsxRuntime.jsx(
1765
- react.Button,
1766
- {
1767
- asChild: true,
1768
- size: "lg",
1769
- variant: tone === "default" && !onImage ? "secondary" : "default",
1770
- children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: cta.href || "#", children: [
1771
- cta.label,
1772
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "size-4" })
1773
- ] })
1774
- }
1775
- ) })
1776
- ] })
1777
- ]
1778
- }
1779
- );
1780
- }
1781
- function LogoCloud({ items, testId }) {
1782
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center justify-center gap-4", "data-testid": testId, children: (items ?? []).map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(
1783
- "span",
1784
- {
1785
- className: "rounded-md border border-border bg-muted px-5 py-2.5 text-sm font-semibold uppercase tracking-wide text-muted-foreground",
1786
- "data-testid": testId && `${testId}-item-${i}`,
1787
- children: item.label
1788
- },
1789
- i
1790
- )) });
1791
- }
1792
- function FAQ({ items, testId }) {
1793
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-3xl divide-y divide-border", "data-testid": testId, children: (items ?? []).map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "group py-4", "data-testid": testId && `${testId}-item-${i}`, children: [
1794
- /* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "flex cursor-pointer list-none items-center justify-between gap-4 text-left text-base font-medium", children: [
1795
- item.question,
1796
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-180" })
1797
- ] }),
1798
- item.answer && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-3 text-sm leading-relaxed text-muted-foreground", children: item.answer })
1799
- ] }, i)) });
1800
- }
1801
- function RichTextBlock({ content, testId }) {
1802
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-3xl", "data-testid": testId, children: /* @__PURE__ */ jsxRuntime.jsx(react.AiMarkdown, { children: content ?? "" }) });
1803
- }
1804
- var STYLES = {
1805
- info: { wrap: "border-primary/30 bg-primary/5", icon: "text-primary", Icon: lucideReact.Info },
1806
- success: { wrap: "border-success/30 bg-success/10", icon: "text-success", Icon: lucideReact.CheckCircle2 },
1807
- warning: { wrap: "border-warning/40 bg-warning/10", icon: "text-warning", Icon: lucideReact.AlertTriangle },
1808
- danger: {
1809
- wrap: "border-destructive/30 bg-destructive/10",
1810
- icon: "text-destructive",
1811
- Icon: lucideReact.XCircle
1812
- }
1813
- };
1814
- function Callout({ variant = "info", title, body, testId }) {
1815
- const style = STYLES[variant] ?? STYLES.info;
1816
- const Icon = style.Icon;
1817
- return /* @__PURE__ */ jsxRuntime.jsxs(
1818
- "div",
1819
- {
1820
- className: react.cn("flex gap-3 rounded-lg border p-4 text-foreground", style.wrap),
1821
- "data-testid": testId,
1822
- role: "note",
1823
- children: [
1824
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: react.cn("mt-0.5 size-5 shrink-0", style.icon), "aria-hidden": true }),
1825
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
1826
- title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold", children: title }),
1827
- body && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-relaxed text-muted-foreground", children: body })
1828
- ] })
1829
- ]
1830
- }
1831
- );
1832
- }
1833
- var SIZE = {
1834
- sm: "size-8 text-xs",
1835
- md: "size-10 text-sm",
1836
- lg: "size-14 text-base",
1837
- xl: "size-20 text-xl"
1838
- };
1839
- function AvatarBlock({ src, name = "", size = "md", testId }) {
1840
- return /* @__PURE__ */ jsxRuntime.jsxs(react.Avatar, { className: react.cn(SIZE[size] ?? SIZE.md), "data-testid": testId, children: [
1841
- src && /* @__PURE__ */ jsxRuntime.jsx(react.AvatarImage, { src, alt: name }),
1842
- /* @__PURE__ */ jsxRuntime.jsx(react.AvatarFallback, { className: "font-semibold", children: initials(name || "?") })
1843
- ] });
1844
- }
1845
- function Navbar({ brand, links, cta, testId }) {
1846
- return /* @__PURE__ */ jsxRuntime.jsx("header", { className: "border-b border-border bg-background", "data-testid": testId, children: /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "mx-auto flex max-w-7xl items-center justify-between gap-6 px-5 py-4 lg:px-8", children: [
1847
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-semibold tracking-tight", children: brand }),
1848
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden items-center gap-6 md:flex", children: (links ?? []).map((link, i) => /* @__PURE__ */ jsxRuntime.jsx(
1849
- "a",
1850
- {
1851
- href: link.href || "#",
1852
- className: "text-sm font-medium text-muted-foreground transition-colors hover:text-foreground",
1853
- "data-testid": testId && `${testId}-link-${i}`,
1854
- children: link.label
1855
- },
1856
- i
1857
- )) }),
1858
- cta?.label && /* @__PURE__ */ jsxRuntime.jsx(react.Button, { asChild: true, size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: cta.href || "#", children: cta.label }) })
1859
- ] }) });
1860
- }
1861
- function Footer({ columns, copyright, testId }) {
1862
- return /* @__PURE__ */ jsxRuntime.jsx("footer", { className: "border-t border-border bg-muted text-foreground", "data-testid": testId, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-7xl px-5 py-14 lg:px-8", children: [
1863
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-8 sm:grid-cols-2 lg:grid-cols-4", children: (columns ?? []).map((col, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": testId && `${testId}-col-${i}`, children: [
1864
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold tracking-tight", children: col.heading }),
1865
- /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-4 space-y-2", children: (col.links ?? []).map((link, j) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
1866
- "a",
1867
- {
1868
- href: link.href || "#",
1869
- className: "text-sm text-muted-foreground transition-colors hover:text-foreground",
1870
- children: link.label
1871
- }
1872
- ) }, j)) })
1873
- ] }, i)) }),
1874
- copyright && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-12 border-t border-border pt-6 text-sm text-muted-foreground", children: copyright })
1875
- ] }) });
1876
- }
1877
- function ListBlock({ ordered = false, items, testId }) {
1878
- const list = items ?? [];
1879
- const className = react.cn(
1880
- "mx-auto max-w-3xl space-y-2 pl-5 text-foreground",
1881
- ordered ? "list-decimal" : "list-disc"
1882
- );
1883
- const content = list.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "leading-relaxed marker:text-muted-foreground", children: item.text }, i));
1884
- return ordered ? /* @__PURE__ */ jsxRuntime.jsx("ol", { className, "data-testid": testId, children: content }) : /* @__PURE__ */ jsxRuntime.jsx("ul", { className, "data-testid": testId, children: content });
1885
- }
1886
- var GRID2 = {
1887
- 2: "sm:grid-cols-2",
1888
- 3: "sm:grid-cols-2 lg:grid-cols-3",
1889
- 4: "sm:grid-cols-2 lg:grid-cols-4"
1890
- };
1891
- var GAP = {
1892
- sm: "gap-3",
1893
- md: "gap-6",
1894
- lg: "gap-10"
1895
- };
1896
- function Columns({ count = 3, gap = "md", columns, testId }) {
1897
- return /* @__PURE__ */ jsxRuntime.jsx(
1898
- "div",
1899
- {
1900
- className: react.cn("grid grid-cols-1", GRID2[count] ?? GRID2[3], GAP[gap] ?? GAP.md),
1901
- "data-testid": testId,
1902
- children: columns.map((col, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": testId && `${testId}-col-${i}`, children: col }, i))
1903
- }
1904
- );
1905
- }
1906
- var SIZE2 = {
1907
- sm: "h-4",
1908
- md: "h-8",
1909
- lg: "h-16",
1910
- xl: "h-24"
1911
- };
1912
- function Spacer({ size = "md", testId }) {
1913
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: react.cn("w-full", SIZE2[size] ?? SIZE2.md), "data-testid": testId, "aria-hidden": true });
1914
- }
1915
- var WIDTH = {
1916
- narrow: "max-w-3xl",
1917
- default: "max-w-5xl",
1918
- wide: "max-w-7xl",
1919
- full: "max-w-none"
1920
- };
1921
- var PADDING = {
1922
- none: "px-0 py-0",
1923
- sm: "px-4 py-6",
1924
- md: "px-5 py-12 lg:px-8",
1925
- lg: "px-5 py-20 lg:px-8"
1926
- };
1927
- function Container({ width = "default", padding = "md", children, testId }) {
1928
- return /* @__PURE__ */ jsxRuntime.jsx(
1929
- "div",
1930
- {
1931
- className: react.cn(
1932
- "mx-auto w-full",
1933
- WIDTH[width] ?? WIDTH.default,
1934
- PADDING[padding] ?? PADDING.md
1935
- ),
1936
- "data-testid": testId,
1937
- children
1938
- }
1939
- );
1940
- }
1941
- function PricingTable({ plans, testId }) {
1942
- return /* @__PURE__ */ jsxRuntime.jsx(
1943
- "div",
1944
- {
1945
- className: react.cn("grid gap-6", (plans?.length ?? 0) >= 3 ? "md:grid-cols-3" : "sm:grid-cols-2"),
1946
- "data-testid": testId,
1947
- children: (plans ?? []).map((plan, i) => /* @__PURE__ */ jsxRuntime.jsxs(
1948
- react.Card,
1949
- {
1950
- variant: plan.featured ? "elevated" : "outline",
1951
- className: react.cn("flex h-full flex-col p-6", plan.featured && "ring-2 ring-primary"),
1952
- "data-testid": testId && `${testId}-item-${i}`,
1953
- children: [
1954
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold tracking-tight", children: plan.name }),
1955
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex items-baseline gap-1", children: [
1956
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-3xl font-semibold tracking-tight", children: plan.price }),
1957
- plan.period && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground", children: [
1958
- "/",
1959
- plan.period
1960
- ] })
1961
- ] }),
1962
- plan.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm leading-relaxed text-muted-foreground", children: plan.description }),
1963
- plan.features && plan.features.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-5 flex-1 space-y-2", children: plan.features.map((f, j) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start gap-2 text-sm", children: [
1964
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "mt-0.5 size-4 shrink-0 text-primary" }),
1965
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: f })
1966
- ] }, j)) }),
1967
- plan.cta?.label && /* @__PURE__ */ jsxRuntime.jsx(react.Button, { asChild: true, className: "mt-6 w-full", variant: plan.featured ? "default" : "outline", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: plan.cta.href || "#", children: plan.cta.label }) })
1968
- ]
1969
- },
1970
- i
1971
- ))
1972
- }
1973
- );
1974
- }
1975
- function Tabs({ items, testId }) {
1976
- const [active, setActive] = react$1.useState(0);
1977
- const list = items ?? [];
1978
- const current = list[Math.min(active, Math.max(list.length - 1, 0))];
1979
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": testId, children: [
1980
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 border-b border-border", role: "tablist", children: list.map((t, i) => {
1981
- const selected = i === active;
1982
- return /* @__PURE__ */ jsxRuntime.jsx(
1983
- "button",
1984
- {
1985
- type: "button",
1986
- role: "tab",
1987
- "aria-selected": selected,
1988
- onClick: () => setActive(i),
1989
- className: react.cn(
1990
- "-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors",
1991
- selected ? "border-primary text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
1992
- ),
1993
- "data-testid": testId && `${testId}-tab-${i}`,
1994
- children: t.label
1995
- },
1996
- i
1997
- );
1998
- }) }),
1999
- current && /* @__PURE__ */ jsxRuntime.jsx(
2000
- "div",
2001
- {
2002
- role: "tabpanel",
2003
- className: "pt-5 text-sm leading-relaxed text-muted-foreground",
2004
- "data-testid": testId && `${testId}-panel`,
2005
- children: current.content
2006
- }
2007
- )
2008
- ] });
2009
- }
2010
- function Accordion({ items, allowMultiple = false, testId }) {
2011
- const [open, setOpen] = react$1.useState([]);
2012
- const toggle2 = (i) => setOpen(
2013
- (prev) => prev.includes(i) ? prev.filter((n) => n !== i) : allowMultiple ? [...prev, i] : [i]
2014
- );
2015
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border border-y border-border", "data-testid": testId, children: (items ?? []).map((item, i) => {
2016
- const isOpen = open.includes(i);
2017
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": testId && `${testId}-item-${i}`, children: [
2018
- /* @__PURE__ */ jsxRuntime.jsxs(
2019
- "button",
2020
- {
2021
- type: "button",
2022
- "aria-expanded": isOpen,
2023
- onClick: () => toggle2(i),
2024
- className: "flex w-full items-center justify-between gap-4 py-4 text-left text-base font-medium",
2025
- "data-testid": testId && `${testId}-trigger-${i}`,
2026
- children: [
2027
- item.title,
2028
- /* @__PURE__ */ jsxRuntime.jsx(
2029
- lucideReact.ChevronDown,
2030
- {
2031
- className: react.cn("size-4 shrink-0 transition-transform", isOpen && "rotate-180")
2032
- }
2033
- )
2034
- ]
2035
- }
2036
- ),
2037
- isOpen && /* @__PURE__ */ jsxRuntime.jsx(
2038
- "p",
2039
- {
2040
- className: "pb-4 text-sm leading-relaxed text-muted-foreground",
2041
- "data-testid": testId && `${testId}-content-${i}`,
2042
- children: item.content
2043
- }
2044
- )
2045
- ] }, i);
2046
- }) });
2047
- }
2048
- var COLS2 = {
2049
- "2": "grid-cols-2",
2050
- "3": "grid-cols-2 sm:grid-cols-3",
2051
- "4": "grid-cols-2 sm:grid-cols-4"
2052
- };
2053
- function Gallery({
2054
- images,
2055
- columns = "3",
2056
- aspect = "1:1",
2057
- rounded = "lg",
2058
- testId
2059
- }) {
2060
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: react.cn("grid gap-4", COLS2[columns] ?? COLS2["3"]), "data-testid": testId, children: (images ?? []).map((img, i) => /* @__PURE__ */ jsxRuntime.jsxs("figure", { "data-testid": testId && `${testId}-item-${i}`, children: [
2061
- /* @__PURE__ */ jsxRuntime.jsx(
2062
- BlockImage,
2063
- {
2064
- src: img.src,
2065
- alt: img.alt,
2066
- aspect,
2067
- rounded,
2068
- testId: testId && `${testId}-item-${i}-image`
2069
- }
2070
- ),
2071
- img.caption && /* @__PURE__ */ jsxRuntime.jsx("figcaption", { className: "mt-1.5 text-xs text-muted-foreground", children: img.caption })
2072
- ] }, i)) });
2073
- }
2074
- var ASPECT2 = {
2075
- "16:9": "aspect-video",
2076
- "4:3": "aspect-[4/3]",
2077
- "1:1": "aspect-square"
2078
- };
2079
- function toEmbedUrl(url) {
2080
- if (!url) return null;
2081
- const yt = url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([\w-]{11})/);
2082
- if (yt) return `https://www.youtube.com/embed/${yt[1]}`;
2083
- const vimeo = url.match(/vimeo\.com\/(?:video\/)?(\d+)/);
2084
- if (vimeo) return `https://player.vimeo.com/video/${vimeo[1]}`;
2085
- const loom = url.match(/loom\.com\/(?:share|embed)\/([\w-]+)/);
2086
- if (loom) return `https://www.loom.com/embed/${loom[1]}`;
2087
- return null;
2088
- }
2089
- function VideoEmbed({
2090
- url,
2091
- title,
2092
- aspect = "16:9",
2093
- rounded = true,
2094
- testId
2095
- }) {
2096
- const embed = toEmbedUrl(url);
2097
- const frame = react.cn(
2098
- "w-full overflow-hidden border border-border bg-muted",
2099
- ASPECT2[aspect] ?? ASPECT2["16:9"],
2100
- rounded && "rounded-lg"
2101
- );
2102
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: frame, "data-testid": testId, children: embed ? /* @__PURE__ */ jsxRuntime.jsx(
2103
- "iframe",
2104
- {
2105
- src: embed,
2106
- title: title || "Embedded video",
2107
- className: "size-full",
2108
- allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
2109
- allowFullScreen: true,
2110
- "data-testid": testId && `${testId}-iframe`
2111
- }
2112
- ) : url ? /* @__PURE__ */ jsxRuntime.jsx("video", { src: url, controls: true, className: "size-full", "data-testid": testId && `${testId}-video` }) : null });
2113
- }
2114
- function ContactForm({
2115
- fields,
2116
- submitLabel = "Send",
2117
- action,
2118
- successMessage = "Thanks \u2014 we\u2019ll be in touch shortly.",
2119
- testId
2120
- }) {
2121
- const [sent, setSent] = react$1.useState(false);
2122
- const list = fields ?? [];
2123
- const onSubmit = (e) => {
2124
- if (!action) {
2125
- e.preventDefault();
2126
- setSent(true);
2127
- }
2128
- };
2129
- if (sent) {
2130
- return /* @__PURE__ */ jsxRuntime.jsx(
2131
- "p",
2132
- {
2133
- className: "rounded-lg border border-border bg-muted p-6 text-center text-sm text-foreground",
2134
- role: "status",
2135
- "data-testid": testId && `${testId}-success`,
2136
- children: successMessage
2137
- }
2138
- );
2139
- }
2140
- return /* @__PURE__ */ jsxRuntime.jsxs(
2141
- "form",
2142
- {
2143
- action,
2144
- method: action ? "post" : void 0,
2145
- onSubmit,
2146
- className: "mx-auto flex max-w-xl flex-col gap-4",
2147
- "data-testid": testId,
2148
- children: [
2149
- list.map((f, i) => {
2150
- const inputClass = "w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground outline-none focus:border-primary";
2151
- return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1.5 text-left", children: [
2152
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: f.label }),
2153
- f.type === "textarea" ? /* @__PURE__ */ jsxRuntime.jsx(
2154
- "textarea",
2155
- {
2156
- name: f.name,
2157
- required: f.required,
2158
- rows: 4,
2159
- className: inputClass,
2160
- "data-testid": testId && `${testId}-field-${f.name}`
2161
- }
2162
- ) : /* @__PURE__ */ jsxRuntime.jsx(
2163
- "input",
2164
- {
2165
- name: f.name,
2166
- type: f.type || "text",
2167
- required: f.required,
2168
- className: inputClass,
2169
- "data-testid": testId && `${testId}-field-${f.name}`
2170
- }
2171
- )
2172
- ] }, i);
2173
- }),
2174
- /* @__PURE__ */ jsxRuntime.jsx(
2175
- react.Button,
2176
- {
2177
- type: "submit",
2178
- className: react.cn("mt-1 self-start"),
2179
- "data-testid": testId && `${testId}-submit`,
2180
- children: submitLabel
2181
- }
2182
- )
2183
- ]
2184
- }
2185
- );
2186
- }
2187
- var TONE = {
2188
- primary: "bg-primary text-primary-foreground",
2189
- muted: "bg-muted text-foreground",
2190
- ink: "bg-foreground text-background"
2191
- };
2192
- function Banner({ text, cta, tone = "primary", testId }) {
2193
- return /* @__PURE__ */ jsxRuntime.jsxs(
2194
- "div",
2195
- {
2196
- className: react.cn("w-full px-5 py-2.5 text-center text-sm", TONE[tone] ?? TONE.primary),
2197
- "data-testid": testId,
2198
- children: [
2199
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: text }),
2200
- cta?.label && /* @__PURE__ */ jsxRuntime.jsxs(
2201
- "a",
2202
- {
2203
- href: cta.href || "#",
2204
- className: "ml-2 inline-flex items-center gap-1 font-semibold underline underline-offset-4",
2205
- "data-testid": testId && `${testId}-cta`,
2206
- children: [
2207
- cta.label,
2208
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "size-3.5" })
2209
- ]
2210
- }
2211
- )
2212
- ]
2213
- }
2214
- );
2215
- }
2216
- function MediaText({
2217
- eyebrow,
2218
- title,
2219
- body,
2220
- imageUrl,
2221
- mediaSide = "left",
2222
- cta,
2223
- testId
2224
- }) {
2225
- const media = /* @__PURE__ */ jsxRuntime.jsx(BlockImage, { src: imageUrl, aspect: "4:3", rounded: "lg", testId: testId && `${testId}-image` });
2226
- const copy = /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2227
- eyebrow && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: eyebrow }),
2228
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl font-semibold tracking-tight text-balance", children: title }),
2229
- body && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 text-lg leading-relaxed text-muted-foreground", children: body }),
2230
- cta?.label && /* @__PURE__ */ jsxRuntime.jsx(react.Button, { asChild: true, className: "mt-6", children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: cta.href || "#", children: [
2231
- cta.label,
2232
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "size-4" })
2233
- ] }) })
2234
- ] });
2235
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid items-center gap-10 lg:grid-cols-2", "data-testid": testId, children: mediaSide === "right" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2236
- copy,
2237
- media
2238
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2239
- media,
2240
- copy
2241
- ] }) });
2242
- }
2243
- var COLS3 = {
2244
- "2": "sm:grid-cols-2",
2245
- "3": "sm:grid-cols-2 lg:grid-cols-3",
2246
- "4": "sm:grid-cols-2 lg:grid-cols-4"
2247
- };
2248
- function TeamGrid({ members, columns = "3", testId }) {
2249
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: react.cn("grid gap-6", COLS3[columns] ?? COLS3["3"]), "data-testid": testId, children: (members ?? []).map((m, i) => /* @__PURE__ */ jsxRuntime.jsxs(
1059
+ }
1060
+ var MAX_AVATARS = 4;
1061
+ function WorkspaceCard({
1062
+ name,
1063
+ matterRef,
1064
+ description,
1065
+ docCount,
1066
+ memberCount,
1067
+ members = [],
1068
+ updatedAt,
1069
+ active = false,
1070
+ busy = false,
1071
+ onOpen,
1072
+ icon: Icon = lucideReact.FolderLock,
1073
+ testId,
1074
+ buttonTestId,
1075
+ className
1076
+ }) {
1077
+ const totalMembers = memberCount ?? members.length;
1078
+ const shownMembers = members.slice(0, MAX_AVATARS);
1079
+ const extraMembers = totalMembers - shownMembers.length;
1080
+ const btnTestId = buttonTestId ?? (testId ? `${testId}-open` : void 0);
1081
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2250
1082
  react.Card,
2251
1083
  {
2252
1084
  variant: "outline",
2253
- className: "flex h-full flex-col items-center p-6 text-center",
2254
- "data-testid": testId && `${testId}-item-${i}`,
1085
+ className: react.cn("card-hover flex flex-col p-5", className),
1086
+ "data-testid": testId,
2255
1087
  children: [
2256
- /* @__PURE__ */ jsxRuntime.jsxs(react.Avatar, { className: "size-20", children: [
2257
- m.avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(react.AvatarImage, { src: m.avatarUrl, alt: m.name }),
2258
- /* @__PURE__ */ jsxRuntime.jsx(react.AvatarFallback, { children: initials(m.name || "?") })
1088
+ /* @__PURE__ */ jsxRuntime.jsxs(react.CardHeader, { className: "p-0", children: [
1089
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
1090
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-10 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "size-5" }) }),
1091
+ active ? /* @__PURE__ */ jsxRuntime.jsxs(react.Badge, { children: [
1092
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "mr-1 size-3" }),
1093
+ " Active"
1094
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(react.Badge, { variant: "secondary", children: "Encrypted" })
1095
+ ] }),
1096
+ /* @__PURE__ */ jsxRuntime.jsx(react.CardTitle, { className: "mt-3 text-base", children: name }),
1097
+ matterRef && /* @__PURE__ */ jsxRuntime.jsx(react.CardDescription, { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: matterRef })
2259
1098
  ] }),
2260
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mt-4 text-base font-semibold tracking-tight", children: m.name }),
2261
- m.role && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-primary", children: m.role }),
2262
- m.bio && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm leading-relaxed text-muted-foreground", children: m.bio })
1099
+ /* @__PURE__ */ jsxRuntime.jsxs(react.CardContent, { className: "mt-3 flex-1 space-y-4 p-0", children: [
1100
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-2 text-sm text-muted-foreground", children: description }),
1101
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 text-sm", children: [
1102
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 text-foreground", children: [
1103
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "size-4 text-muted-foreground" }),
1104
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: docCount.toLocaleString() }),
1105
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "docs" })
1106
+ ] }),
1107
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 text-foreground", children: [
1108
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Users, { className: "size-4 text-muted-foreground" }),
1109
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: totalMembers }),
1110
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "members" })
1111
+ ] })
1112
+ ] }),
1113
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
1114
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex -space-x-2", children: [
1115
+ shownMembers.map((m, i) => /* @__PURE__ */ jsxRuntime.jsxs(react.Avatar, { className: "size-7 border-2 border-card", title: m.name, children: [
1116
+ m.picture && /* @__PURE__ */ jsxRuntime.jsx(react.AvatarImage, { src: m.picture, alt: m.name }),
1117
+ /* @__PURE__ */ jsxRuntime.jsx(react.AvatarFallback, { className: "bg-foreground text-[10px] font-medium text-background", children: chunkAHWIZJ4M_cjs.initials(m.name || "?") })
1118
+ ] }, i)),
1119
+ extraMembers > 0 && /* @__PURE__ */ jsxRuntime.jsx(react.Avatar, { className: "size-7 border-2 border-card", children: /* @__PURE__ */ jsxRuntime.jsxs(react.AvatarFallback, { className: "bg-accent text-[10px] font-medium text-muted-foreground", children: [
1120
+ "+",
1121
+ extraMembers
1122
+ ] }) })
1123
+ ] }),
1124
+ updatedAt && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", title: chunkAHWIZJ4M_cjs.fmtDate(updatedAt), children: [
1125
+ "Updated ",
1126
+ chunkAHWIZJ4M_cjs.fromNow(updatedAt)
1127
+ ] })
1128
+ ] })
1129
+ ] }),
1130
+ /* @__PURE__ */ jsxRuntime.jsx(react.CardFooter, { className: "mt-4 p-0", children: active ? /* @__PURE__ */ jsxRuntime.jsxs(react.Button, { variant: "outline", className: "w-full", disabled: true, "data-testid": btnTestId, children: [
1131
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "size-4" }),
1132
+ " Current workspace"
1133
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(react.Button, { className: "w-full", onClick: onOpen, disabled: busy, "data-testid": btnTestId, children: [
1134
+ busy ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeftRight, { className: "size-4" }),
1135
+ "Open"
1136
+ ] }) })
2263
1137
  ]
2264
- },
2265
- i
2266
- )) });
2267
- }
2268
- function Steps({ steps, variant = "numbered", testId }) {
2269
- const list = steps ?? [];
2270
- if (variant === "timeline") {
2271
- return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "relative ml-3 border-l border-border", "data-testid": testId, children: list.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "mb-8 ml-6 last:mb-0", "data-testid": testId && `${testId}-item-${i}`, children: [
2272
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -left-3 flex size-6 items-center justify-center rounded-full bg-primary text-xs font-semibold text-primary-foreground", children: i + 1 }),
2273
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold tracking-tight", children: s.title }),
2274
- s.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm leading-relaxed text-muted-foreground", children: s.description })
2275
- ] }, i)) });
2276
- }
2277
- return /* @__PURE__ */ jsxRuntime.jsx(
2278
- "div",
2279
- {
2280
- className: react.cn("grid gap-6", list.length >= 4 ? "md:grid-cols-4" : "sm:grid-cols-3"),
2281
- "data-testid": testId,
2282
- children: list.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": testId && `${testId}-item-${i}`, children: [
2283
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-9 items-center justify-center rounded-full bg-primary/10 text-sm font-semibold text-primary", children: i + 1 }),
2284
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mt-4 text-base font-semibold tracking-tight", children: s.title }),
2285
- s.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm leading-relaxed text-muted-foreground", children: s.description })
2286
- ] }, i))
2287
1138
  }
2288
1139
  );
2289
1140
  }
2290
- var COLS4 = {
2291
- "2": "sm:grid-cols-2",
2292
- "3": "sm:grid-cols-2 lg:grid-cols-3"
1141
+ var GRID = {
1142
+ 1: "grid-cols-1",
1143
+ 2: "grid-cols-2",
1144
+ 3: "grid-cols-2 sm:grid-cols-3",
1145
+ 4: "grid-cols-2 lg:grid-cols-4"
2293
1146
  };
2294
- function TestimonialGrid({ items, columns = "3", testId }) {
2295
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: react.cn("grid gap-6", COLS4[columns] ?? COLS4["3"]), "data-testid": testId, children: (items ?? []).map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs(
2296
- react.Card,
2297
- {
2298
- variant: "outline",
2299
- className: "flex h-full flex-col p-6",
2300
- "data-testid": testId && `${testId}-item-${i}`,
2301
- children: [
2302
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Quote, { className: "size-6 text-primary/40", "aria-hidden": true }),
2303
- /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: "mt-3 flex-1 text-base leading-relaxed", children: t.quote }),
2304
- (t.author || t.avatarUrl) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-5 flex items-center gap-3", children: [
2305
- /* @__PURE__ */ jsxRuntime.jsxs(react.Avatar, { className: "size-9", children: [
2306
- t.avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(react.AvatarImage, { src: t.avatarUrl, alt: t.author ?? "" }),
2307
- /* @__PURE__ */ jsxRuntime.jsx(react.AvatarFallback, { children: initials(t.author || "?") })
2308
- ] }),
2309
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2310
- t.author && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold", children: t.author }),
2311
- t.role && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: t.role })
2312
- ] })
2313
- ] })
2314
- ]
2315
- },
2316
- i
2317
- )) });
1147
+ function StatGroup({ items, testId }) {
1148
+ const list = items ?? [];
1149
+ const cols = GRID[Math.min(list.length, 4)] ?? GRID[4];
1150
+ return /* @__PURE__ */ jsxRuntime.jsx("dl", { className: react.cn("grid gap-8", cols), "data-testid": testId, children: list.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", "data-testid": testId && `${testId}-item-${i}`, children: [
1151
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "sr-only", children: item.label }),
1152
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "text-4xl font-semibold tracking-tight sm:text-5xl", children: item.value }),
1153
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: item.label }),
1154
+ item.sub && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-muted-foreground/80", children: item.sub })
1155
+ ] }, i)) });
2318
1156
  }
2319
1157
  function NavItemLink({ item, onNavigate }) {
2320
1158
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2323,7 +1161,7 @@ function NavItemLink({ item, onNavigate }) {
2323
1161
  to: item.to,
2324
1162
  end: item.end,
2325
1163
  onClick: onNavigate,
2326
- "data-testid": tid("sidebar-nav", item.id),
1164
+ "data-testid": chunkAHWIZJ4M_cjs.tid("sidebar-nav", item.id),
2327
1165
  className: ({ isActive }) => react.cn(
2328
1166
  "group flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
2329
1167
  isActive ? "bg-sidebar-accent text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground"
@@ -2387,85 +1225,90 @@ function AppShell({
2387
1225
  onNavigate
2388
1226
  }
2389
1227
  );
2390
- return /* @__PURE__ */ jsxRuntime.jsxs(
2391
- "div",
2392
- {
2393
- className: "flex h-screen overflow-hidden bg-background",
2394
- "data-testid": `${testIdPrefix}-shell`,
2395
- children: [
2396
- /* @__PURE__ */ jsxRuntime.jsx(
2397
- "aside",
2398
- {
2399
- className: "hidden h-full w-64 shrink-0 flex-col border-r border-sidebar-border bg-sidebar lg:flex",
2400
- "data-testid": `${testIdPrefix}-sidebar`,
2401
- children: body()
2402
- }
2403
- ),
2404
- open && /* @__PURE__ */ jsxRuntime.jsxs(
2405
- "div",
2406
- {
2407
- className: "fixed inset-0 z-50 lg:hidden",
2408
- "data-testid": `${testIdPrefix}-sidebar-mobile`,
2409
- children: [
2410
- /* @__PURE__ */ jsxRuntime.jsx(
2411
- "div",
2412
- {
2413
- className: "absolute inset-0 bg-black/60 backdrop-blur-sm",
2414
- onClick: () => setOpen(false),
2415
- "aria-hidden": true
2416
- }
2417
- ),
2418
- /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "absolute inset-y-0 left-0 flex w-64 max-w-[82%] flex-col border-r border-sidebar-border bg-sidebar shadow-xl", children: [
2419
- /* @__PURE__ */ jsxRuntime.jsx(
2420
- "button",
2421
- {
2422
- type: "button",
2423
- onClick: () => setOpen(false),
2424
- className: "absolute right-3 top-4 z-10 flex size-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground",
2425
- "aria-label": "Close menu",
2426
- "data-testid": `${testIdPrefix}-sidebar-close`,
2427
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-5" })
2428
- }
2429
- ),
2430
- body(() => setOpen(false))
2431
- ] })
2432
- ]
2433
- }
2434
- ),
2435
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
2436
- /* @__PURE__ */ jsxRuntime.jsxs(
2437
- "header",
1228
+ return (
1229
+ // One TooltipProvider for the whole back office: every kit component that
1230
+ // renders a tooltip (entity pills, document tiles, toolbars) inherits the
1231
+ // same hover delay, and no app has to remember to mount it.
1232
+ /* @__PURE__ */ jsxRuntime.jsx(react.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
1233
+ "div",
1234
+ {
1235
+ className: "flex h-screen overflow-hidden bg-background",
1236
+ "data-testid": `${testIdPrefix}-shell`,
1237
+ children: [
1238
+ /* @__PURE__ */ jsxRuntime.jsx(
1239
+ "aside",
1240
+ {
1241
+ className: "hidden h-full w-64 shrink-0 flex-col border-r border-sidebar-border bg-sidebar lg:flex",
1242
+ "data-testid": `${testIdPrefix}-sidebar`,
1243
+ children: body()
1244
+ }
1245
+ ),
1246
+ open && /* @__PURE__ */ jsxRuntime.jsxs(
1247
+ "div",
2438
1248
  {
2439
- className: "flex h-16 shrink-0 items-center gap-4 border-b border-border bg-card/80 px-6 backdrop-blur",
2440
- "data-testid": `${testIdPrefix}-topbar`,
1249
+ className: "fixed inset-0 z-50 lg:hidden",
1250
+ "data-testid": `${testIdPrefix}-sidebar-mobile`,
2441
1251
  children: [
2442
1252
  /* @__PURE__ */ jsxRuntime.jsx(
2443
- "button",
1253
+ "div",
2444
1254
  {
2445
- type: "button",
2446
- onClick: () => setOpen(true),
2447
- className: "flex size-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground lg:hidden",
2448
- "data-testid": `${testIdPrefix}-nav-toggle`,
2449
- "aria-label": "Open menu",
2450
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "size-5" })
1255
+ className: "absolute inset-0 bg-black/60 backdrop-blur-sm",
1256
+ onClick: () => setOpen(false),
1257
+ "aria-hidden": true
2451
1258
  }
2452
1259
  ),
2453
- topbar
1260
+ /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "absolute inset-y-0 left-0 flex w-64 max-w-[82%] flex-col border-r border-sidebar-border bg-sidebar shadow-xl", children: [
1261
+ /* @__PURE__ */ jsxRuntime.jsx(
1262
+ "button",
1263
+ {
1264
+ type: "button",
1265
+ onClick: () => setOpen(false),
1266
+ className: "absolute right-3 top-4 z-10 flex size-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground",
1267
+ "aria-label": "Close menu",
1268
+ "data-testid": `${testIdPrefix}-sidebar-close`,
1269
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-5" })
1270
+ }
1271
+ ),
1272
+ body(() => setOpen(false))
1273
+ ] })
2454
1274
  ]
2455
1275
  }
2456
1276
  ),
2457
- /* @__PURE__ */ jsxRuntime.jsx(
2458
- "main",
2459
- {
2460
- className: react.cn("flex-1 overflow-y-auto", mainClassName),
2461
- "data-testid": `${testIdPrefix}-main`,
2462
- children
2463
- }
2464
- )
2465
- ] }),
2466
- rightRail
2467
- ]
2468
- }
1277
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
1278
+ /* @__PURE__ */ jsxRuntime.jsxs(
1279
+ "header",
1280
+ {
1281
+ className: "flex h-16 shrink-0 items-center gap-4 border-b border-border bg-card/80 px-6 backdrop-blur",
1282
+ "data-testid": `${testIdPrefix}-topbar`,
1283
+ children: [
1284
+ /* @__PURE__ */ jsxRuntime.jsx(
1285
+ "button",
1286
+ {
1287
+ type: "button",
1288
+ onClick: () => setOpen(true),
1289
+ className: "flex size-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground lg:hidden",
1290
+ "data-testid": `${testIdPrefix}-nav-toggle`,
1291
+ "aria-label": "Open menu",
1292
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "size-5" })
1293
+ }
1294
+ ),
1295
+ topbar
1296
+ ]
1297
+ }
1298
+ ),
1299
+ /* @__PURE__ */ jsxRuntime.jsx(
1300
+ "main",
1301
+ {
1302
+ className: react.cn("flex-1 overflow-y-auto", mainClassName),
1303
+ "data-testid": `${testIdPrefix}-main`,
1304
+ children
1305
+ }
1306
+ )
1307
+ ] }),
1308
+ rightRail
1309
+ ]
1310
+ }
1311
+ ) })
2469
1312
  );
2470
1313
  }
2471
1314
  function AppHeader({
@@ -2491,7 +1334,7 @@ function AppHeader({
2491
1334
  type: "button",
2492
1335
  onClick: onSearch,
2493
1336
  className: classNames?.search ?? "relative hidden max-w-md flex-1 items-center rounded-md border border-input bg-background py-2 pl-9 pr-3 text-left text-sm text-muted-foreground transition-colors hover:bg-accent md:flex",
2494
- "data-testid": tid(testIdPrefix, "global-search"),
1337
+ "data-testid": chunkAHWIZJ4M_cjs.tid(testIdPrefix, "global-search"),
2495
1338
  children: [
2496
1339
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
2497
1340
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: searchPlaceholder }),
@@ -2507,7 +1350,7 @@ function AppHeader({
2507
1350
  size: "sm",
2508
1351
  onClick: onAsk ?? onSearch,
2509
1352
  className: classNames?.askButton,
2510
- "data-testid": tid(testIdPrefix, "ask-ai"),
1353
+ "data-testid": chunkAHWIZJ4M_cjs.tid(testIdPrefix, "ask-ai"),
2511
1354
  children: [
2512
1355
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "size-4" }),
2513
1356
  askLabel
@@ -2518,7 +1361,7 @@ function AppHeader({
2518
1361
  /* @__PURE__ */ jsxRuntime.jsx(
2519
1362
  react.NotificationBell,
2520
1363
  {
2521
- testId: tid(testIdPrefix, "notifications"),
1364
+ testId: chunkAHWIZJ4M_cjs.tid(testIdPrefix, "notifications"),
2522
1365
  onNavigate: onNotificationNavigate,
2523
1366
  toneClassNames: notificationTones
2524
1367
  }
@@ -2529,8 +1372,8 @@ function AppHeader({
2529
1372
  user,
2530
1373
  items: userItems,
2531
1374
  onLogout,
2532
- testId: tid(testIdPrefix, "user-menu"),
2533
- logoutTestId: tid(testIdPrefix, "logout")
1375
+ testId: chunkAHWIZJ4M_cjs.tid(testIdPrefix, "user-menu"),
1376
+ logoutTestId: chunkAHWIZJ4M_cjs.tid(testIdPrefix, "logout")
2534
1377
  }
2535
1378
  )
2536
1379
  ] })
@@ -2700,6 +1543,32 @@ function createLiveWidgets(kit) {
2700
1543
  LiveMetric: LiveMetricWidget
2701
1544
  };
2702
1545
  }
1546
+ function useAssetImage(docId) {
1547
+ const arbi = react.useArbi();
1548
+ const { data: thumbs } = react.useThumbnails([docId]);
1549
+ const thumb = thumbs?.[docId];
1550
+ const { data: objectUrl } = reactQuery.useQuery({
1551
+ queryKey: ["arbi", "asset-image", docId],
1552
+ queryFn: async () => {
1553
+ const res = await arbi.documents.download(docId);
1554
+ const blob = await res.blob();
1555
+ return URL.createObjectURL(blob);
1556
+ },
1557
+ // Only download when the thumbnail is genuinely absent (not merely loading).
1558
+ enabled: !!docId && thumbs != null && !thumb && arbi.hasWorkspace,
1559
+ staleTime: 10 * 6e4
1560
+ });
1561
+ react$1.useEffect(() => {
1562
+ return () => {
1563
+ if (objectUrl) URL.revokeObjectURL(objectUrl);
1564
+ };
1565
+ }, [objectUrl]);
1566
+ return thumb ?? objectUrl;
1567
+ }
1568
+ function AssetThumb({ docId, alt, className, testId }) {
1569
+ const src = useAssetImage(docId);
1570
+ return /* @__PURE__ */ jsxRuntime.jsx("img", { src: src ?? void 0, alt: alt ?? "", className, "data-testid": testId });
1571
+ }
2703
1572
 
2704
1573
  // src/studio/publish.ts
2705
1574
  function blobToDataUrl(blob) {
@@ -2724,7 +1593,7 @@ function createArbiMaterializer(arbi, opts = {}) {
2724
1593
  }
2725
1594
  function collectAssetRefs(node, acc) {
2726
1595
  if (typeof node === "string") {
2727
- if (isAssetRef(node)) acc.add(node);
1596
+ if (chunkAHWIZJ4M_cjs.isAssetRef(node)) acc.add(node);
2728
1597
  return;
2729
1598
  }
2730
1599
  if (Array.isArray(node)) {
@@ -2758,7 +1627,7 @@ async function materializePageData(data, materialize) {
2758
1627
  const replacements = /* @__PURE__ */ new Map();
2759
1628
  await Promise.all(
2760
1629
  [...refs].map(async (ref) => {
2761
- const src = await materialize(assetRefId(ref));
1630
+ const src = await materialize(chunkAHWIZJ4M_cjs.assetRefId(ref));
2762
1631
  if (src) replacements.set(ref, src);
2763
1632
  })
2764
1633
  );
@@ -2818,7 +1687,7 @@ function StudioEditor({
2818
1687
  delete w.__studioResetSlug;
2819
1688
  };
2820
1689
  }, [resetSeam, arbi, live, persistence]);
2821
- const persist4 = react$1.useCallback(
1690
+ const persist3 = react$1.useCallback(
2822
1691
  async (toSave) => {
2823
1692
  setSaving(true);
2824
1693
  try {
@@ -2843,7 +1712,7 @@ function StudioEditor({
2843
1712
  radius: stored.radius ?? defaultTheme.radius,
2844
1713
  activePresetId: null
2845
1714
  });
2846
- applyStoredTheme(themeBundle);
1715
+ chunkAHWIZJ4M_cjs.applyStoredTheme(themeBundle);
2847
1716
  })();
2848
1717
  return () => {
2849
1718
  cancelled = true;
@@ -2911,7 +1780,7 @@ function StudioEditor({
2911
1780
  "button",
2912
1781
  {
2913
1782
  type: "button",
2914
- onClick: () => void persist4(latest.current),
1783
+ onClick: () => void persist3(latest.current),
2915
1784
  disabled: saving || loading,
2916
1785
  className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-60",
2917
1786
  "data-testid": `${testIdPrefix}-publish`,
@@ -2936,7 +1805,7 @@ function StudioEditor({
2936
1805
  "\u201D\u2026"
2937
1806
  ]
2938
1807
  }
2939
- ) : /* @__PURE__ */ jsxRuntime.jsx(AssetResolverProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
1808
+ ) : /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.AssetResolverProvider, { render: AssetThumb, children: /* @__PURE__ */ jsxRuntime.jsx(
2940
1809
  puck.Puck,
2941
1810
  {
2942
1811
  config,
@@ -2944,7 +1813,7 @@ function StudioEditor({
2944
1813
  onChange: (d) => {
2945
1814
  latest.current = d;
2946
1815
  },
2947
- onPublish: (d) => void persist4(d)
1816
+ onPublish: (d) => void persist3(d)
2948
1817
  },
2949
1818
  `${slug}-${rev}`
2950
1819
  ) }) }),
@@ -2954,7 +1823,7 @@ function StudioEditor({
2954
1823
  className: "w-80 shrink-0 border-l border-border",
2955
1824
  "data-testid": `${testIdPrefix}-theme-drawer`,
2956
1825
  children: /* @__PURE__ */ jsxRuntime.jsx(
2957
- ThemeEditor,
1826
+ chunkAHWIZJ4M_cjs.ThemeEditor,
2958
1827
  {
2959
1828
  bundle: themeBundle,
2960
1829
  variant: "drawer",
@@ -2993,7 +1862,7 @@ function PageRenderer({
2993
1862
  const page = initialData ?? (await persistence.loadPublished(arbi, live, slug)).data ?? (await persistence.loadPage(arbi, live, slug)).data;
2994
1863
  if (cancelled) return;
2995
1864
  if (applyTheme) {
2996
- applyThemeVars(
1865
+ chunkAHWIZJ4M_cjs.applyThemeVars(
2997
1866
  theme ? { ...defaultTheme, ...theme, colors: { ...defaultTheme.colors, ...theme.colors } } : defaultTheme
2998
1867
  );
2999
1868
  }
@@ -3195,7 +2064,7 @@ function AiTextField({
3195
2064
  setActive(true);
3196
2065
  await task.run(buildPrompt({ kind, label, current: value ?? "" }), docIds);
3197
2066
  };
3198
- const inputTid = tid(`${testIdPrefix}-field`, name);
2067
+ const inputTid = chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-field`, name);
3199
2068
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "al-ai-field", children: [
3200
2069
  multiline ? /* @__PURE__ */ jsxRuntime.jsx(
3201
2070
  "textarea",
@@ -3224,7 +2093,7 @@ function AiTextField({
3224
2093
  className: "al-ai-field__btn",
3225
2094
  onClick: () => void write(),
3226
2095
  disabled: task.isRunning,
3227
- "data-testid": tid(`${testIdPrefix}-ai-write`, name),
2096
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-ai-write`, name),
3228
2097
  title: "Draft this field with AI, grounded in the marketing workspace",
3229
2098
  children: [
3230
2099
  task.isRunning ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-3 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "size-3" }),
@@ -3326,8 +2195,8 @@ function ImageFieldControl({
3326
2195
  const arbi = react.useArbi();
3327
2196
  const gen = useImageGen();
3328
2197
  const queryClient = reactQuery.useQueryClient();
3329
- const currentAssetImage = useAssetImage(isAssetRef(value) ? assetRefId(value) : "");
3330
- const tp = (...q) => tid(`${testIdPrefix}-image`, name, ...q);
2198
+ const currentAssetImage = useAssetImage(chunkAHWIZJ4M_cjs.isAssetRef(value) ? chunkAHWIZJ4M_cjs.assetRefId(value) : "");
2199
+ const tp = (...q) => chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-image`, name, ...q);
3331
2200
  const refreshAssets = () => queryClient.invalidateQueries({ queryKey: ["arbi", "documents", workspaceId] });
3332
2201
  const { data: docs } = react.useDocuments(workspaceId);
3333
2202
  const imageDocs = react$1.useMemo(
@@ -3361,7 +2230,7 @@ function ImageFieldControl({
3361
2230
  const res = await arbi.documents.uploadFile(file, name2, { folder });
3362
2231
  const id = res.doc_ext_ids?.[0];
3363
2232
  if (id) {
3364
- onChange(asAssetRef(id));
2233
+ onChange(chunkAHWIZJ4M_cjs.asAssetRef(id));
3365
2234
  void refreshAssets();
3366
2235
  }
3367
2236
  } finally {
@@ -3378,7 +2247,7 @@ function ImageFieldControl({
3378
2247
  if (!prompt.trim() || gen.isGenerating) return;
3379
2248
  const id = await gen.generate(prompt);
3380
2249
  if (id) {
3381
- onChange(asAssetRef(id));
2250
+ onChange(chunkAHWIZJ4M_cjs.asAssetRef(id));
3382
2251
  void refreshAssets();
3383
2252
  }
3384
2253
  };
@@ -3392,7 +2261,7 @@ function ImageFieldControl({
3392
2261
  const tabClass = (on) => `inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs font-medium ${on ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"}`;
3393
2262
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", "data-testid": tp(), children: [
3394
2263
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
3395
- /* @__PURE__ */ jsxRuntime.jsx(BlockImage, { src: value, aspect: "16:9", rounded: "md", testId: tp("preview") }),
2264
+ /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.BlockImage, { src: value, aspect: "16:9", rounded: "md", testId: tp("preview") }),
3396
2265
  currentAssetImage ? /* @__PURE__ */ jsxRuntime.jsxs(
3397
2266
  "button",
3398
2267
  {
@@ -3426,12 +2295,12 @@ function ImageFieldControl({
3426
2295
  imageDocs.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "col-span-3 py-3 text-center text-xs text-muted-foreground", children: "No image assets yet \u2014 upload or generate one." }),
3427
2296
  imageDocs.map((d) => {
3428
2297
  const thumb = thumbs?.[d.external_id];
3429
- const selected = value === asAssetRef(d.external_id);
2298
+ const selected = value === chunkAHWIZJ4M_cjs.asAssetRef(d.external_id);
3430
2299
  return /* @__PURE__ */ jsxRuntime.jsx(
3431
2300
  "button",
3432
2301
  {
3433
2302
  type: "button",
3434
- onClick: () => onChange(asAssetRef(d.external_id)),
2303
+ onClick: () => onChange(chunkAHWIZJ4M_cjs.asAssetRef(d.external_id)),
3435
2304
  className: `overflow-hidden rounded border ${selected ? "border-primary ring-1 ring-primary" : "border-border"}`,
3436
2305
  title: d.file_name ?? "",
3437
2306
  "data-testid": tp("asset", d.external_id),
@@ -3565,13 +2434,13 @@ var TEXTURE_STYLE = {
3565
2434
  backgroundSize: "4px 4px",
3566
2435
  opacity: 0.04
3567
2436
  };
3568
- var PADDING2 = {
2437
+ var PADDING = {
3569
2438
  none: "",
3570
2439
  sm: "py-8 lg:py-10",
3571
2440
  md: "py-16 lg:py-20",
3572
2441
  lg: "py-24 lg:py-28"
3573
2442
  };
3574
- var WIDTH2 = {
2443
+ var WIDTH = {
3575
2444
  narrow: "max-w-3xl",
3576
2445
  default: "max-w-7xl",
3577
2446
  wide: "max-w-[90rem]",
@@ -3603,8 +2472,8 @@ function Section({
3603
2472
  {
3604
2473
  className: react.cn(
3605
2474
  "relative mx-auto px-5 lg:px-8",
3606
- WIDTH2[maxWidth],
3607
- PADDING2[padding],
2475
+ WIDTH[maxWidth],
2476
+ PADDING[padding],
3608
2477
  className
3609
2478
  ),
3610
2479
  children
@@ -3669,7 +2538,7 @@ function createBlockKit(ai, image, eyebrowClassName) {
3669
2538
  }),
3670
2539
  iconField: (label = "Icon") => ({ type: "select", label, options: ICON_OPTIONS }),
3671
2540
  resolveIcon: (name) => name ? iconMap[name] : void 0,
3672
- blockTestId: (id) => tid("arbi-block", id)
2541
+ blockTestId: (id) => chunkAHWIZJ4M_cjs.tid("arbi-block", id)
3673
2542
  };
3674
2543
  }
3675
2544
  var emptySlot = [];
@@ -3734,7 +2603,7 @@ function createWebsiteBlocks(kit) {
3734
2603
  render: ({ id, count, gap, col1, col2, col3, col4 }) => {
3735
2604
  const n = Number(count) || 3;
3736
2605
  const columns = [col1, col2, col3, col4].slice(0, n).map(renderSlot);
3737
- return /* @__PURE__ */ jsxRuntime.jsx(Columns, { count: n, gap, columns, testId: blockTestId(id) });
2606
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Columns, { count: n, gap, columns, testId: blockTestId(id) });
3738
2607
  }
3739
2608
  };
3740
2609
  const SpacerBlock = {
@@ -3752,7 +2621,7 @@ function createWebsiteBlocks(kit) {
3752
2621
  }
3753
2622
  },
3754
2623
  defaultProps: { size: "md" },
3755
- render: ({ id, size }) => /* @__PURE__ */ jsxRuntime.jsx(Spacer, { size, testId: blockTestId(id) })
2624
+ render: ({ id, size }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Spacer, { size, testId: blockTestId(id) })
3756
2625
  };
3757
2626
  const ContainerBlock = {
3758
2627
  label: "Container",
@@ -3780,7 +2649,7 @@ function createWebsiteBlocks(kit) {
3780
2649
  children: { type: "slot" }
3781
2650
  },
3782
2651
  defaultProps: { width: "default", padding: "md", children: emptySlot },
3783
- render: ({ id, width, padding, children }) => /* @__PURE__ */ jsxRuntime.jsx(Container, { width, padding, testId: blockTestId(id), children: renderSlot(children) })
2652
+ render: ({ id, width, padding, children }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Container, { width, padding, testId: blockTestId(id), children: renderSlot(children) })
3784
2653
  };
3785
2654
  const HeroBlock = {
3786
2655
  label: "Hero",
@@ -3831,7 +2700,7 @@ function createWebsiteBlocks(kit) {
3831
2700
  backgroundImage,
3832
2701
  overlay
3833
2702
  }) => /* @__PURE__ */ jsxRuntime.jsx(
3834
- Hero,
2703
+ chunkAHWIZJ4M_cjs.Hero,
3835
2704
  {
3836
2705
  eyebrow,
3837
2706
  title,
@@ -3903,7 +2772,7 @@ function createWebsiteBlocks(kit) {
3903
2772
  icon: resolveIcon(it.icon)
3904
2773
  })
3905
2774
  );
3906
- return /* @__PURE__ */ jsxRuntime.jsx(FeatureGrid, { columns, items: list, testId: blockTestId(id) });
2775
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.FeatureGrid, { columns, items: list, testId: blockTestId(id) });
3907
2776
  }
3908
2777
  };
3909
2778
  const StatGroupBlock = {
@@ -3945,7 +2814,7 @@ function createWebsiteBlocks(kit) {
3945
2814
  avatarUrl: ""
3946
2815
  },
3947
2816
  render: ({ id, quote, author, role, avatarUrl }) => /* @__PURE__ */ jsxRuntime.jsx(
3948
- Testimonial,
2817
+ chunkAHWIZJ4M_cjs.Testimonial,
3949
2818
  {
3950
2819
  quote,
3951
2820
  author,
@@ -3974,7 +2843,7 @@ function createWebsiteBlocks(kit) {
3974
2843
  overlay: true
3975
2844
  },
3976
2845
  render: ({ id, title, subtitle, cta, tone, backgroundImage, overlay }) => /* @__PURE__ */ jsxRuntime.jsx(
3977
- CTABanner,
2846
+ chunkAHWIZJ4M_cjs.CTABanner,
3978
2847
  {
3979
2848
  title,
3980
2849
  subtitle,
@@ -4006,7 +2875,7 @@ function createWebsiteBlocks(kit) {
4006
2875
  { label: "Umbrella" }
4007
2876
  ]
4008
2877
  },
4009
- render: ({ id, items }) => /* @__PURE__ */ jsxRuntime.jsx(LogoCloud, { items, testId: blockTestId(id) })
2878
+ render: ({ id, items }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.LogoCloud, { items, testId: blockTestId(id) })
4010
2879
  };
4011
2880
  const FAQBlock = {
4012
2881
  label: "FAQ",
@@ -4038,7 +2907,7 @@ function createWebsiteBlocks(kit) {
4038
2907
  }
4039
2908
  ]
4040
2909
  },
4041
- render: ({ id, items }) => /* @__PURE__ */ jsxRuntime.jsx(FAQ, { items, testId: blockTestId(id) })
2910
+ render: ({ id, items }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.FAQ, { items, testId: blockTestId(id) })
4042
2911
  };
4043
2912
  const RichTextBlockConfig = {
4044
2913
  label: "Rich text",
@@ -4048,7 +2917,7 @@ function createWebsiteBlocks(kit) {
4048
2917
  defaultProps: {
4049
2918
  content: "## About us\n\nWe build tools that help teams do their best work. Our platform combines **power** and _simplicity_ so you can focus on what matters.\n\n- Fast to learn\n- Easy to scale\n- Loved by teams"
4050
2919
  },
4051
- render: ({ id, content }) => /* @__PURE__ */ jsxRuntime.jsx(RichTextBlock, { content, testId: blockTestId(id) })
2920
+ render: ({ id, content }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.RichTextBlock, { content, testId: blockTestId(id) })
4052
2921
  };
4053
2922
  const CalloutBlock = {
4054
2923
  label: "Callout",
@@ -4071,7 +2940,7 @@ function createWebsiteBlocks(kit) {
4071
2940
  title: "Good to know",
4072
2941
  body: "This is a helpful note that draws attention to important information."
4073
2942
  },
4074
- render: ({ id, variant, title, body }) => /* @__PURE__ */ jsxRuntime.jsx(Callout, { variant, title, body, testId: blockTestId(id) })
2943
+ render: ({ id, variant, title, body }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Callout, { variant, title, body, testId: blockTestId(id) })
4075
2944
  };
4076
2945
  const ImageBlock = {
4077
2946
  label: "Image",
@@ -4102,7 +2971,7 @@ function createWebsiteBlocks(kit) {
4102
2971
  },
4103
2972
  defaultProps: { src: "", alt: "Image", aspect: "16:9", rounded: "lg", framed: false },
4104
2973
  render: ({ id, src, alt, aspect, rounded, framed }) => /* @__PURE__ */ jsxRuntime.jsx(
4105
- BlockImage,
2974
+ chunkAHWIZJ4M_cjs.BlockImage,
4106
2975
  {
4107
2976
  src,
4108
2977
  alt,
@@ -4130,7 +2999,7 @@ function createWebsiteBlocks(kit) {
4130
2999
  }
4131
3000
  },
4132
3001
  defaultProps: { src: "", name: "Jane Doe", size: "md" },
4133
- render: ({ id, src, name, size }) => /* @__PURE__ */ jsxRuntime.jsx(AvatarBlock, { src, name, size, testId: blockTestId(id) })
3002
+ render: ({ id, src, name, size }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.AvatarBlock, { src, name, size, testId: blockTestId(id) })
4134
3003
  };
4135
3004
  const NavbarBlock = {
4136
3005
  label: "Navbar",
@@ -4158,7 +3027,7 @@ function createWebsiteBlocks(kit) {
4158
3027
  ],
4159
3028
  cta: { label: "Sign up", href: "#" }
4160
3029
  },
4161
- render: ({ id, brand, links, cta }) => /* @__PURE__ */ jsxRuntime.jsx(Navbar, { brand, links, cta, testId: blockTestId(id) })
3030
+ render: ({ id, brand, links, cta }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Navbar, { brand, links, cta, testId: blockTestId(id) })
4162
3031
  };
4163
3032
  const FooterBlock = {
4164
3033
  label: "Footer",
@@ -4217,7 +3086,7 @@ function createWebsiteBlocks(kit) {
4217
3086
  ],
4218
3087
  copyright: "\xA9 2026 Acme, Inc. All rights reserved."
4219
3088
  },
4220
- render: ({ id, columns, copyright }) => /* @__PURE__ */ jsxRuntime.jsx(Footer, { columns, copyright, testId: blockTestId(id) })
3089
+ render: ({ id, columns, copyright }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Footer, { columns, copyright, testId: blockTestId(id) })
4221
3090
  };
4222
3091
  const ListBlockConfig = {
4223
3092
  label: "List",
@@ -4235,7 +3104,7 @@ function createWebsiteBlocks(kit) {
4235
3104
  ordered: false,
4236
3105
  items: [{ text: "First item" }, { text: "Second item" }, { text: "Third item" }]
4237
3106
  },
4238
- render: ({ id, ordered, items }) => /* @__PURE__ */ jsxRuntime.jsx(ListBlock, { ordered, items, testId: blockTestId(id) })
3107
+ render: ({ id, ordered, items }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.ListBlock, { ordered, items, testId: blockTestId(id) })
4239
3108
  };
4240
3109
  return {
4241
3110
  Columns: ColumnsBlock,
@@ -4337,7 +3206,7 @@ function createSiteBlocks(kit) {
4337
3206
  ]
4338
3207
  },
4339
3208
  render: ({ id, plans }) => /* @__PURE__ */ jsxRuntime.jsx(
4340
- PricingTable,
3209
+ chunkAHWIZJ4M_cjs.PricingTable,
4341
3210
  {
4342
3211
  plans: (plans ?? []).map(
4343
3212
  (p) => ({
@@ -4375,7 +3244,7 @@ function createSiteBlocks(kit) {
4375
3244
  { label: "FAQ", content: "Answers to common questions." }
4376
3245
  ]
4377
3246
  },
4378
- render: ({ id, items }) => /* @__PURE__ */ jsxRuntime.jsx(Tabs, { items, testId: blockTestId(id) })
3247
+ render: ({ id, items }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Tabs, { items, testId: blockTestId(id) })
4379
3248
  };
4380
3249
  const AccordionBlock = {
4381
3250
  label: "Accordion",
@@ -4399,7 +3268,7 @@ function createSiteBlocks(kit) {
4399
3268
  { title: "How does billing work?", content: "Monthly or annually, cancel anytime." }
4400
3269
  ]
4401
3270
  },
4402
- render: ({ id, allowMultiple, items }) => /* @__PURE__ */ jsxRuntime.jsx(Accordion, { allowMultiple, items, testId: blockTestId(id) })
3271
+ render: ({ id, allowMultiple, items }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Accordion, { allowMultiple, items, testId: blockTestId(id) })
4403
3272
  };
4404
3273
  const GalleryBlock = {
4405
3274
  label: "Gallery",
@@ -4435,7 +3304,7 @@ function createSiteBlocks(kit) {
4435
3304
  { src: "", alt: "Image three", caption: "" }
4436
3305
  ]
4437
3306
  },
4438
- render: ({ id, columns, aspect, images }) => /* @__PURE__ */ jsxRuntime.jsx(Gallery, { columns, aspect, images, testId: blockTestId(id) })
3307
+ render: ({ id, columns, aspect, images }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Gallery, { columns, aspect, images, testId: blockTestId(id) })
4439
3308
  };
4440
3309
  const VideoBlock = {
4441
3310
  label: "Video",
@@ -4455,7 +3324,7 @@ function createSiteBlocks(kit) {
4455
3324
  },
4456
3325
  defaultProps: { url: "", title: "", aspect: "16:9", rounded: true },
4457
3326
  render: ({ id, url, title, aspect, rounded }) => /* @__PURE__ */ jsxRuntime.jsx(
4458
- VideoEmbed,
3327
+ chunkAHWIZJ4M_cjs.VideoEmbed,
4459
3328
  {
4460
3329
  url,
4461
3330
  title,
@@ -4504,7 +3373,7 @@ function createSiteBlocks(kit) {
4504
3373
  ]
4505
3374
  },
4506
3375
  render: ({ id, submitLabel, action, successMessage, fields }) => /* @__PURE__ */ jsxRuntime.jsx(
4507
- ContactForm,
3376
+ chunkAHWIZJ4M_cjs.ContactForm,
4508
3377
  {
4509
3378
  submitLabel,
4510
3379
  action: action || void 0,
@@ -4534,7 +3403,7 @@ function createSiteBlocks(kit) {
4534
3403
  cta: { label: "Read more", href: "#" },
4535
3404
  tone: "primary"
4536
3405
  },
4537
- render: ({ id, text, cta, tone }) => /* @__PURE__ */ jsxRuntime.jsx(Banner, { text, cta, tone, testId: blockTestId(id) })
3406
+ render: ({ id, text, cta, tone }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Banner, { text, cta, tone, testId: blockTestId(id) })
4538
3407
  };
4539
3408
  const MediaTextBlock = {
4540
3409
  label: "Media & text",
@@ -4562,7 +3431,7 @@ function createSiteBlocks(kit) {
4562
3431
  cta: { label: "Learn more", href: "#" }
4563
3432
  },
4564
3433
  render: ({ id, eyebrow, title, body, imageUrl, mediaSide, cta }) => /* @__PURE__ */ jsxRuntime.jsx(
4565
- MediaText,
3434
+ chunkAHWIZJ4M_cjs.MediaText,
4566
3435
  {
4567
3436
  eyebrow,
4568
3437
  title,
@@ -4599,7 +3468,7 @@ function createSiteBlocks(kit) {
4599
3468
  { name: "Jordan Lee", role: "Lead Engineer", bio: "", avatarUrl: "" }
4600
3469
  ]
4601
3470
  },
4602
- render: ({ id, columns, members }) => /* @__PURE__ */ jsxRuntime.jsx(TeamGrid, { columns, members, testId: blockTestId(id) })
3471
+ render: ({ id, columns, members }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.TeamGrid, { columns, members, testId: blockTestId(id) })
4603
3472
  };
4604
3473
  const StepsBlock = {
4605
3474
  label: "Steps",
@@ -4631,7 +3500,7 @@ function createSiteBlocks(kit) {
4631
3500
  { title: "Launch", description: "Go live and start seeing results." }
4632
3501
  ]
4633
3502
  },
4634
- render: ({ id, variant, steps }) => /* @__PURE__ */ jsxRuntime.jsx(Steps, { variant, steps, testId: blockTestId(id) })
3503
+ render: ({ id, variant, steps }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.Steps, { variant, steps, testId: blockTestId(id) })
4635
3504
  };
4636
3505
  const TestimonialGridBlock = {
4637
3506
  label: "Testimonial grid",
@@ -4673,7 +3542,7 @@ function createSiteBlocks(kit) {
4673
3542
  }
4674
3543
  ]
4675
3544
  },
4676
- render: ({ id, columns, items }) => /* @__PURE__ */ jsxRuntime.jsx(TestimonialGrid, { columns, items, testId: blockTestId(id) })
3545
+ render: ({ id, columns, items }) => /* @__PURE__ */ jsxRuntime.jsx(chunkAHWIZJ4M_cjs.TestimonialGrid, { columns, items, testId: blockTestId(id) })
4677
3546
  };
4678
3547
  return {
4679
3548
  Pricing: PricingBlock,
@@ -4717,7 +3586,7 @@ function createArbiBlocksConfig(opts = {}) {
4717
3586
  },
4718
3587
  defaultProps: { title: "Section title", align: "left", invert: false },
4719
3588
  render: ({ id, title, eyebrow, lead, align, invert }) => /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": blockTestId(id), children: /* @__PURE__ */ jsxRuntime.jsx(
4720
- SectionHeading,
3589
+ chunkAHWIZJ4M_cjs.SectionHeading,
4721
3590
  {
4722
3591
  title,
4723
3592
  eyebrow,
@@ -5311,7 +4180,7 @@ function ModuleManager({ store, testIdPrefix = "builder" }) {
5311
4180
  {
5312
4181
  variant: "elevated",
5313
4182
  className: "rounded-xl",
5314
- "data-testid": tid(`${testIdPrefix}-modules-section`, group.section),
4183
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-modules-section`, group.section),
5315
4184
  children: [
5316
4185
  /* @__PURE__ */ jsxRuntime.jsx(react.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(react.CardTitle, { className: "text-base", children: group.section }) }),
5317
4186
  /* @__PURE__ */ jsxRuntime.jsx(react.CardContent, { className: "space-y-1.5", children: group.modules.map((m, idx) => {
@@ -5320,7 +4189,7 @@ function ModuleManager({ store, testIdPrefix = "builder" }) {
5320
4189
  "div",
5321
4190
  {
5322
4191
  className: "flex items-center gap-3 rounded-md border border-border/60 bg-card px-3 py-2",
5323
- "data-testid": tid(`${testIdPrefix}-module`, m.id),
4192
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-module`, m.id),
5324
4193
  children: [
5325
4194
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
5326
4195
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -5332,7 +4201,7 @@ function ModuleManager({ store, testIdPrefix = "builder" }) {
5332
4201
  disabled: idx === 0,
5333
4202
  onClick: () => move(m.id, "up"),
5334
4203
  "aria-label": `Move ${m.label} up`,
5335
- "data-testid": tid(`${testIdPrefix}-module-up`, m.id),
4204
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-module-up`, m.id),
5336
4205
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "size-3.5" })
5337
4206
  }
5338
4207
  ),
@@ -5345,7 +4214,7 @@ function ModuleManager({ store, testIdPrefix = "builder" }) {
5345
4214
  disabled: idx === group.modules.length - 1,
5346
4215
  onClick: () => move(m.id, "down"),
5347
4216
  "aria-label": `Move ${m.label} down`,
5348
- "data-testid": tid(`${testIdPrefix}-module-down`, m.id),
4217
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-module-down`, m.id),
5349
4218
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-3.5" })
5350
4219
  }
5351
4220
  )
@@ -5365,7 +4234,7 @@ function ModuleManager({ store, testIdPrefix = "builder" }) {
5365
4234
  checked: m.enabled,
5366
4235
  onCheckedChange: () => toggle2(m.id),
5367
4236
  "aria-label": `Enable ${m.label}`,
5368
- "data-testid": tid(`${testIdPrefix}-module-toggle`, m.id)
4237
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-module-toggle`, m.id)
5369
4238
  }
5370
4239
  )
5371
4240
  ]
@@ -5397,7 +4266,7 @@ function ConfigModelBadge({ configId, testIdPrefix }) {
5397
4266
  react.Badge,
5398
4267
  {
5399
4268
  variant: TIER_VARIANT[tier] ?? "secondary",
5400
- "data-testid": tid(`${testIdPrefix}-agents-config-tier`, configId),
4269
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-agents-config-tier`, configId),
5401
4270
  children: [
5402
4271
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Cpu, { className: "size-3" }),
5403
4272
  " ",
@@ -5434,14 +4303,14 @@ function AgentsPanel({ store, testIdPrefix = "builder" }) {
5434
4303
  "label",
5435
4304
  {
5436
4305
  className: "flex cursor-pointer items-center gap-3 rounded-md border border-border/60 bg-card px-3 py-2",
5437
- "data-testid": tid(`${testIdPrefix}-agents-config`, v.external_id),
4306
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-agents-config`, v.external_id),
5438
4307
  children: [
5439
4308
  /* @__PURE__ */ jsxRuntime.jsx(
5440
4309
  react.Checkbox,
5441
4310
  {
5442
4311
  checked: configIds.includes(v.external_id),
5443
4312
  onCheckedChange: () => toggleConfig(v.external_id),
5444
- "data-testid": tid(`${testIdPrefix}-agents-config-toggle`, v.external_id)
4313
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-agents-config-toggle`, v.external_id)
5445
4314
  }
5446
4315
  ),
5447
4316
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
@@ -5470,14 +4339,14 @@ function AgentsPanel({ store, testIdPrefix = "builder" }) {
5470
4339
  "label",
5471
4340
  {
5472
4341
  className: "flex cursor-pointer items-center gap-3 rounded-md border border-border/60 bg-card px-3 py-2",
5473
- "data-testid": tid(`${testIdPrefix}-agents-agent`, a.external_id),
4342
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-agents-agent`, a.external_id),
5474
4343
  children: [
5475
4344
  /* @__PURE__ */ jsxRuntime.jsx(
5476
4345
  react.Checkbox,
5477
4346
  {
5478
4347
  checked: agentIds.includes(a.external_id),
5479
4348
  onCheckedChange: () => toggleAgent(a.external_id),
5480
- "data-testid": tid(`${testIdPrefix}-agents-agent-toggle`, a.external_id)
4349
+ "data-testid": chunkAHWIZJ4M_cjs.tid(`${testIdPrefix}-agents-agent-toggle`, a.external_id)
5481
4350
  }
5482
4351
  ),
5483
4352
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
@@ -5564,7 +4433,7 @@ function VerticalBuilder({
5564
4433
  ] })
5565
4434
  ] }),
5566
4435
  /* @__PURE__ */ jsxRuntime.jsx(react.TabsContent, { value: "theme", children: /* @__PURE__ */ jsxRuntime.jsx(
5567
- ThemeEditor,
4436
+ chunkAHWIZJ4M_cjs.ThemeEditor,
5568
4437
  {
5569
4438
  bundle: themeBundle,
5570
4439
  variant: "panel",
@@ -5588,6 +4457,246 @@ function VerticalBuilder({
5588
4457
  ] });
5589
4458
  }
5590
4459
 
4460
+ Object.defineProperty(exports, "ASSET_REF_PREFIX", {
4461
+ enumerable: true,
4462
+ get: function () { return chunkAHWIZJ4M_cjs.ASSET_REF_PREFIX; }
4463
+ });
4464
+ Object.defineProperty(exports, "Accordion", {
4465
+ enumerable: true,
4466
+ get: function () { return chunkAHWIZJ4M_cjs.Accordion; }
4467
+ });
4468
+ Object.defineProperty(exports, "AssetResolverProvider", {
4469
+ enumerable: true,
4470
+ get: function () { return chunkAHWIZJ4M_cjs.AssetResolverProvider; }
4471
+ });
4472
+ Object.defineProperty(exports, "AvatarBlock", {
4473
+ enumerable: true,
4474
+ get: function () { return chunkAHWIZJ4M_cjs.AvatarBlock; }
4475
+ });
4476
+ Object.defineProperty(exports, "Banner", {
4477
+ enumerable: true,
4478
+ get: function () { return chunkAHWIZJ4M_cjs.Banner; }
4479
+ });
4480
+ Object.defineProperty(exports, "BlockImage", {
4481
+ enumerable: true,
4482
+ get: function () { return chunkAHWIZJ4M_cjs.BlockImage; }
4483
+ });
4484
+ Object.defineProperty(exports, "BlockLink", {
4485
+ enumerable: true,
4486
+ get: function () { return chunkAHWIZJ4M_cjs.BlockLink; }
4487
+ });
4488
+ Object.defineProperty(exports, "CTABanner", {
4489
+ enumerable: true,
4490
+ get: function () { return chunkAHWIZJ4M_cjs.CTABanner; }
4491
+ });
4492
+ Object.defineProperty(exports, "Callout", {
4493
+ enumerable: true,
4494
+ get: function () { return chunkAHWIZJ4M_cjs.Callout; }
4495
+ });
4496
+ Object.defineProperty(exports, "Columns", {
4497
+ enumerable: true,
4498
+ get: function () { return chunkAHWIZJ4M_cjs.Columns; }
4499
+ });
4500
+ Object.defineProperty(exports, "ContactForm", {
4501
+ enumerable: true,
4502
+ get: function () { return chunkAHWIZJ4M_cjs.ContactForm; }
4503
+ });
4504
+ Object.defineProperty(exports, "Container", {
4505
+ enumerable: true,
4506
+ get: function () { return chunkAHWIZJ4M_cjs.Container; }
4507
+ });
4508
+ Object.defineProperty(exports, "FAQ", {
4509
+ enumerable: true,
4510
+ get: function () { return chunkAHWIZJ4M_cjs.FAQ; }
4511
+ });
4512
+ Object.defineProperty(exports, "FONT_PAIRINGS", {
4513
+ enumerable: true,
4514
+ get: function () { return chunkAHWIZJ4M_cjs.FONT_PAIRINGS; }
4515
+ });
4516
+ Object.defineProperty(exports, "FeatureGrid", {
4517
+ enumerable: true,
4518
+ get: function () { return chunkAHWIZJ4M_cjs.FeatureGrid; }
4519
+ });
4520
+ Object.defineProperty(exports, "Footer", {
4521
+ enumerable: true,
4522
+ get: function () { return chunkAHWIZJ4M_cjs.Footer; }
4523
+ });
4524
+ Object.defineProperty(exports, "Gallery", {
4525
+ enumerable: true,
4526
+ get: function () { return chunkAHWIZJ4M_cjs.Gallery; }
4527
+ });
4528
+ Object.defineProperty(exports, "Hero", {
4529
+ enumerable: true,
4530
+ get: function () { return chunkAHWIZJ4M_cjs.Hero; }
4531
+ });
4532
+ Object.defineProperty(exports, "ListBlock", {
4533
+ enumerable: true,
4534
+ get: function () { return chunkAHWIZJ4M_cjs.ListBlock; }
4535
+ });
4536
+ Object.defineProperty(exports, "LogoCloud", {
4537
+ enumerable: true,
4538
+ get: function () { return chunkAHWIZJ4M_cjs.LogoCloud; }
4539
+ });
4540
+ Object.defineProperty(exports, "MediaText", {
4541
+ enumerable: true,
4542
+ get: function () { return chunkAHWIZJ4M_cjs.MediaText; }
4543
+ });
4544
+ Object.defineProperty(exports, "Navbar", {
4545
+ enumerable: true,
4546
+ get: function () { return chunkAHWIZJ4M_cjs.Navbar; }
4547
+ });
4548
+ Object.defineProperty(exports, "PricingTable", {
4549
+ enumerable: true,
4550
+ get: function () { return chunkAHWIZJ4M_cjs.PricingTable; }
4551
+ });
4552
+ Object.defineProperty(exports, "RichTextBlock", {
4553
+ enumerable: true,
4554
+ get: function () { return chunkAHWIZJ4M_cjs.RichTextBlock; }
4555
+ });
4556
+ Object.defineProperty(exports, "SectionHeading", {
4557
+ enumerable: true,
4558
+ get: function () { return chunkAHWIZJ4M_cjs.SectionHeading; }
4559
+ });
4560
+ Object.defineProperty(exports, "Spacer", {
4561
+ enumerable: true,
4562
+ get: function () { return chunkAHWIZJ4M_cjs.Spacer; }
4563
+ });
4564
+ Object.defineProperty(exports, "Steps", {
4565
+ enumerable: true,
4566
+ get: function () { return chunkAHWIZJ4M_cjs.Steps; }
4567
+ });
4568
+ Object.defineProperty(exports, "THEME_STYLE_ID", {
4569
+ enumerable: true,
4570
+ get: function () { return chunkAHWIZJ4M_cjs.THEME_STYLE_ID; }
4571
+ });
4572
+ Object.defineProperty(exports, "Tabs", {
4573
+ enumerable: true,
4574
+ get: function () { return chunkAHWIZJ4M_cjs.Tabs; }
4575
+ });
4576
+ Object.defineProperty(exports, "TeamGrid", {
4577
+ enumerable: true,
4578
+ get: function () { return chunkAHWIZJ4M_cjs.TeamGrid; }
4579
+ });
4580
+ Object.defineProperty(exports, "Testimonial", {
4581
+ enumerable: true,
4582
+ get: function () { return chunkAHWIZJ4M_cjs.Testimonial; }
4583
+ });
4584
+ Object.defineProperty(exports, "TestimonialGrid", {
4585
+ enumerable: true,
4586
+ get: function () { return chunkAHWIZJ4M_cjs.TestimonialGrid; }
4587
+ });
4588
+ Object.defineProperty(exports, "ThemeEditor", {
4589
+ enumerable: true,
4590
+ get: function () { return chunkAHWIZJ4M_cjs.ThemeEditor; }
4591
+ });
4592
+ Object.defineProperty(exports, "VideoEmbed", {
4593
+ enumerable: true,
4594
+ get: function () { return chunkAHWIZJ4M_cjs.VideoEmbed; }
4595
+ });
4596
+ Object.defineProperty(exports, "applyFontVars", {
4597
+ enumerable: true,
4598
+ get: function () { return chunkAHWIZJ4M_cjs.applyFontVars; }
4599
+ });
4600
+ Object.defineProperty(exports, "applyStoredTheme", {
4601
+ enumerable: true,
4602
+ get: function () { return chunkAHWIZJ4M_cjs.applyStoredTheme; }
4603
+ });
4604
+ Object.defineProperty(exports, "applyThemeVars", {
4605
+ enumerable: true,
4606
+ get: function () { return chunkAHWIZJ4M_cjs.applyThemeVars; }
4607
+ });
4608
+ Object.defineProperty(exports, "asAssetRef", {
4609
+ enumerable: true,
4610
+ get: function () { return chunkAHWIZJ4M_cjs.asAssetRef; }
4611
+ });
4612
+ Object.defineProperty(exports, "assetRefId", {
4613
+ enumerable: true,
4614
+ get: function () { return chunkAHWIZJ4M_cjs.assetRefId; }
4615
+ });
4616
+ Object.defineProperty(exports, "clearFontVars", {
4617
+ enumerable: true,
4618
+ get: function () { return chunkAHWIZJ4M_cjs.clearFontVars; }
4619
+ });
4620
+ Object.defineProperty(exports, "clearThemeVars", {
4621
+ enumerable: true,
4622
+ get: function () { return chunkAHWIZJ4M_cjs.clearThemeVars; }
4623
+ });
4624
+ Object.defineProperty(exports, "createThemeStore", {
4625
+ enumerable: true,
4626
+ get: function () { return chunkAHWIZJ4M_cjs.createThemeStore; }
4627
+ });
4628
+ Object.defineProperty(exports, "daysUntil", {
4629
+ enumerable: true,
4630
+ get: function () { return chunkAHWIZJ4M_cjs.daysUntil; }
4631
+ });
4632
+ Object.defineProperty(exports, "fmtDate", {
4633
+ enumerable: true,
4634
+ get: function () { return chunkAHWIZJ4M_cjs.fmtDate; }
4635
+ });
4636
+ Object.defineProperty(exports, "fmtDateTime", {
4637
+ enumerable: true,
4638
+ get: function () { return chunkAHWIZJ4M_cjs.fmtDateTime; }
4639
+ });
4640
+ Object.defineProperty(exports, "fontPackages", {
4641
+ enumerable: true,
4642
+ get: function () { return chunkAHWIZJ4M_cjs.fontPackages; }
4643
+ });
4644
+ Object.defineProperty(exports, "fromNow", {
4645
+ enumerable: true,
4646
+ get: function () { return chunkAHWIZJ4M_cjs.fromNow; }
4647
+ });
4648
+ Object.defineProperty(exports, "gbp", {
4649
+ enumerable: true,
4650
+ get: function () { return chunkAHWIZJ4M_cjs.gbp; }
4651
+ });
4652
+ Object.defineProperty(exports, "getFontPairing", {
4653
+ enumerable: true,
4654
+ get: function () { return chunkAHWIZJ4M_cjs.getFontPairing; }
4655
+ });
4656
+ Object.defineProperty(exports, "hrs", {
4657
+ enumerable: true,
4658
+ get: function () { return chunkAHWIZJ4M_cjs.hrs; }
4659
+ });
4660
+ Object.defineProperty(exports, "initials", {
4661
+ enumerable: true,
4662
+ get: function () { return chunkAHWIZJ4M_cjs.initials; }
4663
+ });
4664
+ Object.defineProperty(exports, "isAssetRef", {
4665
+ enumerable: true,
4666
+ get: function () { return chunkAHWIZJ4M_cjs.isAssetRef; }
4667
+ });
4668
+ Object.defineProperty(exports, "matchFontPairing", {
4669
+ enumerable: true,
4670
+ get: function () { return chunkAHWIZJ4M_cjs.matchFontPairing; }
4671
+ });
4672
+ Object.defineProperty(exports, "pct", {
4673
+ enumerable: true,
4674
+ get: function () { return chunkAHWIZJ4M_cjs.pct; }
4675
+ });
4676
+ Object.defineProperty(exports, "tid", {
4677
+ enumerable: true,
4678
+ get: function () { return chunkAHWIZJ4M_cjs.tid; }
4679
+ });
4680
+ Object.defineProperty(exports, "toEmbedUrl", {
4681
+ enumerable: true,
4682
+ get: function () { return chunkAHWIZJ4M_cjs.toEmbedUrl; }
4683
+ });
4684
+ Object.defineProperty(exports, "toHslTriplet", {
4685
+ enumerable: true,
4686
+ get: function () { return chunkAHWIZJ4M_cjs.toHslTriplet; }
4687
+ });
4688
+ Object.defineProperty(exports, "useAssetRenderer", {
4689
+ enumerable: true,
4690
+ get: function () { return chunkAHWIZJ4M_cjs.useAssetRenderer; }
4691
+ });
4692
+ Object.defineProperty(exports, "useAssetResolverActive", {
4693
+ enumerable: true,
4694
+ get: function () { return chunkAHWIZJ4M_cjs.useAssetResolverActive; }
4695
+ });
4696
+ Object.defineProperty(exports, "DocumentCard", {
4697
+ enumerable: true,
4698
+ get: function () { return react.DocumentCard; }
4699
+ });
5591
4700
  Object.defineProperty(exports, "Table", {
5592
4701
  enumerable: true,
5593
4702
  get: function () { return react.Table; }
@@ -5612,6 +4721,22 @@ Object.defineProperty(exports, "TableRow", {
5612
4721
  enumerable: true,
5613
4722
  get: function () { return react.TableRow; }
5614
4723
  });
4724
+ Object.defineProperty(exports, "Tooltip", {
4725
+ enumerable: true,
4726
+ get: function () { return react.Tooltip; }
4727
+ });
4728
+ Object.defineProperty(exports, "TooltipContent", {
4729
+ enumerable: true,
4730
+ get: function () { return react.TooltipContent; }
4731
+ });
4732
+ Object.defineProperty(exports, "TooltipProvider", {
4733
+ enumerable: true,
4734
+ get: function () { return react.TooltipProvider; }
4735
+ });
4736
+ Object.defineProperty(exports, "TooltipTrigger", {
4737
+ enumerable: true,
4738
+ get: function () { return react.TooltipTrigger; }
4739
+ });
5615
4740
  Object.defineProperty(exports, "redlineStats", {
5616
4741
  enumerable: true,
5617
4742
  get: function () { return react.redlineStats; }
@@ -5624,63 +4749,29 @@ Object.defineProperty(exports, "toRedlineMarkdown", {
5624
4749
  enumerable: true,
5625
4750
  get: function () { return react.toRedlineMarkdown; }
5626
4751
  });
5627
- exports.ASSET_REF_PREFIX = ASSET_REF_PREFIX;
5628
- exports.Accordion = Accordion;
5629
4752
  exports.AgentsPanel = AgentsPanel;
5630
4753
  exports.AppHeader = AppHeader;
5631
4754
  exports.AppShell = AppShell;
5632
- exports.AssetResolverProvider = AssetResolverProvider;
5633
- exports.AvatarBlock = AvatarBlock;
5634
- exports.Banner = Banner;
5635
- exports.BlockImage = BlockImage;
5636
- exports.CTABanner = CTABanner;
5637
- exports.Callout = Callout;
5638
- exports.Columns = Columns;
4755
+ exports.AssetThumb = AssetThumb;
5639
4756
  exports.ConnectionProvider = ConnectionProvider;
5640
- exports.ContactForm = ContactForm;
5641
- exports.Container = Container;
5642
4757
  exports.DataTable = DataTable;
5643
4758
  exports.DataTableBlock = DataTableBlock;
5644
4759
  exports.EmptyState = EmptyState;
5645
- exports.FAQ = FAQ;
5646
- exports.FeatureGrid = FeatureGrid;
5647
- exports.Footer = Footer;
5648
- exports.Gallery = Gallery;
5649
4760
  exports.GridView = GridView;
5650
- exports.Hero = Hero;
5651
4761
  exports.LegalArbiProvider = LegalArbiProvider;
5652
- exports.ListBlock = ListBlock;
5653
4762
  exports.LiveDataProvider = LiveDataProvider;
5654
- exports.LogoCloud = LogoCloud;
5655
- exports.MediaText = MediaText;
5656
4763
  exports.MetricCard = MetricCard;
5657
4764
  exports.ModuleManager = ModuleManager;
5658
- exports.Navbar = Navbar;
5659
4765
  exports.PageHeader = PageHeader;
5660
4766
  exports.PageRenderer = PageRenderer;
5661
- exports.PricingTable = PricingTable;
5662
- exports.RichTextBlock = RichTextBlock;
5663
4767
  exports.Section = Section;
5664
- exports.SectionHeading = SectionHeading;
5665
- exports.Spacer = Spacer;
5666
4768
  exports.StatGroup = StatGroup;
5667
- exports.Steps = Steps;
5668
4769
  exports.StudioEditor = StudioEditor;
5669
- exports.THEME_STYLE_ID = THEME_STYLE_ID;
5670
- exports.Tabs = Tabs;
5671
- exports.TeamGrid = TeamGrid;
5672
- exports.Testimonial = Testimonial;
5673
- exports.TestimonialGrid = TestimonialGrid;
5674
- exports.ThemeEditor = ThemeEditor;
5675
4770
  exports.Toolbar = Toolbar;
4771
+ exports.UploadDropzone = UploadDropzone;
5676
4772
  exports.VerticalBuilder = VerticalBuilder;
5677
- exports.VideoEmbed = VideoEmbed;
5678
4773
  exports.WidgetPlaceholder = WidgetPlaceholder;
5679
- exports.applyStoredTheme = applyStoredTheme;
5680
- exports.applyThemeVars = applyThemeVars;
5681
- exports.asAssetRef = asAssetRef;
5682
- exports.assetRefId = assetRefId;
5683
- exports.clearThemeVars = clearThemeVars;
4774
+ exports.WorkspaceCard = WorkspaceCard;
5684
4775
  exports.createAgentSelectionStore = createAgentSelectionStore;
5685
4776
  exports.createAiFields = createAiFields;
5686
4777
  exports.createArbiBlocksConfig = createArbiBlocksConfig;
@@ -5693,26 +4784,13 @@ exports.createModuleStore = createModuleStore;
5693
4784
  exports.createPromptLibrary = createPromptLibrary;
5694
4785
  exports.createSiteBlocks = createSiteBlocks;
5695
4786
  exports.createStudioPersistence = createStudioPersistence;
5696
- exports.createThemeStore = createThemeStore;
5697
4787
  exports.createVerticalExport = createVerticalExport;
5698
4788
  exports.createWebsiteBlocks = createWebsiteBlocks;
5699
- exports.daysUntil = daysUntil;
5700
- exports.fmtDate = fmtDate;
5701
- exports.fmtDateTime = fmtDateTime;
5702
- exports.fromNow = fromNow;
5703
- exports.gbp = gbp;
5704
- exports.hrs = hrs;
5705
4789
  exports.iconMap = iconMap;
5706
- exports.initials = initials;
5707
- exports.isAssetRef = isAssetRef;
5708
4790
  exports.isAuthenticated = isAuthenticated;
5709
4791
  exports.materializePageData = materializePageData;
5710
4792
  exports.matterToContext = matterToContext;
5711
- exports.pct = pct;
5712
- exports.tid = tid;
5713
- exports.toEmbedUrl = toEmbedUrl;
5714
- exports.toHslTriplet = toHslTriplet;
5715
- exports.useAssetResolverActive = useAssetResolverActive;
4793
+ exports.useAssetImage = useAssetImage;
5716
4794
  exports.useConnection = useConnection;
5717
4795
  exports.useFirmAiTask = useFirmAiTask;
5718
4796
  exports.useImageGen = useImageGen;