@nebutra/ui 0.2.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/animate-in-BlvjVh2S.d.ts +250 -0
  2. package/dist/{canonical-CrO71UPO.d.ts → canonical-Bf4czR2u.d.ts} +225 -211
  3. package/dist/chat/index.d.ts +1 -0
  4. package/dist/chat/index.js +3 -0
  5. package/dist/chat/index.js.map +1 -0
  6. package/dist/components/index.d.ts +58 -123
  7. package/dist/components/index.js +504 -203
  8. package/dist/components/index.js.map +1 -1
  9. package/dist/editorial/index.d.ts +404 -0
  10. package/dist/editorial/index.js +868 -0
  11. package/dist/editorial/index.js.map +1 -0
  12. package/dist/icons/index.d.ts +1 -0
  13. package/dist/layout/index.d.ts +2 -2
  14. package/dist/layout/index.js +116 -26
  15. package/dist/layout/index.js.map +1 -1
  16. package/dist/layouts/index.d.ts +80 -2
  17. package/dist/layouts/index.js +13 -11
  18. package/dist/layouts/index.js.map +1 -1
  19. package/dist/patterns/index.d.ts +4 -5
  20. package/dist/patterns/index.js +221 -106
  21. package/dist/patterns/index.js.map +1 -1
  22. package/dist/primitives/canonical.d.ts +4 -3
  23. package/dist/primitives/canonical.js +609 -197
  24. package/dist/primitives/canonical.js.map +1 -1
  25. package/dist/primitives/index.d.ts +213 -21
  26. package/dist/primitives/index.js +2209 -1317
  27. package/dist/primitives/index.js.map +1 -1
  28. package/dist/tailwind.preset.d.ts +2 -2
  29. package/dist/tailwind.preset.js +1 -1
  30. package/dist/tailwind.preset.js.map +1 -1
  31. package/dist/typography/fonts.css +21 -26
  32. package/dist/typography/index.d.ts +4 -4
  33. package/dist/typography/index.js +1 -1
  34. package/dist/typography/index.js.map +1 -1
  35. package/dist/utils/auth-surfaces.d.ts +33 -0
  36. package/dist/utils/auth-surfaces.js +9 -0
  37. package/dist/utils/auth-surfaces.js.map +1 -0
  38. package/dist/utils/index.d.ts +33 -5
  39. package/dist/utils/index.js +15 -3
  40. package/dist/utils/index.js.map +1 -1
  41. package/package.json +43 -9
  42. package/src/styles/sources.css +10 -0
  43. package/src/typography/fonts.css +21 -26
@@ -1,8 +1,4 @@
1
1
  "use client";
2
- import { Button as Button$1 } from '@lobehub/ui';
3
- export { ActionIcon, ActionIconGroup, Alert, Avatar, Button, Checkbox, DraggablePanel, DraggablePanelBody, DraggablePanelContainer, DraggablePanelFooter, DraggablePanelHeader, Flexbox, Form, FormGroup, FormItem, Highlighter, Image, Input, List, Markdown, Menu, Modal, SearchBar, Segmented, Select, SideNav, Tag, TextArea, Tooltip } from '@lobehub/ui';
4
- export { ChatInputArea, ChatItem, ChatList, MessageInput, MessageModal } from '@lobehub/ui/chat';
5
- export { default as Spotlight } from '@lobehub/ui/es/awesome/Spotlight/Spotlight';
6
2
  import { motion, AnimatePresence, useReducedMotion, m, LazyMotion, domAnimation } from 'framer-motion';
7
3
  export { AnimatePresence, LayoutGroup, LazyMotion, MotionConfig, animate, domAnimation, m, motion, useAnimationFrame, useInView, useMotionTemplate, useMotionValue, useReducedMotion, useScroll, useSpring, useTransform, useVelocity } from 'framer-motion';
8
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -11,18 +7,19 @@ import Image from 'next/image';
11
7
  import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
12
8
  import * as React5 from 'react';
13
9
  import React5__default, { useEffectEvent, useId, useState } from 'react';
14
- import { colors, emerge, flow, brandSpring } from '@nebutra/brand';
10
+ import { colors, brandSpring, flow, emerge } from '@nebutra/brand';
15
11
  import { clsx } from 'clsx';
16
12
  import { twMerge } from 'tailwind-merge';
17
13
  import { cva } from 'class-variance-authority';
18
14
  import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
19
15
  import { useAsciiText, slant } from 'react-ascii-text';
16
+ import { Popover as Popover$1 } from '@base-ui/react/popover';
20
17
  import { ReactFlowProvider, ReactFlow, Background, Controls, Panel, Handle, Position } from '@xyflow/react';
21
18
  import '@xyflow/react/dist/style.css';
22
19
  import { wouldCreateCycle } from '@nebutra/graph-model';
23
20
  import { Input as Input$1 } from '@base-ui/react/input';
24
21
 
25
- // src/components/index.ts
22
+ // src/shared/animation/motion/index.ts
26
23
 
27
24
  // src/shared/animation/motion/tokens.ts
