@wealthx/shadcn 1.5.40 → 1.5.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/.turbo/turbo-build.log +103 -103
  2. package/CHANGELOG.md +12 -0
  3. package/dist/{chunk-MGIDYXOP.mjs → chunk-DWNLBUDC.mjs} +459 -67
  4. package/dist/{chunk-EFHPSKVF.mjs → chunk-EGM4DARZ.mjs} +110 -1
  5. package/dist/{chunk-B5PSUONN.mjs → chunk-TF5TOVIM.mjs} +1 -1
  6. package/dist/{chunk-STN5QIWN.mjs → chunk-THOHFAW2.mjs} +119 -46
  7. package/dist/{chunk-RRROLESJ.mjs → chunk-XHZONBL4.mjs} +1 -1
  8. package/dist/components/ui/ai-assistant-drawer.js +101 -0
  9. package/dist/components/ui/ai-assistant-drawer.mjs +2 -2
  10. package/dist/components/ui/ai-conversations/index.js +101 -0
  11. package/dist/components/ui/ai-conversations/index.mjs +2 -2
  12. package/dist/components/ui/chat-input-area.js +101 -0
  13. package/dist/components/ui/chat-input-area.mjs +1 -1
  14. package/dist/components/ui/policy-ai/index.js +818 -261
  15. package/dist/components/ui/policy-ai/index.mjs +11 -2
  16. package/dist/components/ui/support-agent/index.js +218 -44
  17. package/dist/components/ui/support-agent/index.mjs +2 -2
  18. package/dist/index.js +3506 -3329
  19. package/dist/index.mjs +5 -5
  20. package/dist/styles.css +1 -1
  21. package/package.json +1 -1
  22. package/src/components/ui/chat-input-area.tsx +181 -2
  23. package/src/components/ui/policy-ai/index.tsx +12 -0
  24. package/src/components/ui/policy-ai/policy-ai-context-sidebar.tsx +231 -0
  25. package/src/components/ui/policy-ai/policy-ai-history-panel.tsx +175 -0
  26. package/src/components/ui/policy-ai/policy-ai-page.tsx +243 -0
  27. package/src/components/ui/policy-ai/policy-ai-panel.tsx +64 -57
  28. package/src/components/ui/policy-ai/policy-ai-responses.tsx +8 -12
  29. package/src/components/ui/support-agent/support-agent-panel.tsx +153 -46
  30. package/src/styles/styles-css.ts +1 -1
@@ -59,7 +59,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
59
59
  // src/components/ui/policy-ai/index.tsx
60
60
  var policy_ai_exports = {};
