@olundot/ui 0.14.1 → 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
@@ -595,12 +595,15 @@ var fileUploadZoneVariants = cva3(
595
595
  "group/file-upload relative flex w-full cursor-pointer flex-col items-center justify-center text-center",
596
596
  "border-2 border-dashed border-[var(--border)]",
597
597
  "transition-[background-color,border-color,color,box-shadow] motion-reduce:transition-none",
598
- "hover:border-[var(--border-strong)] hover:bg-[var(--action-selected)]",
599
- "focus-within:border-[var(--focus-ring)] focus-within:bg-[var(--action-selected)] focus-within:shadow-[0_0_0_1px_var(--focus-ring)]",
600
- "data-[has-file=true]:border-[var(--border-strong)] data-[has-file=true]:bg-[var(--action-selected)]",
601
- "data-[dragging=true]:border-[var(--border-strong)] data-[dragging=true]:bg-[var(--action-selected)]",
598
+ "hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)]",
599
+ "focus-within:border-[var(--focus-ring)] focus-within:shadow-[0_0_0_1px_var(--focus-ring)]",
600
+ "data-[has-file=true]:border-solid data-[has-file=true]:border-[var(--border-strong)] data-[has-file=true]:bg-[var(--bg-inset)]",
601
+ "data-[dragging=true]:border-[var(--border-strong)] data-[dragging=true]:bg-[var(--action-active)]",
602
602
  "data-[error=true]:border-[var(--error)]",
603
- "data-[disabled=true]:cursor-not-allowed data-[disabled=true]:border-[var(--border-subtle)] data-[disabled=true]:bg-[var(--bg-raised)]",
603
+ "data-[disabled=true]:cursor-not-allowed data-[disabled=true]:border-[var(--border-subtle)] data-[disabled=true]:bg-[var(--action-disabled-bg)]",
604
+ "data-[error=true]:data-[has-file=true]:border-[var(--error)] data-[error=true]:data-[dragging=true]:border-[var(--error)]",
605
+ "data-[disabled=true]:data-[has-file=true]:border-dashed data-[disabled=true]:data-[has-file=true]:border-[var(--border-subtle)] data-[disabled=true]:data-[has-file=true]:bg-[var(--action-disabled-bg)]",
606
+ "data-[disabled=true]:data-[dragging=true]:border-[var(--border-subtle)] data-[disabled=true]:data-[dragging=true]:bg-[var(--action-disabled-bg)]",
604
607
  "data-[disabled=true]:text-text-disabled"
605
608
  ].join(" "),
