@dimaan/ui 0.0.28 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -120,21 +120,21 @@ var AlertDialogDescription = react.forwardRef(function AlertDialogDescription2({
120
120
 
121
121
  // src/components/button/buttonVariants.ts
122
122
  var buttonVariantClass = {
123
- primary: "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90 focus-visible:ring-primary/40",
123
+ primary: "bg-primary text-primary-foreground shadow-[var(--shadow-btn)] hover:bg-primary/95 hover:-translate-y-px hover:shadow-[var(--shadow-btn-hover)] active:translate-y-0 active:shadow-[var(--shadow-btn-active)] focus-visible:ring-primary/40",
124
124
  secondary: "bg-muted text-foreground hover:bg-muted/80 focus-visible:ring-muted-foreground/30",
125
125
  outline: "border border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring/40",
126
126
  ghost: "bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring/40",
127
- destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 focus-visible:ring-destructive/40",
128
- success: "bg-success text-success-foreground shadow-sm hover:bg-success/90 focus-visible:ring-success/40",
129
- warning: "bg-warning text-warning-foreground shadow-sm hover:bg-warning/90 focus-visible:ring-warning/40",
127
+ destructive: "bg-destructive text-destructive-foreground shadow-[var(--shadow-solid)] hover:bg-destructive/95 hover:-translate-y-px hover:shadow-[var(--shadow-solid-hover)] active:translate-y-0 active:shadow-[var(--shadow-solid-active)] focus-visible:ring-destructive/40",
128
+ success: "bg-success text-success-foreground shadow-[var(--shadow-solid)] hover:bg-success/95 hover:-translate-y-px hover:shadow-[var(--shadow-solid-hover)] active:translate-y-0 active:shadow-[var(--shadow-solid-active)] focus-visible:ring-success/40",
129
+ warning: "bg-warning text-warning-foreground shadow-[var(--shadow-solid)] hover:bg-warning/95 hover:-translate-y-px hover:shadow-[var(--shadow-solid-hover)] active:translate-y-0 active:shadow-[var(--shadow-solid-active)] focus-visible:ring-warning/40",
130
130
  link: "text-primary underline-offset-4 hover:underline focus-visible:ring-primary/40 px-0 shadow-none"
131
131
  };
132
132
  var buttonSizeClass = {
133
- sm: "h-8 gap-1.5 rounded-md px-3 text-sm",
134
- md: "h-9 gap-2 rounded-md px-4 text-sm",
135
- lg: "h-11 gap-2.5 rounded-md px-6 text-base",
136
- icon: "h-9 w-9 shrink-0 rounded-md p-0",
137
- "icon-sm": "h-8 w-8 shrink-0 rounded-md p-0"
133
+ sm: "h-8 gap-1.5 rounded-[10px] px-3 text-sm",
134
+ md: "h-9 gap-2 rounded-[10px] px-4 text-sm",
135
+ lg: "h-11 gap-2.5 rounded-[10px] px-6 text-base",
136
+ icon: "size-9 shrink-0 rounded-[10px] p-0",
137
+ "icon-sm": "size-8 shrink-0 rounded-[10px] p-0"
138
138
  };
139
139
  var buttonBaseClass = "group/button relative inline-flex items-center justify-center font-medium select-none whitespace-nowrap outline-none transition-[background-color,color,box-shadow,opacity,transform] active:scale-[0.98] focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 motion-reduce:transition-none motion-reduce:active:scale-100 [&_svg]:pointer-events-none [&_svg]:shrink-0";
140
140
  var Button = react.forwardRef(function Button2({
@@ -197,10 +197,10 @@ var Button = react.forwardRef(function Button2({
197
197
  );
198
198
  });
199
199
  function Slot({ children }) {
200
- return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "inline-flex h-4 w-4 items-center justify-center", children });
200
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "inline-flex size-4 items-center justify-center", children });
201
201
  }
202
202
  function Spinner() {
203
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { "aria-hidden": "true", className: "h-4 w-4 animate-spin", "data-testid": "button-spinner" });
203
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { "aria-hidden": "true", className: "size-4 animate-spin", "data-testid": "button-spinner" });
204
204
  }
205
205
  var ConfirmDialogContext = react.createContext(null);
206
206
  function ConfirmDialogProvider({ labels, children }) {
@@ -372,7 +372,7 @@ function DashboardMain({ className, children, ...props }) {
372
372
  // stretching the whole layout past 100%.
373
373
  "flex min-h-screen min-w-0 flex-1 flex-col transition-[margin] duration-200 ease-out",
374
374
  // On desktop, push the main column past the fixed sidebar using logical margin.
375
- collapsed ? "lg:ms-[var(--sidebar-width-collapsed)]" : "lg:ms-[var(--sidebar-width)]",
375
+ collapsed ? "lg:ms-0" : "lg:ms-(--sidebar-width)",
376
376
  className
377
377
  ),
378
378
  ...props,
@@ -475,7 +475,7 @@ var HeaderSearch = react.forwardRef(
475
475
  "span",
476
476
  {
477
477
  "aria-hidden": "true",
478
- className: "pointer-events-none absolute start-3 flex h-4 w-4 items-center justify-center text-muted-foreground",
478
+ className: "pointer-events-none absolute start-3 flex size-4 items-center justify-center text-muted-foreground",
479
479
  children: icon
480
480
  }
481
481
  ) : null,
@@ -541,14 +541,16 @@ function Sidebar({ className, children, ...props }) {
541
541
  "fixed inset-y-0 start-0 z-40 flex flex-col",
542
542
  // Surface
543
543
  "bg-sidebar text-sidebar-foreground border-e border-sidebar-border",
544
- // Sizing — width animates between full and collapsed
545
- collapsed ? "w-[var(--sidebar-width-collapsed)]" : "w-[var(--sidebar-width)]",
544
+ // Sizing — always full width; collapse hides it off-canvas (below).
545
+ "w-[var(--sidebar-width)]",
546
546
  // Motion
547
- "transition-[transform,width] duration-200 ease-out",
548
- // Mobile slide: hidden by default, visible when mobileOpen.
549
- // Logical translate via rtl variant so it slides off the inline-start edge
550
- // in both LTR and RTL.
551
- mobileOpen ? "translate-x-0" : "-translate-x-full rtl:translate-x-full lg:translate-x-0 lg:rtl:translate-x-0",
547
+ "transition-transform duration-200 ease-out",
548
+ // Mobile: slide in/out via mobileOpen. Logical translate (rtl variant)
549
+ // so it slides off the inline-start edge in both LTR and RTL.
550
+ mobileOpen ? "translate-x-0" : "-translate-x-full rtl:translate-x-full",
551
+ // Desktop: collapse fully hides the sidebar off-canvas; the header
552
+ // trigger slides it back in and the main content reclaims the width.
553
+ collapsed ? "lg:-translate-x-full lg:rtl:translate-x-full" : "lg:translate-x-0 lg:rtl:translate-x-0",
552
554
  className
553
555
  ),
554
556
  ...props,
@@ -571,18 +573,8 @@ function SidebarFooter({ className, children, ...props }) {
571
573
  );
572
574
  }
