@almadar/ui 5.121.3 → 5.122.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.
@@ -1,6 +1,6 @@
1
- import * as React81 from 'react';
2
- import React81__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, createContext, useSyncExternalStore, lazy, useLayoutEffect, useId } from 'react';
3
- import { EventBusContext, useTraitScope, useEntitySchemaOptional, useEntitySchema, getAllPages, OrbitalProvider, TraitScopeProvider, ServerBridgeProvider, useCurrentPagePath, useGameAudioContextOptional, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge } from '@almadar/ui/providers';
1
+ import * as React82 from 'react';
2
+ import React82__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, lazy, useLayoutEffect, useId } from 'react';
3
+ import { EventBusContext, useTraitScopeChain, useEntitySchemaOptional, useEntitySchema, getAllPages, OrbitalProvider, TraitScopeProvider, ServerBridgeProvider, useCurrentPagePath, useGameAudioContextOptional, 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, setNamespaceLevel, isLogLevelEnabled } from '@almadar/logger';
6
6
  import { clsx } from 'clsx';
@@ -39,7 +39,7 @@ import ReactMarkdown from 'react-markdown';
39
39
  import remarkGfm from 'remark-gfm';
40
40
  import remarkMath from 'remark-math';
41
41
  import rehypeKatex from 'rehype-katex';
42
- import { isCircuitEvent, schemaToIR, getPage, clearSchemaCache as clearSchemaCache$1, walkSExpr, buildResolvedTraitConfigs, mergeEntityFrame, isInlineTrait, isSExpr, isEventPayloadValue } from '@almadar/core';
42
+ import { mergeEntityFrame, isCircuitEvent, schemaToIR, getPage, clearSchemaCache as clearSchemaCache$1, walkSExpr, buildResolvedTraitConfigs, isInlineTrait, isSExpr, isEventPayloadValue } from '@almadar/core';
43
43
  import { DndContext, pointerWithin, rectIntersection, closestCorners, useSensors, useSensor, PointerSensor, KeyboardSensor, useDroppable } from '@dnd-kit/core';
