@almadar/ui 5.80.0 → 5.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1439,6 +1439,7 @@ var init_Button = __esm({
1439
1439
  rightIcon,
1440
1440
  icon: iconProp,
1441
1441
  iconRight: iconRightProp,
1442
+ iconAsset,
1442
1443
  action,
1443
1444
  actionPayload,
1444
1445
  label,
@@ -1450,7 +1451,8 @@ var init_Button = __esm({
1450
1451
  const eventBus = useEventBus();
1451
1452
  const leftIconValue = leftIcon || iconProp;
1452
1453
  const rightIconValue = rightIcon || iconRightProp;
1453
- const resolvedLeftIcon = resolveIconProp(leftIconValue, iconSizeStyles[size]);
1454
+ const px = size === "sm" ? 16 : size === "lg" ? 20 : 16;
1455
+ const resolvedLeftIcon = iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: iconAsset.name ?? iconAsset.category ?? "", width: px, height: px, style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px }, className: "flex-shrink-0" }) : resolveIconProp(leftIconValue, iconSizeStyles[size]);
1454
1456
  const resolvedRightIcon = resolveIconProp(rightIconValue, iconSizeStyles[size]);
1455
1457
  const handleClick = (e) => {
1456
1458
  if (action) {
@@ -2108,13 +2110,14 @@ var init_Badge = __esm({
2108
2110
  lg: "px-3 py-1.5 text-base"
2109
2111
  };
2110
2112
  Badge = React105__default.forwardRef(
2111
- ({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
2113
+ ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
2112
2114
  const iconSizes3 = {
2113
2115
  sm: "h-icon-default w-icon-default",
2114
2116
  md: "h-icon-default w-icon-default",
2115
2117
  lg: "h-icon-default w-icon-default"
2116
2118
  };
2117
- const resolvedIcon = typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsx(Icon, { icon, className: iconSizes3[size] }) : null;
2119
+ const iconPx = size === "lg" ? 20 : 16;
2120
+ const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: iconAsset.name ?? iconAsset.category ?? "", width: iconPx, height: iconPx, style: { imageRendering: "pixelated", objectFit: "contain", width: iconPx, height: iconPx }, className: "flex-shrink-0" }) : typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsx(Icon, { icon, className: iconSizes3[size] }) : null;
2118
2121
  return /* @__PURE__ */ jsxs(
2119
2122
  "span",
2120
2123
  {
@@ -8357,10 +8360,43 @@ var init_shared = __esm({
8357
8360
  init_canvasEffects();
8358
8361
  }
8359
8362
  });
8363
+ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
8364
+ const px = typeof size === "number" ? size : sizeMap[size];
8365
+ if (assetUrl?.url) {
8366
+ return /* @__PURE__ */ jsx(
8367
+ "img",
8368
+ {
8369
+ src: assetUrl.url,
8370
+ alt: alt ?? assetUrl.category ?? "",
8371
+ width: px,
8372
+ height: px,
8373
+ style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
8374
+ className: cn("flex-shrink-0", className)
8375
+ }
8376
+ );
8377
+ }
8378
+ const I = typeof icon === "string" ? resolveIcon(icon) : icon;
8379
+ return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
8380
+ }
8381
+ var sizeMap;
8382
+ var init_GameIcon = __esm({
8383
+ "components/game/2d/atoms/GameIcon.tsx"() {
8384
+ "use client";
8385
+ init_cn();
8386
+ init_Icon();
8387
+ sizeMap = {
8388
+ sm: 16,
8389
+ md: 24,
8390
+ lg: 32
8391
+ };
8392
+ GameIcon.displayName = "GameIcon";
8393
+ }
8394
+ });
8360
8395
  function GameCard({
8361
8396
  id,
8362
8397
  cost,
8363
8398
  art,
8399
+ frameAsset,
8364
8400
  attack,
8365
8401
  defense,
8366
8402
  name,
@@ -8378,16 +8414,19 @@ function GameCard({
8378
8414
  if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { cardId: id });
8379
8415
  }, [disabled, id, onClick, clickEvent, eventBus]);
8380
8416
  const artPx = artPxMap[size];
8417
+ const frameStyle = frameAsset?.url ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%", backgroundRepeat: "no-repeat" } : {};
8381
8418
  return /* @__PURE__ */ jsxs(
8382
- "button",
8419
+ Button,
8383
8420
  {
8384
- type: "button",
8421
+ variant: "ghost",
8385
8422
  onClick: handleClick,
8386
8423
  disabled,
8387
8424
  title: name,
8425
+ style: frameStyle,
8388
8426
  className: cn(
8389
- "relative flex flex-col items-center rounded-interactive border-2",
8427
+ "relative flex flex-col items-center rounded-interactive",
8390
8428
  "bg-card/90 px-1.5 pt-1.5 pb-1 transition-all duration-150",
8429
+ frameAsset?.url ? "border-0" : "border-2",
8391
8430
  cardSizeMap[size],
8392
8431
  disabled ? "border-border opacity-50 cursor-not-allowed" : "border-accent hover:brightness-125 hover:-translate-y-1 cursor-pointer",
8393
8432
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background -translate-y-1",
@@ -8395,8 +8434,9 @@ function GameCard({
8395
8434
  ),
8396
8435
  children: [
8397
8436
  cost != null && /* @__PURE__ */ jsx(
8398
- "span",
8437
+ Typography,
8399
8438
  {
8439
+ as: "span",
8400
8440
  className: cn(
8401
8441
  "absolute -top-2 -left-2 flex items-center justify-center",
8402
8442
  "min-w-[22px] h-[22px] rounded-full px-1",
@@ -8405,17 +8445,7 @@ function GameCard({
8405
8445
  children: cost
8406
8446
  }
8407
8447
  ),
8408
- /* @__PURE__ */ jsx(Box, { className: "flex-1 flex items-center justify-center w-full", children: art ? /* @__PURE__ */ jsx(
8409
- "img",
8410
- {
8411
- src: art.url,
8412
- alt: name ?? id,
8413
- width: artPx,
8414
- height: artPx,
8415
- style: { imageRendering: "pixelated", objectFit: "contain" },
8416
- className: "flex-shrink-0"
8417
- }
8418
- ) : /* @__PURE__ */ jsx(Box, { className: "rounded bg-muted/40", style: { width: artPx, height: artPx } }) }),
8448
+ /* @__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 } }) }),
8419
8449
  name != null && /* @__PURE__ */ jsx(
8420
8450
  Typography,
8421
8451
  {
@@ -8425,8 +8455,8 @@ function GameCard({
8425
8455
  }
8426
8456
  ),
8427
8457
  (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: [
8428
- /* @__PURE__ */ jsx("span", { className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
8429
- /* @__PURE__ */ jsx("span", { className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
8458
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
8459
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
8430
8460
  ] })
8431
8461
  ]
8432
8462
  }
@@ -8439,7 +8469,9 @@ var init_GameCard = __esm({
8439
8469
  init_cn();
8440
8470
  init_useEventBus();
8441
8471
  init_Box();
8472
+ init_Button();
8442
8473
  init_Typography();
8474
+ init_GameIcon();
8443
8475
  cardSizeMap = {
8444
8476
  sm: "w-16 h-24",
8445
8477
  md: "w-20 h-28",
@@ -8462,12 +8494,13 @@ function HealthBar({
8462
8494
  frameAsset,
8463
8495
  fillAsset
8464
8496
  }) {
8465
- const sizes = sizeMap[size];
8497
+ const sizes = sizeMap2[size];
8466
8498
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
8467
8499
  if (format === "hearts") {
8468
- return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
8469
- "span",
8500
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
8501
+ Box,
8470
8502
  {
8503
+ as: "span",
8471
8504
  className: cn(animated && "transition-transform hover:scale-110"),
8472
8505
  children: heartIcon(i < current, sizes.heart)
8473
8506
  },
@@ -8476,10 +8509,12 @@ function HealthBar({
8476
8509
  }
8477
8510
  if (format === "bar") {
8478
8511
  return /* @__PURE__ */ jsx(
8479
- "div",
8512
+ Box,
8480
8513
  {
8514
+ position: "relative",
8515
+ overflow: "hidden",
8481
8516
  className: cn(
8482
- "relative overflow-hidden rounded-full",
8517
+ "rounded-full",
8483
8518
  !frameAsset && "bg-muted",
8484
8519
  sizes.bar,
8485
8520
  "w-24",
@@ -8487,10 +8522,11 @@ function HealthBar({
8487
8522
  ),
8488
8523
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
8489
8524
  children: /* @__PURE__ */ jsx(
8490
- "div",
8525
+ Box,
8491
8526
  {
8527
+ position: "absolute",
8492
8528
  className: cn(
8493
- "absolute inset-y-0 left-0 rounded-full",
8529
+ "inset-y-0 left-0 rounded-full",
8494
8530
  !fillAsset && (percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error"),
8495
8531
  animated && "transition-all duration-300"
8496
8532
  ),
@@ -8504,10 +8540,11 @@ function HealthBar({
8504
8540
  );
8505
8541
  }
8506
8542
  if (format === "progress") {
8507
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
8543
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex items-center gap-2", className), children: [
8508
8544
  level != null && /* @__PURE__ */ jsxs(
8509
- "span",
8545
+ Typography,
8510
8546
  {
8547
+ as: "span",
8511
8548
  className: cn(
8512
8549
  "flex-shrink-0 rounded-interactive font-bold",
8513
8550
  "bg-accent text-accent-foreground border border-accent",
@@ -8519,21 +8556,23 @@ function HealthBar({
8519
8556
  ]
8520
8557
  }
8521
8558
  ),
8522
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [
8559
+ /* @__PURE__ */ jsxs(Box, { className: "flex-1 flex flex-col gap-0.5", children: [
8523
8560
  /* @__PURE__ */ jsx(
8524
- "div",
8561
+ Box,
8525
8562
  {
8563
+ position: "relative",
8526
8564
  className: cn(
8527
- "relative w-full overflow-hidden rounded-full",
8565
+ "w-full overflow-hidden rounded-full",
8528
8566
  !frameAsset && "bg-muted border border-muted",
8529
8567
  sizes.bar
8530
8568
  ),
8531
8569
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
8532
8570
  children: /* @__PURE__ */ jsx(
8533
- "div",
8571
+ Box,
8534
8572
  {
8573
+ position: "absolute",
8535
8574
  className: cn(
8536
- "absolute inset-y-0 left-0 rounded-full",
8575
+ "inset-y-0 left-0 rounded-full",
8537
8576
  !fillAsset && "bg-gradient-to-r from-accent to-info",
8538
8577
  animated && "transition-all duration-500 ease-out"
8539
8578
  ),
@@ -8545,7 +8584,7 @@ function HealthBar({
8545
8584
  )
8546
8585
  }
8547
8586
  ),
8548
- showLabel && /* @__PURE__ */ jsxs("span", { className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
8587
+ showLabel && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
8549
8588
  current,
8550
8589
  " / ",
8551
8590
  max,
@@ -8554,16 +8593,18 @@ function HealthBar({
8554
8593
  ] })
8555
8594
  ] });
8556
8595
  }
8557
- return /* @__PURE__ */ jsxs("span", { className: cn("font-mono font-bold", sizes.text, className), children: [
8596
+ return /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-mono font-bold", sizes.text, className), children: [
8558
8597
  current,
8559
8598
  "/",
8560
8599
  max
8561
8600
  ] });
8562
8601
  }
8563
- var heartIcon, sizeMap;
8602
+ var heartIcon, sizeMap2;
8564
8603
  var init_HealthBar = __esm({
8565
8604
  "components/game/2d/atoms/HealthBar.tsx"() {
8566
8605
  init_cn();
8606
+ init_Box();
8607
+ init_Typography();
8567
8608
  heartIcon = (filled, size) => /* @__PURE__ */ jsx(
8568
8609
  "svg",
8569
8610
  {
@@ -8575,7 +8616,7 @@ var init_HealthBar = __esm({
8575
8616
  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" })
8576
8617
  }
8577
8618
  );
8578
- sizeMap = {
8619
+ sizeMap2 = {
8579
8620
  sm: { heart: "w-4 h-4", bar: "h-2", text: "text-sm", label: "text-xs", badge: "text-xs px-1.5 py-0.5" },
8580
8621
  md: { heart: "w-6 h-6", bar: "h-3", text: "text-base", label: "text-xs", badge: "text-xs px-2 py-0.5" },
8581
8622
  lg: { heart: "w-8 h-8", bar: "h-4", text: "text-lg", label: "text-sm", badge: "text-sm px-2.5 py-1" }
@@ -8596,37 +8637,30 @@ function ScoreDisplay({
8596
8637
  const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
8597
8638
  const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
8598
8639
  return /* @__PURE__ */ jsxs(
8599
- "div",
8640
+ Box,
8600
8641
  {
8601
8642
  className: cn(
8602
8643
  "flex items-center gap-2 font-bold",
8603
- sizeMap2[size],
8644
+ sizeMap3[size],
8604
8645
  className
8605
8646
  ),
8606
8647
  children: [
8607
- assetUrl ? /* @__PURE__ */ jsx(
8608
- "img",
8609
- {
8610
- src: assetUrl.url,
8611
- alt: "",
8612
- width: 20,
8613
- height: 20,
8614
- style: { imageRendering: "pixelated", objectFit: "contain" },
8615
- className: "flex-shrink-0"
8616
- }
8617
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
8618
- label && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
8619
- /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formattedValue })
8648
+ 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,
8649
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
8650
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "tabular-nums", children: formattedValue })
8620
8651
  ]
8621
8652
  }
8622
8653
  );
8623
8654
  }
8624
- var sizeMap2, DEFAULT_ASSET_URL;
8655
+ var sizeMap3, DEFAULT_ASSET_URL;
8625
8656
  var init_ScoreDisplay = __esm({
8626
8657
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
8627
8658
  init_cn();
8628
8659
  init_Icon();
8629
- sizeMap2 = {
8660
+ init_Box();
8661
+ init_Typography();
8662
+ init_GameIcon();
8663
+ sizeMap3 = {
8630
8664
  sm: "text-sm",
8631
8665
  md: "text-lg",
8632
8666
  lg: "text-2xl",
@@ -8689,9 +8723,9 @@ function ControlButton({
8689
8723
  [isPressed, releaseEvent, eventBus, onRelease]
8690
8724
  );
8691
8725
  return /* @__PURE__ */ jsx(
8692
- "button",
8726
+ Button,
8693
8727
  {
8694
- type: "button",
8728
+ variant,
8695
8729
  disabled,
8696
8730
  onPointerDown: handlePointerDown,
8697
8731
  onPointerUp: handlePointerUp,
@@ -8702,41 +8736,35 @@ function ControlButton({
8702
8736
  "select-none touch-none",
8703
8737
  "transition-all duration-100",
8704
8738
  "active:scale-95",
8705
- sizeMap3[size] ?? sizeMap3.md,
8739
+ sizeMap4[size] ?? sizeMap4.md,
8706
8740
  shapeMap[shape] ?? shapeMap.circle,
8707
8741
  variantMap[variant] ?? variantMap.secondary,
8708
8742
  actualPressed && "scale-95 brightness-110 border-foreground",
8709
8743
  disabled && "opacity-50 cursor-not-allowed",
8710
8744
  className
8711
8745
  ),
8712
- children: assetUrl ? /* @__PURE__ */ jsx(
8713
- "img",
8714
- {
8715
- src: assetUrl.url,
8716
- alt: "",
8717
- width: 24,
8718
- height: 24,
8719
- style: { imageRendering: "pixelated", objectFit: "contain" },
8720
- className: "flex-shrink-0"
8721
- }
8722
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
8746
+ 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) ? (() => {
8723
8747
  const I = resolveIcon(icon);
8724
8748
  return I ? /* @__PURE__ */ jsx(I, { className: "w-6 h-6" }) : null;
8725
8749
  })() : icon : /* @__PURE__ */ (() => {
8726
8750
  const I = icon;
8727
8751
  return /* @__PURE__ */ jsx(I, { className: "w-6 h-6" });
8728
- })() }) : label ? /* @__PURE__ */ jsx("span", { children: label }) : null
8752
+ })() }) : label ? /* @__PURE__ */ jsx(Typography, { as: "span", children: label }) : null
8729
8753
  }
8730
8754
  );
8731
8755
  }
8732
- var sizeMap3, shapeMap, variantMap, DEFAULT_ASSET_URL2;
8756
+ var sizeMap4, shapeMap, variantMap, DEFAULT_ASSET_URL2;
8733
8757
  var init_ControlButton = __esm({
8734
8758
  "components/game/2d/atoms/ControlButton.tsx"() {
8735
8759
  "use client";
8736
8760
  init_cn();
8737
8761
  init_useEventBus();
8738
8762
  init_Icon();
8739
- sizeMap3 = {
8763
+ init_Button();
8764
+ init_Box();
8765
+ init_Typography();
8766
+ init_GameIcon();
8767
+ sizeMap4 = {
8740
8768
  sm: "w-10 h-10 text-sm",
8741
8769
  md: "w-14 h-14 text-base",
8742
8770
  lg: "w-18 h-18 text-lg",
@@ -8806,12 +8834,12 @@ function Sprite({
8806
8834
  onClick?.();
8807
8835
  };
8808
8836
  return /* @__PURE__ */ jsx(
8809
- "div",
8837
+ Box,
8810
8838
  {
8839
+ position: "absolute",
8811
8840
  className,
8812
8841
  onClick: action || onClick ? handleClick : void 0,
8813
8842
  style: {
8814
- position: "absolute",
8815
8843
  width: frameWidth,
8816
8844
  height: frameHeight,
8817
8845
  backgroundImage: `url(${spritesheet.url})`,
@@ -8832,6 +8860,7 @@ var init_Sprite = __esm({
8832
8860
  "components/game/2d/atoms/Sprite.tsx"() {
8833
8861
  "use client";
8834
8862
  init_useEventBus();
8863
+ init_Box();
8835
8864
  init_spriteAnimation();
8836
8865
  DEFAULT_SPRITESHEET = {
8837
8866
  url: "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
@@ -8868,17 +8897,7 @@ function StateIndicator({
8868
8897
  className
8869
8898
  ),
8870
8899
  children: [
8871
- /* @__PURE__ */ jsx(Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsx(
8872
- "img",
8873
- {
8874
- src: assetUrl.url,
8875
- alt: displayLabel,
8876
- width: 16,
8877
- height: 16,
8878
- style: { imageRendering: "pixelated", objectFit: "contain" },
8879
- className: "flex-shrink-0"
8880
- }
8881
- ) : 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 }) }),
8900
+ /* @__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 }) }),
8882
8901
  /* @__PURE__ */ jsx(Box, { as: "span", children: displayLabel })
8883
8902
  ]
8884
8903
  }
@@ -8890,6 +8909,7 @@ var init_StateIndicator = __esm({
8890
8909
  init_Box();
8891
8910
  init_Icon();
8892
8911
  init_cn();
8912
+ init_GameIcon();
8893
8913
  DEFAULT_ASSET_URL3 = {
8894
8914
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
8895
8915
  role: "ui",
@@ -8943,29 +8963,31 @@ function TimerDisplay({
8943
8963
  }) {
8944
8964
  const isLow = lowThreshold != null && seconds <= lowThreshold && seconds > 0;
8945
8965
  return /* @__PURE__ */ jsxs(
8946
- "div",
8966
+ Box,
8947
8967
  {
8948
8968
  className: cn(
8949
8969
  "inline-flex items-center gap-1 justify-center rounded-container",
8950
8970
  "bg-card/80 border border-muted font-mono font-bold tabular-nums",
8951
- sizeMap4[size],
8971
+ sizeMap5[size],
8952
8972
  running && "border-success/50",
8953
8973
  isLow && "text-error border-error/50 animate-pulse",
8954
8974
  !isLow && "text-foreground",
8955
8975
  className
8956
8976
  ),
8957
8977
  children: [
8958
- iconAsset && /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: "", className: "w-4 h-4 object-contain flex-shrink-0" }),
8978
+ iconAsset && /* @__PURE__ */ jsx(GameIcon, { assetUrl: iconAsset, icon: "image", size: 16, className: "w-4 h-4 object-contain flex-shrink-0" }),
8959
8979
  formatTime(seconds, format)
8960
8980
  ]
8961
8981
  }
8962
8982
  );
8963
8983
  }
8964
- var sizeMap4;
8984
+ var sizeMap5;
8965
8985
  var init_TimerDisplay = __esm({
8966
8986
  "components/game/2d/atoms/TimerDisplay.tsx"() {
8967
8987
  init_cn();
8968
- sizeMap4 = {
8988
+ init_Box();
8989
+ init_GameIcon();
8990
+ sizeMap5 = {
8969
8991
  sm: "text-sm px-2 py-0.5",
8970
8992
  md: "text-lg px-3 py-1",
8971
8993
  lg: "text-2xl px-4 py-1.5"
@@ -8983,9 +9005,9 @@ function ResourceCounter({
8983
9005
  size = "md",
8984
9006
  className
8985
9007
  }) {
8986
- const sizes = sizeMap5[size];
9008
+ const sizes = sizeMap6[size];
8987
9009
  return /* @__PURE__ */ jsxs(
8988
- "div",
9010
+ Box,
8989
9011
  {
8990
9012
  className: cn(
8991
9013
  "inline-flex items-center rounded-container",
@@ -8994,21 +9016,11 @@ function ResourceCounter({
8994
9016
  className
8995
9017
  ),
8996
9018
  children: [
8997
- assetUrl ? /* @__PURE__ */ jsx(
8998
- "img",
8999
- {
9000
- src: assetUrl.url,
9001
- alt: label,
9002
- width: sizes.img,
9003
- height: sizes.img,
9004
- style: { imageRendering: "pixelated", objectFit: "contain" },
9005
- className: "flex-shrink-0"
9006
- }
9007
- ) : 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,
9008
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
9009
- /* @__PURE__ */ jsxs("span", { className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
9019
+ 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,
9020
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
9021
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
9010
9022
  value,
9011
- max != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9023
+ max != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
9012
9024
  "/",
9013
9025
  max
9014
9026
  ] })
@@ -9017,11 +9029,14 @@ function ResourceCounter({
9017
9029
  }
9018
9030
  );
9019
9031
  }
9020
- var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap5;
9032
+ var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap6;
9021
9033
  var init_ResourceCounter = __esm({
9022
9034
  "components/game/2d/atoms/ResourceCounter.tsx"() {
9023
9035
  init_cn();
9024
9036
  init_Icon();
9037
+ init_Box();
9038
+ init_Typography();
9039
+ init_GameIcon();
9025
9040
  colorTokenClasses2 = {
9026
9041
  primary: "text-primary",
9027
9042
  secondary: "text-secondary",
@@ -9035,7 +9050,7 @@ var init_ResourceCounter = __esm({
9035
9050
  role: "ui",
9036
9051
  category: "coin"
9037
9052
  };
9038
- sizeMap5 = {
9053
+ sizeMap6 = {
9039
9054
  sm: { wrapper: "text-xs gap-1 px-1.5 py-0.5", icon: "text-sm", img: 16 },
9040
9055
  md: { wrapper: "text-sm gap-1.5 px-2 py-1", icon: "text-base", img: 20 },
9041
9056
  lg: { wrapper: "text-base gap-2 px-3 py-1.5", icon: "text-lg", img: 28 }
@@ -9060,9 +9075,9 @@ function ItemSlot({
9060
9075
  const isClickable = onClick != null || action != null;
9061
9076
  const px = assetSizeMap[size];
9062
9077
  return /* @__PURE__ */ jsx(
9063
- "button",
9078
+ Button,
9064
9079
  {
9065
- type: "button",
9080
+ variant: "ghost",
9066
9081
  onClick: () => {
9067
9082
  if (action) eventBus.emit(`UI:${action}`, {});
9068
9083
  onClick?.();
@@ -9072,7 +9087,7 @@ function ItemSlot({
9072
9087
  className: cn(
9073
9088
  "relative flex items-center justify-center rounded-interactive border-2",
9074
9089
  "bg-card/80 transition-all duration-150",
9075
- sizeMap6[size],
9090
+ sizeMap7[size],
9076
9091
  empty ? "border-border bg-card/50" : rarityBorderMap[rarity],
9077
9092
  !empty && rarityGlowMap[rarity],
9078
9093
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background",
@@ -9081,21 +9096,12 @@ function ItemSlot({
9081
9096
  !isClickable && "cursor-default",
9082
9097
  className
9083
9098
  ),
9084
- children: empty ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9085
- assetUrl ? /* @__PURE__ */ jsx(
9086
- "img",
9087
- {
9088
- src: assetUrl?.url,
9089
- alt: label,
9090
- width: px,
9091
- height: px,
9092
- style: { imageRendering: "pixelated", objectFit: "contain" },
9093
- className: "flex-shrink-0"
9094
- }
9095
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9099
+ children: empty ? /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9100
+ 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,
9096
9101
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
9097
- "span",
9102
+ Typography,
9098
9103
  {
9104
+ as: "span",
9099
9105
  className: cn(
9100
9106
  "absolute -bottom-1 -right-1 flex items-center justify-center",
9101
9107
  "min-w-[18px] h-[18px] rounded-full px-1",
@@ -9108,14 +9114,18 @@ function ItemSlot({
9108
9114
  }
9109
9115
  );
9110
9116
  }
9111
- var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9117
+ var sizeMap7, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9112
9118
  var init_ItemSlot = __esm({
9113
9119
  "components/game/2d/atoms/ItemSlot.tsx"() {
9114
9120
  "use client";
9115
9121
  init_cn();
9116
9122
  init_Icon();
9117
9123
  init_useEventBus();
9118
- sizeMap6 = {
9124
+ init_Button();
9125
+ init_Box();
9126
+ init_Typography();
9127
+ init_GameIcon();
9128
+ sizeMap7 = {
9119
9129
  sm: "w-10 h-10 text-lg",
9120
9130
  md: "w-14 h-14 text-2xl",
9121
9131
  lg: "w-18 h-18 text-3xl"
@@ -9156,9 +9166,9 @@ function TurnIndicator({
9156
9166
  size = "md",
9157
9167
  className
9158
9168
  }) {
9159
- const sizes = sizeMap7[size];
9169
+ const sizes = sizeMap8[size];
9160
9170
  return /* @__PURE__ */ jsxs(
9161
- "div",
9171
+ Box,
9162
9172
  {
9163
9173
  className: cn(
9164
9174
  "inline-flex items-center rounded-container",
@@ -9167,42 +9177,35 @@ function TurnIndicator({
9167
9177
  className
9168
9178
  ),
9169
9179
  children: [
9170
- /* @__PURE__ */ jsxs("span", { className: "font-bold tabular-nums", children: [
9180
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: "font-bold tabular-nums", children: [
9171
9181
  "Turn ",
9172
9182
  currentTurn,
9173
- maxTurns != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9183
+ maxTurns != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
9174
9184
  "/",
9175
9185
  maxTurns
9176
9186
  ] })
9177
9187
  ] }),
9178
9188
  phase && /* @__PURE__ */ jsxs(Fragment, { children: [
9179
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
9180
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: phase })
9189
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9190
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: phase })
9181
9191
  ] }),
9182
9192
  activeTeam && /* @__PURE__ */ jsxs(Fragment, { children: [
9183
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
9184
- assetUrl ? /* @__PURE__ */ jsx(
9185
- "img",
9186
- {
9187
- src: assetUrl.url,
9188
- alt: "",
9189
- width: 12,
9190
- height: 12,
9191
- style: { imageRendering: "pixelated", objectFit: "contain" },
9192
- className: "flex-shrink-0"
9193
- }
9194
- ) : /* @__PURE__ */ jsx("span", { className: cn("rounded-full bg-success/20", sizes.dot) }),
9195
- /* @__PURE__ */ jsx("span", { className: "text-success", children: activeTeam })
9193
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9194
+ 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) }),
9195
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-success", children: activeTeam })
9196
9196
  ] })
9197
9197
  ]
9198
9198
  }
9199
9199
  );
9200
9200
  }
9201
- var sizeMap7, DEFAULT_ASSET_URL6;
9201
+ var sizeMap8, DEFAULT_ASSET_URL6;
9202
9202
  var init_TurnIndicator = __esm({
9203
9203
  "components/game/2d/atoms/TurnIndicator.tsx"() {
9204
9204
  init_cn();
9205
- sizeMap7 = {
9205
+ init_Box();
9206
+ init_Typography();
9207
+ init_GameIcon();
9208
+ sizeMap8 = {
9206
9209
  sm: { wrapper: "text-xs gap-1.5 px-2 py-0.5", dot: "w-1.5 h-1.5" },
9207
9210
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
9208
9211
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
@@ -9234,10 +9237,10 @@ function ComboCounter({
9234
9237
  size = "md",
9235
9238
  className
9236
9239
  }) {
9237
- const sizes = sizeMap8[size];
9240
+ const sizes = sizeMap9[size];
9238
9241
  if (combo <= 0) return null;
9239
9242
  return /* @__PURE__ */ jsxs(
9240
- "div",
9243
+ Box,
9241
9244
  {
9242
9245
  className: cn(
9243
9246
  "inline-flex flex-col items-center justify-center",
@@ -9247,24 +9250,14 @@ function ComboCounter({
9247
9250
  className
9248
9251
  ),
9249
9252
  children: [
9250
- assetUrl && /* @__PURE__ */ jsx(
9251
- "img",
9252
- {
9253
- src: assetUrl.url,
9254
- alt: "combo",
9255
- width: 24,
9256
- height: 24,
9257
- style: { imageRendering: "pixelated", objectFit: "contain" },
9258
- className: "flex-shrink-0 mb-0.5"
9259
- }
9260
- ),
9261
- /* @__PURE__ */ jsx("span", { className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
9262
- /* @__PURE__ */ jsx("span", { className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
9263
- multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs("span", { className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
9253
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0 mb-0.5" }),
9254
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
9255
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
9256
+ multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
9264
9257
  "x",
9265
9258
  multiplier.toFixed(1)
9266
9259
  ] }),
9267
- streak != null && streak > 0 && /* @__PURE__ */ jsxs("span", { className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9260
+ streak != null && streak > 0 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9268
9261
  streak,
9269
9262
  " streak"
9270
9263
  ] })
@@ -9272,16 +9265,19 @@ function ComboCounter({
9272
9265
  }
9273
9266
  );
9274
9267
  }
9275
- var DEFAULT_ASSET_URL7, sizeMap8;
9268
+ var DEFAULT_ASSET_URL7, sizeMap9;
9276
9269
  var init_ComboCounter = __esm({
9277
9270
  "components/game/2d/atoms/ComboCounter.tsx"() {
9278
9271
  init_cn();
9272
+ init_Box();
9273
+ init_Typography();
9274
+ init_GameIcon();
9279
9275
  DEFAULT_ASSET_URL7 = {
9280
9276
  url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
9281
9277
  role: "effect",
9282
9278
  category: "effect"
9283
9279
  };
9284
- sizeMap8 = {
9280
+ sizeMap9 = {
9285
9281
  sm: { combo: "text-lg", label: "text-xs", multiplier: "text-xs" },
9286
9282
  md: { combo: "text-2xl", label: "text-xs", multiplier: "text-sm" },
9287
9283
  lg: { combo: "text-4xl", label: "text-sm", multiplier: "text-base" }
@@ -9298,54 +9294,48 @@ function WaypointMarker({
9298
9294
  size = "md",
9299
9295
  className
9300
9296
  }) {
9301
- const sizes = sizeMap9[size];
9302
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center", className), children: [
9303
- /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
9297
+ const sizes = sizeMap10[size];
9298
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col items-center", className), children: [
9299
+ /* @__PURE__ */ jsxs(Box, { className: "relative flex items-center justify-center", children: [
9304
9300
  active && /* @__PURE__ */ jsx(
9305
- "div",
9301
+ Box,
9306
9302
  {
9303
+ position: "absolute",
9307
9304
  className: cn(
9308
- "absolute rounded-full border-2 border-info animate-ping opacity-50",
9305
+ "rounded-full border-2 border-info animate-ping opacity-50",
9309
9306
  sizes.ring
9310
9307
  )
9311
9308
  }
9312
9309
  ),
9313
9310
  active && /* @__PURE__ */ jsx(
9314
- "div",
9311
+ Box,
9315
9312
  {
9313
+ position: "absolute",
9316
9314
  className: cn(
9317
- "absolute rounded-full border-2 border-info",
9315
+ "rounded-full border-2 border-info",
9318
9316
  sizes.ring
9319
9317
  )
9320
9318
  }
9321
9319
  ),
9322
9320
  /* @__PURE__ */ jsx(
9323
- "div",
9321
+ Box,
9324
9322
  {
9323
+ position: "relative",
9325
9324
  className: cn(
9326
- "relative flex items-center justify-center rounded-full transition-all duration-200",
9325
+ "flex items-center justify-center rounded-full transition-all duration-200",
9327
9326
  sizes.dot,
9328
9327
  completed && "bg-success text-foreground",
9329
9328
  active && !completed && "bg-info text-foreground",
9330
9329
  !active && !completed && "bg-muted"
9331
9330
  ),
9332
- children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsx(
9333
- "img",
9334
- {
9335
- src: assetUrl.url,
9336
- alt: label,
9337
- width: sizes.img,
9338
- height: sizes.img,
9339
- style: { imageRendering: "pixelated", objectFit: "contain" },
9340
- className: "flex-shrink-0"
9341
- }
9342
- ) : icon ? typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) : null
9331
+ 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
9343
9332
  }
9344
9333
  )
9345
9334
  ] }),
9346
9335
  label && /* @__PURE__ */ jsx(
9347
- "span",
9336
+ Typography,
9348
9337
  {
9338
+ as: "span",
9349
9339
  className: cn(
9350
9340
  "text-center whitespace-nowrap",
9351
9341
  sizes.label,
@@ -9356,17 +9346,20 @@ function WaypointMarker({
9356
9346
  )
9357
9347
  ] });
9358
9348
  }
9359
- var DEFAULT_ASSET_URL8, sizeMap9, checkIcon;
9349
+ var DEFAULT_ASSET_URL8, sizeMap10, checkIcon;
9360
9350
  var init_WaypointMarker = __esm({
9361
9351
  "components/game/2d/atoms/WaypointMarker.tsx"() {
9362
9352
  init_cn();
9363
9353
  init_Icon();
9354
+ init_Box();
9355
+ init_Typography();
9356
+ init_GameIcon();
9364
9357
  DEFAULT_ASSET_URL8 = {
9365
9358
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
9366
9359
  role: "ui",
9367
9360
  category: "waypoint"
9368
9361
  };
9369
- sizeMap9 = {
9362
+ sizeMap10 = {
9370
9363
  sm: { dot: "w-4 h-4", ring: "w-6 h-6", label: "text-xs mt-1", img: 12 },
9371
9364
  md: { dot: "w-6 h-6", ring: "w-8 h-8", label: "text-sm mt-1.5", img: 18 },
9372
9365
  lg: { dot: "w-8 h-8", ring: "w-10 h-10", label: "text-base mt-2", img: 24 }
@@ -9391,32 +9384,24 @@ function StatusEffect({
9391
9384
  size = "md",
9392
9385
  className
9393
9386
  }) {
9394
- const sizes = sizeMap10[size];
9395
- return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex flex-col items-center", className), children: [
9387
+ const sizes = sizeMap11[size];
9388
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn("inline-flex flex-col items-center", className), children: [
9396
9389
  /* @__PURE__ */ jsxs(
9397
- "div",
9390
+ Box,
9398
9391
  {
9392
+ position: "relative",
9399
9393
  className: cn(
9400
- "relative flex items-center justify-center rounded-interactive border-2",
9394
+ "flex items-center justify-center rounded-interactive border-2",
9401
9395
  sizes.container,
9402
9396
  variantStyles7[variant]
9403
9397
  ),
9404
9398
  title: label,
9405
9399
  children: [
9406
- /* @__PURE__ */ jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsx(
9407
- "img",
9408
- {
9409
- src: assetUrl.url,
9410
- alt: label,
9411
- width: sizes.img,
9412
- height: sizes.img,
9413
- style: { imageRendering: "pixelated", objectFit: "contain" },
9414
- className: "flex-shrink-0"
9415
- }
9416
- ) : icon != null && typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsx(Icon, { icon, size: "sm" }) : null }),
9400
+ /* @__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 }),
9417
9401
  duration !== void 0 && /* @__PURE__ */ jsx(
9418
- "span",
9402
+ Typography,
9419
9403
  {
9404
+ as: "span",
9420
9405
  className: cn(
9421
9406
  "absolute bottom-0 left-0 right-0 text-center font-mono font-bold text-foreground bg-background/60 leading-tight",
9422
9407
  sizes.timer
@@ -9428,8 +9413,9 @@ function StatusEffect({
9428
9413
  }
9429
9414
  ),
9430
9415
  stacks !== void 0 && stacks > 1 && /* @__PURE__ */ jsx(
9431
- "span",
9416
+ Typography,
9432
9417
  {
9418
+ as: "span",
9433
9419
  className: cn(
9434
9420
  "absolute flex items-center justify-center rounded-full bg-card text-foreground font-bold leading-none",
9435
9421
  sizes.badge
@@ -9437,20 +9423,23 @@ function StatusEffect({
9437
9423
  children: stacks
9438
9424
  }
9439
9425
  ),
9440
- label && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9426
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9441
9427
  ] });
9442
9428
  }
9443
- var DEFAULT_ASSET_URL9, sizeMap10, variantStyles7;
9429
+ var DEFAULT_ASSET_URL9, sizeMap11, variantStyles7;
9444
9430
  var init_StatusEffect = __esm({
9445
9431
  "components/game/2d/atoms/StatusEffect.tsx"() {
9446
9432
  init_cn();
9447
9433
  init_Icon();
9434
+ init_Box();
9435
+ init_Typography();
9436
+ init_GameIcon();
9448
9437
  DEFAULT_ASSET_URL9 = {
9449
9438
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
9450
9439
  role: "ui",
9451
9440
  category: "effect"
9452
9441
  };
9453
- sizeMap10 = {
9442
+ sizeMap11 = {
9454
9443
  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 },
9455
9444
  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 },
9456
9445
  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 }
@@ -9474,38 +9463,31 @@ function DamageNumber({
9474
9463
  return /* @__PURE__ */ jsxs(Fragment, { children: [
9475
9464
  /* @__PURE__ */ jsx("style", { children: floatKeyframes }),
9476
9465
  /* @__PURE__ */ jsxs(
9477
- "span",
9466
+ Typography,
9478
9467
  {
9468
+ as: "span",
9479
9469
  className: cn(
9480
9470
  "inline-flex items-center gap-0.5 font-mono select-none pointer-events-none",
9481
- sizeMap11[size],
9471
+ sizeMap12[size],
9482
9472
  typeStyles[type],
9483
9473
  className
9484
9474
  ),
9485
9475
  style: { animation: "damageFloat 1s ease-out forwards" },
9486
9476
  children: [
9487
- assetUrl && /* @__PURE__ */ jsx(
9488
- "img",
9489
- {
9490
- src: assetUrl.url,
9491
- alt: "",
9492
- width: 14,
9493
- height: 14,
9494
- style: { imageRendering: "pixelated", objectFit: "contain" },
9495
- className: "flex-shrink-0"
9496
- }
9497
- ),
9477
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 14, className: "flex-shrink-0" }),
9498
9478
  displayText
9499
9479
  ]
9500
9480
  }
9501
9481
  )
9502
9482
  ] });
9503
9483
  }
9504
- var sizeMap11, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
9484
+ var sizeMap12, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
9505
9485
  var init_DamageNumber = __esm({
9506
9486
  "components/game/2d/atoms/DamageNumber.tsx"() {
9507
9487
  init_cn();
9508
- sizeMap11 = {
9488
+ init_Typography();
9489
+ init_GameIcon();
9490
+ sizeMap12 = {
9509
9491
  sm: "text-sm",
9510
9492
  md: "text-lg",
9511
9493
  lg: "text-2xl"
@@ -9539,7 +9521,7 @@ function DialogueBubble({
9539
9521
  className
9540
9522
  }) {
9541
9523
  return /* @__PURE__ */ jsxs(
9542
- "div",
9524
+ Box,
9543
9525
  {
9544
9526
  className: cn(
9545
9527
  "flex items-start gap-3 rounded-container bg-background/80 backdrop-blur-sm px-4 py-3 border border-border/10",
@@ -9547,17 +9529,10 @@ function DialogueBubble({
9547
9529
  className
9548
9530
  ),
9549
9531
  children: [
9550
- portrait && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 w-12 h-12 rounded-full overflow-hidden border-2 border-warning/60", children: /* @__PURE__ */ jsx(
9551
- "img",
9552
- {
9553
- src: portrait?.url,
9554
- alt: speaker ?? "speaker",
9555
- className: "w-full h-full object-cover"
9556
- }
9557
- ) }),
9558
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
9559
- speaker && /* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-warning", children: speaker }),
9560
- /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground leading-relaxed", children: text })
9532
+ 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" }) }),
9533
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-1 min-w-0", children: [
9534
+ speaker && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm font-bold text-warning", children: speaker }),
9535
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm text-foreground leading-relaxed", children: text })
9561
9536
  ] })
9562
9537
  ]
9563
9538
  }
@@ -9567,6 +9542,9 @@ var DEFAULT_PORTRAIT;
9567
9542
  var init_DialogueBubble = __esm({
9568
9543
  "components/game/2d/atoms/DialogueBubble.tsx"() {
9569
9544
  init_cn();
9545
+ init_Box();
9546
+ init_Typography();
9547
+ init_GameIcon();
9570
9548
  DEFAULT_PORTRAIT = {
9571
9549
  url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
9572
9550
  role: "effect",
@@ -9588,11 +9566,11 @@ function ChoiceButton({
9588
9566
  }) {
9589
9567
  const eventBus = useEventBus();
9590
9568
  return /* @__PURE__ */ jsxs(
9591
- "button",
9569
+ Button,
9592
9570
  {
9593
- type: "button",
9571
+ variant: "ghost",
9594
9572
  disabled,
9595
- onClick: (e) => {
9573
+ onClick: () => {
9596
9574
  if (action) eventBus.emit(`UI:${action}`, {});
9597
9575
  onClick?.();
9598
9576
  },
@@ -9605,8 +9583,9 @@ function ChoiceButton({
9605
9583
  ),
9606
9584
  children: [
9607
9585
  index !== void 0 && /* @__PURE__ */ jsxs(
9608
- "span",
9586
+ Typography,
9609
9587
  {
9588
+ as: "span",
9610
9589
  className: cn(
9611
9590
  "flex-shrink-0 font-mono font-bold text-sm",
9612
9591
  selected ? "text-accent" : "text-muted-foreground"
@@ -9617,24 +9596,14 @@ function ChoiceButton({
9617
9596
  ]
9618
9597
  }
9619
9598
  ),
9620
- assetUrl ? /* @__PURE__ */ jsx(
9621
- "img",
9622
- {
9623
- src: assetUrl.url,
9624
- alt: "",
9625
- width: 16,
9626
- height: 16,
9627
- style: { imageRendering: "pixelated", objectFit: "contain" },
9628
- className: "flex-shrink-0"
9629
- }
9630
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
9599
+ 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" ? (() => {
9631
9600
  const I = resolveIcon(icon);
9632
9601
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
9633
9602
  })() : /* @__PURE__ */ (() => {
9634
9603
  const I = icon;
9635
9604
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
9636
9605
  })() }) : null,
9637
- /* @__PURE__ */ jsx("span", { className: "text-sm leading-snug", children: text })
9606
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm leading-snug", children: text })
9638
9607
  ]
9639
9608
  }
9640
9609
  );
@@ -9644,6 +9613,10 @@ var init_ChoiceButton = __esm({
9644
9613
  init_cn();
9645
9614
  init_Icon();
9646
9615
  init_useEventBus();
9616
+ init_Button();
9617
+ init_Box();
9618
+ init_Typography();
9619
+ init_GameIcon();
9647
9620
  ChoiceButton.displayName = "ChoiceButton";
9648
9621
  }
9649
9622
  });
@@ -9661,16 +9634,16 @@ function ActionButton({
9661
9634
  className
9662
9635
  }) {
9663
9636
  const eventBus = useEventBus();
9664
- const sizes = sizeMap12[size];
9637
+ const sizes = sizeMap13[size];
9665
9638
  const onCooldown = cooldown > 0;
9666
9639
  const isDisabled = disabled || onCooldown;
9667
9640
  const cooldownDeg = Math.round(cooldown * 360);
9668
9641
  return /* @__PURE__ */ jsxs(
9669
- "button",
9642
+ Button,
9670
9643
  {
9671
- type: "button",
9644
+ variant: variant === "danger" ? "danger" : variant === "secondary" ? "secondary" : "primary",
9672
9645
  disabled: isDisabled,
9673
- onClick: (e) => {
9646
+ onClick: () => {
9674
9647
  if (action) eventBus.emit(`UI:${action}`, {});
9675
9648
  onClick?.();
9676
9649
  },
@@ -9683,9 +9656,10 @@ function ActionButton({
9683
9656
  ),
9684
9657
  children: [
9685
9658
  onCooldown && /* @__PURE__ */ jsx(
9686
- "div",
9659
+ Box,
9687
9660
  {
9688
- className: "absolute inset-0 bg-foreground/40 pointer-events-none",
9661
+ position: "absolute",
9662
+ className: "inset-0 bg-foreground/40 pointer-events-none",
9689
9663
  style: {
9690
9664
  clipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
9691
9665
  WebkitClipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
@@ -9693,27 +9667,18 @@ function ActionButton({
9693
9667
  }
9694
9668
  }
9695
9669
  ),
9696
- assetUrl ? /* @__PURE__ */ jsx(
9697
- "img",
9698
- {
9699
- src: assetUrl.url,
9700
- alt: "",
9701
- width: 16,
9702
- height: 16,
9703
- style: { imageRendering: "pixelated", objectFit: "contain" },
9704
- className: cn("flex-shrink-0", sizes.icon)
9705
- }
9706
- ) : icon ? /* @__PURE__ */ jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
9670
+ 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" ? (() => {
9707
9671
  const I = resolveIcon(icon);
9708
9672
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
9709
9673
  })() : /* @__PURE__ */ (() => {
9710
9674
  const I = icon;
9711
9675
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
9712
9676
  })() }) : null,
9713
- /* @__PURE__ */ jsx("span", { className: "relative z-10", children: label }),
9677
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "relative z-10", children: label }),
9714
9678
  hotkey && /* @__PURE__ */ jsx(
9715
- "span",
9679
+ Typography,
9716
9680
  {
9681
+ as: "span",
9717
9682
  className: cn(
9718
9683
  "absolute top-0.5 right-0.5 bg-foreground/30 text-primary-foreground rounded font-mono leading-tight",
9719
9684
  sizes.hotkey
@@ -9725,13 +9690,17 @@ function ActionButton({
9725
9690
  }
9726
9691
  );
9727
9692
  }
9728
- var sizeMap12, variantStyles8, DEFAULT_ASSET_URL11;
9693
+ var sizeMap13, variantStyles8, DEFAULT_ASSET_URL11;
9729
9694
  var init_ActionButton = __esm({
9730
9695
  "components/game/2d/atoms/ActionButton.tsx"() {
9731
9696
  init_cn();
9732
9697
  init_Icon();
9733
9698
  init_useEventBus();
9734
- sizeMap12 = {
9699
+ init_Button();
9700
+ init_Box();
9701
+ init_Typography();
9702
+ init_GameIcon();
9703
+ sizeMap13 = {
9735
9704
  sm: { button: "h-button-sm px-3 text-xs", hotkey: "text-[9px] px-1", icon: "text-xs" },
9736
9705
  md: { button: "h-button-md px-4 text-sm", hotkey: "text-xs px-1.5", icon: "text-sm" },
9737
9706
  lg: { button: "h-button-lg px-5 text-base", hotkey: "text-xs px-2", icon: "text-base" }
@@ -9833,10 +9802,12 @@ function MiniMap({
9833
9802
  return /* @__PURE__ */ jsxs(Fragment, { children: [
9834
9803
  /* @__PURE__ */ jsx("style", { children: `@keyframes minimap-blink{0%,49%{opacity:1}50%,100%{opacity:0}}` }),
9835
9804
  /* @__PURE__ */ jsxs(
9836
- "div",
9805
+ Box,
9837
9806
  {
9807
+ position: "relative",
9808
+ display: "inline-block",
9838
9809
  className: cn(
9839
- "relative inline-block border border-border/20 rounded-container",
9810
+ "border border-border/20 rounded-container",
9840
9811
  className
9841
9812
  ),
9842
9813
  children: [
@@ -9851,10 +9822,10 @@ function MiniMap({
9851
9822
  }
9852
9823
  ),
9853
9824
  playerLeft !== null && playerTop !== null && /* @__PURE__ */ jsx(
9854
- "div",
9825
+ Box,
9855
9826
  {
9827
+ position: "absolute",
9856
9828
  style: {
9857
- position: "absolute",
9858
9829
  left: playerLeft,
9859
9830
  top: playerTop,
9860
9831
  width: 3,
@@ -9875,6 +9846,7 @@ var init_MiniMap = __esm({
9875
9846
  "components/game/2d/atoms/MiniMap.tsx"() {
9876
9847
  "use client";
9877
9848
  init_cn();
9849
+ init_Box();
9878
9850
  DEFAULT_TILES = [
9879
9851
  { x: 10, y: 10, color: "#4ade80" },
9880
9852
  { x: 20, y: 15, color: "#4ade80" },
@@ -9892,38 +9864,6 @@ var init_MiniMap = __esm({
9892
9864
  MiniMap.displayName = "MiniMap";
9893
9865
  }
9894
9866
  });
9895
- function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
9896
- const px = typeof size === "number" ? size : sizeMap13[size];
9897
- if (assetUrl?.url) {
9898
- return /* @__PURE__ */ jsx(
9899
- "img",
9900
- {
9901
- src: assetUrl.url,
9902
- alt: alt ?? assetUrl.category ?? "",
9903
- width: px,
9904
- height: px,
9905
- style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
9906
- className: cn("flex-shrink-0", className)
9907
- }
9908
- );
9909
- }
9910
- const I = typeof icon === "string" ? resolveIcon(icon) : icon;
9911
- return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
9912
- }
9913
- var sizeMap13;
9914
- var init_GameIcon = __esm({
9915
- "components/game/2d/atoms/GameIcon.tsx"() {
9916
- "use client";
9917
- init_cn();
9918
- init_Icon();
9919
- sizeMap13 = {
9920
- sm: 16,
9921
- md: 24,
9922
- lg: 32
9923
- };
9924
- GameIcon.displayName = "GameIcon";
9925
- }
9926
- });
9927
9867
  function ControlGrid({
9928
9868
  kind,
9929
9869
  buttons = DEFAULT_BUTTONS,
@@ -9984,22 +9924,22 @@ function ControlGrid({
9984
9924
  },
9985
9925
  d
9986
9926
  );
9987
- return /* @__PURE__ */ jsxs("div", { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
9988
- /* @__PURE__ */ jsx("div", {}),
9927
+ return /* @__PURE__ */ jsxs(Box, { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
9928
+ /* @__PURE__ */ jsx(Box, {}),
9989
9929
  dir("up"),
9990
- /* @__PURE__ */ jsx("div", {}),
9930
+ /* @__PURE__ */ jsx(Box, {}),
9991
9931
  dir("left"),
9992
- /* @__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" }) }),
9932
+ /* @__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" }) }),
9993
9933
  dir("right"),
9994
- /* @__PURE__ */ jsx("div", {}),
9934
+ /* @__PURE__ */ jsx(Box, {}),
9995
9935
  dir("down"),
9996
- /* @__PURE__ */ jsx("div", {})
9936
+ /* @__PURE__ */ jsx(Box, {})
9997
9937
  ] });
9998
9938
  }
9999
9939
  if (layout === "diamond" && buttons.length === 4) {
10000
9940
  const [top, right, bottom, left] = buttons;
10001
- return /* @__PURE__ */ jsxs("div", { className: cn(layoutClass.diamond, className), children: [
10002
- /* @__PURE__ */ jsx("div", {}),
9941
+ return /* @__PURE__ */ jsxs(Box, { className: cn(layoutClass.diamond, className), children: [
9942
+ /* @__PURE__ */ jsx(Box, {}),
10003
9943
  /* @__PURE__ */ jsx(
10004
9944
  ControlButton,
10005
9945
  {
@@ -10014,7 +9954,7 @@ function ControlGrid({
10014
9954
  disabled
10015
9955
  }
10016
9956
  ),
10017
- /* @__PURE__ */ jsx("div", {}),
9957
+ /* @__PURE__ */ jsx(Box, {}),
10018
9958
  /* @__PURE__ */ jsx(
10019
9959
  ControlButton,
10020
9960
  {
@@ -10029,7 +9969,7 @@ function ControlGrid({
10029
9969
  disabled
10030
9970
  }
10031
9971
  ),
10032
- /* @__PURE__ */ jsx("div", {}),
9972
+ /* @__PURE__ */ jsx(Box, {}),
10033
9973
  /* @__PURE__ */ jsx(
10034
9974
  ControlButton,
10035
9975
  {
@@ -10044,7 +9984,7 @@ function ControlGrid({
10044
9984
  disabled
10045
9985
  }
10046
9986
  ),
10047
- /* @__PURE__ */ jsx("div", {}),
9987
+ /* @__PURE__ */ jsx(Box, {}),
10048
9988
  /* @__PURE__ */ jsx(
10049
9989
  ControlButton,
10050
9990
  {
@@ -10059,10 +9999,10 @@ function ControlGrid({
10059
9999
  disabled
10060
10000
  }
10061
10001
  ),
10062
- /* @__PURE__ */ jsx("div", {})
10002
+ /* @__PURE__ */ jsx(Box, {})
10063
10003
  ] });
10064
10004
  }
10065
- return /* @__PURE__ */ jsx("div", { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
10005
+ return /* @__PURE__ */ jsx(Box, { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
10066
10006
  ControlButton,
10067
10007
  {
10068
10008
  icon: button.icon,
@@ -10084,6 +10024,7 @@ var init_ControlGrid = __esm({
10084
10024
  "use client";
10085
10025
  init_cn();
10086
10026
  init_useEventBus();
10027
+ init_Box();
10087
10028
  init_ControlButton();
10088
10029
  sizeKey = { sm: "sm", md: "md", lg: "lg" };
10089
10030
  layoutClass = {
@@ -10128,7 +10069,7 @@ function StatBadge({
10128
10069
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
10129
10070
  const resolvedAsset = iconUrl ?? assetUrl;
10130
10071
  return /* @__PURE__ */ jsxs(
10131
- "div",
10072
+ Box,
10132
10073
  {
10133
10074
  className: cn(
10134
10075
  "inline-flex items-center gap-2 rounded-container border backdrop-blur-sm",
@@ -10137,18 +10078,8 @@ function StatBadge({
10137
10078
  className
10138
10079
  ),
10139
10080
  children: [
10140
- resolvedAsset ? /* @__PURE__ */ jsx(
10141
- "img",
10142
- {
10143
- src: resolvedAsset.url,
10144
- alt: "",
10145
- width: 16,
10146
- height: 16,
10147
- style: { imageRendering: "pixelated", objectFit: "contain" },
10148
- className: "flex-shrink-0"
10149
- }
10150
- ) : 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,
10151
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-medium", children: label }),
10081
+ 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,
10082
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground font-medium", children: label }),
10152
10083
  format === "hearts" && max && /* @__PURE__ */ jsx(
10153
10084
  HealthBar,
10154
10085
  {
@@ -10174,7 +10105,7 @@ function StatBadge({
10174
10105
  size: size === "lg" ? "md" : "sm"
10175
10106
  }
10176
10107
  ),
10177
- format === "text" && /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground", children: value })
10108
+ format === "text" && /* @__PURE__ */ jsx(Typography, { as: "span", className: "font-bold text-foreground", children: value })
10178
10109
  ]
10179
10110
  }
10180
10111
  );
@@ -10184,6 +10115,9 @@ var init_StatBadge = __esm({
10184
10115
  "components/game/2d/molecules/StatBadge.tsx"() {
10185
10116
  init_cn();
10186
10117
  init_Icon();
10118
+ init_Box();
10119
+ init_Typography();
10120
+ init_GameIcon();
10187
10121
  init_HealthBar();
10188
10122
  init_ScoreDisplay();
10189
10123
  sizeMap14 = {
@@ -10361,9 +10295,9 @@ function GameHud({
10361
10295
  if (position === "corners") {
10362
10296
  const leftStats = stats.slice(0, Math.ceil(stats.length / 2));
10363
10297
  const rightStats = stats.slice(Math.ceil(stats.length / 2));
10364
- return /* @__PURE__ */ jsxs("div", { className: cn("relative", positionMap[position], className), children: [
10365
- /* @__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)) }),
10366
- /* @__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)) })
10298
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn(positionMap[position], className), children: [
10299
+ /* @__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)) }),
10300
+ /* @__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)) })
10367
10301
  ] });
10368
10302
  }
10369
10303
  if (position === "top" || position === "bottom") {
@@ -10372,7 +10306,7 @@ function GameHud({
10372
10306
  const rightStats = stats.slice(mid);
10373
10307
  const isTop = position === "top";
10374
10308
  return /* @__PURE__ */ jsxs(
10375
- "div",
10309
+ Box,
10376
10310
  {
10377
10311
  className: cn(
10378
10312
  "flex items-center justify-between w-full",
@@ -10382,17 +10316,18 @@ function GameHud({
10382
10316
  className
10383
10317
  ),
10384
10318
  children: [
10385
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10386
- 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)) })
10319
+ /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10320
+ 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)) })
10387
10321
  ]
10388
10322
  }
10389
10323
  );
10390
10324
  }
10391
10325
  return /* @__PURE__ */ jsx(
10392
- "div",
10326
+ Box,
10393
10327
  {
10328
+ position: "relative",
10394
10329
  className: cn(
10395
- "relative z-10 flex items-center gap-4 px-4 py-2",
10330
+ "z-10 flex items-center gap-4 px-4 py-2",
10396
10331
  transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
10397
10332
  className
10398
10333
  ),
@@ -10404,6 +10339,7 @@ var positionMap, DEFAULT_HUD_STATS;
10404
10339
  var init_GameHud = __esm({
10405
10340
  "components/game/2d/molecules/GameHud.tsx"() {
10406
10341
  init_cn();
10342
+ init_Box();
10407
10343
  init_StatBadge();
10408
10344
  positionMap = {
10409
10345
  corners: "inset-0 pointer-events-none"
@@ -10444,7 +10380,7 @@ function GameMenu({
10444
10380
  [eventBus, onSelect]
10445
10381
  );
10446
10382
  return /* @__PURE__ */ jsxs(
10447
- "div",
10383
+ Box,
10448
10384
  {
10449
10385
  className: cn(
10450
10386
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
@@ -10454,18 +10390,12 @@ function GameMenu({
10454
10390
  background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
10455
10391
  },
10456
10392
  children: [
10457
- /* @__PURE__ */ jsxs("div", { className: "text-center mb-12 animate-fade-in", children: [
10458
- logo && /* @__PURE__ */ jsx(
10459
- "img",
10460
- {
10461
- src: logo.url,
10462
- alt: title,
10463
- className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl"
10464
- }
10465
- ),
10393
+ /* @__PURE__ */ jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
10394
+ logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
10466
10395
  /* @__PURE__ */ jsx(
10467
- "h1",
10396
+ Typography,
10468
10397
  {
10398
+ variant: "h1",
10469
10399
  className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
10470
10400
  style: {
10471
10401
  textShadow: "0 4px 12px rgba(0,0,0,0.5)"
@@ -10473,9 +10403,9 @@ function GameMenu({
10473
10403
  children: title
10474
10404
  }
10475
10405
  ),
10476
- subtitle && /* @__PURE__ */ jsx("p", { className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
10406
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
10477
10407
  ] }),
10478
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
10408
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
10479
10409
  ChoiceButton,
10480
10410
  {
10481
10411
  text: option.label,
@@ -10486,9 +10416,9 @@ function GameMenu({
10486
10416
  },
10487
10417
  index
10488
10418
  )) }),
10489
- /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 pointer-events-none overflow-hidden", children: [
10490
- /* @__PURE__ */ jsx("div", { className: "absolute top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
10491
- /* @__PURE__ */ jsx("div", { className: "absolute bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
10419
+ /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
10420
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
10421
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
10492
10422
  ] })
10493
10423
  ]
10494
10424
  }
@@ -10500,6 +10430,9 @@ var init_GameMenu = __esm({
10500
10430
  "use client";
10501
10431
  init_cn();
10502
10432
  init_useEventBus();
10433
+ init_Box();
10434
+ init_Typography();
10435
+ init_GameIcon();
10503
10436
  init_ChoiceButton();
10504
10437
  DEFAULT_MENU_OPTIONS = [
10505
10438
  { label: "New Game", event: "NEW_GAME", variant: "primary" },
@@ -11919,10 +11852,11 @@ function Canvas2D({
11919
11852
  }
11920
11853
  }
11921
11854
  ),
11922
- process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs("div", { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
11855
+ process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs(Box, { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
11923
11856
  tileClickEvent && /* @__PURE__ */ jsx(
11924
- "button",
11857
+ Button,
11925
11858
  {
11859
+ variant: "ghost",
11926
11860
  "data-event": tileClickEvent,
11927
11861
  "data-x": "0",
11928
11862
  "data-y": "0",
@@ -11931,8 +11865,9 @@ function Canvas2D({
11931
11865
  }
11932
11866
  ),
11933
11867
  unitClickEvent && units && units.length > 0 && /* @__PURE__ */ jsx(
11934
- "button",
11868
+ Button,
11935
11869
  {
11870
+ variant: "ghost",
11936
11871
  "data-event": unitClickEvent,
11937
11872
  "data-unit-id": units[0].id,
11938
11873
  onClick: () => eventBus.emit(`UI:${unitClickEvent}`, { unitId: units[0].id }),
@@ -11941,15 +11876,17 @@ function Canvas2D({
11941
11876
  )
11942
11877
  ] }),
11943
11878
  unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxs(
11944
- "div",
11879
+ Box,
11945
11880
  {
11946
- className: "absolute pointer-events-none",
11881
+ position: "absolute",
11882
+ className: "pointer-events-none",
11947
11883
  style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
11948
11884
  children: [
11949
11885
  unit.name && /* @__PURE__ */ jsx(
11950
- "div",
11886
+ Typography,
11951
11887
  {
11952
- className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
11888
+ as: "span",
11889
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap block",
11953
11890
  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)" },
11954
11891
  children: unit.name
11955
11892
  }
@@ -11959,7 +11896,7 @@ function Canvas2D({
11959
11896
  },
11960
11897
  unit.id
11961
11898
  )),
11962
- showMinimap && /* @__PURE__ */ jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
11899
+ showMinimap && /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
11963
11900
  MiniMap,
11964
11901
  {
11965
11902
  tiles: miniMapTiles,
@@ -11981,6 +11918,7 @@ var init_Canvas2D = __esm({
11981
11918
  init_cn();
11982
11919
  init_useEventBus();
11983
11920
  init_Box();
11921
+ init_Button();
11984
11922
  init_Stack();
11985
11923
  init_Icon();
11986
11924
  init_Typography();
@@ -12312,7 +12250,7 @@ function GameAudioToggle({
12312
12250
  onClick: handleToggle,
12313
12251
  className: cn("text-lg leading-none px-2", className),
12314
12252
  "aria-pressed": muted,
12315
- 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}"
12253
+ 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}"
12316
12254
  }
12317
12255
  );
12318
12256
  }
@@ -12322,6 +12260,7 @@ var init_GameAudioToggle = __esm({
12322
12260
  init_atoms();
12323
12261
  init_cn();
12324
12262
  init_GameAudioProvider();
12263
+ init_GameIcon();
12325
12264
  GameAudioToggle.displayName = "GameAudioToggle";
12326
12265
  }
12327
12266
  });
@@ -23292,7 +23231,7 @@ var init_Tabs = __esm({
23292
23231
  isActive ? variant === "pills" ? "text-primary-foreground font-bold" : "text-foreground font-bold" : "text-muted-foreground hover:text-foreground"
23293
23232
  ),
23294
23233
  children: [
23295
- item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm" })),
23234
+ item.iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: item.iconAsset.url, alt: item.iconAsset.name ?? item.iconAsset.category ?? "", width: 16, height: 16, style: { imageRendering: "pixelated", objectFit: "contain", width: 16, height: 16 }, className: "flex-shrink-0" }) : item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm" })),
23296
23235
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: isActive ? "semibold" : "normal", className: "!text-inherit", children: item.label }),
23297
23236
  item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge })
23298
23237
  ]