@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.
package/dist/avl/index.js CHANGED
@@ -12111,6 +12111,38 @@ var init_shared = __esm({
12111
12111
  init_canvasEffects();
12112
12112
  }
12113
12113
  });
12114
+ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
12115
+ const px = typeof size === "number" ? size : sizeMap[size];
12116
+ if (assetUrl?.url) {
12117
+ return /* @__PURE__ */ jsx(
12118
+ "img",
12119
+ {
12120
+ src: assetUrl.url,
12121
+ alt: alt ?? assetUrl.category ?? "",
12122
+ width: px,
12123
+ height: px,
12124
+ style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
12125
+ className: cn("flex-shrink-0", className)
12126
+ }
12127
+ );
12128
+ }
12129
+ const I = typeof icon === "string" ? resolveIcon(icon) : icon;
12130
+ return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
12131
+ }
12132
+ var sizeMap;
12133
+ var init_GameIcon = __esm({
12134
+ "components/game/2d/atoms/GameIcon.tsx"() {
12135
+ "use client";
12136
+ init_cn();
12137
+ init_Icon();
12138
+ sizeMap = {
12139
+ sm: 16,
12140
+ md: 24,
12141
+ lg: 32
12142
+ };
12143
+ GameIcon.displayName = "GameIcon";
12144
+ }
12145
+ });
12114
12146
  function GameCard({
12115
12147
  id,
12116
12148
  cost,
@@ -12133,9 +12165,9 @@ function GameCard({
12133
12165
  }, [disabled, id, onClick, clickEvent, eventBus]);
12134
12166
  const artPx = artPxMap[size];
12135
12167
  return /* @__PURE__ */ jsxs(
12136
- "button",
12168
+ Button,
12137
12169
  {
12138
- type: "button",
12170
+ variant: "ghost",
12139
12171
  onClick: handleClick,
12140
12172
  disabled,
12141
12173
  title: name,
@@ -12149,8 +12181,9 @@ function GameCard({
12149
12181
  ),
12150
12182
  children: [
12151
12183
  cost != null && /* @__PURE__ */ jsx(
12152
- "span",
12184
+ Typography,
12153
12185
  {
12186
+ as: "span",
12154
12187
  className: cn(
12155
12188
  "absolute -top-2 -left-2 flex items-center justify-center",
12156
12189
  "min-w-[22px] h-[22px] rounded-full px-1",
@@ -12159,17 +12192,7 @@ function GameCard({
12159
12192
  children: cost
12160
12193
  }
12161
12194
  ),
12162
- /* @__PURE__ */ jsx(Box, { className: "flex-1 flex items-center justify-center w-full", children: art ? /* @__PURE__ */ jsx(
12163
- "img",
12164
- {
12165
- src: art.url,
12166
- alt: name ?? id,
12167
- width: artPx,
12168
- height: artPx,
12169
- style: { imageRendering: "pixelated", objectFit: "contain" },
12170
- className: "flex-shrink-0"
12171
- }
12172
- ) : /* @__PURE__ */ jsx(Box, { className: "rounded bg-muted/40", style: { width: artPx, height: artPx } }) }),
12195
+ /* @__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 } }) }),
12173
12196
  name != null && /* @__PURE__ */ jsx(
12174
12197
  Typography,
12175
12198
  {
@@ -12179,8 +12202,8 @@ function GameCard({
12179
12202
  }
12180
12203
  ),
12181
12204
  (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: [
12182
- /* @__PURE__ */ jsx("span", { className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
12183
- /* @__PURE__ */ jsx("span", { className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
12205
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
12206
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
12184
12207
  ] })
12185
12208
  ]
12186
12209
  }
@@ -12193,7 +12216,9 @@ var init_GameCard = __esm({
12193
12216
  init_cn();
12194
12217
  init_useEventBus();
12195
12218
  init_Box();
12219
+ init_Button();
12196
12220
  init_Typography();
12221
+ init_GameIcon();
12197
12222
  cardSizeMap = {
12198
12223
  sm: "w-16 h-24",
12199
12224
  md: "w-20 h-28",
@@ -12216,12 +12241,13 @@ function HealthBar({
12216
12241
  frameAsset,
12217
12242
  fillAsset
12218
12243
  }) {
12219
- const sizes = sizeMap[size];
12244
+ const sizes = sizeMap2[size];
12220
12245
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
12221
12246
  if (format === "hearts") {
12222
- return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
12223
- "span",
12247
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
12248
+ Box,
12224
12249
  {
12250
+ as: "span",
12225
12251
  className: cn(animated && "transition-transform hover:scale-110"),
12226
12252
  children: heartIcon(i < current, sizes.heart)
12227
12253
  },
@@ -12230,10 +12256,12 @@ function HealthBar({
12230
12256
  }
12231
12257
  if (format === "bar") {
12232
12258
  return /* @__PURE__ */ jsx(
12233
- "div",
12259
+ Box,
12234
12260
  {
12261
+ position: "relative",
12262
+ overflow: "hidden",
12235
12263
  className: cn(
12236
- "relative overflow-hidden rounded-full",
12264
+ "rounded-full",
12237
12265
  !frameAsset && "bg-muted",
12238
12266
  sizes.bar,
12239
12267
  "w-24",
@@ -12241,10 +12269,11 @@ function HealthBar({
12241
12269
  ),
12242
12270
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
12243
12271
  children: /* @__PURE__ */ jsx(
12244
- "div",
12272
+ Box,
12245
12273
  {
12274
+ position: "absolute",
12246
12275
  className: cn(
12247
- "absolute inset-y-0 left-0 rounded-full",
12276
+ "inset-y-0 left-0 rounded-full",
12248
12277
  !fillAsset && (percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error"),
12249
12278
  animated && "transition-all duration-300"
12250
12279
  ),
@@ -12258,10 +12287,11 @@ function HealthBar({
12258
12287
  );
12259
12288
  }
12260
12289
  if (format === "progress") {
12261
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
12290
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex items-center gap-2", className), children: [
12262
12291
  level != null && /* @__PURE__ */ jsxs(
12263
- "span",
12292
+ Typography,
12264
12293
  {
12294
+ as: "span",
12265
12295
  className: cn(
12266
12296
  "flex-shrink-0 rounded-interactive font-bold",
12267
12297
  "bg-accent text-accent-foreground border border-accent",
@@ -12273,21 +12303,23 @@ function HealthBar({
12273
12303
  ]
12274
12304
  }
12275
12305
  ),
12276
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [
12306
+ /* @__PURE__ */ jsxs(Box, { className: "flex-1 flex flex-col gap-0.5", children: [
12277
12307
  /* @__PURE__ */ jsx(
12278
- "div",
12308
+ Box,
12279
12309
  {
12310
+ position: "relative",
12280
12311
  className: cn(
12281
- "relative w-full overflow-hidden rounded-full",
12312
+ "w-full overflow-hidden rounded-full",
12282
12313
  !frameAsset && "bg-muted border border-muted",
12283
12314
  sizes.bar
12284
12315
  ),
12285
12316
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
12286
12317
  children: /* @__PURE__ */ jsx(
12287
- "div",
12318
+ Box,
12288
12319
  {
12320
+ position: "absolute",
12289
12321
  className: cn(
12290
- "absolute inset-y-0 left-0 rounded-full",
12322
+ "inset-y-0 left-0 rounded-full",
12291
12323
  !fillAsset && "bg-gradient-to-r from-accent to-info",
12292
12324
  animated && "transition-all duration-500 ease-out"
12293
12325
  ),
@@ -12299,7 +12331,7 @@ function HealthBar({
12299
12331
  )
12300
12332
  }
12301
12333
  ),
12302
- showLabel && /* @__PURE__ */ jsxs("span", { className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
12334
+ showLabel && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
12303
12335
  current,
12304
12336
  " / ",
12305
12337
  max,
@@ -12308,16 +12340,18 @@ function HealthBar({
12308
12340
  ] })
12309
12341
  ] });
12310
12342
  }
12311
- return /* @__PURE__ */ jsxs("span", { className: cn("font-mono font-bold", sizes.text, className), children: [
12343
+ return /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-mono font-bold", sizes.text, className), children: [
12312
12344
  current,
12313
12345
  "/",
12314
12346
  max
12315
12347
  ] });
12316
12348
  }
12317
- var heartIcon, sizeMap;
12349
+ var heartIcon, sizeMap2;
12318
12350
  var init_HealthBar = __esm({
12319
12351
  "components/game/2d/atoms/HealthBar.tsx"() {
12320
12352
  init_cn();
12353
+ init_Box();
12354
+ init_Typography();
12321
12355
  heartIcon = (filled, size) => /* @__PURE__ */ jsx(
12322
12356
  "svg",
12323
12357
  {
@@ -12329,7 +12363,7 @@ var init_HealthBar = __esm({
12329
12363
  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" })
12330
12364
  }
12331
12365
  );
12332
- sizeMap = {
12366
+ sizeMap2 = {
12333
12367
  sm: { heart: "w-4 h-4", bar: "h-2", text: "text-sm", label: "text-xs", badge: "text-xs px-1.5 py-0.5" },
12334
12368
  md: { heart: "w-6 h-6", bar: "h-3", text: "text-base", label: "text-xs", badge: "text-xs px-2 py-0.5" },
12335
12369
  lg: { heart: "w-8 h-8", bar: "h-4", text: "text-lg", label: "text-sm", badge: "text-sm px-2.5 py-1" }
@@ -12350,37 +12384,30 @@ function ScoreDisplay({
12350
12384
  const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
12351
12385
  const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
12352
12386
  return /* @__PURE__ */ jsxs(
12353
- "div",
12387
+ Box,
12354
12388
  {
12355
12389
  className: cn(
12356
12390
  "flex items-center gap-2 font-bold",
12357
- sizeMap2[size],
12391
+ sizeMap3[size],
12358
12392
  className
12359
12393
  ),
12360
12394
  children: [
12361
- assetUrl ? /* @__PURE__ */ jsx(
12362
- "img",
12363
- {
12364
- src: assetUrl.url,
12365
- alt: "",
12366
- width: 20,
12367
- height: 20,
12368
- style: { imageRendering: "pixelated", objectFit: "contain" },
12369
- className: "flex-shrink-0"
12370
- }
12371
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
12372
- label && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
12373
- /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formattedValue })
12395
+ 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,
12396
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
12397
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "tabular-nums", children: formattedValue })
12374
12398
  ]
12375
12399
  }
12376
12400
  );
12377
12401
  }
12378
- var sizeMap2, DEFAULT_ASSET_URL;
12402
+ var sizeMap3, DEFAULT_ASSET_URL;
12379
12403
  var init_ScoreDisplay = __esm({
12380
12404
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
12381
12405
  init_cn();
12382
12406
  init_Icon();
12383
- sizeMap2 = {
12407
+ init_Box();
12408
+ init_Typography();
12409
+ init_GameIcon();
12410
+ sizeMap3 = {
12384
12411
  sm: "text-sm",
12385
12412
  md: "text-lg",
12386
12413
  lg: "text-2xl",
@@ -12443,9 +12470,9 @@ function ControlButton({
12443
12470
  [isPressed, releaseEvent, eventBus, onRelease]
12444
12471
  );
12445
12472
  return /* @__PURE__ */ jsx(
12446
- "button",
12473
+ Button,
12447
12474
  {
12448
- type: "button",
12475
+ variant,
12449
12476
  disabled,
12450
12477
  onPointerDown: handlePointerDown,
12451
12478
  onPointerUp: handlePointerUp,
@@ -12456,41 +12483,35 @@ function ControlButton({
12456
12483
  "select-none touch-none",
12457
12484
  "transition-all duration-100",
12458
12485
  "active:scale-95",
12459
- sizeMap3[size] ?? sizeMap3.md,
12486
+ sizeMap4[size] ?? sizeMap4.md,
12460
12487
  shapeMap[shape] ?? shapeMap.circle,
12461
12488
  variantMap[variant] ?? variantMap.secondary,
12462
12489
  actualPressed && "scale-95 brightness-110 border-foreground",
12463
12490
  disabled && "opacity-50 cursor-not-allowed",
12464
12491
  className
12465
12492
  ),
12466
- children: assetUrl ? /* @__PURE__ */ jsx(
12467
- "img",
12468
- {
12469
- src: assetUrl.url,
12470
- alt: "",
12471
- width: 24,
12472
- height: 24,
12473
- style: { imageRendering: "pixelated", objectFit: "contain" },
12474
- className: "flex-shrink-0"
12475
- }
12476
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
12493
+ 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) ? (() => {
12477
12494
  const I = resolveIcon(icon);
12478
12495
  return I ? /* @__PURE__ */ jsx(I, { className: "w-6 h-6" }) : null;
12479
12496
  })() : icon : /* @__PURE__ */ (() => {
12480
12497
  const I = icon;
12481
12498
  return /* @__PURE__ */ jsx(I, { className: "w-6 h-6" });
12482
- })() }) : label ? /* @__PURE__ */ jsx("span", { children: label }) : null
12499
+ })() }) : label ? /* @__PURE__ */ jsx(Typography, { as: "span", children: label }) : null
12483
12500
  }
12484
12501
  );
12485
12502
  }
12486
- var sizeMap3, shapeMap, variantMap, DEFAULT_ASSET_URL2;
12503
+ var sizeMap4, shapeMap, variantMap, DEFAULT_ASSET_URL2;
12487
12504
  var init_ControlButton = __esm({
12488
12505
  "components/game/2d/atoms/ControlButton.tsx"() {
12489
12506
  "use client";
12490
12507
  init_cn();
12491
12508
  init_useEventBus();
12492
12509
  init_Icon();
12493
- sizeMap3 = {
12510
+ init_Button();
12511
+ init_Box();
12512
+ init_Typography();
12513
+ init_GameIcon();
12514
+ sizeMap4 = {
12494
12515
  sm: "w-10 h-10 text-sm",
12495
12516
  md: "w-14 h-14 text-base",
12496
12517
  lg: "w-18 h-18 text-lg",
@@ -12560,12 +12581,12 @@ function Sprite({
12560
12581
  onClick?.();
12561
12582
  };
12562
12583
  return /* @__PURE__ */ jsx(
12563
- "div",
12584
+ Box,
12564
12585
  {
12586
+ position: "absolute",
12565
12587
  className,
12566
12588
  onClick: action || onClick ? handleClick : void 0,
12567
12589
  style: {
12568
- position: "absolute",
12569
12590
  width: frameWidth,
12570
12591
  height: frameHeight,
12571
12592
  backgroundImage: `url(${spritesheet.url})`,
@@ -12586,6 +12607,7 @@ var init_Sprite = __esm({
12586
12607
  "components/game/2d/atoms/Sprite.tsx"() {
12587
12608
  "use client";
12588
12609
  init_useEventBus();
12610
+ init_Box();
12589
12611
  init_spriteAnimation();
12590
12612
  DEFAULT_SPRITESHEET = {
12591
12613
  url: "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
@@ -12622,17 +12644,7 @@ function StateIndicator({
12622
12644
  className
12623
12645
  ),
12624
12646
  children: [
12625
- /* @__PURE__ */ jsx(Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsx(
12626
- "img",
12627
- {
12628
- src: assetUrl.url,
12629
- alt: displayLabel,
12630
- width: 16,
12631
- height: 16,
12632
- style: { imageRendering: "pixelated", objectFit: "contain" },
12633
- className: "flex-shrink-0"
12634
- }
12635
- ) : 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 }) }),
12647
+ /* @__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 }) }),
12636
12648
  /* @__PURE__ */ jsx(Box, { as: "span", children: displayLabel })
12637
12649
  ]
12638
12650
  }
@@ -12644,6 +12656,7 @@ var init_StateIndicator = __esm({
12644
12656
  init_Box();
12645
12657
  init_Icon();
12646
12658
  init_cn();
12659
+ init_GameIcon();
12647
12660
  DEFAULT_ASSET_URL3 = {
12648
12661
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
12649
12662
  role: "ui",
@@ -12697,29 +12710,31 @@ function TimerDisplay({
12697
12710
  }) {
12698
12711
  const isLow = lowThreshold != null && seconds <= lowThreshold && seconds > 0;
12699
12712
  return /* @__PURE__ */ jsxs(
12700
- "div",
12713
+ Box,
12701
12714
  {
12702
12715
  className: cn(
12703
12716
  "inline-flex items-center gap-1 justify-center rounded-container",
12704
12717
  "bg-card/80 border border-muted font-mono font-bold tabular-nums",
12705
- sizeMap4[size],
12718
+ sizeMap5[size],
12706
12719
  running && "border-success/50",
12707
12720
  isLow && "text-error border-error/50 animate-pulse",
12708
12721
  !isLow && "text-foreground",
12709
12722
  className
12710
12723
  ),
12711
12724
  children: [
12712
- iconAsset && /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: "", className: "w-4 h-4 object-contain flex-shrink-0" }),
12725
+ iconAsset && /* @__PURE__ */ jsx(GameIcon, { assetUrl: iconAsset, icon: "image", size: 16, className: "w-4 h-4 object-contain flex-shrink-0" }),
12713
12726
  formatTime(seconds, format)
12714
12727
  ]
12715
12728
  }
12716
12729
  );
12717
12730
  }
12718
- var sizeMap4;
12731
+ var sizeMap5;
12719
12732
  var init_TimerDisplay = __esm({
12720
12733
  "components/game/2d/atoms/TimerDisplay.tsx"() {
12721
12734
  init_cn();
12722
- sizeMap4 = {
12735
+ init_Box();
12736
+ init_GameIcon();
12737
+ sizeMap5 = {
12723
12738
  sm: "text-sm px-2 py-0.5",
12724
12739
  md: "text-lg px-3 py-1",
12725
12740
  lg: "text-2xl px-4 py-1.5"
@@ -12737,9 +12752,9 @@ function ResourceCounter({
12737
12752
  size = "md",
12738
12753
  className
12739
12754
  }) {
12740
- const sizes = sizeMap5[size];
12755
+ const sizes = sizeMap6[size];
12741
12756
  return /* @__PURE__ */ jsxs(
12742
- "div",
12757
+ Box,
12743
12758
  {
12744
12759
  className: cn(
12745
12760
  "inline-flex items-center rounded-container",
@@ -12748,21 +12763,11 @@ function ResourceCounter({
12748
12763
  className
12749
12764
  ),
12750
12765
  children: [
12751
- assetUrl ? /* @__PURE__ */ jsx(
12752
- "img",
12753
- {
12754
- src: assetUrl.url,
12755
- alt: label,
12756
- width: sizes.img,
12757
- height: sizes.img,
12758
- style: { imageRendering: "pixelated", objectFit: "contain" },
12759
- className: "flex-shrink-0"
12760
- }
12761
- ) : 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,
12762
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
12763
- /* @__PURE__ */ jsxs("span", { className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
12766
+ 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,
12767
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
12768
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
12764
12769
  value,
12765
- max != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
12770
+ max != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
12766
12771
  "/",
12767
12772
  max
12768
12773
  ] })
@@ -12771,11 +12776,14 @@ function ResourceCounter({
12771
12776
  }
12772
12777
  );
12773
12778
  }
12774
- var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap5;
12779
+ var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap6;
12775
12780
  var init_ResourceCounter = __esm({
12776
12781
  "components/game/2d/atoms/ResourceCounter.tsx"() {
12777
12782
  init_cn();
12778
12783
  init_Icon();
12784
+ init_Box();
12785
+ init_Typography();
12786
+ init_GameIcon();
12779
12787
  colorTokenClasses2 = {
12780
12788
  primary: "text-primary",
12781
12789
  secondary: "text-secondary",
@@ -12789,7 +12797,7 @@ var init_ResourceCounter = __esm({
12789
12797
  role: "ui",
12790
12798
  category: "coin"
12791
12799
  };
12792
- sizeMap5 = {
12800
+ sizeMap6 = {
12793
12801
  sm: { wrapper: "text-xs gap-1 px-1.5 py-0.5", icon: "text-sm", img: 16 },
12794
12802
  md: { wrapper: "text-sm gap-1.5 px-2 py-1", icon: "text-base", img: 20 },
12795
12803
  lg: { wrapper: "text-base gap-2 px-3 py-1.5", icon: "text-lg", img: 28 }
@@ -12814,9 +12822,9 @@ function ItemSlot({
12814
12822
  const isClickable = onClick != null || action != null;
12815
12823
  const px = assetSizeMap[size];
12816
12824
  return /* @__PURE__ */ jsx(
12817
- "button",
12825
+ Button,
12818
12826
  {
12819
- type: "button",
12827
+ variant: "ghost",
12820
12828
  onClick: () => {
12821
12829
  if (action) eventBus.emit(`UI:${action}`, {});
12822
12830
  onClick?.();
@@ -12826,7 +12834,7 @@ function ItemSlot({
12826
12834
  className: cn(
12827
12835
  "relative flex items-center justify-center rounded-interactive border-2",
12828
12836
  "bg-card/80 transition-all duration-150",
12829
- sizeMap6[size],
12837
+ sizeMap7[size],
12830
12838
  empty ? "border-border bg-card/50" : rarityBorderMap[rarity],
12831
12839
  !empty && rarityGlowMap[rarity],
12832
12840
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background",
@@ -12835,21 +12843,12 @@ function ItemSlot({
12835
12843
  !isClickable && "cursor-default",
12836
12844
  className
12837
12845
  ),
12838
- children: empty ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
12839
- assetUrl ? /* @__PURE__ */ jsx(
12840
- "img",
12841
- {
12842
- src: assetUrl?.url,
12843
- alt: label,
12844
- width: px,
12845
- height: px,
12846
- style: { imageRendering: "pixelated", objectFit: "contain" },
12847
- className: "flex-shrink-0"
12848
- }
12849
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
12846
+ children: empty ? /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
12847
+ 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,
12850
12848
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
12851
- "span",
12849
+ Typography,
12852
12850
  {
12851
+ as: "span",
12853
12852
  className: cn(
12854
12853
  "absolute -bottom-1 -right-1 flex items-center justify-center",
12855
12854
  "min-w-[18px] h-[18px] rounded-full px-1",
@@ -12862,14 +12861,18 @@ function ItemSlot({
12862
12861
  }
12863
12862
  );
12864
12863
  }
12865
- var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
12864
+ var sizeMap7, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
12866
12865
  var init_ItemSlot = __esm({
12867
12866
  "components/game/2d/atoms/ItemSlot.tsx"() {
12868
12867
  "use client";
12869
12868
  init_cn();
12870
12869
  init_Icon();
12871
12870
  init_useEventBus();
12872
- sizeMap6 = {
12871
+ init_Button();
12872
+ init_Box();
12873
+ init_Typography();
12874
+ init_GameIcon();
12875
+ sizeMap7 = {
12873
12876
  sm: "w-10 h-10 text-lg",
12874
12877
  md: "w-14 h-14 text-2xl",
12875
12878
  lg: "w-18 h-18 text-3xl"
@@ -12910,9 +12913,9 @@ function TurnIndicator({
12910
12913
  size = "md",
12911
12914
  className
12912
12915
  }) {
12913
- const sizes = sizeMap7[size];
12916
+ const sizes = sizeMap8[size];
12914
12917
  return /* @__PURE__ */ jsxs(
12915
- "div",
12918
+ Box,
12916
12919
  {
12917
12920
  className: cn(
12918
12921
  "inline-flex items-center rounded-container",
@@ -12921,42 +12924,35 @@ function TurnIndicator({
12921
12924
  className
12922
12925
  ),
12923
12926
  children: [
12924
- /* @__PURE__ */ jsxs("span", { className: "font-bold tabular-nums", children: [
12927
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: "font-bold tabular-nums", children: [
12925
12928
  "Turn ",
12926
12929
  currentTurn,
12927
- maxTurns != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
12930
+ maxTurns != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
12928
12931
  "/",
12929
12932
  maxTurns
12930
12933
  ] })
12931
12934
  ] }),
12932
12935
  phase && /* @__PURE__ */ jsxs(Fragment, { children: [
12933
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
12934
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: phase })
12936
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
12937
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: phase })
12935
12938
  ] }),
12936
12939
  activeTeam && /* @__PURE__ */ jsxs(Fragment, { children: [
12937
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
12938
- assetUrl ? /* @__PURE__ */ jsx(
12939
- "img",
12940
- {
12941
- src: assetUrl.url,
12942
- alt: "",
12943
- width: 12,
12944
- height: 12,
12945
- style: { imageRendering: "pixelated", objectFit: "contain" },
12946
- className: "flex-shrink-0"
12947
- }
12948
- ) : /* @__PURE__ */ jsx("span", { className: cn("rounded-full bg-success/20", sizes.dot) }),
12949
- /* @__PURE__ */ jsx("span", { className: "text-success", children: activeTeam })
12940
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
12941
+ 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) }),
12942
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-success", children: activeTeam })
12950
12943
  ] })
12951
12944
  ]
12952
12945
  }
12953
12946
  );
12954
12947
  }
12955
- var sizeMap7, DEFAULT_ASSET_URL6;
12948
+ var sizeMap8, DEFAULT_ASSET_URL6;
12956
12949
  var init_TurnIndicator = __esm({
12957
12950
  "components/game/2d/atoms/TurnIndicator.tsx"() {
12958
12951
  init_cn();
12959
- sizeMap7 = {
12952
+ init_Box();
12953
+ init_Typography();
12954
+ init_GameIcon();
12955
+ sizeMap8 = {
12960
12956
  sm: { wrapper: "text-xs gap-1.5 px-2 py-0.5", dot: "w-1.5 h-1.5" },
12961
12957
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
12962
12958
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
@@ -12988,10 +12984,10 @@ function ComboCounter({
12988
12984
  size = "md",
12989
12985
  className
12990
12986
  }) {
12991
- const sizes = sizeMap8[size];
12987
+ const sizes = sizeMap9[size];
12992
12988
  if (combo <= 0) return null;
12993
12989
  return /* @__PURE__ */ jsxs(
12994
- "div",
12990
+ Box,
12995
12991
  {
12996
12992
  className: cn(
12997
12993
  "inline-flex flex-col items-center justify-center",
@@ -13001,24 +12997,14 @@ function ComboCounter({
13001
12997
  className
13002
12998
  ),
13003
12999
  children: [
13004
- assetUrl && /* @__PURE__ */ jsx(
13005
- "img",
13006
- {
13007
- src: assetUrl.url,
13008
- alt: "combo",
13009
- width: 24,
13010
- height: 24,
13011
- style: { imageRendering: "pixelated", objectFit: "contain" },
13012
- className: "flex-shrink-0 mb-0.5"
13013
- }
13014
- ),
13015
- /* @__PURE__ */ jsx("span", { className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
13016
- /* @__PURE__ */ jsx("span", { className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
13017
- multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs("span", { className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
13000
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0 mb-0.5" }),
13001
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
13002
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
13003
+ multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
13018
13004
  "x",
13019
13005
  multiplier.toFixed(1)
13020
13006
  ] }),
13021
- streak != null && streak > 0 && /* @__PURE__ */ jsxs("span", { className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
13007
+ streak != null && streak > 0 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
13022
13008
  streak,
13023
13009
  " streak"
13024
13010
  ] })
@@ -13026,16 +13012,19 @@ function ComboCounter({
13026
13012
  }
13027
13013
  );
13028
13014
  }
13029
- var DEFAULT_ASSET_URL7, sizeMap8;
13015
+ var DEFAULT_ASSET_URL7, sizeMap9;
13030
13016
  var init_ComboCounter = __esm({
13031
13017
  "components/game/2d/atoms/ComboCounter.tsx"() {
13032
13018
  init_cn();
13019
+ init_Box();
13020
+ init_Typography();
13021
+ init_GameIcon();
13033
13022
  DEFAULT_ASSET_URL7 = {
13034
13023
  url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
13035
13024
  role: "effect",
13036
13025
  category: "effect"
13037
13026
  };
13038
- sizeMap8 = {
13027
+ sizeMap9 = {
13039
13028
  sm: { combo: "text-lg", label: "text-xs", multiplier: "text-xs" },
13040
13029
  md: { combo: "text-2xl", label: "text-xs", multiplier: "text-sm" },
13041
13030
  lg: { combo: "text-4xl", label: "text-sm", multiplier: "text-base" }
@@ -13052,54 +13041,48 @@ function WaypointMarker({
13052
13041
  size = "md",
13053
13042
  className
13054
13043
  }) {
13055
- const sizes = sizeMap9[size];
13056
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center", className), children: [
13057
- /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
13044
+ const sizes = sizeMap10[size];
13045
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col items-center", className), children: [
13046
+ /* @__PURE__ */ jsxs(Box, { className: "relative flex items-center justify-center", children: [
13058
13047
  active && /* @__PURE__ */ jsx(
13059
- "div",
13048
+ Box,
13060
13049
  {
13050
+ position: "absolute",
13061
13051
  className: cn(
13062
- "absolute rounded-full border-2 border-info animate-ping opacity-50",
13052
+ "rounded-full border-2 border-info animate-ping opacity-50",
13063
13053
  sizes.ring
13064
13054
  )
13065
13055
  }
13066
13056
  ),
13067
13057
  active && /* @__PURE__ */ jsx(
13068
- "div",
13058
+ Box,
13069
13059
  {
13060
+ position: "absolute",
13070
13061
  className: cn(
13071
- "absolute rounded-full border-2 border-info",
13062
+ "rounded-full border-2 border-info",
13072
13063
  sizes.ring
13073
13064
  )
13074
13065
  }
13075
13066
  ),
13076
13067
  /* @__PURE__ */ jsx(
13077
- "div",
13068
+ Box,
13078
13069
  {
13070
+ position: "relative",
13079
13071
  className: cn(
13080
- "relative flex items-center justify-center rounded-full transition-all duration-200",
13072
+ "flex items-center justify-center rounded-full transition-all duration-200",
13081
13073
  sizes.dot,
13082
13074
  completed && "bg-success text-foreground",
13083
13075
  active && !completed && "bg-info text-foreground",
13084
13076
  !active && !completed && "bg-muted"
13085
13077
  ),
13086
- children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsx(
13087
- "img",
13088
- {
13089
- src: assetUrl.url,
13090
- alt: label,
13091
- width: sizes.img,
13092
- height: sizes.img,
13093
- style: { imageRendering: "pixelated", objectFit: "contain" },
13094
- className: "flex-shrink-0"
13095
- }
13096
- ) : icon ? typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) : null
13078
+ 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
13097
13079
  }
13098
13080
  )
13099
13081
  ] }),
13100
13082
  label && /* @__PURE__ */ jsx(
13101
- "span",
13083
+ Typography,
13102
13084
  {
13085
+ as: "span",
13103
13086
  className: cn(
13104
13087
  "text-center whitespace-nowrap",
13105
13088
  sizes.label,
@@ -13110,17 +13093,20 @@ function WaypointMarker({
13110
13093
  )
13111
13094
  ] });
13112
13095
  }
13113
- var DEFAULT_ASSET_URL8, sizeMap9, checkIcon;
13096
+ var DEFAULT_ASSET_URL8, sizeMap10, checkIcon;
13114
13097
  var init_WaypointMarker = __esm({
13115
13098
  "components/game/2d/atoms/WaypointMarker.tsx"() {
13116
13099
  init_cn();
13117
13100
  init_Icon();
13101
+ init_Box();
13102
+ init_Typography();
13103
+ init_GameIcon();
13118
13104
  DEFAULT_ASSET_URL8 = {
13119
13105
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
13120
13106
  role: "ui",
13121
13107
  category: "waypoint"
13122
13108
  };
13123
- sizeMap9 = {
13109
+ sizeMap10 = {
13124
13110
  sm: { dot: "w-4 h-4", ring: "w-6 h-6", label: "text-xs mt-1", img: 12 },
13125
13111
  md: { dot: "w-6 h-6", ring: "w-8 h-8", label: "text-sm mt-1.5", img: 18 },
13126
13112
  lg: { dot: "w-8 h-8", ring: "w-10 h-10", label: "text-base mt-2", img: 24 }
@@ -13145,32 +13131,24 @@ function StatusEffect({
13145
13131
  size = "md",
13146
13132
  className
13147
13133
  }) {
13148
- const sizes = sizeMap10[size];
13149
- return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex flex-col items-center", className), children: [
13134
+ const sizes = sizeMap11[size];
13135
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn("inline-flex flex-col items-center", className), children: [
13150
13136
  /* @__PURE__ */ jsxs(
13151
- "div",
13137
+ Box,
13152
13138
  {
13139
+ position: "relative",
13153
13140
  className: cn(
13154
- "relative flex items-center justify-center rounded-interactive border-2",
13141
+ "flex items-center justify-center rounded-interactive border-2",
13155
13142
  sizes.container,
13156
13143
  variantStyles7[variant]
13157
13144
  ),
13158
13145
  title: label,
13159
13146
  children: [
13160
- /* @__PURE__ */ jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsx(
13161
- "img",
13162
- {
13163
- src: assetUrl.url,
13164
- alt: label,
13165
- width: sizes.img,
13166
- height: sizes.img,
13167
- style: { imageRendering: "pixelated", objectFit: "contain" },
13168
- className: "flex-shrink-0"
13169
- }
13170
- ) : icon != null && typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsx(Icon, { icon, size: "sm" }) : null }),
13147
+ /* @__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 }),
13171
13148
  duration !== void 0 && /* @__PURE__ */ jsx(
13172
- "span",
13149
+ Typography,
13173
13150
  {
13151
+ as: "span",
13174
13152
  className: cn(
13175
13153
  "absolute bottom-0 left-0 right-0 text-center font-mono font-bold text-foreground bg-background/60 leading-tight",
13176
13154
  sizes.timer
@@ -13182,8 +13160,9 @@ function StatusEffect({
13182
13160
  }
13183
13161
  ),
13184
13162
  stacks !== void 0 && stacks > 1 && /* @__PURE__ */ jsx(
13185
- "span",
13163
+ Typography,
13186
13164
  {
13165
+ as: "span",
13187
13166
  className: cn(
13188
13167
  "absolute flex items-center justify-center rounded-full bg-card text-foreground font-bold leading-none",
13189
13168
  sizes.badge
@@ -13191,20 +13170,23 @@ function StatusEffect({
13191
13170
  children: stacks
13192
13171
  }
13193
13172
  ),
13194
- label && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
13173
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
13195
13174
  ] });
13196
13175
  }
13197
- var DEFAULT_ASSET_URL9, sizeMap10, variantStyles7;
13176
+ var DEFAULT_ASSET_URL9, sizeMap11, variantStyles7;
13198
13177
  var init_StatusEffect = __esm({
13199
13178
  "components/game/2d/atoms/StatusEffect.tsx"() {
13200
13179
  init_cn();
13201
13180
  init_Icon();
13181
+ init_Box();
13182
+ init_Typography();
13183
+ init_GameIcon();
13202
13184
  DEFAULT_ASSET_URL9 = {
13203
13185
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
13204
13186
  role: "ui",
13205
13187
  category: "effect"
13206
13188
  };
13207
- sizeMap10 = {
13189
+ sizeMap11 = {
13208
13190
  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 },
13209
13191
  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 },
13210
13192
  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 }
@@ -13228,38 +13210,31 @@ function DamageNumber({
13228
13210
  return /* @__PURE__ */ jsxs(Fragment, { children: [
13229
13211
  /* @__PURE__ */ jsx("style", { children: floatKeyframes }),
13230
13212
  /* @__PURE__ */ jsxs(
13231
- "span",
13213
+ Typography,
13232
13214
  {
13215
+ as: "span",
13233
13216
  className: cn(
13234
13217
  "inline-flex items-center gap-0.5 font-mono select-none pointer-events-none",
13235
- sizeMap11[size],
13218
+ sizeMap12[size],
13236
13219
  typeStyles[type],
13237
13220
  className
13238
13221
  ),
13239
13222
  style: { animation: "damageFloat 1s ease-out forwards" },
13240
13223
  children: [
13241
- assetUrl && /* @__PURE__ */ jsx(
13242
- "img",
13243
- {
13244
- src: assetUrl.url,
13245
- alt: "",
13246
- width: 14,
13247
- height: 14,
13248
- style: { imageRendering: "pixelated", objectFit: "contain" },
13249
- className: "flex-shrink-0"
13250
- }
13251
- ),
13224
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 14, className: "flex-shrink-0" }),
13252
13225
  displayText
13253
13226
  ]
13254
13227
  }
13255
13228
  )
13256
13229
  ] });
13257
13230
  }
13258
- var sizeMap11, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
13231
+ var sizeMap12, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
13259
13232
  var init_DamageNumber = __esm({
13260
13233
  "components/game/2d/atoms/DamageNumber.tsx"() {
13261
13234
  init_cn();
13262
- sizeMap11 = {
13235
+ init_Typography();
13236
+ init_GameIcon();
13237
+ sizeMap12 = {
13263
13238
  sm: "text-sm",
13264
13239
  md: "text-lg",
13265
13240
  lg: "text-2xl"
@@ -13293,7 +13268,7 @@ function DialogueBubble({
13293
13268
  className
13294
13269
  }) {
13295
13270
  return /* @__PURE__ */ jsxs(
13296
- "div",
13271
+ Box,
13297
13272
  {
13298
13273
  className: cn(
13299
13274
  "flex items-start gap-3 rounded-container bg-background/80 backdrop-blur-sm px-4 py-3 border border-border/10",
@@ -13301,17 +13276,10 @@ function DialogueBubble({
13301
13276
  className
13302
13277
  ),
13303
13278
  children: [
13304
- portrait && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 w-12 h-12 rounded-full overflow-hidden border-2 border-warning/60", children: /* @__PURE__ */ jsx(
13305
- "img",
13306
- {
13307
- src: portrait?.url,
13308
- alt: speaker ?? "speaker",
13309
- className: "w-full h-full object-cover"
13310
- }
13311
- ) }),
13312
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
13313
- speaker && /* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-warning", children: speaker }),
13314
- /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground leading-relaxed", children: text })
13279
+ 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" }) }),
13280
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-1 min-w-0", children: [
13281
+ speaker && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm font-bold text-warning", children: speaker }),
13282
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm text-foreground leading-relaxed", children: text })
13315
13283
  ] })
13316
13284
  ]
13317
13285
  }
@@ -13321,6 +13289,9 @@ var DEFAULT_PORTRAIT;
13321
13289
  var init_DialogueBubble = __esm({
13322
13290
  "components/game/2d/atoms/DialogueBubble.tsx"() {
13323
13291
  init_cn();
13292
+ init_Box();
13293
+ init_Typography();
13294
+ init_GameIcon();
13324
13295
  DEFAULT_PORTRAIT = {
13325
13296
  url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
13326
13297
  role: "effect",
@@ -13342,11 +13313,11 @@ function ChoiceButton({
13342
13313
  }) {
13343
13314
  const eventBus = useEventBus();
13344
13315
  return /* @__PURE__ */ jsxs(
13345
- "button",
13316
+ Button,
13346
13317
  {
13347
- type: "button",
13318
+ variant: "ghost",
13348
13319
  disabled,
13349
- onClick: (e) => {
13320
+ onClick: () => {
13350
13321
  if (action) eventBus.emit(`UI:${action}`, {});
13351
13322
  onClick?.();
13352
13323
  },
@@ -13359,8 +13330,9 @@ function ChoiceButton({
13359
13330
  ),
13360
13331
  children: [
13361
13332
  index !== void 0 && /* @__PURE__ */ jsxs(
13362
- "span",
13333
+ Typography,
13363
13334
  {
13335
+ as: "span",
13364
13336
  className: cn(
13365
13337
  "flex-shrink-0 font-mono font-bold text-sm",
13366
13338
  selected ? "text-accent" : "text-muted-foreground"
@@ -13371,24 +13343,14 @@ function ChoiceButton({
13371
13343
  ]
13372
13344
  }
13373
13345
  ),
13374
- assetUrl ? /* @__PURE__ */ jsx(
13375
- "img",
13376
- {
13377
- src: assetUrl.url,
13378
- alt: "",
13379
- width: 16,
13380
- height: 16,
13381
- style: { imageRendering: "pixelated", objectFit: "contain" },
13382
- className: "flex-shrink-0"
13383
- }
13384
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
13346
+ 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" ? (() => {
13385
13347
  const I = resolveIcon(icon);
13386
13348
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
13387
13349
  })() : /* @__PURE__ */ (() => {
13388
13350
  const I = icon;
13389
13351
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
13390
13352
  })() }) : null,
13391
- /* @__PURE__ */ jsx("span", { className: "text-sm leading-snug", children: text })
13353
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm leading-snug", children: text })
13392
13354
  ]
13393
13355
  }
13394
13356
  );
@@ -13398,6 +13360,10 @@ var init_ChoiceButton = __esm({
13398
13360
  init_cn();
13399
13361
  init_Icon();
13400
13362
  init_useEventBus();
13363
+ init_Button();
13364
+ init_Box();
13365
+ init_Typography();
13366
+ init_GameIcon();
13401
13367
  ChoiceButton.displayName = "ChoiceButton";
13402
13368
  }
13403
13369
  });
@@ -13415,16 +13381,16 @@ function ActionButton({
13415
13381
  className
13416
13382
  }) {
13417
13383
  const eventBus = useEventBus();
13418
- const sizes = sizeMap12[size];
13384
+ const sizes = sizeMap13[size];
13419
13385
  const onCooldown = cooldown > 0;
13420
13386
  const isDisabled = disabled || onCooldown;
13421
13387
  const cooldownDeg = Math.round(cooldown * 360);
13422
13388
  return /* @__PURE__ */ jsxs(
13423
- "button",
13389
+ Button,
13424
13390
  {
13425
- type: "button",
13391
+ variant: variant === "danger" ? "danger" : variant === "secondary" ? "secondary" : "primary",
13426
13392
  disabled: isDisabled,
13427
- onClick: (e) => {
13393
+ onClick: () => {
13428
13394
  if (action) eventBus.emit(`UI:${action}`, {});
13429
13395
  onClick?.();
13430
13396
  },
@@ -13437,9 +13403,10 @@ function ActionButton({
13437
13403
  ),
13438
13404
  children: [
13439
13405
  onCooldown && /* @__PURE__ */ jsx(
13440
- "div",
13406
+ Box,
13441
13407
  {
13442
- className: "absolute inset-0 bg-foreground/40 pointer-events-none",
13408
+ position: "absolute",
13409
+ className: "inset-0 bg-foreground/40 pointer-events-none",
13443
13410
  style: {
13444
13411
  clipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
13445
13412
  WebkitClipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
@@ -13447,27 +13414,18 @@ function ActionButton({
13447
13414
  }
13448
13415
  }
13449
13416
  ),
13450
- assetUrl ? /* @__PURE__ */ jsx(
13451
- "img",
13452
- {
13453
- src: assetUrl.url,
13454
- alt: "",
13455
- width: 16,
13456
- height: 16,
13457
- style: { imageRendering: "pixelated", objectFit: "contain" },
13458
- className: cn("flex-shrink-0", sizes.icon)
13459
- }
13460
- ) : icon ? /* @__PURE__ */ jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
13417
+ 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" ? (() => {
13461
13418
  const I = resolveIcon(icon);
13462
13419
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
13463
13420
  })() : /* @__PURE__ */ (() => {
13464
13421
  const I = icon;
13465
13422
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
13466
13423
  })() }) : null,
13467
- /* @__PURE__ */ jsx("span", { className: "relative z-10", children: label }),
13424
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "relative z-10", children: label }),
13468
13425
  hotkey && /* @__PURE__ */ jsx(
13469
- "span",
13426
+ Typography,
13470
13427
  {
13428
+ as: "span",
13471
13429
  className: cn(
13472
13430
  "absolute top-0.5 right-0.5 bg-foreground/30 text-primary-foreground rounded font-mono leading-tight",
13473
13431
  sizes.hotkey
@@ -13479,13 +13437,17 @@ function ActionButton({
13479
13437
  }
13480
13438
  );
13481
13439
  }
13482
- var sizeMap12, variantStyles8, DEFAULT_ASSET_URL11;
13440
+ var sizeMap13, variantStyles8, DEFAULT_ASSET_URL11;
13483
13441
  var init_ActionButton = __esm({
13484
13442
  "components/game/2d/atoms/ActionButton.tsx"() {
13485
13443
  init_cn();
13486
13444
  init_Icon();
13487
13445
  init_useEventBus();
13488
- sizeMap12 = {
13446
+ init_Button();
13447
+ init_Box();
13448
+ init_Typography();
13449
+ init_GameIcon();
13450
+ sizeMap13 = {
13489
13451
  sm: { button: "h-button-sm px-3 text-xs", hotkey: "text-[9px] px-1", icon: "text-xs" },
13490
13452
  md: { button: "h-button-md px-4 text-sm", hotkey: "text-xs px-1.5", icon: "text-sm" },
13491
13453
  lg: { button: "h-button-lg px-5 text-base", hotkey: "text-xs px-2", icon: "text-base" }
@@ -13587,10 +13549,12 @@ function MiniMap({
13587
13549
  return /* @__PURE__ */ jsxs(Fragment, { children: [
13588
13550
  /* @__PURE__ */ jsx("style", { children: `@keyframes minimap-blink{0%,49%{opacity:1}50%,100%{opacity:0}}` }),
13589
13551
  /* @__PURE__ */ jsxs(
13590
- "div",
13552
+ Box,
13591
13553
  {
13554
+ position: "relative",
13555
+ display: "inline-block",
13592
13556
  className: cn(
13593
- "relative inline-block border border-border/20 rounded-container",
13557
+ "border border-border/20 rounded-container",
13594
13558
  className
13595
13559
  ),
13596
13560
  children: [
@@ -13605,10 +13569,10 @@ function MiniMap({
13605
13569
  }
13606
13570
  ),
13607
13571
  playerLeft !== null && playerTop !== null && /* @__PURE__ */ jsx(
13608
- "div",
13572
+ Box,
13609
13573
  {
13574
+ position: "absolute",
13610
13575
  style: {
13611
- position: "absolute",
13612
13576
  left: playerLeft,
13613
13577
  top: playerTop,
13614
13578
  width: 3,
@@ -13629,6 +13593,7 @@ var init_MiniMap = __esm({
13629
13593
  "components/game/2d/atoms/MiniMap.tsx"() {
13630
13594
  "use client";
13631
13595
  init_cn();
13596
+ init_Box();
13632
13597
  DEFAULT_TILES = [
13633
13598
  { x: 10, y: 10, color: "#4ade80" },
13634
13599
  { x: 20, y: 15, color: "#4ade80" },
@@ -13646,38 +13611,6 @@ var init_MiniMap = __esm({
13646
13611
  MiniMap.displayName = "MiniMap";
13647
13612
  }
13648
13613
  });
13649
- function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
13650
- const px = typeof size === "number" ? size : sizeMap13[size];
13651
- if (assetUrl?.url) {
13652
- return /* @__PURE__ */ jsx(
13653
- "img",
13654
- {
13655
- src: assetUrl.url,
13656
- alt: alt ?? assetUrl.category ?? "",
13657
- width: px,
13658
- height: px,
13659
- style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
13660
- className: cn("flex-shrink-0", className)
13661
- }
13662
- );
13663
- }
13664
- const I = typeof icon === "string" ? resolveIcon(icon) : icon;
13665
- return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
13666
- }
13667
- var sizeMap13;
13668
- var init_GameIcon = __esm({
13669
- "components/game/2d/atoms/GameIcon.tsx"() {
13670
- "use client";
13671
- init_cn();
13672
- init_Icon();
13673
- sizeMap13 = {
13674
- sm: 16,
13675
- md: 24,
13676
- lg: 32
13677
- };
13678
- GameIcon.displayName = "GameIcon";
13679
- }
13680
- });
13681
13614
  function ControlGrid({
13682
13615
  kind,
13683
13616
  buttons = DEFAULT_BUTTONS,
@@ -13738,22 +13671,22 @@ function ControlGrid({
13738
13671
  },
13739
13672
  d
13740
13673
  );
13741
- return /* @__PURE__ */ jsxs("div", { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
13742
- /* @__PURE__ */ jsx("div", {}),
13674
+ return /* @__PURE__ */ jsxs(Box, { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
13675
+ /* @__PURE__ */ jsx(Box, {}),
13743
13676
  dir("up"),
13744
- /* @__PURE__ */ jsx("div", {}),
13677
+ /* @__PURE__ */ jsx(Box, {}),
13745
13678
  dir("left"),
13746
- /* @__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" }) }),
13679
+ /* @__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" }) }),
13747
13680
  dir("right"),
13748
- /* @__PURE__ */ jsx("div", {}),
13681
+ /* @__PURE__ */ jsx(Box, {}),
13749
13682
  dir("down"),
13750
- /* @__PURE__ */ jsx("div", {})
13683
+ /* @__PURE__ */ jsx(Box, {})
13751
13684
  ] });
13752
13685
  }
13753
13686
  if (layout === "diamond" && buttons.length === 4) {
13754
13687
  const [top, right, bottom, left] = buttons;
13755
- return /* @__PURE__ */ jsxs("div", { className: cn(layoutClass.diamond, className), children: [
13756
- /* @__PURE__ */ jsx("div", {}),
13688
+ return /* @__PURE__ */ jsxs(Box, { className: cn(layoutClass.diamond, className), children: [
13689
+ /* @__PURE__ */ jsx(Box, {}),
13757
13690
  /* @__PURE__ */ jsx(
13758
13691
  ControlButton,
13759
13692
  {
@@ -13768,7 +13701,7 @@ function ControlGrid({
13768
13701
  disabled
13769
13702
  }
13770
13703
  ),
13771
- /* @__PURE__ */ jsx("div", {}),
13704
+ /* @__PURE__ */ jsx(Box, {}),
13772
13705
  /* @__PURE__ */ jsx(
13773
13706
  ControlButton,
13774
13707
  {
@@ -13783,7 +13716,7 @@ function ControlGrid({
13783
13716
  disabled
13784
13717
  }
13785
13718
  ),
13786
- /* @__PURE__ */ jsx("div", {}),
13719
+ /* @__PURE__ */ jsx(Box, {}),
13787
13720
  /* @__PURE__ */ jsx(
13788
13721
  ControlButton,
13789
13722
  {
@@ -13798,7 +13731,7 @@ function ControlGrid({
13798
13731
  disabled
13799
13732
  }
13800
13733
  ),
13801
- /* @__PURE__ */ jsx("div", {}),
13734
+ /* @__PURE__ */ jsx(Box, {}),
13802
13735
  /* @__PURE__ */ jsx(
13803
13736
  ControlButton,
13804
13737
  {
@@ -13813,10 +13746,10 @@ function ControlGrid({
13813
13746
  disabled
13814
13747
  }
13815
13748
  ),
13816
- /* @__PURE__ */ jsx("div", {})
13749
+ /* @__PURE__ */ jsx(Box, {})
13817
13750
  ] });
13818
13751
  }
13819
- return /* @__PURE__ */ jsx("div", { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
13752
+ return /* @__PURE__ */ jsx(Box, { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
13820
13753
  ControlButton,
13821
13754
  {
13822
13755
  icon: button.icon,
@@ -13838,6 +13771,7 @@ var init_ControlGrid = __esm({
13838
13771
  "use client";
13839
13772
  init_cn();
13840
13773
  init_useEventBus();
13774
+ init_Box();
13841
13775
  init_ControlButton();
13842
13776
  sizeKey = { sm: "sm", md: "md", lg: "lg" };
13843
13777
  layoutClass = {
@@ -13882,7 +13816,7 @@ function StatBadge({
13882
13816
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
13883
13817
  const resolvedAsset = iconUrl ?? assetUrl;
13884
13818
  return /* @__PURE__ */ jsxs(
13885
- "div",
13819
+ Box,
13886
13820
  {
13887
13821
  className: cn(
13888
13822
  "inline-flex items-center gap-2 rounded-container border backdrop-blur-sm",
@@ -13891,18 +13825,8 @@ function StatBadge({
13891
13825
  className
13892
13826
  ),
13893
13827
  children: [
13894
- resolvedAsset ? /* @__PURE__ */ jsx(
13895
- "img",
13896
- {
13897
- src: resolvedAsset.url,
13898
- alt: "",
13899
- width: 16,
13900
- height: 16,
13901
- style: { imageRendering: "pixelated", objectFit: "contain" },
13902
- className: "flex-shrink-0"
13903
- }
13904
- ) : 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,
13905
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-medium", children: label }),
13828
+ 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,
13829
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground font-medium", children: label }),
13906
13830
  format === "hearts" && max && /* @__PURE__ */ jsx(
13907
13831
  HealthBar,
13908
13832
  {
@@ -13928,7 +13852,7 @@ function StatBadge({
13928
13852
  size: size === "lg" ? "md" : "sm"
13929
13853
  }
13930
13854
  ),
13931
- format === "text" && /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground", children: value })
13855
+ format === "text" && /* @__PURE__ */ jsx(Typography, { as: "span", className: "font-bold text-foreground", children: value })
13932
13856
  ]
13933
13857
  }
13934
13858
  );
@@ -13938,6 +13862,9 @@ var init_StatBadge = __esm({
13938
13862
  "components/game/2d/molecules/StatBadge.tsx"() {
13939
13863
  init_cn();
13940
13864
  init_Icon();
13865
+ init_Box();
13866
+ init_Typography();
13867
+ init_GameIcon();
13941
13868
  init_HealthBar();
13942
13869
  init_ScoreDisplay();
13943
13870
  sizeMap14 = {
@@ -14115,9 +14042,9 @@ function GameHud({
14115
14042
  if (position === "corners") {
14116
14043
  const leftStats = stats.slice(0, Math.ceil(stats.length / 2));
14117
14044
  const rightStats = stats.slice(Math.ceil(stats.length / 2));
14118
- return /* @__PURE__ */ jsxs("div", { className: cn("relative", positionMap[position], className), children: [
14119
- /* @__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)) }),
14120
- /* @__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)) })
14045
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn(positionMap[position], className), children: [
14046
+ /* @__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)) }),
14047
+ /* @__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)) })
14121
14048
  ] });
14122
14049
  }
14123
14050
  if (position === "top" || position === "bottom") {
@@ -14126,7 +14053,7 @@ function GameHud({
14126
14053
  const rightStats = stats.slice(mid);
14127
14054
  const isTop = position === "top";
14128
14055
  return /* @__PURE__ */ jsxs(
14129
- "div",
14056
+ Box,
14130
14057
  {
14131
14058
  className: cn(
14132
14059
  "flex items-center justify-between w-full",
@@ -14136,17 +14063,18 @@ function GameHud({
14136
14063
  className
14137
14064
  ),
14138
14065
  children: [
14139
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
14140
- 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)) })
14066
+ /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
14067
+ 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)) })
14141
14068
  ]
14142
14069
  }
14143
14070
  );
14144
14071
  }
14145
14072
  return /* @__PURE__ */ jsx(
14146
- "div",
14073
+ Box,
14147
14074
  {
14075
+ position: "relative",
14148
14076
  className: cn(
14149
- "relative z-10 flex items-center gap-4 px-4 py-2",
14077
+ "z-10 flex items-center gap-4 px-4 py-2",
14150
14078
  transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
14151
14079
  className
14152
14080
  ),
@@ -14158,6 +14086,7 @@ var positionMap, DEFAULT_HUD_STATS;
14158
14086
  var init_GameHud = __esm({
14159
14087
  "components/game/2d/molecules/GameHud.tsx"() {
14160
14088
  init_cn();
14089
+ init_Box();
14161
14090
  init_StatBadge();
14162
14091
  positionMap = {
14163
14092
  corners: "inset-0 pointer-events-none"
@@ -14198,7 +14127,7 @@ function GameMenu({
14198
14127
  [eventBus, onSelect]
14199
14128
  );
14200
14129
  return /* @__PURE__ */ jsxs(
14201
- "div",
14130
+ Box,
14202
14131
  {
14203
14132
  className: cn(
14204
14133
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
@@ -14208,18 +14137,12 @@ function GameMenu({
14208
14137
  background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
14209
14138
  },
14210
14139
  children: [
14211
- /* @__PURE__ */ jsxs("div", { className: "text-center mb-12 animate-fade-in", children: [
14212
- logo && /* @__PURE__ */ jsx(
14213
- "img",
14214
- {
14215
- src: logo.url,
14216
- alt: title,
14217
- className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl"
14218
- }
14219
- ),
14140
+ /* @__PURE__ */ jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
14141
+ logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
14220
14142
  /* @__PURE__ */ jsx(
14221
- "h1",
14143
+ Typography,
14222
14144
  {
14145
+ variant: "h1",
14223
14146
  className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
14224
14147
  style: {
14225
14148
  textShadow: "0 4px 12px rgba(0,0,0,0.5)"
@@ -14227,9 +14150,9 @@ function GameMenu({
14227
14150
  children: title
14228
14151
  }
14229
14152
  ),
14230
- subtitle && /* @__PURE__ */ jsx("p", { className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
14153
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
14231
14154
  ] }),
14232
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
14155
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
14233
14156
  ChoiceButton,
14234
14157
  {
14235
14158
  text: option.label,
@@ -14240,9 +14163,9 @@ function GameMenu({
14240
14163
  },
14241
14164
  index
14242
14165
  )) }),
14243
- /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 pointer-events-none overflow-hidden", children: [
14244
- /* @__PURE__ */ jsx("div", { className: "absolute top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
14245
- /* @__PURE__ */ jsx("div", { className: "absolute bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
14166
+ /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
14167
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
14168
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
14246
14169
  ] })
14247
14170
  ]
14248
14171
  }
@@ -14254,6 +14177,9 @@ var init_GameMenu = __esm({
14254
14177
  "use client";
14255
14178
  init_cn();
14256
14179
  init_useEventBus();
14180
+ init_Box();
14181
+ init_Typography();
14182
+ init_GameIcon();
14257
14183
  init_ChoiceButton();
14258
14184
  DEFAULT_MENU_OPTIONS = [
14259
14185
  { label: "New Game", event: "NEW_GAME", variant: "primary" },
@@ -15673,10 +15599,11 @@ function Canvas2D({
15673
15599
  }
15674
15600
  }
15675
15601
  ),
15676
- process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs("div", { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
15602
+ process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs(Box, { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
15677
15603
  tileClickEvent && /* @__PURE__ */ jsx(
15678
- "button",
15604
+ Button,
15679
15605
  {
15606
+ variant: "ghost",
15680
15607
  "data-event": tileClickEvent,
15681
15608
  "data-x": "0",
15682
15609
  "data-y": "0",
@@ -15685,8 +15612,9 @@ function Canvas2D({
15685
15612
  }
15686
15613
  ),
15687
15614
  unitClickEvent && units && units.length > 0 && /* @__PURE__ */ jsx(
15688
- "button",
15615
+ Button,
15689
15616
  {
15617
+ variant: "ghost",
15690
15618
  "data-event": unitClickEvent,
15691
15619
  "data-unit-id": units[0].id,
15692
15620
  onClick: () => eventBus.emit(`UI:${unitClickEvent}`, { unitId: units[0].id }),
@@ -15695,15 +15623,17 @@ function Canvas2D({
15695
15623
  )
15696
15624
  ] }),
15697
15625
  unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxs(
15698
- "div",
15626
+ Box,
15699
15627
  {
15700
- className: "absolute pointer-events-none",
15628
+ position: "absolute",
15629
+ className: "pointer-events-none",
15701
15630
  style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
15702
15631
  children: [
15703
15632
  unit.name && /* @__PURE__ */ jsx(
15704
- "div",
15633
+ Typography,
15705
15634
  {
15706
- className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
15635
+ as: "span",
15636
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap block",
15707
15637
  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)" },
15708
15638
  children: unit.name
15709
15639
  }
@@ -15713,7 +15643,7 @@ function Canvas2D({
15713
15643
  },
15714
15644
  unit.id
15715
15645
  )),
15716
- showMinimap && /* @__PURE__ */ jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
15646
+ showMinimap && /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
15717
15647
  MiniMap,
15718
15648
  {
15719
15649
  tiles: miniMapTiles,
@@ -15735,6 +15665,7 @@ var init_Canvas2D = __esm({
15735
15665
  init_cn();
15736
15666
  init_useEventBus();
15737
15667
  init_Box();
15668
+ init_Button();
15738
15669
  init_Stack();
15739
15670
  init_Icon();
15740
15671
  init_Typography();
@@ -16066,7 +15997,7 @@ function GameAudioToggle({
16066
15997
  onClick: handleToggle,
16067
15998
  className: cn("text-lg leading-none px-2", className),
16068
15999
  "aria-pressed": muted,
16069
- 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}"
16000
+ 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}"
16070
16001
  }
16071
16002
  );
16072
16003
  }
@@ -16076,6 +16007,7 @@ var init_GameAudioToggle = __esm({
16076
16007
  init_atoms();
16077
16008
  init_cn();
16078
16009
  init_GameAudioProvider();
16010
+ init_GameIcon();
16079
16011
  GameAudioToggle.displayName = "GameAudioToggle";
16080
16012
  }
16081
16013
  });