28
25
  var animationDurations = {
@@ -298,41 +295,52 @@ var primitiveFontSize = {
298
295
  // src/tokens/shadows.ts
299
296
  var shadowClasses = {
300
297
  md: "shadow-md",
298
+ xl: "shadow-xl",
301
299
  "2xl": "shadow-2xl"};
302
300
 
303
301
  // src/tokens/components/overlay.ts
304
- var overlayFocusRingClassName = "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2";
302
+ var overlayFocusRingClassName = "outline-none";
305
303
  var overlayZIndex = {
306
304
  backdrop: 1040,
307
305
  modal: 1050,
306
+ popover: 1060,
308
307
  tooltip: 1070
309
308
  };
310
309
  var overlayClassNames = {
311
- backdrop: "fixed inset-0 bg-black/40 backdrop-blur-sm transition-[opacity,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)] data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none",
310
+ backdrop: "fixed inset-0 bg-black/40 backdrop-blur-sm transition-[opacity,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)] data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none",
312
311
  modalSurface: [
313
312
  "fixed left-1/2 top-1/2 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4",
314
313
  "border border-border/60 bg-background/95 p-6 text-foreground backdrop-blur-xl",
315
314
  "rounded-[var(--radius-xl)]",
316
315
  shadowClasses["2xl"],
317
316
  "outline-none",
318
- "transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)]",
317
+ "transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)]",
319
318
  "data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0",
320
319
  "motion-reduce:transition-none motion-reduce:data-starting-style:transform-none motion-reduce:data-ending-style:transform-none"
321
320
  ].join(" "),
321
+ popoverSurface: [
322
+ "w-72 origin-[var(--transform-origin)] rounded-[var(--radius-lg)] border border-border/70 bg-popover/95 p-4 text-popover-foreground backdrop-blur-md",
323
+ shadowClasses.xl,
324
+ "outline-none transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)]",
325
+ "data-[open]:opacity-100 data-[closed]:opacity-0 data-[closed]:scale-[0.97] data-[open]:scale-100",
326
+ "motion-reduce:transition-none motion-reduce:data-[closed]:transform-none motion-reduce:data-[open]:transform-none"
327
+ ].join(" "),
322
328
  tooltipSurface: [
323
- "overflow-hidden rounded-[var(--radius-md)] border border-border/70 bg-popover/95 px-3 py-1.5 text-sm text-popover-foreground backdrop-blur-md",
329
+ "origin-[var(--transform-origin)] overflow-hidden rounded-[var(--radius-md)] border border-border/70 bg-popover/95 px-3 py-1.5 text-sm text-popover-foreground backdrop-blur-md",
324
330
  shadowClasses.md,
325
- "transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)]",
326
- "data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0",
331
+ "transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)]",
332
+ "data-starting-style:scale-[0.97] data-starting-style:opacity-0 data-ending-style:scale-[0.97] data-ending-style:opacity-0",
333
+ "data-[instant]:duration-0",
327
334
  "motion-reduce:transition-none motion-reduce:data-starting-style:transform-none motion-reduce:data-ending-style:transform-none"
328
335
  ].join(" "),
329
- closeButton: `absolute right-4 top-4 rounded-[var(--radius-sm)] opacity-70 ring-offset-background ${overlayFocusRingClassName} transition-opacity duration-[var(--motion-duration-micro)] ease-[var(--ease-out)] hover:opacity-100 disabled:pointer-events-none data-[open]:bg-accent data-[open]:text-muted-foreground motion-reduce:transition-none`
336
+ closeButton: `absolute right-4 top-4 rounded-[var(--radius-sm)] opacity-70 ring-offset-background ${overlayFocusRingClassName} transition-opacity duration-[var(--motion-duration-micro)] ease-[var(--ease-brand)] hover:opacity-100 disabled:pointer-events-none data-[open]:bg-accent data-[open]:text-muted-foreground motion-reduce:transition-none`
330
337
  };
331
338
  function cn(...inputs) {
332
339
  return twMerge(clsx(inputs));
333
340
  }
334
341
  var overlayPrimitiveClassNames = {
335
- modalSurface: "rounded-[var(--radius-md)] border-border/70 bg-popover/95 text-popover-foreground shadow-xl"};
342
+ modalSurface: "rounded-[var(--radius-md)] border-border/70 bg-popover/95 text-popover-foreground shadow-xl",
343
+ popoverSurface: "rounded-[var(--radius-md)] border-border/70 bg-popover/95 shadow-md"};
336
344
  var Dialog = Dialog$1.Root;
337
345
  var DialogPortal = Dialog$1.Portal;
338
346
  var DialogTrigger = ({
@@ -549,8 +557,8 @@ var buttonVariants = cva(
549
557
  "inline-flex items-center justify-center gap-2 whitespace-nowrap",
550
558
  "rounded-[var(--btn-default-radius,var(--radius-md))]",
551
559
  "text-[length:var(--control-font-size-md,0.875rem)] font-[number:var(--font-weight-medium,500)]",
552
- "transition-colors duration-micro ease-out",
553
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
560
+ "transition-[color,background-color,border-color,transform] duration-flow ease-[var(--ease-brand)]",
561
+ "active:scale-[0.97] motion-reduce:active:scale-100 motion-reduce:transition-none",
554
562
  "disabled:pointer-events-none disabled:opacity-50",
555
563
  "aria-busy:cursor-wait"
556
564
  ].join(" "),
@@ -577,8 +585,30 @@ var buttonVariants = cva(
577
585
  },
578
586
  shape: {
579
587
  default: "",
580
- square: "",
581
- circle: ""
588
+ // Radius from --btn-default-radius / --radius-md — brand-switchable.
589
+ // Do not hardcode rounded-md here; a language must be able to retarget
590
+ // the corner treatment of every icon trigger at once.
591
+ square: "rounded-[var(--btn-default-radius,var(--radius-md))]",
592
+ // Pill radius token, not Tailwind rounded-full — same 9999px default,
593
+ // but a brand that ships a softer "circle" can override --radius-pill.
594
+ circle: "rounded-[var(--radius-pill,9999px)]",
595
+ pill: "rounded-[var(--radius-pill,9999px)]"
596
+ },
597
+ // Icon-only box size — orthogonal to `size` (which tunes text-button
598
+ // height/padding/font together) and to `shape` (which picks the
599
+ // corner treatment). Only takes effect combined with shape="square"
600
+ // or shape="circle" (see compoundVariants below); every other
601
+ // combination ignores it. 28/32/36 cover the icon-trigger sizes that
602
+ // actually occur in the app — 24/40/48 are already reachable via
603
+ // shape + size (tiny/default/lg). Heights read --control-height-icon-*
604
+ // so density-aware Brand Packages can scale them with the ladder.
605
+ iconSize: {
606
+ sm: "",
607
+ // 28px default
608
+ md: "",
609
+ // 32px default
610
+ lg: ""
611
+ // 36px default
582
612
  }
583
613
  },
584
614
  compoundVariants: [
@@ -589,22 +619,56 @@ var buttonVariants = cva(
589
619
  {
590
620
  shape: "circle",
591
621
  size: "tiny",
592
- className: "w-[var(--control-height-tiny,1.5rem)] px-0 rounded-full"
622
+ className: "w-[var(--control-height-tiny,1.5rem)] px-0"
593
623
  },
594
624
  {
595
625
  shape: "circle",
596
626
  size: "sm",
597
- className: "w-[var(--control-height-sm,2rem)] px-0 rounded-full"
627
+ className: "w-[var(--control-height-sm,2rem)] px-0"
598
628
  },
599
629
  {
600
630
  shape: "circle",
601
631
  size: "default",
602
- className: "w-[var(--control-height-md,2.5rem)] px-0 rounded-full"
632
+ className: "w-[var(--control-height-md,2.5rem)] px-0"
603
633
  },
604
634
  {
605
635
  shape: "circle",
606
636
  size: "lg",
607
- className: "w-[var(--control-height-lg,3rem)] px-0 rounded-full"
637
+ className: "w-[var(--control-height-lg,3rem)] px-0"
638
+ },
639
+ // iconSize wins over the size-driven box above — matched on shape +
640
+ // iconSize only, so it applies regardless of whatever `size` was
641
+ // passed (or left at its "default" fallback). Corner treatment stays
642
+ // on the shape variant (token-backed); only the box is set here.
643
+ {
644
+ shape: "square",
645
+ iconSize: "sm",
646
+ className: "h-[var(--control-height-icon-sm,1.75rem)] w-[var(--control-height-icon-sm,1.75rem)] px-0"
647
+ },
648
+ {
649
+ shape: "square",
650
+ iconSize: "md",
651
+ className: "h-[var(--control-height-icon-md,2rem)] w-[var(--control-height-icon-md,2rem)] px-0"
652
+ },
653
+ {
654
+ shape: "square",
655
+ iconSize: "lg",
656
+ className: "h-[var(--control-height-icon-lg,2.25rem)] w-[var(--control-height-icon-lg,2.25rem)] px-0"
657
+ },
658
+ {
659
+ shape: "circle",
660
+ iconSize: "sm",
661
+ className: "h-[var(--control-height-icon-sm,1.75rem)] w-[var(--control-height-icon-sm,1.75rem)] px-0"
662
+ },
663
+ {
664
+ shape: "circle",
665
+ iconSize: "md",
666
+ className: "h-[var(--control-height-icon-md,2rem)] w-[var(--control-height-icon-md,2rem)] px-0"
667
+ },
668
+ {
669
+ shape: "circle",
670
+ iconSize: "lg",
671
+ className: "h-[var(--control-height-icon-lg,2.25rem)] w-[var(--control-height-icon-lg,2.25rem)] px-0"
608
672
  }
609
673
  ],
610
674
  defaultVariants: {
@@ -626,7 +690,10 @@ function Spinner({ className }) {
626
690
  }
627
691
  );
628
692
  }
629
- function getIconSizeClass(size) {
693
+ function getIconSizeClass(size, iconSize) {
694
+ if (iconSize === "sm") return "[&>svg]:size-3.5";
695
+ if (iconSize === "md") return "[&>svg]:size-3.5";
696
+ if (iconSize === "lg") return "[&>svg]:size-4";
630
697
  switch (size) {
631
698
  case "tiny":
632
699
  return "[&>svg]:size-3";
@@ -641,7 +708,10 @@ function getIconSizeClass(size) {
641
708
  return "[&>svg]:size-4";
642
709
  }
643
710
  }
644
- function getSpinnerSizeClass(size) {
711
+ function getSpinnerSizeClass(size, iconSize) {
712
+ if (iconSize === "sm") return "size-3.5";
713
+ if (iconSize === "md") return "size-3.5";
714
+ if (iconSize === "lg") return "size-4";
645
715
  switch (size) {
646
716
  case "tiny":
647
717
  return "size-3";
@@ -666,10 +736,10 @@ function resolveShadowClass(shadow) {
666
736
  const level = shadow === true ? "md" : shadow;
667
737
  return SHADOW_CLASSES[level];
668
738
  }
669
- function ButtonContent({ loading, prefix, suffix, size, children }) {
670
- const iconSizeClass = getIconSizeClass(size);
739
+ function ButtonContent({ loading, prefix, suffix, size, iconSize, children }) {
740
+ const iconSizeClass = getIconSizeClass(size, iconSize);
671
741
  return /* @__PURE__ */ jsxs(Fragment, { children: [
672
- loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size) }),
742
+ loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size, iconSize) }),
673
743
  prefix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: prefix }),
674
744
  children,
675
745
  suffix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: suffix })
@@ -680,6 +750,7 @@ var Button = ({
680
750
  variant,
681
751
  size,
682
752
  shape,
753
+ iconSize,
683
754
  asChild = false,
684
755
  loading = false,
685
756
  disabled,
@@ -697,11 +768,21 @@ var Button = ({
697
768
  Comp,
698
769
  {
699
770
  ref,
700
- className: cn(buttonVariants({ variant, size, shape }), shadowClass, className),
771
+ className: cn(buttonVariants({ variant, size, shape, iconSize }), shadowClass, className),
701
772
  disabled: isDisabled,
702
773
  "aria-busy": loading || void 0,
703
774
  ...props,
704
- children: asChild ? children : /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
775
+ children: asChild ? children : /* @__PURE__ */ jsx(
776
+ ButtonContent,
777
+ {
778
+ loading,
779
+ prefix,
780
+ suffix,
781
+ size,
782
+ iconSize,
783
+ children
784
+ }
785
+ )
705
786
  }
706
787
  );
707
788
  };
@@ -736,6 +817,12 @@ var textareaTokens = {
736
817
  focusRingWidth: 3,
737
818
  fieldGap: primitiveSpacing[2] - primitiveSpacing[1] / 2};
738
819
 
820
+ // src/utils/primitive-props.ts
821
+ function asPlainStyle(style) {
822
+ if (style == null || typeof style === "function") return {};
823
+ return style;
824
+ }
825
+
739
826
  // src/primitives/form-control.ts
740
827
  var formControlFocusClassNames = {
741
828
  input: "outline-none focus:border-ring focus:ring-[length:var(--input-focus-ring-width)] focus:ring-ring/30",
@@ -756,7 +843,7 @@ function getTextareaStyle(size, style) {
756
843
  "--textarea-focus-ring-width": `${textareaTokens.focusRingWidth}px`,
757
844
  borderRadius: "var(--textarea-radius)",
758
845
  outline: "none",
759
- ...style
846
+ ...asPlainStyle(style)
760
847
  };
761
848
  }
762
849
  function getTextareaFieldStyle() {
@@ -848,19 +935,54 @@ var Textarea = ({
848
935
  };
849
936
  Textarea.displayName = "Textarea";
850
937
  var DEFAULT_TOOLTIP_DELAY_MS = 150;
938
+ var SKIP_DELAY_WINDOW_MS = 400;
939
+ var lastTooltipOpenAt = 0;
940
+ var skipDelayListeners = /* @__PURE__ */ new Set();
941
+ function markTooltipOpened() {
942
+ lastTooltipOpenAt = Date.now();
943
+ for (const listener of skipDelayListeners) listener();
944
+ }
945
+ function shouldSkipDelay() {
946
+ return Date.now() - lastTooltipOpenAt < SKIP_DELAY_WINDOW_MS;
947
+ }
948
+ function useSkipDelay() {
949
+ const [, tick] = React5.useReducer((count) => count + 1, 0);
950
+ React5.useEffect(() => {
951
+ skipDelayListeners.add(tick);
952
+ return () => {
953
+ skipDelayListeners.delete(tick);
954
+ };
955
+ }, []);
956
+ return shouldSkipDelay();
957
+ }
958
+ var TooltipInstantContext = React5.createContext(false);
851
959
  var TooltipProvider = ({
852
960
  children,
853
961
  delayDuration = DEFAULT_TOOLTIP_DELAY_MS
854
962
  }) => {
855
- return /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay: delayDuration, children });
963
+ const skipDelay = useSkipDelay();
964
+ return /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay: skipDelay ? 0 : delayDuration, children });
856
965
  };
857
966
  var Tooltip = ({
858
967
  delayDuration,
859
968
  children,
969
+ onOpenChange,
860
970
  ...props
861
971
  }) => {
862
- const delay = delayDuration ?? DEFAULT_TOOLTIP_DELAY_MS;
863
- return /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay, children: /* @__PURE__ */ jsx(Tooltip$1.Root, { ...props, children }) });
972
+ const skipDelay = useSkipDelay();
973
+ const instant = delayDuration == null && skipDelay;
974
+ const delay = delayDuration ?? (instant ? 0 : DEFAULT_TOOLTIP_DELAY_MS);
975
+ return /* @__PURE__ */ jsx(TooltipInstantContext.Provider, { value: instant, children: /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay, children: /* @__PURE__ */ jsx(
976
+ Tooltip$1.Root,
977
+ {
978
+ ...props,
979
+ onOpenChange: (open, eventDetails) => {
980
+ if (open) markTooltipOpened();
981
+ onOpenChange?.(open, eventDetails);
982
+ },
983
+ children
984
+ }
985
+ ) }) });
864
986
  };
