@olundot/ui 0.17.1 → 0.19.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
@@ -186,10 +186,63 @@ import * as React from "react";
186
186
  import { cva } from "class-variance-authority";
187
187
  import { Loader2 } from "lucide-react";
188
188
  import { Slot } from "radix-ui";
189
+
190
+ // src/components/ui/action-variants.ts
191
+ var actionPaint = {
192
+ // = Button `primary`
193
+ filledPrimary: "border-[var(--primary)] bg-[var(--primary)] text-[var(--primary-fg)] hover:bg-[var(--primary-hover)] hover:border-[var(--primary-hover)]",
194
+ // = IconButton `subtle`; the transparent 1px border keeps Button's box model
195
+ filledNeutral: "border-transparent bg-[var(--bg-inset)] text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
196
+ // = Button `danger`
197
+ filledDanger: "border-[var(--error)] bg-[var(--error)] text-[var(--error-contrast)] hover:bg-[var(--error-hover)] hover:border-[var(--error-hover)]",
198
+ // = Button `secondary`
199
+ outlineNeutral: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-foreground hover:border-[var(--border)] hover:bg-[var(--action-hover)]",
200
+ // = Button and IconButton `ghost`
201
+ ghostNeutral: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground"
202
+ };
203
+ var actionAxisVariants = {
204
+ appearance: { filled: "", outline: "", ghost: "" },
205
+ tone: { primary: "", neutral: "", danger: "" }
206
+ };
207
+ var actionCompoundVariants = [
208
+ { appearance: "filled", tone: "primary", className: actionPaint.filledPrimary },
209
+ { appearance: "filled", tone: "neutral", className: actionPaint.filledNeutral },
210
+ { appearance: "filled", tone: "danger", className: actionPaint.filledDanger },
211
+ { appearance: "outline", tone: "neutral", className: actionPaint.outlineNeutral },
212
+ { appearance: "ghost", tone: "neutral", className: actionPaint.ghostNeutral }
213
+ ];
214
+ function resolveActionStyle(appearance, tone, fallback) {
215
+ const resolvedAppearance = appearance ?? fallback;
216
+ return {
217
+ appearance: resolvedAppearance,
218
+ tone: tone ?? (resolvedAppearance === "filled" ? "primary" : "neutral")
219
+ };
220
+ }
221
+
222
+ // src/components/ui/button.tsx
189
223
  import { jsx, jsxs } from "react/jsx-runtime";
