@olundot/ui 0.20.0-next.5 → 0.20.0-next.6

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
@@ -187,19 +187,38 @@ import { cva } from "class-variance-authority";
187
187
  import { ChevronDown, Loader2 } from "lucide-react";
188
188
  import { Slot } from "radix-ui";
189
189
 
190
+ // src/components/ui/surface.ts
191
+ var insetMarkerContext = "[--fill-on-bg:var(--fill-on-inset)]";
192
+ var surfaceMarkerContext = "[--fill-on-bg:initial]";
193
+ var surfaceClassNames = {
194
+ surface: `bg-[var(--bg-surface)] ${surfaceMarkerContext}`,
195
+ canvas: `bg-[var(--bg-canvas)] ${surfaceMarkerContext}`,
196
+ raised: `bg-[var(--bg-raised)] ${surfaceMarkerContext}`
197
+ };
198
+ var fieldSurfaceClassNames = {
199
+ surface: "bg-[var(--bg-surface)]",
200
+ canvas: "bg-[var(--bg-canvas)]",
201
+ raised: "bg-[var(--bg-raised)]"
202
+ };
203
+ var selectSurfaceClassNames = {
204
+ surface: "bg-[var(--bg-surface)] [background-color:var(--bg-surface)]",
205
+ canvas: "bg-[var(--bg-canvas)] [background-color:var(--bg-canvas)]",
206
+ raised: "bg-[var(--bg-raised)] [background-color:var(--bg-raised)]"
207
+ };
208
+
190
209
  // src/components/ui/action-variants.ts
