@platned/ui 0.1.4 → 0.3.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.
package/dist/index.js CHANGED
@@ -1,7 +1,4 @@
1
- // src/index.tsx
2
- import clsx21 from "clsx";
3
-
4
- // src/components/button.tsx
1
+ // src/components/forms/button.tsx
5
2
  import clsx from "clsx";
6
3
  import { jsx, jsxs } from "react/jsx-runtime";
7
4
  var variantStyles = {
@@ -69,7 +66,7 @@ function Button({
69
66
  );
70
67
  }
71
68
 
72
- // src/components/icon-button.tsx
69
+ // src/components/forms/icon-button.tsx
73
70
  import clsx2 from "clsx";
74
71
  import { jsx as jsx2 } from "react/jsx-runtime";
75
72
  var variantStyles2 = {
@@ -122,7 +119,7 @@ function IconButton({
122
119
  );
123
120
  }
124
121
 
125
- // src/components/button-group.tsx
122
+ // src/components/forms/button-group.tsx
126
123
  import clsx3 from "clsx";
127
124
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
128
125
  var containerStyles = {
@@ -219,7 +216,7 @@ function ButtonGroup({
219
216
  );
220
217
  }
221
218
 
222
- // src/components/avatar.tsx
219
+ // src/components/avatar/avatar.tsx
223
220
  import clsx4 from "clsx";
224
221
  import { jsx as jsx4 } from "react/jsx-runtime";
225
222
  var sizeStyles3 = {
@@ -275,7 +272,7 @@ function Avatar(props) {
275
272
  );
276
273
  }
277
274
 
278
- // src/components/avatar-group.tsx
275
+ // src/components/avatar/avatar-group.tsx
279
276
  import clsx5 from "clsx";
280
277
  import { jsxs as jsxs3 } from "react/jsx-runtime";
281
278
  function AvatarGroup({
@@ -314,55 +311,23 @@ function AvatarGroup({
314
311
  );
315
312
  }
316
313
 
317
- // src/components/avatar-block.tsx
314
+ // src/components/avatar/avatar-block.tsx
318
315
  import clsx6 from "clsx";
319
316
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
320
317
  function AvatarBlock({ children, title, description, className }) {
321
318
  return /* @__PURE__ */ jsxs4("div", { className: clsx6("flex items-start gap-3", className), children: [
322
319
  /* @__PURE__ */ jsx5("div", { className: "shrink-0", children }),
323
320
  /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
324
- /* @__PURE__ */ jsx5("span", { className: "text-body font-semibold leading-[1.4] text-default-secondary", children: title }),
325
- description && /* @__PURE__ */ jsx5("span", { className: "text-body leading-[1.4] text-default-tertiary", children: description })
321
+ /* @__PURE__ */ jsx5("span", { className: "text-body font-semibold text-default-secondary", children: title }),
322
+ description && /* @__PURE__ */ jsx5("span", { className: "text-body text-default-tertiary", children: description })
326
323
  ] })
327
324
  ] });
328
325
  }
329
326
 
330
- // src/components/nav-item.tsx
327
+ // src/components/forms/input.tsx
328
+ import { forwardRef } from "react";
331
329
  import clsx7 from "clsx";
332
330
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
333
- function NavItem({
334
- icon,
335
- label,
336
- isActive = false,
337
- indicator = false,
338
- collapsed = false,
339
- className
340
- }) {
341
- return /* @__PURE__ */ jsxs5(
342
- "span",
343
- {
344
- className: clsx7(
345
- "relative flex h-11 w-full items-center gap-3 rounded-xl px-3.5 py-2.5 transition-colors",
346
- collapsed && "justify-center",
347
- isActive ? "bg-brand text-brand-on-brand" : [
348
- "border border-default bg-default text-default-secondary",
349
- "hover:bg-brand-tertiary-hover hover:border-brand-tertiary hover:text-brand"
350
- ],
351
- className
352
- ),
353
- children: [
354
- icon !== void 0 && /* @__PURE__ */ jsx6("span", { className: "shrink-0 [&_svg]:size-4", children: icon }),
355
- !collapsed && /* @__PURE__ */ jsx6("span", { className: "flex-1 min-w-0 truncate text-body-sm font-regular leading-snug", children: label }),
356
- indicator && /* @__PURE__ */ jsx6("span", { className: "absolute -right-px -top-px size-2 rounded-full bg-danger" })
357
- ]
358
- }
359
- );
360
- }
361
-
362
- // src/components/input.tsx
363
- import { forwardRef } from "react";
364
- import clsx8 from "clsx";
365
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
366
331
  var wrapGap = {
367
332
  lg: "gap-2",
368
333
  // 8px
@@ -377,17 +342,17 @@ var labelText = {
377
342
  sm: "text-body-tiny"
378
343
  };
379
344
  var inputBase = {
380
- lg: "h-12 px-4 py-3.5 text-body",
381
- md: "h-9 px-3 py-2.5 text-body-sm",
382
- sm: "h-6 px-2 py-[5px] text-body-tiny"
345
+ lg: "h-12 px-5 py-3.5 text-body",
346
+ md: "h-9 px-4 py-2.5 text-body-sm",
347
+ sm: "h-6 px-3 py-[5px] text-body-tiny"
383
348
  };
384
349
  var leadingPad = {
385
- lg: "pl-10",
350
+ lg: "pl-12",
386
351
  md: "pl-8",
387
352
  sm: "pl-6"
388
353
  };
389
354
  var trailingPad = {
390
- lg: "pr-10",
355
+ lg: "pr-12",
391
356
  md: "pr-8",
392
357
  sm: "pr-6"
393
358
  };
@@ -396,50 +361,51 @@ var iconWrap = {
396
361
  md: { left: "left-3", right: "right-3", size: "size-4" },
397
362
  sm: { left: "left-2", right: "right-2", size: "size-3" }
398
363
  };
399
- var Input = forwardRef(function Input2({ label, description, error, hint, size = "md", leadingIcon, trailingIcon, className, disabled, id, ...props }, ref) {
364
+ var Input = forwardRef(function Input2({ label, description, error, hint, size = "md", leadingIcon, trailingIcon, trailingAction, className, disabled, id, ...props }, ref) {
400
365
  const hasError = !!error;
401
366
  const iw = iconWrap[size];
402
- return /* @__PURE__ */ jsxs6("div", { className: clsx8("flex flex-col", wrapGap[size], className), children: [
403
- label && /* @__PURE__ */ jsx7(
367
+ return /* @__PURE__ */ jsxs5("div", { className: clsx7("flex flex-col", wrapGap[size], className), children: [
368
+ label && /* @__PURE__ */ jsx6(
404
369
  "label",
405
370
  {
406
371
  htmlFor: id,
407
- className: clsx8(labelText[size], disabled ? "text-disabled" : "text-default"),
372
+ className: clsx7(labelText[size], disabled ? "text-disabled" : "text-default"),
408
373
  children: label
409
374
  }
410
375
  ),
411
- description && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
412
- /* @__PURE__ */ jsxs6("div", { className: "relative flex items-center", children: [
413
- leadingIcon && /* @__PURE__ */ jsx7("span", { className: clsx8("pointer-events-none absolute", iw.left, iw.size, "flex items-center justify-center text-icon-default-secondary"), children: leadingIcon }),
414
- /* @__PURE__ */ jsx7(
376
+ description && /* @__PURE__ */ jsx6("p", { className: clsx7(labelText[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
377
+ /* @__PURE__ */ jsxs5("div", { className: "relative flex items-center", children: [
378
+ leadingIcon && /* @__PURE__ */ jsx6("span", { className: clsx7("pointer-events-none absolute", iw.left, iw.size, "flex items-center justify-center text-icon-default-secondary"), children: leadingIcon }),
379
+ /* @__PURE__ */ jsx6(
415
380
  "input",
416
381
  {
417
382
  ref,
418
383
  id,
419
384
  disabled,
420
- className: clsx8(
385
+ className: clsx7(
421
386
  "w-full rounded-lg border outline-none transition-colors",
422
387
  "bg-default text-default",
423
388
  "placeholder:text-default-tertiary",
424
389
  inputBase[size],
425
390
  leadingIcon && leadingPad[size],
426
- trailingIcon && trailingPad[size],
427
- disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled placeholder:text-disabled" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-tertiary focus:ring-1 focus:ring-brand-tertiary"
391
+ (trailingIcon || trailingAction) && trailingPad[size],
392
+ disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled placeholder:text-disabled" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-secondary focus:ring-1 focus:ring-brand-secondary"
428
393
  ),
429
394
  ...props
430
395
  }
431
396
  ),
432
- trailingIcon && /* @__PURE__ */ jsx7("span", { className: clsx8("pointer-events-none absolute", iw.right, iw.size, "flex items-center justify-center text-icon-default-secondary"), children: trailingIcon })
397
+ trailingIcon && !trailingAction && /* @__PURE__ */ jsx6("span", { className: clsx7("pointer-events-none absolute", iw.right, iw.size, "flex items-center justify-center text-icon-default-secondary"), children: trailingIcon }),
398
+ trailingAction && /* @__PURE__ */ jsx6("span", { className: clsx7("absolute", iw.right, "flex items-center justify-center text-icon-default-secondary"), children: trailingAction })
433
399
  ] }),
434
- hasError && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText[size], "text-danger"), children: error }),
435
- !hasError && hint && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText[size], "text-default-secondary"), children: hint })
400
+ hasError && /* @__PURE__ */ jsx6("p", { className: clsx7(labelText[size], "text-danger"), children: error }),
401
+ !hasError && hint && /* @__PURE__ */ jsx6("p", { className: clsx7(labelText[size], "text-default"), children: hint })
436
402
  ] });
437
403
  });
438
404
 
439
- // src/components/textarea.tsx
405
+ // src/components/forms/textarea.tsx
440
406
  import { forwardRef as forwardRef2 } from "react";
441
- import clsx9 from "clsx";
442
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
407
+ import clsx8 from "clsx";
408
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
443
409
  var wrapGap2 = {
444
410
  lg: "gap-2",
445
411
  md: "gap-1",
@@ -457,42 +423,42 @@ var textareaBase = {
457
423
  };
458
424
  var Textarea = forwardRef2(function Textarea2({ label, description, error, hint, size = "md", className, disabled, id, ...props }, ref) {
459
425
  const hasError = !!error;
460
- return /* @__PURE__ */ jsxs7("div", { className: clsx9("flex flex-col", wrapGap2[size], className), children: [
461
- label && /* @__PURE__ */ jsx8(
426
+ return /* @__PURE__ */ jsxs6("div", { className: clsx8("flex flex-col", wrapGap2[size], className), children: [
427
+ label && /* @__PURE__ */ jsx7(
462
428
  "label",
463
429
  {
464
430
  htmlFor: id,
465
- className: clsx9(labelText2[size], disabled ? "text-disabled" : "text-default"),
431
+ className: clsx8(labelText2[size], disabled ? "text-disabled" : "text-default"),
466
432
  children: label
467
433
  }
468
434
  ),
469
- description && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText2[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
470
- /* @__PURE__ */ jsx8(
435
+ description && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText2[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
436
+ /* @__PURE__ */ jsx7(
471
437
  "textarea",
472
438
  {
473
439
  ref,
474
440
  id,
475
441
  disabled,
476
- className: clsx9(
442
+ className: clsx8(
477
443
  "w-full rounded-lg border outline-none transition-colors resize-y",
478
444
  "bg-default text-default",
479
445
  "placeholder:text-default-tertiary",
480
446
  textareaBase[size],
481
- disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled placeholder:text-disabled resize-none" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-tertiary focus:ring-1 focus:ring-brand-tertiary"
447
+ disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled placeholder:text-disabled resize-none" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-secondary focus:ring-1 focus:ring-brand-secondary"
482
448
  ),
483
449
  ...props
484
450
  }
485
451
  ),
486
- hasError && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText2[size], "text-danger"), children: error }),
487
- !hasError && hint && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText2[size], "text-default-secondary"), children: hint })
452
+ hasError && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText2[size], "text-danger"), children: error }),
453
+ !hasError && hint && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText2[size], "text-default-secondary"), children: hint })
488
454
  ] });
489
455
  });
490
456
 
491
- // src/components/select.tsx
457
+ // src/components/forms/select.tsx
492
458
  import { forwardRef as forwardRef3 } from "react";
493
- import clsx10 from "clsx";
459
+ import clsx9 from "clsx";
494
460
  import { LuChevronDown } from "react-icons/lu";
495
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
461
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
496
462
  var wrapGap3 = {
497
463
  lg: "gap-2",
498
464
  md: "gap-1",
@@ -519,56 +485,136 @@ var chevronPos = {
519
485
  var Select = forwardRef3(function Select2({ label, description, error, hint, size = "md", options, placeholder, className, disabled, id, ...props }, ref) {
520
486
  const hasError = !!error;
521
487
  const cp = chevronPos[size];
522
- return /* @__PURE__ */ jsxs8("div", { className: clsx10("flex flex-col", wrapGap3[size], className), children: [
523
- label && /* @__PURE__ */ jsx9(
488
+ return /* @__PURE__ */ jsxs7("div", { className: clsx9("flex flex-col", wrapGap3[size], className), children: [
489
+ label && /* @__PURE__ */ jsx8(
524
490
  "label",
525
491
  {
526
492
  htmlFor: id,
527
- className: clsx10(labelText3[size], disabled ? "text-disabled" : "text-default"),
493
+ className: clsx9(labelText3[size], disabled ? "text-disabled" : "text-default"),
528
494
  children: label
529
495
  }
530
496
  ),
531
- description && /* @__PURE__ */ jsx9("p", { className: clsx10(labelText3[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
532
- /* @__PURE__ */ jsxs8("div", { className: "relative flex items-center", children: [
533
- /* @__PURE__ */ jsxs8(
497
+ description && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText3[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
498
+ /* @__PURE__ */ jsxs7("div", { className: "relative flex items-center", children: [
499
+ /* @__PURE__ */ jsxs7(
534
500
  "select",
535
501
  {
536
502
  ref,
537
503
  id,
538
504
  disabled,
539
- className: clsx10(
505
+ className: clsx9(
540
506
  "w-full appearance-none rounded-lg border outline-none transition-colors pt-0.5",
541
507
  "bg-default text-default",
542
508
  selectBase[size],
543
- disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-tertiary focus:ring-1 focus:ring-brand-tertiary"
509
+ disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-secondary focus:ring-1 focus:ring-brand-secondary"
544
510
  ),
545
511
  ...props,
546
512
  children: [
547
- placeholder && /* @__PURE__ */ jsx9("option", { value: "", disabled: true, children: placeholder }),
548
- options.map((opt) => /* @__PURE__ */ jsx9("option", { value: opt.value, children: opt.label }, opt.value))
513
+ placeholder && /* @__PURE__ */ jsx8("option", { value: "", disabled: true, children: placeholder }),
514
+ options.map((opt) => /* @__PURE__ */ jsx8("option", { value: opt.value, children: opt.label }, opt.value))
549
515
  ]
550
516
  }
551
517
  ),
552
- /* @__PURE__ */ jsx9(
518
+ /* @__PURE__ */ jsx8(
553
519
  "span",
554
520
  {
555
- className: clsx10(
521
+ className: clsx9(
556
522
  "pointer-events-none absolute",
557
523
  cp.right,
558
524
  cp.size,
559
525
  "flex items-center justify-center",
560
526
  disabled ? "text-icon-disabled" : "text-icon-default-secondary"
561
527
  ),
562
- children: /* @__PURE__ */ jsx9(LuChevronDown, { className: "size-full" })
528
+ children: /* @__PURE__ */ jsx8(LuChevronDown, { className: "size-full" })
529
+ }
530
+ )
531
+ ] }),
532
+ hasError && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText3[size], "text-danger"), children: error }),
533
+ !hasError && hint && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText3[size], "text-default-secondary"), children: hint })
534
+ ] });
535
+ });
536
+
537
+ // src/components/forms/date-picker.tsx
538
+ import { forwardRef as forwardRef4 } from "react";
539
+ import clsx10 from "clsx";
540
+ import { LuCalendar } from "react-icons/lu";
541
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
542
+ var wrapGap4 = {
543
+ lg: "gap-2",
544
+ md: "gap-1",
545
+ sm: "gap-0.5"
546
+ };
547
+ var labelText4 = {
548
+ lg: "text-body",
549
+ md: "text-body-sm",
550
+ sm: "text-body-tiny"
551
+ };
552
+ var inputBase2 = {
553
+ lg: "h-12 px-5 py-3.5 pr-12 text-body",
554
+ md: "h-9 px-4 py-2.5 pr-8 text-body-sm",
555
+ sm: "h-6 px-3 py-[5px] pr-6 text-body-tiny"
556
+ };
557
+ var iconWrap2 = {
558
+ lg: { right: "right-4", size: "size-5" },
559
+ md: { right: "right-3", size: "size-4" },
560
+ sm: { right: "right-2", size: "size-3" }
561
+ };
562
+ var DatePicker = forwardRef4(function DatePicker2({ label, description, error, hint, size = "md", className, disabled, id, ...props }, ref) {
563
+ const hasError = !!error;
564
+ const iw = iconWrap2[size];
565
+ return /* @__PURE__ */ jsxs8("div", { className: clsx10("flex flex-col", wrapGap4[size], className), children: [
566
+ label && /* @__PURE__ */ jsx9(
567
+ "label",
568
+ {
569
+ htmlFor: id,
570
+ className: clsx10(labelText4[size], disabled ? "text-disabled" : "text-default"),
571
+ children: label
572
+ }
573
+ ),
574
+ description && /* @__PURE__ */ jsx9("p", { className: clsx10(labelText4[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
575
+ /* @__PURE__ */ jsxs8("div", { className: "relative flex items-center", children: [
576
+ /* @__PURE__ */ jsx9(
577
+ "input",
578
+ {
579
+ ref,
580
+ id,
581
+ type: "date",
582
+ disabled,
583
+ className: clsx10(
584
+ "w-full rounded-lg border outline-none transition-colors",
585
+ "bg-default text-default",
586
+ "[&::-webkit-calendar-picker-indicator]:opacity-0",
587
+ "[&::-webkit-calendar-picker-indicator]:absolute",
588
+ "[&::-webkit-calendar-picker-indicator]:right-0",
589
+ "[&::-webkit-calendar-picker-indicator]:h-full",
590
+ "[&::-webkit-calendar-picker-indicator]:w-10",
591
+ "[&::-webkit-calendar-picker-indicator]:cursor-pointer",
592
+ inputBase2[size],
593
+ disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-secondary focus:ring-1 focus:ring-brand-secondary"
594
+ ),
595
+ ...props
596
+ }
597
+ ),
598
+ /* @__PURE__ */ jsx9(
599
+ "span",
600
+ {
601
+ className: clsx10(
602
+ "pointer-events-none absolute",
603
+ iw.right,
604
+ iw.size,
605
+ "flex items-center justify-center",
606
+ disabled ? "text-icon-disabled" : "text-icon-default-secondary"
607
+ ),
608
+ children: /* @__PURE__ */ jsx9(LuCalendar, { className: "size-full" })
563
609
  }
564
610
  )
565
611
  ] }),
566
- hasError && /* @__PURE__ */ jsx9("p", { className: clsx10(labelText3[size], "text-danger"), children: error }),
567
- !hasError && hint && /* @__PURE__ */ jsx9("p", { className: clsx10(labelText3[size], "text-default-secondary"), children: hint })
612
+ hasError && /* @__PURE__ */ jsx9("p", { className: clsx10(labelText4[size], "text-danger"), children: error }),
613
+ !hasError && hint && /* @__PURE__ */ jsx9("p", { className: clsx10(labelText4[size], "text-default"), children: hint })
568
614
  ] });
569
615
  });
570
616
 
571
- // src/components/stepper.tsx
617
+ // src/components/forms/stepper.tsx
572
618
  import clsx11 from "clsx";
573
619
  import { LuCheck, LuChevronRight } from "react-icons/lu";
574
620
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -577,7 +623,7 @@ function StepIndicator({ status }) {
577
623
  return /* @__PURE__ */ jsx10("span", { className: "flex size-5 shrink-0 items-center justify-center rounded-full bg-brand text-white", children: /* @__PURE__ */ jsx10(LuCheck, { size: 11, "aria-hidden": true }) });
578
624
  }
579
625
  if (status === "active") {
580
- return /* @__PURE__ */ jsx10("span", { className: "flex size-5 shrink-0 items-center justify-center rounded-full border-2 border-background-brand", children: /* @__PURE__ */ jsx10("span", { className: "size-2.5 rounded-full bg-brand" }) });
626
+ return /* @__PURE__ */ jsx10("span", { className: "flex size-5 shrink-0 items-center justify-center rounded-full border-2 border-brand-emphasis", children: /* @__PURE__ */ jsx10("span", { className: "size-2.5 rounded-full bg-brand" }) });
581
627
  }
582
628
  return /* @__PURE__ */ jsx10("span", { className: "size-5 shrink-0 rounded-full border-2 border-disabled", "aria-hidden": "true" });
583
629
  }
@@ -614,8 +660,9 @@ function Stepper({ steps, className }) {
614
660
  );
615
661
  }
616
662
 
617
- // src/components/multiselect-card.tsx
663
+ // src/components/forms/multiselect-card.tsx
618
664
  import clsx12 from "clsx";
665
+ import { LuCheck as LuCheck2 } from "react-icons/lu";
619
666
  import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
620
667
  function MultiSelectCard({
621
668
  icon,
@@ -650,16 +697,7 @@ function MultiSelectCard({
650
697
  children: /* @__PURE__ */ jsx11("span", { className: clsx12("size-5", selected ? "text-icon-brand-on-brand" : "text-icon-brand"), children: icon })
651
698
  }
652
699
  ),
653
- selected ? /* @__PURE__ */ jsx11("span", { className: "flex size-5 shrink-0 items-center justify-center rounded-full bg-brand", children: /* @__PURE__ */ jsx11("svg", { width: "11", height: "8", viewBox: "0 0 11 8", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx11(
654
- "path",
655
- {
656
- d: "M1 4L3.9 7L10 1",
657
- stroke: "white",
658
- strokeWidth: "1.5",
659
- strokeLinecap: "round",
660
- strokeLinejoin: "round"
661
- }
662
- ) }) }) : /* @__PURE__ */ jsx11(
700
+ selected ? /* @__PURE__ */ jsx11("span", { className: "flex size-5 shrink-0 items-center justify-center rounded-full bg-brand text-icon-brand-on-brand", children: /* @__PURE__ */ jsx11(LuCheck2, { className: "size-3", strokeWidth: 2.5, "aria-hidden": true }) }) : /* @__PURE__ */ jsx11(
663
701
  "span",
664
702
  {
665
703
  className: "size-5 shrink-0 rounded-full border-2 border-default",
@@ -685,238 +723,193 @@ function MultiSelectCard({
685
723
  );
686
724
  }
687
725
 
688
- // src/components/data-table.tsx
726
+ // src/components/forms/toggle.tsx
689
727
  import clsx13 from "clsx";
690
728
  import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
691
- function DataTable({
692
- columns,
693
- rows,
694
- getRowKey,
695
- className,
696
- onRowClick
697
- }) {
698
- return /* @__PURE__ */ jsxs11(
699
- "div",
700
- {
701
- className: clsx13(
702
- "overflow-hidden rounded-xl border border-default bg-default",
703
- className
704
- ),
705
- children: [
706
- /* @__PURE__ */ jsx12("div", { className: "flex items-center bg-default-secondary px-4 py-3", children: columns.map((col) => /* @__PURE__ */ jsx12("div", { className: clsx13("overflow-hidden", col.grow ? "flex-1 min-w-0" : "shrink-0"), style: col.grow ? { minWidth: col.width } : { width: col.width }, children: /* @__PURE__ */ jsx12("span", { className: "text-body-xs font-medium text-default-secondary whitespace-nowrap", children: col.header }) }, col.key)) }),
707
- /* @__PURE__ */ jsx12("div", { children: rows.map((row, i) => /* @__PURE__ */ jsx12(
708
- "div",
709
- {
710
- className: clsx13(
711
- "flex items-center px-4 py-[14px] transition-colors hover:bg-default-secondary/50",
712
- i > 0 && "border-t border-[#ececec]",
713
- onRowClick && "cursor-pointer"
714
- ),
715
- onClick: onRowClick ? () => onRowClick(row) : void 0,
716
- children: columns.map((col) => /* @__PURE__ */ jsx12("div", { className: clsx13("overflow-hidden", col.grow ? "flex-1 min-w-0" : "shrink-0"), style: col.grow ? { minWidth: col.width } : { width: col.width }, children: col.render(row) }, col.key))
717
- },
718
- getRowKey(row, i)
719
- )) })
720
- ]
721
- }
722
- );
723
- }
724
- function TableCellLeadText({
725
- primary,
726
- secondary
727
- }) {
728
- return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-0.5", children: [
729
- /* @__PURE__ */ jsx12("span", { className: "text-body-sm font-medium text-default leading-snug", children: primary }),
730
- secondary && /* @__PURE__ */ jsx12("span", { className: "text-body-xs font-normal text-default-secondary leading-tight", children: secondary })
731
- ] });
732
- }
733
- function TableCellText({
734
- children,
735
- muted = true
736
- }) {
737
- return /* @__PURE__ */ jsx12(
738
- "span",
739
- {
740
- className: clsx13(
741
- "text-body-xs font-normal leading-snug whitespace-nowrap",
742
- muted ? "text-default-secondary" : "text-default"
743
- ),
744
- children
745
- }
746
- );
747
- }
748
- function TableCellBadge({ label }) {
749
- return /* @__PURE__ */ jsx12("span", { className: "inline-flex items-center rounded-md border border-default bg-default-secondary px-2 py-0.5 text-body-tiny font-medium text-default-secondary whitespace-nowrap", children: label });
750
- }
751
- function TableCellStatusPill({
729
+ var SIZE = {
730
+ sm: { track: "h-5 w-9", knob: "size-4", translate: "translate-x-4" },
731
+ md: { track: "h-6 w-11", knob: "size-5", translate: "translate-x-5" }
732
+ };
733
+ function Toggle({
734
+ checked,
735
+ onChange,
752
736
  label,
753
- dotColor,
754
- backgroundColor,
755
- textColor
737
+ size = "md",
738
+ disabled = false,
739
+ id,
740
+ "aria-label": ariaLabel,
741
+ "aria-labelledby": ariaLabelledBy,
742
+ className
756
743
  }) {
744
+ const s = SIZE[size];
757
745
  return /* @__PURE__ */ jsxs11(
758
- "span",
759
- {
760
- className: "inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-body-xs font-medium leading-tight whitespace-nowrap",
761
- style: { backgroundColor, color: textColor },
762
- children: [
763
- /* @__PURE__ */ jsx12("span", { className: "size-1.5 shrink-0 rounded-full", style: { backgroundColor: dotColor } }),
764
- label
765
- ]
766
- }
767
- );
768
- }
769
- function TableCellProgress({
770
- percent,
771
- barColor
772
- }) {
773
- const color = barColor ?? "#0c2d58";
774
- const clamped = Math.min(100, Math.max(0, percent));
775
- return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-1", children: [
776
- /* @__PURE__ */ jsx12("div", { className: "h-1.5 w-16 overflow-hidden rounded-full bg-default-secondary", children: /* @__PURE__ */ jsx12(
777
- "div",
778
- {
779
- className: "h-full rounded-full transition-all",
780
- style: { width: `${clamped}%`, backgroundColor: color }
781
- }
782
- ) }),
783
- /* @__PURE__ */ jsxs11("span", { className: "text-body-tiny text-default-secondary leading-none", children: [
784
- percent,
785
- "%"
786
- ] })
787
- ] });
788
- }
789
-
790
- // src/components/stat-tile.tsx
791
- import clsx14 from "clsx";
792
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
793
- function StatTile({ label, value, dotColor, className }) {
794
- return /* @__PURE__ */ jsxs12(
795
- "div",
796
- {
797
- className: clsx14(
798
- "flex flex-col gap-2 rounded-xl border border-default bg-default p-4",
799
- className
800
- ),
801
- children: [
802
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5", children: [
803
- dotColor && /* @__PURE__ */ jsx13("span", { className: "size-2 shrink-0 rounded-full", style: { backgroundColor: dotColor } }),
804
- /* @__PURE__ */ jsx13("span", { className: "text-body-xs font-medium text-default-secondary whitespace-nowrap", children: label })
805
- ] }),
806
- /* @__PURE__ */ jsx13("span", { className: "text-heading font-semibold text-default leading-none", children: value })
807
- ]
808
- }
809
- );
810
- }
811
-
812
- // src/components/toggle.tsx
813
- import clsx15 from "clsx";
814
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
815
- function Toggle({ checked, onChange, label, disabled = false }) {
816
- return /* @__PURE__ */ jsxs13(
817
746
  "button",
818
747
  {
819
748
  type: "button",
820
749
  role: "switch",
750
+ id,
821
751
  "aria-checked": checked,
752
+ "aria-label": label ? void 0 : ariaLabel,
753
+ "aria-labelledby": ariaLabelledBy,
822
754
  disabled,
823
755
  onClick: () => onChange(!checked),
824
- className: clsx15(
825
- "flex items-center gap-2",
756
+ className: clsx13(
757
+ "group flex items-center gap-2",
826
758
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1",
827
- disabled && "cursor-not-allowed opacity-50"
759
+ disabled && "cursor-not-allowed opacity-50",
760
+ className
828
761
  ),
829
762
  children: [
830
- /* @__PURE__ */ jsx14(
763
+ /* @__PURE__ */ jsx12(
831
764
  "span",
832
765
  {
833
- className: clsx15(
834
- "relative inline-flex h-6 w-10 shrink-0 rounded-full transition-colors",
835
- checked ? "bg-brand" : "border border-default bg-neutral-tertiary"
766
+ className: clsx13(
767
+ "relative inline-flex shrink-0 rounded-full transition-colors",
768
+ s.track,
769
+ // The unchecked track is borderless per the spec. A border here would also
770
+ // shift the knob's rendered inset by 1px between states, since the knob is
771
+ // positioned against the padding box.
772
+ disabled ? "bg-disabled" : checked ? "bg-brand group-hover:bg-brand-hover" : "bg-default-secondary group-hover:bg-default-secondary-hover"
836
773
  ),
837
- children: /* @__PURE__ */ jsx14(
774
+ children: /* @__PURE__ */ jsx12(
838
775
  "span",
839
776
  {
840
- className: clsx15(
841
- "absolute left-0.5 top-0.5 size-5 rounded-full bg-white shadow-sm transition-transform",
842
- checked ? "translate-x-4" : "translate-x-0"
777
+ className: clsx13(
778
+ "absolute left-0.5 top-0.5 rounded-full bg-default shadow-sm transition-transform",
779
+ s.knob,
780
+ checked ? s.translate : "translate-x-0"
843
781
  )
844
782
  }
845
783
  )
846
784
  }
847
785
  ),
848
- label && /* @__PURE__ */ jsx14("span", { className: "text-body-xs text-default", children: label })
786
+ label && /* @__PURE__ */ jsx12("span", { className: "text-body-xs text-default", children: label })
849
787
  ]
850
788
  }
851
789
  );
852
790
  }
853
791
 
854
- // src/components/file-drop-zone.tsx
792
+ // src/components/forms/file-drop-zone.tsx
855
793
  import { useRef, useState } from "react";
856
- import clsx16 from "clsx";
794
+ import clsx14 from "clsx";
857
795
  import { LuUpload } from "react-icons/lu";
858
- import { Fragment, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
859
- function FileDropZone({ className }) {
796
+ import { Fragment, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
797
+ var DEFAULT_ACCEPT = ".pdf,.jpg,.jpeg,.png";
798
+ var DEFAULT_MAX_SIZE_BYTES = 10 * 1024 * 1024;
799
+ function formatSize(bytes) {
800
+ const mb = bytes / (1024 * 1024);
801
+ return `${Number.isInteger(mb) ? mb : mb.toFixed(1)} MB`;
802
+ }
803
+ function matchesAccept(file, accept) {
804
+ const extensions = accept.split(",").map((part) => part.trim().toLowerCase()).filter((part) => part.startsWith("."));
805
+ if (extensions.length === 0) {
806
+ return true;
807
+ }
808
+ return extensions.some((extension) => file.name.toLowerCase().endsWith(extension));
809
+ }
810
+ function FileDropZone({
811
+ className,
812
+ description = "Drag & drop or browse \xB7 PDF, JPG, PNG \xB7 up to 10 MB",
813
+ accept = DEFAULT_ACCEPT,
814
+ maxSizeBytes = DEFAULT_MAX_SIZE_BYTES,
815
+ onFileSelected,
816
+ disabled = false
817
+ }) {
860
818
  const inputRef = useRef(null);
861
819
  const [isDragging, setIsDragging] = useState(false);
862
- return /* @__PURE__ */ jsxs14(Fragment, { children: [
863
- /* @__PURE__ */ jsx15(
820
+ const [error, setError] = useState(null);
821
+ function handleFiles(files) {
822
+ const file = files?.[0];
823
+ if (!file) {
824
+ return;
825
+ }
826
+ if (!matchesAccept(file, accept)) {
827
+ setError(`Unsupported file type. Allowed: ${accept}.`);
828
+ return;
829
+ }
830
+ if (file.size > maxSizeBytes) {
831
+ setError(`That file is ${formatSize(file.size)}. The limit is ${formatSize(maxSizeBytes)}.`);
832
+ return;
833
+ }
834
+ setError(null);
835
+ onFileSelected?.(file);
836
+ }
837
+ return /* @__PURE__ */ jsxs12(Fragment, { children: [
838
+ /* @__PURE__ */ jsx13(
864
839
  "input",
865
840
  {
866
841
  ref: inputRef,
867
842
  type: "file",
868
- accept: ".pdf,.jpg,.jpeg,.png",
843
+ accept,
869
844
  className: "sr-only",
870
- tabIndex: -1
845
+ tabIndex: -1,
846
+ disabled,
847
+ onChange: (e) => {
848
+ handleFiles(e.target.files);
849
+ e.target.value = "";
850
+ }
871
851
  }
872
852
  ),
873
- /* @__PURE__ */ jsxs14(
853
+ /* @__PURE__ */ jsxs12(
874
854
  "div",
875
855
  {
876
856
  role: "button",
877
- tabIndex: 0,
878
- onClick: () => inputRef.current?.click(),
879
- onKeyDown: (e) => (e.key === "Enter" || e.key === " ") && inputRef.current?.click(),
857
+ tabIndex: disabled ? -1 : 0,
858
+ "aria-disabled": disabled,
859
+ onClick: () => {
860
+ if (!disabled) inputRef.current?.click();
861
+ },
862
+ onKeyDown: (e) => {
863
+ if (!disabled && (e.key === "Enter" || e.key === " ")) {
864
+ e.preventDefault();
865
+ inputRef.current?.click();
866
+ }
867
+ },
880
868
  onDragOver: (e) => {
881
869
  e.preventDefault();
882
- setIsDragging(true);
870
+ if (!disabled) setIsDragging(true);
883
871
  },
884
872
  onDragEnter: (e) => {
885
873
  e.preventDefault();
886
- setIsDragging(true);
874
+ if (!disabled) setIsDragging(true);
887
875
  },
888
876
  onDragLeave: () => setIsDragging(false),
889
877
  onDrop: (e) => {
890
878
  e.preventDefault();
891
879
  setIsDragging(false);
880
+ if (!disabled) handleFiles(e.dataTransfer.files);
892
881
  },
893
- className: clsx16(
894
- "flex flex-col items-center justify-center gap-1 rounded-lg border-2 border-dashed py-4 px-4 cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1",
895
- isDragging ? "border-brand bg-brand-tertiary" : "border-default bg-default-secondary hover:border-brand hover:bg-brand-tertiary",
882
+ className: clsx14(
883
+ "flex flex-col items-center justify-center gap-1 rounded-lg border-2 border-dashed py-4 px-4 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1",
884
+ disabled ? "cursor-not-allowed border-disabled bg-disabled" : clsx14(
885
+ "cursor-pointer",
886
+ isDragging ? "border-brand bg-brand-tertiary" : "border-default bg-default-secondary hover:border-brand hover:bg-brand-tertiary"
887
+ ),
896
888
  className
897
889
  ),
898
890
  children: [
899
- /* @__PURE__ */ jsx15("span", { className: isDragging ? "text-brand" : "text-default-secondary", children: /* @__PURE__ */ jsx15(LuUpload, { size: 20 }) }),
900
- /* @__PURE__ */ jsx15("span", { className: "text-body-sm font-medium text-default", children: "Upload file" }),
901
- /* @__PURE__ */ jsx15("span", { className: "text-body-xs text-default-secondary text-center", children: "Drag & drop or browse \xB7 PDF, JPG, PNG \xB7 up to 10 MB" })
891
+ /* @__PURE__ */ jsx13("span", { className: disabled ? "text-disabled" : isDragging ? "text-brand" : "text-default-secondary", children: /* @__PURE__ */ jsx13(LuUpload, { className: "size-5" }) }),
892
+ /* @__PURE__ */ jsx13("span", { className: clsx14("text-body-sm font-medium", disabled ? "text-disabled" : "text-default"), children: "Upload file" }),
893
+ /* @__PURE__ */ jsx13("span", { className: "text-body-xs text-default-secondary text-center", children: description })
902
894
  ]
903
895
  }
904
- )
896
+ ),
897
+ error && /* @__PURE__ */ jsx13("span", { role: "alert", className: "text-body-xs text-danger", children: error })
905
898
  ] });
906
899
  }
907
900
 
908
- // src/components/form-card.tsx
909
- import clsx17 from "clsx";
901
+ // src/components/forms/form-card.tsx
902
+ import clsx15 from "clsx";
910
903
  import { LuArrowLeft, LuArrowRight } from "react-icons/lu";
911
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
904
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
912
905
  function FormCard({
913
906
  children,
914
907
  className
915
908
  }) {
916
- return /* @__PURE__ */ jsx16(
909
+ return /* @__PURE__ */ jsx14(
917
910
  "div",
918
911
  {
919
- className: clsx17(
912
+ className: clsx15(
920
913
  "overflow-hidden rounded-xl border border-default bg-default",
921
914
  className
922
915
  ),
@@ -925,9 +918,9 @@ function FormCard({
925
918
  );
926
919
  }
927
920
  function FormCardHeader({ title, subtitle }) {
928
- return /* @__PURE__ */ jsxs15("div", { className: "border-b border-default px-7 py-6", children: [
929
- /* @__PURE__ */ jsx16("h2", { className: "text-heading-sm font-semibold text-default leading-snug", children: title }),
930
- subtitle && /* @__PURE__ */ jsx16("p", { className: "mt-1 text-body-xs text-default-secondary", children: subtitle })
921
+ return /* @__PURE__ */ jsxs13("div", { className: "border-b border-default px-7 py-6", children: [
922
+ /* @__PURE__ */ jsx14("h2", { className: "text-heading-sm font-semibold text-default leading-snug", children: title }),
923
+ subtitle && /* @__PURE__ */ jsx14("p", { className: "mt-1 text-body-xs text-default-secondary", children: subtitle })
931
924
  ] });
932
925
  }
933
926
  function FormCardFooter({
@@ -935,131 +928,104 @@ function FormCardFooter({
935
928
  onBack,
936
929
  onContinue,
937
930
  continueLabel = "Continue",
938
- backDisabled = false
931
+ backDisabled = false,
932
+ continueDisabled = false
939
933
  }) {
940
- return /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between border-t border-default px-7 py-5", children: [
941
- /* @__PURE__ */ jsx16(Button, { variant: "neutral", size: "md", onClick: onSaveDraft, children: "Save as draft" }),
942
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
943
- !backDisabled && /* @__PURE__ */ jsx16(Button, { variant: "neutral", size: "md", leadingIcon: /* @__PURE__ */ jsx16(LuArrowLeft, { size: 16 }), onClick: onBack, children: "Back" }),
944
- /* @__PURE__ */ jsx16(Button, { variant: "primary", size: "md", trailingIcon: /* @__PURE__ */ jsx16(LuArrowRight, { size: 16 }), onClick: onContinue, children: continueLabel })
934
+ return /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between border-t border-default px-7 py-5", children: [
935
+ /* @__PURE__ */ jsx14(Button, { variant: "neutral", size: "md", onClick: onSaveDraft, disabled: !onSaveDraft, children: "Save as draft" }),
936
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
937
+ !backDisabled && /* @__PURE__ */ jsx14(Button, { variant: "neutral", size: "md", leadingIcon: /* @__PURE__ */ jsx14(LuArrowLeft, { size: 16 }), onClick: onBack, children: "Back" }),
938
+ /* @__PURE__ */ jsx14(Button, { variant: "primary", size: "md", trailingIcon: /* @__PURE__ */ jsx14(LuArrowRight, { size: 16 }), onClick: onContinue, disabled: continueDisabled, children: continueLabel })
945
939
  ] })
946
940
  ] });
947
941
  }
948
942
 
949
- // src/components/document-row.tsx
950
- import clsx18 from "clsx";
951
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
952
- var STATUS_CONFIG = {
953
- uploaded: { label: "\u2713 Uploaded", style: "bg-[#e6f4ea] text-[#1f7a3d]" },
954
- "under-review": { label: "\u25CF Under review", style: "bg-[#fbe6cf] text-[#9a6206]" },
955
- processing: { label: "\u25CF Processing", style: "bg-[#e9eff7] text-[#0c2d58]" },
956
- missing: { label: "Missing", style: "bg-[#fee2e2] text-[#b91c1c]" },
957
- "not-provided": { label: "Not provided", style: "bg-default-secondary text-default-secondary" }
943
+ // src/components/status/badge.tsx
944
+ import clsx16 from "clsx";
945
+ import { LuX } from "react-icons/lu";
946
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
947
+ var defaultClasses = {
948
+ gray: "bg-badge-gray text-badge-gray",
949
+ red: "bg-badge-red text-badge-red",
950
+ yellow: "bg-badge-yellow text-badge-yellow",
951
+ lime: "bg-badge-lime text-badge-lime",
952
+ green: "bg-badge-green text-badge-green",
953
+ teal: "bg-badge-teal text-badge-teal",
954
+ blue: "bg-badge-blue text-badge-blue",
955
+ pink: "bg-badge-pink text-badge-pink",
956
+ slate: "bg-badge-slate text-badge-slate"
958
957
  };
959
- function FileTypeBadge({ type }) {
960
- return /* @__PURE__ */ jsx17("div", { className: "flex h-[34px] w-[34px] shrink-0 items-center justify-center rounded-md bg-brand-tertiary", children: /* @__PURE__ */ jsx17("span", { className: "text-body-tiny font-semibold text-brand", children: type }) });
961
- }
962
- function DocumentRow({
963
- title,
964
- required,
965
- description,
966
- status,
967
- fileName,
968
- fileSize,
969
- fileType = "PDF"
958
+ var subtleClasses = {
959
+ gray: "border border-badge-gray text-default-secondary",
960
+ red: "border border-badge-red text-default-secondary",
961
+ yellow: "border border-badge-yellow text-default-secondary",
962
+ lime: "border border-badge-lime text-default-secondary",
963
+ green: "border border-badge-green text-default-secondary",
964
+ teal: "border border-badge-teal text-default-secondary",
965
+ blue: "border border-badge-blue text-default-secondary",
966
+ pink: "border border-badge-pink text-default-secondary",
967
+ slate: "border border-badge-slate text-default-secondary"
968
+ };
969
+ function Badge({
970
+ label,
971
+ color = "gray",
972
+ size = "sm",
973
+ variant = "default",
974
+ indicator = false,
975
+ onClose,
976
+ className
970
977
  }) {
971
- const hasFile = (status === "uploaded" || status === "under-review" || status === "processing") && !!fileName;
972
- const cfg = STATUS_CONFIG[status];
973
- return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-3 py-4", children: [
974
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between gap-2", children: [
975
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 min-w-0", children: [
976
- /* @__PURE__ */ jsx17("span", { className: "text-body-sm font-semibold text-default truncate", children: title }),
977
- /* @__PURE__ */ jsx17("span", { className: "shrink-0 rounded-md border border-default bg-default-secondary px-2 py-0.5 text-body-tiny font-medium text-default-secondary", children: required ? "Required" : "Optional" })
978
- ] }),
979
- /* @__PURE__ */ jsx17(
980
- "span",
981
- {
982
- className: clsx18(
983
- "shrink-0 rounded-full px-2.5 py-0.5 text-body-tiny font-medium whitespace-nowrap",
984
- cfg.style
985
- ),
986
- children: cfg.label
987
- }
988
- )
989
- ] }),
990
- /* @__PURE__ */ jsx17("p", { className: "text-body-xs text-default-secondary", children: description }),
991
- hasFile ? /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3 rounded-lg border border-default bg-default px-3 py-2.5", children: [
992
- /* @__PURE__ */ jsx17(FileTypeBadge, { type: fileType }),
993
- /* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
994
- /* @__PURE__ */ jsx17("span", { className: "truncate text-body-sm font-medium text-default", children: fileName }),
995
- fileSize && /* @__PURE__ */ jsx17("span", { className: "text-body-xs text-default-secondary", children: fileSize })
996
- ] }),
997
- /* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-4", children: [
998
- /* @__PURE__ */ jsx17(
999
- "button",
978
+ const isDefault = variant === "default";
979
+ return /* @__PURE__ */ jsxs14(
980
+ "span",
981
+ {
982
+ className: clsx16(
983
+ "inline-flex items-center rounded-full px-2 py-0.5",
984
+ size === "sm" ? "gap-1" : "gap-1.5",
985
+ isDefault ? defaultClasses[color] : subtleClasses[color],
986
+ className
987
+ ),
988
+ children: [
989
+ indicator && /* @__PURE__ */ jsx15(
990
+ "span",
1000
991
  {
1001
- type: "button",
1002
- className: "text-body-xs font-medium text-brand hover:underline",
1003
- children: "Replace"
992
+ className: clsx16(
993
+ "shrink-0 rounded-full bg-current",
994
+ size === "sm" ? "h-1.5 w-1.5" : "h-2 w-2"
995
+ )
996
+ }
997
+ ),
998
+ /* @__PURE__ */ jsx15(
999
+ "span",
1000
+ {
1001
+ className: clsx16(
1002
+ "whitespace-nowrap",
1003
+ size === "sm" ? clsx16("text-body-tiny", isDefault && "font-semibold") : "text-body-xs"
1004
+ ),
1005
+ children: label
1004
1006
  }
1005
1007
  ),
1006
- /* @__PURE__ */ jsx17(
1008
+ onClose && /* @__PURE__ */ jsx15(
1007
1009
  "button",
1008
1010
  {
1009
1011
  type: "button",
1010
- className: "text-body-xs font-medium text-danger hover:underline",
1011
- children: "Remove"
1012
+ onClick: onClose,
1013
+ className: clsx16(
1014
+ "inline-flex shrink-0 items-center justify-center rounded-full opacity-60 transition-opacity hover:opacity-100",
1015
+ size === "sm" ? "h-3 w-3" : "h-4 w-4"
1016
+ ),
1017
+ "aria-label": "Remove",
1018
+ children: /* @__PURE__ */ jsx15(LuX, { className: "h-full w-full", strokeWidth: 2.5, "aria-hidden": true })
1012
1019
  }
1013
1020
  )
1014
- ] })
1015
- ] }) : /* @__PURE__ */ jsx17(FileDropZone, {})
1016
- ] });
1021
+ ]
1022
+ }
1023
+ );
1017
1024
  }
1018
1025
 
1019
- // src/components/modal.tsx
1020
- import clsx19 from "clsx";
1021
- import { LuX } from "react-icons/lu";
1022
- import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
1023
- function Modal({ isOpen, onClose, title, subtitle, children, footer, maxWidth = "max-w-[540px]" }) {
1024
- if (!isOpen) return null;
1025
- return /* @__PURE__ */ jsx18(
1026
- "div",
1027
- {
1028
- className: "fixed inset-0 z-50 flex items-center justify-center bg-black/80",
1029
- onClick: (e) => {
1030
- if (e.target === e.currentTarget) onClose();
1031
- },
1032
- children: /* @__PURE__ */ jsxs17("div", { className: clsx19("w-full mx-4 rounded-2xl bg-white shadow-xl", maxWidth), children: [
1033
- /* @__PURE__ */ jsxs17("div", { className: "flex items-start justify-between px-6 py-5", children: [
1034
- /* @__PURE__ */ jsxs17("div", { children: [
1035
- /* @__PURE__ */ jsx18("h2", { className: "text-heading-sm font-semibold text-default", children: title }),
1036
- subtitle && /* @__PURE__ */ jsx18("p", { className: "mt-0.5 text-body-xs text-default-secondary", children: subtitle })
1037
- ] }),
1038
- /* @__PURE__ */ jsx18(
1039
- IconButton,
1040
- {
1041
- variant: "subtle",
1042
- size: "sm",
1043
- "aria-label": "Close dialog",
1044
- onClick: onClose,
1045
- children: /* @__PURE__ */ jsx18(LuX, { size: 16 })
1046
- }
1047
- )
1048
- ] }),
1049
- /* @__PURE__ */ jsx18("hr", { className: "border-default" }),
1050
- /* @__PURE__ */ jsx18("div", { className: "px-6 py-5", children }),
1051
- footer && /* @__PURE__ */ jsxs17(Fragment2, { children: [
1052
- /* @__PURE__ */ jsx18("hr", { className: "border-default" }),
1053
- /* @__PURE__ */ jsx18("div", { className: "flex items-center justify-end gap-2 px-6 py-4", children: footer })
1054
- ] })
1055
- ] })
1056
- }
1057
- );
1058
- }
1059
-
1060
- // src/components/role-badge.tsx
1061
- import clsx20 from "clsx";
1062
- import { jsx as jsx19 } from "react/jsx-runtime";
1026
+ // src/components/status/role-badge.tsx
1027
+ import clsx17 from "clsx";
1028
+ import { jsx as jsx16 } from "react/jsx-runtime";
1063
1029
  var ROLE_COLORS = {
1064
1030
  "Super Admin": { bg: "#e9eff7", text: "#0c2d58" },
1065
1031
  "Admin": { bg: "#e9eff7", text: "#0c2d58" },
@@ -1073,12 +1039,19 @@ var ROLE_COLORS = {
1073
1039
  "User": { bg: "#e9eff7", text: "#0c2d58" }
1074
1040
  };
1075
1041
  var FALLBACK = { bg: "#f5f5f5", text: "#757575" };
1076
- function RoleBadge({ role, size = "sm" }) {
1077
- const colors = ROLE_COLORS[role] ?? FALLBACK;
1078
- return /* @__PURE__ */ jsx19(
1042
+ var HEX6 = /^#[0-9a-fA-F]{6}$/;
1043
+ function resolveColors(role, color) {
1044
+ if (color && HEX6.test(color)) {
1045
+ return { bg: `${color}1F`, text: color };
1046
+ }
1047
+ return ROLE_COLORS[role] ?? FALLBACK;
1048
+ }
1049
+ function RoleBadge({ role, size = "sm", color }) {
1050
+ const colors = resolveColors(role, color);
1051
+ return /* @__PURE__ */ jsx16(
1079
1052
  "span",
1080
1053
  {
1081
- className: clsx20(
1054
+ className: clsx17(
1082
1055
  "inline-flex items-center rounded-full font-medium whitespace-nowrap",
1083
1056
  size === "sm" ? "px-2 py-0.5 text-body-tiny" : "px-3 py-1 text-body-xs"
1084
1057
  ),
@@ -1088,10 +1061,10 @@ function RoleBadge({ role, size = "sm" }) {
1088
1061
  );
1089
1062
  }
1090
1063
 
1091
- // src/components/role-combo-box.tsx
1064
+ // src/components/forms/role-combo-box.tsx
1092
1065
  import { useEffect, useRef as useRef2, useState as useState2 } from "react";
1093
1066
  import { LuChevronDown as LuChevronDown2 } from "react-icons/lu";
1094
- import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
1067
+ import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1095
1068
  var ROLE_COMBO_OPTIONS = [
1096
1069
  { role: "Reviewer", description: "Reviews onboarding requests" },
1097
1070
  { role: "Admin", description: "Full org control" },
@@ -1130,21 +1103,32 @@ function RoleComboBox({ value, onChange, options = ROLE_COMBO_OPTIONS }) {
1130
1103
  const otherOptions = options.filter(
1131
1104
  (o) => o.role !== value && o.role.toLowerCase().includes(query.toLowerCase())
1132
1105
  );
1133
- return /* @__PURE__ */ jsxs18("div", { className: "relative", ref: containerRef, children: [
1134
- /* @__PURE__ */ jsxs18(
1106
+ return /* @__PURE__ */ jsxs15("div", { className: "relative", ref: containerRef, children: [
1107
+ /* @__PURE__ */ jsxs15(
1135
1108
  "div",
1136
1109
  {
1137
1110
  role: "combobox",
1138
1111
  "aria-expanded": open,
1139
1112
  "aria-haspopup": "listbox",
1140
1113
  onClick: openDropdown,
1114
+ tabIndex: 0,
1115
+ onKeyDown: (e) => {
1116
+ if (e.key === "Enter" || e.key === " ") {
1117
+ e.preventDefault();
1118
+ openDropdown();
1119
+ }
1120
+ if (e.key === "Escape") {
1121
+ setOpen(false);
1122
+ setQuery("");
1123
+ }
1124
+ },
1141
1125
  className: `flex h-11 cursor-pointer items-center gap-2 rounded-lg border-[1.5px] pl-2.5 pr-3 transition-colors ${open ? "border-blue-500" : "border-default hover:border-brand-tertiary"}`,
1142
1126
  children: [
1143
- /* @__PURE__ */ jsxs18("div", { className: "flex flex-1 min-w-0 items-center gap-1.5 overflow-hidden", children: [
1144
- /* @__PURE__ */ jsx20(RoleBadge, { role: value, size: "sm" }),
1145
- value === "User" && !open && /* @__PURE__ */ jsx20("span", { className: "rounded border border-default bg-default-secondary px-1.5 py-0.5 text-body-tiny font-medium text-default-secondary", children: "DEFAULT" }),
1146
- open && /* @__PURE__ */ jsxs18(Fragment3, { children: [
1147
- /* @__PURE__ */ jsx20(
1127
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-1 min-w-0 items-center gap-1.5 overflow-hidden", children: [
1128
+ /* @__PURE__ */ jsx17(RoleBadge, { role: value, size: "sm" }),
1129
+ value === "User" && !open && /* @__PURE__ */ jsx17("span", { className: "rounded border border-default bg-default-secondary px-1.5 py-0.5 text-body-tiny font-medium text-default-secondary", children: "DEFAULT" }),
1130
+ open && /* @__PURE__ */ jsxs15(Fragment2, { children: [
1131
+ /* @__PURE__ */ jsx17(
1148
1132
  "input",
1149
1133
  {
1150
1134
  ref: inputRef,
@@ -1156,20 +1140,20 @@ function RoleComboBox({ value, onChange, options = ROLE_COMBO_OPTIONS }) {
1156
1140
  "aria-label": "Search roles"
1157
1141
  }
1158
1142
  ),
1159
- /* @__PURE__ */ jsx20("span", { className: "mx-0.5 h-[18px] w-px shrink-0 bg-text-default", "aria-hidden": true })
1143
+ /* @__PURE__ */ jsx17("span", { className: "mx-0.5 h-[18px] w-px shrink-0 bg-divider", "aria-hidden": true })
1160
1144
  ] })
1161
1145
  ] }),
1162
- /* @__PURE__ */ jsx20("span", { className: "shrink-0 text-default-secondary", children: /* @__PURE__ */ jsx20(LuChevronDown2, { size: 14 }) })
1146
+ /* @__PURE__ */ jsx17("span", { className: "shrink-0 text-default-secondary", children: /* @__PURE__ */ jsx17(LuChevronDown2, { size: 14 }) })
1163
1147
  ]
1164
1148
  }
1165
1149
  ),
1166
- open && /* @__PURE__ */ jsxs18(
1150
+ open && /* @__PURE__ */ jsxs15(
1167
1151
  "div",
1168
1152
  {
1169
1153
  role: "listbox",
1170
1154
  className: "absolute left-0 right-0 top-full z-20 mt-1 flex max-h-64 flex-col gap-0.5 overflow-y-auto rounded-xl border border-default bg-white p-1.5 shadow-lg",
1171
1155
  children: [
1172
- selectedEntry && /* @__PURE__ */ jsxs18(
1156
+ selectedEntry && /* @__PURE__ */ jsxs15(
1173
1157
  "div",
1174
1158
  {
1175
1159
  role: "option",
@@ -1177,31 +1161,38 @@ function RoleComboBox({ value, onChange, options = ROLE_COMBO_OPTIONS }) {
1177
1161
  className: "flex cursor-pointer items-center gap-2.5 rounded-md bg-blue-50 px-2.5 py-2",
1178
1162
  onClick: () => select(selectedEntry.role),
1179
1163
  children: [
1180
- /* @__PURE__ */ jsx20(RoleBadge, { role: selectedEntry.role, size: "sm" }),
1181
- /* @__PURE__ */ jsx20("span", { className: "flex-1 text-body-xs text-default-secondary", children: selectedEntry.description }),
1182
- /* @__PURE__ */ jsx20("span", { className: "shrink-0 text-sm font-bold text-blue-600", children: "\u2713" })
1164
+ /* @__PURE__ */ jsx17(RoleBadge, { role: selectedEntry.role, size: "sm" }),
1165
+ /* @__PURE__ */ jsx17("span", { className: "flex-1 text-body-xs text-default-secondary", children: selectedEntry.description }),
1166
+ /* @__PURE__ */ jsx17("span", { className: "shrink-0 text-sm font-bold text-blue-600", children: "\u2713" })
1183
1167
  ]
1184
1168
  }
1185
1169
  ),
1186
- /* @__PURE__ */ jsx20("div", { className: "h-px bg-border-default" }),
1187
- otherOptions.length > 0 && /* @__PURE__ */ jsxs18(Fragment3, { children: [
1188
- /* @__PURE__ */ jsx20("div", { className: "px-2.5 pb-1 pt-1.5", children: /* @__PURE__ */ jsx20("span", { className: "text-body-tiny font-semibold uppercase tracking-wide text-default-secondary", children: "Other roles" }) }),
1189
- otherOptions.map((opt) => /* @__PURE__ */ jsxs18(
1170
+ /* @__PURE__ */ jsx17("div", { className: "h-px bg-divider" }),
1171
+ otherOptions.length > 0 && /* @__PURE__ */ jsxs15(Fragment2, { children: [
1172
+ /* @__PURE__ */ jsx17("div", { className: "px-2.5 pb-1 pt-1.5", children: /* @__PURE__ */ jsx17("span", { className: "text-body-tiny font-semibold uppercase tracking-wide text-default-secondary", children: "Other roles" }) }),
1173
+ otherOptions.map((opt) => /* @__PURE__ */ jsxs15(
1190
1174
  "div",
1191
1175
  {
1192
1176
  role: "option",
1193
1177
  "aria-selected": false,
1194
1178
  className: "flex cursor-pointer items-center gap-2.5 rounded-md px-2.5 py-2 hover:bg-default-secondary",
1195
1179
  onClick: () => select(opt.role),
1180
+ tabIndex: 0,
1181
+ onKeyDown: (e) => {
1182
+ if (e.key === "Enter" || e.key === " ") {
1183
+ e.preventDefault();
1184
+ select(opt.role);
1185
+ }
1186
+ },
1196
1187
  children: [
1197
- /* @__PURE__ */ jsx20(RoleBadge, { role: opt.role, size: "sm" }),
1198
- /* @__PURE__ */ jsx20("span", { className: "text-body-xs text-default-secondary", children: opt.description })
1188
+ /* @__PURE__ */ jsx17(RoleBadge, { role: opt.role, size: "sm" }),
1189
+ /* @__PURE__ */ jsx17("span", { className: "text-body-xs text-default-secondary", children: opt.description })
1199
1190
  ]
1200
1191
  },
1201
1192
  opt.role
1202
1193
  ))
1203
1194
  ] }),
1204
- otherOptions.length === 0 && query && /* @__PURE__ */ jsxs18("p", { className: "px-2.5 py-2 text-body-xs text-default-secondary", children: [
1195
+ otherOptions.length === 0 && query && /* @__PURE__ */ jsxs15("p", { className: "px-2.5 py-2 text-body-xs text-default-secondary", children: [
1205
1196
  'No roles match "',
1206
1197
  query,
1207
1198
  '"'
@@ -1212,93 +1203,2754 @@ function RoleComboBox({ value, onChange, options = ROLE_COMBO_OPTIONS }) {
1212
1203
  ] });
1213
1204
  }
1214
1205
 
1215
- // src/index.tsx
1216
- import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
1217
- function Panel({
1206
+ // src/components/status/status-badge.tsx
1207
+ import clsx18 from "clsx";
1208
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
1209
+ var TONE_STYLES = {
1210
+ neutral: "bg-status-neutral text-status-neutral",
1211
+ info: "bg-status-info text-status-info",
1212
+ warning: "bg-status-warning text-status-warning",
1213
+ caution: "bg-status-caution text-status-caution",
1214
+ accent: "bg-status-accent text-status-accent",
1215
+ positive: "bg-status-positive text-status-positive",
1216
+ danger: "bg-status-danger text-status-danger"
1217
+ };
1218
+ var DOT_STYLES = {
1219
+ neutral: "bg-status-dot-neutral",
1220
+ info: "bg-status-dot-info",
1221
+ warning: "bg-status-dot-warning",
1222
+ caution: "bg-status-dot-caution",
1223
+ accent: "bg-status-dot-accent",
1224
+ positive: "bg-status-dot-positive",
1225
+ danger: "bg-status-dot-danger"
1226
+ };
1227
+ var SIZE_STYLES = {
1228
+ sm: "px-2 py-0.5 text-body-tiny",
1229
+ md: "px-2.5 py-1 text-body-xs"
1230
+ };
1231
+ function StatusBadge({
1232
+ label,
1233
+ tone = "neutral",
1234
+ size = "md",
1235
+ dot = true,
1236
+ icon,
1237
+ className
1238
+ }) {
1239
+ return /* @__PURE__ */ jsxs16(
1240
+ "span",
1241
+ {
1242
+ className: clsx18(
1243
+ "inline-flex items-center gap-1.5 rounded-full font-medium leading-tight whitespace-nowrap",
1244
+ SIZE_STYLES[size],
1245
+ TONE_STYLES[tone],
1246
+ className
1247
+ ),
1248
+ children: [
1249
+ icon ? /* @__PURE__ */ jsx18("span", { className: "shrink-0", children: icon }) : dot && /* @__PURE__ */ jsx18("span", { className: clsx18("size-1.5 shrink-0 rounded-full", DOT_STYLES[tone]) }),
1250
+ label
1251
+ ]
1252
+ }
1253
+ );
1254
+ }
1255
+
1256
+ // src/components/status/status-dot.tsx
1257
+ import clsx19 from "clsx";
1258
+ import { jsx as jsx19 } from "react/jsx-runtime";
1259
+ var dotTones = {
1260
+ brand: "bg-brand",
1261
+ positive: "bg-positive",
1262
+ warning: "bg-warning",
1263
+ danger: "bg-danger",
1264
+ neutral: "bg-neutral",
1265
+ default: "bg-default-tertiary"
1266
+ };
1267
+ function StatusDot({ tone = "default", color, className }) {
1268
+ return /* @__PURE__ */ jsx19(
1269
+ "span",
1270
+ {
1271
+ className: clsx19("inline-block size-1.5 shrink-0 rounded-full", !color && dotTones[tone], className),
1272
+ style: color ? { backgroundColor: color } : void 0
1273
+ }
1274
+ );
1275
+ }
1276
+
1277
+ // src/components/status/status-chip.tsx
1278
+ import clsx20 from "clsx";
1279
+ import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
1280
+ function StatusChip({ label, count, tone = "default", dotColor, bg, className }) {
1281
+ return /* @__PURE__ */ jsxs17(
1282
+ "span",
1283
+ {
1284
+ className: clsx20(
1285
+ "inline-flex items-center gap-1.5 rounded-full px-2.5 py-1",
1286
+ !bg && "bg-default-secondary",
1287
+ className
1288
+ ),
1289
+ style: bg ? { backgroundColor: bg } : void 0,
1290
+ children: [
1291
+ /* @__PURE__ */ jsx20(StatusDot, { tone, color: dotColor }),
1292
+ /* @__PURE__ */ jsx20("span", { className: "text-body-xs font-medium text-default", children: count }),
1293
+ /* @__PURE__ */ jsx20("span", { className: "text-body-xs text-default-secondary", children: label })
1294
+ ]
1295
+ }
1296
+ );
1297
+ }
1298
+
1299
+ // src/components/status/count-badge.tsx
1300
+ import clsx21 from "clsx";
1301
+ import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
1302
+ function CountBadge({ count, label, tone = "positive", className }) {
1303
+ return /* @__PURE__ */ jsxs18(
1304
+ "span",
1305
+ {
1306
+ className: clsx21(
1307
+ "inline-flex items-center gap-1.5 rounded-full border border-default px-2.5 py-1 text-body-xs font-medium text-default",
1308
+ className
1309
+ ),
1310
+ children: [
1311
+ /* @__PURE__ */ jsx21(StatusDot, { tone }),
1312
+ count,
1313
+ label && /* @__PURE__ */ jsx21("span", { className: "text-default-secondary", children: label })
1314
+ ]
1315
+ }
1316
+ );
1317
+ }
1318
+
1319
+ // src/components/status/tag-pill.tsx
1320
+ import clsx22 from "clsx";
1321
+ import { jsx as jsx22 } from "react/jsx-runtime";
1322
+ var toneStyles = {
1323
+ default: "bg-default-secondary text-default-secondary",
1324
+ brand: "bg-brand-tertiary text-brand",
1325
+ positive: "bg-positive-tertiary text-positive",
1326
+ warning: "bg-warning-tertiary text-warning",
1327
+ danger: "bg-danger-tertiary text-danger"
1328
+ };
1329
+ function TagPill({ label, tone = "default", bg, color, className }) {
1330
+ return /* @__PURE__ */ jsx22(
1331
+ "span",
1332
+ {
1333
+ className: clsx22(
1334
+ "inline-flex items-center rounded-full px-2 py-0.5 text-body-xs font-medium",
1335
+ !bg && !color && toneStyles[tone],
1336
+ className
1337
+ ),
1338
+ style: {
1339
+ ...bg ? { backgroundColor: bg } : void 0,
1340
+ ...color ? { color } : void 0
1341
+ },
1342
+ children: label
1343
+ }
1344
+ );
1345
+ }
1346
+
1347
+ // src/components/status/trail-chip.tsx
1348
+ import clsx23 from "clsx";
1349
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
1350
+ var DOT = {
1351
+ neutral: "bg-status-dot-neutral",
1352
+ info: "bg-status-dot-info",
1353
+ warning: "bg-status-dot-warning",
1354
+ caution: "bg-status-dot-caution",
1355
+ accent: "bg-status-dot-accent",
1356
+ positive: "bg-status-dot-positive",
1357
+ danger: "bg-status-dot-danger"
1358
+ };
1359
+ function TrailChip({ label, value, tone = "info", dotColor, className }) {
1360
+ return /* @__PURE__ */ jsxs19(
1361
+ "div",
1362
+ {
1363
+ className: clsx23(
1364
+ "flex items-center gap-2 rounded-full border border-default bg-default px-3 py-1.5",
1365
+ className
1366
+ ),
1367
+ children: [
1368
+ /* @__PURE__ */ jsx23(
1369
+ "span",
1370
+ {
1371
+ className: clsx23("size-1.5 shrink-0 rounded-full", !dotColor && DOT[tone]),
1372
+ style: dotColor ? { backgroundColor: dotColor } : void 0
1373
+ }
1374
+ ),
1375
+ /* @__PURE__ */ jsx23("span", { className: "text-body-tiny font-semibold uppercase tracking-wide text-default-secondary", children: label }),
1376
+ /* @__PURE__ */ jsx23("span", { className: "text-body-xs font-medium text-default", children: value })
1377
+ ]
1378
+ }
1379
+ );
1380
+ }
1381
+
1382
+ // src/components/status/user-status-pill.tsx
1383
+ import { jsx as jsx24 } from "react/jsx-runtime";
1384
+ var STATUS_META = {
1385
+ active: { label: "Active", tone: "positive" },
1386
+ // `caution` (pale yellow), not `warning` (orange) — Pending is one step below a
1387
+ // warning on the severity ramp, and reads as waiting rather than at risk.
1388
+ pending: { label: "Pending", tone: "caution" },
1389
+ deactivated: { label: "Deactivated", tone: "danger" }
1390
+ };
1391
+ function UserStatusPill({ status }) {
1392
+ const { label, tone } = STATUS_META[status];
1393
+ return /* @__PURE__ */ jsx24(StatusBadge, { label, tone });
1394
+ }
1395
+
1396
+ // src/components/status/check-indicator.tsx
1397
+ import clsx24 from "clsx";
1398
+ import { LuCheck as LuCheck3, LuCircleAlert, LuLoaderCircle, LuMinus, LuX as LuX2 } from "react-icons/lu";
1399
+ import { jsx as jsx25 } from "react/jsx-runtime";
1400
+ var STATUS_STYLES = {
1401
+ passed: "bg-status-check-passed border-status-check-passed text-status-check-passed",
1402
+ in_progress: "bg-status-check-progress border-status-check-progress text-status-check-progress",
1403
+ action_required: "bg-status-check-failed border-status-check-failed text-status-check-failed",
1404
+ failed: "bg-status-check-failed border-status-check-failed text-status-check-failed",
1405
+ pending: "bg-status-check-pending border-status-check-pending text-status-check-pending",
1406
+ waived: "bg-status-check-pending border-status-check-pending text-status-check-pending"
1407
+ };
1408
+ function StatusGlyph({ status }) {
1409
+ switch (status) {
1410
+ case "passed":
1411
+ return /* @__PURE__ */ jsx25(LuCheck3, { className: "size-3", strokeWidth: 3, "aria-hidden": true });
1412
+ case "failed":
1413
+ return /* @__PURE__ */ jsx25(LuX2, { className: "size-3", strokeWidth: 3, "aria-hidden": true });
1414
+ case "waived":
1415
+ return /* @__PURE__ */ jsx25(LuMinus, { className: "size-3", strokeWidth: 3, "aria-hidden": true });
1416
+ case "in_progress":
1417
+ return /* @__PURE__ */ jsx25(LuLoaderCircle, { className: "size-3", strokeWidth: 3, "aria-hidden": true });
1418
+ case "action_required":
1419
+ return /* @__PURE__ */ jsx25(LuCircleAlert, { className: "size-3.5", strokeWidth: 2.5, "aria-hidden": true });
1420
+ case "pending":
1421
+ return null;
1422
+ }
1423
+ }
1424
+ function CheckIndicator({ status, label, className }) {
1425
+ return /* @__PURE__ */ jsx25(
1426
+ "div",
1427
+ {
1428
+ className: clsx24(
1429
+ "flex size-[22px] shrink-0 items-center justify-center rounded-full border-[1.5px]",
1430
+ STATUS_STYLES[status],
1431
+ className
1432
+ ),
1433
+ role: label ? "img" : void 0,
1434
+ "aria-label": label,
1435
+ "aria-hidden": label ? void 0 : true,
1436
+ children: /* @__PURE__ */ jsx25(StatusGlyph, { status })
1437
+ }
1438
+ );
1439
+ }
1440
+
1441
+ // src/components/status/entity-icon-badge.tsx
1442
+ import clsx25 from "clsx";
1443
+ import { jsx as jsx26 } from "react/jsx-runtime";
1444
+ var sizeStyles4 = {
1445
+ sm: "size-8",
1446
+ md: "size-10"
1447
+ };
1448
+ var shapeStyles = {
1449
+ square: { sm: "rounded-lg", md: "rounded-xl" },
1450
+ circle: { sm: "rounded-full", md: "rounded-full" }
1451
+ };
1452
+ var toneStyles2 = {
1453
+ default: "bg-default-secondary text-icon-default",
1454
+ brand: "bg-brand-tertiary text-icon-brand",
1455
+ positive: "bg-positive-tertiary text-icon-positive",
1456
+ warning: "bg-warning-tertiary text-icon-warning",
1457
+ danger: "bg-danger-tertiary text-icon-danger",
1458
+ neutral: "bg-neutral-tertiary text-icon-neutral"
1459
+ };
1460
+ function EntityIconBadge({ size = "sm", tone = "default", shape = "square", bg, iconColor, children, className }) {
1461
+ return /* @__PURE__ */ jsx26(
1462
+ "span",
1463
+ {
1464
+ className: clsx25(
1465
+ "inline-flex shrink-0 items-center justify-center",
1466
+ sizeStyles4[size],
1467
+ shapeStyles[shape][size],
1468
+ !bg && !iconColor && toneStyles2[tone],
1469
+ className
1470
+ ),
1471
+ style: {
1472
+ ...bg ? { backgroundColor: bg } : void 0,
1473
+ ...iconColor ? { color: iconColor } : void 0
1474
+ },
1475
+ children
1476
+ }
1477
+ );
1478
+ }
1479
+
1480
+ // src/components/forms/checkbox.tsx
1481
+ import { useEffect as useEffect2, useRef as useRef3 } from "react";
1482
+ import clsx26 from "clsx";
1483
+ import { LuCheck as LuCheck4, LuMinus as LuMinus2 } from "react-icons/lu";
1484
+ import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
1485
+ function Checkbox({
1486
+ checked,
1487
+ onChange,
1488
+ label,
1489
+ disabled = false,
1490
+ indeterminate = false,
1491
+ className
1492
+ }) {
1493
+ const inputRef = useRef3(null);
1494
+ useEffect2(() => {
1495
+ if (inputRef.current) inputRef.current.indeterminate = indeterminate;
1496
+ }, [indeterminate]);
1497
+ return /* @__PURE__ */ jsxs20(
1498
+ "label",
1499
+ {
1500
+ className: clsx26(
1501
+ "group inline-flex items-start gap-2.5",
1502
+ disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer",
1503
+ className
1504
+ ),
1505
+ children: [
1506
+ /* @__PURE__ */ jsx27(
1507
+ "input",
1508
+ {
1509
+ ref: inputRef,
1510
+ type: "checkbox",
1511
+ checked,
1512
+ disabled,
1513
+ onChange: (e) => onChange(e.target.checked),
1514
+ className: "peer sr-only"
1515
+ }
1516
+ ),
1517
+ /* @__PURE__ */ jsx27(
1518
+ "span",
1519
+ {
1520
+ "aria-hidden": true,
1521
+ className: clsx26(
1522
+ "mt-px flex size-[18px] shrink-0 items-center justify-center rounded-[4px] border-[1.5px] transition-colors",
1523
+ "peer-focus-visible:ring-2 peer-focus-visible:ring-brand peer-focus-visible:ring-offset-1",
1524
+ checked || indeterminate ? "border-brand-emphasis bg-brand text-brand-on-brand" : "border-default-secondary bg-default"
1525
+ ),
1526
+ children: indeterminate ? /* @__PURE__ */ jsx27(LuMinus2, { className: "size-3", strokeWidth: 3 }) : checked ? /* @__PURE__ */ jsx27(LuCheck4, { className: "size-3", strokeWidth: 3 }) : null
1527
+ }
1528
+ ),
1529
+ label && /* @__PURE__ */ jsx27("span", { className: "text-body-xs text-default", children: label })
1530
+ ]
1531
+ }
1532
+ );
1533
+ }
1534
+
1535
+ // src/components/forms/segmented-control.tsx
1536
+ import clsx27 from "clsx";
1537
+ import { jsx as jsx28 } from "react/jsx-runtime";
1538
+ function SegmentedControl({ options, value, onChange, className }) {
1539
+ return /* @__PURE__ */ jsx28(
1540
+ "div",
1541
+ {
1542
+ className: clsx27(
1543
+ "inline-flex items-center rounded-xl border border-default bg-default-secondary p-0.5",
1544
+ className
1545
+ ),
1546
+ children: options.map((opt) => /* @__PURE__ */ jsx28(
1547
+ "button",
1548
+ {
1549
+ type: "button",
1550
+ onClick: () => onChange?.(opt.value),
1551
+ className: clsx27(
1552
+ "rounded-lg px-3.5 py-1.5 text-body-xs font-medium transition-colors",
1553
+ opt.value === value ? "bg-default shadow-panel text-default" : "text-default-secondary hover:text-default"
1554
+ ),
1555
+ children: opt.label
1556
+ },
1557
+ opt.value
1558
+ ))
1559
+ }
1560
+ );
1561
+ }
1562
+
1563
+ // src/components/overlays/modal.tsx
1564
+ import { useRef as useRef4 } from "react";
1565
+ import { LuCircleCheckBig, LuInfo, LuOctagonAlert, LuTriangleAlert, LuX as LuX3 } from "react-icons/lu";
1566
+
1567
+ // src/lib/cn.ts
1568
+ import { clsx as clsx28 } from "clsx";
1569
+ import { twMerge } from "tailwind-merge";
1570
+ function cn(...inputs) {
1571
+ return twMerge(clsx28(inputs));
1572
+ }
1573
+
1574
+ // src/components/overlays/overlay.ts
1575
+ import { useEffect as useEffect3 } from "react";
1576
+ var OVERLAY_SCRIM = "bg-overlay";
1577
+ var FOCUSABLE = [
1578
+ "a[href]",
1579
+ "button:not([disabled])",
1580
+ "input:not([disabled])",
1581
+ "select:not([disabled])",
1582
+ "textarea:not([disabled])",
1583
+ '[tabindex]:not([tabindex="-1"])'
1584
+ ].join(",");
1585
+ function focusableWithin(root) {
1586
+ return Array.from(root.querySelectorAll(FOCUSABLE)).filter(
1587
+ (el) => el.offsetParent !== null || el === root
1588
+ );
1589
+ }
1590
+ function useOverlayDismiss(onClose, panelRef) {
1591
+ useEffect3(() => {
1592
+ function onKeyDown(e) {
1593
+ const panel = panelRef.current;
1594
+ if (e.key === "Escape") {
1595
+ e.stopPropagation();
1596
+ onClose();
1597
+ return;
1598
+ }
1599
+ if (e.key !== "Tab" || !panel) return;
1600
+ const items = focusableWithin(panel);
1601
+ if (items.length === 0) return;
1602
+ const first = items[0];
1603
+ const last = items[items.length - 1];
1604
+ const active = document.activeElement;
1605
+ if (e.shiftKey && (active === first || !panel.contains(active))) {
1606
+ e.preventDefault();
1607
+ last.focus();
1608
+ } else if (!e.shiftKey && active === last) {
1609
+ e.preventDefault();
1610
+ first.focus();
1611
+ }
1612
+ }
1613
+ document.addEventListener("keydown", onKeyDown);
1614
+ return () => document.removeEventListener("keydown", onKeyDown);
1615
+ }, [onClose, panelRef]);
1616
+ useEffect3(() => {
1617
+ const previouslyFocused = document.activeElement;
1618
+ const panel = panelRef.current;
1619
+ if (panel) {
1620
+ const target = focusableWithin(panel)[0] ?? panel;
1621
+ target.focus({ preventScroll: true });
1622
+ }
1623
+ return () => previouslyFocused?.focus?.({ preventScroll: true });
1624
+ }, [panelRef]);
1625
+ }
1626
+
1627
+ // src/components/overlays/modal.tsx
1628
+ import { jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
1629
+ var SIZE2 = {
1630
+ sm: "sm:max-w-[420px]",
1631
+ md: "sm:max-w-[540px]",
1632
+ lg: "sm:max-w-[640px]",
1633
+ xl: "sm:max-w-[800px]"
1634
+ };
1635
+ var TONE_ICON = {
1636
+ info: /* @__PURE__ */ jsx29(LuInfo, { className: "size-5" }),
1637
+ positive: /* @__PURE__ */ jsx29(LuCircleCheckBig, { className: "size-5" }),
1638
+ warning: /* @__PURE__ */ jsx29(LuTriangleAlert, { className: "size-5" }),
1639
+ danger: /* @__PURE__ */ jsx29(LuOctagonAlert, { className: "size-5" })
1640
+ };
1641
+ var TONE_BADGE = {
1642
+ info: "brand",
1643
+ positive: "positive",
1644
+ warning: "warning",
1645
+ danger: "danger"
1646
+ };
1647
+ var FOOTER_ALIGN = {
1648
+ start: "justify-start",
1649
+ between: "justify-between",
1650
+ end: "justify-end"
1651
+ };
1652
+ function Modal(props) {
1653
+ if (!props.isOpen) return null;
1654
+ return /* @__PURE__ */ jsx29(ModalShell, { ...props });
1655
+ }
1656
+ function ModalShell({
1657
+ onClose,
1658
+ label,
1218
1659
  children,
1660
+ size = "md",
1661
+ showClose = true,
1219
1662
  className
1220
1663
  }) {
1221
- return /* @__PURE__ */ jsx21("section", { className: clsx21("rounded-3xl border border-white/70 bg-white/90 p-6 shadow-panel backdrop-blur", className), children });
1664
+ const panelRef = useRef4(null);
1665
+ useOverlayDismiss(onClose, panelRef);
1666
+ return /* @__PURE__ */ jsx29(
1667
+ "div",
1668
+ {
1669
+ className: cn("fixed inset-0 z-50 flex items-end justify-center sm:items-center", OVERLAY_SCRIM),
1670
+ onClick: (e) => {
1671
+ if (e.target === e.currentTarget) onClose();
1672
+ },
1673
+ children: /* @__PURE__ */ jsxs21(
1674
+ "div",
1675
+ {
1676
+ ref: panelRef,
1677
+ role: "dialog",
1678
+ "aria-modal": "true",
1679
+ "aria-label": label,
1680
+ className: cn(
1681
+ "relative max-h-[92dvh] w-full overflow-y-auto bg-default shadow-xl",
1682
+ "rounded-t-2xl pb-[env(safe-area-inset-bottom)] sm:mx-4 sm:rounded-2xl sm:pb-0",
1683
+ SIZE2[size],
1684
+ className
1685
+ ),
1686
+ children: [
1687
+ showClose && /* @__PURE__ */ jsx29(
1688
+ IconButton,
1689
+ {
1690
+ variant: "subtle",
1691
+ size: "sm",
1692
+ "aria-label": "Close dialog",
1693
+ onClick: onClose,
1694
+ className: "absolute right-6 top-5 z-10",
1695
+ children: /* @__PURE__ */ jsx29(LuX3, { size: 16 })
1696
+ }
1697
+ ),
1698
+ children
1699
+ ]
1700
+ }
1701
+ )
1702
+ }
1703
+ );
1704
+ }
1705
+ function ModalHeader({
1706
+ children,
1707
+ tone = "default",
1708
+ divider = true,
1709
+ className,
1710
+ ...rest
1711
+ }) {
1712
+ return /* @__PURE__ */ jsxs21(
1713
+ "div",
1714
+ {
1715
+ className: cn(
1716
+ // pr-14 reserves the floating close button's column (24px gutter + 24px
1717
+ // button + gap), which the old flex-between header used to hold open.
1718
+ "flex items-start gap-3 px-6 py-5 pr-14",
1719
+ divider && "border-b border-default",
1720
+ className
1721
+ ),
1722
+ ...rest,
1723
+ children: [
1724
+ tone !== "default" && /* @__PURE__ */ jsx29(EntityIconBadge, { size: "md", shape: "circle", tone: TONE_BADGE[tone], children: TONE_ICON[tone] }),
1725
+ /* @__PURE__ */ jsx29("div", { className: "min-w-0 flex-1", children })
1726
+ ]
1727
+ }
1728
+ );
1729
+ }
1730
+ function ModalTitle({ children, className, ...rest }) {
1731
+ return /* @__PURE__ */ jsx29("h2", { className: cn("text-heading-sm font-semibold text-default", className), ...rest, children });
1732
+ }
1733
+ function ModalDescription({ children, className, ...rest }) {
1734
+ return /* @__PURE__ */ jsx29("p", { className: cn("mt-0.5 text-body-xs text-default-secondary", className), ...rest, children });
1735
+ }
1736
+ function ModalBody({ children, className, ...rest }) {
1737
+ return /* @__PURE__ */ jsx29("div", { className: cn("px-6 py-5", className), ...rest, children });
1738
+ }
1739
+ function ModalFooter({
1740
+ children,
1741
+ align = "end",
1742
+ divider = true,
1743
+ className,
1744
+ ...rest
1745
+ }) {
1746
+ return /* @__PURE__ */ jsx29(
1747
+ "div",
1748
+ {
1749
+ className: cn(
1750
+ "flex items-center gap-2 px-6 py-4",
1751
+ FOOTER_ALIGN[align],
1752
+ divider && "border-t border-default",
1753
+ className
1754
+ ),
1755
+ ...rest,
1756
+ children
1757
+ }
1758
+ );
1759
+ }
1760
+
1761
+ // src/components/overlays/drawer.tsx
1762
+ import { useRef as useRef5 } from "react";
1763
+ import clsx29 from "clsx";
1764
+ import { LuX as LuX4 } from "react-icons/lu";
1765
+ import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
1766
+ function Drawer(props) {
1767
+ if (!props.isOpen) return null;
1768
+ return /* @__PURE__ */ jsx30(DrawerShell, { ...props });
1222
1769
  }
1223
- function MetricCard({
1770
+ function DrawerShell({
1771
+ onClose,
1772
+ header,
1773
+ children,
1774
+ footer,
1775
+ footerAlign = "end",
1776
+ width = "w-[440px] max-w-[90vw]",
1224
1777
  label,
1225
- value,
1226
- tone = "default"
1778
+ className
1227
1779
  }) {
1228
- const tones = {
1229
- default: "from-white to-slate-50 text-default",
1230
- signal: "from-brand-tertiary to-cyan-50 text-brand",
1231
- ember: "from-amber-50 to-orange-50 text-danger",
1232
- moss: "from-emerald-50 to-lime-50 text-positive"
1233
- };
1234
- return /* @__PURE__ */ jsxs19(Panel, { className: clsx21("bg-gradient-to-br", tones[tone]), children: [
1235
- /* @__PURE__ */ jsx21("p", { className: "text-sm uppercase tracking-[0.2em] text-slate-500", children: label }),
1236
- /* @__PURE__ */ jsx21("p", { className: "mt-3 text-3xl font-semibold", children: value })
1237
- ] });
1780
+ const panelRef = useRef5(null);
1781
+ useOverlayDismiss(onClose, panelRef);
1782
+ return /* @__PURE__ */ jsx30(
1783
+ "div",
1784
+ {
1785
+ className: clsx29("fixed inset-0 z-50 flex justify-end", OVERLAY_SCRIM),
1786
+ onClick: (e) => {
1787
+ if (e.target === e.currentTarget) onClose();
1788
+ },
1789
+ children: /* @__PURE__ */ jsxs22(
1790
+ "aside",
1791
+ {
1792
+ ref: panelRef,
1793
+ role: "dialog",
1794
+ "aria-modal": "true",
1795
+ "aria-label": label,
1796
+ className: clsx29("relative flex h-full flex-col bg-default shadow-2xl", width, className),
1797
+ children: [
1798
+ /* @__PURE__ */ jsxs22("div", { className: "flex items-start justify-between gap-3 border-b border-default p-6", children: [
1799
+ /* @__PURE__ */ jsx30("div", { className: "min-w-0", children: header }),
1800
+ /* @__PURE__ */ jsx30(IconButton, { variant: "subtle", size: "sm", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx30(LuX4, { size: 18 }) })
1801
+ ] }),
1802
+ /* @__PURE__ */ jsx30("div", { className: "flex-1 space-y-6 overflow-y-auto p-6", children }),
1803
+ footer && /* @__PURE__ */ jsx30(
1804
+ "div",
1805
+ {
1806
+ className: clsx29(
1807
+ "flex items-center gap-2 border-t border-default px-6 py-4",
1808
+ footerAlign === "between" ? "justify-between" : "justify-end"
1809
+ ),
1810
+ children: footer
1811
+ }
1812
+ )
1813
+ ]
1814
+ }
1815
+ )
1816
+ }
1817
+ );
1238
1818
  }
1239
- function SeverityBadge({ severity }) {
1240
- const styles = {
1241
- critical: "bg-red-100 text-red-700",
1242
- high: "bg-orange-100 text-orange-700",
1243
- medium: "bg-amber-100 text-amber-700",
1244
- low: "bg-slate-100 text-slate-700"
1245
- };
1246
- return /* @__PURE__ */ jsx21("span", { className: clsx21("inline-flex rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wide", styles[severity ?? "low"]), children: severity ?? "unknown" });
1247
- }
1248
- function SentimentBadge({ sentiment }) {
1249
- const styles = {
1250
- positive: "bg-emerald-100 text-emerald-700",
1251
- neutral: "bg-slate-100 text-slate-700",
1252
- negative: "bg-rose-100 text-rose-700",
1253
- concerning: "bg-amber-100 text-amber-700"
1254
- };
1255
- return /* @__PURE__ */ jsx21("span", { className: clsx21("inline-flex rounded-full px-3 py-1 text-xs font-semibold capitalize", styles[sentiment ?? "neutral"] ?? styles.neutral), children: sentiment ?? "unknown" });
1256
- }
1257
- function SectionHeading({
1258
- eyebrow,
1819
+
1820
+ // src/components/overlays/confirm-dialog.tsx
1821
+ import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
1822
+ function ConfirmDialog({
1823
+ isOpen,
1259
1824
  title,
1260
- detail
1825
+ subtitle,
1826
+ tone = "default",
1827
+ size = "md",
1828
+ confirmLabel = "Confirm",
1829
+ cancelLabel = "Cancel",
1830
+ confirmVariant = "primary",
1831
+ isConfirming = false,
1832
+ confirmingLabel = "Working\u2026",
1833
+ children,
1834
+ className,
1835
+ onConfirm,
1836
+ onClose
1261
1837
  }) {
1262
- return /* @__PURE__ */ jsxs19("div", { children: [
1263
- /* @__PURE__ */ jsx21("p", { className: "text-xs uppercase tracking-[0.25em] text-brand", children: eyebrow }),
1264
- /* @__PURE__ */ jsx21("h2", { className: "mt-2 text-2xl font-semibold text-default", children: title }),
1265
- detail ? /* @__PURE__ */ jsx21("p", { className: "mt-2 max-w-2xl text-sm text-slate-600", children: detail }) : null
1838
+ return /* @__PURE__ */ jsxs23(Modal, { isOpen, onClose, label: title, size, className, children: [
1839
+ /* @__PURE__ */ jsxs23(ModalHeader, { tone, divider: Boolean(children), children: [
1840
+ /* @__PURE__ */ jsx31(ModalTitle, { children: title }),
1841
+ subtitle && /* @__PURE__ */ jsx31(ModalDescription, { children: subtitle })
1842
+ ] }),
1843
+ children && /* @__PURE__ */ jsx31(ModalBody, { children }),
1844
+ /* @__PURE__ */ jsxs23(ModalFooter, { children: [
1845
+ /* @__PURE__ */ jsx31(Button, { variant: "neutral", size: "md", onClick: onClose, children: cancelLabel }),
1846
+ /* @__PURE__ */ jsx31(Button, { variant: confirmVariant, size: "md", disabled: isConfirming, onClick: onConfirm, children: isConfirming ? confirmingLabel : confirmLabel })
1847
+ ] })
1266
1848
  ] });
1267
1849
  }
1850
+
1851
+ // src/components/overlays/note-confirm-modal.tsx
1852
+ import { useState as useState3 } from "react";
1853
+ import { jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
1854
+ function NoteConfirmModal({ isOpen, ...rest }) {
1855
+ if (!isOpen) return null;
1856
+ return /* @__PURE__ */ jsx32(NoteConfirmModalShell, { ...rest });
1857
+ }
1858
+ function NoteConfirmModalShell({
1859
+ title,
1860
+ subtitle,
1861
+ tone = "default",
1862
+ size = "md",
1863
+ confirmLabel,
1864
+ cancelLabel = "Cancel",
1865
+ confirmVariant = "primary",
1866
+ requireNote = false,
1867
+ notePlaceholder = "Add a note\u2026",
1868
+ submittingLabel = "Saving\u2026",
1869
+ isSubmitting = false,
1870
+ className,
1871
+ onClose,
1872
+ onConfirm
1873
+ }) {
1874
+ const [note, setNote] = useState3("");
1875
+ const disabled = isSubmitting || requireNote && !note.trim();
1876
+ return /* @__PURE__ */ jsxs24(Modal, { isOpen: true, onClose, label: title, size, className, children: [
1877
+ /* @__PURE__ */ jsxs24(ModalHeader, { tone, children: [
1878
+ /* @__PURE__ */ jsx32(ModalTitle, { children: title }),
1879
+ subtitle && /* @__PURE__ */ jsx32(ModalDescription, { children: subtitle })
1880
+ ] }),
1881
+ /* @__PURE__ */ jsx32(ModalBody, { children: /* @__PURE__ */ jsx32(
1882
+ Textarea,
1883
+ {
1884
+ value: note,
1885
+ onChange: (e) => setNote(e.target.value),
1886
+ placeholder: notePlaceholder,
1887
+ rows: 4
1888
+ }
1889
+ ) }),
1890
+ /* @__PURE__ */ jsxs24(ModalFooter, { children: [
1891
+ /* @__PURE__ */ jsx32(Button, { variant: "neutral", size: "md", onClick: onClose, children: cancelLabel }),
1892
+ /* @__PURE__ */ jsx32(Button, { variant: confirmVariant, size: "md", disabled, onClick: () => onConfirm(note.trim()), children: isSubmitting ? submittingLabel : confirmLabel })
1893
+ ] })
1894
+ ] });
1895
+ }
1896
+
1897
+ // src/components/overlays/dropdown-menu.tsx
1898
+ import { useEffect as useEffect4, useRef as useRef6, useState as useState4 } from "react";
1899
+ import clsx30 from "clsx";
1900
+ import { LuEllipsis } from "react-icons/lu";
1901
+ import { jsx as jsx33, jsxs as jsxs25 } from "react/jsx-runtime";
1902
+ function DropdownMenu({
1903
+ items,
1904
+ trigger,
1905
+ label,
1906
+ align = "right",
1907
+ className
1908
+ }) {
1909
+ const [open, setOpen] = useState4(false);
1910
+ const rootRef = useRef6(null);
1911
+ useEffect4(() => {
1912
+ if (!open) return;
1913
+ function handleOutside(e) {
1914
+ const root = rootRef.current;
1915
+ if (root && !root.contains(e.target)) setOpen(false);
1916
+ }
1917
+ function handleKey(e) {
1918
+ if (e.key === "Escape") setOpen(false);
1919
+ }
1920
+ document.addEventListener("mousedown", handleOutside);
1921
+ document.addEventListener("keydown", handleKey);
1922
+ return () => {
1923
+ document.removeEventListener("mousedown", handleOutside);
1924
+ document.removeEventListener("keydown", handleKey);
1925
+ };
1926
+ }, [open]);
1927
+ const visible = items.filter((item) => item.label);
1928
+ return /* @__PURE__ */ jsxs25(
1929
+ "div",
1930
+ {
1931
+ ref: rootRef,
1932
+ className: clsx30("relative", className),
1933
+ onMouseDown: (e) => e.stopPropagation(),
1934
+ children: [
1935
+ /* @__PURE__ */ jsx33(
1936
+ "button",
1937
+ {
1938
+ type: "button",
1939
+ "aria-label": label,
1940
+ "aria-haspopup": "menu",
1941
+ "aria-expanded": open,
1942
+ onClick: (e) => {
1943
+ e.stopPropagation();
1944
+ setOpen((v) => !v);
1945
+ },
1946
+ className: clsx30(
1947
+ "rounded-md border border-default bg-default text-body-xs font-medium leading-none text-default transition-colors hover:bg-default-secondary",
1948
+ trigger ? "p-1.5" : "px-2.5 py-1.5"
1949
+ ),
1950
+ children: trigger ?? /* @__PURE__ */ jsx33(LuEllipsis, { className: "size-4" })
1951
+ }
1952
+ ),
1953
+ open && /* @__PURE__ */ jsx33(
1954
+ "div",
1955
+ {
1956
+ role: "menu",
1957
+ className: clsx30(
1958
+ "absolute top-full z-20 mt-1 min-w-[148px] rounded-lg border border-default bg-default py-1 shadow-lg",
1959
+ align === "right" ? "right-0" : "left-0"
1960
+ ),
1961
+ children: visible.map((item, i) => /* @__PURE__ */ jsxs25("div", { children: [
1962
+ item.separatorBefore && i > 0 && /* @__PURE__ */ jsx33("div", { className: "my-1 h-px bg-divider" }),
1963
+ /* @__PURE__ */ jsx33(
1964
+ "button",
1965
+ {
1966
+ type: "button",
1967
+ role: "menuitem",
1968
+ disabled: item.disabled,
1969
+ className: clsx30(
1970
+ "flex w-full items-center px-3 py-2 text-left text-body-sm transition-colors",
1971
+ item.disabled && "cursor-not-allowed opacity-50",
1972
+ item.tone === "danger" ? "text-danger hover:bg-danger-tertiary" : "text-default hover:bg-default-secondary"
1973
+ ),
1974
+ onClick: (e) => {
1975
+ e.stopPropagation();
1976
+ setOpen(false);
1977
+ item.onSelect();
1978
+ },
1979
+ children: item.label
1980
+ }
1981
+ )
1982
+ ] }, item.label))
1983
+ }
1984
+ )
1985
+ ]
1986
+ }
1987
+ );
1988
+ }
1989
+
1990
+ // src/components/cards/card.tsx
1991
+ import { jsx as jsx34 } from "react/jsx-runtime";
1992
+ var RADIUS = {
1993
+ lg: "rounded-lg",
1994
+ xl: "rounded-xl",
1995
+ "2xl": "rounded-2xl"
1996
+ };
1997
+ var TONE = {
1998
+ default: "border-default bg-default",
1999
+ brand: "border-brand-tertiary bg-brand-tertiary",
2000
+ positive: "border-positive-tertiary bg-positive-tertiary",
2001
+ warning: "border-warning-tertiary bg-warning-tertiary",
2002
+ // The one asymmetry: danger keeps the strong `border-danger` rather than the
2003
+ // tertiary border, because it is the only tone that has to read as an alarm from
2004
+ // across a dashboard. Byte-identical to the deleted AlertCard's danger surface.
2005
+ danger: "border-danger bg-danger-tertiary"
2006
+ };
2007
+ var BOX = {
2008
+ sm: "px-3 py-2",
2009
+ md: "px-4 py-3",
2010
+ lg: "px-5 py-4"
2011
+ };
2012
+ var BODY_BOX = {
2013
+ sm: "gap-3 p-3",
2014
+ md: "gap-4 p-4",
2015
+ lg: "gap-5 p-5"
2016
+ };
2017
+ var TITLE_SIZE = {
2018
+ sm: "text-body-xs",
2019
+ md: "text-body-sm",
2020
+ lg: "text-subheading-sm"
2021
+ };
2022
+ var FOOTER_ALIGN2 = {
2023
+ start: "justify-start",
2024
+ between: "justify-between",
2025
+ end: "justify-end"
2026
+ };
2027
+ function Card({ children, radius = "2xl", tone = "default", className, ...rest }) {
2028
+ return /* @__PURE__ */ jsx34(
2029
+ "div",
2030
+ {
2031
+ "data-slot": "card",
2032
+ className: cn("flex flex-col overflow-hidden border", RADIUS[radius], TONE[tone], className),
2033
+ ...rest,
2034
+ children
2035
+ }
2036
+ );
2037
+ }
2038
+ function CardHeader({
2039
+ children,
2040
+ size = "md",
2041
+ divider = true,
2042
+ className,
2043
+ ...rest
2044
+ }) {
2045
+ return /* @__PURE__ */ jsx34(
2046
+ "div",
2047
+ {
2048
+ "data-slot": "card-header",
2049
+ className: cn(
2050
+ "grid auto-rows-min items-center gap-x-3 gap-y-0.5",
2051
+ "has-[[data-slot=card-action]]:grid-cols-[1fr_auto]",
2052
+ BOX[size],
2053
+ divider && "border-b border-default",
2054
+ className
2055
+ ),
2056
+ ...rest,
2057
+ children
2058
+ }
2059
+ );
2060
+ }
2061
+ function CardTitle({ children, size = "md", as: Tag = "p", className, ...rest }) {
2062
+ return /* @__PURE__ */ jsx34(
2063
+ Tag,
2064
+ {
2065
+ "data-slot": "card-title",
2066
+ className: cn("min-w-0 font-semibold text-default", TITLE_SIZE[size], className),
2067
+ ...rest,
2068
+ children
2069
+ }
2070
+ );
2071
+ }
2072
+ function CardDescription({ children, className, ...rest }) {
2073
+ return /* @__PURE__ */ jsx34(
2074
+ "p",
2075
+ {
2076
+ "data-slot": "card-description",
2077
+ className: cn("min-w-0 text-body-tiny text-default-secondary", className),
2078
+ ...rest,
2079
+ children
2080
+ }
2081
+ );
2082
+ }
2083
+ function CardAction({ children, className, ...rest }) {
2084
+ return /* @__PURE__ */ jsx34(
2085
+ "div",
2086
+ {
2087
+ "data-slot": "card-action",
2088
+ className: cn("col-start-2 row-span-2 row-start-1 shrink-0 self-center justify-self-end", className),
2089
+ ...rest,
2090
+ children
2091
+ }
2092
+ );
2093
+ }
2094
+ function CardBody({ children, size = "md", className, ...rest }) {
2095
+ return /* @__PURE__ */ jsx34("div", { "data-slot": "card-body", className: cn("flex flex-col", BODY_BOX[size], className), ...rest, children });
2096
+ }
2097
+ function CardFooter({
2098
+ children,
2099
+ size = "md",
2100
+ divider = true,
2101
+ align = "end",
2102
+ className,
2103
+ ...rest
2104
+ }) {
2105
+ return /* @__PURE__ */ jsx34(
2106
+ "div",
2107
+ {
2108
+ "data-slot": "card-footer",
2109
+ className: cn(
2110
+ "flex items-center gap-2",
2111
+ BOX[size],
2112
+ FOOTER_ALIGN2[align],
2113
+ divider && "border-t border-default",
2114
+ className
2115
+ ),
2116
+ ...rest,
2117
+ children
2118
+ }
2119
+ );
2120
+ }
2121
+
2122
+ // src/components/chrome/page-heading.tsx
2123
+ import clsx31 from "clsx";
2124
+ import { jsx as jsx35, jsxs as jsxs26 } from "react/jsx-runtime";
2125
+ var TITLE = {
2126
+ page: "text-2xl font-semibold text-default",
2127
+ toolbar: "text-heading-sm font-semibold leading-snug text-default",
2128
+ section: "text-lg font-semibold text-default"
2129
+ };
2130
+ var SUBTITLE = {
2131
+ page: "mt-1 text-body-sm text-default-secondary",
2132
+ toolbar: "text-body-xs text-default-secondary",
2133
+ section: "mt-1 text-body-sm text-default-secondary"
2134
+ };
2135
+ function PageHeading({
2136
+ title,
2137
+ subtitle,
2138
+ size = "page",
2139
+ as,
2140
+ actions,
2141
+ truncateTitle,
2142
+ className
2143
+ }) {
2144
+ const Tag = as ?? (size === "section" ? "h2" : "h1");
2145
+ const heading = /* @__PURE__ */ jsxs26("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
2146
+ /* @__PURE__ */ jsx35(Tag, { className: clsx31(TITLE[size], truncateTitle && "truncate"), children: title }),
2147
+ subtitle && /* @__PURE__ */ jsx35("p", { className: SUBTITLE[size], children: subtitle })
2148
+ ] });
2149
+ if (!actions) return className ? /* @__PURE__ */ jsx35("div", { className, children: heading }) : heading;
2150
+ return /* @__PURE__ */ jsxs26("div", { className: clsx31("flex items-start justify-between gap-4", className), children: [
2151
+ heading,
2152
+ /* @__PURE__ */ jsx35("div", { className: "flex shrink-0 items-center gap-2", children: actions })
2153
+ ] });
2154
+ }
2155
+
2156
+ // src/components/chrome/page-toolbar.tsx
2157
+ import clsx32 from "clsx";
2158
+ import { jsx as jsx36 } from "react/jsx-runtime";
2159
+ var SIZE3 = {
2160
+ sm: "min-h-[56px] px-4 py-2.5 md:px-7",
2161
+ md: "min-h-[72px] px-4 py-4 md:px-7"
2162
+ };
2163
+ function PageToolbar({ children, wrap, size = "md", className }) {
2164
+ return /* @__PURE__ */ jsx36(
2165
+ "div",
2166
+ {
2167
+ className: clsx32(
2168
+ "flex shrink-0 items-center justify-between gap-4 border-b border-default bg-default",
2169
+ SIZE3[size],
2170
+ wrap && "flex-wrap gap-2",
2171
+ className
2172
+ ),
2173
+ children
2174
+ }
2175
+ );
2176
+ }
2177
+
2178
+ // src/components/chrome/filter-bar.tsx
2179
+ import clsx33 from "clsx";
2180
+ import { jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
2181
+ var GAP = {
2182
+ sm: "gap-2",
2183
+ md: "gap-3"
2184
+ };
2185
+ function FilterBar({ children, trailing, size = "md", className }) {
2186
+ return /* @__PURE__ */ jsxs27("div", { className: clsx33("flex flex-wrap items-center", GAP[size], className), children: [
2187
+ children,
2188
+ trailing && /* @__PURE__ */ jsx37("div", { className: "ml-auto flex items-center gap-2", children: trailing })
2189
+ ] });
2190
+ }
2191
+
2192
+ // src/components/chrome/tabs.tsx
2193
+ import clsx34 from "clsx";
2194
+ import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
2195
+ var SIZE4 = {
2196
+ underline: {
2197
+ sm: { strip: "gap-4", tab: "px-0.5 py-1.5 text-body-xs" },
2198
+ md: { strip: "gap-6", tab: "px-0.5 py-2.5 text-body-sm" }
2199
+ },
2200
+ pill: {
2201
+ sm: { strip: "gap-1", tab: "rounded-md px-2.5 py-1.5 text-body-tiny" },
2202
+ md: { strip: "gap-1.5", tab: "rounded-lg px-3.5 py-2 text-body-xs" }
2203
+ }
2204
+ };
2205
+ function Tabs({
2206
+ items,
2207
+ value,
2208
+ onChange,
2209
+ variant = "underline",
2210
+ size = "md",
2211
+ className
2212
+ }) {
2213
+ const isPill = variant === "pill";
2214
+ const s = SIZE4[variant][size];
2215
+ return /* @__PURE__ */ jsx38(
2216
+ "div",
2217
+ {
2218
+ role: "tablist",
2219
+ className: clsx34(
2220
+ "flex shrink-0 overflow-x-auto",
2221
+ s.strip,
2222
+ !isPill && "border-b border-default",
2223
+ className
2224
+ ),
2225
+ children: items.map((tab) => {
2226
+ const active = tab.key === value;
2227
+ return /* @__PURE__ */ jsxs28(
2228
+ "button",
2229
+ {
2230
+ type: "button",
2231
+ role: "tab",
2232
+ "aria-selected": active,
2233
+ onClick: () => onChange(tab.key),
2234
+ className: clsx34(
2235
+ "flex shrink-0 items-center gap-1.5 whitespace-nowrap transition-colors",
2236
+ s.tab,
2237
+ isPill ? clsx34(
2238
+ "font-medium",
2239
+ active ? "bg-brand text-brand-on-brand" : "text-default-secondary hover:bg-default-secondary"
2240
+ ) : clsx34(
2241
+ "leading-snug",
2242
+ active ? "border-b-2 border-brand-emphasis font-semibold text-brand-emphasis" : "font-normal text-default-secondary hover:text-default"
2243
+ )
2244
+ ),
2245
+ children: [
2246
+ tab.label,
2247
+ tab.count !== void 0 && /* @__PURE__ */ jsx38(
2248
+ "span",
2249
+ {
2250
+ className: clsx34(
2251
+ "rounded-md px-1.5 py-px text-body-tiny font-medium leading-snug",
2252
+ active && isPill ? "bg-brand-hover text-brand-on-brand" : "bg-default-secondary text-default-secondary"
2253
+ ),
2254
+ children: tab.count
2255
+ }
2256
+ )
2257
+ ]
2258
+ },
2259
+ tab.key
2260
+ );
2261
+ })
2262
+ }
2263
+ );
2264
+ }
2265
+
2266
+ // src/components/chrome/nav-item.tsx
2267
+ import clsx35 from "clsx";
2268
+ import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
2269
+ var SIZE5 = {
2270
+ sm: { box: "h-9 gap-2 rounded-lg px-2.5 py-1.5", label: "text-body-xs" },
2271
+ md: { box: "h-11 gap-3 rounded-xl px-3.5 py-2.5", label: "text-body-sm" }
2272
+ };
2273
+ function NavItem({
2274
+ icon,
2275
+ label,
2276
+ isActive = false,
2277
+ indicator = false,
2278
+ collapsed = false,
2279
+ size = "md",
2280
+ className
2281
+ }) {
2282
+ const s = SIZE5[size];
2283
+ return /* @__PURE__ */ jsxs29(
2284
+ "span",
2285
+ {
2286
+ className: clsx35(
2287
+ "relative flex w-full items-center transition-colors",
2288
+ s.box,
2289
+ collapsed && "justify-center",
2290
+ isActive ? "bg-brand text-brand-on-brand" : [
2291
+ "border border-default bg-default text-default-secondary",
2292
+ "hover:bg-brand-tertiary-hover hover:border-brand-tertiary hover:text-brand"
2293
+ ],
2294
+ className
2295
+ ),
2296
+ children: [
2297
+ icon !== void 0 && /* @__PURE__ */ jsx39("span", { className: "shrink-0 [&_svg]:size-4", children: icon }),
2298
+ !collapsed && /* @__PURE__ */ jsx39("span", { className: clsx35("min-w-0 flex-1 truncate font-regular leading-snug", s.label), children: label }),
2299
+ indicator && /* @__PURE__ */ jsx39("span", { className: "absolute -right-px -top-px size-2 rounded-full bg-danger" })
2300
+ ]
2301
+ }
2302
+ );
2303
+ }
2304
+
2305
+ // src/components/chrome/eyebrow-label.tsx
2306
+ import clsx36 from "clsx";
2307
+ import { jsx as jsx40 } from "react/jsx-runtime";
2308
+ function EyebrowLabel({ children, variant = "uppercase", className }) {
2309
+ return /* @__PURE__ */ jsx40(
2310
+ "p",
2311
+ {
2312
+ className: clsx36(
2313
+ "text-body-tiny font-semibold tracking-wide text-default-secondary",
2314
+ variant === "uppercase" && "uppercase",
2315
+ className
2316
+ ),
2317
+ children
2318
+ }
2319
+ );
2320
+ }
2321
+
2322
+ // src/components/widgets/widget-header.tsx
2323
+ import clsx38 from "clsx";
2324
+
2325
+ // src/components/widgets/widget-title.tsx
2326
+ import clsx37 from "clsx";
2327
+ import { jsx as jsx41 } from "react/jsx-runtime";
2328
+ var sizeStyles5 = {
2329
+ sm: "text-subheading-sm font-semibold leading-none",
2330
+ md: "text-[18px] font-bold leading-normal",
2331
+ lg: "text-subheading font-semibold leading-[1.2]"
2332
+ };
2333
+ function WidgetTitle({ children, size = "sm", className }) {
2334
+ return /* @__PURE__ */ jsx41("h3", { className: clsx37(sizeStyles5[size], "text-default", className), children });
2335
+ }
2336
+
2337
+ // src/components/widgets/widget-header.tsx
2338
+ import { jsx as jsx42, jsxs as jsxs30 } from "react/jsx-runtime";
2339
+ var eyebrowStyles = {
2340
+ uppercase: "text-body-tiny font-medium uppercase tracking-[0.66px] text-default-secondary",
2341
+ plain: "text-body-xs leading-[1.4] text-default-secondary"
2342
+ };
2343
+ function WidgetHeader({
2344
+ eyebrow,
2345
+ eyebrowVariant = "uppercase",
2346
+ title,
2347
+ titleSize,
2348
+ subtitle,
2349
+ badge,
2350
+ action,
2351
+ className
2352
+ }) {
2353
+ return /* @__PURE__ */ jsxs30("div", { className: clsx38("flex items-start justify-between gap-2", className), children: [
2354
+ /* @__PURE__ */ jsxs30("div", { className: "min-w-0 flex-1", children: [
2355
+ eyebrow && /* @__PURE__ */ jsx42("p", { className: eyebrowStyles[eyebrowVariant], children: eyebrow }),
2356
+ /* @__PURE__ */ jsx42(WidgetTitle, { size: titleSize, children: title }),
2357
+ subtitle && /* @__PURE__ */ jsx42("p", { className: "mt-1 text-body-xs text-default-secondary leading-snug", children: subtitle })
2358
+ ] }),
2359
+ /* @__PURE__ */ jsxs30("div", { className: "flex shrink-0 items-center gap-2", children: [
2360
+ badge,
2361
+ action
2362
+ ] })
2363
+ ] });
2364
+ }
2365
+
2366
+ // src/components/widgets/widget-footer.tsx
2367
+ import clsx39 from "clsx";
2368
+ import { jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
2369
+ function WidgetFooter({ caption, subcaption, action, className }) {
2370
+ return /* @__PURE__ */ jsxs31("div", { className: clsx39("flex items-center gap-3", className), children: [
2371
+ caption && /* @__PURE__ */ jsxs31("div", { className: "flex items-stretch gap-3 flex-1 min-w-0", children: [
2372
+ /* @__PURE__ */ jsx43("div", { className: "w-0.5 shrink-0 self-stretch rounded-full bg-brand" }),
2373
+ /* @__PURE__ */ jsxs31("div", { className: "min-w-0", children: [
2374
+ /* @__PURE__ */ jsx43("p", { className: "text-body-sm font-medium text-default leading-snug", children: caption }),
2375
+ subcaption && /* @__PURE__ */ jsx43("p", { className: "mt-0.5 text-body-xs text-default-secondary", children: subcaption })
2376
+ ] })
2377
+ ] }),
2378
+ action && /* @__PURE__ */ jsx43("div", { className: "ml-auto shrink-0", children: action })
2379
+ ] });
2380
+ }
2381
+
2382
+ // src/components/stats/stat-tile.tsx
2383
+ import clsx40 from "clsx";
2384
+ import { jsx as jsx44, jsxs as jsxs32 } from "react/jsx-runtime";
2385
+ var DOT_TONE = {
2386
+ neutral: "bg-status-dot-neutral",
2387
+ info: "bg-status-dot-info",
2388
+ warning: "bg-status-dot-warning",
2389
+ caution: "bg-status-dot-caution",
2390
+ accent: "bg-status-dot-accent",
2391
+ positive: "bg-status-dot-positive",
2392
+ danger: "bg-status-dot-danger"
2393
+ };
2394
+ function StatTile({ label, value, tone, dotColor, className }) {
2395
+ const showDot = Boolean(tone || dotColor);
2396
+ return /* @__PURE__ */ jsxs32(
2397
+ "div",
2398
+ {
2399
+ className: clsx40(
2400
+ "flex flex-col gap-2 rounded-xl border border-default bg-default p-4",
2401
+ className
2402
+ ),
2403
+ children: [
2404
+ /* @__PURE__ */ jsxs32("div", { className: "flex items-center gap-1.5", children: [
2405
+ showDot && /* @__PURE__ */ jsx44(
2406
+ "span",
2407
+ {
2408
+ className: clsx40("size-2 shrink-0 rounded-full", tone && DOT_TONE[tone]),
2409
+ style: tone ? void 0 : { backgroundColor: dotColor }
2410
+ }
2411
+ ),
2412
+ /* @__PURE__ */ jsx44("span", { className: "text-body-xs font-medium text-default-secondary whitespace-nowrap", children: label })
2413
+ ] }),
2414
+ /* @__PURE__ */ jsx44("span", { className: "text-heading font-semibold text-default leading-none", children: value })
2415
+ ]
2416
+ }
2417
+ );
2418
+ }
2419
+
2420
+ // src/components/stats/stat-number.tsx
2421
+ import clsx41 from "clsx";
2422
+ import { jsx as jsx45, jsxs as jsxs33 } from "react/jsx-runtime";
2423
+ var sizeStyles6 = {
2424
+ sm: "text-subtitle",
2425
+ md: "text-subtitle-lg",
2426
+ lg: "text-title"
2427
+ };
2428
+ var weightStyles = {
2429
+ medium: "font-medium",
2430
+ bold: "font-bold"
2431
+ };
2432
+ function StatNumber({ value, unit, size = "md", weight = "bold", color, className }) {
2433
+ return /* @__PURE__ */ jsxs33(
2434
+ "p",
2435
+ {
2436
+ className: clsx41(sizeStyles6[size], weightStyles[weight], "leading-none", !color && "text-default", className),
2437
+ style: color ? { color } : void 0,
2438
+ children: [
2439
+ value,
2440
+ unit && /* @__PURE__ */ jsx45("span", { className: "ml-1 text-subheading font-medium text-default-secondary", children: unit })
2441
+ ]
2442
+ }
2443
+ );
2444
+ }
2445
+
2446
+ // src/components/stats/score-value.tsx
2447
+ import clsx42 from "clsx";
2448
+ import { jsx as jsx46, jsxs as jsxs34 } from "react/jsx-runtime";
2449
+ var DEFAULT_SCORE_THRESHOLDS = { danger: 80, warning: 65, neutral: 50 };
2450
+ function getScoreTone(score, {
2451
+ direction = "higher-is-worse",
2452
+ thresholds = DEFAULT_SCORE_THRESHOLDS
2453
+ } = {}) {
2454
+ const v = direction === "higher-is-better" ? 100 - score : score;
2455
+ if (v >= thresholds.danger) return "danger";
2456
+ if (v >= thresholds.warning) return "warning";
2457
+ if (v >= thresholds.neutral) return "neutral";
2458
+ return "positive";
2459
+ }
2460
+ var SIZE6 = {
2461
+ sm: "text-body-xs",
2462
+ md: "text-body-sm",
2463
+ lg: "text-subheading-sm",
2464
+ xl: "text-subheading",
2465
+ "2xl": "text-subtitle"
2466
+ };
2467
+ var WEIGHT = {
2468
+ normal: "font-normal",
2469
+ semibold: "font-semibold",
2470
+ bold: "font-bold"
2471
+ };
2472
+ var TONE2 = {
2473
+ brand: "text-brand",
2474
+ positive: "text-positive",
2475
+ warning: "text-warning",
2476
+ danger: "text-danger",
2477
+ neutral: "text-default-secondary",
2478
+ default: "text-default"
2479
+ };
2480
+ function ScoreValue({
2481
+ value,
2482
+ label,
2483
+ size = "md",
2484
+ weight = "bold",
2485
+ tone = "auto",
2486
+ direction = "higher-is-worse",
2487
+ thresholds = DEFAULT_SCORE_THRESHOLDS,
2488
+ className
2489
+ }) {
2490
+ const numeric = typeof value === "number" ? value : Number(value);
2491
+ const resolved = tone === "auto" ? Number.isFinite(numeric) ? getScoreTone(numeric, { direction, thresholds }) : "default" : tone;
2492
+ return /* @__PURE__ */ jsxs34("span", { className: clsx42("inline-flex items-baseline gap-1", className), children: [
2493
+ /* @__PURE__ */ jsx46("span", { className: clsx42(SIZE6[size], WEIGHT[weight], TONE2[resolved]), children: value }),
2494
+ label && /* @__PURE__ */ jsx46("span", { className: "text-body-xs text-default-secondary whitespace-nowrap", children: label })
2495
+ ] });
2496
+ }
2497
+
2498
+ // src/components/stats/tile-grid.tsx
2499
+ import clsx43 from "clsx";
2500
+ import { jsx as jsx47 } from "react/jsx-runtime";
2501
+ var COLUMNS = {
2502
+ sm: {
2503
+ 2: "grid-cols-2",
2504
+ 3: "grid-cols-2 sm:grid-cols-3",
2505
+ 4: "grid-cols-2 sm:grid-cols-4",
2506
+ 5: "grid-cols-2 sm:grid-cols-5",
2507
+ 6: "grid-cols-2 sm:grid-cols-6"
2508
+ },
2509
+ md: {
2510
+ 2: "grid-cols-2",
2511
+ 3: "grid-cols-2 md:grid-cols-3",
2512
+ 4: "grid-cols-2 md:grid-cols-4",
2513
+ 5: "grid-cols-2 md:grid-cols-5",
2514
+ 6: "grid-cols-2 sm:grid-cols-3 md:grid-cols-6"
2515
+ },
2516
+ lg: {
2517
+ 2: "grid-cols-2",
2518
+ 3: "grid-cols-2 lg:grid-cols-3",
2519
+ 4: "grid-cols-2 lg:grid-cols-4",
2520
+ 5: "grid-cols-2 lg:grid-cols-5",
2521
+ 6: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6"
2522
+ }
2523
+ };
2524
+ function TileGrid({
2525
+ children,
2526
+ columns = 4,
2527
+ at = "lg",
2528
+ className
2529
+ }) {
2530
+ return /* @__PURE__ */ jsx47("div", { className: clsx43("grid gap-3", COLUMNS[at][columns], className), children });
2531
+ }
2532
+
2533
+ // src/components/charts/chart-tone.ts
2534
+ var CHART_TONE = {
2535
+ brand: "var(--color-background-brand-default)",
2536
+ info: "var(--status-info-dot)",
2537
+ positive: "var(--color-background-positive-default)",
2538
+ warning: "var(--color-background-warning-default)",
2539
+ danger: "var(--color-background-danger-default)",
2540
+ neutral: "var(--color-background-neutral-default)"
2541
+ };
2542
+ var CHART_TRACK = "var(--color-background-default-tertiary)";
2543
+ var CHART_SEQUENCE = ["brand", "info", "positive", "warning", "danger", "neutral"];
2544
+ function resolveChartColor(color, tone, index = 0) {
2545
+ if (color) return color;
2546
+ if (tone) return CHART_TONE[tone];
2547
+ return CHART_TONE[CHART_SEQUENCE[index % CHART_SEQUENCE.length]];
2548
+ }
2549
+
2550
+ // src/components/charts/bar-chart.tsx
2551
+ import clsx44 from "clsx";
2552
+ import { jsx as jsx48, jsxs as jsxs35 } from "react/jsx-runtime";
2553
+ var SIZE7 = {
2554
+ sm: { band: 14, gap: 6, label: "text-body-tiny" },
2555
+ md: { band: 20, gap: 8, label: "text-body-xs" },
2556
+ lg: { band: 28, gap: 10, label: "text-body-xs" }
2557
+ };
2558
+ function BarChart({
2559
+ categories,
2560
+ series,
2561
+ orientation = "horizontal",
2562
+ stacked = false,
2563
+ size = "md",
2564
+ length = 240,
2565
+ showLabels = true,
2566
+ showValues = false,
2567
+ radius = 3,
2568
+ label,
2569
+ className
2570
+ }) {
2571
+ const { band, gap, label: labelClass2 } = SIZE7[size];
2572
+ if (categories.length === 0 || series.length === 0) return null;
2573
+ const perCategory = stacked ? band : band * series.length + gap * (series.length - 1);
2574
+ const categoryTotals = categories.map(
2575
+ (_, ci) => stacked ? series.reduce((sum, s) => sum + Math.max(0, s.values[ci] ?? 0), 0) : Math.max(...series.map((s) => Math.max(0, s.values[ci] ?? 0)))
2576
+ );
2577
+ const max = Math.max(...categoryTotals, 1);
2578
+ const horizontal = orientation === "horizontal";
2579
+ return /* @__PURE__ */ jsx48(
2580
+ "div",
2581
+ {
2582
+ className: clsx44("flex w-full min-w-0", horizontal ? "flex-col gap-2" : "flex-row items-end gap-3", className),
2583
+ role: label ? "img" : void 0,
2584
+ "aria-label": label,
2585
+ children: categories.map((category, ci) => {
2586
+ const bars = series.map((s, si) => ({
2587
+ key: s.label,
2588
+ value: Math.max(0, s.values[ci] ?? 0),
2589
+ color: resolveChartColor(s.color, s.tone, si)
2590
+ }));
2591
+ return /* @__PURE__ */ jsxs35(
2592
+ "div",
2593
+ {
2594
+ className: clsx44("flex min-w-0", horizontal ? "flex-col gap-1" : "h-full flex-col justify-end gap-1.5"),
2595
+ style: horizontal ? void 0 : { width: perCategory },
2596
+ children: [
2597
+ showLabels && horizontal && /* @__PURE__ */ jsx48("span", { className: clsx44("truncate text-default-secondary", labelClass2), children: category }),
2598
+ /* @__PURE__ */ jsxs35(
2599
+ "div",
2600
+ {
2601
+ className: clsx44("flex", horizontal ? "items-center gap-2" : "w-full flex-1 items-end justify-center"),
2602
+ style: horizontal ? void 0 : { height: length },
2603
+ children: [
2604
+ /* @__PURE__ */ jsx48(
2605
+ "div",
2606
+ {
2607
+ className: clsx44("flex min-w-0", stacked ? "gap-0" : ""),
2608
+ style: horizontal ? { width: length, flexDirection: stacked ? "row" : "column", gap: stacked ? 0 : gap } : {
2609
+ height: "100%",
2610
+ width: perCategory,
2611
+ flexDirection: stacked ? "column-reverse" : "row",
2612
+ alignItems: "flex-end",
2613
+ gap: stacked ? 0 : gap
2614
+ },
2615
+ children: bars.map((bar) => {
2616
+ const extent = `${bar.value / max * 100}%`;
2617
+ return /* @__PURE__ */ jsx48(
2618
+ "div",
2619
+ {
2620
+ title: `${category} \xB7 ${bar.key}: ${bar.value}`,
2621
+ className: "transition-all",
2622
+ style: {
2623
+ backgroundColor: bar.color,
2624
+ borderRadius: radius,
2625
+ ...horizontal ? { width: extent, height: stacked ? band : band } : { height: extent, width: stacked ? perCategory : band }
2626
+ }
2627
+ },
2628
+ bar.key
2629
+ );
2630
+ })
2631
+ }
2632
+ ),
2633
+ showValues && horizontal && /* @__PURE__ */ jsx48("span", { className: clsx44("shrink-0 tabular-nums text-default-secondary", labelClass2), children: categoryTotals[ci] })
2634
+ ]
2635
+ }
2636
+ ),
2637
+ showLabels && !horizontal && /* @__PURE__ */ jsx48("span", { className: clsx44("truncate text-center text-default-secondary", labelClass2), children: category })
2638
+ ]
2639
+ },
2640
+ category
2641
+ );
2642
+ })
2643
+ }
2644
+ );
2645
+ }
2646
+
2647
+ // src/components/charts/donut-chart.tsx
2648
+ import clsx45 from "clsx";
2649
+ import { jsx as jsx49, jsxs as jsxs36 } from "react/jsx-runtime";
2650
+ var SIZE8 = {
2651
+ sm: { box: 88, thickness: 10 },
2652
+ md: { box: 128, thickness: 14 },
2653
+ lg: { box: 180, thickness: 20 }
2654
+ };
2655
+ function DonutChart({
2656
+ segments,
2657
+ size = "md",
2658
+ thickness,
2659
+ centerValue,
2660
+ centerLabel,
2661
+ gap = 2,
2662
+ label,
2663
+ className
2664
+ }) {
2665
+ const { box, thickness: presetThickness } = SIZE8[size];
2666
+ const ring = thickness ?? presetThickness;
2667
+ const radius = (box - ring) / 2;
2668
+ const circumference = 2 * Math.PI * radius;
2669
+ const total = segments.reduce((sum, s) => sum + Math.max(0, s.value), 0);
2670
+ const visible = segments.filter((s) => s.value > 0);
2671
+ const gapLength = visible.length > 1 ? gap / 360 * circumference : 0;
2672
+ let offset = 0;
2673
+ return /* @__PURE__ */ jsxs36("div", { className: clsx45("relative inline-flex shrink-0 items-center justify-center", className), children: [
2674
+ /* @__PURE__ */ jsxs36(
2675
+ "svg",
2676
+ {
2677
+ width: box,
2678
+ height: box,
2679
+ viewBox: `0 0 ${box} ${box}`,
2680
+ role: label ? "img" : void 0,
2681
+ "aria-label": label,
2682
+ "aria-hidden": label ? void 0 : true,
2683
+ className: "block -rotate-90",
2684
+ children: [
2685
+ /* @__PURE__ */ jsx49("circle", { cx: box / 2, cy: box / 2, r: radius, fill: "none", stroke: CHART_TRACK, strokeWidth: ring }),
2686
+ total > 0 && segments.map((segment, i) => {
2687
+ const fraction = Math.max(0, segment.value) / total;
2688
+ const length = Math.max(0, fraction * circumference - gapLength);
2689
+ const dash = `${length} ${circumference - length}`;
2690
+ const thisOffset = offset;
2691
+ offset += fraction * circumference;
2692
+ if (segment.value <= 0) return null;
2693
+ return /* @__PURE__ */ jsx49(
2694
+ "circle",
2695
+ {
2696
+ cx: box / 2,
2697
+ cy: box / 2,
2698
+ r: radius,
2699
+ fill: "none",
2700
+ stroke: resolveChartColor(segment.color, segment.tone, i),
2701
+ strokeWidth: ring,
2702
+ strokeDasharray: dash,
2703
+ strokeDashoffset: -thisOffset,
2704
+ strokeLinecap: "butt"
2705
+ },
2706
+ segment.label
2707
+ );
2708
+ })
2709
+ ]
2710
+ }
2711
+ ),
2712
+ (centerValue != null || centerLabel != null) && /* @__PURE__ */ jsxs36("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-center", children: [
2713
+ centerValue != null && /* @__PURE__ */ jsx49("span", { className: "text-subheading-sm font-bold leading-none text-default", children: centerValue }),
2714
+ centerLabel != null && /* @__PURE__ */ jsx49("span", { className: "mt-0.5 text-body-tiny text-default-secondary", children: centerLabel })
2715
+ ] })
2716
+ ] });
2717
+ }
2718
+
2719
+ // src/components/charts/radial-gauge.tsx
2720
+ import clsx46 from "clsx";
2721
+ import { jsx as jsx50, jsxs as jsxs37 } from "react/jsx-runtime";
2722
+ var SIZE9 = {
2723
+ sm: { box: 72, thickness: 8, value: "text-body-sm" },
2724
+ md: { box: 104, thickness: 11, value: "text-subheading-sm" },
2725
+ lg: { box: 148, thickness: 15, value: "text-subheading" }
2726
+ };
2727
+ function RadialGauge({
2728
+ value,
2729
+ max = 100,
2730
+ size = "md",
2731
+ tone = "brand",
2732
+ color,
2733
+ thickness,
2734
+ sweep = 270,
2735
+ children,
2736
+ centerLabel,
2737
+ label,
2738
+ className
2739
+ }) {
2740
+ const preset = SIZE9[size];
2741
+ const box = preset.box;
2742
+ const ring = thickness ?? preset.thickness;
2743
+ const radius = (box - ring) / 2;
2744
+ const circumference = 2 * Math.PI * radius;
2745
+ const clampedSweep = Math.min(360, Math.max(1, sweep));
2746
+ const arc = clampedSweep / 360 * circumference;
2747
+ const fraction = max > 0 ? Math.min(1, Math.max(0, value / max)) : 0;
2748
+ const stroke = resolveChartColor(color, tone);
2749
+ const rotation = -90 + (360 - clampedSweep) / 2;
2750
+ return /* @__PURE__ */ jsxs37("div", { className: clsx46("relative inline-flex shrink-0 items-center justify-center", className), children: [
2751
+ /* @__PURE__ */ jsxs37(
2752
+ "svg",
2753
+ {
2754
+ width: box,
2755
+ height: box,
2756
+ viewBox: `0 0 ${box} ${box}`,
2757
+ role: label ? "img" : void 0,
2758
+ "aria-label": label,
2759
+ "aria-hidden": label ? void 0 : true,
2760
+ className: "block",
2761
+ style: { transform: `rotate(${rotation}deg)` },
2762
+ children: [
2763
+ /* @__PURE__ */ jsx50(
2764
+ "circle",
2765
+ {
2766
+ cx: box / 2,
2767
+ cy: box / 2,
2768
+ r: radius,
2769
+ fill: "none",
2770
+ stroke: CHART_TRACK,
2771
+ strokeWidth: ring,
2772
+ strokeDasharray: `${arc} ${circumference - arc}`,
2773
+ strokeLinecap: "round"
2774
+ }
2775
+ ),
2776
+ /* @__PURE__ */ jsx50(
2777
+ "circle",
2778
+ {
2779
+ cx: box / 2,
2780
+ cy: box / 2,
2781
+ r: radius,
2782
+ fill: "none",
2783
+ stroke,
2784
+ strokeWidth: ring,
2785
+ strokeDasharray: `${arc * fraction} ${circumference - arc * fraction}`,
2786
+ strokeLinecap: "round",
2787
+ className: "transition-all"
2788
+ }
2789
+ )
2790
+ ]
2791
+ }
2792
+ ),
2793
+ /* @__PURE__ */ jsxs37("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-center", children: [
2794
+ children === void 0 ? /* @__PURE__ */ jsx50("span", { className: clsx46("font-bold leading-none text-default", preset.value), children: value }) : children,
2795
+ centerLabel != null && /* @__PURE__ */ jsx50("span", { className: "mt-0.5 text-body-tiny text-default-secondary", children: centerLabel })
2796
+ ] })
2797
+ ] });
2798
+ }
2799
+
2800
+ // src/components/charts/sparkline.tsx
2801
+ import { useId } from "react";
2802
+ import clsx47 from "clsx";
2803
+ import { Fragment as Fragment3, jsx as jsx51, jsxs as jsxs38 } from "react/jsx-runtime";
2804
+ var SIZE10 = {
2805
+ sm: { width: 80, height: 24 },
2806
+ md: { width: 120, height: 36 },
2807
+ lg: { width: 200, height: 56 }
2808
+ };
2809
+ function Sparkline({
2810
+ data,
2811
+ variant = "line",
2812
+ tone = "brand",
2813
+ color,
2814
+ size = "md",
2815
+ width,
2816
+ height,
2817
+ strokeWidth = 1.5,
2818
+ showEndDot = false,
2819
+ label,
2820
+ className
2821
+ }) {
2822
+ const gradientId = useId();
2823
+ if (data.length < 2) return null;
2824
+ const w = width ?? SIZE10[size].width;
2825
+ const h = height ?? SIZE10[size].height;
2826
+ const stroke = resolveChartColor(color, tone);
2827
+ const min = Math.min(...data);
2828
+ const max = Math.max(...data);
2829
+ const range = max - min || 1;
2830
+ const pad = strokeWidth;
2831
+ const innerH = h - pad * 2;
2832
+ const innerW = w - pad * 2;
2833
+ const coords = data.map((v, i) => ({
2834
+ x: pad + i / (data.length - 1) * innerW,
2835
+ y: pad + innerH - (v - min) / range * innerH
2836
+ }));
2837
+ const points = coords.map((p) => `${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(" ");
2838
+ const areaPath = `M ${points.split(" ").join(" L ")} L ${coords[coords.length - 1].x.toFixed(2)},${h} L ${coords[0].x.toFixed(2)},${h} Z`;
2839
+ const last = coords[coords.length - 1];
2840
+ return /* @__PURE__ */ jsxs38(
2841
+ "svg",
2842
+ {
2843
+ width: w,
2844
+ height: h,
2845
+ viewBox: `0 0 ${w} ${h}`,
2846
+ fill: "none",
2847
+ role: label ? "img" : void 0,
2848
+ "aria-label": label,
2849
+ "aria-hidden": label ? void 0 : true,
2850
+ className: clsx47("block shrink-0", className),
2851
+ children: [
2852
+ variant === "area" && /* @__PURE__ */ jsxs38(Fragment3, { children: [
2853
+ /* @__PURE__ */ jsx51("defs", { children: /* @__PURE__ */ jsxs38("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2854
+ /* @__PURE__ */ jsx51("stop", { offset: "0%", stopColor: stroke, stopOpacity: 0.24 }),
2855
+ /* @__PURE__ */ jsx51("stop", { offset: "100%", stopColor: stroke, stopOpacity: 0 })
2856
+ ] }) }),
2857
+ /* @__PURE__ */ jsx51("path", { d: areaPath, fill: `url(#${gradientId})` })
2858
+ ] }),
2859
+ /* @__PURE__ */ jsx51(
2860
+ "polyline",
2861
+ {
2862
+ points,
2863
+ stroke,
2864
+ strokeWidth,
2865
+ strokeLinecap: "round",
2866
+ strokeLinejoin: "round",
2867
+ fill: "none"
2868
+ }
2869
+ ),
2870
+ showEndDot && /* @__PURE__ */ jsx51("circle", { cx: last.x, cy: last.y, r: strokeWidth * 1.6, fill: stroke, stroke: CHART_TONE.neutral, strokeWidth: 0 })
2871
+ ]
2872
+ }
2873
+ );
2874
+ }
2875
+
2876
+ // src/components/charts/mini-bar-chart.tsx
2877
+ import clsx48 from "clsx";
2878
+ import { jsx as jsx52 } from "react/jsx-runtime";
2879
+ var SIZE11 = {
2880
+ sm: { width: 80, height: 32, gap: 2 },
2881
+ md: { width: 120, height: 48, gap: 3 },
2882
+ lg: { width: 200, height: 72, gap: 4 }
2883
+ };
2884
+ function MiniBarChart({
2885
+ bars,
2886
+ tone = "brand",
2887
+ color,
2888
+ restColor = CHART_TRACK,
2889
+ highlight = -1,
2890
+ size = "md",
2891
+ width,
2892
+ height,
2893
+ gap,
2894
+ orientation = "vertical",
2895
+ radius = 2,
2896
+ label,
2897
+ className
2898
+ }) {
2899
+ if (bars.length === 0) return null;
2900
+ const preset = SIZE11[size];
2901
+ const w = width ?? preset.width;
2902
+ const h = height ?? preset.height;
2903
+ const g = gap ?? preset.gap;
2904
+ const fill = resolveChartColor(color, tone);
2905
+ const highlighted = new Set(
2906
+ (Array.isArray(highlight) ? highlight : [highlight]).map((i) => i < 0 ? bars.length + i : i)
2907
+ );
2908
+ const max = Math.max(...bars) || 1;
2909
+ const vertical = orientation === "vertical";
2910
+ const span = vertical ? w : h;
2911
+ const extent = vertical ? h : w;
2912
+ const barThickness = (span - g * (bars.length - 1)) / bars.length;
2913
+ return /* @__PURE__ */ jsx52(
2914
+ "svg",
2915
+ {
2916
+ width: w,
2917
+ height: h,
2918
+ viewBox: `0 0 ${w} ${h}`,
2919
+ fill: "none",
2920
+ role: label ? "img" : void 0,
2921
+ "aria-label": label,
2922
+ "aria-hidden": label ? void 0 : true,
2923
+ className: clsx48("block shrink-0", className),
2924
+ children: bars.map((v, i) => {
2925
+ const magnitude = Math.max(2, v / max * extent);
2926
+ const offset = i * (barThickness + g);
2927
+ return /* @__PURE__ */ jsx52(
2928
+ "rect",
2929
+ {
2930
+ x: (vertical ? offset : 0).toFixed(2),
2931
+ y: (vertical ? extent - magnitude : offset).toFixed(2),
2932
+ width: (vertical ? barThickness : magnitude).toFixed(2),
2933
+ height: (vertical ? magnitude : barThickness).toFixed(2),
2934
+ fill: highlighted.has(i) ? fill : restColor,
2935
+ rx: radius
2936
+ },
2937
+ i
2938
+ );
2939
+ })
2940
+ }
2941
+ );
2942
+ }
2943
+
2944
+ // src/components/charts/chart-legend.tsx
2945
+ import clsx50 from "clsx";
2946
+
2947
+ // src/components/charts/legend-dot.tsx
2948
+ import clsx49 from "clsx";
2949
+ import { jsx as jsx53 } from "react/jsx-runtime";
2950
+ var SHAPE = {
2951
+ dot: { sm: "size-1.5 rounded-full", md: "size-2 rounded-full" },
2952
+ square: { sm: "size-1.5 rounded-[2px]", md: "size-2 rounded-[3px]" },
2953
+ line: { sm: "h-0.5 w-3 rounded-full", md: "h-0.5 w-4 rounded-full" }
2954
+ };
2955
+ function LegendDot({ tone, color, size = "md", shape = "dot", className }) {
2956
+ return /* @__PURE__ */ jsx53(
2957
+ "span",
2958
+ {
2959
+ className: clsx49("inline-block shrink-0", SHAPE[shape][size], className),
2960
+ style: { backgroundColor: resolveChartColor(color, tone) },
2961
+ "aria-hidden": true
2962
+ }
2963
+ );
2964
+ }
2965
+
2966
+ // src/components/charts/chart-legend.tsx
2967
+ import { jsx as jsx54, jsxs as jsxs39 } from "react/jsx-runtime";
2968
+ function ChartLegend({
2969
+ items,
2970
+ orientation = "vertical",
2971
+ size = "md",
2972
+ shape = "dot",
2973
+ className
2974
+ }) {
2975
+ const horizontal = orientation === "horizontal";
2976
+ return /* @__PURE__ */ jsx54(
2977
+ "div",
2978
+ {
2979
+ className: clsx50(
2980
+ horizontal ? "flex flex-wrap items-center gap-x-4 gap-y-2" : "flex flex-col gap-3",
2981
+ className
2982
+ ),
2983
+ children: items.map((item, i) => /* @__PURE__ */ jsxs39(
2984
+ "div",
2985
+ {
2986
+ className: clsx50("flex items-center gap-2", horizontal ? "min-w-0" : "justify-between"),
2987
+ children: [
2988
+ /* @__PURE__ */ jsxs39("div", { className: "flex min-w-0 items-center gap-2", children: [
2989
+ /* @__PURE__ */ jsx54(LegendDot, { color: resolveChartColor(item.color, item.tone, i), size, shape }),
2990
+ /* @__PURE__ */ jsx54("span", { className: "truncate text-body-xs text-default-secondary", children: item.label })
2991
+ ] }),
2992
+ item.count != null && /* @__PURE__ */ jsx54("span", { className: "shrink-0 text-body-xs font-semibold tabular-nums text-default", children: item.count })
2993
+ ]
2994
+ },
2995
+ item.label
2996
+ ))
2997
+ }
2998
+ );
2999
+ }
3000
+
3001
+ // src/components/charts/trend-label.tsx
3002
+ import clsx51 from "clsx";
3003
+ import { LuTrendingDown, LuTrendingUp } from "react-icons/lu";
3004
+ import { jsx as jsx55, jsxs as jsxs40 } from "react/jsx-runtime";
3005
+ var SIZE12 = {
3006
+ sm: "text-body-xs",
3007
+ md: "text-body-sm",
3008
+ lg: "text-subheading-sm"
3009
+ };
3010
+ var ICON_SIZE = {
3011
+ sm: "size-3",
3012
+ md: "size-3.5",
3013
+ lg: "size-4"
3014
+ };
3015
+ var weightBySize = {
3016
+ sm: "semibold",
3017
+ md: "semibold",
3018
+ lg: "bold"
3019
+ };
3020
+ var WEIGHT2 = {
3021
+ semibold: "font-semibold",
3022
+ bold: "font-bold"
3023
+ };
3024
+ function TrendLabel({
3025
+ value,
3026
+ suffix = "%",
3027
+ size = "md",
3028
+ weight,
3029
+ direction = "up-is-good",
3030
+ showArrow = true,
3031
+ color,
3032
+ className
3033
+ }) {
3034
+ const rising = value > 0;
3035
+ const flat = value === 0;
3036
+ const good = direction === "up-is-good" ? rising : !rising;
3037
+ const Arrow = rising ? LuTrendingUp : LuTrendingDown;
3038
+ return /* @__PURE__ */ jsxs40(
3039
+ "span",
3040
+ {
3041
+ className: clsx51(
3042
+ "inline-flex items-center gap-1 whitespace-nowrap",
3043
+ SIZE12[size],
3044
+ WEIGHT2[weight ?? weightBySize[size]],
3045
+ !color && (flat ? "text-default-secondary" : good ? "text-positive" : "text-danger"),
3046
+ className
3047
+ ),
3048
+ style: color ? { color } : void 0,
3049
+ children: [
3050
+ showArrow && !flat && /* @__PURE__ */ jsx55(Arrow, { className: clsx51("shrink-0", ICON_SIZE[size]), "aria-hidden": true }),
3051
+ rising ? "+" : "",
3052
+ value,
3053
+ suffix
3054
+ ]
3055
+ }
3056
+ );
3057
+ }
3058
+
3059
+ // src/components/lists/list-row.tsx
3060
+ import clsx52 from "clsx";
3061
+ import { jsx as jsx56, jsxs as jsxs41 } from "react/jsx-runtime";
3062
+ var DENSITY = {
3063
+ default: {
3064
+ pad: "py-4",
3065
+ gap: "gap-3",
3066
+ title: "text-body-sm font-semibold text-default",
3067
+ description: "text-body-xs text-default-secondary"
3068
+ },
3069
+ compact: {
3070
+ pad: "py-2.5",
3071
+ gap: "gap-2",
3072
+ title: "text-body-xs font-semibold text-default",
3073
+ description: "text-body-tiny text-default-secondary"
3074
+ }
3075
+ };
3076
+ var DIVIDER = {
3077
+ none: "",
3078
+ top: "border-t border-default",
3079
+ bottom: "border-b border-default"
3080
+ };
3081
+ function ListRow({
3082
+ leading,
3083
+ title,
3084
+ titleMeta,
3085
+ description,
3086
+ meta,
3087
+ trailing,
3088
+ footer,
3089
+ density = "default",
3090
+ divider = "none",
3091
+ as: Tag = "div",
3092
+ onClick,
3093
+ className
3094
+ }) {
3095
+ const d = DENSITY[density];
3096
+ const hasTitleLine = Boolean(leading || title != null || titleMeta || meta);
3097
+ return /* @__PURE__ */ jsxs41(
3098
+ Tag,
3099
+ {
3100
+ className: clsx52(
3101
+ "flex w-full items-start",
3102
+ d.pad,
3103
+ DIVIDER[divider],
3104
+ onClick && "cursor-pointer rounded-lg transition-colors hover:bg-default-secondary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand",
3105
+ className
3106
+ ),
3107
+ onClick,
3108
+ role: onClick ? "button" : void 0,
3109
+ tabIndex: onClick ? 0 : void 0,
3110
+ onKeyDown: onClick ? (e) => {
3111
+ if (e.key === "Enter" || e.key === " ") {
3112
+ e.preventDefault();
3113
+ onClick();
3114
+ }
3115
+ } : void 0,
3116
+ children: [
3117
+ /* @__PURE__ */ jsxs41("div", { className: clsx52("flex min-w-0 flex-1 flex-col", d.gap), children: [
3118
+ hasTitleLine && /* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between gap-2", children: [
3119
+ /* @__PURE__ */ jsxs41("div", { className: "flex min-w-0 items-center gap-2", children: [
3120
+ leading,
3121
+ title != null && /* @__PURE__ */ jsx56("span", { className: clsx52("truncate", d.title), children: title }),
3122
+ titleMeta && /* @__PURE__ */ jsx56("span", { className: "shrink-0", children: titleMeta })
3123
+ ] }),
3124
+ meta && /* @__PURE__ */ jsx56("span", { className: "shrink-0", children: meta })
3125
+ ] }),
3126
+ description && /* @__PURE__ */ jsx56("p", { className: d.description, children: description }),
3127
+ footer
3128
+ ] }),
3129
+ trailing && /* @__PURE__ */ jsx56("div", { className: "ml-3 flex shrink-0 items-center self-center", children: trailing })
3130
+ ]
3131
+ }
3132
+ );
3133
+ }
3134
+
3135
+ // src/components/lists/file-row.tsx
3136
+ import clsx53 from "clsx";
3137
+ import { jsx as jsx57, jsxs as jsxs42 } from "react/jsx-runtime";
3138
+ function FileTypeBadge({ type }) {
3139
+ return /* @__PURE__ */ jsx57("span", { className: "flex size-[34px] shrink-0 items-center justify-center rounded-md bg-brand-tertiary text-body-tiny font-semibold text-brand", children: type });
3140
+ }
3141
+ function FileRow({
3142
+ name,
3143
+ detail,
3144
+ fileType,
3145
+ leading,
3146
+ onDownload,
3147
+ downloadLabel = "Download",
3148
+ actions,
3149
+ className
3150
+ }) {
3151
+ const lead = leading ?? (fileType ? /* @__PURE__ */ jsx57(FileTypeBadge, { type: fileType }) : null);
3152
+ return /* @__PURE__ */ jsxs42(
3153
+ "div",
3154
+ {
3155
+ className: clsx53(
3156
+ "flex items-center gap-3 rounded-lg border border-default bg-default px-3 py-2.5",
3157
+ className
3158
+ ),
3159
+ children: [
3160
+ lead,
3161
+ /* @__PURE__ */ jsxs42("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
3162
+ /* @__PURE__ */ jsx57("span", { className: "truncate text-body-sm font-medium text-default", children: name }),
3163
+ detail && /* @__PURE__ */ jsx57("span", { className: "text-body-xs text-default-secondary", children: detail })
3164
+ ] }),
3165
+ (onDownload || actions) && /* @__PURE__ */ jsxs42("div", { className: "flex shrink-0 items-center gap-3", children: [
3166
+ onDownload && /* @__PURE__ */ jsx57(
3167
+ "button",
3168
+ {
3169
+ type: "button",
3170
+ onClick: onDownload,
3171
+ className: "text-body-xs font-medium text-brand hover:underline",
3172
+ children: downloadLabel
3173
+ }
3174
+ ),
3175
+ actions
3176
+ ] })
3177
+ ]
3178
+ }
3179
+ );
3180
+ }
3181
+
3182
+ // src/components/lists/scored-row.tsx
3183
+ import clsx54 from "clsx";
3184
+ import { jsx as jsx58, jsxs as jsxs43 } from "react/jsx-runtime";
3185
+ var GAP2 = {
3186
+ sm: "gap-2",
3187
+ md: "gap-3",
3188
+ lg: "gap-5",
3189
+ xl: "gap-12"
3190
+ };
3191
+ var ALIGN = {
3192
+ center: "items-center",
3193
+ end: "items-end"
3194
+ };
3195
+ function ScoredRow({
3196
+ leading,
3197
+ title,
3198
+ subtitle,
3199
+ aside,
3200
+ meter,
3201
+ trailing,
3202
+ titleWidth,
3203
+ asideWidth,
3204
+ meterWidth,
3205
+ trailingWidth,
3206
+ gap = "md",
3207
+ leadingGap,
3208
+ align = "center",
3209
+ className
3210
+ }) {
3211
+ return /* @__PURE__ */ jsxs43("div", { className: clsx54("flex w-full", ALIGN[align], GAP2[gap], className), children: [
3212
+ /* @__PURE__ */ jsxs43(
3213
+ "div",
3214
+ {
3215
+ className: clsx54(
3216
+ "flex min-w-0",
3217
+ ALIGN[align],
3218
+ GAP2[leadingGap ?? gap],
3219
+ titleWidth ? "shrink-0" : "flex-1"
3220
+ ),
3221
+ style: titleWidth ? { width: titleWidth } : void 0,
3222
+ children: [
3223
+ leading,
3224
+ /* @__PURE__ */ jsxs43("div", { className: "min-w-0 flex-1", children: [
3225
+ /* @__PURE__ */ jsx58("p", { className: "truncate text-body-sm font-medium leading-none text-default", children: title }),
3226
+ subtitle && /* @__PURE__ */ jsx58("p", { className: "mt-0.5 truncate text-body-xs text-default-secondary", children: subtitle })
3227
+ ] })
3228
+ ]
3229
+ }
3230
+ ),
3231
+ aside && /* @__PURE__ */ jsx58(
3232
+ "div",
3233
+ {
3234
+ className: clsx54("min-w-0", asideWidth ? "shrink-0" : "flex-1"),
3235
+ style: asideWidth ? { width: asideWidth } : void 0,
3236
+ children: aside
3237
+ }
3238
+ ),
3239
+ meter && /* @__PURE__ */ jsx58(
3240
+ "div",
3241
+ {
3242
+ className: clsx54("min-w-0", meterWidth ? "shrink-0" : "flex-1"),
3243
+ style: meterWidth ? { width: meterWidth } : void 0,
3244
+ children: meter
3245
+ }
3246
+ ),
3247
+ trailing && /* @__PURE__ */ jsx58("div", { className: "shrink-0 text-right", style: trailingWidth ? { width: trailingWidth } : void 0, children: trailing })
3248
+ ] });
3249
+ }
3250
+
3251
+ // src/components/lists/ranked-row.tsx
3252
+ import clsx55 from "clsx";
3253
+
3254
+ // src/components/feedback/progress-bar.tsx
3255
+ import { jsx as jsx59, jsxs as jsxs44 } from "react/jsx-runtime";
3256
+ var SIZE13 = {
3257
+ xs: "h-1",
3258
+ sm: "h-1.5",
3259
+ md: "h-2",
3260
+ lg: "h-3"
3261
+ };
3262
+ var FILL = {
3263
+ brand: "bg-brand",
3264
+ positive: "bg-positive",
3265
+ warning: "bg-warning",
3266
+ danger: "bg-danger",
3267
+ neutral: "bg-neutral"
3268
+ };
3269
+ function ProgressBar({
3270
+ value,
3271
+ tone = "brand",
3272
+ size = "sm",
3273
+ label,
3274
+ showValue = false,
3275
+ radius,
3276
+ "aria-label": ariaLabel,
3277
+ className
3278
+ }) {
3279
+ const clamped = Math.min(100, Math.max(0, value));
3280
+ const rounded = radius ? void 0 : "rounded-full";
3281
+ const track = /* @__PURE__ */ jsx59(
3282
+ "div",
3283
+ {
3284
+ role: "progressbar",
3285
+ "aria-valuenow": clamped,
3286
+ "aria-valuemin": 0,
3287
+ "aria-valuemax": 100,
3288
+ "aria-label": label ? void 0 : ariaLabel,
3289
+ className: cn("w-full overflow-hidden bg-default-tertiary", SIZE13[size], rounded, className),
3290
+ style: radius ? { borderRadius: radius } : void 0,
3291
+ children: /* @__PURE__ */ jsx59(
3292
+ "div",
3293
+ {
3294
+ className: cn("h-full transition-all", rounded, FILL[tone]),
3295
+ style: { width: `${clamped}%`, ...radius ? { borderRadius: radius } : void 0 }
3296
+ }
3297
+ )
3298
+ }
3299
+ );
3300
+ if (!label && !showValue) return track;
3301
+ return /* @__PURE__ */ jsxs44("div", { children: [
3302
+ /* @__PURE__ */ jsxs44("div", { className: "mb-1.5 flex items-center justify-between gap-2", children: [
3303
+ label && /* @__PURE__ */ jsx59("span", { className: "text-body-xs text-default-secondary", children: label }),
3304
+ showValue && /* @__PURE__ */ jsxs44("span", { className: "ml-auto text-body-xs font-medium tabular-nums text-default", children: [
3305
+ Math.round(clamped),
3306
+ "%"
3307
+ ] })
3308
+ ] }),
3309
+ track
3310
+ ] });
3311
+ }
3312
+
3313
+ // src/components/lists/ranked-row.tsx
3314
+ import { jsx as jsx60, jsxs as jsxs45 } from "react/jsx-runtime";
3315
+ function RankedRow({
3316
+ rank,
3317
+ name,
3318
+ sublabel,
3319
+ score,
3320
+ tone = "auto",
3321
+ direction = "higher-is-worse",
3322
+ scoreSize = "md",
3323
+ scoreWeight = "bold",
3324
+ className
3325
+ }) {
3326
+ const resolved = tone === "auto" ? getScoreTone(score, { direction }) : tone;
3327
+ return /* @__PURE__ */ jsxs45("div", { className: clsx55("flex w-full shrink-0 flex-col gap-1.5", className), children: [
3328
+ /* @__PURE__ */ jsxs45("div", { className: "flex w-full items-center justify-between", children: [
3329
+ /* @__PURE__ */ jsxs45("div", { className: "flex min-w-0 items-center gap-2.5", children: [
3330
+ rank !== void 0 && /* @__PURE__ */ jsx60("p", { className: "w-[14px] shrink-0 text-body-xs font-bold text-default-secondary", children: rank }),
3331
+ /* @__PURE__ */ jsxs45("div", { className: "flex min-w-0 flex-col gap-px", children: [
3332
+ /* @__PURE__ */ jsx60("p", { className: "truncate text-body-sm font-medium leading-none text-default", children: name }),
3333
+ sublabel && /* @__PURE__ */ jsx60("p", { className: "text-body-tiny text-default-tertiary", children: sublabel })
3334
+ ] })
3335
+ ] }),
3336
+ /* @__PURE__ */ jsx60(
3337
+ ScoreValue,
3338
+ {
3339
+ value: score,
3340
+ size: scoreSize,
3341
+ weight: scoreWeight,
3342
+ tone: resolved,
3343
+ className: "ml-2 shrink-0"
3344
+ }
3345
+ )
3346
+ ] }),
3347
+ /* @__PURE__ */ jsx60(ProgressBar, { value: score, tone: resolved, "aria-label": `${name} score` })
3348
+ ] });
3349
+ }
3350
+
3351
+ // src/components/lists/icon-text-row.tsx
3352
+ import clsx56 from "clsx";
3353
+ import { jsx as jsx61, jsxs as jsxs46 } from "react/jsx-runtime";
3354
+ function IconTextRow({ icon, title, detail, className }) {
3355
+ return /* @__PURE__ */ jsxs46("div", { className: clsx56("flex items-start gap-3", className), children: [
3356
+ /* @__PURE__ */ jsx61("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-full bg-brand-tertiary text-brand", children: icon }),
3357
+ /* @__PURE__ */ jsxs46("div", { className: "min-w-0", children: [
3358
+ /* @__PURE__ */ jsx61("p", { className: "text-body-sm font-semibold text-default", children: title }),
3359
+ /* @__PURE__ */ jsx61("p", { className: "mt-0.5 text-body-xs text-default-secondary", children: detail })
3360
+ ] })
3361
+ ] });
3362
+ }
3363
+
3364
+ // src/components/lists/checklist-row.tsx
3365
+ import clsx57 from "clsx";
3366
+ import { LuCheck as LuCheck5 } from "react-icons/lu";
3367
+ import { jsx as jsx62, jsxs as jsxs47 } from "react/jsx-runtime";
3368
+ function ChecklistRow({ label, state, className }) {
3369
+ return /* @__PURE__ */ jsxs47("li", { className: clsx57("flex items-center gap-3", className), children: [
3370
+ /* @__PURE__ */ jsx62("span", { className: "flex size-5 shrink-0 items-center justify-center", children: state === "done" ? /* @__PURE__ */ jsx62(LuCheck5, { className: "size-4 text-positive", strokeWidth: 2.5, "aria-hidden": true }) : /* @__PURE__ */ jsx62(
3371
+ "span",
3372
+ {
3373
+ className: clsx57(
3374
+ "size-3.5 rounded-full border-2",
3375
+ state === "active" ? "animate-pulse border-brand-emphasis border-t-transparent" : "border-disabled"
3376
+ )
3377
+ }
3378
+ ) }),
3379
+ /* @__PURE__ */ jsx62(
3380
+ "span",
3381
+ {
3382
+ className: clsx57(
3383
+ "text-body-sm",
3384
+ state === "pending" ? "text-default-tertiary" : "font-semibold text-default"
3385
+ ),
3386
+ children: label
3387
+ }
3388
+ )
3389
+ ] });
3390
+ }
3391
+
3392
+ // src/components/lists/numbered-steps-list.tsx
3393
+ import clsx58 from "clsx";
3394
+ import { jsx as jsx63, jsxs as jsxs48 } from "react/jsx-runtime";
3395
+ function NumberedStepsList({ steps, className }) {
3396
+ return /* @__PURE__ */ jsx63("ol", { className: clsx58("flex flex-col gap-1.5", className), children: steps.map((step, i) => /* @__PURE__ */ jsxs48("li", { className: "flex items-start gap-2 text-[12px] text-default", children: [
3397
+ /* @__PURE__ */ jsx63("span", { className: "mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full bg-brand-tertiary text-[9px] font-bold text-brand", children: i + 1 }),
3398
+ step
3399
+ ] }, i)) });
3400
+ }
3401
+
3402
+ // src/components/lists/meta-field.tsx
3403
+ import clsx59 from "clsx";
3404
+ import { jsx as jsx64, jsxs as jsxs49 } from "react/jsx-runtime";
3405
+ function MetaField({
3406
+ label,
3407
+ value,
3408
+ detail,
3409
+ layout = "stacked",
3410
+ className
3411
+ }) {
3412
+ const shown = value === null || value === void 0 || value === "" ? "\u2014" : value;
3413
+ if (layout === "inline") {
3414
+ return /* @__PURE__ */ jsxs49("div", { className: clsx59("flex gap-3 text-body-xs", className), children: [
3415
+ /* @__PURE__ */ jsx64("span", { className: "w-[120px] shrink-0 text-default-secondary", children: label }),
3416
+ /* @__PURE__ */ jsx64("span", { className: "min-w-0 flex-1 text-default", children: shown })
3417
+ ] });
3418
+ }
3419
+ return /* @__PURE__ */ jsxs49("div", { className: clsx59("flex flex-col gap-0.5", className), children: [
3420
+ /* @__PURE__ */ jsx64("p", { className: "text-body-tiny font-medium text-default-secondary", children: label }),
3421
+ /* @__PURE__ */ jsx64("p", { className: "text-body-sm font-medium text-default", children: shown }),
3422
+ detail && /* @__PURE__ */ jsx64("p", { className: "text-body-xs text-default-secondary", children: detail })
3423
+ ] });
3424
+ }
3425
+ function MetaFieldGrid({ children, className }) {
3426
+ return /* @__PURE__ */ jsx64("div", { className: clsx59("flex flex-wrap gap-x-4 gap-y-3.5", className), children });
3427
+ }
3428
+
3429
+ // src/components/lists/checked-group-list.tsx
3430
+ import clsx60 from "clsx";
3431
+ import { LuCheck as LuCheck6 } from "react-icons/lu";
3432
+ import { jsx as jsx65, jsxs as jsxs50 } from "react/jsx-runtime";
3433
+ var COLUMNS2 = {
3434
+ 1: "columns-1",
3435
+ 2: "columns-2",
3436
+ 3: "columns-3"
3437
+ };
3438
+ function CheckedGroupList({
3439
+ groups,
3440
+ columns = 2,
3441
+ icon,
3442
+ emptyLabel = "None.",
3443
+ className
3444
+ }) {
3445
+ if (groups.length === 0) {
3446
+ return /* @__PURE__ */ jsx65("p", { className: clsx60("text-body-xs text-default-secondary", className), children: emptyLabel });
3447
+ }
3448
+ const glyph = icon === void 0 ? /* @__PURE__ */ jsx65(LuCheck6, { className: "size-3.5", strokeWidth: 2.5, "aria-hidden": true }) : icon;
3449
+ return /* @__PURE__ */ jsx65("div", { className: clsx60(COLUMNS2[columns], "gap-x-6", className), children: groups.map((group) => /* @__PURE__ */ jsxs50("div", { className: "mb-5 break-inside-avoid last:mb-0", children: [
3450
+ /* @__PURE__ */ jsx65("p", { className: "mb-2 text-body-tiny font-semibold uppercase tracking-wide text-default-secondary", children: group.label }),
3451
+ /* @__PURE__ */ jsx65("ul", { className: "space-y-1.5", children: group.items.map((item) => /* @__PURE__ */ jsxs50("li", { className: "flex items-center gap-2 text-body-xs text-default", children: [
3452
+ glyph && /* @__PURE__ */ jsx65("span", { className: "shrink-0", children: glyph }),
3453
+ item
3454
+ ] }, item)) })
3455
+ ] }, group.label)) });
3456
+ }
3457
+
3458
+ // src/components/lists/data-table.tsx
3459
+ import clsx61 from "clsx";
3460
+ import { jsx as jsx66, jsxs as jsxs51 } from "react/jsx-runtime";
3461
+ var DENSITY2 = {
3462
+ default: {
3463
+ headerCell: "px-4 py-3",
3464
+ headerText: "text-body-xs font-medium text-default-secondary whitespace-nowrap",
3465
+ bodyCell: "px-4 py-[14px]"
3466
+ },
3467
+ compact: {
3468
+ headerCell: "px-3 py-2",
3469
+ headerText: "text-body-tiny font-semibold uppercase tracking-[0.4px] text-default-secondary whitespace-nowrap",
3470
+ bodyCell: "px-3 py-2 text-body-xs text-default"
3471
+ }
3472
+ };
3473
+ var ALIGN2 = {
3474
+ center: "align-middle",
3475
+ top: "align-top"
3476
+ };
3477
+ function DataTable({
3478
+ columns,
3479
+ rows,
3480
+ getRowKey,
3481
+ density = "default",
3482
+ align = "center",
3483
+ onRowClick,
3484
+ emptyLabel,
3485
+ className
3486
+ }) {
3487
+ const d = DENSITY2[density];
3488
+ const minWidth = columns.length ? `calc(${columns.map((c) => c.width).join(" + ")})` : void 0;
3489
+ return /* @__PURE__ */ jsx66("div", { className: clsx61("overflow-x-auto rounded-xl border border-default bg-default", className), children: /* @__PURE__ */ jsxs51("table", { className: "w-full table-fixed border-collapse text-left", style: { minWidth }, children: [
3490
+ /* @__PURE__ */ jsx66("colgroup", { children: columns.map((col) => (
3491
+ // A grow column gets no width, so table-fixed hands it the leftover space.
3492
+ // Its floor is already counted in the table's min-width.
3493
+ /* @__PURE__ */ jsx66("col", { style: col.grow ? void 0 : { width: col.width } }, col.key)
3494
+ )) }),
3495
+ /* @__PURE__ */ jsx66("thead", { children: /* @__PURE__ */ jsx66("tr", { className: "bg-default-secondary", children: columns.map((col) => /* @__PURE__ */ jsx66("th", { scope: "col", className: clsx61("overflow-hidden", d.headerCell, d.headerText), children: col.header }, col.key)) }) }),
3496
+ /* @__PURE__ */ jsx66("tbody", { children: rows.length === 0 ? emptyLabel && /* @__PURE__ */ jsx66("tr", { children: /* @__PURE__ */ jsx66(
3497
+ "td",
3498
+ {
3499
+ colSpan: columns.length,
3500
+ className: clsx61(d.bodyCell, "text-center text-body-sm text-default-secondary"),
3501
+ children: emptyLabel
3502
+ }
3503
+ ) }) : rows.map((row, i) => /* @__PURE__ */ jsx66(
3504
+ "tr",
3505
+ {
3506
+ className: clsx61(
3507
+ "transition-colors hover:bg-default-secondary/50",
3508
+ i > 0 && "border-t border-default",
3509
+ // outline, not ring: `ring-*` compiles to box-shadow, which browsers
3510
+ // do not paint on a <tr> under border-collapse: collapse.
3511
+ onRowClick && "cursor-pointer outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-brand"
3512
+ ),
3513
+ tabIndex: onRowClick ? 0 : void 0,
3514
+ onClick: onRowClick ? () => onRowClick(row) : void 0,
3515
+ onKeyDown: onRowClick ? (e) => {
3516
+ if (e.key === "Enter" || e.key === " ") {
3517
+ e.preventDefault();
3518
+ onRowClick(row);
3519
+ }
3520
+ } : void 0,
3521
+ children: columns.map((col) => /* @__PURE__ */ jsx66("td", { className: clsx61("overflow-hidden", d.bodyCell, ALIGN2[align]), children: col.render(row) }, col.key))
3522
+ },
3523
+ getRowKey(row, i)
3524
+ )) })
3525
+ ] }) });
3526
+ }
3527
+ function TableCellLeadText({ primary, secondary, size = "md", className }) {
3528
+ return /* @__PURE__ */ jsxs51("div", { className: clsx61("flex flex-col gap-0.5", className), children: [
3529
+ /* @__PURE__ */ jsx66(
3530
+ "span",
3531
+ {
3532
+ className: clsx61(
3533
+ "font-medium leading-snug text-default",
3534
+ size === "sm" ? "text-body-xs" : "text-body-sm"
3535
+ ),
3536
+ children: primary
3537
+ }
3538
+ ),
3539
+ secondary && /* @__PURE__ */ jsx66(
3540
+ "span",
3541
+ {
3542
+ className: clsx61(
3543
+ "font-normal leading-tight text-default-secondary",
3544
+ size === "sm" ? "text-body-tiny" : "text-body-xs"
3545
+ ),
3546
+ children: secondary
3547
+ }
3548
+ )
3549
+ ] });
3550
+ }
3551
+ function TableCellText({
3552
+ children,
3553
+ muted = true,
3554
+ size = "md",
3555
+ truncate = false,
3556
+ className
3557
+ }) {
3558
+ return /* @__PURE__ */ jsx66(
3559
+ "span",
3560
+ {
3561
+ className: clsx61(
3562
+ "font-normal leading-snug",
3563
+ size === "sm" ? "text-body-tiny" : "text-body-xs",
3564
+ truncate ? "block truncate" : "whitespace-nowrap",
3565
+ muted ? "text-default-secondary" : "text-default",
3566
+ className
3567
+ ),
3568
+ children
3569
+ }
3570
+ );
3571
+ }
3572
+ function TableCellBadge({ label, className }) {
3573
+ return /* @__PURE__ */ jsx66(
3574
+ "span",
3575
+ {
3576
+ className: clsx61(
3577
+ "inline-flex items-center rounded-md border border-default bg-default-secondary px-2 py-0.5 text-body-tiny font-medium text-default-secondary whitespace-nowrap",
3578
+ className
3579
+ ),
3580
+ children: label
3581
+ }
3582
+ );
3583
+ }
3584
+ function TableCellProgress({
3585
+ percent,
3586
+ tone = "brand",
3587
+ size = "md",
3588
+ className
3589
+ }) {
3590
+ const clamped = Math.min(100, Math.max(0, percent));
3591
+ return /* @__PURE__ */ jsxs51("div", { className: clsx61("flex flex-col gap-1", className), children: [
3592
+ /* @__PURE__ */ jsx66(ProgressBar, { value: clamped, tone, size: "sm", className: "w-16", "aria-label": `${clamped}%` }),
3593
+ /* @__PURE__ */ jsxs51(
3594
+ "span",
3595
+ {
3596
+ className: clsx61(
3597
+ "leading-none text-default-secondary",
3598
+ size === "sm" ? "text-[10px]" : "text-body-tiny"
3599
+ ),
3600
+ children: [
3601
+ percent,
3602
+ "%"
3603
+ ]
3604
+ }
3605
+ )
3606
+ ] });
3607
+ }
3608
+
3609
+ // src/components/feedback/inline-alert.tsx
3610
+ import clsx62 from "clsx";
3611
+ import { LuCircleCheckBig as LuCircleCheckBig2, LuInfo as LuInfo2, LuTriangleAlert as LuTriangleAlert2 } from "react-icons/lu";
3612
+ import { jsx as jsx67, jsxs as jsxs52 } from "react/jsx-runtime";
3613
+ var toneStyles3 = {
3614
+ info: "border-brand-tertiary bg-brand-tertiary text-brand",
3615
+ warning: "border-warning-tertiary bg-warning-tertiary text-warning",
3616
+ danger: "border-danger-tertiary bg-danger-tertiary text-danger",
3617
+ positive: "border-positive-tertiary bg-positive-tertiary text-positive"
3618
+ };
3619
+ var toneIcons = {
3620
+ info: /* @__PURE__ */ jsx67(LuInfo2, { className: "size-4" }),
3621
+ warning: /* @__PURE__ */ jsx67(LuTriangleAlert2, { className: "size-4" }),
3622
+ danger: /* @__PURE__ */ jsx67(LuTriangleAlert2, { className: "size-4" }),
3623
+ positive: /* @__PURE__ */ jsx67(LuCircleCheckBig2, { className: "size-4" })
3624
+ };
3625
+ function InlineAlert({ tone, children, icon, className }) {
3626
+ const glyph = icon === void 0 ? toneIcons[tone] : icon;
3627
+ return /* @__PURE__ */ jsxs52(
3628
+ "div",
3629
+ {
3630
+ role: tone === "danger" ? "alert" : "status",
3631
+ className: clsx62(
3632
+ "flex items-start gap-2.5 rounded-xl border p-3.5 text-body-xs",
3633
+ toneStyles3[tone],
3634
+ className
3635
+ ),
3636
+ children: [
3637
+ glyph && /* @__PURE__ */ jsx67("span", { className: "mt-px shrink-0", children: glyph }),
3638
+ /* @__PURE__ */ jsx67("div", { className: "min-w-0", children })
3639
+ ]
3640
+ }
3641
+ );
3642
+ }
3643
+
3644
+ // src/components/feedback/empty-state.tsx
3645
+ import clsx63 from "clsx";
3646
+ import { jsx as jsx68, jsxs as jsxs53 } from "react/jsx-runtime";
3647
+ var SIZES = {
3648
+ sm: "py-8",
3649
+ md: "py-12",
3650
+ lg: "py-16"
3651
+ };
3652
+ var TONES = {
3653
+ empty: "text-default-secondary",
3654
+ loading: "text-default-secondary",
3655
+ error: "text-danger"
3656
+ };
3657
+ function EmptyState({
3658
+ message,
3659
+ variant = "empty",
3660
+ size = "sm",
3661
+ icon,
3662
+ action,
3663
+ className
3664
+ }) {
3665
+ return /* @__PURE__ */ jsxs53(
3666
+ "div",
3667
+ {
3668
+ className: clsx63(
3669
+ "flex flex-col items-center justify-center gap-2 px-4 text-center text-body-sm",
3670
+ SIZES[size],
3671
+ TONES[variant],
3672
+ className
3673
+ ),
3674
+ "aria-live": variant === "empty" ? void 0 : "polite",
3675
+ children: [
3676
+ icon && /* @__PURE__ */ jsx68("span", { className: "text-default-tertiary", children: icon }),
3677
+ /* @__PURE__ */ jsx68("p", { children: message }),
3678
+ action
3679
+ ]
3680
+ }
3681
+ );
3682
+ }
3683
+
3684
+ // src/components/forms/password-input.tsx
3685
+ import { forwardRef as forwardRef5, useState as useState5 } from "react";
3686
+ import { LuEye, LuEyeOff } from "react-icons/lu";
3687
+ import { jsx as jsx69 } from "react/jsx-runtime";
3688
+ var PasswordInput = forwardRef5(function PasswordInput2(props, ref) {
3689
+ const [visible, setVisible] = useState5(false);
3690
+ return /* @__PURE__ */ jsx69(
3691
+ Input,
3692
+ {
3693
+ ref,
3694
+ ...props,
3695
+ type: visible ? "text" : "password",
3696
+ trailingAction: /* @__PURE__ */ jsx69(
3697
+ "button",
3698
+ {
3699
+ type: "button",
3700
+ "aria-label": visible ? "Hide password" : "Show password",
3701
+ onClick: () => setVisible((v) => !v),
3702
+ className: "flex items-center justify-center rounded transition-colors hover:text-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand",
3703
+ children: visible ? /* @__PURE__ */ jsx69(LuEyeOff, { className: "size-4" }) : /* @__PURE__ */ jsx69(LuEye, { className: "size-4" })
3704
+ }
3705
+ )
3706
+ }
3707
+ );
3708
+ });
3709
+
3710
+ // src/components/ai/ai-chat-bar.tsx
3711
+ import clsx64 from "clsx";
3712
+ import { LuArrowRight as LuArrowRight2, LuSearch } from "react-icons/lu";
3713
+ import { jsx as jsx70, jsxs as jsxs54 } from "react/jsx-runtime";
3714
+ function AIChatBar({
3715
+ placeholder = "Ask Intelligence about any entity, supplier, or risk\u2026",
3716
+ className
3717
+ }) {
3718
+ return /* @__PURE__ */ jsxs54(
3719
+ "div",
3720
+ {
3721
+ className: clsx64(
3722
+ "flex h-16 items-center gap-3 rounded-2xl border border-default bg-default px-6 shadow-panel",
3723
+ className
3724
+ ),
3725
+ children: [
3726
+ /* @__PURE__ */ jsx70("span", { className: "shrink-0 text-icon-default-secondary", children: /* @__PURE__ */ jsx70(LuSearch, { className: "size-4" }) }),
3727
+ /* @__PURE__ */ jsx70("p", { className: "flex-1 text-body-sm text-default-tertiary truncate", children: placeholder }),
3728
+ /* @__PURE__ */ jsxs54(
3729
+ "button",
3730
+ {
3731
+ type: "button",
3732
+ className: "inline-flex shrink-0 items-center gap-2 rounded-xl bg-brand px-4 py-3 text-body-sm font-semibold text-brand-on-brand hover:bg-brand-hover transition-colors",
3733
+ children: [
3734
+ "Ask",
3735
+ /* @__PURE__ */ jsx70(LuArrowRight2, { className: "size-4" })
3736
+ ]
3737
+ }
3738
+ )
3739
+ ]
3740
+ }
3741
+ );
3742
+ }
3743
+
3744
+ // src/components/ai/ai-suggestion-chip.tsx
3745
+ import clsx65 from "clsx";
3746
+ import { LuArrowRight as LuArrowRight3, LuCpu } from "react-icons/lu";
3747
+ import { jsx as jsx71, jsxs as jsxs55 } from "react/jsx-runtime";
3748
+ function AISuggestionChip({ prompt, onClick, className }) {
3749
+ return /* @__PURE__ */ jsxs55(
3750
+ "button",
3751
+ {
3752
+ type: "button",
3753
+ onClick,
3754
+ className: clsx65(
3755
+ "flex h-12 w-full items-center gap-3 rounded-xl border border-default bg-default px-3 text-left hover:bg-default-hover transition-colors",
3756
+ className
3757
+ ),
3758
+ children: [
3759
+ /* @__PURE__ */ jsx71("span", { className: "shrink-0 text-icon-brand", children: /* @__PURE__ */ jsx71(LuCpu, { className: "size-4" }) }),
3760
+ /* @__PURE__ */ jsx71("span", { className: "flex-1 text-body-sm text-default truncate", children: prompt }),
3761
+ /* @__PURE__ */ jsx71("span", { className: "shrink-0 text-icon-default-secondary", children: /* @__PURE__ */ jsx71(LuArrowRight3, { className: "size-3.5", strokeWidth: 2.5 }) })
3762
+ ]
3763
+ }
3764
+ );
3765
+ }
3766
+
3767
+ // src/components/ai/quick-actions-bar.tsx
3768
+ import clsx66 from "clsx";
3769
+ import { jsx as jsx72 } from "react/jsx-runtime";
3770
+ function QuickActionsBar({ actions, active, onSelect, className }) {
3771
+ return /* @__PURE__ */ jsx72("div", { className: clsx66("flex items-center gap-3 flex-wrap", className), children: actions.map((action) => /* @__PURE__ */ jsx72(
3772
+ "button",
3773
+ {
3774
+ type: "button",
3775
+ onClick: () => onSelect?.(action.value),
3776
+ className: "focus:outline-none",
3777
+ children: /* @__PURE__ */ jsx72(
3778
+ TagPill,
3779
+ {
3780
+ label: action.label,
3781
+ tone: active === action.value ? "brand" : "default"
3782
+ }
3783
+ )
3784
+ },
3785
+ action.value
3786
+ )) });
3787
+ }
3788
+
3789
+ // src/components/decorative/aurora-backdrop.tsx
3790
+ import { jsx as jsx73, jsxs as jsxs56 } from "react/jsx-runtime";
3791
+ function AuroraBackdrop() {
3792
+ return /* @__PURE__ */ jsxs56("div", { className: "pointer-events-none absolute inset-0", "aria-hidden": true, children: [
3793
+ /* @__PURE__ */ jsx73("div", { className: "absolute -left-24 -top-28", style: { width: 380, height: 380, background: "radial-gradient(ellipse, rgba(249,133,133,0.45) 0%, transparent 70%)" } }),
3794
+ /* @__PURE__ */ jsx73("div", { className: "absolute -top-24 right-[-4%]", style: { width: 320, height: 320, background: "radial-gradient(ellipse, rgba(254,160,160,0.4) 0%, transparent 70%)" } }),
3795
+ /* @__PURE__ */ jsx73("div", { className: "absolute bottom-[-10%] right-[14%]", style: { width: 420, height: 420, background: "radial-gradient(ellipse, rgba(196,181,253,0.3) 0%, transparent 70%)" } }),
3796
+ /* @__PURE__ */ jsx73("div", { className: "absolute bottom-[-6%] left-[4%]", style: { width: 280, height: 280, background: "radial-gradient(ellipse, rgba(147,197,253,0.25) 0%, transparent 70%)" } }),
3797
+ /* @__PURE__ */ jsx73("div", { className: "absolute left-[20%] top-[30%]", style: { width: 240, height: 240, background: "radial-gradient(ellipse, rgba(173,216,255,0.18) 0%, transparent 70%)" } })
3798
+ ] });
3799
+ }
3800
+
3801
+ // src/components/icons/solid.tsx
3802
+ import { jsx as jsx74 } from "react/jsx-runtime";
3803
+ function solid(path, displayName) {
3804
+ const Component = ({ className }) => /* @__PURE__ */ jsx74("svg", { viewBox: "0 0 20 20", fill: "currentColor", className, "aria-hidden": "true", children: /* @__PURE__ */ jsx74("path", { fillRule: "evenodd", d: path, clipRule: "evenodd" }) });
3805
+ Component.displayName = displayName;
3806
+ return Component;
3807
+ }
3808
+ var SolidAlertTriangle = solid(
3809
+ "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",
3810
+ "SolidAlertTriangle"
3811
+ );
3812
+ var SolidShieldCheck = solid(
3813
+ "M10 1.944A11.954 11.954 0 012.166 5C2.056 5.649 2 6.319 2 7c0 5.225 3.34 9.67 8 11.317C14.66 16.67 18 12.225 18 7c0-.682-.057-1.35-.166-2.001A11.954 11.954 0 0110 1.944zm1.414 7.349a1 1 0 00-1.414-1.414L8.5 9.379l-.793-.793a1 1 0 00-1.414 1.414l1.5 1.5a1 1 0 001.414 0l2.207-2.207z",
3814
+ "SolidShieldCheck"
3815
+ );
3816
+ var SolidGlobe = solid(
3817
+ "M10 18a8 8 0 100-16 8 8 0 000 16zM4.332 8.027a6.012 6.012 0 011.912-2.706C6.512 5.73 6.974 6 7.5 6A1.5 1.5 0 019 7.5V8a2 2 0 004 0 2 2 0 011.523-1.943A5.977 5.977 0 0116 10c0 .34-.028.675-.083 1H15a2 2 0 00-2 2v2.197A5.973 5.973 0 0110 16v-2a2 2 0 00-2-2 2 2 0 01-2-2 2 2 0 00-1.668-1.973z",
3818
+ "SolidGlobe"
3819
+ );
3820
+ var SolidMapPin = solid(
3821
+ "M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z",
3822
+ "SolidMapPin"
3823
+ );
3824
+ var SolidClock = solid(
3825
+ "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z",
3826
+ "SolidClock"
3827
+ );
3828
+ var SolidArrowRight = solid(
3829
+ "M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z",
3830
+ "SolidArrowRight"
3831
+ );
3832
+ var SolidInfoCircle = solid(
3833
+ "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z",
3834
+ "SolidInfoCircle"
3835
+ );
3836
+ var SolidCheck = solid(
3837
+ "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
3838
+ "SolidCheck"
3839
+ );
3840
+ function SolidChartBar({ className }) {
3841
+ return /* @__PURE__ */ jsx74("svg", { viewBox: "0 0 20 20", fill: "currentColor", className, "aria-hidden": "true", children: /* @__PURE__ */ jsx74("path", { d: "M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z" }) });
3842
+ }
1268
3843
  export {
3844
+ AIChatBar,
3845
+ AISuggestionChip,
3846
+ AuroraBackdrop,
1269
3847
  Avatar,
1270
3848
  AvatarBlock,
1271
3849
  AvatarGroup,
3850
+ Badge,
3851
+ BarChart,
1272
3852
  Button,
1273
3853
  ButtonGroup,
3854
+ CHART_SEQUENCE,
3855
+ CHART_TONE,
3856
+ CHART_TRACK,
3857
+ Card,
3858
+ CardAction,
3859
+ CardBody,
3860
+ CardDescription,
3861
+ CardFooter,
3862
+ CardHeader,
3863
+ CardTitle,
3864
+ ChartLegend,
3865
+ CheckIndicator,
3866
+ Checkbox,
3867
+ CheckedGroupList,
3868
+ ChecklistRow,
3869
+ ConfirmDialog,
3870
+ CountBadge,
3871
+ DEFAULT_SCORE_THRESHOLDS,
1274
3872
  DataTable,
1275
- DocumentRow,
3873
+ DatePicker,
3874
+ DonutChart,
3875
+ Drawer,
3876
+ DropdownMenu,
3877
+ EmptyState,
3878
+ EntityIconBadge,
3879
+ EyebrowLabel,
1276
3880
  FileDropZone,
3881
+ FileRow,
3882
+ FilterBar,
1277
3883
  FormCard,
1278
3884
  FormCardFooter,
1279
3885
  FormCardHeader,
1280
3886
  IconButton,
3887
+ IconTextRow,
3888
+ InlineAlert,
1281
3889
  Input,
1282
- MetricCard,
3890
+ LegendDot,
3891
+ ListRow,
3892
+ MetaField,
3893
+ MetaFieldGrid,
3894
+ MiniBarChart,
1283
3895
  Modal,
3896
+ ModalBody,
3897
+ ModalDescription,
3898
+ ModalFooter,
3899
+ ModalHeader,
3900
+ ModalTitle,
1284
3901
  MultiSelectCard,
1285
3902
  NavItem,
1286
- Panel,
3903
+ NoteConfirmModal,
3904
+ NumberedStepsList,
3905
+ OVERLAY_SCRIM,
3906
+ PageHeading,
3907
+ PageToolbar,
3908
+ PasswordInput,
3909
+ ProgressBar,
3910
+ QuickActionsBar,
1287
3911
  ROLE_COMBO_OPTIONS,
3912
+ RadialGauge,
3913
+ RankedRow,
1288
3914
  RoleBadge,
1289
3915
  RoleComboBox,
1290
- SectionHeading,
3916
+ ScoreValue,
3917
+ ScoredRow,
3918
+ SegmentedControl,
1291
3919
  Select,
1292
- SentimentBadge,
1293
- SeverityBadge,
3920
+ SolidAlertTriangle,
3921
+ SolidArrowRight,
3922
+ SolidChartBar,
3923
+ SolidCheck,
3924
+ SolidClock,
3925
+ SolidGlobe,
3926
+ SolidInfoCircle,
3927
+ SolidMapPin,
3928
+ SolidShieldCheck,
3929
+ Sparkline,
3930
+ StatNumber,
1294
3931
  StatTile,
3932
+ StatusBadge,
3933
+ StatusChip,
3934
+ StatusDot,
1295
3935
  Stepper,
1296
3936
  TableCellBadge,
1297
3937
  TableCellLeadText,
1298
3938
  TableCellProgress,
1299
- TableCellStatusPill,
1300
3939
  TableCellText,
3940
+ Tabs,
3941
+ TagPill,
1301
3942
  Textarea,
1302
- Toggle
3943
+ TileGrid,
3944
+ Toggle,
3945
+ TrailChip,
3946
+ TrendLabel,
3947
+ UserStatusPill,
3948
+ WidgetFooter,
3949
+ WidgetHeader,
3950
+ WidgetTitle,
3951
+ cn,
3952
+ getScoreTone,
3953
+ resolveChartColor,
3954
+ useOverlayDismiss
1303
3955
  };
1304
3956
  //# sourceMappingURL=index.js.map