865
987
  var TooltipTrigger = ({
866
988
  asChild,
@@ -890,25 +1012,29 @@ var TooltipContent = ({
890
1012
  alignOffset = 0,
891
1013
  ref,
892
1014
  ...props
893
- }) => /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(
894
- Tooltip$1.Positioner,
895
- {
896
- side,
897
- align,
898
- sideOffset,
899
- alignOffset,
900
- style: { zIndex: overlayZIndex.tooltip },
901
- children: /* @__PURE__ */ jsx(
902
- Tooltip$1.Popup,
903
- {
904
- ref,
905
- className: cn(overlayClassNames.tooltipSurface, className),
906
- style: { zIndex: overlayZIndex.tooltip, ...style },
907
- ...props
908
- }
909
- )
910
- }
911
- ) });
1015
+ }) => {
1016
+ const instant = React5.use(TooltipInstantContext);
1017
+ return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(
1018
+ Tooltip$1.Positioner,
1019
+ {
1020
+ side,
1021
+ align,
1022
+ sideOffset,
1023
+ alignOffset,
1024
+ style: { zIndex: overlayZIndex.tooltip },
1025
+ children: /* @__PURE__ */ jsx(
1026
+ Tooltip$1.Popup,
1027
+ {
1028
+ ref,
1029
+ className: cn(overlayClassNames.tooltipSurface, className),
1030
+ "data-instant": instant || void 0,
1031
+ style: { zIndex: overlayZIndex.tooltip, ...style },
1032
+ ...props
1033
+ }
1034
+ )
1035
+ }
1036
+ ) });
1037
+ };
912
1038
  TooltipContent.displayName = "TooltipContent";
