@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.
@@ -1173,7 +1173,7 @@ var init_Button = __esm({
1173
1173
  "cursor-pointer",
1174
1174
  "chrome-button",
1175
1175
  "transition-all duration-normal",
1176
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-offset-[length:var(--focus-ring-offset)]",
1176
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--focus-ring-offset)]",
1177
1177
  "disabled:opacity-50 disabled:cursor-not-allowed",
1178
1178
  variantStyles[variant],
1179
1179
  sizeStyles[size],
@@ -1894,6 +1894,8 @@ var init_Badge = __esm({
1894
1894
  };
1895
1895
  const iconPx = size === "lg" ? 20 : 16;
1896
1896
  const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsxRuntime.jsx(AtlasImage, { asset: iconAsset, size: iconPx, alt: iconAsset.name ?? iconAsset.category ?? "", className: "flex-shrink-0" }) : typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, className: iconSizes3[size] }) : null;
1897
+ const hasText = Boolean(children) || amount != null || label !== void 0 && label !== null && label !== "";
1898
+ if (!hasText && !resolvedIcon && !onRemove) return null;
1897
1899
  return /* @__PURE__ */ jsxRuntime.jsxs(
1898
1900
  "span",
1899
1901
  {
@@ -1920,7 +1922,7 @@ var init_Badge = __esm({
1920
1922
  },
1921
1923
  className: cn(
1922
1924
  "inline-flex items-center justify-center rounded-sm",
1923
- "hover:bg-foreground/10 focus:outline-none focus:ring-1 focus:ring-ring",
1925
+ "hover:bg-foreground/10 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
1924
1926
  "transition-colors",
1925
1927
  size === "sm" ? "w-4 h-4 ml-0.5" : size === "md" ? "w-5 h-5 ml-1" : "w-6 h-6 ml-1"
1926
1928
  ),
@@ -3278,7 +3280,7 @@ function NativeSelect({
3278
3280
  "block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
3279
3281
  "px-3 py-2 pr-10 text-sm text-foreground font-medium",
3280
3282
  "bg-card",
3281
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
3283
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
3282
3284
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
3283
3285
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
3284
3286
  className
@@ -3385,7 +3387,7 @@ function RichSelect({
3385
3387
  "block w-full border-[length:var(--border-width)] shadow-sm",
3386
3388
  "px-3 py-2 pr-10 text-sm text-start font-medium",
3387
3389
  "bg-card rounded-sm",
3388
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
3390
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
3389
3391
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
3390
3392
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
3391
3393
  !hasValue && "text-muted-foreground"
@@ -4308,9 +4310,9 @@ var init_Radio = __esm({
4308
4310
  "flex items-center justify-center",
4309
4311
  "border-[length:var(--border-width)] transition-all cursor-pointer",
4310
4312
  sizeClasses4[size],
4311
- hasError ? "border-error peer-focus:ring-error/20" : "border-border peer-focus:ring-ring/20",
4313
+ hasError ? "border-error peer-focus-visible:ring-error/20" : "border-border peer-focus-visible:ring-ring/20",
4312
4314
  isChecked2 ? hasError ? "border-error" : "border-primary bg-primary" : "",
4313
- "peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-offset-2",
4315
+ "peer-focus:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2",
4314
4316
  disabled && "opacity-50 cursor-not-allowed",
4315
4317
  !disabled && "hover:border-[var(--color-border-hover)]"
4316
4318
  ),
@@ -4781,7 +4783,7 @@ var init_ThemeToggle = __esm({
4781
4783
  "inline-flex items-center justify-center gap-2",
4782
4784
  "text-foreground",
4783
4785
  "hover:bg-muted border-[length:var(--border-width)] border-transparent hover:border-border",
4784
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
4786
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4785
4787
  "transition-colors duration-fast",
4786
4788
  sizeClasses5[size],
4787
4789
  className
@@ -5216,11 +5218,13 @@ var init_TrendIndicator = __esm({
5216
5218
  size = "md",
5217
5219
  ...props
5218
5220
  }, ref) => {
5219
- const dir = resolveDirection(value, direction);
5221
+ const hasValue = typeof value === "number" && Number.isFinite(value);
5222
+ if (!hasValue && !direction) return null;
5223
+ const dir = resolveDirection(hasValue ? value : void 0, direction);
5220
5224
  const colorClass = resolveColor(dir, invert);
5221
5225
  const iconName = iconNameMap[dir];
5222
5226
  const styles = sizeStyles6[size];
5223
- const formattedValue = value !== void 0 ? `${value > 0 ? "+" : ""}${value}%` : void 0;
5227
+ const formattedValue = hasValue ? `${value > 0 ? "+" : ""}${value}%` : void 0;
5224
5228
  const ariaLabel = label ?? (formattedValue ? `${dir} ${formattedValue}` : dir);
5225
5229
  return /* @__PURE__ */ jsxRuntime.jsxs(
5226
5230
  "span",
@@ -11819,10 +11823,12 @@ var init_Container = __esm({
11819
11823
  };
11820
11824
  paddingStyles3 = {
11821
11825
  none: "px-0",
11822
- sm: "px-4",
11823
- md: "px-6",
11824
- lg: "px-8",
11825
- xl: "px-12"
11826
+ // Mobile-tighter, desktop-identical: fixed px-6 on a 360px phone eats ~13% of
11827
+ // the viewport, so each token steps down below the sm breakpoint.
11828
+ sm: "px-3 sm:px-4",
11829
+ md: "px-4 sm:px-6",
11830
+ lg: "px-4 sm:px-6 md:px-8",
11831
+ xl: "px-4 sm:px-8 md:px-12"
11826
11832
  };
11827
11833
  Container = ({
11828
11834
  size,
@@ -12521,7 +12527,7 @@ var init_Accordion = __esm({
12521
12527
  "bg-card",
12522
12528
  "hover:bg-muted",
12523
12529
  "transition-colors duration-fast",
12524
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-inset",
12530
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
12525
12531
  "disabled:opacity-50 disabled:cursor-not-allowed",
12526
12532
  isOpen && "bg-muted font-bold"
12527
12533
  ),
@@ -18118,26 +18124,19 @@ var init_BookViewer = __esm({
18118
18124
  function BoxPattern({
18119
18125
  p,
18120
18126
  m,
18121
- bg = "transparent",
18122
- border = false,
18123
- radius = "none",
18124
- shadow = "none",
18125
- className,
18126
- style,
18127
- children
18127
+ radius,
18128
+ isLoading: _isLoading,
18129
+ error: _error,
18130
+ entity: _entity,
18131
+ ...boxProps
18128
18132
  }) {
18129
18133
  return /* @__PURE__ */ jsxRuntime.jsx(
18130
18134
  Box,
18131
18135
  {
18132
- padding: p,
18133
- margin: m,
18134
- bg,
18135
- border,
18136
- rounded: radius,
18137
- shadow,
18138
- className,
18139
- style,
18140
- children
18136
+ padding: boxProps.padding ?? p,
18137
+ margin: boxProps.margin ?? m,
18138
+ rounded: boxProps.rounded ?? radius,
18139
+ ...boxProps
18141
18140
  }
18142
18141
  );
18143
18142
  }
@@ -18726,7 +18725,7 @@ var init_Breadcrumb = __esm({
18726
18725
  },
18727
18726
  className: cn(
18728
18727
  "flex items-center gap-1.5 transition-colors",
18729
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
18728
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
18730
18729
  isLast ? "text-foreground font-bold cursor-default" : "text-muted-foreground hover:text-foreground"
18731
18730
  ),
18732
18731
  "aria-current": isLast ? "page" : void 0,
@@ -21828,17 +21827,19 @@ var init_DashboardLayout = __esm({
21828
21827
  const [sidebarOpen, setSidebarOpen] = React84.useState(false);
21829
21828
  const [userMenuOpen, setUserMenuOpen] = React84.useState(false);
21830
21829
  const layoutRef = React84.useRef(null);
21831
- const [isMobile, setIsMobile] = React84.useState(false);
21830
+ const [layoutWidth, setLayoutWidth] = React84.useState(null);
21832
21831
  React84.useEffect(() => {
21833
21832
  const el = layoutRef.current;
21834
21833
  if (!el || typeof ResizeObserver === "undefined") return;
21835
21834
  const ro = new ResizeObserver((entries) => {
21836
21835
  const w = entries[0]?.contentRect.width ?? el.clientWidth;
21837
- setIsMobile(w < 1024);
21836
+ setLayoutWidth(w);
21838
21837
  });
21839
21838
  ro.observe(el);
21840
21839
  return () => ro.disconnect();
21841
21840
  }, []);
21841
+ const isMobile = layoutWidth !== null && layoutWidth < 768;
21842
+ const isRail = layoutWidth !== null && layoutWidth >= 768 && layoutWidth < 1024;
21842
21843
  React84.useEffect(() => {
21843
21844
  if (!isMobile && sidebarOpen) setSidebarOpen(false);
21844
21845
  }, [isMobile, sidebarOpen]);
@@ -21871,7 +21872,8 @@ var init_DashboardLayout = __esm({
21871
21872
  {
21872
21873
  as: "aside",
21873
21874
  className: cn(
21874
- "z-30 w-64 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
21875
+ "z-30 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
21876
+ isRail ? "w-16" : "w-64",
21875
21877
  "flex flex-col"
21876
21878
  ),
21877
21879
  style: isMobile ? {
@@ -21887,10 +21889,10 @@ var init_DashboardLayout = __esm({
21887
21889
  HStack,
21888
21890
  {
21889
21891
  align: "center",
21890
- justify: "between",
21891
- className: "h-16 px-4 border-b border-border dark:border-border",
21892
+ justify: isRail ? "center" : "between",
21893
+ className: cn("h-16 border-b border-border dark:border-border", isRail ? "px-2" : "px-4"),
21892
21894
  children: [
21893
- /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Link, { to: "/", className: "flex items-center gap-2", children: [
21895
+ /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Link, { to: "/", className: "flex items-center gap-2", title: isRail ? appName : void 0, children: [
21894
21896
  logo || /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 h-8 bg-primary rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
21895
21897
  Typography,
21896
21898
  {
@@ -21900,7 +21902,7 @@ var init_DashboardLayout = __esm({
21900
21902
  children: appName.charAt(0).toUpperCase()
21901
21903
  }
21902
21904
  ) }),
21903
- /* @__PURE__ */ jsxRuntime.jsx(
21905
+ !isRail && /* @__PURE__ */ jsxRuntime.jsx(
21904
21906
  Typography,
21905
21907
  {
21906
21908
  variant: "label",
@@ -21927,12 +21929,13 @@ var init_DashboardLayout = __esm({
21927
21929
  {
21928
21930
  as: "nav",
21929
21931
  gap: "none",
21930
- className: "flex-1 px-3 py-4 space-y-1 overflow-y-auto",
21932
+ className: cn("flex-1 py-4 space-y-1 overflow-y-auto", isRail ? "px-2" : "px-3"),
21931
21933
  children: navItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
21932
21934
  NavLink,
21933
21935
  {
21934
21936
  item,
21935
- currentPath: activePath
21937
+ currentPath: activePath,
21938
+ compact: isRail
21936
21939
  },
21937
21940
  item.href
21938
21941
  ))
@@ -22187,13 +22190,40 @@ var init_DashboardLayout = __esm({
22187
22190
  DashboardLayout.displayName = "DashboardLayout";
22188
22191
  NavLink = ({
22189
22192
  item,
22190
- currentPath
22193
+ currentPath,
22194
+ compact = false
22191
22195
  }) => {
22192
22196
  const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
22193
22197
  const iconClassName = cn(
22194
22198
  "h-5 w-5",
22195
22199
  isActive ? "text-primary-foreground" : "text-muted-foreground"
22196
22200
  );
22201
+ if (compact) {
22202
+ return /* @__PURE__ */ jsxRuntime.jsx(
22203
+ reactRouterDom.Link,
22204
+ {
22205
+ to: item.href,
22206
+ title: item.label,
22207
+ "aria-label": item.label,
22208
+ className: cn(
22209
+ "flex items-center justify-center px-2 py-2 rounded-lg transition-colors",
22210
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
22211
+ ),
22212
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { as: "span", className: "relative inline-flex", children: [
22213
+ item.icon ? typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, className: iconClassName }) : /* @__PURE__ */ jsxRuntime.jsx(item.icon, { className: iconClassName }) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "font-semibold", as: "span", children: item.label.charAt(0).toUpperCase() }),
22214
+ item.badge && /* @__PURE__ */ jsxRuntime.jsx(
22215
+ Badge,
22216
+ {
22217
+ variant: isActive ? "primary" : "default",
22218
+ size: "sm",
22219
+ className: "absolute -top-2 -right-2 px-1 py-0 text-[10px] leading-4",
22220
+ children: item.badge
22221
+ }
22222
+ )
22223
+ ] })
22224
+ }
22225
+ );
22226
+ }
22197
22227
  return /* @__PURE__ */ jsxRuntime.jsxs(
22198
22228
  reactRouterDom.Link,
22199
22229
  {
@@ -23259,40 +23289,55 @@ function DataGrid({
23259
23289
  {
23260
23290
  "data-entity-row": true,
23261
23291
  "data-entity-id": id,
23262
- className: cn(isSelected && "ring-2 ring-primary rounded-lg"),
23292
+ className: cn("relative group/rowactions", isSelected && "ring-2 ring-primary rounded-lg"),
23263
23293
  children: [
23264
23294
  children(itemData, index),
23265
- actionDefs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-end", children: [
23266
- (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23267
- Button,
23268
- {
23269
- variant: action.variant === "primary" ? "primary" : "ghost",
23270
- size: "sm",
23271
- onClick: handleActionClick(action, itemData),
23272
- "data-testid": `action-${action.event}`,
23273
- "data-row-id": String(itemData.id),
23274
- className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
23275
- children: [
23276
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
23277
- action.label
23278
- ]
23279
- },
23280
- idx
23281
- )),
23282
- maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
23295
+ actionDefs.length > 0 && /* @__PURE__ */ jsxRuntime.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: [
23296
+ /* @__PURE__ */ jsxRuntime.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: [
23297
+ (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23298
+ Button,
23299
+ {
23300
+ variant: action.variant === "primary" ? "primary" : "ghost",
23301
+ size: "sm",
23302
+ onClick: handleActionClick(action, itemData),
23303
+ "data-testid": `action-${action.event}`,
23304
+ "data-row-id": String(itemData.id),
23305
+ className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
23306
+ children: [
23307
+ action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
23308
+ action.label
23309
+ ]
23310
+ },
23311
+ idx
23312
+ )),
23313
+ maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
23314
+ Menu,
23315
+ {
23316
+ position: "bottom-end",
23317
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23318
+ items: actionDefs.slice(maxInlineActions).map((action) => ({
23319
+ label: action.label,
23320
+ icon: action.icon,
23321
+ event: action.event,
23322
+ onClick: () => fireAction(action, itemData)
23323
+ }))
23324
+ }
23325
+ )
23326
+ ] }),
23327
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(
23283
23328
  Menu,
23284
23329
  {
23285
23330
  position: "bottom-end",
23286
23331
  trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23287
- items: actionDefs.slice(maxInlineActions).map((action) => ({
23332
+ items: actionDefs.map((action) => ({
23288
23333
  label: action.label,
23289
23334
  icon: action.icon,
23290
23335
  event: action.event,
23291
23336
  onClick: () => fireAction(action, itemData)
23292
23337
  }))
23293
23338
  }
23294
- )
23295
- ] }) })
23339
+ ) })
23340
+ ] })
23296
23341
  ]
23297
23342
  },
23298
23343
  id
@@ -23328,7 +23373,7 @@ function DataGrid({
23328
23373
  }
23329
23374
  ) });
23330
23375
  })(),
23331
- /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
23376
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("p-4", bodyFields.length > 0 && "pb-0"), children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
23332
23377
  selectable && /* @__PURE__ */ jsxRuntime.jsx(
23333
23378
  "input",
23334
23379
  {
@@ -23361,79 +23406,77 @@ function DataGrid({
23361
23406
  ] }, field.name);
23362
23407
  }) })
23363
23408
  ] }),
23364
- dangerActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23365
- Button,
23366
- {
23367
- variant: "ghost",
23368
- size: "sm",
23369
- onClick: handleActionClick(action, itemData),
23370
- "data-testid": `action-${action.event}`,
23371
- "data-row-id": String(itemData.id),
23372
- className: "text-error hover:text-error hover:bg-error/10 px-2",
23373
- children: [
23374
- action.icon && renderIconInput(action.icon, { size: "xs" }),
23375
- action.label
23376
- ]
23377
- },
23378
- idx
23379
- )) })
23380
- ] }) }),
23381
- bodyFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
23382
- const value = getNestedValue(itemData, field.name);
23383
- if (value === void 0 || value === null || value === "") return null;
23384
- if (field.format === "boolean") {
23385
- return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
23386
- /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
23387
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23388
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
23389
- ] }),
23390
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
23391
- ] }, field.name);
23392
- }
23393
- return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
23394
- /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
23395
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23396
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
23397
- ] }),
23398
- /* @__PURE__ */ jsxRuntime.jsx(
23399
- Typography,
23409
+ (primaryActions.length > 0 || dangerActions.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "flex-shrink-0", children: [
23410
+ (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
23411
+ Button,
23412
+ {
23413
+ variant: action.variant === "primary" ? "primary" : "ghost",
23414
+ size: "sm",
23415
+ onClick: handleActionClick(action, itemData),
23416
+ "data-testid": `action-${action.event}`,
23417
+ "data-row-id": String(itemData.id),
23418
+ "aria-label": action.label,
23419
+ title: action.label,
23420
+ className: cn(
23421
+ action.variant === "primary" ? void 0 : "text-muted-foreground hover:text-foreground",
23422
+ action.icon && "px-2"
23423
+ ),
23424
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
23425
+ },
23426
+ idx
23427
+ )),
23428
+ maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
23429
+ Menu,
23400
23430
  {
23401
- variant: field.variant === "caption" ? "caption" : "small",
23402
- className: "text-right truncate max-w-[60%]",
23403
- children: formatValue(value, field.format)
23431
+ position: "bottom-end",
23432
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23433
+ items: primaryActions.slice(maxInlineActions).map((action) => ({
23434
+ label: action.label,
23435
+ icon: action.icon,
23436
+ event: action.event,
23437
+ onClick: () => fireAction(action, itemData)
23438
+ }))
23404
23439
  }
23405
- )
23406
- ] }, field.name);
23407
- }) }) }),
23408
- primaryActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-end flex-wrap", children: [
23409
- (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23410
- Button,
23411
- {
23412
- variant: action.variant === "primary" ? "primary" : "ghost",
23413
- size: "sm",
23414
- onClick: handleActionClick(action, itemData),
23415
- "data-testid": `action-${action.event}`,
23416
- "data-row-id": String(itemData.id),
23417
- children: [
23418
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
23419
- action.label
23420
- ]
23421
- },
23422
- idx
23423
- )),
23424
- maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
23425
- Menu,
23426
- {
23427
- position: "bottom-end",
23428
- trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23429
- items: primaryActions.slice(maxInlineActions).map((action) => ({
23430
- label: action.label,
23431
- icon: action.icon,
23432
- event: action.event,
23433
- onClick: () => fireAction(action, itemData)
23434
- }))
23440
+ ),
23441
+ dangerActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
23442
+ Button,
23443
+ {
23444
+ variant: "ghost",
23445
+ size: "sm",
23446
+ onClick: handleActionClick(action, itemData),
23447
+ "data-testid": `action-${action.event}`,
23448
+ "data-row-id": String(itemData.id),
23449
+ "aria-label": action.label,
23450
+ title: action.label,
23451
+ className: "text-error hover:text-error hover:bg-error/10 px-2",
23452
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
23453
+ },
23454
+ `danger-${idx}`
23455
+ ))
23456
+ ] })
23457
+ ] }) }),
23458
+ bodyFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 pt-2 pb-4 flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
23459
+ bodyFields.filter((f3) => f3.variant === "caption" && f3.format !== "boolean").map((field) => {
23460
+ const value = getNestedValue(itemData, field.name);
23461
+ if (value === void 0 || value === null || value === "") return null;
23462
+ return /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: formatValue(value, field.format) }, field.name);
23463
+ }),
23464
+ /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "flex-wrap gap-y-1", children: bodyFields.filter((f3) => f3.variant !== "caption" || f3.format === "boolean").map((field) => {
23465
+ const value = getNestedValue(itemData, field.name);
23466
+ if (value === void 0 || value === null || value === "") return null;
23467
+ if (field.format === "boolean") {
23468
+ return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
23469
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23470
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) }),
23471
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
23472
+ ] }, field.name);
23435
23473
  }