61
61
  __export(policy_ai_exports, {
62
+ PolicyAIContextSidebar: () => PolicyAIContextSidebar,
62
63
  PolicyAIFAB: () => PolicyAIFAB,
64
+ PolicyAIHistoryPanel: () => PolicyAIHistoryPanel,
65
+ PolicyAIPage: () => PolicyAIPage,
63
66
  PolicyAIPanel: () => PolicyAIPanel,
64
67
  PolicyCitationPanel: () => PolicyCitationPanel,
65
68
  PolicyComparisonTable: () => PolicyComparisonTable,
@@ -399,11 +402,52 @@ function PolicyCitationPanel({
399
402
  var React5 = __toESM(require("react"));
400
403
  var import_lucide_react3 = require("lucide-react");
401
404
 
402
- // src/components/ui/input.tsx
405
+ // src/components/ui/avatar.tsx
406
+ var import_avatar = require("@base-ui/react/avatar");
403
407
  var import_jsx_runtime4 = require("react/jsx-runtime");
408
+ function Avatar(_a) {
409
+ var _b = _a, {
410
+ className,
411
+ size = "default"
412
+ } = _b, props = __objRest(_b, [
413
+ "className",
414
+ "size"
415
+ ]);
416
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
417
+ import_avatar.Avatar.Root,
418
+ __spreadValues({
419
+ className: cn(
420
+ "group/avatar relative flex size-8 shrink-0 rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
421
+ className
422
+ ),
423
+ "data-size": size,
424
+ "data-slot": "avatar"
425
+ }, props)
426
+ );
427
+ }
428
+ function AvatarFallback(_a) {
429
+ var _b = _a, {
430
+ className
431
+ } = _b, props = __objRest(_b, [
432
+ "className"
433
+ ]);
434
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
435
+ import_avatar.Avatar.Fallback,
436
+ __spreadValues({
437
+ className: cn(
438
+ "flex size-full items-center justify-center rounded-full overflow-hidden bg-muted text-body-small font-sans text-muted-foreground group-data-[size=sm]/avatar:text-caption",
439
+ className
440
+ ),
441
+ "data-slot": "avatar-fallback"
442
+ }, props)
443
+ );
444
+ }
445
+
446
+ // src/components/ui/input.tsx
447
+ var import_jsx_runtime5 = require("react/jsx-runtime");
404
448
  function Input(_a) {
405
449
  var _b = _a, { className, type } = _b, props = __objRest(_b, ["className", "type"]);
406
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
450
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
407
451
  "input",
408
452
  __spreadValues({
409
453
  className: cn(
@@ -423,21 +467,21 @@ var import_tooltip = require("@base-ui/react/tooltip");
423
467
 
424
468
  // src/lib/theme-provider.tsx
425
469
  var import_react2 = require("react");
426
- var import_jsx_runtime5 = require("react/jsx-runtime");
470
+ var import_jsx_runtime6 = require("react/jsx-runtime");
427
471
  var ThemeVarsContext = (0, import_react2.createContext)({});
428
472
  function useThemeVars() {
429
473
  return (0, import_react2.useContext)(ThemeVarsContext);
430
474
  }
431
475
 
432
476
  // src/components/ui/tooltip.tsx
433
- var import_jsx_runtime6 = require("react/jsx-runtime");
477
+ var import_jsx_runtime7 = require("react/jsx-runtime");
434
478
  function TooltipProvider(_a) {
435
479
  var _b = _a, {
436
480
  delay = 0
437
481
  } = _b, props = __objRest(_b, [
438
482
  "delay"
439
483
  ]);
440
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
484
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
441
485
  import_tooltip.Tooltip.Provider,
442
486
  __spreadValues({
443
487
  "data-slot": "tooltip-provider",
@@ -447,11 +491,11 @@ function TooltipProvider(_a) {
447
491
  }
448
492
  function Tooltip(_a) {
449
493
  var props = __objRest(_a, []);
450
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_tooltip.Tooltip.Root, __spreadValues({ "data-slot": "tooltip" }, props));
494
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_tooltip.Tooltip.Root, __spreadValues({ "data-slot": "tooltip" }, props));
451
495
  }
452
496
  function TooltipTrigger(_a) {
453
497
  var props = __objRest(_a, []);
454
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_tooltip.Tooltip.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
498
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_tooltip.Tooltip.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
455
499
  }
456
500
  function TooltipContent(_a) {
457
501
  var _b = _a, {
@@ -468,7 +512,7 @@ function TooltipContent(_a) {
468
512
  "style"
469
513
  ]);
470
514
  const themeVars = useThemeVars();
471
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_tooltip.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_tooltip.Tooltip.Positioner, { sideOffset, side, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
515
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_tooltip.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_tooltip.Tooltip.Positioner, { sideOffset, side, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
472
516
  import_tooltip.Tooltip.Popup,
473
517
  __spreadProps(__spreadValues({
474
518
  className: cn(
@@ -480,7 +524,7 @@ function TooltipContent(_a) {
480
524
  }, props), {
481
525
  children: [
482
526
  children,
483
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_tooltip.Tooltip.Arrow, { className: "z-50 size-2.5 rotate-45 bg-brand-secondary data-[side=bottom]:-top-1 data-[side=left]:-right-1 data-[side=right]:-left-1 data-[side=top]:-bottom-1" })
527
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_tooltip.Tooltip.Arrow, { className: "z-50 size-2.5 rotate-45 bg-brand-secondary data-[side=bottom]:-top-1 data-[side=left]:-right-1 data-[side=right]:-left-1 data-[side=top]:-bottom-1" })
484
528
  ]
485
529
  })
486
530
  ) }) });
@@ -489,15 +533,15 @@ function TooltipContent(_a) {
489
533
  // src/components/ui/popover.tsx
490
534
  var React4 = __toESM(require("react"));
491
535
  var import_popover = require("@base-ui/react/popover");
492
- var import_jsx_runtime7 = require("react/jsx-runtime");
536
+ var import_jsx_runtime8 = require("react/jsx-runtime");
493
537
  var PopoverPortalContext = React4.createContext(void 0);
494
538
  function Popover(_a) {
495
539
  var props = __objRest(_a, []);
496
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_popover.Popover.Root, __spreadValues({ "data-slot": "popover" }, props));
540
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_popover.Popover.Root, __spreadValues({ "data-slot": "popover" }, props));
497
541
  }
498
542
  function PopoverTrigger(_a) {
499
543
  var props = __objRest(_a, []);
500
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_popover.Popover.Trigger, __spreadValues({ "data-slot": "popover-trigger" }, props));
544
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_popover.Popover.Trigger, __spreadValues({ "data-slot": "popover-trigger" }, props));
501
545
  }
502
546
  function PopoverContent(_a) {
503
547
  var _b = _a, {
@@ -513,13 +557,13 @@ function PopoverContent(_a) {
513
557
  ]);
514
558
  const themeVars = useThemeVars();
515
559
  const portalContainer = React4.useContext(PopoverPortalContext);
516
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_popover.Popover.Portal, { container: portalContainer != null ? portalContainer : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
560
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_popover.Popover.Portal, { container: portalContainer != null ? portalContainer : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
517
561
  import_popover.Popover.Positioner,
518
562
  {
519
563
  className: "z-[200]",
520
564
  align,
521
565
  sideOffset,
522
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
566
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
523
567
  import_popover.Popover.Popup,
524
568
  __spreadValues({
525
569
  className: cn(
@@ -536,7 +580,7 @@ function PopoverContent(_a) {
536
580
 
537
581
  // src/components/ui/progress.tsx
538
582
  var import_progress = require("@base-ui/react/progress");
539
- var import_jsx_runtime8 = require("react/jsx-runtime");
583
+ var import_jsx_runtime9 = require("react/jsx-runtime");
540
584
  function Progress(_a) {
541
585
  var _b = _a, {
542
586
  className,
@@ -547,14 +591,14 @@ function Progress(_a) {
547
591
  "value",
548
592
  "indicatorClassName"
549
593
  ]);
550
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
594
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
551
595
  import_progress.Progress.Root,
552
596
  __spreadProps(__spreadValues({
553
597
  className: cn("relative h-2 w-full overflow-hidden bg-muted", className),
554
598
  "data-slot": "progress",
555
599
  value
556
600
  }, props), {
557
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_progress.Progress.Track, { className: "h-full", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
601
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_progress.Progress.Track, { className: "h-full", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
558
602
  import_progress.Progress.Indicator,
559
603
  {
560
604
  className: cn("h-full bg-primary transition-all", indicatorClassName),
@@ -568,7 +612,7 @@ function Progress(_a) {
568
612
  // src/components/ui/tabs.tsx
569
613
  var import_class_variance_authority3 = require("class-variance-authority");
570
614
  var import_tabs = require("@base-ui/react/tabs");
571
- var import_jsx_runtime9 = require("react/jsx-runtime");
615
+ var import_jsx_runtime10 = require("react/jsx-runtime");
572
616
  function Tabs(_a) {
573
617
  var _b = _a, {
574
618
  className,
@@ -577,7 +621,7 @@ function Tabs(_a) {
577
621
  "className",
578
622
  "orientation"
579
623
  ]);
580
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
624
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
581
625
  import_tabs.Tabs.Root,
582
626
  __spreadValues({
583
627
  className: cn(
@@ -611,7 +655,7 @@ function TabsList(_a) {
611
655
  "className",
612
656
  "variant"
613
657
  ]);
614
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
658
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
615
659
  import_tabs.Tabs.List,
616
660
  __spreadValues({
617
661
  className: cn(tabsListVariants({ variant }), className),
@@ -622,7 +666,7 @@ function TabsList(_a) {
622
666
  }
623
667
  function TabsTrigger(_a) {
624
668
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
625
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
669
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
626
670
  import_tabs.Tabs.Tab,
627
671
  __spreadValues({
628
672
  className: cn(
@@ -659,28 +703,21 @@ function TabsTrigger(_a) {
659
703
  }
660
704
 
661
705
  // src/components/ui/policy-ai/policy-ai-responses.tsx
662
- var import_jsx_runtime10 = require("react/jsx-runtime");
706
+ var import_jsx_runtime11 = require("react/jsx-runtime");
663
707
  function BankAvatar({ name }) {
664
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
665
- "span",
666
- {
667
- "aria-hidden": "true",
668
- className: "shrink-0 inline-flex items-center justify-center size-7 bg-muted text-muted-foreground text-xs font-semibold border border-border",
669
- children: name.charAt(0).toUpperCase()
670
- }
671
- );
708
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Avatar, { "aria-hidden": "true", className: "size-7 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AvatarFallback, { children: name.charAt(0).toUpperCase() }) });
672
709
  }
673
710
  function QueryContextInfo({ label }) {
674
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Tooltip, { children: [
675
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
711
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
712
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
676
713
  "span",
677
714
  {
678
715
  className: "shrink-0 text-muted-foreground/60 hover:text-muted-foreground cursor-default transition-colors",
679
716
  "aria-label": label,
680
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.Info, { className: "size-3.5", "aria-hidden": "true" })
717
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Info, { className: "size-3.5", "aria-hidden": "true" })
681
718
  }
682
719
  ) }),
683
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipContent, { side: "top", children: label })
720
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipContent, { side: "top", children: label })
684
721
  ] }) });
685
722
  }
686
723
  function queryContextLabel(context) {
@@ -691,8 +728,8 @@ function queryContextLabel(context) {
691
728
  ].join(" \xB7 ");
692
729
  }
693
730
  function CitationBadge({ citation }) {
694
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Popover, { children: [
695
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": `View source ${citation.index}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
731
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Popover, { children: [
732
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": `View source ${citation.index}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
696
733
  Badge,
697
734
  {
698
735
  variant: "secondary",
@@ -700,12 +737,12 @@ function CitationBadge({ citation }) {
700
737
  children: citation.index
701
738
  }
702
739
  ) }) }),
703
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverContent, { className: "w-72 p-3", sideOffset: 6, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-2", children: [
704
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
705
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs font-semibold text-foreground", children: citation.bankName }),
706
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Badge, { variant: "secondary", className: "text-xs px-1.5 py-0", children: citation.category })
740
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PopoverContent, { className: "w-72 p-3", sideOffset: 6, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-2", children: [
741
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
742
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm font-semibold text-foreground", children: citation.bankName }),
743
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Badge, { variant: "secondary", className: "text-xs px-1.5 py-0", children: citation.category })
707
744
  ] }),
708
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-xs text-muted-foreground leading-relaxed", children: citation.excerpt })
745
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-muted-foreground", children: citation.excerpt })
709
746
  ] }) })
710
747
  ] });
711
748
  }
@@ -715,14 +752,14 @@ function AnswerWithCitations({
715
752
  }) {
716
753
  const citationMap = new Map(citations.map((c) => [c.index, c]));
717
754
  const parts = answer.split(/(\[\d+\])/g);
718
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-sm text-foreground leading-relaxed whitespace-pre-line", children: parts.map((part, i) => {
755
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-foreground leading-relaxed whitespace-pre-line", children: parts.map((part, i) => {
719
756
  const match = part.match(/^\[(\d+)\]$/);
720
757
  if (match) {
721
758
  const citation = citationMap.get(parseInt(match[1], 10));
722
- if (citation) return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CitationBadge, { citation }, i);
723
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs text-muted-foreground", children: part }, i);
759
+ if (citation) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CitationBadge, { citation }, i);
760
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-caption text-muted-foreground", children: part }, i);
724
761
  }
725
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(React5.Fragment, { children: part }, i);
762
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(React5.Fragment, { children: part }, i);
726
763
  }) });
727
764
  }
728
765
  function PolicySingleBankAnswer({
@@ -733,21 +770,21 @@ function PolicySingleBankAnswer({
733
770
  queryContext,
734
771
  className
735
772
  }) {
736
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
773
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
737
774
  "div",
738
775
  {
739
776
  "data-slot": "policy-single-bank-answer",
740
777
  className: cn("border border-border bg-card flex flex-col", className),
741
778
  children: [
742
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-3 px-4 py-3 border-b border-border", children: [
743
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BankAvatar, { name: bankName }),
744
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex-1 flex items-center gap-1.5 min-w-0", children: [
745
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-sm text-foreground truncate", children: bankName }),
746
- queryContext && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(QueryContextInfo, { label: queryContextLabel(queryContext) })
779
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-3 px-4 py-3 border-b border-border", children: [
780
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BankAvatar, { name: bankName }),
781
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex-1 flex items-center gap-1.5 min-w-0", children: [
782
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-sm text-foreground truncate", children: bankName }),
783
+ queryContext && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(QueryContextInfo, { label: queryContextLabel(queryContext) })
747
784
  ] }),
748
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PolicyVerdictBadge, { verdict })
785
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PolicyVerdictBadge, { verdict })
749
786
  ] }),
750
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AnswerWithCitations, { answer, citations }) })
787
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AnswerWithCitations, { answer, citations }) })
751
788
  ]
752
789
  }
753
790
  );
@@ -773,42 +810,42 @@ function PolicyComparisonTable({
773
810
  }
774
811
  return result;
775
812
  }, [banks, search, filter]);
776
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
813
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
777
814
  "div",
778
815
  {
779
816
  "data-slot": "policy-comparison-table",
780
817
  className: cn("border border-border bg-card flex flex-col", className),
781
818
  children: [
782
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-3 px-4 py-2.5 border-b border-border bg-muted/30", children: [
783
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
819
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-3 px-4 py-2.5 border-b border-border bg-muted/30", children: [
820
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
784
821
  import_lucide_react3.Building2,
785
822
  {
786
823
  className: "size-3.5 text-muted-foreground shrink-0",
787
824
  "aria-hidden": "true"
788
825
  }
789
826
  ),
790
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2 text-sm flex-wrap flex-1 min-w-0", children: [
791
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-semibold text-foreground", children: [
827
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 text-sm flex-wrap flex-1 min-w-0", children: [
828
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-semibold text-foreground", children: [
792
829
  summaryCounts.total,
793
830
  " banks"
794
831
  ] }),
