@olundot/ui 0.15.0 → 0.16.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
@@ -1376,7 +1376,7 @@ var selectVariants = cva5(
1376
1376
  variants: {
1377
1377
  size: {
1378
1378
  sm: "h-[30px] px-pad-compact-x text-body-sm",
1379
- md: "h-[32px] px-pad-default-x text-sm",
1379
+ md: "h-[32px] px-pad-default-x text-body-sm",
1380
1380
  lg: "h-[36px] px-pad-default-x text-sm"
1381
1381
  },
1382
1382
  fullWidth: {
@@ -3757,426 +3757,192 @@ function InfoModal({
3757
3757
  }
3758
3758
 
3759
3759
  // src/components/ui/filter-toolbar.tsx
3760
- import * as React22 from "react";
3761
- import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
3762
- var FilterToolbar = React22.forwardRef(
3763
- ({
3764
- className,
3765
- search,
3766
- filters,
3767
- resultSummary,
3768
- clearAction,
3769
- actions,
3770
- ...props
3771
- }, ref) => {
3772
- const hasMeta = Boolean(resultSummary || clearAction || actions);
3773
- const hasLeft = Boolean(search || filters);
3774
- return /* @__PURE__ */ jsx24(
3775
- "div",
3776
- {
3777
- ref,
3778
- "data-slot": "filter-toolbar",
3779
- className: cn(
3780
- "flex w-full flex-col gap-[var(--space-2)] text-foreground",
3781
- className
3782
- ),
3783
- ...props,
3784
- children: /* @__PURE__ */ jsxs23(
3785
- "div",
3786
- {
3787
- "data-slot": "filter-toolbar-row",
3788
- className: cn(
3789
- "flex min-h-[34px] w-full flex-wrap items-center gap-x-[var(--space-2)] gap-y-[var(--space-2)]",
3790
- hasLeft ? "justify-start" : "justify-end"
3791
- ),
3792
- children: [
3793
- search ? /* @__PURE__ */ jsx24(
3794
- "div",
3795
- {
3796
- "data-slot": "filter-toolbar-search",
3797
- className: "min-w-0 flex-[1_1_280px] max-w-full",
3798
- children: search
3799
- }
3800
- ) : null,
3801
- filters ? /* @__PURE__ */ jsx24(
3802
- "div",
3803
- {
3804
- "data-slot": "filter-toolbar-filters",
3805
- className: "flex min-w-0 flex-[2_1_auto] flex-wrap items-center gap-[var(--space-2)]",
3806
- children: filters
3807
- }
3808
- ) : null,
3809
- hasMeta ? /* @__PURE__ */ jsxs23(
3810
- "div",
3811
- {
3812
- "data-slot": "filter-toolbar-meta",
3813
- className: "ml-auto flex min-w-0 flex-wrap items-center justify-end gap-[var(--space-2)]",
3814
- children: [
3815
- resultSummary ? /* @__PURE__ */ jsx24(
3816
- "div",
3817
- {
3818
- "data-slot": "filter-toolbar-summary",
3819
- className: "shrink-0 whitespace-nowrap text-xs leading-snug text-text-tertiary",
3820
- children: resultSummary
3821
- }
3822
- ) : null,
3823
- clearAction ? /* @__PURE__ */ jsx24(
3824
- "div",
3825
- {
3826
- "data-slot": "filter-toolbar-clear",
3827
- className: "shrink-0",
3828
- children: clearAction
3829
- }
3830
- ) : null,
3831
- actions ? /* @__PURE__ */ jsx24(
3832
- "div",
3833
- {
3834
- "data-slot": "filter-toolbar-actions",
3835
- className: "flex shrink-0 flex-wrap items-center gap-[var(--space-2)]",
3836
- children: actions
3837
- }
3838
- ) : null
3839
- ]
3840
- }
3841
- ) : null
3842
- ]
3843
- }
3844
- )
3845
- }
3846
- );
3847
- }
3848
- );
3849
- FilterToolbar.displayName = "FilterToolbar";
3850
-
3851
- // src/components/ui/data-table.tsx
3852
- import * as React24 from "react";
3853
- import { ChevronDown as ChevronDown3, ChevronUp as ChevronUp2, ChevronsUpDown } from "lucide-react";
3854
- import { cva as cva10 } from "class-variance-authority";
3760
+ import * as React25 from "react";
3761
+ import { SlidersHorizontal } from "lucide-react";
3855
3762
 
3856
- // src/components/ui/checkbox.tsx
3857
- import * as React23 from "react";
3763
+ // src/components/ui/chip.tsx
3764
+ import * as React22 from "react";
3858
3765
  import { cva as cva9 } from "class-variance-authority";
3859
- import { Check as Check3, Minus } from "lucide-react";
3860
- import { Checkbox as CheckboxPrimitive } from "radix-ui";
3861
- import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3862
- var checkboxFieldVariants = cva9(
3863
- "flex flex-col gap-[var(--space-1)]",
3864
- {
3865
- variants: {
3866
- fullWidth: {
3867
- true: "w-full",
3868
- false: "w-fit"
3869
- }
3870
- },
3871
- defaultVariants: {
3872
- fullWidth: false
3873
- }
3874
- }
3875
- );
3876
- var checkboxVariants = checkboxFieldVariants;
3877
- var checkboxRootVariants = cva9(
3878
- [
3879
- "group shrink-0 cursor-pointer rounded-[var(--radius-xs)]",
3880
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]",
3881
- "disabled:cursor-not-allowed"
3882
- ].join(" ")
3883
- );
3884
- var checkboxBoxVariants = cva9(
3766
+ import { X as X2 } from "lucide-react";
3767
+ import { Slot as Slot2 } from "radix-ui";
3768
+ import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
3769
+ var chipVariants = cva9(
3885
3770
  [
3886
- "flex shrink-0 items-center justify-center rounded-[var(--radius-xs)] border",
3887
- "border-[var(--border-strong)] bg-[var(--bg-surface)] text-transparent",
3888
- "transition-colors motion-reduce:transition-none",
3889
- "group-hover:bg-[var(--action-hover)]",
3890
- "group-disabled:border-[var(--border-subtle)] group-disabled:bg-[var(--action-disabled-bg)]",
3891
- "group-data-[state=checked]:border-[var(--primary)] group-data-[state=checked]:bg-[var(--primary)] group-data-[state=checked]:text-[var(--primary-fg)]",
3892
- "group-data-[state=indeterminate]:border-[var(--primary)] group-data-[state=indeterminate]:bg-[var(--primary)] group-data-[state=indeterminate]:text-[var(--primary-fg)]",
3893
- "group-disabled:group-data-[state=checked]:border-[var(--border-subtle)] group-disabled:group-data-[state=checked]:bg-[var(--action-disabled-bg)] group-disabled:group-data-[state=checked]:text-text-disabled",
3894
- "group-disabled:group-data-[state=indeterminate]:border-[var(--border-subtle)] group-disabled:group-data-[state=indeterminate]:bg-[var(--action-disabled-bg)] group-disabled:group-data-[state=indeterminate]:text-text-disabled"
3771
+ "inline-flex w-fit shrink-0 items-center justify-center whitespace-nowrap",
3772
+ "rounded-[var(--radius-full)] border leading-none",
3773
+ "font-medium transition-colors motion-reduce:transition-none",
3774
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
3775
+ "disabled:pointer-events-none disabled:opacity-50"
3895
3776
  ].join(" "),
3896
3777
  {
3897
3778
  variants: {
3779
+ variant: {
3780
+ // interactive 3종 — 클릭 가능 (toggle / select / remove). cursor:pointer으로 affordance 명시.
3781
+ // (Tailwind v4 preflight + site reset은 button cursor 보장 안 함 → variant level에서 강제.)
3782
+ filter: "cursor-pointer",
3783
+ choice: "cursor-pointer",
3784
+ removable: "cursor-pointer",
3785
+ // status-filter — 정적 표시 chip (display only, 클릭 affordance 없음).
3786
+ "status-filter": "cursor-default"
3787
+ },
3788
+ tone: {
3789
+ neutral: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-text-secondary hover:bg-[var(--action-hover)]",
3790
+ accent: "border-[var(--border-accent)] bg-transparent text-[var(--accent)] hover:bg-[var(--accent-bg-strong)]",
3791
+ success: "border-transparent bg-[var(--success-bg)] text-[var(--success)] hover:bg-[var(--action-hover)]",
3792
+ warning: "border-transparent bg-[var(--warning-bg)] text-[var(--warning)] hover:bg-[var(--action-hover)]",
3793
+ danger: "border-transparent bg-[var(--error-bg)] text-[var(--error)] hover:bg-[var(--action-hover)]",
3794
+ muted: "border-[var(--border-subtle)] bg-transparent text-text-tertiary hover:bg-[var(--action-hover)]"
3795
+ },
3898
3796
  size: {
3899
- sm: "size-[calc(var(--space-4)+var(--space-1))]",
3900
- md: "size-[calc(var(--space-4)+var(--space-1))]"
3901
- }
3902
- },
3903
- defaultVariants: {
3904
- size: "md"
3905
- }
3906
- }
3907
- );
3908
- var checkboxGroupItemVariants = cva9(
3909
- [
3910
- "group w-full cursor-pointer text-left transition-colors motion-reduce:transition-none",
3911
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]",
3912
- "disabled:cursor-not-allowed disabled:text-text-disabled"
3913
- ].join(" "),
3914
- {
3915
- variants: {
3916
- appearance: {
3917
- plain: "inline-flex items-start gap-[var(--space-3)] rounded-[var(--radius-sm)] px-pad-compact-x py-pad-compact-y",
3918
- card: [
3919
- "flex min-h-[calc(var(--space-12)+var(--space-2))] items-start gap-[var(--space-3)]",
3920
- "rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-surface)]",
3921
- "hover:bg-[var(--action-hover)]",
3922
- "data-[state=checked]:border-[var(--border-strong)] data-[state=checked]:bg-[var(--action-selected)]",
3923
- "disabled:border-[var(--border-subtle)] disabled:bg-[var(--action-disabled-bg)]",
3924
- "disabled:data-[state=checked]:border-[var(--border-subtle)] disabled:data-[state=checked]:bg-[var(--action-disabled-bg)]"
3925
- ].join(" ")
3797
+ sm: "h-[30px] gap-[var(--space-1)] px-[var(--space-2)] text-xs",
3798
+ md: "h-[32px] gap-[var(--space-2)] px-[var(--space-3)] text-body-sm",
3799
+ lg: "h-[36px] gap-[var(--space-2)] px-[var(--space-4)] text-body-sm"
3926
3800
  },
3927
- density: {
3928
- comfortable: "",
3929
- compact: ""
3801
+ pressed: {
3802
+ true: "",
3803
+ false: ""
3930
3804
  }
3931
3805
  },
3932
3806
  compoundVariants: [
3933
3807
  {
3934
- appearance: "card",
3935
- density: "comfortable",
3936
- className: "px-pad-default-x py-pad-roomy-y"
3808
+ pressed: true,
3809
+ tone: "neutral",
3810
+ className: "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground"
3937
3811
  },
3938
3812
  {
3939
- appearance: "card",
3940
- density: "compact",
3941
- className: "px-pad-compact-x py-pad-default-y"
3813
+ // R10 — wash 패턴 정합 (--accent-bg-strong deep olive wash / --accent olive/lime text).
3814
+ pressed: true,
3815
+ tone: "accent",
3816
+ className: "border-[var(--border-accent)] bg-[var(--accent-bg-strong)] text-[var(--accent)]"
3817
+ },
3818
+ {
3819
+ pressed: true,
3820
+ tone: "muted",
3821
+ className: "border-[var(--border-strong)] bg-[var(--bg-raised)] text-text-secondary"
3942
3822
  }
3943
3823
  ],
3944
3824
  defaultVariants: {
3945
- appearance: "plain",
3946
- density: "comfortable"
3825
+ variant: "filter",
3826
+ tone: "neutral",
3827
+ size: "md",
3828
+ pressed: false
3947
3829
  }
3948
3830
  }
3949
3831
  );
3950
- var checkboxGroupBoxVariants = cva9(
3951
- "mt-[2px]",
3832
+ var chipCountVariants = cva9(
3833
+ [
3834
+ "inline-flex min-w-[var(--space-4)] items-center justify-center",
3835
+ "rounded-[var(--radius-full)] px-[var(--space-1)]",
3836
+ "font-[family-name:var(--font-display)]"
3837
+ ].join(" "),
3952
3838
  {
3953
3839
  variants: {
3954
- appearance: {
3955
- plain: "",
3956
- card: "mt-[var(--space-1)]"
3840
+ tone: {
3841
+ neutral: "bg-[var(--bg-raised)] text-text-tertiary",
3842
+ accent: "bg-[var(--accent-pop)] text-[var(--accent-on-fill)]",
3843
+ success: "bg-[var(--success)] text-[var(--success-contrast)]",
3844
+ warning: "bg-[var(--warning)] text-[var(--warning-contrast)]",
3845
+ danger: "bg-[var(--error)] text-[var(--error-contrast)]",
3846
+ muted: "bg-[var(--bg-raised)] text-text-tertiary"
3847
+ },
3848
+ size: {
3849
+ sm: "h-[var(--space-4)] text-xs",
3850
+ md: "h-[var(--space-4)] text-xs",
3851
+ lg: "h-[calc(var(--space-4)+var(--space-1))] text-xs"
3957
3852
  }
3958
3853
  },
3959
3854
  defaultVariants: {
3960
- appearance: "plain"
3855
+ tone: "neutral",
3856
+ size: "md"
3961
3857
  }
3962
3858
  }
3963
3859
  );
3964
- var CheckboxGroupContext = React23.createContext(null);
3965
- function getLabel(children, label) {
3966
- return children ?? label;
3967
- }
3968
- var Checkbox = React23.forwardRef(
3860
+ var Chip = React22.forwardRef(
3969
3861
  ({
3970
3862
  className,
3863
+ variant = "filter",
3864
+ tone = "neutral",
3971
3865
  size = "md",
3972
- fullWidth = false,
3866
+ pressed = false,
3867
+ count,
3868
+ removeLabel = "Remove",
3869
+ asChild = false,
3973
3870
  children,
3974
- label,
3975
- description,
3976
- required,
3977
- error,
3978
- id,
3979
- value,
3980
- name,
3981
- checked,
3982
- disabled,
3983
- onCheckedChange,
3984
3871
  ...props
3985
3872
  }, ref) => {
3986
- const group = React23.useContext(CheckboxGroupContext);
3987
- const generatedId = React23.useId();
3988
- const checkboxId = id ?? generatedId;
3989
- const labelContent = getLabel(children, label);
3990
- const isGrouped = Boolean(group && value != null);
3991
- const valueString = value == null ? void 0 : String(value);
3992
- const resolvedChecked = isGrouped && valueString ? group?.selectedValues.has(valueString) : checked;
3993
- const resolvedDisabled = disabled || group?.disabled;
3994
- const resolvedName = name ?? group?.name;
3995
- const labelId = `${checkboxId}-label`;
3996
- const descriptionId = description && !error ? `${checkboxId}-description` : void 0;
3997
- const errorId = error ? `${checkboxId}-error` : void 0;
3998
- const describedBy = errorId ?? descriptionId;
3999
- const handleCheckedChange = (nextChecked) => {
4000
- onCheckedChange?.(nextChecked);
4001
- if (isGrouped && valueString) {
4002
- group?.toggleValue(valueString, nextChecked === true);
4003
- }
4004
- };
4005
- if (isGrouped) {
4006
- const appearance = group?.appearance ?? "plain";
4007
- const density = group?.density ?? "comfortable";
4008
- return /* @__PURE__ */ jsxs24(
4009
- CheckboxPrimitive.Root,
4010
- {
4011
- ref,
4012
- id: checkboxId,
4013
- "data-slot": "checkbox",
4014
- "aria-labelledby": labelId,
4015
- "aria-describedby": describedBy,
4016
- "aria-required": required || void 0,
4017
- "aria-invalid": error ? true : void 0,
4018
- name: resolvedName,
4019
- value: valueString,
4020
- checked: resolvedChecked,
4021
- disabled: resolvedDisabled,
4022
- className: cn(
4023
- checkboxGroupItemVariants({ appearance, density }),
4024
- className
4025
- ),
4026
- onCheckedChange: handleCheckedChange,
4027
- ...props,
3873
+ const removable = variant === "removable";
3874
+ if (removable) {
3875
+ const {
3876
+ onClick,
3877
+ disabled,
3878
+ type: _type,
3879
+ autoFocus: _af,
3880
+ form: _form,
3881
+ name: _name,
3882
+ value: _value,
3883
+ ...spanProps
3884
+ } = props;
3885
+ return /* @__PURE__ */ jsxs23(
3886
+ "span",
3887
+ {
3888
+ "data-slot": "chip",
3889
+ "data-variant": variant,
3890
+ "data-tone": tone,
3891
+ className: cn(chipVariants({ variant, tone, size, pressed, className })),
3892
+ ...spanProps,
4028
3893
  children: [
4029
- /* @__PURE__ */ jsx25(
3894
+ /* @__PURE__ */ jsx24("span", { children }),
3895
+ count !== void 0 ? /* @__PURE__ */ jsx24(
4030
3896
  "span",
4031
3897
  {
4032
3898
  "aria-hidden": "true",
4033
- "data-slot": "checkbox-box",
4034
- className: cn(
4035
- checkboxBoxVariants({ size }),
4036
- checkboxGroupBoxVariants({ appearance })
4037
- ),
4038
- children: /* @__PURE__ */ jsx25(
4039
- CheckboxPrimitive.Indicator,
4040
- {
4041
- "data-slot": "checkbox-indicator",
4042
- className: "flex items-center justify-center",
4043
- children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx25(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx25(Check3, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
4044
- }
4045
- )
3899
+ "data-slot": "chip-count",
3900
+ "data-count-tone": tone,
3901
+ className: chipCountVariants({ tone, size }),
3902
+ children: count
4046
3903
  }
4047
- ),
4048
- /* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 flex-col gap-[var(--space-1)]", children: [
4049
- /* @__PURE__ */ jsxs24(
4050
- "span",
4051
- {
4052
- id: labelId,
4053
- "data-slot": "checkbox-label",
4054
- className: "text-sm font-medium leading-snug text-foreground group-disabled:text-text-disabled",
4055
- children: [
4056
- labelContent,
4057
- required ? /* @__PURE__ */ jsx25(
4058
- "span",
4059
- {
4060
- "aria-hidden": "true",
4061
- "data-slot": "checkbox-required-marker",
4062
- className: "ml-[var(--space-1)] font-bold text-[var(--semantic-error,var(--error))]",
4063
- children: "*"
4064
- }
4065
- ) : null
4066
- ]
4067
- }
4068
- ),
4069
- error ? /* @__PURE__ */ jsx25(
4070
- "span",
4071
- {
4072
- id: errorId,
4073
- role: "alert",
4074
- "data-slot": "checkbox-error",
4075
- className: "text-xs font-medium leading-normal text-[var(--error)]",
4076
- children: error
4077
- }
4078
- ) : description ? /* @__PURE__ */ jsx25(
4079
- "span",
4080
- {
4081
- id: descriptionId,
4082
- "data-slot": "checkbox-description",
4083
- className: "text-xs font-normal leading-normal text-text-tertiary group-disabled:text-text-disabled",
4084
- children: description
4085
- }
4086
- ) : null
4087
- ] })
3904
+ ) : null,
3905
+ /* @__PURE__ */ jsx24(
3906
+ "button",
3907
+ {
3908
+ ref,
3909
+ type: "button",
3910
+ "data-slot": "chip-remove",
3911
+ "aria-label": removeLabel,
3912
+ disabled,
3913
+ onClick,
3914
+ className: "inline-flex size-[var(--space-4)] items-center justify-center rounded-[var(--radius-full)] text-text-tertiary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
3915
+ children: /* @__PURE__ */ jsx24(X2, { "aria-hidden": "true", size: 14, strokeWidth: 2.25 })
3916
+ }
3917
+ )
4088
3918
  ]
4089
3919
  }
4090
3920
  );
4091
3921
  }
4092
- const labelClassName = cn(
4093
- "cursor-pointer select-none text-left font-medium text-foreground",
4094
- size === "sm" ? "text-xs" : "text-sm",
4095
- resolvedDisabled && "cursor-not-allowed text-text-disabled"
4096
- );
4097
- return /* @__PURE__ */ jsxs24(
4098
- "div",
3922
+ const Comp = asChild ? Slot2.Root : "button";
3923
+ return /* @__PURE__ */ jsxs23(
3924
+ Comp,
4099
3925
  {
4100
- "data-slot": "checkbox-field",
4101
- "data-disabled": resolvedDisabled ? "" : void 0,
4102
- className: checkboxFieldVariants({ fullWidth }),
3926
+ ref,
3927
+ "data-slot": "chip",
3928
+ "data-variant": variant,
3929
+ "data-tone": tone,
3930
+ "aria-pressed": pressed,
3931
+ className: cn(
3932
+ chipVariants({ variant, tone, size, pressed, className })
3933
+ ),
3934
+ type: asChild ? void 0 : props.type ?? "button",
3935
+ ...props,
4103
3936
  children: [
4104
- /* @__PURE__ */ jsxs24("div", { className: "inline-flex items-center gap-[var(--space-3)]", children: [
4105
- /* @__PURE__ */ jsx25(
4106
- CheckboxPrimitive.Root,
4107
- {
4108
- ref,
4109
- id: checkboxId,
4110
- "data-slot": "checkbox",
4111
- "aria-describedby": describedBy,
4112
- "aria-required": required || void 0,
4113
- "aria-invalid": error ? true : void 0,
4114
- name: resolvedName,
4115
- value: valueString,
4116
- checked: resolvedChecked,
4117
- disabled: resolvedDisabled,
4118
- className: cn(checkboxRootVariants(), className),
4119
- onCheckedChange: handleCheckedChange,
4120
- ...props,
4121
- children: /* @__PURE__ */ jsx25(
4122
- "span",
4123
- {
4124
- "aria-hidden": "true",
4125
- "data-slot": "checkbox-box",
4126
- className: checkboxBoxVariants({ size }),
4127
- children: /* @__PURE__ */ jsx25(
4128
- CheckboxPrimitive.Indicator,
4129
- {
4130
- "data-slot": "checkbox-indicator",
4131
- className: "flex items-center justify-center",
4132
- children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx25(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx25(Check3, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
4133
- }
4134
- )
4135
- }
4136
- )
4137
- }
4138
- ),
4139
- labelContent ? /* @__PURE__ */ jsxs24(
4140
- "label",
4141
- {
4142
- id: labelId,
4143
- htmlFor: checkboxId,
4144
- "data-slot": "checkbox-label",
4145
- className: labelClassName,
4146
- children: [
4147
- labelContent,
4148
- required ? /* @__PURE__ */ jsx25(
4149
- "span",
4150
- {
4151
- "aria-hidden": "true",
4152
- "data-slot": "checkbox-required-marker",
4153
- className: "ml-[var(--space-1)] font-bold text-[var(--semantic-error,var(--error))]",
4154
- children: "*"
4155
- }
4156
- ) : null
4157
- ]
4158
- }
4159
- ) : null
4160
- ] }),
4161
- error ? /* @__PURE__ */ jsx25(
4162
- "p",
4163
- {
4164
- id: errorId,
4165
- role: "alert",
4166
- "data-slot": "checkbox-error",
4167
- className: "ml-[32px] text-xs font-medium leading-normal text-[var(--error)]",
4168
- children: error
4169
- }
4170
- ) : description ? /* @__PURE__ */ jsx25(
4171
- "p",
3937
+ children,
3938
+ count !== void 0 ? /* @__PURE__ */ jsx24(
3939
+ "span",
4172
3940
  {
4173
- id: descriptionId,
4174
- "data-slot": "checkbox-description",
4175
- className: cn(
4176
- "ml-[32px] text-xs font-normal leading-normal text-text-tertiary",
4177
- resolvedDisabled && "text-text-disabled"
4178
- ),
4179
- children: description
3941
+ "aria-hidden": "true",
3942
+ "data-slot": "chip-count",
3943
+ "data-count-tone": tone,
3944
+ className: chipCountVariants({ tone, size }),
3945
+ children: count
4180
3946
  }
4181
3947
  ) : null
4182
3948
  ]
@@ -4184,54 +3950,1230 @@ var Checkbox = React23.forwardRef(
4184
3950
  );
4185
3951
  }
4186
3952
  );
4187
- Checkbox.displayName = "Checkbox";
3953
+ Chip.displayName = "Chip";
4188
3954
 
4189
- // src/components/ui/data-table.tsx
4190
- import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
4191
- var dataTableVariants = cva10(
3955
+ // src/components/ui/icon-button.tsx
3956
+ import * as React23 from "react";
3957
+ import { cva as cva10 } from "class-variance-authority";
3958
+ import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3959
+ var iconButtonVariants = cva10(
4192
3960
  [
4193
- "relative overflow-hidden rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
4194
- "text-foreground"
3961
+ "olun-icon-button relative inline-flex cursor-pointer shrink-0 items-center justify-center before:absolute before:content-['']",
3962
+ "rounded-[var(--radius-sm)] border font-medium",
3963
+ "transition-colors motion-reduce:transition-none",
3964
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
3965
+ "disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled",
3966
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0"
4195
3967
  ].join(" "),
4196
3968
  {
4197
3969
  variants: {
4198
- density: {
4199
- standard: "",
4200
- compact: ""
3970
+ variant: {
3971
+ ghost: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
3972
+ outline: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-text-secondary hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)] hover:text-foreground",
3973
+ subtle: "border-transparent bg-[var(--bg-raised)] text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
3974
+ danger: "border-transparent bg-[var(--error-bg)] text-[var(--error)] hover:bg-[var(--action-hover)]"
4201
3975
  },
4202
- surface: surfaceClassNames
3976
+ size: {
3977
+ sm: "size-[28px] before:-inset-[8px]",
3978
+ md: "size-[32px] before:-inset-[6px]",
3979
+ lg: "size-[40px] before:-inset-[2px]"
3980
+ },
3981
+ pressed: {
3982
+ true: "",
3983
+ false: ""
3984
+ }
4203
3985
  },
3986
+ compoundVariants: [
3987
+ {
3988
+ pressed: true,
3989
+ variant: ["ghost", "outline", "subtle"],
3990
+ className: "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground"
3991
+ },
3992
+ {
3993
+ pressed: true,
3994
+ variant: "danger",
3995
+ className: "border-[var(--error)] bg-[var(--error-bg)] text-[var(--error)]"
3996
+ }
3997
+ ],
4204
3998
  defaultVariants: {
4205
- density: "standard",
4206
- surface: "surface"
3999
+ variant: "ghost",
4000
+ size: "md",
4001
+ pressed: false
4207
4002
  }
4208
4003
  }
4209
4004
  );
4210
- var dataTableRowVariants = cva10(
4005
+ var iconButtonBadgeVariants = cva10(
4211
4006
  [
4212
- "grid min-h-[48px] items-center border-t border-[var(--border-subtle)]",
4213
- "text-body-sm leading-compact text-foreground",
4214
- "transition-colors motion-reduce:transition-none"
4007
+ "pointer-events-none absolute right-0 top-0 inline-flex",
4008
+ "olun-icon-button__badge",
4009
+ "min-h-[var(--space-3)] min-w-[var(--space-3)] translate-x-1/3 -translate-y-1/3",
4010
+ "items-center justify-center gap-[2px] rounded-[var(--radius-full)] px-[3px]",
4011
+ "font-[family-name:var(--font-display)] text-[10px] font-semibold leading-none",
4012
+ "[&:has(svg)]:size-[var(--space-3)] [&:has(svg)]:px-0 [&_svg]:size-[10px]"
4215
4013
  ].join(" "),
4216
4014
  {
4217
4015
  variants: {
4218
- interactive: {
4219
- true: "cursor-pointer hover:bg-[var(--action-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--focus-ring)]",
4220
- false: ""
4221
- },
4222
- selected: {
4223
- true: "bg-[var(--action-selected)]",
4224
- false: ""
4016
+ tone: {
4017
+ info: "bg-[var(--accent-pop)] text-[var(--accent-on-fill)]",
4018
+ error: "bg-[var(--error)] text-[var(--error-contrast)]"
4225
4019
  }
4226
4020
  },
4227
4021
  defaultVariants: {
4228
- interactive: false,
4229
- selected: false
4022
+ tone: "info"
4230
4023
  }
4231
4024
  }
4232
4025
  );
4233
- var alignmentClass = {
4234
- left: "justify-start text-left",
4026
+ var iconSize2 = {
4027
+ sm: 14,
4028
+ md: 16,
4029
+ lg: 18
4030
+ };
4031
+ var iconStrokeWidth = {
4032
+ sm: 2.25,
4033
+ md: 2.25,
4034
+ lg: 1.75
4035
+ };
4036
+ var IconButton = React23.forwardRef(
4037
+ ({
4038
+ className,
4039
+ variant = "ghost",
4040
+ size = "md",
4041
+ pressed = void 0,
4042
+ icon: Icon,
4043
+ badge,
4044
+ badgeTone = "info",
4045
+ type,
4046
+ title,
4047
+ "aria-label": ariaLabel,
4048
+ "aria-labelledby": ariaLabelledBy,
4049
+ ...props
4050
+ }, ref) => {
4051
+ const resolvedSize = size ?? "md";
4052
+ const isToggle = pressed !== void 0;
4053
+ const isPressed = pressed === true;
4054
+ const hoverTitle = title ?? (typeof ariaLabel === "string" ? ariaLabel : void 0);
4055
+ return /* @__PURE__ */ jsxs24(
4056
+ "button",
4057
+ {
4058
+ ref,
4059
+ ...props,
4060
+ "data-slot": "icon-button",
4061
+ "data-variant": variant,
4062
+ "data-size": resolvedSize,
4063
+ "data-pressed": isToggle ? String(isPressed) : void 0,
4064
+ "aria-label": ariaLabel,
4065
+ "aria-labelledby": ariaLabelledBy,
4066
+ "aria-pressed": isToggle ? isPressed : void 0,
4067
+ title: hoverTitle,
4068
+ className: cn(
4069
+ iconButtonVariants({ variant, size, pressed: isPressed, className })
4070
+ ),
4071
+ type: type ?? "button",
4072
+ children: [
4073
+ /* @__PURE__ */ jsx25(
4074
+ Icon,
4075
+ {
4076
+ "aria-hidden": "true",
4077
+ "data-slot": "icon-button-icon",
4078
+ size: iconSize2[resolvedSize],
4079
+ strokeWidth: iconStrokeWidth[resolvedSize]
4080
+ }
4081
+ ),
4082
+ badge !== void 0 ? /* @__PURE__ */ jsx25(
4083
+ "span",
4084
+ {
4085
+ "aria-hidden": "true",
4086
+ "data-slot": "icon-button-badge",
4087
+ "data-badge-tone": badgeTone,
4088
+ className: iconButtonBadgeVariants({ tone: badgeTone }),
4089
+ children: badge
4090
+ }
4091
+ ) : null
4092
+ ]
4093
+ }
4094
+ );
4095
+ }
4096
+ );
4097
+ IconButton.displayName = "IconButton";
4098
+
4099
+ // src/components/ui/popover.tsx
4100
+ import * as React24 from "react";
4101
+ import { Popover as PopoverPrimitive } from "radix-ui";
4102
+ import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
4103
+ function Popover({ modal = false, ...props }) {
4104
+ return /* @__PURE__ */ jsx26(PopoverPrimitive.Root, { modal, ...props });
4105
+ }
4106
+ var popoverArrowClassName = "fill-[var(--bg-surface)] stroke-[var(--border)] [&>polygon]:[vector-effect:non-scaling-stroke]";
4107
+ var PopoverTrigger = PopoverPrimitive.Trigger;
4108
+ var PopoverAnchor = PopoverPrimitive.Anchor;
4109
+ var PopoverClose = PopoverPrimitive.Close;
4110
+ var PopoverContent = React24.forwardRef(({ className, align = "center", sideOffset = 8, collisionPadding = 8, showArrow = false, children, ...props }, ref) => /* @__PURE__ */ jsx26(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsxs25(
4111
+ PopoverPrimitive.Content,
4112
+ {
4113
+ ref,
4114
+ align,
4115
+ sideOffset,
4116
+ collisionPadding,
4117
+ "data-slot": "popover-content",
4118
+ className: cn(
4119
+ "z-[var(--z-popover)] w-[260px] outline-none",
4120
+ "rounded-[var(--radius-md)] border border-[var(--border)]",
4121
+ "bg-[var(--bg-surface)] p-[var(--space-4)] text-foreground",
4122
+ "shadow-[var(--shadow-4)]",
4123
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
4124
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
4125
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
4126
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
4127
+ "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4128
+ "motion-reduce:animate-none",
4129
+ className
4130
+ ),
4131
+ ...props,
4132
+ children: [
4133
+ children,
4134
+ showArrow ? /* @__PURE__ */ jsx26(
4135
+ PopoverPrimitive.Arrow,
4136
+ {
4137
+ "data-slot": "popover-arrow",
4138
+ className: popoverArrowClassName,
4139
+ width: 11,
4140
+ height: 5
4141
+ }
4142
+ ) : null
4143
+ ]
4144
+ }
4145
+ ) }));
4146
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
4147
+ var PopoverArrow = React24.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
4148
+ PopoverPrimitive.Arrow,
4149
+ {
4150
+ ref,
4151
+ "data-slot": "popover-arrow",
4152
+ className: cn(popoverArrowClassName, className),
4153
+ width: 11,
4154
+ height: 5,
4155
+ ...props
4156
+ }
4157
+ ));
4158
+ PopoverArrow.displayName = PopoverPrimitive.Arrow.displayName;
4159
+
4160
+ // src/components/ui/sheet-drawer.tsx
4161
+ import { Maximize2Icon, Minimize2Icon, XIcon as XIcon3 } from "lucide-react";
4162
+
4163
+ // src/components/ui/sheet.tsx
4164
+ import { XIcon as XIcon2 } from "lucide-react";
4165
+ import { Dialog as SheetPrimitive } from "radix-ui";
4166
+ import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
4167
+ var defaultSheetMotionConfig = {
4168
+ type: "slide",
4169
+ duration: 300,
4170
+ easing: "decel"
4171
+ };
4172
+ var sheetMotionEasingValue = {
4173
+ standard: "var(--ease-standard)",
4174
+ // decel/sharp have no canonical --ease-* token; these compat beziers are frozen
4175
+ // specifically to back this public `easing` prop (see tokens/compat.css).
4176
+ decel: "var(--easing-decel)",
4177
+ accel: "var(--ease-in)",
4178
+ sharp: "var(--easing-sharp)",
4179
+ bounce: "var(--ease-out)"
4180
+ };
4181
+ function resolveSheetMotionConfig(motion) {
4182
+ if (motion === false) return false;
4183
+ return {
4184
+ ...defaultSheetMotionConfig,
4185
+ ...motion
4186
+ };
4187
+ }
4188
+ function formatSheetMotionDuration(duration) {
4189
+ return typeof duration === "number" ? `${duration}ms` : duration;
4190
+ }
4191
+ function getSheetMotionStyle(motionConfig, style) {
4192
+ if (!motionConfig) return style;
4193
+ return {
4194
+ ...style,
4195
+ "--sheet-motion-duration": formatSheetMotionDuration(motionConfig.duration),
4196
+ "--sheet-motion-easing": sheetMotionEasingValue[motionConfig.easing]
4197
+ };
4198
+ }
4199
+ function Sheet({ ...props }) {
4200
+ return /* @__PURE__ */ jsx27(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
4201
+ }
4202
+ function SheetTrigger({
4203
+ ...props
4204
+ }) {
4205
+ return /* @__PURE__ */ jsx27(SheetPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
4206
+ }
4207
+ function SheetClose({
4208
+ ...props
4209
+ }) {
4210
+ return /* @__PURE__ */ jsx27(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
4211
+ }
4212
+ function SheetPortal({
4213
+ ...props
4214
+ }) {
4215
+ return /* @__PURE__ */ jsx27(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
4216
+ }
4217
+ function SheetOverlay({
4218
+ className,
4219
+ motion,
4220
+ style,
4221
+ ...props
4222
+ }) {
4223
+ const motionConfig = resolveSheetMotionConfig(motion);
4224
+ return /* @__PURE__ */ jsx27(
4225
+ SheetPrimitive.Overlay,
4226
+ {
4227
+ "data-slot": "sheet-overlay",
4228
+ className: cn(
4229
+ "fixed inset-0 z-[var(--z-overlay)] bg-[var(--scrim)]",
4230
+ motionConfig && cn(
4231
+ "transition-opacity motion-reduce:transition-none",
4232
+ "duration-[var(--sheet-motion-duration)]",
4233
+ "data-[state=closed]:opacity-0 data-[state=open]:opacity-100",
4234
+ "data-[state=open]:animate-[olun-sheet-fade-in_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
4235
+ "data-[state=closed]:animate-[olun-sheet-fade-out_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
4236
+ "motion-reduce:animate-none"
4237
+ ),
4238
+ className
4239
+ ),
4240
+ style: getSheetMotionStyle(motionConfig, style),
4241
+ ...props
4242
+ }
4243
+ );
4244
+ }
4245
+ function SheetContent({
4246
+ className,
4247
+ children,
4248
+ side = "right",
4249
+ mobileSide,
4250
+ motion,
4251
+ showCloseButton = false,
4252
+ style,
4253
+ ...props
4254
+ }) {
4255
+ const motionConfig = resolveSheetMotionConfig(motion);
4256
+ const hasSlideMotion = motionConfig && motionConfig.type === "slide";
4257
+ return /* @__PURE__ */ jsxs26(SheetPortal, { children: [
4258
+ /* @__PURE__ */ jsx27(SheetOverlay, { motion: motionConfig }),
4259
+ /* @__PURE__ */ jsxs26(
4260
+ SheetPrimitive.Content,
4261
+ {
4262
+ "data-slot": "sheet-content",
4263
+ className: cn(
4264
+ "fixed z-[var(--z-modal)] flex flex-col gap-4 border-[var(--border)] bg-[var(--bg-surface)] shadow-[var(--shadow-4)]",
4265
+ motionConfig && cn(
4266
+ "motion-reduce:animate-none",
4267
+ motionConfig.type === "fade" && "data-[state=open]:animate-[olun-sheet-fade-in_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-fade-out_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4268
+ ),
4269
+ side === "right" && cn(
4270
+ "inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
4271
+ hasSlideMotion && "data-[state=open]:animate-[olun-sheet-in-from-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-out-to-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4272
+ ),
4273
+ side === "left" && cn(
4274
+ "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
4275
+ hasSlideMotion && "data-[state=open]:animate-[olun-sheet-in-from-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-out-to-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4276
+ ),
4277
+ side === "top" && cn(
4278
+ "inset-x-0 top-0 h-auto border-b",
4279
+ hasSlideMotion && "data-[state=open]:animate-[olun-sheet-in-from-top_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-out-to-top_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4280
+ ),
4281
+ side === "bottom" && cn(
4282
+ "inset-x-0 bottom-0 h-auto border-t",
4283
+ hasSlideMotion && "data-[state=open]:animate-[olun-sheet-in-from-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-out-to-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4284
+ ),
4285
+ mobileSide === "right" && cn(
4286
+ "max-[899px]:inset-y-0 max-[899px]:right-0 max-[899px]:left-auto max-[899px]:h-full max-[899px]:w-3/4 max-[899px]:border-l max-[899px]:border-t-0 max-[899px]:rounded-none",
4287
+ hasSlideMotion && "max-[899px]:data-[state=open]:animate-[olun-sheet-in-from-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] max-[899px]:data-[state=closed]:animate-[olun-sheet-out-to-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4288
+ ),
4289
+ mobileSide === "left" && cn(
4290
+ "max-[899px]:inset-y-0 max-[899px]:left-0 max-[899px]:right-auto max-[899px]:h-full max-[899px]:w-3/4 max-[899px]:border-r max-[899px]:border-t-0 max-[899px]:rounded-none",
4291
+ hasSlideMotion && "max-[899px]:data-[state=open]:animate-[olun-sheet-in-from-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] max-[899px]:data-[state=closed]:animate-[olun-sheet-out-to-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4292
+ ),
4293
+ mobileSide === "top" && cn(
4294
+ // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap (see mobileSide bottom).
4295
+ "max-[899px]:inset-x-0 max-[899px]:top-0 max-[899px]:bottom-auto max-[899px]:h-auto max-[899px]:w-full max-[899px]:max-w-none! max-[899px]:border-b max-[899px]:border-l-0 max-[899px]:rounded-none",
4296
+ hasSlideMotion && "max-[899px]:data-[state=open]:animate-[olun-sheet-in-from-top_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] max-[899px]:data-[state=closed]:animate-[olun-sheet-out-to-top_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4297
+ ),
4298
+ mobileSide === "bottom" && cn(
4299
+ // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap so the bottom sheet
4300
+ // spans the full viewport width across the whole < 900px band (not capped to 24rem).
4301
+ "max-[899px]:inset-x-0 max-[899px]:bottom-0 max-[899px]:top-auto max-[899px]:h-auto max-[899px]:w-full max-[899px]:max-w-none! max-[899px]:border-t max-[899px]:border-l-0 max-[899px]:rounded-none",
4302
+ hasSlideMotion && "max-[899px]:data-[state=open]:animate-[olun-sheet-in-from-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] max-[899px]:data-[state=closed]:animate-[olun-sheet-out-to-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4303
+ ),
4304
+ className
4305
+ ),
4306
+ style: getSheetMotionStyle(motionConfig, style),
4307
+ ...props,
4308
+ children: [
4309
+ children,
4310
+ showCloseButton && /* @__PURE__ */ jsxs26(SheetPrimitive.Close, { className: "absolute top-4 right-4 cursor-pointer rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
4311
+ /* @__PURE__ */ jsx27(XIcon2, { className: "size-[16px]" }),
4312
+ /* @__PURE__ */ jsx27("span", { className: "sr-only", children: "Close" })
4313
+ ] })
4314
+ ]
4315
+ }
4316
+ )
4317
+ ] });
4318
+ }
4319
+ function SheetBody({ className, ...props }) {
4320
+ return /* @__PURE__ */ jsx27(
4321
+ "div",
4322
+ {
4323
+ "data-slot": "sheet-body",
4324
+ className: cn("flex-1 overflow-y-auto p-4", className),
4325
+ ...props
4326
+ }
4327
+ );
4328
+ }
4329
+ function SheetHeader({ className, ...props }) {
4330
+ return /* @__PURE__ */ jsx27(
4331
+ "div",
4332
+ {
4333
+ "data-slot": "sheet-header",
4334
+ className: cn("flex flex-col gap-1.5 p-4", className),
4335
+ ...props
4336
+ }
4337
+ );
4338
+ }
4339
+ function SheetFooter({ className, ...props }) {
4340
+ return /* @__PURE__ */ jsx27(
4341
+ "div",
4342
+ {
4343
+ "data-slot": "sheet-footer",
4344
+ className: cn("mt-auto flex flex-col gap-2 p-4", className),
4345
+ ...props
4346
+ }
4347
+ );
4348
+ }
4349
+ function SheetTitle({
4350
+ className,
4351
+ ...props
4352
+ }) {
4353
+ return /* @__PURE__ */ jsx27(
4354
+ SheetPrimitive.Title,
4355
+ {
4356
+ "data-slot": "sheet-title",
4357
+ className: cn("font-semibold text-foreground", className),
4358
+ ...props
4359
+ }
4360
+ );
4361
+ }
4362
+ function SheetDescription({
4363
+ className,
4364
+ ...props
4365
+ }) {
4366
+ return /* @__PURE__ */ jsx27(
4367
+ SheetPrimitive.Description,
4368
+ {
4369
+ "data-slot": "sheet-description",
4370
+ className: cn("text-sm text-muted-foreground", className),
4371
+ ...props
4372
+ }
4373
+ );
4374
+ }
4375
+
4376
+ // src/components/ui/sheet-drawer.tsx
4377
+ import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
4378
+ var sheetDrawerContentClassName = cn(
4379
+ "gap-0 p-0",
4380
+ "bg-[var(--bg-surface)] text-foreground",
4381
+ "border-[var(--border)] shadow-[var(--shadow-4)]",
4382
+ "min-[900px]:w-[480px] min-[900px]:max-w-[480px]",
4383
+ "max-[899px]:h-[min(85dvh,720px)] max-[899px]:max-h-[85dvh] max-[899px]:w-full max-[899px]:max-w-none",
4384
+ "max-[899px]:rounded-t-[var(--radius-lg)]"
4385
+ );
4386
+ var sheetDrawerWideContentClassName = "min-[900px]:w-[720px] min-[900px]:max-w-[720px]";
4387
+ var sheetDrawerFullContentClassName = cn(
4388
+ "min-[900px]:w-[calc(100vw_-_var(--space-8))] min-[900px]:max-w-[calc(100vw_-_var(--space-8))]",
4389
+ "max-[899px]:h-[100dvh] max-[899px]:max-h-[100dvh] max-[899px]:rounded-none"
4390
+ );
4391
+ var sheetDrawerHeaderClassName = cn(
4392
+ "flex items-start justify-between gap-[var(--space-4)]",
4393
+ "border-b border-[var(--border)] px-[var(--space-6)] py-[var(--space-6)]"
4394
+ );
4395
+ var sheetDrawerHeaderTextClassName = "flex min-w-0 flex-1 flex-col gap-[var(--space-2)]";
4396
+ var sheetDrawerCaptionClassName = "flex flex-wrap items-center gap-[var(--space-2)]";
4397
+ var sheetDrawerTitleClassName = "text-[18px] font-bold leading-snug text-foreground";
4398
+ var sheetDrawerDescriptionClassName = "break-keep text-[14px] leading-normal text-text-secondary";
4399
+ var sheetDrawerCloseButtonClassName = cn(
4400
+ "flex size-[32px] shrink-0 cursor-pointer items-center justify-center",
4401
+ "rounded-[var(--radius-sm)] text-text-tertiary transition-colors",
4402
+ "hover:bg-[var(--action-hover)] hover:text-foreground",
4403
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2"
4404
+ );
4405
+ var sheetDrawerHeaderActionsClassName = cn(
4406
+ "flex shrink-0 items-center gap-[var(--space-1)]"
4407
+ );
4408
+ var sheetDrawerExpandButtonClassName = cn(
4409
+ "inline-flex cursor-pointer items-center justify-center gap-[var(--space-1)]",
4410
+ "rounded-[var(--radius-sm)] text-text-tertiary transition-colors",
4411
+ "hover:bg-[var(--action-hover)] hover:text-foreground",
4412
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2",
4413
+ "h-[32px] px-[var(--space-2)]"
4414
+ );
4415
+ var sheetDrawerBodyClassName = cn(
4416
+ "min-h-0 flex-1 overflow-y-auto",
4417
+ "px-[var(--space-6)] py-[var(--space-6)]"
4418
+ );
4419
+ var sheetDrawerFooterClassName = cn(
4420
+ "border-t border-[var(--border)] px-[var(--space-6)] py-[var(--space-4)]",
4421
+ "flex justify-end gap-[var(--space-2)]"
4422
+ );
4423
+ function SheetDrawer({
4424
+ open,
4425
+ onOpenChange,
4426
+ caption,
4427
+ title,
4428
+ description,
4429
+ children,
4430
+ expandHref,
4431
+ onExpand,
4432
+ expandLabel = "\uD06C\uAC8C \uBCF4\uAE30",
4433
+ expanded = false,
4434
+ onExpandedChange,
4435
+ collapseLabel = "\uC791\uAC8C \uBCF4\uAE30",
4436
+ footer,
4437
+ width = "default",
4438
+ motion,
4439
+ closeLabel = "\uB2EB\uAE30"
4440
+ }) {
4441
+ const hasExpandedToggle = typeof onExpandedChange === "function";
4442
+ const showExpandAction = Boolean(hasExpandedToggle || expandHref || onExpand);
4443
+ const resolvedWidth = expanded ? "full" : width;
4444
+ const resolvedExpandLabel = hasExpandedToggle && expanded ? collapseLabel : expandLabel;
4445
+ const ExpandActionIcon = hasExpandedToggle && expanded ? Minimize2Icon : Maximize2Icon;
4446
+ return /* @__PURE__ */ jsx28(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs27(
4447
+ SheetContent,
4448
+ {
4449
+ "data-slot": "sheet-drawer-content",
4450
+ side: "right",
4451
+ mobileSide: "bottom",
4452
+ motion,
4453
+ showCloseButton: false,
4454
+ className: cn(
4455
+ sheetDrawerContentClassName,
4456
+ resolvedWidth === "wide" && sheetDrawerWideContentClassName,
4457
+ resolvedWidth === "full" && sheetDrawerFullContentClassName
4458
+ ),
4459
+ children: [
4460
+ /* @__PURE__ */ jsxs27("div", { "data-slot": "sheet-drawer-header", className: sheetDrawerHeaderClassName, children: [
4461
+ /* @__PURE__ */ jsxs27("div", { className: sheetDrawerHeaderTextClassName, children: [
4462
+ caption ? /* @__PURE__ */ jsx28("div", { "data-slot": "sheet-drawer-caption", className: sheetDrawerCaptionClassName, children: caption }) : null,
4463
+ /* @__PURE__ */ jsx28(SheetTitle, { "data-slot": "sheet-drawer-title", className: sheetDrawerTitleClassName, children: title }),
4464
+ description ? /* @__PURE__ */ jsx28(
4465
+ SheetDescription,
4466
+ {
4467
+ "data-slot": "sheet-drawer-description",
4468
+ className: sheetDrawerDescriptionClassName,
4469
+ children: description
4470
+ }
4471
+ ) : null
4472
+ ] }),
4473
+ /* @__PURE__ */ jsxs27("div", { "data-slot": "sheet-drawer-header-actions", className: sheetDrawerHeaderActionsClassName, children: [
4474
+ showExpandAction ? hasExpandedToggle ? /* @__PURE__ */ jsxs27(
4475
+ "button",
4476
+ {
4477
+ type: "button",
4478
+ "aria-label": resolvedExpandLabel,
4479
+ "aria-pressed": expanded,
4480
+ "data-slot": "sheet-drawer-expand",
4481
+ "data-expanded": expanded ? "true" : "false",
4482
+ className: sheetDrawerExpandButtonClassName,
4483
+ onClick: () => onExpandedChange(!expanded),
4484
+ children: [
4485
+ /* @__PURE__ */ jsx28(ExpandActionIcon, { className: "size-[16px]" }),
4486
+ /* @__PURE__ */ jsx28("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: resolvedExpandLabel })
4487
+ ]
4488
+ }
4489
+ ) : expandHref ? /* @__PURE__ */ jsxs27(
4490
+ "a",
4491
+ {
4492
+ href: expandHref,
4493
+ "aria-label": expandLabel,
4494
+ "data-slot": "sheet-drawer-expand",
4495
+ className: sheetDrawerExpandButtonClassName,
4496
+ children: [
4497
+ /* @__PURE__ */ jsx28(ExpandActionIcon, { className: "size-[16px]" }),
4498
+ /* @__PURE__ */ jsx28("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
4499
+ ]
4500
+ }
4501
+ ) : /* @__PURE__ */ jsxs27(
4502
+ "button",
4503
+ {
4504
+ type: "button",
4505
+ "aria-label": expandLabel,
4506
+ "data-slot": "sheet-drawer-expand",
4507
+ className: sheetDrawerExpandButtonClassName,
4508
+ onClick: onExpand,
4509
+ children: [
4510
+ /* @__PURE__ */ jsx28(ExpandActionIcon, { className: "size-[16px]" }),
4511
+ /* @__PURE__ */ jsx28("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
4512
+ ]
4513
+ }
4514
+ ) : null,
4515
+ /* @__PURE__ */ jsx28(
4516
+ SheetClose,
4517
+ {
4518
+ "aria-label": closeLabel,
4519
+ "data-slot": "sheet-drawer-close",
4520
+ className: sheetDrawerCloseButtonClassName,
4521
+ children: /* @__PURE__ */ jsx28(XIcon3, { className: "size-[16px]" })
4522
+ }
4523
+ )
4524
+ ] })
4525
+ ] }),
4526
+ /* @__PURE__ */ jsx28("div", { "data-slot": "sheet-drawer-body", className: sheetDrawerBodyClassName, children }),
4527
+ footer ? /* @__PURE__ */ jsx28("div", { "data-slot": "sheet-drawer-footer", className: sheetDrawerFooterClassName, children: footer }) : null
4528
+ ]
4529
+ }
4530
+ ) });
4531
+ }
4532
+
4533
+ // src/components/ui/filter-toolbar.tsx
4534
+ import { Fragment as Fragment7, jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
4535
+ var collapsibleClassNames = {
4536
+ sm: {
4537
+ inline: "hidden @[640px]:flex",
4538
+ trigger: "@[640px]:hidden"
4539
+ },
4540
+ md: {
4541
+ inline: "hidden @[768px]:flex",
4542
+ trigger: "@[768px]:hidden"
4543
+ },
4544
+ lg: {
4545
+ inline: "hidden @[1024px]:flex",
4546
+ trigger: "@[1024px]:hidden"
4547
+ },
4548
+ never: {
4549
+ inline: "flex",
4550
+ trigger: "hidden"
4551
+ }
4552
+ };
4553
+ var FilterToolbar = React25.forwardRef(
4554
+ ({
4555
+ className,
4556
+ search,
4557
+ filters,
4558
+ collapsible,
4559
+ collapseBelow = "lg",
4560
+ activeFilterCount = 0,
4561
+ onClearFilters,
4562
+ collapsedLabel = "\uD544\uD130",
4563
+ resultSummary,
4564
+ clearAction,
4565
+ actions,
4566
+ ...props
4567
+ }, ref) => {
4568
+ const [rootElement, setRootElement] = React25.useState(
4569
+ null
4570
+ );
4571
+ const [containerWidth, setContainerWidth] = React25.useState(
4572
+ null
4573
+ );
4574
+ const [overlayOpen, setOverlayOpen] = React25.useState(false);
4575
+ const triggerRef = React25.useRef(null);
4576
+ const setRootRefs = React25.useCallback(
4577
+ (element) => {
4578
+ setRootElement(element);
4579
+ if (typeof ref === "function") ref(element);
4580
+ else if (ref) ref.current = element;
4581
+ },
4582
+ [ref]
4583
+ );
4584
+ React25.useEffect(() => {
4585
+ if (!rootElement) return;
4586
+ const updateWidth = () => {
4587
+ setContainerWidth(rootElement.getBoundingClientRect().width);
4588
+ };
4589
+ updateWidth();
4590
+ if (typeof ResizeObserver === "undefined") return;
4591
+ const observer = new ResizeObserver(updateWidth);
4592
+ observer.observe(rootElement);
4593
+ return () => observer.disconnect();
4594
+ }, [rootElement]);
4595
+ const handleOverlayOpenChange = React25.useCallback((open) => {
4596
+ setOverlayOpen(open);
4597
+ if (!open) queueMicrotask(() => triggerRef.current?.focus());
4598
+ }, []);
4599
+ const hasMeta = Boolean(resultSummary || clearAction || actions);
4600
+ const hasControls = Boolean(search || filters || collapsible);
4601
+ const hasAppliedFilters = activeFilterCount > 0;
4602
+ const usesSheet = containerWidth !== null && containerWidth < 640;
4603
+ const collapseClasses = collapsibleClassNames[collapseBelow];
4604
+ const collapseTriggerLabel = hasAppliedFilters ? `${collapsedLabel}, ${activeFilterCount}\uAC1C \uC801\uC6A9` : collapsedLabel;
4605
+ const clearFiltersButton = onClearFilters ? /* @__PURE__ */ jsx29(
4606
+ "button",
4607
+ {
4608
+ type: "button",
4609
+ "data-slot": "filter-toolbar-clear-filters",
4610
+ className: "cursor-pointer border-0 bg-transparent p-0 text-body-sm font-medium text-text-secondary no-underline",
4611
+ onClick: onClearFilters,
4612
+ children: "\uD574\uC81C"
4613
+ }
4614
+ ) : null;
4615
+ const collapsedContent = collapsible ? /* @__PURE__ */ jsx29(
4616
+ "div",
4617
+ {
4618
+ "data-slot": "filter-toolbar-collapsed-content",
4619
+ className: "flex flex-col gap-[var(--space-3)] [&>*]:w-full",
4620
+ children: collapsible
4621
+ }
4622
+ ) : null;
4623
+ const collapseTrigger = collapsible ? /* @__PURE__ */ jsxs28(
4624
+ "span",
4625
+ {
4626
+ "data-slot": "filter-toolbar-collapse-trigger",
4627
+ className: cn(
4628
+ "relative order-2 shrink-0 @[640px]:order-4",
4629
+ collapseClasses.trigger
4630
+ ),
4631
+ children: [
4632
+ /* @__PURE__ */ jsx29(
4633
+ IconButton,
4634
+ {
4635
+ ref: triggerRef,
4636
+ "aria-label": collapseTriggerLabel,
4637
+ icon: SlidersHorizontal,
4638
+ size: "md",
4639
+ variant: "outline",
4640
+ onClick: () => handleOverlayOpenChange(true)
4641
+ }
4642
+ ),
4643
+ hasAppliedFilters ? /* @__PURE__ */ jsx29(
4644
+ "span",
4645
+ {
4646
+ "aria-hidden": "true",
4647
+ "data-slot": "filter-toolbar-collapse-count",
4648
+ className: cn(
4649
+ chipCountVariants({ tone: "accent", size: "md" }),
4650
+ "pointer-events-none absolute right-0 top-0 translate-x-1/3 -translate-y-1/3"
4651
+ ),
4652
+ children: activeFilterCount
4653
+ }
4654
+ ) : null
4655
+ ]
4656
+ }
4657
+ ) : null;
4658
+ return /* @__PURE__ */ jsxs28(
4659
+ "div",
4660
+ {
4661
+ ref: setRootRefs,
4662
+ "data-slot": "filter-toolbar",
4663
+ className: cn(
4664
+ "@container flex w-full flex-col gap-[var(--space-2)] text-foreground",
4665
+ className
4666
+ ),
4667
+ ...props,
4668
+ children: [
4669
+ hasControls ? /* @__PURE__ */ jsxs28(
4670
+ "div",
4671
+ {
4672
+ "data-slot": "filter-toolbar-row",
4673
+ className: "flex min-h-[32px] w-full flex-wrap items-center justify-start gap-x-[var(--space-2)] gap-y-[var(--space-2)]",
4674
+ children: [
4675
+ search ? /* @__PURE__ */ jsx29(
4676
+ "div",
4677
+ {
4678
+ "data-slot": "filter-toolbar-search",
4679
+ className: "order-1 min-w-0 max-w-full flex-[1_1_auto] @[640px]:flex-[1_1_280px]",
4680
+ children: search
4681
+ }
4682
+ ) : null,
4683
+ collapsible && usesSheet ? collapseTrigger : null,
4684
+ collapsible && !usesSheet ? /* @__PURE__ */ jsxs28(Popover, { open: overlayOpen, onOpenChange: handleOverlayOpenChange, children: [
4685
+ /* @__PURE__ */ jsx29(PopoverAnchor, { asChild: true, children: collapseTrigger }),
4686
+ overlayOpen ? /* @__PURE__ */ jsxs28(
4687
+ PopoverContent,
4688
+ {
4689
+ role: "dialog",
4690
+ "aria-label": collapsedLabel,
4691
+ side: "bottom",
4692
+ align: "start",
4693
+ className: "w-[320px]",
4694
+ children: [
4695
+ /* @__PURE__ */ jsx29("div", { className: "mb-[var(--space-3)] text-sm font-semibold", children: "\uD544\uD130" }),
4696
+ collapsedContent,
4697
+ clearFiltersButton ? /* @__PURE__ */ jsx29("div", { className: "mt-[var(--space-4)] flex justify-end", children: clearFiltersButton }) : null
4698
+ ]
4699
+ }
4700
+ ) : null
4701
+ ] }) : null,
4702
+ filters ? /* @__PURE__ */ jsx29(
4703
+ "div",
4704
+ {
4705
+ "data-slot": "filter-toolbar-filters",
4706
+ className: "order-3 flex min-w-0 flex-[1_0_100%] flex-wrap items-center gap-[var(--space-2)] @[640px]:flex-[2_1_auto]",
4707
+ children: filters
4708
+ }
4709
+ ) : null,
4710
+ collapsible && !overlayOpen ? /* @__PURE__ */ jsx29(
4711
+ "div",
4712
+ {
4713
+ "data-slot": "filter-toolbar-collapsible",
4714
+ className: cn(
4715
+ "order-5 min-w-0 items-center gap-[var(--space-2)]",
4716
+ collapseClasses.inline
4717
+ ),
4718
+ children: collapsible
4719
+ }
4720
+ ) : null
4721
+ ]
4722
+ }
4723
+ ) : null,
4724
+ collapsible && usesSheet && overlayOpen ? /* @__PURE__ */ jsx29(
4725
+ SheetDrawer,
4726
+ {
4727
+ open: overlayOpen,
4728
+ onOpenChange: handleOverlayOpenChange,
4729
+ title: "\uD544\uD130",
4730
+ footer: clearFiltersButton,
4731
+ children: collapsedContent
4732
+ }
4733
+ ) : null,
4734
+ hasAppliedFilters ? /* @__PURE__ */ jsxs28(
4735
+ "div",
4736
+ {
4737
+ "data-slot": "filter-toolbar-applied",
4738
+ className: "flex items-center gap-[var(--space-1)] text-[11px] text-text-tertiary",
4739
+ children: [
4740
+ /* @__PURE__ */ jsxs28("span", { children: [
4741
+ "\uD544\uD130 ",
4742
+ activeFilterCount,
4743
+ "\uAC1C \uC801\uC6A9"
4744
+ ] }),
4745
+ onClearFilters ? /* @__PURE__ */ jsxs28(Fragment7, { children: [
4746
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: " \xB7 " }),
4747
+ /* @__PURE__ */ jsx29(
4748
+ "button",
4749
+ {
4750
+ type: "button",
4751
+ className: "cursor-pointer border-0 bg-transparent p-0 text-[11px] text-text-secondary no-underline",
4752
+ onClick: onClearFilters,
4753
+ children: "\uD574\uC81C"
4754
+ }
4755
+ )
4756
+ ] }) : null
4757
+ ]
4758
+ }
4759
+ ) : null,
4760
+ hasMeta ? /* @__PURE__ */ jsxs28(
4761
+ "div",
4762
+ {
4763
+ "data-slot": "filter-toolbar-meta",
4764
+ className: "flex min-w-0 flex-wrap items-center justify-end gap-[var(--space-2)]",
4765
+ children: [
4766
+ resultSummary ? /* @__PURE__ */ jsx29(
4767
+ "div",
4768
+ {
4769
+ "data-slot": "filter-toolbar-summary",
4770
+ className: "shrink-0 whitespace-nowrap text-xs leading-snug text-text-tertiary",
4771
+ children: resultSummary
4772
+ }
4773
+ ) : null,
4774
+ clearAction ? /* @__PURE__ */ jsx29("div", { "data-slot": "filter-toolbar-clear", className: "shrink-0", children: clearAction }) : null,
4775
+ actions ? /* @__PURE__ */ jsx29(
4776
+ "div",
4777
+ {
4778
+ "data-slot": "filter-toolbar-actions",
4779
+ className: "flex shrink-0 flex-wrap items-center gap-[var(--space-2)]",
4780
+ children: actions
4781
+ }
4782
+ ) : null
4783
+ ]
4784
+ }
4785
+ ) : null
4786
+ ]
4787
+ }
4788
+ );
4789
+ }
4790
+ );
4791
+ FilterToolbar.displayName = "FilterToolbar";
4792
+
4793
+ // src/components/ui/data-table.tsx
4794
+ import * as React27 from "react";
4795
+ import { ChevronDown as ChevronDown3, ChevronUp as ChevronUp2, ChevronsUpDown } from "lucide-react";
4796
+ import { cva as cva12 } from "class-variance-authority";
4797
+
4798
+ // src/components/ui/checkbox.tsx
4799
+ import * as React26 from "react";
4800
+ import { cva as cva11 } from "class-variance-authority";
4801
+ import { Check as Check3, Minus } from "lucide-react";
4802
+ import { Checkbox as CheckboxPrimitive } from "radix-ui";
4803
+ import { jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
4804
+ var checkboxFieldVariants = cva11(
4805
+ "flex flex-col gap-[var(--space-1)]",
4806
+ {
4807
+ variants: {
4808
+ fullWidth: {
4809
+ true: "w-full",
4810
+ false: "w-fit"
4811
+ }
4812
+ },
4813
+ defaultVariants: {
4814
+ fullWidth: false
4815
+ }
4816
+ }
4817
+ );
4818
+ var checkboxVariants = checkboxFieldVariants;
4819
+ var checkboxRootVariants = cva11(
4820
+ [
4821
+ "group shrink-0 cursor-pointer rounded-[var(--radius-xs)]",
4822
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]",
4823
+ "disabled:cursor-not-allowed"
4824
+ ].join(" ")
4825
+ );
4826
+ var checkboxBoxVariants = cva11(
4827
+ [
4828
+ "flex shrink-0 items-center justify-center rounded-[var(--radius-xs)] border",
4829
+ "border-[var(--border-strong)] bg-[var(--bg-surface)] text-transparent",
4830
+ "transition-colors motion-reduce:transition-none",
4831
+ "group-hover:bg-[var(--action-hover)]",
4832
+ "group-disabled:border-[var(--border-subtle)] group-disabled:bg-[var(--action-disabled-bg)]",
4833
+ "group-data-[state=checked]:border-[var(--primary)] group-data-[state=checked]:bg-[var(--primary)] group-data-[state=checked]:text-[var(--primary-fg)]",
4834
+ "group-data-[state=indeterminate]:border-[var(--primary)] group-data-[state=indeterminate]:bg-[var(--primary)] group-data-[state=indeterminate]:text-[var(--primary-fg)]",
4835
+ "group-disabled:group-data-[state=checked]:border-[var(--border-subtle)] group-disabled:group-data-[state=checked]:bg-[var(--action-disabled-bg)] group-disabled:group-data-[state=checked]:text-text-disabled",
4836
+ "group-disabled:group-data-[state=indeterminate]:border-[var(--border-subtle)] group-disabled:group-data-[state=indeterminate]:bg-[var(--action-disabled-bg)] group-disabled:group-data-[state=indeterminate]:text-text-disabled"
4837
+ ].join(" "),
4838
+ {
4839
+ variants: {
4840
+ size: {
4841
+ sm: "size-[calc(var(--space-4)+var(--space-1))]",
4842
+ md: "size-[calc(var(--space-4)+var(--space-1))]"
4843
+ }
4844
+ },
4845
+ defaultVariants: {
4846
+ size: "md"
4847
+ }
4848
+ }
4849
+ );
4850
+ var checkboxGroupItemVariants = cva11(
4851
+ [
4852
+ "group w-full cursor-pointer text-left transition-colors motion-reduce:transition-none",
4853
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]",
4854
+ "disabled:cursor-not-allowed disabled:text-text-disabled"
4855
+ ].join(" "),
4856
+ {
4857
+ variants: {
4858
+ appearance: {
4859
+ plain: "inline-flex items-start gap-[var(--space-3)] rounded-[var(--radius-sm)] px-pad-compact-x py-pad-compact-y",
4860
+ card: [
4861
+ "flex min-h-[calc(var(--space-12)+var(--space-2))] items-start gap-[var(--space-3)]",
4862
+ "rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-surface)]",
4863
+ "hover:bg-[var(--action-hover)]",
4864
+ "data-[state=checked]:border-[var(--border-strong)] data-[state=checked]:bg-[var(--action-selected)]",
4865
+ "disabled:border-[var(--border-subtle)] disabled:bg-[var(--action-disabled-bg)]",
4866
+ "disabled:data-[state=checked]:border-[var(--border-subtle)] disabled:data-[state=checked]:bg-[var(--action-disabled-bg)]"
4867
+ ].join(" ")
4868
+ },
4869
+ density: {
4870
+ comfortable: "",
4871
+ compact: ""
4872
+ }
4873
+ },
4874
+ compoundVariants: [
4875
+ {
4876
+ appearance: "card",
4877
+ density: "comfortable",
4878
+ className: "px-pad-default-x py-pad-roomy-y"
4879
+ },
4880
+ {
4881
+ appearance: "card",
4882
+ density: "compact",
4883
+ className: "px-pad-compact-x py-pad-default-y"
4884
+ }
4885
+ ],
4886
+ defaultVariants: {
4887
+ appearance: "plain",
4888
+ density: "comfortable"
4889
+ }
4890
+ }
4891
+ );
4892
+ var checkboxGroupBoxVariants = cva11(
4893
+ "mt-[2px]",
4894
+ {
4895
+ variants: {
4896
+ appearance: {
4897
+ plain: "",
4898
+ card: "mt-[var(--space-1)]"
4899
+ }
4900
+ },
4901
+ defaultVariants: {
4902
+ appearance: "plain"
4903
+ }
4904
+ }
4905
+ );
4906
+ var CheckboxGroupContext = React26.createContext(null);
4907
+ function getLabel(children, label) {
4908
+ return children ?? label;
4909
+ }
4910
+ var Checkbox = React26.forwardRef(
4911
+ ({
4912
+ className,
4913
+ size = "md",
4914
+ fullWidth = false,
4915
+ children,
4916
+ label,
4917
+ description,
4918
+ required,
4919
+ error,
4920
+ id,
4921
+ value,
4922
+ name,
4923
+ checked,
4924
+ disabled,
4925
+ onCheckedChange,
4926
+ ...props
4927
+ }, ref) => {
4928
+ const group = React26.useContext(CheckboxGroupContext);
4929
+ const generatedId = React26.useId();
4930
+ const checkboxId = id ?? generatedId;
4931
+ const labelContent = getLabel(children, label);
4932
+ const isGrouped = Boolean(group && value != null);
4933
+ const valueString = value == null ? void 0 : String(value);
4934
+ const resolvedChecked = isGrouped && valueString ? group?.selectedValues.has(valueString) : checked;
4935
+ const resolvedDisabled = disabled || group?.disabled;
4936
+ const resolvedName = name ?? group?.name;
4937
+ const labelId = `${checkboxId}-label`;
4938
+ const descriptionId = description && !error ? `${checkboxId}-description` : void 0;
4939
+ const errorId = error ? `${checkboxId}-error` : void 0;
4940
+ const describedBy = errorId ?? descriptionId;
4941
+ const handleCheckedChange = (nextChecked) => {
4942
+ onCheckedChange?.(nextChecked);
4943
+ if (isGrouped && valueString) {
4944
+ group?.toggleValue(valueString, nextChecked === true);
4945
+ }
4946
+ };
4947
+ if (isGrouped) {
4948
+ const appearance = group?.appearance ?? "plain";
4949
+ const density = group?.density ?? "comfortable";
4950
+ return /* @__PURE__ */ jsxs29(
4951
+ CheckboxPrimitive.Root,
4952
+ {
4953
+ ref,
4954
+ id: checkboxId,
4955
+ "data-slot": "checkbox",
4956
+ "aria-labelledby": labelId,
4957
+ "aria-describedby": describedBy,
4958
+ "aria-required": required || void 0,
4959
+ "aria-invalid": error ? true : void 0,
4960
+ name: resolvedName,
4961
+ value: valueString,
4962
+ checked: resolvedChecked,
4963
+ disabled: resolvedDisabled,
4964
+ className: cn(
4965
+ checkboxGroupItemVariants({ appearance, density }),
4966
+ className
4967
+ ),
4968
+ onCheckedChange: handleCheckedChange,
4969
+ ...props,
4970
+ children: [
4971
+ /* @__PURE__ */ jsx30(
4972
+ "span",
4973
+ {
4974
+ "aria-hidden": "true",
4975
+ "data-slot": "checkbox-box",
4976
+ className: cn(
4977
+ checkboxBoxVariants({ size }),
4978
+ checkboxGroupBoxVariants({ appearance })
4979
+ ),
4980
+ children: /* @__PURE__ */ jsx30(
4981
+ CheckboxPrimitive.Indicator,
4982
+ {
4983
+ "data-slot": "checkbox-indicator",
4984
+ className: "flex items-center justify-center",
4985
+ children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx30(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx30(Check3, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
4986
+ }
4987
+ )
4988
+ }
4989
+ ),
4990
+ /* @__PURE__ */ jsxs29("span", { className: "flex min-w-0 flex-col gap-[var(--space-1)]", children: [
4991
+ /* @__PURE__ */ jsxs29(
4992
+ "span",
4993
+ {
4994
+ id: labelId,
4995
+ "data-slot": "checkbox-label",
4996
+ className: "text-sm font-medium leading-snug text-foreground group-disabled:text-text-disabled",
4997
+ children: [
4998
+ labelContent,
4999
+ required ? /* @__PURE__ */ jsx30(
5000
+ "span",
5001
+ {
5002
+ "aria-hidden": "true",
5003
+ "data-slot": "checkbox-required-marker",
5004
+ className: "ml-[var(--space-1)] font-bold text-[var(--semantic-error,var(--error))]",
5005
+ children: "*"
5006
+ }
5007
+ ) : null
5008
+ ]
5009
+ }
5010
+ ),
5011
+ error ? /* @__PURE__ */ jsx30(
5012
+ "span",
5013
+ {
5014
+ id: errorId,
5015
+ role: "alert",
5016
+ "data-slot": "checkbox-error",
5017
+ className: "text-xs font-medium leading-normal text-[var(--error)]",
5018
+ children: error
5019
+ }
5020
+ ) : description ? /* @__PURE__ */ jsx30(
5021
+ "span",
5022
+ {
5023
+ id: descriptionId,
5024
+ "data-slot": "checkbox-description",
5025
+ className: "text-xs font-normal leading-normal text-text-tertiary group-disabled:text-text-disabled",
5026
+ children: description
5027
+ }
5028
+ ) : null
5029
+ ] })
5030
+ ]
5031
+ }
5032
+ );
5033
+ }
5034
+ const labelClassName = cn(
5035
+ "cursor-pointer select-none text-left font-medium text-foreground",
5036
+ size === "sm" ? "text-xs" : "text-sm",
5037
+ resolvedDisabled && "cursor-not-allowed text-text-disabled"
5038
+ );
5039
+ return /* @__PURE__ */ jsxs29(
5040
+ "div",
5041
+ {
5042
+ "data-slot": "checkbox-field",
5043
+ "data-disabled": resolvedDisabled ? "" : void 0,
5044
+ className: checkboxFieldVariants({ fullWidth }),
5045
+ children: [
5046
+ /* @__PURE__ */ jsxs29("div", { className: "inline-flex items-center gap-[var(--space-3)]", children: [
5047
+ /* @__PURE__ */ jsx30(
5048
+ CheckboxPrimitive.Root,
5049
+ {
5050
+ ref,
5051
+ id: checkboxId,
5052
+ "data-slot": "checkbox",
5053
+ "aria-describedby": describedBy,
5054
+ "aria-required": required || void 0,
5055
+ "aria-invalid": error ? true : void 0,
5056
+ name: resolvedName,
5057
+ value: valueString,
5058
+ checked: resolvedChecked,
5059
+ disabled: resolvedDisabled,
5060
+ className: cn(checkboxRootVariants(), className),
5061
+ onCheckedChange: handleCheckedChange,
5062
+ ...props,
5063
+ children: /* @__PURE__ */ jsx30(
5064
+ "span",
5065
+ {
5066
+ "aria-hidden": "true",
5067
+ "data-slot": "checkbox-box",
5068
+ className: checkboxBoxVariants({ size }),
5069
+ children: /* @__PURE__ */ jsx30(
5070
+ CheckboxPrimitive.Indicator,
5071
+ {
5072
+ "data-slot": "checkbox-indicator",
5073
+ className: "flex items-center justify-center",
5074
+ children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx30(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx30(Check3, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
5075
+ }
5076
+ )
5077
+ }
5078
+ )
5079
+ }
5080
+ ),
5081
+ labelContent ? /* @__PURE__ */ jsxs29(
5082
+ "label",
5083
+ {
5084
+ id: labelId,
5085
+ htmlFor: checkboxId,
5086
+ "data-slot": "checkbox-label",
5087
+ className: labelClassName,
5088
+ children: [
5089
+ labelContent,
5090
+ required ? /* @__PURE__ */ jsx30(
5091
+ "span",
5092
+ {
5093
+ "aria-hidden": "true",
5094
+ "data-slot": "checkbox-required-marker",
5095
+ className: "ml-[var(--space-1)] font-bold text-[var(--semantic-error,var(--error))]",
5096
+ children: "*"
5097
+ }
5098
+ ) : null
5099
+ ]
5100
+ }
5101
+ ) : null
5102
+ ] }),
5103
+ error ? /* @__PURE__ */ jsx30(
5104
+ "p",
5105
+ {
5106
+ id: errorId,
5107
+ role: "alert",
5108
+ "data-slot": "checkbox-error",
5109
+ className: "ml-[32px] text-xs font-medium leading-normal text-[var(--error)]",
5110
+ children: error
5111
+ }
5112
+ ) : description ? /* @__PURE__ */ jsx30(
5113
+ "p",
5114
+ {
5115
+ id: descriptionId,
5116
+ "data-slot": "checkbox-description",
5117
+ className: cn(
5118
+ "ml-[32px] text-xs font-normal leading-normal text-text-tertiary",
5119
+ resolvedDisabled && "text-text-disabled"
5120
+ ),
5121
+ children: description
5122
+ }
5123
+ ) : null
5124
+ ]
5125
+ }
5126
+ );
5127
+ }
5128
+ );
5129
+ Checkbox.displayName = "Checkbox";
5130
+
5131
+ // src/components/ui/data-table.tsx
5132
+ import { jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
5133
+ var dataTableVariants = cva12(
5134
+ [
5135
+ "relative overflow-hidden rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
5136
+ "text-foreground"
5137
+ ].join(" "),
5138
+ {
5139
+ variants: {
5140
+ density: {
5141
+ standard: "",
5142
+ compact: ""
5143
+ },
5144
+ surface: surfaceClassNames
5145
+ },
5146
+ defaultVariants: {
5147
+ density: "standard",
5148
+ surface: "surface"
5149
+ }
5150
+ }
5151
+ );
5152
+ var dataTableRowVariants = cva12(
5153
+ [
5154
+ "grid min-h-[48px] items-center border-t border-[var(--border-subtle)]",
5155
+ "text-body-sm leading-compact text-foreground",
5156
+ "transition-colors motion-reduce:transition-none"
5157
+ ].join(" "),
5158
+ {
5159
+ variants: {
5160
+ interactive: {
5161
+ true: "cursor-pointer hover:bg-[var(--action-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--focus-ring)]",
5162
+ false: ""
5163
+ },
5164
+ selected: {
5165
+ true: "bg-[var(--action-selected)]",
5166
+ false: ""
5167
+ }
5168
+ },
5169
+ defaultVariants: {
5170
+ interactive: false,
5171
+ selected: false
5172
+ }
5173
+ }
5174
+ );
5175
+ var alignmentClass = {
5176
+ left: "justify-start text-left",
4235
5177
  center: "justify-center text-center",
4236
5178
  right: "justify-end text-right"
4237
5179
  };
@@ -4250,7 +5192,7 @@ function getRenderedCell(row, column) {
4250
5192
  if (value === null || value === void 0) {
4251
5193
  return null;
4252
5194
  }
4253
- if (React24.isValidElement(value)) {
5195
+ if (React27.isValidElement(value)) {
4254
5196
  return value;
4255
5197
  }
4256
5198
  return String(value);
@@ -4290,7 +5232,7 @@ function isInteractiveTarget(target) {
4290
5232
  function SortIcon({ sort, columnKey }) {
4291
5233
  const isActive = sort?.key === columnKey;
4292
5234
  if (!isActive) {
4293
- return /* @__PURE__ */ jsx26(
5235
+ return /* @__PURE__ */ jsx31(
4294
5236
  ChevronsUpDown,
4295
5237
  {
4296
5238
  "aria-hidden": "true",
@@ -4302,7 +5244,7 @@ function SortIcon({ sort, columnKey }) {
4302
5244
  );
4303
5245
  }
4304
5246
  const Icon = sort.dir === "asc" ? ChevronUp2 : ChevronDown3;
4305
- return /* @__PURE__ */ jsx26(
5247
+ return /* @__PURE__ */ jsx31(
4306
5248
  Icon,
4307
5249
  {
4308
5250
  "aria-hidden": "true",
@@ -4325,7 +5267,7 @@ function MobileSortControls({
4325
5267
  if (sortableColumns.length === 0) {
4326
5268
  return null;
4327
5269
  }
4328
- return /* @__PURE__ */ jsxs25(
5270
+ return /* @__PURE__ */ jsxs30(
4329
5271
  "div",
4330
5272
  {
4331
5273
  "data-slot": "data-table-mobile-sort-toolbar",
@@ -4336,11 +5278,11 @@ function MobileSortControls({
4336
5278
  surfaceClassNames[surface]
4337
5279
  ),
4338
5280
  children: [
4339
- /* @__PURE__ */ jsx26("span", { className: "text-[12px] font-medium text-text-tertiary", children: "\uC815\uB82C" }),
5281
+ /* @__PURE__ */ jsx31("span", { className: "text-[12px] font-medium text-text-tertiary", children: "\uC815\uB82C" }),
4340
5282
  sortableColumns.map((column) => {
4341
5283
  const active = sortBy?.key === column.key;
4342
5284
  const nextSort = getNextSort(sortBy, column.key);
4343
- return /* @__PURE__ */ jsx26(
5285
+ return /* @__PURE__ */ jsx31(
4344
5286
  Button,
4345
5287
  {
4346
5288
  type: "button",
@@ -4349,9 +5291,9 @@ function MobileSortControls({
4349
5291
  variant: active ? "secondary" : "outline",
4350
5292
  "aria-pressed": active,
4351
5293
  onClick: () => onSortChange?.(column.key, nextSort),
4352
- children: /* @__PURE__ */ jsxs25("span", { className: "inline-flex min-w-0 items-center gap-[var(--space-1)]", children: [
4353
- /* @__PURE__ */ jsx26("span", { className: "truncate", children: column.header }),
4354
- /* @__PURE__ */ jsx26(SortIcon, { sort: sortBy, columnKey: column.key })
5294
+ children: /* @__PURE__ */ jsxs30("span", { className: "inline-flex min-w-0 items-center gap-[var(--space-1)]", children: [
5295
+ /* @__PURE__ */ jsx31("span", { className: "truncate", children: column.header }),
5296
+ /* @__PURE__ */ jsx31(SortIcon, { sort: sortBy, columnKey: column.key })
4355
5297
  ] })
4356
5298
  },
4357
5299
  column.key
@@ -4371,17 +5313,17 @@ function SkeletonRows({
4371
5313
  // role="table"의 허용 자식은 row/rowgroup뿐이라 컨테이너는 rowgroup이어야 한다.
4372
5314
  // 로딩 알림은 그 안의 row/cell 안에 둔다 — 종전에는 컨테이너가 role="status"라
4373
5315
  // aria-required-children(Critical)이 났다.
4374
- /* @__PURE__ */ jsxs25("div", { role: "rowgroup", children: [
4375
- /* @__PURE__ */ jsx26("div", { role: "row", children: /* @__PURE__ */ jsx26("div", { role: "cell", "aria-colindex": 1, "aria-label": "\uB370\uC774\uD130 \uB85C\uB4DC \uC911", children: /* @__PURE__ */ jsx26("span", { role: "status", className: "sr-only", children: "\uB370\uC774\uD130 \uB85C\uB4DC \uC911" }) }) }),
4376
- Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */ jsxs25(
5316
+ /* @__PURE__ */ jsxs30("div", { role: "rowgroup", children: [
5317
+ /* @__PURE__ */ jsx31("div", { role: "row", children: /* @__PURE__ */ jsx31("div", { role: "cell", "aria-colindex": 1, "aria-label": "\uB370\uC774\uD130 \uB85C\uB4DC \uC911", children: /* @__PURE__ */ jsx31("span", { role: "status", className: "sr-only", children: "\uB370\uC774\uD130 \uB85C\uB4DC \uC911" }) }) }),
5318
+ Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */ jsxs30(
4377
5319
  "div",
4378
5320
  {
4379
5321
  "data-slot": "data-table-skeleton-row",
4380
5322
  className: "grid min-h-[48px] items-center border-t border-[var(--border-subtle)]",
4381
5323
  style: { gridTemplateColumns },
4382
5324
  children: [
4383
- selectable ? /* @__PURE__ */ jsx26("div", { "aria-hidden": "true", className: "px-[var(--space-4)]" }) : null,
4384
- columns.map((column, columnIndex) => /* @__PURE__ */ jsx26("div", { className: "px-[var(--space-4)] py-[var(--space-2)]", children: /* @__PURE__ */ jsx26(
5325
+ selectable ? /* @__PURE__ */ jsx31("div", { "aria-hidden": "true", className: "px-[var(--space-4)]" }) : null,
5326
+ columns.map((column, columnIndex) => /* @__PURE__ */ jsx31("div", { className: "px-[var(--space-4)] py-[var(--space-2)]", children: /* @__PURE__ */ jsx31(
4385
5327
  "div",
4386
5328
  {
4387
5329
  className: cn(
@@ -4398,22 +5340,22 @@ function SkeletonRows({
4398
5340
  );
4399
5341
  }
4400
5342
  function MobileSkeletonCards({ count }) {
4401
- return /* @__PURE__ */ jsx26(
5343
+ return /* @__PURE__ */ jsx31(
4402
5344
  "div",
4403
5345
  {
4404
5346
  "data-slot": "data-table-mobile-skeleton",
4405
5347
  "aria-label": "\uB370\uC774\uD130 \uB85C\uB4DC \uC911",
4406
5348
  role: "status",
4407
5349
  className: "md:hidden",
4408
- children: Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */ jsxs25(
5350
+ children: Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */ jsxs30(
4409
5351
  "div",
4410
5352
  {
4411
5353
  "data-slot": "data-table-mobile-skeleton-card",
4412
5354
  className: "flex flex-col gap-[var(--space-2)] border-t border-[var(--border-subtle)] px-[var(--space-4)] py-[var(--space-4)]",
4413
5355
  children: [
4414
- /* @__PURE__ */ jsx26("div", { className: "h-[14px] w-[72%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]" }),
4415
- /* @__PURE__ */ jsx26("div", { className: "h-[12px] w-[56%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]" }),
4416
- /* @__PURE__ */ jsx26("div", { className: "h-[12px] w-[64%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]" })
5356
+ /* @__PURE__ */ jsx31("div", { className: "h-[14px] w-[72%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]" }),
5357
+ /* @__PURE__ */ jsx31("div", { className: "h-[12px] w-[56%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]" }),
5358
+ /* @__PURE__ */ jsx31("div", { className: "h-[12px] w-[64%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]" })
4417
5359
  ]
4418
5360
  },
4419
5361
  rowIndex
@@ -4471,7 +5413,7 @@ function DataTableInner({
4471
5413
  }
4472
5414
  emitSelection(nextIds);
4473
5415
  };
4474
- return /* @__PURE__ */ jsxs25(
5416
+ return /* @__PURE__ */ jsxs30(
4475
5417
  "div",
4476
5418
  {
4477
5419
  ref,
@@ -4479,7 +5421,7 @@ function DataTableInner({
4479
5421
  className: cn(dataTableVariants({ density, surface, className })),
4480
5422
  ...props,
4481
5423
  children: [
4482
- selectable ? /* @__PURE__ */ jsx26(
5424
+ selectable ? /* @__PURE__ */ jsx31(
4483
5425
  "div",
4484
5426
  {
4485
5427
  "data-slot": "data-table-selection-status",
@@ -4488,17 +5430,17 @@ function DataTableInner({
4488
5430
  children: selectedCount > 0 ? `${selectedCount.toLocaleString("ko-KR")}\uAC1C \uC120\uD0DD\uB428` : ""
4489
5431
  }
4490
5432
  ) : null,
4491
- loading && data.length > 0 ? /* @__PURE__ */ jsx26(
5433
+ loading && data.length > 0 ? /* @__PURE__ */ jsx31(
4492
5434
  "div",
4493
5435
  {
4494
5436
  "data-slot": "data-table-progress",
4495
5437
  "aria-hidden": "true",
4496
5438
  className: "absolute left-0 right-0 top-0 z-10 h-[2px] overflow-hidden bg-[var(--action-selected)]",
4497
- children: /* @__PURE__ */ jsx26("div", { className: "h-full w-1/3 animate-pulse bg-[var(--primary)]" })
5439
+ children: /* @__PURE__ */ jsx31("div", { className: "h-full w-1/3 animate-pulse bg-[var(--primary)]" })
4498
5440
  }
4499
5441
  ) : null,
4500
- /* @__PURE__ */ jsx26("div", { "data-slot": "data-table-desktop", className: "max-md:hidden md:block", children: /* @__PURE__ */ jsxs25("div", { role: "table", "aria-label": ariaLabel, children: [
4501
- /* @__PURE__ */ jsxs25(
5442
+ /* @__PURE__ */ jsx31("div", { "data-slot": "data-table-desktop", className: "max-md:hidden md:block", children: /* @__PURE__ */ jsxs30("div", { role: "table", "aria-label": ariaLabel, children: [
5443
+ /* @__PURE__ */ jsxs30(
4502
5444
  "div",
4503
5445
  {
4504
5446
  "data-slot": "data-table-header",
@@ -4506,20 +5448,20 @@ function DataTableInner({
4506
5448
  className: "grid min-h-[40px] items-center bg-[var(--bg-raised)] text-[12px] font-semibold uppercase leading-snug text-text-tertiary",
4507
5449
  style: { gridTemplateColumns },
4508
5450
  children: [
4509
- selectable ? /* @__PURE__ */ jsx26("div", { role: "columnheader", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx26(
5451
+ selectable ? /* @__PURE__ */ jsx31("div", { role: "columnheader", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx31(
4510
5452
  Checkbox,
4511
5453
  {
4512
5454
  "aria-label": "\uC804\uCCB4 \uD589 \uC120\uD0DD",
4513
5455
  checked: partiallySelected ? "indeterminate" : allVisibleRowsSelected,
4514
5456
  onCheckedChange: (nextChecked) => toggleAllRows(nextChecked === true),
4515
- children: /* @__PURE__ */ jsx26("span", { className: "sr-only", children: "\uC804\uCCB4 \uD589 \uC120\uD0DD" })
5457
+ children: /* @__PURE__ */ jsx31("span", { className: "sr-only", children: "\uC804\uCCB4 \uD589 \uC120\uD0DD" })
4516
5458
  }
4517
5459
  ) }) : null,
4518
5460
  columns.map((column) => {
4519
5461
  const align = column.align ?? "left";
4520
5462
  const nextSort = getNextSort(sortBy, column.key);
4521
5463
  const ariaSort = sortBy?.key === column.key ? sortBy.dir === "asc" ? "ascending" : "descending" : void 0;
4522
- return /* @__PURE__ */ jsx26(
5464
+ return /* @__PURE__ */ jsx31(
4523
5465
  "div",
4524
5466
  {
4525
5467
  role: "columnheader",
@@ -4528,7 +5470,7 @@ function DataTableInner({
4528
5470
  "flex min-w-0 items-center gap-[var(--space-1)] px-[var(--space-4)] py-[var(--space-2)]",
4529
5471
  alignmentClass[align]
4530
5472
  ),
4531
- children: column.sortable ? /* @__PURE__ */ jsxs25(
5473
+ children: column.sortable ? /* @__PURE__ */ jsxs30(
4532
5474
  "button",
4533
5475
  {
4534
5476
  type: "button",
@@ -4539,11 +5481,11 @@ function DataTableInner({
4539
5481
  ),
4540
5482
  onClick: () => onSortChange?.(column.key, nextSort),
4541
5483
  children: [
4542
- /* @__PURE__ */ jsx26("span", { className: "truncate", children: column.header }),
4543
- /* @__PURE__ */ jsx26(SortIcon, { sort: sortBy, columnKey: column.key })
5484
+ /* @__PURE__ */ jsx31("span", { className: "truncate", children: column.header }),
5485
+ /* @__PURE__ */ jsx31(SortIcon, { sort: sortBy, columnKey: column.key })
4544
5486
  ]
4545
5487
  }
4546
- ) : /* @__PURE__ */ jsx26("span", { className: "truncate", children: column.header })
5488
+ ) : /* @__PURE__ */ jsx31("span", { className: "truncate", children: column.header })
4547
5489
  },
4548
5490
  column.key
4549
5491
  );
@@ -4551,7 +5493,7 @@ function DataTableInner({
4551
5493
  ]
4552
5494
  }
4553
5495
  ),
4554
- loading && data.length === 0 ? /* @__PURE__ */ jsx26(
5496
+ loading && data.length === 0 ? /* @__PURE__ */ jsx31(
4555
5497
  SkeletonRows,
4556
5498
  {
4557
5499
  columns,
@@ -4562,7 +5504,7 @@ function DataTableInner({
4562
5504
  ) : data.length === 0 ? (
4563
5505
  /* role="table" 직계 자식은 row/rowgroup이어야 한다. data-slot과 테두리는
4564
5506
  그대로 유지해 시각 계약을 깨지 않는다(빈 상태에서도 표가 테두리를 그린다). */
4565
- /* @__PURE__ */ jsx26("div", { role: "rowgroup", children: /* @__PURE__ */ jsx26("div", { role: "row", children: /* @__PURE__ */ jsx26(
5507
+ /* @__PURE__ */ jsx31("div", { role: "rowgroup", children: /* @__PURE__ */ jsx31("div", { role: "row", children: /* @__PURE__ */ jsx31(
4566
5508
  "div",
4567
5509
  {
4568
5510
  role: "cell",
@@ -4572,12 +5514,12 @@ function DataTableInner({
4572
5514
  children: emptyState
4573
5515
  }
4574
5516
  ) }) })
4575
- ) : /* @__PURE__ */ jsx26("div", { role: "rowgroup", children: data.map((row) => {
5517
+ ) : /* @__PURE__ */ jsx31("div", { role: "rowgroup", children: data.map((row) => {
4576
5518
  const rowId = getRowId(row, keyField);
4577
5519
  const selected = resolvedSelectedIds.has(rowId);
4578
5520
  const visuallySelected = selected || rowId === activeRowId;
4579
5521
  const href = rowHref?.(row);
4580
- return /* @__PURE__ */ jsxs25(
5522
+ return /* @__PURE__ */ jsxs30(
4581
5523
  "div",
4582
5524
  {
4583
5525
  "data-slot": "data-table-row",
@@ -4604,13 +5546,13 @@ function DataTableInner({
4604
5546
  }
4605
5547
  },
4606
5548
  children: [
4607
- selectable ? /* @__PURE__ */ jsx26("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx26(
5549
+ selectable ? /* @__PURE__ */ jsx31("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx31(
4608
5550
  Checkbox,
4609
5551
  {
4610
5552
  "aria-label": `${String(row[columns[0]?.key] ?? rowId)} \uD589 \uC120\uD0DD`,
4611
5553
  checked: selected,
4612
5554
  onCheckedChange: (nextChecked) => toggleRow(rowId, nextChecked === true),
4613
- children: /* @__PURE__ */ jsxs25("span", { className: "sr-only", children: [
5555
+ children: /* @__PURE__ */ jsxs30("span", { className: "sr-only", children: [
4614
5556
  rowId,
4615
5557
  " \uD589 \uC120\uD0DD"
4616
5558
  ] })
@@ -4618,7 +5560,7 @@ function DataTableInner({
4618
5560
  ) }) : null,
4619
5561
  columns.map((column) => {
4620
5562
  const align = column.align ?? "left";
4621
- return /* @__PURE__ */ jsx26(
5563
+ return /* @__PURE__ */ jsx31(
4622
5564
  "div",
4623
5565
  {
4624
5566
  "data-slot": "data-table-cell",
@@ -4629,7 +5571,7 @@ function DataTableInner({
4629
5571
  column.tabular ? "font-[family-name:var(--font-display)] tabular-nums" : null,
4630
5572
  align === "right" ? "text-text-tertiary" : null
4631
5573
  ),
4632
- children: /* @__PURE__ */ jsx26("span", { className: "min-w-0 truncate", children: getRenderedCell(row, column) })
5574
+ children: /* @__PURE__ */ jsx31("span", { className: "min-w-0 truncate", children: getRenderedCell(row, column) })
4633
5575
  },
4634
5576
  column.key
4635
5577
  );
@@ -4640,7 +5582,7 @@ function DataTableInner({
4640
5582
  );
4641
5583
  }) })
4642
5584
  ] }) }),
4643
- /* @__PURE__ */ jsx26(
5585
+ /* @__PURE__ */ jsx31(
4644
5586
  MobileSortControls,
4645
5587
  {
4646
5588
  columns,
@@ -4650,14 +5592,14 @@ function DataTableInner({
4650
5592
  surface
4651
5593
  }
4652
5594
  ),
4653
- loading && data.length === 0 ? /* @__PURE__ */ jsx26(MobileSkeletonCards, { count: skeletonRowCount }) : data.length === 0 ? /* @__PURE__ */ jsx26(
5595
+ loading && data.length === 0 ? /* @__PURE__ */ jsx31(MobileSkeletonCards, { count: skeletonRowCount }) : data.length === 0 ? /* @__PURE__ */ jsx31(
4654
5596
  "div",
4655
5597
  {
4656
5598
  "data-slot": "data-table-mobile-empty",
4657
5599
  className: "border-t border-[var(--border-subtle)] p-[var(--space-4)] md:hidden",
4658
5600
  children: emptyState
4659
5601
  }
4660
- ) : /* @__PURE__ */ jsx26(
5602
+ ) : /* @__PURE__ */ jsx31(
4661
5603
  "div",
4662
5604
  {
4663
5605
  "data-slot": "data-table-mobile-list",
@@ -4671,7 +5613,7 @@ function DataTableInner({
4671
5613
  const href = rowHref?.(row);
4672
5614
  const primaryText = getAccessibleCellText(row, primaryColumn, rowId);
4673
5615
  const primaryLabel = primaryColumn ? getHeaderLabel(primaryColumn) : "\uD589";
4674
- return /* @__PURE__ */ jsxs25(
5616
+ return /* @__PURE__ */ jsxs30(
4675
5617
  "div",
4676
5618
  {
4677
5619
  "data-slot": "data-table-mobile-card",
@@ -4703,20 +5645,20 @@ function DataTableInner({
4703
5645
  }
4704
5646
  },
4705
5647
  children: [
4706
- /* @__PURE__ */ jsxs25("div", { className: "flex min-w-0 items-start gap-[var(--space-3)]", children: [
4707
- selectable ? /* @__PURE__ */ jsx26("div", { "data-slot": "data-table-mobile-card-select", className: "shrink-0 pt-[2px]", children: /* @__PURE__ */ jsx26(
5648
+ /* @__PURE__ */ jsxs30("div", { className: "flex min-w-0 items-start gap-[var(--space-3)]", children: [
5649
+ selectable ? /* @__PURE__ */ jsx31("div", { "data-slot": "data-table-mobile-card-select", className: "shrink-0 pt-[2px]", children: /* @__PURE__ */ jsx31(
4708
5650
  Checkbox,
4709
5651
  {
4710
5652
  "aria-label": `${primaryText} \uBAA8\uBC14\uC77C \uCE74\uB4DC \uC120\uD0DD`,
4711
5653
  checked: selected,
4712
5654
  onCheckedChange: (nextChecked) => toggleRow(rowId, nextChecked === true),
4713
- children: /* @__PURE__ */ jsxs25("span", { className: "sr-only", children: [
5655
+ children: /* @__PURE__ */ jsxs30("span", { className: "sr-only", children: [
4714
5656
  rowId,
4715
5657
  " \uBAA8\uBC14\uC77C \uCE74\uB4DC \uC120\uD0DD"
4716
5658
  ] })
4717
5659
  }
4718
5660
  ) }) : null,
4719
- /* @__PURE__ */ jsx26(
5661
+ /* @__PURE__ */ jsx31(
4720
5662
  "div",
4721
5663
  {
4722
5664
  "data-slot": "data-table-mobile-card-primary",
@@ -4725,16 +5667,16 @@ function DataTableInner({
4725
5667
  }
4726
5668
  )
4727
5669
  ] }),
4728
- secondaryColumns.length > 0 ? /* @__PURE__ */ jsx26("dl", { className: "grid min-w-0 gap-[var(--space-2)]", children: secondaryColumns.map((column) => {
5670
+ secondaryColumns.length > 0 ? /* @__PURE__ */ jsx31("dl", { className: "grid min-w-0 gap-[var(--space-2)]", children: secondaryColumns.map((column) => {
4729
5671
  const align = column.align ?? "left";
4730
- return /* @__PURE__ */ jsxs25(
5672
+ return /* @__PURE__ */ jsxs30(
4731
5673
  "div",
4732
5674
  {
4733
5675
  "data-slot": "data-table-mobile-card-field",
4734
5676
  className: "grid min-w-0 grid-cols-[minmax(0,0.42fr)_minmax(0,1fr)] gap-[var(--space-2)] text-[12px] leading-snug",
4735
5677
  children: [
4736
- /* @__PURE__ */ jsx26("dt", { className: "min-w-0 text-text-tertiary", children: /* @__PURE__ */ jsx26("span", { className: "truncate", children: column.header }) }),
4737
- /* @__PURE__ */ jsx26(
5678
+ /* @__PURE__ */ jsx31("dt", { className: "min-w-0 text-text-tertiary", children: /* @__PURE__ */ jsx31("span", { className: "truncate", children: column.header }) }),
5679
+ /* @__PURE__ */ jsx31(
4738
5680
  "dd",
4739
5681
  {
4740
5682
  className: cn(
@@ -4742,7 +5684,7 @@ function DataTableInner({
4742
5684
  alignmentClass[align],
4743
5685
  column.tabular ? "font-[family-name:var(--font-display)] tabular-nums" : null
4744
5686
  ),
4745
- children: /* @__PURE__ */ jsx26("span", { className: "min-w-0 truncate", children: getRenderedCell(row, column) })
5687
+ children: /* @__PURE__ */ jsx31("span", { className: "min-w-0 truncate", children: getRenderedCell(row, column) })
4746
5688
  }
4747
5689
  )
4748
5690
  ]
@@ -4761,27 +5703,27 @@ function DataTableInner({
4761
5703
  }
4762
5704
  );
4763
5705
  }
4764
- var DataTable = React24.forwardRef(DataTableInner);
5706
+ var DataTable = React27.forwardRef(DataTableInner);
4765
5707
  DataTable.displayName = "DataTable";
4766
5708
 
4767
5709
  // src/components/ui/dropdown-menu.tsx
4768
5710
  import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
4769
5711
  import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
4770
- import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
5712
+ import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
4771
5713
  function DropdownMenu({
4772
5714
  ...props
4773
5715
  }) {
4774
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
5716
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
4775
5717
  }
4776
5718
  function DropdownMenuPortal({
4777
5719
  ...props
4778
5720
  }) {
4779
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
5721
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
4780
5722
  }
4781
5723
  function DropdownMenuTrigger({
4782
5724
  ...props
4783
5725
  }) {
4784
- return /* @__PURE__ */ jsx27(
5726
+ return /* @__PURE__ */ jsx32(
4785
5727
  DropdownMenuPrimitive.Trigger,
4786
5728
  {
4787
5729
  "data-slot": "dropdown-menu-trigger",
@@ -4794,7 +5736,7 @@ function DropdownMenuContent({
4794
5736
  sideOffset = 4,
4795
5737
  ...props
4796
5738
  }) {
4797
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx27(
5739
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx32(
4798
5740
  DropdownMenuPrimitive.Content,
4799
5741
  {
4800
5742
  "data-slot": "dropdown-menu-content",
@@ -4817,7 +5759,7 @@ function DropdownMenuContent({
4817
5759
  function DropdownMenuGroup({
4818
5760
  ...props
4819
5761
  }) {
4820
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
5762
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
4821
5763
  }
4822
5764
  function DropdownMenuItem({
4823
5765
  className,
@@ -4825,7 +5767,7 @@ function DropdownMenuItem({
4825
5767
  variant = "default",
4826
5768
  ...props
4827
5769
  }) {
4828
- return /* @__PURE__ */ jsx27(
5770
+ return /* @__PURE__ */ jsx32(
4829
5771
  DropdownMenuPrimitive.Item,
4830
5772
  {
4831
5773
  "data-slot": "dropdown-menu-item",
@@ -4852,7 +5794,7 @@ function DropdownMenuCheckboxItem({
4852
5794
  checked,
4853
5795
  ...props
4854
5796
  }) {
4855
- return /* @__PURE__ */ jsxs26(
5797
+ return /* @__PURE__ */ jsxs31(
4856
5798
  DropdownMenuPrimitive.CheckboxItem,
4857
5799
  {
4858
5800
  "data-slot": "dropdown-menu-checkbox-item",
@@ -4868,7 +5810,7 @@ function DropdownMenuCheckboxItem({
4868
5810
  checked,
4869
5811
  ...props,
4870
5812
  children: [
4871
- /* @__PURE__ */ jsx27("span", { className: "pointer-events-none absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx27(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx27(CheckIcon, { size: 16 }) }) }),
5813
+ /* @__PURE__ */ jsx32("span", { className: "pointer-events-none absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx32(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx32(CheckIcon, { size: 16 }) }) }),
4872
5814
  children
4873
5815
  ]
4874
5816
  }
@@ -4877,7 +5819,7 @@ function DropdownMenuCheckboxItem({
4877
5819
  function DropdownMenuRadioGroup({
4878
5820
  ...props
4879
5821
  }) {
4880
- return /* @__PURE__ */ jsx27(
5822
+ return /* @__PURE__ */ jsx32(
4881
5823
  DropdownMenuPrimitive.RadioGroup,
4882
5824
  {
4883
5825
  "data-slot": "dropdown-menu-radio-group",
@@ -4890,7 +5832,7 @@ function DropdownMenuRadioItem({
4890
5832
  children,
4891
5833
  ...props
4892
5834
  }) {
4893
- return /* @__PURE__ */ jsxs26(
5835
+ return /* @__PURE__ */ jsxs31(
4894
5836
  DropdownMenuPrimitive.RadioItem,
4895
5837
  {
4896
5838
  "data-slot": "dropdown-menu-radio-item",
@@ -4905,7 +5847,7 @@ function DropdownMenuRadioItem({
4905
5847
  ),
4906
5848
  ...props,
4907
5849
  children: [
4908
- /* @__PURE__ */ jsx27("span", { className: "pointer-events-none absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx27(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx27(CircleIcon, { size: 8, className: "fill-current" }) }) }),
5850
+ /* @__PURE__ */ jsx32("span", { className: "pointer-events-none absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx32(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx32(CircleIcon, { size: 8, className: "fill-current" }) }) }),
4909
5851
  children
4910
5852
  ]
4911
5853
  }
@@ -4916,7 +5858,7 @@ function DropdownMenuLabel({
4916
5858
  inset,
4917
5859
  ...props
4918
5860
  }) {
4919
- return /* @__PURE__ */ jsx27(
5861
+ return /* @__PURE__ */ jsx32(
4920
5862
  DropdownMenuPrimitive.Label,
4921
5863
  {
4922
5864
  "data-slot": "dropdown-menu-label",
@@ -4933,7 +5875,7 @@ function DropdownMenuSeparator({
4933
5875
  className,
4934
5876
  ...props
4935
5877
  }) {
4936
- return /* @__PURE__ */ jsx27(
5878
+ return /* @__PURE__ */ jsx32(
4937
5879
  DropdownMenuPrimitive.Separator,
4938
5880
  {
4939
5881
  "data-slot": "dropdown-menu-separator",
@@ -4946,7 +5888,7 @@ function DropdownMenuShortcut({
4946
5888
  className,
4947
5889
  ...props
4948
5890
  }) {
4949
- return /* @__PURE__ */ jsx27(
5891
+ return /* @__PURE__ */ jsx32(
4950
5892
  "span",
4951
5893
  {
4952
5894
  "data-slot": "dropdown-menu-shortcut",
@@ -4961,7 +5903,7 @@ function DropdownMenuShortcut({
4961
5903
  function DropdownMenuSub({
4962
5904
  ...props
4963
5905
  }) {
4964
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
5906
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
4965
5907
  }
4966
5908
  function DropdownMenuSubTrigger({
4967
5909
  className,
@@ -4969,7 +5911,7 @@ function DropdownMenuSubTrigger({
4969
5911
  children,
4970
5912
  ...props
4971
5913
  }) {
4972
- return /* @__PURE__ */ jsxs26(
5914
+ return /* @__PURE__ */ jsxs31(
4973
5915
  DropdownMenuPrimitive.SubTrigger,
4974
5916
  {
4975
5917
  "data-slot": "dropdown-menu-sub-trigger",
@@ -4986,7 +5928,7 @@ function DropdownMenuSubTrigger({
4986
5928
  ...props,
4987
5929
  children: [
4988
5930
  children,
4989
- /* @__PURE__ */ jsx27(ChevronRightIcon, { className: "ml-auto", size: 16 })
5931
+ /* @__PURE__ */ jsx32(ChevronRightIcon, { className: "ml-auto", size: 16 })
4990
5932
  ]
4991
5933
  }
4992
5934
  );
@@ -4995,7 +5937,7 @@ function DropdownMenuSubContent({
4995
5937
  className,
4996
5938
  ...props
4997
5939
  }) {
4998
- return /* @__PURE__ */ jsx27(
5940
+ return /* @__PURE__ */ jsx32(
4999
5941
  DropdownMenuPrimitive.SubContent,
5000
5942
  {
5001
5943
  "data-slot": "dropdown-menu-sub-content",
@@ -5015,7 +5957,7 @@ function DropdownMenuSubContent({
5015
5957
  }
5016
5958
 
5017
5959
  // src/components/ui/context-menu.tsx
5018
- import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
5960
+ import { jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
5019
5961
  function ContextMenu({
5020
5962
  open,
5021
5963
  onOpenChange,
@@ -5026,8 +5968,8 @@ function ContextMenu({
5026
5968
  if (!position) {
5027
5969
  return null;
5028
5970
  }
5029
- return /* @__PURE__ */ jsxs27(DropdownMenu, { open, onOpenChange, modal: false, children: [
5030
- /* @__PURE__ */ jsx28(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(
5971
+ return /* @__PURE__ */ jsxs32(DropdownMenu, { open, onOpenChange, modal: false, children: [
5972
+ /* @__PURE__ */ jsx33(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx33(
5031
5973
  "span",
5032
5974
  {
5033
5975
  "aria-hidden": "true",
@@ -5041,18 +5983,18 @@ function ContextMenu({
5041
5983
  }
5042
5984
  }
5043
5985
  ) }),
5044
- /* @__PURE__ */ jsx28(DropdownMenuContent, { ...contentProps, children })
5986
+ /* @__PURE__ */ jsx33(DropdownMenuContent, { ...contentProps, children })
5045
5987
  ] });
5046
5988
  }
5047
5989
 
5048
5990
  // src/components/ui/bulk-action-bar.tsx
5049
- import { X as X2 } from "lucide-react";
5050
- import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
5991
+ import { X as X3 } from "lucide-react";
5992
+ import { jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
5051
5993
  function ActionButton({ action }) {
5052
5994
  const danger = action.variant === "destructive";
5053
5995
  const off = action.disabled;
5054
5996
  const Icon = action.icon;
5055
- return /* @__PURE__ */ jsxs28(
5997
+ return /* @__PURE__ */ jsxs33(
5056
5998
  "button",
5057
5999
  {
5058
6000
  type: "button",
@@ -5079,7 +6021,7 @@ function ActionButton({ action }) {
5079
6021
  whiteSpace: "nowrap"
5080
6022
  },
5081
6023
  children: [
5082
- Icon ? /* @__PURE__ */ jsx29(
6024
+ Icon ? /* @__PURE__ */ jsx34(
5083
6025
  Icon,
5084
6026
  {
5085
6027
  "aria-hidden": "true",
@@ -5094,7 +6036,7 @@ function ActionButton({ action }) {
5094
6036
  );
5095
6037
  }
5096
6038
  function Divider() {
5097
- return /* @__PURE__ */ jsx29(
6039
+ return /* @__PURE__ */ jsx34(
5098
6040
  "span",
5099
6041
  {
5100
6042
  "aria-hidden": "true",
@@ -5109,7 +6051,7 @@ function Divider() {
5109
6051
  );
5110
6052
  }
5111
6053
  function ClearButton({ onClear }) {
5112
- return /* @__PURE__ */ jsx29(
6054
+ return /* @__PURE__ */ jsx34(
5113
6055
  "button",
5114
6056
  {
5115
6057
  type: "button",
@@ -5131,7 +6073,7 @@ function ClearButton({ onClear }) {
5131
6073
  justifyContent: "center",
5132
6074
  borderRadius: "var(--radius-sm)"
5133
6075
  },
5134
- children: /* @__PURE__ */ jsx29(X2, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" })
6076
+ children: /* @__PURE__ */ jsx34(X3, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" })
5135
6077
  }
5136
6078
  );
5137
6079
  }
@@ -5147,7 +6089,7 @@ function BulkActionBar({
5147
6089
  if (count === 0 && emptyHint === void 0) {
5148
6090
  return null;
5149
6091
  }
5150
- return /* @__PURE__ */ jsxs28(
6092
+ return /* @__PURE__ */ jsxs33(
5151
6093
  "div",
5152
6094
  {
5153
6095
  role: "toolbar",
@@ -5179,7 +6121,7 @@ function BulkActionBar({
5179
6121
  },
5180
6122
  ...props,
5181
6123
  children: [
5182
- /* @__PURE__ */ jsx29(
6124
+ /* @__PURE__ */ jsx34(
5183
6125
  "span",
5184
6126
  {
5185
6127
  "data-slot": "bulk-action-bar-count",
@@ -5196,8 +6138,8 @@ function BulkActionBar({
5196
6138
  children: count > 0 ? `${count.toLocaleString("ko-KR")}\uAC1C \uC120\uD0DD\uB428` : emptyHint
5197
6139
  }
5198
6140
  ),
5199
- count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx29(Divider, {}) : null,
5200
- /* @__PURE__ */ jsx29(
6141
+ count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx34(Divider, {}) : null,
6142
+ /* @__PURE__ */ jsx34(
5201
6143
  "div",
5202
6144
  {
5203
6145
  "data-slot": "bulk-action-bar-actions",
@@ -5209,19 +6151,19 @@ function BulkActionBar({
5209
6151
  justifyContent: "flex-end",
5210
6152
  gap: 2
5211
6153
  },
5212
- children: actions.map((action) => /* @__PURE__ */ jsx29(ActionButton, { action }, action.key))
6154
+ children: actions.map((action) => /* @__PURE__ */ jsx34(ActionButton, { action }, action.key))
5213
6155
  }
5214
6156
  ),
5215
- /* @__PURE__ */ jsx29(Divider, {}),
5216
- /* @__PURE__ */ jsx29(ClearButton, { onClear })
6157
+ /* @__PURE__ */ jsx34(Divider, {}),
6158
+ /* @__PURE__ */ jsx34(ClearButton, { onClear })
5217
6159
  ]
5218
6160
  }
5219
6161
  );
5220
6162
  }
5221
6163
 
5222
6164
  // src/components/ui/confirm-dialog.tsx
5223
- import * as React25 from "react";
5224
- import { Fragment as Fragment7, jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
6165
+ import * as React28 from "react";
6166
+ import { Fragment as Fragment8, jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
5225
6167
  var confirmDialogContentClassName = cn(
5226
6168
  "fixed left-1/2 top-1/2 z-[var(--z-modal)]",
5227
6169
  "-translate-x-1/2 -translate-y-1/2",
@@ -5249,10 +6191,10 @@ function ConfirmDialog({
5249
6191
  onConfirm,
5250
6192
  loading = false
5251
6193
  }) {
5252
- const [pending, setPending] = React25.useState(false);
5253
- const busyRef = React25.useRef(false);
6194
+ const [pending, setPending] = React28.useState(false);
6195
+ const busyRef = React28.useRef(false);
5254
6196
  const isBusy = loading || pending;
5255
- const handleOpenChange = React25.useCallback(
6197
+ const handleOpenChange = React28.useCallback(
5256
6198
  (nextOpen) => {
5257
6199
  if (!nextOpen && isBusy) {
5258
6200
  return;
@@ -5261,7 +6203,7 @@ function ConfirmDialog({
5261
6203
  },
5262
6204
  [isBusy, onOpenChange]
5263
6205
  );
5264
- const handleConfirm = React25.useCallback(async () => {
6206
+ const handleConfirm = React28.useCallback(async () => {
5265
6207
  if (busyRef.current || loading) {
5266
6208
  return;
5267
6209
  }
@@ -5275,9 +6217,9 @@ function ConfirmDialog({
5275
6217
  setPending(false);
5276
6218
  }
5277
6219
  }, [loading, onConfirm, onOpenChange]);
5278
- const dialogBody = /* @__PURE__ */ jsxs29(Fragment7, { children: [
5279
- /* @__PURE__ */ jsx30("div", { className: "flex items-start justify-between gap-[var(--space-4)]", children: /* @__PURE__ */ jsxs29("div", { className: "min-w-0 space-y-[var(--space-2)]", children: [
5280
- /* @__PURE__ */ jsx30(
6220
+ const dialogBody = /* @__PURE__ */ jsxs34(Fragment8, { children: [
6221
+ /* @__PURE__ */ jsx35("div", { className: "flex items-start justify-between gap-[var(--space-4)]", children: /* @__PURE__ */ jsxs34("div", { className: "min-w-0 space-y-[var(--space-2)]", children: [
6222
+ /* @__PURE__ */ jsx35(
5281
6223
  DialogTitle,
5282
6224
  {
5283
6225
  "data-slot": "dialog-title",
@@ -5285,571 +6227,139 @@ function ConfirmDialog({
5285
6227
  children: title
5286
6228
  }
5287
6229
  ),
5288
- description ? /* @__PURE__ */ jsx30(
6230
+ description ? /* @__PURE__ */ jsx35(
5289
6231
  DialogDescription,
5290
6232
  {
5291
6233
  "data-slot": "dialog-description",
5292
6234
  className: confirmDialogDescriptionClassName,
5293
6235
  children: description
5294
- }
5295
- ) : null
5296
- ] }) }),
5297
- /* @__PURE__ */ jsxs29(
5298
- "div",
5299
- {
5300
- "data-slot": "dialog-footer",
5301
- className: confirmDialogFooterClassName,
5302
- children: [
5303
- /* @__PURE__ */ jsx30(Button, { variant: "secondary", disabled: isBusy, onClick: () => handleOpenChange(false), children: cancelLabel }),
5304
- /* @__PURE__ */ jsx30(
5305
- Button,
5306
- {
5307
- variant: tone === "destructive" ? "destructive" : "primary",
5308
- loading: isBusy,
5309
- onClick: handleConfirm,
5310
- children: confirmLabel
5311
- }
5312
- )
5313
- ]
5314
- }
5315
- )
5316
- ] });
5317
- return /* @__PURE__ */ jsx30(Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs29(DialogPortal, { children: [
5318
- /* @__PURE__ */ jsx30(DialogOverlay, {}),
5319
- /* @__PURE__ */ jsx30(DialogRawContent, { role: "alertdialog", "data-slot": "dialog-content", className: confirmDialogContentClassName, children: dialogBody })
5320
- ] }) });
5321
- }
5322
-
5323
- // src/components/ui/separator.tsx
5324
- import { Separator as SeparatorPrimitive } from "radix-ui";
5325
- import { jsx as jsx31 } from "react/jsx-runtime";
5326
- function Separator2({
5327
- className,
5328
- orientation = "horizontal",
5329
- decorative = true,
5330
- ...props
5331
- }) {
5332
- return /* @__PURE__ */ jsx31(
5333
- SeparatorPrimitive.Root,
5334
- {
5335
- "data-slot": "separator",
5336
- decorative,
5337
- orientation,
5338
- className: cn(
5339
- "shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
5340
- className
5341
- ),
5342
- ...props
5343
- }
5344
- );
5345
- }
5346
-
5347
- // src/components/ui/avatar.tsx
5348
- import { Avatar as AvatarPrimitive } from "radix-ui";
5349
- import { jsx as jsx32 } from "react/jsx-runtime";
5350
- function Avatar({
5351
- className,
5352
- size = "md",
5353
- ...props
5354
- }) {
5355
- return /* @__PURE__ */ jsx32(
5356
- AvatarPrimitive.Root,
5357
- {
5358
- "data-slot": "avatar",
5359
- "data-size": size,
5360
- className: cn(
5361
- "group/avatar relative flex shrink-0 overflow-hidden rounded-full select-none",
5362
- "border border-[var(--border-subtle)] bg-[var(--bg-raised)] text-text-secondary",
5363
- "h-9 w-9",
5364
- "data-[size=sm]:h-8 data-[size=sm]:w-8",
5365
- "data-[size=lg]:h-11 data-[size=lg]:w-11",
5366
- className
5367
- ),
5368
- ...props
5369
- }
5370
- );
5371
- }
5372
- function AvatarImage({
5373
- className,
5374
- ...props
5375
- }) {
5376
- return /* @__PURE__ */ jsx32(
5377
- AvatarPrimitive.Image,
5378
- {
5379
- "data-slot": "avatar-image",
5380
- className: cn("aspect-square h-full w-full object-cover", className),
5381
- ...props
5382
- }
5383
- );
5384
- }
5385
- function getAvatarFallbackText(name) {
5386
- const trimmedName = name.trim();
5387
- if (!trimmedName) return null;
5388
- const segmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter("ko", { granularity: "grapheme" }) : null;
5389
- if (segmenter) {
5390
- return segmenter.segment(trimmedName)[Symbol.iterator]().next().value?.segment ?? null;
5391
- }
5392
- return Array.from(trimmedName)[0] ?? null;
5393
- }
5394
- function AvatarFallback({
5395
- className,
5396
- children,
5397
- name,
5398
- ...props
5399
- }) {
5400
- const fallbackText = children ?? (name ? getAvatarFallbackText(name) : null);
5401
- return /* @__PURE__ */ jsx32(
5402
- AvatarPrimitive.Fallback,
5403
- {
5404
- "data-slot": "avatar-fallback",
5405
- className: cn(
5406
- "flex h-full w-full items-center justify-center rounded-full",
5407
- "bg-[var(--bg-raised)] text-sm font-semibold text-text-secondary",
5408
- "font-[family-name:var(--font-display)]",
5409
- "group-data-[size=sm]/avatar:text-xs",
5410
- className
5411
- ),
5412
- ...props,
5413
- children: fallbackText
5414
- }
5415
- );
5416
- }
5417
-
5418
- // src/components/ui/sheet.tsx
5419
- import { XIcon as XIcon2 } from "lucide-react";
5420
- import { Dialog as SheetPrimitive } from "radix-ui";
5421
- import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
5422
- var defaultSheetMotionConfig = {
5423
- type: "slide",
5424
- duration: 300,
5425
- easing: "decel"
5426
- };
5427
- var sheetMotionEasingValue = {
5428
- standard: "var(--ease-standard)",
5429
- // decel/sharp have no canonical --ease-* token; these compat beziers are frozen
5430
- // specifically to back this public `easing` prop (see tokens/compat.css).
5431
- decel: "var(--easing-decel)",
5432
- accel: "var(--ease-in)",
5433
- sharp: "var(--easing-sharp)",
5434
- bounce: "var(--ease-out)"
5435
- };
5436
- function resolveSheetMotionConfig(motion) {
5437
- if (motion === false) return false;
5438
- return {
5439
- ...defaultSheetMotionConfig,
5440
- ...motion
5441
- };
5442
- }
5443
- function formatSheetMotionDuration(duration) {
5444
- return typeof duration === "number" ? `${duration}ms` : duration;
5445
- }
5446
- function getSheetMotionStyle(motionConfig, style) {
5447
- if (!motionConfig) return style;
5448
- return {
5449
- ...style,
5450
- "--sheet-motion-duration": formatSheetMotionDuration(motionConfig.duration),
5451
- "--sheet-motion-easing": sheetMotionEasingValue[motionConfig.easing]
5452
- };
5453
- }
5454
- function Sheet({ ...props }) {
5455
- return /* @__PURE__ */ jsx33(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
5456
- }
5457
- function SheetTrigger({
5458
- ...props
5459
- }) {
5460
- return /* @__PURE__ */ jsx33(SheetPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
5461
- }
5462
- function SheetClose({
5463
- ...props
5464
- }) {
5465
- return /* @__PURE__ */ jsx33(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
5466
- }
5467
- function SheetPortal({
5468
- ...props
5469
- }) {
5470
- return /* @__PURE__ */ jsx33(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
5471
- }
5472
- function SheetOverlay({
5473
- className,
5474
- motion,
5475
- style,
5476
- ...props
5477
- }) {
5478
- const motionConfig = resolveSheetMotionConfig(motion);
5479
- return /* @__PURE__ */ jsx33(
5480
- SheetPrimitive.Overlay,
5481
- {
5482
- "data-slot": "sheet-overlay",
5483
- className: cn(
5484
- "fixed inset-0 z-[var(--z-overlay)] bg-[var(--scrim)]",
5485
- motionConfig && cn(
5486
- "transition-opacity motion-reduce:transition-none",
5487
- "duration-[var(--sheet-motion-duration)]",
5488
- "data-[state=closed]:opacity-0 data-[state=open]:opacity-100",
5489
- "data-[state=open]:animate-[olun-sheet-fade-in_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
5490
- "data-[state=closed]:animate-[olun-sheet-fade-out_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
5491
- "motion-reduce:animate-none"
5492
- ),
5493
- className
5494
- ),
5495
- style: getSheetMotionStyle(motionConfig, style),
5496
- ...props
5497
- }
5498
- );
5499
- }
5500
- function SheetContent({
5501
- className,
5502
- children,
5503
- side = "right",
5504
- mobileSide,
5505
- motion,
5506
- showCloseButton = false,
5507
- style,
5508
- ...props
5509
- }) {
5510
- const motionConfig = resolveSheetMotionConfig(motion);
5511
- const hasSlideMotion = motionConfig && motionConfig.type === "slide";
5512
- return /* @__PURE__ */ jsxs30(SheetPortal, { children: [
5513
- /* @__PURE__ */ jsx33(SheetOverlay, { motion: motionConfig }),
5514
- /* @__PURE__ */ jsxs30(
5515
- SheetPrimitive.Content,
6236
+ }
6237
+ ) : null
6238
+ ] }) }),
6239
+ /* @__PURE__ */ jsxs34(
6240
+ "div",
5516
6241
  {
5517
- "data-slot": "sheet-content",
5518
- className: cn(
5519
- "fixed z-[var(--z-modal)] flex flex-col gap-4 border-[var(--border)] bg-[var(--bg-surface)] shadow-[var(--shadow-4)]",
5520
- motionConfig && cn(
5521
- "motion-reduce:animate-none",
5522
- motionConfig.type === "fade" && "data-[state=open]:animate-[olun-sheet-fade-in_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-fade-out_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
5523
- ),
5524
- side === "right" && cn(
5525
- "inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
5526
- hasSlideMotion && "data-[state=open]:animate-[olun-sheet-in-from-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-out-to-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
5527
- ),
5528
- side === "left" && cn(
5529
- "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
5530
- hasSlideMotion && "data-[state=open]:animate-[olun-sheet-in-from-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-out-to-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
5531
- ),
5532
- side === "top" && cn(
5533
- "inset-x-0 top-0 h-auto border-b",
5534
- hasSlideMotion && "data-[state=open]:animate-[olun-sheet-in-from-top_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-out-to-top_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
5535
- ),
5536
- side === "bottom" && cn(
5537
- "inset-x-0 bottom-0 h-auto border-t",
5538
- hasSlideMotion && "data-[state=open]:animate-[olun-sheet-in-from-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] data-[state=closed]:animate-[olun-sheet-out-to-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
5539
- ),
5540
- mobileSide === "right" && cn(
5541
- "max-[899px]:inset-y-0 max-[899px]:right-0 max-[899px]:left-auto max-[899px]:h-full max-[899px]:w-3/4 max-[899px]:border-l max-[899px]:border-t-0 max-[899px]:rounded-none",
5542
- hasSlideMotion && "max-[899px]:data-[state=open]:animate-[olun-sheet-in-from-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] max-[899px]:data-[state=closed]:animate-[olun-sheet-out-to-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
5543
- ),
5544
- mobileSide === "left" && cn(
5545
- "max-[899px]:inset-y-0 max-[899px]:left-0 max-[899px]:right-auto max-[899px]:h-full max-[899px]:w-3/4 max-[899px]:border-r max-[899px]:border-t-0 max-[899px]:rounded-none",
5546
- hasSlideMotion && "max-[899px]:data-[state=open]:animate-[olun-sheet-in-from-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] max-[899px]:data-[state=closed]:animate-[olun-sheet-out-to-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
5547
- ),
5548
- mobileSide === "top" && cn(
5549
- // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap (see mobileSide bottom).
5550
- "max-[899px]:inset-x-0 max-[899px]:top-0 max-[899px]:bottom-auto max-[899px]:h-auto max-[899px]:w-full max-[899px]:max-w-none! max-[899px]:border-b max-[899px]:border-l-0 max-[899px]:rounded-none",
5551
- hasSlideMotion && "max-[899px]:data-[state=open]:animate-[olun-sheet-in-from-top_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] max-[899px]:data-[state=closed]:animate-[olun-sheet-out-to-top_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
5552
- ),
5553
- mobileSide === "bottom" && cn(
5554
- // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap so the bottom sheet
5555
- // spans the full viewport width across the whole < 900px band (not capped to 24rem).
5556
- "max-[899px]:inset-x-0 max-[899px]:bottom-0 max-[899px]:top-auto max-[899px]:h-auto max-[899px]:w-full max-[899px]:max-w-none! max-[899px]:border-t max-[899px]:border-l-0 max-[899px]:rounded-none",
5557
- hasSlideMotion && "max-[899px]:data-[state=open]:animate-[olun-sheet-in-from-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] max-[899px]:data-[state=closed]:animate-[olun-sheet-out-to-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
5558
- ),
5559
- className
5560
- ),
5561
- style: getSheetMotionStyle(motionConfig, style),
5562
- ...props,
6242
+ "data-slot": "dialog-footer",
6243
+ className: confirmDialogFooterClassName,
5563
6244
  children: [
5564
- children,
5565
- showCloseButton && /* @__PURE__ */ jsxs30(SheetPrimitive.Close, { className: "absolute top-4 right-4 cursor-pointer rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
5566
- /* @__PURE__ */ jsx33(XIcon2, { className: "size-[16px]" }),
5567
- /* @__PURE__ */ jsx33("span", { className: "sr-only", children: "Close" })
5568
- ] })
6245
+ /* @__PURE__ */ jsx35(Button, { variant: "secondary", disabled: isBusy, onClick: () => handleOpenChange(false), children: cancelLabel }),
6246
+ /* @__PURE__ */ jsx35(
6247
+ Button,
6248
+ {
6249
+ variant: tone === "destructive" ? "destructive" : "primary",
6250
+ loading: isBusy,
6251
+ onClick: handleConfirm,
6252
+ children: confirmLabel
6253
+ }
6254
+ )
5569
6255
  ]
5570
6256
  }
5571
6257
  )
5572
6258
  ] });
6259
+ return /* @__PURE__ */ jsx35(Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs34(DialogPortal, { children: [
6260
+ /* @__PURE__ */ jsx35(DialogOverlay, {}),
6261
+ /* @__PURE__ */ jsx35(DialogRawContent, { role: "alertdialog", "data-slot": "dialog-content", className: confirmDialogContentClassName, children: dialogBody })
6262
+ ] }) });
5573
6263
  }
5574
- function SheetBody({ className, ...props }) {
5575
- return /* @__PURE__ */ jsx33(
5576
- "div",
5577
- {
5578
- "data-slot": "sheet-body",
5579
- className: cn("flex-1 overflow-y-auto p-4", className),
5580
- ...props
5581
- }
5582
- );
5583
- }
5584
- function SheetHeader({ className, ...props }) {
5585
- return /* @__PURE__ */ jsx33(
5586
- "div",
5587
- {
5588
- "data-slot": "sheet-header",
5589
- className: cn("flex flex-col gap-1.5 p-4", className),
5590
- ...props
5591
- }
5592
- );
5593
- }
5594
- function SheetFooter({ className, ...props }) {
5595
- return /* @__PURE__ */ jsx33(
5596
- "div",
5597
- {
5598
- "data-slot": "sheet-footer",
5599
- className: cn("mt-auto flex flex-col gap-2 p-4", className),
5600
- ...props
5601
- }
5602
- );
5603
- }
5604
- function SheetTitle({
6264
+
6265
+ // src/components/ui/separator.tsx
6266
+ import { Separator as SeparatorPrimitive } from "radix-ui";
6267
+ import { jsx as jsx36 } from "react/jsx-runtime";
6268
+ function Separator2({
5605
6269
  className,
6270
+ orientation = "horizontal",
6271
+ decorative = true,
5606
6272
  ...props
5607
6273
  }) {
5608
- return /* @__PURE__ */ jsx33(
5609
- SheetPrimitive.Title,
6274
+ return /* @__PURE__ */ jsx36(
6275
+ SeparatorPrimitive.Root,
5610
6276
  {
5611
- "data-slot": "sheet-title",
5612
- className: cn("font-semibold text-foreground", className),
6277
+ "data-slot": "separator",
6278
+ decorative,
6279
+ orientation,
6280
+ className: cn(
6281
+ "shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
6282
+ className
6283
+ ),
5613
6284
  ...props
5614
6285
  }
5615
6286
  );
5616
6287
  }
5617
- function SheetDescription({
6288
+
6289
+ // src/components/ui/avatar.tsx
6290
+ import { Avatar as AvatarPrimitive } from "radix-ui";
6291
+ import { jsx as jsx37 } from "react/jsx-runtime";
6292
+ function Avatar({
5618
6293
  className,
6294
+ size = "md",
5619
6295
  ...props
5620
6296
  }) {
5621
- return /* @__PURE__ */ jsx33(
5622
- SheetPrimitive.Description,
5623
- {
5624
- "data-slot": "sheet-description",
5625
- className: cn("text-sm text-muted-foreground", className),
5626
- ...props
5627
- }
5628
- );
5629
- }
5630
-
5631
- // src/components/ui/sheet-drawer.tsx
5632
- import { Maximize2Icon, Minimize2Icon, XIcon as XIcon3 } from "lucide-react";
5633
- import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
5634
- var sheetDrawerContentClassName = cn(
5635
- "gap-0 p-0",
5636
- "bg-[var(--bg-surface)] text-foreground",
5637
- "border-[var(--border)] shadow-[var(--shadow-4)]",
5638
- "min-[900px]:w-[480px] min-[900px]:max-w-[480px]",
5639
- "max-[899px]:h-[min(85dvh,720px)] max-[899px]:max-h-[85dvh] max-[899px]:w-full max-[899px]:max-w-none",
5640
- "max-[899px]:rounded-t-[var(--radius-lg)]"
5641
- );
5642
- var sheetDrawerWideContentClassName = "min-[900px]:w-[720px] min-[900px]:max-w-[720px]";
5643
- var sheetDrawerFullContentClassName = cn(
5644
- "min-[900px]:w-[calc(100vw_-_var(--space-8))] min-[900px]:max-w-[calc(100vw_-_var(--space-8))]",
5645
- "max-[899px]:h-[100dvh] max-[899px]:max-h-[100dvh] max-[899px]:rounded-none"
5646
- );
5647
- var sheetDrawerHeaderClassName = cn(
5648
- "flex items-start justify-between gap-[var(--space-4)]",
5649
- "border-b border-[var(--border)] px-[var(--space-6)] py-[var(--space-6)]"
5650
- );
5651
- var sheetDrawerHeaderTextClassName = "flex min-w-0 flex-1 flex-col gap-[var(--space-2)]";
5652
- var sheetDrawerCaptionClassName = "flex flex-wrap items-center gap-[var(--space-2)]";
5653
- var sheetDrawerTitleClassName = "text-[18px] font-bold leading-snug text-foreground";
5654
- var sheetDrawerDescriptionClassName = "break-keep text-[14px] leading-normal text-text-secondary";
5655
- var sheetDrawerCloseButtonClassName = cn(
5656
- "flex size-[32px] shrink-0 cursor-pointer items-center justify-center",
5657
- "rounded-[var(--radius-sm)] text-text-tertiary transition-colors",
5658
- "hover:bg-[var(--action-hover)] hover:text-foreground",
5659
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2"
5660
- );
5661
- var sheetDrawerHeaderActionsClassName = cn(
5662
- "flex shrink-0 items-center gap-[var(--space-1)]"
5663
- );
5664
- var sheetDrawerExpandButtonClassName = cn(
5665
- "inline-flex cursor-pointer items-center justify-center gap-[var(--space-1)]",
5666
- "rounded-[var(--radius-sm)] text-text-tertiary transition-colors",
5667
- "hover:bg-[var(--action-hover)] hover:text-foreground",
5668
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2",
5669
- "h-[32px] px-[var(--space-2)]"
5670
- );
5671
- var sheetDrawerBodyClassName = cn(
5672
- "min-h-0 flex-1 overflow-y-auto",
5673
- "px-[var(--space-6)] py-[var(--space-6)]"
5674
- );
5675
- var sheetDrawerFooterClassName = cn(
5676
- "border-t border-[var(--border)] px-[var(--space-6)] py-[var(--space-4)]",
5677
- "flex justify-end gap-[var(--space-2)]"
5678
- );
5679
- function SheetDrawer({
5680
- open,
5681
- onOpenChange,
5682
- caption,
5683
- title,
5684
- description,
5685
- children,
5686
- expandHref,
5687
- onExpand,
5688
- expandLabel = "\uD06C\uAC8C \uBCF4\uAE30",
5689
- expanded = false,
5690
- onExpandedChange,
5691
- collapseLabel = "\uC791\uAC8C \uBCF4\uAE30",
5692
- footer,
5693
- width = "default",
5694
- motion,
5695
- closeLabel = "\uB2EB\uAE30"
5696
- }) {
5697
- const hasExpandedToggle = typeof onExpandedChange === "function";
5698
- const showExpandAction = Boolean(hasExpandedToggle || expandHref || onExpand);
5699
- const resolvedWidth = expanded ? "full" : width;
5700
- const resolvedExpandLabel = hasExpandedToggle && expanded ? collapseLabel : expandLabel;
5701
- const ExpandActionIcon = hasExpandedToggle && expanded ? Minimize2Icon : Maximize2Icon;
5702
- return /* @__PURE__ */ jsx34(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs31(
5703
- SheetContent,
6297
+ return /* @__PURE__ */ jsx37(
6298
+ AvatarPrimitive.Root,
5704
6299
  {
5705
- "data-slot": "sheet-drawer-content",
5706
- side: "right",
5707
- mobileSide: "bottom",
5708
- motion,
5709
- showCloseButton: false,
5710
- className: cn(
5711
- sheetDrawerContentClassName,
5712
- resolvedWidth === "wide" && sheetDrawerWideContentClassName,
5713
- resolvedWidth === "full" && sheetDrawerFullContentClassName
5714
- ),
5715
- children: [
5716
- /* @__PURE__ */ jsxs31("div", { "data-slot": "sheet-drawer-header", className: sheetDrawerHeaderClassName, children: [
5717
- /* @__PURE__ */ jsxs31("div", { className: sheetDrawerHeaderTextClassName, children: [
5718
- caption ? /* @__PURE__ */ jsx34("div", { "data-slot": "sheet-drawer-caption", className: sheetDrawerCaptionClassName, children: caption }) : null,
5719
- /* @__PURE__ */ jsx34(SheetTitle, { "data-slot": "sheet-drawer-title", className: sheetDrawerTitleClassName, children: title }),
5720
- description ? /* @__PURE__ */ jsx34(
5721
- SheetDescription,
5722
- {
5723
- "data-slot": "sheet-drawer-description",
5724
- className: sheetDrawerDescriptionClassName,
5725
- children: description
5726
- }
5727
- ) : null
5728
- ] }),
5729
- /* @__PURE__ */ jsxs31("div", { "data-slot": "sheet-drawer-header-actions", className: sheetDrawerHeaderActionsClassName, children: [
5730
- showExpandAction ? hasExpandedToggle ? /* @__PURE__ */ jsxs31(
5731
- "button",
5732
- {
5733
- type: "button",
5734
- "aria-label": resolvedExpandLabel,
5735
- "aria-pressed": expanded,
5736
- "data-slot": "sheet-drawer-expand",
5737
- "data-expanded": expanded ? "true" : "false",
5738
- className: sheetDrawerExpandButtonClassName,
5739
- onClick: () => onExpandedChange(!expanded),
5740
- children: [
5741
- /* @__PURE__ */ jsx34(ExpandActionIcon, { className: "size-[16px]" }),
5742
- /* @__PURE__ */ jsx34("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: resolvedExpandLabel })
5743
- ]
5744
- }
5745
- ) : expandHref ? /* @__PURE__ */ jsxs31(
5746
- "a",
5747
- {
5748
- href: expandHref,
5749
- "aria-label": expandLabel,
5750
- "data-slot": "sheet-drawer-expand",
5751
- className: sheetDrawerExpandButtonClassName,
5752
- children: [
5753
- /* @__PURE__ */ jsx34(ExpandActionIcon, { className: "size-[16px]" }),
5754
- /* @__PURE__ */ jsx34("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
5755
- ]
5756
- }
5757
- ) : /* @__PURE__ */ jsxs31(
5758
- "button",
5759
- {
5760
- type: "button",
5761
- "aria-label": expandLabel,
5762
- "data-slot": "sheet-drawer-expand",
5763
- className: sheetDrawerExpandButtonClassName,
5764
- onClick: onExpand,
5765
- children: [
5766
- /* @__PURE__ */ jsx34(ExpandActionIcon, { className: "size-[16px]" }),
5767
- /* @__PURE__ */ jsx34("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
5768
- ]
5769
- }
5770
- ) : null,
5771
- /* @__PURE__ */ jsx34(
5772
- SheetClose,
5773
- {
5774
- "aria-label": closeLabel,
5775
- "data-slot": "sheet-drawer-close",
5776
- className: sheetDrawerCloseButtonClassName,
5777
- children: /* @__PURE__ */ jsx34(XIcon3, { className: "size-[16px]" })
5778
- }
5779
- )
5780
- ] })
5781
- ] }),
5782
- /* @__PURE__ */ jsx34("div", { "data-slot": "sheet-drawer-body", className: sheetDrawerBodyClassName, children }),
5783
- footer ? /* @__PURE__ */ jsx34("div", { "data-slot": "sheet-drawer-footer", className: sheetDrawerFooterClassName, children: footer }) : null
5784
- ]
6300
+ "data-slot": "avatar",
6301
+ "data-size": size,
6302
+ className: cn(
6303
+ "group/avatar relative flex shrink-0 overflow-hidden rounded-full select-none",
6304
+ "border border-[var(--border-subtle)] bg-[var(--bg-raised)] text-text-secondary",
6305
+ "h-9 w-9",
6306
+ "data-[size=sm]:h-8 data-[size=sm]:w-8",
6307
+ "data-[size=lg]:h-11 data-[size=lg]:w-11",
6308
+ className
6309
+ ),
6310
+ ...props
5785
6311
  }
5786
- ) });
6312
+ );
5787
6313
  }
5788
-
5789
- // src/components/ui/popover.tsx
5790
- import * as React26 from "react";
5791
- import { Popover as PopoverPrimitive } from "radix-ui";
5792
- import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
5793
- function Popover({ modal = false, ...props }) {
5794
- return /* @__PURE__ */ jsx35(PopoverPrimitive.Root, { modal, ...props });
6314
+ function AvatarImage({
6315
+ className,
6316
+ ...props
6317
+ }) {
6318
+ return /* @__PURE__ */ jsx37(
6319
+ AvatarPrimitive.Image,
6320
+ {
6321
+ "data-slot": "avatar-image",
6322
+ className: cn("aspect-square h-full w-full object-cover", className),
6323
+ ...props
6324
+ }
6325
+ );
5795
6326
  }
5796
- var popoverArrowClassName = "fill-[var(--bg-surface)] stroke-[var(--border)] [&>polygon]:[vector-effect:non-scaling-stroke]";
5797
- var PopoverTrigger = PopoverPrimitive.Trigger;
5798
- var PopoverAnchor = PopoverPrimitive.Anchor;
5799
- var PopoverClose = PopoverPrimitive.Close;
5800
- var PopoverContent = React26.forwardRef(({ className, align = "center", sideOffset = 8, collisionPadding = 8, showArrow = false, children, ...props }, ref) => /* @__PURE__ */ jsx35(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsxs32(
5801
- PopoverPrimitive.Content,
5802
- {
5803
- ref,
5804
- align,
5805
- sideOffset,
5806
- collisionPadding,
5807
- "data-slot": "popover-content",
5808
- className: cn(
5809
- "z-[var(--z-popover)] w-[260px] outline-none",
5810
- "rounded-[var(--radius-md)] border border-[var(--border)]",
5811
- "bg-[var(--bg-surface)] p-[var(--space-4)] text-foreground",
5812
- "shadow-[var(--shadow-4)]",
5813
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
5814
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
5815
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
5816
- "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
5817
- "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
5818
- "motion-reduce:animate-none",
5819
- className
5820
- ),
5821
- ...props,
5822
- children: [
5823
- children,
5824
- showArrow ? /* @__PURE__ */ jsx35(
5825
- PopoverPrimitive.Arrow,
5826
- {
5827
- "data-slot": "popover-arrow",
5828
- className: popoverArrowClassName,
5829
- width: 11,
5830
- height: 5
5831
- }
5832
- ) : null
5833
- ]
5834
- }
5835
- ) }));
5836
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
5837
- var PopoverArrow = React26.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx35(
5838
- PopoverPrimitive.Arrow,
5839
- {
5840
- ref,
5841
- "data-slot": "popover-arrow",
5842
- className: cn(popoverArrowClassName, className),
5843
- width: 11,
5844
- height: 5,
5845
- ...props
6327
+ function getAvatarFallbackText(name) {
6328
+ const trimmedName = name.trim();
6329
+ if (!trimmedName) return null;
6330
+ const segmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter("ko", { granularity: "grapheme" }) : null;
6331
+ if (segmenter) {
6332
+ return segmenter.segment(trimmedName)[Symbol.iterator]().next().value?.segment ?? null;
5846
6333
  }
5847
- ));
5848
- PopoverArrow.displayName = PopoverPrimitive.Arrow.displayName;
6334
+ return Array.from(trimmedName)[0] ?? null;
6335
+ }
6336
+ function AvatarFallback({
6337
+ className,
6338
+ children,
6339
+ name,
6340
+ ...props
6341
+ }) {
6342
+ const fallbackText = children ?? (name ? getAvatarFallbackText(name) : null);
6343
+ return /* @__PURE__ */ jsx37(
6344
+ AvatarPrimitive.Fallback,
6345
+ {
6346
+ "data-slot": "avatar-fallback",
6347
+ className: cn(
6348
+ "flex h-full w-full items-center justify-center rounded-full",
6349
+ "bg-[var(--bg-raised)] text-sm font-semibold text-text-secondary",
6350
+ "font-[family-name:var(--font-display)]",
6351
+ "group-data-[size=sm]/avatar:text-xs",
6352
+ className
6353
+ ),
6354
+ ...props,
6355
+ children: fallbackText
6356
+ }
6357
+ );
6358
+ }
5849
6359
 
5850
6360
  // src/components/ui/badge.tsx
5851
- import * as React27 from "react";
5852
- import { jsx as jsx36, jsxs as jsxs33 } from "react/jsx-runtime";
6361
+ import * as React29 from "react";
6362
+ import { jsx as jsx38, jsxs as jsxs35 } from "react/jsx-runtime";
5853
6363
  var DOT = {
5854
6364
  error: "var(--semantic-error-fg)",
5855
6365
  warning: "var(--semantic-warning-fg)",
@@ -5858,8 +6368,8 @@ var DOT = {
5858
6368
  neutral: "var(--text-tertiary)",
5859
6369
  brand: "var(--accent-pop)"
5860
6370
  };
5861
- var Badge = React27.forwardRef(
5862
- ({ tone = "neutral", className, children, ...props }, ref) => /* @__PURE__ */ jsxs33(
6371
+ var Badge = React29.forwardRef(
6372
+ ({ tone = "neutral", className, children, ...props }, ref) => /* @__PURE__ */ jsxs35(
5863
6373
  "span",
5864
6374
  {
5865
6375
  ref,
@@ -5873,7 +6383,7 @@ var Badge = React27.forwardRef(
5873
6383
  ),
5874
6384
  ...props,
5875
6385
  children: [
5876
- /* @__PURE__ */ jsx36(
6386
+ /* @__PURE__ */ jsx38(
5877
6387
  "span",
5878
6388
  {
5879
6389
  "aria-hidden": "true",
@@ -5890,8 +6400,8 @@ var Badge = React27.forwardRef(
5890
6400
  Badge.displayName = "Badge";
5891
6401
 
5892
6402
  // src/components/ui/two-tier-badge.tsx
5893
- import * as React28 from "react";
5894
- import { jsx as jsx37, jsxs as jsxs34 } from "react/jsx-runtime";
6403
+ import * as React30 from "react";
6404
+ import { jsx as jsx39, jsxs as jsxs36 } from "react/jsx-runtime";
5895
6405
  var FG = {
5896
6406
  neutral: "var(--text-secondary)",
5897
6407
  info: "var(--semantic-info-fg)",
@@ -5912,7 +6422,7 @@ var SEGMENT = {
5912
6422
  md: "gap-[7px] py-[var(--space-1)] px-[var(--space-3)] text-[14px]"
5913
6423
  };
5914
6424
  var DOT2 = { xs: 5, sm: 6, md: 7 };
5915
- var TwoTierBadge = React28.forwardRef(
6425
+ var TwoTierBadge = React30.forwardRef(
5916
6426
  ({ primary, secondary, tone = "neutral", emphasis = "subtle", size = "sm", showDot = false, className, style, ...props }, ref) => {
5917
6427
  const strong = emphasis === "strong";
5918
6428
  const fg = FG[tone];
@@ -5921,7 +6431,7 @@ var TwoTierBadge = React28.forwardRef(
5921
6431
  const frame = strong ? tinted : "var(--border-subtle)";
5922
6432
  const divider = strong ? tinted : "var(--border)";
5923
6433
  const dotSize = DOT2[size];
5924
- return /* @__PURE__ */ jsxs34(
6434
+ return /* @__PURE__ */ jsxs36(
5925
6435
  "span",
5926
6436
  {
5927
6437
  ref,
@@ -5935,14 +6445,14 @@ var TwoTierBadge = React28.forwardRef(
5935
6445
  style: { fontFamily: "var(--font-sans)", borderColor: frame, background: "transparent", ...style },
5936
6446
  ...props,
5937
6447
  children: [
5938
- /* @__PURE__ */ jsxs34(
6448
+ /* @__PURE__ */ jsxs36(
5939
6449
  "span",
5940
6450
  {
5941
6451
  "data-slot": "two-tier-badge-primary",
5942
6452
  className: cn("inline-flex items-center whitespace-nowrap font-semibold", SEGMENT[size]),
5943
6453
  style: { color: fg, background: strong ? BG[tone] : "transparent" },
5944
6454
  children: [
5945
- showDot ? /* @__PURE__ */ jsx37(
6455
+ showDot ? /* @__PURE__ */ jsx39(
5946
6456
  "span",
5947
6457
  {
5948
6458
  "aria-hidden": "true",
@@ -5957,11 +6467,11 @@ var TwoTierBadge = React28.forwardRef(
5957
6467
  }
5958
6468
  }
5959
6469
  ) : null,
5960
- /* @__PURE__ */ jsx37("span", { children: primary })
6470
+ /* @__PURE__ */ jsx39("span", { children: primary })
5961
6471
  ]
5962
6472
  }
5963
6473
  ),
5964
- secondary != null ? /* @__PURE__ */ jsx37(
6474
+ secondary != null ? /* @__PURE__ */ jsx39(
5965
6475
  "span",
5966
6476
  {
5967
6477
  "data-slot": "two-tier-badge-secondary",
@@ -5982,8 +6492,8 @@ var TwoTierBadge = React28.forwardRef(
5982
6492
  TwoTierBadge.displayName = "TwoTierBadge";
5983
6493
 
5984
6494
  // src/components/ui/status-badge.tsx
5985
- import * as React29 from "react";
5986
- import { jsx as jsx38, jsxs as jsxs35 } from "react/jsx-runtime";
6495
+ import * as React31 from "react";
6496
+ import { jsx as jsx40, jsxs as jsxs37 } from "react/jsx-runtime";
5987
6497
  var ROLE = {
5988
6498
  error: "error",
5989
6499
  warning: "warning",
@@ -6012,13 +6522,13 @@ var SIZE = {
6012
6522
  sm: { cls: "gap-[6px] py-[var(--space-1)] px-[var(--space-2)] text-[12px]", dot: 6 },
6013
6523
  md: { cls: "gap-[var(--space-2)] py-[var(--space-1)] px-[14px] text-[14px]", dot: 7 }
6014
6524
  };
6015
- var StatusBadge = React29.forwardRef(
6525
+ var StatusBadge = React31.forwardRef(
6016
6526
  ({ status = "active", emphasis = "subtle", size = "sm", showDot = true, pulse = true, className, children, style, ...props }, ref) => {
6017
6527
  const role = ROLE[status];
6018
6528
  const fg = FG2[role];
6019
6529
  const strong = emphasis === "strong";
6020
6530
  const ringDot = role === "neutral";
6021
- return /* @__PURE__ */ jsxs35(
6531
+ return /* @__PURE__ */ jsxs37(
6022
6532
  "span",
6023
6533
  {
6024
6534
  ref,
@@ -6036,7 +6546,7 @@ var StatusBadge = React29.forwardRef(
6036
6546
  },
6037
6547
  ...props,
6038
6548
  children: [
6039
- showDot ? /* @__PURE__ */ jsx38(
6549
+ showDot ? /* @__PURE__ */ jsx40(
6040
6550
  "span",
6041
6551
  {
6042
6552
  "aria-hidden": "true",
@@ -6054,7 +6564,7 @@ var StatusBadge = React29.forwardRef(
6054
6564
  }
6055
6565
  ) : null,
6056
6566
  children,
6057
- /* @__PURE__ */ jsx38("style", { children: "@keyframes olun-status-pulse{0%,100%{opacity:1}50%{opacity:.4}}@media (prefers-reduced-motion: reduce){[data-slot=status-badge-dot]{animation:none!important}}" })
6567
+ /* @__PURE__ */ jsx40("style", { children: "@keyframes olun-status-pulse{0%,100%{opacity:1}50%{opacity:.4}}@media (prefers-reduced-motion: reduce){[data-slot=status-badge-dot]{animation:none!important}}" })
6058
6568
  ]
6059
6569
  }
6060
6570
  );
@@ -6063,10 +6573,10 @@ var StatusBadge = React29.forwardRef(
6063
6573
  StatusBadge.displayName = "StatusBadge";
6064
6574
 
6065
6575
  // src/components/ui/notification-badge.tsx
6066
- import * as React30 from "react";
6067
- import { cva as cva11 } from "class-variance-authority";
6068
- import { jsx as jsx39 } from "react/jsx-runtime";
6069
- var notificationBadgeVariants = cva11(
6576
+ import * as React32 from "react";
6577
+ import { cva as cva13 } from "class-variance-authority";
6578
+ import { jsx as jsx41 } from "react/jsx-runtime";
6579
+ var notificationBadgeVariants = cva13(
6070
6580
  [
6071
6581
  "inline-flex shrink-0 items-center justify-center rounded-[var(--radius-full)]",
6072
6582
  "bg-[var(--semantic-error,var(--error))] text-[var(--error-contrast)]",
@@ -6075,256 +6585,64 @@ var notificationBadgeVariants = cva11(
6075
6585
  {
6076
6586
  variants: {
6077
6587
  size: {
6078
- sm: "h-[15px] min-w-[15px] px-[3px] text-[9px]",
6079
- md: "h-[18px] min-w-[18px] px-[3px] text-[10px]"
6080
- },
6081
- placement: {
6082
- corner: "absolute -right-[4px] -top-[4px]",
6083
- inline: "ml-auto",
6084
- none: ""
6085
- }
6086
- },
6087
- defaultVariants: {
6088
- size: "sm",
6089
- placement: "none"
6090
- }
6091
- }
6092
- );
6093
- function formatNotificationCount(count, max) {
6094
- if (count > max) {
6095
- return `${max}+`;
6096
- }
6097
- return String(count);
6098
- }
6099
- var NotificationBadge = React30.forwardRef(
6100
- ({
6101
- className,
6102
- count,
6103
- max = 99,
6104
- size = "sm",
6105
- placement = "none",
6106
- "aria-label": ariaLabel,
6107
- ...props
6108
- }, ref) => {
6109
- if (count <= 0) {
6110
- return null;
6111
- }
6112
- const normalizedMax = Math.max(1, Math.floor(max));
6113
- const label = ariaLabel ?? (count > normalizedMax ? `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${normalizedMax}\uAC1C \uC774\uC0C1` : `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${count}\uAC1C`);
6114
- return /* @__PURE__ */ jsx39(
6115
- "span",
6116
- {
6117
- ref,
6118
- "data-slot": "notification-badge",
6119
- "data-size": size,
6120
- "data-placement": placement,
6121
- "aria-label": label,
6122
- className: cn(notificationBadgeVariants({ size, placement, className })),
6123
- ...props,
6124
- children: formatNotificationCount(count, normalizedMax)
6125
- }
6126
- );
6127
- }
6128
- );
6129
- NotificationBadge.displayName = "NotificationBadge";
6130
-
6131
- // src/components/ui/chip.tsx
6132
- import * as React31 from "react";
6133
- import { cva as cva12 } from "class-variance-authority";
6134
- import { X as X3 } from "lucide-react";
6135
- import { Slot as Slot2 } from "radix-ui";
6136
- import { jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
6137
- var chipVariants = cva12(
6138
- [
6139
- "inline-flex w-fit shrink-0 items-center justify-center whitespace-nowrap",
6140
- "rounded-[var(--radius-full)] border leading-none",
6141
- "font-medium transition-colors motion-reduce:transition-none",
6142
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
6143
- "disabled:pointer-events-none disabled:opacity-50"
6144
- ].join(" "),
6145
- {
6146
- variants: {
6147
- variant: {
6148
- // interactive 3종 — 클릭 가능 (toggle / select / remove). cursor:pointer으로 affordance 명시.
6149
- // (Tailwind v4 preflight + site reset은 button cursor 보장 안 함 → variant level에서 강제.)
6150
- filter: "cursor-pointer",
6151
- choice: "cursor-pointer",
6152
- removable: "cursor-pointer",
6153
- // status-filter — 정적 표시 chip (display only, 클릭 affordance 없음).
6154
- "status-filter": "cursor-default"
6155
- },
6156
- tone: {
6157
- neutral: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-text-secondary hover:bg-[var(--action-hover)]",
6158
- accent: "border-[var(--border-accent)] bg-transparent text-[var(--accent)] hover:bg-[var(--accent-bg-strong)]",
6159
- success: "border-transparent bg-[var(--success-bg)] text-[var(--success)] hover:bg-[var(--action-hover)]",
6160
- warning: "border-transparent bg-[var(--warning-bg)] text-[var(--warning)] hover:bg-[var(--action-hover)]",
6161
- danger: "border-transparent bg-[var(--error-bg)] text-[var(--error)] hover:bg-[var(--action-hover)]",
6162
- muted: "border-[var(--border-subtle)] bg-transparent text-text-tertiary hover:bg-[var(--action-hover)]"
6163
- },
6164
- size: {
6165
- sm: "h-[26px] gap-[var(--space-1)] px-[var(--space-2)] text-xs",
6166
- md: "h-[30px] gap-[var(--space-2)] px-[var(--space-3)] text-xs",
6167
- lg: "h-[34px] gap-[var(--space-2)] px-[var(--space-4)] text-sm"
6168
- },
6169
- pressed: {
6170
- true: "",
6171
- false: ""
6172
- }
6173
- },
6174
- compoundVariants: [
6175
- {
6176
- pressed: true,
6177
- tone: "neutral",
6178
- className: "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground"
6179
- },
6180
- {
6181
- // R10 — wash 패턴 정합 (--accent-bg-strong deep olive wash / --accent olive/lime text).
6182
- pressed: true,
6183
- tone: "accent",
6184
- className: "border-[var(--border-accent)] bg-[var(--accent-bg-strong)] text-[var(--accent)]"
6185
- },
6186
- {
6187
- pressed: true,
6188
- tone: "muted",
6189
- className: "border-[var(--border-strong)] bg-[var(--bg-raised)] text-text-secondary"
6190
- }
6191
- ],
6192
- defaultVariants: {
6193
- variant: "filter",
6194
- tone: "neutral",
6195
- size: "md",
6196
- pressed: false
6197
- }
6198
- }
6199
- );
6200
- var chipCountVariants = cva12(
6201
- [
6202
- "inline-flex min-w-[var(--space-4)] items-center justify-center",
6203
- "rounded-[var(--radius-full)] px-[var(--space-1)]",
6204
- "font-[family-name:var(--font-display)]"
6205
- ].join(" "),
6206
- {
6207
- variants: {
6208
- tone: {
6209
- neutral: "bg-[var(--bg-raised)] text-text-tertiary",
6210
- accent: "bg-[var(--accent-pop)] text-[var(--accent-on-fill)]",
6211
- success: "bg-[var(--success)] text-[var(--success-contrast)]",
6212
- warning: "bg-[var(--warning)] text-[var(--warning-contrast)]",
6213
- danger: "bg-[var(--error)] text-[var(--error-contrast)]",
6214
- muted: "bg-[var(--bg-raised)] text-text-tertiary"
6215
- },
6216
- size: {
6217
- sm: "h-[var(--space-4)] text-xs",
6218
- md: "h-[var(--space-4)] text-xs",
6219
- lg: "h-[calc(var(--space-4)+var(--space-1))] text-xs"
6588
+ sm: "h-[15px] min-w-[15px] px-[3px] text-[9px]",
6589
+ md: "h-[18px] min-w-[18px] px-[3px] text-[10px]"
6590
+ },
6591
+ placement: {
6592
+ corner: "absolute -right-[4px] -top-[4px]",
6593
+ inline: "ml-auto",
6594
+ none: ""
6220
6595
  }
6221
6596
  },
6222
6597
  defaultVariants: {
6223
- tone: "neutral",
6224
- size: "md"
6598
+ size: "sm",
6599
+ placement: "none"
6225
6600
  }
6226
6601
  }
6227
6602
  );
6228
- var Chip = React31.forwardRef(
6603
+ function formatNotificationCount(count, max) {
6604
+ if (count > max) {
6605
+ return `${max}+`;
6606
+ }
6607
+ return String(count);
6608
+ }
6609
+ var NotificationBadge = React32.forwardRef(
6229
6610
  ({
6230
6611
  className,
6231
- variant = "filter",
6232
- tone = "neutral",
6233
- size = "md",
6234
- pressed = false,
6235
6612
  count,
6236
- removeLabel = "Remove",
6237
- asChild = false,
6238
- children,
6613
+ max = 99,
6614
+ size = "sm",
6615
+ placement = "none",
6616
+ "aria-label": ariaLabel,
6239
6617
  ...props
6240
6618
  }, ref) => {
6241
- const removable = variant === "removable";
6242
- if (removable) {
6243
- const {
6244
- onClick,
6245
- disabled,
6246
- type: _type,
6247
- autoFocus: _af,
6248
- form: _form,
6249
- name: _name,
6250
- value: _value,
6251
- ...spanProps
6252
- } = props;
6253
- return /* @__PURE__ */ jsxs36(
6254
- "span",
6255
- {
6256
- "data-slot": "chip",
6257
- "data-variant": variant,
6258
- "data-tone": tone,
6259
- className: cn(chipVariants({ variant, tone, size, pressed, className })),
6260
- ...spanProps,
6261
- children: [
6262
- /* @__PURE__ */ jsx40("span", { children }),
6263
- count !== void 0 ? /* @__PURE__ */ jsx40(
6264
- "span",
6265
- {
6266
- "aria-hidden": "true",
6267
- "data-slot": "chip-count",
6268
- "data-count-tone": tone,
6269
- className: chipCountVariants({ tone, size }),
6270
- children: count
6271
- }
6272
- ) : null,
6273
- /* @__PURE__ */ jsx40(
6274
- "button",
6275
- {
6276
- ref,
6277
- type: "button",
6278
- "data-slot": "chip-remove",
6279
- "aria-label": removeLabel,
6280
- disabled,
6281
- onClick,
6282
- className: "inline-flex size-[var(--space-4)] items-center justify-center rounded-[var(--radius-full)] text-text-tertiary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
6283
- children: /* @__PURE__ */ jsx40(X3, { "aria-hidden": "true", size: 14, strokeWidth: 2.25 })
6284
- }
6285
- )
6286
- ]
6287
- }
6288
- );
6619
+ if (count <= 0) {
6620
+ return null;
6289
6621
  }
6290
- const Comp = asChild ? Slot2.Root : "button";
6291
- return /* @__PURE__ */ jsxs36(
6292
- Comp,
6622
+ const normalizedMax = Math.max(1, Math.floor(max));
6623
+ const label = ariaLabel ?? (count > normalizedMax ? `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${normalizedMax}\uAC1C \uC774\uC0C1` : `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${count}\uAC1C`);
6624
+ return /* @__PURE__ */ jsx41(
6625
+ "span",
6293
6626
  {
6294
6627
  ref,
6295
- "data-slot": "chip",
6296
- "data-variant": variant,
6297
- "data-tone": tone,
6298
- "aria-pressed": pressed,
6299
- className: cn(
6300
- chipVariants({ variant, tone, size, pressed, className })
6301
- ),
6302
- type: asChild ? void 0 : props.type ?? "button",
6628
+ "data-slot": "notification-badge",
6629
+ "data-size": size,
6630
+ "data-placement": placement,
6631
+ "aria-label": label,
6632
+ className: cn(notificationBadgeVariants({ size, placement, className })),
6303
6633
  ...props,
6304
- children: [
6305
- children,
6306
- count !== void 0 ? /* @__PURE__ */ jsx40(
6307
- "span",
6308
- {
6309
- "aria-hidden": "true",
6310
- "data-slot": "chip-count",
6311
- "data-count-tone": tone,
6312
- className: chipCountVariants({ tone, size }),
6313
- children: count
6314
- }
6315
- ) : null
6316
- ]
6634
+ children: formatNotificationCount(count, normalizedMax)
6317
6635
  }
6318
6636
  );
6319
6637
  }
6320
6638
  );
6321
- Chip.displayName = "Chip";
6639
+ NotificationBadge.displayName = "NotificationBadge";
6322
6640
 
6323
6641
  // src/components/ui/empty-state.tsx
6324
- import * as React32 from "react";
6325
- import { cva as cva13 } from "class-variance-authority";
6326
- import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
6327
- var emptyStateBaseVariants = cva13(
6642
+ import * as React33 from "react";
6643
+ import { cva as cva14 } from "class-variance-authority";
6644
+ import { jsx as jsx42, jsxs as jsxs38 } from "react/jsx-runtime";
6645
+ var emptyStateBaseVariants = cva14(
6328
6646
  [
6329
6647
  "flex flex-col items-center justify-center text-center",
6330
6648
  "text-foreground"
@@ -6372,7 +6690,7 @@ function emptyStateVariants({
6372
6690
  className
6373
6691
  );
6374
6692
  }
6375
- var emptyStateIconVariants = cva13(
6693
+ var emptyStateIconVariants = cva14(
6376
6694
  [
6377
6695
  "inline-flex items-center justify-center rounded-[var(--radius-full)]",
6378
6696
  "border border-[var(--border-subtle)] bg-[var(--bg-inset)] text-text-tertiary"
@@ -6390,12 +6708,12 @@ var emptyStateIconVariants = cva13(
6390
6708
  }
6391
6709
  }
6392
6710
  );
6393
- var iconSize2 = {
6711
+ var iconSize3 = {
6394
6712
  sm: 18,
6395
6713
  md: 20,
6396
6714
  lg: 24
6397
6715
  };
6398
- var EmptyState = React32.forwardRef(
6716
+ var EmptyState = React33.forwardRef(
6399
6717
  ({
6400
6718
  className,
6401
6719
  size = "md",
@@ -6410,7 +6728,7 @@ var EmptyState = React32.forwardRef(
6410
6728
  ...props
6411
6729
  }, ref) => {
6412
6730
  const resolvedSize = size ?? "md";
6413
- return /* @__PURE__ */ jsxs37(
6731
+ return /* @__PURE__ */ jsxs38(
6414
6732
  "div",
6415
6733
  {
6416
6734
  ref,
@@ -6419,17 +6737,17 @@ var EmptyState = React32.forwardRef(
6419
6737
  className: cn(emptyStateVariants({ size, tone, surface, bordered, className })),
6420
6738
  ...props,
6421
6739
  children: [
6422
- Icon ? /* @__PURE__ */ jsx41(
6740
+ Icon ? /* @__PURE__ */ jsx42(
6423
6741
  "span",
6424
6742
  {
6425
6743
  "aria-hidden": "true",
6426
6744
  "data-slot": "empty-state-icon",
6427
6745
  className: emptyStateIconVariants({ size: resolvedSize }),
6428
- children: /* @__PURE__ */ jsx41(Icon, { size: iconSize2[resolvedSize], strokeWidth: 1.75 })
6746
+ children: /* @__PURE__ */ jsx42(Icon, { size: iconSize3[resolvedSize], strokeWidth: 1.75 })
6429
6747
  }
6430
6748
  ) : null,
6431
- /* @__PURE__ */ jsxs37("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
6432
- /* @__PURE__ */ jsx41(
6749
+ /* @__PURE__ */ jsxs38("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
6750
+ /* @__PURE__ */ jsx42(
6433
6751
  "h2",
6434
6752
  {
6435
6753
  "data-slot": "empty-state-title",
@@ -6437,7 +6755,7 @@ var EmptyState = React32.forwardRef(
6437
6755
  children: title
6438
6756
  }
6439
6757
  ),
6440
- description ? /* @__PURE__ */ jsx41(
6758
+ description ? /* @__PURE__ */ jsx42(
6441
6759
  "p",
6442
6760
  {
6443
6761
  "data-slot": "empty-state-description",
@@ -6445,7 +6763,7 @@ var EmptyState = React32.forwardRef(
6445
6763
  children: description
6446
6764
  }
6447
6765
  ) : null,
6448
- hint ? /* @__PURE__ */ jsx41(
6766
+ hint ? /* @__PURE__ */ jsx42(
6449
6767
  "p",
6450
6768
  {
6451
6769
  "data-slot": "empty-state-hint",
@@ -6454,7 +6772,7 @@ var EmptyState = React32.forwardRef(
6454
6772
  }
6455
6773
  ) : null
6456
6774
  ] }),
6457
- action ? /* @__PURE__ */ jsx41("div", { "data-slot": "empty-state-action", className: "mt-[var(--space-2)]", children: action }) : null
6775
+ action ? /* @__PURE__ */ jsx42("div", { "data-slot": "empty-state-action", className: "mt-[var(--space-2)]", children: action }) : null
6458
6776
  ]
6459
6777
  }
6460
6778
  );
@@ -6463,11 +6781,11 @@ var EmptyState = React32.forwardRef(
6463
6781
  EmptyState.displayName = "EmptyState";
6464
6782
 
6465
6783
  // src/components/ui/error-state.tsx
6466
- import * as React33 from "react";
6784
+ import * as React34 from "react";
6467
6785
  import { AlertTriangle } from "lucide-react";
6468
- import { cva as cva14 } from "class-variance-authority";
6469
- import { jsx as jsx42, jsxs as jsxs38 } from "react/jsx-runtime";
6470
- var errorStateVariants = cva14(
6786
+ import { cva as cva15 } from "class-variance-authority";
6787
+ import { jsx as jsx43, jsxs as jsxs39 } from "react/jsx-runtime";
6788
+ var errorStateVariants = cva15(
6471
6789
  [
6472
6790
  "flex flex-col items-center justify-center text-center",
6473
6791
  "rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
@@ -6488,7 +6806,7 @@ var errorStateVariants = cva14(
6488
6806
  }
6489
6807
  }
6490
6808
  );
6491
- var ErrorState = React33.forwardRef(
6809
+ var ErrorState = React34.forwardRef(
6492
6810
  ({
6493
6811
  className,
6494
6812
  size = "md",
@@ -6499,7 +6817,7 @@ var ErrorState = React33.forwardRef(
6499
6817
  onRetry,
6500
6818
  retryLabel = "\uB2E4\uC2DC \uC2DC\uB3C4",
6501
6819
  ...props
6502
- }, ref) => /* @__PURE__ */ jsxs38(
6820
+ }, ref) => /* @__PURE__ */ jsxs39(
6503
6821
  "div",
6504
6822
  {
6505
6823
  ref,
@@ -6508,17 +6826,17 @@ var ErrorState = React33.forwardRef(
6508
6826
  className: cn(errorStateVariants({ size, surface, className })),
6509
6827
  ...props,
6510
6828
  children: [
6511
- /* @__PURE__ */ jsx42(
6829
+ /* @__PURE__ */ jsx43(
6512
6830
  "span",
6513
6831
  {
6514
6832
  "aria-hidden": "true",
6515
6833
  "data-slot": "error-state-icon",
6516
6834
  className: "inline-flex size-[48px] items-center justify-center rounded-[var(--radius-full)] bg-[var(--error-bg)] text-[var(--error)]",
6517
- children: /* @__PURE__ */ jsx42(AlertTriangle, { size: 24, strokeWidth: 1.75 })
6835
+ children: /* @__PURE__ */ jsx43(AlertTriangle, { size: 24, strokeWidth: 1.75 })
6518
6836
  }
6519
6837
  ),
6520
- /* @__PURE__ */ jsxs38("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
6521
- /* @__PURE__ */ jsx42(
6838
+ /* @__PURE__ */ jsxs39("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
6839
+ /* @__PURE__ */ jsx43(
6522
6840
  "h2",
6523
6841
  {
6524
6842
  "data-slot": "error-state-title",
@@ -6526,7 +6844,7 @@ var ErrorState = React33.forwardRef(
6526
6844
  children: title
6527
6845
  }
6528
6846
  ),
6529
- /* @__PURE__ */ jsx42(
6847
+ /* @__PURE__ */ jsx43(
6530
6848
  "p",
6531
6849
  {
6532
6850
  "data-slot": "error-state-message",
@@ -6534,7 +6852,7 @@ var ErrorState = React33.forwardRef(
6534
6852
  children: message
6535
6853
  }
6536
6854
  ),
6537
- errorCode ? /* @__PURE__ */ jsx42(
6855
+ errorCode ? /* @__PURE__ */ jsx43(
6538
6856
  "p",
6539
6857
  {
6540
6858
  "data-slot": "error-state-code",
@@ -6543,7 +6861,7 @@ var ErrorState = React33.forwardRef(
6543
6861
  }
6544
6862
  ) : null
6545
6863
  ] }),
6546
- onRetry ? /* @__PURE__ */ jsx42(Button, { size: "sm", variant: "outline", onClick: onRetry, children: retryLabel }) : null
6864
+ onRetry ? /* @__PURE__ */ jsx43(Button, { size: "sm", variant: "outline", onClick: onRetry, children: retryLabel }) : null
6547
6865
  ]
6548
6866
  }
6549
6867
  )
@@ -6551,10 +6869,10 @@ var ErrorState = React33.forwardRef(
6551
6869
  ErrorState.displayName = "ErrorState";
6552
6870
 
6553
6871
  // src/components/ui/skeleton.tsx
6554
- import * as React34 from "react";
6555
- import { cva as cva15 } from "class-variance-authority";
6556
- import { jsx as jsx43 } from "react/jsx-runtime";
6557
- var skeletonVariants = cva15(
6872
+ import * as React35 from "react";
6873
+ import { cva as cva16 } from "class-variance-authority";
6874
+ import { jsx as jsx44 } from "react/jsx-runtime";
6875
+ var skeletonVariants = cva16(
6558
6876
  [
6559
6877
  "animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]",
6560
6878
  "motion-reduce:animate-none motion-reduce:opacity-80"
@@ -6572,7 +6890,7 @@ var skeletonVariants = cva15(
6572
6890
  }
6573
6891
  }
6574
6892
  );
6575
- var spinnerVariants = cva15(
6893
+ var spinnerVariants = cva16(
6576
6894
  [
6577
6895
  "inline-block shrink-0 animate-spin rounded-[var(--radius-full)] border-2",
6578
6896
  "border-[var(--border-subtle)] border-t-[var(--primary)]",
@@ -6595,8 +6913,8 @@ var spinnerVariants = cva15(
6595
6913
  }
6596
6914
  }
6597
6915
  );
6598
- var Skeleton = React34.forwardRef(
6599
- ({ className, shape, style, ...props }, ref) => /* @__PURE__ */ jsx43(
6916
+ var Skeleton = React35.forwardRef(
6917
+ ({ className, shape, style, ...props }, ref) => /* @__PURE__ */ jsx44(
6600
6918
  "div",
6601
6919
  {
6602
6920
  ref,
@@ -6609,15 +6927,15 @@ var Skeleton = React34.forwardRef(
6609
6927
  );
6610
6928
  Skeleton.displayName = "Skeleton";
6611
6929
  var defaultTextWidths = ["92%", "84%", "68%", "76%"];
6612
- var SkeletonText = React34.forwardRef(
6613
- ({ className, lines = 3, widths = defaultTextWidths, ...props }, ref) => /* @__PURE__ */ jsx43(
6930
+ var SkeletonText = React35.forwardRef(
6931
+ ({ className, lines = 3, widths = defaultTextWidths, ...props }, ref) => /* @__PURE__ */ jsx44(
6614
6932
  "div",
6615
6933
  {
6616
6934
  ref,
6617
6935
  "data-slot": "skeleton-text",
6618
6936
  className: cn("flex flex-col gap-[var(--space-2)]", className),
6619
6937
  ...props,
6620
- children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx43(
6938
+ children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx44(
6621
6939
  Skeleton,
6622
6940
  {
6623
6941
  shape: "text",
@@ -6629,7 +6947,7 @@ var SkeletonText = React34.forwardRef(
6629
6947
  )
6630
6948
  );
6631
6949
  SkeletonText.displayName = "SkeletonText";
6632
- var SkeletonRow = React34.forwardRef(
6950
+ var SkeletonRow = React35.forwardRef(
6633
6951
  ({
6634
6952
  className,
6635
6953
  columns,
@@ -6640,7 +6958,7 @@ var SkeletonRow = React34.forwardRef(
6640
6958
  }, ref) => {
6641
6959
  const rowCount = Math.max(5, count);
6642
6960
  const gridTemplateColumns = columns.map((column) => column.width ?? "1fr").join(" ");
6643
- return /* @__PURE__ */ jsx43(
6961
+ return /* @__PURE__ */ jsx44(
6644
6962
  "div",
6645
6963
  {
6646
6964
  ref,
@@ -6654,7 +6972,7 @@ var SkeletonRow = React34.forwardRef(
6654
6972
  className
6655
6973
  ),
6656
6974
  ...props,
6657
- children: Array.from({ length: rowCount }, (_, rowIndex) => /* @__PURE__ */ jsx43(
6975
+ children: Array.from({ length: rowCount }, (_, rowIndex) => /* @__PURE__ */ jsx44(
6658
6976
  "div",
6659
6977
  {
6660
6978
  "data-slot": "skeleton-row",
@@ -6662,11 +6980,11 @@ var SkeletonRow = React34.forwardRef(
6662
6980
  "grid min-h-[48px] items-center border-t border-[var(--border-subtle)] first:border-t-0"
6663
6981
  ),
6664
6982
  style: { gridTemplateColumns },
6665
- children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx43(
6983
+ children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx44(
6666
6984
  "div",
6667
6985
  {
6668
6986
  className: "px-[var(--space-4)] py-[var(--space-2)]",
6669
- children: /* @__PURE__ */ jsx43(
6987
+ children: /* @__PURE__ */ jsx44(
6670
6988
  Skeleton,
6671
6989
  {
6672
6990
  shape: "text",
@@ -6686,8 +7004,8 @@ var SkeletonRow = React34.forwardRef(
6686
7004
  }
6687
7005
  );
6688
7006
  SkeletonRow.displayName = "SkeletonRow";
6689
- var Spinner = React34.forwardRef(
6690
- ({ className, size, label = "\uB85C\uB529 \uC911", ...props }, ref) => /* @__PURE__ */ jsx43(
7007
+ var Spinner = React35.forwardRef(
7008
+ ({ className, size, label = "\uB85C\uB529 \uC911", ...props }, ref) => /* @__PURE__ */ jsx44(
6691
7009
  "span",
6692
7010
  {
6693
7011
  ref,
@@ -6701,150 +7019,6 @@ var Spinner = React34.forwardRef(
6701
7019
  );
6702
7020
  Spinner.displayName = "Spinner";
6703
7021
 
6704
- // src/components/ui/icon-button.tsx
6705
- import * as React35 from "react";
6706
- import { cva as cva16 } from "class-variance-authority";
6707
- import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
6708
- var iconButtonVariants = cva16(
6709
- [
6710
- "olun-icon-button relative inline-flex cursor-pointer shrink-0 items-center justify-center",
6711
- "rounded-[var(--radius-sm)] border font-medium",
6712
- "transition-colors motion-reduce:transition-none",
6713
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
6714
- "disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled",
6715
- "[&_svg]:pointer-events-none [&_svg]:shrink-0"
6716
- ].join(" "),
6717
- {
6718
- variants: {
6719
- variant: {
6720
- ghost: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
6721
- outline: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-text-secondary hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)] hover:text-foreground",
6722
- subtle: "border-transparent bg-[var(--bg-raised)] text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
6723
- danger: "border-transparent bg-[var(--error-bg)] text-[var(--error)] hover:bg-[var(--action-hover)]"
6724
- },
6725
- size: {
6726
- sm: "size-[28px]",
6727
- md: "size-[32px]",
6728
- lg: "size-[40px]"
6729
- },
6730
- pressed: {
6731
- true: "",
6732
- false: ""
6733
- }
6734
- },
6735
- compoundVariants: [
6736
- {
6737
- pressed: true,
6738
- variant: ["ghost", "outline", "subtle"],
6739
- className: "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground"
6740
- },
6741
- {
6742
- pressed: true,
6743
- variant: "danger",
6744
- className: "border-[var(--error)] bg-[var(--error-bg)] text-[var(--error)]"
6745
- }
6746
- ],
6747
- defaultVariants: {
6748
- variant: "ghost",
6749
- size: "md",
6750
- pressed: false
6751
- }
6752
- }
6753
- );
6754
- var iconButtonBadgeVariants = cva16(
6755
- [
6756
- "pointer-events-none absolute right-0 top-0 inline-flex",
6757
- "olun-icon-button__badge",
6758
- "min-h-[var(--space-3)] min-w-[var(--space-3)] translate-x-1/3 -translate-y-1/3",
6759
- "items-center justify-center gap-[2px] rounded-[var(--radius-full)] px-[3px]",
6760
- "font-[family-name:var(--font-display)] text-[10px] font-semibold leading-none",
6761
- "[&:has(svg)]:size-[var(--space-3)] [&:has(svg)]:px-0 [&_svg]:size-[10px]"
6762
- ].join(" "),
6763
- {
6764
- variants: {
6765
- tone: {
6766
- info: "bg-[var(--accent-pop)] text-[var(--accent-on-fill)]",
6767
- error: "bg-[var(--error)] text-[var(--error-contrast)]"
6768
- }
6769
- },
6770
- defaultVariants: {
6771
- tone: "info"
6772
- }
6773
- }
6774
- );
6775
- var iconSize3 = {
6776
- sm: 14,
6777
- md: 16,
6778
- lg: 18
6779
- };
6780
- var iconStrokeWidth = {
6781
- sm: 2.25,
6782
- md: 2.25,
6783
- lg: 1.75
6784
- };
6785
- var IconButton = React35.forwardRef(
6786
- ({
6787
- className,
6788
- variant = "ghost",
6789
- size = "md",
6790
- pressed = void 0,
6791
- icon: Icon,
6792
- badge,
6793
- badgeTone = "info",
6794
- type,
6795
- title,
6796
- "aria-label": ariaLabel,
6797
- "aria-labelledby": ariaLabelledBy,
6798
- ...props
6799
- }, ref) => {
6800
- const resolvedSize = size ?? "md";
6801
- const isToggle = pressed !== void 0;
6802
- const isPressed = pressed === true;
6803
- const hoverTitle = title ?? (typeof ariaLabel === "string" ? ariaLabel : void 0);
6804
- return /* @__PURE__ */ jsxs39(
6805
- "button",
6806
- {
6807
- ref,
6808
- ...props,
6809
- "data-slot": "icon-button",
6810
- "data-variant": variant,
6811
- "data-size": resolvedSize,
6812
- "data-pressed": isToggle ? String(isPressed) : void 0,
6813
- "aria-label": ariaLabel,
6814
- "aria-labelledby": ariaLabelledBy,
6815
- "aria-pressed": isToggle ? isPressed : void 0,
6816
- title: hoverTitle,
6817
- className: cn(
6818
- iconButtonVariants({ variant, size, pressed: isPressed, className })
6819
- ),
6820
- type: type ?? "button",
6821
- children: [
6822
- /* @__PURE__ */ jsx44(
6823
- Icon,
6824
- {
6825
- "aria-hidden": "true",
6826
- "data-slot": "icon-button-icon",
6827
- size: iconSize3[resolvedSize],
6828
- strokeWidth: iconStrokeWidth[resolvedSize]
6829
- }
6830
- ),
6831
- badge !== void 0 ? /* @__PURE__ */ jsx44(
6832
- "span",
6833
- {
6834
- "aria-hidden": "true",
6835
- "data-slot": "icon-button-badge",
6836
- "data-badge-tone": badgeTone,
6837
- className: iconButtonBadgeVariants({ tone: badgeTone }),
6838
- children: badge
6839
- }
6840
- ) : null
6841
- ]
6842
- }
6843
- );
6844
- }
6845
- );
6846
- IconButton.displayName = "IconButton";
6847
-
6848
7022
  // src/components/ui/pagination.tsx
6849
7023
  import * as React36 from "react";
6850
7024
  import { ChevronsLeft, ChevronLeft, ChevronRight as ChevronRight2, ChevronsRight } from "lucide-react";
@@ -7615,7 +7789,7 @@ function ToastProvider({ children, maxToasts = 3, className, ...props }) {
7615
7789
  import * as React39 from "react";
7616
7790
  import { cva as cva21 } from "class-variance-authority";
7617
7791
  import { AlertCircle as AlertCircle4 } from "lucide-react";
7618
- import { Fragment as Fragment8, jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
7792
+ import { Fragment as Fragment9, jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
7619
7793
  var otpFieldVariants = cva21("flex w-full min-w-0 flex-col gap-[var(--space-3)]", {
7620
7794
  variants: {
7621
7795
  size: {
@@ -7937,7 +8111,7 @@ var OTPField = React39.forwardRef(
7937
8111
  "data-slot": "otp-field-message",
7938
8112
  "data-kind": errorText ? "error" : "helper",
7939
8113
  className: otpFieldMessageVariants({ state: resolvedState }),
7940
- children: errorText ? /* @__PURE__ */ jsxs45(Fragment8, { children: [
8114
+ children: errorText ? /* @__PURE__ */ jsxs45(Fragment9, { children: [
7941
8115
  /* @__PURE__ */ jsx50(
7942
8116
  AlertCircle4,
7943
8117
  {