@bug-on/m3-expressive 1.3.1 → 1.3.3

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +113 -60
  3. package/dist/buttons.d.mts +3 -3
  4. package/dist/buttons.d.ts +3 -3
  5. package/dist/{core-CAU8g2HY.d.mts → core-D8FdHY6I.d.mts} +1 -1
  6. package/dist/{core-DRrLnsnJ.d.ts → core-DyEy8H9Z.d.ts} +1 -1
  7. package/dist/core.d.mts +2 -2
  8. package/dist/core.d.ts +2 -2
  9. package/dist/core.js +9 -7
  10. package/dist/core.js.map +1 -1
  11. package/dist/core.mjs +9 -7
  12. package/dist/core.mjs.map +1 -1
  13. package/dist/feedback.d.mts +2 -1
  14. package/dist/feedback.d.ts +2 -1
  15. package/dist/feedback.js +11 -8
  16. package/dist/feedback.js.map +1 -1
  17. package/dist/feedback.mjs +11 -9
  18. package/dist/feedback.mjs.map +1 -1
  19. package/dist/forms.d.mts +4 -3
  20. package/dist/forms.d.ts +4 -3
  21. package/dist/forms.js +5084 -2987
  22. package/dist/forms.js.map +1 -1
  23. package/dist/forms.mjs +5083 -2989
  24. package/dist/forms.mjs.map +1 -1
  25. package/dist/{icon-button-USJo7AqO.d.mts → icon-button-CxyJv7UV.d.mts} +1 -1
  26. package/dist/{icon-button-CqdQBsRe.d.ts → icon-button-Di8VX6ou.d.ts} +1 -1
  27. package/dist/index.d.mts +13 -83
  28. package/dist/index.d.ts +13 -83
  29. package/dist/index.js +2843 -1210
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +2692 -1072
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/layout.d.mts +496 -37
  34. package/dist/layout.d.ts +496 -37
  35. package/dist/layout.js +1537 -238
  36. package/dist/layout.js.map +1 -1
  37. package/dist/layout.mjs +1509 -226
  38. package/dist/layout.mjs.map +1 -1
  39. package/dist/{md3-D0_Z7IXj.d.mts → md3-BQhRygSi.d.mts} +1 -1
  40. package/dist/{md3-D0_Z7IXj.d.ts → md3-BQhRygSi.d.ts} +1 -1
  41. package/dist/menu-types-rZNQFO7Y.d.mts +315 -0
  42. package/dist/menu-types-rZNQFO7Y.d.ts +315 -0
  43. package/dist/navigation.d.mts +28 -296
  44. package/dist/navigation.d.ts +28 -296
  45. package/dist/navigation.js +584 -288
  46. package/dist/navigation.js.map +1 -1
  47. package/dist/navigation.mjs +576 -282
  48. package/dist/navigation.mjs.map +1 -1
  49. package/dist/overlays.d.mts +2 -2
  50. package/dist/overlays.d.ts +2 -2
  51. package/dist/{side-sheet-modal-Dgjt739k.d.mts → side-sheet-modal-64FGhDxL.d.mts} +1 -1
  52. package/dist/{side-sheet-modal-DdEZR6Vl.d.ts → side-sheet-modal-Bd5Qqvp9.d.ts} +1 -1
  53. package/dist/{split-button-trailing-uncheckable-DTQJjzsB.d.ts → split-button-trailing-uncheckable-CGzk7KcG.d.ts} +1 -1
  54. package/dist/{split-button-trailing-uncheckable-CIVEYgjY.d.mts → split-button-trailing-uncheckable-gAz6OAIi.d.mts} +1 -1
  55. package/dist/{text-field-Ear3hCSq.d.mts → text-field-4OlT9o8s.d.mts} +155 -5
  56. package/dist/{text-field-CiOmDM_8.d.ts → text-field-DARNdj14.d.ts} +155 -5
  57. package/llms-full.txt +255 -0
  58. package/llms.txt +102 -0
  59. package/package.json +10 -5
package/dist/layout.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import { Slot } from '@radix-ui/react-slot';
3
3
  import { cva } from 'class-variance-authority';
4
4
  import { m, LazyMotion, domMax, useMotionValue, animate, useAnimationFrame, AnimatePresence, useReducedMotion } from 'motion/react';
5
- import * as React18 from 'react';
5
+ import * as React23 from 'react';
6
6
  import { createContext, useState, useCallback, useMemo, useEffect, useContext, createElement } from 'react';
7
7
  import { clsx } from 'clsx';
8
8
  import { twMerge } from 'tailwind-merge';
@@ -55,7 +55,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
55
55
  function cn(...inputs) {
56
56
  return twMerge(clsx(inputs));
57
57
  }
