@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.
@@ -1099,7 +1099,7 @@ var init_Button = __esm({
1099
1099
  "cursor-pointer",
1100
1100
  "chrome-button",
1101
1101
  "transition-all duration-normal",
1102
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-offset-[length:var(--focus-ring-offset)]",
1102
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--focus-ring-offset)]",
1103
1103
  "disabled:opacity-50 disabled:cursor-not-allowed",
1104
1104
  variantStyles[variant],
1105
1105
  sizeStyles[size],
@@ -1820,6 +1820,8 @@ var init_Badge = __esm({
1820
1820
  };
1821
1821
  const iconPx = size === "lg" ? 20 : 16;
1822
1822
  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;
1823
+ const hasText = Boolean(children) || amount != null || label !== void 0 && label !== null && label !== "";
1824
+ if (!hasText && !resolvedIcon && !onRemove) return null;
1823
1825
  return /* @__PURE__ */ jsxs(
1824
1826
  "span",
1825
1827
  {
@@ -1846,7 +1848,7 @@ var init_Badge = __esm({
1846
1848
  },
1847
1849
  className: cn(
1848
1850
  "inline-flex items-center justify-center rounded-sm",
1849
- "hover:bg-foreground/10 focus:outline-none focus:ring-1 focus:ring-ring",
1851
+ "hover:bg-foreground/10 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
1850
1852
  "transition-colors",
1851
1853
  size === "sm" ? "w-4 h-4 ml-0.5" : size === "md" ? "w-5 h-5 ml-1" : "w-6 h-6 ml-1"
1852
1854
  ),
@@ -3204,7 +3206,7 @@ function NativeSelect({
3204
3206
  "block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
3205
3207
  "px-3 py-2 pr-10 text-sm text-foreground font-medium",
3206
3208
  "bg-card",
3207
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
3209
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
3208
3210
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
3209
3211
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
3210
3212
  className
@@ -3311,7 +3313,7 @@ function RichSelect({
3311
3313
  "block w-full border-[length:var(--border-width)] shadow-sm",
3312
3314
  "px-3 py-2 pr-10 text-sm text-start font-medium",
3313
3315
  "bg-card rounded-sm",
3314
- "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
3316
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-ring",
3315
3317
  "disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
3316
3318
  error ? "border-error focus:border-error" : "border-border focus:border-primary",
3317
3319
  !hasValue && "text-muted-foreground"
@@ -4234,9 +4236,9 @@ var init_Radio = __esm({
4234
4236
  "flex items-center justify-center",
4235
4237
  "border-[length:var(--border-width)] transition-all cursor-pointer",
4236
4238
  sizeClasses4[size],
4237
- hasError ? "border-error peer-focus:ring-error/20" : "border-border peer-focus:ring-ring/20",
4239
+ hasError ? "border-error peer-focus-visible:ring-error/20" : "border-border peer-focus-visible:ring-ring/20",
4238
4240
  isChecked2 ? hasError ? "border-error" : "border-primary bg-primary" : "",
4239
- "peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-offset-2",
4241
+ "peer-focus:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2",
4240
4242
  disabled && "opacity-50 cursor-not-allowed",
4241
4243
  !disabled && "hover:border-[var(--color-border-hover)]"
4242
4244
  ),
@@ -4707,7 +4709,7 @@ var init_ThemeToggle = __esm({
4707
4709
  "inline-flex items-center justify-center gap-2",
4708
4710
  "text-foreground",
4709
4711
  "hover:bg-muted border-[length:var(--border-width)] border-transparent hover:border-border",
4710
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
4712
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4711
4713
  "transition-colors duration-fast",
4712
4714
  sizeClasses5[size],
4713
4715
  className
@@ -5142,11 +5144,13 @@ var init_TrendIndicator = __esm({
5142
5144
  size = "md",
5143
5145
  ...props
5144
5146
  }, ref) => {
5145
- const dir = resolveDirection(value, direction);
5147
+ const hasValue = typeof value === "number" && Number.isFinite(value);
5148
+ if (!hasValue && !direction) return null;
5149
+ const dir = resolveDirection(hasValue ? value : void 0, direction);
5146
5150
  const colorClass = resolveColor(dir, invert);
5147
5151
  const iconName = iconNameMap[dir];
5148
5152
  const styles = sizeStyles6[size];
5149
- const formattedValue = value !== void 0 ? `${value > 0 ? "+" : ""}${value}%` : void 0;
5153
+ const formattedValue = hasValue ? `${value > 0 ? "+" : ""}${value}%` : void 0;
5150
5154
  const ariaLabel = label ?? (formattedValue ? `${dir} ${formattedValue}` : dir);
5151
5155
  return /* @__PURE__ */ jsxs(
5152
5156
  "span",
@@ -11745,10 +11749,12 @@ var init_Container = __esm({
11745
11749
  };
11746
11750
  paddingStyles3 = {
11747
11751
  none: "px-0",
11748
- sm: "px-4",
11749
- md: "px-6",
11750
- lg: "px-8",
11751
- xl: "px-12"
11752
+ // Mobile-tighter, desktop-identical: fixed px-6 on a 360px phone eats ~13% of
11753
+ // the viewport, so each token steps down below the sm breakpoint.
11754
+ sm: "px-3 sm:px-4",
11755
+ md: "px-4 sm:px-6",
11756
+ lg: "px-4 sm:px-6 md:px-8",
11757
+ xl: "px-4 sm:px-8 md:px-12"
11752
11758
  };
11753
11759
  Container = ({
11754
11760
  size,
@@ -12447,7 +12453,7 @@ var init_Accordion = __esm({
12447
12453
  "bg-card",
12448
12454
  "hover:bg-muted",
12449
12455
  "transition-colors duration-fast",
12450
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-inset",
12456
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
12451
12457
  "disabled:opacity-50 disabled:cursor-not-allowed",
12452
12458
  isOpen && "bg-muted font-bold"
12453
12459
  ),
@@ -18044,26 +18050,19 @@ var init_BookViewer = __esm({
18044
18050
  function BoxPattern({
18045
18051
  p,
18046
18052
  m,
18047
- bg = "transparent",
18048
- border = false,
18049
- radius = "none",
18050
- shadow = "none",
18051
- className,
18052
- style,
18053
- children
18053
+ radius,
18054
+ isLoading: _isLoading,
18055
+ error: _error,
18056
+ entity: _entity,
18057
+ ...boxProps
18054
18058
  }) {
18055
18059
  return /* @__PURE__ */ jsx(
18056
18060
  Box,
18057
18061
  {
18058
- padding: p,
18059
- margin: m,
18060
- bg,
18061
- border,
18062
- rounded: radius,
18063
- shadow,
18064
- className,
18065
- style,
18066
- children
18062
+ padding: boxProps.padding ?? p,
18063
+ margin: boxProps.margin ?? m,
18064
+ rounded: boxProps.rounded ?? radius,
18065
+ ...boxProps
18067
18066
  }
18068
18067
  );
18069
18068
  }
@@ -18652,7 +18651,7 @@ var init_Breadcrumb = __esm({
18652
18651
  },
18653
18652
  className: cn(
18654
18653
  "flex items-center gap-1.5 transition-colors",
18655
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
18654
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
18656
18655
  isLast ? "text-foreground font-bold cursor-default" : "text-muted-foreground hover:text-foreground"
18657
18656
  ),
18658
18657
  "aria-current": isLast ? "page" : void 0,
@@ -21754,17 +21753,19 @@ var init_DashboardLayout = __esm({
21754
21753
  const [sidebarOpen, setSidebarOpen] = useState(false);
21755
21754
  const [userMenuOpen, setUserMenuOpen] = useState(false);
21756
21755
  const layoutRef = useRef(null);
21757
- const [isMobile, setIsMobile] = useState(false);
21756
+ const [layoutWidth, setLayoutWidth] = useState(null);
21758
21757
  useEffect(() => {
21759
21758
  const el = layoutRef.current;
21760
21759
  if (!el || typeof ResizeObserver === "undefined") return;
21761
21760
  const ro = new ResizeObserver((entries) => {
21762
21761
  const w = entries[0]?.contentRect.width ?? el.clientWidth;
21763
- setIsMobile(w < 1024);
21762
+ setLayoutWidth(w);
21764
21763
  });
21765
21764
  ro.observe(el);
21766
21765
  return () => ro.disconnect();
21767
21766
  }, []);
21767
+ const isMobile = layoutWidth !== null && layoutWidth < 768;
21768
+ const isRail = layoutWidth !== null && layoutWidth >= 768 && layoutWidth < 1024;
21768
21769
  useEffect(() => {
21769
21770
  if (!isMobile && sidebarOpen) setSidebarOpen(false);
21770
21771
  }, [isMobile, sidebarOpen]);
@@ -21797,7 +21798,8 @@ var init_DashboardLayout = __esm({
21797
21798
  {
21798
21799
  as: "aside",
21799
21800
  className: cn(
21800
- "z-30 w-64 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
21801
+ "z-30 flex-shrink-0 bg-card dark:bg-card border-r border-border dark:border-border",
21802
+ isRail ? "w-16" : "w-64",
21801
21803
  "flex flex-col"
21802
21804
  ),
21803
21805
  style: isMobile ? {
@@ -21813,10 +21815,10 @@ var init_DashboardLayout = __esm({
21813
21815
  HStack,
21814
21816
  {
21815
21817
  align: "center",
21816
- justify: "between",
21817
- className: "h-16 px-4 border-b border-border dark:border-border",
21818
+ justify: isRail ? "center" : "between",
21819
+ className: cn("h-16 border-b border-border dark:border-border", isRail ? "px-2" : "px-4"),
21818
21820
  children: [
21819
- /* @__PURE__ */ jsxs(Link, { to: "/", className: "flex items-center gap-2", children: [
21821
+ /* @__PURE__ */ jsxs(Link, { to: "/", className: "flex items-center gap-2", title: isRail ? appName : void 0, children: [
21820
21822
  logo || /* @__PURE__ */ jsx(Box, { className: "w-8 h-8 bg-primary rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx(
21821
21823
  Typography,
21822
21824
  {
@@ -21826,7 +21828,7 @@ var init_DashboardLayout = __esm({
21826
21828
  children: appName.charAt(0).toUpperCase()
21827
21829
  }
21828
21830
  ) }),
21829
- /* @__PURE__ */ jsx(
21831
+ !isRail && /* @__PURE__ */ jsx(
21830
21832
  Typography,
21831
21833
  {
21832
21834
  variant: "label",
@@ -21853,12 +21855,13 @@ var init_DashboardLayout = __esm({
21853
21855
  {
21854
21856
  as: "nav",
21855
21857
  gap: "none",
21856
- className: "flex-1 px-3 py-4 space-y-1 overflow-y-auto",
21858
+ className: cn("flex-1 py-4 space-y-1 overflow-y-auto", isRail ? "px-2" : "px-3"),
21857
21859
  children: navItems.map((item) => /* @__PURE__ */ jsx(
21858
21860
  NavLink,
21859
21861
  {
21860
21862
  item,
21861
- currentPath: activePath
21863
+ currentPath: activePath,
21864
+ compact: isRail
21862
21865
  },
21863
21866
  item.href
21864
21867
  ))
@@ -22113,13 +22116,40 @@ var init_DashboardLayout = __esm({
22113
22116
  DashboardLayout.displayName = "DashboardLayout";
22114
22117
  NavLink = ({
22115
22118
  item,
22116
- currentPath
22119
+ currentPath,
22120
+ compact = false
22117
22121
  }) => {
22118
22122
  const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
22119
22123
  const iconClassName = cn(
22120
22124
  "h-5 w-5",
22121
22125
  isActive ? "text-primary-foreground" : "text-muted-foreground"
22122
22126
  );
22127
+ if (compact) {
22128
+ return /* @__PURE__ */ jsx(
22129
+ Link,
22130
+ {
22131
+ to: item.href,
22132
+ title: item.label,
22133
+ "aria-label": item.label,
22134
+ className: cn(
22135
+ "flex items-center justify-center px-2 py-2 rounded-lg transition-colors",
22136
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
22137
+ ),
22138
+ children: /* @__PURE__ */ jsxs(Box, { as: "span", className: "relative inline-flex", children: [
22139
+ 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() }),
22140
+ item.badge && /* @__PURE__ */ jsx(
22141
+ Badge,
22142
+ {
22143
+ variant: isActive ? "primary" : "default",
22144
+ size: "sm",
22145
+ className: "absolute -top-2 -right-2 px-1 py-0 text-[10px] leading-4",
22146
+ children: item.badge
22147
+ }
22148
+ )
22149
+ ] })
22150
+ }
22151
+ );
22152
+ }
22123
22153
  return /* @__PURE__ */ jsxs(
22124
22154
  Link,
22125
22155
  {
@@ -23185,40 +23215,55 @@ function DataGrid({
23185
23215
  {
23186
23216
  "data-entity-row": true,
23187
23217
  "data-entity-id": id,
23188
- className: cn(isSelected && "ring-2 ring-primary rounded-lg"),
23218
+ className: cn("relative group/rowactions", isSelected && "ring-2 ring-primary rounded-lg"),
23189
23219
  children: [
23190
23220
  children(itemData, index),
23191
- 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: [
23192
- (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxs(
23193
- Button,
23194
- {
23195
- variant: action.variant === "primary" ? "primary" : "ghost",
23196
- size: "sm",
23197
- onClick: handleActionClick(action, itemData),
23198
- "data-testid": `action-${action.event}`,
23199
- "data-row-id": String(itemData.id),
23200
- className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
23201
- children: [
23202
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
23203
- action.label
23204
- ]
23205
- },
23206
- idx
23207
- )),
23208
- maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsx(
23221
+ 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: [
23222
+ /* @__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: [
23223
+ (maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : actionDefs).map((action, idx) => /* @__PURE__ */ jsxs(
23224
+ Button,
23225
+ {
23226
+ variant: action.variant === "primary" ? "primary" : "ghost",
23227
+ size: "sm",
23228
+ onClick: handleActionClick(action, itemData),
23229
+ "data-testid": `action-${action.event}`,
23230
+ "data-row-id": String(itemData.id),
23231
+ className: action.variant === "danger" ? "text-error hover:text-error hover:bg-error/10" : void 0,
23232
+ children: [
23233
+ action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
23234
+ action.label
23235
+ ]
23236
+ },
23237
+ idx
23238
+ )),
23239
+ maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsx(
23240
+ Menu,
23241
+ {
23242
+ position: "bottom-end",
23243
+ 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" }) }),
23244
+ items: actionDefs.slice(maxInlineActions).map((action) => ({
23245
+ label: action.label,
23246
+ icon: action.icon,
23247
+ event: action.event,
23248
+ onClick: () => fireAction(action, itemData)
23249
+ }))
23250
+ }
23251
+ )
23252
+ ] }),
23253
+ /* @__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(
23209
23254
  Menu,
23210
23255
  {
23211
23256
  position: "bottom-end",
23212
23257
  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" }) }),
23213
- items: actionDefs.slice(maxInlineActions).map((action) => ({
23258
+ items: actionDefs.map((action) => ({
23214
23259
  label: action.label,
23215
23260
  icon: action.icon,
23216
23261
  event: action.event,
23217
23262
  onClick: () => fireAction(action, itemData)
23218
23263
  }))
23219
23264
  }
23220
- )
23221
- ] }) })
23265
+ ) })
23266
+ ] })
23222
23267
  ]
23223
23268
  },
23224
23269
  id
@@ -23254,7 +23299,7 @@ function DataGrid({
23254
23299
  }
23255
23300
  ) });
23256
23301
  })(),
23257
- /* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
23302
+ /* @__PURE__ */ jsx(Box, { className: cn("p-4", bodyFields.length > 0 && "pb-0"), children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
23258
23303
  selectable && /* @__PURE__ */ jsx(
23259
23304
  "input",
23260
23305
  {
@@ -23287,79 +23332,77 @@ function DataGrid({
23287
23332
  ] }, field.name);
23288
23333
  }) })
23289
23334
  ] }),
23290
- dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxs(
23291
- Button,
23292
- {
23293
- variant: "ghost",
23294
- size: "sm",
23295
- onClick: handleActionClick(action, itemData),
23296
- "data-testid": `action-${action.event}`,
23297
- "data-row-id": String(itemData.id),
23298
- className: "text-error hover:text-error hover:bg-error/10 px-2",
23299
- children: [
23300
- action.icon && renderIconInput(action.icon, { size: "xs" }),
23301
- action.label
23302
- ]
23303
- },
23304
- idx
23305
- )) })
23306
- ] }) }),
23307
- bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
23308
- const value = getNestedValue(itemData, field.name);
23309
- if (value === void 0 || value === null || value === "") return null;
23310
- if (field.format === "boolean") {
23311
- return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
23312
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
23313
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23314
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
23315
- ] }),
23316
- /* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
23317
- ] }, field.name);
23318
- }
23319
- return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
23320
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
23321
- field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23322
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
23323
- ] }),
23324
- /* @__PURE__ */ jsx(
23325
- Typography,
23335
+ (primaryActions.length > 0 || dangerActions.length > 0) && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "flex-shrink-0", children: [
23336
+ (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsx(
23337
+ Button,
23338
+ {
23339
+ variant: action.variant === "primary" ? "primary" : "ghost",
23340
+ size: "sm",
23341
+ onClick: handleActionClick(action, itemData),
23342
+ "data-testid": `action-${action.event}`,
23343
+ "data-row-id": String(itemData.id),
23344
+ "aria-label": action.label,
23345
+ title: action.label,
23346
+ className: cn(
23347
+ action.variant === "primary" ? void 0 : "text-muted-foreground hover:text-foreground",
23348
+ action.icon && "px-2"
23349
+ ),
23350
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
23351
+ },
23352
+ idx
23353
+ )),
23354
+ maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsx(
23355
+ Menu,
23326
23356
  {
23327
- variant: field.variant === "caption" ? "caption" : "small",
23328
- className: "text-right truncate max-w-[60%]",
23329
- children: formatValue(value, field.format)
23357
+ position: "bottom-end",
23358
+ 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" }) }),
23359
+ items: primaryActions.slice(maxInlineActions).map((action) => ({
23360
+ label: action.label,
23361
+ icon: action.icon,
23362
+ event: action.event,
23363
+ onClick: () => fireAction(action, itemData)
23364
+ }))
23330
23365
  }
23331
- )
23332
- ] }, field.name);
23333
- }) }) }),
23334
- 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: [
23335
- (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxs(
23336
- Button,
23337
- {
23338
- variant: action.variant === "primary" ? "primary" : "ghost",
23339
- size: "sm",
23340
- onClick: handleActionClick(action, itemData),
23341
- "data-testid": `action-${action.event}`,
23342
- "data-row-id": String(itemData.id),
23343
- children: [
23344
- action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
23345
- action.label
23346
- ]
23347
- },
23348
- idx
23349
- )),
23350
- maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsx(
23351
- Menu,
23352
- {
23353
- position: "bottom-end",
23354
- 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" }) }),
23355
- items: primaryActions.slice(maxInlineActions).map((action) => ({
23356
- label: action.label,
23357
- icon: action.icon,
23358
- event: action.event,
23359
- onClick: () => fireAction(action, itemData)
23360
- }))
23366
+ ),
23367
+ dangerActions.map((action, idx) => /* @__PURE__ */ jsx(
23368
+ Button,
23369
+ {
23370
+ variant: "ghost",
23371
+ size: "sm",
23372
+ onClick: handleActionClick(action, itemData),
23373
+ "data-testid": `action-${action.event}`,
23374
+ "data-row-id": String(itemData.id),
23375
+ "aria-label": action.label,
23376
+ title: action.label,
23377
+ className: "text-error hover:text-error hover:bg-error/10 px-2",
23378
+ children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
23379
+ },
23380
+ `danger-${idx}`
23381
+ ))
23382
+ ] })
23383
+ ] }) }),
23384
+ bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 pt-2 pb-4 flex-1", children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
23385
+ bodyFields.filter((f3) => f3.variant === "caption" && f3.format !== "boolean").map((field) => {
23386
+ const value = getNestedValue(itemData, field.name);
23387
+ if (value === void 0 || value === null || value === "") return null;
23388
+ return /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: formatValue(value, field.format) }, field.name);
23389
+ }),
23390
+ /* @__PURE__ */ jsx(HStack, { gap: "md", className: "flex-wrap gap-y-1", children: bodyFields.filter((f3) => f3.variant !== "caption" || f3.format === "boolean").map((field) => {
23391
+ const value = getNestedValue(itemData, field.name);
23392
+ if (value === void 0 || value === null || value === "") return null;
23393
+ if (field.format === "boolean") {
23394
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
23395
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23396
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) }),
23397
+ /* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
23398
+ ] }, field.name);
23361
23399
  }
23362
- )
23400
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
23401
+ field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
23402
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
23403
+ /* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
23404
+ ] }, field.name);
23405
+ }) })
23363
23406
  ] }) })
23364
23407
  ]
23365
23408
  },
@@ -23707,11 +23750,29 @@ function DataList({
23707
23750
  const wrapDnd = (node) => dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: dndId, children: node }, dndId) : node;
23708
23751
  if (hasRenderProp) {
23709
23752
  const id2 = itemData.id || String(index);
23753
+ const actions = renderItemActions(itemData);
23710
23754
  return wrapDnd(
23711
- /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn(itemClickEvent && "cursor-pointer"), children: [
23712
- /* @__PURE__ */ jsxs(Box, { className: "group flex items-stretch gap-2", children: [
23713
- /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
23714
- renderItemActions(itemData)
23755
+ /* @__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: [
23756
+ children(itemData, index),
23757
+ 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: [
23758
+ /* @__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 }),
23759
+ /* @__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(
23760
+ Menu,
23761
+ {
23762
+ position: "bottom-end",
23763
+ 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" }) }),
23764
+ items: (itemActions ?? []).map((action) => ({
23765
+ label: action.label,
23766
+ icon: action.icon,
23767
+ event: action.event,
23768
+ variant: action.variant === "danger" ? "danger" : "default",
23769
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
23770
+ id: itemData.id,
23771
+ row: itemData
23772
+ })
23773
+ }))
23774
+ }
23775
+ ) })
23715
23776
  ] }),
23716
23777
  isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
23717
23778
  ] }, id2)
@@ -23751,7 +23812,7 @@ function DataList({
23751
23812
  ] }, field.name);
23752
23813
  })
23753
23814
  ] }),
23754
- bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
23815
+ bodyFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "md", className: cn("flex-wrap", isCompact ? "mt-0.5" : "mt-1.5"), children: bodyFields.map((field) => {
23755
23816
  const value = getNestedValue(itemData, field.name);
23756
23817
  if (value === void 0 || value === null || value === "") return null;
23757
23818
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
@@ -24101,10 +24162,7 @@ var init_FileTree = __esm({
24101
24162
  className,
24102
24163
  indent = 16
24103
24164
  }) => {
24104
- const { t } = useTranslate();
24105
- if (tree.length === 0) {
24106
- return /* @__PURE__ */ jsx(Box, { className: `p-4 ${className ?? ""}`, children: /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: t("fileTree.noFiles") }) });
24107
- }
24165
+ if (tree.length === 0) return null;
24108
24166
  return /* @__PURE__ */ jsx(Box, { className: `py-1 overflow-y-auto ${className ?? ""}`, role: "tree", children: tree.map((node) => /* @__PURE__ */ jsx(
24109
24167
  TreeNodeItem,
24110
24168
  {
@@ -27350,7 +27408,7 @@ var init_MapView = __esm({
27350
27408
  shadowSize: [41, 41]
27351
27409
  });
27352
27410
  L.Marker.prototype.options.icon = defaultIcon;
27353
- const { useEffect: useEffect62, useRef: useRef60, useCallback: useCallback93, useState: useState91 } = React84__default;
27411
+ const { useEffect: useEffect62, useRef: useRef60, useCallback: useCallback94, useState: useState91 } = React84__default;
27354
27412
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
27355
27413
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
27356
27414
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -27396,7 +27454,7 @@ var init_MapView = __esm({
27396
27454
  }) {
27397
27455
  const eventBus = useEventBus2();
27398
27456
  const [clickedPosition, setClickedPosition] = useState91(null);
27399
- const handleMapClick = useCallback93((lat, lng) => {
27457
+ const handleMapClick = useCallback94((lat, lng) => {
27400
27458
  if (showClickedPin) {
27401
27459
  setClickedPosition({ lat, lng });
27402
27460
  }
@@ -27405,7 +27463,7 @@ var init_MapView = __esm({
27405
27463
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
27406
27464
  }
27407
27465
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
27408
- const handleMarkerClick = useCallback93((marker) => {
27466
+ const handleMarkerClick = useCallback94((marker) => {
27409
27467
  onMarkerClick?.(marker);
27410
27468
  if (markerClickEvent) {
27411
27469
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -27607,7 +27665,7 @@ var init_NumberStepper = __esm({
27607
27665
  "active:bg-muted",
27608
27666
  "transition-colors duration-instant",
27609
27667
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27610
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27668
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
27611
27669
  styles.button
27612
27670
  ),
27613
27671
  "aria-label": t("aria.decrease"),
@@ -27648,7 +27706,7 @@ var init_NumberStepper = __esm({
27648
27706
  "active:bg-muted",
27649
27707
  "transition-colors duration-instant",
27650
27708
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27651
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27709
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
27652
27710
  styles.button
27653
27711
  ),
27654
27712
  "aria-label": t("aria.increase"),
@@ -28104,7 +28162,7 @@ var init_Lightbox = __esm({
28104
28162
  "p-2 rounded-full",
28105
28163
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
28106
28164
  "hover:bg-opacity-70 transition-opacity",
28107
- "focus:outline-none focus:ring-2 focus:ring-ring"
28165
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
28108
28166
  ),
28109
28167
  "aria-label": t("aria.closeModal"),
28110
28168
  children: /* @__PURE__ */ jsx(Icon, { name: "x", className: "w-6 h-6" })
@@ -28123,7 +28181,7 @@ var init_Lightbox = __esm({
28123
28181
  "p-2 rounded-full",
28124
28182
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
28125
28183
  "hover:bg-opacity-70 transition-opacity",
28126
- "focus:outline-none focus:ring-2 focus:ring-ring"
28184
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
28127
28185
  ),
28128
28186
  "aria-label": t("aria.previousImage"),
28129
28187
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-left", className: "w-8 h-8" })
@@ -28160,7 +28218,7 @@ var init_Lightbox = __esm({
28160
28218
  "p-2 rounded-full",
28161
28219
  "text-[var(--color-foreground)] bg-[var(--color-card)]",
28162
28220
  "hover:bg-opacity-70 transition-opacity",
28163
- "focus:outline-none focus:ring-2 focus:ring-ring"
28221
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
28164
28222
  ),
28165
28223
  "aria-label": t("aria.nextImage"),
28166
28224
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", className: "w-8 h-8" })
@@ -28181,6 +28239,26 @@ var init_Lightbox = __esm({
28181
28239
  Lightbox.displayName = "Lightbox";
28182
28240
  }
28183
28241
  });
28242
+ function useMediaQuery(query) {
28243
+ const subscribe = useCallback(
28244
+ (onChange) => {
28245
+ const mql = window.matchMedia(query);
28246
+ mql.addEventListener("change", onChange);
28247
+ return () => mql.removeEventListener("change", onChange);
28248
+ },
28249
+ [query]
28250
+ );
28251
+ return useSyncExternalStore(
28252
+ subscribe,
28253
+ () => window.matchMedia(query).matches,
28254
+ () => false
28255
+ );
28256
+ }
28257
+ var init_useMediaQuery = __esm({
28258
+ "hooks/useMediaQuery.ts"() {
28259
+ "use client";
28260
+ }
28261
+ });
28184
28262
  function renderIconInput3(icon, props) {
28185
28263
  return typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsx(Icon, { icon, ...props });
28186
28264
  }
@@ -28287,6 +28365,7 @@ function TableView({
28287
28365
  const hasMore = pageSize > 0 && visibleCount < ordered.length;
28288
28366
  const hasRenderProp = typeof children === "function";
28289
28367
  const idField = dndItemIdField ?? "id";
28368
+ const isCoarsePointer = useMediaQuery("(pointer: coarse)");
28290
28369
  const selected = selectedIds ? new Set(selectedIds) : localSelected;
28291
28370
  const emitSelection = (next) => {
28292
28371
  if (!selectedIds) setLocalSelected(next);
@@ -28319,6 +28398,17 @@ function TableView({
28319
28398
  };
28320
28399
  eventBus.emit(`UI:${action.event}`, payload);
28321
28400
  };
28401
+ const colFloors = React84__default.useMemo(
28402
+ () => colDefs.map((col) => {
28403
+ const longest = data.reduce((widest, row) => {
28404
+ const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
28405
+ return Math.max(widest, cell.length);
28406
+ }, columnLabel(col).length);
28407
+ const chrome = col.format === "badge" ? BADGE_CHROME_CH : 0;
28408
+ return Math.min(longest + chrome, MAX_MEASURED_COL_CH);
28409
+ }),
28410
+ [colDefs, data]
28411
+ );
28322
28412
  if (isLoading) {
28323
28413
  return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") }) });
28324
28414
  }
@@ -28331,19 +28421,10 @@ function TableView({
28331
28421
  }
28332
28422
  const lk = LOOKS[look];
28333
28423
  const hasActions = Boolean(itemActions && itemActions.length > 0);
28334
- const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
28335
- const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
28424
+ const effectiveMaxInline = isCoarsePointer ? 0 : maxInlineActions;
28425
+ const inlineActionCount = hasActions ? effectiveMaxInline != null ? Math.min(itemActions.length, effectiveMaxInline) : itemActions.length : 0;
28426
+ const hasOverflowActions = hasActions && effectiveMaxInline != null && itemActions.length > effectiveMaxInline;
28336
28427
  const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
28337
- const colFloors = React84__default.useMemo(
28338
- () => colDefs.map((col) => {
28339
- const longest = data.reduce((widest, row) => {
28340
- const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
28341
- return Math.max(widest, cell.length);
28342
- }, columnLabel(col).length);
28343
- return Math.min(longest, MAX_MEASURED_COL_CH);
28344
- }),
28345
- [colDefs, data]
28346
- );
28347
28428
  const gridTemplateColumns = [
28348
28429
  selectable ? "auto" : null,
28349
28430
  ...colDefs.map((c, i) => c.width ?? `minmax(${colFloors[i]}ch, 1fr)`),
@@ -28430,9 +28511,9 @@ function TableView({
28430
28511
  col.className
28431
28512
  );
28432
28513
  if (col.format === "badge" && raw != null && raw !== "") {
28433
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
28514
+ 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);
28434
28515
  }
28435
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
28516
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format) }) }, col.key);
28436
28517
  }),
28437
28518
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(
28438
28519
  HStack,
@@ -28446,15 +28527,15 @@ function TableView({
28446
28527
  lk.striped && index % 2 === 1 ? "bg-[var(--color-surface-subtle)]" : "bg-[var(--color-card)] group-hover:bg-[var(--color-surface-subtle)]"
28447
28528
  ),
28448
28529
  children: [
28449
- (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
28530
+ (effectiveMaxInline != null ? itemActions.slice(0, effectiveMaxInline) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
28450
28531
  Button,
28451
28532
  {
28452
- variant: action.variant ?? "ghost",
28533
+ variant: action.variant === "primary" ? "primary" : "ghost",
28453
28534
  size: "sm",
28454
28535
  onClick: handleActionClick(action, row),
28455
28536
  "data-testid": `action-${action.event}`,
28456
28537
  "data-row-id": String(row.id),
28457
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
28538
+ className: cn(action.variant === "danger" && "text-error hover:text-error hover:bg-error/10"),
28458
28539
  children: [
28459
28540
  action.icon && renderIconInput3(action.icon, { size: "xs", className: "mr-1" }),
28460
28541
  action.label
@@ -28462,12 +28543,12 @@ function TableView({
28462
28543
  },
28463
28544
  i
28464
28545
  )),
28465
- maxInlineActions != null && itemActions.length > maxInlineActions && /* @__PURE__ */ jsx(
28546
+ effectiveMaxInline != null && itemActions.length > effectiveMaxInline && /* @__PURE__ */ jsx(
28466
28547
  Menu,
28467
28548
  {
28468
28549
  position: "bottom-end",
28469
28550
  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" }) }),
28470
- items: itemActions.slice(maxInlineActions).map((action) => ({
28551
+ items: itemActions.slice(effectiveMaxInline).map((action) => ({
28471
28552
  label: action.label,
28472
28553
  icon: action.icon,
28473
28554
  event: action.event,
@@ -28513,13 +28594,14 @@ function TableView({
28513
28594
  }
28514
28595
  );
28515
28596
  }
28516
- var MAX_MEASURED_COL_CH, alignClass, weightClass, LOOKS;
28597
+ var MAX_MEASURED_COL_CH, BADGE_CHROME_CH, alignClass, weightClass, LOOKS;
28517
28598
  var init_TableView = __esm({
28518
28599
  "components/core/molecules/TableView.tsx"() {
28519
28600
  "use client";
28520
28601
  init_cn();
28521
28602
  init_getNestedValue();
28522
28603
  init_useEventBus();
28604
+ init_useMediaQuery();
28523
28605
  init_Box();
28524
28606
  init_Stack();
28525
28607
  init_Typography();
@@ -28532,6 +28614,7 @@ var init_TableView = __esm({
28532
28614
  init_useDataDnd();
28533
28615
  createLogger("almadar:ui:table-view");
28534
28616
  MAX_MEASURED_COL_CH = 32;
28617
+ BADGE_CHROME_CH = 4;
28535
28618
  alignClass = {
28536
28619
  left: "justify-start text-left",
28537
28620
  center: "justify-center text-center",
@@ -28543,7 +28626,7 @@ var init_TableView = __esm({
28543
28626
  semibold: "font-semibold"
28544
28627
  };
28545
28628
  LOOKS = {
28546
- dense: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true },
28629
+ dense: { rowPad: "px-card-md py-2", headPad: "px-card-md py-2", striped: false, divider: true },
28547
28630
  spacious: { rowPad: "px-card-lg py-card-md", headPad: "px-card-lg py-card-sm", striped: false, divider: true },
28548
28631
  striped: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: true, divider: false },
28549
28632
  borderless: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: false },
@@ -30767,7 +30850,7 @@ var init_VoteStack = __esm({
30767
30850
  "active:bg-muted",
30768
30851
  "transition-colors duration-instant",
30769
30852
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30770
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30853
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
30771
30854
  styles.button
30772
30855
  ),
30773
30856
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-up", className: styles.icon })
@@ -30804,7 +30887,7 @@ var init_VoteStack = __esm({
30804
30887
  "active:bg-muted",
30805
30888
  "transition-colors duration-instant",
30806
30889
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30807
- "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30890
+ "focus:outline-none focus-visible:ring-[length:var(--focus-ring-width)] focus-visible:ring-ring focus-visible:ring-inset",
30808
30891
  styles.button
30809
30892
  ),
30810
30893
  children: /* @__PURE__ */ jsx(Icon, { name: "chevron-down", className: styles.icon })
@@ -31325,7 +31408,7 @@ var init_QrScanner = __esm({
31325
31408
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31326
31409
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
31327
31410
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31328
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
31411
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
31329
31412
  ),
31330
31413
  "aria-label": isPaused ? t("qrScanner.resumeScanning") : t("qrScanner.pauseScanning"),
31331
31414
  children: isPaused ? /* @__PURE__ */ jsx(Icon, { name: "play", className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Icon, { name: "pause", className: "h-4 w-4" })
@@ -31340,7 +31423,7 @@ var init_QrScanner = __esm({
31340
31423
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31341
31424
  "rounded-full bg-black bg-opacity-60 p-2 text-white",
31342
31425
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31343
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
31426
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
31344
31427
  ),
31345
31428
  "aria-label": currentFacing === "environment" ? t("qrScanner.switchToFrontCamera") : t("qrScanner.switchToRearCamera"),
31346
31429
  children: /* @__PURE__ */ jsx(Icon, { name: "refresh-cw", className: "h-4 w-4" })
@@ -31355,7 +31438,7 @@ var init_QrScanner = __esm({
31355
31438
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31356
31439
  "rounded-full bg-black bg-opacity-60 px-3 py-2 text-xs text-white",
31357
31440
  // eslint-disable-next-line almadar/no-hardcoded-colors -- media overlay: always over a dark scrim
31358
- "hover:bg-opacity-80 focus:outline-none focus:ring-2 focus:ring-white"
31441
+ "hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
31359
31442
  ),
31360
31443
  "aria-label": t("aria.mockScanDev"),
31361
31444
  children: t("qrScanner.mockScan")
@@ -39600,27 +39683,24 @@ var init_MasterDetailLayout = __esm({
39600
39683
  masterClassName,
39601
39684
  detailClassName
39602
39685
  }) => {
39603
- masterWidth.endsWith("%") ? parseInt(masterWidth, 10) : 30;
39604
39686
  return /* @__PURE__ */ jsxs(
39605
39687
  "div",
39606
39688
  {
39607
- className: cn("flex h-full w-full", className),
39608
- style: {
39609
- display: "grid",
39610
- gridTemplateColumns: masterWidth.endsWith("%") ? `${masterWidth} 1fr` : `${masterWidth} 1fr`
39611
- },
39689
+ className: cn("w-full h-full md:grid md:grid-cols-[var(--master-detail-cols)]", className),
39690
+ style: { "--master-detail-cols": `${masterWidth} 1fr` },
39612
39691
  children: [
39613
39692
  /* @__PURE__ */ jsx(
39614
39693
  "div",
39615
39694
  {
39616
39695
  className: cn(
39617
- "border-r-2 border-border overflow-auto",
39696
+ "border-r border-border overflow-auto",
39697
+ hasSelection && "hidden md:block",
39618
39698
  masterClassName
39619
39699
  ),
39620
39700
  children: master
39621
39701
  }
39622
39702
  ),
39623
- /* @__PURE__ */ jsx("div", { className: cn("overflow-auto", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsx(DefaultEmptyDetail, {}) })
39703
+ /* @__PURE__ */ jsx("div", { className: cn("overflow-auto", !hasSelection && "hidden md:block", detailClassName), children: hasSelection ? detail : emptyDetail || /* @__PURE__ */ jsx(DefaultEmptyDetail, {}) })
39624
39704
  ]
39625
39705
  }
39626
39706
  );
@@ -43173,7 +43253,7 @@ var init_TabbedContainer = __esm({
43173
43253
  onClick: () => !isDisabled && handleTabChange(tab.id),
43174
43254
  className: cn(
43175
43255
  "flex items-center gap-2 px-4 py-3 text-sm font-medium transition-colors",
43176
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
43256
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
43177
43257
  "disabled:opacity-50 disabled:cursor-not-allowed",
43178
43258
  isActive ? "bg-primary text-primary-foreground" : "bg-card text-foreground hover:bg-muted",
43179
43259
  isVertical ? "justify-start" : "justify-center"