795
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-muted-foreground", children: "\xB7" }),
796
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Badge, { variant: "success", className: "text-xs px-1.5 py-0", children: [
832
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-muted-foreground", children: "\xB7" }),
833
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Badge, { variant: "success", className: "text-xs px-1.5 py-0", children: [
797
834
  summaryCounts.yes,
798
835
  " Yes"
799
836
  ] }),
800
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Badge, { variant: "warning", className: "text-xs px-1.5 py-0", children: [
837
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Badge, { variant: "warning", className: "text-xs px-1.5 py-0", children: [
801
838
  summaryCounts.softNo,
802
839
  " Soft No"
803
840
  ] }),
804
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Badge, { variant: "destructive", className: "text-xs px-1.5 py-0", children: [
841
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Badge, { variant: "destructive", className: "text-xs px-1.5 py-0", children: [
805
842
  summaryCounts.no,
806
843
  " No"
807
844
  ] })
808
845
  ] }),
809
- queryContext && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(QueryContextInfo, { label: queryContextLabel(queryContext) })
846
+ queryContext && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(QueryContextInfo, { label: queryContextLabel(queryContext) })
810
847
  ] }),
811
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "px-4 py-2.5 border-b border-border", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
848
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "px-4 py-2.5 border-b border-border", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
812
849
  Input,
813
850
  {
814
851
  "aria-label": "Search banks",
@@ -818,23 +855,23 @@ function PolicyComparisonTable({
818
855
  className: "h-8 text-sm"
819
856
  }
820
857
  ) }),
821
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "border-b border-border px-4 pt-1", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
858
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "border-b border-border px-4 pt-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
822
859
  Tabs,
823
860
  {
824
861
  value: filter,
825
862
  onValueChange: (v) => setFilter(v),
826
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(TabsList, { variant: "line", className: "justify-start h-8 gap-0 -mb-px", children: [
827
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TabsTrigger, { value: "all", className: "text-sm px-3 h-7", children: "All" }),
828
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TabsTrigger, { value: "yes", className: "text-sm px-3 h-7", children: "Yes" }),
829
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TabsTrigger, { value: "soft_no", className: "text-sm px-3 h-7", children: "Soft No" }),
830
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TabsTrigger, { value: "no", className: "text-sm px-3 h-7", children: "No" })
863
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(TabsList, { variant: "line", className: "justify-start h-8 gap-0 -mb-px", children: [
864
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TabsTrigger, { value: "all", className: "text-sm px-3 h-7", children: "All" }),
865
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TabsTrigger, { value: "yes", className: "text-sm px-3 h-7", children: "Yes" }),
866
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TabsTrigger, { value: "soft_no", className: "text-sm px-3 h-7", children: "Soft No" }),
867
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TabsTrigger, { value: "no", className: "text-sm px-3 h-7", children: "No" })
831
868
  ] })
832
869
  }
833
870
  ) }),
834
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("table", { className: "w-full text-sm border-collapse", children: [
835
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("tr", { className: "border-b border-border bg-muted/20", children: [
836
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("th", { className: "text-left text-sm font-medium text-muted-foreground px-4 py-2", children: "Bank" }),
837
- categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
871
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("table", { className: "w-full text-sm border-collapse", children: [
872
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("tr", { className: "border-b border-border bg-muted/20", children: [
873
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("th", { className: "text-left text-sm font-medium text-muted-foreground px-4 py-2", children: "Bank" }),
874
+ categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
838
875
  "th",
839
876
  {
840
877
  className: "text-left text-sm font-medium text-muted-foreground px-3 py-2 w-px whitespace-nowrap",
@@ -843,26 +880,26 @@ function PolicyComparisonTable({
843
880
  cat
844
881
  ))
845
882
  ] }) }),
846
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tbody", { children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
883
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tbody", { children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
847
884
  "td",
848
885
  {
849
886
  colSpan: categories.length + 1,
850
887
  className: "px-4 py-6 text-center text-sm text-muted-foreground",
851
888
  children: "No banks match your search."
852
889
  }
853
- ) }) : filtered.map((bank) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("tr", { className: "border-b border-border", children: [
854
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2", children: [
855
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BankAvatar, { name: bank.bankName }),
856
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-0.5 min-w-0", children: [
857
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm font-medium text-foreground leading-snug", children: bank.bankName }),
858
- bank.details && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs text-muted-foreground leading-snug", children: bank.details })
890
+ ) }) : filtered.map((bank) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("tr", { className: "border-b border-border", children: [
891
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2", children: [
892
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BankAvatar, { name: bank.bankName }),
893
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-0.5 min-w-0", children: [
894
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm font-medium text-foreground leading-snug", children: bank.bankName }),
895
+ bank.details && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-caption text-muted-foreground", children: bank.details })
859
896
  ] })
860
897
  ] }) }),
861
- categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
898
+ categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
862
899
  "td",
863
900
  {
864
901
  className: "px-3 py-2.5 align-top w-px whitespace-nowrap",
865
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PolicyVerdictBadge, { verdict: bank.verdict })
902
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PolicyVerdictBadge, { verdict: bank.verdict })
866
903
  },
867
904
  cat
868
905
  ))
@@ -885,45 +922,45 @@ function PolicyRankedList({
885
922
  queryContext,
886
923
  className
887
924
  }) {
888
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
925
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
889
926
  "div",
890
927
  {
891
928
  "data-slot": "policy-ranked-list",
892
929
  className: cn("border border-border bg-card flex flex-col", className),
893
930
  children: [
894
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2 px-4 py-2.5 border-b border-border bg-muted/30", children: [
895
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm text-muted-foreground shrink-0", children: "Ranked:" }),
896
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center gap-1 flex-wrap flex-1 min-w-0", children: categories.map((cat, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(React5.Fragment, { children: [
897
- i > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm text-muted-foreground", children: "+" }),
898
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Badge, { variant: "secondary", className: "text-xs px-1.5 py-0", children: cat })
931
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 px-4 py-2.5 border-b border-border bg-muted/30", children: [
932
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm text-muted-foreground shrink-0", children: "Ranked:" }),
933
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex items-center gap-1 flex-wrap flex-1 min-w-0", children: categories.map((cat, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React5.Fragment, { children: [
934
+ i > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm text-muted-foreground", children: "+" }),
935
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Badge, { variant: "secondary", className: "text-xs px-1.5 py-0", children: cat })
899
936
  ] }, cat)) }),
900
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-sm text-muted-foreground shrink-0", children: [
937
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-sm text-muted-foreground shrink-0", children: [
901
938
  banks.length,
902
939
  " banks"
903
940
  ] }),
904
- queryContext && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(QueryContextInfo, { label: queryContextLabel(queryContext) })
941
+ queryContext && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(QueryContextInfo, { label: queryContextLabel(queryContext) })
905
942
  ] }),
906
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "divide-y divide-border", children: banks.map((bank) => {
943
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "divide-y divide-border", children: banks.map((bank) => {
907
944
  var _a, _b;
908
945
  const scorePercent = Math.round(bank.score * 100);
909
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col", children: [
910
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-3 px-4 py-3", children: [
911
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "shrink-0 w-6 text-center text-sm font-bold text-muted-foreground", children: [
946
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col", children: [
947
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-3 px-4 py-3", children: [
948
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "shrink-0 w-6 text-center text-sm font-bold text-muted-foreground", children: [
912
949
  "#",
913
950
  bank.rank
914
951
  ] }),
915
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-1.5", children: [
916
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
917
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm font-medium text-foreground truncate", children: bank.bankName }),
918
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [
919
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-sm text-muted-foreground font-mono", children: [
952
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-1.5", children: [
953
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
954
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm font-medium text-foreground truncate", children: bank.bankName }),
955
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [
956
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-sm text-muted-foreground font-mono", children: [
920
957
  scorePercent,
921
958
  "%"
922
959
  ] }),
923
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PolicyVerdictBadge, { verdict: bank.verdict })
960
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PolicyVerdictBadge, { verdict: bank.verdict })
924
961
  ] })
925
962
  ] }),
926
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
963
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
927
964
  Progress,
928
965
  {
929
966
  value: scorePercent,
@@ -937,7 +974,7 @@ function PolicyRankedList({
937
974
  )
938
975
  ] })
939
976
  ] }),