191
210
  var actionPaint = {
192
211
  // = Button `primary`
193
212
  filledPrimary: "border-[var(--primary)] bg-[var(--primary)] text-[var(--primary-fg)] hover:bg-[var(--primary-hover)] hover:border-[var(--primary-hover)]",
194
213
  // = 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",
214
+ filledNeutral: `border-transparent bg-[var(--bg-inset)] text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground ${insetMarkerContext}`,
196
215
  // = Button `danger`
197
216
  filledDanger: "border-[var(--error)] bg-[var(--error)] text-[var(--error-contrast)] hover:bg-[var(--error-hover)] hover:border-[var(--error-hover)]",
198
217
  // = Button `secondary`
199
- outlineNeutral: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-foreground hover:border-[var(--border)] hover:bg-[var(--action-hover)]",
218
+ outlineNeutral: `border-[var(--border-subtle)] bg-[var(--bg-surface)] text-foreground hover:border-[var(--border)] hover:bg-[var(--action-hover)] ${surfaceMarkerContext}`,
200
219
  // Destructive action that is not the main one: outline neutral's surface, error border and
201
220
  // label, error wash on hover.
202
- outlineDanger: "border-[var(--error)] bg-[var(--bg-surface)] text-[var(--error)] hover:bg-[var(--error-bg)]",
221
+ outlineDanger: `border-[var(--error)] bg-[var(--bg-surface)] text-[var(--error)] hover:bg-[var(--error-bg)] ${surfaceMarkerContext}`,
203
222
  // = Button and IconButton `ghost`
204
223
  ghostNeutral: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
205
224
  // Button `appearance="link"` only: the label color; the box and underline live in button.tsx.
@@ -440,25 +459,6 @@ CopyButton.displayName = "CopyButton";
440
459
  import * as React3 from "react";
441
460
  import { cva as cva2 } from "class-variance-authority";
442
461
  import { AlertCircle, CheckCircle2 } from "lucide-react";
443
-
444
- // src/components/ui/surface.ts
445
- var surfaceClassNames = {
446
- surface: "bg-[var(--bg-surface)]",
447
- canvas: "bg-[var(--bg-canvas)]",
448
- raised: "bg-[var(--bg-raised)]"
449
- };
450
- var fieldSurfaceClassNames = {
451
- surface: "bg-[var(--bg-surface)]",
452
- canvas: "bg-[var(--bg-canvas)]",
453
- raised: "bg-[var(--bg-raised)]"
454
- };
455
- var selectSurfaceClassNames = {
456
- surface: "bg-[var(--bg-surface)] [background-color:var(--bg-surface)]",
457
- canvas: "bg-[var(--bg-canvas)] [background-color:var(--bg-canvas)]",
458
- raised: "bg-[var(--bg-raised)] [background-color:var(--bg-raised)]"
459
- };
460
-
461
- // src/components/ui/input.tsx
462
462
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
463
463
  var inputVariants = cva2(
464
464
  [
@@ -657,6 +657,8 @@ var fileUploadZoneVariants = cva3(
657
657
  "hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)]",
658
658
  "focus-within:border-[var(--focus-ring)] focus-within:shadow-[0_0_0_1px_var(--focus-ring)]",
659
659
  "data-[has-file=true]:border-solid data-[has-file=true]:border-[var(--border-strong)] data-[has-file=true]:bg-[var(--bg-inset)]",
660
+ // the filled zone is an inset well for neutral markers inside it (insetMarkerContext, surface.ts)
661
+ "data-[has-file=true]:[--fill-on-bg:var(--fill-on-inset)]",
660
662
  "data-[dragging=true]:border-[var(--border-strong)] data-[dragging=true]:bg-[var(--action-active)]",
661
663
  "data-[error=true]:border-[var(--error)]",
662
664
  "data-[disabled=true]:cursor-not-allowed data-[disabled=true]:border-[var(--border-subtle)] data-[disabled=true]:bg-[var(--action-disabled-bg)]",
@@ -1915,9 +1917,26 @@ Label.displayName = "Label";
1915
1917
 
1916
1918
  // src/components/ui/switch.tsx
1917
1919
  import * as React9 from "react";
1920
+ import { cva as cva7 } from "class-variance-authority";
1918
1921
  import { Loader2 as Loader22 } from "lucide-react";
1919
1922
  import { Switch as SwitchPrimitive } from "radix-ui";
1920
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1923
+ import { Fragment, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1924
+ var switchFieldVariants = cva7("", {
1925
+ variants: {
1926
+ labelPlacement: {
1927
+ end: "flex flex-col gap-[var(--space-1)]",
1928
+ start: "flex items-start gap-[var(--space-3)]"
1929
+ },
1930
+ fullWidth: {
1931
+ true: "w-full",
1932
+ false: "w-fit"
1933
+ }
1934
+ },
1935
+ defaultVariants: {
1936
+ labelPlacement: "end",
1937
+ fullWidth: false
1938
+ }
1939
+ });
1921
1940
  var Switch = React9.forwardRef(
1922
1941
  ({
1923
1942
  className,
@@ -1925,6 +1944,8 @@ var Switch = React9.forwardRef(
1925
1944
  description,
1926
1945
  required,
1927
1946
  loading,
1947
+ labelPlacement = "end",
1948
+ fullWidth = false,
1928
1949
  disabled,
1929
1950
  id,
1930
1951
  ...props
@@ -1934,95 +1955,108 @@ var Switch = React9.forwardRef(
1934
1955
  const labelId = id ? `${id}-label` : `${generatedId}-label`;
1935
1956
  const descriptionId = description ? id ? `${id}-description` : `${generatedId}-description` : void 0;
1936
1957
  const isDisabled = disabled || loading;
1937
- return /* @__PURE__ */ jsxs10(
1938
- "div",
1958
+ const isStart = labelPlacement === "start";
1959
+ const track = /* @__PURE__ */ jsxs10(
1960
+ SwitchPrimitive.Root,
1939
1961
  {
1940
- "data-slot": "switch-field",
1941
- "data-disabled": isDisabled ? "" : void 0,
1942
- className: "flex flex-col gap-[var(--space-1)] w-fit",
1962
+ ref,
1963
+ id: switchId,
1964
+ "data-slot": "switch",
1965
+ disabled: isDisabled,
1966
+ "aria-required": required || void 0,
1967
+ "aria-busy": loading || void 0,
1968
+ "aria-describedby": descriptionId,
1969
+ className: cn(
1970
+ "group relative inline-flex h-[24px] w-[44px] cursor-pointer items-center rounded-full transition-colors",
1971
+ "bg-[var(--border)] data-[state=checked]:bg-[var(--primary)]",
1972
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]",
1973
+ "disabled:cursor-not-allowed disabled:opacity-50",
1974
+ isStart && "shrink-0",
1975
+ className
1976
+ ),
1977
+ ...props,
1943
1978
  children: [
1944
- /* @__PURE__ */ jsxs10("div", { className: "inline-flex items-center gap-[var(--space-3)]", children: [
1945
- /* @__PURE__ */ jsxs10(
1946
- SwitchPrimitive.Root,
1947
- {
1948
- ref,
1949
- id: switchId,
1950
- "data-slot": "switch",
1951
- disabled: isDisabled,
1952
- "aria-required": required || void 0,
1953
- "aria-busy": loading || void 0,
1954
- "aria-describedby": descriptionId,
1955
- className: cn(
1956
- "group relative inline-flex h-[24px] w-[44px] cursor-pointer items-center rounded-full transition-colors",
1957
- "bg-[var(--border)] data-[state=checked]:bg-[var(--primary)]",
1958
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]",
1959
- "disabled:cursor-not-allowed disabled:opacity-50",
1960
- className
1961
- ),
1962
- ...props,
1963
- children: [
1964
- /* @__PURE__ */ jsx10(
1965
- SwitchPrimitive.Thumb,
1966
- {
1967
- "data-slot": "switch-thumb",
1968
- className: cn(
1969
- "pointer-events-none block h-[20px] w-[20px] rounded-full bg-[var(--bg-surface)] shadow",
1970
- "transition-transform translate-x-[2px] data-[state=checked]:translate-x-[22px]"
1971
- )
1972
- }
1973
- ),
1974
- loading ? /* @__PURE__ */ jsx10(
1975
- "span",
1976
- {
1977
- "aria-hidden": "true",
1978
- "data-slot": "switch-loading",
1979
- className: "absolute inset-0 flex items-center justify-center",
1980
- children: /* @__PURE__ */ jsx10(Loader22, { className: "size-[14px] animate-spin text-text-secondary" })
1981
- }
1982
- ) : null
1983
- ]
1984
- }
1985
- ),
1986
- /* @__PURE__ */ jsxs10(
1987
- "label",
1988
- {
1989
- htmlFor: switchId,
1990
- id: labelId,
1991
- "data-slot": "switch-label",
1992
- className: cn(
1993
- "cursor-pointer select-none text-sm font-medium text-foreground",
1994
- isDisabled && "cursor-not-allowed text-text-disabled"
1995
- ),
1996
- children: [
1997
- label,
1998
- required ? /* @__PURE__ */ jsx10(
1999
- "span",
2000
- {
2001
- "aria-hidden": "true",
2002
- "data-slot": "switch-required-marker",
2003
- className: "ml-[var(--space-1)] font-bold text-[var(--semantic-error,var(--error))]",
2004
- children: "*"
2005
- }
2006
- ) : null
2007
- ]
2008
- }
2009
- )
2010
- ] }),
2011
- description ? /* @__PURE__ */ jsx10(
2012
- "p",
1979
+ /* @__PURE__ */ jsx10(
1980
+ SwitchPrimitive.Thumb,
2013
1981
  {
2014
- id: descriptionId,
2015
- "data-slot": "switch-description",
1982
+ "data-slot": "switch-thumb",
2016
1983
  className: cn(
2017
- "ml-[var(--space-3)] text-xs font-normal leading-normal text-text-tertiary",
2018
- isDisabled && "text-text-disabled"
2019
- ),
2020
- children: description
1984
+ "pointer-events-none block h-[20px] w-[20px] rounded-full bg-[var(--bg-surface)] shadow",
1985
+ "transition-transform translate-x-[2px] data-[state=checked]:translate-x-[22px]"
1986
+ )
1987
+ }
1988
+ ),
1989
+ loading ? /* @__PURE__ */ jsx10(
1990
+ "span",
1991
+ {
1992
+ "aria-hidden": "true",
1993
+ "data-slot": "switch-loading",
1994
+ className: "absolute inset-0 flex items-center justify-center",
1995
+ children: /* @__PURE__ */ jsx10(Loader22, { className: "size-[14px] animate-spin text-text-secondary" })
2021
1996
  }
2022
1997
  ) : null
2023
1998
  ]
2024
1999
  }
2025
2000
  );
2001
+ const labelNode = /* @__PURE__ */ jsxs10(
2002
+ "label",
2003
+ {
2004
+ htmlFor: switchId,
2005
+ id: labelId,
2006
+ "data-slot": "switch-label",
2007
+ className: cn(
2008
+ "cursor-pointer select-none break-keep text-sm font-medium text-foreground [overflow-wrap:anywhere]",
2009
+ isStart && "leading-6",
2010
+ isDisabled && "cursor-not-allowed text-text-disabled"
2011
+ ),
2012
+ children: [
2013
+ label,
2014
+ required ? /* @__PURE__ */ jsx10(
2015
+ "span",
2016
+ {
2017
+ "aria-hidden": "true",
2018
+ "data-slot": "switch-required-marker",
2019
+ className: "ml-[var(--space-1)] font-bold text-[var(--semantic-error,var(--error))]",
2020
+ children: "*"
2021
+ }
2022
+ ) : null
2023
+ ]
2024
+ }
2025
+ );
2026
+ const descriptionNode = description ? /* @__PURE__ */ jsx10(
2027
+ "p",
2028
+ {
2029
+ id: descriptionId,
2030
+ "data-slot": "switch-description",
2031
+ className: cn(
2032
+ "break-keep text-xs font-normal leading-normal text-text-tertiary [overflow-wrap:anywhere]",
2033
+ !isStart && "ml-[var(--space-3)]",
2034
+ isDisabled && "text-text-disabled"
2035
+ ),
2036
+ children: description
2037
+ }
2038
+ ) : null;
2039
+ return /* @__PURE__ */ jsx10(
2040
+ "div",
2041
+ {
2042
+ "data-slot": "switch-field",
2043
+ "data-disabled": isDisabled ? "" : void 0,
2044
+ className: switchFieldVariants({ labelPlacement, fullWidth }),
2045
+ children: isStart ? /* @__PURE__ */ jsxs10(Fragment, { children: [
2046
+ /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 grow flex-col gap-[var(--space-1)]", children: [
2047
+ labelNode,
2048
+ descriptionNode
2049
+ ] }),
2050
+ track
2051
+ ] }) : /* @__PURE__ */ jsxs10(Fragment, { children: [
2052
+ /* @__PURE__ */ jsxs10("div", { className: "inline-flex items-center gap-[var(--space-3)]", children: [
2053
+ track,
2054
+ labelNode
2055
+ ] }),
2056
+ descriptionNode
2057
+ ] })
2058
+ }
2059
+ );
2026
2060
  }
2027
2061
  );
2028
2062
  Switch.displayName = "Switch";
@@ -2126,7 +2160,7 @@ function TooltipContent({
2126
2160
  }
2127
2161
 
2128
2162
  // src/components/ui/permission-guard.tsx
2129
- import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2163
+ import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2130
2164
  var defaultDisabledReason = "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4";
2131
2165
  var PermissionContext = React11.createContext(
2132
2166
  void 0
@@ -2173,7 +2207,7 @@ function PermissionGuard({
2173
2207
  const state = React11.useContext(PermissionContext);
2174
2208
  const allowed = evaluatePermission(permission, permissions ?? state, scope);
2175
2209
  if (allowed) {
2176
- return /* @__PURE__ */ jsx12(Fragment2, { children });
2210
+ return /* @__PURE__ */ jsx12(Fragment3, { children });
2177
2211
  }
2178
2212
  if (fallback === "hide" || fallback == null) {
2179
2213
  return null;
@@ -2181,7 +2215,7 @@ function PermissionGuard({
2181
2215
  if (fallback === "disabled") {
2182
2216
  return renderDisabledFallback(children, disabledReason);
2183
2217
  }
2184
- return /* @__PURE__ */ jsx12(Fragment2, { children: fallback });
2218
+ return /* @__PURE__ */ jsx12(Fragment3, { children: fallback });
2185
2219
  }
2186
2220
  function getPermissionCandidates(permission, scope) {
2187
2221
  const candidates = /* @__PURE__ */ new Set([permission]);
@@ -2234,9 +2268,9 @@ function isPermissionState(value) {
2234
2268
 
2235
2269
  // src/components/ui/card.tsx
2236
2270
  import * as React12 from "react";
2237
- import { cva as cva7 } from "class-variance-authority";
2271
+ import { cva as cva8 } from "class-variance-authority";
2238
2272
  import { jsx as jsx13 } from "react/jsx-runtime";
2239
- var cardBaseVariants = cva7(
2273
+ var cardBaseVariants = cva8(
2240
2274
  [
2241
2275
  "rounded-[var(--radius-lg)] border border-[var(--border)]",
2242
2276
  "px-[var(--space-6)] py-[var(--space-4)] text-foreground"
@@ -2621,7 +2655,7 @@ DataLayout.displayName = "DataLayout";
2621
2655
  // src/components/ui/wizard-layout.tsx
2622
2656
  import * as React16 from "react";
2623
2657
  import { Check as Check2 } from "lucide-react";
2624
- import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
2658
+ import { Fragment as Fragment6, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
2625
2659
  var circleBaseClassName = [
2626
2660
  "flex items-center justify-center rounded-[var(--radius-full)] border text-[12px] font-semibold leading-none",
2627
2661
  "transition-[background-color,border-color,color] motion-reduce:transition-none"
@@ -2912,7 +2946,7 @@ var WizardLayout = React16.forwardRef(
2912
2946
  ) : null
2913
2947
  ]
2914
2948
  }
2915
- ) : /* @__PURE__ */ jsxs16(Fragment5, { children: [
2949
+ ) : /* @__PURE__ */ jsxs16(Fragment6, { children: [
2916
2950
  /* @__PURE__ */ jsx17(
2917
2951
  "span",
2918
2952
  {
@@ -2979,10 +3013,10 @@ import * as React18 from "react";
2979
3013
  // src/components/ui/tabs.tsx
2980
3014
  import * as React17 from "react";
2981
3015
  import { Tabs as TabsPrimitive } from "radix-ui";
2982
- import { cva as cva8 } from "class-variance-authority";
3016
+ import { cva as cva9 } from "class-variance-authority";
2983
3017
  import { Lock } from "lucide-react";
2984
- import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2985
- var tabsRootVariants = cva8("w-full", {
3018
+ import { Fragment as Fragment7, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
3019
+ var tabsRootVariants = cva9("w-full", {
2986
3020
  variants: {
2987
3021
  orientation: {
2988
3022
  horizontal: "",
@@ -2993,13 +3027,14 @@ var tabsRootVariants = cva8("w-full", {
2993
3027
  orientation: "horizontal"
2994
3028
  }
2995
3029
  });
2996
- var tabsListVariants = cva8(
2997
- "flex",
3030
+ var tabsListVariants = cva9(
3031
+ // A list that overflows scrolls sideways without showing a scrollbar.
3032
+ "flex [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden",
2998
3033
  {
2999
3034
  variants: {
3000
3035
  variant: {
3001
3036
  line: "",
3002
- contained: "rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-inset)] p-[var(--space-1)]"
3037
+ contained: `rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-inset)] p-[var(--space-1)] ${insetMarkerContext}`
3003
3038
  },
3004
3039
  orientation: {
3005
3040
  horizontal: "",
@@ -3034,7 +3069,7 @@ var tabsListVariants = cva8(
3034
3069
  }
3035
3070
  }
3036
3071
  );
3037
- var tabsTriggerVariants = cva8(
3072
+ var tabsTriggerVariants = cva9(
3038
3073
  [
3039
3074
  "relative inline-flex shrink-0 cursor-pointer items-center gap-[var(--space-2)]",
3040
3075
  "px-0 py-[var(--space-2)] text-body-sm font-medium",
@@ -3088,7 +3123,7 @@ var tabsTriggerVariants = cva8(
3088
3123
  }
3089
3124
  }
3090
3125
  );
3091
- var tabsIndicatorVariants = cva8(
3126
+ var tabsIndicatorVariants = cva9(
3092
3127
  [
3093
3128
  "pointer-events-none absolute invisible bg-[var(--text-primary)]",
3094
3129
  // transition-property stays none (duration alone would animate every property, visibility included)
@@ -3117,18 +3152,11 @@ var tabsLabelReserveClassName = [
3117
3152
  "before:invisible before:h-0 before:overflow-hidden before:font-medium before:content-[attr(data-label)]",
3118
3153
  "after:invisible after:h-0 after:overflow-hidden after:font-bold after:content-[attr(data-label)]"
3119
3154
  ].join(" ");
3120
- var tabsBadgeVariants = cva8(
3155
+ var tabsBadgeVariants = cva9(
3121
3156
  [
3122
- "inline-flex h-[18px] min-w-[18px] items-center justify-center",
3123
- "rounded-[var(--radius-full)] border border-[var(--border-subtle)]",
3124
- "bg-[var(--bg-inset)] px-[var(--space-1)]",
3125
- "font-[family-name:var(--font-display)] text-xs font-semibold leading-none tabular-nums",
3126
- // R14 — Badge는 metadata, 추가 marker(filled wash)가 아니다. marker 종류는
3127
- // trigger underline 하나(active-state doctrine). single-hue-family: active 시 인접
3128
- // visible token(underline + badge text + badge border)을 같은 hue family로 — text는
3129
- // inherit, border는 active만 중립 --border-strong로 lift(accent rationing — selection은 brand 미사용). filled wash는 여전히 금지.
3130
- "text-inherit",
3131
- "group-data-[state=active]:border-[var(--border-strong)]"
3157
+ "inline-flex h-[var(--space-4)] min-w-[var(--space-4)] items-center justify-center",
3158
+ "rounded-[var(--radius-full)] px-[var(--space-1)] bg-[var(--action-selected)]",
3159
+ "font-[family-name:var(--font-display)] text-xs font-medium tabular-nums text-inherit"
3132
3160
  ].join(" ")
3133
3161
  );
3134
3162
  function useTabsIndicator(enabled, activeKey, tabsKey, listRef, indicatorRef) {
@@ -3188,7 +3216,15 @@ function useTabsIndicator(enabled, activeKey, tabsKey, listRef, indicatorRef) {
3188
3216
  }, [enabled, tabsKey, place, listRef]);
3189
3217
  }
3190
3218
  function formatTabBadge(value) {
3191
- return value > 99 ? "99+" : String(value);
3219
+ return value > 999 ? "999+" : String(value);
3220
+ }
3221
+ function isShownTabBadge(value) {
3222
+ if (value === void 0) return false;
3223
+ if (Number.isFinite(value) && value >= 0) return true;
3224
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
3225
+ console.warn(`Tabs: badge must be a number 0 or greater (got ${value}). The badge is not shown.`);
3226
+ }
3227
+ return false;
3192
3228
  }
3193
3229
  function getTabId(baseId, key) {
3194
3230
  return baseId ? `${baseId}-tab-${key}` : `tab-${key}`;
@@ -3246,7 +3282,10 @@ var Tabs = React17.forwardRef(
3246
3282
  className: cn("group", tabsTriggerVariants({ variant, orientation }), triggerClassName),
3247
3283
  children: [
3248
3284
  isLine ? /* @__PURE__ */ jsx18("span", { "data-label": tab.label, className: tabsLabelReserveClassName, children: tab.label }) : /* @__PURE__ */ jsx18("span", { children: tab.label }),
3249
- tab.badge !== void 0 && tab.badge > 0 ? /* @__PURE__ */ jsx18("span", { "aria-hidden": "true", "data-slot": "tabs-badge", className: tabsBadgeVariants(), children: formatTabBadge(tab.badge) }) : null,
3285
+ isShownTabBadge(tab.badge) ? /* @__PURE__ */ jsxs17(Fragment7, { children: [
3286
+ /* @__PURE__ */ jsx18("span", { "aria-hidden": "true", "data-slot": "tabs-badge", className: tabsBadgeVariants(), children: formatTabBadge(tab.badge) }),
3287
+ /* @__PURE__ */ jsx18("span", { className: "sr-only", children: ` ${tab.badge}` })
3288
+ ] }) : null,
3250
3289
  tab.disabled ? /* @__PURE__ */ jsx18(
3251
3290
  Lock,
3252
3291
  {
@@ -3302,7 +3341,7 @@ var TabsContent = React17.forwardRef(({ className, tabKey, baseId, ...props }, r
3302
3341
  TabsContent.displayName = TabsPrimitive.Content.displayName;
3303
3342
 
3304
3343
  // src/components/ui/detail-layout.tsx
3305
- import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
3344
+ import { Fragment as Fragment8, jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
3306
3345
  function DetailLayoutBody({
3307
3346
  children,
3308
3347
  aside,
@@ -3355,7 +3394,7 @@ function appendFooterToActiveTabsContent(children, activeTab, footer) {
3355
3394
  return React18.cloneElement(
3356
3395
  child,
3357
3396
  void 0,
3358
- /* @__PURE__ */ jsxs18(Fragment6, { children: [
3397
+ /* @__PURE__ */ jsxs18(Fragment8, { children: [
3359
3398
  child.props.children,
3360
3399
  /* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-footer", className: "min-w-0", children: footer })
3361
3400
  ] })
@@ -3437,7 +3476,7 @@ var DetailLayout = React18.forwardRef(
3437
3476
  baseId,
3438
3477
  forceMount: true,
3439
3478
  hidden: tab.key !== activeTab,
3440
- children: tab.key === activeTab ? /* @__PURE__ */ jsxs18(Fragment6, { children: [
3479
+ children: tab.key === activeTab ? /* @__PURE__ */ jsxs18(Fragment8, { children: [
3441
3480
  body,
3442
3481
  footer ? /* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-footer", className: "min-w-0", children: footer }) : null
3443
3482
  ] }) : null
@@ -3445,7 +3484,7 @@ var DetailLayout = React18.forwardRef(
3445
3484
  tab.key
3446
3485
  ))
3447
3486
  }
3448
- ) : /* @__PURE__ */ jsxs18(Fragment6, { children: [
3487
+ ) : /* @__PURE__ */ jsxs18(Fragment8, { children: [
3449
3488
  body,
3450
3489
  footer ? /* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-footer", className: "min-w-0", children: footer }) : null
3451
3490
  ] })
@@ -3874,11 +3913,11 @@ import { Dialog as DialogPrimitive } from "radix-ui";
3874
3913
 
3875
3914
  // src/components/ui/icon-button.tsx
3876
3915
  import * as React23 from "react";
3877
- import { cva as cva9 } from "class-variance-authority";
3916
+ import { cva as cva10 } from "class-variance-authority";
3878
3917
  import { ChevronDown as ChevronDown4, Loader2 as Loader23 } from "lucide-react";
3879
3918
  import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
3880
3919
  var pressedNeutralClassName = "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground";
3881
- var iconButtonCva = cva9(
3920
+ var iconButtonCva = cva10(
3882
3921
  [
3883
3922
  "olun-icon-button relative inline-flex cursor-pointer shrink-0 items-center justify-center before:absolute before:content-['']",
3884
3923
  "rounded-[var(--radius-md)] border font-medium",
@@ -3932,7 +3971,7 @@ function iconButtonVariants(options) {
3932
3971
  ...resolveActionStyle(options?.appearance, options?.tone, "ghost")
3933
3972
  });
3934
3973
  }
3935
- var iconButtonBadgeVariants = cva9(
3974
+ var iconButtonBadgeVariants = cva10(
3936
3975
  [
3937
3976
  "pointer-events-none absolute right-0 top-0 inline-flex",
3938
3977
  "olun-icon-button__badge",
@@ -4646,7 +4685,7 @@ function SheetDescription({
4646
4685
  }
4647
4686
 
4648
4687
  // src/components/ui/dialog.tsx
4649
- import { Fragment as Fragment7, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
4688
+ import { Fragment as Fragment9, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
4650
4689
  function dialogMobileSheetStyle(style) {
4651
4690
  return getDefaultSheetMotionStyle(style);
4652
4691
  }
@@ -4740,7 +4779,7 @@ function StructuredDialog({
4740
4779
  footerRow
4741
4780
  ]
4742
4781
  }
4743
- ) : /* @__PURE__ */ jsxs23(Fragment7, { children: [
4782
+ ) : /* @__PURE__ */ jsxs23(Fragment9, { children: [
4744
4783
  body,
4745
4784
  footerRow
4746
4785
  ] })
@@ -4941,7 +4980,7 @@ function FormModal({
4941
4980
 
4942
4981
  // src/components/ui/alert-dialog.tsx
4943
4982
  import { AlertDialog as AlertDialogPrimitive2 } from "radix-ui";
4944
- import { Fragment as Fragment8, jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
4983
+ import { Fragment as Fragment10, jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
4945
4984
  function AlertDialogFrame({
4946
4985
  open,
4947
4986
  onOpenChange,
@@ -5005,7 +5044,7 @@ function AlertDialog({
5005
5044
  disabled: confirmDisabled,
5006
5045
  onError
5007
5046
  });
5008
- const footer = confirmLabel != null ? /* @__PURE__ */ jsxs25(Fragment8, { children: [
5047
+ const footer = confirmLabel != null ? /* @__PURE__ */ jsxs25(Fragment10, { children: [
5009
5048
  /* @__PURE__ */ jsx28(AlertDialogPrimitive2.Cancel, { asChild: true, children: /* @__PURE__ */ jsx28(Button, { appearance: "outline", tone: "neutral", size: "lg", className: footerButtonHitAreaClassName, disabled: isBusy, children: cancelLabel }) }),
5010
5049
  /* @__PURE__ */ jsx28(
5011
5050
  Button,
@@ -5080,11 +5119,11 @@ import { SlidersHorizontal } from "lucide-react";
5080
5119
 
5081
5120
  // src/components/ui/chip.tsx
5082
5121
  import * as React27 from "react";
5083
- import { cva as cva10 } from "class-variance-authority";
5122
+ import { cva as cva11 } from "class-variance-authority";
5084
5123
  import { X as X2 } from "lucide-react";
5085
5124
  import { Slot as Slot2 } from "radix-ui";
5086
5125
  import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
5087
- var chipVariants = cva10(
5126
+ var chipVariants = cva11(
5088
5127
  [
5089
5128
  "inline-flex w-fit shrink-0 items-center justify-center whitespace-nowrap",
5090
5129
  "rounded-[var(--radius-full)] border leading-none",
@@ -5105,7 +5144,7 @@ var chipVariants = cva10(
5105
5144
  "status-filter": "cursor-default"
5106
5145
  },
5107
5146
  tone: {
5108
- neutral: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-text-secondary hover:bg-[var(--action-hover)]",
5147
+ neutral: `border-[var(--border-subtle)] bg-[var(--bg-surface)] text-text-secondary hover:bg-[var(--action-hover)] ${surfaceMarkerContext}`,
5109
5148
  accent: "border-[var(--border-accent)] bg-transparent text-[var(--accent)] hover:bg-[var(--accent-bg-strong)]",
5110
5149
  success: "border-transparent bg-[var(--success-bg)] text-[var(--success)] hover:bg-[var(--action-hover)]",
5111
5150
  warning: "border-transparent bg-[var(--warning-bg)] text-[var(--warning)] hover:bg-[var(--action-hover)]",
@@ -5137,7 +5176,7 @@ var chipVariants = cva10(
5137
5176
  {
5138
5177
  pressed: true,
5139
5178
  tone: "muted",
5140
- className: "border-[var(--border-strong)] bg-[var(--bg-inset)] text-text-secondary"
5179
+ className: `border-[var(--border-strong)] bg-[var(--bg-inset)] text-text-secondary ${insetMarkerContext}`
5141
5180
  }
5142
5181
  ],
5143
5182
  defaultVariants: {
@@ -5148,7 +5187,7 @@ var chipVariants = cva10(
5148
5187
  }
5149
5188
  }
5150
5189
  );
5151
- var chipCountVariants = cva10(
5190
+ var chipCountVariants = cva11(
5152
5191
  [
5153
5192
  "inline-flex min-w-[var(--space-4)] items-center justify-center",
5154
5193
  "rounded-[var(--radius-full)] px-[var(--space-1)]",
@@ -5157,12 +5196,13 @@ var chipCountVariants = cva10(
5157
5196
  {
5158
5197
  variants: {
5159
5198
  tone: {
5160
- neutral: "bg-[var(--bg-inset)] text-text-tertiary",
5199
+ // neutral·muted take --fill-on-bg when an inset background sets it (see surface.ts).
5200
+ neutral: "bg-[var(--fill-on-bg,var(--bg-inset))] text-text-tertiary",
5161
5201
  accent: "bg-[var(--accent-pop)] text-[var(--accent-on-fill)]",
5162
5202
  success: "bg-[var(--success)] text-[var(--success-contrast)]",
5163
5203
  warning: "bg-[var(--warning)] text-[var(--warning-contrast)]",
5164
5204
  danger: "bg-[var(--error)] text-[var(--error-contrast)]",
5165
- muted: "bg-[var(--bg-inset)] text-text-tertiary"
5205
+ muted: "bg-[var(--fill-on-bg,var(--bg-inset))] text-text-tertiary"
5166
5206
  },
5167
5207
  size: {
5168
5208
  sm: "h-[var(--space-4)] text-xs",
@@ -5333,7 +5373,7 @@ var PopoverArrow = React28.forwardRef(({ className, ...props }, ref) => /* @__PU
5333
5373
  PopoverArrow.displayName = PopoverPrimitive.Arrow.displayName;
5334
5374
 
5335
5375
  // src/components/ui/filter-toolbar.tsx
5336
- import { Fragment as Fragment9, jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
5376
+ import { Fragment as Fragment11, jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
5337
5377
  var collapsibleClassNames = {
5338
5378
  sm: {
5339
5379
  inline: "hidden @[640px]:flex",
@@ -5545,7 +5585,7 @@ var FilterToolbar = React29.forwardRef(
5545
5585
  activeFilterCount,
5546
5586
  "\uAC1C \uC801\uC6A9"
5547
5587
  ] }),
5548
- onClearFilters ? /* @__PURE__ */ jsxs28(Fragment9, { children: [
5588
+ onClearFilters ? /* @__PURE__ */ jsxs28(Fragment11, { children: [
5549
5589
  /* @__PURE__ */ jsx32("span", { "aria-hidden": "true", children: " \xB7 " }),
5550
5590
  /* @__PURE__ */ jsx32(
5551
5591
  "button",
@@ -5595,16 +5635,16 @@ FilterToolbar.displayName = "FilterToolbar";
5595
5635
 
5596
5636
  // src/components/ui/data-table.tsx
5597
5637
  import * as React33 from "react";
5598
- import { ChevronDown as ChevronDown5, ChevronUp as ChevronUp2, ChevronsUpDown } from "lucide-react";
5599
- import { cva as cva12 } from "class-variance-authority";
5638
+ import { ChevronDown as ChevronDown5, ChevronRight as ChevronRight3, ChevronUp as ChevronUp2, ChevronsUpDown } from "lucide-react";
5639
+ import { cva as cva13 } from "class-variance-authority";
5600
5640
 
5601
5641
  // src/components/ui/checkbox.tsx
5602
5642
  import * as React30 from "react";
5603
- import { cva as cva11 } from "class-variance-authority";
5643
+ import { cva as cva12 } from "class-variance-authority";
5604
5644
  import { Check as Check3, Minus } from "lucide-react";
5605
5645
  import { Checkbox as CheckboxPrimitive } from "radix-ui";
5606
5646
  import { jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
5607
- var checkboxFieldVariants = cva11(
5647
+ var checkboxFieldVariants = cva12(
5608
5648
  "flex flex-col gap-[var(--space-1)]",
5609
5649
  {
5610
5650
  variants: {
@@ -5619,14 +5659,14 @@ var checkboxFieldVariants = cva11(
5619
5659
  }
5620
5660
  );
5621
5661
  var checkboxVariants = checkboxFieldVariants;
5622
- var checkboxRootVariants = cva11(
5662
+ var checkboxRootVariants = cva12(
5623
5663
  [
5624
5664
  "group shrink-0 cursor-pointer rounded-[var(--radius-xs)]",
5625
5665
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]",
5626
5666
  "disabled:cursor-not-allowed"
5627
5667
  ].join(" ")
5628
5668
  );
5629
- var checkboxBoxVariants = cva11(
5669
+ var checkboxBoxVariants = cva12(
5630
5670
  [
5631
5671
  "flex shrink-0 items-center justify-center rounded-[var(--radius-xs)] border",
5632
5672
  "border-[var(--border-strong)] bg-[var(--bg-surface)] text-transparent",
@@ -5650,7 +5690,7 @@ var checkboxBoxVariants = cva11(
5650
5690
  }
5651
5691
  }
5652
5692
  );
5653
- var checkboxGroupItemVariants = cva11(
5693
+ var checkboxGroupItemVariants = cva12(
5654
5694
  [
5655
5695
  "group w-full cursor-pointer text-left transition-colors motion-reduce:transition-none",
5656
5696
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]",
@@ -5692,7 +5732,7 @@ var checkboxGroupItemVariants = cva11(
5692
5732
  }
5693
5733
  }
5694
5734
  );
5695
- var checkboxGroupBoxVariants = cva11(
5735
+ var checkboxGroupBoxVariants = cva12(
5696
5736
  "mt-[2px]",
5697
5737
  {
5698
5738
  variants: {
@@ -6188,7 +6228,7 @@ import { ChevronRight as ChevronRight2, MoreVertical } from "lucide-react";
6188
6228
  // src/components/ui/action-menu.tsx
6189
6229
  import * as React31 from "react";
6190
6230
  import { Dialog as DialogPrimitive4, Slot as Slot3 } from "radix-ui";
6191
- import { Fragment as Fragment11, jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
6231
+ import { Fragment as Fragment13, jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
6192
6232
  var sheetRowClassName = cn(
6193
6233
  "group flex min-h-12 w-full cursor-pointer items-center gap-[var(--space-3)] px-[var(--space-4)] py-[var(--space-2)] text-left",
6194
6234
  "border-t border-[var(--border-subtle)] text-[13px] font-medium leading-normal text-text-primary",
@@ -6346,7 +6386,7 @@ function ActionMenu({
6346
6386
  triggerRef.current?.focus();
6347
6387
  };
6348
6388
  const triggerLabel = trigger.props["aria-label"];
6349
- return /* @__PURE__ */ jsxs31(Fragment11, { children: [
6389
+ return /* @__PURE__ */ jsxs31(Fragment13, { children: [
6350
6390
  /* @__PURE__ */ jsxs31(DropdownMenu, { open: open && presentation === "dropdown", onOpenChange: setOpen, children: [
6351
6391
  /* @__PURE__ */ jsx35(DropdownMenuTrigger, { asChild: true, "aria-expanded": open, children: /* @__PURE__ */ jsx35(Slot3.Root, { ref: triggerRef, children: trigger }) }),
6352
6392
  /* @__PURE__ */ jsx35(DropdownMenuContent, { align: "end", onCloseAutoFocus: handleDropdownCloseAutoFocus, children: menuGroups.map((group, index) => /* @__PURE__ */ jsxs31(React31.Fragment, { children: [
@@ -6390,7 +6430,7 @@ function ActionMenu({
6390
6430
  }
6391
6431
 
6392
6432
  // src/components/ui/list-card.tsx
6393
- import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
6433
+ import { Fragment as Fragment14, jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
6394
6434
  function lineTokens(value) {
6395
6435
  return React32.Children.toArray(value).filter((token) => token !== "");
6396
6436
  }
@@ -6477,7 +6517,7 @@ function ListCard({
6477
6517
  children: overlay && href != null ? React32.createElement(linkComponent ?? "a", { ...linkProps, href, className: overlayClassName }, title) : title
6478
6518
  }
6479
6519
  );
6480
- const content = /* @__PURE__ */ jsxs32(Fragment12, { children: [
6520
+ const content = /* @__PURE__ */ jsxs32(Fragment14, { children: [
6481
6521
  leading != null ? /* @__PURE__ */ jsx36("span", { className: "flex min-h-[18px] items-center", children: leading }) : null,
6482
6522
  /* @__PURE__ */ jsxs32("span", { className: "min-w-0", children: [
6483
6523
  overlay && href == null ? (
@@ -6542,8 +6582,8 @@ function ListCard({
6542
6582
  }
6543
6583
 
6544
6584
  // src/components/ui/data-table.tsx
6545
- import { Fragment as Fragment13, jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
6546
- var dataTableVariants = cva12(
6585
+ import { Fragment as Fragment15, jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
6586
+ var dataTableVariants = cva13(
6547
6587
  [
6548
6588
  "relative overflow-hidden rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
6549
6589
  "text-foreground"
@@ -6562,7 +6602,7 @@ var dataTableVariants = cva12(
6562
6602
  }
6563
6603
  }
6564
6604
  );
6565
- var dataTableRowVariants = cva12(
6605
+ var dataTableRowVariants = cva13(
6566
6606
  [
6567
6607
  "grid min-h-[48px] items-center border-t border-[var(--border-subtle)]",
6568
6608
  "text-body-sm leading-compact text-foreground",
@@ -6593,9 +6633,9 @@ var alignmentClass = {
6593
6633
  function getRowId(row, keyField) {
6594
6634
  return String(row[keyField]);
6595
6635
  }
6596
- function getGridTemplate(columns, selectable) {
6636
+ function getGridTemplate(columns, selectable, expandable) {
6597
6637
  const columnWidths = columns.map((column) => column.width ?? "1fr");
6598
- return [selectable ? "44px" : null, ...columnWidths].filter(Boolean).join(" ");
6638
+ return [selectable ? "44px" : null, ...columnWidths, expandable ? "40px" : null].filter(Boolean).join(" ");
6599
6639
  }
6600
6640
  function getRenderedCell(row, column) {
6601
6641
  if (column.render) {
@@ -6665,7 +6705,7 @@ function MobileSortMenu({
6665
6705
  size: "sm",
6666
6706
  className: "ml-auto min-w-0",
6667
6707
  children: [
6668
- active && sortBy ? /* @__PURE__ */ jsxs33(Fragment13, { children: [
6708
+ active && sortBy ? /* @__PURE__ */ jsxs33(Fragment15, { children: [
6669
6709
  /* @__PURE__ */ jsx37("span", { className: "sr-only", children: "\uC815\uB82C " }),
6670
6710
  /* @__PURE__ */ jsx37("span", { className: "truncate", children: active.header }),
6671
6711
  /* @__PURE__ */ jsxs33("span", { className: "sr-only", children: [
@@ -6805,6 +6845,19 @@ var rowLinkClass = cn(
6805
6845
  "text-inherit no-underline outline-none after:absolute after:inset-0 after:content-['']",
6806
6846
  "focus-visible:after:ring-2 focus-visible:after:ring-inset focus-visible:after:ring-[var(--focus-ring)]"
6807
6847
  );
6848
+ var expandedPanelClass = cn(
6849
+ "grid grid-rows-[0fr] invisible data-[state=open]:grid-rows-[1fr] data-[state=open]:visible",
6850
+ "motion-safe:[transition:grid-template-rows_var(--dur-base)_var(--ease-standard),visibility_0s_linear_var(--dur-base)]",
6851
+ "motion-safe:data-[state=open]:[transition:grid-template-rows_var(--dur-base)_var(--ease-out),visibility_0s]"
6852
+ );
6853
+ var expandChevronClass = "motion-safe:transition-transform motion-safe:duration-[var(--dur-base)] motion-safe:ease-[var(--ease-standard)]";
6854
+ function useOpenedOnce(expanded) {
6855
+ const [opened, setOpened] = React33.useState(expanded);
6856
+ if (expanded && !opened) {
6857
+ setOpened(true);
6858
+ }
6859
+ return opened || expanded;
6860
+ }
6808
6861
  function useActivationHandlers({ row, href, activatable, onActivate }) {
6809
6862
  return {
6810
6863
  onClick: (event) => {
@@ -6837,12 +6890,14 @@ function DataTableRowView({
6837
6890
  onToggle,
6838
6891
  onActivate,
6839
6892
  onRowContextMenu,
6893
+ expand,
6840
6894
  gridTemplateColumns,
6841
6895
  ariaRowIndex
6842
6896
  }) {
6843
6897
  const linked = Boolean(LinkComponent && href);
6844
6898
  const handlers = useActivationHandlers({ row, href, activatable, onActivate });
6845
- return /* @__PURE__ */ jsxs33(
6899
+ const opened = useOpenedOnce(expand?.expanded ?? false);
6900
+ const dataRow = /* @__PURE__ */ jsxs33(
6846
6901
  "div",
6847
6902
  {
6848
6903
  "data-slot": "data-table-row",
@@ -6852,12 +6907,14 @@ function DataTableRowView({
6852
6907
  "aria-rowindex": ariaRowIndex,
6853
6908
  tabIndex: activatable ? 0 : void 0,
6854
6909
  className: cn(
6855
- dataTableRowVariants({ interactive: activatable || linked, selected: visuallySelected }),
6910
+ dataTableRowVariants({ interactive: activatable || linked || expand != null, selected: visuallySelected }),
6856
6911
  linked ? rowLinkHostClass : null
6857
6912
  ),
6858
6913
  style: { gridTemplateColumns },
6859
6914
  onContextMenu: (event) => onRowContextMenu?.(rowId, event),
6860
- onClick: handlers.onClick,
6915
+ onClick: expand ? (event) => {
6916
+ if (!isInteractiveTarget(event.target)) expand.onToggle(rowId);
6917
+ } : handlers.onClick,
6861
6918
  onKeyDown: handlers.onKeyDown,
6862
6919
  children: [
6863
6920
  selectable ? /* @__PURE__ */ jsx37("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx37(RowCheckbox, { row, rowId, columns, selected, onToggle }) }) : null,
@@ -6878,10 +6935,53 @@ function DataTableRowView({
6878
6935
  },
6879
6936
  column.key
6880
6937
  );
6881
- })
6938
+ }),
6939
+ expand ? /* @__PURE__ */ jsx37("div", { role: "cell", "data-slot": "data-table-expand-cell", className: "flex items-center justify-end pr-[var(--space-2)]", children: /* @__PURE__ */ jsx37(
6940
+ IconButton,
6941
+ {
6942
+ icon: ChevronRight3,
6943
+ "aria-label": expand.label,
6944
+ "aria-expanded": expand.expanded,
6945
+ "aria-controls": expand.panelId,
6946
+ appearance: "ghost",
6947
+ tone: "neutral",
6948
+ size: "md",
6949
+ className: cn(
6950
+ "aria-expanded:[&_svg]:rotate-90",
6951
+ "motion-safe:[&_svg]:transition-transform motion-safe:[&_svg]:duration-[var(--dur-base)] motion-safe:[&_svg]:ease-[var(--ease-standard)]"
6952
+ ),
6953
+ onClick: () => expand.onToggle(rowId)
6954
+ }
6955
+ ) }) : null
6882
6956
  ]
6883
6957
  }
6884
6958
  );
6959
+ if (!expand) {
6960
+ return dataRow;
6961
+ }
6962
+ return /* @__PURE__ */ jsxs33(Fragment15, { children: [
6963
+ dataRow,
6964
+ /* @__PURE__ */ jsx37(
6965
+ "div",
6966
+ {
6967
+ role: "row",
6968
+ "data-slot": "data-table-expanded-row",
6969
+ "data-row-id": rowId,
6970
+ "data-state": expand.expanded ? "open" : "closed",
6971
+ className: expandedPanelClass,
6972
+ children: /* @__PURE__ */ jsx37(
6973
+ "div",
6974
+ {
6975
+ role: "cell",
6976
+ id: expand.panelId,
6977
+ "aria-colspan": columns.length + (selectable ? 2 : 1),
6978
+ className: "min-h-0 min-w-0 overflow-hidden",
6979
+ children: opened ? expand.render(row) : null
6980
+ }
6981
+ )
6982
+ }
6983
+ )
6984
+ ] });
6885
6985
  }
6886
6986
  function DataTableMobileCardView({
6887
6987
  row,
@@ -6896,6 +6996,7 @@ function DataTableMobileCardView({
6896
6996
  onToggle,
6897
6997
  onActivate,
6898
6998
  onRowContextMenu,
6999
+ expand,
6899
7000
  getMobileCardContent,
6900
7001
  ariaPosInSet,
6901
7002
  ariaSetSize,
@@ -6904,12 +7005,27 @@ function DataTableMobileCardView({
6904
7005
  const linked = Boolean(LinkComponent && href);
6905
7006
  const content = getMobileCardContent(row);
6906
7007
  const navigable = linked || activatable;
7008
+ const opened = useOpenedOnce(expand?.expanded ?? false);
6907
7009
  const leading = selectable || content.leading != null ? /* @__PURE__ */ jsxs33("span", { className: "flex items-center gap-[var(--space-2)]", children: [
6908
7010
  selectable ? /* @__PURE__ */ jsx37(RowCheckbox, { row, rowId, columns, selected, onToggle }) : null,
6909
7011
  content.leading
6910
7012
  ] }) : void 0;
6911
7013
  let title = content.title;
6912
- if (linked && LinkComponent) {
7014
+ if (expand) {
7015
+ title = /* @__PURE__ */ jsx37(
7016
+ "button",
7017
+ {
7018
+ type: "button",
7019
+ "data-slot": "data-table-row-link",
7020
+ "aria-label": expand.label,
7021
+ "aria-expanded": expand.expanded,
7022
+ "aria-controls": expand.panelId,
7023
+ className: cn(rowLinkClass, "block w-full text-left"),
7024
+ onClick: () => expand.onToggle(rowId),
7025
+ children: /* @__PURE__ */ jsx37("span", { className: "line-clamp-2", children: content.title })
7026
+ }
7027
+ );
7028
+ } else if (linked && LinkComponent) {
6913
7029
  title = /* @__PURE__ */ jsx37(LinkComponent, { href, "data-slot": "data-table-row-link", className: rowLinkClass, children: content.title });
6914
7030
  } else if (activatable) {
6915
7031
  title = /* @__PURE__ */ jsx37(
@@ -6923,7 +7039,7 @@ function DataTableMobileCardView({
6923
7039
  }
6924
7040
  );
6925
7041
  }
6926
- return /* @__PURE__ */ jsx37(
7042
+ return /* @__PURE__ */ jsxs33(
6927
7043
  "div",
6928
7044
  {
6929
7045
  "data-slot": "data-table-mobile-card",
@@ -6941,20 +7057,42 @@ function DataTableMobileCardView({
6941
7057
  navigable ? rowLinkHostClass : null
6942
7058
  ),
6943
7059
  onContextMenu: (event) => onRowContextMenu?.(rowId, event),
6944
- children: /* @__PURE__ */ jsx37(
6945
- ListCard,
6946
- {
6947
- className: "px-[var(--space-4)] py-[var(--space-3)]",
6948
- title,
6949
- meta: content.meta ? [content.meta[0], content.meta[1]] : void 0,
6950
- status: content.status,
6951
- caption: content.date,
6952
- value: content.value,
6953
- leading,
6954
- trailing: navigable ? "chevron" : "none",
6955
- actions: content.actions
6956
- }
6957
- )
7060
+ children: [
7061
+ /* @__PURE__ */ jsx37(
7062
+ ListCard,
7063
+ {
7064
+ className: cn(
7065
+ "px-[var(--space-4)] py-[var(--space-3)]",
7066
+ expand ? ["cursor-pointer transition-colors hover:bg-[var(--action-hover)] motion-reduce:transition-none", rowLinkHostClass] : null
7067
+ ),
7068
+ title,
7069
+ meta: content.meta ? [content.meta[0], content.meta[1]] : void 0,
7070
+ status: content.status,
7071
+ caption: content.date,
7072
+ value: content.value,
7073
+ leading,
7074
+ trailing: expand ? /* @__PURE__ */ jsx37(
7075
+ ChevronRight3,
7076
+ {
7077
+ "aria-hidden": true,
7078
+ "data-state": expand.expanded ? "open" : "closed",
7079
+ className: cn("block size-[var(--space-4)] shrink-0 text-text-tertiary data-[state=open]:rotate-90", expandChevronClass)
7080
+ }
7081
+ ) : navigable ? "chevron" : "none",
7082
+ actions: content.actions
7083
+ }
7084
+ ),
7085
+ expand ? /* @__PURE__ */ jsx37(
7086
+ "div",
7087
+ {
7088
+ id: expand.panelId,
7089
+ "data-slot": "data-table-expanded",
7090
+ "data-state": expand.expanded ? "open" : "closed",
7091
+ className: expandedPanelClass,
7092
+ children: /* @__PURE__ */ jsx37("div", { className: "min-h-0 min-w-0 overflow-hidden", children: opened ? expand.render(row) : null })
7093
+ }
7094
+ ) : null
7095
+ ]
6958
7096
  }
6959
7097
  );
6960
7098
  }
@@ -7262,7 +7400,7 @@ function useLayoutFocusHandoff({
7262
7400
  const item = record.rowId ? Array.from(container.querySelectorAll("[data-row-id]")).find(
7263
7401
  (node) => node.getAttribute("data-row-id") === record.rowId
7264
7402
  ) : void 0;
7265
- const target = (item && (record.checkbox ? item.querySelector('[role="checkbox"]') : item.hasAttribute("tabindex") ? item : item.querySelector('[data-slot="data-table-row-link"]'))) ?? item ?? container;
7403
+ const target = (item && (record.checkbox ? item.querySelector('[role="checkbox"]') : item.hasAttribute("tabindex") ? item : item.querySelector('[data-slot="data-table-row-link"],[data-slot="data-table-expand-cell"] button'))) ?? item ?? container;
7266
7404
  if (target instanceof HTMLElement) {
7267
7405
  if (!target.hasAttribute("tabindex") && !target.matches("a[href],button,input")) {
7268
7406
  target.tabIndex = -1;
@@ -7294,6 +7432,10 @@ function DataTableInner({
7294
7432
  linkComponent,
7295
7433
  onRowClick,
7296
7434
  virtual,
7435
+ renderExpanded,
7436
+ getExpandLabel,
7437
+ expandedIds,
7438
+ onExpandedChange,
7297
7439
  skeletonRowCount = 8,
7298
7440
  "aria-label": ariaLabel = "\uB370\uC774\uD130 \uD14C\uC774\uBE14",
7299
7441
  ...props
@@ -7341,7 +7483,23 @@ function DataTableInner({
7341
7483
  const allVisibleRowsSelected = rowIds.length > 0 && selectedCount === rowIds.length;
7342
7484
  const partiallySelected = selectedCount > 0 && !allVisibleRowsSelected;
7343
7485
  const selectAllChecked = partiallySelected ? "indeterminate" : allVisibleRowsSelected;
7344
- const gridTemplateColumns = getGridTemplate(columns, selectable);
7486
+ const expandable = renderExpanded != null;
7487
+ const gridTemplateColumns = getGridTemplate(columns, selectable, expandable);
7488
+ const panelIdBase = React33.useId();
7489
+ const [ownExpandedIds, setOwnExpandedIds] = React33.useState(() => /* @__PURE__ */ new Set());
7490
+ const resolvedExpandedIds = expandedIds ?? ownExpandedIds;
7491
+ const toggleExpanded = (id) => {
7492
+ const nextIds = new Set(resolvedExpandedIds);
7493
+ if (nextIds.has(id)) {
7494
+ nextIds.delete(id);
7495
+ } else {
7496
+ nextIds.add(id);
7497
+ }
7498
+ if (expandedIds === void 0) {
7499
+ setOwnExpandedIds(nextIds);
7500
+ }
7501
+ onExpandedChange?.(nextIds);
7502
+ };
7345
7503
  const emitSelection = (nextIds) => {
7346
7504
  onSelectionChange?.(nextIds);
7347
7505
  };
@@ -7386,7 +7544,7 @@ function DataTableInner({
7386
7544
  (rowId, event) => latestHandlers.current.onRowContextMenu?.(rowId, event),
7387
7545
  []
7388
7546
  );
7389
- const getItemProps = (row) => {
7547
+ const getItemProps = (row, layout, index) => {
7390
7548
  const rowId = getRowId(row, keyField);
7391
7549
  const selected = resolvedSelectedIds.has(rowId);
7392
7550
  const href = rowHref?.(row);
@@ -7403,7 +7561,14 @@ function DataTableInner({
7403
7561
  LinkComponent: linkComponent,
7404
7562
  onToggle: isVirtual ? stableToggleRow : toggleRow,
7405
7563
  onActivate: isVirtual ? stableActivateRow : activateRow,
7406
- onRowContextMenu: isVirtual ? stableRowContextMenu : onRowContextMenu
7564
+ onRowContextMenu: isVirtual ? stableRowContextMenu : onRowContextMenu,
7565
+ expand: renderExpanded && getExpandLabel ? {
7566
+ expanded: resolvedExpandedIds.has(rowId),
7567
+ label: getExpandLabel(row),
7568
+ panelId: `${panelIdBase}-${layout}-${index}`,
7569
+ render: renderExpanded,
7570
+ onToggle: toggleExpanded
7571
+ } : void 0
7407
7572
  };
7408
7573
  };
7409
7574
  const sliceFor = (layout) => {
@@ -7521,7 +7686,8 @@ function DataTableInner({
7521
7686
  },
7522
7687
  column.key
7523
7688
  );
7524
- })
7689
+ }),
7690
+ expandable ? /* @__PURE__ */ jsx37("div", { role: "cell" }) : null
7525
7691
  ]
7526
7692
  }
7527
7693
  ),
@@ -7547,7 +7713,7 @@ function DataTableInner({
7547
7713
  }
7548
7714
  ) }) })
7549
7715
  ) : /* @__PURE__ */ jsx37("div", { ref: desktopListRef, role: "rowgroup", style: desktopSlice.style, children: desktopSlice.rows.map((row, index) => {
7550
- const itemProps = getItemProps(row);
7716
+ const itemProps = getItemProps(row, "desktop", desktopSlice.start + index);
7551
7717
  return /* @__PURE__ */ jsx37(
7552
7718
  RowComponent,
7553
7719
  {
@@ -7582,8 +7748,8 @@ function DataTableInner({
7582
7748
  "aria-label": `${ariaLabel} \uBAA8\uBC14\uC77C \uCE74\uB4DC \uBAA9\uB85D`,
7583
7749
  style: mobileSlice.style,
7584
7750
  children: mobileSlice.rows.map((row, index) => {
7585
- const itemProps = getItemProps(row);
7586
7751
  const rowIndex = mobileSlice.start + index;
7752
+ const itemProps = getItemProps(row, "mobile", rowIndex);
7587
7753
  return /* @__PURE__ */ jsx37(
7588
7754
  CardComponent,
7589
7755
  {
@@ -8292,7 +8458,7 @@ function ActionSheet({
8292
8458
  import * as React35 from "react";
8293
8459
  import { jsx as jsx45 } from "react/jsx-runtime";
8294
8460
  var TONE = {
8295
- neutral: "bg-[var(--semantic-neutral-bg)] text-[var(--semantic-neutral-fg)]",
8461
+ neutral: "bg-[var(--fill-on-bg,var(--semantic-neutral-bg))] text-[var(--semantic-neutral-fg)]",
8296
8462
  info: "bg-[var(--semantic-info-bg)] text-[var(--semantic-info-fg)]",
8297
8463
  success: "bg-[var(--semantic-success-bg)] text-[var(--semantic-success-fg)]",
8298
8464
  warning: "bg-[var(--semantic-warning-bg)] text-[var(--semantic-warning-fg)]",
@@ -8330,7 +8496,8 @@ var FG = {
8330
8496
  error: "var(--semantic-error-fg)"
8331
8497
  };
8332
8498
  var BG = {
8333
- neutral: "var(--bg-inset)",
8499
+ // takes --fill-on-bg when an inset background sets it (see surface.ts)
8500
+ neutral: "var(--fill-on-bg, var(--bg-inset))",
8334
8501
  info: "var(--semantic-info-bg)",
8335
8502
  success: "var(--semantic-success-bg)",
8336
8503
  warning: "var(--semantic-warning-bg)",
@@ -8399,7 +8566,7 @@ var TwoTierBadge = React36.forwardRef(
8399
8566
  style: {
8400
8567
  borderLeft: `1px solid ${divider}`,
8401
8568
  color: "var(--text-tertiary)",
8402
- background: strong ? "var(--bg-inset)" : "transparent"
8569
+ background: strong ? BG.neutral : "transparent"
8403
8570
  },
8404
8571
  children: secondary
8405
8572
  }
@@ -8473,9 +8640,9 @@ StatusDot.displayName = "StatusDot";
8473
8640
 
8474
8641
  // src/components/ui/notification-badge.tsx
8475
8642
  import * as React39 from "react";
8476
- import { cva as cva13 } from "class-variance-authority";
8643
+ import { cva as cva14 } from "class-variance-authority";
8477
8644
  import { jsx as jsx49 } from "react/jsx-runtime";
8478
- var notificationBadgeVariants = cva13(
8645
+ var notificationBadgeVariants = cva14(
8479
8646
  [
8480
8647
  "inline-flex shrink-0 items-center justify-center rounded-[var(--radius-full)]",
8481
8648
  "bg-[var(--semantic-error,var(--error))] text-[var(--error-contrast)]",
@@ -8539,9 +8706,9 @@ NotificationBadge.displayName = "NotificationBadge";
8539
8706
 
8540
8707
  // src/components/ui/empty-state.tsx
8541
8708
  import * as React40 from "react";
8542
- import { cva as cva14 } from "class-variance-authority";
8709
+ import { cva as cva15 } from "class-variance-authority";
8543
8710
  import { jsx as jsx50, jsxs as jsxs39 } from "react/jsx-runtime";
8544
- var emptyStateBaseVariants = cva14(
8711
+ var emptyStateBaseVariants = cva15(
8545
8712
  [
8546
8713
  "flex flex-col items-center justify-center text-center",
8547
8714
  "text-foreground"
@@ -8565,6 +8732,71 @@ var emptyStateBaseVariants = cva14(
8565
8732
  }
8566
8733
  }
8567
8734
  );
8735
+ var PAGE_FILL_QUERY = "(min-width: 768px)";
8736
+ var useIsomorphicLayoutEffect3 = typeof window === "undefined" ? React40.useEffect : React40.useLayoutEffect;
8737
+ function findScrollParent(node) {
8738
+ for (let el = node.parentElement; el && el !== document.body && el !== document.documentElement; el = el.parentElement) {
8739
+ const { overflowY } = getComputedStyle(el);
8740
+ if (overflowY === "auto" || overflowY === "scroll") return el;
8741
+ }
8742
+ return null;
8743
+ }
8744
+ function freeHeight(area) {
8745
+ const rect = area.getBoundingClientRect();
8746
+ const style = getComputedStyle(area);
8747
+ const start = area === document.documentElement ? rect.top : rect.top + area.clientTop - area.scrollTop;
8748
+ let end = start + parseFloat(style.paddingTop);
8749
+ for (const child of Array.from(area.children)) {
8750
+ const childStyle = getComputedStyle(child);
8751
+ if (childStyle.display === "none" || childStyle.position === "absolute" || childStyle.position === "fixed") continue;
8752
+ end = Math.max(end, child.getBoundingClientRect().bottom + parseFloat(childStyle.marginBottom));
8753
+ }
8754
+ return area.clientHeight - (end - start + parseFloat(style.paddingBottom));
8755
+ }
8756
+ function usePageFill(ref, enabled) {
8757
+ useIsomorphicLayoutEffect3(() => {
8758
+ const node = ref.current;
8759
+ if (!enabled || !node) return;
8760
+ const scroller = findScrollParent(node);
8761
+ const parent = node.parentElement;
8762
+ const media = typeof window.matchMedia === "function" ? window.matchMedia(PAGE_FILL_QUERY) : null;
8763
+ let observer = null;
8764
+ let frame = 0;
8765
+ const fit = () => {
8766
+ const previous = node.style.minHeight;
8767
+ let next = "";
8768
+ if (media?.matches ?? true) {
8769
+ node.style.minHeight = "";
8770
+ const free = freeHeight(scroller ?? document.scrollingElement ?? document.documentElement);
8771
+ if (free > 0) next = `${Math.floor(node.getBoundingClientRect().height + free)}px`;
8772
+ }
8773
+ node.style.minHeight = next;
8774
+ if (next !== previous && observer && parent && !frame) {
8775
+ observer.unobserve(parent);
8776
+ frame = requestAnimationFrame(() => {
8777
+ frame = 0;
8778
+ observer?.observe(parent);
8779
+ });
8780
+ }
8781
+ };
8782
+ fit();
8783
+ if (typeof ResizeObserver === "function") {
8784
+ observer = new ResizeObserver(fit);
8785
+ if (scroller) observer.observe(scroller);
8786
+ if (parent) observer.observe(parent);
8787
+ }
8788
+ if (!scroller) window.addEventListener("resize", fit);
8789
+ media?.addEventListener?.("change", fit);
8790
+ return () => {
8791
+ observer?.disconnect();
8792
+ observer = null;
8793
+ cancelAnimationFrame(frame);
8794
+ window.removeEventListener("resize", fit);
8795
+ media?.removeEventListener?.("change", fit);
8796
+ node.style.minHeight = "";
8797
+ };
8798
+ }, [enabled]);
8799
+ }
8568
8800
  function getEmptyStateToneSurface(tone) {
8569
8801
  switch (tone) {
8570
8802
  case "muted":
@@ -8590,7 +8822,7 @@ function emptyStateVariants({
8590
8822
  className
8591
8823
  );
8592
8824
  }
8593
- var emptyStateIconVariants = cva14(
8825
+ var emptyStateIconVariants = cva15(
8594
8826
  [
8595
8827
  "inline-flex items-center justify-center rounded-[var(--radius-full)]",
8596
8828
  "border border-[var(--border-subtle)] bg-[var(--bg-inset)] text-text-tertiary"
@@ -8625,10 +8857,13 @@ var EmptyState = React40.forwardRef(
8625
8857
  hint,
8626
8858
  action,
8627
8859
  bordered = false,
8860
+ layout = "inline",
8628
8861
  ...props
8629
8862
  }, ref) => {
8630
8863
  const resolvedSize = size ?? "md";
8631
- return /* @__PURE__ */ jsxs39(
8864
+ const pageRef = React40.useRef(null);
8865
+ usePageFill(pageRef, layout === "page");
8866
+ const box = /* @__PURE__ */ jsxs39(
8632
8867
  "div",
8633
8868
  {
8634
8869
  ref,
@@ -8676,6 +8911,17 @@ var EmptyState = React40.forwardRef(
8676
8911
  ]
8677
8912
  }
8678
8913
  );
8914
+ if (layout !== "page") return box;
8915
+ return /* @__PURE__ */ jsx50(
8916
+ "div",
8917
+ {
8918
+ ref: pageRef,
8919
+ "data-slot": "empty-state-page",
8920
+ "data-layout": "page",
8921
+ className: "flex w-full flex-col justify-start pt-[var(--space-12)] md:justify-center md:pt-0",
8922
+ children: box
8923
+ }
8924
+ );
8679
8925
  }
8680
8926
  );
8681
8927
  EmptyState.displayName = "EmptyState";
@@ -8683,9 +8929,9 @@ EmptyState.displayName = "EmptyState";
8683
8929
  // src/components/ui/error-state.tsx
8684
8930
  import * as React41 from "react";
8685
8931
  import { AlertTriangle } from "lucide-react";
8686
- import { cva as cva15 } from "class-variance-authority";
8932
+ import { cva as cva16 } from "class-variance-authority";
8687
8933
  import { jsx as jsx51, jsxs as jsxs40 } from "react/jsx-runtime";
8688
- var errorStateVariants = cva15(
8934
+ var errorStateVariants = cva16(
8689
8935
  [
8690
8936
  "flex flex-col items-center justify-center text-center",
8691
8937
  "rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
@@ -8770,9 +9016,9 @@ ErrorState.displayName = "ErrorState";
8770
9016
 
8771
9017
  // src/components/ui/skeleton.tsx
8772
9018
  import * as React42 from "react";
8773
- import { cva as cva16 } from "class-variance-authority";
9019
+ import { cva as cva17 } from "class-variance-authority";
8774
9020
  import { jsx as jsx52 } from "react/jsx-runtime";
8775
- var skeletonVariants = cva16(
9021
+ var skeletonVariants = cva17(
8776
9022
  [
8777
9023
  // bg-inset: light #F1F2F4 reads on white surfaces (bg-raised was white = invisible);
8778
9024
  // dark value equals the old bg-raised (#16181D), so dark mode is unchanged.
@@ -8792,7 +9038,7 @@ var skeletonVariants = cva16(
8792
9038
  }
8793
9039
  }
8794
9040
  );
8795
- var spinnerVariants = cva16(
9041
+ var spinnerVariants = cva17(
8796
9042
  [
8797
9043
  "inline-block shrink-0 animate-spin rounded-[var(--radius-full)] border-2",
8798
9044
  "border-[var(--border-subtle)] border-t-[var(--primary)]",
@@ -8923,8 +9169,8 @@ Spinner.displayName = "Spinner";
8923
9169
 
8924
9170
  // src/components/ui/pagination.tsx
8925
9171
  import * as React43 from "react";
8926
- import { ChevronsLeft, ChevronLeft, ChevronRight as ChevronRight3, ChevronsRight } from "lucide-react";
8927
- import { cva as cva17 } from "class-variance-authority";
9172
+ import { ChevronsLeft, ChevronLeft, ChevronRight as ChevronRight4, ChevronsRight } from "lucide-react";
9173
+ import { cva as cva18 } from "class-variance-authority";
8928
9174
 
8929
9175
  // src/components/ui/page-size-select.tsx
8930
9176
  import { jsx as jsx53, jsxs as jsxs41 } from "react/jsx-runtime";
@@ -8979,7 +9225,7 @@ function PageSizeSelect({
8979
9225
 
8980
9226
  // src/components/ui/pagination.tsx
8981
9227
  import { jsx as jsx54, jsxs as jsxs42 } from "react/jsx-runtime";
8982
- var paginationVariants = cva17(
9228
+ var paginationVariants = cva18(
8983
9229
  [
8984
9230
  "flex w-full flex-col gap-[var(--space-3)]",
8985
9231
  "text-sm text-text-secondary",
@@ -8997,7 +9243,7 @@ var paginationVariants = cva17(
8997
9243
  }
8998
9244
  }
8999
9245
  );
9000
- var paginationControlVariants = cva17(
9246
+ var paginationControlVariants = cva18(
9001
9247
  [
9002
9248
  "inline-flex shrink-0 items-center justify-center rounded-[var(--radius-md)] border",
9003
9249
  "border-transparent bg-transparent font-medium text-text-secondary",
@@ -9174,7 +9420,7 @@ var Pagination = React43.forwardRef(
9174
9420
  page: Math.min(pageCount, currentPage + 1),
9175
9421
  disabled: isLastPage,
9176
9422
  size: resolvedSize,
9177
- icon: ChevronRight3,
9423
+ icon: ChevronRight4,
9178
9424
  onPageChange
9179
9425
  }
9180
9426
  ),
@@ -9200,15 +9446,16 @@ var Pagination = React43.forwardRef(
9200
9446
  Pagination.displayName = "Pagination";
9201
9447
 
9202
9448
  // src/components/ui/mode-toggle.tsx
9203
- import { cva as cva18 } from "class-variance-authority";
9449
+ import { cva as cva19 } from "class-variance-authority";
9204
9450
  import { jsx as jsx55, jsxs as jsxs43 } from "react/jsx-runtime";
9205
- var modeToggleVariants = cva18(
9451
+ var modeToggleVariants = cva19(
9206
9452
  [
9207
9453
  "inline-flex items-center rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
9208
- "bg-[var(--bg-inset)] p-[2px]"
9454
+ "bg-[var(--bg-inset)] p-[2px]",
9455
+ insetMarkerContext
9209
9456
  ].join(" ")
9210
9457
  );
9211
- var modeToggleItemVariants = cva18(
9458
+ var modeToggleItemVariants = cva19(
9212
9459
  [
9213
9460
  "inline-flex min-h-[28px] cursor-pointer items-center justify-center gap-[var(--space-1)]",
9214
9461
  "rounded-[calc(var(--radius-md)_-_2px)] px-[var(--space-3)] py-[var(--space-1)]",
@@ -9270,9 +9517,9 @@ function ModeToggle({
9270
9517
 
9271
9518
  // src/components/ui/action-footer.tsx
9272
9519
  import * as React44 from "react";
9273
- import { cva as cva19 } from "class-variance-authority";
9520
+ import { cva as cva20 } from "class-variance-authority";
9274
9521
  import { jsx as jsx56, jsxs as jsxs44 } from "react/jsx-runtime";
9275
- var actionFooterVariants = cva19(
9522
+ var actionFooterVariants = cva20(
9276
9523
  [
9277
9524
  // Below sm: two fixed rows — destructive actions (start) and status (end) on top, the main
9278
9525
  // actions filling the bottom row. The top row is omitted when both are absent. From sm: one
@@ -9297,7 +9544,7 @@ var actionFooterVariants = cva19(
9297
9544
  }
9298
9545
  }
9299
9546
  );
9300
- var actionFooterStatusVariants = cva19(
9547
+ var actionFooterStatusVariants = cva20(
9301
9548
  [
9302
9549
  "col-start-2 flex min-w-0 items-center justify-self-end gap-[var(--space-2)]",
9303
9550
  "sm:ml-auto",
@@ -9441,7 +9688,7 @@ ActionFooter.displayName = "ActionFooter";
9441
9688
 
9442
9689
  // src/components/ui/toast.tsx
9443
9690
  import * as React45 from "react";
9444
- import { cva as cva20 } from "class-variance-authority";
9691
+ import { cva as cva21 } from "class-variance-authority";
9445
9692
  import { jsx as jsx57, jsxs as jsxs45 } from "react/jsx-runtime";
9446
9693
  var DOT3 = {
9447
9694
  default: "var(--neutral)",
@@ -9450,7 +9697,7 @@ var DOT3 = {
9450
9697
  info: "var(--info)",
9451
9698
  error: "var(--error)"
9452
9699
  };
9453
- var toastVariants = cva20(
9700
+ var toastVariants = cva21(
9454
9701
  [
9455
9702
  "flex min-w-[280px] max-w-[420px] items-center",
9456
9703
  "gap-[11px] rounded-[10px] border border-[var(--border)]",
@@ -9472,7 +9719,7 @@ var toastVariants = cva20(
9472
9719
  defaultVariants: { variant: "default" }
9473
9720
  }
9474
9721
  );
9475
- var toastViewportVariants = cva20(
9722
+ var toastViewportVariants = cva21(
9476
9723
  [
9477
9724
  "fixed bottom-[var(--space-6)] right-[var(--space-6)] z-[var(--z-toast,50)]",
9478
9725
  "flex w-[min(420px,calc(100vw-var(--space-12)))] list-none flex-col gap-[var(--space-2)]",
@@ -9704,10 +9951,10 @@ function ToastProvider({ children, maxToasts = 3, className, ...props }) {
9704
9951
 
9705
9952
  // src/components/ui/otp-field.tsx
9706
9953
  import * as React46 from "react";
9707
- import { cva as cva21 } from "class-variance-authority";
9954
+ import { cva as cva22 } from "class-variance-authority";
9708
9955
  import { AlertCircle as AlertCircle4 } from "lucide-react";
9709
- import { Fragment as Fragment14, jsx as jsx58, jsxs as jsxs46 } from "react/jsx-runtime";
9710
- var otpFieldVariants = cva21("flex w-full min-w-0 flex-col gap-[var(--space-3)]", {
9956
+ import { Fragment as Fragment16, jsx as jsx58, jsxs as jsxs46 } from "react/jsx-runtime";
9957
+ var otpFieldVariants = cva22("flex w-full min-w-0 flex-col gap-[var(--space-3)]", {
9711
9958
  variants: {
9712
9959
  size: {
9713
9960
  default: "",
@@ -9718,7 +9965,7 @@ var otpFieldVariants = cva21("flex w-full min-w-0 flex-col gap-[var(--space-3)]"
9718
9965
  size: "default"
9719
9966
  }
9720
9967
  });
9721
- var otpFieldGroupVariants = cva21("flex items-start gap-[var(--space-2)] pt-[var(--space-1)]", {
9968
+ var otpFieldGroupVariants = cva22("flex items-start gap-[var(--space-2)] pt-[var(--space-1)]", {
9722
9969
  variants: {
9723
9970
  size: {
9724
9971
  default: "",
@@ -9734,7 +9981,7 @@ var otpFieldGroupVariants = cva21("flex items-start gap-[var(--space-2)] pt-[var
9734
9981
  fluid: false
9735
9982
  }
9736
9983
  });
9737
- var otpCellVariants = cva21(
9984
+ var otpCellVariants = cva22(
9738
9985
  [
9739
9986
  "flex items-center justify-center rounded-[var(--radius-md)] border",
9740
9987
  "border-[var(--border)] text-foreground",
@@ -9789,7 +10036,7 @@ var otpCellVariants = cva21(
9789
10036
  }
9790
10037
  }
9791
10038
  );
9792
- var otpFieldMessageVariants = cva21("flex items-start gap-[var(--space-1)] text-xs leading-snug", {
10039
+ var otpFieldMessageVariants = cva22("flex items-start gap-[var(--space-1)] text-xs leading-snug", {
9793
10040
  variants: {
9794
10041
  state: {
9795
10042
  default: "text-text-tertiary",
@@ -10028,7 +10275,7 @@ var OTPField = React46.forwardRef(
10028
10275
  "data-slot": "otp-field-message",
10029
10276
  "data-kind": errorText ? "error" : "helper",
10030
10277
  className: otpFieldMessageVariants({ state: resolvedState }),
10031
- children: errorText ? /* @__PURE__ */ jsxs46(Fragment14, { children: [
10278
+ children: errorText ? /* @__PURE__ */ jsxs46(Fragment16, { children: [
10032
10279
  /* @__PURE__ */ jsx58(
10033
10280
  AlertCircle4,
10034
10281
  {
@@ -10064,9 +10311,9 @@ OTPField.displayName = "OTPField";
10064
10311
  // src/components/ui/search-field.tsx
10065
10312
  import * as React47 from "react";
10066
10313
  import { Search, X as X4 } from "lucide-react";
10067
- import { cva as cva22 } from "class-variance-authority";
10314
+ import { cva as cva23 } from "class-variance-authority";
10068
10315
  import { jsx as jsx59, jsxs as jsxs47 } from "react/jsx-runtime";
10069
- var searchFieldVariants = cva22("relative flex w-full items-center", {
10316
+ var searchFieldVariants = cva23("relative flex w-full items-center", {
10070
10317
  variants: {
10071
10318
  size: {
10072
10319
  // Field-control scale follows Select: sm/md/lg = 30/32/36px. Pair with Button sm/md/lg.
@@ -10079,7 +10326,7 @@ var searchFieldVariants = cva22("relative flex w-full items-center", {
10079
10326
  size: "md"
10080
10327
  }
10081
10328
  });
10082
- var searchFieldInputVariants = cva22(
10329
+ var searchFieldInputVariants = cva23(
10083
10330
  [
10084
10331
  "h-full w-full rounded-[var(--radius-md)] border",
10085
10332
  "border-[var(--border)]",
@@ -10222,9 +10469,9 @@ SearchField.displayName = "SearchField";
10222
10469
 
10223
10470
  // src/components/ui/checkbox-group.tsx
10224
10471
  import * as React48 from "react";
10225
- import { cva as cva23 } from "class-variance-authority";
10472
+ import { cva as cva24 } from "class-variance-authority";
10226
10473
  import { jsx as jsx60 } from "react/jsx-runtime";
10227
- var checkboxGroupVariants = cva23("gap-[var(--space-2)]", {
10474
+ var checkboxGroupVariants = cva24("gap-[var(--space-2)]", {
10228
10475
  variants: {
10229
10476
  appearance: {
10230
10477
  plain: "flex",
@@ -10324,11 +10571,11 @@ CheckboxGroup.displayName = "CheckboxGroup";
10324
10571
 
10325
10572
  // src/components/ui/radio-group.tsx
10326
10573
  import * as React49 from "react";
10327
- import { cva as cva24 } from "class-variance-authority";
10574
+ import { cva as cva25 } from "class-variance-authority";
10328
10575
  import { Circle } from "lucide-react";
10329
10576
  import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
10330
10577
  import { jsx as jsx61, jsxs as jsxs48 } from "react/jsx-runtime";
10331
- var radioGroupVariants = cva24("gap-[var(--space-2)]", {
10578
+ var radioGroupVariants = cva25("gap-[var(--space-2)]", {
10332
10579
  variants: {
10333
10580
  appearance: {
10334
10581
  plain: "flex",
@@ -10353,7 +10600,7 @@ var radioGroupVariants = cva24("gap-[var(--space-2)]", {
10353
10600
  columns: "one"
10354
10601
  }
10355
10602
  });
10356
- var radioVariants = cva24(
10603
+ var radioVariants = cva25(
10357
10604
  [
10358
10605
  "group w-full cursor-pointer text-left transition-colors motion-reduce:transition-none",
10359
10606
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]",
@@ -10395,7 +10642,7 @@ var radioVariants = cva24(
10395
10642
  }
10396
10643
  }
10397
10644
  );
10398
- var radioControlVariants = cva24(
10645
+ var radioControlVariants = cva25(
10399
10646
  [
10400
10647
  "flex size-[calc(var(--space-4)+var(--space-1))] shrink-0 items-center justify-center",
10401
10648
  "rounded-[var(--radius-full)] border border-[var(--border-strong)] bg-[var(--bg-surface)] text-transparent",
@@ -10629,13 +10876,13 @@ function Progress({
10629
10876
 
10630
10877
  // src/components/ui/tree-view.tsx
10631
10878
  import * as React50 from "react";
10632
- import { ChevronRight as ChevronRight4 } from "lucide-react";
10633
- import { cva as cva25 } from "class-variance-authority";
10879
+ import { ChevronRight as ChevronRight5 } from "lucide-react";
10880
+ import { cva as cva26 } from "class-variance-authority";
10634
10881
  import { jsx as jsx64, jsxs as jsxs50 } from "react/jsx-runtime";
10635
- var treeViewVariants = cva25(
10882
+ var treeViewVariants = cva26(
10636
10883
  "m-0 list-none p-[var(--space-1)] text-body-sm text-foreground"
10637
10884
  );
10638
- var treeItemRowVariants = cva25(
10885
+ var treeItemRowVariants = cva26(
10639
10886
  [
10640
10887
  "flex min-h-[32px] w-full cursor-pointer select-none items-center gap-[var(--space-2)]",
10641
10888
  "rounded-[var(--radius-sm)] py-[var(--space-2)] pr-[var(--space-3)]",
@@ -10846,7 +11093,7 @@ function TreeView({
10846
11093
  },
10847
11094
  className: "flex size-[var(--space-4)] shrink-0 items-center justify-center text-text-tertiary",
10848
11095
  children: /* @__PURE__ */ jsx64(
10849
- ChevronRight4,
11096
+ ChevronRight5,
10850
11097
  {
10851
11098
  "aria-hidden": "true",
10852
11099
  "data-slot": "treeitem-chevron",
@@ -10894,7 +11141,7 @@ function TreeView({
10894
11141
 
10895
11142
  // src/components/branding/olun-logo.tsx
10896
11143
  import { OLUN_MASTER, OLUN_SYMBOL, OLUN_WORDMARK } from "@olundot/tokens/brand";
10897
- import { Fragment as Fragment15, jsx as jsx65, jsxs as jsxs51 } from "react/jsx-runtime";
11144
+ import { Fragment as Fragment17, jsx as jsx65, jsxs as jsxs51 } from "react/jsx-runtime";
10898
11145
  var ACCENT_FILL = "var(--accent-pop)";
10899
11146
  var INK = { color: "var(--text-primary)" };
10900
11147
  var INK_TIGHT = { ...INK, display: "block", overflow: "visible" };
@@ -10904,7 +11151,7 @@ function symbolGeometry(size) {
10904
11151
  function SymbolCircles({ size }) {
10905
11152
  const { ring } = OLUN_SYMBOL;
10906
11153
  const g = symbolGeometry(size);
10907
- return /* @__PURE__ */ jsxs51(Fragment15, { children: [
11154
+ return /* @__PURE__ */ jsxs51(Fragment17, { children: [
10908
11155
  /* @__PURE__ */ jsx65(
10909
11156
  "circle",
10910
11157
  {