@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 React83 from 'react';
2
- import React83__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, lazy, useLayoutEffect, useId, useSyncExternalStore } from 'react';
3
- import { EventBusContext, useTraitScope, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
1
+ import * as React84 from 'react';
2
+ import React84__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, lazy, useLayoutEffect, useId, useSyncExternalStore } from 'react';
3
+ import { EventBusContext, useTraitScopeChain, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
4
4
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
@@ -94,9 +94,9 @@ function getGlobalEventBus() {
94
94
  function useEventBus() {
95
95
  const context = useContext(EventBusContext);
96
96
  const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
97
- const scope = useTraitScope();
97
+ const chain = useTraitScopeChain();
98
98
  return useMemo(() => {
99
- if (!scope) {
99
+ if (chain.length === 0) {
100
100
  return {
101
101
  ...baseBus,
102
102
  emit: (type, payload, source) => {
@@ -112,22 +112,31 @@ function useEventBus() {
112
112
  emit: (type, payload, source) => {
113
113
  if (typeof type === "string" && type.startsWith("UI:")) {
114
114
  const tail = type.slice(3);
115
- const qualified = tail.includes(".") ? type : `UI:${scope.orbital}.${scope.trait}.${tail}`;
116
- if (qualified !== type) {
117
- scopeLog.info("emit:qualified", {
115
+ const isQualified = tail.includes(".");
116
+ const event = isQualified ? tail.split(".").slice(2).join(".") : tail;
117
+ if (!event) {
118
+ baseBus.emit(type, payload, source);
119
+ return;
120
+ }
121
+ const keys = /* @__PURE__ */ new Set();
122
+ if (isQualified) keys.add(type);
123
+ for (const sc of chain) {
124
+ keys.add(`UI:${sc.orbital}.${sc.trait}.${event}`);
125
+ }
126
+ if (keys.size > 1) {
127
+ scopeLog.info("emit:fan-out", {
118
128
  from: type,
119
- to: qualified,
120
- scopeOrbital: scope.orbital,
121
- scopeTrait: scope.trait
129
+ keys: Array.from(keys),
130
+ chainDepth: chain.length
122
131
  });
123
132
  }
124
- baseBus.emit(qualified, payload, source);
133
+ for (const key of keys) baseBus.emit(key, payload, source);
125
134
  return;
126
135
  }
127
136
  baseBus.emit(type, payload, source);
128
137
  }
129
138
  };
130
- }, [baseBus, scope]);
139
+ }, [baseBus, chain]);
131
140
  }
132
141
  function useEventListener(event, handler) {
133
142
  const eventBus = useEventBus();
@@ -390,7 +399,7 @@ var init_Box = __esm({
390
399
  fixed: "fixed",
391
400
  sticky: "sticky"
392
401
  };
393
- Box = React83__default.forwardRef(
402
+ Box = React84__default.forwardRef(
394
403
  ({
395
404
  padding,
396
405
  paddingX,
@@ -455,7 +464,7 @@ var init_Box = __esm({
455
464
  onPointerDown?.(e);
456
465
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
457
466
  const isClickable = action || onClick;
458
- return React83__default.createElement(
467
+ return React84__default.createElement(
459
468
  Component,
460
469
  {
461
470
  ref,
@@ -669,13 +678,13 @@ var init_Icon = __esm({
669
678
  style
670
679
  }) => {
671
680
  const directIcon = typeof icon === "string" ? void 0 : icon;
672
- const effectiveName = typeof icon === "string" ? icon : name;
681
+ const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
682
+ const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
673
683
  const family = useIconFamily();
674
- const RenderedComponent = React83__default.useMemo(() => {
684
+ const RenderedComponent = React84__default.useMemo(() => {
675
685
  if (directIcon) return null;
676
686
  return effectiveName ? resolveIconForFamily(effectiveName) : null;
677
687
  }, [directIcon, effectiveName, family]);
678
- const effectiveStrokeWidth = strokeWidth ?? void 0;
679
688
  const inlineStyle = {
680
689
  ...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
681
690
  ...style
@@ -792,7 +801,7 @@ var init_atlasSlice = __esm({
792
801
  }
793
802
  });
794
803
  function useAtlasSliceDataUrl(asset) {
795
- const [, bump] = React83.useReducer((x) => x + 1, 0);
804
+ const [, bump] = React84.useReducer((x) => x + 1, 0);
796
805
  if (!isAtlasAsset(asset)) return void 0;
797
806
  const key = `${asset.atlas}#${asset.sprite}`;
798
807
  const cached = sliceDataUrlCache.get(key);
@@ -855,13 +864,13 @@ function AtlasImage({
855
864
  style,
856
865
  "aria-hidden": ariaHidden
857
866
  }) {
858
- const [, bump] = React83.useReducer((x) => x + 1, 0);
859
- const canvasRef = React83.useRef(null);
867
+ const [, bump] = React84.useReducer((x) => x + 1, 0);
868
+ const canvasRef = React84.useRef(null);
860
869
  const sliced = isAtlasAsset(asset);
861
870
  const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
862
871
  const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
863
872
  const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
864
- React83.useEffect(() => {
873
+ React84.useEffect(() => {
865
874
  const canvas = canvasRef.current;
866
875
  if (!canvas || !img || !rect) return;
867
876
  canvas.width = rect.sw;
@@ -937,7 +946,7 @@ function resolveIconProp(value, sizeClass) {
937
946
  const IconComp = value;
938
947
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
939
948
  }
940
- if (React83__default.isValidElement(value)) {
949
+ if (React84__default.isValidElement(value)) {
941
950
  return value;
942
951
  }
943
952
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -1014,7 +1023,7 @@ var init_Button = __esm({
1014
1023
  md: "h-icon-default w-icon-default",
1015
1024
  lg: "h-icon-default w-icon-default"
1016
1025
  };
1017
- Button = React83__default.forwardRef(
1026
+ Button = React84__default.forwardRef(
1018
1027
  ({
1019
1028
  className,
1020
1029
  variant = "primary",
@@ -1056,7 +1065,8 @@ var init_Button = __esm({
1056
1065
  "font-medium",
1057
1066
  "rounded-sm",
1058
1067
  "cursor-pointer",
1059
- "transition-all duration-[var(--transition-normal)]",
1068
+ "chrome-button",
1069
+ "transition-all duration-normal",
1060
1070
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-offset-[length:var(--focus-ring-offset)]",
1061
1071
  "disabled:opacity-50 disabled:cursor-not-allowed",
1062
1072
  variantStyles[variant],
@@ -1082,7 +1092,7 @@ var Dialog;
1082
1092
  var init_Dialog = __esm({
1083
1093
  "components/core/atoms/Dialog.tsx"() {
1084
1094
  init_cn();
1085
- Dialog = React83__default.forwardRef(
1095
+ Dialog = React84__default.forwardRef(
1086
1096
  ({
1087
1097
  role = "dialog",
1088
1098
  "aria-modal": ariaModal = true,
@@ -1200,7 +1210,7 @@ var init_Typography = __esm({
1200
1210
  }) => {
1201
1211
  const variant = variantProp ?? (level ? `h${level}` : "body1");
1202
1212
  const Component = as || defaultElements[variant];
1203
- return React83__default.createElement(
1213
+ return React84__default.createElement(
1204
1214
  Component,
1205
1215
  {
1206
1216
  id,
@@ -1275,6 +1285,15 @@ var init_Modal = __esm({
1275
1285
  const [dragY, setDragY] = useState(0);
1276
1286
  const dragStartY = useRef(0);
1277
1287
  const isDragging = useRef(false);
1288
+ const [closing, setClosing] = useState(false);
1289
+ const wasOpenRef = useRef(isOpen);
1290
+ useEffect(() => {
1291
+ if (wasOpenRef.current && !isOpen) setClosing(true);
1292
+ wasOpenRef.current = isOpen;
1293
+ }, [isOpen]);
1294
+ const handleAnimEnd = (e) => {
1295
+ if (closing && e.target === e.currentTarget) setClosing(false);
1296
+ };
1278
1297
  useEffect(() => {
1279
1298
  if (isOpen) {
1280
1299
  previousActiveElement.current = document.activeElement;
@@ -1308,7 +1327,11 @@ var init_Modal = __esm({
1308
1327
  document.body.style.overflow = "";
1309
1328
  };
1310
1329
  }, [isOpen]);
1311
- if (!isOpen || typeof document === "undefined") return null;
1330
+ if (typeof document === "undefined") return null;
1331
+ const renderOpen = isOpen || closing;
1332
+ if (!renderOpen) return null;
1333
+ const dialogAnim = closing ? "animate-modal-out" : "animate-modal-in";
1334
+ const overlayAnim = closing ? "animate-overlay-out" : "animate-overlay-in";
1312
1335
  const handleClose = () => {
1313
1336
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
1314
1337
  onClose();
@@ -1325,7 +1348,8 @@ var init_Modal = __esm({
1325
1348
  className: cn(
1326
1349
  "fixed inset-0 z-[1000]",
1327
1350
  "flex items-start justify-center px-4 pb-4 pt-[10vh]",
1328
- "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
1351
+ "max-sm:items-stretch max-sm:p-0 max-sm:pt-0",
1352
+ overlayAnim
1329
1353
  ),
1330
1354
  style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
1331
1355
  onClick: handleOverlayClick,
@@ -1353,8 +1377,10 @@ var init_Modal = __esm({
1353
1377
  // full height, no rounded corners, no min-width.
1354
1378
  "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
1355
1379
  lookStyles[look],
1356
- className
1380
+ className,
1381
+ dialogAnim
1357
1382
  ),
1383
+ onAnimationEnd: handleAnimEnd,
1358
1384
  style: dragY > 0 ? {
1359
1385
  transform: `translateY(${dragY}px)`,
1360
1386
  transition: isDragging.current ? "none" : "transform 200ms ease-out"
@@ -1436,12 +1462,84 @@ var init_Modal = __esm({
1436
1462
  Modal.displayName = "Modal";
1437
1463
  }
1438
1464
  });
1465
+ function isMotionEnabled() {
1466
+ if (typeof document === "undefined") return true;
1467
+ if (motionEnabledCache !== null) return motionEnabledCache;
1468
+ const v = getComputedStyle(document.documentElement).getPropertyValue("--motion-enable").trim().toLowerCase();
1469
+ motionEnabledCache = v !== "off";
1470
+ return motionEnabledCache;
1471
+ }
1472
+ function usePresence(show, opts) {
1473
+ const { animation, animate = true, onExited } = opts;
1474
+ const [mounted, setMounted] = useState(show);
1475
+ const [exiting, setExiting] = useState(false);
1476
+ const prev = useRef(show);
1477
+ const onExitedRef = useRef(onExited);
1478
+ onExitedRef.current = onExited;
1479
+ const safeTimer = useRef(null);
1480
+ const clearSafe = useCallback(() => {
1481
+ if (safeTimer.current) {
1482
+ clearTimeout(safeTimer.current);
1483
+ safeTimer.current = null;
1484
+ }
1485
+ }, []);
1486
+ const finishExit = useCallback(() => {
1487
+ clearSafe();
1488
+ setExiting(false);
1489
+ setMounted(false);
1490
+ onExitedRef.current?.();
1491
+ }, [clearSafe]);
1492
+ useEffect(() => {
1493
+ const moving = animate && isMotionEnabled();
1494
+ if (show && !prev.current) {
1495
+ setExiting(false);
1496
+ setMounted(true);
1497
+ } else if (!show && prev.current) {
1498
+ if (moving) {
1499
+ setExiting(true);
1500
+ clearSafe();
1501
+ safeTimer.current = setTimeout(finishExit, SAFE_EXIT_MS);
1502
+ } else {
1503
+ setMounted(false);
1504
+ setExiting(false);
1505
+ }
1506
+ }
1507
+ prev.current = show;
1508
+ }, [show, animate, clearSafe, finishExit]);
1509
+ useEffect(() => () => clearSafe(), [clearSafe]);
1510
+ const disabled = !animate || !isMotionEnabled();
1511
+ const className = disabled ? "" : exiting ? `animate-${animation}-out` : `animate-${animation}-in`;
1512
+ const onAnimationEnd = useCallback(
1513
+ (e) => {
1514
+ if (e.target !== e.currentTarget) return;
1515
+ if (exiting) finishExit();
1516
+ },
1517
+ [exiting, finishExit]
1518
+ );
1519
+ return { mounted, exiting, className, onAnimationEnd };
1520
+ }
1521
+ var SAFE_EXIT_MS, motionEnabledCache, Presence;
1522
+ var init_Presence = __esm({
1523
+ "components/core/atoms/Presence.tsx"() {
1524
+ "use client";
1525
+ init_cn();
1526
+ SAFE_EXIT_MS = 1e3;
1527
+ motionEnabledCache = null;
1528
+ Presence = ({ show, className, children, ...opts }) => {
1529
+ const { mounted, className: animClass, onAnimationEnd } = usePresence(show, opts);
1530
+ if (!mounted) return null;
1531
+ return /* @__PURE__ */ jsx("div", { className: cn(animClass, className), onAnimationEnd, children });
1532
+ };
1533
+ Presence.displayName = "Presence";
1534
+ }
1535
+ });
1439
1536
  var Overlay;
1440
1537
  var init_Overlay = __esm({
1441
1538
  "components/core/atoms/Overlay.tsx"() {
1442
1539
  "use client";
1443
1540
  init_cn();
1444
1541
  init_useEventBus();
1542
+ init_Presence();
1445
1543
  Overlay = ({
1446
1544
  isVisible = true,
1447
1545
  onClick,
@@ -1450,7 +1548,8 @@ var init_Overlay = __esm({
1450
1548
  action
1451
1549
  }) => {
1452
1550
  const eventBus = useEventBus();
1453
- if (!isVisible) return null;
1551
+ const { mounted, className: animClass, onAnimationEnd } = usePresence(isVisible, { animation: "overlay" });
1552
+ if (!mounted) return null;
1454
1553
  const handleClick = (e) => {
1455
1554
  if (action) {
1456
1555
  eventBus.emit(`UI:${action}`, {});
@@ -1463,10 +1562,12 @@ var init_Overlay = __esm({
1463
1562
  className: cn(
1464
1563
  "fixed inset-0 z-40",
1465
1564
  blur && "backdrop-blur-sm",
1565
+ animClass,
1466
1566
  className
1467
1567
  ),
1468
1568
  style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
1469
1569
  onClick: action || onClick ? handleClick : void 0,
1570
+ onAnimationEnd,
1470
1571
  "aria-hidden": "true"
1471
1572
  }
1472
1573
  );
@@ -1481,6 +1582,7 @@ var init_Drawer = __esm({
1481
1582
  init_Button();
1482
1583
  init_Typography();
1483
1584
  init_Overlay();
1585
+ init_Presence();
1484
1586
  init_cn();
1485
1587
  init_useEventBus();
1486
1588
  sizeWidths = {
@@ -1534,6 +1636,7 @@ var init_Drawer = __esm({
1534
1636
  document.addEventListener("keydown", handleEscape);
1535
1637
  return () => document.removeEventListener("keydown", handleEscape);
1536
1638
  }, [isOpen, closeOnEscape, onClose, closeEvent, eventBus]);
1639
+ const { mounted, className: drawerAnim, onAnimationEnd } = usePresence(isOpen, { animation: "drawer" });
1537
1640
  useEffect(() => {
1538
1641
  if (isOpen) {
1539
1642
  document.body.style.overflow = "hidden";
@@ -1544,7 +1647,7 @@ var init_Drawer = __esm({
1544
1647
  document.body.style.overflow = "";
1545
1648
  };
1546
1649
  }, [isOpen]);
1547
- if (!isOpen) return null;
1650
+ if (!mounted) return null;
1548
1651
  const handleClose = () => {
1549
1652
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
1550
1653
  onClose();
@@ -1557,7 +1660,7 @@ var init_Drawer = __esm({
1557
1660
  const widthClass = width in sizeWidths ? sizeWidths[width] : "";
1558
1661
  const widthStyle = width in sizeWidths ? void 0 : { width };
1559
1662
  const positionClasses = position === "right" ? "right-0 border-l" : "left-0 border-r";
1560
- const animationClasses2 = position === "right" ? "animate-slide-in-right" : "animate-slide-in-left";
1663
+ const drawerSign = position === "right" ? 1 : -1;
1561
1664
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1562
1665
  /* @__PURE__ */ jsx(
1563
1666
  Overlay,
@@ -1579,12 +1682,13 @@ var init_Drawer = __esm({
1579
1682
  "flex flex-col max-h-screen",
1580
1683
  positionClasses,
1581
1684
  widthClass,
1582
- animationClasses2,
1685
+ drawerAnim,
1583
1686
  className
1584
1687
  ),
1585
- style: widthStyle,
1688
+ style: { ...widthStyle, "--motion-drawer-sign": drawerSign },
1586
1689
  role: "dialog",
1587
1690
  "aria-modal": "true",
1691
+ onAnimationEnd,
1588
1692
  ...title && { "aria-labelledby": "drawer-title" },
1589
1693
  children: [
1590
1694
  (title || showCloseButton) && /* @__PURE__ */ jsxs(
@@ -1623,31 +1727,7 @@ var init_Drawer = __esm({
1623
1727
  )
1624
1728
  ]
1625
1729
  }
1626
- ),
1627
- /* @__PURE__ */ jsx("style", { children: `
1628
- @keyframes slide-in-right {
1629
- from {
1630
- transform: translateX(100%);
1631
- }
1632
- to {
1633
- transform: translateX(0);
1634
- }
1635
- }
1636
- @keyframes slide-in-left {
1637
- from {
1638
- transform: translateX(-100%);
1639
- }
1640
- to {
1641
- transform: translateX(0);
1642
- }
1643
- }
1644
- .animate-slide-in-right {
1645
- animation: slide-in-right 0.3s ease-out;
1646
- }
1647
- .animate-slide-in-left {
1648
- animation: slide-in-left 0.3s ease-out;
1649
- }
1650
- ` })
1730
+ )
1651
1731
  ] });
1652
1732
  };
1653
1733
  Drawer.displayName = "Drawer";
@@ -1696,7 +1776,7 @@ var init_Badge = __esm({
1696
1776
  md: "px-2.5 py-1 text-sm",
1697
1777
  lg: "px-3 py-1.5 text-base"
1698
1778
  };
1699
- Badge = React83__default.forwardRef(
1779
+ Badge = React84__default.forwardRef(
1700
1780
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
1701
1781
  const iconSizes3 = {
1702
1782
  sm: "h-icon-default w-icon-default",
@@ -1791,14 +1871,23 @@ var init_Toast = __esm({
1791
1871
  }) => {
1792
1872
  const eventBus = useEventBus();
1793
1873
  const { t } = useTranslate();
1794
- const handleDismiss = () => {
1874
+ const [leaving, setLeaving] = useState(false);
1875
+ const doRealDismiss = () => {
1795
1876
  if (dismissEvent) eventBus.emit(`UI:${dismissEvent}`, {});
1796
1877
  onDismiss?.();
1797
1878
  };
1879
+ const handleDismiss = () => {
1880
+ if (leaving) return;
1881
+ setLeaving(true);
1882
+ };
1798
1883
  const handleAction = () => {
1799
1884
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, {});
1800
1885
  onAction?.();
1801
1886
  };
1887
+ const handleAnimEnd = (e) => {
1888
+ if (e.target !== e.currentTarget) return;
1889
+ if (leaving) doRealDismiss();
1890
+ };
1802
1891
  useEffect(() => {
1803
1892
  if (duration <= 0 || !onDismiss && !dismissEvent) {
1804
1893
  return;
@@ -1817,10 +1906,12 @@ var init_Toast = __esm({
1817
1906
  // edge. `max-w-[calc(100vw-2rem)]` clamps to viewport too.
1818
1907
  "border-l-4 p-4 shadow-elevation-toast min-w-0 sm:min-w-[300px] max-w-md max-w-[calc(100vw-2rem)]",
1819
1908
  "rounded-sm",
1909
+ leaving ? "animate-toast-out" : "animate-toast-in",
1820
1910
  variantClasses[variant],
1821
1911
  className
1822
1912
  ),
1823
1913
  role: "alert",
1914
+ onAnimationEnd: handleAnimEnd,
1824
1915
  children: /* @__PURE__ */ jsxs(Box, { className: "flex items-start gap-3", children: [
1825
1916
  /* @__PURE__ */ jsx(Box, { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx(
1826
1917
  Icon,
@@ -2033,7 +2124,7 @@ var init_SvgFlow = __esm({
2033
2124
  width = 100,
2034
2125
  height = 100
2035
2126
  }) => {
2036
- const markerId = React83__default.useMemo(() => {
2127
+ const markerId = React84__default.useMemo(() => {
2037
2128
  flowIdCounter += 1;
2038
2129
  return `almadar-flow-arrow-${flowIdCounter}`;
2039
2130
  }, []);
@@ -2626,7 +2717,7 @@ var init_SvgRing = __esm({
2626
2717
  width = 100,
2627
2718
  height = 100
2628
2719
  }) => {
2629
- const gradientId = React83__default.useMemo(() => {
2720
+ const gradientId = React84__default.useMemo(() => {
2630
2721
  ringIdCounter += 1;
2631
2722
  return `almadar-ring-glow-${ringIdCounter}`;
2632
2723
  }, []);
@@ -2807,7 +2898,7 @@ var init_Input = __esm({
2807
2898
  init_cn();
2808
2899
  init_Icon();
2809
2900
  init_useEventBus();
2810
- Input = React83__default.forwardRef(
2901
+ Input = React84__default.forwardRef(
2811
2902
  ({
2812
2903
  className,
2813
2904
  inputType,
@@ -2842,7 +2933,7 @@ var init_Input = __esm({
2842
2933
  const showClearButton = clearable && value && String(value).length > 0;
2843
2934
  const isMultiline = type === "textarea";
2844
2935
  const baseClassName = cn(
2845
- "block w-full rounded-sm transition-all duration-[var(--transition-fast)]",
2936
+ "block w-full rounded-sm transition-all duration-fast",
2846
2937
  "border-[length:var(--border-width-thin)] border-border",
2847
2938
  isMultiline ? "px-3 py-2 text-sm" : "h-input-md px-3 text-sm",
2848
2939
  "bg-card hover:bg-muted focus:bg-card",
@@ -2875,7 +2966,7 @@ var init_Input = __esm({
2875
2966
  eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
2876
2967
  }
2877
2968
  };
2878
- const wrapField = (field) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
2969
+ const wrapField = (field, fullWidth = true) => /* @__PURE__ */ jsxs("div", { className: fullWidth ? "w-full" : "w-fit", children: [
2879
2970
  label && /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
2880
2971
  field,
2881
2972
  (helperText || error) && /* @__PURE__ */ jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
@@ -2935,7 +3026,8 @@ var init_Input = __esm({
2935
3026
  ),
2936
3027
  ...props
2937
3028
  }
2938
- )
3029
+ ),
3030
+ false
2939
3031
  );
2940
3032
  }
2941
3033
  return wrapField(
@@ -2974,7 +3066,7 @@ var Label;
2974
3066
  var init_Label = __esm({
2975
3067
  "components/core/atoms/Label.tsx"() {
2976
3068
  init_cn();
2977
- Label = React83__default.forwardRef(
3069
+ Label = React84__default.forwardRef(
2978
3070
  ({ className, required, children, ...props }, ref) => {
2979
3071
  return /* @__PURE__ */ jsxs(
2980
3072
  "label",
@@ -3001,7 +3093,7 @@ var init_Textarea = __esm({
3001
3093
  "components/core/atoms/Textarea.tsx"() {
3002
3094
  init_cn();
3003
3095
  init_useEventBus();
3004
- Textarea = React83__default.forwardRef(
3096
+ Textarea = React84__default.forwardRef(
3005
3097
  ({ className, error, onChange, ...props }, ref) => {
3006
3098
  const eventBus = useEventBus();
3007
3099
  const handleChange = (e) => {
@@ -3240,7 +3332,7 @@ var init_Select = __esm({
3240
3332
  init_cn();
3241
3333
  init_Icon();
3242
3334
  init_useEventBus();
3243
- Select = React83__default.forwardRef(
3335
+ Select = React84__default.forwardRef(
3244
3336
  (props, _ref) => {
3245
3337
  const { multiple, searchable, clearable } = props;
3246
3338
  if (multiple || searchable || clearable) {
@@ -3257,7 +3349,7 @@ var init_Checkbox = __esm({
3257
3349
  "components/core/atoms/Checkbox.tsx"() {
3258
3350
  init_cn();
3259
3351
  init_useEventBus();
3260
- Checkbox = React83__default.forwardRef(
3352
+ Checkbox = React84__default.forwardRef(
3261
3353
  ({ className, label, id, onChange, ...props }, ref) => {
3262
3354
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
3263
3355
  const eventBus = useEventBus();
@@ -3311,7 +3403,7 @@ var init_Spinner = __esm({
3311
3403
  md: "h-6 w-6",
3312
3404
  lg: "h-8 w-8"
3313
3405
  };
3314
- Spinner = React83__default.forwardRef(
3406
+ Spinner = React84__default.forwardRef(
3315
3407
  ({ className, size = "md", overlay, ...props }, ref) => {
3316
3408
  if (overlay) {
3317
3409
  return /* @__PURE__ */ jsx(
@@ -3353,21 +3445,21 @@ var init_Card = __esm({
3353
3445
  "bg-card",
3354
3446
  "border-[length:var(--border-width)] border-border",
3355
3447
  "shadow-elevation-card",
3356
- "transition-all duration-[var(--transition-normal)]",
3448
+ "transition-all duration-normal",
3357
3449
  "hover:shadow-elevation-dialog hover:translate-y-[var(--hover-translate-y)]"
3358
3450
  ].join(" "),
3359
3451
  bordered: [
3360
3452
  "bg-card",
3361
3453
  "border-[length:var(--border-width)] border-border",
3362
3454
  "shadow-elevation-card",
3363
- "transition-all duration-[var(--transition-normal)]",
3455
+ "transition-all duration-normal",
3364
3456
  "hover:shadow-elevation-dialog hover:translate-y-[var(--hover-translate-y)]"
3365
3457
  ].join(" "),
3366
3458
  elevated: [
3367
3459
  "bg-card",
3368
3460
  "border-[length:var(--border-width)] border-border",
3369
3461
  "shadow",
3370
- "transition-all duration-[var(--transition-normal)]",
3462
+ "transition-all duration-normal",
3371
3463
  "hover:shadow-elevation-dialog hover:translate-y-[var(--hover-translate-y)]"
3372
3464
  ].join(" "),
3373
3465
  // Interactive variant with theme-specific hover effects
@@ -3376,7 +3468,7 @@ var init_Card = __esm({
3376
3468
  "border-[length:var(--border-width)] border-border",
3377
3469
  "shadow",
3378
3470
  "cursor-pointer",
3379
- "transition-all duration-[var(--transition-normal)]",
3471
+ "transition-all duration-normal",
3380
3472
  "hover:shadow-elevation-dialog"
3381
3473
  ].join(" ")
3382
3474
  };
@@ -3401,7 +3493,7 @@ var init_Card = __esm({
3401
3493
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
3402
3494
  "tile-image-first": "p-0 overflow-hidden"
3403
3495
  };
3404
- Card = React83__default.forwardRef(
3496
+ Card = React84__default.forwardRef(
3405
3497
  ({
3406
3498
  className,
3407
3499
  variant = "bordered",
@@ -3427,7 +3519,8 @@ var init_Card = __esm({
3427
3519
  ref,
3428
3520
  className: cn(
3429
3521
  "rounded-container relative",
3430
- "transition-all duration-[var(--transition-normal)]",
3522
+ "transition-all duration-normal",
3523
+ "chrome-panel",
3431
3524
  variantStyles4[variant],
3432
3525
  paddingStyles2[padding],
3433
3526
  lookStyles2[look],
@@ -3449,9 +3542,9 @@ var init_Card = __esm({
3449
3542
  }
3450
3543
  );
3451
3544
  Card.displayName = "Card";
3452
- CardHeader = React83__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3545
+ CardHeader = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3453
3546
  CardHeader.displayName = "CardHeader";
3454
- CardTitle = React83__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3547
+ CardTitle = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3455
3548
  "h3",
3456
3549
  {
3457
3550
  ref,
@@ -3464,11 +3557,11 @@ var init_Card = __esm({
3464
3557
  }
3465
3558
  ));
3466
3559
  CardTitle.displayName = "CardTitle";
3467
- CardContent = React83__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3560
+ CardContent = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3468
3561
  CardContent.displayName = "CardContent";
3469
3562
  CardBody = CardContent;
3470
3563
  CardBody.displayName = "CardBody";
3471
- CardFooter = React83__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3564
+ CardFooter = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3472
3565
  "div",
3473
3566
  {
3474
3567
  ref,
@@ -3555,7 +3648,7 @@ var init_FilterPill = __esm({
3555
3648
  md: "w-3.5 h-3.5",
3556
3649
  lg: "w-4 h-4"
3557
3650
  };
3558
- FilterPill = React83__default.forwardRef(
3651
+ FilterPill = React84__default.forwardRef(
3559
3652
  ({
3560
3653
  className,
3561
3654
  variant = "default",
@@ -3684,8 +3777,8 @@ var init_Avatar = __esm({
3684
3777
  actionPayload
3685
3778
  }) => {
3686
3779
  const eventBus = useEventBus();
3687
- const [imgFailed, setImgFailed] = React83__default.useState(false);
3688
- React83__default.useEffect(() => {
3780
+ const [imgFailed, setImgFailed] = React84__default.useState(false);
3781
+ React84__default.useEffect(() => {
3689
3782
  setImgFailed(false);
3690
3783
  }, [src]);
3691
3784
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -3798,7 +3891,7 @@ var init_Center = __esm({
3798
3891
  as: Component = "div"
3799
3892
  }) => {
3800
3893
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
3801
- return React83__default.createElement(Component, {
3894
+ return React84__default.createElement(Component, {
3802
3895
  className: cn(
3803
3896
  inline ? "inline-flex" : "flex",
3804
3897
  horizontal && "justify-center",
@@ -4066,7 +4159,7 @@ var init_Radio = __esm({
4066
4159
  md: "w-2.5 h-2.5",
4067
4160
  lg: "w-3 h-3"
4068
4161
  };
4069
- Radio = React83__default.forwardRef(
4162
+ Radio = React84__default.forwardRef(
4070
4163
  ({
4071
4164
  label,
4072
4165
  helperText,
@@ -4083,12 +4176,12 @@ var init_Radio = __esm({
4083
4176
  onChange,
4084
4177
  ...props
4085
4178
  }, ref) => {
4086
- const reactId = React83__default.useId();
4179
+ const reactId = React84__default.useId();
4087
4180
  const baseId = id || `radio-${reactId}`;
4088
4181
  const hasError = !!error;
4089
4182
  const eventBus = useEventBus();
4090
- const [selected, setSelected] = React83__default.useState(value);
4091
- React83__default.useEffect(() => {
4183
+ const [selected, setSelected] = React84__default.useState(value);
4184
+ React84__default.useEffect(() => {
4092
4185
  if (value !== void 0) setSelected(value);
4093
4186
  }, [value]);
4094
4187
  const pick = (next, e) => {
@@ -4270,7 +4363,7 @@ var init_Switch = __esm({
4270
4363
  "components/core/atoms/Switch.tsx"() {
4271
4364
  "use client";
4272
4365
  init_cn();
4273
- Switch = React83.forwardRef(
4366
+ Switch = React84.forwardRef(
4274
4367
  ({
4275
4368
  checked,
4276
4369
  defaultChecked = false,
@@ -4281,10 +4374,10 @@ var init_Switch = __esm({
4281
4374
  name,
4282
4375
  className
4283
4376
  }, ref) => {
4284
- const [isChecked, setIsChecked] = React83.useState(
4377
+ const [isChecked, setIsChecked] = React84.useState(
4285
4378
  checked !== void 0 ? checked : defaultChecked
4286
4379
  );
4287
- React83.useEffect(() => {
4380
+ React84.useEffect(() => {
4288
4381
  if (checked !== void 0) {
4289
4382
  setIsChecked(checked);
4290
4383
  }
@@ -4315,7 +4408,7 @@ var init_Switch = __esm({
4315
4408
  // redefine --space-11 to 68px, which makes w-11 enormous and leaves
4316
4409
  // the thumb stuck near the left edge. The switch geometry must stay
4317
4410
  // proportional regardless of a theme's density scale.
4318
- "relative inline-flex h-[1.5rem] w-[2.75rem] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors",
4411
+ "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",
4319
4412
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
4320
4413
  isChecked ? "bg-primary" : "bg-muted",
4321
4414
  disabled && "cursor-not-allowed opacity-50"
@@ -4324,7 +4417,7 @@ var init_Switch = __esm({
4324
4417
  "span",
4325
4418
  {
4326
4419
  className: cn(
4327
- "pointer-events-none block h-[1.25rem] w-[1.25rem] rounded-full bg-background shadow-lg ring-0 transition-transform",
4420
+ "pointer-events-none block h-[1.25rem] w-[1.25rem] rounded-full bg-background shadow-lg ring-0 transition-transform duration-fast",
4328
4421
  isChecked ? "translate-x-[1.25rem]" : "translate-x-0"
4329
4422
  )
4330
4423
  }
@@ -4447,7 +4540,7 @@ var init_Stack = __esm({
4447
4540
  };
4448
4541
  const isHorizontal = direction === "horizontal";
4449
4542
  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";
4450
- return React83__default.createElement(
4543
+ return React84__default.createElement(
4451
4544
  Component,
4452
4545
  {
4453
4546
  className: cn(
@@ -4492,7 +4585,7 @@ var init_TextHighlight = __esm({
4492
4585
  hoverEvent
4493
4586
  }) => {
4494
4587
  const eventBus = useEventBus();
4495
- const baseStyles = "cursor-pointer transition-all duration-150";
4588
+ const baseStyles = "cursor-pointer transition-all duration-fast";
4496
4589
  const typeStyles = {
4497
4590
  question: cn(
4498
4591
  // Blue border for questions
@@ -4647,7 +4740,7 @@ var Aside;
4647
4740
  var init_Aside = __esm({
4648
4741
  "components/core/atoms/Aside.tsx"() {
4649
4742
  init_cn();
4650
- Aside = React83__default.forwardRef(
4743
+ Aside = React84__default.forwardRef(
4651
4744
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
4652
4745
  );
4653
4746
  Aside.displayName = "Aside";
@@ -4726,9 +4819,9 @@ var init_LawReferenceTooltip = __esm({
4726
4819
  className
4727
4820
  }) => {
4728
4821
  const { t } = useTranslate();
4729
- const [isVisible, setIsVisible] = React83__default.useState(false);
4730
- const timeoutRef = React83__default.useRef(null);
4731
- const triggerRef = React83__default.useRef(null);
4822
+ const [isVisible, setIsVisible] = React84__default.useState(false);
4823
+ const timeoutRef = React84__default.useRef(null);
4824
+ const triggerRef = React84__default.useRef(null);
4732
4825
  const handleMouseEnter = () => {
4733
4826
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4734
4827
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -4739,7 +4832,7 @@ var init_LawReferenceTooltip = __esm({
4739
4832
  };
4740
4833
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
4741
4834
  const open = isVisible || revealed;
4742
- React83__default.useEffect(() => {
4835
+ React84__default.useEffect(() => {
4743
4836
  return () => {
4744
4837
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4745
4838
  };
@@ -4949,7 +5042,7 @@ var init_StatusDot = __esm({
4949
5042
  md: "w-2.5 h-2.5",
4950
5043
  lg: "w-3 h-3"
4951
5044
  };
4952
- StatusDot = React83__default.forwardRef(
5045
+ StatusDot = React84__default.forwardRef(
4953
5046
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
4954
5047
  return /* @__PURE__ */ jsx(
4955
5048
  "span",
@@ -5003,7 +5096,7 @@ var init_TrendIndicator = __esm({
5003
5096
  down: "trending-down",
5004
5097
  flat: "arrow-right"
5005
5098
  };
5006
- TrendIndicator = React83__default.forwardRef(
5099
+ TrendIndicator = React84__default.forwardRef(
5007
5100
  ({
5008
5101
  className,
5009
5102
  value,
@@ -5070,7 +5163,7 @@ var init_RangeSlider = __esm({
5070
5163
  md: "w-4 h-4",
5071
5164
  lg: "w-5 h-5"
5072
5165
  };
5073
- RangeSlider = React83__default.forwardRef(
5166
+ RangeSlider = React84__default.forwardRef(
5074
5167
  ({
5075
5168
  className,
5076
5169
  min = 0,
@@ -5213,7 +5306,7 @@ var init_RangeSlider = __esm({
5213
5306
  "border-2 border-primary",
5214
5307
  "shadow-sm",
5215
5308
  "pointer-events-none",
5216
- "transition-transform duration-100",
5309
+ "transition-transform duration-instant",
5217
5310
  isDragging && "scale-[var(--hover-scale)]",
5218
5311
  thumbSizes[size]
5219
5312
  ),
@@ -5263,6 +5356,18 @@ var init_RangeSlider = __esm({
5263
5356
  function easeOut(t) {
5264
5357
  return t * (2 - t);
5265
5358
  }
5359
+ function formatDisplay(value, format, decimals) {
5360
+ switch (format) {
5361
+ case "currency":
5362
+ return `$${value.toFixed(2)}`;
5363
+ case "percent":
5364
+ return `${Math.round(value)}%`;
5365
+ case "number":
5366
+ return value.toLocaleString();
5367
+ default:
5368
+ return value.toFixed(decimals);
5369
+ }
5370
+ }
5266
5371
  var AnimatedCounter;
5267
5372
  var init_AnimatedCounter = __esm({
5268
5373
  "components/marketing/atoms/AnimatedCounter.tsx"() {
@@ -5274,6 +5379,7 @@ var init_AnimatedCounter = __esm({
5274
5379
  duration = 600,
5275
5380
  prefix,
5276
5381
  suffix,
5382
+ format,
5277
5383
  className
5278
5384
  }) => {
5279
5385
  const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
@@ -5289,6 +5395,10 @@ var init_AnimatedCounter = __esm({
5289
5395
  setDisplayValue(to);
5290
5396
  return;
5291
5397
  }
5398
+ if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
5399
+ setDisplayValue(to);
5400
+ return;
5401
+ }
5292
5402
  const startTime = performance.now();
5293
5403
  const diff = to - from;
5294
5404
  function animate(currentTime) {
@@ -5310,7 +5420,7 @@ var init_AnimatedCounter = __esm({
5310
5420
  };
5311
5421
  }, [value, duration]);
5312
5422
  const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
5313
- const formattedValue = displayValue.toFixed(decimalPlaces);
5423
+ const formattedValue = formatDisplay(displayValue, format, decimalPlaces);
5314
5424
  return /* @__PURE__ */ jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
5315
5425
  prefix,
5316
5426
  formattedValue,
@@ -5664,7 +5774,7 @@ var init_ContentSection = __esm({
5664
5774
  md: "py-16",
5665
5775
  lg: "py-24"
5666
5776
  };
5667
- ContentSection = React83__default.forwardRef(
5777
+ ContentSection = React84__default.forwardRef(
5668
5778
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
5669
5779
  return /* @__PURE__ */ jsx(
5670
5780
  Box,
@@ -6198,7 +6308,7 @@ var init_AnimatedReveal = __esm({
6198
6308
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
6199
6309
  "none": {}
6200
6310
  };
6201
- AnimatedReveal = React83__default.forwardRef(
6311
+ AnimatedReveal = React84__default.forwardRef(
6202
6312
  ({
6203
6313
  trigger = "scroll",
6204
6314
  animation = "fade-up",
@@ -6358,7 +6468,7 @@ var init_AnimatedGraphic = __esm({
6358
6468
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6359
6469
  "use client";
6360
6470
  init_cn();
6361
- AnimatedGraphic = React83__default.forwardRef(
6471
+ AnimatedGraphic = React84__default.forwardRef(
6362
6472
  ({
6363
6473
  src,
6364
6474
  svgContent,
@@ -6381,7 +6491,7 @@ var init_AnimatedGraphic = __esm({
6381
6491
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6382
6492
  const resolvedSvg = svgContent ?? fetchedSvg;
6383
6493
  const prevAnimateRef = useRef(animate);
6384
- const setRef = React83__default.useCallback(
6494
+ const setRef = React84__default.useCallback(
6385
6495
  (node) => {
6386
6496
  containerRef.current = node;
6387
6497
  if (typeof ref === "function") ref(node);
@@ -6589,14 +6699,29 @@ function recordTransition(trace) {
6589
6699
  "pass"
6590
6700
  );
6591
6701
  } else {
6592
- const hasRenderUI = entry.effects.some((e) => e.type === "render-ui");
6593
- if (hasRenderUI) {
6594
- registerCheck(
6595
- checkId,
6596
- `INIT transition for "${entry.traitName}" missing fetch effect`,
6597
- "fail",
6598
- "Entity-bound render-ui without a fetch effect will show empty data"
6702
+ const rendersEntityData = entry.effects.some(
6703
+ (e) => e.type === "render-ui" && JSON.stringify(e.args).includes("@entity.")
6704
+ );
6705
+ if (rendersEntityData) {
6706
+ const siblingSeeds = getState().transitions.some(
6707
+ (t) => t.event === "INIT" && t.effects.some(
6708
+ (e) => e.type === "fetch" || e.type === "set" && typeof e.args[0] === "string" && e.args[0].startsWith("@entity.")
6709
+ )
6599
6710
  );
6711
+ if (siblingSeeds) {
6712
+ registerCheck(
6713
+ checkId,
6714
+ `INIT transition for "${entry.traitName}" has sibling entity-seed (shared entity)`,
6715
+ "pass"
6716
+ );
6717
+ } else {
6718
+ registerCheck(
6719
+ checkId,
6720
+ `INIT transition for "${entry.traitName}" missing fetch effect`,
6721
+ "fail",
6722
+ "Entity-bound render-ui without a fetch effect will show empty data"
6723
+ );
6724
+ }
6600
6725
  }
6601
6726
  }
6602
6727
  }
@@ -6714,19 +6839,32 @@ function bindEventBus(eventBus) {
6714
6839
  log3.debug("sendEvent", { event: prefixed, traitScope, payloadKeys: payload ? Object.keys(payload) : [] });
6715
6840
  eventBus.emit(prefixed, payload);
6716
6841
  };
6842
+ const MAX_EVENT_LOG = 5e3;
6717
6843
  const eventLog = [];
6844
+ let eventLogDropped = 0;
6845
+ const bumpEpoch = () => {
6846
+ window.__orbitalVerification.eventLogEpoch = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
6847
+ };
6718
6848
  window.__orbitalVerification.eventLog = eventLog;
6849
+ window.__orbitalVerification.eventLogDropped = 0;
6850
+ bumpEpoch();
6719
6851
  window.__orbitalVerification.clearEventLog = () => {
6720
6852
  eventLog.length = 0;
6853
+ eventLogDropped = 0;
6854
+ window.__orbitalVerification.eventLogDropped = 0;
6855
+ bumpEpoch();
6721
6856
  };
6722
6857
  if (eventBus.onAny) {
6723
6858
  const verificationRegistryEventLogger = (event) => {
6724
- if (eventLog.length < 200) {
6725
- eventLog.push({
6726
- type: event.type,
6727
- payload: event.payload,
6728
- timestamp: Date.now()
6729
- });
6859
+ eventLog.push({
6860
+ type: event.type,
6861
+ payload: event.payload,
6862
+ timestamp: Date.now()
6863
+ });
6864
+ if (eventLog.length > MAX_EVENT_LOG) {
6865
+ eventLog.shift();
6866
+ eventLogDropped += 1;
6867
+ window.__orbitalVerification.eventLogDropped = eventLogDropped;
6730
6868
  }
6731
6869
  };
6732
6870
  Object.defineProperty(verificationRegistryEventLogger, "name", {
@@ -7082,9 +7220,9 @@ function ControlButton({
7082
7220
  className
7083
7221
  }) {
7084
7222
  const eventBus = useEventBus();
7085
- const [isPressed, setIsPressed] = React83.useState(false);
7223
+ const [isPressed, setIsPressed] = React84.useState(false);
7086
7224
  const actualPressed = pressed ?? isPressed;
7087
- const handlePointerDown = React83.useCallback(
7225
+ const handlePointerDown = React84.useCallback(
7088
7226
  (e) => {
7089
7227
  e.preventDefault();
7090
7228
  if (disabled) return;
@@ -7094,7 +7232,7 @@ function ControlButton({
7094
7232
  },
7095
7233
  [disabled, pressEvent, eventBus, onPress]
7096
7234
  );
7097
- const handlePointerUp = React83.useCallback(
7235
+ const handlePointerUp = React84.useCallback(
7098
7236
  (e) => {
7099
7237
  e.preventDefault();
7100
7238
  if (disabled) return;
@@ -7104,7 +7242,7 @@ function ControlButton({
7104
7242
  },
7105
7243
  [disabled, releaseEvent, eventBus, onRelease]
7106
7244
  );
7107
- const handlePointerLeave = React83.useCallback(
7245
+ const handlePointerLeave = React84.useCallback(
7108
7246
  (e) => {
7109
7247
  if (isPressed) {
7110
7248
  setIsPressed(false);
@@ -7362,8 +7500,8 @@ function ControlGrid({
7362
7500
  className
7363
7501
  }) {
7364
7502
  const eventBus = useEventBus();
7365
- const [active, setActive] = React83.useState(/* @__PURE__ */ new Set());
7366
- const handlePress = React83.useCallback(
7503
+ const [active, setActive] = React84.useState(/* @__PURE__ */ new Set());
7504
+ const handlePress = React84.useCallback(
7367
7505
  (id) => {
7368
7506
  setActive((prev) => new Set(prev).add(id));
7369
7507
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -7377,7 +7515,7 @@ function ControlGrid({
7377
7515
  },
7378
7516
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
7379
7517
  );
7380
- const handleRelease = React83.useCallback(
7518
+ const handleRelease = React84.useCallback(
7381
7519
  (id) => {
7382
7520
  setActive((prev) => {
7383
7521
  const next = new Set(prev);
@@ -7670,17 +7808,18 @@ function GameHud({
7670
7808
  const mid = Math.ceil(stats.length / 2);
7671
7809
  const leftStats = stats.slice(0, mid);
7672
7810
  const rightStats = stats.slice(mid);
7673
- const isTop = position === "top";
7674
7811
  return /* @__PURE__ */ jsxs(
7675
- Box,
7812
+ Card,
7676
7813
  {
7814
+ variant: "bordered",
7815
+ padding: "none",
7677
7816
  className: cn(
7678
- "flex items-center justify-between w-full",
7817
+ "flex items-center justify-between w-full rounded-none bg-card",
7679
7818
  "px-4 py-2 gap-4",
7680
- !transparent && (isTop ? "border-b border-border/40 bg-surface/90 backdrop-blur-sm" : "border-t border-border/40 bg-surface/90 backdrop-blur-sm"),
7681
- transparent && (isTop ? "border-b border-white/10 bg-black/40 backdrop-blur-sm" : "border-t border-white/10 bg-black/40 backdrop-blur-sm"),
7819
+ transparent && "backdrop-blur-sm",
7682
7820
  className
7683
7821
  ),
7822
+ style: transparent ? { backgroundColor: "color-mix(in srgb, var(--color-card) 40%, transparent)" } : void 0,
7684
7823
  children: [
7685
7824
  /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
7686
7825
  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)) })
@@ -7689,14 +7828,16 @@ function GameHud({
7689
7828
  );
7690
7829
  }
7691
7830
  return /* @__PURE__ */ jsx(
7692
- Box,
7831
+ Card,
7693
7832
  {
7694
- position: "relative",
7833
+ variant: "bordered",
7834
+ padding: "sm",
7695
7835
  className: cn(
7696
- "z-10 flex items-center gap-4 px-4 py-2",
7697
- transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
7836
+ "z-10 relative flex items-center gap-4 bg-card",
7837
+ transparent && "backdrop-blur-sm",
7698
7838
  className
7699
7839
  ),
7840
+ style: transparent ? { backgroundColor: "color-mix(in srgb, var(--color-card) 30%, transparent)" } : void 0,
7700
7841
  children: stats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i))
7701
7842
  }
7702
7843
  );
@@ -7706,6 +7847,7 @@ var init_GameHud = __esm({
7706
7847
  "components/game/molecules/GameHud.tsx"() {
7707
7848
  init_cn();
7708
7849
  init_Box();
7850
+ init_Card();
7709
7851
  init_StatBadge();
7710
7852
  positionMap = {
7711
7853
  corners: "inset-0 pointer-events-none"
@@ -7729,9 +7871,9 @@ function GameMenu({
7729
7871
  logo,
7730
7872
  className
7731
7873
  }) {
7732
- const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
7874
+ const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
7733
7875
  const eventBus = useEventBus();
7734
- const handleOptionClick = React83.useCallback(
7876
+ const handleOptionClick = React84.useCallback(
7735
7877
  (option) => {
7736
7878
  if (option.event) {
7737
7879
  eventBus.emit(`UI:${option.event}`, { option });
@@ -7750,39 +7892,48 @@ function GameMenu({
7750
7892
  {
7751
7893
  className: cn(
7752
7894
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
7895
+ !background && "bg-background",
7753
7896
  className
7754
7897
  ),
7755
- style: {
7756
- background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
7757
- },
7898
+ style: background ? { background } : void 0,
7758
7899
  children: [
7759
- /* @__PURE__ */ jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
7760
- logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
7761
- /* @__PURE__ */ jsx(
7762
- Typography,
7763
- {
7764
- variant: "h1",
7765
- className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
7766
- style: {
7767
- textShadow: "0 4px 12px rgba(0,0,0,0.5)"
7768
- },
7769
- children: title
7770
- }
7771
- ),
7772
- subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
7773
- ] }),
7774
- /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
7775
- ChoiceButton,
7900
+ /* @__PURE__ */ jsxs(
7901
+ Card,
7776
7902
  {
7777
- text: option.label,
7778
- index: index + 1,
7779
- disabled: option.disabled,
7780
- onClick: () => handleOptionClick(option),
7781
- className: "text-lg py-4 px-8"
7782
- },
7783
- index
7784
- )) }),
7785
- /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
7903
+ variant: "bordered",
7904
+ padding: "lg",
7905
+ className: "bg-card flex flex-col items-center max-w-md w-full",
7906
+ children: [
7907
+ /* @__PURE__ */ jsxs(Box, { className: "text-center mb-8 animate-fade-in", children: [
7908
+ logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
7909
+ /* @__PURE__ */ jsx(
7910
+ Typography,
7911
+ {
7912
+ variant: "h1",
7913
+ className: "text-4xl md:text-5xl font-bold text-foreground tracking-tight",
7914
+ style: {
7915
+ textShadow: "0 4px 12px rgba(0,0,0,0.5)"
7916
+ },
7917
+ children: title
7918
+ }
7919
+ ),
7920
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
7921
+ ] }),
7922
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
7923
+ ChoiceButton,
7924
+ {
7925
+ text: option.label,
7926
+ index: index + 1,
7927
+ disabled: option.disabled,
7928
+ onClick: () => handleOptionClick(option),
7929
+ className: "text-lg py-4 px-8"
7930
+ },
7931
+ index
7932
+ )) })
7933
+ ]
7934
+ }
7935
+ ),
7936
+ /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden -z-10", children: [
7786
7937
  /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
7787
7938
  /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
7788
7939
  ] })
@@ -7797,6 +7948,7 @@ var init_GameMenu = __esm({
7797
7948
  init_cn();
7798
7949
  init_useEventBus();
7799
7950
  init_Box();
7951
+ init_Card();
7800
7952
  init_Typography();
7801
7953
  init_GameIcon();
7802
7954
  init_ChoiceButton();
@@ -7957,7 +8109,7 @@ function StateGraph({
7957
8109
  }) {
7958
8110
  const eventBus = useEventBus();
7959
8111
  const nodes = states ?? [];
7960
- const positions = React83.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
8112
+ const positions = React84.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
7961
8113
  return /* @__PURE__ */ jsxs(
7962
8114
  Box,
7963
8115
  {
@@ -8028,8 +8180,8 @@ function MiniMap({
8028
8180
  tileAssets,
8029
8181
  unitAssets
8030
8182
  }) {
8031
- const canvasRef = React83.useRef(null);
8032
- const imgCacheRef = React83.useRef(/* @__PURE__ */ new Map());
8183
+ const canvasRef = React84.useRef(null);
8184
+ const imgCacheRef = React84.useRef(/* @__PURE__ */ new Map());
8033
8185
  function loadImg(url) {
8034
8186
  const cached = imgCacheRef.current.get(url);
8035
8187
  if (cached) return cached.complete ? cached : null;
@@ -8044,7 +8196,7 @@ function MiniMap({
8044
8196
  imgCacheRef.current.set(url, img);
8045
8197
  return null;
8046
8198
  }
8047
- React83.useEffect(() => {
8199
+ React84.useEffect(() => {
8048
8200
  const canvas = canvasRef.current;
8049
8201
  if (!canvas) return;
8050
8202
  const ctx = canvas.getContext("2d");
@@ -9127,6 +9279,10 @@ function Canvas2D({
9127
9279
  window.removeEventListener("keyup", onUp);
9128
9280
  };
9129
9281
  }, [keyMap, keyUpMap, eventBus]);
9282
+ useEffect(() => {
9283
+ if (!keyMap && !keyUpMap) return;
9284
+ canvasRef.current?.focus();
9285
+ }, [keyMap, keyUpMap]);
9130
9286
  if (error) {
9131
9287
  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: [
9132
9288
  /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
@@ -9175,7 +9331,7 @@ function Canvas2D({
9175
9331
  onWheel: gestureHandlers.onWheel,
9176
9332
  onContextMenu: (e) => e.preventDefault(),
9177
9333
  className: "cursor-pointer touch-none",
9178
- tabIndex: isFree ? 0 : void 0,
9334
+ tabIndex: isFree || keyMap || keyUpMap ? 0 : void 0,
9179
9335
  style: {
9180
9336
  width: viewportSize.width,
9181
9337
  height: viewportSize.height
@@ -9729,7 +9885,7 @@ function LinearView({
9729
9885
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
9730
9886
  const isDone = i < currentIdx;
9731
9887
  const isCurrent = i === currentIdx;
9732
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
9888
+ return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
9733
9889
  i > 0 && /* @__PURE__ */ jsx(
9734
9890
  Typography,
9735
9891
  {
@@ -10264,7 +10420,7 @@ function SequenceBar({
10264
10420
  else onSlotRemove?.(index);
10265
10421
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
10266
10422
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
10267
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
10423
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
10268
10424
  i > 0 && /* @__PURE__ */ jsx(
10269
10425
  Typography,
10270
10426
  {
@@ -10351,6 +10507,7 @@ var init_GameShell = __esm({
10351
10507
  "components/game/templates/GameShell.tsx"() {
10352
10508
  init_cn();
10353
10509
  init_Box();
10510
+ init_Card();
10354
10511
  init_Typography();
10355
10512
  init_AtlasImage();
10356
10513
  FONT_BASE = "https://almadar-kflow-assets.web.app/shared/_shared/kenney-fonts/fonts";
@@ -10379,13 +10536,14 @@ var init_GameShell = __esm({
10379
10536
  showTopBar = true,
10380
10537
  children,
10381
10538
  backgroundAsset,
10382
- hudBackgroundAsset,
10383
- fontFamily = "future"
10539
+ fontFamily = "future",
10540
+ "data-theme": dataTheme
10384
10541
  }) => {
10385
10542
  const font = GAME_FONTS[fontFamily] ?? fontFamily;
10386
10543
  return /* @__PURE__ */ jsxs(
10387
10544
  Box,
10388
10545
  {
10546
+ "data-theme": dataTheme || void 0,
10389
10547
  className: cn("game-shell", className),
10390
10548
  style: {
10391
10549
  position: "relative",
@@ -10393,7 +10551,7 @@ var init_GameShell = __esm({
10393
10551
  height: "100vh",
10394
10552
  overflow: "hidden",
10395
10553
  background: "var(--color-background, #0a0a0f)",
10396
- color: "var(--color-text, #e0e0e0)",
10554
+ color: "var(--color-foreground, #e0e0e0)",
10397
10555
  fontFamily: `'${font}', system-ui, sans-serif`
10398
10556
  },
10399
10557
  children: [
@@ -10425,19 +10583,12 @@ var init_GameShell = __esm({
10425
10583
  },
10426
10584
  children: [
10427
10585
  showTopBar && /* @__PURE__ */ jsx(
10428
- AtlasPanel,
10586
+ Card,
10429
10587
  {
10430
- asset: hudBackgroundAsset,
10431
- borderSlice: 12,
10432
- borderWidth: 10,
10433
- className: "game-shell__title pointer-events-auto",
10434
- style: {
10435
- padding: "6px 16px",
10436
- background: hudBackgroundAsset ? void 0 : "rgba(18, 18, 31, 0.85)",
10437
- borderRadius: hudBackgroundAsset ? void 0 : 10,
10438
- boxShadow: "0 4px 14px rgba(0,0,0,0.45)",
10439
- flexShrink: 0
10440
- },
10588
+ variant: "bordered",
10589
+ padding: "none",
10590
+ className: "game-shell__title bg-card pointer-events-auto",
10591
+ style: { padding: "6px 16px", flexShrink: 0 },
10441
10592
  children: /* @__PURE__ */ jsx(
10442
10593
  Typography,
10443
10594
  {
@@ -10918,7 +11069,7 @@ var init_ErrorBoundary = __esm({
10918
11069
  }
10919
11070
  );
10920
11071
  };
10921
- ErrorBoundary = class extends React83__default.Component {
11072
+ ErrorBoundary = class extends React84__default.Component {
10922
11073
  constructor(props) {
10923
11074
  super(props);
10924
11075
  __publicField(this, "reset", () => {
@@ -11568,7 +11719,7 @@ var init_Container = __esm({
11568
11719
  as: Component = "div"
11569
11720
  }) => {
11570
11721
  const resolvedSize = maxWidth ?? size ?? "lg";
11571
- return React83__default.createElement(
11722
+ return React84__default.createElement(
11572
11723
  Component,
11573
11724
  {
11574
11725
  className: cn(
@@ -14076,7 +14227,8 @@ var init_LoadingState = __esm({
14076
14227
  LoadingState = ({
14077
14228
  title,
14078
14229
  message,
14079
- className
14230
+ className,
14231
+ fullPage = false
14080
14232
  }) => {
14081
14233
  const { t } = useTranslate();
14082
14234
  const displayMessage = message ?? t("common.loading");
@@ -14085,7 +14237,8 @@ var init_LoadingState = __esm({
14085
14237
  {
14086
14238
  align: "center",
14087
14239
  className: cn(
14088
- "justify-center py-12",
14240
+ "justify-center",
14241
+ fullPage ? "fixed inset-0 z-[1000] py-12 bg-background/80 backdrop-blur-sm animate-overlay-in" : "py-12",
14089
14242
  className
14090
14243
  ),
14091
14244
  children: [
@@ -14393,7 +14546,7 @@ var init_CodeBlock = __esm({
14393
14546
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
14394
14547
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
14395
14548
  HIDDEN_LINE_NUMBERS = { display: "none" };
14396
- CodeBlock = React83__default.memo(
14549
+ CodeBlock = React84__default.memo(
14397
14550
  ({
14398
14551
  code: rawCode,
14399
14552
  language = "text",
@@ -14980,7 +15133,7 @@ var init_MarkdownContent = __esm({
14980
15133
  init_Box();
14981
15134
  init_CodeBlock();
14982
15135
  init_cn();
14983
- MarkdownContent = React83__default.memo(
15136
+ MarkdownContent = React84__default.memo(
14984
15137
  ({ content, direction = "ltr", className }) => {
14985
15138
  const { t: _t } = useTranslate();
14986
15139
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -15943,7 +16096,7 @@ var init_StateMachineView = __esm({
15943
16096
  Box,
15944
16097
  {
15945
16098
  className: cn(
15946
- "fixed z-50 animate-in fade-in-0 zoom-in-95 duration-150",
16099
+ "fixed z-50 animate-in fade-in-0 zoom-in-95 duration-fast",
15947
16100
  tooltip.pinned ? "pointer-events-auto" : "pointer-events-none"
15948
16101
  ),
15949
16102
  style: {
@@ -16307,7 +16460,7 @@ var init_StateMachineView = __esm({
16307
16460
  style: { top: title ? 30 : 0 },
16308
16461
  children: [
16309
16462
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
16310
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React83__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
16463
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React84__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
16311
16464
  StateNode2,
16312
16465
  {
16313
16466
  state,
@@ -17287,7 +17440,7 @@ var init_BookCoverPage = __esm({
17287
17440
  size: "lg",
17288
17441
  action: "BOOK_START",
17289
17442
  className: "mt-8",
17290
- children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: t("book.startReading") })
17443
+ children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "inherit", children: t("book.startReading") })
17291
17444
  }
17292
17445
  )
17293
17446
  ]
@@ -18346,6 +18499,129 @@ var init_Breadcrumb = __esm({
18346
18499
  Breadcrumb.displayName = "Breadcrumb";
18347
18500
  }
18348
18501
  });
18502
+ function useSafeEventBus2() {
18503
+ try {
18504
+ return useEventBus();
18505
+ } catch {
18506
+ return { emit: () => {
18507
+ }, on: () => () => {
18508
+ }, once: () => {
18509
+ } };
18510
+ }
18511
+ }
18512
+ var log8, lookStyles4, ButtonGroup;
18513
+ var init_ButtonGroup = __esm({
18514
+ "components/core/molecules/ButtonGroup.tsx"() {
18515
+ "use client";
18516
+ init_cn();
18517
+ init_atoms();
18518
+ init_useEventBus();
18519
+ log8 = createLogger("almadar:ui:button-group");
18520
+ lookStyles4 = {
18521
+ "right-aligned-buttons": "",
18522
+ "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
18523
+ "inline-row": "gap-2 inline-flex",
18524
+ "dropdown-menu": "[&>button:not(:first-child)]:hidden",
18525
+ "command-palette-trigger": "[&>button:not(:first-child)]:hidden"
18526
+ };
18527
+ ButtonGroup = ({
18528
+ children,
18529
+ primary,
18530
+ secondary,
18531
+ variant = "default",
18532
+ orientation = "horizontal",
18533
+ className,
18534
+ // Filter-group pattern props (entity and filters are used for schema-driven filtering)
18535
+ entity: _entity,
18536
+ filters,
18537
+ look = "right-aligned-buttons"
18538
+ }) => {
18539
+ const eventBus = useSafeEventBus2();
18540
+ const variantClasses2 = {
18541
+ default: "gap-0",
18542
+ 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",
18543
+ 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"
18544
+ };
18545
+ const orientationClasses = {
18546
+ horizontal: "flex-row",
18547
+ 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"
18548
+ };
18549
+ const handleActionClick = (action) => {
18550
+ if (action.event) {
18551
+ eventBus.emit("UI:DISPATCH", { event: action.event });
18552
+ }
18553
+ if (action.navigatesTo) {
18554
+ eventBus.emit("UI:NAVIGATE", { url: action.navigatesTo });
18555
+ }
18556
+ };
18557
+ const renderFormActions = () => {
18558
+ const buttons = [];
18559
+ if (secondary) {
18560
+ secondary.forEach((action, index) => {
18561
+ buttons.push(
18562
+ /* @__PURE__ */ jsx(
18563
+ Button,
18564
+ {
18565
+ type: action.actionType === "submit" ? "submit" : "button",
18566
+ variant: action.variant || "ghost",
18567
+ onClick: () => handleActionClick(action),
18568
+ children: action.label
18569
+ },
18570
+ `secondary-${index}`
18571
+ )
18572
+ );
18573
+ });
18574
+ }
18575
+ if (primary) {
18576
+ const isSubmit = primary.actionType === "submit";
18577
+ buttons.push(
18578
+ /* @__PURE__ */ jsx(
18579
+ Button,
18580
+ {
18581
+ type: isSubmit ? "submit" : "button",
18582
+ variant: primary.variant || "primary",
18583
+ onClick: () => handleActionClick(primary),
18584
+ "data-testid": isSubmit ? "form-submit" : void 0,
18585
+ children: primary.label
18586
+ },
18587
+ "primary"
18588
+ )
18589
+ );
18590
+ }
18591
+ return buttons;
18592
+ };
18593
+ const renderFilters = () => {
18594
+ if (!filters || filters.length === 0) return null;
18595
+ return filters.map((filter, index) => /* @__PURE__ */ jsx(
18596
+ Button,
18597
+ {
18598
+ variant: "ghost",
18599
+ onClick: () => {
18600
+ log8.debug("Filter clicked", { field: filter.field });
18601
+ },
18602
+ children: filter.label
18603
+ },
18604
+ `filter-${filter.field}-${index}`
18605
+ ));
18606
+ };
18607
+ return /* @__PURE__ */ jsx(
18608
+ "div",
18609
+ {
18610
+ className: cn(
18611
+ "inline-flex gap-2",
18612
+ variantClasses2[variant],
18613
+ orientationClasses[orientation],
18614
+ lookStyles4[look],
18615
+ className
18616
+ ),
18617
+ role: "group",
18618
+ children: children || renderFilters() || renderFormActions()
18619
+ }
18620
+ );
18621
+ };
18622
+ ButtonGroup.displayName = "ButtonGroup";
18623
+ }
18624
+ });
18349
18625
  function useSwipeGesture(callbacks, options = {}) {
18350
18626
  const { threshold = 50, velocityThreshold = 0.3, preventDefault = false } = options;
18351
18627
  const startX = useRef(0);
@@ -19155,7 +19431,7 @@ var init_CardGrid = __esm({
19155
19431
  CardGrid.displayName = "CardGrid";
19156
19432
  }
19157
19433
  });
19158
- function useSafeEventBus2() {
19434
+ function useSafeEventBus3() {
19159
19435
  try {
19160
19436
  return useEventBus();
19161
19437
  } catch {
@@ -19191,7 +19467,7 @@ var init_Carousel = __esm({
19191
19467
  const [activeIndex, setActiveIndex] = useState(0);
19192
19468
  const scrollRef = useRef(null);
19193
19469
  const autoPlayRef = useRef(null);
19194
- const eventBus = useSafeEventBus2();
19470
+ const eventBus = useSafeEventBus3();
19195
19471
  const { t } = useTranslate();
19196
19472
  const safeItems = items ?? [];
19197
19473
  const totalSlides = safeItems.length;
@@ -19553,7 +19829,7 @@ var init_Chart = __esm({
19553
19829
  return /* @__PURE__ */ jsx(
19554
19830
  Box,
19555
19831
  {
19556
- className: "h-full rounded-r-sm transition-all duration-500 ease-out min-w-[2px] cursor-pointer hover:opacity-80",
19832
+ className: "h-full rounded-r-sm transition-all duration-slow ease-standard min-w-[2px] cursor-pointer hover:opacity-80",
19557
19833
  style: {
19558
19834
  width: `${ratio}%`,
19559
19835
  backgroundColor: color
@@ -19599,8 +19875,9 @@ var init_Chart = __esm({
19599
19875
  align: "center",
19600
19876
  flex: true,
19601
19877
  className: "min-w-0",
19878
+ style: { height: "100%" },
19602
19879
  children: [
19603
- /* @__PURE__ */ jsx(HStack, { gap: histogram ? "none" : "xs", align: "end", className: "w-full", style: { height: "100%" }, children: series.map((s, sIdx) => {
19880
+ /* @__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) => {
19604
19881
  const value = valueAt(s, label);
19605
19882
  const barHeight = value / maxValue * 100;
19606
19883
  const color = seriesColor(s, sIdx);
@@ -19608,11 +19885,13 @@ var init_Chart = __esm({
19608
19885
  Box,
19609
19886
  {
19610
19887
  className: cn(
19611
- "rounded-t-sm transition-all duration-500 ease-out min-h-[4px] cursor-pointer hover:opacity-80",
19888
+ "rounded-t-sm transition-all duration-slow ease-standard min-h-[4px] cursor-pointer hover:opacity-80",
19612
19889
  histogram ? "flex-1 mx-0" : "flex-1"
19613
19890
  ),
19614
19891
  style: {
19615
19892
  height: `${barHeight}%`,
19893
+ // Cap width so a lone category doesn't paint the whole plot as one solid block; narrow columns are unaffected (flex-1 binds first).
19894
+ ...!histogram && { maxWidth: 72 },
19616
19895
  backgroundColor: color
19617
19896
  },
19618
19897
  onClick: () => onPointClick?.(
@@ -19647,15 +19926,16 @@ var init_Chart = __esm({
19647
19926
  align: "center",
19648
19927
  flex: true,
19649
19928
  className: "min-w-0",
19929
+ style: { height: "100%" },
19650
19930
  children: [
19651
- /* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full", style: { height: "100%" }, justify: "end", children: series.map((s, sIdx) => {
19931
+ /* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full flex-1 min-h-0", justify: "end", children: series.map((s, sIdx) => {
19652
19932
  const value = valueAt(s, label);
19653
19933
  const ratio = stack === "normalize" ? total === 0 ? 0 : value / total * 100 : value / maxValue * 100;
19654
19934
  const color = seriesColor(s, sIdx);
19655
19935
  return /* @__PURE__ */ jsx(
19656
19936
  Box,
19657
19937
  {
19658
- className: "w-full transition-all duration-500 ease-out cursor-pointer hover:opacity-80",
19938
+ className: "w-full transition-all duration-slow ease-standard cursor-pointer hover:opacity-80",
19659
19939
  style: {
19660
19940
  height: `${ratio}%`,
19661
19941
  backgroundColor: color
@@ -19693,6 +19973,7 @@ var init_Chart = __esm({
19693
19973
  const innerRadius = donut ? radius * 0.6 : 0;
19694
19974
  const center = size / 2;
19695
19975
  const segments = useMemo(() => {
19976
+ if (!Number.isFinite(total) || total <= 0) return [];
19696
19977
  let currentAngle = -Math.PI / 2;
19697
19978
  return data.map((point, idx) => {
19698
19979
  const angle = point.value / total * 2 * Math.PI;
@@ -19704,13 +19985,25 @@ var init_Chart = __esm({
19704
19985
  const y1 = center + radius * Math.sin(startAngle);
19705
19986
  const x2 = center + radius * Math.cos(endAngle);
19706
19987
  const y2 = center + radius * Math.sin(endAngle);
19988
+ const fullCircle = angle >= 2 * Math.PI - 1e-9;
19989
+ const midAngle = startAngle + angle / 2;
19990
+ const xm = center + radius * Math.cos(midAngle);
19991
+ const ym = center + radius * Math.sin(midAngle);
19707
19992
  let d;
19708
19993
  if (innerRadius > 0) {
19709
19994
  const ix1 = center + innerRadius * Math.cos(startAngle);
19710
19995
  const iy1 = center + innerRadius * Math.sin(startAngle);
19711
19996
  const ix2 = center + innerRadius * Math.cos(endAngle);
19712
19997
  const iy2 = center + innerRadius * Math.sin(endAngle);
19713
- 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`;
19998
+ if (fullCircle) {
19999
+ const ixm = center + innerRadius * Math.cos(midAngle);
20000
+ const iym = center + innerRadius * Math.sin(midAngle);
20001
+ 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`;
20002
+ } else {
20003
+ 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`;
20004
+ }
20005
+ } else if (fullCircle) {
20006
+ d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} Z`;
19714
20007
  } else {
19715
20008
  d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`;
19716
20009
  }
@@ -19732,7 +20025,7 @@ var init_Chart = __esm({
19732
20025
  fill: seg.color,
19733
20026
  stroke: "var(--color-card)",
19734
20027
  strokeWidth: "2",
19735
- className: "transition-opacity duration-200 hover:opacity-80 cursor-pointer",
20028
+ className: "transition-opacity duration-fast hover:opacity-80 cursor-pointer",
19736
20029
  onClick: () => onPointClick?.(
19737
20030
  { label: seg.label, value: seg.value, color: seg.color },
19738
20031
  "default"
@@ -21945,8 +22238,8 @@ var init_Menu = __esm({
21945
22238
  "bottom-end": "bottom-start"
21946
22239
  };
21947
22240
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
21948
- const triggerChild = React83__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
21949
- const triggerElement = React83__default.cloneElement(
22241
+ const triggerChild = React84__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
22242
+ const triggerElement = React84__default.cloneElement(
21950
22243
  triggerChild,
21951
22244
  {
21952
22245
  ref: triggerRef,
@@ -22041,14 +22334,14 @@ function useDataDnd(args) {
22041
22334
  const isZone = Boolean(dragGroup || accepts || sortable);
22042
22335
  const enabled = isZone || Boolean(dndRoot);
22043
22336
  const eventBus = useEventBus();
22044
- const parentRoot = React83__default.useContext(RootCtx);
22337
+ const parentRoot = React84__default.useContext(RootCtx);
22045
22338
  const isRoot = enabled && parentRoot === null;
22046
- const zoneId = React83__default.useId();
22339
+ const zoneId = React84__default.useId();
22047
22340
  const ownGroup = dragGroup ?? accepts ?? zoneId;
22048
- const [optimisticOrders, setOptimisticOrders] = React83__default.useState(() => /* @__PURE__ */ new Map());
22049
- const optimisticOrdersRef = React83__default.useRef(optimisticOrders);
22341
+ const [optimisticOrders, setOptimisticOrders] = React84__default.useState(() => /* @__PURE__ */ new Map());
22342
+ const optimisticOrdersRef = React84__default.useRef(optimisticOrders);
22050
22343
  optimisticOrdersRef.current = optimisticOrders;
22051
- const clearOptimisticOrder = React83__default.useCallback((group) => {
22344
+ const clearOptimisticOrder = React84__default.useCallback((group) => {
22052
22345
  setOptimisticOrders((prev) => {
22053
22346
  if (!prev.has(group)) return prev;
22054
22347
  const next = new Map(prev);
@@ -22073,7 +22366,7 @@ function useDataDnd(args) {
22073
22366
  const raw = it[dndItemIdField];
22074
22367
  return raw != null ? String(raw) : `__idx_${idx}`;
22075
22368
  }).join("|");
22076
- const itemIds = React83__default.useMemo(
22369
+ const itemIds = React84__default.useMemo(
22077
22370
  () => orderedItems.map((it, idx) => {
22078
22371
  const raw = it[dndItemIdField];
22079
22372
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -22084,7 +22377,7 @@ function useDataDnd(args) {
22084
22377
  const raw = it[dndItemIdField];
22085
22378
  return raw != null ? String(raw) : `__${idx}`;
22086
22379
  }).join("|");
22087
- React83__default.useEffect(() => {
22380
+ React84__default.useEffect(() => {
22088
22381
  const root = isRoot ? null : parentRoot;
22089
22382
  if (root) {
22090
22383
  root.clearOptimisticOrder(ownGroup);
@@ -22092,20 +22385,20 @@ function useDataDnd(args) {
22092
22385
  clearOptimisticOrder(ownGroup);
22093
22386
  }
22094
22387
  }, [itemsContentSig, ownGroup]);
22095
- const zonesRef = React83__default.useRef(/* @__PURE__ */ new Map());
22096
- const registerZone = React83__default.useCallback((zoneId2, meta2) => {
22388
+ const zonesRef = React84__default.useRef(/* @__PURE__ */ new Map());
22389
+ const registerZone = React84__default.useCallback((zoneId2, meta2) => {
22097
22390
  zonesRef.current.set(zoneId2, meta2);
22098
22391
  }, []);
22099
- const unregisterZone = React83__default.useCallback((zoneId2) => {
22392
+ const unregisterZone = React84__default.useCallback((zoneId2) => {
22100
22393
  zonesRef.current.delete(zoneId2);
22101
22394
  }, []);
22102
- const [activeDrag, setActiveDrag] = React83__default.useState(null);
22103
- const [overZoneGroup, setOverZoneGroup] = React83__default.useState(null);
22104
- const meta = React83__default.useMemo(
22395
+ const [activeDrag, setActiveDrag] = React84__default.useState(null);
22396
+ const [overZoneGroup, setOverZoneGroup] = React84__default.useState(null);
22397
+ const meta = React84__default.useMemo(
22105
22398
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
22106
22399
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
22107
22400
  );
22108
- React83__default.useEffect(() => {
22401
+ React84__default.useEffect(() => {
22109
22402
  const target = isRoot ? null : parentRoot;
22110
22403
  if (!target) {
22111
22404
  zonesRef.current.set(zoneId, meta);
@@ -22124,7 +22417,7 @@ function useDataDnd(args) {
22124
22417
  }, [parentRoot, isRoot, zoneId, meta]);
22125
22418
  const sensors = useAlmadarDndSensors(true);
22126
22419
  const collisionDetection = almadarDndCollisionDetection;
22127
- const findZoneByItem = React83__default.useCallback(
22420
+ const findZoneByItem = React84__default.useCallback(
22128
22421
  (id) => {
22129
22422
  for (const z of zonesRef.current.values()) {
22130
22423
  if (z.itemIds.includes(id)) return z;
@@ -22133,7 +22426,7 @@ function useDataDnd(args) {
22133
22426
  },
22134
22427
  []
22135
22428
  );
22136
- React83__default.useCallback(
22429
+ React84__default.useCallback(
22137
22430
  (group) => {
22138
22431
  for (const z of zonesRef.current.values()) {
22139
22432
  if (z.group === group) return z;
@@ -22142,7 +22435,7 @@ function useDataDnd(args) {
22142
22435
  },
22143
22436
  []
22144
22437
  );
22145
- const handleDragEnd = React83__default.useCallback(
22438
+ const handleDragEnd = React84__default.useCallback(
22146
22439
  (event) => {
22147
22440
  const { active, over } = event;
22148
22441
  const activeIdStr = String(active.id);
@@ -22233,8 +22526,8 @@ function useDataDnd(args) {
22233
22526
  },
22234
22527
  [eventBus]
22235
22528
  );
22236
- const sortableData = React83__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
22237
- const SortableItem = React83__default.useCallback(
22529
+ const sortableData = React84__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
22530
+ const SortableItem = React84__default.useCallback(
22238
22531
  ({ id, children }) => {
22239
22532
  const {
22240
22533
  attributes,
@@ -22274,7 +22567,7 @@ function useDataDnd(args) {
22274
22567
  id: droppableId,
22275
22568
  data: sortableData
22276
22569
  });
22277
- const ctx = React83__default.useContext(RootCtx);
22570
+ const ctx = React84__default.useContext(RootCtx);
22278
22571
  const activeDrag2 = ctx?.activeDrag ?? null;
22279
22572
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
22280
22573
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -22289,7 +22582,7 @@ function useDataDnd(args) {
22289
22582
  showForeignPlaceholder,
22290
22583
  ctxAvailable: ctx != null
22291
22584
  });
22292
- React83__default.useEffect(() => {
22585
+ React84__default.useEffect(() => {
22293
22586
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
22294
22587
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
22295
22588
  return /* @__PURE__ */ jsx(
@@ -22303,11 +22596,11 @@ function useDataDnd(args) {
22303
22596
  }
22304
22597
  );
22305
22598
  };
22306
- const rootContextValue = React83__default.useMemo(
22599
+ const rootContextValue = React84__default.useMemo(
22307
22600
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
22308
22601
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
22309
22602
  );
22310
- const handleDragStart = React83__default.useCallback((event) => {
22603
+ const handleDragStart = React84__default.useCallback((event) => {
22311
22604
  const sourceZone = findZoneByItem(event.active.id);
22312
22605
  const rect = event.active.rect.current.initial;
22313
22606
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -22326,7 +22619,7 @@ function useDataDnd(args) {
22326
22619
  isRoot
22327
22620
  });
22328
22621
  }, [findZoneByItem, isRoot, zoneId]);
22329
- const handleDragOver = React83__default.useCallback((event) => {
22622
+ const handleDragOver = React84__default.useCallback((event) => {
22330
22623
  const { active, over } = event;
22331
22624
  const overData = over?.data?.current;
22332
22625
  const overGroup = overData?.dndGroup ?? null;
@@ -22396,7 +22689,7 @@ function useDataDnd(args) {
22396
22689
  return next;
22397
22690
  });
22398
22691
  }, []);
22399
- const handleDragCancel = React83__default.useCallback((event) => {
22692
+ const handleDragCancel = React84__default.useCallback((event) => {
22400
22693
  setActiveDrag(null);
22401
22694
  setOverZoneGroup(null);
22402
22695
  dndLog.warn("dragCancel", {
@@ -22404,12 +22697,12 @@ function useDataDnd(args) {
22404
22697
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
22405
22698
  });
22406
22699
  }, []);
22407
- const handleDragEndWithCleanup = React83__default.useCallback((event) => {
22700
+ const handleDragEndWithCleanup = React84__default.useCallback((event) => {
22408
22701
  handleDragEnd(event);
22409
22702
  setActiveDrag(null);
22410
22703
  setOverZoneGroup(null);
22411
22704
  }, [handleDragEnd]);
22412
- const wrapContainer = React83__default.useCallback(
22705
+ const wrapContainer = React84__default.useCallback(
22413
22706
  (children) => {
22414
22707
  if (!enabled) return children;
22415
22708
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -22463,7 +22756,7 @@ var init_useDataDnd = __esm({
22463
22756
  init_useAlmadarDndCollision();
22464
22757
  init_Box();
22465
22758
  dndLog = createLogger("almadar:ui:dnd");
22466
- RootCtx = React83__default.createContext(null);
22759
+ RootCtx = React84__default.createContext(null);
22467
22760
  }
22468
22761
  });
22469
22762
  function renderIconInput(icon, props) {
@@ -22660,7 +22953,7 @@ function DataGrid({
22660
22953
  /* @__PURE__ */ jsx(
22661
22954
  Box,
22662
22955
  {
22663
- className: cn("grid", gapStyles5[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles4[look], className),
22956
+ className: cn("grid", gapStyles5[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles5[look], className),
22664
22957
  style: scrollX ? { gridAutoFlow: "column", gridAutoColumns: `minmax(${minCardWidth}px, 1fr)` } : gridTemplateColumns ? { gridTemplateColumns } : void 0,
22665
22958
  children: data.map((item, index) => {
22666
22959
  const itemData = item;
@@ -22737,10 +23030,10 @@ function DataGrid({
22737
23030
  ] }),
22738
23031
  badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
22739
23032
  const val = getNestedValue(itemData, field.name);
22740
- if (val === void 0 || val === null) return null;
23033
+ if (val === void 0 || val === null || val === "") return null;
22741
23034
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
22742
23035
  field.icon && renderIconInput(field.icon, { size: "xs" }),
22743
- /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
23036
+ /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: formatValue(val, field.format) })
22744
23037
  ] }, field.name);
22745
23038
  }) })
22746
23039
  ] }),
@@ -22855,7 +23148,7 @@ function DataGrid({
22855
23148
  ] })
22856
23149
  );
22857
23150
  }
22858
- var dataGridLog, BADGE_VARIANTS, gapStyles5, lookStyles4;
23151
+ var dataGridLog, BADGE_VARIANTS, gapStyles5, lookStyles5;
22859
23152
  var init_DataGrid = __esm({
22860
23153
  "components/core/molecules/DataGrid.tsx"() {
22861
23154
  "use client";
@@ -22890,7 +23183,7 @@ var init_DataGrid = __esm({
22890
23183
  lg: "gap-6",
22891
23184
  xl: "gap-8"
22892
23185
  };
22893
- lookStyles4 = {
23186
+ lookStyles5 = {
22894
23187
  dense: "gap-2 [&>*]:p-card-sm",
22895
23188
  spacious: "gap-8 [&>*]:p-card-lg",
22896
23189
  striped: "[&>*:nth-child(even)]:bg-muted/30",
@@ -22990,7 +23283,7 @@ function DataList({
22990
23283
  }) {
22991
23284
  const eventBus = useEventBus();
22992
23285
  const { t } = useTranslate();
22993
- const [visibleCount, setVisibleCount] = React83__default.useState(pageSize || Infinity);
23286
+ const [visibleCount, setVisibleCount] = React84__default.useState(pageSize || Infinity);
22994
23287
  const fieldDefs = fields ?? columns ?? [];
22995
23288
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
22996
23289
  const dnd = useDataDnd({
@@ -23009,7 +23302,7 @@ function DataList({
23009
23302
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
23010
23303
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
23011
23304
  const hasRenderProp = typeof children === "function";
23012
- React83__default.useEffect(() => {
23305
+ React84__default.useEffect(() => {
23013
23306
  const renderItemTypeOf = typeof schemaRenderItem;
23014
23307
  const childrenTypeOf = typeof children;
23015
23308
  if (data.length > 0 && !hasRenderProp) {
@@ -23113,7 +23406,7 @@ function DataList({
23113
23406
  const items2 = [...data];
23114
23407
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
23115
23408
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
23116
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
23409
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
23117
23410
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
23118
23411
  group.items.map((itemData, index) => {
23119
23412
  const id = itemData.id || `${gi}-${index}`;
@@ -23254,7 +23547,7 @@ function DataList({
23254
23547
  className
23255
23548
  ),
23256
23549
  children: [
23257
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
23550
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
23258
23551
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
23259
23552
  group.items.map(
23260
23553
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -23339,7 +23632,7 @@ var init_FormSection = __esm({
23339
23632
  columns = 1,
23340
23633
  className
23341
23634
  }) => {
23342
- const [collapsed, setCollapsed] = React83__default.useState(defaultCollapsed);
23635
+ const [collapsed, setCollapsed] = React84__default.useState(defaultCollapsed);
23343
23636
  const { t } = useTranslate();
23344
23637
  const eventBus = useEventBus();
23345
23638
  const gridClass = {
@@ -23347,7 +23640,7 @@ var init_FormSection = __esm({
23347
23640
  2: "grid-cols-1 md:grid-cols-2",
23348
23641
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
23349
23642
  }[columns];
23350
- React83__default.useCallback(() => {
23643
+ React84__default.useCallback(() => {
23351
23644
  if (collapsible) {
23352
23645
  setCollapsed((prev) => !prev);
23353
23646
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -23605,129 +23898,6 @@ var init_FormField = __esm({
23605
23898
  FormField.displayName = "FormField";
23606
23899
  }
23607
23900
  });
23608
- function useSafeEventBus3() {
23609
- try {
23610
- return useEventBus();
23611
- } catch {
23612
- return { emit: () => {
23613
- }, on: () => () => {
23614
- }, once: () => {
23615
- } };
23616
- }
23617
- }
23618
- var log8, lookStyles5, ButtonGroup;
23619
- var init_ButtonGroup = __esm({
23620
- "components/core/molecules/ButtonGroup.tsx"() {
23621
- "use client";
23622
- init_cn();
23623
- init_atoms();
23624
- init_useEventBus();
23625
- log8 = createLogger("almadar:ui:button-group");
23626
- lookStyles5 = {
23627
- "right-aligned-buttons": "",
23628
- "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
23629
- "inline-row": "gap-2 inline-flex",
23630
- "dropdown-menu": "[&>button:not(:first-child)]:hidden",
23631
- "command-palette-trigger": "[&>button:not(:first-child)]:hidden"
23632
- };
23633
- ButtonGroup = ({
23634
- children,
23635
- primary,
23636
- secondary,
23637
- variant = "default",
23638
- orientation = "horizontal",
23639
- className,
23640
- // Filter-group pattern props (entity and filters are used for schema-driven filtering)
23641
- entity: _entity,
23642
- filters,
23643
- look = "right-aligned-buttons"
23644
- }) => {
23645
- const eventBus = useSafeEventBus3();
23646
- const variantClasses2 = {
23647
- default: "gap-0",
23648
- 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",
23649
- 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"
23650
- };
23651
- const orientationClasses = {
23652
- horizontal: "flex-row",
23653
- 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"
23654
- };
23655
- const handleActionClick = (action) => {
23656
- if (action.event) {
23657
- eventBus.emit("UI:DISPATCH", { event: action.event });
23658
- }
23659
- if (action.navigatesTo) {
23660
- eventBus.emit("UI:NAVIGATE", { url: action.navigatesTo });
23661
- }
23662
- };
23663
- const renderFormActions = () => {
23664
- const buttons = [];
23665
- if (secondary) {
23666
- secondary.forEach((action, index) => {
23667
- buttons.push(
23668
- /* @__PURE__ */ jsx(
23669
- Button,
23670
- {
23671
- type: action.actionType === "submit" ? "submit" : "button",
23672
- variant: action.variant || "ghost",
23673
- onClick: () => handleActionClick(action),
23674
- children: action.label
23675
- },
23676
- `secondary-${index}`
23677
- )
23678
- );
23679
- });
23680
- }
23681
- if (primary) {
23682
- const isSubmit = primary.actionType === "submit";
23683
- buttons.push(
23684
- /* @__PURE__ */ jsx(
23685
- Button,
23686
- {
23687
- type: isSubmit ? "submit" : "button",
23688
- variant: primary.variant || "primary",
23689
- onClick: () => handleActionClick(primary),
23690
- "data-testid": isSubmit ? "form-submit" : void 0,
23691
- children: primary.label
23692
- },
23693
- "primary"
23694
- )
23695
- );
23696
- }
23697
- return buttons;
23698
- };
23699
- const renderFilters = () => {
23700
- if (!filters || filters.length === 0) return null;
23701
- return filters.map((filter, index) => /* @__PURE__ */ jsx(
23702
- Button,
23703
- {
23704
- variant: "ghost",
23705
- onClick: () => {
23706
- log8.debug("Filter clicked", { field: filter.field });
23707
- },
23708
- children: filter.label
23709
- },
23710
- `filter-${filter.field}-${index}`
23711
- ));
23712
- };
23713
- return /* @__PURE__ */ jsx(
23714
- "div",
23715
- {
23716
- className: cn(
23717
- "inline-flex gap-2",
23718
- variantClasses2[variant],
23719
- orientationClasses[orientation],
23720
- lookStyles5[look],
23721
- className
23722
- ),
23723
- role: "group",
23724
- children: children || renderFilters() || renderFormActions()
23725
- }
23726
- );
23727
- };
23728
- ButtonGroup.displayName = "ButtonGroup";
23729
- }
23730
- });
23731
23901
  function getOrCreateStore(query) {
23732
23902
  if (!queryStores.has(query)) {
23733
23903
  queryStores.set(query, {
@@ -23904,7 +24074,7 @@ var init_FilterGroup = __esm({
23904
24074
  type: "button",
23905
24075
  onClick: () => handleFilterSelect(filter.field, null),
23906
24076
  className: cn(
23907
- "px-3 py-1.5 text-sm font-medium transition-all duration-[var(--transition-fast)]",
24077
+ "px-3 py-1.5 text-sm font-medium transition-all duration-fast",
23908
24078
  !selectedValues[filter.field] ? "bg-primary text-primary-foreground" : "bg-card text-muted-foreground hover:bg-muted"
23909
24079
  ),
23910
24080
  children: t("filterGroup.all")
@@ -23916,7 +24086,7 @@ var init_FilterGroup = __esm({
23916
24086
  type: "button",
23917
24087
  onClick: () => handleFilterSelect(filter.field, option),
23918
24088
  className: cn(
23919
- "px-3 py-1.5 text-sm font-medium transition-all duration-[var(--transition-fast)]",
24089
+ "px-3 py-1.5 text-sm font-medium transition-all duration-fast",
23920
24090
  "border-l-[length:var(--border-width)] border-border",
23921
24091
  selectedValues[filter.field] === option ? "bg-primary text-primary-foreground" : "bg-card text-muted-foreground hover:bg-muted"
23922
24092
  ),
@@ -24297,7 +24467,7 @@ var init_Flex = __esm({
24297
24467
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
24298
24468
  }
24299
24469
  }
24300
- return React83__default.createElement(Component, {
24470
+ return React84__default.createElement(Component, {
24301
24471
  className: cn(
24302
24472
  inline ? "inline-flex" : "flex",
24303
24473
  directionStyles[direction],
@@ -24416,7 +24586,7 @@ var init_Grid = __esm({
24416
24586
  as: Component = "div"
24417
24587
  }) => {
24418
24588
  const mergedStyle = rows ? { gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, ...style } : style;
24419
- return React83__default.createElement(
24589
+ return React84__default.createElement(
24420
24590
  Component,
24421
24591
  {
24422
24592
  className: cn(
@@ -24527,6 +24697,7 @@ var init_Popover = __esm({
24527
24697
  "components/core/molecules/Popover.tsx"() {
24528
24698
  "use client";
24529
24699
  init_Typography();
24700
+ init_Presence();
24530
24701
  init_cn();
24531
24702
  init_useTapReveal();
24532
24703
  arrowClasses = {
@@ -24550,6 +24721,7 @@ var init_Popover = __esm({
24550
24721
  const [popoverWidth, setPopoverWidth] = useState(0);
24551
24722
  const triggerRef = useRef(null);
24552
24723
  const popoverRef = useRef(null);
24724
+ const { mounted, className: panelAnim, onAnimationEnd } = usePresence(isOpen, { animation: "popover" });
24553
24725
  const updatePosition = () => {
24554
24726
  if (triggerRef.current) {
24555
24727
  setTriggerRect(triggerRef.current.getBoundingClientRect());
@@ -24575,10 +24747,11 @@ var init_Popover = __esm({
24575
24747
  useEffect(() => {
24576
24748
  if (isOpen) {
24577
24749
  updatePosition();
24578
- } else {
24579
- setPopoverWidth(0);
24580
24750
  }
24581
24751
  }, [isOpen]);
24752
+ useEffect(() => {
24753
+ if (!mounted) setPopoverWidth(0);
24754
+ }, [mounted]);
24582
24755
  useLayoutEffect(() => {
24583
24756
  if (isOpen && popoverRef.current) {
24584
24757
  const measured = popoverRef.current.offsetWidth;
@@ -24612,9 +24785,9 @@ var init_Popover = __esm({
24612
24785
  onMouseLeave: handleClose,
24613
24786
  onPointerDown: tapTriggerProps.onPointerDown
24614
24787
  };
24615
- const childElement = React83__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24788
+ const childElement = React84__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24616
24789
  const childPointerDown = childElement.props.onPointerDown;
24617
- const triggerElement = React83__default.cloneElement(
24790
+ const triggerElement = React84__default.cloneElement(
24618
24791
  childElement,
24619
24792
  {
24620
24793
  ref: triggerRef,
@@ -24627,13 +24800,14 @@ var init_Popover = __esm({
24627
24800
  } : void 0
24628
24801
  }
24629
24802
  );
24630
- const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
24803
+ const panel = mounted && triggerRect ? /* @__PURE__ */ jsxs(
24631
24804
  "div",
24632
24805
  {
24633
24806
  ref: popoverRef,
24634
24807
  className: cn(
24635
24808
  "fixed z-50 p-4",
24636
24809
  "bg-card border-2 border-border shadow-elevation-popover",
24810
+ panelAnim,
24637
24811
  className
24638
24812
  ),
24639
24813
  style: {
@@ -24641,6 +24815,7 @@ var init_Popover = __esm({
24641
24815
  ...popoverWidth === 0 ? { visibility: "hidden" } : void 0
24642
24816
  },
24643
24817
  role: "dialog",
24818
+ onAnimationEnd,
24644
24819
  onMouseEnter: trigger === "hover" ? handleOpen : void 0,
24645
24820
  onMouseLeave: trigger === "hover" ? handleClose : void 0,
24646
24821
  children: [
@@ -25054,6 +25229,7 @@ var init_SidePanel = __esm({
25054
25229
  init_Box();
25055
25230
  init_Button();
25056
25231
  init_Typography();
25232
+ init_Presence();
25057
25233
  init_cn();
25058
25234
  init_useEventBus();
25059
25235
  SidePanel = ({
@@ -25073,15 +25249,17 @@ var init_SidePanel = __esm({
25073
25249
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
25074
25250
  onClose();
25075
25251
  };
25076
- if (!isOpen) return null;
25252
+ const { mounted, className: panelAnim, onAnimationEnd } = usePresence(isOpen, { animation: "drawer" });
25253
+ const drawerSign = position === "right" ? 1 : -1;
25254
+ if (!mounted) return null;
25077
25255
  return /* @__PURE__ */ jsxs(Fragment, { children: [
25078
- showOverlay && /* @__PURE__ */ jsx(
25256
+ showOverlay && /* @__PURE__ */ jsx(Presence, { show: isOpen, animation: "overlay", children: /* @__PURE__ */ jsx(
25079
25257
  Box,
25080
25258
  {
25081
25259
  className: "fixed inset-0 bg-white/80 backdrop-blur-sm z-40 lg:hidden",
25082
25260
  onClick: handleClose
25083
25261
  }
25084
- ),
25262
+ ) }),
25085
25263
  /* @__PURE__ */ jsxs(
25086
25264
  Aside,
25087
25265
  {
@@ -25091,11 +25269,13 @@ var init_SidePanel = __esm({
25091
25269
  "border-l-2 border-border",
25092
25270
  position === "left" && "border-l-0 border-r-2",
25093
25271
  "flex flex-col",
25094
- "transition-transform duration-normal ease-standard",
25272
+ panelAnim,
25095
25273
  width,
25096
25274
  position === "right" ? "right-0" : "left-0",
25097
25275
  className
25098
25276
  ),
25277
+ style: { "--motion-drawer-sign": drawerSign },
25278
+ onAnimationEnd,
25099
25279
  children: [
25100
25280
  /* @__PURE__ */ jsxs(Box, { className: "flex items-center justify-between p-4 border-b-2 border-border sticky top-0 bg-card z-10", children: [
25101
25281
  /* @__PURE__ */ jsx(Typography, { variant: "h6", children: title }),
@@ -25216,9 +25396,9 @@ var init_Tooltip = __esm({
25216
25396
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
25217
25397
  };
25218
25398
  }, []);
25219
- const triggerElement = React83__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25399
+ const triggerElement = React84__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25220
25400
  const childPointerDown = triggerElement.props.onPointerDown;
25221
- const trigger = React83__default.cloneElement(triggerElement, {
25401
+ const trigger = React84__default.cloneElement(triggerElement, {
25222
25402
  ref: triggerRef,
25223
25403
  onMouseEnter: handleMouseEnter,
25224
25404
  onMouseLeave: handleMouseLeave,
@@ -25308,7 +25488,7 @@ var init_WizardProgress = __esm({
25308
25488
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
25309
25489
  const isActive = index === currentStep;
25310
25490
  const isCompleted = index < currentStep;
25311
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
25491
+ return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
25312
25492
  /* @__PURE__ */ jsx(
25313
25493
  "button",
25314
25494
  {
@@ -25859,7 +26039,7 @@ var init_FormSectionHeader = __esm({
25859
26039
  name: "chevron-down",
25860
26040
  size: "sm",
25861
26041
  className: cn(
25862
- "text-muted-foreground transition-transform duration-200 shrink-0",
26042
+ "text-muted-foreground transition-transform duration-fast shrink-0",
25863
26043
  isCollapsed && "-rotate-90"
25864
26044
  )
25865
26045
  }
@@ -26869,13 +27049,13 @@ var init_MapView = __esm({
26869
27049
  shadowSize: [41, 41]
26870
27050
  });
26871
27051
  L.Marker.prototype.options.icon = defaultIcon;
26872
- const { useEffect: useEffect61, useRef: useRef58, useCallback: useCallback92, useState: useState89 } = React83__default;
27052
+ const { useEffect: useEffect62, useRef: useRef59, useCallback: useCallback93, useState: useState91 } = React84__default;
26873
27053
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
26874
27054
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
26875
27055
  function MapUpdater({ centerLat, centerLng, zoom }) {
26876
27056
  const map = useMap();
26877
- const prevRef = useRef58({ centerLat, centerLng, zoom });
26878
- useEffect61(() => {
27057
+ const prevRef = useRef59({ centerLat, centerLng, zoom });
27058
+ useEffect62(() => {
26879
27059
  const prev = prevRef.current;
26880
27060
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
26881
27061
  map.setView([centerLat, centerLng], zoom);
@@ -26886,7 +27066,7 @@ var init_MapView = __esm({
26886
27066
  }
26887
27067
  function MapClickHandler({ onMapClick }) {
26888
27068
  const map = useMap();
26889
- useEffect61(() => {
27069
+ useEffect62(() => {
26890
27070
  if (!onMapClick) return;
26891
27071
  const handler = (e) => {
26892
27072
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -26914,8 +27094,8 @@ var init_MapView = __esm({
26914
27094
  showAttribution = true
26915
27095
  }) {
26916
27096
  const eventBus = useEventBus2();
26917
- const [clickedPosition, setClickedPosition] = useState89(null);
26918
- const handleMapClick = useCallback92((lat, lng) => {
27097
+ const [clickedPosition, setClickedPosition] = useState91(null);
27098
+ const handleMapClick = useCallback93((lat, lng) => {
26919
27099
  if (showClickedPin) {
26920
27100
  setClickedPosition({ lat, lng });
26921
27101
  }
@@ -26924,7 +27104,7 @@ var init_MapView = __esm({
26924
27104
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
26925
27105
  }
26926
27106
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
26927
- const handleMarkerClick = useCallback92((marker) => {
27107
+ const handleMarkerClick = useCallback93((marker) => {
26928
27108
  onMarkerClick?.(marker);
26929
27109
  if (markerClickEvent) {
26930
27110
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -27124,7 +27304,7 @@ var init_NumberStepper = __esm({
27124
27304
  "text-foreground",
27125
27305
  "hover:bg-muted",
27126
27306
  "active:bg-muted",
27127
- "transition-colors duration-100",
27307
+ "transition-colors duration-instant",
27128
27308
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27129
27309
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27130
27310
  styles.button
@@ -27165,7 +27345,7 @@ var init_NumberStepper = __esm({
27165
27345
  "text-foreground",
27166
27346
  "hover:bg-muted",
27167
27347
  "active:bg-muted",
27168
- "transition-colors duration-100",
27348
+ "transition-colors duration-instant",
27169
27349
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
27170
27350
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
27171
27351
  styles.button
@@ -27289,7 +27469,7 @@ var init_StarRating = __esm({
27289
27469
  className: cn(
27290
27470
  styles.star,
27291
27471
  "text-foreground/30",
27292
- "transition-colors duration-100"
27472
+ "transition-colors duration-instant"
27293
27473
  ),
27294
27474
  strokeWidth: 1.5
27295
27475
  }
@@ -27302,7 +27482,7 @@ var init_StarRating = __esm({
27302
27482
  styles.star,
27303
27483
  "absolute inset-0",
27304
27484
  "text-warning fill-warning",
27305
- "transition-colors duration-100"
27485
+ "transition-colors duration-instant"
27306
27486
  ),
27307
27487
  strokeWidth: 1.5,
27308
27488
  style: isHalf ? { clipPath: "inset(0 50% 0 0)" } : void 0
@@ -27457,7 +27637,7 @@ var init_UploadDropZone = __esm({
27457
27637
  "relative flex flex-col items-center justify-center",
27458
27638
  "p-8 rounded-sm",
27459
27639
  "border-2 border-dashed",
27460
- "transition-colors duration-150",
27640
+ "transition-colors duration-fast",
27461
27641
  "cursor-pointer",
27462
27642
  isDragOver ? "border-primary bg-primary bg-opacity-5" : "border-border bg-surface",
27463
27643
  error && "border-error",
@@ -27784,8 +27964,8 @@ function TableView({
27784
27964
  }) {
27785
27965
  const eventBus = useEventBus();
27786
27966
  const { t } = useTranslate();
27787
- const [visibleCount, setVisibleCount] = React83__default.useState(pageSize > 0 ? pageSize : Infinity);
27788
- const [localSelected, setLocalSelected] = React83__default.useState(/* @__PURE__ */ new Set());
27967
+ const [visibleCount, setVisibleCount] = React84__default.useState(pageSize > 0 ? pageSize : Infinity);
27968
+ const [localSelected, setLocalSelected] = React84__default.useState(/* @__PURE__ */ new Set());
27789
27969
  const colDefs = columns ?? fields ?? [];
27790
27970
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
27791
27971
  const dnd = useDataDnd({
@@ -27865,7 +28045,7 @@ function TableView({
27865
28045
  className: cn(
27866
28046
  "grid items-center gap-3 sticky top-0 z-10",
27867
28047
  "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
27868
- "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
28048
+ "text-muted-foreground uppercase text-xs font-semibold tracking-wide",
27869
28049
  lk.headPad
27870
28050
  ),
27871
28051
  children: [
@@ -27980,12 +28160,12 @@ function TableView({
27980
28160
  ]
27981
28161
  }
27982
28162
  );
27983
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React83__default.Fragment, { children: rowInner }, id);
28163
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React84__default.Fragment, { children: rowInner }, id);
27984
28164
  };
27985
28165
  const items = Array.from(data);
27986
28166
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
27987
28167
  let runningIndex = 0;
27988
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
28168
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
27989
28169
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
27990
28170
  group.items.map((row) => renderRow(row, runningIndex++))
27991
28171
  ] }, gi)) });
@@ -28721,7 +28901,7 @@ function SortableListInner({
28721
28901
  "flex items-center justify-center",
28722
28902
  "text-muted-foreground",
28723
28903
  "hover:text-foreground",
28724
- "transition-colors duration-100",
28904
+ "transition-colors duration-instant",
28725
28905
  "px-1"
28726
28906
  ),
28727
28907
  "aria-grabbed": ariaGrabbed,
@@ -28748,7 +28928,7 @@ function SortableListInner({
28748
28928
  gap: "sm",
28749
28929
  align: "center",
28750
28930
  className: cn(
28751
- "transition-opacity duration-150",
28931
+ "transition-opacity duration-fast",
28752
28932
  isBeingDragged && "opacity-50"
28753
28933
  ),
28754
28934
  children: [
@@ -28920,7 +29100,7 @@ var init_PullToRefresh = __esm({
28920
29100
  children: /* @__PURE__ */ jsx(
28921
29101
  Box,
28922
29102
  {
28923
- className: "transition-transform duration-150",
29103
+ className: "transition-transform duration-fast",
28924
29104
  style: {
28925
29105
  transform: `scale(${isRefreshing ? 1 : pullProgress})`,
28926
29106
  opacity: isRefreshing ? 1 : pullProgress
@@ -29342,7 +29522,7 @@ var init_StepFlow = __esm({
29342
29522
  className
29343
29523
  }) => {
29344
29524
  if (orientation === "vertical") {
29345
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React83__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
29525
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React84__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
29346
29526
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
29347
29527
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
29348
29528
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -29353,7 +29533,7 @@ var init_StepFlow = __esm({
29353
29533
  ] })
29354
29534
  ] }) }, index)) });
29355
29535
  }
29356
- 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(React83__default.Fragment, { children: [
29536
+ 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(React84__default.Fragment, { children: [
29357
29537
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
29358
29538
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
29359
29539
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -30230,6 +30410,11 @@ var init_VoteStack = __esm({
30230
30410
  {
30231
30411
  className: cn(
30232
30412
  "inline-flex items-center justify-center",
30413
+ // Shrink-wrap in stretch contexts (slot/sidecar wrappers are
30414
+ // flex-column with stretch alignment): without this the root spans
30415
+ // the full wrapper width and the count row's `w-full` turns the
30416
+ // compact pill into a page-wide band.
30417
+ "w-fit",
30233
30418
  variant === "vertical" ? "flex-col" : "flex-row",
30234
30419
  "rounded-sm",
30235
30420
  "border-[length:var(--border-width)] border-border",
@@ -30254,7 +30439,7 @@ var init_VoteStack = __esm({
30254
30439
  isUp ? "text-primary" : "text-muted-foreground",
30255
30440
  "hover:bg-muted",
30256
30441
  "active:bg-muted",
30257
- "transition-colors duration-100",
30442
+ "transition-colors duration-instant",
30258
30443
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30259
30444
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30260
30445
  styles.button
@@ -30291,7 +30476,7 @@ var init_VoteStack = __esm({
30291
30476
  isDown ? "text-primary" : "text-muted-foreground",
30292
30477
  "hover:bg-muted",
30293
30478
  "active:bg-muted",
30294
- "transition-colors duration-100",
30479
+ "transition-colors duration-instant",
30295
30480
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
30296
30481
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30297
30482
  styles.button
@@ -30338,7 +30523,7 @@ var init_LikertScale = __esm({
30338
30523
  md: "text-base",
30339
30524
  lg: "text-lg"
30340
30525
  };
30341
- LikertScale = React83__default.forwardRef(
30526
+ LikertScale = React84__default.forwardRef(
30342
30527
  ({
30343
30528
  question,
30344
30529
  options = DEFAULT_LIKERT_OPTIONS,
@@ -30350,7 +30535,7 @@ var init_LikertScale = __esm({
30350
30535
  variant = "radios",
30351
30536
  className
30352
30537
  }, ref) => {
30353
- const groupId = React83__default.useId();
30538
+ const groupId = React84__default.useId();
30354
30539
  const eventBus = useEventBus();
30355
30540
  const handleSelect = useCallback(
30356
30541
  (next) => {
@@ -30403,7 +30588,7 @@ var init_LikertScale = __esm({
30403
30588
  disabled,
30404
30589
  onClick: () => handleSelect(opt.value),
30405
30590
  className: cn(
30406
- "flex-1 text-center font-medium transition-colors duration-100",
30591
+ "flex-1 text-center font-medium transition-colors duration-instant",
30407
30592
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
30408
30593
  "disabled:cursor-not-allowed",
30409
30594
  "rounded-none gap-0 shadow-none border-none",
@@ -32632,7 +32817,7 @@ var init_DocBreadcrumb = __esm({
32632
32817
  "aria-label": t("aria.breadcrumb"),
32633
32818
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
32634
32819
  const isLast = idx === items.length - 1;
32635
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
32820
+ return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
32636
32821
  idx > 0 && /* @__PURE__ */ jsx(
32637
32822
  Icon,
32638
32823
  {
@@ -33501,7 +33686,7 @@ var init_MiniStateMachine = __esm({
33501
33686
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
33502
33687
  const tc = transitionCounts[s.name] ?? 0;
33503
33688
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
33504
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
33689
+ return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
33505
33690
  /* @__PURE__ */ jsx(
33506
33691
  AvlState,
33507
33692
  {
@@ -33705,7 +33890,7 @@ var init_PageHeader = __esm({
33705
33890
  info: "bg-info/10 text-info"
33706
33891
  };
33707
33892
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
33708
- 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(React83__default.Fragment, { children: [
33893
+ 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(React84__default.Fragment, { children: [
33709
33894
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
33710
33895
  crumb.href ? /* @__PURE__ */ jsx(
33711
33896
  "a",
@@ -34063,7 +34248,7 @@ var init_Section = __esm({
34063
34248
  as: Component = "section"
34064
34249
  }) => {
34065
34250
  const hasHeader = title || description || action;
34066
- return React83__default.createElement(
34251
+ return React84__default.createElement(
34067
34252
  Component,
34068
34253
  {
34069
34254
  className: cn(
@@ -34130,12 +34315,12 @@ var init_Sidebar = __esm({
34130
34315
  variant: "ghost",
34131
34316
  onClick: item.onClick,
34132
34317
  className: cn(
34133
- "w-full flex items-center gap-3 px-3 py-2.5 transition-all duration-[var(--transition-fast)] group relative",
34318
+ "w-full flex items-center gap-3 px-3 py-2.5 transition-all duration-fast group relative",
34134
34319
  "rounded-sm border-[length:var(--border-width-thin)] border-transparent",
34135
34320
  isActive ? [
34136
34321
  "bg-primary text-primary-foreground",
34137
34322
  "font-medium shadow-sm",
34138
- "border-primary translate-x-1 -translate-y-0.5"
34323
+ "border-primary translate-x-1 rtl:-translate-x-1 -translate-y-0.5"
34139
34324
  ].join(" ") : [
34140
34325
  "text-foreground",
34141
34326
  "hover:bg-muted hover:border-border",
@@ -34145,10 +34330,10 @@ var init_Sidebar = __esm({
34145
34330
  title: collapsed ? item.label : void 0,
34146
34331
  children: [
34147
34332
  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") })),
34148
- !collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-left", children: item.label }),
34333
+ !collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-start", children: item.label }),
34149
34334
  !collapsed && item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "danger", size: "sm", children: item.badge }),
34150
34335
  collapsed && /* @__PURE__ */ jsx(Box, { className: cn(
34151
- "absolute left-full ml-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
34336
+ "absolute start-full ms-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
34152
34337
  "pointer-events-none whitespace-nowrap z-50 transition-opacity",
34153
34338
  "bg-primary text-primary-foreground",
34154
34339
  "border-[length:var(--border-width-thin)] border-border",
@@ -34203,8 +34388,8 @@ var init_Sidebar = __esm({
34203
34388
  as: "aside",
34204
34389
  className: cn(
34205
34390
  "flex flex-col h-full",
34206
- "bg-card border-r border-border",
34207
- "transition-all duration-300 ease-in-out",
34391
+ "bg-card border-e border-border",
34392
+ "transition-all duration-normal ease-standard",
34208
34393
  collapsed ? "w-20" : "w-64",
34209
34394
  className
34210
34395
  ),
@@ -34437,7 +34622,7 @@ var init_WizardContainer = __esm({
34437
34622
  const isCompleted = index < currentStep;
34438
34623
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
34439
34624
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
34440
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
34625
+ return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
34441
34626
  /* @__PURE__ */ jsx(
34442
34627
  Button,
34443
34628
  {
@@ -35364,7 +35549,7 @@ function resolveColor3(color, el) {
35364
35549
  function truncateLabel(label) {
35365
35550
  return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
35366
35551
  }
35367
- var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
35552
+ var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, NO_NODES, NO_EDGES, NO_SIM, GraphCanvas;
35368
35553
  var init_GraphCanvas = __esm({
35369
35554
  "components/core/molecules/GraphCanvas.tsx"() {
35370
35555
  "use client";
@@ -35388,11 +35573,14 @@ var init_GraphCanvas = __esm({
35388
35573
  UNGROUPED_GRAVITY = 0.02;
35389
35574
  labelMeasureCtx = null;
35390
35575
  MAX_LABEL_CHARS = 22;
35576
+ NO_NODES = [];
35577
+ NO_EDGES = [];
35578
+ NO_SIM = [];
35391
35579
  GraphCanvas = ({
35392
35580
  title,
35393
- nodes: propNodes = [],
35394
- edges: propEdges = [],
35395
- similarity: propSimilarity = [],
35581
+ nodes: propNodes = NO_NODES,
35582
+ edges: propEdges = NO_EDGES,
35583
+ similarity: propSimilarity = NO_SIM,
35396
35584
  height = 400,
35397
35585
  showLabels = true,
35398
35586
  interactive = true,
@@ -35442,6 +35630,7 @@ var init_GraphCanvas = __esm({
35442
35630
  const interactionRef = useRef({
35443
35631
  mode: "none",
35444
35632
  dragNodeId: null,
35633
+ pressedNodeId: null,
35445
35634
  startMouse: { x: 0, y: 0 },
35446
35635
  startOffset: { x: 0, y: 0 },
35447
35636
  downPos: { x: 0, y: 0 }
@@ -35489,6 +35678,11 @@ var init_GraphCanvas = __esm({
35489
35678
  () => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
35490
35679
  [propNodes]
35491
35680
  );
35681
+ const nodesKey = useMemo(() => propNodes.map((n) => n.id).join(""), [propNodes]);
35682
+ const edgesKey = useMemo(
35683
+ () => propEdges.map((e) => `${e.source}${e.target}`).join(""),
35684
+ [propEdges]
35685
+ );
35492
35686
  useEffect(() => {
35493
35687
  const canvas = canvasRef.current;
35494
35688
  if (!canvas || propNodes.length === 0) return;
@@ -35669,7 +35863,7 @@ var init_GraphCanvas = __esm({
35669
35863
  return () => {
35670
35864
  cancelAnimationFrame(animRef.current);
35671
35865
  };
35672
- }, [propNodes, propEdges, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
35866
+ }, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
35673
35867
  useEffect(() => {
35674
35868
  const canvas = canvasRef.current;
35675
35869
  if (!canvas) return;
@@ -35799,6 +35993,7 @@ var init_GraphCanvas = __esm({
35799
35993
  const cancelSinglePointer = useCallback(() => {
35800
35994
  interactionRef.current.mode = "none";
35801
35995
  interactionRef.current.dragNodeId = null;
35996
+ interactionRef.current.pressedNodeId = null;
35802
35997
  }, []);
35803
35998
  const handlePointerDown = useCallback(
35804
35999
  (e) => {
@@ -35809,6 +36004,7 @@ var init_GraphCanvas = __esm({
35809
36004
  state.downPos = { x: e.clientX, y: e.clientY };
35810
36005
  state.startMouse = { x: e.clientX, y: e.clientY };
35811
36006
  state.startOffset = { ...offset };
36007
+ state.pressedNodeId = node?.id ?? null;
35812
36008
  if (draggable && node) {
35813
36009
  state.mode = "dragging";
35814
36010
  state.dragNodeId = node.id;
@@ -35860,7 +36056,8 @@ var init_GraphCanvas = __esm({
35860
36056
  if (moved < 4) {
35861
36057
  const coords = toCoords(e);
35862
36058
  if (!coords) return;
35863
- const node = nodeAt(coords.graphX, coords.graphY);
36059
+ const node = (state.pressedNodeId ? nodesRef.current.find((n) => n.id === state.pressedNodeId) : void 0) ?? nodeAt(coords.graphX, coords.graphY);
36060
+ state.pressedNodeId = null;
35864
36061
  if (node) {
35865
36062
  if (node.badge && node.badge > 1 && onBadgeClick) {
35866
36063
  const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
@@ -35880,6 +36077,7 @@ var init_GraphCanvas = __esm({
35880
36077
  );
35881
36078
  const handlePointerLeave = useCallback(() => {
35882
36079
  setHoveredNode(null);
36080
+ interactionRef.current.pressedNodeId = null;
35883
36081
  }, []);
35884
36082
  const gestureHandlers = useCanvasGestures({
35885
36083
  canvasRef,
@@ -37027,7 +37225,7 @@ var init_DetailPanel = __esm({
37027
37225
  }
37028
37226
  });
37029
37227
  function extractTitle(children) {
37030
- if (!React83__default.isValidElement(children)) return void 0;
37228
+ if (!React84__default.isValidElement(children)) return void 0;
37031
37229
  const props = children.props;
37032
37230
  if (typeof props.title === "string") {
37033
37231
  return props.title;
@@ -37377,12 +37575,12 @@ var init_Form = __esm({
37377
37575
  const isSchemaEntity = isOrbitalEntitySchema(entity);
37378
37576
  const resolvedEntity = isSchemaEntity ? entity : void 0;
37379
37577
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
37380
- const normalizedInitialData = React83__default.useMemo(() => {
37578
+ const normalizedInitialData = React84__default.useMemo(() => {
37381
37579
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
37382
37580
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
37383
37581
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
37384
37582
  }, [entity, initialData]);
37385
- const entityDerivedFields = React83__default.useMemo(() => {
37583
+ const entityDerivedFields = React84__default.useMemo(() => {
37386
37584
  if (fields && fields.length > 0) return void 0;
37387
37585
  if (!resolvedEntity) return void 0;
37388
37586
  return resolvedEntity.fields.map(
@@ -37403,16 +37601,16 @@ var init_Form = __esm({
37403
37601
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
37404
37602
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
37405
37603
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
37406
- const [formData, setFormData] = React83__default.useState(
37604
+ const [formData, setFormData] = React84__default.useState(
37407
37605
  normalizedInitialData
37408
37606
  );
37409
- const [collapsedSections, setCollapsedSections] = React83__default.useState(
37607
+ const [collapsedSections, setCollapsedSections] = React84__default.useState(
37410
37608
  /* @__PURE__ */ new Set()
37411
37609
  );
37412
- const [submitError, setSubmitError] = React83__default.useState(null);
37413
- const formRef = React83__default.useRef(null);
37610
+ const [submitError, setSubmitError] = React84__default.useState(null);
37611
+ const formRef = React84__default.useRef(null);
37414
37612
  const formMode = props.mode;
37415
- const mountedRef = React83__default.useRef(false);
37613
+ const mountedRef = React84__default.useRef(false);
37416
37614
  if (!mountedRef.current) {
37417
37615
  mountedRef.current = true;
37418
37616
  debug("forms", "mount", {
@@ -37425,7 +37623,7 @@ var init_Form = __esm({
37425
37623
  });
37426
37624
  }
37427
37625
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
37428
- const evalContext = React83__default.useMemo(
37626
+ const evalContext = React84__default.useMemo(
37429
37627
  () => ({
37430
37628
  formValues: formData,
37431
37629
  globalVariables: externalContext?.globalVariables ?? {},
@@ -37434,7 +37632,7 @@ var init_Form = __esm({
37434
37632
  }),
37435
37633
  [formData, externalContext]
37436
37634
  );
37437
- React83__default.useEffect(() => {
37635
+ React84__default.useEffect(() => {
37438
37636
  debug("forms", "initialData-sync", {
37439
37637
  mode: formMode,
37440
37638
  normalizedInitialData,
@@ -37445,7 +37643,7 @@ var init_Form = __esm({
37445
37643
  setFormData(normalizedInitialData);
37446
37644
  }
37447
37645
  }, [normalizedInitialData]);
37448
- const processCalculations = React83__default.useCallback(
37646
+ const processCalculations = React84__default.useCallback(
37449
37647
  (changedFieldId, newFormData) => {
37450
37648
  if (!hiddenCalculations.length) return;
37451
37649
  const context = {
@@ -37470,7 +37668,7 @@ var init_Form = __esm({
37470
37668
  },
37471
37669
  [hiddenCalculations, externalContext, eventBus]
37472
37670
  );
37473
- const checkViolations = React83__default.useCallback(
37671
+ const checkViolations = React84__default.useCallback(
37474
37672
  (changedFieldId, newFormData) => {
37475
37673
  if (!violationTriggers.length) return;
37476
37674
  const context = {
@@ -37508,7 +37706,7 @@ var init_Form = __esm({
37508
37706
  processCalculations(name, newFormData);
37509
37707
  checkViolations(name, newFormData);
37510
37708
  };
37511
- const isFieldVisible = React83__default.useCallback(
37709
+ const isFieldVisible = React84__default.useCallback(
37512
37710
  (fieldName) => {
37513
37711
  const condition = conditionalFields[fieldName];
37514
37712
  if (!condition) return true;
@@ -37516,7 +37714,7 @@ var init_Form = __esm({
37516
37714
  },
37517
37715
  [conditionalFields, evalContext]
37518
37716
  );
37519
- const isSectionVisible = React83__default.useCallback(
37717
+ const isSectionVisible = React84__default.useCallback(
37520
37718
  (section) => {
37521
37719
  if (!section.condition) return true;
37522
37720
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -37592,7 +37790,7 @@ var init_Form = __esm({
37592
37790
  eventBus.emit(`UI:${onCancel}`);
37593
37791
  }
37594
37792
  };
37595
- const renderField = React83__default.useCallback(
37793
+ const renderField = React84__default.useCallback(
37596
37794
  (field) => {
37597
37795
  const fieldName = field.name || field.field;
37598
37796
  if (!fieldName) return null;
@@ -37613,7 +37811,7 @@ var init_Form = __esm({
37613
37811
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
37614
37812
  );
37615
37813
  const effectiveFields = entityDerivedFields ?? fields;
37616
- const normalizedFields = React83__default.useMemo(() => {
37814
+ const normalizedFields = React84__default.useMemo(() => {
37617
37815
  if (!effectiveFields || effectiveFields.length === 0) return [];
37618
37816
  return effectiveFields.map((field) => {
37619
37817
  if (typeof field === "string") {
@@ -37637,7 +37835,7 @@ var init_Form = __esm({
37637
37835
  return field;
37638
37836
  });
37639
37837
  }, [effectiveFields, resolvedEntity]);
37640
- const schemaFields = React83__default.useMemo(() => {
37838
+ const schemaFields = React84__default.useMemo(() => {
37641
37839
  if (normalizedFields.length === 0) return null;
37642
37840
  if (isDebugEnabled()) {
37643
37841
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -37647,7 +37845,7 @@ var init_Form = __esm({
37647
37845
  }
37648
37846
  return normalizedFields.map(renderField).filter(Boolean);
37649
37847
  }, [normalizedFields, renderField, entityName, conditionalFields]);
37650
- const sectionElements = React83__default.useMemo(() => {
37848
+ const sectionElements = React84__default.useMemo(() => {
37651
37849
  if (!sections || sections.length === 0) return null;
37652
37850
  return sections.map((section) => {
37653
37851
  if (!isSectionVisible(section)) {
@@ -38330,7 +38528,7 @@ var init_List = __esm({
38330
38528
  Box,
38331
38529
  {
38332
38530
  className: cn(
38333
- "h-full rounded-full transition-all duration-500",
38531
+ "h-full rounded-full transition-all duration-slow",
38334
38532
  clampedValue >= 100 ? "bg-success" : clampedValue >= 70 ? "bg-info" : clampedValue >= 40 ? "bg-warning" : "bg-muted-foreground"
38335
38533
  ),
38336
38534
  style: { width: `${clampedValue}%` }
@@ -38372,7 +38570,7 @@ var init_List = __esm({
38372
38570
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
38373
38571
  return [];
38374
38572
  }, [entity]);
38375
- const getItemActions = React83__default.useCallback(
38573
+ const getItemActions = React84__default.useCallback(
38376
38574
  (item) => {
38377
38575
  if (!itemActions) return [];
38378
38576
  if (typeof itemActions === "function") {
@@ -38499,7 +38697,7 @@ var init_List = __esm({
38499
38697
  {
38500
38698
  className: cn(
38501
38699
  "group flex items-center gap-5 px-6 py-5",
38502
- "transition-all duration-300 ease-out",
38700
+ "transition-all duration-normal ease-standard",
38503
38701
  hasExplicitClick && "cursor-pointer",
38504
38702
  // Hover state
38505
38703
  "hover:bg-muted/80",
@@ -38606,7 +38804,7 @@ var init_List = __esm({
38606
38804
  variant: "ghost",
38607
38805
  action: editAction.event,
38608
38806
  className: cn(
38609
- "p-2 rounded-lg transition-all duration-200",
38807
+ "p-2 rounded-lg transition-all duration-fast",
38610
38808
  "hover:bg-primary/10 hover:text-primary",
38611
38809
  "text-muted-foreground",
38612
38810
  "active:scale-95"
@@ -38622,7 +38820,7 @@ var init_List = __esm({
38622
38820
  variant: "ghost",
38623
38821
  action: viewAction.event,
38624
38822
  className: cn(
38625
- "p-2 rounded-lg transition-all duration-200",
38823
+ "p-2 rounded-lg transition-all duration-fast",
38626
38824
  "hover:bg-muted hover:text-foreground",
38627
38825
  "text-muted-foreground",
38628
38826
  "active:scale-95"
@@ -38644,7 +38842,7 @@ var init_List = __esm({
38644
38842
  {
38645
38843
  variant: "ghost",
38646
38844
  className: cn(
38647
- "p-2 rounded-lg transition-all duration-200",
38845
+ "p-2 rounded-lg transition-all duration-fast",
38648
38846
  "hover:bg-muted hover:shadow-sm",
38649
38847
  "text-muted-foreground hover:text-foreground",
38650
38848
  "active:scale-95"
@@ -38831,8 +39029,17 @@ var init_MediaGallery = __esm({
38831
39029
  const eventBus = useEventBus();
38832
39030
  const { t } = useTranslate();
38833
39031
  const [lightboxItem, setLightboxItem] = useState(null);
39032
+ const [failedIds, setFailedIds] = useState(/* @__PURE__ */ new Set());
38834
39033
  const closeLightbox = useCallback(() => setLightboxItem(null), []);
38835
39034
  useEventListener("UI:LIGHTBOX_CLOSE", closeLightbox);
39035
+ const handleImageError = useCallback((id) => {
39036
+ setFailedIds((prev) => {
39037
+ if (prev.has(id)) return prev;
39038
+ const next = new Set(prev);
39039
+ next.add(id);
39040
+ return next;
39041
+ });
39042
+ }, []);
38836
39043
  const handleItemClick = useCallback(
38837
39044
  (item) => {
38838
39045
  if (selectable) {
@@ -38847,8 +39054,8 @@ var init_MediaGallery = __esm({
38847
39054
  [selectable, selectedItems, selectionEvent, eventBus]
38848
39055
  );
38849
39056
  const entityData = Array.isArray(entity) ? entity : [];
38850
- const items = React83__default.useMemo(() => {
38851
- if (propItems) return propItems;
39057
+ const items = React84__default.useMemo(() => {
39058
+ if (propItems && propItems.length > 0) return propItems;
38852
39059
  if (entityData.length === 0) return [];
38853
39060
  return entityData.map((record, idx) => {
38854
39061
  return {
@@ -38925,19 +39132,20 @@ var init_MediaGallery = __esm({
38925
39132
  {
38926
39133
  className: cn(
38927
39134
  "group relative overflow-hidden rounded-md cursor-pointer",
38928
- "border-2 transition-all duration-200",
39135
+ "border-2 transition-all duration-fast",
38929
39136
  isSelected ? "border-primary ring-2 ring-primary/30" : "border-transparent hover:border-border",
38930
39137
  ASPECT_CLASSES[aspectRatio]
38931
39138
  ),
38932
39139
  onClick: () => handleItemClick(item),
38933
39140
  children: [
38934
- /* @__PURE__ */ jsx(
39141
+ 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(
38935
39142
  "img",
38936
39143
  {
38937
39144
  src: item.thumbnail || item.src,
38938
39145
  alt: item.alt || item.caption || "",
38939
39146
  className: "w-full h-full object-cover",
38940
- loading: "lazy"
39147
+ loading: "lazy",
39148
+ onError: () => handleImageError(item.id)
38941
39149
  }
38942
39150
  ),
38943
39151
  /* @__PURE__ */ jsx(
@@ -38945,14 +39153,14 @@ var init_MediaGallery = __esm({
38945
39153
  {
38946
39154
  className: cn(
38947
39155
  "absolute inset-0 bg-foreground/0 group-hover:bg-foreground/20",
38948
- "transition-colors duration-200 flex items-center justify-center"
39156
+ "transition-colors duration-fast flex items-center justify-center"
38949
39157
  ),
38950
39158
  children: /* @__PURE__ */ jsx(
38951
39159
  Icon,
38952
39160
  {
38953
39161
  icon: ZoomIn,
38954
39162
  size: "md",
38955
- className: "text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200"
39163
+ className: "text-white opacity-0 group-hover:opacity-100 transition-opacity duration-fast"
38956
39164
  }
38957
39165
  )
38958
39166
  }
@@ -39010,7 +39218,7 @@ var init_MediaGallery = __esm({
39010
39218
  }
39011
39219
  });
39012
39220
  function extractTitle2(children) {
39013
- if (!React83__default.isValidElement(children)) return void 0;
39221
+ if (!React84__default.isValidElement(children)) return void 0;
39014
39222
  const props = children.props;
39015
39223
  if (typeof props.title === "string") {
39016
39224
  return props.title;
@@ -39265,7 +39473,7 @@ var init_debugRegistry = __esm({
39265
39473
  }
39266
39474
  });
39267
39475
  function useDebugData() {
39268
- const [data, setData] = React83.useState(() => ({
39476
+ const [data, setData] = React84.useState(() => ({
39269
39477
  traits: [],
39270
39478
  ticks: [],
39271
39479
  guards: [],
@@ -39279,7 +39487,7 @@ function useDebugData() {
39279
39487
  },
39280
39488
  lastUpdate: Date.now()
39281
39489
  }));
39282
- React83.useEffect(() => {
39490
+ React84.useEffect(() => {
39283
39491
  const updateData = () => {
39284
39492
  setData({
39285
39493
  traits: getAllTraits(),
@@ -39388,12 +39596,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
39388
39596
  return positions;
39389
39597
  }
39390
39598
  function WalkMinimap() {
39391
- const [walkStep, setWalkStep] = React83.useState(null);
39392
- const [traits2, setTraits] = React83.useState([]);
39393
- const [coveredEdges, setCoveredEdges] = React83.useState([]);
39394
- const [completedTraits, setCompletedTraits] = React83.useState(/* @__PURE__ */ new Set());
39395
- const prevTraitRef = React83.useRef(null);
39396
- React83.useEffect(() => {
39599
+ const [walkStep, setWalkStep] = React84.useState(null);
39600
+ const [traits2, setTraits] = React84.useState([]);
39601
+ const [coveredEdges, setCoveredEdges] = React84.useState([]);
39602
+ const [completedTraits, setCompletedTraits] = React84.useState(/* @__PURE__ */ new Set());
39603
+ const prevTraitRef = React84.useRef(null);
39604
+ React84.useEffect(() => {
39397
39605
  const interval = setInterval(() => {
39398
39606
  const w = window;
39399
39607
  const step = w.__orbitalWalkStep;
@@ -39829,15 +40037,15 @@ var init_EntitiesTab = __esm({
39829
40037
  });
39830
40038
  function EventFlowTab({ events: events2 }) {
39831
40039
  const { t } = useTranslate();
39832
- const [filter, setFilter] = React83.useState("all");
39833
- const containerRef = React83.useRef(null);
39834
- const [autoScroll, setAutoScroll] = React83.useState(true);
39835
- React83.useEffect(() => {
40040
+ const [filter, setFilter] = React84.useState("all");
40041
+ const containerRef = React84.useRef(null);
40042
+ const [autoScroll, setAutoScroll] = React84.useState(true);
40043
+ React84.useEffect(() => {
39836
40044
  if (autoScroll && containerRef.current) {
39837
40045
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
39838
40046
  }
39839
40047
  }, [events2.length, autoScroll]);
39840
- const filteredEvents = React83.useMemo(() => {
40048
+ const filteredEvents = React84.useMemo(() => {
39841
40049
  if (filter === "all") return events2;
39842
40050
  return events2.filter((e) => e.type === filter);
39843
40051
  }, [events2, filter]);
@@ -39953,7 +40161,7 @@ var init_EventFlowTab = __esm({
39953
40161
  });
39954
40162
  function GuardsPanel({ guards }) {
39955
40163
  const { t } = useTranslate();
39956
- const [filter, setFilter] = React83.useState("all");
40164
+ const [filter, setFilter] = React84.useState("all");
39957
40165
  if (guards.length === 0) {
39958
40166
  return /* @__PURE__ */ jsx(
39959
40167
  EmptyState,
@@ -39966,7 +40174,7 @@ function GuardsPanel({ guards }) {
39966
40174
  }
39967
40175
  const passedCount = guards.filter((g) => g.result).length;
39968
40176
  const failedCount = guards.length - passedCount;
39969
- const filteredGuards = React83.useMemo(() => {
40177
+ const filteredGuards = React84.useMemo(() => {
39970
40178
  if (filter === "all") return guards;
39971
40179
  if (filter === "passed") return guards.filter((g) => g.result);
39972
40180
  return guards.filter((g) => !g.result);
@@ -40129,10 +40337,10 @@ function EffectBadge({ effect }) {
40129
40337
  }
40130
40338
  function TransitionTimeline({ transitions }) {
40131
40339
  const { t } = useTranslate();
40132
- const containerRef = React83.useRef(null);
40133
- const [autoScroll, setAutoScroll] = React83.useState(true);
40134
- const [expandedId, setExpandedId] = React83.useState(null);
40135
- React83.useEffect(() => {
40340
+ const containerRef = React84.useRef(null);
40341
+ const [autoScroll, setAutoScroll] = React84.useState(true);
40342
+ const [expandedId, setExpandedId] = React84.useState(null);
40343
+ React84.useEffect(() => {
40136
40344
  if (autoScroll && containerRef.current) {
40137
40345
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
40138
40346
  }
@@ -40412,9 +40620,9 @@ function getAllEvents(traits2) {
40412
40620
  function EventDispatcherTab({ traits: traits2, schema }) {
40413
40621
  const eventBus = useEventBus();
40414
40622
  const { t } = useTranslate();
40415
- const [log13, setLog] = React83.useState([]);
40416
- const prevStatesRef = React83.useRef(/* @__PURE__ */ new Map());
40417
- React83.useEffect(() => {
40623
+ const [log13, setLog] = React84.useState([]);
40624
+ const prevStatesRef = React84.useRef(/* @__PURE__ */ new Map());
40625
+ React84.useEffect(() => {
40418
40626
  for (const trait of traits2) {
40419
40627
  const prev = prevStatesRef.current.get(trait.id);
40420
40628
  if (prev && prev !== trait.currentState) {
@@ -40583,10 +40791,10 @@ function VerifyModePanel({
40583
40791
  localCount
40584
40792
  }) {
40585
40793
  const { t } = useTranslate();
40586
- const [expanded, setExpanded] = React83.useState(true);
40587
- const scrollRef = React83.useRef(null);
40588
- const prevCountRef = React83.useRef(0);
40589
- React83.useEffect(() => {
40794
+ const [expanded, setExpanded] = React84.useState(true);
40795
+ const scrollRef = React84.useRef(null);
40796
+ const prevCountRef = React84.useRef(0);
40797
+ React84.useEffect(() => {
40590
40798
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
40591
40799
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
40592
40800
  }
@@ -40643,10 +40851,10 @@ function RuntimeDebugger({
40643
40851
  schema
40644
40852
  }) {
40645
40853
  const { t } = useTranslate();
40646
- const [isCollapsed, setIsCollapsed] = React83.useState(mode === "verify" ? true : defaultCollapsed);
40647
- const [isVisible, setIsVisible] = React83.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
40854
+ const [isCollapsed, setIsCollapsed] = React84.useState(mode === "verify" ? true : defaultCollapsed);
40855
+ const [isVisible, setIsVisible] = React84.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
40648
40856
  const debugData = useDebugData();
40649
- React83.useEffect(() => {
40857
+ React84.useEffect(() => {
40650
40858
  if (mode === "inline") return;
40651
40859
  return onDebugToggle((enabled) => {
40652
40860
  setIsVisible(enabled);
@@ -40655,7 +40863,7 @@ function RuntimeDebugger({
40655
40863
  }
40656
40864
  });
40657
40865
  }, [mode]);
40658
- React83.useEffect(() => {
40866
+ React84.useEffect(() => {
40659
40867
  if (mode === "inline") return;
40660
40868
  const handleKeyDown = (e) => {
40661
40869
  if (e.key === "`" && isVisible) {
@@ -41175,7 +41383,7 @@ var init_StatCard = __esm({
41175
41383
  const labelToUse = propLabel ?? propTitle;
41176
41384
  const eventBus = useEventBus();
41177
41385
  const { t } = useTranslate();
41178
- const handleActionClick = React83__default.useCallback(() => {
41386
+ const handleActionClick = React84__default.useCallback(() => {
41179
41387
  if (action?.event) {
41180
41388
  eventBus.emit(`UI:${action.event}`, {});
41181
41389
  }
@@ -41186,7 +41394,7 @@ var init_StatCard = __esm({
41186
41394
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
41187
41395
  const isLoading = externalLoading ?? false;
41188
41396
  const error = externalError;
41189
- const computeMetricValue = React83__default.useCallback(
41397
+ const computeMetricValue = React84__default.useCallback(
41190
41398
  (metric, items) => {
41191
41399
  if (metric.value !== void 0) {
41192
41400
  return metric.value;
@@ -41225,7 +41433,7 @@ var init_StatCard = __esm({
41225
41433
  },
41226
41434
  []
41227
41435
  );
41228
- const schemaStats = React83__default.useMemo(() => {
41436
+ const schemaStats = React84__default.useMemo(() => {
41229
41437
  if (!metrics || metrics.length === 0) return null;
41230
41438
  return metrics.map((metric) => ({
41231
41439
  label: metric.label,
@@ -41233,7 +41441,7 @@ var init_StatCard = __esm({
41233
41441
  format: metric.format
41234
41442
  }));
41235
41443
  }, [metrics, data, computeMetricValue]);
41236
- const calculatedTrend = React83__default.useMemo(() => {
41444
+ const calculatedTrend = React84__default.useMemo(() => {
41237
41445
  if (manualTrend !== void 0) return manualTrend;
41238
41446
  if (previousValue === void 0 || currentValue === void 0)
41239
41447
  return void 0;
@@ -41873,8 +42081,8 @@ var init_SubagentTracePanel = __esm({
41873
42081
  ] });
41874
42082
  };
41875
42083
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
41876
- const endRef = React83__default.useRef(null);
41877
- React83__default.useEffect(() => {
42084
+ const endRef = React84__default.useRef(null);
42085
+ React84__default.useEffect(() => {
41878
42086
  if (!autoScroll) return;
41879
42087
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
41880
42088
  }, [activities.length, autoScroll]);
@@ -41968,7 +42176,7 @@ var init_SubagentTracePanel = __esm({
41968
42176
  };
41969
42177
  SubagentRichCard = ({ subagent }) => {
41970
42178
  const { t } = useTranslate();
41971
- const activities = React83__default.useMemo(
42179
+ const activities = React84__default.useMemo(
41972
42180
  () => subagentMessagesToActivities(subagent.messages),
41973
42181
  [subagent.messages]
41974
42182
  );
@@ -42045,8 +42253,8 @@ var init_SubagentTracePanel = __esm({
42045
42253
  ] });
42046
42254
  };
42047
42255
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
42048
- const endRef = React83__default.useRef(null);
42049
- React83__default.useEffect(() => {
42256
+ const endRef = React84__default.useRef(null);
42257
+ React84__default.useEffect(() => {
42050
42258
  if (!autoScroll) return;
42051
42259
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
42052
42260
  }, [messages.length, autoScroll]);
@@ -42425,6 +42633,11 @@ var init_TeamOrganism = __esm({
42425
42633
  TeamOrganism.displayName = "TeamOrganism";
42426
42634
  }
42427
42635
  });
42636
+ function formatDate4(value) {
42637
+ const d = new Date(value);
42638
+ if (isNaN(d.getTime())) return value;
42639
+ return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
42640
+ }
42428
42641
  var lookStyles10, STATUS_STYLES2, Timeline;
42429
42642
  var init_Timeline = __esm({
42430
42643
  "components/core/organisms/Timeline.tsx"() {
@@ -42476,7 +42689,7 @@ var init_Timeline = __esm({
42476
42689
  }) => {
42477
42690
  const { t } = useTranslate();
42478
42691
  const entityData = entity ?? [];
42479
- const items = React83__default.useMemo(() => {
42692
+ const items = React84__default.useMemo(() => {
42480
42693
  if (propItems) return propItems;
42481
42694
  if (entityData.length === 0) return [];
42482
42695
  return entityData.map((record, idx) => {
@@ -42552,7 +42765,7 @@ var init_Timeline = __esm({
42552
42765
  /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
42553
42766
  /* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
42554
42767
  /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
42555
- item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: item.date })
42768
+ item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: formatDate4(item.date) })
42556
42769
  ] }),
42557
42770
  item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
42558
42771
  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)) }),
@@ -42578,7 +42791,7 @@ var init_Timeline = __esm({
42578
42791
  }
42579
42792
  });
42580
42793
  function extractToastProps(children) {
42581
- if (!React83__default.isValidElement(children)) {
42794
+ if (!React84__default.isValidElement(children)) {
42582
42795
  if (typeof children === "string") {
42583
42796
  return { message: children };
42584
42797
  }
@@ -42620,7 +42833,7 @@ var init_ToastSlot = __esm({
42620
42833
  eventBus.emit(`${prefix}CLOSE`);
42621
42834
  };
42622
42835
  if (!isVisible) return null;
42623
- const isCustomContent = React83__default.isValidElement(children) && !message;
42836
+ const isCustomContent = React84__default.isValidElement(children) && !message;
42624
42837
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
42625
42838
  Toast,
42626
42839
  {
@@ -42668,6 +42881,7 @@ var init_component_registry_generated = __esm({
42668
42881
  init_LayoutPatterns();
42669
42882
  init_BranchingLogicBuilder();
42670
42883
  init_Breadcrumb();
42884
+ init_ButtonGroup();
42671
42885
  init_CTABanner();
42672
42886
  init_CalendarGrid();
42673
42887
  init_Canvas();
@@ -42738,8 +42952,8 @@ var init_component_registry_generated = __esm({
42738
42952
  init_FlipContainer();
42739
42953
  init_FloatingActionButton();
42740
42954
  init_Form();
42741
- init_FormSection();
42742
42955
  init_FormField();
42956
+ init_FormSection();
42743
42957
  init_FormSectionHeader();
42744
42958
  init_GameAudioToggle();
42745
42959
  init_GameHud();
@@ -42925,6 +43139,7 @@ var init_component_registry_generated = __esm({
42925
43139
  "BranchingLogicBuilder": BranchingLogicBuilder,
42926
43140
  "Breadcrumb": Breadcrumb,
42927
43141
  "Button": ButtonPattern,
43142
+ "ButtonGroup": ButtonGroup,
42928
43143
  "ButtonPattern": ButtonPattern,
42929
43144
  "CTABanner": CTABanner,
42930
43145
  "CalendarGrid": CalendarGrid,
@@ -42998,7 +43213,6 @@ var init_component_registry_generated = __esm({
42998
43213
  "FlipContainer": FlipContainer,
42999
43214
  "FloatingActionButton": FloatingActionButton,
43000
43215
  "Form": Form,
43001
- "FormActions": FormActions,
43002
43216
  "FormField": FormField,
43003
43217
  "FormLayout": FormLayout,
43004
43218
  "FormSectionHeader": FormSectionHeader,
@@ -43178,7 +43392,7 @@ function SuspenseConfigProvider({
43178
43392
  config,
43179
43393
  children
43180
43394
  }) {
43181
- return React83__default.createElement(
43395
+ return React84__default.createElement(
43182
43396
  SuspenseConfigContext.Provider,
43183
43397
  { value: config },
43184
43398
  children
@@ -43220,7 +43434,7 @@ function enrichFormFields(fields, entityDef) {
43220
43434
  }
43221
43435
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
43222
43436
  }
43223
- if (field && typeof field === "object" && !Array.isArray(field) && !React83__default.isValidElement(field) && !(field instanceof Date)) {
43437
+ if (field && typeof field === "object" && !Array.isArray(field) && !React84__default.isValidElement(field) && !(field instanceof Date)) {
43224
43438
  const obj = field;
43225
43439
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
43226
43440
  if (!fieldName) return field;
@@ -43673,7 +43887,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
43673
43887
  const key = `${parentId}-${index}-trait:${traitName}`;
43674
43888
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
43675
43889
  }
43676
- return /* @__PURE__ */ jsx(React83__default.Fragment, { children: child }, `${parentId}-${index}`);
43890
+ return /* @__PURE__ */ jsx(React84__default.Fragment, { children: child }, `${parentId}-${index}`);
43677
43891
  }
43678
43892
  if (!child || typeof child !== "object") return null;
43679
43893
  const childId = `${parentId}-${index}`;
@@ -43726,14 +43940,14 @@ function isPatternConfig(value) {
43726
43940
  if (value === null || value === void 0) return false;
43727
43941
  if (typeof value !== "object") return false;
43728
43942
  if (Array.isArray(value)) return false;
43729
- if (React83__default.isValidElement(value)) return false;
43943
+ if (React84__default.isValidElement(value)) return false;
43730
43944
  if (value instanceof Date) return false;
43731
43945
  if (typeof value === "function") return false;
43732
43946
  const record = value;
43733
43947
  return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
43734
43948
  }
43735
43949
  function isPlainConfigObject(value) {
43736
- if (React83__default.isValidElement(value)) return false;
43950
+ if (React84__default.isValidElement(value)) return false;
43737
43951
  if (value instanceof Date) return false;
43738
43952
  const proto = Object.getPrototypeOf(value);
43739
43953
  return proto === Object.prototype || proto === null;
@@ -43764,7 +43978,7 @@ function substituteTraitRefsDeep(value, pathKey) {
43764
43978
  }
43765
43979
  return value;
43766
43980
  }
43767
- function renderPatternProps(props, onDismiss) {
43981
+ function renderPatternProps(props, onDismiss, propsSchema) {
43768
43982
  const rendered = {};
43769
43983
  for (const [key, value] of Object.entries(props)) {
43770
43984
  if (key === "children") {
@@ -43782,9 +43996,10 @@ function renderPatternProps(props, onDismiss) {
43782
43996
  };
43783
43997
  rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
43784
43998
  } else if (Array.isArray(value)) {
43999
+ const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
43785
44000
  rendered[key] = value.map((item, i) => {
43786
44001
  const el = item;
43787
- if (isPatternConfig(el)) {
44002
+ if (!isDataArray && isPatternConfig(el)) {
43788
44003
  const nestedProps = {};
43789
44004
  for (const [k, v] of Object.entries(el)) {
43790
44005
  if (k !== "type") nestedProps[k] = v;
@@ -43860,7 +44075,7 @@ function SlotContentRenderer({
43860
44075
  for (const slotKey of CONTENT_NODE_SLOTS) {
43861
44076
  const slotVal = restProps[slotKey];
43862
44077
  if (slotVal === void 0 || slotVal === null) continue;
43863
- if (React83__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
44078
+ if (React84__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
43864
44079
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
43865
44080
  nodeSlotOverrides[slotKey] = renderPatternChildren(
43866
44081
  slotVal,
@@ -43872,14 +44087,15 @@ function SlotContentRenderer({
43872
44087
  );
43873
44088
  }
43874
44089
  }
43875
- const renderedProps = renderPatternProps(restProps, onDismiss);
43876
44090
  const patternDef = getPatternDefinition(content.pattern);
43877
44091
  const propsSchema = patternDef?.propsSchema;
44092
+ const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
43878
44093
  if (propsSchema) {
43879
44094
  for (const [propKey, propValue] of Object.entries(renderedProps)) {
43880
44095
  if (typeof propValue !== "string") continue;
43881
44096
  const propDef = propsSchema[propKey];
43882
44097
  if (!propDef || propDef.kind !== "callback") continue;
44098
+ if (propValue === "") continue;
43883
44099
  renderedProps[propKey] = wrapCallbackForEvent(
43884
44100
  `UI:${propValue}`,
43885
44101
  propDef.callbackArgs,
@@ -43912,7 +44128,7 @@ function SlotContentRenderer({
43912
44128
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
43913
44129
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
43914
44130
  const sample = resolvedItems[0];
43915
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React83__default.isValidElement(sample) && !(sample instanceof Date)) {
44131
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React84__default.isValidElement(sample) && !(sample instanceof Date)) {
43916
44132
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
43917
44133
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
43918
44134
  }
@@ -44165,7 +44381,7 @@ function EventBusProvider({ children, isolated = false }) {
44165
44381
  const listenerCount = (listeners7?.size ?? 0) + anyListenersRef.current.size;
44166
44382
  busLog.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount });
44167
44383
  if (listenerCount === 0) {
44168
- busLog.warn("emit:no-listeners", { type });
44384
+ busLog.debug("emit:no-listeners", { type });
44169
44385
  }
44170
44386
  if (listeners7) {
44171
44387
  const listenersCopy = Array.from(listeners7);
@@ -45430,17 +45646,27 @@ function useTrait(traitName) {
45430
45646
  const context = useTraitContext();
45431
45647
  return context.getTrait(traitName);
45432
45648
  }
45649
+ var EMPTY_CHAIN = Object.freeze([]);
45433
45650
  var TraitScopeContext = createContext(null);
45434
45651
  function TraitScopeProvider3({
45435
45652
  orbital,
45436
45653
  trait,
45437
45654
  children
45438
45655
  }) {
45439
- const value = useMemo(() => ({ orbital, trait }), [orbital, trait]);
45656
+ const parentChain = useContext(TraitScopeContext);
45657
+ const value = useMemo(() => {
45658
+ const self = { orbital, trait };
45659
+ return parentChain && parentChain.length > 0 ? [self, ...parentChain] : [self];
45660
+ }, [orbital, trait, parentChain]);
45440
45661
  return /* @__PURE__ */ jsx(TraitScopeContext.Provider, { value, children });
45441
45662
  }
45442
- function useTraitScope2() {
45443
- return useContext(TraitScopeContext);
45663
+ function useTraitScopeChain2() {
45664
+ const chain = useContext(TraitScopeContext);
45665
+ return chain ?? EMPTY_CHAIN;
45666
+ }
45667
+ function useTraitScope() {
45668
+ const chain = useContext(TraitScopeContext);
45669
+ return chain && chain.length > 0 ? chain[0] : null;
45444
45670
  }
45445
45671
 
45446
45672
  // providers/OfflineModeProvider.tsx
@@ -45534,4 +45760,4 @@ function GameAudioProvider2({
45534
45760
  }
45535
45761
  GameAudioProvider2.displayName = "GameAudioProvider";
45536
45762
 
45537
- export { ANONYMOUS_USER, CurrentPagePathContext, CurrentPagePathProvider, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, GameAudioContext2 as GameAudioContext, GameAudioProvider2 as GameAudioProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntitySchema, useEntitySchemaOptional6 as useEntitySchemaOptional, useGameAudioContext2 as useGameAudioContext, useGameAudioContextOptional2 as useGameAudioContextOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope2 as useTraitScope, useUser, useUserForEvaluation };
45763
+ export { ANONYMOUS_USER, CurrentPagePathContext, CurrentPagePathProvider, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, GameAudioContext2 as GameAudioContext, GameAudioProvider2 as GameAudioProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntitySchema, useEntitySchemaOptional6 as useEntitySchemaOptional, useGameAudioContext2 as useGameAudioContext, useGameAudioContextOptional2 as useGameAudioContextOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope, useTraitScopeChain2 as useTraitScopeChain, useUser, useUserForEvaluation };