940
- bank.highlights.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "px-4 pb-3 pl-[52px]", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "flex flex-col gap-0.5", children: bank.highlights.map((h, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
977
+ bank.highlights.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "px-4 pb-3 pl-[52px]", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "flex flex-col gap-0.5", children: bank.highlights.map((h, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
941
978
  "li",
942
979
  {
943
980
  className: "text-sm text-muted-foreground leading-relaxed list-disc list-inside",
@@ -956,15 +993,32 @@ function PolicyRankedList({
956
993
  var React7 = __toESM(require("react"));
957
994
  var import_lucide_react6 = require("lucide-react");
958
995
 
996
+ // src/components/ui/card.tsx
997
+ var import_jsx_runtime12 = require("react/jsx-runtime");
998
+ function Card(_a) {
999
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1000
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1001
+ "div",
1002
+ __spreadValues({
1003
+ className: cn(
1004
+ "flex flex-col gap-6 border bg-card py-6 text-card-foreground shadow-sm",
1005
+ className
1006
+ ),
1007
+ "data-slot": "card"
1008
+ }, props)
1009
+ );
1010
+ }
1011
+
959
1012
  // src/components/ui/chat-input-area.tsx
960
1013
  var React6 = __toESM(require("react"));
1014
+ var import_react_dom = require("react-dom");
961
1015
  var import_lucide_react4 = require("lucide-react");
962
1016
 
963
1017
  // src/components/ui/textarea.tsx
964
- var import_jsx_runtime11 = require("react/jsx-runtime");
1018
+ var import_jsx_runtime13 = require("react/jsx-runtime");
965
1019
  function Textarea(_a) {
966
1020
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
967
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1021
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
968
1022
  "textarea",
969
1023
  __spreadValues({
970
1024
  className: cn(
@@ -978,8 +1032,99 @@ function Textarea(_a) {
978
1032
  }
979
1033
 
980
1034
  // src/components/ui/chat-input-area.tsx
981
- var import_jsx_runtime12 = require("react/jsx-runtime");
1035
+ var import_jsx_runtime14 = require("react/jsx-runtime");
982
1036
  var DEFAULT_HINT = "Enter to send \xB7 Shift+Enter for new line";
1037
+ var TOOLBAR_ITEMS = [
1038
+ {
1039
+ type: "button",
1040
+ icon: import_lucide_react4.Bold,
1041
+ label: "Bold",
1042
+ title: "Bold (Ctrl+B)",
1043
+ before: "**",
1044
+ after: "**",
1045
+ placeholder: "bold text"
1046
+ },
1047
+ {
1048
+ type: "button",
1049
+ icon: import_lucide_react4.Italic,
1050
+ label: "Italic",
1051
+ title: "Italic (Ctrl+I)",
1052
+ before: "*",
1053
+ after: "*",
1054
+ placeholder: "italic text"
1055
+ },
1056
+ {
1057
+ type: "button",
1058
+ icon: import_lucide_react4.Code,
1059
+ label: "Inline code",
1060
+ title: "Inline code",
1061
+ before: "`",
1062
+ after: "`",
1063
+ placeholder: "code"
1064
+ },
1065
+ { type: "divider" },
1066
+ {
1067
+ type: "button",
1068
+ icon: import_lucide_react4.Code2,
1069
+ label: "Code block",
1070
+ title: "Code block",
1071
+ before: "```\n",
1072
+ after: "\n```",
1073
+ placeholder: "code block"
1074
+ }
1075
+ ];
1076
+ function applyMarkdown(textarea, before, after, placeholder, onChange) {
1077
+ const start = textarea.selectionStart;
1078
+ const end = textarea.selectionEnd;
1079
+ const selected = textarea.value.slice(start, end);
1080
+ const insertion = selected || placeholder;
1081
+ const next = textarea.value.slice(0, start) + before + insertion + after + textarea.value.slice(end);
1082
+ const newStart = start + before.length;
1083
+ const newEnd = newStart + insertion.length;
1084
+ (0, import_react_dom.flushSync)(() => onChange(next));
1085
+ textarea.focus();
1086
+ textarea.setSelectionRange(newStart, newEnd);
1087
+ }
1088
+ var MarkdownToolbar = React6.memo(function MarkdownToolbar2({
1089
+ textareaRef,
1090
+ onChange,
1091
+ disabled
1092
+ }) {
1093
+ const handleFormat = React6.useCallback(
1094
+ (e) => {
1095
+ if (!textareaRef.current) return;
1096
+ const { before, after, placeholder } = e.currentTarget.dataset;
1097
+ applyMarkdown(textareaRef.current, before, after, placeholder, onChange);
1098
+ },
1099
+ [textareaRef, onChange]
1100
+ );
1101
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex items-center gap-0.5 border-b border-border px-2 py-1", children: TOOLBAR_ITEMS.map(
1102
+ (item, i) => item.type === "divider" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1103
+ "span",
1104
+ {
1105
+ className: "mx-0.5 h-3.5 w-px bg-border",
1106
+ "aria-hidden": "true"
1107
+ },
1108
+ i
1109
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1110
+ Button,
1111
+ {
1112
+ variant: "ghost",
1113
+ size: "icon-sm",
1114
+ type: "button",
1115
+ title: item.title,
1116
+ "aria-label": item.label,
1117
+ disabled,
1118
+ "data-before": item.before,
1119
+ "data-after": item.after,
1120
+ "data-placeholder": item.placeholder,
1121
+ onClick: handleFormat,
1122
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(item.icon, { className: "size-3.5", "aria-hidden": "true" })
1123
+ },
1124
+ item.label
1125
+ )
1126
+ ) });
1127
+ });
983
1128
  function ChatInputArea({
984
1129
  value,
985
1130
  onChange,
@@ -991,6 +1136,7 @@ function ChatInputArea({
991
1136
  hint = DEFAULT_HINT,
992
1137
  maxHeight = 160,
993
1138
  autoFocus = false,
1139
+ showMarkdownToolbar = false,
994
1140
  className
995
1141
  }) {
996
1142
  const textareaRef = React6.useRef(null);
@@ -1052,14 +1198,22 @@ function ChatInputArea({
1052
1198
  );
1053
1199
  const showFileButton = typeof onAttachFile === "function";
1054
1200
  const showImageButton = typeof onAttachImage === "function";
1055
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1201
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1056
1202
  "div",
1057
1203
  {
1058
1204
  "data-slot": "chat-input-area",
1059
1205
  className: cn("flex flex-col gap-1.5", className),
1060
1206
  children: [
1061
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "border border-border bg-background flex flex-col focus-within:ring-1 focus-within:ring-ring", children: [
1062
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1207
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "border border-border bg-background flex flex-col focus-within:ring-1 focus-within:ring-ring", children: [
1208
+ showMarkdownToolbar && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1209
+ MarkdownToolbar,
1210
+ {
1211
+ textareaRef,
1212
+ onChange,
1213
+ disabled
1214
+ }
1215
+ ),
1216
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1063
1217
  Textarea,
1064
1218
  {
1065
1219
  ref: textareaRef,
@@ -1073,10 +1227,10 @@ function ChatInputArea({
1073
1227
  "aria-label": placeholder
1074
1228
  }
1075
1229
  ),
1076
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-between px-2 pb-2", children: [
1077
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-0.5", children: [
1078
- showFileButton && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1079
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1230
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between px-2 pb-2", children: [
1231
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-0.5", children: [
1232
+ showFileButton && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1233
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1080
1234
  Button,
1081
1235
  {
1082
1236
  variant: "ghost",
@@ -1089,10 +1243,10 @@ function ChatInputArea({
1089
1243
  var _a;
1090
1244
  return (_a = fileInputRef.current) == null ? void 0 : _a.click();
1091
1245
  },
1092
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.Paperclip, { className: "size-3.5", "aria-hidden": "true" })
1246
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.Paperclip, { className: "size-3.5", "aria-hidden": "true" })
1093
1247
  }
1094
1248
  ),
1095
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1249
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1096
1250
  "input",
1097
1251
  {
1098
1252
  ref: fileInputRef,
@@ -1104,8 +1258,8 @@ function ChatInputArea({
1104
1258
  }
1105
1259
  )
1106
1260
  ] }),
1107
- showImageButton && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1108
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1261
+ showImageButton && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1262
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1109
1263
  Button,
1110
1264
  {
1111
1265
  variant: "ghost",
@@ -1118,10 +1272,10 @@ function ChatInputArea({
1118
1272
  var _a;
1119
1273
  return (_a = imageInputRef.current) == null ? void 0 : _a.click();
1120
1274
  },
1121
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.ImagePlus, { className: "size-3.5", "aria-hidden": "true" })
1275
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.ImagePlus, { className: "size-3.5", "aria-hidden": "true" })
1122
1276
  }
1123
1277
  ),
1124
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1278
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1125
1279
  "input",
1126
1280
  {
1127
1281
  ref: imageInputRef,
@@ -1135,7 +1289,7 @@ function ChatInputArea({
1135
1289
  )
1136
1290
  ] })
1137
1291
  ] }),
1138
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1292
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1139
1293
  Button,
1140
1294
  {
1141
1295
  size: "icon-sm",
@@ -1143,12 +1297,12 @@ function ChatInputArea({
1143
1297
  "aria-label": "Send message",
1144
1298
  disabled: !value.trim() || disabled,
1145
1299
  onClick: handleSend,
1146
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.Send, { className: "size-3.5", "aria-hidden": "true" })
1300
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.Send, { className: "size-3.5", "aria-hidden": "true" })
1147
1301
  }
1148
1302
  )
1149
1303
  ] })
1150
1304
  ] }),
1151
- hint !== false && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs text-muted-foreground", children: hint })
1305
+ hint !== false && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-xs text-muted-foreground", children: hint })
1152
1306
  ]
1153
1307
  }