573
575
  function SidebarGroup({ label, className, children, ...props }) {
574
- const { collapsed } = useDashboardLayout();
575
576
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-1 py-2", className), ...props, children: [
576
- label ? /* @__PURE__ */ jsxRuntime.jsx(
577
- "div",
578
- {
579
- className: cn(
580
- "px-3 pb-1 text-xs font-medium uppercase tracking-wider text-muted-foreground transition-opacity",
581
- collapsed && "pointer-events-none h-0 overflow-hidden opacity-0"
582
- ),
583
- children: label
584
- }
585
- ) : null,
577
+ label ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-1 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: label }) : null,
586
578
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children })
587
579
  ] });
588
580
  }
@@ -616,7 +608,6 @@ function SidebarNavGroup({
616
608
  onClick,
617
609
  ...props
618
610
  }) {
619
- const { collapsed } = useDashboardLayout();
620
611
  const submenuId = react.useId();
621
612
  const [internalOpen, setInternalOpen] = react.useState(defaultOpen);
622
613
  const isControlled = openProp !== void 0;
@@ -643,27 +634,23 @@ function SidebarNavGroup({
643
634
  const isActive = active || hasActiveChild;
644
635
  const prevHasActiveChild = react.useRef(false);
645
636
  react.useEffect(() => {
646
- if (hasActiveChild && !prevHasActiveChild.current && !collapsed) {
637
+ if (hasActiveChild && !prevHasActiveChild.current) {
647
638
  setOpen(true);
648
639
  }
649
640
  prevHasActiveChild.current = hasActiveChild;
650
- }, [hasActiveChild, collapsed, setOpen]);
651
- react.useEffect(() => {
652
- if (collapsed && open) setOpen(false);
653
- }, [collapsed, open, setOpen]);
654
- const titleAttr = collapsed && typeof label === "string" ? label : props.title ?? void 0;
655
- const showChildren = !collapsed;
641
+ }, [hasActiveChild, setOpen]);
642
+ const titleAttr = props.title ?? void 0;
656
643
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 flex-col", children: [
657
644
  /* @__PURE__ */ jsxRuntime.jsxs(
658
645
  "button",
659
646
  {
660
647
  type: "button",
661
- "aria-expanded": showChildren ? open : void 0,
662
- "aria-controls": showChildren ? submenuId : void 0,
648
+ "aria-expanded": open,
649
+ "aria-controls": submenuId,
663
650
  "data-active": isActive ? "true" : void 0,
664
651
  title: titleAttr,
665
652
  onClick: (e) => {
666
- if (showChildren) setOpen(!open);
653
+ setOpen(!open);
667
654
  onClick?.(e);
668
655
  },
669
656
  className: cn(
@@ -671,7 +658,6 @@ function SidebarNavGroup({
671
658
  "text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
672
659
  "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-sidebar",
673
660
  isActive && "bg-sidebar-accent text-sidebar-accent-foreground",
674
- collapsed && "justify-center px-0",
675
661
  className
676
662
  ),
677
663
  ...props,
@@ -683,19 +669,10 @@ function SidebarNavGroup({
683
669
  className: "absolute inset-y-1.5 start-0 w-1 rounded-full bg-primary"
684
670
  }
685
671
  ) : null,
686
- icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex h-5 w-5 shrink-0 items-center justify-center", children: icon }) : null,
687
- /* @__PURE__ */ jsxRuntime.jsx(
688
- "span",
689
- {
690
- className: cn(
691
- "flex-1 truncate text-start transition-[opacity,width]",
692
- collapsed && "pointer-events-none w-0 opacity-0"
693
- ),
694
- children: label
695
- }
696
- ),
697
- endSlot && !collapsed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 items-center", children: endSlot }) : null,
698
- showChildren ? /* @__PURE__ */ jsxRuntime.jsx(ChevronCaret, { open }) : null
672
+ icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex size-5 shrink-0 items-center justify-center", children: icon }) : null,
673
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-start", children: label }),
674
+ endSlot ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 items-center", children: endSlot }) : null,
675
+ /* @__PURE__ */ jsxRuntime.jsx(ChevronCaret, { open })
699
676
  ]
700
677
  }
701
678
  ),
@@ -703,10 +680,10 @@ function SidebarNavGroup({
703
680
  "div",
704
681
  {
705
682
  id: submenuId,
706
- hidden: !showChildren || !open,
683
+ hidden: !open,
707
684
  className: cn(
708
685
  "grid transition-[grid-template-rows] duration-200 ease-out",
709
- showChildren && open ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
686
+ open ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
710
687
  ),
711
688
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5 ps-7 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarNavGroupContext.Provider, { value: contextValue, children }) }) })
712
689
  }
