@almadar/ui 5.80.0 → 5.82.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.
@@ -1988,6 +1988,7 @@ var init_Button = __esm({
1988
1988
  rightIcon,
1989
1989
  icon: iconProp,
1990
1990
  iconRight: iconRightProp,
1991
+ iconAsset,
1991
1992
  action,
1992
1993
  actionPayload,
1993
1994
  label,
@@ -1999,7 +2000,8 @@ var init_Button = __esm({
1999
2000
  const eventBus = useEventBus();
2000
2001
  const leftIconValue = leftIcon || iconProp;
2001
2002
  const rightIconValue = rightIcon || iconRightProp;
2002
- const resolvedLeftIcon = resolveIconProp(leftIconValue, iconSizeStyles[size]);
2003
+ const px = size === "sm" ? 16 : size === "lg" ? 20 : 16;
2004
+ const resolvedLeftIcon = iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: iconAsset.name ?? iconAsset.category ?? "", width: px, height: px, style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px }, className: "flex-shrink-0" }) : resolveIconProp(leftIconValue, iconSizeStyles[size]);
2003
2005
  const resolvedRightIcon = resolveIconProp(rightIconValue, iconSizeStyles[size]);
2004
2006
  const handleClick = (e) => {
2005
2007
  if (action) {
@@ -2657,13 +2659,14 @@ var init_Badge = __esm({
2657
2659
  lg: "px-3 py-1.5 text-base"
2658
2660
  };
2659
2661
  Badge = React103__default.forwardRef(
2660
- ({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
2662
+ ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
2661
2663
  const iconSizes3 = {
2662
2664
  sm: "h-icon-default w-icon-default",
2663
2665
  md: "h-icon-default w-icon-default",
2664
2666
  lg: "h-icon-default w-icon-default"
2665
2667
  };
2666
- const resolvedIcon = typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsx(Icon, { icon, className: iconSizes3[size] }) : null;
2668
+ const iconPx = size === "lg" ? 20 : 16;
2669
+ const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: iconAsset.name ?? iconAsset.category ?? "", width: iconPx, height: iconPx, style: { imageRendering: "pixelated", objectFit: "contain", width: iconPx, height: iconPx }, className: "flex-shrink-0" }) : typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsx(Icon, { icon, className: iconSizes3[size] }) : null;
2667
2670
  return /* @__PURE__ */ jsxs(
2668
2671
  "span",
2669
2672
  {
@@ -8883,10 +8886,43 @@ var init_shared = __esm({
8883
8886
  init_canvasEffects();
8884
8887
  }
8885
8888
  });
8889
+ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
8890
+ const px = typeof size === "number" ? size : sizeMap[size];
8891
+ if (assetUrl?.url) {
8892
+ return /* @__PURE__ */ jsx(
8893
+ "img",
8894
+ {
8895
+ src: assetUrl.url,
8896
+ alt: alt ?? assetUrl.category ?? "",
8897
+ width: px,
8898
+ height: px,
8899
+ style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
8900
+ className: cn("flex-shrink-0", className)
8901
+ }
8902
+ );
8903
+ }
8904
+ const I = typeof icon === "string" ? resolveIcon(icon) : icon;
8905
+ return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
8906
+ }
8907
+ var sizeMap;
8908
+ var init_GameIcon = __esm({
8909
+ "components/game/2d/atoms/GameIcon.tsx"() {
8910
+ "use client";
8911
+ init_cn();
8912
+ init_Icon();
8913
+ sizeMap = {
8914
+ sm: 16,
8915
+ md: 24,
8916
+ lg: 32
8917
+ };
8918
+ GameIcon.displayName = "GameIcon";
8919
+ }
8920
+ });
8886
8921
  function GameCard({
8887
8922
  id,
8888
8923
  cost,
8889
8924
  art,
8925
+ frameAsset,
8890
8926
  attack,
8891
8927
  defense,
8892
8928
  name,
@@ -8904,16 +8940,19 @@ function GameCard({
8904
8940
  if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { cardId: id });
8905
8941
  }, [disabled, id, onClick, clickEvent, eventBus]);
8906
8942
  const artPx = artPxMap[size];
8943
+ const frameStyle = frameAsset?.url ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%", backgroundRepeat: "no-repeat" } : {};
8907
8944
  return /* @__PURE__ */ jsxs(
8908
- "button",
8945
+ Button,
8909
8946
  {
8910
- type: "button",
8947
+ variant: "ghost",
8911
8948
  onClick: handleClick,
8912
8949
  disabled,
8913
8950
  title: name,
8951
+ style: frameStyle,
8914
8952
  className: cn(
8915
- "relative flex flex-col items-center rounded-interactive border-2",
8953
+ "relative flex flex-col items-center rounded-interactive",
8916
8954
  "bg-card/90 px-1.5 pt-1.5 pb-1 transition-all duration-150",
8955
+ frameAsset?.url ? "border-0" : "border-2",
8917
8956
  cardSizeMap[size],
8918
8957
  disabled ? "border-border opacity-50 cursor-not-allowed" : "border-accent hover:brightness-125 hover:-translate-y-1 cursor-pointer",
8919
8958
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background -translate-y-1",
@@ -8921,8 +8960,9 @@ function GameCard({
8921
8960
  ),
8922
8961
  children: [
8923
8962
  cost != null && /* @__PURE__ */ jsx(
8924
- "span",
8963
+ Typography,
8925
8964
  {
8965
+ as: "span",
8926
8966
  className: cn(
8927
8967
  "absolute -top-2 -left-2 flex items-center justify-center",
8928
8968
  "min-w-[22px] h-[22px] rounded-full px-1",
@@ -8931,17 +8971,7 @@ function GameCard({
8931
8971
  children: cost
8932
8972
  }
8933
8973
  ),
8934
- /* @__PURE__ */ jsx(Box, { className: "flex-1 flex items-center justify-center w-full", children: art ? /* @__PURE__ */ jsx(
8935
- "img",
8936
- {
8937
- src: art.url,
8938
- alt: name ?? id,
8939
- width: artPx,
8940
- height: artPx,
8941
- style: { imageRendering: "pixelated", objectFit: "contain" },
8942
- className: "flex-shrink-0"
8943
- }
8944
- ) : /* @__PURE__ */ jsx(Box, { className: "rounded bg-muted/40", style: { width: artPx, height: artPx } }) }),
8974
+ /* @__PURE__ */ jsx(Box, { className: "flex-1 flex items-center justify-center w-full", children: art ? /* @__PURE__ */ jsx(GameIcon, { assetUrl: art, icon: "image", size: artPx, alt: name ?? id, className: "flex-shrink-0" }) : /* @__PURE__ */ jsx(Box, { className: "rounded bg-muted/40", style: { width: artPx, height: artPx } }) }),
8945
8975
  name != null && /* @__PURE__ */ jsx(
8946
8976
  Typography,
8947
8977
  {
@@ -8951,8 +8981,8 @@ function GameCard({
8951
8981
  }
8952
8982
  ),
8953
8983
  (attack != null || defense != null) && /* @__PURE__ */ jsxs(Box, { className: "flex w-full items-center justify-between px-0.5 text-[10px] font-bold leading-none", children: [
8954
- /* @__PURE__ */ jsx("span", { className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
8955
- /* @__PURE__ */ jsx("span", { className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
8984
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
8985
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
8956
8986
  ] })
8957
8987
  ]
8958
8988
  }
@@ -8965,7 +8995,9 @@ var init_GameCard = __esm({
8965
8995
  init_cn();
8966
8996
  init_useEventBus();
8967
8997
  init_Box();
8998
+ init_Button();
8968
8999
  init_Typography();
9000
+ init_GameIcon();
8969
9001
  cardSizeMap = {
8970
9002
  sm: "w-16 h-24",
8971
9003
  md: "w-20 h-28",
@@ -8988,12 +9020,13 @@ function HealthBar({
8988
9020
  frameAsset,
8989
9021
  fillAsset
8990
9022
  }) {
8991
- const sizes = sizeMap[size];
9023
+ const sizes = sizeMap2[size];
8992
9024
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
8993
9025
  if (format === "hearts") {
8994
- return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
8995
- "span",
9026
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
9027
+ Box,
8996
9028
  {
9029
+ as: "span",
8997
9030
  className: cn(animated && "transition-transform hover:scale-110"),
8998
9031
  children: heartIcon(i < current, sizes.heart)
8999
9032
  },
@@ -9002,10 +9035,12 @@ function HealthBar({
9002
9035
  }
9003
9036
  if (format === "bar") {
9004
9037
  return /* @__PURE__ */ jsx(
9005
- "div",
9038
+ Box,
9006
9039
  {
9040
+ position: "relative",
9041
+ overflow: "hidden",
9007
9042
  className: cn(
9008
- "relative overflow-hidden rounded-full",
9043
+ "rounded-full",
9009
9044
  !frameAsset && "bg-muted",
9010
9045
  sizes.bar,
9011
9046
  "w-24",
@@ -9013,10 +9048,11 @@ function HealthBar({
9013
9048
  ),
9014
9049
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
9015
9050
  children: /* @__PURE__ */ jsx(
9016
- "div",
9051
+ Box,
9017
9052
  {
9053
+ position: "absolute",
9018
9054
  className: cn(
9019
- "absolute inset-y-0 left-0 rounded-full",
9055
+ "inset-y-0 left-0 rounded-full",
9020
9056
  !fillAsset && (percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error"),
9021
9057
  animated && "transition-all duration-300"
9022
9058
  ),
@@ -9030,10 +9066,11 @@ function HealthBar({
9030
9066
  );
9031
9067
  }
9032
9068
  if (format === "progress") {
9033
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
9069
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex items-center gap-2", className), children: [
9034
9070
  level != null && /* @__PURE__ */ jsxs(
9035
- "span",
9071
+ Typography,
9036
9072
  {
9073
+ as: "span",
9037
9074
  className: cn(
9038
9075
  "flex-shrink-0 rounded-interactive font-bold",
9039
9076
  "bg-accent text-accent-foreground border border-accent",
@@ -9045,21 +9082,23 @@ function HealthBar({
9045
9082
  ]
9046
9083
  }
9047
9084
  ),
9048
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [
9085
+ /* @__PURE__ */ jsxs(Box, { className: "flex-1 flex flex-col gap-0.5", children: [
9049
9086
  /* @__PURE__ */ jsx(
9050
- "div",
9087
+ Box,
9051
9088
  {
9089
+ position: "relative",
9052
9090
  className: cn(
9053
- "relative w-full overflow-hidden rounded-full",
9091
+ "w-full overflow-hidden rounded-full",
9054
9092
  !frameAsset && "bg-muted border border-muted",
9055
9093
  sizes.bar
9056
9094
  ),
9057
9095
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
9058
9096
  children: /* @__PURE__ */ jsx(
9059
- "div",
9097
+ Box,
9060
9098
  {
9099
+ position: "absolute",
9061
9100
  className: cn(
9062
- "absolute inset-y-0 left-0 rounded-full",
9101
+ "inset-y-0 left-0 rounded-full",
9063
9102
  !fillAsset && "bg-gradient-to-r from-accent to-info",
9064
9103
  animated && "transition-all duration-500 ease-out"
9065
9104
  ),
@@ -9071,7 +9110,7 @@ function HealthBar({
9071
9110
  )
9072
9111
  }
9073
9112
  ),
9074
- showLabel && /* @__PURE__ */ jsxs("span", { className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
9113
+ showLabel && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
9075
9114
  current,
9076
9115
  " / ",
9077
9116
  max,
@@ -9080,16 +9119,18 @@ function HealthBar({
9080
9119
  ] })
9081
9120
  ] });
9082
9121
  }
9083
- return /* @__PURE__ */ jsxs("span", { className: cn("font-mono font-bold", sizes.text, className), children: [
9122
+ return /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-mono font-bold", sizes.text, className), children: [
9084
9123
  current,
9085
9124
  "/",
9086
9125
  max
9087
9126
  ] });
9088
9127
  }
9089
- var heartIcon, sizeMap;
9128
+ var heartIcon, sizeMap2;
9090
9129
  var init_HealthBar = __esm({
9091
9130
  "components/game/2d/atoms/HealthBar.tsx"() {
9092
9131
  init_cn();
9132
+ init_Box();
9133
+ init_Typography();
9093
9134
  heartIcon = (filled, size) => /* @__PURE__ */ jsx(
9094
9135
  "svg",
9095
9136
  {
@@ -9101,7 +9142,7 @@ var init_HealthBar = __esm({
9101
9142
  children: /* @__PURE__ */ jsx("path", { d: "M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" })
9102
9143
  }
9103
9144
  );
9104
- sizeMap = {
9145
+ sizeMap2 = {
9105
9146
  sm: { heart: "w-4 h-4", bar: "h-2", text: "text-sm", label: "text-xs", badge: "text-xs px-1.5 py-0.5" },
9106
9147
  md: { heart: "w-6 h-6", bar: "h-3", text: "text-base", label: "text-xs", badge: "text-xs px-2 py-0.5" },
9107
9148
  lg: { heart: "w-8 h-8", bar: "h-4", text: "text-lg", label: "text-sm", badge: "text-sm px-2.5 py-1" }
@@ -9122,37 +9163,30 @@ function ScoreDisplay({
9122
9163
  const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
9123
9164
  const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
9124
9165
  return /* @__PURE__ */ jsxs(
9125
- "div",
9166
+ Box,
9126
9167
  {
9127
9168
  className: cn(
9128
9169
  "flex items-center gap-2 font-bold",
9129
- sizeMap2[size],
9170
+ sizeMap3[size],
9130
9171
  className
9131
9172
  ),
9132
9173
  children: [
9133
- assetUrl ? /* @__PURE__ */ jsx(
9134
- "img",
9135
- {
9136
- src: assetUrl.url,
9137
- alt: "",
9138
- width: 20,
9139
- height: 20,
9140
- style: { imageRendering: "pixelated", objectFit: "contain" },
9141
- className: "flex-shrink-0"
9142
- }
9143
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9144
- label && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
9145
- /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formattedValue })
9174
+ assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 20, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsx(Box, { as: "span", className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9175
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
9176
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "tabular-nums", children: formattedValue })
9146
9177
  ]
9147
9178
  }
9148
9179
  );
9149
9180
  }
9150
- var sizeMap2, DEFAULT_ASSET_URL;
9181
+ var sizeMap3, DEFAULT_ASSET_URL;
9151
9182
  var init_ScoreDisplay = __esm({
9152
9183
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
9153
9184
  init_cn();
9154
9185
  init_Icon();
9155
- sizeMap2 = {
9186
+ init_Box();
9187
+ init_Typography();
9188
+ init_GameIcon();
9189
+ sizeMap3 = {
9156
9190
  sm: "text-sm",
9157
9191
  md: "text-lg",
9158
9192
  lg: "text-2xl",
@@ -9215,9 +9249,9 @@ function ControlButton({
9215
9249
  [isPressed, releaseEvent, eventBus, onRelease]
9216
9250
  );
9217
9251
  return /* @__PURE__ */ jsx(
9218
- "button",
9252
+ Button,
9219
9253
  {
9220
- type: "button",
9254
+ variant,
9221
9255
  disabled,
9222
9256
  onPointerDown: handlePointerDown,
9223
9257
  onPointerUp: handlePointerUp,
@@ -9228,41 +9262,35 @@ function ControlButton({
9228
9262
  "select-none touch-none",
9229
9263
  "transition-all duration-100",
9230
9264
  "active:scale-95",
9231
- sizeMap3[size] ?? sizeMap3.md,
9265
+ sizeMap4[size] ?? sizeMap4.md,
9232
9266
  shapeMap[shape] ?? shapeMap.circle,
9233
9267
  variantMap[variant] ?? variantMap.secondary,
9234
9268
  actualPressed && "scale-95 brightness-110 border-foreground",
9235
9269
  disabled && "opacity-50 cursor-not-allowed",
9236
9270
  className
9237
9271
  ),
9238
- children: assetUrl ? /* @__PURE__ */ jsx(
9239
- "img",
9240
- {
9241
- src: assetUrl.url,
9242
- alt: "",
9243
- width: 24,
9244
- height: 24,
9245
- style: { imageRendering: "pixelated", objectFit: "contain" },
9246
- className: "flex-shrink-0"
9247
- }
9248
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
9272
+ children: assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsx(Box, { as: "span", className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
9249
9273
  const I = resolveIcon(icon);
9250
9274
  return I ? /* @__PURE__ */ jsx(I, { className: "w-6 h-6" }) : null;
9251
9275
  })() : icon : /* @__PURE__ */ (() => {
9252
9276
  const I = icon;
9253
9277
  return /* @__PURE__ */ jsx(I, { className: "w-6 h-6" });
9254
- })() }) : label ? /* @__PURE__ */ jsx("span", { children: label }) : null
9278
+ })() }) : label ? /* @__PURE__ */ jsx(Typography, { as: "span", children: label }) : null
9255
9279
  }
9256
9280
  );
9257
9281
  }
9258
- var sizeMap3, shapeMap, variantMap, DEFAULT_ASSET_URL2;
9282
+ var sizeMap4, shapeMap, variantMap, DEFAULT_ASSET_URL2;
9259
9283
  var init_ControlButton = __esm({
9260
9284
  "components/game/2d/atoms/ControlButton.tsx"() {
9261
9285
  "use client";
9262
9286
  init_cn();
9263
9287
  init_useEventBus();
9264
9288
  init_Icon();
9265
- sizeMap3 = {
9289
+ init_Button();
9290
+ init_Box();
9291
+ init_Typography();
9292
+ init_GameIcon();
9293
+ sizeMap4 = {
9266
9294
  sm: "w-10 h-10 text-sm",
9267
9295
  md: "w-14 h-14 text-base",
9268
9296
  lg: "w-18 h-18 text-lg",
@@ -9332,12 +9360,12 @@ function Sprite({
9332
9360
  onClick?.();
9333
9361
  };
9334
9362
  return /* @__PURE__ */ jsx(
9335
- "div",
9363
+ Box,
9336
9364
  {
9365
+ position: "absolute",
9337
9366
  className,
9338
9367
  onClick: action || onClick ? handleClick : void 0,
9339
9368
  style: {
9340
- position: "absolute",
9341
9369
  width: frameWidth,
9342
9370
  height: frameHeight,
9343
9371
  backgroundImage: `url(${spritesheet.url})`,
@@ -9358,6 +9386,7 @@ var init_Sprite = __esm({
9358
9386
  "components/game/2d/atoms/Sprite.tsx"() {
9359
9387
  "use client";
9360
9388
  init_useEventBus();
9389
+ init_Box();
9361
9390
  init_spriteAnimation();
9362
9391
  DEFAULT_SPRITESHEET = {
9363
9392
  url: "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
@@ -9394,17 +9423,7 @@ function StateIndicator({
9394
9423
  className
9395
9424
  ),
9396
9425
  children: [
9397
- /* @__PURE__ */ jsx(Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsx(
9398
- "img",
9399
- {
9400
- src: assetUrl.url,
9401
- alt: displayLabel,
9402
- width: 16,
9403
- height: 16,
9404
- style: { imageRendering: "pixelated", objectFit: "contain" },
9405
- className: "flex-shrink-0"
9406
- }
9407
- ) : typeof config.icon === "string" ? /^[a-zA-Z0-9-]+$/.test(config.icon) ? /* @__PURE__ */ jsx(Icon, { name: config.icon }) : config.icon : /* @__PURE__ */ jsx(Icon, { icon: config.icon }) }),
9426
+ /* @__PURE__ */ jsx(Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 16, alt: displayLabel, className: "flex-shrink-0" }) : typeof config.icon === "string" ? /^[a-zA-Z0-9-]+$/.test(config.icon) ? /* @__PURE__ */ jsx(Icon, { name: config.icon }) : config.icon : /* @__PURE__ */ jsx(Icon, { icon: config.icon }) }),
9408
9427
  /* @__PURE__ */ jsx(Box, { as: "span", children: displayLabel })
9409
9428
  ]
9410
9429
  }
@@ -9416,6 +9435,7 @@ var init_StateIndicator = __esm({
9416
9435
  init_Box();
9417
9436
  init_Icon();
9418
9437
  init_cn();
9438
+ init_GameIcon();
9419
9439
  DEFAULT_ASSET_URL3 = {
9420
9440
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
9421
9441
  role: "ui",
@@ -9469,29 +9489,31 @@ function TimerDisplay({
9469
9489
  }) {
9470
9490
  const isLow = lowThreshold != null && seconds <= lowThreshold && seconds > 0;
9471
9491
  return /* @__PURE__ */ jsxs(
9472
- "div",
9492
+ Box,
9473
9493
  {
9474
9494
  className: cn(
9475
9495
  "inline-flex items-center gap-1 justify-center rounded-container",
9476
9496
  "bg-card/80 border border-muted font-mono font-bold tabular-nums",
9477
- sizeMap4[size],
9497
+ sizeMap5[size],
9478
9498
  running && "border-success/50",
9479
9499
  isLow && "text-error border-error/50 animate-pulse",
9480
9500
  !isLow && "text-foreground",
9481
9501
  className
9482
9502
  ),
9483
9503
  children: [
9484
- iconAsset && /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: "", className: "w-4 h-4 object-contain flex-shrink-0" }),
9504
+ iconAsset && /* @__PURE__ */ jsx(GameIcon, { assetUrl: iconAsset, icon: "image", size: 16, className: "w-4 h-4 object-contain flex-shrink-0" }),
9485
9505
  formatTime(seconds, format)
9486
9506
  ]
9487
9507
  }
9488
9508
  );
9489
9509
  }
9490
- var sizeMap4;
9510
+ var sizeMap5;
9491
9511
  var init_TimerDisplay = __esm({
9492
9512
  "components/game/2d/atoms/TimerDisplay.tsx"() {
9493
9513
  init_cn();
9494
- sizeMap4 = {
9514
+ init_Box();
9515
+ init_GameIcon();
9516
+ sizeMap5 = {
9495
9517
  sm: "text-sm px-2 py-0.5",
9496
9518
  md: "text-lg px-3 py-1",
9497
9519
  lg: "text-2xl px-4 py-1.5"
@@ -9509,9 +9531,9 @@ function ResourceCounter({
9509
9531
  size = "md",
9510
9532
  className
9511
9533
  }) {
9512
- const sizes = sizeMap5[size];
9534
+ const sizes = sizeMap6[size];
9513
9535
  return /* @__PURE__ */ jsxs(
9514
- "div",
9536
+ Box,
9515
9537
  {
9516
9538
  className: cn(
9517
9539
  "inline-flex items-center rounded-container",
@@ -9520,21 +9542,11 @@ function ResourceCounter({
9520
9542
  className
9521
9543
  ),
9522
9544
  children: [
9523
- assetUrl ? /* @__PURE__ */ jsx(
9524
- "img",
9525
- {
9526
- src: assetUrl.url,
9527
- alt: label,
9528
- width: sizes.img,
9529
- height: sizes.img,
9530
- style: { imageRendering: "pixelated", objectFit: "contain" },
9531
- className: "flex-shrink-0"
9532
- }
9533
- ) : icon ? /* @__PURE__ */ jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9534
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
9535
- /* @__PURE__ */ jsxs("span", { className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
9545
+ assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: sizes.img, alt: label, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsx(Box, { as: "span", className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9546
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
9547
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
9536
9548
  value,
9537
- max != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9549
+ max != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
9538
9550
  "/",
9539
9551
  max
9540
9552
  ] })
@@ -9543,11 +9555,14 @@ function ResourceCounter({
9543
9555
  }
9544
9556
  );
9545
9557
  }
9546
- var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap5;
9558
+ var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap6;
9547
9559
  var init_ResourceCounter = __esm({
9548
9560
  "components/game/2d/atoms/ResourceCounter.tsx"() {
9549
9561
  init_cn();
9550
9562
  init_Icon();
9563
+ init_Box();
9564
+ init_Typography();
9565
+ init_GameIcon();
9551
9566
  colorTokenClasses2 = {
9552
9567
  primary: "text-primary",
9553
9568
  secondary: "text-secondary",
@@ -9561,7 +9576,7 @@ var init_ResourceCounter = __esm({
9561
9576
  role: "ui",
9562
9577
  category: "coin"
9563
9578
  };
9564
- sizeMap5 = {
9579
+ sizeMap6 = {
9565
9580
  sm: { wrapper: "text-xs gap-1 px-1.5 py-0.5", icon: "text-sm", img: 16 },
9566
9581
  md: { wrapper: "text-sm gap-1.5 px-2 py-1", icon: "text-base", img: 20 },
9567
9582
  lg: { wrapper: "text-base gap-2 px-3 py-1.5", icon: "text-lg", img: 28 }
@@ -9586,9 +9601,9 @@ function ItemSlot({
9586
9601
  const isClickable = onClick != null || action != null;
9587
9602
  const px = assetSizeMap[size];
9588
9603
  return /* @__PURE__ */ jsx(
9589
- "button",
9604
+ Button,
9590
9605
  {
9591
- type: "button",
9606
+ variant: "ghost",
9592
9607
  onClick: () => {
9593
9608
  if (action) eventBus.emit(`UI:${action}`, {});
9594
9609
  onClick?.();
@@ -9598,7 +9613,7 @@ function ItemSlot({
9598
9613
  className: cn(
9599
9614
  "relative flex items-center justify-center rounded-interactive border-2",
9600
9615
  "bg-card/80 transition-all duration-150",
9601
- sizeMap6[size],
9616
+ sizeMap7[size],
9602
9617
  empty ? "border-border bg-card/50" : rarityBorderMap[rarity],
9603
9618
  !empty && rarityGlowMap[rarity],
9604
9619
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background",
@@ -9607,21 +9622,12 @@ function ItemSlot({
9607
9622
  !isClickable && "cursor-default",
9608
9623
  className
9609
9624
  ),
9610
- children: empty ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9611
- assetUrl ? /* @__PURE__ */ jsx(
9612
- "img",
9613
- {
9614
- src: assetUrl?.url,
9615
- alt: label,
9616
- width: px,
9617
- height: px,
9618
- style: { imageRendering: "pixelated", objectFit: "contain" },
9619
- className: "flex-shrink-0"
9620
- }
9621
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9625
+ children: empty ? /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9626
+ assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: px, alt: label, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsx(Box, { as: "span", className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9622
9627
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
9623
- "span",
9628
+ Typography,
9624
9629
  {
9630
+ as: "span",
9625
9631
  className: cn(
9626
9632
  "absolute -bottom-1 -right-1 flex items-center justify-center",
9627
9633
  "min-w-[18px] h-[18px] rounded-full px-1",
@@ -9634,14 +9640,18 @@ function ItemSlot({
9634
9640
  }
9635
9641
  );
9636
9642
  }
9637
- var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9643
+ var sizeMap7, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9638
9644
  var init_ItemSlot = __esm({
9639
9645
  "components/game/2d/atoms/ItemSlot.tsx"() {
9640
9646
  "use client";
9641
9647
  init_cn();
9642
9648
  init_Icon();
9643
9649
  init_useEventBus();
9644
- sizeMap6 = {
9650
+ init_Button();
9651
+ init_Box();
9652
+ init_Typography();
9653
+ init_GameIcon();
9654
+ sizeMap7 = {
9645
9655
  sm: "w-10 h-10 text-lg",
9646
9656
  md: "w-14 h-14 text-2xl",
9647
9657
  lg: "w-18 h-18 text-3xl"
@@ -9682,9 +9692,9 @@ function TurnIndicator({
9682
9692
  size = "md",
9683
9693
  className
9684
9694
  }) {
9685
- const sizes = sizeMap7[size];
9695
+ const sizes = sizeMap8[size];
9686
9696
  return /* @__PURE__ */ jsxs(
9687
- "div",
9697
+ Box,
9688
9698
  {
9689
9699
  className: cn(
9690
9700
  "inline-flex items-center rounded-container",
@@ -9693,42 +9703,35 @@ function TurnIndicator({
9693
9703
  className
9694
9704
  ),
9695
9705
  children: [
9696
- /* @__PURE__ */ jsxs("span", { className: "font-bold tabular-nums", children: [
9706
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: "font-bold tabular-nums", children: [
9697
9707
  "Turn ",
9698
9708
  currentTurn,
9699
- maxTurns != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9709
+ maxTurns != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
9700
9710
  "/",
9701
9711
  maxTurns
9702
9712
  ] })
9703
9713
  ] }),
9704
9714
  phase && /* @__PURE__ */ jsxs(Fragment, { children: [
9705
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
9706
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: phase })
9715
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9716
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: phase })
9707
9717
  ] }),
9708
9718
  activeTeam && /* @__PURE__ */ jsxs(Fragment, { children: [
9709
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
9710
- assetUrl ? /* @__PURE__ */ jsx(
9711
- "img",
9712
- {
9713
- src: assetUrl.url,
9714
- alt: "",
9715
- width: 12,
9716
- height: 12,
9717
- style: { imageRendering: "pixelated", objectFit: "contain" },
9718
- className: "flex-shrink-0"
9719
- }
9720
- ) : /* @__PURE__ */ jsx("span", { className: cn("rounded-full bg-success/20", sizes.dot) }),
9721
- /* @__PURE__ */ jsx("span", { className: "text-success", children: activeTeam })
9719
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9720
+ assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 12, className: "flex-shrink-0" }) : /* @__PURE__ */ jsx(Box, { as: "span", className: cn("rounded-full bg-success/20", sizes.dot) }),
9721
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-success", children: activeTeam })
9722
9722
  ] })
9723
9723
  ]
9724
9724
  }
9725
9725
  );
9726
9726
  }
9727
- var sizeMap7, DEFAULT_ASSET_URL6;
9727
+ var sizeMap8, DEFAULT_ASSET_URL6;
9728
9728
  var init_TurnIndicator = __esm({
9729
9729
  "components/game/2d/atoms/TurnIndicator.tsx"() {
9730
9730
  init_cn();
9731
- sizeMap7 = {
9731
+ init_Box();
9732
+ init_Typography();
9733
+ init_GameIcon();
9734
+ sizeMap8 = {
9732
9735
  sm: { wrapper: "text-xs gap-1.5 px-2 py-0.5", dot: "w-1.5 h-1.5" },
9733
9736
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
9734
9737
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
@@ -9760,10 +9763,10 @@ function ComboCounter({
9760
9763
  size = "md",
9761
9764
  className
9762
9765
  }) {
9763
- const sizes = sizeMap8[size];
9766
+ const sizes = sizeMap9[size];
9764
9767
  if (combo <= 0) return null;
9765
9768
  return /* @__PURE__ */ jsxs(
9766
- "div",
9769
+ Box,
9767
9770
  {
9768
9771
  className: cn(
9769
9772
  "inline-flex flex-col items-center justify-center",
@@ -9773,24 +9776,14 @@ function ComboCounter({
9773
9776
  className
9774
9777
  ),
9775
9778
  children: [
9776
- assetUrl && /* @__PURE__ */ jsx(
9777
- "img",
9778
- {
9779
- src: assetUrl.url,
9780
- alt: "combo",
9781
- width: 24,
9782
- height: 24,
9783
- style: { imageRendering: "pixelated", objectFit: "contain" },
9784
- className: "flex-shrink-0 mb-0.5"
9785
- }
9786
- ),
9787
- /* @__PURE__ */ jsx("span", { className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
9788
- /* @__PURE__ */ jsx("span", { className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
9789
- multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs("span", { className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
9779
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0 mb-0.5" }),
9780
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
9781
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
9782
+ multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
9790
9783
  "x",
9791
9784
  multiplier.toFixed(1)
9792
9785
  ] }),
9793
- streak != null && streak > 0 && /* @__PURE__ */ jsxs("span", { className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9786
+ streak != null && streak > 0 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9794
9787
  streak,
9795
9788
  " streak"
9796
9789
  ] })
@@ -9798,16 +9791,19 @@ function ComboCounter({
9798
9791
  }
9799
9792
  );
9800
9793
  }
9801
- var DEFAULT_ASSET_URL7, sizeMap8;
9794
+ var DEFAULT_ASSET_URL7, sizeMap9;
9802
9795
  var init_ComboCounter = __esm({
9803
9796
  "components/game/2d/atoms/ComboCounter.tsx"() {
9804
9797
  init_cn();
9798
+ init_Box();
9799
+ init_Typography();
9800
+ init_GameIcon();
9805
9801
  DEFAULT_ASSET_URL7 = {
9806
9802
  url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
9807
9803
  role: "effect",
9808
9804
  category: "effect"
9809
9805
  };
9810
- sizeMap8 = {
9806
+ sizeMap9 = {
9811
9807
  sm: { combo: "text-lg", label: "text-xs", multiplier: "text-xs" },
9812
9808
  md: { combo: "text-2xl", label: "text-xs", multiplier: "text-sm" },
9813
9809
  lg: { combo: "text-4xl", label: "text-sm", multiplier: "text-base" }
@@ -9824,54 +9820,48 @@ function WaypointMarker({
9824
9820
  size = "md",
9825
9821
  className
9826
9822
  }) {
9827
- const sizes = sizeMap9[size];
9828
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center", className), children: [
9829
- /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
9823
+ const sizes = sizeMap10[size];
9824
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col items-center", className), children: [
9825
+ /* @__PURE__ */ jsxs(Box, { className: "relative flex items-center justify-center", children: [
9830
9826
  active && /* @__PURE__ */ jsx(
9831
- "div",
9827
+ Box,
9832
9828
  {
9829
+ position: "absolute",
9833
9830
  className: cn(
9834
- "absolute rounded-full border-2 border-info animate-ping opacity-50",
9831
+ "rounded-full border-2 border-info animate-ping opacity-50",
9835
9832
  sizes.ring
9836
9833
  )
9837
9834
  }
9838
9835
  ),
9839
9836
  active && /* @__PURE__ */ jsx(
9840
- "div",
9837
+ Box,
9841
9838
  {
9839
+ position: "absolute",
9842
9840
  className: cn(
9843
- "absolute rounded-full border-2 border-info",
9841
+ "rounded-full border-2 border-info",
9844
9842
  sizes.ring
9845
9843
  )
9846
9844
  }
9847
9845
  ),
9848
9846
  /* @__PURE__ */ jsx(
9849
- "div",
9847
+ Box,
9850
9848
  {
9849
+ position: "relative",
9851
9850
  className: cn(
9852
- "relative flex items-center justify-center rounded-full transition-all duration-200",
9851
+ "flex items-center justify-center rounded-full transition-all duration-200",
9853
9852
  sizes.dot,
9854
9853
  completed && "bg-success text-foreground",
9855
9854
  active && !completed && "bg-info text-foreground",
9856
9855
  !active && !completed && "bg-muted"
9857
9856
  ),
9858
- children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsx(
9859
- "img",
9860
- {
9861
- src: assetUrl.url,
9862
- alt: label,
9863
- width: sizes.img,
9864
- height: sizes.img,
9865
- style: { imageRendering: "pixelated", objectFit: "contain" },
9866
- className: "flex-shrink-0"
9867
- }
9868
- ) : icon ? typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) : null
9857
+ children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: sizes.img, alt: label, className: "flex-shrink-0" }) : icon ? typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) : null
9869
9858
  }
9870
9859
  )
9871
9860
  ] }),
9872
9861
  label && /* @__PURE__ */ jsx(
9873
- "span",
9862
+ Typography,
9874
9863
  {
9864
+ as: "span",
9875
9865
  className: cn(
9876
9866
  "text-center whitespace-nowrap",
9877
9867
  sizes.label,
@@ -9882,17 +9872,20 @@ function WaypointMarker({
9882
9872
  )
9883
9873
  ] });
9884
9874
  }
9885
- var DEFAULT_ASSET_URL8, sizeMap9, checkIcon;
9875
+ var DEFAULT_ASSET_URL8, sizeMap10, checkIcon;
9886
9876
  var init_WaypointMarker = __esm({
9887
9877
  "components/game/2d/atoms/WaypointMarker.tsx"() {
9888
9878
  init_cn();
9889
9879
  init_Icon();
9880
+ init_Box();
9881
+ init_Typography();
9882
+ init_GameIcon();
9890
9883
  DEFAULT_ASSET_URL8 = {
9891
9884
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
9892
9885
  role: "ui",
9893
9886
  category: "waypoint"
9894
9887
  };
9895
- sizeMap9 = {
9888
+ sizeMap10 = {
9896
9889
  sm: { dot: "w-4 h-4", ring: "w-6 h-6", label: "text-xs mt-1", img: 12 },
9897
9890
  md: { dot: "w-6 h-6", ring: "w-8 h-8", label: "text-sm mt-1.5", img: 18 },
9898
9891
  lg: { dot: "w-8 h-8", ring: "w-10 h-10", label: "text-base mt-2", img: 24 }
@@ -9917,32 +9910,24 @@ function StatusEffect({
9917
9910
  size = "md",
9918
9911
  className
9919
9912
  }) {
9920
- const sizes = sizeMap10[size];
9921
- return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex flex-col items-center", className), children: [
9913
+ const sizes = sizeMap11[size];
9914
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn("inline-flex flex-col items-center", className), children: [
9922
9915
  /* @__PURE__ */ jsxs(
9923
- "div",
9916
+ Box,
9924
9917
  {
9918
+ position: "relative",
9925
9919
  className: cn(
9926
- "relative flex items-center justify-center rounded-interactive border-2",
9920
+ "flex items-center justify-center rounded-interactive border-2",
9927
9921
  sizes.container,
9928
9922
  variantStyles7[variant]
9929
9923
  ),
9930
9924
  title: label,
9931
9925
  children: [
9932
- /* @__PURE__ */ jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsx(
9933
- "img",
9934
- {
9935
- src: assetUrl.url,
9936
- alt: label,
9937
- width: sizes.img,
9938
- height: sizes.img,
9939
- style: { imageRendering: "pixelated", objectFit: "contain" },
9940
- className: "flex-shrink-0"
9941
- }
9942
- ) : icon != null && typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsx(Icon, { icon, size: "sm" }) : null }),
9926
+ /* @__PURE__ */ jsx(Box, { as: "span", className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: sizes.img, alt: label, className: "flex-shrink-0" }) : icon != null && typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsx(Icon, { icon, size: "sm" }) : null }),
9943
9927
  duration !== void 0 && /* @__PURE__ */ jsx(
9944
- "span",
9928
+ Typography,
9945
9929
  {
9930
+ as: "span",
9946
9931
  className: cn(
9947
9932
  "absolute bottom-0 left-0 right-0 text-center font-mono font-bold text-foreground bg-background/60 leading-tight",
9948
9933
  sizes.timer
@@ -9954,8 +9939,9 @@ function StatusEffect({
9954
9939
  }
9955
9940
  ),
9956
9941
  stacks !== void 0 && stacks > 1 && /* @__PURE__ */ jsx(
9957
- "span",
9942
+ Typography,
9958
9943
  {
9944
+ as: "span",
9959
9945
  className: cn(
9960
9946
  "absolute flex items-center justify-center rounded-full bg-card text-foreground font-bold leading-none",
9961
9947
  sizes.badge
@@ -9963,20 +9949,23 @@ function StatusEffect({
9963
9949
  children: stacks
9964
9950
  }
9965
9951
  ),
9966
- label && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9952
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9967
9953
  ] });
9968
9954
  }
9969
- var DEFAULT_ASSET_URL9, sizeMap10, variantStyles7;
9955
+ var DEFAULT_ASSET_URL9, sizeMap11, variantStyles7;
9970
9956
  var init_StatusEffect = __esm({
9971
9957
  "components/game/2d/atoms/StatusEffect.tsx"() {
9972
9958
  init_cn();
9973
9959
  init_Icon();
9960
+ init_Box();
9961
+ init_Typography();
9962
+ init_GameIcon();
9974
9963
  DEFAULT_ASSET_URL9 = {
9975
9964
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
9976
9965
  role: "ui",
9977
9966
  category: "effect"
9978
9967
  };
9979
- sizeMap10 = {
9968
+ sizeMap11 = {
9980
9969
  sm: { container: "w-8 h-8", icon: "text-sm", badge: "text-xs -top-1 -right-1 w-4 h-4", timer: "text-[9px]", img: 20 },
9981
9970
  md: { container: "w-10 h-10", icon: "text-base", badge: "text-xs -top-1 -right-1 w-5 h-5", timer: "text-xs", img: 28 },
9982
9971
  lg: { container: "w-12 h-12", icon: "text-lg", badge: "text-sm -top-1.5 -right-1.5 w-6 h-6", timer: "text-xs", img: 36 }
@@ -10000,38 +9989,31 @@ function DamageNumber({
10000
9989
  return /* @__PURE__ */ jsxs(Fragment, { children: [
10001
9990
  /* @__PURE__ */ jsx("style", { children: floatKeyframes }),
10002
9991
  /* @__PURE__ */ jsxs(
10003
- "span",
9992
+ Typography,
10004
9993
  {
9994
+ as: "span",
10005
9995
  className: cn(
10006
9996
  "inline-flex items-center gap-0.5 font-mono select-none pointer-events-none",
10007
- sizeMap11[size],
9997
+ sizeMap12[size],
10008
9998
  typeStyles[type],
10009
9999
  className
10010
10000
  ),
10011
10001
  style: { animation: "damageFloat 1s ease-out forwards" },
10012
10002
  children: [
10013
- assetUrl && /* @__PURE__ */ jsx(
10014
- "img",
10015
- {
10016
- src: assetUrl.url,
10017
- alt: "",
10018
- width: 14,
10019
- height: 14,
10020
- style: { imageRendering: "pixelated", objectFit: "contain" },
10021
- className: "flex-shrink-0"
10022
- }
10023
- ),
10003
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 14, className: "flex-shrink-0" }),
10024
10004
  displayText
10025
10005
  ]
10026
10006
  }
10027
10007
  )
10028
10008
  ] });
10029
10009
  }
10030
- var sizeMap11, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
10010
+ var sizeMap12, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
10031
10011
  var init_DamageNumber = __esm({
10032
10012
  "components/game/2d/atoms/DamageNumber.tsx"() {
10033
10013
  init_cn();
10034
- sizeMap11 = {
10014
+ init_Typography();
10015
+ init_GameIcon();
10016
+ sizeMap12 = {
10035
10017
  sm: "text-sm",
10036
10018
  md: "text-lg",
10037
10019
  lg: "text-2xl"
@@ -10065,7 +10047,7 @@ function DialogueBubble({
10065
10047
  className
10066
10048
  }) {
10067
10049
  return /* @__PURE__ */ jsxs(
10068
- "div",
10050
+ Box,
10069
10051
  {
10070
10052
  className: cn(
10071
10053
  "flex items-start gap-3 rounded-container bg-background/80 backdrop-blur-sm px-4 py-3 border border-border/10",
@@ -10073,17 +10055,10 @@ function DialogueBubble({
10073
10055
  className
10074
10056
  ),
10075
10057
  children: [
10076
- portrait && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 w-12 h-12 rounded-full overflow-hidden border-2 border-warning/60", children: /* @__PURE__ */ jsx(
10077
- "img",
10078
- {
10079
- src: portrait?.url,
10080
- alt: speaker ?? "speaker",
10081
- className: "w-full h-full object-cover"
10082
- }
10083
- ) }),
10084
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
10085
- speaker && /* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-warning", children: speaker }),
10086
- /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground leading-relaxed", children: text })
10058
+ portrait && /* @__PURE__ */ jsx(Box, { className: "flex-shrink-0 w-12 h-12 rounded-full overflow-hidden border-2 border-warning/60", children: /* @__PURE__ */ jsx(GameIcon, { assetUrl: portrait, icon: "image", size: 48, alt: speaker ?? "speaker", className: "w-full h-full object-cover" }) }),
10059
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-1 min-w-0", children: [
10060
+ speaker && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm font-bold text-warning", children: speaker }),
10061
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm text-foreground leading-relaxed", children: text })
10087
10062
  ] })
10088
10063
  ]
10089
10064
  }
@@ -10093,6 +10068,9 @@ var DEFAULT_PORTRAIT;
10093
10068
  var init_DialogueBubble = __esm({
10094
10069
  "components/game/2d/atoms/DialogueBubble.tsx"() {
10095
10070
  init_cn();
10071
+ init_Box();
10072
+ init_Typography();
10073
+ init_GameIcon();
10096
10074
  DEFAULT_PORTRAIT = {
10097
10075
  url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
10098
10076
  role: "effect",
@@ -10114,11 +10092,11 @@ function ChoiceButton({
10114
10092
  }) {
10115
10093
  const eventBus = useEventBus();
10116
10094
  return /* @__PURE__ */ jsxs(
10117
- "button",
10095
+ Button,
10118
10096
  {
10119
- type: "button",
10097
+ variant: "ghost",
10120
10098
  disabled,
10121
- onClick: (e) => {
10099
+ onClick: () => {
10122
10100
  if (action) eventBus.emit(`UI:${action}`, {});
10123
10101
  onClick?.();
10124
10102
  },
@@ -10131,8 +10109,9 @@ function ChoiceButton({
10131
10109
  ),
10132
10110
  children: [
10133
10111
  index !== void 0 && /* @__PURE__ */ jsxs(
10134
- "span",
10112
+ Typography,
10135
10113
  {
10114
+ as: "span",
10136
10115
  className: cn(
10137
10116
  "flex-shrink-0 font-mono font-bold text-sm",
10138
10117
  selected ? "text-accent" : "text-muted-foreground"
@@ -10143,24 +10122,14 @@ function ChoiceButton({
10143
10122
  ]
10144
10123
  }
10145
10124
  ),
10146
- assetUrl ? /* @__PURE__ */ jsx(
10147
- "img",
10148
- {
10149
- src: assetUrl.url,
10150
- alt: "",
10151
- width: 16,
10152
- height: 16,
10153
- style: { imageRendering: "pixelated", objectFit: "contain" },
10154
- className: "flex-shrink-0"
10155
- }
10156
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
10125
+ assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 16, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsx(Box, { as: "span", className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
10157
10126
  const I = resolveIcon(icon);
10158
10127
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
10159
10128
  })() : /* @__PURE__ */ (() => {
10160
10129
  const I = icon;
10161
10130
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
10162
10131
  })() }) : null,
10163
- /* @__PURE__ */ jsx("span", { className: "text-sm leading-snug", children: text })
10132
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm leading-snug", children: text })
10164
10133
  ]
10165
10134
  }
10166
10135
  );
@@ -10170,6 +10139,10 @@ var init_ChoiceButton = __esm({
10170
10139
  init_cn();
10171
10140
  init_Icon();
10172
10141
  init_useEventBus();
10142
+ init_Button();
10143
+ init_Box();
10144
+ init_Typography();
10145
+ init_GameIcon();
10173
10146
  ChoiceButton.displayName = "ChoiceButton";
10174
10147
  }
10175
10148
  });
@@ -10187,16 +10160,16 @@ function ActionButton({
10187
10160
  className
10188
10161
  }) {
10189
10162
  const eventBus = useEventBus();
10190
- const sizes = sizeMap12[size];
10163
+ const sizes = sizeMap13[size];
10191
10164
  const onCooldown = cooldown > 0;
10192
10165
  const isDisabled = disabled || onCooldown;
10193
10166
  const cooldownDeg = Math.round(cooldown * 360);
10194
10167
  return /* @__PURE__ */ jsxs(
10195
- "button",
10168
+ Button,
10196
10169
  {
10197
- type: "button",
10170
+ variant: variant === "danger" ? "danger" : variant === "secondary" ? "secondary" : "primary",
10198
10171
  disabled: isDisabled,
10199
- onClick: (e) => {
10172
+ onClick: () => {
10200
10173
  if (action) eventBus.emit(`UI:${action}`, {});
10201
10174
  onClick?.();
10202
10175
  },
@@ -10209,9 +10182,10 @@ function ActionButton({
10209
10182
  ),
10210
10183
  children: [
10211
10184
  onCooldown && /* @__PURE__ */ jsx(
10212
- "div",
10185
+ Box,
10213
10186
  {
10214
- className: "absolute inset-0 bg-foreground/40 pointer-events-none",
10187
+ position: "absolute",
10188
+ className: "inset-0 bg-foreground/40 pointer-events-none",
10215
10189
  style: {
10216
10190
  clipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
10217
10191
  WebkitClipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
@@ -10219,27 +10193,18 @@ function ActionButton({
10219
10193
  }
10220
10194
  }
10221
10195
  ),
10222
- assetUrl ? /* @__PURE__ */ jsx(
10223
- "img",
10224
- {
10225
- src: assetUrl.url,
10226
- alt: "",
10227
- width: 16,
10228
- height: 16,
10229
- style: { imageRendering: "pixelated", objectFit: "contain" },
10230
- className: cn("flex-shrink-0", sizes.icon)
10231
- }
10232
- ) : icon ? /* @__PURE__ */ jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
10196
+ assetUrl ? /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 16, className: cn("flex-shrink-0", sizes.icon) }) : icon ? /* @__PURE__ */ jsx(Box, { as: "span", className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
10233
10197
  const I = resolveIcon(icon);
10234
10198
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
10235
10199
  })() : /* @__PURE__ */ (() => {
10236
10200
  const I = icon;
10237
10201
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
10238
10202
  })() }) : null,
10239
- /* @__PURE__ */ jsx("span", { className: "relative z-10", children: label }),
10203
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "relative z-10", children: label }),
10240
10204
  hotkey && /* @__PURE__ */ jsx(
10241
- "span",
10205
+ Typography,
10242
10206
  {
10207
+ as: "span",
10243
10208
  className: cn(
10244
10209
  "absolute top-0.5 right-0.5 bg-foreground/30 text-primary-foreground rounded font-mono leading-tight",
10245
10210
  sizes.hotkey
@@ -10251,13 +10216,17 @@ function ActionButton({
10251
10216
  }
10252
10217
  );
10253
10218
  }
10254
- var sizeMap12, variantStyles8, DEFAULT_ASSET_URL11;
10219
+ var sizeMap13, variantStyles8, DEFAULT_ASSET_URL11;
10255
10220
  var init_ActionButton = __esm({
10256
10221
  "components/game/2d/atoms/ActionButton.tsx"() {
10257
10222
  init_cn();
10258
10223
  init_Icon();
10259
10224
  init_useEventBus();
10260
- sizeMap12 = {
10225
+ init_Button();
10226
+ init_Box();
10227
+ init_Typography();
10228
+ init_GameIcon();
10229
+ sizeMap13 = {
10261
10230
  sm: { button: "h-button-sm px-3 text-xs", hotkey: "text-[9px] px-1", icon: "text-xs" },
10262
10231
  md: { button: "h-button-md px-4 text-sm", hotkey: "text-xs px-1.5", icon: "text-sm" },
10263
10232
  lg: { button: "h-button-lg px-5 text-base", hotkey: "text-xs px-2", icon: "text-base" }
@@ -10359,10 +10328,12 @@ function MiniMap({
10359
10328
  return /* @__PURE__ */ jsxs(Fragment, { children: [
10360
10329
  /* @__PURE__ */ jsx("style", { children: `@keyframes minimap-blink{0%,49%{opacity:1}50%,100%{opacity:0}}` }),
10361
10330
  /* @__PURE__ */ jsxs(
10362
- "div",
10331
+ Box,
10363
10332
  {
10333
+ position: "relative",
10334
+ display: "inline-block",
10364
10335
  className: cn(
10365
- "relative inline-block border border-border/20 rounded-container",
10336
+ "border border-border/20 rounded-container",
10366
10337
  className
10367
10338
  ),
10368
10339
  children: [
@@ -10377,10 +10348,10 @@ function MiniMap({
10377
10348
  }
10378
10349
  ),
10379
10350
  playerLeft !== null && playerTop !== null && /* @__PURE__ */ jsx(
10380
- "div",
10351
+ Box,
10381
10352
  {
10353
+ position: "absolute",
10382
10354
  style: {
10383
- position: "absolute",
10384
10355
  left: playerLeft,
10385
10356
  top: playerTop,
10386
10357
  width: 3,
@@ -10401,6 +10372,7 @@ var init_MiniMap = __esm({
10401
10372
  "components/game/2d/atoms/MiniMap.tsx"() {
10402
10373
  "use client";
10403
10374
  init_cn();
10375
+ init_Box();
10404
10376
  DEFAULT_TILES = [
10405
10377
  { x: 10, y: 10, color: "#4ade80" },
10406
10378
  { x: 20, y: 15, color: "#4ade80" },
@@ -10418,38 +10390,6 @@ var init_MiniMap = __esm({
10418
10390
  MiniMap.displayName = "MiniMap";
10419
10391
  }
10420
10392
  });
10421
- function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
10422
- const px = typeof size === "number" ? size : sizeMap13[size];
10423
- if (assetUrl?.url) {
10424
- return /* @__PURE__ */ jsx(
10425
- "img",
10426
- {
10427
- src: assetUrl.url,
10428
- alt: alt ?? assetUrl.category ?? "",
10429
- width: px,
10430
- height: px,
10431
- style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
10432
- className: cn("flex-shrink-0", className)
10433
- }
10434
- );
10435
- }
10436
- const I = typeof icon === "string" ? resolveIcon(icon) : icon;
10437
- return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
10438
- }
10439
- var sizeMap13;
10440
- var init_GameIcon = __esm({
10441
- "components/game/2d/atoms/GameIcon.tsx"() {
10442
- "use client";
10443
- init_cn();
10444
- init_Icon();
10445
- sizeMap13 = {
10446
- sm: 16,
10447
- md: 24,
10448
- lg: 32
10449
- };
10450
- GameIcon.displayName = "GameIcon";
10451
- }
10452
- });
10453
10393
  function ControlGrid({
10454
10394
  kind,
10455
10395
  buttons = DEFAULT_BUTTONS,
@@ -10510,22 +10450,22 @@ function ControlGrid({
10510
10450
  },
10511
10451
  d
10512
10452
  );
10513
- return /* @__PURE__ */ jsxs("div", { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
10514
- /* @__PURE__ */ jsx("div", {}),
10453
+ return /* @__PURE__ */ jsxs(Box, { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
10454
+ /* @__PURE__ */ jsx(Box, {}),
10515
10455
  dir("up"),
10516
- /* @__PURE__ */ jsx("div", {}),
10456
+ /* @__PURE__ */ jsx(Box, {}),
10517
10457
  dir("left"),
10518
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "w-6 h-6 rounded-interactive bg-muted border-2 border-muted-foreground" }) }),
10458
+ /* @__PURE__ */ jsx(Box, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Box, { className: "w-6 h-6 rounded-interactive bg-muted border-2 border-muted-foreground" }) }),
10519
10459
  dir("right"),
10520
- /* @__PURE__ */ jsx("div", {}),
10460
+ /* @__PURE__ */ jsx(Box, {}),
10521
10461
  dir("down"),
10522
- /* @__PURE__ */ jsx("div", {})
10462
+ /* @__PURE__ */ jsx(Box, {})
10523
10463
  ] });
10524
10464
  }
10525
10465
  if (layout === "diamond" && buttons.length === 4) {
10526
10466
  const [top, right, bottom, left] = buttons;
10527
- return /* @__PURE__ */ jsxs("div", { className: cn(layoutClass.diamond, className), children: [
10528
- /* @__PURE__ */ jsx("div", {}),
10467
+ return /* @__PURE__ */ jsxs(Box, { className: cn(layoutClass.diamond, className), children: [
10468
+ /* @__PURE__ */ jsx(Box, {}),
10529
10469
  /* @__PURE__ */ jsx(
10530
10470
  ControlButton,
10531
10471
  {
@@ -10540,7 +10480,7 @@ function ControlGrid({
10540
10480
  disabled
10541
10481
  }
10542
10482
  ),
10543
- /* @__PURE__ */ jsx("div", {}),
10483
+ /* @__PURE__ */ jsx(Box, {}),
10544
10484
  /* @__PURE__ */ jsx(
10545
10485
  ControlButton,
10546
10486
  {
@@ -10555,7 +10495,7 @@ function ControlGrid({
10555
10495
  disabled
10556
10496
  }
10557
10497
  ),
10558
- /* @__PURE__ */ jsx("div", {}),
10498
+ /* @__PURE__ */ jsx(Box, {}),
10559
10499
  /* @__PURE__ */ jsx(
10560
10500
  ControlButton,
10561
10501
  {
@@ -10570,7 +10510,7 @@ function ControlGrid({
10570
10510
  disabled
10571
10511
  }
10572
10512
  ),
10573
- /* @__PURE__ */ jsx("div", {}),
10513
+ /* @__PURE__ */ jsx(Box, {}),
10574
10514
  /* @__PURE__ */ jsx(
10575
10515
  ControlButton,
10576
10516
  {
@@ -10585,10 +10525,10 @@ function ControlGrid({
10585
10525
  disabled
10586
10526
  }
10587
10527
  ),
10588
- /* @__PURE__ */ jsx("div", {})
10528
+ /* @__PURE__ */ jsx(Box, {})
10589
10529
  ] });
10590
10530
  }
10591
- return /* @__PURE__ */ jsx("div", { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
10531
+ return /* @__PURE__ */ jsx(Box, { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
10592
10532
  ControlButton,
10593
10533
  {
10594
10534
  icon: button.icon,
@@ -10610,6 +10550,7 @@ var init_ControlGrid = __esm({
10610
10550
  "use client";
10611
10551
  init_cn();
10612
10552
  init_useEventBus();
10553
+ init_Box();
10613
10554
  init_ControlButton();
10614
10555
  sizeKey = { sm: "sm", md: "md", lg: "lg" };
10615
10556
  layoutClass = {
@@ -10654,7 +10595,7 @@ function StatBadge({
10654
10595
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
10655
10596
  const resolvedAsset = iconUrl ?? assetUrl;
10656
10597
  return /* @__PURE__ */ jsxs(
10657
- "div",
10598
+ Box,
10658
10599
  {
10659
10600
  className: cn(
10660
10601
  "inline-flex items-center gap-2 rounded-container border backdrop-blur-sm",
@@ -10663,18 +10604,8 @@ function StatBadge({
10663
10604
  className
10664
10605
  ),
10665
10606
  children: [
10666
- resolvedAsset ? /* @__PURE__ */ jsx(
10667
- "img",
10668
- {
10669
- src: resolvedAsset.url,
10670
- alt: "",
10671
- width: 16,
10672
- height: 16,
10673
- style: { imageRendering: "pixelated", objectFit: "contain" },
10674
- className: "flex-shrink-0"
10675
- }
10676
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-lg", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: "w-4 h-4" }) : /* @__PURE__ */ jsx(Icon, { icon, className: "w-4 h-4" }) }) : null,
10677
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-medium", children: label }),
10607
+ resolvedAsset ? /* @__PURE__ */ jsx(GameIcon, { assetUrl: resolvedAsset, icon: "image", size: 16, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsx(Box, { as: "span", className: "flex-shrink-0 text-lg", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: "w-4 h-4" }) : /* @__PURE__ */ jsx(Icon, { icon, className: "w-4 h-4" }) }) : null,
10608
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground font-medium", children: label }),
10678
10609
  format === "hearts" && max && /* @__PURE__ */ jsx(
10679
10610
  HealthBar,
10680
10611
  {
@@ -10700,7 +10631,7 @@ function StatBadge({
10700
10631
  size: size === "lg" ? "md" : "sm"
10701
10632
  }
10702
10633
  ),
10703
- format === "text" && /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground", children: value })
10634
+ format === "text" && /* @__PURE__ */ jsx(Typography, { as: "span", className: "font-bold text-foreground", children: value })
10704
10635
  ]
10705
10636
  }
10706
10637
  );
@@ -10710,6 +10641,9 @@ var init_StatBadge = __esm({
10710
10641
  "components/game/2d/molecules/StatBadge.tsx"() {
10711
10642
  init_cn();
10712
10643
  init_Icon();
10644
+ init_Box();
10645
+ init_Typography();
10646
+ init_GameIcon();
10713
10647
  init_HealthBar();
10714
10648
  init_ScoreDisplay();
10715
10649
  sizeMap14 = {
@@ -10887,9 +10821,9 @@ function GameHud({
10887
10821
  if (position === "corners") {
10888
10822
  const leftStats = stats.slice(0, Math.ceil(stats.length / 2));
10889
10823
  const rightStats = stats.slice(Math.ceil(stats.length / 2));
10890
- return /* @__PURE__ */ jsxs("div", { className: cn("relative", positionMap[position], className), children: [
10891
- /* @__PURE__ */ jsx("div", { className: "absolute top-4 left-4 flex flex-col gap-2 pointer-events-auto", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10892
- /* @__PURE__ */ jsx("div", { className: "absolute top-4 right-4 flex flex-col gap-2 items-end pointer-events-auto", children: rightStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) })
10824
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn(positionMap[position], className), children: [
10825
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-4 left-4 flex flex-col gap-2 pointer-events-auto", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10826
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-4 right-4 flex flex-col gap-2 items-end pointer-events-auto", children: rightStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) })
10893
10827
  ] });
10894
10828
  }
10895
10829
  if (position === "top" || position === "bottom") {
@@ -10898,7 +10832,7 @@ function GameHud({
10898
10832
  const rightStats = stats.slice(mid);
10899
10833
  const isTop = position === "top";
10900
10834
  return /* @__PURE__ */ jsxs(
10901
- "div",
10835
+ Box,
10902
10836
  {
10903
10837
  className: cn(
10904
10838
  "flex items-center justify-between w-full",
@@ -10908,17 +10842,18 @@ function GameHud({
10908
10842
  className
10909
10843
  ),
10910
10844
  children: [
10911
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10912
- rightStats.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 flex-shrink-0", children: rightStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) })
10845
+ /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10846
+ rightStats.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: rightStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) })
10913
10847
  ]
10914
10848
  }
10915
10849
  );
10916
10850
  }
10917
10851
  return /* @__PURE__ */ jsx(
10918
- "div",
10852
+ Box,
10919
10853
  {
10854
+ position: "relative",
10920
10855
  className: cn(
10921
- "relative z-10 flex items-center gap-4 px-4 py-2",
10856
+ "z-10 flex items-center gap-4 px-4 py-2",
10922
10857
  transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
10923
10858
  className
10924
10859
  ),
@@ -10930,6 +10865,7 @@ var positionMap, DEFAULT_HUD_STATS;
10930
10865
  var init_GameHud = __esm({
10931
10866
  "components/game/2d/molecules/GameHud.tsx"() {
10932
10867
  init_cn();
10868
+ init_Box();
10933
10869
  init_StatBadge();
10934
10870
  positionMap = {
10935
10871
  corners: "inset-0 pointer-events-none"
@@ -10970,7 +10906,7 @@ function GameMenu({
10970
10906
  [eventBus, onSelect]
10971
10907
  );
10972
10908
  return /* @__PURE__ */ jsxs(
10973
- "div",
10909
+ Box,
10974
10910
  {
10975
10911
  className: cn(
10976
10912
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
@@ -10980,18 +10916,12 @@ function GameMenu({
10980
10916
  background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
10981
10917
  },
10982
10918
  children: [
10983
- /* @__PURE__ */ jsxs("div", { className: "text-center mb-12 animate-fade-in", children: [
10984
- logo && /* @__PURE__ */ jsx(
10985
- "img",
10986
- {
10987
- src: logo.url,
10988
- alt: title,
10989
- className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl"
10990
- }
10991
- ),
10919
+ /* @__PURE__ */ jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
10920
+ logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
10992
10921
  /* @__PURE__ */ jsx(
10993
- "h1",
10922
+ Typography,
10994
10923
  {
10924
+ variant: "h1",
10995
10925
  className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
10996
10926
  style: {
10997
10927
  textShadow: "0 4px 12px rgba(0,0,0,0.5)"
@@ -10999,9 +10929,9 @@ function GameMenu({
10999
10929
  children: title
11000
10930
  }
11001
10931
  ),
11002
- subtitle && /* @__PURE__ */ jsx("p", { className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
10932
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
11003
10933
  ] }),
11004
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
10934
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
11005
10935
  ChoiceButton,
11006
10936
  {
11007
10937
  text: option.label,
@@ -11012,9 +10942,9 @@ function GameMenu({
11012
10942
  },
11013
10943
  index
11014
10944
  )) }),
11015
- /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 pointer-events-none overflow-hidden", children: [
11016
- /* @__PURE__ */ jsx("div", { className: "absolute top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
11017
- /* @__PURE__ */ jsx("div", { className: "absolute bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
10945
+ /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
10946
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
10947
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
11018
10948
  ] })
11019
10949
  ]
11020
10950
  }
@@ -11026,6 +10956,9 @@ var init_GameMenu = __esm({
11026
10956
  "use client";
11027
10957
  init_cn();
11028
10958
  init_useEventBus();
10959
+ init_Box();
10960
+ init_Typography();
10961
+ init_GameIcon();
11029
10962
  init_ChoiceButton();
11030
10963
  DEFAULT_MENU_OPTIONS = [
11031
10964
  { label: "New Game", event: "NEW_GAME", variant: "primary" },
@@ -12266,10 +12199,11 @@ function Canvas2D({
12266
12199
  }
12267
12200
  }
12268
12201
  ),
12269
- process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs("div", { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
12202
+ process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs(Box, { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
12270
12203
  tileClickEvent && /* @__PURE__ */ jsx(
12271
- "button",
12204
+ Button,
12272
12205
  {
12206
+ variant: "ghost",
12273
12207
  "data-event": tileClickEvent,
12274
12208
  "data-x": "0",
12275
12209
  "data-y": "0",
@@ -12278,8 +12212,9 @@ function Canvas2D({
12278
12212
  }
12279
12213
  ),
12280
12214
  unitClickEvent && units && units.length > 0 && /* @__PURE__ */ jsx(
12281
- "button",
12215
+ Button,
12282
12216
  {
12217
+ variant: "ghost",
12283
12218
  "data-event": unitClickEvent,
12284
12219
  "data-unit-id": units[0].id,
12285
12220
  onClick: () => eventBus.emit(`UI:${unitClickEvent}`, { unitId: units[0].id }),
@@ -12288,15 +12223,17 @@ function Canvas2D({
12288
12223
  )
12289
12224
  ] }),
12290
12225
  unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxs(
12291
- "div",
12226
+ Box,
12292
12227
  {
12293
- className: "absolute pointer-events-none",
12228
+ position: "absolute",
12229
+ className: "pointer-events-none",
12294
12230
  style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
12295
12231
  children: [
12296
12232
  unit.name && /* @__PURE__ */ jsx(
12297
- "div",
12233
+ Typography,
12298
12234
  {
12299
- className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
12235
+ as: "span",
12236
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap block",
12300
12237
  style: { background: unit.team === "player" ? "rgba(59,130,246,0.9)" : unit.team === "enemy" ? "rgba(239,68,68,0.9)" : "rgba(107,114,128,0.9)" },
12301
12238
  children: unit.name
12302
12239
  }
@@ -12306,7 +12243,7 @@ function Canvas2D({
12306
12243
  },
12307
12244
  unit.id
12308
12245
  )),
12309
- showMinimap && /* @__PURE__ */ jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
12246
+ showMinimap && /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
12310
12247
  MiniMap,
12311
12248
  {
12312
12249
  tiles: miniMapTiles,
@@ -12328,6 +12265,7 @@ var init_Canvas2D = __esm({
12328
12265
  init_cn();
12329
12266
  init_useEventBus();
12330
12267
  init_Box();
12268
+ init_Button();
12331
12269
  init_Stack();
12332
12270
  init_Icon();
12333
12271
  init_Typography();
@@ -12659,7 +12597,7 @@ function GameAudioToggle({
12659
12597
  onClick: handleToggle,
12660
12598
  className: cn("text-lg leading-none px-2", className),
12661
12599
  "aria-pressed": muted,
12662
- children: activeAsset ? /* @__PURE__ */ jsx("img", { src: activeAsset.url, alt: muted ? "Muted" : "Sound on", className: "w-5 h-5 object-contain" }) : muted ? "\u{1F507}" : "\u{1F50A}"
12600
+ children: activeAsset ? /* @__PURE__ */ jsx(GameIcon, { assetUrl: activeAsset, icon: "image", size: 20, alt: muted ? "Muted" : "Sound on", className: "w-5 h-5 object-contain" }) : muted ? "\u{1F507}" : "\u{1F50A}"
12663
12601
  }
12664
12602
  );
12665
12603
  }
@@ -12669,6 +12607,7 @@ var init_GameAudioToggle = __esm({
12669
12607
  init_atoms();
12670
12608
  init_cn();
12671
12609
  init_GameAudioProvider();
12610
+ init_GameIcon();
12672
12611
  GameAudioToggle.displayName = "GameAudioToggle";
12673
12612
  }
12674
12613
  });
@@ -23256,7 +23195,7 @@ var init_Tabs = __esm({
23256
23195
  isActive ? variant === "pills" ? "text-primary-foreground font-bold" : "text-foreground font-bold" : "text-muted-foreground hover:text-foreground"
23257
23196
  ),
23258
23197
  children: [
23259
- item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm" })),
23198
+ item.iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: item.iconAsset.url, alt: item.iconAsset.name ?? item.iconAsset.category ?? "", width: 16, height: 16, style: { imageRendering: "pixelated", objectFit: "contain", width: 16, height: 16 }, className: "flex-shrink-0" }) : item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm" })),
23260
23199
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: isActive ? "semibold" : "normal", className: "!text-inherit", children: item.label }),
23261
23200
  item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge })
23262
23201
  ]