@madebywild/wvk 0.0.2 → 0.1.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
@@ -7,6 +7,7 @@ var __export = (target, all) => {
7
7
 
8
8
  // src/components/ui/alert.tsx
9
9
  import * as React from "react";
10
+ import { motion } from "framer-motion";
10
11
  import { cva } from "class-variance-authority";
11
12
 
12
13
  // src/lib/utils.ts
@@ -4745,12 +4746,15 @@ var Alert = React.forwardRef(
4745
4746
  const resolvedIcon = icon ?? defaultIcons[resolvedVariant];
4746
4747
  const bodyId = React.useId();
4747
4748
  return /* @__PURE__ */ jsxs17(
4748
- "div",
4749
+ motion.div,
4749
4750
  {
4750
4751
  className: cn(alertVariants({ variant, className })),
4751
4752
  ref,
4752
4753
  role: "alert",
4753
4754
  "aria-describedby": children ? bodyId : void 0,
4755
+ initial: { opacity: 0, y: -6 },
4756
+ animate: { opacity: 1, y: 0 },
4757
+ transition: { duration: 0.25, ease: "easeOut" },
4754
4758
  ...props,
4755
4759
  children: [
4756
4760
  resolvedIcon && /* @__PURE__ */ jsx184("span", { className: "mt-0.5 shrink-0", children: resolvedIcon }),
@@ -4835,11 +4839,11 @@ BottomTabBarItem.displayName = "BottomTabBarItem";
4835
4839
 
4836
4840
  // src/components/ui/button.tsx
4837
4841
  import * as React3 from "react";
4838
- import { Slot } from "@radix-ui/react-slot";
4842
+ import { useRender } from "@base-ui-components/react/use-render";
4839
4843
  import { cva as cva2 } from "class-variance-authority";
4840
4844
  import { Fragment as Fragment2, jsx as jsx186, jsxs as jsxs19 } from "react/jsx-runtime";
4841
4845
  var buttonVariants = cva2(
4842
- "inline-flex items-center justify-center font-bold whitespace-nowrap transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",
4846
+ "inline-flex items-center justify-center font-bold whitespace-nowrap transition-[transform,colors] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.97]",
4843
4847
  {
4844
4848
  variants: {
4845
4849
  variant: {
@@ -4854,11 +4858,21 @@ var buttonVariants = cva2(
4854
4858
  sm: "h-8 px-3 text-xs rounded-[var(--radius-md)] gap-1",
4855
4859
  md: "h-10 px-4 text-sm rounded-[var(--radius-md)] gap-1.5",
4856
4860
  lg: "h-14 px-6 text-sm rounded-[var(--radius-md)] gap-2"
4861
+ },
4862
+ iconOnly: {
4863
+ true: "p-0 gap-0",
4864
+ false: ""
4857
4865
  }
4858
4866
  },
4867
+ compoundVariants: [
4868
+ { size: "sm", iconOnly: true, class: "w-8" },
4869
+ { size: "md", iconOnly: true, class: "w-10" },
4870
+ { size: "lg", iconOnly: true, class: "w-14" }
4871
+ ],
4859
4872
  defaultVariants: {
4860
4873
  variant: "primary",
4861
- size: "lg"
4874
+ size: "lg",
4875
+ iconOnly: false
4862
4876
  }
4863
4877
  }
4864
4878
  );
@@ -4867,37 +4881,56 @@ var Button = React3.forwardRef(
4867
4881
  className,
4868
4882
  variant,
4869
4883
  size,
4870
- asChild = false,
4884
+ iconOnly,
4885
+ render,
4871
4886
  leadingIcon,
4872
4887
  trailingIcon,
4873
4888
  children,
4874
4889
  ...props
4875
4890
  }, ref) => {
4876
- const Comp = asChild ? Slot : "button";
4877
4891
  const resolvedSize = size ?? "lg";
4878
- const showIcons = !asChild && Boolean(leadingIcon || trailingIcon);
4879
- const content = showIcons ? /* @__PURE__ */ jsxs19(Fragment2, { children: [
4880
- leadingIcon ? /* @__PURE__ */ jsx186("span", { className: "inline-flex shrink-0 items-center justify-center text-current [&_svg]:block", children: leadingIcon }) : null,
4881
- /* @__PURE__ */ jsx186("span", { className: "min-w-0", children }),
4882
- trailingIcon ? /* @__PURE__ */ jsx186("span", { className: "inline-flex shrink-0 items-center justify-center text-current [&_svg]:block", children: trailingIcon }) : null
4883
- ] }) : children;
4884
- return /* @__PURE__ */ jsx186(
4885
- Comp,
4886
- {
4887
- className: cn(buttonVariants({ variant, size: resolvedSize, className })),
4888
- ref,
4892
+ const showIcons = !iconOnly && !render && Boolean(leadingIcon || trailingIcon);
4893
+ let content;
4894
+ if (iconOnly) {
4895
+ content = /* @__PURE__ */ jsx186("span", { className: "inline-flex shrink-0 items-center justify-center text-current [&_svg]:block", children });
4896
+ } else if (showIcons) {
4897
+ content = /* @__PURE__ */ jsxs19(Fragment2, { children: [
4898
+ leadingIcon ? /* @__PURE__ */ jsx186("span", { className: "inline-flex shrink-0 items-center justify-center text-current [&_svg]:block", children: leadingIcon }) : null,
4899
+ /* @__PURE__ */ jsx186("span", { className: "min-w-0", children }),
4900
+ trailingIcon ? /* @__PURE__ */ jsx186("span", { className: "inline-flex shrink-0 items-center justify-center text-current [&_svg]:block", children: trailingIcon }) : null
4901
+ ] });
4902
+ } else {
4903
+ content = children;
4904
+ }
4905
+ const element = useRender({
4906
+ defaultTagName: "button",
4907
+ render,
4908
+ ref,
4909
+ props: {
4889
4910
  ...props,
4911
+ className: cn(
4912
+ buttonVariants({
4913
+ variant,
4914
+ size: resolvedSize,
4915
+ iconOnly: Boolean(iconOnly),
4916
+ className
4917
+ })
4918
+ ),
4890
4919
  children: content
4891
4920
  }
4892
- );
4921
+ });
4922
+ return element;
4893
4923
  }
4894
4924
  );
4895
4925
  Button.displayName = "Button";
4896
4926
 
4897
4927
  // src/components/ui/checkbox.tsx
4898
4928
  import * as React4 from "react";
4929
+ import { Checkbox as BaseCheckbox } from "@base-ui-components/react/checkbox";
4930
+ import { motion as motion2 } from "framer-motion";
4899
4931
  import { cva as cva3 } from "class-variance-authority";
4900
4932
  import { jsx as jsx187, jsxs as jsxs20 } from "react/jsx-runtime";
4933
+ var CHECKBOX_TAP_TRANSITION = { type: "spring", stiffness: 600, damping: 22 };
4901
4934
  var CHECKMARK_PATH = "m7.951 12.537 7.296-8.195a1 1 0 0 1 1.506 1.317l-8 9a1 1 0 0 1-1.46.048l-4-4a1 1 0 1 1 1.414-1.414z";
4902
4935
  var MINUS_PATH = "M4 9h12a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Z";
4903
4936
  var CHECKBOX_MARK_GROUP_TRANSFORM = `translate(11 11) scale(${11 / 12}) translate(-10 -10)`;
@@ -4905,7 +4938,7 @@ var checkboxFrameVariants = cva3(
4905
4938
  [
4906
4939
  "relative inline-flex items-center justify-center p-0 bg-transparent border-0 cursor-pointer transition-colors",
4907
4940
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
4908
- "disabled:pointer-events-none disabled:opacity-50"
4941
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
4909
4942
  ],
4910
4943
  {
4911
4944
  variants: {
@@ -4922,75 +4955,74 @@ var checkboxFrameVariants = cva3(
4922
4955
  );
4923
4956
  var Checkbox = React4.forwardRef(
4924
4957
  ({
4925
- checked = false,
4926
- indeterminate = false,
4927
- onCheckedChange,
4928
- disabled = false,
4929
4958
  className,
4930
- size = "lg",
4931
- onClick,
4959
+ size,
4960
+ onCheckedChange,
4961
+ indeterminate,
4932
4962
  ...rest
4933
4963
  }, ref) => {
4934
- const handleClick = (e) => {
4935
- onClick?.(e);
4936
- if (!disabled && !e.defaultPrevented) {
4937
- onCheckedChange?.(!checked);
4938
- }
4939
- };
4940
- const isActive = checked || indeterminate;
4941
4964
  const s = size ?? "lg";
4942
4965
  return /* @__PURE__ */ jsx187(
4943
- "button",
4966
+ BaseCheckbox.Root,
4944
4967
  {
4945
- ...rest,
4946
4968
  ref,
4947
- type: "button",
4948
- role: "checkbox",
4949
- "aria-checked": indeterminate ? "mixed" : checked,
4950
- disabled,
4951
- onClick: handleClick,
4969
+ indeterminate,
4970
+ onCheckedChange: (checked) => onCheckedChange?.(checked),
4971
+ nativeButton: true,
4952
4972
  className: cn(checkboxFrameVariants({ size: s }), className),
4953
- children: /* @__PURE__ */ jsxs20(
4954
- "svg",
4955
- {
4956
- className: "size-full max-h-none max-w-none",
4957
- viewBox: "0 0 22 22",
4958
- fill: "none",
4959
- xmlns: "http://www.w3.org/2000/svg",
4960
- "aria-hidden": true,
4961
- children: [
4962
- /* @__PURE__ */ jsx187(
4963
- "rect",
4964
- {
4965
- x: "0.5",
4966
- y: "0.5",
4967
- width: "21",
4968
- height: "21",
4969
- rx: "4",
4970
- fill: isActive ? "var(--color-primary)" : "transparent",
4971
- stroke: isActive ? "var(--color-primary)" : "var(--color-primary)",
4972
- strokeWidth: "1"
4973
- }
4974
- ),
4975
- checked && !indeterminate ? /* @__PURE__ */ jsx187(
4976
- "g",
4977
- {
4978
- fill: "var(--color-primary-foreground)",
4979
- transform: CHECKBOX_MARK_GROUP_TRANSFORM,
4980
- children: /* @__PURE__ */ jsx187("path", { d: CHECKMARK_PATH })
4981
- }
4982
- ) : null,
4983
- indeterminate ? /* @__PURE__ */ jsx187(
4984
- "g",
4973
+ ...rest,
4974
+ render: (props, state) => {
4975
+ const isActive = state.checked || state.indeterminate;
4976
+ return /* @__PURE__ */ jsx187(
4977
+ motion2.span,
4978
+ {
4979
+ className: "inline-flex",
4980
+ whileTap: { scale: 0.85 },
4981
+ transition: CHECKBOX_TAP_TRANSITION,
4982
+ children: /* @__PURE__ */ jsx187("button", { ...props, type: "button", children: /* @__PURE__ */ jsxs20(
4983
+ "svg",
4985
4984
  {
4986
- fill: "var(--color-primary-foreground)",
4987
- transform: CHECKBOX_MARK_GROUP_TRANSFORM,
4988
- children: /* @__PURE__ */ jsx187("path", { d: MINUS_PATH })
4985
+ className: "size-full max-h-none max-w-none",
4986
+ viewBox: "0 0 22 22",
4987
+ fill: "none",
4988
+ xmlns: "http://www.w3.org/2000/svg",
4989
+ "aria-hidden": true,
4990
+ children: [
4991
+ /* @__PURE__ */ jsx187(
4992
+ "rect",
4993
+ {
4994
+ x: "0.5",
4995
+ y: "0.5",
4996
+ width: "21",
4997
+ height: "21",
4998
+ rx: "4",
4999
+ fill: isActive ? "var(--color-primary)" : "transparent",
5000
+ stroke: "var(--color-primary)",
5001
+ strokeWidth: "1"
5002
+ }
5003
+ ),
5004
+ state.checked && !state.indeterminate ? /* @__PURE__ */ jsx187(
5005
+ "g",
5006
+ {
5007
+ fill: "var(--color-primary-foreground)",
5008
+ transform: CHECKBOX_MARK_GROUP_TRANSFORM,
5009
+ children: /* @__PURE__ */ jsx187("path", { d: CHECKMARK_PATH })
5010
+ }
5011
+ ) : null,
5012
+ state.indeterminate ? /* @__PURE__ */ jsx187(
5013
+ "g",
5014
+ {
5015
+ fill: "var(--color-primary-foreground)",
5016
+ transform: CHECKBOX_MARK_GROUP_TRANSFORM,
5017
+ children: /* @__PURE__ */ jsx187("path", { d: MINUS_PATH })
5018
+ }
5019
+ ) : null
5020
+ ]
4989
5021
  }
4990
- ) : null
4991
- ]
4992
- }
4993
- )
5022
+ ) })
5023
+ }
5024
+ );
5025
+ }
4994
5026
  }
4995
5027
  );
4996
5028
  }
@@ -5002,6 +5034,7 @@ import * as React6 from "react";
5002
5034
 
5003
5035
  // src/components/ui/tooltip.tsx
5004
5036
  import * as React5 from "react";
5037
+ import { Tooltip as BaseTooltip } from "@base-ui-components/react/tooltip";
5005
5038
  import { cva as cva4 } from "class-variance-authority";
5006
5039
  import { jsx as jsx188, jsxs as jsxs21 } from "react/jsx-runtime";
5007
5040
  var tooltipVariants = cva4("relative rounded-[var(--radius-md)] w-max", {
@@ -5062,6 +5095,41 @@ var Tooltip = React5.forwardRef(
5062
5095
  }
5063
5096
  );
5064
5097
  Tooltip.displayName = "Tooltip";
5098
+ var TooltipProvider = BaseTooltip.Provider;
5099
+ function TooltipPopup({
5100
+ trigger,
5101
+ children,
5102
+ theme,
5103
+ size,
5104
+ side = "top",
5105
+ sideOffset = 8,
5106
+ className,
5107
+ ...rest
5108
+ }) {
5109
+ const resolvedTheme = theme ?? "dark";
5110
+ return /* @__PURE__ */ jsxs21(BaseTooltip.Root, { children: [
5111
+ /* @__PURE__ */ jsx188(BaseTooltip.Trigger, { render: trigger }),
5112
+ /* @__PURE__ */ jsx188(BaseTooltip.Portal, { children: /* @__PURE__ */ jsx188(BaseTooltip.Positioner, { side, sideOffset, children: /* @__PURE__ */ jsxs21(
5113
+ BaseTooltip.Popup,
5114
+ {
5115
+ className: cn(tooltipVariants({ theme, size }), className),
5116
+ ...rest,
5117
+ children: [
5118
+ children,
5119
+ /* @__PURE__ */ jsx188(
5120
+ BaseTooltip.Arrow,
5121
+ {
5122
+ className: cn(
5123
+ "h-0 w-0 border-l-[4px] border-r-[4px] border-t-[4px] border-l-transparent border-r-transparent",
5124
+ resolvedTheme === "dark" ? "border-t-primary" : "border-t-border"
5125
+ )
5126
+ }
5127
+ )
5128
+ ]
5129
+ }
5130
+ ) }) })
5131
+ ] });
5132
+ }
5065
5133
 
5066
5134
  // src/components/ui/field-label.tsx
5067
5135
  import { Fragment as Fragment3, jsx as jsx189, jsxs as jsxs22 } from "react/jsx-runtime";
@@ -5255,16 +5323,17 @@ InfoBar.displayName = "InfoBar";
5255
5323
 
5256
5324
  // src/components/ui/link.tsx
5257
5325
  import * as React8 from "react";
5326
+ import { motion as motion3 } from "framer-motion";
5258
5327
  import { cva as cva5 } from "class-variance-authority";
5259
- import { jsx as jsx192 } from "react/jsx-runtime";
5328
+ import { jsx as jsx192, jsxs as jsxs24 } from "react/jsx-runtime";
5260
5329
  var linkVariants = cva5(
5261
- "inline-flex w-fit items-center gap-[var(--wvk-gap-sm)] font-bold border-b-2 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
5330
+ "relative inline-flex w-fit items-center gap-[var(--wvk-gap-sm)] font-bold focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
5262
5331
  {
5263
5332
  variants: {
5264
5333
  theme: {
5265
- dark: "text-primary border-primary",
5266
- light: "text-primary-foreground border-primary-foreground",
5267
- medium: "text-muted-foreground border-muted-foreground"
5334
+ dark: "text-primary",
5335
+ light: "text-primary-foreground",
5336
+ medium: "text-muted-foreground"
5268
5337
  },
5269
5338
  size: {
5270
5339
  body: "text-sm leading-5",
@@ -5278,13 +5347,36 @@ var linkVariants = cva5(
5278
5347
  }
5279
5348
  );
5280
5349
  var Link2 = React8.forwardRef(
5281
- ({ className, theme, size, ...props }, ref) => {
5282
- return /* @__PURE__ */ jsx192(
5350
+ ({ className, theme, size, underlined = false, children, onMouseEnter, onMouseLeave, ...props }, ref) => {
5351
+ const [hovered, setHovered] = React8.useState(false);
5352
+ const showUnderline = underlined ? !hovered : hovered;
5353
+ return /* @__PURE__ */ jsxs24(
5283
5354
  "a",
5284
5355
  {
5285
5356
  className: cn(linkVariants({ theme, size, className })),
5286
5357
  ref,
5287
- ...props
5358
+ onMouseEnter: (e) => {
5359
+ setHovered(true);
5360
+ onMouseEnter?.(e);
5361
+ },
5362
+ onMouseLeave: (e) => {
5363
+ setHovered(false);
5364
+ onMouseLeave?.(e);
5365
+ },
5366
+ ...props,
5367
+ children: [
5368
+ children,
5369
+ /* @__PURE__ */ jsx192(
5370
+ motion3.span,
5371
+ {
5372
+ "aria-hidden": true,
5373
+ className: "pointer-events-none absolute bottom-0 left-0 h-0.5 w-full origin-left bg-current",
5374
+ animate: { scaleX: showUnderline ? 1 : 0 },
5375
+ initial: { scaleX: underlined ? 1 : 0 },
5376
+ transition: { duration: 0.2, ease: [0.4, 0, 0.2, 1] }
5377
+ }
5378
+ )
5379
+ ]
5288
5380
  }
5289
5381
  );
5290
5382
  }
@@ -5294,7 +5386,7 @@ Link2.displayName = "Link";
5294
5386
  // src/components/ui/list-item.tsx
5295
5387
  import * as React9 from "react";
5296
5388
  import { cva as cva6 } from "class-variance-authority";
5297
- import { jsx as jsx193, jsxs as jsxs24 } from "react/jsx-runtime";
5389
+ import { jsx as jsx193, jsxs as jsxs25 } from "react/jsx-runtime";
5298
5390
  var LIST_CHECKMARK_PATH = "m7.951 12.537 7.296-8.195a1 1 0 0 1 1.506 1.317l-8 9a1 1 0 0 1-1.46.048l-4-4a1 1 0 1 1 1.414-1.414z";
5299
5391
  var LIST_CHECKBOX_MARK_TRANSFORM = `translate(10 10) scale(${5 / 6}) translate(-10 -10)`;
5300
5392
  var listItemVariants = cva6(
@@ -5312,7 +5404,7 @@ var listItemVariants = cva6(
5312
5404
  }
5313
5405
  }
5314
5406
  );
5315
- var ListItemCheckbox = ({ checked }) => /* @__PURE__ */ jsx193("span", { className: "relative inline-flex size-5 shrink-0", children: /* @__PURE__ */ jsxs24(
5407
+ var ListItemCheckbox = ({ checked }) => /* @__PURE__ */ jsx193("span", { className: "relative inline-flex size-5 shrink-0", children: /* @__PURE__ */ jsxs25(
5316
5408
  "svg",
5317
5409
  {
5318
5410
  className: "size-full",
@@ -5345,7 +5437,7 @@ var ListItemCheckbox = ({ checked }) => /* @__PURE__ */ jsx193("span", { classNa
5345
5437
  ]
5346
5438
  }
5347
5439
  ) });
5348
- var ListItemRadio = ({ checked }) => /* @__PURE__ */ jsxs24(
5440
+ var ListItemRadio = ({ checked }) => /* @__PURE__ */ jsxs25(
5349
5441
  "svg",
5350
5442
  {
5351
5443
  width: "20",
@@ -5416,7 +5508,7 @@ var ListItem = React9.forwardRef(
5416
5508
  onCheckedChange?.(!checked);
5417
5509
  }
5418
5510
  };
5419
- return /* @__PURE__ */ jsxs24(
5511
+ return /* @__PURE__ */ jsxs25(
5420
5512
  "div",
5421
5513
  {
5422
5514
  ...rest,
@@ -5484,7 +5576,7 @@ LoadingSpinner.displayName = "LoadingSpinner";
5484
5576
  // src/components/ui/media.tsx
5485
5577
  import * as React11 from "react";
5486
5578
  import { cva as cva8 } from "class-variance-authority";
5487
- import { jsx as jsx195, jsxs as jsxs25 } from "react/jsx-runtime";
5579
+ import { jsx as jsx195, jsxs as jsxs26 } from "react/jsx-runtime";
5488
5580
  var placeholderVariants = cva8(
5489
5581
  "relative flex items-center justify-center bg-muted rounded-[var(--radius-md)] overflow-hidden",
5490
5582
  {
@@ -5511,7 +5603,7 @@ var ImagePlaceholder = React11.forwardRef(
5511
5603
  );
5512
5604
  ImagePlaceholder.displayName = "ImagePlaceholder";
5513
5605
  var VideoPlaceholder = React11.forwardRef(
5514
- ({ className, size, ...props }, ref) => /* @__PURE__ */ jsxs25("div", { ref, className: cn(placeholderVariants({ size }), className), ...props, children: [
5606
+ ({ className, size, ...props }, ref) => /* @__PURE__ */ jsxs26("div", { ref, className: cn(placeholderVariants({ size }), className), ...props, children: [
5515
5607
  /* @__PURE__ */ jsx195("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx195("div", { className: "w-12 h-12 rounded-full bg-primary flex items-center justify-center", children: /* @__PURE__ */ jsx195(
5516
5608
  Play_default,
5517
5609
  {
@@ -5532,7 +5624,7 @@ VideoPlaceholder.displayName = "VideoPlaceholder";
5532
5624
  var VideoControls = React11.forwardRef(
5533
5625
  ({ className, progress = 0, ...props }, ref) => {
5534
5626
  const clamped = Math.min(100, Math.max(0, progress));
5535
- return /* @__PURE__ */ jsxs25(
5627
+ return /* @__PURE__ */ jsxs26(
5536
5628
  "div",
5537
5629
  {
5538
5630
  ref,
@@ -5559,10 +5651,58 @@ var VideoControls = React11.forwardRef(
5559
5651
  );
5560
5652
  VideoControls.displayName = "VideoControls";
5561
5653
 
5562
- // src/components/ui/pagination.tsx
5654
+ // src/components/ui/menu.tsx
5563
5655
  import * as React12 from "react";
5564
- import { cva as cva9 } from "class-variance-authority";
5656
+ import { Menu as BaseMenu } from "@base-ui-components/react/menu";
5565
5657
  import { jsx as jsx196 } from "react/jsx-runtime";
5658
+ var Menu2 = BaseMenu.Root;
5659
+ var MenuTrigger = BaseMenu.Trigger;
5660
+ var MenuPopup = React12.forwardRef(
5661
+ ({ className, children, side = "bottom", sideOffset = 6, ...rest }, ref) => /* @__PURE__ */ jsx196(BaseMenu.Portal, { children: /* @__PURE__ */ jsx196(BaseMenu.Positioner, { side, sideOffset, children: /* @__PURE__ */ jsx196(
5662
+ BaseMenu.Popup,
5663
+ {
5664
+ ref,
5665
+ className: cn(
5666
+ "z-50 min-w-[8rem] overflow-hidden rounded-[var(--radius-md)] border border-border bg-popover p-1 text-popover-foreground shadow-md outline-none",
5667
+ className
5668
+ ),
5669
+ ...rest,
5670
+ children
5671
+ }
5672
+ ) }) })
5673
+ );
5674
+ MenuPopup.displayName = "MenuPopup";
5675
+ var MenuItem = React12.forwardRef(({ className, ...rest }, ref) => /* @__PURE__ */ jsx196(
5676
+ BaseMenu.Item,
5677
+ {
5678
+ ref,
5679
+ className: cn(
5680
+ "relative flex w-full cursor-pointer select-none items-center rounded-[var(--radius-sm)] px-2 py-1.5 text-sm outline-none transition-colors",
5681
+ "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground",
5682
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
5683
+ className
5684
+ ),
5685
+ ...rest
5686
+ }
5687
+ ));
5688
+ MenuItem.displayName = "MenuItem";
5689
+ var MenuSeparator = React12.forwardRef(({ className, ...rest }, ref) => /* @__PURE__ */ jsx196(
5690
+ "div",
5691
+ {
5692
+ ref,
5693
+ role: "separator",
5694
+ className: cn("my-1 h-px bg-border", className),
5695
+ ...rest
5696
+ }
5697
+ ));
5698
+ MenuSeparator.displayName = "MenuSeparator";
5699
+ var MenuGroup = BaseMenu.Group;
5700
+ var MenuGroupLabel = BaseMenu.GroupLabel;
5701
+
5702
+ // src/components/ui/pagination.tsx
5703
+ import * as React13 from "react";
5704
+ import { cva as cva9 } from "class-variance-authority";
5705
+ import { jsx as jsx197 } from "react/jsx-runtime";
5566
5706
  var paginationVariants = cva9("inline-flex items-center", {
5567
5707
  variants: {
5568
5708
  size: {
@@ -5580,11 +5720,11 @@ var dotSizes = {
5580
5720
  md: { active: "w-2.5 h-2.5", inactive: "w-2 h-2" },
5581
5721
  lg: { active: "w-3 h-3", inactive: "w-2 h-2" }
5582
5722
  };
5583
- var Pagination = React12.forwardRef(
5723
+ var Pagination = React13.forwardRef(
5584
5724
  ({ pages, current, onPageChange, size = "md", className, ...rest }, ref) => {
5585
5725
  const sizeKey = size ?? "md";
5586
5726
  const sizes = dotSizes[sizeKey];
5587
- return /* @__PURE__ */ jsx196(
5727
+ return /* @__PURE__ */ jsx197(
5588
5728
  "div",
5589
5729
  {
5590
5730
  ...rest,
@@ -5594,7 +5734,7 @@ var Pagination = React12.forwardRef(
5594
5734
  className: cn(paginationVariants({ size, className })),
5595
5735
  children: Array.from({ length: pages }, (_, i) => {
5596
5736
  const isActive = i === current;
5597
- return /* @__PURE__ */ jsx196(
5737
+ return /* @__PURE__ */ jsx197(
5598
5738
  "button",
5599
5739
  {
5600
5740
  type: "button",
@@ -5616,43 +5756,54 @@ var Pagination = React12.forwardRef(
5616
5756
  Pagination.displayName = "Pagination";
5617
5757
 
5618
5758
  // src/components/ui/progress-bar.tsx
5619
- import * as React13 from "react";
5620
- import { jsx as jsx197 } from "react/jsx-runtime";
5621
- var ProgressBar = React13.forwardRef(
5759
+ import * as React14 from "react";
5760
+ import { Progress as BaseProgress } from "@base-ui-components/react/progress";
5761
+ import { Meter as BaseMeter } from "@base-ui-components/react/meter";
5762
+ import { jsx as jsx198 } from "react/jsx-runtime";
5763
+ var ProgressBar = React14.forwardRef(
5622
5764
  ({ className, value = 0, ...props }, ref) => {
5623
- const clampedValue = Math.min(100, Math.max(0, value));
5624
- return /* @__PURE__ */ jsx197(
5625
- "div",
5765
+ return /* @__PURE__ */ jsx198(
5766
+ BaseProgress.Root,
5626
5767
  {
5627
- className: cn("w-full h-2 bg-muted rounded-full overflow-hidden", className),
5628
5768
  ref,
5629
- role: "progressbar",
5630
- "aria-valuenow": clampedValue,
5631
- "aria-valuemin": 0,
5632
- "aria-valuemax": 100,
5769
+ value,
5770
+ className: cn("w-full", className),
5633
5771
  ...props,
5634
- children: /* @__PURE__ */ jsx197(
5635
- "div",
5636
- {
5637
- className: "h-full bg-primary rounded-full transition-all duration-300",
5638
- style: { width: `${clampedValue}%` }
5639
- }
5640
- )
5772
+ children: /* @__PURE__ */ jsx198(BaseProgress.Track, { className: "block h-2 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx198(BaseProgress.Indicator, { className: "block h-full rounded-full bg-primary transition-all duration-300" }) })
5641
5773
  }
5642
5774
  );
5643
5775
  }
5644
5776
  );
5645
5777
  ProgressBar.displayName = "ProgressBar";
5778
+ var Meter = React14.forwardRef(
5779
+ ({ className, value = 0, ...props }, ref) => {
5780
+ return /* @__PURE__ */ jsx198(
5781
+ BaseMeter.Root,
5782
+ {
5783
+ ref,
5784
+ value,
5785
+ className: cn("w-full", className),
5786
+ ...props,
5787
+ children: /* @__PURE__ */ jsx198(BaseMeter.Track, { className: "block h-2 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx198(BaseMeter.Indicator, { className: "block h-full rounded-full bg-primary transition-all duration-300" }) })
5788
+ }
5789
+ );
5790
+ }
5791
+ );
5792
+ Meter.displayName = "Meter";
5646
5793
 
5647
5794
  // src/components/ui/radio.tsx
5648
- import * as React14 from "react";
5795
+ import * as React15 from "react";
5796
+ import { Radio as BaseRadio } from "@base-ui-components/react/radio";
5797
+ import { RadioGroup as BaseRadioGroup } from "@base-ui-components/react/radio-group";
5798
+ import { motion as motion4 } from "framer-motion";
5649
5799
  import { cva as cva10 } from "class-variance-authority";
5650
- import { jsx as jsx198, jsxs as jsxs26 } from "react/jsx-runtime";
5800
+ import { jsx as jsx199, jsxs as jsxs27 } from "react/jsx-runtime";
5801
+ var RADIO_TAP_TRANSITION = { type: "spring", stiffness: 600, damping: 22 };
5651
5802
  var radioFrameVariants = cva10(
5652
5803
  [
5653
5804
  "inline-flex items-center justify-center p-0 bg-transparent border-0 cursor-pointer transition-colors",
5654
5805
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
5655
- "disabled:pointer-events-none disabled:opacity-50"
5806
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50 disabled:pointer-events-none disabled:opacity-50"
5656
5807
  ],
5657
5808
  {
5658
5809
  variants: {
@@ -5667,7 +5818,33 @@ var radioFrameVariants = cva10(
5667
5818
  }
5668
5819
  }
5669
5820
  );
5670
- var Radio = React14.forwardRef(
5821
+ function RadioGlyph({ checked }) {
5822
+ return /* @__PURE__ */ jsxs27(
5823
+ "svg",
5824
+ {
5825
+ className: "size-full max-h-none max-w-none",
5826
+ viewBox: "0 0 24 24",
5827
+ fill: "none",
5828
+ xmlns: "http://www.w3.org/2000/svg",
5829
+ "aria-hidden": true,
5830
+ children: [
5831
+ /* @__PURE__ */ jsx199(
5832
+ "circle",
5833
+ {
5834
+ cx: "12",
5835
+ cy: "12",
5836
+ r: "11.5",
5837
+ stroke: "var(--color-primary)",
5838
+ strokeWidth: "1",
5839
+ fill: "transparent"
5840
+ }
5841
+ ),
5842
+ checked && /* @__PURE__ */ jsx199("circle", { cx: "12", cy: "12", r: "5", fill: "var(--color-primary)" })
5843
+ ]
5844
+ }
5845
+ );
5846
+ }
5847
+ var Radio = React15.forwardRef(
5671
5848
  ({
5672
5849
  checked = false,
5673
5850
  onCheckedChange,
@@ -5680,57 +5857,80 @@ var Radio = React14.forwardRef(
5680
5857
  }, ref) => {
5681
5858
  const handleClick = (e) => {
5682
5859
  onClick?.(e);
5683
- if (!disabled && !e.defaultPrevented) {
5684
- onCheckedChange?.(!checked);
5860
+ if (!disabled && !e.defaultPrevented && !checked) {
5861
+ onCheckedChange?.(true);
5685
5862
  }
5686
5863
  };
5687
5864
  const s = size ?? "lg";
5688
- return /* @__PURE__ */ jsx198(
5689
- "button",
5865
+ return /* @__PURE__ */ jsx199(
5866
+ motion4.span,
5867
+ {
5868
+ className: cn("inline-flex", disabled && "pointer-events-none"),
5869
+ whileTap: { scale: 0.85 },
5870
+ transition: RADIO_TAP_TRANSITION,
5871
+ children: /* @__PURE__ */ jsx199(
5872
+ "button",
5873
+ {
5874
+ ...rest,
5875
+ ref,
5876
+ type: "button",
5877
+ role: "radio",
5878
+ "aria-checked": checked,
5879
+ "data-value": value,
5880
+ disabled,
5881
+ onClick: handleClick,
5882
+ className: cn(radioFrameVariants({ size: s }), className),
5883
+ children: /* @__PURE__ */ jsx199(RadioGlyph, { checked })
5884
+ }
5885
+ )
5886
+ }
5887
+ );
5888
+ }
5889
+ );
5890
+ Radio.displayName = "Radio";
5891
+ var RadioGroup = React15.forwardRef(
5892
+ ({ className, onValueChange, ...rest }, ref) => /* @__PURE__ */ jsx199(
5893
+ BaseRadioGroup,
5894
+ {
5895
+ ref,
5896
+ onValueChange: (value) => onValueChange?.(value),
5897
+ className: cn("flex flex-col gap-2", className),
5898
+ ...rest
5899
+ }
5900
+ )
5901
+ );
5902
+ RadioGroup.displayName = "RadioGroup";
5903
+ var RadioGroupItem = React15.forwardRef(
5904
+ ({ className, size, ...rest }, ref) => {
5905
+ const s = size ?? "lg";
5906
+ return /* @__PURE__ */ jsx199(
5907
+ BaseRadio.Root,
5690
5908
  {
5691
- ...rest,
5692
5909
  ref,
5693
- type: "button",
5694
- role: "radio",
5695
- "aria-checked": checked,
5696
- "data-value": value,
5697
- disabled,
5698
- onClick: handleClick,
5910
+ nativeButton: true,
5699
5911
  className: cn(radioFrameVariants({ size: s }), className),
5700
- children: /* @__PURE__ */ jsxs26(
5701
- "svg",
5912
+ ...rest,
5913
+ render: (props, state) => /* @__PURE__ */ jsx199(
5914
+ motion4.span,
5702
5915
  {
5703
- className: "size-full max-h-none max-w-none",
5704
- viewBox: "0 0 24 24",
5705
- fill: "none",
5706
- xmlns: "http://www.w3.org/2000/svg",
5707
- "aria-hidden": true,
5708
- children: [
5709
- /* @__PURE__ */ jsx198(
5710
- "circle",
5711
- {
5712
- cx: "12",
5713
- cy: "12",
5714
- r: "11.5",
5715
- stroke: "var(--color-primary)",
5716
- strokeWidth: "1",
5717
- fill: "transparent"
5718
- }
5719
- ),
5720
- checked && /* @__PURE__ */ jsx198("circle", { cx: "12", cy: "12", r: "5", fill: "var(--color-primary)" })
5721
- ]
5916
+ className: "inline-flex",
5917
+ whileTap: { scale: 0.85 },
5918
+ transition: RADIO_TAP_TRANSITION,
5919
+ children: /* @__PURE__ */ jsx199("button", { ...props, type: "button", children: /* @__PURE__ */ jsx199(RadioGlyph, { checked: state.checked }) })
5722
5920
  }
5723
5921
  )
5724
5922
  }
5725
5923
  );
5726
5924
  }
5727
5925
  );
5728
- Radio.displayName = "Radio";
5926
+ RadioGroupItem.displayName = "RadioGroupItem";
5729
5927
 
5730
5928
  // src/components/ui/segmented-control.tsx
5731
- import * as React15 from "react";
5929
+ import * as React16 from "react";
5930
+ import { ToggleGroup as BaseToggleGroup } from "@base-ui-components/react/toggle-group";
5931
+ import { Toggle as BaseToggle } from "@base-ui-components/react/toggle";
5732
5932
  import { cva as cva11 } from "class-variance-authority";
5733
- import { Fragment as Fragment4, jsx as jsx199, jsxs as jsxs27 } from "react/jsx-runtime";
5933
+ import { Fragment as Fragment4, jsx as jsx200, jsxs as jsxs28 } from "react/jsx-runtime";
5734
5934
  var controlVariants = cva11(
5735
5935
  [
5736
5936
  "inline-flex min-w-0 items-stretch overflow-hidden rounded-[var(--radius-md)]",
@@ -5761,7 +5961,11 @@ var segmentVariants = cva11(
5761
5961
  "text-center text-sm font-bold leading-5 transition-colors",
5762
5962
  "border-0 border-r border-[var(--wvk-border-bold)] last:border-r-0",
5763
5963
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
5764
- "[&_svg]:shrink-0 [&_svg]:text-current"
5964
+ "[&_svg]:shrink-0 [&_svg]:text-current",
5965
+ /** Semantic primary / primary-foreground: blue pill + white ink in light; white pill + blue ink in dark. */
5966
+ "data-[pressed]:bg-primary data-[pressed]:text-primary-foreground",
5967
+ "bg-transparent text-[var(--wvk-foreground-primary)] hover:bg-[var(--wvk-surface-tertiary)]",
5968
+ "data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 data-[disabled]:pointer-events-none"
5765
5969
  ],
5766
5970
  {
5767
5971
  variants: {
@@ -5770,11 +5974,6 @@ var segmentVariants = cva11(
5770
5974
  md: "gap-2 px-[var(--wvk-px-md)] py-0 text-sm leading-5",
5771
5975
  lg: "gap-2 px-[var(--wvk-px-lg)] py-0 text-sm leading-5"
5772
5976
  },
5773
- active: {
5774
- /** Semantic primary / primary-foreground: blue pill + white ink in light; white pill + blue ink in dark. */
5775
- true: "bg-primary text-primary-foreground",
5776
- false: "bg-transparent text-[var(--wvk-foreground-primary)] hover:bg-[var(--wvk-surface-tertiary)]"
5777
- },
5778
5977
  widthMode: {
5779
5978
  fill: "min-w-0 flex-1",
5780
5979
  auto: "shrink-0 grow-0"
@@ -5782,20 +5981,19 @@ var segmentVariants = cva11(
5782
5981
  },
5783
5982
  defaultVariants: {
5784
5983
  size: "md",
5785
- active: false,
5786
5984
  widthMode: "fill"
5787
5985
  }
5788
5986
  }
5789
5987
  );
5790
- var SegmentedControlContext = React15.createContext(null);
5988
+ var SegmentedControlContext = React16.createContext(null);
5791
5989
  function useSegmentedControlContext(component) {
5792
- const ctx = React15.useContext(SegmentedControlContext);
5990
+ const ctx = React16.useContext(SegmentedControlContext);
5793
5991
  if (!ctx) {
5794
5992
  throw new Error(`${component} must be used within <SegmentedControl>`);
5795
5993
  }
5796
5994
  return ctx;
5797
5995
  }
5798
- var SegmentedControl = React15.forwardRef(
5996
+ var SegmentedControl = React16.forwardRef(
5799
5997
  ({
5800
5998
  value,
5801
5999
  onChange,
@@ -5812,31 +6010,30 @@ var SegmentedControl = React15.forwardRef(
5812
6010
  labelInfo,
5813
6011
  children
5814
6012
  }, ref) => {
5815
- const labelId = React15.useId();
6013
+ const labelId = React16.useId();
5816
6014
  const resolvedSize = size ?? "md";
5817
6015
  const widthMode = autoWidth ? "auto" : "fill";
5818
6016
  const labelled = fieldLabel && hasRenderableFieldLabelText(label);
5819
- const notify = React15.useCallback(
6017
+ const notify = React16.useCallback(
5820
6018
  (next) => {
5821
6019
  onValueChange?.(next);
5822
6020
  onChange?.(next);
5823
6021
  },
5824
6022
  [onChange, onValueChange]
5825
6023
  );
5826
- const ctx = React15.useMemo(
5827
- () => ({
5828
- value,
5829
- onValueChange: notify,
5830
- size: resolvedSize,
5831
- widthMode
5832
- }),
5833
- [value, notify, resolvedSize, widthMode]
6024
+ const ctx = React16.useMemo(
6025
+ () => ({ size: resolvedSize, widthMode }),
6026
+ [resolvedSize, widthMode]
5834
6027
  );
5835
- const tablist = /* @__PURE__ */ jsx199(
5836
- "div",
6028
+ const group = /* @__PURE__ */ jsx200(
6029
+ BaseToggleGroup,
5837
6030
  {
5838
6031
  ref,
5839
- role: "tablist",
6032
+ value: value ? [value] : [],
6033
+ onValueChange: (next) => {
6034
+ const v = next[0];
6035
+ if (typeof v === "string") notify(v);
6036
+ },
5840
6037
  "aria-label": labelled ? void 0 : ariaLabel,
5841
6038
  "aria-labelledby": labelled ? labelId : void 0,
5842
6039
  className: cn(
@@ -5845,8 +6042,8 @@ var SegmentedControl = React15.forwardRef(
5845
6042
  children
5846
6043
  }
5847
6044
  );
5848
- return /* @__PURE__ */ jsx199(SegmentedControlContext.Provider, { value: ctx, children: labelled ? /* @__PURE__ */ jsxs27("div", { className: "flex w-full min-w-0 flex-col gap-1", children: [
5849
- /* @__PURE__ */ jsx199(
6045
+ return /* @__PURE__ */ jsx200(SegmentedControlContext.Provider, { value: ctx, children: labelled ? /* @__PURE__ */ jsxs28("div", { className: "flex w-full min-w-0 flex-col gap-1", children: [
6046
+ /* @__PURE__ */ jsx200(
5850
6047
  FieldLabel,
5851
6048
  {
5852
6049
  id: labelId,
@@ -5857,28 +6054,23 @@ var SegmentedControl = React15.forwardRef(
5857
6054
  children: label
5858
6055
  }
5859
6056
  ),
5860
- tablist
5861
- ] }) : tablist });
6057
+ group
6058
+ ] }) : group });
5862
6059
  }
5863
6060
  );
5864
6061
  SegmentedControl.displayName = "SegmentedControl";
5865
- var SegmentedControlItem = React15.forwardRef(
6062
+ var SegmentedControlItem = React16.forwardRef(
5866
6063
  ({
5867
- value: itemValue,
6064
+ value,
5868
6065
  label,
5869
6066
  icon,
5870
6067
  iconPlacement = "trailing",
5871
- disabled,
5872
6068
  className,
5873
- type = "button",
5874
6069
  ...rest
5875
6070
  }, ref) => {
5876
- const { value, onValueChange, size, widthMode } = useSegmentedControlContext(
5877
- "SegmentedControlItem"
5878
- );
5879
- const isActive = itemValue === value;
6071
+ const { size, widthMode } = useSegmentedControlContext("SegmentedControlItem");
5880
6072
  const iconBoxClass2 = size === "sm" ? wvkIconSmClass : wvkIconLgClass;
5881
- const iconBox = icon ? /* @__PURE__ */ jsx199(
6073
+ const iconBox = icon ? /* @__PURE__ */ jsx200(
5882
6074
  "span",
5883
6075
  {
5884
6076
  className: cn(
@@ -5890,30 +6082,19 @@ var SegmentedControlItem = React15.forwardRef(
5890
6082
  ) : null;
5891
6083
  const hasLabel = Boolean(label);
5892
6084
  const hasIcon = Boolean(icon);
5893
- const content = hasLabel && hasIcon ? iconPlacement === "leading" ? /* @__PURE__ */ jsxs27(Fragment4, { children: [
6085
+ const content = hasLabel && hasIcon ? iconPlacement === "leading" ? /* @__PURE__ */ jsxs28(Fragment4, { children: [
5894
6086
  iconBox,
5895
- /* @__PURE__ */ jsx199("span", { className: "min-w-0 truncate", children: label })
5896
- ] }) : /* @__PURE__ */ jsxs27(Fragment4, { children: [
5897
- /* @__PURE__ */ jsx199("span", { className: "min-w-0 truncate", children: label }),
6087
+ /* @__PURE__ */ jsx200("span", { className: "min-w-0 truncate", children: label })
6088
+ ] }) : /* @__PURE__ */ jsxs28(Fragment4, { children: [
6089
+ /* @__PURE__ */ jsx200("span", { className: "min-w-0 truncate", children: label }),
5898
6090
  iconBox
5899
- ] }) : hasIcon ? iconBox : hasLabel ? /* @__PURE__ */ jsx199("span", { className: "min-w-0 truncate", children: label }) : null;
5900
- return /* @__PURE__ */ jsx199(
5901
- "button",
6091
+ ] }) : hasIcon ? iconBox : hasLabel ? /* @__PURE__ */ jsx200("span", { className: "min-w-0 truncate", children: label }) : null;
6092
+ return /* @__PURE__ */ jsx200(
6093
+ BaseToggle,
5902
6094
  {
5903
6095
  ref,
5904
- type,
5905
- role: "tab",
5906
- "aria-selected": isActive,
5907
- disabled,
5908
- "data-active": isActive ? "" : void 0,
5909
- onClick: () => {
5910
- if (!disabled) onValueChange(itemValue);
5911
- },
5912
- className: cn(
5913
- segmentVariants({ size, active: isActive, widthMode }),
5914
- disabled && "cursor-not-allowed opacity-50 pointer-events-none",
5915
- className
5916
- ),
6096
+ value,
6097
+ className: cn(segmentVariants({ size, widthMode }), className),
5917
6098
  ...rest,
5918
6099
  children: content
5919
6100
  }
@@ -5925,20 +6106,21 @@ var SegmentedControlTrigger = SegmentedControlItem;
5925
6106
  SegmentedControlTrigger.displayName = "SegmentedControlTrigger";
5926
6107
 
5927
6108
  // src/components/ui/select.tsx
5928
- import * as React16 from "react";
6109
+ import * as React17 from "react";
6110
+ import { Select as BaseSelect } from "@base-ui-components/react/select";
5929
6111
  import { cva as cva12 } from "class-variance-authority";
5930
- import { jsx as jsx200, jsxs as jsxs28 } from "react/jsx-runtime";
6112
+ import { jsx as jsx201, jsxs as jsxs29 } from "react/jsx-runtime";
5931
6113
  var selectShellVariants = cva12(
5932
6114
  [
5933
6115
  "relative isolate min-h-0 min-w-0 w-full overflow-visible border-0 bg-[var(--input-surface)] text-[var(--input-text)] outline-none transition-[box-shadow,background-color,color]",
5934
- "focus-within:outline-none",
5935
- "has-[:disabled]:bg-wvk-tertiary has-[:disabled]:text-[var(--input-text)]/40"
6116
+ "data-[popup-open]:shadow-[0_0_0_2px_var(--input-focus)] focus-visible:shadow-[0_0_0_2px_var(--input-focus)]",
6117
+ "data-[disabled]:bg-wvk-tertiary data-[disabled]:text-[var(--input-text)]/40 data-[disabled]:cursor-not-allowed"
5936
6118
  ],
5937
6119
  {
5938
6120
  variants: {
5939
6121
  inputStyle: {
5940
- border: "shadow-[0_0_0_1px_var(--input-border-rest)] has-[:disabled]:shadow-[0_0_0_1px_var(--input-border-rest)]",
5941
- solid: "shadow-none has-[:disabled]:shadow-none"
6122
+ border: "shadow-[0_0_0_1px_var(--input-border-rest)] data-[disabled]:shadow-[0_0_0_1px_var(--input-border-rest)]",
6123
+ solid: "shadow-none data-[disabled]:shadow-none"
5942
6124
  },
5943
6125
  size: {
5944
6126
  sm: "h-8 rounded-[var(--radius-md)]",
@@ -5952,26 +6134,11 @@ var selectShellVariants = cva12(
5952
6134
  }
5953
6135
  }
5954
6136
  );
5955
- var selectFieldVariants = cva12(
5956
- [
5957
- "absolute inset-0 z-[1] box-border min-h-0 min-w-0 h-full w-full cursor-pointer appearance-none border-0 bg-transparent py-0",
5958
- "outline-none ring-0 focus:border-0 focus:outline-none focus:ring-0",
5959
- "text-[var(--input-text)] disabled:cursor-not-allowed"
5960
- ],
5961
- {
5962
- variants: {
5963
- size: {
5964
- /* pr: inset + chevron (kit 20px on md/lg, 14px sm) + gap so text never clips the icon */
5965
- sm: "rounded-[var(--radius-md)] pl-[var(--wvk-px-sm)] pr-[calc(var(--wvk-px-sm)+var(--wvk-icon-sm)+var(--wvk-gap-lg))] text-xs",
5966
- md: "rounded-[var(--radius-md)] pl-[var(--wvk-px-md)] pr-[calc(var(--wvk-px-md)+var(--wvk-icon-lg)+var(--wvk-gap-lg))] text-sm",
5967
- lg: "rounded-[var(--radius-md)] pl-[var(--wvk-px-lg)] pr-[calc(var(--wvk-px-lg)+var(--wvk-icon-lg)+var(--wvk-gap-lg))] text-sm"
5968
- }
5969
- },
5970
- defaultVariants: {
5971
- size: "md"
5972
- }
5973
- }
5974
- );
6137
+ var triggerInsetClass = {
6138
+ sm: "pl-[var(--wvk-px-sm)] pr-[calc(var(--wvk-px-sm)+var(--wvk-icon-sm)+var(--wvk-gap-lg))] text-xs",
6139
+ md: "pl-[var(--wvk-px-md)] pr-[calc(var(--wvk-px-md)+var(--wvk-icon-lg)+var(--wvk-gap-lg))] text-sm",
6140
+ lg: "pl-[var(--wvk-px-lg)] pr-[calc(var(--wvk-px-lg)+var(--wvk-icon-lg)+var(--wvk-gap-lg))] text-sm"
6141
+ };
5975
6142
  var chevronInset = {
5976
6143
  sm: "right-[var(--wvk-px-sm)]",
5977
6144
  md: "right-[var(--wvk-px-md)]",
@@ -5982,292 +6149,302 @@ var chevronIconClass = {
5982
6149
  md: "size-[length:var(--wvk-icon-lg)] min-h-0 min-w-0 shrink-0",
5983
6150
  lg: "size-[length:var(--wvk-icon-lg)] min-h-0 min-w-0 shrink-0"
5984
6151
  };
5985
- var Select = React16.forwardRef(
5986
- ({
5987
- className,
5988
- inputStyle,
5989
- size = "md",
5990
- placeholder,
5991
- children,
5992
- disabled,
5993
- onFocus,
5994
- onBlur,
5995
- fieldLabel = false,
5996
- label,
5997
- labelRequired,
5998
- labelOptional = false,
5999
- labelIcon,
6000
- labelInfo,
6001
- id: idProp,
6002
- ...props
6003
- }, ref) => {
6004
- const [active, setActive] = React16.useState(false);
6005
- const generatedId = React16.useId();
6152
+ var SelectContext = React17.createContext({ multiple: false });
6153
+ var Select = React17.forwardRef(
6154
+ (props, ref) => {
6155
+ const {
6156
+ className,
6157
+ inputStyle,
6158
+ size = "md",
6159
+ placeholder,
6160
+ children,
6161
+ disabled,
6162
+ multiple,
6163
+ value,
6164
+ defaultValue,
6165
+ onValueChange,
6166
+ fieldLabel = false,
6167
+ label,
6168
+ labelRequired,
6169
+ labelOptional = false,
6170
+ labelIcon,
6171
+ labelInfo,
6172
+ id: idProp,
6173
+ name,
6174
+ required,
6175
+ open,
6176
+ defaultOpen,
6177
+ onOpenChange,
6178
+ "aria-label": ariaLabel
6179
+ } = props;
6180
+ const generatedId = React17.useId();
6006
6181
  const controlId = idProp ?? generatedId;
6007
6182
  const s = size ?? "md";
6008
6183
  const style = inputStyle ?? "border";
6009
- const shellClass = cn(
6010
- selectShellVariants({ inputStyle: style, size: s }),
6011
- !disabled && active && "shadow-[0_0_0_2px_var(--input-focus)]",
6012
- className
6013
- );
6014
- const shell = /* @__PURE__ */ jsxs28("div", { className: shellClass, "data-wvk-select": "", children: [
6015
- /* @__PURE__ */ jsxs28(
6016
- "select",
6017
- {
6018
- ref,
6019
- id: controlId,
6020
- disabled,
6021
- className: selectFieldVariants({ size: s }),
6022
- onFocus: (e) => {
6023
- setActive(true);
6024
- onFocus?.(e);
6025
- },
6026
- onBlur: (e) => {
6027
- setActive(false);
6028
- onBlur?.(e);
6029
- },
6030
- ...props,
6031
- children: [
6032
- placeholder && /* @__PURE__ */ jsx200("option", { value: "", disabled: true, hidden: true, children: placeholder }),
6033
- children
6034
- ]
6035
- }
6036
- ),
6037
- /* @__PURE__ */ jsx200(
6038
- "div",
6039
- {
6040
- className: cn(
6041
- "pointer-events-none absolute top-1/2 z-[2] flex -translate-y-1/2 items-center justify-center overflow-visible text-[var(--input-icon-muted)]",
6042
- chevronInset[s]
6043
- ),
6044
- "aria-hidden": true,
6045
- children: /* @__PURE__ */ jsx200(
6046
- ChevronUpDown_default,
6184
+ const isMultiple = Boolean(multiple);
6185
+ const trigger = /* @__PURE__ */ jsxs29(
6186
+ BaseSelect.Trigger,
6187
+ {
6188
+ ref,
6189
+ id: controlId,
6190
+ disabled,
6191
+ "aria-label": ariaLabel,
6192
+ className: cn(
6193
+ selectShellVariants({ inputStyle: style, size: s }),
6194
+ "flex items-center gap-1 text-left",
6195
+ triggerInsetClass[s],
6196
+ className
6197
+ ),
6198
+ children: [
6199
+ /* @__PURE__ */ jsx201(BaseSelect.Value, { className: "flex-1 min-w-0 truncate", children: (v) => {
6200
+ const empty = v == null || v === "" || Array.isArray(v) && v.length === 0;
6201
+ if (empty) {
6202
+ return /* @__PURE__ */ jsx201("span", { className: "text-[var(--input-placeholder)]", children: placeholder });
6203
+ }
6204
+ if (Array.isArray(v)) return v.join(", ");
6205
+ return v;
6206
+ } }),
6207
+ /* @__PURE__ */ jsx201(
6208
+ BaseSelect.Icon,
6047
6209
  {
6048
- className: chevronIconClass[s],
6049
6210
  "aria-hidden": true,
6050
- focusable: false
6211
+ className: cn(
6212
+ "pointer-events-none absolute top-1/2 z-[2] flex -translate-y-1/2 items-center justify-center text-[var(--input-icon-muted)]",
6213
+ chevronInset[s]
6214
+ ),
6215
+ children: /* @__PURE__ */ jsx201(ChevronUpDown_default, { className: chevronIconClass[s], "aria-hidden": true })
6051
6216
  }
6052
6217
  )
6053
- }
6054
- )
6055
- ] });
6056
- if (fieldLabel && hasRenderableFieldLabelText(label)) {
6057
- return /* @__PURE__ */ jsxs28("div", { className: "flex w-full min-w-0 flex-col gap-1", children: [
6058
- /* @__PURE__ */ jsx200(
6059
- FieldLabel,
6218
+ ]
6219
+ }
6220
+ );
6221
+ const popup = /* @__PURE__ */ jsx201(BaseSelect.Portal, { children: /* @__PURE__ */ jsx201(
6222
+ BaseSelect.Positioner,
6223
+ {
6224
+ alignItemWithTrigger: false,
6225
+ sideOffset: 6,
6226
+ className: "z-50 outline-none",
6227
+ children: /* @__PURE__ */ jsx201(
6228
+ BaseSelect.Popup,
6060
6229
  {
6061
- htmlFor: controlId,
6062
- required: labelRequired,
6063
- optional: labelOptional,
6064
- icon: labelIcon,
6065
- info: labelInfo,
6066
- children: label
6230
+ className: cn(
6231
+ /* `--available-height` caps to viewport; the explicit `max-h` caps to a
6232
+ reasonable list size so menus with many items scroll. */
6233
+ "min-w-[var(--anchor-width)] max-h-[min(var(--available-height),18rem)] overflow-auto",
6234
+ "rounded-[var(--radius-md)]",
6235
+ "bg-[var(--wvk-surface-primary)] text-[var(--wvk-foreground-primary)]",
6236
+ /* Border sits *outside* the popup via ring (no layout shift) and uses
6237
+ the kit's low-transparency "dark" ramp — blue on light theme,
6238
+ white on dark theme — so the outline reads against either canvas.
6239
+ shadow-lg = elevated drop. */
6240
+ "shadow-lg ring-1 ring-[var(--wvk-transparency-dark-20)]",
6241
+ "p-1 outline-none"
6242
+ ),
6243
+ children: /* @__PURE__ */ jsx201(BaseSelect.List, { children })
6067
6244
  }
6245
+ )
6246
+ }
6247
+ ) });
6248
+ const baseProps = {
6249
+ disabled,
6250
+ name,
6251
+ required,
6252
+ open,
6253
+ defaultOpen,
6254
+ onOpenChange: onOpenChange ? (next) => onOpenChange(next) : void 0
6255
+ };
6256
+ const root = isMultiple ? /* @__PURE__ */ jsxs29(
6257
+ BaseSelect.Root,
6258
+ {
6259
+ multiple: true,
6260
+ value,
6261
+ defaultValue,
6262
+ onValueChange: (v) => onValueChange?.(
6263
+ v
6068
6264
  ),
6069
- shell
6070
- ] });
6265
+ ...baseProps,
6266
+ children: [
6267
+ trigger,
6268
+ popup
6269
+ ]
6270
+ }
6271
+ ) : /* @__PURE__ */ jsxs29(
6272
+ BaseSelect.Root,
6273
+ {
6274
+ value,
6275
+ defaultValue,
6276
+ onValueChange: (v) => onValueChange?.(
6277
+ v
6278
+ ),
6279
+ ...baseProps,
6280
+ children: [
6281
+ trigger,
6282
+ popup
6283
+ ]
6284
+ }
6285
+ );
6286
+ const ctx = React17.useMemo(
6287
+ () => ({ multiple: isMultiple }),
6288
+ [isMultiple]
6289
+ );
6290
+ const wrappedRoot = /* @__PURE__ */ jsx201(SelectContext.Provider, { value: ctx, children: root });
6291
+ if (fieldLabel && hasRenderableFieldLabelText(label)) {
6292
+ return /* @__PURE__ */ jsxs29("div", { className: "flex w-full min-w-0 flex-col gap-1", children: [
6293
+ /* @__PURE__ */ jsx201(
6294
+ FieldLabel,
6295
+ {
6296
+ htmlFor: controlId,
6297
+ required: labelRequired,
6298
+ optional: labelOptional,
6299
+ icon: labelIcon,
6300
+ info: labelInfo,
6301
+ children: label
6302
+ }
6303
+ ),
6304
+ wrappedRoot
6305
+ ] });
6071
6306
  }
6072
- return shell;
6307
+ return wrappedRoot;
6073
6308
  }
6074
6309
  );
6075
6310
  Select.displayName = "Select";
6311
+ function MultiSelectGlyph({ checked }) {
6312
+ return /* @__PURE__ */ jsx201(
6313
+ "span",
6314
+ {
6315
+ className: cn(
6316
+ "inline-flex size-4 shrink-0 items-center justify-center rounded-[3px] border border-[var(--color-primary)] transition-colors",
6317
+ checked ? "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]" : "bg-transparent text-transparent"
6318
+ ),
6319
+ "aria-hidden": true,
6320
+ children: /* @__PURE__ */ jsx201(Checkmark_default, { className: "size-3" })
6321
+ }
6322
+ );
6323
+ }
6324
+ var SelectItem = React17.forwardRef(
6325
+ ({ className, children, leadingIcon, trailingIcon, ...rest }, ref) => {
6326
+ const { multiple } = React17.useContext(SelectContext);
6327
+ return /* @__PURE__ */ jsxs29(
6328
+ BaseSelect.Item,
6329
+ {
6330
+ ref,
6331
+ className: cn(
6332
+ "relative flex w-full cursor-pointer select-none items-center gap-2 rounded-[var(--radius-sm)] px-2 py-1.5 text-sm outline-none transition-colors",
6333
+ "text-[var(--wvk-foreground-primary)] data-[selected]:font-bold",
6334
+ "data-[highlighted]:bg-[var(--wvk-surface-tertiary)]",
6335
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
6336
+ className
6337
+ ),
6338
+ ...rest,
6339
+ children: [
6340
+ multiple ? (
6341
+ /* Multi: checkbox on the LEFT, always rendered so labels align. */
6342
+ /* @__PURE__ */ jsx201(
6343
+ BaseSelect.ItemIndicator,
6344
+ {
6345
+ keepMounted: true,
6346
+ render: (props, state) => /* @__PURE__ */ jsx201("span", { ...props, children: /* @__PURE__ */ jsx201(MultiSelectGlyph, { checked: state.selected }) }),
6347
+ className: "inline-flex shrink-0 items-center justify-center"
6348
+ }
6349
+ )
6350
+ ) : null,
6351
+ leadingIcon ? /* @__PURE__ */ jsx201(
6352
+ "span",
6353
+ {
6354
+ className: "inline-flex size-4 shrink-0 items-center justify-center text-current [&_svg]:size-full",
6355
+ "aria-hidden": true,
6356
+ children: leadingIcon
6357
+ }
6358
+ ) : null,
6359
+ /* @__PURE__ */ jsx201(BaseSelect.ItemText, { className: "min-w-0 flex-1 truncate", children }),
6360
+ trailingIcon ? /* @__PURE__ */ jsx201(
6361
+ "span",
6362
+ {
6363
+ className: "inline-flex size-4 shrink-0 items-center justify-center text-current [&_svg]:size-full",
6364
+ "aria-hidden": true,
6365
+ children: trailingIcon
6366
+ }
6367
+ ) : null,
6368
+ !multiple ? (
6369
+ /* Single: tick on the RIGHT, only when selected. */
6370
+ /* @__PURE__ */ jsx201(BaseSelect.ItemIndicator, { className: "inline-flex size-4 shrink-0 items-center justify-center text-current", children: /* @__PURE__ */ jsx201(Checkmark_default, { className: "size-4", "aria-hidden": true }) })
6371
+ ) : null
6372
+ ]
6373
+ }
6374
+ );
6375
+ }
6376
+ );
6377
+ SelectItem.displayName = "SelectItem";
6378
+ var SelectGroup = BaseSelect.Group;
6379
+ var SelectGroupLabel = React17.forwardRef(({ className, ...rest }, ref) => /* @__PURE__ */ jsx201(
6380
+ BaseSelect.GroupLabel,
6381
+ {
6382
+ ref,
6383
+ className: cn(
6384
+ "px-2 py-1 text-xs font-bold uppercase tracking-wide text-[var(--wvk-foreground-tertiary)]",
6385
+ className
6386
+ ),
6387
+ ...rest
6388
+ }
6389
+ ));
6390
+ SelectGroupLabel.displayName = "SelectGroupLabel";
6391
+ var SelectSeparator = React17.forwardRef(({ className, ...rest }, ref) => /* @__PURE__ */ jsx201(
6392
+ "div",
6393
+ {
6394
+ ref,
6395
+ role: "separator",
6396
+ className: cn("my-1 h-px bg-[var(--wvk-border-default)]", className),
6397
+ ...rest
6398
+ }
6399
+ ));
6400
+ SelectSeparator.displayName = "SelectSeparator";
6076
6401
 
6077
6402
  // src/components/ui/slider.tsx
6078
- import * as React17 from "react";
6079
- import { Fragment as Fragment5, jsx as jsx201, jsxs as jsxs29 } from "react/jsx-runtime";
6080
- function clamp(val, min, max) {
6081
- return Math.min(Math.max(val, min), max);
6082
- }
6083
- var Slider = React17.forwardRef(
6403
+ import * as React18 from "react";
6404
+ import { Slider as BaseSlider } from "@base-ui-components/react/slider";
6405
+ import { Fragment as Fragment5, jsx as jsx202, jsxs as jsxs30 } from "react/jsx-runtime";
6406
+ var thumbClass = "absolute top-1/2 -translate-y-1/2 -translate-x-1/2 w-4 h-4 rounded-[var(--radius-full)] bg-white border-2 border-primary cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background dark:bg-primary-foreground";
6407
+ var Slider = React18.forwardRef(
6084
6408
  ({
6085
6409
  value,
6086
6410
  onChange,
6087
6411
  min = 0,
6088
6412
  max = 100,
6413
+ step = 1,
6089
6414
  disabled = false,
6090
6415
  className,
6091
6416
  ...rest
6092
6417
  }, ref) => {
6093
- const trackRef = React17.useRef(null);
6094
- const draggingRef = React17.useRef(null);
6095
6418
  const isRange = Array.isArray(value);
6096
- const singleValue = isRange ? 0 : value ?? min;
6097
- const rangeValue = isRange ? value : [min, max];
6098
- const toPercent = (v) => (v - min) / (max - min) * 100;
6099
- const valueFromPosition = (clientX) => {
6100
- const track = trackRef.current;
6101
- if (!track) return min;
6102
- const rect = track.getBoundingClientRect();
6103
- const ratio = clamp((clientX - rect.left) / rect.width, 0, 1);
6104
- return Math.round(min + ratio * (max - min));
6105
- };
6106
- const handlePointerDown = (e, thumb) => {
6107
- if (disabled) return;
6108
- e.preventDefault();
6109
- e.target.setPointerCapture(e.pointerId);
6110
- draggingRef.current = thumb;
6111
- };
6112
- const handlePointerMove = (e) => {
6113
- if (!draggingRef.current || disabled) return;
6114
- const next = valueFromPosition(e.clientX);
6115
- if (draggingRef.current === "single") {
6116
- onChange?.(next);
6117
- } else if (draggingRef.current === "start") {
6118
- onChange?.([clamp(next, min, rangeValue[1]), rangeValue[1]]);
6119
- } else {
6120
- onChange?.([rangeValue[0], clamp(next, rangeValue[0], max)]);
6121
- }
6122
- };
6123
- const handlePointerUp = () => {
6124
- draggingRef.current = null;
6125
- };
6126
- const handleKeyDown = (e, thumb) => {
6127
- if (disabled) return;
6128
- const step = 1;
6129
- if (thumb === "single") {
6130
- if (e.key === "ArrowRight" || e.key === "ArrowUp") {
6131
- e.preventDefault();
6132
- onChange?.(clamp(singleValue + step, min, max));
6133
- } else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
6134
- e.preventDefault();
6135
- onChange?.(clamp(singleValue - step, min, max));
6136
- } else if (e.key === "Home") {
6137
- e.preventDefault();
6138
- onChange?.(min);
6139
- } else if (e.key === "End") {
6140
- e.preventDefault();
6141
- onChange?.(max);
6142
- }
6143
- } else if (thumb === "start") {
6144
- if (e.key === "ArrowRight" || e.key === "ArrowUp") {
6145
- e.preventDefault();
6146
- onChange?.([clamp(rangeValue[0] + step, min, rangeValue[1]), rangeValue[1]]);
6147
- } else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
6148
- e.preventDefault();
6149
- onChange?.([clamp(rangeValue[0] - step, min, rangeValue[1]), rangeValue[1]]);
6150
- } else if (e.key === "Home") {
6151
- e.preventDefault();
6152
- onChange?.([min, rangeValue[1]]);
6153
- } else if (e.key === "End") {
6154
- e.preventDefault();
6155
- onChange?.([rangeValue[1], rangeValue[1]]);
6156
- }
6157
- } else {
6158
- if (e.key === "ArrowRight" || e.key === "ArrowUp") {
6159
- e.preventDefault();
6160
- onChange?.([rangeValue[0], clamp(rangeValue[1] + step, rangeValue[0], max)]);
6161
- } else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
6162
- e.preventDefault();
6163
- onChange?.([rangeValue[0], clamp(rangeValue[1] - step, rangeValue[0], max)]);
6164
- } else if (e.key === "Home") {
6165
- e.preventDefault();
6166
- onChange?.([rangeValue[0], rangeValue[0]]);
6167
- } else if (e.key === "End") {
6168
- e.preventDefault();
6169
- onChange?.([rangeValue[0], max]);
6170
- }
6171
- }
6172
- };
6173
- const handleTrackClick = (e) => {
6174
- if (disabled) return;
6175
- const next = valueFromPosition(e.clientX);
6176
- if (!isRange) {
6177
- onChange?.(next);
6178
- } else {
6179
- const distStart = Math.abs(next - rangeValue[0]);
6180
- const distEnd = Math.abs(next - rangeValue[1]);
6181
- if (distStart <= distEnd) {
6182
- onChange?.([clamp(next, min, rangeValue[1]), rangeValue[1]]);
6183
- } else {
6184
- onChange?.([rangeValue[0], clamp(next, rangeValue[0], max)]);
6185
- }
6186
- }
6187
- };
6188
- const thumbStyle = "absolute top-1/2 -translate-y-1/2 -translate-x-1/2 w-4 h-4 rounded-[var(--radius-full)] bg-white border-2 border-primary cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background dark:bg-primary-foreground";
6189
- return /* @__PURE__ */ jsx201(
6190
- "div",
6419
+ return /* @__PURE__ */ jsx202(
6420
+ BaseSlider.Root,
6191
6421
  {
6192
- ...rest,
6193
6422
  ref,
6423
+ value,
6424
+ onValueChange: (next) => {
6425
+ if (Array.isArray(next)) {
6426
+ onChange?.([next[0], next[1]]);
6427
+ } else {
6428
+ onChange?.(next);
6429
+ }
6430
+ },
6431
+ min,
6432
+ max,
6433
+ step,
6434
+ disabled,
6194
6435
  className: cn(
6195
6436
  "relative w-full select-none",
6196
- disabled && "pointer-events-none opacity-50",
6437
+ disabled && "opacity-50",
6197
6438
  className
6198
6439
  ),
6199
- children: /* @__PURE__ */ jsx201(
6200
- "div",
6201
- {
6202
- ref: trackRef,
6203
- className: "relative h-2 w-full cursor-pointer rounded-[var(--radius-full)] bg-muted",
6204
- onClick: handleTrackClick,
6205
- onPointerMove: handlePointerMove,
6206
- onPointerUp: handlePointerUp,
6207
- children: isRange ? /* @__PURE__ */ jsxs29(Fragment5, { children: [
6208
- /* @__PURE__ */ jsx201(
6209
- "div",
6210
- {
6211
- className: "absolute top-0 h-full rounded-[var(--radius-full)] bg-primary",
6212
- style: {
6213
- left: `${toPercent(rangeValue[0])}%`,
6214
- width: `${toPercent(rangeValue[1]) - toPercent(rangeValue[0])}%`
6215
- }
6216
- }
6217
- ),
6218
- /* @__PURE__ */ jsx201(
6219
- "div",
6220
- {
6221
- role: "slider",
6222
- tabIndex: disabled ? -1 : 0,
6223
- "aria-valuemin": min,
6224
- "aria-valuemax": max,
6225
- "aria-valuenow": rangeValue[0],
6226
- className: thumbStyle,
6227
- style: { left: `${toPercent(rangeValue[0])}%` },
6228
- onPointerDown: (e) => handlePointerDown(e, "start"),
6229
- onKeyDown: (e) => handleKeyDown(e, "start")
6230
- }
6231
- ),
6232
- /* @__PURE__ */ jsx201(
6233
- "div",
6234
- {
6235
- role: "slider",
6236
- tabIndex: disabled ? -1 : 0,
6237
- "aria-valuemin": min,
6238
- "aria-valuemax": max,
6239
- "aria-valuenow": rangeValue[1],
6240
- className: thumbStyle,
6241
- style: { left: `${toPercent(rangeValue[1])}%` },
6242
- onPointerDown: (e) => handlePointerDown(e, "end"),
6243
- onKeyDown: (e) => handleKeyDown(e, "end")
6244
- }
6245
- )
6246
- ] }) : /* @__PURE__ */ jsxs29(Fragment5, { children: [
6247
- /* @__PURE__ */ jsx201(
6248
- "div",
6249
- {
6250
- className: "absolute top-0 left-0 h-full rounded-[var(--radius-full)] bg-primary",
6251
- style: { width: `${toPercent(singleValue)}%` }
6252
- }
6253
- ),
6254
- /* @__PURE__ */ jsx201(
6255
- "div",
6256
- {
6257
- role: "slider",
6258
- tabIndex: disabled ? -1 : 0,
6259
- "aria-valuemin": min,
6260
- "aria-valuemax": max,
6261
- "aria-valuenow": singleValue,
6262
- className: thumbStyle,
6263
- style: { left: `${toPercent(singleValue)}%` },
6264
- onPointerDown: (e) => handlePointerDown(e, "single"),
6265
- onKeyDown: (e) => handleKeyDown(e, "single")
6266
- }
6267
- )
6268
- ] })
6269
- }
6270
- )
6440
+ ...rest,
6441
+ children: /* @__PURE__ */ jsxs30(BaseSlider.Control, { className: "relative h-2 w-full cursor-pointer rounded-[var(--radius-full)] bg-muted", children: [
6442
+ /* @__PURE__ */ jsx202(BaseSlider.Track, { className: "h-full w-full rounded-[var(--radius-full)]", children: /* @__PURE__ */ jsx202(BaseSlider.Indicator, { className: "h-full rounded-[var(--radius-full)] bg-primary" }) }),
6443
+ isRange ? /* @__PURE__ */ jsxs30(Fragment5, { children: [
6444
+ /* @__PURE__ */ jsx202(BaseSlider.Thumb, { index: 0, className: thumbClass }),
6445
+ /* @__PURE__ */ jsx202(BaseSlider.Thumb, { index: 1, className: thumbClass })
6446
+ ] }) : /* @__PURE__ */ jsx202(BaseSlider.Thumb, { className: thumbClass })
6447
+ ] })
6271
6448
  }
6272
6449
  );
6273
6450
  }
@@ -6275,9 +6452,9 @@ var Slider = React17.forwardRef(
6275
6452
  Slider.displayName = "Slider";
6276
6453
 
6277
6454
  // src/components/ui/split-button.tsx
6278
- import * as React18 from "react";
6455
+ import * as React19 from "react";
6279
6456
  import { cva as cva13 } from "class-variance-authority";
6280
- import { jsx as jsx202, jsxs as jsxs30 } from "react/jsx-runtime";
6457
+ import { jsx as jsx203, jsxs as jsxs31 } from "react/jsx-runtime";
6281
6458
  var splitButtonVariants = cva13(
6282
6459
  "inline-flex items-center font-bold whitespace-nowrap transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",
6283
6460
  {
@@ -6311,9 +6488,9 @@ var caretPadding = {
6311
6488
  lg: "px-4"
6312
6489
  };
6313
6490
  function CaretIcon({ className }) {
6314
- return /* @__PURE__ */ jsx202(ChevronDown_default, { className: cn(wvkIconLgClass, className), "aria-hidden": true });
6491
+ return /* @__PURE__ */ jsx203(ChevronDown_default, { className: cn(wvkIconLgClass, className), "aria-hidden": true });
6315
6492
  }
6316
- var SplitButton = React18.forwardRef(
6493
+ var SplitButton = React19.forwardRef(
6317
6494
  ({
6318
6495
  className,
6319
6496
  variant,
@@ -6325,7 +6502,7 @@ var SplitButton = React18.forwardRef(
6325
6502
  ...props
6326
6503
  }, ref) => {
6327
6504
  const resolvedSize = size ?? "lg";
6328
- return /* @__PURE__ */ jsxs30(
6505
+ return /* @__PURE__ */ jsxs31(
6329
6506
  "div",
6330
6507
  {
6331
6508
  ...wrapperProps,
@@ -6334,7 +6511,7 @@ var SplitButton = React18.forwardRef(
6334
6511
  wrapperProps?.className
6335
6512
  ),
6336
6513
  children: [
6337
- /* @__PURE__ */ jsx202(
6514
+ /* @__PURE__ */ jsx203(
6338
6515
  "button",
6339
6516
  {
6340
6517
  ref,
@@ -6347,14 +6524,14 @@ var SplitButton = React18.forwardRef(
6347
6524
  children
6348
6525
  }
6349
6526
  ),
6350
- /* @__PURE__ */ jsx202(
6527
+ /* @__PURE__ */ jsx203(
6351
6528
  "span",
6352
6529
  {
6353
6530
  className: "h-8 w-px self-center opacity-20 bg-current",
6354
6531
  "aria-hidden": "true"
6355
6532
  }
6356
6533
  ),
6357
- /* @__PURE__ */ jsx202(
6534
+ /* @__PURE__ */ jsx203(
6358
6535
  "button",
6359
6536
  {
6360
6537
  type: "button",
@@ -6365,7 +6542,7 @@ var SplitButton = React18.forwardRef(
6365
6542
  caretPadding[resolvedSize]
6366
6543
  ),
6367
6544
  "aria-label": "Open menu",
6368
- children: /* @__PURE__ */ jsx202(CaretIcon, {})
6545
+ children: /* @__PURE__ */ jsx203(CaretIcon, {})
6369
6546
  }
6370
6547
  )
6371
6548
  ]
@@ -6376,17 +6553,17 @@ var SplitButton = React18.forwardRef(
6376
6553
  SplitButton.displayName = "SplitButton";
6377
6554
 
6378
6555
  // src/components/ui/star-rating.tsx
6379
- import * as React19 from "react";
6380
- import { jsx as jsx203 } from "react/jsx-runtime";
6556
+ import * as React20 from "react";
6557
+ import { jsx as jsx204 } from "react/jsx-runtime";
6381
6558
  function StarIcon({ filled }) {
6382
6559
  if (filled) {
6383
- return /* @__PURE__ */ jsx203(StarActive_default, { className: wvkIconLgClass, "aria-hidden": true });
6560
+ return /* @__PURE__ */ jsx204(StarActive_default, { className: wvkIconLgClass, "aria-hidden": true });
6384
6561
  }
6385
- return /* @__PURE__ */ jsx203(Star_default, { className: wvkIconLgClass, "aria-hidden": true });
6562
+ return /* @__PURE__ */ jsx204(Star_default, { className: wvkIconLgClass, "aria-hidden": true });
6386
6563
  }
6387
- var StarRating = React19.forwardRef(
6564
+ var StarRating = React20.forwardRef(
6388
6565
  ({ value = 0, onChange, readonly = false, className }, ref) => {
6389
- const buttonRefs = React19.useRef([]);
6566
+ const buttonRefs = React20.useRef([]);
6390
6567
  const handleKeyDown = (e, starValue) => {
6391
6568
  if (readonly) return;
6392
6569
  if (e.key === "ArrowRight" || e.key === "ArrowUp") {
@@ -6401,7 +6578,7 @@ var StarRating = React19.forwardRef(
6401
6578
  buttonRefs.current[next - 1]?.focus();
6402
6579
  }
6403
6580
  };
6404
- return /* @__PURE__ */ jsx203(
6581
+ return /* @__PURE__ */ jsx204(
6405
6582
  "div",
6406
6583
  {
6407
6584
  ref,
@@ -6411,7 +6588,7 @@ var StarRating = React19.forwardRef(
6411
6588
  children: Array.from({ length: 5 }, (_, i) => {
6412
6589
  const starValue = i + 1;
6413
6590
  const filled = starValue <= value;
6414
- return /* @__PURE__ */ jsx203(
6591
+ return /* @__PURE__ */ jsx204(
6415
6592
  "button",
6416
6593
  {
6417
6594
  ref: (el) => {
@@ -6429,7 +6606,7 @@ var StarRating = React19.forwardRef(
6429
6606
  readonly ? "cursor-default" : "cursor-pointer hover:scale-110 transition-transform",
6430
6607
  filled ? "text-primary" : "text-muted-foreground"
6431
6608
  ),
6432
- children: /* @__PURE__ */ jsx203(StarIcon, { filled })
6609
+ children: /* @__PURE__ */ jsx204(StarIcon, { filled })
6433
6610
  },
6434
6611
  starValue
6435
6612
  );
@@ -6441,11 +6618,12 @@ var StarRating = React19.forwardRef(
6441
6618
  StarRating.displayName = "StarRating";
6442
6619
 
6443
6620
  // src/components/ui/tabs.tsx
6444
- import * as React20 from "react";
6621
+ import * as React21 from "react";
6622
+ import { Tabs as BaseTabs } from "@base-ui-components/react/tabs";
6445
6623
  import { cva as cva14 } from "class-variance-authority";
6446
- import { Fragment as Fragment6, jsx as jsx204, jsxs as jsxs31 } from "react/jsx-runtime";
6624
+ import { Fragment as Fragment6, jsx as jsx205, jsxs as jsxs32 } from "react/jsx-runtime";
6447
6625
  var tabListVariants = cva14(
6448
- "inline-flex w-full items-stretch border-b border-[var(--wvk-border-bold)]",
6626
+ "inline-flex w-full items-stretch border-b border-[var(--wvk-transparency-dark-20)]",
6449
6627
  {
6450
6628
  variants: {
6451
6629
  size: {
@@ -6459,44 +6637,40 @@ var tabListVariants = cva14(
6459
6637
  }
6460
6638
  }
6461
6639
  );
6462
- var TabsContext = React20.createContext(null);
6463
- var TabListContext = React20.createContext(null);
6640
+ var TabListContext = React21.createContext(null);
6464
6641
  function Tabs({
6465
- value: valueProp,
6642
+ value,
6466
6643
  defaultValue = "",
6467
6644
  onValueChange,
6645
+ className,
6468
6646
  children,
6469
- className
6647
+ ...rest
6470
6648
  }) {
6471
- const [uncontrolled, setUncontrolled] = React20.useState(defaultValue);
6472
- const isControlled = valueProp !== void 0;
6473
- const value = isControlled ? valueProp : uncontrolled;
6474
- const setValue = React20.useCallback(
6475
- (next) => {
6476
- if (!isControlled) setUncontrolled(next);
6477
- onValueChange?.(next);
6478
- },
6479
- [isControlled, onValueChange]
6480
- );
6481
- const ctx = React20.useMemo(
6482
- () => ({ value, onValueChange: setValue }),
6483
- [value, setValue]
6649
+ return /* @__PURE__ */ jsx205(
6650
+ BaseTabs.Root,
6651
+ {
6652
+ value,
6653
+ defaultValue,
6654
+ onValueChange: (next) => onValueChange?.(next),
6655
+ className: cn("w-full", className),
6656
+ ...rest,
6657
+ children
6658
+ }
6484
6659
  );
6485
- return /* @__PURE__ */ jsx204(TabsContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx204("div", { className: cn("w-full", className), children }) });
6486
6660
  }
6487
- var TabList = React20.forwardRef(
6488
- ({ children, size, autoWidth = false, className }, ref) => {
6661
+ var TabList = React21.forwardRef(
6662
+ ({ children, size, autoWidth = false, className, ...rest }, ref) => {
6489
6663
  const resolvedSize = size ?? "md";
6490
- const listCtx = React20.useMemo(
6664
+ const listCtx = React21.useMemo(
6491
6665
  () => ({ size: resolvedSize, autoWidth }),
6492
6666
  [resolvedSize, autoWidth]
6493
6667
  );
6494
- return /* @__PURE__ */ jsx204(TabListContext.Provider, { value: listCtx, children: /* @__PURE__ */ jsx204(
6495
- "div",
6668
+ return /* @__PURE__ */ jsx205(TabListContext.Provider, { value: listCtx, children: /* @__PURE__ */ jsx205(
6669
+ BaseTabs.List,
6496
6670
  {
6497
6671
  ref,
6498
- role: "tablist",
6499
6672
  className: cn(tabListVariants({ size: resolvedSize }), className),
6673
+ ...rest,
6500
6674
  children
6501
6675
  }
6502
6676
  ) });
@@ -6508,68 +6682,58 @@ var tabTextSize = {
6508
6682
  md: "text-sm",
6509
6683
  lg: "text-sm"
6510
6684
  };
6511
- var Tab = React20.forwardRef(
6685
+ var Tab = React21.forwardRef(
6512
6686
  ({
6513
6687
  value: tabValue = "",
6514
6688
  label,
6515
6689
  icon,
6516
6690
  iconPlacement = "trailing",
6517
- active: activeLegacy,
6518
6691
  children,
6519
- onClick,
6520
6692
  className,
6521
- type = "button",
6522
6693
  ...rest
6523
6694
  }, ref) => {
6524
- const tabsCtx = React20.useContext(TabsContext);
6525
- const listCtx = React20.useContext(TabListContext);
6695
+ const listCtx = React21.useContext(TabListContext);
6526
6696
  const size = listCtx?.size ?? "md";
6527
6697
  const fillRow = listCtx ? !listCtx.autoWidth : true;
6528
- const isActive = tabsCtx ? tabsCtx.value === tabValue : Boolean(activeLegacy);
6529
- const iconBox = icon ? /* @__PURE__ */ jsx204(
6698
+ const iconBox = icon ? /* @__PURE__ */ jsx205(
6530
6699
  "span",
6531
6700
  {
6532
6701
  className: cn(
6533
6702
  wvkIconMdClass,
6534
- "inline-flex items-center justify-center text-current [&_svg]:size-full"
6703
+ "inline-flex shrink-0 items-center justify-center text-current [&_svg]:size-full"
6535
6704
  ),
6536
6705
  children: icon
6537
6706
  }
6538
6707
  ) : null;
6539
6708
  let inner;
6540
6709
  if (!icon) {
6541
- inner = label != null ? /* @__PURE__ */ jsx204("span", { className: "min-w-0 truncate", children: label }) : children;
6710
+ inner = label != null ? /* @__PURE__ */ jsx205("span", { className: "min-w-0 truncate", children: label }) : children;
6542
6711
  } else {
6543
6712
  const textContent = label ?? children;
6544
6713
  const hasText = textContent != null && textContent !== false && !(Array.isArray(textContent) && textContent.length === 0);
6545
- inner = hasText && icon ? iconPlacement === "leading" ? /* @__PURE__ */ jsxs31(Fragment6, { children: [
6714
+ inner = hasText && icon ? iconPlacement === "leading" ? /* @__PURE__ */ jsxs32(Fragment6, { children: [
6546
6715
  iconBox,
6547
- /* @__PURE__ */ jsx204("span", { className: "inline-flex min-w-0 items-center justify-center gap-0.5 truncate", children: textContent })
6548
- ] }) : /* @__PURE__ */ jsxs31(Fragment6, { children: [
6549
- /* @__PURE__ */ jsx204("span", { className: "inline-flex min-w-0 items-center justify-center gap-0.5 truncate", children: textContent }),
6716
+ /* @__PURE__ */ jsx205("span", { className: "min-w-0 truncate", children: textContent })
6717
+ ] }) : /* @__PURE__ */ jsxs32(Fragment6, { children: [
6718
+ /* @__PURE__ */ jsx205("span", { className: "min-w-0 truncate", children: textContent }),
6550
6719
  iconBox
6551
6720
  ] }) : iconBox;
6552
6721
  }
6553
- return /* @__PURE__ */ jsx204(
6554
- "button",
6722
+ return /* @__PURE__ */ jsx205(
6723
+ BaseTabs.Tab,
6555
6724
  {
6556
6725
  ref,
6557
- type,
6558
- role: "tab",
6559
- "aria-selected": isActive,
6726
+ value: tabValue,
6560
6727
  className: cn(
6561
- "inline-flex items-center justify-center gap-2 px-4",
6728
+ "flex items-center justify-center gap-2 px-4 -mb-px",
6562
6729
  fillRow ? "min-w-0 flex-1" : "shrink-0 grow-0",
6563
6730
  "border-0 border-b-2 bg-transparent transition-colors",
6564
6731
  tabTextSize[size],
6565
6732
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
6566
- isActive ? "border-[var(--wvk-border-bold)] font-bold text-foreground" : "border-transparent font-normal text-muted-foreground hover:text-foreground/80",
6733
+ "border-transparent font-normal text-foreground hover:text-foreground/80",
6734
+ "data-[active]:border-[var(--wvk-border-bold)] data-[active]:font-bold data-[active]:text-foreground",
6567
6735
  className
6568
6736
  ),
6569
- onClick: (e) => {
6570
- tabsCtx?.onValueChange(tabValue);
6571
- onClick?.(e);
6572
- },
6573
6737
  ...rest,
6574
6738
  children: inner
6575
6739
  }
@@ -6577,22 +6741,23 @@ var Tab = React20.forwardRef(
6577
6741
  }
6578
6742
  );
6579
6743
  Tab.displayName = "Tab";
6744
+ var TabPanel = BaseTabs.Panel;
6745
+ var TabIndicator = BaseTabs.Indicator;
6580
6746
  var TabsList = TabList;
6581
- TabsList.displayName = "TabsList";
6582
6747
  var TabsTrigger = Tab;
6583
- TabsTrigger.displayName = "TabsTrigger";
6748
+ var TabsContent = TabPanel;
6584
6749
 
6585
6750
  // src/components/ui/tag.tsx
6586
- import * as React21 from "react";
6751
+ import * as React22 from "react";
6587
6752
  import { cva as cva15 } from "class-variance-authority";
6588
- import { jsx as jsx205, jsxs as jsxs32 } from "react/jsx-runtime";
6753
+ import { jsx as jsx206, jsxs as jsxs33 } from "react/jsx-runtime";
6589
6754
  function TagIconGlyph(props) {
6590
- return /* @__PURE__ */ jsx205(Tag_default, { ...props });
6755
+ return /* @__PURE__ */ jsx206(Tag_default, { ...props });
6591
6756
  }
6592
6757
  function applyTagIconSizing(node) {
6593
- if (!React21.isValidElement(node)) return node;
6758
+ if (!React22.isValidElement(node)) return node;
6594
6759
  const el = node;
6595
- return React21.cloneElement(el, {
6760
+ return React22.cloneElement(el, {
6596
6761
  className: cn("size-full", el.props.className)
6597
6762
  });
6598
6763
  }
@@ -6625,15 +6790,15 @@ function resolveTagLeadingContent(showLeadingIcon, leadingIcon, icon, size) {
6625
6790
  if (showLeadingIcon === false) return null;
6626
6791
  if (showLeadingIcon === true) {
6627
6792
  if (leadingIcon != null) {
6628
- return /* @__PURE__ */ jsx205(TagLeadingIcon, { name: leadingIcon, className: "size-full", "aria-hidden": true });
6793
+ return /* @__PURE__ */ jsx206(TagLeadingIcon, { name: leadingIcon, className: "size-full", "aria-hidden": true });
6629
6794
  }
6630
6795
  if (icon != null) return applyTagIconSizing(icon);
6631
- return /* @__PURE__ */ jsx205(TagIconGlyph, { className: "size-full", "aria-hidden": true });
6796
+ return /* @__PURE__ */ jsx206(TagIconGlyph, { className: "size-full", "aria-hidden": true });
6632
6797
  }
6633
6798
  if (icon != null) return applyTagIconSizing(icon);
6634
6799
  return null;
6635
6800
  }
6636
- var Tag2 = React21.forwardRef(
6801
+ var Tag2 = React22.forwardRef(
6637
6802
  ({
6638
6803
  className,
6639
6804
  tagStyle,
@@ -6658,14 +6823,14 @@ var Tag2 = React21.forwardRef(
6658
6823
  const body = hasLabelProp ? label : children;
6659
6824
  const hasBody = body != null && body !== false && !(typeof body === "string" && body.trim() === "");
6660
6825
  const clampTitle = labelTooltip ?? (hasLabelProp && typeof label === "string" && label.length > 0 ? label : void 0) ?? (typeof children === "string" && children.trim().length > 0 ? children : void 0);
6661
- return /* @__PURE__ */ jsxs32(
6826
+ return /* @__PURE__ */ jsxs33(
6662
6827
  "span",
6663
6828
  {
6664
6829
  className: cn(tagVariants({ tagStyle, size, className })),
6665
6830
  ref,
6666
6831
  ...props,
6667
6832
  children: [
6668
- leading != null ? /* @__PURE__ */ jsx205(
6833
+ leading != null ? /* @__PURE__ */ jsx206(
6669
6834
  "span",
6670
6835
  {
6671
6836
  className: cn(tagIconBoxClass[resolvedSize]),
@@ -6673,7 +6838,7 @@ var Tag2 = React21.forwardRef(
6673
6838
  children: leading
6674
6839
  }
6675
6840
  ) : null,
6676
- hasBody ? /* @__PURE__ */ jsx205(
6841
+ hasBody ? /* @__PURE__ */ jsx206(
6677
6842
  "span",
6678
6843
  {
6679
6844
  className: "min-h-0 min-w-0 flex-1 line-clamp-3 break-words text-left whitespace-normal [overflow-wrap:anywhere]",
@@ -6681,7 +6846,7 @@ var Tag2 = React21.forwardRef(
6681
6846
  children: body
6682
6847
  }
6683
6848
  ) : null,
6684
- onClose ? /* @__PURE__ */ jsx205(
6849
+ onClose ? /* @__PURE__ */ jsx206(
6685
6850
  "button",
6686
6851
  {
6687
6852
  type: "button",
@@ -6691,7 +6856,7 @@ var Tag2 = React21.forwardRef(
6691
6856
  tagIconBoxClass[resolvedSize]
6692
6857
  ),
6693
6858
  "aria-label": "Remove",
6694
- children: /* @__PURE__ */ jsx205(Close_default, { className: "size-full", "aria-hidden": true })
6859
+ children: /* @__PURE__ */ jsx206(Close_default, { className: "size-full", "aria-hidden": true })
6695
6860
  }
6696
6861
  ) : null
6697
6862
  ]
@@ -6702,9 +6867,10 @@ var Tag2 = React21.forwardRef(
6702
6867
  Tag2.displayName = "Tag";
6703
6868
 
6704
6869
  // src/components/ui/text-area.tsx
6705
- import * as React22 from "react";
6870
+ import * as React23 from "react";
6871
+ import { Field as BaseField } from "@base-ui-components/react/field";
6706
6872
  import { cva as cva16 } from "class-variance-authority";
6707
- import { jsx as jsx206, jsxs as jsxs33 } from "react/jsx-runtime";
6873
+ import { jsx as jsx207, jsxs as jsxs34 } from "react/jsx-runtime";
6708
6874
  var textAreaShellVariants = cva16(
6709
6875
  [
6710
6876
  "relative flex w-full min-w-0 flex-col border-0 bg-[var(--input-surface)] text-[var(--input-text)] outline-none transition-[box-shadow,background-color,color]",
@@ -6764,7 +6930,7 @@ function mergeRefs(...refs) {
6764
6930
  }
6765
6931
  };
6766
6932
  }
6767
- var TextArea = React22.forwardRef(
6933
+ var TextArea = React23.forwardRef(
6768
6934
  ({
6769
6935
  className,
6770
6936
  inputStyle,
@@ -6780,16 +6946,17 @@ var TextArea = React22.forwardRef(
6780
6946
  id: idProp,
6781
6947
  ...props
6782
6948
  }, ref) => {
6783
- const innerRef = React22.useRef(null);
6949
+ const innerRef = React23.useRef(null);
6784
6950
  const setRefs = mergeRefs(ref, innerRef);
6785
- const generatedId = React22.useId();
6951
+ const generatedId = React23.useId();
6786
6952
  const controlId = idProp ?? generatedId;
6787
6953
  const s = size ?? "md";
6788
6954
  const minH = MIN_HEIGHT_PX[s];
6789
- const [heightPx, setHeightPx] = React22.useState(null);
6790
- const dragRef = React22.useRef(
6955
+ const [heightPx, setHeightPx] = React23.useState(null);
6956
+ const dragRef = React23.useRef(
6791
6957
  null
6792
6958
  );
6959
+ const [isDragging, setIsDragging] = React23.useState(false);
6793
6960
  const onResizePointerDown = (e) => {
6794
6961
  if (disabled) return;
6795
6962
  e.preventDefault();
@@ -6801,6 +6968,7 @@ var TextArea = React22.forwardRef(
6801
6968
  startY: e.clientY,
6802
6969
  startH: ta.getBoundingClientRect().height
6803
6970
  };
6971
+ setIsDragging(true);
6804
6972
  };
6805
6973
  const onResizePointerMove = (e) => {
6806
6974
  const drag = dragRef.current;
@@ -6815,10 +6983,11 @@ var TextArea = React22.forwardRef(
6815
6983
  e.currentTarget.releasePointerCapture(e.pointerId);
6816
6984
  }
6817
6985
  dragRef.current = null;
6986
+ setIsDragging(false);
6818
6987
  };
6819
- const shell = /* @__PURE__ */ jsxs33("div", { className: cn(textAreaShellVariants({ inputStyle, size }), className), children: [
6820
- /* @__PURE__ */ jsx206(
6821
- "textarea",
6988
+ const shell = /* @__PURE__ */ jsxs34("div", { "data-wvk-input": "shell", style: { cursor: disabled ? "not-allowed" : "var(--wvk-cursor-text)" }, className: cn(textAreaShellVariants({ inputStyle, size }), className), children: [
6989
+ /* @__PURE__ */ jsx207(
6990
+ BaseField.Control,
6822
6991
  {
6823
6992
  ref: setRefs,
6824
6993
  id: controlId,
@@ -6828,20 +6997,24 @@ var TextArea = React22.forwardRef(
6828
6997
  ...style,
6829
6998
  ...heightPx != null ? { height: `${heightPx}px` } : void 0
6830
6999
  },
7000
+ render: /* @__PURE__ */ jsx207("textarea", {}),
6831
7001
  ...props
6832
7002
  }
6833
7003
  ),
6834
- !disabled && /* @__PURE__ */ jsx206(
7004
+ !disabled && /* @__PURE__ */ jsx207(
6835
7005
  "button",
6836
7006
  {
6837
7007
  type: "button",
6838
- className: "absolute bottom-0 right-0 z-10 flex h-8 w-8 cursor-ns-resize touch-none items-center justify-center border-0 bg-transparent p-0 select-none outline-none focus-visible:ring-2 focus-visible:ring-ring",
7008
+ className: cn(
7009
+ "absolute bottom-0 right-0 z-10 flex h-8 w-8 touch-none items-center justify-center border-0 bg-transparent p-0 select-none outline-none focus-visible:ring-2 focus-visible:ring-ring",
7010
+ isDragging ? "cursor-grabbing" : "cursor-ns-resize"
7011
+ ),
6839
7012
  onPointerDown: onResizePointerDown,
6840
7013
  onPointerMove: onResizePointerMove,
6841
7014
  onPointerUp: onResizePointerUp,
6842
7015
  onPointerCancel: onResizePointerUp,
6843
7016
  "aria-label": "Drag to resize height",
6844
- children: /* @__PURE__ */ jsx206(
7017
+ children: /* @__PURE__ */ jsx207(
6845
7018
  Expand_default,
6846
7019
  {
6847
7020
  className: cn(
@@ -6855,8 +7028,8 @@ var TextArea = React22.forwardRef(
6855
7028
  )
6856
7029
  ] });
6857
7030
  if (fieldLabel && hasRenderableFieldLabelText(label)) {
6858
- return /* @__PURE__ */ jsxs33("div", { className: "flex w-full min-w-0 flex-col gap-1", children: [
6859
- /* @__PURE__ */ jsx206(
7031
+ return /* @__PURE__ */ jsxs34("div", { className: "flex w-full min-w-0 flex-col gap-1", children: [
7032
+ /* @__PURE__ */ jsx207(
6860
7033
  FieldLabel,
6861
7034
  {
6862
7035
  htmlFor: controlId,
@@ -6876,9 +7049,10 @@ var TextArea = React22.forwardRef(
6876
7049
  TextArea.displayName = "TextArea";
6877
7050
 
6878
7051
  // src/components/ui/text-input.tsx
6879
- import * as React23 from "react";
7052
+ import * as React24 from "react";
7053
+ import { Input as BaseInput } from "@base-ui-components/react/input";
6880
7054
  import { cva as cva17 } from "class-variance-authority";
6881
- import { Fragment as Fragment7, jsx as jsx207, jsxs as jsxs34 } from "react/jsx-runtime";
7055
+ import { Fragment as Fragment7, jsx as jsx208, jsxs as jsxs35 } from "react/jsx-runtime";
6882
7056
  var textInputShellVariants = cva17(
6883
7057
  [
6884
7058
  "flex min-w-0 w-full items-center border-0 bg-[var(--input-surface)] text-[var(--input-text)] outline-none transition-[box-shadow,background-color,color]",
@@ -6938,15 +7112,15 @@ function mergeRefs2(...refs) {
6938
7112
  };
6939
7113
  }
6940
7114
  function ClearGlyph() {
6941
- return /* @__PURE__ */ jsx207(Close_default, { "aria-hidden": true, className: "size-full" });
7115
+ return /* @__PURE__ */ jsx208(Close_default, { "aria-hidden": true, className: "size-full" });
6942
7116
  }
6943
7117
  function TextInputSearchIcon(props) {
6944
- return /* @__PURE__ */ jsx207(MagnifyingGlass_default, { "aria-hidden": true, className: "size-full", ...props });
7118
+ return /* @__PURE__ */ jsx208(MagnifyingGlass_default, { "aria-hidden": true, className: "size-full", ...props });
6945
7119
  }
6946
7120
  function TextInputCalendarIcon(props) {
6947
- return /* @__PURE__ */ jsx207(Calendar_default, { "aria-hidden": true, className: "size-full", ...props });
7121
+ return /* @__PURE__ */ jsx208(Calendar_default, { "aria-hidden": true, className: "size-full", ...props });
6948
7122
  }
6949
- var TextInput = React23.forwardRef(
7123
+ var TextInput = React24.forwardRef(
6950
7124
  ({
6951
7125
  className,
6952
7126
  inputStyle,
@@ -6969,11 +7143,11 @@ var TextInput = React23.forwardRef(
6969
7143
  id: idProp,
6970
7144
  ...props
6971
7145
  }, ref) => {
6972
- const innerRef = React23.useRef(null);
6973
- const generatedId = React23.useId();
7146
+ const innerRef = React24.useRef(null);
7147
+ const generatedId = React24.useId();
6974
7148
  const inputId = idProp ?? generatedId;
6975
7149
  const controlled = value !== void 0;
6976
- const [internalValue, setInternalValue] = React23.useState(
7150
+ const [internalValue, setInternalValue] = React24.useState(
6977
7151
  () => defaultValue?.toString() ?? ""
6978
7152
  );
6979
7153
  const displayLength = controlled ? String(value ?? "").length : internalValue.length;
@@ -6995,7 +7169,7 @@ var TextInput = React23.forwardRef(
6995
7169
  onChange?.(e);
6996
7170
  };
6997
7171
  const setRefs = mergeRefs2(ref, innerRef);
6998
- const clearBtn = reserveClear ? /* @__PURE__ */ jsx207(
7172
+ const clearBtn = reserveClear ? /* @__PURE__ */ jsx208(
6999
7173
  "button",
7000
7174
  {
7001
7175
  type: "button",
@@ -7008,16 +7182,18 @@ var TextInput = React23.forwardRef(
7008
7182
  showClear ? "hover:text-[var(--input-text)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--input-surface)]" : "pointer-events-none opacity-0"
7009
7183
  ),
7010
7184
  "aria-label": "Clear input",
7011
- children: /* @__PURE__ */ jsx207(ClearGlyph, {})
7185
+ children: /* @__PURE__ */ jsx208(ClearGlyph, {})
7012
7186
  }
7013
7187
  ) : null;
7014
7188
  const hasAction = action != null && action !== false;
7015
- const shell = /* @__PURE__ */ jsxs34(
7189
+ const shell = /* @__PURE__ */ jsxs35(
7016
7190
  "div",
7017
7191
  {
7192
+ "data-wvk-input": "shell",
7193
+ style: { cursor: disabled ? "not-allowed" : "var(--wvk-cursor-text)" },
7018
7194
  className: cn(textInputShellVariants({ inputStyle, size }), className),
7019
7195
  children: [
7020
- leadingIcon ? /* @__PURE__ */ jsx207(
7196
+ leadingIcon ? /* @__PURE__ */ jsx208(
7021
7197
  "span",
7022
7198
  {
7023
7199
  className: cn(iconBoxClass[s], "text-[var(--input-icon-muted)]"),
@@ -7025,8 +7201,8 @@ var TextInput = React23.forwardRef(
7025
7201
  children: leadingIcon
7026
7202
  }
7027
7203
  ) : null,
7028
- /* @__PURE__ */ jsx207(
7029
- "input",
7204
+ /* @__PURE__ */ jsx208(
7205
+ BaseInput,
7030
7206
  {
7031
7207
  ref: setRefs,
7032
7208
  id: inputId,
@@ -7037,9 +7213,9 @@ var TextInput = React23.forwardRef(
7037
7213
  ...props
7038
7214
  }
7039
7215
  ),
7040
- /* @__PURE__ */ jsxs34("div", { className: "flex min-w-0 shrink-0 items-center gap-2", children: [
7216
+ /* @__PURE__ */ jsxs35("div", { className: "flex min-w-0 shrink-0 items-center gap-2", children: [
7041
7217
  clearBtn,
7042
- trailingIcon ? /* @__PURE__ */ jsx207(
7218
+ trailingIcon ? /* @__PURE__ */ jsx208(
7043
7219
  "span",
7044
7220
  {
7045
7221
  className: cn(
@@ -7050,23 +7226,23 @@ var TextInput = React23.forwardRef(
7050
7226
  children: trailingIcon
7051
7227
  }
7052
7228
  ) : null,
7053
- hasAction ? /* @__PURE__ */ jsxs34(Fragment7, { children: [
7054
- /* @__PURE__ */ jsx207(
7229
+ hasAction ? /* @__PURE__ */ jsxs35(Fragment7, { children: [
7230
+ /* @__PURE__ */ jsx208(
7055
7231
  "span",
7056
7232
  {
7057
7233
  className: "h-6 w-px shrink-0 rounded-full bg-[var(--input-border-rest)]",
7058
7234
  "aria-hidden": true
7059
7235
  }
7060
7236
  ),
7061
- /* @__PURE__ */ jsx207("div", { className: "min-w-0 text-sm font-bold uppercase leading-5 text-[var(--input-text)] [&_a]:border-0 [&_a]:text-sm [&_a]:font-bold [&_a]:uppercase [&_a]:leading-5 [&_a]:text-[var(--input-text)]", children: action })
7237
+ /* @__PURE__ */ jsx208("div", { className: "min-w-0 text-sm font-bold uppercase leading-5 text-[var(--input-text)] [&_a]:border-0 [&_a]:text-sm [&_a]:font-bold [&_a]:uppercase [&_a]:leading-5 [&_a]:text-[var(--input-text)]", children: action })
7062
7238
  ] }) : null
7063
7239
  ] })
7064
7240
  ]
7065
7241
  }
7066
7242
  );
7067
7243
  if (fieldLabel && hasRenderableFieldLabelText(label)) {
7068
- return /* @__PURE__ */ jsxs34("div", { className: "flex w-full min-w-0 flex-col gap-1", children: [
7069
- /* @__PURE__ */ jsx207(
7244
+ return /* @__PURE__ */ jsxs35("div", { className: "flex w-full min-w-0 flex-col gap-1", children: [
7245
+ /* @__PURE__ */ jsx208(
7070
7246
  FieldLabel,
7071
7247
  {
7072
7248
  htmlFor: inputId,
@@ -7086,15 +7262,19 @@ var TextInput = React23.forwardRef(
7086
7262
  TextInput.displayName = "TextInput";
7087
7263
 
7088
7264
  // src/components/ui/toggle-switch.tsx
7089
- import * as React24 from "react";
7265
+ import * as React25 from "react";
7266
+ import { Switch as BaseSwitch } from "@base-ui-components/react/switch";
7267
+ import { motion as motion5 } from "framer-motion";
7090
7268
  import { cva as cva18 } from "class-variance-authority";
7091
- import { jsx as jsx208 } from "react/jsx-runtime";
7269
+ import { jsx as jsx209 } from "react/jsx-runtime";
7092
7270
  var toggleSwitchVariants = cva18(
7093
7271
  [
7094
- "relative inline-flex shrink-0 cursor-pointer border transition-colors",
7272
+ "relative inline-flex shrink-0 cursor-pointer border transition-colors overflow-hidden",
7095
7273
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
7096
- "disabled:pointer-events-none disabled:opacity-50",
7097
- "rounded-full"
7274
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50 disabled:pointer-events-none disabled:opacity-50",
7275
+ "rounded-full",
7276
+ "data-[checked]:bg-primary data-[checked]:border-primary",
7277
+ "data-[unchecked]:bg-transparent data-[unchecked]:border-primary"
7098
7278
  ],
7099
7279
  {
7100
7280
  variants: {
@@ -7105,15 +7285,10 @@ var toggleSwitchVariants = cva18(
7105
7285
  md: "h-7 w-12 [--toggle-pad:3px] [--thumb-size:20px]",
7106
7286
  /** ~32×56px — pairs with Checkbox/Radio `lg`. */
7107
7287
  lg: "h-8 w-14 [--toggle-pad:2px] [--thumb-size:26px]"
7108
- },
7109
- checked: {
7110
- true: "bg-primary border-primary",
7111
- false: "bg-transparent border-primary"
7112
7288
  }
7113
7289
  },
7114
7290
  defaultVariants: {
7115
- size: "lg",
7116
- checked: false
7291
+ size: "lg"
7117
7292
  }
7118
7293
  }
7119
7294
  );
@@ -7121,49 +7296,82 @@ var toggleThumbVariants = cva18(
7121
7296
  [
7122
7297
  "pointer-events-none absolute top-1/2 -translate-y-1/2 rounded-full",
7123
7298
  "h-[length:var(--thumb-size)] w-[length:var(--thumb-size)]",
7124
- "transition-[left] duration-200 ease-in-out"
7125
- ],
7126
- {
7127
- variants: {
7128
- checked: {
7129
- true: "left-[calc(100%_-_var(--toggle-pad)_-_var(--thumb-size))] bg-white dark:bg-primary-foreground",
7130
- false: "left-[var(--toggle-pad)] bg-primary"
7131
- }
7132
- },
7133
- defaultVariants: {
7134
- checked: false
7135
- }
7136
- }
7137
- );
7138
- var ToggleSwitch = React24.forwardRef(
7299
+ "transition-[left] duration-200 ease-in-out",
7300
+ "data-[checked]:left-[calc(100%_-_var(--toggle-pad)_-_var(--thumb-size))] data-[checked]:bg-white dark:data-[checked]:bg-primary-foreground",
7301
+ "data-[unchecked]:left-[var(--toggle-pad)] data-[unchecked]:bg-primary"
7302
+ ]
7303
+ );
7304
+ var THUMB_CONFIG = {
7305
+ sm: { size: 16, pad: 3, leftOn: 23 },
7306
+ md: { size: 20, pad: 3, leftOn: 23 },
7307
+ lg: { size: 26, pad: 2, leftOn: 26 }
7308
+ };
7309
+ var ToggleSwitch = React25.forwardRef(
7139
7310
  ({
7140
- checked = false,
7141
- onCheckedChange,
7142
- disabled = false,
7143
7311
  className,
7144
7312
  size = "lg",
7145
- onClick,
7313
+ onCheckedChange,
7146
7314
  ...rest
7147
7315
  }, ref) => {
7148
- const handleClick = (e) => {
7149
- onClick?.(e);
7150
- if (!disabled && !e.defaultPrevented) {
7151
- onCheckedChange?.(!checked);
7152
- }
7153
- };
7154
7316
  const s = size ?? "lg";
7155
- return /* @__PURE__ */ jsx208(
7156
- "button",
7317
+ const cfg = THUMB_CONFIG[s];
7318
+ const [isPressed, setIsPressed] = React25.useState(false);
7319
+ return /* @__PURE__ */ jsx209(
7320
+ BaseSwitch.Root,
7157
7321
  {
7158
- ...rest,
7159
7322
  ref,
7160
- type: "button",
7161
- role: "switch",
7162
- "aria-checked": checked,
7163
- disabled,
7164
- onClick: handleClick,
7165
- className: cn(toggleSwitchVariants({ size: s, checked }), className),
7166
- children: /* @__PURE__ */ jsx208("span", { className: toggleThumbVariants({ checked }) })
7323
+ onCheckedChange: (checked) => onCheckedChange?.(checked),
7324
+ nativeButton: true,
7325
+ className: cn(toggleSwitchVariants({ size: s }), className),
7326
+ ...rest,
7327
+ render: (props, state) => /* @__PURE__ */ jsx209(
7328
+ "button",
7329
+ {
7330
+ ...props,
7331
+ type: "button",
7332
+ onPointerDown: (e) => {
7333
+ setIsPressed(true);
7334
+ props.onPointerDown?.(e);
7335
+ },
7336
+ onPointerUp: (e) => {
7337
+ setIsPressed(false);
7338
+ props.onPointerUp?.(e);
7339
+ },
7340
+ onPointerLeave: (e) => {
7341
+ setIsPressed(false);
7342
+ props.onPointerLeave?.(e);
7343
+ },
7344
+ onPointerCancel: () => setIsPressed(false),
7345
+ children: /* @__PURE__ */ jsx209(
7346
+ motion5.span,
7347
+ {
7348
+ "aria-hidden": true,
7349
+ className: cn(
7350
+ "pointer-events-none absolute rounded-full",
7351
+ state.checked ? "bg-white dark:bg-primary-foreground" : "bg-primary"
7352
+ ),
7353
+ style: {
7354
+ height: cfg.size,
7355
+ top: "50%",
7356
+ marginTop: -(cfg.size / 2),
7357
+ originX: state.checked ? 1 : 0
7358
+ },
7359
+ initial: false,
7360
+ animate: {
7361
+ left: state.checked ? cfg.leftOn : cfg.pad,
7362
+ width: cfg.size,
7363
+ scaleX: isPressed ? 1.28 : 1,
7364
+ scaleY: isPressed ? 0.82 : 1
7365
+ },
7366
+ transition: {
7367
+ left: { type: "spring", stiffness: 420, damping: 30 },
7368
+ scaleX: { type: "spring", stiffness: 700, damping: 22 },
7369
+ scaleY: { type: "spring", stiffness: 700, damping: 22 }
7370
+ }
7371
+ }
7372
+ )
7373
+ }
7374
+ )
7167
7375
  }
7168
7376
  );
7169
7377
  }
@@ -7171,18 +7379,263 @@ var ToggleSwitch = React24.forwardRef(
7171
7379
  ToggleSwitch.displayName = "ToggleSwitch";
7172
7380
 
7173
7381
  // src/components/theme-provider.tsx
7174
- import * as React25 from "react";
7175
- import { jsx as jsx209 } from "react/jsx-runtime";
7382
+ import * as React27 from "react";
7383
+
7384
+ // src/components/whimsy-cursor.tsx
7385
+ import * as React26 from "react";
7386
+ import { motion as motion6 } from "framer-motion";
7387
+ import { jsx as jsx210, jsxs as jsxs36 } from "react/jsx-runtime";
7388
+ var INTERACTIVE_SELECTOR = [
7389
+ "a[href]",
7390
+ "button:not(:disabled)",
7391
+ '[role="button"]:not([aria-disabled="true"])',
7392
+ '[role="link"]',
7393
+ '[role="tab"]',
7394
+ '[role="menuitem"]',
7395
+ "label[for]",
7396
+ "summary",
7397
+ 'input[type="checkbox"]:not(:disabled)',
7398
+ 'input[type="radio"]:not(:disabled)',
7399
+ "select:not(:disabled)",
7400
+ ".cursor-pointer"
7401
+ ].join(",");
7402
+ var ACTIVE_CLASS = "wvk-whimsy-cursor-active";
7403
+ var HIDE_STYLE_ID = "wvk-whimsy-cursor-style";
7404
+ var HIDE_NATIVE_CSS = `
7405
+ html.${ACTIVE_CLASS},
7406
+ html.${ACTIVE_CLASS} *,
7407
+ html.${ACTIVE_CLASS} *::before,
7408
+ html.${ACTIVE_CLASS} *::after {
7409
+ cursor: none !important;
7410
+ }
7411
+ `;
7412
+ function injectStyle(id, css) {
7413
+ if (typeof document === "undefined" || document.getElementById(id)) return;
7414
+ const style = document.createElement("style");
7415
+ style.id = id;
7416
+ style.textContent = css;
7417
+ document.head.appendChild(style);
7418
+ }
7419
+ function WhimsyCursor({
7420
+ hoverRotateDeg = -22
7421
+ } = {}) {
7422
+ const wrapperRef = React26.useRef(null);
7423
+ const [hover, setHover] = React26.useState(false);
7424
+ const [visible, setVisible] = React26.useState(false);
7425
+ const variant = hover ? "pointer" : "default";
7426
+ const hotspot = variant === "pointer" ? { x: 12, y: 8 } : { x: 9, y: 5 };
7427
+ React26.useEffect(() => {
7428
+ if (typeof window === "undefined") return;
7429
+ if (!window.matchMedia("(pointer: fine)").matches) return;
7430
+ injectStyle(HIDE_STYLE_ID, HIDE_NATIVE_CSS);
7431
+ document.documentElement.classList.add(ACTIVE_CLASS);
7432
+ let rafId = null;
7433
+ let nextX = 0;
7434
+ let nextY = 0;
7435
+ let dirty = false;
7436
+ const draw = () => {
7437
+ rafId = null;
7438
+ if (!dirty) return;
7439
+ const el = wrapperRef.current;
7440
+ if (el) {
7441
+ el.style.transform = `translate3d(${nextX}px, ${nextY}px, 0)`;
7442
+ }
7443
+ dirty = false;
7444
+ };
7445
+ const schedule = () => {
7446
+ if (rafId == null) rafId = requestAnimationFrame(draw);
7447
+ };
7448
+ const onMove = (e) => {
7449
+ nextX = e.clientX;
7450
+ nextY = e.clientY;
7451
+ dirty = true;
7452
+ setVisible(true);
7453
+ const target = e.target;
7454
+ const isInteractive = !!target?.closest?.(INTERACTIVE_SELECTOR);
7455
+ setHover((prev) => prev !== isInteractive ? isInteractive : prev);
7456
+ schedule();
7457
+ };
7458
+ const onLeave = () => setVisible(false);
7459
+ const onEnter = () => setVisible(true);
7460
+ window.addEventListener("pointermove", onMove, { passive: true });
7461
+ document.addEventListener("pointerleave", onLeave);
7462
+ document.addEventListener("pointerenter", onEnter);
7463
+ return () => {
7464
+ window.removeEventListener("pointermove", onMove);
7465
+ document.removeEventListener("pointerleave", onLeave);
7466
+ document.removeEventListener("pointerenter", onEnter);
7467
+ if (rafId != null) cancelAnimationFrame(rafId);
7468
+ document.documentElement.classList.remove(ACTIVE_CLASS);
7469
+ };
7470
+ }, []);
7471
+ return /* @__PURE__ */ jsx210(
7472
+ "div",
7473
+ {
7474
+ ref: wrapperRef,
7475
+ "aria-hidden": true,
7476
+ style: {
7477
+ position: "fixed",
7478
+ top: 0,
7479
+ left: 0,
7480
+ width: 32,
7481
+ height: 32,
7482
+ pointerEvents: "none",
7483
+ zIndex: 2147483647,
7484
+ opacity: visible ? 1 : 0,
7485
+ transition: "opacity 120ms ease",
7486
+ marginLeft: -hotspot.x,
7487
+ marginTop: -hotspot.y,
7488
+ willChange: "transform"
7489
+ },
7490
+ children: /* @__PURE__ */ jsx210(
7491
+ motion6.div,
7492
+ {
7493
+ className: "wvk-whimsy-cursor-rotor",
7494
+ "data-hover": hover ? "true" : "false",
7495
+ animate: { rotate: hover ? hoverRotateDeg : 0 },
7496
+ transition: { type: "spring", stiffness: 600, damping: 12, mass: 0.4 },
7497
+ style: {
7498
+ width: 32,
7499
+ height: 32,
7500
+ transformOrigin: `${hotspot.x}px ${hotspot.y}px`
7501
+ },
7502
+ children: variant === "pointer" ? /* @__PURE__ */ jsx210(PointerSvg, {}) : /* @__PURE__ */ jsx210(DefaultSvg, {})
7503
+ }
7504
+ )
7505
+ }
7506
+ );
7507
+ }
7508
+ function DefaultSvg() {
7509
+ return /* @__PURE__ */ jsxs36(
7510
+ "svg",
7511
+ {
7512
+ xmlns: "http://www.w3.org/2000/svg",
7513
+ width: 32,
7514
+ height: 32,
7515
+ fill: "none",
7516
+ viewBox: "0 0 32 32",
7517
+ children: [
7518
+ /* @__PURE__ */ jsx210("defs", { children: /* @__PURE__ */ jsx210(
7519
+ "filter",
7520
+ {
7521
+ id: "wvk-whimsy-cursor-default-shadow",
7522
+ filterUnits: "userSpaceOnUse",
7523
+ x: "-4",
7524
+ y: "-4",
7525
+ width: "40",
7526
+ height: "40",
7527
+ colorInterpolationFilters: "sRGB",
7528
+ children: /* @__PURE__ */ jsx210(
7529
+ "feDropShadow",
7530
+ {
7531
+ dx: "0",
7532
+ dy: "1.25",
7533
+ stdDeviation: "1",
7534
+ floodColor: "#000000",
7535
+ floodOpacity: "0.38"
7536
+ }
7537
+ )
7538
+ }
7539
+ ) }),
7540
+ /* @__PURE__ */ jsxs36("g", { filter: "url(#wvk-whimsy-cursor-default-shadow)", children: [
7541
+ /* @__PURE__ */ jsx210(
7542
+ "path",
7543
+ {
7544
+ fill: "#0055FF",
7545
+ d: "M10 6.028v14.637a.5.5 0 0 0 .86.348l2.424-2.503a.5.5 0 0 1 .808.127l2.225 4.523a1 1 0 0 0 1.379.435l2.234-1.229a1 1 0 0 0 .41-1.33l-2.192-4.31a.5.5 0 0 1 .446-.726h3.96a.5.5 0 0 0 .31-.893L10.808 5.635a.5.5 0 0 0-.809.393Z"
7546
+ }
7547
+ ),
7548
+ /* @__PURE__ */ jsx210(
7549
+ "path",
7550
+ {
7551
+ stroke: "white",
7552
+ strokeOpacity: ".8",
7553
+ strokeWidth: "2",
7554
+ d: "M9.42 4.985a1.502 1.502 0 0 1 1.882-.225l.125.089L23.48 14.32a1.501 1.501 0 0 1-.926 2.68h-3.147l1.823 3.583a2 2 0 0 1-.819 2.66l-2.234 1.229a2 2 0 0 1-2.759-.87l-1.911-3.886-1.93 1.993A1.5 1.5 0 0 1 9 20.665V6.028a1.5 1.5 0 0 1 .32-.926l.1-.117Z"
7555
+ }
7556
+ )
7557
+ ] })
7558
+ ]
7559
+ }
7560
+ );
7561
+ }
7562
+ function PointerSvg() {
7563
+ return /* @__PURE__ */ jsxs36(
7564
+ "svg",
7565
+ {
7566
+ xmlns: "http://www.w3.org/2000/svg",
7567
+ width: 32,
7568
+ height: 32,
7569
+ fill: "none",
7570
+ viewBox: "0 0 32 32",
7571
+ children: [
7572
+ /* @__PURE__ */ jsx210("defs", { children: /* @__PURE__ */ jsx210(
7573
+ "filter",
7574
+ {
7575
+ id: "wvk-whimsy-cursor-pointer-shadow",
7576
+ filterUnits: "userSpaceOnUse",
7577
+ x: "-4",
7578
+ y: "-4",
7579
+ width: "40",
7580
+ height: "40",
7581
+ colorInterpolationFilters: "sRGB",
7582
+ children: /* @__PURE__ */ jsx210(
7583
+ "feDropShadow",
7584
+ {
7585
+ dx: "0",
7586
+ dy: "1.25",
7587
+ stdDeviation: "1",
7588
+ floodColor: "#000000",
7589
+ floodOpacity: "0.38"
7590
+ }
7591
+ )
7592
+ }
7593
+ ) }),
7594
+ /* @__PURE__ */ jsxs36("g", { filter: "url(#wvk-whimsy-cursor-pointer-shadow)", children: [
7595
+ /* @__PURE__ */ jsx210(
7596
+ "path",
7597
+ {
7598
+ fill: "white",
7599
+ d: "M18.5 30H13c-5.44 0-9.083-4.964-11.41-14.272C.659 12.003 3.917 8.913 7 9.65V6a5 5 0 0 1 10 0v2.1a4.99 4.99 0 0 1 2.105.98A5 5 0 0 1 24.001 11a5 5 0 0 1 5 5v4c0 .19-.019.38-.054.565C28.409 25.897 23.907 30 18.5 30Z"
7600
+ }
7601
+ ),
7602
+ /* @__PURE__ */ jsx210(
7603
+ "path",
7604
+ {
7605
+ fill: "#0055FF",
7606
+ d: "M25 19.5V16a1 1 0 1 0-2 0 1 1 0 1 1-2 0v-2a1 1 0 1 0-2 0 1 1 0 1 1-2 0 3 3 0 0 1 5.895-.79A3 3 0 0 1 27 16v4a1 1 0 0 1-.033.256A8.5 8.5 0 0 1 18.5 28H13c-4.284 0-7.37-4.357-9.47-12.758-.698-2.792 2.321-4.805 4.177-2.95L9 13.587V6a3 3 0 1 1 6 0v7a1 1 0 1 1-2 0V6a1 1 0 1 0-2 0v10a1 1 0 0 1-1.707.707l-3-3c-.344-.344-1.053.129-.823 1.05C7.37 22.358 9.95 26 13 26h5.5a6.5 6.5 0 0 0 6.5-6.5ZM16 10a3 3 0 0 1 3 3v1a1 1 0 1 1-2 0v-1a1 1 0 1 0-2 0 1 1 0 1 1-2 0 3 3 0 0 1 3-3Zm-1 7a1 1 0 0 1 1 1v3a1 1 0 1 1-2 0v-3a1 1 0 0 1 1-1Zm4 0a1 1 0 0 1 1 1v3a1 1 0 1 1-2 0v-3a1 1 0 0 1 1-1Z"
7607
+ }
7608
+ )
7609
+ ] })
7610
+ ]
7611
+ }
7612
+ );
7613
+ }
7614
+
7615
+ // src/components/theme-provider.tsx
7616
+ import { jsx as jsx211, jsxs as jsxs37 } from "react/jsx-runtime";
7176
7617
  var STORAGE_KEY = "wvk-theme";
7618
+ var CURSOR_STYLE_STORAGE_KEY = "wvk-cursor-style";
7619
+ var CURSOR_STYLE_CLASS_ARROW = "wvk-cursor-style-arrow";
7177
7620
  var CURSOR_STYLE_ID = "wvk-cursor-style";
7178
7621
  var CURSOR_DEFAULT = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDMyIDMyIj4KICA8ZGVmcz4KICAgIDxmaWx0ZXIKICAgICAgaWQ9Ind2ay1jdXJzb3Itc2hhZG93IgogICAgICBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgIHg9Ii00IgogICAgICB5PSItNCIKICAgICAgd2lkdGg9IjQwIgogICAgICBoZWlnaHQ9IjQwIgogICAgICBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiCiAgICA+CiAgICAgIDxmZURyb3BTaGFkb3cgZHg9IjAiIGR5PSIxLjI1IiBzdGREZXZpYXRpb249IjEiIGZsb29kLWNvbG9yPSIjMDAwMDAwIiBmbG9vZC1vcGFjaXR5PSIwLjM4IiAvPgogICAgPC9maWx0ZXI+CiAgPC9kZWZzPgogIDxnIGZpbHRlcj0idXJsKCN3dmstY3Vyc29yLXNoYWRvdykiPgogICAgPHBhdGggZmlsbD0iIzAwNTVGRiIgZD0iTTEwIDYuMDI4djE0LjYzN2EuNS41IDAgMCAwIC44Ni4zNDhsMi40MjQtMi41MDNhLjUuNSAwIDAgMSAuODA4LjEyN2wyLjIyNSA0LjUyM2ExIDEgMCAwIDAgMS4zNzkuNDM1bDIuMjM0LTEuMjI5YTEgMSAwIDAgMCAuNDEtMS4zM2wtMi4xOTItNC4zMWEuNS41IDAgMCAxIC40NDYtLjcyNmgzLjk2YS41LjUgMCAwIDAgLjMxLS44OTNMMTAuODA4IDUuNjM1YS41LjUgMCAwIDAtLjgwOS4zOTNaIi8+CiAgICA8cGF0aCBzdHJva2U9IndoaXRlIiBzdHJva2Utb3BhY2l0eT0iLjgiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTkuNDIgNC45ODVhMS41MDIgMS41MDIgMCAwIDEgMS44ODItLjIyNWwuMTI1LjA4OUwyMy40OCAxNC4zMmExLjUwMSAxLjUwMSAwIDAgMS0uOTI2IDIuNjhoLTMuMTQ3bDEuODIzIDMuNTgzYTIgMiAwIDAgMS0uODE5IDIuNjZsLTIuMjM0IDEuMjI5YTIgMiAwIDAgMS0yLjc1OS0uODdsLTEuOTExLTMuODg2LTEuOTMgMS45OTNBMS41IDEuNSAwIDAgMSA5IDIwLjY2NVY2LjAyOGExLjUgMS41IDAgMCAxIC4zMi0uOTI2bC4xLS4xMTdaIi8+CiAgPC9nPgo8L3N2Zz4K") 9 5, default';
7179
7622
  var CURSOR_POINTER = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDMyIDMyIj4KICA8ZGVmcz4KICAgIDxmaWx0ZXIKICAgICAgaWQ9Ind2ay1jdXJzb3Itc2hhZG93IgogICAgICBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgIHg9Ii00IgogICAgICB5PSItNCIKICAgICAgd2lkdGg9IjQwIgogICAgICBoZWlnaHQ9IjQwIgogICAgICBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiCiAgICA+CiAgICAgIDxmZURyb3BTaGFkb3cgZHg9IjAiIGR5PSIxLjI1IiBzdGREZXZpYXRpb249IjEiIGZsb29kLWNvbG9yPSIjMDAwMDAwIiBmbG9vZC1vcGFjaXR5PSIwLjM4IiAvPgogICAgPC9maWx0ZXI+CiAgPC9kZWZzPgogIDxnIGZpbHRlcj0idXJsKCN3dmstY3Vyc29yLXNoYWRvdykiPgogICAgPHBhdGggZmlsbD0id2hpdGUiIGQ9Ik0xOC41IDMwSDEzYy01LjQ0IDAtOS4wODMtNC45NjQtMTEuNDEtMTQuMjcyQy42NTkgMTIuMDAzIDMuOTE3IDguOTEzIDcgOS42NVY2YTUgNSAwIDAgMSAxMCAwdjIuMWE0Ljk5IDQuOTkgMCAwIDEgMi4xMDUuOThBNSA1IDAgMCAxIDI0LjAwMSAxMWE1IDUgMCAwIDEgNSA1djRjMCAuMTktLjAxOS4zOC0uMDU0LjU2NUMyOC40MDkgMjUuODk3IDIzLjkwNyAzMCAxOC41IDMwWiIvPgogICAgPHBhdGggZmlsbD0iIzAwNTVGRiIgZD0iTTI1IDE5LjVWMTZhMSAxIDAgMSAwLTIgMCAxIDEgMCAxIDEtMiAwdi0yYTEgMSAwIDEgMC0yIDAgMSAxIDAgMSAxLTIgMCAzIDMgMCAwIDEgNS44OTUtLjc5QTMgMyAwIDAgMSAyNyAxNnY0YTEgMSAwIDAgMS0uMDMzLjI1NkE4LjUgOC41IDAgMCAxIDE4LjUgMjhIMTNjLTQuMjg0IDAtNy4zNy00LjM1Ny05LjQ3LTEyLjc1OC0uNjk4LTIuNzkyIDIuMzIxLTQuODA1IDQuMTc3LTIuOTVMOSAxMy41ODdWNmEzIDMgMCAxIDEgNiAwdjdhMSAxIDAgMSAxLTIgMFY2YTEgMSAwIDEgMC0yIDB2MTBhMSAxIDAgMCAxLTEuNzA3LjcwN2wtMy0zYy0uMzQ0LS4zNDQtMS4wNTMuMTI5LS44MjMgMS4wNUM3LjM3IDIyLjM1OCA5Ljk1IDI2IDEzIDI2aDUuNWE2LjUgNi41IDAgMCAwIDYuNS02LjVaTTE2IDEwYTMgMyAwIDAgMSAzIDN2MWExIDEgMCAxIDEtMiAwdi0xYTEgMSAwIDEgMC0yIDAgMSAxIDAgMSAxLTIgMCAzIDMgMCAwIDEgMy0zWm0tMSA3YTEgMSAwIDAgMSAxIDF2M2ExIDEgMCAxIDEtMiAwdi0zYTEgMSAwIDAgMSAxLTFabTQgMGExIDEgMCAwIDEgMSAxdjNhMSAxIDAgMSAxLTIgMHYtM2ExIDEgMCAwIDEgMS0xWiIvPgogIDwvZz4KPC9zdmc+Cg==") 12 8, pointer';
7180
7623
  var CURSOR_MOVE = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDMyIDMyIj4KICA8ZGVmcz4KICAgIDxmaWx0ZXIKICAgICAgaWQ9Ind2ay1jdXJzb3Itc2hhZG93IgogICAgICBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgIHg9Ii00IgogICAgICB5PSItNCIKICAgICAgd2lkdGg9IjQwIgogICAgICBoZWlnaHQ9IjQwIgogICAgICBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiCiAgICA+CiAgICAgIDxmZURyb3BTaGFkb3cgZHg9IjAiIGR5PSIxLjI1IiBzdGREZXZpYXRpb249IjEiIGZsb29kLWNvbG9yPSIjMDAwMDAwIiBmbG9vZC1vcGFjaXR5PSIwLjM4IiAvPgogICAgPC9maWx0ZXI+CiAgPC9kZWZzPgogIDxnIGZpbHRlcj0idXJsKCN3dmstY3Vyc29yLXNoYWRvdykiPgogICAgPHBhdGggZmlsbD0id2hpdGUiIGQ9Im0xNiAyLjAzIDE0LjE0MiAxNC4xNEwxNiAzMC4zMTQgMS44NTggMTYuMTcgMTYgMi4wM1oiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDU1RkYiIGQ9Ik0xMCAxOC45NmEuNS41IDAgMCAxLS44MTMuMzlsLTMuNy0yLjk2YS41LjUgMCAwIDEgMC0uNzhsMy43LTIuOTZhLjUuNSAwIDAgMSAuODEzLjM5VjE1bDQuOTk5LS4wMDF2LTVoLTEuOTZhLjUuNSAwIDAgMS0uMzktLjgxMmwyLjk2LTMuN2EuNS41IDAgMCAxIC43ODEgMGwyLjk2IDMuN2EuNS41IDAgMCAxLS4zOS44MTJIMTdsLS4wMDEgNWg1di0xLjk2YS41LjUgMCAwIDEgLjgxMy0uMzlsMy43IDIuOTZhLjUuNSAwIDAgMSAwIC43OGwtMy43IDIuOTZhLjUuNSAwIDAgMS0uODEyLS4zOVYxN2gtNS4wMDF2NWgxLjk2YS41LjUgMCAwIDEgLjM5LjgxM2wtMi45NTkgMy43YS41LjUgMCAwIDEtLjc4IDBsLTIuOTYtMy43YS41LjUgMCAwIDEgLjM5LS44MTNIMTVsLS4wMDEtNWgtNXYxLjk2WiIvPgogIDwvZz4KPC9zdmc+Cg==") 16 16, move';
7624
+ var CURSOR_DEFAULT_ARROW = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMyIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDMyIDMzIj4KICA8ZyBmaWx0ZXI9InVybCgjYSkiPgogICAgPHBhdGggZmlsbD0iIzAwNTVGRiIgZD0iTTEwIDI0VjcuMjE2YzAtLjg2MSAxLjAxNi0xLjMyIDEuNjYyLS43NWwxMy4wNDYgMTEuNTExYy43MjUuNjQuMjEgMS44MzQtLjc1MiAxLjc0NmwtNy40LS42NzJhMSAxIDAgMCAwLS44OS4zOTVMMTEuOCAyNC42Yy0uNTc3Ljc2OS0xLjguMzYxLTEuOC0uNloiLz4KICAgIDxwYXRoIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTkgNy4yMTZjMC0xLjcyMiAyLjAzMi0yLjY0IDMuMzIzLTEuNUwyNS4zNyAxNy4yMjdjMS40NSAxLjI4LjQyMiAzLjY2Ny0xLjUwNCAzLjQ5MmwtNy40LS42NzJMMTIuNiAyNS4yQzExLjQ0NiAyNi43MzcgOSAyNS45MjIgOSAyNFY3LjIxNloiLz4KICA8L2c+CiAgPGRlZnM+CiAgICA8ZmlsdGVyIGlkPSJhIiB3aWR0aD0iMjcuMDU1IiBoZWlnaHQ9IjMwLjc5NiIgeD0iNCIgeT0iMi4yMSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiPgogICAgICA8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgogICAgICA8ZmVDb2xvck1hdHJpeCBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0iaGFyZEFscGhhIiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDEyNyAwIi8+CiAgICAgIDxmZU9mZnNldCBkeT0iMiIvPgogICAgICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIyIi8+CiAgICAgIDxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMC4xNiAwIi8+CiAgICAgIDxmZUJsZW5kIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9ImVmZmVjdDFfZHJvcFNoYWRvd180ODA5XzY2OSIvPgogICAgICA8ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJlZmZlY3QxX2Ryb3BTaGFkb3dfNDgwOV82NjkiIHJlc3VsdD0ic2hhcGUiLz4KICAgIDwvZmlsdGVyPgogIDwvZGVmcz4KPC9zdmc+Cg==") 10 7, default';
7625
+ var CURSOR_GRABBING = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNSIgaGVpZ2h0PSIzNiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDM1IDM2Ij4KICA8ZyBmaWx0ZXI9InVybCgjYSkiPgogICAgPHBhdGggZmlsbD0id2hpdGUiIGQ9Ik0zMC4xNzYgMTguNjY3QzMwLjE3NiAyNC45MjYgMjUuMTAyIDMwIDE4Ljg0MyAzMGgtMy4xODhhMTAgMTAgMCAwIDEtOS4wOC01LjgxTDQuNjUgMjAuMDE4Yy0xLjY4NS0zLjY1LjA1Ni03LjgyNCAzLjU0LTkuMzQ1YTUgNSAwIDAgMSA4LjA5LTMuNTkxIDQuOTc3IDQuOTc3IDAgMCAxIDQgMSA0Ljk3NyA0Ljk3NyAwIDAgMSAzLjk3Ny45ODFBNC45IDQuOSAwIDAgMSAyNS4wNDQgOWE1LjEzNCA1LjEzNCAwIDAgMSA1LjEzMyA1LjEzNHY0LjUzM1oiLz4KICA8L2c+CiAgPHBhdGggZmlsbD0iIzAwNTVGRiIgZD0iTTEzLjE3NyA4YzEuMDYyIDAgMS45OTQuNTU0IDIuNTI3IDEuMzg4YTIuOTk2IDIuOTk2IDAgMCAxIDQgMSAyLjk5NyAyLjk5NyAwIDAgMSAzLjk3NC45NTdBMi44NSAyLjg1IDAgMCAxIDI1LjA0MyAxMWEzLjEzNCAzLjEzNCAwIDAgMSAzLjEzNCAzLjEzNHY0LjUzM0E5LjMzNCA5LjMzNCAwIDAgMSAxOC44NDQgMjhoLTMuMTg5YTggOCAwIDAgMS03LjI2NC00LjY0OEw2LjQ2NiAxOS4xOGMtMS4zODItMi45OTMuNDYtNi40OCAzLjcxLTcuMDI3VjExYTMgMyAwIDAgMSAzLTNabTAgMmExIDEgMCAwIDAtMSAxdjVhMSAxIDAgMCAxLTIgMHYtMS44YTMgMyAwIDAgMC0xLjg5NiA0LjE0bDEuOTI3IDQuMTc1QTYgNiAwIDAgMCAxNS42NTUgMjZoMy4xODlhNy4zMzQgNy4zMzQgMCAwIDAgNy4zMzMtNy4zMzN2LTQuNTMzYzAtLjYyNi0uNTA4LTEuMTM0LTEuMTM0LTEuMTM0YS44NjcuODY3IDAgMCAwLS44NjYuODY2VjE0YTEgMSAwIDAgMS0yIDB2LTFhMSAxIDAgMCAwLTEuOTk1LS4xMDJsLS4wMS4yMDRBMSAxIDAgMCAxIDE4LjE3NyAxM3YtMWExIDEgMCAwIDAtMS45OTUtLjEwMmwtLjAxLjIwNEExIDEgMCAwIDEgMTQuMTc3IDEydi0xYTEgMSAwIDAgMC0xLTFabTMgN2ExIDEgMCAwIDEgMSAxdjNhMSAxIDAgMCAxLTIgMHYtM2ExIDEgMCAwIDEgMS0xWm00IDBhMSAxIDAgMCAxIDEgMXYzYTEgMSAwIDAgMS0yIDB2LTNhMSAxIDAgMCAxIDEtMVoiLz4KICA8ZGVmcz4KICAgIDxmaWx0ZXIgaWQ9ImEiIHdpZHRoPSIzNC4xNzYiIGhlaWdodD0iMzIiIHg9IjAiIHk9IjQiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KICAgICAgPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KICAgICAgPGZlQ29sb3JNYXRyaXggaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9ImhhcmRBbHBoYSIgdmFsdWVzPSIwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAxMjcgMCIvPgogICAgICA8ZmVPZmZzZXQgZHk9IjIiLz4KICAgICAgPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMiIvPgogICAgICA8ZmVDb2xvck1hdHJpeCB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAuMTYgMCIvPgogICAgICA8ZmVCbGVuZCBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJlZmZlY3QxX2Ryb3BTaGFkb3dfNDgxMF83MzAiLz4KICAgICAgPGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iZWZmZWN0MV9kcm9wU2hhZG93XzQ4MTBfNzMwIiByZXN1bHQ9InNoYXBlIi8+CiAgICA8L2ZpbHRlcj4KICA8L2RlZnM+Cjwvc3ZnPgo=") 17 18, grabbing';
7626
+ var CURSOR_TEXT = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzNCIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDMyIDM0Ij4KICA8ZyBmaWx0ZXI9InVybCgjYSkiPgogICAgPHBhdGggZmlsbD0id2hpdGUiIGZpbGwtb3BhY2l0eT0iLjgiIGQ9Ik0xNC41ODYgNGMuNDg4IDAgLjk2Ni4wOSAxLjQxNC4yNi40NDgtLjE3LjkyNi0uMjYgMS40MTQtLjI2SDIwYTMgMyAwIDEgMSAwIDZoLTF2MTJoMWEzIDMgMCAxIDEgMCA2aC0yLjU4NmMtLjQ4OCAwLS45NjYtLjA5LTEuNDE0LS4yNi0uNDQ4LjE3LS45MjYuMjYtMS40MTQuMjZIMTJhMyAzIDAgMSAxIDAtNmgxVjEwaC0xYTMgMyAwIDEgMSAwLTZoMi41ODZaIi8+CiAgPC9nPgogIDxwYXRoIHN0cm9rZT0iIzAwNTVGRiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0xMiA3aDIuMTcyYTIgMiAwIDAgMSAxLjQxNC41ODZMMTYgOG0wIDB2MTZtMC0xNiAuNDE0LS40MTRBMiAyIDAgMCAxIDE3LjgyOCA3SDIwbS00IDE3IC40MTQuNDE0YTIgMiAwIDAgMCAxLjQxNC41ODZIMjBtLTQtMS0uNDE0LjQxNGEyIDIgMCAwIDEtMS40MTQuNTg2SDEyIi8+CiAgPGRlZnM+CiAgICA8ZmlsdGVyIGlkPSJhIiB3aWR0aD0iMjIiIGhlaWdodD0iMzIiIHg9IjUiIHk9IjIiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KICAgICAgPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KICAgICAgPGZlQ29sb3JNYXRyaXggaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9ImhhcmRBbHBoYSIgdmFsdWVzPSIwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAxMjcgMCIvPgogICAgICA8ZmVPZmZzZXQgZHk9IjIiLz4KICAgICAgPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMiIvPgogICAgICA8ZmVDb2xvck1hdHJpeCB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAuMTYgMCIvPgogICAgICA8ZmVCbGVuZCBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJlZmZlY3QxX2Ryb3BTaGFkb3dfNDgxMF82ODUiLz4KICAgICAgPGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iZWZmZWN0MV9kcm9wU2hhZG93XzQ4MTBfNjg1IiByZXN1bHQ9InNoYXBlIi8+CiAgICA8L2ZpbHRlcj4KICA8L2RlZnM+Cjwvc3ZnPgo=") 16 17, text';
7181
7627
  var CURSOR_FALLBACK_CSS = `
7182
7628
  :root {
7183
7629
  --wvk-cursor-default: ${CURSOR_DEFAULT};
7630
+ --wvk-cursor-default-arrow: ${CURSOR_DEFAULT_ARROW};
7184
7631
  --wvk-cursor-pointer: ${CURSOR_POINTER};
7185
7632
  --wvk-cursor-move: ${CURSOR_MOVE};
7633
+ --wvk-cursor-grabbing: ${CURSOR_GRABBING};
7634
+ --wvk-cursor-text: ${CURSOR_TEXT};
7635
+ }
7636
+
7637
+ html.${CURSOR_STYLE_CLASS_ARROW} {
7638
+ --wvk-cursor-default: var(--wvk-cursor-default-arrow);
7186
7639
  }
7187
7640
 
7188
7641
  html {
@@ -7198,8 +7651,13 @@ input[type="url"],
7198
7651
  input[type="password"],
7199
7652
  input[type="number"],
7200
7653
  textarea,
7201
- [contenteditable="true"] {
7202
- cursor: text;
7654
+ [contenteditable="true"],
7655
+ [data-wvk-input="shell"] {
7656
+ cursor: var(--wvk-cursor-text);
7657
+ }
7658
+
7659
+ [data-wvk-input="shell"]:has(:disabled) {
7660
+ cursor: not-allowed;
7203
7661
  }
7204
7662
 
7205
7663
  a[href],
@@ -7221,16 +7679,29 @@ select:not(:disabled),
7221
7679
  cursor: var(--wvk-cursor-default);
7222
7680
  }
7223
7681
 
7224
- .cursor-move,
7225
- .cursor-grab,
7682
+ .cursor-text {
7683
+ cursor: var(--wvk-cursor-text);
7684
+ }
7685
+
7226
7686
  .cursor-grabbing {
7687
+ cursor: var(--wvk-cursor-grabbing);
7688
+ }
7689
+
7690
+ .cursor-move,
7691
+ .cursor-grab {
7227
7692
  cursor: var(--wvk-cursor-move);
7228
7693
  }
7229
7694
  `;
7230
- var ThemeContext = React25.createContext(null);
7695
+ var ThemeContext = React27.createContext(null);
7231
7696
  function applyThemeClass(theme) {
7232
7697
  document.documentElement.classList.toggle("dark", theme === "dark");
7233
7698
  }
7699
+ function applyCursorStyleClass(style) {
7700
+ document.documentElement.classList.toggle(
7701
+ CURSOR_STYLE_CLASS_ARROW,
7702
+ style === "arrow"
7703
+ );
7704
+ }
7234
7705
  function ensureCursorStyleFallback() {
7235
7706
  const root = document.documentElement;
7236
7707
  const hasPackageCursorCss = getComputedStyle(root).getPropertyValue("--wvk-cursor-default").trim();
@@ -7242,12 +7713,17 @@ function ensureCursorStyleFallback() {
7242
7713
  style.textContent = CURSOR_FALLBACK_CSS;
7243
7714
  document.head.appendChild(style);
7244
7715
  }
7245
- function ThemeProvider({ children }) {
7246
- const [theme, setThemeState] = React25.useState("light");
7247
- React25.useInsertionEffect(() => {
7716
+ function ThemeProvider({
7717
+ children,
7718
+ cursorStyle: cursorStyleProp = "default",
7719
+ whimsyCursor = true
7720
+ }) {
7721
+ const [theme, setThemeState] = React27.useState("light");
7722
+ const [cursorStyle, setCursorStyleState] = React27.useState(cursorStyleProp);
7723
+ React27.useInsertionEffect(() => {
7248
7724
  ensureCursorStyleFallback();
7249
7725
  }, []);
7250
- React25.useEffect(() => {
7726
+ React27.useEffect(() => {
7251
7727
  const stored = localStorage.getItem(STORAGE_KEY);
7252
7728
  if (stored === "dark" || stored === "light") {
7253
7729
  setThemeState(stored);
@@ -7255,37 +7731,63 @@ function ThemeProvider({ children }) {
7255
7731
  setThemeState("dark");
7256
7732
  }
7257
7733
  }, []);
7258
- React25.useEffect(() => {
7734
+ React27.useEffect(() => {
7735
+ const stored = localStorage.getItem(CURSOR_STYLE_STORAGE_KEY);
7736
+ if (stored === "default" || stored === "arrow") {
7737
+ setCursorStyleState(stored);
7738
+ } else if (document.documentElement.classList.contains(CURSOR_STYLE_CLASS_ARROW)) {
7739
+ setCursorStyleState("arrow");
7740
+ }
7741
+ }, []);
7742
+ React27.useEffect(() => {
7259
7743
  applyThemeClass(theme);
7260
7744
  }, [theme]);
7261
- const setTheme = React25.useCallback((t) => {
7745
+ React27.useEffect(() => {
7746
+ applyCursorStyleClass(cursorStyle);
7747
+ }, [cursorStyle]);
7748
+ const setTheme = React27.useCallback((t) => {
7262
7749
  setThemeState(t);
7263
7750
  localStorage.setItem(STORAGE_KEY, t);
7264
7751
  }, []);
7265
- const value = React25.useMemo(
7266
- () => ({ theme, setTheme }),
7267
- [theme, setTheme]
7752
+ const setCursorStyle = React27.useCallback((c) => {
7753
+ setCursorStyleState(c);
7754
+ localStorage.setItem(CURSOR_STYLE_STORAGE_KEY, c);
7755
+ }, []);
7756
+ const value = React27.useMemo(
7757
+ () => ({ theme, setTheme, cursorStyle, setCursorStyle }),
7758
+ [theme, setTheme, cursorStyle, setCursorStyle]
7268
7759
  );
7269
- return /* @__PURE__ */ jsx209(ThemeContext.Provider, { value, children });
7760
+ const cursorProps = cursorStyle === "arrow" || whimsyCursor === false ? null : whimsyCursor === true ? {} : whimsyCursor;
7761
+ return /* @__PURE__ */ jsxs37(ThemeContext.Provider, { value, children: [
7762
+ cursorProps ? /* @__PURE__ */ jsx211(WhimsyCursor, { ...cursorProps }) : null,
7763
+ children
7764
+ ] });
7270
7765
  }
7271
7766
  function useTheme() {
7272
- const ctx = React25.useContext(ThemeContext);
7767
+ const ctx = React27.useContext(ThemeContext);
7273
7768
  if (!ctx) {
7274
7769
  throw new Error("useTheme must be used inside <ThemeProvider>");
7275
7770
  }
7276
7771
  return ctx;
7277
7772
  }
7773
+ function useCursorStyle() {
7774
+ const ctx = React27.useContext(ThemeContext);
7775
+ if (!ctx) {
7776
+ throw new Error("useCursorStyle must be used inside <ThemeProvider>");
7777
+ }
7778
+ return { cursorStyle: ctx.cursorStyle, setCursorStyle: ctx.setCursorStyle };
7779
+ }
7278
7780
 
7279
7781
  // src/components/theme-switcher.tsx
7280
- import * as React26 from "react";
7281
- import { jsx as jsx210, jsxs as jsxs35 } from "react/jsx-runtime";
7782
+ import * as React28 from "react";
7783
+ import { jsx as jsx212, jsxs as jsxs38 } from "react/jsx-runtime";
7282
7784
  function ThemeSwitcher() {
7283
- const ctx = React26.useContext(ThemeContext);
7785
+ const ctx = React28.useContext(ThemeContext);
7284
7786
  if (!ctx) {
7285
7787
  return null;
7286
7788
  }
7287
7789
  const { theme, setTheme } = ctx;
7288
- return /* @__PURE__ */ jsxs35(
7790
+ return /* @__PURE__ */ jsxs38(
7289
7791
  SegmentedControl,
7290
7792
  {
7291
7793
  size: "sm",
@@ -7294,19 +7796,19 @@ function ThemeSwitcher() {
7294
7796
  onValueChange: (v) => setTheme(v),
7295
7797
  "aria-label": "Color theme",
7296
7798
  children: [
7297
- /* @__PURE__ */ jsx210(
7799
+ /* @__PURE__ */ jsx212(
7298
7800
  SegmentedControlItem,
7299
7801
  {
7300
7802
  value: "light",
7301
- icon: /* @__PURE__ */ jsx210(Sun_default, { "aria-hidden": true, className: "size-full" }),
7803
+ icon: /* @__PURE__ */ jsx212(Sun_default, { "aria-hidden": true, className: "size-full" }),
7302
7804
  "aria-label": "Light theme"
7303
7805
  }
7304
7806
  ),
7305
- /* @__PURE__ */ jsx210(
7807
+ /* @__PURE__ */ jsx212(
7306
7808
  SegmentedControlItem,
7307
7809
  {
7308
7810
  value: "dark",
7309
- icon: /* @__PURE__ */ jsx210(Moon_default, { "aria-hidden": true, className: "size-full" }),
7811
+ icon: /* @__PURE__ */ jsx212(Moon_default, { "aria-hidden": true, className: "size-full" }),
7310
7812
  "aria-label": "Dark theme"
7311
7813
  }
7312
7814
  )
@@ -7315,48 +7817,29 @@ function ThemeSwitcher() {
7315
7817
  );
7316
7818
  }
7317
7819
 
7318
- // src/lib/button-decorative-icons.tsx
7319
- import { jsx as jsx211 } from "react/jsx-runtime";
7320
- var BUTTON_DECORATIVE_ICON_NAMES = [
7321
- "none",
7322
- "plus",
7323
- "chevronRight",
7324
- "home",
7325
- "search",
7326
- "user",
7327
- "settings"
7328
- ];
7329
- var iconClass = (size) => cn(size === "lg" ? wvkIconLgClass : wvkIconMdClass, "shrink-0");
7330
- function ButtonDecorativeIconGlyph({
7331
- name,
7332
- size,
7333
- className
7334
- }) {
7335
- const c = cn(iconClass(size), className);
7336
- switch (name) {
7337
- case "plus":
7338
- return /* @__PURE__ */ jsx211(Plus_default, { className: c, "aria-hidden": true });
7339
- case "chevronRight":
7340
- return /* @__PURE__ */ jsx211(ChevronRight_default, { className: c, "aria-hidden": true });
7341
- case "home":
7342
- return /* @__PURE__ */ jsx211(Home_default, { className: c, "aria-hidden": true });
7343
- case "search":
7344
- return /* @__PURE__ */ jsx211(MagnifyingGlass_default, { className: c, "aria-hidden": true });
7345
- case "user":
7346
- return /* @__PURE__ */ jsx211(User_default, { className: c, "aria-hidden": true });
7347
- case "settings":
7348
- return /* @__PURE__ */ jsx211(Settings_default, { className: c, "aria-hidden": true });
7349
- default:
7350
- return null;
7820
+ // src/lib/motion-presets.ts
7821
+ import { AnimatePresence, motion as motion7 } from "framer-motion";
7822
+ var staggerContainer = {
7823
+ hidden: { opacity: 0 },
7824
+ show: {
7825
+ opacity: 1,
7826
+ transition: { staggerChildren: 0.05 }
7351
7827
  }
7352
- }
7828
+ };
7829
+ var fadeInUp = {
7830
+ hidden: { opacity: 0, y: 8 },
7831
+ show: {
7832
+ opacity: 1,
7833
+ y: 0,
7834
+ transition: { duration: 0.2, ease: "easeOut" }
7835
+ }
7836
+ };
7353
7837
  export {
7354
7838
  Alert,
7355
- BUTTON_DECORATIVE_ICON_NAMES,
7839
+ AnimatePresence,
7356
7840
  BottomTabBar,
7357
7841
  BottomTabBarItem,
7358
7842
  Button,
7359
- ButtonDecorativeIconGlyph,
7360
7843
  Checkbox,
7361
7844
  FieldGroup,
7362
7845
  FieldLabel,
@@ -7365,20 +7848,37 @@ export {
7365
7848
  Link2 as Link,
7366
7849
  ListItem,
7367
7850
  LoadingSpinner,
7851
+ Menu2 as Menu,
7852
+ MenuGroup,
7853
+ MenuGroupLabel,
7854
+ MenuItem,
7855
+ MenuPopup,
7856
+ MenuSeparator,
7857
+ MenuTrigger,
7858
+ Meter,
7368
7859
  Pagination,
7369
7860
  ProgressBar,
7370
7861
  Radio,
7862
+ RadioGroup,
7863
+ RadioGroupItem,
7371
7864
  SegmentedControl,
7372
7865
  SegmentedControlItem,
7373
7866
  SegmentedControlTrigger,
7374
7867
  Select,
7868
+ SelectGroup,
7869
+ SelectGroupLabel,
7870
+ SelectItem,
7871
+ SelectSeparator,
7375
7872
  Slider,
7376
7873
  SplitButton,
7377
7874
  StarRating,
7378
7875
  TAG_LEADING_ICON_NAMES,
7379
7876
  Tab,
7877
+ TabIndicator,
7380
7878
  TabList,
7879
+ TabPanel,
7381
7880
  Tabs,
7881
+ TabsContent,
7382
7882
  TabsList,
7383
7883
  TabsTrigger,
7384
7884
  Tag2 as Tag,
@@ -7393,20 +7893,25 @@ export {
7393
7893
  ThemeSwitcher,
7394
7894
  ToggleSwitch,
7395
7895
  Tooltip,
7896
+ TooltipPopup,
7897
+ TooltipProvider,
7396
7898
  VideoControls,
7397
7899
  VideoPlaceholder,
7900
+ WhimsyCursor,
7398
7901
  buttonVariants,
7399
7902
  checkboxFrameVariants,
7400
7903
  cn,
7904
+ fadeInUp,
7401
7905
  hasRenderableFieldLabelText,
7402
7906
  linkVariants,
7403
7907
  listItemVariants,
7908
+ motion7 as motion,
7404
7909
  placeholderVariants,
7405
7910
  radioFrameVariants,
7406
- selectFieldVariants,
7407
7911
  selectShellVariants,
7408
7912
  selectShellVariants as selectVariants,
7409
7913
  splitButtonVariants,
7914
+ staggerContainer,
7410
7915
  tabListVariants,
7411
7916
  tagVariants,
7412
7917
  textAreaFieldVariants,
@@ -7414,6 +7919,7 @@ export {
7414
7919
  textInputShellVariants,
7415
7920
  toggleSwitchVariants,
7416
7921
  toggleThumbVariants,
7922
+ useCursorStyle,
7417
7923
  useTheme,
7418
7924
  wvkIconBoxLgClass,
7419
7925
  wvkIconLgClass,