@timbal-ai/timbal-react 0.8.0 → 0.8.2

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.
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  SIDEBAR_INSET_PX_EXPANDED,
3
+ STORAGE_KEYS,
3
4
  ShellInsetProvider,
4
5
  studioChromeShellStyle,
5
6
  studioSidebarWidthTransition
6
- } from "./chunk-Z27GBSOT.esm.js";
7
+ } from "./chunk-QIABF4KB.esm.js";
7
8
  import {
8
9
  ChartArtifactView,
9
10
  LineAreaChart,
@@ -16,10 +17,10 @@ import {
16
17
  studioSecondaryChromeClass,
17
18
  studioTopbarPillHeightClass,
18
19
  toNum
19
- } from "./chunk-VVTTLIGT.esm.js";
20
+ } from "./chunk-5ZKLPWVN.esm.js";
20
21
  import {
21
22
  PillSegmentedTabs
22
- } from "./chunk-YNDXBN6C.esm.js";
23
+ } from "./chunk-OISVICYF.esm.js";
23
24
  import {
24
25
  Button,
25
26
  Dialog,
@@ -31,7 +32,7 @@ import {
31
32
  TIMBAL_V2_SWITCH_TRACK_OFF,
32
33
  TimbalV2Button,
33
34
  cn
34
- } from "./chunk-QKO67F4V.esm.js";
35
+ } from "./chunk-QVAUCVQA.esm.js";
35
36
 
36
37
  // src/app/agent-instructions.ts
37
38
  var APP_KIT_AGENT_INSTRUCTIONS = `
@@ -66,6 +67,8 @@ Presentational groups \u2014 import from the package root, not from these paths:
66
67
 
67
68
  Also re-exported: \`Button\`, \`TimbalChat\`, \`ChartArtifactView\`, \`APP_KIT_AGENT_INSTRUCTIONS\`.
68
69
 
70
+ Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\`, \`themeToCss\`, \`applyTimbalTheme\`, \`TIMBAL_THEME_PRESETS\`, \`applyThemePreset\`, \`ThemePresetGallery\`, \`TimbalThemeStyle\`, \`THEME_AGENT_INSTRUCTIONS\`.
71
+
69
72
  ### Design guidelines (required)
70
73
 
71
74
  | Area | Rule |
@@ -73,7 +76,7 @@ Also re-exported: \`Button\`, \`TimbalChat\`, \`ChartArtifactView\`, \`APP_KIT_A
73
76
  | **Copilot** | Use \`AppCopilotProvider\` for page context (\`useAppCopilotContext\`). Copilot is a **floating overlay** via \`AppShell\` \`chat={<AppChatPanel />}\` \u2014 not a sidebar column that shrinks main content. |
74
77
  | **Chat panel** | \`AppChatPanel\` only; \`Thread\` uses \`variant="panel"\` internally. Dismiss with **X**; trigger is a **text-only** pill (e.g. "Assistant") \u2014 **no** MessageSquare or chat icons on the shell trigger. |
75
78
  | **Context** | Do not show raw JSON context in the panel header; keep context in \`AppCopilotProvider\` only. |
76
- | **Theming** | Use semantic Tailwind tokens (\`bg-background\`, \`text-foreground\`, \`border-border\`, \`bg-elevated-from\`, etc.) from the host app's \`styles.css\`. Optional: \`import "@timbal-ai/timbal-react/styles.css"\`. |
79
+ | **Theming** | Use semantic Tailwind tokens (\`bg-background\`, \`text-foreground\`, \`border-border\`, \`bg-elevated-from\`, etc.) from the host app's \`styles.css\`. To rebrand, **never hand-author OKLCH** \u2014 call \`createTimbalTheme({ brand })\` + \`themeToCss\`/\`applyTimbalTheme\`, or apply a catalog preset (\`TIMBAL_THEME_PRESETS\` / \`applyThemePreset\`). To offer styles, render \`ThemePresetGallery\`. See \`THEME_AGENT_INSTRUCTIONS\`. |
77
80
  | **Layout chrome** | \`Page\` \u2192 \`Section\` for main content hierarchy. \`AppShellTopbar\` for global actions (auth, theme). |
78
81
  | **Data** | Prefer \`DataTable\` with typed \`columns\` / \`rows\` / \`getRowKey\`; use \`ChartPanel\` with \`ChartArtifact\` for charts. |
79
82
  | **Modals** | Use \`AppConfirmDialog\` for destructive/export confirmations. |
@@ -173,6 +176,7 @@ Studio chrome (\`StudioSidebar\`, \`ModeToggle\`, \u2026) lives in \`@timbal-ai/
173
176
  | \`resource-gallery.tsx\` | \`ResourceCard\`, \`StatusDot\`, \`Sparkline\` |
174
177
  | \`charts-panel.tsx\` | \`ChartPanel\`, \`ChartArtifact\` |
175
178
  | \`copilot-overlay.tsx\` | \`AppShell\`, \`AppChatPanel\` |
179
+ | \`theme-presets.tsx\` | \`ThemePresetGallery\`, \`applyTimbalTheme\` |
176
180
 
177
181
  ### Typical compositions
178
182
 
@@ -218,6 +222,864 @@ import {
218
222
  - For rich in-chat widgets, use **artifacts** (\`ARTIFACT_AGENT_INSTRUCTIONS\`) \u2014 app kit is for the **host application shell**.
219
223
  `.trim();
220
224
 