606
609
  {
@@ -620,7 +623,7 @@ var fileUploadZoneVariants = cva3(
620
623
  var fileUploadIconVariants = cva3(
621
624
  [
622
625
  "inline-flex items-center justify-center rounded-[var(--radius-full)]",
623
- "border border-[var(--border)] bg-[var(--bg-raised)] text-text-secondary",
626
+ "border border-[var(--border)] bg-[var(--bg-inset)] text-text-secondary",
624
627
  "transition-[border-color,color,background-color] motion-reduce:transition-none",
625
628
  "group-hover/file-upload:border-[var(--border-strong)] group-hover/file-upload:text-foreground",
626
629
  "group-data-[has-file=true]/file-upload:border-[var(--border-strong)] group-data-[has-file=true]/file-upload:text-foreground",
@@ -1373,7 +1376,7 @@ var selectVariants = cva5(
1373
1376
  variants: {
1374
1377
  size: {
1375
1378
  sm: "h-[30px] px-pad-compact-x text-body-sm",
1376
- md: "h-[32px] px-pad-default-x text-sm",
1379
+ md: "h-[32px] px-pad-default-x text-body-sm",
1377
1380
  lg: "h-[36px] px-pad-default-x text-sm"
1378
1381
  },
1379
1382
  fullWidth: {
@@ -1528,13 +1531,13 @@ var Select = React7.forwardRef(
1528
1531
  "data-slot": "select-content",
1529
1532
  position: "popper",
1530
1533
  sideOffset: 4,
1531
- className: "z-[var(--z-popover)] max-h-[var(--radix-select-content-available-height)] min-w-[var(--radix-select-trigger-width)] overflow-hidden rounded-[var(--radius-md)] border border-[var(--border)] bg-[var(--bg-raised)] text-foreground shadow-md",
1534
+ className: "z-[var(--z-popover)] max-h-[var(--radix-select-content-available-height)] min-w-[var(--radix-select-trigger-width)] overflow-hidden rounded-[var(--radius-md)] border border-[var(--border)] bg-[var(--bg-surface)] text-foreground shadow-[var(--shadow-4)]",
1532
1535
  children: [
1533
1536
  /* @__PURE__ */ jsx7(
1534
1537
  SelectPrimitive.ScrollUpButton,
1535
1538
  {
1536
1539
  "data-slot": "select-scroll-up",
1537
- className: "flex items-center justify-center border-b border-[var(--border)] bg-[var(--bg-raised)] py-[var(--space-1)] text-text-tertiary",
1540
+ className: "flex items-center justify-center border-b border-[var(--border)] bg-[var(--bg-surface)] py-[var(--space-1)] text-text-tertiary",
1538
1541
  children: /* @__PURE__ */ jsx7(ChevronUp, { "aria-hidden": "true", className: "size-[16px]" })
1539
1542
  }
1540
1543
  ),
@@ -1558,7 +1561,7 @@ var Select = React7.forwardRef(
1558
1561
  SelectPrimitive.ScrollDownButton,
1559
1562
  {
1560
1563
  "data-slot": "select-scroll-down",
1561
- className: "flex items-center justify-center border-t border-[var(--border)] bg-[var(--bg-raised)] py-[var(--space-1)] text-text-tertiary",
1564
+ className: "flex items-center justify-center border-t border-[var(--border)] bg-[var(--bg-surface)] py-[var(--space-1)] text-text-tertiary",
1562
1565
  children: /* @__PURE__ */ jsx7(ChevronDown, { "aria-hidden": "true", className: "size-[16px]" })
1563
1566
  }
1564
1567
  )
@@ -3434,7 +3437,7 @@ var DialogOverlay = React20.forwardRef(({ className, ...props }, ref) => /* @__P
3434
3437
  className: cn(
3435
3438
  "fixed inset-0 z-[var(--z-modal)]",
3436
3439
  // 2026: 글래스모피즘 블러 제거 — 단정한 scrim 딤만(FE-skill anti-slop).
3437
- "bg-[var(--bg-base)]/65",
3440
+ "bg-[var(--scrim)]",
3438
3441
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
3439
3442
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
3440
3443
  "motion-reduce:animate-none",
@@ -3454,9 +3457,10 @@ var DialogContent = React20.forwardRef(({ className, children, showCloseButton =
3454
3457
  "fixed left-1/2 top-1/2 z-[var(--z-modal)]",
3455
3458
  "-translate-x-1/2 -translate-y-1/2",
3456
3459
  "grid w-full max-w-lg gap-4 p-[var(--space-8)]",
3457
- // modal은 dim overlay 위 — 가장 밝은 DS surface(--bg-base #F1F3F5·여전히 tinted·순백 아님)로 깨끗하게.
3460
+ // modal은 dim overlay 위 — panel surface 토큰(--bg-surface)으로 깨끗하게.
3461
+ // (page 배경 --bg-base가 아니라 카드/섹션과 같은 surface 층을 쓴다.)
3458
3462
  // arbitrary var 사용: 소비 site/app이 dist를 content-scan 안 해 `bg-base` 유틸이 purge될 수 있어 안전하게 var로.
3459
- "bg-[var(--bg-base)] text-foreground",
3463
+ "bg-[var(--bg-surface)] text-foreground",
3460
3464
  // 2026: generic 무거운 그림자 대신 floating shadow-8 + 또렷한 중립 grey border(--border·16%) + radius-lg.
3461
3465
  // (border-subtle=8%는 너무 흐려 가장자리가 안 보였음 → border-border로 grey 또렷하게.)
3462
3466
  "border border-border rounded-[var(--radius-lg)] shadow-8",
@@ -3567,8 +3571,8 @@ var formModalContentClassName = cn(
3567
3571
  "w-[calc(100vw-2rem)]",
3568
3572
  "max-w-[560px]",
3569
3573
  "gap-0 p-[var(--space-6)]",
3570
- "bg-[var(--bg-raised)]",
3571
- "border-[var(--border-subtle)]",
3574
+ "bg-[var(--bg-surface)]",
3575
+ "border-[var(--border)]",
3572
3576
  "rounded-[var(--radius-lg)]",
3573
3577
  "shadow-[var(--shadow-4)]",
3574
3578
  "text-foreground"
@@ -3680,8 +3684,8 @@ var infoModalContentClassName = cn(
3680
3684
  "w-[calc(100vw-2rem)]",
3681
3685
  "max-w-[420px]",
3682
3686
  "gap-0 p-[var(--space-6)]",
3683
- "bg-[var(--bg-raised)]",
3684
- "border border-[var(--border-subtle)]",
3687
+ "bg-[var(--bg-surface)]",
3688
+ "border border-[var(--border)]",
3685
3689
  "rounded-[var(--radius-lg)]",
3686
3690
  "shadow-[var(--shadow-4)]",
3687
3691
  "text-foreground"
@@ -3753,426 +3757,192 @@ function InfoModal({
3753
3757
  }
3754
3758
 
3755
3759
  // src/components/ui/filter-toolbar.tsx
3756
- import * as React22 from "react";
3757
- import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
3758
- var FilterToolbar = React22.forwardRef(
3759
- ({
3760
- className,
3761
- search,
3762
- filters,
3763
- resultSummary,
3764
- clearAction,
3765
- actions,
3766
- ...props
3767
- }, ref) => {
3768
- const hasMeta = Boolean(resultSummary || clearAction || actions);
3769
- const hasLeft = Boolean(search || filters);
3770
- return /* @__PURE__ */ jsx24(
3771
- "div",
3772
- {
3773
- ref,
3774
- "data-slot": "filter-toolbar",
3775
- className: cn(
3776
- "flex w-full flex-col gap-[var(--space-2)] text-foreground",
3777
- className
3778
- ),
3779
- ...props,
3780
- children: /* @__PURE__ */ jsxs23(
3781
- "div",
3782
- {
3783
- "data-slot": "filter-toolbar-row",
3784
- className: cn(
3785
- "flex min-h-[34px] w-full flex-wrap items-center gap-x-[var(--space-2)] gap-y-[var(--space-2)]",
3786
- hasLeft ? "justify-start" : "justify-end"
3787
- ),
3788
- children: [
3789
- search ? /* @__PURE__ */ jsx24(
3790
- "div",
3791
- {
3792
- "data-slot": "filter-toolbar-search",
3793
- className: "min-w-0 flex-[1_1_280px] max-w-full",
3794
- children: search
3795
- }
3796
- ) : null,
3797
- filters ? /* @__PURE__ */ jsx24(
3798
- "div",
3799
- {
3800
- "data-slot": "filter-toolbar-filters",
3801
- className: "flex min-w-0 flex-[2_1_auto] flex-wrap items-center gap-[var(--space-2)]",
3802
- children: filters
3803
- }
3804
- ) : null,
3805
- hasMeta ? /* @__PURE__ */ jsxs23(
3806
- "div",
3807
- {
3808
- "data-slot": "filter-toolbar-meta",
3809
- className: "ml-auto flex min-w-0 flex-wrap items-center justify-end gap-[var(--space-2)]",
3810
- children: [
3811
- resultSummary ? /* @__PURE__ */ jsx24(
3812
- "div",
3813
- {
3814
- "data-slot": "filter-toolbar-summary",
3815
- className: "shrink-0 whitespace-nowrap text-xs leading-snug text-text-tertiary",
3816
- children: resultSummary
3817
- }
3818
- ) : null,
3819
- clearAction ? /* @__PURE__ */ jsx24(
3820
- "div",
3821
- {
3822
- "data-slot": "filter-toolbar-clear",
3823
- className: "shrink-0",
3824
- children: clearAction
3825
- }
3826
- ) : null,
3827
- actions ? /* @__PURE__ */ jsx24(
3828
- "div",
3829
- {
3830
- "data-slot": "filter-toolbar-actions",
3831
- className: "flex shrink-0 flex-wrap items-center gap-[var(--space-2)]",
3832
- children: actions
3833
- }
3834
- ) : null
3835
- ]
3836
- }
3837
- ) : null
3838
- ]
3839
- }
3840
- )
3841
- }
3842
- );
3843
- }
3844
- );
3845
- FilterToolbar.displayName = "FilterToolbar";
3846
-
3847
- // src/components/ui/data-table.tsx
3848
- import * as React24 from "react";
3849
- import { ChevronDown as ChevronDown3, ChevronUp as ChevronUp2, ChevronsUpDown } from "lucide-react";
3850
- import { cva as cva10 } from "class-variance-authority";
3760
+ import * as React25 from "react";
3761
+ import { SlidersHorizontal } from "lucide-react";
3851
3762
 
3852
- // src/components/ui/checkbox.tsx
3853
- import * as React23 from "react";
3763
+ // src/components/ui/chip.tsx
3764
+ import * as React22 from "react";
3854
3765
  import { cva as cva9 } from "class-variance-authority";
3855
- import { Check as Check3, Minus } from "lucide-react";
3856
- import { Checkbox as CheckboxPrimitive } from "radix-ui";
3857
- import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3858
- var checkboxFieldVariants = cva9(
3859
- "flex flex-col gap-[var(--space-1)]",
3860
- {
3861
- variants: {
3862
- fullWidth: {
3863
- true: "w-full",
3864
- false: "w-fit"
3865
- }
3866
- },
3867
- defaultVariants: {
3868
- fullWidth: false
3869
- }
3870
- }
3871
- );
3872
- var checkboxVariants = checkboxFieldVariants;
3873
- var checkboxRootVariants = cva9(
3874
- [
3875
- "group shrink-0 cursor-pointer rounded-[var(--radius-xs)]",
3876
- "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)]",
3877
- "disabled:cursor-not-allowed"
3878
- ].join(" ")
3879
- );
3880
- 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(
3881
3770
  [
3882
- "flex shrink-0 items-center justify-center rounded-[var(--radius-xs)] border",
3883
- "border-[var(--border-strong)] bg-[var(--bg-surface)] text-transparent",
3884
- "transition-colors motion-reduce:transition-none",
3885
- "group-hover:bg-[var(--action-hover)]",
3886
- "group-disabled:border-[var(--border-subtle)] group-disabled:bg-[var(--action-disabled-bg)]",
3887
- "group-data-[state=checked]:border-[var(--primary)] group-data-[state=checked]:bg-[var(--primary)] group-data-[state=checked]:text-[var(--primary-fg)]",
3888
- "group-data-[state=indeterminate]:border-[var(--primary)] group-data-[state=indeterminate]:bg-[var(--primary)] group-data-[state=indeterminate]:text-[var(--primary-fg)]",
3889
- "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",
3890
- "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"
3891
3776
  ].join(" "),
3892
3777
  {
3893
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
+ },
3894
3796
  size: {
3895
- sm: "size-[calc(var(--space-4)+var(--space-1))]",
3896
- md: "size-[calc(var(--space-4)+var(--space-1))]"
3897
- }
3898
- },
3899
- defaultVariants: {
3900
- size: "md"
3901
- }
3902
- }
3903
- );
3904
- var checkboxGroupItemVariants = cva9(
3905
- [
3906
- "group w-full cursor-pointer text-left transition-colors motion-reduce:transition-none",
3907
- "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)]",
3908
- "disabled:cursor-not-allowed disabled:text-text-disabled"
3909
- ].join(" "),
3910
- {
3911
- variants: {
3912
- appearance: {
3913
- plain: "inline-flex items-start gap-[var(--space-3)] rounded-[var(--radius-sm)] px-pad-compact-x py-pad-compact-y",
3914
- card: [
3915
- "flex min-h-[calc(var(--space-12)+var(--space-2))] items-start gap-[var(--space-3)]",
3916
- "rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-base)]",
3917
- "hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)]",
3918
- "data-[state=checked]:border-[var(--border-strong)] data-[state=checked]:bg-[var(--action-selected)]",
3919
- "disabled:border-[var(--border-subtle)] disabled:bg-[var(--action-disabled-bg)]",
3920
- "disabled:data-[state=checked]:border-[var(--border-subtle)] disabled:data-[state=checked]:bg-[var(--action-disabled-bg)]"
3921
- ].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"
3922
3800
  },
3923
- density: {
3924
- comfortable: "",
3925
- compact: ""
3801
+ pressed: {
3802
+ true: "",
3803
+ false: ""
3926
3804
  }
3927
3805
  },
3928
3806
  compoundVariants: [
3929
3807
  {
3930
- appearance: "card",
3931
- density: "comfortable",
3932
- 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"
3933
3811
  },
3934
3812
  {
3935
- appearance: "card",
3936
- density: "compact",
3937
- 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"
3938
3822
  }
3939
3823
  ],
3940
3824
  defaultVariants: {
3941
- appearance: "plain",
3942
- density: "comfortable"
3825
+ variant: "filter",
3826
+ tone: "neutral",
3827
+ size: "md",
3828
+ pressed: false
3943
3829
  }
3944
3830
  }
3945
3831
  );
3946
- var checkboxGroupBoxVariants = cva9(
3947
- "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(" "),
3948
3838
  {
3949
3839
  variants: {
3950
- appearance: {
3951
- plain: "",
3952
- 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"
3953
3852
  }
3954
3853
  },
3955
3854
  defaultVariants: {
3956
- appearance: "plain"
3855
+ tone: "neutral",
3856
+ size: "md"
3957
3857
  }
3958
3858
  }
3959
3859
  );
3960
- var CheckboxGroupContext = React23.createContext(null);
3961
- function getLabel(children, label) {
3962
- return children ?? label;
3963
- }
3964
- var Checkbox = React23.forwardRef(
3860
+ var Chip = React22.forwardRef(
3965
3861
  ({
3966
3862
  className,
3863
+ variant = "filter",
3864
+ tone = "neutral",
3967
3865
  size = "md",
3968
- fullWidth = false,
3866
+ pressed = false,
3867
+ count,
3868
+ removeLabel = "Remove",
3869
+ asChild = false,
3969
3870
  children,
3970
- label,
3971
- description,
3972
- required,
3973
- error,
3974
- id,
3975
- value,
3976
- name,
3977
- checked,
3978
- disabled,
3979
- onCheckedChange,
3980
3871
  ...props
3981
3872
  }, ref) => {
3982
- const group = React23.useContext(CheckboxGroupContext);
3983
- const generatedId = React23.useId();
3984
- const checkboxId = id ?? generatedId;
3985
- const labelContent = getLabel(children, label);
3986
- const isGrouped = Boolean(group && value != null);
3987
- const valueString = value == null ? void 0 : String(value);
3988
- const resolvedChecked = isGrouped && valueString ? group?.selectedValues.has(valueString) : checked;
3989
- const resolvedDisabled = disabled || group?.disabled;
3990
- const resolvedName = name ?? group?.name;
3991
- const labelId = `${checkboxId}-label`;
3992
- const descriptionId = description && !error ? `${checkboxId}-description` : void 0;
3993
- const errorId = error ? `${checkboxId}-error` : void 0;
3994
- const describedBy = errorId ?? descriptionId;
3995
- const handleCheckedChange = (nextChecked) => {
3996
- onCheckedChange?.(nextChecked);
3997
- if (isGrouped && valueString) {
3998
- group?.toggleValue(valueString, nextChecked === true);
3999
- }
4000
- };
4001
- if (isGrouped) {
4002
- const appearance = group?.appearance ?? "plain";
4003
- const density = group?.density ?? "comfortable";
4004
- return /* @__PURE__ */ jsxs24(
4005
- CheckboxPrimitive.Root,
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",
4006
3887
  {
4007
- ref,
4008
- id: checkboxId,
4009
- "data-slot": "checkbox",
4010
- "aria-labelledby": labelId,
4011
- "aria-describedby": describedBy,
4012
- "aria-required": required || void 0,
4013
- "aria-invalid": error ? true : void 0,
4014
- name: resolvedName,
4015
- value: valueString,
4016
- checked: resolvedChecked,
4017
- disabled: resolvedDisabled,
4018
- className: cn(
4019
- checkboxGroupItemVariants({ appearance, density }),
4020
- className
4021
- ),
4022
- onCheckedChange: handleCheckedChange,
4023
- ...props,
3888
+ "data-slot": "chip",
3889
+ "data-variant": variant,
3890
+ "data-tone": tone,
3891
+ className: cn(chipVariants({ variant, tone, size, pressed, className })),
3892
+ ...spanProps,
4024
3893
  children: [
4025
- /* @__PURE__ */ jsx25(
3894
+ /* @__PURE__ */ jsx24("span", { children }),
3895
+ count !== void 0 ? /* @__PURE__ */ jsx24(
4026
3896
  "span",
4027
3897
  {
4028
3898
  "aria-hidden": "true",
4029
- "data-slot": "checkbox-box",
4030
- className: cn(
4031
- checkboxBoxVariants({ size }),
4032
- checkboxGroupBoxVariants({ appearance })
4033
- ),
4034
- children: /* @__PURE__ */ jsx25(
4035
- CheckboxPrimitive.Indicator,
4036
- {
4037
- "data-slot": "checkbox-indicator",
4038
- className: "flex items-center justify-center",
4039
- 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 })
4040
- }
4041
- )
3899
+ "data-slot": "chip-count",
3900
+ "data-count-tone": tone,
3901
+ className: chipCountVariants({ tone, size }),
3902
+ children: count
4042
3903
  }
4043
- ),
4044
- /* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 flex-col gap-[var(--space-1)]", children: [
4045
- /* @__PURE__ */ jsxs24(
4046
- "span",
4047
- {
4048
- id: labelId,
4049
- "data-slot": "checkbox-label",
4050
- className: "text-sm font-medium leading-snug text-foreground group-disabled:text-text-disabled",
4051
- children: [
4052
- labelContent,
4053
- required ? /* @__PURE__ */ jsx25(
4054
- "span",
4055
- {
4056
- "aria-hidden": "true",
4057
- "data-slot": "checkbox-required-marker",
4058
- className: "ml-[var(--space-1)] font-bold text-[var(--semantic-error,var(--error))]",
4059
- children: "*"
4060
- }
4061
- ) : null
4062
- ]
4063
- }
4064
- ),
4065
- error ? /* @__PURE__ */ jsx25(
4066
- "span",
4067
- {
4068
- id: errorId,
4069
- role: "alert",
4070
- "data-slot": "checkbox-error",
4071
- className: "text-xs font-medium leading-normal text-[var(--error)]",
4072
- children: error
4073
- }
4074
- ) : description ? /* @__PURE__ */ jsx25(
4075
- "span",
4076
- {
4077
- id: descriptionId,
4078
- "data-slot": "checkbox-description",
4079
- className: "text-xs font-normal leading-normal text-text-tertiary group-disabled:text-text-disabled",
4080
- children: description
4081
- }
4082
- ) : null
4083
- ] })
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
+ )
4084
3918
  ]
4085
3919
  }
4086
3920
  );
4087
3921
  }
4088
- const labelClassName = cn(
4089
- "cursor-pointer select-none text-left font-medium text-foreground",
4090
- size === "sm" ? "text-xs" : "text-sm",
4091
- resolvedDisabled && "cursor-not-allowed text-text-disabled"
4092
- );
4093
- return /* @__PURE__ */ jsxs24(
4094
- "div",
3922
+ const Comp = asChild ? Slot2.Root : "button";
3923
+ return /* @__PURE__ */ jsxs23(
3924
+ Comp,
4095
3925
  {
4096
- "data-slot": "checkbox-field",
4097
- "data-disabled": resolvedDisabled ? "" : void 0,
4098
- 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,
4099
3936
  children: [
4100
- /* @__PURE__ */ jsxs24("div", { className: "inline-flex items-center gap-[var(--space-3)]", children: [
4101
- /* @__PURE__ */ jsx25(
4102
- CheckboxPrimitive.Root,
4103
- {
4104
- ref,
4105
- id: checkboxId,
4106
- "data-slot": "checkbox",
4107
- "aria-describedby": describedBy,
4108
- "aria-required": required || void 0,
4109
- "aria-invalid": error ? true : void 0,
4110
- name: resolvedName,
4111
- value: valueString,
4112
- checked: resolvedChecked,
4113
- disabled: resolvedDisabled,
4114
- className: cn(checkboxRootVariants(), className),
4115
- onCheckedChange: handleCheckedChange,
4116
- ...props,
4117
- children: /* @__PURE__ */ jsx25(
4118
- "span",
4119
- {
4120
- "aria-hidden": "true",
4121
- "data-slot": "checkbox-box",
4122
- className: checkboxBoxVariants({ size }),
4123
- children: /* @__PURE__ */ jsx25(
4124
- CheckboxPrimitive.Indicator,
4125
- {
4126
- "data-slot": "checkbox-indicator",
4127
- className: "flex items-center justify-center",
4128
- 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 })
4129
- }
4130
- )
4131
- }
4132
- )
4133
- }
4134
- ),
4135
- labelContent ? /* @__PURE__ */ jsxs24(
4136
- "label",
4137
- {
4138
- id: labelId,
4139
- htmlFor: checkboxId,
4140
- "data-slot": "checkbox-label",
4141
- className: labelClassName,
4142
- children: [
4143
- labelContent,
4144
- required ? /* @__PURE__ */ jsx25(
4145
- "span",
4146
- {
4147
- "aria-hidden": "true",
4148
- "data-slot": "checkbox-required-marker",
4149
- className: "ml-[var(--space-1)] font-bold text-[var(--semantic-error,var(--error))]",
4150
- children: "*"
4151
- }
4152
- ) : null
4153
- ]
4154
- }
4155
- ) : null
4156
- ] }),
4157
- error ? /* @__PURE__ */ jsx25(
4158
- "p",
4159
- {
4160
- id: errorId,
4161
- role: "alert",
4162
- "data-slot": "checkbox-error",
4163
- className: "ml-[32px] text-xs font-medium leading-normal text-[var(--error)]",
4164
- children: error
4165
- }
4166
- ) : description ? /* @__PURE__ */ jsx25(
4167
- "p",
3937
+ children,
3938
+ count !== void 0 ? /* @__PURE__ */ jsx24(
3939
+ "span",
4168
3940
  {
4169
- id: descriptionId,
4170
- "data-slot": "checkbox-description",
4171
- className: cn(
4172
- "ml-[32px] text-xs font-normal leading-normal text-text-tertiary",
4173
- resolvedDisabled && "text-text-disabled"
4174
- ),
4175
- children: description
3941
+ "aria-hidden": "true",
3942
+ "data-slot": "chip-count",
3943
+ "data-count-tone": tone,
3944
+ className: chipCountVariants({ tone, size }),
3945
+ children: count
4176
3946
  }
4177
3947
  ) : null
4178
3948
  ]
@@ -4180,59 +3950,1235 @@ var Checkbox = React23.forwardRef(
4180
3950
  );
4181
3951
  }
4182
3952
  );
4183
- Checkbox.displayName = "Checkbox";
3953
+ Chip.displayName = "Chip";
4184
3954
 
4185
- // src/components/ui/data-table.tsx
4186
- import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
4187
- 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(
4188
3960
  [
4189
- "relative overflow-hidden rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
4190
- "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"
4191
3967
  ].join(" "),
4192
3968
  {
4193
3969
  variants: {
4194
- density: {
4195
- standard: "",
4196
- 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)]"
4197
3975
  },
4198
- 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
+ }
4199
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
+ ],
4200
3998
  defaultVariants: {
4201
- density: "standard",
4202
- surface: "surface"
3999
+ variant: "ghost",
4000
+ size: "md",
4001
+ pressed: false
4203
4002
  }
4204
4003
  }
4205
4004
  );
4206
- var dataTableRowVariants = cva10(
4005
+ var iconButtonBadgeVariants = cva10(
4207
4006
  [
4208
- "grid min-h-[48px] items-center border-t border-[var(--border-subtle)]",
4209
- "text-body-sm leading-compact text-foreground",
4210
- "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]"
4211
4013
  ].join(" "),
4212
4014
  {
4213
4015
  variants: {
4214
- interactive: {
4215
- 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)]",
4216
- false: ""
4217
- },
4218
- selected: {
4219
- true: "bg-[var(--action-selected)]",
4220
- false: ""
4016
+ tone: {
4017
+ info: "bg-[var(--accent-pop)] text-[var(--accent-on-fill)]",
4018
+ error: "bg-[var(--error)] text-[var(--error-contrast)]"
4221
4019
  }
4222
4020
  },
4223
4021
  defaultVariants: {
4224
- interactive: false,
4225
- selected: false
4022
+ tone: "info"
4226
4023
  }
4227
4024
  }
4228
4025
  );
4229
- var alignmentClass = {
4230
- left: "justify-start text-left",
4231
- center: "justify-center text-center",
4232
- right: "justify-end text-right"
4233
- };
4234
- function getRowId(row, keyField) {
4235
- return String(row[keyField]);
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",
5177
+ center: "justify-center text-center",
5178
+ right: "justify-end text-right"
5179
+ };
5180
+ function getRowId(row, keyField) {
5181
+ return String(row[keyField]);
4236
5182
  }
4237
5183
  function getGridTemplate(columns, selectable) {
4238
5184
  const columnWidths = columns.map((column) => column.width ?? "1fr");
@@ -4246,7 +5192,7 @@ function getRenderedCell(row, column) {
4246
5192
  if (value === null || value === void 0) {
4247
5193
  return null;
4248
5194
  }
4249
- if (React24.isValidElement(value)) {
5195
+ if (React27.isValidElement(value)) {
4250
5196
  return value;
4251
5197
  }
4252
5198
  return String(value);
@@ -4286,7 +5232,7 @@ function isInteractiveTarget(target) {
4286
5232
  function SortIcon({ sort, columnKey }) {
4287
5233
  const isActive = sort?.key === columnKey;
4288
5234
  if (!isActive) {
4289
- return /* @__PURE__ */ jsx26(
5235
+ return /* @__PURE__ */ jsx31(
4290
5236
  ChevronsUpDown,
4291
5237
  {
4292
5238
  "aria-hidden": "true",
@@ -4298,7 +5244,7 @@ function SortIcon({ sort, columnKey }) {
4298
5244
  );
4299
5245
  }
4300
5246
  const Icon = sort.dir === "asc" ? ChevronUp2 : ChevronDown3;
4301
- return /* @__PURE__ */ jsx26(
5247
+ return /* @__PURE__ */ jsx31(
4302
5248
  Icon,
4303
5249
  {
4304
5250
  "aria-hidden": "true",
@@ -4321,7 +5267,7 @@ function MobileSortControls({
4321
5267
  if (sortableColumns.length === 0) {
4322
5268
  return null;
4323
5269
  }
4324
- return /* @__PURE__ */ jsxs25(
5270
+ return /* @__PURE__ */ jsxs30(
4325
5271
  "div",
4326
5272
  {
4327
5273
  "data-slot": "data-table-mobile-sort-toolbar",
@@ -4332,11 +5278,11 @@ function MobileSortControls({
4332
5278
  surfaceClassNames[surface]
4333
5279
  ),
4334
5280
  children: [
4335
- /* @__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" }),
4336
5282
  sortableColumns.map((column) => {
4337
5283
  const active = sortBy?.key === column.key;
4338
5284
  const nextSort = getNextSort(sortBy, column.key);
4339
- return /* @__PURE__ */ jsx26(
5285
+ return /* @__PURE__ */ jsx31(
4340
5286
  Button,
4341
5287
  {
4342
5288
  type: "button",
@@ -4345,9 +5291,9 @@ function MobileSortControls({
4345
5291
  variant: active ? "secondary" : "outline",
4346
5292
  "aria-pressed": active,
4347
5293
  onClick: () => onSortChange?.(column.key, nextSort),
4348
- children: /* @__PURE__ */ jsxs25("span", { className: "inline-flex min-w-0 items-center gap-[var(--space-1)]", children: [
4349
- /* @__PURE__ */ jsx26("span", { className: "truncate", children: column.header }),
4350
- /* @__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 })
4351
5297
  ] })
4352
5298
  },
4353
5299
  column.key
@@ -4367,17 +5313,17 @@ function SkeletonRows({
4367
5313
  // role="table"의 허용 자식은 row/rowgroup뿐이라 컨테이너는 rowgroup이어야 한다.
4368
5314
  // 로딩 알림은 그 안의 row/cell 안에 둔다 — 종전에는 컨테이너가 role="status"라
4369
5315
  // aria-required-children(Critical)이 났다.
4370
- /* @__PURE__ */ jsxs25("div", { role: "rowgroup", children: [
4371
- /* @__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" }) }) }),
4372
- 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(
4373
5319
  "div",
4374
5320
  {
4375
5321
  "data-slot": "data-table-skeleton-row",
4376
5322
  className: "grid min-h-[48px] items-center border-t border-[var(--border-subtle)]",
4377
5323
  style: { gridTemplateColumns },
4378
5324
  children: [
4379
- selectable ? /* @__PURE__ */ jsx26("div", { "aria-hidden": "true", className: "px-[var(--space-4)]" }) : null,
4380
- 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(
4381
5327
  "div",
4382
5328
  {
4383
5329
  className: cn(
@@ -4394,22 +5340,22 @@ function SkeletonRows({
4394
5340
  );
4395
5341
  }
4396
5342
  function MobileSkeletonCards({ count }) {
4397
- return /* @__PURE__ */ jsx26(
5343
+ return /* @__PURE__ */ jsx31(
4398
5344
  "div",
4399
5345
  {
4400
5346
  "data-slot": "data-table-mobile-skeleton",
4401
5347
  "aria-label": "\uB370\uC774\uD130 \uB85C\uB4DC \uC911",
4402
5348
  role: "status",
4403
5349
  className: "md:hidden",
4404
- children: Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */ jsxs25(
5350
+ children: Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */ jsxs30(
4405
5351
  "div",
4406
5352
  {
4407
5353
  "data-slot": "data-table-mobile-skeleton-card",
4408
5354
  className: "flex flex-col gap-[var(--space-2)] border-t border-[var(--border-subtle)] px-[var(--space-4)] py-[var(--space-4)]",
4409
5355
  children: [
4410
- /* @__PURE__ */ jsx26("div", { className: "h-[14px] w-[72%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]" }),
4411
- /* @__PURE__ */ jsx26("div", { className: "h-[12px] w-[56%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]" }),
4412
- /* @__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)]" })
4413
5359
  ]
4414
5360
  },
4415
5361
  rowIndex
@@ -4467,7 +5413,7 @@ function DataTableInner({
4467
5413
  }
4468
5414
  emitSelection(nextIds);
4469
5415
  };
4470
- return /* @__PURE__ */ jsxs25(
5416
+ return /* @__PURE__ */ jsxs30(
4471
5417
  "div",
4472
5418
  {
4473
5419
  ref,
@@ -4475,7 +5421,7 @@ function DataTableInner({
4475
5421
  className: cn(dataTableVariants({ density, surface, className })),
4476
5422
  ...props,
4477
5423
  children: [
4478
- selectable ? /* @__PURE__ */ jsx26(
5424
+ selectable ? /* @__PURE__ */ jsx31(
4479
5425
  "div",
4480
5426
  {
4481
5427
  "data-slot": "data-table-selection-status",
@@ -4484,17 +5430,17 @@ function DataTableInner({
4484
5430
  children: selectedCount > 0 ? `${selectedCount.toLocaleString("ko-KR")}\uAC1C \uC120\uD0DD\uB428` : ""
4485
5431
  }
4486
5432
  ) : null,
4487
- loading && data.length > 0 ? /* @__PURE__ */ jsx26(
5433
+ loading && data.length > 0 ? /* @__PURE__ */ jsx31(
4488
5434
  "div",
4489
5435
  {
4490
5436
  "data-slot": "data-table-progress",
4491
5437
  "aria-hidden": "true",
4492
5438
  className: "absolute left-0 right-0 top-0 z-10 h-[2px] overflow-hidden bg-[var(--action-selected)]",
4493
- 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)]" })
4494
5440
  }
4495
5441
  ) : null,
4496
- /* @__PURE__ */ jsx26("div", { "data-slot": "data-table-desktop", className: "max-md:hidden md:block", children: /* @__PURE__ */ jsxs25("div", { role: "table", "aria-label": ariaLabel, children: [
4497
- /* @__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(
4498
5444
  "div",
4499
5445
  {
4500
5446
  "data-slot": "data-table-header",
@@ -4502,20 +5448,20 @@ function DataTableInner({
4502
5448
  className: "grid min-h-[40px] items-center bg-[var(--bg-raised)] text-[12px] font-semibold uppercase leading-snug text-text-tertiary",
4503
5449
  style: { gridTemplateColumns },
4504
5450
  children: [
4505
- 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(
4506
5452
  Checkbox,
4507
5453
  {
4508
5454
  "aria-label": "\uC804\uCCB4 \uD589 \uC120\uD0DD",
4509
5455
  checked: partiallySelected ? "indeterminate" : allVisibleRowsSelected,
4510
5456
  onCheckedChange: (nextChecked) => toggleAllRows(nextChecked === true),
4511
- 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" })
4512
5458
  }
4513
5459
  ) }) : null,
4514
5460
  columns.map((column) => {
4515
5461
  const align = column.align ?? "left";
4516
5462
  const nextSort = getNextSort(sortBy, column.key);
4517
5463
  const ariaSort = sortBy?.key === column.key ? sortBy.dir === "asc" ? "ascending" : "descending" : void 0;
4518
- return /* @__PURE__ */ jsx26(
5464
+ return /* @__PURE__ */ jsx31(
4519
5465
  "div",
4520
5466
  {
4521
5467
  role: "columnheader",
@@ -4524,7 +5470,7 @@ function DataTableInner({
4524
5470
  "flex min-w-0 items-center gap-[var(--space-1)] px-[var(--space-4)] py-[var(--space-2)]",
4525
5471
  alignmentClass[align]
4526
5472
  ),
4527
- children: column.sortable ? /* @__PURE__ */ jsxs25(
5473
+ children: column.sortable ? /* @__PURE__ */ jsxs30(
4528
5474
  "button",
4529
5475
  {
4530
5476
  type: "button",
@@ -4535,11 +5481,11 @@ function DataTableInner({
4535
5481
  ),
4536
5482
  onClick: () => onSortChange?.(column.key, nextSort),
4537
5483
  children: [
4538
- /* @__PURE__ */ jsx26("span", { className: "truncate", children: column.header }),
4539
- /* @__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 })
4540
5486
  ]
4541
5487
  }
4542
- ) : /* @__PURE__ */ jsx26("span", { className: "truncate", children: column.header })
5488
+ ) : /* @__PURE__ */ jsx31("span", { className: "truncate", children: column.header })
4543
5489
  },
4544
5490
  column.key
4545
5491
  );
@@ -4547,7 +5493,7 @@ function DataTableInner({
4547
5493
  ]
4548
5494
  }
4549
5495
  ),
4550
- loading && data.length === 0 ? /* @__PURE__ */ jsx26(
5496
+ loading && data.length === 0 ? /* @__PURE__ */ jsx31(
4551
5497
  SkeletonRows,
4552
5498
  {
4553
5499
  columns,
@@ -4558,7 +5504,7 @@ function DataTableInner({
4558
5504
  ) : data.length === 0 ? (
4559
5505
  /* role="table" 직계 자식은 row/rowgroup이어야 한다. data-slot과 테두리는
4560
5506
  그대로 유지해 시각 계약을 깨지 않는다(빈 상태에서도 표가 테두리를 그린다). */
4561
- /* @__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(
4562
5508
  "div",
4563
5509
  {
4564
5510
  role: "cell",
@@ -4568,12 +5514,12 @@ function DataTableInner({
4568
5514
  children: emptyState
4569
5515
  }
4570
5516
  ) }) })
4571
- ) : /* @__PURE__ */ jsx26("div", { role: "rowgroup", children: data.map((row) => {
5517
+ ) : /* @__PURE__ */ jsx31("div", { role: "rowgroup", children: data.map((row) => {
4572
5518
  const rowId = getRowId(row, keyField);
4573
5519
  const selected = resolvedSelectedIds.has(rowId);
4574
5520
  const visuallySelected = selected || rowId === activeRowId;
4575
5521
  const href = rowHref?.(row);
4576
- return /* @__PURE__ */ jsxs25(
5522
+ return /* @__PURE__ */ jsxs30(
4577
5523
  "div",
4578
5524
  {
4579
5525
  "data-slot": "data-table-row",
@@ -4600,13 +5546,13 @@ function DataTableInner({
4600
5546
  }
4601
5547
  },
4602
5548
  children: [
4603
- 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(
4604
5550
  Checkbox,
4605
5551
  {
4606
5552
  "aria-label": `${String(row[columns[0]?.key] ?? rowId)} \uD589 \uC120\uD0DD`,
4607
5553
  checked: selected,
4608
5554
  onCheckedChange: (nextChecked) => toggleRow(rowId, nextChecked === true),
4609
- children: /* @__PURE__ */ jsxs25("span", { className: "sr-only", children: [
5555
+ children: /* @__PURE__ */ jsxs30("span", { className: "sr-only", children: [
4610
5556
  rowId,
4611
5557
  " \uD589 \uC120\uD0DD"
4612
5558
  ] })
@@ -4614,7 +5560,7 @@ function DataTableInner({
4614
5560
  ) }) : null,
4615
5561
  columns.map((column) => {
4616
5562
  const align = column.align ?? "left";
4617
- return /* @__PURE__ */ jsx26(
5563
+ return /* @__PURE__ */ jsx31(
4618
5564
  "div",
4619
5565
  {
4620
5566
  "data-slot": "data-table-cell",
@@ -4625,7 +5571,7 @@ function DataTableInner({
4625
5571
  column.tabular ? "font-[family-name:var(--font-display)] tabular-nums" : null,
4626
5572
  align === "right" ? "text-text-tertiary" : null
4627
5573
  ),
4628
- 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) })
4629
5575
  },
4630
5576
  column.key
4631
5577
  );
@@ -4636,7 +5582,7 @@ function DataTableInner({
4636
5582
  );
4637
5583
  }) })
4638
5584
  ] }) }),
4639
- /* @__PURE__ */ jsx26(
5585
+ /* @__PURE__ */ jsx31(
4640
5586
  MobileSortControls,
4641
5587
  {
4642
5588
  columns,
@@ -4646,14 +5592,14 @@ function DataTableInner({
4646
5592
  surface
4647
5593
  }
4648
5594
  ),
4649
- 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(
4650
5596
  "div",
4651
5597
  {
4652
5598
  "data-slot": "data-table-mobile-empty",
4653
5599
  className: "border-t border-[var(--border-subtle)] p-[var(--space-4)] md:hidden",
4654
5600
  children: emptyState
4655
5601
  }
4656
- ) : /* @__PURE__ */ jsx26(
5602
+ ) : /* @__PURE__ */ jsx31(
4657
5603
  "div",
4658
5604
  {
4659
5605
  "data-slot": "data-table-mobile-list",
@@ -4667,7 +5613,7 @@ function DataTableInner({
4667
5613
  const href = rowHref?.(row);
4668
5614
  const primaryText = getAccessibleCellText(row, primaryColumn, rowId);
4669
5615
  const primaryLabel = primaryColumn ? getHeaderLabel(primaryColumn) : "\uD589";
4670
- return /* @__PURE__ */ jsxs25(
5616
+ return /* @__PURE__ */ jsxs30(
4671
5617
  "div",
4672
5618
  {
4673
5619
  "data-slot": "data-table-mobile-card",
@@ -4699,20 +5645,20 @@ function DataTableInner({
4699
5645
  }
4700
5646
  },
4701
5647
  children: [
4702
- /* @__PURE__ */ jsxs25("div", { className: "flex min-w-0 items-start gap-[var(--space-3)]", children: [
4703
- 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(
4704
5650
  Checkbox,
4705
5651
  {
4706
5652
  "aria-label": `${primaryText} \uBAA8\uBC14\uC77C \uCE74\uB4DC \uC120\uD0DD`,
4707
5653
  checked: selected,
4708
5654
  onCheckedChange: (nextChecked) => toggleRow(rowId, nextChecked === true),
4709
- children: /* @__PURE__ */ jsxs25("span", { className: "sr-only", children: [
5655
+ children: /* @__PURE__ */ jsxs30("span", { className: "sr-only", children: [
4710
5656
  rowId,
4711
5657
  " \uBAA8\uBC14\uC77C \uCE74\uB4DC \uC120\uD0DD"
4712
5658
  ] })
4713
5659
  }
4714
5660
  ) }) : null,
4715
- /* @__PURE__ */ jsx26(
5661
+ /* @__PURE__ */ jsx31(
4716
5662
  "div",
4717
5663
  {
4718
5664
  "data-slot": "data-table-mobile-card-primary",
@@ -4721,16 +5667,16 @@ function DataTableInner({
4721
5667
  }
4722
5668
  )
4723
5669
  ] }),
4724
- 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) => {
4725
5671
  const align = column.align ?? "left";
4726
- return /* @__PURE__ */ jsxs25(
5672
+ return /* @__PURE__ */ jsxs30(
4727
5673
  "div",
4728
5674
  {
4729
5675
  "data-slot": "data-table-mobile-card-field",
4730
5676
  className: "grid min-w-0 grid-cols-[minmax(0,0.42fr)_minmax(0,1fr)] gap-[var(--space-2)] text-[12px] leading-snug",
4731
5677
  children: [
4732
- /* @__PURE__ */ jsx26("dt", { className: "min-w-0 text-text-tertiary", children: /* @__PURE__ */ jsx26("span", { className: "truncate", children: column.header }) }),
4733
- /* @__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(
4734
5680
  "dd",
4735
5681
  {
4736
5682
  className: cn(
@@ -4738,7 +5684,7 @@ function DataTableInner({
4738
5684
  alignmentClass[align],
4739
5685
  column.tabular ? "font-[family-name:var(--font-display)] tabular-nums" : null
4740
5686
  ),
4741
- 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) })
4742
5688
  }
4743
5689
  )
4744
5690
  ]
@@ -4757,27 +5703,27 @@ function DataTableInner({
4757
5703
  }
4758
5704
  );
4759
5705
  }
4760
- var DataTable = React24.forwardRef(DataTableInner);
5706
+ var DataTable = React27.forwardRef(DataTableInner);
4761
5707
  DataTable.displayName = "DataTable";
4762
5708
 
4763
5709
  // src/components/ui/dropdown-menu.tsx
4764
5710
  import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
4765
5711
  import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
4766
- import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
5712
+ import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
4767
5713
  function DropdownMenu({
4768
5714
  ...props
4769
5715
  }) {
4770
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
5716
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
4771
5717
  }
4772
5718
  function DropdownMenuPortal({
4773
5719
  ...props
4774
5720
  }) {
4775
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
5721
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
4776
5722
  }
4777
5723
  function DropdownMenuTrigger({
4778
5724
  ...props
4779
5725
  }) {
4780
- return /* @__PURE__ */ jsx27(
5726
+ return /* @__PURE__ */ jsx32(
4781
5727
  DropdownMenuPrimitive.Trigger,
4782
5728
  {
4783
5729
  "data-slot": "dropdown-menu-trigger",
@@ -4790,7 +5736,7 @@ function DropdownMenuContent({
4790
5736
  sideOffset = 4,
4791
5737
  ...props
4792
5738
  }) {
4793
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx27(
5739
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx32(
4794
5740
  DropdownMenuPrimitive.Content,
4795
5741
  {
4796
5742
  "data-slot": "dropdown-menu-content",
@@ -4798,7 +5744,7 @@ function DropdownMenuContent({
4798
5744
  className: cn(
4799
5745
  "z-[var(--z-popover)] max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem]",
4800
5746
  "origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto",
4801
- "rounded-sm border border-[var(--border)] bg-canvas p-[var(--space-1)] text-text-primary shadow-2",
5747
+ "rounded-sm border border-[var(--border)] bg-[var(--bg-surface)] p-[var(--space-1)] text-text-primary shadow-2",
4802
5748
  "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
4803
5749
  "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4804
5750
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
@@ -4813,7 +5759,7 @@ function DropdownMenuContent({
4813
5759
  function DropdownMenuGroup({
4814
5760
  ...props
4815
5761
  }) {
4816
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
5762
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
4817
5763
  }
4818
5764
  function DropdownMenuItem({
4819
5765
  className,
@@ -4821,7 +5767,7 @@ function DropdownMenuItem({
4821
5767
  variant = "default",
4822
5768
  ...props
4823
5769
  }) {
4824
- return /* @__PURE__ */ jsx27(
5770
+ return /* @__PURE__ */ jsx32(
4825
5771
  DropdownMenuPrimitive.Item,
4826
5772
  {
4827
5773
  "data-slot": "dropdown-menu-item",
@@ -4848,7 +5794,7 @@ function DropdownMenuCheckboxItem({
4848
5794
  checked,
4849
5795
  ...props
4850
5796
  }) {
4851
- return /* @__PURE__ */ jsxs26(
5797
+ return /* @__PURE__ */ jsxs31(
4852
5798
  DropdownMenuPrimitive.CheckboxItem,
4853
5799
  {
4854
5800
  "data-slot": "dropdown-menu-checkbox-item",
@@ -4864,7 +5810,7 @@ function DropdownMenuCheckboxItem({
4864
5810
  checked,
4865
5811
  ...props,
4866
5812
  children: [
4867
- /* @__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 }) }) }),
4868
5814
  children
4869
5815
  ]
4870
5816
  }
@@ -4873,7 +5819,7 @@ function DropdownMenuCheckboxItem({
4873
5819
  function DropdownMenuRadioGroup({
4874
5820
  ...props
4875
5821
  }) {
4876
- return /* @__PURE__ */ jsx27(
5822
+ return /* @__PURE__ */ jsx32(
4877
5823
  DropdownMenuPrimitive.RadioGroup,
4878
5824
  {
4879
5825
  "data-slot": "dropdown-menu-radio-group",
@@ -4886,7 +5832,7 @@ function DropdownMenuRadioItem({
4886
5832
  children,
4887
5833
  ...props
4888
5834
  }) {
4889
- return /* @__PURE__ */ jsxs26(
5835
+ return /* @__PURE__ */ jsxs31(
4890
5836
  DropdownMenuPrimitive.RadioItem,
4891
5837
  {
4892
5838
  "data-slot": "dropdown-menu-radio-item",
@@ -4901,7 +5847,7 @@ function DropdownMenuRadioItem({
4901
5847
  ),
4902
5848
  ...props,
4903
5849
  children: [
4904
- /* @__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" }) }) }),
4905
5851
  children
4906
5852
  ]
4907
5853
  }
@@ -4912,7 +5858,7 @@ function DropdownMenuLabel({
4912
5858
  inset,
4913
5859
  ...props
4914
5860
  }) {
4915
- return /* @__PURE__ */ jsx27(
5861
+ return /* @__PURE__ */ jsx32(
4916
5862
  DropdownMenuPrimitive.Label,
4917
5863
  {
4918
5864
  "data-slot": "dropdown-menu-label",
@@ -4929,7 +5875,7 @@ function DropdownMenuSeparator({
4929
5875
  className,
4930
5876
  ...props
4931
5877
  }) {
4932
- return /* @__PURE__ */ jsx27(
5878
+ return /* @__PURE__ */ jsx32(
4933
5879
  DropdownMenuPrimitive.Separator,
4934
5880
  {
4935
5881
  "data-slot": "dropdown-menu-separator",
@@ -4942,7 +5888,7 @@ function DropdownMenuShortcut({
4942
5888
  className,
4943
5889
  ...props
4944
5890
  }) {
4945
- return /* @__PURE__ */ jsx27(
5891
+ return /* @__PURE__ */ jsx32(
4946
5892
  "span",
4947
5893
  {
4948
5894
  "data-slot": "dropdown-menu-shortcut",
@@ -4957,7 +5903,7 @@ function DropdownMenuShortcut({
4957
5903
  function DropdownMenuSub({
4958
5904
  ...props
4959
5905
  }) {
4960
- return /* @__PURE__ */ jsx27(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
5906
+ return /* @__PURE__ */ jsx32(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
4961
5907
  }
4962
5908
  function DropdownMenuSubTrigger({
4963
5909
  className,
@@ -4965,7 +5911,7 @@ function DropdownMenuSubTrigger({
4965
5911
  children,
4966
5912
  ...props
4967
5913
  }) {
4968
- return /* @__PURE__ */ jsxs26(
5914
+ return /* @__PURE__ */ jsxs31(
4969
5915
  DropdownMenuPrimitive.SubTrigger,
4970
5916
  {
4971
5917
  "data-slot": "dropdown-menu-sub-trigger",
@@ -4982,7 +5928,7 @@ function DropdownMenuSubTrigger({
4982
5928
  ...props,
4983
5929
  children: [
4984
5930
  children,
4985
- /* @__PURE__ */ jsx27(ChevronRightIcon, { className: "ml-auto", size: 16 })
5931
+ /* @__PURE__ */ jsx32(ChevronRightIcon, { className: "ml-auto", size: 16 })
4986
5932
  ]
4987
5933
  }
4988
5934
  );
@@ -4991,13 +5937,13 @@ function DropdownMenuSubContent({
4991
5937
  className,
4992
5938
  ...props
4993
5939
  }) {
4994
- return /* @__PURE__ */ jsx27(
5940
+ return /* @__PURE__ */ jsx32(
4995
5941
  DropdownMenuPrimitive.SubContent,
4996
5942
  {
4997
5943
  "data-slot": "dropdown-menu-sub-content",
4998
5944
  className: cn(
4999
5945
  "z-[var(--z-popover)] min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden",
5000
- "rounded-sm border border-[var(--border)] bg-canvas p-[var(--space-1)] text-text-primary shadow-2",
5946
+ "rounded-sm border border-[var(--border)] bg-[var(--bg-surface)] p-[var(--space-1)] text-text-primary shadow-2",
5001
5947
  "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
5002
5948
  "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
5003
5949
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
@@ -5011,7 +5957,7 @@ function DropdownMenuSubContent({
5011
5957
  }
5012
5958
 
5013
5959
  // src/components/ui/context-menu.tsx
5014
- import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
5960
+ import { jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
5015
5961
  function ContextMenu({
5016
5962
  open,
5017
5963
  onOpenChange,
@@ -5022,8 +5968,8 @@ function ContextMenu({
5022
5968
  if (!position) {
5023
5969
  return null;
5024
5970
  }
5025
- return /* @__PURE__ */ jsxs27(DropdownMenu, { open, onOpenChange, modal: false, children: [
5026
- /* @__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(
5027
5973
  "span",
5028
5974
  {
5029
5975
  "aria-hidden": "true",
@@ -5037,18 +5983,18 @@ function ContextMenu({
5037
5983
  }
5038
5984
  }
5039
5985
  ) }),
5040
- /* @__PURE__ */ jsx28(DropdownMenuContent, { ...contentProps, children })
5986
+ /* @__PURE__ */ jsx33(DropdownMenuContent, { ...contentProps, children })
5041
5987
  ] });
5042
5988
  }
5043
5989
 
5044
5990
  // src/components/ui/bulk-action-bar.tsx
5045
- import { X as X2 } from "lucide-react";
5046
- 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";
5047
5993
  function ActionButton({ action }) {
5048
5994
  const danger = action.variant === "destructive";
5049
5995
  const off = action.disabled;
5050
5996
  const Icon = action.icon;
5051
- return /* @__PURE__ */ jsxs28(
5997
+ return /* @__PURE__ */ jsxs33(
5052
5998
  "button",
5053
5999
  {
5054
6000
  type: "button",
@@ -5075,7 +6021,7 @@ function ActionButton({ action }) {
5075
6021
  whiteSpace: "nowrap"
5076
6022
  },
5077
6023
  children: [
5078
- Icon ? /* @__PURE__ */ jsx29(
6024
+ Icon ? /* @__PURE__ */ jsx34(
5079
6025
  Icon,
5080
6026
  {
5081
6027
  "aria-hidden": "true",
@@ -5090,7 +6036,7 @@ function ActionButton({ action }) {
5090
6036
  );
5091
6037
  }
5092
6038
  function Divider() {
5093
- return /* @__PURE__ */ jsx29(
6039
+ return /* @__PURE__ */ jsx34(
5094
6040
  "span",
5095
6041
  {
5096
6042
  "aria-hidden": "true",
@@ -5105,7 +6051,7 @@ function Divider() {
5105
6051
  );
5106
6052
  }
5107
6053
  function ClearButton({ onClear }) {
5108
- return /* @__PURE__ */ jsx29(
6054
+ return /* @__PURE__ */ jsx34(
5109
6055
  "button",
5110
6056
  {
5111
6057
  type: "button",
@@ -5127,7 +6073,7 @@ function ClearButton({ onClear }) {
5127
6073
  justifyContent: "center",
5128
6074
  borderRadius: "var(--radius-sm)"
5129
6075
  },
5130
- 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" })
5131
6077
  }
5132
6078
  );
5133
6079
  }
@@ -5143,7 +6089,7 @@ function BulkActionBar({
5143
6089
  if (count === 0 && emptyHint === void 0) {
5144
6090
  return null;
5145
6091
  }
5146
- return /* @__PURE__ */ jsxs28(
6092
+ return /* @__PURE__ */ jsxs33(
5147
6093
  "div",
5148
6094
  {
5149
6095
  role: "toolbar",
@@ -5175,7 +6121,7 @@ function BulkActionBar({
5175
6121
  },
5176
6122
  ...props,
5177
6123
  children: [
5178
- /* @__PURE__ */ jsx29(
6124
+ /* @__PURE__ */ jsx34(
5179
6125
  "span",
5180
6126
  {
5181
6127
  "data-slot": "bulk-action-bar-count",
@@ -5192,8 +6138,8 @@ function BulkActionBar({
5192
6138
  children: count > 0 ? `${count.toLocaleString("ko-KR")}\uAC1C \uC120\uD0DD\uB428` : emptyHint
5193
6139
  }
5194
6140
  ),
5195
- count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx29(Divider, {}) : null,
5196
- /* @__PURE__ */ jsx29(
6141
+ count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx34(Divider, {}) : null,
6142
+ /* @__PURE__ */ jsx34(
5197
6143
  "div",
5198
6144
  {
5199
6145
  "data-slot": "bulk-action-bar-actions",
@@ -5205,25 +6151,25 @@ function BulkActionBar({
5205
6151
  justifyContent: "flex-end",
5206
6152
  gap: 2
5207
6153
  },
5208
- children: actions.map((action) => /* @__PURE__ */ jsx29(ActionButton, { action }, action.key))
6154
+ children: actions.map((action) => /* @__PURE__ */ jsx34(ActionButton, { action }, action.key))
5209
6155
  }
5210
6156
  ),
5211
- /* @__PURE__ */ jsx29(Divider, {}),
5212
- /* @__PURE__ */ jsx29(ClearButton, { onClear })
6157
+ /* @__PURE__ */ jsx34(Divider, {}),
6158
+ /* @__PURE__ */ jsx34(ClearButton, { onClear })
5213
6159
  ]
5214
6160
  }
5215
6161
  );
5216
6162
  }
5217
6163
 
5218
6164
  // src/components/ui/confirm-dialog.tsx
5219
- import * as React25 from "react";
5220
- 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";
5221
6167
  var confirmDialogContentClassName = cn(
5222
6168
  "fixed left-1/2 top-1/2 z-[var(--z-modal)]",
5223
6169
  "-translate-x-1/2 -translate-y-1/2",
5224
6170
  "w-[calc(100vw-2rem)] max-w-[420px]",
5225
6171
  "flex flex-col gap-[var(--space-6)]",
5226
- "bg-[var(--bg-raised)] border border-[var(--border-subtle)]",
6172
+ "bg-[var(--bg-surface)] border border-[var(--border)]",
5227
6173
  "rounded-[var(--radius-lg)] p-[var(--space-6)] shadow-[var(--shadow-4)]",
5228
6174
  "text-foreground"
5229
6175
  );
@@ -5245,10 +6191,10 @@ function ConfirmDialog({
5245
6191
  onConfirm,
5246
6192
  loading = false
5247
6193
  }) {
5248
- const [pending, setPending] = React25.useState(false);
5249
- const busyRef = React25.useRef(false);
6194
+ const [pending, setPending] = React28.useState(false);
6195
+ const busyRef = React28.useRef(false);
5250
6196
  const isBusy = loading || pending;
5251
- const handleOpenChange = React25.useCallback(
6197
+ const handleOpenChange = React28.useCallback(
5252
6198
  (nextOpen) => {
5253
6199
  if (!nextOpen && isBusy) {
5254
6200
  return;
@@ -5257,7 +6203,7 @@ function ConfirmDialog({
5257
6203
  },
5258
6204
  [isBusy, onOpenChange]
5259
6205
  );
5260
- const handleConfirm = React25.useCallback(async () => {
6206
+ const handleConfirm = React28.useCallback(async () => {
5261
6207
  if (busyRef.current || loading) {
5262
6208
  return;
5263
6209
  }
@@ -5271,9 +6217,9 @@ function ConfirmDialog({
5271
6217
  setPending(false);
5272
6218
  }
5273
6219
  }, [loading, onConfirm, onOpenChange]);
5274
- const dialogBody = /* @__PURE__ */ jsxs29(Fragment7, { children: [
5275
- /* @__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: [
5276
- /* @__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(
5277
6223
  DialogTitle,
5278
6224
  {
5279
6225
  "data-slot": "dialog-title",
@@ -5281,570 +6227,139 @@ function ConfirmDialog({
5281
6227
  children: title
5282
6228
  }
5283
6229
  ),
5284
- description ? /* @__PURE__ */ jsx30(
6230
+ description ? /* @__PURE__ */ jsx35(
5285
6231
  DialogDescription,
5286
6232
  {
5287
6233
  "data-slot": "dialog-description",
5288
6234
  className: confirmDialogDescriptionClassName,
5289
- children: description
5290
- }
5291
- ) : null
5292
- ] }) }),
5293
- /* @__PURE__ */ jsxs29(
5294
- "div",
5295
- {
5296
- "data-slot": "dialog-footer",
5297
- className: confirmDialogFooterClassName,
5298
- children: [
5299
- /* @__PURE__ */ jsx30(Button, { variant: "secondary", disabled: isBusy, onClick: () => handleOpenChange(false), children: cancelLabel }),
5300
- /* @__PURE__ */ jsx30(
5301
- Button,
5302
- {
5303
- variant: tone === "destructive" ? "destructive" : "primary",
5304
- loading: isBusy,
5305
- onClick: handleConfirm,
5306
- children: confirmLabel
5307
- }
5308
- )
5309
- ]
5310
- }
5311
- )
5312
- ] });
5313
- return /* @__PURE__ */ jsx30(Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs29(DialogPortal, { children: [
5314
- /* @__PURE__ */ jsx30(DialogOverlay, {}),
5315
- /* @__PURE__ */ jsx30(DialogRawContent, { role: "alertdialog", "data-slot": "dialog-content", className: confirmDialogContentClassName, children: dialogBody })
5316
- ] }) });
5317
- }
5318
-
5319
- // src/components/ui/separator.tsx
5320
- import { Separator as SeparatorPrimitive } from "radix-ui";
5321
- import { jsx as jsx31 } from "react/jsx-runtime";
5322
- function Separator2({
5323
- className,
5324
- orientation = "horizontal",
5325
- decorative = true,
5326
- ...props
5327
- }) {
5328
- return /* @__PURE__ */ jsx31(
5329
- SeparatorPrimitive.Root,
5330
- {
5331
- "data-slot": "separator",
5332
- decorative,
5333
- orientation,
5334
- className: cn(
5335
- "shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
5336
- className
5337
- ),
5338
- ...props
5339
- }
5340
- );
5341
- }
5342
-
5343
- // src/components/ui/avatar.tsx
5344
- import { Avatar as AvatarPrimitive } from "radix-ui";
5345
- import { jsx as jsx32 } from "react/jsx-runtime";
5346
- function Avatar({
5347
- className,
5348
- size = "md",
5349
- ...props
5350
- }) {
5351
- return /* @__PURE__ */ jsx32(
5352
- AvatarPrimitive.Root,
5353
- {
5354
- "data-slot": "avatar",
5355
- "data-size": size,
5356
- className: cn(
5357
- "group/avatar relative flex shrink-0 overflow-hidden rounded-full select-none",
5358
- "border border-[var(--border-subtle)] bg-[var(--bg-raised)] text-text-secondary",
5359
- "h-9 w-9",
5360
- "data-[size=sm]:h-8 data-[size=sm]:w-8",
5361
- "data-[size=lg]:h-11 data-[size=lg]:w-11",
5362
- className
5363
- ),
5364
- ...props
5365
- }
5366
- );
5367
- }
5368
- function AvatarImage({
5369
- className,
5370
- ...props
5371
- }) {
5372
- return /* @__PURE__ */ jsx32(
5373
- AvatarPrimitive.Image,
5374
- {
5375
- "data-slot": "avatar-image",
5376
- className: cn("aspect-square h-full w-full object-cover", className),
5377
- ...props
5378
- }
5379
- );
5380
- }
5381
- function getAvatarFallbackText(name) {
5382
- const trimmedName = name.trim();
5383
- if (!trimmedName) return null;
5384
- const segmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter("ko", { granularity: "grapheme" }) : null;
5385
- if (segmenter) {
5386
- return segmenter.segment(trimmedName)[Symbol.iterator]().next().value?.segment ?? null;
5387
- }
5388
- return Array.from(trimmedName)[0] ?? null;
5389
- }
5390
- function AvatarFallback({
5391
- className,
5392
- children,
5393
- name,
5394
- ...props
5395
- }) {
5396
- const fallbackText = children ?? (name ? getAvatarFallbackText(name) : null);
5397
- return /* @__PURE__ */ jsx32(
5398
- AvatarPrimitive.Fallback,
5399
- {
5400
- "data-slot": "avatar-fallback",
5401
- className: cn(
5402
- "flex h-full w-full items-center justify-center rounded-full",
5403
- "bg-[var(--bg-raised)] text-sm font-semibold text-text-secondary",
5404
- "font-[family-name:var(--font-display)]",
5405
- "group-data-[size=sm]/avatar:text-xs",
5406
- className
5407
- ),
5408
- ...props,
5409
- children: fallbackText
5410
- }
5411
- );
5412
- }
5413
-
5414
- // src/components/ui/sheet.tsx
5415
- import { XIcon as XIcon2 } from "lucide-react";
5416
- import { Dialog as SheetPrimitive } from "radix-ui";
5417
- import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
5418
- var defaultSheetMotionConfig = {
5419
- type: "slide",
5420
- duration: 300,
5421
- easing: "decel"
5422
- };
5423
- var sheetMotionEasingValue = {
5424
- standard: "var(--ease-standard)",
5425
- // decel/sharp have no canonical --ease-* token; these compat beziers are frozen
5426
- // specifically to back this public `easing` prop (see tokens/compat.css).
5427
- decel: "var(--easing-decel)",
5428
- accel: "var(--ease-in)",
5429
- sharp: "var(--easing-sharp)",
5430
- bounce: "var(--ease-out)"
5431
- };
5432
- function resolveSheetMotionConfig(motion) {
5433
- if (motion === false) return false;
5434
- return {
5435
- ...defaultSheetMotionConfig,
5436
- ...motion
5437
- };
5438
- }
5439
- function formatSheetMotionDuration(duration) {
5440
- return typeof duration === "number" ? `${duration}ms` : duration;
5441
- }
5442
- function getSheetMotionStyle(motionConfig, style) {
5443
- if (!motionConfig) return style;
5444
- return {
5445
- ...style,
5446
- "--sheet-motion-duration": formatSheetMotionDuration(motionConfig.duration),
5447
- "--sheet-motion-easing": sheetMotionEasingValue[motionConfig.easing]
5448
- };
5449
- }
5450
- function Sheet({ ...props }) {
5451
- return /* @__PURE__ */ jsx33(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
5452
- }
5453
- function SheetTrigger({
5454
- ...props
5455
- }) {
5456
- return /* @__PURE__ */ jsx33(SheetPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
5457
- }
5458
- function SheetClose({
5459
- ...props
5460
- }) {
5461
- return /* @__PURE__ */ jsx33(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
5462
- }
5463
- function SheetPortal({
5464
- ...props
5465
- }) {
5466
- return /* @__PURE__ */ jsx33(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
5467
- }
5468
- function SheetOverlay({
5469
- className,
5470
- motion,
5471
- style,
5472
- ...props
5473
- }) {
5474
- const motionConfig = resolveSheetMotionConfig(motion);
5475
- return /* @__PURE__ */ jsx33(
5476
- SheetPrimitive.Overlay,
5477
- {
5478
- "data-slot": "sheet-overlay",
5479
- className: cn(
5480
- "fixed inset-0 z-[var(--z-overlay)] bg-black/50",
5481
- motionConfig && cn(
5482
- "transition-opacity motion-reduce:transition-none",
5483
- "duration-[var(--sheet-motion-duration)]",
5484
- "data-[state=closed]:opacity-0 data-[state=open]:opacity-100",
5485
- "data-[state=open]:animate-[olun-sheet-fade-in_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
5486
- "data-[state=closed]:animate-[olun-sheet-fade-out_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
5487
- "motion-reduce:animate-none"
5488
- ),
5489
- className
5490
- ),
5491
- style: getSheetMotionStyle(motionConfig, style),
5492
- ...props
5493
- }
5494
- );
5495
- }
5496
- function SheetContent({
5497
- className,
5498
- children,
5499
- side = "right",
5500
- mobileSide,
5501
- motion,
5502
- showCloseButton = false,
5503
- style,
5504
- ...props
5505
- }) {
5506
- const motionConfig = resolveSheetMotionConfig(motion);
5507
- const hasSlideMotion = motionConfig && motionConfig.type === "slide";
5508
- return /* @__PURE__ */ jsxs30(SheetPortal, { children: [
5509
- /* @__PURE__ */ jsx33(SheetOverlay, { motion: motionConfig }),
5510
- /* @__PURE__ */ jsxs30(
5511
- SheetPrimitive.Content,
6235
+ children: description
6236
+ }
6237
+ ) : null
6238
+ ] }) }),
6239
+ /* @__PURE__ */ jsxs34(
6240
+ "div",
5512
6241
  {
5513
- "data-slot": "sheet-content",
5514
- className: cn(
5515
- "fixed z-[var(--z-modal)] flex flex-col gap-4 border-[var(--border)] bg-background shadow-lg",
5516
- motionConfig && cn(
5517
- "motion-reduce:animate-none",
5518
- 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]"
5519
- ),
5520
- side === "right" && cn(
5521
- "inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
5522
- 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]"
5523
- ),
5524
- side === "left" && cn(
5525
- "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
5526
- 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]"
5527
- ),
5528
- side === "top" && cn(
5529
- "inset-x-0 top-0 h-auto border-b",
5530
- 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]"
5531
- ),
5532
- side === "bottom" && cn(
5533
- "inset-x-0 bottom-0 h-auto border-t",
5534
- 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]"
5535
- ),
5536
- mobileSide === "right" && cn(
5537
- "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",
5538
- 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]"
5539
- ),
5540
- mobileSide === "left" && cn(
5541
- "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",
5542
- 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]"
5543
- ),
5544
- mobileSide === "top" && cn(
5545
- // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap (see mobileSide bottom).
5546
- "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",
5547
- 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]"
5548
- ),
5549
- mobileSide === "bottom" && cn(
5550
- // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap so the bottom sheet
5551
- // spans the full viewport width across the whole < 900px band (not capped to 24rem).
5552
- "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",
5553
- 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]"
5554
- ),
5555
- className
5556
- ),
5557
- style: getSheetMotionStyle(motionConfig, style),
5558
- ...props,
6242
+ "data-slot": "dialog-footer",
6243
+ className: confirmDialogFooterClassName,
5559
6244
  children: [
5560
- children,
5561
- 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: [
5562
- /* @__PURE__ */ jsx33(XIcon2, { className: "size-[16px]" }),
5563
- /* @__PURE__ */ jsx33("span", { className: "sr-only", children: "Close" })
5564
- ] })
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
+ )
5565
6255
  ]
5566
6256
  }
5567
6257
  )
5568
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
+ ] }) });
5569
6263
  }
5570
- function SheetBody({ className, ...props }) {
5571
- return /* @__PURE__ */ jsx33(
5572
- "div",
5573
- {
5574
- "data-slot": "sheet-body",
5575
- className: cn("flex-1 overflow-y-auto p-4", className),
5576
- ...props
5577
- }
5578
- );
5579
- }
5580
- function SheetHeader({ className, ...props }) {
5581
- return /* @__PURE__ */ jsx33(
5582
- "div",
5583
- {
5584
- "data-slot": "sheet-header",
5585
- className: cn("flex flex-col gap-1.5 p-4", className),
5586
- ...props
5587
- }
5588
- );
5589
- }
5590
- function SheetFooter({ className, ...props }) {
5591
- return /* @__PURE__ */ jsx33(
5592
- "div",
5593
- {
5594
- "data-slot": "sheet-footer",
5595
- className: cn("mt-auto flex flex-col gap-2 p-4", className),
5596
- ...props
5597
- }
5598
- );
5599
- }
5600
- function SheetTitle({
5601
- className,
5602
- ...props
5603
- }) {
5604
- return /* @__PURE__ */ jsx33(
5605
- SheetPrimitive.Title,
5606
- {
5607
- "data-slot": "sheet-title",
5608
- className: cn("font-semibold text-foreground", className),
5609
- ...props
5610
- }
5611
- );
5612
- }
5613
- function SheetDescription({
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({
5614
6269
  className,
6270
+ orientation = "horizontal",
6271
+ decorative = true,
5615
6272
  ...props
5616
6273
  }) {
5617
- return /* @__PURE__ */ jsx33(
5618
- SheetPrimitive.Description,
6274
+ return /* @__PURE__ */ jsx36(
6275
+ SeparatorPrimitive.Root,
5619
6276
  {
5620
- "data-slot": "sheet-description",
5621
- className: cn("text-sm text-muted-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
+ ),
5622
6284
  ...props
5623
6285
  }
5624
6286
  );
5625
6287
  }
5626
6288
 
5627
- // src/components/ui/sheet-drawer.tsx
5628
- import { Maximize2Icon, Minimize2Icon, XIcon as XIcon3 } from "lucide-react";
5629
- import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
5630
- var sheetDrawerContentClassName = cn(
5631
- "gap-0 p-0",
5632
- "bg-[var(--bg-surface)] text-foreground",
5633
- "border-[var(--border)] shadow-[var(--shadow-4)]",
5634
- "min-[900px]:w-[480px] min-[900px]:max-w-[480px]",
5635
- "max-[899px]:h-[min(85dvh,720px)] max-[899px]:max-h-[85dvh] max-[899px]:w-full max-[899px]:max-w-none",
5636
- "max-[899px]:rounded-t-[var(--radius-lg)]"
5637
- );
5638
- var sheetDrawerWideContentClassName = "min-[900px]:w-[720px] min-[900px]:max-w-[720px]";
5639
- var sheetDrawerFullContentClassName = cn(
5640
- "min-[900px]:w-[calc(100vw_-_var(--space-8))] min-[900px]:max-w-[calc(100vw_-_var(--space-8))]",
5641
- "max-[899px]:h-[100dvh] max-[899px]:max-h-[100dvh] max-[899px]:rounded-none"
5642
- );
5643
- var sheetDrawerHeaderClassName = cn(
5644
- "flex items-start justify-between gap-[var(--space-4)]",
5645
- "border-b border-[var(--border)] px-[var(--space-6)] py-[var(--space-6)]"
5646
- );
5647
- var sheetDrawerHeaderTextClassName = "flex min-w-0 flex-1 flex-col gap-[var(--space-2)]";
5648
- var sheetDrawerCaptionClassName = "flex flex-wrap items-center gap-[var(--space-2)]";
5649
- var sheetDrawerTitleClassName = "text-[18px] font-bold leading-snug text-foreground";
5650
- var sheetDrawerDescriptionClassName = "break-keep text-[14px] leading-normal text-text-secondary";
5651
- var sheetDrawerCloseButtonClassName = cn(
5652
- "flex size-[32px] shrink-0 cursor-pointer items-center justify-center",
5653
- "rounded-[var(--radius-sm)] text-text-tertiary transition-colors",
5654
- "hover:bg-[var(--action-hover)] hover:text-foreground",
5655
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2"
5656
- );
5657
- var sheetDrawerHeaderActionsClassName = cn(
5658
- "flex shrink-0 items-center gap-[var(--space-1)]"
5659
- );
5660
- var sheetDrawerExpandButtonClassName = cn(
5661
- "inline-flex cursor-pointer items-center justify-center gap-[var(--space-1)]",
5662
- "rounded-[var(--radius-sm)] text-text-tertiary transition-colors",
5663
- "hover:bg-[var(--action-hover)] hover:text-foreground",
5664
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2",
5665
- "h-[32px] px-[var(--space-2)]"
5666
- );
5667
- var sheetDrawerBodyClassName = cn(
5668
- "min-h-0 flex-1 overflow-y-auto",
5669
- "px-[var(--space-6)] py-[var(--space-6)]"
5670
- );
5671
- var sheetDrawerFooterClassName = cn(
5672
- "border-t border-[var(--border)] px-[var(--space-6)] py-[var(--space-4)]",
5673
- "flex justify-end gap-[var(--space-2)]"
5674
- );
5675
- function SheetDrawer({
5676
- open,
5677
- onOpenChange,
5678
- caption,
5679
- title,
5680
- description,
5681
- children,
5682
- expandHref,
5683
- onExpand,
5684
- expandLabel = "\uD06C\uAC8C \uBCF4\uAE30",
5685
- expanded = false,
5686
- onExpandedChange,
5687
- collapseLabel = "\uC791\uAC8C \uBCF4\uAE30",
5688
- footer,
5689
- width = "default",
5690
- motion,
5691
- closeLabel = "\uB2EB\uAE30"
5692
- }) {
5693
- const hasExpandedToggle = typeof onExpandedChange === "function";
5694
- const showExpandAction = Boolean(hasExpandedToggle || expandHref || onExpand);
5695
- const resolvedWidth = expanded ? "full" : width;
5696
- const resolvedExpandLabel = hasExpandedToggle && expanded ? collapseLabel : expandLabel;
5697
- const ExpandActionIcon = hasExpandedToggle && expanded ? Minimize2Icon : Maximize2Icon;
5698
- return /* @__PURE__ */ jsx34(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs31(
5699
- SheetContent,
5700
- {
5701
- "data-slot": "sheet-drawer-content",
5702
- side: "right",
5703
- mobileSide: "bottom",
5704
- motion,
5705
- showCloseButton: false,
5706
- className: cn(
5707
- sheetDrawerContentClassName,
5708
- resolvedWidth === "wide" && sheetDrawerWideContentClassName,
5709
- resolvedWidth === "full" && sheetDrawerFullContentClassName
5710
- ),
5711
- children: [
5712
- /* @__PURE__ */ jsxs31("div", { "data-slot": "sheet-drawer-header", className: sheetDrawerHeaderClassName, children: [
5713
- /* @__PURE__ */ jsxs31("div", { className: sheetDrawerHeaderTextClassName, children: [
5714
- caption ? /* @__PURE__ */ jsx34("div", { "data-slot": "sheet-drawer-caption", className: sheetDrawerCaptionClassName, children: caption }) : null,
5715
- /* @__PURE__ */ jsx34(SheetTitle, { "data-slot": "sheet-drawer-title", className: sheetDrawerTitleClassName, children: title }),
5716
- description ? /* @__PURE__ */ jsx34(
5717
- SheetDescription,
5718
- {
5719
- "data-slot": "sheet-drawer-description",
5720
- className: sheetDrawerDescriptionClassName,
5721
- children: description
5722
- }
5723
- ) : null
5724
- ] }),
5725
- /* @__PURE__ */ jsxs31("div", { "data-slot": "sheet-drawer-header-actions", className: sheetDrawerHeaderActionsClassName, children: [
5726
- showExpandAction ? hasExpandedToggle ? /* @__PURE__ */ jsxs31(
5727
- "button",
5728
- {
5729
- type: "button",
5730
- "aria-label": resolvedExpandLabel,
5731
- "aria-pressed": expanded,
5732
- "data-slot": "sheet-drawer-expand",
5733
- "data-expanded": expanded ? "true" : "false",
5734
- className: sheetDrawerExpandButtonClassName,
5735
- onClick: () => onExpandedChange(!expanded),
5736
- children: [
5737
- /* @__PURE__ */ jsx34(ExpandActionIcon, { className: "size-[16px]" }),
5738
- /* @__PURE__ */ jsx34("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: resolvedExpandLabel })
5739
- ]
5740
- }
5741
- ) : expandHref ? /* @__PURE__ */ jsxs31(
5742
- "a",
5743
- {
5744
- href: expandHref,
5745
- "aria-label": expandLabel,
5746
- "data-slot": "sheet-drawer-expand",
5747
- className: sheetDrawerExpandButtonClassName,
5748
- children: [
5749
- /* @__PURE__ */ jsx34(ExpandActionIcon, { className: "size-[16px]" }),
5750
- /* @__PURE__ */ jsx34("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
5751
- ]
5752
- }
5753
- ) : /* @__PURE__ */ jsxs31(
5754
- "button",
5755
- {
5756
- type: "button",
5757
- "aria-label": expandLabel,
5758
- "data-slot": "sheet-drawer-expand",
5759
- className: sheetDrawerExpandButtonClassName,
5760
- onClick: onExpand,
5761
- children: [
5762
- /* @__PURE__ */ jsx34(ExpandActionIcon, { className: "size-[16px]" }),
5763
- /* @__PURE__ */ jsx34("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
5764
- ]
5765
- }
5766
- ) : null,
5767
- /* @__PURE__ */ jsx34(
5768
- SheetClose,
5769
- {
5770
- "aria-label": closeLabel,
5771
- "data-slot": "sheet-drawer-close",
5772
- className: sheetDrawerCloseButtonClassName,
5773
- children: /* @__PURE__ */ jsx34(XIcon3, { className: "size-[16px]" })
5774
- }
5775
- )
5776
- ] })
5777
- ] }),
5778
- /* @__PURE__ */ jsx34("div", { "data-slot": "sheet-drawer-body", className: sheetDrawerBodyClassName, children }),
5779
- footer ? /* @__PURE__ */ jsx34("div", { "data-slot": "sheet-drawer-footer", className: sheetDrawerFooterClassName, children: footer }) : null
5780
- ]
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({
6293
+ className,
6294
+ size = "md",
6295
+ ...props
6296
+ }) {
6297
+ return /* @__PURE__ */ jsx37(
6298
+ AvatarPrimitive.Root,
6299
+ {
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
5781
6311
  }
5782
- ) });
6312
+ );
5783
6313
  }
5784
-
5785
- // src/components/ui/popover.tsx
5786
- import * as React26 from "react";
5787
- import { Popover as PopoverPrimitive } from "radix-ui";
5788
- import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
5789
- function Popover({ modal = false, ...props }) {
5790
- 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
+ );
5791
6326
  }
5792
- var PopoverTrigger = PopoverPrimitive.Trigger;
5793
- var PopoverAnchor = PopoverPrimitive.Anchor;
5794
- var PopoverClose = PopoverPrimitive.Close;
5795
- var PopoverContent = React26.forwardRef(({ className, align = "center", sideOffset = 8, collisionPadding = 8, showArrow = false, children, ...props }, ref) => /* @__PURE__ */ jsx35(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsxs32(
5796
- PopoverPrimitive.Content,
5797
- {
5798
- ref,
5799
- align,
5800
- sideOffset,
5801
- collisionPadding,
5802
- "data-slot": "popover-content",
5803
- className: cn(
5804
- "z-[var(--z-popover)] w-[260px] outline-none",
5805
- "rounded-[var(--radius-md)] border border-[var(--border)]",
5806
- "bg-[var(--bg-raised)] p-[var(--space-4)] text-foreground",
5807
- "shadow-[var(--shadow-4)]",
5808
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
5809
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
5810
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
5811
- "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
5812
- "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
5813
- "motion-reduce:animate-none",
5814
- className
5815
- ),
5816
- ...props,
5817
- children: [
5818
- children,
5819
- showArrow ? /* @__PURE__ */ jsx35(
5820
- PopoverPrimitive.Arrow,
5821
- {
5822
- "data-slot": "popover-arrow",
5823
- className: "fill-[var(--bg-raised)]",
5824
- width: 11,
5825
- height: 5
5826
- }
5827
- ) : null
5828
- ]
5829
- }
5830
- ) }));
5831
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
5832
- var PopoverArrow = React26.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx35(
5833
- PopoverPrimitive.Arrow,
5834
- {
5835
- ref,
5836
- "data-slot": "popover-arrow",
5837
- className: cn("fill-[var(--bg-raised)]", className),
5838
- width: 11,
5839
- height: 5,
5840
- ...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;
5841
6333
  }
5842
- ));
5843
- 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
+ }
5844
6359
 
5845
6360
  // src/components/ui/badge.tsx
5846
- import * as React27 from "react";
5847
- 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";
5848
6363
  var DOT = {
5849
6364
  error: "var(--semantic-error-fg)",
5850
6365
  warning: "var(--semantic-warning-fg)",
@@ -5853,8 +6368,8 @@ var DOT = {
5853
6368
  neutral: "var(--text-tertiary)",
5854
6369
  brand: "var(--accent-pop)"
5855
6370
  };
5856
- var Badge = React27.forwardRef(
5857
- ({ tone = "neutral", className, children, ...props }, ref) => /* @__PURE__ */ jsxs33(
6371
+ var Badge = React29.forwardRef(
6372
+ ({ tone = "neutral", className, children, ...props }, ref) => /* @__PURE__ */ jsxs35(
5858
6373
  "span",
5859
6374
  {
5860
6375
  ref,
@@ -5868,7 +6383,7 @@ var Badge = React27.forwardRef(
5868
6383
  ),
5869
6384
  ...props,
5870
6385
  children: [
5871
- /* @__PURE__ */ jsx36(
6386
+ /* @__PURE__ */ jsx38(
5872
6387
  "span",
5873
6388
  {
5874
6389
  "aria-hidden": "true",
@@ -5885,8 +6400,8 @@ var Badge = React27.forwardRef(
5885
6400
  Badge.displayName = "Badge";
5886
6401
 
5887
6402
  // src/components/ui/two-tier-badge.tsx
5888
- import * as React28 from "react";
5889
- 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";
5890
6405
  var FG = {
5891
6406
  neutral: "var(--text-secondary)",
5892
6407
  info: "var(--semantic-info-fg)",
@@ -5907,7 +6422,7 @@ var SEGMENT = {
5907
6422
  md: "gap-[7px] py-[var(--space-1)] px-[var(--space-3)] text-[14px]"
5908
6423
  };
5909
6424
  var DOT2 = { xs: 5, sm: 6, md: 7 };
5910
- var TwoTierBadge = React28.forwardRef(
6425
+ var TwoTierBadge = React30.forwardRef(
5911
6426
  ({ primary, secondary, tone = "neutral", emphasis = "subtle", size = "sm", showDot = false, className, style, ...props }, ref) => {
5912
6427
  const strong = emphasis === "strong";
5913
6428
  const fg = FG[tone];
@@ -5916,7 +6431,7 @@ var TwoTierBadge = React28.forwardRef(
5916
6431
  const frame = strong ? tinted : "var(--border-subtle)";
5917
6432
  const divider = strong ? tinted : "var(--border)";
5918
6433
  const dotSize = DOT2[size];
5919
- return /* @__PURE__ */ jsxs34(
6434
+ return /* @__PURE__ */ jsxs36(
5920
6435
  "span",
5921
6436
  {
5922
6437
  ref,
@@ -5930,14 +6445,14 @@ var TwoTierBadge = React28.forwardRef(
5930
6445
  style: { fontFamily: "var(--font-sans)", borderColor: frame, background: "transparent", ...style },
5931
6446
  ...props,
5932
6447
  children: [
5933
- /* @__PURE__ */ jsxs34(
6448
+ /* @__PURE__ */ jsxs36(
5934
6449
  "span",
5935
6450
  {
5936
6451
  "data-slot": "two-tier-badge-primary",
5937
6452
  className: cn("inline-flex items-center whitespace-nowrap font-semibold", SEGMENT[size]),
5938
6453
  style: { color: fg, background: strong ? BG[tone] : "transparent" },
5939
6454
  children: [
5940
- showDot ? /* @__PURE__ */ jsx37(
6455
+ showDot ? /* @__PURE__ */ jsx39(
5941
6456
  "span",
5942
6457
  {
5943
6458
  "aria-hidden": "true",
@@ -5952,11 +6467,11 @@ var TwoTierBadge = React28.forwardRef(
5952
6467
  }
5953
6468
  }
5954
6469
  ) : null,
5955
- /* @__PURE__ */ jsx37("span", { children: primary })
6470
+ /* @__PURE__ */ jsx39("span", { children: primary })
5956
6471
  ]
5957
6472
  }
5958
6473
  ),
5959
- secondary != null ? /* @__PURE__ */ jsx37(
6474
+ secondary != null ? /* @__PURE__ */ jsx39(
5960
6475
  "span",
5961
6476
  {
5962
6477
  "data-slot": "two-tier-badge-secondary",
@@ -5977,8 +6492,8 @@ var TwoTierBadge = React28.forwardRef(
5977
6492
  TwoTierBadge.displayName = "TwoTierBadge";
5978
6493
 
5979
6494
  // src/components/ui/status-badge.tsx
5980
- import * as React29 from "react";
5981
- 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";
5982
6497
  var ROLE = {
5983
6498
  error: "error",
5984
6499
  warning: "warning",
@@ -6007,13 +6522,13 @@ var SIZE = {
6007
6522
  sm: { cls: "gap-[6px] py-[var(--space-1)] px-[var(--space-2)] text-[12px]", dot: 6 },
6008
6523
  md: { cls: "gap-[var(--space-2)] py-[var(--space-1)] px-[14px] text-[14px]", dot: 7 }
6009
6524
  };
6010
- var StatusBadge = React29.forwardRef(
6525
+ var StatusBadge = React31.forwardRef(
6011
6526
  ({ status = "active", emphasis = "subtle", size = "sm", showDot = true, pulse = true, className, children, style, ...props }, ref) => {
6012
6527
  const role = ROLE[status];
6013
6528
  const fg = FG2[role];
6014
6529
  const strong = emphasis === "strong";
6015
6530
  const ringDot = role === "neutral";
6016
- return /* @__PURE__ */ jsxs35(
6531
+ return /* @__PURE__ */ jsxs37(
6017
6532
  "span",
6018
6533
  {
6019
6534
  ref,
@@ -6031,7 +6546,7 @@ var StatusBadge = React29.forwardRef(
6031
6546
  },
6032
6547
  ...props,
6033
6548
  children: [
6034
- showDot ? /* @__PURE__ */ jsx38(
6549
+ showDot ? /* @__PURE__ */ jsx40(
6035
6550
  "span",
6036
6551
  {
6037
6552
  "aria-hidden": "true",
@@ -6049,7 +6564,7 @@ var StatusBadge = React29.forwardRef(
6049
6564
  }
6050
6565
  ) : null,
6051
6566
  children,
6052
- /* @__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}}" })
6053
6568
  ]
6054
6569
  }
6055
6570
  );
@@ -6058,10 +6573,10 @@ var StatusBadge = React29.forwardRef(
6058
6573
  StatusBadge.displayName = "StatusBadge";
6059
6574
 
6060
6575
  // src/components/ui/notification-badge.tsx
6061
- import * as React30 from "react";
6062
- import { cva as cva11 } from "class-variance-authority";
6063
- import { jsx as jsx39 } from "react/jsx-runtime";
6064
- 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(
6065
6580
  [
6066
6581
  "inline-flex shrink-0 items-center justify-center rounded-[var(--radius-full)]",
6067
6582
  "bg-[var(--semantic-error,var(--error))] text-[var(--error-contrast)]",
@@ -6071,255 +6586,63 @@ var notificationBadgeVariants = cva11(
6071
6586
  variants: {
6072
6587
  size: {
6073
6588
  sm: "h-[15px] min-w-[15px] px-[3px] text-[9px]",
6074
- md: "h-[18px] min-w-[18px] px-[3px] text-[10px]"
6075
- },
6076
- placement: {
6077
- corner: "absolute -right-[4px] -top-[4px]",
6078
- inline: "ml-auto",
6079
- none: ""
6080
- }
6081
- },
6082
- defaultVariants: {
6083
- size: "sm",
6084
- placement: "none"
6085
- }
6086
- }
6087
- );
6088
- function formatNotificationCount(count, max) {
6089
- if (count > max) {
6090
- return `${max}+`;
6091
- }
6092
- return String(count);
6093
- }
6094
- var NotificationBadge = React30.forwardRef(
6095
- ({
6096
- className,
6097
- count,
6098
- max = 99,
6099
- size = "sm",
6100
- placement = "none",
6101
- "aria-label": ariaLabel,
6102
- ...props
6103
- }, ref) => {
6104
- if (count <= 0) {
6105
- return null;
6106
- }
6107
- const normalizedMax = Math.max(1, Math.floor(max));
6108
- const label = ariaLabel ?? (count > normalizedMax ? `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${normalizedMax}\uAC1C \uC774\uC0C1` : `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${count}\uAC1C`);
6109
- return /* @__PURE__ */ jsx39(
6110
- "span",
6111
- {
6112
- ref,
6113
- "data-slot": "notification-badge",
6114
- "data-size": size,
6115
- "data-placement": placement,
6116
- "aria-label": label,
6117
- className: cn(notificationBadgeVariants({ size, placement, className })),
6118
- ...props,
6119
- children: formatNotificationCount(count, normalizedMax)
6120
- }
6121
- );
6122
- }
6123
- );
6124
- NotificationBadge.displayName = "NotificationBadge";
6125
-
6126
- // src/components/ui/chip.tsx
6127
- import * as React31 from "react";
6128
- import { cva as cva12 } from "class-variance-authority";
6129
- import { X as X3 } from "lucide-react";
6130
- import { Slot as Slot2 } from "radix-ui";
6131
- import { jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
6132
- var chipVariants = cva12(
6133
- [
6134
- "inline-flex w-fit shrink-0 items-center justify-center whitespace-nowrap",
6135
- "rounded-[var(--radius-full)] border leading-none",
6136
- "font-medium transition-colors motion-reduce:transition-none",
6137
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
6138
- "disabled:pointer-events-none disabled:opacity-50"
6139
- ].join(" "),
6140
- {
6141
- variants: {
6142
- variant: {
6143
- // interactive 3종 — 클릭 가능 (toggle / select / remove). cursor:pointer으로 affordance 명시.
6144
- // (Tailwind v4 preflight + site reset은 button cursor 보장 안 함 → variant level에서 강제.)
6145
- filter: "cursor-pointer",
6146
- choice: "cursor-pointer",
6147
- removable: "cursor-pointer",
6148
- // status-filter — 정적 표시 chip (display only, 클릭 affordance 없음).
6149
- "status-filter": "cursor-default"
6150
- },
6151
- tone: {
6152
- neutral: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-text-secondary hover:bg-[var(--action-hover)]",
6153
- accent: "border-[var(--border-accent)] bg-transparent text-[var(--accent)] hover:bg-[var(--action-accent-hover)]",
6154
- success: "border-transparent bg-[var(--success-bg)] text-[var(--success)] hover:bg-[var(--action-hover)]",
6155
- warning: "border-transparent bg-[var(--warning-bg)] text-[var(--warning)] hover:bg-[var(--action-hover)]",
6156
- danger: "border-transparent bg-[var(--error-bg)] text-[var(--error)] hover:bg-[var(--action-hover)]",
6157
- muted: "border-[var(--border-subtle)] bg-transparent text-text-tertiary hover:bg-[var(--action-hover)]"
6158
- },
6159
- size: {
6160
- sm: "h-[26px] gap-[var(--space-1)] px-[var(--space-2)] text-xs",
6161
- md: "h-[30px] gap-[var(--space-2)] px-[var(--space-3)] text-xs",
6162
- lg: "h-[34px] gap-[var(--space-2)] px-[var(--space-4)] text-sm"
6163
- },
6164
- pressed: {
6165
- true: "",
6166
- false: ""
6167
- }
6168
- },
6169
- compoundVariants: [
6170
- {
6171
- pressed: true,
6172
- tone: "neutral",
6173
- className: "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground"
6174
- },
6175
- {
6176
- // R10 — wash 패턴 정합 (--accent-bg-strong deep olive wash / --accent olive/lime text).
6177
- pressed: true,
6178
- tone: "accent",
6179
- className: "border-[var(--border-accent)] bg-[var(--accent-bg-strong)] text-[var(--accent)]"
6180
- },
6181
- {
6182
- pressed: true,
6183
- tone: "muted",
6184
- className: "border-[var(--border-strong)] bg-[var(--bg-raised)] text-text-secondary"
6185
- }
6186
- ],
6187
- defaultVariants: {
6188
- variant: "filter",
6189
- tone: "neutral",
6190
- size: "md",
6191
- pressed: false
6192
- }
6193
- }
6194
- );
6195
- var chipCountVariants = cva12(
6196
- [
6197
- "inline-flex min-w-[var(--space-4)] items-center justify-center",
6198
- "rounded-[var(--radius-full)] px-[var(--space-1)]",
6199
- "font-[family-name:var(--font-display)]"
6200
- ].join(" "),
6201
- {
6202
- variants: {
6203
- tone: {
6204
- neutral: "bg-[var(--bg-raised)] text-text-tertiary",
6205
- accent: "bg-[var(--accent-pop)] text-[var(--accent-on-fill)]",
6206
- success: "bg-[var(--success)] text-[var(--success-contrast)]",
6207
- warning: "bg-[var(--warning)] text-[var(--warning-contrast)]",
6208
- danger: "bg-[var(--error)] text-[var(--error-contrast)]",
6209
- muted: "bg-[var(--bg-raised)] text-text-tertiary"
6210
- },
6211
- size: {
6212
- sm: "h-[var(--space-4)] text-xs",
6213
- md: "h-[var(--space-4)] text-xs",
6214
- lg: "h-[calc(var(--space-4)+var(--space-1))] text-xs"
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: ""
6215
6595
  }
6216
6596
  },
6217
6597
  defaultVariants: {
6218
- tone: "neutral",
6219
- size: "md"
6598
+ size: "sm",
6599
+ placement: "none"
6220
6600
  }
6221
6601
  }
6222
6602
  );
6223
- 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(
6224
6610
  ({
6225
6611
  className,
6226
- variant = "filter",
6227
- tone = "neutral",
6228
- size = "md",
6229
- pressed = false,
6230
6612
  count,
6231
- removeLabel = "Remove",
6232
- asChild = false,
6233
- children,
6613
+ max = 99,
6614
+ size = "sm",
6615
+ placement = "none",
6616
+ "aria-label": ariaLabel,
6234
6617
  ...props
6235
6618
  }, ref) => {
6236
- const removable = variant === "removable";
6237
- if (removable) {
6238
- const {
6239
- onClick,
6240
- disabled,
6241
- type: _type,
6242
- autoFocus: _af,
6243
- form: _form,
6244
- name: _name,
6245
- value: _value,
6246
- ...spanProps
6247
- } = props;
6248
- return /* @__PURE__ */ jsxs36(
6249
- "span",
6250
- {
6251
- "data-slot": "chip",
6252
- "data-variant": variant,
6253
- "data-tone": tone,
6254
- className: cn(chipVariants({ variant, tone, size, pressed, className })),
6255
- ...spanProps,
6256
- children: [
6257
- /* @__PURE__ */ jsx40("span", { children }),
6258
- count !== void 0 ? /* @__PURE__ */ jsx40(
6259
- "span",
6260
- {
6261
- "aria-hidden": "true",
6262
- "data-slot": "chip-count",
6263
- "data-count-tone": tone,
6264
- className: chipCountVariants({ tone, size }),
6265
- children: count
6266
- }
6267
- ) : null,
6268
- /* @__PURE__ */ jsx40(
6269
- "button",
6270
- {
6271
- ref,
6272
- type: "button",
6273
- "data-slot": "chip-remove",
6274
- "aria-label": removeLabel,
6275
- disabled,
6276
- onClick,
6277
- 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)]",
6278
- children: /* @__PURE__ */ jsx40(X3, { "aria-hidden": "true", size: 14, strokeWidth: 2.25 })
6279
- }
6280
- )
6281
- ]
6282
- }
6283
- );
6619
+ if (count <= 0) {
6620
+ return null;
6284
6621
  }
6285
- const Comp = asChild ? Slot2.Root : "button";
6286
- return /* @__PURE__ */ jsxs36(
6287
- 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",
6288
6626
  {
6289
6627
  ref,
6290
- "data-slot": "chip",
6291
- "data-variant": variant,
6292
- "data-tone": tone,
6293
- "aria-pressed": pressed,
6294
- className: cn(
6295
- chipVariants({ variant, tone, size, pressed, className })
6296
- ),
6297
- 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 })),
6298
6633
  ...props,
6299
- children: [
6300
- children,
6301
- count !== void 0 ? /* @__PURE__ */ jsx40(
6302
- "span",
6303
- {
6304
- "aria-hidden": "true",
6305
- "data-slot": "chip-count",
6306
- "data-count-tone": tone,
6307
- className: chipCountVariants({ tone, size }),
6308
- children: count
6309
- }
6310
- ) : null
6311
- ]
6634
+ children: formatNotificationCount(count, normalizedMax)
6312
6635
  }
6313
6636
  );
6314
6637
  }
6315
6638
  );
6316
- Chip.displayName = "Chip";
6639
+ NotificationBadge.displayName = "NotificationBadge";
6317
6640
 
6318
6641
  // src/components/ui/empty-state.tsx
6319
- import * as React32 from "react";
6320
- import { cva as cva13 } from "class-variance-authority";
6321
- import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
6322
- 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(
6323
6646
  [
6324
6647
  "flex flex-col items-center justify-center text-center",
6325
6648
  "text-foreground"
@@ -6338,7 +6661,7 @@ var emptyStateBaseVariants = cva13(
6338
6661
  },
6339
6662
  defaultVariants: {
6340
6663
  size: "md",
6341
- bordered: true
6664
+ bordered: false
6342
6665
  }
6343
6666
  }
6344
6667
  );
@@ -6357,7 +6680,7 @@ function emptyStateVariants({
6357
6680
  size,
6358
6681
  tone = "neutral",
6359
6682
  surface,
6360
- bordered = true,
6683
+ bordered = false,
6361
6684
  className
6362
6685
  } = {}) {
6363
6686
  const hasBorder = bordered !== false;
@@ -6367,10 +6690,10 @@ function emptyStateVariants({
6367
6690
  className
6368
6691
  );
6369
6692
  }
6370
- var emptyStateIconVariants = cva13(
6693
+ var emptyStateIconVariants = cva14(
6371
6694
  [
6372
6695
  "inline-flex items-center justify-center rounded-[var(--radius-full)]",
6373
- "border border-[var(--border-subtle)] bg-[var(--bg-raised)] text-text-tertiary"
6696
+ "border border-[var(--border-subtle)] bg-[var(--bg-inset)] text-text-tertiary"
6374
6697
  ].join(" "),
6375
6698
  {
6376
6699
  variants: {
@@ -6385,12 +6708,12 @@ var emptyStateIconVariants = cva13(
6385
6708
  }
6386
6709
  }
6387
6710
  );
6388
- var iconSize2 = {
6711
+ var iconSize3 = {
6389
6712
  sm: 18,
6390
6713
  md: 20,
6391
6714
  lg: 24
6392
6715
  };
6393
- var EmptyState = React32.forwardRef(
6716
+ var EmptyState = React33.forwardRef(
6394
6717
  ({
6395
6718
  className,
6396
6719
  size = "md",
@@ -6401,11 +6724,11 @@ var EmptyState = React32.forwardRef(
6401
6724
  description,
6402
6725
  hint,
6403
6726
  action,
6404
- bordered = true,
6727
+ bordered = false,
6405
6728
  ...props
6406
6729
  }, ref) => {
6407
6730
  const resolvedSize = size ?? "md";
6408
- return /* @__PURE__ */ jsxs37(
6731
+ return /* @__PURE__ */ jsxs38(
6409
6732
  "div",
6410
6733
  {
6411
6734
  ref,
@@ -6414,17 +6737,17 @@ var EmptyState = React32.forwardRef(
6414
6737
  className: cn(emptyStateVariants({ size, tone, surface, bordered, className })),
6415
6738
  ...props,
6416
6739
  children: [
6417
- Icon ? /* @__PURE__ */ jsx41(
6740
+ Icon ? /* @__PURE__ */ jsx42(
6418
6741
  "span",
6419
6742
  {
6420
6743
  "aria-hidden": "true",
6421
6744
  "data-slot": "empty-state-icon",
6422
6745
  className: emptyStateIconVariants({ size: resolvedSize }),
6423
- children: /* @__PURE__ */ jsx41(Icon, { size: iconSize2[resolvedSize], strokeWidth: 1.75 })
6746
+ children: /* @__PURE__ */ jsx42(Icon, { size: iconSize3[resolvedSize], strokeWidth: 1.75 })
6424
6747
  }
6425
6748
  ) : null,
6426
- /* @__PURE__ */ jsxs37("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
6427
- /* @__PURE__ */ jsx41(
6749
+ /* @__PURE__ */ jsxs38("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
6750
+ /* @__PURE__ */ jsx42(
6428
6751
  "h2",
6429
6752
  {
6430
6753
  "data-slot": "empty-state-title",
@@ -6432,7 +6755,7 @@ var EmptyState = React32.forwardRef(
6432
6755
  children: title
6433
6756
  }
6434
6757
  ),
6435
- description ? /* @__PURE__ */ jsx41(
6758
+ description ? /* @__PURE__ */ jsx42(
6436
6759
  "p",
6437
6760
  {
6438
6761
  "data-slot": "empty-state-description",
@@ -6440,7 +6763,7 @@ var EmptyState = React32.forwardRef(
6440
6763
  children: description
6441
6764
  }
6442
6765
  ) : null,
6443
- hint ? /* @__PURE__ */ jsx41(
6766
+ hint ? /* @__PURE__ */ jsx42(
6444
6767
  "p",
6445
6768
  {
6446
6769
  "data-slot": "empty-state-hint",
@@ -6449,7 +6772,7 @@ var EmptyState = React32.forwardRef(
6449
6772
  }
6450
6773
  ) : null
6451
6774
  ] }),
6452
- 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
6453
6776
  ]
6454
6777
  }
6455
6778
  );
@@ -6458,11 +6781,11 @@ var EmptyState = React32.forwardRef(
6458
6781
  EmptyState.displayName = "EmptyState";
6459
6782
 
6460
6783
  // src/components/ui/error-state.tsx
6461
- import * as React33 from "react";
6784
+ import * as React34 from "react";
6462
6785
  import { AlertTriangle } from "lucide-react";
6463
- import { cva as cva14 } from "class-variance-authority";
6464
- import { jsx as jsx42, jsxs as jsxs38 } from "react/jsx-runtime";
6465
- 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(
6466
6789
  [
6467
6790
  "flex flex-col items-center justify-center text-center",
6468
6791
  "rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
@@ -6483,7 +6806,7 @@ var errorStateVariants = cva14(
6483
6806
  }
6484
6807
  }
6485
6808
  );
6486
- var ErrorState = React33.forwardRef(
6809
+ var ErrorState = React34.forwardRef(
6487
6810
  ({
6488
6811
  className,
6489
6812
  size = "md",
@@ -6494,7 +6817,7 @@ var ErrorState = React33.forwardRef(
6494
6817
  onRetry,
6495
6818
  retryLabel = "\uB2E4\uC2DC \uC2DC\uB3C4",
6496
6819
  ...props
6497
- }, ref) => /* @__PURE__ */ jsxs38(
6820
+ }, ref) => /* @__PURE__ */ jsxs39(
6498
6821
  "div",
6499
6822
  {
6500
6823
  ref,
@@ -6503,17 +6826,17 @@ var ErrorState = React33.forwardRef(
6503
6826
  className: cn(errorStateVariants({ size, surface, className })),
6504
6827
  ...props,
6505
6828
  children: [
6506
- /* @__PURE__ */ jsx42(
6829
+ /* @__PURE__ */ jsx43(
6507
6830
  "span",
6508
6831
  {
6509
6832
  "aria-hidden": "true",
6510
6833
  "data-slot": "error-state-icon",
6511
6834
  className: "inline-flex size-[48px] items-center justify-center rounded-[var(--radius-full)] bg-[var(--error-bg)] text-[var(--error)]",
6512
- children: /* @__PURE__ */ jsx42(AlertTriangle, { size: 24, strokeWidth: 1.75 })
6835
+ children: /* @__PURE__ */ jsx43(AlertTriangle, { size: 24, strokeWidth: 1.75 })
6513
6836
  }
6514
6837
  ),
6515
- /* @__PURE__ */ jsxs38("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
6516
- /* @__PURE__ */ jsx42(
6838
+ /* @__PURE__ */ jsxs39("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
6839
+ /* @__PURE__ */ jsx43(
6517
6840
  "h2",
6518
6841
  {
6519
6842
  "data-slot": "error-state-title",
@@ -6521,7 +6844,7 @@ var ErrorState = React33.forwardRef(
6521
6844
  children: title
6522
6845
  }
6523
6846
  ),
6524
- /* @__PURE__ */ jsx42(
6847
+ /* @__PURE__ */ jsx43(
6525
6848
  "p",
6526
6849
  {
6527
6850
  "data-slot": "error-state-message",
@@ -6529,7 +6852,7 @@ var ErrorState = React33.forwardRef(
6529
6852
  children: message
6530
6853
  }
6531
6854
  ),
6532
- errorCode ? /* @__PURE__ */ jsx42(
6855
+ errorCode ? /* @__PURE__ */ jsx43(
6533
6856
  "p",
6534
6857
  {
6535
6858
  "data-slot": "error-state-code",
@@ -6538,7 +6861,7 @@ var ErrorState = React33.forwardRef(
6538
6861
  }
6539
6862
  ) : null
6540
6863
  ] }),
6541
- 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
6542
6865
  ]
6543
6866
  }
6544
6867
  )
@@ -6546,10 +6869,10 @@ var ErrorState = React33.forwardRef(
6546
6869
  ErrorState.displayName = "ErrorState";
6547
6870
 
6548
6871
  // src/components/ui/skeleton.tsx
6549
- import * as React34 from "react";
6550
- import { cva as cva15 } from "class-variance-authority";
6551
- import { jsx as jsx43 } from "react/jsx-runtime";
6552
- 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(
6553
6876
  [
6554
6877
  "animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-raised)]",
6555
6878
  "motion-reduce:animate-none motion-reduce:opacity-80"
@@ -6567,7 +6890,7 @@ var skeletonVariants = cva15(
6567
6890
  }
6568
6891
  }
6569
6892
  );
6570
- var spinnerVariants = cva15(
6893
+ var spinnerVariants = cva16(
6571
6894
  [
6572
6895
  "inline-block shrink-0 animate-spin rounded-[var(--radius-full)] border-2",
6573
6896
  "border-[var(--border-subtle)] border-t-[var(--primary)]",
@@ -6590,8 +6913,8 @@ var spinnerVariants = cva15(
6590
6913
  }
6591
6914
  }
6592
6915
  );
6593
- var Skeleton = React34.forwardRef(
6594
- ({ className, shape, style, ...props }, ref) => /* @__PURE__ */ jsx43(
6916
+ var Skeleton = React35.forwardRef(
6917
+ ({ className, shape, style, ...props }, ref) => /* @__PURE__ */ jsx44(
6595
6918
  "div",
6596
6919
  {
6597
6920
  ref,
@@ -6604,15 +6927,15 @@ var Skeleton = React34.forwardRef(
6604
6927
  );
6605
6928
  Skeleton.displayName = "Skeleton";
6606
6929
  var defaultTextWidths = ["92%", "84%", "68%", "76%"];
6607
- var SkeletonText = React34.forwardRef(
6608
- ({ className, lines = 3, widths = defaultTextWidths, ...props }, ref) => /* @__PURE__ */ jsx43(
6930
+ var SkeletonText = React35.forwardRef(
6931
+ ({ className, lines = 3, widths = defaultTextWidths, ...props }, ref) => /* @__PURE__ */ jsx44(
6609
6932
  "div",
6610
6933
  {
6611
6934
  ref,
6612
6935
  "data-slot": "skeleton-text",
6613
6936
  className: cn("flex flex-col gap-[var(--space-2)]", className),
6614
6937
  ...props,
6615
- children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx43(
6938
+ children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx44(
6616
6939
  Skeleton,
6617
6940
  {
6618
6941
  shape: "text",
@@ -6624,7 +6947,7 @@ var SkeletonText = React34.forwardRef(
6624
6947
  )
6625
6948
  );
6626
6949
  SkeletonText.displayName = "SkeletonText";
6627
- var SkeletonRow = React34.forwardRef(
6950
+ var SkeletonRow = React35.forwardRef(
6628
6951
  ({
6629
6952
  className,
6630
6953
  columns,
@@ -6635,7 +6958,7 @@ var SkeletonRow = React34.forwardRef(
6635
6958
  }, ref) => {
6636
6959
  const rowCount = Math.max(5, count);
6637
6960
  const gridTemplateColumns = columns.map((column) => column.width ?? "1fr").join(" ");
6638
- return /* @__PURE__ */ jsx43(
6961
+ return /* @__PURE__ */ jsx44(
6639
6962
  "div",
6640
6963
  {
6641
6964
  ref,
@@ -6649,7 +6972,7 @@ var SkeletonRow = React34.forwardRef(
6649
6972
  className
6650
6973
  ),
6651
6974
  ...props,
6652
- children: Array.from({ length: rowCount }, (_, rowIndex) => /* @__PURE__ */ jsx43(
6975
+ children: Array.from({ length: rowCount }, (_, rowIndex) => /* @__PURE__ */ jsx44(
6653
6976
  "div",
6654
6977
  {
6655
6978
  "data-slot": "skeleton-row",
@@ -6657,11 +6980,11 @@ var SkeletonRow = React34.forwardRef(
6657
6980
  "grid min-h-[48px] items-center border-t border-[var(--border-subtle)] first:border-t-0"
6658
6981
  ),
6659
6982
  style: { gridTemplateColumns },
6660
- children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx43(
6983
+ children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx44(
6661
6984
  "div",
6662
6985
  {
6663
6986
  className: "px-[var(--space-4)] py-[var(--space-2)]",
6664
- children: /* @__PURE__ */ jsx43(
6987
+ children: /* @__PURE__ */ jsx44(
6665
6988
  Skeleton,
6666
6989
  {
6667
6990
  shape: "text",
@@ -6681,8 +7004,8 @@ var SkeletonRow = React34.forwardRef(
6681
7004
  }
6682
7005
  );
6683
7006
  SkeletonRow.displayName = "SkeletonRow";
6684
- var Spinner = React34.forwardRef(
6685
- ({ 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(
6686
7009
  "span",
6687
7010
  {
6688
7011
  ref,
@@ -6696,150 +7019,6 @@ var Spinner = React34.forwardRef(
6696
7019
  );
6697
7020
  Spinner.displayName = "Spinner";
6698
7021
 
6699
- // src/components/ui/icon-button.tsx
6700
- import * as React35 from "react";
6701
- import { cva as cva16 } from "class-variance-authority";
6702
- import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
6703
- var iconButtonVariants = cva16(
6704
- [
6705
- "olun-icon-button relative inline-flex cursor-pointer shrink-0 items-center justify-center",
6706
- "rounded-[var(--radius-sm)] border font-medium",
6707
- "transition-colors motion-reduce:transition-none",
6708
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
6709
- "disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled",
6710
- "[&_svg]:pointer-events-none [&_svg]:shrink-0"
6711
- ].join(" "),
6712
- {
6713
- variants: {
6714
- variant: {
6715
- ghost: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
6716
- 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",
6717
- subtle: "border-transparent bg-[var(--bg-raised)] text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
6718
- danger: "border-transparent bg-[var(--error-bg)] text-[var(--error)] hover:bg-[var(--action-hover)]"
6719
- },
6720
- size: {
6721
- sm: "size-[28px]",
6722
- md: "size-[32px]",
6723
- lg: "size-[40px]"
6724
- },
6725
- pressed: {
6726
- true: "",
6727
- false: ""
6728
- }
6729
- },
6730
- compoundVariants: [
6731
- {
6732
- pressed: true,
6733
- variant: ["ghost", "outline", "subtle"],
6734
- className: "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground"
6735
- },
6736
- {
6737
- pressed: true,
6738
- variant: "danger",
6739
- className: "border-[var(--error)] bg-[var(--error-bg)] text-[var(--error)]"
6740
- }
6741
- ],
6742
- defaultVariants: {
6743
- variant: "ghost",
6744
- size: "md",
6745
- pressed: false
6746
- }
6747
- }
6748
- );
6749
- var iconButtonBadgeVariants = cva16(
6750
- [
6751
- "pointer-events-none absolute right-0 top-0 inline-flex",
6752
- "olun-icon-button__badge",
6753
- "min-h-[var(--space-3)] min-w-[var(--space-3)] translate-x-1/3 -translate-y-1/3",
6754
- "items-center justify-center gap-[2px] rounded-[var(--radius-full)] px-[3px]",
6755
- "font-[family-name:var(--font-display)] text-[10px] font-semibold leading-none",
6756
- "[&:has(svg)]:size-[var(--space-3)] [&:has(svg)]:px-0 [&_svg]:size-[10px]"
6757
- ].join(" "),
6758
- {
6759
- variants: {
6760
- tone: {
6761
- info: "bg-[var(--accent-pop)] text-[var(--accent-on-fill)]",
6762
- error: "bg-[var(--error)] text-[var(--error-contrast)]"
6763
- }
6764
- },
6765
- defaultVariants: {
6766
- tone: "info"
6767
- }
6768
- }
6769
- );
6770
- var iconSize3 = {
6771
- sm: 14,
6772
- md: 16,
6773
- lg: 18
6774
- };
6775
- var iconStrokeWidth = {
6776
- sm: 2.25,
6777
- md: 2.25,
6778
- lg: 1.75
6779
- };
6780
- var IconButton = React35.forwardRef(
6781
- ({
6782
- className,
6783
- variant = "ghost",
6784
- size = "md",
6785
- pressed = void 0,
6786
- icon: Icon,
6787
- badge,
6788
- badgeTone = "info",
6789
- type,
6790
- title,
6791
- "aria-label": ariaLabel,
6792
- "aria-labelledby": ariaLabelledBy,
6793
- ...props
6794
- }, ref) => {
6795
- const resolvedSize = size ?? "md";
6796
- const isToggle = pressed !== void 0;
6797
- const isPressed = pressed === true;
6798
- const hoverTitle = title ?? (typeof ariaLabel === "string" ? ariaLabel : void 0);
6799
- return /* @__PURE__ */ jsxs39(
6800
- "button",
6801
- {
6802
- ref,
6803
- ...props,
6804
- "data-slot": "icon-button",
6805
- "data-variant": variant,
6806
- "data-size": resolvedSize,
6807
- "data-pressed": isToggle ? String(isPressed) : void 0,
6808
- "aria-label": ariaLabel,
6809
- "aria-labelledby": ariaLabelledBy,
6810
- "aria-pressed": isToggle ? isPressed : void 0,
6811
- title: hoverTitle,
6812
- className: cn(
6813
- iconButtonVariants({ variant, size, pressed: isPressed, className })
6814
- ),
6815
- type: type ?? "button",
6816
- children: [
6817
- /* @__PURE__ */ jsx44(
6818
- Icon,
6819
- {
6820
- "aria-hidden": "true",
6821
- "data-slot": "icon-button-icon",
6822
- size: iconSize3[resolvedSize],
6823
- strokeWidth: iconStrokeWidth[resolvedSize]
6824
- }
6825
- ),
6826
- badge !== void 0 ? /* @__PURE__ */ jsx44(
6827
- "span",
6828
- {
6829
- "aria-hidden": "true",
6830
- "data-slot": "icon-button-badge",
6831
- "data-badge-tone": badgeTone,
6832
- className: iconButtonBadgeVariants({ tone: badgeTone }),
6833
- children: badge
6834
- }
6835
- ) : null
6836
- ]
6837
- }
6838
- );
6839
- }
6840
- );
6841
- IconButton.displayName = "IconButton";
6842
-
6843
7022
  // src/components/ui/pagination.tsx
6844
7023
  import * as React36 from "react";
6845
7024
  import { ChevronsLeft, ChevronLeft, ChevronRight as ChevronRight2, ChevronsRight } from "lucide-react";
@@ -7367,11 +7546,11 @@ var toastVariants = cva20(
7367
7546
  {
7368
7547
  variants: {
7369
7548
  variant: {
7370
- default: "bg-[var(--bg-raised)]",
7371
- success: "bg-[var(--bg-raised)]",
7549
+ default: "bg-[var(--bg-surface)]",
7550
+ success: "bg-[var(--bg-surface)]",
7372
7551
  error: "bg-[var(--error-bg)]",
7373
- warning: "bg-[var(--bg-raised)]",
7374
- info: "bg-[var(--bg-raised)]"
7552
+ warning: "bg-[var(--bg-surface)]",
7553
+ info: "bg-[var(--bg-surface)]"
7375
7554
  }
7376
7555
  },
7377
7556
  defaultVariants: { variant: "default" }
@@ -7610,7 +7789,7 @@ function ToastProvider({ children, maxToasts = 3, className, ...props }) {
7610
7789
  import * as React39 from "react";
7611
7790
  import { cva as cva21 } from "class-variance-authority";
7612
7791
  import { AlertCircle as AlertCircle4 } from "lucide-react";
7613
- 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";
7614
7793
  var otpFieldVariants = cva21("flex w-full min-w-0 flex-col gap-[var(--space-3)]", {
7615
7794
  variants: {
7616
7795
  size: {
@@ -7932,7 +8111,7 @@ var OTPField = React39.forwardRef(
7932
8111
  "data-slot": "otp-field-message",
7933
8112
  "data-kind": errorText ? "error" : "helper",
7934
8113
  className: otpFieldMessageVariants({ state: resolvedState }),
7935
- children: errorText ? /* @__PURE__ */ jsxs45(Fragment8, { children: [
8114
+ children: errorText ? /* @__PURE__ */ jsxs45(Fragment9, { children: [
7936
8115
  /* @__PURE__ */ jsx50(
7937
8116
  AlertCircle4,
7938
8117
  {
@@ -8269,8 +8448,8 @@ var radioVariants = cva24(
8269
8448
  plain: "inline-flex items-start gap-[var(--space-3)] rounded-[var(--radius-sm)] px-pad-compact-x py-pad-compact-y",
8270
8449
  card: [
8271
8450
  "flex min-h-[calc(var(--space-12)+var(--space-2))] items-start gap-[var(--space-3)]",
8272
- "rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-base)]",
8273
- "hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)]",
8451
+ "rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-surface)]",
8452
+ "hover:bg-[var(--action-hover)]",
8274
8453
  "data-[state=checked]:border-[var(--border-strong)] data-[state=checked]:bg-[var(--action-selected)]",
8275
8454
  "disabled:border-[var(--border-subtle)] disabled:bg-[var(--action-disabled-bg)]",
8276
8455
  "disabled:data-[state=checked]:border-[var(--border-subtle)] disabled:data-[state=checked]:bg-[var(--action-disabled-bg)]"