@almadar/ui 5.80.0 → 5.81.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.
@@ -8883,6 +8883,38 @@ var init_shared = __esm({
8883
8883
  init_canvasEffects();
8884
8884
  }
8885
8885
  });
8886
+ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
8887
+ const px = typeof size === "number" ? size : sizeMap[size];
8888
+ if (assetUrl?.url) {
8889
+ return /* @__PURE__ */ jsx(
8890
+ "img",
8891
+ {
8892
+ src: assetUrl.url,
8893
+ alt: alt ?? assetUrl.category ?? "",
8894
+ width: px,
8895
+ height: px,
8896
+ style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
8897
+ className: cn("flex-shrink-0", className)
8898
+ }
8899
+ );
8900
+ }
8901
+ const I = typeof icon === "string" ? resolveIcon(icon) : icon;
8902
+ return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
8903
+ }
8904
+ var sizeMap;
8905
+ var init_GameIcon = __esm({
8906
+ "components/game/2d/atoms/GameIcon.tsx"() {
8907
+ "use client";
8908
+ init_cn();
8909
+ init_Icon();
8910
+ sizeMap = {
8911
+ sm: 16,
8912
+ md: 24,
8913
+ lg: 32
8914
+ };
8915
+ GameIcon.displayName = "GameIcon";
8916
+ }
8917
+ });
8886
8918
  function GameCard({
8887
8919
  id,
8888
8920
  cost,
@@ -8905,9 +8937,9 @@ function GameCard({
8905
8937
  }, [disabled, id, onClick, clickEvent, eventBus]);
8906
8938
  const artPx = artPxMap[size];
8907
8939
  return /* @__PURE__ */ jsxs(
8908
- "button",
8940
+ Button,
8909
8941
  {
8910
- type: "button",
8942
+ variant: "ghost",
8911
8943
  onClick: handleClick,
8912
8944
  disabled,
8913
8945
  title: name,
@@ -8921,8 +8953,9 @@ function GameCard({
8921
8953
  ),
8922
8954
  children: [
8923
8955
  cost != null && /* @__PURE__ */ jsx(
8924
- "span",
8956
+ Typography,
8925
8957
  {
8958
+ as: "span",
8926
8959
  className: cn(
8927
8960
  "absolute -top-2 -left-2 flex items-center justify-center",
8928
8961
  "min-w-[22px] h-[22px] rounded-full px-1",
@@ -8931,17 +8964,7 @@ function GameCard({
8931
8964
  children: cost
8932
8965
  }
8933
8966
  ),
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 } }) }),
8967
+ /* @__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
8968
  name != null && /* @__PURE__ */ jsx(
8946
8969
  Typography,
8947
8970
  {
@@ -8951,8 +8974,8 @@ function GameCard({
8951
8974
  }
8952
8975
  ),
8953
8976
  (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}` : "" })
8977
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
8978
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
8956
8979
  ] })
8957
8980
  ]
8958
8981
  }
@@ -8965,7 +8988,9 @@ var init_GameCard = __esm({
8965
8988
  init_cn();
8966
8989
  init_useEventBus();
8967
8990
  init_Box();
8991
+ init_Button();
8968
8992
  init_Typography();
8993
+ init_GameIcon();
8969
8994
  cardSizeMap = {
8970
8995
  sm: "w-16 h-24",
8971
8996
  md: "w-20 h-28",
@@ -8988,12 +9013,13 @@ function HealthBar({
8988
9013
  frameAsset,
8989
9014
  fillAsset
8990
9015
  }) {
8991
- const sizes = sizeMap[size];
9016
+ const sizes = sizeMap2[size];
8992
9017
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
8993
9018
  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",
9019
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
9020
+ Box,
8996
9021
  {
9022
+ as: "span",
8997
9023
  className: cn(animated && "transition-transform hover:scale-110"),
8998
9024
  children: heartIcon(i < current, sizes.heart)
8999
9025
  },
@@ -9002,10 +9028,12 @@ function HealthBar({
9002
9028
  }
9003
9029
  if (format === "bar") {
9004
9030
  return /* @__PURE__ */ jsx(
9005
- "div",
9031
+ Box,
9006
9032
  {
9033
+ position: "relative",
9034
+ overflow: "hidden",
9007
9035
  className: cn(
9008
- "relative overflow-hidden rounded-full",
9036
+ "rounded-full",
9009
9037
  !frameAsset && "bg-muted",
9010
9038
  sizes.bar,
9011
9039
  "w-24",
@@ -9013,10 +9041,11 @@ function HealthBar({
9013
9041
  ),
9014
9042
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
9015
9043
  children: /* @__PURE__ */ jsx(
9016
- "div",
9044
+ Box,
9017
9045
  {
9046
+ position: "absolute",
9018
9047
  className: cn(
9019
- "absolute inset-y-0 left-0 rounded-full",
9048
+ "inset-y-0 left-0 rounded-full",
9020
9049
  !fillAsset && (percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error"),
9021
9050
  animated && "transition-all duration-300"
9022
9051
  ),
@@ -9030,10 +9059,11 @@ function HealthBar({
9030
9059
  );
9031
9060
  }
9032
9061
  if (format === "progress") {
9033
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
9062
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex items-center gap-2", className), children: [
9034
9063
  level != null && /* @__PURE__ */ jsxs(
9035
- "span",
9064
+ Typography,
9036
9065
  {
9066
+ as: "span",
9037
9067
  className: cn(
9038
9068
  "flex-shrink-0 rounded-interactive font-bold",
9039
9069
  "bg-accent text-accent-foreground border border-accent",
@@ -9045,21 +9075,23 @@ function HealthBar({
9045
9075
  ]
9046
9076
  }
9047
9077
  ),
9048
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [
9078
+ /* @__PURE__ */ jsxs(Box, { className: "flex-1 flex flex-col gap-0.5", children: [
9049
9079
  /* @__PURE__ */ jsx(
9050
- "div",
9080
+ Box,
9051
9081
  {
9082
+ position: "relative",
9052
9083
  className: cn(
9053
- "relative w-full overflow-hidden rounded-full",
9084
+ "w-full overflow-hidden rounded-full",
9054
9085
  !frameAsset && "bg-muted border border-muted",
9055
9086
  sizes.bar
9056
9087
  ),
9057
9088
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
9058
9089
  children: /* @__PURE__ */ jsx(
9059
- "div",
9090
+ Box,
9060
9091
  {
9092
+ position: "absolute",
9061
9093
  className: cn(
9062
- "absolute inset-y-0 left-0 rounded-full",
9094
+ "inset-y-0 left-0 rounded-full",
9063
9095
  !fillAsset && "bg-gradient-to-r from-accent to-info",
9064
9096
  animated && "transition-all duration-500 ease-out"
9065
9097
  ),
@@ -9071,7 +9103,7 @@ function HealthBar({
9071
9103
  )
9072
9104
  }
9073
9105
  ),
9074
- showLabel && /* @__PURE__ */ jsxs("span", { className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
9106
+ showLabel && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
9075
9107
  current,
9076
9108
  " / ",
9077
9109
  max,
@@ -9080,16 +9112,18 @@ function HealthBar({
9080
9112
  ] })
9081
9113
  ] });
9082
9114
  }
9083
- return /* @__PURE__ */ jsxs("span", { className: cn("font-mono font-bold", sizes.text, className), children: [
9115
+ return /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-mono font-bold", sizes.text, className), children: [
9084
9116
  current,
9085
9117
  "/",
9086
9118
  max
9087
9119
  ] });
9088
9120
  }
9089
- var heartIcon, sizeMap;
9121
+ var heartIcon, sizeMap2;
9090
9122
  var init_HealthBar = __esm({
9091
9123
  "components/game/2d/atoms/HealthBar.tsx"() {
9092
9124
  init_cn();
9125
+ init_Box();
9126
+ init_Typography();
9093
9127
  heartIcon = (filled, size) => /* @__PURE__ */ jsx(
9094
9128
  "svg",
9095
9129
  {
@@ -9101,7 +9135,7 @@ var init_HealthBar = __esm({
9101
9135
  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
9136
  }
9103
9137
  );
9104
- sizeMap = {
9138
+ sizeMap2 = {
9105
9139
  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
9140
  md: { heart: "w-6 h-6", bar: "h-3", text: "text-base", label: "text-xs", badge: "text-xs px-2 py-0.5" },
9107
9141
  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 +9156,30 @@ function ScoreDisplay({
9122
9156
  const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
9123
9157
  const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
9124
9158
  return /* @__PURE__ */ jsxs(
9125
- "div",
9159
+ Box,
9126
9160
  {
9127
9161
  className: cn(
9128
9162
  "flex items-center gap-2 font-bold",
9129
- sizeMap2[size],
9163
+ sizeMap3[size],
9130
9164
  className
9131
9165
  ),
9132
9166
  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 })
9167
+ 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,
9168
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
9169
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "tabular-nums", children: formattedValue })
9146
9170
  ]
9147
9171
  }
9148
9172
  );
9149
9173
  }
9150
- var sizeMap2, DEFAULT_ASSET_URL;
9174
+ var sizeMap3, DEFAULT_ASSET_URL;
9151
9175
  var init_ScoreDisplay = __esm({
9152
9176
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
9153
9177
  init_cn();
9154
9178
  init_Icon();
9155
- sizeMap2 = {
9179
+ init_Box();
9180
+ init_Typography();
9181
+ init_GameIcon();
9182
+ sizeMap3 = {
9156
9183
  sm: "text-sm",
9157
9184
  md: "text-lg",
9158
9185
  lg: "text-2xl",
@@ -9215,9 +9242,9 @@ function ControlButton({
9215
9242
  [isPressed, releaseEvent, eventBus, onRelease]
9216
9243
  );
9217
9244
  return /* @__PURE__ */ jsx(
9218
- "button",
9245
+ Button,
9219
9246
  {
9220
- type: "button",
9247
+ variant,
9221
9248
  disabled,
9222
9249
  onPointerDown: handlePointerDown,
9223
9250
  onPointerUp: handlePointerUp,
@@ -9228,41 +9255,35 @@ function ControlButton({
9228
9255
  "select-none touch-none",
9229
9256
  "transition-all duration-100",
9230
9257
  "active:scale-95",
9231
- sizeMap3[size] ?? sizeMap3.md,
9258
+ sizeMap4[size] ?? sizeMap4.md,
9232
9259
  shapeMap[shape] ?? shapeMap.circle,
9233
9260
  variantMap[variant] ?? variantMap.secondary,
9234
9261
  actualPressed && "scale-95 brightness-110 border-foreground",
9235
9262
  disabled && "opacity-50 cursor-not-allowed",
9236
9263
  className
9237
9264
  ),
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) ? (() => {
9265
+ 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
9266
  const I = resolveIcon(icon);
9250
9267
  return I ? /* @__PURE__ */ jsx(I, { className: "w-6 h-6" }) : null;
9251
9268
  })() : icon : /* @__PURE__ */ (() => {
9252
9269
  const I = icon;
9253
9270
  return /* @__PURE__ */ jsx(I, { className: "w-6 h-6" });
9254
- })() }) : label ? /* @__PURE__ */ jsx("span", { children: label }) : null
9271
+ })() }) : label ? /* @__PURE__ */ jsx(Typography, { as: "span", children: label }) : null
9255
9272
  }
9256
9273
  );
9257
9274
  }
9258
- var sizeMap3, shapeMap, variantMap, DEFAULT_ASSET_URL2;
9275
+ var sizeMap4, shapeMap, variantMap, DEFAULT_ASSET_URL2;
9259
9276
  var init_ControlButton = __esm({
9260
9277
  "components/game/2d/atoms/ControlButton.tsx"() {
9261
9278
  "use client";
9262
9279
  init_cn();
9263
9280
  init_useEventBus();
9264
9281
  init_Icon();
9265
- sizeMap3 = {
9282
+ init_Button();
9283
+ init_Box();
9284
+ init_Typography();
9285
+ init_GameIcon();
9286
+ sizeMap4 = {
9266
9287
  sm: "w-10 h-10 text-sm",
9267
9288
  md: "w-14 h-14 text-base",
9268
9289
  lg: "w-18 h-18 text-lg",
@@ -9332,12 +9353,12 @@ function Sprite({
9332
9353
  onClick?.();
9333
9354
  };
9334
9355
  return /* @__PURE__ */ jsx(
9335
- "div",
9356
+ Box,
9336
9357
  {
9358
+ position: "absolute",
9337
9359
  className,
9338
9360
  onClick: action || onClick ? handleClick : void 0,
9339
9361
  style: {
9340
- position: "absolute",
9341
9362
  width: frameWidth,
9342
9363
  height: frameHeight,
9343
9364
  backgroundImage: `url(${spritesheet.url})`,
@@ -9358,6 +9379,7 @@ var init_Sprite = __esm({
9358
9379
  "components/game/2d/atoms/Sprite.tsx"() {
9359
9380
  "use client";
9360
9381
  init_useEventBus();
9382
+ init_Box();
9361
9383
  init_spriteAnimation();
9362
9384
  DEFAULT_SPRITESHEET = {
9363
9385
  url: "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
@@ -9394,17 +9416,7 @@ function StateIndicator({
9394
9416
  className
9395
9417
  ),
9396
9418
  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 }) }),
9419
+ /* @__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
9420
  /* @__PURE__ */ jsx(Box, { as: "span", children: displayLabel })
9409
9421
  ]
9410
9422
  }
@@ -9416,6 +9428,7 @@ var init_StateIndicator = __esm({
9416
9428
  init_Box();
9417
9429
  init_Icon();
9418
9430
  init_cn();
9431
+ init_GameIcon();
9419
9432
  DEFAULT_ASSET_URL3 = {
9420
9433
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
9421
9434
  role: "ui",
@@ -9469,29 +9482,31 @@ function TimerDisplay({
9469
9482
  }) {
9470
9483
  const isLow = lowThreshold != null && seconds <= lowThreshold && seconds > 0;
9471
9484
  return /* @__PURE__ */ jsxs(
9472
- "div",
9485
+ Box,
9473
9486
  {
9474
9487
  className: cn(
9475
9488
  "inline-flex items-center gap-1 justify-center rounded-container",
9476
9489
  "bg-card/80 border border-muted font-mono font-bold tabular-nums",
9477
- sizeMap4[size],
9490
+ sizeMap5[size],
9478
9491
  running && "border-success/50",
9479
9492
  isLow && "text-error border-error/50 animate-pulse",
9480
9493
  !isLow && "text-foreground",
9481
9494
  className
9482
9495
  ),
9483
9496
  children: [
9484
- iconAsset && /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: "", className: "w-4 h-4 object-contain flex-shrink-0" }),
9497
+ iconAsset && /* @__PURE__ */ jsx(GameIcon, { assetUrl: iconAsset, icon: "image", size: 16, className: "w-4 h-4 object-contain flex-shrink-0" }),
9485
9498
  formatTime(seconds, format)
9486
9499
  ]
9487
9500
  }
9488
9501
  );
9489
9502
  }
9490
- var sizeMap4;
9503
+ var sizeMap5;
9491
9504
  var init_TimerDisplay = __esm({
9492
9505
  "components/game/2d/atoms/TimerDisplay.tsx"() {
9493
9506
  init_cn();
9494
- sizeMap4 = {
9507
+ init_Box();
9508
+ init_GameIcon();
9509
+ sizeMap5 = {
9495
9510
  sm: "text-sm px-2 py-0.5",
9496
9511
  md: "text-lg px-3 py-1",
9497
9512
  lg: "text-2xl px-4 py-1.5"
@@ -9509,9 +9524,9 @@ function ResourceCounter({
9509
9524
  size = "md",
9510
9525
  className
9511
9526
  }) {
9512
- const sizes = sizeMap5[size];
9527
+ const sizes = sizeMap6[size];
9513
9528
  return /* @__PURE__ */ jsxs(
9514
- "div",
9529
+ Box,
9515
9530
  {
9516
9531
  className: cn(
9517
9532
  "inline-flex items-center rounded-container",
@@ -9520,21 +9535,11 @@ function ResourceCounter({
9520
9535
  className
9521
9536
  ),
9522
9537
  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: [
9538
+ 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,
9539
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
9540
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
9536
9541
  value,
9537
- max != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9542
+ max != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
9538
9543
  "/",
9539
9544
  max
9540
9545
  ] })
@@ -9543,11 +9548,14 @@ function ResourceCounter({
9543
9548
  }
9544
9549
  );
9545
9550
  }
9546
- var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap5;
9551
+ var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap6;
9547
9552
  var init_ResourceCounter = __esm({
9548
9553
  "components/game/2d/atoms/ResourceCounter.tsx"() {
9549
9554
  init_cn();
9550
9555
  init_Icon();
9556
+ init_Box();
9557
+ init_Typography();
9558
+ init_GameIcon();
9551
9559
  colorTokenClasses2 = {
9552
9560
  primary: "text-primary",
9553
9561
  secondary: "text-secondary",
@@ -9561,7 +9569,7 @@ var init_ResourceCounter = __esm({
9561
9569
  role: "ui",
9562
9570
  category: "coin"
9563
9571
  };
9564
- sizeMap5 = {
9572
+ sizeMap6 = {
9565
9573
  sm: { wrapper: "text-xs gap-1 px-1.5 py-0.5", icon: "text-sm", img: 16 },
9566
9574
  md: { wrapper: "text-sm gap-1.5 px-2 py-1", icon: "text-base", img: 20 },
9567
9575
  lg: { wrapper: "text-base gap-2 px-3 py-1.5", icon: "text-lg", img: 28 }
@@ -9586,9 +9594,9 @@ function ItemSlot({
9586
9594
  const isClickable = onClick != null || action != null;
9587
9595
  const px = assetSizeMap[size];
9588
9596
  return /* @__PURE__ */ jsx(
9589
- "button",
9597
+ Button,
9590
9598
  {
9591
- type: "button",
9599
+ variant: "ghost",
9592
9600
  onClick: () => {
9593
9601
  if (action) eventBus.emit(`UI:${action}`, {});
9594
9602
  onClick?.();
@@ -9598,7 +9606,7 @@ function ItemSlot({
9598
9606
  className: cn(
9599
9607
  "relative flex items-center justify-center rounded-interactive border-2",
9600
9608
  "bg-card/80 transition-all duration-150",
9601
- sizeMap6[size],
9609
+ sizeMap7[size],
9602
9610
  empty ? "border-border bg-card/50" : rarityBorderMap[rarity],
9603
9611
  !empty && rarityGlowMap[rarity],
9604
9612
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background",
@@ -9607,21 +9615,12 @@ function ItemSlot({
9607
9615
  !isClickable && "cursor-default",
9608
9616
  className
9609
9617
  ),
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,
9618
+ children: empty ? /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9619
+ 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
9620
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
9623
- "span",
9621
+ Typography,
9624
9622
  {
9623
+ as: "span",
9625
9624
  className: cn(
9626
9625
  "absolute -bottom-1 -right-1 flex items-center justify-center",
9627
9626
  "min-w-[18px] h-[18px] rounded-full px-1",
@@ -9634,14 +9633,18 @@ function ItemSlot({
9634
9633
  }
9635
9634
  );
9636
9635
  }
9637
- var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9636
+ var sizeMap7, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9638
9637
  var init_ItemSlot = __esm({
9639
9638
  "components/game/2d/atoms/ItemSlot.tsx"() {
9640
9639
  "use client";
9641
9640
  init_cn();
9642
9641
  init_Icon();
9643
9642
  init_useEventBus();
9644
- sizeMap6 = {
9643
+ init_Button();
9644
+ init_Box();
9645
+ init_Typography();
9646
+ init_GameIcon();
9647
+ sizeMap7 = {
9645
9648
  sm: "w-10 h-10 text-lg",
9646
9649
  md: "w-14 h-14 text-2xl",
9647
9650
  lg: "w-18 h-18 text-3xl"
@@ -9682,9 +9685,9 @@ function TurnIndicator({
9682
9685
  size = "md",
9683
9686
  className
9684
9687
  }) {
9685
- const sizes = sizeMap7[size];
9688
+ const sizes = sizeMap8[size];
9686
9689
  return /* @__PURE__ */ jsxs(
9687
- "div",
9690
+ Box,
9688
9691
  {
9689
9692
  className: cn(
9690
9693
  "inline-flex items-center rounded-container",
@@ -9693,42 +9696,35 @@ function TurnIndicator({
9693
9696
  className
9694
9697
  ),
9695
9698
  children: [
9696
- /* @__PURE__ */ jsxs("span", { className: "font-bold tabular-nums", children: [
9699
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: "font-bold tabular-nums", children: [
9697
9700
  "Turn ",
9698
9701
  currentTurn,
9699
- maxTurns != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9702
+ maxTurns != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
9700
9703
  "/",
9701
9704
  maxTurns
9702
9705
  ] })
9703
9706
  ] }),
9704
9707
  phase && /* @__PURE__ */ jsxs(Fragment, { children: [
9705
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
9706
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: phase })
9708
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9709
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: phase })
9707
9710
  ] }),
9708
9711
  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 })
9712
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9713
+ 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) }),
9714
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-success", children: activeTeam })
9722
9715
  ] })
9723
9716
  ]
9724
9717
  }
9725
9718
  );
9726
9719
  }
9727
- var sizeMap7, DEFAULT_ASSET_URL6;
9720
+ var sizeMap8, DEFAULT_ASSET_URL6;
9728
9721
  var init_TurnIndicator = __esm({
9729
9722
  "components/game/2d/atoms/TurnIndicator.tsx"() {
9730
9723
  init_cn();
9731
- sizeMap7 = {
9724
+ init_Box();
9725
+ init_Typography();
9726
+ init_GameIcon();
9727
+ sizeMap8 = {
9732
9728
  sm: { wrapper: "text-xs gap-1.5 px-2 py-0.5", dot: "w-1.5 h-1.5" },
9733
9729
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
9734
9730
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
@@ -9760,10 +9756,10 @@ function ComboCounter({
9760
9756
  size = "md",
9761
9757
  className
9762
9758
  }) {
9763
- const sizes = sizeMap8[size];
9759
+ const sizes = sizeMap9[size];
9764
9760
  if (combo <= 0) return null;
9765
9761
  return /* @__PURE__ */ jsxs(
9766
- "div",
9762
+ Box,
9767
9763
  {
9768
9764
  className: cn(
9769
9765
  "inline-flex flex-col items-center justify-center",
@@ -9773,24 +9769,14 @@ function ComboCounter({
9773
9769
  className
9774
9770
  ),
9775
9771
  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: [
9772
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0 mb-0.5" }),
9773
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
9774
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
9775
+ multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
9790
9776
  "x",
9791
9777
  multiplier.toFixed(1)
9792
9778
  ] }),
9793
- streak != null && streak > 0 && /* @__PURE__ */ jsxs("span", { className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9779
+ streak != null && streak > 0 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9794
9780
  streak,
9795
9781
  " streak"
9796
9782
  ] })
@@ -9798,16 +9784,19 @@ function ComboCounter({
9798
9784
  }
9799
9785
  );
9800
9786
  }
9801
- var DEFAULT_ASSET_URL7, sizeMap8;
9787
+ var DEFAULT_ASSET_URL7, sizeMap9;
9802
9788
  var init_ComboCounter = __esm({
9803
9789
  "components/game/2d/atoms/ComboCounter.tsx"() {
9804
9790
  init_cn();
9791
+ init_Box();
9792
+ init_Typography();
9793
+ init_GameIcon();
9805
9794
  DEFAULT_ASSET_URL7 = {
9806
9795
  url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
9807
9796
  role: "effect",
9808
9797
  category: "effect"
9809
9798
  };
9810
- sizeMap8 = {
9799
+ sizeMap9 = {
9811
9800
  sm: { combo: "text-lg", label: "text-xs", multiplier: "text-xs" },
9812
9801
  md: { combo: "text-2xl", label: "text-xs", multiplier: "text-sm" },
9813
9802
  lg: { combo: "text-4xl", label: "text-sm", multiplier: "text-base" }
@@ -9824,54 +9813,48 @@ function WaypointMarker({
9824
9813
  size = "md",
9825
9814
  className
9826
9815
  }) {
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: [
9816
+ const sizes = sizeMap10[size];
9817
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col items-center", className), children: [
9818
+ /* @__PURE__ */ jsxs(Box, { className: "relative flex items-center justify-center", children: [
9830
9819
  active && /* @__PURE__ */ jsx(
9831
- "div",
9820
+ Box,
9832
9821
  {
9822
+ position: "absolute",
9833
9823
  className: cn(
9834
- "absolute rounded-full border-2 border-info animate-ping opacity-50",
9824
+ "rounded-full border-2 border-info animate-ping opacity-50",
9835
9825
  sizes.ring
9836
9826
  )
9837
9827
  }
9838
9828
  ),
9839
9829
  active && /* @__PURE__ */ jsx(
9840
- "div",
9830
+ Box,
9841
9831
  {
9832
+ position: "absolute",
9842
9833
  className: cn(
9843
- "absolute rounded-full border-2 border-info",
9834
+ "rounded-full border-2 border-info",
9844
9835
  sizes.ring
9845
9836
  )
9846
9837
  }
9847
9838
  ),
9848
9839
  /* @__PURE__ */ jsx(
9849
- "div",
9840
+ Box,
9850
9841
  {
9842
+ position: "relative",
9851
9843
  className: cn(
9852
- "relative flex items-center justify-center rounded-full transition-all duration-200",
9844
+ "flex items-center justify-center rounded-full transition-all duration-200",
9853
9845
  sizes.dot,
9854
9846
  completed && "bg-success text-foreground",
9855
9847
  active && !completed && "bg-info text-foreground",
9856
9848
  !active && !completed && "bg-muted"
9857
9849
  ),
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
9850
+ 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
9851
  }
9870
9852
  )
9871
9853
  ] }),
9872
9854
  label && /* @__PURE__ */ jsx(
9873
- "span",
9855
+ Typography,
9874
9856
  {
9857
+ as: "span",
9875
9858
  className: cn(
9876
9859
  "text-center whitespace-nowrap",
9877
9860
  sizes.label,
@@ -9882,17 +9865,20 @@ function WaypointMarker({
9882
9865
  )
9883
9866
  ] });
9884
9867
  }
9885
- var DEFAULT_ASSET_URL8, sizeMap9, checkIcon;
9868
+ var DEFAULT_ASSET_URL8, sizeMap10, checkIcon;
9886
9869
  var init_WaypointMarker = __esm({
9887
9870
  "components/game/2d/atoms/WaypointMarker.tsx"() {
9888
9871
  init_cn();
9889
9872
  init_Icon();
9873
+ init_Box();
9874
+ init_Typography();
9875
+ init_GameIcon();
9890
9876
  DEFAULT_ASSET_URL8 = {
9891
9877
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
9892
9878
  role: "ui",
9893
9879
  category: "waypoint"
9894
9880
  };
9895
- sizeMap9 = {
9881
+ sizeMap10 = {
9896
9882
  sm: { dot: "w-4 h-4", ring: "w-6 h-6", label: "text-xs mt-1", img: 12 },
9897
9883
  md: { dot: "w-6 h-6", ring: "w-8 h-8", label: "text-sm mt-1.5", img: 18 },
9898
9884
  lg: { dot: "w-8 h-8", ring: "w-10 h-10", label: "text-base mt-2", img: 24 }
@@ -9917,32 +9903,24 @@ function StatusEffect({
9917
9903
  size = "md",
9918
9904
  className
9919
9905
  }) {
9920
- const sizes = sizeMap10[size];
9921
- return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex flex-col items-center", className), children: [
9906
+ const sizes = sizeMap11[size];
9907
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn("inline-flex flex-col items-center", className), children: [
9922
9908
  /* @__PURE__ */ jsxs(
9923
- "div",
9909
+ Box,
9924
9910
  {
9911
+ position: "relative",
9925
9912
  className: cn(
9926
- "relative flex items-center justify-center rounded-interactive border-2",
9913
+ "flex items-center justify-center rounded-interactive border-2",
9927
9914
  sizes.container,
9928
9915
  variantStyles7[variant]
9929
9916
  ),
9930
9917
  title: label,
9931
9918
  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 }),
9919
+ /* @__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
9920
  duration !== void 0 && /* @__PURE__ */ jsx(
9944
- "span",
9921
+ Typography,
9945
9922
  {
9923
+ as: "span",
9946
9924
  className: cn(
9947
9925
  "absolute bottom-0 left-0 right-0 text-center font-mono font-bold text-foreground bg-background/60 leading-tight",
9948
9926
  sizes.timer
@@ -9954,8 +9932,9 @@ function StatusEffect({
9954
9932
  }
9955
9933
  ),
9956
9934
  stacks !== void 0 && stacks > 1 && /* @__PURE__ */ jsx(
9957
- "span",
9935
+ Typography,
9958
9936
  {
9937
+ as: "span",
9959
9938
  className: cn(
9960
9939
  "absolute flex items-center justify-center rounded-full bg-card text-foreground font-bold leading-none",
9961
9940
  sizes.badge
@@ -9963,20 +9942,23 @@ function StatusEffect({
9963
9942
  children: stacks
9964
9943
  }
9965
9944
  ),
9966
- label && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9945
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9967
9946
  ] });
9968
9947
  }
9969
- var DEFAULT_ASSET_URL9, sizeMap10, variantStyles7;
9948
+ var DEFAULT_ASSET_URL9, sizeMap11, variantStyles7;
9970
9949
  var init_StatusEffect = __esm({
9971
9950
  "components/game/2d/atoms/StatusEffect.tsx"() {
9972
9951
  init_cn();
9973
9952
  init_Icon();
9953
+ init_Box();
9954
+ init_Typography();
9955
+ init_GameIcon();
9974
9956
  DEFAULT_ASSET_URL9 = {
9975
9957
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
9976
9958
  role: "ui",
9977
9959
  category: "effect"
9978
9960
  };
9979
- sizeMap10 = {
9961
+ sizeMap11 = {
9980
9962
  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
9963
  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
9964
  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 +9982,31 @@ function DamageNumber({
10000
9982
  return /* @__PURE__ */ jsxs(Fragment, { children: [
10001
9983
  /* @__PURE__ */ jsx("style", { children: floatKeyframes }),
10002
9984
  /* @__PURE__ */ jsxs(
10003
- "span",
9985
+ Typography,
10004
9986
  {
9987
+ as: "span",
10005
9988
  className: cn(
10006
9989
  "inline-flex items-center gap-0.5 font-mono select-none pointer-events-none",
10007
- sizeMap11[size],
9990
+ sizeMap12[size],
10008
9991
  typeStyles[type],
10009
9992
  className
10010
9993
  ),
10011
9994
  style: { animation: "damageFloat 1s ease-out forwards" },
10012
9995
  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
- ),
9996
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 14, className: "flex-shrink-0" }),
10024
9997
  displayText
10025
9998
  ]
10026
9999
  }
10027
10000
  )
10028
10001
  ] });
10029
10002
  }
10030
- var sizeMap11, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
10003
+ var sizeMap12, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
10031
10004
  var init_DamageNumber = __esm({
10032
10005
  "components/game/2d/atoms/DamageNumber.tsx"() {
10033
10006
  init_cn();
10034
- sizeMap11 = {
10007
+ init_Typography();
10008
+ init_GameIcon();
10009
+ sizeMap12 = {
10035
10010
  sm: "text-sm",
10036
10011
  md: "text-lg",
10037
10012
  lg: "text-2xl"
@@ -10065,7 +10040,7 @@ function DialogueBubble({
10065
10040
  className
10066
10041
  }) {
10067
10042
  return /* @__PURE__ */ jsxs(
10068
- "div",
10043
+ Box,
10069
10044
  {
10070
10045
  className: cn(
10071
10046
  "flex items-start gap-3 rounded-container bg-background/80 backdrop-blur-sm px-4 py-3 border border-border/10",
@@ -10073,17 +10048,10 @@ function DialogueBubble({
10073
10048
  className
10074
10049
  ),
10075
10050
  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 })
10051
+ 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" }) }),
10052
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-1 min-w-0", children: [
10053
+ speaker && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm font-bold text-warning", children: speaker }),
10054
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm text-foreground leading-relaxed", children: text })
10087
10055
  ] })
10088
10056
  ]
10089
10057
  }
@@ -10093,6 +10061,9 @@ var DEFAULT_PORTRAIT;
10093
10061
  var init_DialogueBubble = __esm({
10094
10062
  "components/game/2d/atoms/DialogueBubble.tsx"() {
10095
10063
  init_cn();
10064
+ init_Box();
10065
+ init_Typography();
10066
+ init_GameIcon();
10096
10067
  DEFAULT_PORTRAIT = {
10097
10068
  url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
10098
10069
  role: "effect",
@@ -10114,11 +10085,11 @@ function ChoiceButton({
10114
10085
  }) {
10115
10086
  const eventBus = useEventBus();
10116
10087
  return /* @__PURE__ */ jsxs(
10117
- "button",
10088
+ Button,
10118
10089
  {
10119
- type: "button",
10090
+ variant: "ghost",
10120
10091
  disabled,
10121
- onClick: (e) => {
10092
+ onClick: () => {
10122
10093
  if (action) eventBus.emit(`UI:${action}`, {});
10123
10094
  onClick?.();
10124
10095
  },
@@ -10131,8 +10102,9 @@ function ChoiceButton({
10131
10102
  ),
10132
10103
  children: [
10133
10104
  index !== void 0 && /* @__PURE__ */ jsxs(
10134
- "span",
10105
+ Typography,
10135
10106
  {
10107
+ as: "span",
10136
10108
  className: cn(
10137
10109
  "flex-shrink-0 font-mono font-bold text-sm",
10138
10110
  selected ? "text-accent" : "text-muted-foreground"
@@ -10143,24 +10115,14 @@ function ChoiceButton({
10143
10115
  ]
10144
10116
  }
10145
10117
  ),
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" ? (() => {
10118
+ 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
10119
  const I = resolveIcon(icon);
10158
10120
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
10159
10121
  })() : /* @__PURE__ */ (() => {
10160
10122
  const I = icon;
10161
10123
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
10162
10124
  })() }) : null,
10163
- /* @__PURE__ */ jsx("span", { className: "text-sm leading-snug", children: text })
10125
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm leading-snug", children: text })
10164
10126
  ]
10165
10127
  }
10166
10128
  );
@@ -10170,6 +10132,10 @@ var init_ChoiceButton = __esm({
10170
10132
  init_cn();
10171
10133
  init_Icon();
10172
10134
  init_useEventBus();
10135
+ init_Button();
10136
+ init_Box();
10137
+ init_Typography();
10138
+ init_GameIcon();
10173
10139
  ChoiceButton.displayName = "ChoiceButton";
10174
10140
  }
10175
10141
  });
@@ -10187,16 +10153,16 @@ function ActionButton({
10187
10153
  className
10188
10154
  }) {
10189
10155
  const eventBus = useEventBus();
10190
- const sizes = sizeMap12[size];
10156
+ const sizes = sizeMap13[size];
10191
10157
  const onCooldown = cooldown > 0;
10192
10158
  const isDisabled = disabled || onCooldown;
10193
10159
  const cooldownDeg = Math.round(cooldown * 360);
10194
10160
  return /* @__PURE__ */ jsxs(
10195
- "button",
10161
+ Button,
10196
10162
  {
10197
- type: "button",
10163
+ variant: variant === "danger" ? "danger" : variant === "secondary" ? "secondary" : "primary",
10198
10164
  disabled: isDisabled,
10199
- onClick: (e) => {
10165
+ onClick: () => {
10200
10166
  if (action) eventBus.emit(`UI:${action}`, {});
10201
10167
  onClick?.();
10202
10168
  },
@@ -10209,9 +10175,10 @@ function ActionButton({
10209
10175
  ),
10210
10176
  children: [
10211
10177
  onCooldown && /* @__PURE__ */ jsx(
10212
- "div",
10178
+ Box,
10213
10179
  {
10214
- className: "absolute inset-0 bg-foreground/40 pointer-events-none",
10180
+ position: "absolute",
10181
+ className: "inset-0 bg-foreground/40 pointer-events-none",
10215
10182
  style: {
10216
10183
  clipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
10217
10184
  WebkitClipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
@@ -10219,27 +10186,18 @@ function ActionButton({
10219
10186
  }
10220
10187
  }
10221
10188
  ),
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" ? (() => {
10189
+ 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
10190
  const I = resolveIcon(icon);
10234
10191
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
10235
10192
  })() : /* @__PURE__ */ (() => {
10236
10193
  const I = icon;
10237
10194
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
10238
10195
  })() }) : null,
10239
- /* @__PURE__ */ jsx("span", { className: "relative z-10", children: label }),
10196
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "relative z-10", children: label }),
10240
10197
  hotkey && /* @__PURE__ */ jsx(
10241
- "span",
10198
+ Typography,
10242
10199
  {
10200
+ as: "span",
10243
10201
  className: cn(
10244
10202
  "absolute top-0.5 right-0.5 bg-foreground/30 text-primary-foreground rounded font-mono leading-tight",
10245
10203
  sizes.hotkey
@@ -10251,13 +10209,17 @@ function ActionButton({
10251
10209
  }
10252
10210
  );
10253
10211
  }
10254
- var sizeMap12, variantStyles8, DEFAULT_ASSET_URL11;
10212
+ var sizeMap13, variantStyles8, DEFAULT_ASSET_URL11;
10255
10213
  var init_ActionButton = __esm({
10256
10214
  "components/game/2d/atoms/ActionButton.tsx"() {
10257
10215
  init_cn();
10258
10216
  init_Icon();
10259
10217
  init_useEventBus();
10260
- sizeMap12 = {
10218
+ init_Button();
10219
+ init_Box();
10220
+ init_Typography();
10221
+ init_GameIcon();
10222
+ sizeMap13 = {
10261
10223
  sm: { button: "h-button-sm px-3 text-xs", hotkey: "text-[9px] px-1", icon: "text-xs" },
10262
10224
  md: { button: "h-button-md px-4 text-sm", hotkey: "text-xs px-1.5", icon: "text-sm" },
10263
10225
  lg: { button: "h-button-lg px-5 text-base", hotkey: "text-xs px-2", icon: "text-base" }
@@ -10359,10 +10321,12 @@ function MiniMap({
10359
10321
  return /* @__PURE__ */ jsxs(Fragment, { children: [
10360
10322
  /* @__PURE__ */ jsx("style", { children: `@keyframes minimap-blink{0%,49%{opacity:1}50%,100%{opacity:0}}` }),
10361
10323
  /* @__PURE__ */ jsxs(
10362
- "div",
10324
+ Box,
10363
10325
  {
10326
+ position: "relative",
10327
+ display: "inline-block",
10364
10328
  className: cn(
10365
- "relative inline-block border border-border/20 rounded-container",
10329
+ "border border-border/20 rounded-container",
10366
10330
  className
10367
10331
  ),
10368
10332
  children: [
@@ -10377,10 +10341,10 @@ function MiniMap({
10377
10341
  }
10378
10342
  ),
10379
10343
  playerLeft !== null && playerTop !== null && /* @__PURE__ */ jsx(
10380
- "div",
10344
+ Box,
10381
10345
  {
10346
+ position: "absolute",
10382
10347
  style: {
10383
- position: "absolute",
10384
10348
  left: playerLeft,
10385
10349
  top: playerTop,
10386
10350
  width: 3,
@@ -10401,6 +10365,7 @@ var init_MiniMap = __esm({
10401
10365
  "components/game/2d/atoms/MiniMap.tsx"() {
10402
10366
  "use client";
10403
10367
  init_cn();
10368
+ init_Box();
10404
10369
  DEFAULT_TILES = [
10405
10370
  { x: 10, y: 10, color: "#4ade80" },
10406
10371
  { x: 20, y: 15, color: "#4ade80" },
@@ -10418,38 +10383,6 @@ var init_MiniMap = __esm({
10418
10383
  MiniMap.displayName = "MiniMap";
10419
10384
  }
10420
10385
  });
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
10386
  function ControlGrid({
10454
10387
  kind,
10455
10388
  buttons = DEFAULT_BUTTONS,
@@ -10510,22 +10443,22 @@ function ControlGrid({
10510
10443
  },
10511
10444
  d
10512
10445
  );
10513
- return /* @__PURE__ */ jsxs("div", { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
10514
- /* @__PURE__ */ jsx("div", {}),
10446
+ return /* @__PURE__ */ jsxs(Box, { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
10447
+ /* @__PURE__ */ jsx(Box, {}),
10515
10448
  dir("up"),
10516
- /* @__PURE__ */ jsx("div", {}),
10449
+ /* @__PURE__ */ jsx(Box, {}),
10517
10450
  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" }) }),
10451
+ /* @__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
10452
  dir("right"),
10520
- /* @__PURE__ */ jsx("div", {}),
10453
+ /* @__PURE__ */ jsx(Box, {}),
10521
10454
  dir("down"),
10522
- /* @__PURE__ */ jsx("div", {})
10455
+ /* @__PURE__ */ jsx(Box, {})
10523
10456
  ] });
10524
10457
  }
10525
10458
  if (layout === "diamond" && buttons.length === 4) {
10526
10459
  const [top, right, bottom, left] = buttons;
10527
- return /* @__PURE__ */ jsxs("div", { className: cn(layoutClass.diamond, className), children: [
10528
- /* @__PURE__ */ jsx("div", {}),
10460
+ return /* @__PURE__ */ jsxs(Box, { className: cn(layoutClass.diamond, className), children: [
10461
+ /* @__PURE__ */ jsx(Box, {}),
10529
10462
  /* @__PURE__ */ jsx(
10530
10463
  ControlButton,
10531
10464
  {
@@ -10540,7 +10473,7 @@ function ControlGrid({
10540
10473
  disabled
10541
10474
  }
10542
10475
  ),
10543
- /* @__PURE__ */ jsx("div", {}),
10476
+ /* @__PURE__ */ jsx(Box, {}),
10544
10477
  /* @__PURE__ */ jsx(
10545
10478
  ControlButton,
10546
10479
  {
@@ -10555,7 +10488,7 @@ function ControlGrid({
10555
10488
  disabled
10556
10489
  }
10557
10490
  ),
10558
- /* @__PURE__ */ jsx("div", {}),
10491
+ /* @__PURE__ */ jsx(Box, {}),
10559
10492
  /* @__PURE__ */ jsx(
10560
10493
  ControlButton,
10561
10494
  {
@@ -10570,7 +10503,7 @@ function ControlGrid({
10570
10503
  disabled
10571
10504
  }
10572
10505
  ),
10573
- /* @__PURE__ */ jsx("div", {}),
10506
+ /* @__PURE__ */ jsx(Box, {}),
10574
10507
  /* @__PURE__ */ jsx(
10575
10508
  ControlButton,
10576
10509
  {
@@ -10585,10 +10518,10 @@ function ControlGrid({
10585
10518
  disabled
10586
10519
  }
10587
10520
  ),
10588
- /* @__PURE__ */ jsx("div", {})
10521
+ /* @__PURE__ */ jsx(Box, {})
10589
10522
  ] });
10590
10523
  }
10591
- return /* @__PURE__ */ jsx("div", { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
10524
+ return /* @__PURE__ */ jsx(Box, { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
10592
10525
  ControlButton,
10593
10526
  {
10594
10527
  icon: button.icon,
@@ -10610,6 +10543,7 @@ var init_ControlGrid = __esm({
10610
10543
  "use client";
10611
10544
  init_cn();
10612
10545
  init_useEventBus();
10546
+ init_Box();
10613
10547
  init_ControlButton();
10614
10548
  sizeKey = { sm: "sm", md: "md", lg: "lg" };
10615
10549
  layoutClass = {
@@ -10654,7 +10588,7 @@ function StatBadge({
10654
10588
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
10655
10589
  const resolvedAsset = iconUrl ?? assetUrl;
10656
10590
  return /* @__PURE__ */ jsxs(
10657
- "div",
10591
+ Box,
10658
10592
  {
10659
10593
  className: cn(
10660
10594
  "inline-flex items-center gap-2 rounded-container border backdrop-blur-sm",
@@ -10663,18 +10597,8 @@ function StatBadge({
10663
10597
  className
10664
10598
  ),
10665
10599
  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 }),
10600
+ 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,
10601
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground font-medium", children: label }),
10678
10602
  format === "hearts" && max && /* @__PURE__ */ jsx(
10679
10603
  HealthBar,
10680
10604
  {
@@ -10700,7 +10624,7 @@ function StatBadge({
10700
10624
  size: size === "lg" ? "md" : "sm"
10701
10625
  }
10702
10626
  ),
10703
- format === "text" && /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground", children: value })
10627
+ format === "text" && /* @__PURE__ */ jsx(Typography, { as: "span", className: "font-bold text-foreground", children: value })
10704
10628
  ]
10705
10629
  }
10706
10630
  );
@@ -10710,6 +10634,9 @@ var init_StatBadge = __esm({
10710
10634
  "components/game/2d/molecules/StatBadge.tsx"() {
10711
10635
  init_cn();
10712
10636
  init_Icon();
10637
+ init_Box();
10638
+ init_Typography();
10639
+ init_GameIcon();
10713
10640
  init_HealthBar();
10714
10641
  init_ScoreDisplay();
10715
10642
  sizeMap14 = {
@@ -10887,9 +10814,9 @@ function GameHud({
10887
10814
  if (position === "corners") {
10888
10815
  const leftStats = stats.slice(0, Math.ceil(stats.length / 2));
10889
10816
  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)) })
10817
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn(positionMap[position], className), children: [
10818
+ /* @__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)) }),
10819
+ /* @__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
10820
  ] });
10894
10821
  }
10895
10822
  if (position === "top" || position === "bottom") {
@@ -10898,7 +10825,7 @@ function GameHud({
10898
10825
  const rightStats = stats.slice(mid);
10899
10826
  const isTop = position === "top";
10900
10827
  return /* @__PURE__ */ jsxs(
10901
- "div",
10828
+ Box,
10902
10829
  {
10903
10830
  className: cn(
10904
10831
  "flex items-center justify-between w-full",
@@ -10908,17 +10835,18 @@ function GameHud({
10908
10835
  className
10909
10836
  ),
10910
10837
  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)) })
10838
+ /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10839
+ 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
10840
  ]
10914
10841
  }
10915
10842
  );
10916
10843
  }
10917
10844
  return /* @__PURE__ */ jsx(
10918
- "div",
10845
+ Box,
10919
10846
  {
10847
+ position: "relative",
10920
10848
  className: cn(
10921
- "relative z-10 flex items-center gap-4 px-4 py-2",
10849
+ "z-10 flex items-center gap-4 px-4 py-2",
10922
10850
  transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
10923
10851
  className
10924
10852
  ),
@@ -10930,6 +10858,7 @@ var positionMap, DEFAULT_HUD_STATS;
10930
10858
  var init_GameHud = __esm({
10931
10859
  "components/game/2d/molecules/GameHud.tsx"() {
10932
10860
  init_cn();
10861
+ init_Box();
10933
10862
  init_StatBadge();
10934
10863
  positionMap = {
10935
10864
  corners: "inset-0 pointer-events-none"
@@ -10970,7 +10899,7 @@ function GameMenu({
10970
10899
  [eventBus, onSelect]
10971
10900
  );
10972
10901
  return /* @__PURE__ */ jsxs(
10973
- "div",
10902
+ Box,
10974
10903
  {
10975
10904
  className: cn(
10976
10905
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
@@ -10980,18 +10909,12 @@ function GameMenu({
10980
10909
  background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
10981
10910
  },
10982
10911
  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
- ),
10912
+ /* @__PURE__ */ jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
10913
+ 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
10914
  /* @__PURE__ */ jsx(
10993
- "h1",
10915
+ Typography,
10994
10916
  {
10917
+ variant: "h1",
10995
10918
  className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
10996
10919
  style: {
10997
10920
  textShadow: "0 4px 12px rgba(0,0,0,0.5)"
@@ -10999,9 +10922,9 @@ function GameMenu({
10999
10922
  children: title
11000
10923
  }
11001
10924
  ),
11002
- subtitle && /* @__PURE__ */ jsx("p", { className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
10925
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
11003
10926
  ] }),
11004
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
10927
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
11005
10928
  ChoiceButton,
11006
10929
  {
11007
10930
  text: option.label,
@@ -11012,9 +10935,9 @@ function GameMenu({
11012
10935
  },
11013
10936
  index
11014
10937
  )) }),
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" })
10938
+ /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
10939
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
10940
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
11018
10941
  ] })
11019
10942
  ]
11020
10943
  }
@@ -11026,6 +10949,9 @@ var init_GameMenu = __esm({
11026
10949
  "use client";
11027
10950
  init_cn();
11028
10951
  init_useEventBus();
10952
+ init_Box();
10953
+ init_Typography();
10954
+ init_GameIcon();
11029
10955
  init_ChoiceButton();
11030
10956
  DEFAULT_MENU_OPTIONS = [
11031
10957
  { label: "New Game", event: "NEW_GAME", variant: "primary" },
@@ -12266,10 +12192,11 @@ function Canvas2D({
12266
12192
  }
12267
12193
  }
12268
12194
  ),
12269
- process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs("div", { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
12195
+ process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs(Box, { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
12270
12196
  tileClickEvent && /* @__PURE__ */ jsx(
12271
- "button",
12197
+ Button,
12272
12198
  {
12199
+ variant: "ghost",
12273
12200
  "data-event": tileClickEvent,
12274
12201
  "data-x": "0",
12275
12202
  "data-y": "0",
@@ -12278,8 +12205,9 @@ function Canvas2D({
12278
12205
  }
12279
12206
  ),
12280
12207
  unitClickEvent && units && units.length > 0 && /* @__PURE__ */ jsx(
12281
- "button",
12208
+ Button,
12282
12209
  {
12210
+ variant: "ghost",
12283
12211
  "data-event": unitClickEvent,
12284
12212
  "data-unit-id": units[0].id,
12285
12213
  onClick: () => eventBus.emit(`UI:${unitClickEvent}`, { unitId: units[0].id }),
@@ -12288,15 +12216,17 @@ function Canvas2D({
12288
12216
  )
12289
12217
  ] }),
12290
12218
  unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxs(
12291
- "div",
12219
+ Box,
12292
12220
  {
12293
- className: "absolute pointer-events-none",
12221
+ position: "absolute",
12222
+ className: "pointer-events-none",
12294
12223
  style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
12295
12224
  children: [
12296
12225
  unit.name && /* @__PURE__ */ jsx(
12297
- "div",
12226
+ Typography,
12298
12227
  {
12299
- className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
12228
+ as: "span",
12229
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap block",
12300
12230
  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
12231
  children: unit.name
12302
12232
  }
@@ -12306,7 +12236,7 @@ function Canvas2D({
12306
12236
  },
12307
12237
  unit.id
12308
12238
  )),
12309
- showMinimap && /* @__PURE__ */ jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
12239
+ showMinimap && /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
12310
12240
  MiniMap,
12311
12241
  {
12312
12242
  tiles: miniMapTiles,
@@ -12328,6 +12258,7 @@ var init_Canvas2D = __esm({
12328
12258
  init_cn();
12329
12259
  init_useEventBus();
12330
12260
  init_Box();
12261
+ init_Button();
12331
12262
  init_Stack();
12332
12263
  init_Icon();
12333
12264
  init_Typography();
@@ -12659,7 +12590,7 @@ function GameAudioToggle({
12659
12590
  onClick: handleToggle,
12660
12591
  className: cn("text-lg leading-none px-2", className),
12661
12592
  "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}"
12593
+ 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
12594
  }
12664
12595
  );
12665
12596
  }
@@ -12669,6 +12600,7 @@ var init_GameAudioToggle = __esm({
12669
12600
  init_atoms();
12670
12601
  init_cn();
12671
12602
  init_GameAudioProvider();
12603
+ init_GameIcon();
12672
12604
  GameAudioToggle.displayName = "GameAudioToggle";
12673
12605
  }
12674
12606
  });