225
+ // src/design/oklch.ts
226
+ var clamp = (n, min, max) => Math.min(max, Math.max(min, n));
227
+ var round = (n, digits) => {
228
+ const f = 10 ** digits;
229
+ return Math.round(n * f) / f;
230
+ };
231
+ function srgbToLinear(channel) {
232
+ const c = channel / 255;
233
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
234
+ }
235
+ function linearRgbToOklch(r, g, b, alpha) {
236
+ const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
237
+ const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
238
+ const s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
239
+ const l_ = Math.cbrt(l);
240
+ const m_ = Math.cbrt(m);
241
+ const s_ = Math.cbrt(s);
242
+ const labL = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
243
+ const labA = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
244
+ const labB = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
245
+ const c = Math.sqrt(labA * labA + labB * labB);
246
+ let h = Math.atan2(labB, labA) * 180 / Math.PI;
247
+ if (h < 0) h += 360;
248
+ return { l: labL, c, h, alpha };
249
+ }
250
+ function oklchToLinearRgb(color) {
251
+ const hRad = color.h * Math.PI / 180;
252
+ const labA = color.c * Math.cos(hRad);
253
+ const labB = color.c * Math.sin(hRad);
254
+ const l_ = color.l + 0.3963377774 * labA + 0.2158037573 * labB;
255
+ const m_ = color.l - 0.1055613458 * labA - 0.0638541728 * labB;
256
+ const s_ = color.l - 0.0894841775 * labA - 1.291485548 * labB;
257
+ const l = l_ ** 3;
258
+ const m = m_ ** 3;
259
+ const s = s_ ** 3;
260
+ return {
261
+ r: 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
262
+ g: -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
263
+ b: -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
264
+ };
265
+ }
266
+ function parseHex(value) {
267
+ let hex = value.trim().replace(/^#/, "");
268
+ if (![3, 4, 6, 8].includes(hex.length)) return null;
269
+ if (hex.length === 3 || hex.length === 4) {
270
+ hex = hex.split("").map((ch) => ch + ch).join("");
271
+ }
272
+ const int = Number.parseInt(hex, 16);
273
+ if (Number.isNaN(int)) return null;
274
+ const hasAlpha = hex.length === 8;
275
+ const r = int >>> (hasAlpha ? 24 : 16) & 255;
276
+ const g = int >>> (hasAlpha ? 16 : 8) & 255;
277
+ const b = int >>> (hasAlpha ? 8 : 0) & 255;
278
+ const alpha = hasAlpha ? (int & 255) / 255 : 1;
279
+ return linearRgbToOklch(
280
+ srgbToLinear(r),
281
+ srgbToLinear(g),
282
+ srgbToLinear(b),
283
+ alpha
284
+ );
285
+ }
286
+ function parseRgb(value) {
287
+ const match = value.match(
288
+ /rgba?\(\s*([0-9.]+)[\s,]+([0-9.]+)[\s,]+([0-9.]+)(?:[\s,/]+([0-9.%]+))?\s*\)/i
289
+ );
290
+ if (!match) return null;
291
+ const r = Number.parseFloat(match[1]);
292
+ const g = Number.parseFloat(match[2]);
293
+ const b = Number.parseFloat(match[3]);
294
+ let alpha = 1;
295
+ if (match[4]) {
296
+ alpha = match[4].includes("%") ? Number.parseFloat(match[4]) / 100 : Number.parseFloat(match[4]);
297
+ }
298
+ if (![r, g, b].every(Number.isFinite)) return null;
299
+ return linearRgbToOklch(
300
+ srgbToLinear(r),
301
+ srgbToLinear(g),
302
+ srgbToLinear(b),
303
+ Number.isFinite(alpha) ? alpha : 1
304
+ );
305
+ }
306
+ function parseOklch(value) {
307
+ const match = value.match(
308
+ /oklch\(\s*([0-9.]+%?)\s+([0-9.]+%?)\s+([0-9.]+)(?:deg)?(?:\s*\/\s*([0-9.%]+))?\s*\)/i
309
+ );
310
+ if (!match) return null;
311
+ const l = match[1].includes("%") ? Number.parseFloat(match[1]) / 100 : Number.parseFloat(match[1]);
312
+ const c = match[2].includes("%") ? Number.parseFloat(match[2]) / 100 * 0.4 : Number.parseFloat(match[2]);
313
+ const h = Number.parseFloat(match[3]);
314
+ let alpha = 1;
315
+ if (match[4]) {
316
+ alpha = match[4].includes("%") ? Number.parseFloat(match[4]) / 100 : Number.parseFloat(match[4]);
317
+ }
318
+ if (![l, c, h].every(Number.isFinite)) return null;
319
+ return { l, c, h, alpha: Number.isFinite(alpha) ? alpha : 1 };
320
+ }
321
+ function parseColor(value) {
322
+ const parsed = parseOklch(value) ?? parseHex(value) ?? parseRgb(value);
323
+ if (!parsed) {
324
+ throw new Error(
325
+ `[@timbal-ai/timbal-react] Could not parse color "${value}". Use a hex (#1E40AF), rgb()/rgba(), or oklch() string.`
326
+ );
327
+ }
328
+ return parsed;
329
+ }
330
+ function lighten(color, delta) {
331
+ return { ...color, l: clamp(color.l + delta, 0, 1) };
332
+ }
333
+ function scaleChroma(color, factor) {
334
+ return { ...color, c: clamp(color.c * factor, 0, 0.4) };
335
+ }
336
+ function withAlpha(color, alpha) {
337
+ return { ...color, alpha: clamp(alpha, 0, 1) };
338
+ }
339
+ function oklchToString(color) {
340
+ const l = round(clamp(color.l, 0, 1), 4);
341
+ const c = round(clamp(color.c, 0, 0.4), 4);
342
+ const h = round((color.h % 360 + 360) % 360, 2);
343
+ const a = clamp(color.alpha, 0, 1);
344
+ const base = `oklch(${l} ${c} ${h}`;
345
+ return a >= 1 ? `${base})` : `${base} / ${round(a, 3)})`;
346
+ }
347
+ function readableForeground(bg, options) {
348
+ const threshold = options?.threshold ?? 0.62;
349
+ const lightText = options?.light ?? "oklch(0.985 0 0)";
350
+ const darkText = options?.dark ?? "oklch(0.205 0 0)";
351
+ return bg.l >= threshold ? darkText : lightText;
352
+ }
353
+ function relativeLuminance(color) {
354
+ const { r, g, b } = oklchToLinearRgb(color);
355
+ const lr = clamp(r, 0, 1);
356
+ const lg = clamp(g, 0, 1);
357
+ const lb = clamp(b, 0, 1);
358
+ return 0.2126 * lr + 0.7152 * lg + 0.0722 * lb;
359
+ }
360
+
361
+ // src/design/theme.ts
362
+ var SHADOW_PRESETS = {
363
+ none: {
364
+ lightCard: "none",
365
+ lightElevated: "none",
366
+ darkCard: "none",
367
+ darkElevated: "none"
368
+ },
369
+ hairline: {
370
+ lightCard: "0 0 0 1px rgba(15, 23, 42, 0.06)",
371
+ lightElevated: "0 1px 2px rgba(15, 23, 42, 0.06)",
372
+ darkCard: "0 0 0 1px rgba(255, 255, 255, 0.06)",
373
+ darkElevated: "0 2px 8px rgba(0, 0, 0, 0.4)"
374
+ },
375
+ soft: {
376
+ lightCard: "0 1px 2px rgba(15, 23, 42, 0.04)",
377
+ lightElevated: "0 8px 30px rgba(15, 23, 42, 0.07)",
378
+ darkCard: "0 1px 2px rgba(0, 0, 0, 0.3)",
379
+ darkElevated: "0 10px 34px rgba(0, 0, 0, 0.45)"
380
+ },
381
+ medium: {
382
+ lightCard: "0 1px 2px -0.5px rgba(0, 0, 0, 0.05)",
383
+ lightElevated: "0 4px 24px rgba(0, 0, 0, 0.06)",
384
+ darkCard: "0 1px 3px rgba(0, 0, 0, 0.22)",
385
+ darkElevated: "0 4px 24px rgba(0, 0, 0, 0.35)"
386
+ },
387
+ strong: {
388
+ lightCard: "0 2px 6px rgba(15, 23, 42, 0.10)",
389
+ lightElevated: "0 16px 48px rgba(15, 23, 42, 0.16)",
390
+ darkCard: "0 2px 6px rgba(0, 0, 0, 0.4)",
391
+ darkElevated: "0 18px 50px rgba(0, 0, 0, 0.6)"
392
+ }
393
+ };
394
+ function primaryForMode(brand, mode) {
395
+ if (mode === "light") {
396
+ return { ...brand, l: Math.min(Math.max(brand.l, 0.42), 0.68) };
397
+ }
398
+ const lightened = lighten(brand, 0.06);
399
+ return {
400
+ ...lightened,
401
+ l: Math.min(Math.max(lightened.l, 0.5), 0.78),
402
+ c: Math.min(brand.c, 0.22)
403
+ };
404
+ }
405
+ function brandGradient(primary) {
406
+ return {
407
+ from: lighten(primary, 0.03),
408
+ to: lighten(primary, -0.02),
409
+ hoverFrom: lighten(primary, 0.06),
410
+ hoverTo: lighten(primary, 0.01),
411
+ activeFrom: lighten(primary, -0.02),
412
+ activeTo: lighten(primary, -0.06)
413
+ };
414
+ }
415
+ function neutralTints(brand) {
416
+ return {
417
+ lightHue: brand.h,
418
+ darkHue: brand.h,
419
+ lightChroma: 6e-3,
420
+ darkChroma: 8e-3
421
+ };
422
+ }
423
+ function createTimbalTheme(intent) {
424
+ const brand = parseColor(intent.brand);
425
+ const accent = intent.accent ? parseColor(intent.accent) : null;
426
+ const light = {};
427
+ const dark = {};
428
+ const root = {};
429
+ let fontFamily;
430
+ let fontImportUrl;
431
+ if (typeof intent.radius === "number") {
432
+ root["--radius"] = `${intent.radius}rem`;
433
+ root["--radius-2xl"] = `${Math.max(intent.radius + 0.25, 0)}rem`;
434
+ }
435
+ if (intent.typography) {
436
+ const { sans, display, mono, importUrl } = intent.typography;
437
+ root["--font-sans"] = sans;
438
+ if (display) root["--font-display"] = display;
439
+ if (mono) root["--font-mono"] = mono;
440
+ fontFamily = sans;
441
+ fontImportUrl = importUrl;
442
+ }
443
+ if (intent.shadow) {
444
+ const s = SHADOW_PRESETS[intent.shadow];
445
+ light["--shadow-card-value"] = s.lightCard;
446
+ light["--shadow-card-elevated-value"] = s.lightElevated;
447
+ dark["--shadow-card-value"] = s.darkCard;
448
+ dark["--shadow-card-elevated-value"] = s.darkElevated;
449
+ }
450
+ const primaryLight = primaryForMode(brand, "light");
451
+ const primaryDark = primaryForMode(brand, "dark");
452
+ light["--primary"] = oklchToString(primaryLight);
453
+ light["--primary-foreground"] = readableForeground(primaryLight);
454
+ light["--ring"] = oklchToString(
455
+ scaleChroma({ ...primaryLight, l: 0.6 }, 0.7)
456
+ );
457
+ dark["--primary"] = oklchToString(primaryDark);
458
+ dark["--primary-foreground"] = readableForeground(primaryDark);
459
+ dark["--ring"] = oklchToString(scaleChroma({ ...primaryDark, l: 0.62 }, 0.6));
460
+ const gLight = brandGradient(primaryLight);
461
+ light["--primary-fill-from"] = oklchToString(gLight.from);
462
+ light["--primary-fill-to"] = oklchToString(gLight.to);
463
+ light["--primary-fill-hover-from"] = oklchToString(gLight.hoverFrom);
464
+ light["--primary-fill-hover-to"] = oklchToString(gLight.hoverTo);
465
+ light["--primary-fill-active-from"] = oklchToString(gLight.activeFrom);
466
+ light["--primary-fill-active-to"] = oklchToString(gLight.activeTo);
467
+ const gDark = brandGradient(primaryDark);
468
+ dark["--primary-fill-from"] = oklchToString(gDark.from);
469
+ dark["--primary-fill-to"] = oklchToString(gDark.to);
470
+ dark["--primary-fill-hover-from"] = oklchToString(gDark.hoverFrom);
471
+ dark["--primary-fill-hover-to"] = oklchToString(gDark.hoverTo);
472
+ dark["--primary-fill-active-from"] = oklchToString(gDark.activeFrom);
473
+ dark["--primary-fill-active-to"] = oklchToString(gDark.activeTo);
474
+ if (accent) {
475
+ const accentLight = { ...accent, l: Math.min(Math.max(accent.l, 0.9), 0.97) };
476
+ const accentDark = { ...accent, l: 0.25, c: Math.min(accent.c, 0.04) };
477
+ light["--accent"] = oklchToString(accentLight);
478
+ light["--accent-foreground"] = readableForeground(accentLight);
479
+ dark["--accent"] = oklchToString(accentDark);
480
+ dark["--accent-foreground"] = readableForeground(accentDark);
481
+ }
482
+ light["--playground-from"] = oklchToString(
483
+ withAlpha({ l: 0.91, c: 0.03, h: brand.h, alpha: 0.6 }, 0.6)
484
+ );
485
+ light["--playground-via"] = oklchToString(
486
+ withAlpha({ l: 0.965, c: 0.015, h: brand.h, alpha: 0.3 }, 0.3)
487
+ );
488
+ dark["--playground-from"] = oklchToString({
489
+ l: 0.27,
490
+ c: 0.03,
491
+ h: brand.h,
492
+ alpha: 1
493
+ });
494
+ dark["--playground-via"] = oklchToString({
495
+ l: 0.19,
496
+ c: 0.02,
497
+ h: brand.h,
498
+ alpha: 1
499
+ });
500
+ if (intent.tintNeutrals) {
501
+ const t = neutralTints(brand);
502
+ light["--secondary"] = oklchToString({
503
+ l: 0.975,
504
+ c: t.lightChroma,
505
+ h: t.lightHue,
506
+ alpha: 1
507
+ });
508
+ light["--muted"] = light["--secondary"];
509
+ light["--accent"] ?? (light["--accent"] = oklchToString({
510
+ l: 0.965,
511
+ c: t.lightChroma,
512
+ h: t.lightHue,
513
+ alpha: 1
514
+ }));
515
+ light["--border"] = oklchToString({
516
+ l: 0.91,
517
+ c: t.lightChroma,
518
+ h: t.lightHue,
519
+ alpha: 1
520
+ });
521
+ dark["--secondary"] = oklchToString({
522
+ l: 0.22,
523
+ c: t.darkChroma,
524
+ h: t.darkHue,
525
+ alpha: 1
526
+ });
527
+ dark["--muted"] = dark["--secondary"];
528
+ dark["--border"] = oklchToString({
529
+ l: 1,
530
+ c: 0,
531
+ h: 0,
532
+ alpha: 0.1
533
+ });
534
+ }
535
+ if (isDev()) {
536
+ const lum = relativeLuminance(primaryLight);
537
+ const fgIsLight = light["--primary-foreground"].includes("0.985");
538
+ const fgLum = fgIsLight ? 1 : 0.05;
539
+ const ratio = (Math.max(lum, fgLum) + 0.05) / (Math.min(lum, fgLum) + 0.05);
540
+ if (ratio < 3.5) {
541
+ console.warn(
542
+ `[@timbal-ai/timbal-react] createTimbalTheme: brand "${intent.brand}" yields a low primary/foreground contrast (~${ratio.toFixed(2)}:1). Consider a darker or more saturated brand color for buttons/CTAs.`
543
+ );
544
+ }
545
+ }
546
+ return { light, dark, root, fontFamily, fontImportUrl };
547
+ }
548
+ function declarations(map, indent) {
549
+ return Object.entries(map).map(([name, value]) => `${indent}${name}: ${value};`).join("\n");
550
+ }
551
+ function themeToCss(theme, options = {}) {
552
+ const indent = options.indent ?? " ";
553
+ const blocks = [];
554
+ const lightVars = { ...theme.root ?? {}, ...theme.light };
555
+ if (options.scope) {
556
+ const sel = `[data-timbal-theme="${options.scope}"]`;
557
+ if (Object.keys(lightVars).length) {
558
+ blocks.push(`${sel} {
559
+ ${declarations(lightVars, indent)}
560
+ }`);
561
+ }
562
+ if (Object.keys(theme.dark).length) {
563
+ blocks.push(
564
+ `.dark ${sel}, ${sel}.dark {
565
+ ${declarations(theme.dark, indent)}
566
+ }`
567
+ );
568
+ }
569
+ if (theme.fontFamily) {
570
+ blocks.push(`${sel} {
571
+ ${indent}font-family: var(--font-sans);
572
+ }`);
573
+ }
574
+ } else {
575
+ if (Object.keys(lightVars).length) {
576
+ blocks.push(`:root {
577
+ ${declarations(lightVars, indent)}
578
+ }`);
579
+ }
580
+ if (Object.keys(theme.dark).length) {
581
+ blocks.push(`.dark {
582
+ ${declarations(theme.dark, indent)}
583
+ }`);
584
+ }
585
+ if (theme.fontFamily) {
586
+ blocks.push(`:root,
587
+ body {
588
+ ${indent}font-family: var(--font-sans);
589
+ }`);
590
+ }
591
+ }
592
+ const css = blocks.join("\n\n");
593
+ if (options.includeFontImport && theme.fontImportUrl) {
594
+ return `@import url("${theme.fontImportUrl}");
595
+
596
+ ${css}`;
597
+ }
598
+ return css;
599
+ }
600
+ var RUNTIME_STYLE_ID = "timbal-theme-runtime";
601
+ var FONT_LINK_ATTR = "data-timbal-theme-font";
602
+ function ensureThemeFontLink(url) {
603
+ if (typeof document === "undefined") return;
604
+ const existing = document.head.querySelector(
605
+ `link[${FONT_LINK_ATTR}]`
606
+ );
607
+ if (!url) {
608
+ existing?.remove();
609
+ return;
610
+ }
611
+ if (existing?.getAttribute("href") === url) return;
612
+ const link = existing ?? document.createElement("link");
613
+ link.rel = "stylesheet";
614
+ link.href = url;
615
+ link.setAttribute(FONT_LINK_ATTR, "");
616
+ if (!existing) document.head.appendChild(link);
617
+ }
618
+ function applyTimbalTheme(theme) {
619
+ if (typeof document === "undefined") return () => {
620
+ };
621
+ ensureThemeFontLink(theme.fontImportUrl);
622
+ let el = document.getElementById(RUNTIME_STYLE_ID);
623
+ if (!el) {
624
+ el = document.createElement("style");
625
+ el.id = RUNTIME_STYLE_ID;
626
+ el.setAttribute("data-timbal-theme-runtime", "");
627
+ document.head.appendChild(el);
628
+ }
629
+ el.textContent = themeToCss(theme);
630
+ return () => {
631
+ el?.parentNode?.removeChild(el);
632
+ ensureThemeFontLink(void 0);
633
+ };
634
+ }
635
+ function clearTimbalTheme() {
636
+ if (typeof document === "undefined") return;
637
+ document.getElementById(RUNTIME_STYLE_ID)?.remove();
638
+ ensureThemeFontLink(void 0);
639
+ }
640
+ function isDev() {
641
+ if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") {
642
+ return false;
643
+ }
644
+ return true;
645
+ }
646
+
647
+ // src/design/theme-presets.ts
648
+ var EMPTY_TOKENS = { light: {}, dark: {}, root: {} };
649
+ var FONT_URL = {
650
+ geist: "https://fonts.googleapis.com/css2?family=Geist:wght@400..600&display=swap",
651
+ sora: "https://fonts.googleapis.com/css2?family=Sora:wght@400..600&display=swap",
652
+ lexend: "https://fonts.googleapis.com/css2?family=Lexend:wght@400..600&display=swap",
653
+ inter: "https://fonts.googleapis.com/css2?family=Inter:wght@400..600&display=swap",
654
+ fraunces: "https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400..600&display=swap",
655
+ jetbrains: "https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400..600&display=swap"
656
+ };
657
+ var STACK = {
658
+ geist: '"Geist", ui-sans-serif, system-ui, sans-serif',
659
+ sora: '"Sora", ui-sans-serif, system-ui, sans-serif',
660
+ lexend: '"Lexend", ui-sans-serif, system-ui, sans-serif',
661
+ inter: '"Inter", ui-sans-serif, system-ui, sans-serif',
662
+ fraunces: '"Fraunces", ui-serif, Georgia, "Times New Roman", serif',
663
+ jetbrains: '"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace'
664
+ };
665
+ var TIMBAL_THEME_PRESETS = [
666
+ {
667
+ id: "platform",
668
+ label: "Platform",
669
+ description: "Shipped neutral monochrome \u2014 the Timbal Platform default. Calm, brand-agnostic, system font.",
670
+ swatch: "oklch(0.205 0 0)",
671
+ font: null,
672
+ tokens: EMPTY_TOKENS
673
+ },
674
+ {
675
+ id: "indigo",
676
+ label: "Indigo",
677
+ description: "Cool, trustworthy blue-violet, Geist type, generous radius, soft shadows \u2014 analytics & ops dashboards.",
678
+ swatch: "#4f46e5",
679
+ font: "Geist",
680
+ tokens: createTimbalTheme({
681
+ brand: "#4f46e5",
682
+ radius: 0.875,
683
+ shadow: "soft",
684
+ typography: { sans: STACK.geist, importUrl: FONT_URL.geist }
685
+ })
686
+ },
687
+ {
688
+ id: "violet",
689
+ label: "Violet",
690
+ description: "Vivid purple, Sora type, rounded, soft shadows \u2014 expressive product / marketing surfaces.",
691
+ swatch: "#7c3aed",
692
+ font: "Sora",
693
+ tokens: createTimbalTheme({
694
+ brand: "#7c3aed",
695
+ radius: 1,
696
+ shadow: "soft",
697
+ typography: { sans: STACK.sora, importUrl: FONT_URL.sora }
698
+ })
699
+ },
700
+ {
701
+ id: "forest",
702
+ label: "Forest",
703
+ description: "Grounded green, Lexend type, compact radius \u2014 finance, sustainability, status-positive apps.",
704
+ swatch: "#16a34a",
705
+ font: "Lexend",
706
+ tokens: createTimbalTheme({
707
+ brand: "#16a34a",
708
+ radius: 0.625,
709
+ shadow: "soft",
710
+ typography: { sans: STACK.lexend, importUrl: FONT_URL.lexend }
711
+ })
712
+ },
713
+ {
714
+ id: "warm",
715
+ label: "Warm",
716
+ description: "Energetic orange, Lexend type, friendly radius \u2014 consumer, creative, high-engagement tools.",
717
+ swatch: "#ea580c",
718
+ font: "Lexend",
719
+ tokens: createTimbalTheme({
720
+ brand: "#ea580c",
721
+ radius: 0.875,
722
+ shadow: "soft",
723
+ typography: { sans: STACK.lexend, importUrl: FONT_URL.lexend }
724
+ })
725
+ },
726
+ {
727
+ id: "slate",
728
+ label: "Slate",
729
+ description: "Muted enterprise gray-blue, Inter type, tight radius, hairline shadows, tinted neutrals.",
730
+ swatch: "#475569",
731
+ font: "Inter",
732
+ tokens: createTimbalTheme({
733
+ brand: "#475569",
734
+ radius: 0.5,
735
+ shadow: "hairline",
736
+ tintNeutrals: true,
737
+ typography: { sans: STACK.inter, importUrl: FONT_URL.inter }
738
+ })
739
+ },
740
+ {
741
+ id: "folio",
742
+ label: "Folio",
743
+ description: "Editorial serif (Fraunces), near-sharp corners, hairline shadows \u2014 content / docs / reports.",
744
+ swatch: "#9a3412",
745
+ font: "Fraunces",
746
+ tokens: createTimbalTheme({
747
+ brand: "#9a3412",
748
+ radius: 0.25,
749
+ shadow: "hairline",
750
+ typography: { sans: STACK.fraunces, importUrl: FONT_URL.fraunces }
751
+ })
752
+ },
753
+ {
754
+ id: "carbon",
755
+ label: "Carbon",
756
+ description: "Terminal monospace (JetBrains Mono), crisp corners, green accent \u2014 developer / infra tools.",
757
+ swatch: "#15803d",
758
+ font: "JetBrains Mono",
759
+ tokens: createTimbalTheme({
760
+ brand: "#15803d",
761
+ radius: 0.375,
762
+ shadow: "hairline",
763
+ typography: { sans: STACK.jetbrains, importUrl: FONT_URL.jetbrains }
764
+ })
765
+ }
766
+ ];
767
+ var PRESET_BY_ID = new Map(
768
+ TIMBAL_THEME_PRESETS.map((preset) => [preset.id, preset])
769
+ );
770
+ function getThemePreset(id) {
771
+ return PRESET_BY_ID.get(id);
772
+ }
773
+ function applyThemePreset(id) {
774
+ const preset = PRESET_BY_ID.get(id);
775
+ if (!preset) return () => {
776
+ };
777
+ if (typeof window !== "undefined") {
778
+ try {
779
+ window.localStorage.setItem(STORAGE_KEYS.themePreset, id);
780
+ } catch {
781
+ }
782
+ }
783
+ return applyTimbalTheme(preset.tokens);
784
+ }
785
+ function getStoredThemePreset() {
786
+ if (typeof window === "undefined") return null;
787
+ try {
788
+ const value = window.localStorage.getItem(STORAGE_KEYS.themePreset);
789
+ return value && PRESET_BY_ID.has(value) ? value : null;
790
+ } catch {
791
+ return null;
792
+ }
793
+ }
794
+
795
+ // src/design/theme-instructions.ts
796
+ var THEME_AGENT_INSTRUCTIONS = `
797
+ ## Theming (@timbal-ai/timbal-react)
798
+
799
+ The package ships a complete light + dark token system (\`styles.css\`). Components are written against semantic Tailwind tokens (\`bg-background\`, \`text-primary\`, \`border-border\`, \`bg-elevated-from\`, \`bg-bubble-user\`, \u2026). To restyle, you change CSS variables \u2014 **never** hardcode colors in component code.
800
+
801
+ ### Golden rule
802
+
803
+ **Never write \`oklch(...)\` / hex literals or hand-author paired \`:root\` + \`.dark\` blocks.** Express intent and let the package derive a complete, contrast-correct, paired palette.
804
+
805
+ ### Generate a full personality (color + roundness + fonts + shadows)
806
+
807
+ \`\`\`ts
808
+ import { createTimbalTheme, themeToCss } from "@timbal-ai/timbal-react";
809
+
810
+ const theme = createTimbalTheme({
811
+ brand: "#4f46e5",
812
+ radius: 0.875, // corner roundness in rem (sets --radius + --radius-2xl)
813
+ shadow: "soft", // "none" | "hairline" | "soft" | "medium" | "strong"
814
+ tintNeutrals: false, // tint background/border toward the brand hue
815
+ accent: "#10b981", // optional secondary accent
816
+ typography: { // optional \u2014 re-skins every component's font
817
+ sans: '"Geist", ui-sans-serif, system-ui, sans-serif',
818
+ importUrl: "https://fonts.googleapis.com/css2?family=Geist:wght@400..600&display=swap",
819
+ // display?, mono? also supported
820
+ },
821
+ });
822
+ const css = themeToCss(theme); // paired light + dark, guaranteed in sync
823
+ \`\`\`
824
+
825
+ - \`createTimbalTheme\` derives \`--primary\`, its foreground, ring, the full button gradient, and a soft playground tint from \`brand\`. \`radius\` sets roundness, \`shadow\` sets card depth, \`typography\` sets fonts. You only supply intent \u2014 never raw OKLCH.
826
+ - For a real company, look up the actual brand hex first (brandfetch / "<company> brand color hex").
827
+ - **Web fonts must be loaded.** \`applyTimbalTheme\` / \`TimbalThemeStyle\` inject the \`<link>\` for \`typography.importUrl\` automatically. For build-time \`themeToCss\`, add the \`<link rel="stylesheet" href="\u2026">\` to your \`index.html\` yourself (or pass \`themeToCss(theme, { includeFontImport: true })\` when the result is a standalone stylesheet).
828
+
829
+ ### Apply a theme
830
+
831
+ - **Build-time / SSR:** \`themeToCss(theme)\` \u2192 paste the returned CSS into your \`index.css\` (after the \`@import "@timbal-ai/timbal-react/styles.css"\`). One block, both modes.
832
+ - **Runtime / swappable:** \`applyTimbalTheme(theme)\` injects a managed \`<style>\` and returns a disposer. Works with the \`.dark\` toggle (next-themes / ModeToggle).
833
+ - **Component:** render \`<TimbalThemeStyle theme={theme} />\` (or \`preset="indigo"\`) once near the app root.
834
+
835
+ ### Offer styles to the user ("show compatible styles, then apply")
836
+
837
+ Use the closed preset catalog \u2014 do not invent options:
838
+
839
+ \`\`\`ts
840
+ import { TIMBAL_THEME_PRESETS, applyThemePreset } from "@timbal-ai/timbal-react";
841
+ // TIMBAL_THEME_PRESETS: { id, label, description, swatch, tokens }[]
842
+ \`\`\`
843
+
844
+ Each preset is a **full personality** (color + radius + shadows + font), not just a color:
845
+
846
+ | Preset id | Personality |
847
+ |-----------|-------------|
848
+ | \`platform\` | Neutral monochrome, system font (the default \u2014 no brand) |
849
+ | \`indigo\` | Blue-violet, Geist, generous radius, soft shadows \u2014 analytics / ops |
850
+ | \`violet\` | Purple, Sora, rounded \u2014 product / marketing |
851
+ | \`forest\` | Green, Lexend, compact \u2014 finance / sustainability |
852
+ | \`warm\` | Orange, Lexend, friendly \u2014 consumer / creative |
853
+ | \`slate\` | Enterprise gray-blue, Inter, tight radius, hairline shadows |
854
+ | \`folio\` | Editorial serif (Fraunces), near-sharp corners \u2014 content / docs |
855
+ | \`carbon\` | Terminal monospace (JetBrains Mono), green accent \u2014 dev / infra |
856
+
857
+ - To present options visually, render \`<ThemePresetGallery value={id} onSelect={setId} />\` \u2014 each swatch previews real components (Button + metric tile) scoped via \`data-timbal-theme\`, so the live app doesn't change until the user picks.
858
+ - On selection, call \`applyThemePreset(id)\` (persists to \`localStorage\` and restores on reload).
859
+
860
+ ### Rules
861
+
862
+ - Generated pages use **semantic Tailwind tokens only** \u2014 never literal colors or per-element \`style={{ color }}\`.
863
+ - Light/dark mode stays the \`.dark\` class (\`next-themes attribute="class"\` or \`ModeToggle\`). Presets are **brand**, not a second dark-mode system.
864
+ - Override individual tokens only for one-offs the generator doesn't cover; if you must, set the variable in **both** \`:root\` and \`.dark\` (a dev-only warning fires otherwise).
865
+ `.trim();
866
+
867
+ // src/app/theme/TimbalThemeStyle.tsx
868
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
869
+ var TimbalThemeStyle = ({
870
+ theme,
871
+ preset,
872
+ scope,
873
+ nonce
874
+ }) => {
875
+ const tokens = theme ?? (preset ? getThemePreset(preset)?.tokens : void 0);
876
+ if (!tokens) return null;
877
+ const css = themeToCss(tokens, scope ? { scope } : void 0);
878
+ if (!css) return null;
879
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
880
+ tokens.fontImportUrl ? /* @__PURE__ */ jsx("link", { rel: "stylesheet", href: tokens.fontImportUrl }) : null,
881
+ /* @__PURE__ */ jsx(
882
+ "style",
883
+ {
884
+ "data-timbal-theme-style": scope ?? "root",
885
+ nonce,
886
+ dangerouslySetInnerHTML: { __html: css }
887
+ }
888
+ )
889
+ ] });
890
+ };
891
+
892
+ // src/app/data/metrics-shared.tsx
893
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
894
+ var metricCardShellClass = cn(
895
+ studioIntegrationCardClass,
896
+ "aui-app-metric-card shadow-none",
897
+ "flex flex-col overflow-hidden"
898
+ );
899
+ var metricCardHeaderClass = "flex items-start justify-between gap-3 px-4 pb-1 pt-3";
900
+ var metricTilesRowClass = "grid w-full min-w-0";
901
+ var metricChartRegionClass = "relative min-h-0 w-full border-t border-border/40 pt-2";
902
+ var metricChartPlotRegionClass = "relative min-h-0 w-full border-t border-border/40 px-0 pt-5 pb-3";
903
+ var metricCellDividerClass = "border-r border-border/40";
904
+ var MetricCardHeader = ({
905
+ title,
906
+ titleId,
907
+ description,
908
+ actions
909
+ }) => {
910
+ if (!title && !description && !actions) return null;
911
+ return /* @__PURE__ */ jsxs2("header", { className: metricCardHeaderClass, children: [
912
+ /* @__PURE__ */ jsxs2("div", { className: "min-w-0", children: [
913
+ title ? /* @__PURE__ */ jsx2("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
914
+ description ? /* @__PURE__ */ jsx2("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
915
+ ] }),
916
+ actions ? /* @__PURE__ */ jsx2("div", { className: "shrink-0", children: actions }) : null
917
+ ] });
918
+ };
919
+ function metricTilesGridColsClass(n) {
920
+ switch (n) {
921
+ case 1:
922
+ return "grid-cols-1";
923
+ case 2:
924
+ return "grid-cols-2";
925
+ case 3:
926
+ return "grid-cols-3";
927
+ case 5:
928
+ return "grid-cols-2 sm:grid-cols-5";
929
+ case 6:
930
+ return "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6";
931
+ default:
932
+ return "grid-cols-2 md:grid-cols-4";
933
+ }
934
+ }
935
+
936
+ // src/app/data/MetricTile.tsx
937
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
938
+ var trendToneClass = {
939
+ up: "border-border/80 bg-muted/40 text-muted-foreground",
940
+ down: "border-border/80 bg-muted/40 text-muted-foreground",
941
+ neutral: "border-border/80 bg-muted/30 text-muted-foreground"
942
+ };
943
+ var metricTileBaseClass = "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal";
944
+ var metricTileInteractiveClass = cn(
945
+ metricTileBaseClass,
946
+ "bg-transparent hover:bg-transparent active:bg-transparent",
947
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10"
948
+ );
949
+ var MetricTile = ({
950
+ label,
951
+ value,
952
+ unit,
953
+ trend,
954
+ trendTone = "neutral",
955
+ active = false,
956
+ showDivider = false,
957
+ onSelect,
958
+ ariaLabel,
959
+ className
960
+ }) => {
961
+ const content = /* @__PURE__ */ jsxs3(Fragment2, { children: [
962
+ active ? /* @__PURE__ */ jsx3(
963
+ "span",
964
+ {
965
+ "aria-hidden": true,
966
+ className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground dark:bg-white"
967
+ }
968
+ ) : null,
969
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
970
+ /* @__PURE__ */ jsxs3("span", { className: "flex items-center gap-2", children: [
971
+ /* @__PURE__ */ jsxs3("span", { className: "flex items-baseline gap-1", children: [
972
+ /* @__PURE__ */ jsx3("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
973
+ unit ? /* @__PURE__ */ jsx3("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
974
+ ] }),
975
+ trend ? /* @__PURE__ */ jsx3(
976
+ "span",
977
+ {
978
+ className: cn(
979
+ "rounded-full border px-1.5 py-0.5 text-xs font-normal",
980
+ trendToneClass[trendTone]
981
+ ),
982
+ children: trend
983
+ }
984
+ ) : null
985
+ ] })
986
+ ] });
987
+ const divider = showDivider ? metricCellDividerClass : void 0;
988
+ if (onSelect) {
989
+ return /* @__PURE__ */ jsx3(
990
+ "button",
991
+ {
992
+ type: "button",
993
+ onClick: onSelect,
994
+ "aria-pressed": active,
995
+ "aria-label": ariaLabel,
996
+ className: cn(metricTileInteractiveClass, divider, className),
997
+ children: content
998
+ }
999
+ );
1000
+ }
1001
+ return /* @__PURE__ */ jsx3("div", { className: cn(metricTileBaseClass, divider, className), children: content });
1002
+ };
1003
+
1004
+ // src/app/theme/ThemePresetGallery.tsx
1005
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1006
+ var ThemePresetGallery = ({
1007
+ value,
1008
+ onSelect,
1009
+ presets,
1010
+ className
1011
+ }) => {
1012
+ const items = presets ? TIMBAL_THEME_PRESETS.filter((p) => presets.includes(p.id)) : TIMBAL_THEME_PRESETS;
1013
+ return /* @__PURE__ */ jsx4(
1014
+ "div",
1015
+ {
1016
+ role: "radiogroup",
1017
+ "aria-label": "Theme presets",
1018
+ className: cn(
1019
+ "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",
1020
+ className
1021
+ ),
1022
+ children: items.map((preset) => {
1023
+ const selected = value === preset.id;
1024
+ return /* @__PURE__ */ jsxs4("div", { "data-timbal-theme": preset.id, children: [
1025
+ /* @__PURE__ */ jsx4(TimbalThemeStyle, { preset: preset.id, scope: preset.id }),
1026
+ /* @__PURE__ */ jsxs4(
1027
+ "button",
1028
+ {
1029
+ type: "button",
1030
+ role: "radio",
1031
+ "aria-checked": selected,
1032
+ "aria-label": `${preset.label} theme`,
1033
+ onClick: () => onSelect?.(preset.id),
1034
+ className: cn(
1035
+ "group flex w-full flex-col gap-3 rounded-xl border bg-card p-3 text-left transition-colors",
1036
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1037
+ selected ? "border-primary ring-2 ring-primary/30" : "border-border hover:border-foreground/30"
1038
+ ),
1039
+ children: [
1040
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-2", children: [
1041
+ /* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-2", children: [
1042
+ /* @__PURE__ */ jsx4(
1043
+ "span",
1044
+ {
1045
+ "aria-hidden": true,
1046
+ className: "size-4 shrink-0 rounded-full ring-1 ring-black/10",
1047
+ style: { background: preset.swatch }
1048
+ }
1049
+ ),
1050
+ /* @__PURE__ */ jsx4("span", { className: "text-sm font-medium text-foreground", children: preset.label })
1051
+ ] }),
1052
+ selected ? /* @__PURE__ */ jsx4("span", { className: "text-xs font-medium text-primary", children: "Selected" }) : null
1053
+ ] }),
1054
+ /* @__PURE__ */ jsx4("p", { className: "text-xs leading-snug text-muted-foreground", children: preset.description }),
1055
+ preset.font ? /* @__PURE__ */ jsxs4("span", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: [
1056
+ "Aa \xB7 ",
1057
+ preset.font
1058
+ ] }) : null,
1059
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-2 rounded-lg border border-border bg-background p-2", children: [
1060
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1061
+ /* @__PURE__ */ jsx4(Button, { size: "xs", className: "pointer-events-none", children: "Primary" }),
1062
+ /* @__PURE__ */ jsx4("span", { className: "size-5 rounded-md bg-primary", "aria-hidden": true }),
1063
+ /* @__PURE__ */ jsx4("span", { className: "size-5 rounded-md bg-muted", "aria-hidden": true }),
1064
+ /* @__PURE__ */ jsx4(
1065
+ "span",
1066
+ {
1067
+ className: "size-5 rounded-md border border-border bg-accent",
1068
+ "aria-hidden": true
1069
+ }
1070
+ )
1071
+ ] }),
1072
+ /* @__PURE__ */ jsx4(MetricTile, { label: "Active users", value: "1,248", trend: "+8%" })
1073
+ ] })
1074
+ ]
1075
+ }
1076
+ )
1077
+ ] }, preset.id);
1078
+ })
1079
+ }
1080
+ );
1081
+ };
1082
+
221
1083
  // src/design/app-classes.ts