913
1039
  var MAX_VISUALIZER_BARS = 64;
914
1040
  var VISUALIZER_BAR_STYLES = Array.from({ length: MAX_VISUALIZER_BARS }, (_, index) => ({
@@ -1040,7 +1166,7 @@ var PromptInputTextarea = ({ className, onKeyDown, disableAutosize = false, plac
1040
1166
  onKeyDown: handleKeyDown,
1041
1167
  rows: 1,
1042
1168
  style: { "--textarea-min-height": "2rem", ...style },
1043
- className: cn("resize-none border-0 shadow-none focus-visible:ring-0", className),
1169
+ className: cn("resize-none border-0 shadow-none", className),
1044
1170
  disabled,
1045
1171
  placeholder,
1046
1172
  ...props
@@ -1240,8 +1366,8 @@ function PromptSubmitAction({
1240
1366
  variant: "default",
1241
1367
  size: "icon",
1242
1368
  className: cn(
1243
- "h-8 w-8 rounded-full transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-200",
1244
- isRecording ? "bg-transparent hover:bg-accent text-destructive hover:text-destructive/80" : hasContent ? "bg-primary hover:bg-primary/90 text-primary-foreground" : "bg-transparent hover:bg-accent text-muted-foreground hover:text-foreground"
1369
+ "h-8 w-8 rounded-full transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-micro",
1370
+ isRecording ? "bg-transparent hover:bg-accent text-destructive hover:text-destructive/80" : hasContent ? "bg-primary hover:bg-primary/90 text-primary-foreground" : "bg-transparent hover:bg-accent text-muted-foreground hover:text-accent-foreground"
1245
1371
  ),
1246
1372
  onClick: onActivate,
1247
1373
  disabled: isLoading && !hasContent,
@@ -1487,90 +1613,168 @@ var PromptInputBox = (props) => {
1487
1613
  ] });
1488
1614
  };
1489
1615
  PromptInputBox.displayName = "PromptInputBox";
1490
- var emergeTransition = {
1491
- duration: emerge.transition.duration,
1492
- ease: [0.16, 1, 0.3, 1]
1493
- };
1494
- var flowTransition = {
1495
- duration: flow.transition.duration,
1496
- ease: [0, 0, 0.2, 1]
1616
+
1617
+ // src/tokens/motion.ts
1618
+ var motionDurations = {
1619
+ /** 300ms — content unveil (slide, expand, accordion, drawer) */
1620
+ reveal: 300};
1621
+ var motionVariants = {
1622
+ fadeInUp: {
1623
+ initial: { opacity: 0, transform: "translateY(20px)" },
1624
+ animate: { opacity: 1, transform: "translateY(0px)" },
1625
+ exit: { opacity: 0, transform: "translateY(10px)" }
1626
+ },
1627
+ scaleIn: {
1628
+ initial: { opacity: 0, scale: 0.95 },
1629
+ animate: { opacity: 1, scale: 1 },
1630
+ exit: { opacity: 0, scale: 0.95 }
1631
+ }};
1632
+ var staggerContainers = {
1633
+ fast: {
1634
+ initial: {},
1635
+ animate: { transition: { staggerChildren: 0.04, delayChildren: 0 } }
1636
+ },
1637
+ normal: {
1638
+ initial: {},
1639
+ animate: { transition: { staggerChildren: 0.06, delayChildren: 0.04 } }
1640
+ },
1641
+ slow: {
1642
+ initial: {},
1643
+ animate: { transition: { staggerChildren: 0.08, delayChildren: 0.05 } }
1644
+ }
1497
1645
  };
1498
- var defaultSpringTransition = {
1499
- type: "spring",
1500
- stiffness: brandSpring.default.stiffness,
1501
- damping: brandSpring.default.damping,
1502
- mass: brandSpring.default.mass
1646
+ var viewportSettings = {
1647
+ once: { once: true, margin: "-100px" }};
1648
+ var fadeInVariant = {
1649
+ initial: { opacity: 0 },
1650
+ animate: { opacity: 1 },
1651
+ exit: { opacity: 0 },
1652
+ transition: { duration: 0.3 }
1503
1653
  };
1504
1654
  var PRESETS = {
1655
+ /** 涌现 — materialize from the cloud (default) */
1505
1656
  emerge: {
1506
1657
  initial: emerge.initial,
1507
1658
  animate: emerge.animate,
1508
1659
  exit: emerge.exit,
1509
- transition: emergeTransition
1660
+ transition: emerge.transition
1510
1661
  },
1662
+ /** 流动 — stream horizontally */
1511
1663
  flow: {
1512
1664
  initial: flow.initial,
1513
1665
  animate: flow.animate,
1514
1666
  exit: flow.exit,
1515
- transition: flowTransition
1667
+ transition: flow.transition
1516
1668
  },
1517
- fade: {
1518
- initial: { opacity: 0 },
1519
- animate: { opacity: 1 },
1520
- exit: { opacity: 0 },
1521
- transition: { duration: 0.3 }
1669
+ /** Simple fade */
1670
+ fade: fadeInVariant,
1671
+ /** Fade + rise */
1672
+ fadeUp: motionVariants.fadeInUp,
1673
+ /** Scale in */
1674
+ scale: motionVariants.scaleIn,
1675
+ /**
1676
+ * Keyed content swap — short, symmetric, blur-softened. Rises in, sinks out.
1677
+ * Shorter and shallower than `emerge` on purpose: a swap replaces content the
1678
+ * reader is already looking at, so it must resolve inside the reveal rail.
1679
+ * Pair with `AnimateSwap`.
1680
+ */
1681
+ swap: {
1682
+ initial: { opacity: 0, transform: "translateY(10px)", filter: "blur(4px)" },
1683
+ animate: { opacity: 1, transform: "translateY(0px)", filter: "blur(0px)" },
1684
+ exit: { opacity: 0, transform: "translateY(-10px)", filter: "blur(4px)" },
1685
+ transition: { duration: motionDurations.reveal / 1e3 }
1522
1686
  },
1523
- fadeUp: {
1524
- initial: { opacity: 0, y: 16 },
1525
- animate: { opacity: 1, y: 0 },
1526
- exit: { opacity: 0, y: 16 },
1527
- transition: defaultSpringTransition
1687
+ /** Off-canvas panel entering from the right edge (drawer, sheet). */
1688
+ slideFromRight: {
1689
+ initial: { transform: "translateX(100%)" },
1690
+ animate: { transform: "translateX(0%)" },
1691
+ exit: { transform: "translateX(100%)" },
1692
+ transition: brandSpring.default
1528
1693
  },
1529
- scale: {
1530
- initial: { opacity: 0, scale: 0.95 },
1531
- animate: { opacity: 1, scale: 1 },
1532
- exit: { opacity: 0, scale: 0.95 },
1533
- transition: defaultSpringTransition
1694
+ /** Off-canvas panel entering from the left edge. */
1695
+ slideFromLeft: {
1696
+ initial: { transform: "translateX(-100%)" },
1697
+ animate: { transform: "translateX(0%)" },
1698
+ exit: { transform: "translateX(-100%)" },
1699
+ transition: brandSpring.default
1700
+ },
1701
+ /** Off-canvas panel entering from the top edge (banner, command bar). */
1702
+ slideFromTop: {
1703
+ initial: { transform: "translateY(-100%)" },
1704
+ animate: { transform: "translateY(0%)" },
1705
+ exit: { transform: "translateY(-100%)" },
1706
+ transition: brandSpring.default
1707
+ },
1708
+ /** Off-canvas panel entering from the bottom edge (mobile action sheet). */
1709
+ slideFromBottom: {
1710
+ initial: { transform: "translateY(100%)" },
1711
+ animate: { transform: "translateY(0%)" },
1712
+ exit: { transform: "translateY(100%)" },
1713
+ transition: brandSpring.default
1534
1714
  }
1535
1715
  };
1536
- var STAGGER = { fast: 0.05, normal: 0.1, slow: 0.2 };
1537
1716
  function MotionDiv(props) {
1538
1717
  return /* @__PURE__ */ jsx(LazyMotion, { features: domAnimation, children: /* @__PURE__ */ jsx(m.div, { ...props }) });
1539
1718
  }
1540
1719
  function AnimateIn(props) {
1541
- const { children, preset = "emerge", delay = 0, duration, inView = false, className } = props;
1720
+ const {
1721
+ children,
1722
+ preset = "fade",
1723
+ delay = 0,
1724
+ duration,
1725
+ inView = false,
1726
+ className,
1727
+ ...rest
1728
+ } = props;
1542
1729
  const shouldReduce = useReducedMotion();
1543
- const { initial, animate: animate2, exit, transition } = PRESETS[preset];
1544
- const t = {
1545
- ...transition,
1546
- ...delay ? { delay } : {},
1730
+ const base = PRESETS[preset] || PRESETS.fade;
1731
+ const initial = shouldReduce ? { opacity: 0 } : base.initial;
1732
+ const animate2 = shouldReduce ? { opacity: 1 } : base.animate;
1733
+ const exit = shouldReduce ? { opacity: 0 } : "exit" in base ? base.exit : void 0;
1734
+ const transition = {
1735
+ ...shouldReduce ? { duration: 0.15 } : base.transition,
1736
+ delay,
1547
1737
  ...duration ? { duration } : {}
1548
1738
  };
1549
- if (shouldReduce) return /* @__PURE__ */ jsx("div", { className, children });
1550
1739
  if (inView) {
1551
1740
  return /* @__PURE__ */ jsx(
1552
1741
  MotionDiv,
1553
1742
  {
1743
+ ...rest,
1554
1744
  className,
1555
1745
  initial,
1556
1746
  whileInView: animate2,
1557
- exit,
1558
- viewport: { once: true, margin: "-10%" },
1559
- transition: t,
1747
+ ...exit && { exit },
1748
+ transition,
1749
+ viewport: viewportSettings.once,
1560
1750
  children
1561
1751
  }
1562
1752
  );
1563
1753
  }
1564
- return /* @__PURE__ */ jsx(MotionDiv, { className, initial, animate: animate2, exit, transition: t, children });
1754
+ return /* @__PURE__ */ jsx(
1755
+ MotionDiv,
1756
+ {
1757
+ ...rest,
1758
+ className,
1759
+ initial,
1760
+ animate: animate2,
1761
+ ...exit && { exit },
1762
+ transition,
1763
+ children
1764
+ }
1765
+ );
1766
+ }
1767
+ function AnimateSwap(props) {
1768
+ const { swapKey, ...animateInProps } = props;
1769
+ return /* @__PURE__ */ jsx(LazyMotion, { features: domAnimation, children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(AnimateIn, { ...animateInProps }, swapKey) }) });
1565
1770
  }
1566
1771
  function AnimateInGroup(props) {
1567
1772
  const { children, stagger = "normal", inView = false, className } = props;
1568
1773
  const shouldReduce = useReducedMotion();
1569
- const variants = {
1570
- initial: {},
1571
- animate: { transition: { staggerChildren: STAGGER[stagger] } }
1572
- };
1573
- if (shouldReduce) return /* @__PURE__ */ jsx("div", { className, children });
1774
+ const container = staggerContainers[stagger];
1775
+ if (shouldReduce) {
1776
+ return /* @__PURE__ */ jsx("div", { className, children });
1777
+ }
1574
1778
  if (inView) {
1575
1779
  return /* @__PURE__ */ jsx(
1576
1780
  MotionDiv,
@@ -1578,13 +1782,13 @@ function AnimateInGroup(props) {
1578
1782
  className,
1579
1783
  initial: "initial",
1580
1784
  whileInView: "animate",
1581
- viewport: { once: true, margin: "-10%" },
1582
- variants,
1785
+ viewport: viewportSettings.once,
1786
+ variants: container,
1583
1787
  children
1584
1788
  }
1585
1789
  );
1586
1790
  }
1587
- return /* @__PURE__ */ jsx(MotionDiv, { className, initial: "initial", animate: "animate", variants, children });
1791
+ return /* @__PURE__ */ jsx(MotionDiv, { className, initial: "initial", animate: "animate", variants: container, children });
1588
1792
  }
1589
1793
  function AsciiText({ text, className = "", font = slant }) {
1590
1794
  const asciiTextRef = useAsciiText({
@@ -1599,6 +1803,93 @@ function AsciiText({ text, className = "", font = slant }) {
1599
1803
  }
1600
1804
  );
1601
1805
  }
1806
+ function Popover({ ...props }) {
1807
+ return /* @__PURE__ */ jsx(Popover$1.Root, { "data-slot": "popover", ...props });
1808
+ }
1809
+ function PopoverTrigger({ asChild, children, render, ...props }) {
1810
+ const renderElement = asChild && React5.isValidElement(children) ? children : render;
1811
+ return /* @__PURE__ */ jsx(
1812
+ Popover$1.Trigger,
1813
+ {
1814
+ "data-slot": "popover-trigger",
1815
+ render: renderElement,
1816
+ ...renderElement ? props : { ...props, children }
1817
+ }
1818
+ );
1819
+ }
1820
+ function PopoverContent({
1821
+ className,
1822
+ align = "center",
1823
+ sideOffset = 8,
1824
+ alignOffset = 0,
1825
+ side = "bottom",
1826
+ children,
1827
+ showArrow = false,
1828
+ style,
1829
+ ...props
1830
+ }) {
1831
+ return /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(
1832
+ Popover$1.Positioner,
1833
+ {
1834
+ "data-slot": "popover-positioner",
1835
+ sideOffset,
1836
+ align,
1837
+ alignOffset,
1838
+ side,
1839
+ children: /* @__PURE__ */ jsxs(
1840
+ Popover$1.Popup,
1841
+ {
1842
+ "data-slot": "popover-content",
1843
+ className: cn(
1844
+ overlayClassNames.popoverSurface,
1845
+ overlayPrimitiveClassNames.popoverSurface,
1846
+ className
1847
+ ),
1848
+ style: { zIndex: overlayZIndex.popover, ...style },
1849
+ ...props,
1850
+ children: [
1851
+ children,
1852
+ showArrow && /* @__PURE__ */ jsx(PopoverArrow, {})
1853
+ ]
1854
+ }
1855
+ )
1856
+ }
1857
+ ) });
1858
+ }
1859
+ function PopoverArrow({
1860
+ className,
1861
+ style,
1862
+ ...props
1863
+ }) {
1864
+ return /* @__PURE__ */ jsx(
1865
+ Popover$1.Arrow,
1866
+ {
1867
+ "data-slot": "popover-arrow",
1868
+ className: cn(
1869
+ "data-[side=bottom]:top-[-8px] data-[side=left]:right-[-13px] data-[side=left]:rotate-90 data-[side=right]:left-[-13px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180",
1870
+ className
1871
+ ),
1872
+ style: { zIndex: overlayZIndex.popover, ...style },
1873
+ ...props,
1874
+ children: /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", width: "20", height: "10", viewBox: "0 0 20 10", fill: "none", children: [
1875
+ /* @__PURE__ */ jsx(
1876
+ "path",
1877
+ {
1878
+ d: "M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V9H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z",
1879
+ className: "fill-popover"
1880
+ }
1881
+ ),
1882
+ /* @__PURE__ */ jsx(
1883
+ "path",
1884
+ {
1885
+ d: "M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z",
1886
+ className: "fill-border"
1887
+ }
1888
+ )
1889
+ ] })
1890
+ }
1891
+ );
1892
+ }
1602
1893
  var TAG_COLOR_MAP = {
1603
1894
  feature: "bg-[hsl(var(--primary))] text-white",
1604
1895
  fix: "bg-[var(--status-success)] text-white",
@@ -1623,93 +1914,81 @@ function ChangelogWidget({
1623
1914
  }) {
1624
1915
  const [isOpen, setIsOpen] = React5.useState(false);
1625
1916
  const [lastSeenVersion, setLastSeenVersion] = React5.useState(null);
1626
- const dropdownRef = React5.useRef(null);
1627
1917
  const unreadCount = getUnreadCount(entries, lastSeenVersion);
1628
1918
  const recentEntries = entries.slice(0, 5);
1629
1919
  const latestVersion = recentEntries[0]?.version ?? null;
1630
- const closeAndMarkSeen = () => {
1631
- setIsOpen(false);
1632
- if (latestVersion) setLastSeenVersion(latestVersion);
1920
+ const handleOpenChange = (open) => {
1921
+ setIsOpen(open);
1922
+ if (!open && latestVersion) setLastSeenVersion(latestVersion);
1633
1923
  };
1634
- const closeFromDocumentEvent = useEffectEvent(() => {
1635
- closeAndMarkSeen();
1636
- });
1637
- React5.useEffect(() => {
1638
- if (!isOpen) return;
1639
- const handleEscape = (e) => {
1640
- if (e.key === "Escape") closeFromDocumentEvent();
1641
- };
1642
- const handleClickOutside = (e) => {
1643
- if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
1644
- closeFromDocumentEvent();
1645
- }
1646
- };
1647
- document.addEventListener("keydown", handleEscape);
1648
- document.addEventListener("mousedown", handleClickOutside);
1649
- return () => {
1650
- document.removeEventListener("keydown", handleEscape);
1651
- document.removeEventListener("mousedown", handleClickOutside);
1652
- };
1653
- }, [isOpen]);
1654
- return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), ref: dropdownRef, children: [
1924
+ return /* @__PURE__ */ jsxs(Popover, { open: isOpen, onOpenChange: handleOpenChange, children: [
1655
1925
  /* @__PURE__ */ jsxs(
1656
- "button",
1926
+ PopoverTrigger,
1657
1927
  {
1658
- type: "button",
1659
1928
  "aria-label": "View changelog",
1660
- "aria-expanded": isOpen,
1661
- onClick: () => setIsOpen((open) => !open),
1662
- className: "relative inline-flex items-center justify-center rounded-[var(--radius-lg)] p-2 transition-colors hover:bg-muted",
1929
+ className: cn(
1930
+ "relative inline-flex items-center justify-center rounded-[var(--radius-lg)] p-2 transition-colors hover:bg-muted",
1931
+ className
1932
+ ),
1663
1933
  children: [
1664
1934
  /* @__PURE__ */ jsx(Bell, { className: "h-5 w-5 text-muted-foreground" }),
1665
1935
  unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute right-0 top-0 flex h-5 w-5 items-center justify-center rounded-full bg-[var(--status-danger)] text-xs font-bold text-white", children: unreadCount > 9 ? "9+" : unreadCount })
1666
1936
  ]
1667
1937
  }
1668
1938
  ),
1669
- isOpen && /* @__PURE__ */ jsxs("div", { className: "absolute right-0 top-full z-50 mt-2 w-80 overflow-hidden rounded-[var(--radius-lg)] border border-border bg-white shadow-lg transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-200", children: [
1670
- /* @__PURE__ */ jsx("div", { className: "bg-gradient-to-r from-[var(--blue-3)] to-[var(--cyan-3)] px-4 py-3", children: /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground", children: "What's New" }) }),
1671
- /* @__PURE__ */ jsx("div", { className: "max-h-96 overflow-y-auto", children: recentEntries.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-6 text-center text-sm text-muted-foreground", children: "No updates available" }) : recentEntries.map((entry) => /* @__PURE__ */ jsxs(
1672
- "a",
1673
- {
1674
- href: entry.url,
1675
- className: "block border-b border-border px-4 py-3 transition-colors hover:bg-muted",
1676
- children: [
1677
- /* @__PURE__ */ jsx("div", { className: "mb-2 flex items-center justify-between gap-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1678
- /* @__PURE__ */ jsxs("span", { className: "font-mono text-xs font-bold text-primary", children: [
1679
- "v",
1680
- entry.version
1681
- ] }),
1682
- entry.tag && /* @__PURE__ */ jsx(
1683
- "span",
1684
- {
1685
- className: cn(
1686
- "rounded px-2 py-0.5 text-xs font-medium",
1687
- getTagColor(entry.tag)
1688
- ),
1689
- children: entry.tag
1690
- }
1691
- )
1692
- ] }) }),
1693
- /* @__PURE__ */ jsx("p", { className: "mb-1 text-sm font-medium text-foreground", children: entry.title }),
1694
- /* @__PURE__ */ jsx("p", { className: "mb-2 line-clamp-2 text-xs text-muted-foreground", children: entry.excerpt }),
1695
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: entry.date })
1696
- ]
1697
- },
1698
- entry.version
1699
- )) }),
1700
- /* @__PURE__ */ jsxs(
1701
- "a",
1702
- {
1703
- href: changelogUrl,
1704
- onClick: closeAndMarkSeen,
1705
- className: "flex items-center justify-between border-t border-border bg-background px-4 py-3 text-sm font-medium text-primary transition-colors hover:bg-muted",
1706
- children: [
1707
- /* @__PURE__ */ jsx("span", { children: "View all updates" }),
1708
- /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
1709
- ]
1710
- }
1711
- )
1712
- ] })
1939
+ /* @__PURE__ */ jsxs(
1940
+ PopoverContent,
1941
+ {
1942
+ align: "end",
1943
+ side: "bottom",
1944
+ sideOffset: 8,
1945
+ className: "w-80 overflow-hidden rounded-[var(--radius-lg)] border-border bg-white p-0 shadow-lg",
1946
+ children: [
1947
+ /* @__PURE__ */ jsx("div", { className: "bg-gradient-to-r from-[var(--blue-3)] to-[var(--cyan-3)] px-4 py-3", children: /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground", children: "What's New" }) }),
1948
+ /* @__PURE__ */ jsx("div", { className: "max-h-96 overflow-y-auto", children: recentEntries.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-6 text-center text-sm text-muted-foreground", children: "No updates available" }) : recentEntries.map((entry) => /* @__PURE__ */ jsxs(
1949
+ "a",
1950
+ {
1951
+ href: entry.url,
1952
+ className: "block border-b border-border px-4 py-3 transition-colors hover:bg-muted",
1953
+ children: [
1954
+ /* @__PURE__ */ jsx("div", { className: "mb-2 flex items-center justify-between gap-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1955
+ /* @__PURE__ */ jsxs("span", { className: "font-mono text-xs font-bold text-primary", children: [
1956
+ "v",
1957
+ entry.version
1958
+ ] }),
1959
+ entry.tag && /* @__PURE__ */ jsx(
1960
+ "span",
1961
+ {
1962
+ className: cn(
1963
+ "rounded px-2 py-0.5 text-xs font-medium",
1964
+ getTagColor(entry.tag)
1965
+ ),
1966
+ children: entry.tag
1967
+ }
1968
+ )
1969
+ ] }) }),
1970
+ /* @__PURE__ */ jsx("p", { className: "mb-1 text-sm font-medium text-foreground", children: entry.title }),
1971
+ /* @__PURE__ */ jsx("p", { className: "mb-2 line-clamp-2 text-xs text-muted-foreground", children: entry.excerpt }),
1972
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: entry.date })
1973
+ ]
1974
+ },
1975
+ entry.version
1976
+ )) }),
1977
+ /* @__PURE__ */ jsxs(
1978
+ "a",
1979
+ {
1980
+ href: changelogUrl,
1981
+ onClick: () => handleOpenChange(false),
1982
+ className: "flex items-center justify-between border-t border-border bg-background px-4 py-3 text-sm font-medium text-primary transition-colors hover:bg-muted",
1983
+ children: [
1984
+ /* @__PURE__ */ jsx("span", { children: "View all updates" }),
1985
+ /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
1986
+ ]
1987
+ }
1988
+ )
1989
+ ]
1990
+ }
1991
+ )
1713
1992
  ] });
