@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.
@@ -12157,6 +12157,38 @@ var init_shared = __esm({
12157
12157
  init_canvasEffects();
12158
12158
  }
12159
12159
  });
12160
+ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
12161
+ const px = typeof size === "number" ? size : sizeMap[size];
12162
+ if (assetUrl?.url) {
12163
+ return /* @__PURE__ */ jsxRuntime.jsx(
12164
+ "img",
12165
+ {
12166
+ src: assetUrl.url,
12167
+ alt: alt ?? assetUrl.category ?? "",
12168
+ width: px,
12169
+ height: px,
12170
+ style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
12171
+ className: cn("flex-shrink-0", className)
12172
+ }
12173
+ );
12174
+ }
12175
+ const I = typeof icon === "string" ? resolveIcon(icon) : icon;
12176
+ return /* @__PURE__ */ jsxRuntime.jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
12177
+ }
12178
+ var sizeMap;
12179
+ var init_GameIcon = __esm({
12180
+ "components/game/2d/atoms/GameIcon.tsx"() {
12181
+ "use client";
12182
+ init_cn();
12183
+ init_Icon();
12184
+ sizeMap = {
12185
+ sm: 16,
12186
+ md: 24,
12187
+ lg: 32
12188
+ };
12189
+ GameIcon.displayName = "GameIcon";
12190
+ }
12191
+ });
12160
12192
  function GameCard({
12161
12193
  id,
12162
12194
  cost,
@@ -12179,9 +12211,9 @@ function GameCard({
12179
12211
  }, [disabled, id, onClick, clickEvent, eventBus]);
12180
12212
  const artPx = artPxMap[size];
12181
12213
  return /* @__PURE__ */ jsxRuntime.jsxs(
12182
- "button",
12214
+ Button,
12183
12215
  {
12184
- type: "button",
12216
+ variant: "ghost",
12185
12217
  onClick: handleClick,
12186
12218
  disabled,
12187
12219
  title: name,
@@ -12195,8 +12227,9 @@ function GameCard({
12195
12227
  ),
12196
12228
  children: [
12197
12229
  cost != null && /* @__PURE__ */ jsxRuntime.jsx(
12198
- "span",
12230
+ Typography,
12199
12231
  {
12232
+ as: "span",
12200
12233
  className: cn(
12201
12234
  "absolute -top-2 -left-2 flex items-center justify-center",
12202
12235
  "min-w-[22px] h-[22px] rounded-full px-1",
@@ -12205,17 +12238,7 @@ function GameCard({
12205
12238
  children: cost
12206
12239
  }
12207
12240
  ),
12208
- /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-1 flex items-center justify-center w-full", children: art ? /* @__PURE__ */ jsxRuntime.jsx(
12209
- "img",
12210
- {
12211
- src: art.url,
12212
- alt: name ?? id,
12213
- width: artPx,
12214
- height: artPx,
12215
- style: { imageRendering: "pixelated", objectFit: "contain" },
12216
- className: "flex-shrink-0"
12217
- }
12218
- ) : /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "rounded bg-muted/40", style: { width: artPx, height: artPx } }) }),
12241
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-1 flex items-center justify-center w-full", children: art ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl: art, icon: "image", size: artPx, alt: name ?? id, className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "rounded bg-muted/40", style: { width: artPx, height: artPx } }) }),
12219
12242
  name != null && /* @__PURE__ */ jsxRuntime.jsx(
12220
12243
  Typography,
12221
12244
  {
@@ -12225,8 +12248,8 @@ function GameCard({
12225
12248
  }
12226
12249
  ),
12227
12250
  (attack != null || defense != null) && /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex w-full items-center justify-between px-0.5 text-[10px] font-bold leading-none", children: [
12228
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
12229
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
12251
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
12252
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
12230
12253
  ] })
12231
12254
  ]
12232
12255
  }
@@ -12239,7 +12262,9 @@ var init_GameCard = __esm({
12239
12262
  init_cn();
12240
12263
  init_useEventBus();
12241
12264
  init_Box();
12265
+ init_Button();
12242
12266
  init_Typography();
12267
+ init_GameIcon();
12243
12268
  cardSizeMap = {
12244
12269
  sm: "w-16 h-24",
12245
12270
  md: "w-20 h-28",
@@ -12262,12 +12287,13 @@ function HealthBar({
12262
12287
  frameAsset,
12263
12288
  fillAsset
12264
12289
  }) {
12265
- const sizes = sizeMap[size];
12290
+ const sizes = sizeMap2[size];
12266
12291
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
12267
12292
  if (format === "hearts") {
12268
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
12269
- "span",
12293
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
12294
+ Box,
12270
12295
  {
12296
+ as: "span",
12271
12297
  className: cn(animated && "transition-transform hover:scale-110"),
12272
12298
  children: heartIcon(i < current, sizes.heart)
12273
12299
  },
@@ -12276,10 +12302,12 @@ function HealthBar({
12276
12302
  }
12277
12303
  if (format === "bar") {
12278
12304
  return /* @__PURE__ */ jsxRuntime.jsx(
12279
- "div",
12305
+ Box,
12280
12306
  {
12307
+ position: "relative",
12308
+ overflow: "hidden",
12281
12309
  className: cn(
12282
- "relative overflow-hidden rounded-full",
12310
+ "rounded-full",
12283
12311
  !frameAsset && "bg-muted",
12284
12312
  sizes.bar,
12285
12313
  "w-24",
@@ -12287,10 +12315,11 @@ function HealthBar({
12287
12315
  ),
12288
12316
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
12289
12317
  children: /* @__PURE__ */ jsxRuntime.jsx(
12290
- "div",
12318
+ Box,
12291
12319
  {
12320
+ position: "absolute",
12292
12321
  className: cn(
12293
- "absolute inset-y-0 left-0 rounded-full",
12322
+ "inset-y-0 left-0 rounded-full",
12294
12323
  !fillAsset && (percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error"),
12295
12324
  animated && "transition-all duration-300"
12296
12325
  ),
@@ -12304,10 +12333,11 @@ function HealthBar({
12304
12333
  );
12305
12334
  }
12306
12335
  if (format === "progress") {
12307
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2", className), children: [
12336
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: cn("flex items-center gap-2", className), children: [
12308
12337
  level != null && /* @__PURE__ */ jsxRuntime.jsxs(
12309
- "span",
12338
+ Typography,
12310
12339
  {
12340
+ as: "span",
12311
12341
  className: cn(
12312
12342
  "flex-shrink-0 rounded-interactive font-bold",
12313
12343
  "bg-accent text-accent-foreground border border-accent",
@@ -12319,21 +12349,23 @@ function HealthBar({
12319
12349
  ]
12320
12350
  }
12321
12351
  ),
12322
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [
12352
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex-1 flex flex-col gap-0.5", children: [
12323
12353
  /* @__PURE__ */ jsxRuntime.jsx(
12324
- "div",
12354
+ Box,
12325
12355
  {
12356
+ position: "relative",
12326
12357
  className: cn(
12327
- "relative w-full overflow-hidden rounded-full",
12358
+ "w-full overflow-hidden rounded-full",
12328
12359
  !frameAsset && "bg-muted border border-muted",
12329
12360
  sizes.bar
12330
12361
  ),
12331
12362
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
12332
12363
  children: /* @__PURE__ */ jsxRuntime.jsx(
12333
- "div",
12364
+ Box,
12334
12365
  {
12366
+ position: "absolute",
12335
12367
  className: cn(
12336
- "absolute inset-y-0 left-0 rounded-full",
12368
+ "inset-y-0 left-0 rounded-full",
12337
12369
  !fillAsset && "bg-gradient-to-r from-accent to-info",
12338
12370
  animated && "transition-all duration-500 ease-out"
12339
12371
  ),
@@ -12345,7 +12377,7 @@ function HealthBar({
12345
12377
  )
12346
12378
  }
12347
12379
  ),
12348
- showLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
12380
+ showLabel && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { as: "span", className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
12349
12381
  current,
12350
12382
  " / ",
12351
12383
  max,
@@ -12354,16 +12386,18 @@ function HealthBar({
12354
12386
  ] })
12355
12387
  ] });
12356
12388
  }
12357
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("font-mono font-bold", sizes.text, className), children: [
12389
+ return /* @__PURE__ */ jsxRuntime.jsxs(Typography, { as: "span", className: cn("font-mono font-bold", sizes.text, className), children: [
12358
12390
  current,
12359
12391
  "/",
12360
12392
  max
12361
12393
  ] });
12362
12394
  }
12363
- var heartIcon, sizeMap;
12395
+ var heartIcon, sizeMap2;
12364
12396
  var init_HealthBar = __esm({
12365
12397
  "components/game/2d/atoms/HealthBar.tsx"() {
12366
12398
  init_cn();
12399
+ init_Box();
12400
+ init_Typography();
12367
12401
  heartIcon = (filled, size) => /* @__PURE__ */ jsxRuntime.jsx(
12368
12402
  "svg",
12369
12403
  {
@@ -12375,7 +12409,7 @@ var init_HealthBar = __esm({
12375
12409
  children: /* @__PURE__ */ jsxRuntime.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" })
12376
12410
  }
12377
12411
  );
12378
- sizeMap = {
12412
+ sizeMap2 = {
12379
12413
  sm: { heart: "w-4 h-4", bar: "h-2", text: "text-sm", label: "text-xs", badge: "text-xs px-1.5 py-0.5" },
12380
12414
  md: { heart: "w-6 h-6", bar: "h-3", text: "text-base", label: "text-xs", badge: "text-xs px-2 py-0.5" },
12381
12415
  lg: { heart: "w-8 h-8", bar: "h-4", text: "text-lg", label: "text-sm", badge: "text-sm px-2.5 py-1" }
@@ -12396,37 +12430,30 @@ function ScoreDisplay({
12396
12430
  const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
12397
12431
  const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
12398
12432
  return /* @__PURE__ */ jsxRuntime.jsxs(
12399
- "div",
12433
+ Box,
12400
12434
  {
12401
12435
  className: cn(
12402
12436
  "flex items-center gap-2 font-bold",
12403
- sizeMap2[size],
12437
+ sizeMap3[size],
12404
12438
  className
12405
12439
  ),
12406
12440
  children: [
12407
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
12408
- "img",
12409
- {
12410
- src: assetUrl.url,
12411
- alt: "",
12412
- width: 20,
12413
- height: 20,
12414
- style: { imageRendering: "pixelated", objectFit: "contain" },
12415
- className: "flex-shrink-0"
12416
- }
12417
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }) : null,
12418
- label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: label }),
12419
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums", children: formattedValue })
12441
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 20, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }) : null,
12442
+ label && /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
12443
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "tabular-nums", children: formattedValue })
12420
12444
  ]
12421
12445
  }
12422
12446
  );
12423
12447
  }
12424
- var sizeMap2, DEFAULT_ASSET_URL;
12448
+ var sizeMap3, DEFAULT_ASSET_URL;
12425
12449
  var init_ScoreDisplay = __esm({
12426
12450
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
12427
12451
  init_cn();
12428
12452
  init_Icon();
12429
- sizeMap2 = {
12453
+ init_Box();
12454
+ init_Typography();
12455
+ init_GameIcon();
12456
+ sizeMap3 = {
12430
12457
  sm: "text-sm",
12431
12458
  md: "text-lg",
12432
12459
  lg: "text-2xl",
@@ -12489,9 +12516,9 @@ function ControlButton({
12489
12516
  [isPressed, releaseEvent, eventBus, onRelease]
12490
12517
  );
12491
12518
  return /* @__PURE__ */ jsxRuntime.jsx(
12492
- "button",
12519
+ Button,
12493
12520
  {
12494
- type: "button",
12521
+ variant,
12495
12522
  disabled,
12496
12523
  onPointerDown: handlePointerDown,
12497
12524
  onPointerUp: handlePointerUp,
@@ -12502,41 +12529,35 @@ function ControlButton({
12502
12529
  "select-none touch-none",
12503
12530
  "transition-all duration-100",
12504
12531
  "active:scale-95",
12505
- sizeMap3[size] ?? sizeMap3.md,
12532
+ sizeMap4[size] ?? sizeMap4.md,
12506
12533
  shapeMap[shape] ?? shapeMap.circle,
12507
12534
  variantMap[variant] ?? variantMap.secondary,
12508
12535
  actualPressed && "scale-95 brightness-110 border-foreground",
12509
12536
  disabled && "opacity-50 cursor-not-allowed",
12510
12537
  className
12511
12538
  ),
12512
- children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
12513
- "img",
12514
- {
12515
- src: assetUrl.url,
12516
- alt: "",
12517
- width: 24,
12518
- height: 24,
12519
- style: { imageRendering: "pixelated", objectFit: "contain" },
12520
- className: "flex-shrink-0"
12521
- }
12522
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
12539
+ children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
12523
12540
  const I = resolveIcon(icon);
12524
12541
  return I ? /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-6 h-6" }) : null;
12525
12542
  })() : icon : /* @__PURE__ */ (() => {
12526
12543
  const I = icon;
12527
12544
  return /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-6 h-6" });
12528
- })() }) : label ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }) : null
12545
+ })() }) : label ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", children: label }) : null
12529
12546
  }
12530
12547
  );
12531
12548
  }
12532
- var sizeMap3, shapeMap, variantMap, DEFAULT_ASSET_URL2;
12549
+ var sizeMap4, shapeMap, variantMap, DEFAULT_ASSET_URL2;
12533
12550
  var init_ControlButton = __esm({
12534
12551
  "components/game/2d/atoms/ControlButton.tsx"() {
12535
12552
  "use client";
12536
12553
  init_cn();
12537
12554
  init_useEventBus();
12538
12555
  init_Icon();
12539
- sizeMap3 = {
12556
+ init_Button();
12557
+ init_Box();
12558
+ init_Typography();
12559
+ init_GameIcon();
12560
+ sizeMap4 = {
12540
12561
  sm: "w-10 h-10 text-sm",
12541
12562
  md: "w-14 h-14 text-base",
12542
12563
  lg: "w-18 h-18 text-lg",
@@ -12606,12 +12627,12 @@ function Sprite({
12606
12627
  onClick?.();
12607
12628
  };
12608
12629
  return /* @__PURE__ */ jsxRuntime.jsx(
12609
- "div",
12630
+ Box,
12610
12631
  {
12632
+ position: "absolute",
12611
12633
  className,
12612
12634
  onClick: action || onClick ? handleClick : void 0,
12613
12635
  style: {
12614
- position: "absolute",
12615
12636
  width: frameWidth,
12616
12637
  height: frameHeight,
12617
12638
  backgroundImage: `url(${spritesheet.url})`,
@@ -12632,6 +12653,7 @@ var init_Sprite = __esm({
12632
12653
  "components/game/2d/atoms/Sprite.tsx"() {
12633
12654
  "use client";
12634
12655
  init_useEventBus();
12656
+ init_Box();
12635
12657
  init_spriteAnimation();
12636
12658
  DEFAULT_SPRITESHEET = {
12637
12659
  url: "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
@@ -12668,17 +12690,7 @@ function StateIndicator({
12668
12690
  className
12669
12691
  ),
12670
12692
  children: [
12671
- /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
12672
- "img",
12673
- {
12674
- src: assetUrl.url,
12675
- alt: displayLabel,
12676
- width: 16,
12677
- height: 16,
12678
- style: { imageRendering: "pixelated", objectFit: "contain" },
12679
- className: "flex-shrink-0"
12680
- }
12681
- ) : typeof config.icon === "string" ? /^[a-zA-Z0-9-]+$/.test(config.icon) ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: config.icon }) : config.icon : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: config.icon }) }),
12693
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(Icon, { name: config.icon }) : config.icon : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: config.icon }) }),
12682
12694
  /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", children: displayLabel })
12683
12695
  ]
12684
12696
  }
@@ -12690,6 +12702,7 @@ var init_StateIndicator = __esm({
12690
12702
  init_Box();
12691
12703
  init_Icon();
12692
12704
  init_cn();
12705
+ init_GameIcon();
12693
12706
  DEFAULT_ASSET_URL3 = {
12694
12707
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
12695
12708
  role: "ui",
@@ -12743,29 +12756,31 @@ function TimerDisplay({
12743
12756
  }) {
12744
12757
  const isLow = lowThreshold != null && seconds <= lowThreshold && seconds > 0;
12745
12758
  return /* @__PURE__ */ jsxRuntime.jsxs(
12746
- "div",
12759
+ Box,
12747
12760
  {
12748
12761
  className: cn(
12749
12762
  "inline-flex items-center gap-1 justify-center rounded-container",
12750
12763
  "bg-card/80 border border-muted font-mono font-bold tabular-nums",
12751
- sizeMap4[size],
12764
+ sizeMap5[size],
12752
12765
  running && "border-success/50",
12753
12766
  isLow && "text-error border-error/50 animate-pulse",
12754
12767
  !isLow && "text-foreground",
12755
12768
  className
12756
12769
  ),
12757
12770
  children: [
12758
- iconAsset && /* @__PURE__ */ jsxRuntime.jsx("img", { src: iconAsset.url, alt: "", className: "w-4 h-4 object-contain flex-shrink-0" }),
12771
+ iconAsset && /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl: iconAsset, icon: "image", size: 16, className: "w-4 h-4 object-contain flex-shrink-0" }),
12759
12772
  formatTime(seconds, format)
12760
12773
  ]
12761
12774
  }
12762
12775
  );
12763
12776
  }
12764
- var sizeMap4;
12777
+ var sizeMap5;
12765
12778
  var init_TimerDisplay = __esm({
12766
12779
  "components/game/2d/atoms/TimerDisplay.tsx"() {
12767
12780
  init_cn();
12768
- sizeMap4 = {
12781
+ init_Box();
12782
+ init_GameIcon();
12783
+ sizeMap5 = {
12769
12784
  sm: "text-sm px-2 py-0.5",
12770
12785
  md: "text-lg px-3 py-1",
12771
12786
  lg: "text-2xl px-4 py-1.5"
@@ -12783,9 +12798,9 @@ function ResourceCounter({
12783
12798
  size = "md",
12784
12799
  className
12785
12800
  }) {
12786
- const sizes = sizeMap5[size];
12801
+ const sizes = sizeMap6[size];
12787
12802
  return /* @__PURE__ */ jsxRuntime.jsxs(
12788
- "div",
12803
+ Box,
12789
12804
  {
12790
12805
  className: cn(
12791
12806
  "inline-flex items-center rounded-container",
@@ -12794,21 +12809,11 @@ function ResourceCounter({
12794
12809
  className
12795
12810
  ),
12796
12811
  children: [
12797
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
12798
- "img",
12799
- {
12800
- src: assetUrl.url,
12801
- alt: label,
12802
- width: sizes.img,
12803
- height: sizes.img,
12804
- style: { imageRendering: "pixelated", objectFit: "contain" },
12805
- className: "flex-shrink-0"
12806
- }
12807
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }) : null,
12808
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: label }),
12809
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
12812
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: sizes.img, alt: label, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }) : null,
12813
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
12814
+ /* @__PURE__ */ jsxRuntime.jsxs(Typography, { as: "span", className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
12810
12815
  value,
12811
- max != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
12816
+ max != null && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
12812
12817
  "/",
12813
12818
  max
12814
12819
  ] })
@@ -12817,11 +12822,14 @@ function ResourceCounter({
12817
12822
  }
12818
12823
  );
12819
12824
  }
12820
- var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap5;
12825
+ var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap6;
12821
12826
  var init_ResourceCounter = __esm({
12822
12827
  "components/game/2d/atoms/ResourceCounter.tsx"() {
12823
12828
  init_cn();
12824
12829
  init_Icon();
12830
+ init_Box();
12831
+ init_Typography();
12832
+ init_GameIcon();
12825
12833
  colorTokenClasses2 = {
12826
12834
  primary: "text-primary",
12827
12835
  secondary: "text-secondary",
@@ -12835,7 +12843,7 @@ var init_ResourceCounter = __esm({
12835
12843
  role: "ui",
12836
12844
  category: "coin"
12837
12845
  };
12838
- sizeMap5 = {
12846
+ sizeMap6 = {
12839
12847
  sm: { wrapper: "text-xs gap-1 px-1.5 py-0.5", icon: "text-sm", img: 16 },
12840
12848
  md: { wrapper: "text-sm gap-1.5 px-2 py-1", icon: "text-base", img: 20 },
12841
12849
  lg: { wrapper: "text-base gap-2 px-3 py-1.5", icon: "text-lg", img: 28 }
@@ -12860,9 +12868,9 @@ function ItemSlot({
12860
12868
  const isClickable = onClick != null || action != null;
12861
12869
  const px = assetSizeMap[size];
12862
12870
  return /* @__PURE__ */ jsxRuntime.jsx(
12863
- "button",
12871
+ Button,
12864
12872
  {
12865
- type: "button",
12873
+ variant: "ghost",
12866
12874
  onClick: () => {
12867
12875
  if (action) eventBus.emit(`UI:${action}`, {});
12868
12876
  onClick?.();
@@ -12872,7 +12880,7 @@ function ItemSlot({
12872
12880
  className: cn(
12873
12881
  "relative flex items-center justify-center rounded-interactive border-2",
12874
12882
  "bg-card/80 transition-all duration-150",
12875
- sizeMap6[size],
12883
+ sizeMap7[size],
12876
12884
  empty ? "border-border bg-card/50" : rarityBorderMap[rarity],
12877
12885
  !empty && rarityGlowMap[rarity],
12878
12886
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background",
@@ -12881,21 +12889,12 @@ function ItemSlot({
12881
12889
  !isClickable && "cursor-default",
12882
12890
  className
12883
12891
  ),
12884
- children: empty ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12885
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
12886
- "img",
12887
- {
12888
- src: assetUrl?.url,
12889
- alt: label,
12890
- width: px,
12891
- height: px,
12892
- style: { imageRendering: "pixelated", objectFit: "contain" },
12893
- className: "flex-shrink-0"
12894
- }
12895
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }) : null,
12892
+ children: empty ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12893
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: px, alt: label, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }) : null,
12896
12894
  quantity != null && quantity > 1 && /* @__PURE__ */ jsxRuntime.jsx(
12897
- "span",
12895
+ Typography,
12898
12896
  {
12897
+ as: "span",
12899
12898
  className: cn(
12900
12899
  "absolute -bottom-1 -right-1 flex items-center justify-center",
12901
12900
  "min-w-[18px] h-[18px] rounded-full px-1",
@@ -12908,14 +12907,18 @@ function ItemSlot({
12908
12907
  }
12909
12908
  );
12910
12909
  }
12911
- var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
12910
+ var sizeMap7, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
12912
12911
  var init_ItemSlot = __esm({
12913
12912
  "components/game/2d/atoms/ItemSlot.tsx"() {
12914
12913
  "use client";
12915
12914
  init_cn();
12916
12915
  init_Icon();
12917
12916
  init_useEventBus();
12918
- sizeMap6 = {
12917
+ init_Button();
12918
+ init_Box();
12919
+ init_Typography();
12920
+ init_GameIcon();
12921
+ sizeMap7 = {
12919
12922
  sm: "w-10 h-10 text-lg",
12920
12923
  md: "w-14 h-14 text-2xl",
12921
12924
  lg: "w-18 h-18 text-3xl"
@@ -12956,9 +12959,9 @@ function TurnIndicator({
12956
12959
  size = "md",
12957
12960
  className
12958
12961
  }) {
12959
- const sizes = sizeMap7[size];
12962
+ const sizes = sizeMap8[size];
12960
12963
  return /* @__PURE__ */ jsxRuntime.jsxs(
12961
- "div",
12964
+ Box,
12962
12965
  {
12963
12966
  className: cn(
12964
12967
  "inline-flex items-center rounded-container",
@@ -12967,42 +12970,35 @@ function TurnIndicator({
12967
12970
  className
12968
12971
  ),
12969
12972
  children: [
12970
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold tabular-nums", children: [
12973
+ /* @__PURE__ */ jsxRuntime.jsxs(Typography, { as: "span", className: "font-bold tabular-nums", children: [
12971
12974
  "Turn ",
12972
12975
  currentTurn,
12973
- maxTurns != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
12976
+ maxTurns != null && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
12974
12977
  "/",
12975
12978
  maxTurns
12976
12979
  ] })
12977
12980
  ] }),
12978
12981
  phase && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12979
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "|" }),
12980
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: phase })
12982
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
12983
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-muted-foreground", children: phase })
12981
12984
  ] }),
12982
12985
  activeTeam && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12983
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "|" }),
12984
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
12985
- "img",
12986
- {
12987
- src: assetUrl.url,
12988
- alt: "",
12989
- width: 12,
12990
- height: 12,
12991
- style: { imageRendering: "pixelated", objectFit: "contain" },
12992
- className: "flex-shrink-0"
12993
- }
12994
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("rounded-full bg-success/20", sizes.dot) }),
12995
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-success", children: activeTeam })
12986
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
12987
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 12, className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: cn("rounded-full bg-success/20", sizes.dot) }),
12988
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-success", children: activeTeam })
12996
12989
  ] })
12997
12990
  ]
12998
12991
  }
12999
12992
  );
13000
12993
  }
13001
- var sizeMap7, DEFAULT_ASSET_URL6;
12994
+ var sizeMap8, DEFAULT_ASSET_URL6;
13002
12995
  var init_TurnIndicator = __esm({
13003
12996
  "components/game/2d/atoms/TurnIndicator.tsx"() {
13004
12997
  init_cn();
13005
- sizeMap7 = {
12998
+ init_Box();
12999
+ init_Typography();
13000
+ init_GameIcon();
13001
+ sizeMap8 = {
13006
13002
  sm: { wrapper: "text-xs gap-1.5 px-2 py-0.5", dot: "w-1.5 h-1.5" },
13007
13003
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
13008
13004
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
@@ -13034,10 +13030,10 @@ function ComboCounter({
13034
13030
  size = "md",
13035
13031
  className
13036
13032
  }) {
13037
- const sizes = sizeMap8[size];
13033
+ const sizes = sizeMap9[size];
13038
13034
  if (combo <= 0) return null;
13039
13035
  return /* @__PURE__ */ jsxRuntime.jsxs(
13040
- "div",
13036
+ Box,
13041
13037
  {
13042
13038
  className: cn(
13043
13039
  "inline-flex flex-col items-center justify-center",
@@ -13047,24 +13043,14 @@ function ComboCounter({
13047
13043
  className
13048
13044
  ),
13049
13045
  children: [
13050
- assetUrl && /* @__PURE__ */ jsxRuntime.jsx(
13051
- "img",
13052
- {
13053
- src: assetUrl.url,
13054
- alt: "combo",
13055
- width: 24,
13056
- height: 24,
13057
- style: { imageRendering: "pixelated", objectFit: "contain" },
13058
- className: "flex-shrink-0 mb-0.5"
13059
- }
13060
- ),
13061
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
13062
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
13063
- multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
13046
+ assetUrl && /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0 mb-0.5" }),
13047
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
13048
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
13049
+ multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { as: "span", className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
13064
13050
  "x",
13065
13051
  multiplier.toFixed(1)
13066
13052
  ] }),
13067
- streak != null && streak > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
13053
+ streak != null && streak > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { as: "span", className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
13068
13054
  streak,
13069
13055
  " streak"
13070
13056
  ] })
@@ -13072,16 +13058,19 @@ function ComboCounter({
13072
13058
  }
13073
13059
  );
13074
13060
  }
13075
- var DEFAULT_ASSET_URL7, sizeMap8;
13061
+ var DEFAULT_ASSET_URL7, sizeMap9;
13076
13062
  var init_ComboCounter = __esm({
13077
13063
  "components/game/2d/atoms/ComboCounter.tsx"() {
13078
13064
  init_cn();
13065
+ init_Box();
13066
+ init_Typography();
13067
+ init_GameIcon();
13079
13068
  DEFAULT_ASSET_URL7 = {
13080
13069
  url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
13081
13070
  role: "effect",
13082
13071
  category: "effect"
13083
13072
  };
13084
- sizeMap8 = {
13073
+ sizeMap9 = {
13085
13074
  sm: { combo: "text-lg", label: "text-xs", multiplier: "text-xs" },
13086
13075
  md: { combo: "text-2xl", label: "text-xs", multiplier: "text-sm" },
13087
13076
  lg: { combo: "text-4xl", label: "text-sm", multiplier: "text-base" }
@@ -13098,54 +13087,48 @@ function WaypointMarker({
13098
13087
  size = "md",
13099
13088
  className
13100
13089
  }) {
13101
- const sizes = sizeMap9[size];
13102
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col items-center", className), children: [
13103
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center", children: [
13090
+ const sizes = sizeMap10[size];
13091
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: cn("flex flex-col items-center", className), children: [
13092
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative flex items-center justify-center", children: [
13104
13093
  active && /* @__PURE__ */ jsxRuntime.jsx(
13105
- "div",
13094
+ Box,
13106
13095
  {
13096
+ position: "absolute",
13107
13097
  className: cn(
13108
- "absolute rounded-full border-2 border-info animate-ping opacity-50",
13098
+ "rounded-full border-2 border-info animate-ping opacity-50",
13109
13099
  sizes.ring
13110
13100
  )
13111
13101
  }
13112
13102
  ),
13113
13103
  active && /* @__PURE__ */ jsxRuntime.jsx(
13114
- "div",
13104
+ Box,
13115
13105
  {
13106
+ position: "absolute",
13116
13107
  className: cn(
13117
- "absolute rounded-full border-2 border-info",
13108
+ "rounded-full border-2 border-info",
13118
13109
  sizes.ring
13119
13110
  )
13120
13111
  }
13121
13112
  ),
13122
13113
  /* @__PURE__ */ jsxRuntime.jsx(
13123
- "div",
13114
+ Box,
13124
13115
  {
13116
+ position: "relative",
13125
13117
  className: cn(
13126
- "relative flex items-center justify-center rounded-full transition-all duration-200",
13118
+ "flex items-center justify-center rounded-full transition-all duration-200",
13127
13119
  sizes.dot,
13128
13120
  completed && "bg-success text-foreground",
13129
13121
  active && !completed && "bg-info text-foreground",
13130
13122
  !active && !completed && "bg-muted"
13131
13123
  ),
13132
- children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
13133
- "img",
13134
- {
13135
- src: assetUrl.url,
13136
- alt: label,
13137
- width: sizes.img,
13138
- height: sizes.img,
13139
- style: { imageRendering: "pixelated", objectFit: "contain" },
13140
- className: "flex-shrink-0"
13141
- }
13142
- ) : icon ? typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) : null
13124
+ children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: sizes.img, alt: label, className: "flex-shrink-0" }) : icon ? typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) : null
13143
13125
  }
13144
13126
  )
13145
13127
  ] }),
13146
13128
  label && /* @__PURE__ */ jsxRuntime.jsx(
13147
- "span",
13129
+ Typography,
13148
13130
  {
13131
+ as: "span",
13149
13132
  className: cn(
13150
13133
  "text-center whitespace-nowrap",
13151
13134
  sizes.label,
@@ -13156,17 +13139,20 @@ function WaypointMarker({
13156
13139
  )
13157
13140
  ] });
13158
13141
  }
13159
- var DEFAULT_ASSET_URL8, sizeMap9, checkIcon;
13142
+ var DEFAULT_ASSET_URL8, sizeMap10, checkIcon;
13160
13143
  var init_WaypointMarker = __esm({
13161
13144
  "components/game/2d/atoms/WaypointMarker.tsx"() {
13162
13145
  init_cn();
13163
13146
  init_Icon();
13147
+ init_Box();
13148
+ init_Typography();
13149
+ init_GameIcon();
13164
13150
  DEFAULT_ASSET_URL8 = {
13165
13151
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
13166
13152
  role: "ui",
13167
13153
  category: "waypoint"
13168
13154
  };
13169
- sizeMap9 = {
13155
+ sizeMap10 = {
13170
13156
  sm: { dot: "w-4 h-4", ring: "w-6 h-6", label: "text-xs mt-1", img: 12 },
13171
13157
  md: { dot: "w-6 h-6", ring: "w-8 h-8", label: "text-sm mt-1.5", img: 18 },
13172
13158
  lg: { dot: "w-8 h-8", ring: "w-10 h-10", label: "text-base mt-2", img: 24 }
@@ -13191,32 +13177,24 @@ function StatusEffect({
13191
13177
  size = "md",
13192
13178
  className
13193
13179
  }) {
13194
- const sizes = sizeMap10[size];
13195
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative inline-flex flex-col items-center", className), children: [
13180
+ const sizes = sizeMap11[size];
13181
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { position: "relative", className: cn("inline-flex flex-col items-center", className), children: [
13196
13182
  /* @__PURE__ */ jsxRuntime.jsxs(
13197
- "div",
13183
+ Box,
13198
13184
  {
13185
+ position: "relative",
13199
13186
  className: cn(
13200
- "relative flex items-center justify-center rounded-interactive border-2",
13187
+ "flex items-center justify-center rounded-interactive border-2",
13201
13188
  sizes.container,
13202
13189
  variantStyles7[variant]
13203
13190
  ),
13204
13191
  title: label,
13205
13192
  children: [
13206
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
13207
- "img",
13208
- {
13209
- src: assetUrl.url,
13210
- alt: label,
13211
- width: sizes.img,
13212
- height: sizes.img,
13213
- style: { imageRendering: "pixelated", objectFit: "contain" },
13214
- className: "flex-shrink-0"
13215
- }
13216
- ) : icon != null && typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, size: "sm" }) : null }),
13193
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: sizes.img, alt: label, className: "flex-shrink-0" }) : icon != null && typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, size: "sm" }) : null }),
13217
13194
  duration !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
13218
- "span",
13195
+ Typography,
13219
13196
  {
13197
+ as: "span",
13220
13198
  className: cn(
13221
13199
  "absolute bottom-0 left-0 right-0 text-center font-mono font-bold text-foreground bg-background/60 leading-tight",
13222
13200
  sizes.timer
@@ -13228,8 +13206,9 @@ function StatusEffect({
13228
13206
  }
13229
13207
  ),
13230
13208
  stacks !== void 0 && stacks > 1 && /* @__PURE__ */ jsxRuntime.jsx(
13231
- "span",
13209
+ Typography,
13232
13210
  {
13211
+ as: "span",
13233
13212
  className: cn(
13234
13213
  "absolute flex items-center justify-center rounded-full bg-card text-foreground font-bold leading-none",
13235
13214
  sizes.badge
@@ -13237,20 +13216,23 @@ function StatusEffect({
13237
13216
  children: stacks
13238
13217
  }
13239
13218
  ),
13240
- label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
13219
+ label && /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
13241
13220
  ] });
13242
13221
  }
13243
- var DEFAULT_ASSET_URL9, sizeMap10, variantStyles7;
13222
+ var DEFAULT_ASSET_URL9, sizeMap11, variantStyles7;
13244
13223
  var init_StatusEffect = __esm({
13245
13224
  "components/game/2d/atoms/StatusEffect.tsx"() {
13246
13225
  init_cn();
13247
13226
  init_Icon();
13227
+ init_Box();
13228
+ init_Typography();
13229
+ init_GameIcon();
13248
13230
  DEFAULT_ASSET_URL9 = {
13249
13231
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
13250
13232
  role: "ui",
13251
13233
  category: "effect"
13252
13234
  };
13253
- sizeMap10 = {
13235
+ sizeMap11 = {
13254
13236
  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 },
13255
13237
  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 },
13256
13238
  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 }
@@ -13274,38 +13256,31 @@ function DamageNumber({
13274
13256
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13275
13257
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: floatKeyframes }),
13276
13258
  /* @__PURE__ */ jsxRuntime.jsxs(
13277
- "span",
13259
+ Typography,
13278
13260
  {
13261
+ as: "span",
13279
13262
  className: cn(
13280
13263
  "inline-flex items-center gap-0.5 font-mono select-none pointer-events-none",
13281
- sizeMap11[size],
13264
+ sizeMap12[size],
13282
13265
  typeStyles[type],
13283
13266
  className
13284
13267
  ),
13285
13268
  style: { animation: "damageFloat 1s ease-out forwards" },
13286
13269
  children: [
13287
- assetUrl && /* @__PURE__ */ jsxRuntime.jsx(
13288
- "img",
13289
- {
13290
- src: assetUrl.url,
13291
- alt: "",
13292
- width: 14,
13293
- height: 14,
13294
- style: { imageRendering: "pixelated", objectFit: "contain" },
13295
- className: "flex-shrink-0"
13296
- }
13297
- ),
13270
+ assetUrl && /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 14, className: "flex-shrink-0" }),
13298
13271
  displayText
13299
13272
  ]
13300
13273
  }
13301
13274
  )
13302
13275
  ] });
13303
13276
  }
13304
- var sizeMap11, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
13277
+ var sizeMap12, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
13305
13278
  var init_DamageNumber = __esm({
13306
13279
  "components/game/2d/atoms/DamageNumber.tsx"() {
13307
13280
  init_cn();
13308
- sizeMap11 = {
13281
+ init_Typography();
13282
+ init_GameIcon();
13283
+ sizeMap12 = {
13309
13284
  sm: "text-sm",
13310
13285
  md: "text-lg",
13311
13286
  lg: "text-2xl"
@@ -13339,7 +13314,7 @@ function DialogueBubble({
13339
13314
  className
13340
13315
  }) {
13341
13316
  return /* @__PURE__ */ jsxRuntime.jsxs(
13342
- "div",
13317
+ Box,
13343
13318
  {
13344
13319
  className: cn(
13345
13320
  "flex items-start gap-3 rounded-container bg-background/80 backdrop-blur-sm px-4 py-3 border border-border/10",
@@ -13347,17 +13322,10 @@ function DialogueBubble({
13347
13322
  className
13348
13323
  ),
13349
13324
  children: [
13350
- portrait && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 w-12 h-12 rounded-full overflow-hidden border-2 border-warning/60", children: /* @__PURE__ */ jsxRuntime.jsx(
13351
- "img",
13352
- {
13353
- src: portrait?.url,
13354
- alt: speaker ?? "speaker",
13355
- className: "w-full h-full object-cover"
13356
- }
13357
- ) }),
13358
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
13359
- speaker && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold text-warning", children: speaker }),
13360
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-foreground leading-relaxed", children: text })
13325
+ portrait && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-shrink-0 w-12 h-12 rounded-full overflow-hidden border-2 border-warning/60", children: /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl: portrait, icon: "image", size: 48, alt: speaker ?? "speaker", className: "w-full h-full object-cover" }) }),
13326
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex flex-col gap-1 min-w-0", children: [
13327
+ speaker && /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-sm font-bold text-warning", children: speaker }),
13328
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-sm text-foreground leading-relaxed", children: text })
13361
13329
  ] })
13362
13330
  ]
13363
13331
  }
@@ -13367,6 +13335,9 @@ var DEFAULT_PORTRAIT;
13367
13335
  var init_DialogueBubble = __esm({
13368
13336
  "components/game/2d/atoms/DialogueBubble.tsx"() {
13369
13337
  init_cn();
13338
+ init_Box();
13339
+ init_Typography();
13340
+ init_GameIcon();
13370
13341
  DEFAULT_PORTRAIT = {
13371
13342
  url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
13372
13343
  role: "effect",
@@ -13388,11 +13359,11 @@ function ChoiceButton({
13388
13359
  }) {
13389
13360
  const eventBus = useEventBus();
13390
13361
  return /* @__PURE__ */ jsxRuntime.jsxs(
13391
- "button",
13362
+ Button,
13392
13363
  {
13393
- type: "button",
13364
+ variant: "ghost",
13394
13365
  disabled,
13395
- onClick: (e) => {
13366
+ onClick: () => {
13396
13367
  if (action) eventBus.emit(`UI:${action}`, {});
13397
13368
  onClick?.();
13398
13369
  },
@@ -13405,8 +13376,9 @@ function ChoiceButton({
13405
13376
  ),
13406
13377
  children: [
13407
13378
  index !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(
13408
- "span",
13379
+ Typography,
13409
13380
  {
13381
+ as: "span",
13410
13382
  className: cn(
13411
13383
  "flex-shrink-0 font-mono font-bold text-sm",
13412
13384
  selected ? "text-accent" : "text-muted-foreground"
@@ -13417,24 +13389,14 @@ function ChoiceButton({
13417
13389
  ]
13418
13390
  }
13419
13391
  ),
13420
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
13421
- "img",
13422
- {
13423
- src: assetUrl.url,
13424
- alt: "",
13425
- width: 16,
13426
- height: 16,
13427
- style: { imageRendering: "pixelated", objectFit: "contain" },
13428
- className: "flex-shrink-0"
13429
- }
13430
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
13392
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 16, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
13431
13393
  const I = resolveIcon(icon);
13432
13394
  return I ? /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-4 h-4" }) : null;
13433
13395
  })() : /* @__PURE__ */ (() => {
13434
13396
  const I = icon;
13435
13397
  return /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-4 h-4" });
13436
13398
  })() }) : null,
13437
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-snug", children: text })
13399
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-sm leading-snug", children: text })
13438
13400
  ]
13439
13401
  }
13440
13402
  );
@@ -13444,6 +13406,10 @@ var init_ChoiceButton = __esm({
13444
13406
  init_cn();
13445
13407
  init_Icon();
13446
13408
  init_useEventBus();
13409
+ init_Button();
13410
+ init_Box();
13411
+ init_Typography();
13412
+ init_GameIcon();
13447
13413
  ChoiceButton.displayName = "ChoiceButton";
13448
13414
  }
13449
13415
  });
@@ -13461,16 +13427,16 @@ function ActionButton({
13461
13427
  className
13462
13428
  }) {
13463
13429
  const eventBus = useEventBus();
13464
- const sizes = sizeMap12[size];
13430
+ const sizes = sizeMap13[size];
13465
13431
  const onCooldown = cooldown > 0;
13466
13432
  const isDisabled = disabled || onCooldown;
13467
13433
  const cooldownDeg = Math.round(cooldown * 360);
13468
13434
  return /* @__PURE__ */ jsxRuntime.jsxs(
13469
- "button",
13435
+ Button,
13470
13436
  {
13471
- type: "button",
13437
+ variant: variant === "danger" ? "danger" : variant === "secondary" ? "secondary" : "primary",
13472
13438
  disabled: isDisabled,
13473
- onClick: (e) => {
13439
+ onClick: () => {
13474
13440
  if (action) eventBus.emit(`UI:${action}`, {});
13475
13441
  onClick?.();
13476
13442
  },
@@ -13483,9 +13449,10 @@ function ActionButton({
13483
13449
  ),
13484
13450
  children: [
13485
13451
  onCooldown && /* @__PURE__ */ jsxRuntime.jsx(
13486
- "div",
13452
+ Box,
13487
13453
  {
13488
- className: "absolute inset-0 bg-foreground/40 pointer-events-none",
13454
+ position: "absolute",
13455
+ className: "inset-0 bg-foreground/40 pointer-events-none",
13489
13456
  style: {
13490
13457
  clipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
13491
13458
  WebkitClipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
@@ -13493,27 +13460,18 @@ function ActionButton({
13493
13460
  }
13494
13461
  }
13495
13462
  ),
13496
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
13497
- "img",
13498
- {
13499
- src: assetUrl.url,
13500
- alt: "",
13501
- width: 16,
13502
- height: 16,
13503
- style: { imageRendering: "pixelated", objectFit: "contain" },
13504
- className: cn("flex-shrink-0", sizes.icon)
13505
- }
13506
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
13463
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 16, className: cn("flex-shrink-0", sizes.icon) }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
13507
13464
  const I = resolveIcon(icon);
13508
13465
  return I ? /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-4 h-4" }) : null;
13509
13466
  })() : /* @__PURE__ */ (() => {
13510
13467
  const I = icon;
13511
13468
  return /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-4 h-4" });
13512
13469
  })() }) : null,
13513
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative z-10", children: label }),
13470
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "relative z-10", children: label }),
13514
13471
  hotkey && /* @__PURE__ */ jsxRuntime.jsx(
13515
- "span",
13472
+ Typography,
13516
13473
  {
13474
+ as: "span",
13517
13475
  className: cn(
13518
13476
  "absolute top-0.5 right-0.5 bg-foreground/30 text-primary-foreground rounded font-mono leading-tight",
13519
13477
  sizes.hotkey
@@ -13525,13 +13483,17 @@ function ActionButton({
13525
13483
  }
13526
13484
  );
13527
13485
  }
13528
- var sizeMap12, variantStyles8, DEFAULT_ASSET_URL11;
13486
+ var sizeMap13, variantStyles8, DEFAULT_ASSET_URL11;
13529
13487
  var init_ActionButton = __esm({
13530
13488
  "components/game/2d/atoms/ActionButton.tsx"() {
13531
13489
  init_cn();
13532
13490
  init_Icon();
13533
13491
  init_useEventBus();
13534
- sizeMap12 = {
13492
+ init_Button();
13493
+ init_Box();
13494
+ init_Typography();
13495
+ init_GameIcon();
13496
+ sizeMap13 = {
13535
13497
  sm: { button: "h-button-sm px-3 text-xs", hotkey: "text-[9px] px-1", icon: "text-xs" },
13536
13498
  md: { button: "h-button-md px-4 text-sm", hotkey: "text-xs px-1.5", icon: "text-sm" },
13537
13499
  lg: { button: "h-button-lg px-5 text-base", hotkey: "text-xs px-2", icon: "text-base" }
@@ -13633,10 +13595,12 @@ function MiniMap({
13633
13595
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13634
13596
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: `@keyframes minimap-blink{0%,49%{opacity:1}50%,100%{opacity:0}}` }),
13635
13597
  /* @__PURE__ */ jsxRuntime.jsxs(
13636
- "div",
13598
+ Box,
13637
13599
  {
13600
+ position: "relative",
13601
+ display: "inline-block",
13638
13602
  className: cn(
13639
- "relative inline-block border border-border/20 rounded-container",
13603
+ "border border-border/20 rounded-container",
13640
13604
  className
13641
13605
  ),
13642
13606
  children: [
@@ -13651,10 +13615,10 @@ function MiniMap({
13651
13615
  }
13652
13616
  ),
13653
13617
  playerLeft !== null && playerTop !== null && /* @__PURE__ */ jsxRuntime.jsx(
13654
- "div",
13618
+ Box,
13655
13619
  {
13620
+ position: "absolute",
13656
13621
  style: {
13657
- position: "absolute",
13658
13622
  left: playerLeft,
13659
13623
  top: playerTop,
13660
13624
  width: 3,
@@ -13675,6 +13639,7 @@ var init_MiniMap = __esm({
13675
13639
  "components/game/2d/atoms/MiniMap.tsx"() {
13676
13640
  "use client";
13677
13641
  init_cn();
13642
+ init_Box();
13678
13643
  DEFAULT_TILES = [
13679
13644
  { x: 10, y: 10, color: "#4ade80" },
13680
13645
  { x: 20, y: 15, color: "#4ade80" },
@@ -13692,38 +13657,6 @@ var init_MiniMap = __esm({
13692
13657
  MiniMap.displayName = "MiniMap";
13693
13658
  }
13694
13659
  });
13695
- function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
13696
- const px = typeof size === "number" ? size : sizeMap13[size];
13697
- if (assetUrl?.url) {
13698
- return /* @__PURE__ */ jsxRuntime.jsx(
13699
- "img",
13700
- {
13701
- src: assetUrl.url,
13702
- alt: alt ?? assetUrl.category ?? "",
13703
- width: px,
13704
- height: px,
13705
- style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
13706
- className: cn("flex-shrink-0", className)
13707
- }
13708
- );
13709
- }
13710
- const I = typeof icon === "string" ? resolveIcon(icon) : icon;
13711
- return /* @__PURE__ */ jsxRuntime.jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
13712
- }
13713
- var sizeMap13;
13714
- var init_GameIcon = __esm({
13715
- "components/game/2d/atoms/GameIcon.tsx"() {
13716
- "use client";
13717
- init_cn();
13718
- init_Icon();
13719
- sizeMap13 = {
13720
- sm: 16,
13721
- md: 24,
13722
- lg: 32
13723
- };
13724
- GameIcon.displayName = "GameIcon";
13725
- }
13726
- });
13727
13660
  function ControlGrid({
13728
13661
  kind,
13729
13662
  buttons = DEFAULT_BUTTONS,
@@ -13784,22 +13717,22 @@ function ControlGrid({
13784
13717
  },
13785
13718
  d
13786
13719
  );
13787
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
13788
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
13720
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
13721
+ /* @__PURE__ */ jsxRuntime.jsx(Box, {}),
13789
13722
  dir("up"),
13790
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
13723
+ /* @__PURE__ */ jsxRuntime.jsx(Box, {}),
13791
13724
  dir("left"),
13792
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-6 h-6 rounded-interactive bg-muted border-2 border-muted-foreground" }) }),
13725
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-6 h-6 rounded-interactive bg-muted border-2 border-muted-foreground" }) }),
13793
13726
  dir("right"),
13794
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
13727
+ /* @__PURE__ */ jsxRuntime.jsx(Box, {}),
13795
13728
  dir("down"),
13796
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
13729
+ /* @__PURE__ */ jsxRuntime.jsx(Box, {})
13797
13730
  ] });
13798
13731
  }
13799
13732
  if (layout === "diamond" && buttons.length === 4) {
13800
13733
  const [top, right, bottom, left] = buttons;
13801
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(layoutClass.diamond, className), children: [
13802
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
13734
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: cn(layoutClass.diamond, className), children: [
13735
+ /* @__PURE__ */ jsxRuntime.jsx(Box, {}),
13803
13736
  /* @__PURE__ */ jsxRuntime.jsx(
13804
13737
  ControlButton,
13805
13738
  {
@@ -13814,7 +13747,7 @@ function ControlGrid({
13814
13747
  disabled
13815
13748
  }
13816
13749
  ),
13817
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
13750
+ /* @__PURE__ */ jsxRuntime.jsx(Box, {}),
13818
13751
  /* @__PURE__ */ jsxRuntime.jsx(
13819
13752
  ControlButton,
13820
13753
  {
@@ -13829,7 +13762,7 @@ function ControlGrid({
13829
13762
  disabled
13830
13763
  }
13831
13764
  ),
13832
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
13765
+ /* @__PURE__ */ jsxRuntime.jsx(Box, {}),
13833
13766
  /* @__PURE__ */ jsxRuntime.jsx(
13834
13767
  ControlButton,
13835
13768
  {
@@ -13844,7 +13777,7 @@ function ControlGrid({
13844
13777
  disabled
13845
13778
  }
13846
13779
  ),
13847
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
13780
+ /* @__PURE__ */ jsxRuntime.jsx(Box, {}),
13848
13781
  /* @__PURE__ */ jsxRuntime.jsx(
13849
13782
  ControlButton,
13850
13783
  {
@@ -13859,10 +13792,10 @@ function ControlGrid({
13859
13792
  disabled
13860
13793
  }
13861
13794
  ),
13862
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
13795
+ /* @__PURE__ */ jsxRuntime.jsx(Box, {})
13863
13796
  ] });
13864
13797
  }
13865
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsxRuntime.jsx(
13798
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsxRuntime.jsx(
13866
13799
  ControlButton,
13867
13800
  {
13868
13801
  icon: button.icon,
@@ -13884,6 +13817,7 @@ var init_ControlGrid = __esm({
13884
13817
  "use client";
13885
13818
  init_cn();
13886
13819
  init_useEventBus();
13820
+ init_Box();
13887
13821
  init_ControlButton();
13888
13822
  sizeKey = { sm: "sm", md: "md", lg: "lg" };
13889
13823
  layoutClass = {
@@ -13928,7 +13862,7 @@ function StatBadge({
13928
13862
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
13929
13863
  const resolvedAsset = iconUrl ?? assetUrl;
13930
13864
  return /* @__PURE__ */ jsxRuntime.jsxs(
13931
- "div",
13865
+ Box,
13932
13866
  {
13933
13867
  className: cn(
13934
13868
  "inline-flex items-center gap-2 rounded-container border backdrop-blur-sm",
@@ -13937,18 +13871,8 @@ function StatBadge({
13937
13871
  className
13938
13872
  ),
13939
13873
  children: [
13940
- resolvedAsset ? /* @__PURE__ */ jsxRuntime.jsx(
13941
- "img",
13942
- {
13943
- src: resolvedAsset.url,
13944
- alt: "",
13945
- width: 16,
13946
- height: 16,
13947
- style: { imageRendering: "pixelated", objectFit: "contain" },
13948
- className: "flex-shrink-0"
13949
- }
13950
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 text-lg", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, className: "w-4 h-4" }) }) : null,
13951
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-medium", children: label }),
13874
+ resolvedAsset ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl: resolvedAsset, icon: "image", size: 16, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: "flex-shrink-0 text-lg", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, className: "w-4 h-4" }) }) : null,
13875
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "text-muted-foreground font-medium", children: label }),
13952
13876
  format === "hearts" && max && /* @__PURE__ */ jsxRuntime.jsx(
13953
13877
  HealthBar,
13954
13878
  {
@@ -13974,7 +13898,7 @@ function StatBadge({
13974
13898
  size: size === "lg" ? "md" : "sm"
13975
13899
  }
13976
13900
  ),
13977
- format === "text" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold text-foreground", children: value })
13901
+ format === "text" && /* @__PURE__ */ jsxRuntime.jsx(Typography, { as: "span", className: "font-bold text-foreground", children: value })
13978
13902
  ]
13979
13903
  }
13980
13904
  );
@@ -13984,6 +13908,9 @@ var init_StatBadge = __esm({
13984
13908
  "components/game/2d/molecules/StatBadge.tsx"() {
13985
13909
  init_cn();
13986
13910
  init_Icon();
13911
+ init_Box();
13912
+ init_Typography();
13913
+ init_GameIcon();
13987
13914
  init_HealthBar();
13988
13915
  init_ScoreDisplay();
13989
13916
  sizeMap14 = {
@@ -14161,9 +14088,9 @@ function GameHud({
14161
14088
  if (position === "corners") {
14162
14089
  const leftStats = stats.slice(0, Math.ceil(stats.length / 2));
14163
14090
  const rightStats = stats.slice(Math.ceil(stats.length / 2));
14164
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", positionMap[position], className), children: [
14165
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-4 left-4 flex flex-col gap-2 pointer-events-auto", children: leftStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) }),
14166
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-4 right-4 flex flex-col gap-2 items-end pointer-events-auto", children: rightStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) })
14091
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { position: "relative", className: cn(positionMap[position], className), children: [
14092
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { position: "absolute", className: "top-4 left-4 flex flex-col gap-2 pointer-events-auto", children: leftStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) }),
14093
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) })
14167
14094
  ] });
14168
14095
  }
14169
14096
  if (position === "top" || position === "bottom") {
@@ -14172,7 +14099,7 @@ function GameHud({
14172
14099
  const rightStats = stats.slice(mid);
14173
14100
  const isTop = position === "top";
14174
14101
  return /* @__PURE__ */ jsxRuntime.jsxs(
14175
- "div",
14102
+ Box,
14176
14103
  {
14177
14104
  className: cn(
14178
14105
  "flex items-center justify-between w-full",
@@ -14182,17 +14109,18 @@ function GameHud({
14182
14109
  className
14183
14110
  ),
14184
14111
  children: [
14185
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) }),
14186
- rightStats.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 flex-shrink-0", children: rightStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) })
14112
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) }),
14113
+ rightStats.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: rightStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) })
14187
14114
  ]
14188
14115
  }
14189
14116
  );
14190
14117
  }
14191
14118
  return /* @__PURE__ */ jsxRuntime.jsx(
14192
- "div",
14119
+ Box,
14193
14120
  {
14121
+ position: "relative",
14194
14122
  className: cn(
14195
- "relative z-10 flex items-center gap-4 px-4 py-2",
14123
+ "z-10 flex items-center gap-4 px-4 py-2",
14196
14124
  transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
14197
14125
  className
14198
14126
  ),
@@ -14204,6 +14132,7 @@ var positionMap, DEFAULT_HUD_STATS;
14204
14132
  var init_GameHud = __esm({
14205
14133
  "components/game/2d/molecules/GameHud.tsx"() {
14206
14134
  init_cn();
14135
+ init_Box();
14207
14136
  init_StatBadge();
14208
14137
  positionMap = {
14209
14138
  corners: "inset-0 pointer-events-none"
@@ -14244,7 +14173,7 @@ function GameMenu({
14244
14173
  [eventBus, onSelect]
14245
14174
  );
14246
14175
  return /* @__PURE__ */ jsxRuntime.jsxs(
14247
- "div",
14176
+ Box,
14248
14177
  {
14249
14178
  className: cn(
14250
14179
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
@@ -14254,18 +14183,12 @@ function GameMenu({
14254
14183
  background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
14255
14184
  },
14256
14185
  children: [
14257
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center mb-12 animate-fade-in", children: [
14258
- logo && /* @__PURE__ */ jsxRuntime.jsx(
14259
- "img",
14260
- {
14261
- src: logo.url,
14262
- alt: title,
14263
- className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl"
14264
- }
14265
- ),
14186
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
14187
+ logo && /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
14266
14188
  /* @__PURE__ */ jsxRuntime.jsx(
14267
- "h1",
14189
+ Typography,
14268
14190
  {
14191
+ variant: "h1",
14269
14192
  className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
14270
14193
  style: {
14271
14194
  textShadow: "0 4px 12px rgba(0,0,0,0.5)"
@@ -14273,9 +14196,9 @@ function GameMenu({
14273
14196
  children: title
14274
14197
  }
14275
14198
  ),
14276
- subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
14199
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
14277
14200
  ] }),
14278
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
14201
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
14279
14202
  ChoiceButton,
14280
14203
  {
14281
14204
  text: option.label,
@@ -14286,9 +14209,9 @@ function GameMenu({
14286
14209
  },
14287
14210
  index
14288
14211
  )) }),
14289
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 pointer-events-none overflow-hidden", children: [
14290
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
14291
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
14212
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
14213
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
14214
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
14292
14215
  ] })
14293
14216
  ]
14294
14217
  }
@@ -14300,6 +14223,9 @@ var init_GameMenu = __esm({
14300
14223
  "use client";
14301
14224
  init_cn();
14302
14225
  init_useEventBus();
14226
+ init_Box();
14227
+ init_Typography();
14228
+ init_GameIcon();
14303
14229
  init_ChoiceButton();
14304
14230
  DEFAULT_MENU_OPTIONS = [
14305
14231
  { label: "New Game", event: "NEW_GAME", variant: "primary" },
@@ -15719,10 +15645,11 @@ function Canvas2D({
15719
15645
  }
15720
15646
  }
15721
15647
  ),
15722
- process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
15648
+ process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
15723
15649
  tileClickEvent && /* @__PURE__ */ jsxRuntime.jsx(
15724
- "button",
15650
+ Button,
15725
15651
  {
15652
+ variant: "ghost",
15726
15653
  "data-event": tileClickEvent,
15727
15654
  "data-x": "0",
15728
15655
  "data-y": "0",
@@ -15731,8 +15658,9 @@ function Canvas2D({
15731
15658
  }
15732
15659
  ),
15733
15660
  unitClickEvent && units && units.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
15734
- "button",
15661
+ Button,
15735
15662
  {
15663
+ variant: "ghost",
15736
15664
  "data-event": unitClickEvent,
15737
15665
  "data-unit-id": units[0].id,
15738
15666
  onClick: () => eventBus.emit(`UI:${unitClickEvent}`, { unitId: units[0].id }),
@@ -15741,15 +15669,17 @@ function Canvas2D({
15741
15669
  )
15742
15670
  ] }),
15743
15671
  unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxRuntime.jsxs(
15744
- "div",
15672
+ Box,
15745
15673
  {
15746
- className: "absolute pointer-events-none",
15674
+ position: "absolute",
15675
+ className: "pointer-events-none",
15747
15676
  style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
15748
15677
  children: [
15749
15678
  unit.name && /* @__PURE__ */ jsxRuntime.jsx(
15750
- "div",
15679
+ Typography,
15751
15680
  {
15752
- className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
15681
+ as: "span",
15682
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap block",
15753
15683
  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)" },
15754
15684
  children: unit.name
15755
15685
  }
@@ -15759,7 +15689,7 @@ function Canvas2D({
15759
15689
  },
15760
15690
  unit.id
15761
15691
  )),
15762
- showMinimap && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsxRuntime.jsx(
15692
+ showMinimap && /* @__PURE__ */ jsxRuntime.jsx(Box, { position: "absolute", className: "bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsxRuntime.jsx(
15763
15693
  MiniMap,
15764
15694
  {
15765
15695
  tiles: miniMapTiles,
@@ -15781,6 +15711,7 @@ var init_Canvas2D = __esm({
15781
15711
  init_cn();
15782
15712
  init_useEventBus();
15783
15713
  init_Box();
15714
+ init_Button();
15784
15715
  init_Stack();
15785
15716
  init_Icon();
15786
15717
  init_Typography();
@@ -16112,7 +16043,7 @@ function GameAudioToggle({
16112
16043
  onClick: handleToggle,
16113
16044
  className: cn("text-lg leading-none px-2", className),
16114
16045
  "aria-pressed": muted,
16115
- children: activeAsset ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: activeAsset.url, alt: muted ? "Muted" : "Sound on", className: "w-5 h-5 object-contain" }) : muted ? "\u{1F507}" : "\u{1F50A}"
16046
+ children: activeAsset ? /* @__PURE__ */ jsxRuntime.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}"
16116
16047
  }
16117
16048
  );
16118
16049
  }
@@ -16122,6 +16053,7 @@ var init_GameAudioToggle = __esm({
16122
16053
  init_atoms();
16123
16054
  init_cn();
16124
16055
  init_GameAudioProvider();
16056
+ init_GameIcon();
16125
16057
  GameAudioToggle.displayName = "GameAudioToggle";
16126
16058
  }
16127
16059
  });