@@ -719,7 +696,7 @@ function ChevronCaret({ open }) {
719
696
  {
720
697
  "aria-hidden": "true",
721
698
  className: cn(
722
- "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform duration-200",
699
+ "size-3.5 shrink-0 text-muted-foreground transition-transform duration-200",
723
700
  open && "rotate-180"
724
701
  )
725
702
  }
@@ -737,7 +714,6 @@ function SidebarNavItem({
737
714
  end,
738
715
  ...props
739
716
  }) {
740
- const { collapsed } = useDashboardLayout();
741
717
  const resolved = reactRouterDom.useResolvedPath(to);
742
718
  const group = react.useContext(SidebarNavGroupContext);
743
719
  const itemId = react.useId();
@@ -749,13 +725,12 @@ function SidebarNavItem({
749
725
  return () => group.reportActive(itemId, false);
750
726
  }, [group, itemId, isActive]);
751
727
  const labelContent = label ?? children;
752
- const titleAttr = collapsed && typeof labelContent === "string" ? labelContent : props.title;
728
+ const titleAttr = props.title;
753
729
  const getClassName = (active) => cn(
754
730
  "group relative flex h-9 shrink-0 items-center gap-3 rounded-md px-3 text-sm font-medium outline-none transition-colors",
755
731
  "text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
756
732
  "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-sidebar",
757
733
  active && "bg-sidebar-accent text-sidebar-accent-foreground",
758
- collapsed && "justify-center px-0",
759
734
  className
760
735
  );
761
736
  const innerContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -766,18 +741,9 @@ function SidebarNavItem({
766
741
  className: "absolute inset-y-1.5 start-0 w-1 rounded-full bg-primary"
767
742
  }
768
743
  ) : null,
769
- icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex h-5 w-5 shrink-0 items-center justify-center", children: icon }) : null,
770
- /* @__PURE__ */ jsxRuntime.jsx(
771
- "span",
772
- {
773
- className: cn(
774
- "flex-1 truncate text-start transition-[opacity,width]",
775
- collapsed && "pointer-events-none w-0 opacity-0"
776
- ),
777
- children: labelContent
778
- }
779
- ),
780
- endSlot && !collapsed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ms-auto flex shrink-0 items-center", children: endSlot }) : null
744
+ icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex size-5 shrink-0 items-center justify-center", children: icon }) : null,
745
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-start", children: labelContent }),
746
+ endSlot ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ms-auto flex shrink-0 items-center", children: endSlot }) : null
781
747
  ] });
