@almadar/ui 5.130.0 → 5.132.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.
@@ -538,6 +538,26 @@ var init_useDragReorder = __esm({
538
538
  "use client";
539
539
  }
540
540
  });
541
+ function useMediaQuery(query) {
542
+ const subscribe = useCallback(
543
+ (onChange) => {
544
+ const mql = window.matchMedia(query);
545
+ mql.addEventListener("change", onChange);
546
+ return () => mql.removeEventListener("change", onChange);
547
+ },
548
+ [query]
549
+ );
550
+ return useSyncExternalStore(
551
+ subscribe,
552
+ () => window.matchMedia(query).matches,
553
+ () => false
554
+ );
555
+ }
556
+ var init_useMediaQuery = __esm({
557
+ "hooks/useMediaQuery.ts"() {
558
+ "use client";
559
+ }
560
+ });
541
561
  function useInfiniteScroll(onLoadMore, options = {}) {
542
562
  const { rootMargin = "200px", hasMore = true, isLoading = false } = options;
543
563
  const observerRef = useRef(null);
@@ -1577,7 +1597,7 @@ var init_Button = __esm({
1577
1597
  "cursor-pointer",
1578
1598
  "chrome-button",
1579
1599
  "transition-all duration-normal",
1580
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-offset-[length:var(--focus-ring-offset)]",
1600
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--focus-ring-offset)]",
1581
1601
  "disabled:opacity-50 disabled:cursor-not-allowed",
1582
1602
  variantStyles[variant],
1583
1603
  sizeStyles[size],
@@ -2298,6 +2318,8 @@ var init_Badge = __esm({
2298
2318
  };
2299
2319
  const iconPx = size === "lg" ? 20 : 16;
2300
2320
  const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsx(AtlasImage, { asset: iconAsset, size: iconPx, alt: iconAsset.name ?? iconAsset.category ?? "", className: "flex-shrink-0" }) : typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsx(Icon, { icon, className: iconSizes3[size] }) : null;
2321
+ const hasText = Boolean(children) || amount != null || label !== void 0 && label !== null && label !== "";
2322
+ if (!hasText && !resolvedIcon && !onRemove) return null;
2301
2323
  return /* @__PURE__ */ jsxs(
2302
2324
  "span",
2303
2325
  {
@@ -2324,7 +2346,7 @@ var init_Badge = __esm({
2324
2346
  },
2325
2347
  className: cn(
2326
2348
  "inline-flex items-center justify-center rounded-sm",
2327
- "hover:bg-foreground/10 focus:outline-none focus:ring-1 focus:ring-ring",
2349
+ "hover:bg-foreground/10 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
2328
2350
  "transition-colors",
2329
2351
  size === "sm" ? "w-4 h-4 ml-0.5" : size === "md" ? "w-5 h-5 ml-1" : "w-6 h-6 ml-1"
2330
2352
  ),
@@ -3682,7 +3704,7 @@ function NativeSelect({
3682
3704
  "block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
3683
3705
  "px-3 py-2 pr-10 text-sm text-foreground font-medium",
3684
3706
  "bg-card",
3685
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
3707
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
3686
3708
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
3687
3709
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
3688
3710
  className
@@ -3789,7 +3811,7 @@ function RichSelect({
3789
3811
  "block w-full border-[length:var(--border-width)] shadow-sm",
3790
3812
  "px-3 py-2 pr-10 text-sm text-start font-medium",
3791
3813
  "bg-card rounded-sm",
3792
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
3814
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
3793
3815
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
3794
3816
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
3795
3817
  !hasValue && "text-muted-foreground"
@@ -4712,9 +4734,9 @@ var init_Radio = __esm({
4712
4734
  "flex items-center justify-center",
4713
4735
  "border-[length:var(--border-width)] transition-all cursor-pointer",
4714
4736
  sizeClasses4[size],
4715
- hasError ? "border-error peer-focus:ring-error/20" : "border-border peer-focus:ring-ring/20",
4737
+ hasError ? "border-error peer-focus-visible:ring-error/20" : "border-border peer-focus-visible:ring-ring/20",
4716
4738
  isChecked2 ? hasError ? "border-error" : "border-primary bg-primary" : "",
4717
- "peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-offset-2",
4739
+ "peer-focus:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2",
4718
4740
  disabled && "opacity-50 cursor-not-allowed",
4719
4741
  !disabled && "hover:border-[var(--color-border-hover)]"
4720
4742
  ),
@@ -5185,7 +5207,7 @@ var init_ThemeToggle = __esm({
5185
5207
  "inline-flex items-center justify-center gap-2",
5186
5208
  "text-foreground",
5187
5209
  "hover:bg-muted border-[length:var(--border-width)] border-transparent hover:border-border",
5188
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
5210
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
5189
5211
  "transition-colors duration-fast",
5190
5212
  sizeClasses5[size],
5191
5213
  className
@@ -5620,11 +5642,13 @@ var init_TrendIndicator = __esm({
5620
5642
  size = "md",
5621
5643
  ...props
5622
5644
  }, ref) => {
5623
- const dir = resolveDirection(value, direction);
5645
+ const hasValue = typeof value === "number" && Number.isFinite(value);
5646
+ if (!hasValue && !direction) return null;
5647
+ const dir = resolveDirection(hasValue ? value : void 0, direction);
5624
5648
  const colorClass = resolveColor(dir, invert);
5625
5649
  const iconName = iconNameMap[dir];
5626
5650
  const styles = sizeStyles6[size];
5627
- const formattedValue = value !== void 0 ? `${value > 0 ? "+" : ""}${value}%` : void 0;
5651
+ const formattedValue = hasValue ? `${value > 0 ? "+" : ""}${value}%` : void 0;
5628
5652
  const ariaLabel = label ?? (formattedValue ? `${dir} ${formattedValue}` : dir);
5629
5653
  return /* @__PURE__ */ jsxs(
5630
5654
  "span",
@@ -11430,10 +11454,12 @@ var init_Container = __esm({
11430
11454
  };
11431
11455
  paddingStyles3 = {
11432
11456
  none: "px-0",
11433
- sm: "px-4",
11434
- md: "px-6",
11435
- lg: "px-8",
11436
- xl: "px-12"
11457
+ // Mobile-tighter, desktop-identical: fixed px-6 on a 360px phone eats ~13% of
11458
+ // the viewport, so each token steps down below the sm breakpoint.
11459
+ sm: "px-3 sm:px-4",
11460
+ md: "px-4 sm:px-6",
11461
+ lg: "px-4 sm:px-6 md:px-8",
11462
+ xl: "px-4 sm:px-8 md:px-12"
11437
11463
  };
11438
11464
  Container = ({
11439
11465
  size,
@@ -12132,7 +12158,7 @@ var init_Accordion = __esm({
12132
12158
  "bg-card",
12133
12159
  "hover:bg-muted",
12134
12160
  "transition-colors duration-fast",
12135
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-inset",
12161
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
12136
12162
  "disabled:opacity-50 disabled:cursor-not-allowed",
12137
12163
  isOpen && "bg-muted font-bold"
12138
12164
  ),
@@ -17679,26 +17705,19 @@ var init_BookViewer = __esm({
17679
17705
  function BoxPattern({
17680
17706
  p,
17681
17707
  m,
17682
- bg = "transparent",
17683
- border = false,
17684
- radius = "none",
17685
- shadow = "none",
17686
- className,
17687
- style,
17688
- children
17708
+ radius,
17709
+ isLoading: _isLoading,
17710
+ error: _error,
17711
+ entity: _entity,
17712
+ ...boxProps
17689
17713
  }) {
17690
17714
  return /* @__PURE__ */ jsx(
17691
17715
  Box,
17692
17716
  {
17693
- padding: p,
17694
- margin: m,
17695
- bg,
17696
- border,
17697
- rounded: radius,
17698
- shadow,
17699
- className,
17700
- style,
17701
- children
17717
+ padding: boxProps.padding ?? p,
17718
+ margin: boxProps.margin ?? m,
17719
+ rounded: boxProps.rounded ?? radius,
17720
+ ...boxProps
17702
17721
  }
17703
17722
  );
17704
17723
  }
@@ -18287,7 +18306,7 @@ var init_Breadcrumb = __esm({
18287
18306
  },
18288
18307
  className: cn(
18289
18308
  "flex items-center gap-1.5 transition-colors",
18290
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
18309
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
18291
18310
  isLast ? "text-foreground font-bold cursor-default" : "text-muted-foreground hover:text-foreground"
18292
18311
  ),
18293
18312
  "aria-current": isLast ? "page" : void 0,
@@ -21308,17 +21327,19 @@ var init_DashboardLayout = __esm({
21308
21327
  const [sidebarOpen, setSidebarOpen] = useState(false);
21309
21328
  const [userMenuOpen, setUserMenuOpen] = useState(false);
21310
21329
  const layoutRef = useRef(null);
21311
- const [isMobile, setIsMobile] = useState(false);
21330
+ const [layoutWidth, setLayoutWidth] = useState(null);
21312
21331
  useEffect(() => {
21313
21332
  const el = layoutRef.current;
21314
21333
  if (!el || typeof ResizeObserver === "undefined") return;
21315
21334
  const ro = new ResizeObserver((entries) => {
21316
21335
  const w = entries[0]?.contentRect.width ?? el.clientWidth;
21317
- setIsMobile(w < 1024);
21336
+ setLayoutWidth(w);
21318
21337
  });
21319
21338
  ro.observe(el);
21320
21339
  return () => ro.disconnect();
21321
21340
  }, []);
21341
+ const isMobile = layoutWidth !== null && layoutWidth < 768;
21342
+ const isRail = layoutWidth !== null && layoutWidth >= 768 && layoutWidth < 1024;
21322
21343
  useEffect(() => {
21323
21344
  if (!isMobile && sidebarOpen) setSidebarOpen(false);
21324
21345
  }, [isMobile, sidebarOpen]);
@@ -21351,7 +21372,8 @@ var init_DashboardLayout = __esm({
21351
21372
  {
21352
21373
  as: "aside",
21353
21374
  className: cn(
21354
- "z-30 w-64 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
21375
+ "z-30 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
21376
+ isRail ? "w-16" : "w-64",
21355
21377
  "flex flex-col"
21356
21378
  ),
21357
21379
  style: isMobile ? {
@@ -21367,10 +21389,10 @@ var init_DashboardLayout = __esm({
21367
21389
  HStack,
21368
21390
  {
21369
21391
  align: "center",
21370
- justify: "between",
21371
- className: "h-16 px-4 border-b border-border dark:border-border",
21392
+ justify: isRail ? "center" : "between",
21393
+ className: cn("h-16 border-b border-border dark:border-border", isRail ? "px-2" : "px-4"),
21372
21394
  children: [
21373
- /* @__PURE__ */ jsxs(Link, { to: "/", className: "flex items-center gap-2", children: [
21395
+ /* @__PURE__ */ jsxs(Link, { to: "/", className: "flex items-center gap-2", title: isRail ? appName : void 0, children: [
21374
21396
  logo || /* @__PURE__ */ jsx(Box, { className: "w-8 h-8 bg-primary rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx(
21375
21397
  Typography,
21376
21398
  {
@@ -21380,7 +21402,7 @@ var init_DashboardLayout = __esm({
21380
21402
  children: appName.charAt(0).toUpperCase()
21381
21403
  }
21382
21404
  ) }),
21383
- /* @__PURE__ */ jsx(
21405
+ !isRail && /* @__PURE__ */ jsx(
21384
21406
  Typography,
21385
21407
  {
21386
21408
  variant: "label",
@@ -21407,12 +21429,13 @@ var init_DashboardLayout = __esm({
21407
21429
  {
21408
21430
  as: "nav",
21409
21431
  gap: "none",
21410
- className: "flex-1 px-3 py-4 space-y-1 overflow-y-auto",
21432
+ className: cn("flex-1 py-4 space-y-1 overflow-y-auto", isRail ? "px-2" : "px-3"),
21411
21433
  children: navItems.map((item) => /* @__PURE__ */ jsx(
21412
21434
  NavLink,
21413
21435
  {
21414
21436
  item,
21415
- currentPath: activePath
21437
+ currentPath: activePath,
21438
+ compact: isRail
21416
21439
  },
21417
21440
  item.href
21418
21441
  ))
@@ -21667,13 +21690,40 @@ var init_DashboardLayout = __esm({
21667
21690
  DashboardLayout.displayName = "DashboardLayout";
21668
21691
  NavLink = ({
21669
21692
  item,
21670
- currentPath
21693
+ currentPath,
21694
+ compact = false
21671
21695
  }) => {
21672
21696
  const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
21673
21697
  const iconClassName = cn(
21674
21698
  "h-5 w-5",
21675
21699
  isActive ? "text-primary-foreground" : "text-muted-foreground"
21676
21700
  );
21701
+ if (compact) {
21702
+ return /* @__PURE__ */ jsx(
21703
+ Link,
21704
+ {
21705
+ to: item.href,
21706
+ title: item.label,
21707
+ "aria-label": item.label,
21708
+ className: cn(
21709
+ "flex items-center justify-center px-2 py-2 rounded-lg transition-colors",
21710
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
21711
+ ),
21712
+ children: /* @__PURE__ */ jsxs(Box, { as: "span", className: "relative inline-flex", children: [
21713
+ item.icon ? typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, className: iconClassName }) : /* @__PURE__ */ jsx(item.icon, { className: iconClassName }) : /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-semibold", as: "span", children: item.label.charAt(0).toUpperCase() }),
21714
+ item.badge && /* @__PURE__ */ jsx(
21715
+ Badge,
21716
+ {
21717
+ variant: isActive ? "primary" : "default",
21718
+ size: "sm",
21719
+ className: "absolute -top-2 -right-2 px-1 py-0 text-[10px] leading-4",
21720
+ children: item.badge
21721
+ }
21722
+ )
21723
+ ] })
21724
+ }
21725
+ );
21726
+ }
21677
21727
  return /* @__PURE__ */ jsxs(
21678
21728
  Link,
21679
21729
  {
@@ -22739,40 +22789,55 @@ function DataGrid({
22739
22789
  {
22740
22790
  "data-entity-row": true,
22741
22791
  "data-entity-id": id,
22742
- className: cn(isSelected && "ring-2 ring-primary rounded-lg"),
22792
+ className: cn("relative group/rowactions", isSelected && "ring-2 ring-primary rounded-lg"),
22743
22793
  children: [
22744
22794
  children(itemData, index),
22745
- actionDefs.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 border-t border-border", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-end", children: [
22746
- (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxs(
22747
- Button,
22748
- {
22749
- variant: action.variant === "primary" ? "primary" : "ghost",
22750
- size: "sm",
22751
- onClick: handleActionClick(action, itemData),
22752
- "data-testid": `action-${action.event}`,
22753
- "data-row-id": String(itemData.id),
22754
- className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
22755
- children: [
22756
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
22757
- action.label
22758
- ]
22759
- },
22760
- idx
22761
- )),
22762
- maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsx(
22795
+ actionDefs.length > 0 && /* @__PURE__ */ jsxs(Box, { className: "absolute top-2 right-2 z-10 opacity-0 group-hover/rowactions:opacity-100 focus-within:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity duration-fast", children: [
22796
+ /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5 [@media(pointer:coarse)]:hidden", children: [
22797
+ (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxs(
22798
+ Button,
22799
+ {
22800
+ variant: action.variant === "primary" ? "primary" : "ghost",
22801
+ size: "sm",
22802
+ onClick: handleActionClick(action, itemData),
22803
+ "data-testid": `action-${action.event}`,
22804
+ "data-row-id": String(itemData.id),
22805
+ className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
22806
+ children: [
22807
+ action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
22808
+ action.label
22809
+ ]
22810
+ },
22811
+ idx
22812
+ )),
22813
+ maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsx(
22814
+ Menu,
22815
+ {
22816
+ position: "bottom-end",
22817
+ trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
22818
+ items: actionDefs.slice(maxInlineActions).map((action) => ({
22819
+ label: action.label,
22820
+ icon: action.icon,
22821
+ event: action.event,
22822
+ onClick: () => fireAction(action, itemData)
22823
+ }))
22824
+ }
22825
+ )
22826
+ ] }),
22827
+ /* @__PURE__ */ jsx(Box, { className: "hidden [@media(pointer:coarse)]:block rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5", children: /* @__PURE__ */ jsx(
22763
22828
  Menu,
22764
22829
  {
22765
22830
  position: "bottom-end",
22766
22831
  trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
22767
- items: actionDefs.slice(maxInlineActions).map((action) => ({
22832
+ items: actionDefs.map((action) => ({
22768
22833
  label: action.label,
22769
22834
  icon: action.icon,
22770
22835
  event: action.event,
22771
22836
  onClick: () => fireAction(action, itemData)
22772
22837
  }))
22773
22838
  }
22774
- )
22775
- ] }) })
22839
+ ) })
22840
+ ] })
22776
22841
  ]
22777
22842
  },
22778
22843
  id
@@ -22808,7 +22873,7 @@ function DataGrid({
22808
22873
  }
22809
22874
  ) });
22810
22875
  })(),
22811
- /* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
22876
+ /* @__PURE__ */ jsx(Box, { className: cn("p-4", bodyFields.length > 0 && "pb-0"), children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
22812
22877
  selectable && /* @__PURE__ */ jsx(
22813
22878
  "input",
22814
22879
  {
@@ -22841,79 +22906,77 @@ function DataGrid({
22841
22906
  ] }, field.name);
22842
22907
  }) })
22843
22908
  ] }),
22844
- dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxs(
22845
- Button,
22846
- {
22847
- variant: "ghost",
22848
- size: "sm",
22849
- onClick: handleActionClick(action, itemData),
22850
- "data-testid": `action-${action.event}`,
22851
- "data-row-id": String(itemData.id),
22852
- className: "text-error hover:text-error hover:bg-error/10 px-2",
22853
- children: [
22854
- action.icon && renderIconInput(action.icon, { size: "xs" }),
22855
- action.label
22856
- ]
22857
- },
22858
- idx
22859
- )) })
22860
- ] }) }),
22861
- bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
22862
- const value = getNestedValue(itemData, field.name);
22863
- if (value === void 0 || value === null || value === "") return null;
22864
- if (field.format === "boolean") {
22865
- return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
22866
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
22867
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
22868
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
22869
- ] }),
22870
- /* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
22871
- ] }, field.name);
22872
- }
22873
- return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
22874
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
22875
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
22876
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
22877
- ] }),
22878
- /* @__PURE__ */ jsx(
22879
- Typography,
22909
+ (primaryActions.length > 0 || dangerActions.length > 0) && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "flex-shrink-0", children: [
22910
+ (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsx(
22911
+ Button,
22880
22912
  {
22881
- variant: field.variant === "caption" ? "caption" : "small",
22882
- className: "text-right truncate max-w-[60%]",
22883
- children: formatValue(value, field.format)
22913
+ variant: action.variant === "primary" ? "primary" : "ghost",
22914
+ size: "sm",
22915
+ onClick: handleActionClick(action, itemData),
22916
+ "data-testid": `action-${action.event}`,
22917
+ "data-row-id": String(itemData.id),
22918
+ "aria-label": action.label,
22919
+ title: action.label,
22920
+ className: cn(
22921
+ action.variant === "primary" ? void 0 : "text-muted-foreground hover:text-foreground",
22922
+ action.icon && "px-2"
22923
+ ),
22924
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
22925
+ },
22926
+ idx
22927
+ )),
22928
+ maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsx(
22929
+ Menu,
22930
+ {
22931
+ position: "bottom-end",
22932
+ trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
22933
+ items: primaryActions.slice(maxInlineActions).map((action) => ({
22934
+ label: action.label,
22935
+ icon: action.icon,
22936
+ event: action.event,
22937
+ onClick: () => fireAction(action, itemData)
22938
+ }))
22884
22939
  }
22885
- )
22886
- ] }, field.name);
22887
- }) }) }),
22888
- primaryActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-end flex-wrap", children: [
22889
- (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxs(
22890
- Button,
22891
- {
22892
- variant: action.variant === "primary" ? "primary" : "ghost",
22893
- size: "sm",
22894
- onClick: handleActionClick(action, itemData),
22895
- "data-testid": `action-${action.event}`,
22896
- "data-row-id": String(itemData.id),
22897
- children: [
22898
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
22899
- action.label
22900
- ]
22901
- },
22902
- idx
22903
- )),
22904
- maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsx(
22905
- Menu,
22906
- {
22907
- position: "bottom-end",
22908
- trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
22909
- items: primaryActions.slice(maxInlineActions).map((action) => ({
22910
- label: action.label,
22911
- icon: action.icon,
22912
- event: action.event,
22913
- onClick: () => fireAction(action, itemData)
22914
- }))
22940
+ ),
22941
+ dangerActions.map((action, idx) => /* @__PURE__ */ jsx(
22942
+ Button,
22943
+ {
22944
+ variant: "ghost",
22945
+ size: "sm",
22946
+ onClick: handleActionClick(action, itemData),
22947
+ "data-testid": `action-${action.event}`,
22948
+ "data-row-id": String(itemData.id),
22949
+ "aria-label": action.label,
22950
+ title: action.label,
22951
+ className: "text-error hover:text-error hover:bg-error/10 px-2",
22952
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
22953
+ },
22954
+ `danger-${idx}`
22955
+ ))
22956
+ ] })
22957
+ ] }) }),
22958
+ bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 pt-2 pb-4 flex-1", children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
22959
+ bodyFields.filter((f3) => f3.variant === "caption" && f3.format !== "boolean").map((field) => {
22960
+ const value = getNestedValue(itemData, field.name);
22961
+ if (value === void 0 || value === null || value === "") return null;
22962
+ return /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: formatValue(value, field.format) }, field.name);
22963
+ }),
22964
+ /* @__PURE__ */ jsx(HStack, { gap: "md", className: "flex-wrap gap-y-1", children: bodyFields.filter((f3) => f3.variant !== "caption" || f3.format === "boolean").map((field) => {
22965
+ const value = getNestedValue(itemData, field.name);
22966
+ if (value === void 0 || value === null || value === "") return null;
22967
+ if (field.format === "boolean") {
22968
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
22969
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
22970
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) }),
22971
+ /* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
22972
+ ] }, field.name);
22915
22973
  }
22916
- )
22974
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
22975
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
22976
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
22977
+ /* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
22978
+ ] }, field.name);
22979
+ }) })
22917
22980
  ] }) })
22918
22981
  ]
22919
22982
  },
@@ -23261,11 +23324,29 @@ function DataList({
23261
23324
  const wrapDnd = (node) => dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: dndId, children: node }, dndId) : node;
23262
23325
  if (hasRenderProp) {
23263
23326
  const id2 = itemData.id || String(index);
23327
+ const actions = renderItemActions(itemData);
23264
23328
  return wrapDnd(
23265
- /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn(itemClickEvent && "cursor-pointer"), children: [
23266
- /* @__PURE__ */ jsxs(Box, { className: "group flex items-stretch gap-2", children: [
23267
- /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
23268
- renderItemActions(itemData)
23329
+ /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn("relative group/rowactions", itemClickEvent && "cursor-pointer"), children: [
23330
+ children(itemData, index),
23331
+ actions && /* @__PURE__ */ jsxs(Box, { className: "absolute top-2 right-2 z-10 opacity-0 group-hover/rowactions:opacity-100 focus-within:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity duration-fast", children: [
23332
+ /* @__PURE__ */ jsx(Box, { className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5 [@media(pointer:coarse)]:hidden", children: actions }),
23333
+ /* @__PURE__ */ jsx(Box, { className: "hidden [@media(pointer:coarse)]:block rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5", children: /* @__PURE__ */ jsx(
23334
+ Menu,
23335
+ {
23336
+ position: "bottom-end",
23337
+ trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23338
+ items: (itemActions ?? []).map((action) => ({
23339
+ label: action.label,
23340
+ icon: action.icon,
23341
+ event: action.event,
23342
+ variant: action.variant === "danger" ? "danger" : "default",
23343
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
23344
+ id: itemData.id,
23345
+ row: itemData
23346
+ })
23347
+ }))
23348
+ }
23349
+ ) })
23269
23350
  ] }),
23270
23351
  isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
23271
23352
  ] }, id2)
@@ -23305,7 +23386,7 @@ function DataList({
23305
23386
  ] }, field.name);
23306
23387
  })
23307
23388
  ] }),
23308
- bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
23389
+ bodyFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "md", className: cn("flex-wrap", isCompact ? "mt-0.5" : "mt-1.5"), children: bodyFields.map((field) => {
23309
23390
  const value = getNestedValue(itemData, field.name);
23310
23391
  if (value === void 0 || value === null || value === "") return null;
23311
23392
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
@@ -23655,10 +23736,7 @@ var init_FileTree = __esm({
23655
23736
  className,
23656
23737
  indent = 16
23657
23738
  }) => {
23658
- const { t } = useTranslate();
23659
- if (tree.length === 0) {
23660
- return /* @__PURE__ */ jsx(Box, { className: `p-4 ${className ?? ""}`, children: /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: t("fileTree.noFiles") }) });
23661
- }
23739
+ if (tree.length === 0) return null;
23662
23740
  return /* @__PURE__ */ jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsx(
23663
23741
  TreeNodeItem,
23664
23742
  {
@@ -26840,7 +26918,7 @@ var init_MapView = __esm({
26840
26918
  shadowSize: [41, 41]
26841
26919
  });
26842
26920
  L.Marker.prototype.options.icon = defaultIcon;
26843
- const { useEffect: useEffect59, useRef: useRef60, useCallback: useCallback87, useState: useState89 } = React82__default;
26921
+ const { useEffect: useEffect59, useRef: useRef60, useCallback: useCallback88, useState: useState89 } = React82__default;
26844
26922
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
26845
26923
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
26846
26924
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -26886,7 +26964,7 @@ var init_MapView = __esm({
26886
26964
  }) {
26887
26965
  const eventBus = useEventBus2();
26888
26966
  const [clickedPosition, setClickedPosition] = useState89(null);
26889
- const handleMapClick = useCallback87((lat, lng) => {
26967
+ const handleMapClick = useCallback88((lat, lng) => {
26890
26968
  if (showClickedPin) {
26891
26969
  setClickedPosition({ lat, lng });
26892
26970
  }
@@ -26895,7 +26973,7 @@ var init_MapView = __esm({
26895
26973
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
26896
26974
  }
26897
26975
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
26898
- const handleMarkerClick = useCallback87((marker) => {
26976
+ const handleMarkerClick = useCallback88((marker) => {
26899
26977
  onMarkerClick?.(marker);
26900
26978
  if (markerClickEvent) {
26901
26979
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -27097,7 +27175,7 @@ var init_NumberStepper = __esm({
27097
27175
  "active:bg-muted",
27098
27176
  "transition-colors duration-instant",
27099
27177
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27100
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27178
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
27101
27179
  styles.button
27102
27180
  ),
27103
27181
  "aria-label": t("aria.decrease"),
@@ -27138,7 +27216,7 @@ var init_NumberStepper = __esm({
27138
27216
  "active:bg-muted",
27139
27217
  "transition-colors duration-instant",
27140
27218
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27141
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27219
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
27142
27220
  styles.button
27143
27221
  ),
27144
27222
  "aria-label": t("aria.increase"),
@@ -27594,7 +27672,7 @@ var init_Lightbox = __esm({
27594
27672
  "p-2 rounded-full",
27595
27673
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
27596
27674
  "hover:bg-opacity-70 transition-opacity",
27597
- "focus:outline-none focus:ring-2 focus:ring-ring"
27675
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
27598
27676
  ),
27599
27677
  "aria-label": t("aria.closeModal"),
27600
27678
  children: /* @__PURE__ */ jsx(Icon, { name: "x", className: "w-6 h-6" })
@@ -27613,7 +27691,7 @@ var init_Lightbox = __esm({
27613
27691
  "p-2 rounded-full",
27614
27692
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
27615
27693
  "hover:bg-opacity-70 transition-opacity",
27616
- "focus:outline-none focus:ring-2 focus:ring-ring"
27694
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
27617
27695
  ),
27618
27696
  "aria-label": t("aria.previousImage"),
27619
27697
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-left", className: "w-8 h-8" })
@@ -27650,7 +27728,7 @@ var init_Lightbox = __esm({
27650
27728
  "p-2 rounded-full",
27651
27729
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
27652
27730
  "hover:bg-opacity-70 transition-opacity",
27653
- "focus:outline-none focus:ring-2 focus:ring-ring"
27731
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
27654
27732
  ),
27655
27733
  "aria-label": t("aria.nextImage"),
27656
27734
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", className: "w-8 h-8" })
@@ -27777,6 +27855,7 @@ function TableView({
27777
27855
  const hasMore = pageSize > 0 && visibleCount < ordered.length;
27778
27856
  const hasRenderProp = typeof children === "function";
27779
27857
  const idField = dndItemIdField ?? "id";
27858
+ const isCoarsePointer = useMediaQuery("(pointer: coarse)");
27780
27859
  const selected = selectedIds ? new Set(selectedIds) : localSelected;
27781
27860
  const emitSelection = (next) => {
27782
27861
  if (!selectedIds) setLocalSelected(next);
@@ -27809,6 +27888,17 @@ function TableView({
27809
27888
  };
27810
27889
  eventBus.emit(`UI:${action.event}`, payload);
27811
27890
  };
27891
+ const colFloors = React82__default.useMemo(
27892
+ () => colDefs.map((col) => {
27893
+ const longest = data.reduce((widest, row) => {
27894
+ const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
27895
+ return Math.max(widest, cell.length);
27896
+ }, columnLabel(col).length);
27897
+ const chrome = col.format === "badge" ? BADGE_CHROME_CH : 0;
27898
+ return Math.min(longest + chrome, MAX_MEASURED_COL_CH);
27899
+ }),
27900
+ [colDefs, data]
27901
+ );
27812
27902
  if (isLoading) {
27813
27903
  return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") }) });
27814
27904
  }
@@ -27821,19 +27911,10 @@ function TableView({
27821
27911
  }
27822
27912
  const lk = LOOKS[look];
27823
27913
  const hasActions = Boolean(itemActions && itemActions.length > 0);
27824
- const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
27825
- const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
27914
+ const effectiveMaxInline = isCoarsePointer ? 0 : maxInlineActions;
27915
+ const inlineActionCount = hasActions ? effectiveMaxInline != null ? Math.min(itemActions.length, effectiveMaxInline) : itemActions.length : 0;
27916
+ const hasOverflowActions = hasActions && effectiveMaxInline != null && itemActions.length > effectiveMaxInline;
27826
27917
  const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
27827
- const colFloors = React82__default.useMemo(
27828
- () => colDefs.map((col) => {
27829
- const longest = data.reduce((widest, row) => {
27830
- const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
27831
- return Math.max(widest, cell.length);
27832
- }, columnLabel(col).length);
27833
- return Math.min(longest, MAX_MEASURED_COL_CH);
27834
- }),
27835
- [colDefs, data]
27836
- );
27837
27918
  const gridTemplateColumns = [
27838
27919
  selectable ? "auto" : null,
27839
27920
  ...colDefs.map((c, i) => c.width ?? `minmax(${colFloors[i]}ch, 1fr)`),
@@ -27920,9 +28001,9 @@ function TableView({
27920
28001
  col.className
27921
28002
  );
27922
28003
  if (col.format === "badge" && raw != null && raw !== "") {
27923
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
28004
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", className: "whitespace-nowrap", children: String(raw) }) }, col.key);
27924
28005
  }
27925
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
28006
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format) }) }, col.key);
27926
28007
  }),
27927
28008
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(
27928
28009
  HStack,
@@ -27936,15 +28017,15 @@ function TableView({
27936
28017
  lk.striped && index % 2 === 1 ? "bg-[var(--color-surface-subtle)]" : "bg-[var(--color-card)] group-hover:bg-[var(--color-surface-subtle)]"
27937
28018
  ),
27938
28019
  children: [
27939
- (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
28020
+ (effectiveMaxInline != null ? itemActions.slice(0, effectiveMaxInline) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
27940
28021
  Button,
27941
28022
  {
27942
- variant: action.variant ?? "ghost",
28023
+ variant: action.variant === "primary" ? "primary" : "ghost",
27943
28024
  size: "sm",
27944
28025
  onClick: handleActionClick(action, row),
27945
28026
  "data-testid": `action-${action.event}`,
27946
28027
  "data-row-id": String(row.id),
27947
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
28028
+ className: cn(action.variant === "danger" && "text-error hover:text-error hover:bg-error/10"),
27948
28029
  children: [
27949
28030
  action.icon && renderIconInput3(action.icon, { size: "xs", className: "mr-1" }),
27950
28031
  action.label
@@ -27952,12 +28033,12 @@ function TableView({
27952
28033
  },
27953
28034
  i
27954
28035
  )),
27955
- maxInlineActions != null && itemActions.length > maxInlineActions && /* @__PURE__ */ jsx(
28036
+ effectiveMaxInline != null && itemActions.length > effectiveMaxInline && /* @__PURE__ */ jsx(
27956
28037
  Menu,
27957
28038
  {
27958
28039
  position: "bottom-end",
27959
28040
  trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
27960
- items: itemActions.slice(maxInlineActions).map((action) => ({
28041
+ items: itemActions.slice(effectiveMaxInline).map((action) => ({
27961
28042
  label: action.label,
27962
28043
  icon: action.icon,
27963
28044
  event: action.event,
@@ -28003,13 +28084,14 @@ function TableView({
28003
28084
  }
28004
28085
  );
28005
28086
  }
28006
- var MAX_MEASURED_COL_CH, alignClass, weightClass, LOOKS;
28087
+ var MAX_MEASURED_COL_CH, BADGE_CHROME_CH, alignClass, weightClass, LOOKS;
28007
28088
  var init_TableView = __esm({
28008
28089
  "components/core/molecules/TableView.tsx"() {
28009
28090
  "use client";
28010
28091
  init_cn();
28011
28092
  init_getNestedValue();
28012
28093
  init_useEventBus();
28094
+ init_useMediaQuery();
28013
28095
  init_Box();
28014
28096
  init_Stack();
28015
28097
  init_Typography();
@@ -28022,6 +28104,7 @@ var init_TableView = __esm({
28022
28104
  init_useDataDnd();
28023
28105
  createLogger("almadar:ui:table-view");
28024
28106
  MAX_MEASURED_COL_CH = 32;
28107
+ BADGE_CHROME_CH = 4;
28025
28108
  alignClass = {
28026
28109
  left: "justify-start text-left",
28027
28110
  center: "justify-center text-center",
@@ -28033,7 +28116,7 @@ var init_TableView = __esm({
28033
28116
  semibold: "font-semibold"
28034
28117
  };
28035
28118
  LOOKS = {
28036
- dense: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true },
28119
+ dense: { rowPad: "px-card-md py-2", headPad: "px-card-md py-2", striped: false, divider: true },
28037
28120
  spacious: { rowPad: "px-card-lg py-card-md", headPad: "px-card-lg py-card-sm", striped: false, divider: true },
28038
28121
  striped: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: true, divider: false },
28039
28122
  borderless: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: false },
@@ -30119,7 +30202,7 @@ var init_VoteStack = __esm({
30119
30202
  "active:bg-muted",
30120
30203
  "transition-colors duration-instant",
30121
30204
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30122
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30205
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
30123
30206
  styles.button
30124
30207
  ),
30125
30208
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-up", className: styles.icon })
@@ -30156,7 +30239,7 @@ var init_VoteStack = __esm({
30156
30239
  "active:bg-muted",
30157
30240
  "transition-colors duration-instant",
30158
30241
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30159
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30242
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
30160
30243
  styles.button
30161
30244
  ),
30162
30245
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-down", className: styles.icon })
@@ -30677,7 +30760,7 @@ var init_QrScanner = __esm({
30677
30760
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30678
30761
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
30679
30762
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30680
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
30763
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
30681
30764
  ),
30682
30765
  "aria-label": isPaused ? t("qrScanner.resumeScanning") : t("qrScanner.pauseScanning"),
30683
30766
  children: isPaused ? /* @__PURE__ */ jsx(Icon, { name: "play", className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Icon, { name: "pause", className: "h-4 w-4" })
@@ -30692,7 +30775,7 @@ var init_QrScanner = __esm({
30692
30775
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30693
30776
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
30694
30777
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30695
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
30778
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
30696
30779
  ),
30697
30780
  "aria-label": currentFacing === "environment" ? t("qrScanner.switchToFrontCamera") : t("qrScanner.switchToRearCamera"),
30698
30781
  children: /* @__PURE__ */ jsx(Icon, { name: "refresh-cw", className: "h-4 w-4" })
@@ -30707,7 +30790,7 @@ var init_QrScanner = __esm({
30707
30790
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30708
30791
  "rounded-full bg-black bg-opacity-60 px-3 py-2 text-xs text-white",
30709
30792
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
30710
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
30793
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
30711
30794
  ),
30712
30795
  "aria-label": t("aria.mockScanDev"),
30713
30796
  children: t("qrScanner.mockScan")
@@ -38952,27 +39035,24 @@ var init_MasterDetailLayout = __esm({
38952
39035
  masterClassName,
38953
39036
  detailClassName
38954
39037
  }) => {
38955
- masterWidth.endsWith("%") ? parseInt(masterWidth, 10) : 30;
38956
39038
  return /* @__PURE__ */ jsxs(
38957
39039
  "div",
38958
39040
  {
38959
- className: cn("flex h-full w-full", className),
38960
- style: {
38961
- display: "grid",
38962
- gridTemplateColumns: masterWidth.endsWith("%") ? `${masterWidth} 1fr` : `${masterWidth} 1fr`
38963
- },
39041
+ className: cn("w-full h-full md:grid md:grid-cols-[var(--master-detail-cols)]", className),
39042
+ style: { "--master-detail-cols": `${masterWidth} 1fr` },
38964
39043
  children: [
38965
39044
  /* @__PURE__ */ jsx(
38966
39045
  "div",
38967
39046
  {
38968
39047
  className: cn(
38969
- "border-r-2 border-border overflow-auto",
39048
+ "border-r border-border overflow-auto",
39049
+ hasSelection && "hidden md:block",
38970
39050
  masterClassName
38971
39051
  ),
38972
39052
  children: master
38973
39053
  }
38974
39054
  ),
38975
- /* @__PURE__ */ jsx("div", { className: cn("overflow-auto", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsx(DefaultEmptyDetail, {}) })
39055
+ /* @__PURE__ */ jsx("div", { className: cn("overflow-auto", !hasSelection && "hidden md:block", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsx(DefaultEmptyDetail, {}) })
38976
39056
  ]
38977
39057
  }
38978
39058
  );
@@ -42544,7 +42624,7 @@ var init_TabbedContainer = __esm({
42544
42624
  onClick: () => !isDisabled && handleTabChange(tab.id),
42545
42625
  className: cn(
42546
42626
  "flex items-center gap-2 px-4 py-3 text-sm font-medium transition-colors",
42547
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
42627
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
42548
42628
  "disabled:opacity-50 disabled:cursor-not-allowed",
42549
42629
  isActive ? "bg-primary text-primary-foreground" : "bg-card text-foreground hover:bg-muted",
42550
42630
  isVertical ? "justify-start" : "justify-center"