@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.
@@ -2168,6 +2168,7 @@ var init_Button = __esm({
2168
2168
  rightIcon,
2169
2169
  icon: iconProp,
2170
2170
  iconRight: iconRightProp,
2171
+ iconAsset,
2171
2172
  action,
2172
2173
  actionPayload,
2173
2174
  label,
@@ -2179,7 +2180,8 @@ var init_Button = __esm({
2179
2180
  const eventBus = useEventBus();
2180
2181
  const leftIconValue = leftIcon || iconProp;
2181
2182
  const rightIconValue = rightIcon || iconRightProp;
2182
- const resolvedLeftIcon = resolveIconProp(leftIconValue, iconSizeStyles[size]);
2183
+ const px = size === "sm" ? 16 : size === "lg" ? 20 : 16;
2184
+ const resolvedLeftIcon = iconAsset?.url ? /* @__PURE__ */ jsxRuntime.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]);
2183
2185
  const resolvedRightIcon = resolveIconProp(rightIconValue, iconSizeStyles[size]);
2184
2186
  const handleClick = (e) => {
2185
2187
  if (action) {
@@ -2933,13 +2935,14 @@ var init_Badge = __esm({
2933
2935
  lg: "px-3 py-1.5 text-base"
2934
2936
  };
2935
2937
  exports.Badge = React79__namespace.default.forwardRef(
2936
- ({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
2938
+ ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
2937
2939
  const iconSizes3 = {
2938
2940
  sm: "h-icon-default w-icon-default",
2939
2941
  md: "h-icon-default w-icon-default",
2940
2942
  lg: "h-icon-default w-icon-default"
2941
2943
  };
2942
- const resolvedIcon = typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon, className: iconSizes3[size] }) : null;
2944
+ const iconPx = size === "lg" ? 20 : 16;
2945
+ const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(exports.Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon, className: iconSizes3[size] }) : null;
2943
2946
  return /* @__PURE__ */ jsxRuntime.jsxs(
2944
2947
  "span",
2945
2948
  {
@@ -7972,6 +7975,38 @@ var init_Accordion = __esm({
7972
7975
  exports.Accordion.displayName = "Accordion";
7973
7976
  }
7974
7977
  });
7978
+ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
7979
+ const px = typeof size === "number" ? size : sizeMap[size];
7980
+ if (assetUrl?.url) {
7981
+ return /* @__PURE__ */ jsxRuntime.jsx(
7982
+ "img",
7983
+ {
7984
+ src: assetUrl.url,
7985
+ alt: alt ?? assetUrl.category ?? "",
7986
+ width: px,
7987
+ height: px,
7988
+ style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
7989
+ className: cn("flex-shrink-0", className)
7990
+ }
7991
+ );
7992
+ }
7993
+ const I = typeof icon === "string" ? resolveIcon(icon) : icon;
7994
+ return /* @__PURE__ */ jsxRuntime.jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
7995
+ }
7996
+ var sizeMap;
7997
+ var init_GameIcon = __esm({
7998
+ "components/game/2d/atoms/GameIcon.tsx"() {
7999
+ "use client";
8000
+ init_cn();
8001
+ init_Icon();
8002
+ sizeMap = {
8003
+ sm: 16,
8004
+ md: 24,
8005
+ lg: 32
8006
+ };
8007
+ GameIcon.displayName = "GameIcon";
8008
+ }
8009
+ });
7975
8010
  function ActionButton({
7976
8011
  assetUrl = DEFAULT_ASSET_URL,
7977
8012
  label = "Attack",
@@ -7986,16 +8021,16 @@ function ActionButton({
7986
8021
  className
7987
8022
  }) {
7988
8023
  const eventBus = useEventBus();
7989
- const sizes = sizeMap[size];
8024
+ const sizes = sizeMap2[size];
7990
8025
  const onCooldown = cooldown > 0;
7991
8026
  const isDisabled = disabled || onCooldown;
7992
8027
  const cooldownDeg = Math.round(cooldown * 360);
7993
8028
  return /* @__PURE__ */ jsxRuntime.jsxs(
7994
- "button",
8029
+ exports.Button,
7995
8030
  {
7996
- type: "button",
8031
+ variant: variant === "danger" ? "danger" : variant === "secondary" ? "secondary" : "primary",
7997
8032
  disabled: isDisabled,
7998
- onClick: (e) => {
8033
+ onClick: () => {
7999
8034
  if (action) eventBus.emit(`UI:${action}`, {});
8000
8035
  onClick?.();
8001
8036
  },
@@ -8008,9 +8043,10 @@ function ActionButton({
8008
8043
  ),
8009
8044
  children: [
8010
8045
  onCooldown && /* @__PURE__ */ jsxRuntime.jsx(
8011
- "div",
8046
+ exports.Box,
8012
8047
  {
8013
- className: "absolute inset-0 bg-foreground/40 pointer-events-none",
8048
+ position: "absolute",
8049
+ className: "inset-0 bg-foreground/40 pointer-events-none",
8014
8050
  style: {
8015
8051
  clipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
8016
8052
  WebkitClipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
@@ -8018,27 +8054,18 @@ function ActionButton({
8018
8054
  }
8019
8055
  }
8020
8056
  ),
8021
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
8022
- "img",
8023
- {
8024
- src: assetUrl.url,
8025
- alt: "",
8026
- width: 16,
8027
- height: 16,
8028
- style: { imageRendering: "pixelated", objectFit: "contain" },
8029
- className: cn("flex-shrink-0", sizes.icon)
8030
- }
8031
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
8057
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 16, className: cn("flex-shrink-0", sizes.icon) }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
8032
8058
  const I = resolveIcon(icon);
8033
8059
  return I ? /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-4 h-4" }) : null;
8034
8060
  })() : /* @__PURE__ */ (() => {
8035
8061
  const I = icon;
8036
8062
  return /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-4 h-4" });
8037
8063
  })() }) : null,
8038
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative z-10", children: label }),
8064
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "relative z-10", children: label }),
8039
8065
  hotkey && /* @__PURE__ */ jsxRuntime.jsx(
8040
- "span",
8066
+ exports.Typography,
8041
8067
  {
8068
+ as: "span",
8042
8069
  className: cn(
8043
8070
  "absolute top-0.5 right-0.5 bg-foreground/30 text-primary-foreground rounded font-mono leading-tight",
8044
8071
  sizes.hotkey
@@ -8050,13 +8077,17 @@ function ActionButton({
8050
8077
  }
8051
8078
  );
8052
8079
  }
8053
- var sizeMap, variantStyles7, DEFAULT_ASSET_URL;
8080
+ var sizeMap2, variantStyles7, DEFAULT_ASSET_URL;
8054
8081
  var init_ActionButton = __esm({
8055
8082
  "components/game/2d/atoms/ActionButton.tsx"() {
8056
8083
  init_cn();
8057
8084
  init_Icon();
8058
8085
  init_useEventBus();
8059
- sizeMap = {
8086
+ init_Button();
8087
+ init_Box();
8088
+ init_Typography();
8089
+ init_GameIcon();
8090
+ sizeMap2 = {
8060
8091
  sm: { button: "h-button-sm px-3 text-xs", hotkey: "text-[9px] px-1", icon: "text-xs" },
8061
8092
  md: { button: "h-button-md px-4 text-sm", hotkey: "text-xs px-1.5", icon: "text-sm" },
8062
8093
  lg: { button: "h-button-lg px-5 text-base", hotkey: "text-xs px-2", icon: "text-base" }
@@ -8789,10 +8820,12 @@ function MiniMap({
8789
8820
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8790
8821
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: `@keyframes minimap-blink{0%,49%{opacity:1}50%,100%{opacity:0}}` }),
8791
8822
  /* @__PURE__ */ jsxRuntime.jsxs(
8792
- "div",
8823
+ exports.Box,
8793
8824
  {
8825
+ position: "relative",
8826
+ display: "inline-block",
8794
8827
  className: cn(
8795
- "relative inline-block border border-border/20 rounded-container",
8828
+ "border border-border/20 rounded-container",
8796
8829
  className
8797
8830
  ),
8798
8831
  children: [
@@ -8807,10 +8840,10 @@ function MiniMap({
8807
8840
  }
8808
8841
  ),
8809
8842
  playerLeft !== null && playerTop !== null && /* @__PURE__ */ jsxRuntime.jsx(
8810
- "div",
8843
+ exports.Box,
8811
8844
  {
8845
+ position: "absolute",
8812
8846
  style: {
8813
- position: "absolute",
8814
8847
  left: playerLeft,
8815
8848
  top: playerTop,
8816
8849
  width: 3,
@@ -8831,6 +8864,7 @@ var init_MiniMap = __esm({
8831
8864
  "components/game/2d/atoms/MiniMap.tsx"() {
8832
8865
  "use client";
8833
8866
  init_cn();
8867
+ init_Box();
8834
8868
  DEFAULT_TILES = [
8835
8869
  { x: 10, y: 10, color: "#4ade80" },
8836
8870
  { x: 20, y: 15, color: "#4ade80" },
@@ -8861,12 +8895,13 @@ function HealthBar({
8861
8895
  frameAsset,
8862
8896
  fillAsset
8863
8897
  }) {
8864
- const sizes = sizeMap2[size];
8898
+ const sizes = sizeMap3[size];
8865
8899
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
8866
8900
  if (format === "hearts") {
8867
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
8868
- "span",
8901
+ return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
8902
+ exports.Box,
8869
8903
  {
8904
+ as: "span",
8870
8905
  className: cn(animated && "transition-transform hover:scale-110"),
8871
8906
  children: heartIcon(i < current, sizes.heart)
8872
8907
  },
@@ -8875,10 +8910,12 @@ function HealthBar({
8875
8910
  }
8876
8911
  if (format === "bar") {
8877
8912
  return /* @__PURE__ */ jsxRuntime.jsx(
8878
- "div",
8913
+ exports.Box,
8879
8914
  {
8915
+ position: "relative",
8916
+ overflow: "hidden",
8880
8917
  className: cn(
8881
- "relative overflow-hidden rounded-full",
8918
+ "rounded-full",
8882
8919
  !frameAsset && "bg-muted",
8883
8920
  sizes.bar,
8884
8921
  "w-24",
@@ -8886,10 +8923,11 @@ function HealthBar({
8886
8923
  ),
8887
8924
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
8888
8925
  children: /* @__PURE__ */ jsxRuntime.jsx(
8889
- "div",
8926
+ exports.Box,
8890
8927
  {
8928
+ position: "absolute",
8891
8929
  className: cn(
8892
- "absolute inset-y-0 left-0 rounded-full",
8930
+ "inset-y-0 left-0 rounded-full",
8893
8931
  !fillAsset && (percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error"),
8894
8932
  animated && "transition-all duration-300"
8895
8933
  ),
@@ -8903,10 +8941,11 @@ function HealthBar({
8903
8941
  );
8904
8942
  }
8905
8943
  if (format === "progress") {
8906
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2", className), children: [
8944
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: cn("flex items-center gap-2", className), children: [
8907
8945
  level != null && /* @__PURE__ */ jsxRuntime.jsxs(
8908
- "span",
8946
+ exports.Typography,
8909
8947
  {
8948
+ as: "span",
8910
8949
  className: cn(
8911
8950
  "flex-shrink-0 rounded-interactive font-bold",
8912
8951
  "bg-accent text-accent-foreground border border-accent",
@@ -8918,21 +8957,23 @@ function HealthBar({
8918
8957
  ]
8919
8958
  }
8920
8959
  ),
8921
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [
8960
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex-1 flex flex-col gap-0.5", children: [
8922
8961
  /* @__PURE__ */ jsxRuntime.jsx(
8923
- "div",
8962
+ exports.Box,
8924
8963
  {
8964
+ position: "relative",
8925
8965
  className: cn(
8926
- "relative w-full overflow-hidden rounded-full",
8966
+ "w-full overflow-hidden rounded-full",
8927
8967
  !frameAsset && "bg-muted border border-muted",
8928
8968
  sizes.bar
8929
8969
  ),
8930
8970
  style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
8931
8971
  children: /* @__PURE__ */ jsxRuntime.jsx(
8932
- "div",
8972
+ exports.Box,
8933
8973
  {
8974
+ position: "absolute",
8934
8975
  className: cn(
8935
- "absolute inset-y-0 left-0 rounded-full",
8976
+ "inset-y-0 left-0 rounded-full",
8936
8977
  !fillAsset && "bg-gradient-to-r from-accent to-info",
8937
8978
  animated && "transition-all duration-500 ease-out"
8938
8979
  ),
@@ -8944,7 +8985,7 @@ function HealthBar({
8944
8985
  )
8945
8986
  }
8946
8987
  ),
8947
- showLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
8988
+ showLabel && /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { as: "span", className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
8948
8989
  current,
8949
8990
  " / ",
8950
8991
  max,
@@ -8953,16 +8994,18 @@ function HealthBar({
8953
8994
  ] })
8954
8995
  ] });
8955
8996
  }
8956
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("font-mono font-bold", sizes.text, className), children: [
8997
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { as: "span", className: cn("font-mono font-bold", sizes.text, className), children: [
8957
8998
  current,
8958
8999
  "/",
8959
9000
  max
8960
9001
  ] });
8961
9002
  }
8962
- var heartIcon, sizeMap2;
9003
+ var heartIcon, sizeMap3;
8963
9004
  var init_HealthBar = __esm({
8964
9005
  "components/game/2d/atoms/HealthBar.tsx"() {
8965
9006
  init_cn();
9007
+ init_Box();
9008
+ init_Typography();
8966
9009
  heartIcon = (filled, size) => /* @__PURE__ */ jsxRuntime.jsx(
8967
9010
  "svg",
8968
9011
  {
@@ -8974,7 +9017,7 @@ var init_HealthBar = __esm({
8974
9017
  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" })
8975
9018
  }
8976
9019
  );
8977
- sizeMap2 = {
9020
+ sizeMap3 = {
8978
9021
  sm: { heart: "w-4 h-4", bar: "h-2", text: "text-sm", label: "text-xs", badge: "text-xs px-1.5 py-0.5" },
8979
9022
  md: { heart: "w-6 h-6", bar: "h-3", text: "text-base", label: "text-xs", badge: "text-xs px-2 py-0.5" },
8980
9023
  lg: { heart: "w-8 h-8", bar: "h-4", text: "text-lg", label: "text-sm", badge: "text-sm px-2.5 py-1" }
@@ -10762,10 +10805,11 @@ function Canvas2D({
10762
10805
  }
10763
10806
  }
10764
10807
  ),
10765
- process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
10808
+ process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
10766
10809
  tileClickEvent && /* @__PURE__ */ jsxRuntime.jsx(
10767
- "button",
10810
+ exports.Button,
10768
10811
  {
10812
+ variant: "ghost",
10769
10813
  "data-event": tileClickEvent,
10770
10814
  "data-x": "0",
10771
10815
  "data-y": "0",
@@ -10774,8 +10818,9 @@ function Canvas2D({
10774
10818
  }
10775
10819
  ),
10776
10820
  unitClickEvent && units && units.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
10777
- "button",
10821
+ exports.Button,
10778
10822
  {
10823
+ variant: "ghost",
10779
10824
  "data-event": unitClickEvent,
10780
10825
  "data-unit-id": units[0].id,
10781
10826
  onClick: () => eventBus.emit(`UI:${unitClickEvent}`, { unitId: units[0].id }),
@@ -10784,15 +10829,17 @@ function Canvas2D({
10784
10829
  )
10785
10830
  ] }),
10786
10831
  unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxRuntime.jsxs(
10787
- "div",
10832
+ exports.Box,
10788
10833
  {
10789
- className: "absolute pointer-events-none",
10834
+ position: "absolute",
10835
+ className: "pointer-events-none",
10790
10836
  style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
10791
10837
  children: [
10792
10838
  unit.name && /* @__PURE__ */ jsxRuntime.jsx(
10793
- "div",
10839
+ exports.Typography,
10794
10840
  {
10795
- className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
10841
+ as: "span",
10842
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap block",
10796
10843
  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)" },
10797
10844
  children: unit.name
10798
10845
  }
@@ -10802,7 +10849,7 @@ function Canvas2D({
10802
10849
  },
10803
10850
  unit.id
10804
10851
  )),
10805
- showMinimap && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsxRuntime.jsx(
10852
+ showMinimap && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { position: "absolute", className: "bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsxRuntime.jsx(
10806
10853
  MiniMap,
10807
10854
  {
10808
10855
  tiles: miniMapTiles,
@@ -10824,6 +10871,7 @@ var init_Canvas2D = __esm({
10824
10871
  init_cn();
10825
10872
  init_useEventBus();
10826
10873
  init_Box();
10874
+ init_Button();
10827
10875
  init_Stack();
10828
10876
  init_Icon();
10829
10877
  init_Typography();
@@ -12854,7 +12902,7 @@ var init_Tabs = __esm({
12854
12902
  isActive ? variant === "pills" ? "text-primary-foreground font-bold" : "text-foreground font-bold" : "text-muted-foreground hover:text-foreground"
12855
12903
  ),
12856
12904
  children: [
12857
- item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: item.icon, size: "sm" })),
12905
+ item.iconAsset?.url ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(exports.Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: item.icon, size: "sm" })),
12858
12906
  /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: isActive ? "semibold" : "normal", className: "!text-inherit", children: item.label }),
12859
12907
  item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", size: "sm", children: item.badge })
12860
12908
  ]
@@ -17201,38 +17249,6 @@ var init_Breadcrumb = __esm({
17201
17249
  exports.Breadcrumb.displayName = "Breadcrumb";
17202
17250
  }
17203
17251
  });
17204
- function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
17205
- const px = typeof size === "number" ? size : sizeMap3[size];
17206
- if (assetUrl?.url) {
17207
- return /* @__PURE__ */ jsxRuntime.jsx(
17208
- "img",
17209
- {
17210
- src: assetUrl.url,
17211
- alt: alt ?? assetUrl.category ?? "",
17212
- width: px,
17213
- height: px,
17214
- style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
17215
- className: cn("flex-shrink-0", className)
17216
- }
17217
- );
17218
- }
17219
- const I = typeof icon === "string" ? resolveIcon(icon) : icon;
17220
- return /* @__PURE__ */ jsxRuntime.jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
17221
- }
17222
- var sizeMap3;
17223
- var init_GameIcon = __esm({
17224
- "components/game/2d/atoms/GameIcon.tsx"() {
17225
- "use client";
17226
- init_cn();
17227
- init_Icon();
17228
- sizeMap3 = {
17229
- sm: 16,
17230
- md: 24,
17231
- lg: 32
17232
- };
17233
- GameIcon.displayName = "GameIcon";
17234
- }
17235
- });
17236
17252
  function BuilderBoard({
17237
17253
  entity,
17238
17254
  completeEvent = "PUZZLE_COMPLETE",
@@ -19046,6 +19062,7 @@ function GameCard({
19046
19062
  id,
19047
19063
  cost,
19048
19064
  art,
19065
+ frameAsset,
19049
19066
  attack,
19050
19067
  defense,
19051
19068
  name,
@@ -19063,16 +19080,19 @@ function GameCard({
19063
19080
  if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { cardId: id });
19064
19081
  }, [disabled, id, onClick, clickEvent, eventBus]);
19065
19082
  const artPx = artPxMap[size];
19083
+ const frameStyle = frameAsset?.url ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%", backgroundRepeat: "no-repeat" } : {};
19066
19084
  return /* @__PURE__ */ jsxRuntime.jsxs(
19067
- "button",
19085
+ exports.Button,
19068
19086
  {
19069
- type: "button",
19087
+ variant: "ghost",
19070
19088
  onClick: handleClick,
19071
19089
  disabled,
19072
19090
  title: name,
19091
+ style: frameStyle,
19073
19092
  className: cn(
19074
- "relative flex flex-col items-center rounded-interactive border-2",
19093
+ "relative flex flex-col items-center rounded-interactive",
19075
19094
  "bg-card/90 px-1.5 pt-1.5 pb-1 transition-all duration-150",
19095
+ frameAsset?.url ? "border-0" : "border-2",
19076
19096
  cardSizeMap[size],
19077
19097
  disabled ? "border-border opacity-50 cursor-not-allowed" : "border-accent hover:brightness-125 hover:-translate-y-1 cursor-pointer",
19078
19098
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background -translate-y-1",
@@ -19080,8 +19100,9 @@ function GameCard({
19080
19100
  ),
19081
19101
  children: [
19082
19102
  cost != null && /* @__PURE__ */ jsxRuntime.jsx(
19083
- "span",
19103
+ exports.Typography,
19084
19104
  {
19105
+ as: "span",
19085
19106
  className: cn(
19086
19107
  "absolute -top-2 -left-2 flex items-center justify-center",
19087
19108
  "min-w-[22px] h-[22px] rounded-full px-1",
@@ -19090,17 +19111,7 @@ function GameCard({
19090
19111
  children: cost
19091
19112
  }
19092
19113
  ),
19093
- /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex-1 flex items-center justify-center w-full", children: art ? /* @__PURE__ */ jsxRuntime.jsx(
19094
- "img",
19095
- {
19096
- src: art.url,
19097
- alt: name ?? id,
19098
- width: artPx,
19099
- height: artPx,
19100
- style: { imageRendering: "pixelated", objectFit: "contain" },
19101
- className: "flex-shrink-0"
19102
- }
19103
- ) : /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "rounded bg-muted/40", style: { width: artPx, height: artPx } }) }),
19114
+ /* @__PURE__ */ jsxRuntime.jsx(exports.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(exports.Box, { className: "rounded bg-muted/40", style: { width: artPx, height: artPx } }) }),
19104
19115
  name != null && /* @__PURE__ */ jsxRuntime.jsx(
19105
19116
  exports.Typography,
19106
19117
  {
@@ -19110,8 +19121,8 @@ function GameCard({
19110
19121
  }
19111
19122
  ),
19112
19123
  (attack != null || defense != null) && /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex w-full items-center justify-between px-0.5 text-[10px] font-bold leading-none", children: [
19113
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
19114
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
19124
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
19125
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
19115
19126
  ] })
19116
19127
  ]
19117
19128
  }
@@ -19124,7 +19135,9 @@ var init_GameCard = __esm({
19124
19135
  init_cn();
19125
19136
  init_useEventBus();
19126
19137
  init_Box();
19138
+ init_Button();
19127
19139
  init_Typography();
19140
+ init_GameIcon();
19128
19141
  cardSizeMap = {
19129
19142
  sm: "w-16 h-24",
19130
19143
  md: "w-20 h-28",
@@ -21535,11 +21548,11 @@ function ChoiceButton({
21535
21548
  }) {
21536
21549
  const eventBus = useEventBus();
21537
21550
  return /* @__PURE__ */ jsxRuntime.jsxs(
21538
- "button",
21551
+ exports.Button,
21539
21552
  {
21540
- type: "button",
21553
+ variant: "ghost",
21541
21554
  disabled,
21542
- onClick: (e) => {
21555
+ onClick: () => {
21543
21556
  if (action) eventBus.emit(`UI:${action}`, {});
21544
21557
  onClick?.();
21545
21558
  },
@@ -21552,8 +21565,9 @@ function ChoiceButton({
21552
21565
  ),
21553
21566
  children: [
21554
21567
  index !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(
21555
- "span",
21568
+ exports.Typography,
21556
21569
  {
21570
+ as: "span",
21557
21571
  className: cn(
21558
21572
  "flex-shrink-0 font-mono font-bold text-sm",
21559
21573
  selected ? "text-accent" : "text-muted-foreground"
@@ -21564,24 +21578,14 @@ function ChoiceButton({
21564
21578
  ]
21565
21579
  }
21566
21580
  ),
21567
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
21568
- "img",
21569
- {
21570
- src: assetUrl.url,
21571
- alt: "",
21572
- width: 16,
21573
- height: 16,
21574
- style: { imageRendering: "pixelated", objectFit: "contain" },
21575
- className: "flex-shrink-0"
21576
- }
21577
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
21581
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 16, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
21578
21582
  const I = resolveIcon(icon);
21579
21583
  return I ? /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-4 h-4" }) : null;
21580
21584
  })() : /* @__PURE__ */ (() => {
21581
21585
  const I = icon;
21582
21586
  return /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-4 h-4" });
21583
21587
  })() }) : null,
21584
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-snug", children: text })
21588
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-sm leading-snug", children: text })
21585
21589
  ]
21586
21590
  }
21587
21591
  );
@@ -21591,6 +21595,10 @@ var init_ChoiceButton = __esm({
21591
21595
  init_cn();
21592
21596
  init_Icon();
21593
21597
  init_useEventBus();
21598
+ init_Button();
21599
+ init_Box();
21600
+ init_Typography();
21601
+ init_GameIcon();
21594
21602
  ChoiceButton.displayName = "ChoiceButton";
21595
21603
  }
21596
21604
  });
@@ -22268,7 +22276,7 @@ function ComboCounter({
22268
22276
  const sizes = sizeMap4[size];
22269
22277
  if (combo <= 0) return null;
22270
22278
  return /* @__PURE__ */ jsxRuntime.jsxs(
22271
- "div",
22279
+ exports.Box,
22272
22280
  {
22273
22281
  className: cn(
22274
22282
  "inline-flex flex-col items-center justify-center",
@@ -22278,24 +22286,14 @@ function ComboCounter({
22278
22286
  className
22279
22287
  ),
22280
22288
  children: [
22281
- assetUrl && /* @__PURE__ */ jsxRuntime.jsx(
22282
- "img",
22283
- {
22284
- src: assetUrl.url,
22285
- alt: "combo",
22286
- width: 24,
22287
- height: 24,
22288
- style: { imageRendering: "pixelated", objectFit: "contain" },
22289
- className: "flex-shrink-0 mb-0.5"
22290
- }
22291
- ),
22292
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
22293
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
22294
- multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
22289
+ assetUrl && /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0 mb-0.5" }),
22290
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
22291
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
22292
+ multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { as: "span", className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
22295
22293
  "x",
22296
22294
  multiplier.toFixed(1)
22297
22295
  ] }),
22298
- streak != null && streak > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
22296
+ streak != null && streak > 0 && /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { as: "span", className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
22299
22297
  streak,
22300
22298
  " streak"
22301
22299
  ] })
@@ -22307,6 +22305,9 @@ var DEFAULT_ASSET_URL2, sizeMap4;
22307
22305
  var init_ComboCounter = __esm({
22308
22306
  "components/game/2d/atoms/ComboCounter.tsx"() {
22309
22307
  init_cn();
22308
+ init_Box();
22309
+ init_Typography();
22310
+ init_GameIcon();
22310
22311
  DEFAULT_ASSET_URL2 = {
22311
22312
  url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
22312
22313
  role: "effect",
@@ -22556,9 +22557,9 @@ function ControlButton({
22556
22557
  [isPressed, releaseEvent, eventBus, onRelease]
22557
22558
  );
22558
22559
  return /* @__PURE__ */ jsxRuntime.jsx(
22559
- "button",
22560
+ exports.Button,
22560
22561
  {
22561
- type: "button",
22562
+ variant,
22562
22563
  disabled,
22563
22564
  onPointerDown: handlePointerDown,
22564
22565
  onPointerUp: handlePointerUp,
@@ -22576,23 +22577,13 @@ function ControlButton({
22576
22577
  disabled && "opacity-50 cursor-not-allowed",
22577
22578
  className
22578
22579
  ),
22579
- children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
22580
- "img",
22581
- {
22582
- src: assetUrl.url,
22583
- alt: "",
22584
- width: 24,
22585
- height: 24,
22586
- style: { imageRendering: "pixelated", objectFit: "contain" },
22587
- className: "flex-shrink-0"
22588
- }
22589
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
22580
+ children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
22590
22581
  const I = resolveIcon(icon);
22591
22582
  return I ? /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-6 h-6" }) : null;
22592
22583
  })() : icon : /* @__PURE__ */ (() => {
22593
22584
  const I = icon;
22594
22585
  return /* @__PURE__ */ jsxRuntime.jsx(I, { className: "w-6 h-6" });
22595
- })() }) : label ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }) : null
22586
+ })() }) : label ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", children: label }) : null
22596
22587
  }
22597
22588
  );
22598
22589
  }
@@ -22603,6 +22594,10 @@ var init_ControlButton = __esm({
22603
22594
  init_cn();
22604
22595
  init_useEventBus();
22605
22596
  init_Icon();
22597
+ init_Button();
22598
+ init_Box();
22599
+ init_Typography();
22600
+ init_GameIcon();
22606
22601
  sizeMap5 = {
22607
22602
  sm: "w-10 h-10 text-sm",
22608
22603
  md: "w-14 h-14 text-base",
@@ -22687,22 +22682,22 @@ function ControlGrid({
22687
22682
  },
22688
22683
  d
22689
22684
  );
22690
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
22691
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
22685
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
22686
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, {}),
22692
22687
  dir("up"),
22693
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
22688
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, {}),
22694
22689
  dir("left"),
22695
- /* @__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" }) }),
22690
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-6 h-6 rounded-interactive bg-muted border-2 border-muted-foreground" }) }),
22696
22691
  dir("right"),
22697
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
22692
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, {}),
22698
22693
  dir("down"),
22699
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
22694
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, {})
22700
22695
  ] });
22701
22696
  }
22702
22697
  if (layout === "diamond" && buttons.length === 4) {
22703
22698
  const [top, right, bottom, left] = buttons;
22704
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(layoutClass.diamond, className), children: [
22705
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
22699
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: cn(layoutClass.diamond, className), children: [
22700
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, {}),
22706
22701
  /* @__PURE__ */ jsxRuntime.jsx(
22707
22702
  ControlButton,
22708
22703
  {
@@ -22717,7 +22712,7 @@ function ControlGrid({
22717
22712
  disabled
22718
22713
  }
22719
22714
  ),
22720
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
22715
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, {}),
22721
22716
  /* @__PURE__ */ jsxRuntime.jsx(
22722
22717
  ControlButton,
22723
22718
  {
@@ -22732,7 +22727,7 @@ function ControlGrid({
22732
22727
  disabled
22733
22728
  }
22734
22729
  ),
22735
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
22730
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, {}),
22736
22731
  /* @__PURE__ */ jsxRuntime.jsx(
22737
22732
  ControlButton,
22738
22733
  {
@@ -22747,7 +22742,7 @@ function ControlGrid({
22747
22742
  disabled
22748
22743
  }
22749
22744
  ),
22750
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
22745
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, {}),
22751
22746
  /* @__PURE__ */ jsxRuntime.jsx(
22752
22747
  ControlButton,
22753
22748
  {
@@ -22762,10 +22757,10 @@ function ControlGrid({
22762
22757
  disabled
22763
22758
  }
22764
22759
  ),
22765
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
22760
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, {})
22766
22761
  ] });
22767
22762
  }
22768
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsxRuntime.jsx(
22763
+ return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsxRuntime.jsx(
22769
22764
  ControlButton,
22770
22765
  {
22771
22766
  icon: button.icon,
@@ -22787,6 +22782,7 @@ var init_ControlGrid = __esm({
22787
22782
  "use client";
22788
22783
  init_cn();
22789
22784
  init_useEventBus();
22785
+ init_Box();
22790
22786
  init_ControlButton();
22791
22787
  sizeKey = { sm: "sm", md: "md", lg: "lg" };
22792
22788
  layoutClass = {
@@ -23051,8 +23047,9 @@ function DamageNumber({
23051
23047
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
23052
23048
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: floatKeyframes }),
23053
23049
  /* @__PURE__ */ jsxRuntime.jsxs(
23054
- "span",
23050
+ exports.Typography,
23055
23051
  {
23052
+ as: "span",
23056
23053
  className: cn(
23057
23054
  "inline-flex items-center gap-0.5 font-mono select-none pointer-events-none",
23058
23055
  sizeMap6[size],
@@ -23061,17 +23058,7 @@ function DamageNumber({
23061
23058
  ),
23062
23059
  style: { animation: "damageFloat 1s ease-out forwards" },
23063
23060
  children: [
23064
- assetUrl && /* @__PURE__ */ jsxRuntime.jsx(
23065
- "img",
23066
- {
23067
- src: assetUrl.url,
23068
- alt: "",
23069
- width: 14,
23070
- height: 14,
23071
- style: { imageRendering: "pixelated", objectFit: "contain" },
23072
- className: "flex-shrink-0"
23073
- }
23074
- ),
23061
+ assetUrl && /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 14, className: "flex-shrink-0" }),
23075
23062
  displayText
23076
23063
  ]
23077
23064
  }
@@ -23082,6 +23069,8 @@ var sizeMap6, typeStyles, floatKeyframes, DEFAULT_ASSET_URL4;
23082
23069
  var init_DamageNumber = __esm({
23083
23070
  "components/game/2d/atoms/DamageNumber.tsx"() {
23084
23071
  init_cn();
23072
+ init_Typography();
23073
+ init_GameIcon();
23085
23074
  sizeMap6 = {
23086
23075
  sm: "text-sm",
23087
23076
  md: "text-lg",
@@ -29443,7 +29432,7 @@ function ScoreDisplay({
29443
29432
  const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
29444
29433
  const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
29445
29434
  return /* @__PURE__ */ jsxRuntime.jsxs(
29446
- "div",
29435
+ exports.Box,
29447
29436
  {
29448
29437
  className: cn(
29449
29438
  "flex items-center gap-2 font-bold",
@@ -29451,19 +29440,9 @@ function ScoreDisplay({
29451
29440
  className
29452
29441
  ),
29453
29442
  children: [
29454
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
29455
- "img",
29456
- {
29457
- src: assetUrl.url,
29458
- alt: "",
29459
- width: 20,
29460
- height: 20,
29461
- style: { imageRendering: "pixelated", objectFit: "contain" },
29462
- className: "flex-shrink-0"
29463
- }
29464
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) }) : null,
29465
- label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: label }),
29466
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums", children: formattedValue })
29443
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 20, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) }) : null,
29444
+ label && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-muted-foreground", children: label }),
29445
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "tabular-nums", children: formattedValue })
29467
29446
  ]
29468
29447
  }
29469
29448
  );
@@ -29473,6 +29452,9 @@ var init_ScoreDisplay = __esm({
29473
29452
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
29474
29453
  init_cn();
29475
29454
  init_Icon();
29455
+ init_Box();
29456
+ init_Typography();
29457
+ init_GameIcon();
29476
29458
  sizeMap8 = {
29477
29459
  sm: "text-sm",
29478
29460
  md: "text-lg",
@@ -29533,12 +29515,12 @@ function Sprite({
29533
29515
  onClick?.();
29534
29516
  };
29535
29517
  return /* @__PURE__ */ jsxRuntime.jsx(
29536
- "div",
29518
+ exports.Box,
29537
29519
  {
29520
+ position: "absolute",
29538
29521
  className,
29539
29522
  onClick: action || onClick ? handleClick : void 0,
29540
29523
  style: {
29541
- position: "absolute",
29542
29524
  width: frameWidth,
29543
29525
  height: frameHeight,
29544
29526
  backgroundImage: `url(${spritesheet.url})`,
@@ -29594,6 +29576,7 @@ var init_Sprite = __esm({
29594
29576
  "components/game/2d/atoms/Sprite.tsx"() {
29595
29577
  "use client";
29596
29578
  init_useEventBus();
29579
+ init_Box();
29597
29580
  init_spriteAnimation();
29598
29581
  DEFAULT_SPRITESHEET = {
29599
29582
  url: "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
@@ -29630,17 +29613,7 @@ function StateIndicator({
29630
29613
  className
29631
29614
  ),
29632
29615
  children: [
29633
- /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
29634
- "img",
29635
- {
29636
- src: assetUrl.url,
29637
- alt: displayLabel,
29638
- width: 16,
29639
- height: 16,
29640
- style: { imageRendering: "pixelated", objectFit: "contain" },
29641
- className: "flex-shrink-0"
29642
- }
29643
- ) : typeof config.icon === "string" ? /^[a-zA-Z0-9-]+$/.test(config.icon) ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: config.icon }) : config.icon : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: config.icon }) }),
29616
+ /* @__PURE__ */ jsxRuntime.jsx(exports.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(exports.Icon, { name: config.icon }) : config.icon : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: config.icon }) }),
29644
29617
  /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", children: displayLabel })
29645
29618
  ]
29646
29619
  }
@@ -29652,6 +29625,7 @@ var init_StateIndicator = __esm({
29652
29625
  init_Box();
29653
29626
  init_Icon();
29654
29627
  init_cn();
29628
+ init_GameIcon();
29655
29629
  DEFAULT_ASSET_URL6 = {
29656
29630
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
29657
29631
  role: "ui",
@@ -29705,7 +29679,7 @@ function TimerDisplay({
29705
29679
  }) {
29706
29680
  const isLow = lowThreshold != null && seconds <= lowThreshold && seconds > 0;
29707
29681
  return /* @__PURE__ */ jsxRuntime.jsxs(
29708
- "div",
29682
+ exports.Box,
29709
29683
  {
29710
29684
  className: cn(
29711
29685
  "inline-flex items-center gap-1 justify-center rounded-container",
@@ -29717,7 +29691,7 @@ function TimerDisplay({
29717
29691
  className
29718
29692
  ),
29719
29693
  children: [
29720
- iconAsset && /* @__PURE__ */ jsxRuntime.jsx("img", { src: iconAsset.url, alt: "", className: "w-4 h-4 object-contain flex-shrink-0" }),
29694
+ iconAsset && /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl: iconAsset, icon: "image", size: 16, className: "w-4 h-4 object-contain flex-shrink-0" }),
29721
29695
  formatTime(seconds, format)
29722
29696
  ]
29723
29697
  }
@@ -29727,6 +29701,8 @@ var sizeMap9;
29727
29701
  var init_TimerDisplay = __esm({
29728
29702
  "components/game/2d/atoms/TimerDisplay.tsx"() {
29729
29703
  init_cn();
29704
+ init_Box();
29705
+ init_GameIcon();
29730
29706
  sizeMap9 = {
29731
29707
  sm: "text-sm px-2 py-0.5",
29732
29708
  md: "text-lg px-3 py-1",
@@ -29747,7 +29723,7 @@ function ResourceCounter({
29747
29723
  }) {
29748
29724
  const sizes = sizeMap10[size];
29749
29725
  return /* @__PURE__ */ jsxRuntime.jsxs(
29750
- "div",
29726
+ exports.Box,
29751
29727
  {
29752
29728
  className: cn(
29753
29729
  "inline-flex items-center rounded-container",
@@ -29756,21 +29732,11 @@ function ResourceCounter({
29756
29732
  className
29757
29733
  ),
29758
29734
  children: [
29759
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
29760
- "img",
29761
- {
29762
- src: assetUrl.url,
29763
- alt: label,
29764
- width: sizes.img,
29765
- height: sizes.img,
29766
- style: { imageRendering: "pixelated", objectFit: "contain" },
29767
- className: "flex-shrink-0"
29768
- }
29769
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) }) : null,
29770
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: label }),
29771
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
29735
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: sizes.img, alt: label, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) }) : null,
29736
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-muted-foreground", children: label }),
29737
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { as: "span", className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
29772
29738
  value,
29773
- max != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
29739
+ max != null && /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { as: "span", className: "text-muted-foreground", children: [
29774
29740
  "/",
29775
29741
  max
29776
29742
  ] })
@@ -29784,6 +29750,9 @@ var init_ResourceCounter = __esm({
29784
29750
  "components/game/2d/atoms/ResourceCounter.tsx"() {
29785
29751
  init_cn();
29786
29752
  init_Icon();
29753
+ init_Box();
29754
+ init_Typography();
29755
+ init_GameIcon();
29787
29756
  colorTokenClasses2 = {
29788
29757
  primary: "text-primary",
29789
29758
  secondary: "text-secondary",
@@ -29822,9 +29791,9 @@ function ItemSlot({
29822
29791
  const isClickable = onClick != null || action != null;
29823
29792
  const px = assetSizeMap[size];
29824
29793
  return /* @__PURE__ */ jsxRuntime.jsx(
29825
- "button",
29794
+ exports.Button,
29826
29795
  {
29827
- type: "button",
29796
+ variant: "ghost",
29828
29797
  onClick: () => {
29829
29798
  if (action) eventBus.emit(`UI:${action}`, {});
29830
29799
  onClick?.();
@@ -29843,21 +29812,12 @@ function ItemSlot({
29843
29812
  !isClickable && "cursor-default",
29844
29813
  className
29845
29814
  ),
29846
- children: empty ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
29847
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
29848
- "img",
29849
- {
29850
- src: assetUrl?.url,
29851
- alt: label,
29852
- width: px,
29853
- height: px,
29854
- style: { imageRendering: "pixelated", objectFit: "contain" },
29855
- className: "flex-shrink-0"
29856
- }
29857
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) }) : null,
29815
+ children: empty ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
29816
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: px, alt: label, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) }) : null,
29858
29817
  quantity != null && quantity > 1 && /* @__PURE__ */ jsxRuntime.jsx(
29859
- "span",
29818
+ exports.Typography,
29860
29819
  {
29820
+ as: "span",
29861
29821
  className: cn(
29862
29822
  "absolute -bottom-1 -right-1 flex items-center justify-center",
29863
29823
  "min-w-[18px] h-[18px] rounded-full px-1",
@@ -29877,6 +29837,10 @@ var init_ItemSlot = __esm({
29877
29837
  init_cn();
29878
29838
  init_Icon();
29879
29839
  init_useEventBus();
29840
+ init_Button();
29841
+ init_Box();
29842
+ init_Typography();
29843
+ init_GameIcon();
29880
29844
  sizeMap11 = {
29881
29845
  sm: "w-10 h-10 text-lg",
29882
29846
  md: "w-14 h-14 text-2xl",
@@ -29920,7 +29884,7 @@ function TurnIndicator({
29920
29884
  }) {
29921
29885
  const sizes = sizeMap12[size];
29922
29886
  return /* @__PURE__ */ jsxRuntime.jsxs(
29923
- "div",
29887
+ exports.Box,
29924
29888
  {
29925
29889
  className: cn(
29926
29890
  "inline-flex items-center rounded-container",
@@ -29929,32 +29893,22 @@ function TurnIndicator({
29929
29893
  className
29930
29894
  ),
29931
29895
  children: [
29932
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold tabular-nums", children: [
29896
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { as: "span", className: "font-bold tabular-nums", children: [
29933
29897
  "Turn ",
29934
29898
  currentTurn,
29935
- maxTurns != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
29899
+ maxTurns != null && /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { as: "span", className: "text-muted-foreground", children: [
29936
29900
  "/",
29937
29901
  maxTurns
29938
29902
  ] })
29939
29903
  ] }),
29940
29904
  phase && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
29941
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "|" }),
29942
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: phase })
29905
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
29906
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-muted-foreground", children: phase })
29943
29907
  ] }),
29944
29908
  activeTeam && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
29945
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "|" }),
29946
- assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
29947
- "img",
29948
- {
29949
- src: assetUrl.url,
29950
- alt: "",
29951
- width: 12,
29952
- height: 12,
29953
- style: { imageRendering: "pixelated", objectFit: "contain" },
29954
- className: "flex-shrink-0"
29955
- }
29956
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("rounded-full bg-success/20", sizes.dot) }),
29957
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-success", children: activeTeam })
29909
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
29910
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl, icon: "image", size: 12, className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", className: cn("rounded-full bg-success/20", sizes.dot) }),
29911
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-success", children: activeTeam })
29958
29912
  ] })
29959
29913
  ]
29960
29914
  }
@@ -29964,6 +29918,9 @@ var sizeMap12, DEFAULT_ASSET_URL9;
29964
29918
  var init_TurnIndicator = __esm({
29965
29919
  "components/game/2d/atoms/TurnIndicator.tsx"() {
29966
29920
  init_cn();
29921
+ init_Box();
29922
+ init_Typography();
29923
+ init_GameIcon();
29967
29924
  sizeMap12 = {
29968
29925
  sm: { wrapper: "text-xs gap-1.5 px-2 py-0.5", dot: "w-1.5 h-1.5" },
29969
29926
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
@@ -29987,53 +29944,47 @@ function WaypointMarker({
29987
29944
  className
29988
29945
  }) {
29989
29946
  const sizes = sizeMap13[size];
29990
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col items-center", className), children: [
29991
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center", children: [
29947
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: cn("flex flex-col items-center", className), children: [
29948
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "relative flex items-center justify-center", children: [
29992
29949
  active && /* @__PURE__ */ jsxRuntime.jsx(
29993
- "div",
29950
+ exports.Box,
29994
29951
  {
29952
+ position: "absolute",
29995
29953
  className: cn(
29996
- "absolute rounded-full border-2 border-info animate-ping opacity-50",
29954
+ "rounded-full border-2 border-info animate-ping opacity-50",
29997
29955
  sizes.ring
29998
29956
  )
29999
29957
  }
30000
29958
  ),
30001
29959
  active && /* @__PURE__ */ jsxRuntime.jsx(
30002
- "div",
29960
+ exports.Box,
30003
29961
  {
29962
+ position: "absolute",
30004
29963
  className: cn(
30005
- "absolute rounded-full border-2 border-info",
29964
+ "rounded-full border-2 border-info",
30006
29965
  sizes.ring
30007
29966
  )
30008
29967
  }
30009
29968
  ),
30010
29969
  /* @__PURE__ */ jsxRuntime.jsx(
30011
- "div",
29970
+ exports.Box,
30012
29971
  {
29972
+ position: "relative",
30013
29973
  className: cn(
30014
- "relative flex items-center justify-center rounded-full transition-all duration-200",
29974
+ "flex items-center justify-center rounded-full transition-all duration-200",
30015
29975
  sizes.dot,
30016
29976
  completed && "bg-success text-foreground",
30017
29977
  active && !completed && "bg-info text-foreground",
30018
29978
  !active && !completed && "bg-muted"
30019
29979
  ),
30020
- children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
30021
- "img",
30022
- {
30023
- src: assetUrl.url,
30024
- alt: label,
30025
- width: sizes.img,
30026
- height: sizes.img,
30027
- style: { imageRendering: "pixelated", objectFit: "contain" },
30028
- className: "flex-shrink-0"
30029
- }
30030
- ) : icon ? typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) : null
29980
+ 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(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) : null
30031
29981
  }
30032
29982
  )
30033
29983
  ] }),
30034
29984
  label && /* @__PURE__ */ jsxRuntime.jsx(
30035
- "span",
29985
+ exports.Typography,
30036
29986
  {
29987
+ as: "span",
30037
29988
  className: cn(
30038
29989
  "text-center whitespace-nowrap",
30039
29990
  sizes.label,
@@ -30049,6 +30000,9 @@ var init_WaypointMarker = __esm({
30049
30000
  "components/game/2d/atoms/WaypointMarker.tsx"() {
30050
30001
  init_cn();
30051
30002
  init_Icon();
30003
+ init_Box();
30004
+ init_Typography();
30005
+ init_GameIcon();
30052
30006
  DEFAULT_ASSET_URL10 = {
30053
30007
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
30054
30008
  role: "ui",
@@ -30080,31 +30034,23 @@ function StatusEffect({
30080
30034
  className
30081
30035
  }) {
30082
30036
  const sizes = sizeMap14[size];
30083
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative inline-flex flex-col items-center", className), children: [
30037
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { position: "relative", className: cn("inline-flex flex-col items-center", className), children: [
30084
30038
  /* @__PURE__ */ jsxRuntime.jsxs(
30085
- "div",
30039
+ exports.Box,
30086
30040
  {
30041
+ position: "relative",
30087
30042
  className: cn(
30088
- "relative flex items-center justify-center rounded-interactive border-2",
30043
+ "flex items-center justify-center rounded-interactive border-2",
30089
30044
  sizes.container,
30090
30045
  variantStyles8[variant]
30091
30046
  ),
30092
30047
  title: label,
30093
30048
  children: [
30094
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
30095
- "img",
30096
- {
30097
- src: assetUrl.url,
30098
- alt: label,
30099
- width: sizes.img,
30100
- height: sizes.img,
30101
- style: { imageRendering: "pixelated", objectFit: "contain" },
30102
- className: "flex-shrink-0"
30103
- }
30104
- ) : icon != null && typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon, size: "sm" }) : null }),
30049
+ /* @__PURE__ */ jsxRuntime.jsx(exports.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(exports.Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon, size: "sm" }) : null }),
30105
30050
  duration !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
30106
- "span",
30051
+ exports.Typography,
30107
30052
  {
30053
+ as: "span",
30108
30054
  className: cn(
30109
30055
  "absolute bottom-0 left-0 right-0 text-center font-mono font-bold text-foreground bg-background/60 leading-tight",
30110
30056
  sizes.timer
@@ -30116,8 +30062,9 @@ function StatusEffect({
30116
30062
  }
30117
30063
  ),
30118
30064
  stacks !== void 0 && stacks > 1 && /* @__PURE__ */ jsxRuntime.jsx(
30119
- "span",
30065
+ exports.Typography,
30120
30066
  {
30067
+ as: "span",
30121
30068
  className: cn(
30122
30069
  "absolute flex items-center justify-center rounded-full bg-card text-foreground font-bold leading-none",
30123
30070
  sizes.badge
@@ -30125,7 +30072,7 @@ function StatusEffect({
30125
30072
  children: stacks
30126
30073
  }
30127
30074
  ),
30128
- label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
30075
+ label && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
30129
30076
  ] });
30130
30077
  }
30131
30078
  var DEFAULT_ASSET_URL11, sizeMap14, variantStyles8;
@@ -30133,6 +30080,9 @@ var init_StatusEffect = __esm({
30133
30080
  "components/game/2d/atoms/StatusEffect.tsx"() {
30134
30081
  init_cn();
30135
30082
  init_Icon();
30083
+ init_Box();
30084
+ init_Typography();
30085
+ init_GameIcon();
30136
30086
  DEFAULT_ASSET_URL11 = {
30137
30087
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
30138
30088
  role: "ui",
@@ -30159,7 +30109,7 @@ function DialogueBubble({
30159
30109
  className
30160
30110
  }) {
30161
30111
  return /* @__PURE__ */ jsxRuntime.jsxs(
30162
- "div",
30112
+ exports.Box,
30163
30113
  {
30164
30114
  className: cn(
30165
30115
  "flex items-start gap-3 rounded-container bg-background/80 backdrop-blur-sm px-4 py-3 border border-border/10",
@@ -30167,17 +30117,10 @@ function DialogueBubble({
30167
30117
  className
30168
30118
  ),
30169
30119
  children: [
30170
- 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(
30171
- "img",
30172
- {
30173
- src: portrait?.url,
30174
- alt: speaker ?? "speaker",
30175
- className: "w-full h-full object-cover"
30176
- }
30177
- ) }),
30178
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
30179
- speaker && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold text-warning", children: speaker }),
30180
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-foreground leading-relaxed", children: text })
30120
+ portrait && /* @__PURE__ */ jsxRuntime.jsx(exports.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" }) }),
30121
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex flex-col gap-1 min-w-0", children: [
30122
+ speaker && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-sm font-bold text-warning", children: speaker }),
30123
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-sm text-foreground leading-relaxed", children: text })
30181
30124
  ] })
30182
30125
  ]
30183
30126
  }
@@ -30187,6 +30130,9 @@ var DEFAULT_PORTRAIT;
30187
30130
  var init_DialogueBubble = __esm({
30188
30131
  "components/game/2d/atoms/DialogueBubble.tsx"() {
30189
30132
  init_cn();
30133
+ init_Box();
30134
+ init_Typography();
30135
+ init_GameIcon();
30190
30136
  DEFAULT_PORTRAIT = {
30191
30137
  url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
30192
30138
  role: "effect",
@@ -30213,7 +30159,7 @@ function StatBadge({
30213
30159
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
30214
30160
  const resolvedAsset = iconUrl ?? assetUrl;
30215
30161
  return /* @__PURE__ */ jsxRuntime.jsxs(
30216
- "div",
30162
+ exports.Box,
30217
30163
  {
30218
30164
  className: cn(
30219
30165
  "inline-flex items-center gap-2 rounded-container border backdrop-blur-sm",
@@ -30222,18 +30168,8 @@ function StatBadge({
30222
30168
  className
30223
30169
  ),
30224
30170
  children: [
30225
- resolvedAsset ? /* @__PURE__ */ jsxRuntime.jsx(
30226
- "img",
30227
- {
30228
- src: resolvedAsset.url,
30229
- alt: "",
30230
- width: 16,
30231
- height: 16,
30232
- style: { imageRendering: "pixelated", objectFit: "contain" },
30233
- className: "flex-shrink-0"
30234
- }
30235
- ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 text-lg", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon, className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon, className: "w-4 h-4" }) }) : null,
30236
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-medium", children: label }),
30171
+ resolvedAsset ? /* @__PURE__ */ jsxRuntime.jsx(GameIcon, { assetUrl: resolvedAsset, icon: "image", size: 16, className: "flex-shrink-0" }) : icon ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", className: "flex-shrink-0 text-lg", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon, className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon, className: "w-4 h-4" }) }) : null,
30172
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "text-muted-foreground font-medium", children: label }),
30237
30173
  format === "hearts" && max && /* @__PURE__ */ jsxRuntime.jsx(
30238
30174
  HealthBar,
30239
30175
  {
@@ -30259,7 +30195,7 @@ function StatBadge({
30259
30195
  size: size === "lg" ? "md" : "sm"
30260
30196
  }
30261
30197
  ),
30262
- format === "text" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold text-foreground", children: value })
30198
+ format === "text" && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", className: "font-bold text-foreground", children: value })
30263
30199
  ]
30264
30200
  }
30265
30201
  );
@@ -30269,6 +30205,9 @@ var init_StatBadge = __esm({
30269
30205
  "components/game/2d/molecules/StatBadge.tsx"() {
30270
30206
  init_cn();
30271
30207
  init_Icon();
30208
+ init_Box();
30209
+ init_Typography();
30210
+ init_GameIcon();
30272
30211
  init_HealthBar();
30273
30212
  init_ScoreDisplay();
30274
30213
  sizeMap15 = {
@@ -30446,9 +30385,9 @@ function GameHud({
30446
30385
  if (position === "corners") {
30447
30386
  const leftStats = stats.slice(0, Math.ceil(stats.length / 2));
30448
30387
  const rightStats = stats.slice(Math.ceil(stats.length / 2));
30449
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", positionMap[position], className), children: [
30450
- /* @__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)) }),
30451
- /* @__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)) })
30388
+ return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { position: "relative", className: cn(positionMap[position], className), children: [
30389
+ /* @__PURE__ */ jsxRuntime.jsx(exports.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)) }),
30390
+ /* @__PURE__ */ jsxRuntime.jsx(exports.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)) })
30452
30391
  ] });
30453
30392
  }
30454
30393
  if (position === "top" || position === "bottom") {
@@ -30457,7 +30396,7 @@ function GameHud({
30457
30396
  const rightStats = stats.slice(mid);
30458
30397
  const isTop = position === "top";
30459
30398
  return /* @__PURE__ */ jsxRuntime.jsxs(
30460
- "div",
30399
+ exports.Box,
30461
30400
  {
30462
30401
  className: cn(
30463
30402
  "flex items-center justify-between w-full",
@@ -30467,17 +30406,18 @@ function GameHud({
30467
30406
  className
30468
30407
  ),
30469
30408
  children: [
30470
- /* @__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)) }),
30471
- 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)) })
30409
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) }),
30410
+ rightStats.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex items-center gap-3 flex-shrink-0", children: rightStats.map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatBadge, { ...stat, size }, i)) })
30472
30411
  ]
30473
30412
  }
30474
30413
  );
30475
30414
  }
30476
30415
  return /* @__PURE__ */ jsxRuntime.jsx(
30477
- "div",
30416
+ exports.Box,
30478
30417
  {
30418
+ position: "relative",
30479
30419
  className: cn(
30480
- "relative z-10 flex items-center gap-4 px-4 py-2",
30420
+ "z-10 flex items-center gap-4 px-4 py-2",
30481
30421
  transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
30482
30422
  className
30483
30423
  ),
@@ -30489,6 +30429,7 @@ var positionMap, DEFAULT_HUD_STATS;
30489
30429
  var init_GameHud = __esm({
30490
30430
  "components/game/2d/molecules/GameHud.tsx"() {
30491
30431
  init_cn();
30432
+ init_Box();
30492
30433
  init_StatBadge();
30493
30434
  positionMap = {
30494
30435
  corners: "inset-0 pointer-events-none"
@@ -30529,7 +30470,7 @@ function GameMenu({
30529
30470
  [eventBus, onSelect]
30530
30471
  );
30531
30472
  return /* @__PURE__ */ jsxRuntime.jsxs(
30532
- "div",
30473
+ exports.Box,
30533
30474
  {
30534
30475
  className: cn(
30535
30476
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
@@ -30539,18 +30480,12 @@ function GameMenu({
30539
30480
  background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
30540
30481
  },
30541
30482
  children: [
30542
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center mb-12 animate-fade-in", children: [
30543
- logo && /* @__PURE__ */ jsxRuntime.jsx(
30544
- "img",
30545
- {
30546
- src: logo.url,
30547
- alt: title,
30548
- className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl"
30549
- }
30550
- ),
30483
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "text-center mb-12 animate-fade-in", children: [
30484
+ 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" }),
30551
30485
  /* @__PURE__ */ jsxRuntime.jsx(
30552
- "h1",
30486
+ exports.Typography,
30553
30487
  {
30488
+ variant: "h1",
30554
30489
  className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
30555
30490
  style: {
30556
30491
  textShadow: "0 4px 12px rgba(0,0,0,0.5)"
@@ -30558,9 +30493,9 @@ function GameMenu({
30558
30493
  children: title
30559
30494
  }
30560
30495
  ),
30561
- subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
30496
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
30562
30497
  ] }),
30563
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
30498
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
30564
30499
  ChoiceButton,
30565
30500
  {
30566
30501
  text: option.label,
@@ -30571,9 +30506,9 @@ function GameMenu({
30571
30506
  },
30572
30507
  index
30573
30508
  )) }),
30574
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 pointer-events-none overflow-hidden", children: [
30575
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
30576
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
30509
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
30510
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
30511
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
30577
30512
  ] })
30578
30513
  ]
30579
30514
  }
@@ -30585,6 +30520,9 @@ var init_GameMenu = __esm({
30585
30520
  "use client";
30586
30521
  init_cn();
30587
30522
  init_useEventBus();
30523
+ init_Box();
30524
+ init_Typography();
30525
+ init_GameIcon();
30588
30526
  init_ChoiceButton();
30589
30527
  DEFAULT_MENU_OPTIONS = [
30590
30528
  { label: "New Game", event: "NEW_GAME", variant: "primary" },
@@ -31023,7 +30961,7 @@ function GameAudioToggle({
31023
30961
  onClick: handleToggle,
31024
30962
  className: cn("text-lg leading-none px-2", className),
31025
30963
  "aria-pressed": muted,
31026
- 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}"
30964
+ 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}"
31027
30965
  }
31028
30966
  );
31029
30967
  }
@@ -31033,6 +30971,7 @@ var init_GameAudioToggle = __esm({
31033
30971
  init_atoms();
31034
30972
  init_cn();
31035
30973
  init_GameAudioProvider();
30974
+ init_GameIcon();
31036
30975
  GameAudioToggle.displayName = "GameAudioToggle";
31037
30976
  }
31038
30977
  });