@almadar/ui 5.79.2 → 5.81.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/avl/index.cjs +1963 -1948
  2. package/dist/avl/index.css +3 -3
  3. package/dist/avl/index.js +754 -739
  4. package/dist/components/core/atoms/FlipContainer.d.ts +1 -1
  5. package/dist/components/core/molecules/Card.d.ts +1 -1
  6. package/dist/components/core/molecules/DataGrid.d.ts +1 -1
  7. package/dist/components/core/molecules/DataList.d.ts +1 -1
  8. package/dist/components/core/molecules/DocPagination.d.ts +1 -8
  9. package/dist/components/core/molecules/DocSearch.d.ts +1 -8
  10. package/dist/components/core/molecules/FlipCard.d.ts +1 -1
  11. package/dist/components/core/molecules/MapView.d.ts +1 -18
  12. package/dist/components/core/molecules/SortableList.d.ts +1 -1
  13. package/dist/components/core/molecules/TableView.d.ts +1 -1
  14. package/dist/components/core/molecules/WizardContainer.d.ts +7 -1
  15. package/dist/components/core/organisms/DataTable.d.ts +1 -1
  16. package/dist/components/core/organisms/DrawerSlot.d.ts +2 -0
  17. package/dist/components/core/organisms/ModalSlot.d.ts +2 -0
  18. package/dist/components/core/organisms/ToastSlot.d.ts +2 -0
  19. package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +1 -10
  20. package/dist/components/core/organisms/debug/tabs/EntitiesTab.d.ts +1 -2
  21. package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +1 -2
  22. package/dist/components/core/organisms/debug/tabs/EventFlowTab.d.ts +1 -6
  23. package/dist/components/core/organisms/debug/tabs/GuardsPanel.d.ts +1 -6
  24. package/dist/components/core/organisms/debug/tabs/ServerBridgeTab.d.ts +1 -12
  25. package/dist/components/core/organisms/debug/tabs/TicksTab.d.ts +1 -2
  26. package/dist/components/core/organisms/debug/tabs/TraitsTab.d.ts +1 -2
  27. package/dist/components/core/organisms/debug/tabs/TransitionTimeline.d.ts +1 -11
  28. package/dist/components/core/organisms/debug/tabs/VerificationTab.d.ts +1 -8
  29. package/dist/components/core/templates/CounterTemplate.d.ts +7 -0
  30. package/dist/components/game/2d/atoms/ActionButton.d.ts +4 -3
  31. package/dist/components/game/2d/atoms/ChoiceButton.d.ts +4 -3
  32. package/dist/components/game/2d/atoms/ComboCounter.d.ts +1 -2
  33. package/dist/components/game/2d/atoms/ControlButton.d.ts +1 -2
  34. package/dist/components/game/2d/atoms/DamageNumber.d.ts +1 -2
  35. package/dist/components/game/2d/atoms/DialogueBubble.d.ts +1 -2
  36. package/dist/components/game/2d/atoms/GameAudioToggle.d.ts +6 -1
  37. package/dist/components/game/2d/atoms/GameIcon.d.ts +1 -2
  38. package/dist/components/game/2d/atoms/HealthBar.d.ts +6 -2
  39. package/dist/components/game/2d/atoms/ItemSlot.d.ts +4 -3
  40. package/dist/components/game/2d/atoms/MiniMap.d.ts +6 -2
  41. package/dist/components/game/2d/atoms/ResourceCounter.d.ts +1 -2
  42. package/dist/components/game/2d/atoms/ScoreDisplay.d.ts +1 -2
  43. package/dist/components/game/2d/atoms/StatusEffect.d.ts +1 -2
  44. package/dist/components/game/2d/atoms/TimerDisplay.d.ts +4 -2
  45. package/dist/components/game/2d/atoms/TurnIndicator.d.ts +1 -2
  46. package/dist/components/game/2d/atoms/WaypointMarker.d.ts +1 -2
  47. package/dist/components/game/2d/molecules/ControlGrid.d.ts +3 -1
  48. package/dist/components/game/2d/molecules/GameHud.d.ts +1 -2
  49. package/dist/components/game/2d/molecules/GameMenu.d.ts +4 -8
  50. package/dist/components/game/2d/molecules/InventoryGrid.d.ts +1 -2
  51. package/dist/components/game/2d/molecules/ResourceBar.d.ts +1 -2
  52. package/dist/components/game/2d/molecules/StatBadge.d.ts +1 -2
  53. package/dist/components/game/2d/organisms/CityBuilderBoard.d.ts +2 -0
  54. package/dist/components/game/2d/organisms/PlatformerBoard.d.ts +3 -1
  55. package/dist/components/game/2d/organisms/RoguelikeBoard.d.ts +2 -0
  56. package/dist/components/game/2d/organisms/SequencerBoard.d.ts +5 -1
  57. package/dist/components/game/2d/organisms/SimulationControls.d.ts +25 -8
  58. package/dist/components/game/2d/organisms/TanksBoard.d.ts +4 -2
  59. package/dist/components/game/2d/organisms/TopDownShooterBoard.d.ts +2 -0
  60. package/dist/components/game/2d/organisms/TowerDefenseBoard.d.ts +2 -0
  61. package/dist/components/game/2d/organisms/TraitSlot.d.ts +5 -5
  62. package/dist/components/game/2d/templates/GameShell.d.ts +5 -0
  63. package/dist/components/game/2d/templates/GameTemplate.d.ts +3 -0
  64. package/dist/components/game/shared/lib/editorUtils.d.ts +8 -8
  65. package/dist/components/index.cjs +530 -483
  66. package/dist/components/index.css +3 -3
  67. package/dist/components/index.js +532 -485
  68. package/dist/hooks/useGitHub.d.ts +7 -7
  69. package/dist/marketing/index.cjs +2 -2
  70. package/dist/marketing/index.js +2 -2
  71. package/dist/providers/EventBusProvider.d.ts +1 -1
  72. package/dist/providers/SelectionProvider.d.ts +1 -1
  73. package/dist/providers/ServerBridge.d.ts +1 -1
  74. package/dist/providers/index.cjs +1826 -1811
  75. package/dist/providers/index.css +3 -3
  76. package/dist/providers/index.js +726 -711
  77. package/dist/runtime/index.cjs +1820 -1805
  78. package/dist/runtime/index.css +3 -3
  79. package/dist/runtime/index.js +730 -715
  80. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- import * as React107 from 'react';
2
- import React107__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId, useSyncExternalStore } from 'react';
1
+ import * as React105 from 'react';
2
+ import React105__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId, useSyncExternalStore } from 'react';
3
3
  import { EventBusContext, useTraitScope, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath } from '@almadar/ui/providers';
4
4
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
5
5
  import { clsx } from 'clsx';
@@ -12,7 +12,6 @@ import { useTranslate } from '@almadar/ui/hooks';
12
12
  import { useUISlots, ThemeProvider, useTheme } from '@almadar/ui/context';
13
13
  export { DesignThemeProvider, useDesignTheme } from '@almadar/ui/context';
14
14
  import { evaluate, createMinimalContext } from '@almadar/evaluator';
15
- import { getPatternDefinition, getComponentForPattern } from '@almadar/patterns';
16
15
  import { Link, Outlet, useLocation } from 'react-router-dom';
17
16
  import ELK from 'elkjs/lib/elk.bundled.js';
18
17
  import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light.js';