23436
- )
23474
+ return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
23475
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23476
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
23477
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
23478
+ ] }, field.name);
23479
+ }) })
23437
23480
  ] }) })
23438
23481
  ]
23439
23482
  },
@@ -23781,11 +23824,29 @@ function DataList({
23781
23824
  const wrapDnd = (node) => dnd.isZone ? /* @__PURE__ */ jsxRuntime.jsx(dnd.SortableItem, { id: dndId, children: node }, dndId) : node;
23782
23825
  if (hasRenderProp) {
23783
23826
  const id2 = itemData.id || String(index);
23827
+ const actions = renderItemActions(itemData);
23784
23828
  return wrapDnd(
23785
- /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn(itemClickEvent && "cursor-pointer"), children: [
23786
- /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "group flex items-stretch gap-2", children: [
23787
- /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
23788
- renderItemActions(itemData)
23829
+ /* @__PURE__ */ jsxRuntime.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: [
23830
+ children(itemData, index),
23831
+ actions && /* @__PURE__ */ jsxRuntime.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: [
23832
+ /* @__PURE__ */ jsxRuntime.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 }),
23833
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(
23834
+ Menu,
23835
+ {
23836
+ position: "bottom-end",
23837
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23838
+ items: (itemActions ?? []).map((action) => ({
23839
+ label: action.label,
23840
+ icon: action.icon,
23841
+ event: action.event,
23842
+ variant: action.variant === "danger" ? "danger" : "default",
23843
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
23844
+ id: itemData.id,
23845
+ row: itemData
23846
+ })
23847
+ }))
23848
+ }
23849
+ ) })
23789
23850
  ] }),
