@refraction-ui/react 0.20.1 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/dist/{chunk-ZF3OHCGV.js → chunk-2Q6HHFAN.js} +1 -1
  2. package/dist/chunk-2Q6HHFAN.js.map +7 -0
  3. package/dist/{chunk-533MCMSU.js → chunk-3I3DYDHR.js} +2 -2
  4. package/dist/{chunk-F7B64KT3.js → chunk-3Y2T26QD.js} +13 -7
  5. package/dist/chunk-3Y2T26QD.js.map +7 -0
  6. package/dist/{chunk-H54FLNAF.js → chunk-63N4PZUJ.js} +2 -2
  7. package/dist/{chunk-Y2FNNAIL.js → chunk-EGVPAMQU.js} +2 -2
  8. package/dist/chunk-EGVPAMQU.js.map +1 -0
  9. package/dist/{chunk-WK2IIUFO.js → chunk-QDMLIDYN.js} +2 -2
  10. package/dist/{chunk-BOLFYVI6.js → chunk-QPCKJ2YR.js} +2 -2
  11. package/dist/{chunk-TOZBR4GL.js → chunk-RSWOLRIC.js} +4 -4
  12. package/dist/{chunk-TOZBR4GL.js.map → chunk-RSWOLRIC.js.map} +1 -1
  13. package/dist/{chunk-UNEM2TRI.js → chunk-SDAJVXD4.js} +2 -2
  14. package/dist/{chunk-VK3EQ34F.js → chunk-V24GDHUX.js} +2 -2
  15. package/dist/{chunk-AMK4VCBG.js → chunk-WYKPPK3W.js} +2 -2
  16. package/dist/{chunk-ONACRMG4.js → chunk-XMFNBOPO.js} +2 -2
  17. package/dist/form.cjs.map +1 -1
  18. package/dist/form.js +1 -1
  19. package/dist/index.cjs +632 -47
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +4 -0
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.js +4 -0
  24. package/dist/internal/action-list/index.d.ts +39 -0
  25. package/dist/internal/badge/index.d.cts +2 -2
  26. package/dist/internal/badge/index.d.ts +2 -2
  27. package/dist/internal/button/index.d.cts +4 -4
  28. package/dist/internal/button/index.d.ts +4 -4
  29. package/dist/internal/card/index.d.cts +14 -2
  30. package/dist/internal/card/index.d.ts +14 -2
  31. package/dist/internal/funnel-chart/index.d.ts +60 -0
  32. package/dist/internal/line-chart/index.d.ts +110 -0
  33. package/dist/internal/page-header/index.d.ts +35 -0
  34. package/dist/internal/react-action-list/index.d.ts +28 -0
  35. package/dist/internal/react-card/index.d.cts +12 -3
  36. package/dist/internal/react-card/index.d.ts +12 -3
  37. package/dist/internal/react-funnel-chart/index.d.ts +28 -0
  38. package/dist/internal/react-line-chart/index.d.ts +33 -0
  39. package/dist/internal/react-page-header/index.d.ts +23 -0
  40. package/dist/internal/react-select/index.d.cts +21 -3
  41. package/dist/internal/react-select/index.d.ts +21 -3
  42. package/dist/internal/react-separator/index.d.cts +6 -1
  43. package/dist/internal/react-separator/index.d.ts +6 -1
  44. package/dist/internal/select/index.d.cts +14 -1
  45. package/dist/internal/select/index.d.ts +14 -1
  46. package/dist/internal/separator/index.d.cts +6 -1
  47. package/dist/internal/separator/index.d.ts +6 -1
  48. package/dist/internal/shared/index.d.cts +6 -3
  49. package/dist/internal/shared/index.d.ts +6 -3
  50. package/dist/internal/tabs/index.d.cts +8 -1
  51. package/dist/internal/tabs/index.d.ts +8 -1
  52. package/dist/react-accordion.js +1 -1
  53. package/dist/react-action-list.js +74 -0
  54. package/dist/react-action-list.js.map +7 -0
  55. package/dist/react-ai.js +1 -1
  56. package/dist/react-analytics.js +1 -1
  57. package/dist/react-animated-text.js +1 -1
  58. package/dist/react-app-shell.js +1 -1
  59. package/dist/react-audience-feature-card.js +1 -1
  60. package/dist/react-audio-room.js +1 -1
  61. package/dist/react-auth.js +1 -1
  62. package/dist/react-avatar-group.js +1 -1
  63. package/dist/react-avatar.js +1 -1
  64. package/dist/react-badge.js +16 -4
  65. package/dist/react-badge.js.map +2 -2
  66. package/dist/react-bottom-nav.js +1 -1
  67. package/dist/react-brand-network-cell.js +1 -1
  68. package/dist/react-breadcrumbs.js +1 -1
  69. package/dist/react-browser-chrome-mock.js +1 -1
  70. package/dist/react-browser-chrome-mock.js.map +2 -2
  71. package/dist/react-button.js +3 -3
  72. package/dist/react-calendar.js +1 -1
  73. package/dist/react-call-controls.js +1 -1
  74. package/dist/react-callout.js +8 -3
  75. package/dist/react-callout.js.map +2 -2
  76. package/dist/react-card-grid.js +1 -1
  77. package/dist/react-card.js +15 -6
  78. package/dist/react-card.js.map +2 -2
  79. package/dist/react-carousel.js +1 -1
  80. package/dist/react-charts.js +1 -1
  81. package/dist/react-checkbox.js +1 -1
  82. package/dist/react-checklist.js +1 -1
  83. package/dist/react-code-block.js +1 -1
  84. package/dist/react-code-editor.js +1 -1
  85. package/dist/react-collapsible.js +1 -1
  86. package/dist/react-combobox.js +1 -1
  87. package/dist/react-command-input.js +1 -1
  88. package/dist/react-command.js +1 -1
  89. package/dist/react-composer.js +3 -3
  90. package/dist/react-content-protection.js +1 -1
  91. package/dist/react-conversation.js +5 -5
  92. package/dist/react-cookie-consent.js +1 -1
  93. package/dist/react-data-table.js +1 -1
  94. package/dist/react-date-picker.js +1 -1
  95. package/dist/react-device-frame.js +1 -1
  96. package/dist/react-dialog.js +2 -2
  97. package/dist/react-diff-viewer.js +4 -1
  98. package/dist/react-diff-viewer.js.map +2 -2
  99. package/dist/react-dropdown-menu.js +1 -1
  100. package/dist/react-editor-status-bar.js +1 -1
  101. package/dist/react-editor-tabs.js +1 -1
  102. package/dist/react-emoji-picker.js +2 -2
  103. package/dist/react-empty-state.js +1 -1
  104. package/dist/react-feedback-dialog.js +2 -2
  105. package/dist/react-file-tree.js +1 -1
  106. package/dist/react-file-upload.js +1 -1
  107. package/dist/react-floating-reactions.js +1 -1
  108. package/dist/react-flow-editor.js +2 -2
  109. package/dist/react-footer.js +1 -1
  110. package/dist/react-funnel-chart.js +105 -0
  111. package/dist/react-funnel-chart.js.map +7 -0
  112. package/dist/react-graph-view.js +2 -2
  113. package/dist/react-infinite-canvas.js +2 -2
  114. package/dist/react-inline-editor.js +1 -1
  115. package/dist/react-input-group.js +1 -1
  116. package/dist/react-input.js +2 -2
  117. package/dist/react-install-prompt.js +1 -1
  118. package/dist/react-kanban-board.js +1 -1
  119. package/dist/react-keyboard-shortcut.js +2 -2
  120. package/dist/react-language-selector.js +1 -1
  121. package/dist/react-line-chart.js +242 -0
  122. package/dist/react-line-chart.js.map +7 -0
  123. package/dist/react-link-card.js +1 -1
  124. package/dist/react-live-captions.js +1 -1
  125. package/dist/react-live-cursors.js +1 -1
  126. package/dist/react-live-transcript.js +1 -1
  127. package/dist/react-location-selector.js +1 -1
  128. package/dist/react-logger.js +1 -1
  129. package/dist/react-markdown-renderer.js +2 -2
  130. package/dist/react-marquee-strip.js +1 -1
  131. package/dist/react-mascot.js +1 -1
  132. package/dist/react-mastery-bar.js +1 -1
  133. package/dist/react-mini-map.js +1 -1
  134. package/dist/react-mobile-nav.js +1 -1
  135. package/dist/react-navbar.js +1 -1
  136. package/dist/react-numbered-steps.js +1 -1
  137. package/dist/react-otp-input.js +1 -1
  138. package/dist/react-page-header.js +40 -0
  139. package/dist/react-page-header.js.map +7 -0
  140. package/dist/react-pagination.js +1 -1
  141. package/dist/react-password-input.js +2 -2
  142. package/dist/react-payment.js +1 -1
  143. package/dist/react-popover.js +1 -1
  144. package/dist/react-pre-call-lobby.js +1 -1
  145. package/dist/react-presence-indicator.js +1 -1
  146. package/dist/react-pricing-card.js +1 -1
  147. package/dist/react-progress-display.js +2 -2
  148. package/dist/react-progress-display.js.map +1 -1
  149. package/dist/react-radial-gauge.js +1 -1
  150. package/dist/react-radio.js +1 -1
  151. package/dist/react-rating-scale.js +1 -1
  152. package/dist/react-reaction-bar.js +1 -1
  153. package/dist/react-resizable-layout.js +1 -1
  154. package/dist/react-search-bar.js +1 -1
  155. package/dist/react-section-head.js +1 -1
  156. package/dist/react-segmented-control.js +1 -1
  157. package/dist/react-select.js +94 -20
  158. package/dist/react-select.js.map +3 -3
  159. package/dist/react-separator.js +19 -7
  160. package/dist/react-separator.js.map +2 -2
  161. package/dist/react-sheet.js +1 -1
  162. package/dist/react-sidebar.js +1 -1
  163. package/dist/react-skeleton.js +1 -1
  164. package/dist/react-skip-to-content.js +1 -1
  165. package/dist/react-slide-viewer.js +3 -1
  166. package/dist/react-slide-viewer.js.map +2 -2
  167. package/dist/react-slider.js +1 -1
  168. package/dist/react-slot-picker.js +1 -1
  169. package/dist/react-social-auth-button.js +3 -3
  170. package/dist/react-sortable-list.js +1 -1
  171. package/dist/react-stat-grid.js +1 -1
  172. package/dist/react-status-indicator.js +1 -1
  173. package/dist/react-steps.js +1 -1
  174. package/dist/react-sticky-note.js +3 -1
  175. package/dist/react-sticky-note.js.map +2 -2
  176. package/dist/react-switch.js +1 -1
  177. package/dist/react-table-of-contents.js +1 -1
  178. package/dist/react-tabs.js +50 -2
  179. package/dist/react-tabs.js.map +2 -2
  180. package/dist/react-terminal.js +1 -1
  181. package/dist/react-test-results.js +1 -1
  182. package/dist/react-textarea.js +3 -3
  183. package/dist/react-textarea.js.map +1 -1
  184. package/dist/react-thread-view.js +2 -2
  185. package/dist/react-timeline.js +1 -1
  186. package/dist/react-toast.js +1 -1
  187. package/dist/react-tooltip.js +1 -1
  188. package/dist/react-version-selector.js +1 -1
  189. package/dist/react-video-grid.js +2 -2
  190. package/dist/react-video-player.js +1 -1
  191. package/dist/react-video-tile.js +2 -2
  192. package/dist/react-voice-pill.js +1 -1
  193. package/dist/react-waveform.js +1 -1
  194. package/dist/react-wizard.js +1 -1
  195. package/dist/styles.css +48 -0
  196. package/dist/theme.js +1 -1
  197. package/package.json +5 -1
  198. package/dist/chunk-F7B64KT3.js.map +0 -7
  199. package/dist/chunk-Y2FNNAIL.js.map +0 -1
  200. package/dist/chunk-ZF3OHCGV.js.map +0 -7
  201. /package/dist/{chunk-533MCMSU.js.map → chunk-3I3DYDHR.js.map} +0 -0
  202. /package/dist/{chunk-H54FLNAF.js.map → chunk-63N4PZUJ.js.map} +0 -0
  203. /package/dist/{chunk-WK2IIUFO.js.map → chunk-QDMLIDYN.js.map} +0 -0
  204. /package/dist/{chunk-BOLFYVI6.js.map → chunk-QPCKJ2YR.js.map} +0 -0
  205. /package/dist/{chunk-UNEM2TRI.js.map → chunk-SDAJVXD4.js.map} +0 -0
  206. /package/dist/{chunk-VK3EQ34F.js.map → chunk-V24GDHUX.js.map} +0 -0
  207. /package/dist/{chunk-AMK4VCBG.js.map → chunk-WYKPPK3W.js.map} +0 -0
  208. /package/dist/{chunk-ONACRMG4.js.map → chunk-XMFNBOPO.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -1751,7 +1751,14 @@ function AuthGuard({
1751
1751
  }
1752
1752
 
1753
1753
  // ../badge/dist/index.js
1754
- var statusVariants = ["success", "warning", "destructive"];
1754
+ var statusVariants = [
1755
+ "success",
1756
+ "warning",
1757
+ "destructive",
1758
+ "positive",
1759
+ "caution",
1760
+ "done"
1761
+ ];
1755
1762
  function createBadge(props = {}) {
1756
1763
  const { variant = "default" } = props;
1757
1764
  const ariaProps = {};
@@ -1766,7 +1773,7 @@ function createBadge(props = {}) {
1766
1773
  };
1767
1774
  }
1768
1775
  var badgeVariants = cva({
1769
- base: "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
1776
+ base: "inline-flex items-center rounded-full border font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
1770
1777
  variants: {
1771
1778
  variant: {
1772
1779
  default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
@@ -1775,7 +1782,12 @@ var badgeVariants = cva({
1775
1782
  destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80 font-semibold",
1776
1783
  outline: "text-foreground",
1777
1784
  success: "border-transparent bg-success text-success-foreground shadow hover:bg-success/80 font-semibold",
1778
- warning: "border-transparent bg-warning text-warning-foreground shadow hover:bg-warning/80 font-semibold"
1785
+ warning: "border-transparent bg-warning text-warning-foreground shadow hover:bg-warning/80 font-semibold",
1786
+ // Second brand accent + extended status roles (issue #485).
1787
+ tertiary: "border-transparent bg-tertiary text-tertiary-foreground shadow hover:bg-tertiary/80 font-semibold",
1788
+ positive: "border-transparent bg-positive text-positive-foreground shadow hover:bg-positive/80 font-semibold",
1789
+ caution: "border-transparent bg-caution text-caution-foreground shadow hover:bg-caution/80 font-semibold",
1790
+ done: "border-transparent bg-done text-info-foreground shadow hover:bg-done/80 font-semibold"
1779
1791
  },
1780
1792
  size: {
1781
1793
  sm: "px-2 py-0 text-[10px]",
@@ -2060,7 +2072,7 @@ var buttonTokens = {
2060
2072
  }
2061
2073
  };
2062
2074
  var buttonVariants = cva({
2063
- base: "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
2075
+ base: "inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
2064
2076
  variants: {
2065
2077
  variant: {
2066
2078
  default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
@@ -2071,15 +2083,21 @@ var buttonVariants = cva({
2071
2083
  destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
2072
2084
  outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
2073
2085
  secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
2086
+ // Soft tinted brand fill — lower-emphasis primary action (issue #485).
2087
+ soft: "bg-primary-soft text-primary-soft-foreground shadow-sm hover:bg-primary-soft/80",
2088
+ // Second brand accent (issue #485).
2089
+ tertiary: "bg-tertiary text-tertiary-foreground shadow-sm hover:bg-tertiary/90",
2074
2090
  ghost: "hover:bg-accent hover:text-accent-foreground",
2075
2091
  link: "text-primary underline-offset-4 hover:underline"
2076
2092
  },
2077
2093
  size: {
2078
2094
  xs: "h-7 rounded px-2 text-xs",
2079
2095
  sm: "h-8 rounded-md px-3 text-xs",
2080
- default: "h-9 px-4 py-2",
2081
- lg: "h-10 rounded-md px-8",
2082
- icon: "h-9 w-9"
2096
+ default: "h-9 rounded-md px-4 py-2 text-sm",
2097
+ lg: "h-10 rounded-md px-8 text-sm",
2098
+ icon: "h-9 w-9 rounded-md text-sm",
2099
+ "icon-sm": "h-8 w-8 rounded-md text-xs",
2100
+ "icon-xs": "h-7 w-7 rounded text-xs"
2083
2101
  }
2084
2102
  },
2085
2103
  defaultVariants: {
@@ -12427,11 +12445,11 @@ function createInput(props = {}) {
12427
12445
  };
12428
12446
  }
12429
12447
  var inputVariants = cva({
12430
- base: "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
12448
+ base: "flex w-full rounded-md border border-input bg-transparent px-3 py-1 shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
12431
12449
  variants: {
12432
12450
  size: {
12433
12451
  sm: "h-8 text-xs",
12434
- default: "h-9",
12452
+ default: "h-9 text-sm",
12435
12453
  lg: "h-10 text-base"
12436
12454
  },
12437
12455
  validationState: {
@@ -14578,6 +14596,23 @@ function createTabs(props = {}) {
14578
14596
  idPrefix
14579
14597
  };
14580
14598
  }
14599
+ function getNextTabIndex(current, key, count, orientation = "horizontal") {
14600
+ if (count === 0) return null;
14601
+ const prev = orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
14602
+ const next = orientation === "horizontal" ? "ArrowRight" : "ArrowDown";
14603
+ switch (key) {
14604
+ case next:
14605
+ return current < 0 ? 0 : (current + 1) % count;
14606
+ case prev:
14607
+ return current < 0 ? count - 1 : (current - 1 + count) % count;
14608
+ case "Home":
14609
+ return 0;
14610
+ case "End":
14611
+ return count - 1;
14612
+ default:
14613
+ return null;
14614
+ }
14615
+ }
14581
14616
  var tabsListVariants = cva({
14582
14617
  base: "inline-flex max-w-full overflow-x-auto items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground"
14583
14618
  });
@@ -14634,17 +14669,48 @@ var Tabs = React52__namespace.forwardRef(
14634
14669
  }
14635
14670
  );
14636
14671
  var TabsList = React52__namespace.forwardRef(
14637
- function TabsList2({ className, ...props }, ref) {
14672
+ function TabsList2({ className, onKeyDown, ...props }, forwardedRef) {
14638
14673
  const { orientation } = useTabsContext();
14674
+ const listRef = React52__namespace.useRef(null);
14675
+ const ref = React52__namespace.useCallback(
14676
+ (node) => {
14677
+ listRef.current = node;
14678
+ if (typeof forwardedRef === "function") forwardedRef(node);
14679
+ else if (forwardedRef) forwardedRef.current = node;
14680
+ },
14681
+ [forwardedRef]
14682
+ );
14683
+ React52__namespace.useEffect(() => {
14684
+ const tabs = enabledTabs(listRef.current);
14685
+ const stop = tabs.find((tab) => tab.getAttribute("aria-selected") === "true") ?? tabs[0];
14686
+ for (const tab of tabs) tab.tabIndex = tab === stop ? 0 : -1;
14687
+ });
14688
+ const handleKeyDown = (e) => {
14689
+ onKeyDown?.(e);
14690
+ if (e.defaultPrevented) return;
14691
+ const tabs = enabledTabs(listRef.current);
14692
+ const current = tabs.indexOf(e.target);
14693
+ if (current === -1) return;
14694
+ const next = getNextTabIndex(current, e.key, tabs.length, orientation);
14695
+ if (next === null) return;
14696
+ e.preventDefault();
14697
+ tabs[next].focus();
14698
+ tabs[next].click();
14699
+ };
14639
14700
  return React52__namespace.createElement("div", {
14640
14701
  ref,
14641
14702
  role: "tablist",
14642
14703
  "aria-orientation": orientation,
14643
14704
  className: cn(tabsListVariants(), className),
14705
+ onKeyDown: handleKeyDown,
14644
14706
  ...props
14645
14707
  });
14646
14708
  }
14647
14709
  );
14710
+ function enabledTabs(list) {
14711
+ if (!list) return [];
14712
+ return Array.from(list.querySelectorAll('[role="tab"]:not([disabled])'));
14713
+ }
14648
14714
  var TabsTrigger = React52__namespace.forwardRef(
14649
14715
  function TabsTrigger2({ value, className, onClick, onKeyDown, children, ...props }, ref) {
14650
14716
  const { value: activeValue, onValueChange, orientation, idPrefix } = useTabsContext();
@@ -14736,11 +14802,11 @@ function createTextarea(props = {}) {
14736
14802
  };
14737
14803
  }
14738
14804
  var textareaVariants = cva({
14739
- base: "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
14805
+ base: "flex w-full rounded-md border border-input bg-transparent px-3 py-2 shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
14740
14806
  variants: {
14741
14807
  size: {
14742
14808
  sm: "min-h-[40px] text-xs",
14743
- default: "min-h-[60px]",
14809
+ default: "min-h-[60px] text-sm",
14744
14810
  lg: "min-h-[80px] text-base"
14745
14811
  }
14746
14812
  },
@@ -16277,7 +16343,7 @@ var badgeItemVariants = cva({
16277
16343
  }
16278
16344
  });
16279
16345
  var progressBarVariants = cva({
16280
- base: "h-2 w-full overflow-hidden rounded-full bg-secondary",
16346
+ base: "w-full overflow-hidden rounded-full bg-secondary",
16281
16347
  variants: {
16282
16348
  size: {
16283
16349
  sm: "h-1",
@@ -16496,6 +16562,8 @@ var slideViewerProgressBarVariants = cva({
16496
16562
  var slideTypeBadgeVariants = cva({
16497
16563
  base: "inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium",
16498
16564
  variants: {
16565
+ // Slide-type accents are a content-category palette (lesson/quiz/exercise…),
16566
+ // not status tones — deliberately not routed through the theme tokens.
16499
16567
  type: {
16500
16568
  lesson: "bg-blue-100 text-blue-800",
16501
16569
  quiz: "bg-purple-100 text-purple-800",
@@ -18200,6 +18268,9 @@ var diffViewerTokens = {
18200
18268
  sidebarBg: { variable: "--rfr-diff-sidebar-bg", fallback: "hsl(var(--muted))" },
18201
18269
  headerBg: { variable: "--rfr-diff-header-bg", fallback: "hsl(var(--muted))" },
18202
18270
  border: { variable: "--rfr-diff-border", fallback: "hsl(var(--border))" },
18271
+ // Diff add/del colors are syntax semantics (like code highlighting), not
18272
+ // theme status tones — deliberately NOT routed through the success/
18273
+ // destructive tokens. The --rfr-diff-* variables are the theming seam.
18203
18274
  addBg: { variable: "--rfr-diff-add-bg", fallback: "rgba(46, 160, 67, 0.15)" },
18204
18275
  delBg: { variable: "--rfr-diff-del-bg", fallback: "rgba(248, 81, 73, 0.15)" },
18205
18276
  addFg: { variable: "--rfr-diff-add-fg", fallback: "#3fb950" },
@@ -18807,8 +18878,16 @@ var cardTokens = {
18807
18878
  }
18808
18879
  };
18809
18880
  var cardVariants = cva({
18810
- base: "rounded-lg border bg-card text-card-foreground shadow",
18881
+ base: "rounded-lg border shadow",
18811
18882
  variants: {
18883
+ variant: {
18884
+ // Default — unchanged surface (bg-card + border via the global token).
18885
+ default: "bg-card text-card-foreground",
18886
+ // Lower-emphasis container on the subtle surface token (issue #485).
18887
+ subtle: "bg-surface-subtle text-card-foreground",
18888
+ // Tinted second-accent card (issue #485).
18889
+ tertiary: "border-transparent bg-tertiary-soft text-tertiary-soft-foreground"
18890
+ },
18812
18891
  padding: {
18813
18892
  none: "",
18814
18893
  default: "p-6",
@@ -18816,6 +18895,7 @@ var cardVariants = cva({
18816
18895
  }
18817
18896
  },
18818
18897
  defaultVariants: {
18898
+ variant: "default",
18819
18899
  padding: "none"
18820
18900
  }
18821
18901
  });
@@ -18845,9 +18925,9 @@ var cardFooterVariants = cva({
18845
18925
  base: "flex items-center p-6 pt-0"
18846
18926
  });
18847
18927
  var Card = React52__namespace.forwardRef(
18848
- function Card2({ className, asChild = false, ...props }, ref) {
18928
+ function Card2({ className, variant, padding, asChild = false, ...props }, ref) {
18849
18929
  const api = createCard();
18850
- const classes = cn(cardVariants(), className);
18930
+ const classes = cn(cardVariants({ variant, padding }), className);
18851
18931
  if (asChild) {
18852
18932
  return /* @__PURE__ */ jsxRuntime.jsx(
18853
18933
  Slot,
@@ -18887,10 +18967,10 @@ var CardHeader = React52__namespace.forwardRef(
18887
18967
  }
18888
18968
  );
18889
18969
  var CardTitle = React52__namespace.forwardRef(
18890
- function CardTitle2({ className, ...props }, ref) {
18970
+ function CardTitle2({ className, as: Heading = "h3", ...props }, ref) {
18891
18971
  const api = createCardTitle();
18892
18972
  return /* @__PURE__ */ jsxRuntime.jsx(
18893
- "h3",
18973
+ Heading,
18894
18974
  {
18895
18975
  ref,
18896
18976
  className: cn(cardTitleVariants(), className),
@@ -20449,13 +20529,12 @@ function createSelect(props = {}) {
20449
20529
  } = props;
20450
20530
  const isInteractive = !disabled;
20451
20531
  const selectedOption = options.find((o) => o.value === value);
20452
- const triggerId = generateId("select-trigger");
20453
- const contentId = generateId("select-content");
20532
+ const triggerId = props.ids?.trigger ?? generateId("select-trigger");
20533
+ const contentId = props.ids?.content ?? generateId("select-content");
20454
20534
  const triggerAriaProps = {
20455
20535
  role: "combobox",
20456
20536
  "aria-expanded": open,
20457
- "aria-controls": contentId,
20458
- "aria-labelledby": triggerId
20537
+ "aria-controls": contentId
20459
20538
  };
20460
20539
  if (disabled) {
20461
20540
  triggerAriaProps["aria-disabled"] = true;
@@ -20537,7 +20616,7 @@ var selectTokens = {
20537
20616
  }
20538
20617
  };
20539
20618
  var selectTriggerVariants = cva({
20540
- base: "flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
20619
+ base: "flex w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
20541
20620
  variants: {
20542
20621
  size: {
20543
20622
  sm: "h-8 text-xs",
@@ -20550,10 +20629,10 @@ var selectTriggerVariants = cva({
20550
20629
  }
20551
20630
  });
20552
20631
  var selectContentVariants = cva({
20553
- base: "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95",
20632
+ base: "absolute left-0 top-full z-50 mt-1 max-h-96 w-full min-w-[8rem] overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95",
20554
20633
  variants: {
20555
20634
  position: {
20556
- popper: "translate-y-1",
20635
+ popper: "",
20557
20636
  "item-aligned": ""
20558
20637
  }
20559
20638
  },
@@ -20573,6 +20652,8 @@ var selectItemVariants = cva({
20573
20652
  selected: "false"
20574
20653
  }
20575
20654
  });
20655
+ var selectRootClass = "relative";
20656
+ var selectValueClass = "truncate text-left data-[placeholder]:text-muted-foreground";
20576
20657
  var SelectContext = React52__namespace.createContext({
20577
20658
  __isDefault: true,
20578
20659
  value: void 0,
@@ -20585,7 +20666,10 @@ var SelectContext = React52__namespace.createContext({
20585
20666
  disabled: false,
20586
20667
  placeholder: "Select an option",
20587
20668
  triggerId: "",
20588
- contentId: ""
20669
+ contentId: "",
20670
+ labels: /* @__PURE__ */ new Map(),
20671
+ registerLabel: () => {
20672
+ }
20589
20673
  });
20590
20674
  function useSelectContext(part) {
20591
20675
  const ctx = React52__namespace.useContext(SelectContext);
@@ -20597,22 +20681,70 @@ function useSelectContext(part) {
20597
20681
  }
20598
20682
  return ctx;
20599
20683
  }
20684
+ function collectItemLabels(node, into) {
20685
+ React52__namespace.Children.forEach(node, (child) => {
20686
+ if (!React52__namespace.isValidElement(child)) return;
20687
+ if (child.type === SelectItem && typeof child.props.value === "string") {
20688
+ into.set(child.props.value, child.props.children);
20689
+ return;
20690
+ }
20691
+ collectItemLabels(child.props.children, into);
20692
+ });
20693
+ return into;
20694
+ }
20600
20695
  function Select({
20601
- value,
20696
+ value: controlledValue,
20697
+ defaultValue,
20602
20698
  onValueChange,
20603
20699
  disabled = false,
20604
20700
  children,
20605
- placeholder = "Select an option"
20701
+ placeholder = "Select an option",
20702
+ className
20606
20703
  }) {
20607
20704
  const [open, setOpen] = React52__namespace.useState(false);
20608
- const api = createSelect({ value, disabled, open, placeholder });
20705
+ const [uncontrolledValue, setUncontrolledValue] = React52__namespace.useState(defaultValue);
20706
+ const isControlled = controlledValue !== void 0;
20707
+ const value = isControlled ? controlledValue : uncontrolledValue;
20708
+ const rootRef = React52__namespace.useRef(null);
20709
+ const baseId = React52__namespace.useId();
20710
+ const triggerId = `${baseId}-trigger`;
20711
+ const contentId = `${baseId}-content`;
20712
+ const [registered, setRegistered] = React52__namespace.useState(
20713
+ () => /* @__PURE__ */ new Map()
20714
+ );
20715
+ const registerLabel = React52__namespace.useCallback((itemValue, label) => {
20716
+ setRegistered((prev) => {
20717
+ if (prev.get(itemValue) === label) return prev;
20718
+ const next = new Map(prev);
20719
+ next.set(itemValue, label);
20720
+ return next;
20721
+ });
20722
+ }, []);
20723
+ const labels = React52__namespace.useMemo(
20724
+ () => collectItemLabels(children, new Map(registered)),
20725
+ [children, registered]
20726
+ );
20727
+ React52__namespace.useEffect(() => {
20728
+ if (!open) return;
20729
+ const onPointerDown = (event) => {
20730
+ if (rootRef.current && !rootRef.current.contains(event.target)) setOpen(false);
20731
+ };
20732
+ document.addEventListener("pointerdown", onPointerDown);
20733
+ return () => document.removeEventListener("pointerdown", onPointerDown);
20734
+ }, [open]);
20735
+ const handleValueChange = React52__namespace.useCallback(
20736
+ (next) => {
20737
+ if (!isControlled) setUncontrolledValue(next);
20738
+ onValueChange?.(next);
20739
+ },
20740
+ [isControlled, onValueChange]
20741
+ );
20609
20742
  return /* @__PURE__ */ jsxRuntime.jsx(
20610
20743
  SelectContext.Provider,
20611
20744
  {
20612
20745
  value: {
20613
20746
  value,
20614
- onValueChange: onValueChange ?? (() => {
20615
- }),
20747
+ onValueChange: handleValueChange,
20616
20748
  open,
20617
20749
  setOpen: (v2) => {
20618
20750
  if (!disabled) setOpen(v2);
@@ -20620,17 +20752,19 @@ function Select({
20620
20752
  options: [],
20621
20753
  disabled,
20622
20754
  placeholder,
20623
- triggerId: api.ids.trigger,
20624
- contentId: api.ids.content
20755
+ triggerId,
20756
+ contentId,
20757
+ labels,
20758
+ registerLabel
20625
20759
  },
20626
- children
20760
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: rootRef, className: cn(selectRootClass, className), "data-slot": "select", children })
20627
20761
  }
20628
20762
  );
20629
20763
  }
20630
20764
  var SelectTrigger = React52__namespace.forwardRef(
20631
20765
  function SelectTrigger2({ className, children, size = "default", ...props }, ref) {
20632
20766
  const { open, setOpen, disabled, triggerId, contentId } = useSelectContext("SelectTrigger");
20633
- const api = createSelect({ disabled, open });
20767
+ const api = createSelect({ disabled, open, ids: { trigger: triggerId, content: contentId } });
20634
20768
  const handleClick = () => {
20635
20769
  if (!disabled) {
20636
20770
  setOpen(!open);
@@ -20661,7 +20795,6 @@ var SelectTrigger = React52__namespace.forwardRef(
20661
20795
  disabled,
20662
20796
  ...api.triggerProps.ariaProps,
20663
20797
  ...api.triggerProps.dataAttributes,
20664
- "aria-controls": contentId,
20665
20798
  ...props,
20666
20799
  children: [
20667
20800
  children,
@@ -20747,8 +20880,11 @@ var SelectContent = React52__namespace.forwardRef(
20747
20880
  );
20748
20881
  var SelectItem = React52__namespace.forwardRef(
20749
20882
  function SelectItem2({ className, children, value: itemValue, disabled: itemDisabled = false, ...props }, ref) {
20750
- const { value, onValueChange, setOpen, triggerId } = useSelectContext("SelectItem");
20883
+ const { value, onValueChange, setOpen, triggerId, registerLabel } = useSelectContext("SelectItem");
20751
20884
  const isSelected = value === itemValue;
20885
+ React52__namespace.useEffect(() => {
20886
+ registerLabel(itemValue, children);
20887
+ }, [registerLabel, itemValue, children]);
20752
20888
  const handleClick = () => {
20753
20889
  if (!itemDisabled) {
20754
20890
  onValueChange(itemValue);
@@ -20802,6 +20938,23 @@ var SelectItem = React52__namespace.forwardRef(
20802
20938
  );
20803
20939
  }
20804
20940
  );
20941
+ var SelectValue = React52__namespace.forwardRef(
20942
+ function SelectValue2({ placeholder, className, children, ...props }, ref) {
20943
+ const ctx = useSelectContext("SelectValue");
20944
+ const label = ctx.value !== void 0 ? ctx.labels.get(ctx.value) : void 0;
20945
+ const showPlaceholder = children == null && label === void 0;
20946
+ return /* @__PURE__ */ jsxRuntime.jsx(
20947
+ "span",
20948
+ {
20949
+ ref,
20950
+ className: cn(selectValueClass, className),
20951
+ "data-placeholder": showPlaceholder ? "" : void 0,
20952
+ ...props,
20953
+ children: children ?? (showPlaceholder ? placeholder ?? ctx.placeholder : label)
20954
+ }
20955
+ );
20956
+ }
20957
+ );
20805
20958
 
20806
20959
  // ../status-indicator/dist/index.js
20807
20960
  var STATUS_INDICATOR_COLORS = {
@@ -21583,7 +21736,9 @@ function createCallout(props = {}) {
21583
21736
  const ariaProps = {};
21584
21737
  if (props.role) {
21585
21738
  ariaProps.role = props.role;
21586
- } else {
21739
+ } else if (props.destructive) {
21740
+ ariaProps.role = "alert";
21741
+ } else if (props.labelled) {
21587
21742
  ariaProps.role = "region";
21588
21743
  }
21589
21744
  return {
@@ -21626,7 +21781,10 @@ var calloutDescriptionVariants = cva({
21626
21781
  });
21627
21782
  var Callout = React52__namespace.forwardRef(
21628
21783
  function Callout2({ className, variant, asChild = false, ...props }, ref) {
21629
- const api = createCallout({ role: variant === "destructive" ? "alert" : "region" });
21784
+ const api = createCallout({
21785
+ destructive: variant === "destructive",
21786
+ labelled: Boolean(props["aria-label"] || props["aria-labelledby"])
21787
+ });
21630
21788
  const classes = cn(calloutVariants({ variant }), className);
21631
21789
  if (asChild) {
21632
21790
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -24951,8 +25109,16 @@ var separatorVariants = cva({
24951
25109
  base: "",
24952
25110
  variants: {
24953
25111
  orientation: {
24954
- horizontal: "h-px w-full bg-border",
24955
- vertical: "w-px h-full bg-border"
25112
+ horizontal: "h-px w-full",
25113
+ vertical: "w-px h-full"
25114
+ },
25115
+ // Line color (issue #485). `default` is the standard border token;
25116
+ // `subtle` uses the hairline `border-subtle` token for a lighter rule.
25117
+ // Keeping the color here (not in `orientation`) keeps every existing call
25118
+ // pixel-identical while adding the subtle option.
25119
+ tone: {
25120
+ default: "bg-border",
25121
+ subtle: "bg-border-subtle"
24956
25122
  },
24957
25123
  labeled: {
24958
25124
  true: "flex items-center",
@@ -24961,31 +25127,35 @@ var separatorVariants = cva({
24961
25127
  },
24962
25128
  defaultVariants: {
24963
25129
  orientation: "horizontal",
25130
+ tone: "default",
24964
25131
  labeled: "false"
24965
25132
  }
24966
25133
  });
24967
25134
  var separatorLineClass = "h-px flex-1 bg-border";
25135
+ var separatorSubtleLineClass = "h-px flex-1 bg-border-subtle";
24968
25136
  var separatorLabelClass = "px-3 text-xs uppercase tracking-wide text-muted-foreground";
24969
25137
  var Separator = React52__namespace.forwardRef(
24970
25138
  function Separator2({
24971
25139
  orientation = "horizontal",
25140
+ tone = "default",
24972
25141
  label,
24973
25142
  decorative = true,
24974
25143
  className,
24975
25144
  ...props
24976
25145
  }, ref) {
24977
25146
  if (orientation === "horizontal" && label != null) {
25147
+ const lineClass = tone === "subtle" ? separatorSubtleLineClass : separatorLineClass;
24978
25148
  return /* @__PURE__ */ jsxRuntime.jsxs(
24979
25149
  "div",
24980
25150
  {
24981
25151
  ref,
24982
25152
  role: "none",
24983
- className: cn(separatorVariants({ labeled: "true" }), className),
25153
+ className: cn(separatorVariants({ labeled: "true", tone }), className),
24984
25154
  ...props,
24985
25155
  children: [
24986
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: separatorLineClass }),
25156
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: lineClass }),
24987
25157
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: separatorLabelClass, children: label }),
24988
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: separatorLineClass })
25158
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: lineClass })
24989
25159
  ]
24990
25160
  }
24991
25161
  );
@@ -24998,7 +25168,7 @@ var Separator = React52__namespace.forwardRef(
24998
25168
  "div",
24999
25169
  {
25000
25170
  ref,
25001
- className: cn(separatorVariants({ orientation }), className),
25171
+ className: cn(separatorVariants({ orientation, tone }), className),
25002
25172
  ...ariaProps,
25003
25173
  ...dataAttributes,
25004
25174
  ...props
@@ -25887,7 +26057,7 @@ function createEditorTabs(props = {}) {
25887
26057
  }
25888
26058
  return { ariaProps, dataAttributes };
25889
26059
  }
25890
- function getNextTabIndex(currentIndex, key, count) {
26060
+ function getNextTabIndex2(currentIndex, key, count) {
25891
26061
  if (count <= 0) return currentIndex;
25892
26062
  switch (key) {
25893
26063
  case "ArrowRight":
@@ -25945,7 +26115,7 @@ var EditorTabs = React52__namespace.forwardRef(
25945
26115
  const activeIndex = tabs.findIndex((t) => t.id === activeId);
25946
26116
  const tabbableIndex = activeIndex === -1 ? 0 : activeIndex;
25947
26117
  const handleKeyDown = (event, index2) => {
25948
- const next = getNextTabIndex(index2, event.key, tabs.length);
26118
+ const next = getNextTabIndex2(index2, event.key, tabs.length);
25949
26119
  if (next !== index2) {
25950
26120
  event.preventDefault();
25951
26121
  onSelect(tabs[next].id);
@@ -27707,6 +27877,8 @@ var stickyNoteVariants = cva({
27707
27877
  "min-w-[160px] min-h-[120px]"
27708
27878
  ].join(" "),
27709
27879
  variants: {
27880
+ // Named paper colors are product semantics (physical sticky notes),
27881
+ // not status tones — deliberately not routed through the theme tokens.
27710
27882
  color: {
27711
27883
  yellow: "bg-yellow-100 text-yellow-900",
27712
27884
  pink: "bg-pink-100 text-pink-900",
@@ -29628,11 +29800,420 @@ var SlotPicker = React52__namespace.forwardRef(
29628
29800
  }
29629
29801
  );
29630
29802
 
29803
+ // ../action-list/dist/index.js
29804
+ function createActionListItem(props = {}) {
29805
+ const { disabled = false, density = "default" } = props;
29806
+ const dataAttributes = {
29807
+ "data-slot": "action-list-item",
29808
+ "data-density": density
29809
+ };
29810
+ if (disabled) dataAttributes["data-disabled"] = "";
29811
+ const ariaProps = {};
29812
+ if (disabled) ariaProps["aria-disabled"] = true;
29813
+ return { ariaProps, dataAttributes };
29814
+ }
29815
+ var actionListClass = "m-0 flex list-none flex-col divide-y divide-border-subtle p-0";
29816
+ var actionListItemVariants = cva({
29817
+ base: "flex w-full items-center gap-4 bg-transparent text-left text-sm text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
29818
+ variants: {
29819
+ density: {
29820
+ default: "px-4 py-3",
29821
+ compact: "px-3 py-2"
29822
+ }
29823
+ },
29824
+ defaultVariants: {
29825
+ density: "default"
29826
+ }
29827
+ });
29828
+ var actionListItemBodyClass = "flex min-w-0 flex-1 flex-col gap-0.5";
29829
+ var actionListItemTitleClass = "break-words font-semibold text-foreground";
29830
+ var actionListItemDescriptionClass = "break-words text-xs text-muted-foreground";
29831
+ var actionListItemMetaClass = "break-words text-xs text-muted-foreground";
29832
+ var actionListItemTrailingClass = "flex flex-none items-center gap-4 text-xs tabular-nums text-muted-foreground";
29833
+ var ActionList = React52__namespace.forwardRef(function ActionList2({ className, ...props }, ref) {
29834
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { ref, className: cn(actionListClass, className), "data-slot": "action-list", ...props });
29835
+ });
29836
+ var ActionListItem = React52__namespace.forwardRef(
29837
+ function ActionListItem2({ title, description, meta, trailing, density = "default", disabled, className, ...props }, ref) {
29838
+ const api = createActionListItem({ disabled, density });
29839
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
29840
+ "button",
29841
+ {
29842
+ ref,
29843
+ type: "button",
29844
+ disabled,
29845
+ className: cn(actionListItemVariants({ density }), className),
29846
+ ...api.ariaProps,
29847
+ ...api.dataAttributes,
29848
+ ...props,
29849
+ children: [
29850
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: actionListItemBodyClass, children: [
29851
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: actionListItemTitleClass, children: title }),
29852
+ description != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: actionListItemDescriptionClass, children: description }),
29853
+ meta != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: actionListItemMetaClass, children: meta })
29854
+ ] }),
29855
+ trailing != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: actionListItemTrailingClass, children: trailing })
29856
+ ]
29857
+ }
29858
+ ) });
29859
+ }
29860
+ );
29861
+
29862
+ // ../funnel-chart/dist/index.js
29863
+ var DEFAULT_FUNNEL_MIN_BAR_PERCENT = 6;
29864
+ var percentOf = (part, whole) => whole ? part / whole * 100 : 0;
29865
+ function computeFunnel(steps, minBarPercent = DEFAULT_FUNNEL_MIN_BAR_PERCENT) {
29866
+ const top = steps.length ? steps[0].value : 0;
29867
+ return steps.map((step, i) => {
29868
+ const shareOfTop = percentOf(step.value, top);
29869
+ const following = steps[i + 1];
29870
+ return {
29871
+ step,
29872
+ shareOfTop,
29873
+ barPercent: Math.min(100, Math.max(shareOfTop, minBarPercent)),
29874
+ next: following ? {
29875
+ conversion: percentOf(following.value, step.value),
29876
+ dropped: step.value - following.value
29877
+ } : void 0
29878
+ };
29879
+ });
29880
+ }
29881
+ var funnelChartDefaults = {
29882
+ formatValue: (value) => value.toLocaleString("en-US"),
29883
+ formatPercent: (percent) => `${percent.toFixed(1)}%`,
29884
+ shareLabel: (share) => `${share} of top`,
29885
+ conversionLabel: (percent) => `${percent} continue`,
29886
+ droppedLabel: (count) => `\u2212${count} dropped`
29887
+ };
29888
+ var funnelChartClasses = {
29889
+ root: "m-0 grid list-none p-0",
29890
+ bar: "relative flex items-center gap-3 overflow-hidden rounded-lg border border-border bg-background px-3.5 py-3",
29891
+ fill: "absolute inset-y-0 left-0 border-r-2 border-primary bg-accent",
29892
+ chevron: "relative shrink-0 text-primary",
29893
+ text: "relative grid min-w-0 flex-1",
29894
+ label: "text-[13px] font-bold text-foreground",
29895
+ description: "text-[11px] text-muted-foreground",
29896
+ figure: "relative grid text-right",
29897
+ value: "text-[15px] font-bold tabular-nums text-foreground",
29898
+ share: "text-[10.5px] text-muted-foreground",
29899
+ transition: "flex items-center gap-2 py-1.5 pl-[18px] text-[11px] text-muted-foreground",
29900
+ conversion: "font-semibold text-success",
29901
+ dropped: "font-semibold text-destructive"
29902
+ };
29903
+ function Chevron() {
29904
+ return /* @__PURE__ */ jsxRuntime.jsx(
29905
+ "svg",
29906
+ {
29907
+ className: funnelChartClasses.chevron,
29908
+ width: "15",
29909
+ height: "15",
29910
+ viewBox: "0 0 24 24",
29911
+ fill: "none",
29912
+ stroke: "currentColor",
29913
+ strokeWidth: "2",
29914
+ strokeLinecap: "round",
29915
+ strokeLinejoin: "round",
29916
+ "aria-hidden": "true",
29917
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 18 6-6-6-6" })
29918
+ }
29919
+ );
29920
+ }
29921
+ var FunnelChart = React52__namespace.forwardRef(function FunnelChart2({
29922
+ steps,
29923
+ formatValue = funnelChartDefaults.formatValue,
29924
+ formatPercent = funnelChartDefaults.formatPercent,
29925
+ minBarPercent = DEFAULT_FUNNEL_MIN_BAR_PERCENT,
29926
+ shareLabel = funnelChartDefaults.shareLabel,
29927
+ conversionLabel = funnelChartDefaults.conversionLabel,
29928
+ droppedLabel = funnelChartDefaults.droppedLabel,
29929
+ className,
29930
+ ...rest
29931
+ }, ref) {
29932
+ const rows = React52__namespace.useMemo(() => computeFunnel(steps, minBarPercent), [steps, minBarPercent]);
29933
+ return /* @__PURE__ */ jsxRuntime.jsx("ol", { ref, className: cn(funnelChartClasses.root, className), "data-slot": "funnel-chart", ...rest, children: rows.map((row) => /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
29934
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: funnelChartClasses.bar, children: [
29935
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: funnelChartClasses.fill, style: { width: `${row.barPercent}%` }, "aria-hidden": "true" }),
29936
+ /* @__PURE__ */ jsxRuntime.jsx(Chevron, {}),
29937
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: funnelChartClasses.text, children: [
29938
+ /* @__PURE__ */ jsxRuntime.jsx("b", { className: funnelChartClasses.label, children: row.step.label }),
29939
+ row.step.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: funnelChartClasses.description, children: row.step.description })
29940
+ ] }),
29941
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: funnelChartClasses.figure, children: [
29942
+ /* @__PURE__ */ jsxRuntime.jsx("b", { className: funnelChartClasses.value, children: formatValue(row.step.value) }),
29943
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: funnelChartClasses.share, children: shareLabel(formatPercent(row.shareOfTop)) })
29944
+ ] })
29945
+ ] }),
29946
+ row.next && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: funnelChartClasses.transition, children: [
29947
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: funnelChartClasses.conversion, children: conversionLabel(formatPercent(row.next.conversion)) }),
29948
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xB7" }),
29949
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: funnelChartClasses.dropped, children: droppedLabel(formatValue(row.next.dropped)) })
29950
+ ] })
29951
+ ] }, row.step.id)) });
29952
+ });
29953
+
29954
+ // ../line-chart/dist/index.js
29955
+ var DEFAULT_LINE_CHART_PADDING = {
29956
+ top: 14,
29957
+ right: 14,
29958
+ bottom: 24,
29959
+ left: 40
29960
+ };
29961
+ var DEFAULT_LINE_CHART_WIDTH = 760;
29962
+ var DEFAULT_LINE_CHART_HEIGHT = 230;
29963
+ var DEFAULT_TICK_COUNT = 4;
29964
+ var DEFAULT_HEADROOM = 1.08;
29965
+ var DEFAULT_LABEL_EVERY = 2;
29966
+ var CHART_TOKEN_COUNT = 5;
29967
+ function lineChartColor(index2) {
29968
+ return `hsl(var(--chart-${index2 % CHART_TOKEN_COUNT + 1}))`;
29969
+ }
29970
+ function pathFrom(points) {
29971
+ return points.map(([px, py], i) => (i ? "L" : "M") + px.toFixed(1) + " " + py.toFixed(1)).join(" ");
29972
+ }
29973
+ function computeLineChart(options) {
29974
+ const {
29975
+ series,
29976
+ labels,
29977
+ width,
29978
+ height,
29979
+ tickCount = DEFAULT_TICK_COUNT,
29980
+ headroom = DEFAULT_HEADROOM,
29981
+ labelEvery = DEFAULT_LABEL_EVERY
29982
+ } = options;
29983
+ const padding = { ...DEFAULT_LINE_CHART_PADDING, ...options.padding };
29984
+ const n = labels.length;
29985
+ const values = series.flatMap((s) => s.data);
29986
+ const peak = values.length ? Math.max(...values) : 0;
29987
+ const max = peak > 0 ? peak * headroom : 1;
29988
+ const plotW = width - padding.left - padding.right;
29989
+ const plotTop = padding.top;
29990
+ const plotBottom = height - padding.bottom;
29991
+ const plotH = plotBottom - plotTop;
29992
+ const x = (index2) => padding.left + (n > 1 ? index2 / (n - 1) * plotW : plotW / 2);
29993
+ const y = (value) => plotTop + (1 - value / max) * plotH;
29994
+ const ticks = Array.from({ length: tickCount + 1 }, (_2, t) => {
29995
+ const value = max / tickCount * t;
29996
+ return { value, y: y(value) };
29997
+ });
29998
+ const xLabels = labels.map((label, index2) => ({ index: index2, label, x: x(index2) })).filter(({ index: index2 }) => index2 % labelEvery === 0 || index2 === n - 1);
29999
+ const paths = series.map((s, si) => {
30000
+ const points = s.data.map((v2, i) => [x(i), y(v2)]);
30001
+ const line = pathFrom(points);
30002
+ const first = points.length ? points[0][0] : x(0);
30003
+ const last = points.length ? points[points.length - 1][0] : x(0);
30004
+ const base = y(0).toFixed(1);
30005
+ const area = `${line} L ${last.toFixed(1)} ${base} L ${first.toFixed(1)} ${base} Z`;
30006
+ return { id: s.id, color: s.color ?? lineChartColor(si), line, area };
30007
+ });
30008
+ const colW = n > 1 ? plotW / (n - 1) : plotW;
30009
+ const columns = labels.map((_2, index2) => ({
30010
+ index: index2,
30011
+ x: x(index2) - colW / 2,
30012
+ width: colW
30013
+ }));
30014
+ return { width, height, padding, max, ticks, xLabels, paths, columns, x, y, plotTop, plotBottom };
30015
+ }
30016
+ function tooltipLeftPercent(geometry, index2) {
30017
+ return geometry.x(index2) / geometry.width * 100;
30018
+ }
30019
+ function nextLineChartIndex(current, key, count) {
30020
+ if (count === 0) return null;
30021
+ const last = count - 1;
30022
+ switch (key) {
30023
+ case "ArrowRight":
30024
+ return current == null ? 0 : Math.min(current + 1, last);
30025
+ case "ArrowLeft":
30026
+ return current == null ? last : Math.max(current - 1, 0);
30027
+ case "Home":
30028
+ return 0;
30029
+ case "End":
30030
+ return last;
30031
+ default:
30032
+ return current;
30033
+ }
30034
+ }
30035
+ var lineChartClasses = {
30036
+ root: "relative",
30037
+ svg: "block w-full rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
30038
+ gridline: "stroke-border",
30039
+ axis: "fill-muted-foreground text-[9px]",
30040
+ crosshair: "stroke-border",
30041
+ marker: "stroke-card",
30042
+ tooltip: "pointer-events-none absolute z-10 -translate-x-1/2 whitespace-nowrap rounded-md bg-tertiary px-2.5 py-2 text-[11px] text-tertiary-foreground shadow-lg",
30043
+ tooltipLabel: "mb-1 opacity-60",
30044
+ tooltipRow: "flex justify-between gap-2",
30045
+ legend: "mt-2.5 flex flex-wrap gap-3.5",
30046
+ legendItem: "inline-flex items-center gap-1.5 text-[11px] text-muted-foreground",
30047
+ legendSwatch: "h-[3px] w-2.5 rounded-sm"
30048
+ };
30049
+ var defaultFormat = (value) => String(Math.round(value));
30050
+ var MARKER_RADIUS = 3.5;
30051
+ var STROKE_WIDTH = 2.2;
30052
+ var TOOLTIP_TOP_PX = 8;
30053
+ var LineChart = React52__namespace.forwardRef(function LineChart2({
30054
+ series,
30055
+ labels,
30056
+ ariaLabel,
30057
+ height = DEFAULT_LINE_CHART_HEIGHT,
30058
+ width = DEFAULT_LINE_CHART_WIDTH,
30059
+ formatValue = defaultFormat,
30060
+ formatTick: formatTick2,
30061
+ area,
30062
+ showLegend = true,
30063
+ className,
30064
+ ...rest
30065
+ }, ref) {
30066
+ const [active, setActive] = React52__namespace.useState(null);
30067
+ const gradientBase = React52__namespace.useId().replace(/:/g, "");
30068
+ const geo = React52__namespace.useMemo(
30069
+ () => computeLineChart({ series, labels, width, height }),
30070
+ [series, labels, width, height]
30071
+ );
30072
+ const fillArea = area ?? series.length === 1;
30073
+ const tick = formatTick2 ?? formatValue;
30074
+ const handleKeyDown = (event) => {
30075
+ const next = nextLineChartIndex(active, event.key, labels.length);
30076
+ if (next === active) return;
30077
+ event.preventDefault();
30078
+ setActive(next);
30079
+ };
30080
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn(lineChartClasses.root, className), "data-slot": "line-chart", ...rest, children: [
30081
+ /* @__PURE__ */ jsxRuntime.jsxs(
30082
+ "svg",
30083
+ {
30084
+ className: lineChartClasses.svg,
30085
+ viewBox: `0 0 ${width} ${height}`,
30086
+ style: { height },
30087
+ role: "img",
30088
+ "aria-label": ariaLabel,
30089
+ tabIndex: 0,
30090
+ onKeyDown: handleKeyDown,
30091
+ onBlur: () => setActive(null),
30092
+ onMouseLeave: () => setActive(null),
30093
+ children: [
30094
+ geo.ticks.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
30095
+ /* @__PURE__ */ jsxRuntime.jsx("line", { className: lineChartClasses.gridline, x1: geo.padding.left, y1: t.y, x2: width - geo.padding.right, y2: t.y }),
30096
+ /* @__PURE__ */ jsxRuntime.jsx("text", { className: lineChartClasses.axis, x: geo.padding.left - 8, y: t.y + 3, textAnchor: "end", children: tick(t.value) })
30097
+ ] }, i)),
30098
+ geo.xLabels.map((l2) => /* @__PURE__ */ jsxRuntime.jsx("text", { className: lineChartClasses.axis, x: l2.x, y: height - 6, textAnchor: "middle", children: l2.label }, l2.index)),
30099
+ geo.paths.map((p, si) => {
30100
+ const gid = `${gradientBase}-${si}`;
30101
+ const value = active != null ? series[si].data[active] : void 0;
30102
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
30103
+ fillArea && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
30104
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: gid, x1: "0", y1: "0", x2: "0", y2: "1", children: [
30105
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: p.color, stopOpacity: "0.22" }),
30106
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: p.color, stopOpacity: "0" })
30107
+ ] }) }),
30108
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: p.area, fill: `url(#${gid})` })
30109
+ ] }),
30110
+ /* @__PURE__ */ jsxRuntime.jsx(
30111
+ "path",
30112
+ {
30113
+ d: p.line,
30114
+ fill: "none",
30115
+ stroke: p.color,
30116
+ strokeWidth: STROKE_WIDTH,
30117
+ strokeLinecap: "round",
30118
+ strokeLinejoin: "round"
30119
+ }
30120
+ ),
30121
+ active != null && value != null && /* @__PURE__ */ jsxRuntime.jsx(
30122
+ "circle",
30123
+ {
30124
+ className: lineChartClasses.marker,
30125
+ cx: geo.x(active),
30126
+ cy: geo.y(value),
30127
+ r: MARKER_RADIUS,
30128
+ fill: p.color,
30129
+ strokeWidth: "1.5"
30130
+ }
30131
+ )
30132
+ ] }, p.id);
30133
+ }),
30134
+ active != null && /* @__PURE__ */ jsxRuntime.jsx(
30135
+ "line",
30136
+ {
30137
+ className: lineChartClasses.crosshair,
30138
+ x1: geo.x(active),
30139
+ y1: geo.plotTop,
30140
+ x2: geo.x(active),
30141
+ y2: geo.plotBottom,
30142
+ strokeDasharray: "3 3"
30143
+ }
30144
+ ),
30145
+ geo.columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
30146
+ "rect",
30147
+ {
30148
+ "data-index": col.index,
30149
+ x: col.x,
30150
+ y: 0,
30151
+ width: col.width,
30152
+ height,
30153
+ fill: "transparent",
30154
+ onMouseEnter: () => setActive(col.index)
30155
+ },
30156
+ col.index
30157
+ ))
30158
+ ]
30159
+ }
30160
+ ),
30161
+ active != null && /* @__PURE__ */ jsxRuntime.jsxs(
30162
+ "div",
30163
+ {
30164
+ className: lineChartClasses.tooltip,
30165
+ role: "status",
30166
+ style: { left: `${tooltipLeftPercent(geo, active)}%`, top: TOOLTIP_TOP_PX },
30167
+ children: [
30168
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: lineChartClasses.tooltipLabel, children: labels[active] }),
30169
+ series.map((s, si) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: lineChartClasses.tooltipRow, children: [
30170
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: geo.paths[si].color }, children: s.name }),
30171
+ /* @__PURE__ */ jsxRuntime.jsx("b", { children: s.data[active] != null ? formatValue(s.data[active]) : "\u2014" })
30172
+ ] }, s.id))
30173
+ ]
30174
+ }
30175
+ ),
30176
+ showLegend && /* @__PURE__ */ jsxRuntime.jsx("div", { className: lineChartClasses.legend, children: series.map((s, si) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: lineChartClasses.legendItem, children: [
30177
+ /* @__PURE__ */ jsxRuntime.jsx("i", { className: lineChartClasses.legendSwatch, style: { background: geo.paths[si].color }, "aria-hidden": "true" }),
30178
+ s.name
30179
+ ] }, s.id)) })
30180
+ ] });
30181
+ });
30182
+
30183
+ // ../page-header/dist/index.js
30184
+ function createPageHeader(props = {}) {
30185
+ return {
30186
+ dataAttributes: {
30187
+ "data-slot": "page-header",
30188
+ "data-has-actions": props.hasActions ? "true" : "false"
30189
+ }
30190
+ };
30191
+ }
30192
+ var pageHeaderClass = "flex flex-wrap items-start justify-between gap-4";
30193
+ var pageHeaderTextClass = "flex min-w-0 flex-1 flex-col gap-1";
30194
+ var pageHeaderKickerClass = "break-words text-[11px] uppercase tracking-wider text-muted-foreground";
30195
+ var pageHeaderTitleClass = "break-words text-xl font-semibold text-foreground";
30196
+ var pageHeaderDescriptionClass = "max-w-prose text-sm text-muted-foreground";
30197
+ var pageHeaderActionsClass = "flex flex-none flex-wrap items-center gap-2";
30198
+ var PageHeader = React52__namespace.forwardRef(function PageHeader2({ kicker, title, description, actions, as: Title = "h1", className, ...props }, ref) {
30199
+ const { dataAttributes } = createPageHeader({ hasActions: actions != null });
30200
+ return /* @__PURE__ */ jsxRuntime.jsxs("header", { ref, className: cn(pageHeaderClass, className), ...dataAttributes, ...props, children: [
30201
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: pageHeaderTextClass, children: [
30202
+ kicker != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: pageHeaderKickerClass, children: kicker }),
30203
+ /* @__PURE__ */ jsxRuntime.jsx(Title, { className: pageHeaderTitleClass, children: title }),
30204
+ description != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: pageHeaderDescriptionClass, children: description })
30205
+ ] }),
30206
+ actions != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: pageHeaderActionsClass, children: actions })
30207
+ ] });
30208
+ });
30209
+
29631
30210
  exports.AIProvider = AIProvider;