1154
1308
  );
@@ -1156,50 +1310,7 @@ function ChatInputArea({
1156
1310
 
1157
1311
  // src/components/ui/chat-widget-primitives.tsx
1158
1312
  var import_lucide_react5 = require("lucide-react");
1159
-
1160
- // src/components/ui/avatar.tsx
1161
- var import_avatar = require("@base-ui/react/avatar");
1162
- var import_jsx_runtime13 = require("react/jsx-runtime");
1163
- function Avatar(_a) {
1164
- var _b = _a, {
1165
- className,
1166
- size = "default"
1167
- } = _b, props = __objRest(_b, [
1168
- "className",
1169
- "size"
1170
- ]);
1171
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1172
- import_avatar.Avatar.Root,
1173
- __spreadValues({
1174
- className: cn(
1175
- "group/avatar relative flex size-8 shrink-0 rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
1176
- className
1177
- ),
1178
- "data-size": size,
1179
- "data-slot": "avatar"
1180
- }, props)
1181
- );
1182
- }
1183
- function AvatarFallback(_a) {
1184
- var _b = _a, {
1185
- className
1186
- } = _b, props = __objRest(_b, [
1187
- "className"
1188
- ]);
1189
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1190
- import_avatar.Avatar.Fallback,
1191
- __spreadValues({
1192
- className: cn(
1193
- "flex size-full items-center justify-center rounded-full overflow-hidden bg-muted text-body-small font-sans text-muted-foreground group-data-[size=sm]/avatar:text-caption",
1194
- className
1195
- ),
1196
- "data-slot": "avatar-fallback"
1197
- }, props)
1198
- );
1199
- }
1200
-
1201
- // src/components/ui/chat-widget-primitives.tsx
1202
- var import_jsx_runtime14 = require("react/jsx-runtime");
1313
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1203
1314
  function ChatWidgetMessage({
1204
1315
  role,
1205
1316
  content,
@@ -1208,10 +1319,10 @@ function ChatWidgetMessage({
1208
1319
  className
1209
1320
  }) {
1210
1321
  if (role === "system") {
1211
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn("flex items-center justify-center py-2", className), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-body-small text-muted-foreground", children: content }) });
1322
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn("flex items-center justify-center py-2", className), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-body-small text-muted-foreground", children: content }) });
1212
1323
  }
1213
1324
  const isLeft = role === "bot" || role === "advisor";
1214
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1325
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1215
1326
  "div",
1216
1327
  {
1217
1328
  className: cn(
@@ -1220,14 +1331,14 @@ function ChatWidgetMessage({
1220
1331
  className
1221
1332
  ),
1222
1333
  children: [
1223
- isLeft && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Avatar, { className: "size-7", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1334
+ isLeft && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Avatar, { className: "size-7", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1224
1335
  AvatarFallback,
1225
1336
  {
1226
1337
  className: role === "advisor" ? "bg-primary/15 text-foreground" : void 0,
1227
- children: role === "advisor" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.UserRound, { className: "size-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.Bot, { className: "size-3.5" })
1338
+ children: role === "advisor" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.UserRound, { className: "size-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Bot, { className: "size-3.5" })
1228
1339
  }
1229
1340
  ) }),
1230
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1341
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1231
1342
  "div",
1232
1343
  {
1233
1344
  className: cn(
@@ -1235,7 +1346,7 @@ function ChatWidgetMessage({
1235
1346
  !isLeft && "items-end"
1236
1347
  ),
1237
1348
  children: [
1238
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1349
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1239
1350
  "div",
1240
1351
  {
1241
1352
  className: cn(
@@ -1243,10 +1354,10 @@ function ChatWidgetMessage({
1243
1354
  isLeft ? "border border-border bg-card text-card-foreground shadow-sm" : "text-primary-foreground"
1244
1355
  ),
1245
1356
  style: !isLeft ? { backgroundColor: "var(--primary)" } : void 0,
1246
- children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChatWidgetTypingIndicator, {}) : content
1357
+ children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChatWidgetTypingIndicator, {}) : content
1247
1358
  }
1248
1359
  ),
1249
- timestamp && !isStreaming && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-[10px] text-muted-foreground", children: timestamp })
1360
+ timestamp && !isStreaming && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[10px] text-muted-foreground", children: timestamp })
1250
1361
  ]
1251
1362
  }
1252
1363
  )
@@ -1257,13 +1368,13 @@ function ChatWidgetMessage({
1257
1368
  function ChatWidgetTypingIndicator({
1258
1369
  className
1259
1370
  }) {
1260
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1371
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1261
1372
  "div",
1262
1373
  {
1263
1374
  role: "status",
1264
1375
  "aria-label": "Typing",
1265
1376
  className: cn("flex items-center gap-1 py-0.5", className),
1266
- children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1377
+ children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1267
1378
  "span",
1268
1379
  {
1269
1380
  className: "size-1.5 animate-bounce rounded-full bg-muted-foreground/60",
@@ -1277,7 +1388,7 @@ function ChatWidgetTypingIndicator({
1277
1388
  }
1278
1389
 
1279
1390
  // src/components/ui/policy-ai/policy-ai-panel.tsx
1280
- var import_jsx_runtime15 = require("react/jsx-runtime");
1391
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1281
1392
  var DEFAULT_SUGGESTED = {
1282
1393
  Income: [
1283
1394
  "Which banks accept casual income?",
@@ -1321,11 +1432,11 @@ function PolicyAIThinkingSteps({ steps }) {
1321
1432
  const timer = setTimeout(() => setCurrentStep((s) => s + 1), 1400);
1322
1433
  return () => clearTimeout(timer);
1323
1434
  }, [currentStep, steps.length]);
1324
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex flex-col gap-2.5 px-4 py-3", children: steps.map((step, i) => {
1435
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex flex-col gap-2.5 px-4 py-3", children: steps.map((step, i) => {
1325
1436
  const isDone = i < currentStep;
1326
1437
  const isCurrent = i === currentStep;
1327
1438
  const isPending = i > currentStep;
1328
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1439
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1329
1440
  "div",
1330
1441
  {
1331
1442
  className: cn(
@@ -1333,12 +1444,12 @@ function PolicyAIThinkingSteps({ steps }) {
1333
1444
  isPending && "opacity-30"
1334
1445
  ),
1335
1446
  children: [
1336
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "shrink-0 size-4 flex items-center justify-center", children: isDone ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.Check, { className: "size-3.5 text-primary", "aria-hidden": "true" }) : isCurrent ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1447
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "shrink-0 size-4 flex items-center justify-center", children: isDone ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Check, { className: "size-3.5 text-primary", "aria-hidden": "true" }) : isCurrent ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1337
1448
  "span",
1338
1449
  {
1339
1450
  className: "flex items-center gap-0.5",
1340
1451
  "aria-label": "In progress",
1341
- children: [0, 1, 2].map((j) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1452
+ children: [0, 1, 2].map((j) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1342
1453
  "span",
1343
1454
  {
1344
1455
  className: "size-1 bg-muted-foreground/70 animate-bounce",
@@ -1348,7 +1459,7 @@ function PolicyAIThinkingSteps({ steps }) {
1348
1459
  ))
1349
1460
  }
1350
1461
  ) : null }),
1351
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1462
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1352
1463
  "span",
1353
1464
  {
1354
1465
  className: cn(
@@ -1371,7 +1482,7 @@ function ResponseCard({
1371
1482
  queryContext
1372
1483
  }) {
1373
1484
  if (content.type === "single_bank") {
1374
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1485
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1375
1486
  PolicySingleBankAnswer,
1376
1487
  {
1377
1488
  bankName: content.bankName,
@@ -1383,7 +1494,7 @@ function ResponseCard({
1383
1494
  );
1384
1495
  }
1385
1496
  if (content.type === "cross_bank_comparison") {
1386
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1497
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1387
1498
  PolicyComparisonTable,
1388
1499
  {
1389
1500
  categories: content.categories,
@@ -1395,7 +1506,7 @@ function ResponseCard({
1395
1506
  );
1396
1507
  }
1397
1508
  if (content.type === "ranked_list") {
1398
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1509
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1399
1510
  PolicyRankedList,
1400
1511
  {
1401
1512
  categories: content.categories,
@@ -1412,8 +1523,8 @@ function PolicyAIFAB({
1412
1523
  hasNudge,
1413
1524
  className
1414
1525
  }) {
1415
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cn("relative inline-flex shrink-0", className), children: [
1416
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1526
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cn("relative inline-flex shrink-0", className), children: [
1527
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1417
1528
  Button,
1418
1529
  {
1419
1530
  "data-slot": "policy-ai-fab",
@@ -1421,14 +1532,14 @@ function PolicyAIFAB({
1421
1532
  onClick,
1422
1533
  className: "size-12 shadow-lg rounded-full",
1423
1534
  "aria-label": "Open Policy AI",
1424
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.BrainCircuit, { className: "size-5", "aria-hidden": "true" })
1535
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.BrainCircuit, { className: "size-5", "aria-hidden": "true" })
1425
1536
  }
1426
1537
  ),
1427
- hasNudge && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "absolute -top-1 -right-1 size-3 bg-destructive rounded-full border-2 border-background" })
1538
+ hasNudge && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "absolute -top-1 -right-1 size-3 bg-destructive rounded-full border-2 border-background" })
1428
1539
  ] });
1429
1540
  }
1430
1541
  function PolicyAIPanel({
1431
- open,
1542
+ open = true,
1432
1543
  onClose,
1433
1544
  messages = [],
1434
1545
  suggestedQuestions,
@@ -1466,7 +1577,7 @@ function PolicyAIPanel({
1466
1577
  );
1467
1578
  if (!open) return null;
1468
1579
  const positionClass = position === "bottom-left" ? "left-6" : "right-6";
1469
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1580
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1470
1581
  "div",
1471
1582
  {
1472
1583
  "data-slot": "policy-ai-panel",
@@ -1485,17 +1596,17 @@ function PolicyAIPanel({
1485
1596
  maxHeight: minimised ? "auto" : "min(600px, calc(100vh - 120px))"
1486
1597
  },
1487
1598
  children: [
1488
- !inline && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "shrink-0 flex items-center gap-2.5 px-3 py-2.5 border-b border-border bg-card", children: [
1489
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1599
+ !inline && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "shrink-0 flex items-center gap-2.5 px-3 py-2.5 border-b border-border bg-card", children: [
1600
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1490
1601
  import_lucide_react6.BrainCircuit,
1491
1602
  {
1492
1603
  className: "size-4 text-primary shrink-0",
1493
1604
  "aria-hidden": "true"
1494
1605
  }
1495
1606
  ),
1496
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-sm font-semibold text-foreground flex-1 truncate", children: "Policy AI" }),
1497
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-0.5", children: [
1498
- isChatMode && onReset && !minimised && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1607
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-sm font-semibold text-foreground flex-1 truncate", children: "Policy AI" }),
1608
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-0.5", children: [
1609
+ isChatMode && onReset && !minimised && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1499
1610
  Button,
1500
1611
  {
1501
1612
  variant: "ghost",
@@ -1503,10 +1614,10 @@ function PolicyAIPanel({
1503
1614
  onClick: onReset,
1504
1615
  title: "New conversation",
1505
1616
  "aria-label": "New conversation",
1506
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.RotateCcw, { className: "size-3.5", "aria-hidden": "true" })
1617
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.RotateCcw, { className: "size-3.5", "aria-hidden": "true" })
1507
1618
  }
1508
1619
  ),
1509
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1620
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1510
1621
  Button,
1511
1622
  {
1512
1623
  variant: "ghost",
@@ -1514,10 +1625,10 @@ function PolicyAIPanel({
1514
1625
  onClick: () => setMinimised((v) => !v),
1515
1626
  title: minimised ? "Restore" : "Minimise",
1516
1627
  "aria-label": minimised ? "Restore panel" : "Minimise panel",
1517
- children: minimised ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.ChevronDown, { className: "size-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.Minus, { className: "size-3.5", "aria-hidden": "true" })
1628
+ children: minimised ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.ChevronDown, { className: "size-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Minus, { className: "size-3.5", "aria-hidden": "true" })
1518
1629
  }
1519
1630
  ),
1520
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1631
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1521
1632
  Button,
1522
1633
  {
1523
1634
  variant: "ghost",
@@ -1525,65 +1636,68 @@ function PolicyAIPanel({
1525
1636
  onClick: onClose,
1526
1637
  title: "Close",
1527
1638
  "aria-label": "Close Policy AI",
1528
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.X, { className: "size-3.5", "aria-hidden": "true" })
1639
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.X, { className: "size-3.5", "aria-hidden": "true" })
1529
1640
  }
1530
1641
  )
1531
1642
  ] })
1532
1643
  ] }),
1533
- (!minimised || inline) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
1534
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn(!inline && "flex-1 overflow-y-auto min-h-0"), children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex flex-col justify-center h-full py-8", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PolicyAIThinkingSteps, { steps: resolvedThinkingSteps }) }) : !isChatMode ? (
1644
+ (!minimised || inline) && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
1645
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex-1 overflow-y-auto min-h-0", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex flex-col justify-center h-full py-8", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PolicyAIThinkingSteps, { steps: resolvedThinkingSteps }) }) : !isChatMode ? (
1535
1646
  /* Home state — suggested questions by policy type */
1536
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col", children: [
1537
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "px-3 pt-3 pb-2", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-xs text-muted-foreground leading-relaxed", children: "Ask me about lending policies across 40+ Australian banks \u2014 income, LVR, security types, serviceability, and more." }) }),
1538
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "border-b border-border px-3 pt-1", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1539
- Tabs,
1540
- {
1541
- value: activeTab,
1542
- onValueChange: (v) => setActiveTab(v),
1543
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1544
- TabsList,
1647
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-3 px-3 py-3", children: [
1648
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm text-muted-foreground", children: "Ask me about lending policies across 40+ Australian banks \u2014 income, LVR, security types, serviceability, and more." }),
1649
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1650
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-overline text-muted-foreground", children: "Suggested" }),
1651
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Card, { className: "gap-0 py-0 shadow-none overflow-hidden", children: [
1652
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "border-b border-border px-3 pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1653
+ Tabs,
1545
1654
  {
1546
- variant: "line",
1547
- className: "justify-start h-8 gap-0 -mb-px overflow-x-auto",
1548
- children: Object.keys(DEFAULT_SUGGESTED).map(
1549
- (type) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1550
- TabsTrigger,
1551
- {
1552
- value: type,
1553
- className: "text-xs px-2 h-7 shrink-0",
1554
- children: type
1555
- },
1556
- type
1557
- )
1655
+ value: activeTab,
1656
+ onValueChange: (v) => setActiveTab(v),
1657
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1658
+ TabsList,
1659
+ {
1660
+ variant: "line",
1661
+ className: "justify-start h-8 gap-0 -mb-px overflow-x-auto",
1662
+ children: Object.keys(DEFAULT_SUGGESTED).map((type) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1663
+ TabsTrigger,
1664
+ {
1665
+ value: type,
1666
+ className: "px-2 h-7 shrink-0",
1667
+ children: type
1668
+ },
1669
+ type
1670
+ ))
1671
+ }
1558
1672
  )
1559
1673
  }
1560
- )
1561
- }
1562
- ) }),
1563
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex flex-col px-3 py-2 gap-1", children: ((_a = (suggestedQuestions != null ? suggestedQuestions : DEFAULT_SUGGESTED)[activeTab]) != null ? _a : []).map((q) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1564
- "button",
1565
- {
1566
- onClick: () => setInputValue(q),
1567
- className: "w-full text-left text-xs text-foreground px-3 py-2 border border-border hover:bg-muted/60 transition-colors leading-relaxed",
1568
- children: q
1569
- },
1570
- q
1571
- )) })
1674
+ ) }),
1675
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "divide-y divide-border", children: ((_a = (suggestedQuestions != null ? suggestedQuestions : DEFAULT_SUGGESTED)[activeTab]) != null ? _a : []).map((q) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1676
+ "button",
1677
+ {
1678
+ onClick: () => setInputValue(q),
1679
+ className: "w-full text-left text-sm text-foreground px-3 py-2.5 hover:bg-muted/60 transition-colors",
1680
+ children: q
1681
+ },
1682
+ q
1683
+ )) })
1684
+ ] })
1685
+ ] })
1572
1686
  ] })
