@ansh-ui/vue 0.2.0 → 0.3.1

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 (84) hide show
  1. package/dist/{chunk-B6OXKW5Q.js → chunk-AL4PPK25.js} +5 -2
  2. package/dist/chunk-AL4PPK25.js.map +1 -0
  3. package/dist/{chunk-2VSROZ2N.js → chunk-D3HH726R.js} +152 -144
  4. package/dist/chunk-D3HH726R.js.map +1 -0
  5. package/dist/{chunk-5BQEZYG6.cjs → chunk-EDAF7RAN.cjs} +163 -155
  6. package/dist/chunk-EDAF7RAN.cjs.map +1 -0
  7. package/dist/{chunk-TMG3M6TK.js → chunk-G2OX2NH2.js} +3 -3
  8. package/dist/chunk-G2OX2NH2.js.map +1 -0
  9. package/dist/{chunk-SOYRICHU.js → chunk-G3EIU6VM.js} +14 -8
  10. package/dist/chunk-G3EIU6VM.js.map +1 -0
  11. package/dist/{chunk-KCA7RNJ4.cjs → chunk-IHH6KMBY.cjs} +239 -5
  12. package/dist/chunk-IHH6KMBY.cjs.map +1 -0
  13. package/dist/{chunk-J2LA4GRP.cjs → chunk-IO6WJEJI.cjs} +122 -120
  14. package/dist/chunk-IO6WJEJI.cjs.map +1 -0
  15. package/dist/{chunk-IOXGBPOV.cjs → chunk-JJBYF7AH.cjs} +14 -8
  16. package/dist/chunk-JJBYF7AH.cjs.map +1 -0
  17. package/dist/{chunk-Z7XOFKM4.cjs → chunk-KKCZ5RUE.cjs} +4 -2
  18. package/dist/chunk-KKCZ5RUE.cjs.map +1 -0
  19. package/dist/{chunk-6ABPGOJP.js → chunk-LFGAOD32.js} +4 -2
  20. package/dist/chunk-LFGAOD32.js.map +1 -0
  21. package/dist/{chunk-EISHOEB6.cjs → chunk-MWGVDY6K.cjs} +3 -3
  22. package/dist/chunk-MWGVDY6K.cjs.map +1 -0
  23. package/dist/{chunk-FVKLCGA4.js → chunk-NJMTWLT2.js} +123 -121
  24. package/dist/chunk-NJMTWLT2.js.map +1 -0
  25. package/dist/{chunk-T425FIC7.js → chunk-NKRPZTQA.js} +238 -5
  26. package/dist/chunk-NKRPZTQA.js.map +1 -0
  27. package/dist/{chunk-JQ4YLXXM.cjs → chunk-PNR4RQ4T.cjs} +5 -2
  28. package/dist/chunk-PNR4RQ4T.cjs.map +1 -0
  29. package/dist/data.cjs +16 -16
  30. package/dist/data.d.cts +54 -52
  31. package/dist/data.d.ts +54 -52
  32. package/dist/data.js +1 -1
  33. package/dist/form.cjs +36 -36
  34. package/dist/form.d.cts +53 -45
  35. package/dist/form.d.ts +53 -45
  36. package/dist/form.js +1 -1
  37. package/dist/index.cjs +208 -180
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +33 -8
  40. package/dist/index.d.ts +33 -8
  41. package/dist/index.js +31 -15
  42. package/dist/index.js.map +1 -1
  43. package/dist/layout.cjs +13 -13
  44. package/dist/layout.d.cts +23 -14
  45. package/dist/layout.d.ts +23 -14
  46. package/dist/layout.js +1 -1
  47. package/dist/motion.cjs +11 -11
  48. package/dist/motion.d.cts +41 -37
  49. package/dist/motion.d.ts +41 -37
  50. package/dist/motion.js +1 -1
  51. package/dist/navigation.cjs +13 -9
  52. package/dist/navigation.d.cts +125 -4
  53. package/dist/navigation.d.ts +125 -4
  54. package/dist/navigation.js +2 -2
  55. package/dist/overlay.cjs +14 -14
  56. package/dist/overlay.d.cts +36 -33
  57. package/dist/overlay.d.ts +36 -33
  58. package/dist/overlay.js +2 -2
  59. package/dist/{position-Cn7qP1pn.d.cts → position-CiY171HP.d.cts} +2 -1
  60. package/dist/{position-Cn7qP1pn.d.ts → position-CiY171HP.d.ts} +2 -1
  61. package/dist/primitives.cjs +6 -6
  62. package/dist/primitives.d.cts +6 -5
  63. package/dist/primitives.d.ts +6 -5
  64. package/dist/primitives.js +1 -1
  65. package/dist/{sidebar-CTZ-Ckko.d.ts → sidebar-B9zDHMbn.d.cts} +5 -4
  66. package/dist/{sidebar-CQqEmpid.d.cts → sidebar-DMrKHqZ5.d.ts} +5 -4
  67. package/dist/styles.css +464 -0
  68. package/dist/{utils-IKPG3zcC.d.cts → utils-D4XwXDeX.d.cts} +2 -1
  69. package/dist/{utils-IKPG3zcC.d.ts → utils-D4XwXDeX.d.ts} +2 -1
  70. package/package.json +3 -3
  71. package/dist/chunk-2VSROZ2N.js.map +0 -1
  72. package/dist/chunk-5BQEZYG6.cjs.map +0 -1
  73. package/dist/chunk-6ABPGOJP.js.map +0 -1
  74. package/dist/chunk-B6OXKW5Q.js.map +0 -1
  75. package/dist/chunk-EISHOEB6.cjs.map +0 -1
  76. package/dist/chunk-FVKLCGA4.js.map +0 -1
  77. package/dist/chunk-IOXGBPOV.cjs.map +0 -1
  78. package/dist/chunk-J2LA4GRP.cjs.map +0 -1
  79. package/dist/chunk-JQ4YLXXM.cjs.map +0 -1
  80. package/dist/chunk-KCA7RNJ4.cjs.map +0 -1
  81. package/dist/chunk-SOYRICHU.js.map +0 -1
  82. package/dist/chunk-T425FIC7.js.map +0 -1
  83. package/dist/chunk-TMG3M6TK.js.map +0 -1
  84. package/dist/chunk-Z7XOFKM4.cjs.map +0 -1
