@papernote/ui 1.10.26 → 1.11.0

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 (58) hide show
  1. package/dist/components/ActionCard.d.ts +48 -0
  2. package/dist/components/ActionCard.d.ts.map +1 -0
  3. package/dist/components/AnomalyBanner.d.ts +27 -0
  4. package/dist/components/AnomalyBanner.d.ts.map +1 -0
  5. package/dist/components/CaseQueueItem.d.ts +35 -0
  6. package/dist/components/CaseQueueItem.d.ts.map +1 -0
  7. package/dist/components/ConfidenceBadge.d.ts +19 -0
  8. package/dist/components/ConfidenceBadge.d.ts.map +1 -0
  9. package/dist/components/ConfidenceIndicator.d.ts +25 -0
  10. package/dist/components/ConfidenceIndicator.d.ts.map +1 -0
  11. package/dist/components/EntityCard.d.ts +46 -0
  12. package/dist/components/EntityCard.d.ts.map +1 -0
  13. package/dist/components/FunnelChart.d.ts +31 -0
  14. package/dist/components/FunnelChart.d.ts.map +1 -0
  15. package/dist/components/MatchIndicator.d.ts +20 -0
  16. package/dist/components/MatchIndicator.d.ts.map +1 -0
  17. package/dist/components/PersonaDashboard.d.ts +39 -0
  18. package/dist/components/PersonaDashboard.d.ts.map +1 -0
  19. package/dist/components/ProcessHealthBar.d.ts +28 -0
  20. package/dist/components/ProcessHealthBar.d.ts.map +1 -0
  21. package/dist/components/ProcessIndicator.d.ts +38 -0
  22. package/dist/components/ProcessIndicator.d.ts.map +1 -0
  23. package/dist/components/ReviewDecisionCard.d.ts +53 -0
  24. package/dist/components/ReviewDecisionCard.d.ts.map +1 -0
  25. package/dist/components/SLAIndicator.d.ts +24 -0
  26. package/dist/components/SLAIndicator.d.ts.map +1 -0
  27. package/dist/components/SplitPane.d.ts +33 -0
  28. package/dist/components/SplitPane.d.ts.map +1 -0
  29. package/dist/components/SystemActionEntry.d.ts +42 -0
  30. package/dist/components/SystemActionEntry.d.ts.map +1 -0
  31. package/dist/components/VarianceDisplay.d.ts +26 -0
  32. package/dist/components/VarianceDisplay.d.ts.map +1 -0
  33. package/dist/components/index.d.ts +32 -0
  34. package/dist/components/index.d.ts.map +1 -1
  35. package/dist/index.d.ts +529 -2
  36. package/dist/index.esm.js +661 -28
  37. package/dist/index.esm.js.map +1 -1
  38. package/dist/index.js +675 -26
  39. package/dist/index.js.map +1 -1
  40. package/dist/styles.css +369 -0
  41. package/package.json +1 -1
  42. package/src/components/ActionCard.tsx +176 -0
  43. package/src/components/AnomalyBanner.tsx +113 -0
  44. package/src/components/CaseQueueItem.tsx +145 -0
  45. package/src/components/ConfidenceBadge.tsx +62 -0
  46. package/src/components/ConfidenceIndicator.tsx +96 -0
  47. package/src/components/EntityCard.tsx +216 -0
  48. package/src/components/FunnelChart.tsx +160 -0
  49. package/src/components/MatchIndicator.tsx +73 -0
  50. package/src/components/PersonaDashboard.tsx +105 -0
  51. package/src/components/ProcessHealthBar.tsx +107 -0
  52. package/src/components/ProcessIndicator.tsx +167 -0
  53. package/src/components/ReviewDecisionCard.tsx +186 -0
  54. package/src/components/SLAIndicator.tsx +108 -0
  55. package/src/components/SplitPane.tsx +150 -0
  56. package/src/components/SystemActionEntry.tsx +175 -0
  57. package/src/components/VarianceDisplay.tsx +116 -0
  58. package/src/components/index.ts +48 -0
package/dist/index.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default, { forwardRef, useState, useRef, useEffect, useId, useCallback, useImperativeHandle, useMemo, Children, isValidElement, cloneElement, Component, createContext as createContext$1, useContext, useLayoutEffect, createElement, useReducer } from 'react';
4
- import { Loader2, Check, X, EyeOff, Eye, AlertTriangle, CheckCircle, AlertCircle, ChevronDown, Search, Minus, Star, Calendar as Calendar$1, ChevronLeft, ChevronRight, Clock, ChevronUp, Plus, TrendingUp, TrendingDown, Lightbulb, Sparkles, PartyPopper, Flame, Shield, Pencil, User, Users, Activity, Mail, Send, Info, Trash2, HelpCircle, ChevronsLeft, ChevronsRight, Circle, MoreVertical, GripVertical, Upload, Bold, Italic, Underline, List, ListOrdered, Code, Link, ExternalLink, MoreHorizontal, Home, FileText, Image, File as File$1, Menu as Menu$1, ArrowDown, Settings, LogOut, Moon, Sun, Bell, Edit, Trash, Pin, PinOff, Download, Save, ArrowUpDown, Filter, XCircle, BarChart3, MessageSquare } from 'lucide-react';
4
+ import { Loader2, Check, X, EyeOff, Eye, AlertTriangle, CheckCircle, AlertCircle, ChevronDown, Search, Minus, Star, Calendar as Calendar$1, ChevronLeft, ChevronRight, Clock, ChevronUp, Plus, TrendingUp, TrendingDown, Lightbulb, Sparkles, PartyPopper, Flame, Shield, Pencil, User, Users, Activity, Mail, Send, Info, Trash2, HelpCircle, ChevronsLeft, ChevronsRight, Circle, MoreVertical, GripVertical, Upload, Bold, Italic, Underline, List, ListOrdered, Code, Link, ExternalLink, MoreHorizontal, Home, ArrowUp, ArrowDown, RotateCcw, ArrowRight, FileText, Image, File as File$1, Menu as Menu$1, Settings, LogOut, Moon, Sun, Bell, Edit, Trash, Pin, PinOff, Download, Save, ArrowUpDown, Filter, XCircle, BarChart3, MessageSquare } from 'lucide-react';
5
5
  import { createPortal } from 'react-dom';
6
6
  import { Link as Link$1, useInRouterContext, useNavigate, useLocation } from 'react-router-dom';
7
7
 
@@ -704,7 +704,7 @@ function usePrefersMobile() {
704
704
  }
705
705
 
706
706
  // Size classes for trigger button