782
748
  if (render) {
783
749
  return render({
@@ -884,9 +850,9 @@ function AppShell({
884
850
  ) });
885
851
  }
886
852
  var sizeClass = {
887
- sm: "h-7 w-7 text-xs",
888
- md: "h-9 w-9 text-sm",
889
- lg: "h-11 w-11 text-base"
853
+ sm: "size-7 text-xs",
854
+ md: "size-9 text-sm",
855
+ lg: "size-11 text-base"
890
856
  };
891
857
  function Avatar({ src, alt = "", fallback, size = "md", className, ...props }) {
892
858
  const [errored, setErrored] = react.useState(false);
@@ -922,6 +888,14 @@ var badgeVariantClass = {
922
888
  destructive: "bg-destructive text-destructive-foreground border-transparent",
923
889
  outline: "border-border bg-transparent text-foreground"
924
890
  };
891
+ var badgeSoftVariantClass = {
892
+ default: "bg-muted text-muted-foreground border-transparent",
893
+ primary: "bg-primary/15 text-primary-soft-foreground border-transparent",
894
+ success: "bg-success/15 text-success-soft-foreground border-transparent",
895
+ warning: "bg-warning/15 text-warning-soft-foreground border-transparent",
896
+ destructive: "bg-destructive/15 text-destructive-soft-foreground border-transparent",
897
+ outline: "border-border bg-transparent text-foreground"
898
+ };
925
899
  var badgeSizeClass = {
926
900
  sm: "h-5 gap-1 px-2 text-[11px]",
927
901
  md: "h-6 gap-1.5 px-2.5 text-xs"
@@ -931,14 +905,16 @@ var badgeDotSizeClass = {
931
905
  md: "size-2"
932
906
  };
933
907
  var badgeBaseClass = "inline-flex shrink-0 items-center rounded-full border font-medium leading-none whitespace-nowrap select-none transition-colors";
934
- var Badge = react.forwardRef(function Badge2({ variant = "default", size = "md", dot = false, className, children, ...props }, ref) {
908
+ var Badge = react.forwardRef(function Badge2({ variant = "default", size = "md", tone = "solid", dot = false, className, children, ...props }, ref) {
909
+ const variantClass = tone === "soft" ? badgeSoftVariantClass[variant] : badgeVariantClass[variant];
935
910
  return /* @__PURE__ */ jsxRuntime.jsxs(
936
911
  "span",
937
912
  {
938
913
  ref,
939
914
  "data-slot": "badge",
940
915
  "data-variant": variant,
941
- className: cn(badgeBaseClass, badgeVariantClass[variant], badgeSizeClass[size], className),
916
+ "data-tone": tone,
917
+ className: cn(badgeBaseClass, variantClass, badgeSizeClass[size], className),
942
918
  ...props,
943
919
  children: [
944
920
  dot ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -953,9 +929,75 @@ var Badge = react.forwardRef(function Badge2({ variant = "default", size = "md",
953
929
  }
954
930
  );
955
931
  });
932
+
933
+ // src/components/card/cardVariants.ts
934
+ var cardBaseClass = "rounded-xl border border-border bg-card text-card-foreground shadow-[var(--shadow-card)]";
935
+ var cardHeaderClass = "flex flex-col gap-1.5 p-6";
936
+ var cardTitleClass = "text-lg font-semibold leading-none tracking-tight text-foreground";
937
+ var cardDescriptionClass = "text-sm text-muted-foreground";
938
+ var cardContentClass = "p-6 pt-0";
939
+ var cardFooterClass = "flex items-center gap-2 p-6 pt-0";
940
+ var Card = react.forwardRef(function Card2({ className, ...props }, ref) {
941
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, "data-slot": "card", className: cn(cardBaseClass, className), ...props });
942
+ });
943
+ var CardHeader = react.forwardRef(
944
+ function CardHeader2({ className, ...props }, ref) {
945
+ return /* @__PURE__ */ jsxRuntime.jsx(
946
+ "div",
947
+ {
948
+ ref,
949
+ "data-slot": "card-header",
950
+ className: cn(cardHeaderClass, className),
951
+ ...props
952
+ }
953
+ );
954
+ }
955
+ );
956
+ var CardTitle = react.forwardRef(
957
+ function CardTitle2({ className, ...props }, ref) {
958
+ return /* @__PURE__ */ jsxRuntime.jsx("h3", { ref, "data-slot": "card-title", className: cn(cardTitleClass, className), ...props });
959
+ }
960
+ );
961
+ var CardDescription = react.forwardRef(function CardDescription2({ className, ...props }, ref) {
962
+ return /* @__PURE__ */ jsxRuntime.jsx(
963
+ "p",
964
+ {
965
+ ref,
966
+ "data-slot": "card-description",
967
+ className: cn(cardDescriptionClass, className),
968
+ ...props
969
+ }
970
+ );
971
+ });
972
+ var CardContent = react.forwardRef(
973
+ function CardContent2({ className, ...props }, ref) {
974
+ return /* @__PURE__ */ jsxRuntime.jsx(
975
+ "div",
976
+ {
977
+ ref,
978
+ "data-slot": "card-content",
979
+ className: cn(cardContentClass, className),
980
+ ...props
981
+ }
982
+ );
983
+ }
984
+ );
985
+ var CardFooter = react.forwardRef(
986
+ function CardFooter2({ className, ...props }, ref) {
987
+ return /* @__PURE__ */ jsxRuntime.jsx(
988
+ "div",
989
+ {
990
+ ref,
991
+ "data-slot": "card-footer",
992
+ className: cn(cardFooterClass, className),
993
+ ...props
994
+ }
995
+ );
996
+ }
997
+ );
956
998
  var sizeClass2 = {
957
- sm: "h-3.5 w-3.5",
958
- md: "h-4 w-4"
999
+ sm: "size-3.5",
1000
+ md: "size-4"
959
1001
  };
960
1002
  var Checkbox = react.forwardRef(function Checkbox2({
961
1003
  checked,
@@ -998,7 +1040,7 @@ var Checkbox = react.forwardRef(function Checkbox2({
998
1040
  "indeterminate:border-primary indeterminate:bg-primary",
999
1041
  "hover:border-ring",
1000
1042
  "disabled:cursor-not-allowed disabled:opacity-50",
1001
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background"
1043
+ "focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-primary-glow"
1002
1044
  ),
1003
1045
  ...rest
1004
1046
  }
@@ -1008,7 +1050,7 @@ var Checkbox = react.forwardRef(function Checkbox2({
1008
1050
  {
1009
1051
  "aria-hidden": "true",
1010
1052
  strokeWidth: 3,
1011
- className: "pointer-events-none absolute inset-0 m-auto h-3 w-3 text-primary-foreground opacity-0 peer-checked:opacity-100 peer-indeterminate:opacity-0"
1053
+ className: "pointer-events-none absolute inset-0 m-auto size-3 text-primary-foreground opacity-0 peer-checked:opacity-100 peer-indeterminate:opacity-0"
1012
1054
  }
1013
1055
  ),
1014
1056
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1016,7 +1058,7 @@ var Checkbox = react.forwardRef(function Checkbox2({
1016
1058
  {
1017
1059
  "aria-hidden": "true",
1018
1060
  strokeWidth: 3,
1019
- className: "pointer-events-none absolute inset-0 m-auto h-3 w-3 text-primary-foreground opacity-0 peer-indeterminate:opacity-100"
1061
+ className: "pointer-events-none absolute inset-0 m-auto size-3 text-primary-foreground opacity-0 peer-indeterminate:opacity-100"
1020
1062
  }
1021
1063
  )
1022
1064
  ] });
@@ -1033,20 +1075,20 @@ var datePickerTriggerSizeClass = {
1033
1075
  md: "h-9 rounded-md ps-3 pe-9 text-sm gap-2",
1034
1076
  lg: "h-11 rounded-md ps-4 pe-10 text-base gap-2"
1035
1077
  };
1036
- var datePickerTriggerBaseClass = "group/datepicker relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-1 focus-visible:ring-offset-background aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer";
1078
+ var datePickerTriggerBaseClass = "group/datepicker relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-visible:ring-[3px] focus-visible:ring-primary-glow aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer";
1037
1079
  var datePickerPlaceholderClass = "truncate text-muted-foreground";
1038
1080
  var datePickerValueClass = "truncate text-foreground";
1039
1081
  var datePickerContentClass = "z-50 overflow-hidden rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
1040
1082
  var datePickerCalendarClass = "text-sm";
1041
1083
  var datePickerCaptionClass = "flex items-center justify-between gap-2 pb-2 text-sm font-semibold";
1042
- var datePickerNavButtonClass = "inline-flex h-7 w-7 items-center justify-center rounded-md border border-input bg-background text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50";
1084
+ var datePickerNavButtonClass = "inline-flex size-7 items-center justify-center rounded-md border border-input bg-background text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50";
1043
1085
  var datePickerDayWrapperClass = "p-0 text-center";
1044
- var datePickerDayBaseClass = "inline-flex h-8 w-8 items-center justify-center rounded-md text-sm text-foreground font-normal transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40";
1086
+ var datePickerDayBaseClass = "inline-flex size-8 items-center justify-center rounded-md text-sm text-foreground font-normal transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40";
1045
1087
  var datePickerSelectedClass = "[&_button]:bg-primary [&_button]:text-primary-foreground [&_button]:hover:bg-primary [&_button]:hover:text-primary-foreground";
1046
1088
  var datePickerTodayClass = "[&_button]:font-semibold [&_button]:ring-1 [&_button]:ring-inset [&_button]:ring-ring/40";
1047
1089
  var datePickerOutsideClass = "[&_button]:text-muted-foreground [&_button]:opacity-60";
1048
1090
  var datePickerDisabledClass = "[&_button]:pointer-events-none [&_button]:opacity-40";
1049
- var datePickerWeekdayClass = "h-8 w-8 text-center text-xs font-medium text-muted-foreground";
1091
+ var datePickerWeekdayClass = "size-8 text-center text-xs font-medium text-muted-foreground";
1050
1092
  var datePickerWeekClass = "flex w-full";
1051
1093
  var datePickerWeekdaysClass = "flex w-full";
1052
1094
  var datePickerMonthGridClass = "w-full border-collapse";
@@ -1357,6 +1399,9 @@ var pageHeaderBorderedClass = "border-b border-border pb-4";
1357
1399
  var pageHeaderTitleRowClass = "flex flex-wrap items-start justify-between gap-3 sm:gap-4";
1358
1400
  var pageHeaderTitleBlockClass = "min-w-0 flex-1 space-y-1";
1359
1401
  var pageHeaderTitleClass = "text-2xl font-semibold tracking-tight text-foreground";
1402
+ var pageHeaderEyebrowClass = "text-xs font-semibold uppercase tracking-wide text-primary";
1403
+ var pageHeaderTitleLineClass = "flex flex-wrap items-center gap-x-2.5 gap-y-1";
1404
+ var pageHeaderTitleMetaClass = "shrink-0";
1360
1405
  var pageHeaderDescriptionClass = "text-sm text-muted-foreground";
1361
1406
  var pageHeaderActionsClass = "flex shrink-0 flex-wrap items-center gap-2";
1362
1407
  var pageHeaderBackClass = "inline-flex items-center gap-1.5 self-start text-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-md";
@@ -1365,6 +1410,8 @@ var pageHeaderBreadcrumbsClass = "text-xs text-muted-foreground";
1365
1410
  var PageHeader = react.forwardRef(function PageHeader2({
1366
1411
  title,
1367
1412
  description,
1413
+ eyebrow,
1414
+ titleMeta,
1368
1415
  breadcrumbs,
1369
1416
  back,
1370
1417
  actions,
@@ -1385,11 +1432,15 @@ var PageHeader = react.forwardRef(function PageHeader2({
1385
1432
  back ? /* @__PURE__ */ jsxRuntime.jsx(PageHeaderBack, { ...back }) : null,
1386
1433
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "page-header-row", className: pageHeaderTitleRowClass, children: [
1387
1434
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: pageHeaderTitleBlockClass, children: [
1388
- react.createElement(
1389
- as,
1390
- { "data-slot": "page-header-title", className: pageHeaderTitleClass },
1391
- title
1392
- ),
1435
+ eyebrow ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-slot": "page-header-eyebrow", className: pageHeaderEyebrowClass, children: eyebrow }) : null,
1436
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: pageHeaderTitleLineClass, children: [
1437
+ react.createElement(
1438
+ as,
1439
+ { "data-slot": "page-header-title", className: pageHeaderTitleClass },
1440
+ title
1441
+ ),
1442
+ titleMeta ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-slot": "page-header-title-meta", className: pageHeaderTitleMetaClass, children: titleMeta }) : null
1443
+ ] }),
1393
1444
  description ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-slot": "page-header-description", className: pageHeaderDescriptionClass, children: description }) : null
1394
1445
  ] }),
1395
1446
  actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "page-header-actions", className: pageHeaderActionsClass, children: actions }) : null
@@ -1421,7 +1472,7 @@ function PageHeaderBack({ label = "Back", to, onClick, render }) {
1421
1472
  var detailPageBaseClass = "flex w-full flex-col gap-6";
1422
1473
  var detailPageBodyClass = "flex flex-col gap-6";
1423
1474
  var detailPageSkeletonRowClass = "h-5 w-full animate-pulse rounded-md bg-muted";
1424
- var detailPageEmptyClass = "rounded-md border border-border bg-card";
1475
+ var detailPageEmptyClass = "rounded-xl border border-border bg-card";
1425
1476
  var DEFAULT_LABELS_LTR = {
1426
1477
  back: "Back",
1427
1478
  notFoundTitle: "Not found",
@@ -2088,7 +2139,7 @@ var inputSizeClass = {
2088
2139
  md: "h-9 rounded-md px-3 text-sm gap-2",
2089
2140
  lg: "h-11 rounded-md px-4 text-base gap-2.5"
2090
2141
  };
2091
- var inputBaseClass = "group/input relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-within:ring-2 focus-within:ring-ring/40 focus-within:ring-offset-1 focus-within:ring-offset-background aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-within:ring-destructive/40 has-[input:disabled]:pointer-events-none has-[input:disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0";
2142
+ var inputBaseClass = "group/input relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-within:ring-[3px] focus-within:ring-primary-glow aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-within:ring-destructive/40 has-[input:disabled]:pointer-events-none has-[input:disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0";
2092
2143
  var Input = react.forwardRef(function Input2({
2093
2144
  variant = "default",
2094
2145
  inputSize = "md",
@@ -2122,7 +2173,7 @@ var Input = react.forwardRef(function Input2({
2122
2173
  "span",
2123
2174
  {
2124
2175
  "aria-hidden": "true",
2125
- className: "inline-flex h-4 w-4 items-center justify-center text-muted-foreground",
2176
+ className: "inline-flex size-4 items-center justify-center text-muted-foreground",
2126
2177
  children: leadingIcon
2127
2178
  }
2128
2179
  ) : null,
@@ -2146,7 +2197,7 @@ var Input = react.forwardRef(function Input2({
2146
2197
  "span",
2147
2198
  {
2148
2199
  "aria-hidden": "true",
2149
- className: "inline-flex h-4 w-4 items-center justify-center text-muted-foreground",
2200
+ className: "inline-flex size-4 items-center justify-center text-muted-foreground",
2150
2201
  children: trailingIcon
2151
2202
  }
2152
2203
  ) : null
@@ -2267,7 +2318,7 @@ function Pagination({
2267
2318
  disabled: isFirst,
2268
2319
  onClick: goPrev,
2269
2320
  "aria-label": labels.previousPage,
2270
- children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
2321
+ children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "size-3.5" })
2271
2322
  }
2272
2323
  ),
2273
2324
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-1 text-foreground", children: [
@@ -2284,7 +2335,7 @@ function Pagination({
2284
2335
  disabled: isLast,
2285
2336
  onClick: goNext,
2286
2337
  "aria-label": labels.nextPage,
2287
- children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
2338
+ children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "size-3.5" })
2288
2339
  }
2289
2340
  )
2290
2341
  ] })
@@ -2313,23 +2364,23 @@ function Toolbar({ count, onClear, renderLabel, clearLabel, children }) {
2313
2364
  var tableSizeClass = {
2314
2365
  sm: {
2315
2366
  row: "",
2316
- cell: "px-3 py-1.5 text-xs",
2367
+ cell: "px-3 py-1.5 text-xs tabular-nums",
2317
2368
  head: "whitespace-nowrap px-3 py-2 text-xs font-medium"
2318
2369
  },
2319
2370
  md: {
2320
2371
  row: "",
2321
- cell: "px-4 py-2.5 text-sm",
2372
+ cell: "px-4 py-2.5 text-sm tabular-nums",
2322
2373
  head: "whitespace-nowrap px-4 py-2.5 text-xs font-medium uppercase tracking-wide"
2323
2374
  },
2324
2375
  lg: {
2325
2376
  row: "",
2326
- cell: "px-5 py-3.5 text-sm",
2377
+ cell: "px-5 py-3.5 text-sm tabular-nums",
2327
2378
  head: "whitespace-nowrap px-5 py-3 text-sm font-medium"
2328
2379
  }
2329
2380
  };
2330
2381
  var tableBaseClass = "w-full caption-bottom border-collapse";
2331
- var selectedRowClass = "bg-muted/40";
2332
- var sortIconClass = "inline-flex h-3 w-3 shrink-0 items-center justify-center";
2382
+ var selectedRowClass = "bg-primary/10";
2383
+ var sortIconClass = "inline-flex size-3 shrink-0 items-center justify-center";
2333
2384
  var alignClass = {
2334
2385
  start: "text-start",
2335
2386
  center: "text-center",
@@ -2456,7 +2507,7 @@ function Table(props) {
2456
2507
  "div",
2457
2508
  {
2458
2509
  className: cn(
2459
- "overflow-x-auto rounded-md border border-border bg-background",
2510
+ "overflow-x-auto rounded-xl border border-border bg-card shadow-[var(--shadow-card)]",
2460
2511
  maxHeight !== void 0 && "overflow-y-auto"
2461
2512
  ),
2462
2513
  style: maxHeight !== void 0 ? { maxHeight } : void 0,
@@ -2474,9 +2525,11 @@ function Table(props) {
2474
2525
  "thead",
2475
2526
  {
2476
2527
  className: cn(
2477
- // Opaque (not bg-muted/40) so a sticky header fully hides the rows
2478
- // scrolling underneath it.
2479
- "bg-muted text-muted-foreground",
2528
+ // Clean opaque header (so a sticky header fully hides the rows
2529
+ // scrolling underneath it) with a hairline bottom rule drawn via an
2530
+ // inset shadow — it stays attached to the sticky header instead of
2531
+ // collapsing into the first row's border.
2532
+ "bg-card text-muted-foreground shadow-[inset_0_-1px_0_var(--color-border)]",
2480
2533
  maxHeight !== void 0 && "sticky top-0 z-10"
2481
2534
  ),
2482
2535
  children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
@@ -2553,8 +2606,8 @@ function Table(props) {
2553
2606
  "data-selected": isSelected ? "true" : void 0,
2554
2607
  "aria-selected": enableRowSelection ? isSelected : void 0,
2555
2608
  className: cn(
2556
- "border-t border-border transition-colors",
2557
- "hover:bg-accent",
2609
+ "border-t border-border/60 first:border-t-0 transition-colors",
2610
+ "hover:bg-primary/5",
2558
2611
  striped && rowIndex % 2 === 1 && "bg-muted/20",
2559
2612
  isSelected && selectedRowClass,
2560
2613
  onRowClick && "cursor-pointer"
@@ -2637,10 +2690,7 @@ function SkeletonRows({ rowCount, columnCount, cellClassName }) {
2637
2690
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: rowKeys.map((rowKey) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "border-t border-border", "data-testid": "table-skeleton-row", children: colKeys.map((colKey) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: cellClassName, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block h-3 w-full animate-pulse rounded bg-muted" }) }, `${rowKey}-${colKey}`)) }, rowKey)) });
2638
2691
  }
2639
2692
  function SortIndicator({ active, direction }) {
2640
- const className = cn(
2641
- "h-3.5 w-3.5 shrink-0",
2642
- active ? "text-foreground" : "text-muted-foreground"
2643
- );
2693
+ const className = cn("size-3.5 shrink-0", active ? "text-foreground" : "text-muted-foreground");
2644
2694
  if (!active) return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { "aria-hidden": "true", className });
2645
2695
  return direction === "asc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { "aria-hidden": "true", className }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { "aria-hidden": "true", className });
2646
2696
  }
@@ -2656,11 +2706,11 @@ var selectSizeClass = {
2656
2706
  md: "h-9 rounded-md ps-3 pe-9 text-sm",
2657
2707
  lg: "h-11 rounded-md ps-4 pe-10 text-base"
2658
2708
  };
2659
- var selectBaseClass = "group/select relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus:ring-2 focus:ring-ring/40 focus:ring-offset-1 focus:ring-offset-background aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer data-[placeholder]:text-muted-foreground";
2709
+ var selectBaseClass = "group/select relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus:ring-[3px] focus:ring-primary-glow aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer data-[placeholder]:text-muted-foreground";
2660
2710
  var selectContentClass = "z-50 max-h-(--radix-select-content-available-height) min-w-(--radix-select-trigger-width) overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
2661
2711
  var selectViewportClass = "p-1";
2662
2712
  var selectItemClass = "relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 ps-8 pe-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
2663
- var selectItemIndicatorClass = "absolute start-2 inline-flex h-3.5 w-3.5 items-center justify-center [&_svg]:h-3.5 [&_svg]:w-3.5";
2713
+ var selectItemIndicatorClass = "absolute start-2 inline-flex size-3.5 items-center justify-center [&_svg]:h-3.5 [&_svg]:w-3.5";
2664
2714
  var selectGroupLabelClass = "px-2 py-1.5 text-xs font-semibold text-muted-foreground";
2665
2715
  var selectSeparatorClass = "-mx-1 my-1 h-px bg-border";
2666
2716
  var selectStatusClass = "flex items-center justify-center gap-2 px-2 py-6 text-center text-sm text-muted-foreground";
@@ -3023,6 +3073,16 @@ function hasActiveFilters(filters, values) {
3023
3073
  }
3024
3074
  return false;
3025
3075
  }
3076
+ function countActiveFilters(filters, values) {
3077
+ let count = 0;
3078
+ for (const filter of filters ?? []) {
3079
+ const current = values?.[filter.key];
3080
+ if (current === void 0) continue;
3081
+ const value = filter.type === "text" ? current.trim() : current;
3082
+ if (value !== filterDefaultValue(filter)) count += 1;
3083
+ }
3084
+ return count;
3085
+ }
3026
3086
  function DebouncedFilterInput({
3027
3087
  value,
3028
3088
  onChange,
@@ -3087,7 +3147,6 @@ function ListPageFilterBar({
3087
3147
  labels
3088
3148
  }) {
3089
3149
  const manual = mode === "manual";
3090
- const active = hasActiveFilters(filters, values);
3091
3150
  const appliedKey = JSON.stringify(values ?? {});
3092
3151
  const [draft, setDraft] = react.useState(values ?? {});
3093
3152
  react.useEffect(() => {
@@ -3118,8 +3177,11 @@ function ListPageFilterBar({
3118
3177
  for (const filter of filters ?? []) {
3119
3178
  onChange?.(filter.key, filterDefaultValue(filter));
3120
3179
  }
3180
+ if (manual) setDraft({});
3121
3181
  };
3122
- const controls = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: filters?.map((filter) => /* @__PURE__ */ jsxRuntime.jsx(
3182
+ if (!filters || filters.length === 0) return null;
3183
+ const activeCount = countActiveFilters(filters, effectiveValues);
3184
+ const controls = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: filters.map((filter) => /* @__PURE__ */ jsxRuntime.jsx(
3123
3185
  FilterControl,
3124
3186
  {
3125
3187
  filter,
@@ -3130,22 +3192,41 @@ function ListPageFilterBar({
3130
3192
  },
3131
3193
  filter.key
3132
3194
  )) });
3133
- const resetButton = active && !disabled ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", size: "sm", onClick: reset, children: [
3134
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" }),
3135
- labels.reset
3136
- ] }) : null;
3195
+ const header = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 border-b border-border bg-primary/5 px-4 py-3", children: [
3196
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-foreground", children: labels.title ?? "Filters" }),
3197
+ activeCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center rounded-full bg-primary/10 px-2 py-0.5 text-xs font-semibold text-primary", children: [
3198
+ activeCount,
3199
+ " ",
3200
+ labels.activeLabel ?? "active"
3201
+ ] }) : null,
3202
+ activeCount > 0 && !disabled ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "ms-auto", onClick: reset, children: [
3203
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" }),
3204
+ labels.reset
3205
+ ] }) : null
3206
+ ] });
3207
+ const cardClass = "overflow-hidden rounded-xl border border-border bg-card";
3137
3208
  if (manual) {
3138
- return /* @__PURE__ */ jsxRuntime.jsxs("form", { "data-slot": "list-page-filter-bar", className: "space-y-3", onSubmit: apply, children: [
3139
- controls,
3140
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
3141
- resetButton,
3142
- /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", size: "sm", disabled: disabled || !dirty, children: labels.apply ?? "Apply" })
3209
+ return /* @__PURE__ */ jsxRuntime.jsxs("form", { "data-slot": "list-page-filter-bar", className: cardClass, onSubmit: apply, children: [
3210
+ header,
3211
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 p-4", children: [
3212
+ controls,
3213
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
3214
+ Button,
3215
+ {
3216
+ type: "submit",
3217
+ size: "sm",
3218
+ leadingIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "size-4" }),
3219
+ className: "min-w-32",
3220
+ disabled: disabled || !dirty,
3221
+ children: labels.apply ?? "Apply"
3222
+ }
3223
+ ) })
3143
3224
  ] })
3144
3225
  ] });
3145
3226
  }
3146
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page-filter-bar", className: "space-y-3", children: [
3147
- controls,
3148
- resetButton ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: resetButton }) : null
3227
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page-filter-bar", className: cardClass, children: [
3228
+ header,
3229
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: controls })
3149
3230
  ] });
3150
3231
  }
3151
3232
  function FilterControl({ filter, value, onChange, disabled, mode }) {
@@ -3213,6 +3294,8 @@ function renderFilterControl({
3213
3294
  var EN_LABELS2 = {
3214
3295
  reset: "Reset filters",
3215
3296
  apply: "Apply",
3297
+ filtersTitle: "Filters",
3298
+ filtersActive: "active",
3216
3299
  emptyTitle: "No results",
3217
3300
  emptyDescription: "Try clearing the search or adjusting the filters.",
3218
3301
  noDataTitle: "No data yet",
@@ -3220,7 +3303,9 @@ var EN_LABELS2 = {
3220
3303
  };
3221
3304
  var AR_LABELS2 = {
3222
3305
  reset: "\u0625\u0639\u0627\u062F\u0629 \u062A\u0639\u064A\u064A\u0646 \u0627\u0644\u0641\u0644\u0627\u062A\u0631",
3223
- apply: "\u062A\u0637\u0628\u064A\u0642",
3306
+ apply: "\u0639\u0631\u0636 \u0627\u0644\u0646\u062A\u0627\u0626\u062C",
3307
+ filtersTitle: "\u0627\u0644\u062A\u0635\u0641\u064A\u0629",
3308
+ filtersActive: "\u0645\u0641\u0639\u0651\u0644",
3224
3309
  emptyTitle: "\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C",
3225
3310
  emptyDescription: "\u062C\u0631\u0651\u0628 \u0645\u0633\u062D \u0627\u0644\u0628\u062D\u062B \u0623\u0648 \u062A\u0639\u062F\u064A\u0644 \u0627\u0644\u0641\u0644\u0627\u062A\u0631.",
3226
3311
  noDataTitle: "\u0644\u0627 \u062A\u0648\u062C\u062F \u0628\u064A\u0627\u0646\u0627\u062A \u0628\u0639\u062F",
@@ -3245,6 +3330,7 @@ function ListPage({
3245
3330
  pagination,
3246
3331
  onPaginationChange,
3247
3332
  totalCount,
3333
+ eyebrow,
3248
3334
  pageSizeOptions,
3249
3335
  emptyState,
3250
3336
  noDataState,
@@ -3265,7 +3351,17 @@ function ListPage({
3265
3351
  };
3266
3352
  const tableMode = isLoading ? "loading" : data.length === 0 && !hasActiveQuery ? "no-data" : data.length === 0 && hasActiveQuery ? "no-results" : "rows";
3267
3353
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page", className: cn("space-y-6", className), children: [
3268
- /* @__PURE__ */ jsxRuntime.jsx(PageHeader, { title, description, bordered, actions }),
3354
+ /* @__PURE__ */ jsxRuntime.jsx(
3355
+ PageHeader,
3356
+ {
3357
+ title,
3358
+ description,
3359
+ eyebrow,
3360
+ titleMeta: typeof totalCount === "number" && totalCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "primary", tone: "soft", size: "sm", children: totalCount }) : void 0,
3361
+ bordered,
3362
+ actions
3363
+ }
3364
+ ),
3269
3365
  showFilterBar ? /* @__PURE__ */ jsxRuntime.jsx(
3270
3366
  ListPageFilterBar,
3271
3367
  {
@@ -3273,7 +3369,12 @@ function ListPage({
3273
3369
  values: filterValues,
3274
3370
  onChange: onFilterChange,
3275
3371
  mode: filterMode,
3276
- labels: { reset: labels.reset, apply: labels.apply }
3372
+ labels: {
3373
+ reset: labels.reset,
3374
+ apply: labels.apply,
3375
+ title: labels.filtersTitle,
3376
+ activeLabel: labels.filtersActive
3377
+ }
3277
3378
  }
3278
3379
  ) : null,
3279
3380
  tableMode === "loading" || tableMode === "rows" ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -3350,7 +3451,7 @@ var radioLabelSizeClass = {
3350
3451
  md: "text-sm",
3351
3452
  lg: "text-base"
3352
3453
  };
3353
- var radioItemBaseClass = "aspect-square shrink-0 rounded-full border border-input bg-background text-primary outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background hover:border-ring disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/40 data-[state=checked]:border-primary";
3454
+ var radioItemBaseClass = "aspect-square shrink-0 rounded-full border border-input bg-background text-primary outline-none transition-colors focus-visible:ring-[3px] focus-visible:ring-primary-glow hover:border-ring disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/40 data-[state=checked]:border-primary";
3354
3455
  var radioIndicatorBaseClass = "flex h-full w-full items-center justify-center";
3355
3456
  var radioIndicatorDotClass = "rounded-full bg-primary";
3356
3457
  var radioOptionRowClass = "flex cursor-pointer items-start gap-2 has-[button:disabled]:cursor-not-allowed";
@@ -3521,7 +3622,7 @@ var switchThumbClass = {
3521
3622
  md: "size-4 data-[state=checked]:translate-x-4 data-[state=checked]:rtl:-translate-x-4",
3522
3623
  lg: "size-5 data-[state=checked]:translate-x-5 data-[state=checked]:rtl:-translate-x-5"
3523
3624
  };
3524
- var switchTrackBaseClass = "relative inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary aria-[invalid=true]:ring-2 aria-[invalid=true]:ring-destructive/40";
3625
+ var switchTrackBaseClass = "relative inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input transition-colors focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-primary-glow disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary aria-[invalid=true]:ring-[3px] aria-[invalid=true]:ring-destructive/40";
3525
3626
  var switchThumbBaseClass = "pointer-events-none block rounded-full bg-background shadow-sm ring-0 transition-transform";
3526
3627
  var Switch = react.forwardRef(function Switch2({
3527
3628
  switchSize = "md",
@@ -3602,7 +3703,7 @@ var textareaResizeClass = {
3602
3703
  horizontal: "resize-x",
3603
3704
  both: "resize"
3604
3705
  };
3605
- var textareaBaseClass = "group/textarea relative flex w-full text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-within:ring-2 focus-within:ring-ring/40 focus-within:ring-offset-1 focus-within:ring-offset-background aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-within:ring-destructive/40 has-[textarea:disabled]:pointer-events-none has-[textarea:disabled]:opacity-50";
3706
+ var textareaBaseClass = "group/textarea relative flex w-full text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-within:ring-[3px] focus-within:ring-primary-glow aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-within:ring-destructive/40 has-[textarea:disabled]:pointer-events-none has-[textarea:disabled]:opacity-50";
3606
3707
  var Textarea = react.forwardRef(function Textarea2({
3607
3708
  variant = "default",
3608
3709
  textareaSize = "md",
@@ -3765,6 +3866,12 @@ exports.AppShell = AppShell;
3765
3866
  exports.Avatar = Avatar;
3766
3867
  exports.Badge = Badge;
3767
3868
  exports.Button = Button;
3869
+ exports.Card = Card;
3870
+ exports.CardContent = CardContent;
3871
+ exports.CardDescription = CardDescription;
3872
+ exports.CardFooter = CardFooter;
3873
+ exports.CardHeader = CardHeader;
3874
+ exports.CardTitle = CardTitle;
3768
3875
  exports.Checkbox = Checkbox;
3769
3876
  exports.ConfirmDialogProvider = ConfirmDialogProvider;
3770
3877
  exports.DashboardContent = DashboardContent;
@@ -3826,10 +3933,17 @@ exports.TooltipProvider = TooltipProvider;
3826
3933
  exports.badgeBaseClass = badgeBaseClass;
3827
3934
  exports.badgeDotSizeClass = badgeDotSizeClass;
3828
3935
  exports.badgeSizeClass = badgeSizeClass;
3936
+ exports.badgeSoftVariantClass = badgeSoftVariantClass;
3829
3937
  exports.badgeVariantClass = badgeVariantClass;
3830
3938
  exports.buttonBaseClass = buttonBaseClass;
3831
3939
  exports.buttonSizeClass = buttonSizeClass;
3832
3940
  exports.buttonVariantClass = buttonVariantClass;
3941
+ exports.cardBaseClass = cardBaseClass;
3942
+ exports.cardContentClass = cardContentClass;
3943
+ exports.cardDescriptionClass = cardDescriptionClass;
3944
+ exports.cardFooterClass = cardFooterClass;
3945
+ exports.cardHeaderClass = cardHeaderClass;
3946
+ exports.cardTitleClass = cardTitleClass;
3833
3947
  exports.cn = cn;
3834
3948
  exports.datePickerCalendarClass = datePickerCalendarClass;
3835
3949
  exports.datePickerCaptionClass = datePickerCaptionClass;
@@ -3910,8 +4024,11 @@ exports.pageHeaderBaseClass = pageHeaderBaseClass;
3910
4024
  exports.pageHeaderBorderedClass = pageHeaderBorderedClass;
3911
4025
  exports.pageHeaderBreadcrumbsClass = pageHeaderBreadcrumbsClass;
3912
4026
  exports.pageHeaderDescriptionClass = pageHeaderDescriptionClass;
4027
+ exports.pageHeaderEyebrowClass = pageHeaderEyebrowClass;
3913
4028
  exports.pageHeaderTitleBlockClass = pageHeaderTitleBlockClass;
3914
4029
  exports.pageHeaderTitleClass = pageHeaderTitleClass;
4030
+ exports.pageHeaderTitleLineClass = pageHeaderTitleLineClass;
4031
+ exports.pageHeaderTitleMetaClass = pageHeaderTitleMetaClass;
3915
4032
  exports.pageHeaderTitleRowClass = pageHeaderTitleRowClass;
3916
4033
  exports.radioGroupBaseClass = radioGroupBaseClass;
3917
4034
  exports.radioGroupOrientationClass = radioGroupOrientationClass;