29632
30211
  exports.Accordion = Accordion;
29633
30212
  exports.AccordionContent = AccordionContent;
29634
30213
  exports.AccordionItem = AccordionItem;
29635
30214
  exports.AccordionTrigger = AccordionTrigger;
30215
+ exports.ActionList = ActionList;
30216
+ exports.ActionListItem = ActionListItem;
29636
30217
  exports.AltHintState = AltHintState;
29637
30218
  exports.AnalyticsProvider = AnalyticsProvider;
29638
30219
  exports.AnimatedText = AnimatedText;
@@ -29750,6 +30331,7 @@ exports.FileUpload = FileUpload;
29750
30331
  exports.FloatingReactions = FloatingReactions;
29751
30332
  exports.FlowEditor = FlowEditor;
29752
30333
  exports.Footer = Footer;
30334
+ exports.FunnelChart = FunnelChart;
29753
30335
  exports.Gradient = Gradient;
29754
30336
  exports.GraphView = GraphView;
29755
30337
  exports.Histogram = Histogram;
@@ -29768,6 +30350,7 @@ exports.KanbanColumn = KanbanColumn;
29768
30350
  exports.KeyboardShortcut = KeyboardShortcut;
29769
30351
  exports.LanguageSelector = LanguageSelector;
29770
30352
  exports.Line = Line;
30353
+ exports.LineChart = LineChart;
29771
30354
  exports.LinkCard = LinkCard;
29772
30355
  exports.LiveCaptions = LiveCaptions;
29773
30356
  exports.LiveCursors = LiveCursors;
@@ -29787,6 +30370,7 @@ exports.NumberedSteps = NumberedSteps;
29787
30370
  exports.OtpInput = OtpInput;
29788
30371
  exports.PRESENCE_STATUS_COLORS = STATUS_COLORS;
29789
30372
  exports.PRESENCE_STATUS_LABELS = STATUS_LABELS;
30373
+ exports.PageHeader = PageHeader;
29790
30374
  exports.Pagination = Pagination;
29791
30375
  exports.PasswordInput = PasswordInput;
29792
30376
  exports.Payment = Payment;
@@ -29826,6 +30410,7 @@ exports.Select = Select;
29826
30410
  exports.SelectContent = SelectContent;
29827
30411
  exports.SelectItem = SelectItem;
29828
30412
  exports.SelectTrigger = SelectTrigger;
30413
+ exports.SelectValue = SelectValue;
29829
30414
  exports.Separator = Separator;
29830
30415
  exports.Sheet = Sheet;
29831
30416
  exports.SheetClose = SheetClose;