@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.
package/dist/avl/index.js CHANGED
@@ -5050,7 +5050,7 @@ var init_Button = __esm({
5050
5050
  "cursor-pointer",
5051
5051
  "chrome-button",
5052
5052
  "transition-all duration-normal",
5053
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-offset-[length:var(--focus-ring-offset)]",
5053
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--focus-ring-offset)]",
5054
5054
  "disabled:opacity-50 disabled:cursor-not-allowed",
5055
5055
  variantStyles2[variant],
5056
5056
  sizeStyles[size],
@@ -5647,6 +5647,8 @@ var init_Badge = __esm({
5647
5647
  };
5648
5648
  const iconPx = size === "lg" ? 20 : 16;
5649
5649
  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;
5650
+ const hasText = Boolean(children) || amount != null || label !== void 0 && label !== null && label !== "";
5651
+ if (!hasText && !resolvedIcon && !onRemove) return null;
5650
5652
  return /* @__PURE__ */ jsxs(
5651
5653
  "span",
5652
5654
  {
@@ -5673,7 +5675,7 @@ var init_Badge = __esm({
5673
5675
  },
5674
5676
  className: cn(
5675
5677
  "inline-flex items-center justify-center rounded-sm",
5676
- "hover:bg-foreground/10 focus:outline-none focus:ring-1 focus:ring-ring",
5678
+ "hover:bg-foreground/10 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
5677
5679
  "transition-colors",
5678
5680
  size === "sm" ? "w-4 h-4 ml-0.5" : size === "md" ? "w-5 h-5 ml-1" : "w-6 h-6 ml-1"
5679
5681
  ),
@@ -7031,7 +7033,7 @@ function NativeSelect({
7031
7033
  "block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
7032
7034
  "px-3 py-2 pr-10 text-sm text-foreground font-medium",
7033
7035
  "bg-card",
7034
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
7036
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
7035
7037
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
7036
7038
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
7037
7039
  className
@@ -7138,7 +7140,7 @@ function RichSelect({
7138
7140
  "block w-full border-[length:var(--border-width)] shadow-sm",
7139
7141
  "px-3 py-2 pr-10 text-sm text-start font-medium",
7140
7142
  "bg-card rounded-sm",
7141
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
7143
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
7142
7144
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
7143
7145
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
7144
7146
  !hasValue && "text-muted-foreground"
@@ -8061,9 +8063,9 @@ var init_Radio = __esm({
8061
8063
  "flex items-center justify-center",
8062
8064
  "border-[length:var(--border-width)] transition-all cursor-pointer",
8063
8065
  sizeClasses4[size],
8064
- hasError ? "border-error peer-focus:ring-error/20" : "border-border peer-focus:ring-ring/20",
8066
+ hasError ? "border-error peer-focus-visible:ring-error/20" : "border-border peer-focus-visible:ring-ring/20",
8065
8067
  isChecked2 ? hasError ? "border-error" : "border-primary bg-primary" : "",
8066
- "peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-offset-2",
8068
+ "peer-focus:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2",
8067
8069
  disabled && "opacity-50 cursor-not-allowed",
8068
8070
  !disabled && "hover:border-[var(--color-border-hover)]"
8069
8071
  ),
@@ -8449,7 +8451,7 @@ var init_ThemeToggle = __esm({
8449
8451
  "inline-flex items-center justify-center gap-2",
8450
8452
  "text-foreground",
8451
8453
  "hover:bg-muted border-[length:var(--border-width)] border-transparent hover:border-border",
8452
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8454
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
8453
8455
  "transition-colors duration-fast",
8454
8456
  sizeClasses5[size],
8455
8457
  className
@@ -8884,11 +8886,13 @@ var init_TrendIndicator = __esm({
8884
8886
  size = "md",
8885
8887
  ...props
8886
8888
  }, ref) => {
8887
- const dir = resolveDirection(value, direction);
8889
+ const hasValue = typeof value === "number" && Number.isFinite(value);
8890
+ if (!hasValue && !direction) return null;
8891
+ const dir = resolveDirection(hasValue ? value : void 0, direction);
8888
8892
  const colorClass = resolveColor(dir, invert);
8889
8893
  const iconName = iconNameMap[dir];
8890
8894
  const styles = sizeStyles6[size];
8891
- const formattedValue = value !== void 0 ? `${value > 0 ? "+" : ""}${value}%` : void 0;
8895
+ const formattedValue = hasValue ? `${value > 0 ? "+" : ""}${value}%` : void 0;
8892
8896
  const ariaLabel = label ?? (formattedValue ? `${dir} ${formattedValue}` : dir);
8893
8897
  return /* @__PURE__ */ jsxs(
8894
8898
  "span",
@@ -14836,10 +14840,12 @@ var init_Container = __esm({
14836
14840
  };
14837
14841
  paddingStyles3 = {
14838
14842
  none: "px-0",
14839
- sm: "px-4",
14840
- md: "px-6",
14841
- lg: "px-8",
14842
- xl: "px-12"
14843
+ // Mobile-tighter, desktop-identical: fixed px-6 on a 360px phone eats ~13% of
14844
+ // the viewport, so each token steps down below the sm breakpoint.
14845
+ sm: "px-3 sm:px-4",
14846
+ md: "px-4 sm:px-6",
14847
+ lg: "px-4 sm:px-6 md:px-8",
14848
+ xl: "px-4 sm:px-8 md:px-12"
14843
14849
  };
14844
14850
  Container = ({
14845
14851
  size,
@@ -15538,7 +15544,7 @@ var init_Accordion = __esm({
15538
15544
  "bg-card",
15539
15545
  "hover:bg-muted",
15540
15546
  "transition-colors duration-fast",
15541
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-inset",
15547
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
15542
15548
  "disabled:opacity-50 disabled:cursor-not-allowed",
15543
15549
  isOpen && "bg-muted font-bold"
15544
15550
  ),
@@ -20308,26 +20314,19 @@ var init_BookViewer = __esm({
20308
20314
  function BoxPattern({
20309
20315
  p,
20310
20316
  m,
20311
- bg = "transparent",
20312
- border = false,
20313
- radius = "none",
20314
- shadow = "none",
20315
- className,
20316
- style,
20317
- children
20317
+ radius,
20318
+ isLoading: _isLoading,
20319
+ error: _error,
20320
+ entity: _entity,
20321
+ ...boxProps
20318
20322
  }) {
20319
20323
  return /* @__PURE__ */ jsx(
20320
20324
  Box,
20321
20325
  {
20322
- padding: p,
20323
- margin: m,
20324
- bg,
20325
- border,
20326
- rounded: radius,
20327
- shadow,
20328
- className,
20329
- style,
20330
- children
20326
+ padding: boxProps.padding ?? p,
20327
+ margin: boxProps.margin ?? m,
20328
+ rounded: boxProps.rounded ?? radius,
20329
+ ...boxProps
20331
20330
  }
20332
20331
  );
20333
20332
  }
@@ -20916,7 +20915,7 @@ var init_Breadcrumb = __esm({
20916
20915
  },
20917
20916
  className: cn(
20918
20917
  "flex items-center gap-1.5 transition-colors",
20919
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
20918
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
20920
20919
  isLast ? "text-foreground font-bold cursor-default" : "text-muted-foreground hover:text-foreground"
20921
20920
  ),
20922
20921
  "aria-current": isLast ? "page" : void 0,
@@ -24018,17 +24017,19 @@ var init_DashboardLayout = __esm({
24018
24017
  const [sidebarOpen, setSidebarOpen] = useState(false);
24019
24018
  const [userMenuOpen, setUserMenuOpen] = useState(false);
24020
24019
  const layoutRef = useRef(null);
24021
- const [isMobile, setIsMobile] = useState(false);
24020
+ const [layoutWidth, setLayoutWidth] = useState(null);
24022
24021
  useEffect(() => {
24023
24022
  const el = layoutRef.current;
24024
24023
  if (!el || typeof ResizeObserver === "undefined") return;
24025
24024
  const ro = new ResizeObserver((entries) => {
24026
24025
  const w = entries[0]?.contentRect.width ?? el.clientWidth;
24027
- setIsMobile(w < 1024);
24026
+ setLayoutWidth(w);
24028
24027
  });
24029
24028
  ro.observe(el);
24030
24029
  return () => ro.disconnect();
24031
24030
  }, []);
24031
+ const isMobile = layoutWidth !== null && layoutWidth < 768;
24032
+ const isRail = layoutWidth !== null && layoutWidth >= 768 && layoutWidth < 1024;
24032
24033
  useEffect(() => {
24033
24034
  if (!isMobile && sidebarOpen) setSidebarOpen(false);
24034
24035
  }, [isMobile, sidebarOpen]);
@@ -24061,7 +24062,8 @@ var init_DashboardLayout = __esm({
24061
24062
  {
24062
24063
  as: "aside",
24063
24064
  className: cn(
24064
- "z-30 w-64 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
24065
+ "z-30 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
24066
+ isRail ? "w-16" : "w-64",
24065
24067
  "flex flex-col"
24066
24068
  ),
24067
24069
  style: isMobile ? {
@@ -24077,10 +24079,10 @@ var init_DashboardLayout = __esm({
24077
24079
  HStack,
24078
24080
  {
24079
24081
  align: "center",
24080
- justify: "between",
24081
- className: "h-16 px-4 border-b border-border dark:border-border",
24082
+ justify: isRail ? "center" : "between",
24083
+ className: cn("h-16 border-b border-border dark:border-border", isRail ? "px-2" : "px-4"),
24082
24084
  children: [
24083
- /* @__PURE__ */ jsxs(Link, { to: "/", className: "flex items-center gap-2", children: [
24085
+ /* @__PURE__ */ jsxs(Link, { to: "/", className: "flex items-center gap-2", title: isRail ? appName : void 0, children: [
24084
24086
  logo || /* @__PURE__ */ jsx(Box, { className: "w-8 h-8 bg-primary rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx(
24085
24087
  Typography,
24086
24088
  {
@@ -24090,7 +24092,7 @@ var init_DashboardLayout = __esm({
24090
24092
  children: appName.charAt(0).toUpperCase()
24091
24093
  }
24092
24094
  ) }),
24093
- /* @__PURE__ */ jsx(
24095
+ !isRail && /* @__PURE__ */ jsx(
24094
24096
  Typography,
24095
24097
  {
24096
24098
  variant: "label",
@@ -24117,12 +24119,13 @@ var init_DashboardLayout = __esm({
24117
24119
  {
24118
24120
  as: "nav",
24119
24121
  gap: "none",
24120
- className: "flex-1 px-3 py-4 space-y-1 overflow-y-auto",
24122
+ className: cn("flex-1 py-4 space-y-1 overflow-y-auto", isRail ? "px-2" : "px-3"),
24121
24123
  children: navItems.map((item) => /* @__PURE__ */ jsx(
24122
24124
  NavLink,
24123
24125
  {
24124
24126
  item,
24125
- currentPath: activePath
24127
+ currentPath: activePath,
24128
+ compact: isRail
24126
24129
  },
24127
24130
  item.href
24128
24131
  ))
@@ -24377,13 +24380,40 @@ var init_DashboardLayout = __esm({
24377
24380
  DashboardLayout.displayName = "DashboardLayout";
24378
24381
  NavLink = ({
24379
24382
  item,
24380
- currentPath
24383
+ currentPath,
24384
+ compact = false
24381
24385
  }) => {
24382
24386
  const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
24383
24387
  const iconClassName = cn(
24384
24388
  "h-5 w-5",
24385
24389
  isActive ? "text-primary-foreground" : "text-muted-foreground"
24386
24390
  );
24391
+ if (compact) {
24392
+ return /* @__PURE__ */ jsx(
24393
+ Link,
24394
+ {
24395
+ to: item.href,
24396
+ title: item.label,
24397
+ "aria-label": item.label,
24398
+ className: cn(
24399
+ "flex items-center justify-center px-2 py-2 rounded-lg transition-colors",
24400
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
24401
+ ),
24402
+ children: /* @__PURE__ */ jsxs(Box, { as: "span", className: "relative inline-flex", children: [
24403
+ 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() }),
24404
+ item.badge && /* @__PURE__ */ jsx(
24405
+ Badge,
24406
+ {
24407
+ variant: isActive ? "primary" : "default",
24408
+ size: "sm",
24409
+ className: "absolute -top-2 -right-2 px-1 py-0 text-[10px] leading-4",
24410
+ children: item.badge
24411
+ }
24412
+ )
24413
+ ] })
24414
+ }
24415
+ );
24416
+ }
24387
24417
  return /* @__PURE__ */ jsxs(
24388
24418
  Link,
24389
24419
  {
@@ -25449,40 +25479,55 @@ function DataGrid({
25449
25479
  {
25450
25480
  "data-entity-row": true,
25451
25481
  "data-entity-id": id,
25452
- className: cn(isSelected && "ring-2 ring-primary rounded-lg"),
25482
+ className: cn("relative group/rowactions", isSelected && "ring-2 ring-primary rounded-lg"),
25453
25483
  children: [
25454
25484
  children(itemData, index),
25455
- 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: [
25456
- (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxs(
25457
- Button,
25458
- {
25459
- variant: action.variant === "primary" ? "primary" : "ghost",
25460
- size: "sm",
25461
- onClick: handleActionClick(action, itemData),
25462
- "data-testid": `action-${action.event}`,
25463
- "data-row-id": String(itemData.id),
25464
- className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
25465
- children: [
25466
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
25467
- action.label
25468
- ]
25469
- },
25470
- idx
25471
- )),
25472
- maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsx(
25485
+ 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: [
25486
+ /* @__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: [
25487
+ (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxs(
25488
+ Button,
25489
+ {
25490
+ variant: action.variant === "primary" ? "primary" : "ghost",
25491
+ size: "sm",
25492
+ onClick: handleActionClick(action, itemData),
25493
+ "data-testid": `action-${action.event}`,
25494
+ "data-row-id": String(itemData.id),
25495
+ className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
25496
+ children: [
25497
+ action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
25498
+ action.label
25499
+ ]
25500
+ },
25501
+ idx
25502
+ )),
25503
+ maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsx(
25504
+ Menu,
25505
+ {
25506
+ position: "bottom-end",
25507
+ 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" }) }),
25508
+ items: actionDefs.slice(maxInlineActions).map((action) => ({
25509
+ label: action.label,
25510
+ icon: action.icon,
25511
+ event: action.event,
25512
+ onClick: () => fireAction(action, itemData)
25513
+ }))
25514
+ }
25515
+ )
25516
+ ] }),
25517
+ /* @__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(
25473
25518
  Menu,
25474
25519
  {
25475
25520
  position: "bottom-end",
25476
25521
  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" }) }),
25477
- items: actionDefs.slice(maxInlineActions).map((action) => ({
25522
+ items: actionDefs.map((action) => ({
25478
25523
  label: action.label,
25479
25524
  icon: action.icon,
25480
25525
  event: action.event,
25481
25526
  onClick: () => fireAction(action, itemData)
25482
25527
  }))
25483
25528
  }
25484
- )
25485
- ] }) })
25529
+ ) })
25530
+ ] })
25486
25531
  ]
25487
25532
  },
25488
25533
  id
@@ -25518,7 +25563,7 @@ function DataGrid({
25518
25563
  }
25519
25564
  ) });
25520
25565
  })(),
25521
- /* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
25566
+ /* @__PURE__ */ jsx(Box, { className: cn("p-4", bodyFields.length > 0 && "pb-0"), children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
25522
25567
  selectable && /* @__PURE__ */ jsx(
25523
25568
  "input",
25524
25569
  {
@@ -25551,79 +25596,77 @@ function DataGrid({
25551
25596
  ] }, field.name);
25552
25597
  }) })
25553
25598
  ] }),
25554
- dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxs(
25555
- Button,
25556
- {
25557
- variant: "ghost",
25558
- size: "sm",
25559
- onClick: handleActionClick(action, itemData),
25560
- "data-testid": `action-${action.event}`,
25561
- "data-row-id": String(itemData.id),
25562
- className: "text-error hover:text-error hover:bg-error/10 px-2",
25563
- children: [
25564
- action.icon && renderIconInput(action.icon, { size: "xs" }),
25565
- action.label
25566
- ]
25567
- },
25568
- idx
25569
- )) })
25570
- ] }) }),
25571
- bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
25572
- const value = getNestedValue(itemData, field.name);
25573
- if (value === void 0 || value === null || value === "") return null;
25574
- if (field.format === "boolean") {
25575
- return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
25576
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
25577
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
25578
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
25579
- ] }),
25580
- /* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
25581
- ] }, field.name);
25582
- }
25583
- return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
25584
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
25585
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
25586
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
25587
- ] }),
25588
- /* @__PURE__ */ jsx(
25589
- Typography,
25599
+ (primaryActions.length > 0 || dangerActions.length > 0) && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "flex-shrink-0", children: [
25600
+ (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsx(
25601
+ Button,
25602
+ {
25603
+ variant: action.variant === "primary" ? "primary" : "ghost",
25604
+ size: "sm",
25605
+ onClick: handleActionClick(action, itemData),
25606
+ "data-testid": `action-${action.event}`,
25607
+ "data-row-id": String(itemData.id),
25608
+ "aria-label": action.label,
25609
+ title: action.label,
25610
+ className: cn(
25611
+ action.variant === "primary" ? void 0 : "text-muted-foreground hover:text-foreground",
25612
+ action.icon && "px-2"
25613
+ ),
25614
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
25615
+ },
25616
+ idx
25617
+ )),
25618
+ maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsx(
25619
+ Menu,
25590
25620
  {
25591
- variant: field.variant === "caption" ? "caption" : "small",
25592
- className: "text-right truncate max-w-[60%]",
25593
- children: formatValue(value, field.format)
25621
+ position: "bottom-end",
25622
+ 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" }) }),
25623
+ items: primaryActions.slice(maxInlineActions).map((action) => ({
25624
+ label: action.label,
25625
+ icon: action.icon,
25626
+ event: action.event,
25627
+ onClick: () => fireAction(action, itemData)
25628
+ }))
25594
25629
  }
25595
- )
25596
- ] }, field.name);
25597
- }) }) }),
25598
- 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: [
25599
- (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxs(
25600
- Button,
25601
- {
25602
- variant: action.variant === "primary" ? "primary" : "ghost",
25603
- size: "sm",
25604
- onClick: handleActionClick(action, itemData),
25605
- "data-testid": `action-${action.event}`,
25606
- "data-row-id": String(itemData.id),
25607
- children: [
25608
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
25609
- action.label
25610
- ]
25611
- },
25612
- idx
25613
- )),
25614
- maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsx(
25615
- Menu,
25616
- {
25617
- position: "bottom-end",
25618
- 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" }) }),
25619
- items: primaryActions.slice(maxInlineActions).map((action) => ({
25620
- label: action.label,
25621
- icon: action.icon,
25622
- event: action.event,
25623
- onClick: () => fireAction(action, itemData)
25624
- }))
25630
+ ),
25631
+ dangerActions.map((action, idx) => /* @__PURE__ */ jsx(
25632
+ Button,
25633
+ {
25634
+ variant: "ghost",
25635
+ size: "sm",
25636
+ onClick: handleActionClick(action, itemData),
25637
+ "data-testid": `action-${action.event}`,
25638
+ "data-row-id": String(itemData.id),
25639
+ "aria-label": action.label,
25640
+ title: action.label,
25641
+ className: "text-error hover:text-error hover:bg-error/10 px-2",
25642
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
25643
+ },
25644
+ `danger-${idx}`
25645
+ ))
25646
+ ] })
25647
+ ] }) }),
25648
+ bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 pt-2 pb-4 flex-1", children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
25649
+ bodyFields.filter((f3) => f3.variant === "caption" && f3.format !== "boolean").map((field) => {
25650
+ const value = getNestedValue(itemData, field.name);
25651
+ if (value === void 0 || value === null || value === "") return null;
25652
+ return /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: formatValue(value, field.format) }, field.name);
25653
+ }),
25654
+ /* @__PURE__ */ jsx(HStack, { gap: "md", className: "flex-wrap gap-y-1", children: bodyFields.filter((f3) => f3.variant !== "caption" || f3.format === "boolean").map((field) => {
25655
+ const value = getNestedValue(itemData, field.name);
25656
+ if (value === void 0 || value === null || value === "") return null;
25657
+ if (field.format === "boolean") {
25658
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
25659
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
25660
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) }),
25661
+ /* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
25662
+ ] }, field.name);
25625
25663
  }
25626
- )
25664
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
25665
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
25666
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
25667
+ /* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
25668
+ ] }, field.name);
25669
+ }) })
25627
25670
  ] }) })
25628
25671
  ]
25629
25672
  },
@@ -25971,11 +26014,29 @@ function DataList({
25971
26014
  const wrapDnd = (node) => dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: dndId, children: node }, dndId) : node;
25972
26015
  if (hasRenderProp) {
25973
26016
  const id2 = itemData.id || String(index);
26017
+ const actions = renderItemActions(itemData);
25974
26018
  return wrapDnd(
25975
- /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn(itemClickEvent && "cursor-pointer"), children: [
25976
- /* @__PURE__ */ jsxs(Box, { className: "group flex items-stretch gap-2", children: [
25977
- /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
25978
- renderItemActions(itemData)
26019
+ /* @__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: [
26020
+ children(itemData, index),
26021
+ 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: [
26022
+ /* @__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 }),
26023
+ /* @__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(
26024
+ Menu,
26025
+ {
26026
+ position: "bottom-end",
26027
+ 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" }) }),
26028
+ items: (itemActions ?? []).map((action) => ({
26029
+ label: action.label,
26030
+ icon: action.icon,
26031
+ event: action.event,
26032
+ variant: action.variant === "danger" ? "danger" : "default",
26033
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
26034
+ id: itemData.id,
26035
+ row: itemData
26036
+ })
26037
+ }))
26038
+ }
26039
+ ) })
25979
26040
  ] }),
25980
26041
  isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
25981
26042
  ] }, id2)
@@ -26015,7 +26076,7 @@ function DataList({
26015
26076
  ] }, field.name);
26016
26077
  })
26017
26078
  ] }),
26018
- bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
26079
+ bodyFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "md", className: cn("flex-wrap", isCompact ? "mt-0.5" : "mt-1.5"), children: bodyFields.map((field) => {
26019
26080
  const value = getNestedValue(itemData, field.name);
26020
26081
  if (value === void 0 || value === null || value === "") return null;
26021
26082
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
@@ -26365,10 +26426,7 @@ var init_FileTree = __esm({
26365
26426
  className,
26366
26427
  indent = 16
26367
26428
  }) => {
26368
- const { t } = useTranslate();
26369
- if (tree.length === 0) {
26370
- return /* @__PURE__ */ jsx(Box, { className: `p-4 ${className ?? ""}`, children: /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: t("fileTree.noFiles") }) });
26371
- }
26429
+ if (tree.length === 0) return null;
26372
26430
  return /* @__PURE__ */ jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsx(
26373
26431
  TreeNodeItem,
26374
26432
  {
@@ -29614,7 +29672,7 @@ var init_MapView = __esm({
29614
29672
  shadowSize: [41, 41]
29615
29673
  });
29616
29674
  L.Marker.prototype.options.icon = defaultIcon;
29617
- const { useEffect: useEffect63, useRef: useRef62, useCallback: useCallback93, useState: useState97 } = React91__default;
29675
+ const { useEffect: useEffect63, useRef: useRef62, useCallback: useCallback94, useState: useState97 } = React91__default;
29618
29676
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
29619
29677
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
29620
29678
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -29660,7 +29718,7 @@ var init_MapView = __esm({
29660
29718
  }) {
29661
29719
  const eventBus = useEventBus2();
29662
29720
  const [clickedPosition, setClickedPosition] = useState97(null);
29663
- const handleMapClick = useCallback93((lat, lng) => {
29721
+ const handleMapClick = useCallback94((lat, lng) => {
29664
29722
  if (showClickedPin) {
29665
29723
  setClickedPosition({ lat, lng });
29666
29724
  }
@@ -29669,7 +29727,7 @@ var init_MapView = __esm({
29669
29727
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
29670
29728
  }
29671
29729
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
29672
- const handleMarkerClick = useCallback93((marker) => {
29730
+ const handleMarkerClick = useCallback94((marker) => {
29673
29731
  onMarkerClick?.(marker);
29674
29732
  if (markerClickEvent) {
29675
29733
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -29871,7 +29929,7 @@ var init_NumberStepper = __esm({
29871
29929
  "active:bg-muted",
29872
29930
  "transition-colors duration-instant",
29873
29931
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
29874
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
29932
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
29875
29933
  styles.button
29876
29934
  ),
29877
29935
  "aria-label": t("aria.decrease"),
@@ -29912,7 +29970,7 @@ var init_NumberStepper = __esm({
29912
29970
  "active:bg-muted",
29913
29971
  "transition-colors duration-instant",
29914
29972
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
29915
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
29973
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
29916
29974
  styles.button
29917
29975
  ),
29918
29976
  "aria-label": t("aria.increase"),
@@ -30368,7 +30426,7 @@ var init_Lightbox = __esm({
30368
30426
  "p-2 rounded-full",
30369
30427
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
30370
30428
  "hover:bg-opacity-70 transition-opacity",
30371
- "focus:outline-none focus:ring-2 focus:ring-ring"
30429
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
30372
30430
  ),
30373
30431
  "aria-label": t("aria.closeModal"),
30374
30432
  children: /* @__PURE__ */ jsx(Icon, { name: "x", className: "w-6 h-6" })
@@ -30387,7 +30445,7 @@ var init_Lightbox = __esm({
30387
30445
  "p-2 rounded-full",
30388
30446
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
30389
30447
  "hover:bg-opacity-70 transition-opacity",
30390
- "focus:outline-none focus:ring-2 focus:ring-ring"
30448
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
30391
30449
  ),
30392
30450
  "aria-label": t("aria.previousImage"),
30393
30451
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-left", className: "w-8 h-8" })
@@ -30424,7 +30482,7 @@ var init_Lightbox = __esm({
30424
30482
  "p-2 rounded-full",
30425
30483
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
30426
30484
  "hover:bg-opacity-70 transition-opacity",
30427
- "focus:outline-none focus:ring-2 focus:ring-ring"
30485
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
30428
30486
  ),
30429
30487
  "aria-label": t("aria.nextImage"),
30430
30488
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", className: "w-8 h-8" })
@@ -30445,6 +30503,26 @@ var init_Lightbox = __esm({
30445
30503
  Lightbox.displayName = "Lightbox";
30446
30504
  }
30447
30505
  });
30506
+ function useMediaQuery(query) {
30507
+ const subscribe = useCallback(
30508
+ (onChange) => {
30509
+ const mql = window.matchMedia(query);
30510
+ mql.addEventListener("change", onChange);
30511
+ return () => mql.removeEventListener("change", onChange);
30512
+ },
30513
+ [query]
30514
+ );
30515
+ return useSyncExternalStore(
30516
+ subscribe,
30517
+ () => window.matchMedia(query).matches,
30518
+ () => false
30519
+ );
30520
+ }
30521
+ var init_useMediaQuery = __esm({
30522
+ "hooks/useMediaQuery.ts"() {
30523
+ "use client";
30524
+ }
30525
+ });
30448
30526
  function renderIconInput3(icon, props) {
30449
30527
  return typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsx(Icon, { icon, ...props });
30450
30528
  }
@@ -30551,6 +30629,7 @@ function TableView({
30551
30629
  const hasMore = pageSize > 0 && visibleCount < ordered.length;
30552
30630
  const hasRenderProp = typeof children === "function";
30553
30631
  const idField = dndItemIdField ?? "id";
30632
+ const isCoarsePointer = useMediaQuery("(pointer: coarse)");
30554
30633
  const selected = selectedIds ? new Set(selectedIds) : localSelected;
30555
30634
  const emitSelection = (next) => {
30556
30635
  if (!selectedIds) setLocalSelected(next);
@@ -30583,6 +30662,17 @@ function TableView({
30583
30662
  };
30584
30663
  eventBus.emit(`UI:${action.event}`, payload);
30585
30664
  };
30665
+ const colFloors = React91__default.useMemo(
30666
+ () => colDefs.map((col) => {
30667
+ const longest = data.reduce((widest, row) => {
30668
+ const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
30669
+ return Math.max(widest, cell.length);
30670
+ }, columnLabel(col).length);
30671
+ const chrome = col.format === "badge" ? BADGE_CHROME_CH : 0;
30672
+ return Math.min(longest + chrome, MAX_MEASURED_COL_CH);
30673
+ }),
30674
+ [colDefs, data]
30675
+ );
30586
30676
  if (isLoading) {
30587
30677
  return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") }) });
30588
30678
  }
@@ -30595,19 +30685,10 @@ function TableView({
30595
30685
  }
30596
30686
  const lk = LOOKS[look];
30597
30687
  const hasActions = Boolean(itemActions && itemActions.length > 0);
30598
- const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
30599
- const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
30688
+ const effectiveMaxInline = isCoarsePointer ? 0 : maxInlineActions;
30689
+ const inlineActionCount = hasActions ? effectiveMaxInline != null ? Math.min(itemActions.length, effectiveMaxInline) : itemActions.length : 0;
30690
+ const hasOverflowActions = hasActions && effectiveMaxInline != null && itemActions.length > effectiveMaxInline;
30600
30691
  const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
30601
- const colFloors = React91__default.useMemo(
30602
- () => colDefs.map((col) => {
30603
- const longest = data.reduce((widest, row) => {
30604
- const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
30605
- return Math.max(widest, cell.length);
30606
- }, columnLabel(col).length);
30607
- return Math.min(longest, MAX_MEASURED_COL_CH);
30608
- }),
30609
- [colDefs, data]
30610
- );
30611
30692
  const gridTemplateColumns = [
30612
30693
  selectable ? "auto" : null,
30613
30694
  ...colDefs.map((c, i) => c.width ?? `minmax(${colFloors[i]}ch, 1fr)`),
@@ -30694,9 +30775,9 @@ function TableView({
30694
30775
  col.className
30695
30776
  );
30696
30777
  if (col.format === "badge" && raw != null && raw !== "") {
30697
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
30778
+ 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);
30698
30779
  }
30699
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
30780
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format) }) }, col.key);
30700
30781
  }),
30701
30782
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(
30702
30783
  HStack,
@@ -30710,15 +30791,15 @@ function TableView({
30710
30791
  lk.striped && index % 2 === 1 ? "bg-[var(--color-surface-subtle)]" : "bg-[var(--color-card)] group-hover:bg-[var(--color-surface-subtle)]"
30711
30792
  ),
30712
30793
  children: [
30713
- (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
30794
+ (effectiveMaxInline != null ? itemActions.slice(0, effectiveMaxInline) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
30714
30795
  Button,
30715
30796
  {
30716
- variant: action.variant ?? "ghost",
30797
+ variant: action.variant === "primary" ? "primary" : "ghost",
30717
30798
  size: "sm",
30718
30799
  onClick: handleActionClick(action, row),
30719
30800
  "data-testid": `action-${action.event}`,
30720
30801
  "data-row-id": String(row.id),
30721
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
30802
+ className: cn(action.variant === "danger" && "text-error hover:text-error hover:bg-error/10"),
30722
30803
  children: [
30723
30804
  action.icon && renderIconInput3(action.icon, { size: "xs", className: "mr-1" }),
30724
30805
  action.label
@@ -30726,12 +30807,12 @@ function TableView({
30726
30807
  },
30727
30808
  i
30728
30809
  )),
30729
- maxInlineActions != null && itemActions.length > maxInlineActions && /* @__PURE__ */ jsx(
30810
+ effectiveMaxInline != null && itemActions.length > effectiveMaxInline && /* @__PURE__ */ jsx(
30730
30811
  Menu,
30731
30812
  {
30732
30813
  position: "bottom-end",
30733
30814
  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" }) }),
30734
- items: itemActions.slice(maxInlineActions).map((action) => ({
30815
+ items: itemActions.slice(effectiveMaxInline).map((action) => ({
30735
30816
  label: action.label,
30736
30817
  icon: action.icon,
30737
30818
  event: action.event,
@@ -30777,13 +30858,14 @@ function TableView({
30777
30858
  }
30778
30859
  );
30779
30860
  }
30780
- var MAX_MEASURED_COL_CH, alignClass, weightClass, LOOKS;
30861
+ var MAX_MEASURED_COL_CH, BADGE_CHROME_CH, alignClass, weightClass, LOOKS;
30781
30862
  var init_TableView = __esm({
30782
30863
  "components/core/molecules/TableView.tsx"() {
30783
30864
  "use client";
30784
30865
  init_cn();
30785
30866
  init_getNestedValue();
30786
30867
  init_useEventBus();
30868
+ init_useMediaQuery();
30787
30869
  init_Box();
30788
30870
  init_Stack();
30789
30871
  init_Typography();
@@ -30796,6 +30878,7 @@ var init_TableView = __esm({
30796
30878
  init_useDataDnd();
30797
30879
  createLogger("almadar:ui:table-view");
30798
30880
  MAX_MEASURED_COL_CH = 32;
30881
+ BADGE_CHROME_CH = 4;
30799
30882
  alignClass = {
30800
30883
  left: "justify-start text-left",
30801
30884
  center: "justify-center text-center",
@@ -30807,7 +30890,7 @@ var init_TableView = __esm({
30807
30890
  semibold: "font-semibold"
30808
30891
  };
30809
30892
  LOOKS = {
30810
- dense: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true },
30893
+ dense: { rowPad: "px-card-md py-2", headPad: "px-card-md py-2", striped: false, divider: true },
30811
30894
  spacious: { rowPad: "px-card-lg py-card-md", headPad: "px-card-lg py-card-sm", striped: false, divider: true },
30812
30895
  striped: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: true, divider: false },
30813
30896
  borderless: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: false },
@@ -33031,7 +33114,7 @@ var init_VoteStack = __esm({
33031
33114
  "active:bg-muted",
33032
33115
  "transition-colors duration-instant",
33033
33116
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
33034
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
33117
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
33035
33118
  styles.button
33036
33119
  ),
33037
33120
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-up", className: styles.icon })
@@ -33068,7 +33151,7 @@ var init_VoteStack = __esm({
33068
33151
  "active:bg-muted",
33069
33152
  "transition-colors duration-instant",
33070
33153
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
33071
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
33154
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
33072
33155
  styles.button
33073
33156
  ),
33074
33157
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-down", className: styles.icon })
@@ -33589,7 +33672,7 @@ var init_QrScanner = __esm({
33589
33672
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
33590
33673
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
33591
33674
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
33592
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
33675
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
33593
33676
  ),
33594
33677
  "aria-label": isPaused ? t("qrScanner.resumeScanning") : t("qrScanner.pauseScanning"),
33595
33678
  children: isPaused ? /* @__PURE__ */ jsx(Icon, { name: "play", className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Icon, { name: "pause", className: "h-4 w-4" })
@@ -33604,7 +33687,7 @@ var init_QrScanner = __esm({
33604
33687
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
33605
33688
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
33606
33689
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
33607
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
33690
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
33608
33691
  ),
33609
33692
  "aria-label": currentFacing === "environment" ? t("qrScanner.switchToFrontCamera") : t("qrScanner.switchToRearCamera"),
33610
33693
  children: /* @__PURE__ */ jsx(Icon, { name: "refresh-cw", className: "h-4 w-4" })
@@ -33619,7 +33702,7 @@ var init_QrScanner = __esm({
33619
33702
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
33620
33703
  "rounded-full bg-black bg-opacity-60 px-3 py-2 text-xs text-white",
33621
33704
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
33622
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
33705
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
33623
33706
  ),
33624
33707
  "aria-label": t("aria.mockScanDev"),
33625
33708
  children: t("qrScanner.mockScan")
@@ -41455,27 +41538,24 @@ var init_MasterDetailLayout = __esm({
41455
41538
  masterClassName,
41456
41539
  detailClassName
41457
41540
  }) => {
41458
- masterWidth.endsWith("%") ? parseInt(masterWidth, 10) : 30;
41459
41541
  return /* @__PURE__ */ jsxs(
41460
41542
  "div",
41461
41543
  {
41462
- className: cn("flex h-full w-full", className),
41463
- style: {
41464
- display: "grid",
41465
- gridTemplateColumns: masterWidth.endsWith("%") ? `${masterWidth} 1fr` : `${masterWidth} 1fr`
41466
- },
41544
+ className: cn("w-full h-full md:grid md:grid-cols-[var(--master-detail-cols)]", className),
41545
+ style: { "--master-detail-cols": `${masterWidth} 1fr` },
41467
41546
  children: [
41468
41547
  /* @__PURE__ */ jsx(
41469
41548
  "div",
41470
41549
  {
41471
41550
  className: cn(
41472
- "border-r-2 border-border overflow-auto",
41551
+ "border-r border-border overflow-auto",
41552
+ hasSelection && "hidden md:block",
41473
41553
  masterClassName
41474
41554
  ),
41475
41555
  children: master
41476
41556
  }
41477
41557
  ),
41478
- /* @__PURE__ */ jsx("div", { className: cn("overflow-auto", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsx(DefaultEmptyDetail, {}) })
41558
+ /* @__PURE__ */ jsx("div", { className: cn("overflow-auto", !hasSelection && "hidden md:block", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsx(DefaultEmptyDetail, {}) })
41479
41559
  ]
41480
41560
  }
41481
41561
  );
@@ -45047,7 +45127,7 @@ var init_TabbedContainer = __esm({
45047
45127
  onClick: () => !isDisabled && handleTabChange(tab.id),
45048
45128
  className: cn(
45049
45129
  "flex items-center gap-2 px-4 py-3 text-sm font-medium transition-colors",
45050
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
45130
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
45051
45131
  "disabled:opacity-50 disabled:cursor-not-allowed",
45052
45132
  isActive ? "bg-primary text-primary-foreground" : "bg-card text-foreground hover:bg-muted",
45053
45133
  isVertical ? "justify-start" : "justify-center"