23790
23851
  isCard && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mx-6 border-b border-border/40" })
23791
23852
  ] }, id2)
@@ -23825,7 +23886,7 @@ function DataList({
23825
23886
  ] }, field.name);
23826
23887
  })
23827
23888
  ] }),
23828
- bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
23889
+ bodyFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: cn("flex-wrap", isCompact ? "mt-0.5" : "mt-1.5"), children: bodyFields.map((field) => {
23829
23890
  const value = getNestedValue(itemData, field.name);
23830
23891
  if (value === void 0 || value === null || value === "") return null;
23831
23892
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
@@ -24175,10 +24236,7 @@ var init_FileTree = __esm({
24175
24236
  className,
24176
24237
  indent = 16
24177
24238
  }) => {
24178
- const { t } = hooks.useTranslate();
24179
- if (tree.length === 0) {
24180
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `p-4 ${className ?? ""}`, children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "muted", children: t("fileTree.noFiles") }) });
24181
- }
24239
+ if (tree.length === 0) return null;
24182
24240
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
24183
24241
  TreeNodeItem,
24184
24242
  {
@@ -27424,7 +27482,7 @@ var init_MapView = __esm({
27424
27482
  shadowSize: [41, 41]
27425
27483
  });
27426
27484
  L.Marker.prototype.options.icon = defaultIcon;
27427
- const { useEffect: useEffect62, useRef: useRef60, useCallback: useCallback93, useState: useState91 } = React84__namespace.default;
27485
+ const { useEffect: useEffect62, useRef: useRef60, useCallback: useCallback94, useState: useState91 } = React84__namespace.default;
27428
27486
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
27429
27487
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
27430
27488
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -27470,7 +27528,7 @@ var init_MapView = __esm({
27470
27528
  }) {
27471
27529
  const eventBus = useEventBus2();
27472
27530
  const [clickedPosition, setClickedPosition] = useState91(null);
27473
- const handleMapClick = useCallback93((lat, lng) => {
27531
+ const handleMapClick = useCallback94((lat, lng) => {
27474
27532
  if (showClickedPin) {
27475
27533
  setClickedPosition({ lat, lng });
27476
27534
  }
@@ -27479,7 +27537,7 @@ var init_MapView = __esm({
27479
27537
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
27480
27538
  }
27481
27539
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
27482
- const handleMarkerClick = useCallback93((marker) => {
27540
+ const handleMarkerClick = useCallback94((marker) => {
27483
27541
  onMarkerClick?.(marker);
27484
27542
  if (markerClickEvent) {
27485
27543
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -27681,7 +27739,7 @@ var init_NumberStepper = __esm({
27681
27739
  "active:bg-muted",
27682
27740
  "transition-colors duration-instant",
27683
27741
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27684
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27742
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
27685
27743
  styles.button
27686
27744
  ),
27687
27745
  "aria-label": t("aria.decrease"),
@@ -27722,7 +27780,7 @@ var init_NumberStepper = __esm({
27722
27780
  "active:bg-muted",
27723
27781
  "transition-colors duration-instant",
27724
27782
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27725
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27783
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
27726
27784
  styles.button
27727
27785
  ),
27728
27786
  "aria-label": t("aria.increase"),
@@ -28178,7 +28236,7 @@ var init_Lightbox = __esm({
28178
28236
  "p-2 rounded-full",
28179
28237
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
28180
28238
  "hover:bg-opacity-70 transition-opacity",
28181
- "focus:outline-none focus:ring-2 focus:ring-ring"
28239
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
28182
28240
  ),
28183
28241
  "aria-label": t("aria.closeModal"),
28184
28242
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "x", className: "w-6 h-6" })
@@ -28197,7 +28255,7 @@ var init_Lightbox = __esm({
28197
28255
  "p-2 rounded-full",
28198
28256
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
28199
28257
  "hover:bg-opacity-70 transition-opacity",
28200
- "focus:outline-none focus:ring-2 focus:ring-ring"
28258
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
28201
28259
  ),
28202
28260
  "aria-label": t("aria.previousImage"),
28203
28261
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-left", className: "w-8 h-8" })
@@ -28234,7 +28292,7 @@ var init_Lightbox = __esm({
28234
28292
  "p-2 rounded-full",
28235
28293
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
28236
28294
  "hover:bg-opacity-70 transition-opacity",
28237
- "focus:outline-none focus:ring-2 focus:ring-ring"
28295
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
28238
28296
  ),
28239
28297
  "aria-label": t("aria.nextImage"),
28240
28298
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-right", className: "w-8 h-8" })
@@ -28255,6 +28313,26 @@ var init_Lightbox = __esm({
28255
28313
  Lightbox.displayName = "Lightbox";
28256
28314
  }
28257
28315
  });
28316
+ function useMediaQuery(query) {
28317
+ const subscribe = React84.useCallback(
28318
+ (onChange) => {
28319
+ const mql = window.matchMedia(query);
28320
+ mql.addEventListener("change", onChange);
28321
+ return () => mql.removeEventListener("change", onChange);
28322
+ },
28323
+ [query]
28324
+ );
28325
+ return React84.useSyncExternalStore(
28326
+ subscribe,
28327
+ () => window.matchMedia(query).matches,
28328
+ () => false
28329
+ );
28330
+ }
28331
+ var init_useMediaQuery = __esm({
28332
+ "hooks/useMediaQuery.ts"() {
28333
+ "use client";
28334
+ }
28335
+ });
28258
28336
  function renderIconInput3(icon, props) {
28259
28337
  return typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, ...props });
28260
28338
  }
@@ -28361,6 +28439,7 @@ function TableView({
28361
28439
  const hasMore = pageSize > 0 && visibleCount < ordered.length;
28362
28440
  const hasRenderProp = typeof children === "function";
28363
28441
  const idField = dndItemIdField ?? "id";
28442
+ const isCoarsePointer = useMediaQuery("(pointer: coarse)");
28364
28443
  const selected = selectedIds ? new Set(selectedIds) : localSelected;
28365
28444
  const emitSelection = (next) => {
28366
28445
  if (!selectedIds) setLocalSelected(next);
@@ -28393,6 +28472,17 @@ function TableView({
28393
28472
  };
28394
28473
  eventBus.emit(`UI:${action.event}`, payload);
28395
28474
  };
28475
+ const colFloors = React84__namespace.default.useMemo(
28476
+ () => colDefs.map((col) => {
28477
+ const longest = data.reduce((widest, row) => {
28478
+ const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
28479
+ return Math.max(widest, cell.length);
28480
+ }, columnLabel(col).length);
28481
+ const chrome = col.format === "badge" ? BADGE_CHROME_CH : 0;
28482
+ return Math.min(longest + chrome, MAX_MEASURED_COL_CH);
28483
+ }),
28484
+ [colDefs, data]
28485
+ );
28396
28486
  if (isLoading) {
28397
28487
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") }) });
28398
28488
  }
@@ -28405,19 +28495,10 @@ function TableView({
28405
28495
  }
28406
28496
  const lk = LOOKS[look];
28407
28497
  const hasActions = Boolean(itemActions && itemActions.length > 0);
28408
- const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
28409
- const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
28498
+ const effectiveMaxInline = isCoarsePointer ? 0 : maxInlineActions;
28499
+ const inlineActionCount = hasActions ? effectiveMaxInline != null ? Math.min(itemActions.length, effectiveMaxInline) : itemActions.length : 0;
28500
+ const hasOverflowActions = hasActions && effectiveMaxInline != null && itemActions.length > effectiveMaxInline;
28410
28501
  const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
28411
- const colFloors = React84__namespace.default.useMemo(
28412
- () => colDefs.map((col) => {
28413
- const longest = data.reduce((widest, row) => {
28414
- const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
28415
- return Math.max(widest, cell.length);
28416
- }, columnLabel(col).length);
28417
- return Math.min(longest, MAX_MEASURED_COL_CH);
28418
- }),
28419
- [colDefs, data]
28420
- );
28421
28502
  const gridTemplateColumns = [
28422
28503
  selectable ? "auto" : null,
28423
28504
  ...colDefs.map((c, i) => c.width ?? `minmax(${colFloors[i]}ch, 1fr)`),
@@ -28504,9 +28585,9 @@ function TableView({
28504
28585
  col.className
28505
28586
  );
28506
28587
  if (col.format === "badge" && raw != null && raw !== "") {
28507
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
28588
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", className: "whitespace-nowrap", children: String(raw) }) }, col.key);
28508
28589
  }
28509
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
28590
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format) }) }, col.key);
28510
28591
  }),
28511
28592
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
28512
28593
  HStack,
@@ -28520,15 +28601,15 @@ function TableView({
28520
28601
  lk.striped && index % 2 === 1 ? "bg-[var(--color-surface-subtle)]" : "bg-[var(--color-card)] group-hover:bg-[var(--color-surface-subtle)]"
28521
28602
  ),
28522
28603
  children: [
28523
- (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
28604
+ (effectiveMaxInline != null ? itemActions.slice(0, effectiveMaxInline) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
28524
28605
  Button,
28525
28606
  {
28526
- variant: action.variant ?? "ghost",
28607
+ variant: action.variant === "primary" ? "primary" : "ghost",
28527
28608
  size: "sm",
28528
28609
  onClick: handleActionClick(action, row),
28529
28610
  "data-testid": `action-${action.event}`,
28530
28611
  "data-row-id": String(row.id),
28531
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
28612
+ className: cn(action.variant === "danger" && "text-error hover:text-error hover:bg-error/10"),
28532
28613
  children: [
28533
28614
  action.icon && renderIconInput3(action.icon, { size: "xs", className: "mr-1" }),
28534
28615
  action.label
@@ -28536,12 +28617,12 @@ function TableView({
28536
28617
  },
28537
28618
  i
28538
28619
  )),
28539
- maxInlineActions != null && itemActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
28620
+ effectiveMaxInline != null && itemActions.length > effectiveMaxInline && /* @__PURE__ */ jsxRuntime.jsx(
28540
28621
  Menu,
28541
28622
  {
28542
28623
  position: "bottom-end",
28543
28624
  trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
28544
- items: itemActions.slice(maxInlineActions).map((action) => ({
28625
+ items: itemActions.slice(effectiveMaxInline).map((action) => ({
28545
28626
  label: action.label,
28546
28627
  icon: action.icon,
28547
28628
  event: action.event,
@@ -28587,13 +28668,14 @@ function TableView({
28587
28668
  }
28588
28669
  );
28589
28670
  }
28590
- var MAX_MEASURED_COL_CH, alignClass, weightClass, LOOKS;
28671
+ var MAX_MEASURED_COL_CH, BADGE_CHROME_CH, alignClass, weightClass, LOOKS;
28591
28672
  var init_TableView = __esm({
28592
28673
  "components/core/molecules/TableView.tsx"() {
28593
28674
  "use client";
28594
28675
  init_cn();
28595
28676
  init_getNestedValue();
28596
28677
  init_useEventBus();
28678
+ init_useMediaQuery();
28597
28679
  init_Box();
28598
28680
  init_Stack();
28599
28681
  init_Typography();
@@ -28606,6 +28688,7 @@ var init_TableView = __esm({
28606
28688
  init_useDataDnd();
28607
28689
  logger.createLogger("almadar:ui:table-view");
28608
28690
  MAX_MEASURED_COL_CH = 32;
28691
+ BADGE_CHROME_CH = 4;
28609
28692
  alignClass = {
28610
28693
  left: "justify-start text-left",
28611
28694
  center: "justify-center text-center",
@@ -28617,7 +28700,7 @@ var init_TableView = __esm({
28617
28700
  semibold: "font-semibold"
28618
28701
  };
28619
28702
  LOOKS = {
28620
- dense: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true },
28703
+ dense: { rowPad: "px-card-md py-2", headPad: "px-card-md py-2", striped: false, divider: true },
28621
28704
  spacious: { rowPad: "px-card-lg py-card-md", headPad: "px-card-lg py-card-sm", striped: false, divider: true },
28622
28705
  striped: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: true, divider: false },
28623
28706
  borderless: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: false },
@@ -30841,7 +30924,7 @@ var init_VoteStack = __esm({
30841
30924
  "active:bg-muted",
30842
30925
  "transition-colors duration-instant",
30843
30926
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30844
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30927
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
30845
30928
  styles.button
30846
30929
  ),
30847
30930
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-up", className: styles.icon })
@@ -30878,7 +30961,7 @@ var init_VoteStack = __esm({
30878
30961
  "active:bg-muted",
30879
30962
  "transition-colors duration-instant",
30880
30963
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30881
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30964
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
30882
30965
  styles.button
30883
30966
  ),
30884
30967
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", className: styles.icon })
@@ -31399,7 +31482,7 @@ var init_QrScanner = __esm({
31399
31482
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31400
31483
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
31401
31484
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31402
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
31485
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
31403
31486
  ),
31404
31487
  "aria-label": isPaused ? t("qrScanner.resumeScanning") : t("qrScanner.pauseScanning"),
31405
31488
  children: isPaused ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "play", className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "pause", className: "h-4 w-4" })
@@ -31414,7 +31497,7 @@ var init_QrScanner = __esm({
31414
31497
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31415
31498
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
31416
31499
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31417
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
31500
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
31418
31501
  ),
31419
31502
  "aria-label": currentFacing === "environment" ? t("qrScanner.switchToFrontCamera") : t("qrScanner.switchToRearCamera"),
31420
31503
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "refresh-cw", className: "h-4 w-4" })
@@ -31429,7 +31512,7 @@ var init_QrScanner = __esm({
31429
31512
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31430
31513
  "rounded-full bg-black bg-opacity-60 px-3 py-2 text-xs text-white",
31431
31514
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31432
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
31515
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
31433
31516
  ),
31434
31517
  "aria-label": t("aria.mockScanDev"),
31435
31518
  children: t("qrScanner.mockScan")
@@ -39674,27 +39757,24 @@ var init_MasterDetailLayout = __esm({
39674
39757
  masterClassName,
39675
39758
  detailClassName
39676
39759
  }) => {
39677
- masterWidth.endsWith("%") ? parseInt(masterWidth, 10) : 30;
39678
39760
  return /* @__PURE__ */ jsxRuntime.jsxs(
39679
39761
  "div",
39680
39762
  {
39681
- className: cn("flex h-full w-full", className),
39682
- style: {
39683
- display: "grid",
39684
- gridTemplateColumns: masterWidth.endsWith("%") ? `${masterWidth} 1fr` : `${masterWidth} 1fr`
39685
- },
39763
+ className: cn("w-full h-full md:grid md:grid-cols-[var(--master-detail-cols)]", className),
39764
+ style: { "--master-detail-cols": `${masterWidth} 1fr` },
39686
39765
  children: [
39687
39766
  /* @__PURE__ */ jsxRuntime.jsx(
39688
39767
  "div",
39689
39768
  {
39690
39769
  className: cn(
39691
- "border-r-2 border-border overflow-auto",
39770
+ "border-r border-border overflow-auto",
39771
+ hasSelection && "hidden md:block",
39692
39772
  masterClassName
39693
39773
  ),
39694
39774
  children: master
39695
39775
  }
39696
39776
  ),
39697
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("overflow-auto", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsxRuntime.jsx(DefaultEmptyDetail, {}) })
39777
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("overflow-auto", !hasSelection && "hidden md:block", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsxRuntime.jsx(DefaultEmptyDetail, {}) })
39698
39778
  ]
39699
39779
  }
39700
39780
  );
@@ -43247,7 +43327,7 @@ var init_TabbedContainer = __esm({
43247
43327
  onClick: () => !isDisabled && handleTabChange(tab.id),
43248
43328
  className: cn(
43249
43329
  "flex items-center gap-2 px-4 py-3 text-sm font-medium transition-colors",
43250
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
43330
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
43251
43331
  "disabled:opacity-50 disabled:cursor-not-allowed",
43252
43332
  isActive ? "bg-primary text-primary-foreground" : "bg-card text-foreground hover:bg-muted",
43253
43333
  isVertical ? "justify-start" : "justify-center"