@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.
package/dist/avl/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import * as React90 from 'react';
3
- import React90__default, { createContext, useState, useMemo, useRef, useEffect, useContext, useCallback, Suspense, useLayoutEffect, Profiler, useReducer, useSyncExternalStore, lazy, useId } from 'react';
4
- import { getAllPages, OrbitalProvider, EventBusContext, useTraitScope, ServerBridgeProvider, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge, useEntitySchema, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
2
+ import * as React91 from 'react';
3
+ import React91__default, { createContext, useState, useMemo, useRef, useEffect, useContext, useCallback, Suspense, useLayoutEffect, Profiler, useReducer, useSyncExternalStore, lazy, useId } from 'react';
4
+ import { getAllPages, OrbitalProvider, EventBusContext, useTraitScopeChain, ServerBridgeProvider, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge, useEntitySchema, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
5
5
  import { createLogger, setNamespaceLevel, isLogLevelEnabled } from '@almadar/logger';
6
6
  import ELK from 'elkjs/lib/elk.bundled.js';
7
7
  import { MarkerType, useReactFlow, Handle, Position, getBezierPath, EdgeLabelRenderer, useNodeId, ReactFlowProvider, BaseEdge, useNodesState, useEdgesState, ReactFlow, Controls, Background, BackgroundVariant } from '@xyflow/react';
@@ -36,7 +36,7 @@ import ReactMarkdown from 'react-markdown';
36
36
  import remarkGfm from 'remark-gfm';
37
37
  import remarkMath from 'remark-math';
38
38
  import rehypeKatex from 'rehype-katex';
39
- import { FieldTypeSchema, isInlineTrait, isPageReference, buildResolvedTraitConfigs, schemaToIR, getPage, isCircuitEvent, walkSExpr, mergeEntityFrame, isSExpr, isEventPayloadValue } from '@almadar/core';
39
+ import { FieldTypeSchema, isInlineTrait, isPageReference, buildResolvedTraitConfigs, schemaToIR, getPage, mergeEntityFrame, isCircuitEvent, walkSExpr, isSExpr, isEventPayloadValue } from '@almadar/core';
40
40
  import { useDroppable, useDraggable, DndContext, DragOverlay, useSensors, useSensor, PointerSensor, KeyboardSensor, pointerWithin, rectIntersection, closestCorners } from '@dnd-kit/core';
41
41
  import { sortableKeyboardCoordinates, useSortable, arrayMove, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
42
42
  import { CSS } from '@dnd-kit/utilities';
@@ -3177,7 +3177,7 @@ var init_Typography = __esm({
3177
3177
  }) => {
3178
3178
  const variant = variantProp ?? (level ? `h${level}` : "body1");
3179
3179
  const Component = as || defaultElements[variant];
3180
- return React90__default.createElement(
3180
+ return React91__default.createElement(
3181
3181
  Component,
3182
3182
  {
3183
3183
  id,
@@ -3225,9 +3225,9 @@ function getGlobalEventBus() {
3225
3225
  function useEventBus() {
3226
3226
  const context = useContext(EventBusContext);
3227
3227
  const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
3228
- const scope = useTraitScope();
3228
+ const chain = useTraitScopeChain();
3229
3229
  return useMemo(() => {
3230
- if (!scope) {
3230
+ if (chain.length === 0) {
3231
3231
  return {
3232
3232
  ...baseBus,
3233
3233
  emit: (type, payload, source) => {
@@ -3243,22 +3243,31 @@ function useEventBus() {
3243
3243
  emit: (type, payload, source) => {
3244
3244
  if (typeof type === "string" && type.startsWith("UI:")) {
3245
3245
  const tail = type.slice(3);
3246
- const qualified = tail.includes(".") ? type : `UI:${scope.orbital}.${scope.trait}.${tail}`;
3247
- if (qualified !== type) {
3248
- scopeLog.info("emit:qualified", {
3246
+ const isQualified = tail.includes(".");
3247
+ const event = isQualified ? tail.split(".").slice(2).join(".") : tail;
3248
+ if (!event) {
3249
+ baseBus.emit(type, payload, source);
3250
+ return;
3251
+ }
3252
+ const keys = /* @__PURE__ */ new Set();
3253
+ if (isQualified) keys.add(type);
3254
+ for (const sc of chain) {
3255
+ keys.add(`UI:${sc.orbital}.${sc.trait}.${event}`);
3256
+ }
3257
+ if (keys.size > 1) {
3258
+ scopeLog.info("emit:fan-out", {
3249
3259
  from: type,
3250
- to: qualified,
3251
- scopeOrbital: scope.orbital,
3252
- scopeTrait: scope.trait
3260
+ keys: Array.from(keys),
3261
+ chainDepth: chain.length
3253
3262
  });
3254
3263
  }
3255
- baseBus.emit(qualified, payload, source);
3264
+ for (const key of keys) baseBus.emit(key, payload, source);
3256
3265
  return;
3257
3266
  }
3258
3267
  baseBus.emit(type, payload, source);
3259
3268
  }
3260
3269
  };
3261
- }, [baseBus, scope]);
3270
+ }, [baseBus, chain]);
3262
3271
  }
3263
3272
  function useEventListener(event, handler) {
3264
3273
  const eventBus = useEventBus();
@@ -3514,7 +3523,7 @@ var init_Box = __esm({
3514
3523
  fixed: "fixed",
3515
3524
  sticky: "sticky"
3516
3525
  };
3517
- Box = React90__default.forwardRef(
3526
+ Box = React91__default.forwardRef(
3518
3527
  ({
3519
3528
  padding,
3520
3529
  paddingX,
@@ -3579,7 +3588,7 @@ var init_Box = __esm({
3579
3588
  onPointerDown?.(e);
3580
3589
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
3581
3590
  const isClickable = action || onClick;
3582
- return React90__default.createElement(
3591
+ return React91__default.createElement(
3583
3592
  Component,
3584
3593
  {
3585
3594
  ref,
@@ -3675,7 +3684,7 @@ var init_Stack = __esm({
3675
3684
  };
3676
3685
  const isHorizontal = direction === "horizontal";
3677
3686
  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";
3678
- return React90__default.createElement(
3687
+ return React91__default.createElement(
3679
3688
  Component,
3680
3689
  {
3681
3690
  className: cn(
@@ -4167,7 +4176,7 @@ var init_MiniStateMachine = __esm({
4167
4176
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
4168
4177
  const tc = transitionCounts[s.name] ?? 0;
4169
4178
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
4170
- return /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
4179
+ return /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
4171
4180
  /* @__PURE__ */ jsx(
4172
4181
  AvlState,
4173
4182
  {
@@ -4615,13 +4624,13 @@ var init_Icon = __esm({
4615
4624
  style
4616
4625
  }) => {
4617
4626
  const directIcon = typeof icon === "string" ? void 0 : icon;
4618
- const effectiveName = typeof icon === "string" ? icon : name;
4627
+ const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
4628
+ const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
4619
4629
  const family = useIconFamily();
4620
- const RenderedComponent = React90__default.useMemo(() => {
4630
+ const RenderedComponent = React91__default.useMemo(() => {
4621
4631
  if (directIcon) return null;
4622
4632
  return effectiveName ? resolveIconForFamily(effectiveName) : null;
4623
4633
  }, [directIcon, effectiveName, family]);
4624
- const effectiveStrokeWidth = strokeWidth ?? void 0;
4625
4634
  const inlineStyle = {
4626
4635
  ...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
4627
4636
  ...style
@@ -4738,7 +4747,7 @@ var init_atlasSlice = __esm({
4738
4747
  }
4739
4748
  });
4740
4749
  function useAtlasSliceDataUrl(asset) {
4741
- const [, bump] = React90.useReducer((x) => x + 1, 0);
4750
+ const [, bump] = React91.useReducer((x) => x + 1, 0);
4742
4751
  if (!isAtlasAsset(asset)) return void 0;
4743
4752
  const key = `${asset.atlas}#${asset.sprite}`;
4744
4753
  const cached = sliceDataUrlCache.get(key);
@@ -4801,13 +4810,13 @@ function AtlasImage({
4801
4810
  style,
4802
4811
  "aria-hidden": ariaHidden
4803
4812
  }) {
4804
- const [, bump] = React90.useReducer((x) => x + 1, 0);
4805
- const canvasRef = React90.useRef(null);
4813
+ const [, bump] = React91.useReducer((x) => x + 1, 0);
4814
+ const canvasRef = React91.useRef(null);
4806
4815
  const sliced = isAtlasAsset(asset);
4807
4816
  const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
4808
4817
  const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
4809
4818
  const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
4810
- React90.useEffect(() => {
4819
+ React91.useEffect(() => {
4811
4820
  const canvas = canvasRef.current;
4812
4821
  if (!canvas || !img || !rect) return;
4813
4822
  canvas.width = rect.sw;
@@ -4883,7 +4892,7 @@ function resolveIconProp(value, sizeClass) {
4883
4892
  const IconComp = value;
4884
4893
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
4885
4894
  }
4886
- if (React90__default.isValidElement(value)) {
4895
+ if (React91__default.isValidElement(value)) {
4887
4896
  return value;
4888
4897
  }
4889
4898
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -4960,7 +4969,7 @@ var init_Button = __esm({
4960
4969
  md: "h-icon-default w-icon-default",
4961
4970
  lg: "h-icon-default w-icon-default"
4962
4971
  };
4963
- Button = React90__default.forwardRef(
4972
+ Button = React91__default.forwardRef(
4964
4973
  ({
4965
4974
  className,
4966
4975
  variant = "primary",
@@ -5002,7 +5011,8 @@ var init_Button = __esm({
5002
5011
  "font-medium",
5003
5012
  "rounded-sm",
5004
5013
  "cursor-pointer",
5005
- "transition-all duration-[var(--transition-normal)]",
5014
+ "chrome-button",
5015
+ "transition-all duration-normal",
5006
5016
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-offset-[length:var(--focus-ring-offset)]",
5007
5017
  "disabled:opacity-50 disabled:cursor-not-allowed",
5008
5018
  variantStyles2[variant],
@@ -5028,7 +5038,7 @@ var Dialog;
5028
5038
  var init_Dialog = __esm({
5029
5039
  "components/core/atoms/Dialog.tsx"() {
5030
5040
  init_cn();
5031
- Dialog = React90__default.forwardRef(
5041
+ Dialog = React91__default.forwardRef(
5032
5042
  ({
5033
5043
  role = "dialog",
5034
5044
  "aria-modal": ariaModal = true,
@@ -5103,6 +5113,15 @@ var init_Modal = __esm({
5103
5113
  const [dragY, setDragY] = useState(0);
5104
5114
  const dragStartY = useRef(0);
5105
5115
  const isDragging = useRef(false);
5116
+ const [closing, setClosing] = useState(false);
5117
+ const wasOpenRef = useRef(isOpen);
5118
+ useEffect(() => {
5119
+ if (wasOpenRef.current && !isOpen) setClosing(true);
5120
+ wasOpenRef.current = isOpen;
5121
+ }, [isOpen]);
5122
+ const handleAnimEnd = (e) => {
5123
+ if (closing && e.target === e.currentTarget) setClosing(false);
5124
+ };
5106
5125
  useEffect(() => {
5107
5126
  if (isOpen) {
5108
5127
  previousActiveElement.current = document.activeElement;
@@ -5136,7 +5155,11 @@ var init_Modal = __esm({
5136
5155
  document.body.style.overflow = "";
5137
5156
  };
5138
5157
  }, [isOpen]);
5139
- if (!isOpen || typeof document === "undefined") return null;
5158
+ if (typeof document === "undefined") return null;
5159
+ const renderOpen = isOpen || closing;
5160
+ if (!renderOpen) return null;
5161
+ const dialogAnim = closing ? "animate-modal-out" : "animate-modal-in";
5162
+ const overlayAnim = closing ? "animate-overlay-out" : "animate-overlay-in";
5140
5163
  const handleClose = () => {
5141
5164
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
5142
5165
  onClose();
@@ -5153,7 +5176,8 @@ var init_Modal = __esm({
5153
5176
  className: cn(
5154
5177
  "fixed inset-0 z-[1000]",
5155
5178
  "flex items-start justify-center px-4 pb-4 pt-[10vh]",
5156
- "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
5179
+ "max-sm:items-stretch max-sm:p-0 max-sm:pt-0",
5180
+ overlayAnim
5157
5181
  ),
5158
5182
  style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
5159
5183
  onClick: handleOverlayClick,
@@ -5181,8 +5205,10 @@ var init_Modal = __esm({
5181
5205
  // full height, no rounded corners, no min-width.
5182
5206
  "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
5183
5207
  lookStyles[look],
5184
- className
5208
+ className,
5209
+ dialogAnim
5185
5210
  ),
5211
+ onAnimationEnd: handleAnimEnd,
5186
5212
  style: dragY > 0 ? {
5187
5213
  transform: `translateY(${dragY}px)`,
5188
5214
  transition: isDragging.current ? "none" : "transform 200ms ease-out"
@@ -5264,12 +5290,84 @@ var init_Modal = __esm({
5264
5290
  Modal.displayName = "Modal";
5265
5291
  }
5266
5292
  });
5293
+ function isMotionEnabled() {
5294
+ if (typeof document === "undefined") return true;
5295
+ if (motionEnabledCache !== null) return motionEnabledCache;
5296
+ const v = getComputedStyle(document.documentElement).getPropertyValue("--motion-enable").trim().toLowerCase();
5297
+ motionEnabledCache = v !== "off";
5298
+ return motionEnabledCache;
5299
+ }
5300
+ function usePresence(show, opts) {
5301
+ const { animation, animate = true, onExited } = opts;
5302
+ const [mounted, setMounted] = useState(show);
5303
+ const [exiting, setExiting] = useState(false);
5304
+ const prev = useRef(show);
5305
+ const onExitedRef = useRef(onExited);
5306
+ onExitedRef.current = onExited;
5307
+ const safeTimer = useRef(null);
5308
+ const clearSafe = useCallback(() => {
5309
+ if (safeTimer.current) {
5310
+ clearTimeout(safeTimer.current);
5311
+ safeTimer.current = null;
5312
+ }
5313
+ }, []);
5314
+ const finishExit = useCallback(() => {
5315
+ clearSafe();
5316
+ setExiting(false);
5317
+ setMounted(false);
5318
+ onExitedRef.current?.();
5319
+ }, [clearSafe]);
5320
+ useEffect(() => {
5321
+ const moving = animate && isMotionEnabled();
5322
+ if (show && !prev.current) {
5323
+ setExiting(false);
5324
+ setMounted(true);
5325
+ } else if (!show && prev.current) {
5326
+ if (moving) {
5327
+ setExiting(true);
5328
+ clearSafe();
5329
+ safeTimer.current = setTimeout(finishExit, SAFE_EXIT_MS);
5330
+ } else {
5331
+ setMounted(false);
5332
+ setExiting(false);
5333
+ }
5334
+ }
5335
+ prev.current = show;
5336
+ }, [show, animate, clearSafe, finishExit]);
5337
+ useEffect(() => () => clearSafe(), [clearSafe]);
5338
+ const disabled = !animate || !isMotionEnabled();
5339
+ const className = disabled ? "" : exiting ? `animate-${animation}-out` : `animate-${animation}-in`;
5340
+ const onAnimationEnd = useCallback(
5341
+ (e) => {
5342
+ if (e.target !== e.currentTarget) return;
5343
+ if (exiting) finishExit();
5344
+ },
5345
+ [exiting, finishExit]
5346
+ );
5347
+ return { mounted, exiting, className, onAnimationEnd };
5348
+ }
5349
+ var SAFE_EXIT_MS, motionEnabledCache, Presence;
5350
+ var init_Presence = __esm({
5351
+ "components/core/atoms/Presence.tsx"() {
5352
+ "use client";
5353
+ init_cn();
5354
+ SAFE_EXIT_MS = 1e3;
5355
+ motionEnabledCache = null;
5356
+ Presence = ({ show, className, children, ...opts }) => {
5357
+ const { mounted, className: animClass, onAnimationEnd } = usePresence(show, opts);
5358
+ if (!mounted) return null;
5359
+ return /* @__PURE__ */ jsx("div", { className: cn(animClass, className), onAnimationEnd, children });
5360
+ };
5361
+ Presence.displayName = "Presence";
5362
+ }
5363
+ });
5267
5364
  var Overlay;
5268
5365
  var init_Overlay = __esm({
5269
5366
  "components/core/atoms/Overlay.tsx"() {
5270
5367
  "use client";
5271
5368
  init_cn();
5272
5369
  init_useEventBus();
5370
+ init_Presence();
5273
5371
  Overlay = ({
5274
5372
  isVisible = true,
5275
5373
  onClick,
@@ -5278,7 +5376,8 @@ var init_Overlay = __esm({
5278
5376
  action
5279
5377
  }) => {
5280
5378
  const eventBus = useEventBus();
5281
- if (!isVisible) return null;
5379
+ const { mounted, className: animClass, onAnimationEnd } = usePresence(isVisible, { animation: "overlay" });
5380
+ if (!mounted) return null;
5282
5381
  const handleClick = (e) => {
5283
5382
  if (action) {
5284
5383
  eventBus.emit(`UI:${action}`, {});
@@ -5291,10 +5390,12 @@ var init_Overlay = __esm({
5291
5390
  className: cn(
5292
5391
  "fixed inset-0 z-40",
5293
5392
  blur && "backdrop-blur-sm",
5393
+ animClass,
5294
5394
  className
5295
5395
  ),
5296
5396
  style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
5297
5397
  onClick: action || onClick ? handleClick : void 0,
5398
+ onAnimationEnd,
5298
5399
  "aria-hidden": "true"
5299
5400
  }
5300
5401
  );
@@ -5309,6 +5410,7 @@ var init_Drawer = __esm({
5309
5410
  init_Button();
5310
5411
  init_Typography();
5311
5412
  init_Overlay();
5413
+ init_Presence();
5312
5414
  init_cn();
5313
5415
  init_useEventBus();
5314
5416
  sizeWidths = {
@@ -5362,6 +5464,7 @@ var init_Drawer = __esm({
5362
5464
  document.addEventListener("keydown", handleEscape);
5363
5465
  return () => document.removeEventListener("keydown", handleEscape);
5364
5466
  }, [isOpen, closeOnEscape, onClose, closeEvent, eventBus]);
5467
+ const { mounted, className: drawerAnim, onAnimationEnd } = usePresence(isOpen, { animation: "drawer" });
5365
5468
  useEffect(() => {
5366
5469
  if (isOpen) {
5367
5470
  document.body.style.overflow = "hidden";
@@ -5372,7 +5475,7 @@ var init_Drawer = __esm({
5372
5475
  document.body.style.overflow = "";
5373
5476
  };
5374
5477
  }, [isOpen]);
5375
- if (!isOpen) return null;
5478
+ if (!mounted) return null;
5376
5479
  const handleClose = () => {
5377
5480
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
5378
5481
  onClose();
@@ -5385,7 +5488,7 @@ var init_Drawer = __esm({
5385
5488
  const widthClass = width in sizeWidths ? sizeWidths[width] : "";
5386
5489
  const widthStyle = width in sizeWidths ? void 0 : { width };
5387
5490
  const positionClasses = position === "right" ? "right-0 border-l" : "left-0 border-r";
5388
- const animationClasses2 = position === "right" ? "animate-slide-in-right" : "animate-slide-in-left";
5491
+ const drawerSign = position === "right" ? 1 : -1;
5389
5492
  return /* @__PURE__ */ jsxs(Fragment, { children: [
5390
5493
  /* @__PURE__ */ jsx(
5391
5494
  Overlay,
@@ -5407,12 +5510,13 @@ var init_Drawer = __esm({
5407
5510
  "flex flex-col max-h-screen",
5408
5511
  positionClasses,
5409
5512
  widthClass,
5410
- animationClasses2,
5513
+ drawerAnim,
5411
5514
  className
5412
5515
  ),
5413
- style: widthStyle,
5516
+ style: { ...widthStyle, "--motion-drawer-sign": drawerSign },
5414
5517
  role: "dialog",
5415
5518
  "aria-modal": "true",
5519
+ onAnimationEnd,
5416
5520
  ...title && { "aria-labelledby": "drawer-title" },
5417
5521
  children: [
5418
5522
  (title || showCloseButton) && /* @__PURE__ */ jsxs(
@@ -5451,31 +5555,7 @@ var init_Drawer = __esm({
5451
5555
  )
5452
5556
  ]
5453
5557
  }
5454
- ),
5455
- /* @__PURE__ */ jsx("style", { children: `
5456
- @keyframes slide-in-right {
5457
- from {
5458
- transform: translateX(100%);
5459
- }
5460
- to {
5461
- transform: translateX(0);
5462
- }
5463
- }
5464
- @keyframes slide-in-left {
5465
- from {
5466
- transform: translateX(-100%);
5467
- }
5468
- to {
5469
- transform: translateX(0);
5470
- }
5471
- }
5472
- .animate-slide-in-right {
5473
- animation: slide-in-right 0.3s ease-out;
5474
- }
5475
- .animate-slide-in-left {
5476
- animation: slide-in-left 0.3s ease-out;
5477
- }
5478
- ` })
5558
+ )
5479
5559
  ] });
5480
5560
  };
5481
5561
  Drawer.displayName = "Drawer";
@@ -5524,7 +5604,7 @@ var init_Badge = __esm({
5524
5604
  md: "px-2.5 py-1 text-sm",
5525
5605
  lg: "px-3 py-1.5 text-base"
5526
5606
  };
5527
- Badge = React90__default.forwardRef(
5607
+ Badge = React91__default.forwardRef(
5528
5608
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
5529
5609
  const iconSizes3 = {
5530
5610
  sm: "h-icon-default w-icon-default",
@@ -5619,14 +5699,23 @@ var init_Toast = __esm({
5619
5699
  }) => {
5620
5700
  const eventBus = useEventBus();
5621
5701
  const { t } = useTranslate();
5622
- const handleDismiss = () => {
5702
+ const [leaving, setLeaving] = useState(false);
5703
+ const doRealDismiss = () => {
5623
5704
  if (dismissEvent) eventBus.emit(`UI:${dismissEvent}`, {});
5624
5705
  onDismiss?.();
5625
5706
  };
5707
+ const handleDismiss = () => {
5708
+ if (leaving) return;
5709
+ setLeaving(true);
5710
+ };
5626
5711
  const handleAction = () => {
5627
5712
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, {});
5628
5713
  onAction?.();
5629
5714
  };
5715
+ const handleAnimEnd = (e) => {
5716
+ if (e.target !== e.currentTarget) return;
5717
+ if (leaving) doRealDismiss();
5718
+ };
5630
5719
  useEffect(() => {
5631
5720
  if (duration <= 0 || !onDismiss && !dismissEvent) {
5632
5721
  return;
@@ -5645,10 +5734,12 @@ var init_Toast = __esm({
5645
5734
  // edge. `max-w-[calc(100vw-2rem)]` clamps to viewport too.
5646
5735
  "border-l-4 p-4 shadow-elevation-toast min-w-0 sm:min-w-[300px] max-w-md max-w-[calc(100vw-2rem)]",
5647
5736
  "rounded-sm",
5737
+ leaving ? "animate-toast-out" : "animate-toast-in",
5648
5738
  variantClasses[variant],
5649
5739
  className
5650
5740
  ),
5651
5741
  role: "alert",
5742
+ onAnimationEnd: handleAnimEnd,
5652
5743
  children: /* @__PURE__ */ jsxs(Box, { className: "flex items-start gap-3", children: [
5653
5744
  /* @__PURE__ */ jsx(Box, { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx(
5654
5745
  Icon,
@@ -5861,7 +5952,7 @@ var init_SvgFlow = __esm({
5861
5952
  width = 100,
5862
5953
  height = 100
5863
5954
  }) => {
5864
- const markerId = React90__default.useMemo(() => {
5955
+ const markerId = React91__default.useMemo(() => {
5865
5956
  flowIdCounter += 1;
5866
5957
  return `almadar-flow-arrow-${flowIdCounter}`;
5867
5958
  }, []);
@@ -6454,7 +6545,7 @@ var init_SvgRing = __esm({
6454
6545
  width = 100,
6455
6546
  height = 100
6456
6547
  }) => {
6457
- const gradientId = React90__default.useMemo(() => {
6548
+ const gradientId = React91__default.useMemo(() => {
6458
6549
  ringIdCounter += 1;
6459
6550
  return `almadar-ring-glow-${ringIdCounter}`;
6460
6551
  }, []);
@@ -6635,7 +6726,7 @@ var init_Input = __esm({
6635
6726
  init_cn();
6636
6727
  init_Icon();
6637
6728
  init_useEventBus();
6638
- Input = React90__default.forwardRef(
6729
+ Input = React91__default.forwardRef(
6639
6730
  ({
6640
6731
  className,
6641
6732
  inputType,
@@ -6670,7 +6761,7 @@ var init_Input = __esm({
6670
6761
  const showClearButton = clearable && value && String(value).length > 0;
6671
6762
  const isMultiline = type === "textarea";
6672
6763
  const baseClassName = cn(
6673
- "block w-full rounded-sm transition-all duration-[var(--transition-fast)]",
6764
+ "block w-full rounded-sm transition-all duration-fast",
6674
6765
  "border-[length:var(--border-width-thin)] border-border",
6675
6766
  isMultiline ? "px-3 py-2 text-sm" : "h-input-md px-3 text-sm",
6676
6767
  "bg-card hover:bg-muted focus:bg-card",
@@ -6703,7 +6794,7 @@ var init_Input = __esm({
6703
6794
  eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
6704
6795
  }
6705
6796
  };
6706
- const wrapField = (field) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
6797
+ const wrapField = (field, fullWidth = true) => /* @__PURE__ */ jsxs("div", { className: fullWidth ? "w-full" : "w-fit", children: [
6707
6798
  label && /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
6708
6799
  field,
6709
6800
  (helperText || error) && /* @__PURE__ */ jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
@@ -6763,7 +6854,8 @@ var init_Input = __esm({
6763
6854
  ),
6764
6855
  ...props
6765
6856
  }
6766
- )
6857
+ ),
6858
+ false
6767
6859
  );
6768
6860
  }
6769
6861
  return wrapField(
@@ -6802,7 +6894,7 @@ var Label;
6802
6894
  var init_Label = __esm({
6803
6895
  "components/core/atoms/Label.tsx"() {
6804
6896
  init_cn();
6805
- Label = React90__default.forwardRef(
6897
+ Label = React91__default.forwardRef(
6806
6898
  ({ className, required, children, ...props }, ref) => {
6807
6899
  return /* @__PURE__ */ jsxs(
6808
6900
  "label",
@@ -6829,7 +6921,7 @@ var init_Textarea = __esm({
6829
6921
  "components/core/atoms/Textarea.tsx"() {
6830
6922
  init_cn();
6831
6923
  init_useEventBus();
6832
- Textarea = React90__default.forwardRef(
6924
+ Textarea = React91__default.forwardRef(
6833
6925
  ({ className, error, onChange, ...props }, ref) => {
6834
6926
  const eventBus = useEventBus();
6835
6927
  const handleChange = (e) => {
@@ -7068,7 +7160,7 @@ var init_Select = __esm({
7068
7160
  init_cn();
7069
7161
  init_Icon();
7070
7162
  init_useEventBus();
7071
- Select = React90__default.forwardRef(
7163
+ Select = React91__default.forwardRef(
7072
7164
  (props, _ref) => {
7073
7165
  const { multiple, searchable, clearable } = props;
7074
7166
  if (multiple || searchable || clearable) {
@@ -7085,7 +7177,7 @@ var init_Checkbox = __esm({
7085
7177
  "components/core/atoms/Checkbox.tsx"() {
7086
7178
  init_cn();
7087
7179
  init_useEventBus();
7088
- Checkbox = React90__default.forwardRef(
7180
+ Checkbox = React91__default.forwardRef(
7089
7181
  ({ className, label, id, onChange, ...props }, ref) => {
7090
7182
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
7091
7183
  const eventBus = useEventBus();
@@ -7139,7 +7231,7 @@ var init_Spinner = __esm({
7139
7231
  md: "h-6 w-6",
7140
7232
  lg: "h-8 w-8"
7141
7233
  };
7142
- Spinner = React90__default.forwardRef(
7234
+ Spinner = React91__default.forwardRef(
7143
7235
  ({ className, size = "md", overlay, ...props }, ref) => {
7144
7236
  if (overlay) {
7145
7237
  return /* @__PURE__ */ jsx(
@@ -7181,21 +7273,21 @@ var init_Card = __esm({
7181
7273
  "bg-card",
7182
7274
  "border-[length:var(--border-width)] border-border",
7183
7275
  "shadow-elevation-card",
7184
- "transition-all duration-[var(--transition-normal)]",
7276
+ "transition-all duration-normal",
7185
7277
  "hover:shadow-elevation-dialog hover:translate-y-[var(--hover-translate-y)]"
7186
7278
  ].join(" "),
7187
7279
  bordered: [
7188
7280
  "bg-card",
7189
7281
  "border-[length:var(--border-width)] border-border",
7190
7282
  "shadow-elevation-card",
7191
- "transition-all duration-[var(--transition-normal)]",
7283
+ "transition-all duration-normal",
7192
7284
  "hover:shadow-elevation-dialog hover:translate-y-[var(--hover-translate-y)]"
7193
7285
  ].join(" "),
7194
7286
  elevated: [
7195
7287
  "bg-card",
7196
7288
  "border-[length:var(--border-width)] border-border",
7197
7289
  "shadow",
7198
- "transition-all duration-[var(--transition-normal)]",
7290
+ "transition-all duration-normal",
7199
7291
  "hover:shadow-elevation-dialog hover:translate-y-[var(--hover-translate-y)]"
7200
7292
  ].join(" "),
7201
7293
  // Interactive variant with theme-specific hover effects
@@ -7204,7 +7296,7 @@ var init_Card = __esm({
7204
7296
  "border-[length:var(--border-width)] border-border",
7205
7297
  "shadow",
7206
7298
  "cursor-pointer",
7207
- "transition-all duration-[var(--transition-normal)]",
7299
+ "transition-all duration-normal",
7208
7300
  "hover:shadow-elevation-dialog"
7209
7301
  ].join(" ")
7210
7302
  };
@@ -7229,7 +7321,7 @@ var init_Card = __esm({
7229
7321
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
7230
7322
  "tile-image-first": "p-0 overflow-hidden"
7231
7323
  };
7232
- Card = React90__default.forwardRef(
7324
+ Card = React91__default.forwardRef(
7233
7325
  ({
7234
7326
  className,
7235
7327
  variant = "bordered",
@@ -7255,7 +7347,8 @@ var init_Card = __esm({
7255
7347
  ref,
7256
7348
  className: cn(
7257
7349
  "rounded-container relative",
7258
- "transition-all duration-[var(--transition-normal)]",
7350
+ "transition-all duration-normal",
7351
+ "chrome-panel",
7259
7352
  variantStyles4[variant],
7260
7353
  paddingStyles2[padding],
7261
7354
  lookStyles2[look],
@@ -7277,9 +7370,9 @@ var init_Card = __esm({
7277
7370
  }
7278
7371
  );
7279
7372
  Card.displayName = "Card";
7280
- CardHeader = React90__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
7373
+ CardHeader = React91__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
7281
7374
  CardHeader.displayName = "CardHeader";
7282
- CardTitle = React90__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7375
+ CardTitle = React91__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7283
7376
  "h3",
7284
7377
  {
7285
7378
  ref,
@@ -7292,11 +7385,11 @@ var init_Card = __esm({
7292
7385
  }
7293
7386
  ));
7294
7387
  CardTitle.displayName = "CardTitle";
7295
- CardContent = React90__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
7388
+ CardContent = React91__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
7296
7389
  CardContent.displayName = "CardContent";
7297
7390
  CardBody = CardContent;
7298
7391
  CardBody.displayName = "CardBody";
7299
- CardFooter = React90__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7392
+ CardFooter = React91__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7300
7393
  "div",
7301
7394
  {
7302
7395
  ref,
@@ -7383,7 +7476,7 @@ var init_FilterPill = __esm({
7383
7476
  md: "w-3.5 h-3.5",
7384
7477
  lg: "w-4 h-4"
7385
7478
  };
7386
- FilterPill = React90__default.forwardRef(
7479
+ FilterPill = React91__default.forwardRef(
7387
7480
  ({
7388
7481
  className,
7389
7482
  variant = "default",
@@ -7512,8 +7605,8 @@ var init_Avatar = __esm({
7512
7605
  actionPayload
7513
7606
  }) => {
7514
7607
  const eventBus = useEventBus();
7515
- const [imgFailed, setImgFailed] = React90__default.useState(false);
7516
- React90__default.useEffect(() => {
7608
+ const [imgFailed, setImgFailed] = React91__default.useState(false);
7609
+ React91__default.useEffect(() => {
7517
7610
  setImgFailed(false);
7518
7611
  }, [src]);
7519
7612
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -7626,7 +7719,7 @@ var init_Center = __esm({
7626
7719
  as: Component = "div"
7627
7720
  }) => {
7628
7721
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
7629
- return React90__default.createElement(Component, {
7722
+ return React91__default.createElement(Component, {
7630
7723
  className: cn(
7631
7724
  inline ? "inline-flex" : "flex",
7632
7725
  horizontal && "justify-center",
@@ -7894,7 +7987,7 @@ var init_Radio = __esm({
7894
7987
  md: "w-2.5 h-2.5",
7895
7988
  lg: "w-3 h-3"
7896
7989
  };
7897
- Radio = React90__default.forwardRef(
7990
+ Radio = React91__default.forwardRef(
7898
7991
  ({
7899
7992
  label,
7900
7993
  helperText,
@@ -7911,12 +8004,12 @@ var init_Radio = __esm({
7911
8004
  onChange,
7912
8005
  ...props
7913
8006
  }, ref) => {
7914
- const reactId = React90__default.useId();
8007
+ const reactId = React91__default.useId();
7915
8008
  const baseId = id || `radio-${reactId}`;
7916
8009
  const hasError = !!error;
7917
8010
  const eventBus = useEventBus();
7918
- const [selected, setSelected] = React90__default.useState(value);
7919
- React90__default.useEffect(() => {
8011
+ const [selected, setSelected] = React91__default.useState(value);
8012
+ React91__default.useEffect(() => {
7920
8013
  if (value !== void 0) setSelected(value);
7921
8014
  }, [value]);
7922
8015
  const pick = (next, e) => {
@@ -8098,7 +8191,7 @@ var init_Switch = __esm({
8098
8191
  "components/core/atoms/Switch.tsx"() {
8099
8192
  "use client";
8100
8193
  init_cn();
8101
- Switch = React90.forwardRef(
8194
+ Switch = React91.forwardRef(
8102
8195
  ({
8103
8196
  checked,
8104
8197
  defaultChecked = false,
@@ -8109,10 +8202,10 @@ var init_Switch = __esm({
8109
8202
  name,
8110
8203
  className
8111
8204
  }, ref) => {
8112
- const [isChecked, setIsChecked] = React90.useState(
8205
+ const [isChecked, setIsChecked] = React91.useState(
8113
8206
  checked !== void 0 ? checked : defaultChecked
8114
8207
  );
8115
- React90.useEffect(() => {
8208
+ React91.useEffect(() => {
8116
8209
  if (checked !== void 0) {
8117
8210
  setIsChecked(checked);
8118
8211
  }
@@ -8143,7 +8236,7 @@ var init_Switch = __esm({
8143
8236
  // redefine --space-11 to 68px, which makes w-11 enormous and leaves
8144
8237
  // the thumb stuck near the left edge. The switch geometry must stay
8145
8238
  // proportional regardless of a theme's density scale.
8146
- "relative inline-flex h-[1.5rem] w-[2.75rem] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors",
8239
+ "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",
8147
8240
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
8148
8241
  isChecked ? "bg-primary" : "bg-muted",
8149
8242
  disabled && "cursor-not-allowed opacity-50"
@@ -8152,7 +8245,7 @@ var init_Switch = __esm({
8152
8245
  "span",
8153
8246
  {
8154
8247
  className: cn(
8155
- "pointer-events-none block h-[1.25rem] w-[1.25rem] rounded-full bg-background shadow-lg ring-0 transition-transform",
8248
+ "pointer-events-none block h-[1.25rem] w-[1.25rem] rounded-full bg-background shadow-lg ring-0 transition-transform duration-fast",
8156
8249
  isChecked ? "translate-x-[1.25rem]" : "translate-x-0"
8157
8250
  )
8158
8251
  }
@@ -8235,7 +8328,7 @@ var init_TextHighlight = __esm({
8235
8328
  hoverEvent
8236
8329
  }) => {
8237
8330
  const eventBus = useEventBus();
8238
- const baseStyles = "cursor-pointer transition-all duration-150";
8331
+ const baseStyles = "cursor-pointer transition-all duration-fast";
8239
8332
  const typeStyles = {
8240
8333
  question: cn(
8241
8334
  // Blue border for questions
@@ -8390,7 +8483,7 @@ var Aside;
8390
8483
  var init_Aside = __esm({
8391
8484
  "components/core/atoms/Aside.tsx"() {
8392
8485
  init_cn();
8393
- Aside = React90__default.forwardRef(
8486
+ Aside = React91__default.forwardRef(
8394
8487
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
8395
8488
  );
8396
8489
  Aside.displayName = "Aside";
@@ -8469,9 +8562,9 @@ var init_LawReferenceTooltip = __esm({
8469
8562
  className
8470
8563
  }) => {
8471
8564
  const { t } = useTranslate();
8472
- const [isVisible, setIsVisible] = React90__default.useState(false);
8473
- const timeoutRef = React90__default.useRef(null);
8474
- const triggerRef = React90__default.useRef(null);
8565
+ const [isVisible, setIsVisible] = React91__default.useState(false);
8566
+ const timeoutRef = React91__default.useRef(null);
8567
+ const triggerRef = React91__default.useRef(null);
8475
8568
  const handleMouseEnter = () => {
8476
8569
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
8477
8570
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -8482,7 +8575,7 @@ var init_LawReferenceTooltip = __esm({
8482
8575
  };
8483
8576
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
8484
8577
  const open = isVisible || revealed;
8485
- React90__default.useEffect(() => {
8578
+ React91__default.useEffect(() => {
8486
8579
  return () => {
8487
8580
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
8488
8581
  };
@@ -8692,7 +8785,7 @@ var init_StatusDot = __esm({
8692
8785
  md: "w-2.5 h-2.5",
8693
8786
  lg: "w-3 h-3"
8694
8787
  };
8695
- StatusDot = React90__default.forwardRef(
8788
+ StatusDot = React91__default.forwardRef(
8696
8789
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
8697
8790
  return /* @__PURE__ */ jsx(
8698
8791
  "span",
@@ -8746,7 +8839,7 @@ var init_TrendIndicator = __esm({
8746
8839
  down: "trending-down",
8747
8840
  flat: "arrow-right"
8748
8841
  };
8749
- TrendIndicator = React90__default.forwardRef(
8842
+ TrendIndicator = React91__default.forwardRef(
8750
8843
  ({
8751
8844
  className,
8752
8845
  value,
@@ -8813,7 +8906,7 @@ var init_RangeSlider = __esm({
8813
8906
  md: "w-4 h-4",
8814
8907
  lg: "w-5 h-5"
8815
8908
  };
8816
- RangeSlider = React90__default.forwardRef(
8909
+ RangeSlider = React91__default.forwardRef(
8817
8910
  ({
8818
8911
  className,
8819
8912
  min = 0,
@@ -8956,7 +9049,7 @@ var init_RangeSlider = __esm({
8956
9049
  "border-2 border-primary",
8957
9050
  "shadow-sm",
8958
9051
  "pointer-events-none",
8959
- "transition-transform duration-100",
9052
+ "transition-transform duration-instant",
8960
9053
  isDragging && "scale-[var(--hover-scale)]",
8961
9054
  thumbSizes[size]
8962
9055
  ),
@@ -9006,6 +9099,18 @@ var init_RangeSlider = __esm({
9006
9099
  function easeOut(t) {
9007
9100
  return t * (2 - t);
9008
9101
  }
9102
+ function formatDisplay(value, format, decimals) {
9103
+ switch (format) {
9104
+ case "currency":
9105
+ return `$${value.toFixed(2)}`;
9106
+ case "percent":
9107
+ return `${Math.round(value)}%`;
9108
+ case "number":
9109
+ return value.toLocaleString();
9110
+ default:
9111
+ return value.toFixed(decimals);
9112
+ }
9113
+ }
9009
9114
  var AnimatedCounter;
9010
9115
  var init_AnimatedCounter = __esm({
9011
9116
  "components/marketing/atoms/AnimatedCounter.tsx"() {
@@ -9017,6 +9122,7 @@ var init_AnimatedCounter = __esm({
9017
9122
  duration = 600,
9018
9123
  prefix,
9019
9124
  suffix,
9125
+ format,
9020
9126
  className
9021
9127
  }) => {
9022
9128
  const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
@@ -9032,6 +9138,10 @@ var init_AnimatedCounter = __esm({
9032
9138
  setDisplayValue(to);
9033
9139
  return;
9034
9140
  }
9141
+ if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
9142
+ setDisplayValue(to);
9143
+ return;
9144
+ }
9035
9145
  const startTime = performance.now();
9036
9146
  const diff = to - from;
9037
9147
  function animate(currentTime) {
@@ -9053,7 +9163,7 @@ var init_AnimatedCounter = __esm({
9053
9163
  };
9054
9164
  }, [value, duration]);
9055
9165
  const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
9056
- const formattedValue = displayValue.toFixed(decimalPlaces);
9166
+ const formattedValue = formatDisplay(displayValue, format, decimalPlaces);
9057
9167
  return /* @__PURE__ */ jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
9058
9168
  prefix,
9059
9169
  formattedValue,
@@ -9407,7 +9517,7 @@ var init_ContentSection = __esm({
9407
9517
  md: "py-16",
9408
9518
  lg: "py-24"
9409
9519
  };
9410
- ContentSection = React90__default.forwardRef(
9520
+ ContentSection = React91__default.forwardRef(
9411
9521
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
9412
9522
  return /* @__PURE__ */ jsx(
9413
9523
  Box,
@@ -9941,7 +10051,7 @@ var init_AnimatedReveal = __esm({
9941
10051
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
9942
10052
  "none": {}
9943
10053
  };
9944
- AnimatedReveal = React90__default.forwardRef(
10054
+ AnimatedReveal = React91__default.forwardRef(
9945
10055
  ({
9946
10056
  trigger = "scroll",
9947
10057
  animation = "fade-up",
@@ -10101,7 +10211,7 @@ var init_AnimatedGraphic = __esm({
10101
10211
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
10102
10212
  "use client";
10103
10213
  init_cn();
10104
- AnimatedGraphic = React90__default.forwardRef(
10214
+ AnimatedGraphic = React91__default.forwardRef(
10105
10215
  ({
10106
10216
  src,
10107
10217
  svgContent,
@@ -10124,7 +10234,7 @@ var init_AnimatedGraphic = __esm({
10124
10234
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
10125
10235
  const resolvedSvg = svgContent ?? fetchedSvg;
10126
10236
  const prevAnimateRef = useRef(animate);
10127
- const setRef = React90__default.useCallback(
10237
+ const setRef = React91__default.useCallback(
10128
10238
  (node) => {
10129
10239
  containerRef.current = node;
10130
10240
  if (typeof ref === "function") ref(node);
@@ -10332,14 +10442,29 @@ function recordTransition(trace) {
10332
10442
  "pass"
10333
10443
  );
10334
10444
  } else {
10335
- const hasRenderUI = entry.effects.some((e) => e.type === "render-ui");
10336
- if (hasRenderUI) {
10337
- registerCheck(
10338
- checkId,
10339
- `INIT transition for "${entry.traitName}" missing fetch effect`,
10340
- "fail",
10341
- "Entity-bound render-ui without a fetch effect will show empty data"
10445
+ const rendersEntityData = entry.effects.some(
10446
+ (e) => e.type === "render-ui" && JSON.stringify(e.args).includes("@entity.")
10447
+ );
10448
+ if (rendersEntityData) {
10449
+ const siblingSeeds = getState().transitions.some(
10450
+ (t) => t.event === "INIT" && t.effects.some(
10451
+ (e) => e.type === "fetch" || e.type === "set" && typeof e.args[0] === "string" && e.args[0].startsWith("@entity.")
10452
+ )
10342
10453
  );
10454
+ if (siblingSeeds) {
10455
+ registerCheck(
10456
+ checkId,
10457
+ `INIT transition for "${entry.traitName}" has sibling entity-seed (shared entity)`,
10458
+ "pass"
10459
+ );
10460
+ } else {
10461
+ registerCheck(
10462
+ checkId,
10463
+ `INIT transition for "${entry.traitName}" missing fetch effect`,
10464
+ "fail",
10465
+ "Entity-bound render-ui without a fetch effect will show empty data"
10466
+ );
10467
+ }
10343
10468
  }
10344
10469
  }
10345
10470
  }
@@ -10837,9 +10962,9 @@ function ControlButton({
10837
10962
  className
10838
10963
  }) {
10839
10964
  const eventBus = useEventBus();
10840
- const [isPressed, setIsPressed] = React90.useState(false);
10965
+ const [isPressed, setIsPressed] = React91.useState(false);
10841
10966
  const actualPressed = pressed ?? isPressed;
10842
- const handlePointerDown = React90.useCallback(
10967
+ const handlePointerDown = React91.useCallback(
10843
10968
  (e) => {
10844
10969
  e.preventDefault();
10845
10970
  if (disabled) return;
@@ -10849,7 +10974,7 @@ function ControlButton({
10849
10974
  },
10850
10975
  [disabled, pressEvent, eventBus, onPress]
10851
10976
  );
10852
- const handlePointerUp = React90.useCallback(
10977
+ const handlePointerUp = React91.useCallback(
10853
10978
  (e) => {
10854
10979
  e.preventDefault();
10855
10980
  if (disabled) return;
@@ -10859,7 +10984,7 @@ function ControlButton({
10859
10984
  },
10860
10985
  [disabled, releaseEvent, eventBus, onRelease]
10861
10986
  );
10862
- const handlePointerLeave = React90.useCallback(
10987
+ const handlePointerLeave = React91.useCallback(
10863
10988
  (e) => {
10864
10989
  if (isPressed) {
10865
10990
  setIsPressed(false);
@@ -11117,8 +11242,8 @@ function ControlGrid({
11117
11242
  className
11118
11243
  }) {
11119
11244
  const eventBus = useEventBus();
11120
- const [active, setActive] = React90.useState(/* @__PURE__ */ new Set());
11121
- const handlePress = React90.useCallback(
11245
+ const [active, setActive] = React91.useState(/* @__PURE__ */ new Set());
11246
+ const handlePress = React91.useCallback(
11122
11247
  (id) => {
11123
11248
  setActive((prev) => new Set(prev).add(id));
11124
11249
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -11132,7 +11257,7 @@ function ControlGrid({
11132
11257
  },
11133
11258
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
11134
11259
  );
11135
- const handleRelease = React90.useCallback(
11260
+ const handleRelease = React91.useCallback(
11136
11261
  (id) => {
11137
11262
  setActive((prev) => {
11138
11263
  const next = new Set(prev);
@@ -11425,17 +11550,18 @@ function GameHud({
11425
11550
  const mid = Math.ceil(stats.length / 2);
11426
11551
  const leftStats = stats.slice(0, mid);
11427
11552
  const rightStats = stats.slice(mid);
11428
- const isTop = position === "top";
11429
11553
  return /* @__PURE__ */ jsxs(
11430
- Box,
11554
+ Card,
11431
11555
  {
11556
+ variant: "bordered",
11557
+ padding: "none",
11432
11558
  className: cn(
11433
- "flex items-center justify-between w-full",
11559
+ "flex items-center justify-between w-full rounded-none bg-card",
11434
11560
  "px-4 py-2 gap-4",
11435
- !transparent && (isTop ? "border-b border-border/40 bg-surface/90 backdrop-blur-sm" : "border-t border-border/40 bg-surface/90 backdrop-blur-sm"),
11436
- transparent && (isTop ? "border-b border-white/10 bg-black/40 backdrop-blur-sm" : "border-t border-white/10 bg-black/40 backdrop-blur-sm"),
11561
+ transparent && "backdrop-blur-sm",
11437
11562
  className
11438
11563
  ),
11564
+ style: transparent ? { backgroundColor: "color-mix(in srgb, var(--color-card) 40%, transparent)" } : void 0,
11439
11565
  children: [
11440
11566
  /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-3 flex-shrink-0", children: leftStats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i)) }),
11441
11567
  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)) })
@@ -11444,14 +11570,16 @@ function GameHud({
11444
11570
  );
11445
11571
  }
11446
11572
  return /* @__PURE__ */ jsx(
11447
- Box,
11573
+ Card,
11448
11574
  {
11449
- position: "relative",
11575
+ variant: "bordered",
11576
+ padding: "sm",
11450
11577
  className: cn(
11451
- "z-10 flex items-center gap-4 px-4 py-2",
11452
- transparent ? "bg-black/30 backdrop-blur-sm" : "bg-surface/90 backdrop-blur-sm",
11578
+ "z-10 relative flex items-center gap-4 bg-card",
11579
+ transparent && "backdrop-blur-sm",
11453
11580
  className
11454
11581
  ),
11582
+ style: transparent ? { backgroundColor: "color-mix(in srgb, var(--color-card) 30%, transparent)" } : void 0,
11455
11583
  children: stats.map((stat, i) => /* @__PURE__ */ jsx(StatBadge, { ...stat, size }, i))
11456
11584
  }
11457
11585
  );
@@ -11461,6 +11589,7 @@ var init_GameHud = __esm({
11461
11589
  "components/game/molecules/GameHud.tsx"() {
11462
11590
  init_cn();
11463
11591
  init_Box();
11592
+ init_Card();
11464
11593
  init_StatBadge();
11465
11594
  positionMap = {
11466
11595
  corners: "inset-0 pointer-events-none"
@@ -11484,9 +11613,9 @@ function GameMenu({
11484
11613
  logo,
11485
11614
  className
11486
11615
  }) {
11487
- const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
11616
+ const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
11488
11617
  const eventBus = useEventBus();
11489
- const handleOptionClick = React90.useCallback(
11618
+ const handleOptionClick = React91.useCallback(
11490
11619
  (option) => {
11491
11620
  if (option.event) {
11492
11621
  eventBus.emit(`UI:${option.event}`, { option });
@@ -11505,39 +11634,48 @@ function GameMenu({
11505
11634
  {
11506
11635
  className: cn(
11507
11636
  "min-h-screen w-full flex flex-col items-center justify-center p-8",
11637
+ !background && "bg-background",
11508
11638
  className
11509
11639
  ),
11510
- style: {
11511
- background: background ?? "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f0e17 100%)"
11512
- },
11640
+ style: background ? { background } : void 0,
11513
11641
  children: [
11514
- /* @__PURE__ */ jsxs(Box, { className: "text-center mb-12 animate-fade-in", children: [
11515
- logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
11516
- /* @__PURE__ */ jsx(
11517
- Typography,
11518
- {
11519
- variant: "h1",
11520
- className: "text-5xl md:text-7xl font-bold text-[var(--color-foreground)] tracking-tight",
11521
- style: {
11522
- textShadow: "0 4px 12px rgba(0,0,0,0.5)"
11523
- },
11524
- children: title
11525
- }
11526
- ),
11527
- subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
11528
- ] }),
11529
- /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full max-w-md", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
11530
- ChoiceButton,
11531
- {
11532
- text: option.label,
11533
- index: index + 1,
11534
- disabled: option.disabled,
11535
- onClick: () => handleOptionClick(option),
11536
- className: "text-lg py-4 px-8"
11537
- },
11538
- index
11539
- )) }),
11540
- /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden", children: [
11642
+ /* @__PURE__ */ jsxs(
11643
+ Card,
11644
+ {
11645
+ variant: "bordered",
11646
+ padding: "lg",
11647
+ className: "bg-card flex flex-col items-center max-w-md w-full",
11648
+ children: [
11649
+ /* @__PURE__ */ jsxs(Box, { className: "text-center mb-8 animate-fade-in", children: [
11650
+ logo && /* @__PURE__ */ jsx(GameIcon, { assetUrl: logo, icon: "image", size: 96, alt: title, className: "h-24 w-auto mx-auto mb-6 drop-shadow-2xl" }),
11651
+ /* @__PURE__ */ jsx(
11652
+ Typography,
11653
+ {
11654
+ variant: "h1",
11655
+ className: "text-4xl md:text-5xl font-bold text-foreground tracking-tight",
11656
+ style: {
11657
+ textShadow: "0 4px 12px rgba(0,0,0,0.5)"
11658
+ },
11659
+ children: title
11660
+ }
11661
+ ),
11662
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "mt-2 text-lg text-muted-foreground tracking-widest uppercase", children: subtitle })
11663
+ ] }),
11664
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-4 w-full", children: resolvedOptions.map((option, index) => /* @__PURE__ */ jsx(
11665
+ ChoiceButton,
11666
+ {
11667
+ text: option.label,
11668
+ index: index + 1,
11669
+ disabled: option.disabled,
11670
+ onClick: () => handleOptionClick(option),
11671
+ className: "text-lg py-4 px-8"
11672
+ },
11673
+ index
11674
+ )) })
11675
+ ]
11676
+ }
11677
+ ),
11678
+ /* @__PURE__ */ jsxs(Box, { position: "absolute", className: "inset-0 pointer-events-none overflow-hidden -z-10", children: [
11541
11679
  /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-1/4 left-1/4 w-64 h-64 bg-info/10 rounded-container blur-3xl" }),
11542
11680
  /* @__PURE__ */ jsx(Box, { position: "absolute", className: "bottom-1/4 right-1/4 w-96 h-96 bg-accent/10 rounded-container blur-3xl" })
11543
11681
  ] })
@@ -11552,6 +11690,7 @@ var init_GameMenu = __esm({
11552
11690
  init_cn();
11553
11691
  init_useEventBus();
11554
11692
  init_Box();
11693
+ init_Card();
11555
11694
  init_Typography();
11556
11695
  init_GameIcon();
11557
11696
  init_ChoiceButton();
@@ -11712,7 +11851,7 @@ function StateGraph({
11712
11851
  }) {
11713
11852
  const eventBus = useEventBus();
11714
11853
  const nodes = states ?? [];
11715
- const positions = React90.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
11854
+ const positions = React91.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
11716
11855
  return /* @__PURE__ */ jsxs(
11717
11856
  Box,
11718
11857
  {
@@ -11783,8 +11922,8 @@ function MiniMap({
11783
11922
  tileAssets,
11784
11923
  unitAssets
11785
11924
  }) {
11786
- const canvasRef = React90.useRef(null);
11787
- const imgCacheRef = React90.useRef(/* @__PURE__ */ new Map());
11925
+ const canvasRef = React91.useRef(null);
11926
+ const imgCacheRef = React91.useRef(/* @__PURE__ */ new Map());
11788
11927
  function loadImg(url) {
11789
11928
  const cached = imgCacheRef.current.get(url);
11790
11929
  if (cached) return cached.complete ? cached : null;
@@ -11799,7 +11938,7 @@ function MiniMap({
11799
11938
  imgCacheRef.current.set(url, img);
11800
11939
  return null;
11801
11940
  }
11802
- React90.useEffect(() => {
11941
+ React91.useEffect(() => {
11803
11942
  const canvas = canvasRef.current;
11804
11943
  if (!canvas) return;
11805
11944
  const ctx = canvas.getContext("2d");
@@ -12882,6 +13021,10 @@ function Canvas2D({
12882
13021
  window.removeEventListener("keyup", onUp);
12883
13022
  };
12884
13023
  }, [keyMap, keyUpMap, eventBus]);
13024
+ useEffect(() => {
13025
+ if (!keyMap && !keyUpMap) return;
13026
+ canvasRef.current?.focus();
13027
+ }, [keyMap, keyUpMap]);
12885
13028
  if (error) {
12886
13029
  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: [
12887
13030
  /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
@@ -12930,7 +13073,7 @@ function Canvas2D({
12930
13073
  onWheel: gestureHandlers.onWheel,
12931
13074
  onContextMenu: (e) => e.preventDefault(),
12932
13075
  className: "cursor-pointer touch-none",
12933
- tabIndex: isFree ? 0 : void 0,
13076
+ tabIndex: isFree || keyMap || keyUpMap ? 0 : void 0,
12934
13077
  style: {
12935
13078
  width: viewportSize.width,
12936
13079
  height: viewportSize.height
@@ -13217,7 +13360,7 @@ function LinearView({
13217
13360
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
13218
13361
  const isDone = i < currentIdx;
13219
13362
  const isCurrent = i === currentIdx;
13220
- return /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
13363
+ return /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
13221
13364
  i > 0 && /* @__PURE__ */ jsx(
13222
13365
  Typography,
13223
13366
  {
@@ -13752,7 +13895,7 @@ function SequenceBar({
13752
13895
  else onSlotRemove?.(index);
13753
13896
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
13754
13897
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
13755
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
13898
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
13756
13899
  i > 0 && /* @__PURE__ */ jsx(
13757
13900
  Typography,
13758
13901
  {
@@ -13839,6 +13982,7 @@ var init_GameShell = __esm({
13839
13982
  "components/game/templates/GameShell.tsx"() {
13840
13983
  init_cn();
13841
13984
  init_Box();
13985
+ init_Card();
13842
13986
  init_Typography();
13843
13987
  init_AtlasImage();
13844
13988
  FONT_BASE = "https://almadar-kflow-assets.web.app/shared/_shared/kenney-fonts/fonts";
@@ -13867,13 +14011,14 @@ var init_GameShell = __esm({
13867
14011
  showTopBar = true,
13868
14012
  children,
13869
14013
  backgroundAsset,
13870
- hudBackgroundAsset,
13871
- fontFamily = "future"
14014
+ fontFamily = "future",
14015
+ "data-theme": dataTheme
13872
14016
  }) => {
13873
14017
  const font = GAME_FONTS[fontFamily] ?? fontFamily;
13874
14018
  return /* @__PURE__ */ jsxs(
13875
14019
  Box,
13876
14020
  {
14021
+ "data-theme": dataTheme || void 0,
13877
14022
  className: cn("game-shell", className),
13878
14023
  style: {
13879
14024
  position: "relative",
@@ -13881,7 +14026,7 @@ var init_GameShell = __esm({
13881
14026
  height: "100vh",
13882
14027
  overflow: "hidden",
13883
14028
  background: "var(--color-background, #0a0a0f)",
13884
- color: "var(--color-text, #e0e0e0)",
14029
+ color: "var(--color-foreground, #e0e0e0)",
13885
14030
  fontFamily: `'${font}', system-ui, sans-serif`
13886
14031
  },
13887
14032
  children: [
@@ -13913,19 +14058,12 @@ var init_GameShell = __esm({
13913
14058
  },
13914
14059
  children: [
13915
14060
  showTopBar && /* @__PURE__ */ jsx(
13916
- AtlasPanel,
14061
+ Card,
13917
14062
  {
13918
- asset: hudBackgroundAsset,
13919
- borderSlice: 12,
13920
- borderWidth: 10,
13921
- className: "game-shell__title pointer-events-auto",
13922
- style: {
13923
- padding: "6px 16px",
13924
- background: hudBackgroundAsset ? void 0 : "rgba(18, 18, 31, 0.85)",
13925
- borderRadius: hudBackgroundAsset ? void 0 : 10,
13926
- boxShadow: "0 4px 14px rgba(0,0,0,0.45)",
13927
- flexShrink: 0
13928
- },
14063
+ variant: "bordered",
14064
+ padding: "none",
14065
+ className: "game-shell__title bg-card pointer-events-auto",
14066
+ style: { padding: "6px 16px", flexShrink: 0 },
13929
14067
  children: /* @__PURE__ */ jsx(
13930
14068
  Typography,
13931
14069
  {
@@ -14406,7 +14544,7 @@ var init_ErrorBoundary = __esm({
14406
14544
  }
14407
14545
  );
14408
14546
  };
14409
- ErrorBoundary = class extends React90__default.Component {
14547
+ ErrorBoundary = class extends React91__default.Component {
14410
14548
  constructor(props) {
14411
14549
  super(props);
14412
14550
  __publicField(this, "reset", () => {
@@ -14673,7 +14811,7 @@ var init_Container = __esm({
14673
14811
  as: Component = "div"
14674
14812
  }) => {
14675
14813
  const resolvedSize = maxWidth ?? size ?? "lg";
14676
- return React90__default.createElement(
14814
+ return React91__default.createElement(
14677
14815
  Component,
14678
14816
  {
14679
14817
  className: cn(
@@ -16354,7 +16492,8 @@ var init_LoadingState = __esm({
16354
16492
  LoadingState = ({
16355
16493
  title,
16356
16494
  message,
16357
- className
16495
+ className,
16496
+ fullPage = false
16358
16497
  }) => {
16359
16498
  const { t } = useTranslate();
16360
16499
  const displayMessage = message ?? t("common.loading");
@@ -16363,7 +16502,8 @@ var init_LoadingState = __esm({
16363
16502
  {
16364
16503
  align: "center",
16365
16504
  className: cn(
16366
- "justify-center py-12",
16505
+ "justify-center",
16506
+ fullPage ? "fixed inset-0 z-[1000] py-12 bg-background/80 backdrop-blur-sm animate-overlay-in" : "py-12",
16367
16507
  className
16368
16508
  ),
16369
16509
  children: [
@@ -16671,7 +16811,7 @@ var init_CodeBlock = __esm({
16671
16811
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
16672
16812
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
16673
16813
  HIDDEN_LINE_NUMBERS = { display: "none" };
16674
- CodeBlock = React90__default.memo(
16814
+ CodeBlock = React91__default.memo(
16675
16815
  ({
16676
16816
  code: rawCode,
16677
16817
  language = "text",
@@ -17258,7 +17398,7 @@ var init_MarkdownContent = __esm({
17258
17398
  init_Box();
17259
17399
  init_CodeBlock();
17260
17400
  init_cn();
17261
- MarkdownContent = React90__default.memo(
17401
+ MarkdownContent = React91__default.memo(
17262
17402
  ({ content, direction = "ltr", className }) => {
17263
17403
  const { t: _t } = useTranslate();
17264
17404
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -18221,7 +18361,7 @@ var init_StateMachineView = __esm({
18221
18361
  Box,
18222
18362
  {
18223
18363
  className: cn(
18224
- "fixed z-50 animate-in fade-in-0 zoom-in-95 duration-150",
18364
+ "fixed z-50 animate-in fade-in-0 zoom-in-95 duration-fast",
18225
18365
  tooltip.pinned ? "pointer-events-auto" : "pointer-events-none"
18226
18366
  ),
18227
18367
  style: {
@@ -18585,7 +18725,7 @@ var init_StateMachineView = __esm({
18585
18725
  style: { top: title ? 30 : 0 },
18586
18726
  children: [
18587
18727
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
18588
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React90__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
18728
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React91__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
18589
18729
  StateNode2,
18590
18730
  {
18591
18731
  state,
@@ -19565,7 +19705,7 @@ var init_BookCoverPage = __esm({
19565
19705
  size: "lg",
19566
19706
  action: "BOOK_START",
19567
19707
  className: "mt-8",
19568
- children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: t("book.startReading") })
19708
+ children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "inherit", children: t("book.startReading") })
19569
19709
  }
19570
19710
  )
19571
19711
  ]
@@ -20624,6 +20764,129 @@ var init_Breadcrumb = __esm({
20624
20764
  Breadcrumb.displayName = "Breadcrumb";
20625
20765
  }
20626
20766
  });
20767
+ function useSafeEventBus2() {
20768
+ try {
20769
+ return useEventBus();
20770
+ } catch {
20771
+ return { emit: () => {
20772
+ }, on: () => () => {
20773
+ }, once: () => {
20774
+ } };
20775
+ }
20776
+ }
20777
+ var log5, lookStyles4, ButtonGroup;
20778
+ var init_ButtonGroup = __esm({
20779
+ "components/core/molecules/ButtonGroup.tsx"() {
20780
+ "use client";
20781
+ init_cn();
20782
+ init_atoms();
20783
+ init_useEventBus();
20784
+ log5 = createLogger("almadar:ui:button-group");
20785
+ lookStyles4 = {
20786
+ "right-aligned-buttons": "",
20787
+ "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
20788
+ "inline-row": "gap-2 inline-flex",
20789
+ "dropdown-menu": "[&>button:not(:first-child)]:hidden",
20790
+ "command-palette-trigger": "[&>button:not(:first-child)]:hidden"
20791
+ };
20792
+ ButtonGroup = ({
20793
+ children,
20794
+ primary,
20795
+ secondary,
20796
+ variant = "default",
20797
+ orientation = "horizontal",
20798
+ className,
20799
+ // Filter-group pattern props (entity and filters are used for schema-driven filtering)
20800
+ entity: _entity,
20801
+ filters,
20802
+ look = "right-aligned-buttons"
20803
+ }) => {
20804
+ const eventBus = useSafeEventBus2();
20805
+ const variantClasses2 = {
20806
+ default: "gap-0",
20807
+ 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",
20808
+ 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"
20809
+ };
20810
+ const orientationClasses = {
20811
+ horizontal: "flex-row",
20812
+ 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"
20813
+ };
20814
+ const handleActionClick = (action) => {
20815
+ if (action.event) {
20816
+ eventBus.emit("UI:DISPATCH", { event: action.event });
20817
+ }
20818
+ if (action.navigatesTo) {
20819
+ eventBus.emit("UI:NAVIGATE", { url: action.navigatesTo });
20820
+ }
20821
+ };
20822
+ const renderFormActions = () => {
20823
+ const buttons = [];
20824
+ if (secondary) {
20825
+ secondary.forEach((action, index) => {
20826
+ buttons.push(
20827
+ /* @__PURE__ */ jsx(
20828
+ Button,
20829
+ {
20830
+ type: action.actionType === "submit" ? "submit" : "button",
20831
+ variant: action.variant || "ghost",
20832
+ onClick: () => handleActionClick(action),
20833
+ children: action.label
20834
+ },
20835
+ `secondary-${index}`
20836
+ )
20837
+ );
20838
+ });
20839
+ }
20840
+ if (primary) {
20841
+ const isSubmit = primary.actionType === "submit";
20842
+ buttons.push(
20843
+ /* @__PURE__ */ jsx(
20844
+ Button,
20845
+ {
20846
+ type: isSubmit ? "submit" : "button",
20847
+ variant: primary.variant || "primary",
20848
+ onClick: () => handleActionClick(primary),
20849
+ "data-testid": isSubmit ? "form-submit" : void 0,
20850
+ children: primary.label
20851
+ },
20852
+ "primary"
20853
+ )
20854
+ );
20855
+ }
20856
+ return buttons;
20857
+ };
20858
+ const renderFilters = () => {
20859
+ if (!filters || filters.length === 0) return null;
20860
+ return filters.map((filter, index) => /* @__PURE__ */ jsx(
20861
+ Button,
20862
+ {
20863
+ variant: "ghost",
20864
+ onClick: () => {
20865
+ log5.debug("Filter clicked", { field: filter.field });
20866
+ },
20867
+ children: filter.label
20868
+ },
20869
+ `filter-${filter.field}-${index}`
20870
+ ));
20871
+ };
20872
+ return /* @__PURE__ */ jsx(
20873
+ "div",
20874
+ {
20875
+ className: cn(
20876
+ "inline-flex gap-2",
20877
+ variantClasses2[variant],
20878
+ orientationClasses[orientation],
20879
+ lookStyles4[look],
20880
+ className
20881
+ ),
20882
+ role: "group",
20883
+ children: children || renderFilters() || renderFormActions()
20884
+ }
20885
+ );
20886
+ };
20887
+ ButtonGroup.displayName = "ButtonGroup";
20888
+ }
20889
+ });
20627
20890
  function useSwipeGesture(callbacks, options = {}) {
20628
20891
  const { threshold = 50, velocityThreshold = 0.3, preventDefault = false } = options;
20629
20892
  const startX = useRef(0);
@@ -21433,7 +21696,7 @@ var init_CardGrid = __esm({
21433
21696
  CardGrid.displayName = "CardGrid";
21434
21697
  }
21435
21698
  });
21436
- function useSafeEventBus2() {
21699
+ function useSafeEventBus3() {
21437
21700
  try {
21438
21701
  return useEventBus();
21439
21702
  } catch {
@@ -21469,7 +21732,7 @@ var init_Carousel = __esm({
21469
21732
  const [activeIndex, setActiveIndex] = useState(0);
21470
21733
  const scrollRef = useRef(null);
21471
21734
  const autoPlayRef = useRef(null);
21472
- const eventBus = useSafeEventBus2();
21735
+ const eventBus = useSafeEventBus3();
21473
21736
  const { t } = useTranslate();
21474
21737
  const safeItems = items ?? [];
21475
21738
  const totalSlides = safeItems.length;
@@ -21831,7 +22094,7 @@ var init_Chart = __esm({
21831
22094
  return /* @__PURE__ */ jsx(
21832
22095
  Box,
21833
22096
  {
21834
- className: "h-full rounded-r-sm transition-all duration-500 ease-out min-w-[2px] cursor-pointer hover:opacity-80",
22097
+ className: "h-full rounded-r-sm transition-all duration-slow ease-standard min-w-[2px] cursor-pointer hover:opacity-80",
21835
22098
  style: {
21836
22099
  width: `${ratio}%`,
21837
22100
  backgroundColor: color
@@ -21877,8 +22140,9 @@ var init_Chart = __esm({
21877
22140
  align: "center",
21878
22141
  flex: true,
21879
22142
  className: "min-w-0",
22143
+ style: { height: "100%" },
21880
22144
  children: [
21881
- /* @__PURE__ */ jsx(HStack, { gap: histogram ? "none" : "xs", align: "end", className: "w-full", style: { height: "100%" }, children: series.map((s, sIdx) => {
22145
+ /* @__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) => {
21882
22146
  const value = valueAt(s, label);
21883
22147
  const barHeight = value / maxValue * 100;
21884
22148
  const color = seriesColor(s, sIdx);
@@ -21886,11 +22150,13 @@ var init_Chart = __esm({
21886
22150
  Box,
21887
22151
  {
21888
22152
  className: cn(
21889
- "rounded-t-sm transition-all duration-500 ease-out min-h-[4px] cursor-pointer hover:opacity-80",
22153
+ "rounded-t-sm transition-all duration-slow ease-standard min-h-[4px] cursor-pointer hover:opacity-80",
21890
22154
  histogram ? "flex-1 mx-0" : "flex-1"
21891
22155
  ),
21892
22156
  style: {
21893
22157
  height: `${barHeight}%`,
22158
+ // Cap width so a lone category doesn't paint the whole plot as one solid block; narrow columns are unaffected (flex-1 binds first).
22159
+ ...!histogram && { maxWidth: 72 },
21894
22160
  backgroundColor: color
21895
22161
  },
21896
22162
  onClick: () => onPointClick?.(
@@ -21925,15 +22191,16 @@ var init_Chart = __esm({
21925
22191
  align: "center",
21926
22192
  flex: true,
21927
22193
  className: "min-w-0",
22194
+ style: { height: "100%" },
21928
22195
  children: [
21929
- /* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full", style: { height: "100%" }, justify: "end", children: series.map((s, sIdx) => {
22196
+ /* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full flex-1 min-h-0", justify: "end", children: series.map((s, sIdx) => {
21930
22197
  const value = valueAt(s, label);
21931
22198
  const ratio = stack === "normalize" ? total === 0 ? 0 : value / total * 100 : value / maxValue * 100;
21932
22199
  const color = seriesColor(s, sIdx);
21933
22200
  return /* @__PURE__ */ jsx(
21934
22201
  Box,
21935
22202
  {
21936
- className: "w-full transition-all duration-500 ease-out cursor-pointer hover:opacity-80",
22203
+ className: "w-full transition-all duration-slow ease-standard cursor-pointer hover:opacity-80",
21937
22204
  style: {
21938
22205
  height: `${ratio}%`,
21939
22206
  backgroundColor: color
@@ -21971,6 +22238,7 @@ var init_Chart = __esm({
21971
22238
  const innerRadius = donut ? radius * 0.6 : 0;
21972
22239
  const center = size / 2;
21973
22240
  const segments = useMemo(() => {
22241
+ if (!Number.isFinite(total) || total <= 0) return [];
21974
22242
  let currentAngle = -Math.PI / 2;
21975
22243
  return data.map((point, idx) => {
21976
22244
  const angle = point.value / total * 2 * Math.PI;
@@ -21982,13 +22250,25 @@ var init_Chart = __esm({
21982
22250
  const y1 = center + radius * Math.sin(startAngle);
21983
22251
  const x2 = center + radius * Math.cos(endAngle);
21984
22252
  const y2 = center + radius * Math.sin(endAngle);
22253
+ const fullCircle = angle >= 2 * Math.PI - 1e-9;
22254
+ const midAngle = startAngle + angle / 2;
22255
+ const xm = center + radius * Math.cos(midAngle);
22256
+ const ym = center + radius * Math.sin(midAngle);
21985
22257
  let d;
21986
22258
  if (innerRadius > 0) {
21987
22259
  const ix1 = center + innerRadius * Math.cos(startAngle);
21988
22260
  const iy1 = center + innerRadius * Math.sin(startAngle);
21989
22261
  const ix2 = center + innerRadius * Math.cos(endAngle);
21990
22262
  const iy2 = center + innerRadius * Math.sin(endAngle);
21991
- 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`;
22263
+ if (fullCircle) {
22264
+ const ixm = center + innerRadius * Math.cos(midAngle);
22265
+ const iym = center + innerRadius * Math.sin(midAngle);
22266
+ 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`;
22267
+ } else {
22268
+ 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`;
22269
+ }
22270
+ } else if (fullCircle) {
22271
+ d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} Z`;
21992
22272
  } else {
21993
22273
  d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`;
21994
22274
  }
@@ -22010,7 +22290,7 @@ var init_Chart = __esm({
22010
22290
  fill: seg.color,
22011
22291
  stroke: "var(--color-card)",
22012
22292
  strokeWidth: "2",
22013
- className: "transition-opacity duration-200 hover:opacity-80 cursor-pointer",
22293
+ className: "transition-opacity duration-fast hover:opacity-80 cursor-pointer",
22014
22294
  onClick: () => onPointClick?.(
22015
22295
  { label: seg.label, value: seg.value, color: seg.color },
22016
22296
  "default"
@@ -24223,8 +24503,8 @@ var init_Menu = __esm({
24223
24503
  "bottom-end": "bottom-start"
24224
24504
  };
24225
24505
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
24226
- const triggerChild = React90__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
24227
- const triggerElement = React90__default.cloneElement(
24506
+ const triggerChild = React91__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
24507
+ const triggerElement = React91__default.cloneElement(
24228
24508
  triggerChild,
24229
24509
  {
24230
24510
  ref: triggerRef,
@@ -24319,14 +24599,14 @@ function useDataDnd(args) {
24319
24599
  const isZone = Boolean(dragGroup || accepts || sortable);
24320
24600
  const enabled = isZone || Boolean(dndRoot);
24321
24601
  const eventBus = useEventBus();
24322
- const parentRoot = React90__default.useContext(RootCtx);
24602
+ const parentRoot = React91__default.useContext(RootCtx);
24323
24603
  const isRoot = enabled && parentRoot === null;
24324
- const zoneId = React90__default.useId();
24604
+ const zoneId = React91__default.useId();
24325
24605
  const ownGroup = dragGroup ?? accepts ?? zoneId;
24326
- const [optimisticOrders, setOptimisticOrders] = React90__default.useState(() => /* @__PURE__ */ new Map());
24327
- const optimisticOrdersRef = React90__default.useRef(optimisticOrders);
24606
+ const [optimisticOrders, setOptimisticOrders] = React91__default.useState(() => /* @__PURE__ */ new Map());
24607
+ const optimisticOrdersRef = React91__default.useRef(optimisticOrders);
24328
24608
  optimisticOrdersRef.current = optimisticOrders;
24329
- const clearOptimisticOrder = React90__default.useCallback((group) => {
24609
+ const clearOptimisticOrder = React91__default.useCallback((group) => {
24330
24610
  setOptimisticOrders((prev) => {
24331
24611
  if (!prev.has(group)) return prev;
24332
24612
  const next = new Map(prev);
@@ -24351,7 +24631,7 @@ function useDataDnd(args) {
24351
24631
  const raw = it[dndItemIdField];
24352
24632
  return raw != null ? String(raw) : `__idx_${idx}`;
24353
24633
  }).join("|");
24354
- const itemIds = React90__default.useMemo(
24634
+ const itemIds = React91__default.useMemo(
24355
24635
  () => orderedItems.map((it, idx) => {
24356
24636
  const raw = it[dndItemIdField];
24357
24637
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -24362,7 +24642,7 @@ function useDataDnd(args) {
24362
24642
  const raw = it[dndItemIdField];
24363
24643
  return raw != null ? String(raw) : `__${idx}`;
24364
24644
  }).join("|");
24365
- React90__default.useEffect(() => {
24645
+ React91__default.useEffect(() => {
24366
24646
  const root = isRoot ? null : parentRoot;
24367
24647
  if (root) {
24368
24648
  root.clearOptimisticOrder(ownGroup);
@@ -24370,20 +24650,20 @@ function useDataDnd(args) {
24370
24650
  clearOptimisticOrder(ownGroup);
24371
24651
  }
24372
24652
  }, [itemsContentSig, ownGroup]);
24373
- const zonesRef = React90__default.useRef(/* @__PURE__ */ new Map());
24374
- const registerZone = React90__default.useCallback((zoneId2, meta2) => {
24653
+ const zonesRef = React91__default.useRef(/* @__PURE__ */ new Map());
24654
+ const registerZone = React91__default.useCallback((zoneId2, meta2) => {
24375
24655
  zonesRef.current.set(zoneId2, meta2);
24376
24656
  }, []);
24377
- const unregisterZone = React90__default.useCallback((zoneId2) => {
24657
+ const unregisterZone = React91__default.useCallback((zoneId2) => {
24378
24658
  zonesRef.current.delete(zoneId2);
24379
24659
  }, []);
24380
- const [activeDrag, setActiveDrag] = React90__default.useState(null);
24381
- const [overZoneGroup, setOverZoneGroup] = React90__default.useState(null);
24382
- const meta = React90__default.useMemo(
24660
+ const [activeDrag, setActiveDrag] = React91__default.useState(null);
24661
+ const [overZoneGroup, setOverZoneGroup] = React91__default.useState(null);
24662
+ const meta = React91__default.useMemo(
24383
24663
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
24384
24664
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
24385
24665
  );
24386
- React90__default.useEffect(() => {
24666
+ React91__default.useEffect(() => {
24387
24667
  const target = isRoot ? null : parentRoot;
24388
24668
  if (!target) {
24389
24669
  zonesRef.current.set(zoneId, meta);
@@ -24402,7 +24682,7 @@ function useDataDnd(args) {
24402
24682
  }, [parentRoot, isRoot, zoneId, meta]);
24403
24683
  const sensors = useAlmadarDndSensors(true);
24404
24684
  const collisionDetection = almadarDndCollisionDetection;
24405
- const findZoneByItem = React90__default.useCallback(
24685
+ const findZoneByItem = React91__default.useCallback(
24406
24686
  (id) => {
24407
24687
  for (const z of zonesRef.current.values()) {
24408
24688
  if (z.itemIds.includes(id)) return z;
@@ -24411,7 +24691,7 @@ function useDataDnd(args) {
24411
24691
  },
24412
24692
  []
24413
24693
  );
24414
- React90__default.useCallback(
24694
+ React91__default.useCallback(
24415
24695
  (group) => {
24416
24696
  for (const z of zonesRef.current.values()) {
24417
24697
  if (z.group === group) return z;
@@ -24420,7 +24700,7 @@ function useDataDnd(args) {
24420
24700
  },
24421
24701
  []
24422
24702
  );
24423
- const handleDragEnd = React90__default.useCallback(
24703
+ const handleDragEnd = React91__default.useCallback(
24424
24704
  (event) => {
24425
24705
  const { active, over } = event;
24426
24706
  const activeIdStr = String(active.id);
@@ -24511,8 +24791,8 @@ function useDataDnd(args) {
24511
24791
  },
24512
24792
  [eventBus]
24513
24793
  );
24514
- const sortableData = React90__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
24515
- const SortableItem = React90__default.useCallback(
24794
+ const sortableData = React91__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
24795
+ const SortableItem = React91__default.useCallback(
24516
24796
  ({ id, children }) => {
24517
24797
  const {
24518
24798
  attributes,
@@ -24552,7 +24832,7 @@ function useDataDnd(args) {
24552
24832
  id: droppableId,
24553
24833
  data: sortableData
24554
24834
  });
24555
- const ctx = React90__default.useContext(RootCtx);
24835
+ const ctx = React91__default.useContext(RootCtx);
24556
24836
  const activeDrag2 = ctx?.activeDrag ?? null;
24557
24837
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
24558
24838
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -24567,7 +24847,7 @@ function useDataDnd(args) {
24567
24847
  showForeignPlaceholder,
24568
24848
  ctxAvailable: ctx != null
24569
24849
  });
24570
- React90__default.useEffect(() => {
24850
+ React91__default.useEffect(() => {
24571
24851
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
24572
24852
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
24573
24853
  return /* @__PURE__ */ jsx(
@@ -24581,11 +24861,11 @@ function useDataDnd(args) {
24581
24861
  }
24582
24862
  );
24583
24863
  };
24584
- const rootContextValue = React90__default.useMemo(
24864
+ const rootContextValue = React91__default.useMemo(
24585
24865
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
24586
24866
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
24587
24867
  );
24588
- const handleDragStart = React90__default.useCallback((event) => {
24868
+ const handleDragStart = React91__default.useCallback((event) => {
24589
24869
  const sourceZone = findZoneByItem(event.active.id);
24590
24870
  const rect = event.active.rect.current.initial;
24591
24871
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -24604,7 +24884,7 @@ function useDataDnd(args) {
24604
24884
  isRoot
24605
24885
  });
24606
24886
  }, [findZoneByItem, isRoot, zoneId]);
24607
- const handleDragOver = React90__default.useCallback((event) => {
24887
+ const handleDragOver = React91__default.useCallback((event) => {
24608
24888
  const { active, over } = event;
24609
24889
  const overData = over?.data?.current;
24610
24890
  const overGroup = overData?.dndGroup ?? null;
@@ -24674,7 +24954,7 @@ function useDataDnd(args) {
24674
24954
  return next;
24675
24955
  });
24676
24956
  }, []);
24677
- const handleDragCancel = React90__default.useCallback((event) => {
24957
+ const handleDragCancel = React91__default.useCallback((event) => {
24678
24958
  setActiveDrag(null);
24679
24959
  setOverZoneGroup(null);
24680
24960
  dndLog.warn("dragCancel", {
@@ -24682,12 +24962,12 @@ function useDataDnd(args) {
24682
24962
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
24683
24963
  });
24684
24964
  }, []);
24685
- const handleDragEndWithCleanup = React90__default.useCallback((event) => {
24965
+ const handleDragEndWithCleanup = React91__default.useCallback((event) => {
24686
24966
  handleDragEnd(event);
24687
24967
  setActiveDrag(null);
24688
24968
  setOverZoneGroup(null);
24689
24969
  }, [handleDragEnd]);
24690
- const wrapContainer = React90__default.useCallback(
24970
+ const wrapContainer = React91__default.useCallback(
24691
24971
  (children) => {
24692
24972
  if (!enabled) return children;
24693
24973
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -24741,7 +25021,7 @@ var init_useDataDnd = __esm({
24741
25021
  init_useAlmadarDndCollision();
24742
25022
  init_Box();
24743
25023
  dndLog = createLogger("almadar:ui:dnd");
24744
- RootCtx = React90__default.createContext(null);
25024
+ RootCtx = React91__default.createContext(null);
24745
25025
  }
24746
25026
  });
24747
25027
  function renderIconInput(icon, props) {
@@ -24938,7 +25218,7 @@ function DataGrid({
24938
25218
  /* @__PURE__ */ jsx(
24939
25219
  Box,
24940
25220
  {
24941
- className: cn("grid", gapStyles5[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles4[look], className),
25221
+ className: cn("grid", gapStyles5[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles5[look], className),
24942
25222
  style: scrollX ? { gridAutoFlow: "column", gridAutoColumns: `minmax(${minCardWidth}px, 1fr)` } : gridTemplateColumns ? { gridTemplateColumns } : void 0,
24943
25223
  children: data.map((item, index) => {
24944
25224
  const itemData = item;
@@ -25015,10 +25295,10 @@ function DataGrid({
25015
25295
  ] }),
25016
25296
  badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
25017
25297
  const val = getNestedValue(itemData, field.name);
25018
- if (val === void 0 || val === null) return null;
25298
+ if (val === void 0 || val === null || val === "") return null;
25019
25299
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
25020
25300
  field.icon && renderIconInput(field.icon, { size: "xs" }),
25021
- /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
25301
+ /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: formatValue(val, field.format) })
25022
25302
  ] }, field.name);
25023
25303
  }) })
25024
25304
  ] }),
@@ -25133,7 +25413,7 @@ function DataGrid({
25133
25413
  ] })
25134
25414
  );
25135
25415
  }
25136
- var dataGridLog, BADGE_VARIANTS, gapStyles5, lookStyles4;
25416
+ var dataGridLog, BADGE_VARIANTS, gapStyles5, lookStyles5;
25137
25417
  var init_DataGrid = __esm({
25138
25418
  "components/core/molecules/DataGrid.tsx"() {
25139
25419
  "use client";
@@ -25168,7 +25448,7 @@ var init_DataGrid = __esm({
25168
25448
  lg: "gap-6",
25169
25449
  xl: "gap-8"
25170
25450
  };
25171
- lookStyles4 = {
25451
+ lookStyles5 = {
25172
25452
  dense: "gap-2 [&>*]:p-card-sm",
25173
25453
  spacious: "gap-8 [&>*]:p-card-lg",
25174
25454
  striped: "[&>*:nth-child(even)]:bg-muted/30",
@@ -25268,7 +25548,7 @@ function DataList({
25268
25548
  }) {
25269
25549
  const eventBus = useEventBus();
25270
25550
  const { t } = useTranslate();
25271
- const [visibleCount, setVisibleCount] = React90__default.useState(pageSize || Infinity);
25551
+ const [visibleCount, setVisibleCount] = React91__default.useState(pageSize || Infinity);
25272
25552
  const fieldDefs = fields ?? columns ?? [];
25273
25553
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
25274
25554
  const dnd = useDataDnd({
@@ -25287,7 +25567,7 @@ function DataList({
25287
25567
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
25288
25568
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
25289
25569
  const hasRenderProp = typeof children === "function";
25290
- React90__default.useEffect(() => {
25570
+ React91__default.useEffect(() => {
25291
25571
  const renderItemTypeOf = typeof schemaRenderItem;
25292
25572
  const childrenTypeOf = typeof children;
25293
25573
  if (data.length > 0 && !hasRenderProp) {
@@ -25391,7 +25671,7 @@ function DataList({
25391
25671
  const items2 = [...data];
25392
25672
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
25393
25673
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
25394
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
25674
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
25395
25675
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
25396
25676
  group.items.map((itemData, index) => {
25397
25677
  const id = itemData.id || `${gi}-${index}`;
@@ -25532,7 +25812,7 @@ function DataList({
25532
25812
  className
25533
25813
  ),
25534
25814
  children: [
25535
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
25815
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
25536
25816
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
25537
25817
  group.items.map(
25538
25818
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -25617,7 +25897,7 @@ var init_FormSection = __esm({
25617
25897
  columns = 1,
25618
25898
  className
25619
25899
  }) => {
25620
- const [collapsed, setCollapsed] = React90__default.useState(defaultCollapsed);
25900
+ const [collapsed, setCollapsed] = React91__default.useState(defaultCollapsed);
25621
25901
  const { t } = useTranslate();
25622
25902
  const eventBus = useEventBus();
25623
25903
  const gridClass = {
@@ -25625,7 +25905,7 @@ var init_FormSection = __esm({
25625
25905
  2: "grid-cols-1 md:grid-cols-2",
25626
25906
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
25627
25907
  }[columns];
25628
- React90__default.useCallback(() => {
25908
+ React91__default.useCallback(() => {
25629
25909
  if (collapsible) {
25630
25910
  setCollapsed((prev) => !prev);
25631
25911
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -25883,129 +26163,6 @@ var init_FormField = __esm({
25883
26163
  FormField.displayName = "FormField";
25884
26164
  }
25885
26165
  });
25886
- function useSafeEventBus3() {
25887
- try {
25888
- return useEventBus();
25889
- } catch {
25890
- return { emit: () => {
25891
- }, on: () => () => {
25892
- }, once: () => {
25893
- } };
25894
- }
25895
- }
25896
- var log5, lookStyles5, ButtonGroup;
25897
- var init_ButtonGroup = __esm({
25898
- "components/core/molecules/ButtonGroup.tsx"() {
25899
- "use client";
25900
- init_cn();
25901
- init_atoms();
25902
- init_useEventBus();
25903
- log5 = createLogger("almadar:ui:button-group");
25904
- lookStyles5 = {
25905
- "right-aligned-buttons": "",
25906
- "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
25907
- "inline-row": "gap-2 inline-flex",
25908
- "dropdown-menu": "[&>button:not(:first-child)]:hidden",
25909
- "command-palette-trigger": "[&>button:not(:first-child)]:hidden"
25910
- };
25911
- ButtonGroup = ({
25912
- children,
25913
- primary,
25914
- secondary,
25915
- variant = "default",
25916
- orientation = "horizontal",
25917
- className,
25918
- // Filter-group pattern props (entity and filters are used for schema-driven filtering)
25919
- entity: _entity,
25920
- filters,
25921
- look = "right-aligned-buttons"
25922
- }) => {
25923
- const eventBus = useSafeEventBus3();
25924
- const variantClasses2 = {
25925
- default: "gap-0",
25926
- 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",
25927
- 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"
25928
- };
25929
- const orientationClasses = {
25930
- horizontal: "flex-row",
25931
- 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"
25932
- };
25933
- const handleActionClick = (action) => {
25934
- if (action.event) {
25935
- eventBus.emit("UI:DISPATCH", { event: action.event });
25936
- }
25937
- if (action.navigatesTo) {
25938
- eventBus.emit("UI:NAVIGATE", { url: action.navigatesTo });
25939
- }
25940
- };
25941
- const renderFormActions = () => {
25942
- const buttons = [];
25943
- if (secondary) {
25944
- secondary.forEach((action, index) => {
25945
- buttons.push(
25946
- /* @__PURE__ */ jsx(
25947
- Button,
25948
- {
25949
- type: action.actionType === "submit" ? "submit" : "button",
25950
- variant: action.variant || "ghost",
25951
- onClick: () => handleActionClick(action),
25952
- children: action.label
25953
- },
25954
- `secondary-${index}`
25955
- )
25956
- );
25957
- });
25958
- }
25959
- if (primary) {
25960
- const isSubmit = primary.actionType === "submit";
25961
- buttons.push(
25962
- /* @__PURE__ */ jsx(
25963
- Button,
25964
- {
25965
- type: isSubmit ? "submit" : "button",
25966
- variant: primary.variant || "primary",
25967
- onClick: () => handleActionClick(primary),
25968
- "data-testid": isSubmit ? "form-submit" : void 0,
25969
- children: primary.label
25970
- },
25971
- "primary"
25972
- )
25973
- );
25974
- }
25975
- return buttons;
25976
- };
25977
- const renderFilters = () => {
25978
- if (!filters || filters.length === 0) return null;
25979
- return filters.map((filter, index) => /* @__PURE__ */ jsx(
25980
- Button,
25981
- {
25982
- variant: "ghost",
25983
- onClick: () => {
25984
- log5.debug("Filter clicked", { field: filter.field });
25985
- },
25986
- children: filter.label
25987
- },
25988
- `filter-${filter.field}-${index}`
25989
- ));
25990
- };
25991
- return /* @__PURE__ */ jsx(
25992
- "div",
25993
- {
25994
- className: cn(
25995
- "inline-flex gap-2",
25996
- variantClasses2[variant],
25997
- orientationClasses[orientation],
25998
- lookStyles5[look],
25999
- className
26000
- ),
26001
- role: "group",
26002
- children: children || renderFilters() || renderFormActions()
26003
- }
26004
- );
26005
- };
26006
- ButtonGroup.displayName = "ButtonGroup";
26007
- }
26008
- });
26009
26166
  function getOrCreateStore(query) {
26010
26167
  if (!queryStores.has(query)) {
26011
26168
  queryStores.set(query, {
@@ -26182,7 +26339,7 @@ var init_FilterGroup = __esm({
26182
26339
  type: "button",
26183
26340
  onClick: () => handleFilterSelect(filter.field, null),
26184
26341
  className: cn(
26185
- "px-3 py-1.5 text-sm font-medium transition-all duration-[var(--transition-fast)]",
26342
+ "px-3 py-1.5 text-sm font-medium transition-all duration-fast",
26186
26343
  !selectedValues[filter.field] ? "bg-primary text-primary-foreground" : "bg-card text-muted-foreground hover:bg-muted"
26187
26344
  ),
26188
26345
  children: t("filterGroup.all")
@@ -26194,7 +26351,7 @@ var init_FilterGroup = __esm({
26194
26351
  type: "button",
26195
26352
  onClick: () => handleFilterSelect(filter.field, option),
26196
26353
  className: cn(
26197
- "px-3 py-1.5 text-sm font-medium transition-all duration-[var(--transition-fast)]",
26354
+ "px-3 py-1.5 text-sm font-medium transition-all duration-fast",
26198
26355
  "border-l-[length:var(--border-width)] border-border",
26199
26356
  selectedValues[filter.field] === option ? "bg-primary text-primary-foreground" : "bg-card text-muted-foreground hover:bg-muted"
26200
26357
  ),
@@ -26575,7 +26732,7 @@ var init_Flex = __esm({
26575
26732
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
26576
26733
  }
26577
26734
  }
26578
- return React90__default.createElement(Component, {
26735
+ return React91__default.createElement(Component, {
26579
26736
  className: cn(
26580
26737
  inline ? "inline-flex" : "flex",
26581
26738
  directionStyles[direction],
@@ -26694,7 +26851,7 @@ var init_Grid = __esm({
26694
26851
  as: Component = "div"
26695
26852
  }) => {
26696
26853
  const mergedStyle = rows ? { gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, ...style } : style;
26697
- return React90__default.createElement(
26854
+ return React91__default.createElement(
26698
26855
  Component,
26699
26856
  {
26700
26857
  className: cn(
@@ -26805,6 +26962,7 @@ var init_Popover = __esm({
26805
26962
  "components/core/molecules/Popover.tsx"() {
26806
26963
  "use client";
26807
26964
  init_Typography();
26965
+ init_Presence();
26808
26966
  init_cn();
26809
26967
  init_useTapReveal();
26810
26968
  arrowClasses = {
@@ -26828,6 +26986,7 @@ var init_Popover = __esm({
26828
26986
  const [popoverWidth, setPopoverWidth] = useState(0);
26829
26987
  const triggerRef = useRef(null);
26830
26988
  const popoverRef = useRef(null);
26989
+ const { mounted, className: panelAnim, onAnimationEnd } = usePresence(isOpen, { animation: "popover" });
26831
26990
  const updatePosition = () => {
26832
26991
  if (triggerRef.current) {
26833
26992
  setTriggerRect(triggerRef.current.getBoundingClientRect());
@@ -26853,10 +27012,11 @@ var init_Popover = __esm({
26853
27012
  useEffect(() => {
26854
27013
  if (isOpen) {
26855
27014
  updatePosition();
26856
- } else {
26857
- setPopoverWidth(0);
26858
27015
  }
26859
27016
  }, [isOpen]);
27017
+ useEffect(() => {
27018
+ if (!mounted) setPopoverWidth(0);
27019
+ }, [mounted]);
26860
27020
  useLayoutEffect(() => {
26861
27021
  if (isOpen && popoverRef.current) {
26862
27022
  const measured = popoverRef.current.offsetWidth;
@@ -26890,9 +27050,9 @@ var init_Popover = __esm({
26890
27050
  onMouseLeave: handleClose,
26891
27051
  onPointerDown: tapTriggerProps.onPointerDown
26892
27052
  };
26893
- const childElement = React90__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
27053
+ const childElement = React91__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26894
27054
  const childPointerDown = childElement.props.onPointerDown;
26895
- const triggerElement = React90__default.cloneElement(
27055
+ const triggerElement = React91__default.cloneElement(
26896
27056
  childElement,
26897
27057
  {
26898
27058
  ref: triggerRef,
@@ -26905,13 +27065,14 @@ var init_Popover = __esm({
26905
27065
  } : void 0
26906
27066
  }
26907
27067
  );
26908
- const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
27068
+ const panel = mounted && triggerRect ? /* @__PURE__ */ jsxs(
26909
27069
  "div",
26910
27070
  {
26911
27071
  ref: popoverRef,
26912
27072
  className: cn(
26913
27073
  "fixed z-50 p-4",
26914
27074
  "bg-card border-2 border-border shadow-elevation-popover",
27075
+ panelAnim,
26915
27076
  className
26916
27077
  ),
26917
27078
  style: {
@@ -26919,6 +27080,7 @@ var init_Popover = __esm({
26919
27080
  ...popoverWidth === 0 ? { visibility: "hidden" } : void 0
26920
27081
  },
26921
27082
  role: "dialog",
27083
+ onAnimationEnd,
26922
27084
  onMouseEnter: trigger === "hover" ? handleOpen : void 0,
26923
27085
  onMouseLeave: trigger === "hover" ? handleClose : void 0,
26924
27086
  children: [
@@ -27332,6 +27494,7 @@ var init_SidePanel = __esm({
27332
27494
  init_Box();
27333
27495
  init_Button();
27334
27496
  init_Typography();
27497
+ init_Presence();
27335
27498
  init_cn();
27336
27499
  init_useEventBus();
27337
27500
  SidePanel = ({
@@ -27351,15 +27514,17 @@ var init_SidePanel = __esm({
27351
27514
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
27352
27515
  onClose();
27353
27516
  };
27354
- if (!isOpen) return null;
27517
+ const { mounted, className: panelAnim, onAnimationEnd } = usePresence(isOpen, { animation: "drawer" });
27518
+ const drawerSign = position === "right" ? 1 : -1;
27519
+ if (!mounted) return null;
27355
27520
  return /* @__PURE__ */ jsxs(Fragment, { children: [
27356
- showOverlay && /* @__PURE__ */ jsx(
27521
+ showOverlay && /* @__PURE__ */ jsx(Presence, { show: isOpen, animation: "overlay", children: /* @__PURE__ */ jsx(
27357
27522
  Box,
27358
27523
  {
27359
27524
  className: "fixed inset-0 bg-white/80 backdrop-blur-sm z-40 lg:hidden",
27360
27525
  onClick: handleClose
27361
27526
  }
27362
- ),
27527
+ ) }),
27363
27528
  /* @__PURE__ */ jsxs(
27364
27529
  Aside,
27365
27530
  {
@@ -27369,11 +27534,13 @@ var init_SidePanel = __esm({
27369
27534
  "border-l-2 border-border",
27370
27535
  position === "left" && "border-l-0 border-r-2",
27371
27536
  "flex flex-col",
27372
- "transition-transform duration-normal ease-standard",
27537
+ panelAnim,
27373
27538
  width,
27374
27539
  position === "right" ? "right-0" : "left-0",
27375
27540
  className
27376
27541
  ),
27542
+ style: { "--motion-drawer-sign": drawerSign },
27543
+ onAnimationEnd,
27377
27544
  children: [
27378
27545
  /* @__PURE__ */ jsxs(Box, { className: "flex items-center justify-between p-4 border-b-2 border-border sticky top-0 bg-card z-10", children: [
27379
27546
  /* @__PURE__ */ jsx(Typography, { variant: "h6", children: title }),
@@ -27494,9 +27661,9 @@ var init_Tooltip = __esm({
27494
27661
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
27495
27662
  };
27496
27663
  }, []);
27497
- const triggerElement = React90__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
27664
+ const triggerElement = React91__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
27498
27665
  const childPointerDown = triggerElement.props.onPointerDown;
27499
- const trigger = React90__default.cloneElement(triggerElement, {
27666
+ const trigger = React91__default.cloneElement(triggerElement, {
27500
27667
  ref: triggerRef,
27501
27668
  onMouseEnter: handleMouseEnter,
27502
27669
  onMouseLeave: handleMouseLeave,
@@ -27586,7 +27753,7 @@ var init_WizardProgress = __esm({
27586
27753
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
27587
27754
  const isActive = index === currentStep;
27588
27755
  const isCompleted = index < currentStep;
27589
- return /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
27756
+ return /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
27590
27757
  /* @__PURE__ */ jsx(
27591
27758
  "button",
27592
27759
  {
@@ -28137,7 +28304,7 @@ var init_FormSectionHeader = __esm({
28137
28304
  name: "chevron-down",
28138
28305
  size: "sm",
28139
28306
  className: cn(
28140
- "text-muted-foreground transition-transform duration-200 shrink-0",
28307
+ "text-muted-foreground transition-transform duration-fast shrink-0",
28141
28308
  isCollapsed && "-rotate-90"
28142
28309
  )
28143
28310
  }
@@ -29147,13 +29314,13 @@ var init_MapView = __esm({
29147
29314
  shadowSize: [41, 41]
29148
29315
  });
29149
29316
  L.Marker.prototype.options.icon = defaultIcon;
29150
- const { useEffect: useEffect62, useRef: useRef60, useCallback: useCallback92, useState: useState95 } = React90__default;
29317
+ const { useEffect: useEffect63, useRef: useRef61, useCallback: useCallback93, useState: useState97 } = React91__default;
29151
29318
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
29152
29319
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
29153
29320
  function MapUpdater({ centerLat, centerLng, zoom }) {
29154
29321
  const map = useMap();
29155
- const prevRef = useRef60({ centerLat, centerLng, zoom });
29156
- useEffect62(() => {
29322
+ const prevRef = useRef61({ centerLat, centerLng, zoom });
29323
+ useEffect63(() => {
29157
29324
  const prev = prevRef.current;
29158
29325
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
29159
29326
  map.setView([centerLat, centerLng], zoom);
@@ -29164,7 +29331,7 @@ var init_MapView = __esm({
29164
29331
  }
29165
29332
  function MapClickHandler({ onMapClick }) {
29166
29333
  const map = useMap();
29167
- useEffect62(() => {
29334
+ useEffect63(() => {
29168
29335
  if (!onMapClick) return;
29169
29336
  const handler = (e) => {
29170
29337
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -29192,8 +29359,8 @@ var init_MapView = __esm({
29192
29359
  showAttribution = true
29193
29360
  }) {
29194
29361
  const eventBus = useEventBus2();
29195
- const [clickedPosition, setClickedPosition] = useState95(null);
29196
- const handleMapClick = useCallback92((lat, lng) => {
29362
+ const [clickedPosition, setClickedPosition] = useState97(null);
29363
+ const handleMapClick = useCallback93((lat, lng) => {
29197
29364
  if (showClickedPin) {
29198
29365
  setClickedPosition({ lat, lng });
29199
29366
  }
@@ -29202,7 +29369,7 @@ var init_MapView = __esm({
29202
29369
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
29203
29370
  }
29204
29371
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
29205
- const handleMarkerClick = useCallback92((marker) => {
29372
+ const handleMarkerClick = useCallback93((marker) => {
29206
29373
  onMarkerClick?.(marker);
29207
29374
  if (markerClickEvent) {
29208
29375
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -29402,7 +29569,7 @@ var init_NumberStepper = __esm({
29402
29569
  "text-foreground",
29403
29570
  "hover:bg-muted",
29404
29571
  "active:bg-muted",
29405
- "transition-colors duration-100",
29572
+ "transition-colors duration-instant",
29406
29573
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
29407
29574
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
29408
29575
  styles.button
@@ -29443,7 +29610,7 @@ var init_NumberStepper = __esm({
29443
29610
  "text-foreground",
29444
29611
  "hover:bg-muted",
29445
29612
  "active:bg-muted",
29446
- "transition-colors duration-100",
29613
+ "transition-colors duration-instant",
29447
29614
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
29448
29615
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
29449
29616
  styles.button
@@ -29567,7 +29734,7 @@ var init_StarRating = __esm({
29567
29734
  className: cn(
29568
29735
  styles.star,
29569
29736
  "text-foreground/30",
29570
- "transition-colors duration-100"
29737
+ "transition-colors duration-instant"
29571
29738
  ),
29572
29739
  strokeWidth: 1.5
29573
29740
  }
@@ -29580,7 +29747,7 @@ var init_StarRating = __esm({
29580
29747
  styles.star,
29581
29748
  "absolute inset-0",
29582
29749
  "text-warning fill-warning",
29583
- "transition-colors duration-100"
29750
+ "transition-colors duration-instant"
29584
29751
  ),
29585
29752
  strokeWidth: 1.5,
29586
29753
  style: isHalf ? { clipPath: "inset(0 50% 0 0)" } : void 0
@@ -29735,7 +29902,7 @@ var init_UploadDropZone = __esm({
29735
29902
  "relative flex flex-col items-center justify-center",
29736
29903
  "p-8 rounded-sm",
29737
29904
  "border-2 border-dashed",
29738
- "transition-colors duration-150",
29905
+ "transition-colors duration-fast",
29739
29906
  "cursor-pointer",
29740
29907
  isDragOver ? "border-primary bg-primary bg-opacity-5" : "border-border bg-surface",
29741
29908
  error && "border-error",
@@ -30062,8 +30229,8 @@ function TableView({
30062
30229
  }) {
30063
30230
  const eventBus = useEventBus();
30064
30231
  const { t } = useTranslate();
30065
- const [visibleCount, setVisibleCount] = React90__default.useState(pageSize > 0 ? pageSize : Infinity);
30066
- const [localSelected, setLocalSelected] = React90__default.useState(/* @__PURE__ */ new Set());
30232
+ const [visibleCount, setVisibleCount] = React91__default.useState(pageSize > 0 ? pageSize : Infinity);
30233
+ const [localSelected, setLocalSelected] = React91__default.useState(/* @__PURE__ */ new Set());
30067
30234
  const colDefs = columns ?? fields ?? [];
30068
30235
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
30069
30236
  const dnd = useDataDnd({
@@ -30143,7 +30310,7 @@ function TableView({
30143
30310
  className: cn(
30144
30311
  "grid items-center gap-3 sticky top-0 z-10",
30145
30312
  "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
30146
- "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
30313
+ "text-muted-foreground uppercase text-xs font-semibold tracking-wide",
30147
30314
  lk.headPad
30148
30315
  ),
30149
30316
  children: [
@@ -30258,12 +30425,12 @@ function TableView({
30258
30425
  ]
30259
30426
  }
30260
30427
  );
30261
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React90__default.Fragment, { children: rowInner }, id);
30428
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React91__default.Fragment, { children: rowInner }, id);
30262
30429
  };
30263
30430
  const items = Array.from(data);
30264
30431
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
30265
30432
  let runningIndex = 0;
30266
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
30433
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
30267
30434
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
30268
30435
  group.items.map((row) => renderRow(row, runningIndex++))
30269
30436
  ] }, gi)) });
@@ -30999,7 +31166,7 @@ function SortableListInner({
30999
31166
  "flex items-center justify-center",
31000
31167
  "text-muted-foreground",
31001
31168
  "hover:text-foreground",
31002
- "transition-colors duration-100",
31169
+ "transition-colors duration-instant",
31003
31170
  "px-1"
31004
31171
  ),
31005
31172
  "aria-grabbed": ariaGrabbed,
@@ -31026,7 +31193,7 @@ function SortableListInner({
31026
31193
  gap: "sm",
31027
31194
  align: "center",
31028
31195
  className: cn(
31029
- "transition-opacity duration-150",
31196
+ "transition-opacity duration-fast",
31030
31197
  isBeingDragged && "opacity-50"
31031
31198
  ),
31032
31199
  children: [
@@ -31198,7 +31365,7 @@ var init_PullToRefresh = __esm({
31198
31365
  children: /* @__PURE__ */ jsx(
31199
31366
  Box,
31200
31367
  {
31201
- className: "transition-transform duration-150",
31368
+ className: "transition-transform duration-fast",
31202
31369
  style: {
31203
31370
  transform: `scale(${isRefreshing ? 1 : pullProgress})`,
31204
31371
  opacity: isRefreshing ? 1 : pullProgress
@@ -31620,7 +31787,7 @@ var init_StepFlow = __esm({
31620
31787
  className
31621
31788
  }) => {
31622
31789
  if (orientation === "vertical") {
31623
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React90__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
31790
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React91__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
31624
31791
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
31625
31792
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
31626
31793
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -31631,7 +31798,7 @@ var init_StepFlow = __esm({
31631
31798
  ] })
31632
31799
  ] }) }, index)) });
31633
31800
  }
31634
- 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(React90__default.Fragment, { children: [
31801
+ 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(React91__default.Fragment, { children: [
31635
31802
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
31636
31803
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
31637
31804
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -32508,6 +32675,11 @@ var init_VoteStack = __esm({
32508
32675
  {
32509
32676
  className: cn(
32510
32677
  "inline-flex items-center justify-center",
32678
+ // Shrink-wrap in stretch contexts (slot/sidecar wrappers are
32679
+ // flex-column with stretch alignment): without this the root spans
32680
+ // the full wrapper width and the count row's `w-full` turns the
32681
+ // compact pill into a page-wide band.
32682
+ "w-fit",
32511
32683
  variant === "vertical" ? "flex-col" : "flex-row",
32512
32684
  "rounded-sm",
32513
32685
  "border-[length:var(--border-width)] border-border",
@@ -32532,7 +32704,7 @@ var init_VoteStack = __esm({
32532
32704
  isUp ? "text-primary" : "text-muted-foreground",
32533
32705
  "hover:bg-muted",
32534
32706
  "active:bg-muted",
32535
- "transition-colors duration-100",
32707
+ "transition-colors duration-instant",
32536
32708
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
32537
32709
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
32538
32710
  styles.button
@@ -32569,7 +32741,7 @@ var init_VoteStack = __esm({
32569
32741
  isDown ? "text-primary" : "text-muted-foreground",
32570
32742
  "hover:bg-muted",
32571
32743
  "active:bg-muted",
32572
- "transition-colors duration-100",
32744
+ "transition-colors duration-instant",
32573
32745
  "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent",
32574
32746
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
32575
32747
  styles.button
@@ -32616,7 +32788,7 @@ var init_LikertScale = __esm({
32616
32788
  md: "text-base",
32617
32789
  lg: "text-lg"
32618
32790
  };
32619
- LikertScale = React90__default.forwardRef(
32791
+ LikertScale = React91__default.forwardRef(
32620
32792
  ({
32621
32793
  question,
32622
32794
  options = DEFAULT_LIKERT_OPTIONS,
@@ -32628,7 +32800,7 @@ var init_LikertScale = __esm({
32628
32800
  variant = "radios",
32629
32801
  className
32630
32802
  }, ref) => {
32631
- const groupId = React90__default.useId();
32803
+ const groupId = React91__default.useId();
32632
32804
  const eventBus = useEventBus();
32633
32805
  const handleSelect = useCallback(
32634
32806
  (next) => {
@@ -32681,7 +32853,7 @@ var init_LikertScale = __esm({
32681
32853
  disabled,
32682
32854
  onClick: () => handleSelect(opt.value),
32683
32855
  className: cn(
32684
- "flex-1 text-center font-medium transition-colors duration-100",
32856
+ "flex-1 text-center font-medium transition-colors duration-instant",
32685
32857
  "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-inset",
32686
32858
  "disabled:cursor-not-allowed",
32687
32859
  "rounded-none gap-0 shadow-none border-none",
@@ -34910,7 +35082,7 @@ var init_DocBreadcrumb = __esm({
34910
35082
  "aria-label": t("aria.breadcrumb"),
34911
35083
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
34912
35084
  const isLast = idx === items.length - 1;
34913
- return /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
35085
+ return /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
34914
35086
  idx > 0 && /* @__PURE__ */ jsx(
34915
35087
  Icon,
34916
35088
  {
@@ -35574,7 +35746,7 @@ var init_PageHeader = __esm({
35574
35746
  info: "bg-info/10 text-info"
35575
35747
  };
35576
35748
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
35577
- 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(React90__default.Fragment, { children: [
35749
+ 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(React91__default.Fragment, { children: [
35578
35750
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
35579
35751
  crumb.href ? /* @__PURE__ */ jsx(
35580
35752
  "a",
@@ -35932,7 +36104,7 @@ var init_Section = __esm({
35932
36104
  as: Component = "section"
35933
36105
  }) => {
35934
36106
  const hasHeader = title || description || action;
35935
- return React90__default.createElement(
36107
+ return React91__default.createElement(
35936
36108
  Component,
35937
36109
  {
35938
36110
  className: cn(
@@ -35999,12 +36171,12 @@ var init_Sidebar = __esm({
35999
36171
  variant: "ghost",
36000
36172
  onClick: item.onClick,
36001
36173
  className: cn(
36002
- "w-full flex items-center gap-3 px-3 py-2.5 transition-all duration-[var(--transition-fast)] group relative",
36174
+ "w-full flex items-center gap-3 px-3 py-2.5 transition-all duration-fast group relative",
36003
36175
  "rounded-sm border-[length:var(--border-width-thin)] border-transparent",
36004
36176
  isActive ? [
36005
36177
  "bg-primary text-primary-foreground",
36006
36178
  "font-medium shadow-sm",
36007
- "border-primary translate-x-1 -translate-y-0.5"
36179
+ "border-primary translate-x-1 rtl:-translate-x-1 -translate-y-0.5"
36008
36180
  ].join(" ") : [
36009
36181
  "text-foreground",
36010
36182
  "hover:bg-muted hover:border-border",
@@ -36014,10 +36186,10 @@ var init_Sidebar = __esm({
36014
36186
  title: collapsed ? item.label : void 0,
36015
36187
  children: [
36016
36188
  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") })),
36017
- !collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-left", children: item.label }),
36189
+ !collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-start", children: item.label }),
36018
36190
  !collapsed && item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "danger", size: "sm", children: item.badge }),
36019
36191
  collapsed && /* @__PURE__ */ jsx(Box, { className: cn(
36020
- "absolute left-full ml-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
36192
+ "absolute start-full ms-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
36021
36193
  "pointer-events-none whitespace-nowrap z-50 transition-opacity",
36022
36194
  "bg-primary text-primary-foreground",
36023
36195
  "border-[length:var(--border-width-thin)] border-border",
@@ -36072,8 +36244,8 @@ var init_Sidebar = __esm({
36072
36244
  as: "aside",
36073
36245
  className: cn(
36074
36246
  "flex flex-col h-full",
36075
- "bg-card border-r border-border",
36076
- "transition-all duration-300 ease-in-out",
36247
+ "bg-card border-e border-border",
36248
+ "transition-all duration-normal ease-standard",
36077
36249
  collapsed ? "w-20" : "w-64",
36078
36250
  className
36079
36251
  ),
@@ -36306,7 +36478,7 @@ var init_WizardContainer = __esm({
36306
36478
  const isCompleted = index < currentStep;
36307
36479
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
36308
36480
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
36309
- return /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
36481
+ return /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
36310
36482
  /* @__PURE__ */ jsx(
36311
36483
  Button,
36312
36484
  {
@@ -37233,7 +37405,7 @@ function resolveColor3(color, el) {
37233
37405
  function truncateLabel(label) {
37234
37406
  return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
37235
37407
  }
37236
- var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
37408
+ var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, NO_NODES, NO_EDGES, NO_SIM, GraphCanvas;
37237
37409
  var init_GraphCanvas = __esm({
37238
37410
  "components/core/molecules/GraphCanvas.tsx"() {
37239
37411
  "use client";
@@ -37257,11 +37429,14 @@ var init_GraphCanvas = __esm({
37257
37429
  UNGROUPED_GRAVITY = 0.02;
37258
37430
  labelMeasureCtx = null;
37259
37431
  MAX_LABEL_CHARS = 22;
37432
+ NO_NODES = [];
37433
+ NO_EDGES = [];
37434
+ NO_SIM = [];
37260
37435
  GraphCanvas = ({
37261
37436
  title,
37262
- nodes: propNodes = [],
37263
- edges: propEdges = [],
37264
- similarity: propSimilarity = [],
37437
+ nodes: propNodes = NO_NODES,
37438
+ edges: propEdges = NO_EDGES,
37439
+ similarity: propSimilarity = NO_SIM,
37265
37440
  height = 400,
37266
37441
  showLabels = true,
37267
37442
  interactive = true,
@@ -37311,6 +37486,7 @@ var init_GraphCanvas = __esm({
37311
37486
  const interactionRef = useRef({
37312
37487
  mode: "none",
37313
37488
  dragNodeId: null,
37489
+ pressedNodeId: null,
37314
37490
  startMouse: { x: 0, y: 0 },
37315
37491
  startOffset: { x: 0, y: 0 },
37316
37492
  downPos: { x: 0, y: 0 }
@@ -37358,6 +37534,11 @@ var init_GraphCanvas = __esm({
37358
37534
  () => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
37359
37535
  [propNodes]
37360
37536
  );
37537
+ const nodesKey = useMemo(() => propNodes.map((n) => n.id).join(""), [propNodes]);
37538
+ const edgesKey = useMemo(
37539
+ () => propEdges.map((e) => `${e.source}${e.target}`).join(""),
37540
+ [propEdges]
37541
+ );
37361
37542
  useEffect(() => {
37362
37543
  const canvas = canvasRef.current;
37363
37544
  if (!canvas || propNodes.length === 0) return;
@@ -37538,7 +37719,7 @@ var init_GraphCanvas = __esm({
37538
37719
  return () => {
37539
37720
  cancelAnimationFrame(animRef.current);
37540
37721
  };
37541
- }, [propNodes, propEdges, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
37722
+ }, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
37542
37723
  useEffect(() => {
37543
37724
  const canvas = canvasRef.current;
37544
37725
  if (!canvas) return;
@@ -37668,6 +37849,7 @@ var init_GraphCanvas = __esm({
37668
37849
  const cancelSinglePointer = useCallback(() => {
37669
37850
  interactionRef.current.mode = "none";
37670
37851
  interactionRef.current.dragNodeId = null;
37852
+ interactionRef.current.pressedNodeId = null;
37671
37853
  }, []);
37672
37854
  const handlePointerDown = useCallback(
37673
37855
  (e) => {
@@ -37678,6 +37860,7 @@ var init_GraphCanvas = __esm({
37678
37860
  state.downPos = { x: e.clientX, y: e.clientY };
37679
37861
  state.startMouse = { x: e.clientX, y: e.clientY };
37680
37862
  state.startOffset = { ...offset };
37863
+ state.pressedNodeId = node?.id ?? null;
37681
37864
  if (draggable && node) {
37682
37865
  state.mode = "dragging";
37683
37866
  state.dragNodeId = node.id;
@@ -37729,7 +37912,8 @@ var init_GraphCanvas = __esm({
37729
37912
  if (moved < 4) {
37730
37913
  const coords = toCoords(e);
37731
37914
  if (!coords) return;
37732
- const node = nodeAt(coords.graphX, coords.graphY);
37915
+ const node = (state.pressedNodeId ? nodesRef.current.find((n) => n.id === state.pressedNodeId) : void 0) ?? nodeAt(coords.graphX, coords.graphY);
37916
+ state.pressedNodeId = null;
37733
37917
  if (node) {
37734
37918
  if (node.badge && node.badge > 1 && onBadgeClick) {
37735
37919
  const r2 = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
@@ -37749,6 +37933,7 @@ var init_GraphCanvas = __esm({
37749
37933
  );
37750
37934
  const handlePointerLeave = useCallback(() => {
37751
37935
  setHoveredNode(null);
37936
+ interactionRef.current.pressedNodeId = null;
37752
37937
  }, []);
37753
37938
  const gestureHandlers = useCanvasGestures({
37754
37939
  canvasRef,
@@ -38896,7 +39081,7 @@ var init_DetailPanel = __esm({
38896
39081
  }
38897
39082
  });
38898
39083
  function extractTitle(children) {
38899
- if (!React90__default.isValidElement(children)) return void 0;
39084
+ if (!React91__default.isValidElement(children)) return void 0;
38900
39085
  const props = children.props;
38901
39086
  if (typeof props.title === "string") {
38902
39087
  return props.title;
@@ -39246,12 +39431,12 @@ var init_Form = __esm({
39246
39431
  const isSchemaEntity = isOrbitalEntitySchema(entity);
39247
39432
  const resolvedEntity = isSchemaEntity ? entity : void 0;
39248
39433
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
39249
- const normalizedInitialData = React90__default.useMemo(() => {
39434
+ const normalizedInitialData = React91__default.useMemo(() => {
39250
39435
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
39251
39436
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
39252
39437
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
39253
39438
  }, [entity, initialData]);
39254
- const entityDerivedFields = React90__default.useMemo(() => {
39439
+ const entityDerivedFields = React91__default.useMemo(() => {
39255
39440
  if (fields && fields.length > 0) return void 0;
39256
39441
  if (!resolvedEntity) return void 0;
39257
39442
  return resolvedEntity.fields.map(
@@ -39272,16 +39457,16 @@ var init_Form = __esm({
39272
39457
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
39273
39458
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
39274
39459
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
39275
- const [formData, setFormData] = React90__default.useState(
39460
+ const [formData, setFormData] = React91__default.useState(
39276
39461
  normalizedInitialData
39277
39462
  );
39278
- const [collapsedSections, setCollapsedSections] = React90__default.useState(
39463
+ const [collapsedSections, setCollapsedSections] = React91__default.useState(
39279
39464
  /* @__PURE__ */ new Set()
39280
39465
  );
39281
- const [submitError, setSubmitError] = React90__default.useState(null);
39282
- const formRef = React90__default.useRef(null);
39466
+ const [submitError, setSubmitError] = React91__default.useState(null);
39467
+ const formRef = React91__default.useRef(null);
39283
39468
  const formMode = props.mode;
39284
- const mountedRef = React90__default.useRef(false);
39469
+ const mountedRef = React91__default.useRef(false);
39285
39470
  if (!mountedRef.current) {
39286
39471
  mountedRef.current = true;
39287
39472
  debug("forms", "mount", {
@@ -39294,7 +39479,7 @@ var init_Form = __esm({
39294
39479
  });
39295
39480
  }
39296
39481
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
39297
- const evalContext = React90__default.useMemo(
39482
+ const evalContext = React91__default.useMemo(
39298
39483
  () => ({
39299
39484
  formValues: formData,
39300
39485
  globalVariables: externalContext?.globalVariables ?? {},
@@ -39303,7 +39488,7 @@ var init_Form = __esm({
39303
39488
  }),
39304
39489
  [formData, externalContext]
39305
39490
  );
39306
- React90__default.useEffect(() => {
39491
+ React91__default.useEffect(() => {
39307
39492
  debug("forms", "initialData-sync", {
39308
39493
  mode: formMode,
39309
39494
  normalizedInitialData,
@@ -39314,7 +39499,7 @@ var init_Form = __esm({
39314
39499
  setFormData(normalizedInitialData);
39315
39500
  }
39316
39501
  }, [normalizedInitialData]);
39317
- const processCalculations = React90__default.useCallback(
39502
+ const processCalculations = React91__default.useCallback(
39318
39503
  (changedFieldId, newFormData) => {
39319
39504
  if (!hiddenCalculations.length) return;
39320
39505
  const context = {
@@ -39339,7 +39524,7 @@ var init_Form = __esm({
39339
39524
  },
39340
39525
  [hiddenCalculations, externalContext, eventBus]
39341
39526
  );
39342
- const checkViolations = React90__default.useCallback(
39527
+ const checkViolations = React91__default.useCallback(
39343
39528
  (changedFieldId, newFormData) => {
39344
39529
  if (!violationTriggers.length) return;
39345
39530
  const context = {
@@ -39377,7 +39562,7 @@ var init_Form = __esm({
39377
39562
  processCalculations(name, newFormData);
39378
39563
  checkViolations(name, newFormData);
39379
39564
  };
39380
- const isFieldVisible = React90__default.useCallback(
39565
+ const isFieldVisible = React91__default.useCallback(
39381
39566
  (fieldName) => {
39382
39567
  const condition = conditionalFields[fieldName];
39383
39568
  if (!condition) return true;
@@ -39385,7 +39570,7 @@ var init_Form = __esm({
39385
39570
  },
39386
39571
  [conditionalFields, evalContext]
39387
39572
  );
39388
- const isSectionVisible = React90__default.useCallback(
39573
+ const isSectionVisible = React91__default.useCallback(
39389
39574
  (section) => {
39390
39575
  if (!section.condition) return true;
39391
39576
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -39461,7 +39646,7 @@ var init_Form = __esm({
39461
39646
  eventBus.emit(`UI:${onCancel}`);
39462
39647
  }
39463
39648
  };
39464
- const renderField = React90__default.useCallback(
39649
+ const renderField = React91__default.useCallback(
39465
39650
  (field) => {
39466
39651
  const fieldName = field.name || field.field;
39467
39652
  if (!fieldName) return null;
@@ -39482,7 +39667,7 @@ var init_Form = __esm({
39482
39667
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
39483
39668
  );
39484
39669
  const effectiveFields = entityDerivedFields ?? fields;
39485
- const normalizedFields = React90__default.useMemo(() => {
39670
+ const normalizedFields = React91__default.useMemo(() => {
39486
39671
  if (!effectiveFields || effectiveFields.length === 0) return [];
39487
39672
  return effectiveFields.map((field) => {
39488
39673
  if (typeof field === "string") {
@@ -39506,7 +39691,7 @@ var init_Form = __esm({
39506
39691
  return field;
39507
39692
  });
39508
39693
  }, [effectiveFields, resolvedEntity]);
39509
- const schemaFields = React90__default.useMemo(() => {
39694
+ const schemaFields = React91__default.useMemo(() => {
39510
39695
  if (normalizedFields.length === 0) return null;
39511
39696
  if (isDebugEnabled()) {
39512
39697
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -39516,7 +39701,7 @@ var init_Form = __esm({
39516
39701
  }
39517
39702
  return normalizedFields.map(renderField).filter(Boolean);
39518
39703
  }, [normalizedFields, renderField, entityName, conditionalFields]);
39519
- const sectionElements = React90__default.useMemo(() => {
39704
+ const sectionElements = React91__default.useMemo(() => {
39520
39705
  if (!sections || sections.length === 0) return null;
39521
39706
  return sections.map((section) => {
39522
39707
  if (!isSectionVisible(section)) {
@@ -40199,7 +40384,7 @@ var init_List = __esm({
40199
40384
  Box,
40200
40385
  {
40201
40386
  className: cn(
40202
- "h-full rounded-full transition-all duration-500",
40387
+ "h-full rounded-full transition-all duration-slow",
40203
40388
  clampedValue >= 100 ? "bg-success" : clampedValue >= 70 ? "bg-info" : clampedValue >= 40 ? "bg-warning" : "bg-muted-foreground"
40204
40389
  ),
40205
40390
  style: { width: `${clampedValue}%` }
@@ -40241,7 +40426,7 @@ var init_List = __esm({
40241
40426
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
40242
40427
  return [];
40243
40428
  }, [entity]);
40244
- const getItemActions = React90__default.useCallback(
40429
+ const getItemActions = React91__default.useCallback(
40245
40430
  (item) => {
40246
40431
  if (!itemActions) return [];
40247
40432
  if (typeof itemActions === "function") {
@@ -40368,7 +40553,7 @@ var init_List = __esm({
40368
40553
  {
40369
40554
  className: cn(
40370
40555
  "group flex items-center gap-5 px-6 py-5",
40371
- "transition-all duration-300 ease-out",
40556
+ "transition-all duration-normal ease-standard",
40372
40557
  hasExplicitClick && "cursor-pointer",
40373
40558
  // Hover state
40374
40559
  "hover:bg-muted/80",
@@ -40475,7 +40660,7 @@ var init_List = __esm({
40475
40660
  variant: "ghost",
40476
40661
  action: editAction.event,
40477
40662
  className: cn(
40478
- "p-2 rounded-lg transition-all duration-200",
40663
+ "p-2 rounded-lg transition-all duration-fast",
40479
40664
  "hover:bg-primary/10 hover:text-primary",
40480
40665
  "text-muted-foreground",
40481
40666
  "active:scale-95"
@@ -40491,7 +40676,7 @@ var init_List = __esm({
40491
40676
  variant: "ghost",
40492
40677
  action: viewAction.event,
40493
40678
  className: cn(
40494
- "p-2 rounded-lg transition-all duration-200",
40679
+ "p-2 rounded-lg transition-all duration-fast",
40495
40680
  "hover:bg-muted hover:text-foreground",
40496
40681
  "text-muted-foreground",
40497
40682
  "active:scale-95"
@@ -40513,7 +40698,7 @@ var init_List = __esm({
40513
40698
  {
40514
40699
  variant: "ghost",
40515
40700
  className: cn(
40516
- "p-2 rounded-lg transition-all duration-200",
40701
+ "p-2 rounded-lg transition-all duration-fast",
40517
40702
  "hover:bg-muted hover:shadow-sm",
40518
40703
  "text-muted-foreground hover:text-foreground",
40519
40704
  "active:scale-95"
@@ -40700,8 +40885,17 @@ var init_MediaGallery = __esm({
40700
40885
  const eventBus = useEventBus();
40701
40886
  const { t } = useTranslate();
40702
40887
  const [lightboxItem, setLightboxItem] = useState(null);
40888
+ const [failedIds, setFailedIds] = useState(/* @__PURE__ */ new Set());
40703
40889
  const closeLightbox = useCallback(() => setLightboxItem(null), []);
40704
40890
  useEventListener("UI:LIGHTBOX_CLOSE", closeLightbox);
40891
+ const handleImageError = useCallback((id) => {
40892
+ setFailedIds((prev) => {
40893
+ if (prev.has(id)) return prev;
40894
+ const next = new Set(prev);
40895
+ next.add(id);
40896
+ return next;
40897
+ });
40898
+ }, []);
40705
40899
  const handleItemClick = useCallback(
40706
40900
  (item) => {
40707
40901
  if (selectable) {
@@ -40716,8 +40910,8 @@ var init_MediaGallery = __esm({
40716
40910
  [selectable, selectedItems, selectionEvent, eventBus]
40717
40911
  );
40718
40912
  const entityData = Array.isArray(entity) ? entity : [];
40719
- const items = React90__default.useMemo(() => {
40720
- if (propItems) return propItems;
40913
+ const items = React91__default.useMemo(() => {
40914
+ if (propItems && propItems.length > 0) return propItems;
40721
40915
  if (entityData.length === 0) return [];
40722
40916
  return entityData.map((record, idx) => {
40723
40917
  return {
@@ -40794,19 +40988,20 @@ var init_MediaGallery = __esm({
40794
40988
  {
40795
40989
  className: cn(
40796
40990
  "group relative overflow-hidden rounded-md cursor-pointer",
40797
- "border-2 transition-all duration-200",
40991
+ "border-2 transition-all duration-fast",
40798
40992
  isSelected ? "border-primary ring-2 ring-primary/30" : "border-transparent hover:border-border",
40799
40993
  ASPECT_CLASSES[aspectRatio]
40800
40994
  ),
40801
40995
  onClick: () => handleItemClick(item),
40802
40996
  children: [
40803
- /* @__PURE__ */ jsx(
40997
+ 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(
40804
40998
  "img",
40805
40999
  {
40806
41000
  src: item.thumbnail || item.src,
40807
41001
  alt: item.alt || item.caption || "",
40808
41002
  className: "w-full h-full object-cover",
40809
- loading: "lazy"
41003
+ loading: "lazy",
41004
+ onError: () => handleImageError(item.id)
40810
41005
  }
40811
41006
  ),
40812
41007
  /* @__PURE__ */ jsx(
@@ -40814,14 +41009,14 @@ var init_MediaGallery = __esm({
40814
41009
  {
40815
41010
  className: cn(
40816
41011
  "absolute inset-0 bg-foreground/0 group-hover:bg-foreground/20",
40817
- "transition-colors duration-200 flex items-center justify-center"
41012
+ "transition-colors duration-fast flex items-center justify-center"
40818
41013
  ),
40819
41014
  children: /* @__PURE__ */ jsx(
40820
41015
  Icon,
40821
41016
  {
40822
41017
  icon: ZoomIn,
40823
41018
  size: "md",
40824
- className: "text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200"
41019
+ className: "text-white opacity-0 group-hover:opacity-100 transition-opacity duration-fast"
40825
41020
  }
40826
41021
  )
40827
41022
  }
@@ -40879,7 +41074,7 @@ var init_MediaGallery = __esm({
40879
41074
  }
40880
41075
  });
40881
41076
  function extractTitle2(children) {
40882
- if (!React90__default.isValidElement(children)) return void 0;
41077
+ if (!React91__default.isValidElement(children)) return void 0;
40883
41078
  const props = children.props;
40884
41079
  if (typeof props.title === "string") {
40885
41080
  return props.title;
@@ -41153,7 +41348,7 @@ var init_debugRegistry = __esm({
41153
41348
  }
41154
41349
  });
41155
41350
  function useDebugData() {
41156
- const [data, setData] = React90.useState(() => ({
41351
+ const [data, setData] = React91.useState(() => ({
41157
41352
  traits: [],
41158
41353
  ticks: [],
41159
41354
  guards: [],
@@ -41167,7 +41362,7 @@ function useDebugData() {
41167
41362
  },
41168
41363
  lastUpdate: Date.now()
41169
41364
  }));
41170
- React90.useEffect(() => {
41365
+ React91.useEffect(() => {
41171
41366
  const updateData = () => {
41172
41367
  setData({
41173
41368
  traits: getAllTraits(),
@@ -41276,12 +41471,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
41276
41471
  return positions;
41277
41472
  }
41278
41473
  function WalkMinimap() {
41279
- const [walkStep, setWalkStep] = React90.useState(null);
41280
- const [traits2, setTraits] = React90.useState([]);
41281
- const [coveredEdges, setCoveredEdges] = React90.useState([]);
41282
- const [completedTraits, setCompletedTraits] = React90.useState(/* @__PURE__ */ new Set());
41283
- const prevTraitRef = React90.useRef(null);
41284
- React90.useEffect(() => {
41474
+ const [walkStep, setWalkStep] = React91.useState(null);
41475
+ const [traits2, setTraits] = React91.useState([]);
41476
+ const [coveredEdges, setCoveredEdges] = React91.useState([]);
41477
+ const [completedTraits, setCompletedTraits] = React91.useState(/* @__PURE__ */ new Set());
41478
+ const prevTraitRef = React91.useRef(null);
41479
+ React91.useEffect(() => {
41285
41480
  const interval = setInterval(() => {
41286
41481
  const w = window;
41287
41482
  const step = w.__orbitalWalkStep;
@@ -41717,15 +41912,15 @@ var init_EntitiesTab = __esm({
41717
41912
  });
41718
41913
  function EventFlowTab({ events: events2 }) {
41719
41914
  const { t } = useTranslate();
41720
- const [filter, setFilter] = React90.useState("all");
41721
- const containerRef = React90.useRef(null);
41722
- const [autoScroll, setAutoScroll] = React90.useState(true);
41723
- React90.useEffect(() => {
41915
+ const [filter, setFilter] = React91.useState("all");
41916
+ const containerRef = React91.useRef(null);
41917
+ const [autoScroll, setAutoScroll] = React91.useState(true);
41918
+ React91.useEffect(() => {
41724
41919
  if (autoScroll && containerRef.current) {
41725
41920
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
41726
41921
  }
41727
41922
  }, [events2.length, autoScroll]);
41728
- const filteredEvents = React90.useMemo(() => {
41923
+ const filteredEvents = React91.useMemo(() => {
41729
41924
  if (filter === "all") return events2;
41730
41925
  return events2.filter((e) => e.type === filter);
41731
41926
  }, [events2, filter]);
@@ -41841,7 +42036,7 @@ var init_EventFlowTab = __esm({
41841
42036
  });
41842
42037
  function GuardsPanel({ guards }) {
41843
42038
  const { t } = useTranslate();
41844
- const [filter, setFilter] = React90.useState("all");
42039
+ const [filter, setFilter] = React91.useState("all");
41845
42040
  if (guards.length === 0) {
41846
42041
  return /* @__PURE__ */ jsx(
41847
42042
  EmptyState,
@@ -41854,7 +42049,7 @@ function GuardsPanel({ guards }) {
41854
42049
  }
41855
42050
  const passedCount = guards.filter((g) => g.result).length;
41856
42051
  const failedCount = guards.length - passedCount;
41857
- const filteredGuards = React90.useMemo(() => {
42052
+ const filteredGuards = React91.useMemo(() => {
41858
42053
  if (filter === "all") return guards;
41859
42054
  if (filter === "passed") return guards.filter((g) => g.result);
41860
42055
  return guards.filter((g) => !g.result);
@@ -42017,10 +42212,10 @@ function EffectBadge({ effect }) {
42017
42212
  }
42018
42213
  function TransitionTimeline({ transitions }) {
42019
42214
  const { t } = useTranslate();
42020
- const containerRef = React90.useRef(null);
42021
- const [autoScroll, setAutoScroll] = React90.useState(true);
42022
- const [expandedId, setExpandedId] = React90.useState(null);
42023
- React90.useEffect(() => {
42215
+ const containerRef = React91.useRef(null);
42216
+ const [autoScroll, setAutoScroll] = React91.useState(true);
42217
+ const [expandedId, setExpandedId] = React91.useState(null);
42218
+ React91.useEffect(() => {
42024
42219
  if (autoScroll && containerRef.current) {
42025
42220
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
42026
42221
  }
@@ -42300,9 +42495,9 @@ function getAllEvents(traits2) {
42300
42495
  function EventDispatcherTab({ traits: traits2, schema }) {
42301
42496
  const eventBus = useEventBus();
42302
42497
  const { t } = useTranslate();
42303
- const [log11, setLog] = React90.useState([]);
42304
- const prevStatesRef = React90.useRef(/* @__PURE__ */ new Map());
42305
- React90.useEffect(() => {
42498
+ const [log11, setLog] = React91.useState([]);
42499
+ const prevStatesRef = React91.useRef(/* @__PURE__ */ new Map());
42500
+ React91.useEffect(() => {
42306
42501
  for (const trait of traits2) {
42307
42502
  const prev = prevStatesRef.current.get(trait.id);
42308
42503
  if (prev && prev !== trait.currentState) {
@@ -42471,10 +42666,10 @@ function VerifyModePanel({
42471
42666
  localCount
42472
42667
  }) {
42473
42668
  const { t } = useTranslate();
42474
- const [expanded, setExpanded] = React90.useState(true);
42475
- const scrollRef = React90.useRef(null);
42476
- const prevCountRef = React90.useRef(0);
42477
- React90.useEffect(() => {
42669
+ const [expanded, setExpanded] = React91.useState(true);
42670
+ const scrollRef = React91.useRef(null);
42671
+ const prevCountRef = React91.useRef(0);
42672
+ React91.useEffect(() => {
42478
42673
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
42479
42674
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
42480
42675
  }
@@ -42531,10 +42726,10 @@ function RuntimeDebugger({
42531
42726
  schema
42532
42727
  }) {
42533
42728
  const { t } = useTranslate();
42534
- const [isCollapsed, setIsCollapsed] = React90.useState(mode === "verify" ? true : defaultCollapsed);
42535
- const [isVisible, setIsVisible] = React90.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
42729
+ const [isCollapsed, setIsCollapsed] = React91.useState(mode === "verify" ? true : defaultCollapsed);
42730
+ const [isVisible, setIsVisible] = React91.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
42536
42731
  const debugData = useDebugData();
42537
- React90.useEffect(() => {
42732
+ React91.useEffect(() => {
42538
42733
  if (mode === "inline") return;
42539
42734
  return onDebugToggle((enabled) => {
42540
42735
  setIsVisible(enabled);
@@ -42543,7 +42738,7 @@ function RuntimeDebugger({
42543
42738
  }
42544
42739
  });
42545
42740
  }, [mode]);
42546
- React90.useEffect(() => {
42741
+ React91.useEffect(() => {
42547
42742
  if (mode === "inline") return;
42548
42743
  const handleKeyDown = (e) => {
42549
42744
  if (e.key === "`" && isVisible) {
@@ -43063,7 +43258,7 @@ var init_StatCard = __esm({
43063
43258
  const labelToUse = propLabel ?? propTitle;
43064
43259
  const eventBus = useEventBus();
43065
43260
  const { t } = useTranslate();
43066
- const handleActionClick = React90__default.useCallback(() => {
43261
+ const handleActionClick = React91__default.useCallback(() => {
43067
43262
  if (action?.event) {
43068
43263
  eventBus.emit(`UI:${action.event}`, {});
43069
43264
  }
@@ -43074,7 +43269,7 @@ var init_StatCard = __esm({
43074
43269
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
43075
43270
  const isLoading = externalLoading ?? false;
43076
43271
  const error = externalError;
43077
- const computeMetricValue = React90__default.useCallback(
43272
+ const computeMetricValue = React91__default.useCallback(
43078
43273
  (metric, items) => {
43079
43274
  if (metric.value !== void 0) {
43080
43275
  return metric.value;
@@ -43113,7 +43308,7 @@ var init_StatCard = __esm({
43113
43308
  },
43114
43309
  []
43115
43310
  );
43116
- const schemaStats = React90__default.useMemo(() => {
43311
+ const schemaStats = React91__default.useMemo(() => {
43117
43312
  if (!metrics || metrics.length === 0) return null;
43118
43313
  return metrics.map((metric) => ({
43119
43314
  label: metric.label,
@@ -43121,7 +43316,7 @@ var init_StatCard = __esm({
43121
43316
  format: metric.format
43122
43317
  }));
43123
43318
  }, [metrics, data, computeMetricValue]);
43124
- const calculatedTrend = React90__default.useMemo(() => {
43319
+ const calculatedTrend = React91__default.useMemo(() => {
43125
43320
  if (manualTrend !== void 0) return manualTrend;
43126
43321
  if (previousValue === void 0 || currentValue === void 0)
43127
43322
  return void 0;
@@ -43761,8 +43956,8 @@ var init_SubagentTracePanel = __esm({
43761
43956
  ] });
43762
43957
  };
43763
43958
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
43764
- const endRef = React90__default.useRef(null);
43765
- React90__default.useEffect(() => {
43959
+ const endRef = React91__default.useRef(null);
43960
+ React91__default.useEffect(() => {
43766
43961
  if (!autoScroll) return;
43767
43962
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
43768
43963
  }, [activities.length, autoScroll]);
@@ -43856,7 +44051,7 @@ var init_SubagentTracePanel = __esm({
43856
44051
  };
43857
44052
  SubagentRichCard = ({ subagent }) => {
43858
44053
  const { t } = useTranslate();
43859
- const activities = React90__default.useMemo(
44054
+ const activities = React91__default.useMemo(
43860
44055
  () => subagentMessagesToActivities(subagent.messages),
43861
44056
  [subagent.messages]
43862
44057
  );
@@ -43933,8 +44128,8 @@ var init_SubagentTracePanel = __esm({
43933
44128
  ] });
43934
44129
  };
43935
44130
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
43936
- const endRef = React90__default.useRef(null);
43937
- React90__default.useEffect(() => {
44131
+ const endRef = React91__default.useRef(null);
44132
+ React91__default.useEffect(() => {
43938
44133
  if (!autoScroll) return;
43939
44134
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
43940
44135
  }, [messages.length, autoScroll]);
@@ -44313,6 +44508,11 @@ var init_TeamOrganism = __esm({
44313
44508
  TeamOrganism.displayName = "TeamOrganism";
44314
44509
  }
44315
44510
  });
44511
+ function formatDate4(value) {
44512
+ const d = new Date(value);
44513
+ if (isNaN(d.getTime())) return value;
44514
+ return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
44515
+ }
44316
44516
  var lookStyles10, STATUS_STYLES2, Timeline;
44317
44517
  var init_Timeline = __esm({
44318
44518
  "components/core/organisms/Timeline.tsx"() {
@@ -44364,7 +44564,7 @@ var init_Timeline = __esm({
44364
44564
  }) => {
44365
44565
  const { t } = useTranslate();
44366
44566
  const entityData = entity ?? [];
44367
- const items = React90__default.useMemo(() => {
44567
+ const items = React91__default.useMemo(() => {
44368
44568
  if (propItems) return propItems;
44369
44569
  if (entityData.length === 0) return [];
44370
44570
  return entityData.map((record, idx) => {
@@ -44440,7 +44640,7 @@ var init_Timeline = __esm({
44440
44640
  /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
44441
44641
  /* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
44442
44642
  /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
44443
- item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: item.date })
44643
+ item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: formatDate4(item.date) })
44444
44644
  ] }),
44445
44645
  item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
44446
44646
  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)) }),
@@ -44466,7 +44666,7 @@ var init_Timeline = __esm({
44466
44666
  }
44467
44667
  });
44468
44668
  function extractToastProps(children) {
44469
- if (!React90__default.isValidElement(children)) {
44669
+ if (!React91__default.isValidElement(children)) {
44470
44670
  if (typeof children === "string") {
44471
44671
  return { message: children };
44472
44672
  }
@@ -44508,7 +44708,7 @@ var init_ToastSlot = __esm({
44508
44708
  eventBus.emit(`${prefix}CLOSE`);
44509
44709
  };
44510
44710
  if (!isVisible) return null;
44511
- const isCustomContent = React90__default.isValidElement(children) && !message;
44711
+ const isCustomContent = React91__default.isValidElement(children) && !message;
44512
44712
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
44513
44713
  Toast,
44514
44714
  {
@@ -44556,6 +44756,7 @@ var init_component_registry_generated = __esm({
44556
44756
  init_LayoutPatterns();
44557
44757
  init_BranchingLogicBuilder();
44558
44758
  init_Breadcrumb();
44759
+ init_ButtonGroup();
44559
44760
  init_CTABanner();
44560
44761
  init_CalendarGrid();
44561
44762
  init_Canvas();
@@ -44626,8 +44827,8 @@ var init_component_registry_generated = __esm({
44626
44827
  init_FlipContainer();
44627
44828
  init_FloatingActionButton();
44628
44829
  init_Form();
44629
- init_FormSection();
44630
44830
  init_FormField();
44831
+ init_FormSection();
44631
44832
  init_FormSectionHeader();
44632
44833
  init_GameAudioToggle();
44633
44834
  init_GameHud();
@@ -44813,6 +45014,7 @@ var init_component_registry_generated = __esm({
44813
45014
  "BranchingLogicBuilder": BranchingLogicBuilder,
44814
45015
  "Breadcrumb": Breadcrumb,
44815
45016
  "Button": ButtonPattern,
45017
+ "ButtonGroup": ButtonGroup,
44816
45018
  "ButtonPattern": ButtonPattern,
44817
45019
  "CTABanner": CTABanner,
44818
45020
  "CalendarGrid": CalendarGrid,
@@ -44886,7 +45088,6 @@ var init_component_registry_generated = __esm({
44886
45088
  "FlipContainer": FlipContainer,
44887
45089
  "FloatingActionButton": FloatingActionButton,
44888
45090
  "Form": Form,
44889
- "FormActions": FormActions,
44890
45091
  "FormField": FormField,
44891
45092
  "FormLayout": FormLayout,
44892
45093
  "FormSectionHeader": FormSectionHeader,
@@ -45066,7 +45267,7 @@ function SuspenseConfigProvider({
45066
45267
  config,
45067
45268
  children
45068
45269
  }) {
45069
- return React90__default.createElement(
45270
+ return React91__default.createElement(
45070
45271
  SuspenseConfigContext.Provider,
45071
45272
  { value: config },
45072
45273
  children
@@ -45108,7 +45309,7 @@ function enrichFormFields(fields, entityDef) {
45108
45309
  }
45109
45310
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
45110
45311
  }
45111
- if (field && typeof field === "object" && !Array.isArray(field) && !React90__default.isValidElement(field) && !(field instanceof Date)) {
45312
+ if (field && typeof field === "object" && !Array.isArray(field) && !React91__default.isValidElement(field) && !(field instanceof Date)) {
45112
45313
  const obj = field;
45113
45314
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
45114
45315
  if (!fieldName) return field;
@@ -45561,7 +45762,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
45561
45762
  const key = `${parentId}-${index}-trait:${traitName}`;
45562
45763
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
45563
45764
  }
45564
- return /* @__PURE__ */ jsx(React90__default.Fragment, { children: child }, `${parentId}-${index}`);
45765
+ return /* @__PURE__ */ jsx(React91__default.Fragment, { children: child }, `${parentId}-${index}`);
45565
45766
  }
45566
45767
  if (!child || typeof child !== "object") return null;
45567
45768
  const childId = `${parentId}-${index}`;
@@ -45614,14 +45815,14 @@ function isPatternConfig(value) {
45614
45815
  if (value === null || value === void 0) return false;
45615
45816
  if (typeof value !== "object") return false;
45616
45817
  if (Array.isArray(value)) return false;
45617
- if (React90__default.isValidElement(value)) return false;
45818
+ if (React91__default.isValidElement(value)) return false;
45618
45819
  if (value instanceof Date) return false;
45619
45820
  if (typeof value === "function") return false;
45620
45821
  const record = value;
45621
45822
  return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
45622
45823
  }
45623
45824
  function isPlainConfigObject(value) {
45624
- if (React90__default.isValidElement(value)) return false;
45825
+ if (React91__default.isValidElement(value)) return false;
45625
45826
  if (value instanceof Date) return false;
45626
45827
  const proto = Object.getPrototypeOf(value);
45627
45828
  return proto === Object.prototype || proto === null;
@@ -45652,7 +45853,7 @@ function substituteTraitRefsDeep(value, pathKey) {
45652
45853
  }
45653
45854
  return value;
45654
45855
  }
45655
- function renderPatternProps(props, onDismiss) {
45856
+ function renderPatternProps(props, onDismiss, propsSchema) {
45656
45857
  const rendered = {};
45657
45858
  for (const [key, value] of Object.entries(props)) {
45658
45859
  if (key === "children") {
@@ -45670,9 +45871,10 @@ function renderPatternProps(props, onDismiss) {
45670
45871
  };
45671
45872
  rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
45672
45873
  } else if (Array.isArray(value)) {
45874
+ const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
45673
45875
  rendered[key] = value.map((item, i) => {
45674
45876
  const el = item;
45675
- if (isPatternConfig(el)) {
45877
+ if (!isDataArray && isPatternConfig(el)) {
45676
45878
  const nestedProps = {};
45677
45879
  for (const [k, v] of Object.entries(el)) {
45678
45880
  if (k !== "type") nestedProps[k] = v;
@@ -45748,7 +45950,7 @@ function SlotContentRenderer({
45748
45950
  for (const slotKey of CONTENT_NODE_SLOTS) {
45749
45951
  const slotVal = restProps[slotKey];
45750
45952
  if (slotVal === void 0 || slotVal === null) continue;
45751
- if (React90__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
45953
+ if (React91__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
45752
45954
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
45753
45955
  nodeSlotOverrides[slotKey] = renderPatternChildren(
45754
45956
  slotVal,
@@ -45760,14 +45962,15 @@ function SlotContentRenderer({
45760
45962
  );
45761
45963
  }
45762
45964
  }
45763
- const renderedProps = renderPatternProps(restProps, onDismiss);
45764
45965
  const patternDef = getPatternDefinition(content.pattern);
45765
45966
  const propsSchema = patternDef?.propsSchema;
45967
+ const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
45766
45968
  if (propsSchema) {
45767
45969
  for (const [propKey, propValue] of Object.entries(renderedProps)) {
45768
45970
  if (typeof propValue !== "string") continue;
45769
45971
  const propDef = propsSchema[propKey];
45770
45972
  if (!propDef || propDef.kind !== "callback") continue;
45973
+ if (propValue === "") continue;
45771
45974
  renderedProps[propKey] = wrapCallbackForEvent(
45772
45975
  `UI:${propValue}`,
45773
45976
  propDef.callbackArgs,
@@ -45800,7 +46003,7 @@ function SlotContentRenderer({
45800
46003
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
45801
46004
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
45802
46005
  const sample = resolvedItems[0];
45803
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React90__default.isValidElement(sample) && !(sample instanceof Date)) {
46006
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React91__default.isValidElement(sample) && !(sample instanceof Date)) {
45804
46007
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
45805
46008
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
45806
46009
  }
@@ -46165,7 +46368,7 @@ var AvlTransition = ({
46165
46368
  opacity = 1,
46166
46369
  className
46167
46370
  }) => {
46168
- const ids = React90__default.useMemo(() => {
46371
+ const ids = React91__default.useMemo(() => {
46169
46372
  avlTransitionId += 1;
46170
46373
  return { arrow: `avl-tr-${avlTransitionId}-arrow` };
46171
46374
  }, []);
@@ -46726,7 +46929,7 @@ var AvlStateMachine = ({
46726
46929
  color = "var(--color-primary)",
46727
46930
  animated = false
46728
46931
  }) => {
46729
- const ids = React90__default.useMemo(() => {
46932
+ const ids = React91__default.useMemo(() => {
46730
46933
  avlSmId += 1;
46731
46934
  const base = `avl-sm-${avlSmId}`;
46732
46935
  return { glow: `${base}-glow`, grad: `${base}-grad` };
@@ -46925,7 +47128,7 @@ var AvlOrbitalUnit = ({
46925
47128
  color = "var(--color-primary)",
46926
47129
  animated = false
46927
47130
  }) => {
46928
- const ids = React90__default.useMemo(() => {
47131
+ const ids = React91__default.useMemo(() => {
46929
47132
  avlOuId += 1;
46930
47133
  const base = `avl-ou-${avlOuId}`;
46931
47134
  return { glow: `${base}-glow`, grad: `${base}-grad` };
@@ -47021,7 +47224,7 @@ var AvlClosedCircuit = ({
47021
47224
  color = "var(--color-primary)",
47022
47225
  animated = false
47023
47226
  }) => {
47024
- const ids = React90__default.useMemo(() => {
47227
+ const ids = React91__default.useMemo(() => {
47025
47228
  avlCcId += 1;
47026
47229
  const base = `avl-cc-${avlCcId}`;
47027
47230
  return { glow: `${base}-glow`, grad: `${base}-grad`, arrow: `${base}-arrow` };
@@ -47176,7 +47379,7 @@ var AvlEmitListen = ({
47176
47379
  color = "var(--color-primary)",
47177
47380
  animated = false
47178
47381
  }) => {
47179
- const ids = React90__default.useMemo(() => {
47382
+ const ids = React91__default.useMemo(() => {
47180
47383
  avlElId += 1;
47181
47384
  const base = `avl-el-${avlElId}`;
47182
47385
  return { arrow: `${base}-arrow`, grad: `${base}-grad` };
@@ -47450,7 +47653,7 @@ function renderNode(node, color, glowId) {
47450
47653
  const baseR = node.type === "operator" ? 20 : 16;
47451
47654
  const r2 = Math.max(baseR, labelLen * 3.5 + 6);
47452
47655
  const nc = nodeColor(node.type, color);
47453
- return /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
47656
+ return /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
47454
47657
  node.children.map((child, i) => {
47455
47658
  const childR = Math.max(
47456
47659
  child.type === "operator" ? 20 : 16,
@@ -47507,7 +47710,7 @@ var AvlExprTree = ({
47507
47710
  className,
47508
47711
  color = "var(--color-primary)"
47509
47712
  }) => {
47510
- const ids = React90__default.useMemo(() => {
47713
+ const ids = React91__default.useMemo(() => {
47511
47714
  avlEtId += 1;
47512
47715
  return { glow: `avl-et-${avlEtId}-glow` };
47513
47716
  }, []);
@@ -48342,7 +48545,7 @@ var SystemNode = ({ data }) => {
48342
48545
  stateChain.length > 0 && /* @__PURE__ */ jsx("svg", { width: stateChain.length * 14 + 2, height: 10, viewBox: `0 0 ${stateChain.length * 14 + 2} 10`, children: stateChain.map((s, i) => {
48343
48546
  const tc = transitionCounts[s.name] ?? 0;
48344
48547
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
48345
- return /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
48548
+ return /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
48346
48549
  /* @__PURE__ */ jsx(AvlState, { x: i * 14 + 1, y: 1, width: 10, height: 8, name: "", role, isInitial: s.isInitial ?? void 0, isTerminal: s.isTerminal ?? void 0 }),
48347
48550
  i < stateChain.length - 1 && /* @__PURE__ */ jsx("line", { x1: i * 14 + 12, y1: 5, x2: i * 14 + 15, y2: 5, stroke: "var(--color-border)", strokeWidth: 0.5 })
48348
48551
  ] }, s.name);
@@ -49424,7 +49627,7 @@ function resolveLambdaBindings(body, params, item, index) {
49424
49627
  }
49425
49628
  return substituted;
49426
49629
  }
49427
- if (body !== null && typeof body === "object" && !React90__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
49630
+ if (body !== null && typeof body === "object" && !React91__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
49428
49631
  const out = {};
49429
49632
  for (const [k, v] of Object.entries(body)) {
49430
49633
  out[k] = recur(v);
@@ -49443,7 +49646,7 @@ function getSlotContentRenderer2() {
49443
49646
  function makeLambdaFn(params, lambdaBody, callerKey) {
49444
49647
  return (item, index) => {
49445
49648
  const resolvedBody = resolveLambdaBindings(lambdaBody, params, item, index);
49446
- if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React90__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
49649
+ if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React91__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
49447
49650
  return null;
49448
49651
  }
49449
49652
  const record = resolvedBody;
@@ -49462,7 +49665,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
49462
49665
  props: childProps,
49463
49666
  priority: 0
49464
49667
  };
49465
- return React90__default.createElement(SlotContentRenderer2, { content: childContent });
49668
+ return React91__default.createElement(SlotContentRenderer2, { content: childContent });
49466
49669
  };
49467
49670
  }
49468
49671
  function convertNode(node, callerKey) {
@@ -49481,7 +49684,7 @@ function convertNode(node, callerKey) {
49481
49684
  });
49482
49685
  return anyChanged ? mapped : node;
49483
49686
  }
49484
- if (typeof node === "object" && !React90__default.isValidElement(node) && !(node instanceof Date)) {
49687
+ if (typeof node === "object" && !React91__default.isValidElement(node) && !(node instanceof Date)) {
49485
49688
  return convertObjectProps(node);
49486
49689
  }
49487
49690
  return node;
@@ -49562,6 +49765,7 @@ function useSharedEntityStore() {
49562
49765
  }
49563
49766
  return storeRef.current;
49564
49767
  }
49768
+ createContext(null);
49565
49769
  function runTickFrame(entityId, orderedWriters, store) {
49566
49770
  let scratch = store.getSnapshot(entityId);
49567
49771
  for (const writer of orderedWriters) {
@@ -49659,6 +49863,11 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
49659
49863
  "do",
49660
49864
  "when"
49661
49865
  ]);
49866
+ var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
49867
+ "canvas",
49868
+ "game-hud",
49869
+ "game-shell"
49870
+ ]);
49662
49871
  var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
49663
49872
  function toTraitDefinition(binding) {
49664
49873
  return {
@@ -49911,6 +50120,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
49911
50120
  }, [traitStates]);
49912
50121
  const traitSnapshotDataRef = useRef(/* @__PURE__ */ new Map());
49913
50122
  const traitFieldStatesRef = useRef(/* @__PURE__ */ new Map());
50123
+ const lastCanvasRenderUiRef = useRef(/* @__PURE__ */ new Map());
50124
+ const executeTransitionEffectsRef = useRef(null);
49914
50125
  useEffect(() => {
49915
50126
  const mgr = managerRef.current;
49916
50127
  const bindings = traitBindingsRef.current;
@@ -49951,11 +50162,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
49951
50162
  bindTraitStateGetter((traitName) => {
49952
50163
  const allStates = newManager.getAllStates();
49953
50164
  if (allStates instanceof Map) {
49954
- const val = allStates.get(traitName);
49955
- return typeof val === "string" ? val : void 0;
50165
+ return allStates.get(traitName)?.currentState;
49956
50166
  }
49957
- const state = newManager.getState(traitName);
49958
- return typeof state === "string" ? state : void 0;
50167
+ return newManager.getState(traitName)?.currentState;
49959
50168
  });
49960
50169
  const snapshotUnregs = [];
49961
50170
  for (const binding of traitBindingsRef.current) {
@@ -50040,6 +50249,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50040
50249
  const existing = pendingSlots.get(slot) || [];
50041
50250
  existing.push({ pattern, props: props || {} });
50042
50251
  pendingSlots.set(slot, existing);
50252
+ const patternType = pattern?.type;
50253
+ if (patternType !== void 0 && REACTIVE_REPAINT_PATTERN_TYPES.has(patternType)) {
50254
+ const rawForSlot = effects.filter(
50255
+ (e) => Array.isArray(e) && (e[0] === "render-ui" || e[0] === "render") && e[1] === slot
50256
+ );
50257
+ if (rawForSlot.length > 0) {
50258
+ lastCanvasRenderUiRef.current.set(traitName, rawForSlot);
50259
+ }
50260
+ }
50043
50261
  },
50044
50262
  clearSlot: (slot) => {
50045
50263
  pendingSlots.set(slot, []);
@@ -50110,11 +50328,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50110
50328
  notify: clientHandlers.notify
50111
50329
  };
50112
50330
  }
50331
+ const sharedWrites = [];
50113
50332
  const baseSet = handlers.set;
50114
50333
  handlers = {
50115
50334
  ...handlers,
50116
50335
  set: async (targetId, field, value) => {
50117
50336
  if (baseSet) await baseSet(targetId, field, value);
50337
+ if (sharedKey !== void 0) {
50338
+ sharedWrites.push({ field, value });
50339
+ }
50118
50340
  log11.debug("set:write", {
50119
50341
  traitName,
50120
50342
  field,
@@ -50190,7 +50412,10 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50190
50412
  });
50191
50413
  }
50192
50414
  if (sharedKey !== void 0) {
50193
- sharedEntityStore.commit(sharedKey, liveEntity);
50415
+ sharedEntityStore.commit(
50416
+ sharedKey,
50417
+ mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
50418
+ );
50194
50419
  }
50195
50420
  log11.debug("effects:executed", () => ({
50196
50421
  traitName,
@@ -50216,6 +50441,38 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50216
50441
  entity: binding.linkedEntity
50217
50442
  });
50218
50443
  }
50444
+ if (pendingSlots.size === 0 && effectsCallOp(effects, SHARED_ENTITY_WRITE_OPS)) {
50445
+ const stashed = lastCanvasRenderUiRef.current.get(traitName);
50446
+ if (stashed !== void 0 && stashed.length > 0) {
50447
+ await executor.executeAll(stashed);
50448
+ for (const [slot, patterns] of pendingSlots) {
50449
+ flushSlot(traitName, slot, patterns, {
50450
+ event: flushEvent,
50451
+ state: previousState,
50452
+ entity: binding.linkedEntity
50453
+ });
50454
+ }
50455
+ }
50456
+ if (sharedKey !== void 0 && executeTransitionEffectsRef.current !== null) {
50457
+ for (const sibling of traitBindingsRef.current) {
50458
+ const siblingName = sibling.trait.name;
50459
+ if (siblingName === traitName) continue;
50460
+ if (sharedKeyByTraitNameRef.current.get(siblingName) !== sharedKey) continue;
50461
+ const siblingStash = lastCanvasRenderUiRef.current.get(siblingName);
50462
+ if (siblingStash === void 0 || siblingStash.length === 0) continue;
50463
+ const siblingState = traitStatesRef.current.get(siblingName)?.currentState ?? "";
50464
+ await executeTransitionEffectsRef.current({
50465
+ binding: sibling,
50466
+ effects: siblingStash,
50467
+ previousState: siblingState,
50468
+ newState: siblingState,
50469
+ flushEvent: `${flushEvent}:repaint`,
50470
+ syncOnly,
50471
+ log: log11
50472
+ });
50473
+ }
50474
+ }
50475
+ }
50219
50476
  } catch (error) {
50220
50477
  log11.error("effects:error", {
50221
50478
  traitName,
@@ -50227,6 +50484,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50227
50484
  }
50228
50485
  return emittedDuringExec;
50229
50486
  }, [eventBus, flushSlot, sharedEntityStore]);
50487
+ useEffect(() => {
50488
+ executeTransitionEffectsRef.current = executeTransitionEffects;
50489
+ }, [executeTransitionEffects]);
50230
50490
  const runTickEffects = useCallback((tick, binding) => {
50231
50491
  const traitName = binding.trait.name;
50232
50492
  const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
@@ -50289,6 +50549,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50289
50549
  ({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
50290
50550
  );
50291
50551
  runTickFrame(group.storeKey, writers, sharedEntityStore);
50552
+ const repaint = executeTransitionEffectsRef.current;
50553
+ if (repaint !== null) {
50554
+ for (const renderBinding of group.renderBindings) {
50555
+ const renderTraitName = renderBinding.trait.name;
50556
+ const stash = lastCanvasRenderUiRef.current.get(renderTraitName);
50557
+ if (stash === void 0 || stash.length === 0) continue;
50558
+ const renderState = traitStatesRef.current.get(renderTraitName)?.currentState ?? "";
50559
+ void repaint({
50560
+ binding: renderBinding,
50561
+ effects: stash,
50562
+ previousState: renderState,
50563
+ newState: renderState,
50564
+ flushEvent: "tick:repaint",
50565
+ syncOnly: true,
50566
+ log: sharedEntityLog
50567
+ });
50568
+ }
50569
+ }
50292
50570
  };
50293
50571
  if (interval === "frame") {
50294
50572
  scheduler.add(0, onDue);
@@ -50338,6 +50616,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50338
50616
  entityByTrait[name] = fields;
50339
50617
  }
50340
50618
  }
50619
+ for (const binding of bindings) {
50620
+ const name = binding.trait.name;
50621
+ const sharedKey = sharedKeyByTraitNameRef.current.get(name);
50622
+ if (sharedKey !== void 0) {
50623
+ entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
50624
+ }
50625
+ }
50341
50626
  const results = currentManager.sendEvent(
50342
50627
  normalizedEvent,
50343
50628
  payload,
@@ -50491,7 +50776,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50491
50776
  }
50492
50777
  await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
50493
50778
  }
50494
- }, [entities, eventBus]);
50779
+ }, [entities, eventBus, sharedEntityStore]);
50495
50780
  const drainEventQueue = useCallback(async () => {
50496
50781
  if (processingRef.current) return;
50497
50782
  processingRef.current = true;
@@ -50561,6 +50846,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50561
50846
  });
50562
50847
  }
50563
50848
  }
50849
+ const bareCascadeKeys = /* @__PURE__ */ new Set();
50850
+ for (const binding of traitBindings) {
50851
+ for (const transition of binding.trait.transitions) {
50852
+ const eventKey = transition.event;
50853
+ if (LIFECYCLE_EVENTS.includes(eventKey)) continue;
50854
+ if (bareCascadeKeys.has(eventKey)) continue;
50855
+ bareCascadeKeys.add(eventKey);
50856
+ const bareKey = `UI:${eventKey}`;
50857
+ const unsub = eventBus.on(bareKey, (event) => {
50858
+ crossTraitLog.debug("bare-cascade:fire", { bareKey, eventKey });
50859
+ enqueueAndDrain(eventKey, event.payload);
50860
+ });
50861
+ unsubscribes.push(() => {
50862
+ crossTraitLog.debug("bare-cascade:unsubscribe", { bareKey, eventKey });
50863
+ unsub();
50864
+ });
50865
+ }
50866
+ }
50564
50867
  for (const binding of traitBindings) {
50565
50868
  const ownOrbital = orbitalsByTrait?.[binding.trait.name];
50566
50869
  const listens = binding.trait.listens ?? [];
@@ -50644,9 +50947,16 @@ function normalizeChild(child) {
50644
50947
  props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
50645
50948
  };
50646
50949
  }
50647
- function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
50950
+ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
50648
50951
  for (const eff of effects) {
50649
50952
  if (eff.type === "render-ui" && eff.slot && eff.pattern) {
50953
+ if (eff.traitName && activeTraits && !activeTraits.has(eff.traitName)) {
50954
+ xOrbitalLog.debug("slot:off-page-trait-skipped", {
50955
+ sourceTrait: eff.traitName,
50956
+ slot: eff.slot
50957
+ });
50958
+ continue;
50959
+ }
50650
50960
  const patternRecord = eff.pattern;
50651
50961
  const { type: patternType, children, ...inlineProps } = patternRecord;
50652
50962
  const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
@@ -50687,8 +50997,38 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
50687
50997
  }
50688
50998
  }
50689
50999
  }
50690
- function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
51000
+ function collectServerActiveTraits(ir, allTraits, mountedTraitNames) {
51001
+ if (!ir?.pages || ir.pages.size <= 1) return void 0;
51002
+ const pageBound = /* @__PURE__ */ new Set();
51003
+ for (const page of ir.pages.values()) {
51004
+ const queue = page.traits.map((b) => b.trait.name).filter((n) => !!n);
51005
+ for (const name of queue) {
51006
+ if (pageBound.has(name)) continue;
51007
+ pageBound.add(name);
51008
+ const rt = allTraits.get(name);
51009
+ if (!rt) continue;
51010
+ queue.push(...collectTraitRefsFromResolvedTrait(rt));
51011
+ }
51012
+ }
51013
+ const active = new Set(mountedTraitNames);
51014
+ for (const name of allTraits.keys()) {
51015
+ if (!pageBound.has(name)) active.add(name);
51016
+ }
51017
+ return active;
51018
+ }
51019
+ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits }) {
50691
51020
  const bridge = useServerBridge();
51021
+ const activeTraitNames = useMemo(
51022
+ () => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
51023
+ [traits2]
51024
+ );
51025
+ const withActiveTraits = useCallback(
51026
+ (payload) => {
51027
+ if (!serverActiveTraits || serverActiveTraits.size === 0) return payload;
51028
+ return { ...payload ?? {}, _activeTraits: Array.from(serverActiveTraits) };
51029
+ },
51030
+ [serverActiveTraits]
51031
+ );
50692
51032
  const uiSlots = useUISlots();
50693
51033
  const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
50694
51034
  if (!bridge.connected || !orbitalNames?.length) return;
@@ -50700,11 +51040,11 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
50700
51040
  dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
50701
51041
  }));
50702
51042
  for (const name of targets) {
50703
- const { effects, meta } = await bridge.sendEvent(name, event, payload);
51043
+ const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
50704
51044
  recordServerResponse(name, event, meta);
50705
- applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
51045
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
50706
51046
  }
50707
- }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
51047
+ }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
50708
51048
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
50709
51049
  const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
50710
51050
  const initSentRef = useRef(false);
@@ -50741,7 +51081,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
50741
51081
  initSentRef.current = true;
50742
51082
  (async () => {
50743
51083
  for (const name of orbitalNames) {
50744
- const { effects, meta } = await bridge.sendEvent(name, "INIT", {});
51084
+ const { effects, meta } = await bridge.sendEvent(name, "INIT", withActiveTraits({}));
50745
51085
  recordServerResponse(name, "INIT", meta);
50746
51086
  const effectTraces = [
50747
51087
  { type: "fetch", args: [], status: "executed" },
@@ -50759,10 +51099,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
50759
51099
  effects: effectTraces,
50760
51100
  timestamp: Date.now()
50761
51101
  });
50762
- applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
51102
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
50763
51103
  }
50764
51104
  })();
50765
- }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
51105
+ }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
50766
51106
  return null;
50767
51107
  }
50768
51108
  function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
@@ -50849,6 +51189,14 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
50849
51189
  }
50850
51190
  return Array.from(set);
50851
51191
  }, [allPageTraits, orbitalsByTrait]);
51192
+ const serverActiveTraits = useMemo(
51193
+ () => collectServerActiveTraits(
51194
+ ir,
51195
+ allTraits,
51196
+ new Set(allPageTraits.map((b) => b.trait.name).filter((n) => !!n))
51197
+ ),
51198
+ [ir, allTraits, allPageTraits]
51199
+ );
50852
51200
  useEffect(() => {
50853
51201
  const traitNames = allPageTraits.map((b) => b.trait.name);
50854
51202
  const orbitalsByTraitForPage = {};
@@ -50858,7 +51206,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
50858
51206
  }
50859
51207
  xOrbitalLog.info("SchemaRunner:mount", {
50860
51208
  pageName,
50861
- traitNames,
51209
+ traitNames: traitNames.join(","),
50862
51210
  orbitalsByTraitForPage,
50863
51211
  pageOrbitalNames: pageOrbitalNames.join(",")
50864
51212
  });
@@ -50903,6 +51251,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
50903
51251
  traitConfigsByName,
50904
51252
  orbitalsByTrait,
50905
51253
  embeddedTraits,
51254
+ serverActiveTraits,
50906
51255
  onNavigate,
50907
51256
  onLocalFallback,
50908
51257
  persistence
@@ -51208,8 +51557,8 @@ function CanvasDndProvider({
51208
51557
  }) {
51209
51558
  const eventBus = useEventBus();
51210
51559
  const sensors = useAlmadarDndSensors(false);
51211
- const [activePayload, setActivePayload] = React90__default.useState(null);
51212
- const handleDragStart = React90__default.useCallback((e) => {
51560
+ const [activePayload, setActivePayload] = React91__default.useState(null);
51561
+ const handleDragStart = React91__default.useCallback((e) => {
51213
51562
  const data = e.active.data.current;
51214
51563
  const payload = data?.payload;
51215
51564
  if (payload) {
@@ -51220,7 +51569,7 @@ function CanvasDndProvider({
51220
51569
  log9.warn("dragStart:missing-payload", { id: e.active.id });
51221
51570
  }
51222
51571
  }, [eventBus]);
51223
- const handleDragEnd = React90__default.useCallback((e) => {
51572
+ const handleDragEnd = React91__default.useCallback((e) => {
51224
51573
  setActivePayload(null);
51225
51574
  const activeData = e.active.data.current;
51226
51575
  const payload = activeData?.payload;
@@ -51249,7 +51598,7 @@ function CanvasDndProvider({
51249
51598
  const suppressed = onDrop ? onDrop(drop) === true : false;
51250
51599
  if (!suppressed) defaultEmit(eventBus, drop);
51251
51600
  }, [eventBus, onDrop]);
51252
- const handleDragCancel = React90__default.useCallback(() => {
51601
+ const handleDragCancel = React91__default.useCallback(() => {
51253
51602
  setActivePayload(null);
51254
51603
  log9.info("dragCancel");
51255
51604
  }, []);
@@ -52007,7 +52356,7 @@ var OrbPreviewNodeInner = (props) => {
52007
52356
  }
52008
52357
  );
52009
52358
  };
52010
- var OrbPreviewNode = React90__default.memo(OrbPreviewNodeInner);
52359
+ var OrbPreviewNode = React91__default.memo(OrbPreviewNodeInner);
52011
52360
  OrbPreviewNode.displayName = "OrbPreviewNode";
52012
52361
  orbPreviewLog.debug("export-resolved", () => ({
52013
52362
  type: typeof OrbPreviewNode,
@@ -52112,7 +52461,7 @@ var EventFlowEdgeInner = (props) => {
52112
52461
  ) })
52113
52462
  ] });
52114
52463
  };
52115
- var EventFlowEdge = React90__default.memo(EventFlowEdgeInner);
52464
+ var EventFlowEdge = React91__default.memo(EventFlowEdgeInner);
52116
52465
  EventFlowEdge.displayName = "EventFlowEdge";
52117
52466
 
52118
52467
  // components/avl/molecules/BehaviorComposeNode.tsx
@@ -52259,7 +52608,7 @@ var BehaviorComposeNodeInner = (props) => {
52259
52608
  }
52260
52609
  );
52261
52610
  };
52262
- var BehaviorComposeNode = React90__default.memo(BehaviorComposeNodeInner);
52611
+ var BehaviorComposeNode = React91__default.memo(BehaviorComposeNodeInner);
52263
52612
  BehaviorComposeNode.displayName = "BehaviorComposeNode";
52264
52613
 
52265
52614
  // components/avl/lib/avl-behavior-compose-converter.ts
@@ -53285,7 +53634,7 @@ var TraitCardNodeInner = (props) => {
53285
53634
  }
53286
53635
  );
53287
53636
  };
53288
- var TraitCardNode = React90__default.memo(TraitCardNodeInner);
53637
+ var TraitCardNode = React91__default.memo(TraitCardNodeInner);
53289
53638
  TraitCardNode.displayName = "TraitCardNode";
53290
53639
 
53291
53640
  // components/avl/organisms/FlowCanvas.tsx
@@ -53366,7 +53715,7 @@ function FlowCanvasInner({
53366
53715
  initialOrbital
53367
53716
  );
53368
53717
  const [expandedBehaviorAlias, setExpandedBehaviorAlias] = useState(void 0);
53369
- const screenSizeUserOverrideRef = React90__default.useRef(false);
53718
+ const screenSizeUserOverrideRef = React91__default.useRef(false);
53370
53719
  const [screenSize, setScreenSize] = useState(
53371
53720
  () => typeof window === "undefined" ? "laptop" : detectScreenSize(window.innerWidth)
53372
53721
  );
@@ -53750,7 +54099,7 @@ var ZoomBreadcrumb = ({
53750
54099
  if (eventName && band === "detail") {
53751
54100
  segments.push({ icon: "\u26A1", label: eventName });
53752
54101
  }
53753
- return /* @__PURE__ */ jsx("div", { className: "absolute top-2 left-2 z-10 flex items-center gap-1 px-2 py-1 rounded-md bg-card/90 border border-border text-xs text-muted-foreground backdrop-blur-sm", children: segments.map((seg, i) => /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
54102
+ return /* @__PURE__ */ jsx("div", { className: "absolute top-2 left-2 z-10 flex items-center gap-1 px-2 py-1 rounded-md bg-card/90 border border-border text-xs text-muted-foreground backdrop-blur-sm", children: segments.map((seg, i) => /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
53754
54103
  i > 0 && /* @__PURE__ */ jsx("span", { className: "opacity-40", children: ">" }),
53755
54104
  /* @__PURE__ */ jsx("span", { className: "opacity-60", children: seg.icon }),
53756
54105
  /* @__PURE__ */ jsx("span", { children: seg.label })
@@ -54091,7 +54440,7 @@ var EventWireOverlay = ({
54091
54440
  containerW,
54092
54441
  containerH
54093
54442
  }) => {
54094
- const ids = React90__default.useMemo(() => {
54443
+ const ids = React91__default.useMemo(() => {
54095
54444
  avlOczWireId += 1;
54096
54445
  return { arrow: `avl-ocz-wire-${avlOczWireId}-arrow` };
54097
54446
  }, []);
@@ -54458,7 +54807,7 @@ var AvlOrbitalsCosmicZoom = ({
54458
54807
  borderRadius: 6,
54459
54808
  border: `1px solid ${color}`
54460
54809
  },
54461
- children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs(React90__default.Fragment, { children: [
54810
+ children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
54462
54811
  i > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", style: { opacity: 0.5, color }, children: "/" }),
54463
54812
  i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsx(
54464
54813
  Box,