package/dist/overlay.js CHANGED
@@ -1,7 +1,7 @@
1
- export { AlertDialog, ContextMenu, Dialog, DialogFooter, Drawer, DropdownMenu, HoverCard, Popover, PopoverContent, PopoverTrigger, Tooltip, TooltipProvider } from './chunk-2VSROZ2N.js';
1
+ export { AlertDialog, ContextMenu, Dialog, DialogFooter, Drawer, DropdownMenu, HoverCard, Popover, PopoverContent, PopoverTrigger, Tooltip, TooltipProvider } from './chunk-D3HH726R.js';
2
2
  import './chunk-6XJOB6LE.js';
3
3
  import './chunk-XZ5ZFLZM.js';
4
- import './chunk-TMG3M6TK.js';
4
+ import './chunk-G2OX2NH2.js';
5
5
  import './chunk-OAQ7MDYX.js';
6
6
  import './chunk-NJDDNO4C.js';
7
7
  //# sourceMappingURL=overlay.js.map
@@ -47,4 +47,5 @@ interface PositionResult {
47
47
  }
48
48
  declare function computePosition(anchor: Rect, floating: Rect, viewport: Rect, options?: PositionOptions): PositionResult;
49
49
 
50
- export { type Align as A, type Placement as P, type Rect as R, type Side as S, type PositionOptions as a, type PositionResult as b, computePosition as c };
50
+ export { computePosition as c };
51
+ export type { Align as A, Placement as P, Rect as R, Side as S, PositionOptions as a, PositionResult as b };
@@ -47,4 +47,5 @@ interface PositionResult {
47
47
  }
48
48
  declare function computePosition(anchor: Rect, floating: Rect, viewport: Rect, options?: PositionOptions): PositionResult;
49
49
 
50
- export { type Align as A, type Placement as P, type Rect as R, type Side as S, type PositionOptions as a, type PositionResult as b, computePosition as c };
50
+ export { computePosition as c };
51
+ export type { Align as A, Placement as P, Rect as R, Side as S, PositionOptions as a, PositionResult as b };
@@ -2,7 +2,7 @@
2
2
 
3
3
  var chunkDMPNT3MY_cjs = require('./chunk-DMPNT3MY.cjs');
4
4
  var chunkXLLSS464_cjs = require('./chunk-XLLSS464.cjs');
5
- var chunkEISHOEB6_cjs = require('./chunk-EISHOEB6.cjs');
5
+ var chunkMWGVDY6K_cjs = require('./chunk-MWGVDY6K.cjs');
6
6
  var chunk774WBLDR_cjs = require('./chunk-774WBLDR.cjs');
7
7
  var chunkPP6OYURM_cjs = require('./chunk-PP6OYURM.cjs');
8
8
  var chunk6732H4BQ_cjs = require('./chunk-6732H4BQ.cjs');
@@ -35,23 +35,23 @@ Object.defineProperty(exports, "useScrollLock", {
35
35
  });
36
36
  Object.defineProperty(exports, "getTabbable", {
37
37
  enumerable: true,
38
- get: function () { return chunkEISHOEB6_cjs.getTabbable; }
38
+ get: function () { return chunkMWGVDY6K_cjs.getTabbable; }
39
39
  });
40
40
  Object.defineProperty(exports, "useAutoFocus", {
41
41
  enumerable: true,
42
- get: function () { return chunkEISHOEB6_cjs.useAutoFocus; }
42
+ get: function () { return chunkMWGVDY6K_cjs.useAutoFocus; }
43
43
  });
44
44
  Object.defineProperty(exports, "useFocusRestore", {
45
45
  enumerable: true,
46
- get: function () { return chunkEISHOEB6_cjs.useFocusRestore; }
46
+ get: function () { return chunkMWGVDY6K_cjs.useFocusRestore; }
47
47
  });