58
- var RippleItem = React18.memo(function RippleItem2({
58
+ var RippleItem = React23.memo(function RippleItem2({
59
59
  ripple,
60
60
  onDone
61
61
  }) {
@@ -99,8 +99,8 @@ function Ripple({
99
99
  }
100
100
  function useRippleState(options = {}) {
101
101
  const { disabled = false } = options;
102
- const [ripples, setRipples] = React18.useState([]);
103
- const onPointerDown = React18.useCallback(
102
+ const [ripples, setRipples] = React23.useState([]);
103
+ const onPointerDown = React23.useCallback(
104
104
  (e) => {
105
105
  if (disabled) return;
106
106
  const rect = e.currentTarget.getBoundingClientRect();
@@ -117,21 +117,36 @@ function useRippleState(options = {}) {
117
117
  },
118
118
  [disabled]
119
119
  );
120
- const removeRipple = React18.useCallback((id) => {
120
+ const removeRipple = React23.useCallback((id) => {
121
121
  setRipples((prev) => prev.filter((r) => r.id !== id));
122
122
  }, []);
123
123
  return { ripples, onPointerDown, removeRipple };
124
124
  }
125
+
126
+ // src/ui/cards/card/card-tokens.ts
125
127
  var SHADOW = {
126
128
  level0: "none",
127
129
  level1: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 1px 3px 1px rgba(0,0,0,.15)",
128
- level2: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 2px 6px 2px rgba(0,0,0,.15)"
130
+ level2: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 2px 6px 2px rgba(0,0,0,.15)",
131
+ level3: "0px 4px 8px 3px rgba(0,0,0,.15), 0px 1px 3px 0px rgba(0,0,0,.3)",
132
+ level4: "0px 6px 10px 4px rgba(0,0,0,.15), 0px 2px 3px 0px rgba(0,0,0,.3)",
133
+ level5: "0px 8px 12px 6px rgba(0,0,0,.15), 0px 4px 4px 0px rgba(0,0,0,.3)"
129
134
  };
135
+ function resolveElevationShadow(level) {
136
+ var _a;
137
+ if (level === void 0) return void 0;
138
+ if (typeof level === "number") {
139
+ const key = `level${level}`;
140
+ return (_a = SHADOW[key]) != null ? _a : SHADOW.level0;
141
+ }
142
+ return level;
143
+ }
130
144
  var VARIANT_ELEVATION = {
131
145
  elevated: {
132
146
  rest: SHADOW.level1,
133
147
  hover: SHADOW.level2,
134
148
  pressed: SHADOW.level1,
149
+ dragged: SHADOW.level3,
135
150
  disabled: SHADOW.level1
136
151
  // ElevatedCardTokens.DisabledContainerElevation = Level1
137
152
  },
@@ -139,78 +154,177 @@ var VARIANT_ELEVATION = {
139
154
  rest: SHADOW.level0,
140
155
  hover: SHADOW.level1,
141
156
  pressed: SHADOW.level0,
157
+ dragged: SHADOW.level3,
142
158
  disabled: SHADOW.level0
143
159
  },
144
160
  outlined: {
145
161
  rest: SHADOW.level0,
146
162
  hover: SHADOW.level1,
147
163
  pressed: SHADOW.level0,
164
+ dragged: SHADOW.level3,
148
165
  disabled: SHADOW.level0
149
166
  }
150
167
  };
168
+ function useCardElevation({
169
+ variant = "elevated",
170
+ disabled = false,
171
+ draggable = false,
172
+ elevation,
173
+ disableElevation = false,
174
+ hoverEffect = true
175
+ }) {
176
+ var _a, _b, _c, _d, _e, _f, _g;
177
+ const defaultLevels = VARIANT_ELEVATION[variant] || VARIANT_ELEVATION.elevated;
178
+ let restShadow = defaultLevels.rest;
179
+ let hoverShadow = defaultLevels.hover;
180
+ let pressedShadow = defaultLevels.pressed;
181
+ let draggedShadow = defaultLevels.dragged;
182
+ if (disableElevation) {
183
+ restShadow = SHADOW.level0;
184
+ hoverShadow = SHADOW.level0;
185
+ pressedShadow = SHADOW.level0;
186
+ draggedShadow = SHADOW.level0;
187
+ } else if (typeof elevation === "number") {
188
+ const resolved = (_a = resolveElevationShadow(elevation)) != null ? _a : SHADOW.level0;
189
+ restShadow = resolved;
190
+ const hoverLevel = hoverEffect ? Math.min(elevation + 1, 5) : elevation;
191
+ hoverShadow = (_b = resolveElevationShadow(hoverLevel)) != null ? _b : resolved;
192
+ pressedShadow = resolved;
193
+ draggedShadow = (_c = resolveElevationShadow(
194
+ Math.min(elevation + 2, 5)
195
+ )) != null ? _c : resolved;
196
+ } else if (elevation && typeof elevation === "object") {
197
+ if (elevation.rest !== void 0) {
198
+ restShadow = (_d = resolveElevationShadow(elevation.rest)) != null ? _d : restShadow;
199
+ }
200
+ if (elevation.hover !== void 0) {
201
+ hoverShadow = (_e = resolveElevationShadow(elevation.hover)) != null ? _e : hoverShadow;
202
+ }
203
+ if (elevation.pressed !== void 0) {
204
+ pressedShadow = (_f = resolveElevationShadow(elevation.pressed)) != null ? _f : pressedShadow;
205
+ }
206
+ if (elevation.dragged !== void 0) {
207
+ draggedShadow = (_g = resolveElevationShadow(elevation.dragged)) != null ? _g : draggedShadow;
208
+ }
209
+ }
210
+ if (!hoverEffect) {
211
+ hoverShadow = restShadow;
212
+ }
213
+ const animateShadow = disabled ? disableElevation ? SHADOW.level0 : defaultLevels.disabled : restShadow;
214
+ return {
215
+ animate: { boxShadow: animateShadow },
216
+ whileHover: disabled || !hoverEffect ? void 0 : { boxShadow: hoverShadow },
217
+ whileTap: disabled ? void 0 : { boxShadow: pressedShadow },
218
+ whileFocus: disabled || !hoverEffect ? void 0 : { boxShadow: hoverShadow },
219
+ whileDrag: !disabled && draggable ? { boxShadow: draggedShadow } : void 0,
220
+ transition: {
221
+ boxShadow: {
222
+ // Incoming: 120ms (from Elevation.kt DefaultIncomingSpec)
223
+ duration: 0.12,
224
+ ease: [0.4, 0, 0.2, 1]
225
+ }
226
+ }
227
+ };
228
+ }
151
229
  var cardVariants = cva(
152
- "rounded-m3-lg flex flex-col relative overflow-hidden transition-colors duration-200",
230
+ "rounded-m3-lg flex flex-col relative overflow-hidden transition-all duration-200",
153
231
  {
154
232
  variants: {
155
233
  variant: {
156
234
  // ElevatedCardTokens.ContainerColor = SurfaceContainerLow
157
- elevated: "bg-m3-surface-container-low",
235
+ elevated: "bg-m3-surface-container-low text-m3-on-surface",
158
236
  // FilledCardTokens.ContainerColor = SurfaceContainerHighest
159
- filled: "bg-m3-surface-container-highest",
237
+ filled: "bg-m3-surface-container-highest text-m3-on-surface",
160
238
  // OutlinedCardTokens.ContainerColor = Surface, OutlineColor = OutlineVariant
161
- outlined: "bg-m3-surface border border-m3-outline-variant"
239
+ outlined: "bg-m3-surface text-m3-on-surface border border-m3-outline-variant"
162
240
  }
163
241
  },
164
242
  defaultVariants: { variant: "elevated" }
165
243
  }
166
244
  );
167
- function useCardElevation(variant, disabled) {
168
- const levels = VARIANT_ELEVATION[variant];
169
- return {
170
- animate: { boxShadow: disabled ? levels.disabled : levels.rest },
171
- whileHover: disabled ? void 0 : { boxShadow: levels.hover },
172
- whileTap: disabled ? void 0 : { boxShadow: levels.pressed },
173
- whileFocus: disabled ? void 0 : { boxShadow: levels.hover },
174
- transition: {
175
- boxShadow: {
176
- // Incoming: 120ms (from Elevation.kt DefaultIncomingSpec)
177
- duration: 0.12,
178
- ease: [0.4, 0, 0.2, 1]
179
- }
180
- }
181
- };
182
- }
183
- var CardImpl = React18.forwardRef(
245
+ var CardImpl = React23.forwardRef(
184
246
  (_a, ref) => {
185
247
  var _b = _a, {
186
248
  className,
187
249
  variant = "elevated",
250
+ elevation,
251
+ disableElevation = false,
252
+ ripple = true,
253
+ disableRipple = false,
254
+ hoverEffect = true,
255
+ disableHoverEffect = false,
256
+ stateLayer = true,
257
+ disableStateLayer = false,
188
258
  disabled = false,
189
259
  interactive = false,
260
+ draggable = false,
190
261
  href,
191
262
  target,
192
263
  rel: relProp,
193
264
  onClick,
265
+ onPointerDown: userOnPointerDown,
266
+ whileHover,
267
+ whileTap,
268
+ whileFocus,
269
+ whileDrag,
270
+ transition,
194
271
  asChild = false,
195
272
  children
196
273
  } = _b, props = __objRest(_b, [
197
274
  "className",
198
275
  "variant",
276
+ "elevation",
277
+ "disableElevation",
278
+ "ripple",
279
+ "disableRipple",
280
+ "hoverEffect",
281
+ "disableHoverEffect",
282
+ "stateLayer",
283
+ "disableStateLayer",
199
284
  "disabled",
200
285
  "interactive",
286
+ "draggable",
201
287
  "href",
202
288
  "target",
203
289
  "rel",
204
290
  "onClick",
291
+ "onPointerDown",
292
+ "whileHover",
293
+ "whileTap",
294
+ "whileFocus",
295
+ "whileDrag",
296
+ "transition",
205
297
  "asChild",
206
298
  "children"
207
299
  ]);
208
- const safeVariant = variant;
300
+ const safeVariant = variant || "elevated";
209
301
  const isInteractive = !!onClick || !!href || interactive || asChild;
210
- const elevationProps = useCardElevation(safeVariant, disabled);
211
- const { ripples, onPointerDown, removeRipple } = useRippleState();
302
+ const isHoverEnabled = hoverEffect !== false && !disableHoverEffect;
303
+ const isRippleEnabled = ripple !== false && !disableRipple && isInteractive && !disabled;
304
+ const isStateLayerEnabled = stateLayer !== false && !disableStateLayer && isInteractive && !disabled;
305
+ const elevationProps = useCardElevation({
306
+ variant: safeVariant,
307
+ disabled,
308
+ draggable,
309
+ elevation,
310
+ disableElevation,
311
+ hoverEffect: isHoverEnabled
312
+ });
313
+ const {
314
+ ripples,
315
+ onPointerDown: rippleOnPointerDown,
316
+ removeRipple
317
+ } = useRippleState();
318
+ const handlePointerDown = (event) => {
319
+ if (isRippleEnabled) {
320
+ rippleOnPointerDown(event);
321
+ }
322
+ userOnPointerDown == null ? void 0 : userOnPointerDown(
323
+ event
324
+ );
325
+ };
212
326
  const baseClass = cn(
213
- cardVariants({ variant }),
327
+ cardVariants({ variant: safeVariant }),
214
328
  // Disabled state:
215
329
  // - pointer-events-none → disable interactions completely
216
330
  // - opacity-[0.38] → MD3 DisabledContainerOpacity
@@ -220,17 +334,25 @@ var CardImpl = React18.forwardRef(
220
334
  const interactiveClass = cn(
221
335
  // Remove default outline, use MD3 state overlay & elevation for focus
222
336
  "focus-visible:outline-none focus:outline-none group",
223
- // Base pseudo-element overlay layer
224
- "before:absolute before:inset-0 before:pointer-events-none before:bg-m3-on-surface before:opacity-0 before:transition-opacity before:duration-200",
225
- // Interactive state opacities
226
- "hover:before:opacity-[0.08] focus-visible:before:opacity-[0.10] active:before:opacity-[0.10]",
227
- // Outlined interactive card: change border color to m3-outline on focus/press/hover
228
- variant === "outlined" && "hover:border-m3-outline focus-visible:border-m3-outline active:border-m3-outline"
337
+ // Base pseudo-element overlay layer (when stateLayer is enabled)
338
+ isStateLayerEnabled && [
339
+ "before:absolute before:inset-0 before:pointer-events-none before:bg-m3-on-surface before:opacity-0 before:transition-opacity before:duration-200",
340
+ isHoverEnabled && "hover:before:opacity-[0.08]",
341
+ "focus-visible:before:opacity-[0.10] active:before:opacity-[0.10]",
342
+ draggable && "active:before:opacity-[0.16]"
343
+ ],
344
+ // Outlined interactive card: smooth transition of border color to m3-outline on hover/focus/press
345
+ safeVariant === "outlined" && "transition-colors duration-200 hover:border-m3-outline focus-visible:border-m3-outline active:border-m3-outline"
229
346
  );
347
+ const mergedWhileHover = elevationProps.whileHover || whileHover ? __spreadValues(__spreadValues({}, elevationProps.whileHover), typeof whileHover === "object" ? whileHover : {}) : void 0;
348
+ const mergedWhileTap = elevationProps.whileTap || whileTap ? __spreadValues(__spreadValues({}, elevationProps.whileTap), typeof whileTap === "object" ? whileTap : {}) : void 0;
349
+ const mergedWhileFocus = elevationProps.whileFocus || whileFocus ? __spreadValues(__spreadValues({}, elevationProps.whileFocus), typeof whileFocus === "object" ? whileFocus : {}) : void 0;
350
+ const mergedWhileDrag = elevationProps.whileDrag || whileDrag ? __spreadValues(__spreadValues({}, elevationProps.whileDrag), typeof whileDrag === "object" ? whileDrag : {}) : void 0;
351
+ const mergedTransition = elevationProps.transition || transition ? __spreadValues(__spreadValues({}, elevationProps.transition), typeof transition === "object" ? transition : {}) : void 0;
230
352
  if (asChild) {
231
- const child = React18.Children.only(children);
353
+ const child = React23.Children.only(children);
232
354
  const innerContent = /* @__PURE__ */ jsxs(Fragment, { children: [
233
- /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
355
+ isRippleEnabled && /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
234
356
  child.props.children
235
357
  ] });
236
358
  return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(
@@ -240,22 +362,26 @@ var CardImpl = React18.forwardRef(
240
362
  className: cn(baseClass, interactiveClass),
241
363
  "aria-disabled": disabled ? true : void 0,
242
364
  tabIndex: disabled ? -1 : 0,
243
- onPointerDown,
365
+ onPointerDown: handlePointerDown,
244
366
  onClick
245
367
  }, props), {
246
- children: React18.cloneElement(child, { children: innerContent })
368
+ children: React23.cloneElement(child, { children: innerContent })
247
369
  })
248
370
  ) });
249
371
  }
250
372
  if (!isInteractive) {
251
373
  return /* @__PURE__ */ jsx(
252
374
  "div",
253
- {
375
+ __spreadProps(__spreadValues({
254
376
  ref,
255
377
  className: baseClass,
256
- "aria-disabled": disabled ? true : void 0,
378
+ style: __spreadValues({
379
+ boxShadow: elevationProps.animate.boxShadow
380
+ }, props.style || {}),
381
+ "aria-disabled": disabled ? true : void 0
382
+ }, props), {
257
383
  children
258
- }
384
+ })
259
385
  );
260
386
  }
261
387
  const safeRel = href ? relProp != null ? relProp : target === "_blank" ? "noreferrer" : void 0 : void 0;
@@ -270,10 +396,16 @@ var CardImpl = React18.forwardRef(
270
396
  className: cn(baseClass, interactiveClass),
271
397
  "aria-disabled": disabled ? true : void 0,
272
398
  tabIndex: disabled ? -1 : 0,
273
- onPointerDown
274
- }, elevationProps), {
399
+ onPointerDown: handlePointerDown,
400
+ animate: elevationProps.animate,
401
+ whileHover: mergedWhileHover,
402
+ whileTap: mergedWhileTap,
403
+ whileFocus: mergedWhileFocus,
404
+ whileDrag: mergedWhileDrag,
405
+ transition: mergedTransition
406
+ }, props), {
275
407
  children: [
276
- /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
408
+ isRippleEnabled && /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
277
409
  children
278
410
  ]
279
411
  })
@@ -281,7 +413,7 @@ var CardImpl = React18.forwardRef(
281
413
  }
282
414
  return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsxs(
283
415
  m.button,
284
- __spreadProps(__spreadValues(__spreadValues({
416
+ __spreadProps(__spreadValues({
285
417
  ref,
286
418
  type: "button",
287
419
  disabled,
@@ -289,10 +421,16 @@ var CardImpl = React18.forwardRef(
289
421
  className: cn(baseClass, interactiveClass),
290
422
  "aria-disabled": disabled ? true : void 0,
291
423
  tabIndex: disabled ? -1 : 0,
292
- onPointerDown
293
- }, elevationProps), props), {
424
+ onPointerDown: handlePointerDown,
425
+ animate: elevationProps.animate,
426
+ whileHover: mergedWhileHover,
427
+ whileTap: mergedWhileTap,
428
+ whileFocus: mergedWhileFocus,
429
+ whileDrag: mergedWhileDrag,
430
+ transition: mergedTransition
431
+ }, props), {
294
432
  children: [
295
- /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
433
+ isRippleEnabled && /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
296
434
  children
297
435
  ]
298
436
  })
@@ -300,7 +438,1132 @@ var CardImpl = React18.forwardRef(
300
438
  }
301
439
  );
302
440
  CardImpl.displayName = "Card";
303
- var Card = React18.memo(CardImpl);
441
+ var Card = React23.memo(CardImpl);
442
+ var CardHeader = React23.forwardRef(
443
+ (_a, ref) => {
444
+ var _b = _a, { className, avatar, title, subheader, action, children } = _b, props = __objRest(_b, ["className", "avatar", "title", "subheader", "action", "children"]);
445
+ return /* @__PURE__ */ jsxs(
446
+ "div",
447
+ __spreadProps(__spreadValues({
448
+ ref,
449
+ className: cn(
450
+ "flex items-center gap-4 px-6 pt-6 pb-2 relative z-1",
451
+ className
452
+ )
453
+ }, props), {
454
+ children: [
455
+ avatar && /* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center", children: avatar }),
456
+ title || subheader ? /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
457
+ title && /* @__PURE__ */ jsx("div", { className: "text-base font-medium text-m3-on-surface truncate", children: title }),
458
+ subheader && /* @__PURE__ */ jsx("div", { className: "text-sm text-m3-on-surface-variant truncate", children: subheader })
459
+ ] }) : null,
460
+ children,
461
+ action && /* @__PURE__ */ jsx("div", { className: "shrink-0 ml-auto flex items-center", children: action })
462
+ ]
463
+ })
464
+ );
465
+ }
466
+ );
467
+ CardHeader.displayName = "CardHeader";
468
+ var ASPECT_RATIO_CLASSES = {
469
+ video: "aspect-video",
470
+ square: "aspect-square",
471
+ wide: "aspect-[21/9]",
472
+ auto: ""
473
+ };
474
+ var CardMedia = React23.forwardRef(
475
+ (_a, ref) => {
476
+ var _b = _a, {
477
+ className,
478
+ src,
479
+ alt = "",
480
+ aspectRatio = "video",
481
+ component,
482
+ children
483
+ } = _b, props = __objRest(_b, [
484
+ "className",
485
+ "src",
486
+ "alt",
487
+ "aspectRatio",
488
+ "component",
489
+ "children"
490
+ ]);
491
+ const ratioClass = aspectRatio in ASPECT_RATIO_CLASSES ? ASPECT_RATIO_CLASSES[aspectRatio] : "";
492
+ const Component = component || (src && !children ? "img" : "div");
493
+ return /* @__PURE__ */ jsx(
494
+ "div",
495
+ __spreadProps(__spreadValues({
496
+ ref,
497
+ className: cn(
498
+ "relative w-full overflow-hidden shrink-0",
499
+ ratioClass,
500
+ className
501
+ )
502
+ }, props), {
503
+ children: children ? children : src ? /* @__PURE__ */ jsx(
504
+ Component,
505
+ {
506
+ src,
507
+ alt,
508
+ className: "w-full h-full object-cover"
509
+ }
510
+ ) : null
511
+ })
512
+ );
513
+ }
514
+ );
515
+ CardMedia.displayName = "CardMedia";
516
+ var CardContent = React23.forwardRef(
517
+ (_a, ref) => {
518
+ var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
519
+ return /* @__PURE__ */ jsx(
520
+ "div",
521
+ __spreadProps(__spreadValues({
522
+ ref,
523
+ className: cn(
524
+ "px-6 py-4 text-sm text-m3-on-surface-variant flex-1 relative z-1",
525
+ className
526
+ )
527
+ }, props), {
528
+ children
529
+ })
530
+ );
531
+ }
532
+ );
533
+ CardContent.displayName = "CardContent";
534
+ var ALIGN_CLASSES = {
535
+ start: "justify-start",
536
+ center: "justify-center",
537
+ end: "justify-end",
538
+ between: "justify-between"
539
+ };
540
+ var CardFooter = React23.forwardRef(
541
+ (_a, ref) => {
542
+ var _b = _a, { className, align = "end", children } = _b, props = __objRest(_b, ["className", "align", "children"]);
543
+ return /* @__PURE__ */ jsx(
544
+ "div",
545
+ __spreadProps(__spreadValues({
546
+ ref,
547
+ className: cn(
548
+ "flex items-center gap-2 px-6 pb-6 pt-2 relative z-1",
549
+ ALIGN_CLASSES[align],
550
+ className
551
+ )
552
+ }, props), {
553
+ children
554
+ })
555
+ );
556
+ }
557
+ );
558
+ CardFooter.displayName = "CardFooter";
559
+ function CarouselGrid(_a) {
560
+ var _b = _a, {
561
+ children,
562
+ items,
563
+ renderItem,
564
+ preferredItemWidth = 240,
565
+ className,
566
+ style
567
+ } = _b, props = __objRest(_b, [
568
+ "children",
569
+ "items",
570
+ "renderItem",
571
+ "preferredItemWidth",
572
+ "className",
573
+ "style"
574
+ ]);
575
+ const gridStyle = __spreadValues({
576
+ display: "grid",
577
+ gridTemplateColumns: `repeat(auto-fill, minmax(${preferredItemWidth}px, 1fr))`,
578
+ gap: "8px",
579
+ padding: "8px 16px",
580
+ width: "100%",
581
+ boxSizing: "border-box"
582
+ }, style);
583
+ const itemStyle = {
584
+ position: "relative",
585
+ width: "100%",
586
+ minHeight: "180px",
587
+ borderRadius: "28px",
588
+ overflow: "hidden"
589
+ };
590
+ if (items && renderItem) {
591
+ return /* @__PURE__ */ jsx(
592
+ "section",
593
+ __spreadProps(__spreadValues({
594
+ className,
595
+ style: gridStyle,
596
+ "aria-label": "Expanded carousel grid"
597
+ }, props), {
598
+ children: items.map((item, index) => {
599
+ const itemKey = typeof item === "object" && item !== null && "id" in item ? item.id : typeof item === "object" && item !== null && "key" in item ? item.key : index;
600
+ return /* @__PURE__ */ jsx("div", { style: itemStyle, children: renderItem(item, index) }, itemKey);
601
+ })
602
+ })
603
+ );
604
+ }
605
+ return /* @__PURE__ */ jsx(
606
+ "section",
607
+ __spreadProps(__spreadValues({
608
+ className,
609
+ style: gridStyle,
610
+ "aria-label": "Expanded carousel grid"
611
+ }, props), {
612
+ children: React23.Children.map(children, (child, index) => {
613
+ const childKey = React23.isValidElement(child) && child.key != null ? child.key : index;
614
+ return /* @__PURE__ */ jsx("div", { style: itemStyle, children: child }, childKey);
615
+ })
616
+ })
617
+ );
618
+ }
619
+ var CarouselItem = React23.forwardRef(
620
+ function CarouselItem2(_a, ref) {
621
+ var _b = _a, {
622
+ index,
623
+ totalItems,
624
+ layout = "multi-browse",
625
+ width,
626
+ minContentWidth,
627
+ maskClipPercent = 0,
628
+ parallaxOffset = 0,
629
+ isFocused = false,
630
+ isScrolling = false,
631
+ disabled = false,
632
+ className,
633
+ style,
634
+ children,
635
+ onClick,
636
+ onPointerDown
637
+ } = _b, props = __objRest(_b, [
638
+ "index",
639
+ "totalItems",
640
+ "layout",
641
+ "width",
642
+ "minContentWidth",
643
+ "maskClipPercent",
644
+ "parallaxOffset",
645
+ "isFocused",
646
+ "isScrolling",
647
+ "disabled",
648
+ "className",
649
+ "style",
650
+ "children",
651
+ "onClick",
652
+ "onPointerDown"
653
+ ]);
654
+ const {
655
+ ripples,
656
+ onPointerDown: handleRipplePointerDown,
657
+ removeRipple
658
+ } = useRippleState();
659
+ const itemNumber = index + 1;
660
+ const ariaLabel = props["aria-label"] || `Item ${itemNumber} of ${totalItems}`;
661
+ const isFullScreen = layout === "full-screen";
662
+ const isCenterHero = layout === "center-aligned-hero";
663
+ const combinedStyle = __spreadValues({
664
+ width: isFullScreen ? "100%" : width ? `${width}px` : void 0,
665
+ height: isFullScreen ? "100%" : void 0,
666
+ flexShrink: 0
667
+ }, style);
668
+ const handlePointerDown = (e) => {
669
+ if (!disabled) {
670
+ handleRipplePointerDown(e);
671
+ }
672
+ onPointerDown == null ? void 0 : onPointerDown(e);
673
+ };
674
+ const handleKeyDown = (e) => {
675
+ var _a2;
676
+ if (!disabled && (e.key === "Enter" || e.key === " ")) {
677
+ e.preventDefault();
678
+ onClick == null ? void 0 : onClick(e);
679
+ }
680
+ (_a2 = props.onKeyDown) == null ? void 0 : _a2.call(props, e);
681
+ };
682
+ return (
683
+ // biome-ignore lint/a11y/useSemanticElements: ARIA carousel pattern requires role="group" for slide items
684
+ /* @__PURE__ */ jsxs(
685
+ "div",
686
+ __spreadProps(__spreadValues({
687
+ ref,
688
+ role: "group",
689
+ "aria-roledescription": "slide",
690
+ "aria-label": ariaLabel,
691
+ tabIndex: disabled ? -1 : isFocused ? 0 : -1,
692
+ className: cn(
693
+ // Base item styles: overflow-hidden + rounded 28px acts as MD3 keyline mask
694
+ "relative flex flex-col overflow-hidden rounded-[28px] cursor-pointer select-none box-border outline-none shrink-0",
695
+ // GPU Composition & Layout Containment
696
+ "will-change-[transform,clip-path] contain-[layout_paint_style] [user-select:none] [-webkit-user-drag:none] [&_img]:pointer-events-none [&_img]:select-none [&_img]:[-webkit-user-drag:none]",
697
+ // Scroll snap: center-aligned hero snaps to center, all others snap start
698
+ isCenterHero ? "snap-center" : "snap-start",
699
+ // Full-screen: no rounding, fill height
700
+ isFullScreen && "rounded-none",
701
+ // State layers via ::after pseudo-element
702
+ "after:absolute after:inset-0 after:rounded-[inherit] after:bg-black after:opacity-0 after:pointer-events-none after:z-2 after:transition-opacity after:duration-150 after:motion-reduce:transition-none",
703
+ "hover:after:opacity-[0.08]",
704
+ "active:after:opacity-[0.10]",
705
+ // Focus ring
706
+ "focus-visible:outline-[3px] focus-visible:outline-(--md-sys-color-secondary,#625b71) focus-visible:outline-offset-2 focus-visible:z-3",
707
+ // Disabled
708
+ disabled && "opacity-[0.38] pointer-events-none",
709
+ className
710
+ ),
711
+ style: combinedStyle,
712
+ onPointerDown: handlePointerDown,
713
+ onKeyDown: handleKeyDown,
714
+ onClick: disabled ? void 0 : onClick
715
+ }, props), {
716
+ children: [
717
+ /* @__PURE__ */ jsx(
718
+ "div",
719
+ {
720
+ className: "w-full flex-1 flex flex-col will-change-transform select-none",
721
+ style: {
722
+ width: isFullScreen ? "100%" : minContentWidth ? `${minContentWidth}px` : "100%",
723
+ minWidth: isFullScreen ? "100%" : minContentWidth ? `${minContentWidth}px` : void 0,
724
+ transform: parallaxOffset !== 0 ? `translateX(${parallaxOffset}px)` : void 0
725
+ },
726
+ children
727
+ }
728
+ ),
729
+ /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple })
730
+ ]
731
+ })
732
+ )
733
+ );
734
+ }
735
+ );
736
+ CarouselItem.displayName = "CarouselItem";
737
+ function useCarouselA11y({
738
+ totalItems,
739
+ onItemSelect,
740
+ onExitNavigation,
741
+ scrollToIndex
742
+ }) {
743
+ const [focusedIndex, setFocusedIndex] = useState(0);
744
+ const handleKeyDown = useCallback(
745
+ (event) => {
746
+ if (totalItems === 0) return;
747
+ switch (event.key) {
748
+ case "ArrowRight":
749
+ case "ArrowDown": {
750
+ if (event.key === "ArrowDown" && onExitNavigation) {
751
+ onExitNavigation();
752
+ return;
753
+ }
754
+ event.preventDefault();
755
+ setFocusedIndex((prev) => {
756
+ const next = Math.min(totalItems - 1, prev + 1);
757
+ scrollToIndex == null ? void 0 : scrollToIndex(next);
758
+ return next;
759
+ });
760
+ break;
761
+ }
762
+ case "ArrowLeft":
763
+ case "ArrowUp": {
764
+ if (event.key === "ArrowUp" && onExitNavigation) {
765
+ onExitNavigation();
766
+ return;
767
+ }
768
+ event.preventDefault();
769
+ setFocusedIndex((prev) => {
770
+ const next = Math.max(0, prev - 1);
771
+ scrollToIndex == null ? void 0 : scrollToIndex(next);
772
+ return next;
773
+ });
774
+ break;
775
+ }
776
+ case "Home": {
777
+ event.preventDefault();
778
+ setFocusedIndex(0);
779
+ scrollToIndex == null ? void 0 : scrollToIndex(0);
780
+ break;
781
+ }
782
+ case "End": {
783
+ event.preventDefault();
784
+ const lastIndex = totalItems - 1;
785
+ setFocusedIndex(lastIndex);
786
+ scrollToIndex == null ? void 0 : scrollToIndex(lastIndex);
787
+ break;
788
+ }
789
+ case " ":
790
+ case "Enter": {
791
+ event.preventDefault();
792
+ onItemSelect == null ? void 0 : onItemSelect(focusedIndex);
793
+ break;
794
+ }
795
+ }
796
+ },
797
+ [totalItems, focusedIndex, onItemSelect, onExitNavigation, scrollToIndex]
798
+ );
799
+ const getItemA11yProps = useCallback(
800
+ (index, customLabel) => {
801
+ const itemNumber = index + 1;
802
+ const defaultLabel = `Item ${itemNumber} of ${totalItems}`;
803
+ return {
804
+ role: "group",
805
+ "aria-roledescription": "slide",
806
+ "aria-label": customLabel ? `${customLabel} (${itemNumber} of ${totalItems})` : defaultLabel,
807
+ tabIndex: index === focusedIndex ? 0 : -1,
808
+ onFocus: () => setFocusedIndex(index)
809
+ };
810
+ },
811
+ [focusedIndex, totalItems]
812
+ );
813
+ return {
814
+ focusedIndex,
815
+ setFocusedIndex,
816
+ handleKeyDown,
817
+ getItemA11yProps
818
+ };
819
+ }
820
+
821
+ // src/ui/carousel/carousel.tokens.ts
822
+ var CarouselTokens = {
823
+ /** Corner radius shape (M3 extraLarge shape: 28dp) */
824
+ containerRadius: 28,
825
+ /** Small item dimension limits (dp) */
826
+ smallItemMin: 40,
827
+ smallItemMax: 56,
828
+ /** Layout defaults (dp) */
829
+ itemSpacing: 8,
830
+ contentPadding: 16,
831
+ verticalPadding: 8,
832
+ /** Interactive state overlays */
833
+ hoverOpacity: 0.08,
834
+ focusOpacity: 0.1,
835
+ pressedOpacity: 0.1,
836
+ disabledOpacity: 0.38,
837
+ /** Focus indicator dimensions */
838
+ focusThickness: 3,
839
+ focusOffset: 2,
840
+ /** Touch target minimum size for accessibility (WCAG 2.1 AAA / M3) */
841
+ minTouchTargetSize: 48,
842
+ /** CSS Custom Property token maps for fallback and runtime injection */
843
+ cssVars: {
844
+ shape: "--carousel-item-shape",
845
+ spacing: "--carousel-item-spacing",
846
+ contentPadding: "--carousel-content-padding",
847
+ verticalPadding: "--carousel-vertical-padding",
848
+ smallMin: "--carousel-small-item-min",
849
+ smallMax: "--carousel-small-item-max",
850
+ hoverOpacity: "--carousel-hover-opacity",
851
+ focusThickness: "--carousel-focus-thickness",
852
+ focusOffset: "--carousel-focus-offset",
853
+ pressedOpacity: "--carousel-pressed-opacity",
854
+ disabledOpacity: "--carousel-disabled-opacity"
855
+ }
856
+ };
857
+
858
+ // src/ui/carousel/hooks/useCarouselKeylines.ts
859
+ function useCarouselKeylines({
860
+ containerWidth,
861
+ preferredItemWidth = 300,
862
+ layout = "multi-browse",
863
+ itemSpacing = CarouselTokens.itemSpacing,
864
+ contentPadding = CarouselTokens.contentPadding,
865
+ totalItems,
866
+ scrollX: _scrollX = 0
867
+ }) {
868
+ return useMemo(() => {
869
+ const safeContainerWidth = Math.max(containerWidth, 100);
870
+ const smallWidth = Math.min(
871
+ Math.max(
872
+ CarouselTokens.smallItemMin,
873
+ Math.round(safeContainerWidth * 0.1)
874
+ ),
875
+ CarouselTokens.smallItemMax
876
+ );
877
+ let largeWidth = preferredItemWidth;
878
+ let mediumWidth = Math.round(preferredItemWidth * 0.65);
879
+ switch (layout) {
880
+ case "hero": {
881
+ const availableWidth = safeContainerWidth - contentPadding * 2 - smallWidth - itemSpacing;
882
+ largeWidth = Math.max(160, availableWidth);
883
+ mediumWidth = largeWidth;
884
+ break;
885
+ }
886
+ case "center-aligned-hero": {
887
+ const availableWidth = safeContainerWidth - contentPadding * 2 - smallWidth * 2 - itemSpacing * 2;
888
+ largeWidth = Math.max(160, availableWidth);
889
+ mediumWidth = largeWidth;
890
+ break;
891
+ }
892
+ case "uncontained":
893
+ case "uncontained-multi-aspect": {
894
+ largeWidth = Math.min(
895
+ preferredItemWidth,
896
+ safeContainerWidth - contentPadding * 2
897
+ );
898
+ mediumWidth = largeWidth;
899
+ break;
900
+ }
901
+ case "full-screen": {
902
+ largeWidth = safeContainerWidth;
903
+ mediumWidth = safeContainerWidth;
904
+ break;
905
+ }
906
+ default: {
907
+ const maxLargeWidth = safeContainerWidth - contentPadding * 2 - smallWidth - itemSpacing;
908
+ largeWidth = Math.min(preferredItemWidth, Math.max(160, maxLargeWidth));
909
+ mediumWidth = Math.max(smallWidth + 16, Math.round(largeWidth * 0.65));
910
+ break;
911
+ }
912
+ }
913
+ const keylines = [];
914
+ if (layout === "hero") {
915
+ const smallMask = Math.max(
916
+ 0,
917
+ Math.min(
918
+ 100,
919
+ Math.round((largeWidth - smallWidth) / largeWidth * 100)
920
+ )
921
+ );
922
+ keylines.push(
923
+ {
924
+ offset: contentPadding,
925
+ width: largeWidth,
926
+ type: "large",
927
+ maskClip: 0
928
+ },
929
+ {
930
+ offset: contentPadding + largeWidth + itemSpacing,
931
+ width: smallWidth,
932
+ type: "small",
933
+ maskClip: smallMask
934
+ }
935
+ );
936
+ } else if (layout === "center-aligned-hero") {
937
+ const smallMask = Math.max(
938
+ 0,
939
+ Math.min(
940
+ 100,
941
+ Math.round((largeWidth - smallWidth) / largeWidth * 100)
942
+ )
943
+ );
944
+ keylines.push(
945
+ {
946
+ offset: contentPadding,
947
+ width: smallWidth,
948
+ type: "small",
949
+ maskClip: smallMask
950
+ },
951
+ {
952
+ offset: contentPadding + smallWidth + itemSpacing,
953
+ width: largeWidth,
954
+ type: "large",
955
+ maskClip: 0
956
+ },
957
+ {
958
+ offset: contentPadding + smallWidth + itemSpacing + largeWidth + itemSpacing,
959
+ width: smallWidth,
960
+ type: "small",
961
+ maskClip: smallMask
962
+ }
963
+ );
964
+ } else if (layout === "multi-browse") {
965
+ const mediumMask = Math.max(
966
+ 0,
967
+ Math.min(
968
+ 100,
969
+ Math.round((largeWidth - mediumWidth) / largeWidth * 100)
970
+ )
971
+ );
972
+ const smallMask = Math.max(
973
+ 0,
974
+ Math.min(
975
+ 100,
976
+ Math.round((largeWidth - smallWidth) / largeWidth * 100)
977
+ )
978
+ );
979
+ const availableWidth = safeContainerWidth - contentPadding * 2;
980
+ const numLarge = Math.max(
981
+ 1,
982
+ Math.floor((availableWidth + itemSpacing) / (largeWidth + itemSpacing))
983
+ );
984
+ let offset = contentPadding;
985
+ for (let k = 0; k < numLarge; k++) {
986
+ keylines.push({
987
+ offset,
988
+ width: largeWidth,
989
+ type: "large",
990
+ maskClip: 0
991
+ });
992
+ offset += largeWidth + itemSpacing;
993
+ }
994
+ keylines.push({
995
+ offset,
996
+ width: mediumWidth,
997
+ type: "medium",
998
+ maskClip: mediumMask
999
+ });
1000
+ offset += mediumWidth + itemSpacing;
1001
+ keylines.push({
1002
+ offset,
1003
+ width: smallWidth,
1004
+ type: "small",
1005
+ maskClip: smallMask
1006
+ });
1007
+ } else {
1008
+ keylines.push({
1009
+ offset: contentPadding,
1010
+ width: largeWidth,
1011
+ type: "large",
1012
+ maskClip: 0
1013
+ });
1014
+ }
1015
+ const getItemRestWidth = (i) => {
1016
+ if (layout === "full-screen") return safeContainerWidth;
1017
+ if (layout === "uncontained") return largeWidth;
1018
+ if (layout === "uncontained-multi-aspect") {
1019
+ const ratios = [1.77, 1.33, 1, 0.56];
1020
+ const ratio = ratios[i % ratios.length];
1021
+ return Math.round(Math.min(largeWidth, 220 * ratio));
1022
+ }
1023
+ if (layout === "hero") return i === 0 ? largeWidth : smallWidth;
1024
+ if (layout === "center-aligned-hero")
1025
+ return i === 0 || i === totalItems - 1 ? smallWidth : largeWidth;
1026
+ const pattern = [largeWidth, largeWidth, mediumWidth, smallWidth];
1027
+ return pattern[i % pattern.length];
1028
+ };
1029
+ const snapPositions = [];
1030
+ let currentOffset = 0;
1031
+ const itemLayoutWidth = layout === "full-screen" ? safeContainerWidth : largeWidth;
1032
+ for (let i = 0; i < totalItems; i++) {
1033
+ snapPositions.push(currentOffset);
1034
+ currentOffset += itemLayoutWidth + itemSpacing;
1035
+ }
1036
+ const getItemWidth = (_index) => {
1037
+ if (layout === "full-screen") return safeContainerWidth;
1038
+ return largeWidth;
1039
+ };
1040
+ const getItemMaskClip = (index) => {
1041
+ if (layout === "full-screen" || layout === "uncontained" || layout === "uncontained-multi-aspect") {
1042
+ return 0;
1043
+ }
1044
+ const itemW = getItemRestWidth(index);
1045
+ if (itemW >= largeWidth || largeWidth <= 0) return 0;
1046
+ return Math.max(
1047
+ 0,
1048
+ Math.min(100, Math.round((largeWidth - itemW) / largeWidth * 100))
1049
+ );
1050
+ };
1051
+ const getItemParallaxOffset = (index) => {
1052
+ const maskClip = getItemMaskClip(index);
1053
+ if (maskClip <= 0) return 0;
1054
+ return calculateParallaxOffset(0, maskClip, largeWidth);
1055
+ };
1056
+ let maxAccumulatedShift = 0;
1057
+ if (layout === "hero") {
1058
+ maxAccumulatedShift = Math.max(
1059
+ 0,
1060
+ (totalItems - 1) * (largeWidth - smallWidth)
1061
+ );
1062
+ } else if (layout === "center-aligned-hero") {
1063
+ maxAccumulatedShift = Math.max(
1064
+ 0,
1065
+ Math.min(totalItems, 2) * (largeWidth - smallWidth)
1066
+ );
1067
+ } else if (layout === "multi-browse") {
1068
+ const availableWidth = safeContainerWidth - contentPadding * 2;
1069
+ const numLarge = Math.max(
1070
+ 1,
1071
+ Math.floor((availableWidth + itemSpacing) / (largeWidth + itemSpacing))
1072
+ );
1073
+ const nonLargeItems = Math.max(0, totalItems - numLarge);
1074
+ if (nonLargeItems > 0) {
1075
+ const mediumClipped = largeWidth - mediumWidth;
1076
+ const smallClipped = largeWidth - smallWidth;
1077
+ const numSmall = Math.max(0, nonLargeItems - 1);
1078
+ maxAccumulatedShift = mediumClipped + numSmall * smallClipped;
1079
+ }
1080
+ }
1081
+ return {
1082
+ largeWidth,
1083
+ mediumWidth,
1084
+ smallWidth,
1085
+ keylines,
1086
+ snapPositions,
1087
+ maxAccumulatedShift,
1088
+ getItemWidth,
1089
+ getItemMaskClip,
1090
+ getItemParallaxOffset
1091
+ };
1092
+ }, [
1093
+ containerWidth,
1094
+ preferredItemWidth,
1095
+ layout,
1096
+ itemSpacing,
1097
+ contentPadding,
1098
+ totalItems
1099
+ ]);
1100
+ }
1101
+ function calculateMaskClipForOffset(itemLeftInViewport, containerWidth, largeWidth, mediumWidth, smallWidth, contentPadding = 16, layout = "multi-browse") {
1102
+ if (layout === "full-screen" || layout === "uncontained" || layout === "uncontained-multi-aspect" || largeWidth <= 0) {
1103
+ return 0;
1104
+ }
1105
+ const mediumMask = Math.max(
1106
+ 0,
1107
+ Math.min(100, (largeWidth - mediumWidth) / largeWidth * 100)
1108
+ );
1109
+ const smallMask = Math.max(
1110
+ 0,
1111
+ Math.min(100, (largeWidth - smallWidth) / largeWidth * 100)
1112
+ );
1113
+ const trailingFocalThreshold = containerWidth - contentPadding - mediumWidth - (largeWidth - mediumWidth);
1114
+ const trailingMediumThreshold = containerWidth - contentPadding - smallWidth;
1115
+ const trailingEndThreshold = containerWidth - contentPadding;
1116
+ const leadingThreshold = contentPadding;
1117
+ if (itemLeftInViewport < leadingThreshold) {
1118
+ const dist = leadingThreshold - itemLeftInViewport;
1119
+ const progress = Math.min(1, Math.max(0, dist / largeWidth));
1120
+ return Math.min(100, Math.max(0, progress * smallMask));
1121
+ }
1122
+ if (itemLeftInViewport > trailingFocalThreshold) {
1123
+ if (itemLeftInViewport < trailingMediumThreshold) {
1124
+ const range2 = Math.max(
1125
+ 1,
1126
+ trailingMediumThreshold - trailingFocalThreshold
1127
+ );
1128
+ const progress2 = Math.min(
1129
+ 1,
1130
+ Math.max(0, (itemLeftInViewport - trailingFocalThreshold) / range2)
1131
+ );
1132
+ return progress2 * mediumMask;
1133
+ }
1134
+ const range = Math.max(1, trailingEndThreshold - trailingMediumThreshold);
1135
+ const progress = Math.min(
1136
+ 1,
1137
+ Math.max(0, (itemLeftInViewport - trailingMediumThreshold) / range)
1138
+ );
1139
+ return mediumMask + progress * (smallMask - mediumMask);
1140
+ }
1141
+ return 0;
1142
+ }
1143
+ function calculateParallaxOffset(_itemLeftInViewport, maskClipPercent, largeWidth) {
1144
+ if (maskClipPercent <= 0 || largeWidth <= 0) return 0;
1145
+ return -Math.round(maskClipPercent / 100 * (largeWidth * 0.2));
1146
+ }
1147
+ function CarouselScrollClient(_a) {
1148
+ var _b = _a, {
1149
+ children,
1150
+ items,
1151
+ renderItem,
1152
+ layout = "multi-browse",
1153
+ preferredItemWidth = 300,
1154
+ itemSpacing = 8,
1155
+ contentPadding = 16,
1156
+ verticalPadding = 8,
1157
+ userScrollEnabled = true,
1158
+ totalItemsCount,
1159
+ className,
1160
+ style
1161
+ } = _b, props = __objRest(_b, [
1162
+ "children",
1163
+ "items",
1164
+ "renderItem",
1165
+ "layout",
1166
+ "preferredItemWidth",
1167
+ "itemSpacing",
1168
+ "contentPadding",
1169
+ "verticalPadding",
1170
+ "userScrollEnabled",
1171
+ "totalItemsCount",
1172
+ "className",
1173
+ "style"
1174
+ ]);
1175
+ const trackRef = React23.useRef(null);
1176
+ const [containerWidth, setContainerWidth] = React23.useState(600);
1177
+ const rafIdRef = React23.useRef(null);
1178
+ const isDraggingRef = React23.useRef(false);
1179
+ const hasMovedRef = React23.useRef(false);
1180
+ const startPosRef = React23.useRef(0);
1181
+ const startScrollRef = React23.useRef(0);
1182
+ const keylines = useCarouselKeylines({
1183
+ containerWidth,
1184
+ preferredItemWidth,
1185
+ layout,
1186
+ itemSpacing,
1187
+ contentPadding,
1188
+ totalItems: totalItemsCount
1189
+ });
1190
+ const handleScroll = React23.useCallback(() => {
1191
+ if (rafIdRef.current !== null) return;
1192
+ rafIdRef.current = requestAnimationFrame(() => {
1193
+ var _a2, _b2;
1194
+ const track = trackRef.current;
1195
+ if (track) {
1196
+ const scrollVal = layout === "full-screen" ? track.scrollTop : track.scrollLeft;
1197
+ track.style.setProperty("--carousel-scroll-left", `${scrollVal}px`);
1198
+ if (layout !== "full-screen") {
1199
+ const prefersReducedMotion = typeof window !== "undefined" && ((_b2 = (_a2 = window.matchMedia) == null ? void 0 : _a2.call(window, "(prefers-reduced-motion: reduce)")) == null ? void 0 : _b2.matches);
1200
+ let accumulatedShift = 0;
1201
+ const items2 = track.children;
1202
+ for (let i = 0; i < items2.length; i++) {
1203
+ const itemEl = items2[i];
1204
+ if (!itemEl || itemEl.getAttribute("role") !== "group") continue;
1205
+ if (prefersReducedMotion) {
1206
+ itemEl.style.clipPath = "none";
1207
+ itemEl.style.transform = "none";
1208
+ const innerContent2 = itemEl.firstElementChild;
1209
+ if (innerContent2) innerContent2.style.transform = "none";
1210
+ continue;
1211
+ }
1212
+ const nativeOffset = itemEl.offsetLeft - scrollVal;
1213
+ const visualOffset = nativeOffset - accumulatedShift;
1214
+ const maskPercent = calculateMaskClipForOffset(
1215
+ visualOffset,
1216
+ containerWidth,
1217
+ keylines.largeWidth,
1218
+ keylines.mediumWidth,
1219
+ keylines.smallWidth,
1220
+ contentPadding,
1221
+ layout
1222
+ );
1223
+ const clippedPixels = maskPercent / 100 * keylines.largeWidth;
1224
+ itemEl.style.transform = accumulatedShift > 0 ? `translateX(${-accumulatedShift}px)` : "none";
1225
+ itemEl.style.clipPath = maskPercent > 0 ? `inset(0px ${maskPercent}% 0px 0px round 28px)` : "none";
1226
+ const innerContent = itemEl.firstElementChild;
1227
+ if (innerContent) {
1228
+ const parallaxX = calculateParallaxOffset(
1229
+ visualOffset,
1230
+ maskPercent,
1231
+ keylines.largeWidth
1232
+ );
1233
+ innerContent.style.transform = parallaxX !== 0 ? `translateX(${parallaxX}px)` : "none";
1234
+ }
1235
+ accumulatedShift += clippedPixels;
1236
+ }
1237
+ }
1238
+ }
1239
+ rafIdRef.current = null;
1240
+ });
1241
+ }, [
1242
+ layout,
1243
+ containerWidth,
1244
+ keylines.largeWidth,
1245
+ keylines.mediumWidth,
1246
+ keylines.smallWidth,
1247
+ contentPadding
1248
+ ]);
1249
+ React23.useEffect(() => {
1250
+ const track = trackRef.current;
1251
+ if (!track) return;
1252
+ const updateWidth = () => {
1253
+ if (track.clientWidth > 0) {
1254
+ setContainerWidth(track.clientWidth);
1255
+ }
1256
+ };
1257
+ updateWidth();
1258
+ const observer = new ResizeObserver(updateWidth);
1259
+ observer.observe(track);
1260
+ return () => observer.disconnect();
1261
+ }, []);
1262
+ React23.useEffect(() => {
1263
+ handleScroll();
1264
+ }, [handleScroll]);
1265
+ React23.useEffect(() => {
1266
+ return () => {
1267
+ if (rafIdRef.current !== null) {
1268
+ cancelAnimationFrame(rafIdRef.current);
1269
+ }
1270
+ };
1271
+ }, []);
1272
+ const handlePointerDown = React23.useCallback(
1273
+ (e) => {
1274
+ var _a2, _b2;
1275
+ if (!userScrollEnabled || e.button !== 0) return;
1276
+ const track = trackRef.current;
1277
+ if (!track) return;
1278
+ isDraggingRef.current = true;
1279
+ hasMovedRef.current = false;
1280
+ startPosRef.current = layout === "full-screen" ? e.clientY : e.clientX;
1281
+ startScrollRef.current = layout === "full-screen" ? track.scrollTop : track.scrollLeft;
1282
+ try {
1283
+ (_b2 = (_a2 = e.target).setPointerCapture) == null ? void 0 : _b2.call(_a2, e.pointerId);
1284
+ } catch (e2) {
1285
+ }
1286
+ },
1287
+ [userScrollEnabled, layout]
1288
+ );
1289
+ const handlePointerMove = React23.useCallback(
1290
+ (e) => {
1291
+ if (!isDraggingRef.current || !trackRef.current) return;
1292
+ const currentPos = layout === "full-screen" ? e.clientY : e.clientX;
1293
+ const delta = currentPos - startPosRef.current;
1294
+ if (Math.abs(delta) > 4) {
1295
+ hasMovedRef.current = true;
1296
+ }
1297
+ if (hasMovedRef.current) {
1298
+ if (layout === "full-screen") {
1299
+ trackRef.current.scrollTop = startScrollRef.current - delta;
1300
+ } else {
1301
+ trackRef.current.scrollLeft = startScrollRef.current - delta;
1302
+ }
1303
+ }
1304
+ },
1305
+ [layout]
1306
+ );
1307
+ const handlePointerUp = React23.useCallback(
1308
+ (e) => {
1309
+ var _a2, _b2;
1310
+ if (!isDraggingRef.current) return;
1311
+ isDraggingRef.current = false;
1312
+ try {
1313
+ (_b2 = (_a2 = e.target).releasePointerCapture) == null ? void 0 : _b2.call(_a2, e.pointerId);
1314
+ } catch (e2) {
1315
+ }
1316
+ },
1317
+ []
1318
+ );
1319
+ const handleClickCapture = React23.useCallback((e) => {
1320
+ if (hasMovedRef.current) {
1321
+ e.stopPropagation();
1322
+ e.preventDefault();
1323
+ hasMovedRef.current = false;
1324
+ }
1325
+ }, []);
1326
+ const scrollToIndex = React23.useCallback(
1327
+ (index) => {
1328
+ const track = trackRef.current;
1329
+ if (!track) return;
1330
+ const itemEl = track.children[index];
1331
+ if (!itemEl) return;
1332
+ const targetPos = Math.max(0, itemEl.offsetLeft - contentPadding);
1333
+ track.scrollTo({
1334
+ left: targetPos,
1335
+ behavior: "smooth"
1336
+ });
1337
+ },
1338
+ [contentPadding]
1339
+ );
1340
+ const { focusedIndex, handleKeyDown, getItemA11yProps } = useCarouselA11y({
1341
+ totalItems: totalItemsCount,
1342
+ scrollToIndex
1343
+ });
1344
+ const isFullScreen = layout === "full-screen";
1345
+ const isHero = layout === "hero" || layout === "center-aligned-hero";
1346
+ const trackClasses = cn(
1347
+ // Base layout & GPU containment
1348
+ "relative box-border select-none [contain:layout_style]",
1349
+ userScrollEnabled && "cursor-grab active:cursor-grabbing",
1350
+ // Scrollbar hide
1351
+ "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
1352
+ // Full-screen: vertical snap column
1353
+ isFullScreen ? "flex flex-col flex-1 min-h-0 overflow-x-hidden overflow-y-auto p-0 gap-0 [scroll-snap-type:y_mandatory] [touch-action:pan-y]" : "flex flex-row items-stretch overflow-x-auto overflow-y-hidden [-webkit-overflow-scrolling:touch] [touch-action:pan-x]",
1354
+ // Snap for hero/center-aligned-hero
1355
+ isHero && !isFullScreen && "[scroll-snap-type:x_mandatory]",
1356
+ // Disabled
1357
+ !userScrollEnabled && "overflow-x-hidden pointer-events-none [touch-action:none]",
1358
+ className
1359
+ );
1360
+ const trackStyle = isFullScreen ? __spreadValues({}, style) : __spreadValues({
1361
+ paddingLeft: `${contentPadding}px`,
1362
+ paddingRight: layout === "uncontained" || layout === "uncontained-multi-aspect" ? 0 : `${contentPadding}px`,
1363
+ scrollPaddingLeft: `${contentPadding}px`,
1364
+ scrollPaddingRight: `${contentPadding}px`,
1365
+ paddingTop: `${verticalPadding}px`,
1366
+ paddingBottom: `${verticalPadding}px`,
1367
+ gap: `${itemSpacing}px`
1368
+ }, style);
1369
+ const renderSlides = () => {
1370
+ if (items && renderItem) {
1371
+ return items.map((item, index) => {
1372
+ const itemWidth = keylines.largeWidth;
1373
+ const maskClip = keylines.getItemMaskClip(index);
1374
+ const parallax = keylines.getItemParallaxOffset(index);
1375
+ const a11yProps = getItemA11yProps(index);
1376
+ const itemKey = typeof item === "object" && item !== null && "id" in item ? item.id : typeof item === "object" && item !== null && "key" in item ? item.key : index;
1377
+ return /* @__PURE__ */ jsx(
1378
+ CarouselItem,
1379
+ __spreadProps(__spreadValues({
1380
+ index,
1381
+ totalItems: totalItemsCount,
1382
+ layout,
1383
+ width: itemWidth,
1384
+ minContentWidth: keylines.largeWidth,
1385
+ maskClipPercent: maskClip,
1386
+ parallaxOffset: parallax,
1387
+ isFocused: focusedIndex === index
1388
+ }, a11yProps), {
1389
+ children: renderItem(item, index)
1390
+ }),
1391
+ itemKey
1392
+ );
1393
+ });
1394
+ }
1395
+ return React23.Children.map(children, (child, index) => {
1396
+ if (!React23.isValidElement(child)) return child;
1397
+ const itemWidth = keylines.largeWidth;
1398
+ const maskClip = keylines.getItemMaskClip(index);
1399
+ const parallax = keylines.getItemParallaxOffset(index);
1400
+ const a11yProps = getItemA11yProps(index);
1401
+ const childKey = child.key != null ? child.key : index;
1402
+ return /* @__PURE__ */ jsx(
1403
+ CarouselItem,
1404
+ __spreadProps(__spreadValues({
1405
+ index,
1406
+ totalItems: totalItemsCount,
1407
+ layout,
1408
+ width: itemWidth,
1409
+ minContentWidth: keylines.largeWidth,
1410
+ maskClipPercent: maskClip,
1411
+ parallaxOffset: parallax,
1412
+ isFocused: focusedIndex === index
1413
+ }, a11yProps), {
1414
+ children: child
1415
+ }),
1416
+ childKey
1417
+ );
1418
+ });
1419
+ };
1420
+ return /* @__PURE__ */ jsxs(
1421
+ "section",
1422
+ __spreadProps(__spreadValues({
1423
+ ref: trackRef,
1424
+ "aria-roledescription": "carousel",
1425
+ "aria-label": props["aria-label"] || "Content carousel",
1426
+ tabIndex: 0,
1427
+ className: trackClasses,
1428
+ style: trackStyle,
1429
+ onScroll: handleScroll,
1430
+ onPointerDown: handlePointerDown,
1431
+ onPointerMove: handlePointerMove,
1432
+ onPointerUp: handlePointerUp,
1433
+ onPointerCancel: handlePointerUp,
1434
+ onClickCapture: handleClickCapture,
1435
+ onKeyDown: handleKeyDown
1436
+ }, props), {
1437
+ children: [
1438
+ renderSlides(),
1439
+ !isFullScreen && /* @__PURE__ */ jsx(
1440
+ "div",
1441
+ {
1442
+ "aria-hidden": "true",
1443
+ className: "shrink-0 pointer-events-none",
1444
+ style: {
1445
+ width: 0,
1446
+ marginRight: keylines.maxAccumulatedShift > 0 ? `-${keylines.maxAccumulatedShift}px` : void 0
1447
+ }
1448
+ }
1449
+ )
1450
+ ]
1451
+ })
1452
+ );
1453
+ }
1454
+ function Carousel(_a) {
1455
+ var _b = _a, {
1456
+ children,
1457
+ items,
1458
+ renderItem,
1459
+ layout = "multi-browse",
1460
+ preferredItemWidth = 300,
1461
+ itemSpacing = 8,
1462
+ contentPadding = 16,
1463
+ verticalPadding = 8,
1464
+ isExpanded: controlledExpanded,
1465
+ onShowAllClick,
1466
+ showAllLabel = "Show all",
1467
+ userScrollEnabled = true,
1468
+ className,
1469
+ style
1470
+ } = _b, props = __objRest(_b, [
1471
+ "children",
1472
+ "items",
1473
+ "renderItem",
1474
+ "layout",
1475
+ "preferredItemWidth",
1476
+ "itemSpacing",
1477
+ "contentPadding",
1478
+ "verticalPadding",
1479
+ "isExpanded",
1480
+ "onShowAllClick",
1481
+ "showAllLabel",
1482
+ "userScrollEnabled",
1483
+ "className",
1484
+ "style"
1485
+ ]);
1486
+ const [internalExpanded, setInternalExpanded] = React23.useState(false);
1487
+ const isExpanded = controlledExpanded != null ? controlledExpanded : internalExpanded;
1488
+ const totalItemsCount = React23.useMemo(() => {
1489
+ if (items) return items.length;
1490
+ return React23.Children.count(children);
1491
+ }, [items, children]);
1492
+ const handleShowAllToggle = React23.useCallback(() => {
1493
+ if (onShowAllClick) {
1494
+ onShowAllClick();
1495
+ } else {
1496
+ setInternalExpanded((prev) => !prev);
1497
+ }
1498
+ }, [onShowAllClick]);
1499
+ const isFullScreen = layout === "full-screen";
1500
+ return /* @__PURE__ */ jsxs(
1501
+ "div",
1502
+ {
1503
+ className: cn(
1504
+ "relative w-full flex flex-col gap-3 box-border min-h-0",
1505
+ // Full-screen: propagate height to track
1506
+ isFullScreen && "flex-1",
1507
+ className
1508
+ ),
1509
+ style,
1510
+ children: [
1511
+ !isFullScreen && /* @__PURE__ */ jsxs(
1512
+ "div",
1513
+ {
1514
+ className: "flex items-center justify-between",
1515
+ style: { padding: `0 ${contentPadding}px` },
1516
+ children: [
1517
+ props["aria-label"] && /* @__PURE__ */ jsx("h3", { className: "m-0 text-(length:--md-sys-typescale-title-medium-size,1.125rem) font-medium text-(--md-sys-color-on-surface,currentColor)", children: props["aria-label"] }),
1518
+ /* @__PURE__ */ jsx(
1519
+ "button",
1520
+ {
1521
+ type: "button",
1522
+ className: cn(
1523
+ "inline-flex items-center justify-center min-h-12 min-w-12 px-4 py-2",
1524
+ "rounded-[20px] border border-(--md-sys-color-outline-variant,rgba(121,116,126,0.3))",
1525
+ "bg-transparent text-(--md-sys-color-primary,#6750a4) font-medium text-[0.875rem]",
1526
+ "cursor-pointer outline-none transition-colors duration-200",
1527
+ "hover:bg-(--md-sys-color-surface-container-high,rgba(103,80,164,0.08))",
1528
+ "focus-visible:outline-[3px] focus-visible:outline-(--md-sys-color-secondary,#625b71) focus-visible:outline-offset-2"
1529
+ ),
1530
+ onClick: handleShowAllToggle,
1531
+ "aria-expanded": isExpanded,
1532
+ "aria-label": isExpanded ? "Collapse carousel view" : `${showAllLabel} (${totalItemsCount} items)`,
1533
+ children: isExpanded ? "Show carousel" : showAllLabel
1534
+ }
1535
+ )
1536
+ ]
1537
+ }
1538
+ ),
1539
+ isExpanded ? /* @__PURE__ */ jsx(
1540
+ CarouselGrid,
1541
+ {
1542
+ items,
1543
+ renderItem,
1544
+ preferredItemWidth,
1545
+ children
1546
+ }
1547
+ ) : /* @__PURE__ */ jsx(
1548
+ CarouselScrollClient,
1549
+ __spreadProps(__spreadValues({
1550
+ items,
1551
+ renderItem,
1552
+ layout,
1553
+ preferredItemWidth,
1554
+ itemSpacing,
1555
+ contentPadding,
1556
+ verticalPadding,
1557
+ userScrollEnabled,
1558
+ totalItemsCount
1559
+ }, props), {
1560
+ children
1561
+ })
1562
+ )
1563
+ ]
1564
+ }
1565
+ );
1566
+ }
304
1567
  var SHAPE_KEY_TIMES = "0; 0.14; 0.14; 0.29; 0.29; 0.43; 0.43; 0.57; 0.57; 0.71; 0.71; 0.86; 0.86; 1";
305
1568
  var SHAPE_KEY_SPLINES = [
306
1569
  "0.5 0.2 0 0.8",
@@ -346,11 +1609,11 @@ var ROTATE_KEY_SPLINES = [
346
1609
  var ROTATE_VALUES = "0 24 24; 154 24 24; 309 24 24; 463 24 24; 617 24 24; 771 24 24; 926 24 24; 1080 24 24";
347
1610
  var DETERMINATE_CIRCLE = "M24 7 C34.49 7 41 13.51 41 24 C41 34.49 34.49 41 24 41 C13.51 41 7 34.49 7 24 C7 13.51 13.51 7 24 7 Z";
348
1611
  var DETERMINATE_SOFT_BURST = "M20.9 10.4 21.4 9.5 21.9 8.7 22.5 7.8 23.2 7.2 24.2 7 25.1 7.4 25.7 8.1 26.2 9 26.8 9.8 27.3 10.6 28.1 11.2 29 11.3 30 11 30.9 10.6 31.8 10.3 32.8 9.9 33.7 10 34.5 10.6 34.9 11.5 34.8 12.5 34.8 13.5 34.7 14.5 34.7 15.5 35.2 16.3 36 16.8 37 17.1 37.9 17.3 38.9 17.5 39.8 17.9 40.4 18.7 40.5 19.7 40 20.5 39.4 21.3 38.7 22 38.1 22.8 37.6 23.7 37.7 24.6 38.3 25.5 38.9 26.2 39.6 27 40.2 27.7 40.5 28.7 40.3 29.6 39.5 30.3 38.6 30.6 37.6 30.8 36.7 31 35.7 31.3 35 31.9 34.6 32.8 34.7 33.8 34.8 34.8 34.9 35.8 34.8 36.8 34.3 37.6 33.4 38.1 32.4 38 31.5 37.6 30.6 37.2 29.7 36.9 28.7 36.6 27.8 36.9 27.1 37.6 26.6 38.5 26.1 39.3 25.5 40.2 24.8 40.8 23.8 41 22.9 40.6 22.3 39.9 21.8 39 21.2 38.2 20.7 37.4 19.9 36.8 19 36.7 18 37 17.1 37.4 16.2 37.7 15.2 38.1 14.3 38 13.5 37.4 13.1 36.5 13.2 35.5 13.2 34.5 13.3 33.5 13.3 32.5 12.8 31.7 12 31.2 11 31 10.1 30.7 9.1 30.5 8.2 30.1 7.6 29.3 7.5 28.3 8 27.5 8.7 26.7 9.3 26 9.9 25.2 10.4 24.3 10.3 23.4 9.7 22.5 9.1 21.8 8.4 21 7.8 20.3 7.5 19.3 7.7 18.4 8.5 17.7 9.4 17.4 10.4 17.2 11.3 17 12.3 16.7 13 16.1 13.4 15.2 13.3 14.2 13.2 13.2 13.1 12.2 13.2 11.2 13.7 10.4 14.6 9.9 15.6 10 16.5 10.4 17.4 10.8 18.3 11.1 19.3 11.4 20.2 11.1Z";
349
- var IndeterminateSvg = React18.memo(function IndeterminateSvg2({
1612
+ var IndeterminateSvg = React23.memo(function IndeterminateSvg2({
350
1613
  size
351
1614
  }) {
352
- const [ready, setReady] = React18.useState(false);
353
- React18.useEffect(() => {
1615
+ const [ready, setReady] = React23.useState(false);
1616
+ React23.useEffect(() => {
354
1617
  const raf = requestAnimationFrame(() => setReady(true));
355
1618
  return () => cancelAnimationFrame(raf);
356
1619
  }, []);
@@ -395,7 +1658,7 @@ var IndeterminateSvg = React18.memo(function IndeterminateSvg2({
395
1658
  }
396
1659
  );
397
1660
  });
398
- var DeterminateSvg = React18.memo(function DeterminateSvg2({
1661
+ var DeterminateSvg = React23.memo(function DeterminateSvg2({
399
1662
  size,
400
1663
  progress
401
1664
  }) {
@@ -420,7 +1683,7 @@ var DeterminateSvg = React18.memo(function DeterminateSvg2({
420
1683
  }
421
1684
  );
422
1685
  });
423
- var LoadingIndicator = React18.forwardRef(
1686
+ var LoadingIndicator = React23.forwardRef(
424
1687
  (_a, ref) => {
425
1688
  var _b = _a, {
426
1689
  variant = "uncontained",
@@ -555,7 +1818,7 @@ var ADDITIONAL_ROTATION_EASE_DURATION = 500;
555
1818
  var DEFAULT_MIN_PROGRESS = 0.1;
556
1819
  var DEFAULT_MAX_PROGRESS = 0.8;
557
1820
  var PROGRESS_CYCLE_DURATION = 1500;
558
- var CircularProgress = React18.forwardRef(
1821
+ var CircularProgress = React23.forwardRef(
559
1822
  (_a, ref) => {
560
1823
  var _b = _a, {
561
1824
  value,
@@ -609,19 +1872,19 @@ var CircularProgress = React18.forwardRef(
609
1872
  const shouldShowDeterminateTrack = showTrack === "auto" ? true : showTrack;
610
1873
  const BASELINE_SIZE = 48;
611
1874
  const scaleFactor = size / BASELINE_SIZE;
612
- const effectiveAmplitude = React18.useMemo(
1875
+ const effectiveAmplitude = React23.useMemo(
613
1876
  () => amplitude != null ? amplitude : 1.6 * scaleFactor,
614
1877
  [amplitude, scaleFactor]
615
1878
  );
616
- const effectiveWavelength = React18.useMemo(
1879
+ const effectiveWavelength = React23.useMemo(
617
1880
  () => wavelength != null ? wavelength : 15 * scaleFactor,
618
1881
  [wavelength, scaleFactor]
619
1882
  );
620
- const resolvedAmplitudeRange = React18.useMemo(
1883
+ const resolvedAmplitudeRange = React23.useMemo(
621
1884
  () => amplitudeRange != null ? amplitudeRange : [0, effectiveAmplitude],
622
1885
  [amplitudeRange, effectiveAmplitude]
623
1886
  );
624
- const wavyActivePath = React18.useMemo(
1887
+ const wavyActivePath = React23.useMemo(
625
1888
  () => isWavy ? generateWavyCircularPath(
626
1889
  center,
627
1890
  radius,
@@ -630,8 +1893,8 @@ var CircularProgress = React18.forwardRef(
630
1893
  ) : null,
631
1894
  [isWavy, center, radius, effectiveAmplitude, effectiveWavelength]
632
1895
  );
633
- const circumference = React18.useMemo(() => 2 * Math.PI * radius, [radius]);
634
- const gapForTrack = React18.useMemo(
1896
+ const circumference = React23.useMemo(() => 2 * Math.PI * radius, [radius]);
1897
+ const gapForTrack = React23.useMemo(
635
1898
  () => (gapSize + trackHeight) / circumference,
636
1899
  [gapSize, trackHeight, circumference]
637
1900
  );
@@ -639,17 +1902,17 @@ var CircularProgress = React18.forwardRef(
639
1902
  const trackOffset = isDeterminate ? activeAngularFraction + gapForTrack : 0;
640
1903
  const trackLength = isDeterminate ? Math.max(1e-3, 1 - activeAngularFraction - 2 * gapForTrack) : 1;
641
1904
  const ActiveCircleElem = m.circle;
642
- const indeterminateSvgRef = React18.useRef(null);
643
- const indeterminateTrackRef = React18.useRef(null);
644
- const indeterminateActiveRef = React18.useRef(null);
645
- const indeterminateWavyTrackPathRef = React18.useRef(null);
646
- const indeterminateWavyActivePathRef = React18.useRef(null);
647
- const determinateWavyActivePathRef = React18.useRef(null);
648
- const determinateWavyTrackPathRef = React18.useRef(null);
649
- const cachedPathLengthRef = React18.useRef(0);
1905
+ const indeterminateSvgRef = React23.useRef(null);
1906
+ const indeterminateTrackRef = React23.useRef(null);
1907
+ const indeterminateActiveRef = React23.useRef(null);
1908
+ const indeterminateWavyTrackPathRef = React23.useRef(null);
1909
+ const indeterminateWavyActivePathRef = React23.useRef(null);
1910
+ const determinateWavyActivePathRef = React23.useRef(null);
1911
+ const determinateWavyTrackPathRef = React23.useRef(null);
1912
+ const cachedPathLengthRef = React23.useRef(0);
650
1913
  const fractionMV = useMotionValue(isDeterminate ? clampedValue / 100 : 0);
651
1914
  const amplitudeMV = useMotionValue(isWavy ? effectiveAmplitude : 0);
652
- React18.useEffect(() => {
1915
+ React23.useEffect(() => {
653
1916
  if (isDeterminate) {
654
1917
  animate(fractionMV, clampedValue / 100, {
655
1918
  duration: 0.4,
@@ -657,7 +1920,7 @@ var CircularProgress = React18.forwardRef(
657
1920
  });
658
1921
  }
659
1922
  }, [clampedValue, isDeterminate, fractionMV]);
660
- React18.useEffect(() => {
1923
+ React23.useEffect(() => {
661
1924
  if (!isDeterminate || !isWavy) return;
662
1925
  const fraction = clampedValue / 100;
663
1926
  let targetAmp = effectiveAmplitude;
@@ -677,7 +1940,7 @@ var CircularProgress = React18.forwardRef(
677
1940
  amplitudeMV,
678
1941
  determinateAnimation
679
1942
  ]);
680
- React18.useLayoutEffect(() => {
1943
+ React23.useLayoutEffect(() => {
681
1944
  if (!isWavy || !wavyActivePath) {
682
1945
  cachedPathLengthRef.current = circumference;
683
1946
  return;
@@ -1054,9 +2317,9 @@ var CircularProgress = React18.forwardRef(
1054
2317
  );
1055
2318
  CircularProgress.displayName = "CircularProgress";
1056
2319
  function useContainerWidth() {
1057
- const [width, setWidth] = React18.useState(0);
1058
- const observerRef = React18.useRef(null);
1059
- const ref = React18.useCallback((node) => {
2320
+ const [width, setWidth] = React23.useState(0);
2321
+ const observerRef = React23.useRef(null);
2322
+ const ref = React23.useCallback((node) => {
1060
2323
  if (observerRef.current) {
1061
2324
  observerRef.current.disconnect();
1062
2325
  observerRef.current = null;
@@ -1070,7 +2333,7 @@ function useContainerWidth() {
1070
2333
  observerRef.current = obs;
1071
2334
  }
1072
2335
  }, []);
1073
- React18.useEffect(() => {
2336
+ React23.useEffect(() => {
1074
2337
  return () => {
1075
2338
  if (observerRef.current) {
1076
2339
  observerRef.current.disconnect();
@@ -1080,7 +2343,7 @@ function useContainerWidth() {
1080
2343
  return [ref, width];
1081
2344
  }
1082
2345
  function useMergedRef(...refs) {
1083
- return React18.useCallback(
2346
+ return React23.useCallback(
1084
2347
  (node) => {
1085
2348
  for (const ref of refs) {
1086
2349
  if (typeof ref === "function") {
@@ -1094,7 +2357,7 @@ function useMergedRef(...refs) {
1094
2357
  [refs]
1095
2358
  );
1096
2359
  }
1097
- var FlatLinearTrack = React18.memo(function FlatLinearTrack2({
2360
+ var FlatLinearTrack = React23.memo(function FlatLinearTrack2({
1098
2361
  trackHeight,
1099
2362
  activeColor,
1100
2363
  trackColor,
@@ -1170,7 +2433,7 @@ var FlatLinearTrack = React18.memo(function FlatLinearTrack2({
1170
2433
  }
1171
2434
  );
1172
2435
  });
1173
- var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
2436
+ var WavyLinearTrack = React23.memo(function WavyLinearTrack2({
1174
2437
  trackHeight,
1175
2438
  svgHeight,
1176
2439
  amplitude,
@@ -1189,13 +2452,13 @@ var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
1189
2452
  }) {
1190
2453
  const isDeterminate = typeof value === "number";
1191
2454
  const clampedValue = isDeterminate ? Math.max(0, Math.min(100, value)) : 100;
1192
- const titleId = React18.useId();
2455
+ const titleId = React23.useId();
1193
2456
  const [containerRef, width] = useContainerWidth();
1194
- const activePathRef = React18.useRef(null);
1195
- const trackPathRef = React18.useRef(null);
2457
+ const activePathRef = React23.useRef(null);
2458
+ const trackPathRef = React23.useRef(null);
1196
2459
  const amplitudeMV = useMotionValue(amplitude);
1197
2460
  const fractionMV = useMotionValue(isDeterminate ? clampedValue / 100 : 1);
1198
- React18.useEffect(() => {
2461
+ React23.useEffect(() => {
1199
2462
  if (isDeterminate) {
1200
2463
  const fraction = clampedValue / 100;
1201
2464
  let targetAmp = amplitude;
@@ -1383,7 +2646,7 @@ var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
1383
2646
  }
1384
2647
  );
1385
2648
  });
1386
- var LinearProgress = React18.forwardRef(
2649
+ var LinearProgress = React23.forwardRef(
1387
2650
  (_a, ref) => {
1388
2651
  var _b = _a, {
1389
2652
  value,
@@ -1424,10 +2687,10 @@ var LinearProgress = React18.forwardRef(
1424
2687
  ]);
1425
2688
  const isDeterminate = value !== void 0;
1426
2689
  const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
1427
- const containerRef = React18.useRef(null);
2690
+ const containerRef = React23.useRef(null);
1428
2691
  const mergedRef = useMergedRef(ref, containerRef);
1429
- const [isRtl, setIsRtl] = React18.useState(false);
1430
- React18.useEffect(() => {
2692
+ const [isRtl, setIsRtl] = React23.useState(false);
2693
+ React23.useEffect(() => {
1431
2694
  if (containerRef.current) {
1432
2695
  const dir = getComputedStyle(containerRef.current).direction;
1433
2696
  setIsRtl(dir === "rtl");
@@ -1435,16 +2698,16 @@ var LinearProgress = React18.forwardRef(
1435
2698
  }, []);
1436
2699
  const resolvedTrackShape = trackShape != null ? trackShape : shape;
1437
2700
  const isWavy = shape === "wavy" || resolvedTrackShape === "wavy";
1438
- const effectiveAmplitude = React18.useMemo(() => amplitude != null ? amplitude : 3, [amplitude]);
1439
- const svgHeight = React18.useMemo(
2701
+ const effectiveAmplitude = React23.useMemo(() => amplitude != null ? amplitude : 3, [amplitude]);
2702
+ const svgHeight = React23.useMemo(
1440
2703
  () => isWavy ? trackHeight + effectiveAmplitude * 2 : trackHeight,
1441
2704
  [isWavy, trackHeight, effectiveAmplitude]
1442
2705
  );
1443
- const shouldShowStop = React18.useMemo(
2706
+ const shouldShowStop = React23.useMemo(
1444
2707
  () => isDeterminate && resolvedTrackShape === "flat" && showStopIndicator !== false,
1445
2708
  [isDeterminate, resolvedTrackShape, showStopIndicator]
1446
2709
  );
1447
- const stopSize = React18.useMemo(
2710
+ const stopSize = React23.useMemo(
1448
2711
  () => Math.max(2, trackHeight > 4 ? 4 : trackHeight / 2),
1449
2712
  [trackHeight]
1450
2713
  );
@@ -1519,7 +2782,7 @@ var LinearProgress = React18.forwardRef(
1519
2782
  }
1520
2783
  );
1521
2784
  LinearProgress.displayName = "LinearProgress";
1522
- var ProgressIndicator = React18.forwardRef((props, ref) => {
2785
+ var ProgressIndicator = React23.forwardRef((props, ref) => {
1523
2786
  if (props.variant === "circular") {
1524
2787
  return /* @__PURE__ */ jsx(CircularProgress, __spreadValues({ ref }, props));
1525
2788
  }
@@ -1773,7 +3036,7 @@ function AnimatedIconSlot({
1773
3036
  }
1774
3037
  );
1775
3038
  }
1776
- var ButtonComponent = React18.forwardRef(
3039
+ var ButtonComponent = React23.forwardRef(
1777
3040
  (_a, ref) => {
1778
3041
  var _b = _a, {
1779
3042
  className,
@@ -1839,9 +3102,9 @@ var ButtonComponent = React18.forwardRef(
1839
3102
  borderWidth: outlineWidth != null ? outlineWidth : colorStyle === "outlined" ? sizeTokens.outlineWidth : 0,
1840
3103
  borderStyle: colorStyle === "outlined" ? "solid" : void 0
1841
3104
  }, style);
1842
- const labelText = React18.useMemo(() => {
3105
+ const labelText = React23.useMemo(() => {
1843
3106
  if (asChild) {
1844
- const child = React18.Children.only(children);
3107
+ const child = React23.Children.only(children);
1845
3108
  return child.props.children;
1846
3109
  }
1847
3110
  return children;
@@ -1849,8 +3112,8 @@ var ButtonComponent = React18.forwardRef(
1849
3112
  const computedAriaLabel = ariaLabelProp || (typeof children === "string" ? children : void 0);
1850
3113
  const needsTouchTarget = size === "xs" || size === "sm";
1851
3114
  const motionRadius = useMotionValue(animateRadius);
1852
- const asChildRef = React18.useRef(null);
1853
- const mergedRef = React18.useCallback(
3115
+ const asChildRef = React23.useRef(null);
3116
+ const mergedRef = React23.useCallback(
1854
3117
  (node) => {
1855
3118
  asChildRef.current = node;
1856
3119
  if (typeof ref === "function") ref(node);
@@ -1859,14 +3122,14 @@ var ButtonComponent = React18.forwardRef(
1859
3122
  },
1860
3123
  [ref]
1861
3124
  );
1862
- React18.useEffect(() => {
3125
+ React23.useEffect(() => {
1863
3126
  if (!asChild) return;
1864
3127
  return motionRadius.on("change", (v) => {
1865
3128
  if (asChildRef.current)
1866
3129
  asChildRef.current.style.borderRadius = `${v}px`;
1867
3130
  });
1868
3131
  }, [motionRadius, asChild]);
1869
- React18.useEffect(() => {
3132
+ React23.useEffect(() => {
1870
3133
  if (!asChild) return;
1871
3134
  const controls = springAnimate(motionRadius, animateRadius);
1872
3135
  return () => controls.stop();
@@ -1874,14 +3137,14 @@ var ButtonComponent = React18.forwardRef(
1874
3137
  const { ripples, onPointerDown, removeRipple } = useRippleState({
1875
3138
  disabled: loading
1876
3139
  });
1877
- const handleClick = React18.useCallback(
3140
+ const handleClick = React23.useCallback(
1878
3141
  (e) => {
1879
3142
  if (loading) return e.preventDefault();
1880
3143
  onClick == null ? void 0 : onClick(e);
1881
3144
  },
1882
3145
  [loading, onClick]
1883
3146
  );
1884
- const handleKeyDown = React18.useCallback(
3147
+ const handleKeyDown = React23.useCallback(
1885
3148
  (e) => {
1886
3149
  if (loading) return;
1887
3150
  if (onClick && (e.key === "Enter" || e.key === " ")) {
@@ -1960,17 +3223,17 @@ var ButtonComponent = React18.forwardRef(
1960
3223
  isSelected && selectedIcon ? "selected-icon" : "icon"
1961
3224
  ) })
1962
3225
  ] });
1963
- const handleAsChildPointerDown = React18.useCallback(
3226
+ const handleAsChildPointerDown = React23.useCallback(
1964
3227
  (e) => {
1965
3228
  springAnimate(motionRadius, pressedRadius);
1966
3229
  onPointerDown == null ? void 0 : onPointerDown(e);
1967
3230
  },
1968
3231
  [motionRadius, pressedRadius, onPointerDown]
1969
3232
  );
1970
- const handleAsChildPointerUp = React18.useCallback(() => {
3233
+ const handleAsChildPointerUp = React23.useCallback(() => {
1971
3234
  springAnimate(motionRadius, animateRadius);
1972
3235
  }, [motionRadius, animateRadius]);
1973
- const handlePointerDown = React18.useCallback(
3236
+ const handlePointerDown = React23.useCallback(
1974
3237
  (e) => {
1975
3238
  onPointerDown(e);
1976
3239
  },
@@ -1980,7 +3243,7 @@ var ButtonComponent = React18.forwardRef(
1980
3243
  const strippedProps = __spreadValues({}, restProps);
1981
3244
  for (const key of MOTION_PROP_KEYS) delete strippedProps[key];
1982
3245
  const htmlProps = strippedProps;
1983
- const child = React18.Children.only(children);
3246
+ const child = React23.Children.only(children);
1984
3247
  return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(
1985
3248
  Slot,
1986
3249
  __spreadProps(__spreadValues({
@@ -1997,7 +3260,7 @@ var ButtonComponent = React18.forwardRef(
1997
3260
  }),
1998
3261
  className: buttonClassName
1999
3262
  }, htmlProps), {
2000
- children: React18.cloneElement(child, { children: innerContent })
3263
+ children: React23.cloneElement(child, { children: innerContent })
2001
3264
  })
2002
3265
  ) });
2003
3266
  }
@@ -2025,13 +3288,13 @@ var ButtonComponent = React18.forwardRef(
2025
3288
  }
2026
3289
  );
2027
3290
  ButtonComponent.displayName = "Button";
2028
- var Button = React18.memo(ButtonComponent);
3291
+ var Button = React23.memo(ButtonComponent);
2029
3292
  var VARIANT_FONT = {
2030
3293
  outlined: "'Material Symbols Outlined'",
2031
3294
  rounded: "'Material Symbols Rounded'",
2032
3295
  sharp: "'Material Symbols Sharp'"
2033
3296
  };
2034
- var IconComponent = React18.forwardRef(
3297
+ var IconComponent = React23.forwardRef(
2035
3298
  (_a, ref) => {
2036
3299
  var _b = _a, {
2037
3300
  name,
@@ -2097,8 +3360,8 @@ var IconComponent = React18.forwardRef(
2097
3360
  }
2098
3361
  );
2099
3362
  IconComponent.displayName = "Icon";
2100
- var Icon = React18.memo(IconComponent);
2101
- var ScrollArea = React18.forwardRef(
3363
+ var Icon = React23.memo(IconComponent);
3364
+ var ScrollArea = React23.forwardRef(
2102
3365
  (_a, ref) => {
2103
3366
  var _b = _a, {
2104
3367
  className,
@@ -2119,15 +3382,15 @@ var ScrollArea = React18.forwardRef(
2119
3382
  "viewportRef",
2120
3383
  "viewportProps"
2121
3384
  ]);
2122
- const [isTouchDevice, setIsTouchDevice] = React18.useState(false);
2123
- React18.useEffect(() => {
3385
+ const [isTouchDevice, setIsTouchDevice] = React23.useState(false);
3386
+ React23.useEffect(() => {
2124
3387
  if (typeof window !== "undefined") {
2125
3388
  setIsTouchDevice(
2126
3389
  "ontouchstart" in window || navigator.maxTouchPoints > 0
2127
3390
  );
2128
3391
  }
2129
3392
  }, []);
2130
- const resolvedType = React18.useMemo(() => {
3393
+ const resolvedType = React23.useMemo(() => {
2131
3394
  if (type === "hover" && isTouchDevice) {
2132
3395
  return "scroll";
2133
3396
  }
@@ -2178,7 +3441,7 @@ var ScrollArea = React18.forwardRef(
2178
3441
  }
2179
3442
  );
2180
3443
  ScrollArea.displayName = "ScrollArea";
2181
- var ScrollAreaScrollbar = React18.forwardRef((_a, ref) => {
3444
+ var ScrollAreaScrollbar = React23.forwardRef((_a, ref) => {
2182
3445
  var _b = _a, { className, orientation = "vertical" } = _b, props = __objRest(_b, ["className", "orientation"]);
2183
3446
  return /* @__PURE__ */ jsx(
2184
3447
  RadixScrollArea.Scrollbar,
@@ -2208,7 +3471,7 @@ var ScrollAreaScrollbar = React18.forwardRef((_a, ref) => {
2208
3471
  );
2209
3472
  });
2210
3473
  ScrollAreaScrollbar.displayName = RadixScrollArea.Scrollbar.displayName;
2211
- var ScrollAreaCorner = React18.forwardRef((_a, ref) => {
3474
+ var ScrollAreaCorner = React23.forwardRef((_a, ref) => {
2212
3475
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2213
3476
  return /* @__PURE__ */ jsx(
2214
3477
  RadixScrollArea.Corner,
@@ -2404,7 +3667,7 @@ function buildWavePath(startX, endX, amplitude = 2, wavelength = 32, yCenter = 4
2404
3667
  }
2405
3668
  return d;
2406
3669
  }
2407
- var DividerImpl = React18.forwardRef(
3670
+ var DividerImpl = React23.forwardRef(
2408
3671
  (_a, ref) => {
2409
3672
  var _b = _a, {
2410
3673
  variant = "full-bleed",
@@ -2524,9 +3787,9 @@ var DividerImpl = React18.forwardRef(
2524
3787
  }
2525
3788
  );
2526
3789
  DividerImpl.displayName = "Divider";
2527
- var Divider = React18.memo(DividerImpl);
2528
- var ListContext = React18.createContext(null);
2529
- var useListContext = () => React18.useContext(ListContext);
3790
+ var Divider = React23.memo(DividerImpl);
3791
+ var ListContext = React23.createContext(null);
3792
+ var useListContext = () => React23.useContext(ListContext);
2530
3793
  var LIST_TOKENS = {
2531
3794
  oneLineHeight: 56,
2532
3795
  twoLineHeight: 72,
@@ -2591,9 +3854,9 @@ function resolveItemId(item) {
2591
3854
  return String(item);
2592
3855
  }
2593
3856
  function isListItem(child) {
2594
- return React18.isValidElement(child) && child.props != null && typeof child.props === "object" && "value" in child.props;
3857
+ return React23.isValidElement(child) && child.props != null && typeof child.props === "object" && "value" in child.props;
2595
3858
  }
2596
- var ListImpl = React18.forwardRef(
3859
+ var ListImpl = React23.forwardRef(
2597
3860
  (_a, ref) => {
2598
3861
  var _b = _a, {
2599
3862
  className,
@@ -2624,12 +3887,12 @@ var ListImpl = React18.forwardRef(
2624
3887
  "innerRadius",
2625
3888
  "children"
2626
3889
  ]);
2627
- const listRef = React18.useRef(null);
2628
- const [draggedOrder, setDraggedOrder] = React18.useState(
3890
+ const listRef = React23.useRef(null);
3891
+ const [draggedOrder, setDraggedOrder] = React23.useState(
2629
3892
  null
2630
3893
  );
2631
- React18.useImperativeHandle(ref, () => listRef.current);
2632
- const [selectedState, setSelectedState] = React18.useState(
3894
+ React23.useImperativeHandle(ref, () => listRef.current);
3895
+ const [selectedState, setSelectedState] = React23.useState(
2633
3896
  () => {
2634
3897
  var _a2;
2635
3898
  const initialValue = (_a2 = value != null ? value : defaultValue) != null ? _a2 : [];
@@ -2639,13 +3902,13 @@ var ListImpl = React18.forwardRef(
2639
3902
  }
2640
3903
  );
2641
3904
  const isControlled = value !== void 0;
2642
- const selectedValues = React18.useMemo(() => {
3905
+ const selectedValues = React23.useMemo(() => {
2643
3906
  if (isControlled) {
2644
3907
  return new Set(Array.isArray(value) ? value : value ? [value] : []);
2645
3908
  }
2646
3909
  return selectedState;
2647
3910
  }, [isControlled, value, selectedState]);
2648
- const onItemChange = React18.useCallback(
3911
+ const onItemChange = React23.useCallback(
2649
3912
  (itemValue, selected) => {
2650
3913
  const nextSet = new Set(selectedValues);
2651
3914
  if (selectionMode === "single-select") {
@@ -2677,11 +3940,11 @@ var ListImpl = React18.forwardRef(
2677
3940
  coordinateGetter: sortableKeyboardCoordinates
2678
3941
  })
2679
3942
  );
2680
- const itemIds = React18.useMemo(
3943
+ const itemIds = React23.useMemo(
2681
3944
  () => items ? items.map(resolveItemId) : [],
2682
3945
  [items]
2683
3946
  );
2684
- const currentOrder = React18.useMemo(
3947
+ const currentOrder = React23.useMemo(
2685
3948
  () => draggedOrder || itemIds,
2686
3949
  [draggedOrder, itemIds]
2687
3950
  );
@@ -2741,20 +4004,20 @@ var ListImpl = React18.forwardRef(
2741
4004
  }
2742
4005
  (_a2 = focusableItems[nextIndex]) == null ? void 0 : _a2.focus();
2743
4006
  };
2744
- const childrenArray = React18.Children.toArray(children);
4007
+ const childrenArray = React23.Children.toArray(children);
2745
4008
  const listItemCount = childrenArray.filter(isListItem).length;
2746
4009
  let currentListItemIndex = 0;
2747
- const processedChildren = React18.Children.map(children, (child) => {
4010
+ const processedChildren = React23.Children.map(children, (child) => {
2748
4011
  if (!isListItem(child)) return child;
2749
4012
  const childValue = child.props.value;
2750
4013
  const index = reorderable && currentOrder.length > 0 ? currentOrder.indexOf(String(childValue)) : currentListItemIndex;
2751
4014
  currentListItemIndex++;
2752
- return React18.cloneElement(
4015
+ return React23.cloneElement(
2753
4016
  child,
2754
4017
  { _listIndex: index }
2755
4018
  );
2756
4019
  });
2757
- const contextValue = React18.useMemo(
4020
+ const contextValue = React23.useMemo(
2758
4021
  () => ({
2759
4022
  selectionMode,
2760
4023
  variant,
@@ -2778,7 +4041,7 @@ var ListImpl = React18.forwardRef(
2778
4041
  innerRadius
2779
4042
  ]
2780
4043
  );
2781
- const dndId = React18.useId();
4044
+ const dndId = React23.useId();
2782
4045
  const isListbox = selectionMode === "single-select" || selectionMode === "multi-select";
2783
4046
  const role = isListbox ? "listbox" : "list";
2784
4047
  const ariaMultiselectable = selectionMode === "multi-select" ? true : void 0;
@@ -2825,13 +4088,13 @@ var ListImpl = React18.forwardRef(
2825
4088
  }
2826
4089
  );
2827
4090
  ListImpl.displayName = "List";
2828
- var List = React18.memo(ListImpl);
4091
+ var List = React23.memo(ListImpl);
2829
4092
  var INSET_CLASSES = {
2830
4093
  icon: "pl-[56px]",
2831
4094
  avatar: "pl-[72px]",
2832
4095
  custom: "pl-4"
2833
4096
  };
2834
- var ListDividerImpl = React18.forwardRef(
4097
+ var ListDividerImpl = React23.forwardRef(
2835
4098
  (_a, ref) => {
2836
4099
  var _b = _a, { className, inset = false, insetType = "avatar" } = _b, props = __objRest(_b, ["className", "inset", "insetType"]);
2837
4100
  const insetClass = inset ? INSET_CLASSES[insetType] : "";
@@ -2856,7 +4119,7 @@ var ListDividerImpl = React18.forwardRef(
2856
4119
  }
2857
4120
  );
2858
4121
  ListDividerImpl.displayName = "ListDivider";
2859
- var ListDivider = React18.memo(ListDividerImpl);
4122
+ var ListDivider = React23.memo(ListDividerImpl);
2860
4123
  var MD3_STANDARD = [0.2, 0, 0, 1];
2861
4124
  var MD3_FAST_EFFECTS = [0.3, 0, 1, 1];
2862
4125
  var CHECKMARK_PATH = "M 4.5 9.5 L 7.5 12.5 L 13.5 5.5";
@@ -2870,7 +4133,7 @@ var NEXT_STATE = {
2870
4133
  checked: "indeterminate",
2871
4134
  indeterminate: "unchecked"
2872
4135
  };
2873
- var CheckboxVisual = React18.memo(function CheckboxVisual2({
4136
+ var CheckboxVisual = React23.memo(function CheckboxVisual2({
2874
4137
  isSelected,
2875
4138
  isIndeterminate,
2876
4139
  containerBg,
@@ -2941,7 +4204,7 @@ var CheckboxVisual = React18.memo(function CheckboxVisual2({
2941
4204
  );
2942
4205
  });
2943
4206
  function useMergedRef2(externalRef, internalRef) {
2944
- return React18.useCallback(
4207
+ return React23.useCallback(
2945
4208
  (node) => {
2946
4209
  internalRef.current = node;
2947
4210
  if (!externalRef) return;
@@ -2954,7 +4217,7 @@ function useMergedRef2(externalRef, internalRef) {
2954
4217
  [externalRef, internalRef]
2955
4218
  );
2956
4219
  }
2957
- var CheckboxComponent = React18.forwardRef(
4220
+ var CheckboxComponent = React23.forwardRef(
2958
4221
  ({
2959
4222
  checked,
2960
4223
  defaultChecked = false,
@@ -2976,20 +4239,20 @@ var CheckboxComponent = React18.forwardRef(
2976
4239
  }, ref) => {
2977
4240
  var _a;
2978
4241
  const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
2979
- const generatedId = React18.useId();
4242
+ const generatedId = React23.useId();
2980
4243
  const inputId = idProp != null ? idProp : label ? `checkbox-${generatedId}` : void 0;
2981
- const [internalState, setInternalState] = React18.useState(
4244
+ const [internalState, setInternalState] = React23.useState(
2982
4245
  () => defaultChecked ? "checked" : "unchecked"
2983
4246
  );
2984
4247
  const isControlled = stateProp !== void 0 || checked !== void 0;
2985
4248
  const baseState = isControlled ? resolveState(checked, false, stateProp) : internalState;
2986
4249
  const effectiveState = indeterminate ? "indeterminate" : baseState;
2987
- const [ripples, setRipples] = React18.useState([]);
2988
- const removeRipple = React18.useCallback(
4250
+ const [ripples, setRipples] = React23.useState([]);
4251
+ const removeRipple = React23.useCallback(
2989
4252
  (id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
2990
4253
  []
2991
4254
  );
2992
- const onPointerDown = React18.useCallback(
4255
+ const onPointerDown = React23.useCallback(
2993
4256
  (e) => {
2994
4257
  if (disabled) return;
2995
4258
  const rect = e.currentTarget.getBoundingClientRect();
@@ -3003,7 +4266,7 @@ var CheckboxComponent = React18.forwardRef(
3003
4266
  },
3004
4267
  [disabled]
3005
4268
  );
3006
- const handleChange = React18.useCallback(
4269
+ const handleChange = React23.useCallback(
3007
4270
  (e) => {
3008
4271
  if (disabled) return;
3009
4272
  if (stateProp !== void 0) {
@@ -3029,9 +4292,9 @@ var CheckboxComponent = React18.forwardRef(
3029
4292
  onCheckedChange
3030
4293
  ]
3031
4294
  );
3032
- const inputRef = React18.useRef(null);
4295
+ const inputRef = React23.useRef(null);
3033
4296
  const mergedRef = useMergedRef2(ref, inputRef);
3034
- React18.useEffect(() => {
4297
+ React23.useEffect(() => {
3035
4298
  if (inputRef.current) {
3036
4299
  inputRef.current.indeterminate = effectiveState === "indeterminate";
3037
4300
  }
@@ -3156,19 +4419,19 @@ var CheckboxComponent = React18.forwardRef(
3156
4419
  }
3157
4420
  );
3158
4421
  CheckboxComponent.displayName = "Checkbox";
3159
- var Checkbox = React18.memo(CheckboxComponent);
3160
- var TriStateCheckboxComponent = React18.forwardRef((_a, ref) => {
4422
+ var Checkbox = React23.memo(CheckboxComponent);
4423
+ var TriStateCheckboxComponent = React23.forwardRef((_a, ref) => {
3161
4424
  var _b = _a, { state, onStateChange } = _b, rest = __objRest(_b, ["state", "onStateChange"]);
3162
4425
  return /* @__PURE__ */ jsx(Checkbox, __spreadValues({ ref, state, onStateChange }, rest));
3163
4426
  });
3164
4427
  TriStateCheckboxComponent.displayName = "TriStateCheckbox";
3165
- React18.memo(TriStateCheckboxComponent);
4428
+ React23.memo(TriStateCheckboxComponent);
3166
4429
  var MD3_FAST_EFFECTS2 = [0.3, 0, 1, 1];
3167
- var RadioGroupContext = React18.createContext(
4430
+ var RadioGroupContext = React23.createContext(
3168
4431
  null
3169
4432
  );
3170
4433
  function useMergedRef3(externalRef, internalRef) {
3171
- return React18.useCallback(
4434
+ return React23.useCallback(
3172
4435
  (node) => {
3173
4436
  internalRef.current = node;
3174
4437
  if (!externalRef) return;
@@ -3181,7 +4444,7 @@ function useMergedRef3(externalRef, internalRef) {
3181
4444
  [externalRef, internalRef]
3182
4445
  );
3183
4446
  }
3184
- var RadioVisual = React18.memo(function RadioVisual2({
4447
+ var RadioVisual = React23.memo(function RadioVisual2({
3185
4448
  isSelected,
3186
4449
  disabled,
3187
4450
  error,
@@ -3234,7 +4497,7 @@ var RadioVisual = React18.memo(function RadioVisual2({
3234
4497
  }
3235
4498
  );
3236
4499
  });
3237
- var RadioButtonComponent = React18.forwardRef(
4500
+ var RadioButtonComponent = React23.forwardRef(
3238
4501
  ({
3239
4502
  selected,
3240
4503
  defaultSelected = false,
@@ -3253,23 +4516,23 @@ var RadioButtonComponent = React18.forwardRef(
3253
4516
  required: requiredProp
3254
4517
  }, ref) => {
3255
4518
  var _a, _b;
3256
- const group = React18.useContext(RadioGroupContext);
4519
+ const group = React23.useContext(RadioGroupContext);
3257
4520
  const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
3258
- const generatedId = React18.useId();
4521
+ const generatedId = React23.useId();
3259
4522
  const inputId = idProp != null ? idProp : label ? `radio-${generatedId}` : void 0;
3260
4523
  const name = (_b = group == null ? void 0 : group.name) != null ? _b : nameProp;
3261
4524
  const disabled = (group == null ? void 0 : group.disabled) || disabledProp;
3262
4525
  const error = (group == null ? void 0 : group.error) || errorProp || color === "error";
3263
4526
  const required = (group == null ? void 0 : group.required) || requiredProp;
3264
- const [internalSelected, setInternalSelected] = React18.useState(defaultSelected);
4527
+ const [internalSelected, setInternalSelected] = React23.useState(defaultSelected);
3265
4528
  const isControlled = selected !== void 0;
3266
4529
  const isSelected = group ? group.selectedValue === value : isControlled ? selected != null ? selected : false : internalSelected;
3267
- const [ripples, setRipples] = React18.useState([]);
3268
- const removeRipple = React18.useCallback(
4530
+ const [ripples, setRipples] = React23.useState([]);
4531
+ const removeRipple = React23.useCallback(
3269
4532
  (id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
3270
4533
  []
3271
4534
  );
3272
- const onPointerDown = React18.useCallback(
4535
+ const onPointerDown = React23.useCallback(
3273
4536
  (e) => {
3274
4537
  if (disabled) return;
3275
4538
  const rect = e.currentTarget.getBoundingClientRect();
@@ -3283,12 +4546,12 @@ var RadioButtonComponent = React18.forwardRef(
3283
4546
  },
3284
4547
  [disabled]
3285
4548
  );
3286
- const [isHovered, setIsHovered] = React18.useState(false);
3287
- const onPointerEnter = React18.useCallback(() => {
4549
+ const [isHovered, setIsHovered] = React23.useState(false);
4550
+ const onPointerEnter = React23.useCallback(() => {
3288
4551
  if (!disabled) setIsHovered(true);
3289
4552
  }, [disabled]);
3290
- const onPointerLeave = React18.useCallback(() => setIsHovered(false), []);
3291
- const handleChange = React18.useCallback(
4553
+ const onPointerLeave = React23.useCallback(() => setIsHovered(false), []);
4554
+ const handleChange = React23.useCallback(
3292
4555
  (_e) => {
3293
4556
  if (disabled || onClick === null) return;
3294
4557
  if (group) {
@@ -3302,7 +4565,7 @@ var RadioButtonComponent = React18.forwardRef(
3302
4565
  },
3303
4566
  [disabled, onClick, group, value, isControlled]
3304
4567
  );
3305
- const inputRef = React18.useRef(null);
4568
+ const inputRef = React23.useRef(null);
3306
4569
  const mergedRef = useMergedRef3(ref, inputRef);
3307
4570
  const stateLayerBg = error ? "before:bg-m3-error" : "before:bg-m3-primary";
3308
4571
  const stateLayerClass = cn(
@@ -3413,8 +4676,8 @@ var RadioButtonComponent = React18.forwardRef(
3413
4676
  }
3414
4677
  );
3415
4678
  RadioButtonComponent.displayName = "RadioButton";
3416
- var RadioButton = React18.memo(RadioButtonComponent);
3417
- var RadioGroupComponent = React18.forwardRef(
4679
+ var RadioButton = React23.memo(RadioButtonComponent);
4680
+ var RadioGroupComponent = React23.forwardRef(
3418
4681
  ({
3419
4682
  name,
3420
4683
  value: valueProp,
@@ -3429,19 +4692,19 @@ var RadioGroupComponent = React18.forwardRef(
3429
4692
  children,
3430
4693
  className
3431
4694
  }, ref) => {
3432
- const [internalValue, setInternalValue] = React18.useState(defaultValue);
4695
+ const [internalValue, setInternalValue] = React23.useState(defaultValue);
3433
4696
  const isControlled = valueProp !== void 0;
3434
4697
  const selectedValue = isControlled ? valueProp : internalValue;
3435
- const handleValueChange = React18.useCallback(
4698
+ const handleValueChange = React23.useCallback(
3436
4699
  (val) => {
3437
4700
  if (!isControlled) setInternalValue(val);
3438
4701
  onValueChange == null ? void 0 : onValueChange(val);
3439
4702
  },
3440
4703
  [isControlled, onValueChange]
3441
4704
  );
3442
- const groupRef = React18.useRef(null);
4705
+ const groupRef = React23.useRef(null);
3443
4706
  const mergedRef = useMergedRef3(ref, groupRef);
3444
- const onKeyDown = React18.useCallback(
4707
+ const onKeyDown = React23.useCallback(
3445
4708
  (e) => {
3446
4709
  var _a, _b;
3447
4710
  if (disabled) return;
@@ -3465,7 +4728,7 @@ var RadioGroupComponent = React18.forwardRef(
3465
4728
  },
3466
4729
  [disabled, handleValueChange]
3467
4730
  );
3468
- const contextValue = React18.useMemo(
4731
+ const contextValue = React23.useMemo(
3469
4732
  () => ({
3470
4733
  name,
3471
4734
  selectedValue,
@@ -3500,7 +4763,7 @@ var RadioGroupComponent = React18.forwardRef(
3500
4763
  }
3501
4764
  );
3502
4765
  RadioGroupComponent.displayName = "RadioGroup";
3503
- React18.memo(RadioGroupComponent);
4766
+ React23.memo(RadioGroupComponent);
3504
4767
 
3505
4768
  // src/ui/switch/switch.tokens.ts
3506
4769
  var SwitchTokens = {
@@ -3578,7 +4841,7 @@ function isIconVisible(thumbContent, icons, showOnlySelectedIcon, checked) {
3578
4841
  if (icons) return true;
3579
4842
  return showOnlySelectedIcon && checked;
3580
4843
  }
3581
- var SwitchVisual = React18.memo(function SwitchVisual2({
4844
+ var SwitchVisual = React23.memo(function SwitchVisual2({
3582
4845
  checked,
3583
4846
  disabled,
3584
4847
  isPressed,
@@ -3698,7 +4961,7 @@ var SwitchVisual = React18.memo(function SwitchVisual2({
3698
4961
  }
3699
4962
  );
3700
4963
  });
3701
- var SwitchComponent = React18.forwardRef(
4964
+ var SwitchComponent = React23.forwardRef(
3702
4965
  ({
3703
4966
  checked,
3704
4967
  onCheckedChange,
@@ -3716,16 +4979,16 @@ var SwitchComponent = React18.forwardRef(
3716
4979
  }, ref) => {
3717
4980
  var _a;
3718
4981
  const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
3719
- const [isPressed, setIsPressed] = React18.useState(false);
3720
- const [isHovered, setIsHovered] = React18.useState(false);
3721
- const [isFocused, setIsFocused] = React18.useState(false);
3722
- const [ripples, setRipples] = React18.useState([]);
3723
- const generatedId = React18.useId();
4982
+ const [isPressed, setIsPressed] = React23.useState(false);
4983
+ const [isHovered, setIsHovered] = React23.useState(false);
4984
+ const [isFocused, setIsFocused] = React23.useState(false);
4985
+ const [ripples, setRipples] = React23.useState([]);
4986
+ const generatedId = React23.useId();
3724
4987
  const switchId = label ? `switch-${generatedId}` : void 0;
3725
- const handleClick = React18.useCallback(() => {
4988
+ const handleClick = React23.useCallback(() => {
3726
4989
  if (!disabled) onCheckedChange(!checked);
3727
4990
  }, [disabled, checked, onCheckedChange]);
3728
- const handleKeyDown = React18.useCallback(
4991
+ const handleKeyDown = React23.useCallback(
3729
4992
  (e) => {
3730
4993
  if (disabled) return;
3731
4994
  if (e.key === " " || e.key === "Enter") {
@@ -3735,7 +4998,7 @@ var SwitchComponent = React18.forwardRef(
3735
4998
  },
3736
4999
  [disabled, checked, onCheckedChange]
3737
5000
  );
3738
- const handlePointerDown = React18.useCallback(
5001
+ const handlePointerDown = React23.useCallback(
3739
5002
  (e) => {
3740
5003
  if (disabled) return;
3741
5004
  setIsPressed(true);
@@ -3750,19 +5013,19 @@ var SwitchComponent = React18.forwardRef(
3750
5013
  },
3751
5014
  [disabled]
3752
5015
  );
3753
- const handlePointerUp = React18.useCallback(() => {
5016
+ const handlePointerUp = React23.useCallback(() => {
3754
5017
  setIsPressed(false);
3755
5018
  }, []);
3756
- const handlePointerEnter = React18.useCallback(() => {
5019
+ const handlePointerEnter = React23.useCallback(() => {
3757
5020
  if (!disabled) setIsHovered(true);
3758
5021
  }, [disabled]);
3759
- const handlePointerLeave = React18.useCallback(() => {
5022
+ const handlePointerLeave = React23.useCallback(() => {
3760
5023
  setIsHovered(false);
3761
5024
  setIsPressed(false);
3762
5025
  }, []);
3763
- const handleFocus = React18.useCallback(() => setIsFocused(true), []);
3764
- const handleBlur = React18.useCallback(() => setIsFocused(false), []);
3765
- const removeRipple = React18.useCallback(
5026
+ const handleFocus = React23.useCallback(() => setIsFocused(true), []);
5027
+ const handleBlur = React23.useCallback(() => setIsFocused(false), []);
5028
+ const removeRipple = React23.useCallback(
3766
5029
  (id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
3767
5030
  []
3768
5031
  );
@@ -3788,7 +5051,7 @@ var SwitchComponent = React18.forwardRef(
3788
5051
  onFocus: handleFocus,
3789
5052
  onBlur: handleBlur,
3790
5053
  className: cn(
3791
- "relative inline-flex items-center justify-center cursor-pointer select-none",
5054
+ "relative inline-flex items-center justify-center cursor-pointer select-none shrink-0",
3792
5055
  // Touch target: 48×48 minimum (pad around 32px track)
3793
5056
  "min-w-12 min-h-12",
3794
5057
  // Focus ring — MD3 FocusIndicatorColor = secondary
@@ -3798,7 +5061,7 @@ var SwitchComponent = React18.forwardRef(
3798
5061
  disabled && "pointer-events-none cursor-not-allowed",
3799
5062
  !label && className
3800
5063
  ),
3801
- children: /* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-full", children: [
5064
+ children: /* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-full shrink-0", children: [
3802
5065
  /* @__PURE__ */ jsx(
3803
5066
  SwitchVisual,
3804
5067
  {
@@ -3847,7 +5110,7 @@ var SwitchComponent = React18.forwardRef(
3847
5110
  }
3848
5111
  );
3849
5112
  SwitchComponent.displayName = "Switch";
3850
- var Switch = React18.memo(SwitchComponent);
5113
+ var Switch = React23.memo(SwitchComponent);
3851
5114
 
3852
5115
  // src/ui/lists/list-utils.ts
3853
5116
  function getListItemHeight(hasOverline, supportingTextLines) {
@@ -3987,7 +5250,7 @@ function renderSwitchTrailing({
3987
5250
  trailingClass
3988
5251
  }) {
3989
5252
  const isSelectingMode = selectionMode === "single-select" || selectionMode === "multi-select";
3990
- const switchElement = React18.isValidElement(trailingContent) ? (() => {
5253
+ const switchElement = React23.isValidElement(trailingContent) ? (() => {
3991
5254
  const trailingProps = trailingContent.props;
3992
5255
  const checkedValue = !isSelectingMode && trailingProps.checked !== void 0 ? trailingProps.checked : isSelected;
3993
5256
  const disabledValue = trailingProps.disabled !== void 0 ? disabled || trailingProps.disabled : disabled;
@@ -3998,7 +5261,7 @@ function renderSwitchTrailing({
3998
5261
  onItemChange(value, checked);
3999
5262
  }
4000
5263
  };
4001
- return React18.cloneElement(
5264
+ return React23.cloneElement(
4002
5265
  trailingContent,
4003
5266
  { checked: checkedValue, disabled: disabledValue, onCheckedChange }
4004
5267
  );
@@ -4023,7 +5286,7 @@ function renderSwitchTrailing({
4023
5286
  )
4024
5287
  );
4025
5288
  }
4026
- var ListItemImpl = React18.forwardRef(
5289
+ var ListItemImpl = React23.forwardRef(
4027
5290
  (_a, ref) => {
4028
5291
  var _b = _a, {
4029
5292
  className,
@@ -4079,9 +5342,9 @@ var ListItemImpl = React18.forwardRef(
4079
5342
  });
4080
5343
  const reorderable = (_e = context == null ? void 0 : context.reorderable) != null ? _e : false;
4081
5344
  const isSelected = selected !== void 0 ? selected : (_f = context == null ? void 0 : context.selectedValues.has(value)) != null ? _f : false;
4082
- const [isHovered, setIsHovered] = React18.useState(false);
4083
- const [isFocused, setIsFocused] = React18.useState(false);
4084
- const [isPressed, setIsPressed] = React18.useState(false);
5345
+ const [isHovered, setIsHovered] = React23.useState(false);
5346
+ const [isFocused, setIsFocused] = React23.useState(false);
5347
+ const [isPressed, setIsPressed] = React23.useState(false);
4085
5348
  const { ripples, onPointerDown, removeRipple } = useRippleState({
4086
5349
  disabled
4087
5350
  });
@@ -4093,8 +5356,8 @@ var ListItemImpl = React18.forwardRef(
4093
5356
  transition,
4094
5357
  isDragging
4095
5358
  } = useSortable({ id: value, disabled: !reorderable });
4096
- const itemRef = React18.useRef(null);
4097
- const setRefs = React18.useCallback(
5359
+ const itemRef = React23.useRef(null);
5360
+ const setRefs = React23.useCallback(
4098
5361
  (node) => {
4099
5362
  itemRef.current = node;
4100
5363
  setNodeRef(node);
@@ -4547,7 +5810,7 @@ var ListItemImpl = React18.forwardRef(
4547
5810
  }
4548
5811
  );
4549
5812
  ListItemImpl.displayName = "ListItem";
4550
- var ListItem = React18.memo(ListItemImpl);
5813
+ var ListItem = React23.memo(ListItemImpl);
4551
5814
  var typographyVariants = cva("m-0 p-0 text-m3-on-surface", {
4552
5815
  variants: {
4553
5816
  variant: {
@@ -4573,10 +5836,10 @@ var typographyVariants = cva("m-0 p-0 text-m3-on-surface", {
4573
5836
  variant: "body-md"
4574
5837
  }
4575
5838
  });
4576
- var Text = React18.forwardRef(
5839
+ var Text = React23.forwardRef(
4577
5840
  (_a, ref) => {
4578
5841
  var _b = _a, { className, variant, as: Component, color, weight, style } = _b, props = __objRest(_b, ["className", "variant", "as", "color", "weight", "style"]);
4579
- const defaultComponent = React18.useMemo(() => {
5842
+ const defaultComponent = React23.useMemo(() => {
4580
5843
  const v = variant ? String(variant).toLowerCase() : "";
4581
5844
  if (v.startsWith("display") || v.startsWith("headline")) return "h1";
4582
5845
  if (v.startsWith("title")) return "h2";
@@ -4598,12 +5861,15 @@ Text.displayName = "Text";
4598
5861
  function TableOfContents({
4599
5862
  items,
4600
5863
  className,
4601
- scrollAreaProps
5864
+ scrollAreaProps,
5865
+ scrollContainerRef
4602
5866
  }) {
4603
5867
  const [activeId, setActiveId] = useState("");
4604
5868
  const itemIds = useMemo(() => items.map((i) => i.id), [items]);
4605
5869
  useEffect(() => {
5870
+ var _a;
4606
5871
  if (typeof IntersectionObserver === "undefined") return;
5872
+ const root = (_a = scrollContainerRef == null ? void 0 : scrollContainerRef.current) != null ? _a : null;
4607
5873
  const observer = new IntersectionObserver(
4608
5874
  (entries) => {
4609
5875
  for (const entry of entries) {
@@ -4611,19 +5877,20 @@ function TableOfContents({
4611
5877
  }
4612
5878
  },
4613
5879
  // rootMargin: top offset ~100px (fixed header), bottom -80% (early switch)
4614
- { rootMargin: "-100px 0% -80% 0%" }
5880
+ { root, rootMargin: "-100px 0% -80% 0%" }
4615
5881
  );
4616
5882
  for (const id of itemIds) {
4617
5883
  const el = document.getElementById(id);
4618
5884
  if (el) observer.observe(el);
4619
5885
  }
4620
5886
  return () => observer.disconnect();
4621
- }, [itemIds]);
5887
+ }, [itemIds, scrollContainerRef]);
4622
5888
  const handleClick = useCallback(
4623
5889
  (e, id) => {
4624
- var _a;
4625
5890
  e.preventDefault();
4626
- (_a = document.getElementById(id)) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "start" });
5891
+ const target = document.getElementById(id);
5892
+ if (!target) return;
5893
+ target.scrollIntoView({ behavior: "smooth", block: "start" });
4627
5894
  },
4628
5895
  []
4629
5896
  );
@@ -4640,19 +5907,35 @@ function TableOfContents({
4640
5907
  type: "hover"
4641
5908
  }, scrollAreaProps), {
4642
5909
  className: cn("flex-1 min-h-0", scrollAreaProps == null ? void 0 : scrollAreaProps.className),
4643
- children: /* @__PURE__ */ jsx("ul", { className: "space-y-4 pr-4", children: items.map((item) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
4644
- "a",
4645
- {
4646
- href: `#${item.id}`,
4647
- onClick: (e) => handleClick(e, item.id),
4648
- "aria-current": activeId === item.id ? "true" : void 0,
4649
- className: cn(
4650
- "text-sm transition-colors hover:text-m3-primary block",
4651
- activeId === item.id ? "text-m3-primary font-bold" : "text-m3-on-surface-variant font-medium"
4652
- ),
4653
- children: item.label
4654
- }
4655
- ) }, item.id)) })
5910
+ children: /* @__PURE__ */ jsx("ul", { className: "space-y-2 pr-4", children: items.map((item) => {
5911
+ var _a;
5912
+ const depth = (_a = item.depth) != null ? _a : 1;
5913
+ const isSubItem = depth > 1;
5914
+ return /* @__PURE__ */ jsx(
5915
+ "li",
5916
+ {
5917
+ className: cn(
5918
+ isSubItem && "pl-3.5 border-l border-m3-outline-variant/40 ml-1"
5919
+ ),
5920
+ children: /* @__PURE__ */ jsx(
5921
+ "a",
5922
+ {
5923
+ href: `#${item.id}`,
5924
+ onClick: (e) => handleClick(e, item.id),
5925
+ "aria-current": activeId === item.id ? "true" : void 0,
5926
+ className: cn(
5927
+ "transition-colors hover:text-m3-primary block truncate",
5928
+ isSubItem ? "text-xs py-0.5 leading-relaxed" : "text-sm py-1 font-medium leading-snug",
5929
+ activeId === item.id ? "text-m3-primary font-bold" : "text-m3-on-surface-variant"
5930
+ ),
5931
+ title: item.label,
5932
+ children: item.label
5933
+ }
5934
+ )
5935
+ },
5936
+ item.id
5937
+ );
5938
+ }) })
4656
5939
  })
4657
5940
  )
4658
5941
  ]
@@ -5395,6 +6678,6 @@ function TypographyProvider({
5395
6678
  return /* @__PURE__ */ jsx(TypographyContext.Provider, { value, children });
5396
6679
  }
5397
6680
 
5398
- export { Card, CodeBlock, DEFAULT_FONT_VARIATION_AXES, Divider, LIST_TOKENS, List, ListContext, ListDivider, ListItem, MD3_EXPRESSIVE_FONT_VARIATION, ScrollArea, ScrollAreaScrollbar, TableOfContents, Text, TypeScaleTokens, Typography, TypographyContext, TypographyKeyTokens, TypographyProvider, TypographyTokens, buildWavePath, getExpressiveShape, getListItemHeight, serializeFontVariationAxes, shouldTopAlign, typographyVariants, useListContext, useTypography };
6681
+ export { Card, CardContent, CardFooter, CardHeader, CardMedia, Carousel, CarouselGrid, CarouselItem, CarouselScrollClient, CarouselTokens, CodeBlock, DEFAULT_FONT_VARIATION_AXES, Divider, LIST_TOKENS, List, ListContext, ListDivider, ListItem, MD3_EXPRESSIVE_FONT_VARIATION, SHADOW, ScrollArea, ScrollAreaScrollbar, TableOfContents, Text, TypeScaleTokens, Typography, TypographyContext, TypographyKeyTokens, TypographyProvider, TypographyTokens, VARIANT_ELEVATION, buildWavePath, cardVariants, getExpressiveShape, getListItemHeight, resolveElevationShadow, serializeFontVariationAxes, shouldTopAlign, typographyVariants, useCardElevation, useCarouselA11y, useCarouselKeylines, useListContext, useTypography };
5399
6682
  //# sourceMappingURL=layout.mjs.map
5400
6683
  //# sourceMappingURL=layout.mjs.map