1573
1687
  ) : (
1574
1688
  /* Chat state — messages + structured response cards */
1575
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-4 px-3 py-3", children: [
1689
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-4 px-3 py-3", children: [
1576
1690
  messages.map(
1577
- (msg) => msg.role === "user" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1691
+ (msg) => msg.role === "user" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1578
1692
  ChatWidgetMessage,
1579
1693
  {
1580
1694
  role: "user",
1581
1695
  content: msg.content
1582
1696
  },
1583
1697
  msg.id
1584
- ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1585
- msg.content && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-foreground leading-relaxed", children: msg.content }),
1586
- msg.responseContent && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1698
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1699
+ msg.content && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm text-foreground leading-relaxed", children: msg.content }),
1700
+ msg.responseContent && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1587
1701
  ResponseCard,
1588
1702
  {
1589
1703
  content: msg.responseContent,
@@ -1592,30 +1706,470 @@ function PolicyAIPanel({
1592
1706
  )
1593
1707
  ] }, msg.id)
1594
1708
  ),
1595
- isStreaming && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PolicyAIThinkingSteps, { steps: resolvedThinkingSteps }),
1596
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: messagesEndRef })
1709
+ isStreaming && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PolicyAIThinkingSteps, { steps: resolvedThinkingSteps }),
1710
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: messagesEndRef })
1597
1711
  ] })
1598
1712
  ) }),
