@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 React105 from 'react';
2
- import React105__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, createContext, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
1
+ import * as React103 from 'react';
2
+ import React103__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, createContext, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
3
3
  import { EventBusContext, useTraitScope, useEntitySchemaOptional, useEntitySchema, getAllPages, OrbitalProvider, TraitScopeProvider, ServerBridgeProvider, useCurrentPagePath, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge } from '@almadar/ui/providers';
4
4
  export { EntitySchemaProvider, ServerBridgeProvider, TraitContext, TraitProvider, useEntitySchema, useEntitySchemaOptional, useServerBridge, useTrait, useTraitContext } from '@almadar/ui/providers';
5
5
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
@@ -12,7 +12,6 @@ import { createPortal } from 'react-dom';
12
12
  import { useTranslate } from '@almadar/ui/hooks';
13
13
  import { useUISlots, UISlotProvider, useTheme } from '@almadar/ui/context';
14
14
  import { evaluateGuard, 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
  import { StateMachineManager, collectDeclaredConfigDefaults, createServerEffectHandlers, EffectExecutor, createContextFromBindings, InMemoryPersistence } from '@almadar/runtime';
47
47
  import { OrbitalServerRuntime } from '@almadar/runtime/OrbitalServerRuntime';
48
48
 
@@ -937,7 +937,7 @@ var init_Box = __esm({
937
937
  fixed: "fixed",
938
938
  sticky: "sticky"
939
939
  };
940
- Box = React105__default.forwardRef(
940
+ Box = React103__default.forwardRef(
941
941
  ({
942
942
  padding,
943
943
  paddingX,
@@ -1002,7 +1002,7 @@ var init_Box = __esm({
1002
1002
  onPointerDown?.(e);
1003
1003
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
1004
1004
  const isClickable = action || onClick;
1005
- return React105__default.createElement(
1005
+ return React103__default.createElement(
1006
1006
  Component,
1007
1007
  {
1008
1008
  ref,
@@ -1098,7 +1098,7 @@ function loadLib(key, importer) {
1098
1098
  return p2;
1099
1099
  }
1100
1100
  function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
1101
- const Lazy = React105__default.lazy(async () => {
1101
+ const Lazy = React103__default.lazy(async () => {
1102
1102
  const lib = await loadLib(libKey, importer);
1103
1103
  const Comp = pick(lib);
1104
1104
  if (!Comp) {
@@ -1108,7 +1108,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
1108
1108
  return { default: Comp };
1109
1109
  });
1110
1110
  const Wrapped = (props) => /* @__PURE__ */ jsx(
1111
- React105__default.Suspense,
1111
+ React103__default.Suspense,
1112
1112
  {
1113
1113
  fallback: /* @__PURE__ */ jsx(
1114
1114
  "span",
@@ -1839,7 +1839,7 @@ var init_Icon = __esm({
1839
1839
  const directIcon = typeof icon === "string" ? void 0 : icon;
1840
1840
  const effectiveName = typeof icon === "string" ? icon : name;
1841
1841
  const family = useIconFamily();
1842
- const RenderedComponent = React105__default.useMemo(() => {
1842
+ const RenderedComponent = React103__default.useMemo(() => {
1843
1843
  if (directIcon) return null;
1844
1844
  return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
1845
1845
  }, [directIcon, effectiveName, family]);
@@ -1901,7 +1901,7 @@ function resolveIconProp(value, sizeClass) {
1901
1901
  const IconComp = value;
1902
1902
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1903
1903
  }
1904
- if (React105__default.isValidElement(value)) {
1904
+ if (React103__default.isValidElement(value)) {
1905
1905
  return value;
1906
1906
  }
1907
1907
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -1977,7 +1977,7 @@ var init_Button = __esm({
1977
1977
  md: "h-icon-default w-icon-default",
1978
1978
  lg: "h-icon-default w-icon-default"
1979
1979
  };
1980
- Button = React105__default.forwardRef(
1980
+ Button = React103__default.forwardRef(
1981
1981
  ({
1982
1982
  className,
1983
1983
  variant = "primary",
@@ -2043,7 +2043,7 @@ var Dialog;
2043
2043
  var init_Dialog = __esm({
2044
2044
  "components/core/atoms/Dialog.tsx"() {
2045
2045
  init_cn();
2046
- Dialog = React105__default.forwardRef(
2046
+ Dialog = React103__default.forwardRef(
2047
2047
  ({
2048
2048
  role = "dialog",
2049
2049
  "aria-modal": ariaModal = true,
@@ -2161,7 +2161,7 @@ var init_Typography = __esm({
2161
2161
  }) => {
2162
2162
  const variant = variantProp ?? (level ? `h${level}` : "body1");
2163
2163
  const Component = as || defaultElements[variant];
2164
- return React105__default.createElement(
2164
+ return React103__default.createElement(
2165
2165
  Component,
2166
2166
  {
2167
2167
  id,
@@ -2656,7 +2656,7 @@ var init_Badge = __esm({
2656
2656
  md: "px-2.5 py-1 text-sm",
2657
2657
  lg: "px-3 py-1.5 text-base"
2658
2658
  };
2659
- Badge = React105__default.forwardRef(
2659
+ Badge = React103__default.forwardRef(
2660
2660
  ({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
2661
2661
  const iconSizes3 = {
2662
2662
  sm: "h-icon-default w-icon-default",
@@ -2992,7 +2992,7 @@ var init_SvgFlow = __esm({
2992
2992
  width = 100,
2993
2993
  height = 100
2994
2994
  }) => {
2995
- const markerId = React105__default.useMemo(() => {
2995
+ const markerId = React103__default.useMemo(() => {
2996
2996
  flowIdCounter += 1;
2997
2997
  return `almadar-flow-arrow-${flowIdCounter}`;
2998
2998
  }, []);
@@ -3585,7 +3585,7 @@ var init_SvgRing = __esm({
3585
3585
  width = 100,
3586
3586
  height = 100
3587
3587
  }) => {
3588
- const gradientId = React105__default.useMemo(() => {
3588
+ const gradientId = React103__default.useMemo(() => {
3589
3589
  ringIdCounter += 1;
3590
3590
  return `almadar-ring-glow-${ringIdCounter}`;
3591
3591
  }, []);
@@ -3766,7 +3766,7 @@ var init_Input = __esm({
3766
3766
  init_cn();
3767
3767
  init_Icon();
3768
3768
  init_useEventBus();
3769
- Input = React105__default.forwardRef(
3769
+ Input = React103__default.forwardRef(
3770
3770
  ({
3771
3771
  className,
3772
3772
  inputType,
@@ -3926,7 +3926,7 @@ var Label;
3926
3926
  var init_Label = __esm({
3927
3927
  "components/core/atoms/Label.tsx"() {
3928
3928
  init_cn();
3929
- Label = React105__default.forwardRef(
3929
+ Label = React103__default.forwardRef(
3930
3930
  ({ className, required, children, ...props }, ref) => {
3931
3931
  return /* @__PURE__ */ jsxs(
3932
3932
  "label",
@@ -3953,7 +3953,7 @@ var init_Textarea = __esm({
3953
3953
  "components/core/atoms/Textarea.tsx"() {
3954
3954
  init_cn();
3955
3955
  init_useEventBus();
3956
- Textarea = React105__default.forwardRef(
3956
+ Textarea = React103__default.forwardRef(
3957
3957
  ({ className, error, onChange, ...props }, ref) => {
3958
3958
  const eventBus = useEventBus();
3959
3959
  const handleChange = (e) => {
@@ -4192,7 +4192,7 @@ var init_Select = __esm({
4192
4192
  init_cn();
4193
4193
  init_Icon();
4194
4194
  init_useEventBus();
4195
- Select = React105__default.forwardRef(
4195
+ Select = React103__default.forwardRef(
4196
4196
  (props, _ref) => {
4197
4197
  const { multiple, searchable, clearable } = props;
4198
4198
  if (multiple || searchable || clearable) {
@@ -4209,7 +4209,7 @@ var init_Checkbox = __esm({
4209
4209
  "components/core/atoms/Checkbox.tsx"() {
4210
4210
  init_cn();
4211
4211
  init_useEventBus();
4212
- Checkbox = React105__default.forwardRef(
4212
+ Checkbox = React103__default.forwardRef(
4213
4213
  ({ className, label, id, onChange, ...props }, ref) => {
4214
4214
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
4215
4215
  const eventBus = useEventBus();
@@ -4263,7 +4263,7 @@ var init_Spinner = __esm({
4263
4263
  md: "h-6 w-6",
4264
4264
  lg: "h-8 w-8"
4265
4265
  };
4266
- Spinner = React105__default.forwardRef(
4266
+ Spinner = React103__default.forwardRef(
4267
4267
  ({ className, size = "md", overlay, ...props }, ref) => {
4268
4268
  if (overlay) {
4269
4269
  return /* @__PURE__ */ jsx(
@@ -4353,7 +4353,7 @@ var init_Card = __esm({
4353
4353
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
4354
4354
  "tile-image-first": "p-0 overflow-hidden"
4355
4355
  };
4356
- Card = React105__default.forwardRef(
4356
+ Card = React103__default.forwardRef(
4357
4357
  ({
4358
4358
  className,
4359
4359
  variant = "bordered",
@@ -4401,9 +4401,9 @@ var init_Card = __esm({
4401
4401
  }
4402
4402
  );
4403
4403
  Card.displayName = "Card";
4404
- CardHeader = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
4404
+ CardHeader = React103__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
4405
4405
  CardHeader.displayName = "CardHeader";
4406
- CardTitle = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4406
+ CardTitle = React103__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4407
4407
  "h3",
4408
4408
  {
4409
4409
  ref,
@@ -4416,11 +4416,11 @@ var init_Card = __esm({
4416
4416
  }
4417
4417
  ));
4418
4418
  CardTitle.displayName = "CardTitle";
4419
- CardContent = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
4419
+ CardContent = React103__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
4420
4420
  CardContent.displayName = "CardContent";
4421
4421
  CardBody = CardContent;
4422
4422
  CardBody.displayName = "CardBody";
4423
- CardFooter = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4423
+ CardFooter = React103__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4424
4424
  "div",
4425
4425
  {
4426
4426
  ref,
@@ -4475,7 +4475,7 @@ var init_FilterPill = __esm({
4475
4475
  md: "w-3.5 h-3.5",
4476
4476
  lg: "w-4 h-4"
4477
4477
  };
4478
- FilterPill = React105__default.forwardRef(
4478
+ FilterPill = React103__default.forwardRef(
4479
4479
  ({
4480
4480
  className,
4481
4481
  variant = "default",
@@ -4604,8 +4604,8 @@ var init_Avatar = __esm({
4604
4604
  actionPayload
4605
4605
  }) => {
4606
4606
  const eventBus = useEventBus();
4607
- const [imgFailed, setImgFailed] = React105__default.useState(false);
4608
- React105__default.useEffect(() => {
4607
+ const [imgFailed, setImgFailed] = React103__default.useState(false);
4608
+ React103__default.useEffect(() => {
4609
4609
  setImgFailed(false);
4610
4610
  }, [src]);
4611
4611
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -4718,7 +4718,7 @@ var init_Center = __esm({
4718
4718
  as: Component = "div"
4719
4719
  }) => {
4720
4720
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
4721
- return React105__default.createElement(Component, {
4721
+ return React103__default.createElement(Component, {
4722
4722
  className: cn(
4723
4723
  inline ? "inline-flex" : "flex",
4724
4724
  horizontal && "justify-center",
@@ -4986,7 +4986,7 @@ var init_Radio = __esm({
4986
4986
  md: "w-2.5 h-2.5",
4987
4987
  lg: "w-3 h-3"
4988
4988
  };
4989
- Radio = React105__default.forwardRef(
4989
+ Radio = React103__default.forwardRef(
4990
4990
  ({
4991
4991
  label,
4992
4992
  helperText,
@@ -5003,12 +5003,12 @@ var init_Radio = __esm({
5003
5003
  onChange,
5004
5004
  ...props
5005
5005
  }, ref) => {
5006
- const reactId = React105__default.useId();
5006
+ const reactId = React103__default.useId();
5007
5007
  const baseId = id || `radio-${reactId}`;
5008
5008
  const hasError = !!error;
5009
5009
  const eventBus = useEventBus();
5010
- const [selected, setSelected] = React105__default.useState(value);
5011
- React105__default.useEffect(() => {
5010
+ const [selected, setSelected] = React103__default.useState(value);
5011
+ React103__default.useEffect(() => {
5012
5012
  if (value !== void 0) setSelected(value);
5013
5013
  }, [value]);
5014
5014
  const pick = (next, e) => {
@@ -5190,7 +5190,7 @@ var init_Switch = __esm({
5190
5190
  "components/core/atoms/Switch.tsx"() {
5191
5191
  "use client";
5192
5192
  init_cn();
5193
- Switch = React105.forwardRef(
5193
+ Switch = React103.forwardRef(
5194
5194
  ({
5195
5195
  checked,
5196
5196
  defaultChecked = false,
@@ -5201,10 +5201,10 @@ var init_Switch = __esm({
5201
5201
  name,
5202
5202
  className
5203
5203
  }, ref) => {
5204
- const [isChecked, setIsChecked] = React105.useState(
5204
+ const [isChecked, setIsChecked] = React103.useState(
5205
5205
  checked !== void 0 ? checked : defaultChecked
5206
5206
  );
5207
- React105.useEffect(() => {
5207
+ React103.useEffect(() => {
5208
5208
  if (checked !== void 0) {
5209
5209
  setIsChecked(checked);
5210
5210
  }
@@ -5367,7 +5367,7 @@ var init_Stack = __esm({
5367
5367
  };
5368
5368
  const isHorizontal = direction === "horizontal";
5369
5369
  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";
5370
- return React105__default.createElement(
5370
+ return React103__default.createElement(
5371
5371
  Component,
5372
5372
  {
5373
5373
  className: cn(
@@ -5567,7 +5567,7 @@ var Aside;
5567
5567
  var init_Aside = __esm({
5568
5568
  "components/core/atoms/Aside.tsx"() {
5569
5569
  init_cn();
5570
- Aside = React105__default.forwardRef(
5570
+ Aside = React103__default.forwardRef(
5571
5571
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
5572
5572
  );
5573
5573
  Aside.displayName = "Aside";
@@ -5646,9 +5646,9 @@ var init_LawReferenceTooltip = __esm({
5646
5646
  className
5647
5647
  }) => {
5648
5648
  const { t } = useTranslate();
5649
- const [isVisible, setIsVisible] = React105__default.useState(false);
5650
- const timeoutRef = React105__default.useRef(null);
5651
- const triggerRef = React105__default.useRef(null);
5649
+ const [isVisible, setIsVisible] = React103__default.useState(false);
5650
+ const timeoutRef = React103__default.useRef(null);
5651
+ const triggerRef = React103__default.useRef(null);
5652
5652
  const handleMouseEnter = () => {
5653
5653
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5654
5654
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -5659,7 +5659,7 @@ var init_LawReferenceTooltip = __esm({
5659
5659
  };
5660
5660
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
5661
5661
  const open = isVisible || revealed;
5662
- React105__default.useEffect(() => {
5662
+ React103__default.useEffect(() => {
5663
5663
  return () => {
5664
5664
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5665
5665
  };
@@ -5869,7 +5869,7 @@ var init_StatusDot = __esm({
5869
5869
  md: "w-2.5 h-2.5",
5870
5870
  lg: "w-3 h-3"
5871
5871
  };
5872
- StatusDot = React105__default.forwardRef(
5872
+ StatusDot = React103__default.forwardRef(
5873
5873
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
5874
5874
  return /* @__PURE__ */ jsx(
5875
5875
  "span",
@@ -5923,7 +5923,7 @@ var init_TrendIndicator = __esm({
5923
5923
  down: "trending-down",
5924
5924
  flat: "arrow-right"
5925
5925
  };
5926
- TrendIndicator = React105__default.forwardRef(
5926
+ TrendIndicator = React103__default.forwardRef(
5927
5927
  ({
5928
5928
  className,
5929
5929
  value,
@@ -5990,7 +5990,7 @@ var init_RangeSlider = __esm({
5990
5990
  md: "w-4 h-4",
5991
5991
  lg: "w-5 h-5"
5992
5992
  };
5993
- RangeSlider = React105__default.forwardRef(
5993
+ RangeSlider = React103__default.forwardRef(
5994
5994
  ({
5995
5995
  className,
5996
5996
  min = 0,
@@ -6549,7 +6549,7 @@ var init_ContentSection = __esm({
6549
6549
  md: "py-16",
6550
6550
  lg: "py-24"
6551
6551
  };
6552
- ContentSection = React105__default.forwardRef(
6552
+ ContentSection = React103__default.forwardRef(
6553
6553
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
6554
6554
  return /* @__PURE__ */ jsx(
6555
6555
  Box,
@@ -7083,7 +7083,7 @@ var init_AnimatedReveal = __esm({
7083
7083
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
7084
7084
  "none": {}
7085
7085
  };
7086
- AnimatedReveal = React105__default.forwardRef(
7086
+ AnimatedReveal = React103__default.forwardRef(
7087
7087
  ({
7088
7088
  trigger = "scroll",
7089
7089
  animation = "fade-up",
@@ -7243,7 +7243,7 @@ var init_AnimatedGraphic = __esm({
7243
7243
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
7244
7244
  "use client";
7245
7245
  init_cn();
7246
- AnimatedGraphic = React105__default.forwardRef(
7246
+ AnimatedGraphic = React103__default.forwardRef(
7247
7247
  ({
7248
7248
  src,
7249
7249
  svgContent,
@@ -7266,7 +7266,7 @@ var init_AnimatedGraphic = __esm({
7266
7266
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
7267
7267
  const resolvedSvg = svgContent ?? fetchedSvg;
7268
7268
  const prevAnimateRef = useRef(animate);
7269
- const setRef = React105__default.useCallback(
7269
+ const setRef = React103__default.useCallback(
7270
7270
  (node) => {
7271
7271
  containerRef.current = node;
7272
7272
  if (typeof ref === "function") ref(node);
@@ -8883,6 +8883,38 @@ var init_shared = __esm({
8883
8883
  init_canvasEffects();
8884
8884
  }
8885
8885
  });
8886
+ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
8887
+ const px = typeof size === "number" ? size : sizeMap[size];
8888
+ if (assetUrl?.url) {
8889
+ return /* @__PURE__ */ jsx(
8890
+ "img",
8891
+ {
8892
+ src: assetUrl.url,
8893
+ alt: alt ?? assetUrl.category ?? "",
8894
+ width: px,
8895
+ height: px,
8896
+ style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
8897
+ className: cn("flex-shrink-0", className)
8898
+ }
8899
+ );
8900
+ }
8901
+ const I = typeof icon === "string" ? resolveIcon(icon) : icon;
8902
+ return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
8903
+ }
8904
+ var sizeMap;
8905
+ var init_GameIcon = __esm({
8906
+ "components/game/2d/atoms/GameIcon.tsx"() {
8907
+ "use client";
8908
+ init_cn();
8909
+ init_Icon();
8910
+ sizeMap = {
8911
+ sm: 16,
8912
+ md: 24,
8913
+ lg: 32
8914
+ };
8915
+ GameIcon.displayName = "GameIcon";
8916
+ }
8917
+ });
8886
8918
  function GameCard({
8887
8919
  id,
8888
8920
  cost,
@@ -8898,16 +8930,16 @@ function GameCard({
8898
8930
  className
8899
8931
  }) {
8900
8932
  const eventBus = useEventBus();
8901
- const handleClick = React105.useCallback(() => {
8933
+ const handleClick = React103.useCallback(() => {
8902
8934
  if (disabled) return;
8903
8935
  onClick?.(id);
8904
8936
  if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { cardId: id });
8905
8937
  }, [disabled, id, onClick, clickEvent, eventBus]);
8906
8938
  const artPx = artPxMap[size];
8907
8939
  return /* @__PURE__ */ jsxs(
8908
- "button",
8940
+ Button,
8909
8941
  {
8910
- type: "button",
8942
+ variant: "ghost",
8911
8943
  onClick: handleClick,
8912
8944
  disabled,
8913
8945
  title: name,
@@ -8921,8 +8953,9 @@ function GameCard({
8921
8953
  ),
8922
8954
  children: [
8923
8955
  cost != null && /* @__PURE__ */ jsx(
8924
- "span",
8956
+ Typography,
8925
8957
  {
8958
+ as: "span",
8926
8959
  className: cn(
8927
8960
  "absolute -top-2 -left-2 flex items-center justify-center",
8928
8961
  "min-w-[22px] h-[22px] rounded-full px-1",
@@ -8931,17 +8964,7 @@ function GameCard({
8931
8964
  children: cost
8932
8965
  }
8933
8966
  ),
8934
- /* @__PURE__ */ jsx(Box, { className: "flex-1 flex items-center justify-center w-full", children: art ? /* @__PURE__ */ jsx(
8935
- "img",
8936
- {
8937
- src: art.url,
8938
- alt: name ?? id,
8939
- width: artPx,
8940
- height: artPx,
8941
- style: { imageRendering: "pixelated", objectFit: "contain" },
8942
- className: "flex-shrink-0"
8943
- }
8944
- ) : /* @__PURE__ */ jsx(Box, { className: "rounded bg-muted/40", style: { width: artPx, height: artPx } }) }),
8967
+ /* @__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 } }) }),
8945
8968
  name != null && /* @__PURE__ */ jsx(
8946
8969
  Typography,
8947
8970
  {
@@ -8951,8 +8974,8 @@ function GameCard({
8951
8974
  }
8952
8975
  ),
8953
8976
  (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: [
8954
- /* @__PURE__ */ jsx("span", { className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
8955
- /* @__PURE__ */ jsx("span", { className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
8977
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-error", children: attack != null ? `\u2694${attack}` : "" }),
8978
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-info", children: defense != null ? `\u{1F6E1}${defense}` : "" })
8956
8979
  ] })
8957
8980
  ]
8958
8981
  }
@@ -8965,7 +8988,9 @@ var init_GameCard = __esm({
8965
8988
  init_cn();
8966
8989
  init_useEventBus();
8967
8990
  init_Box();
8991
+ init_Button();
8968
8992
  init_Typography();
8993
+ init_GameIcon();
8969
8994
  cardSizeMap = {
8970
8995
  sm: "w-16 h-24",
8971
8996
  md: "w-20 h-28",
@@ -8984,14 +9009,17 @@ function HealthBar({
8984
9009
  labelSuffix,
8985
9010
  size = "md",
8986
9011
  className,
8987
- animated = true
9012
+ animated = true,
9013
+ frameAsset,
9014
+ fillAsset
8988
9015
  }) {
8989
- const sizes = sizeMap[size];
9016
+ const sizes = sizeMap2[size];
8990
9017
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
8991
9018
  if (format === "hearts") {
8992
- return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
8993
- "span",
9019
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center gap-1", className), children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx(
9020
+ Box,
8994
9021
  {
9022
+ as: "span",
8995
9023
  className: cn(animated && "transition-transform hover:scale-110"),
8996
9024
  children: heartIcon(i < current, sizes.heart)
8997
9025
  },
@@ -9000,33 +9028,42 @@ function HealthBar({
9000
9028
  }
9001
9029
  if (format === "bar") {
9002
9030
  return /* @__PURE__ */ jsx(
9003
- "div",
9031
+ Box,
9004
9032
  {
9033
+ position: "relative",
9034
+ overflow: "hidden",
9005
9035
  className: cn(
9006
- "relative overflow-hidden rounded-full bg-muted",
9036
+ "rounded-full",
9037
+ !frameAsset && "bg-muted",
9007
9038
  sizes.bar,
9008
9039
  "w-24",
9009
9040
  className
9010
9041
  ),
9042
+ style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
9011
9043
  children: /* @__PURE__ */ jsx(
9012
- "div",
9044
+ Box,
9013
9045
  {
9046
+ position: "absolute",
9014
9047
  className: cn(
9015
- "absolute inset-y-0 left-0 rounded-full",
9016
- percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error",
9048
+ "inset-y-0 left-0 rounded-full",
9049
+ !fillAsset && (percentage > 66 ? "bg-success" : percentage > 33 ? "bg-warning" : "bg-error"),
9017
9050
  animated && "transition-all duration-300"
9018
9051
  ),
9019
- style: { width: `${percentage}%` }
9052
+ style: {
9053
+ width: `${percentage}%`,
9054
+ ...fillAsset ? { backgroundImage: `url(${fillAsset.url})`, backgroundSize: "auto 100%" } : {}
9055
+ }
9020
9056
  }
9021
9057
  )
9022
9058
  }
9023
9059
  );
9024
9060
  }
9025
9061
  if (format === "progress") {
9026
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
9062
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex items-center gap-2", className), children: [
9027
9063
  level != null && /* @__PURE__ */ jsxs(
9028
- "span",
9064
+ Typography,
9029
9065
  {
9066
+ as: "span",
9030
9067
  className: cn(
9031
9068
  "flex-shrink-0 rounded-interactive font-bold",
9032
9069
  "bg-accent text-accent-foreground border border-accent",
@@ -9038,28 +9075,35 @@ function HealthBar({
9038
9075
  ]
9039
9076
  }
9040
9077
  ),
9041
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [
9078
+ /* @__PURE__ */ jsxs(Box, { className: "flex-1 flex flex-col gap-0.5", children: [
9042
9079
  /* @__PURE__ */ jsx(
9043
- "div",
9080
+ Box,
9044
9081
  {
9082
+ position: "relative",
9045
9083
  className: cn(
9046
- "relative w-full overflow-hidden rounded-full bg-muted border border-muted",
9084
+ "w-full overflow-hidden rounded-full",
9085
+ !frameAsset && "bg-muted border border-muted",
9047
9086
  sizes.bar
9048
9087
  ),
9088
+ style: frameAsset ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%" } : void 0,
9049
9089
  children: /* @__PURE__ */ jsx(
9050
- "div",
9090
+ Box,
9051
9091
  {
9092
+ position: "absolute",
9052
9093
  className: cn(
9053
- "absolute inset-y-0 left-0 rounded-full",
9054
- "bg-gradient-to-r from-accent to-info",
9094
+ "inset-y-0 left-0 rounded-full",
9095
+ !fillAsset && "bg-gradient-to-r from-accent to-info",
9055
9096
  animated && "transition-all duration-500 ease-out"
9056
9097
  ),
9057
- style: { width: `${percentage}%` }
9098
+ style: {
9099
+ width: `${percentage}%`,
9100
+ ...fillAsset ? { backgroundImage: `url(${fillAsset.url})`, backgroundSize: "auto 100%" } : {}
9101
+ }
9058
9102
  }
9059
9103
  )
9060
9104
  }
9061
9105
  ),
9062
- showLabel && /* @__PURE__ */ jsxs("span", { className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
9106
+ showLabel && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-foreground/70 tabular-nums", sizes.label), children: [
9063
9107
  current,
9064
9108
  " / ",
9065
9109
  max,
@@ -9068,16 +9112,18 @@ function HealthBar({
9068
9112
  ] })
9069
9113
  ] });
9070
9114
  }
9071
- return /* @__PURE__ */ jsxs("span", { className: cn("font-mono font-bold", sizes.text, className), children: [
9115
+ return /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-mono font-bold", sizes.text, className), children: [
9072
9116
  current,
9073
9117
  "/",
9074
9118
  max
9075
9119
  ] });
9076
9120
  }
9077
- var heartIcon, sizeMap;
9121
+ var heartIcon, sizeMap2;
9078
9122
  var init_HealthBar = __esm({
9079
9123
  "components/game/2d/atoms/HealthBar.tsx"() {
9080
9124
  init_cn();
9125
+ init_Box();
9126
+ init_Typography();
9081
9127
  heartIcon = (filled, size) => /* @__PURE__ */ jsx(
9082
9128
  "svg",
9083
9129
  {
@@ -9089,7 +9135,7 @@ var init_HealthBar = __esm({
9089
9135
  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" })
9090
9136
  }
9091
9137
  );
9092
- sizeMap = {
9138
+ sizeMap2 = {
9093
9139
  sm: { heart: "w-4 h-4", bar: "h-2", text: "text-sm", label: "text-xs", badge: "text-xs px-1.5 py-0.5" },
9094
9140
  md: { heart: "w-6 h-6", bar: "h-3", text: "text-base", label: "text-xs", badge: "text-xs px-2 py-0.5" },
9095
9141
  lg: { heart: "w-8 h-8", bar: "h-4", text: "text-lg", label: "text-sm", badge: "text-sm px-2.5 py-1" }
@@ -9110,37 +9156,30 @@ function ScoreDisplay({
9110
9156
  const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
9111
9157
  const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
9112
9158
  return /* @__PURE__ */ jsxs(
9113
- "div",
9159
+ Box,
9114
9160
  {
9115
9161
  className: cn(
9116
9162
  "flex items-center gap-2 font-bold",
9117
- sizeMap2[size],
9163
+ sizeMap3[size],
9118
9164
  className
9119
9165
  ),
9120
9166
  children: [
9121
- assetUrl ? /* @__PURE__ */ jsx(
9122
- "img",
9123
- {
9124
- src: assetUrl.url,
9125
- alt: "",
9126
- width: 20,
9127
- height: 20,
9128
- style: { imageRendering: "pixelated", objectFit: "contain" },
9129
- className: "flex-shrink-0"
9130
- }
9131
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9132
- label && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
9133
- /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formattedValue })
9167
+ 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,
9168
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
9169
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "tabular-nums", children: formattedValue })
9134
9170
  ]
9135
9171
  }
9136
9172
  );
9137
9173
  }
9138
- var sizeMap2, DEFAULT_ASSET_URL;
9174
+ var sizeMap3, DEFAULT_ASSET_URL;
9139
9175
  var init_ScoreDisplay = __esm({
9140
9176
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
9141
9177
  init_cn();
9142
9178
  init_Icon();
9143
- sizeMap2 = {
9179
+ init_Box();
9180
+ init_Typography();
9181
+ init_GameIcon();
9182
+ sizeMap3 = {
9144
9183
  sm: "text-sm",
9145
9184
  md: "text-lg",
9146
9185
  lg: "text-2xl",
@@ -9170,9 +9209,9 @@ function ControlButton({
9170
9209
  className
9171
9210
  }) {
9172
9211
  const eventBus = useEventBus();
9173
- const [isPressed, setIsPressed] = React105.useState(false);
9212
+ const [isPressed, setIsPressed] = React103.useState(false);
9174
9213
  const actualPressed = pressed ?? isPressed;
9175
- const handlePointerDown = React105.useCallback(
9214
+ const handlePointerDown = React103.useCallback(
9176
9215
  (e) => {
9177
9216
  e.preventDefault();
9178
9217
  if (disabled) return;
@@ -9182,7 +9221,7 @@ function ControlButton({
9182
9221
  },
9183
9222
  [disabled, pressEvent, eventBus, onPress]
9184
9223
  );
9185
- const handlePointerUp = React105.useCallback(
9224
+ const handlePointerUp = React103.useCallback(
9186
9225
  (e) => {
9187
9226
  e.preventDefault();
9188
9227
  if (disabled) return;
@@ -9192,7 +9231,7 @@ function ControlButton({
9192
9231
  },
9193
9232
  [disabled, releaseEvent, eventBus, onRelease]
9194
9233
  );
9195
- const handlePointerLeave = React105.useCallback(
9234
+ const handlePointerLeave = React103.useCallback(
9196
9235
  (e) => {
9197
9236
  if (isPressed) {
9198
9237
  setIsPressed(false);
@@ -9203,9 +9242,9 @@ function ControlButton({
9203
9242
  [isPressed, releaseEvent, eventBus, onRelease]
9204
9243
  );
9205
9244
  return /* @__PURE__ */ jsx(
9206
- "button",
9245
+ Button,
9207
9246
  {
9208
- type: "button",
9247
+ variant,
9209
9248
  disabled,
9210
9249
  onPointerDown: handlePointerDown,
9211
9250
  onPointerUp: handlePointerUp,
@@ -9216,41 +9255,35 @@ function ControlButton({
9216
9255
  "select-none touch-none",
9217
9256
  "transition-all duration-100",
9218
9257
  "active:scale-95",
9219
- sizeMap3[size] ?? sizeMap3.md,
9258
+ sizeMap4[size] ?? sizeMap4.md,
9220
9259
  shapeMap[shape] ?? shapeMap.circle,
9221
9260
  variantMap[variant] ?? variantMap.secondary,
9222
9261
  actualPressed && "scale-95 brightness-110 border-foreground",
9223
9262
  disabled && "opacity-50 cursor-not-allowed",
9224
9263
  className
9225
9264
  ),
9226
- children: assetUrl ? /* @__PURE__ */ jsx(
9227
- "img",
9228
- {
9229
- src: assetUrl.url,
9230
- alt: "",
9231
- width: 24,
9232
- height: 24,
9233
- style: { imageRendering: "pixelated", objectFit: "contain" },
9234
- className: "flex-shrink-0"
9235
- }
9236
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "text-2xl", children: typeof icon === "string" ? /^[a-zA-Z0-9-]+$/.test(icon) ? (() => {
9265
+ 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) ? (() => {
9237
9266
  const I = resolveIcon(icon);
9238
9267
  return I ? /* @__PURE__ */ jsx(I, { className: "w-6 h-6" }) : null;
9239
9268
  })() : icon : /* @__PURE__ */ (() => {
9240
9269
  const I = icon;
9241
9270
  return /* @__PURE__ */ jsx(I, { className: "w-6 h-6" });
9242
- })() }) : label ? /* @__PURE__ */ jsx("span", { children: label }) : null
9271
+ })() }) : label ? /* @__PURE__ */ jsx(Typography, { as: "span", children: label }) : null
9243
9272
  }
9244
9273
  );
9245
9274
  }
9246
- var sizeMap3, shapeMap, variantMap, DEFAULT_ASSET_URL2;
9275
+ var sizeMap4, shapeMap, variantMap, DEFAULT_ASSET_URL2;
9247
9276
  var init_ControlButton = __esm({
9248
9277
  "components/game/2d/atoms/ControlButton.tsx"() {
9249
9278
  "use client";
9250
9279
  init_cn();
9251
9280
  init_useEventBus();
9252
9281
  init_Icon();
9253
- sizeMap3 = {
9282
+ init_Button();
9283
+ init_Box();
9284
+ init_Typography();
9285
+ init_GameIcon();
9286
+ sizeMap4 = {
9254
9287
  sm: "w-10 h-10 text-sm",
9255
9288
  md: "w-14 h-14 text-base",
9256
9289
  lg: "w-18 h-18 text-lg",
@@ -9320,12 +9353,12 @@ function Sprite({
9320
9353
  onClick?.();
9321
9354
  };
9322
9355
  return /* @__PURE__ */ jsx(
9323
- "div",
9356
+ Box,
9324
9357
  {
9358
+ position: "absolute",
9325
9359
  className,
9326
9360
  onClick: action || onClick ? handleClick : void 0,
9327
9361
  style: {
9328
- position: "absolute",
9329
9362
  width: frameWidth,
9330
9363
  height: frameHeight,
9331
9364
  backgroundImage: `url(${spritesheet.url})`,
@@ -9346,6 +9379,7 @@ var init_Sprite = __esm({
9346
9379
  "components/game/2d/atoms/Sprite.tsx"() {
9347
9380
  "use client";
9348
9381
  init_useEventBus();
9382
+ init_Box();
9349
9383
  init_spriteAnimation();
9350
9384
  DEFAULT_SPRITESHEET = {
9351
9385
  url: "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
@@ -9382,17 +9416,7 @@ function StateIndicator({
9382
9416
  className
9383
9417
  ),
9384
9418
  children: [
9385
- /* @__PURE__ */ jsx(Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsx(
9386
- "img",
9387
- {
9388
- src: assetUrl.url,
9389
- alt: displayLabel,
9390
- width: 16,
9391
- height: 16,
9392
- style: { imageRendering: "pixelated", objectFit: "contain" },
9393
- className: "flex-shrink-0"
9394
- }
9395
- ) : 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 }) }),
9419
+ /* @__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 }) }),
9396
9420
  /* @__PURE__ */ jsx(Box, { as: "span", children: displayLabel })
9397
9421
  ]
9398
9422
  }
@@ -9404,6 +9428,7 @@ var init_StateIndicator = __esm({
9404
9428
  init_Box();
9405
9429
  init_Icon();
9406
9430
  init_cn();
9431
+ init_GameIcon();
9407
9432
  DEFAULT_ASSET_URL3 = {
9408
9433
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
9409
9434
  role: "ui",
@@ -9452,30 +9477,36 @@ function TimerDisplay({
9452
9477
  format = "mm:ss",
9453
9478
  size = "md",
9454
9479
  className,
9455
- lowThreshold
9480
+ lowThreshold,
9481
+ iconAsset
9456
9482
  }) {
9457
9483
  const isLow = lowThreshold != null && seconds <= lowThreshold && seconds > 0;
9458
- return /* @__PURE__ */ jsx(
9459
- "div",
9484
+ return /* @__PURE__ */ jsxs(
9485
+ Box,
9460
9486
  {
9461
9487
  className: cn(
9462
- "inline-flex items-center justify-center rounded-container",
9488
+ "inline-flex items-center gap-1 justify-center rounded-container",
9463
9489
  "bg-card/80 border border-muted font-mono font-bold tabular-nums",
9464
- sizeMap4[size],
9490
+ sizeMap5[size],
9465
9491
  running && "border-success/50",
9466
9492
  isLow && "text-error border-error/50 animate-pulse",
9467
9493
  !isLow && "text-foreground",
9468
9494
  className
9469
9495
  ),
9470
- children: formatTime(seconds, format)
9496
+ children: [
9497
+ iconAsset && /* @__PURE__ */ jsx(GameIcon, { assetUrl: iconAsset, icon: "image", size: 16, className: "w-4 h-4 object-contain flex-shrink-0" }),
9498
+ formatTime(seconds, format)
9499
+ ]
9471
9500
  }
9472
9501
  );
9473
9502
  }
9474
- var sizeMap4;
9503
+ var sizeMap5;
9475
9504
  var init_TimerDisplay = __esm({
9476
9505
  "components/game/2d/atoms/TimerDisplay.tsx"() {
9477
9506
  init_cn();
9478
- sizeMap4 = {
9507
+ init_Box();
9508
+ init_GameIcon();
9509
+ sizeMap5 = {
9479
9510
  sm: "text-sm px-2 py-0.5",
9480
9511
  md: "text-lg px-3 py-1",
9481
9512
  lg: "text-2xl px-4 py-1.5"
@@ -9493,9 +9524,9 @@ function ResourceCounter({
9493
9524
  size = "md",
9494
9525
  className
9495
9526
  }) {
9496
- const sizes = sizeMap5[size];
9527
+ const sizes = sizeMap6[size];
9497
9528
  return /* @__PURE__ */ jsxs(
9498
- "div",
9529
+ Box,
9499
9530
  {
9500
9531
  className: cn(
9501
9532
  "inline-flex items-center rounded-container",
@@ -9504,21 +9535,11 @@ function ResourceCounter({
9504
9535
  className
9505
9536
  ),
9506
9537
  children: [
9507
- assetUrl ? /* @__PURE__ */ jsx(
9508
- "img",
9509
- {
9510
- src: assetUrl.url,
9511
- alt: label,
9512
- width: sizes.img,
9513
- height: sizes.img,
9514
- style: { imageRendering: "pixelated", objectFit: "contain" },
9515
- className: "flex-shrink-0"
9516
- }
9517
- ) : 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,
9518
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
9519
- /* @__PURE__ */ jsxs("span", { className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
9538
+ 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,
9539
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: label }),
9540
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
9520
9541
  value,
9521
- max != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9542
+ max != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
9522
9543
  "/",
9523
9544
  max
9524
9545
  ] })
@@ -9527,11 +9548,14 @@ function ResourceCounter({
9527
9548
  }
9528
9549
  );
9529
9550
  }
9530
- var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap5;
9551
+ var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap6;
9531
9552
  var init_ResourceCounter = __esm({
9532
9553
  "components/game/2d/atoms/ResourceCounter.tsx"() {
9533
9554
  init_cn();
9534
9555
  init_Icon();
9556
+ init_Box();
9557
+ init_Typography();
9558
+ init_GameIcon();
9535
9559
  colorTokenClasses2 = {
9536
9560
  primary: "text-primary",
9537
9561
  secondary: "text-secondary",
@@ -9545,7 +9569,7 @@ var init_ResourceCounter = __esm({
9545
9569
  role: "ui",
9546
9570
  category: "coin"
9547
9571
  };
9548
- sizeMap5 = {
9572
+ sizeMap6 = {
9549
9573
  sm: { wrapper: "text-xs gap-1 px-1.5 py-0.5", icon: "text-sm", img: 16 },
9550
9574
  md: { wrapper: "text-sm gap-1.5 px-2 py-1", icon: "text-base", img: 20 },
9551
9575
  lg: { wrapper: "text-base gap-2 px-3 py-1.5", icon: "text-lg", img: 28 }
@@ -9563,21 +9587,26 @@ function ItemSlot({
9563
9587
  size = "md",
9564
9588
  selected,
9565
9589
  onClick,
9590
+ action,
9566
9591
  className
9567
9592
  }) {
9568
- const isClickable = onClick != null;
9593
+ const eventBus = useEventBus();
9594
+ const isClickable = onClick != null || action != null;
9569
9595
  const px = assetSizeMap[size];
9570
9596
  return /* @__PURE__ */ jsx(
9571
- "button",
9597
+ Button,
9572
9598
  {
9573
- type: "button",
9574
- onClick,
9599
+ variant: "ghost",
9600
+ onClick: () => {
9601
+ if (action) eventBus.emit(`UI:${action}`, {});
9602
+ onClick?.();
9603
+ },
9575
9604
  disabled: !isClickable,
9576
9605
  title: label,
9577
9606
  className: cn(
9578
9607
  "relative flex items-center justify-center rounded-interactive border-2",
9579
9608
  "bg-card/80 transition-all duration-150",
9580
- sizeMap6[size],
9609
+ sizeMap7[size],
9581
9610
  empty ? "border-border bg-card/50" : rarityBorderMap[rarity],
9582
9611
  !empty && rarityGlowMap[rarity],
9583
9612
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background",
@@ -9586,21 +9615,12 @@ function ItemSlot({
9586
9615
  !isClickable && "cursor-default",
9587
9616
  className
9588
9617
  ),
9589
- children: empty ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9590
- assetUrl ? /* @__PURE__ */ jsx(
9591
- "img",
9592
- {
9593
- src: assetUrl?.url,
9594
- alt: label,
9595
- width: px,
9596
- height: px,
9597
- style: { imageRendering: "pixelated", objectFit: "contain" },
9598
- className: "flex-shrink-0"
9599
- }
9600
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
9618
+ children: empty ? /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9619
+ 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,
9601
9620
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
9602
- "span",
9621
+ Typography,
9603
9622
  {
9623
+ as: "span",
9604
9624
  className: cn(
9605
9625
  "absolute -bottom-1 -right-1 flex items-center justify-center",
9606
9626
  "min-w-[18px] h-[18px] rounded-full px-1",
@@ -9613,13 +9633,18 @@ function ItemSlot({
9613
9633
  }
9614
9634
  );
9615
9635
  }
9616
- var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9636
+ var sizeMap7, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
9617
9637
  var init_ItemSlot = __esm({
9618
9638
  "components/game/2d/atoms/ItemSlot.tsx"() {
9619
9639
  "use client";
9620
9640
  init_cn();
9621
9641
  init_Icon();
9622
- sizeMap6 = {
9642
+ init_useEventBus();
9643
+ init_Button();
9644
+ init_Box();
9645
+ init_Typography();
9646
+ init_GameIcon();
9647
+ sizeMap7 = {
9623
9648
  sm: "w-10 h-10 text-lg",
9624
9649
  md: "w-14 h-14 text-2xl",
9625
9650
  lg: "w-18 h-18 text-3xl"
@@ -9660,9 +9685,9 @@ function TurnIndicator({
9660
9685
  size = "md",
9661
9686
  className
9662
9687
  }) {
9663
- const sizes = sizeMap7[size];
9688
+ const sizes = sizeMap8[size];
9664
9689
  return /* @__PURE__ */ jsxs(
9665
- "div",
9690
+ Box,
9666
9691
  {
9667
9692
  className: cn(
9668
9693
  "inline-flex items-center rounded-container",
@@ -9671,42 +9696,35 @@ function TurnIndicator({
9671
9696
  className
9672
9697
  ),
9673
9698
  children: [
9674
- /* @__PURE__ */ jsxs("span", { className: "font-bold tabular-nums", children: [
9699
+ /* @__PURE__ */ jsxs(Typography, { as: "span", className: "font-bold tabular-nums", children: [
9675
9700
  "Turn ",
9676
9701
  currentTurn,
9677
- maxTurns != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
9702
+ maxTurns != null && /* @__PURE__ */ jsxs(Typography, { as: "span", className: "text-muted-foreground", children: [
9678
9703
  "/",
9679
9704
  maxTurns
9680
9705
  ] })
9681
9706
  ] }),
9682
9707
  phase && /* @__PURE__ */ jsxs(Fragment, { children: [
9683
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
9684
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: phase })
9708
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9709
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: phase })
9685
9710
  ] }),
9686
9711
  activeTeam && /* @__PURE__ */ jsxs(Fragment, { children: [
9687
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "|" }),
9688
- assetUrl ? /* @__PURE__ */ jsx(
9689
- "img",
9690
- {
9691
- src: assetUrl.url,
9692
- alt: "",
9693
- width: 12,
9694
- height: 12,
9695
- style: { imageRendering: "pixelated", objectFit: "contain" },
9696
- className: "flex-shrink-0"
9697
- }
9698
- ) : /* @__PURE__ */ jsx("span", { className: cn("rounded-full bg-success/20", sizes.dot) }),
9699
- /* @__PURE__ */ jsx("span", { className: "text-success", children: activeTeam })
9712
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground", children: "|" }),
9713
+ 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) }),
9714
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-success", children: activeTeam })
9700
9715
  ] })
9701
9716
  ]
9702
9717
  }
9703
9718
  );
9704
9719
  }
9705
- var sizeMap7, DEFAULT_ASSET_URL6;
9720
+ var sizeMap8, DEFAULT_ASSET_URL6;
9706
9721
  var init_TurnIndicator = __esm({
9707
9722
  "components/game/2d/atoms/TurnIndicator.tsx"() {
9708
9723
  init_cn();
9709
- sizeMap7 = {
9724
+ init_Box();
9725
+ init_Typography();
9726
+ init_GameIcon();
9727
+ sizeMap8 = {
9710
9728
  sm: { wrapper: "text-xs gap-1.5 px-2 py-0.5", dot: "w-1.5 h-1.5" },
9711
9729
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
9712
9730
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
@@ -9738,10 +9756,10 @@ function ComboCounter({
9738
9756
  size = "md",
9739
9757
  className
9740
9758
  }) {
9741
- const sizes = sizeMap8[size];
9759
+ const sizes = sizeMap9[size];
9742
9760
  if (combo <= 0) return null;
9743
9761
  return /* @__PURE__ */ jsxs(
9744
- "div",
9762
+ Box,
9745
9763
  {
9746
9764
  className: cn(
9747
9765
  "inline-flex flex-col items-center justify-center",
@@ -9751,24 +9769,14 @@ function ComboCounter({
9751
9769
  className
9752
9770
  ),
9753
9771
  children: [
9754
- assetUrl && /* @__PURE__ */ jsx(
9755
- "img",
9756
- {
9757
- src: assetUrl.url,
9758
- alt: "combo",
9759
- width: 24,
9760
- height: 24,
9761
- style: { imageRendering: "pixelated", objectFit: "contain" },
9762
- className: "flex-shrink-0 mb-0.5"
9763
- }
9764
- ),
9765
- /* @__PURE__ */ jsx("span", { className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
9766
- /* @__PURE__ */ jsx("span", { className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
9767
- multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs("span", { className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
9772
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 24, className: "flex-shrink-0 mb-0.5" }),
9773
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-black tabular-nums leading-none", sizes.combo, getComboIntensity(combo)), children: combo }),
9774
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: cn("font-bold uppercase tracking-wider text-muted-foreground", sizes.label), children: "combo" }),
9775
+ multiplier != null && multiplier > 1 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("font-bold text-warning tabular-nums", sizes.multiplier), children: [
9768
9776
  "x",
9769
9777
  multiplier.toFixed(1)
9770
9778
  ] }),
9771
- streak != null && streak > 0 && /* @__PURE__ */ jsxs("span", { className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9779
+ streak != null && streak > 0 && /* @__PURE__ */ jsxs(Typography, { as: "span", className: cn("text-muted-foreground tabular-nums", sizes.label), children: [
9772
9780
  streak,
9773
9781
  " streak"
9774
9782
  ] })
@@ -9776,16 +9784,19 @@ function ComboCounter({
9776
9784
  }
9777
9785
  );
9778
9786
  }
9779
- var DEFAULT_ASSET_URL7, sizeMap8;
9787
+ var DEFAULT_ASSET_URL7, sizeMap9;
9780
9788
  var init_ComboCounter = __esm({
9781
9789
  "components/game/2d/atoms/ComboCounter.tsx"() {
9782
9790
  init_cn();
9791
+ init_Box();
9792
+ init_Typography();
9793
+ init_GameIcon();
9783
9794
  DEFAULT_ASSET_URL7 = {
9784
9795
  url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
9785
9796
  role: "effect",
9786
9797
  category: "effect"
9787
9798
  };
9788
- sizeMap8 = {
9799
+ sizeMap9 = {
9789
9800
  sm: { combo: "text-lg", label: "text-xs", multiplier: "text-xs" },
9790
9801
  md: { combo: "text-2xl", label: "text-xs", multiplier: "text-sm" },
9791
9802
  lg: { combo: "text-4xl", label: "text-sm", multiplier: "text-base" }
@@ -9802,54 +9813,48 @@ function WaypointMarker({
9802
9813
  size = "md",
9803
9814
  className
9804
9815
  }) {
9805
- const sizes = sizeMap9[size];
9806
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center", className), children: [
9807
- /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
9816
+ const sizes = sizeMap10[size];
9817
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col items-center", className), children: [
9818
+ /* @__PURE__ */ jsxs(Box, { className: "relative flex items-center justify-center", children: [
9808
9819
  active && /* @__PURE__ */ jsx(
9809
- "div",
9820
+ Box,
9810
9821
  {
9822
+ position: "absolute",
9811
9823
  className: cn(
9812
- "absolute rounded-full border-2 border-info animate-ping opacity-50",
9824
+ "rounded-full border-2 border-info animate-ping opacity-50",
9813
9825
  sizes.ring
9814
9826
  )
9815
9827
  }
9816
9828
  ),
9817
9829
  active && /* @__PURE__ */ jsx(
9818
- "div",
9830
+ Box,
9819
9831
  {
9832
+ position: "absolute",
9820
9833
  className: cn(
9821
- "absolute rounded-full border-2 border-info",
9834
+ "rounded-full border-2 border-info",
9822
9835
  sizes.ring
9823
9836
  )
9824
9837
  }
9825
9838
  ),
9826
9839
  /* @__PURE__ */ jsx(
9827
- "div",
9840
+ Box,
9828
9841
  {
9842
+ position: "relative",
9829
9843
  className: cn(
9830
- "relative flex items-center justify-center rounded-full transition-all duration-200",
9844
+ "flex items-center justify-center rounded-full transition-all duration-200",
9831
9845
  sizes.dot,
9832
9846
  completed && "bg-success text-foreground",
9833
9847
  active && !completed && "bg-info text-foreground",
9834
9848
  !active && !completed && "bg-muted"
9835
9849
  ),
9836
- children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsx(
9837
- "img",
9838
- {
9839
- src: assetUrl.url,
9840
- alt: label,
9841
- width: sizes.img,
9842
- height: sizes.img,
9843
- style: { imageRendering: "pixelated", objectFit: "contain" },
9844
- className: "flex-shrink-0"
9845
- }
9846
- ) : icon ? typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) : null
9850
+ 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
9847
9851
  }
9848
9852
  )
9849
9853
  ] }),
9850
9854
  label && /* @__PURE__ */ jsx(
9851
- "span",
9855
+ Typography,
9852
9856
  {
9857
+ as: "span",
9853
9858
  className: cn(
9854
9859
  "text-center whitespace-nowrap",
9855
9860
  sizes.label,
@@ -9860,17 +9865,20 @@ function WaypointMarker({
9860
9865
  )
9861
9866
  ] });
9862
9867
  }
9863
- var DEFAULT_ASSET_URL8, sizeMap9, checkIcon;
9868
+ var DEFAULT_ASSET_URL8, sizeMap10, checkIcon;
9864
9869
  var init_WaypointMarker = __esm({
9865
9870
  "components/game/2d/atoms/WaypointMarker.tsx"() {
9866
9871
  init_cn();
9867
9872
  init_Icon();
9873
+ init_Box();
9874
+ init_Typography();
9875
+ init_GameIcon();
9868
9876
  DEFAULT_ASSET_URL8 = {
9869
9877
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
9870
9878
  role: "ui",
9871
9879
  category: "waypoint"
9872
9880
  };
9873
- sizeMap9 = {
9881
+ sizeMap10 = {
9874
9882
  sm: { dot: "w-4 h-4", ring: "w-6 h-6", label: "text-xs mt-1", img: 12 },
9875
9883
  md: { dot: "w-6 h-6", ring: "w-8 h-8", label: "text-sm mt-1.5", img: 18 },
9876
9884
  lg: { dot: "w-8 h-8", ring: "w-10 h-10", label: "text-base mt-2", img: 24 }
@@ -9895,32 +9903,24 @@ function StatusEffect({
9895
9903
  size = "md",
9896
9904
  className
9897
9905
  }) {
9898
- const sizes = sizeMap10[size];
9899
- return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex flex-col items-center", className), children: [
9906
+ const sizes = sizeMap11[size];
9907
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn("inline-flex flex-col items-center", className), children: [
9900
9908
  /* @__PURE__ */ jsxs(
9901
- "div",
9909
+ Box,
9902
9910
  {
9911
+ position: "relative",
9903
9912
  className: cn(
9904
- "relative flex items-center justify-center rounded-interactive border-2",
9913
+ "flex items-center justify-center rounded-interactive border-2",
9905
9914
  sizes.container,
9906
9915
  variantStyles7[variant]
9907
9916
  ),
9908
9917
  title: label,
9909
9918
  children: [
9910
- /* @__PURE__ */ jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsx(
9911
- "img",
9912
- {
9913
- src: assetUrl.url,
9914
- alt: label,
9915
- width: sizes.img,
9916
- height: sizes.img,
9917
- style: { imageRendering: "pixelated", objectFit: "contain" },
9918
- className: "flex-shrink-0"
9919
- }
9920
- ) : icon != null && typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, size: "sm" }) : icon != null ? /* @__PURE__ */ jsx(Icon, { icon, size: "sm" }) : null }),
9919
+ /* @__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 }),
9921
9920
  duration !== void 0 && /* @__PURE__ */ jsx(
9922
- "span",
9921
+ Typography,
9923
9922
  {
9923
+ as: "span",
9924
9924
  className: cn(
9925
9925
  "absolute bottom-0 left-0 right-0 text-center font-mono font-bold text-foreground bg-background/60 leading-tight",
9926
9926
  sizes.timer
@@ -9932,8 +9932,9 @@ function StatusEffect({
9932
9932
  }
9933
9933
  ),
9934
9934
  stacks !== void 0 && stacks > 1 && /* @__PURE__ */ jsx(
9935
- "span",
9935
+ Typography,
9936
9936
  {
9937
+ as: "span",
9937
9938
  className: cn(
9938
9939
  "absolute flex items-center justify-center rounded-full bg-card text-foreground font-bold leading-none",
9939
9940
  sizes.badge
@@ -9941,20 +9942,23 @@ function StatusEffect({
9941
9942
  children: stacks
9942
9943
  }
9943
9944
  ),
9944
- label && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9945
+ label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
9945
9946
  ] });
9946
9947
  }
9947
- var DEFAULT_ASSET_URL9, sizeMap10, variantStyles7;
9948
+ var DEFAULT_ASSET_URL9, sizeMap11, variantStyles7;
9948
9949
  var init_StatusEffect = __esm({
9949
9950
  "components/game/2d/atoms/StatusEffect.tsx"() {
9950
9951
  init_cn();
9951
9952
  init_Icon();
9953
+ init_Box();
9954
+ init_Typography();
9955
+ init_GameIcon();
9952
9956
  DEFAULT_ASSET_URL9 = {
9953
9957
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
9954
9958
  role: "ui",
9955
9959
  category: "effect"
9956
9960
  };
9957
- sizeMap10 = {
9961
+ sizeMap11 = {
9958
9962
  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 },
9959
9963
  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 },
9960
9964
  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 }
@@ -9978,38 +9982,31 @@ function DamageNumber({
9978
9982
  return /* @__PURE__ */ jsxs(Fragment, { children: [
9979
9983
  /* @__PURE__ */ jsx("style", { children: floatKeyframes }),
9980
9984
  /* @__PURE__ */ jsxs(
9981
- "span",
9985
+ Typography,
9982
9986
  {
9987
+ as: "span",
9983
9988
  className: cn(
9984
9989
  "inline-flex items-center gap-0.5 font-mono select-none pointer-events-none",
9985
- sizeMap11[size],
9990
+ sizeMap12[size],
9986
9991
  typeStyles[type],
9987
9992
  className
9988
9993
  ),
9989
9994
  style: { animation: "damageFloat 1s ease-out forwards" },
9990
9995
  children: [
9991
- assetUrl && /* @__PURE__ */ jsx(
9992
- "img",
9993
- {
9994
- src: assetUrl.url,
9995
- alt: "",
9996
- width: 14,
9997
- height: 14,
9998
- style: { imageRendering: "pixelated", objectFit: "contain" },
9999
- className: "flex-shrink-0"
10000
- }
10001
- ),
9996
+ assetUrl && /* @__PURE__ */ jsx(GameIcon, { assetUrl, icon: "image", size: 14, className: "flex-shrink-0" }),
10002
9997
  displayText
10003
9998
  ]
10004
9999
  }
10005
10000
  )
10006
10001
  ] });
10007
10002
  }
10008
- var sizeMap11, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
10003
+ var sizeMap12, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
10009
10004
  var init_DamageNumber = __esm({
10010
10005
  "components/game/2d/atoms/DamageNumber.tsx"() {
10011
10006
  init_cn();
10012
- sizeMap11 = {
10007
+ init_Typography();
10008
+ init_GameIcon();
10009
+ sizeMap12 = {
10013
10010
  sm: "text-sm",
10014
10011
  md: "text-lg",
10015
10012
  lg: "text-2xl"
@@ -10043,7 +10040,7 @@ function DialogueBubble({
10043
10040
  className
10044
10041
  }) {
10045
10042
  return /* @__PURE__ */ jsxs(
10046
- "div",
10043
+ Box,
10047
10044
  {
10048
10045
  className: cn(
10049
10046
  "flex items-start gap-3 rounded-container bg-background/80 backdrop-blur-sm px-4 py-3 border border-border/10",
@@ -10051,17 +10048,10 @@ function DialogueBubble({
10051
10048
  className
10052
10049
  ),
10053
10050
  children: [
10054
- portrait && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 w-12 h-12 rounded-full overflow-hidden border-2 border-warning/60", children: /* @__PURE__ */ jsx(
10055
- "img",
10056
- {
10057
- src: portrait?.url,
10058
- alt: speaker ?? "speaker",
10059
- className: "w-full h-full object-cover"
10060
- }
10061
- ) }),
10062
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
10063
- speaker && /* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-warning", children: speaker }),
10064
- /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground leading-relaxed", children: text })
10051
+ 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" }) }),
10052
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-1 min-w-0", children: [
10053
+ speaker && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm font-bold text-warning", children: speaker }),
10054
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm text-foreground leading-relaxed", children: text })
10065
10055
  ] })
10066
10056
  ]
10067
10057
  }
@@ -10071,6 +10061,9 @@ var DEFAULT_PORTRAIT;
10071
10061
  var init_DialogueBubble = __esm({
10072
10062
  "components/game/2d/atoms/DialogueBubble.tsx"() {
10073
10063
  init_cn();
10064
+ init_Box();
10065
+ init_Typography();
10066
+ init_GameIcon();
10074
10067
  DEFAULT_PORTRAIT = {
10075
10068
  url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
10076
10069
  role: "effect",
@@ -10087,14 +10080,19 @@ function ChoiceButton({
10087
10080
  disabled = false,
10088
10081
  selected = false,
10089
10082
  onClick,
10083
+ action,
10090
10084
  className
10091
10085
  }) {
10086
+ const eventBus = useEventBus();
10092
10087
  return /* @__PURE__ */ jsxs(
10093
- "button",
10088
+ Button,
10094
10089
  {
10095
- type: "button",
10090
+ variant: "ghost",
10096
10091
  disabled,
10097
- onClick,
10092
+ onClick: () => {
10093
+ if (action) eventBus.emit(`UI:${action}`, {});
10094
+ onClick?.();
10095
+ },
10098
10096
  className: cn(
10099
10097
  "w-full text-left px-4 py-2.5 rounded-interactive border transition-all duration-150",
10100
10098
  "flex items-center gap-2",
@@ -10104,8 +10102,9 @@ function ChoiceButton({
10104
10102
  ),
10105
10103
  children: [
10106
10104
  index !== void 0 && /* @__PURE__ */ jsxs(
10107
- "span",
10105
+ Typography,
10108
10106
  {
10107
+ as: "span",
10109
10108
  className: cn(
10110
10109
  "flex-shrink-0 font-mono font-bold text-sm",
10111
10110
  selected ? "text-accent" : "text-muted-foreground"
@@ -10116,24 +10115,14 @@ function ChoiceButton({
10116
10115
  ]
10117
10116
  }
10118
10117
  ),
10119
- assetUrl ? /* @__PURE__ */ jsx(
10120
- "img",
10121
- {
10122
- src: assetUrl.url,
10123
- alt: "",
10124
- width: 16,
10125
- height: 16,
10126
- style: { imageRendering: "pixelated", objectFit: "contain" },
10127
- className: "flex-shrink-0"
10128
- }
10129
- ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
10118
+ 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" ? (() => {
10130
10119
  const I = resolveIcon(icon);
10131
10120
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
10132
10121
  })() : /* @__PURE__ */ (() => {
10133
10122
  const I = icon;
10134
10123
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
10135
10124
  })() }) : null,
10136
- /* @__PURE__ */ jsx("span", { className: "text-sm leading-snug", children: text })
10125
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-sm leading-snug", children: text })
10137
10126
  ]
10138
10127
  }
10139
10128
  );
@@ -10142,6 +10131,11 @@ var init_ChoiceButton = __esm({
10142
10131
  "components/game/2d/atoms/ChoiceButton.tsx"() {
10143
10132
  init_cn();
10144
10133
  init_Icon();
10134
+ init_useEventBus();
10135
+ init_Button();
10136
+ init_Box();
10137
+ init_Typography();
10138
+ init_GameIcon();
10145
10139
  ChoiceButton.displayName = "ChoiceButton";
10146
10140
  }
10147
10141
  });
@@ -10155,18 +10149,23 @@ function ActionButton({
10155
10149
  size = "md",
10156
10150
  variant = "primary",
10157
10151
  onClick,
10152
+ action,
10158
10153
  className
10159
10154
  }) {
10160
- const sizes = sizeMap12[size];
10155
+ const eventBus = useEventBus();
10156
+ const sizes = sizeMap13[size];
10161
10157
  const onCooldown = cooldown > 0;
10162
10158
  const isDisabled = disabled || onCooldown;
10163
10159
  const cooldownDeg = Math.round(cooldown * 360);
10164
10160
  return /* @__PURE__ */ jsxs(
10165
- "button",
10161
+ Button,
10166
10162
  {
10167
- type: "button",
10163
+ variant: variant === "danger" ? "danger" : variant === "secondary" ? "secondary" : "primary",
10168
10164
  disabled: isDisabled,
10169
- onClick,
10165
+ onClick: () => {
10166
+ if (action) eventBus.emit(`UI:${action}`, {});
10167
+ onClick?.();
10168
+ },
10170
10169
  className: cn(
10171
10170
  "relative inline-flex items-center gap-1.5 rounded-interactive border font-medium overflow-hidden transition-colors duration-150",
10172
10171
  sizes.button,
@@ -10176,9 +10175,10 @@ function ActionButton({
10176
10175
  ),
10177
10176
  children: [
10178
10177
  onCooldown && /* @__PURE__ */ jsx(
10179
- "div",
10178
+ Box,
10180
10179
  {
10181
- className: "absolute inset-0 bg-foreground/40 pointer-events-none",
10180
+ position: "absolute",
10181
+ className: "inset-0 bg-foreground/40 pointer-events-none",
10182
10182
  style: {
10183
10183
  clipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
10184
10184
  WebkitClipPath: `conic-gradient(from 0deg, transparent ${360 - cooldownDeg}deg, black ${360 - cooldownDeg}deg)`,
@@ -10186,27 +10186,18 @@ function ActionButton({
10186
10186
  }
10187
10187
  }
10188
10188
  ),
10189
- assetUrl ? /* @__PURE__ */ jsx(
10190
- "img",
10191
- {
10192
- src: assetUrl.url,
10193
- alt: "",
10194
- width: 16,
10195
- height: 16,
10196
- style: { imageRendering: "pixelated", objectFit: "contain" },
10197
- className: cn("flex-shrink-0", sizes.icon)
10198
- }
10199
- ) : icon ? /* @__PURE__ */ jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: typeof icon === "string" ? (() => {
10189
+ 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" ? (() => {
10200
10190
  const I = resolveIcon(icon);
10201
10191
  return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
10202
10192
  })() : /* @__PURE__ */ (() => {
10203
10193
  const I = icon;
10204
10194
  return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
10205
10195
  })() }) : null,
10206
- /* @__PURE__ */ jsx("span", { className: "relative z-10", children: label }),
10196
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "relative z-10", children: label }),
10207
10197
  hotkey && /* @__PURE__ */ jsx(
10208
- "span",
10198
+ Typography,
10209
10199
  {
10200
+ as: "span",
10210
10201
  className: cn(
10211
10202
  "absolute top-0.5 right-0.5 bg-foreground/30 text-primary-foreground rounded font-mono leading-tight",
10212
10203
  sizes.hotkey
@@ -10218,12 +10209,17 @@ function ActionButton({
10218
10209
  }
10219
10210
  );
10220
10211
  }
10221
- var sizeMap12, variantStyles8, DEFAULT_ASSET_URL11;
10212
+ var sizeMap13, variantStyles8, DEFAULT_ASSET_URL11;
10222
10213
  var init_ActionButton = __esm({
10223
10214
  "components/game/2d/atoms/ActionButton.tsx"() {
10224
10215
  init_cn();
10225
10216
  init_Icon();
10226
- sizeMap12 = {
10217
+ init_useEventBus();
10218
+ init_Button();
10219
+ init_Box();
10220
+ init_Typography();
10221
+ init_GameIcon();
10222
+ sizeMap13 = {
10227
10223
  sm: { button: "h-button-sm px-3 text-xs", hotkey: "text-[9px] px-1", icon: "text-xs" },
10228
10224
  md: { button: "h-button-md px-4 text-sm", hotkey: "text-xs px-1.5", icon: "text-sm" },
10229
10225
  lg: { button: "h-button-lg px-5 text-base", hotkey: "text-xs px-2", icon: "text-base" }
@@ -10249,10 +10245,27 @@ function MiniMap({
10249
10245
  mapWidth = 100,
10250
10246
  mapHeight = 100,
10251
10247
  viewportRect = DEFAULT_VIEWPORT,
10252
- className
10248
+ className,
10249
+ tileAssets,
10250
+ unitAssets
10253
10251
  }) {
10254
- const canvasRef = React105.useRef(null);
10255
- React105.useEffect(() => {
10252
+ const canvasRef = React103.useRef(null);
10253
+ const imgCacheRef = React103.useRef(/* @__PURE__ */ new Map());
10254
+ function loadImg(url) {
10255
+ const cached = imgCacheRef.current.get(url);
10256
+ if (cached) return cached.complete ? cached : null;
10257
+ const img = new Image();
10258
+ img.src = url;
10259
+ img.onload = () => {
10260
+ const canvas = canvasRef.current;
10261
+ if (!canvas) return;
10262
+ const ctx = canvas.getContext("2d");
10263
+ if (ctx) ctx.clearRect(0, 0, 0, 0);
10264
+ };
10265
+ imgCacheRef.current.set(url, img);
10266
+ return null;
10267
+ }
10268
+ React103.useEffect(() => {
10256
10269
  const canvas = canvasRef.current;
10257
10270
  if (!canvas) return;
10258
10271
  const ctx = canvas.getContext("2d");
@@ -10263,20 +10276,31 @@ function MiniMap({
10263
10276
  ctx.fillStyle = "#111";
10264
10277
  ctx.fillRect(0, 0, width, height);
10265
10278
  for (const tile of tiles) {
10266
- ctx.fillStyle = tile.color;
10267
- ctx.fillRect(
10268
- Math.floor(tile.x * scaleX2),
10269
- Math.floor(tile.y * scaleY2),
10270
- Math.max(1, Math.ceil(scaleX2)),
10271
- Math.max(1, Math.ceil(scaleY2))
10272
- );
10279
+ const tileAsset = tileAssets?.[tile.color] ?? tileAssets?.["default"];
10280
+ const tileImg = tileAsset ? loadImg(tileAsset.url) : null;
10281
+ const tx = Math.floor(tile.x * scaleX2);
10282
+ const ty = Math.floor(tile.y * scaleY2);
10283
+ const tw = Math.max(1, Math.ceil(scaleX2));
10284
+ const th = Math.max(1, Math.ceil(scaleY2));
10285
+ if (tileImg) {
10286
+ ctx.drawImage(tileImg, tx, ty, tw, th);
10287
+ } else {
10288
+ ctx.fillStyle = tile.color;
10289
+ ctx.fillRect(tx, ty, tw, th);
10290
+ }
10273
10291
  }
10274
10292
  for (const unit of units) {
10275
10293
  if (unit.isPlayer) continue;
10276
- ctx.fillStyle = unit.color;
10294
+ const unitAsset = unitAssets?.[unit.color] ?? unitAssets?.["default"];
10295
+ const unitImg = unitAsset ? loadImg(unitAsset.url) : null;
10277
10296
  const ux = Math.floor(unit.x * scaleX2) - 1;
10278
10297
  const uy = Math.floor(unit.y * scaleY2) - 1;
10279
- ctx.fillRect(ux, uy, 3, 3);
10298
+ if (unitImg) {
10299
+ ctx.drawImage(unitImg, ux, uy, 5, 5);
10300
+ } else {
10301
+ ctx.fillStyle = unit.color;
10302
+ ctx.fillRect(ux, uy, 3, 3);
10303
+ }
10280
10304
  }
10281
10305
  if (viewportRect) {
10282
10306
  ctx.strokeStyle = "#ffffff";
@@ -10288,7 +10312,7 @@ function MiniMap({
10288
10312
  Math.floor(viewportRect.h * scaleY2)
10289
10313
  );
10290
10314
  }
10291
- }, [tiles, units, width, height, mapWidth, mapHeight, viewportRect]);
10315
+ }, [tiles, units, width, height, mapWidth, mapHeight, viewportRect, tileAssets, unitAssets]);
10292
10316
  const scaleX = width / mapWidth;
10293
10317
  const scaleY = height / mapHeight;
10294
10318
  const playerUnit = units.find((u) => u.isPlayer);
@@ -10297,10 +10321,12 @@ function MiniMap({
10297
10321
  return /* @__PURE__ */ jsxs(Fragment, { children: [
10298
10322
  /* @__PURE__ */ jsx("style", { children: `@keyframes minimap-blink{0%,49%{opacity:1}50%,100%{opacity:0}}` }),
10299
10323
  /* @__PURE__ */ jsxs(
10300
- "div",
10324
+ Box,
10301
10325
  {
10326
+ position: "relative",
10327
+ display: "inline-block",
10302
10328
  className: cn(
10303
- "relative inline-block border border-border/20 rounded-container",
10329
+ "border border-border/20 rounded-container",
10304
10330
  className
10305
10331
  ),
10306
10332
  children: [
@@ -10315,10 +10341,10 @@ function MiniMap({
10315
10341
  }
10316
10342
  ),
10317
10343
  playerLeft !== null && playerTop !== null && /* @__PURE__ */ jsx(
10318
- "div",
10344
+ Box,
10319
10345
  {
10346
+ position: "absolute",
10320
10347
  style: {
10321
- position: "absolute",
10322
10348
  left: playerLeft,
10323
10349
  top: playerTop,
10324
10350
  width: 3,
@@ -10339,6 +10365,7 @@ var init_MiniMap = __esm({
10339
10365
  "components/game/2d/atoms/MiniMap.tsx"() {
10340
10366
  "use client";
10341
10367
  init_cn();
10368
+ init_Box();
10342
10369
  DEFAULT_TILES = [
10343
10370
  { x: 10, y: 10, color: "#4ade80" },
10344
10371
  { x: 20, y: 15, color: "#4ade80" },
@@ -10356,38 +10383,6 @@ var init_MiniMap = __esm({
10356
10383
  MiniMap.displayName = "MiniMap";
10357
10384
  }
10358
10385
  });
10359
- function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
10360
- const px = typeof size === "number" ? size : sizeMap13[size];
10361
- if (assetUrl?.url) {
10362
- return /* @__PURE__ */ jsx(
10363
- "img",
10364
- {
10365
- src: assetUrl.url,
10366
- alt: alt ?? assetUrl.category ?? "",
10367
- width: px,
10368
- height: px,
10369
- style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
10370
- className: cn("flex-shrink-0", className)
10371
- }
10372
- );
10373
- }
10374
- const I = typeof icon === "string" ? resolveIcon(icon) : icon;
10375
- return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
10376
- }
10377
- var sizeMap13;
10378
- var init_GameIcon = __esm({
10379
- "components/game/2d/atoms/GameIcon.tsx"() {
10380
- "use client";
10381
- init_cn();
10382
- init_Icon();
10383
- sizeMap13 = {
10384
- sm: 16,
10385
- md: 24,
10386
- lg: 32
10387
- };
10388
- GameIcon.displayName = "GameIcon";
10389
- }
10390
- });
10391
10386
  function ControlGrid({
10392
10387
  kind,
10393
10388
  buttons = DEFAULT_BUTTONS,
@@ -10397,13 +10392,14 @@ function ControlGrid({
10397
10392
  actionEvent,
10398
10393
  onDirection,
10399
10394
  directionEvent,
10395
+ directionAssets,
10400
10396
  size = "md",
10401
10397
  disabled,
10402
10398
  className
10403
10399
  }) {
10404
10400
  const eventBus = useEventBus();
10405
- const [active, setActive] = React105.useState(/* @__PURE__ */ new Set());
10406
- const handlePress = React105.useCallback(
10401
+ const [active, setActive] = React103.useState(/* @__PURE__ */ new Set());
10402
+ const handlePress = React103.useCallback(
10407
10403
  (id) => {
10408
10404
  setActive((prev) => new Set(prev).add(id));
10409
10405
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -10415,7 +10411,7 @@ function ControlGrid({
10415
10411
  },
10416
10412
  [kind, actionEvent, directionEvent, eventBus, onAction, onDirection]
10417
10413
  );
10418
- const handleRelease = React105.useCallback(
10414
+ const handleRelease = React103.useCallback(
10419
10415
  (id) => {
10420
10416
  setActive((prev) => {
10421
10417
  const next = new Set(prev);
@@ -10436,7 +10432,8 @@ function ControlGrid({
10436
10432
  const dir = (d) => /* @__PURE__ */ jsx(
10437
10433
  ControlButton,
10438
10434
  {
10439
- icon: arrowIcons[d],
10435
+ icon: directionAssets?.[d] ? void 0 : arrowIcons[d],
10436
+ assetUrl: directionAssets?.[d],
10440
10437
  size: sizeKey[size],
10441
10438
  variant: "secondary",
10442
10439
  pressed: active.has(d),
@@ -10446,22 +10443,22 @@ function ControlGrid({
10446
10443
  },
10447
10444
  d
10448
10445
  );
10449
- return /* @__PURE__ */ jsxs("div", { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
10450
- /* @__PURE__ */ jsx("div", {}),
10446
+ return /* @__PURE__ */ jsxs(Box, { className: cn("inline-grid grid-cols-3", ds.gap, ds.container, className), children: [
10447
+ /* @__PURE__ */ jsx(Box, {}),
10451
10448
  dir("up"),
10452
- /* @__PURE__ */ jsx("div", {}),
10449
+ /* @__PURE__ */ jsx(Box, {}),
10453
10450
  dir("left"),
10454
- /* @__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" }) }),
10451
+ /* @__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" }) }),
10455
10452
  dir("right"),
10456
- /* @__PURE__ */ jsx("div", {}),
10453
+ /* @__PURE__ */ jsx(Box, {}),
10457
10454
  dir("down"),
10458
- /* @__PURE__ */ jsx("div", {})
10455
+ /* @__PURE__ */ jsx(Box, {})
10459
10456
  ] });
10460
10457
  }
10461
10458
  if (layout === "diamond" && buttons.length === 4) {
10462
10459
  const [top, right, bottom, left] = buttons;
10463
- return /* @__PURE__ */ jsxs("div", { className: cn(layoutClass.diamond, className), children: [
10464
- /* @__PURE__ */ jsx("div", {}),
10460
+ return /* @__PURE__ */ jsxs(Box, { className: cn(layoutClass.diamond, className), children: [
10461
+ /* @__PURE__ */ jsx(Box, {}),
10465
10462
  /* @__PURE__ */ jsx(
10466
10463
  ControlButton,
10467
10464
  {
@@ -10476,7 +10473,7 @@ function ControlGrid({
10476
10473
  disabled
10477
10474
  }
10478
10475
  ),
10479
- /* @__PURE__ */ jsx("div", {}),
10476
+ /* @__PURE__ */ jsx(Box, {}),
10480
10477
  /* @__PURE__ */ jsx(
10481
10478
  ControlButton,
10482
10479
  {
@@ -10491,7 +10488,7 @@ function ControlGrid({
10491
10488
  disabled
10492
10489
  }
10493
10490
  ),
10494
- /* @__PURE__ */ jsx("div", {}),
10491
+ /* @__PURE__ */ jsx(Box, {}),
10495
10492
  /* @__PURE__ */ jsx(
10496
10493
  ControlButton,
10497
10494
  {
@@ -10506,7 +10503,7 @@ function ControlGrid({
10506
10503
  disabled
10507
10504
  }
10508
10505
  ),
10509
- /* @__PURE__ */ jsx("div", {}),
10506
+ /* @__PURE__ */ jsx(Box, {}),
10510
10507
  /* @__PURE__ */ jsx(
10511
10508
  ControlButton,
10512
10509
  {
@@ -10521,10 +10518,10 @@ function ControlGrid({
10521
10518
  disabled
10522
10519
  }
10523
10520
  ),
10524
- /* @__PURE__ */ jsx("div", {})
10521
+ /* @__PURE__ */ jsx(Box, {})
10525
10522
  ] });
10526
10523
  }
10527
- return /* @__PURE__ */ jsx("div", { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
10524
+ return /* @__PURE__ */ jsx(Box, { className: cn(layoutClass[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
10528
10525
  ControlButton,
10529
10526
  {
10530
10527
  icon: button.icon,
@@ -10546,6 +10543,7 @@ var init_ControlGrid = __esm({
10546
10543
  "use client";
10547
10544
  init_cn();
10548
10545
  init_useEventBus();
10546
+ init_Box();
10549
10547
  init_ControlButton();
10550
10548
  sizeKey = { sm: "sm", md: "md", lg: "lg" };
10551
10549
  layoutClass = {
@@ -10590,7 +10588,7 @@ function StatBadge({
10590
10588
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
10591
10589
  const resolvedAsset = iconUrl ?? assetUrl;
10592
10590
  return /* @__PURE__ */ jsxs(
10593
- "div",
10591
+ Box,
10594
10592
  {
10595
10593
  className: cn(
10596
10594
  "inline-flex items-center gap-2 rounded-container border backdrop-blur-sm",
@@ -10599,18 +10597,8 @@ function StatBadge({
10599
10597
  className
10600
10598
  ),
10601
10599
  children: [
10602
- resolvedAsset ? /* @__PURE__ */ jsx(
10603
- "img",
10604
- {
10605
- src: resolvedAsset.url,
10606
- alt: "",
10607
- width: 16,
10608
- height: 16,
10609
- style: { imageRendering: "pixelated", objectFit: "contain" },
10610
- className: "flex-shrink-0"
10611
- }
10612
- ) : 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,
10613
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-medium", children: label }),
10600
+ 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,
10601
+ /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-muted-foreground font-medium", children: label }),
10614
10602
  format === "hearts" && max && /* @__PURE__ */ jsx(
10615
10603
  HealthBar,
10616
10604
  {
@@ -10636,7 +10624,7 @@ function StatBadge({
10636
10624
  size: size === "lg" ? "md" : "sm"
10637
10625
  }
10638
10626
  ),
10639
- format === "text" && /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground", children: value })
10627
+ format === "text" && /* @__PURE__ */ jsx(Typography, { as: "span", className: "font-bold text-foreground", children: value })
10640
10628
  ]
10641
10629
  }
10642
10630
  );
@@ -10646,6 +10634,9 @@ var init_StatBadge = __esm({
10646
10634
  "components/game/2d/molecules/StatBadge.tsx"() {
10647
10635
  init_cn();
10648
10636
  init_Icon();
10637
+ init_Box();
10638
+ init_Typography();
10639
+ init_GameIcon();
10649
10640
  init_HealthBar();
10650
10641
  init_ScoreDisplay();
10651
10642
  sizeMap14 = {
@@ -10676,11 +10667,11 @@ function InventoryGrid({
10676
10667
  const eventBus = useEventBus();
10677
10668
  const slotCount = totalSlots ?? items.length;
10678
10669
  const emptySlotCount = Math.max(0, slotCount - items.length);
10679
- const handleSelect = React105.useCallback(
10670
+ const handleSelect = React103.useCallback(
10680
10671
  (id) => {
10681
10672
  onSelect?.(id);
10682
10673
  if (selectEvent) {
10683
- eventBus.emit(selectEvent, { id });
10674
+ eventBus.emit(`UI:${selectEvent}`, { id });
10684
10675
  }
10685
10676
  },
10686
10677
  [onSelect, selectEvent, eventBus]
@@ -10823,9 +10814,9 @@ function GameHud({
10823
10814
  if (position === "corners") {
10824
10815
  const leftStats = stats.slice(0, Math.ceil(stats.length / 2));
10825
10816
  const rightStats = stats.slice(Math.ceil(stats.length / 2));
10826
- return /* @__PURE__ */ jsxs("div", { className: cn("relative", positionMap[position], className), children: [
10827
- /* @__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)) }),
10828
- /* @__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)) })
10817
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", className: cn(positionMap[position], className), children: [
10818
+ /* @__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)) }),
10819
+ /* @__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)) })
10829
10820
  ] });
10830
10821
  }
10831
10822
  if (position === "top" || position === "bottom") {
@@ -10834,7 +10825,7 @@ function GameHud({
10834
10825
  const rightStats = stats.slice(mid);
10835
10826
  const isTop = position === "top";
10836
10827
  return /* @__PURE__ */ jsxs(
10837
- "div",
10828
+ Box,
10838
10829
  {
10839
10830
  className: cn(
10840
10831
  "flex items-center justify-between w-full",
@@ -10844,17 +10835,18 @@ function GameHud({
10844
10835
  className
10845
10836
  ),
10846
10837
  children: [
10847
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10848
- 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)) })
10838
+ /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
10839
+ 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)) })
10849
10840
  ]
10850
10841
  }
10851
10842
  );
10852
10843
  }
10853
10844
  return /* @__PURE__ */ jsx(
10854
- "div",
10845
+ Box,
10855
10846
  {
10847
+ position: "relative",
10856
10848
  className: cn(
10857
- "relative z-10 flex items-center gap-4 px-4 py-2",
10849
+ "z-10 flex items-center gap-4 px-4 py-2",
10858
10850
  transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
10859
10851
  className
10860
10852
  ),
@@ -10866,6 +10858,7 @@ var positionMap, DEFAULT_HUD_STATS;
10866
10858
  var init_GameHud = __esm({
10867
10859
  "components/game/2d/molecules/GameHud.tsx"() {
10868
10860
  init_cn();
10861
+ init_Box();
10869
10862
  init_StatBadge();
10870
10863
  positionMap = {
10871
10864
  corners: "inset-0 pointer-events-none"
@@ -10885,34 +10878,28 @@ function GameMenu({
10885
10878
  options,
10886
10879
  menuItems,
10887
10880
  onSelect,
10888
- eventBus: eventBusProp,
10889
10881
  background,
10890
- logo = "",
10882
+ logo,
10891
10883
  className
10892
10884
  }) {
10893
10885
  const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
10894
- let eventBusFromHook = null;
10895
- try {
10896
- eventBusFromHook = useEventBus();
10897
- } catch {
10898
- }
10899
- const eventBus = eventBusProp || eventBusFromHook;
10900
- const handleOptionClick = React105.useCallback(
10886
+ const eventBus = useEventBus();
10887
+ const handleOptionClick = React103.useCallback(
10901
10888
  (option) => {
10902
- if (option.event && eventBus) {
10889
+ if (option.event) {
10903
10890
  eventBus.emit(`UI:${option.event}`, { option });
10904
10891
  }
10905
10892
  if (onSelect) {
10906
10893
  onSelect(option);
10907
10894
  }
10908
- if (option.navigatesTo && eventBus) {
10895
+ if (option.navigatesTo) {
10909
10896
  eventBus.emit("UI:NAVIGATE", { url: option.navigatesTo, option });
10910
10897
  }
10911
10898
  },
10912
10899
  [eventBus, onSelect]
10913
10900
  );
10914
10901
  return /* @__PURE__ */ jsxs(
10915
- "div",
10902
+ Box,
10916
10903
  {
10917
10904
  className: cn(
10918
10905
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
@@ -10922,18 +10909,12 @@ function GameMenu({
10922
10909
  background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
10923
10910
  },
10924
10911
  children: [
10925
- /* @__PURE__ */ jsxs("div", { className: "text-center mb-12 animate-fade-in", children: [
10926
- logo && /* @__PURE__ */ jsx(
10927
- "img",
10928
- {
10929
- src: logo,
10930
- alt: title,
10931
- className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl"
10932
- }
10933
- ),
10912
+ /* @__PURE__ */ jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
10913
+ logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
10934
10914
  /* @__PURE__ */ jsx(
10935
- "h1",
10915
+ Typography,
10936
10916
  {
10917
+ variant: "h1",
10937
10918
  className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
10938
10919
  style: {
10939
10920
  textShadow: "0 4px 12px rgba(0,0,0,0.5)"
@@ -10941,9 +10922,9 @@ function GameMenu({
10941
10922
  children: title
10942
10923
  }
10943
10924
  ),
10944
- subtitle && /* @__PURE__ */ jsx("p", { className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
10925
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
10945
10926
  ] }),
10946
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
10927
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
10947
10928
  ChoiceButton,
10948
10929
  {
10949
10930
  text: option.label,
@@ -10954,9 +10935,9 @@ function GameMenu({
10954
10935
  },
10955
10936
  index
10956
10937
  )) }),
10957
- /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 pointer-events-none overflow-hidden", children: [
10958
- /* @__PURE__ */ jsx("div", { className: "absolute top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
10959
- /* @__PURE__ */ jsx("div", { className: "absolute bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
10938
+ /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
10939
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
10940
+ /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
10960
10941
  ] })
10961
10942
  ]
10962
10943
  }
@@ -10968,6 +10949,9 @@ var init_GameMenu = __esm({
10968
10949
  "use client";
10969
10950
  init_cn();
10970
10951
  init_useEventBus();
10952
+ init_Box();
10953
+ init_Typography();
10954
+ init_GameIcon();
10971
10955
  init_ChoiceButton();
10972
10956
  DEFAULT_MENU_OPTIONS = [
10973
10957
  { label: "New Game", event: "NEW_GAME", variant: "primary" },
@@ -12208,10 +12192,11 @@ function Canvas2D({
12208
12192
  }
12209
12193
  }
12210
12194
  ),
12211
- process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs("div", { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
12195
+ process.env.NODE_ENV !== "production" && /* @__PURE__ */ jsxs(Box, { "data-game-actions": "", className: "sr-only", "aria-hidden": "true", children: [
12212
12196
  tileClickEvent && /* @__PURE__ */ jsx(
12213
- "button",
12197
+ Button,
12214
12198
  {
12199
+ variant: "ghost",
12215
12200
  "data-event": tileClickEvent,
12216
12201
  "data-x": "0",
12217
12202
  "data-y": "0",
@@ -12220,8 +12205,9 @@ function Canvas2D({
12220
12205
  }
12221
12206
  ),
12222
12207
  unitClickEvent && units && units.length > 0 && /* @__PURE__ */ jsx(
12223
- "button",
12208
+ Button,
12224
12209
  {
12210
+ variant: "ghost",
12225
12211
  "data-event": unitClickEvent,
12226
12212
  "data-unit-id": units[0].id,
12227
12213
  onClick: () => eventBus.emit(`UI:${unitClickEvent}`, { unitId: units[0].id }),
@@ -12230,15 +12216,17 @@ function Canvas2D({
12230
12216
  )
12231
12217
  ] }),
12232
12218
  unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxs(
12233
- "div",
12219
+ Box,
12234
12220
  {
12235
- className: "absolute pointer-events-none",
12221
+ position: "absolute",
12222
+ className: "pointer-events-none",
12236
12223
  style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
12237
12224
  children: [
12238
12225
  unit.name && /* @__PURE__ */ jsx(
12239
- "div",
12226
+ Typography,
12240
12227
  {
12241
- className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
12228
+ as: "span",
12229
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap block",
12242
12230
  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)" },
12243
12231
  children: unit.name
12244
12232
  }
@@ -12248,7 +12236,7 @@ function Canvas2D({
12248
12236
  },
12249
12237
  unit.id
12250
12238
  )),
12251
- showMinimap && /* @__PURE__ */ jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
12239
+ showMinimap && /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
12252
12240
  MiniMap,
12253
12241
  {
12254
12242
  tiles: miniMapTiles,
@@ -12270,6 +12258,7 @@ var init_Canvas2D = __esm({
12270
12258
  init_cn();
12271
12259
  init_useEventBus();
12272
12260
  init_Box();
12261
+ init_Button();
12273
12262
  init_Stack();
12274
12263
  init_Icon();
12275
12264
  init_Typography();
@@ -12581,7 +12570,9 @@ var init_GameAudioProvider = __esm({
12581
12570
  });
12582
12571
  function GameAudioToggle({
12583
12572
  size = "sm",
12584
- className
12573
+ className,
12574
+ onAsset,
12575
+ offAsset
12585
12576
  }) {
12586
12577
  const ctx = useGameAudioContextOptional();
12587
12578
  const [localMuted, setLocalMuted] = useState(false);
@@ -12590,6 +12581,7 @@ function GameAudioToggle({
12590
12581
  const handleToggle = useCallback(() => {
12591
12582
  setMuted(!muted);
12592
12583
  }, [muted, setMuted]);
12584
+ const activeAsset = muted ? offAsset : onAsset;
12593
12585
  return /* @__PURE__ */ jsx(
12594
12586
  Button,
12595
12587
  {
@@ -12598,7 +12590,7 @@ function GameAudioToggle({
12598
12590
  onClick: handleToggle,
12599
12591
  className: cn("text-lg leading-none px-2", className),
12600
12592
  "aria-pressed": muted,
12601
- children: muted ? "\u{1F507}" : "\u{1F50A}"
12593
+ 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}"
12602
12594
  }
12603
12595
  );
12604
12596
  }
@@ -12608,6 +12600,7 @@ var init_GameAudioToggle = __esm({
12608
12600
  init_atoms();
12609
12601
  init_cn();
12610
12602
  init_GameAudioProvider();
12603
+ init_GameIcon();
12611
12604
  GameAudioToggle.displayName = "GameAudioToggle";
12612
12605
  }
12613
12606
  });
@@ -13890,6 +13883,7 @@ function PlatformerBoard({
13890
13883
  canvasHeight: _canvasHeight = 400,
13891
13884
  playerSprite,
13892
13885
  tileSprites,
13886
+ ui: _ui,
13893
13887
  bgColor: _bgColor,
13894
13888
  keyEvent = "KEY",
13895
13889
  playAgainEvent = "PLAY_AGAIN",
@@ -15748,6 +15742,7 @@ function TanksBoard({
15748
15742
  features,
15749
15743
  assetManifest,
15750
15744
  assetBaseUrl,
15745
+ ui: _ui,
15751
15746
  scale = 0.45,
15752
15747
  showMinimap = true,
15753
15748
  enableCamera = true,
@@ -16275,7 +16270,7 @@ function LinearView({
16275
16270
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
16276
16271
  const isDone = i < currentIdx;
16277
16272
  const isCurrent = i === currentIdx;
16278
- return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
16273
+ return /* @__PURE__ */ jsxs(React103__default.Fragment, { children: [
16279
16274
  i > 0 && /* @__PURE__ */ jsx(
16280
16275
  Typography,
16281
16276
  {
@@ -16496,7 +16491,7 @@ function TraitSlot({
16496
16491
  size = "md",
16497
16492
  showTooltip = true,
16498
16493
  categoryColors,
16499
- tooltipFrameUrl = "",
16494
+ tooltipFrameUrl,
16500
16495
  className,
16501
16496
  feedback,
16502
16497
  onItemDrop,
@@ -16626,7 +16621,7 @@ function TraitSlot({
16626
16621
  as: "img",
16627
16622
  className: "object-contain",
16628
16623
  style: { width: config.icon, height: config.icon },
16629
- ...{ src: equippedItem.iconUrl, alt: equippedItem.name }
16624
+ ...{ src: equippedItem.iconUrl.url, alt: equippedItem.name }
16630
16625
  }
16631
16626
  ) : /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-center leading-none", style: { fontSize: config.icon }, children: equippedItem.iconEmoji || "\u2726" }),
16632
16627
  (onRemove || removeEvent) && /* @__PURE__ */ jsx(
@@ -16655,7 +16650,7 @@ function TraitSlot({
16655
16650
  ...getTooltipStyle(),
16656
16651
  minWidth: 200,
16657
16652
  ...tooltipFrameUrl ? {
16658
- borderImage: `url(${tooltipFrameUrl}) 60 fill / 15px / 0 stretch`,
16653
+ borderImage: `url(${tooltipFrameUrl.url}) 60 fill / 15px / 0 stretch`,
16659
16654
  border: "none"
16660
16655
  } : {}
16661
16656
  },
@@ -16730,7 +16725,7 @@ function ActionTile({
16730
16725
  draggable: !disabled,
16731
16726
  onDragStart: handleDragStart,
16732
16727
  children: [
16733
- 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" }),
16728
+ 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" }),
16734
16729
  /* @__PURE__ */ jsx(Typography, { variant: "caption", className: cn(config.text, "text-foreground font-medium whitespace-nowrap"), children: action.name })
16735
16730
  ]
16736
16731
  }
@@ -16803,7 +16798,7 @@ function SequenceBar({
16803
16798
  onSlotRemove(index);
16804
16799
  }, [onSlotRemove, playing]);
16805
16800
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
16806
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
16801
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React103__default.Fragment, { children: [
16807
16802
  i > 0 && /* @__PURE__ */ jsx(
16808
16803
  Typography,
16809
16804
  {
@@ -16854,6 +16849,42 @@ function computeSlotFeedback(playerSeq, solutions) {
16854
16849
  (id, i) => id !== void 0 && id === bestSolution[i] ? "correct" : "wrong"
16855
16850
  );
16856
16851
  }
16852
+ function isFieldRecord(v) {
16853
+ return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
16854
+ }
16855
+ function assetFromField(v) {
16856
+ if (!isFieldRecord(v)) return void 0;
16857
+ const url = typeof v.url === "string" ? v.url : void 0;
16858
+ const role = typeof v.role === "string" ? v.role : void 0;
16859
+ const category = typeof v.category === "string" ? v.category : "";
16860
+ if (!url || !role) return void 0;
16861
+ return {
16862
+ url,
16863
+ role,
16864
+ category,
16865
+ name: typeof v.name === "string" ? v.name : void 0,
16866
+ thumbnailUrl: typeof v.thumbnailUrl === "string" ? v.thumbnailUrl : void 0,
16867
+ style: typeof v.style === "string" ? v.style : void 0,
16868
+ variant: typeof v.variant === "string" ? v.variant : void 0,
16869
+ dimension: typeof v.dimension === "string" ? v.dimension : void 0,
16870
+ aspect: typeof v.aspect === "string" ? v.aspect : void 0
16871
+ };
16872
+ }
16873
+ function slotItemFromField(fv) {
16874
+ if (!isFieldRecord(fv)) return void 0;
16875
+ const id = typeof fv.id === "string" ? fv.id : void 0;
16876
+ const name = typeof fv.name === "string" ? fv.name : void 0;
16877
+ const category = typeof fv.category === "string" ? fv.category : void 0;
16878
+ if (!id || !name || !category) return void 0;
16879
+ return {
16880
+ id,
16881
+ name,
16882
+ category,
16883
+ description: typeof fv.description === "string" ? fv.description : void 0,
16884
+ iconEmoji: typeof fv.iconEmoji === "string" ? fv.iconEmoji : void 0,
16885
+ iconUrl: assetFromField(fv.iconUrl)
16886
+ };
16887
+ }
16857
16888
  function SequencerBoard({
16858
16889
  entity,
16859
16890
  categoryColors,
@@ -16864,6 +16895,7 @@ function SequencerBoard({
16864
16895
  removeEvent,
16865
16896
  checkEvent,
16866
16897
  playAgainEvent,
16898
+ stepEvent,
16867
16899
  className
16868
16900
  }) {
16869
16901
  const { emit } = useEventBus();
@@ -16871,7 +16903,11 @@ function SequencerBoard({
16871
16903
  const resolved = boardEntity(entity);
16872
16904
  const maxSlots = num(resolved?.maxSlots) || 3;
16873
16905
  const solutions = Array.isArray(resolved?.solutions) ? resolved.solutions : [];
16874
- const availableActions = Array.isArray(resolved?.availableActions) ? resolved.availableActions : [];
16906
+ const availableActions = (Array.isArray(resolved?.availableActions) ? resolved.availableActions : []).reduce((acc, fv) => {
16907
+ const item = slotItemFromField(fv);
16908
+ if (item) acc.push(item);
16909
+ return acc;
16910
+ }, []);
16875
16911
  const allowDuplicates = resolved?.allowDuplicates !== false;
16876
16912
  const entitySlots = Array.isArray(resolved?.slots) ? resolved.slots : [];
16877
16913
  const entityResult = str(resolved?.result);
@@ -16929,7 +16965,7 @@ function SequencerBoard({
16929
16965
  let step = 0;
16930
16966
  const advance = () => {
16931
16967
  step++;
16932
- emit("UI:STEP", { step });
16968
+ if (stepEvent) emit(`UI:${stepEvent}`, { step });
16933
16969
  if (step >= maxSlots) {
16934
16970
  if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
16935
16971
  const playerSeq = slots.map((s) => s?.id);
@@ -19154,35 +19190,7 @@ var init_SimulationCanvas = __esm({
19154
19190
  SimulationCanvas.displayName = "SimulationCanvas";
19155
19191
  }
19156
19192
  });
19157
- function getSlotContentRenderer2() {
19158
- if (_scr) return _scr;
19159
- const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
19160
- _scr = mod.SlotContentRenderer;
19161
- return _scr;
19162
- }
19163
- function resolveDescriptor(value, idPrefix) {
19164
- if (value === null || value === void 0) return value;
19165
- if (React105__default.isValidElement(value)) return value;
19166
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
19167
- if (Array.isArray(value)) {
19168
- return value.map((item, i) => /* @__PURE__ */ jsx(React105__default.Fragment, { children: resolveDescriptor(item, `${idPrefix}-${i}`) }, i));
19169
- }
19170
- if (typeof value === "object") {
19171
- const rec = value;
19172
- if (typeof rec.type === "string" && getComponentForPattern(rec.type) !== null) {
19173
- const type = rec.type;
19174
- const _id = typeof rec._id === "string" ? rec._id : void 0;
19175
- const nestedProps = rec.props !== void 0 && typeof rec.props === "object" && !Array.isArray(rec.props) && rec.props !== null ? rec.props : void 0;
19176
- const { type: _t, props: _p, _id: _d, ...flatRest } = rec;
19177
- const resolvedProps = nestedProps !== void 0 ? nestedProps : flatRest;
19178
- const content = { id: _id ?? idPrefix, pattern: type, props: resolvedProps, priority: 0 };
19179
- const SCR = getSlotContentRenderer2();
19180
- return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 });
19181
- }
19182
- }
19183
- return null;
19184
- }
19185
- var _scr, GameTemplate;
19193
+ var GameTemplate;
19186
19194
  var init_GameTemplate = __esm({
19187
19195
  "components/game/2d/templates/GameTemplate.tsx"() {
19188
19196
  init_cn();
@@ -19190,7 +19198,6 @@ var init_GameTemplate = __esm({
19190
19198
  init_Stack();
19191
19199
  init_Typography();
19192
19200
  init_Button();
19193
- _scr = null;
19194
19201
  GameTemplate = ({
19195
19202
  entity,
19196
19203
  title = "Game",
@@ -19199,7 +19206,8 @@ var init_GameTemplate = __esm({
19199
19206
  debugPanel,
19200
19207
  showDebugPanel = false,
19201
19208
  controls,
19202
- className
19209
+ className,
19210
+ backgroundAsset
19203
19211
  }) => {
19204
19212
  return /* @__PURE__ */ jsxs(
19205
19213
  Box,
@@ -19256,15 +19264,16 @@ var init_GameTemplate = __esm({
19256
19264
  {
19257
19265
  position: "relative",
19258
19266
  fullWidth: true,
19259
- className: "flex-1 bg-muted",
19267
+ className: backgroundAsset ? "flex-1" : "flex-1 bg-muted",
19268
+ style: backgroundAsset ? { backgroundImage: `url(${backgroundAsset.url})`, backgroundSize: "cover", backgroundPosition: "center" } : void 0,
19260
19269
  children: [
19261
- resolveDescriptor(children, "gt-children"),
19270
+ children,
19262
19271
  hud && /* @__PURE__ */ jsx(
19263
19272
  Box,
19264
19273
  {
19265
19274
  position: "absolute",
19266
19275
  className: "top-0 left-0 right-0 pointer-events-none",
19267
- children: /* @__PURE__ */ jsx(Box, { padding: "md", className: "pointer-events-auto w-fit", children: resolveDescriptor(hud, "gt-hud") })
19276
+ children: /* @__PURE__ */ jsx(Box, { padding: "md", className: "pointer-events-auto w-fit", children: hud })
19268
19277
  }
19269
19278
  )
19270
19279
  ]
@@ -19289,7 +19298,7 @@ var init_GameTemplate = __esm({
19289
19298
  children: /* @__PURE__ */ jsx(Typography, { variant: "h6", children: "Debug Panel" })
19290
19299
  }
19291
19300
  ),
19292
- /* @__PURE__ */ jsx(Box, { padding: "md", children: resolveDescriptor(debugPanel, "gt-debug") })
19301
+ /* @__PURE__ */ jsx(Box, { padding: "md", children: debugPanel })
19293
19302
  ]
19294
19303
  }
19295
19304
  )
@@ -19300,59 +19309,21 @@ var init_GameTemplate = __esm({
19300
19309
  GameTemplate.displayName = "GameTemplate";
19301
19310
  }
19302
19311
  });
19303
- function asDescriptor(v) {
19304
- if (Array.isArray(v) || React105__default.isValidElement(v)) return null;
19305
- const o = v;
19306
- if (typeof o.type !== "string") return null;
19307
- const props = o.props !== void 0 && typeof o.props === "object" && !Array.isArray(o.props) && o.props !== null ? o.props : void 0;
19308
- const _id = typeof o._id === "string" ? o._id : void 0;
19309
- const sourceTrait = typeof o.sourceTrait === "string" ? o.sourceTrait : void 0;
19310
- return { type: o.type, props, _id, sourceTrait };
19311
- }
19312
- function getSlotContentRenderer3() {
19313
- if (_scr2) return _scr2;
19314
- const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
19315
- _scr2 = mod.SlotContentRenderer;
19316
- return _scr2;
19317
- }
19318
- function resolveDescriptor2(value, idPrefix) {
19319
- if (value === null || value === void 0) return value;
19320
- if (React105__default.isValidElement(value)) return value;
19321
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
19322
- if (Array.isArray(value)) {
19323
- return value.map((item, i) => /* @__PURE__ */ jsx(React105__default.Fragment, { children: resolveDescriptor2(item, `${idPrefix}-${i}`) }, i));
19324
- }
19325
- if (typeof value === "object" && value !== null) {
19326
- const desc = asDescriptor(value);
19327
- if (desc !== null && getComponentForPattern(desc.type) !== null) {
19328
- const resolvedProps = desc.props ?? {};
19329
- const content = {
19330
- id: desc._id ?? idPrefix,
19331
- pattern: desc.type,
19332
- props: resolvedProps,
19333
- priority: 0,
19334
- ...desc.sourceTrait !== void 0 && { sourceTrait: desc.sourceTrait }
19335
- };
19336
- const SCR = getSlotContentRenderer3();
19337
- return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 }, content.id);
19338
- }
19339
- }
19340
- return null;
19341
- }
19342
- var _scr2, GameShell;
19312
+ var GameShell;
19343
19313
  var init_GameShell = __esm({
19344
19314
  "components/game/2d/templates/GameShell.tsx"() {
19345
19315
  init_cn();
19346
19316
  init_Box();
19347
19317
  init_Stack();
19348
19318
  init_Typography();
19349
- _scr2 = null;
19350
19319
  GameShell = ({
19351
19320
  appName = "Game",
19352
19321
  hud,
19353
19322
  className,
19354
19323
  showTopBar = true,
19355
- children
19324
+ children,
19325
+ backgroundAsset,
19326
+ hudBackgroundAsset
19356
19327
  }) => {
19357
19328
  return /* @__PURE__ */ jsxs(
19358
19329
  Box,
@@ -19367,7 +19338,7 @@ var init_GameShell = __esm({
19367
19338
  width: "100vw",
19368
19339
  height: "100vh",
19369
19340
  overflow: "hidden",
19370
- background: "var(--color-background, #0a0a0f)",
19341
+ background: backgroundAsset ? `url(${backgroundAsset.url}) center/cover no-repeat` : "var(--color-background, #0a0a0f)",
19371
19342
  color: "var(--color-text, #e0e0e0)"
19372
19343
  },
19373
19344
  children: [
@@ -19377,7 +19348,7 @@ var init_GameShell = __esm({
19377
19348
  className: "game-shell__header",
19378
19349
  style: {
19379
19350
  flexShrink: 0,
19380
- background: "var(--color-surface, #12121f)",
19351
+ background: hudBackgroundAsset ? `url(${hudBackgroundAsset.url}) center/cover no-repeat` : "var(--color-surface, #12121f)",
19381
19352
  borderBottom: "1px solid var(--color-border, #2a2a3a)"
19382
19353
  },
19383
19354
  children: [
@@ -19400,7 +19371,7 @@ var init_GameShell = __esm({
19400
19371
  )
19401
19372
  }
19402
19373
  ),
19403
- hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud", style: { width: "100%" }, children: resolveDescriptor2(hud, "gs-hud") })
19374
+ hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud", style: { width: "100%" }, children: hud })
19404
19375
  ]
19405
19376
  }
19406
19377
  ),
@@ -19413,7 +19384,7 @@ var init_GameShell = __esm({
19413
19384
  overflow: "hidden",
19414
19385
  position: "relative"
19415
19386
  },
19416
- children: resolveDescriptor2(children, "gs-children")
19387
+ children
19417
19388
  }
19418
19389
  )
19419
19390
  ]
@@ -20620,7 +20591,7 @@ var init_ErrorBoundary = __esm({
20620
20591
  }
20621
20592
  );
20622
20593
  };
20623
- ErrorBoundary = class extends React105__default.Component {
20594
+ ErrorBoundary = class extends React103__default.Component {
20624
20595
  constructor(props) {
20625
20596
  super(props);
20626
20597
  __publicField(this, "reset", () => {
@@ -20902,7 +20873,7 @@ var init_Container = __esm({
20902
20873
  as: Component = "div"
20903
20874
  }) => {
20904
20875
  const resolvedSize = maxWidth ?? size ?? "lg";
20905
- return React105__default.createElement(
20876
+ return React103__default.createElement(
20906
20877
  Component,
20907
20878
  {
20908
20879
  className: cn(
@@ -23084,9 +23055,9 @@ var init_BiologyCanvas = __esm({
23084
23055
  }
23085
23056
  });
23086
23057
 
23087
- // node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css
23058
+ // node_modules/katex/dist/katex.min.css
23088
23059
  var init_katex_min = __esm({
23089
- "node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css"() {
23060
+ "node_modules/katex/dist/katex.min.css"() {
23090
23061
  }
23091
23062
  });
23092
23063
  var Tabs;
@@ -23526,7 +23497,7 @@ var init_CodeBlock = __esm({
23526
23497
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
23527
23498
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
23528
23499
  HIDDEN_LINE_NUMBERS = { display: "none" };
23529
- CodeBlock = React105__default.memo(
23500
+ CodeBlock = React103__default.memo(
23530
23501
  ({
23531
23502
  code: rawCode,
23532
23503
  language = "text",
@@ -24113,7 +24084,7 @@ var init_MarkdownContent = __esm({
24113
24084
  init_Box();
24114
24085
  init_CodeBlock();
24115
24086
  init_cn();
24116
- MarkdownContent = React105__default.memo(
24087
+ MarkdownContent = React103__default.memo(
24117
24088
  ({ content, direction = "ltr", className }) => {
24118
24089
  const { t: _t } = useTranslate();
24119
24090
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -25390,7 +25361,7 @@ var init_StateMachineView = __esm({
25390
25361
  style: { top: title ? 30 : 0 },
25391
25362
  children: [
25392
25363
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
25393
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React105__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
25364
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React103__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
25394
25365
  StateNode2,
25395
25366
  {
25396
25367
  state,
@@ -29926,6 +29897,8 @@ function CounterMinimal({
29926
29897
  size = "md",
29927
29898
  onDecrement,
29928
29899
  onIncrement,
29900
+ decrementEvent,
29901
+ incrementEvent,
29929
29902
  className
29930
29903
  }) {
29931
29904
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
@@ -29936,6 +29909,7 @@ function CounterMinimal({
29936
29909
  {
29937
29910
  variant: "secondary",
29938
29911
  size: sizeStyles8[size].button,
29912
+ action: decrementEvent,
29939
29913
  onClick: onDecrement,
29940
29914
  disabled: resolved.decrementDisabled,
29941
29915
  icon: "minus",
@@ -29958,6 +29932,7 @@ function CounterMinimal({
29958
29932
  {
29959
29933
  variant: "secondary",
29960
29934
  size: sizeStyles8[size].button,
29935
+ action: incrementEvent,
29961
29936
  onClick: onIncrement,
29962
29937
  disabled: resolved.incrementDisabled,
29963
29938
  icon: "plus",
@@ -29974,6 +29949,9 @@ function CounterStandard({
29974
29949
  onDecrement,
29975
29950
  onIncrement,
29976
29951
  onReset,
29952
+ decrementEvent,
29953
+ incrementEvent,
29954
+ resetEvent,
29977
29955
  className
29978
29956
  }) {
29979
29957
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
@@ -30004,6 +29982,7 @@ function CounterStandard({
30004
29982
  {
30005
29983
  variant: "secondary",
30006
29984
  size: sizeStyles8[size].button,
29985
+ action: decrementEvent,
30007
29986
  onClick: onDecrement,
30008
29987
  disabled: resolved.decrementDisabled,
30009
29988
  icon: "minus"
@@ -30014,6 +29993,7 @@ function CounterStandard({
30014
29993
  {
30015
29994
  variant: "primary",
30016
29995
  size: sizeStyles8[size].button,
29996
+ action: incrementEvent,
30017
29997
  onClick: onIncrement,
30018
29998
  disabled: resolved.incrementDisabled,
30019
29999
  icon: "plus"
@@ -30025,6 +30005,7 @@ function CounterStandard({
30025
30005
  {
30026
30006
  variant: "ghost",
30027
30007
  size: "sm",
30008
+ action: resetEvent,
30028
30009
  onClick: onReset,
30029
30010
  icon: "rotate-ccw",
30030
30011
  children: "Reset"
@@ -30040,6 +30021,9 @@ function CounterFull({
30040
30021
  onDecrement,
30041
30022
  onIncrement,
30042
30023
  onReset,
30024
+ decrementEvent,
30025
+ incrementEvent,
30026
+ resetEvent,
30043
30027
  className
30044
30028
  }) {
30045
30029
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
@@ -30073,6 +30057,7 @@ function CounterFull({
30073
30057
  {
30074
30058
  variant: "secondary",
30075
30059
  size: sizeStyles8[size].button,
30060
+ action: decrementEvent,
30076
30061
  onClick: onDecrement,
30077
30062
  disabled: resolved.decrementDisabled,
30078
30063
  icon: "minus",
@@ -30084,6 +30069,7 @@ function CounterFull({
30084
30069
  {
30085
30070
  variant: "primary",
30086
30071
  size: sizeStyles8[size].button,
30072
+ action: incrementEvent,
30087
30073
  onClick: onIncrement,
30088
30074
  disabled: resolved.incrementDisabled,
30089
30075
  icon: "plus",
@@ -30096,6 +30082,7 @@ function CounterFull({
30096
30082
  {
30097
30083
  variant: "ghost",
30098
30084
  size: "sm",
30085
+ action: resetEvent,
30099
30086
  onClick: onReset,
30100
30087
  icon: "rotate-ccw",
30101
30088
  children: "Reset to 0"
@@ -30931,8 +30918,8 @@ var init_Menu = __esm({
30931
30918
  "bottom-end": "bottom-start"
30932
30919
  };
30933
30920
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
30934
- const triggerChild = React105__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
30935
- const triggerElement = React105__default.cloneElement(
30921
+ const triggerChild = React103__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
30922
+ const triggerElement = React103__default.cloneElement(
30936
30923
  triggerChild,
30937
30924
  {
30938
30925
  ref: triggerRef,
@@ -31027,14 +31014,14 @@ function useDataDnd(args) {
31027
31014
  const isZone = Boolean(dragGroup || accepts || sortable);
31028
31015
  const enabled = isZone || Boolean(dndRoot);
31029
31016
  const eventBus = useEventBus();
31030
- const parentRoot = React105__default.useContext(RootCtx);
31017
+ const parentRoot = React103__default.useContext(RootCtx);
31031
31018
  const isRoot = enabled && parentRoot === null;
31032
- const zoneId = React105__default.useId();
31019
+ const zoneId = React103__default.useId();
31033
31020
  const ownGroup = dragGroup ?? accepts ?? zoneId;
31034
- const [optimisticOrders, setOptimisticOrders] = React105__default.useState(() => /* @__PURE__ */ new Map());
31035
- const optimisticOrdersRef = React105__default.useRef(optimisticOrders);
31021
+ const [optimisticOrders, setOptimisticOrders] = React103__default.useState(() => /* @__PURE__ */ new Map());
31022
+ const optimisticOrdersRef = React103__default.useRef(optimisticOrders);
31036
31023
  optimisticOrdersRef.current = optimisticOrders;
31037
- const clearOptimisticOrder = React105__default.useCallback((group) => {
31024
+ const clearOptimisticOrder = React103__default.useCallback((group) => {
31038
31025
  setOptimisticOrders((prev) => {
31039
31026
  if (!prev.has(group)) return prev;
31040
31027
  const next = new Map(prev);
@@ -31059,7 +31046,7 @@ function useDataDnd(args) {
31059
31046
  const raw = it[dndItemIdField];
31060
31047
  return raw != null ? String(raw) : `__idx_${idx}`;
31061
31048
  }).join("|");
31062
- const itemIds = React105__default.useMemo(
31049
+ const itemIds = React103__default.useMemo(
31063
31050
  () => orderedItems.map((it, idx) => {
31064
31051
  const raw = it[dndItemIdField];
31065
31052
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -31070,7 +31057,7 @@ function useDataDnd(args) {
31070
31057
  const raw = it[dndItemIdField];
31071
31058
  return raw != null ? String(raw) : `__${idx}`;
31072
31059
  }).join("|");
31073
- React105__default.useEffect(() => {
31060
+ React103__default.useEffect(() => {
31074
31061
  const root = isRoot ? null : parentRoot;
31075
31062
  if (root) {
31076
31063
  root.clearOptimisticOrder(ownGroup);
@@ -31078,20 +31065,20 @@ function useDataDnd(args) {
31078
31065
  clearOptimisticOrder(ownGroup);
31079
31066
  }
31080
31067
  }, [itemsContentSig, ownGroup]);
31081
- const zonesRef = React105__default.useRef(/* @__PURE__ */ new Map());
31082
- const registerZone = React105__default.useCallback((zoneId2, meta2) => {
31068
+ const zonesRef = React103__default.useRef(/* @__PURE__ */ new Map());
31069
+ const registerZone = React103__default.useCallback((zoneId2, meta2) => {
31083
31070
  zonesRef.current.set(zoneId2, meta2);
31084
31071
  }, []);
31085
- const unregisterZone = React105__default.useCallback((zoneId2) => {
31072
+ const unregisterZone = React103__default.useCallback((zoneId2) => {
31086
31073
  zonesRef.current.delete(zoneId2);
31087
31074
  }, []);
31088
- const [activeDrag, setActiveDrag] = React105__default.useState(null);
31089
- const [overZoneGroup, setOverZoneGroup] = React105__default.useState(null);
31090
- const meta = React105__default.useMemo(
31075
+ const [activeDrag, setActiveDrag] = React103__default.useState(null);
31076
+ const [overZoneGroup, setOverZoneGroup] = React103__default.useState(null);
31077
+ const meta = React103__default.useMemo(
31091
31078
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
31092
31079
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
31093
31080
  );
31094
- React105__default.useEffect(() => {
31081
+ React103__default.useEffect(() => {
31095
31082
  const target = isRoot ? null : parentRoot;
31096
31083
  if (!target) {
31097
31084
  zonesRef.current.set(zoneId, meta);
@@ -31110,7 +31097,7 @@ function useDataDnd(args) {
31110
31097
  }, [parentRoot, isRoot, zoneId, meta]);
31111
31098
  const sensors = useAlmadarDndSensors(true);
31112
31099
  const collisionDetection = almadarDndCollisionDetection;
31113
- const findZoneByItem = React105__default.useCallback(
31100
+ const findZoneByItem = React103__default.useCallback(
31114
31101
  (id) => {
31115
31102
  for (const z of zonesRef.current.values()) {
31116
31103
  if (z.itemIds.includes(id)) return z;
@@ -31119,7 +31106,7 @@ function useDataDnd(args) {
31119
31106
  },
31120
31107
  []
31121
31108
  );
31122
- React105__default.useCallback(
31109
+ React103__default.useCallback(
31123
31110
  (group) => {
31124
31111
  for (const z of zonesRef.current.values()) {
31125
31112
  if (z.group === group) return z;
@@ -31128,7 +31115,7 @@ function useDataDnd(args) {
31128
31115
  },
31129
31116
  []
31130
31117
  );
31131
- const handleDragEnd = React105__default.useCallback(
31118
+ const handleDragEnd = React103__default.useCallback(
31132
31119
  (event) => {
31133
31120
  const { active, over } = event;
31134
31121
  const activeIdStr = String(active.id);
@@ -31219,8 +31206,8 @@ function useDataDnd(args) {
31219
31206
  },
31220
31207
  [eventBus]
31221
31208
  );
31222
- const sortableData = React105__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
31223
- const SortableItem = React105__default.useCallback(
31209
+ const sortableData = React103__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
31210
+ const SortableItem = React103__default.useCallback(
31224
31211
  ({ id, children }) => {
31225
31212
  const {
31226
31213
  attributes,
@@ -31260,7 +31247,7 @@ function useDataDnd(args) {
31260
31247
  id: droppableId,
31261
31248
  data: sortableData
31262
31249
  });
31263
- const ctx = React105__default.useContext(RootCtx);
31250
+ const ctx = React103__default.useContext(RootCtx);
31264
31251
  const activeDrag2 = ctx?.activeDrag ?? null;
31265
31252
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
31266
31253
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -31275,7 +31262,7 @@ function useDataDnd(args) {
31275
31262
  showForeignPlaceholder,
31276
31263
  ctxAvailable: ctx != null
31277
31264
  });
31278
- React105__default.useEffect(() => {
31265
+ React103__default.useEffect(() => {
31279
31266
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
31280
31267
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
31281
31268
  return /* @__PURE__ */ jsx(
@@ -31289,11 +31276,11 @@ function useDataDnd(args) {
31289
31276
  }
31290
31277
  );
31291
31278
  };
31292
- const rootContextValue = React105__default.useMemo(
31279
+ const rootContextValue = React103__default.useMemo(
31293
31280
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
31294
31281
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
31295
31282
  );
31296
- const handleDragStart = React105__default.useCallback((event) => {
31283
+ const handleDragStart = React103__default.useCallback((event) => {
31297
31284
  const sourceZone = findZoneByItem(event.active.id);
31298
31285
  const rect = event.active.rect.current.initial;
31299
31286
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -31312,7 +31299,7 @@ function useDataDnd(args) {
31312
31299
  isRoot
31313
31300
  });
31314
31301
  }, [findZoneByItem, isRoot, zoneId]);
31315
- const handleDragOver = React105__default.useCallback((event) => {
31302
+ const handleDragOver = React103__default.useCallback((event) => {
31316
31303
  const { active, over } = event;
31317
31304
  const overData = over?.data?.current;
31318
31305
  const overGroup = overData?.dndGroup ?? null;
@@ -31382,7 +31369,7 @@ function useDataDnd(args) {
31382
31369
  return next;
31383
31370
  });
31384
31371
  }, []);
31385
- const handleDragCancel = React105__default.useCallback((event) => {
31372
+ const handleDragCancel = React103__default.useCallback((event) => {
31386
31373
  setActiveDrag(null);
31387
31374
  setOverZoneGroup(null);
31388
31375
  dndLog.warn("dragCancel", {
@@ -31390,12 +31377,12 @@ function useDataDnd(args) {
31390
31377
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
31391
31378
  });
31392
31379
  }, []);
31393
- const handleDragEndWithCleanup = React105__default.useCallback((event) => {
31380
+ const handleDragEndWithCleanup = React103__default.useCallback((event) => {
31394
31381
  handleDragEnd(event);
31395
31382
  setActiveDrag(null);
31396
31383
  setOverZoneGroup(null);
31397
31384
  }, [handleDragEnd]);
31398
- const wrapContainer = React105__default.useCallback(
31385
+ const wrapContainer = React103__default.useCallback(
31399
31386
  (children) => {
31400
31387
  if (!enabled) return children;
31401
31388
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -31449,7 +31436,7 @@ var init_useDataDnd = __esm({
31449
31436
  init_useAlmadarDndCollision();
31450
31437
  init_Box();
31451
31438
  dndLog = createLogger("almadar:ui:dnd");
31452
- RootCtx = React105__default.createContext(null);
31439
+ RootCtx = React103__default.createContext(null);
31453
31440
  }
31454
31441
  });
31455
31442
  function renderIconInput(icon, props) {
@@ -31975,7 +31962,7 @@ function DataList({
31975
31962
  }) {
31976
31963
  const eventBus = useEventBus();
31977
31964
  const { t } = useTranslate();
31978
- const [visibleCount, setVisibleCount] = React105__default.useState(pageSize || Infinity);
31965
+ const [visibleCount, setVisibleCount] = React103__default.useState(pageSize || Infinity);
31979
31966
  const fieldDefs = fields ?? columns ?? [];
31980
31967
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
31981
31968
  const dnd = useDataDnd({
@@ -31994,7 +31981,7 @@ function DataList({
31994
31981
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
31995
31982
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
31996
31983
  const hasRenderProp = typeof children === "function";
31997
- React105__default.useEffect(() => {
31984
+ React103__default.useEffect(() => {
31998
31985
  const renderItemTypeOf = typeof schemaRenderItem;
31999
31986
  const childrenTypeOf = typeof children;
32000
31987
  if (data.length > 0 && !hasRenderProp) {
@@ -32098,7 +32085,7 @@ function DataList({
32098
32085
  const items2 = [...data];
32099
32086
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
32100
32087
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
32101
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
32088
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React103__default.Fragment, { children: [
32102
32089
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
32103
32090
  group.items.map((itemData, index) => {
32104
32091
  const id = itemData.id || `${gi}-${index}`;
@@ -32239,7 +32226,7 @@ function DataList({
32239
32226
  className
32240
32227
  ),
32241
32228
  children: [
32242
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
32229
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React103__default.Fragment, { children: [
32243
32230
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
32244
32231
  group.items.map(
32245
32232
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -32324,7 +32311,7 @@ var init_FormSection = __esm({
32324
32311
  columns = 1,
32325
32312
  className
32326
32313
  }) => {
32327
- const [collapsed, setCollapsed] = React105__default.useState(defaultCollapsed);
32314
+ const [collapsed, setCollapsed] = React103__default.useState(defaultCollapsed);
32328
32315
  const { t } = useTranslate();
32329
32316
  const eventBus = useEventBus();
32330
32317
  const gridClass = {
@@ -32332,7 +32319,7 @@ var init_FormSection = __esm({
32332
32319
  2: "grid-cols-1 md:grid-cols-2",
32333
32320
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
32334
32321
  }[columns];
32335
- React105__default.useCallback(() => {
32322
+ React103__default.useCallback(() => {
32336
32323
  if (collapsible) {
32337
32324
  setCollapsed((prev) => !prev);
32338
32325
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -33218,7 +33205,7 @@ var init_Flex = __esm({
33218
33205
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
33219
33206
  }
33220
33207
  }
33221
- return React105__default.createElement(Component, {
33208
+ return React103__default.createElement(Component, {
33222
33209
  className: cn(
33223
33210
  inline ? "inline-flex" : "flex",
33224
33211
  directionStyles[direction],
@@ -33337,7 +33324,7 @@ var init_Grid = __esm({
33337
33324
  as: Component = "div"
33338
33325
  }) => {
33339
33326
  const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
33340
- return React105__default.createElement(
33327
+ return React103__default.createElement(
33341
33328
  Component,
33342
33329
  {
33343
33330
  className: cn(
@@ -33533,9 +33520,9 @@ var init_Popover = __esm({
33533
33520
  onMouseLeave: handleClose,
33534
33521
  onPointerDown: tapTriggerProps.onPointerDown
33535
33522
  };
33536
- const childElement = React105__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
33523
+ const childElement = React103__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
33537
33524
  const childPointerDown = childElement.props.onPointerDown;
33538
- const triggerElement = React105__default.cloneElement(
33525
+ const triggerElement = React103__default.cloneElement(
33539
33526
  childElement,
33540
33527
  {
33541
33528
  ref: triggerRef,
@@ -34137,9 +34124,9 @@ var init_Tooltip = __esm({
34137
34124
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
34138
34125
  };
34139
34126
  }, []);
34140
- const triggerElement = React105__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
34127
+ const triggerElement = React103__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
34141
34128
  const childPointerDown = triggerElement.props.onPointerDown;
34142
- const trigger = React105__default.cloneElement(triggerElement, {
34129
+ const trigger = React103__default.cloneElement(triggerElement, {
34143
34130
  ref: triggerRef,
34144
34131
  onMouseEnter: handleMouseEnter,
34145
34132
  onMouseLeave: handleMouseLeave,
@@ -34229,7 +34216,7 @@ var init_WizardProgress = __esm({
34229
34216
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
34230
34217
  const isActive = index === currentStep;
34231
34218
  const isCompleted = index < currentStep;
34232
- return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
34219
+ return /* @__PURE__ */ jsxs(React103__default.Fragment, { children: [
34233
34220
  /* @__PURE__ */ jsx(
34234
34221
  "button",
34235
34222
  {
@@ -35789,7 +35776,7 @@ var init_MapView = __esm({
35789
35776
  shadowSize: [41, 41]
35790
35777
  });
35791
35778
  L.Marker.prototype.options.icon = defaultIcon;
35792
- const { useEffect: useEffect75, useRef: useRef77, useCallback: useCallback112, useState: useState107 } = React105__default;
35779
+ const { useEffect: useEffect75, useRef: useRef77, useCallback: useCallback112, useState: useState107 } = React103__default;
35793
35780
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
35794
35781
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
35795
35782
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -36704,8 +36691,8 @@ function TableView({
36704
36691
  }) {
36705
36692
  const eventBus = useEventBus();
36706
36693
  const { t } = useTranslate();
36707
- const [visibleCount, setVisibleCount] = React105__default.useState(pageSize > 0 ? pageSize : Infinity);
36708
- const [localSelected, setLocalSelected] = React105__default.useState(/* @__PURE__ */ new Set());
36694
+ const [visibleCount, setVisibleCount] = React103__default.useState(pageSize > 0 ? pageSize : Infinity);
36695
+ const [localSelected, setLocalSelected] = React103__default.useState(/* @__PURE__ */ new Set());
36709
36696
  const colDefs = columns ?? fields ?? [];
36710
36697
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
36711
36698
  const dnd = useDataDnd({
@@ -36900,12 +36887,12 @@ function TableView({
36900
36887
  ]
36901
36888
  }
36902
36889
  );
36903
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React105__default.Fragment, { children: rowInner }, id);
36890
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React103__default.Fragment, { children: rowInner }, id);
36904
36891
  };
36905
36892
  const items = Array.from(data);
36906
36893
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
36907
36894
  let runningIndex = 0;
36908
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
36895
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React103__default.Fragment, { children: [
36909
36896
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
36910
36897
  group.items.map((row) => renderRow(row, runningIndex++))
36911
36898
  ] }, gi)) });
@@ -38124,7 +38111,7 @@ var init_StepFlow = __esm({
38124
38111
  className
38125
38112
  }) => {
38126
38113
  if (orientation === "vertical") {
38127
- 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: [
38114
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React103__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
38128
38115
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
38129
38116
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
38130
38117
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -38135,7 +38122,7 @@ var init_StepFlow = __esm({
38135
38122
  ] })
38136
38123
  ] }) }, index)) });
38137
38124
  }
38138
- 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: [
38125
+ 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(React103__default.Fragment, { children: [
38139
38126
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
38140
38127
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
38141
38128
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -39120,7 +39107,7 @@ var init_LikertScale = __esm({
39120
39107
  md: "text-base",
39121
39108
  lg: "text-lg"
39122
39109
  };
39123
- LikertScale = React105__default.forwardRef(
39110
+ LikertScale = React103__default.forwardRef(
39124
39111
  ({
39125
39112
  question,
39126
39113
  options = DEFAULT_LIKERT_OPTIONS,
@@ -39132,7 +39119,7 @@ var init_LikertScale = __esm({
39132
39119
  variant = "radios",
39133
39120
  className
39134
39121
  }, ref) => {
39135
- const groupId = React105__default.useId();
39122
+ const groupId = React103__default.useId();
39136
39123
  const eventBus = useEventBus();
39137
39124
  const handleSelect = useCallback(
39138
39125
  (next) => {
@@ -41414,7 +41401,7 @@ var init_DocBreadcrumb = __esm({
41414
41401
  "aria-label": t("aria.breadcrumb"),
41415
41402
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
41416
41403
  const isLast = idx === items.length - 1;
41417
- return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
41404
+ return /* @__PURE__ */ jsxs(React103__default.Fragment, { children: [
41418
41405
  idx > 0 && /* @__PURE__ */ jsx(
41419
41406
  Icon,
41420
41407
  {
@@ -42283,7 +42270,7 @@ var init_MiniStateMachine = __esm({
42283
42270
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
42284
42271
  const tc = transitionCounts[s.name] ?? 0;
42285
42272
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
42286
- return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
42273
+ return /* @__PURE__ */ jsxs(React103__default.Fragment, { children: [
42287
42274
  /* @__PURE__ */ jsx(
42288
42275
  AvlState,
42289
42276
  {
@@ -42487,7 +42474,7 @@ var init_PageHeader = __esm({
42487
42474
  info: "bg-info/10 text-info"
42488
42475
  };
42489
42476
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
42490
- 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: [
42477
+ 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(React103__default.Fragment, { children: [
42491
42478
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
42492
42479
  crumb.href ? /* @__PURE__ */ jsx(
42493
42480
  "a",
@@ -42845,7 +42832,7 @@ var init_Section = __esm({
42845
42832
  as: Component = "section"
42846
42833
  }) => {
42847
42834
  const hasHeader = title || description || action;
42848
- return React105__default.createElement(
42835
+ return React103__default.createElement(
42849
42836
  Component,
42850
42837
  {
42851
42838
  className: cn(
@@ -43147,6 +43134,7 @@ var init_WizardContainer = __esm({
43147
43134
  init_Stack();
43148
43135
  init_Icon();
43149
43136
  init_cn();
43137
+ init_useEventBus();
43150
43138
  WizardContainer = ({
43151
43139
  steps,
43152
43140
  currentStep: controlledStep,
@@ -43155,9 +43143,13 @@ var init_WizardContainer = __esm({
43155
43143
  showProgress = true,
43156
43144
  allowBack = true,
43157
43145
  compact = false,
43158
- className
43146
+ className,
43147
+ nextEvent,
43148
+ backEvent,
43149
+ completeEvent
43159
43150
  }) => {
43160
43151
  const { t } = useTranslate();
43152
+ const eventBus = useEventBus();
43161
43153
  const [internalStep, setInternalStep] = useState(0);
43162
43154
  const normalizedControlledStep = (() => {
43163
43155
  if (controlledStep === void 0 || controlledStep === null)
@@ -43187,13 +43179,16 @@ var init_WizardContainer = __esm({
43187
43179
  return;
43188
43180
  }
43189
43181
  if (isLastStep) {
43182
+ if (completeEvent) eventBus.emit(`UI:${completeEvent}`, { step: currentStep });
43190
43183
  onComplete?.();
43191
43184
  } else {
43185
+ if (nextEvent) eventBus.emit(`UI:${nextEvent}`, { step: currentStep + 1 });
43192
43186
  goToStep(currentStep + 1);
43193
43187
  }
43194
43188
  };
43195
43189
  const handleBack = () => {
43196
43190
  if (!isFirstStep && allowBack) {
43191
+ if (backEvent) eventBus.emit(`UI:${backEvent}`, { step: currentStep - 1 });
43197
43192
  goToStep(currentStep - 1);
43198
43193
  }
43199
43194
  };
@@ -43211,7 +43206,7 @@ var init_WizardContainer = __esm({
43211
43206
  const isCompleted = index < currentStep;
43212
43207
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
43213
43208
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
43214
- return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
43209
+ return /* @__PURE__ */ jsxs(React103__default.Fragment, { children: [
43215
43210
  /* @__PURE__ */ jsx(
43216
43211
  Button,
43217
43212
  {
@@ -45644,7 +45639,7 @@ var init_DetailPanel = __esm({
45644
45639
  }
45645
45640
  });
45646
45641
  function extractTitle(children) {
45647
- if (!React105__default.isValidElement(children)) return void 0;
45642
+ if (!React103__default.isValidElement(children)) return void 0;
45648
45643
  const props = children.props;
45649
45644
  if (typeof props.title === "string") {
45650
45645
  return props.title;
@@ -45662,14 +45657,18 @@ var init_DrawerSlot = __esm({
45662
45657
  title: overrideTitle,
45663
45658
  position = "right",
45664
45659
  size = "md",
45665
- className
45660
+ className,
45661
+ sourceTrait
45666
45662
  }) => {
45667
45663
  const eventBus = useEventBus();
45664
+ const schemaCtx = useEntitySchemaOptional();
45668
45665
  const isOpen = Boolean(children);
45669
45666
  const title = overrideTitle || extractTitle(children);
45670
45667
  const handleClose = () => {
45671
- eventBus.emit("UI:CLOSE");
45672
- eventBus.emit("UI:CANCEL");
45668
+ const orbital = sourceTrait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
45669
+ const prefix = orbital !== void 0 && sourceTrait !== void 0 ? `UI:${orbital}.${sourceTrait}.` : "UI:";
45670
+ eventBus.emit(`${prefix}CLOSE`);
45671
+ eventBus.emit(`${prefix}CANCEL`);
45673
45672
  };
45674
45673
  if (!isOpen) return null;
45675
45674
  return /* @__PURE__ */ jsx(
@@ -45990,12 +45989,12 @@ var init_Form = __esm({
45990
45989
  const isSchemaEntity = isOrbitalEntitySchema(entity);
45991
45990
  const resolvedEntity = isSchemaEntity ? entity : void 0;
45992
45991
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
45993
- const normalizedInitialData = React105__default.useMemo(() => {
45992
+ const normalizedInitialData = React103__default.useMemo(() => {
45994
45993
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
45995
45994
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
45996
45995
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
45997
45996
  }, [entity, initialData]);
45998
- const entityDerivedFields = React105__default.useMemo(() => {
45997
+ const entityDerivedFields = React103__default.useMemo(() => {
45999
45998
  if (fields && fields.length > 0) return void 0;
46000
45999
  if (!resolvedEntity) return void 0;
46001
46000
  return resolvedEntity.fields.map(
@@ -46016,16 +46015,16 @@ var init_Form = __esm({
46016
46015
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
46017
46016
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
46018
46017
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
46019
- const [formData, setFormData] = React105__default.useState(
46018
+ const [formData, setFormData] = React103__default.useState(
46020
46019
  normalizedInitialData
46021
46020
  );
46022
- const [collapsedSections, setCollapsedSections] = React105__default.useState(
46021
+ const [collapsedSections, setCollapsedSections] = React103__default.useState(
46023
46022
  /* @__PURE__ */ new Set()
46024
46023
  );
46025
- const [submitError, setSubmitError] = React105__default.useState(null);
46026
- const formRef = React105__default.useRef(null);
46024
+ const [submitError, setSubmitError] = React103__default.useState(null);
46025
+ const formRef = React103__default.useRef(null);
46027
46026
  const formMode = props.mode;
46028
- const mountedRef = React105__default.useRef(false);
46027
+ const mountedRef = React103__default.useRef(false);
46029
46028
  if (!mountedRef.current) {
46030
46029
  mountedRef.current = true;
46031
46030
  debug("forms", "mount", {
@@ -46038,7 +46037,7 @@ var init_Form = __esm({
46038
46037
  });
46039
46038
  }
46040
46039
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
46041
- const evalContext = React105__default.useMemo(
46040
+ const evalContext = React103__default.useMemo(
46042
46041
  () => ({
46043
46042
  formValues: formData,
46044
46043
  globalVariables: externalContext?.globalVariables ?? {},
@@ -46047,7 +46046,7 @@ var init_Form = __esm({
46047
46046
  }),
46048
46047
  [formData, externalContext]
46049
46048
  );
46050
- React105__default.useEffect(() => {
46049
+ React103__default.useEffect(() => {
46051
46050
  debug("forms", "initialData-sync", {
46052
46051
  mode: formMode,
46053
46052
  normalizedInitialData,
@@ -46058,7 +46057,7 @@ var init_Form = __esm({
46058
46057
  setFormData(normalizedInitialData);
46059
46058
  }
46060
46059
  }, [normalizedInitialData]);
46061
- const processCalculations = React105__default.useCallback(
46060
+ const processCalculations = React103__default.useCallback(
46062
46061
  (changedFieldId, newFormData) => {
46063
46062
  if (!hiddenCalculations.length) return;
46064
46063
  const context = {
@@ -46083,7 +46082,7 @@ var init_Form = __esm({
46083
46082
  },
46084
46083
  [hiddenCalculations, externalContext, eventBus]
46085
46084
  );
46086
- const checkViolations = React105__default.useCallback(
46085
+ const checkViolations = React103__default.useCallback(
46087
46086
  (changedFieldId, newFormData) => {
46088
46087
  if (!violationTriggers.length) return;
46089
46088
  const context = {
@@ -46121,7 +46120,7 @@ var init_Form = __esm({
46121
46120
  processCalculations(name, newFormData);
46122
46121
  checkViolations(name, newFormData);
46123
46122
  };
46124
- const isFieldVisible = React105__default.useCallback(
46123
+ const isFieldVisible = React103__default.useCallback(
46125
46124
  (fieldName) => {
46126
46125
  const condition = conditionalFields[fieldName];
46127
46126
  if (!condition) return true;
@@ -46129,7 +46128,7 @@ var init_Form = __esm({
46129
46128
  },
46130
46129
  [conditionalFields, evalContext]
46131
46130
  );
46132
- const isSectionVisible = React105__default.useCallback(
46131
+ const isSectionVisible = React103__default.useCallback(
46133
46132
  (section) => {
46134
46133
  if (!section.condition) return true;
46135
46134
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -46205,7 +46204,7 @@ var init_Form = __esm({
46205
46204
  eventBus.emit(`UI:${onCancel}`);
46206
46205
  }
46207
46206
  };
46208
- const renderField = React105__default.useCallback(
46207
+ const renderField = React103__default.useCallback(
46209
46208
  (field) => {
46210
46209
  const fieldName = field.name || field.field;
46211
46210
  if (!fieldName) return null;
@@ -46226,7 +46225,7 @@ var init_Form = __esm({
46226
46225
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
46227
46226
  );
46228
46227
  const effectiveFields = entityDerivedFields ?? fields;
46229
- const normalizedFields = React105__default.useMemo(() => {
46228
+ const normalizedFields = React103__default.useMemo(() => {
46230
46229
  if (!effectiveFields || effectiveFields.length === 0) return [];
46231
46230
  return effectiveFields.map((field) => {
46232
46231
  if (typeof field === "string") {
@@ -46250,7 +46249,7 @@ var init_Form = __esm({
46250
46249
  return field;
46251
46250
  });
46252
46251
  }, [effectiveFields, resolvedEntity]);
46253
- const schemaFields = React105__default.useMemo(() => {
46252
+ const schemaFields = React103__default.useMemo(() => {
46254
46253
  if (normalizedFields.length === 0) return null;
46255
46254
  if (isDebugEnabled()) {
46256
46255
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -46260,7 +46259,7 @@ var init_Form = __esm({
46260
46259
  }
46261
46260
  return normalizedFields.map(renderField).filter(Boolean);
46262
46261
  }, [normalizedFields, renderField, entityName, conditionalFields]);
46263
- const sectionElements = React105__default.useMemo(() => {
46262
+ const sectionElements = React103__default.useMemo(() => {
46264
46263
  if (!sections || sections.length === 0) return null;
46265
46264
  return sections.map((section) => {
46266
46265
  if (!isSectionVisible(section)) {
@@ -46985,7 +46984,7 @@ var init_List = __esm({
46985
46984
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
46986
46985
  return [];
46987
46986
  }, [entity]);
46988
- const getItemActions = React105__default.useCallback(
46987
+ const getItemActions = React103__default.useCallback(
46989
46988
  (item) => {
46990
46989
  if (!itemActions) return [];
46991
46990
  if (typeof itemActions === "function") {
@@ -47460,7 +47459,7 @@ var init_MediaGallery = __esm({
47460
47459
  [selectable, selectedItems, selectionEvent, eventBus]
47461
47460
  );
47462
47461
  const entityData = Array.isArray(entity) ? entity : [];
47463
- const items = React105__default.useMemo(() => {
47462
+ const items = React103__default.useMemo(() => {
47464
47463
  if (propItems) return propItems;
47465
47464
  if (entityData.length === 0) return [];
47466
47465
  return entityData.map((record, idx) => {
@@ -47623,7 +47622,7 @@ var init_MediaGallery = __esm({
47623
47622
  }
47624
47623
  });
47625
47624
  function extractTitle2(children) {
47626
- if (!React105__default.isValidElement(children)) return void 0;
47625
+ if (!React103__default.isValidElement(children)) return void 0;
47627
47626
  const props = children.props;
47628
47627
  if (typeof props.title === "string") {
47629
47628
  return props.title;
@@ -47640,14 +47639,18 @@ var init_ModalSlot = __esm({
47640
47639
  children,
47641
47640
  title: overrideTitle,
47642
47641
  size = "md",
47643
- className
47642
+ className,
47643
+ sourceTrait
47644
47644
  }) => {
47645
47645
  const eventBus = useEventBus();
47646
+ const schemaCtx = useEntitySchemaOptional();
47646
47647
  const isOpen = Boolean(children);
47647
47648
  const title = overrideTitle || extractTitle2(children);
47648
47649
  const handleClose = () => {
47649
- eventBus.emit("UI:CLOSE");
47650
- eventBus.emit("UI:CANCEL");
47650
+ const orbital = sourceTrait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
47651
+ const prefix = orbital !== void 0 && sourceTrait !== void 0 ? `UI:${orbital}.${sourceTrait}.` : "UI:";
47652
+ eventBus.emit(`${prefix}CLOSE`);
47653
+ eventBus.emit(`${prefix}CANCEL`);
47651
47654
  };
47652
47655
  if (!isOpen) return null;
47653
47656
  return /* @__PURE__ */ jsx(
@@ -47893,7 +47896,7 @@ var init_debugRegistry = __esm({
47893
47896
  }
47894
47897
  });
47895
47898
  function useDebugData() {
47896
- const [data, setData] = React105.useState(() => ({
47899
+ const [data, setData] = React103.useState(() => ({
47897
47900
  traits: [],
47898
47901
  ticks: [],
47899
47902
  guards: [],
@@ -47907,7 +47910,7 @@ function useDebugData() {
47907
47910
  },
47908
47911
  lastUpdate: Date.now()
47909
47912
  }));
47910
- React105.useEffect(() => {
47913
+ React103.useEffect(() => {
47911
47914
  const updateData = () => {
47912
47915
  setData({
47913
47916
  traits: getAllTraits(),
@@ -48016,12 +48019,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
48016
48019
  return positions;
48017
48020
  }
48018
48021
  function WalkMinimap() {
48019
- const [walkStep, setWalkStep] = React105.useState(null);
48020
- const [traits2, setTraits] = React105.useState([]);
48021
- const [coveredEdges, setCoveredEdges] = React105.useState([]);
48022
- const [completedTraits, setCompletedTraits] = React105.useState(/* @__PURE__ */ new Set());
48023
- const prevTraitRef = React105.useRef(null);
48024
- React105.useEffect(() => {
48022
+ const [walkStep, setWalkStep] = React103.useState(null);
48023
+ const [traits2, setTraits] = React103.useState([]);
48024
+ const [coveredEdges, setCoveredEdges] = React103.useState([]);
48025
+ const [completedTraits, setCompletedTraits] = React103.useState(/* @__PURE__ */ new Set());
48026
+ const prevTraitRef = React103.useRef(null);
48027
+ React103.useEffect(() => {
48025
48028
  const interval = setInterval(() => {
48026
48029
  const w = window;
48027
48030
  const step = w.__orbitalWalkStep;
@@ -48457,15 +48460,15 @@ var init_EntitiesTab = __esm({
48457
48460
  });
48458
48461
  function EventFlowTab({ events: events2 }) {
48459
48462
  const { t } = useTranslate();
48460
- const [filter, setFilter] = React105.useState("all");
48461
- const containerRef = React105.useRef(null);
48462
- const [autoScroll, setAutoScroll] = React105.useState(true);
48463
- React105.useEffect(() => {
48463
+ const [filter, setFilter] = React103.useState("all");
48464
+ const containerRef = React103.useRef(null);
48465
+ const [autoScroll, setAutoScroll] = React103.useState(true);
48466
+ React103.useEffect(() => {
48464
48467
  if (autoScroll && containerRef.current) {
48465
48468
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
48466
48469
  }
48467
48470
  }, [events2.length, autoScroll]);
48468
- const filteredEvents = React105.useMemo(() => {
48471
+ const filteredEvents = React103.useMemo(() => {
48469
48472
  if (filter === "all") return events2;
48470
48473
  return events2.filter((e) => e.type === filter);
48471
48474
  }, [events2, filter]);
@@ -48581,7 +48584,7 @@ var init_EventFlowTab = __esm({
48581
48584
  });
48582
48585
  function GuardsPanel({ guards }) {
48583
48586
  const { t } = useTranslate();
48584
- const [filter, setFilter] = React105.useState("all");
48587
+ const [filter, setFilter] = React103.useState("all");
48585
48588
  if (guards.length === 0) {
48586
48589
  return /* @__PURE__ */ jsx(
48587
48590
  EmptyState,
@@ -48594,7 +48597,7 @@ function GuardsPanel({ guards }) {
48594
48597
  }
48595
48598
  const passedCount = guards.filter((g) => g.result).length;
48596
48599
  const failedCount = guards.length - passedCount;
48597
- const filteredGuards = React105.useMemo(() => {
48600
+ const filteredGuards = React103.useMemo(() => {
48598
48601
  if (filter === "all") return guards;
48599
48602
  if (filter === "passed") return guards.filter((g) => g.result);
48600
48603
  return guards.filter((g) => !g.result);
@@ -48757,10 +48760,10 @@ function EffectBadge({ effect }) {
48757
48760
  }
48758
48761
  function TransitionTimeline({ transitions }) {
48759
48762
  const { t } = useTranslate();
48760
- const containerRef = React105.useRef(null);
48761
- const [autoScroll, setAutoScroll] = React105.useState(true);
48762
- const [expandedId, setExpandedId] = React105.useState(null);
48763
- React105.useEffect(() => {
48763
+ const containerRef = React103.useRef(null);
48764
+ const [autoScroll, setAutoScroll] = React103.useState(true);
48765
+ const [expandedId, setExpandedId] = React103.useState(null);
48766
+ React103.useEffect(() => {
48764
48767
  if (autoScroll && containerRef.current) {
48765
48768
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
48766
48769
  }
@@ -49040,9 +49043,9 @@ function getAllEvents(traits2) {
49040
49043
  function EventDispatcherTab({ traits: traits2, schema }) {
49041
49044
  const eventBus = useEventBus();
49042
49045
  const { t } = useTranslate();
49043
- const [log9, setLog] = React105.useState([]);
49044
- const prevStatesRef = React105.useRef(/* @__PURE__ */ new Map());
49045
- React105.useEffect(() => {
49046
+ const [log9, setLog] = React103.useState([]);
49047
+ const prevStatesRef = React103.useRef(/* @__PURE__ */ new Map());
49048
+ React103.useEffect(() => {
49046
49049
  for (const trait of traits2) {
49047
49050
  const prev = prevStatesRef.current.get(trait.id);
49048
49051
  if (prev && prev !== trait.currentState) {
@@ -49211,10 +49214,10 @@ function VerifyModePanel({
49211
49214
  localCount
49212
49215
  }) {
49213
49216
  const { t } = useTranslate();
49214
- const [expanded, setExpanded] = React105.useState(true);
49215
- const scrollRef = React105.useRef(null);
49216
- const prevCountRef = React105.useRef(0);
49217
- React105.useEffect(() => {
49217
+ const [expanded, setExpanded] = React103.useState(true);
49218
+ const scrollRef = React103.useRef(null);
49219
+ const prevCountRef = React103.useRef(0);
49220
+ React103.useEffect(() => {
49218
49221
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
49219
49222
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
49220
49223
  }
@@ -49271,10 +49274,10 @@ function RuntimeDebugger({
49271
49274
  schema
49272
49275
  }) {
49273
49276
  const { t } = useTranslate();
49274
- const [isCollapsed, setIsCollapsed] = React105.useState(mode === "verify" ? true : defaultCollapsed);
49275
- const [isVisible, setIsVisible] = React105.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
49277
+ const [isCollapsed, setIsCollapsed] = React103.useState(mode === "verify" ? true : defaultCollapsed);
49278
+ const [isVisible, setIsVisible] = React103.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
49276
49279
  const debugData = useDebugData();
49277
- React105.useEffect(() => {
49280
+ React103.useEffect(() => {
49278
49281
  if (mode === "inline") return;
49279
49282
  return onDebugToggle((enabled) => {
49280
49283
  setIsVisible(enabled);
@@ -49283,7 +49286,7 @@ function RuntimeDebugger({
49283
49286
  }
49284
49287
  });
49285
49288
  }, [mode]);
49286
- React105.useEffect(() => {
49289
+ React103.useEffect(() => {
49287
49290
  if (mode === "inline") return;
49288
49291
  const handleKeyDown = (e) => {
49289
49292
  if (e.key === "`" && isVisible) {
@@ -49803,7 +49806,7 @@ var init_StatCard = __esm({
49803
49806
  const labelToUse = propLabel ?? propTitle;
49804
49807
  const eventBus = useEventBus();
49805
49808
  const { t } = useTranslate();
49806
- const handleActionClick = React105__default.useCallback(() => {
49809
+ const handleActionClick = React103__default.useCallback(() => {
49807
49810
  if (action?.event) {
49808
49811
  eventBus.emit(`UI:${action.event}`, {});
49809
49812
  }
@@ -49814,7 +49817,7 @@ var init_StatCard = __esm({
49814
49817
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
49815
49818
  const isLoading = externalLoading ?? false;
49816
49819
  const error = externalError;
49817
- const computeMetricValue = React105__default.useCallback(
49820
+ const computeMetricValue = React103__default.useCallback(
49818
49821
  (metric, items) => {
49819
49822
  if (metric.value !== void 0) {
49820
49823
  return metric.value;
@@ -49853,7 +49856,7 @@ var init_StatCard = __esm({
49853
49856
  },
49854
49857
  []
49855
49858
  );
49856
- const schemaStats = React105__default.useMemo(() => {
49859
+ const schemaStats = React103__default.useMemo(() => {
49857
49860
  if (!metrics || metrics.length === 0) return null;
49858
49861
  return metrics.map((metric) => ({
49859
49862
  label: metric.label,
@@ -49861,7 +49864,7 @@ var init_StatCard = __esm({
49861
49864
  format: metric.format
49862
49865
  }));
49863
49866
  }, [metrics, data, computeMetricValue]);
49864
- const calculatedTrend = React105__default.useMemo(() => {
49867
+ const calculatedTrend = React103__default.useMemo(() => {
49865
49868
  if (manualTrend !== void 0) return manualTrend;
49866
49869
  if (previousValue === void 0 || currentValue === void 0)
49867
49870
  return void 0;
@@ -50501,8 +50504,8 @@ var init_SubagentTracePanel = __esm({
50501
50504
  ] });
50502
50505
  };
50503
50506
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
50504
- const endRef = React105__default.useRef(null);
50505
- React105__default.useEffect(() => {
50507
+ const endRef = React103__default.useRef(null);
50508
+ React103__default.useEffect(() => {
50506
50509
  if (!autoScroll) return;
50507
50510
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
50508
50511
  }, [activities.length, autoScroll]);
@@ -50596,7 +50599,7 @@ var init_SubagentTracePanel = __esm({
50596
50599
  };
50597
50600
  SubagentRichCard = ({ subagent }) => {
50598
50601
  const { t } = useTranslate();
50599
- const activities = React105__default.useMemo(
50602
+ const activities = React103__default.useMemo(
50600
50603
  () => subagentMessagesToActivities(subagent.messages),
50601
50604
  [subagent.messages]
50602
50605
  );
@@ -50673,8 +50676,8 @@ var init_SubagentTracePanel = __esm({
50673
50676
  ] });
50674
50677
  };
50675
50678
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
50676
- const endRef = React105__default.useRef(null);
50677
- React105__default.useEffect(() => {
50679
+ const endRef = React103__default.useRef(null);
50680
+ React103__default.useEffect(() => {
50678
50681
  if (!autoScroll) return;
50679
50682
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
50680
50683
  }, [messages.length, autoScroll]);
@@ -51104,7 +51107,7 @@ var init_Timeline = __esm({
51104
51107
  }) => {
51105
51108
  const { t } = useTranslate();
51106
51109
  const entityData = entity ?? [];
51107
- const items = React105__default.useMemo(() => {
51110
+ const items = React103__default.useMemo(() => {
51108
51111
  if (propItems) return propItems;
51109
51112
  if (entityData.length === 0) return [];
51110
51113
  return entityData.map((record, idx) => {
@@ -51206,7 +51209,7 @@ var init_Timeline = __esm({
51206
51209
  }
51207
51210
  });
51208
51211
  function extractToastProps(children) {
51209
- if (!React105__default.isValidElement(children)) {
51212
+ if (!React103__default.isValidElement(children)) {
51210
51213
  if (typeof children === "string") {
51211
51214
  return { message: children };
51212
51215
  }
@@ -51231,20 +51234,24 @@ var init_ToastSlot = __esm({
51231
51234
  variant: overrideVariant,
51232
51235
  title: overrideTitle,
51233
51236
  duration = 5e3,
51234
- className
51237
+ className,
51238
+ sourceTrait
51235
51239
  }) => {
51236
51240
  const eventBus = useEventBus();
51241
+ const schemaCtx = useEntitySchemaOptional();
51237
51242
  const isVisible = Boolean(children);
51238
51243
  const extracted = extractToastProps(children);
51239
51244
  const variant = overrideVariant || extracted.variant || "info";
51240
51245
  const title = overrideTitle || extracted.title;
51241
51246
  const message = extracted.message || (typeof children === "string" ? children : "");
51242
51247
  const handleDismiss = () => {
51243
- eventBus.emit("UI:DISMISS");
51244
- eventBus.emit("UI:CLOSE");
51248
+ const orbital = sourceTrait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
51249
+ const prefix = orbital !== void 0 && sourceTrait !== void 0 ? `UI:${orbital}.${sourceTrait}.` : "UI:";
51250
+ eventBus.emit(`${prefix}DISMISS`);
51251
+ eventBus.emit(`${prefix}CLOSE`);
51245
51252
  };
51246
51253
  if (!isVisible) return null;
51247
- const isCustomContent = React105__default.isValidElement(children) && !message;
51254
+ const isCustomContent = React103__default.isValidElement(children) && !message;
51248
51255
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
51249
51256
  Toast,
51250
51257
  {
@@ -51261,7 +51268,7 @@ var init_ToastSlot = __esm({
51261
51268
  }
51262
51269
  });
51263
51270
  function lazyThree(name, loader) {
51264
- const Lazy = React105__default.lazy(
51271
+ const Lazy = React103__default.lazy(
51265
51272
  () => loader().then((m) => {
51266
51273
  const Resolved = m[name];
51267
51274
  if (!Resolved) {
@@ -51273,13 +51280,13 @@ function lazyThree(name, loader) {
51273
51280
  })
51274
51281
  );
51275
51282
  function ThreeWrapper(props) {
51276
- return React105__default.createElement(
51283
+ return React103__default.createElement(
51277
51284
  ThreeBoundary,
51278
51285
  { name },
51279
- React105__default.createElement(
51280
- React105__default.Suspense,
51286
+ React103__default.createElement(
51287
+ React103__default.Suspense,
51281
51288
  { fallback: null },
51282
- React105__default.createElement(Lazy, props)
51289
+ React103__default.createElement(Lazy, props)
51283
51290
  )
51284
51291
  );
51285
51292
  }
@@ -51591,7 +51598,7 @@ var init_component_registry_generated = __esm({
51591
51598
  init_WizardProgress();
51592
51599
  init_WorldMapBoard();
51593
51600
  init_WorldMapTemplate();
51594
- ThreeBoundary = class extends React105__default.Component {
51601
+ ThreeBoundary = class extends React103__default.Component {
51595
51602
  constructor() {
51596
51603
  super(...arguments);
51597
51604
  __publicField(this, "state", { failed: false });
@@ -51601,7 +51608,7 @@ var init_component_registry_generated = __esm({
51601
51608
  }
51602
51609
  render() {
51603
51610
  if (this.state.failed) {
51604
- return React105__default.createElement(
51611
+ return React103__default.createElement(
51605
51612
  "div",
51606
51613
  {
51607
51614
  "data-testid": "three-unavailable",
@@ -51957,7 +51964,7 @@ function SuspenseConfigProvider({
51957
51964
  config,
51958
51965
  children
51959
51966
  }) {
51960
- return React105__default.createElement(
51967
+ return React103__default.createElement(
51961
51968
  SuspenseConfigContext.Provider,
51962
51969
  { value: config },
51963
51970
  children
@@ -51968,8 +51975,8 @@ function getSlotFallback(slot, config) {
51968
51975
  const variant = SLOT_SKELETON_MAP[slot] ?? "text";
51969
51976
  return /* @__PURE__ */ jsx(Skeleton, { variant });
51970
51977
  }
51971
- function getComponentForPattern3(patternType) {
51972
- const mapping = getComponentForPattern(patternType);
51978
+ function getComponentForPattern(patternType) {
51979
+ const mapping = getComponentForPattern$1(patternType);
51973
51980
  if (!mapping) {
51974
51981
  return null;
51975
51982
  }
@@ -51999,7 +52006,7 @@ function enrichFormFields(fields, entityDef) {
51999
52006
  }
52000
52007
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
52001
52008
  }
52002
- if (field && typeof field === "object" && !Array.isArray(field) && !React105__default.isValidElement(field) && !(field instanceof Date)) {
52009
+ if (field && typeof field === "object" && !Array.isArray(field) && !React103__default.isValidElement(field) && !(field instanceof Date)) {
52003
52010
  const obj = field;
52004
52011
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
52005
52012
  if (!fieldName) return field;
@@ -52177,6 +52184,7 @@ function UISlotComponent({
52177
52184
  const { t } = useTranslate();
52178
52185
  const suspenseConfig = useContext(SuspenseConfigContext);
52179
52186
  const contained = useContext(SlotContainedContext);
52187
+ const schemaCtx = useEntitySchemaOptional();
52180
52188
  const content = slots[slot];
52181
52189
  if (children !== void 0) {
52182
52190
  if (pattern === "clear") {
@@ -52222,8 +52230,11 @@ function UISlotComponent({
52222
52230
  }
52223
52231
  const handleDismiss = () => {
52224
52232
  if (slot === "modal" || slot === "drawer") {
52225
- eventBus.emit("UI:CLOSE");
52226
- eventBus.emit("UI:CANCEL");
52233
+ const trait = content?.sourceTrait;
52234
+ const orbital = trait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(trait) : void 0;
52235
+ const prefix = orbital !== void 0 && trait !== void 0 ? `UI:${orbital}.${trait}.` : "UI:";
52236
+ eventBus.emit(`${prefix}CLOSE`);
52237
+ eventBus.emit(`${prefix}CANCEL`);
52227
52238
  }
52228
52239
  clear(slot);
52229
52240
  };
@@ -52277,6 +52288,7 @@ function CompiledPortal({ slot, className, pattern, sourceTrait, children }) {
52277
52288
  const slotsBus = useUISlots();
52278
52289
  const eventBus = useEventBus();
52279
52290
  const { t } = useTranslate();
52291
+ const compiledPortalSchemaCtx = useEntitySchemaOptional();
52280
52292
  useEffect(() => {
52281
52293
  setPortalRoot(getOrCreatePortalRoot());
52282
52294
  }, []);
@@ -52285,8 +52297,10 @@ function CompiledPortal({ slot, className, pattern, sourceTrait, children }) {
52285
52297
  });
52286
52298
  const handleDismiss = () => {
52287
52299
  if (slot === "modal" || slot === "drawer") {
52288
- eventBus.emit("UI:CLOSE");
52289
- eventBus.emit("UI:CANCEL");
52300
+ const orbital = sourceTrait !== void 0 && compiledPortalSchemaCtx !== null ? compiledPortalSchemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
52301
+ const prefix = orbital !== void 0 && sourceTrait !== void 0 ? `UI:${orbital}.${sourceTrait}.` : "UI:";
52302
+ eventBus.emit(`${prefix}CLOSE`);
52303
+ eventBus.emit(`${prefix}CANCEL`);
52290
52304
  }
52291
52305
  slotsBus.clear(slot);
52292
52306
  };
@@ -52445,7 +52459,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
52445
52459
  const key = `${parentId}-${index}-trait:${traitName}`;
52446
52460
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
52447
52461
  }
52448
- return /* @__PURE__ */ jsx(React105__default.Fragment, { children: child }, `${parentId}-${index}`);
52462
+ return /* @__PURE__ */ jsx(React103__default.Fragment, { children: child }, `${parentId}-${index}`);
52449
52463
  }
52450
52464
  if (!child || typeof child !== "object") return null;
52451
52465
  const childId = `${parentId}-${index}`;
@@ -52485,14 +52499,14 @@ function isPatternConfig(value) {
52485
52499
  if (value === null || value === void 0) return false;
52486
52500
  if (typeof value !== "object") return false;
52487
52501
  if (Array.isArray(value)) return false;
52488
- if (React105__default.isValidElement(value)) return false;
52502
+ if (React103__default.isValidElement(value)) return false;
52489
52503
  if (value instanceof Date) return false;
52490
52504
  if (typeof value === "function") return false;
52491
52505
  const record = value;
52492
- return "type" in record && typeof record.type === "string" && getComponentForPattern(record.type) !== null;
52506
+ return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
52493
52507
  }
52494
52508
  function isPlainConfigObject(value) {
52495
- if (React105__default.isValidElement(value)) return false;
52509
+ if (React103__default.isValidElement(value)) return false;
52496
52510
  if (value instanceof Date) return false;
52497
52511
  const proto = Object.getPrototypeOf(value);
52498
52512
  return proto === Object.prototype || proto === null;
@@ -52598,7 +52612,7 @@ function SlotContentRenderer({
52598
52612
  }
52599
52613
  }
52600
52614
  const orbitalName = schemaCtx && content.sourceTrait !== void 0 ? schemaCtx.orbitalsByTrait.get(content.sourceTrait) : void 0;
52601
- const PatternComponent = getComponentForPattern3(content.pattern);
52615
+ const PatternComponent = getComponentForPattern(content.pattern);
52602
52616
  if (PatternComponent) {
52603
52617
  const childrenConfig = content.props.children;
52604
52618
  const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
@@ -52618,7 +52632,7 @@ function SlotContentRenderer({
52618
52632
  for (const slotKey of CONTENT_NODE_SLOTS) {
52619
52633
  const slotVal = restProps[slotKey];
52620
52634
  if (slotVal === void 0 || slotVal === null) continue;
52621
- if (React105__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
52635
+ if (React103__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
52622
52636
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
52623
52637
  nodeSlotOverrides[slotKey] = renderPatternChildren(
52624
52638
  slotVal,
@@ -52667,7 +52681,7 @@ function SlotContentRenderer({
52667
52681
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
52668
52682
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
52669
52683
  const sample = resolvedItems[0];
52670
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React105__default.isValidElement(sample) && !(sample instanceof Date)) {
52684
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React103__default.isValidElement(sample) && !(sample instanceof Date)) {
52671
52685
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
52672
52686
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
52673
52687
  }
@@ -52845,6 +52859,7 @@ var init_UISlotRenderer = __esm({
52845
52859
  "custom",
52846
52860
  "dashboard-layout",
52847
52861
  "game-shell",
52862
+ "game-template",
52848
52863
  "scaled-diagram",
52849
52864
  "master-detail",
52850
52865
  "form-field",
@@ -52958,7 +52973,7 @@ function resolveLambdaBindings(body, params, item, index) {
52958
52973
  if (Array.isArray(body)) {
52959
52974
  return body.map((b) => recur(b));
52960
52975
  }
52961
- if (body !== null && typeof body === "object" && !React105__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
52976
+ if (body !== null && typeof body === "object" && !React103__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
52962
52977
  const out = {};
52963
52978
  for (const [k, v] of Object.entries(body)) {
52964
52979
  out[k] = recur(v);
@@ -52968,7 +52983,7 @@ function resolveLambdaBindings(body, params, item, index) {
52968
52983
  return body;
52969
52984
  }
52970
52985
  var _slotContentRenderer2 = null;
52971
- function getSlotContentRenderer4() {
52986
+ function getSlotContentRenderer2() {
52972
52987
  if (_slotContentRenderer2) return _slotContentRenderer2;
52973
52988
  const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
52974
52989
  _slotContentRenderer2 = mod.SlotContentRenderer;
@@ -52977,14 +52992,14 @@ function getSlotContentRenderer4() {
52977
52992
  function makeLambdaFn(params, lambdaBody, callerKey) {
52978
52993
  return (item, index) => {
52979
52994
  const resolvedBody = resolveLambdaBindings(lambdaBody, params, item, index);
52980
- if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React105__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
52995
+ if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React103__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
52981
52996
  return null;
52982
52997
  }
52983
52998
  const record = resolvedBody;
52984
52999
  if (typeof record.type !== "string") {
52985
53000
  return null;
52986
53001
  }
52987
- const SlotContentRenderer2 = getSlotContentRenderer4();
53002
+ const SlotContentRenderer2 = getSlotContentRenderer2();
52988
53003
  const rawChildProps = {};
52989
53004
  for (const [k, v] of Object.entries(record)) {
52990
53005
  if (k !== "type") rawChildProps[k] = v;
@@ -52996,7 +53011,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
52996
53011
  props: childProps,
52997
53012
  priority: 0
52998
53013
  };
52999
- return React105__default.createElement(SlotContentRenderer2, { content: childContent });
53014
+ return React103__default.createElement(SlotContentRenderer2, { content: childContent });
53000
53015
  };
53001
53016
  }
53002
53017
  function convertNode(node, callerKey) {
@@ -53015,7 +53030,7 @@ function convertNode(node, callerKey) {
53015
53030
  });
53016
53031
  return anyChanged ? mapped : node;
53017
53032
  }
53018
- if (typeof node === "object" && !React105__default.isValidElement(node) && !(node instanceof Date)) {
53033
+ if (typeof node === "object" && !React103__default.isValidElement(node) && !(node instanceof Date)) {
53019
53034
  return convertObjectProps(node);
53020
53035
  }
53021
53036
  return node;