@@ -43,6 +42,7 @@ import { DndContext, pointerWithin, rectIntersection, closestCorners, useSensors
43
42
  import { useSortable, arrayMove, sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
44
43
  import { CSS } from '@dnd-kit/utilities';
45
44
  import { useNodeId, ReactFlowProvider, Handle, Position } from '@xyflow/react';
45
+ import { getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/patterns';
46
46
 
47
47
  var __defProp = Object.defineProperty;
48
48
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -388,7 +388,7 @@ var init_Box = __esm({
388
388
  fixed: "fixed",
389
389
  sticky: "sticky"
390
390
  };
391
- Box = React107__default.forwardRef(
391
+ Box = React105__default.forwardRef(
392
392
  ({
393
393
  padding,
394
394
  paddingX,
@@ -453,7 +453,7 @@ var init_Box = __esm({
453
453
  onPointerDown?.(e);
454
454
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
455
455
  const isClickable = action || onClick;
456
- return React107__default.createElement(
456
+ return React105__default.createElement(
457
457
  Component,
458
458
  {
459
459
  ref,
@@ -549,7 +549,7 @@ function loadLib(key, importer) {
549
549
  return p2;
550
550
  }
551
551
  function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
552
- const Lazy = React107__default.lazy(async () => {
552
+ const Lazy = React105__default.lazy(async () => {
553
553
  const lib = await loadLib(libKey, importer);
554
554
  const Comp = pick(lib);
555
555
  if (!Comp) {
@@ -559,7 +559,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
559
559
  return { default: Comp };
560
560
  });
561
561
  const Wrapped = (props) => /* @__PURE__ */ jsx(
562
- React107__default.Suspense,
562
+ React105__default.Suspense,
563
563
  {
564
564
  fallback: /* @__PURE__ */ jsx(
565
565
  "span",
@@ -1290,7 +1290,7 @@ var init_Icon = __esm({
1290
1290
  const directIcon = typeof icon === "string" ? void 0 : icon;
1291
1291
  const effectiveName = typeof icon === "string" ? icon : name;
1292
1292
  const family = useIconFamily();
1293
- const RenderedComponent = React107__default.useMemo(() => {
1293
+ const RenderedComponent = React105__default.useMemo(() => {
1294
1294
  if (directIcon) return null;
1295
1295
  return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
1296
1296
  }, [directIcon, effectiveName, family]);
@@ -1352,7 +1352,7 @@ function resolveIconProp(value, sizeClass) {
1352
1352
  const IconComp = value;
1353
1353
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1354
1354
  }
1355
- if (React107__default.isValidElement(value)) {
1355
+ if (React105__default.isValidElement(value)) {
1356
1356
  return value;
1357
1357
  }
1358
1358
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -1428,7 +1428,7 @@ var init_Button = __esm({
1428
1428
  md: "h-icon-default w-icon-default",
1429
1429
  lg: "h-icon-default w-icon-default"
1430
1430
  };
1431
- Button = React107__default.forwardRef(
1431
+ Button = React105__default.forwardRef(
1432
1432
  ({
1433
1433
  className,
1434
1434
  variant = "primary",
@@ -1494,7 +1494,7 @@ var Dialog;
1494
1494
  var init_Dialog = __esm({
1495
1495
  "components/core/atoms/Dialog.tsx"() {
1496
1496
  init_cn();
1497
- Dialog = React107__default.forwardRef(
1497
+ Dialog = React105__default.forwardRef(
1498
1498
  ({
1499
1499
  role = "dialog",
1500
1500
  "aria-modal": ariaModal = true,
@@ -1612,7 +1612,7 @@ var init_Typography = __esm({
1612
1612
  }) => {
1613
1613
  const variant = variantProp ?? (level ? `h${level}` : "body1");
1614
1614
  const Component = as || defaultElements[variant];
1615
- return React107__default.createElement(
1615
+ return React105__default.createElement(
1616
1616
  Component,
1617
1617
  {
1618
1618
  id,
@@ -2107,7 +2107,7 @@ var init_Badge = __esm({
2107
2107
  md: "px-2.5 py-1 text-sm",
2108
2108
  lg: "px-3 py-1.5 text-base"
2109
2109
  };
2110
- Badge = React107__default.forwardRef(
2110
+ Badge = React105__default.forwardRef(
2111
2111
  ({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
2112
2112
  const iconSizes3 = {
2113
2113
  sm: "h-icon-default w-icon-default",
@@ -2443,7 +2443,7 @@ var init_SvgFlow = __esm({
2443
2443
  width = 100,
2444
2444
  height = 100
2445
2445
  }) => {
2446
- const markerId = React107__default.useMemo(() => {
2446
+ const markerId = React105__default.useMemo(() => {
2447
2447
  flowIdCounter += 1;
2448
2448
  return `almadar-flow-arrow-${flowIdCounter}`;
2449
2449
  }, []);
@@ -3036,7 +3036,7 @@ var init_SvgRing = __esm({
3036
3036
  width = 100,
3037
3037
  height = 100
3038
3038
  }) => {
3039
- const gradientId = React107__default.useMemo(() => {
3039
+ const gradientId = React105__default.useMemo(() => {
3040
3040
  ringIdCounter += 1;
3041
3041
  return `almadar-ring-glow-${ringIdCounter}`;
3042
3042
  }, []);
@@ -3217,7 +3217,7 @@ var init_Input = __esm({
3217
3217
  init_cn();
3218
3218
  init_Icon();
3219
3219
  init_useEventBus();
3220
- Input = React107__default.forwardRef(
3220
+ Input = React105__default.forwardRef(
3221
3221
  ({
3222
3222
  className,
3223
3223
  inputType,
@@ -3377,7 +3377,7 @@ var Label;
3377
3377
  var init_Label = __esm({
3378
3378
  "components/core/atoms/Label.tsx"() {
3379
3379
  init_cn();
3380
- Label = React107__default.forwardRef(
3380
+ Label = React105__default.forwardRef(
3381
3381
  ({ className, required, children, ...props }, ref) => {
3382
3382
  return /* @__PURE__ */ jsxs(
3383
3383
  "label",
@@ -3404,7 +3404,7 @@ var init_Textarea = __esm({
3404
3404
  "components/core/atoms/Textarea.tsx"() {
3405
3405
  init_cn();
3406
3406
  init_useEventBus();
3407
- Textarea = React107__default.forwardRef(
3407
+ Textarea = React105__default.forwardRef(
3408
3408
  ({ className, error, onChange, ...props }, ref) => {
3409
3409
  const eventBus = useEventBus();
3410
3410
  const handleChange = (e) => {
@@ -3643,7 +3643,7 @@ var init_Select = __esm({
3643
3643
  init_cn();
3644
3644
  init_Icon();
3645
3645
  init_useEventBus();
3646
- Select = React107__default.forwardRef(
3646
+ Select = React105__default.forwardRef(
3647
3647
  (props, _ref) => {
3648
3648
  const { multiple, searchable, clearable } = props;
3649
3649
  if (multiple || searchable || clearable) {
@@ -3660,7 +3660,7 @@ var init_Checkbox = __esm({
3660
3660
  "components/core/atoms/Checkbox.tsx"() {
3661
3661
  init_cn();
3662
3662
  init_useEventBus();
3663
- Checkbox = React107__default.forwardRef(
3663
+ Checkbox = React105__default.forwardRef(
3664
3664
  ({ className, label, id, onChange, ...props }, ref) => {
3665
3665
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
3666
3666
  const eventBus = useEventBus();
@@ -3714,7 +3714,7 @@ var init_Spinner = __esm({
3714
3714
  md: "h-6 w-6",
3715
3715
  lg: "h-8 w-8"
3716
3716
  };
3717
- Spinner = React107__default.forwardRef(
3717
+ Spinner = React105__default.forwardRef(
3718
3718
  ({ className, size = "md", overlay, ...props }, ref) => {
3719
3719
  if (overlay) {
3720
3720
  return /* @__PURE__ */ jsx(
@@ -3804,7 +3804,7 @@ var init_Card = __esm({
3804
3804
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
3805
3805
  "tile-image-first": "p-0 overflow-hidden"
3806
3806
  };
3807
- Card = React107__default.forwardRef(
3807
+ Card = React105__default.forwardRef(
3808
3808
  ({
3809
3809
  className,
3810
3810
  variant = "bordered",
@@ -3852,9 +3852,9 @@ var init_Card = __esm({
3852
3852
  }
3853
3853
  );
3854
3854
  Card.displayName = "Card";
3855
- CardHeader = React107__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3855
+ CardHeader = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3856
3856
  CardHeader.displayName = "CardHeader";
3857
- CardTitle = React107__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3857
+ CardTitle = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3858
3858
  "h3",
3859
3859
  {
3860
3860
  ref,
@@ -3867,11 +3867,11 @@ var init_Card = __esm({
3867
3867
  }
3868
3868
  ));
3869
3869
  CardTitle.displayName = "CardTitle";
3870
- CardContent = React107__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3870
+ CardContent = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3871
3871
  CardContent.displayName = "CardContent";
3872
3872
  CardBody = CardContent;
3873
3873
  CardBody.displayName = "CardBody";
3874
- CardFooter = React107__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3874
+ CardFooter = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3875
3875
  "div",
3876
3876
  {
3877
3877
  ref,
@@ -3926,7 +3926,7 @@ var init_FilterPill = __esm({
3926
3926
  md: "w-3.5 h-3.5",
3927
3927
  lg: "w-4 h-4"
3928
3928
  };
3929
- FilterPill = React107__default.forwardRef(
3929
+ FilterPill = React105__default.forwardRef(
3930
3930
  ({
3931
3931
  className,
3932
3932
  variant = "default",
@@ -4055,8 +4055,8 @@ var init_Avatar = __esm({
4055
4055
  actionPayload
4056
4056
  }) => {
4057
4057
  const eventBus = useEventBus();
4058
- const [imgFailed, setImgFailed] = React107__default.useState(false);
4059
- React107__default.useEffect(() => {
4058
+ const [imgFailed, setImgFailed] = React105__default.useState(false);
4059
+ React105__default.useEffect(() => {
4060
4060
  setImgFailed(false);
4061
4061
  }, [src]);
4062
4062
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -4169,7 +4169,7 @@ var init_Center = __esm({
4169
4169
  as: Component = "div"
4170
4170
  }) => {
4171
4171
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
4172
- return React107__default.createElement(Component, {
4172
+ return React105__default.createElement(Component, {
4173
4173
  className: cn(
4174
4174
  inline ? "inline-flex" : "flex",
4175
4175
  horizontal && "justify-center",
@@ -4437,7 +4437,7 @@ var init_Radio = __esm({
4437
4437
  md: "w-2.5 h-2.5",
4438
4438
  lg: "w-3 h-3"
4439
4439
  };
4440
- Radio = React107__default.forwardRef(
4440
+ Radio = React105__default.forwardRef(
4441
4441
  ({
4442
4442
  label,
4443
4443
  helperText,
@@ -4454,12 +4454,12 @@ var init_Radio = __esm({
4454
4454
  onChange,
4455
4455
  ...props
4456
4456
  }, ref) => {
4457
- const reactId = React107__default.useId();
4457
+ const reactId = React105__default.useId();
4458
4458
  const baseId = id || `radio-${reactId}`;
4459
4459
  const hasError = !!error;
4460
4460
  const eventBus = useEventBus();
4461
- const [selected, setSelected] = React107__default.useState(value);
4462
- React107__default.useEffect(() => {
4461
+ const [selected, setSelected] = React105__default.useState(value);
4462
+ React105__default.useEffect(() => {
4463
4463
  if (value !== void 0) setSelected(value);
4464
4464
  }, [value]);
4465
4465
  const pick = (next, e) => {
@@ -4641,7 +4641,7 @@ var init_Switch = __esm({
4641
4641
  "components/core/atoms/Switch.tsx"() {
4642
4642
  "use client";
4643
4643
  init_cn();
4644
- Switch = React107.forwardRef(
4644
+ Switch = React105.forwardRef(
4645
4645
  ({
4646
4646
  checked,
4647
4647
  defaultChecked = false,
@@ -4652,10 +4652,10 @@ var init_Switch = __esm({
4652
4652
  name,
4653
4653
  className
4654
4654
  }, ref) => {
4655
- const [isChecked, setIsChecked] = React107.useState(
4655
+ const [isChecked, setIsChecked] = React105.useState(
4656
4656
  checked !== void 0 ? checked : defaultChecked
4657
4657
  );
4658
- React107.useEffect(() => {
4658
+ React105.useEffect(() => {
4659
4659
  if (checked !== void 0) {
4660
4660
  setIsChecked(checked);
4661
4661
  }
@@ -4818,7 +4818,7 @@ var init_Stack = __esm({
4818
4818
  };
4819
4819
  const isHorizontal = direction === "horizontal";
4820
4820
  const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
4821
- return React107__default.createElement(
4821
+ return React105__default.createElement(
4822
4822
  Component,
4823
4823
  {
4824
4824
  className: cn(
@@ -5018,7 +5018,7 @@ var Aside;
5018
5018
  var init_Aside = __esm({
5019
5019
  "components/core/atoms/Aside.tsx"() {
5020
5020
  init_cn();
5021
- Aside = React107__default.forwardRef(
5021
+ Aside = React105__default.forwardRef(
5022
5022
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
5023
5023
  );
5024
5024
  Aside.displayName = "Aside";
@@ -5097,9 +5097,9 @@ var init_LawReferenceTooltip = __esm({
5097
5097
  className
5098
5098
  }) => {
5099
5099
  const { t } = useTranslate();
5100
- const [isVisible, setIsVisible] = React107__default.useState(false);
5101
- const timeoutRef = React107__default.useRef(null);
5102
- const triggerRef = React107__default.useRef(null);
5100
+ const [isVisible, setIsVisible] = React105__default.useState(false);
5101
+ const timeoutRef = React105__default.useRef(null);
5102
+ const triggerRef = React105__default.useRef(null);
5103
5103
  const handleMouseEnter = () => {
5104
5104
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5105
5105
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -5110,7 +5110,7 @@ var init_LawReferenceTooltip = __esm({
5110
5110
  };
5111
5111
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
5112
5112
  const open = isVisible || revealed;
5113
- React107__default.useEffect(() => {
5113
+ React105__default.useEffect(() => {
5114
5114
  return () => {
5115
5115
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5116
5116
  };
@@ -5320,7 +5320,7 @@ var init_StatusDot = __esm({
5320
5320
  md: "w-2.5 h-2.5",
5321
5321
  lg: "w-3 h-3"
5322
5322
  };
5323
- StatusDot = React107__default.forwardRef(
5323
+ StatusDot = React105__default.forwardRef(
5324
5324
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
5325
5325
  return /* @__PURE__ */ jsx(
5326
5326
  "span",
@@ -5374,7 +5374,7 @@ var init_TrendIndicator = __esm({
5374
5374
  down: "trending-down",
5375
5375
  flat: "arrow-right"
5376
5376
  };
5377
- TrendIndicator = React107__default.forwardRef(
5377
+ TrendIndicator = React105__default.forwardRef(
5378
5378
  ({
5379
5379
  className,
5380
5380
  value,
@@ -5441,7 +5441,7 @@ var init_RangeSlider = __esm({
5441
5441
  md: "w-4 h-4",
5442
5442
  lg: "w-5 h-5"
5443
5443
  };
5444
- RangeSlider = React107__default.forwardRef(
5444
+ RangeSlider = React105__default.forwardRef(
5445
5445
  ({
5446
5446
  className,
5447
5447
  min = 0,
@@ -6035,7 +6035,7 @@ var init_ContentSection = __esm({
6035
6035
  md: "py-16",
6036
6036
  lg: "py-24"
6037
6037
  };
6038
- ContentSection = React107__default.forwardRef(
6038
+ ContentSection = React105__default.forwardRef(
6039
6039
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
6040
6040
  return /* @__PURE__ */ jsx(
6041
6041
  Box,
@@ -6569,7 +6569,7 @@ var init_AnimatedReveal = __esm({
6569
6569
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
6570
6570
  "none": {}
6571
6571
  };
6572
- AnimatedReveal = React107__default.forwardRef(
6572
+ AnimatedReveal = React105__default.forwardRef(
6573
6573
  ({
6574
6574
  trigger = "scroll",
6575
6575
  animation = "fade-up",
@@ -6729,7 +6729,7 @@ var init_AnimatedGraphic = __esm({
6729
6729
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6730
6730
  "use client";
6731
6731
  init_cn();
6732
- AnimatedGraphic = React107__default.forwardRef(
6732
+ AnimatedGraphic = React105__default.forwardRef(
6733
6733
  ({
6734
6734
  src,
6735
6735
  svgContent,
@@ -6752,7 +6752,7 @@ var init_AnimatedGraphic = __esm({
6752
6752
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6753
6753
  const resolvedSvg = svgContent ?? fetchedSvg;
6754
6754
  const prevAnimateRef = useRef(animate);
6755
- const setRef = React107__default.useCallback(
6755
+ const setRef = React105__default.useCallback(
6756
6756
  (node) => {
6757
6757
  containerRef.current = node;
6758
6758
  if (typeof ref === "function") ref(node);
@@ -8357,6 +8357,38 @@ var init_shared = __esm({
8357
8357
  init_canvasEffects();
8358
8358
  }
8359
8359
  });
8360
+ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
8361
+ const px = typeof size === "number" ? size : sizeMap[size];
8362
+ if (assetUrl?.url) {
8363
+ return /* @__PURE__ */ jsx(
8364
+ "img",
8365
+ {
8366
+ src: assetUrl.url,
8367
+ alt: alt ?? assetUrl.category ?? "",
8368
+ width: px,
8369
+ height: px,
8370
+ style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
8371
+ className: cn("flex-shrink-0", className)
8372
+ }
8373
+ );
8374
+ }
8375
+ const I = typeof icon === "string" ? resolveIcon(icon) : icon;
8376
+ return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
8377
+ }
8378
+ var sizeMap;
8379
+ var init_GameIcon = __esm({
8380
+ "components/game/2d/atoms/GameIcon.tsx"() {
8381
+ "use client";
8382
+ init_cn();
8383
+ init_Icon();
8384
+ sizeMap = {
8385
+ sm: 16,
8386
+ md: 24,
8387
+ lg: 32
8388
+ };
8389
+ GameIcon.displayName = "GameIcon";
8390
+ }
8391
+ });
8360
8392
  function GameCard({
8361
8393
  id,
8362
8394
  cost,
@@ -8372,16 +8404,16 @@ function GameCard({
8372
8404
  className
8373
8405
  }) {
8374
8406
  const eventBus = useEventBus();
8375
- const handleClick = React107.useCallback(() => {
8407
+ const handleClick = React105.useCallback(() => {
8376
8408
  if (disabled) return;
8377
8409
  onClick?.(id);
8378
8410
  if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { cardId: id });
8379
8411
  }, [disabled, id, onClick, clickEvent, eventBus]);
8380
8412
  const artPx = artPxMap[size];
8381
8413
  return /* @__PURE__ */ jsxs(
8382
- "button",
8414
+ Button,
8383
8415
  {
8384
- type: "button",
8416
+ variant: "ghost",
8385
8417
  onClick: handleClick,
8386
8418
  disabled,
8387
8419
  title: name,
@@ -8395,8 +8427,9 @@ function GameCard({
8395
8427
  ),
8396
8428
  children: [
8397
8429
  cost != null && /* @__PURE__ */ jsx(
8398
- "span",
8430
+ Typography,
8399
8431
  {
8432
+ as: "span",
8400
8433
  className: cn(
8401
8434
  "absolute -top-2 -left-2 flex items-center justify-center",
8402
8435
  "min-w-[22px] h-[22px] rounded-full px-1",
@@ -8405,17 +8438,7 @@ function GameCard({
8405
8438
  children: cost
8406
8439
  }
8407
8440
  ),
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 } }) }),
8441
+ /* @__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
8442
  name != null && /* @__PURE__ */ jsx(
8420
8443
  Typography,
8421
8444
  {
@@ -8425,8 +8448,8 @@ function GameCard({
8425
8448
  }
8426
8449
  ),
8427
8450
  (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}` : "" })
8451
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
8452
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
8430
8453
  ] })
8431
8454
  ]
8432
8455
  }
@@ -8439,7 +8462,9 @@ var init_GameCard = __esm({
8439
8462
  init_cn();
8440
8463
  init_useEventBus();
8441
8464
  init_Box();
8465
+ init_Button();
8442
8466
  init_Typography();
8467
+ init_GameIcon();
8443
8468
  cardSizeMap = {
8444
8469
  sm: "w-16 h-24",
8445
8470
  md: "w-20 h-28",
@@ -8458,14 +8483,17 @@ function HealthBar({
8458
8483
  labelSuffix,
8459
8484
  size = "md",
8460
8485
  className,
8461
- animated = true
8486
+ animated = true,
8487
+ frameAsset,
8488
+ fillAsset
8462
8489
  }) {
8463
- const sizes = sizeMap[size];
8490
+ const sizes = sizeMap2[size];
8464
8491
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
8465
8492
  if (format === "hearts") {
8466
- return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
8467
- "span",
8493
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
8494
+ Box,
8468
8495
  {
8496
+ as: "span",
8469
8497
  className: cn(animated && "transition-transform hover:scale-110"),
8470
8498
  children: heartIcon(i < current, sizes.heart)
8471
8499
  },
@@ -8474,33 +8502,42 @@ function HealthBar({
8474
8502
  }
8475
8503
  if (format === "bar") {
8476
8504
  return /* @__PURE__ */ jsx(
8477
- "div",
8505
+ Box,
8478
8506
  {
8507
+ position: "relative",
8508
+ overflow: "hidden",
8479
8509
  className: cn(
8480
- "relative overflow-hidden rounded-full bg-muted",
8510
+ "rounded-full",
8511
+ !frameAsset && "bg-muted",
8481
8512
  sizes.bar,
8482
8513
  "w-24",
8483
8514
  className
8484
8515
  ),
8516
+ style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
8485
8517
  children: /* @__PURE__ */ jsx(
8486
- "div",
8518
+ Box,
8487
8519
  {
8520
+ position: "absolute",
8488
8521
  className: cn(
8489
- "absolute inset-y-0 left-0 rounded-full",
8490
- percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error",
8522
+ "inset-y-0 left-0 rounded-full",
8523
+ !fillAsset && (percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error"),
8491
8524
  animated && "transition-all duration-300"
8492
8525
  ),
8493
- style: { width: `${percentage}%` }
8526
+ style: {
8527
+ width: `${percentage}%`,
8528
+ ...fillAsset ? { backgroundImage: `url(${fillAsset.url})`, backgroundSize: "auto 100%" } : {}
8529
+ }
8494
8530
  }
8495
8531
  )
8496
8532
  }
8497
8533
  );
8498
8534
  }
8499
8535
  if (format === "progress") {
8500
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
8536
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex items-center gap-2", className), children: [
8501
8537
  level != null && /* @__PURE__ */ jsxs(
8502
- "span",
8538
+ Typography,
8503
8539
  {
8540
+ as: "span",
8504
8541
  className: cn(
8505
8542
  "flex-shrink-0 rounded-interactive font-bold",
8506
8543
  "bg-accent text-accent-foreground border border-accent",
@@ -8512,28 +8549,35 @@ function HealthBar({
8512
8549
  ]
8513
8550
  }
8514
8551
  ),
8515
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [
8552
+ /* @__PURE__ */ jsxs(Box, { className: "flex-1 flex flex-col gap-0.5", children: [
8516
8553
  /* @__PURE__ */ jsx(
8517
- "div",
8554
+ Box,
8518
8555
  {
8556
+ position: "relative",
8519
8557
  className: cn(
8520
- "relative w-full overflow-hidden rounded-full bg-muted border border-muted",
8558
+ "w-full overflow-hidden rounded-full",
8559
+ !frameAsset && "bg-muted border border-muted",
8521
8560
  sizes.bar
8522
8561
  ),
8562
+ style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
8523
8563
  children: /* @__PURE__ */ jsx(
8524
- "div",
8564
+ Box,
8525
8565
  {
8566
+ position: "absolute",
8526
8567
  className: cn(
8527
- "absolute inset-y-0 left-0 rounded-full",
8528
- "bg-gradient-to-r from-accent to-info",
8568
+ "inset-y-0 left-0 rounded-full",
8569
+ !fillAsset && "bg-gradient-to-r from-accent to-info",
8529
8570
  animated && "transition-all duration-500 ease-out"
8530
8571
  ),
8531
- style: { width: `${percentage}%` }
8572
+ style: {
8573
+ width: `${percentage}%`,
8574
+ ...fillAsset ? { backgroundImage: `url(${fillAsset.url})`, backgroundSize: "auto 100%" } : {}
8575
+ }
8532
8576
  }
8533
8577
  )
8534
8578
  }
8535
8579
  ),
8536
- showLabel && /* @__PURE__ */ jsxs("span", { className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
8580
+ showLabel && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
8537
8581
  current,
8538
8582
  " / ",
8539
8583
  max,
@@ -8542,16 +8586,18 @@ function HealthBar({
8542
8586
  ] })
8543
8587
  ] });
8544
8588
  }
8545
- return /* @__PURE__ */ jsxs("span", { className: cn("font-mono font-bold", sizes.text, className), children: [
8589
+ return /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-mono font-bold", sizes.text, className), children: [
8546
8590
  current,
8547
8591
  "/",
8548
8592
  max
8549
8593
  ] });
8550
8594
  }
8551
- var heartIcon, sizeMap;
8595
+ var heartIcon, sizeMap2;
8552
8596
  var init_HealthBar = __esm({
8553
8597
  "components/game/2d/atoms/HealthBar.tsx"() {
8554
8598
  init_cn();
8599
+ init_Box();
8600
+ init_Typography();
8555
8601
  heartIcon = (filled, size) => /* @__PURE__ */ jsx(
8556
8602
  "svg",
8557
8603
  {
@@ -8563,7 +8609,7 @@ var init_HealthBar = __esm({
8563
8609
  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" })
8564
8610
  }
8565
8611
  );
8566
- sizeMap = {
8612
+ sizeMap2 = {
8567
8613
  sm: { heart: "w-4 h-4", bar: "h-2", text: "text-sm", label: "text-xs", badge: "text-xs px-1.5 py-0.5" },
8568
8614
  md: { heart: "w-6 h-6", bar: "h-3", text: "text-base", label: "text-xs", badge: "text-xs px-2 py-0.5" },
8569
8615
  lg: { heart: "w-8 h-8", bar: "h-4", text: "text-lg", label: "text-sm", badge: "text-sm px-2.5 py-1" }
@@ -8584,37 +8630,30 @@ function ScoreDisplay({
8584
8630
  const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
8585
8631
  const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
8586
8632
  return /* @__PURE__ */ jsxs(
8587
- "div",
8633
+ Box,
8588
8634
  {
8589
8635
  className: cn(
8590
8636
  "flex items-center gap-2 font-bold",
8591
- sizeMap2[size],
8637
+ sizeMap3[size],
8592
8638
  className
8593
8639
  ),
8594
8640
  children: [
8595
- assetUrl ? /* @__PURE__ */ jsx(
8596
- "img",
8597
- {
8598
- src: assetUrl.url,
8599
- alt: "",
8600
- width: 20,
8601
- height: 20,
8602
- style: { imageRendering: "pixelated", objectFit: "contain" },
8603
- className: "flex-shrink-0"
8604
- }
8605
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
8606
- label && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
8607
- /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formattedValue })
8641
+ 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,
8642
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
8643
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "tabular-nums", children: formattedValue })
8608
8644
  ]
8609
8645
  }
8610
8646
  );
8611
8647
  }
8612
- var sizeMap2, DEFAULT_ASSET_URL;
8648
+ var sizeMap3, DEFAULT_ASSET_URL;
8613
8649
  var init_ScoreDisplay = __esm({
8614
8650
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
8615
8651
  init_cn();
8616
8652
  init_Icon();
8617
- sizeMap2 = {
8653
+ init_Box();
8654
+ init_Typography();
8655
+ init_GameIcon();
8656
+ sizeMap3 = {
8618
8657
  sm: "text-sm",
8619
8658
  md: "text-lg",
8620
8659
  lg: "text-2xl",
@@ -8644,9 +8683,9 @@ function ControlButton({
8644
8683
  className
8645
8684
  }) {
8646
8685
  const eventBus = useEventBus();
8647
- const [isPressed, setIsPressed] = React107.useState(false);
8686
+ const [isPressed, setIsPressed] = React105.useState(false);
8648
8687
  const actualPressed = pressed ?? isPressed;
8649
- const handlePointerDown = React107.useCallback(
8688
+ const handlePointerDown = React105.useCallback(
8650
8689
  (e) => {
8651
8690
  e.preventDefault();
8652
8691
  if (disabled) return;
@@ -8656,7 +8695,7 @@ function ControlButton({
8656
8695
  },
8657
8696
  [disabled, pressEvent, eventBus, onPress]
8658
8697
  );
8659
- const handlePointerUp = React107.useCallback(
8698
+ const handlePointerUp = React105.useCallback(
8660
8699
  (e) => {
8661
8700
  e.preventDefault();
8662
8701
  if (disabled) return;
@@ -8666,7 +8705,7 @@ function ControlButton({
8666
8705
  },
8667
8706
  [disabled, releaseEvent, eventBus, onRelease]
8668
8707
  );
8669
- const handlePointerLeave = React107.useCallback(
8708
+ const handlePointerLeave = React105.useCallback(
8670
8709
  (e) => {
8671
8710
  if (isPressed) {
8672
8711
  setIsPressed(false);
@@ -8677,9 +8716,9 @@ function ControlButton({
8677
8716
  [isPressed, releaseEvent, eventBus, onRelease]
8678
8717
  );
8679
8718
  return /* @__PURE__ */ jsx(
8680
- "button",
8719
+ Button,
8681
8720
  {
8682
- type: "button",
8721
+ variant,
8683
8722
  disabled,
8684
8723
  onPointerDown: handlePointerDown,
8685
8724
  onPointerUp: handlePointerUp,
@@ -8690,41 +8729,35 @@ function ControlButton({
8690
8729
  "select-none touch-none",
8691
8730
  "transition-all duration-100",
8692
8731
  "active:scale-95",
8693
- sizeMap3[size] ?? sizeMap3.md,
8732
+ sizeMap4[size] ?? sizeMap4.md,
8694
8733
  shapeMap[shape] ?? shapeMap.circle,
8695
8734
  variantMap[variant] ?? variantMap.secondary,
8696
8735
  actualPressed && "scale-95 brightness-110 border-foreground",
8697
8736
  disabled && "opacity-50 cursor-not-allowed",
8698
8737
  className
8699
8738
  ),
8700
- children: assetUrl ? /* @__PURE__ */ jsx(
8701
- "img",
8702
- {
8703
- src: assetUrl.url,
8704
- alt: "",
8705
- width: 24,
8706
- height: 24,
8707
- style: { imageRendering: "pixelated", objectFit: "contain" },
8708
- className: "flex-shrink-0"
8709
- }
8710
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
8739
+ 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) ? (() => {
8711
8740
  const I = resolveIcon(icon);
8712
8741
  return I ? /* @__PURE__ */ jsx(I, { className: "w-6 h-6" }) : null;
8713
8742
  })() : icon : /* @__PURE__ */ (() => {
8714
8743
  const I = icon;
8715
8744
  return /* @__PURE__ */ jsx(I, { className: "w-6 h-6" });
8716
- })() }) : label ? /* @__PURE__ */ jsx("span", { children: label }) : null
8745
+ })() }) : label ? /* @__PURE__ */ jsx(Typography, { as: "span", children: label }) : null
8717
8746
  }
8718
8747
  );
8719
8748
  }
8720
- var sizeMap3, shapeMap, variantMap, DEFAULT_ASSET_URL2;
8749
+ var sizeMap4, shapeMap, variantMap, DEFAULT_ASSET_URL2;
8721
8750
  var init_ControlButton = __esm({
8722
8751
  "components/game/2d/atoms/ControlButton.tsx"() {
8723
8752
  "use client";
8724
8753
  init_cn();
8725
8754
  init_useEventBus();
8726
8755
  init_Icon();
8727
- sizeMap3 = {
8756
+ init_Button();
8757
+ init_Box();
8758
+ init_Typography();
8759
+ init_GameIcon();
8760
+ sizeMap4 = {
8728
8761
  sm: "w-10 h-10 text-sm",
8729
8762
  md: "w-14 h-14 text-base",
8730
8763
  lg: "w-18 h-18 text-lg",
@@ -8794,12 +8827,12 @@ function Sprite({
8794
8827
  onClick?.();
8795
8828
  };
8796
8829
  return /* @__PURE__ */ jsx(
8797
- "div",
8830
+ Box,
8798
8831
  {
8832
+ position: "absolute",
8799
8833
  className,
8800
8834
  onClick: action || onClick ? handleClick : void 0,
8801
8835
  style: {
8802
- position: "absolute",
8803
8836
  width: frameWidth,
8804
8837
  height: frameHeight,
8805
8838
  backgroundImage: `url(${spritesheet.url})`,
@@ -8820,6 +8853,7 @@ var init_Sprite = __esm({
8820
8853
  "components/game/2d/atoms/Sprite.tsx"() {
8821
8854
  "use client";
8822
8855
  init_useEventBus();
8856
+ init_Box();
8823
8857
  init_spriteAnimation();
8824
8858
  DEFAULT_SPRITESHEET = {
8825
8859
  url: "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
@@ -8856,17 +8890,7 @@ function StateIndicator({
8856
8890
  className
8857
8891
  ),
8858
8892
  children: [
8859
- /* @__PURE__ */ jsx(Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsx(
8860
- "img",
8861
- {
8862
- src: assetUrl.url,
8863
- alt: displayLabel,
8864
- width: 16,
8865
- height: 16,
8866
- style: { imageRendering: "pixelated", objectFit: "contain" },
8867
- className: "flex-shrink-0"
8868
- }
8869
- ) : 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 }) }),
8893
+ /* @__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 }) }),
8870
8894
  /* @__PURE__ */ jsx(Box, { as: "span", children: displayLabel })
8871
8895
  ]
8872
8896
  }
@@ -8878,6 +8902,7 @@ var init_StateIndicator = __esm({
8878
8902
  init_Box();
8879
8903
  init_Icon();
8880
8904
  init_cn();
8905
+ init_GameIcon();
8881
8906
  DEFAULT_ASSET_URL3 = {
8882
8907
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
8883
8908
  role: "ui",
@@ -8926,30 +8951,36 @@ function TimerDisplay({
8926
8951
  format = "mm:ss",
8927
8952
  size = "md",
8928
8953
  className,
8929
- lowThreshold
8954
+ lowThreshold,
8955
+ iconAsset
8930
8956
  }) {
8931
8957
  const isLow = lowThreshold != null && seconds <= lowThreshold && seconds > 0;
8932
- return /* @__PURE__ */ jsx(
8933
- "div",
8958
+ return /* @__PURE__ */ jsxs(
8959
+ Box,
8934
8960
  {
8935
8961
  className: cn(
8936
- "inline-flex items-center justify-center rounded-container",
8962
+ "inline-flex items-center gap-1 justify-center rounded-container",
8937
8963
  "bg-card/80 border border-muted font-mono font-bold tabular-nums",
8938
- sizeMap4[size],
8964
+ sizeMap5[size],
8939
8965
  running && "border-success/50",
8940
8966
  isLow && "text-error border-error/50 animate-pulse",
8941
8967
  !isLow && "text-foreground",
8942
8968
  className
8943
8969
  ),
8944
- children: formatTime(seconds, format)
8970
+ children: [
8971
+ iconAsset && /* @__PURE__ */ jsx(GameIcon, { assetUrl: iconAsset, icon: "image", size: 16, className: "w-4 h-4 object-contain flex-shrink-0" }),
8972
+ formatTime(seconds, format)
8973
+ ]
8945
8974
  }
8946
8975
  );
8947
8976
  }
8948
- var sizeMap4;
8977
+ var sizeMap5;
8949
8978
  var init_TimerDisplay = __esm({
8950
8979
  "components/game/2d/atoms/TimerDisplay.tsx"() {
8951
8980
  init_cn();
8952
- sizeMap4 = {
8981
+ init_Box();
8982
+ init_GameIcon();
8983
+ sizeMap5 = {
8953
8984
  sm: "text-sm px-2 py-0.5",
8954
8985
  md: "text-lg px-3 py-1",
8955
8986
  lg: "text-2xl px-4 py-1.5"
@@ -8967,9 +8998,9 @@ function ResourceCounter({
8967
8998
  size = "md",
8968
8999
  className
8969
9000
  }) {
8970
- const sizes = sizeMap5[size];
9001
+ const sizes = sizeMap6[size];
8971
9002
  return /* @__PURE__ */ jsxs(
8972
- "div",
9003
+ Box,
8973
9004
  {
8974
9005
  className: cn(
8975
9006
  "inline-flex items-center rounded-container",
@@ -8978,21 +9009,11 @@ function ResourceCounter({
8978
9009
  className
8979
9010
  ),
8980
9011
  children: [
8981
- assetUrl ? /* @__PURE__ */ jsx(
8982
- "img",
8983
- {
8984
- src: assetUrl.url,
8985
- alt: label,
8986
- width: sizes.img,
8987
- height: sizes.img,
8988
- style: { imageRendering: "pixelated", objectFit: "contain" },
8989
- className: "flex-shrink-0"
8990
- }
8991
- ) : 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,
8992
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
8993
- /* @__PURE__ */ jsxs("span", { className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
9012
+ 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,
9013
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
9014
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
8994
9015
  value,
8995
- max != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9016
+ max != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
8996
9017
  "/",
8997
9018
  max
8998
9019
  ] })
@@ -9001,11 +9022,14 @@ function ResourceCounter({
9001
9022
  }
9002
9023
  );
9003
9024
  }
9004
- var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap5;
9025
+ var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap6;
9005
9026
  var init_ResourceCounter = __esm({
9006
9027
  "components/game/2d/atoms/ResourceCounter.tsx"() {
9007
9028
  init_cn();
9008
9029
  init_Icon();
9030
+ init_Box();
9031
+ init_Typography();
9032
+ init_GameIcon();
9009
9033
  colorTokenClasses2 = {
9010
9034
  primary: "text-primary",
9011
9035
  secondary: "text-secondary",
@@ -9019,7 +9043,7 @@ var init_ResourceCounter = __esm({
9019
9043
  role: "ui",
9020
9044
  category: "coin"
9021
9045
  };
9022
- sizeMap5 = {
9046
+ sizeMap6 = {
9023
9047
  sm: { wrapper: "text-xs gap-1 px-1.5 py-0.5", icon: "text-sm", img: 16 },
9024
9048
  md: { wrapper: "text-sm gap-1.5 px-2 py-1", icon: "text-base", img: 20 },
9025
9049
  lg: { wrapper: "text-base gap-2 px-3 py-1.5", icon: "text-lg", img: 28 }
@@ -9037,21 +9061,26 @@ function ItemSlot({
9037
9061
  size = "md",
9038
9062
  selected,
9039
9063
  onClick,
9064
+ action,
9040
9065
  className
9041
9066
  }) {
9042
- const isClickable = onClick != null;
9067
+ const eventBus = useEventBus();
9068
+ const isClickable = onClick != null || action != null;
9043
9069
  const px = assetSizeMap[size];
9044
9070
  return /* @__PURE__ */ jsx(
9045
- "button",
9071
+ Button,
9046
9072
  {
9047
- type: "button",
9048
- onClick,
9073
+ variant: "ghost",
9074
+ onClick: () => {
9075
+ if (action) eventBus.emit(`UI:${action}`, {});
9076
+ onClick?.();
9077
+ },
9049
9078
  disabled: !isClickable,
9050
9079
  title: label,
9051
9080
  className: cn(
9052
9081
  "relative flex items-center justify-center rounded-interactive border-2",
9053
9082
  "bg-card/80 transition-all duration-150",
9054
- sizeMap6[size],
9083
+ sizeMap7[size],
9055
9084
  empty ? "border-border bg-card/50" : rarityBorderMap[rarity],
9056
9085
  !empty && rarityGlowMap[rarity],
9057
9086
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background",
@@ -9060,21 +9089,12 @@ function ItemSlot({
9060
9089
  !isClickable && "cursor-default",
9061
9090
  className
9062
9091
  ),
9063
- children: empty ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9064
- assetUrl ? /* @__PURE__ */ jsx(
9065
- "img",
9066
- {
9067
- src: assetUrl?.url,
9068
- alt: label,
9069
- width: px,
9070
- height: px,
9071
- style: { imageRendering: "pixelated", objectFit: "contain" },
9072
- className: "flex-shrink-0"
9073
- }
9074
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9092
+ children: empty ? /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9093
+ 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,
9075
9094
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
9076
- "span",
9095
+ Typography,
9077
9096
  {
9097
+ as: "span",
9078
9098
  className: cn(
9079
9099
  "absolute -bottom-1 -right-1 flex items-center justify-center",
9080
9100
  "min-w-[18px] h-[18px] rounded-full px-1",
@@ -9087,13 +9107,18 @@ function ItemSlot({
9087
9107
  }
9088
9108
  );
9089
9109
  }
9090
- var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9110
+ var sizeMap7, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9091
9111
  var init_ItemSlot = __esm({
9092
9112
  "components/game/2d/atoms/ItemSlot.tsx"() {
9093
9113
  "use client";
9094
9114
  init_cn();
9095
9115
  init_Icon();
9096
- sizeMap6 = {
9116
+ init_useEventBus();
9117
+ init_Button();
9118
+ init_Box();
9119
+ init_Typography();
9120
+ init_GameIcon();
9121
+ sizeMap7 = {
9097
9122
  sm: "w-10 h-10 text-lg",
9098
9123
  md: "w-14 h-14 text-2xl",
9099
9124
  lg: "w-18 h-18 text-3xl"
@@ -9134,9 +9159,9 @@ function TurnIndicator({
9134
9159
  size = "md",
9135
9160
  className
9136
9161
  }) {
9137
- const sizes = sizeMap7[size];
9162
+ const sizes = sizeMap8[size];
9138
9163
  return /* @__PURE__ */ jsxs(
9139
- "div",
9164
+ Box,
9140
9165
  {
9141
9166
  className: cn(
9142
9167
  "inline-flex items-center rounded-container",
@@ -9145,42 +9170,35 @@ function TurnIndicator({
9145
9170
  className
9146
9171
  ),
9147
9172
  children: [
9148
- /* @__PURE__ */ jsxs("span", { className: "font-bold tabular-nums", children: [
9173
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: "font-bold tabular-nums", children: [
9149
9174
  "Turn ",
9150
9175
  currentTurn,
9151
- maxTurns != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9176
+ maxTurns != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
9152
9177
  "/",
9153
9178
  maxTurns
9154
9179
  ] })
9155
9180
  ] }),
9156
9181
  phase && /* @__PURE__ */ jsxs(Fragment, { children: [
9157
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
9158
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: phase })
9182
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9183
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: phase })
9159
9184
  ] }),
9160
9185
  activeTeam && /* @__PURE__ */ jsxs(Fragment, { children: [
9161
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
9162
- assetUrl ? /* @__PURE__ */ jsx(
9163
- "img",
9164
- {
9165
- src: assetUrl.url,
9166
- alt: "",
9167
- width: 12,
9168
- height: 12,
9169
- style: { imageRendering: "pixelated", objectFit: "contain" },
9170
- className: "flex-shrink-0"
9171
- }
9172
- ) : /* @__PURE__ */ jsx("span", { className: cn("rounded-full bg-success/20", sizes.dot) }),
9173
- /* @__PURE__ */ jsx("span", { className: "text-success", children: activeTeam })
9186
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9187
+ 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) }),
9188
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-success", children: activeTeam })
9174
9189
  ] })
9175
9190
  ]
9176
9191
  }
9177
9192
  );
9178
9193
  }
9179
- var sizeMap7, DEFAULT_ASSET_URL6;
9194
+ var sizeMap8, DEFAULT_ASSET_URL6;
9180
9195
  var init_TurnIndicator = __esm({
9181
9196
  "components/game/2d/atoms/TurnIndicator.tsx"() {
9182
9197
  init_cn();
9183
- sizeMap7 = {
9198
+ init_Box();
9199
+ init_Typography();
9200
+ init_GameIcon();
9201
+ sizeMap8 = {
9184
9202
  sm: { wrapper: "text-xs gap-1.5 px-2 py-0.5", dot: "w-1.5 h-1.5" },
9185
9203
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
9186
9204
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
@@ -9212,10 +9230,10 @@ function ComboCounter({
9212
9230
  size = "md",
9213
9231
  className
9214
9232
  }) {
9215
- const sizes = sizeMap8[size];
9233
+ const sizes = sizeMap9[size];
9216
9234
  if (combo <= 0) return null;
9217
9235
  return /* @__PURE__ */ jsxs(
9218
- "div",
9236
+ Box,
9219
9237
  {
9220
9238
  className: cn(
9221
9239
  "inline-flex flex-col items-center justify-center",
@@ -9225,24 +9243,14 @@ function ComboCounter({
9225
9243
  className
9226
9244
  ),
9227
9245
  children: [
9228
- assetUrl && /* @__PURE__ */ jsx(
9229
- "img",
9230
- {
9231
- src: assetUrl.url,
9232
- alt: "combo",
9233
- width: 24,
9234
- height: 24,
9235
- style: { imageRendering: "pixelated", objectFit: "contain" },
9236
- className: "flex-shrink-0 mb-0.5"
9237
- }
9238
- ),
9239
- /* @__PURE__ */ jsx("span", { className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
9240
- /* @__PURE__ */ jsx("span", { className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
9241
- multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs("span", { className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
9246
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0 mb-0.5" }),
9247
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
9248
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
9249
+ multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
9242
9250
  "x",
9243
9251
  multiplier.toFixed(1)
9244
9252
  ] }),
9245
- streak != null && streak > 0 && /* @__PURE__ */ jsxs("span", { className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9253
+ streak != null && streak > 0 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9246
9254
  streak,
9247
9255
  " streak"
9248
9256
  ] })
@@ -9250,16 +9258,19 @@ function ComboCounter({
9250
9258
  }
9251
9259
  );
9252
9260
  }
9253
- var DEFAULT_ASSET_URL7, sizeMap8;
9261
+ var DEFAULT_ASSET_URL7, sizeMap9;
9254
9262
  var init_ComboCounter = __esm({
9255
9263
  "components/game/2d/atoms/ComboCounter.tsx"() {
9256
9264
  init_cn();
9265
+ init_Box();
9266
+ init_Typography();
9267
+ init_GameIcon();
9257
9268
  DEFAULT_ASSET_URL7 = {
9258
9269
  url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
9259
9270
  role: "effect",
9260
9271
  category: "effect"
9261
9272
  };
9262
- sizeMap8 = {
9273
+ sizeMap9 = {
9263
9274
  sm: { combo: "text-lg", label: "text-xs", multiplier: "text-xs" },
9264
9275
  md: { combo: "text-2xl", label: "text-xs", multiplier: "text-sm" },
9265
9276
  lg: { combo: "text-4xl", label: "text-sm", multiplier: "text-base" }
@@ -9276,54 +9287,48 @@ function WaypointMarker({
9276
9287
  size = "md",
9277
9288
  className
9278
9289
  }) {
9279
- const sizes = sizeMap9[size];
9280
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center", className), children: [
9281
- /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
9290
+ const sizes = sizeMap10[size];
9291
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col items-center", className), children: [
9292
+ /* @__PURE__ */ jsxs(Box, { className: "relative flex items-center justify-center", children: [
9282
9293
  active && /* @__PURE__ */ jsx(
9283
- "div",
9294
+ Box,
9284
9295
  {
9296
+ position: "absolute",
9285
9297
  className: cn(
9286
- "absolute rounded-full border-2 border-info animate-ping opacity-50",
9298
+ "rounded-full border-2 border-info animate-ping opacity-50",
9287
9299
  sizes.ring
9288
9300
  )
9289
9301
  }
9290
9302
  ),
9291
9303
  active && /* @__PURE__ */ jsx(
9292
- "div",
9304
+ Box,
9293
9305
  {
9306
+ position: "absolute",
9294
9307
  className: cn(
9295
- "absolute rounded-full border-2 border-info",
9308
+ "rounded-full border-2 border-info",
9296
9309
  sizes.ring
9297
9310
  )
9298
9311
  }
9299
9312
  ),
9300
9313
  /* @__PURE__ */ jsx(
9301
- "div",
9314
+ Box,
9302
9315
  {
9316
+ position: "relative",
9303
9317
  className: cn(
9304
- "relative flex items-center justify-center rounded-full transition-all duration-200",
9318
+ "flex items-center justify-center rounded-full transition-all duration-200",
9305
9319
  sizes.dot,
9306
9320
  completed && "bg-success text-foreground",
9307
9321
  active && !completed && "bg-info text-foreground",
9308
9322
  !active && !completed && "bg-muted"
9309
9323
  ),
9310
- children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsx(
9311
- "img",
9312
- {
9313
- src: assetUrl.url,
9314
- alt: label,
9315
- width: sizes.img,
9316
- height: sizes.img,
9317
- style: { imageRendering: "pixelated", objectFit: "contain" },
9318
- className: "flex-shrink-0"
9319
- }
9320
- ) : icon ? typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) : null
9324
+ 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
9321
9325
  }
9322
9326
  )
9323
9327
  ] }),
9324
9328
  label && /* @__PURE__ */ jsx(
9325
- "span",
9329
+ Typography,
9326
9330
  {
9331
+ as: "span",
9327
9332
  className: cn(
9328
9333
  "text-center whitespace-nowrap",
9329
9334
  sizes.label,
@@ -9334,17 +9339,20 @@ function WaypointMarker({
9334
9339
  )
9335
9340
  ] });
9336
9341
  }
9337
- var DEFAULT_ASSET_URL8, sizeMap9, checkIcon;
9342
+ var DEFAULT_ASSET_URL8, sizeMap10, checkIcon;
9338
9343
  var init_WaypointMarker = __esm({
9339
9344
  "components/game/2d/atoms/WaypointMarker.tsx"() {
9340
9345
  init_cn();
9341
9346
  init_Icon();
9347
+ init_Box();
9348
+ init_Typography();
9349
+ init_GameIcon();
9342
9350
  DEFAULT_ASSET_URL8 = {
9343
9351
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
9344
9352
  role: "ui",
9345
9353
  category: "waypoint"
9346
9354
  };
9347
- sizeMap9 = {
9355
+ sizeMap10 = {
9348
9356
  sm: { dot: "w-4 h-4", ring: "w-6 h-6", label: "text-xs mt-1", img: 12 },
9349
9357
  md: { dot: "w-6 h-6", ring: "w-8 h-8", label: "text-sm mt-1.5", img: 18 },
9350
9358
  lg: { dot: "w-8 h-8", ring: "w-10 h-10", label: "text-base mt-2", img: 24 }
@@ -9369,32 +9377,24 @@ function StatusEffect({
9369
9377
  size = "md",
9370
9378
  className
9371
9379
  }) {
9372
- const sizes = sizeMap10[size];
9373
- return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex flex-col items-center", className), children: [
9380
+ const sizes = sizeMap11[size];
9381
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn("inline-flex flex-col items-center", className), children: [
9374
9382
  /* @__PURE__ */ jsxs(
9375
- "div",
9383
+ Box,
9376
9384
  {
9385
+ position: "relative",
9377
9386
  className: cn(
9378
- "relative flex items-center justify-center rounded-interactive border-2",
9387
+ "flex items-center justify-center rounded-interactive border-2",
9379
9388
  sizes.container,
9380
9389
  variantStyles7[variant]
9381
9390
  ),
9382
9391
  title: label,
9383
9392
  children: [
9384
- /* @__PURE__ */ jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsx(
9385
- "img",
9386
- {
9387
- src: assetUrl.url,
9388
- alt: label,
9389
- width: sizes.img,
9390
- height: sizes.img,
9391
- style: { imageRendering: "pixelated", objectFit: "contain" },
9392
- className: "flex-shrink-0"
9393
- }
9394
- ) : icon != null && typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsx(Icon, { icon, size: "sm" }) : null }),
9393
+ /* @__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 }),
9395
9394
  duration !== void 0 && /* @__PURE__ */ jsx(
9396
- "span",
9395
+ Typography,
9397
9396
  {
9397
+ as: "span",
9398
9398
  className: cn(
9399
9399
  "absolute bottom-0 left-0 right-0 text-center font-mono font-bold text-foreground bg-background/60 leading-tight",
9400
9400
  sizes.timer
@@ -9406,8 +9406,9 @@ function StatusEffect({
9406
9406
  }
9407
9407
  ),
9408
9408
  stacks !== void 0 && stacks > 1 && /* @__PURE__ */ jsx(
9409
- "span",
9409
+ Typography,
9410
9410
  {
9411
+ as: "span",
9411
9412
  className: cn(
9412
9413
  "absolute flex items-center justify-center rounded-full bg-card text-foreground font-bold leading-none",
9413
9414
  sizes.badge
@@ -9415,20 +9416,23 @@ function StatusEffect({
9415
9416
  children: stacks
9416
9417
  }
9417
9418
  ),
9418
- label && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9419
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9419
9420
  ] });
9420
9421
  }
9421
- var DEFAULT_ASSET_URL9, sizeMap10, variantStyles7;
9422
+ var DEFAULT_ASSET_URL9, sizeMap11, variantStyles7;
9422
9423
  var init_StatusEffect = __esm({
9423
9424
  "components/game/2d/atoms/StatusEffect.tsx"() {
9424
9425
  init_cn();
9425
9426
  init_Icon();
9427
+ init_Box();
9428
+ init_Typography();
9429
+ init_GameIcon();
9426
9430
  DEFAULT_ASSET_URL9 = {
9427
9431
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
9428
9432
  role: "ui",
9429
9433
  category: "effect"
9430
9434
  };
9431
- sizeMap10 = {
9435
+ sizeMap11 = {
9432
9436
  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 },
9433
9437
  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 },
9434
9438
  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 }
@@ -9452,38 +9456,31 @@ function DamageNumber({
9452
9456
  return /* @__PURE__ */ jsxs(Fragment, { children: [
9453
9457
  /* @__PURE__ */ jsx("style", { children: floatKeyframes }),
9454
9458
  /* @__PURE__ */ jsxs(
9455
- "span",
9459
+ Typography,
9456
9460
  {
9461
+ as: "span",
9457
9462
  className: cn(
9458
9463
  "inline-flex items-center gap-0.5 font-mono select-none pointer-events-none",
9459
- sizeMap11[size],
9464
+ sizeMap12[size],
9460
9465
  typeStyles[type],
9461
9466
  className
9462
9467
  ),
9463
9468
  style: { animation: "damageFloat 1s ease-out forwards" },
9464
9469
  children: [
9465
- assetUrl && /* @__PURE__ */ jsx(
9466
- "img",
9467
- {
9468
- src: assetUrl.url,
9469
- alt: "",
9470
- width: 14,
9471
- height: 14,
9472
- style: { imageRendering: "pixelated", objectFit: "contain" },
9473
- className: "flex-shrink-0"
9474
- }
9475
- ),
9470
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 14, className: "flex-shrink-0" }),
9476
9471
  displayText
9477
9472
  ]
9478
9473
  }
9479
9474
  )
9480
9475
  ] });
9481
9476
  }
9482
- var sizeMap11, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
9477
+ var sizeMap12, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
9483
9478
  var init_DamageNumber = __esm({
9484
9479
  "components/game/2d/atoms/DamageNumber.tsx"() {
9485
9480
  init_cn();
9486
- sizeMap11 = {
9481
+ init_Typography();
9482
+ init_GameIcon();
9483
+ sizeMap12 = {
9487
9484
  sm: "text-sm",
9488
9485
  md: "text-lg",
9489
9486
  lg: "text-2xl"
@@ -9517,7 +9514,7 @@ function DialogueBubble({
9517
9514
  className
9518
9515
  }) {
9519
9516
  return /* @__PURE__ */ jsxs(
9520
- "div",
9517
+ Box,
9521
9518
  {
9522
9519
  className: cn(
9523
9520
  "flex items-start gap-3 rounded-container bg-background/80 backdrop-blur-sm px-4 py-3 border border-border/10",
@@ -9525,17 +9522,10 @@ function DialogueBubble({
9525
9522
  className
9526
9523
  ),
9527
9524
  children: [
9528
- portrait && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 w-12 h-12 rounded-full overflow-hidden border-2 border-warning/60", children: /* @__PURE__ */ jsx(
9529
- "img",
9530
- {
9531
- src: portrait?.url,
9532
- alt: speaker ?? "speaker",
9533
- className: "w-full h-full object-cover"
9534
- }
9535
- ) }),
9536
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
9537
- speaker && /* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-warning", children: speaker }),
9538
- /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground leading-relaxed", children: text })
9525
+ 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" }) }),
9526
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-1 min-w-0", children: [
9527
+ speaker && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm font-bold text-warning", children: speaker }),
9528
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm text-foreground leading-relaxed", children: text })
9539
9529
  ] })
9540
9530
  ]
9541
9531
  }
@@ -9545,6 +9535,9 @@ var DEFAULT_PORTRAIT;
9545
9535
  var init_DialogueBubble = __esm({
9546
9536
  "components/game/2d/atoms/DialogueBubble.tsx"() {
9547
9537
  init_cn();
9538
+ init_Box();
9539
+ init_Typography();
9540
+ init_GameIcon();
9548
9541
  DEFAULT_PORTRAIT = {
9549
9542
  url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
9550
9543
  role: "effect",
@@ -9561,14 +9554,19 @@ function ChoiceButton({
9561
9554
  disabled = false,
9562
9555
  selected = false,
9563
9556
  onClick,
9557
+ action,
9564
9558
  className
9565
9559
  }) {
9560
+ const eventBus = useEventBus();
9566
9561
  return /* @__PURE__ */ jsxs(
9567
- "button",
9562
+ Button,
9568
9563
  {
9569
- type: "button",
9564
+ variant: "ghost",
9570
9565
  disabled,
9571
- onClick,
9566
+ onClick: () => {
9567
+ if (action) eventBus.emit(`UI:${action}`, {});
9568
+ onClick?.();
9569
+ },
9572
9570
  className: cn(
9573
9571
  "w-full text-left px-4 py-2.5 rounded-interactive border transition-all duration-150",
9574
9572
  "flex items-center gap-2",
@@ -9578,8 +9576,9 @@ function ChoiceButton({
9578
9576
  ),
9579
9577
  children: [
9580
9578
  index !== void 0 && /* @__PURE__ */ jsxs(
9581
- "span",
9579
+ Typography,
9582
9580
  {
9581
+ as: "span",
9583
9582
  className: cn(
9584
9583
  "flex-shrink-0 font-mono font-bold text-sm",
9585
9584
  selected ? "text-accent" : "text-muted-foreground"
@@ -9590,24 +9589,14 @@ function ChoiceButton({
9590
9589
  ]
9591
9590
  }
9592
9591
  ),
9593
- assetUrl ? /* @__PURE__ */ jsx(
9594
- "img",
9595
- {
9596
- src: assetUrl.url,
9597
- alt: "",
9598
- width: 16,
9599
- height: 16,
9600
- style: { imageRendering: "pixelated", objectFit: "contain" },
9601
- className: "flex-shrink-0"
9602
- }
9603
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
9592
+ 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" ? (() => {
9604
9593
  const I = resolveIcon(icon);
9605
9594
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
9606
9595
  })() : /* @__PURE__ */ (() => {
9607
9596
  const I = icon;
9608
9597
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
9609
9598
  })() }) : null,
9610
- /* @__PURE__ */ jsx("span", { className: "text-sm leading-snug", children: text })
9599
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm leading-snug", children: text })
9611
9600
  ]
9612
9601
  }
9613
9602
  );
@@ -9616,6 +9605,11 @@ var init_ChoiceButton = __esm({
9616
9605
  "components/game/2d/atoms/ChoiceButton.tsx"() {
9617
9606
  init_cn();
9618
9607
  init_Icon();
9608
+ init_useEventBus();
9609
+ init_Button();
9610
+ init_Box();
9611
+ init_Typography();
9612
+ init_GameIcon();
9619
9613
  ChoiceButton.displayName = "ChoiceButton";
9620
9614
  }
9621
9615
  });
@@ -9629,18 +9623,23 @@ function ActionButton({
9629
9623
  size = "md",
9630
9624
  variant = "primary",
9631
9625
  onClick,
9626
+ action,
9632
9627
  className
9633
9628
  }) {
9634
- const sizes = sizeMap12[size];
9629
+ const eventBus = useEventBus();
9630
+ const sizes = sizeMap13[size];
9635
9631
  const onCooldown = cooldown > 0;
9636
9632
  const isDisabled = disabled || onCooldown;
9637
9633
  const cooldownDeg = Math.round(cooldown * 360);
9638
9634
  return /* @__PURE__ */ jsxs(
9639
- "button",
9635
+ Button,
9640
9636
  {
9641
- type: "button",
9637
+ variant: variant === "danger" ? "danger" : variant === "secondary" ? "secondary" : "primary",
9642
9638
  disabled: isDisabled,
9643
- onClick,
9639
+ onClick: () => {
9640
+ if (action) eventBus.emit(`UI:${action}`, {});
9641
+ onClick?.();
9642
+ },
9644
9643
  className: cn(
9645
9644
  "relative inline-flex items-center gap-1.5 rounded-interactive border font-medium overflow-hidden transition-colors duration-150",
9646
9645
  sizes.button,
@@ -9650,9 +9649,10 @@ function ActionButton({
9650
9649
  ),
9651
9650
  children: [
9652
9651
  onCooldown && /* @__PURE__ */ jsx(
9653
- "div",
9652
+ Box,
9654
9653
  {
9655
- className: "absolute inset-0 bg-foreground/40 pointer-events-none",
9654
+ position: "absolute",
9655
+ className: "inset-0 bg-foreground/40 pointer-events-none",
9656
9656
  style: {
9657
9657
  clipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
9658
9658
  WebkitClipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
@@ -9660,27 +9660,18 @@ function ActionButton({
9660
9660
  }
9661
9661
  }
9662
9662
  ),
9663
- assetUrl ? /* @__PURE__ */ jsx(
9664
- "img",
9665
- {
9666
- src: assetUrl.url,
9667
- alt: "",
9668
- width: 16,
9669
- height: 16,
9670
- style: { imageRendering: "pixelated", objectFit: "contain" },
9671
- className: cn("flex-shrink-0", sizes.icon)
9672
- }
9673
- ) : icon ? /* @__PURE__ */ jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
9663
+ 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" ? (() => {
9674
9664
  const I = resolveIcon(icon);
9675
9665
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
9676
9666
  })() : /* @__PURE__ */ (() => {
9677
9667
  const I = icon;
9678
9668
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
9679
9669
  })() }) : null,
9680
- /* @__PURE__ */ jsx("span", { className: "relative z-10", children: label }),
9670
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "relative z-10", children: label }),
9681
9671
  hotkey && /* @__PURE__ */ jsx(
9682
- "span",
9672
+ Typography,
9683
9673
  {
9674
+ as: "span",
9684
9675
  className: cn(
9685
9676
  "absolute top-0.5 right-0.5 bg-foreground/30 text-primary-foreground rounded font-mono leading-tight",
9686
9677
  sizes.hotkey
@@ -9692,12 +9683,17 @@ function ActionButton({
9692
9683
  }
9693
9684
  );
9694
9685
  }
9695
- var sizeMap12, variantStyles8, DEFAULT_ASSET_URL11;
9686
+ var sizeMap13, variantStyles8, DEFAULT_ASSET_URL11;
9696
9687
  var init_ActionButton = __esm({
9697
9688
  "components/game/2d/atoms/ActionButton.tsx"() {
9698
9689
  init_cn();
9699
9690
  init_Icon();
9700
- sizeMap12 = {
9691
+ init_useEventBus();
9692
+ init_Button();
9693
+ init_Box();
9694
+ init_Typography();
9695
+ init_GameIcon();
9696
+ sizeMap13 = {
9701
9697
  sm: { button: "h-button-sm px-3 text-xs", hotkey: "text-[9px] px-1", icon: "text-xs" },
9702
9698
  md: { button: "h-button-md px-4 text-sm", hotkey: "text-xs px-1.5", icon: "text-sm" },
9703
9699
  lg: { button: "h-button-lg px-5 text-base", hotkey: "text-xs px-2", icon: "text-base" }
@@ -9723,10 +9719,27 @@ function MiniMap({
9723
9719
  mapWidth = 100,
9724
9720
  mapHeight = 100,
9725
9721
  viewportRect = DEFAULT_VIEWPORT,
9726
- className
9722
+ className,
9723
+ tileAssets,
9724
+ unitAssets
9727
9725
  }) {
9728
- const canvasRef = React107.useRef(null);
9729
- React107.useEffect(() => {
9726
+ const canvasRef = React105.useRef(null);
9727
+ const imgCacheRef = React105.useRef(/* @__PURE__ */ new Map());
9728
+ function loadImg(url) {
9729
+ const cached = imgCacheRef.current.get(url);
9730
+ if (cached) return cached.complete ? cached : null;
9731
+ const img = new Image();
9732
+ img.src = url;
9733
+ img.onload = () => {
9734
+ const canvas = canvasRef.current;
9735
+ if (!canvas) return;
9736
+ const ctx = canvas.getContext("2d");
9737
+ if (ctx) ctx.clearRect(0, 0, 0, 0);
9738
+ };
9739
+ imgCacheRef.current.set(url, img);
9740
+ return null;
9741
+ }
9742
+ React105.useEffect(() => {
9730
9743
  const canvas = canvasRef.current;
9731
9744
  if (!canvas) return;
9732
9745
  const ctx = canvas.getContext("2d");
@@ -9737,20 +9750,31 @@ function MiniMap({
9737
9750
  ctx.fillStyle = "#111";
9738
9751
  ctx.fillRect(0, 0, width, height);
9739
9752
  for (const tile of tiles) {
9740
- ctx.fillStyle = tile.color;
9741
- ctx.fillRect(
9742
- Math.floor(tile.x * scaleX2),
9743
- Math.floor(tile.y * scaleY2),
9744
- Math.max(1, Math.ceil(scaleX2)),
9745
- Math.max(1, Math.ceil(scaleY2))
9746
- );
9753
+ const tileAsset = tileAssets?.[tile.color] ?? tileAssets?.["default"];
9754
+ const tileImg = tileAsset ? loadImg(tileAsset.url) : null;
9755
+ const tx = Math.floor(tile.x * scaleX2);
9756
+ const ty = Math.floor(tile.y * scaleY2);
9757
+ const tw = Math.max(1, Math.ceil(scaleX2));
9758
+ const th = Math.max(1, Math.ceil(scaleY2));
9759
+ if (tileImg) {
9760
+ ctx.drawImage(tileImg, tx, ty, tw, th);
9761
+ } else {
9762
+ ctx.fillStyle = tile.color;
9763
+ ctx.fillRect(tx, ty, tw, th);
9764
+ }
9747
9765
  }
9748
9766
  for (const unit of units) {
9749
9767
  if (unit.isPlayer) continue;
9750
- ctx.fillStyle = unit.color;
9768
+ const unitAsset = unitAssets?.[unit.color] ?? unitAssets?.["default"];
9769
+ const unitImg = unitAsset ? loadImg(unitAsset.url) : null;
9751
9770
  const ux = Math.floor(unit.x * scaleX2) - 1;
9752
9771
  const uy = Math.floor(unit.y * scaleY2) - 1;
9753
- ctx.fillRect(ux, uy, 3, 3);
9772
+ if (unitImg) {
9773
+ ctx.drawImage(unitImg, ux, uy, 5, 5);
9774
+ } else {
9775
+ ctx.fillStyle = unit.color;
9776
+ ctx.fillRect(ux, uy, 3, 3);
9777
+ }
9754
9778
  }
9755
9779
  if (viewportRect) {
9756
9780
  ctx.strokeStyle = "#ffffff";
@@ -9762,7 +9786,7 @@ function MiniMap({
9762
9786
  Math.floor(viewportRect.h * scaleY2)
9763
9787
  );
9764
9788
  }
9765
- }, [tiles, units, width, height, mapWidth, mapHeight, viewportRect]);
9789
+ }, [tiles, units, width, height, mapWidth, mapHeight, viewportRect, tileAssets, unitAssets]);
9766
9790
  const scaleX = width / mapWidth;
9767
9791
  const scaleY = height / mapHeight;
9768
9792
  const playerUnit = units.find((u) => u.isPlayer);
@@ -9771,10 +9795,12 @@ function MiniMap({
9771
9795
  return /* @__PURE__ */ jsxs(Fragment, { children: [
9772
9796
  /* @__PURE__ */ jsx("style", { children: `@keyframes minimap-blink{0%,49%{opacity:1}50%,100%{opacity:0}}` }),
9773
9797
  /* @__PURE__ */ jsxs(
9774
- "div",
9798
+ Box,
9775
9799
  {
9800
+ position: "relative",
9801
+ display: "inline-block",
9776
9802
  className: cn(
9777
- "relative inline-block border border-border/20 rounded-container",
9803
+ "border border-border/20 rounded-container",
9778
9804
  className
9779
9805
  ),
9780
9806
  children: [
@@ -9789,10 +9815,10 @@ function MiniMap({
9789
9815
  }
9790
9816
  ),
9791
9817
  playerLeft !== null && playerTop !== null && /* @__PURE__ */ jsx(
9792
- "div",
9818
+ Box,
9793
9819
  {
9820
+ position: "absolute",
9794
9821
  style: {
9795
- position: "absolute",
9796
9822
  left: playerLeft,
9797
9823
  top: playerTop,
9798
9824
  width: 3,
@@ -9813,6 +9839,7 @@ var init_MiniMap = __esm({
9813
9839
  "components/game/2d/atoms/MiniMap.tsx"() {
9814
9840
  "use client";
9815
9841
  init_cn();
9842
+ init_Box();
9816
9843
  DEFAULT_TILES = [
9817
9844
  { x: 10, y: 10, color: "#4ade80" },
9818
9845
  { x: 20, y: 15, color: "#4ade80" },
@@ -9830,38 +9857,6 @@ var init_MiniMap = __esm({
9830
9857
  MiniMap.displayName = "MiniMap";
9831
9858
  }
9832
9859
  });
9833
- function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
9834
- const px = typeof size === "number" ? size : sizeMap13[size];
9835
- if (assetUrl?.url) {
9836
- return /* @__PURE__ */ jsx(
9837
- "img",
9838
- {
9839
- src: assetUrl.url,
9840
- alt: alt ?? assetUrl.category ?? "",
9841
- width: px,
9842
- height: px,
9843
- style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
9844
- className: cn("flex-shrink-0", className)
9845
- }
9846
- );
9847
- }
9848
- const I = typeof icon === "string" ? resolveIcon(icon) : icon;
9849
- return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
9850
- }
9851
- var sizeMap13;
9852
- var init_GameIcon = __esm({
9853
- "components/game/2d/atoms/GameIcon.tsx"() {
9854
- "use client";
9855
- init_cn();
9856
- init_Icon();
9857
- sizeMap13 = {
9858
- sm: 16,
9859
- md: 24,
9860
- lg: 32
9861
- };
9862
- GameIcon.displayName = "GameIcon";
9863
- }
9864
- });
9865
9860
  function ControlGrid({
9866
9861
  kind,
9867
9862
  buttons = DEFAULT_BUTTONS,
@@ -9871,13 +9866,14 @@ function ControlGrid({
9871
9866
  actionEvent,
9872
9867
  onDirection,
9873
9868
  directionEvent,
9869
+ directionAssets,
9874
9870
  size = "md",
9875
9871
  disabled,
9876
9872
  className
9877
9873
  }) {
9878
9874
  const eventBus = useEventBus();
9879
- const [active, setActive] = React107.useState(/* @__PURE__ */ new Set());
9880
- const handlePress = React107.useCallback(
9875
+ const [active, setActive] = React105.useState(/* @__PURE__ */ new Set());
9876
+ const handlePress = React105.useCallback(
9881
9877
  (id) => {
9882
9878
  setActive((prev) => new Set(prev).add(id));
9883
9879
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -9889,7 +9885,7 @@ function ControlGrid({
9889
9885
  },
9890
9886
  [kind, actionEvent, directionEvent, eventBus, onAction, onDirection]
9891
9887
  );
9892
- const handleRelease = React107.useCallback(
9888
+ const handleRelease = React105.useCallback(
9893
9889
  (id) => {
9894
9890
  setActive((prev) => {
9895
9891
  const next = new Set(prev);
@@ -9910,7 +9906,8 @@ function ControlGrid({
9910
9906
  const dir = (d) => /* @__PURE__ */ jsx(
9911
9907
  ControlButton,
9912
9908
  {
9913
- icon: arrowIcons[d],
9909
+ icon: directionAssets?.[d] ? void 0 : arrowIcons[d],
9910
+ assetUrl: directionAssets?.[d],
9914
9911
  size: sizeKey[size],
9915
9912
  variant: "secondary",
9916
9913
  pressed: active.has(d),
@@ -9920,22 +9917,22 @@ function ControlGrid({
9920
9917
  },
9921
9918
  d
9922
9919
  );
9923
- return /* @__PURE__ */ jsxs("div", { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
9924
- /* @__PURE__ */ jsx("div", {}),
9920
+ return /* @__PURE__ */ jsxs(Box, { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
9921
+ /* @__PURE__ */ jsx(Box, {}),
9925
9922
  dir("up"),
9926
- /* @__PURE__ */ jsx("div", {}),
9923
+ /* @__PURE__ */ jsx(Box, {}),
9927
9924
  dir("left"),
9928
- /* @__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" }) }),
9925
+ /* @__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" }) }),
9929
9926
  dir("right"),
9930
- /* @__PURE__ */ jsx("div", {}),
9927
+ /* @__PURE__ */ jsx(Box, {}),
9931
9928
  dir("down"),
9932
- /* @__PURE__ */ jsx("div", {})
9929
+ /* @__PURE__ */ jsx(Box, {})
9933
9930
  ] });
9934
9931
  }
9935
9932
  if (layout === "diamond" && buttons.length === 4) {
9936
9933
  const [top, right, bottom, left] = buttons;
9937
- return /* @__PURE__ */ jsxs("div", { className: cn(layoutClass.diamond, className), children: [
9938
- /* @__PURE__ */ jsx("div", {}),
9934
+ return /* @__PURE__ */ jsxs(Box, { className: cn(layoutClass.diamond, className), children: [
9935
+ /* @__PURE__ */ jsx(Box, {}),
9939
9936
  /* @__PURE__ */ jsx(
9940
9937
  ControlButton,
9941
9938
  {
@@ -9950,7 +9947,7 @@ function ControlGrid({
9950
9947
  disabled
9951
9948
  }
9952
9949
  ),
9953
- /* @__PURE__ */ jsx("div", {}),
9950
+ /* @__PURE__ */ jsx(Box, {}),
9954
9951
  /* @__PURE__ */ jsx(
9955
9952
  ControlButton,
9956
9953
  {
@@ -9965,7 +9962,7 @@ function ControlGrid({
9965
9962
  disabled
9966
9963
  }
9967
9964
  ),
9968
- /* @__PURE__ */ jsx("div", {}),
9965
+ /* @__PURE__ */ jsx(Box, {}),
9969
9966
  /* @__PURE__ */ jsx(
9970
9967
  ControlButton,
9971
9968
  {
@@ -9980,7 +9977,7 @@ function ControlGrid({
9980
9977
  disabled
9981
9978
  }
9982
9979
  ),
9983
- /* @__PURE__ */ jsx("div", {}),
9980
+ /* @__PURE__ */ jsx(Box, {}),
9984
9981
  /* @__PURE__ */ jsx(
9985
9982
  ControlButton,
9986
9983
  {
@@ -9995,10 +9992,10 @@ function ControlGrid({
9995
9992
  disabled
9996
9993
  }
9997
9994
  ),
9998
- /* @__PURE__ */ jsx("div", {})
9995
+ /* @__PURE__ */ jsx(Box, {})
9999
9996
  ] });
10000
9997
  }
10001
- return /* @__PURE__ */ jsx("div", { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
9998
+ return /* @__PURE__ */ jsx(Box, { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
10002
9999
  ControlButton,
10003
10000
  {
10004
10001
  icon: button.icon,
@@ -10020,6 +10017,7 @@ var init_ControlGrid = __esm({
10020
10017
  "use client";
10021
10018
  init_cn();
10022
10019
  init_useEventBus();
10020
+ init_Box();
10023
10021
  init_ControlButton();
10024
10022
  sizeKey = { sm: "sm", md: "md", lg: "lg" };
10025
10023
  layoutClass = {
@@ -10064,7 +10062,7 @@ function StatBadge({
10064
10062
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
10065
10063
  const resolvedAsset = iconUrl ?? assetUrl;
10066
10064
  return /* @__PURE__ */ jsxs(
10067
- "div",
10065
+ Box,
10068
10066
  {
10069
10067
  className: cn(
10070
10068
  "inline-flex items-center gap-2 rounded-container border backdrop-blur-sm",
@@ -10073,18 +10071,8 @@ function StatBadge({
10073
10071
  className
10074
10072
  ),
10075
10073
  children: [
10076
- resolvedAsset ? /* @__PURE__ */ jsx(
10077
- "img",
10078
- {
10079
- src: resolvedAsset.url,
10080
- alt: "",
10081
- width: 16,
10082
- height: 16,
10083
- style: { imageRendering: "pixelated", objectFit: "contain" },
10084
- className: "flex-shrink-0"
10085
- }
10086
- ) : 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,
10087
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-medium", children: label }),
10074
+ 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,
10075
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground font-medium", children: label }),
10088
10076
  format === "hearts" && max && /* @__PURE__ */ jsx(
10089
10077
  HealthBar,
10090
10078
  {
@@ -10110,7 +10098,7 @@ function StatBadge({
10110
10098
  size: size === "lg" ? "md" : "sm"
10111
10099
  }
10112
10100
  ),
10113
- format === "text" && /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground", children: value })
10101
+ format === "text" && /* @__PURE__ */ jsx(Typography, { as: "span", className: "font-bold text-foreground", children: value })
10114
10102
  ]
10115
10103
  }
10116
10104
  );
@@ -10120,6 +10108,9 @@ var init_StatBadge = __esm({
10120
10108
  "components/game/2d/molecules/StatBadge.tsx"() {
10121
10109
  init_cn();
10122
10110
  init_Icon();
10111
+ init_Box();
10112
+ init_Typography();
10113
+ init_GameIcon();
10123
10114
  init_HealthBar();
10124
10115
  init_ScoreDisplay();
10125
10116
  sizeMap14 = {
@@ -10150,11 +10141,11 @@ function InventoryGrid({
10150
10141
  const eventBus = useEventBus();
10151
10142
  const slotCount = totalSlots ?? items.length;
10152
10143
  const emptySlotCount = Math.max(0, slotCount - items.length);
10153
- const handleSelect = React107.useCallback(
10144
+ const handleSelect = React105.useCallback(
10154
10145
  (id) => {
10155
10146
  onSelect?.(id);
10156
10147
  if (selectEvent) {
10157
- eventBus.emit(selectEvent, { id });
10148
+ eventBus.emit(`UI:${selectEvent}`, { id });
10158
10149
  }
10159
10150
  },
10160
10151
  [onSelect, selectEvent, eventBus]
@@ -10297,9 +10288,9 @@ function GameHud({
10297
10288
  if (position === "corners") {
10298
10289
  const leftStats = stats.slice(0, Math.ceil(stats.length / 2));
10299
10290
  const rightStats = stats.slice(Math.ceil(stats.length / 2));
10300
- return /* @__PURE__ */ jsxs("div", { className: cn("relative", positionMap[position], className), children: [
10301
- /* @__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)) }),
10302
- /* @__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)) })
10291
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn(positionMap[position], className), children: [
10292
+ /* @__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)) }),
10293
+ /* @__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)) })
10303
10294
  ] });
10304
10295
  }
10305
10296
  if (position === "top" || position === "bottom") {
@@ -10308,7 +10299,7 @@ function GameHud({
10308
10299
  const rightStats = stats.slice(mid);
10309
10300
  const isTop = position === "top";
10310
10301
  return /* @__PURE__ */ jsxs(
10311
- "div",
10302
+ Box,
10312
10303
  {
10313
10304
  className: cn(
10314
10305
  "flex items-center justify-between w-full",
@@ -10318,17 +10309,18 @@ function GameHud({
10318
10309
  className
10319
10310
  ),
10320
10311
  children: [
10321
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10322
- 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)) })
10312
+ /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10313
+ 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)) })
10323
10314
  ]
10324
10315
  }
10325
10316
  );
10326
10317
  }
10327
10318
  return /* @__PURE__ */ jsx(
10328
- "div",
10319
+ Box,
10329
10320
  {
10321
+ position: "relative",
10330
10322
  className: cn(
10331
- "relative z-10 flex items-center gap-4 px-4 py-2",
10323
+ "z-10 flex items-center gap-4 px-4 py-2",
10332
10324
  transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
10333
10325
  className
10334
10326
  ),
@@ -10340,6 +10332,7 @@ var positionMap, DEFAULT_HUD_STATS;
10340
10332
  var init_GameHud = __esm({
10341
10333
  "components/game/2d/molecules/GameHud.tsx"() {
10342
10334
  init_cn();
10335
+ init_Box();
10343
10336
  init_StatBadge();
10344
10337
  positionMap = {
10345
10338
  corners: "inset-0 pointer-events-none"
@@ -10359,34 +10352,28 @@ function GameMenu({
10359
10352
  options,
10360
10353
  menuItems,
10361
10354
  onSelect,
10362
- eventBus: eventBusProp,
10363
10355
  background,
10364
- logo = "",
10356
+ logo,
10365
10357
  className
10366
10358
  }) {
10367
10359
  const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
10368
- let eventBusFromHook = null;
10369
- try {
10370
- eventBusFromHook = useEventBus();
10371
- } catch {
10372
- }
10373
- const eventBus = eventBusProp || eventBusFromHook;
10374
- const handleOptionClick = React107.useCallback(
10360
+ const eventBus = useEventBus();
10361
+ const handleOptionClick = React105.useCallback(
10375
10362
  (option) => {
10376
- if (option.event && eventBus) {
10363
+ if (option.event) {
10377
10364
  eventBus.emit(`UI:${option.event}`, { option });
10378
10365
  }
10379
10366
  if (onSelect) {
10380
10367
  onSelect(option);
10381
10368
  }
10382
- if (option.navigatesTo && eventBus) {
10369
+ if (option.navigatesTo) {
10383
10370
  eventBus.emit("UI:NAVIGATE", { url: option.navigatesTo, option });
10384
10371
  }
10385
10372
  },
10386
10373
  [eventBus, onSelect]
10387
10374
  );
10388
10375
  return /* @__PURE__ */ jsxs(
10389
- "div",
10376
+ Box,
10390
10377
  {
10391
10378
  className: cn(
10392
10379
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
@@ -10396,18 +10383,12 @@ function GameMenu({
10396
10383
  background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
10397
10384
  },
10398
10385
  children: [
10399
- /* @__PURE__ */ jsxs("div", { className: "text-center mb-12 animate-fade-in", children: [
10400
- logo && /* @__PURE__ */ jsx(
10401
- "img",
10402
- {
10403
- src: logo,
10404
- alt: title,
10405
- className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl"
10406
- }
10407
- ),
10386
+ /* @__PURE__ */ jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
10387
+ logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
10408
10388
  /* @__PURE__ */ jsx(
10409
- "h1",
10389
+ Typography,
10410
10390
  {
10391
+ variant: "h1",
10411
10392
  className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
10412
10393
  style: {
10413
10394
  textShadow: "0 4px 12px rgba(0,0,0,0.5)"
@@ -10415,9 +10396,9 @@ function GameMenu({
10415
10396
  children: title
10416
10397
  }
10417
10398
  ),
10418
- subtitle && /* @__PURE__ */ jsx("p", { className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
10399
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
10419
10400
  ] }),
10420
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
10401
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
10421
10402
  ChoiceButton,
10422
10403
  {
10423
10404
  text: option.label,
@@ -10428,9 +10409,9 @@ function GameMenu({
10428
10409
  },
10429
10410
  index
10430
10411
  )) }),
10431
- /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 pointer-events-none overflow-hidden", children: [
10432
- /* @__PURE__ */ jsx("div", { className: "absolute top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
10433
- /* @__PURE__ */ jsx("div", { className: "absolute bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
10412
+ /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
10413
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
10414
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
10434
10415
  ] })
10435
10416
  ]
10436
10417
  }
@@ -10442,6 +10423,9 @@ var init_GameMenu = __esm({
10442
10423
  "use client";
10443
10424
  init_cn();
10444
10425
  init_useEventBus();
10426
+ init_Box();
10427
+ init_Typography();
10428
+ init_GameIcon();
10445
10429
  init_ChoiceButton();
10446
10430
  DEFAULT_MENU_OPTIONS = [
10447
10431
  { label: "New Game", event: "NEW_GAME", variant: "primary" },
@@ -11861,10 +11845,11 @@ function Canvas2D({
11861
11845
  }
11862
11846
  }
11863
11847
  ),
11864
- process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs("div", { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
11848
+ process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs(Box, { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
11865
11849
  tileClickEvent && /* @__PURE__ */ jsx(
11866
- "button",
11850
+ Button,
11867
11851
  {
11852
+ variant: "ghost",
11868
11853
  "data-event": tileClickEvent,
11869
11854
  "data-x": "0",
11870
11855
  "data-y": "0",
@@ -11873,8 +11858,9 @@ function Canvas2D({
11873
11858
  }
11874
11859
  ),
11875
11860
  unitClickEvent && units && units.length > 0 && /* @__PURE__ */ jsx(
11876
- "button",
11861
+ Button,
11877
11862
  {
11863
+ variant: "ghost",
11878
11864
  "data-event": unitClickEvent,
11879
11865
  "data-unit-id": units[0].id,
11880
11866
  onClick: () => eventBus.emit(`UI:${unitClickEvent}`, { unitId: units[0].id }),
@@ -11883,15 +11869,17 @@ function Canvas2D({
11883
11869
  )
11884
11870
  ] }),
11885
11871
  unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxs(
11886
- "div",
11872
+ Box,
11887
11873
  {
11888
- className: "absolute pointer-events-none",
11874
+ position: "absolute",
11875
+ className: "pointer-events-none",
11889
11876
  style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
11890
11877
  children: [
11891
11878
  unit.name && /* @__PURE__ */ jsx(
11892
- "div",
11879
+ Typography,
11893
11880
  {
11894
- className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
11881
+ as: "span",
11882
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap block",
11895
11883
  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)" },
11896
11884
  children: unit.name
11897
11885
  }
@@ -11901,7 +11889,7 @@ function Canvas2D({
11901
11889
  },
11902
11890
  unit.id
11903
11891
  )),
11904
- showMinimap && /* @__PURE__ */ jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
11892
+ showMinimap && /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
11905
11893
  MiniMap,
11906
11894
  {
11907
11895
  tiles: miniMapTiles,
@@ -11923,6 +11911,7 @@ var init_Canvas2D = __esm({
11923
11911
  init_cn();
11924
11912
  init_useEventBus();
11925
11913
  init_Box();
11914
+ init_Button();
11926
11915
  init_Stack();
11927
11916
  init_Icon();
11928
11917
  init_Typography();
@@ -12234,7 +12223,9 @@ var init_GameAudioProvider = __esm({
12234
12223
  });
12235
12224
  function GameAudioToggle({
12236
12225
  size = "sm",
12237
- className
12226
+ className,
12227
+ onAsset,
12228
+ offAsset
12238
12229
  }) {
12239
12230
  const ctx = useGameAudioContextOptional();
12240
12231
  const [localMuted, setLocalMuted] = useState(false);
@@ -12243,6 +12234,7 @@ function GameAudioToggle({
12243
12234
  const handleToggle = useCallback(() => {
12244
12235
  setMuted(!muted);
12245
12236
  }, [muted, setMuted]);
12237
+ const activeAsset = muted ? offAsset : onAsset;
12246
12238
  return /* @__PURE__ */ jsx(
12247
12239
  Button,
12248
12240
  {
@@ -12251,7 +12243,7 @@ function GameAudioToggle({
12251
12243
  onClick: handleToggle,
12252
12244
  className: cn("text-lg leading-none px-2", className),
12253
12245
  "aria-pressed": muted,
12254
- children: muted ? "\u{1F507}" : "\u{1F50A}"
12246
+ 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}"
12255
12247
  }
12256
12248
  );
12257
12249
  }
@@ -12261,6 +12253,7 @@ var init_GameAudioToggle = __esm({
12261
12253
  init_atoms();
12262
12254
  init_cn();
12263
12255
  init_GameAudioProvider();
12256
+ init_GameIcon();
12264
12257
  GameAudioToggle.displayName = "GameAudioToggle";
12265
12258
  }
12266
12259
  });
@@ -13543,6 +13536,7 @@ function PlatformerBoard({
13543
13536
  canvasHeight: _canvasHeight = 400,
13544
13537
  playerSprite,
13545
13538
  tileSprites,
13539
+ ui: _ui,
13546
13540
  bgColor: _bgColor,
13547
13541
  keyEvent = "KEY",
13548
13542
  playAgainEvent = "PLAY_AGAIN",
@@ -15401,6 +15395,7 @@ function TanksBoard({
15401
15395
  features,
15402
15396
  assetManifest,
15403
15397
  assetBaseUrl,
15398
+ ui: _ui,
15404
15399
  scale = 0.45,
15405
15400
  showMinimap = true,
15406
15401
  enableCamera = true,
@@ -15928,7 +15923,7 @@ function LinearView({
15928
15923
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
15929
15924
  const isDone = i < currentIdx;
15930
15925
  const isCurrent = i === currentIdx;
15931
- return /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
15926
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
15932
15927
  i > 0 && /* @__PURE__ */ jsx(
15933
15928
  Typography,
15934
15929
  {
@@ -16149,7 +16144,7 @@ function TraitSlot({
16149
16144
  size = "md",
16150
16145
  showTooltip = true,
16151
16146
  categoryColors,
16152
- tooltipFrameUrl = "",
16147
+ tooltipFrameUrl,
16153
16148
  className,
16154
16149
  feedback,
16155
16150
  onItemDrop,
@@ -16279,7 +16274,7 @@ function TraitSlot({
16279
16274
  as: "img",
16280
16275
  className: "object-contain",
16281
16276
  style: { width: config.icon, height: config.icon },
16282
- ...{ src: equippedItem.iconUrl, alt: equippedItem.name }
16277
+ ...{ src: equippedItem.iconUrl.url, alt: equippedItem.name }
16283
16278
  }
16284
16279
  ) : /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-center leading-none", style: { fontSize: config.icon }, children: equippedItem.iconEmoji || "\u2726" }),
16285
16280
  (onRemove || removeEvent) && /* @__PURE__ */ jsx(
@@ -16308,7 +16303,7 @@ function TraitSlot({
16308
16303
  ...getTooltipStyle(),
16309
16304
  minWidth: 200,
16310
16305
  ...tooltipFrameUrl ? {
16311
- borderImage: `url(${tooltipFrameUrl}) 60 fill / 15px / 0 stretch`,
16306
+ borderImage: `url(${tooltipFrameUrl.url}) 60 fill / 15px / 0 stretch`,
16312
16307
  border: "none"
16313
16308
  } : {}
16314
16309
  },
@@ -16383,7 +16378,7 @@ function ActionTile({
16383
16378
  draggable: !disabled,
16384
16379
  onDragStart: handleDragStart,
16385
16380
  children: [
16386
- action.iconUrl ? /* @__PURE__ */ jsx("img", { src: action.iconUrl, alt: "", className: "w-8 h-8 object-contain" }) : /* @__PURE__ */ jsx(Typography, { variant: "body1", className: cn(config.icon, "leading-none"), children: action.iconEmoji || "\u2726" }),
16381
+ action.iconUrl ? /* @__PURE__ */ jsx("img", { src: action.iconUrl.url, alt: "", className: "w-8 h-8 object-contain" }) : /* @__PURE__ */ jsx(Typography, { variant: "body1", className: cn(config.icon, "leading-none"), children: action.iconEmoji || "\u2726" }),
16387
16382
  /* @__PURE__ */ jsx(Typography, { variant: "caption", className: cn(config.text, "text-foreground font-medium whitespace-nowrap"), children: action.name })
16388
16383
  ]
16389
16384
  }
@@ -16456,7 +16451,7 @@ function SequenceBar({
16456
16451
  onSlotRemove(index);
16457
16452
  }, [onSlotRemove, playing]);
16458
16453
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
16459
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
16454
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
16460
16455
  i > 0 && /* @__PURE__ */ jsx(
16461
16456
  Typography,
16462
16457
  {
@@ -16507,6 +16502,42 @@ function computeSlotFeedback(playerSeq, solutions) {
16507
16502
  (id, i) => id !== void 0 && id === bestSolution[i] ? "correct" : "wrong"
16508
16503
  );
16509
16504
  }
16505
+ function isFieldRecord(v) {
16506
+ return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
16507
+ }
16508
+ function assetFromField(v) {
16509
+ if (!isFieldRecord(v)) return void 0;
16510
+ const url = typeof v.url === "string" ? v.url : void 0;
16511
+ const role = typeof v.role === "string" ? v.role : void 0;
16512
+ const category = typeof v.category === "string" ? v.category : "";
16513
+ if (!url || !role) return void 0;
16514
+ return {
16515
+ url,
16516
+ role,
16517
+ category,
16518
+ name: typeof v.name === "string" ? v.name : void 0,
16519
+ thumbnailUrl: typeof v.thumbnailUrl === "string" ? v.thumbnailUrl : void 0,
16520
+ style: typeof v.style === "string" ? v.style : void 0,
16521
+ variant: typeof v.variant === "string" ? v.variant : void 0,
16522
+ dimension: typeof v.dimension === "string" ? v.dimension : void 0,
16523
+ aspect: typeof v.aspect === "string" ? v.aspect : void 0
16524
+ };
16525
+ }
16526
+ function slotItemFromField(fv) {
16527
+ if (!isFieldRecord(fv)) return void 0;
16528
+ const id = typeof fv.id === "string" ? fv.id : void 0;
16529
+ const name = typeof fv.name === "string" ? fv.name : void 0;
16530
+ const category = typeof fv.category === "string" ? fv.category : void 0;
16531
+ if (!id || !name || !category) return void 0;
16532
+ return {
16533
+ id,
16534
+ name,
16535
+ category,
16536
+ description: typeof fv.description === "string" ? fv.description : void 0,
16537
+ iconEmoji: typeof fv.iconEmoji === "string" ? fv.iconEmoji : void 0,
16538
+ iconUrl: assetFromField(fv.iconUrl)
16539
+ };
16540
+ }
16510
16541
  function SequencerBoard({
16511
16542
  entity,
16512
16543
  categoryColors,
@@ -16517,6 +16548,7 @@ function SequencerBoard({
16517
16548
  removeEvent,
16518
16549
  checkEvent,
16519
16550
  playAgainEvent,
16551
+ stepEvent,
16520
16552
  className
16521
16553
  }) {
16522
16554
  const { emit } = useEventBus();
@@ -16524,7 +16556,11 @@ function SequencerBoard({
16524
16556
  const resolved = boardEntity(entity);
16525
16557
  const maxSlots = num(resolved?.maxSlots) || 3;
16526
16558
  const solutions = Array.isArray(resolved?.solutions) ? resolved.solutions : [];
16527
- const availableActions = Array.isArray(resolved?.availableActions) ? resolved.availableActions : [];
16559
+ const availableActions = (Array.isArray(resolved?.availableActions) ? resolved.availableActions : []).reduce((acc, fv) => {
16560
+ const item = slotItemFromField(fv);
16561
+ if (item) acc.push(item);
16562
+ return acc;
16563
+ }, []);
16528
16564
  const allowDuplicates = resolved?.allowDuplicates !== false;
16529
16565
  const entitySlots = Array.isArray(resolved?.slots) ? resolved.slots : [];
16530
16566
  const entityResult = str(resolved?.result);
@@ -16582,7 +16618,7 @@ function SequencerBoard({
16582
16618
  let step = 0;
16583
16619
  const advance = () => {
16584
16620
  step++;
16585
- emit("UI:STEP", { step });
16621
+ if (stepEvent) emit(`UI:${stepEvent}`, { step });
16586
16622
  if (step >= maxSlots) {
16587
16623
  if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
16588
16624
  const playerSeq = slots.map((s) => s?.id);
@@ -18807,35 +18843,7 @@ var init_SimulationCanvas = __esm({
18807
18843
  SimulationCanvas.displayName = "SimulationCanvas";
18808
18844
  }
18809
18845
  });
18810
- function getSlotContentRenderer2() {
18811
- if (_scr) return _scr;
18812
- const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
18813
- _scr = mod.SlotContentRenderer;
18814
- return _scr;
18815
- }
18816
- function resolveDescriptor(value, idPrefix) {
18817
- if (value === null || value === void 0) return value;
18818
- if (React107__default.isValidElement(value)) return value;
18819
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
18820
- if (Array.isArray(value)) {
18821
- return value.map((item, i) => /* @__PURE__ */ jsx(React107__default.Fragment, { children: resolveDescriptor(item, `${idPrefix}-${i}`) }, i));
18822
- }
18823
- if (typeof value === "object") {
18824
- const rec = value;
18825
- if (typeof rec.type === "string" && getComponentForPattern(rec.type) !== null) {
18826
- const type = rec.type;
18827
- const _id = typeof rec._id === "string" ? rec._id : void 0;
18828
- const nestedProps = rec.props !== void 0 && typeof rec.props === "object" && !Array.isArray(rec.props) && rec.props !== null ? rec.props : void 0;
18829
- const { type: _t, props: _p, _id: _d, ...flatRest } = rec;
18830
- const resolvedProps = nestedProps !== void 0 ? nestedProps : flatRest;
18831
- const content = { id: _id ?? idPrefix, pattern: type, props: resolvedProps, priority: 0 };
18832
- const SCR = getSlotContentRenderer2();
18833
- return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 });
18834
- }
18835
- }
18836
- return null;
18837
- }
18838
- var _scr, GameTemplate;
18846
+ var GameTemplate;
18839
18847
  var init_GameTemplate = __esm({
18840
18848
  "components/game/2d/templates/GameTemplate.tsx"() {
18841
18849
  init_cn();
@@ -18843,7 +18851,6 @@ var init_GameTemplate = __esm({
18843
18851
  init_Stack();
18844
18852
  init_Typography();
18845
18853
  init_Button();
18846
- _scr = null;
18847
18854
  GameTemplate = ({
18848
18855
  entity,
18849
18856
  title = "Game",
@@ -18852,7 +18859,8 @@ var init_GameTemplate = __esm({
18852
18859
  debugPanel,
18853
18860
  showDebugPanel = false,
18854
18861
  controls,
18855
- className
18862
+ className,
18863
+ backgroundAsset
18856
18864
  }) => {
18857
18865
  return /* @__PURE__ */ jsxs(
18858
18866
  Box,
@@ -18909,15 +18917,16 @@ var init_GameTemplate = __esm({
18909
18917
  {
18910
18918
  position: "relative",
18911
18919
  fullWidth: true,
18912
- className: "flex-1 bg-muted",
18920
+ className: backgroundAsset ? "flex-1" : "flex-1 bg-muted",
18921
+ style: backgroundAsset ? { backgroundImage: `url(${backgroundAsset.url})`, backgroundSize: "cover", backgroundPosition: "center" } : void 0,
18913
18922
  children: [
18914
- resolveDescriptor(children, "gt-children"),
18923
+ children,
18915
18924
  hud && /* @__PURE__ */ jsx(
18916
18925
  Box,
18917
18926
  {
18918
18927
  position: "absolute",
18919
18928
  className: "top-0 left-0 right-0 pointer-events-none",
18920
- children: /* @__PURE__ */ jsx(Box, { padding: "md", className: "pointer-events-auto w-fit", children: resolveDescriptor(hud, "gt-hud") })
18929
+ children: /* @__PURE__ */ jsx(Box, { padding: "md", className: "pointer-events-auto w-fit", children: hud })
18921
18930
  }
18922
18931
  )
18923
18932
  ]
@@ -18942,7 +18951,7 @@ var init_GameTemplate = __esm({
18942
18951
  children: /* @__PURE__ */ jsx(Typography, { variant: "h6", children: "Debug Panel" })
18943
18952
  }
18944
18953
  ),
18945
- /* @__PURE__ */ jsx(Box, { padding: "md", children: resolveDescriptor(debugPanel, "gt-debug") })
18954
+ /* @__PURE__ */ jsx(Box, { padding: "md", children: debugPanel })
18946
18955
  ]
18947
18956
  }
18948
18957
  )
@@ -18953,59 +18962,21 @@ var init_GameTemplate = __esm({
18953
18962
  GameTemplate.displayName = "GameTemplate";
18954
18963
  }
18955
18964
  });
18956
- function asDescriptor(v) {
18957
- if (Array.isArray(v) || React107__default.isValidElement(v)) return null;
18958
- const o = v;
18959
- if (typeof o.type !== "string") return null;
18960
- const props = o.props !== void 0 && typeof o.props === "object" && !Array.isArray(o.props) && o.props !== null ? o.props : void 0;
18961
- const _id = typeof o._id === "string" ? o._id : void 0;
18962
- const sourceTrait = typeof o.sourceTrait === "string" ? o.sourceTrait : void 0;
18963
- return { type: o.type, props, _id, sourceTrait };
18964
- }
18965
- function getSlotContentRenderer3() {
18966
- if (_scr2) return _scr2;
18967
- const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
18968
- _scr2 = mod.SlotContentRenderer;
18969
- return _scr2;
18970
- }
18971
- function resolveDescriptor2(value, idPrefix) {
18972
- if (value === null || value === void 0) return value;
18973
- if (React107__default.isValidElement(value)) return value;
18974
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
18975
- if (Array.isArray(value)) {
18976
- return value.map((item, i) => /* @__PURE__ */ jsx(React107__default.Fragment, { children: resolveDescriptor2(item, `${idPrefix}-${i}`) }, i));
18977
- }
18978
- if (typeof value === "object" && value !== null) {
18979
- const desc = asDescriptor(value);
18980
- if (desc !== null && getComponentForPattern(desc.type) !== null) {
18981
- const resolvedProps = desc.props ?? {};
18982
- const content = {
18983
- id: desc._id ?? idPrefix,
18984
- pattern: desc.type,
18985
- props: resolvedProps,
18986
- priority: 0,
18987
- ...desc.sourceTrait !== void 0 && { sourceTrait: desc.sourceTrait }
18988
- };
18989
- const SCR = getSlotContentRenderer3();
18990
- return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 }, content.id);
18991
- }
18992
- }
18993
- return null;
18994
- }
18995
- var _scr2, GameShell;
18965
+ var GameShell;
18996
18966
  var init_GameShell = __esm({
18997
18967
  "components/game/2d/templates/GameShell.tsx"() {
18998
18968
  init_cn();
18999
18969
  init_Box();
19000
18970
  init_Stack();
19001
18971
  init_Typography();
19002
- _scr2 = null;
19003
18972
  GameShell = ({
19004
18973
  appName = "Game",
19005
18974
  hud,
19006
18975
  className,
19007
18976
  showTopBar = true,
19008
- children
18977
+ children,
18978
+ backgroundAsset,
18979
+ hudBackgroundAsset
19009
18980
  }) => {
19010
18981
  return /* @__PURE__ */ jsxs(
19011
18982
  Box,
@@ -19020,7 +18991,7 @@ var init_GameShell = __esm({
19020
18991
  width: "100vw",
19021
18992
  height: "100vh",
19022
18993
  overflow: "hidden",
19023
- background: "var(--color-background, #0a0a0f)",
18994
+ background: backgroundAsset ? `url(${backgroundAsset.url}) center/cover no-repeat` : "var(--color-background, #0a0a0f)",
19024
18995
  color: "var(--color-text, #e0e0e0)"
19025
18996
  },
19026
18997
  children: [
@@ -19030,7 +19001,7 @@ var init_GameShell = __esm({
19030
19001
  className: "game-shell__header",
19031
19002
  style: {
19032
19003
  flexShrink: 0,
19033
- background: "var(--color-surface, #12121f)",
19004
+ background: hudBackgroundAsset ? `url(${hudBackgroundAsset.url}) center/cover no-repeat` : "var(--color-surface, #12121f)",
19034
19005
  borderBottom: "1px solid var(--color-border, #2a2a3a)"
19035
19006
  },
19036
19007
  children: [
@@ -19053,7 +19024,7 @@ var init_GameShell = __esm({
19053
19024
  )
19054
19025
  }
19055
19026
  ),
19056
- hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud", style: { width: "100%" }, children: resolveDescriptor2(hud, "gs-hud") })
19027
+ hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud", style: { width: "100%" }, children: hud })
19057
19028
  ]
19058
19029
  }
19059
19030
  ),
@@ -19066,7 +19037,7 @@ var init_GameShell = __esm({
19066
19037
  overflow: "hidden",
19067
19038
  position: "relative"
19068
19039
  },
19069
- children: resolveDescriptor2(children, "gs-children")
19040
+ children
19070
19041
  }
19071
19042
  )
19072
19043
  ]
@@ -20273,7 +20244,7 @@ var init_ErrorBoundary = __esm({
20273
20244
  }
20274
20245
  );
20275
20246
  };
20276
- ErrorBoundary = class extends React107__default.Component {
20247
+ ErrorBoundary = class extends React105__default.Component {
20277
20248
  constructor(props) {
20278
20249
  super(props);
20279
20250
  __publicField(this, "reset", () => {
@@ -20938,7 +20909,7 @@ var init_Container = __esm({
20938
20909
  as: Component = "div"
20939
20910
  }) => {
20940
20911
  const resolvedSize = maxWidth ?? size ?? "lg";
20941
- return React107__default.createElement(
20912
+ return React105__default.createElement(
20942
20913
  Component,
20943
20914
  {
20944
20915
  className: cn(
@@ -23120,9 +23091,9 @@ var init_BiologyCanvas = __esm({
23120
23091
  }
23121
23092
  });
23122
23093
 
23123
- // node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css
23094
+ // node_modules/katex/dist/katex.min.css
23124
23095
  var init_katex_min = __esm({
23125
- "node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css"() {
23096
+ "node_modules/katex/dist/katex.min.css"() {
23126
23097
  }
23127
23098
  });
23128
23099
  var Tabs;
@@ -23562,7 +23533,7 @@ var init_CodeBlock = __esm({
23562
23533
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
23563
23534
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
23564
23535
  HIDDEN_LINE_NUMBERS = { display: "none" };
23565
- CodeBlock = React107__default.memo(
23536
+ CodeBlock = React105__default.memo(
23566
23537
  ({
23567
23538
  code: rawCode,
23568
23539
  language = "text",
@@ -24149,7 +24120,7 @@ var init_MarkdownContent = __esm({
24149
24120
  init_Box();
24150
24121
  init_CodeBlock();
24151
24122
  init_cn();
24152
- MarkdownContent = React107__default.memo(
24123
+ MarkdownContent = React105__default.memo(
24153
24124
  ({ content, direction = "ltr", className }) => {
24154
24125
  const { t: _t } = useTranslate();
24155
24126
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -25476,7 +25447,7 @@ var init_StateMachineView = __esm({
25476
25447
  style: { top: title ? 30 : 0 },
25477
25448
  children: [
25478
25449
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
25479
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React107__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
25450
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React105__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
25480
25451
  StateNode2,
25481
25452
  {
25482
25453
  state,
@@ -30079,6 +30050,8 @@ function CounterMinimal({
30079
30050
  size = "md",
30080
30051
  onDecrement,
30081
30052
  onIncrement,
30053
+ decrementEvent,
30054
+ incrementEvent,
30082
30055
  className
30083
30056
  }) {
30084
30057
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
@@ -30089,6 +30062,7 @@ function CounterMinimal({
30089
30062
  {
30090
30063
  variant: "secondary",
30091
30064
  size: sizeStyles8[size].button,
30065
+ action: decrementEvent,
30092
30066
  onClick: onDecrement,
30093
30067
  disabled: resolved.decrementDisabled,
30094
30068
  icon: "minus",
@@ -30111,6 +30085,7 @@ function CounterMinimal({
30111
30085
  {
30112
30086
  variant: "secondary",
30113
30087
  size: sizeStyles8[size].button,
30088
+ action: incrementEvent,
30114
30089
  onClick: onIncrement,
30115
30090
  disabled: resolved.incrementDisabled,
30116
30091
  icon: "plus",
@@ -30127,6 +30102,9 @@ function CounterStandard({
30127
30102
  onDecrement,
30128
30103
  onIncrement,
30129
30104
  onReset,
30105
+ decrementEvent,
30106
+ incrementEvent,
30107
+ resetEvent,
30130
30108
  className
30131
30109
  }) {
30132
30110
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
@@ -30157,6 +30135,7 @@ function CounterStandard({
30157
30135
  {
30158
30136
  variant: "secondary",
30159
30137
  size: sizeStyles8[size].button,
30138
+ action: decrementEvent,
30160
30139
  onClick: onDecrement,
30161
30140
  disabled: resolved.decrementDisabled,
30162
30141
  icon: "minus"
@@ -30167,6 +30146,7 @@ function CounterStandard({
30167
30146
  {
30168
30147
  variant: "primary",
30169
30148
  size: sizeStyles8[size].button,
30149
+ action: incrementEvent,
30170
30150
  onClick: onIncrement,
30171
30151
  disabled: resolved.incrementDisabled,
30172
30152
  icon: "plus"
@@ -30178,6 +30158,7 @@ function CounterStandard({
30178
30158
  {
30179
30159
  variant: "ghost",
30180
30160
  size: "sm",
30161
+ action: resetEvent,
30181
30162
  onClick: onReset,
30182
30163
  icon: "rotate-ccw",
30183
30164
  children: "Reset"
@@ -30193,6 +30174,9 @@ function CounterFull({
30193
30174
  onDecrement,
30194
30175
  onIncrement,
30195
30176
  onReset,
30177
+ decrementEvent,
30178
+ incrementEvent,
30179
+ resetEvent,
30196
30180
  className
30197
30181
  }) {
30198
30182
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
@@ -30226,6 +30210,7 @@ function CounterFull({
30226
30210
  {
30227
30211
  variant: "secondary",
30228
30212
  size: sizeStyles8[size].button,
30213
+ action: decrementEvent,
30229
30214
  onClick: onDecrement,
30230
30215
  disabled: resolved.decrementDisabled,
30231
30216
  icon: "minus",
@@ -30237,6 +30222,7 @@ function CounterFull({
30237
30222
  {
30238
30223
  variant: "primary",
30239
30224
  size: sizeStyles8[size].button,
30225
+ action: incrementEvent,
30240
30226
  onClick: onIncrement,
30241
30227
  disabled: resolved.incrementDisabled,
30242
30228
  icon: "plus",
@@ -30249,6 +30235,7 @@ function CounterFull({
30249
30235
  {
30250
30236
  variant: "ghost",
30251
30237
  size: "sm",
30238
+ action: resetEvent,
30252
30239
  onClick: onReset,
30253
30240
  icon: "rotate-ccw",
30254
30241
  children: "Reset to 0"
@@ -31098,8 +31085,8 @@ var init_Menu = __esm({
31098
31085
  "bottom-end": "bottom-start"
31099
31086
  };
31100
31087
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
31101
- const triggerChild = React107__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
31102
- const triggerElement = React107__default.cloneElement(
31088
+ const triggerChild = React105__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
31089
+ const triggerElement = React105__default.cloneElement(
31103
31090
  triggerChild,
31104
31091
  {
31105
31092
  ref: triggerRef,
@@ -31194,14 +31181,14 @@ function useDataDnd(args) {
31194
31181
  const isZone = Boolean(dragGroup || accepts || sortable);
31195
31182
  const enabled = isZone || Boolean(dndRoot);
31196
31183
  const eventBus = useEventBus();
31197
- const parentRoot = React107__default.useContext(RootCtx);
31184
+ const parentRoot = React105__default.useContext(RootCtx);
31198
31185
  const isRoot = enabled && parentRoot === null;
31199
- const zoneId = React107__default.useId();
31186
+ const zoneId = React105__default.useId();
31200
31187
  const ownGroup = dragGroup ?? accepts ?? zoneId;
31201
- const [optimisticOrders, setOptimisticOrders] = React107__default.useState(() => /* @__PURE__ */ new Map());
31202
- const optimisticOrdersRef = React107__default.useRef(optimisticOrders);
31188
+ const [optimisticOrders, setOptimisticOrders] = React105__default.useState(() => /* @__PURE__ */ new Map());
31189
+ const optimisticOrdersRef = React105__default.useRef(optimisticOrders);
31203
31190
  optimisticOrdersRef.current = optimisticOrders;
31204
- const clearOptimisticOrder = React107__default.useCallback((group) => {
31191
+ const clearOptimisticOrder = React105__default.useCallback((group) => {
31205
31192
  setOptimisticOrders((prev) => {
31206
31193
  if (!prev.has(group)) return prev;
31207
31194
  const next = new Map(prev);
@@ -31226,7 +31213,7 @@ function useDataDnd(args) {
31226
31213
  const raw = it[dndItemIdField];
31227
31214
  return raw != null ? String(raw) : `__idx_${idx}`;
31228
31215
  }).join("|");
31229
- const itemIds = React107__default.useMemo(
31216
+ const itemIds = React105__default.useMemo(
31230
31217
  () => orderedItems.map((it, idx) => {
31231
31218
  const raw = it[dndItemIdField];
31232
31219
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -31237,7 +31224,7 @@ function useDataDnd(args) {
31237
31224
  const raw = it[dndItemIdField];
31238
31225
  return raw != null ? String(raw) : `__${idx}`;
31239
31226
  }).join("|");
31240
- React107__default.useEffect(() => {
31227
+ React105__default.useEffect(() => {
31241
31228
  const root = isRoot ? null : parentRoot;
31242
31229
  if (root) {
31243
31230
  root.clearOptimisticOrder(ownGroup);
@@ -31245,20 +31232,20 @@ function useDataDnd(args) {
31245
31232
  clearOptimisticOrder(ownGroup);
31246
31233
  }
31247
31234
  }, [itemsContentSig, ownGroup]);
31248
- const zonesRef = React107__default.useRef(/* @__PURE__ */ new Map());
31249
- const registerZone = React107__default.useCallback((zoneId2, meta2) => {
31235
+ const zonesRef = React105__default.useRef(/* @__PURE__ */ new Map());
31236
+ const registerZone = React105__default.useCallback((zoneId2, meta2) => {
31250
31237
  zonesRef.current.set(zoneId2, meta2);
31251
31238
  }, []);
31252
- const unregisterZone = React107__default.useCallback((zoneId2) => {
31239
+ const unregisterZone = React105__default.useCallback((zoneId2) => {
31253
31240
  zonesRef.current.delete(zoneId2);
31254
31241
  }, []);
31255
- const [activeDrag, setActiveDrag] = React107__default.useState(null);
31256
- const [overZoneGroup, setOverZoneGroup] = React107__default.useState(null);
31257
- const meta = React107__default.useMemo(
31242
+ const [activeDrag, setActiveDrag] = React105__default.useState(null);
31243
+ const [overZoneGroup, setOverZoneGroup] = React105__default.useState(null);
31244
+ const meta = React105__default.useMemo(
31258
31245
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
31259
31246
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
31260
31247
  );
31261
- React107__default.useEffect(() => {
31248
+ React105__default.useEffect(() => {
31262
31249
  const target = isRoot ? null : parentRoot;
31263
31250
  if (!target) {
31264
31251
  zonesRef.current.set(zoneId, meta);
@@ -31277,7 +31264,7 @@ function useDataDnd(args) {
31277
31264
  }, [parentRoot, isRoot, zoneId, meta]);
31278
31265
  const sensors = useAlmadarDndSensors(true);
31279
31266
  const collisionDetection = almadarDndCollisionDetection;
31280
- const findZoneByItem = React107__default.useCallback(
31267
+ const findZoneByItem = React105__default.useCallback(
31281
31268
  (id) => {
31282
31269
  for (const z of zonesRef.current.values()) {
31283
31270
  if (z.itemIds.includes(id)) return z;
@@ -31286,7 +31273,7 @@ function useDataDnd(args) {
31286
31273
  },
31287
31274
  []
31288
31275
  );
31289
- React107__default.useCallback(
31276
+ React105__default.useCallback(
31290
31277
  (group) => {
31291
31278
  for (const z of zonesRef.current.values()) {
31292
31279
  if (z.group === group) return z;
@@ -31295,7 +31282,7 @@ function useDataDnd(args) {
31295
31282
  },
31296
31283
  []
31297
31284
  );
31298
- const handleDragEnd = React107__default.useCallback(
31285
+ const handleDragEnd = React105__default.useCallback(
31299
31286
  (event) => {
31300
31287
  const { active, over } = event;
31301
31288
  const activeIdStr = String(active.id);
@@ -31386,8 +31373,8 @@ function useDataDnd(args) {
31386
31373
  },
31387
31374
  [eventBus]
31388
31375
  );
31389
- const sortableData = React107__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
31390
- const SortableItem = React107__default.useCallback(
31376
+ const sortableData = React105__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
31377
+ const SortableItem = React105__default.useCallback(
31391
31378
  ({ id, children }) => {
31392
31379
  const {
31393
31380
  attributes,
@@ -31427,7 +31414,7 @@ function useDataDnd(args) {
31427
31414
  id: droppableId,
31428
31415
  data: sortableData
31429
31416
  });
31430
- const ctx = React107__default.useContext(RootCtx);
31417
+ const ctx = React105__default.useContext(RootCtx);
31431
31418
  const activeDrag2 = ctx?.activeDrag ?? null;
31432
31419
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
31433
31420
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -31442,7 +31429,7 @@ function useDataDnd(args) {
31442
31429
  showForeignPlaceholder,
31443
31430
  ctxAvailable: ctx != null
31444
31431
  });
31445
- React107__default.useEffect(() => {
31432
+ React105__default.useEffect(() => {
31446
31433
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
31447
31434
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
31448
31435
  return /* @__PURE__ */ jsx(
@@ -31456,11 +31443,11 @@ function useDataDnd(args) {
31456
31443
  }
31457
31444
  );
31458
31445
  };
31459
- const rootContextValue = React107__default.useMemo(
31446
+ const rootContextValue = React105__default.useMemo(
31460
31447
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
31461
31448
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
31462
31449
  );
31463
- const handleDragStart = React107__default.useCallback((event) => {
31450
+ const handleDragStart = React105__default.useCallback((event) => {
31464
31451
  const sourceZone = findZoneByItem(event.active.id);
31465
31452
  const rect = event.active.rect.current.initial;
31466
31453
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -31479,7 +31466,7 @@ function useDataDnd(args) {
31479
31466
  isRoot
31480
31467
  });
31481
31468
  }, [findZoneByItem, isRoot, zoneId]);
31482
- const handleDragOver = React107__default.useCallback((event) => {
31469
+ const handleDragOver = React105__default.useCallback((event) => {
31483
31470
  const { active, over } = event;
31484
31471
  const overData = over?.data?.current;
31485
31472
  const overGroup = overData?.dndGroup ?? null;
@@ -31549,7 +31536,7 @@ function useDataDnd(args) {
31549
31536
  return next;
31550
31537
  });
31551
31538
  }, []);
31552
- const handleDragCancel = React107__default.useCallback((event) => {
31539
+ const handleDragCancel = React105__default.useCallback((event) => {
31553
31540
  setActiveDrag(null);
31554
31541
  setOverZoneGroup(null);
31555
31542
  dndLog.warn("dragCancel", {
@@ -31557,12 +31544,12 @@ function useDataDnd(args) {
31557
31544
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
31558
31545
  });
31559
31546
  }, []);
31560
- const handleDragEndWithCleanup = React107__default.useCallback((event) => {
31547
+ const handleDragEndWithCleanup = React105__default.useCallback((event) => {
31561
31548
  handleDragEnd(event);
31562
31549
  setActiveDrag(null);
31563
31550
  setOverZoneGroup(null);
31564
31551
  }, [handleDragEnd]);
31565
- const wrapContainer = React107__default.useCallback(
31552
+ const wrapContainer = React105__default.useCallback(
31566
31553
  (children) => {
31567
31554
  if (!enabled) return children;
31568
31555
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -31616,7 +31603,7 @@ var init_useDataDnd = __esm({
31616
31603
  init_useAlmadarDndCollision();
31617
31604
  init_Box();
31618
31605
  dndLog = createLogger("almadar:ui:dnd");
31619
- RootCtx = React107__default.createContext(null);
31606
+ RootCtx = React105__default.createContext(null);
31620
31607
  }
31621
31608
  });
31622
31609
  function renderIconInput(icon, props) {
@@ -32142,7 +32129,7 @@ function DataList({
32142
32129
  }) {
32143
32130
  const eventBus = useEventBus();
32144
32131
  const { t } = useTranslate();
32145
- const [visibleCount, setVisibleCount] = React107__default.useState(pageSize || Infinity);
32132
+ const [visibleCount, setVisibleCount] = React105__default.useState(pageSize || Infinity);
32146
32133
  const fieldDefs = fields ?? columns ?? [];
32147
32134
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
32148
32135
  const dnd = useDataDnd({
@@ -32161,7 +32148,7 @@ function DataList({
32161
32148
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
32162
32149
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
32163
32150
  const hasRenderProp = typeof children === "function";
32164
- React107__default.useEffect(() => {
32151
+ React105__default.useEffect(() => {
32165
32152
  const renderItemTypeOf = typeof schemaRenderItem;
32166
32153
  const childrenTypeOf = typeof children;
32167
32154
  if (data.length > 0 && !hasRenderProp) {
@@ -32265,7 +32252,7 @@ function DataList({
32265
32252
  const items2 = [...data];
32266
32253
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
32267
32254
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
32268
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
32255
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
32269
32256
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
32270
32257
  group.items.map((itemData, index) => {
32271
32258
  const id = itemData.id || `${gi}-${index}`;
@@ -32406,7 +32393,7 @@ function DataList({
32406
32393
  className
32407
32394
  ),
32408
32395
  children: [
32409
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
32396
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
32410
32397
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
32411
32398
  group.items.map(
32412
32399
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -32491,7 +32478,7 @@ var init_FormSection = __esm({
32491
32478
  columns = 1,
32492
32479
  className
32493
32480
  }) => {
32494
- const [collapsed, setCollapsed] = React107__default.useState(defaultCollapsed);
32481
+ const [collapsed, setCollapsed] = React105__default.useState(defaultCollapsed);
32495
32482
  const { t } = useTranslate();
32496
32483
  const eventBus = useEventBus();
32497
32484
  const gridClass = {
@@ -32499,7 +32486,7 @@ var init_FormSection = __esm({
32499
32486
  2: "grid-cols-1 md:grid-cols-2",
32500
32487
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
32501
32488
  }[columns];
32502
- React107__default.useCallback(() => {
32489
+ React105__default.useCallback(() => {
32503
32490
  if (collapsible) {
32504
32491
  setCollapsed((prev) => !prev);
32505
32492
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -33449,7 +33436,7 @@ var init_Flex = __esm({
33449
33436
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
33450
33437
  }
33451
33438
  }
33452
- return React107__default.createElement(Component, {
33439
+ return React105__default.createElement(Component, {
33453
33440
  className: cn(
33454
33441
  inline ? "inline-flex" : "flex",
33455
33442
  directionStyles[direction],
@@ -33568,7 +33555,7 @@ var init_Grid = __esm({
33568
33555
  as: Component = "div"
33569
33556
  }) => {
33570
33557
  const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
33571
- return React107__default.createElement(
33558
+ return React105__default.createElement(
33572
33559
  Component,
33573
33560
  {
33574
33561
  className: cn(
@@ -33764,9 +33751,9 @@ var init_Popover = __esm({
33764
33751
  onMouseLeave: handleClose,
33765
33752
  onPointerDown: tapTriggerProps.onPointerDown
33766
33753
  };
33767
- const childElement = React107__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
33754
+ const childElement = React105__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
33768
33755
  const childPointerDown = childElement.props.onPointerDown;
33769
- const triggerElement = React107__default.cloneElement(
33756
+ const triggerElement = React105__default.cloneElement(
33770
33757
  childElement,
33771
33758
  {
33772
33759
  ref: triggerRef,
@@ -34368,9 +34355,9 @@ var init_Tooltip = __esm({
34368
34355
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
34369
34356
  };
34370
34357
  }, []);
34371
- const triggerElement = React107__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
34358
+ const triggerElement = React105__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
34372
34359
  const childPointerDown = triggerElement.props.onPointerDown;
34373
- const trigger = React107__default.cloneElement(triggerElement, {
34360
+ const trigger = React105__default.cloneElement(triggerElement, {
34374
34361
  ref: triggerRef,
34375
34362
  onMouseEnter: handleMouseEnter,
34376
34363
  onMouseLeave: handleMouseLeave,
@@ -34460,7 +34447,7 @@ var init_WizardProgress = __esm({
34460
34447
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
34461
34448
  const isActive = index === currentStep;
34462
34449
  const isCompleted = index < currentStep;
34463
- return /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
34450
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
34464
34451
  /* @__PURE__ */ jsx(
34465
34452
  "button",
34466
34453
  {
@@ -36020,7 +36007,7 @@ var init_MapView = __esm({
36020
36007
  shadowSize: [41, 41]
36021
36008
  });
36022
36009
  L.Marker.prototype.options.icon = defaultIcon;
36023
- const { useEffect: useEffect76, useRef: useRef77, useCallback: useCallback117, useState: useState108 } = React107__default;
36010
+ const { useEffect: useEffect76, useRef: useRef77, useCallback: useCallback117, useState: useState108 } = React105__default;
36024
36011
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
36025
36012
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
36026
36013
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -36935,8 +36922,8 @@ function TableView({
36935
36922
  }) {
36936
36923
  const eventBus = useEventBus();
36937
36924
  const { t } = useTranslate();
36938
- const [visibleCount, setVisibleCount] = React107__default.useState(pageSize > 0 ? pageSize : Infinity);
36939
- const [localSelected, setLocalSelected] = React107__default.useState(/* @__PURE__ */ new Set());
36925
+ const [visibleCount, setVisibleCount] = React105__default.useState(pageSize > 0 ? pageSize : Infinity);
36926
+ const [localSelected, setLocalSelected] = React105__default.useState(/* @__PURE__ */ new Set());
36940
36927
  const colDefs = columns ?? fields ?? [];
36941
36928
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
36942
36929
  const dnd = useDataDnd({
@@ -37131,12 +37118,12 @@ function TableView({
37131
37118
  ]
37132
37119
  }
37133
37120
  );
37134
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React107__default.Fragment, { children: rowInner }, id);
37121
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React105__default.Fragment, { children: rowInner }, id);
37135
37122
  };
37136
37123
  const items = Array.from(data);
37137
37124
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
37138
37125
  let runningIndex = 0;
37139
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
37126
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
37140
37127
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
37141
37128
  group.items.map((row) => renderRow(row, runningIndex++))
37142
37129
  ] }, gi)) });
@@ -38493,7 +38480,7 @@ var init_StepFlow = __esm({
38493
38480
  className
38494
38481
  }) => {
38495
38482
  if (orientation === "vertical") {
38496
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React107__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
38483
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React105__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
38497
38484
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
38498
38485
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
38499
38486
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -38504,7 +38491,7 @@ var init_StepFlow = __esm({
38504
38491
  ] })
38505
38492
  ] }) }, index)) });
38506
38493
  }
38507
- return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
38494
+ return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
38508
38495
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
38509
38496
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
38510
38497
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -39489,7 +39476,7 @@ var init_LikertScale = __esm({
39489
39476
  md: "text-base",
39490
39477
  lg: "text-lg"
39491
39478
  };
39492
- LikertScale = React107__default.forwardRef(
39479
+ LikertScale = React105__default.forwardRef(
39493
39480
  ({
39494
39481
  question,
39495
39482
  options = DEFAULT_LIKERT_OPTIONS,
@@ -39501,7 +39488,7 @@ var init_LikertScale = __esm({
39501
39488
  variant = "radios",
39502
39489
  className
39503
39490
  }, ref) => {
39504
- const groupId = React107__default.useId();
39491
+ const groupId = React105__default.useId();
39505
39492
  const eventBus = useEventBus();
39506
39493
  const handleSelect = useCallback(
39507
39494
  (next) => {
@@ -41783,7 +41770,7 @@ var init_DocBreadcrumb = __esm({
41783
41770
  "aria-label": t("aria.breadcrumb"),
41784
41771
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
41785
41772
  const isLast = idx === items.length - 1;
41786
- return /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
41773
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
41787
41774
  idx > 0 && /* @__PURE__ */ jsx(
41788
41775
  Icon,
41789
41776
  {
@@ -42652,7 +42639,7 @@ var init_MiniStateMachine = __esm({
42652
42639
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
42653
42640
  const tc = transitionCounts[s.name] ?? 0;
42654
42641
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
42655
- return /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
42642
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
42656
42643
  /* @__PURE__ */ jsx(
42657
42644
  AvlState,
42658
42645
  {
@@ -42856,7 +42843,7 @@ var init_PageHeader = __esm({
42856
42843
  info: "bg-info/10 text-info"
42857
42844
  };
42858
42845
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
42859
- breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
42846
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
42860
42847
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
42861
42848
  crumb.href ? /* @__PURE__ */ jsx(
42862
42849
  "a",
@@ -43214,7 +43201,7 @@ var init_Section = __esm({
43214
43201
  as: Component = "section"
43215
43202
  }) => {
43216
43203
  const hasHeader = title || description || action;
43217
- return React107__default.createElement(
43204
+ return React105__default.createElement(
43218
43205
  Component,
43219
43206
  {
43220
43207
  className: cn(
@@ -43516,6 +43503,7 @@ var init_WizardContainer = __esm({
43516
43503
  init_Stack();
43517
43504
  init_Icon();
43518
43505
  init_cn();
43506
+ init_useEventBus();
43519
43507
  WizardContainer = ({
43520
43508
  steps,
43521
43509
  currentStep: controlledStep,
@@ -43524,9 +43512,13 @@ var init_WizardContainer = __esm({
43524
43512
  showProgress = true,
43525
43513
  allowBack = true,
43526
43514
  compact = false,
43527
- className
43515
+ className,
43516
+ nextEvent,
43517
+ backEvent,
43518
+ completeEvent
43528
43519
  }) => {
43529
43520
  const { t } = useTranslate();
43521
+ const eventBus = useEventBus();
43530
43522
  const [internalStep, setInternalStep] = useState(0);
43531
43523
  const normalizedControlledStep = (() => {
43532
43524
  if (controlledStep === void 0 || controlledStep === null)
@@ -43556,13 +43548,16 @@ var init_WizardContainer = __esm({
43556
43548
  return;
43557
43549
  }
43558
43550
  if (isLastStep) {
43551
+ if (completeEvent) eventBus.emit(`UI:${completeEvent}`, { step: currentStep });
43559
43552
  onComplete?.();
43560
43553
  } else {
43554
+ if (nextEvent) eventBus.emit(`UI:${nextEvent}`, { step: currentStep + 1 });
43561
43555
  goToStep(currentStep + 1);
43562
43556
  }
43563
43557
  };
43564
43558
  const handleBack = () => {
43565
43559
  if (!isFirstStep && allowBack) {
43560
+ if (backEvent) eventBus.emit(`UI:${backEvent}`, { step: currentStep - 1 });
43566
43561
  goToStep(currentStep - 1);
43567
43562
  }
43568
43563
  };
@@ -43580,7 +43575,7 @@ var init_WizardContainer = __esm({
43580
43575
  const isCompleted = index < currentStep;
43581
43576
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
43582
43577
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
43583
- return /* @__PURE__ */ jsxs(React107__default.Fragment, { children: [
43578
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
43584
43579
  /* @__PURE__ */ jsx(
43585
43580
  Button,
43586
43581
  {
@@ -46013,7 +46008,7 @@ var init_DetailPanel = __esm({
46013
46008
  }
46014
46009
  });
46015
46010
  function extractTitle(children) {
46016
- if (!React107__default.isValidElement(children)) return void 0;
46011
+ if (!React105__default.isValidElement(children)) return void 0;
46017
46012
  const props = children.props;
46018
46013
  if (typeof props.title === "string") {
46019
46014
  return props.title;
@@ -46031,14 +46026,18 @@ var init_DrawerSlot = __esm({
46031
46026
  title: overrideTitle,
46032
46027
  position = "right",
46033
46028
  size = "md",
46034
- className
46029
+ className,
46030
+ sourceTrait
46035
46031
  }) => {
46036
46032
  const eventBus = useEventBus();
46033
+ const schemaCtx = useEntitySchemaOptional();
46037
46034
  const isOpen = Boolean(children);
46038
46035
  const title = overrideTitle || extractTitle(children);
46039
46036
  const handleClose = () => {
46040
- eventBus.emit("UI:CLOSE");
46041
- eventBus.emit("UI:CANCEL");
46037
+ const orbital = sourceTrait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
46038
+ const prefix = orbital !== void 0 && sourceTrait !== void 0 ? `UI:${orbital}.${sourceTrait}.` : "UI:";
46039
+ eventBus.emit(`${prefix}CLOSE`);
46040
+ eventBus.emit(`${prefix}CANCEL`);
46042
46041
  };
46043
46042
  if (!isOpen) return null;
46044
46043
  return /* @__PURE__ */ jsx(
@@ -46359,12 +46358,12 @@ var init_Form = __esm({
46359
46358
  const isSchemaEntity = isOrbitalEntitySchema(entity);
46360
46359
  const resolvedEntity = isSchemaEntity ? entity : void 0;
46361
46360
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
46362
- const normalizedInitialData = React107__default.useMemo(() => {
46361
+ const normalizedInitialData = React105__default.useMemo(() => {
46363
46362
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
46364
46363
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
46365
46364
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
46366
46365
  }, [entity, initialData]);
46367
- const entityDerivedFields = React107__default.useMemo(() => {
46366
+ const entityDerivedFields = React105__default.useMemo(() => {
46368
46367
  if (fields && fields.length > 0) return void 0;
46369
46368
  if (!resolvedEntity) return void 0;
46370
46369
  return resolvedEntity.fields.map(
@@ -46385,16 +46384,16 @@ var init_Form = __esm({
46385
46384
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
46386
46385
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
46387
46386
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
46388
- const [formData, setFormData] = React107__default.useState(
46387
+ const [formData, setFormData] = React105__default.useState(
46389
46388
  normalizedInitialData
46390
46389
  );
46391
- const [collapsedSections, setCollapsedSections] = React107__default.useState(
46390
+ const [collapsedSections, setCollapsedSections] = React105__default.useState(
46392
46391
  /* @__PURE__ */ new Set()
46393
46392
  );
46394
- const [submitError, setSubmitError] = React107__default.useState(null);
46395
- const formRef = React107__default.useRef(null);
46393
+ const [submitError, setSubmitError] = React105__default.useState(null);
46394
+ const formRef = React105__default.useRef(null);
46396
46395
  const formMode = props.mode;
46397
- const mountedRef = React107__default.useRef(false);
46396
+ const mountedRef = React105__default.useRef(false);
46398
46397
  if (!mountedRef.current) {
46399
46398
  mountedRef.current = true;
46400
46399
  debug("forms", "mount", {
@@ -46407,7 +46406,7 @@ var init_Form = __esm({
46407
46406
  });
46408
46407
  }
46409
46408
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
46410
- const evalContext = React107__default.useMemo(
46409
+ const evalContext = React105__default.useMemo(
46411
46410
  () => ({
46412
46411
  formValues: formData,
46413
46412
  globalVariables: externalContext?.globalVariables ?? {},
@@ -46416,7 +46415,7 @@ var init_Form = __esm({
46416
46415
  }),
46417
46416
  [formData, externalContext]
46418
46417
  );
46419
- React107__default.useEffect(() => {
46418
+ React105__default.useEffect(() => {
46420
46419
  debug("forms", "initialData-sync", {
46421
46420
  mode: formMode,
46422
46421
  normalizedInitialData,
@@ -46427,7 +46426,7 @@ var init_Form = __esm({
46427
46426
  setFormData(normalizedInitialData);
46428
46427
  }
46429
46428
  }, [normalizedInitialData]);
46430
- const processCalculations = React107__default.useCallback(
46429
+ const processCalculations = React105__default.useCallback(
46431
46430
  (changedFieldId, newFormData) => {
46432
46431
  if (!hiddenCalculations.length) return;
46433
46432
  const context = {
@@ -46452,7 +46451,7 @@ var init_Form = __esm({
46452
46451
  },
46453
46452
  [hiddenCalculations, externalContext, eventBus]
46454
46453
  );
46455
- const checkViolations = React107__default.useCallback(
46454
+ const checkViolations = React105__default.useCallback(
46456
46455
  (changedFieldId, newFormData) => {
46457
46456
  if (!violationTriggers.length) return;
46458
46457
  const context = {
@@ -46490,7 +46489,7 @@ var init_Form = __esm({
46490
46489
  processCalculations(name, newFormData);
46491
46490
  checkViolations(name, newFormData);
46492
46491
  };
46493
- const isFieldVisible = React107__default.useCallback(
46492
+ const isFieldVisible = React105__default.useCallback(
46494
46493
  (fieldName) => {
46495
46494
  const condition = conditionalFields[fieldName];
46496
46495
  if (!condition) return true;
@@ -46498,7 +46497,7 @@ var init_Form = __esm({
46498
46497
  },
46499
46498
  [conditionalFields, evalContext]
46500
46499
  );
46501
- const isSectionVisible = React107__default.useCallback(
46500
+ const isSectionVisible = React105__default.useCallback(
46502
46501
  (section) => {
46503
46502
  if (!section.condition) return true;
46504
46503
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -46574,7 +46573,7 @@ var init_Form = __esm({
46574
46573
  eventBus.emit(`UI:${onCancel}`);
46575
46574
  }
46576
46575
  };
46577
- const renderField = React107__default.useCallback(
46576
+ const renderField = React105__default.useCallback(
46578
46577
  (field) => {
46579
46578
  const fieldName = field.name || field.field;
46580
46579
  if (!fieldName) return null;
@@ -46595,7 +46594,7 @@ var init_Form = __esm({
46595
46594
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
46596
46595
  );
46597
46596
  const effectiveFields = entityDerivedFields ?? fields;
46598
- const normalizedFields = React107__default.useMemo(() => {
46597
+ const normalizedFields = React105__default.useMemo(() => {
46599
46598
  if (!effectiveFields || effectiveFields.length === 0) return [];
46600
46599
  return effectiveFields.map((field) => {
46601
46600
  if (typeof field === "string") {
@@ -46619,7 +46618,7 @@ var init_Form = __esm({
46619
46618
  return field;
46620
46619
  });
46621
46620
  }, [effectiveFields, resolvedEntity]);
46622
- const schemaFields = React107__default.useMemo(() => {
46621
+ const schemaFields = React105__default.useMemo(() => {
46623
46622
  if (normalizedFields.length === 0) return null;
46624
46623
  if (isDebugEnabled()) {
46625
46624
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -46629,7 +46628,7 @@ var init_Form = __esm({
46629
46628
  }
46630
46629
  return normalizedFields.map(renderField).filter(Boolean);
46631
46630
  }, [normalizedFields, renderField, entityName, conditionalFields]);
46632
- const sectionElements = React107__default.useMemo(() => {
46631
+ const sectionElements = React105__default.useMemo(() => {
46633
46632
  if (!sections || sections.length === 0) return null;
46634
46633
  return sections.map((section) => {
46635
46634
  if (!isSectionVisible(section)) {
@@ -47354,7 +47353,7 @@ var init_List = __esm({
47354
47353
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
47355
47354
  return [];
47356
47355
  }, [entity]);
47357
- const getItemActions = React107__default.useCallback(
47356
+ const getItemActions = React105__default.useCallback(
47358
47357
  (item) => {
47359
47358
  if (!itemActions) return [];
47360
47359
  if (typeof itemActions === "function") {
@@ -47829,7 +47828,7 @@ var init_MediaGallery = __esm({
47829
47828
  [selectable, selectedItems, selectionEvent, eventBus]
47830
47829
  );
47831
47830
  const entityData = Array.isArray(entity) ? entity : [];
47832
- const items = React107__default.useMemo(() => {
47831
+ const items = React105__default.useMemo(() => {
47833
47832
  if (propItems) return propItems;
47834
47833
  if (entityData.length === 0) return [];
47835
47834
  return entityData.map((record, idx) => {
@@ -47992,7 +47991,7 @@ var init_MediaGallery = __esm({
47992
47991
  }
47993
47992
  });
47994
47993
  function extractTitle2(children) {
47995
- if (!React107__default.isValidElement(children)) return void 0;
47994
+ if (!React105__default.isValidElement(children)) return void 0;
47996
47995
  const props = children.props;
47997
47996
  if (typeof props.title === "string") {
47998
47997
  return props.title;
@@ -48009,14 +48008,18 @@ var init_ModalSlot = __esm({
48009
48008
  children,
48010
48009
  title: overrideTitle,
48011
48010
  size = "md",
48012
- className
48011
+ className,
48012
+ sourceTrait
48013
48013
  }) => {
48014
48014
  const eventBus = useEventBus();
48015
+ const schemaCtx = useEntitySchemaOptional();
48015
48016
  const isOpen = Boolean(children);
48016
48017
  const title = overrideTitle || extractTitle2(children);
48017
48018
  const handleClose = () => {
48018
- eventBus.emit("UI:CLOSE");
48019
- eventBus.emit("UI:CANCEL");
48019
+ const orbital = sourceTrait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
48020
+ const prefix = orbital !== void 0 && sourceTrait !== void 0 ? `UI:${orbital}.${sourceTrait}.` : "UI:";
48021
+ eventBus.emit(`${prefix}CLOSE`);
48022
+ eventBus.emit(`${prefix}CANCEL`);
48020
48023
  };
48021
48024
  if (!isOpen) return null;
48022
48025
  return /* @__PURE__ */ jsx(
@@ -48243,7 +48246,7 @@ var init_debugRegistry = __esm({
48243
48246
  }
48244
48247
  });
48245
48248
  function useDebugData() {
48246
- const [data, setData] = React107.useState(() => ({
48249
+ const [data, setData] = React105.useState(() => ({
48247
48250
  traits: [],
48248
48251
  ticks: [],
48249
48252
  guards: [],
@@ -48257,7 +48260,7 @@ function useDebugData() {
48257
48260
  },
48258
48261
  lastUpdate: Date.now()
48259
48262
  }));
48260
- React107.useEffect(() => {
48263
+ React105.useEffect(() => {
48261
48264
  const updateData = () => {
48262
48265
  setData({
48263
48266
  traits: getAllTraits(),
@@ -48366,12 +48369,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
48366
48369
  return positions;
48367
48370
  }
48368
48371
  function WalkMinimap() {
48369
- const [walkStep, setWalkStep] = React107.useState(null);
48370
- const [traits2, setTraits] = React107.useState([]);
48371
- const [coveredEdges, setCoveredEdges] = React107.useState([]);
48372
- const [completedTraits, setCompletedTraits] = React107.useState(/* @__PURE__ */ new Set());
48373
- const prevTraitRef = React107.useRef(null);
48374
- React107.useEffect(() => {
48372
+ const [walkStep, setWalkStep] = React105.useState(null);
48373
+ const [traits2, setTraits] = React105.useState([]);
48374
+ const [coveredEdges, setCoveredEdges] = React105.useState([]);
48375
+ const [completedTraits, setCompletedTraits] = React105.useState(/* @__PURE__ */ new Set());
48376
+ const prevTraitRef = React105.useRef(null);
48377
+ React105.useEffect(() => {
48375
48378
  const interval = setInterval(() => {
48376
48379
  const w = window;
48377
48380
  const step = w.__orbitalWalkStep;
@@ -48807,15 +48810,15 @@ var init_EntitiesTab = __esm({
48807
48810
  });
48808
48811
  function EventFlowTab({ events: events2 }) {
48809
48812
  const { t } = useTranslate();
48810
- const [filter, setFilter] = React107.useState("all");
48811
- const containerRef = React107.useRef(null);
48812
- const [autoScroll, setAutoScroll] = React107.useState(true);
48813
- React107.useEffect(() => {
48813
+ const [filter, setFilter] = React105.useState("all");
48814
+ const containerRef = React105.useRef(null);
48815
+ const [autoScroll, setAutoScroll] = React105.useState(true);
48816
+ React105.useEffect(() => {
48814
48817
  if (autoScroll && containerRef.current) {
48815
48818
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
48816
48819
  }
48817
48820
  }, [events2.length, autoScroll]);
48818
- const filteredEvents = React107.useMemo(() => {
48821
+ const filteredEvents = React105.useMemo(() => {
48819
48822
  if (filter === "all") return events2;
48820
48823
  return events2.filter((e) => e.type === filter);
48821
48824
  }, [events2, filter]);
@@ -48931,7 +48934,7 @@ var init_EventFlowTab = __esm({
48931
48934
  });
48932
48935
  function GuardsPanel({ guards }) {
48933
48936
  const { t } = useTranslate();
48934
- const [filter, setFilter] = React107.useState("all");
48937
+ const [filter, setFilter] = React105.useState("all");
48935
48938
  if (guards.length === 0) {
48936
48939
  return /* @__PURE__ */ jsx(
48937
48940
  EmptyState,
@@ -48944,7 +48947,7 @@ function GuardsPanel({ guards }) {
48944
48947
  }
48945
48948
  const passedCount = guards.filter((g) => g.result).length;
48946
48949
  const failedCount = guards.length - passedCount;
48947
- const filteredGuards = React107.useMemo(() => {
48950
+ const filteredGuards = React105.useMemo(() => {
48948
48951
  if (filter === "all") return guards;
48949
48952
  if (filter === "passed") return guards.filter((g) => g.result);
48950
48953
  return guards.filter((g) => !g.result);
@@ -49107,10 +49110,10 @@ function EffectBadge({ effect }) {
49107
49110
  }
49108
49111
  function TransitionTimeline({ transitions }) {
49109
49112
  const { t } = useTranslate();
49110
- const containerRef = React107.useRef(null);
49111
- const [autoScroll, setAutoScroll] = React107.useState(true);
49112
- const [expandedId, setExpandedId] = React107.useState(null);
49113
- React107.useEffect(() => {
49113
+ const containerRef = React105.useRef(null);
49114
+ const [autoScroll, setAutoScroll] = React105.useState(true);
49115
+ const [expandedId, setExpandedId] = React105.useState(null);
49116
+ React105.useEffect(() => {
49114
49117
  if (autoScroll && containerRef.current) {
49115
49118
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
49116
49119
  }
@@ -49390,9 +49393,9 @@ function getAllEvents(traits2) {
49390
49393
  function EventDispatcherTab({ traits: traits2, schema }) {
49391
49394
  const eventBus = useEventBus();
49392
49395
  const { t } = useTranslate();
49393
- const [log13, setLog] = React107.useState([]);
49394
- const prevStatesRef = React107.useRef(/* @__PURE__ */ new Map());
49395
- React107.useEffect(() => {
49396
+ const [log13, setLog] = React105.useState([]);
49397
+ const prevStatesRef = React105.useRef(/* @__PURE__ */ new Map());
49398
+ React105.useEffect(() => {
49396
49399
  for (const trait of traits2) {
49397
49400
  const prev = prevStatesRef.current.get(trait.id);
49398
49401
  if (prev && prev !== trait.currentState) {
@@ -49561,10 +49564,10 @@ function VerifyModePanel({
49561
49564
  localCount
49562
49565
  }) {
49563
49566
  const { t } = useTranslate();
49564
- const [expanded, setExpanded] = React107.useState(true);
49565
- const scrollRef = React107.useRef(null);
49566
- const prevCountRef = React107.useRef(0);
49567
- React107.useEffect(() => {
49567
+ const [expanded, setExpanded] = React105.useState(true);
49568
+ const scrollRef = React105.useRef(null);
49569
+ const prevCountRef = React105.useRef(0);
49570
+ React105.useEffect(() => {
49568
49571
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
49569
49572
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
49570
49573
  }
@@ -49621,10 +49624,10 @@ function RuntimeDebugger({
49621
49624
  schema
49622
49625
  }) {
49623
49626
  const { t } = useTranslate();
49624
- const [isCollapsed, setIsCollapsed] = React107.useState(mode === "verify" ? true : defaultCollapsed);
49625
- const [isVisible, setIsVisible] = React107.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
49627
+ const [isCollapsed, setIsCollapsed] = React105.useState(mode === "verify" ? true : defaultCollapsed);
49628
+ const [isVisible, setIsVisible] = React105.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
49626
49629
  const debugData = useDebugData();
49627
- React107.useEffect(() => {
49630
+ React105.useEffect(() => {
49628
49631
  if (mode === "inline") return;
49629
49632
  return onDebugToggle((enabled) => {
49630
49633
  setIsVisible(enabled);
@@ -49633,7 +49636,7 @@ function RuntimeDebugger({
49633
49636
  }
49634
49637
  });
49635
49638
  }, [mode]);
49636
- React107.useEffect(() => {
49639
+ React105.useEffect(() => {
49637
49640
  if (mode === "inline") return;
49638
49641
  const handleKeyDown = (e) => {
49639
49642
  if (e.key === "`" && isVisible) {
@@ -50153,7 +50156,7 @@ var init_StatCard = __esm({
50153
50156
  const labelToUse = propLabel ?? propTitle;
50154
50157
  const eventBus = useEventBus();
50155
50158
  const { t } = useTranslate();
50156
- const handleActionClick = React107__default.useCallback(() => {
50159
+ const handleActionClick = React105__default.useCallback(() => {
50157
50160
  if (action?.event) {
50158
50161
  eventBus.emit(`UI:${action.event}`, {});
50159
50162
  }
@@ -50164,7 +50167,7 @@ var init_StatCard = __esm({
50164
50167
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
50165
50168
  const isLoading = externalLoading ?? false;
50166
50169
  const error = externalError;
50167
- const computeMetricValue = React107__default.useCallback(
50170
+ const computeMetricValue = React105__default.useCallback(
50168
50171
  (metric, items) => {
50169
50172
  if (metric.value !== void 0) {
50170
50173
  return metric.value;
@@ -50203,7 +50206,7 @@ var init_StatCard = __esm({
50203
50206
  },
50204
50207
  []
50205
50208
  );
50206
- const schemaStats = React107__default.useMemo(() => {
50209
+ const schemaStats = React105__default.useMemo(() => {
50207
50210
  if (!metrics || metrics.length === 0) return null;
50208
50211
  return metrics.map((metric) => ({
50209
50212
  label: metric.label,
@@ -50211,7 +50214,7 @@ var init_StatCard = __esm({
50211
50214
  format: metric.format
50212
50215
  }));
50213
50216
  }, [metrics, data, computeMetricValue]);
50214
- const calculatedTrend = React107__default.useMemo(() => {
50217
+ const calculatedTrend = React105__default.useMemo(() => {
50215
50218
  if (manualTrend !== void 0) return manualTrend;
50216
50219
  if (previousValue === void 0 || currentValue === void 0)
50217
50220
  return void 0;
@@ -50851,8 +50854,8 @@ var init_SubagentTracePanel = __esm({
50851
50854
  ] });
50852
50855
  };
50853
50856
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
50854
- const endRef = React107__default.useRef(null);
50855
- React107__default.useEffect(() => {
50857
+ const endRef = React105__default.useRef(null);
50858
+ React105__default.useEffect(() => {
50856
50859
  if (!autoScroll) return;
50857
50860
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
50858
50861
  }, [activities.length, autoScroll]);
@@ -50946,7 +50949,7 @@ var init_SubagentTracePanel = __esm({
50946
50949
  };
50947
50950
  SubagentRichCard = ({ subagent }) => {
50948
50951
  const { t } = useTranslate();
50949
- const activities = React107__default.useMemo(
50952
+ const activities = React105__default.useMemo(
50950
50953
  () => subagentMessagesToActivities(subagent.messages),
50951
50954
  [subagent.messages]
50952
50955
  );
@@ -51023,8 +51026,8 @@ var init_SubagentTracePanel = __esm({
51023
51026
  ] });
51024
51027
  };
51025
51028
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
51026
- const endRef = React107__default.useRef(null);
51027
- React107__default.useEffect(() => {
51029
+ const endRef = React105__default.useRef(null);
51030
+ React105__default.useEffect(() => {
51028
51031
  if (!autoScroll) return;
51029
51032
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
51030
51033
  }, [messages.length, autoScroll]);
@@ -51454,7 +51457,7 @@ var init_Timeline = __esm({
51454
51457
  }) => {
51455
51458
  const { t } = useTranslate();
51456
51459
  const entityData = entity ?? [];
51457
- const items = React107__default.useMemo(() => {
51460
+ const items = React105__default.useMemo(() => {
51458
51461
  if (propItems) return propItems;
51459
51462
  if (entityData.length === 0) return [];
51460
51463
  return entityData.map((record, idx) => {
@@ -51556,7 +51559,7 @@ var init_Timeline = __esm({
51556
51559
  }
51557
51560
  });
51558
51561
  function extractToastProps(children) {
51559
- if (!React107__default.isValidElement(children)) {
51562
+ if (!React105__default.isValidElement(children)) {
51560
51563
  if (typeof children === "string") {
51561
51564
  return { message: children };
51562
51565
  }
@@ -51581,20 +51584,24 @@ var init_ToastSlot = __esm({
51581
51584
  variant: overrideVariant,
51582
51585
  title: overrideTitle,
51583
51586
  duration = 5e3,
51584
- className
51587
+ className,
51588
+ sourceTrait
51585
51589
  }) => {
51586
51590
  const eventBus = useEventBus();
51591
+ const schemaCtx = useEntitySchemaOptional();
51587
51592
  const isVisible = Boolean(children);
51588
51593
  const extracted = extractToastProps(children);
51589
51594
  const variant = overrideVariant || extracted.variant || "info";
51590
51595
  const title = overrideTitle || extracted.title;
51591
51596
  const message = extracted.message || (typeof children === "string" ? children : "");
51592
51597
  const handleDismiss = () => {
51593
- eventBus.emit("UI:DISMISS");
51594
- eventBus.emit("UI:CLOSE");
51598
+ const orbital = sourceTrait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
51599
+ const prefix = orbital !== void 0 && sourceTrait !== void 0 ? `UI:${orbital}.${sourceTrait}.` : "UI:";
51600
+ eventBus.emit(`${prefix}DISMISS`);
51601
+ eventBus.emit(`${prefix}CLOSE`);
51595
51602
  };
51596
51603
  if (!isVisible) return null;
51597
- const isCustomContent = React107__default.isValidElement(children) && !message;
51604
+ const isCustomContent = React105__default.isValidElement(children) && !message;
51598
51605
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
51599
51606
  Toast,
51600
51607
  {
@@ -51611,7 +51618,7 @@ var init_ToastSlot = __esm({
51611
51618
  }
51612
51619
  });
51613
51620
  function lazyThree(name, loader) {
51614
- const Lazy = React107__default.lazy(
51621
+ const Lazy = React105__default.lazy(
51615
51622
  () => loader().then((m) => {
51616
51623
  const Resolved = m[name];
51617
51624
  if (!Resolved) {
@@ -51623,13 +51630,13 @@ function lazyThree(name, loader) {
51623
51630
  })
51624
51631
  );
51625
51632
  function ThreeWrapper(props) {
51626
- return React107__default.createElement(
51633
+ return React105__default.createElement(
51627
51634
  ThreeBoundary,
51628
51635
  { name },
51629
- React107__default.createElement(
51630
- React107__default.Suspense,
51636
+ React105__default.createElement(
51637
+ React105__default.Suspense,
51631
51638
  { fallback: null },
51632
- React107__default.createElement(Lazy, props)
51639
+ React105__default.createElement(Lazy, props)
51633
51640
  )
51634
51641
  );
51635
51642
  }
@@ -51941,7 +51948,7 @@ var init_component_registry_generated = __esm({
51941
51948
  init_WizardProgress();
51942
51949
  init_WorldMapBoard();
51943
51950
  init_WorldMapTemplate();
51944
- ThreeBoundary = class extends React107__default.Component {
51951
+ ThreeBoundary = class extends React105__default.Component {
51945
51952
  constructor() {
51946
51953
  super(...arguments);
51947
51954
  __publicField(this, "state", { failed: false });
@@ -51951,7 +51958,7 @@ var init_component_registry_generated = __esm({
51951
51958
  }
51952
51959
  render() {
51953
51960
  if (this.state.failed) {
51954
- return React107__default.createElement(
51961
+ return React105__default.createElement(
51955
51962
  "div",
51956
51963
  {
51957
51964
  "data-testid": "three-unavailable",
@@ -52307,7 +52314,7 @@ function SuspenseConfigProvider({
52307
52314
  config,
52308
52315
  children
52309
52316
  }) {
52310
- return React107__default.createElement(
52317
+ return React105__default.createElement(
52311
52318
  SuspenseConfigContext.Provider,
52312
52319
  { value: config },
52313
52320
  children
@@ -52318,8 +52325,8 @@ function getSlotFallback(slot, config) {
52318
52325
  const variant = SLOT_SKELETON_MAP[slot] ?? "text";
52319
52326
  return /* @__PURE__ */ jsx(Skeleton, { variant });
52320
52327
  }
52321
- function getComponentForPattern3(patternType) {
52322
- const mapping = getComponentForPattern(patternType);
52328
+ function getComponentForPattern(patternType) {
52329
+ const mapping = getComponentForPattern$1(patternType);
52323
52330
  if (!mapping) {
52324
52331
  return null;
52325
52332
  }
@@ -52349,7 +52356,7 @@ function enrichFormFields(fields, entityDef) {
52349
52356
  }
52350
52357
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
52351
52358
  }
52352
- if (field && typeof field === "object" && !Array.isArray(field) && !React107__default.isValidElement(field) && !(field instanceof Date)) {
52359
+ if (field && typeof field === "object" && !Array.isArray(field) && !React105__default.isValidElement(field) && !(field instanceof Date)) {
52353
52360
  const obj = field;
52354
52361
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
52355
52362
  if (!fieldName) return field;
@@ -52527,6 +52534,7 @@ function UISlotComponent({
52527
52534
  const { t } = useTranslate();
52528
52535
  const suspenseConfig = useContext(SuspenseConfigContext);
52529
52536
  const contained = useContext(SlotContainedContext);
52537
+ const schemaCtx = useEntitySchemaOptional();
52530
52538
  const content = slots[slot];
52531
52539
  if (children !== void 0) {
52532
52540
  if (pattern === "clear") {
@@ -52572,8 +52580,11 @@ function UISlotComponent({
52572
52580
  }
52573
52581
  const handleDismiss = () => {
52574
52582
  if (slot === "modal" || slot === "drawer") {
52575
- eventBus.emit("UI:CLOSE");
52576
- eventBus.emit("UI:CANCEL");
52583
+ const trait = content?.sourceTrait;
52584
+ const orbital = trait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(trait) : void 0;
52585
+ const prefix = orbital !== void 0 && trait !== void 0 ? `UI:${orbital}.${trait}.` : "UI:";
52586
+ eventBus.emit(`${prefix}CLOSE`);
52587
+ eventBus.emit(`${prefix}CANCEL`);
52577
52588
  }
52578
52589
  clear(slot);
52579
52590
  };
@@ -52627,6 +52638,7 @@ function CompiledPortal({ slot, className, pattern, sourceTrait, children }) {
52627
52638
  const slotsBus = useUISlots();
52628
52639
  const eventBus = useEventBus();
52629
52640
  const { t } = useTranslate();
52641
+ const compiledPortalSchemaCtx = useEntitySchemaOptional();
52630
52642
  useEffect(() => {
52631
52643
  setPortalRoot(getOrCreatePortalRoot());
52632
52644
  }, []);
@@ -52635,8 +52647,10 @@ function CompiledPortal({ slot, className, pattern, sourceTrait, children }) {
52635
52647
  });
52636
52648
  const handleDismiss = () => {
52637
52649
  if (slot === "modal" || slot === "drawer") {
52638
- eventBus.emit("UI:CLOSE");
52639
- eventBus.emit("UI:CANCEL");
52650
+ const orbital = sourceTrait !== void 0 && compiledPortalSchemaCtx !== null ? compiledPortalSchemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
52651
+ const prefix = orbital !== void 0 && sourceTrait !== void 0 ? `UI:${orbital}.${sourceTrait}.` : "UI:";
52652
+ eventBus.emit(`${prefix}CLOSE`);
52653
+ eventBus.emit(`${prefix}CANCEL`);
52640
52654
  }
52641
52655
  slotsBus.clear(slot);
52642
52656
  };
@@ -52795,7 +52809,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
52795
52809
  const key = `${parentId}-${index}-trait:${traitName}`;
52796
52810
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
52797
52811
  }
52798
- return /* @__PURE__ */ jsx(React107__default.Fragment, { children: child }, `${parentId}-${index}`);
52812
+ return /* @__PURE__ */ jsx(React105__default.Fragment, { children: child }, `${parentId}-${index}`);
52799
52813
  }
52800
52814
  if (!child || typeof child !== "object") return null;
52801
52815
  const childId = `${parentId}-${index}`;
@@ -52835,14 +52849,14 @@ function isPatternConfig(value) {
52835
52849
  if (value === null || value === void 0) return false;
52836
52850
  if (typeof value !== "object") return false;
52837
52851
  if (Array.isArray(value)) return false;
52838
- if (React107__default.isValidElement(value)) return false;
52852
+ if (React105__default.isValidElement(value)) return false;
52839
52853
  if (value instanceof Date) return false;
52840
52854
  if (typeof value === "function") return false;
52841
52855
  const record = value;
52842
- return "type" in record && typeof record.type === "string" && getComponentForPattern(record.type) !== null;
52856
+ return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
52843
52857
  }
52844
52858
  function isPlainConfigObject(value) {
52845
- if (React107__default.isValidElement(value)) return false;
52859
+ if (React105__default.isValidElement(value)) return false;
52846
52860
  if (value instanceof Date) return false;
52847
52861
  const proto = Object.getPrototypeOf(value);
52848
52862
  return proto === Object.prototype || proto === null;
@@ -52948,7 +52962,7 @@ function SlotContentRenderer({
52948
52962
  }
52949
52963
  }
52950
52964
  const orbitalName = schemaCtx && content.sourceTrait !== void 0 ? schemaCtx.orbitalsByTrait.get(content.sourceTrait) : void 0;
52951
- const PatternComponent = getComponentForPattern3(content.pattern);
52965
+ const PatternComponent = getComponentForPattern(content.pattern);
52952
52966
  if (PatternComponent) {
52953
52967
  const childrenConfig = content.props.children;
52954
52968
  const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
@@ -52968,7 +52982,7 @@ function SlotContentRenderer({
52968
52982
  for (const slotKey of CONTENT_NODE_SLOTS) {
52969
52983
  const slotVal = restProps[slotKey];
52970
52984
  if (slotVal === void 0 || slotVal === null) continue;
52971
- if (React107__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
52985
+ if (React105__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
52972
52986
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
52973
52987
  nodeSlotOverrides[slotKey] = renderPatternChildren(
52974
52988
  slotVal,
@@ -53017,7 +53031,7 @@ function SlotContentRenderer({
53017
53031
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
53018
53032
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
53019
53033
  const sample = resolvedItems[0];
53020
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React107__default.isValidElement(sample) && !(sample instanceof Date)) {
53034
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React105__default.isValidElement(sample) && !(sample instanceof Date)) {
53021
53035
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
53022
53036
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
53023
53037
  }
@@ -53195,6 +53209,7 @@ var init_UISlotRenderer = __esm({
53195
53209
  "custom",
53196
53210
  "dashboard-layout",
53197
53211
  "game-shell",
53212
+ "game-template",
53198
53213
  "scaled-diagram",
53199
53214
  "master-detail",
53200
53215
  "form-field",
@@ -54050,7 +54065,7 @@ function useEntitySchema() {
54050
54065
  }
54051
54066
  return context;
54052
54067
  }
54053
- function useEntitySchemaOptional3() {
54068
+ function useEntitySchemaOptional6() {
54054
54069
  return useContext(EntitySchemaContext);
54055
54070
  }
54056
54071
  var log11 = createLogger("almadar:ui:navigation");
@@ -54577,4 +54592,4 @@ function useOptionalOfflineMode() {
54577
54592
  return useContext(OfflineModeContext);
54578
54593
  }
54579
54594
 
54580
- export { ANONYMOUS_USER, CurrentPagePathContext, CurrentPagePathProvider, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntitySchema, useEntitySchemaOptional3 as useEntitySchemaOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope2 as useTraitScope, useUser, useUserForEvaluation };
54595
+ export { ANONYMOUS_USER, CurrentPagePathContext, CurrentPagePathProvider, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntitySchema, useEntitySchemaOptional6 as useEntitySchemaOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope2 as useTraitScope, useUser, useUserForEvaluation };