222
1084
  var appPageColumnClass = "mx-auto w-full max-w-6xl px-4 md:px-6";
223
1085
  var appShellTopbarInsetClass = "w-full px-4 md:px-6";
@@ -282,7 +1144,7 @@ function useAppShellChat() {
282
1144
  // src/app/layout/AppShell.tsx
283
1145
  import { motion, useReducedMotion } from "motion/react";
284
1146
  import { useCallback, useState } from "react";
285
- import { jsx, jsxs } from "react/jsx-runtime";
1147
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
286
1148
  var floatingTriggerClass = cn(
287
1149
  "aui-app-shell-chat-trigger-fixed fixed z-50 rounded-full px-5 py-2.5 text-sm font-medium shadow-card-elevated",
288
1150
  "bg-primary text-primary-foreground transition-colors hover:bg-primary/90",
@@ -311,14 +1173,14 @@ var AppShellBody = ({
311
1173
  layoutDirection
312
1174
  );
313
1175
  const insetPadding = sidebar ? insetPaddingPx : 0;
314
- return /* @__PURE__ */ jsx(
1176
+ return /* @__PURE__ */ jsx5(
315
1177
  motion.div,
316
1178
  {
317
1179
  className: "aui-app-shell-body relative z-10 flex min-h-0 min-w-0 flex-1 flex-col",
318
1180
  initial: false,
319
1181
  animate: { paddingLeft: insetPadding },
320
1182
  transition: layoutTransition,
321
- children: /* @__PURE__ */ jsxs(
1183
+ children: /* @__PURE__ */ jsxs5(
322
1184
  "div",
323
1185
  {
324
1186
  className: cn(
@@ -326,8 +1188,8 @@ var AppShellBody = ({
326
1188
  !topbarContent && appShellInsetTopClass
327
1189
  ),
328
1190
  children: [
329
- topbarContent ? /* @__PURE__ */ jsx("header", { className: cn("aui-app-shell-topbar-region", appShellTopbarStickyClass), children: /* @__PURE__ */ jsx("div", { className: appShellTopbarInsetClass, children: topbarContent }) }) : null,
330
- /* @__PURE__ */ jsx("main", { className: cn("aui-app-shell-main min-w-0 flex-1", mainClassName), children })
1191
+ topbarContent ? /* @__PURE__ */ jsx5("header", { className: cn("aui-app-shell-topbar-region", appShellTopbarStickyClass), children: /* @__PURE__ */ jsx5("div", { className: appShellTopbarInsetClass, children: topbarContent }) }) : null,
1192
+ /* @__PURE__ */ jsx5("main", { className: cn("aui-app-shell-main min-w-0 flex-1", mainClassName), children })
331
1193
  ]
332
1194
  }
333
1195
  )
@@ -375,7 +1237,7 @@ var AppShell = ({
375
1237
  setInsetPaddingPx(insetPx);
376
1238
  }, []);
377
1239
  const insetExpanded = insetPaddingPx >= SIDEBAR_INSET_PX_EXPANDED;
378
- const shellBody = /* @__PURE__ */ jsx(
1240
+ const shellBody = /* @__PURE__ */ jsx5(
379
1241
  AppShellBody,
380
1242
  {
381
1243
  sidebar,
@@ -386,7 +1248,7 @@ var AppShell = ({
386
1248
  children
387
1249
  }
388
1250
  );
389
- const tree = /* @__PURE__ */ jsx(ShellInsetProvider, { value: sidebar ? reportShellInset : null, children: /* @__PURE__ */ jsxs(
1251
+ const tree = /* @__PURE__ */ jsx5(ShellInsetProvider, { value: sidebar ? reportShellInset : null, children: /* @__PURE__ */ jsxs5(
390
1252
  "div",
391
1253
  {
392
1254
  className: cn(
@@ -397,7 +1259,7 @@ var AppShell = ({
397
1259
  children: [
398
1260
  sidebar,
399
1261
  shellBody,
400
- hasChat && chatOpen ? /* @__PURE__ */ jsx(
1262
+ hasChat && chatOpen ? /* @__PURE__ */ jsx5(
401
1263
  "div",
402
1264
  {
403
1265
  className: floatingPanelClass,
@@ -410,7 +1272,7 @@ var AppShell = ({
410
1272
  children: chat
411
1273
  }
412
1274
  ) : null,
413
- hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */ jsx(
1275
+ hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */ jsx5(
414
1276
  "button",
415
1277
  {
416
1278
  type: "button",
@@ -426,7 +1288,7 @@ var AppShell = ({
426
1288
  if (!hasChat) {
427
1289
  return tree;
428
1290
  }
429
- return /* @__PURE__ */ jsx(
1291
+ return /* @__PURE__ */ jsx5(
430
1292
  AppShellChatProvider,
431
1293
  {
432
1294
  value: {
@@ -441,24 +1303,24 @@ var AppShell = ({
441
1303
  };
442
1304
 
443
1305
  // src/app/layout/AppShellTopbar.tsx
444
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1306
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
445
1307
  var AppShellTopbar = ({
446
1308
  start,
447
1309
  actions,
448
1310
  children,
449
1311
  className
450
1312
  }) => {
451
- return /* @__PURE__ */ jsxs2("div", { className: cn("aui-app-shell-topbar", appShellTopbarRowClass, className), children: [
452
- /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
1313
+ return /* @__PURE__ */ jsxs6("div", { className: cn("aui-app-shell-topbar", appShellTopbarRowClass, className), children: [
1314
+ /* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
453
1315
  start,
454
1316
  children
455
1317
  ] }),
456
- actions ? /* @__PURE__ */ jsx2("div", { className: "aui-app-shell-topbar-actions flex shrink-0 items-center gap-2", children: actions }) : null
1318
+ actions ? /* @__PURE__ */ jsx6("div", { className: "aui-app-shell-topbar-actions flex shrink-0 items-center gap-2", children: actions }) : null
457
1319
  ] });
458
1320
  };
459
1321
 
460
1322
  // src/app/layout/AppShellChatTrigger.tsx
461
- import { jsx as jsx3 } from "react/jsx-runtime";
1323
+ import { jsx as jsx7 } from "react/jsx-runtime";
462
1324
  var floatingPositionClass = "fixed bottom-6 right-6 z-50 max-sm:bottom-4 max-sm:right-4";
463
1325
  var AppShellChatTrigger = ({
464
1326
  className,
@@ -467,7 +1329,7 @@ var AppShellChatTrigger = ({
467
1329
  }) => {
468
1330
  const shellChat = useAppShellChat();
469
1331
  if (!shellChat || shellChat.open) return null;
470
- return /* @__PURE__ */ jsx3(
1332
+ return /* @__PURE__ */ jsx7(
471
1333
  TimbalV2Button,
472
1334
  {
473
1335
  type: "button",
@@ -487,61 +1349,61 @@ var AppShellChatTrigger = ({
487
1349
  };
488
1350
 
489
1351
  // src/app/layout/PageHeader.tsx
490
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1352
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
491
1353
  var PageHeader = ({
492
1354
  title,
493
1355
  description,
494
1356
  actions,
495
1357
  className
496
1358
  }) => {
497
- return /* @__PURE__ */ jsxs3("header", { className: cn("aui-app-page-header", appPageHeaderClass, className), children: [
498
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0", children: [
499
- /* @__PURE__ */ jsx4("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: title }),
500
- description ? /* @__PURE__ */ jsx4("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
1359
+ return /* @__PURE__ */ jsxs7("header", { className: cn("aui-app-page-header", appPageHeaderClass, className), children: [
1360
+ /* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
1361
+ /* @__PURE__ */ jsx8("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: title }),
1362
+ description ? /* @__PURE__ */ jsx8("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
501
1363
  ] }),
502
- actions ? /* @__PURE__ */ jsx4("div", { className: "aui-app-page-header-actions flex shrink-0 flex-wrap items-center gap-2", children: actions }) : null
1364
+ actions ? /* @__PURE__ */ jsx8("div", { className: "aui-app-page-header-actions flex shrink-0 flex-wrap items-center gap-2", children: actions }) : null
503
1365
  ] });
504
1366
  };
505
1367
 
506
1368
  // src/app/layout/Page.tsx
507
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1369
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
508
1370
  var Page = ({
509
1371
  children,
510
1372
  breadcrumbs,
511
1373
  className,
512
1374
  ...headerProps
513
1375
  }) => {
514
- return /* @__PURE__ */ jsxs4("div", { className: cn("aui-app-page", appPageColumnClass, className), children: [
1376
+ return /* @__PURE__ */ jsxs8("div", { className: cn("aui-app-page", appPageColumnClass, className), children: [
515
1377
  breadcrumbs,
516
- /* @__PURE__ */ jsx5(PageHeader, { ...headerProps }),
1378
+ /* @__PURE__ */ jsx9(PageHeader, { ...headerProps }),
517
1379
  children
518
1380
  ] });
519
1381
  };
520
1382
 
521
1383
  // src/app/layout/Section.tsx
522
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1384
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
523
1385
  var Section = ({
524
1386
  title,
525
1387
  description,
526
1388
  children,
527
1389
  className
528
1390
  }) => {
529
- return /* @__PURE__ */ jsxs5("section", { className: cn("aui-app-section", appSectionClass, className), children: [
530
- title ? /* @__PURE__ */ jsx6("h2", { className: appSectionTitleClass, children: title }) : null,
531
- description ? /* @__PURE__ */ jsx6("p", { className: appSectionDescriptionClass, children: description }) : null,
1391
+ return /* @__PURE__ */ jsxs9("section", { className: cn("aui-app-section", appSectionClass, className), children: [
1392
+ title ? /* @__PURE__ */ jsx10("h2", { className: appSectionTitleClass, children: title }) : null,
1393
+ description ? /* @__PURE__ */ jsx10("p", { className: appSectionDescriptionClass, children: description }) : null,
532
1394
  children
533
1395
  ] });
534
1396
  };
535
1397
 
536
1398
  // src/app/copilot/app-copilot-context.tsx
537
1399
  import { createContext as createContext2, useContext as useContext2 } from "react";
538
- import { jsx as jsx7 } from "react/jsx-runtime";
1400
+ import { jsx as jsx11 } from "react/jsx-runtime";
539
1401
  var AppCopilotContext = createContext2(null);
540
1402
  var AppCopilotProvider = ({
541
1403
  value,
542
1404
  children
543
1405
  }) => {
544
- return /* @__PURE__ */ jsx7(AppCopilotContext.Provider, { value, children });
1406
+ return /* @__PURE__ */ jsx11(AppCopilotContext.Provider, { value, children });
545
1407
  };
546
1408
  function useAppCopilotContext() {
547
1409
  return useContext2(AppCopilotContext) ?? {};
@@ -549,7 +1411,7 @@ function useAppCopilotContext() {
549
1411
 
550
1412
  // src/app/chat/AppChatPanel.tsx
551
1413
  import { XIcon } from "lucide-react";
552
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1414
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
553
1415
  var shellClass = "aui-app-chat-panel flex h-full min-h-0 flex-col overflow-hidden";
554
1416
  var chromeClass = cn(
555
1417
  "aui-app-chat-panel-chrome relative z-20 flex min-h-10 shrink-0 items-center justify-end px-2 pt-2"
@@ -594,18 +1456,18 @@ var AppChatPanel = ({
594
1456
  ...rest
595
1457
  }) => {
596
1458
  const shellChat = useAppShellChat();
597
- return /* @__PURE__ */ jsxs6("div", { className: cn(shellClass, className), children: [
598
- shellChat?.collapsible ? /* @__PURE__ */ jsx8("div", { className: chromeClass, children: /* @__PURE__ */ jsx8(
1459
+ return /* @__PURE__ */ jsxs10("div", { className: cn(shellClass, className), children: [
1460
+ shellChat?.collapsible ? /* @__PURE__ */ jsx12("div", { className: chromeClass, children: /* @__PURE__ */ jsx12(
599
1461
  "button",
600
1462
  {
601
1463
  type: "button",
602
1464
  className: closeButtonClass,
603
1465
  onClick: () => shellChat.setOpen(false),
604
1466
  "aria-label": "Close assistant",
605
- children: /* @__PURE__ */ jsx8(XIcon, { className: "size-4", "aria-hidden": true })
1467
+ children: /* @__PURE__ */ jsx12(XIcon, { className: "size-4", "aria-hidden": true })
606
1468
  }
607
1469
  ) }) : null,
608
- /* @__PURE__ */ jsx8("div", { className: bodyClass, children: /* @__PURE__ */ jsx8(
1470
+ /* @__PURE__ */ jsx12("div", { className: bodyClass, children: /* @__PURE__ */ jsx12(
609
1471
  TimbalRuntimeProvider,
610
1472
  {
611
1473
  workforceId,
@@ -615,7 +1477,7 @@ var AppChatPanel = ({
615
1477
  attachmentsUploadUrl,
616
1478
  attachmentsAccept,
617
1479
  debug,
618
- children: /* @__PURE__ */ jsx8(
1480
+ children: /* @__PURE__ */ jsx12(
619
1481
  Thread,
620
1482
  {
621
1483
  variant: "panel",
@@ -636,38 +1498,38 @@ var AppChatPanel = ({
636
1498
  };
637
1499
 
638
1500
  // src/app/surfaces/SurfaceCard.tsx
639
- import { jsx as jsx9 } from "react/jsx-runtime";
1501
+ import { jsx as jsx13 } from "react/jsx-runtime";
640
1502
  var SurfaceCard = ({ children, className }) => {
641
- return /* @__PURE__ */ jsx9("div", { className: cn("aui-app-surface-card", appSurfaceCardClass, className), children });
1503
+ return /* @__PURE__ */ jsx13("div", { className: cn("aui-app-surface-card", appSurfaceCardClass, className), children });
642
1504
  };
643
1505
 
644
1506
  // src/app/surfaces/StatTile.tsx
645
- import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
1507
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
646
1508
  var StatTile = ({ label, value, hint, className }) => {
647
- return /* @__PURE__ */ jsxs7("div", { className: cn("aui-app-stat-tile", appStatTileClass, className), children: [
648
- /* @__PURE__ */ jsx10("span", { className: appStatLabelClass, children: label }),
649
- /* @__PURE__ */ jsx10("span", { className: appStatValueClass, children: value }),
650
- hint ? /* @__PURE__ */ jsx10("span", { className: "text-xs text-muted-foreground", children: hint }) : null
1509
+ return /* @__PURE__ */ jsxs11("div", { className: cn("aui-app-stat-tile", appStatTileClass, className), children: [
1510
+ /* @__PURE__ */ jsx14("span", { className: appStatLabelClass, children: label }),
1511
+ /* @__PURE__ */ jsx14("span", { className: appStatValueClass, children: value }),
1512
+ hint ? /* @__PURE__ */ jsx14("span", { className: "text-xs text-muted-foreground", children: hint }) : null
651
1513
  ] });
652
1514
  };
653
1515
 
654
1516
  // src/app/surfaces/EmptyState.tsx
655
- import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
1517
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
656
1518
  var EmptyState = ({
657
1519
  title,
658
1520
  description,
659
1521
  action,
660
1522
  className
661
1523
  }) => {
662
- return /* @__PURE__ */ jsxs8("div", { className: cn("aui-app-empty-state", appEmptyStateClass, className), children: [
663
- /* @__PURE__ */ jsx11("p", { className: appEmptyStateTitleClass, children: title }),
664
- description ? /* @__PURE__ */ jsx11("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
1524
+ return /* @__PURE__ */ jsxs12("div", { className: cn("aui-app-empty-state", appEmptyStateClass, className), children: [
1525
+ /* @__PURE__ */ jsx15("p", { className: appEmptyStateTitleClass, children: title }),
1526
+ description ? /* @__PURE__ */ jsx15("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
665
1527
  action
666
1528
  ] });
667
1529
  };
668
1530
 
669
1531
  // src/app/surfaces/StatusBadge.tsx
670
- import { jsx as jsx12 } from "react/jsx-runtime";
1532
+ import { jsx as jsx16 } from "react/jsx-runtime";
671
1533
  var statusBadgeToneClass = {
672
1534
  default: "bg-muted text-foreground",
673
1535
  primary: "bg-primary/10 text-primary",
@@ -680,7 +1542,7 @@ var StatusBadge = ({
680
1542
  tone = "default",
681
1543
  className
682
1544
  }) => {
683
- return /* @__PURE__ */ jsx12(
1545
+ return /* @__PURE__ */ jsx16(
684
1546
  "span",
685
1547
  {
686
1548
  className: cn(
@@ -694,7 +1556,7 @@ var StatusBadge = ({
694
1556
  };
695
1557
 
696
1558
  // src/app/surfaces/AppConfirmDialog.tsx
697
- import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
1559
+ import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
698
1560
  var bodyClass2 = "flex flex-col gap-4 p-6";
699
1561
  var titleClass = "pr-8";
700
1562
  var actionsClass = "flex flex-wrap justify-end gap-2";
@@ -709,15 +1571,15 @@ var AppConfirmDialog = ({
709
1571
  destructive = false,
710
1572
  className
711
1573
  }) => {
712
- return /* @__PURE__ */ jsx13(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx13(
1574
+ return /* @__PURE__ */ jsx17(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx17(
713
1575
  DialogContent,
714
1576
  {
715
1577
  className: cn("gap-0 p-0 sm:max-w-md", className),
716
- children: /* @__PURE__ */ jsxs9("div", { className: bodyClass2, children: [
717
- /* @__PURE__ */ jsx13(DialogTitle, { className: titleClass, children: title }),
718
- description ? /* @__PURE__ */ jsx13("p", { className: "text-sm text-muted-foreground", children: description }) : null,
719
- /* @__PURE__ */ jsxs9("div", { className: actionsClass, children: [
720
- /* @__PURE__ */ jsx13(
1578
+ children: /* @__PURE__ */ jsxs13("div", { className: bodyClass2, children: [
1579
+ /* @__PURE__ */ jsx17(DialogTitle, { className: titleClass, children: title }),
1580
+ description ? /* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground", children: description }) : null,
1581
+ /* @__PURE__ */ jsxs13("div", { className: actionsClass, children: [
1582
+ /* @__PURE__ */ jsx17(
721
1583
  TimbalV2Button,
722
1584
  {
723
1585
  type: "button",
@@ -727,7 +1589,7 @@ var AppConfirmDialog = ({
727
1589
  children: cancelLabel
728
1590
  }
729
1591
  ),
730
- /* @__PURE__ */ jsx13(
1592
+ /* @__PURE__ */ jsx17(
731
1593
  TimbalV2Button,
732
1594
  {
733
1595
  type: "button",
@@ -747,7 +1609,7 @@ var AppConfirmDialog = ({
747
1609
  };
748
1610
 
749
1611
  // src/app/surfaces/InfoCard.tsx
750
- import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
1612
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
751
1613
  var toneClass = {
752
1614
  neutral: "border-border bg-muted/40",
753
1615
  info: "border-primary/25 bg-primary/5",
@@ -762,7 +1624,7 @@ var InfoCard = ({
762
1624
  action,
763
1625
  tone = "neutral",
764
1626
  className
765
- }) => /* @__PURE__ */ jsxs10(
1627
+ }) => /* @__PURE__ */ jsxs14(
766
1628
  "div",
767
1629
  {
768
1630
  className: cn(
@@ -771,18 +1633,18 @@ var InfoCard = ({
771
1633
  className
772
1634
  ),
773
1635
  children: [
774
- icon ? /* @__PURE__ */ jsx14("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: icon }) : null,
775
- /* @__PURE__ */ jsxs10("div", { className: "min-w-0 flex-1", children: [
776
- title ? /* @__PURE__ */ jsx14("p", { className: "text-sm font-medium text-foreground", children: title }) : null,
777
- children ? /* @__PURE__ */ jsx14("div", { className: cn("text-sm text-muted-foreground", title && "mt-1"), children }) : null
1636
+ icon ? /* @__PURE__ */ jsx18("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: icon }) : null,
1637
+ /* @__PURE__ */ jsxs14("div", { className: "min-w-0 flex-1", children: [
1638
+ title ? /* @__PURE__ */ jsx18("p", { className: "text-sm font-medium text-foreground", children: title }) : null,
1639
+ children ? /* @__PURE__ */ jsx18("div", { className: cn("text-sm text-muted-foreground", title && "mt-1"), children }) : null
778
1640
  ] }),
779
- action ? /* @__PURE__ */ jsx14("div", { className: "shrink-0", children: action }) : null
1641
+ action ? /* @__PURE__ */ jsx18("div", { className: "shrink-0", children: action }) : null
780
1642
  ]
781
1643
  }
782
1644
  );
783
1645
 
784
1646
  // src/app/surfaces/StatusDot.tsx
785
- import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
1647
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
786
1648
  var dotClass = {
787
1649
  online: "bg-emerald-500",
788
1650
  busy: "bg-amber-500",
@@ -795,9 +1657,9 @@ var StatusDot = ({
795
1657
  label,
796
1658
  pulse = false,
797
1659
  className
798
- }) => /* @__PURE__ */ jsxs11("span", { className: cn("inline-flex items-center gap-1.5", className), children: [
799
- /* @__PURE__ */ jsxs11("span", { className: "relative flex size-2", children: [
800
- pulse ? /* @__PURE__ */ jsx15(
1660
+ }) => /* @__PURE__ */ jsxs15("span", { className: cn("inline-flex items-center gap-1.5", className), children: [
1661
+ /* @__PURE__ */ jsxs15("span", { className: "relative flex size-2", children: [
1662
+ pulse ? /* @__PURE__ */ jsx19(
801
1663
  "span",
802
1664
  {
803
1665
  className: cn(
@@ -806,25 +1668,25 @@ var StatusDot = ({
806
1668
  )
807
1669
  }
808
1670
  ) : null,
809
- /* @__PURE__ */ jsx15("span", { className: cn("relative inline-flex size-2 rounded-full", dotClass[tone]) })
1671
+ /* @__PURE__ */ jsx19("span", { className: cn("relative inline-flex size-2 rounded-full", dotClass[tone]) })
810
1672
  ] }),
811
- label ? /* @__PURE__ */ jsx15("span", { className: "text-xs text-muted-foreground", children: label }) : null
1673
+ label ? /* @__PURE__ */ jsx19("span", { className: "text-xs text-muted-foreground", children: label }) : null
812
1674
  ] });
813
1675
 
814
1676
  // src/app/surfaces/DescriptionList.tsx
815
- import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
1677
+ import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
816
1678
  var DescriptionList = ({
817
1679
  items,
818
1680
  stacked = false,
819
1681
  className
820
- }) => /* @__PURE__ */ jsx16(
1682
+ }) => /* @__PURE__ */ jsx20(
821
1683
  "dl",
822
1684
  {
823
1685
  className: cn(
824
1686
  "divide-y divide-border rounded-xl border border-border bg-card",
825
1687
  className
826
1688
  ),
827
- children: items.map((item, i) => /* @__PURE__ */ jsxs12(
1689
+ children: items.map((item, i) => /* @__PURE__ */ jsxs16(
828
1690
  "div",
829
1691
  {
830
1692
  className: cn(
@@ -832,8 +1694,8 @@ var DescriptionList = ({
832
1694
  stacked ? "flex flex-col gap-0.5" : "flex items-center justify-between gap-4"
833
1695
  ),
834
1696
  children: [
835
- /* @__PURE__ */ jsx16("dt", { className: "text-sm text-muted-foreground", children: item.label }),
836
- /* @__PURE__ */ jsx16(
1697
+ /* @__PURE__ */ jsx20("dt", { className: "text-sm text-muted-foreground", children: item.label }),
1698
+ /* @__PURE__ */ jsx20(
837
1699
  "dd",
838
1700
  {
839
1701
  className: cn(
@@ -853,8 +1715,8 @@ var DescriptionList = ({
853
1715
  // src/app/surfaces/ExpandableSection.tsx
854
1716
  import { useId, useState as useState2 } from "react";
855
1717
  import { AnimatePresence, motion as motion2, useReducedMotion as useReducedMotion2 } from "motion/react";
856
- import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
857
- var Chevron = ({ open }) => /* @__PURE__ */ jsx17(
1718
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
1719
+ var Chevron = ({ open }) => /* @__PURE__ */ jsx21(
858
1720
  "svg",
859
1721
  {
860
1722
  viewBox: "0 0 24 24",
@@ -868,7 +1730,7 @@ var Chevron = ({ open }) => /* @__PURE__ */ jsx17(
868
1730
  strokeLinecap: "round",
869
1731
  strokeLinejoin: "round",
870
1732
  "aria-hidden": true,
871
- children: /* @__PURE__ */ jsx17("path", { d: "m6 9 6 6 6-6" })
1733
+ children: /* @__PURE__ */ jsx21("path", { d: "m6 9 6 6 6-6" })
872
1734
  }
873
1735
  );
874
1736
  var ExpandableSection = ({
@@ -889,8 +1751,8 @@ var ExpandableSection = ({
889
1751
  if (openProp == null) setInternalOpen((o) => !o);
890
1752
  onOpenChange?.(!open);
891
1753
  };
892
- return /* @__PURE__ */ jsxs13("div", { className: cn("border-b border-border last:border-0", className), children: [
893
- /* @__PURE__ */ jsxs13(
1754
+ return /* @__PURE__ */ jsxs17("div", { className: cn("border-b border-border last:border-0", className), children: [
1755
+ /* @__PURE__ */ jsxs17(
894
1756
  "button",
895
1757
  {
896
1758
  type: "button",
@@ -899,16 +1761,16 @@ var ExpandableSection = ({
899
1761
  "aria-controls": panelId,
900
1762
  className: "flex w-full items-center justify-between gap-3 bg-transparent px-4 py-3 text-left hover:bg-transparent active:bg-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10",
901
1763
  children: [
902
- /* @__PURE__ */ jsxs13("span", { className: "flex min-w-0 items-center gap-3", children: [
903
- icon ? /* @__PURE__ */ jsx17("span", { className: "flex size-8 items-center justify-center rounded-lg border border-border bg-muted text-muted-foreground", children: icon }) : null,
904
- /* @__PURE__ */ jsx17("span", { className: "truncate text-sm font-medium text-foreground", children: title }),
905
- count != null ? /* @__PURE__ */ jsx17("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-xs text-muted-foreground", children: count }) : null
1764
+ /* @__PURE__ */ jsxs17("span", { className: "flex min-w-0 items-center gap-3", children: [
1765
+ icon ? /* @__PURE__ */ jsx21("span", { className: "flex size-8 items-center justify-center rounded-lg border border-border bg-muted text-muted-foreground", children: icon }) : null,
1766
+ /* @__PURE__ */ jsx21("span", { className: "truncate text-sm font-medium text-foreground", children: title }),
1767
+ count != null ? /* @__PURE__ */ jsx21("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-xs text-muted-foreground", children: count }) : null
906
1768
  ] }),
907
- /* @__PURE__ */ jsx17(Chevron, { open })
1769
+ /* @__PURE__ */ jsx21(Chevron, { open })
908
1770
  ]
909
1771
  }
910
1772
  ),
911
- /* @__PURE__ */ jsx17(AnimatePresence, { initial: false, children: open ? /* @__PURE__ */ jsx17(
1773
+ /* @__PURE__ */ jsx21(AnimatePresence, { initial: false, children: open ? /* @__PURE__ */ jsx21(
912
1774
  motion2.div,
913
1775
  {
914
1776
  id: panelId,
@@ -917,7 +1779,7 @@ var ExpandableSection = ({
917
1779
  exit: reduceMotion ? void 0 : { height: 0, opacity: 0 },
918
1780
  transition: { duration: 0.2, ease: "easeOut" },
919
1781
  className: "overflow-hidden",
920
- children: /* @__PURE__ */ jsx17("div", { className: "bg-muted/20", children })
1782
+ children: /* @__PURE__ */ jsx21("div", { className: "bg-muted/20", children })
921
1783
  },
922
1784
  "body"
923
1785
  ) : null })
@@ -925,7 +1787,7 @@ var ExpandableSection = ({
925
1787
  };
926
1788
 
927
1789
  // src/app/surfaces/ResourceCard.tsx
928
- import { Fragment, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
1790
+ import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
929
1791
  var resourceCardShellClass = cn(
930
1792
  "flex min-h-[8.5rem] flex-col rounded-2xl p-4 text-left font-normal",
931
1793
  TIMBAL_V2_ELEVATED_SURFACE
@@ -950,35 +1812,35 @@ var ResourceCard = ({
950
1812
  ariaLabel,
951
1813
  className
952
1814
  }) => {
953
- const body = /* @__PURE__ */ jsxs14(Fragment, { children: [
954
- /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3", children: [
955
- media ? /* @__PURE__ */ jsx18("span", { className: mediaShellClass, children: media }) : null,
956
- /* @__PURE__ */ jsxs14("div", { className: "min-w-0 flex-1 pt-0.5", children: [
957
- /* @__PURE__ */ jsx18("p", { className: "truncate text-sm font-normal leading-snug text-foreground", children: title }),
958
- subtitle ? /* @__PURE__ */ jsx18("p", { className: "mt-1 line-clamp-2 text-xs font-normal text-muted-foreground", children: subtitle }) : null
1815
+ const body = /* @__PURE__ */ jsxs18(Fragment3, { children: [
1816
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-3", children: [
1817
+ media ? /* @__PURE__ */ jsx22("span", { className: mediaShellClass, children: media }) : null,
1818
+ /* @__PURE__ */ jsxs18("div", { className: "min-w-0 flex-1 pt-0.5", children: [
1819
+ /* @__PURE__ */ jsx22("p", { className: "truncate text-sm font-normal leading-snug text-foreground", children: title }),
1820
+ subtitle ? /* @__PURE__ */ jsx22("p", { className: "mt-1 line-clamp-2 text-xs font-normal text-muted-foreground", children: subtitle }) : null
959
1821
  ] }),
960
- badge ? /* @__PURE__ */ jsx18("span", { className: "shrink-0 pt-0.5", children: badge }) : null
1822
+ badge ? /* @__PURE__ */ jsx22("span", { className: "shrink-0 pt-0.5", children: badge }) : null
961
1823
  ] }),
962
- footer || action ? /* @__PURE__ */ jsxs14("div", { className: "mt-auto flex items-center justify-between gap-3 border-t border-border/40 pt-3 text-xs font-normal text-muted-foreground", children: [
963
- /* @__PURE__ */ jsx18("span", { className: "min-w-0 truncate", children: footer }),
964
- action ? /* @__PURE__ */ jsx18("span", { className: "shrink-0 opacity-80", children: action }) : null
1824
+ footer || action ? /* @__PURE__ */ jsxs18("div", { className: "mt-auto flex items-center justify-between gap-3 border-t border-border/40 pt-3 text-xs font-normal text-muted-foreground", children: [
1825
+ /* @__PURE__ */ jsx22("span", { className: "min-w-0 truncate", children: footer }),
1826
+ action ? /* @__PURE__ */ jsx22("span", { className: "shrink-0 opacity-80", children: action }) : null
965
1827
  ] }) : null
966
1828
  ] });
967
1829
  if (onClick) {
968
- return /* @__PURE__ */ jsx18("button", { type: "button", onClick, "aria-label": ariaLabel, className: cn(resourceCardInteractiveClass, className), children: body });
1830
+ return /* @__PURE__ */ jsx22("button", { type: "button", onClick, "aria-label": ariaLabel, className: cn(resourceCardInteractiveClass, className), children: body });
969
1831
  }
970
- return /* @__PURE__ */ jsx18("article", { className: cn(resourceCardShellClass, className), children: body });
1832
+ return /* @__PURE__ */ jsx22("article", { className: cn(resourceCardShellClass, className), children: body });
971
1833
  };
972
1834
 
973
1835
  // src/app/settings/SettingsSection.tsx
974
- import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
1836
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
975
1837
  var SettingsSectionHeader = ({
976
1838
  title,
977
1839
  description,
978
1840
  className
979
- }) => /* @__PURE__ */ jsxs15("div", { className: cn("flex flex-col", className), children: [
980
- /* @__PURE__ */ jsx19("h3", { className: "text-[17px] font-medium leading-tight text-foreground", children: title }),
981
- description ? /* @__PURE__ */ jsx19("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
1841
+ }) => /* @__PURE__ */ jsxs19("div", { className: cn("flex flex-col", className), children: [
1842
+ /* @__PURE__ */ jsx23("h3", { className: "text-[17px] font-medium leading-tight text-foreground", children: title }),
1843
+ description ? /* @__PURE__ */ jsx23("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
982
1844
  ] });
983
1845
  var SettingsSection = ({
984
1846
  title,
@@ -987,7 +1849,7 @@ var SettingsSection = ({
987
1849
  children,
988
1850
  noBorderTop = false,
989
1851
  className
990
- }) => /* @__PURE__ */ jsxs15(
1852
+ }) => /* @__PURE__ */ jsxs19(
991
1853
  "section",
992
1854
  {
993
1855
  className: cn(
@@ -996,18 +1858,18 @@ var SettingsSection = ({
996
1858
  className
997
1859
  ),
998
1860
  children: [
999
- /* @__PURE__ */ jsxs15("div", { className: "min-w-0", children: [
1000
- /* @__PURE__ */ jsx19("h2", { className: "text-sm font-medium text-foreground", children: title }),
1001
- description ? /* @__PURE__ */ jsx19("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null,
1002
- descriptionFooter ? /* @__PURE__ */ jsx19("div", { className: "mt-3 min-w-0", children: descriptionFooter }) : null
1861
+ /* @__PURE__ */ jsxs19("div", { className: "min-w-0", children: [
1862
+ /* @__PURE__ */ jsx23("h2", { className: "text-sm font-medium text-foreground", children: title }),
1863
+ description ? /* @__PURE__ */ jsx23("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null,
1864
+ descriptionFooter ? /* @__PURE__ */ jsx23("div", { className: "mt-3 min-w-0", children: descriptionFooter }) : null
1003
1865
  ] }),
1004
- /* @__PURE__ */ jsx19("div", { className: "min-w-0 space-y-3", children })
1866
+ /* @__PURE__ */ jsx23("div", { className: "min-w-0 space-y-3", children })
1005
1867
  ]
1006
1868
  }
1007
1869
  );
1008
1870
 
1009
1871
  // src/app/settings/FieldRow.tsx
1010
- import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
1872
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
1011
1873
  var FieldRow = ({
1012
1874
  label,
1013
1875
  children,
@@ -1017,7 +1879,7 @@ var FieldRow = ({
1017
1879
  className
1018
1880
  }) => {
1019
1881
  if (inline) {
1020
- return /* @__PURE__ */ jsxs16(
1882
+ return /* @__PURE__ */ jsxs20(
1021
1883
  "div",
1022
1884
  {
1023
1885
  className: cn(
@@ -1025,8 +1887,8 @@ var FieldRow = ({
1025
1887
  className
1026
1888
  ),
1027
1889
  children: [
1028
- /* @__PURE__ */ jsxs16("div", { className: "min-w-0", children: [
1029
- /* @__PURE__ */ jsx20(
1890
+ /* @__PURE__ */ jsxs20("div", { className: "min-w-0", children: [
1891
+ /* @__PURE__ */ jsx24(
1030
1892
  "label",
1031
1893
  {
1032
1894
  htmlFor,
@@ -1034,17 +1896,17 @@ var FieldRow = ({
1034
1896
  children: label
1035
1897
  }
1036
1898
  ),
1037
- description ? /* @__PURE__ */ jsx20("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }) : null
1899
+ description ? /* @__PURE__ */ jsx24("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }) : null
1038
1900
  ] }),
1039
- /* @__PURE__ */ jsx20("div", { className: "shrink-0", children })
1901
+ /* @__PURE__ */ jsx24("div", { className: "shrink-0", children })
1040
1902
  ]
1041
1903
  }
1042
1904
  );
1043
1905
  }
1044
- return /* @__PURE__ */ jsxs16("div", { className: cn("flex flex-col gap-1.5", className), children: [
1045
- /* @__PURE__ */ jsx20("label", { htmlFor, className: "text-sm font-medium text-foreground", children: label }),
1906
+ return /* @__PURE__ */ jsxs20("div", { className: cn("flex flex-col gap-1.5", className), children: [
1907
+ /* @__PURE__ */ jsx24("label", { htmlFor, className: "text-sm font-medium text-foreground", children: label }),
1046
1908
  children,
1047
- description ? /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: description }) : null
1909
+ description ? /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: description }) : null
1048
1910
  ] });
1049
1911
  };
1050
1912
 
@@ -1052,7 +1914,7 @@ var FieldRow = ({
1052
1914
  import { useEffect, useState as useState3 } from "react";
1053
1915
  import { createPortal } from "react-dom";
1054
1916
  import { AnimatePresence as AnimatePresence2, motion as motion3, useReducedMotion as useReducedMotion3 } from "motion/react";
1055
- import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
1917
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
1056
1918
  var FloatingUnsavedChangesBar = ({
1057
1919
  visible,
1058
1920
  message = "Unsaved changes",
@@ -1070,7 +1932,7 @@ var FloatingUnsavedChangesBar = ({
1070
1932
  useEffect(() => setMounted(true), []);
1071
1933
  if (!mounted || typeof document === "undefined") return null;
1072
1934
  return createPortal(
1073
- /* @__PURE__ */ jsx21(AnimatePresence2, { children: visible ? /* @__PURE__ */ jsx21("div", { className: "pointer-events-none fixed inset-x-0 bottom-5 z-50 flex justify-center px-4", children: /* @__PURE__ */ jsxs17(
1935
+ /* @__PURE__ */ jsx25(AnimatePresence2, { children: visible ? /* @__PURE__ */ jsx25("div", { className: "pointer-events-none fixed inset-x-0 bottom-5 z-50 flex justify-center px-4", children: /* @__PURE__ */ jsxs21(
1074
1936
  motion3.div,
1075
1937
  {
1076
1938
  role: "region",
@@ -1084,10 +1946,10 @@ var FloatingUnsavedChangesBar = ({
1084
1946
  className
1085
1947
  ),
1086
1948
  children: [
1087
- /* @__PURE__ */ jsx21("span", { className: "text-sm text-muted-foreground", children: message }),
1088
- /* @__PURE__ */ jsxs17("span", { className: "flex items-center gap-1.5", children: [
1089
- /* @__PURE__ */ jsx21(Button, { variant: "ghost", size: "sm", onClick: onDiscard, disabled: isSaving, children: discardLabel }),
1090
- /* @__PURE__ */ jsx21(Button, { size: "sm", onClick: onSave, disabled: saveDisabled || isSaving, children: isSaving ? "Saving\u2026" : saveLabel })
1949
+ /* @__PURE__ */ jsx25("span", { className: "text-sm text-muted-foreground", children: message }),
1950
+ /* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1.5", children: [
1951
+ /* @__PURE__ */ jsx25(Button, { variant: "ghost", size: "sm", onClick: onDiscard, disabled: isSaving, children: discardLabel }),
1952
+ /* @__PURE__ */ jsx25(Button, { size: "sm", onClick: onSave, disabled: saveDisabled || isSaving, children: isSaving ? "Saving\u2026" : saveLabel })
1091
1953
  ] })
1092
1954
  ]
1093
1955
  }
@@ -1097,13 +1959,13 @@ var FloatingUnsavedChangesBar = ({
1097
1959
  };
1098
1960
 
1099
1961
  // src/app/settings/DangerZone.tsx
1100
- import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
1962
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
1101
1963
  var DangerZoneAction = ({
1102
1964
  title,
1103
1965
  description,
1104
1966
  action,
1105
1967
  className
1106
- }) => /* @__PURE__ */ jsxs18(
1968
+ }) => /* @__PURE__ */ jsxs22(
1107
1969
  "div",
1108
1970
  {
1109
1971
  className: cn(
@@ -1111,11 +1973,11 @@ var DangerZoneAction = ({
1111
1973
  className
1112
1974
  ),
1113
1975
  children: [
1114
- /* @__PURE__ */ jsxs18("div", { className: "min-w-0", children: [
1115
- /* @__PURE__ */ jsx22("p", { className: "text-sm font-medium text-foreground", children: title }),
1116
- description ? /* @__PURE__ */ jsx22("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
1976
+ /* @__PURE__ */ jsxs22("div", { className: "min-w-0", children: [
1977
+ /* @__PURE__ */ jsx26("p", { className: "text-sm font-medium text-foreground", children: title }),
1978
+ description ? /* @__PURE__ */ jsx26("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
1117
1979
  ] }),
1118
- /* @__PURE__ */ jsx22("div", { className: "shrink-0", children: action })
1980
+ /* @__PURE__ */ jsx26("div", { className: "shrink-0", children: action })
1119
1981
  ]
1120
1982
  }
1121
1983
  );
@@ -1124,7 +1986,7 @@ var DangerZone = ({
1124
1986
  description,
1125
1987
  children,
1126
1988
  className
1127
- }) => /* @__PURE__ */ jsxs18(
1989
+ }) => /* @__PURE__ */ jsxs22(
1128
1990
  "section",
1129
1991
  {
1130
1992
  className: cn(
@@ -1132,18 +1994,18 @@ var DangerZone = ({
1132
1994
  className
1133
1995
  ),
1134
1996
  children: [
1135
- (title || description) && /* @__PURE__ */ jsxs18("header", { className: "border-b border-destructive/20 bg-destructive/5 px-4 py-3", children: [
1136
- title ? /* @__PURE__ */ jsx22("h3", { className: "text-sm font-semibold text-destructive", children: title }) : null,
1137
- description ? /* @__PURE__ */ jsx22("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
1997
+ (title || description) && /* @__PURE__ */ jsxs22("header", { className: "border-b border-destructive/20 bg-destructive/5 px-4 py-3", children: [
1998
+ title ? /* @__PURE__ */ jsx26("h3", { className: "text-sm font-semibold text-destructive", children: title }) : null,
1999
+ description ? /* @__PURE__ */ jsx26("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
1138
2000
  ] }),
1139
- /* @__PURE__ */ jsx22("div", { className: "divide-y divide-border bg-card", children })
2001
+ /* @__PURE__ */ jsx26("div", { className: "divide-y divide-border bg-card", children })
1140
2002
  ]
1141
2003
  }
1142
2004
  );
1143
2005
 
1144
2006
  // src/app/integrations/IntegrationCard.tsx
1145
2007
  import { useId as useId2 } from "react";
1146
- import { Fragment as Fragment2, jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
2008
+ import { Fragment as Fragment4, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
1147
2009
  var INTEGRATION_CATALOG_CARD_HEIGHT_CLASS = "h-[12.25rem] min-h-[12.25rem] max-h-[12.25rem]";
1148
2010
  var statusLabel = {
1149
2011
  available: null,
@@ -1184,12 +2046,12 @@ var IntegrationCard = ({
1184
2046
  const titleId = useId2();
1185
2047
  const locked = status === "locked";
1186
2048
  const dimmed = status === "disabled" || locked;
1187
- const body = /* @__PURE__ */ jsxs19("div", { className: "flex h-full min-h-0 flex-col", children: [
1188
- /* @__PURE__ */ jsxs19("div", { className: "flex shrink-0 items-start gap-3 pr-2", children: [
1189
- logo ? /* @__PURE__ */ jsx23("span", { className: logoShellClass, "aria-hidden": Boolean(ariaLabel), children: logo }) : null,
1190
- /* @__PURE__ */ jsx23("div", { className: "min-w-0 flex-1 pt-0.5", children: /* @__PURE__ */ jsxs19("div", { className: "flex items-start justify-between gap-2", children: [
1191
- /* @__PURE__ */ jsxs19("div", { className: "min-w-0", children: [
1192
- /* @__PURE__ */ jsx23(
2049
+ const body = /* @__PURE__ */ jsxs23("div", { className: "flex h-full min-h-0 flex-col", children: [
2050
+ /* @__PURE__ */ jsxs23("div", { className: "flex shrink-0 items-start gap-3 pr-2", children: [
2051
+ logo ? /* @__PURE__ */ jsx27("span", { className: logoShellClass, "aria-hidden": Boolean(ariaLabel), children: logo }) : null,
2052
+ /* @__PURE__ */ jsx27("div", { className: "min-w-0 flex-1 pt-0.5", children: /* @__PURE__ */ jsxs23("div", { className: "flex items-start justify-between gap-2", children: [
2053
+ /* @__PURE__ */ jsxs23("div", { className: "min-w-0", children: [
2054
+ /* @__PURE__ */ jsx27(
1193
2055
  "h4",
1194
2056
  {
1195
2057
  id: onClick && !action ? void 0 : titleId,
@@ -1197,12 +2059,12 @@ var IntegrationCard = ({
1197
2059
  children: name
1198
2060
  }
1199
2061
  ),
1200
- statusLabel[status] ? /* @__PURE__ */ jsx23("p", { className: "mt-0.5 text-xs text-muted-foreground", children: statusLabel[status] }) : null
2062
+ statusLabel[status] ? /* @__PURE__ */ jsx27("p", { className: "mt-0.5 text-xs text-muted-foreground", children: statusLabel[status] }) : null
1201
2063
  ] }),
1202
- badge ? /* @__PURE__ */ jsx23("span", { className: "shrink-0", children: badge }) : null
2064
+ badge ? /* @__PURE__ */ jsx27("span", { className: "shrink-0", children: badge }) : null
1203
2065
  ] }) })
1204
2066
  ] }),
1205
- description ? /* @__PURE__ */ jsx23(
2067
+ description ? /* @__PURE__ */ jsx27(
1206
2068
  "p",
1207
2069
  {
1208
2070
  className: cn(
@@ -1212,9 +2074,9 @@ var IntegrationCard = ({
1212
2074
  children: description
1213
2075
  }
1214
2076
  ) : null,
1215
- action ? /* @__PURE__ */ jsxs19(Fragment2, { children: [
1216
- /* @__PURE__ */ jsx23("div", { className: "min-h-0 flex-1", "aria-hidden": true }),
1217
- /* @__PURE__ */ jsx23("div", { className: "relative mt-3 shrink-0", children: action })
2077
+ action ? /* @__PURE__ */ jsxs23(Fragment4, { children: [
2078
+ /* @__PURE__ */ jsx27("div", { className: "min-h-0 flex-1", "aria-hidden": true }),
2079
+ /* @__PURE__ */ jsx27("div", { className: "relative mt-3 shrink-0", children: action })
1218
2080
  ] }) : null
1219
2081
  ] });
1220
2082
  const shellClass3 = cn(
@@ -1224,7 +2086,7 @@ var IntegrationCard = ({
1224
2086
  className
1225
2087
  );
1226
2088
  if (onClick && !action) {
1227
- return /* @__PURE__ */ jsx23(
2089
+ return /* @__PURE__ */ jsx27(
1228
2090
  "button",
1229
2091
  {
1230
2092
  type: "button",
@@ -1241,12 +2103,12 @@ var IntegrationCard = ({
1241
2103
  }
1242
2104
  );
1243
2105
  }
1244
- return /* @__PURE__ */ jsx23("article", { className: shellClass3, "aria-labelledby": titleId, children: body });
2106
+ return /* @__PURE__ */ jsx27("article", { className: shellClass3, "aria-labelledby": titleId, children: body });
1245
2107
  };
1246
2108
 
1247
2109
  // src/app/integrations/IntegrationsEmptyState.tsx
1248
2110
  import { useId as useId3 } from "react";
1249
- import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
2111
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
1250
2112
  var IntegrationsEmptyState = ({
1251
2113
  title = "No integrations yet",
1252
2114
  description = "Connect a provider to start syncing data and powering your workforce.",
@@ -1255,7 +2117,7 @@ var IntegrationsEmptyState = ({
1255
2117
  className
1256
2118
  }) => {
1257
2119
  const titleId = useId3();
1258
- return /* @__PURE__ */ jsxs20(
2120
+ return /* @__PURE__ */ jsxs24(
1259
2121
  "section",
1260
2122
  {
1261
2123
  className: cn(
@@ -1265,7 +2127,7 @@ var IntegrationsEmptyState = ({
1265
2127
  ),
1266
2128
  "aria-labelledby": titleId,
1267
2129
  children: [
1268
- icon ? /* @__PURE__ */ jsx24(
2130
+ icon ? /* @__PURE__ */ jsx28(
1269
2131
  "span",
1270
2132
  {
1271
2133
  className: cn(
@@ -1277,21 +2139,21 @@ var IntegrationsEmptyState = ({
1277
2139
  children: icon
1278
2140
  }
1279
2141
  ) : null,
1280
- /* @__PURE__ */ jsx24("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }),
1281
- description ? /* @__PURE__ */ jsx24("p", { className: "max-w-sm text-sm text-muted-foreground", children: description }) : null,
1282
- action ? /* @__PURE__ */ jsx24("div", { className: "mt-1", children: action }) : null
2142
+ /* @__PURE__ */ jsx28("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }),
2143
+ description ? /* @__PURE__ */ jsx28("p", { className: "max-w-sm text-sm text-muted-foreground", children: description }) : null,
2144
+ action ? /* @__PURE__ */ jsx28("div", { className: "mt-1", children: action }) : null
1283
2145
  ]
1284
2146
  }
1285
2147
  );
1286
2148
  };
1287
2149
 
1288
2150
  // src/app/integrations/PlanBadge.tsx
1289
- import { jsx as jsx25 } from "react/jsx-runtime";
2151
+ import { jsx as jsx29 } from "react/jsx-runtime";
1290
2152
  var planBadgeClass = "inline-flex h-5 max-w-full shrink-0 items-center rounded-md border border-border bg-muted/90 px-2 text-[11px] font-normal text-muted-foreground dark:border-white/10 dark:bg-white/5 dark:text-muted-foreground";
1291
- var PlanBadge = ({ children, className }) => /* @__PURE__ */ jsx25("span", { className: cn(planBadgeClass, className), children });
2153
+ var PlanBadge = ({ children, className }) => /* @__PURE__ */ jsx29("span", { className: cn(planBadgeClass, className), children });
1292
2154
 
1293
2155
  // src/app/integrations/ConnectionRow.tsx
1294
- import { Fragment as Fragment3, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
2156
+ import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
1295
2157
  var logoShellClass2 = cn(
1296
2158
  "flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg",
1297
2159
  TIMBAL_V2_LOGO_TILE
@@ -1306,14 +2168,14 @@ var ConnectionRow = ({
1306
2168
  ariaLabel,
1307
2169
  className
1308
2170
  }) => {
1309
- const inner = /* @__PURE__ */ jsxs21(Fragment3, { children: [
1310
- logo ? /* @__PURE__ */ jsx26("span", { className: logoShellClass2, children: logo }) : null,
1311
- /* @__PURE__ */ jsxs21("div", { className: "min-w-0 flex-1", children: [
1312
- /* @__PURE__ */ jsx26("p", { className: "truncate text-sm font-normal text-foreground", children: name }),
1313
- meta ? /* @__PURE__ */ jsx26("p", { className: "truncate text-xs text-muted-foreground", children: meta }) : null
2171
+ const inner = /* @__PURE__ */ jsxs25(Fragment5, { children: [
2172
+ logo ? /* @__PURE__ */ jsx30("span", { className: logoShellClass2, children: logo }) : null,
2173
+ /* @__PURE__ */ jsxs25("div", { className: "min-w-0 flex-1", children: [
2174
+ /* @__PURE__ */ jsx30("p", { className: "truncate text-sm font-normal text-foreground", children: name }),
2175
+ meta ? /* @__PURE__ */ jsx30("p", { className: "truncate text-xs text-muted-foreground", children: meta }) : null
1314
2176
  ] }),
1315
- badge ? /* @__PURE__ */ jsx26("span", { className: "shrink-0", children: badge }) : null,
1316
- action ? /* @__PURE__ */ jsx26("span", { className: "shrink-0", children: action }) : null
2177
+ badge ? /* @__PURE__ */ jsx30("span", { className: "shrink-0", children: badge }) : null,
2178
+ action ? /* @__PURE__ */ jsx30("span", { className: "shrink-0", children: action }) : null
1317
2179
  ] });
1318
2180
  const rowClass2 = cn(
1319
2181
  "flex w-full items-center gap-3 px-4 py-3 text-left",
@@ -1321,7 +2183,7 @@ var ConnectionRow = ({
1321
2183
  className
1322
2184
  );
1323
2185
  if (onClick) {
1324
- return /* @__PURE__ */ jsx26(
2186
+ return /* @__PURE__ */ jsx30(
1325
2187
  "button",
1326
2188
  {
1327
2189
  type: "button",
@@ -1333,7 +2195,7 @@ var ConnectionRow = ({
1333
2195
  }
1334
2196
  );
1335
2197
  }
1336
- return /* @__PURE__ */ jsx26("div", { role: "listitem", className: rowClass2, children: inner });
2198
+ return /* @__PURE__ */ jsx30("div", { role: "listitem", className: rowClass2, children: inner });
1337
2199
  };
1338
2200
  var connectionRowListClass = cn(
1339
2201
  "overflow-hidden rounded-2xl",
@@ -1341,12 +2203,12 @@ var connectionRowListClass = cn(
1341
2203
  );
1342
2204
 
1343
2205
  // src/app/integrations/ConnectionRowList.tsx
1344
- import { jsx as jsx27 } from "react/jsx-runtime";
2206
+ import { jsx as jsx31 } from "react/jsx-runtime";
1345
2207
  var ConnectionRowList = ({
1346
2208
  children,
1347
2209
  "aria-label": ariaLabel = "Connected integrations",
1348
2210
  className
1349
- }) => /* @__PURE__ */ jsx27(
2211
+ }) => /* @__PURE__ */ jsx31(
1350
2212
  "div",
1351
2213
  {
1352
2214
  role: "list",
@@ -1357,7 +2219,7 @@ var ConnectionRowList = ({
1357
2219
  );
1358
2220
 
1359
2221
  // src/app/navigation/SubNav.tsx
1360
- import { jsx as jsx28 } from "react/jsx-runtime";
2222
+ import { jsx as jsx32 } from "react/jsx-runtime";
1361
2223
  var SubNav = ({
1362
2224
  items,
1363
2225
  activeId,
@@ -1366,7 +2228,7 @@ var SubNav = ({
1366
2228
  "aria-label": ariaLabel = "Section navigation",
1367
2229
  layoutId
1368
2230
  }) => {
1369
- return /* @__PURE__ */ jsx28("nav", { className: cn("aui-app-sub-nav", className), "aria-label": ariaLabel, children: /* @__PURE__ */ jsx28(
2231
+ return /* @__PURE__ */ jsx32("nav", { className: cn("aui-app-sub-nav", className), "aria-label": ariaLabel, children: /* @__PURE__ */ jsx32(
1370
2232
  PillSegmentedTabs,
1371
2233
  {
1372
2234
  value: activeId,
@@ -1380,13 +2242,13 @@ var SubNav = ({
1380
2242
  };
1381
2243
 
1382
2244
  // src/app/navigation/Breadcrumbs.tsx
1383
- import { jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
2245
+ import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
1384
2246
  var Breadcrumbs = ({ items, className }) => {
1385
- return /* @__PURE__ */ jsx29("nav", { className: cn("aui-app-breadcrumbs", appBreadcrumbsClass, className), "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx29("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, index) => {
2247
+ return /* @__PURE__ */ jsx33("nav", { className: cn("aui-app-breadcrumbs", appBreadcrumbsClass, className), "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx33("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, index) => {
1386
2248
  const isLast = index === items.length - 1;
1387
- return /* @__PURE__ */ jsxs22("li", { className: "inline-flex items-center gap-1.5", children: [
1388
- index > 0 ? /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
1389
- isLast ? /* @__PURE__ */ jsx29("span", { className: "text-foreground", "aria-current": "page", children: item.label }) : item.href ? /* @__PURE__ */ jsx29("a", { href: item.href, className: appBreadcrumbLinkClass, children: item.label }) : /* @__PURE__ */ jsx29(
2249
+ return /* @__PURE__ */ jsxs26("li", { className: "inline-flex items-center gap-1.5", children: [
2250
+ index > 0 ? /* @__PURE__ */ jsx33("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
2251
+ isLast ? /* @__PURE__ */ jsx33("span", { className: "text-foreground", "aria-current": "page", children: item.label }) : item.href ? /* @__PURE__ */ jsx33("a", { href: item.href, className: appBreadcrumbLinkClass, children: item.label }) : /* @__PURE__ */ jsx33(
1390
2252
  "button",
1391
2253
  {
1392
2254
  type: "button",
@@ -1400,7 +2262,7 @@ var Breadcrumbs = ({ items, className }) => {
1400
2262
  };
1401
2263
 
1402
2264
  // src/app/forms/Field.tsx
1403
- import { jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
2265
+ import { jsx as jsx34, jsxs as jsxs27 } from "react/jsx-runtime";
1404
2266
  var Field = ({
1405
2267
  label,
1406
2268
  hint,
@@ -1409,11 +2271,11 @@ var Field = ({
1409
2271
  className,
1410
2272
  htmlFor
1411
2273
  }) => {
1412
- return /* @__PURE__ */ jsxs23("div", { className: cn("aui-app-field", appFieldClass, className), children: [
1413
- /* @__PURE__ */ jsx30("label", { className: appFieldLabelClass, htmlFor, children: label }),
2274
+ return /* @__PURE__ */ jsxs27("div", { className: cn("aui-app-field", appFieldClass, className), children: [
2275
+ /* @__PURE__ */ jsx34("label", { className: appFieldLabelClass, htmlFor, children: label }),
1414
2276
  children,
1415
- hint && !error ? /* @__PURE__ */ jsx30("p", { className: appFieldHintClass, children: hint }) : null,
1416
- error ? /* @__PURE__ */ jsx30("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
2277
+ hint && !error ? /* @__PURE__ */ jsx34("p", { className: appFieldHintClass, children: hint }) : null,
2278
+ error ? /* @__PURE__ */ jsx34("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
1417
2279
  ] });
1418
2280
  };
1419
2281
  var FieldInput = ({
@@ -1426,7 +2288,7 @@ var FieldInput = ({
1426
2288
  ...inputProps
1427
2289
  }) => {
1428
2290
  const inputId = id ?? inputProps.name;
1429
- return /* @__PURE__ */ jsx30(
2291
+ return /* @__PURE__ */ jsx34(
1430
2292
  Field,
1431
2293
  {
1432
2294
  label,
@@ -1434,7 +2296,7 @@ var FieldInput = ({
1434
2296
  error,
1435
2297
  htmlFor: inputId,
1436
2298
  className: fieldClassName,
1437
- children: /* @__PURE__ */ jsx30(
2299
+ children: /* @__PURE__ */ jsx34(
1438
2300
  "input",
1439
2301
  {
1440
2302
  id: inputId,
@@ -1448,7 +2310,7 @@ var FieldInput = ({
1448
2310
  };
1449
2311
 
1450
2312
  // src/app/forms/FieldTextarea.tsx
1451
- import { jsx as jsx31 } from "react/jsx-runtime";
2313
+ import { jsx as jsx35 } from "react/jsx-runtime";
1452
2314
  var textareaClass = cn(
1453
2315
  appInputClass,
1454
2316
  "min-h-[5.5rem] resize-y py-2.5 leading-relaxed"
@@ -1463,7 +2325,7 @@ var FieldTextarea = ({
1463
2325
  ...props
1464
2326
  }) => {
1465
2327
  const textareaId = id ?? props.name;
1466
- return /* @__PURE__ */ jsx31(
2328
+ return /* @__PURE__ */ jsx35(
1467
2329
  Field,
1468
2330
  {
1469
2331
  label,
@@ -1471,7 +2333,7 @@ var FieldTextarea = ({
1471
2333
  error,
1472
2334
  htmlFor: textareaId,
1473
2335
  className: fieldClassName,
1474
- children: /* @__PURE__ */ jsx31(
2336
+ children: /* @__PURE__ */ jsx35(
1475
2337
  "textarea",
1476
2338
  {
1477
2339
  id: textareaId,
@@ -1486,7 +2348,7 @@ var FieldTextarea = ({
1486
2348
 
1487
2349
  // src/app/forms/FieldSelect.tsx
1488
2350
  import { ChevronDownIcon } from "lucide-react";
1489
- import { jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
2351
+ import { jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
1490
2352
  var selectWrapClass = "relative";
1491
2353
  var selectClass = cn(
1492
2354
  appInputClass,
@@ -1503,7 +2365,7 @@ var FieldSelect = ({
1503
2365
  ...props
1504
2366
  }) => {
1505
2367
  const selectId = id ?? props.name;
1506
- return /* @__PURE__ */ jsx32(
2368
+ return /* @__PURE__ */ jsx36(
1507
2369
  Field,
1508
2370
  {
1509
2371
  label,
@@ -1511,8 +2373,8 @@ var FieldSelect = ({
1511
2373
  error,
1512
2374
  htmlFor: selectId,
1513
2375
  className: fieldClassName,
1514
- children: /* @__PURE__ */ jsxs24("div", { className: selectWrapClass, children: [
1515
- /* @__PURE__ */ jsx32(
2376
+ children: /* @__PURE__ */ jsxs28("div", { className: selectWrapClass, children: [
2377
+ /* @__PURE__ */ jsx36(
1516
2378
  "select",
1517
2379
  {
1518
2380
  id: selectId,
@@ -1522,7 +2384,7 @@ var FieldSelect = ({
1522
2384
  children
1523
2385
  }
1524
2386
  ),
1525
- /* @__PURE__ */ jsx32(
2387
+ /* @__PURE__ */ jsx36(
1526
2388
  ChevronDownIcon,
1527
2389
  {
1528
2390
  className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground",
@@ -1535,7 +2397,7 @@ var FieldSelect = ({
1535
2397
  };
1536
2398
 
1537
2399
  // src/app/forms/FieldSwitch.tsx
1538
- import { jsx as jsx33, jsxs as jsxs25 } from "react/jsx-runtime";
2400
+ import { jsx as jsx37, jsxs as jsxs29 } from "react/jsx-runtime";
1539
2401
  var trackClass = cn(
1540
2402
  "relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
1541
2403
  "peer-focus-visible:ring-2 peer-focus-visible:ring-foreground/10",
@@ -1556,7 +2418,7 @@ var FieldSwitch = ({
1556
2418
  ...props
1557
2419
  }) => {
1558
2420
  const inputId = id ?? props.name ?? "switch";
1559
- return /* @__PURE__ */ jsxs25(
2421
+ return /* @__PURE__ */ jsxs29(
1560
2422
  "label",
1561
2423
  {
1562
2424
  className: cn(
@@ -1565,8 +2427,8 @@ var FieldSwitch = ({
1565
2427
  ),
1566
2428
  htmlFor: inputId,
1567
2429
  children: [
1568
- /* @__PURE__ */ jsxs25("span", { className: "relative mt-0.5", children: [
1569
- /* @__PURE__ */ jsx33(
2430
+ /* @__PURE__ */ jsxs29("span", { className: "relative mt-0.5", children: [
2431
+ /* @__PURE__ */ jsx37(
1570
2432
  "input",
1571
2433
  {
1572
2434
  id: inputId,
@@ -1576,11 +2438,11 @@ var FieldSwitch = ({
1576
2438
  ...props
1577
2439
  }
1578
2440
  ),
1579
- /* @__PURE__ */ jsx33("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ jsx33("span", { className: thumbClass }) })
2441
+ /* @__PURE__ */ jsx37("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ jsx37("span", { className: thumbClass }) })
1580
2442
  ] }),
1581
- /* @__PURE__ */ jsxs25("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
1582
- /* @__PURE__ */ jsx33("span", { className: "text-sm font-medium text-foreground", children: label }),
1583
- description ? /* @__PURE__ */ jsx33("span", { className: "text-xs text-muted-foreground", children: description }) : null
2443
+ /* @__PURE__ */ jsxs29("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
2444
+ /* @__PURE__ */ jsx37("span", { className: "text-sm font-medium text-foreground", children: label }),
2445
+ description ? /* @__PURE__ */ jsx37("span", { className: "text-xs text-muted-foreground", children: description }) : null
1584
2446
  ] })
1585
2447
  ]
1586
2448
  }
@@ -1589,13 +2451,13 @@ var FieldSwitch = ({
1589
2451
 
1590
2452
  // src/app/forms/SearchInput.tsx
1591
2453
  import { SearchIcon } from "lucide-react";
1592
- import { jsx as jsx34, jsxs as jsxs26 } from "react/jsx-runtime";
2454
+ import { jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
1593
2455
  var SearchInput = ({
1594
2456
  className,
1595
2457
  placeholder = "Search\u2026",
1596
2458
  ...props
1597
2459
  }) => {
1598
- return /* @__PURE__ */ jsxs26(
2460
+ return /* @__PURE__ */ jsxs30(
1599
2461
  "label",
1600
2462
  {
1601
2463
  className: cn(
@@ -1604,8 +2466,8 @@ var SearchInput = ({
1604
2466
  className
1605
2467
  ),
1606
2468
  children: [
1607
- /* @__PURE__ */ jsx34(SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
1608
- /* @__PURE__ */ jsx34(
2469
+ /* @__PURE__ */ jsx38(SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
2470
+ /* @__PURE__ */ jsx38(
1609
2471
  "input",
1610
2472
  {
1611
2473
  type: "search",
@@ -1620,18 +2482,18 @@ var SearchInput = ({
1620
2482
  };
1621
2483
 
1622
2484
  // src/app/forms/FormSection.tsx
1623
- import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
2485
+ import { jsx as jsx39, jsxs as jsxs31 } from "react/jsx-runtime";
1624
2486
  var FormSection = ({ title, children, className }) => {
1625
- return /* @__PURE__ */ jsxs27("fieldset", { className: cn("aui-app-form-section", appSectionClass, "border-0 p-0", className), children: [
1626
- title ? /* @__PURE__ */ jsx35("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
1627
- /* @__PURE__ */ jsx35("div", { className: "flex flex-col gap-4", children })
2487
+ return /* @__PURE__ */ jsxs31("fieldset", { className: cn("aui-app-form-section", appSectionClass, "border-0 p-0", className), children: [
2488
+ title ? /* @__PURE__ */ jsx39("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
2489
+ /* @__PURE__ */ jsx39("div", { className: "flex flex-col gap-4", children })
1628
2490
  ] });
1629
2491
  };
1630
2492
 
1631
2493
  // src/app/data/FilterBar.tsx
1632
- import { jsx as jsx36 } from "react/jsx-runtime";
2494
+ import { jsx as jsx40 } from "react/jsx-runtime";
1633
2495
  var FilterBar = ({ children, className }) => {
1634
- return /* @__PURE__ */ jsx36(
2496
+ return /* @__PURE__ */ jsx40(
1635
2497
  "div",
1636
2498
  {
1637
2499
  className: cn("aui-app-filter-bar", appFilterBarClass, className),
@@ -1645,7 +2507,7 @@ var FilterBar = ({ children, className }) => {
1645
2507
  // src/app/data/DataTable.tsx
1646
2508
  import { useMemo, useState as useState4 } from "react";
1647
2509
  import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon } from "lucide-react";
1648
- import { jsx as jsx37, jsxs as jsxs28 } from "react/jsx-runtime";
2510
+ import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
1649
2511
  var shellClass2 = "overflow-hidden rounded-xl border border-border bg-card shadow-card";
1650
2512
  var tableClass = "w-full border-collapse bg-transparent text-sm";
1651
2513
  var headCellClass = "border-b border-border/60 bg-transparent px-4 py-2.5 text-left text-xs font-medium uppercase tracking-wide text-muted-foreground";
@@ -1685,12 +2547,12 @@ function SortIndicator({
1685
2547
  }) {
1686
2548
  const iconClass = "size-3.5 shrink-0 opacity-60 group-hover:opacity-100";
1687
2549
  if (!active) {
1688
- return /* @__PURE__ */ jsx37(ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
2550
+ return /* @__PURE__ */ jsx41(ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
1689
2551
  }
1690
2552
  if (direction === "desc") {
1691
- return /* @__PURE__ */ jsx37(ArrowDownIcon, { className: iconClass, "aria-hidden": true });
2553
+ return /* @__PURE__ */ jsx41(ArrowDownIcon, { className: iconClass, "aria-hidden": true });
1692
2554
  }
1693
- return /* @__PURE__ */ jsx37(ArrowUpIcon, { className: iconClass, "aria-hidden": true });
2555
+ return /* @__PURE__ */ jsx41(ArrowUpIcon, { className: iconClass, "aria-hidden": true });
1694
2556
  }
1695
2557
  function DataTable({
1696
2558
  columns,
@@ -1741,28 +2603,28 @@ function DataTable({
1741
2603
  const cellPad = dense ? "px-3 py-2" : void 0;
1742
2604
  const headPad = dense ? "px-3 py-2" : void 0;
1743
2605
  if (rows.length === 0 && emptyMode === "replace") {
1744
- return /* @__PURE__ */ jsx37(EmptyState, { title: emptyTitle, description: emptyDescription, className });
2606
+ return /* @__PURE__ */ jsx41(EmptyState, { title: emptyTitle, description: emptyDescription, className });
1745
2607
  }
1746
2608
  const rowCountText = rowCountLabel?.(sortedRows.length) ?? `${sortedRows.length} row${sortedRows.length === 1 ? "" : "s"}`;
1747
2609
  const hasFoot = Boolean((showRowCount || footer) && sortedRows.length > 0);
1748
- return /* @__PURE__ */ jsx37("div", { className: cn("aui-app-data-table", shellClass2, className), children: /* @__PURE__ */ jsx37("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs28("table", { className: tableClass, children: [
1749
- caption ? /* @__PURE__ */ jsx37("caption", { className: "sr-only", children: caption }) : null,
1750
- /* @__PURE__ */ jsx37("thead", { className: cn(stickyHeader && stickyHeadClass), children: /* @__PURE__ */ jsx37("tr", { children: columns.map((col) => {
2610
+ return /* @__PURE__ */ jsx41("div", { className: cn("aui-app-data-table", shellClass2, className), children: /* @__PURE__ */ jsx41("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs32("table", { className: tableClass, children: [
2611
+ caption ? /* @__PURE__ */ jsx41("caption", { className: "sr-only", children: caption }) : null,
2612
+ /* @__PURE__ */ jsx41("thead", { className: cn(stickyHeader && stickyHeadClass), children: /* @__PURE__ */ jsx41("tr", { children: columns.map((col) => {
1751
2613
  const isSorted = sort?.columnId === col.id;
1752
2614
  const ariaSort = col.sortable ? isSorted ? sort.direction === "asc" ? "ascending" : "descending" : "none" : void 0;
1753
- const headerContent = col.sortable ? /* @__PURE__ */ jsxs28(
2615
+ const headerContent = col.sortable ? /* @__PURE__ */ jsxs32(
1754
2616
  "button",
1755
2617
  {
1756
2618
  type: "button",
1757
2619
  className: sortButtonClass,
1758
2620
  onClick: () => setSort(nextSort(sort, col.id)),
1759
2621
  children: [
1760
- /* @__PURE__ */ jsx37("span", { className: "truncate", children: col.header }),
1761
- /* @__PURE__ */ jsx37(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
2622
+ /* @__PURE__ */ jsx41("span", { className: "truncate", children: col.header }),
2623
+ /* @__PURE__ */ jsx41(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
1762
2624
  ]
1763
2625
  }
1764
2626
  ) : col.header;
1765
- return /* @__PURE__ */ jsx37(
2627
+ return /* @__PURE__ */ jsx41(
1766
2628
  "th",
1767
2629
  {
1768
2630
  scope: "col",
@@ -1778,10 +2640,10 @@ function DataTable({
1778
2640
  col.id
1779
2641
  );
1780
2642
  }) }) }),
1781
- /* @__PURE__ */ jsx37("tbody", { className: cn(!hasFoot && "[&_tr:last-child_td]:border-b-0"), children: sortedRows.length === 0 ? /* @__PURE__ */ jsx37("tr", { children: /* @__PURE__ */ jsx37("td", { colSpan: columns.length, className: emptyCellClass, children: /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center gap-1", children: [
1782
- /* @__PURE__ */ jsx37("p", { className: "font-medium text-foreground", children: emptyTitle }),
1783
- emptyDescription ? /* @__PURE__ */ jsx37("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
1784
- ] }) }) }) : sortedRows.map((row) => /* @__PURE__ */ jsx37(
2643
+ /* @__PURE__ */ jsx41("tbody", { className: cn(!hasFoot && "[&_tr:last-child_td]:border-b-0"), children: sortedRows.length === 0 ? /* @__PURE__ */ jsx41("tr", { children: /* @__PURE__ */ jsx41("td", { colSpan: columns.length, className: emptyCellClass, children: /* @__PURE__ */ jsxs32("div", { className: "flex flex-col items-center gap-1", children: [
2644
+ /* @__PURE__ */ jsx41("p", { className: "font-medium text-foreground", children: emptyTitle }),
2645
+ emptyDescription ? /* @__PURE__ */ jsx41("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
2646
+ ] }) }) }) : sortedRows.map((row) => /* @__PURE__ */ jsx41(
1785
2647
  "tr",
1786
2648
  {
1787
2649
  className: rowClass,
@@ -1795,7 +2657,7 @@ function DataTable({
1795
2657
  } : void 0,
1796
2658
  tabIndex: onRowClick ? 0 : void 0,
1797
2659
  role: onRowClick ? "button" : void 0,
1798
- children: columns.map((col) => /* @__PURE__ */ jsx37(
2660
+ children: columns.map((col) => /* @__PURE__ */ jsx41(
1799
2661
  "td",
1800
2662
  {
1801
2663
  className: cn(
@@ -1811,7 +2673,7 @@ function DataTable({
1811
2673
  },
1812
2674
  getRowKey(row)
1813
2675
  )) }),
1814
- hasFoot ? /* @__PURE__ */ jsx37("tfoot", { children: /* @__PURE__ */ jsx37("tr", { children: /* @__PURE__ */ jsx37("td", { colSpan: columns.length, className: footCellClass, children: /* @__PURE__ */ jsxs28(
2676
+ hasFoot ? /* @__PURE__ */ jsx41("tfoot", { children: /* @__PURE__ */ jsx41("tr", { children: /* @__PURE__ */ jsx41("td", { colSpan: columns.length, className: footCellClass, children: /* @__PURE__ */ jsxs32(
1815
2677
  "div",
1816
2678
  {
1817
2679
  className: cn(
@@ -1819,7 +2681,7 @@ function DataTable({
1819
2681
  showRowCount && footer ? "justify-between" : "justify-start"
1820
2682
  ),
1821
2683
  children: [
1822
- showRowCount ? /* @__PURE__ */ jsx37("span", { children: rowCountText }) : null,
2684
+ showRowCount ? /* @__PURE__ */ jsx41("span", { children: rowCountText }) : null,
1823
2685
  footer
1824
2686
  ]
1825
2687
  }
@@ -1829,53 +2691,7 @@ function DataTable({
1829
2691
 
1830
2692
  // src/app/data/ChartPanel.tsx
1831
2693
  import { useId as useId4 } from "react";
1832
-
1833
- // src/app/data/metrics-shared.tsx
1834
- import { jsx as jsx38, jsxs as jsxs29 } from "react/jsx-runtime";
1835
- var metricCardShellClass = cn(
1836
- studioIntegrationCardClass,
1837
- "aui-app-metric-card shadow-none",
1838
- "flex flex-col overflow-hidden"
1839
- );
1840
- var metricCardHeaderClass = "flex items-start justify-between gap-3 px-4 pb-1 pt-3";
1841
- var metricTilesRowClass = "grid w-full min-w-0";
1842
- var metricChartRegionClass = "relative min-h-0 w-full border-t border-border/40 pt-2";
1843
- var metricChartPlotRegionClass = "relative min-h-0 w-full border-t border-border/40 px-0 pt-5 pb-3";
1844
- var metricCellDividerClass = "border-r border-border/40";
1845
- var MetricCardHeader = ({
1846
- title,
1847
- titleId,
1848
- description,
1849
- actions
1850
- }) => {
1851
- if (!title && !description && !actions) return null;
1852
- return /* @__PURE__ */ jsxs29("header", { className: metricCardHeaderClass, children: [
1853
- /* @__PURE__ */ jsxs29("div", { className: "min-w-0", children: [
1854
- title ? /* @__PURE__ */ jsx38("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
1855
- description ? /* @__PURE__ */ jsx38("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
1856
- ] }),
1857
- actions ? /* @__PURE__ */ jsx38("div", { className: "shrink-0", children: actions }) : null
1858
- ] });
1859
- };
1860
- function metricTilesGridColsClass(n) {
1861
- switch (n) {
1862
- case 1:
1863
- return "grid-cols-1";
1864
- case 2:
1865
- return "grid-cols-2";
1866
- case 3:
1867
- return "grid-cols-3";
1868
- case 5:
1869
- return "grid-cols-2 sm:grid-cols-5";
1870
- case 6:
1871
- return "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6";
1872
- default:
1873
- return "grid-cols-2 md:grid-cols-4";
1874
- }
1875
- }
1876
-
1877
- // src/app/data/ChartPanel.tsx
1878
- import { jsx as jsx39, jsxs as jsxs30 } from "react/jsx-runtime";
2694
+ import { jsx as jsx42, jsxs as jsxs33 } from "react/jsx-runtime";
1879
2695
  var ChartPanel = ({
1880
2696
  title,
1881
2697
  description,
@@ -1888,14 +2704,14 @@ var ChartPanel = ({
1888
2704
  const titleId = useId4();
1889
2705
  const resolvedTitle = title ?? artifact?.title;
1890
2706
  const hasHeader = Boolean(resolvedTitle || description || actions);
1891
- const body = children ?? (artifact ? /* @__PURE__ */ jsx39(ChartArtifactView, { artifact, embedded: true, height }) : null);
1892
- return /* @__PURE__ */ jsxs30(
2707
+ const body = children ?? (artifact ? /* @__PURE__ */ jsx42(ChartArtifactView, { artifact, embedded: true, height }) : null);
2708
+ return /* @__PURE__ */ jsxs33(
1893
2709
  "section",
1894
2710
  {
1895
2711
  className: cn(metricCardShellClass, "aui-app-chart-panel", className),
1896
2712
  "aria-labelledby": resolvedTitle ? titleId : void 0,
1897
2713
  children: [
1898
- /* @__PURE__ */ jsx39(
2714
+ /* @__PURE__ */ jsx42(
1899
2715
  MetricCardHeader,
1900
2716
  {
1901
2717
  title: resolvedTitle,
@@ -1904,14 +2720,14 @@ var ChartPanel = ({
1904
2720
  actions
1905
2721
  }
1906
2722
  ),
1907
- /* @__PURE__ */ jsx39(
2723
+ /* @__PURE__ */ jsx42(
1908
2724
  "div",
1909
2725
  {
1910
2726
  className: cn(
1911
2727
  "relative min-h-0 w-full",
1912
2728
  hasHeader ? metricChartPlotRegionClass : "pt-2 pb-3"
1913
2729
  ),
1914
- children: body ?? /* @__PURE__ */ jsx39(
2730
+ children: body ?? /* @__PURE__ */ jsx42(
1915
2731
  "div",
1916
2732
  {
1917
2733
  className: "flex items-center justify-center text-sm font-normal text-muted-foreground",
@@ -1927,77 +2743,9 @@ var ChartPanel = ({
1927
2743
  );
1928
2744
  };
1929
2745
 
1930
- // src/app/data/MetricTile.tsx
1931
- import { Fragment as Fragment4, jsx as jsx40, jsxs as jsxs31 } from "react/jsx-runtime";
1932
- var trendToneClass = {
1933
- up: "border-border/80 bg-muted/40 text-muted-foreground",
1934
- down: "border-border/80 bg-muted/40 text-muted-foreground",
1935
- neutral: "border-border/80 bg-muted/30 text-muted-foreground"
1936
- };
1937
- var metricTileBaseClass = "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal";
1938
- var metricTileInteractiveClass = cn(
1939
- metricTileBaseClass,
1940
- "bg-transparent hover:bg-transparent active:bg-transparent",
1941
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10"
1942
- );
1943
- var MetricTile = ({
1944
- label,
1945
- value,
1946
- unit,
1947
- trend,
1948
- trendTone = "neutral",
1949
- active = false,
1950
- showDivider = false,
1951
- onSelect,
1952
- ariaLabel,
1953
- className
1954
- }) => {
1955
- const content = /* @__PURE__ */ jsxs31(Fragment4, { children: [
1956
- active ? /* @__PURE__ */ jsx40(
1957
- "span",
1958
- {
1959
- "aria-hidden": true,
1960
- className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground dark:bg-white"
1961
- }
1962
- ) : null,
1963
- /* @__PURE__ */ jsx40("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
1964
- /* @__PURE__ */ jsxs31("span", { className: "flex items-center gap-2", children: [
1965
- /* @__PURE__ */ jsxs31("span", { className: "flex items-baseline gap-1", children: [
1966
- /* @__PURE__ */ jsx40("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
1967
- unit ? /* @__PURE__ */ jsx40("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
1968
- ] }),
1969
- trend ? /* @__PURE__ */ jsx40(
1970
- "span",
1971
- {
1972
- className: cn(
1973
- "rounded-full border px-1.5 py-0.5 text-xs font-normal",
1974
- trendToneClass[trendTone]
1975
- ),
1976
- children: trend
1977
- }
1978
- ) : null
1979
- ] })
1980
- ] });
1981
- const divider = showDivider ? metricCellDividerClass : void 0;
1982
- if (onSelect) {
1983
- return /* @__PURE__ */ jsx40(
1984
- "button",
1985
- {
1986
- type: "button",
1987
- onClick: onSelect,
1988
- "aria-pressed": active,
1989
- "aria-label": ariaLabel,
1990
- className: cn(metricTileInteractiveClass, divider, className),
1991
- children: content
1992
- }
1993
- );
1994
- }
1995
- return /* @__PURE__ */ jsx40("div", { className: cn(metricTileBaseClass, divider, className), children: content });
1996
- };
1997
-
1998
2746
  // src/app/data/MetricRow.tsx
1999
2747
  import { useId as useId5, useState as useState5 } from "react";
2000
- import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
2748
+ import { jsx as jsx43, jsxs as jsxs34 } from "react/jsx-runtime";
2001
2749
  var MetricRow = ({
2002
2750
  title,
2003
2751
  description,
@@ -2019,13 +2767,13 @@ var MetricRow = ({
2019
2767
  if (activeMetricId == null) setInternalId(id);
2020
2768
  onMetricChange?.(id);
2021
2769
  };
2022
- return /* @__PURE__ */ jsxs32(
2770
+ return /* @__PURE__ */ jsxs34(
2023
2771
  "section",
2024
2772
  {
2025
2773
  className: cn(metricCardShellClass, className),
2026
2774
  "aria-labelledby": title ? titleId : void 0,
2027
2775
  children: [
2028
- /* @__PURE__ */ jsx41(
2776
+ /* @__PURE__ */ jsx43(
2029
2777
  MetricCardHeader,
2030
2778
  {
2031
2779
  title,
@@ -2034,7 +2782,7 @@ var MetricRow = ({
2034
2782
  actions
2035
2783
  }
2036
2784
  ),
2037
- /* @__PURE__ */ jsx41(
2785
+ /* @__PURE__ */ jsx43(
2038
2786
  "div",
2039
2787
  {
2040
2788
  role: selectable ? "group" : void 0,
@@ -2044,7 +2792,7 @@ var MetricRow = ({
2044
2792
  metricTilesGridColsClass(metrics.length),
2045
2793
  (title || description || actions) && "mt-3"
2046
2794
  ),
2047
- children: metrics.map((m, index) => /* @__PURE__ */ jsx41(
2795
+ children: metrics.map((m, index) => /* @__PURE__ */ jsx43(
2048
2796
  MetricTile,
2049
2797
  {
2050
2798
  label: m.label,
@@ -2067,7 +2815,7 @@ var MetricRow = ({
2067
2815
 
2068
2816
  // src/app/data/MetricChartCard.tsx
2069
2817
  import { useId as useId6, useState as useState6 } from "react";
2070
- import { jsx as jsx42, jsxs as jsxs33 } from "react/jsx-runtime";
2818
+ import { jsx as jsx44, jsxs as jsxs35 } from "react/jsx-runtime";
2071
2819
  var MetricChartCard = ({
2072
2820
  title,
2073
2821
  description,
@@ -2097,13 +2845,13 @@ var MetricChartCard = ({
2097
2845
  };
2098
2846
  const hasHeader = Boolean(title || description || actions);
2099
2847
  const chartAriaLabel = typeof active?.label === "string" ? `${active.label} over time` : "Metric chart";
2100
- return /* @__PURE__ */ jsxs33(
2848
+ return /* @__PURE__ */ jsxs35(
2101
2849
  "section",
2102
2850
  {
2103
2851
  className: cn(metricCardShellClass, className),
2104
2852
  "aria-labelledby": title ? titleId : void 0,
2105
2853
  children: [
2106
- /* @__PURE__ */ jsx42(
2854
+ /* @__PURE__ */ jsx44(
2107
2855
  MetricCardHeader,
2108
2856
  {
2109
2857
  title,
@@ -2112,7 +2860,7 @@ var MetricChartCard = ({
2112
2860
  actions
2113
2861
  }
2114
2862
  ),
2115
- /* @__PURE__ */ jsx42(
2863
+ /* @__PURE__ */ jsx44(
2116
2864
  "div",
2117
2865
  {
2118
2866
  role: "group",
@@ -2122,7 +2870,7 @@ var MetricChartCard = ({
2122
2870
  metricTilesGridColsClass(metrics.length),
2123
2871
  hasHeader && "mt-3"
2124
2872
  ),
2125
- children: metrics.map((m, index) => /* @__PURE__ */ jsx42(
2873
+ children: metrics.map((m, index) => /* @__PURE__ */ jsx44(
2126
2874
  MetricTile,
2127
2875
  {
2128
2876
  label: m.label,
@@ -2138,7 +2886,7 @@ var MetricChartCard = ({
2138
2886
  ))
2139
2887
  }
2140
2888
  ),
2141
- /* @__PURE__ */ jsx42("div", { className: metricChartRegionClass, "aria-live": "polite", "aria-atomic": "true", children: active?.data && active.data.length > 0 ? /* @__PURE__ */ jsx42(
2889
+ /* @__PURE__ */ jsx44("div", { className: metricChartRegionClass, "aria-live": "polite", "aria-atomic": "true", children: active?.data && active.data.length > 0 ? /* @__PURE__ */ jsx44(
2142
2890
  LineAreaChart,
2143
2891
  {
2144
2892
  data: active.data,
@@ -2158,7 +2906,7 @@ var MetricChartCard = ({
2158
2906
  ariaLabel: chartAriaLabel
2159
2907
  },
2160
2908
  active.id
2161
- ) : /* @__PURE__ */ jsx42(
2909
+ ) : /* @__PURE__ */ jsx44(
2162
2910
  "div",
2163
2911
  {
2164
2912
  className: "flex w-full items-center justify-center text-sm font-normal text-muted-foreground",
@@ -2174,7 +2922,7 @@ var MetricChartCard = ({
2174
2922
 
2175
2923
  // src/charts/sparkline.tsx
2176
2924
  import { useId as useId7 } from "react";
2177
- import { Fragment as Fragment5, jsx as jsx43, jsxs as jsxs34 } from "react/jsx-runtime";
2925
+ import { Fragment as Fragment6, jsx as jsx45, jsxs as jsxs36 } from "react/jsx-runtime";
2178
2926
  var Sparkline = ({
2179
2927
  data,
2180
2928
  dataKey = "value",
@@ -2189,7 +2937,7 @@ var Sparkline = ({
2189
2937
  const uid = useId7();
2190
2938
  const values = data.map((d) => typeof d === "number" ? d : toNum(d[dataKey]));
2191
2939
  if (values.length === 0) {
2192
- return /* @__PURE__ */ jsx43("span", { className: cn("inline-block", className), style: { width, height } });
2940
+ return /* @__PURE__ */ jsx45("span", { className: cn("inline-block", className), style: { width, height } });
2193
2941
  }
2194
2942
  const pad = strokeWidth + 1;
2195
2943
  const min = Math.min(...values);
@@ -2201,7 +2949,7 @@ var Sparkline = ({
2201
2949
  x: pad + (values.length > 1 ? i / (values.length - 1) * innerW : innerW / 2),
2202
2950
  y: pad + innerH - (v - min) / range * innerH
2203
2951
  }));
2204
- return /* @__PURE__ */ jsxs34(
2952
+ return /* @__PURE__ */ jsxs36(
2205
2953
  "svg",
2206
2954
  {
2207
2955
  width,
@@ -2212,14 +2960,14 @@ var Sparkline = ({
2212
2960
  "aria-label": ariaLabel,
2213
2961
  preserveAspectRatio: "none",
2214
2962
  children: [
2215
- area && /* @__PURE__ */ jsxs34(Fragment5, { children: [
2216
- /* @__PURE__ */ jsx43("defs", { children: /* @__PURE__ */ jsxs34("linearGradient", { id: `${uid}-spark`, x1: "0", x2: "0", y1: "0", y2: "1", children: [
2217
- /* @__PURE__ */ jsx43("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
2218
- /* @__PURE__ */ jsx43("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
2963
+ area && /* @__PURE__ */ jsxs36(Fragment6, { children: [
2964
+ /* @__PURE__ */ jsx45("defs", { children: /* @__PURE__ */ jsxs36("linearGradient", { id: `${uid}-spark`, x1: "0", x2: "0", y1: "0", y2: "1", children: [
2965
+ /* @__PURE__ */ jsx45("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
2966
+ /* @__PURE__ */ jsx45("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
2219
2967
  ] }) }),
2220
- /* @__PURE__ */ jsx43("path", { d: monotoneAreaPath(points, height - pad), fill: `url(#${uid}-spark)` })
2968
+ /* @__PURE__ */ jsx45("path", { d: monotoneAreaPath(points, height - pad), fill: `url(#${uid}-spark)` })
2221
2969
  ] }),
2222
- /* @__PURE__ */ jsx43(
2970
+ /* @__PURE__ */ jsx45(
2223
2971
  "path",
2224
2972
  {
2225
2973
  d: monotoneLinePath(points),
@@ -2237,6 +2985,19 @@ var Sparkline = ({
2237
2985
 
2238
2986
  export {
2239
2987
  APP_KIT_AGENT_INSTRUCTIONS,
2988
+ createTimbalTheme,
2989
+ themeToCss,
2990
+ ensureThemeFontLink,
2991
+ applyTimbalTheme,
2992
+ clearTimbalTheme,
2993
+ TIMBAL_THEME_PRESETS,
2994
+ getThemePreset,
2995
+ applyThemePreset,
2996
+ getStoredThemePreset,
2997
+ THEME_AGENT_INSTRUCTIONS,
2998
+ TimbalThemeStyle,
2999
+ MetricTile,
3000
+ ThemePresetGallery,
2240
3001
  appPageColumnClass,
2241
3002
  appShellTopbarInsetClass,
2242
3003
  appShellInsetTopClass,
@@ -2289,7 +3050,6 @@ export {
2289
3050
  FilterBar,
2290
3051
  DataTable,
2291
3052
  ChartPanel,
2292
- MetricTile,
2293
3053
  MetricRow,
2294
3054
  MetricChartCard,
2295
3055
  Sparkline