707
- const sizeClasses$b = {
707
+ const sizeClasses$d = {
708
708
  sm: 'h-8 text-sm py-1',
709
709
  md: 'h-10 text-base py-2',
710
710
  lg: 'h-12 text-base py-3 min-h-touch', // 44px touch target
@@ -1021,14 +1021,14 @@ const Select = forwardRef((props, ref) => {
1021
1021
  if (useNativeSelect) {
1022
1022
  return (jsxs("div", { className: "w-full", children: [label && (jsxs("label", { id: labelId, className: "label", children: [label, required && jsx("span", { className: "text-error-500 ml-1", children: "*" })] })), jsxs("div", { className: "relative", children: [jsxs("select", { ref: nativeSelectRef, value: value || '', onChange: (e) => onChange?.(e.target.value), disabled: disabled, className: `
1023
1023
  input w-full appearance-none pr-10
1024
- ${sizeClasses$b[effectiveSize]}
1024
+ ${sizeClasses$d[effectiveSize]}
1025
1025
  ${error ? 'border-error-400 focus:border-error-400 focus:ring-error-400' : ''}
1026
1026
  ${disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'}
1027
1027
  `, "aria-labelledby": label ? labelId : undefined, "aria-invalid": error ? 'true' : undefined, "aria-describedby": error ? errorId : (helperText ? helperTextId : undefined), "aria-required": required, children: [jsx("option", { value: "", disabled: true, children: placeholder }), options.map((opt) => (jsx("option", { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value))), groups.map((group) => (jsx("optgroup", { label: group.label, children: group.options.map((opt) => (jsx("option", { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value))) }, group.label)))] }), jsx(ChevronDown, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-5 w-5 text-ink-500 pointer-events-none" })] }), error && (jsx("p", { id: errorId, className: "mt-2 text-xs text-error-600", role: "alert", "aria-live": "assertive", children: error })), helperText && !error && (jsx("p", { id: helperTextId, className: "mt-2 text-xs text-ink-600", children: helperText }))] }));
1028
1028
  }
1029
1029
  return (jsxs("div", { className: "w-full", children: [label && (jsxs("label", { id: labelId, className: "label", children: [label, required && jsx("span", { className: "text-error-500 ml-1", children: "*" })] })), jsx("div", { ref: selectRef, className: "relative", children: jsxs("button", { ref: buttonRef, type: "button", onClick: () => !disabled && setIsOpen(!isOpen), disabled: disabled, className: `
1030
1030
  input w-full flex items-center justify-between px-3
1031
- ${sizeClasses$b[effectiveSize]}
1031
+ ${sizeClasses$d[effectiveSize]}
1032
1032
  ${error ? 'border-error-400 focus:border-error-400 focus:ring-error-400' : ''}
1033
1033
  ${disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'}
1034
1034
  `, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-controls": listboxId, "aria-labelledby": label ? labelId : undefined, "aria-label": !label ? placeholder : undefined, "aria-activedescendant": activeDescendant, "aria-invalid": error ? 'true' : undefined, "aria-describedby": error ? errorId : (helperText ? helperTextId : undefined), "aria-disabled": disabled, "aria-required": required, children: [jsxs("span", { className: `flex items-center gap-2 ${selectedOption ? 'text-ink-800' : 'text-ink-400'}`, children: [loading && jsx(Loader2, { className: "h-4 w-4 animate-spin text-ink-500" }), !loading && selectedOption?.icon && jsx("span", { children: selectedOption.icon }), selectedOption ? selectedOption.label : placeholder] }), jsxs("div", { className: "flex items-center gap-1", children: [clearable && value && (jsx("button", { type: "button", onClick: (e) => {
@@ -1173,7 +1173,7 @@ const Switch = forwardRef(({ checked, onChange, label, description, disabled = f
1173
1173
  Switch.displayName = 'Switch';
1174
1174
 
1175
1175
  // Size classes for textarea
1176
- const sizeClasses$a = {
1176
+ const sizeClasses$c = {
1177
1177
  sm: 'px-3 py-2 text-sm',
1178
1178
  md: 'px-4 py-3 text-sm',
1179
1179
  lg: 'px-4 py-3.5 text-base', // Larger padding and text for mobile
@@ -1261,7 +1261,7 @@ const Textarea = forwardRef(({ label, helperText, validationState, validationMes
1261
1261
  bg-white bg-subtle-grain transition-all duration-200
1262
1262
  focus:outline-none focus:ring-2 ${getResizeClass()}
1263
1263
  disabled:bg-paper-100 disabled:text-ink-400 disabled:cursor-not-allowed disabled:opacity-60
1264
- ${sizeClasses$a[effectiveSize]}
1264
+ ${sizeClasses$c[effectiveSize]}
1265
1265
  ${getValidationClasses()}
1266
1266
  ${loading ? 'pr-10' : ''}
1267
1267
  ${className}
@@ -3810,7 +3810,7 @@ var module$1 = {};
3810
3810
  var confetti = module$1.exports;
3811
3811
  module$1.exports.create;
3812
3812
 
3813
- const defaultColors = ['#22c55e', '#3b82f6', '#a855f7', '#f59e0b', '#ef4444', '#ec4899'];
3813
+ const defaultColors$1 = ['#22c55e', '#3b82f6', '#a855f7', '#f59e0b', '#ef4444', '#ec4899'];
3814
3814
  /**
3815
3815
  * Celebration component for triggering confetti and other celebration animations.
3816
3816
  *
@@ -3826,7 +3826,7 @@ const defaultColors = ['#22c55e', '#3b82f6', '#a855f7', '#f59e0b', '#ef4444', '#
3826
3826
  * // Stars with custom colors
3827
3827
  * <Celebration trigger={true} type="stars" colors={['#ffd700', '#ffed4a']} />
3828
3828
  */
3829
- function Celebration({ trigger = false, type = 'confetti', duration = 2000, particleCount = 100, spread = 70, origin = { x: 0.5, y: 0.6 }, colors = defaultColors, onComplete, enabled = true, }) {
3829
+ function Celebration({ trigger = false, type = 'confetti', duration = 2000, particleCount = 100, spread = 70, origin = { x: 0.5, y: 0.6 }, colors = defaultColors$1, onComplete, enabled = true, }) {
3830
3830
  const animationRef = useRef(null);
3831
3831
  const endTimeRef = useRef(0);
3832
3832
  const fireConfetti = useCallback(() => {
@@ -3929,7 +3929,7 @@ function Celebration({ trigger = false, type = 'confetti', duration = 2000, part
3929
3929
  */
3930
3930
  function useCelebration() {
3931
3931
  const celebrate = useCallback((options) => {
3932
- const { type = 'confetti', particleCount = 100, spread = 70, origin = { x: 0.5, y: 0.6 }, colors = defaultColors, duration = 2000, } = options || {};
3932
+ const { type = 'confetti', particleCount = 100, spread = 70, origin = { x: 0.5, y: 0.6 }, colors = defaultColors$1, duration = 2000, } = options || {};
3933
3933
  switch (type) {
3934
3934
  case 'fireworks': {
3935
3935
  const end = Date.now() + duration;
@@ -4590,7 +4590,7 @@ function BottomSheetActions({ children, className = '' }) {
4590
4590
 
4591
4591
  // Selector for all focusable elements
4592
4592
  const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
4593
- const sizeClasses$9 = {
4593
+ const sizeClasses$b = {
4594
4594
  sm: 'max-w-md',
4595
4595
  md: 'max-w-lg',
4596
4596
  lg: 'max-w-2xl',
@@ -4779,7 +4779,7 @@ function Modal({ isOpen, onClose, title, children, size = 'md', showCloseButton
4779
4779
  return createPortal(jsx(BottomSheet, { isOpen: isOpen, onClose: onClose, title: title, height: mobileHeight, showHandle: mobileShowHandle, showCloseButton: showCloseButton, children: children }), document.body);
4780
4780
  }
4781
4781
  // Render as standard modal on desktop
4782
- const modalContent = (jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-ink-900 bg-opacity-50 backdrop-blur-sm animate-fade-in", onMouseDown: handleBackdropMouseDown, onClick: handleBackdropClick, children: jsxs("div", { ref: modalRef, className: `${sizeClasses$9[size]} w-full bg-white bg-subtle-grain rounded-xl shadow-2xl border border-paper-200 ${getAnimationClass()}`, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, children: [jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-paper-200", children: [jsx("h3", { id: titleId, className: "text-lg font-medium text-ink-900", children: title }), showCloseButton && (jsx("button", { onClick: onClose, className: "text-ink-400 hover:text-ink-600 transition-colors", "aria-label": "Close modal", children: jsx(X, { className: "h-5 w-5" }) }))] }), jsx("div", { className: `px-6 py-4 ${scrollable || maxHeight ? 'overflow-y-auto' : ''}`, style: {
4782
+ const modalContent = (jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-ink-900 bg-opacity-50 backdrop-blur-sm animate-fade-in", onMouseDown: handleBackdropMouseDown, onClick: handleBackdropClick, children: jsxs("div", { ref: modalRef, className: `${sizeClasses$b[size]} w-full bg-white bg-subtle-grain rounded-xl shadow-2xl border border-paper-200 ${getAnimationClass()}`, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, children: [jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-paper-200", children: [jsx("h3", { id: titleId, className: "text-lg font-medium text-ink-900", children: title }), showCloseButton && (jsx("button", { onClick: onClose, className: "text-ink-400 hover:text-ink-600 transition-colors", "aria-label": "Close modal", children: jsx(X, { className: "h-5 w-5" }) }))] }), jsx("div", { className: `px-6 py-4 ${scrollable || maxHeight ? 'overflow-y-auto' : ''}`, style: {
4783
4783
  maxHeight: maxHeight || (scrollable ? 'calc(100vh - 200px)' : undefined),
4784
4784
  }, children: children })] }) }));
4785
4785
  return createPortal(modalContent, document.body);
@@ -5161,7 +5161,7 @@ function getAvatarColor(name) {
5161
5161
  return colors[Math.abs(hash) % colors.length];
5162
5162
  }
5163
5163
  // Get initials from name
5164
- function getInitials(name) {
5164
+ function getInitials$1(name) {
5165
5165
  const parts = name.trim().split(/\s+/);
5166
5166
  if (parts.length >= 2) {
5167
5167
  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
@@ -5202,7 +5202,7 @@ const CollaboratorAvatars = forwardRef(function CollaboratorAvatars({ collaborat
5202
5202
  ${collaborator.avatar ? '' : getAvatarColor(collaborator.name)}
5203
5203
  text-white font-medium
5204
5204
  shrink-0
5205
- `, style: { zIndex: visible.length - index }, children: collaborator.avatar ? (jsx("img", { src: collaborator.avatar, alt: collaborator.name, className: "w-full h-full object-cover" })) : (jsx("span", { children: getInitials(collaborator.name) })) }, `${collaborator.name}-${index}`))), hasOverflow && (jsxs("div", { className: `
5205
+ `, style: { zIndex: visible.length - index }, children: collaborator.avatar ? (jsx("img", { src: collaborator.avatar, alt: collaborator.name, className: "w-full h-full object-cover" })) : (jsx("span", { children: getInitials$1(collaborator.name) })) }, `${collaborator.name}-${index}`))), hasOverflow && (jsxs("div", { className: `
5206
5206
  ${styles.container}
5207
5207
  ${styles.overlap}
5208
5208
  ${styles.border}
@@ -5850,7 +5850,7 @@ function Alert({ variant = 'info', title, children, onClose, className = '', act
5850
5850
  return (jsx("div", { className: `rounded-lg border p-4 ${styles.container} ${className}`, role: "alert", children: jsxs("div", { className: "flex items-start gap-3", children: [jsx("div", { className: "flex-shrink-0 mt-0.5", children: styles.icon }), jsxs("div", { className: "flex-1 min-w-0", children: [title && jsx("h4", { className: "text-sm font-medium mb-1", children: title }), jsx("div", { className: "text-sm", children: children }), actions.length > 0 && (jsx("div", { className: "flex gap-2 mt-3", children: actions.map((action, index) => (jsx("button", { onClick: action.onClick, className: getButtonStyles(action.variant), children: action.label }, index))) }))] }), onClose && (jsx("button", { onClick: onClose, className: "flex-shrink-0 text-current opacity-70 hover:opacity-100 transition-opacity", "aria-label": "Close alert", children: jsx(X, { className: "h-4 w-4" }) }))] }) }));
5851
5851
  }
5852
5852
 
5853
- const sizeClasses$8 = {
5853
+ const sizeClasses$a = {
5854
5854
  left: {
5855
5855
  sm: 'w-64',
5856
5856
  md: 'w-96',
@@ -5929,7 +5929,7 @@ function Drawer({ isOpen, onClose, title, children, placement = 'right', size =
5929
5929
  const isHorizontal = placement === 'left' || placement === 'right';
5930
5930
  return (jsxs("div", { className: "fixed inset-0 z-50 flex", children: [showOverlay && (jsx("div", { className: "fixed inset-0 bg-ink-900 bg-opacity-50 backdrop-blur-sm animate-fade-in", onClick: handleOverlayClick, "aria-hidden": "true" })), jsxs("div", { className: `
5931
5931
  fixed ${placementClasses[placement]}
5932
- ${sizeClasses$8[placement][size]}
5932
+ ${sizeClasses$a[placement][size]}
5933
5933
  bg-white border-paper-200 shadow-2xl
5934
5934
  ${isHorizontal ? 'border-r' : 'border-b'}
5935
5935
  ${animationClasses[placement].enter}
@@ -6071,14 +6071,14 @@ function useConfirmDialog() {
6071
6071
  };
6072
6072
  }
6073
6073
 
6074
- const sizeClasses$7 = {
6074
+ const sizeClasses$9 = {
6075
6075
  sm: 'h-3.5 w-3.5',
6076
6076
  md: 'h-4 w-4',
6077
6077
  lg: 'h-5 w-5',
6078
6078
  };
6079
6079
  function HelpTooltip({ content, icon = 'help', size = 'md', position = 'top', className = '', }) {
6080
6080
  const IconComponent = icon === 'info' ? Info : HelpCircle;
6081
- return (jsx(Tooltip, { content: content, position: position, children: jsx("span", { className: `inline-flex items-center justify-center text-ink-400 hover:text-ink-600 cursor-help transition-colors ${className}`, role: "button", "aria-label": "Help", tabIndex: 0, children: jsx(IconComponent, { className: sizeClasses$7[size] }) }) }));
6081
+ return (jsx(Tooltip, { content: content, position: position, children: jsx("span", { className: `inline-flex items-center justify-center text-ink-400 hover:text-ink-600 cursor-help transition-colors ${className}`, role: "button", "aria-label": "Help", tabIndex: 0, children: jsx(IconComponent, { className: sizeClasses$9[size] }) }) }));
6082
6082
  }
6083
6083
 
6084
6084
  /**
@@ -8494,7 +8494,7 @@ const variantClasses$4 = {
8494
8494
  selected: 'bg-accent-200 border-accent-400 ring-2 ring-accent-300',
8495
8495
  },
8496
8496
  };
8497
- const sizeClasses$6 = {
8497
+ const sizeClasses$8 = {
8498
8498
  sm: {
8499
8499
  container: 'h-6 px-2 text-xs gap-1',
8500
8500
  icon: 'h-3 w-3',
@@ -8545,7 +8545,7 @@ const gapClasses = {
8545
8545
  */
8546
8546
  function Chip({ children, variant = 'secondary', size = 'md', onClose, icon, disabled = false, className = '', onClick, selected = false, maxWidth, chipKey, }) {
8547
8547
  const variantStyle = variantClasses$4[variant];
8548
- const sizeStyle = sizeClasses$6[size];
8548
+ const sizeStyle = sizeClasses$8[size];
8549
8549
  const isClickable = !disabled && (onClick || onClose);
8550
8550
  return (jsxs("div", { className: `
8551
8551
  inline-flex items-center rounded-full border font-medium
@@ -8660,7 +8660,7 @@ function ChipGroup({ children, direction = 'horizontal', wrap = false, gap = 'sm
8660
8660
  `, role: selectionMode !== 'none' ? 'group' : undefined, "aria-label": selectionMode !== 'none' ? 'Chip selection group' : undefined, children: enhancedChildren }));
8661
8661
  }
8662
8662
 
8663
- const sizeClasses$5 = {
8663
+ const sizeClasses$7 = {
8664
8664
  sm: {
8665
8665
  item: 'py-1.5 px-2',
8666
8666
  text: 'text-sm',
@@ -8793,7 +8793,7 @@ function CheckboxList({ items, selectedKeys, onSelectionChange, groupLabels = {}
8793
8793
  onSelectionChange(Array.from(newKeys));
8794
8794
  }
8795
8795
  };
8796
- const sizeStyle = sizeClasses$5[size];
8796
+ const sizeStyle = sizeClasses$7[size];
8797
8797
  const enabledItems = filteredItems.filter(item => !item.disabled);
8798
8798
  const allSelected = enabledItems.length > 0 && enabledItems.every(item => selectedKeys.includes(item.key));
8799
8799
  const someSelected = enabledItems.some(item => selectedKeys.includes(item.key)) && !allSelected;
@@ -8832,7 +8832,7 @@ function CheckboxListItemRow({ item, selected, onToggle, size, sizeStyle, indent
8832
8832
  `, children: jsxs("div", { className: "flex items-start gap-3", children: [jsx(Checkbox, { checked: selected, onChange: onToggle, disabled: item.disabled, size: size }), jsxs("div", { className: "flex flex-col flex-1 min-w-0", children: [jsx("span", { className: sizeStyle.text, children: item.label }), item.description && (jsx("span", { className: `${sizeStyle.description} text-ink-500`, children: item.description }))] })] }) }));
8833
8833
  }
8834
8834
 
8835
- const sizeClasses$4 = {
8835
+ const sizeClasses$6 = {
8836
8836
  sm: {
8837
8837
  container: 'text-sm',
8838
8838
  item: 'py-1.5 px-2',
@@ -8955,7 +8955,7 @@ function SearchableList({ items, searchPlaceholder = 'Search...', searchValue: c
8955
8955
  }
8956
8956
  }
8957
8957
  }, [highlightedIndex]);
8958
- const sizeStyle = sizeClasses$4[size];
8958
+ const sizeStyle = sizeClasses$6[size];
8959
8959
  const resultCountText = formatResultCount
8960
8960
  ? formatResultCount(filteredItems.length, items.length)
8961
8961
  : `${filteredItems.length} of ${items.length}`;
@@ -8980,7 +8980,7 @@ function SearchableList({ items, searchPlaceholder = 'Search...', searchValue: c
8980
8980
  })] })] }));
8981
8981
  }
8982
8982
 
8983
- const sizeClasses$3 = {
8983
+ const sizeClasses$5 = {
8984
8984
  sm: {
8985
8985
  input: 'h-8 px-2 text-sm',
8986
8986
  button: 'h-8 w-8',
@@ -9004,7 +9004,7 @@ const NumberInput = forwardRef((props, ref) => {
9004
9004
  const { value = 0, onChange, min, max, step = 1, disabled = false, readOnly = false, label, helperText, error, required = false, size = 'md', className = '', placeholder, id, name, precision, formatValue, } = props;
9005
9005
  const [internalValue, setInternalValue] = useState(String(value));
9006
9006
  const [isFocused, setIsFocused] = useState(false);
9007
- const sizeStyle = sizeClasses$3[size];
9007
+ const sizeStyle = sizeClasses$5[size];
9008
9008
  // Generate unique IDs for ARIA
9009
9009
  const uniqueId = useId();
9010
9010
  const inputId = id || uniqueId;
@@ -9849,7 +9849,7 @@ function PriorityAlertBanner({ alerts, onDismiss, sticky = false, className = ''
9849
9849
  `, role: "alert", "aria-live": "polite", children: alerts.map(renderAlert) }));
9850
9850
  }
9851
9851
 
9852
- const sizeClasses$2 = {
9852
+ const sizeClasses$4 = {
9853
9853
  sm: {
9854
9854
  header: 'h-10 px-3',
9855
9855
  text: 'text-sm',
@@ -9957,7 +9957,7 @@ function ExpandablePanel({ collapsedContent, children, position = 'bottom', mode
9957
9957
  document.addEventListener('keydown', handleEscape);
9958
9958
  return () => document.removeEventListener('keydown', handleEscape);
9959
9959
  }, [closeOnEscape, expanded]);
9960
- const sizeStyle = sizeClasses$2[size];
9960
+ const sizeStyle = sizeClasses$4[size];
9961
9961
  const variantStyle = variantClasses$1[variant];
9962
9962
  const heightValue = typeof expandedHeight === 'number' ? `${expandedHeight}px` : expandedHeight;
9963
9963
  const maxWidthValue = maxWidth
@@ -11850,6 +11850,639 @@ function StepIndicator({ steps, currentStep, variant = 'horizontal', onStepClick
11850
11850
  }) }) }));
11851
11851
  }
11852
11852
 
11853
+ // =============================================================================
11854
+ // Color Mappings
11855
+ // =============================================================================
11856
+ const stageColors = {
11857
+ slate: { bg: 'bg-slate-50', text: 'text-slate-700', border: 'border-slate-200', activeBg: 'bg-slate-100' },
11858
+ blue: { bg: 'bg-blue-50', text: 'text-blue-700', border: 'border-blue-200', activeBg: 'bg-blue-100' },
11859
+ indigo: { bg: 'bg-indigo-50', text: 'text-indigo-700', border: 'border-indigo-200', activeBg: 'bg-indigo-100' },
11860
+ purple: { bg: 'bg-purple-50', text: 'text-purple-700', border: 'border-purple-200', activeBg: 'bg-purple-100' },
11861
+ green: { bg: 'bg-green-50', text: 'text-green-700', border: 'border-green-200', activeBg: 'bg-green-100' },
11862
+ red: { bg: 'bg-red-50', text: 'text-red-700', border: 'border-red-200', activeBg: 'bg-red-100' },
11863
+ yellow: { bg: 'bg-yellow-50', text: 'text-yellow-700', border: 'border-yellow-200', activeBg: 'bg-yellow-100' },
11864
+ orange: { bg: 'bg-orange-50', text: 'text-orange-700', border: 'border-orange-200', activeBg: 'bg-orange-100' },
11865
+ teal: { bg: 'bg-teal-50', text: 'text-teal-700', border: 'border-teal-200', activeBg: 'bg-teal-100' },
11866
+ primary: { bg: 'bg-primary-50', text: 'text-primary-700', border: 'border-primary-200', activeBg: 'bg-primary-100' },
11867
+ };
11868
+ const healthIndicator = {
11869
+ good: 'bg-success-500',
11870
+ warning: 'bg-warning-500',
11871
+ critical: 'bg-error-500',
11872
+ };
11873
+ const sizeClasses$3 = {
11874
+ sm: { wrapper: 'py-2 px-3', count: 'text-lg', label: 'text-xs', chevron: 'h-3 w-3' },
11875
+ md: { wrapper: 'py-3 px-4', count: 'text-2xl', label: 'text-sm', chevron: 'h-4 w-4' },
11876
+ lg: { wrapper: 'py-4 px-5', count: 'text-3xl', label: 'text-base', chevron: 'h-5 w-5' },
11877
+ };
11878
+ // =============================================================================
11879
+ // Component
11880
+ // =============================================================================
11881
+ /**
11882
+ * ProcessIndicator — Horizontal process flow visualization
11883
+ *
11884
+ * Shows stages as connected blocks with names, item counts, and health coloring.
11885
+ * Stages are clickable for filtering. Used at the top of process views
11886
+ * (Sales Pipeline, Support Center, Commission Lifecycle).
11887
+ */
11888
+ function ProcessIndicator({ stages, activeStageId, onStageClick, showConversion = false, size = 'md', className = '', }) {
11889
+ const sizes = sizeClasses$3[size];
11890
+ const totalCount = stages.reduce((sum, s) => sum + s.count, 0);
11891
+ return (jsxs("div", { className: `flex items-stretch overflow-x-auto ${className}`, role: "navigation", "aria-label": "Process stages", children: [stages.map((stage, index) => {
11892
+ const colors = stageColors[stage.color || 'slate'];
11893
+ const isActive = stage.id === activeStageId;
11894
+ const isClickable = !!onStageClick;
11895
+ const conversionRate = showConversion && index > 0 && stages[index - 1].count > 0
11896
+ ? Math.round((stage.count / stages[index - 1].count) * 100)
11897
+ : null;
11898
+ return (jsxs(React__default.Fragment, { children: [index > 0 && (jsxs("div", { className: "flex flex-col items-center justify-center px-1 flex-shrink-0", children: [jsx(ChevronRight, { className: `${sizes.chevron} text-ink-300` }), conversionRate !== null && (jsxs("span", { className: "text-[10px] text-ink-400 mt-0.5", children: [conversionRate, "%"] }))] })), jsxs("button", { type: "button", onClick: () => onStageClick?.(stage.id), disabled: !isClickable, className: `
11899
+ flex flex-col items-center justify-center ${sizes.wrapper}
11900
+ rounded-lg border transition-all min-w-0 flex-1
11901
+ ${isActive ? `${colors.activeBg} ${colors.border} border-2 shadow-sm` : `${colors.bg} ${colors.border}`}
11902
+ ${isClickable ? 'cursor-pointer hover:shadow-sm hover:border-2' : 'cursor-default'}
11903
+ `, "aria-current": isActive ? 'step' : undefined, "aria-label": `${stage.name}: ${stage.count} items`, children: [stage.health && (jsx("div", { className: `w-2 h-2 rounded-full ${healthIndicator[stage.health]} mb-1` })), stage.icon && (jsx("div", { className: `${colors.text} mb-1 opacity-60`, children: stage.icon })), jsx("span", { className: `${sizes.count} font-bold ${colors.text} leading-none`, children: stage.count.toLocaleString() }), jsx("span", { className: `${sizes.label} ${colors.text} opacity-80 mt-1 whitespace-nowrap`, children: stage.name })] })] }, stage.id));
11904
+ }), stages.length > 0 && (jsxs(Fragment, { children: [jsx("div", { className: "flex items-center justify-center px-2 flex-shrink-0", children: jsx("div", { className: "w-px h-8 bg-ink-200" }) }), jsxs("div", { className: `flex flex-col items-center justify-center ${sizes.wrapper} min-w-0`, children: [jsx("span", { className: `${sizes.count} font-bold text-ink-900 leading-none`, children: totalCount.toLocaleString() }), jsx("span", { className: `${sizes.label} text-ink-500 mt-1`, children: "Total" })] })] }))] }));
11905
+ }
11906
+
11907
+ // =============================================================================
11908
+ // Helpers
11909
+ // =============================================================================
11910
+ const statusColors$1 = {
11911
+ slate: { bg: 'bg-slate-100', text: 'text-slate-700' },
11912
+ blue: { bg: 'bg-blue-100', text: 'text-blue-700' },
11913
+ indigo: { bg: 'bg-indigo-100', text: 'text-indigo-700' },
11914
+ purple: { bg: 'bg-purple-100', text: 'text-purple-700' },
11915
+ green: { bg: 'bg-green-100', text: 'text-green-700' },
11916
+ red: { bg: 'bg-red-100', text: 'text-red-700' },
11917
+ yellow: { bg: 'bg-yellow-100', text: 'text-yellow-700' },
11918
+ orange: { bg: 'bg-orange-100', text: 'text-orange-700' },
11919
+ teal: { bg: 'bg-teal-100', text: 'text-teal-700' },
11920
+ };
11921
+ function getInitials(name) {
11922
+ const parts = name.trim().split(/\s+/);
11923
+ if (parts.length >= 2)
11924
+ return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
11925
+ return name.slice(0, 2).toUpperCase();
11926
+ }
11927
+ // =============================================================================
11928
+ // Component
11929
+ // =============================================================================
11930
+ /**
11931
+ * EntityCard — Standardized card for pipeline/board views
11932
+ *
11933
+ * Renders a compact card with title, value, status, assignee, and metadata.
11934
+ * Designed for use in KanbanBoard columns and process view lists.
11935
+ */
11936
+ function EntityCard({ title, subtitle, value, status, statusColor = 'slate', assignee, progress, metadata, icon, onClick, onContextMenu, selected = false, draggable = false, size = 'md', className = '', confidence, }) {
11937
+ const isCompact = size === 'sm';
11938
+ const colors = statusColors$1[statusColor];
11939
+ return (jsxs("div", { onClick: onClick, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, onKeyDown: onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ')
11940
+ onClick(); } : undefined, className: `
11941
+ group relative rounded-lg border bg-white dark:bg-ink-900
11942
+ ${selected ? 'border-primary-400 ring-2 ring-primary-100' : 'border-paper-200 dark:border-ink-700'}
11943
+ ${onClick ? 'cursor-pointer hover:shadow-md hover:border-primary-300 transition-all' : ''}
11944
+ ${draggable ? 'cursor-grab active:cursor-grabbing' : ''}
11945
+ ${isCompact ? 'p-3' : 'p-4'}
11946
+ ${className}
11947
+ `, children: [draggable && (jsx("div", { className: "absolute left-1 top-1/2 -translate-y-1/2 w-1 h-6 rounded-full bg-ink-200 opacity-0 group-hover:opacity-100 transition-opacity" })), jsxs("div", { className: "flex items-start gap-2", children: [icon && (jsx("div", { className: "flex-shrink-0 text-ink-400 mt-0.5", children: icon })), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("h4", { className: `font-medium text-ink-900 dark:text-ink-100 truncate ${isCompact ? 'text-sm' : 'text-base'}`, children: title }), subtitle && (jsx("p", { className: `text-ink-500 dark:text-ink-400 truncate ${isCompact ? 'text-xs' : 'text-sm'}`, children: subtitle }))] }), onContextMenu && (jsx("button", { type: "button", onClick: (e) => { e.stopPropagation(); onContextMenu(); }, className: "flex-shrink-0 opacity-0 group-hover:opacity-100 p-1 rounded hover:bg-paper-100 transition-opacity", "aria-label": "More options", children: jsx(MoreHorizontal, { className: "h-4 w-4 text-ink-400" }) }))] }), (value || status) && (jsxs("div", { className: `flex items-center justify-between gap-2 ${isCompact ? 'mt-2' : 'mt-3'}`, children: [value && (jsx("span", { className: `font-semibold text-ink-900 dark:text-ink-100 ${isCompact ? 'text-sm' : 'text-lg'}`, children: value })), status && colors && (jsx("span", { className: `inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${colors.bg} ${colors.text}`, children: status }))] })), metadata && metadata.length > 0 && (jsx("div", { className: `grid grid-cols-2 gap-x-3 gap-y-1 ${isCompact ? 'mt-2' : 'mt-3'}`, children: metadata.map((item, idx) => (jsxs("div", { className: "min-w-0", children: [jsx("span", { className: "text-xs text-ink-400", children: item.label }), jsx("div", { className: "text-xs text-ink-600 dark:text-ink-300 truncate", children: item.value })] }, idx))) })), (progress !== undefined || assignee || confidence !== undefined) && (jsxs("div", { className: `flex items-center justify-between gap-2 ${isCompact ? 'mt-2' : 'mt-3'}`, children: [progress !== undefined && (jsx("div", { className: "flex-1 min-w-0", children: jsx("div", { className: "h-1.5 bg-paper-200 rounded-full overflow-hidden", children: jsx("div", { className: "h-full bg-primary-500 rounded-full transition-all", style: { width: `${Math.min(100, Math.max(0, progress))}%` } }) }) })), jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [confidence !== undefined && (jsxs("span", { className: `text-xs px-1.5 py-0.5 rounded ${confidence >= 80 ? 'bg-success-50 text-success-700' :
11948
+ confidence >= 50 ? 'bg-warning-50 text-warning-700' :
11949
+ 'bg-error-50 text-error-700'}`, children: [confidence, "%"] })), assignee && (jsx("div", { className: "w-6 h-6 rounded-full bg-primary-100 flex items-center justify-center flex-shrink-0", title: assignee, children: jsx("span", { className: "text-xs font-medium text-primary-700", children: getInitials(assignee) }) }))] })] }))] }));
11950
+ }
11951
+
11952
+ // =============================================================================
11953
+ // Component
11954
+ // =============================================================================
11955
+ /**
11956
+ * SplitPane — Resizable two-panel layout
11957
+ *
11958
+ * Renders a left/primary panel and right/secondary panel with a draggable divider.
11959
+ * Used for list+detail patterns (case queue + case detail, statements + line items).
11960
+ *
11961
+ * The right panel can be toggled on/off via `showRight` prop.
11962
+ */
11963
+ function SplitPane({ left, right, defaultSplit = 0.4, minLeftWidth = 200, minRightWidth = 300, resizable = true, showRight = true, orientation = 'horizontal', onSplitChange, className = '', }) {
11964
+ const containerRef = useRef(null);
11965
+ const [splitRatio, setSplitRatio] = useState(defaultSplit);
11966
+ const [isDragging, setIsDragging] = useState(false);
11967
+ const handleMouseDown = useCallback((e) => {
11968
+ if (!resizable)
11969
+ return;
11970
+ e.preventDefault();
11971
+ setIsDragging(true);
11972
+ }, [resizable]);
11973
+ useEffect(() => {
11974
+ if (!isDragging)
11975
+ return;
11976
+ const handleMouseMove = (e) => {
11977
+ if (!containerRef.current)
11978
+ return;
11979
+ const rect = containerRef.current.getBoundingClientRect();
11980
+ const isHorizontal = orientation === 'horizontal';
11981
+ const containerSize = isHorizontal ? rect.width : rect.height;
11982
+ const position = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;
11983
+ // Enforce min widths
11984
+ const minLeft = minLeftWidth / containerSize;
11985
+ const maxLeft = 1 - (minRightWidth / containerSize);
11986
+ const newRatio = Math.min(maxLeft, Math.max(minLeft, position / containerSize));
11987
+ setSplitRatio(newRatio);
11988
+ onSplitChange?.(newRatio);
11989
+ };
11990
+ const handleMouseUp = () => {
11991
+ setIsDragging(false);
11992
+ };
11993
+ document.addEventListener('mousemove', handleMouseMove);
11994
+ document.addEventListener('mouseup', handleMouseUp);
11995
+ return () => {
11996
+ document.removeEventListener('mousemove', handleMouseMove);
11997
+ document.removeEventListener('mouseup', handleMouseUp);
11998
+ };
11999
+ }, [isDragging, orientation, minLeftWidth, minRightWidth, onSplitChange]);
12000
+ const isHorizontal = orientation === 'horizontal';
12001
+ if (!showRight) {
12002
+ return (jsx("div", { className: `h-full ${className}`, children: left }));
12003
+ }
12004
+ const leftSize = `${(splitRatio * 100).toFixed(1)}%`;
12005
+ const rightSize = `${((1 - splitRatio) * 100).toFixed(1)}%`;
12006
+ return (jsxs("div", { ref: containerRef, className: `
12007
+ flex h-full overflow-hidden
12008
+ ${isHorizontal ? 'flex-row' : 'flex-col'}
12009
+ ${isDragging ? 'select-none' : ''}
12010
+ ${className}
12011
+ `, children: [jsx("div", { className: "overflow-auto", style: isHorizontal ? { width: leftSize } : { height: leftSize }, children: left }), jsx("div", { onMouseDown: handleMouseDown, className: `
12012
+ flex-shrink-0 bg-paper-200 dark:bg-ink-700
12013
+ ${isHorizontal ? 'w-px hover:w-1' : 'h-px hover:h-1'}
12014
+ ${resizable ? 'cursor-col-resize hover:bg-primary-300 transition-all' : ''}
12015
+ ${isDragging ? 'bg-primary-400 w-1' : ''}
12016
+ `, role: "separator", "aria-orientation": isHorizontal ? 'vertical' : 'horizontal' }), jsx("div", { className: "overflow-auto", style: isHorizontal ? { width: rightSize } : { height: rightSize }, children: right })] }));
12017
+ }
12018
+
12019
+ // =============================================================================
12020
+ // Helpers
12021
+ // =============================================================================
12022
+ const priorityConfig = {
12023
+ critical: { bg: 'bg-red-50', text: 'text-red-700', label: 'Critical', dot: 'bg-red-500' },
12024
+ high: { bg: 'bg-orange-50', text: 'text-orange-700', label: 'High', dot: 'bg-orange-500' },
12025
+ medium: { bg: 'bg-yellow-50', text: 'text-yellow-700', label: 'Medium', dot: 'bg-yellow-500' },
12026
+ low: { bg: 'bg-blue-50', text: 'text-blue-700', label: 'Low', dot: 'bg-blue-500' },
12027
+ };
12028
+ const statusColors = {
12029
+ slate: { bg: 'bg-slate-100', text: 'text-slate-700' },
12030
+ blue: { bg: 'bg-blue-100', text: 'text-blue-700' },
12031
+ indigo: { bg: 'bg-indigo-100', text: 'text-indigo-700' },
12032
+ purple: { bg: 'bg-purple-100', text: 'text-purple-700' },
12033
+ green: { bg: 'bg-green-100', text: 'text-green-700' },
12034
+ red: { bg: 'bg-red-100', text: 'text-red-700' },
12035
+ yellow: { bg: 'bg-yellow-100', text: 'text-yellow-700' },
12036
+ orange: { bg: 'bg-orange-100', text: 'text-orange-700' },
12037
+ teal: { bg: 'bg-teal-100', text: 'text-teal-700' },
12038
+ };
12039
+ // =============================================================================
12040
+ // Component
12041
+ // =============================================================================
12042
+ /**
12043
+ * CaseQueueItem — Priority-sorted case card for support queue views
12044
+ *
12045
+ * Shows case subject, priority indicator, status, assignee, and SLA countdown.
12046
+ * Designed for use in the Support Center's case queue list.
12047
+ */
12048
+ function CaseQueueItem({ caseNumber, subject, priority, status, statusColor = 'slate', assignee, account, slaBreach = false, slaTimeRemaining, onClick, selected = false, className = '', }) {
12049
+ const prio = priorityConfig[priority] || priorityConfig.medium;
12050
+ const stColor = statusColors[statusColor];
12051
+ return (jsxs("div", { onClick: onClick, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, onKeyDown: onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ')
12052
+ onClick(); } : undefined, className: `
12053
+ group relative rounded-lg border bg-white dark:bg-ink-900 p-4
12054
+ ${selected ? 'border-primary-400 ring-2 ring-primary-100' : 'border-paper-200 dark:border-ink-700'}
12055
+ ${onClick ? 'cursor-pointer hover:shadow-md hover:border-primary-300 transition-all' : ''}
12056
+ ${slaBreach ? 'border-l-4 border-l-red-500' : ''}
12057
+ ${className}
12058
+ `, "aria-label": `Case ${caseNumber}: ${subject}`, children: [jsxs("div", { className: "flex items-center justify-between gap-2 mb-2", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-xs font-mono text-ink-400", children: caseNumber }), jsxs("span", { className: `inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium ${prio.bg} ${prio.text}`, children: [jsx("span", { className: `w-1.5 h-1.5 rounded-full ${prio.dot}` }), prio.label] })] }), (slaTimeRemaining || slaBreach) && (jsxs("div", { className: `flex items-center gap-1 text-xs ${slaBreach ? 'text-red-600 font-medium' : 'text-ink-500'}`, children: [slaBreach ? jsx(AlertTriangle, { className: "h-3 w-3" }) : jsx(Clock, { className: "h-3 w-3" }), jsx("span", { children: slaBreach ? 'SLA Breached' : slaTimeRemaining })] }))] }), jsx("h4", { className: "text-sm font-medium text-ink-900 dark:text-ink-100 mb-1 line-clamp-2", children: subject }), account && (jsx("p", { className: "text-xs text-ink-500 mb-2", children: account })), jsxs("div", { className: "flex items-center justify-between gap-2", children: [stColor && (jsx("span", { className: `inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${stColor.bg} ${stColor.text}`, children: status })), assignee && (jsxs("div", { className: "flex items-center gap-1 text-xs text-ink-500", children: [jsx(User, { className: "h-3 w-3" }), jsx("span", { children: assignee })] }))] })] }));
12059
+ }
12060
+
12061
+ // =============================================================================
12062
+ // Helpers
12063
+ // =============================================================================
12064
+ const statusConfig$1 = {
12065
+ 'on-track': { icon: jsx(Clock, { className: "h-4 w-4" }), color: 'text-success-600', bg: 'bg-success-50', text: 'text-success-700', label: 'On Track' },
12066
+ 'at-risk': { icon: jsx(Clock, { className: "h-4 w-4" }), color: 'text-warning-600', bg: 'bg-warning-50', text: 'text-warning-700', label: 'At Risk' },
12067
+ 'breached': { icon: jsx(AlertTriangle, { className: "h-4 w-4" }), color: 'text-error-600', bg: 'bg-error-50', text: 'text-error-700', label: 'Breached' },
12068
+ 'met': { icon: jsx(CheckCircle, { className: "h-4 w-4" }), color: 'text-success-600', bg: 'bg-success-50', text: 'text-success-700', label: 'Met' },
12069
+ };
12070
+ const progressColors = {
12071
+ 'on-track': 'bg-success-500',
12072
+ 'at-risk': 'bg-warning-500',
12073
+ 'breached': 'bg-error-500',
12074
+ 'met': 'bg-success-500',
12075
+ };
12076
+ // =============================================================================
12077
+ // Component
12078
+ // =============================================================================
12079
+ /**
12080
+ * SLAIndicator — Visual SLA countdown with urgency coloring
12081
+ *
12082
+ * Shows time remaining, progress bar, and status icon.
12083
+ * Used in Support Center case queue items and case detail views.
12084
+ */
12085
+ function SLAIndicator({ timeRemaining, totalMinutes, elapsedMinutes, status, size = 'md', compact = false, className = '', }) {
12086
+ const config = statusConfig$1[status] || statusConfig$1['on-track'];
12087
+ const progressPercent = totalMinutes && elapsedMinutes
12088
+ ? Math.min(100, (elapsedMinutes / totalMinutes) * 100)
12089
+ : undefined;
12090
+ if (compact) {
12091
+ return (jsxs("span", { className: `inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium ${config.bg} ${config.text} ${className}`, children: [config.icon, jsx("span", { children: timeRemaining || config.label })] }));
12092
+ }
12093
+ const sizeClasses = {
12094
+ sm: { text: 'text-sm', icon: 'h-4 w-4', bar: 'h-1' },
12095
+ md: { text: 'text-base', icon: 'h-5 w-5', bar: 'h-1.5' },
12096
+ lg: { text: 'text-lg', icon: 'h-6 w-6', bar: 'h-2' },
12097
+ };
12098
+ const sizes = sizeClasses[size];
12099
+ return (jsxs("div", { className: `${className}`, children: [jsxs("div", { className: "flex items-center justify-between gap-2 mb-1", children: [jsxs("div", { className: `flex items-center gap-1.5 ${config.color}`, children: [config.icon, jsx("span", { className: `${sizes.text} font-medium`, children: config.label })] }), timeRemaining && (jsx("span", { className: `${sizes.text} font-mono ${config.color}`, children: timeRemaining }))] }), progressPercent !== undefined && (jsx("div", { className: `${sizes.bar} bg-paper-200 rounded-full overflow-hidden`, children: jsx("div", { className: `h-full ${progressColors[status]} rounded-full transition-all`, style: { width: `${progressPercent}%` } }) }))] }));
12100
+ }
12101
+
12102
+ // =============================================================================
12103
+ // Config
12104
+ // =============================================================================
12105
+ const qualityConfig = {
12106
+ exact: { icon: jsx(Check, { className: "h-3 w-3" }), color: 'text-success-600', dot: 'bg-success-500', label: 'Exact Match' },
12107
+ close: { icon: jsx(Check, { className: "h-3 w-3" }), color: 'text-blue-600', dot: 'bg-blue-500', label: 'Close Match' },
12108
+ possible: { icon: jsx(HelpCircle, { className: "h-3 w-3" }), color: 'text-warning-600', dot: 'bg-warning-500', label: 'Possible Match' },
12109
+ unmatched: { icon: jsx(X, { className: "h-3 w-3" }), color: 'text-error-600', dot: 'bg-error-500', label: 'Unmatched' },
12110
+ };
12111
+ // =============================================================================
12112
+ // Component
12113
+ // =============================================================================
12114
+ /**
12115
+ * MatchIndicator — Match quality visualization for reconciliation
12116
+ *
12117
+ * Shows a color-coded dot/icon indicating match quality between
12118
+ * statement lines and invoices. Used in the Reconciliation Hub.
12119
+ */
12120
+ function MatchIndicator({ quality, confidence, showLabel = false, size = 'md', className = '', }) {
12121
+ const config = qualityConfig[quality] || qualityConfig.unmatched;
12122
+ const sizeClasses = {
12123
+ sm: { dot: 'w-2 h-2', text: 'text-xs', icon: 'h-3 w-3' },
12124
+ md: { dot: 'w-2.5 h-2.5', text: 'text-sm', icon: 'h-4 w-4' },
12125
+ lg: { dot: 'w-3 h-3', text: 'text-base', icon: 'h-5 w-5' },
12126
+ };
12127
+ const sizes = sizeClasses[size];
12128
+ return (jsxs("div", { className: `inline-flex items-center gap-1.5 ${className}`, title: config.label, children: [jsx("span", { className: `${sizes.dot} rounded-full ${config.dot} flex-shrink-0` }), showLabel && (jsx("span", { className: `${sizes.text} ${config.color} font-medium`, children: config.label })), confidence !== undefined && (jsxs("span", { className: `${sizes.text} text-ink-400`, children: [confidence, "%"] }))] }));
12129
+ }
12130
+
12131
+ // =============================================================================
12132
+ // Helpers
12133
+ // =============================================================================
12134
+ function formatValue(value, format, currency) {
12135
+ switch (format) {
12136
+ case 'currency':
12137
+ return new Intl.NumberFormat('en-US', { style: 'currency', currency, minimumFractionDigits: 2 }).format(value);
12138
+ case 'percentage':
12139
+ return `${value.toFixed(1)}%`;
12140
+ default:
12141
+ return value.toLocaleString();
12142
+ }
12143
+ }
12144
+ // =============================================================================
12145
+ // Component
12146
+ // =============================================================================
12147
+ /**
12148
+ * VarianceDisplay — Expected vs actual comparison with tolerance coloring
12149
+ *
12150
+ * Shows the difference between expected and actual values, color-coded
12151
+ * by tolerance thresholds. Used in the Reconciliation Hub for variance analysis.
12152
+ */
12153
+ function VarianceDisplay({ expected, actual, format = 'currency', currency = 'USD', tolerancePercent = 1, showValues = true, size = 'md', className = '', }) {
12154
+ const variance = actual - expected;
12155
+ const variancePercent = expected !== 0 ? (variance / expected) * 100 : 0;
12156
+ const absVariancePercent = Math.abs(variancePercent);
12157
+ const isWithinTolerance = absVariancePercent <= tolerancePercent;
12158
+ const isOver = variance > 0;
12159
+ const isExact = variance === 0;
12160
+ const colorClass = isExact ? 'text-success-600' :
12161
+ isWithinTolerance ? 'text-ink-600' :
12162
+ isOver ? 'text-blue-600' : 'text-error-600';
12163
+ const bgClass = isExact ? 'bg-success-50' :
12164
+ isWithinTolerance ? 'bg-paper-100' :
12165
+ isOver ? 'bg-blue-50' : 'bg-error-50';
12166
+ const sizeClasses = {
12167
+ sm: { text: 'text-xs', value: 'text-sm' },
12168
+ md: { text: 'text-sm', value: 'text-base' },
12169
+ lg: { text: 'text-base', value: 'text-lg' },
12170
+ };
12171
+ const sizes = sizeClasses[size];
12172
+ const VarianceIcon = isExact ? Minus : isOver ? ArrowUp : ArrowDown;
12173
+ return (jsxs("div", { className: `${className}`, children: [showValues && (jsxs("div", { className: `flex items-center justify-between gap-4 mb-1 ${sizes.text}`, children: [jsxs("div", { children: [jsx("span", { className: "text-ink-400", children: "Expected: " }), jsx("span", { className: "text-ink-700 font-medium", children: formatValue(expected, format, currency) })] }), jsxs("div", { children: [jsx("span", { className: "text-ink-400", children: "Actual: " }), jsx("span", { className: "text-ink-700 font-medium", children: formatValue(actual, format, currency) })] })] })), jsxs("div", { className: `inline-flex items-center gap-1 px-2 py-1 rounded ${bgClass} ${colorClass}`, children: [jsx(VarianceIcon, { className: "h-3 w-3" }), jsxs("span", { className: `${sizes.value} font-medium`, children: [variance >= 0 ? '+' : '', formatValue(variance, format, currency)] }), jsxs("span", { className: `${sizes.text} opacity-75`, children: ["(", variancePercent >= 0 ? '+' : '', variancePercent.toFixed(1), "%)"] }), isWithinTolerance && !isExact && (jsx("span", { className: `${sizes.text} text-ink-400 ml-1`, children: "within tolerance" }))] })] }));
12174
+ }
12175
+
12176
+ // =============================================================================
12177
+ // Helpers
12178
+ // =============================================================================
12179
+ const priorityStyles = {
12180
+ high: { border: 'border-l-4 border-l-red-400', dot: 'bg-red-500' },
12181
+ medium: { border: 'border-l-4 border-l-yellow-400', dot: 'bg-yellow-500' },
12182
+ low: { border: 'border-l-4 border-l-blue-400', dot: 'bg-blue-500' },
12183
+ };
12184
+ const buttonVariants$1 = {
12185
+ primary: 'bg-primary-600 text-white hover:bg-primary-700',
12186
+ secondary: 'bg-paper-100 text-ink-700 hover:bg-paper-200 border border-paper-300',
12187
+ danger: 'bg-error-600 text-white hover:bg-error-700',
12188
+ ghost: 'text-ink-600 hover:bg-paper-100',
12189
+ };
12190
+ // =============================================================================
12191
+ // Component
12192
+ // =============================================================================
12193
+ /**
12194
+ * ActionCard — Approval workflow card with action buttons
12195
+ *
12196
+ * Shows what needs action, why it was flagged, and provides quick-action buttons.
12197
+ * Used in the Approvals & Review queue across all process domains.
12198
+ */
12199
+ function ActionCard({ title, description, entityType, entityId, onEntityClick, reasoning, actions, priority, icon, confidence, timestamp, selected = false, className = '', }) {
12200
+ const prioStyle = priority ? priorityStyles[priority] : undefined;
12201
+ return (jsxs("div", { className: `
12202
+ rounded-lg border bg-white dark:bg-ink-900 p-4
12203
+ ${selected ? 'border-primary-400 ring-2 ring-primary-100' : 'border-paper-200 dark:border-ink-700'}
12204
+ ${prioStyle?.border || ''}
12205
+ ${className}
12206
+ `, children: [jsxs("div", { className: "flex items-start gap-3 mb-3", children: [icon && (jsx("div", { className: "flex-shrink-0 text-ink-400 mt-0.5", children: icon })), jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("h4", { className: "text-sm font-medium text-ink-900 dark:text-ink-100", children: title }), priority && prioStyle && (jsx("span", { className: `w-2 h-2 rounded-full ${prioStyle.dot} flex-shrink-0` }))] }), description && (jsx("p", { className: "text-sm text-ink-500 mt-0.5", children: description }))] }), confidence !== undefined && (jsxs("span", { className: `text-xs px-2 py-0.5 rounded flex-shrink-0 ${confidence >= 80 ? 'bg-success-50 text-success-700' :
12207
+ confidence >= 50 ? 'bg-warning-50 text-warning-700' :
12208
+ 'bg-error-50 text-error-700'}`, children: [confidence, "% confidence"] }))] }), entityType && entityId && (jsx("div", { className: "mb-2", children: jsxs("button", { type: "button", onClick: onEntityClick, className: "text-xs text-primary-600 hover:text-primary-700 hover:underline", children: [entityType, " #", entityId] }) })), reasoning && (jsx("div", { className: "mb-3 px-3 py-2 bg-paper-50 dark:bg-ink-800 rounded text-xs text-ink-600 dark:text-ink-400 border-l-2 border-ink-200", children: reasoning })), jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsx("div", { className: "flex items-center gap-2", children: actions.map((action, idx) => (jsxs("button", { type: "button", onClick: action.onClick, disabled: action.disabled, className: `
12209
+ inline-flex items-center gap-1 px-3 py-1.5 rounded text-xs font-medium
12210
+ transition-colors disabled:opacity-50 disabled:cursor-not-allowed
12211
+ ${buttonVariants$1[action.variant || 'secondary']}
12212
+ `, children: [action.icon, action.label] }, idx))) }), timestamp && (jsx("span", { className: "text-xs text-ink-400 flex-shrink-0", children: timestamp }))] })] }));
12213
+ }
12214
+
12215
+ // =============================================================================
12216
+ // Helpers
12217
+ // =============================================================================
12218
+ const domainColors = {
12219
+ sales: { bg: 'bg-blue-50', text: 'text-blue-700' },
12220
+ support: { bg: 'bg-teal-50', text: 'text-teal-700' },
12221
+ commission: { bg: 'bg-green-50', text: 'text-green-700' },
12222
+ reconciliation: { bg: 'bg-indigo-50', text: 'text-indigo-700' },
12223
+ };
12224
+ // =============================================================================
12225
+ // Component
12226
+ // =============================================================================
12227
+ /**
12228
+ * SystemActionEntry — Activity feed entry showing what the system did
12229
+ *
12230
+ * Each entry shows: action description, reasoning, affected entity (clickable),
12231
+ * revert button (if applicable), confidence indicator, and timestamp.
12232
+ * Used in the Activity Center system action log.
12233
+ */
12234
+ function SystemActionEntry({ actionDescription, reasoning, entityType, entityLabel, onEntityClick, isRevertible = false, onRevert, confidence, actor = 'System', timestamp, actionType, domain, icon, reverted = false, className = '', }) {
12235
+ const domainColor = domain ? domainColors[domain] : undefined;
12236
+ return (jsxs("div", { className: `
12237
+ group relative flex gap-3 p-4 rounded-lg border
12238
+ bg-white dark:bg-ink-900 border-paper-200 dark:border-ink-700
12239
+ ${reverted ? 'opacity-60' : ''}
12240
+ ${className}
12241
+ `, children: [jsx("div", { className: "flex-shrink-0 mt-0.5 text-ink-400", children: icon || jsx("div", { className: "w-5 h-5 rounded-full bg-primary-100 flex items-center justify-center", children: jsx("span", { className: "text-xs text-primary-600", children: "A" }) }) }), jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-start justify-between gap-2", children: [jsx("p", { className: `text-sm text-ink-900 dark:text-ink-100 ${reverted ? 'line-through' : ''}`, children: actionDescription }), reverted && (jsx("span", { className: "text-xs px-2 py-0.5 rounded bg-paper-100 text-ink-500 flex-shrink-0", children: "Reverted" }))] }), jsx("p", { className: "text-xs text-ink-500 mt-1", children: reasoning }), jsxs("div", { className: "flex items-center gap-2 mt-2 flex-wrap", children: [jsxs("button", { type: "button", onClick: onEntityClick, className: "inline-flex items-center gap-1 text-xs text-primary-600 hover:text-primary-700 hover:underline", children: [entityType, ": ", entityLabel, jsx(ExternalLink, { className: "h-3 w-3" })] }), domainColor && domain && (jsx("span", { className: `text-xs px-1.5 py-0.5 rounded ${domainColor.bg} ${domainColor.text}`, children: domain })), confidence !== undefined && (jsxs("span", { className: `text-xs px-1.5 py-0.5 rounded ${confidence >= 80 ? 'bg-success-50 text-success-700' :
12242
+ confidence >= 50 ? 'bg-warning-50 text-warning-700' :
12243
+ 'bg-error-50 text-error-700'}`, children: [confidence, "%"] }))] }), jsxs("div", { className: "flex items-center justify-between gap-2 mt-2", children: [jsxs("div", { className: "flex items-center gap-2 text-xs text-ink-400", children: [jsx("span", { children: actor }), jsx("span", { children: "\u00B7" }), jsx("span", { children: timestamp }), actionType && (jsxs(Fragment, { children: [jsx("span", { children: "\u00B7" }), jsx("span", { children: actionType })] }))] }), isRevertible && !reverted && onRevert && (jsxs("button", { type: "button", onClick: onRevert, className: "inline-flex items-center gap-1 text-xs text-ink-500 hover:text-error-600 opacity-0 group-hover:opacity-100 transition-opacity", children: [jsx(RotateCcw, { className: "h-3 w-3" }), "Revert"] }))] })] })] }));
12244
+ }
12245
+
12246
+ // =============================================================================
12247
+ // Helpers
12248
+ // =============================================================================
12249
+ const healthDot = {
12250
+ good: 'bg-success-500',
12251
+ warning: 'bg-warning-500',
12252
+ critical: 'bg-error-500',
12253
+ };
12254
+ const healthText = {
12255
+ good: 'text-success-700',
12256
+ warning: 'text-warning-700',
12257
+ critical: 'text-error-700',
12258
+ };
12259
+ const trendSymbol = {
12260
+ up: '\u2191',
12261
+ down: '\u2193',
12262
+ stable: '\u2192',
12263
+ };
12264
+ // =============================================================================
12265
+ // Component
12266
+ // =============================================================================
12267
+ /**
12268
+ * ProcessHealthBar — Compact horizontal process health overview
12269
+ *
12270
+ * Shows traffic-light indicators for a process area's KPIs.
12271
+ * Used in the persona-adaptive dashboard to show overall process health.
12272
+ */
12273
+ function ProcessHealthBar({ processName, metrics, onClick, className = '', }) {
12274
+ // Overall health: worst of all metrics
12275
+ const overallHealth = metrics.some(m => m.status === 'critical') ? 'critical' :
12276
+ metrics.some(m => m.status === 'warning') ? 'warning' : 'good';
12277
+ return (jsxs("div", { onClick: onClick, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, onKeyDown: onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ')
12278
+ onClick(); } : undefined, className: `
12279
+ flex items-center gap-4 px-4 py-3 rounded-lg border
12280
+ bg-white dark:bg-ink-900 border-paper-200 dark:border-ink-700
12281
+ ${onClick ? 'cursor-pointer hover:shadow-sm hover:border-primary-300 transition-all' : ''}
12282
+ ${className}
12283
+ `, children: [jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-shrink-0", children: [jsx("span", { className: `w-3 h-3 rounded-full ${healthDot[overallHealth]}` }), jsx("span", { className: "text-sm font-medium text-ink-900 dark:text-ink-100 whitespace-nowrap", children: processName })] }), jsx("div", { className: "flex items-center gap-4 overflow-x-auto flex-1", children: metrics.map((metric, idx) => (jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: [jsx("span", { className: `w-1.5 h-1.5 rounded-full ${healthDot[metric.status]}` }), jsxs("span", { className: "text-xs text-ink-500 whitespace-nowrap", children: [metric.name, ":"] }), jsxs("span", { className: `text-xs font-medium ${healthText[metric.status]} whitespace-nowrap`, children: [metric.value, metric.trend && (jsx("span", { className: "ml-0.5", children: trendSymbol[metric.trend] }))] })] }, idx))) })] }));
12284
+ }
12285
+
12286
+ // =============================================================================
12287
+ // Default Colors
12288
+ // =============================================================================
12289
+ const defaultColors = [
12290
+ '#6366f1', // indigo
12291
+ '#8b5cf6', // violet
12292
+ '#a78bfa', // violet lighter
12293
+ '#c084fc', // purple lighter
12294
+ '#d8b4fe', // purple lightest
12295
+ '#e9d5ff', // purple very light
12296
+ '#f3e8ff', // purple ultra light
12297
+ ];
12298
+ // =============================================================================
12299
+ // Component
12300
+ // =============================================================================
12301
+ /**
12302
+ * FunnelChart — SVG funnel visualization for pipeline stages
12303
+ *
12304
+ * Renders a vertical funnel where each stage's width is proportional
12305
+ * to its count relative to the first (widest) stage.
12306
+ * Shows stage names, counts, values, and optional conversion rates.
12307
+ */
12308
+ function FunnelChart({ stages, height = 300, showConversion = true, onStageClick, className = '', }) {
12309
+ if (stages.length === 0)
12310
+ return null;
12311
+ const maxCount = Math.max(...stages.map(s => s.count), 1);
12312
+ const stageHeight = height / stages.length;
12313
+ const svgWidth = 400;
12314
+ const padding = 20;
12315
+ const funnelWidth = svgWidth - padding * 2 - 160; // Leave room for labels
12316
+ return (jsx("div", { className: className, children: jsx("svg", { width: "100%", viewBox: `0 0 ${svgWidth} ${height}`, preserveAspectRatio: "xMidYMid meet", children: stages.map((stage, idx) => {
12317
+ const ratio = stage.count / maxCount;
12318
+ const nextRatio = idx < stages.length - 1 ? stages[idx + 1].count / maxCount : ratio;
12319
+ const y = idx * stageHeight;
12320
+ const topWidth = funnelWidth * ratio;
12321
+ const bottomWidth = funnelWidth * nextRatio;
12322
+ const centerX = padding + funnelWidth / 2;
12323
+ const color = stage.color || defaultColors[idx % defaultColors.length];
12324
+ // Conversion rate
12325
+ const conversionRate = idx > 0 && stages[idx - 1].count > 0
12326
+ ? Math.round((stage.count / stages[idx - 1].count) * 100)
12327
+ : null;
12328
+ // Trapezoid path
12329
+ const path = `
12330
+ M ${centerX - topWidth / 2} ${y + 2}
12331
+ L ${centerX + topWidth / 2} ${y + 2}
12332
+ L ${centerX + bottomWidth / 2} ${y + stageHeight - 2}
12333
+ L ${centerX - bottomWidth / 2} ${y + stageHeight - 2}
12334
+ Z
12335
+ `;
12336
+ return (jsxs("g", { onClick: () => onStageClick?.(stage.name), style: onStageClick ? { cursor: 'pointer' } : undefined, role: onStageClick ? 'button' : undefined, children: [jsx("path", { d: path, fill: color, opacity: 0.85, className: "transition-opacity hover:opacity-100" }), jsx("text", { x: centerX, y: y + stageHeight / 2 + 1, textAnchor: "middle", dominantBaseline: "middle", className: "fill-white text-xs font-bold", style: { fontSize: '12px' }, children: stage.count.toLocaleString() }), jsx("text", { x: centerX + funnelWidth / 2 + 12, y: y + stageHeight / 2 - 6, className: "fill-ink-700 dark:fill-ink-300", style: { fontSize: '11px', fontWeight: 500 }, children: stage.name }), stage.value && (jsx("text", { x: centerX + funnelWidth / 2 + 12, y: y + stageHeight / 2 + 8, className: "fill-ink-400", style: { fontSize: '10px' }, children: stage.value })), showConversion && conversionRate !== null && (jsxs("text", { x: centerX - funnelWidth / 2 - 8, y: y + 4, textAnchor: "end", className: "fill-ink-400", style: { fontSize: '10px' }, children: [conversionRate, "%"] }))] }, stage.name));
12337
+ }) }) }));
12338
+ }
12339
+
12340
+ // =============================================================================
12341
+ // Helpers
12342
+ // =============================================================================
12343
+ const sizeClasses$2 = {
12344
+ sm: 'col-span-1',
12345
+ md: 'col-span-1 md:col-span-2',
12346
+ lg: 'col-span-1 md:col-span-2 lg:col-span-3',
12347
+ full: 'col-span-full',
12348
+ };
12349
+ // =============================================================================
12350
+ // Component
12351
+ // =============================================================================
12352
+ /**
12353
+ * PersonaDashboard — Adaptive dashboard shell for persona-specific widgets
12354
+ *
12355
+ * Provides the common dashboard structure:
12356
+ * 1. System action summary (hero, persona-filtered)
12357
+ * 2. Pending attention items
12358
+ * 3. Process health indicators
12359
+ * 4. Persona-specific widgets in a responsive grid
12360
+ *
12361
+ * Used as the layout container on the Home page, populated with
12362
+ * role-specific widgets based on the resolved persona.
12363
+ */
12364
+ function PersonaDashboard({ personaName, systemSummary, pendingAttention, processHealth, widgets, className = '', }) {
12365
+ return (jsxs("div", { className: `space-y-6 ${className}`, children: [systemSummary && (jsx("section", { "aria-label": "System actions", children: systemSummary })), pendingAttention && (jsx("section", { "aria-label": "Items needing attention", children: pendingAttention })), processHealth && (jsx("section", { "aria-label": "Process health", children: processHealth })), widgets.length > 0 && (jsx("section", { "aria-label": `${personaName} dashboard widgets`, children: jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", children: widgets.map(widget => (jsx("div", { className: sizeClasses$2[widget.size], children: widget.render() }, widget.id))) }) }))] }));
12366
+ }
12367
+
12368
+ // =============================================================================
12369
+ // Component
12370
+ // =============================================================================
12371
+ /**
12372
+ * ConfidenceIndicator — Circular gauge showing confidence percentage
12373
+ *
12374
+ * Renders a circular progress arc with color based on score thresholds:
12375
+ * - >= 80: green (high confidence)
12376
+ * - >= 50: yellow (medium confidence)
12377
+ * - < 50: red (low confidence)
12378
+ *
12379
+ * Used in review workflows and process views to show system confidence
12380
+ * in automated actions.
12381
+ */
12382
+ function ConfidenceIndicator({ score, label, size = 80, strokeWidth = 6, className = '', }) {
12383
+ const normalizedScore = Math.min(100, Math.max(0, score));
12384
+ const radius = (size - strokeWidth) / 2;
12385
+ const circumference = 2 * Math.PI * radius;
12386
+ const offset = circumference - (normalizedScore / 100) * circumference;
12387
+ const center = size / 2;
12388
+ const color = normalizedScore >= 80 ? '#10b981' : // success green
12389
+ normalizedScore >= 50 ? '#f59e0b' : // warning amber
12390
+ '#ef4444'; // error red
12391
+ const bgColor = normalizedScore >= 80 ? '#d1fae5' :
12392
+ normalizedScore >= 50 ? '#fef3c7' :
12393
+ '#fee2e2';
12394
+ return (jsxs("div", { className: `inline-flex flex-col items-center ${className}`, children: [jsxs("div", { className: "relative", style: { width: size, height: size }, children: [jsxs("svg", { width: size, height: size, className: "transform -rotate-90", children: [jsx("circle", { cx: center, cy: center, r: radius, fill: "none", stroke: bgColor, strokeWidth: strokeWidth }), jsx("circle", { cx: center, cy: center, r: radius, fill: "none", stroke: color, strokeWidth: strokeWidth, strokeLinecap: "round", strokeDasharray: circumference, strokeDashoffset: offset, className: "transition-all duration-500 ease-out" })] }), jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: jsxs("span", { className: "font-bold text-ink-900 dark:text-ink-100", style: { fontSize: size * 0.22 }, children: [normalizedScore, "%"] }) })] }), label && (jsx("span", { className: "text-xs text-ink-500 mt-1", children: label }))] }));
12395
+ }
12396
+
12397
+ // =============================================================================
12398
+ // Component
12399
+ // =============================================================================
12400
+ /**
12401
+ * ConfidenceBadge — Compact inline confidence display
12402
+ *
12403
+ * Shows a color-coded badge with optional score text.
12404
+ * Used in table cells, Kanban cards, and list items where
12405
+ * the full ConfidenceIndicator gauge would be too large.
12406
+ */
12407
+ function ConfidenceBadge({ score, showScore = true, size = 'md', className = '', }) {
12408
+ const normalizedScore = Math.min(100, Math.max(0, score));
12409
+ const colorClasses = normalizedScore >= 80
12410
+ ? 'bg-success-50 text-success-700 border-success-200'
12411
+ : normalizedScore >= 50
12412
+ ? 'bg-warning-50 text-warning-700 border-warning-200'
12413
+ : 'bg-error-50 text-error-700 border-error-200';
12414
+ const dotColor = normalizedScore >= 80
12415
+ ? 'bg-success-500'
12416
+ : normalizedScore >= 50
12417
+ ? 'bg-warning-500'
12418
+ : 'bg-error-500';
12419
+ const sizeClasses = {
12420
+ sm: { wrapper: 'px-1.5 py-0.5 text-[10px]', dot: 'w-1.5 h-1.5' },
12421
+ md: { wrapper: 'px-2 py-0.5 text-xs', dot: 'w-2 h-2' },
12422
+ };
12423
+ const sizes = sizeClasses[size];
12424
+ return (jsxs("span", { className: `inline-flex items-center gap-1 rounded-full border font-medium ${sizes.wrapper} ${colorClasses} ${className}`, title: `${normalizedScore}% confidence`, children: [jsx("span", { className: `${sizes.dot} rounded-full ${dotColor} flex-shrink-0` }), showScore && jsxs("span", { children: [normalizedScore, "%"] })] }));
12425
+ }
12426
+
12427
+ // =============================================================================
12428
+ // Helpers
12429
+ // =============================================================================
12430
+ const buttonVariants = {
12431
+ primary: 'bg-primary-600 text-white hover:bg-primary-700',
12432
+ secondary: 'bg-paper-100 text-ink-700 hover:bg-paper-200 border border-paper-300',
12433
+ danger: 'bg-error-600 text-white hover:bg-error-700',
12434
+ ghost: 'text-ink-600 hover:bg-paper-100',
12435
+ };
12436
+ // =============================================================================
12437
+ // Component
12438
+ // =============================================================================
12439
+ /**
12440
+ * ReviewDecisionCard — Action card with confidence breakdown
12441
+ *
12442
+ * Extended ActionCard pattern that includes a confidence gauge and
12443
+ * per-factor confidence breakdown. Used in the Approvals & Review queue
12444
+ * for items requiring human judgment.
12445
+ */
12446
+ function ReviewDecisionCard({ title, description, confidence, breakdown, recommendation, actions, entityType, entityLabel, onEntityClick, notes, timestamp, className = '', }) {
12447
+ return (jsxs("div", { className: `
12448
+ rounded-lg border bg-white dark:bg-ink-900 border-paper-200 dark:border-ink-700 p-5
12449
+ ${className}
12450
+ `, children: [jsxs("div", { className: "flex gap-4", children: [jsx("div", { className: "flex-shrink-0", children: jsx(ConfidenceIndicator, { score: confidence, size: 72, strokeWidth: 5 }) }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("h4", { className: "text-base font-medium text-ink-900 dark:text-ink-100", children: title }), description && (jsx("p", { className: "text-sm text-ink-500 mt-0.5", children: description })), entityType && entityLabel && (jsxs("button", { type: "button", onClick: onEntityClick, className: "text-xs text-primary-600 hover:underline mt-1", children: [entityType, ": ", entityLabel] })), recommendation && (jsxs("div", { className: "mt-3 px-3 py-2 bg-primary-50 dark:bg-primary-900/20 rounded text-sm text-primary-700 dark:text-primary-300", children: [jsx("span", { className: "font-medium", children: "Recommendation: " }), recommendation] }))] })] }), breakdown && breakdown.length > 0 && (jsxs("div", { className: "mt-4 pt-3 border-t border-paper-200 dark:border-ink-700", children: [jsx("h5", { className: "text-xs font-medium text-ink-500 mb-2", children: "Confidence Breakdown" }), jsx("div", { className: "space-y-2", children: breakdown.map((factor, idx) => (jsxs("div", { className: "flex items-center gap-3", children: [jsx("span", { className: "text-xs text-ink-600 w-28 flex-shrink-0", children: factor.factor }), jsx("div", { className: "flex-1 h-2 bg-paper-200 rounded-full overflow-hidden", children: jsx("div", { className: `h-full rounded-full transition-all ${factor.score >= 80 ? 'bg-success-500' :
12451
+ factor.score >= 50 ? 'bg-warning-500' :
12452
+ 'bg-error-500'}`, style: { width: `${factor.score}%` } }) }), jsxs("span", { className: "text-xs text-ink-400 w-10 text-right", children: [factor.score, "%"] })] }, idx))) })] })), notes && (jsx("div", { className: "mt-3 px-3 py-2 bg-paper-50 dark:bg-ink-800 rounded text-xs text-ink-600 border-l-2 border-ink-200", children: notes })), jsxs("div", { className: "flex items-center justify-between gap-2 mt-4 pt-3 border-t border-paper-200 dark:border-ink-700", children: [jsx("div", { className: "flex items-center gap-2", children: actions.map((action, idx) => (jsxs("button", { type: "button", onClick: action.onClick, className: `
12453
+ inline-flex items-center gap-1.5 px-4 py-2 rounded text-sm font-medium
12454
+ transition-colors
12455
+ ${buttonVariants[action.variant || 'secondary']}
12456
+ `, children: [action.icon, action.label] }, idx))) }), timestamp && (jsx("span", { className: "text-xs text-ink-400", children: timestamp }))] })] }));
12457
+ }
12458
+
12459
+ // =============================================================================
12460
+ // Helpers
12461
+ // =============================================================================
12462
+ const severityConfig = {
12463
+ info: { bg: 'bg-blue-50 dark:bg-blue-900/20', border: 'border-blue-200 dark:border-blue-800', text: 'text-blue-800 dark:text-blue-200', icon: 'text-blue-500' },
12464
+ warning: { bg: 'bg-warning-50 dark:bg-warning-900/20', border: 'border-warning-200 dark:border-warning-800', text: 'text-warning-800 dark:text-warning-200', icon: 'text-warning-500' },
12465
+ critical: { bg: 'bg-error-50 dark:bg-error-900/20', border: 'border-error-200 dark:border-error-800', text: 'text-error-800 dark:text-error-200', icon: 'text-error-500' },
12466
+ };
12467
+ // =============================================================================
12468
+ // Component
12469
+ // =============================================================================
12470
+ /**
12471
+ * AnomalyBanner — Alert banner for anomaly detection
12472
+ *
12473
+ * Shows a prominent banner when the system detects unusual patterns.
12474
+ * Severity levels: info (FYI), warning (review recommended), critical (immediate action).
12475
+ * Used at the top of process views and dashboards.
12476
+ */
12477
+ function AnomalyBanner({ title, description, severity = 'warning', affectedCount, actionLabel, onAction, onDismiss, className = '', }) {
12478
+ const config = severityConfig[severity];
12479
+ return (jsxs("div", { className: `
12480
+ flex items-start gap-3 px-4 py-3 rounded-lg border
12481
+ ${config.bg} ${config.border}
12482
+ ${className}
12483
+ `, role: "alert", children: [jsx(AlertTriangle, { className: `h-5 w-5 flex-shrink-0 mt-0.5 ${config.icon}` }), jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("h4", { className: `text-sm font-medium ${config.text}`, children: title }), affectedCount !== undefined && (jsxs("span", { className: `text-xs px-1.5 py-0.5 rounded-full ${config.bg} ${config.text} font-medium`, children: [affectedCount, " affected"] }))] }), description && (jsx("p", { className: `text-sm mt-1 ${config.text} opacity-80`, children: description })), actionLabel && onAction && (jsxs("button", { type: "button", onClick: onAction, className: `inline-flex items-center gap-1 text-sm font-medium mt-2 ${config.text} hover:underline`, children: [actionLabel, jsx(ArrowRight, { className: "h-3 w-3" })] }))] }), onDismiss && (jsx("button", { type: "button", onClick: onDismiss, className: `flex-shrink-0 p-1 rounded hover:bg-white/50 transition-colors ${config.text} opacity-60 hover:opacity-100`, "aria-label": "Dismiss", children: jsx(X, { className: "h-4 w-4" }) }))] }));
12484
+ }
12485
+
11853
12486
  /**
11854
12487
  * Avatar component that displays:
11855
12488
  * - User initials in a colored circle (default)
@@ -61942,5 +62575,5 @@ function Responsive({ mobile, tablet, desktop, }) {
61942
62575
  return jsx(Fragment, { children: mobile || tablet || desktop });
61943
62576
  }
61944
62577
 
61945
- export { Accordion, AchievementBadge, AchievementUnlock, ActionBar, ActionBarCenter, ActionBarLeft, ActionBarRight, ActionButton, ActivityFeed, AdminModal, Alert, AlertDialog, AppLayout, Autocomplete, Avatar, BREAKPOINTS, Badge, BottomNavigation, BottomNavigationSpacer, BottomSheet, BottomSheetActions, BottomSheetContent, BottomSheetHeader, Box, Breadcrumbs, Button, ButtonGroup, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CardView, Carousel, Celebration, Checkbox, CheckboxList, Chip, ChipGroup, CollaboratorAvatars, Collapsible, CollapsibleSection, ColorPicker, Combobox, ComingSoon, CommandPalette, CompactStat, ConfirmDialog, ContextMenu, ControlBar, CurrencyDisplay, CurrencyInput, Dashboard, DashboardContent, DashboardHeader, DataGrid, DataTable, DataTableCardView, DateDisplay, DatePicker, DateRangePicker, DateTimePicker, DesktopOnly, Drawer, DrawerFooter, DropZone, Dropdown, DropdownTrigger, EmptyState, ErrorBoundary, ExpandablePanel, ExpandablePanelContainer, ExpandablePanelSpacer, ExpandableRowButton, ExpandableToolbar, ExpandedRowEditForm, ExportButton, FORMULA_CATEGORIES, FORMULA_DEFINITIONS, FORMULA_NAMES, FieldArray, FileUpload, FilterBar, FilterControls, FilterStatusBanner, FloatingActionButton, Form, FormContext, FormControl, FormWizard, Grid, GridItem, HelpTooltip, Hide, HorizontalScroll, HoverCard, InfiniteScroll, Input, InviteCard, KanbanBoard, Layout, Loading, LoadingOverlay, Logo, MarkdownEditor, MaskedInput, Menu, MenuDivider, MobileHeader, MobileHeaderSpacer, MobileLayout, MobileOnly, MobileProvider, Modal, ModalFooter, MotivationalMessage, MultiSelect, NotificationBanner, NotificationBar, NotificationBell, NotificationIndicator, NumberInput, Page, PageHeader, PageLayout, PageNavigation, Pagination, PasswordInput, PermissionBadge, PivotTable, Popover, PriorityAlertBanner, Progress, ProgressCelebration, PullToRefresh, QueryTransparency, RadioGroup, Rating, Responsive, RichTextEditor, SearchBar, SearchableList, Select, Separator, SharedBadge, Show, Sidebar, SidebarGroup, Skeleton, SkeletonCard$1 as SkeletonCard, SkeletonTable, SkipLink, Slider, Spreadsheet, SpreadsheetReport, Stack, StatCard, StatItem, StatsCardGrid, StatsGrid, StatusBadge, StatusBar, StepIndicator, Stepper, StreakBadge, SuccessCheck, SummaryCard, SwipeActions, SwipeableCard, SwipeableListItem, Switch, Tabs, TabsContent, TabsList, TabsRoot, TabsTrigger, Text, Textarea, ThemeToggle, TimePicker, Timeline, TimezoneSelector, Toast, ToastContainer, Tooltip, Transfer, TreeView, TwoColumnContent, UserProfileButton, addErrorMessage, addInfoMessage, addSuccessMessage, addWarningMessage, calculateColumnWidth, createActionsSection, createFiltersSection, createMultiSheetExcel, createPageControlsSection, createQueryDetailsSection, exportDataTableToExcel, exportToExcel, formatStatisticValue, formatStatistics, getFormula, getFormulasByCategory, getLocalTimezone, isValidTimezone, loadColumnOrder, loadColumnWidths, reorderArray, saveColumnOrder, saveColumnWidths, searchFormulas, statusManager, useBreadcrumbReset, useBreakpoint, useBreakpointValue, useCelebration, useColumnReorder, useColumnResize, useCommandPalette, useConfirmDialog, useDelighters, useFABScroll, useFormContext, useIsDesktop, useIsMobile, useIsTablet, useIsTouchDevice, useMediaQuery, useMobileContext, useOrientation, usePrefersMobile, useResponsiveCallback, useSafeAreaInsets, useViewportSize, withMobileContext };
62578
+ export { Accordion, AchievementBadge, AchievementUnlock, ActionBar, ActionBarCenter, ActionBarLeft, ActionBarRight, ActionButton, ActionCard, ActivityFeed, AdminModal, Alert, AlertDialog, AnomalyBanner, AppLayout, Autocomplete, Avatar, BREAKPOINTS, Badge, BottomNavigation, BottomNavigationSpacer, BottomSheet, BottomSheetActions, BottomSheetContent, BottomSheetHeader, Box, Breadcrumbs, Button, ButtonGroup, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CardView, Carousel, CaseQueueItem, Celebration, Checkbox, CheckboxList, Chip, ChipGroup, CollaboratorAvatars, Collapsible, CollapsibleSection, ColorPicker, Combobox, ComingSoon, CommandPalette, CompactStat, ConfidenceBadge, ConfidenceIndicator, ConfirmDialog, ContextMenu, ControlBar, CurrencyDisplay, CurrencyInput, Dashboard, DashboardContent, DashboardHeader, DataGrid, DataTable, DataTableCardView, DateDisplay, DatePicker, DateRangePicker, DateTimePicker, DesktopOnly, Drawer, DrawerFooter, DropZone, Dropdown, DropdownTrigger, EmptyState, EntityCard, ErrorBoundary, ExpandablePanel, ExpandablePanelContainer, ExpandablePanelSpacer, ExpandableRowButton, ExpandableToolbar, ExpandedRowEditForm, ExportButton, FORMULA_CATEGORIES, FORMULA_DEFINITIONS, FORMULA_NAMES, FieldArray, FileUpload, FilterBar, FilterControls, FilterStatusBanner, FloatingActionButton, Form, FormContext, FormControl, FormWizard, FunnelChart, Grid, GridItem, HelpTooltip, Hide, HorizontalScroll, HoverCard, InfiniteScroll, Input, InviteCard, KanbanBoard, Layout, Loading, LoadingOverlay, Logo, MarkdownEditor, MaskedInput, MatchIndicator, Menu, MenuDivider, MobileHeader, MobileHeaderSpacer, MobileLayout, MobileOnly, MobileProvider, Modal, ModalFooter, MotivationalMessage, MultiSelect, NotificationBanner, NotificationBar, NotificationBell, NotificationIndicator, NumberInput, Page, PageHeader, PageLayout, PageNavigation, Pagination, PasswordInput, PermissionBadge, PersonaDashboard, PivotTable, Popover, PriorityAlertBanner, ProcessHealthBar, ProcessIndicator, Progress, ProgressCelebration, PullToRefresh, QueryTransparency, RadioGroup, Rating, Responsive, ReviewDecisionCard, RichTextEditor, SLAIndicator, SearchBar, SearchableList, Select, Separator, SharedBadge, Show, Sidebar, SidebarGroup, Skeleton, SkeletonCard$1 as SkeletonCard, SkeletonTable, SkipLink, Slider, SplitPane, Spreadsheet, SpreadsheetReport, Stack, StatCard, StatItem, StatsCardGrid, StatsGrid, StatusBadge, StatusBar, StepIndicator, Stepper, StreakBadge, SuccessCheck, SummaryCard, SwipeActions, SwipeableCard, SwipeableListItem, Switch, SystemActionEntry, Tabs, TabsContent, TabsList, TabsRoot, TabsTrigger, Text, Textarea, ThemeToggle, TimePicker, Timeline, TimezoneSelector, Toast, ToastContainer, Tooltip, Transfer, TreeView, TwoColumnContent, UserProfileButton, VarianceDisplay, addErrorMessage, addInfoMessage, addSuccessMessage, addWarningMessage, calculateColumnWidth, createActionsSection, createFiltersSection, createMultiSheetExcel, createPageControlsSection, createQueryDetailsSection, exportDataTableToExcel, exportToExcel, formatStatisticValue, formatStatistics, getFormula, getFormulasByCategory, getLocalTimezone, isValidTimezone, loadColumnOrder, loadColumnWidths, reorderArray, saveColumnOrder, saveColumnWidths, searchFormulas, statusManager, useBreadcrumbReset, useBreakpoint, useBreakpointValue, useCelebration, useColumnReorder, useColumnResize, useCommandPalette, useConfirmDialog, useDelighters, useFABScroll, useFormContext, useIsDesktop, useIsMobile, useIsTablet, useIsTouchDevice, useMediaQuery, useMobileContext, useOrientation, usePrefersMobile, useResponsiveCallback, useSafeAreaInsets, useViewportSize, withMobileContext };
61946
62579
  //# sourceMappingURL=index.esm.js.map