44
44
  import { useSortable, arrayMove, sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
45
45
  import { CSS } from '@dnd-kit/utilities';
@@ -98,9 +98,9 @@ function getGlobalEventBus() {
98
98
  function useEventBus() {
99
99
  const context = useContext(EventBusContext);
100
100
  const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
101
- const scope = useTraitScope();
101
+ const chain = useTraitScopeChain();
102
102
  return useMemo(() => {
103
- if (!scope) {
103
+ if (chain.length === 0) {
104
104
  return {
105
105
  ...baseBus,
106
106
  emit: (type, payload, source) => {
@@ -116,22 +116,31 @@ function useEventBus() {
116
116
  emit: (type, payload, source) => {
117
117
  if (typeof type === "string" && type.startsWith("UI:")) {
118
118
  const tail = type.slice(3);
119
- const qualified = tail.includes(".") ? type : `UI:${scope.orbital}.${scope.trait}.${tail}`;
120
- if (qualified !== type) {
121
- scopeLog.info("emit:qualified", {
119
+ const isQualified = tail.includes(".");
120
+ const event = isQualified ? tail.split(".").slice(2).join(".") : tail;
121
+ if (!event) {
122
+ baseBus.emit(type, payload, source);
123
+ return;
124
+ }
125
+ const keys = /* @__PURE__ */ new Set();
126
+ if (isQualified) keys.add(type);
127
+ for (const sc of chain) {
128
+ keys.add(`UI:${sc.orbital}.${sc.trait}.${event}`);
129
+ }
130
+ if (keys.size > 1) {
131
+ scopeLog.info("emit:fan-out", {
122
132
  from: type,
123
- to: qualified,
124
- scopeOrbital: scope.orbital,
125
- scopeTrait: scope.trait
133
+ keys: Array.from(keys),
134
+ chainDepth: chain.length
126
135
  });
127
136
  }
128
- baseBus.emit(qualified, payload, source);
137
+ for (const key of keys) baseBus.emit(key, payload, source);
129
138
  return;
130
139
  }
131
140
  baseBus.emit(type, payload, source);
132
141
  }
133
142
  };
134
- }, [baseBus, scope]);
143
+ }, [baseBus, chain]);
135
144
  }
136
145
  function useEventListener(event, handler) {
137
146
  const eventBus = useEventBus();
@@ -869,7 +878,7 @@ var init_Box = __esm({
869
878
  fixed: "fixed",
870
879
  sticky: "sticky"
871
880
  };
872
- Box = React81__default.forwardRef(
881
+ Box = React82__default.forwardRef(
873
882
  ({
874
883
  padding,
875
884
  paddingX,
@@ -934,7 +943,7 @@ var init_Box = __esm({
934
943
  onPointerDown?.(e);
935
944
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
936
945
  const isClickable = action || onClick;
937
- return React81__default.createElement(
946
+ return React82__default.createElement(
938
947
  Component,
939
948
  {
940
949
  ref,
@@ -1148,13 +1157,13 @@ var init_Icon = __esm({
1148
1157
  style
1149
1158
  }) => {
1150
1159
  const directIcon = typeof icon === "string" ? void 0 : icon;
1151
- const effectiveName = typeof icon === "string" ? icon : name;
1160
+ const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
1161
+ const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
1152
1162
  const family = useIconFamily();
1153
- const RenderedComponent = React81__default.useMemo(() => {
1163
+ const RenderedComponent = React82__default.useMemo(() => {
1154
1164
  if (directIcon) return null;
1155
1165
  return effectiveName ? resolveIconForFamily(effectiveName) : null;
1156
1166
  }, [directIcon, effectiveName, family]);
1157
- const effectiveStrokeWidth = strokeWidth ?? void 0;
1158
1167
  const inlineStyle = {
1159
1168
  ...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
1160
1169
  ...style
@@ -1271,7 +1280,7 @@ var init_atlasSlice = __esm({
1271
1280
  }
1272
1281
  });
1273
1282
  function useAtlasSliceDataUrl(asset) {
1274
- const [, bump] = React81.useReducer((x) => x + 1, 0);
1283
+ const [, bump] = React82.useReducer((x) => x + 1, 0);
1275
1284
  if (!isAtlasAsset(asset)) return void 0;
1276
1285
  const key = `${asset.atlas}#${asset.sprite}`;
1277
1286
  const cached = sliceDataUrlCache.get(key);
@@ -1334,13 +1343,13 @@ function AtlasImage({
1334
1343
  style,
1335
1344
  "aria-hidden": ariaHidden
1336
1345
  }) {
1337
- const [, bump] = React81.useReducer((x) => x + 1, 0);
1338
- const canvasRef = React81.useRef(null);
1346
+ const [, bump] = React82.useReducer((x) => x + 1, 0);
1347
+ const canvasRef = React82.useRef(null);
1339
1348
  const sliced = isAtlasAsset(asset);
1340
1349
  const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
1341
1350
  const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
1342
1351
  const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
1343
- React81.useEffect(() => {
1352
+ React82.useEffect(() => {
1344
1353
  const canvas = canvasRef.current;
1345
1354
  if (!canvas || !img || !rect) return;
1346
1355
  canvas.width = rect.sw;
@@ -1416,7 +1425,7 @@ function resolveIconProp(value, sizeClass) {
1416
1425
  const IconComp = value;
1417
1426
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1418
1427
  }
1419
- if (React81__default.isValidElement(value)) {
1428
+ if (React82__default.isValidElement(value)) {
1420
1429
  return value;
1421
1430
  }
1422
1431
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -1493,7 +1502,7 @@ var init_Button = __esm({
1493
1502
  md: "h-icon-default w-icon-default",
1494
1503
  lg: "h-icon-default w-icon-default"
1495
1504
  };
1496
- Button = React81__default.forwardRef(
1505
+ Button = React82__default.forwardRef(
1497
1506
  ({
1498
1507
  className,
1499
1508
  variant = "primary",
@@ -1535,7 +1544,8 @@ var init_Button = __esm({
1535
1544
  "font-medium",
1536
1545
  "rounded-sm",
1537
1546
  "cursor-pointer",
1538
- "transition-all duration-[var(--transition-normal)]",
1547
+ "chrome-button",
1548
+ "transition-all duration-normal",
1539
1549
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-offset-[length:var(--focus-ring-offset)]",
1540
1550
  "disabled:opacity-50 disabled:cursor-not-allowed",
1541
1551
  variantStyles[variant],
@@ -1561,7 +1571,7 @@ var Dialog;
1561
1571
  var init_Dialog = __esm({
1562
1572
  "components/core/atoms/Dialog.tsx"() {
1563
1573
  init_cn();
1564
- Dialog = React81__default.forwardRef(
1574
+ Dialog = React82__default.forwardRef(
1565
1575
  ({
1566
1576
  role = "dialog",
1567
1577
  "aria-modal": ariaModal = true,
@@ -1679,7 +1689,7 @@ var init_Typography = __esm({
1679
1689
  }) => {
1680
1690
  const variant = variantProp ?? (level ? `h${level}` : "body1");
1681
1691
  const Component = as || defaultElements[variant];
1682
- return React81__default.createElement(
1692
+ return React82__default.createElement(
1683
1693
  Component,
1684
1694
  {
1685
1695
  id,
@@ -1754,6 +1764,15 @@ var init_Modal = __esm({
1754
1764
  const [dragY, setDragY] = useState(0);
1755
1765
  const dragStartY = useRef(0);
1756
1766
  const isDragging = useRef(false);
1767
+ const [closing, setClosing] = useState(false);
1768
+ const wasOpenRef = useRef(isOpen);
1769
+ useEffect(() => {
1770
+ if (wasOpenRef.current && !isOpen) setClosing(true);
1771
+ wasOpenRef.current = isOpen;
1772
+ }, [isOpen]);
1773
+ const handleAnimEnd = (e) => {
1774
+ if (closing && e.target === e.currentTarget) setClosing(false);
1775
+ };
1757
1776
  useEffect(() => {
1758
1777
  if (isOpen) {
1759
1778
  previousActiveElement.current = document.activeElement;
@@ -1787,7 +1806,11 @@ var init_Modal = __esm({
1787
1806
  document.body.style.overflow = "";
1788
1807
  };
1789
1808
  }, [isOpen]);
1790
- if (!isOpen || typeof document === "undefined") return null;
1809
+ if (typeof document === "undefined") return null;
1810
+ const renderOpen = isOpen || closing;
1811
+ if (!renderOpen) return null;
1812
+ const dialogAnim = closing ? "animate-modal-out" : "animate-modal-in";
1813
+ const overlayAnim = closing ? "animate-overlay-out" : "animate-overlay-in";
1791
1814
  const handleClose = () => {
1792
1815
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
1793
1816
  onClose();
@@ -1804,7 +1827,8 @@ var init_Modal = __esm({
1804
1827
  className: cn(
1805
1828
  "fixed inset-0 z-[1000]",
1806
1829
  "flex items-start justify-center px-4 pb-4 pt-[10vh]",
1807
- "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
1830
+ "max-sm:items-stretch max-sm:p-0 max-sm:pt-0",
1831
+ overlayAnim
1808
1832
  ),
1809
1833
  style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
1810
1834
  onClick: handleOverlayClick,
@@ -1832,8 +1856,10 @@ var init_Modal = __esm({
1832
1856
  // full height, no rounded corners, no min-width.
1833
1857
  "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
1834
1858
  lookStyles[look],
1835
- className
1859
+ className,
1860
+ dialogAnim
1836
1861
  ),
1862
+ onAnimationEnd: handleAnimEnd,
1837
1863
  style: dragY > 0 ? {
1838
1864
  transform: `translateY(${dragY}px)`,
1839
1865
  transition: isDragging.current ? "none" : "transform 200ms ease-out"
@@ -1915,12 +1941,84 @@ var init_Modal = __esm({
1915
1941
  Modal.displayName = "Modal";
1916
1942
  }
1917
1943
  });
1944
+ function isMotionEnabled() {
1945
+ if (typeof document === "undefined") return true;
1946
+ if (motionEnabledCache !== null) return motionEnabledCache;
1947
+ const v = getComputedStyle(document.documentElement).getPropertyValue("--motion-enable").trim().toLowerCase();
1948
+ motionEnabledCache = v !== "off";
1949
+ return motionEnabledCache;
1950
+ }
1951
+ function usePresence(show, opts) {
1952
+ const { animation, animate = true, onExited } = opts;
1953
+ const [mounted, setMounted] = useState(show);
1954
+ const [exiting, setExiting] = useState(false);
1955
+ const prev = useRef(show);
1956
+ const onExitedRef = useRef(onExited);
1957
+ onExitedRef.current = onExited;
1958
+ const safeTimer = useRef(null);
1959
+ const clearSafe = useCallback(() => {
1960
+ if (safeTimer.current) {
1961
+ clearTimeout(safeTimer.current);
1962
+ safeTimer.current = null;
1963
+ }
1964
+ }, []);
1965
+ const finishExit = useCallback(() => {
1966
+ clearSafe();
1967
+ setExiting(false);
1968
+ setMounted(false);
1969
+ onExitedRef.current?.();
1970
+ }, [clearSafe]);
1971
+ useEffect(() => {
1972
+ const moving = animate && isMotionEnabled();
1973
+ if (show && !prev.current) {
1974
+ setExiting(false);
1975
+ setMounted(true);
1976
+ } else if (!show && prev.current) {
1977
+ if (moving) {
1978
+ setExiting(true);
1979
+ clearSafe();
1980
+ safeTimer.current = setTimeout(finishExit, SAFE_EXIT_MS);
1981
+ } else {
1982
+ setMounted(false);
1983
+ setExiting(false);
1984
+ }
1985
+ }
1986
+ prev.current = show;
1987
+ }, [show, animate, clearSafe, finishExit]);
1988
+ useEffect(() => () => clearSafe(), [clearSafe]);
1989
+ const disabled = !animate || !isMotionEnabled();
1990
+ const className = disabled ? "" : exiting ? `animate-${animation}-out` : `animate-${animation}-in`;
1991
+ const onAnimationEnd = useCallback(
1992
+ (e) => {
1993
+ if (e.target !== e.currentTarget) return;
1994
+ if (exiting) finishExit();
1995
+ },
1996
+ [exiting, finishExit]
1997
+ );
1998
+ return { mounted, exiting, className, onAnimationEnd };
1999
+ }
2000
+ var SAFE_EXIT_MS, motionEnabledCache, Presence;
2001
+ var init_Presence = __esm({
2002
+ "components/core/atoms/Presence.tsx"() {
2003
+ "use client";
2004
+ init_cn();
2005
+ SAFE_EXIT_MS = 1e3;
2006
+ motionEnabledCache = null;
2007
+ Presence = ({ show, className, children, ...opts }) => {
2008
+ const { mounted, className: animClass, onAnimationEnd } = usePresence(show, opts);
2009
+ if (!mounted) return null;
2010
+ return /* @__PURE__ */ jsx("div", { className: cn(animClass, className), onAnimationEnd, children });
2011
+ };
2012
+ Presence.displayName = "Presence";
2013
+ }
2014
+ });
1918
2015
  var Overlay;
1919
2016
  var init_Overlay = __esm({
1920
2017
  "components/core/atoms/Overlay.tsx"() {
1921
2018
  "use client";
1922
2019
  init_cn();
1923
2020
  init_useEventBus();
2021
+ init_Presence();
1924
2022
  Overlay = ({
1925
2023
  isVisible = true,
1926
2024
  onClick,
@@ -1929,7 +2027,8 @@ var init_Overlay = __esm({
1929
2027
  action
1930
2028
  }) => {
1931
2029
  const eventBus = useEventBus();
1932
- if (!isVisible) return null;
2030
+ const { mounted, className: animClass, onAnimationEnd } = usePresence(isVisible, { animation: "overlay" });
2031
+ if (!mounted) return null;
1933
2032
  const handleClick = (e) => {
1934
2033
  if (action) {
1935
2034
  eventBus.emit(`UI:${action}`, {});
@@ -1942,10 +2041,12 @@ var init_Overlay = __esm({
1942
2041
  className: cn(
1943
2042
  "fixed inset-0 z-40",
1944
2043
  blur && "backdrop-blur-sm",
2044
+ animClass,
1945
2045
  className
1946
2046
  ),
1947
2047
  style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
1948
2048
  onClick: action || onClick ? handleClick : void 0,
2049
+ onAnimationEnd,
1949
2050
  "aria-hidden": "true"
1950
2051
  }
1951
2052
  );
@@ -1960,6 +2061,7 @@ var init_Drawer = __esm({
1960
2061
  init_Button();
1961
2062
  init_Typography();
1962
2063
  init_Overlay();
2064
+ init_Presence();
1963
2065
  init_cn();
1964
2066
  init_useEventBus();
1965
2067
  sizeWidths = {
@@ -2013,6 +2115,7 @@ var init_Drawer = __esm({
2013
2115
  document.addEventListener("keydown", handleEscape);
2014
2116
  return () => document.removeEventListener("keydown", handleEscape);
2015
2117
  }, [isOpen, closeOnEscape, onClose, closeEvent, eventBus]);
2118
+ const { mounted, className: drawerAnim, onAnimationEnd } = usePresence(isOpen, { animation: "drawer" });
2016
2119
  useEffect(() => {
2017
2120
  if (isOpen) {
2018
2121
  document.body.style.overflow = "hidden";
@@ -2023,7 +2126,7 @@ var init_Drawer = __esm({
2023
2126
  document.body.style.overflow = "";
2024
2127
  };
2025
2128
  }, [isOpen]);
2026
- if (!isOpen) return null;
2129
+ if (!mounted) return null;
2027
2130
  const handleClose = () => {
2028
2131
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
2029
2132
  onClose();
@@ -2036,7 +2139,7 @@ var init_Drawer = __esm({
2036
2139
  const widthClass = width in sizeWidths ? sizeWidths[width] : "";
2037
2140
  const widthStyle = width in sizeWidths ? void 0 : { width };
2038
2141
  const positionClasses = position === "right" ? "right-0 border-l" : "left-0 border-r";
2039
- const animationClasses2 = position === "right" ? "animate-slide-in-right" : "animate-slide-in-left";
2142
+ const drawerSign = position === "right" ? 1 : -1;
2040
2143
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2041
2144
  /* @__PURE__ */ jsx(
2042
2145
  Overlay,
@@ -2058,12 +2161,13 @@ var init_Drawer = __esm({
2058
2161
  "flex flex-col max-h-screen",
2059
2162
  positionClasses,
2060
2163
  widthClass,
2061
- animationClasses2,
2164
+ drawerAnim,
2062
2165
  className
2063
2166
  ),
2064
- style: widthStyle,
2167
+ style: { ...widthStyle, "--motion-drawer-sign": drawerSign },
2065
2168
  role: "dialog",
2066
2169
  "aria-modal": "true",
2170
+ onAnimationEnd,
2067
2171
  ...title && { "aria-labelledby": "drawer-title" },
2068
2172
  children: [
2069
2173
  (title || showCloseButton) && /* @__PURE__ */ jsxs(
@@ -2102,31 +2206,7 @@ var init_Drawer = __esm({
2102
2206
  )
2103
2207
  ]
2104
2208
  }
2105
- ),
2106
- /* @__PURE__ */ jsx("style", { children: `
2107
- @keyframes slide-in-right {
2108
- from {
2109
- transform: translateX(100%);
2110
- }
2111
- to {
2112
- transform: translateX(0);
2113
- }
2114
- }
2115
- @keyframes slide-in-left {
2116
- from {
2117
- transform: translateX(-100%);
2118
- }
2119
- to {
2120
- transform: translateX(0);
2121
- }
2122
- }
2123
- .animate-slide-in-right {
2124
- animation: slide-in-right 0.3s ease-out;
2125
- }
2126
- .animate-slide-in-left {
2127
- animation: slide-in-left 0.3s ease-out;
2128
- }
2129
- ` })
2209
+ )
2130
2210
  ] });
2131
2211
  };
2132
2212
  Drawer.displayName = "Drawer";
@@ -2175,7 +2255,7 @@ var init_Badge = __esm({
2175
2255
  md: "px-2.5 py-1 text-sm",
2176
2256
  lg: "px-3 py-1.5 text-base"
2177
2257
  };
2178
- Badge = React81__default.forwardRef(
2258
+ Badge = React82__default.forwardRef(
2179
2259
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
2180
2260
  const iconSizes3 = {
2181
2261
  sm: "h-icon-default w-icon-default",
@@ -2270,14 +2350,23 @@ var init_Toast = __esm({
2270
2350
  }) => {
2271
2351
  const eventBus = useEventBus();
2272
2352
  const { t } = useTranslate();
2273
- const handleDismiss = () => {
2353
+ const [leaving, setLeaving] = useState(false);
2354
+ const doRealDismiss = () => {
2274
2355
  if (dismissEvent) eventBus.emit(`UI:${dismissEvent}`, {});
2275
2356
  onDismiss?.();
2276
2357
  };
2358
+ const handleDismiss = () => {
2359
+ if (leaving) return;
2360
+ setLeaving(true);
2361
+ };
2277
2362
  const handleAction = () => {
2278
2363
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, {});
2279
2364
  onAction?.();
2280
2365
  };
2366
+ const handleAnimEnd = (e) => {
2367
+ if (e.target !== e.currentTarget) return;
2368
+ if (leaving) doRealDismiss();
2369
+ };
2281
2370
  useEffect(() => {
2282
2371
  if (duration <= 0 || !onDismiss && !dismissEvent) {
2283
2372
  return;
@@ -2296,10 +2385,12 @@ var init_Toast = __esm({
2296
2385
  // edge. `max-w-[calc(100vw-2rem)]` clamps to viewport too.
2297
2386
  "border-l-4 p-4 shadow-elevation-toast min-w-0 sm:min-w-[300px] max-w-md max-w-[calc(100vw-2rem)]",
2298
2387
  "rounded-sm",
2388
+ leaving ? "animate-toast-out" : "animate-toast-in",
2299
2389
  variantClasses[variant],
2300
2390
  className
2301
2391
  ),
2302
2392
  role: "alert",
2393
+ onAnimationEnd: handleAnimEnd,
2303
2394
  children: /* @__PURE__ */ jsxs(Box, { className: "flex items-start gap-3", children: [
2304
2395
  /* @__PURE__ */ jsx(Box, { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx(
2305
2396
  Icon,
@@ -2512,7 +2603,7 @@ var init_SvgFlow = __esm({
2512
2603
  width = 100,
2513
2604
  height = 100
2514
2605
  }) => {
2515
- const markerId = React81__default.useMemo(() => {
2606
+ const markerId = React82__default.useMemo(() => {
2516
2607
  flowIdCounter += 1;
2517
2608
  return `almadar-flow-arrow-${flowIdCounter}`;
2518
2609
  }, []);
@@ -3105,7 +3196,7 @@ var init_SvgRing = __esm({
3105
3196
  width = 100,
3106
3197
  height = 100
3107
3198
  }) => {
3108
- const gradientId = React81__default.useMemo(() => {
3199
+ const gradientId = React82__default.useMemo(() => {
3109
3200
  ringIdCounter += 1;
3110
3201
  return `almadar-ring-glow-${ringIdCounter}`;
3111
3202
  }, []);
@@ -3286,7 +3377,7 @@ var init_Input = __esm({
3286
3377
  init_cn();
3287
3378
  init_Icon();
3288
3379
  init_useEventBus();
3289
- Input = React81__default.forwardRef(
3380
+ Input = React82__default.forwardRef(
3290
3381
  ({
3291
3382
  className,
3292
3383
  inputType,
@@ -3321,7 +3412,7 @@ var init_Input = __esm({
3321
3412
  const showClearButton = clearable && value && String(value).length > 0;
3322
3413
  const isMultiline = type === "textarea";
3323
3414
  const baseClassName = cn(
3324
- "block w-full rounded-sm transition-all duration-[var(--transition-fast)]",
3415
+ "block w-full rounded-sm transition-all duration-fast",
3325
3416
  "border-[length:var(--border-width-thin)] border-border",
3326
3417
  isMultiline ? "px-3 py-2 text-sm" : "h-input-md px-3 text-sm",
3327
3418
  "bg-card hover:bg-muted focus:bg-card",
@@ -3354,7 +3445,7 @@ var init_Input = __esm({
3354
3445
  eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
3355
3446
  }
3356
3447
  };
3357
- const wrapField = (field) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
3448
+ const wrapField = (field, fullWidth = true) => /* @__PURE__ */ jsxs("div", { className: fullWidth ? "w-full" : "w-fit", children: [
3358
3449
  label && /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
3359
3450
  field,
3360
3451
  (helperText || error) && /* @__PURE__ */ jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
@@ -3414,7 +3505,8 @@ var init_Input = __esm({
3414
3505
  ),
3415
3506
  ...props
3416
3507
  }
3417
- )
3508
+ ),
3509
+ false
3418
3510
  );
3419
3511
  }
3420
3512
  return wrapField(
@@ -3453,7 +3545,7 @@ var Label;
3453
3545
  var init_Label = __esm({
3454
3546
  "components/core/atoms/Label.tsx"() {
3455
3547
  init_cn();
3456
- Label = React81__default.forwardRef(
3548
+ Label = React82__default.forwardRef(
3457
3549
  ({ className, required, children, ...props }, ref) => {
3458
3550
  return /* @__PURE__ */ jsxs(
3459
3551
  "label",
@@ -3480,7 +3572,7 @@ var init_Textarea = __esm({
3480
3572
  "components/core/atoms/Textarea.tsx"() {
3481
3573
  init_cn();
3482
3574
  init_useEventBus();
3483
- Textarea = React81__default.forwardRef(
3575
+ Textarea = React82__default.forwardRef(
3484
3576
  ({ className, error, onChange, ...props }, ref) => {
3485
3577
  const eventBus = useEventBus();
3486
3578
  const handleChange = (e) => {
@@ -3719,7 +3811,7 @@ var init_Select = __esm({
3719
3811
  init_cn();
3720
3812
  init_Icon();
3721
3813
  init_useEventBus();
3722
- Select = React81__default.forwardRef(
3814
+ Select = React82__default.forwardRef(
3723
3815
  (props, _ref) => {
3724
3816
  const { multiple, searchable, clearable } = props;
3725
3817
  if (multiple || searchable || clearable) {
@@ -3736,7 +3828,7 @@ var init_Checkbox = __esm({
3736
3828
  "components/core/atoms/Checkbox.tsx"() {
3737
3829
  init_cn();
3738
3830
  init_useEventBus();
3739
- Checkbox = React81__default.forwardRef(
3831
+ Checkbox = React82__default.forwardRef(
3740
3832
  ({ className, label, id, onChange, ...props }, ref) => {
3741
3833
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
3742
3834
  const eventBus = useEventBus();
@@ -3790,7 +3882,7 @@ var init_Spinner = __esm({
3790
3882
  md: "h-6 w-6",
3791
3883
  lg: "h-8 w-8"
3792
3884
  };
3793
- Spinner = React81__default.forwardRef(
3885
+ Spinner = React82__default.forwardRef(
3794
3886
  ({ className, size = "md", overlay, ...props }, ref) => {
3795
3887
  if (overlay) {
3796
3888
  return /* @__PURE__ */ jsx(
@@ -3832,21 +3924,21 @@ var init_Card = __esm({
3832
3924
  "bg-card",
3833
3925
  "border-[length:var(--border-width)] border-border",
3834
3926
  "shadow-elevation-card",
3835
- "transition-all duration-[var(--transition-normal)]",
3927
+ "transition-all duration-normal",
3836
3928
  "hover:shadow-elevation-dialog hover:translate-y-[var(--hover-translate-y)]"
3837
3929
  ].join(" "),
3838
3930
  bordered: [
3839
3931
  "bg-card",
3840
3932
  "border-[length:var(--border-width)] border-border",
3841
3933
  "shadow-elevation-card",
3842
- "transition-all duration-[var(--transition-normal)]",
3934
+ "transition-all duration-normal",
3843
3935
  "hover:shadow-elevation-dialog hover:translate-y-[var(--hover-translate-y)]"
3844
3936
  ].join(" "),
3845
3937
  elevated: [
3846
3938
  "bg-card",
3847
3939
  "border-[length:var(--border-width)] border-border",
3848
3940
  "shadow",
3849
- "transition-all duration-[var(--transition-normal)]",
3941
+ "transition-all duration-normal",
3850
3942
  "hover:shadow-elevation-dialog hover:translate-y-[var(--hover-translate-y)]"
3851
3943
  ].join(" "),
3852
3944
  // Interactive variant with theme-specific hover effects
@@ -3855,7 +3947,7 @@ var init_Card = __esm({
3855
3947
  "border-[length:var(--border-width)] border-border",
3856
3948
  "shadow",
3857
3949
  "cursor-pointer",
3858
- "transition-all duration-[var(--transition-normal)]",
3950
+ "transition-all duration-normal",
3859
3951
  "hover:shadow-elevation-dialog"
3860
3952
  ].join(" ")
3861
3953
  };
@@ -3880,7 +3972,7 @@ var init_Card = __esm({
3880
3972
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
3881
3973
  "tile-image-first": "p-0 overflow-hidden"
3882
3974
  };
3883
- Card = React81__default.forwardRef(
3975
+ Card = React82__default.forwardRef(
3884
3976
  ({
3885
3977
  className,
3886
3978
  variant = "bordered",
@@ -3906,7 +3998,8 @@ var init_Card = __esm({
3906
3998
  ref,
3907
3999
  className: cn(
3908
4000
  "rounded-container relative",
3909
- "transition-all duration-[var(--transition-normal)]",
4001
+ "transition-all duration-normal",
4002
+ "chrome-panel",
3910
4003
  variantStyles4[variant],
3911
4004
  paddingStyles2[padding],
3912
4005
  lookStyles2[look],
@@ -3928,9 +4021,9 @@ var init_Card = __esm({
3928
4021
  }
3929
4022
  );
3930
4023
  Card.displayName = "Card";
3931
- CardHeader = React81__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
4024
+ CardHeader = React82__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3932
4025
  CardHeader.displayName = "CardHeader";
3933
- CardTitle = React81__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4026
+ CardTitle = React82__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3934
4027
  "h3",
3935
4028
  {
3936
4029
  ref,
@@ -3943,11 +4036,11 @@ var init_Card = __esm({
3943
4036
  }
3944
4037
  ));
3945
4038
  CardTitle.displayName = "CardTitle";
3946
- CardContent = React81__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
4039
+ CardContent = React82__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3947
4040
  CardContent.displayName = "CardContent";
3948
4041
  CardBody = CardContent;
3949
4042
  CardBody.displayName = "CardBody";
3950
- CardFooter = React81__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4043
+ CardFooter = React82__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3951
4044
  "div",
3952
4045
  {
3953
4046
  ref,
@@ -4034,7 +4127,7 @@ var init_FilterPill = __esm({
4034
4127
  md: "w-3.5 h-3.5",
4035
4128
  lg: "w-4 h-4"
4036
4129
  };
4037
- FilterPill = React81__default.forwardRef(
4130
+ FilterPill = React82__default.forwardRef(
4038
4131
  ({
4039
4132
  className,
4040
4133
  variant = "default",
@@ -4163,8 +4256,8 @@ var init_Avatar = __esm({
4163
4256
  actionPayload
4164
4257
  }) => {
4165
4258
  const eventBus = useEventBus();
4166
- const [imgFailed, setImgFailed] = React81__default.useState(false);
4167
- React81__default.useEffect(() => {
4259
+ const [imgFailed, setImgFailed] = React82__default.useState(false);
4260
+ React82__default.useEffect(() => {
4168
4261
  setImgFailed(false);
4169
4262
  }, [src]);
4170
4263
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -4277,7 +4370,7 @@ var init_Center = __esm({
4277
4370
  as: Component = "div"
4278
4371
  }) => {
4279
4372
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
4280
- return React81__default.createElement(Component, {
4373
+ return React82__default.createElement(Component, {
4281
4374
  className: cn(
4282
4375
  inline ? "inline-flex" : "flex",
4283
4376
  horizontal && "justify-center",
@@ -4545,7 +4638,7 @@ var init_Radio = __esm({
4545
4638
  md: "w-2.5 h-2.5",
4546
4639
  lg: "w-3 h-3"
4547
4640
  };
4548
- Radio = React81__default.forwardRef(
4641
+ Radio = React82__default.forwardRef(
4549
4642
  ({
4550
4643
  label,
4551
4644
  helperText,
@@ -4562,12 +4655,12 @@ var init_Radio = __esm({
4562
4655
  onChange,
4563
4656
  ...props
4564
4657
  }, ref) => {
4565
- const reactId = React81__default.useId();
4658
+ const reactId = React82__default.useId();
4566
4659
  const baseId = id || `radio-${reactId}`;
4567
4660
  const hasError = !!error;
4568
4661
  const eventBus = useEventBus();
4569
- const [selected, setSelected] = React81__default.useState(value);
4570
- React81__default.useEffect(() => {
4662
+ const [selected, setSelected] = React82__default.useState(value);
4663
+ React82__default.useEffect(() => {
4571
4664
  if (value !== void 0) setSelected(value);
4572
4665
  }, [value]);
4573
4666
  const pick = (next, e) => {
@@ -4749,7 +4842,7 @@ var init_Switch = __esm({
4749
4842
  "components/core/atoms/Switch.tsx"() {
4750
4843
  "use client";
4751
4844
  init_cn();
4752
- Switch = React81.forwardRef(
4845
+ Switch = React82.forwardRef(
4753
4846
  ({
4754
4847
  checked,
4755
4848
  defaultChecked = false,
@@ -4760,10 +4853,10 @@ var init_Switch = __esm({
4760
4853
  name,
4761
4854
  className
4762
4855
  }, ref) => {
4763
- const [isChecked, setIsChecked] = React81.useState(
4856
+ const [isChecked, setIsChecked] = React82.useState(
4764
4857
  checked !== void 0 ? checked : defaultChecked
4765
4858
  );
4766
- React81.useEffect(() => {
4859
+ React82.useEffect(() => {
4767
4860
  if (checked !== void 0) {
4768
4861
  setIsChecked(checked);
4769
4862
  }
@@ -4794,7 +4887,7 @@ var init_Switch = __esm({
4794
4887
  // redefine --space-11 to 68px, which makes w-11 enormous and leaves
4795
4888
  // the thumb stuck near the left edge. The switch geometry must stay
4796
4889
  // proportional regardless of a theme's density scale.
4797
- "relative inline-flex h-[1.5rem] w-[2.75rem] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors",
4890
+ "relative inline-flex h-[1.5rem] w-[2.75rem] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors duration-fast",
4798
4891
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
4799
4892
  isChecked ? "bg-primary" : "bg-muted",
4800
4893
  disabled && "cursor-not-allowed opacity-50"
@@ -4803,7 +4896,7 @@ var init_Switch = __esm({
4803
4896
  "span",
4804
4897
  {
4805
4898
  className: cn(
4806
- "pointer-events-none block h-[1.25rem] w-[1.25rem] rounded-full bg-background shadow-lg ring-0 transition-transform",
4899
+ "pointer-events-none block h-[1.25rem] w-[1.25rem] rounded-full bg-background shadow-lg ring-0 transition-transform duration-fast",
4807
4900
  isChecked ? "translate-x-[1.25rem]" : "translate-x-0"
4808
4901
  )
4809
4902
  }
@@ -4926,7 +5019,7 @@ var init_Stack = __esm({
4926
5019
  };
4927
5020
  const isHorizontal = direction === "horizontal";
4928
5021
  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";
4929
- return React81__default.createElement(
5022
+ return React82__default.createElement(
4930
5023
  Component,
4931
5024
  {
4932
5025
  className: cn(
@@ -4971,7 +5064,7 @@ var init_TextHighlight = __esm({
4971
5064
  hoverEvent
4972
5065
  }) => {
4973
5066
  const eventBus = useEventBus();
4974
- const baseStyles = "cursor-pointer transition-all duration-150";
5067
+ const baseStyles = "cursor-pointer transition-all duration-fast";
4975
5068
  const typeStyles = {
4976
5069
  question: cn(
4977
5070
  // Blue border for questions
@@ -5126,7 +5219,7 @@ var Aside;
5126
5219
  var init_Aside = __esm({
5127
5220
  "components/core/atoms/Aside.tsx"() {
5128
5221
  init_cn();
5129
- Aside = React81__default.forwardRef(
5222
+ Aside = React82__default.forwardRef(
5130
5223
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
5131
5224
  );
5132
5225
  Aside.displayName = "Aside";
@@ -5205,9 +5298,9 @@ var init_LawReferenceTooltip = __esm({
5205
5298
  className
5206
5299
  }) => {
5207
5300
  const { t } = useTranslate();
5208
- const [isVisible, setIsVisible] = React81__default.useState(false);
5209
- const timeoutRef = React81__default.useRef(null);
5210
- const triggerRef = React81__default.useRef(null);
5301
+ const [isVisible, setIsVisible] = React82__default.useState(false);
5302
+ const timeoutRef = React82__default.useRef(null);
5303
+ const triggerRef = React82__default.useRef(null);
5211
5304
  const handleMouseEnter = () => {
5212
5305
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5213
5306
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -5218,7 +5311,7 @@ var init_LawReferenceTooltip = __esm({
5218
5311
  };
5219
5312
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
5220
5313
  const open = isVisible || revealed;
5221
- React81__default.useEffect(() => {
5314
+ React82__default.useEffect(() => {
5222
5315
  return () => {
5223
5316
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5224
5317
  };
@@ -5428,7 +5521,7 @@ var init_StatusDot = __esm({
5428
5521
  md: "w-2.5 h-2.5",
5429
5522
  lg: "w-3 h-3"
5430
5523
  };
5431
- StatusDot = React81__default.forwardRef(
5524
+ StatusDot = React82__default.forwardRef(
5432
5525
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
5433
5526
  return /* @__PURE__ */ jsx(
5434
5527
  "span",
@@ -5482,7 +5575,7 @@ var init_TrendIndicator = __esm({
5482
5575
  down: "trending-down",
5483
5576
  flat: "arrow-right"
5484
5577
  };
5485
- TrendIndicator = React81__default.forwardRef(
5578
+ TrendIndicator = React82__default.forwardRef(
5486
5579
  ({
5487
5580
  className,
5488
5581
  value,
@@ -5549,7 +5642,7 @@ var init_RangeSlider = __esm({
5549
5642
  md: "w-4 h-4",
5550
5643
  lg: "w-5 h-5"
5551
5644
  };
5552
- RangeSlider = React81__default.forwardRef(
5645
+ RangeSlider = React82__default.forwardRef(
5553
5646
  ({
5554
5647
  className,
5555
5648
  min = 0,
@@ -5692,7 +5785,7 @@ var init_RangeSlider = __esm({
5692
5785
  "border-2 border-primary",
5693
5786
  "shadow-sm",
5694
5787
  "pointer-events-none",
5695
- "transition-transform duration-100",
5788
+ "transition-transform duration-instant",
5696
5789
  isDragging && "scale-[var(--hover-scale)]",
5697
5790
  thumbSizes[size]
5698
5791
  ),
@@ -5742,6 +5835,18 @@ var init_RangeSlider = __esm({
5742
5835
  function easeOut(t) {
5743
5836
  return t * (2 - t);
5744
5837
  }
5838
+ function formatDisplay(value, format, decimals) {
5839
+ switch (format) {
5840
+ case "currency":
5841
+ return `$${value.toFixed(2)}`;
5842
+ case "percent":
5843
+ return `${Math.round(value)}%`;
5844
+ case "number":
5845
+ return value.toLocaleString();
5846
+ default:
5847
+ return value.toFixed(decimals);
5848
+ }
5849
+ }
5745
5850
  var AnimatedCounter;
5746
5851
  var init_AnimatedCounter = __esm({
5747
5852
  "components/marketing/atoms/AnimatedCounter.tsx"() {
@@ -5753,6 +5858,7 @@ var init_AnimatedCounter = __esm({
5753
5858
  duration = 600,
5754
5859
  prefix,
5755
5860
  suffix,
5861
+ format,
5756
5862
  className
5757
5863
  }) => {
5758
5864
  const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
@@ -5768,6 +5874,10 @@ var init_AnimatedCounter = __esm({
5768
5874
  setDisplayValue(to);
5769
5875
  return;
5770
5876
  }
5877
+ if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
5878
+ setDisplayValue(to);
5879
+ return;
5880
+ }
5771
5881
  const startTime = performance.now();
5772
5882
  const diff = to - from;
5773
5883
  function animate(currentTime) {
@@ -5789,7 +5899,7 @@ var init_AnimatedCounter = __esm({
5789
5899
  };
5790
5900
  }, [value, duration]);
5791
5901
  const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
5792
- const formattedValue = displayValue.toFixed(decimalPlaces);
5902
+ const formattedValue = formatDisplay(displayValue, format, decimalPlaces);
5793
5903
  return /* @__PURE__ */ jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
5794
5904
  prefix,
5795
5905
  formattedValue,
@@ -6108,7 +6218,7 @@ var init_ContentSection = __esm({
6108
6218
  md: "py-16",
6109
6219
  lg: "py-24"
6110
6220
  };
6111
- ContentSection = React81__default.forwardRef(
6221
+ ContentSection = React82__default.forwardRef(
6112
6222
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
6113
6223
  return /* @__PURE__ */ jsx(
6114
6224
  Box,
@@ -6642,7 +6752,7 @@ var init_AnimatedReveal = __esm({
6642
6752
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
6643
6753
  "none": {}
6644
6754
  };
6645
- AnimatedReveal = React81__default.forwardRef(
6755
+ AnimatedReveal = React82__default.forwardRef(
6646
6756
  ({
6647
6757
  trigger = "scroll",
6648
6758
  animation = "fade-up",
@@ -6802,7 +6912,7 @@ var init_AnimatedGraphic = __esm({
6802
6912
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6803
6913
  "use client";
6804
6914
  init_cn();
6805
- AnimatedGraphic = React81__default.forwardRef(
6915
+ AnimatedGraphic = React82__default.forwardRef(
6806
6916
  ({
6807
6917
  src,
6808
6918
  svgContent,
@@ -6825,7 +6935,7 @@ var init_AnimatedGraphic = __esm({
6825
6935
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6826
6936
  const resolvedSvg = svgContent ?? fetchedSvg;
6827
6937
  const prevAnimateRef = useRef(animate);
6828
- const setRef = React81__default.useCallback(
6938
+ const setRef = React82__default.useCallback(
6829
6939
  (node) => {
6830
6940
  containerRef.current = node;
6831
6941
  if (typeof ref === "function") ref(node);
@@ -7033,14 +7143,29 @@ function recordTransition(trace) {
7033
7143
  "pass"
7034
7144
  );
7035
7145
  } else {
7036
- const hasRenderUI = entry.effects.some((e) => e.type === "render-ui");
7037
- if (hasRenderUI) {
7038
- registerCheck(
7039
- checkId,
7040
- `INIT transition for "${entry.traitName}" missing fetch effect`,
7041
- "fail",
7042
- "Entity-bound render-ui without a fetch effect will show empty data"
7146
+ const rendersEntityData = entry.effects.some(
7147
+ (e) => e.type === "render-ui" && JSON.stringify(e.args).includes("@entity.")
7148
+ );
7149
+ if (rendersEntityData) {
7150
+ const siblingSeeds = getState().transitions.some(
7151
+ (t) => t.event === "INIT" && t.effects.some(
7152
+ (e) => e.type === "fetch" || e.type === "set" && typeof e.args[0] === "string" && e.args[0].startsWith("@entity.")
7153
+ )
7043
7154
  );
7155
+ if (siblingSeeds) {
7156
+ registerCheck(
7157
+ checkId,
7158
+ `INIT transition for "${entry.traitName}" has sibling entity-seed (shared entity)`,
7159
+ "pass"
7160
+ );
7161
+ } else {
7162
+ registerCheck(
7163
+ checkId,
7164
+ `INIT transition for "${entry.traitName}" missing fetch effect`,
7165
+ "fail",
7166
+ "Entity-bound render-ui without a fetch effect will show empty data"
7167
+ );
7168
+ }
7044
7169
  }
7045
7170
  }
7046
7171
  }
@@ -7538,9 +7663,9 @@ function ControlButton({
7538
7663
  className
7539
7664
  }) {
7540
7665
  const eventBus = useEventBus();
7541
- const [isPressed, setIsPressed] = React81.useState(false);
7666
+ const [isPressed, setIsPressed] = React82.useState(false);
7542
7667
  const actualPressed = pressed ?? isPressed;
7543
- const handlePointerDown = React81.useCallback(
7668
+ const handlePointerDown = React82.useCallback(
7544
7669
  (e) => {
7545
7670
  e.preventDefault();
7546
7671
  if (disabled) return;
@@ -7550,7 +7675,7 @@ function ControlButton({
7550
7675
  },
7551
7676
  [disabled, pressEvent, eventBus, onPress]
7552
7677
  );
7553
- const handlePointerUp = React81.useCallback(
7678
+ const handlePointerUp = React82.useCallback(
7554
7679
  (e) => {
7555
7680
  e.preventDefault();
7556
7681
  if (disabled) return;
@@ -7560,7 +7685,7 @@ function ControlButton({
7560
7685
  },
7561
7686
  [disabled, releaseEvent, eventBus, onRelease]
7562
7687
  );
7563
- const handlePointerLeave = React81.useCallback(
7688
+ const handlePointerLeave = React82.useCallback(
7564
7689
  (e) => {
7565
7690
  if (isPressed) {
7566
7691
  setIsPressed(false);
@@ -7818,8 +7943,8 @@ function ControlGrid({
7818
7943
  className
7819
7944
  }) {
7820
7945
  const eventBus = useEventBus();
7821
- const [active, setActive] = React81.useState(/* @__PURE__ */ new Set());
7822
- const handlePress = React81.useCallback(
7946
+ const [active, setActive] = React82.useState(/* @__PURE__ */ new Set());
7947
+ const handlePress = React82.useCallback(
7823
7948
  (id) => {
7824
7949
  setActive((prev) => new Set(prev).add(id));
7825
7950
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -7833,7 +7958,7 @@ function ControlGrid({
7833
7958
  },
7834
7959
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
7835
7960
  );
7836
- const handleRelease = React81.useCallback(
7961
+ const handleRelease = React82.useCallback(
7837
7962
  (id) => {
7838
7963
  setActive((prev) => {
7839
7964
  const next = new Set(prev);
@@ -8126,17 +8251,18 @@ function GameHud({
8126
8251
  const mid = Math.ceil(stats.length / 2);
8127
8252
  const leftStats = stats.slice(0, mid);
8128
8253
  const rightStats = stats.slice(mid);
8129
- const isTop = position === "top";
8130
8254
  return /* @__PURE__ */ jsxs(
8131
- Box,
8255
+ Card,
8132
8256
  {
8257
+ variant: "bordered",
8258
+ padding: "none",
8133
8259
  className: cn(
8134
- "flex items-center justify-between w-full",
8260
+ "flex items-center justify-between w-full rounded-none bg-card",
8135
8261
  "px-4 py-2 gap-4",
8136
- !transparent && (isTop ? "border-b border-border/40 bg-surface/90 backdrop-blur-sm" : "border-t border-border/40 bg-surface/90 backdrop-blur-sm"),
8137
- transparent && (isTop ? "border-b border-white/10 bg-black/40 backdrop-blur-sm" : "border-t border-white/10 bg-black/40 backdrop-blur-sm"),
8262
+ transparent && "backdrop-blur-sm",
8138
8263
  className
8139
8264
  ),
8265
+ style: transparent ? { backgroundColor: "color-mix(in srgb, var(--color-card) 40%, transparent)" } : void 0,
8140
8266
  children: [
8141
8267
  /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
8142
8268
  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)) })
@@ -8145,14 +8271,16 @@ function GameHud({
8145
8271
  );
8146
8272
  }
8147
8273
  return /* @__PURE__ */ jsx(
8148
- Box,
8274
+ Card,
8149
8275
  {
8150
- position: "relative",
8276
+ variant: "bordered",
8277
+ padding: "sm",
8151
8278
  className: cn(
8152
- "z-10 flex items-center gap-4 px-4 py-2",
8153
- transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
8279
+ "z-10 relative flex items-center gap-4 bg-card",
8280
+ transparent && "backdrop-blur-sm",
8154
8281
  className
8155
8282
  ),
8283
+ style: transparent ? { backgroundColor: "color-mix(in srgb, var(--color-card) 30%, transparent)" } : void 0,
8156
8284
  children: stats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i))
8157
8285
  }
8158
8286
  );
@@ -8162,6 +8290,7 @@ var init_GameHud = __esm({
8162
8290
  "components/game/molecules/GameHud.tsx"() {
8163
8291
  init_cn();
8164
8292
  init_Box();
8293
+ init_Card();
8165
8294
  init_StatBadge();
8166
8295
  positionMap = {
8167
8296
  corners: "inset-0 pointer-events-none"
@@ -8185,9 +8314,9 @@ function GameMenu({
8185
8314
  logo,
8186
8315
  className
8187
8316
  }) {
8188
- const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
8317
+ const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
8189
8318
  const eventBus = useEventBus();
8190
- const handleOptionClick = React81.useCallback(
8319
+ const handleOptionClick = React82.useCallback(
8191
8320
  (option) => {
8192
8321
  if (option.event) {
8193
8322
  eventBus.emit(`UI:${option.event}`, { option });
@@ -8206,39 +8335,48 @@ function GameMenu({
8206
8335
  {
8207
8336
  className: cn(
8208
8337
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
8338
+ !background && "bg-background",
8209
8339
  className
8210
8340
  ),
8211
- style: {
8212
- background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
8213
- },
8341
+ style: background ? { background } : void 0,
8214
8342
  children: [
8215
- /* @__PURE__ */ jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
8216
- logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
8217
- /* @__PURE__ */ jsx(
8218
- Typography,
8219
- {
8220
- variant: "h1",
8221
- className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
8222
- style: {
8223
- textShadow: "0 4px 12px rgba(0,0,0,0.5)"
8224
- },
8225
- children: title
8226
- }
8227
- ),
8228
- subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
8229
- ] }),
8230
- /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
8231
- ChoiceButton,
8343
+ /* @__PURE__ */ jsxs(
8344
+ Card,
8232
8345
  {
8233
- text: option.label,
8234
- index: index + 1,
8235
- disabled: option.disabled,
8236
- onClick: () => handleOptionClick(option),
8237
- className: "text-lg py-4 px-8"
8238
- },
8239
- index
8240
- )) }),
8241
- /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
8346
+ variant: "bordered",
8347
+ padding: "lg",
8348
+ className: "bg-card flex flex-col items-center max-w-md w-full",
8349
+ children: [
8350
+ /* @__PURE__ */ jsxs(Box, { className: "text-center mb-8 animate-fade-in", children: [
8351
+ logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
8352
+ /* @__PURE__ */ jsx(
8353
+ Typography,
8354
+ {
8355
+ variant: "h1",
8356
+ className: "text-4xl md:text-5xl font-bold text-foreground tracking-tight",
8357
+ style: {
8358
+ textShadow: "0 4px 12px rgba(0,0,0,0.5)"
8359
+ },
8360
+ children: title
8361
+ }
8362
+ ),
8363
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
8364
+ ] }),
8365
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
8366
+ ChoiceButton,
8367
+ {
8368
+ text: option.label,
8369
+ index: index + 1,
8370
+ disabled: option.disabled,
8371
+ onClick: () => handleOptionClick(option),
8372
+ className: "text-lg py-4 px-8"
8373
+ },
8374
+ index
8375
+ )) })
8376
+ ]
8377
+ }
8378
+ ),
8379
+ /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden -z-10", children: [
8242
8380
  /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
8243
8381
  /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
8244
8382
  ] })
@@ -8253,6 +8391,7 @@ var init_GameMenu = __esm({
8253
8391
  init_cn();
8254
8392
  init_useEventBus();
8255
8393
  init_Box();
8394
+ init_Card();
8256
8395
  init_Typography();
8257
8396
  init_GameIcon();
8258
8397
  init_ChoiceButton();
@@ -8413,7 +8552,7 @@ function StateGraph({
8413
8552
  }) {
8414
8553
  const eventBus = useEventBus();
8415
8554
  const nodes = states ?? [];
8416
- const positions = React81.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
8555
+ const positions = React82.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
8417
8556
  return /* @__PURE__ */ jsxs(
8418
8557
  Box,
8419
8558
  {
@@ -8484,8 +8623,8 @@ function MiniMap({
8484
8623
  tileAssets,
8485
8624
  unitAssets
8486
8625
  }) {
8487
- const canvasRef = React81.useRef(null);
8488
- const imgCacheRef = React81.useRef(/* @__PURE__ */ new Map());
8626
+ const canvasRef = React82.useRef(null);
8627
+ const imgCacheRef = React82.useRef(/* @__PURE__ */ new Map());
8489
8628
  function loadImg(url) {
8490
8629
  const cached = imgCacheRef.current.get(url);
8491
8630
  if (cached) return cached.complete ? cached : null;
@@ -8500,7 +8639,7 @@ function MiniMap({
8500
8639
  imgCacheRef.current.set(url, img);
8501
8640
  return null;
8502
8641
  }
8503
- React81.useEffect(() => {
8642
+ React82.useEffect(() => {
8504
8643
  const canvas = canvasRef.current;
8505
8644
  if (!canvas) return;
8506
8645
  const ctx = canvas.getContext("2d");
@@ -9476,6 +9615,10 @@ function Canvas2D({
9476
9615
  window.removeEventListener("keyup", onUp);
9477
9616
  };
9478
9617
  }, [keyMap, keyUpMap, eventBus]);
9618
+ useEffect(() => {
9619
+ if (!keyMap && !keyUpMap) return;
9620
+ canvasRef.current?.focus();
9621
+ }, [keyMap, keyUpMap]);
9479
9622
  if (error) {
9480
9623
  return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
9481
9624
  /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
@@ -9524,7 +9667,7 @@ function Canvas2D({
9524
9667
  onWheel: gestureHandlers.onWheel,
9525
9668
  onContextMenu: (e) => e.preventDefault(),
9526
9669
  className: "cursor-pointer touch-none",
9527
- tabIndex: isFree ? 0 : void 0,
9670
+ tabIndex: isFree || keyMap || keyUpMap ? 0 : void 0,
9528
9671
  style: {
9529
9672
  width: viewportSize.width,
9530
9673
  height: viewportSize.height
@@ -9811,7 +9954,7 @@ function LinearView({
9811
9954
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
9812
9955
  const isDone = i < currentIdx;
9813
9956
  const isCurrent = i === currentIdx;
9814
- return /* @__PURE__ */ jsxs(React81__default.Fragment, { children: [
9957
+ return /* @__PURE__ */ jsxs(React82__default.Fragment, { children: [
9815
9958
  i > 0 && /* @__PURE__ */ jsx(
9816
9959
  Typography,
9817
9960
  {
@@ -10346,7 +10489,7 @@ function SequenceBar({
10346
10489
  else onSlotRemove?.(index);
10347
10490
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
10348
10491
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
10349
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React81__default.Fragment, { children: [
10492
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React82__default.Fragment, { children: [
10350
10493
  i > 0 && /* @__PURE__ */ jsx(
10351
10494
  Typography,
10352
10495
  {
@@ -10433,6 +10576,7 @@ var init_GameShell = __esm({
10433
10576
  "components/game/templates/GameShell.tsx"() {
10434
10577
  init_cn();
10435
10578
  init_Box();
10579
+ init_Card();
10436
10580
  init_Typography();
10437
10581
  init_AtlasImage();
10438
10582
  FONT_BASE = "https://almadar-kflow-assets.web.app/shared/_shared/kenney-fonts/fonts";
@@ -10461,13 +10605,14 @@ var init_GameShell = __esm({
10461
10605
  showTopBar = true,
10462
10606
  children,
10463
10607
  backgroundAsset,
10464
- hudBackgroundAsset,
10465
- fontFamily = "future"
10608
+ fontFamily = "future",
10609
+ "data-theme": dataTheme
10466
10610
  }) => {
10467
10611
  const font = GAME_FONTS[fontFamily] ?? fontFamily;
10468
10612
  return /* @__PURE__ */ jsxs(
10469
10613
  Box,
10470
10614
  {
10615
+ "data-theme": dataTheme || void 0,
10471
10616
  className: cn("game-shell", className),
10472
10617
  style: {
10473
10618
  position: "relative",
@@ -10475,7 +10620,7 @@ var init_GameShell = __esm({
10475
10620
  height: "100vh",
10476
10621
  overflow: "hidden",
10477
10622
  background: "var(--color-background, #0a0a0f)",
10478
- color: "var(--color-text, #e0e0e0)",
10623
+ color: "var(--color-foreground, #e0e0e0)",
10479
10624
  fontFamily: `'${font}', system-ui, sans-serif`
10480
10625
  },
10481
10626
  children: [
@@ -10507,19 +10652,12 @@ var init_GameShell = __esm({
10507
10652
  },
10508
10653
  children: [
10509
10654
  showTopBar && /* @__PURE__ */ jsx(
10510
- AtlasPanel,
10655
+ Card,
10511
10656
  {
10512
- asset: hudBackgroundAsset,
10513
- borderSlice: 12,
10514
- borderWidth: 10,
10515
- className: "game-shell__title pointer-events-auto",
10516
- style: {
10517
- padding: "6px 16px",
10518
- background: hudBackgroundAsset ? void 0 : "rgba(18, 18, 31, 0.85)",
10519
- borderRadius: hudBackgroundAsset ? void 0 : 10,
10520
- boxShadow: "0 4px 14px rgba(0,0,0,0.45)",
10521
- flexShrink: 0
10522
- },
10657
+ variant: "bordered",
10658
+ padding: "none",
10659
+ className: "game-shell__title bg-card pointer-events-auto",
10660
+ style: { padding: "6px 16px", flexShrink: 0 },
10523
10661
  children: /* @__PURE__ */ jsx(
10524
10662
  Typography,
10525
10663
  {
@@ -11000,7 +11138,7 @@ var init_ErrorBoundary = __esm({
11000
11138
  }
11001
11139
  );
11002
11140
  };
11003
- ErrorBoundary = class extends React81__default.Component {
11141
+ ErrorBoundary = class extends React82__default.Component {
11004
11142
  constructor(props) {
11005
11143
  super(props);
11006
11144
  __publicField(this, "reset", () => {
@@ -11267,7 +11405,7 @@ var init_Container = __esm({
11267
11405
  as: Component = "div"
11268
11406
  }) => {
11269
11407
  const resolvedSize = maxWidth ?? size ?? "lg";
11270
- return React81__default.createElement(
11408
+ return React82__default.createElement(
11271
11409
  Component,
11272
11410
  {
11273
11411
  className: cn(
@@ -13775,7 +13913,8 @@ var init_LoadingState = __esm({
13775
13913
  LoadingState = ({
13776
13914
  title,
13777
13915
  message,
13778
- className
13916
+ className,
13917
+ fullPage = false
13779
13918
  }) => {
13780
13919
  const { t } = useTranslate();
13781
13920
  const displayMessage = message ?? t("common.loading");
@@ -13784,7 +13923,8 @@ var init_LoadingState = __esm({
13784
13923
  {
13785
13924
  align: "center",
13786
13925
  className: cn(
13787
- "justify-center py-12",
13926
+ "justify-center",
13927
+ fullPage ? "fixed inset-0 z-[1000] py-12 bg-background/80 backdrop-blur-sm animate-overlay-in" : "py-12",
13788
13928
  className
13789
13929
  ),
13790
13930
  children: [
@@ -14092,7 +14232,7 @@ var init_CodeBlock = __esm({
14092
14232
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
14093
14233
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
14094
14234
  HIDDEN_LINE_NUMBERS = { display: "none" };
14095
- CodeBlock = React81__default.memo(
14235
+ CodeBlock = React82__default.memo(
14096
14236
  ({
14097
14237
  code: rawCode,
14098
14238
  language = "text",
@@ -14679,7 +14819,7 @@ var init_MarkdownContent = __esm({
14679
14819
  init_Box();
14680
14820
  init_CodeBlock();
14681
14821
  init_cn();
14682
- MarkdownContent = React81__default.memo(
14822
+ MarkdownContent = React82__default.memo(
14683
14823
  ({ content, direction = "ltr", className }) => {
14684
14824
  const { t: _t } = useTranslate();
14685
14825
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -15592,7 +15732,7 @@ var init_StateMachineView = __esm({
15592
15732
  Box,
15593
15733
  {
15594
15734
  className: cn(
15595
- "fixed z-50 animate-in fade-in-0 zoom-in-95 duration-150",
15735
+ "fixed z-50 animate-in fade-in-0 zoom-in-95 duration-fast",
15596
15736
  tooltip.pinned ? "pointer-events-auto" : "pointer-events-none"
15597
15737
  ),
15598
15738
  style: {
@@ -15956,7 +16096,7 @@ var init_StateMachineView = __esm({
15956
16096
  style: { top: title ? 30 : 0 },
15957
16097
  children: [
15958
16098
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
15959
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React81__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
16099
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React82__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
15960
16100
  StateNode2,
15961
16101
  {
15962
16102
  state,
@@ -16936,7 +17076,7 @@ var init_BookCoverPage = __esm({
16936
17076
  size: "lg",
16937
17077
  action: "BOOK_START",
16938
17078
  className: "mt-8",
16939
- children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: t("book.startReading") })
17079
+ children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "inherit", children: t("book.startReading") })
16940
17080
  }
16941
17081
  )
16942
17082
  ]
@@ -17995,6 +18135,129 @@ var init_Breadcrumb = __esm({
17995
18135
  Breadcrumb.displayName = "Breadcrumb";
17996
18136
  }
17997
18137
  });
18138
+ function useSafeEventBus2() {
18139
+ try {
18140
+ return useEventBus();
18141
+ } catch {
18142
+ return { emit: () => {
18143
+ }, on: () => () => {
18144
+ }, once: () => {
18145
+ } };
18146
+ }
18147
+ }
18148
+ var log7, lookStyles4, ButtonGroup;
18149
+ var init_ButtonGroup = __esm({
18150
+ "components/core/molecules/ButtonGroup.tsx"() {
18151
+ "use client";
18152
+ init_cn();
18153
+ init_atoms();
18154
+ init_useEventBus();
18155
+ log7 = createLogger("almadar:ui:button-group");
18156
+ lookStyles4 = {
18157
+ "right-aligned-buttons": "",
18158
+ "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
18159
+ "inline-row": "gap-2 inline-flex",
18160
+ "dropdown-menu": "[&>button:not(:first-child)]:hidden",
18161
+ "command-palette-trigger": "[&>button:not(:first-child)]:hidden"
18162
+ };
18163
+ ButtonGroup = ({
18164
+ children,
18165
+ primary,
18166
+ secondary,
18167
+ variant = "default",
18168
+ orientation = "horizontal",
18169
+ className,
18170
+ // Filter-group pattern props (entity and filters are used for schema-driven filtering)
18171
+ entity: _entity,
18172
+ filters,
18173
+ look = "right-aligned-buttons"
18174
+ }) => {
18175
+ const eventBus = useSafeEventBus2();
18176
+ const variantClasses2 = {
18177
+ default: "gap-0",
18178
+ segmented: "gap-0 [&>button]:rounded-none [&>button:first-child]:rounded-l-lg [&>button:last-child]:rounded-r-lg [&>button:not(:first-child)]:border-l-0",
18179
+ toggle: "gap-0 [&>button]:rounded-none [&>button:first-child]:rounded-l-lg [&>button:last-child]:rounded-r-lg [&>button:not(:first-child)]:border-l-0"
18180
+ };
18181
+ const orientationClasses = {
18182
+ horizontal: "flex-row",
18183
+ vertical: "flex-col [&>button:first-child]:rounded-t-lg [&>button:last-child]:rounded-b-lg [&>button:not(:first-child)]:border-t-0 [&>button:not(:first-child)]:border-l"
18184
+ };
18185
+ const handleActionClick = (action) => {
18186
+ if (action.event) {
18187
+ eventBus.emit("UI:DISPATCH", { event: action.event });
18188
+ }
18189
+ if (action.navigatesTo) {
18190
+ eventBus.emit("UI:NAVIGATE", { url: action.navigatesTo });
18191
+ }
18192
+ };
18193
+ const renderFormActions = () => {
18194
+ const buttons = [];
18195
+ if (secondary) {
18196
+ secondary.forEach((action, index) => {
18197
+ buttons.push(
18198
+ /* @__PURE__ */ jsx(
18199
+ Button,
18200
+ {
18201
+ type: action.actionType === "submit" ? "submit" : "button",
18202
+ variant: action.variant || "ghost",
18203
+ onClick: () => handleActionClick(action),
18204
+ children: action.label
18205
+ },
18206
+ `secondary-${index}`
18207
+ )
18208
+ );
18209
+ });
18210
+ }
18211
+ if (primary) {
18212
+ const isSubmit = primary.actionType === "submit";
18213
+ buttons.push(
18214
+ /* @__PURE__ */ jsx(
18215
+ Button,
18216
+ {
18217
+ type: isSubmit ? "submit" : "button",
18218
+ variant: primary.variant || "primary",
18219
+ onClick: () => handleActionClick(primary),
18220
+ "data-testid": isSubmit ? "form-submit" : void 0,
18221
+ children: primary.label
18222
+ },
18223
+ "primary"
18224
+ )
18225
+ );
18226
+ }
18227
+ return buttons;
18228
+ };
18229
+ const renderFilters = () => {
18230
+ if (!filters || filters.length === 0) return null;
18231
+ return filters.map((filter, index) => /* @__PURE__ */ jsx(
18232
+ Button,
18233
+ {
18234
+ variant: "ghost",
18235
+ onClick: () => {
18236
+ log7.debug("Filter clicked", { field: filter.field });
18237
+ },
18238
+ children: filter.label
18239
+ },
18240
+ `filter-${filter.field}-${index}`
18241
+ ));
18242
+ };
18243
+ return /* @__PURE__ */ jsx(
18244
+ "div",
18245
+ {
18246
+ className: cn(
18247
+ "inline-flex gap-2",
18248
+ variantClasses2[variant],
18249
+ orientationClasses[orientation],
18250
+ lookStyles4[look],
18251
+ className
18252
+ ),
18253
+ role: "group",
18254
+ children: children || renderFilters() || renderFormActions()
18255
+ }
18256
+ );
18257
+ };
18258
+ ButtonGroup.displayName = "ButtonGroup";
18259
+ }
18260
+ });
17998
18261
  function dayWindowForViewport(width) {
17999
18262
  if (width <= 640) return 1;
18000
18263
  if (width <= 1024) return 3;
@@ -18737,7 +19000,7 @@ var init_CardGrid = __esm({
18737
19000
  CardGrid.displayName = "CardGrid";
18738
19001
  }
18739
19002
  });
18740
- function useSafeEventBus2() {
19003
+ function useSafeEventBus3() {
18741
19004
  try {
18742
19005
  return useEventBus();
18743
19006
  } catch {
@@ -18773,7 +19036,7 @@ var init_Carousel = __esm({
18773
19036
  const [activeIndex, setActiveIndex] = useState(0);
18774
19037
  const scrollRef = useRef(null);
18775
19038
  const autoPlayRef = useRef(null);
18776
- const eventBus = useSafeEventBus2();
19039
+ const eventBus = useSafeEventBus3();
18777
19040
  const { t } = useTranslate();
18778
19041
  const safeItems = items ?? [];
18779
19042
  const totalSlides = safeItems.length;
@@ -19135,7 +19398,7 @@ var init_Chart = __esm({
19135
19398
  return /* @__PURE__ */ jsx(
19136
19399
  Box,
19137
19400
  {
19138
- className: "h-full rounded-r-sm transition-all duration-500 ease-out min-w-[2px] cursor-pointer hover:opacity-80",
19401
+ className: "h-full rounded-r-sm transition-all duration-slow ease-standard min-w-[2px] cursor-pointer hover:opacity-80",
19139
19402
  style: {
19140
19403
  width: `${ratio}%`,
19141
19404
  backgroundColor: color
@@ -19181,8 +19444,9 @@ var init_Chart = __esm({
19181
19444
  align: "center",
19182
19445
  flex: true,
19183
19446
  className: "min-w-0",
19447
+ style: { height: "100%" },
19184
19448
  children: [
19185
- /* @__PURE__ */ jsx(HStack, { gap: histogram ? "none" : "xs", align: "end", className: "w-full", style: { height: "100%" }, children: series.map((s, sIdx) => {
19449
+ /* @__PURE__ */ jsx(HStack, { gap: histogram ? "none" : "xs", align: "end", justify: histogram ? void 0 : "center", className: "w-full flex-1 min-h-0", children: series.map((s, sIdx) => {
19186
19450
  const value = valueAt(s, label);
19187
19451
  const barHeight = value / maxValue * 100;
19188
19452
  const color = seriesColor(s, sIdx);
@@ -19190,11 +19454,13 @@ var init_Chart = __esm({
19190
19454
  Box,
19191
19455
  {
19192
19456
  className: cn(
19193
- "rounded-t-sm transition-all duration-500 ease-out min-h-[4px] cursor-pointer hover:opacity-80",
19457
+ "rounded-t-sm transition-all duration-slow ease-standard min-h-[4px] cursor-pointer hover:opacity-80",
19194
19458
  histogram ? "flex-1 mx-0" : "flex-1"
19195
19459
  ),
19196
19460
  style: {
19197
19461
  height: `${barHeight}%`,
19462
+ // Cap width so a lone category doesn't paint the whole plot as one solid block; narrow columns are unaffected (flex-1 binds first).
19463
+ ...!histogram && { maxWidth: 72 },
19198
19464
  backgroundColor: color
19199
19465
  },
19200
19466
  onClick: () => onPointClick?.(
@@ -19229,15 +19495,16 @@ var init_Chart = __esm({
19229
19495
  align: "center",
19230
19496
  flex: true,
19231
19497
  className: "min-w-0",
19498
+ style: { height: "100%" },
19232
19499
  children: [
19233
- /* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full", style: { height: "100%" }, justify: "end", children: series.map((s, sIdx) => {
19500
+ /* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full flex-1 min-h-0", justify: "end", children: series.map((s, sIdx) => {
19234
19501
  const value = valueAt(s, label);
19235
19502
  const ratio = stack === "normalize" ? total === 0 ? 0 : value / total * 100 : value / maxValue * 100;
19236
19503
  const color = seriesColor(s, sIdx);
19237
19504
  return /* @__PURE__ */ jsx(
19238
19505
  Box,
19239
19506
  {
19240
- className: "w-full transition-all duration-500 ease-out cursor-pointer hover:opacity-80",
19507
+ className: "w-full transition-all duration-slow ease-standard cursor-pointer hover:opacity-80",
19241
19508
  style: {
19242
19509
  height: `${ratio}%`,
19243
19510
  backgroundColor: color
@@ -19275,6 +19542,7 @@ var init_Chart = __esm({
19275
19542
  const innerRadius = donut ? radius * 0.6 : 0;
19276
19543
  const center = size / 2;
19277
19544
  const segments = useMemo(() => {
19545
+ if (!Number.isFinite(total) || total <= 0) return [];
19278
19546
  let currentAngle = -Math.PI / 2;
19279
19547
  return data.map((point, idx) => {
19280
19548
  const angle = point.value / total * 2 * Math.PI;
@@ -19286,13 +19554,25 @@ var init_Chart = __esm({
19286
19554
  const y1 = center + radius * Math.sin(startAngle);
19287
19555
  const x2 = center + radius * Math.cos(endAngle);
19288
19556
  const y2 = center + radius * Math.sin(endAngle);
19557
+ const fullCircle = angle >= 2 * Math.PI - 1e-9;
19558
+ const midAngle = startAngle + angle / 2;
19559
+ const xm = center + radius * Math.cos(midAngle);
19560
+ const ym = center + radius * Math.sin(midAngle);
19289
19561
  let d;
19290
19562
  if (innerRadius > 0) {
19291
19563
  const ix1 = center + innerRadius * Math.cos(startAngle);
19292
19564
  const iy1 = center + innerRadius * Math.sin(startAngle);
19293
19565
  const ix2 = center + innerRadius * Math.cos(endAngle);
19294
19566
  const iy2 = center + innerRadius * Math.sin(endAngle);
19295
- d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${ix1} ${iy1} Z`;
19567
+ if (fullCircle) {
19568
+ const ixm = center + innerRadius * Math.cos(midAngle);
19569
+ const iym = center + innerRadius * Math.sin(midAngle);
19570
+ d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerRadius} ${innerRadius} 0 1 0 ${ixm} ${iym} A ${innerRadius} ${innerRadius} 0 1 0 ${ix1} ${iy1} Z`;
19571
+ } else {
19572
+ d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${ix1} ${iy1} Z`;
19573
+ }
19574
+ } else if (fullCircle) {
19575
+ d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} Z`;
19296
19576
  } else {
19297
19577
  d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`;
19298
19578
  }
@@ -19314,7 +19594,7 @@ var init_Chart = __esm({
19314
19594
  fill: seg.color,
19315
19595
  stroke: "var(--color-card)",
19316
19596
  strokeWidth: "2",
19317
- className: "transition-opacity duration-200 hover:opacity-80 cursor-pointer",
19597
+ className: "transition-opacity duration-fast hover:opacity-80 cursor-pointer",
19318
19598
  onClick: () => onPointClick?.(
19319
19599
  { label: seg.label, value: seg.value, color: seg.color },
19320
19600
  "default"
@@ -21513,8 +21793,8 @@ var init_Menu = __esm({
21513
21793
  "bottom-end": "bottom-start"
21514
21794
  };
21515
21795
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
21516
- const triggerChild = React81__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
21517
- const triggerElement = React81__default.cloneElement(
21796
+ const triggerChild = React82__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
21797
+ const triggerElement = React82__default.cloneElement(
21518
21798
  triggerChild,
21519
21799
  {
21520
21800
  ref: triggerRef,
@@ -21609,14 +21889,14 @@ function useDataDnd(args) {
21609
21889
  const isZone = Boolean(dragGroup || accepts || sortable);
21610
21890
  const enabled = isZone || Boolean(dndRoot);
21611
21891
  const eventBus = useEventBus();
21612
- const parentRoot = React81__default.useContext(RootCtx);
21892
+ const parentRoot = React82__default.useContext(RootCtx);
21613
21893
  const isRoot = enabled && parentRoot === null;
21614
- const zoneId = React81__default.useId();
21894
+ const zoneId = React82__default.useId();
21615
21895
  const ownGroup = dragGroup ?? accepts ?? zoneId;
21616
- const [optimisticOrders, setOptimisticOrders] = React81__default.useState(() => /* @__PURE__ */ new Map());
21617
- const optimisticOrdersRef = React81__default.useRef(optimisticOrders);
21896
+ const [optimisticOrders, setOptimisticOrders] = React82__default.useState(() => /* @__PURE__ */ new Map());
21897
+ const optimisticOrdersRef = React82__default.useRef(optimisticOrders);
21618
21898
  optimisticOrdersRef.current = optimisticOrders;
21619
- const clearOptimisticOrder = React81__default.useCallback((group) => {
21899
+ const clearOptimisticOrder = React82__default.useCallback((group) => {
21620
21900
  setOptimisticOrders((prev) => {
21621
21901
  if (!prev.has(group)) return prev;
21622
21902
  const next = new Map(prev);
@@ -21641,7 +21921,7 @@ function useDataDnd(args) {
21641
21921
  const raw = it[dndItemIdField];
21642
21922
  return raw != null ? String(raw) : `__idx_${idx}`;
21643
21923
  }).join("|");
21644
- const itemIds = React81__default.useMemo(
21924
+ const itemIds = React82__default.useMemo(
21645
21925
  () => orderedItems.map((it, idx) => {
21646
21926
  const raw = it[dndItemIdField];
21647
21927
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -21652,7 +21932,7 @@ function useDataDnd(args) {
21652
21932
  const raw = it[dndItemIdField];
21653
21933
  return raw != null ? String(raw) : `__${idx}`;
21654
21934
  }).join("|");
21655
- React81__default.useEffect(() => {
21935
+ React82__default.useEffect(() => {
21656
21936
  const root = isRoot ? null : parentRoot;
21657
21937
  if (root) {
21658
21938
  root.clearOptimisticOrder(ownGroup);
@@ -21660,20 +21940,20 @@ function useDataDnd(args) {
21660
21940
  clearOptimisticOrder(ownGroup);
21661
21941
  }
21662
21942
  }, [itemsContentSig, ownGroup]);
21663
- const zonesRef = React81__default.useRef(/* @__PURE__ */ new Map());
21664
- const registerZone = React81__default.useCallback((zoneId2, meta2) => {
21943
+ const zonesRef = React82__default.useRef(/* @__PURE__ */ new Map());
21944
+ const registerZone = React82__default.useCallback((zoneId2, meta2) => {
21665
21945
  zonesRef.current.set(zoneId2, meta2);
21666
21946
  }, []);
21667
- const unregisterZone = React81__default.useCallback((zoneId2) => {
21947
+ const unregisterZone = React82__default.useCallback((zoneId2) => {
21668
21948
  zonesRef.current.delete(zoneId2);
21669
21949
  }, []);
21670
- const [activeDrag, setActiveDrag] = React81__default.useState(null);
21671
- const [overZoneGroup, setOverZoneGroup] = React81__default.useState(null);
21672
- const meta = React81__default.useMemo(
21950
+ const [activeDrag, setActiveDrag] = React82__default.useState(null);
21951
+ const [overZoneGroup, setOverZoneGroup] = React82__default.useState(null);
21952
+ const meta = React82__default.useMemo(
21673
21953
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
21674
21954
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
21675
21955
  );
21676
- React81__default.useEffect(() => {
21956
+ React82__default.useEffect(() => {
21677
21957
  const target = isRoot ? null : parentRoot;
21678
21958
  if (!target) {
21679
21959
  zonesRef.current.set(zoneId, meta);
@@ -21692,7 +21972,7 @@ function useDataDnd(args) {
21692
21972
  }, [parentRoot, isRoot, zoneId, meta]);
21693
21973
  const sensors = useAlmadarDndSensors(true);
21694
21974
  const collisionDetection = almadarDndCollisionDetection;
21695
- const findZoneByItem = React81__default.useCallback(
21975
+ const findZoneByItem = React82__default.useCallback(
21696
21976
  (id) => {
21697
21977
  for (const z of zonesRef.current.values()) {
21698
21978
  if (z.itemIds.includes(id)) return z;
@@ -21701,7 +21981,7 @@ function useDataDnd(args) {
21701
21981
  },
21702
21982
  []
21703
21983
  );
21704
- React81__default.useCallback(
21984
+ React82__default.useCallback(
21705
21985
  (group) => {
21706
21986
  for (const z of zonesRef.current.values()) {
21707
21987
  if (z.group === group) return z;
@@ -21710,7 +21990,7 @@ function useDataDnd(args) {
21710
21990
  },
21711
21991
  []
21712
21992
  );
21713
- const handleDragEnd = React81__default.useCallback(
21993
+ const handleDragEnd = React82__default.useCallback(
21714
21994
  (event) => {
21715
21995
  const { active, over } = event;
21716
21996
  const activeIdStr = String(active.id);
@@ -21801,8 +22081,8 @@ function useDataDnd(args) {
21801
22081
  },
21802
22082
  [eventBus]
21803
22083
  );
21804
- const sortableData = React81__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
21805
- const SortableItem = React81__default.useCallback(
22084
+ const sortableData = React82__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
22085
+ const SortableItem = React82__default.useCallback(
21806
22086
  ({ id, children }) => {
21807
22087
  const {
21808
22088
  attributes,
@@ -21842,7 +22122,7 @@ function useDataDnd(args) {
21842
22122
  id: droppableId,
21843
22123
  data: sortableData
21844
22124
  });
21845
- const ctx = React81__default.useContext(RootCtx);
22125
+ const ctx = React82__default.useContext(RootCtx);
21846
22126
  const activeDrag2 = ctx?.activeDrag ?? null;
21847
22127
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
21848
22128
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -21857,7 +22137,7 @@ function useDataDnd(args) {
21857
22137
  showForeignPlaceholder,
21858
22138
  ctxAvailable: ctx != null
21859
22139
  });
21860
- React81__default.useEffect(() => {
22140
+ React82__default.useEffect(() => {
21861
22141
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
21862
22142
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
21863
22143
  return /* @__PURE__ */ jsx(
@@ -21871,11 +22151,11 @@ function useDataDnd(args) {
21871
22151
  }
21872
22152
  );
21873
22153
  };
21874
- const rootContextValue = React81__default.useMemo(
22154
+ const rootContextValue = React82__default.useMemo(
21875
22155
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
21876
22156
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
21877
22157
  );
21878
- const handleDragStart = React81__default.useCallback((event) => {
22158
+ const handleDragStart = React82__default.useCallback((event) => {
21879
22159
  const sourceZone = findZoneByItem(event.active.id);
21880
22160
  const rect = event.active.rect.current.initial;
21881
22161
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -21894,7 +22174,7 @@ function useDataDnd(args) {
21894
22174
  isRoot
21895
22175
  });
21896
22176
  }, [findZoneByItem, isRoot, zoneId]);
21897
- const handleDragOver = React81__default.useCallback((event) => {
22177
+ const handleDragOver = React82__default.useCallback((event) => {
21898
22178
  const { active, over } = event;
21899
22179
  const overData = over?.data?.current;
21900
22180
  const overGroup = overData?.dndGroup ?? null;
@@ -21964,7 +22244,7 @@ function useDataDnd(args) {
21964
22244
  return next;
21965
22245
  });
21966
22246
  }, []);
21967
- const handleDragCancel = React81__default.useCallback((event) => {
22247
+ const handleDragCancel = React82__default.useCallback((event) => {
21968
22248
  setActiveDrag(null);
21969
22249
  setOverZoneGroup(null);
21970
22250
  dndLog.warn("dragCancel", {
@@ -21972,12 +22252,12 @@ function useDataDnd(args) {
21972
22252
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
21973
22253
  });
21974
22254
  }, []);
21975
- const handleDragEndWithCleanup = React81__default.useCallback((event) => {
22255
+ const handleDragEndWithCleanup = React82__default.useCallback((event) => {
21976
22256
  handleDragEnd(event);
21977
22257
  setActiveDrag(null);
21978
22258
  setOverZoneGroup(null);
21979
22259
  }, [handleDragEnd]);
21980
- const wrapContainer = React81__default.useCallback(
22260
+ const wrapContainer = React82__default.useCallback(
21981
22261
  (children) => {
21982
22262
  if (!enabled) return children;
21983
22263
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -22031,7 +22311,7 @@ var init_useDataDnd = __esm({
22031
22311
  init_useAlmadarDndCollision();
22032
22312
  init_Box();
22033
22313
  dndLog = createLogger("almadar:ui:dnd");
22034
- RootCtx = React81__default.createContext(null);
22314
+ RootCtx = React82__default.createContext(null);
22035
22315
  }
22036
22316
  });
22037
22317
  function renderIconInput(icon, props) {
@@ -22228,7 +22508,7 @@ function DataGrid({
22228
22508
  /* @__PURE__ */ jsx(
22229
22509
  Box,
22230
22510
  {
22231
- className: cn("grid", gapStyles5[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles4[look], className),
22511
+ className: cn("grid", gapStyles5[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles5[look], className),
22232
22512
  style: scrollX ? { gridAutoFlow: "column", gridAutoColumns: `minmax(${minCardWidth}px, 1fr)` } : gridTemplateColumns ? { gridTemplateColumns } : void 0,
22233
22513
  children: data.map((item, index) => {
22234
22514
  const itemData = item;
@@ -22305,10 +22585,10 @@ function DataGrid({
22305
22585
  ] }),
22306
22586
  badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
22307
22587
  const val = getNestedValue(itemData, field.name);
22308
- if (val === void 0 || val === null) return null;
22588
+ if (val === void 0 || val === null || val === "") return null;
22309
22589
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
22310
22590
  field.icon && renderIconInput(field.icon, { size: "xs" }),
22311
- /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
22591
+ /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: formatValue(val, field.format) })
22312
22592
  ] }, field.name);
22313
22593
  }) })
22314
22594
  ] }),
@@ -22423,7 +22703,7 @@ function DataGrid({
22423
22703
  ] })
22424
22704
  );
22425
22705
  }
22426
- var dataGridLog, BADGE_VARIANTS, gapStyles5, lookStyles4;
22706
+ var dataGridLog, BADGE_VARIANTS, gapStyles5, lookStyles5;
22427
22707
  var init_DataGrid = __esm({
22428
22708
  "components/core/molecules/DataGrid.tsx"() {
22429
22709
  "use client";
@@ -22458,7 +22738,7 @@ var init_DataGrid = __esm({
22458
22738
  lg: "gap-6",
22459
22739
  xl: "gap-8"
22460
22740
  };
22461
- lookStyles4 = {
22741
+ lookStyles5 = {
22462
22742
  dense: "gap-2 [&>*]:p-card-sm",
22463
22743
  spacious: "gap-8 [&>*]:p-card-lg",
22464
22744
  striped: "[&>*:nth-child(even)]:bg-muted/30",
@@ -22558,7 +22838,7 @@ function DataList({
22558
22838
  }) {
22559
22839
  const eventBus = useEventBus();
22560
22840
  const { t } = useTranslate();
22561
- const [visibleCount, setVisibleCount] = React81__default.useState(pageSize || Infinity);
22841
+ const [visibleCount, setVisibleCount] = React82__default.useState(pageSize || Infinity);
22562
22842
  const fieldDefs = fields ?? columns ?? [];
22563
22843
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
22564
22844
  const dnd = useDataDnd({
@@ -22577,7 +22857,7 @@ function DataList({
22577
22857
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
22578
22858
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
22579
22859
  const hasRenderProp = typeof children === "function";
22580
- React81__default.useEffect(() => {
22860
+ React82__default.useEffect(() => {
22581
22861
  const renderItemTypeOf = typeof schemaRenderItem;
22582
22862
  const childrenTypeOf = typeof children;
22583
22863
  if (data.length > 0 && !hasRenderProp) {
@@ -22681,7 +22961,7 @@ function DataList({
22681
22961
  const items2 = [...data];
22682
22962
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
22683
22963
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
22684
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React81__default.Fragment, { children: [
22964
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React82__default.Fragment, { children: [
22685
22965
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
22686
22966
  group.items.map((itemData, index) => {
22687
22967
  const id = itemData.id || `${gi}-${index}`;
@@ -22822,7 +23102,7 @@ function DataList({
22822
23102
  className
22823
23103
  ),
22824
23104
  children: [
22825
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React81__default.Fragment, { children: [
23105
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React82__default.Fragment, { children: [
22826
23106
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
22827
23107
  group.items.map(
22828
23108
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -22907,7 +23187,7 @@ var init_FormSection = __esm({
22907
23187
  columns = 1,
22908
23188
  className
22909
23189
  }) => {
22910
- const [collapsed, setCollapsed] = React81__default.useState(defaultCollapsed);
23190
+ const [collapsed, setCollapsed] = React82__default.useState(defaultCollapsed);
22911
23191
  const { t } = useTranslate();
22912
23192
  const eventBus = useEventBus();
22913
23193
  const gridClass = {
@@ -22915,7 +23195,7 @@ var init_FormSection = __esm({
22915
23195
  2: "grid-cols-1 md:grid-cols-2",
22916
23196
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
22917
23197
  }[columns];
22918
- React81__default.useCallback(() => {
23198
+ React82__default.useCallback(() => {
22919
23199
  if (collapsible) {
22920
23200
  setCollapsed((prev) => !prev);
22921
23201
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -23173,129 +23453,6 @@ var init_FormField = __esm({
23173
23453
  FormField.displayName = "FormField";
23174
23454
  }
23175
23455
  });
23176
- function useSafeEventBus3() {
23177
- try {
23178
- return useEventBus();
23179
- } catch {
23180
- return { emit: () => {
23181
- }, on: () => () => {
23182
- }, once: () => {
23183
- } };
23184
- }
23185
- }
23186
- var log7, lookStyles5, ButtonGroup;
23187
- var init_ButtonGroup = __esm({
23188
- "components/core/molecules/ButtonGroup.tsx"() {
23189
- "use client";
23190
- init_cn();
23191
- init_atoms();
23192
- init_useEventBus();
23193
- log7 = createLogger("almadar:ui:button-group");
23194
- lookStyles5 = {
23195
- "right-aligned-buttons": "",
23196
- "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
23197
- "inline-row": "gap-2 inline-flex",
23198
- "dropdown-menu": "[&>button:not(:first-child)]:hidden",
23199
- "command-palette-trigger": "[&>button:not(:first-child)]:hidden"
23200
- };
23201
- ButtonGroup = ({
23202
- children,
23203
- primary,
23204
- secondary,
23205
- variant = "default",
23206
- orientation = "horizontal",
23207
- className,
23208
- // Filter-group pattern props (entity and filters are used for schema-driven filtering)
23209
- entity: _entity,
23210
- filters,
23211
- look = "right-aligned-buttons"
23212
- }) => {
23213
- const eventBus = useSafeEventBus3();
23214
- const variantClasses2 = {
23215
- default: "gap-0",
23216
- segmented: "gap-0 [&>button]:rounded-none [&>button:first-child]:rounded-l-lg [&>button:last-child]:rounded-r-lg [&>button:not(:first-child)]:border-l-0",
23217
- toggle: "gap-0 [&>button]:rounded-none [&>button:first-child]:rounded-l-lg [&>button:last-child]:rounded-r-lg [&>button:not(:first-child)]:border-l-0"
23218
- };
23219
- const orientationClasses = {
23220
- horizontal: "flex-row",
23221
- vertical: "flex-col [&>button:first-child]:rounded-t-lg [&>button:last-child]:rounded-b-lg [&>button:not(:first-child)]:border-t-0 [&>button:not(:first-child)]:border-l"
23222
- };
23223
- const handleActionClick = (action) => {
23224
- if (action.event) {
23225
- eventBus.emit("UI:DISPATCH", { event: action.event });
23226
- }
23227
- if (action.navigatesTo) {
23228
- eventBus.emit("UI:NAVIGATE", { url: action.navigatesTo });
23229
- }
23230
- };
23231
- const renderFormActions = () => {
23232
- const buttons = [];
23233
- if (secondary) {
23234
- secondary.forEach((action, index) => {
23235
- buttons.push(
23236
- /* @__PURE__ */ jsx(
23237
- Button,
23238
- {
23239
- type: action.actionType === "submit" ? "submit" : "button",
23240
- variant: action.variant || "ghost",
23241
- onClick: () => handleActionClick(action),
23242
- children: action.label
23243
- },
23244
- `secondary-${index}`
23245
- )
23246
- );
23247
- });
23248
- }
23249
- if (primary) {
23250
- const isSubmit = primary.actionType === "submit";
23251
- buttons.push(
23252
- /* @__PURE__ */ jsx(
23253
- Button,
23254
- {
23255
- type: isSubmit ? "submit" : "button",
23256
- variant: primary.variant || "primary",
23257
- onClick: () => handleActionClick(primary),
23258
- "data-testid": isSubmit ? "form-submit" : void 0,
23259
- children: primary.label
23260
- },
23261
- "primary"
23262
- )
23263
- );
23264
- }
23265
- return buttons;
23266
- };
23267
- const renderFilters = () => {
23268
- if (!filters || filters.length === 0) return null;
23269
- return filters.map((filter, index) => /* @__PURE__ */ jsx(
23270
- Button,
23271
- {
23272
- variant: "ghost",
23273
- onClick: () => {
23274
- log7.debug("Filter clicked", { field: filter.field });
23275
- },
23276
- children: filter.label
23277
- },
23278
- `filter-${filter.field}-${index}`
23279
- ));
23280
- };
23281
- return /* @__PURE__ */ jsx(
23282
- "div",
23283
- {
23284
- className: cn(
23285
- "inline-flex gap-2",
23286
- variantClasses2[variant],
23287
- orientationClasses[orientation],
23288
- lookStyles5[look],
23289
- className
23290
- ),
23291
- role: "group",
23292
- children: children || renderFilters() || renderFormActions()
23293
- }
23294
- );
23295
- };
23296
- ButtonGroup.displayName = "ButtonGroup";
23297
- }
23298
- });
23299
23456
  var resolveFilterType, lookStyles6, FilterGroup;
23300
23457
  var init_FilterGroup = __esm({
23301
23458
  "components/core/molecules/FilterGroup.tsx"() {
@@ -23408,7 +23565,7 @@ var init_FilterGroup = __esm({
23408
23565
  type: "button",
23409
23566
  onClick: () => handleFilterSelect(filter.field, null),
23410
23567
  className: cn(
23411
- "px-3 py-1.5 text-sm font-medium transition-all duration-[var(--transition-fast)]",
23568
+ "px-3 py-1.5 text-sm font-medium transition-all duration-fast",
23412
23569
  !selectedValues[filter.field] ? "bg-primary text-primary-foreground" : "bg-card text-muted-foreground hover:bg-muted"
23413
23570
  ),
23414
23571
  children: t("filterGroup.all")
@@ -23420,7 +23577,7 @@ var init_FilterGroup = __esm({
23420
23577
  type: "button",
23421
23578
  onClick: () => handleFilterSelect(filter.field, option),
23422
23579
  className: cn(
23423
- "px-3 py-1.5 text-sm font-medium transition-all duration-[var(--transition-fast)]",
23580
+ "px-3 py-1.5 text-sm font-medium transition-all duration-fast",
23424
23581
  "border-l-[length:var(--border-width)] border-border",
23425
23582
  selectedValues[filter.field] === option ? "bg-primary text-primary-foreground" : "bg-card text-muted-foreground hover:bg-muted"
23426
23583
  ),
@@ -23801,7 +23958,7 @@ var init_Flex = __esm({
23801
23958
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
23802
23959
  }
23803
23960
  }
23804
- return React81__default.createElement(Component, {
23961
+ return React82__default.createElement(Component, {
23805
23962
  className: cn(
23806
23963
  inline ? "inline-flex" : "flex",
23807
23964
  directionStyles[direction],
@@ -23920,7 +24077,7 @@ var init_Grid = __esm({
23920
24077
  as: Component = "div"
23921
24078
  }) => {
23922
24079
  const mergedStyle = rows ? { gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, ...style } : style;
23923
- return React81__default.createElement(
24080
+ return React82__default.createElement(
23924
24081
  Component,
23925
24082
  {
23926
24083
  className: cn(
@@ -24031,6 +24188,7 @@ var init_Popover = __esm({
24031
24188
  "components/core/molecules/Popover.tsx"() {
24032
24189
  "use client";
24033
24190
  init_Typography();
24191
+ init_Presence();
24034
24192
  init_cn();
24035
24193
  init_useTapReveal();
24036
24194
  arrowClasses = {
@@ -24054,6 +24212,7 @@ var init_Popover = __esm({
24054
24212
  const [popoverWidth, setPopoverWidth] = useState(0);
24055
24213
  const triggerRef = useRef(null);
24056
24214
  const popoverRef = useRef(null);
24215
+ const { mounted, className: panelAnim, onAnimationEnd } = usePresence(isOpen, { animation: "popover" });
24057
24216
  const updatePosition = () => {
24058
24217
  if (triggerRef.current) {
24059
24218
  setTriggerRect(triggerRef.current.getBoundingClientRect());
@@ -24079,10 +24238,11 @@ var init_Popover = __esm({
24079
24238
  useEffect(() => {
24080
24239
  if (isOpen) {
24081
24240
  updatePosition();
24082
- } else {
24083
- setPopoverWidth(0);
24084
24241
  }
24085
24242
  }, [isOpen]);
24243
+ useEffect(() => {
24244
+ if (!mounted) setPopoverWidth(0);
24245
+ }, [mounted]);
24086
24246
  useLayoutEffect(() => {
24087
24247
  if (isOpen && popoverRef.current) {
24088
24248
  const measured = popoverRef.current.offsetWidth;
@@ -24116,9 +24276,9 @@ var init_Popover = __esm({
24116
24276
  onMouseLeave: handleClose,
24117
24277
  onPointerDown: tapTriggerProps.onPointerDown
24118
24278
  };
24119
- const childElement = React81__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24279
+ const childElement = React82__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24120
24280
  const childPointerDown = childElement.props.onPointerDown;
24121
- const triggerElement = React81__default.cloneElement(
24281
+ const triggerElement = React82__default.cloneElement(
24122
24282
  childElement,
24123
24283
  {
24124
24284
  ref: triggerRef,
@@ -24131,13 +24291,14 @@ var init_Popover = __esm({
24131
24291
  } : void 0
24132
24292
  }
24133
24293
  );
24134
- const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
24294
+ const panel = mounted && triggerRect ? /* @__PURE__ */ jsxs(
24135
24295
  "div",
24136
24296
  {
24137
24297
  ref: popoverRef,
24138
24298
  className: cn(
24139
24299
  "fixed z-50 p-4",
24140
24300
  "bg-card border-2 border-border shadow-elevation-popover",
24301
+ panelAnim,
24141
24302
  className
24142
24303
  ),
24143
24304
  style: {
@@ -24145,6 +24306,7 @@ var init_Popover = __esm({
24145
24306
  ...popoverWidth === 0 ? { visibility: "hidden" } : void 0
24146
24307
  },
24147
24308
  role: "dialog",
24309
+ onAnimationEnd,
24148
24310
  onMouseEnter: trigger === "hover" ? handleOpen : void 0,
24149
24311
  onMouseLeave: trigger === "hover" ? handleClose : void 0,
24150
24312
  children: [
@@ -24558,6 +24720,7 @@ var init_SidePanel = __esm({
24558
24720
  init_Box();
24559
24721
  init_Button();
24560
24722
  init_Typography();
24723
+ init_Presence();
24561
24724
  init_cn();
24562
24725
  init_useEventBus();
24563
24726
  SidePanel = ({
@@ -24577,15 +24740,17 @@ var init_SidePanel = __esm({
24577
24740
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
24578
24741
  onClose();
24579
24742
  };
24580
- if (!isOpen) return null;
24743
+ const { mounted, className: panelAnim, onAnimationEnd } = usePresence(isOpen, { animation: "drawer" });
24744
+ const drawerSign = position === "right" ? 1 : -1;
24745
+ if (!mounted) return null;
24581
24746
  return /* @__PURE__ */ jsxs(Fragment, { children: [
24582
- showOverlay && /* @__PURE__ */ jsx(
24747
+ showOverlay && /* @__PURE__ */ jsx(Presence, { show: isOpen, animation: "overlay", children: /* @__PURE__ */ jsx(
24583
24748
  Box,
24584
24749
  {
24585
24750
  className: "fixed inset-0 bg-white/80 backdrop-blur-sm z-40 lg:hidden",
24586
24751
  onClick: handleClose
24587
24752
  }
24588
- ),
24753
+ ) }),
24589
24754
  /* @__PURE__ */ jsxs(
24590
24755
  Aside,
24591
24756
  {
@@ -24595,11 +24760,13 @@ var init_SidePanel = __esm({
24595
24760
  "border-l-2 border-border",
24596
24761
  position === "left" && "border-l-0 border-r-2",
24597
24762
  "flex flex-col",
24598
- "transition-transform duration-normal ease-standard",
24763
+ panelAnim,
24599
24764
  width,
24600
24765
  position === "right" ? "right-0" : "left-0",
24601
24766
  className
24602
24767
  ),
24768
+ style: { "--motion-drawer-sign": drawerSign },
24769
+ onAnimationEnd,
24603
24770
  children: [
24604
24771
  /* @__PURE__ */ jsxs(Box, { className: "flex items-center justify-between p-4 border-b-2 border-border sticky top-0 bg-card z-10", children: [
24605
24772
  /* @__PURE__ */ jsx(Typography, { variant: "h6", children: title }),
@@ -24720,9 +24887,9 @@ var init_Tooltip = __esm({
24720
24887
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
24721
24888
  };
24722
24889
  }, []);
24723
- const triggerElement = React81__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24890
+ const triggerElement = React82__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24724
24891
  const childPointerDown = triggerElement.props.onPointerDown;
24725
- const trigger = React81__default.cloneElement(triggerElement, {
24892
+ const trigger = React82__default.cloneElement(triggerElement, {
24726
24893
  ref: triggerRef,
24727
24894
  onMouseEnter: handleMouseEnter,
24728
24895
  onMouseLeave: handleMouseLeave,
@@ -24812,7 +24979,7 @@ var init_WizardProgress = __esm({
24812
24979
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
24813
24980
  const isActive = index === currentStep;
24814
24981
  const isCompleted = index < currentStep;
24815
- return /* @__PURE__ */ jsxs(React81__default.Fragment, { children: [
24982
+ return /* @__PURE__ */ jsxs(React82__default.Fragment, { children: [
24816
24983
  /* @__PURE__ */ jsx(
24817
24984
  "button",
24818
24985
  {
@@ -25363,7 +25530,7 @@ var init_FormSectionHeader = __esm({
25363
25530
  name: "chevron-down",
25364
25531
  size: "sm",
25365
25532
  className: cn(
25366
- "text-muted-foreground transition-transform duration-200 shrink-0",
25533
+ "text-muted-foreground transition-transform duration-fast shrink-0",
25367
25534
  isCollapsed && "-rotate-90"
25368
25535
  )
25369
25536
  }
@@ -26373,13 +26540,13 @@ var init_MapView = __esm({
26373
26540
  shadowSize: [41, 41]
26374
26541
  });
26375
26542
  L.Marker.prototype.options.icon = defaultIcon;
26376
- const { useEffect: useEffect58, useRef: useRef58, useCallback: useCallback86, useState: useState87 } = React81__default;
26543
+ const { useEffect: useEffect59, useRef: useRef59, useCallback: useCallback87, useState: useState89 } = React82__default;
26377
26544
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
26378
26545
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
26379
26546
  function MapUpdater({ centerLat, centerLng, zoom }) {
26380
26547
  const map = useMap();
26381
- const prevRef = useRef58({ centerLat, centerLng, zoom });
26382
- useEffect58(() => {
26548
+ const prevRef = useRef59({ centerLat, centerLng, zoom });
26549
+ useEffect59(() => {
26383
26550
  const prev = prevRef.current;
26384
26551
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
26385
26552
  map.setView([centerLat, centerLng], zoom);
@@ -26390,7 +26557,7 @@ var init_MapView = __esm({
26390
26557
  }
26391
26558
  function MapClickHandler({ onMapClick }) {
26392
26559
  const map = useMap();
26393
- useEffect58(() => {
26560
+ useEffect59(() => {
26394
26561
  if (!onMapClick) return;
26395
26562
  const handler = (e) => {
26396
26563
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -26418,8 +26585,8 @@ var init_MapView = __esm({
26418
26585
  showAttribution = true
26419
26586
  }) {
26420
26587
  const eventBus = useEventBus2();
26421
- const [clickedPosition, setClickedPosition] = useState87(null);
26422
- const handleMapClick = useCallback86((lat, lng) => {
26588
+ const [clickedPosition, setClickedPosition] = useState89(null);
26589
+ const handleMapClick = useCallback87((lat, lng) => {
26423
26590
  if (showClickedPin) {
26424
26591
  setClickedPosition({ lat, lng });
26425
26592
  }
@@ -26428,7 +26595,7 @@ var init_MapView = __esm({
26428
26595
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
26429
26596
  }
26430
26597
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
26431
- const handleMarkerClick = useCallback86((marker) => {
26598
+ const handleMarkerClick = useCallback87((marker) => {
26432
26599
  onMarkerClick?.(marker);
26433
26600
  if (markerClickEvent) {
26434
26601
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -26628,7 +26795,7 @@ var init_NumberStepper = __esm({
26628
26795
  "text-foreground",
26629
26796
  "hover:bg-muted",
26630
26797
  "active:bg-muted",
26631
- "transition-colors duration-100",
26798
+ "transition-colors duration-instant",
26632
26799
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
26633
26800
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
26634
26801
  styles.button
@@ -26669,7 +26836,7 @@ var init_NumberStepper = __esm({
26669
26836
  "text-foreground",
26670
26837
  "hover:bg-muted",
26671
26838
  "active:bg-muted",
26672
- "transition-colors duration-100",
26839
+ "transition-colors duration-instant",
26673
26840
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
26674
26841
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
26675
26842
  styles.button
@@ -26793,7 +26960,7 @@ var init_StarRating = __esm({
26793
26960
  className: cn(
26794
26961
  styles.star,
26795
26962
  "text-foreground/30",
26796
- "transition-colors duration-100"
26963
+ "transition-colors duration-instant"
26797
26964
  ),
26798
26965
  strokeWidth: 1.5
26799
26966
  }
@@ -26806,7 +26973,7 @@ var init_StarRating = __esm({
26806
26973
  styles.star,
26807
26974
  "absolute inset-0",
26808
26975
  "text-warning fill-warning",
26809
- "transition-colors duration-100"
26976
+ "transition-colors duration-instant"
26810
26977
  ),
26811
26978
  strokeWidth: 1.5,
26812
26979
  style: isHalf ? { clipPath: "inset(0 50% 0 0)" } : void 0
@@ -26961,7 +27128,7 @@ var init_UploadDropZone = __esm({
26961
27128
  "relative flex flex-col items-center justify-center",
26962
27129
  "p-8 rounded-sm",
26963
27130
  "border-2 border-dashed",
26964
- "transition-colors duration-150",
27131
+ "transition-colors duration-fast",
26965
27132
  "cursor-pointer",
26966
27133
  isDragOver ? "border-primary bg-primary bg-opacity-5" : "border-border bg-surface",
26967
27134
  error && "border-error",
@@ -27288,8 +27455,8 @@ function TableView({
27288
27455
  }) {
27289
27456
  const eventBus = useEventBus();
27290
27457
  const { t } = useTranslate();
27291
- const [visibleCount, setVisibleCount] = React81__default.useState(pageSize > 0 ? pageSize : Infinity);
27292
- const [localSelected, setLocalSelected] = React81__default.useState(/* @__PURE__ */ new Set());
27458
+ const [visibleCount, setVisibleCount] = React82__default.useState(pageSize > 0 ? pageSize : Infinity);
27459
+ const [localSelected, setLocalSelected] = React82__default.useState(/* @__PURE__ */ new Set());
27293
27460
  const colDefs = columns ?? fields ?? [];
27294
27461
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
27295
27462
  const dnd = useDataDnd({
@@ -27369,7 +27536,7 @@ function TableView({
27369
27536
  className: cn(
27370
27537
  "grid items-center gap-3 sticky top-0 z-10",
27371
27538
  "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
27372
- "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
27539
+ "text-muted-foreground uppercase text-xs font-semibold tracking-wide",
27373
27540
  lk.headPad
27374
27541
  ),
27375
27542
  children: [
@@ -27484,12 +27651,12 @@ function TableView({
27484
27651
  ]
27485
27652
  }
27486
27653
  );
27487
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React81__default.Fragment, { children: rowInner }, id);
27654
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React82__default.Fragment, { children: rowInner }, id);
27488
27655
  };
27489
27656
  const items = Array.from(data);
27490
27657
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
27491
27658
  let runningIndex = 0;
27492
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React81__default.Fragment, { children: [
27659
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React82__default.Fragment, { children: [
27493
27660
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
27494
27661
  group.items.map((row) => renderRow(row, runningIndex++))
27495
27662
  ] }, gi)) });
@@ -28152,7 +28319,7 @@ function SortableListInner({
28152
28319
  "flex items-center justify-center",
28153
28320
  "text-muted-foreground",
28154
28321
  "hover:text-foreground",
28155
- "transition-colors duration-100",
28322
+ "transition-colors duration-instant",
28156
28323
  "px-1"
28157
28324
  ),
28158
28325
  "aria-grabbed": ariaGrabbed,
@@ -28179,7 +28346,7 @@ function SortableListInner({
28179
28346
  gap: "sm",
28180
28347
  align: "center",
28181
28348
  className: cn(
28182
- "transition-opacity duration-150",
28349
+ "transition-opacity duration-fast",
28183
28350
  isBeingDragged && "opacity-50"
28184
28351
  ),
28185
28352
  children: [
@@ -28286,7 +28453,7 @@ var init_PullToRefresh = __esm({
28286
28453
  children: /* @__PURE__ */ jsx(
28287
28454
  Box,
28288
28455
  {
28289
- className: "transition-transform duration-150",
28456
+ className: "transition-transform duration-fast",
28290
28457
  style: {
28291
28458
  transform: `scale(${isRefreshing ? 1 : pullProgress})`,
28292
28459
  opacity: isRefreshing ? 1 : pullProgress
@@ -28708,7 +28875,7 @@ var init_StepFlow = __esm({
28708
28875
  className
28709
28876
  }) => {
28710
28877
  if (orientation === "vertical") {
28711
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React81__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
28878
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React82__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
28712
28879
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
28713
28880
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
28714
28881
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -28719,7 +28886,7 @@ var init_StepFlow = __esm({
28719
28886
  ] })
28720
28887
  ] }) }, index)) });
28721
28888
  }
28722
- 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(React81__default.Fragment, { children: [
28889
+ 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(React82__default.Fragment, { children: [
28723
28890
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
28724
28891
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
28725
28892
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -29596,6 +29763,11 @@ var init_VoteStack = __esm({
29596
29763
  {
29597
29764
  className: cn(
29598
29765
  "inline-flex items-center justify-center",
29766
+ // Shrink-wrap in stretch contexts (slot/sidecar wrappers are
29767
+ // flex-column with stretch alignment): without this the root spans
29768
+ // the full wrapper width and the count row's `w-full` turns the
29769
+ // compact pill into a page-wide band.
29770
+ "w-fit",
29599
29771
  variant === "vertical" ? "flex-col" : "flex-row",
29600
29772
  "rounded-sm",
29601
29773
  "border-[length:var(--border-width)] border-border",
@@ -29620,7 +29792,7 @@ var init_VoteStack = __esm({
29620
29792
  isUp ? "text-primary" : "text-muted-foreground",
29621
29793
  "hover:bg-muted",
29622
29794
  "active:bg-muted",
29623
- "transition-colors duration-100",
29795
+ "transition-colors duration-instant",
29624
29796
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
29625
29797
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
29626
29798
  styles.button
@@ -29657,7 +29829,7 @@ var init_VoteStack = __esm({
29657
29829
  isDown ? "text-primary" : "text-muted-foreground",
29658
29830
  "hover:bg-muted",
29659
29831
  "active:bg-muted",
29660
- "transition-colors duration-100",
29832
+ "transition-colors duration-instant",
29661
29833
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
29662
29834
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
29663
29835
  styles.button
@@ -29704,7 +29876,7 @@ var init_LikertScale = __esm({
29704
29876
  md: "text-base",
29705
29877
  lg: "text-lg"
29706
29878
  };
29707
- LikertScale = React81__default.forwardRef(
29879
+ LikertScale = React82__default.forwardRef(
29708
29880
  ({
29709
29881
  question,
29710
29882
  options = DEFAULT_LIKERT_OPTIONS,
@@ -29716,7 +29888,7 @@ var init_LikertScale = __esm({
29716
29888
  variant = "radios",
29717
29889
  className
29718
29890
  }, ref) => {
29719
- const groupId = React81__default.useId();
29891
+ const groupId = React82__default.useId();
29720
29892
  const eventBus = useEventBus();
29721
29893
  const handleSelect = useCallback(
29722
29894
  (next) => {
@@ -29769,7 +29941,7 @@ var init_LikertScale = __esm({
29769
29941
  disabled,
29770
29942
  onClick: () => handleSelect(opt.value),
29771
29943
  className: cn(
29772
- "flex-1 text-center font-medium transition-colors duration-100",
29944
+ "flex-1 text-center font-medium transition-colors duration-instant",
29773
29945
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
29774
29946
  "disabled:cursor-not-allowed",
29775
29947
  "rounded-none gap-0 shadow-none border-none",
@@ -31998,7 +32170,7 @@ var init_DocBreadcrumb = __esm({
31998
32170
  "aria-label": t("aria.breadcrumb"),
31999
32171
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
32000
32172
  const isLast = idx === items.length - 1;
32001
- return /* @__PURE__ */ jsxs(React81__default.Fragment, { children: [
32173
+ return /* @__PURE__ */ jsxs(React82__default.Fragment, { children: [
32002
32174
  idx > 0 && /* @__PURE__ */ jsx(
32003
32175
  Icon,
32004
32176
  {
@@ -32867,7 +33039,7 @@ var init_MiniStateMachine = __esm({
32867
33039
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
32868
33040
  const tc = transitionCounts[s.name] ?? 0;
32869
33041
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
32870
- return /* @__PURE__ */ jsxs(React81__default.Fragment, { children: [
33042
+ return /* @__PURE__ */ jsxs(React82__default.Fragment, { children: [
32871
33043
  /* @__PURE__ */ jsx(
32872
33044
  AvlState,
32873
33045
  {
@@ -33071,7 +33243,7 @@ var init_PageHeader = __esm({
33071
33243
  info: "bg-info/10 text-info"
33072
33244
  };
33073
33245
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
33074
- 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(React81__default.Fragment, { children: [
33246
+ 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(React82__default.Fragment, { children: [
33075
33247
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
33076
33248
  crumb.href ? /* @__PURE__ */ jsx(
33077
33249
  "a",
@@ -33429,7 +33601,7 @@ var init_Section = __esm({
33429
33601
  as: Component = "section"
33430
33602
  }) => {
33431
33603
  const hasHeader = title || description || action;
33432
- return React81__default.createElement(
33604
+ return React82__default.createElement(
33433
33605
  Component,
33434
33606
  {
33435
33607
  className: cn(
@@ -33496,12 +33668,12 @@ var init_Sidebar = __esm({
33496
33668
  variant: "ghost",
33497
33669
  onClick: item.onClick,
33498
33670
  className: cn(
33499
- "w-full flex items-center gap-3 px-3 py-2.5 transition-all duration-[var(--transition-fast)] group relative",
33671
+ "w-full flex items-center gap-3 px-3 py-2.5 transition-all duration-fast group relative",
33500
33672
  "rounded-sm border-[length:var(--border-width-thin)] border-transparent",
33501
33673
  isActive ? [
33502
33674
  "bg-primary text-primary-foreground",
33503
33675
  "font-medium shadow-sm",
33504
- "border-primary translate-x-1 -translate-y-0.5"
33676
+ "border-primary translate-x-1 rtl:-translate-x-1 -translate-y-0.5"
33505
33677
  ].join(" ") : [
33506
33678
  "text-foreground",
33507
33679
  "hover:bg-muted hover:border-border",
@@ -33511,10 +33683,10 @@ var init_Sidebar = __esm({
33511
33683
  title: collapsed ? item.label : void 0,
33512
33684
  children: [
33513
33685
  item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm", className: cn("min-w-[20px] flex-shrink-0", isActive && "text-primary-foreground") }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm", className: cn("min-w-[20px] flex-shrink-0", isActive && "text-primary-foreground") })),
33514
- !collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-left", children: item.label }),
33686
+ !collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-start", children: item.label }),
33515
33687
  !collapsed && item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "danger", size: "sm", children: item.badge }),
33516
33688
  collapsed && /* @__PURE__ */ jsx(Box, { className: cn(
33517
- "absolute left-full ml-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
33689
+ "absolute start-full ms-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
33518
33690
  "pointer-events-none whitespace-nowrap z-50 transition-opacity",
33519
33691
  "bg-primary text-primary-foreground",
33520
33692
  "border-[length:var(--border-width-thin)] border-border",
@@ -33569,8 +33741,8 @@ var init_Sidebar = __esm({
33569
33741
  as: "aside",
33570
33742
  className: cn(
33571
33743
  "flex flex-col h-full",
33572
- "bg-card border-r border-border",
33573
- "transition-all duration-300 ease-in-out",
33744
+ "bg-card border-e border-border",
33745
+ "transition-all duration-normal ease-standard",
33574
33746
  collapsed ? "w-20" : "w-64",
33575
33747
  className
33576
33748
  ),
@@ -33803,7 +33975,7 @@ var init_WizardContainer = __esm({
33803
33975
  const isCompleted = index < currentStep;
33804
33976
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
33805
33977
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
33806
- return /* @__PURE__ */ jsxs(React81__default.Fragment, { children: [
33978
+ return /* @__PURE__ */ jsxs(React82__default.Fragment, { children: [
33807
33979
  /* @__PURE__ */ jsx(
33808
33980
  Button,
33809
33981
  {
@@ -34730,7 +34902,7 @@ function resolveColor3(color, el) {
34730
34902
  function truncateLabel(label) {
34731
34903
  return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
34732
34904
  }
34733
- var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
34905
+ var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, NO_NODES, NO_EDGES, NO_SIM, GraphCanvas;
34734
34906
  var init_GraphCanvas = __esm({
34735
34907
  "components/core/molecules/GraphCanvas.tsx"() {
34736
34908
  "use client";
@@ -34754,11 +34926,14 @@ var init_GraphCanvas = __esm({
34754
34926
  UNGROUPED_GRAVITY = 0.02;
34755
34927
  labelMeasureCtx = null;
34756
34928
  MAX_LABEL_CHARS = 22;
34929
+ NO_NODES = [];
34930
+ NO_EDGES = [];
34931
+ NO_SIM = [];
34757
34932
  GraphCanvas = ({
34758
34933
  title,
34759
- nodes: propNodes = [],
34760
- edges: propEdges = [],
34761
- similarity: propSimilarity = [],
34934
+ nodes: propNodes = NO_NODES,
34935
+ edges: propEdges = NO_EDGES,
34936
+ similarity: propSimilarity = NO_SIM,
34762
34937
  height = 400,
34763
34938
  showLabels = true,
34764
34939
  interactive = true,
@@ -34808,6 +34983,7 @@ var init_GraphCanvas = __esm({
34808
34983
  const interactionRef = useRef({
34809
34984
  mode: "none",
34810
34985
  dragNodeId: null,
34986
+ pressedNodeId: null,
34811
34987
  startMouse: { x: 0, y: 0 },
34812
34988
  startOffset: { x: 0, y: 0 },
34813
34989
  downPos: { x: 0, y: 0 }
@@ -34855,6 +35031,11 @@ var init_GraphCanvas = __esm({
34855
35031
  () => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
34856
35032
  [propNodes]
34857
35033
  );
35034
+ const nodesKey = useMemo(() => propNodes.map((n) => n.id).join(""), [propNodes]);
35035
+ const edgesKey = useMemo(
35036
+ () => propEdges.map((e) => `${e.source}${e.target}`).join(""),
35037
+ [propEdges]
35038
+ );
34858
35039
  useEffect(() => {
34859
35040
  const canvas = canvasRef.current;
34860
35041
  if (!canvas || propNodes.length === 0) return;
@@ -35035,7 +35216,7 @@ var init_GraphCanvas = __esm({
35035
35216
  return () => {
35036
35217
  cancelAnimationFrame(animRef.current);
35037
35218
  };
35038
- }, [propNodes, propEdges, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
35219
+ }, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
35039
35220
  useEffect(() => {
35040
35221
  const canvas = canvasRef.current;
35041
35222
  if (!canvas) return;
@@ -35165,6 +35346,7 @@ var init_GraphCanvas = __esm({
35165
35346
  const cancelSinglePointer = useCallback(() => {
35166
35347
  interactionRef.current.mode = "none";
35167
35348
  interactionRef.current.dragNodeId = null;
35349
+ interactionRef.current.pressedNodeId = null;
35168
35350
  }, []);
35169
35351
  const handlePointerDown = useCallback(
35170
35352
  (e) => {
@@ -35175,6 +35357,7 @@ var init_GraphCanvas = __esm({
35175
35357
  state.downPos = { x: e.clientX, y: e.clientY };
35176
35358
  state.startMouse = { x: e.clientX, y: e.clientY };
35177
35359
  state.startOffset = { ...offset };
35360
+ state.pressedNodeId = node?.id ?? null;
35178
35361
  if (draggable && node) {
35179
35362
  state.mode = "dragging";
35180
35363
  state.dragNodeId = node.id;
@@ -35226,7 +35409,8 @@ var init_GraphCanvas = __esm({
35226
35409
  if (moved < 4) {
35227
35410
  const coords = toCoords(e);
35228
35411
  if (!coords) return;
35229
- const node = nodeAt(coords.graphX, coords.graphY);
35412
+ const node = (state.pressedNodeId ? nodesRef.current.find((n) => n.id === state.pressedNodeId) : void 0) ?? nodeAt(coords.graphX, coords.graphY);
35413
+ state.pressedNodeId = null;
35230
35414
  if (node) {
35231
35415
  if (node.badge && node.badge > 1 && onBadgeClick) {
35232
35416
  const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
@@ -35246,6 +35430,7 @@ var init_GraphCanvas = __esm({
35246
35430
  );
35247
35431
  const handlePointerLeave = useCallback(() => {
35248
35432
  setHoveredNode(null);
35433
+ interactionRef.current.pressedNodeId = null;
35249
35434
  }, []);
35250
35435
  const gestureHandlers = useCanvasGestures({
35251
35436
  canvasRef,
@@ -36393,7 +36578,7 @@ var init_DetailPanel = __esm({
36393
36578
  }
36394
36579
  });
36395
36580
  function extractTitle(children) {
36396
- if (!React81__default.isValidElement(children)) return void 0;
36581
+ if (!React82__default.isValidElement(children)) return void 0;
36397
36582
  const props = children.props;
36398
36583
  if (typeof props.title === "string") {
36399
36584
  return props.title;
@@ -36743,12 +36928,12 @@ var init_Form = __esm({
36743
36928
  const isSchemaEntity = isOrbitalEntitySchema(entity);
36744
36929
  const resolvedEntity = isSchemaEntity ? entity : void 0;
36745
36930
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
36746
- const normalizedInitialData = React81__default.useMemo(() => {
36931
+ const normalizedInitialData = React82__default.useMemo(() => {
36747
36932
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
36748
36933
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
36749
36934
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
36750
36935
  }, [entity, initialData]);
36751
- const entityDerivedFields = React81__default.useMemo(() => {
36936
+ const entityDerivedFields = React82__default.useMemo(() => {
36752
36937
  if (fields && fields.length > 0) return void 0;
36753
36938
  if (!resolvedEntity) return void 0;
36754
36939
  return resolvedEntity.fields.map(
@@ -36769,16 +36954,16 @@ var init_Form = __esm({
36769
36954
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
36770
36955
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
36771
36956
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
36772
- const [formData, setFormData] = React81__default.useState(
36957
+ const [formData, setFormData] = React82__default.useState(
36773
36958
  normalizedInitialData
36774
36959
  );
36775
- const [collapsedSections, setCollapsedSections] = React81__default.useState(
36960
+ const [collapsedSections, setCollapsedSections] = React82__default.useState(
36776
36961
  /* @__PURE__ */ new Set()
36777
36962
  );
36778
- const [submitError, setSubmitError] = React81__default.useState(null);
36779
- const formRef = React81__default.useRef(null);
36963
+ const [submitError, setSubmitError] = React82__default.useState(null);
36964
+ const formRef = React82__default.useRef(null);
36780
36965
  const formMode = props.mode;
36781
- const mountedRef = React81__default.useRef(false);
36966
+ const mountedRef = React82__default.useRef(false);
36782
36967
  if (!mountedRef.current) {
36783
36968
  mountedRef.current = true;
36784
36969
  debug("forms", "mount", {
@@ -36791,7 +36976,7 @@ var init_Form = __esm({
36791
36976
  });
36792
36977
  }
36793
36978
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
36794
- const evalContext = React81__default.useMemo(
36979
+ const evalContext = React82__default.useMemo(
36795
36980
  () => ({
36796
36981
  formValues: formData,
36797
36982
  globalVariables: externalContext?.globalVariables ?? {},
@@ -36800,7 +36985,7 @@ var init_Form = __esm({
36800
36985
  }),
36801
36986
  [formData, externalContext]
36802
36987
  );
36803
- React81__default.useEffect(() => {
36988
+ React82__default.useEffect(() => {
36804
36989
  debug("forms", "initialData-sync", {
36805
36990
  mode: formMode,
36806
36991
  normalizedInitialData,
@@ -36811,7 +36996,7 @@ var init_Form = __esm({
36811
36996
  setFormData(normalizedInitialData);
36812
36997
  }
36813
36998
  }, [normalizedInitialData]);
36814
- const processCalculations = React81__default.useCallback(
36999
+ const processCalculations = React82__default.useCallback(
36815
37000
  (changedFieldId, newFormData) => {
36816
37001
  if (!hiddenCalculations.length) return;
36817
37002
  const context = {
@@ -36836,7 +37021,7 @@ var init_Form = __esm({
36836
37021
  },
36837
37022
  [hiddenCalculations, externalContext, eventBus]
36838
37023
  );
36839
- const checkViolations = React81__default.useCallback(
37024
+ const checkViolations = React82__default.useCallback(
36840
37025
  (changedFieldId, newFormData) => {
36841
37026
  if (!violationTriggers.length) return;
36842
37027
  const context = {
@@ -36874,7 +37059,7 @@ var init_Form = __esm({
36874
37059
  processCalculations(name, newFormData);
36875
37060
  checkViolations(name, newFormData);
36876
37061
  };
36877
- const isFieldVisible = React81__default.useCallback(
37062
+ const isFieldVisible = React82__default.useCallback(
36878
37063
  (fieldName) => {
36879
37064
  const condition = conditionalFields[fieldName];
36880
37065
  if (!condition) return true;
@@ -36882,7 +37067,7 @@ var init_Form = __esm({
36882
37067
  },
36883
37068
  [conditionalFields, evalContext]
36884
37069
  );
36885
- const isSectionVisible = React81__default.useCallback(
37070
+ const isSectionVisible = React82__default.useCallback(
36886
37071
  (section) => {
36887
37072
  if (!section.condition) return true;
36888
37073
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -36958,7 +37143,7 @@ var init_Form = __esm({
36958
37143
  eventBus.emit(`UI:${onCancel}`);
36959
37144
  }
36960
37145
  };
36961
- const renderField = React81__default.useCallback(
37146
+ const renderField = React82__default.useCallback(
36962
37147
  (field) => {
36963
37148
  const fieldName = field.name || field.field;
36964
37149
  if (!fieldName) return null;
@@ -36979,7 +37164,7 @@ var init_Form = __esm({
36979
37164
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
36980
37165
  );
36981
37166
  const effectiveFields = entityDerivedFields ?? fields;
36982
- const normalizedFields = React81__default.useMemo(() => {
37167
+ const normalizedFields = React82__default.useMemo(() => {
36983
37168
  if (!effectiveFields || effectiveFields.length === 0) return [];
36984
37169
  return effectiveFields.map((field) => {
36985
37170
  if (typeof field === "string") {
@@ -37003,7 +37188,7 @@ var init_Form = __esm({
37003
37188
  return field;
37004
37189
  });
37005
37190
  }, [effectiveFields, resolvedEntity]);
37006
- const schemaFields = React81__default.useMemo(() => {
37191
+ const schemaFields = React82__default.useMemo(() => {
37007
37192
  if (normalizedFields.length === 0) return null;
37008
37193
  if (isDebugEnabled()) {
37009
37194
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -37013,7 +37198,7 @@ var init_Form = __esm({
37013
37198
  }
37014
37199
  return normalizedFields.map(renderField).filter(Boolean);
37015
37200
  }, [normalizedFields, renderField, entityName, conditionalFields]);
37016
- const sectionElements = React81__default.useMemo(() => {
37201
+ const sectionElements = React82__default.useMemo(() => {
37017
37202
  if (!sections || sections.length === 0) return null;
37018
37203
  return sections.map((section) => {
37019
37204
  if (!isSectionVisible(section)) {
@@ -37696,7 +37881,7 @@ var init_List = __esm({
37696
37881
  Box,
37697
37882
  {
37698
37883
  className: cn(
37699
- "h-full rounded-full transition-all duration-500",
37884
+ "h-full rounded-full transition-all duration-slow",
37700
37885
  clampedValue >= 100 ? "bg-success" : clampedValue >= 70 ? "bg-info" : clampedValue >= 40 ? "bg-warning" : "bg-muted-foreground"
37701
37886
  ),
37702
37887
  style: { width: `${clampedValue}%` }
@@ -37738,7 +37923,7 @@ var init_List = __esm({
37738
37923
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
37739
37924
  return [];
37740
37925
  }, [entity]);
37741
- const getItemActions = React81__default.useCallback(
37926
+ const getItemActions = React82__default.useCallback(
37742
37927
  (item) => {
37743
37928
  if (!itemActions) return [];
37744
37929
  if (typeof itemActions === "function") {
@@ -37865,7 +38050,7 @@ var init_List = __esm({
37865
38050
  {
37866
38051
  className: cn(
37867
38052
  "group flex items-center gap-5 px-6 py-5",
37868
- "transition-all duration-300 ease-out",
38053
+ "transition-all duration-normal ease-standard",
37869
38054
  hasExplicitClick && "cursor-pointer",
37870
38055
  // Hover state
37871
38056
  "hover:bg-muted/80",
@@ -37972,7 +38157,7 @@ var init_List = __esm({
37972
38157
  variant: "ghost",
37973
38158
  action: editAction.event,
37974
38159
  className: cn(
37975
- "p-2 rounded-lg transition-all duration-200",
38160
+ "p-2 rounded-lg transition-all duration-fast",
37976
38161
  "hover:bg-primary/10 hover:text-primary",
37977
38162
  "text-muted-foreground",
37978
38163
  "active:scale-95"
@@ -37988,7 +38173,7 @@ var init_List = __esm({
37988
38173
  variant: "ghost",
37989
38174
  action: viewAction.event,
37990
38175
  className: cn(
37991
- "p-2 rounded-lg transition-all duration-200",
38176
+ "p-2 rounded-lg transition-all duration-fast",
37992
38177
  "hover:bg-muted hover:text-foreground",
37993
38178
  "text-muted-foreground",
37994
38179
  "active:scale-95"
@@ -38010,7 +38195,7 @@ var init_List = __esm({
38010
38195
  {
38011
38196
  variant: "ghost",
38012
38197
  className: cn(
38013
- "p-2 rounded-lg transition-all duration-200",
38198
+ "p-2 rounded-lg transition-all duration-fast",
38014
38199
  "hover:bg-muted hover:shadow-sm",
38015
38200
  "text-muted-foreground hover:text-foreground",
38016
38201
  "active:scale-95"
@@ -38197,8 +38382,17 @@ var init_MediaGallery = __esm({
38197
38382
  const eventBus = useEventBus();
38198
38383
  const { t } = useTranslate();
38199
38384
  const [lightboxItem, setLightboxItem] = useState(null);
38385
+ const [failedIds, setFailedIds] = useState(/* @__PURE__ */ new Set());
38200
38386
  const closeLightbox = useCallback(() => setLightboxItem(null), []);
38201
38387
  useEventListener("UI:LIGHTBOX_CLOSE", closeLightbox);
38388
+ const handleImageError = useCallback((id) => {
38389
+ setFailedIds((prev) => {
38390
+ if (prev.has(id)) return prev;
38391
+ const next = new Set(prev);
38392
+ next.add(id);
38393
+ return next;
38394
+ });
38395
+ }, []);
38202
38396
  const handleItemClick = useCallback(
38203
38397
  (item) => {
38204
38398
  if (selectable) {
@@ -38213,8 +38407,8 @@ var init_MediaGallery = __esm({
38213
38407
  [selectable, selectedItems, selectionEvent, eventBus]
38214
38408
  );
38215
38409
  const entityData = Array.isArray(entity) ? entity : [];
38216
- const items = React81__default.useMemo(() => {
38217
- if (propItems) return propItems;
38410
+ const items = React82__default.useMemo(() => {
38411
+ if (propItems && propItems.length > 0) return propItems;
38218
38412
  if (entityData.length === 0) return [];
38219
38413
  return entityData.map((record, idx) => {
38220
38414
  return {
@@ -38291,19 +38485,20 @@ var init_MediaGallery = __esm({
38291
38485
  {
38292
38486
  className: cn(
38293
38487
  "group relative overflow-hidden rounded-md cursor-pointer",
38294
- "border-2 transition-all duration-200",
38488
+ "border-2 transition-all duration-fast",
38295
38489
  isSelected ? "border-primary ring-2 ring-primary/30" : "border-transparent hover:border-border",
38296
38490
  ASPECT_CLASSES[aspectRatio]
38297
38491
  ),
38298
38492
  onClick: () => handleItemClick(item),
38299
38493
  children: [
38300
- /* @__PURE__ */ jsx(
38494
+ failedIds.has(item.id) ? /* @__PURE__ */ jsx(Box, { className: "w-full h-full flex items-center justify-center bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx(Icon, { icon: Image$1, size: "lg" }) }) : /* @__PURE__ */ jsx(
38301
38495
  "img",
38302
38496
  {
38303
38497
  src: item.thumbnail || item.src,
38304
38498
  alt: item.alt || item.caption || "",
38305
38499
  className: "w-full h-full object-cover",
38306
- loading: "lazy"
38500
+ loading: "lazy",
38501
+ onError: () => handleImageError(item.id)
38307
38502
  }
38308
38503
  ),
38309
38504
  /* @__PURE__ */ jsx(
@@ -38311,14 +38506,14 @@ var init_MediaGallery = __esm({
38311
38506
  {
38312
38507
  className: cn(
38313
38508
  "absolute inset-0 bg-foreground/0 group-hover:bg-foreground/20",
38314
- "transition-colors duration-200 flex items-center justify-center"
38509
+ "transition-colors duration-fast flex items-center justify-center"
38315
38510
  ),
38316
38511
  children: /* @__PURE__ */ jsx(
38317
38512
  Icon,
38318
38513
  {
38319
38514
  icon: ZoomIn,
38320
38515
  size: "md",
38321
- className: "text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200"
38516
+ className: "text-white opacity-0 group-hover:opacity-100 transition-opacity duration-fast"
38322
38517
  }
38323
38518
  )
38324
38519
  }
@@ -38376,7 +38571,7 @@ var init_MediaGallery = __esm({
38376
38571
  }
38377
38572
  });
38378
38573
  function extractTitle2(children) {
38379
- if (!React81__default.isValidElement(children)) return void 0;
38574
+ if (!React82__default.isValidElement(children)) return void 0;
38380
38575
  const props = children.props;
38381
38576
  if (typeof props.title === "string") {
38382
38577
  return props.title;
@@ -38650,7 +38845,7 @@ var init_debugRegistry = __esm({
38650
38845
  }
38651
38846
  });
38652
38847
  function useDebugData() {
38653
- const [data, setData] = React81.useState(() => ({
38848
+ const [data, setData] = React82.useState(() => ({
38654
38849
  traits: [],
38655
38850
  ticks: [],
38656
38851
  guards: [],
@@ -38664,7 +38859,7 @@ function useDebugData() {
38664
38859
  },
38665
38860
  lastUpdate: Date.now()
38666
38861
  }));
38667
- React81.useEffect(() => {
38862
+ React82.useEffect(() => {
38668
38863
  const updateData = () => {
38669
38864
  setData({
38670
38865
  traits: getAllTraits(),
@@ -38773,12 +38968,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
38773
38968
  return positions;
38774
38969
  }
38775
38970
  function WalkMinimap() {
38776
- const [walkStep, setWalkStep] = React81.useState(null);
38777
- const [traits2, setTraits] = React81.useState([]);
38778
- const [coveredEdges, setCoveredEdges] = React81.useState([]);
38779
- const [completedTraits, setCompletedTraits] = React81.useState(/* @__PURE__ */ new Set());
38780
- const prevTraitRef = React81.useRef(null);
38781
- React81.useEffect(() => {
38971
+ const [walkStep, setWalkStep] = React82.useState(null);
38972
+ const [traits2, setTraits] = React82.useState([]);
38973
+ const [coveredEdges, setCoveredEdges] = React82.useState([]);
38974
+ const [completedTraits, setCompletedTraits] = React82.useState(/* @__PURE__ */ new Set());
38975
+ const prevTraitRef = React82.useRef(null);
38976
+ React82.useEffect(() => {
38782
38977
  const interval = setInterval(() => {
38783
38978
  const w = window;
38784
38979
  const step = w.__orbitalWalkStep;
@@ -39214,15 +39409,15 @@ var init_EntitiesTab = __esm({
39214
39409
  });
39215
39410
  function EventFlowTab({ events: events2 }) {
39216
39411
  const { t } = useTranslate();
39217
- const [filter, setFilter] = React81.useState("all");
39218
- const containerRef = React81.useRef(null);
39219
- const [autoScroll, setAutoScroll] = React81.useState(true);
39220
- React81.useEffect(() => {
39412
+ const [filter, setFilter] = React82.useState("all");
39413
+ const containerRef = React82.useRef(null);
39414
+ const [autoScroll, setAutoScroll] = React82.useState(true);
39415
+ React82.useEffect(() => {
39221
39416
  if (autoScroll && containerRef.current) {
39222
39417
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
39223
39418
  }
39224
39419
  }, [events2.length, autoScroll]);
39225
- const filteredEvents = React81.useMemo(() => {
39420
+ const filteredEvents = React82.useMemo(() => {
39226
39421
  if (filter === "all") return events2;
39227
39422
  return events2.filter((e) => e.type === filter);
39228
39423
  }, [events2, filter]);
@@ -39338,7 +39533,7 @@ var init_EventFlowTab = __esm({
39338
39533
  });
39339
39534
  function GuardsPanel({ guards }) {
39340
39535
  const { t } = useTranslate();
39341
- const [filter, setFilter] = React81.useState("all");
39536
+ const [filter, setFilter] = React82.useState("all");
39342
39537
  if (guards.length === 0) {
39343
39538
  return /* @__PURE__ */ jsx(
39344
39539
  EmptyState,
@@ -39351,7 +39546,7 @@ function GuardsPanel({ guards }) {
39351
39546
  }
39352
39547
  const passedCount = guards.filter((g) => g.result).length;
39353
39548
  const failedCount = guards.length - passedCount;
39354
- const filteredGuards = React81.useMemo(() => {
39549
+ const filteredGuards = React82.useMemo(() => {
39355
39550
  if (filter === "all") return guards;
39356
39551
  if (filter === "passed") return guards.filter((g) => g.result);
39357
39552
  return guards.filter((g) => !g.result);
@@ -39514,10 +39709,10 @@ function EffectBadge({ effect }) {
39514
39709
  }
39515
39710
  function TransitionTimeline({ transitions }) {
39516
39711
  const { t } = useTranslate();
39517
- const containerRef = React81.useRef(null);
39518
- const [autoScroll, setAutoScroll] = React81.useState(true);
39519
- const [expandedId, setExpandedId] = React81.useState(null);
39520
- React81.useEffect(() => {
39712
+ const containerRef = React82.useRef(null);
39713
+ const [autoScroll, setAutoScroll] = React82.useState(true);
39714
+ const [expandedId, setExpandedId] = React82.useState(null);
39715
+ React82.useEffect(() => {
39521
39716
  if (autoScroll && containerRef.current) {
39522
39717
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
39523
39718
  }
@@ -39797,9 +39992,9 @@ function getAllEvents(traits2) {
39797
39992
  function EventDispatcherTab({ traits: traits2, schema }) {
39798
39993
  const eventBus = useEventBus();
39799
39994
  const { t } = useTranslate();
39800
- const [log9, setLog] = React81.useState([]);
39801
- const prevStatesRef = React81.useRef(/* @__PURE__ */ new Map());
39802
- React81.useEffect(() => {
39995
+ const [log9, setLog] = React82.useState([]);
39996
+ const prevStatesRef = React82.useRef(/* @__PURE__ */ new Map());
39997
+ React82.useEffect(() => {
39803
39998
  for (const trait of traits2) {
39804
39999
  const prev = prevStatesRef.current.get(trait.id);
39805
40000
  if (prev && prev !== trait.currentState) {
@@ -39968,10 +40163,10 @@ function VerifyModePanel({
39968
40163
  localCount
39969
40164
  }) {
39970
40165
  const { t } = useTranslate();
39971
- const [expanded, setExpanded] = React81.useState(true);
39972
- const scrollRef = React81.useRef(null);
39973
- const prevCountRef = React81.useRef(0);
39974
- React81.useEffect(() => {
40166
+ const [expanded, setExpanded] = React82.useState(true);
40167
+ const scrollRef = React82.useRef(null);
40168
+ const prevCountRef = React82.useRef(0);
40169
+ React82.useEffect(() => {
39975
40170
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
39976
40171
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
39977
40172
  }
@@ -40028,10 +40223,10 @@ function RuntimeDebugger({
40028
40223
  schema
40029
40224
  }) {
40030
40225
  const { t } = useTranslate();
40031
- const [isCollapsed, setIsCollapsed] = React81.useState(mode === "verify" ? true : defaultCollapsed);
40032
- const [isVisible, setIsVisible] = React81.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
40226
+ const [isCollapsed, setIsCollapsed] = React82.useState(mode === "verify" ? true : defaultCollapsed);
40227
+ const [isVisible, setIsVisible] = React82.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
40033
40228
  const debugData = useDebugData();
40034
- React81.useEffect(() => {
40229
+ React82.useEffect(() => {
40035
40230
  if (mode === "inline") return;
40036
40231
  return onDebugToggle((enabled) => {
40037
40232
  setIsVisible(enabled);
@@ -40040,7 +40235,7 @@ function RuntimeDebugger({
40040
40235
  }
40041
40236
  });
40042
40237
  }, [mode]);
40043
- React81.useEffect(() => {
40238
+ React82.useEffect(() => {
40044
40239
  if (mode === "inline") return;
40045
40240
  const handleKeyDown = (e) => {
40046
40241
  if (e.key === "`" && isVisible) {
@@ -40560,7 +40755,7 @@ var init_StatCard = __esm({
40560
40755
  const labelToUse = propLabel ?? propTitle;
40561
40756
  const eventBus = useEventBus();
40562
40757
  const { t } = useTranslate();
40563
- const handleActionClick = React81__default.useCallback(() => {
40758
+ const handleActionClick = React82__default.useCallback(() => {
40564
40759
  if (action?.event) {
40565
40760
  eventBus.emit(`UI:${action.event}`, {});
40566
40761
  }
@@ -40571,7 +40766,7 @@ var init_StatCard = __esm({
40571
40766
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
40572
40767
  const isLoading = externalLoading ?? false;
40573
40768
  const error = externalError;
40574
- const computeMetricValue = React81__default.useCallback(
40769
+ const computeMetricValue = React82__default.useCallback(
40575
40770
  (metric, items) => {
40576
40771
  if (metric.value !== void 0) {
40577
40772
  return metric.value;
@@ -40610,7 +40805,7 @@ var init_StatCard = __esm({
40610
40805
  },
40611
40806
  []
40612
40807
  );
40613
- const schemaStats = React81__default.useMemo(() => {
40808
+ const schemaStats = React82__default.useMemo(() => {
40614
40809
  if (!metrics || metrics.length === 0) return null;
40615
40810
  return metrics.map((metric) => ({
40616
40811
  label: metric.label,
@@ -40618,7 +40813,7 @@ var init_StatCard = __esm({
40618
40813
  format: metric.format
40619
40814
  }));
40620
40815
  }, [metrics, data, computeMetricValue]);
40621
- const calculatedTrend = React81__default.useMemo(() => {
40816
+ const calculatedTrend = React82__default.useMemo(() => {
40622
40817
  if (manualTrend !== void 0) return manualTrend;
40623
40818
  if (previousValue === void 0 || currentValue === void 0)
40624
40819
  return void 0;
@@ -41258,8 +41453,8 @@ var init_SubagentTracePanel = __esm({
41258
41453
  ] });
41259
41454
  };
41260
41455
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
41261
- const endRef = React81__default.useRef(null);
41262
- React81__default.useEffect(() => {
41456
+ const endRef = React82__default.useRef(null);
41457
+ React82__default.useEffect(() => {
41263
41458
  if (!autoScroll) return;
41264
41459
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
41265
41460
  }, [activities.length, autoScroll]);
@@ -41353,7 +41548,7 @@ var init_SubagentTracePanel = __esm({
41353
41548
  };
41354
41549
  SubagentRichCard = ({ subagent }) => {
41355
41550
  const { t } = useTranslate();
41356
- const activities = React81__default.useMemo(
41551
+ const activities = React82__default.useMemo(
41357
41552
  () => subagentMessagesToActivities(subagent.messages),
41358
41553
  [subagent.messages]
41359
41554
  );
@@ -41430,8 +41625,8 @@ var init_SubagentTracePanel = __esm({
41430
41625
  ] });
41431
41626
  };
41432
41627
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
41433
- const endRef = React81__default.useRef(null);
41434
- React81__default.useEffect(() => {
41628
+ const endRef = React82__default.useRef(null);
41629
+ React82__default.useEffect(() => {
41435
41630
  if (!autoScroll) return;
41436
41631
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
41437
41632
  }, [messages.length, autoScroll]);
@@ -41810,6 +42005,11 @@ var init_TeamOrganism = __esm({
41810
42005
  TeamOrganism.displayName = "TeamOrganism";
41811
42006
  }
41812
42007
  });
42008
+ function formatDate4(value) {
42009
+ const d = new Date(value);
42010
+ if (isNaN(d.getTime())) return value;
42011
+ return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
42012
+ }
41813
42013
  var lookStyles10, STATUS_STYLES2, Timeline;
41814
42014
  var init_Timeline = __esm({
41815
42015
  "components/core/organisms/Timeline.tsx"() {
@@ -41861,7 +42061,7 @@ var init_Timeline = __esm({
41861
42061
  }) => {
41862
42062
  const { t } = useTranslate();
41863
42063
  const entityData = entity ?? [];
41864
- const items = React81__default.useMemo(() => {
42064
+ const items = React82__default.useMemo(() => {
41865
42065
  if (propItems) return propItems;
41866
42066
  if (entityData.length === 0) return [];
41867
42067
  return entityData.map((record, idx) => {
@@ -41937,7 +42137,7 @@ var init_Timeline = __esm({
41937
42137
  /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
41938
42138
  /* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
41939
42139
  /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
41940
- item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: item.date })
42140
+ item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: formatDate4(item.date) })
41941
42141
  ] }),
41942
42142
  item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
41943
42143
  item.tags && item.tags.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: item.tags.map((tag, tagIdx) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: tag }, tagIdx)) }),
@@ -41963,7 +42163,7 @@ var init_Timeline = __esm({
41963
42163
  }
41964
42164
  });
41965
42165
  function extractToastProps(children) {
41966
- if (!React81__default.isValidElement(children)) {
42166
+ if (!React82__default.isValidElement(children)) {
41967
42167
  if (typeof children === "string") {
41968
42168
  return { message: children };
41969
42169
  }
@@ -42005,7 +42205,7 @@ var init_ToastSlot = __esm({
42005
42205
  eventBus.emit(`${prefix}CLOSE`);
42006
42206
  };
42007
42207
  if (!isVisible) return null;
42008
- const isCustomContent = React81__default.isValidElement(children) && !message;
42208
+ const isCustomContent = React82__default.isValidElement(children) && !message;
42009
42209
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
42010
42210
  Toast,
42011
42211
  {
@@ -42053,6 +42253,7 @@ var init_component_registry_generated = __esm({
42053
42253
  init_LayoutPatterns();
42054
42254
  init_BranchingLogicBuilder();
42055
42255
  init_Breadcrumb();
42256
+ init_ButtonGroup();
42056
42257
  init_CTABanner();
42057
42258
  init_CalendarGrid();
42058
42259
  init_Canvas();
@@ -42123,8 +42324,8 @@ var init_component_registry_generated = __esm({
42123
42324
  init_FlipContainer();
42124
42325
  init_FloatingActionButton();
42125
42326
  init_Form();
42126
- init_FormSection();
42127
42327
  init_FormField();
42328
+ init_FormSection();
42128
42329
  init_FormSectionHeader();
42129
42330
  init_GameAudioToggle();
42130
42331
  init_GameHud();
@@ -42310,6 +42511,7 @@ var init_component_registry_generated = __esm({
42310
42511
  "BranchingLogicBuilder": BranchingLogicBuilder,
42311
42512
  "Breadcrumb": Breadcrumb,
42312
42513
  "Button": ButtonPattern,
42514
+ "ButtonGroup": ButtonGroup,
42313
42515
  "ButtonPattern": ButtonPattern,
42314
42516
  "CTABanner": CTABanner,
42315
42517
  "CalendarGrid": CalendarGrid,
@@ -42383,7 +42585,6 @@ var init_component_registry_generated = __esm({
42383
42585
  "FlipContainer": FlipContainer,
42384
42586
  "FloatingActionButton": FloatingActionButton,
42385
42587
  "Form": Form,
42386
- "FormActions": FormActions,
42387
42588
  "FormField": FormField,
42388
42589
  "FormLayout": FormLayout,
42389
42590
  "FormSectionHeader": FormSectionHeader,
@@ -42563,7 +42764,7 @@ function SuspenseConfigProvider({
42563
42764
  config,
42564
42765
  children
42565
42766
  }) {
42566
- return React81__default.createElement(
42767
+ return React82__default.createElement(
42567
42768
  SuspenseConfigContext.Provider,
42568
42769
  { value: config },
42569
42770
  children
@@ -42605,7 +42806,7 @@ function enrichFormFields(fields, entityDef) {
42605
42806
  }
42606
42807
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
42607
42808
  }
42608
- if (field && typeof field === "object" && !Array.isArray(field) && !React81__default.isValidElement(field) && !(field instanceof Date)) {
42809
+ if (field && typeof field === "object" && !Array.isArray(field) && !React82__default.isValidElement(field) && !(field instanceof Date)) {
42609
42810
  const obj = field;
42610
42811
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
42611
42812
  if (!fieldName) return field;
@@ -43058,7 +43259,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
43058
43259
  const key = `${parentId}-${index}-trait:${traitName}`;
43059
43260
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
43060
43261
  }
43061
- return /* @__PURE__ */ jsx(React81__default.Fragment, { children: child }, `${parentId}-${index}`);
43262
+ return /* @__PURE__ */ jsx(React82__default.Fragment, { children: child }, `${parentId}-${index}`);
43062
43263
  }
43063
43264
  if (!child || typeof child !== "object") return null;
43064
43265
  const childId = `${parentId}-${index}`;
@@ -43111,14 +43312,14 @@ function isPatternConfig(value) {
43111
43312
  if (value === null || value === void 0) return false;
43112
43313
  if (typeof value !== "object") return false;
43113
43314
  if (Array.isArray(value)) return false;
43114
- if (React81__default.isValidElement(value)) return false;
43315
+ if (React82__default.isValidElement(value)) return false;
43115
43316
  if (value instanceof Date) return false;
43116
43317
  if (typeof value === "function") return false;
43117
43318
  const record = value;
43118
43319
  return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
43119
43320
  }
43120
43321
  function isPlainConfigObject(value) {
43121
- if (React81__default.isValidElement(value)) return false;
43322
+ if (React82__default.isValidElement(value)) return false;
43122
43323
  if (value instanceof Date) return false;
43123
43324
  const proto = Object.getPrototypeOf(value);
43124
43325
  return proto === Object.prototype || proto === null;
@@ -43149,7 +43350,7 @@ function substituteTraitRefsDeep(value, pathKey) {
43149
43350
  }
43150
43351
  return value;
43151
43352
  }
43152
- function renderPatternProps(props, onDismiss) {
43353
+ function renderPatternProps(props, onDismiss, propsSchema) {
43153
43354
  const rendered = {};
43154
43355
  for (const [key, value] of Object.entries(props)) {
43155
43356
  if (key === "children") {
@@ -43167,9 +43368,10 @@ function renderPatternProps(props, onDismiss) {
43167
43368
  };
43168
43369
  rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
43169
43370
  } else if (Array.isArray(value)) {
43371
+ const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
43170
43372
  rendered[key] = value.map((item, i) => {
43171
43373
  const el = item;
43172
- if (isPatternConfig(el)) {
43374
+ if (!isDataArray && isPatternConfig(el)) {
43173
43375
  const nestedProps = {};
43174
43376
  for (const [k, v] of Object.entries(el)) {
43175
43377
  if (k !== "type") nestedProps[k] = v;
@@ -43245,7 +43447,7 @@ function SlotContentRenderer({
43245
43447
  for (const slotKey of CONTENT_NODE_SLOTS) {
43246
43448
  const slotVal = restProps[slotKey];
43247
43449
  if (slotVal === void 0 || slotVal === null) continue;
43248
- if (React81__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
43450
+ if (React82__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
43249
43451
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
43250
43452
  nodeSlotOverrides[slotKey] = renderPatternChildren(
43251
43453
  slotVal,
@@ -43257,14 +43459,15 @@ function SlotContentRenderer({
43257
43459
  );
43258
43460
  }
43259
43461
  }
43260
- const renderedProps = renderPatternProps(restProps, onDismiss);
43261
43462
  const patternDef = getPatternDefinition(content.pattern);
43262
43463
  const propsSchema = patternDef?.propsSchema;
43464
+ const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
43263
43465
  if (propsSchema) {
43264
43466
  for (const [propKey, propValue] of Object.entries(renderedProps)) {
43265
43467
  if (typeof propValue !== "string") continue;
43266
43468
  const propDef = propsSchema[propKey];
43267
43469
  if (!propDef || propDef.kind !== "callback") continue;
43470
+ if (propValue === "") continue;
43268
43471
  renderedProps[propKey] = wrapCallbackForEvent(
43269
43472
  `UI:${propValue}`,
43270
43473
  propDef.callbackArgs,
@@ -43297,7 +43500,7 @@ function SlotContentRenderer({
43297
43500
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
43298
43501
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
43299
43502
  const sample = resolvedItems[0];
43300
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React81__default.isValidElement(sample) && !(sample instanceof Date)) {
43503
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React82__default.isValidElement(sample) && !(sample instanceof Date)) {
43301
43504
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
43302
43505
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
43303
43506
  }
@@ -43547,6 +43750,7 @@ function useSharedEntityStore() {
43547
43750
  }
43548
43751
  return storeRef.current;
43549
43752
  }
43753
+ createContext(null);
43550
43754
  function runTickFrame(entityId, orderedWriters, store) {
43551
43755
  let scratch = store.getSnapshot(entityId);
43552
43756
  for (const writer of orderedWriters) {
@@ -43667,7 +43871,7 @@ function resolveLambdaBindings(body, params, item, index) {
43667
43871
  }
43668
43872
  return substituted;
43669
43873
  }
43670
- if (body !== null && typeof body === "object" && !React81__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
43874
+ if (body !== null && typeof body === "object" && !React82__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
43671
43875
  const out = {};
43672
43876
  for (const [k, v] of Object.entries(body)) {
43673
43877
  out[k] = recur(v);
@@ -43686,7 +43890,7 @@ function getSlotContentRenderer2() {
43686
43890
  function makeLambdaFn(params, lambdaBody, callerKey) {
43687
43891
  return (item, index) => {
43688
43892
  const resolvedBody = resolveLambdaBindings(lambdaBody, params, item, index);
43689
- if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React81__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
43893
+ if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React82__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
43690
43894
  return null;
43691
43895
  }
43692
43896
  const record = resolvedBody;
@@ -43705,7 +43909,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
43705
43909
  props: childProps,
43706
43910
  priority: 0
43707
43911
  };
43708
- return React81__default.createElement(SlotContentRenderer2, { content: childContent });
43912
+ return React82__default.createElement(SlotContentRenderer2, { content: childContent });
43709
43913
  };
43710
43914
  }
43711
43915
  function convertNode(node, callerKey) {
@@ -43724,7 +43928,7 @@ function convertNode(node, callerKey) {
43724
43928
  });
43725
43929
  return anyChanged ? mapped : node;
43726
43930
  }
43727
- if (typeof node === "object" && !React81__default.isValidElement(node) && !(node instanceof Date)) {
43931
+ if (typeof node === "object" && !React82__default.isValidElement(node) && !(node instanceof Date)) {
43728
43932
  return convertObjectProps(node);
43729
43933
  }
43730
43934
  return node;
@@ -43782,6 +43986,11 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
43782
43986
  "do",
43783
43987
  "when"
43784
43988
  ]);
43989
+ var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
43990
+ "canvas",
43991
+ "game-hud",
43992
+ "game-shell"
43993
+ ]);
43785
43994
  var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
43786
43995
  function toTraitDefinition(binding) {
43787
43996
  return {
@@ -44034,6 +44243,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44034
44243
  }, [traitStates]);
44035
44244
  const traitSnapshotDataRef = useRef(/* @__PURE__ */ new Map());
44036
44245
  const traitFieldStatesRef = useRef(/* @__PURE__ */ new Map());
44246
+ const lastCanvasRenderUiRef = useRef(/* @__PURE__ */ new Map());
44247
+ const executeTransitionEffectsRef = useRef(null);
44037
44248
  useEffect(() => {
44038
44249
  const mgr = managerRef.current;
44039
44250
  const bindings = traitBindingsRef.current;
@@ -44074,11 +44285,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44074
44285
  bindTraitStateGetter((traitName) => {
44075
44286
  const allStates = newManager.getAllStates();
44076
44287
  if (allStates instanceof Map) {
44077
- const val = allStates.get(traitName);
44078
- return typeof val === "string" ? val : void 0;
44288
+ return allStates.get(traitName)?.currentState;
44079
44289
  }
44080
- const state = newManager.getState(traitName);
44081
- return typeof state === "string" ? state : void 0;
44290
+ return newManager.getState(traitName)?.currentState;
44082
44291
  });
44083
44292
  const snapshotUnregs = [];
44084
44293
  for (const binding of traitBindingsRef.current) {
@@ -44163,6 +44372,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44163
44372
  const existing = pendingSlots.get(slot) || [];
44164
44373
  existing.push({ pattern, props: props || {} });
44165
44374
  pendingSlots.set(slot, existing);
44375
+ const patternType = pattern?.type;
44376
+ if (patternType !== void 0 && REACTIVE_REPAINT_PATTERN_TYPES.has(patternType)) {
44377
+ const rawForSlot = effects.filter(
44378
+ (e) => Array.isArray(e) && (e[0] === "render-ui" || e[0] === "render") && e[1] === slot
44379
+ );
44380
+ if (rawForSlot.length > 0) {
44381
+ lastCanvasRenderUiRef.current.set(traitName, rawForSlot);
44382
+ }
44383
+ }
44166
44384
  },
44167
44385
  clearSlot: (slot) => {
44168
44386
  pendingSlots.set(slot, []);
@@ -44233,11 +44451,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44233
44451
  notify: clientHandlers.notify
44234
44452
  };
44235
44453
  }
44454
+ const sharedWrites = [];
44236
44455
  const baseSet = handlers.set;
44237
44456
  handlers = {
44238
44457
  ...handlers,
44239
44458
  set: async (targetId, field, value) => {
44240
44459
  if (baseSet) await baseSet(targetId, field, value);
44460
+ if (sharedKey !== void 0) {
44461
+ sharedWrites.push({ field, value });
44462
+ }
44241
44463
  log9.debug("set:write", {
44242
44464
  traitName,
44243
44465
  field,
@@ -44313,7 +44535,10 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44313
44535
  });
44314
44536
  }
44315
44537
  if (sharedKey !== void 0) {
44316
- sharedEntityStore.commit(sharedKey, liveEntity);
44538
+ sharedEntityStore.commit(
44539
+ sharedKey,
44540
+ mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
44541
+ );
44317
44542
  }
44318
44543
  log9.debug("effects:executed", () => ({
44319
44544
  traitName,
@@ -44339,6 +44564,38 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44339
44564
  entity: binding.linkedEntity
44340
44565
  });
44341
44566
  }
44567
+ if (pendingSlots.size === 0 && effectsCallOp(effects, SHARED_ENTITY_WRITE_OPS)) {
44568
+ const stashed = lastCanvasRenderUiRef.current.get(traitName);
44569
+ if (stashed !== void 0 && stashed.length > 0) {
44570
+ await executor.executeAll(stashed);
44571
+ for (const [slot, patterns] of pendingSlots) {
44572
+ flushSlot(traitName, slot, patterns, {
44573
+ event: flushEvent,
44574
+ state: previousState,
44575
+ entity: binding.linkedEntity
44576
+ });
44577
+ }
44578
+ }
44579
+ if (sharedKey !== void 0 && executeTransitionEffectsRef.current !== null) {
44580
+ for (const sibling of traitBindingsRef.current) {
44581
+ const siblingName = sibling.trait.name;
44582
+ if (siblingName === traitName) continue;
44583
+ if (sharedKeyByTraitNameRef.current.get(siblingName) !== sharedKey) continue;
44584
+ const siblingStash = lastCanvasRenderUiRef.current.get(siblingName);
44585
+ if (siblingStash === void 0 || siblingStash.length === 0) continue;
44586
+ const siblingState = traitStatesRef.current.get(siblingName)?.currentState ?? "";
44587
+ await executeTransitionEffectsRef.current({
44588
+ binding: sibling,
44589
+ effects: siblingStash,
44590
+ previousState: siblingState,
44591
+ newState: siblingState,
44592
+ flushEvent: `${flushEvent}:repaint`,
44593
+ syncOnly,
44594
+ log: log9
44595
+ });
44596
+ }
44597
+ }
44598
+ }
44342
44599
  } catch (error) {
44343
44600
  log9.error("effects:error", {
44344
44601
  traitName,
@@ -44350,6 +44607,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44350
44607
  }
44351
44608
  return emittedDuringExec;
44352
44609
  }, [eventBus, flushSlot, sharedEntityStore]);
44610
+ useEffect(() => {
44611
+ executeTransitionEffectsRef.current = executeTransitionEffects;
44612
+ }, [executeTransitionEffects]);
44353
44613
  const runTickEffects = useCallback((tick, binding) => {
44354
44614
  const traitName = binding.trait.name;
44355
44615
  const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
@@ -44412,6 +44672,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44412
44672
  ({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
44413
44673
  );
44414
44674
  runTickFrame(group.storeKey, writers, sharedEntityStore);
44675
+ const repaint = executeTransitionEffectsRef.current;
44676
+ if (repaint !== null) {
44677
+ for (const renderBinding of group.renderBindings) {
44678
+ const renderTraitName = renderBinding.trait.name;
44679
+ const stash = lastCanvasRenderUiRef.current.get(renderTraitName);
44680
+ if (stash === void 0 || stash.length === 0) continue;
44681
+ const renderState = traitStatesRef.current.get(renderTraitName)?.currentState ?? "";
44682
+ void repaint({
44683
+ binding: renderBinding,
44684
+ effects: stash,
44685
+ previousState: renderState,
44686
+ newState: renderState,
44687
+ flushEvent: "tick:repaint",
44688
+ syncOnly: true,
44689
+ log: sharedEntityLog
44690
+ });
44691
+ }
44692
+ }
44415
44693
  };
44416
44694
  if (interval === "frame") {
44417
44695
  scheduler.add(0, onDue);
@@ -44461,6 +44739,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44461
44739
  entityByTrait[name] = fields;
44462
44740
  }
44463
44741
  }
44742
+ for (const binding of bindings) {
44743
+ const name = binding.trait.name;
44744
+ const sharedKey = sharedKeyByTraitNameRef.current.get(name);
44745
+ if (sharedKey !== void 0) {
44746
+ entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
44747
+ }
44748
+ }
44464
44749
  const results = currentManager.sendEvent(
44465
44750
  normalizedEvent,
44466
44751
  payload,
@@ -44614,7 +44899,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44614
44899
  }
44615
44900
  await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
44616
44901
  }
44617
- }, [entities, eventBus]);
44902
+ }, [entities, eventBus, sharedEntityStore]);
44618
44903
  const drainEventQueue = useCallback(async () => {
44619
44904
  if (processingRef.current) return;
44620
44905
  processingRef.current = true;
@@ -44684,6 +44969,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44684
44969
  });
44685
44970
  }
44686
44971
  }
44972
+ const bareCascadeKeys = /* @__PURE__ */ new Set();
44973
+ for (const binding of traitBindings) {
44974
+ for (const transition of binding.trait.transitions) {
44975
+ const eventKey = transition.event;
44976
+ if (LIFECYCLE_EVENTS.includes(eventKey)) continue;
44977
+ if (bareCascadeKeys.has(eventKey)) continue;
44978
+ bareCascadeKeys.add(eventKey);
44979
+ const bareKey = `UI:${eventKey}`;
44980
+ const unsub = eventBus.on(bareKey, (event) => {
44981
+ crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
44982
+ enqueueAndDrain(eventKey, event.payload);
44983
+ });
44984
+ unsubscribes.push(() => {
44985
+ crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
44986
+ unsub();
44987
+ });
44988
+ }
44989
+ }
44687
44990
  for (const binding of traitBindings) {
44688
44991
  const ownOrbital = orbitalsByTrait?.[binding.trait.name];
44689
44992
  const listens = binding.trait.listens ?? [];
@@ -44868,9 +45171,16 @@ function normalizeChild(child) {
44868
45171
  props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
44869
45172
  };
44870
45173
  }
44871
- function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
45174
+ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
44872
45175
  for (const eff of effects) {
44873
45176
  if (eff.type === "render-ui" && eff.slot && eff.pattern) {
45177
+ if (eff.traitName && activeTraits && !activeTraits.has(eff.traitName)) {
45178
+ xOrbitalLog.debug("slot:off-page-trait-skipped", {
45179
+ sourceTrait: eff.traitName,
45180
+ slot: eff.slot
45181
+ });
45182
+ continue;
45183
+ }
44874
45184
  const patternRecord = eff.pattern;
44875
45185
  const { type: patternType, children, ...inlineProps } = patternRecord;
44876
45186
  const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
@@ -44911,8 +45221,38 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
44911
45221
  }
44912
45222
  }
44913
45223
  }
44914
- function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
45224
+ function collectServerActiveTraits(ir, allTraits, mountedTraitNames) {
45225
+ if (!ir?.pages || ir.pages.size <= 1) return void 0;
45226
+ const pageBound = /* @__PURE__ */ new Set();
45227
+ for (const page of ir.pages.values()) {
45228
+ const queue = page.traits.map((b) => b.trait.name).filter((n) => !!n);
45229
+ for (const name of queue) {
45230
+ if (pageBound.has(name)) continue;
45231
+ pageBound.add(name);
45232
+ const rt = allTraits.get(name);
45233
+ if (!rt) continue;
45234
+ queue.push(...collectTraitRefsFromResolvedTrait(rt));
45235
+ }
45236
+ }
45237
+ const active = new Set(mountedTraitNames);
45238
+ for (const name of allTraits.keys()) {
45239
+ if (!pageBound.has(name)) active.add(name);
45240
+ }
45241
+ return active;
45242
+ }
45243
+ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits }) {
44915
45244
  const bridge = useServerBridge();
45245
+ const activeTraitNames = useMemo(
45246
+ () => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
45247
+ [traits2]
45248
+ );
45249
+ const withActiveTraits = useCallback(
45250
+ (payload) => {
45251
+ if (!serverActiveTraits || serverActiveTraits.size === 0) return payload;
45252
+ return { ...payload ?? {}, _activeTraits: Array.from(serverActiveTraits) };
45253
+ },
45254
+ [serverActiveTraits]
45255
+ );
44916
45256
  const uiSlots = useUISlots();
44917
45257
  const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
44918
45258
  if (!bridge.connected || !orbitalNames?.length) return;
@@ -44924,11 +45264,11 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
44924
45264
  dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
44925
45265
  }));
44926
45266
  for (const name of targets) {
44927
- const { effects, meta } = await bridge.sendEvent(name, event, payload);
45267
+ const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
44928
45268
  recordServerResponse(name, event, meta);
44929
- applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
45269
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
44930
45270
  }
44931
- }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
45271
+ }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
44932
45272
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
44933
45273
  const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
44934
45274
  const initSentRef = useRef(false);
@@ -44965,7 +45305,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
44965
45305
  initSentRef.current = true;
44966
45306
  (async () => {
44967
45307
  for (const name of orbitalNames) {
44968
- const { effects, meta } = await bridge.sendEvent(name, "INIT", {});
45308
+ const { effects, meta } = await bridge.sendEvent(name, "INIT", withActiveTraits({}));
44969
45309
  recordServerResponse(name, "INIT", meta);
44970
45310
  const effectTraces = [
44971
45311
  { type: "fetch", args: [], status: "executed" },
@@ -44983,10 +45323,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
44983
45323
  effects: effectTraces,
44984
45324
  timestamp: Date.now()
44985
45325
  });
44986
- applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
45326
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
44987
45327
  }
44988
45328
  })();
44989
- }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
45329
+ }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
44990
45330
  return null;
44991
45331
  }
44992
45332
  function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
@@ -45073,6 +45413,14 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
45073
45413
  }
45074
45414
  return Array.from(set);
45075
45415
  }, [allPageTraits, orbitalsByTrait]);
45416
+ const serverActiveTraits = useMemo(
45417
+ () => collectServerActiveTraits(
45418
+ ir,
45419
+ allTraits,
45420
+ new Set(allPageTraits.map((b) => b.trait.name).filter((n) => !!n))
45421
+ ),
45422
+ [ir, allTraits, allPageTraits]
45423
+ );
45076
45424
  useEffect(() => {
45077
45425
  const traitNames = allPageTraits.map((b) => b.trait.name);
45078
45426
  const orbitalsByTraitForPage = {};
@@ -45082,7 +45430,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
45082
45430
  }
45083
45431
  xOrbitalLog.info("SchemaRunner:mount", {
45084
45432
  pageName,
45085
- traitNames,
45433
+ traitNames: traitNames.join(","),
45086
45434
  orbitalsByTraitForPage,
45087
45435
  pageOrbitalNames: pageOrbitalNames.join(",")
45088
45436
  });
@@ -45127,6 +45475,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
45127
45475
  traitConfigsByName,
45128
45476
  orbitalsByTrait,
45129
45477
  embeddedTraits,
45478
+ serverActiveTraits,
45130
45479
  onNavigate,
45131
45480
  onLocalFallback,
45132
45481
  persistence