190
- var buttonVariants = cva(
224
+ var buttonSizeMd = "h-[32px] gap-[6px] px-pad-default-x text-body-sm [&_svg]:size-[16px]";
225
+ var buttonSizes = {
226
+ // Cross-control height map: Button sm/md/lg match field controls sm/md/lg (30/32/36px).
227
+ // Height comes from h-* alone — no vertical padding (py-12 inside h-32 left a 6px content box).
228
+ // xs/sm: invisible ::before stretches the hit area to 44px tall (#69), vertically only so
229
+ // side-by-side buttons never overlap. Its inset is measured from the padding box, inside
230
+ // the 1px border every variant carries: inset = (44 - (height - 2 × 1px)) / 2.
231
+ // IconButton with text reuses these through `buttonSizeClassName`.
232
+ xs: "relative h-[28px] gap-[6px] px-pad-compact-x text-[12px] before:absolute before:inset-x-0 before:-inset-y-[9px] before:content-[''] [&_svg]:size-[14px] [&_svg]:stroke-[1.75]",
233
+ sm: "relative h-[30px] gap-[6px] px-pad-compact-x text-body-sm before:absolute before:inset-x-0 before:-inset-y-[8px] before:content-[''] [&_svg]:size-[16px]",
234
+ md: buttonSizeMd,
235
+ lg: "h-[36px] gap-[var(--space-2)] px-pad-default-x text-[15px] [&_svg]:size-[18px]",
236
+ xl: "h-[40px] gap-[var(--space-2)] px-5 text-[15px] [&_svg]:size-[18px]",
237
+ default: buttonSizeMd,
238
+ /** @deprecated Use IconButton `size="lg"`. */
239
+ icon: "size-[36px] p-0 [&_svg]:size-[18px]",
240
+ /** @deprecated Use IconButton `size="md"`. */
241
+ "icon-xs": "size-[32px] p-0 [&_svg]:size-[14px] [&_svg]:stroke-[1.75]"
242
+ };
243
+ var buttonCva = cva(
191
244
  [
192
- "inline-flex cursor-pointer items-center justify-center whitespace-nowrap rounded-[var(--radius-sm)] border font-medium",
245
+ "inline-flex cursor-pointer items-center justify-center whitespace-nowrap rounded-[var(--radius-md)] border font-medium",
193
246
  "transition-[background-color,border-color,color,box-shadow,transform] motion-reduce:transition-none",
194
247
  "focus-visible:outline-none focus-visible:border-[var(--focus-ring)] focus-visible:shadow-[0_0_0_2px_var(--focus-ring)]",
195
248
  "active:scale-[0.98] disabled:active:scale-100 aria-disabled:active:scale-100",
@@ -199,37 +252,50 @@ var buttonVariants = cva(
199
252
  ].join(" "),
200
253
  {
201
254
  variants: {
255
+ // Legacy single axis, deprecated in 0.19 for `appearance` × `tone` and removed in 0.20.
256
+ // Frozen at 0.18; button-appearance.test.tsx keeps each value equal to its new pair.
202
257
  variant: {
258
+ /** @deprecated Use `appearance="filled" tone="primary"`. */
203
259
  primary: "border-[var(--primary)] bg-[var(--primary)] text-[var(--primary-fg)] hover:bg-[var(--primary-hover)] hover:border-[var(--primary-hover)]",
260
+ /** @deprecated Use `appearance="outline" tone="neutral"`. */
204
261
  outline: "border-[var(--border)] bg-transparent text-foreground hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)]",
262
+ /** @deprecated Use `appearance="ghost" tone="neutral"`. */
205
263
  ghost: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
264
+ /** @deprecated Use `appearance="filled" tone="danger"`. */
206
265
  danger: "border-[var(--error)] bg-[var(--error)] text-[var(--error-contrast)] hover:bg-[var(--error-hover)] hover:border-[var(--error-hover)]",
266
+ /** @deprecated Use `appearance="filled" tone="danger"`. */
207
267
  emergency: "border-[var(--error)] bg-[var(--error)] text-[var(--error-contrast)] hover:bg-[var(--error-hover)] hover:border-[var(--error-hover)]",
268
+ /** @deprecated Use `appearance="outline" tone="neutral"`. */
208
269
  subtle: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-foreground hover:border-[var(--border)] hover:bg-[var(--action-hover)]",
270
+ /** @deprecated Use `appearance="filled" tone="primary"`. */
209
271
  default: "border-[var(--primary)] bg-[var(--primary)] text-[var(--primary-fg)] hover:bg-[var(--primary-hover)] hover:border-[var(--primary-hover)]",
272
+ /** @deprecated Use `appearance="filled" tone="danger"`. */
210
273
  destructive: "border-[var(--error)] bg-[var(--error)] text-[var(--error-contrast)] hover:bg-[var(--error-hover)] hover:border-[var(--error-hover)]",
274
+ /** @deprecated Use `appearance="outline" tone="neutral"`. */
211
275
  secondary: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-foreground hover:border-[var(--border)] hover:bg-[var(--action-hover)]",
276
+ /** @deprecated No replacement on Button; a link component is planned. */
212
277
  link: "border-transparent bg-transparent px-0 text-[var(--accent)] underline-offset-4 hover:underline"
213
278
  },
214
- size: {
215
- // Cross-control height map: Button sm/md/lg match field controls sm/md/lg (30/32/36px).
216
- // Height comes from h-* alone — no vertical padding (py-12 inside h-32 left a 6px content box).
217
- xs: "h-[28px] gap-[6px] px-pad-compact-x text-[12px] [&_svg]:size-[14px] [&_svg]:stroke-[1.75]",
218
- sm: "h-[30px] gap-[6px] px-pad-compact-x text-body-sm [&_svg]:size-[16px]",
219
- md: "h-[32px] gap-[6px] px-pad-default-x text-body-sm [&_svg]:size-[16px]",
220
- lg: "h-[36px] gap-[var(--space-2)] px-pad-default-x text-[15px] [&_svg]:size-[18px]",
221
- xl: "h-[40px] gap-[var(--space-2)] px-5 text-[15px] [&_svg]:size-[18px]",
222
- default: "h-[32px] gap-[6px] px-pad-default-x text-body-sm [&_svg]:size-[16px]",
223
- icon: "size-[36px] p-0 [&_svg]:size-[18px]",
224
- "icon-xs": "size-[32px] p-0 [&_svg]:size-[14px] [&_svg]:stroke-[1.75]"
225
- }
279
+ ...actionAxisVariants,
280
+ size: buttonSizes
226
281
  },
282
+ compoundVariants: [...actionCompoundVariants],
227
283
  defaultVariants: {
228
284
  variant: "primary",
229
285
  size: "md"
230
286
  }
231
287
  }
232
288
  );
289
+ function buttonVariants(options) {
290
+ if (options?.appearance == null && options?.tone == null) return buttonCva(options);
291
+ return buttonCva({
292
+ ...options,
293
+ ...resolveActionStyle(options.appearance, options.tone, "filled"),
294
+ variant: null
295
+ });
296
+ }
297
+ var buttonSizeClassName = (size) => buttonSizes[size];
298
+ var footerButtonHitAreaClassName = "relative before:absolute before:inset-x-0 before:-inset-y-[5px] before:content-['']";
233
299
  var Button = React.forwardRef(
234
300
  ({
235
301
  asChild = false,
@@ -241,6 +307,8 @@ var Button = React.forwardRef(
241
307
  trailingIcon: TrailingIcon,
242
308
  type = "button",
243
309
  variant,
310
+ appearance,
311
+ tone,
244
312
  size,
245
313
  style,
246
314
  ...props
@@ -275,7 +343,7 @@ var Button = React.forwardRef(
275
343
  "aria-disabled": isDisabled ? true : void 0,
276
344
  disabled: !asChild ? isDisabled : void 0,
277
345
  type: !asChild ? type : void 0,
278
- className: cn(buttonVariants({ variant, size, className })),
346
+ className: cn(buttonVariants({ variant, appearance, tone, size, className })),
279
347
  style: frozenStyle ? { ...frozenStyle, ...style } : style,
280
348
  ...props,
281
349
  children: [
@@ -325,7 +393,7 @@ var CopyButton = React2.forwardRef(
325
393
  onCopied,
326
394
  size = "sm",
327
395
  value,
328
- variant = "outline",
396
+ variant = "secondary",
329
397
  ...props
330
398
  }, ref) => {
331
399
  const [copied, setCopied] = React2.useState(false);
@@ -611,7 +679,7 @@ var fileUploadZoneVariants = cva3(
611
679
  variants: {
612
680
  size: {
613
681
  default: "gap-[var(--space-2)] rounded-[var(--radius-md)] px-[var(--space-6)] py-[var(--space-10)]",
614
- compact: "gap-[var(--space-1)] rounded-[var(--radius-sm)] px-[var(--space-4)] py-[20px]"
682
+ compact: "gap-[var(--space-1)] rounded-[var(--radius-md)] px-[var(--space-4)] py-[20px]"
615
683
  },
616
684
  surface: surfaceClassNames
617
685
  },
@@ -1046,7 +1114,7 @@ function DismissButton({
1046
1114
  marginTop: -1,
1047
1115
  alignItems: "center",
1048
1116
  justifyContent: "center",
1049
- borderRadius: "var(--radius-sm)",
1117
+ borderRadius: "var(--radius-md)",
1050
1118
  border: 0,
1051
1119
  background: hover ? "var(--action-hover)" : "transparent",
1052
1120
  color: hover ? strong ? fg : "var(--text-primary)" : strong ? "color-mix(in srgb, " + fg + " 70%, transparent)" : "var(--text-tertiary)",
@@ -1532,7 +1600,7 @@ var Select = React7.forwardRef(
1532
1600
  "data-slot": "select-content",
1533
1601
  position: "popper",
1534
1602
  sideOffset: 4,
1535
- 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)]",
1603
+ 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-16)]",
1536
1604
  children: [
1537
1605
  /* @__PURE__ */ jsx7(
1538
1606
  SelectPrimitive.ScrollUpButton,
@@ -2823,7 +2891,7 @@ var WizardLayout = React16.forwardRef(
2823
2891
  type: "button",
2824
2892
  "data-slot": "wizard-layout-step-button",
2825
2893
  "data-step-state": step.resolvedState,
2826
- className: "flex cursor-pointer flex-col items-center gap-[var(--space-2)] rounded-[var(--radius-sm)] focus-visible:outline-none focus-visible:ring-[1px] focus-visible:ring-[var(--focus-ring)]",
2894
+ className: "flex cursor-pointer flex-col items-center gap-[var(--space-2)] rounded-[var(--radius-md)] focus-visible:outline-none focus-visible:ring-[1px] focus-visible:ring-[var(--focus-ring)]",
2827
2895
  onClick: () => onStepChange(index),
2828
2896
  children: [
2829
2897
  /* @__PURE__ */ jsx17(
@@ -2952,17 +3020,17 @@ var tabsListVariants = cva8(
2952
3020
  {
2953
3021
  variant: "line",
2954
3022
  orientation: "horizontal",
2955
- className: "border-b border-[var(--border-subtle)] gap-[var(--space-6)] overflow-x-auto overflow-y-hidden mb-[var(--space-6)]"
3023
+ className: "border-b border-[var(--border-subtle)] gap-[var(--space-6)] overflow-x-auto overflow-y-hidden"
2956
3024
  },
2957
3025
  {
2958
3026
  variant: "line",
2959
3027
  orientation: "vertical",
2960
- className: "border-r border-[var(--border-subtle)] gap-[var(--space-2)] pr-[var(--space-4)]"
3028
+ className: "border-r border-[var(--border-subtle)] gap-[var(--space-2)] pr-[var(--space-4)] max-sm:flex-row max-sm:gap-[var(--space-6)] max-sm:overflow-x-auto max-sm:overflow-y-hidden max-sm:border-r-0 max-sm:border-b max-sm:pr-0"
2961
3029
  },
2962
3030
  {
2963
3031
  variant: "contained",
2964
3032
  orientation: "horizontal",
2965
- className: "gap-[var(--space-1)] overflow-x-auto overflow-y-hidden mb-[var(--space-6)]"
3033
+ className: "gap-[var(--space-1)] overflow-x-auto overflow-y-hidden"
2966
3034
  },
2967
3035
  {
2968
3036
  variant: "contained",
@@ -3000,9 +3068,24 @@ var tabsTriggerVariants = cva8(
3000
3068
  },
3001
3069
  orientation: {
3002
3070
  horizontal: "",
3003
- vertical: "w-full justify-start data-[state=active]:after:bottom-0 data-[state=active]:after:left-auto data-[state=active]:after:right-[-1px] data-[state=active]:after:top-0 data-[state=active]:after:h-auto data-[state=active]:after:w-[2px]"
3071
+ vertical: "sm:w-full sm:justify-start sm:data-[state=active]:after:bottom-0 sm:data-[state=active]:after:left-auto sm:data-[state=active]:after:right-[calc(-1*(var(--space-4)+1px))] sm:data-[state=active]:after:top-0 sm:data-[state=active]:after:h-auto sm:data-[state=active]:after:w-[2px]"
3004
3072
  }
3005
3073
  },
3074
+ compoundVariants: [
3075
+ // 가로 line 목록은 overflow-y-hidden이라 바깥 ring이 잘린다. 2px 안쪽 여백을 두고 inset-ring으로 안쪽에 그린다.
3076
+ // ring-inset은 쓰지 않는다: 토큰 테마의 --color-inset(bg-inset) 때문에 ring 색이 배경색으로 덮인다.
3077
+ // 트리거 사이는 -mx로 보정해 텍스트 간격은 그대로 두고, 양 끝 트리거는 안쪽 여백을 유지해 ring이 목록 안에 남는다.
3078
+ {
3079
+ variant: "line",
3080
+ orientation: "horizontal",
3081
+ className: "mx-[-2px] px-[2px] first:ml-0 last:mr-0 focus-visible:ring-0 focus-visible:inset-ring-2 focus-visible:inset-ring-[var(--focus-ring)]"
3082
+ },
3083
+ {
3084
+ variant: "line",
3085
+ orientation: "vertical",
3086
+ className: "max-sm:mx-[-2px] max-sm:px-[2px] max-sm:first:ml-0 max-sm:last:mr-0 max-sm:focus-visible:ring-0 max-sm:focus-visible:inset-ring-2 max-sm:focus-visible:inset-ring-[var(--focus-ring)]"
3087
+ }
3088
+ ],
3006
3089
  defaultVariants: {
3007
3090
  variant: "line",
3008
3091
  orientation: "horizontal"
@@ -3225,31 +3308,41 @@ var DetailLayout = React18.forwardRef(
3225
3308
  ...props,
3226
3309
  children: [
3227
3310
  /* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-header", className: "min-w-0", children: header }),
3228
- tabs ? /* @__PURE__ */ jsx19(Tabs, { tabs, activeKey: activeTab, onChange: onTabChange, baseId, children: hasExplicitTabsContent ? /* @__PURE__ */ jsx19(
3229
- DetailLayoutBody,
3311
+ tabs ? /* @__PURE__ */ jsx19(
3312
+ Tabs,
3230
3313
  {
3231
- aside,
3232
- bodyClassName,
3233
- contentClassName,
3234
- asideClassName,
3235
- stickyAside,
3236
- stickyAsideTopClassName,
3237
- children: appendFooterToActiveTabsContent(children, activeTab, footer)
3238
- }
3239
- ) : tabs.map((tab) => /* @__PURE__ */ jsx19(
3240
- TabsContent,
3241
- {
3242
- tabKey: tab.key,
3314
+ tabs,
3315
+ activeKey: activeTab,
3316
+ onChange: onTabChange,
3243
3317
  baseId,
3244
- forceMount: true,
3245
- hidden: tab.key !== activeTab,
3246
- children: tab.key === activeTab ? /* @__PURE__ */ jsxs18(Fragment6, { children: [
3247
- body,
3248
- footer ? /* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-footer", className: "min-w-0", children: footer }) : null
3249
- ] }) : null
3250
- },
3251
- tab.key
3252
- )) }) : /* @__PURE__ */ jsxs18(Fragment6, { children: [
3318
+ className: "flex flex-col gap-[var(--space-6)]",
3319
+ children: hasExplicitTabsContent ? /* @__PURE__ */ jsx19(
3320
+ DetailLayoutBody,
3321
+ {
3322
+ aside,
3323
+ bodyClassName,
3324
+ contentClassName,
3325
+ asideClassName,
3326
+ stickyAside,
3327
+ stickyAsideTopClassName,
3328
+ children: appendFooterToActiveTabsContent(children, activeTab, footer)
3329
+ }
3330
+ ) : tabs.map((tab) => /* @__PURE__ */ jsx19(
3331
+ TabsContent,
3332
+ {
3333
+ tabKey: tab.key,
3334
+ baseId,
3335
+ forceMount: true,
3336
+ hidden: tab.key !== activeTab,
3337
+ children: tab.key === activeTab ? /* @__PURE__ */ jsxs18(Fragment6, { children: [
3338
+ body,
3339
+ footer ? /* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-footer", className: "min-w-0", children: footer }) : null
3340
+ ] }) : null
3341
+ },
3342
+ tab.key
3343
+ ))
3344
+ }
3345
+ ) : /* @__PURE__ */ jsxs18(Fragment6, { children: [
3253
3346
  body,
3254
3347
  footer ? /* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-footer", className: "min-w-0", children: footer }) : null
3255
3348
  ] })
@@ -3420,18 +3513,286 @@ var FormLayout = React19.forwardRef(
3420
3513
  FormLayout.displayName = "FormLayout";
3421
3514
 
3422
3515
  // src/components/ui/form-modal.tsx
3423
- import * as React21 from "react";
3516
+ import * as React22 from "react";
3424
3517
 
3425
3518
  // src/components/ui/dialog.tsx
3426
- import * as React20 from "react";
3519
+ import * as React21 from "react";
3427
3520
  import { Dialog as DialogPrimitive } from "radix-ui";
3428
3521
  import { X } from "lucide-react";
3522
+
3523
+ // src/components/ui/sheet.tsx
3524
+ import { XIcon as XIcon2 } from "lucide-react";
3525
+ import { Dialog as SheetPrimitive } from "radix-ui";
3526
+
3527
+ // src/lib/use-return-focus.ts
3528
+ import * as React20 from "react";
3529
+ function useReturnFocus() {
3530
+ const returnTo = React20.useRef(null);
3531
+ const onOpenAutoFocus = React20.useCallback(() => {
3532
+ const active = document.activeElement;
3533
+ returnTo.current = active instanceof HTMLElement && active !== document.body ? active : null;
3534
+ }, []);
3535
+ const onCloseAutoFocus = React20.useCallback((event) => {
3536
+ const target = returnTo.current;
3537
+ returnTo.current = null;
3538
+ if (!target?.isConnected) return;
3539
+ event.preventDefault();
3540
+ target.focus();
3541
+ }, []);
3542
+ return { onOpenAutoFocus, onCloseAutoFocus };
3543
+ }
3544
+
3545
+ // src/components/ui/sheet.tsx
3429
3546
  import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
3547
+ var defaultSheetMotionConfig = {
3548
+ type: "slide",
3549
+ duration: 300,
3550
+ easing: "decel"
3551
+ };
3552
+ var sheetMotionEasingValue = {
3553
+ standard: "var(--ease-standard)",
3554
+ // decel/sharp have no canonical --ease-* token; these compat beziers are frozen
3555
+ // specifically to back this public `easing` prop (see tokens/compat.css).
3556
+ decel: "var(--easing-decel)",
3557
+ accel: "var(--ease-in)",
3558
+ sharp: "var(--easing-sharp)",
3559
+ bounce: "var(--ease-out)"
3560
+ };
3561
+ function resolveSheetMotionConfig(motion) {
3562
+ if (motion === false) return false;
3563
+ return {
3564
+ ...defaultSheetMotionConfig,
3565
+ ...motion
3566
+ };
3567
+ }
3568
+ function formatSheetMotionDuration(duration) {
3569
+ return typeof duration === "number" ? `${duration}ms` : duration;
3570
+ }
3571
+ function getSheetMotionStyle(motionConfig, style) {
3572
+ if (!motionConfig) return style;
3573
+ return {
3574
+ ...style,
3575
+ "--sheet-motion-duration": formatSheetMotionDuration(motionConfig.duration),
3576
+ "--sheet-motion-easing": sheetMotionEasingValue[motionConfig.easing]
3577
+ };
3578
+ }
3579
+ function getDefaultSheetMotionStyle(style) {
3580
+ return getSheetMotionStyle(defaultSheetMotionConfig, style);
3581
+ }
3582
+ function Sheet({ ...props }) {
3583
+ return /* @__PURE__ */ jsx21(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
3584
+ }
3585
+ function SheetTrigger({
3586
+ ...props
3587
+ }) {
3588
+ return /* @__PURE__ */ jsx21(SheetPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
3589
+ }
3590
+ function SheetClose({
3591
+ ...props
3592
+ }) {
3593
+ return /* @__PURE__ */ jsx21(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
3594
+ }
3595
+ function SheetPortal({
3596
+ ...props
3597
+ }) {
3598
+ return /* @__PURE__ */ jsx21(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
3599
+ }
3600
+ function SheetOverlay({
3601
+ className,
3602
+ motion,
3603
+ style,
3604
+ ...props
3605
+ }) {
3606
+ const motionConfig = resolveSheetMotionConfig(motion);
3607
+ return /* @__PURE__ */ jsx21(
3608
+ SheetPrimitive.Overlay,
3609
+ {
3610
+ "data-slot": "sheet-overlay",
3611
+ className: cn(
3612
+ "fixed inset-0 z-[var(--z-overlay)] bg-[var(--scrim)]",
3613
+ motionConfig && cn(
3614
+ "transition-opacity motion-reduce:transition-none",
3615
+ "duration-[var(--sheet-motion-duration)]",
3616
+ "data-[state=closed]:opacity-0 data-[state=open]:opacity-100",
3617
+ "data-[state=open]:animate-[olun-sheet-fade-in_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
3618
+ "data-[state=closed]:animate-[olun-sheet-fade-out_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
3619
+ "motion-reduce:animate-none"
3620
+ ),
3621
+ className
3622
+ ),
3623
+ style: getSheetMotionStyle(motionConfig, style),
3624
+ ...props
3625
+ }
3626
+ );
3627
+ }
3628
+ function SheetContent({
3629
+ className,
3630
+ children,
3631
+ side = "right",
3632
+ mobileSide,
3633
+ motion,
3634
+ showCloseButton = false,
3635
+ style,
3636
+ onOpenAutoFocus,
3637
+ onCloseAutoFocus,
3638
+ ...props
3639
+ }) {
3640
+ const motionConfig = resolveSheetMotionConfig(motion);
3641
+ const hasSlideMotion = motionConfig && motionConfig.type === "slide";
3642
+ const returnFocus = useReturnFocus();
3643
+ const handleOpenAutoFocus = (event) => {
3644
+ returnFocus.onOpenAutoFocus();
3645
+ onOpenAutoFocus?.(event);
3646
+ };
3647
+ const handleCloseAutoFocus = (event) => {
3648
+ onCloseAutoFocus?.(event);
3649
+ if (!event.defaultPrevented) returnFocus.onCloseAutoFocus(event);
3650
+ };
3651
+ return /* @__PURE__ */ jsxs20(SheetPortal, { children: [
3652
+ /* @__PURE__ */ jsx21(SheetOverlay, { motion: motionConfig }),
3653
+ /* @__PURE__ */ jsxs20(
3654
+ SheetPrimitive.Content,
3655
+ {
3656
+ "data-slot": "sheet-content",
3657
+ className: cn(
3658
+ "fixed z-[var(--z-modal)] flex flex-col gap-4 border-[var(--border)] bg-[var(--bg-surface)] shadow-[var(--shadow-16)]",
3659
+ motionConfig && cn(
3660
+ "motion-reduce:animate-none",
3661
+ 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]"
3662
+ ),
3663
+ side === "right" && cn(
3664
+ "inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
3665
+ 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]"
3666
+ ),
3667
+ side === "left" && cn(
3668
+ "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
3669
+ 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]"
3670
+ ),
3671
+ side === "top" && cn(
3672
+ "inset-x-0 top-0 h-auto border-b",
3673
+ 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]"
3674
+ ),
3675
+ side === "bottom" && cn(
3676
+ "inset-x-0 bottom-0 h-auto border-t",
3677
+ 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]"
3678
+ ),
3679
+ mobileSide === "right" && cn(
3680
+ "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",
3681
+ 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]"
3682
+ ),
3683
+ mobileSide === "left" && cn(
3684
+ "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",
3685
+ 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]"
3686
+ ),
3687
+ mobileSide === "top" && cn(
3688
+ // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap (see mobileSide bottom).
3689
+ "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",
3690
+ 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]"
3691
+ ),
3692
+ mobileSide === "bottom" && cn(
3693
+ // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap so the bottom sheet
3694
+ // spans the full viewport width across the whole < 900px band (not capped to 24rem).
3695
+ "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",
3696
+ 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]"
3697
+ ),
3698
+ className
3699
+ ),
3700
+ style: getSheetMotionStyle(motionConfig, style),
3701
+ onOpenAutoFocus: handleOpenAutoFocus,
3702
+ onCloseAutoFocus: handleCloseAutoFocus,
3703
+ ...props,
3704
+ children: [
3705
+ children,
3706
+ showCloseButton && /* @__PURE__ */ jsxs20(SheetPrimitive.Close, { className: "absolute top-4 right-4 cursor-pointer rounded-[var(--radius-md)] 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: [
3707
+ /* @__PURE__ */ jsx21(XIcon2, { className: "size-[16px]" }),
3708
+ /* @__PURE__ */ jsx21("span", { className: "sr-only", children: "Close" })
3709
+ ] })
3710
+ ]
3711
+ }
3712
+ )
3713
+ ] });
3714
+ }
3715
+ function SheetBody({ className, ...props }) {
3716
+ return /* @__PURE__ */ jsx21(
3717
+ "div",
3718
+ {
3719
+ "data-slot": "sheet-body",
3720
+ className: cn("flex-1 overflow-y-auto p-4", className),
3721
+ ...props
3722
+ }
3723
+ );
3724
+ }
3725
+ function SheetHeader({ className, ...props }) {
3726
+ return /* @__PURE__ */ jsx21(
3727
+ "div",
3728
+ {
3729
+ "data-slot": "sheet-header",
3730
+ className: cn("flex flex-col gap-1.5 p-4", className),
3731
+ ...props
3732
+ }
3733
+ );
3734
+ }
3735
+ function SheetFooter({ className, ...props }) {
3736
+ return /* @__PURE__ */ jsx21(
3737
+ "div",
3738
+ {
3739
+ "data-slot": "sheet-footer",
3740
+ className: cn("mt-auto flex flex-col gap-2 p-4", className),
3741
+ ...props
3742
+ }
3743
+ );
3744
+ }
3745
+ function SheetTitle({
3746
+ className,
3747
+ ...props
3748
+ }) {
3749
+ return /* @__PURE__ */ jsx21(
3750
+ SheetPrimitive.Title,
3751
+ {
3752
+ "data-slot": "sheet-title",
3753
+ className: cn("font-semibold text-foreground", className),
3754
+ ...props
3755
+ }
3756
+ );
3757
+ }
3758
+ function SheetDescription({
3759
+ className,
3760
+ ...props
3761
+ }) {
3762
+ return /* @__PURE__ */ jsx21(
3763
+ SheetPrimitive.Description,
3764
+ {
3765
+ "data-slot": "sheet-description",
3766
+ className: cn("text-sm text-muted-foreground", className),
3767
+ ...props
3768
+ }
3769
+ );
3770
+ }
3771
+
3772
+ // src/components/ui/dialog.tsx
3773
+ import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
3774
+ var dialogMobileSheetClassName = cn(
3775
+ // `!` on the box geometry so consumer width/offset classes (unprefixed or `sm:`) never keep
3776
+ // the centered card inside the < 900px band.
3777
+ "max-[899px]:inset-x-0! max-[899px]:top-auto! max-[899px]:bottom-0! max-[899px]:translate-x-0! max-[899px]:translate-y-0!",
3778
+ "max-[899px]:w-full! max-[899px]:max-w-none!",
3779
+ "max-[899px]:max-h-[85dvh] max-[899px]:overflow-y-auto",
3780
+ "max-[899px]:rounded-b-none max-[899px]:border-x-0",
3781
+ // Home-indicator clearance without touching the consumer's padding (DialogFooter's edge bleed
3782
+ // depends on it): a transparent bottom border as tall as the safe area, painted by the surface.
3783
+ "max-[899px]:border-b-[length:env(safe-area-inset-bottom)] max-[899px]:border-b-transparent",
3784
+ // motion-safe gate (not a motion-reduce override): a later-sorted variant would out-rank it.
3785
+ "max-[899px]:motion-safe:data-[state=open]:animate-[olun-sheet-in-from-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
3786
+ "max-[899px]:motion-safe:data-[state=closed]:animate-[olun-sheet-out-to-bottom_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
3787
+ );
3788
+ function dialogMobileSheetStyle(style) {
3789
+ return getDefaultSheetMotionStyle(style);
3790
+ }
3430
3791
  var Dialog = DialogPrimitive.Root;
3431
3792
  var DialogTrigger = DialogPrimitive.Trigger;
3432
3793
  var DialogPortal = DialogPrimitive.Portal;
3433
3794
  var DialogClose = DialogPrimitive.Close;
3434
- var DialogOverlay = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
3795
+ var DialogOverlay = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx22(
3435
3796
  DialogPrimitive.Overlay,
3436
3797
  {
3437
3798
  ref,
@@ -3448,9 +3809,9 @@ var DialogOverlay = React20.forwardRef(({ className, ...props }, ref) => /* @__P
3448
3809
  }
3449
3810
  ));
3450
3811
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
3451
- var DialogContent = React20.forwardRef(({ className, children, showCloseButton = false, ...props }, ref) => /* @__PURE__ */ jsxs20(DialogPortal, { children: [
3452
- /* @__PURE__ */ jsx21(DialogOverlay, {}),
3453
- /* @__PURE__ */ jsxs20(
3812
+ var DialogContent = React21.forwardRef(({ className, children, showCloseButton = false, mobilePresentation = "center", ...props }, ref) => /* @__PURE__ */ jsxs21(DialogPortal, { children: [
3813
+ /* @__PURE__ */ jsx22(DialogOverlay, {}),
3814
+ /* @__PURE__ */ jsxs21(
3454
3815
  DialogPrimitive.Content,
3455
3816
  {
3456
3817
  ref,
@@ -3472,24 +3833,26 @@ var DialogContent = React20.forwardRef(({ className, children, showCloseButton =
3472
3833
  "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
3473
3834
  "data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
3474
3835
  "motion-reduce:animate-none",
3836
+ mobilePresentation === "sheet" && dialogMobileSheetClassName,
3475
3837
  className
3476
3838
  ),
3477
3839
  ...props,
3840
+ ...mobilePresentation === "sheet" && { style: dialogMobileSheetStyle(props.style) },
3478
3841
  children: [
3479
3842
  children,
3480
- showCloseButton ? /* @__PURE__ */ jsx21(
3843
+ showCloseButton ? /* @__PURE__ */ jsx22(
3481
3844
  DialogPrimitive.Close,
3482
3845
  {
3483
3846
  className: cn(
3484
3847
  "absolute right-4 top-4 inline-flex size-[32px] cursor-pointer items-center justify-center",
3485
- "rounded-sm text-text-secondary",
3848
+ "rounded-[var(--radius-md)] text-text-secondary",
3486
3849
  "transition-colors motion-reduce:transition-none",
3487
3850
  "hover:bg-accent hover:text-accent-foreground",
3488
3851
  "focus-visible:outline-none focus-visible:shadow-focus-ring",
3489
3852
  "disabled:pointer-events-none disabled:text-text-disabled"
3490
3853
  ),
3491
3854
  "aria-label": "\uB2EB\uAE30",
3492
- children: /* @__PURE__ */ jsx21(X, { className: "size-[16px]" })
3855
+ children: /* @__PURE__ */ jsx22(X, { className: "size-[16px]" })
3493
3856
  }
3494
3857
  ) : null
3495
3858
  ]
@@ -3500,7 +3863,7 @@ DialogContent.displayName = DialogPrimitive.Content.displayName;
3500
3863
  var DialogHeader = ({
3501
3864
  className,
3502
3865
  ...props
3503
- }) => /* @__PURE__ */ jsx21(
3866
+ }) => /* @__PURE__ */ jsx22(
3504
3867
  "div",
3505
3868
  {
3506
3869
  className: cn(
@@ -3515,7 +3878,7 @@ DialogHeader.displayName = "DialogHeader";
3515
3878
  var DialogFooter = ({
3516
3879
  className,
3517
3880
  ...props
3518
- }) => /* @__PURE__ */ jsx21(
3881
+ }) => /* @__PURE__ */ jsx22(
3519
3882
  "div",
3520
3883
  {
3521
3884
  className: cn(
@@ -3531,7 +3894,7 @@ var DialogFooter = ({
3531
3894
  }
3532
3895
  );
3533
3896
  DialogFooter.displayName = "DialogFooter";
3534
- var DialogTitle = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
3897
+ var DialogTitle = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx22(
3535
3898
  DialogPrimitive.Title,
3536
3899
  {
3537
3900
  ref,
@@ -3543,7 +3906,7 @@ var DialogTitle = React20.forwardRef(({ className, ...props }, ref) => /* @__PUR
3543
3906
  }
3544
3907
  ));
3545
3908
  DialogTitle.displayName = DialogPrimitive.Title.displayName;
3546
- var DialogDescription = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
3909
+ var DialogDescription = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx22(
3547
3910
  DialogPrimitive.Description,
3548
3911
  {
3549
3912
  ref,
@@ -3552,7 +3915,7 @@ var DialogDescription = React20.forwardRef(({ className, ...props }, ref) => /*
3552
3915
  }
3553
3916
  ));
3554
3917
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
3555
- var DialogEyebrow = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
3918
+ var DialogEyebrow = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx22(
3556
3919
  "p",
3557
3920
  {
3558
3921
  ref,
@@ -3567,7 +3930,7 @@ DialogEyebrow.displayName = "DialogEyebrow";
3567
3930
  var DialogRawContent = DialogPrimitive.Content;
3568
3931
 
3569
3932
  // src/components/ui/form-modal.tsx
3570
- import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
3933
+ import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
3571
3934
  var formModalContentClassName = cn(
3572
3935
  "w-[calc(100vw-2rem)]",
3573
3936
  "max-w-[560px]",
@@ -3608,12 +3971,14 @@ function FormModal({
3608
3971
  cancelLabel = "\uCDE8\uC18C",
3609
3972
  wide = false,
3610
3973
  loading = false,
3611
- status
3974
+ status,
3975
+ mobilePresentation = "center"
3612
3976
  }) {
3613
- const [pending, setPending] = React21.useState(false);
3614
- const busyRef = React21.useRef(false);
3977
+ const [pending, setPending] = React22.useState(false);
3978
+ const busyRef = React22.useRef(false);
3615
3979
  const isBusy = loading || pending;
3616
- const handleOpenChange = React21.useCallback(
3980
+ const returnFocus = useReturnFocus();
3981
+ const handleOpenChange = React22.useCallback(
3617
3982
  (nextOpen) => {
3618
3983
  if (!nextOpen && isBusy) {
3619
3984
  return;
@@ -3622,7 +3987,7 @@ function FormModal({
3622
3987
  },
3623
3988
  [isBusy, onOpenChange]
3624
3989
  );
3625
- const handleSubmit = React21.useCallback(
3990
+ const handleSubmit = React22.useCallback(
3626
3991
  async (event) => {
3627
3992
  event.preventDefault();
3628
3993
  if (busyRef.current || loading) {
@@ -3640,37 +4005,41 @@ function FormModal({
3640
4005
  },
3641
4006
  [loading, onOpenChange, onSubmit]
3642
4007
  );
3643
- return /* @__PURE__ */ jsx22(Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsx22(
4008
+ return /* @__PURE__ */ jsx23(Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsx23(
3644
4009
  DialogContent,
3645
4010
  {
3646
4011
  "data-slot": "form-modal-content",
4012
+ mobilePresentation,
4013
+ ...returnFocus,
3647
4014
  className: cn(
3648
4015
  formModalContentClassName,
3649
4016
  wide && formModalWideContentClassName
3650
4017
  ),
3651
- children: /* @__PURE__ */ jsxs21("form", { "data-slot": "form-modal-form", onSubmit: handleSubmit, children: [
3652
- /* @__PURE__ */ jsxs21("div", { "data-slot": "form-modal-header", className: formModalHeaderClassName, children: [
3653
- /* @__PURE__ */ jsx22(DialogTitle, { className: formModalTitleClassName, children: title }),
3654
- description ? /* @__PURE__ */ jsx22(DialogDescription, { className: formModalDescriptionClassName, children: description }) : null,
3655
- status ? /* @__PURE__ */ jsx22("div", { "data-slot": "form-modal-status", children: status }) : null
4018
+ children: /* @__PURE__ */ jsxs22("form", { "data-slot": "form-modal-form", onSubmit: handleSubmit, children: [
4019
+ /* @__PURE__ */ jsxs22("div", { "data-slot": "form-modal-header", className: formModalHeaderClassName, children: [
4020
+ /* @__PURE__ */ jsx23(DialogTitle, { className: formModalTitleClassName, children: title }),
4021
+ description ? /* @__PURE__ */ jsx23(DialogDescription, { className: formModalDescriptionClassName, children: description }) : null,
4022
+ status ? /* @__PURE__ */ jsx23("div", { "data-slot": "form-modal-status", children: status }) : null
3656
4023
  ] }),
3657
- /* @__PURE__ */ jsx22("div", { "data-slot": "form-modal-body", className: formModalBodyClassName, children }),
3658
- /* @__PURE__ */ jsxs21(
4024
+ /* @__PURE__ */ jsx23("div", { "data-slot": "form-modal-body", className: formModalBodyClassName, children }),
4025
+ /* @__PURE__ */ jsxs22(
3659
4026
  "div",
3660
4027
  {
3661
4028
  "data-slot": "form-modal-footer",
3662
4029
  className: formModalFooterClassName,
3663
4030
  children: [
3664
- /* @__PURE__ */ jsx22(
4031
+ /* @__PURE__ */ jsx23(
3665
4032
  Button,
3666
4033
  {
3667
4034
  variant: "secondary",
4035
+ size: "lg",
4036
+ className: footerButtonHitAreaClassName,
3668
4037
  disabled: isBusy,
3669
4038
  onClick: () => handleOpenChange(false),
3670
4039
  children: cancelLabel
3671
4040
  }
3672
4041
  ),
3673
- /* @__PURE__ */ jsx22(Button, { type: "submit", loading: isBusy, children: submitLabel })
4042
+ /* @__PURE__ */ jsx23(Button, { type: "submit", size: "lg", className: footerButtonHitAreaClassName, loading: isBusy, children: submitLabel })
3674
4043
  ]
3675
4044
  }
3676
4045
  )
@@ -3680,7 +4049,7 @@ function FormModal({
3680
4049
  }
3681
4050
 
3682
4051
  // src/components/ui/info-modal.tsx
3683
- import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
4052
+ import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
3684
4053
  var infoModalContentClassName = cn(
3685
4054
  "w-[calc(100vw-2rem)]",
3686
4055
  "max-w-[420px]",
@@ -3719,20 +4088,24 @@ function InfoModal({
3719
4088
  children,
3720
4089
  closeLabel = "\uB2EB\uAE30",
3721
4090
  width = "default",
3722
- footer
4091
+ footer,
4092
+ mobilePresentation = "center"
3723
4093
  }) {
3724
- return /* @__PURE__ */ jsx23(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs22(
4094
+ const returnFocus = useReturnFocus();
4095
+ return /* @__PURE__ */ jsx24(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs23(
3725
4096
  DialogContent,
3726
4097
  {
3727
4098
  "data-slot": "info-modal-content",
4099
+ mobilePresentation,
4100
+ ...returnFocus,
3728
4101
  className: cn(
3729
4102
  infoModalContentClassName,
3730
4103
  width === "wide" && infoModalWideContentClassName
3731
4104
  ),
3732
4105
  children: [
3733
- /* @__PURE__ */ jsxs22("div", { "data-slot": "info-modal-header", className: infoModalHeaderClassName, children: [
3734
- /* @__PURE__ */ jsx23(DialogTitle, { "data-slot": "info-modal-title", className: infoModalTitleClassName, children: title }),
3735
- description ? /* @__PURE__ */ jsx23(
4106
+ /* @__PURE__ */ jsxs23("div", { "data-slot": "info-modal-header", className: infoModalHeaderClassName, children: [
4107
+ /* @__PURE__ */ jsx24(DialogTitle, { "data-slot": "info-modal-title", className: infoModalTitleClassName, children: title }),
4108
+ description ? /* @__PURE__ */ jsx24(
3736
4109
  DialogDescription,
3737
4110
  {
3738
4111
  "data-slot": "info-modal-description",
@@ -3741,13 +4114,14 @@ function InfoModal({
3741
4114
  }
3742
4115
  ) : null
3743
4116
  ] }),
3744
- /* @__PURE__ */ jsx23("div", { "data-slot": "info-modal-body", className: infoModalBodyClassName, children }),
3745
- /* @__PURE__ */ jsx23("div", { "data-slot": "info-modal-footer", className: infoModalFooterClassName, children: footer ?? /* @__PURE__ */ jsx23(
4117
+ /* @__PURE__ */ jsx24("div", { "data-slot": "info-modal-body", className: infoModalBodyClassName, children }),
4118
+ /* @__PURE__ */ jsx24("div", { "data-slot": "info-modal-footer", className: infoModalFooterClassName, children: footer ?? /* @__PURE__ */ jsx24(
3746
4119
  Button,
3747
4120
  {
3748
4121
  "data-slot": "info-modal-close-button",
3749
4122
  variant: "secondary",
3750
- size: "sm",
4123
+ size: "lg",
4124
+ className: footerButtonHitAreaClassName,
3751
4125
  onClick: () => onOpenChange(false),
3752
4126
  children: closeLabel
3753
4127
  }
@@ -3758,15 +4132,15 @@ function InfoModal({
3758
4132
  }
3759
4133
 
3760
4134
  // src/components/ui/filter-toolbar.tsx
3761
- import * as React25 from "react";
4135
+ import * as React26 from "react";
3762
4136
  import { SlidersHorizontal } from "lucide-react";
3763
4137
 
3764
4138
  // src/components/ui/chip.tsx
3765
- import * as React22 from "react";
4139
+ import * as React23 from "react";
3766
4140
  import { cva as cva9 } from "class-variance-authority";
3767
4141
  import { X as X2 } from "lucide-react";
3768
4142
  import { Slot as Slot2 } from "radix-ui";
3769
- import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
4143
+ import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3770
4144
  var chipVariants = cva9(
3771
4145
  [
3772
4146
  "inline-flex w-fit shrink-0 items-center justify-center whitespace-nowrap",
@@ -3858,7 +4232,7 @@ var chipCountVariants = cva9(
3858
4232
  }
3859
4233
  }
3860
4234
  );
3861
- var Chip = React22.forwardRef(
4235
+ var Chip = React23.forwardRef(
3862
4236
  ({
3863
4237
  className,
3864
4238
  variant = "filter",
@@ -3883,7 +4257,7 @@ var Chip = React22.forwardRef(
3883
4257
  value: _value,
3884
4258
  ...spanProps
3885
4259
  } = props;
3886
- return /* @__PURE__ */ jsxs23(
4260
+ return /* @__PURE__ */ jsxs24(
3887
4261
  "span",
3888
4262
  {
3889
4263
  "data-slot": "chip",
@@ -3892,8 +4266,8 @@ var Chip = React22.forwardRef(
3892
4266
  className: cn(chipVariants({ variant, tone, size, pressed, className })),
3893
4267
  ...spanProps,
3894
4268
  children: [
3895
- /* @__PURE__ */ jsx24("span", { children }),
3896
- count !== void 0 ? /* @__PURE__ */ jsx24(
4269
+ /* @__PURE__ */ jsx25("span", { children }),
4270
+ count !== void 0 ? /* @__PURE__ */ jsx25(
3897
4271
  "span",
3898
4272
  {
3899
4273
  "aria-hidden": "true",
@@ -3903,7 +4277,7 @@ var Chip = React22.forwardRef(
3903
4277
  children: count
3904
4278
  }
3905
4279
  ) : null,
3906
- /* @__PURE__ */ jsx24(
4280
+ /* @__PURE__ */ jsx25(
3907
4281
  "button",
3908
4282
  {
3909
4283
  ref,
@@ -3913,7 +4287,7 @@ var Chip = React22.forwardRef(
3913
4287
  disabled,
3914
4288
  onClick,
3915
4289
  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)]",
3916
- children: /* @__PURE__ */ jsx24(X2, { "aria-hidden": "true", size: 14, strokeWidth: 2.25 })
4290
+ children: /* @__PURE__ */ jsx25(X2, { "aria-hidden": "true", size: 14, strokeWidth: 2.25 })
3917
4291
  }
3918
4292
  )
3919
4293
  ]
@@ -3921,7 +4295,7 @@ var Chip = React22.forwardRef(
3921
4295
  );
3922
4296
  }
3923
4297
  const Comp = asChild ? Slot2.Root : "button";
3924
- return /* @__PURE__ */ jsxs23(
4298
+ return /* @__PURE__ */ jsxs24(
3925
4299
  Comp,
3926
4300
  {
3927
4301
  ref,
@@ -3936,7 +4310,7 @@ var Chip = React22.forwardRef(
3936
4310
  ...props,
3937
4311
  children: [
3938
4312
  children,
3939
- count !== void 0 ? /* @__PURE__ */ jsx24(
4313
+ count !== void 0 ? /* @__PURE__ */ jsx25(
3940
4314
  "span",
3941
4315
  {
3942
4316
  "aria-hidden": "true",
@@ -3954,13 +4328,13 @@ var Chip = React22.forwardRef(
3954
4328
  Chip.displayName = "Chip";
3955
4329
 
3956
4330
  // src/components/ui/icon-button.tsx
3957
- import * as React23 from "react";
4331
+ import * as React24 from "react";
3958
4332
  import { cva as cva10 } from "class-variance-authority";
3959
- import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3960
- var iconButtonVariants = cva10(
4333
+ import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
4334
+ var iconButtonCva = cva10(
3961
4335
  [
3962
4336
  "olun-icon-button relative inline-flex cursor-pointer shrink-0 items-center justify-center before:absolute before:content-['']",
3963
- "rounded-[var(--radius-sm)] border font-medium",
4337
+ "rounded-[var(--radius-md)] border font-medium",
3964
4338
  "transition-colors motion-reduce:transition-none",
3965
4339
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
3966
4340
  "disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled",
@@ -3968,12 +4342,21 @@ var iconButtonVariants = cva10(
3968
4342
  ].join(" "),
3969
4343
  {
3970
4344
  variants: {
4345
+ // Legacy single axis, deprecated in 0.19 for `appearance` × `tone` and removed in 0.20.
4346
+ // Frozen at 0.18; button-appearance.test.tsx keeps ghost and subtle equal to their new
4347
+ // pair. `outline` and `danger` differ from the pair they migrate to (outline + neutral =
4348
+ // Button secondary, filled + danger = solid red).
3971
4349
  variant: {
4350
+ /** @deprecated Use `appearance="ghost" tone="neutral"` (the default). */
3972
4351
  ghost: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
4352
+ /** @deprecated Use `appearance="outline" tone="neutral"`. */
3973
4353
  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",
4354
+ /** @deprecated Use `appearance="filled" tone="neutral"`. */
3974
4355
  subtle: "border-transparent bg-[var(--bg-inset)] text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
4356
+ /** @deprecated Use `appearance="filled" tone="danger"` (solid red, like Button). */
3975
4357
  danger: "border-transparent bg-[var(--error-bg)] text-[var(--error)] hover:bg-[var(--action-hover)]"
3976
4358
  },
4359
+ ...actionAxisVariants,
3977
4360
  // Hit area = 44px on every size. The ::before is absolutely positioned, so its
3978
4361
  // inset is measured from the padding box — inside the 1px border every variant
3979
4362
  // carries (transparent or not). Inset = (44 - (size - 2 × 1px border)) / 2.
@@ -3988,6 +4371,7 @@ var iconButtonVariants = cva10(
3988
4371
  }
3989
4372
  },
3990
4373
  compoundVariants: [
4374
+ ...actionCompoundVariants,
3991
4375
  {
3992
4376
  pressed: true,
3993
4377
  variant: ["ghost", "outline", "subtle"],
@@ -3997,8 +4381,16 @@ var iconButtonVariants = cva10(
3997
4381
  pressed: true,
3998
4382
  variant: "danger",
3999
4383
  className: "border-[var(--error)] bg-[var(--error-bg)] text-[var(--error)]"
4384
+ },
4385
+ {
4386
+ pressed: true,
4387
+ tone: "neutral",
4388
+ className: "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground"
4000
4389
  }
4001
4390
  ],
4391
+ // ghost is the intended default, not a fallback: ghost is reserved for icon-only
4392
+ // actions repeated in rows or chrome (toolbars, headers, table rows), and
4393
+ // IconButton is its canonical entry point (#58). Text actions use Button.
4002
4394
  defaultVariants: {
4003
4395
  variant: "ghost",
4004
4396
  size: "md",
@@ -4006,6 +4398,33 @@ var iconButtonVariants = cva10(
4006
4398
  }
4007
4399
  }
4008
4400
  );
4401
+ var axisSizeClassName = {
4402
+ xs: "size-[28px] before:-inset-[9px]",
4403
+ sm: "size-[30px] before:-inset-[8px]",
4404
+ md: "size-[32px] before:-inset-[7px]",
4405
+ lg: "size-[36px] before:-inset-[5px]",
4406
+ xl: "size-[40px] before:-inset-[3px]"
4407
+ };
4408
+ var axisIcon = {
4409
+ xs: { size: 14, strokeWidth: 1.75 },
4410
+ sm: { size: 16, strokeWidth: 2 },
4411
+ md: { size: 16, strokeWidth: 2 },
4412
+ lg: { size: 18, strokeWidth: 2 },
4413
+ xl: { size: 18, strokeWidth: 2 }
4414
+ };
4415
+ function iconButtonVariants(options) {
4416
+ if (options?.appearance == null && options?.tone == null) {
4417
+ return iconButtonCva(options);
4418
+ }
4419
+ const { size, ...rest } = options;
4420
+ const paint = iconButtonCva({
4421
+ ...rest,
4422
+ ...resolveActionStyle(options.appearance, options.tone, "ghost"),
4423
+ variant: null,
4424
+ size: null
4425
+ });
4426
+ return size === null ? paint : `${paint} ${axisSizeClassName[size ?? "md"]}`;
4427
+ }
4009
4428
  var iconButtonBadgeVariants = cva10(
4010
4429
  [
4011
4430
  "pointer-events-none absolute right-0 top-0 inline-flex",
@@ -4032,357 +4451,173 @@ var iconSize2 = {
4032
4451
  md: 16,
4033
4452
  lg: 18
4034
4453
  };
4454
+ var textButtonSize = {
4455
+ sm: "xs",
4456
+ md: "md",
4457
+ lg: "xl"
4458
+ };
4035
4459
  var iconStrokeWidth = {
4036
4460
  sm: 2.25,
4037
4461
  md: 2.25,
4038
4462
  lg: 1.75
4039
4463
  };
4040
- var IconButton = React23.forwardRef(
4464
+ var IconButton = React24.forwardRef(
4041
4465
  ({
4042
4466
  className,
4043
4467
  variant = "ghost",
4468
+ appearance,
4469
+ tone,
4044
4470
  size = "md",
4045
4471
  pressed = void 0,
4046
4472
  icon: Icon,
4047
4473
  badge,
4048
- badgeTone = "info",
4049
- type,
4050
- title,
4051
- "aria-label": ariaLabel,
4052
- "aria-labelledby": ariaLabelledBy,
4053
- ...props
4054
- }, ref) => {
4055
- const resolvedSize = size ?? "md";
4056
- const isToggle = pressed !== void 0;
4057
- const isPressed = pressed === true;
4058
- const hoverTitle = title ?? (typeof ariaLabel === "string" ? ariaLabel : void 0);
4059
- return /* @__PURE__ */ jsxs24(
4060
- "button",
4061
- {
4062
- ref,
4063
- ...props,
4064
- "data-slot": "icon-button",
4065
- "data-variant": variant,
4066
- "data-size": resolvedSize,
4067
- "data-pressed": isToggle ? String(isPressed) : void 0,
4068
- "aria-label": ariaLabel,
4069
- "aria-labelledby": ariaLabelledBy,
4070
- "aria-pressed": isToggle ? isPressed : void 0,
4071
- title: hoverTitle,
4072
- className: cn(
4073
- iconButtonVariants({ variant, size, pressed: isPressed, className })
4074
- ),
4075
- type: type ?? "button",
4076
- children: [
4077
- /* @__PURE__ */ jsx25(
4078
- Icon,
4079
- {
4080
- "aria-hidden": "true",
4081
- "data-slot": "icon-button-icon",
4082
- size: iconSize2[resolvedSize],
4083
- strokeWidth: iconStrokeWidth[resolvedSize]
4084
- }
4085
- ),
4086
- badge !== void 0 ? /* @__PURE__ */ jsx25(
4087
- "span",
4088
- {
4089
- "aria-hidden": "true",
4090
- "data-slot": "icon-button-badge",
4091
- "data-badge-tone": badgeTone,
4092
- className: iconButtonBadgeVariants({ tone: badgeTone }),
4093
- children: badge
4094
- }
4095
- ) : null
4096
- ]
4097
- }
4098
- );
4099
- }
4100
- );
4101
- IconButton.displayName = "IconButton";
4102
-
4103
- // src/components/ui/popover.tsx
4104
- import * as React24 from "react";
4105
- import { Popover as PopoverPrimitive } from "radix-ui";
4106
- import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
4107
- function Popover({ modal = false, ...props }) {
4108
- return /* @__PURE__ */ jsx26(PopoverPrimitive.Root, { modal, ...props });
4109
- }
4110
- var popoverArrowClassName = "fill-[var(--bg-surface)] stroke-[var(--border)] [&>polygon]:[vector-effect:non-scaling-stroke]";
4111
- var PopoverTrigger = PopoverPrimitive.Trigger;
4112
- var PopoverAnchor = PopoverPrimitive.Anchor;
4113
- var PopoverClose = PopoverPrimitive.Close;
4114
- var PopoverContent = React24.forwardRef(({ className, align = "center", sideOffset = 8, collisionPadding = 8, showArrow = false, children, ...props }, ref) => /* @__PURE__ */ jsx26(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsxs25(
4115
- PopoverPrimitive.Content,
4116
- {
4117
- ref,
4118
- align,
4119
- sideOffset,
4120
- collisionPadding,
4121
- "data-slot": "popover-content",
4122
- className: cn(
4123
- "z-[var(--z-popover)] w-[260px] outline-none",
4124
- "rounded-[var(--radius-md)] border border-[var(--border)]",
4125
- "bg-[var(--bg-surface)] p-[var(--space-4)] text-foreground",
4126
- "shadow-[var(--shadow-4)]",
4127
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
4128
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
4129
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
4130
- "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
4131
- "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4132
- "motion-reduce:animate-none",
4133
- className
4134
- ),
4135
- ...props,
4136
- children: [
4137
- children,
4138
- showArrow ? /* @__PURE__ */ jsx26(
4139
- PopoverPrimitive.Arrow,
4140
- {
4141
- "data-slot": "popover-arrow",
4142
- className: popoverArrowClassName,
4143
- width: 11,
4144
- height: 5
4145
- }
4146
- ) : null
4147
- ]
4148
- }
4149
- ) }));
4150
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
4151
- var PopoverArrow = React24.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
4152
- PopoverPrimitive.Arrow,
4153
- {
4154
- ref,
4155
- "data-slot": "popover-arrow",
4156
- className: cn(popoverArrowClassName, className),
4157
- width: 11,
4158
- height: 5,
4159
- ...props
4160
- }
4161
- ));
4162
- PopoverArrow.displayName = PopoverPrimitive.Arrow.displayName;
4163
-
4164
- // src/components/ui/sheet-drawer.tsx
4165
- import { Maximize2Icon, Minimize2Icon, XIcon as XIcon3 } from "lucide-react";
4166
-
4167
- // src/components/ui/sheet.tsx
4168
- import { XIcon as XIcon2 } from "lucide-react";
4169
- import { Dialog as SheetPrimitive } from "radix-ui";
4170
- import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
4171
- var defaultSheetMotionConfig = {
4172
- type: "slide",
4173
- duration: 300,
4174
- easing: "decel"
4175
- };
4176
- var sheetMotionEasingValue = {
4177
- standard: "var(--ease-standard)",
4178
- // decel/sharp have no canonical --ease-* token; these compat beziers are frozen
4179
- // specifically to back this public `easing` prop (see tokens/compat.css).
4180
- decel: "var(--easing-decel)",
4181
- accel: "var(--ease-in)",
4182
- sharp: "var(--easing-sharp)",
4183
- bounce: "var(--ease-out)"
4184
- };
4185
- function resolveSheetMotionConfig(motion) {
4186
- if (motion === false) return false;
4187
- return {
4188
- ...defaultSheetMotionConfig,
4189
- ...motion
4190
- };
4191
- }
4192
- function formatSheetMotionDuration(duration) {
4193
- return typeof duration === "number" ? `${duration}ms` : duration;
4194
- }
4195
- function getSheetMotionStyle(motionConfig, style) {
4196
- if (!motionConfig) return style;
4197
- return {
4198
- ...style,
4199
- "--sheet-motion-duration": formatSheetMotionDuration(motionConfig.duration),
4200
- "--sheet-motion-easing": sheetMotionEasingValue[motionConfig.easing]
4201
- };
4202
- }
4203
- function Sheet({ ...props }) {
4204
- return /* @__PURE__ */ jsx27(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
4205
- }
4206
- function SheetTrigger({
4207
- ...props
4208
- }) {
4209
- return /* @__PURE__ */ jsx27(SheetPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
4210
- }
4211
- function SheetClose({
4212
- ...props
4213
- }) {
4214
- return /* @__PURE__ */ jsx27(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
4215
- }
4216
- function SheetPortal({
4217
- ...props
4218
- }) {
4219
- return /* @__PURE__ */ jsx27(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
4220
- }
4221
- function SheetOverlay({
4222
- className,
4223
- motion,
4224
- style,
4225
- ...props
4226
- }) {
4227
- const motionConfig = resolveSheetMotionConfig(motion);
4228
- return /* @__PURE__ */ jsx27(
4229
- SheetPrimitive.Overlay,
4230
- {
4231
- "data-slot": "sheet-overlay",
4232
- className: cn(
4233
- "fixed inset-0 z-[var(--z-overlay)] bg-[var(--scrim)]",
4234
- motionConfig && cn(
4235
- "transition-opacity motion-reduce:transition-none",
4236
- "duration-[var(--sheet-motion-duration)]",
4237
- "data-[state=closed]:opacity-0 data-[state=open]:opacity-100",
4238
- "data-[state=open]:animate-[olun-sheet-fade-in_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
4239
- "data-[state=closed]:animate-[olun-sheet-fade-out_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
4240
- "motion-reduce:animate-none"
4241
- ),
4242
- className
4243
- ),
4244
- style: getSheetMotionStyle(motionConfig, style),
4245
- ...props
4246
- }
4247
- );
4248
- }
4249
- function SheetContent({
4250
- className,
4251
- children,
4252
- side = "right",
4253
- mobileSide,
4254
- motion,
4255
- showCloseButton = false,
4256
- style,
4257
- ...props
4258
- }) {
4259
- const motionConfig = resolveSheetMotionConfig(motion);
4260
- const hasSlideMotion = motionConfig && motionConfig.type === "slide";
4261
- return /* @__PURE__ */ jsxs26(SheetPortal, { children: [
4262
- /* @__PURE__ */ jsx27(SheetOverlay, { motion: motionConfig }),
4263
- /* @__PURE__ */ jsxs26(
4264
- SheetPrimitive.Content,
4265
- {
4266
- "data-slot": "sheet-content",
4267
- className: cn(
4268
- "fixed z-[var(--z-modal)] flex flex-col gap-4 border-[var(--border)] bg-[var(--bg-surface)] shadow-[var(--shadow-4)]",
4269
- motionConfig && cn(
4270
- "motion-reduce:animate-none",
4271
- 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]"
4272
- ),
4273
- side === "right" && cn(
4274
- "inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
4275
- 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]"
4276
- ),
4277
- side === "left" && cn(
4278
- "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
4279
- 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]"
4280
- ),
4281
- side === "top" && cn(
4282
- "inset-x-0 top-0 h-auto border-b",
4283
- 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]"
4284
- ),
4285
- side === "bottom" && cn(
4286
- "inset-x-0 bottom-0 h-auto border-t",
4287
- 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]"
4288
- ),
4289
- mobileSide === "right" && cn(
4290
- "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",
4291
- 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]"
4292
- ),
4293
- mobileSide === "left" && cn(
4294
- "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",
4295
- 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]"
4296
- ),
4297
- mobileSide === "top" && cn(
4298
- // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap (see mobileSide bottom).
4299
- "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",
4300
- 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]"
4301
- ),
4302
- mobileSide === "bottom" && cn(
4303
- // `max-w-none!` overrides the side variant's `sm:max-w-sm` cap so the bottom sheet
4304
- // spans the full viewport width across the whole < 900px band (not capped to 24rem).
4305
- "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",
4306
- 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]"
4307
- ),
4308
- className
4309
- ),
4310
- style: getSheetMotionStyle(motionConfig, style),
4311
- ...props,
4312
- children: [
4313
- children,
4314
- 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: [
4315
- /* @__PURE__ */ jsx27(XIcon2, { className: "size-[16px]" }),
4316
- /* @__PURE__ */ jsx27("span", { className: "sr-only", children: "Close" })
4317
- ] })
4318
- ]
4319
- }
4320
- )
4321
- ] });
4322
- }
4323
- function SheetBody({ className, ...props }) {
4324
- return /* @__PURE__ */ jsx27(
4325
- "div",
4326
- {
4327
- "data-slot": "sheet-body",
4328
- className: cn("flex-1 overflow-y-auto p-4", className),
4329
- ...props
4330
- }
4331
- );
4332
- }
4333
- function SheetHeader({ className, ...props }) {
4334
- return /* @__PURE__ */ jsx27(
4335
- "div",
4336
- {
4337
- "data-slot": "sheet-header",
4338
- className: cn("flex flex-col gap-1.5 p-4", className),
4339
- ...props
4340
- }
4341
- );
4342
- }
4343
- function SheetFooter({ className, ...props }) {
4344
- return /* @__PURE__ */ jsx27(
4345
- "div",
4346
- {
4347
- "data-slot": "sheet-footer",
4348
- className: cn("mt-auto flex flex-col gap-2 p-4", className),
4349
- ...props
4350
- }
4351
- );
4352
- }
4353
- function SheetTitle({
4354
- className,
4355
- ...props
4356
- }) {
4357
- return /* @__PURE__ */ jsx27(
4358
- SheetPrimitive.Title,
4359
- {
4360
- "data-slot": "sheet-title",
4361
- className: cn("font-semibold text-foreground", className),
4362
- ...props
4363
- }
4364
- );
4365
- }
4366
- function SheetDescription({
4367
- className,
4368
- ...props
4369
- }) {
4370
- return /* @__PURE__ */ jsx27(
4371
- SheetPrimitive.Description,
4372
- {
4373
- "data-slot": "sheet-description",
4374
- className: cn("text-sm text-muted-foreground", className),
4375
- ...props
4376
- }
4377
- );
4474
+ badgeTone = "info",
4475
+ type,
4476
+ title,
4477
+ "aria-label": ariaLabel,
4478
+ "aria-labelledby": ariaLabelledBy,
4479
+ iconPosition = "start",
4480
+ label,
4481
+ children,
4482
+ ...props
4483
+ }, ref) => {
4484
+ const resolvedSize = size ?? "md";
4485
+ const usesAxes = appearance != null || tone != null;
4486
+ const isToggle = pressed !== void 0;
4487
+ const isPressed = pressed === true;
4488
+ const hoverTitle = title ?? (typeof ariaLabel === "string" ? ariaLabel : void 0);
4489
+ const text = label ?? children;
4490
+ const hasText = text !== void 0 && text !== null && text !== false;
4491
+ const style = usesAxes ? resolveActionStyle(appearance, tone, "ghost") : void 0;
4492
+ const axisSize = usesAxes ? resolvedSize : void 0;
4493
+ const legacySize = resolvedSize;
4494
+ const textBoxSize = axisSize ?? textButtonSize[legacySize];
4495
+ const icon = /* @__PURE__ */ jsx26(
4496
+ Icon,
4497
+ {
4498
+ "aria-hidden": "true",
4499
+ "data-slot": "icon-button-icon",
4500
+ size: axisSize ? axisIcon[axisSize].size : iconSize2[legacySize],
4501
+ strokeWidth: axisSize ? axisIcon[axisSize].strokeWidth : hasText ? void 0 : iconStrokeWidth[legacySize]
4502
+ }
4503
+ );
4504
+ return /* @__PURE__ */ jsxs25(
4505
+ "button",
4506
+ {
4507
+ ref,
4508
+ ...props,
4509
+ "data-slot": "icon-button",
4510
+ "data-variant": usesAxes ? void 0 : variant,
4511
+ "data-appearance": style?.appearance,
4512
+ "data-tone": style?.tone,
4513
+ "data-size": resolvedSize,
4514
+ "data-icon-position": hasText ? iconPosition : void 0,
4515
+ "data-pressed": isToggle ? String(isPressed) : void 0,
4516
+ "aria-label": ariaLabel,
4517
+ "aria-labelledby": ariaLabelledBy,
4518
+ "aria-pressed": isToggle ? isPressed : void 0,
4519
+ title: hoverTitle,
4520
+ className: cn(
4521
+ iconButtonVariants({
4522
+ variant,
4523
+ appearance,
4524
+ tone,
4525
+ size: hasText ? null : size,
4526
+ pressed: isPressed
4527
+ }),
4528
+ hasText && ["whitespace-nowrap", buttonSizeClassName(textBoxSize)],
4529
+ className
4530
+ ),
4531
+ type: type ?? "button",
4532
+ children: [
4533
+ hasText && iconPosition === "end" ? null : icon,
4534
+ hasText ? text : null,
4535
+ hasText && iconPosition === "end" ? icon : null,
4536
+ badge !== void 0 ? /* @__PURE__ */ jsx26(
4537
+ "span",
4538
+ {
4539
+ "aria-hidden": "true",
4540
+ "data-slot": "icon-button-badge",
4541
+ "data-badge-tone": badgeTone,
4542
+ className: iconButtonBadgeVariants({ tone: badgeTone }),
4543
+ children: badge
4544
+ }
4545
+ ) : null
4546
+ ]
4547
+ }
4548
+ );
4549
+ }
4550
+ );
4551
+ IconButton.displayName = "IconButton";
4552
+
4553
+ // src/components/ui/popover.tsx
4554
+ import * as React25 from "react";
4555
+ import { Popover as PopoverPrimitive } from "radix-ui";
4556
+ import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
4557
+ function Popover({ modal = false, ...props }) {
4558
+ return /* @__PURE__ */ jsx27(PopoverPrimitive.Root, { modal, ...props });
4378
4559
  }
4560
+ var popoverArrowClassName = "fill-[var(--bg-surface)] stroke-[var(--border)] [&>polygon]:[vector-effect:non-scaling-stroke]";
4561
+ var PopoverTrigger = PopoverPrimitive.Trigger;
4562
+ var PopoverAnchor = PopoverPrimitive.Anchor;
4563
+ var PopoverClose = PopoverPrimitive.Close;
4564
+ var PopoverContent = React25.forwardRef(({ className, align = "center", sideOffset = 8, collisionPadding = 8, showArrow = false, children, ...props }, ref) => /* @__PURE__ */ jsx27(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsxs26(
4565
+ PopoverPrimitive.Content,
4566
+ {
4567
+ ref,
4568
+ align,
4569
+ sideOffset,
4570
+ collisionPadding,
4571
+ "data-slot": "popover-content",
4572
+ className: cn(
4573
+ "z-[var(--z-popover)] w-[260px] outline-none",
4574
+ "rounded-[var(--radius-md)] border border-[var(--border)]",
4575
+ "bg-[var(--bg-surface)] p-[var(--space-4)] text-foreground",
4576
+ "shadow-[var(--shadow-16)]",
4577
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
4578
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
4579
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
4580
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
4581
+ "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4582
+ "motion-reduce:animate-none",
4583
+ className
4584
+ ),
4585
+ ...props,
4586
+ children: [
4587
+ children,
4588
+ showArrow ? /* @__PURE__ */ jsx27(
4589
+ PopoverPrimitive.Arrow,
4590
+ {
4591
+ "data-slot": "popover-arrow",
4592
+ className: popoverArrowClassName,
4593
+ width: 11,
4594
+ height: 5
4595
+ }
4596
+ ) : null
4597
+ ]
4598
+ }
4599
+ ) }));
4600
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
4601
+ var PopoverArrow = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx27(
4602
+ PopoverPrimitive.Arrow,
4603
+ {
4604
+ ref,
4605
+ "data-slot": "popover-arrow",
4606
+ className: cn(popoverArrowClassName, className),
4607
+ width: 11,
4608
+ height: 5,
4609
+ ...props
4610
+ }
4611
+ ));
4612
+ PopoverArrow.displayName = PopoverPrimitive.Arrow.displayName;
4379
4613
 
4380
4614
  // src/components/ui/sheet-drawer.tsx
4615
+ import { Maximize2Icon, Minimize2Icon, XIcon as XIcon3 } from "lucide-react";
4381
4616
  import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
4382
4617
  var sheetDrawerContentClassName = cn(
4383
4618
  "gap-0 p-0",
4384
4619
  "bg-[var(--bg-surface)] text-foreground",
4385
- "border-[var(--border)] shadow-[var(--shadow-4)]",
4620
+ "border-[var(--border)] shadow-[var(--shadow-16)]",
4386
4621
  "min-[900px]:w-[480px] min-[900px]:max-w-[480px]",
4387
4622
  "max-[899px]:h-[min(85dvh,720px)] max-[899px]:max-h-[85dvh] max-[899px]:w-full max-[899px]:max-w-none",
4388
4623
  "max-[899px]:rounded-t-[var(--radius-lg)]"
@@ -4402,7 +4637,7 @@ var sheetDrawerTitleClassName = "text-[18px] font-bold leading-snug text-foregro
4402
4637
  var sheetDrawerDescriptionClassName = "break-keep text-[14px] leading-normal text-text-secondary";
4403
4638
  var sheetDrawerCloseButtonClassName = cn(
4404
4639
  "flex size-[32px] shrink-0 cursor-pointer items-center justify-center",
4405
- "rounded-[var(--radius-sm)] text-text-tertiary transition-colors",
4640
+ "rounded-[var(--radius-md)] text-text-tertiary transition-colors",
4406
4641
  "hover:bg-[var(--action-hover)] hover:text-foreground",
4407
4642
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2"
4408
4643
  );
@@ -4411,7 +4646,7 @@ var sheetDrawerHeaderActionsClassName = cn(
4411
4646
  );
4412
4647
  var sheetDrawerExpandButtonClassName = cn(
4413
4648
  "inline-flex cursor-pointer items-center justify-center gap-[var(--space-1)]",
4414
- "rounded-[var(--radius-sm)] text-text-tertiary transition-colors",
4649
+ "rounded-[var(--radius-md)] text-text-tertiary transition-colors",
4415
4650
  "hover:bg-[var(--action-hover)] hover:text-foreground",
4416
4651
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2",
4417
4652
  "h-[32px] px-[var(--space-2)]"
@@ -4554,7 +4789,7 @@ var collapsibleClassNames = {
4554
4789
  trigger: "hidden"
4555
4790
  }
4556
4791
  };
4557
- var FilterToolbar = React25.forwardRef(
4792
+ var FilterToolbar = React26.forwardRef(
4558
4793
  ({
4559
4794
  className,
4560
4795
  search,
@@ -4569,15 +4804,15 @@ var FilterToolbar = React25.forwardRef(
4569
4804
  actions,
4570
4805
  ...props
4571
4806
  }, ref) => {
4572
- const [rootElement, setRootElement] = React25.useState(
4807
+ const [rootElement, setRootElement] = React26.useState(
4573
4808
  null
4574
4809
  );
4575
- const [containerWidth, setContainerWidth] = React25.useState(
4810
+ const [containerWidth, setContainerWidth] = React26.useState(
4576
4811
  null
4577
4812
  );
4578
- const [overlayOpen, setOverlayOpen] = React25.useState(false);
4579
- const triggerRef = React25.useRef(null);
4580
- const setRootRefs = React25.useCallback(
4813
+ const [overlayOpen, setOverlayOpen] = React26.useState(false);
4814
+ const triggerRef = React26.useRef(null);
4815
+ const setRootRefs = React26.useCallback(
4581
4816
  (element) => {
4582
4817
  setRootElement(element);
4583
4818
  if (typeof ref === "function") ref(element);
@@ -4585,7 +4820,7 @@ var FilterToolbar = React25.forwardRef(
4585
4820
  },
4586
4821
  [ref]
4587
4822
  );
4588
- React25.useEffect(() => {
4823
+ React26.useEffect(() => {
4589
4824
  if (!rootElement) return;
4590
4825
  const updateWidth = () => {
4591
4826
  setContainerWidth(rootElement.getBoundingClientRect().width);
@@ -4596,7 +4831,7 @@ var FilterToolbar = React25.forwardRef(
4596
4831
  observer.observe(rootElement);
4597
4832
  return () => observer.disconnect();
4598
4833
  }, [rootElement]);
4599
- const handleOverlayOpenChange = React25.useCallback((open) => {
4834
+ const handleOverlayOpenChange = React26.useCallback((open) => {
4600
4835
  setOverlayOpen(open);
4601
4836
  if (!open) queueMicrotask(() => triggerRef.current?.focus());
4602
4837
  }, []);
@@ -4795,12 +5030,12 @@ var FilterToolbar = React25.forwardRef(
4795
5030
  FilterToolbar.displayName = "FilterToolbar";
4796
5031
 
4797
5032
  // src/components/ui/data-table.tsx
4798
- import * as React27 from "react";
5033
+ import * as React28 from "react";
4799
5034
  import { ChevronDown as ChevronDown3, ChevronUp as ChevronUp2, ChevronsUpDown } from "lucide-react";
4800
5035
  import { cva as cva12 } from "class-variance-authority";
4801
5036
 
4802
5037
  // src/components/ui/checkbox.tsx
4803
- import * as React26 from "react";
5038
+ import * as React27 from "react";
4804
5039
  import { cva as cva11 } from "class-variance-authority";
4805
5040
  import { Check as Check3, Minus } from "lucide-react";
4806
5041
  import { Checkbox as CheckboxPrimitive } from "radix-ui";
@@ -4860,7 +5095,7 @@ var checkboxGroupItemVariants = cva11(
4860
5095
  {
4861
5096
  variants: {
4862
5097
  appearance: {
4863
- plain: "inline-flex items-start gap-[var(--space-3)] rounded-[var(--radius-sm)] px-pad-compact-x py-pad-compact-y",
5098
+ plain: "inline-flex items-start gap-[var(--space-3)] rounded-[var(--radius-md)] px-pad-compact-x py-pad-compact-y",
4864
5099
  card: [
4865
5100
  "flex min-h-[calc(var(--space-12)+var(--space-2))] items-start gap-[var(--space-3)]",
4866
5101
  "rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-surface)]",
@@ -4907,11 +5142,11 @@ var checkboxGroupBoxVariants = cva11(
4907
5142
  }
4908
5143
  }
4909
5144
  );
4910
- var CheckboxGroupContext = React26.createContext(null);
5145
+ var CheckboxGroupContext = React27.createContext(null);
4911
5146
  function getLabel(children, label) {
4912
5147
  return children ?? label;
4913
5148
  }
4914
- var Checkbox = React26.forwardRef(
5149
+ var Checkbox = React27.forwardRef(
4915
5150
  ({
4916
5151
  className,
4917
5152
  size = "md",
@@ -4929,8 +5164,8 @@ var Checkbox = React26.forwardRef(
4929
5164
  onCheckedChange,
4930
5165
  ...props
4931
5166
  }, ref) => {
4932
- const group = React26.useContext(CheckboxGroupContext);
4933
- const generatedId = React26.useId();
5167
+ const group = React27.useContext(CheckboxGroupContext);
5168
+ const generatedId = React27.useId();
4934
5169
  const checkboxId = id ?? generatedId;
4935
5170
  const labelContent = getLabel(children, label);
4936
5171
  const isGrouped = Boolean(group && value != null);
@@ -5196,7 +5431,7 @@ function getRenderedCell(row, column) {
5196
5431
  if (value === null || value === void 0) {
5197
5432
  return null;
5198
5433
  }
5199
- if (React27.isValidElement(value)) {
5434
+ if (React28.isValidElement(value)) {
5200
5435
  return value;
5201
5436
  }
5202
5437
  return String(value);
@@ -5292,8 +5527,9 @@ function MobileSortControls({
5292
5527
  type: "button",
5293
5528
  "data-slot": "data-table-mobile-sort-button",
5294
5529
  size: "xs",
5295
- variant: active ? "secondary" : "outline",
5530
+ variant: "secondary",
5296
5531
  "aria-pressed": active,
5532
+ className: active ? "border-[var(--border-strong)] bg-[var(--action-selected)] hover:border-[var(--border-strong)] hover:bg-[var(--action-selected)]" : void 0,
5297
5533
  onClick: () => onSortChange?.(column.key, nextSort),
5298
5534
  children: /* @__PURE__ */ jsxs30("span", { className: "inline-flex min-w-0 items-center gap-[var(--space-1)]", children: [
5299
5535
  /* @__PURE__ */ jsx31("span", { className: "truncate", children: column.header }),
@@ -5558,9 +5794,9 @@ function DataTableMobileCardView({
5558
5794
  }
5559
5795
  );
5560
5796
  }
5561
- var MemoDataTableRow = React27.memo(DataTableRowView);
5562
- var MemoDataTableMobileCard = React27.memo(DataTableMobileCardView);
5563
- var useIsomorphicLayoutEffect = typeof window === "undefined" ? React27.useEffect : React27.useLayoutEffect;
5797
+ var MemoDataTableRow = React28.memo(DataTableRowView);
5798
+ var MemoDataTableMobileCard = React28.memo(DataTableMobileCardView);
5799
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? React28.useEffect : React28.useLayoutEffect;
5564
5800
  var VIRTUAL_DEFAULT_OVERSCAN = 8;
5565
5801
  var VIRTUAL_INITIAL_ROWS = 24;
5566
5802
  var VIRTUAL_FALLBACK_SIZE = { desktop: 48, mobile: 120 };
@@ -5583,16 +5819,16 @@ function useVirtualWindow({
5583
5819
  desktopListRef,
5584
5820
  mobileListRef
5585
5821
  }) {
5586
- const [win, setWin] = React27.useState({
5822
+ const [win, setWin] = React28.useState({
5587
5823
  layout: null,
5588
5824
  start: 0,
5589
5825
  end: VIRTUAL_INITIAL_ROWS,
5590
5826
  size: 0
5591
5827
  });
5592
- const measuredSize = React27.useRef({ desktop: 0, mobile: 0 });
5593
- const update = React27.useRef(() => void 0);
5594
- const reported = React27.useRef("");
5595
- const latest = React27.useRef({ count, layout: "desktop" });
5828
+ const measuredSize = React28.useRef({ desktop: 0, mobile: 0 });
5829
+ const update = React28.useRef(() => void 0);
5830
+ const reported = React28.useRef("");
5831
+ const latest = React28.useRef({ count, layout: "desktop" });
5596
5832
  update.current = () => {
5597
5833
  if (!enabled) {
5598
5834
  return;
@@ -5639,7 +5875,7 @@ function useVirtualWindow({
5639
5875
  useIsomorphicLayoutEffect(() => {
5640
5876
  update.current();
5641
5877
  });
5642
- React27.useEffect(() => {
5878
+ React28.useEffect(() => {
5643
5879
  if (!enabled) {
5644
5880
  return;
5645
5881
  }
@@ -5661,7 +5897,7 @@ function useVirtualWindow({
5661
5897
  window.cancelAnimationFrame(frame);
5662
5898
  };
5663
5899
  }, [enabled]);
5664
- const scrollToIndex = React27.useCallback(
5900
+ const scrollToIndex = React28.useCallback(
5665
5901
  (index) => {
5666
5902
  const { count: rowCount, layout } = latest.current;
5667
5903
  const list = (layout === "desktop" ? desktopListRef : mobileListRef).current;
@@ -5718,10 +5954,10 @@ function DataTableInner({
5718
5954
  }, ref) {
5719
5955
  const virtualOptions = virtual ? virtual === true ? {} : virtual : null;
5720
5956
  const isVirtual = virtualOptions !== null;
5721
- const desktopRef = React27.useRef(null);
5722
- const headerRef = React27.useRef(null);
5723
- const desktopListRef = React27.useRef(null);
5724
- const mobileListRef = React27.useRef(null);
5957
+ const desktopRef = React28.useRef(null);
5958
+ const headerRef = React28.useRef(null);
5959
+ const desktopListRef = React28.useRef(null);
5960
+ const mobileListRef = React28.useRef(null);
5725
5961
  const { win: virtualWindow, scrollToIndex } = useVirtualWindow({
5726
5962
  enabled: isVirtual,
5727
5963
  count: data.length,
@@ -5732,7 +5968,7 @@ function DataTableInner({
5732
5968
  desktopListRef,
5733
5969
  mobileListRef
5734
5970
  });
5735
- React27.useImperativeHandle(virtualOptions?.handleRef, () => ({ scrollToIndex }), [scrollToIndex]);
5971
+ React28.useImperativeHandle(virtualOptions?.handleRef, () => ({ scrollToIndex }), [scrollToIndex]);
5736
5972
  const resolvedSelectedIds = selectedIds ?? /* @__PURE__ */ new Set();
5737
5973
  const rowIds = data.map((row) => getRowId(row, keyField));
5738
5974
  const selectedCount = rowIds.filter((id) => resolvedSelectedIds.has(id)).length;
@@ -5767,19 +6003,19 @@ function DataTableInner({
5767
6003
  window.location.assign(href);
5768
6004
  }
5769
6005
  };
5770
- const latestHandlers = React27.useRef({ toggleRow, activateRow, onRowContextMenu });
6006
+ const latestHandlers = React28.useRef({ toggleRow, activateRow, onRowContextMenu });
5771
6007
  useIsomorphicLayoutEffect(() => {
5772
6008
  latestHandlers.current = { toggleRow, activateRow, onRowContextMenu };
5773
6009
  });
5774
- const stableToggleRow = React27.useCallback(
6010
+ const stableToggleRow = React28.useCallback(
5775
6011
  (id, checked) => latestHandlers.current.toggleRow(id, checked),
5776
6012
  []
5777
6013
  );
5778
- const stableActivateRow = React27.useCallback(
6014
+ const stableActivateRow = React28.useCallback(
5779
6015
  (row, href, event) => latestHandlers.current.activateRow(row, href, event),
5780
6016
  []
5781
6017
  );
5782
- const stableRowContextMenu = React27.useCallback(
6018
+ const stableRowContextMenu = React28.useCallback(
5783
6019
  (rowId, event) => latestHandlers.current.onRowContextMenu?.(rowId, event),
5784
6020
  []
5785
6021
  );
@@ -6002,7 +6238,7 @@ function DataTableInner({
6002
6238
  }
6003
6239
  );
6004
6240
  }
6005
- var DataTable = React27.forwardRef(DataTableInner);
6241
+ var DataTable = React28.forwardRef(DataTableInner);
6006
6242
  DataTable.displayName = "DataTable";
6007
6243
 
6008
6244
  // src/components/ui/dropdown-menu.tsx
@@ -6043,7 +6279,7 @@ function DropdownMenuContent({
6043
6279
  className: cn(
6044
6280
  "z-[var(--z-popover)] max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem]",
6045
6281
  "origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto",
6046
- "rounded-sm border border-[var(--border)] bg-[var(--bg-surface)] p-[var(--space-1)] text-text-primary shadow-2",
6282
+ "rounded-[var(--radius-lg)] border border-[var(--border)] bg-[var(--bg-surface)] p-[var(--space-1)] text-text-primary shadow-[var(--shadow-16)]",
6047
6283
  "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
6048
6284
  "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
6049
6285
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
@@ -6242,7 +6478,7 @@ function DropdownMenuSubContent({
6242
6478
  "data-slot": "dropdown-menu-sub-content",
6243
6479
  className: cn(
6244
6480
  "z-[var(--z-popover)] min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden",
6245
- "rounded-sm border border-[var(--border)] bg-[var(--bg-surface)] p-[var(--space-1)] text-text-primary shadow-2",
6481
+ "rounded-[var(--radius-lg)] border border-[var(--border)] bg-[var(--bg-surface)] p-[var(--space-1)] text-text-primary shadow-[var(--shadow-16)]",
6246
6482
  "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
6247
6483
  "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
6248
6484
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
@@ -6287,7 +6523,7 @@ function ContextMenu({
6287
6523
  }
6288
6524
 
6289
6525
  // src/components/ui/bulk-action-bar.tsx
6290
- import * as React28 from "react";
6526
+ import * as React29 from "react";
6291
6527
  import { X as X3 } from "lucide-react";
6292
6528
  import { jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
6293
6529
  function ActionButton({ action }) {
@@ -6314,7 +6550,7 @@ function ActionButton({ action }) {
6314
6550
  gap: 6,
6315
6551
  height: 30,
6316
6552
  padding: "0 10px",
6317
- borderRadius: "var(--radius-sm)",
6553
+ borderRadius: "var(--radius-md)",
6318
6554
  fontFamily: "var(--font-sans)",
6319
6555
  fontSize: 13,
6320
6556
  fontWeight: 500,
@@ -6371,7 +6607,7 @@ function ClearButton({ onClear }) {
6371
6607
  flexShrink: 0,
6372
6608
  alignItems: "center",
6373
6609
  justifyContent: "center",
6374
- borderRadius: "var(--radius-sm)"
6610
+ borderRadius: "var(--radius-md)"
6375
6611
  },
6376
6612
  children: /* @__PURE__ */ jsx34(X3, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" })
6377
6613
  }
@@ -6428,10 +6664,10 @@ var idleLineStyle = {
6428
6664
  fontVariantNumeric: "tabular-nums",
6429
6665
  color: "var(--text-secondary)"
6430
6666
  };
6431
- var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React28.useEffect : React28.useLayoutEffect;
6667
+ var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React29.useEffect : React29.useLayoutEffect;
6432
6668
  function useCompactSummary(slot, enabled) {
6433
- const [fullWidth, setFullWidth] = React28.useState(null);
6434
- const measure = React28.useCallback(() => {
6669
+ const [fullWidth, setFullWidth] = React29.useState(null);
6670
+ const measure = React29.useCallback(() => {
6435
6671
  if (!slot) return;
6436
6672
  setFullWidth((prev) => {
6437
6673
  if (prev === null) return slot.scrollWidth > slot.clientWidth ? slot.scrollWidth : null;
@@ -6441,7 +6677,7 @@ function useCompactSummary(slot, enabled) {
6441
6677
  useIsomorphicLayoutEffect2(() => {
6442
6678
  if (enabled) measure();
6443
6679
  });
6444
- React28.useEffect(() => {
6680
+ React29.useEffect(() => {
6445
6681
  if (!enabled || !slot || typeof ResizeObserver === "undefined") return;
6446
6682
  const observer = new ResizeObserver(measure);
6447
6683
  observer.observe(slot);
@@ -6478,7 +6714,7 @@ function BulkActionBar({
6478
6714
  children: trailing
6479
6715
  }
6480
6716
  ) : null;
6481
- const [summaryElement, setSummaryElement] = React28.useState(null);
6717
+ const [summaryElement, setSummaryElement] = React29.useState(null);
6482
6718
  const compact = useCompactSummary(
6483
6719
  summaryElement,
6484
6720
  inline && compactSummary !== void 0 && compactSummary !== null
@@ -6667,8 +6903,23 @@ function BulkActionBar({
6667
6903
  style: { ...floatingStyle, ...style },
6668
6904
  ...props,
6669
6905
  children: [
6670
- countLabel,
6671
- summarySlot,
6906
+ /* @__PURE__ */ jsxs33(
6907
+ "div",
6908
+ {
6909
+ role: "status",
6910
+ "data-slot": "bulk-action-bar-state",
6911
+ style: {
6912
+ display: "flex",
6913
+ minWidth: 0,
6914
+ alignItems: "center",
6915
+ gap: "var(--space-2)"
6916
+ },
6917
+ children: [
6918
+ countLabel,
6919
+ summarySlot
6920
+ ]
6921
+ }
6922
+ ),
6672
6923
  count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx34(Divider, {}) : null,
6673
6924
  actionGroup,
6674
6925
  /* @__PURE__ */ jsx34(Divider, {}),
@@ -6680,7 +6931,7 @@ function BulkActionBar({
6680
6931
  }
6681
6932
 
6682
6933
  // src/components/ui/confirm-dialog.tsx
6683
- import * as React29 from "react";
6934
+ import * as React30 from "react";
6684
6935
  import { Fragment as Fragment8, jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
6685
6936
  var confirmDialogContentClassName = cn(
6686
6937
  "fixed left-1/2 top-1/2 z-[var(--z-modal)]",
@@ -6710,12 +6961,14 @@ function ConfirmDialog({
6710
6961
  onConfirm,
6711
6962
  loading = false,
6712
6963
  children,
6713
- confirmDisabled = false
6964
+ confirmDisabled = false,
6965
+ mobilePresentation = "center"
6714
6966
  }) {
6715
- const [pending, setPending] = React29.useState(false);
6716
- const busyRef = React29.useRef(false);
6967
+ const [pending, setPending] = React30.useState(false);
6968
+ const busyRef = React30.useRef(false);
6717
6969
  const isBusy = loading || pending;
6718
- const handleOpenChange = React29.useCallback(
6970
+ const returnFocus = useReturnFocus();
6971
+ const handleOpenChange = React30.useCallback(
6719
6972
  (nextOpen) => {
6720
6973
  if (!nextOpen && isBusy) {
6721
6974
  return;
@@ -6724,7 +6977,7 @@ function ConfirmDialog({
6724
6977
  },
6725
6978
  [isBusy, onOpenChange]
6726
6979
  );
6727
- const handleConfirm = React29.useCallback(async () => {
6980
+ const handleConfirm = React30.useCallback(async () => {
6728
6981
  if (busyRef.current || loading || confirmDisabled) {
6729
6982
  return;
6730
6983
  }
@@ -6764,11 +7017,23 @@ function ConfirmDialog({
6764
7017
  "data-slot": "dialog-footer",
6765
7018
  className: confirmDialogFooterClassName,
6766
7019
  children: [
6767
- /* @__PURE__ */ jsx35(Button, { variant: "secondary", disabled: isBusy, onClick: () => handleOpenChange(false), children: cancelLabel }),
7020
+ /* @__PURE__ */ jsx35(
7021
+ Button,
7022
+ {
7023
+ variant: "secondary",
7024
+ size: "lg",
7025
+ className: footerButtonHitAreaClassName,
7026
+ disabled: isBusy,
7027
+ onClick: () => handleOpenChange(false),
7028
+ children: cancelLabel
7029
+ }
7030
+ ),
6768
7031
  /* @__PURE__ */ jsx35(
6769
7032
  Button,
6770
7033
  {
6771
7034
  variant: tone === "destructive" ? "destructive" : "primary",
7035
+ size: "lg",
7036
+ className: footerButtonHitAreaClassName,
6772
7037
  loading: isBusy,
6773
7038
  disabled: confirmDisabled,
6774
7039
  onClick: handleConfirm,
@@ -6781,7 +7046,20 @@ function ConfirmDialog({
6781
7046
  ] });
6782
7047
  return /* @__PURE__ */ jsx35(Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs34(DialogPortal, { children: [
6783
7048
  /* @__PURE__ */ jsx35(DialogOverlay, {}),
6784
- /* @__PURE__ */ jsx35(DialogRawContent, { role: "alertdialog", "data-slot": "dialog-content", className: confirmDialogContentClassName, children: dialogBody })
7049
+ /* @__PURE__ */ jsx35(
7050
+ DialogRawContent,
7051
+ {
7052
+ role: "alertdialog",
7053
+ "data-slot": "dialog-content",
7054
+ className: cn(
7055
+ confirmDialogContentClassName,
7056
+ mobilePresentation === "sheet" && dialogMobileSheetClassName
7057
+ ),
7058
+ style: mobilePresentation === "sheet" ? dialogMobileSheetStyle() : void 0,
7059
+ ...returnFocus,
7060
+ children: dialogBody
7061
+ }
7062
+ )
6785
7063
  ] }) });
6786
7064
  }
6787
7065
 
@@ -6880,9 +7158,100 @@ function AvatarFallback({
6880
7158
  );
6881
7159
  }
6882
7160
 
6883
- // src/components/ui/badge.tsx
6884
- import * as React30 from "react";
7161
+ // src/components/ui/action-sheet.tsx
7162
+ import * as React31 from "react";
7163
+ import { X as X4 } from "lucide-react";
6885
7164
  import { jsx as jsx38, jsxs as jsxs35 } from "react/jsx-runtime";
7165
+ var actionSheetContentClassName = cn(
7166
+ "gap-0 max-h-[85dvh] rounded-t-[var(--radius-lg)]",
7167
+ "pb-[env(safe-area-inset-bottom)]"
7168
+ );
7169
+ var actionSheetHeaderClassName = cn(
7170
+ "flex items-start gap-[var(--space-3)] px-[var(--space-4)] pt-[var(--space-4)] pb-[var(--space-3)]"
7171
+ );
7172
+ var actionSheetTitleClassName = cn(
7173
+ "break-keep text-[15px] font-semibold leading-snug text-foreground"
7174
+ );
7175
+ var actionSheetDescriptionClassName = cn(
7176
+ "mt-[var(--space-1)] break-keep text-[13px] leading-normal text-text-secondary"
7177
+ );
7178
+ var actionSheetListClassName = "min-h-0 overflow-y-auto";
7179
+ var actionSheetItemClassName = cn(
7180
+ "flex min-h-12 w-full cursor-pointer items-center gap-[var(--space-3)] px-[var(--space-4)] text-left",
7181
+ "border-t border-[var(--border-subtle)] text-[13px] font-medium text-text-primary",
7182
+ "transition-colors motion-reduce:transition-none hover:bg-[var(--action-hover)]",
7183
+ "focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[var(--focus-ring)]",
7184
+ "enabled:data-[destructive]:text-[var(--semantic-error-fg)]",
7185
+ "disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled"
7186
+ );
7187
+ function ActionSheet({
7188
+ open,
7189
+ onOpenChange,
7190
+ title,
7191
+ description,
7192
+ items,
7193
+ closeLabel = "\uB2EB\uAE30"
7194
+ }) {
7195
+ const pendingRef = React31.useRef(null);
7196
+ const returnFocus = useReturnFocus();
7197
+ const handleOpenChange = (nextOpen) => {
7198
+ pendingRef.current = null;
7199
+ onOpenChange(nextOpen);
7200
+ };
7201
+ const handleSelect = (item) => {
7202
+ onOpenChange(false);
7203
+ pendingRef.current = item;
7204
+ };
7205
+ const handleCloseAutoFocus = (event) => {
7206
+ returnFocus.onCloseAutoFocus(event);
7207
+ const item = pendingRef.current;
7208
+ pendingRef.current = null;
7209
+ item?.onSelect();
7210
+ };
7211
+ return /* @__PURE__ */ jsx38(Sheet, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs35(
7212
+ SheetContent,
7213
+ {
7214
+ side: "bottom",
7215
+ "data-slot": "action-sheet-content",
7216
+ className: actionSheetContentClassName,
7217
+ onOpenAutoFocus: returnFocus.onOpenAutoFocus,
7218
+ onCloseAutoFocus: handleCloseAutoFocus,
7219
+ ...description ? {} : { "aria-describedby": void 0 },
7220
+ children: [
7221
+ /* @__PURE__ */ jsxs35("div", { "data-slot": "action-sheet-header", className: actionSheetHeaderClassName, children: [
7222
+ /* @__PURE__ */ jsxs35("div", { className: "min-w-0 flex-1", children: [
7223
+ /* @__PURE__ */ jsx38(SheetTitle, { className: actionSheetTitleClassName, children: title }),
7224
+ description ? /* @__PURE__ */ jsx38(SheetDescription, { className: actionSheetDescriptionClassName, children: description }) : null
7225
+ ] }),
7226
+ /* @__PURE__ */ jsx38(SheetClose, { asChild: true, children: /* @__PURE__ */ jsx38(IconButton, { size: "sm", icon: X4, "aria-label": closeLabel }) })
7227
+ ] }),
7228
+ /* @__PURE__ */ jsx38("div", { "data-slot": "action-sheet-list", className: actionSheetListClassName, children: items.map((item) => {
7229
+ const Icon = item.icon;
7230
+ return /* @__PURE__ */ jsxs35(
7231
+ "button",
7232
+ {
7233
+ type: "button",
7234
+ "data-slot": "action-sheet-item",
7235
+ "data-destructive": item.destructive ? "" : void 0,
7236
+ className: actionSheetItemClassName,
7237
+ disabled: item.disabled,
7238
+ onClick: () => handleSelect(item),
7239
+ children: [
7240
+ Icon ? /* @__PURE__ */ jsx38(Icon, { "aria-hidden": true, size: 17, strokeWidth: 1.75, className: "shrink-0" }) : null,
7241
+ /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 break-keep", children: item.label })
7242
+ ]
7243
+ },
7244
+ item.id
7245
+ );
7246
+ }) })
7247
+ ]
7248
+ }
7249
+ ) });
7250
+ }
7251
+
7252
+ // src/components/ui/badge.tsx
7253
+ import * as React32 from "react";
7254
+ import { jsx as jsx39, jsxs as jsxs36 } from "react/jsx-runtime";
6886
7255
  var DOT = {
6887
7256
  error: "var(--semantic-error-fg)",
6888
7257
  warning: "var(--semantic-warning-fg)",
@@ -6891,8 +7260,8 @@ var DOT = {
6891
7260
  neutral: "var(--text-tertiary)",
6892
7261
  brand: "var(--accent-pop)"
6893
7262
  };
6894
- var Badge = React30.forwardRef(
6895
- ({ tone = "neutral", className, children, ...props }, ref) => /* @__PURE__ */ jsxs35(
7263
+ var Badge = React32.forwardRef(
7264
+ ({ tone = "neutral", className, children, ...props }, ref) => /* @__PURE__ */ jsxs36(
6896
7265
  "span",
6897
7266
  {
6898
7267
  ref,
@@ -6906,7 +7275,7 @@ var Badge = React30.forwardRef(
6906
7275
  ),
6907
7276
  ...props,
6908
7277
  children: [
6909
- /* @__PURE__ */ jsx38(
7278
+ /* @__PURE__ */ jsx39(
6910
7279
  "span",
6911
7280
  {
6912
7281
  "aria-hidden": "true",
@@ -6923,8 +7292,8 @@ var Badge = React30.forwardRef(
6923
7292
  Badge.displayName = "Badge";
6924
7293
 
6925
7294
  // src/components/ui/two-tier-badge.tsx
6926
- import * as React31 from "react";
6927
- import { jsx as jsx39, jsxs as jsxs36 } from "react/jsx-runtime";
7295
+ import * as React33 from "react";
7296
+ import { jsx as jsx40, jsxs as jsxs37 } from "react/jsx-runtime";
6928
7297
  var FG = {
6929
7298
  neutral: "var(--text-secondary)",
6930
7299
  info: "var(--semantic-info-fg)",
@@ -6945,7 +7314,7 @@ var SEGMENT = {
6945
7314
  md: "gap-[7px] py-[var(--space-1)] px-[var(--space-3)] text-[14px]"
6946
7315
  };
6947
7316
  var DOT2 = { xs: 5, sm: 6, md: 7 };
6948
- var TwoTierBadge = React31.forwardRef(
7317
+ var TwoTierBadge = React33.forwardRef(
6949
7318
  ({ primary, secondary, tone = "neutral", emphasis = "subtle", size = "sm", showDot = false, className, style, ...props }, ref) => {
6950
7319
  const strong = emphasis === "strong";
6951
7320
  const fg = FG[tone];
@@ -6954,7 +7323,7 @@ var TwoTierBadge = React31.forwardRef(
6954
7323
  const frame = strong ? tinted : "var(--border-subtle)";
6955
7324
  const divider = strong ? tinted : "var(--border)";
6956
7325
  const dotSize = DOT2[size];
6957
- return /* @__PURE__ */ jsxs36(
7326
+ return /* @__PURE__ */ jsxs37(
6958
7327
  "span",
6959
7328
  {
6960
7329
  ref,
@@ -6968,14 +7337,14 @@ var TwoTierBadge = React31.forwardRef(
6968
7337
  style: { fontFamily: "var(--font-sans)", borderColor: frame, background: "transparent", ...style },
6969
7338
  ...props,
6970
7339
  children: [
6971
- /* @__PURE__ */ jsxs36(
7340
+ /* @__PURE__ */ jsxs37(
6972
7341
  "span",
6973
7342
  {
6974
7343
  "data-slot": "two-tier-badge-primary",
6975
7344
  className: cn("inline-flex items-center whitespace-nowrap font-semibold", SEGMENT[size]),
6976
7345
  style: { color: fg, background: strong ? BG[tone] : "transparent" },
6977
7346
  children: [
6978
- showDot ? /* @__PURE__ */ jsx39(
7347
+ showDot ? /* @__PURE__ */ jsx40(
6979
7348
  "span",
6980
7349
  {
6981
7350
  "aria-hidden": "true",
@@ -6990,11 +7359,11 @@ var TwoTierBadge = React31.forwardRef(
6990
7359
  }
6991
7360
  }
6992
7361
  ) : null,
6993
- /* @__PURE__ */ jsx39("span", { children: primary })
7362
+ /* @__PURE__ */ jsx40("span", { children: primary })
6994
7363
  ]
6995
7364
  }
6996
7365
  ),
6997
- secondary != null ? /* @__PURE__ */ jsx39(
7366
+ secondary != null ? /* @__PURE__ */ jsx40(
6998
7367
  "span",
6999
7368
  {
7000
7369
  "data-slot": "two-tier-badge-secondary",
@@ -7015,8 +7384,8 @@ var TwoTierBadge = React31.forwardRef(
7015
7384
  TwoTierBadge.displayName = "TwoTierBadge";
7016
7385
 
7017
7386
  // src/components/ui/status-badge.tsx
7018
- import * as React32 from "react";
7019
- import { jsx as jsx40, jsxs as jsxs37 } from "react/jsx-runtime";
7387
+ import * as React34 from "react";
7388
+ import { jsx as jsx41, jsxs as jsxs38 } from "react/jsx-runtime";
7020
7389
  var ROLE = {
7021
7390
  error: "error",
7022
7391
  warning: "warning",
@@ -7045,13 +7414,13 @@ var SIZE = {
7045
7414
  sm: { cls: "gap-[6px] py-[var(--space-1)] px-[var(--space-2)] text-[12px]", dot: 6 },
7046
7415
  md: { cls: "gap-[var(--space-2)] py-[var(--space-1)] px-[14px] text-[14px]", dot: 7 }
7047
7416
  };
7048
- var StatusBadge = React32.forwardRef(
7417
+ var StatusBadge = React34.forwardRef(
7049
7418
  ({ status = "active", emphasis = "subtle", size = "sm", showDot = true, pulse = true, className, children, style, ...props }, ref) => {
7050
7419
  const role = ROLE[status];
7051
7420
  const fg = FG2[role];
7052
7421
  const strong = emphasis === "strong";
7053
7422
  const ringDot = role === "neutral";
7054
- return /* @__PURE__ */ jsxs37(
7423
+ return /* @__PURE__ */ jsxs38(
7055
7424
  "span",
7056
7425
  {
7057
7426
  ref,
@@ -7069,7 +7438,7 @@ var StatusBadge = React32.forwardRef(
7069
7438
  },
7070
7439
  ...props,
7071
7440
  children: [
7072
- showDot ? /* @__PURE__ */ jsx40(
7441
+ showDot ? /* @__PURE__ */ jsx41(
7073
7442
  "span",
7074
7443
  {
7075
7444
  "aria-hidden": "true",
@@ -7087,7 +7456,7 @@ var StatusBadge = React32.forwardRef(
7087
7456
  }
7088
7457
  ) : null,
7089
7458
  children,
7090
- /* @__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}}" })
7459
+ /* @__PURE__ */ jsx41("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}}" })
7091
7460
  ]
7092
7461
  }
7093
7462
  );
@@ -7096,9 +7465,9 @@ var StatusBadge = React32.forwardRef(
7096
7465
  StatusBadge.displayName = "StatusBadge";
7097
7466
 
7098
7467
  // src/components/ui/notification-badge.tsx
7099
- import * as React33 from "react";
7468
+ import * as React35 from "react";
7100
7469
  import { cva as cva13 } from "class-variance-authority";
7101
- import { jsx as jsx41 } from "react/jsx-runtime";
7470
+ import { jsx as jsx42 } from "react/jsx-runtime";
7102
7471
  var notificationBadgeVariants = cva13(
7103
7472
  [
7104
7473
  "inline-flex shrink-0 items-center justify-center rounded-[var(--radius-full)]",
@@ -7129,7 +7498,7 @@ function formatNotificationCount(count, max) {
7129
7498
  }
7130
7499
  return String(count);
7131
7500
  }
7132
- var NotificationBadge = React33.forwardRef(
7501
+ var NotificationBadge = React35.forwardRef(
7133
7502
  ({
7134
7503
  className,
7135
7504
  count,
@@ -7144,7 +7513,7 @@ var NotificationBadge = React33.forwardRef(
7144
7513
  }
7145
7514
  const normalizedMax = Math.max(1, Math.floor(max));
7146
7515
  const label = ariaLabel ?? (count > normalizedMax ? `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${normalizedMax}\uAC1C \uC774\uC0C1` : `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${count}\uAC1C`);
7147
- return /* @__PURE__ */ jsx41(
7516
+ return /* @__PURE__ */ jsx42(
7148
7517
  "span",
7149
7518
  {
7150
7519
  ref,
@@ -7162,9 +7531,9 @@ var NotificationBadge = React33.forwardRef(
7162
7531
  NotificationBadge.displayName = "NotificationBadge";
7163
7532
 
7164
7533
  // src/components/ui/empty-state.tsx
7165
- import * as React34 from "react";
7534
+ import * as React36 from "react";
7166
7535
  import { cva as cva14 } from "class-variance-authority";
7167
- import { jsx as jsx42, jsxs as jsxs38 } from "react/jsx-runtime";
7536
+ import { jsx as jsx43, jsxs as jsxs39 } from "react/jsx-runtime";
7168
7537
  var emptyStateBaseVariants = cva14(
7169
7538
  [
7170
7539
  "flex flex-col items-center justify-center text-center",
@@ -7236,7 +7605,7 @@ var iconSize3 = {
7236
7605
  md: 20,
7237
7606
  lg: 24
7238
7607
  };
7239
- var EmptyState = React34.forwardRef(
7608
+ var EmptyState = React36.forwardRef(
7240
7609
  ({
7241
7610
  className,
7242
7611
  size = "md",
@@ -7251,7 +7620,7 @@ var EmptyState = React34.forwardRef(
7251
7620
  ...props
7252
7621
  }, ref) => {
7253
7622
  const resolvedSize = size ?? "md";
7254
- return /* @__PURE__ */ jsxs38(
7623
+ return /* @__PURE__ */ jsxs39(
7255
7624
  "div",
7256
7625
  {
7257
7626
  ref,
@@ -7260,17 +7629,17 @@ var EmptyState = React34.forwardRef(
7260
7629
  className: cn(emptyStateVariants({ size, tone, surface, bordered, className })),
7261
7630
  ...props,
7262
7631
  children: [
7263
- Icon ? /* @__PURE__ */ jsx42(
7632
+ Icon ? /* @__PURE__ */ jsx43(
7264
7633
  "span",
7265
7634
  {
7266
7635
  "aria-hidden": "true",
7267
7636
  "data-slot": "empty-state-icon",
7268
7637
  className: emptyStateIconVariants({ size: resolvedSize }),
7269
- children: /* @__PURE__ */ jsx42(Icon, { size: iconSize3[resolvedSize], strokeWidth: 1.75 })
7638
+ children: /* @__PURE__ */ jsx43(Icon, { size: iconSize3[resolvedSize], strokeWidth: 1.75 })
7270
7639
  }
7271
7640
  ) : null,
7272
- /* @__PURE__ */ jsxs38("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
7273
- /* @__PURE__ */ jsx42(
7641
+ /* @__PURE__ */ jsxs39("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
7642
+ /* @__PURE__ */ jsx43(
7274
7643
  "h2",
7275
7644
  {
7276
7645
  "data-slot": "empty-state-title",
@@ -7278,7 +7647,7 @@ var EmptyState = React34.forwardRef(
7278
7647
  children: title
7279
7648
  }
7280
7649
  ),
7281
- description ? /* @__PURE__ */ jsx42(
7650
+ description ? /* @__PURE__ */ jsx43(
7282
7651
  "p",
7283
7652
  {
7284
7653
  "data-slot": "empty-state-description",
@@ -7286,7 +7655,7 @@ var EmptyState = React34.forwardRef(
7286
7655
  children: description
7287
7656
  }
7288
7657
  ) : null,
7289
- hint ? /* @__PURE__ */ jsx42(
7658
+ hint ? /* @__PURE__ */ jsx43(
7290
7659
  "p",
7291
7660
  {
7292
7661
  "data-slot": "empty-state-hint",
@@ -7295,7 +7664,7 @@ var EmptyState = React34.forwardRef(
7295
7664
  }
7296
7665
  ) : null
7297
7666
  ] }),
7298
- action ? /* @__PURE__ */ jsx42("div", { "data-slot": "empty-state-action", className: "mt-[var(--space-2)]", children: action }) : null
7667
+ action ? /* @__PURE__ */ jsx43("div", { "data-slot": "empty-state-action", className: "mt-[var(--space-2)]", children: action }) : null
7299
7668
  ]
7300
7669
  }
7301
7670
  );
@@ -7304,10 +7673,10 @@ var EmptyState = React34.forwardRef(
7304
7673
  EmptyState.displayName = "EmptyState";
7305
7674
 
7306
7675
  // src/components/ui/error-state.tsx
7307
- import * as React35 from "react";
7676
+ import * as React37 from "react";
7308
7677
  import { AlertTriangle } from "lucide-react";
7309
7678
  import { cva as cva15 } from "class-variance-authority";
7310
- import { jsx as jsx43, jsxs as jsxs39 } from "react/jsx-runtime";
7679
+ import { jsx as jsx44, jsxs as jsxs40 } from "react/jsx-runtime";
7311
7680
  var errorStateVariants = cva15(
7312
7681
  [
7313
7682
  "flex flex-col items-center justify-center text-center",
@@ -7329,7 +7698,7 @@ var errorStateVariants = cva15(
7329
7698
  }
7330
7699
  }
7331
7700
  );
7332
- var ErrorState = React35.forwardRef(
7701
+ var ErrorState = React37.forwardRef(
7333
7702
  ({
7334
7703
  className,
7335
7704
  size = "md",
@@ -7340,7 +7709,7 @@ var ErrorState = React35.forwardRef(
7340
7709
  onRetry,
7341
7710
  retryLabel = "\uB2E4\uC2DC \uC2DC\uB3C4",
7342
7711
  ...props
7343
- }, ref) => /* @__PURE__ */ jsxs39(
7712
+ }, ref) => /* @__PURE__ */ jsxs40(
7344
7713
  "div",
7345
7714
  {
7346
7715
  ref,
@@ -7349,17 +7718,17 @@ var ErrorState = React35.forwardRef(
7349
7718
  className: cn(errorStateVariants({ size, surface, className })),
7350
7719
  ...props,
7351
7720
  children: [
7352
- /* @__PURE__ */ jsx43(
7721
+ /* @__PURE__ */ jsx44(
7353
7722
  "span",
7354
7723
  {
7355
7724
  "aria-hidden": "true",
7356
7725
  "data-slot": "error-state-icon",
7357
7726
  className: "inline-flex size-[48px] items-center justify-center rounded-[var(--radius-full)] bg-[var(--error-bg)] text-[var(--error)]",
7358
- children: /* @__PURE__ */ jsx43(AlertTriangle, { size: 24, strokeWidth: 1.75 })
7727
+ children: /* @__PURE__ */ jsx44(AlertTriangle, { size: 24, strokeWidth: 1.75 })
7359
7728
  }
7360
7729
  ),
7361
- /* @__PURE__ */ jsxs39("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
7362
- /* @__PURE__ */ jsx43(
7730
+ /* @__PURE__ */ jsxs40("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
7731
+ /* @__PURE__ */ jsx44(
7363
7732
  "h2",
7364
7733
  {
7365
7734
  "data-slot": "error-state-title",
@@ -7367,7 +7736,7 @@ var ErrorState = React35.forwardRef(
7367
7736
  children: title
7368
7737
  }
7369
7738
  ),
7370
- /* @__PURE__ */ jsx43(
7739
+ /* @__PURE__ */ jsx44(
7371
7740
  "p",
7372
7741
  {
7373
7742
  "data-slot": "error-state-message",
@@ -7375,7 +7744,7 @@ var ErrorState = React35.forwardRef(
7375
7744
  children: message
7376
7745
  }
7377
7746
  ),
7378
- errorCode ? /* @__PURE__ */ jsx43(
7747
+ errorCode ? /* @__PURE__ */ jsx44(
7379
7748
  "p",
7380
7749
  {
7381
7750
  "data-slot": "error-state-code",
@@ -7384,7 +7753,7 @@ var ErrorState = React35.forwardRef(
7384
7753
  }
7385
7754
  ) : null
7386
7755
  ] }),
7387
- onRetry ? /* @__PURE__ */ jsx43(Button, { size: "sm", variant: "outline", onClick: onRetry, children: retryLabel }) : null
7756
+ onRetry ? /* @__PURE__ */ jsx44(Button, { size: "sm", variant: "secondary", onClick: onRetry, children: retryLabel }) : null
7388
7757
  ]
7389
7758
  }
7390
7759
  )
@@ -7392,9 +7761,9 @@ var ErrorState = React35.forwardRef(
7392
7761
  ErrorState.displayName = "ErrorState";
7393
7762
 
7394
7763
  // src/components/ui/skeleton.tsx
7395
- import * as React36 from "react";
7764
+ import * as React38 from "react";
7396
7765
  import { cva as cva16 } from "class-variance-authority";
7397
- import { jsx as jsx44 } from "react/jsx-runtime";
7766
+ import { jsx as jsx45 } from "react/jsx-runtime";
7398
7767
  var skeletonVariants = cva16(
7399
7768
  [
7400
7769
  // bg-inset: light #F1F2F4 reads on white surfaces (bg-raised was white = invisible);
@@ -7438,8 +7807,8 @@ var spinnerVariants = cva16(
7438
7807
  }
7439
7808
  }
7440
7809
  );
7441
- var Skeleton = React36.forwardRef(
7442
- ({ className, shape, style, ...props }, ref) => /* @__PURE__ */ jsx44(
7810
+ var Skeleton = React38.forwardRef(
7811
+ ({ className, shape, style, ...props }, ref) => /* @__PURE__ */ jsx45(
7443
7812
  "div",
7444
7813
  {
7445
7814
  ref,
@@ -7452,15 +7821,15 @@ var Skeleton = React36.forwardRef(
7452
7821
  );
7453
7822
  Skeleton.displayName = "Skeleton";
7454
7823
  var defaultTextWidths = ["92%", "84%", "68%", "76%"];
7455
- var SkeletonText = React36.forwardRef(
7456
- ({ className, lines = 3, widths = defaultTextWidths, ...props }, ref) => /* @__PURE__ */ jsx44(
7824
+ var SkeletonText = React38.forwardRef(
7825
+ ({ className, lines = 3, widths = defaultTextWidths, ...props }, ref) => /* @__PURE__ */ jsx45(
7457
7826
  "div",
7458
7827
  {
7459
7828
  ref,
7460
7829
  "data-slot": "skeleton-text",
7461
7830
  className: cn("flex flex-col gap-[var(--space-2)]", className),
7462
7831
  ...props,
7463
- children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx44(
7832
+ children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx45(
7464
7833
  Skeleton,
7465
7834
  {
7466
7835
  shape: "text",
@@ -7472,7 +7841,7 @@ var SkeletonText = React36.forwardRef(
7472
7841
  )
7473
7842
  );
7474
7843
  SkeletonText.displayName = "SkeletonText";
7475
- var SkeletonRow = React36.forwardRef(
7844
+ var SkeletonRow = React38.forwardRef(
7476
7845
  ({
7477
7846
  className,
7478
7847
  columns,
@@ -7483,7 +7852,7 @@ var SkeletonRow = React36.forwardRef(
7483
7852
  }, ref) => {
7484
7853
  const rowCount = Math.max(5, count);
7485
7854
  const gridTemplateColumns = columns.map((column) => column.width ?? "1fr").join(" ");
7486
- return /* @__PURE__ */ jsx44(
7855
+ return /* @__PURE__ */ jsx45(
7487
7856
  "div",
7488
7857
  {
7489
7858
  ref,
@@ -7497,7 +7866,7 @@ var SkeletonRow = React36.forwardRef(
7497
7866
  className
7498
7867
  ),
7499
7868
  ...props,
7500
- children: Array.from({ length: rowCount }, (_, rowIndex) => /* @__PURE__ */ jsx44(
7869
+ children: Array.from({ length: rowCount }, (_, rowIndex) => /* @__PURE__ */ jsx45(
7501
7870
  "div",
7502
7871
  {
7503
7872
  "data-slot": "skeleton-row",
@@ -7505,11 +7874,11 @@ var SkeletonRow = React36.forwardRef(
7505
7874
  "grid min-h-[48px] items-center border-t border-[var(--border-subtle)] first:border-t-0"
7506
7875
  ),
7507
7876
  style: { gridTemplateColumns },
7508
- children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx44(
7877
+ children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx45(
7509
7878
  "div",
7510
7879
  {
7511
7880
  className: "px-[var(--space-4)] py-[var(--space-2)]",
7512
- children: /* @__PURE__ */ jsx44(
7881
+ children: /* @__PURE__ */ jsx45(
7513
7882
  Skeleton,
7514
7883
  {
7515
7884
  shape: "text",
@@ -7529,8 +7898,8 @@ var SkeletonRow = React36.forwardRef(
7529
7898
  }
7530
7899
  );
7531
7900
  SkeletonRow.displayName = "SkeletonRow";
7532
- var Spinner = React36.forwardRef(
7533
- ({ className, size, label = "\uB85C\uB529 \uC911", ...props }, ref) => /* @__PURE__ */ jsx44(
7901
+ var Spinner = React38.forwardRef(
7902
+ ({ className, size, label = "\uB85C\uB529 \uC911", ...props }, ref) => /* @__PURE__ */ jsx45(
7534
7903
  "span",
7535
7904
  {
7536
7905
  ref,
@@ -7545,12 +7914,12 @@ var Spinner = React36.forwardRef(
7545
7914
  Spinner.displayName = "Spinner";
7546
7915
 
7547
7916
  // src/components/ui/pagination.tsx
7548
- import * as React37 from "react";
7917
+ import * as React39 from "react";
7549
7918
  import { ChevronsLeft, ChevronLeft, ChevronRight as ChevronRight2, ChevronsRight } from "lucide-react";
7550
7919
  import { cva as cva17 } from "class-variance-authority";
7551
7920
 
7552
7921
  // src/components/ui/page-size-select.tsx
7553
- import { jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
7922
+ import { jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
7554
7923
  var DEFAULT_OPTIONS = [10, 20, 50, 100];
7555
7924
  function PageSizeSelect({
7556
7925
  value,
@@ -7569,7 +7938,7 @@ function PageSizeSelect({
7569
7938
  label: `${opt}${unit}`
7570
7939
  }));
7571
7940
  const selectSize = size === "compact" ? "sm" : "md";
7572
- return /* @__PURE__ */ jsxs40(
7941
+ return /* @__PURE__ */ jsxs41(
7573
7942
  "div",
7574
7943
  {
7575
7944
  "data-slot": "page-size-select",
@@ -7578,8 +7947,8 @@ function PageSizeSelect({
7578
7947
  className
7579
7948
  ),
7580
7949
  children: [
7581
- label != null ? /* @__PURE__ */ jsx45("span", { children: label }) : null,
7582
- /* @__PURE__ */ jsx45(
7950
+ label != null ? /* @__PURE__ */ jsx46("span", { children: label }) : null,
7951
+ /* @__PURE__ */ jsx46(
7583
7952
  Select,
7584
7953
  {
7585
7954
  id,
@@ -7601,7 +7970,7 @@ function PageSizeSelect({
7601
7970
  }
7602
7971
 
7603
7972
  // src/components/ui/pagination.tsx
7604
- import { jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
7973
+ import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
7605
7974
  var paginationVariants = cva17(
7606
7975
  [
7607
7976
  "flex w-full flex-col gap-[var(--space-3)]",
@@ -7622,7 +7991,7 @@ var paginationVariants = cva17(
7622
7991
  );
7623
7992
  var paginationControlVariants = cva17(
7624
7993
  [
7625
- "inline-flex shrink-0 items-center justify-center rounded-[var(--radius-sm)] border",
7994
+ "inline-flex shrink-0 items-center justify-center rounded-[var(--radius-md)] border",
7626
7995
  "border-transparent bg-transparent font-medium text-text-secondary",
7627
7996
  "transition-colors motion-reduce:transition-none",
7628
7997
  "hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)] hover:text-foreground",
@@ -7674,7 +8043,7 @@ function NavigationButton({
7674
8043
  icon: Icon,
7675
8044
  onPageChange
7676
8045
  }) {
7677
- return /* @__PURE__ */ jsx46(
8046
+ return /* @__PURE__ */ jsx47(
7678
8047
  "button",
7679
8048
  {
7680
8049
  "aria-label": label,
@@ -7682,11 +8051,11 @@ function NavigationButton({
7682
8051
  className: paginationControlVariants({ size }),
7683
8052
  type: "button",
7684
8053
  onClick: () => onPageChange?.(page),
7685
- children: /* @__PURE__ */ jsx46(Icon, { "aria-hidden": "true", "data-slot": "pagination-icon" })
8054
+ children: /* @__PURE__ */ jsx47(Icon, { "aria-hidden": "true", "data-slot": "pagination-icon" })
7686
8055
  }
7687
8056
  );
7688
8057
  }
7689
- var Pagination = React37.forwardRef(
8058
+ var Pagination = React39.forwardRef(
7690
8059
  ({
7691
8060
  className,
7692
8061
  size = "standard",
@@ -7711,7 +8080,7 @@ var Pagination = React37.forwardRef(
7711
8080
  const items = getPaginationItems(currentPage, pageCount);
7712
8081
  const isFirstPage = currentPage === 1;
7713
8082
  const isLastPage = currentPage === pageCount;
7714
- return /* @__PURE__ */ jsxs41(
8083
+ return /* @__PURE__ */ jsxs42(
7715
8084
  "nav",
7716
8085
  {
7717
8086
  ref,
@@ -7721,9 +8090,9 @@ var Pagination = React37.forwardRef(
7721
8090
  className: cn(paginationVariants({ size: resolvedSize, className })),
7722
8091
  ...props,
7723
8092
  children: [
7724
- /* @__PURE__ */ jsxs41("div", { className: "flex flex-wrap items-center gap-[var(--space-3)]", children: [
7725
- /* @__PURE__ */ jsx46("span", { "data-slot": "pagination-total", className: "font-medium text-text-secondary", children: totalLabel(total) }),
7726
- showPageSize ? /* @__PURE__ */ jsx46("div", { "data-slot": "pagination-size", children: /* @__PURE__ */ jsx46(
8093
+ /* @__PURE__ */ jsxs42("div", { className: "flex flex-wrap items-center gap-[var(--space-3)]", children: [
8094
+ /* @__PURE__ */ jsx47("span", { "data-slot": "pagination-total", className: "font-medium text-text-secondary", children: totalLabel(total) }),
8095
+ showPageSize ? /* @__PURE__ */ jsx47("div", { "data-slot": "pagination-size", children: /* @__PURE__ */ jsx47(
7727
8096
  PageSizeSelect,
7728
8097
  {
7729
8098
  label: pageSizeLabel,
@@ -7735,13 +8104,13 @@ var Pagination = React37.forwardRef(
7735
8104
  }
7736
8105
  ) }) : null
7737
8106
  ] }),
7738
- /* @__PURE__ */ jsxs41(
8107
+ /* @__PURE__ */ jsxs42(
7739
8108
  "div",
7740
8109
  {
7741
8110
  "data-slot": "pagination-list",
7742
8111
  className: "flex items-center justify-center gap-[var(--space-1)]",
7743
8112
  children: [
7744
- /* @__PURE__ */ jsx46(
8113
+ /* @__PURE__ */ jsx47(
7745
8114
  NavigationButton,
7746
8115
  {
7747
8116
  label: "\uCCAB \uD398\uC774\uC9C0",
@@ -7752,7 +8121,7 @@ var Pagination = React37.forwardRef(
7752
8121
  onPageChange
7753
8122
  }
7754
8123
  ),
7755
- /* @__PURE__ */ jsx46(
8124
+ /* @__PURE__ */ jsx47(
7756
8125
  NavigationButton,
7757
8126
  {
7758
8127
  label: "\uC774\uC804 \uD398\uC774\uC9C0",
@@ -7764,7 +8133,7 @@ var Pagination = React37.forwardRef(
7764
8133
  }
7765
8134
  ),
7766
8135
  items.map(
7767
- (item, index) => item === "ellipsis" ? /* @__PURE__ */ jsx46(
8136
+ (item, index) => item === "ellipsis" ? /* @__PURE__ */ jsx47(
7768
8137
  "span",
7769
8138
  {
7770
8139
  "data-slot": "pagination-ellipsis",
@@ -7776,7 +8145,7 @@ var Pagination = React37.forwardRef(
7776
8145
  children: "..."
7777
8146
  },
7778
8147
  `ellipsis-${index}`
7779
- ) : /* @__PURE__ */ jsx46(
8148
+ ) : /* @__PURE__ */ jsx47(
7780
8149
  "button",
7781
8150
  {
7782
8151
  "aria-label": `${item} \uD398\uC774\uC9C0`,
@@ -7790,7 +8159,7 @@ var Pagination = React37.forwardRef(
7790
8159
  item
7791
8160
  )
7792
8161
  ),
7793
- /* @__PURE__ */ jsx46(
8162
+ /* @__PURE__ */ jsx47(
7794
8163
  NavigationButton,
7795
8164
  {
7796
8165
  label: "\uB2E4\uC74C \uD398\uC774\uC9C0",
@@ -7801,7 +8170,7 @@ var Pagination = React37.forwardRef(
7801
8170
  onPageChange
7802
8171
  }
7803
8172
  ),
7804
- /* @__PURE__ */ jsx46(
8173
+ /* @__PURE__ */ jsx47(
7805
8174
  NavigationButton,
7806
8175
  {
7807
8176
  label: "\uB9C8\uC9C0\uB9C9 \uD398\uC774\uC9C0",
@@ -7824,17 +8193,17 @@ Pagination.displayName = "Pagination";
7824
8193
 
7825
8194
  // src/components/ui/mode-toggle.tsx
7826
8195
  import { cva as cva18 } from "class-variance-authority";
7827
- import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
8196
+ import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
7828
8197
  var modeToggleVariants = cva18(
7829
8198
  [
7830
- "inline-flex items-center rounded-[var(--radius-sm)] border border-[var(--border-subtle)]",
8199
+ "inline-flex items-center rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
7831
8200
  "bg-[var(--bg-inset)] p-[2px]"
7832
8201
  ].join(" ")
7833
8202
  );
7834
8203
  var modeToggleItemVariants = cva18(
7835
8204
  [
7836
8205
  "inline-flex min-h-[28px] cursor-pointer items-center justify-center gap-[var(--space-1)]",
7837
- "rounded-[calc(var(--radius-sm)_-_2px)] px-[var(--space-3)] py-[var(--space-1)]",
8206
+ "rounded-[calc(var(--radius-md)_-_2px)] px-[var(--space-3)] py-[var(--space-1)]",
7838
8207
  "font-[family-name:var(--font-display)] text-xs font-medium leading-none",
7839
8208
  "text-text-secondary transition-[background-color,color,box-shadow]",
7840
8209
  "duration-[var(--dur-fast)] ease-[var(--ease-standard)]",
@@ -7854,7 +8223,7 @@ function ModeToggle({
7854
8223
  onChange,
7855
8224
  ...props
7856
8225
  }) {
7857
- return /* @__PURE__ */ jsx47(
8226
+ return /* @__PURE__ */ jsx48(
7858
8227
  "div",
7859
8228
  {
7860
8229
  role: "group",
@@ -7864,7 +8233,7 @@ function ModeToggle({
7864
8233
  children: options.map((option) => {
7865
8234
  const Icon = option.icon;
7866
8235
  const isActive = option.value === value;
7867
- return /* @__PURE__ */ jsxs42(
8236
+ return /* @__PURE__ */ jsxs43(
7868
8237
  "button",
7869
8238
  {
7870
8239
  type: "button",
@@ -7880,8 +8249,8 @@ function ModeToggle({
7880
8249
  }
7881
8250
  },
7882
8251
  children: [
7883
- Icon ? /* @__PURE__ */ jsx47(Icon, { "aria-hidden": "true", "data-slot": "mode-toggle-icon" }) : null,
7884
- /* @__PURE__ */ jsx47("span", { children: option.label })
8252
+ Icon ? /* @__PURE__ */ jsx48(Icon, { "aria-hidden": "true", "data-slot": "mode-toggle-icon" }) : null,
8253
+ /* @__PURE__ */ jsx48("span", { children: option.label })
7885
8254
  ]
7886
8255
  },
7887
8256
  option.value
@@ -7892,9 +8261,9 @@ function ModeToggle({
7892
8261
  }
7893
8262
 
7894
8263
  // src/components/ui/action-footer.tsx
7895
- import * as React38 from "react";
8264
+ import * as React40 from "react";
7896
8265
  import { cva as cva19 } from "class-variance-authority";
7897
- import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
8266
+ import { jsx as jsx49, jsxs as jsxs44 } from "react/jsx-runtime";
7898
8267
  var actionFooterVariants = cva19(
7899
8268
  [
7900
8269
  "flex flex-wrap items-center gap-[var(--space-4)] border-t border-[var(--border-subtle)]",
@@ -7965,11 +8334,12 @@ function getStatusLabel(status) {
7965
8334
  }
7966
8335
  }
7967
8336
  function renderAction(action) {
7968
- return /* @__PURE__ */ jsx48(
8337
+ return /* @__PURE__ */ jsx49(
7969
8338
  Button,
7970
8339
  {
7971
8340
  variant: action.variant,
7972
- size: "md",
8341
+ size: "lg",
8342
+ className: footerButtonHitAreaClassName,
7973
8343
  disabled: action.disabled,
7974
8344
  loading: action.loading,
7975
8345
  leadingIcon: action.leadingIcon,
@@ -7979,7 +8349,7 @@ function renderAction(action) {
7979
8349
  action.id ?? action.label
7980
8350
  );
7981
8351
  }
7982
- var ActionFooter = React38.forwardRef(
8352
+ var ActionFooter = React40.forwardRef(
7983
8353
  ({
7984
8354
  className,
7985
8355
  status,
@@ -7996,7 +8366,7 @@ var ActionFooter = React38.forwardRef(
7996
8366
  const mainActions = sortMainActions(
7997
8367
  visibleActions.filter((action) => !destructiveVariants.has(action.variant ?? "default"))
7998
8368
  );
7999
- return /* @__PURE__ */ jsxs43(
8369
+ return /* @__PURE__ */ jsxs44(
8000
8370
  "div",
8001
8371
  {
8002
8372
  ref,
@@ -8005,7 +8375,7 @@ var ActionFooter = React38.forwardRef(
8005
8375
  className: cn(actionFooterVariants({ position, surface, className })),
8006
8376
  ...props,
8007
8377
  children: [
8008
- destructiveActions.length > 0 ? /* @__PURE__ */ jsx48(
8378
+ destructiveActions.length > 0 ? /* @__PURE__ */ jsx49(
8009
8379
  "div",
8010
8380
  {
8011
8381
  "data-slot": "action-footer-destructive-actions",
@@ -8013,7 +8383,7 @@ var ActionFooter = React38.forwardRef(
8013
8383
  children: destructiveActions.map(renderAction)
8014
8384
  }
8015
8385
  ) : null,
8016
- status ? /* @__PURE__ */ jsxs43(
8386
+ status ? /* @__PURE__ */ jsxs44(
8017
8387
  "div",
8018
8388
  {
8019
8389
  "data-slot": "action-footer-status",
@@ -8021,7 +8391,7 @@ var ActionFooter = React38.forwardRef(
8021
8391
  "aria-live": "polite",
8022
8392
  className: cn(actionFooterStatusVariants({ kind: status.kind })),
8023
8393
  children: [
8024
- /* @__PURE__ */ jsx48(
8394
+ /* @__PURE__ */ jsx49(
8025
8395
  "span",
8026
8396
  {
8027
8397
  "aria-hidden": "true",
@@ -8029,11 +8399,11 @@ var ActionFooter = React38.forwardRef(
8029
8399
  className: "size-[6px] shrink-0 rounded-[var(--radius-full)]"
8030
8400
  }
8031
8401
  ),
8032
- /* @__PURE__ */ jsx48("span", { className: "truncate", children: getStatusLabel(status) })
8402
+ /* @__PURE__ */ jsx49("span", { className: "truncate", children: getStatusLabel(status) })
8033
8403
  ]
8034
8404
  }
8035
8405
  ) : null,
8036
- /* @__PURE__ */ jsx48(
8406
+ /* @__PURE__ */ jsx49(
8037
8407
  "div",
8038
8408
  {
8039
8409
  "data-slot": "action-footer-main-actions",
@@ -8049,9 +8419,9 @@ var ActionFooter = React38.forwardRef(
8049
8419
  ActionFooter.displayName = "ActionFooter";
8050
8420
 
8051
8421
  // src/components/ui/toast.tsx
8052
- import * as React39 from "react";
8422
+ import * as React41 from "react";
8053
8423
  import { cva as cva20 } from "class-variance-authority";
8054
- import { jsx as jsx49, jsxs as jsxs44 } from "react/jsx-runtime";
8424
+ import { jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
8055
8425
  var DOT3 = {
8056
8426
  default: "var(--neutral)",
8057
8427
  success: "var(--success)",
@@ -8064,7 +8434,7 @@ var toastVariants = cva20(
8064
8434
  "flex min-w-[280px] max-w-[420px] items-center",
8065
8435
  "gap-[11px] rounded-[10px] border border-[var(--border)]",
8066
8436
  "px-[14px] py-[11px]",
8067
- "shadow-[var(--shadow-4)]",
8437
+ "shadow-[var(--shadow-8)]",
8068
8438
  "pointer-events-auto",
8069
8439
  "motion-reduce:animate-none"
8070
8440
  ].join(" "),
@@ -8169,7 +8539,7 @@ var toast = {
8169
8539
  }
8170
8540
  };
8171
8541
  var Toast = toast;
8172
- var ToastRoot = React39.forwardRef(
8542
+ var ToastRoot = React41.forwardRef(
8173
8543
  ({
8174
8544
  className,
8175
8545
  id,
@@ -8186,10 +8556,10 @@ var ToastRoot = React39.forwardRef(
8186
8556
  ...props
8187
8557
  }, ref) => {
8188
8558
  const durationMs = getToastDuration({ message, variant, duration });
8189
- const onCloseRef = React39.useRef(onClose);
8559
+ const onCloseRef = React41.useRef(onClose);
8190
8560
  onCloseRef.current = onClose;
8191
- const timerRef = React39.useRef(null);
8192
- React39.useEffect(() => {
8561
+ const timerRef = React41.useRef(null);
8562
+ React41.useEffect(() => {
8193
8563
  if (!onCloseRef.current) return void 0;
8194
8564
  const timer = createToastTimer(durationMs, () => onCloseRef.current?.());
8195
8565
  timerRef.current = timer;
@@ -8198,7 +8568,7 @@ var ToastRoot = React39.forwardRef(
8198
8568
  timerRef.current = null;
8199
8569
  };
8200
8570
  }, [durationMs]);
8201
- return /* @__PURE__ */ jsxs44(
8571
+ return /* @__PURE__ */ jsxs45(
8202
8572
  "div",
8203
8573
  {
8204
8574
  ref,
@@ -8226,7 +8596,7 @@ var ToastRoot = React39.forwardRef(
8226
8596
  },
8227
8597
  ...props,
8228
8598
  children: [
8229
- /* @__PURE__ */ jsx49(
8599
+ /* @__PURE__ */ jsx50(
8230
8600
  "span",
8231
8601
  {
8232
8602
  "aria-hidden": "true",
@@ -8235,8 +8605,8 @@ var ToastRoot = React39.forwardRef(
8235
8605
  style: { background: DOT3[variant] ?? DOT3.default }
8236
8606
  }
8237
8607
  ),
8238
- /* @__PURE__ */ jsxs44("div", { "data-slot": "toast-body", className: "min-w-0 flex-1", children: [
8239
- /* @__PURE__ */ jsx49(
8608
+ /* @__PURE__ */ jsxs45("div", { "data-slot": "toast-body", className: "min-w-0 flex-1", children: [
8609
+ /* @__PURE__ */ jsx50(
8240
8610
  "div",
8241
8611
  {
8242
8612
  "data-slot": "toast-message",
@@ -8244,7 +8614,7 @@ var ToastRoot = React39.forwardRef(
8244
8614
  children: message
8245
8615
  }
8246
8616
  ),
8247
- description ? /* @__PURE__ */ jsx49(
8617
+ description ? /* @__PURE__ */ jsx50(
8248
8618
  "div",
8249
8619
  {
8250
8620
  "data-slot": "toast-description",
@@ -8253,25 +8623,25 @@ var ToastRoot = React39.forwardRef(
8253
8623
  }
8254
8624
  ) : null
8255
8625
  ] }),
8256
- /* @__PURE__ */ jsxs44("div", { "data-slot": "toast-actions", className: "flex shrink-0 items-center gap-[2px]", children: [
8257
- action ? /* @__PURE__ */ jsx49(
8626
+ /* @__PURE__ */ jsxs45("div", { "data-slot": "toast-actions", className: "flex shrink-0 items-center gap-[2px]", children: [
8627
+ action ? /* @__PURE__ */ jsx50(
8258
8628
  Button,
8259
8629
  {
8260
8630
  "data-slot": "toast-action",
8261
8631
  size: "xs",
8262
- variant: "outline",
8632
+ variant: "secondary",
8263
8633
  onClick: action.onClick,
8264
8634
  children: action.label
8265
8635
  }
8266
8636
  ) : null,
8267
- /* @__PURE__ */ jsx49(
8637
+ /* @__PURE__ */ jsx50(
8268
8638
  "button",
8269
8639
  {
8270
8640
  type: "button",
8271
8641
  "aria-label": "\uC54C\uB9BC \uB2EB\uAE30",
8272
8642
  "data-slot": "toast-close",
8273
8643
  className: cn(
8274
- "inline-flex size-[28px] shrink-0 cursor-pointer items-center justify-center rounded-[var(--radius-sm)]",
8644
+ "inline-flex size-[28px] shrink-0 cursor-pointer items-center justify-center rounded-[var(--radius-md)]",
8275
8645
  "text-current opacity-70 transition-opacity hover:opacity-100",
8276
8646
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]"
8277
8647
  ),
@@ -8286,7 +8656,7 @@ var ToastRoot = React39.forwardRef(
8286
8656
  }
8287
8657
  );
8288
8658
  ToastRoot.displayName = "ToastRoot";
8289
- var ToastViewport = React39.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx49(
8659
+ var ToastViewport = React41.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx50(
8290
8660
  "ol",
8291
8661
  {
8292
8662
  ref,
@@ -8297,24 +8667,24 @@ var ToastViewport = React39.forwardRef(({ className, ...props }, ref) => /* @__P
8297
8667
  ));
8298
8668
  ToastViewport.displayName = "ToastViewport";
8299
8669
  function ToastProvider({ children, maxToasts = 3, className, ...props }) {
8300
- const [items, setItems] = React39.useState([]);
8301
- React39.useEffect(
8670
+ const [items, setItems] = React41.useState([]);
8671
+ React41.useEffect(
8302
8672
  () => toast.subscribe((nextItems) => {
8303
8673
  setItems(limitToasts(nextItems, maxToasts));
8304
8674
  }),
8305
8675
  [maxToasts]
8306
8676
  );
8307
- return /* @__PURE__ */ jsxs44("div", { "data-slot": "toast-provider", className, ...props, children: [
8677
+ return /* @__PURE__ */ jsxs45("div", { "data-slot": "toast-provider", className, ...props, children: [
8308
8678
  children,
8309
- /* @__PURE__ */ jsx49(ToastViewport, { children: items.map((item) => /* @__PURE__ */ jsx49("li", { children: /* @__PURE__ */ jsx49(ToastRoot, { ...item, onClose: () => toast.dismiss(item.id) }) }, item.id)) })
8679
+ /* @__PURE__ */ jsx50(ToastViewport, { children: items.map((item) => /* @__PURE__ */ jsx50("li", { children: /* @__PURE__ */ jsx50(ToastRoot, { ...item, onClose: () => toast.dismiss(item.id) }) }, item.id)) })
8310
8680
  ] });
8311
8681
  }
8312
8682
 
8313
8683
  // src/components/ui/otp-field.tsx
8314
- import * as React40 from "react";
8684
+ import * as React42 from "react";
8315
8685
  import { cva as cva21 } from "class-variance-authority";
8316
8686
  import { AlertCircle as AlertCircle4 } from "lucide-react";
8317
- import { Fragment as Fragment9, jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
8687
+ import { Fragment as Fragment9, jsx as jsx51, jsxs as jsxs46 } from "react/jsx-runtime";
8318
8688
  var otpFieldVariants = cva21("flex w-full min-w-0 flex-col gap-[var(--space-3)]", {
8319
8689
  variants: {
8320
8690
  size: {
@@ -8441,7 +8811,7 @@ function fillDigitsFromIndex(slots, index, inserted, length) {
8441
8811
  focusIndex: Math.min(cursor, length - 1)
8442
8812
  };
8443
8813
  }
8444
- var OTPField = React40.forwardRef(
8814
+ var OTPField = React42.forwardRef(
8445
8815
  ({
8446
8816
  className,
8447
8817
  defaultValue,
@@ -8463,24 +8833,24 @@ var OTPField = React40.forwardRef(
8463
8833
  required,
8464
8834
  ...props
8465
8835
  }, ref) => {
8466
- const generatedId = React40.useId();
8836
+ const generatedId = React42.useId();
8467
8837
  const fieldId = id ?? generatedId;
8468
8838
  const labelId = `${fieldId}-label`;
8469
8839
  const helperId = helperText ? `${fieldId}-helper` : void 0;
8470
8840
  const errorId = errorText ? `${fieldId}-error` : void 0;
8471
8841
  const resolvedState = invalid || errorText ? "error" : "default";
8472
8842
  const isControlled = value !== void 0;
8473
- const [uncontrolledSlots, setUncontrolledSlots] = React40.useState(
8843
+ const [uncontrolledSlots, setUncontrolledSlots] = React42.useState(
8474
8844
  () => toDigitsArray(onlyDigits(defaultValue, length), length)
8475
8845
  );
8476
- const resolvedSlots = React40.useMemo(
8846
+ const resolvedSlots = React42.useMemo(
8477
8847
  () => isControlled ? toDigitsArray(onlyDigits(value, length), length) : uncontrolledSlots,
8478
8848
  [isControlled, length, uncontrolledSlots, value]
8479
8849
  );
8480
8850
  const resolvedValue = joinDigits(resolvedSlots).slice(0, length);
8481
- const cellsRef = React40.useRef([]);
8851
+ const cellsRef = React42.useRef([]);
8482
8852
  const groupDescribedBy = [helperId, errorId].filter(Boolean).join(" ") || void 0;
8483
- const setResolvedValue = React40.useCallback(
8853
+ const setResolvedValue = React42.useCallback(
8484
8854
  (nextSlots, focusIndex) => {
8485
8855
  const normalizedSlots = nextSlots.slice(0, length);
8486
8856
  const normalizedValue = joinDigits(normalizedSlots).slice(0, length);
@@ -8499,7 +8869,7 @@ var OTPField = React40.forwardRef(
8499
8869
  },
8500
8870
  [disabled, isControlled, length, onComplete, onValueChange]
8501
8871
  );
8502
- return /* @__PURE__ */ jsxs45(
8872
+ return /* @__PURE__ */ jsxs46(
8503
8873
  "fieldset",
8504
8874
  {
8505
8875
  ref,
@@ -8512,7 +8882,7 @@ var OTPField = React40.forwardRef(
8512
8882
  className: cn(otpFieldVariants({ size, className })),
8513
8883
  ...props,
8514
8884
  children: [
8515
- /* @__PURE__ */ jsxs45(
8885
+ /* @__PURE__ */ jsxs46(
8516
8886
  "legend",
8517
8887
  {
8518
8888
  id: labelId,
@@ -8520,11 +8890,11 @@ var OTPField = React40.forwardRef(
8520
8890
  className: "text-sm font-medium leading-snug text-foreground",
8521
8891
  children: [
8522
8892
  label,
8523
- required ? /* @__PURE__ */ jsx50("span", { "aria-hidden": "true", className: "ml-1 font-bold text-[var(--error)]", children: "*" }) : null
8893
+ required ? /* @__PURE__ */ jsx51("span", { "aria-hidden": "true", className: "ml-1 font-bold text-[var(--error)]", children: "*" }) : null
8524
8894
  ]
8525
8895
  }
8526
8896
  ),
8527
- /* @__PURE__ */ jsx50(
8897
+ /* @__PURE__ */ jsx51(
8528
8898
  "div",
8529
8899
  {
8530
8900
  "data-slot": "otp-field-group",
@@ -8534,7 +8904,7 @@ var OTPField = React40.forwardRef(
8534
8904
  children: Array.from({ length }, (_, index) => {
8535
8905
  const digit = resolvedSlots[index] ?? "";
8536
8906
  const inputId = `${fieldId}-cell-${index + 1}`;
8537
- return /* @__PURE__ */ jsx50(
8907
+ return /* @__PURE__ */ jsx51(
8538
8908
  "input",
8539
8909
  {
8540
8910
  ref: (node) => {
@@ -8629,15 +8999,15 @@ var OTPField = React40.forwardRef(
8629
8999
  })
8630
9000
  }
8631
9001
  ),
8632
- helperText || errorText ? /* @__PURE__ */ jsx50(
9002
+ helperText || errorText ? /* @__PURE__ */ jsx51(
8633
9003
  "p",
8634
9004
  {
8635
9005
  id: errorText ? errorId : helperId,
8636
9006
  "data-slot": "otp-field-message",
8637
9007
  "data-kind": errorText ? "error" : "helper",
8638
9008
  className: otpFieldMessageVariants({ state: resolvedState }),
8639
- children: errorText ? /* @__PURE__ */ jsxs45(Fragment9, { children: [
8640
- /* @__PURE__ */ jsx50(
9009
+ children: errorText ? /* @__PURE__ */ jsxs46(Fragment9, { children: [
9010
+ /* @__PURE__ */ jsx51(
8641
9011
  AlertCircle4,
8642
9012
  {
8643
9013
  "aria-hidden": "true",
@@ -8645,11 +9015,11 @@ var OTPField = React40.forwardRef(
8645
9015
  strokeWidth: 2
8646
9016
  }
8647
9017
  ),
8648
- /* @__PURE__ */ jsx50("span", { children: errorText })
8649
- ] }) : /* @__PURE__ */ jsx50("span", { children: helperText })
9018
+ /* @__PURE__ */ jsx51("span", { children: errorText })
9019
+ ] }) : /* @__PURE__ */ jsx51("span", { children: helperText })
8650
9020
  }
8651
9021
  ) : null,
8652
- name ? /* @__PURE__ */ jsx50(
9022
+ name ? /* @__PURE__ */ jsx51(
8653
9023
  "input",
8654
9024
  {
8655
9025
  "aria-hidden": "true",
@@ -8670,10 +9040,10 @@ var OTPField = React40.forwardRef(
8670
9040
  OTPField.displayName = "OTPField";
8671
9041
 
8672
9042
  // src/components/ui/search-field.tsx
8673
- import * as React41 from "react";
8674
- import { Search, X as X4 } from "lucide-react";
9043
+ import * as React43 from "react";
9044
+ import { Search, X as X5 } from "lucide-react";
8675
9045
  import { cva as cva22 } from "class-variance-authority";
8676
- import { jsx as jsx51, jsxs as jsxs46 } from "react/jsx-runtime";
9046
+ import { jsx as jsx52, jsxs as jsxs47 } from "react/jsx-runtime";
8677
9047
  var searchFieldVariants = cva22("relative flex w-full items-center", {
8678
9048
  variants: {
8679
9049
  size: {
@@ -8738,7 +9108,7 @@ var iconSize4 = {
8738
9108
  function hasVisibleValue(value) {
8739
9109
  return typeof value === "string" ? value.length > 0 : value !== void 0;
8740
9110
  }
8741
- var SearchField = React41.forwardRef(
9111
+ var SearchField = React43.forwardRef(
8742
9112
  ({
8743
9113
  className,
8744
9114
  inputMode = "search",
@@ -8754,12 +9124,12 @@ var SearchField = React41.forwardRef(
8754
9124
  ...props
8755
9125
  }, ref) => {
8756
9126
  const resolvedSize = size ?? "md";
8757
- const inputRef = React41.useRef(null);
8758
- const [hasText, setHasText] = React41.useState(
9127
+ const inputRef = React43.useRef(null);
9128
+ const [hasText, setHasText] = React43.useState(
8759
9129
  () => hasVisibleValue(value ?? defaultValue)
8760
9130
  );
8761
- React41.useImperativeHandle(ref, () => inputRef.current);
8762
- React41.useEffect(() => {
9131
+ React43.useImperativeHandle(ref, () => inputRef.current);
9132
+ React43.useEffect(() => {
8763
9133
  if (value !== void 0) {
8764
9134
  setHasText(hasVisibleValue(value));
8765
9135
  }
@@ -8772,14 +9142,14 @@ var SearchField = React41.forwardRef(
8772
9142
  }
8773
9143
  onClear?.();
8774
9144
  };
8775
- return /* @__PURE__ */ jsxs46(
9145
+ return /* @__PURE__ */ jsxs47(
8776
9146
  "div",
8777
9147
  {
8778
9148
  "data-slot": "search-field",
8779
9149
  "data-size": resolvedSize,
8780
9150
  className: cn(searchFieldVariants({ size, className })),
8781
9151
  children: [
8782
- /* @__PURE__ */ jsx51(
9152
+ /* @__PURE__ */ jsx52(
8783
9153
  Search,
8784
9154
  {
8785
9155
  "aria-hidden": "true",
@@ -8789,7 +9159,7 @@ var SearchField = React41.forwardRef(
8789
9159
  strokeWidth: resolvedSize === "sm" ? 2 : 1.75
8790
9160
  }
8791
9161
  ),
8792
- /* @__PURE__ */ jsx51(
9162
+ /* @__PURE__ */ jsx52(
8793
9163
  "input",
8794
9164
  {
8795
9165
  ref: inputRef,
@@ -8810,7 +9180,7 @@ var SearchField = React41.forwardRef(
8810
9180
  ...props
8811
9181
  }
8812
9182
  ),
8813
- showClear ? /* @__PURE__ */ jsx51(
9183
+ showClear ? /* @__PURE__ */ jsx52(
8814
9184
  "button",
8815
9185
  {
8816
9186
  type: "button",
@@ -8818,7 +9188,7 @@ var SearchField = React41.forwardRef(
8818
9188
  "data-slot": "search-field-clear",
8819
9189
  className: "absolute right-[8px] top-1/2 inline-flex size-[var(--space-4)] -translate-y-1/2 cursor-pointer items-center justify-center rounded-[var(--radius-full)] text-text-tertiary transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
8820
9190
  onClick: clearInput,
8821
- children: /* @__PURE__ */ jsx51(X4, { "aria-hidden": "true", size: 16, strokeWidth: 1.75 })
9191
+ children: /* @__PURE__ */ jsx52(X5, { "aria-hidden": "true", size: 16, strokeWidth: 1.75 })
8822
9192
  }
8823
9193
  ) : null
8824
9194
  ]
@@ -8829,9 +9199,9 @@ var SearchField = React41.forwardRef(
8829
9199
  SearchField.displayName = "SearchField";
8830
9200
 
8831
9201
  // src/components/ui/checkbox-group.tsx
8832
- import * as React42 from "react";
9202
+ import * as React44 from "react";
8833
9203
  import { cva as cva23 } from "class-variance-authority";
8834
- import { jsx as jsx52 } from "react/jsx-runtime";
9204
+ import { jsx as jsx53 } from "react/jsx-runtime";
8835
9205
  var checkboxGroupVariants = cva23("gap-[var(--space-2)]", {
8836
9206
  variants: {
8837
9207
  appearance: {
@@ -8857,7 +9227,7 @@ var checkboxGroupVariants = cva23("gap-[var(--space-2)]", {
8857
9227
  function toSelectionSet(value) {
8858
9228
  return new Set(value ?? []);
8859
9229
  }
8860
- var CheckboxGroup = React42.forwardRef(
9230
+ var CheckboxGroup = React44.forwardRef(
8861
9231
  ({
8862
9232
  className,
8863
9233
  children,
@@ -8873,14 +9243,14 @@ var CheckboxGroup = React42.forwardRef(
8873
9243
  ...props
8874
9244
  }, ref) => {
8875
9245
  const isControlled = value != null;
8876
- const [uncontrolledValue, setUncontrolledValue] = React42.useState(
9246
+ const [uncontrolledValue, setUncontrolledValue] = React44.useState(
8877
9247
  () => toSelectionSet(defaultValue)
8878
9248
  );
8879
- const selectedValues = React42.useMemo(
9249
+ const selectedValues = React44.useMemo(
8880
9250
  () => isControlled ? toSelectionSet(value) : uncontrolledValue,
8881
9251
  [isControlled, uncontrolledValue, value]
8882
9252
  );
8883
- const toggleValue = React42.useCallback(
9253
+ const toggleValue = React44.useCallback(
8884
9254
  (itemValue, checked) => {
8885
9255
  const nextValues = new Set(selectedValues);
8886
9256
  if (checked) {
@@ -8896,7 +9266,7 @@ var CheckboxGroup = React42.forwardRef(
8896
9266
  },
8897
9267
  [isControlled, onValueChange, selectedValues]
8898
9268
  );
8899
- const contextValue = React42.useMemo(
9269
+ const contextValue = React44.useMemo(
8900
9270
  () => ({
8901
9271
  appearance,
8902
9272
  density,
@@ -8907,7 +9277,7 @@ var CheckboxGroup = React42.forwardRef(
8907
9277
  }),
8908
9278
  [appearance, density, disabled, name, selectedValues, toggleValue]
8909
9279
  );
8910
- return /* @__PURE__ */ jsx52(CheckboxGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx52(
9280
+ return /* @__PURE__ */ jsx53(CheckboxGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx53(
8911
9281
  "div",
8912
9282
  {
8913
9283
  ref,
@@ -8931,11 +9301,11 @@ var CheckboxGroup = React42.forwardRef(
8931
9301
  CheckboxGroup.displayName = "CheckboxGroup";
8932
9302
 
8933
9303
  // src/components/ui/radio-group.tsx
8934
- import * as React43 from "react";
9304
+ import * as React45 from "react";
8935
9305
  import { cva as cva24 } from "class-variance-authority";
8936
9306
  import { Circle } from "lucide-react";
8937
9307
  import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
8938
- import { jsx as jsx53, jsxs as jsxs47 } from "react/jsx-runtime";
9308
+ import { jsx as jsx54, jsxs as jsxs48 } from "react/jsx-runtime";
8939
9309
  var radioGroupVariants = cva24("gap-[var(--space-2)]", {
8940
9310
  variants: {
8941
9311
  appearance: {
@@ -8970,7 +9340,7 @@ var radioVariants = cva24(
8970
9340
  {
8971
9341
  variants: {
8972
9342
  appearance: {
8973
- plain: "inline-flex items-start gap-[var(--space-3)] rounded-[var(--radius-sm)] px-pad-compact-x py-pad-compact-y",
9343
+ plain: "inline-flex items-start gap-[var(--space-3)] rounded-[var(--radius-md)] px-pad-compact-x py-pad-compact-y",
8974
9344
  card: [
8975
9345
  "flex min-h-[calc(var(--space-12)+var(--space-2))] items-start gap-[var(--space-3)]",
8976
9346
  "rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-surface)]",
@@ -9024,11 +9394,11 @@ var radioControlVariants = cva24(
9024
9394
  }
9025
9395
  }
9026
9396
  );
9027
- var RadioGroupContext = React43.createContext({
9397
+ var RadioGroupContext = React45.createContext({
9028
9398
  appearance: "plain",
9029
9399
  density: "comfortable"
9030
9400
  });
9031
- var RadioGroup = React43.forwardRef(
9401
+ var RadioGroup = React45.forwardRef(
9032
9402
  ({
9033
9403
  className,
9034
9404
  children,
@@ -9039,11 +9409,11 @@ var RadioGroup = React43.forwardRef(
9039
9409
  required,
9040
9410
  ...props
9041
9411
  }, ref) => {
9042
- const contextValue = React43.useMemo(
9412
+ const contextValue = React45.useMemo(
9043
9413
  () => ({ appearance, density }),
9044
9414
  [appearance, density]
9045
9415
  );
9046
- return /* @__PURE__ */ jsx53(RadioGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx53(
9416
+ return /* @__PURE__ */ jsx54(RadioGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx54(
9047
9417
  RadioGroupPrimitive.Root,
9048
9418
  {
9049
9419
  ref,
@@ -9066,13 +9436,13 @@ var RadioGroup = React43.forwardRef(
9066
9436
  }
9067
9437
  );
9068
9438
  RadioGroup.displayName = "RadioGroup";
9069
- var Radio = React43.forwardRef(({ className, children, description, id, ...props }, ref) => {
9070
- const { appearance, density } = React43.useContext(RadioGroupContext);
9071
- const generatedId = React43.useId();
9439
+ var Radio = React45.forwardRef(({ className, children, description, id, ...props }, ref) => {
9440
+ const { appearance, density } = React45.useContext(RadioGroupContext);
9441
+ const generatedId = React45.useId();
9072
9442
  const radioId = id ?? generatedId;
9073
9443
  const labelId = `${radioId}-label`;
9074
9444
  const descriptionId = description ? `${radioId}-description` : void 0;
9075
- return /* @__PURE__ */ jsxs47(
9445
+ return /* @__PURE__ */ jsxs48(
9076
9446
  RadioGroupPrimitive.Item,
9077
9447
  {
9078
9448
  ref,
@@ -9083,24 +9453,24 @@ var Radio = React43.forwardRef(({ className, children, description, id, ...props
9083
9453
  className: cn(radioVariants({ appearance, density }), className),
9084
9454
  ...props,
9085
9455
  children: [
9086
- /* @__PURE__ */ jsx53(
9456
+ /* @__PURE__ */ jsx54(
9087
9457
  "span",
9088
9458
  {
9089
9459
  "aria-hidden": "true",
9090
9460
  "data-slot": "radio-control",
9091
9461
  className: radioControlVariants({ appearance }),
9092
- children: /* @__PURE__ */ jsx53(
9462
+ children: /* @__PURE__ */ jsx54(
9093
9463
  RadioGroupPrimitive.Indicator,
9094
9464
  {
9095
9465
  "data-slot": "radio-indicator",
9096
9466
  className: "flex items-center justify-center",
9097
- children: /* @__PURE__ */ jsx53(Circle, { "aria-hidden": "true", size: 8, fill: "currentColor" })
9467
+ children: /* @__PURE__ */ jsx54(Circle, { "aria-hidden": "true", size: 8, fill: "currentColor" })
9098
9468
  }
9099
9469
  )
9100
9470
  }
9101
9471
  ),
9102
- /* @__PURE__ */ jsxs47("span", { className: "flex min-w-0 flex-col gap-[var(--space-1)]", children: [
9103
- /* @__PURE__ */ jsx53(
9472
+ /* @__PURE__ */ jsxs48("span", { className: "flex min-w-0 flex-col gap-[var(--space-1)]", children: [
9473
+ /* @__PURE__ */ jsx54(
9104
9474
  "span",
9105
9475
  {
9106
9476
  id: labelId,
@@ -9112,7 +9482,7 @@ var Radio = React43.forwardRef(({ className, children, description, id, ...props
9112
9482
  children
9113
9483
  }
9114
9484
  ),
9115
- description ? /* @__PURE__ */ jsx53(
9485
+ description ? /* @__PURE__ */ jsx54(
9116
9486
  "span",
9117
9487
  {
9118
9488
  id: descriptionId,
@@ -9130,20 +9500,20 @@ Radio.displayName = "Radio";
9130
9500
 
9131
9501
  // src/components/ui/scroll-area.tsx
9132
9502
  import { ScrollArea as ScrollAreaPrimitive } from "radix-ui";
9133
- import { jsx as jsx54, jsxs as jsxs48 } from "react/jsx-runtime";
9503
+ import { jsx as jsx55, jsxs as jsxs49 } from "react/jsx-runtime";
9134
9504
  function ScrollArea({
9135
9505
  className,
9136
9506
  children,
9137
9507
  ...props
9138
9508
  }) {
9139
- return /* @__PURE__ */ jsxs48(
9509
+ return /* @__PURE__ */ jsxs49(
9140
9510
  ScrollAreaPrimitive.Root,
9141
9511
  {
9142
9512
  "data-slot": "scroll-area",
9143
9513
  className: cn("relative", className),
9144
9514
  ...props,
9145
9515
  children: [
9146
- /* @__PURE__ */ jsx54(
9516
+ /* @__PURE__ */ jsx55(
9147
9517
  ScrollAreaPrimitive.Viewport,
9148
9518
  {
9149
9519
  "data-slot": "scroll-area-viewport",
@@ -9151,8 +9521,8 @@ function ScrollArea({
9151
9521
  children
9152
9522
  }
9153
9523
  ),
9154
- /* @__PURE__ */ jsx54(ScrollBar, {}),
9155
- /* @__PURE__ */ jsx54(ScrollAreaPrimitive.Corner, {})
9524
+ /* @__PURE__ */ jsx55(ScrollBar, {}),
9525
+ /* @__PURE__ */ jsx55(ScrollAreaPrimitive.Corner, {})
9156
9526
  ]
9157
9527
  }
9158
9528
  );
@@ -9162,7 +9532,7 @@ function ScrollBar({
9162
9532
  orientation = "vertical",
9163
9533
  ...props
9164
9534
  }) {
9165
- return /* @__PURE__ */ jsx54(
9535
+ return /* @__PURE__ */ jsx55(
9166
9536
  ScrollAreaPrimitive.ScrollAreaScrollbar,
9167
9537
  {
9168
9538
  "data-slot": "scroll-area-scrollbar",
@@ -9174,7 +9544,7 @@ function ScrollBar({
9174
9544
  className
9175
9545
  ),
9176
9546
  ...props,
9177
- children: /* @__PURE__ */ jsx54(
9547
+ children: /* @__PURE__ */ jsx55(
9178
9548
  ScrollAreaPrimitive.ScrollAreaThumb,
9179
9549
  {
9180
9550
  "data-slot": "scroll-area-thumb",
@@ -9186,7 +9556,7 @@ function ScrollBar({
9186
9556
  }
9187
9557
 
9188
9558
  // src/components/ui/progress.tsx
9189
- import { jsx as jsx55 } from "react/jsx-runtime";
9559
+ import { jsx as jsx56 } from "react/jsx-runtime";
9190
9560
  var progressFillByStatus = {
9191
9561
  active: "bg-[var(--primary)]",
9192
9562
  success: "bg-[var(--success)]",
@@ -9207,7 +9577,7 @@ function Progress({
9207
9577
  const clamped = Math.max(0, Math.min(safeMax, value));
9208
9578
  const percent = clamped / safeMax * 100;
9209
9579
  const w = typeof width === "number" ? `${width}px` : width;
9210
- return /* @__PURE__ */ jsx55(
9580
+ return /* @__PURE__ */ jsx56(
9211
9581
  "div",
9212
9582
  {
9213
9583
  role: "progressbar",
@@ -9221,7 +9591,7 @@ function Progress({
9221
9591
  ),
9222
9592
  style: { width: w, height: `${height}px`, ...style },
9223
9593
  ...props,
9224
- children: /* @__PURE__ */ jsx55(
9594
+ children: /* @__PURE__ */ jsx56(
9225
9595
  "div",
9226
9596
  {
9227
9597
  className: cn(
@@ -9236,10 +9606,10 @@ function Progress({
9236
9606
  }
9237
9607
 
9238
9608
  // src/components/ui/tree-view.tsx
9239
- import * as React44 from "react";
9609
+ import * as React46 from "react";
9240
9610
  import { ChevronRight as ChevronRight3 } from "lucide-react";
9241
9611
  import { cva as cva25 } from "class-variance-authority";
9242
- import { jsx as jsx56, jsxs as jsxs49 } from "react/jsx-runtime";
9612
+ import { jsx as jsx57, jsxs as jsxs50 } from "react/jsx-runtime";
9243
9613
  var treeViewVariants = cva25(
9244
9614
  "m-0 list-none p-[var(--space-1)] text-body-sm text-foreground"
9245
9615
  );
@@ -9342,27 +9712,27 @@ function TreeView({
9342
9712
  ...rest
9343
9713
  }) {
9344
9714
  const isExpandedControlled = expandedIds !== void 0;
9345
- const [internalExpanded, setInternalExpanded] = React44.useState(
9715
+ const [internalExpanded, setInternalExpanded] = React46.useState(
9346
9716
  () => defaultExpandedIds ?? []
9347
9717
  );
9348
9718
  const expandedList = isExpandedControlled ? expandedIds : internalExpanded;
9349
- const expandedSet = React44.useMemo(() => new Set(expandedList), [expandedList]);
9350
- const items = React44.useMemo(
9719
+ const expandedSet = React46.useMemo(() => new Set(expandedList), [expandedList]);
9720
+ const items = React46.useMemo(
9351
9721
  () => flattenVisibleNodes(nodes, getChildren, expandedSet),
9352
9722
  [nodes, getChildren, expandedSet]
9353
9723
  );
9354
- const [focusedId, setFocusedId] = React44.useState(null);
9724
+ const [focusedId, setFocusedId] = React46.useState(null);
9355
9725
  const visibleIds = items.map((item) => item.id);
9356
9726
  const activeId = focusedId && visibleIds.includes(focusedId) ? focusedId : selectedId && visibleIds.includes(selectedId) ? selectedId : visibleIds[0] ?? null;
9357
- const itemRefs = React44.useRef(/* @__PURE__ */ new Map());
9358
- const commitExpanded = React44.useCallback(
9727
+ const itemRefs = React46.useRef(/* @__PURE__ */ new Map());
9728
+ const commitExpanded = React46.useCallback(
9359
9729
  (next) => {
9360
9730
  if (!isExpandedControlled) setInternalExpanded(next);
9361
9731
  onExpandedChange?.(next);
9362
9732
  },
9363
9733
  [isExpandedControlled, onExpandedChange]
9364
9734
  );
9365
- const setExpanded = React44.useCallback(
9735
+ const setExpanded = React46.useCallback(
9366
9736
  (id, expand) => {
9367
9737
  const has = expandedSet.has(id);
9368
9738
  if (expand && !has) {
@@ -9373,7 +9743,7 @@ function TreeView({
9373
9743
  },
9374
9744
  [commitExpanded, expandedList, expandedSet]
9375
9745
  );
9376
- const focusItem = React44.useCallback((id) => {
9746
+ const focusItem = React46.useCallback((id) => {
9377
9747
  setFocusedId(id);
9378
9748
  itemRefs.current.get(id)?.focus();
9379
9749
  }, []);
@@ -9409,7 +9779,7 @@ function TreeView({
9409
9779
  const selected = node.id === selectedId;
9410
9780
  const isActive = node.id === activeId;
9411
9781
  const itemState = { expanded, selected, depth, hasChildren };
9412
- return /* @__PURE__ */ jsxs49(
9782
+ return /* @__PURE__ */ jsxs50(
9413
9783
  "li",
9414
9784
  {
9415
9785
  ref: (element) => {
@@ -9434,7 +9804,7 @@ function TreeView({
9434
9804
  onSelect?.(node.id, node);
9435
9805
  },
9436
9806
  children: [
9437
- /* @__PURE__ */ jsxs49(
9807
+ /* @__PURE__ */ jsxs50(
9438
9808
  "span",
9439
9809
  {
9440
9810
  "data-slot": "treeitem-row",
@@ -9443,7 +9813,7 @@ function TreeView({
9443
9813
  },
9444
9814
  className: treeItemRowVariants({ selected }),
9445
9815
  children: [
9446
- hasChildren ? /* @__PURE__ */ jsx56(
9816
+ hasChildren ? /* @__PURE__ */ jsx57(
9447
9817
  "span",
9448
9818
  {
9449
9819
  "data-slot": "treeitem-toggle",
@@ -9453,7 +9823,7 @@ function TreeView({
9453
9823
  setExpanded(node.id, !expanded);
9454
9824
  },
9455
9825
  className: "flex size-[var(--space-4)] shrink-0 items-center justify-center text-text-tertiary",
9456
- children: /* @__PURE__ */ jsx56(
9826
+ children: /* @__PURE__ */ jsx57(
9457
9827
  ChevronRight3,
9458
9828
  {
9459
9829
  "aria-hidden": "true",
@@ -9466,7 +9836,7 @@ function TreeView({
9466
9836
  }
9467
9837
  )
9468
9838
  }
9469
- ) : /* @__PURE__ */ jsx56(
9839
+ ) : /* @__PURE__ */ jsx57(
9470
9840
  "span",
9471
9841
  {
9472
9842
  "data-slot": "treeitem-spacer",
@@ -9474,18 +9844,18 @@ function TreeView({
9474
9844
  className: "size-[var(--space-4)] shrink-0"
9475
9845
  }
9476
9846
  ),
9477
- /* @__PURE__ */ jsx56("span", { className: "flex min-w-0 flex-1 items-center gap-[var(--space-2)]", children: renderItem(node, itemState) })
9847
+ /* @__PURE__ */ jsx57("span", { className: "flex min-w-0 flex-1 items-center gap-[var(--space-2)]", children: renderItem(node, itemState) })
9478
9848
  ]
9479
9849
  }
9480
9850
  ),
9481
- hasChildren && expanded && children ? /* @__PURE__ */ jsx56("ul", { role: "group", "data-slot": "tree-group", className: "m-0 list-none p-0", children: renderLevel(children, depth + 1) }) : null
9851
+ hasChildren && expanded && children ? /* @__PURE__ */ jsx57("ul", { role: "group", "data-slot": "tree-group", className: "m-0 list-none p-0", children: renderLevel(children, depth + 1) }) : null
9482
9852
  ]
9483
9853
  },
9484
9854
  node.id
9485
9855
  );
9486
9856
  });
9487
9857
  }
9488
- return /* @__PURE__ */ jsx56(
9858
+ return /* @__PURE__ */ jsx57(
9489
9859
  "ul",
9490
9860
  {
9491
9861
  role: "tree",
@@ -9501,9 +9871,12 @@ function TreeView({
9501
9871
  }
9502
9872
 
9503
9873
  // src/components/branding/olun-logo.tsx
9504
- import { jsx as jsx57, jsxs as jsxs50 } from "react/jsx-runtime";
9874
+ import { jsx as jsx58, jsxs as jsxs51 } from "react/jsx-runtime";
9875
+ var SYMBOL_LARGE = { stroke: 24, dotX: 184, dotY: 180, dotR: 13 };
9876
+ var SYMBOL_SMALL = { stroke: 18, dotX: 185, dotY: 175, dotR: 22 };
9505
9877
  function OlunSymbol({ size = 28, className }) {
9506
- return /* @__PURE__ */ jsxs50(
9878
+ const g = size > 32 ? SYMBOL_LARGE : SYMBOL_SMALL;
9879
+ return /* @__PURE__ */ jsxs51(
9507
9880
  "svg",
9508
9881
  {
9509
9882
  width: size,
@@ -9514,19 +9887,19 @@ function OlunSymbol({ size = 28, className }) {
9514
9887
  className,
9515
9888
  "aria-hidden": "true",
9516
9889
  children: [
9517
- /* @__PURE__ */ jsx57(
9890
+ /* @__PURE__ */ jsx58(
9518
9891
  "circle",
9519
9892
  {
9520
9893
  cx: "108",
9521
9894
  cy: "120",
9522
9895
  r: "60",
9523
9896
  stroke: "currentColor",
9524
- strokeWidth: "18",
9897
+ strokeWidth: g.stroke,
9525
9898
  fill: "none",
9526
9899
  style: { color: "var(--text-primary)" }
9527
9900
  }
9528
9901
  ),
9529
- /* @__PURE__ */ jsx57("circle", { cx: "185", cy: "175", r: "22", fill: "var(--accent-pop)" })
9902
+ /* @__PURE__ */ jsx58("circle", { cx: g.dotX, cy: g.dotY, r: g.dotR, fill: "var(--accent-pop)" })
9530
9903
  ]
9531
9904
  }
9532
9905
  );
@@ -9537,7 +9910,7 @@ function OlunLogo({
9537
9910
  showSymbol = true,
9538
9911
  className
9539
9912
  }) {
9540
- return /* @__PURE__ */ jsxs50(
9913
+ return /* @__PURE__ */ jsxs51(
9541
9914
  "div",
9542
9915
  {
9543
9916
  className,
@@ -9547,8 +9920,8 @@ function OlunLogo({
9547
9920
  gap: "var(--space-3)"
9548
9921
  },
9549
9922
  children: [
9550
- showSymbol && /* @__PURE__ */ jsx57(OlunSymbol, { size: symbolSize }),
9551
- /* @__PURE__ */ jsxs50(
9923
+ showSymbol && /* @__PURE__ */ jsx58(OlunSymbol, { size: symbolSize }),
9924
+ /* @__PURE__ */ jsxs51(
9552
9925
  "span",
9553
9926
  {
9554
9927
  style: {
@@ -9560,7 +9933,7 @@ function OlunLogo({
9560
9933
  },
9561
9934
  children: [
9562
9935
  "OLUN",
9563
- /* @__PURE__ */ jsx57("span", { style: { color: "var(--accent)" }, children: "." })
9936
+ !showSymbol && /* @__PURE__ */ jsx58("span", { style: { color: "var(--accent)" }, children: "." })
9564
9937
  ]
9565
9938
  }
9566
9939
  )
@@ -9571,30 +9944,30 @@ function OlunLogo({
9571
9944
 
9572
9945
  // src/components/branding/theme-toggle.tsx
9573
9946
  import { Sun, Moon } from "lucide-react";
9574
- import { jsx as jsx58 } from "react/jsx-runtime";
9947
+ import { jsx as jsx59 } from "react/jsx-runtime";
9575
9948
  function ThemeToggle({ className }) {
9576
9949
  const { resolvedTheme, toggleTheme } = useOlunTheme();
9577
9950
  const Icon = resolvedTheme === "dark" ? Moon : Sun;
9578
- return /* @__PURE__ */ jsx58(
9951
+ return /* @__PURE__ */ jsx59(
9579
9952
  "button",
9580
9953
  {
9581
9954
  onClick: () => toggleTheme(),
9582
9955
  className: cn(
9583
- "inline-flex size-[36px] items-center justify-center rounded-sm",
9956
+ "inline-flex size-[36px] items-center justify-center rounded-[var(--radius-md)]",
9584
9957
  "text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
9585
9958
  "transition-colors motion-reduce:transition-none",
9586
9959
  className
9587
9960
  ),
9588
9961
  "aria-label": "\uD14C\uB9C8 \uC804\uD658",
9589
9962
  title: resolvedTheme === "dark" ? "\uB77C\uC774\uD2B8 \uBAA8\uB4DC\uB85C" : "\uB2E4\uD06C \uBAA8\uB4DC\uB85C",
9590
- children: /* @__PURE__ */ jsx58(Icon, { className: "size-[18px]", strokeWidth: 1.75 })
9963
+ children: /* @__PURE__ */ jsx59(Icon, { className: "size-[18px]", strokeWidth: 1.75 })
9591
9964
  }
9592
9965
  );
9593
9966
  }
9594
9967
 
9595
9968
  // src/components/branding/theme-fab.tsx
9596
9969
  import { Sun as Sun2, Moon as Moon2 } from "lucide-react";
9597
- import { jsx as jsx59 } from "react/jsx-runtime";
9970
+ import { jsx as jsx60 } from "react/jsx-runtime";
9598
9971
  function ThemeFab({ variant = "square" } = {}) {
9599
9972
  const { mounted, resolvedTheme, toggleTheme } = useOlunTheme();
9600
9973
  if (!mounted) {
@@ -9614,7 +9987,7 @@ function ThemeFab({ variant = "square" } = {}) {
9614
9987
  right: "12px",
9615
9988
  width: "36px",
9616
9989
  height: "36px",
9617
- borderRadius: "var(--radius-sm)",
9990
+ borderRadius: "var(--radius-md)",
9618
9991
  border: "1px solid var(--border-subtle)",
9619
9992
  background: "var(--bg-surface)",
9620
9993
  color: "var(--text-secondary)",
@@ -9634,7 +10007,7 @@ function ThemeFab({ variant = "square" } = {}) {
9634
10007
  WebkitBackdropFilter: "blur(16px)",
9635
10008
  zIndex: 9999
9636
10009
  };
9637
- return /* @__PURE__ */ jsx59(
10010
+ return /* @__PURE__ */ jsx60(
9638
10011
  "button",
9639
10012
  {
9640
10013
  onClick: () => toggleTheme(),
@@ -9659,7 +10032,7 @@ function ThemeFab({ variant = "square" } = {}) {
9659
10032
  e.currentTarget.style.color = "var(--text-secondary)";
9660
10033
  }
9661
10034
  },
9662
- children: /* @__PURE__ */ jsx59(
10035
+ children: /* @__PURE__ */ jsx60(
9663
10036
  Icon,
9664
10037
  {
9665
10038
  size: isCircle ? 22 : 16,
@@ -9671,7 +10044,7 @@ function ThemeFab({ variant = "square" } = {}) {
9671
10044
  }
9672
10045
 
9673
10046
  // src/components/logos/organization-logo.tsx
9674
- import { jsx as jsx60 } from "react/jsx-runtime";
10047
+ import { jsx as jsx61 } from "react/jsx-runtime";
9675
10048
  var organizationLogoRegistry = {
9676
10049
  jbnu: {
9677
10050
  label: "\uC804\uBD81\uB300\uD559\uAD50 \uC5E0\uBE14\uB7FC",
@@ -9700,7 +10073,7 @@ function OrganizationLogo({
9700
10073
  }) {
9701
10074
  const asset = organizationLogoRegistry[organization];
9702
10075
  const isDecorative = ariaHidden === true || ariaHidden === "true";
9703
- return /* @__PURE__ */ jsx60(
10076
+ return /* @__PURE__ */ jsx61(
9704
10077
  "svg",
9705
10078
  {
9706
10079
  viewBox: asset.viewBox,
@@ -9718,12 +10091,13 @@ function OrganizationLogo({
9718
10091
  ...style
9719
10092
  },
9720
10093
  ...props,
9721
- children: asset.paths.map((path) => /* @__PURE__ */ jsx60("path", { d: path }, path))
10094
+ children: asset.paths.map((path) => /* @__PURE__ */ jsx61("path", { d: path }, path))
9722
10095
  }
9723
10096
  );
9724
10097
  }
9725
10098
  export {
9726
10099
  ActionFooter,
10100
+ ActionSheet,
9727
10101
  Alert,
9728
10102
  Avatar,
9729
10103
  AvatarFallback,