1599
- !isLoading && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1600
- "div",
1713
+ !isLoading && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "shrink-0 border-t border-border px-3 py-3 bg-card", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1714
+ ChatInputArea,
1601
1715
  {
1602
- className: cn(
1603
- "border-t border-border px-3 py-3 bg-card",
1604
- inline ? "sticky bottom-0 z-10" : "shrink-0"
1605
- ),
1606
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1607
- ChatInputArea,
1716
+ value: inputValue,
1717
+ onChange: setInputValue,
1718
+ onSend: handleSend,
1719
+ onAttachFile,
1720
+ onAttachImage,
1721
+ disabled: isStreaming,
1722
+ placeholder: "Ask about lending policies\u2026",
1723
+ autoFocus: !minimised,
1724
+ showMarkdownToolbar: true
1725
+ }
1726
+ ) })
1727
+ ] })
1728
+ ]
1729
+ }
1730
+ );
1731
+ }
1732
+
1733
+ // src/components/ui/policy-ai/policy-ai-history-panel.tsx
1734
+ var import_lucide_react7 = require("lucide-react");
1735
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1736
+ function PolicyAIHistoryItem({
1737
+ conv,
1738
+ isActive,
1739
+ onClick
1740
+ }) {
1741
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1742
+ "button",
1743
+ {
1744
+ type: "button",
1745
+ onClick,
1746
+ className: cn(
1747
+ "w-full flex items-start gap-3 px-3 py-3 text-left transition-colors",
1748
+ "border-b border-border last:border-b-0",
1749
+ isActive ? "bg-muted" : "hover:bg-muted/40"
1750
+ ),
1751
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
1752
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1753
+ "span",
1754
+ {
1755
+ className: cn(
1756
+ "text-sm leading-snug line-clamp-2 min-w-0",
1757
+ isActive ? "font-semibold text-foreground" : "text-foreground"
1758
+ ),
1759
+ children: conv.title
1760
+ }
1761
+ ),
1762
+ conv.timestamp && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "shrink-0 text-caption text-muted-foreground whitespace-nowrap", children: conv.timestamp })
1763
+ ] }) })
1764
+ }
1765
+ );
1766
+ }
1767
+ function PolicyAIHistoryPanel({
1768
+ conversations,
1769
+ activeId,
1770
+ onSelect,
1771
+ onNewChat,
1772
+ searchQuery = "",
1773
+ onSearchChange,
1774
+ className
1775
+ }) {
1776
+ const filtered = searchQuery ? conversations.filter(
1777
+ (c) => c.title.toLowerCase().includes(searchQuery.toLowerCase())
1778
+ ) : conversations;
1779
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1780
+ "div",
1781
+ {
1782
+ "data-slot": "policy-ai-history-panel",
1783
+ className: cn(
1784
+ "flex flex-col h-full border-r border-border bg-background shrink-0",
1785
+ className
1786
+ ),
1787
+ children: [
1788
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "shrink-0 flex flex-col", children: [
1789
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex items-center gap-2 border-b border-border px-3 py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1790
+ Button,
1791
+ {
1792
+ size: "sm",
1793
+ className: "w-full justify-start gap-2",
1794
+ onClick: onNewChat,
1795
+ children: [
1796
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1797
+ import_lucide_react7.MessageSquarePlus,
1798
+ {
1799
+ className: "size-3.5 shrink-0",
1800
+ "aria-hidden": "true"
1801
+ }
1802
+ ),
1803
+ "New Chat"
1804
+ ]
1805
+ }
1806
+ ) }),
1807
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex items-center border-b border-border px-3 py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "relative flex-1", children: [
1808
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1809
+ import_lucide_react7.Search,
1810
+ {
1811
+ className: "absolute left-2.5 top-1/2 -translate-y-1/2 size-3.5 text-muted-foreground pointer-events-none",
1812
+ "aria-hidden": "true"
1813
+ }
1814
+ ),
1815
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1816
+ Input,
1817
+ {
1818
+ value: searchQuery,
1819
+ onChange: (e) => onSearchChange == null ? void 0 : onSearchChange(e.target.value),
1820
+ placeholder: "Search conversations...",
1821
+ className: "h-8 pl-8 text-sm",
1822
+ "aria-label": "Search conversations"
1823
+ }
1824
+ )
1825
+ ] }) })
1826
+ ] }),
1827
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-1 overflow-y-auto min-h-0", tabIndex: 0, children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col items-center justify-center gap-2 p-8 text-muted-foreground", children: [
1828
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.BrainCircuit, { className: "size-8 opacity-30", "aria-hidden": "true" }),
1829
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm", children: searchQuery ? "No conversations found." : "No recent sessions." }),
1830
+ searchQuery && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1831
+ Button,
1832
+ {
1833
+ variant: "outline",
1834
+ size: "sm",
1835
+ onClick: () => onSearchChange == null ? void 0 : onSearchChange(""),
1836
+ children: "Clear search"
1837
+ }
1838
+ )
1839
+ ] }) : filtered.map((conv) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1840
+ PolicyAIHistoryItem,
1841
+ {
1842
+ conv,
1843
+ isActive: conv.id === activeId,
1844
+ onClick: () => onSelect == null ? void 0 : onSelect(conv.id)
1845
+ },
1846
+ conv.id
1847
+ )) })
1848
+ ]
1849
+ }
1850
+ );
1851
+ }
1852
+
1853
+ // src/components/ui/policy-ai/policy-ai-context-sidebar.tsx
1854
+ var import_lucide_react8 = require("lucide-react");
1855
+
1856
+ // src/components/ui/separator.tsx
1857
+ var import_separator = require("@base-ui/react/separator");
1858
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1859
+ function Separator(_a) {
1860
+ var _b = _a, {
1861
+ className,
1862
+ orientation = "horizontal"
1863
+ } = _b, props = __objRest(_b, [
1864
+ "className",
1865
+ "orientation"
1866
+ ]);
1867
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1868
+ import_separator.Separator,
1869
+ __spreadValues({
1870
+ className: cn(
1871
+ "shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
1872
+ className
1873
+ ),
1874
+ "data-orientation": orientation,
1875
+ "data-slot": "separator"
1876
+ }, props)
1877
+ );
1878
+ }
1879
+
1880
+ // src/components/ui/policy-ai/policy-ai-context-sidebar.tsx
1881
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1882
+ var QUERY_TYPE_DESCRIPTIONS = {
1883
+ single_bank: "Answered from a single bank's policy documents.",
1884
+ cross_bank_comparison: "Compared across all indexed banks simultaneously.",
1885
+ threshold_filter: "Filtered banks against a specific threshold or limit.",
1886
+ ranking: "Ranked banks using TOPSIS multi-criteria scoring.",
1887
+ scenario_match: "Matched your scenario against all bank lending criteria.",
1888
+ general: "General policy question answered from the knowledge base."
1889
+ };
1890
+ var QUERY_TYPE_LABELS2 = {
1891
+ single_bank: "Single bank",
1892
+ cross_bank_comparison: "Cross-bank",
1893
+ threshold_filter: "Threshold filter",
1894
+ ranking: "Ranked list",
1895
+ scenario_match: "Scenario match",
1896
+ general: "General"
1897
+ };
1898
+ function SidebarSection({
1899
+ title,
1900
+ children,
1901
+ className
1902
+ }) {
1903
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cn("flex flex-col gap-2", className), children: [
1904
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-overline text-muted-foreground px-3", children: title }),
1905
+ children
1906
+ ] });
1907
+ }
1908
+ function StatRow({
1909
+ icon: Icon,
1910
+ children
1911
+ }) {
1912
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2.5", children: [
1913
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1914
+ Icon,
1915
+ {
1916
+ className: "size-3.5 text-muted-foreground shrink-0",
1917
+ "aria-hidden": "true"
1918
+ }
1919
+ ),
1920
+ children
1921
+ ] });
1922
+ }
1923
+ function PolicyAIContextSidebar({
1924
+ lastQueryContext,
1925
+ suggestedFollowUps,
1926
+ onFollowUpClick,
1927
+ bankCount = 42,
1928
+ categoryCount = 86,
1929
+ lastUpdated = "June 2026",
1930
+ className
1931
+ }) {
1932
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1933
+ "div",
1934
+ {
1935
+ "data-slot": "policy-ai-context-sidebar",
1936
+ className: cn(
1937
+ "flex flex-col h-full border-l border-border bg-card shrink-0 overflow-y-auto",
1938
+ className
1939
+ ),
1940
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-5 px-0 py-4", children: [
1941
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SidebarSection, { title: "Coverage", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1.5 px-3", children: [
1942
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatRow, { icon: import_lucide_react8.BrainCircuit, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-sm text-foreground", children: [
1943
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "font-semibold", children: bankCount }),
1944
+ " banks indexed"
1945
+ ] }) }),
1946
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatRow, { icon: import_lucide_react8.Layers, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-sm text-foreground", children: [
1947
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "font-semibold", children: categoryCount }),
1948
+ " policy categories"
1949
+ ] }) }),
1950
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatRow, { icon: import_lucide_react8.Database, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-caption text-muted-foreground", children: [
1951
+ "Updated ",
1952
+ lastUpdated
1953
+ ] }) })
1954
+ ] }) }),
1955
+ lastQueryContext && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
1956
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Separator, {}),
1957
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SidebarSection, { title: "Last Query", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Card, { className: "gap-0 py-0 shadow-none overflow-hidden mx-3", children: [
1958
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border bg-muted/30", children: [
1959
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-sm font-semibold text-foreground", children: lastQueryContext.policyType }),
1960
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Badge, { variant: "outline", className: "text-xs shrink-0", children: QUERY_TYPE_LABELS2[lastQueryContext.queryType] })
1961
+ ] }),
1962
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-2 px-3 py-2.5", children: [
1963
+ lastQueryContext.bankName && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-semibold text-foreground leading-none", children: lastQueryContext.bankName }),
1964
+ lastQueryContext.categories.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex flex-wrap gap-1", children: lastQueryContext.categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1965
+ Badge,
1608
1966
  {
1609
- value: inputValue,
1610
- onChange: setInputValue,
1611
- onSend: handleSend,
1612
- onAttachFile,
1613
- onAttachImage,
1614
- disabled: isStreaming,
1615
- placeholder: "Ask about lending policies\u2026",
1616
- autoFocus: !minimised
1617
- }
1618
- )
1967
+ variant: "secondary",
1968
+ className: "text-xs font-normal",
1969
+ children: cat
1970
+ },
1971
+ cat
1972
+ )) })
1973
+ ] }),
1974
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "border-t border-border px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-caption text-muted-foreground leading-snug", children: QUERY_TYPE_DESCRIPTIONS[lastQueryContext.queryType] }) })
1975
+ ] }) })
1976
+ ] }),
1977
+ !!(suggestedFollowUps == null ? void 0 : suggestedFollowUps.length) && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
1978
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Separator, {}),
1979
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SidebarSection, { title: "Follow-ups", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex flex-col gap-1 px-3", children: suggestedFollowUps.map((q) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1980
+ Button,
1981
+ {
1982
+ variant: "outline",
1983
+ size: "sm",
1984
+ className: "w-full justify-start h-auto py-1.5 text-muted-foreground font-normal leading-snug whitespace-normal text-left",
1985
+ onClick: () => onFollowUpClick == null ? void 0 : onFollowUpClick(q),
1986
+ children: q
1987
+ },
1988
+ q
1989
+ )) }) })
1990
+ ] })
1991
+ ] })
1992
+ }
1993
+ );
1994
+ }
1995
+
1996
+ // src/components/ui/policy-ai/policy-ai-page.tsx
1997
+ var React8 = __toESM(require("react"));
1998
+ var import_lucide_react10 = require("lucide-react");
1999
+
2000
+ // src/components/ui/page-top-bar.tsx
2001
+ var import_lucide_react9 = require("lucide-react");
2002
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2003
+ function PageTopBar({
2004
+ title,
2005
+ actions,
2006
+ onAskSupport,
2007
+ className
2008
+ }) {
2009
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
2010
+ "div",
2011
+ {
2012
+ "data-slot": "page-top-bar",
2013
+ className: cn(
2014
+ "flex shrink-0 items-center justify-between gap-4",
2015
+ "border-b border-border bg-background px-6 py-3",
2016
+ className
2017
+ ),
2018
+ children: [
2019
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { className: "text-lg font-semibold leading-tight", children: title }),
2020
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2", children: [
2021
+ actions,
2022
+ onAskSupport && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Button, { variant: "outline", size: "sm", onClick: onAskSupport, children: [
2023
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Bot, { className: "size-3.5", "aria-hidden": "true" }),
2024
+ "Ask Support"
2025
+ ] })
2026
+ ] })
2027
+ ]
2028
+ }
2029
+ );
2030
+ }
2031
+
2032
+ // src/components/ui/policy-ai/policy-ai-page.tsx
2033
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2034
+ function deriveFollowUps(context) {
2035
+ var _a;
2036
+ if (!context) return [];
2037
+ const { queryType, policyType, bankName } = context;
2038
+ if (queryType === "cross_bank_comparison") {
2039
+ return [
2040
+ `Which of these banks is best overall for ${(_a = context.categories[0]) != null ? _a : policyType}?`,
2041
+ bankName ? `Does ${bankName} have any exceptions?` : "Which bank has the most flexible policy?",
2042
+ "Show me the ranked list of lenders."
2043
+ ];
2044
+ }
2045
+ if (queryType === "ranking") {
2046
+ return [
2047
+ `What are the full details for the #1 ranked bank?`,
2048
+ `Which banks in the list accept cases under 80% LVR?`,
2049
+ `Compare the top 3 banks side by side.`
2050
+ ];
2051
+ }
2052
+ if (queryType === "single_bank") {
2053
+ return [
2054
+ `How does ${bankName != null ? bankName : "this bank"} compare to other lenders?`,
2055
+ `What documentation does ${bankName != null ? bankName : "this bank"} require?`,
2056
+ `Which banks have a better policy than ${bankName != null ? bankName : "this bank"}?`
2057
+ ];
2058
+ }
2059
+ if (queryType === "threshold_filter") {
2060
+ return [
2061
+ `What is the maximum LVR across all filtered banks?`,
2062
+ `Are any of these banks on a specialist product?`,
2063
+ `Rank the filtered banks best to worst.`
2064
+ ];
2065
+ }
2066
+ return [];
2067
+ }
2068
+ function PolicyAIPage({
2069
+ // Chat
2070
+ messages = [],
2071
+ suggestedQuestions,
2072
+ isStreaming = false,
2073
+ isLoading = false,
2074
+ thinkingSteps,
2075
+ onSendMessage,
2076
+ onAttachFile,
2077
+ onAttachImage,
2078
+ onReset,
2079
+ // History
2080
+ conversations = [],
2081
+ activeConversationId,
2082
+ onSelectConversation,
2083
+ onNewChat,
2084
+ // Context
2085
+ defaultShowContextPanel = true,
2086
+ bankCount = 42,
2087
+ categoryCount = 86,
2088
+ lastUpdated = "June 2026",
2089
+ onAskSupport,
2090
+ className
2091
+ }) {
2092
+ const [showContextPanel, setShowContextPanel] = React8.useState(
2093
+ defaultShowContextPanel
2094
+ );
2095
+ const [historySearch, setHistorySearch] = React8.useState("");
2096
+ const lastQueryContext = React8.useMemo(() => {
2097
+ for (let i = messages.length - 1; i >= 0; i--) {
2098
+ const m = messages[i];
2099
+ if (m.role === "assistant" && m.queryContext) return m.queryContext;
2100
+ }
2101
+ return void 0;
2102
+ }, [messages]);
2103
+ const followUps = deriveFollowUps(lastQueryContext);
2104
+ const handleNewChat = () => {
2105
+ onReset == null ? void 0 : onReset();
2106
+ onNewChat == null ? void 0 : onNewChat();
2107
+ };
2108
+ const panelToggleLabel = showContextPanel ? "Hide context panel" : "Show context panel";
2109
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2110
+ "div",
2111
+ {
2112
+ "data-slot": "policy-ai-page",
2113
+ className: cn("flex flex-col h-full bg-background", className),
2114
+ children: [
2115
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2116
+ PageTopBar,
2117
+ {
2118
+ title: "Policy AI",
2119
+ actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2120
+ Button,
2121
+ {
2122
+ variant: "ghost",
2123
+ size: "icon-sm",
2124
+ onClick: () => setShowContextPanel((v) => !v),
2125
+ "aria-label": panelToggleLabel,
2126
+ "aria-pressed": showContextPanel,
2127
+ title: panelToggleLabel,
2128
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.PanelRight, { className: "size-4", "aria-hidden": "true" })
2129
+ }
2130
+ ),
2131
+ onAskSupport
2132
+ }
2133
+ ),
2134
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-1 min-h-0 overflow-hidden", children: [
2135
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2136
+ PolicyAIHistoryPanel,
2137
+ {
2138
+ conversations,
2139
+ activeId: activeConversationId,
2140
+ onSelect: onSelectConversation,
2141
+ onNewChat: handleNewChat,
2142
+ searchQuery: historySearch,
2143
+ onSearchChange: setHistorySearch,
2144
+ className: "w-[260px]"
2145
+ }
2146
+ ),
2147
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 flex flex-col min-w-0 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2148
+ PolicyAIPanel,
2149
+ {
2150
+ inline: true,
2151
+ messages,
2152
+ suggestedQuestions,
2153
+ isStreaming,
2154
+ isLoading,
2155
+ thinkingSteps,
2156
+ onSendMessage,
2157
+ onAttachFile,
2158
+ onAttachImage,
2159
+ onReset,
2160
+ className: "flex-1 min-h-0"
2161
+ }
2162
+ ) }),
2163
+ showContextPanel && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2164
+ PolicyAIContextSidebar,
2165
+ {
2166
+ lastQueryContext,
2167
+ suggestedFollowUps: followUps,
2168
+ onFollowUpClick: onSendMessage,
2169
+ bankCount,
2170
+ categoryCount,
2171
+ lastUpdated,
2172
+ className: "w-[280px]"
1619
2173
  }
1620
2174
  )
1621
2175
  ] })
@@ -1625,7 +2179,10 @@ function PolicyAIPanel({
1625
2179
  }
1626
2180
  // Annotate the CommonJS export names for ESM import in node:
1627
2181
  0 && (module.exports = {
2182
+ PolicyAIContextSidebar,
1628
2183
  PolicyAIFAB,
2184
+ PolicyAIHistoryPanel,
2185
+ PolicyAIPage,
1629
2186
  PolicyAIPanel,
1630
2187
  PolicyCitationPanel,
1631
2188
  PolicyComparisonTable,