48
48
  Object.defineProperty(exports, "useFocusTrap", {
49
49
  enumerable: true,
50
- get: function () { return chunkEISHOEB6_cjs.useFocusTrap; }
50
+ get: function () { return chunkMWGVDY6K_cjs.useFocusTrap; }
51
51
  });
52
52
  Object.defineProperty(exports, "useRovingFocus", {
53
53
  enumerable: true,
54
- get: function () { return chunkEISHOEB6_cjs.useRovingFocus; }
54
+ get: function () { return chunkMWGVDY6K_cjs.useRovingFocus; }
55
55
  });
56
56
  Object.defineProperty(exports, "useControllableState", {
57
57
  enumerable: true,
@@ -1,7 +1,7 @@
1
- import { R as ReadonlyRef } from './utils-IKPG3zcC.cjs';
2
- export { S as SlotContent, c as cx, r as resolveSlotContent, u as useId } from './utils-IKPG3zcC.cjs';
3
- import { b as PositionResult, a as PositionOptions } from './position-Cn7qP1pn.cjs';
4
- export { A as Align, P as Placement, R as Rect, S as Side, c as computePosition } from './position-Cn7qP1pn.cjs';
1
+ import { R as ReadonlyRef } from './utils-D4XwXDeX.cjs';
2
+ export { S as SlotContent, c as cx, r as resolveSlotContent, u as useId } from './utils-D4XwXDeX.cjs';
3
+ import { b as PositionResult, a as PositionOptions } from './position-CiY171HP.cjs';
4
+ export { A as Align, P as Placement, R as Rect, S as Side, c as computePosition } from './position-CiY171HP.cjs';
5
5
  import { ComputedRef, Ref, ShallowRef } from 'vue';
6
6
  import * as _ansh_ui_core from '@ansh-ui/core';
7
7
  import { BudgetReport, PointerState, ScrollTrackOptions, ScrollProgress, FrameState, MotionValue, AnimationOptions, SpringOptions } from '@ansh-ui/core';
@@ -297,4 +297,5 @@ declare function useAnimate(): <T>(from: T | MotionValue<T>, to: T | readonly T[
297
297
  */
298
298
  declare function useAnimatedFrom<Source, T>(source: Ref<Source>, target: MotionValue<T>, map: (value: Source) => T, options?: AnimationOptions<T>): void;
299
299
 
300
- export { type AnchoredPosition, type AnchoredPositionOptions, type DismissOptions, PositionOptions, PositionResult, ReadonlyRef, type UseInViewOptions, getLayerStack, getTabbable, useAnchoredPosition, useAnimate, useAnimatedFrom, useAutoFocus, useControllableState, useDismiss, useElementSize, useFocusRestore, useFocusTrap, useFrameBudget, useInView, useMotionRef, useMotionStyle, useMotionValue, usePointer, usePresence, useReducedMotion, useRovingFocus, useScrollLock, useScrollProgress, useSpringValue, useTicker, useWindowScroll };
300
+ export { PositionOptions, PositionResult, ReadonlyRef, getLayerStack, getTabbable, useAnchoredPosition, useAnimate, useAnimatedFrom, useAutoFocus, useControllableState, useDismiss, useElementSize, useFocusRestore, useFocusTrap, useFrameBudget, useInView, useMotionRef, useMotionStyle, useMotionValue, usePointer, usePresence, useReducedMotion, useRovingFocus, useScrollLock, useScrollProgress, useSpringValue, useTicker, useWindowScroll };
301
+ export type { AnchoredPosition, AnchoredPositionOptions, DismissOptions, UseInViewOptions };
@@ -1,7 +1,7 @@
1
- import { R as ReadonlyRef } from './utils-IKPG3zcC.js';
2
- export { S as SlotContent, c as cx, r as resolveSlotContent, u as useId } from './utils-IKPG3zcC.js';
3
- import { b as PositionResult, a as PositionOptions } from './position-Cn7qP1pn.js';
4
- export { A as Align, P as Placement, R as Rect, S as Side, c as computePosition } from './position-Cn7qP1pn.js';
1
+ import { R as ReadonlyRef } from './utils-D4XwXDeX.js';
2
+ export { S as SlotContent, c as cx, r as resolveSlotContent, u as useId } from './utils-D4XwXDeX.js';
3
+ import { b as PositionResult, a as PositionOptions } from './position-CiY171HP.js';
4
+ export { A as Align, P as Placement, R as Rect, S as Side, c as computePosition } from './position-CiY171HP.js';
5
5
  import { ComputedRef, Ref, ShallowRef } from 'vue';
6
6
  import * as _ansh_ui_core from '@ansh-ui/core';
7
7
  import { BudgetReport, PointerState, ScrollTrackOptions, ScrollProgress, FrameState, MotionValue, AnimationOptions, SpringOptions } from '@ansh-ui/core';
@@ -297,4 +297,5 @@ declare function useAnimate(): <T>(from: T | MotionValue<T>, to: T | readonly T[
297
297
  */
298
298
  declare function useAnimatedFrom<Source, T>(source: Ref<Source>, target: MotionValue<T>, map: (value: Source) => T, options?: AnimationOptions<T>): void;
299
299
 
300
- export { type AnchoredPosition, type AnchoredPositionOptions, type DismissOptions, PositionOptions, PositionResult, ReadonlyRef, type UseInViewOptions, getLayerStack, getTabbable, useAnchoredPosition, useAnimate, useAnimatedFrom, useAutoFocus, useControllableState, useDismiss, useElementSize, useFocusRestore, useFocusTrap, useFrameBudget, useInView, useMotionRef, useMotionStyle, useMotionValue, usePointer, usePresence, useReducedMotion, useRovingFocus, useScrollLock, useScrollProgress, useSpringValue, useTicker, useWindowScroll };
300
+ export { PositionOptions, PositionResult, ReadonlyRef, getLayerStack, getTabbable, useAnchoredPosition, useAnimate, useAnimatedFrom, useAutoFocus, useControllableState, useDismiss, useElementSize, useFocusRestore, useFocusTrap, useFrameBudget, useInView, useMotionRef, useMotionStyle, useMotionValue, usePointer, usePresence, useReducedMotion, useRovingFocus, useScrollLock, useScrollProgress, useSpringValue, useTicker, useWindowScroll };
301
+ export type { AnchoredPosition, AnchoredPositionOptions, DismissOptions, UseInViewOptions };
@@ -1,6 +1,6 @@
1
1
  export { usePresence } from './chunk-6XJOB6LE.js';
2
2
  export { computePosition, getLayerStack, useAnchoredPosition, useDismiss, useScrollLock } from './chunk-XZ5ZFLZM.js';
3
- export { getTabbable, useAutoFocus, useFocusRestore, useFocusTrap, useRovingFocus } from './chunk-TMG3M6TK.js';
3
+ export { getTabbable, useAutoFocus, useFocusRestore, useFocusTrap, useRovingFocus } from './chunk-G2OX2NH2.js';
4
4
  export { useControllableState } from './chunk-OAQ7MDYX.js';
5
5
  export { useAnimate, useAnimatedFrom, useElementSize, useFrameBudget, useInView, useMotionRef, useMotionStyle, useMotionValue, usePointer, useReducedMotion, useScrollProgress, useSpringValue, useTicker, useWindowScroll } from './chunk-EVO23GUS.js';
6
6
  export { cx, resolveSlotContent, useId } from './chunk-NJDDNO4C.js';
@@ -1,6 +1,6 @@
1
1
  import * as vue from 'vue';
2
2
  import { VNode, PropType } from 'vue';
3
- import { S as SlotContent } from './utils-IKPG3zcC.js';
3
+ import { S as SlotContent } from './utils-D4XwXDeX.cjs';
4
4
 
5
5
  interface NavItem {
6
6
  id: string;
@@ -65,7 +65,7 @@ declare const Sidebar: vue.DefineComponent<vue.ExtractPropTypes<{
65
65
  };
66
66
  }>, () => VNode<vue.RendererNode, vue.RendererElement, {
67
67
  [key: string]: any;
68
- }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("navigate" | "update:collapsed")[], "navigate" | "update:collapsed", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
68
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("update:collapsed" | "navigate")[], "update:collapsed" | "navigate", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
69
69
  sections: {
70
70
  type: PropType<readonly NavSection[]>;
71
71
  required: true;
@@ -94,8 +94,8 @@ declare const Sidebar: vue.DefineComponent<vue.ExtractPropTypes<{
94
94
  default: string;
95
95
  };
96
96
  }>> & Readonly<{
97
- onNavigate?: ((...args: any[]) => any) | undefined;
98
97
  "onUpdate:collapsed"?: ((...args: any[]) => any) | undefined;
98
+ onNavigate?: ((...args: any[]) => any) | undefined;
99
99
  }>, {
100
100
  label: string;
101
101
  activeId: string;
@@ -121,4 +121,5 @@ declare const AppShell: vue.DefineComponent<{}, () => VNode<vue.RendererNode, vu
121
121
  [key: string]: any;
122
122
  }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
123
123
 
124
- export { AppShell as A, type NavItem as N, Sidebar as S, type NavSection as a };
124
+ export { AppShell as A, Sidebar as S };
125
+ export type { NavItem as N, NavSection as a };
@@ -1,6 +1,6 @@
1
1
  import * as vue from 'vue';
2
2
  import { VNode, PropType } from 'vue';
3
- import { S as SlotContent } from './utils-IKPG3zcC.cjs';
3
+ import { S as SlotContent } from './utils-D4XwXDeX.js';
4
4
 
5
5
  interface NavItem {
6
6
  id: string;
@@ -65,7 +65,7 @@ declare const Sidebar: vue.DefineComponent<vue.ExtractPropTypes<{
65
65
  };
66
66
  }>, () => VNode<vue.RendererNode, vue.RendererElement, {
67
67
  [key: string]: any;
68
- }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("navigate" | "update:collapsed")[], "navigate" | "update:collapsed", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
68
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("update:collapsed" | "navigate")[], "update:collapsed" | "navigate", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
69
69
  sections: {
70
70
  type: PropType<readonly NavSection[]>;
71
71
  required: true;
@@ -94,8 +94,8 @@ declare const Sidebar: vue.DefineComponent<vue.ExtractPropTypes<{
94
94
  default: string;
95
95
  };
96
96
  }>> & Readonly<{
97
- onNavigate?: ((...args: any[]) => any) | undefined;
98
97
  "onUpdate:collapsed"?: ((...args: any[]) => any) | undefined;
98
+ onNavigate?: ((...args: any[]) => any) | undefined;
99
99
  }>, {
100
100
  label: string;
101
101
  activeId: string;
@@ -121,4 +121,5 @@ declare const AppShell: vue.DefineComponent<{}, () => VNode<vue.RendererNode, vu
121
121
  [key: string]: any;
122
122
  }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
123
123
 
124
- export { AppShell as A, type NavItem as N, Sidebar as S, type NavSection as a };
124
+ export { AppShell as A, Sidebar as S };
125
+ export type { NavItem as N, NavSection as a };
package/dist/styles.css CHANGED
@@ -1312,6 +1312,353 @@
1312
1312
  }
1313
1313
  }
1314
1314
 
1315
+ /* ==========================================================================
1316
+ Motion UI — presentation components with motion of their own.
1317
+
1318
+ Split out of `components.css`, which is already ~830 lines. Everything here targets a plain
1319
+ `ansh-*` class or a `data-*` attribute and contains nothing React-specific, so it is shared
1320
+ verbatim with `@ansh-ui/vue`'s build the same way every other stylesheet in this directory is.
1321
+ ========================================================================== */
1322
+
1323
+ /* --- Rotating headline word ---------------------------------------------- */
1324
+
1325
+ /*
1326
+ * Deliberately NOT `overflow: hidden` on this element. An inline-level box with clipped overflow
1327
+ * is baseline-aligned by its bottom margin edge rather than by its text, which drops the rotating
1328
+ * word below the line of the sentence containing it. The clipping happens on `__clip` instead,
1329
+ * which is absolutely positioned and so takes no part in baseline alignment.
1330
+ */
1331
+ .ansh-rotate {
1332
+ position: relative;
1333
+ display: inline-block;
1334
+ }
1335
+
1336
+ /*
1337
+ * The width and baseline holder, in normal flow. `visibility: hidden` rather than `display: none`
1338
+ * — a display-none element contributes no size, which would defeat the point of measuring the
1339
+ * longest word.
1340
+ */
1341
+ .ansh-rotate__sizer {
1342
+ display: grid;
1343
+ grid-template-areas: 'word';
1344
+ visibility: hidden;
1345
+ pointer-events: none;
1346
+ }
1347
+
1348
+ .ansh-rotate__ghost {
1349
+ grid-area: word;
1350
+ white-space: nowrap;
1351
+ }
1352
+
1353
+ .ansh-rotate__clip {
1354
+ position: absolute;
1355
+ inset: 0;
1356
+ overflow: hidden;
1357
+ }
1358
+
1359
+ .ansh-rotate__word {
1360
+ display: inline-block;
1361
+ white-space: nowrap;
1362
+ will-change: transform, opacity;
1363
+ }
1364
+
1365
+ .ansh-rotate[data-animation='slide'] .ansh-rotate__word {
1366
+ animation: ansh-rotate-slide var(--ansh-duration-slow, 420ms) var(--ansh-ease-emphasized) both;
1367
+ }
1368
+
1369
+ .ansh-rotate[data-animation='fade'] .ansh-rotate__word {
1370
+ animation: ansh-rotate-fade var(--ansh-duration-slow, 420ms) var(--ansh-ease-standard) both;
1371
+ }
1372
+
1373
+ .ansh-rotate[data-animation='flip'] .ansh-rotate__word {
1374
+ animation: ansh-rotate-flip var(--ansh-duration-slow, 420ms) var(--ansh-ease-emphasized) both;
1375
+ transform-origin: 50% 0;
1376
+ }
1377
+
1378
+ @keyframes ansh-rotate-slide {
1379
+ from {
1380
+ transform: translateY(100%);
1381
+ opacity: 0;
1382
+ }
1383
+ to {
1384
+ transform: translateY(0);
1385
+ opacity: 1;
1386
+ }
1387
+ }
1388
+
1389
+ @keyframes ansh-rotate-fade {
1390
+ from {
1391
+ opacity: 0;
1392
+ }
1393
+ to {
1394
+ opacity: 1;
1395
+ }
1396
+ }
1397
+
1398
+ @keyframes ansh-rotate-flip {
1399
+ from {
1400
+ transform: rotateX(-90deg);
1401
+ opacity: 0;
1402
+ }
1403
+ to {
1404
+ transform: rotateX(0);
1405
+ opacity: 1;
1406
+ }
1407
+ }
1408
+
1409
+ /* --- Before/after comparison --------------------------------------------- */
1410
+
1411
+ .ansh-compare {
1412
+ position: relative;
1413
+ overflow: hidden;
1414
+ border-radius: var(--ansh-radius-lg);
1415
+ /* Without this a drag that starts on the surface scrolls the page on touch instead of moving
1416
+ the divider — the single most common defect in comparison sliders on mobile. */
1417
+ touch-action: none;
1418
+ user-select: none;
1419
+ }
1420
+
1421
+ .ansh-compare__layer {
1422
+ position: absolute;
1423
+ inset: 0;
1424
+ }
1425
+
1426
+ .ansh-compare__layer > * {
1427
+ width: 100%;
1428
+ height: 100%;
1429
+ }
1430
+
1431
+ /*
1432
+ * The revealed layer sits above and is clipped. Clipping rather than resizing is what keeps its
1433
+ * contents from reflowing as the handle moves.
1434
+ */
1435
+ .ansh-compare__layer--before {
1436
+ z-index: 1;
1437
+ }
1438
+
1439
+ .ansh-compare__handle {
1440
+ position: absolute;
1441
+ top: 0;
1442
+ bottom: 0;
1443
+ z-index: 2;
1444
+ width: 2px;
1445
+ margin-left: -1px;
1446
+ background: var(--ansh-content-primary);
1447
+ cursor: ew-resize;
1448
+ touch-action: none;
1449
+ }
1450
+
1451
+ .ansh-compare__handle:focus-visible {
1452
+ outline: 2px solid var(--ansh-border-focus);
1453
+ outline-offset: 2px;
1454
+ }
1455
+
1456
+ .ansh-compare__grip {
1457
+ position: absolute;
1458
+ top: 50%;
1459
+ left: 50%;
1460
+ width: 2.25rem;
1461
+ height: 2.25rem;
1462
+ transform: translate(-50%, -50%);
1463
+ border-radius: var(--ansh-radius-full);
1464
+ background: var(--ansh-content-primary);
1465
+ box-shadow: var(--ansh-shadow-lg);
1466
+ }
1467
+
1468
+ /* The double chevron, drawn with borders so no icon asset or SVG is needed. */
1469
+ .ansh-compare__grip::before,
1470
+ .ansh-compare__grip::after {
1471
+ content: '';
1472
+ position: absolute;
1473
+ top: 50%;
1474
+ width: 0.4rem;
1475
+ height: 0.4rem;
1476
+ border-top: 2px solid var(--ansh-surface-canvas);
1477
+ border-right: 2px solid var(--ansh-surface-canvas);
1478
+ }
1479
+
1480
+ .ansh-compare__grip::before {
1481
+ left: 30%;
1482
+ transform: translate(0, -50%) rotate(-135deg);
1483
+ }
1484
+
1485
+ .ansh-compare__grip::after {
1486
+ right: 30%;
1487
+ transform: translate(0, -50%) rotate(45deg);
1488
+ }
1489
+
1490
+ .ansh-compare[data-dragging] {
1491
+ cursor: ew-resize;
1492
+ }
1493
+
1494
+ /* --- Device / browser mockup --------------------------------------------- */
1495
+
1496
+ .ansh-mock {
1497
+ display: flex;
1498
+ flex-direction: column;
1499
+ overflow: hidden;
1500
+ background: var(--ansh-surface-raised);
1501
+ border: 1px solid var(--ansh-border-default);
1502
+ box-shadow: var(--ansh-shadow-lg);
1503
+ }
1504
+
1505
+ .ansh-mock--browser,
1506
+ .ansh-mock--window {
1507
+ border-radius: var(--ansh-radius-lg);
1508
+ }
1509
+
1510
+ .ansh-mock__chrome {
1511
+ display: flex;
1512
+ align-items: center;
1513
+ gap: var(--ansh-space-3);
1514
+ padding: var(--ansh-space-3) var(--ansh-space-4);
1515
+ background: var(--ansh-surface-sunken);
1516
+ border-bottom: 1px solid var(--ansh-border-subtle);
1517
+ }
1518
+
1519
+ .ansh-mock__dots {
1520
+ display: flex;
1521
+ gap: var(--ansh-space-2);
1522
+ flex-shrink: 0;
1523
+ }
1524
+
1525
+ .ansh-mock__dots i {
1526
+ width: 0.7rem;
1527
+ height: 0.7rem;
1528
+ border-radius: var(--ansh-radius-full);
1529
+ background: var(--ansh-border-strong);
1530
+ }
1531
+
1532
+ .ansh-mock__url,
1533
+ .ansh-mock__title {
1534
+ flex: 1;
1535
+ min-width: 0;
1536
+ overflow: hidden;
1537
+ text-overflow: ellipsis;
1538
+ white-space: nowrap;
1539
+ font-size: var(--ansh-text-xs);
1540
+ color: var(--ansh-content-tertiary);
1541
+ }
1542
+
1543
+ .ansh-mock__url {
1544
+ padding: var(--ansh-space-1) var(--ansh-space-3);
1545
+ border-radius: var(--ansh-radius-full);
1546
+ background: var(--ansh-surface-raised);
1547
+ font-family: var(--ansh-font-mono);
1548
+ }
1549
+
1550
+ .ansh-mock__title {
1551
+ text-align: center;
1552
+ }
1553
+
1554
+ .ansh-mock__screen {
1555
+ flex: 1;
1556
+ min-height: 0;
1557
+ overflow: hidden;
1558
+ background: var(--ansh-surface-canvas);
1559
+ }
1560
+
1561
+ /* The phone frame: a thick bezel and a notch, no chrome bar. */
1562
+ .ansh-mock--phone {
1563
+ border-radius: 2.25rem;
1564
+ border-width: 0.6rem;
1565
+ border-color: var(--ansh-content-primary);
1566
+ padding: 0;
1567
+ position: relative;
1568
+ }
1569
+
1570
+ .ansh-mock--phone .ansh-mock__screen {
1571
+ border-radius: 1.7rem;
1572
+ }
1573
+
1574
+ .ansh-mock__notch {
1575
+ position: absolute;
1576
+ top: 0;
1577
+ left: 50%;
1578
+ transform: translateX(-50%);
1579
+ z-index: 2;
1580
+ width: 38%;
1581
+ height: 1.1rem;
1582
+ border-radius: 0 0 var(--ansh-radius-lg) var(--ansh-radius-lg);
1583
+ background: var(--ansh-content-primary);
1584
+ }
1585
+
1586
+ /* --- Card stack ----------------------------------------------------------- */
1587
+
1588
+ .ansh-stack {
1589
+ display: flex;
1590
+ flex-direction: column;
1591
+ gap: var(--ansh-space-4);
1592
+ }
1593
+
1594
+ .ansh-stack__deck {
1595
+ position: relative;
1596
+ display: grid;
1597
+ /* One cell: every card stacks in it, and the tallest card sets the height so the deck does not
1598
+ resize as cards advance. */
1599
+ grid-template-areas: 'card';
1600
+ isolation: isolate;
1601
+ }
1602
+
1603
+ .ansh-stack__card {
1604
+ grid-area: card;
1605
+ transition:
1606
+ transform var(--ansh-duration-slow, 420ms) var(--ansh-ease-emphasized),
1607
+ opacity var(--ansh-duration-slow, 420ms) var(--ansh-ease-standard);
1608
+ will-change: transform, opacity;
1609
+ }
1610
+
1611
+ .ansh-stack__controls {
1612
+ display: flex;
1613
+ align-items: center;
1614
+ justify-content: center;
1615
+ gap: var(--ansh-space-3);
1616
+ }
1617
+
1618
+ .ansh-stack__button {
1619
+ display: grid;
1620
+ place-items: center;
1621
+ width: 2rem;
1622
+ height: 2rem;
1623
+ border-radius: var(--ansh-radius-full);
1624
+ border: 1px solid var(--ansh-border-default);
1625
+ background: var(--ansh-surface-raised);
1626
+ color: var(--ansh-content-secondary);
1627
+ font: inherit;
1628
+ font-size: var(--ansh-text-lg);
1629
+ line-height: 1;
1630
+ cursor: pointer;
1631
+ }
1632
+
1633
+ .ansh-stack__button:hover {
1634
+ border-color: var(--ansh-border-strong);
1635
+ color: var(--ansh-content-primary);
1636
+ }
1637
+
1638
+ .ansh-stack__count {
1639
+ font-family: var(--ansh-font-mono);
1640
+ font-size: var(--ansh-text-xs);
1641
+ color: var(--ansh-content-tertiary);
1642
+ min-width: 3.5rem;
1643
+ text-align: center;
1644
+ }
1645
+
1646
+ /*
1647
+ * Reduced motion. The library's kernel handles JS-driven motion, but these components animate in
1648
+ * CSS, so they need their own guard — `@ansh-ui/tokens` neutralises durations globally, and this
1649
+ * additionally removes the transform travel so cards and words change in place rather than
1650
+ * snapping across a distance in 0.01ms.
1651
+ */
1652
+ @media (prefers-reduced-motion: reduce) {
1653
+ .ansh-rotate__word {
1654
+ animation: none !important;
1655
+ }
1656
+
1657
+ .ansh-stack__card {
1658
+ transition: none !important;
1659
+ }
1660
+ }
1661
+
1315
1662
  /* ==========================================================================
1316
1663
  Forms
1317
1664
  ========================================================================== */
@@ -5381,6 +5728,123 @@ button.ansh-stepper__button:hover {
5381
5728
  text-underline-offset: 2px;
5382
5729
  }
5383
5730
 
5731
+ /* --- Carousel ------------------------------------------------------------- */
5732
+
5733
+ .ansh-carousel {
5734
+ position: relative;
5735
+ display: flex;
5736
+ flex-direction: column;
5737
+ gap: var(--ansh-space-3);
5738
+ }
5739
+
5740
+ .ansh-carousel__viewport {
5741
+ position: relative;
5742
+ overflow: hidden;
5743
+ border-radius: var(--ansh-radius-lg);
5744
+ /* Without this a horizontal drag scrolls the page on touch instead of moving the track — the
5745
+ same defect the comparison slider guards against. */
5746
+ touch-action: pan-y;
5747
+ }
5748
+
5749
+ .ansh-carousel__track {
5750
+ display: flex;
5751
+ transition: transform var(--ansh-duration-slow, 420ms) var(--ansh-ease-emphasized);
5752
+ will-change: transform;
5753
+ }
5754
+
5755
+ .ansh-carousel__slide {
5756
+ /* `flex: 0 0 100%` rather than `width: 100%`: flex items shrink by default, so eight slides in a
5757
+ row would each collapse to an eighth of the viewport instead of queueing beside it. */
5758
+ flex: 0 0 100%;
5759
+ min-width: 0;
5760
+ }
5761
+
5762
+ .ansh-carousel__viewport[data-dragging] {
5763
+ cursor: grabbing;
5764
+ }
5765
+
5766
+ .ansh-carousel__arrow {
5767
+ position: absolute;
5768
+ top: calc(50% - 1.25rem);
5769
+ display: grid;
5770
+ place-items: center;
5771
+ width: 2.5rem;
5772
+ height: 2.5rem;
5773
+ border-radius: var(--ansh-radius-full);
5774
+ border: 1px solid var(--ansh-border-default);
5775
+ background: var(--ansh-surface-overlay);
5776
+ color: var(--ansh-content-primary);
5777
+ font: inherit;
5778
+ font-size: var(--ansh-text-xl);
5779
+ line-height: 1;
5780
+ cursor: pointer;
5781
+ }
5782
+
5783
+ .ansh-carousel__arrow:hover:not(:disabled) {
5784
+ border-color: var(--ansh-border-strong);
5785
+ }
5786
+
5787
+ .ansh-carousel__arrow:disabled {
5788
+ opacity: 0.4;
5789
+ cursor: default;
5790
+ }
5791
+
5792
+ .ansh-carousel__arrow--prev {
5793
+ left: var(--ansh-space-3);
5794
+ }
5795
+
5796
+ .ansh-carousel__arrow--next {
5797
+ right: var(--ansh-space-3);
5798
+ }
5799
+
5800
+ .ansh-carousel__controls {
5801
+ display: flex;
5802
+ align-items: center;
5803
+ justify-content: center;
5804
+ gap: var(--ansh-space-3);
5805
+ }
5806
+
5807
+ .ansh-carousel__dots {
5808
+ display: flex;
5809
+ gap: var(--ansh-space-2);
5810
+ }
5811
+
5812
+ .ansh-carousel__dot {
5813
+ width: 0.5rem;
5814
+ height: 0.5rem;
5815
+ padding: 0;
5816
+ border: 0;
5817
+ border-radius: var(--ansh-radius-full);
5818
+ background: var(--ansh-border-strong);
5819
+ cursor: pointer;
5820
+ transition: background-color var(--ansh-duration-fast) var(--ansh-ease-standard);
5821
+ }
5822
+
5823
+ .ansh-carousel__dot[aria-current] {
5824
+ background: var(--ansh-accent-default);
5825
+ }
5826
+
5827
+ .ansh-carousel__pause {
5828
+ display: grid;
5829
+ place-items: center;
5830
+ min-width: 1.75rem;
5831
+ height: 1.75rem;
5832
+ padding: 0 var(--ansh-space-2);
5833
+ border-radius: var(--ansh-radius-full);
5834
+ border: 1px solid var(--ansh-border-default);
5835
+ background: transparent;
5836
+ color: var(--ansh-content-secondary);
5837
+ font: inherit;
5838
+ font-size: var(--ansh-text-xs);
5839
+ cursor: pointer;
5840
+ }
5841
+
5842
+ @media (prefers-reduced-motion: reduce) {
5843
+ .ansh-carousel__track {
5844
+ transition: none !important;
5845
+ }
5846
+ }
5847
+
5384
5848
  /* ==========================================================================
5385
5849
  Feedback — alerts, banners, callouts
5386
5850
  ========================================================================== */
@@ -43,4 +43,5 @@ declare function cx(...parts: Array<string | false | null | undefined>): string;
43
43
  */
44
44
  declare function useId(prefix?: string): string;
45
45
 
46
- export { type ReadonlyRef as R, type SlotContent as S, cx as c, resolveSlotContent as r, useId as u };
46
+ export { cx as c, resolveSlotContent as r, useId as u };
47
+ export type { ReadonlyRef as R, SlotContent as S };
@@ -43,4 +43,5 @@ declare function cx(...parts: Array<string | false | null | undefined>): string;
43
43
  */
44
44
  declare function useId(prefix?: string): string;
45
45
 
46
- export { type ReadonlyRef as R, type SlotContent as S, cx as c, resolveSlotContent as r, useId as u };
46
+ export { cx as c, resolveSlotContent as r, useId as u };
47
+ export type { ReadonlyRef as R, SlotContent as S };