1714
1993
  }
1715
1994
  var GRAPH_NODE_FLOW_TYPE = "graph-node";
@@ -1774,14 +2053,14 @@ function removeFlowEdge(graph, flowEdgeId, edgeIdentity) {
1774
2053
  };
1775
2054
  }
1776
2055
  var XYFLOW_TOKEN_THEME = {
1777
- ["--xy-background-pattern-color"]: "var(--neutral-6)",
1778
- ["--xy-edge-stroke"]: "var(--neutral-8)",
1779
- ["--xy-connectionline-stroke"]: "var(--neutral-8)",
1780
- ["--xy-handle-background-color"]: "var(--neutral-9)",
1781
- ["--xy-handle-border-color"]: "var(--neutral-7)",
1782
- ["--xy-controls-button-background-color"]: "var(--neutral-2)",
1783
- ["--xy-controls-button-border-color"]: "var(--neutral-7)",
1784
- ["--xy-controls-button-color"]: "var(--neutral-11)"
2056
+ "--xy-background-pattern-color": "var(--neutral-6)",
2057
+ "--xy-edge-stroke": "var(--neutral-8)",
2058
+ "--xy-connectionline-stroke": "var(--neutral-8)",
2059
+ "--xy-handle-background-color": "var(--neutral-9)",
2060
+ "--xy-handle-border-color": "var(--neutral-7)",
2061
+ "--xy-controls-button-background-color": "var(--neutral-2)",
2062
+ "--xy-controls-button-border-color": "var(--neutral-7)",
2063
+ "--xy-controls-button-color": "var(--neutral-11)"
1785
2064
  };
1786
2065
  var nodeCardVariants = cva(
1787
2066
  "min-w-[160px] rounded-[var(--radius-lg)] border bg-neutral-2 px-3 py-2 text-neutral-12 shadow-sm transition-colors",
@@ -1868,7 +2147,7 @@ function NodeGraphCanvas({
1868
2147
  setRejection(result.reason);
1869
2148
  }
1870
2149
  };
1871
- return /* @__PURE__ */ jsx(AnimateIn, { preset: "emerge", children: /* @__PURE__ */ jsx(
2150
+ return /* @__PURE__ */ jsx(
1872
2151
  "div",
1873
2152
  {
1874
2153
  style: XYFLOW_TOKEN_THEME,
@@ -1903,11 +2182,11 @@ function NodeGraphCanvas({
1903
2182
  children: [
1904
2183
  /* @__PURE__ */ jsx("span", { children: rejection }),
1905
2184
  /* @__PURE__ */ jsx(
1906
- Button$1,
2185
+ Button,
1907
2186
  {
1908
- size: "small",
1909
- type: "text",
1910
- icon: /* @__PURE__ */ jsx(CrossSmall, { size: 14 }),
2187
+ size: "sm",
2188
+ variant: "ghost",
2189
+ prefix: /* @__PURE__ */ jsx(CrossSmall, { size: 14 }),
1911
2190
  "aria-label": "Dismiss connection error",
1912
2191
  onClick: () => setRejection(null),
1913
2192
  children: "Dismiss"
@@ -1920,7 +2199,7 @@ function NodeGraphCanvas({
1920
2199
  }
1921
2200
  ) })
1922
2201
  }
1923
- ) });
2202
+ );
1924
2203
  }
1925
2204
  var containerVariants = {
1926
2205
  hidden: { opacity: 0, y: 20 },
@@ -1997,7 +2276,7 @@ function OnboardingChecklist({
1997
2276
  "a",
1998
2277
  {
1999
2278
  href: item.helperLink.href,
2000
- className: "text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-[var(--radius-sm)]",
2279
+ className: "text-primary underline-offset-4 hover:underline rounded-[var(--radius-sm)]",
2001
2280
  children: item.helperLink.text
2002
2281
  }
2003
2282
  )
@@ -2014,7 +2293,8 @@ function OnboardingChecklist({
2014
2293
  "button",
2015
2294
  {
2016
2295
  type: "button",
2017
- className: "w-full h-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-[var(--radius-lg)]",
2296
+ "aria-label": "Play the video guide",
2297
+ className: "w-full h-full rounded-[var(--radius-lg)]",
2018
2298
  children: [
2019
2299
  /* @__PURE__ */ jsx(
2020
2300
  Image,
@@ -2181,11 +2461,11 @@ var Kbd = ({
2181
2461
  Kbd.displayName = "Kbd";
2182
2462
  var inputVariants = cva(
2183
2463
  [
2184
- "flex h-[var(--input-height)] w-full rounded-[var(--input-radius)] border border-input bg-background",
2185
- "px-[var(--input-padding-x)] text-[length:var(--input-font-size)] text-foreground shadow-xs",
2464
+ "flex h-[var(--input-height)] w-full rounded-[var(--input-radius)]",
2465
+ "px-[var(--input-padding-x)] text-[length:var(--input-font-size)] text-foreground",
2186
2466
  "transition-[background-color,border-color,box-shadow,color] duration-micro ease-out",
2187
2467
  "placeholder:text-muted-foreground",
2188
- formControlFocusClassNames.input,
2468
+ "outline-none",
2189
2469
  "disabled:cursor-not-allowed disabled:opacity-50",
2190
2470
  "read-only:bg-muted/70 read-only:cursor-default",
2191
2471
  "file:h-full file:border-0 file:border-e file:border-solid file:border-input file:bg-transparent",
@@ -2208,11 +2488,31 @@ var inputVariants = cva(
2208
2488
  prefix: "pl-[var(--input-padding-left)]",
2209
2489
  suffix: "pr-[var(--input-padding-right)]",
2210
2490
  both: "pl-[var(--input-padding-left)] pr-[var(--input-padding-right)]"
2491
+ },
2492
+ /**
2493
+ * `bare` drops the field's own stroke, fill and lift so it can sit inside
2494
+ * a container that already provides them — a footer subscribe group, a
2495
+ * search well, a segmented composer. Those surfaces were each being built
2496
+ * by hand with a raw <input>, because overriding the bordered look from
2497
+ * outside is not reliable: `border-transparent` passed via className and
2498
+ * `border-input` from the base are both border-color utilities, so which
2499
+ * one wins depends on their order in the generated stylesheet rather than
2500
+ * on the order they were written. That is why the stroke, fill and shadow
2501
+ * live in this variant instead of the base — the two tones now never emit
2502
+ * a competing declaration.
2503
+ *
2504
+ * A bare field draws no focus ring of its own. The container owns it, so
2505
+ * the ring surrounds the whole group rather than a box inside it.
2506
+ */
2507
+ tone: {
2508
+ bordered: `border border-input bg-background shadow-xs ${formControlFocusClassNames.input}`,
2509
+ bare: "border-0 bg-transparent shadow-none"
2211
2510
  }
2212
2511
  },
2213
2512
  defaultVariants: {
2214
2513
  size: "md",
2215
- affix: "none"
2514
+ affix: "none",
2515
+ tone: "bordered"
2216
2516
  }
2217
2517
  }
2218
2518
  );
@@ -2234,8 +2534,8 @@ var inputControlButtonVariants = cva(
2234
2534
  [
2235
2535
  "absolute right-[var(--input-control-inset)] top-1/2 flex size-[var(--input-control-size)] -translate-y-1/2 items-center justify-center",
2236
2536
  "rounded-[var(--radius-sm)] text-muted-foreground transition-colors duration-micro ease-out",
2237
- "hover:bg-accent hover:text-foreground",
2238
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
2537
+ "hover:bg-accent hover:text-accent-foreground",
2538
+ "focus-visible:outline-none",
2239
2539
  "disabled:pointer-events-none disabled:opacity-50",
2240
2540
  "[&_svg]:size-[var(--input-control-icon-size)]"
2241
2541
  ].join(" ")
@@ -2274,7 +2574,7 @@ function getInputStyle(size, style) {
2274
2574
  "--input-focus-ring-width": `${inputTokens.focusRingWidth}px`,
2275
2575
  borderRadius: "var(--input-radius)",
2276
2576
  outline: "none",
2277
- ...style
2577
+ ...asPlainStyle(style)
2278
2578
  };
2279
2579
  }
2280
2580
  function getAffixMode(prefix, hasRightAdornment) {
@@ -2300,6 +2600,7 @@ var Input = ({
2300
2600
  className,
2301
2601
  type = "text",
2302
2602
  size = "md",
2603
+ tone = "bordered",
2303
2604
  prefix,
2304
2605
  suffix,
2305
2606
  clearable,
@@ -2419,7 +2720,7 @@ var Input = ({
2419
2720
  "aria-describedby": describedBy,
2420
2721
  "aria-busy": loading || void 0,
2421
2722
  className: cn(
2422
- inputVariants({ size, affix }),
2723
+ inputVariants({ size, affix, tone }),
2423
2724
  type === "file" && "p-0 pr-[var(--input-padding-x)] text-muted-foreground",
2424
2725
  className
2425
2726
  ),
@@ -2585,7 +2886,7 @@ function TeamChat({
2585
2886
  "div",
2586
2887
  {
2587
2888
  className: cn(
2588
- "w-full max-w-5xl mx-auto p-6 bg-white dark:bg-black rounded-[var(--radius-3xl)] shadow-lg flex flex-col h-[550px] border border-border",
2889
+ "w-full max-w-content mx-auto p-6 bg-white dark:bg-black rounded-[var(--radius-3xl)] shadow-lg flex flex-col h-[550px] border border-border",
2589
2890
  className
2590
2891
  ),
2591
2892
  children: [
@@ -2700,6 +3001,6 @@ function TeamChat({
2700
3001
  );
2701
3002
  }
2702
3003
 
2703
- export { AnimateIn, AnimateInGroup, AnimatedCard, AnimatedDrawer, AnimatedList, AnimatedModal, AnimatedPopover, AsciiText, ChangelogWidget, FadeIn, ImageViewDialog, MAX_VISUALIZER_BARS, NodeGraphCanvas, OnboardingChecklist, PageTransition, PromptAttachmentPreviews, PromptInputBox, ScaleIn, SlideIn, TeamChat, VISUALIZER_BAR_STYLES, VoiceRecorder, animatedList, animatedListItem, animationDistances, animationDurations, animationEasings, animationSprings, animationTransitions, drawerSurface, fadeIn, formatRecordingTime, getFilePreviewKey, isImageFile, modalSurface, pageTransition, popoverSurface, preventDragDefaults, reducedMotionVariants, scaleIn, slideIn };
3004
+ export { AnimateIn, AnimateInGroup, AnimateSwap, AnimatedCard, AnimatedDrawer, AnimatedList, AnimatedModal, AnimatedPopover, AsciiText, ChangelogWidget, FadeIn, GRAPH_NODE_FLOW_TYPE, ImageViewDialog, MAX_VISUALIZER_BARS, NodeGraphCanvas, OnboardingChecklist, PageTransition, PromptAttachmentPreviews, PromptInputBox, ScaleIn, SlideIn, TeamChat, VISUALIZER_BAR_STYLES, VoiceRecorder, animatedList, animatedListItem, animationDistances, animationDurations, animationEasings, animationSprings, animationTransitions, applyNodePositions, drawerSurface, fadeIn, formatRecordingTime, getFilePreviewKey, graphToFlow, isImageFile, modalSurface, pageTransition, popoverSurface, preventDragDefaults, reducedMotionVariants, removeFlowEdge, removeNode, scaleIn, slideIn, tryAddEdge };
2704
3005
  //# sourceMappingURL=index.js.map
2705
3006
  //# sourceMappingURL=index.js.map