@almadar/std 3.2.0 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/behaviors/exports/atoms/std-async.orb +41 -24
  2. package/behaviors/exports/atoms/std-browse.orb +12 -5
  3. package/behaviors/exports/atoms/std-cache-aside.orb +256 -42
  4. package/behaviors/exports/atoms/std-circuit-breaker.orb +577 -97
  5. package/behaviors/exports/atoms/std-collision.orb +278 -206
  6. package/behaviors/exports/atoms/std-combat-log.orb +6 -1
  7. package/behaviors/exports/atoms/std-combat.orb +6 -1
  8. package/behaviors/exports/atoms/std-confirmation.orb +212 -7
  9. package/behaviors/exports/atoms/std-dialogue-box.orb +6 -1
  10. package/behaviors/exports/atoms/std-display.orb +166 -21
  11. package/behaviors/exports/atoms/std-drawer.orb +208 -104
  12. package/behaviors/exports/atoms/std-filter.orb +211 -18
  13. package/behaviors/exports/atoms/std-game-audio.orb +6 -1
  14. package/behaviors/exports/atoms/std-game-canvas2d.orb +6 -1
  15. package/behaviors/exports/atoms/std-game-canvas3d.orb +6 -1
  16. package/behaviors/exports/atoms/std-game-hud.orb +6 -1
  17. package/behaviors/exports/atoms/std-game-menu.orb +6 -1
  18. package/behaviors/exports/atoms/std-game-over-screen.orb +6 -1
  19. package/behaviors/exports/atoms/std-gameflow.orb +100 -5
  20. package/behaviors/exports/atoms/std-input.orb +142 -137
  21. package/behaviors/exports/atoms/std-inventory-panel.orb +6 -1
  22. package/behaviors/exports/atoms/std-isometric-canvas.orb +6 -1
  23. package/behaviors/exports/atoms/std-loading.orb +27 -76
  24. package/behaviors/exports/atoms/std-modal.orb +177 -93
  25. package/behaviors/exports/atoms/std-movement.orb +401 -31
  26. package/behaviors/exports/atoms/std-notification.orb +46 -95
  27. package/behaviors/exports/atoms/std-overworld.orb +44 -16
  28. package/behaviors/exports/atoms/std-pagination.orb +26 -89
  29. package/behaviors/exports/atoms/std-physics2d.orb +6 -1
  30. package/behaviors/exports/atoms/std-platformer-canvas.orb +6 -1
  31. package/behaviors/exports/atoms/std-quest.orb +309 -34
  32. package/behaviors/exports/atoms/std-rate-limiter.orb +410 -157
  33. package/behaviors/exports/atoms/std-score-board.orb +6 -1
  34. package/behaviors/exports/atoms/std-score.orb +211 -11
  35. package/behaviors/exports/atoms/std-search.orb +28 -27
  36. package/behaviors/exports/atoms/std-selection.orb +160 -121
  37. package/behaviors/exports/atoms/std-simulation-canvas.orb +6 -1
  38. package/behaviors/exports/atoms/std-sort.orb +134 -24
  39. package/behaviors/exports/atoms/std-sprite.orb +6 -1
  40. package/behaviors/exports/atoms/std-tabs.orb +25 -15
  41. package/behaviors/exports/atoms/std-timer.orb +483 -91
  42. package/behaviors/exports/atoms/std-undo.orb +211 -81
  43. package/behaviors/exports/atoms/std-wizard.orb +31 -34
  44. package/behaviors/exports/molecules/std-builder-game.orb +6 -1
  45. package/behaviors/exports/molecules/std-cart.orb +6 -1
  46. package/behaviors/exports/molecules/std-classifier-game.orb +6 -1
  47. package/behaviors/exports/molecules/std-debugger-game.orb +6 -1
  48. package/behaviors/exports/molecules/std-detail.orb +12 -5
  49. package/behaviors/exports/molecules/std-event-handler-game.orb +6 -1
  50. package/behaviors/exports/molecules/std-geospatial.orb +28 -9
  51. package/behaviors/exports/molecules/std-inventory.orb +28 -9
  52. package/behaviors/exports/molecules/std-list.orb +392 -5
  53. package/behaviors/exports/molecules/std-messaging.orb +12 -5
  54. package/behaviors/exports/molecules/std-negotiator-game.orb +6 -1
  55. package/behaviors/exports/molecules/std-platformer-game.orb +40 -1
  56. package/behaviors/exports/molecules/std-puzzle-game.orb +26 -1
  57. package/behaviors/exports/molecules/std-sequencer-game.orb +6 -1
  58. package/behaviors/exports/molecules/std-simulator-game.orb +6 -1
  59. package/behaviors/exports/molecules/std-turn-based-battle.orb +40 -1
  60. package/behaviors/exports/organisms/std-api-gateway.orb +1145 -403
  61. package/behaviors/exports/organisms/std-arcade-game.orb +214 -16
  62. package/behaviors/exports/organisms/std-booking-system.orb +2165 -1605
  63. package/behaviors/exports/organisms/std-cicd-pipeline.orb +581 -47
  64. package/behaviors/exports/organisms/std-cms.orb +1713 -947
  65. package/behaviors/exports/organisms/std-coding-academy.orb +180 -380
  66. package/behaviors/exports/organisms/std-crm.orb +1669 -1153
  67. package/behaviors/exports/organisms/std-devops-dashboard.orb +1430 -378
  68. package/behaviors/exports/organisms/std-ecommerce.orb +2361 -1601
  69. package/behaviors/exports/organisms/std-finance-tracker.orb +622 -438
  70. package/behaviors/exports/organisms/std-healthcare.orb +1687 -1125
  71. package/behaviors/exports/organisms/std-helpdesk.orb +626 -407
  72. package/behaviors/exports/organisms/std-hr-portal.orb +1309 -714
  73. package/behaviors/exports/organisms/std-iot-dashboard.orb +1247 -335
  74. package/behaviors/exports/organisms/std-lms.orb +658 -362
  75. package/behaviors/exports/organisms/std-platformer-app.orb +56 -8
  76. package/behaviors/exports/organisms/std-project-manager.orb +1697 -1183
  77. package/behaviors/exports/organisms/std-puzzle-app.orb +20 -0
  78. package/behaviors/exports/organisms/std-realtime-chat.orb +552 -28
  79. package/behaviors/exports/organisms/std-rpg-game.orb +397 -56
  80. package/behaviors/exports/organisms/std-social-feed.orb +12 -8
  81. package/behaviors/exports/organisms/std-stem-lab.orb +175 -290
  82. package/behaviors/exports/organisms/std-strategy-game.orb +252 -395
  83. package/behaviors/exports/organisms/std-trading-dashboard.orb +718 -524
  84. package/behaviors/exports/validation-report.json +747 -0
  85. package/behaviors/exports/verify-results.json +13 -0
  86. package/dist/behaviors/exports/atoms/std-async.orb +41 -24
  87. package/dist/behaviors/exports/atoms/std-browse.orb +12 -5
  88. package/dist/behaviors/exports/atoms/std-cache-aside.orb +256 -42
  89. package/dist/behaviors/exports/atoms/std-circuit-breaker.orb +577 -97
  90. package/dist/behaviors/exports/atoms/std-collision.orb +278 -206
  91. package/dist/behaviors/exports/atoms/std-combat-log.orb +6 -1
  92. package/dist/behaviors/exports/atoms/std-combat.orb +6 -1
  93. package/dist/behaviors/exports/atoms/std-confirmation.orb +212 -7
  94. package/dist/behaviors/exports/atoms/std-dialogue-box.orb +6 -1
  95. package/dist/behaviors/exports/atoms/std-display.orb +166 -21
  96. package/dist/behaviors/exports/atoms/std-drawer.orb +208 -104
  97. package/dist/behaviors/exports/atoms/std-filter.orb +211 -18
  98. package/dist/behaviors/exports/atoms/std-game-audio.orb +6 -1
  99. package/dist/behaviors/exports/atoms/std-game-canvas2d.orb +6 -1
  100. package/dist/behaviors/exports/atoms/std-game-canvas3d.orb +6 -1
  101. package/dist/behaviors/exports/atoms/std-game-hud.orb +6 -1
  102. package/dist/behaviors/exports/atoms/std-game-menu.orb +6 -1
  103. package/dist/behaviors/exports/atoms/std-game-over-screen.orb +6 -1
  104. package/dist/behaviors/exports/atoms/std-gameflow.orb +100 -5
  105. package/dist/behaviors/exports/atoms/std-input.orb +142 -137
  106. package/dist/behaviors/exports/atoms/std-inventory-panel.orb +6 -1
  107. package/dist/behaviors/exports/atoms/std-isometric-canvas.orb +6 -1
  108. package/dist/behaviors/exports/atoms/std-loading.orb +27 -76
  109. package/dist/behaviors/exports/atoms/std-modal.orb +177 -93
  110. package/dist/behaviors/exports/atoms/std-movement.orb +401 -31
  111. package/dist/behaviors/exports/atoms/std-notification.orb +46 -95
  112. package/dist/behaviors/exports/atoms/std-overworld.orb +44 -16
  113. package/dist/behaviors/exports/atoms/std-pagination.orb +26 -89
  114. package/dist/behaviors/exports/atoms/std-physics2d.orb +6 -1
  115. package/dist/behaviors/exports/atoms/std-platformer-canvas.orb +6 -1
  116. package/dist/behaviors/exports/atoms/std-quest.orb +309 -34
  117. package/dist/behaviors/exports/atoms/std-rate-limiter.orb +410 -157
  118. package/dist/behaviors/exports/atoms/std-score-board.orb +6 -1
  119. package/dist/behaviors/exports/atoms/std-score.orb +211 -11
  120. package/dist/behaviors/exports/atoms/std-search.orb +28 -27
  121. package/dist/behaviors/exports/atoms/std-selection.orb +160 -121
  122. package/dist/behaviors/exports/atoms/std-simulation-canvas.orb +6 -1
  123. package/dist/behaviors/exports/atoms/std-sort.orb +134 -24
  124. package/dist/behaviors/exports/atoms/std-sprite.orb +6 -1
  125. package/dist/behaviors/exports/atoms/std-tabs.orb +25 -15
  126. package/dist/behaviors/exports/atoms/std-timer.orb +483 -91
  127. package/dist/behaviors/exports/atoms/std-undo.orb +211 -81
  128. package/dist/behaviors/exports/atoms/std-wizard.orb +31 -34
  129. package/dist/behaviors/exports/molecules/std-builder-game.orb +6 -1
  130. package/dist/behaviors/exports/molecules/std-cart.orb +6 -1
  131. package/dist/behaviors/exports/molecules/std-classifier-game.orb +6 -1
  132. package/dist/behaviors/exports/molecules/std-debugger-game.orb +6 -1
  133. package/dist/behaviors/exports/molecules/std-detail.orb +12 -5
  134. package/dist/behaviors/exports/molecules/std-event-handler-game.orb +6 -1
  135. package/dist/behaviors/exports/molecules/std-geospatial.orb +28 -9
  136. package/dist/behaviors/exports/molecules/std-inventory.orb +28 -9
  137. package/dist/behaviors/exports/molecules/std-list.orb +392 -5
  138. package/dist/behaviors/exports/molecules/std-messaging.orb +12 -5
  139. package/dist/behaviors/exports/molecules/std-negotiator-game.orb +6 -1
  140. package/dist/behaviors/exports/molecules/std-platformer-game.orb +40 -1
  141. package/dist/behaviors/exports/molecules/std-puzzle-game.orb +26 -1
  142. package/dist/behaviors/exports/molecules/std-sequencer-game.orb +6 -1
  143. package/dist/behaviors/exports/molecules/std-simulator-game.orb +6 -1
  144. package/dist/behaviors/exports/molecules/std-turn-based-battle.orb +40 -1
  145. package/dist/behaviors/exports/organisms/std-api-gateway.orb +1145 -403
  146. package/dist/behaviors/exports/organisms/std-arcade-game.orb +214 -16
  147. package/dist/behaviors/exports/organisms/std-booking-system.orb +2165 -1605
  148. package/dist/behaviors/exports/organisms/std-cicd-pipeline.orb +581 -47
  149. package/dist/behaviors/exports/organisms/std-cms.orb +1713 -947
  150. package/dist/behaviors/exports/organisms/std-coding-academy.orb +180 -380
  151. package/dist/behaviors/exports/organisms/std-crm.orb +1669 -1153
  152. package/dist/behaviors/exports/organisms/std-devops-dashboard.orb +1430 -378
  153. package/dist/behaviors/exports/organisms/std-ecommerce.orb +2361 -1601
  154. package/dist/behaviors/exports/organisms/std-finance-tracker.orb +622 -438
  155. package/dist/behaviors/exports/organisms/std-healthcare.orb +1687 -1125
  156. package/dist/behaviors/exports/organisms/std-helpdesk.orb +626 -407
  157. package/dist/behaviors/exports/organisms/std-hr-portal.orb +1309 -714
  158. package/dist/behaviors/exports/organisms/std-iot-dashboard.orb +1247 -335
  159. package/dist/behaviors/exports/organisms/std-lms.orb +658 -362
  160. package/dist/behaviors/exports/organisms/std-platformer-app.orb +56 -8
  161. package/dist/behaviors/exports/organisms/std-project-manager.orb +1697 -1183
  162. package/dist/behaviors/exports/organisms/std-puzzle-app.orb +20 -0
  163. package/dist/behaviors/exports/organisms/std-realtime-chat.orb +552 -28
  164. package/dist/behaviors/exports/organisms/std-rpg-game.orb +397 -56
  165. package/dist/behaviors/exports/organisms/std-social-feed.orb +12 -8
  166. package/dist/behaviors/exports/organisms/std-stem-lab.orb +175 -290
  167. package/dist/behaviors/exports/organisms/std-strategy-game.orb +252 -395
  168. package/dist/behaviors/exports/organisms/std-trading-dashboard.orb +718 -524
  169. package/dist/behaviors/exports/validation-report.json +747 -0
  170. package/dist/behaviors/exports/verify-results.json +13 -0
  171. package/dist/behaviors/functions/index.js +715 -593
  172. package/dist/behaviors/functions/index.js.map +1 -1
  173. package/dist/behaviors/index.js +715 -593
  174. package/dist/behaviors/index.js.map +1 -1
  175. package/dist/exports/atoms/std-async.orb +41 -24
  176. package/dist/exports/atoms/std-browse.orb +12 -5
  177. package/dist/exports/atoms/std-cache-aside.orb +256 -42
  178. package/dist/exports/atoms/std-circuit-breaker.orb +577 -97
  179. package/dist/exports/atoms/std-collision.orb +278 -206
  180. package/dist/exports/atoms/std-combat-log.orb +6 -1
  181. package/dist/exports/atoms/std-combat.orb +6 -1
  182. package/dist/exports/atoms/std-confirmation.orb +212 -7
  183. package/dist/exports/atoms/std-dialogue-box.orb +6 -1
  184. package/dist/exports/atoms/std-display.orb +166 -21
  185. package/dist/exports/atoms/std-drawer.orb +208 -104
  186. package/dist/exports/atoms/std-filter.orb +211 -18
  187. package/dist/exports/atoms/std-game-audio.orb +6 -1
  188. package/dist/exports/atoms/std-game-canvas2d.orb +6 -1
  189. package/dist/exports/atoms/std-game-canvas3d.orb +6 -1
  190. package/dist/exports/atoms/std-game-hud.orb +6 -1
  191. package/dist/exports/atoms/std-game-menu.orb +6 -1
  192. package/dist/exports/atoms/std-game-over-screen.orb +6 -1
  193. package/dist/exports/atoms/std-gameflow.orb +100 -5
  194. package/dist/exports/atoms/std-input.orb +142 -137
  195. package/dist/exports/atoms/std-inventory-panel.orb +6 -1
  196. package/dist/exports/atoms/std-isometric-canvas.orb +6 -1
  197. package/dist/exports/atoms/std-loading.orb +27 -76
  198. package/dist/exports/atoms/std-modal.orb +177 -93
  199. package/dist/exports/atoms/std-movement.orb +401 -31
  200. package/dist/exports/atoms/std-notification.orb +46 -95
  201. package/dist/exports/atoms/std-overworld.orb +44 -16
  202. package/dist/exports/atoms/std-pagination.orb +26 -89
  203. package/dist/exports/atoms/std-physics2d.orb +6 -1
  204. package/dist/exports/atoms/std-platformer-canvas.orb +6 -1
  205. package/dist/exports/atoms/std-quest.orb +309 -34
  206. package/dist/exports/atoms/std-rate-limiter.orb +410 -157
  207. package/dist/exports/atoms/std-score-board.orb +6 -1
  208. package/dist/exports/atoms/std-score.orb +211 -11
  209. package/dist/exports/atoms/std-search.orb +28 -27
  210. package/dist/exports/atoms/std-selection.orb +160 -121
  211. package/dist/exports/atoms/std-simulation-canvas.orb +6 -1
  212. package/dist/exports/atoms/std-sort.orb +134 -24
  213. package/dist/exports/atoms/std-sprite.orb +6 -1
  214. package/dist/exports/atoms/std-tabs.orb +25 -15
  215. package/dist/exports/atoms/std-timer.orb +483 -91
  216. package/dist/exports/atoms/std-undo.orb +211 -81
  217. package/dist/exports/atoms/std-wizard.orb +31 -34
  218. package/dist/exports/molecules/std-builder-game.orb +6 -1
  219. package/dist/exports/molecules/std-cart.orb +6 -1
  220. package/dist/exports/molecules/std-classifier-game.orb +6 -1
  221. package/dist/exports/molecules/std-debugger-game.orb +6 -1
  222. package/dist/exports/molecules/std-detail.orb +12 -5
  223. package/dist/exports/molecules/std-event-handler-game.orb +6 -1
  224. package/dist/exports/molecules/std-geospatial.orb +28 -9
  225. package/dist/exports/molecules/std-inventory.orb +28 -9
  226. package/dist/exports/molecules/std-list.orb +392 -5
  227. package/dist/exports/molecules/std-messaging.orb +12 -5
  228. package/dist/exports/molecules/std-negotiator-game.orb +6 -1
  229. package/dist/exports/molecules/std-platformer-game.orb +40 -1
  230. package/dist/exports/molecules/std-puzzle-game.orb +26 -1
  231. package/dist/exports/molecules/std-sequencer-game.orb +6 -1
  232. package/dist/exports/molecules/std-simulator-game.orb +6 -1
  233. package/dist/exports/molecules/std-turn-based-battle.orb +40 -1
  234. package/dist/exports/organisms/std-api-gateway.orb +1145 -403
  235. package/dist/exports/organisms/std-arcade-game.orb +214 -16
  236. package/dist/exports/organisms/std-booking-system.orb +2165 -1605
  237. package/dist/exports/organisms/std-cicd-pipeline.orb +581 -47
  238. package/dist/exports/organisms/std-cms.orb +1713 -947
  239. package/dist/exports/organisms/std-coding-academy.orb +180 -380
  240. package/dist/exports/organisms/std-crm.orb +1669 -1153
  241. package/dist/exports/organisms/std-devops-dashboard.orb +1430 -378
  242. package/dist/exports/organisms/std-ecommerce.orb +2361 -1601
  243. package/dist/exports/organisms/std-finance-tracker.orb +622 -438
  244. package/dist/exports/organisms/std-healthcare.orb +1687 -1125
  245. package/dist/exports/organisms/std-helpdesk.orb +626 -407
  246. package/dist/exports/organisms/std-hr-portal.orb +1309 -714
  247. package/dist/exports/organisms/std-iot-dashboard.orb +1247 -335
  248. package/dist/exports/organisms/std-lms.orb +658 -362
  249. package/dist/exports/organisms/std-platformer-app.orb +56 -8
  250. package/dist/exports/organisms/std-project-manager.orb +1697 -1183
  251. package/dist/exports/organisms/std-puzzle-app.orb +20 -0
  252. package/dist/exports/organisms/std-realtime-chat.orb +552 -28
  253. package/dist/exports/organisms/std-rpg-game.orb +397 -56
  254. package/dist/exports/organisms/std-social-feed.orb +12 -8
  255. package/dist/exports/organisms/std-stem-lab.orb +175 -290
  256. package/dist/exports/organisms/std-strategy-game.orb +252 -395
  257. package/dist/exports/organisms/std-trading-dashboard.orb +718 -524
  258. package/dist/exports/validation-report.json +747 -0
  259. package/dist/exports/verify-results.json +13 -0
  260. package/dist/index.js +715 -593
  261. package/dist/index.js.map +1 -1
  262. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3685,10 +3685,10 @@ function buildTrait(c) {
3685
3685
  align: "center",
3686
3686
  children: [
3687
3687
  { type: "icon", name: headerIcon, size: "sm" },
3688
- { type: "typography", variant: "h4", content: `@entity.${listFields[0] ?? "id"}` }
3688
+ { type: "typography", variant: "h4", content: `@item.${listFields[0] ?? "id"}` }
3689
3689
  ]
3690
3690
  },
3691
- ...listFields.length > 1 ? [{ type: "badge", label: `@entity.${listFields[1]}` }] : []
3691
+ ...listFields.length > 1 ? [{ type: "badge", label: `@item.${listFields[1]}` }] : []
3692
3692
  ]
3693
3693
  }
3694
3694
  ];
@@ -3697,7 +3697,7 @@ function buildTrait(c) {
3697
3697
  type: "typography",
3698
3698
  variant: "caption",
3699
3699
  color: "muted",
3700
- content: `@entity.${listFields[2]}`
3700
+ content: `@item.${listFields[2]}`
3701
3701
  });
3702
3702
  }
3703
3703
  const headerChildren = [
@@ -3773,7 +3773,7 @@ function buildTrait(c) {
3773
3773
  ...c.itemActions.length > 0 ? { itemActions: c.itemActions } : {},
3774
3774
  // hover lift: cards rise on hover for interactive feel
3775
3775
  className: "transition-shadow hover:shadow-md cursor-pointer",
3776
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
3776
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
3777
3777
  }
3778
3778
  ]
3779
3779
  }]
@@ -3812,37 +3812,33 @@ function resolve3(params) {
3812
3812
  const nonIdFields = fields.filter((f) => f.name !== "id");
3813
3813
  const p = plural(entityName);
3814
3814
  const defaultContent = {
3815
- type: "stack",
3816
- direction: "vertical",
3817
- gap: "md",
3815
+ type: "modal",
3816
+ title: params.modalTitle ?? "Details",
3817
+ isOpen: true,
3818
3818
  children: [
3819
3819
  {
3820
3820
  type: "stack",
3821
- direction: "horizontal",
3822
- gap: "sm",
3823
- align: "center",
3824
- children: [
3825
- { type: "icon", name: params.headerIcon ?? "maximize-2", size: "md" },
3826
- { type: "typography", content: params.modalTitle ?? "Details", variant: "h3" }
3827
- ]
3828
- },
3829
- { type: "divider" },
3830
- ...nonIdFields.map((f) => ({
3831
- type: "stack",
3832
- direction: "horizontal",
3821
+ direction: "vertical",
3833
3822
  gap: "md",
3834
3823
  children: [
3835
- { type: "typography", variant: "caption", content: f.name.charAt(0).toUpperCase() + f.name.slice(1) },
3836
- { type: "typography", variant: "body", content: `@entity.${f.name}` }
3824
+ ...nonIdFields.map((f) => ({
3825
+ type: "stack",
3826
+ direction: "horizontal",
3827
+ gap: "md",
3828
+ children: [
3829
+ { type: "typography", variant: "caption", content: f.name.charAt(0).toUpperCase() + f.name.slice(1) },
3830
+ { type: "typography", variant: "body", content: ["object/get", ["array/first", "@entity"], f.name] }
3831
+ ]
3832
+ })),
3833
+ { type: "divider" },
3834
+ {
3835
+ type: "stack",
3836
+ direction: "horizontal",
3837
+ gap: "sm",
3838
+ justify: "end",
3839
+ children: [{ type: "button", label: "Close", event: params.closeEvent ?? "CLOSE", variant: "ghost" }]
3840
+ }
3837
3841
  ]
3838
- })),
3839
- { type: "divider" },
3840
- {
3841
- type: "stack",
3842
- direction: "horizontal",
3843
- gap: "sm",
3844
- justify: "end",
3845
- children: [{ type: "button", label: "Close", event: params.closeEvent ?? "CLOSE", variant: "ghost" }]
3846
3842
  }
3847
3843
  ]
3848
3844
  };
@@ -3853,7 +3849,7 @@ function resolve3(params) {
3853
3849
  persistence: params.persistence ?? "runtime",
3854
3850
  traitName: params.traitName ?? `${entityName}Modal`,
3855
3851
  modalTitle: params.modalTitle ?? "Details",
3856
- headerIcon: params.headerIcon ?? "maximize-2",
3852
+ headerIcon: params.headerIcon ?? "layout-panel-top",
3857
3853
  openContent: params.openContent ?? defaultContent,
3858
3854
  openEvent: params.openEvent ?? "OPEN",
3859
3855
  openPayload: params.openPayload ?? [],
@@ -3897,7 +3893,9 @@ function buildTrait2(c) {
3897
3893
  { type: "typography", content: c.modalTitle, variant: "h2" }
3898
3894
  ] },
3899
3895
  { type: "button", label: "Open", event: c.openEvent, variant: "primary", icon: c.headerIcon }
3900
- ] }
3896
+ ] },
3897
+ { type: "divider" },
3898
+ { type: "empty-state", icon: c.headerIcon, title: "Nothing open", description: "Click Open to view details in a modal overlay." }
3901
3899
  ]
3902
3900
  }]] : [["fetch", c.entityName]]
3903
3901
  },
@@ -3908,8 +3906,26 @@ function buildTrait2(c) {
3908
3906
  event: c.openEvent,
3909
3907
  effects: [...c.openEffects, ["render-ui", "modal", c.openContent]]
3910
3908
  },
3911
- // CLOSE: open → closed
3912
- { from: "open", to: "closed", event: c.closeEvent, effects: [["render-ui", "modal", null]] }
3909
+ // CLOSE: open → closed (re-render main to avoid stale content)
3910
+ { from: "open", to: "closed", event: c.closeEvent, effects: [
3911
+ ["render-ui", "modal", null],
3912
+ ...c.standalone ? [["fetch", c.entityName], ["render-ui", "main", {
3913
+ type: "stack",
3914
+ direction: "vertical",
3915
+ gap: "lg",
3916
+ children: [
3917
+ { type: "stack", direction: "horizontal", gap: "md", justify: "space-between", children: [
3918
+ { type: "stack", direction: "horizontal", gap: "md", children: [
3919
+ { type: "icon", name: c.headerIcon, size: "lg" },
3920
+ { type: "typography", content: c.modalTitle, variant: "h2" }
3921
+ ] },
3922
+ { type: "button", label: "Open", event: c.openEvent, variant: "primary", icon: c.headerIcon }
3923
+ ] },
3924
+ { type: "divider" },
3925
+ { type: "empty-state", icon: c.headerIcon, title: "Nothing open", description: "Click Open to view details in a modal overlay." }
3926
+ ]
3927
+ }]] : []
3928
+ ] }
3913
3929
  ];
3914
3930
  if (c.saveEvent) {
3915
3931
  transitions.push({
@@ -3968,7 +3984,7 @@ function resolve4(params) {
3968
3984
  confirmMessage: params.confirmMessage ?? "Are you sure?",
3969
3985
  confirmLabel: params.confirmLabel ?? "Confirm",
3970
3986
  cancelLabel: params.cancelLabel ?? "Cancel",
3971
- headerIcon: params.headerIcon ?? "alert-triangle",
3987
+ headerIcon: params.headerIcon ?? "shield-check",
3972
3988
  requestEvent: params.requestEvent ?? "REQUEST",
3973
3989
  confirmEvent: params.confirmEvent ?? "CONFIRM",
3974
3990
  confirmEffects: params.confirmEffects ?? [],
@@ -3988,6 +4004,66 @@ function buildEntity3(c) {
3988
4004
  }
3989
4005
  function buildTrait3(c) {
3990
4006
  const { entityName, displayField, pluralName, confirmTitle, confirmMessage, confirmLabel, cancelLabel, headerIcon } = c;
4007
+ const idleMainView = {
4008
+ type: "stack",
4009
+ direction: "vertical",
4010
+ gap: "lg",
4011
+ children: [
4012
+ { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
4013
+ { type: "icon", name: headerIcon, size: "lg" },
4014
+ { type: "typography", content: pluralName, variant: "h2" }
4015
+ ] },
4016
+ { type: "divider" },
4017
+ {
4018
+ type: "data-grid",
4019
+ entity: entityName,
4020
+ emptyIcon: "inbox",
4021
+ emptyTitle: `No ${pluralName.toLowerCase()} yet`,
4022
+ emptyDescription: "Items will appear here.",
4023
+ itemActions: [{ label: confirmTitle, event: c.requestEvent, variant: "danger" }],
4024
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: [
4025
+ { type: "typography", variant: "h4", content: `@item.${displayField}` }
4026
+ ] }]
4027
+ }
4028
+ ]
4029
+ };
4030
+ const confirmModalView = {
4031
+ type: "stack",
4032
+ direction: "vertical",
4033
+ gap: "md",
4034
+ children: [
4035
+ {
4036
+ type: "stack",
4037
+ direction: "horizontal",
4038
+ gap: "sm",
4039
+ align: "center",
4040
+ children: [
4041
+ { type: "icon", name: "alert-triangle", size: "md" },
4042
+ { type: "typography", content: confirmTitle, variant: "h3" }
4043
+ ]
4044
+ },
4045
+ { type: "divider" },
4046
+ {
4047
+ type: "alert",
4048
+ variant: "danger",
4049
+ message: confirmMessage
4050
+ },
4051
+ {
4052
+ type: "stack",
4053
+ direction: "horizontal",
4054
+ gap: "sm",
4055
+ justify: "end",
4056
+ children: [
4057
+ { type: "button", label: cancelLabel, event: "CANCEL", variant: "ghost" },
4058
+ { type: "button", label: confirmLabel, event: c.confirmEvent, variant: "danger", icon: "check" }
4059
+ ]
4060
+ }
4061
+ ]
4062
+ };
4063
+ const dismissAndRefresh = [
4064
+ ["render-ui", "modal", null],
4065
+ ...c.standalone ? [["fetch", entityName], ["render-ui", "main", idleMainView]] : [["fetch", entityName]]
4066
+ ];
3991
4067
  return {
3992
4068
  name: c.traitName,
3993
4069
  linkedEntity: entityName,
@@ -4006,36 +4082,12 @@ function buildTrait3(c) {
4006
4082
  { key: "CLOSE", name: "Close" }
4007
4083
  ],
4008
4084
  transitions: [
4009
- // INIT: idle -> idle
4010
4085
  {
4011
4086
  from: "idle",
4012
4087
  to: "idle",
4013
4088
  event: "INIT",
4014
- effects: c.standalone ? [["fetch", entityName], ["render-ui", "main", {
4015
- type: "stack",
4016
- direction: "vertical",
4017
- gap: "lg",
4018
- children: [
4019
- { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
4020
- { type: "icon", name: headerIcon, size: "lg" },
4021
- { type: "typography", content: pluralName, variant: "h2" }
4022
- ] },
4023
- { type: "divider" },
4024
- {
4025
- type: "data-grid",
4026
- entity: entityName,
4027
- emptyIcon: "inbox",
4028
- emptyTitle: `No ${pluralName.toLowerCase()} yet`,
4029
- emptyDescription: "Items will appear here.",
4030
- itemActions: [{ label: confirmTitle, event: c.requestEvent, variant: "danger" }],
4031
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: [
4032
- { type: "typography", variant: "h4", content: `@entity.${displayField}` }
4033
- ] }]
4034
- }
4035
- ]
4036
- }]] : [["fetch", entityName]]
4089
+ effects: c.standalone ? [["fetch", entityName], ["render-ui", "main", idleMainView]] : [["fetch", entityName]]
4037
4090
  },
4038
- // REQUEST: idle -> confirming (fetch entity by ID so server has context)
4039
4091
  {
4040
4092
  from: "idle",
4041
4093
  to: "confirming",
@@ -4043,65 +4095,30 @@ function buildTrait3(c) {
4043
4095
  effects: [
4044
4096
  ["set", "@entity.pendingId", "@payload.id"],
4045
4097
  ["fetch", entityName, "@payload.id"],
4046
- ["render-ui", "modal", {
4047
- type: "stack",
4048
- direction: "vertical",
4049
- gap: "md",
4050
- children: [
4051
- {
4052
- type: "stack",
4053
- direction: "horizontal",
4054
- gap: "sm",
4055
- align: "center",
4056
- children: [
4057
- { type: "icon", name: headerIcon, size: "md" },
4058
- { type: "typography", content: confirmTitle, variant: "h3" }
4059
- ]
4060
- },
4061
- { type: "divider" },
4062
- { type: "typography", content: confirmMessage, variant: "body" },
4063
- {
4064
- type: "stack",
4065
- direction: "horizontal",
4066
- gap: "sm",
4067
- justify: "end",
4068
- children: [
4069
- { type: "button", label: cancelLabel, event: "CANCEL", variant: "ghost" },
4070
- { type: "button", label: confirmLabel, event: c.confirmEvent, variant: "danger", icon: "check" }
4071
- ]
4072
- }
4073
- ]
4074
- }]
4098
+ ["render-ui", "modal", confirmModalView]
4075
4099
  ]
4076
4100
  },
4077
- // CONFIRM: confirming -> idle (run injected effects, dismiss modal)
4078
4101
  {
4079
4102
  from: "confirming",
4080
4103
  to: "idle",
4081
4104
  event: c.confirmEvent,
4082
4105
  effects: [
4083
4106
  ...c.confirmEffects,
4084
- ["render-ui", "modal", null],
4107
+ ...dismissAndRefresh,
4085
4108
  ...c.emitOnConfirm ? [["emit", c.emitOnConfirm]] : []
4086
4109
  ]
4087
4110
  },
4088
- // CANCEL: confirming -> idle (dismiss modal)
4089
4111
  {
4090
4112
  from: "confirming",
4091
4113
  to: "idle",
4092
4114
  event: "CANCEL",
4093
- effects: [
4094
- ["render-ui", "modal", null]
4095
- ]
4115
+ effects: dismissAndRefresh
4096
4116
  },
4097
- // CLOSE: confirming -> idle (dismiss modal)
4098
4117
  {
4099
4118
  from: "confirming",
4100
4119
  to: "idle",
4101
4120
  event: "CLOSE",
4102
- effects: [
4103
- ["render-ui", "modal", null]
4104
- ]
4121
+ effects: dismissAndRefresh
4105
4122
  }
4106
4123
  ]
4107
4124
  }
@@ -4131,8 +4148,8 @@ function stdConfirmation(params) {
4131
4148
  function resolve5(params) {
4132
4149
  const { entityName } = params;
4133
4150
  const baseFields = ensureIdField(params.fields);
4134
- const fields = baseFields.some((f) => f.name === "query") ? baseFields : [...baseFields, { name: "query", type: "string", default: "" }];
4135
- const nonIdFields = baseFields.filter((f) => f.name !== "id" && f.name !== "query");
4151
+ const fields = baseFields;
4152
+ const nonIdFields = baseFields.filter((f) => f.name !== "id");
4136
4153
  const p = plural(entityName);
4137
4154
  return {
4138
4155
  entityName,
@@ -4169,7 +4186,8 @@ function buildTrait4(c) {
4169
4186
  ]
4170
4187
  },
4171
4188
  { type: "divider" },
4172
- { type: "search-input", placeholder, event: "SEARCH" }
4189
+ { type: "search-input", placeholder, event: "SEARCH" },
4190
+ { type: "empty-state", icon: searchIcon, title: "Search to find results", description: `Type a query to search across ${pluralName.toLowerCase()}.` }
4173
4191
  ]
4174
4192
  };
4175
4193
  const resultsView = {
@@ -4191,7 +4209,7 @@ function buildTrait4(c) {
4191
4209
  align: "center",
4192
4210
  children: [
4193
4211
  { type: "icon", name: searchIcon, size: "lg" },
4194
- { type: "typography", content: ["concat", 'Results for "', "@entity.query", '"'], variant: "h2" }
4212
+ { type: "typography", content: ["concat", 'Results for "', "@payload.query", '"'], variant: "h2" }
4195
4213
  ]
4196
4214
  },
4197
4215
  { type: "button", label: "Clear", event: "CLEAR", variant: "ghost", icon: "x" }
@@ -4204,12 +4222,12 @@ function buildTrait4(c) {
4204
4222
  emptyIcon: searchIcon,
4205
4223
  emptyTitle: "No results found",
4206
4224
  emptyDescription: "Try a different search term.",
4207
- children: [{
4225
+ renderItem: ["fn", "item", {
4208
4226
  type: "stack",
4209
4227
  direction: "vertical",
4210
4228
  gap: "sm",
4211
4229
  children: [
4212
- { type: "typography", variant: "h4", content: `@entity.${displayField}` }
4230
+ { type: "typography", variant: "h4", content: `@item.${displayField}` }
4213
4231
  ]
4214
4232
  }]
4215
4233
  }
@@ -4244,7 +4262,6 @@ function buildTrait4(c) {
4244
4262
  to: "searching",
4245
4263
  event: "SEARCH",
4246
4264
  effects: [
4247
- ["set", "@entity.query", "@payload.query"],
4248
4265
  ["fetch", entityName],
4249
4266
  ["render-ui", "main", resultsView]
4250
4267
  ]
@@ -4254,7 +4271,6 @@ function buildTrait4(c) {
4254
4271
  to: "searching",
4255
4272
  event: "SEARCH",
4256
4273
  effects: [
4257
- ["set", "@entity.query", "@payload.query"],
4258
4274
  ["fetch", entityName],
4259
4275
  ["render-ui", "main", resultsView]
4260
4276
  ]
@@ -4264,7 +4280,6 @@ function buildTrait4(c) {
4264
4280
  to: "idle",
4265
4281
  event: "CLEAR",
4266
4282
  effects: [
4267
- ["set", "@entity.query", ""],
4268
4283
  ["fetch", entityName],
4269
4284
  ["render-ui", "main", searchInputView]
4270
4285
  ]
@@ -4322,61 +4337,28 @@ function buildEntity5(c) {
4322
4337
  }
4323
4338
  function buildTrait5(c) {
4324
4339
  const { entityName, displayField, pluralName, headerIcon, pageTitle, filterableFields } = c;
4325
- const filterButtons = filterableFields.map((f) => ({
4326
- type: "stack",
4327
- direction: "vertical",
4328
- gap: "xs",
4329
- children: [
4330
- // overline group label for visual hierarchy
4331
- {
4332
- type: "typography",
4333
- variant: "overline",
4334
- color: "muted",
4335
- content: f.name.charAt(0).toUpperCase() + f.name.slice(1)
4336
- },
4337
- {
4338
- type: "stack",
4339
- direction: "horizontal",
4340
- gap: "sm",
4341
- align: "center",
4342
- children: (f.values ?? []).map((v) => ({
4343
- type: "button",
4344
- label: v,
4345
- event: "FILTER",
4346
- variant: "secondary"
4347
- }))
4348
- }
4349
- ]
4350
- }));
4351
- const activeFilterButtons = filterableFields.map((f) => ({
4340
+ const filterControls = filterableFields.length > 0 ? [{
4341
+ type: "filter-group",
4342
+ entity: entityName,
4343
+ filters: filterableFields.map((f) => ({
4344
+ field: f.name,
4345
+ label: f.name.charAt(0).toUpperCase() + f.name.slice(1),
4346
+ options: f.values ?? [],
4347
+ filterType: f.type === "boolean" ? "toggle" : "select"
4348
+ }))
4349
+ }] : [{ type: "empty-state", icon: "filter-x", title: "No filter fields", description: "Add fields with predefined values to enable filtering." }];
4350
+ const booleanFilters = filterableFields.filter((f) => f.type === "boolean");
4351
+ const switchControls = booleanFilters.map((f) => ({
4352
4352
  type: "stack",
4353
- direction: "vertical",
4354
- gap: "xs",
4353
+ direction: "horizontal",
4354
+ gap: "sm",
4355
+ align: "center",
4356
+ justify: "space-between",
4355
4357
  children: [
4356
- {
4357
- type: "typography",
4358
- variant: "overline",
4359
- color: "muted",
4360
- content: f.name.charAt(0).toUpperCase() + f.name.slice(1)
4361
- },
4362
- {
4363
- type: "stack",
4364
- direction: "horizontal",
4365
- gap: "sm",
4366
- align: "center",
4367
- children: (f.values ?? []).map((v) => ({
4368
- // active filter chip uses 'primary' variant so runtime highlights it
4369
- type: "button",
4370
- label: v,
4371
- event: "FILTER",
4372
- variant: "primary"
4373
- }))
4374
- }
4358
+ { type: "typography", variant: "body", content: f.name.charAt(0).toUpperCase() + f.name.slice(1) },
4359
+ { type: "switch", checked: false }
4375
4360
  ]
4376
4361
  }));
4377
- if (filterButtons.length === 0) {
4378
- filterButtons.push({ type: "badge", label: "No filter fields defined" });
4379
- }
4380
4362
  const header = {
4381
4363
  type: "stack",
4382
4364
  direction: "horizontal",
@@ -4398,17 +4380,37 @@ function buildTrait5(c) {
4398
4380
  emptyTitle: `No ${pluralName.toLowerCase()} yet`,
4399
4381
  emptyDescription: `Add ${pluralName.toLowerCase()} to see them here.`,
4400
4382
  className: "transition-shadow hover:shadow-md cursor-pointer",
4401
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: [
4402
- { type: "typography", variant: "h4", content: `@entity.${displayField}` },
4383
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: [
4384
+ { type: "typography", variant: "h4", content: `@item.${displayField}` },
4403
4385
  // show the filterable field value to confirm what was filtered
4404
- ...filterableFields[0] ? [{ type: "typography", variant: "caption", color: "muted", content: `@entity.${filterableFields[0].name}` }] : []
4386
+ ...filterableFields[0] ? [{ type: "typography", variant: "caption", color: "muted", content: `@item.${filterableFields[0].name}` }] : []
4405
4387
  ] }]
4406
4388
  };
4407
4389
  const browsingView = {
4408
4390
  type: "stack",
4409
4391
  direction: "vertical",
4410
4392
  gap: "lg",
4411
- children: [header, { type: "divider" }, ...filterButtons, { type: "divider" }, dataGrid]
4393
+ children: [
4394
+ header,
4395
+ { type: "divider" },
4396
+ ...filterControls,
4397
+ ...switchControls.length > 0 ? [{ type: "divider" }, ...switchControls] : [],
4398
+ { type: "divider" },
4399
+ dataGrid
4400
+ ]
4401
+ };
4402
+ const activeFilterIndicator = {
4403
+ type: "stack",
4404
+ direction: "horizontal",
4405
+ gap: "sm",
4406
+ align: "center",
4407
+ children: [
4408
+ { type: "icon", name: "filter", size: "sm" },
4409
+ { type: "typography", variant: "caption", color: "muted", content: "Filtered by" },
4410
+ { type: "badge", label: "@payload.field", variant: "secondary" },
4411
+ { type: "typography", variant: "caption", content: "=" },
4412
+ { type: "badge", label: "@payload.value", variant: "primary" }
4413
+ ]
4412
4414
  };
4413
4415
  const filteredView = {
4414
4416
  type: "stack",
@@ -4426,15 +4428,16 @@ function buildTrait5(c) {
4426
4428
  { type: "icon", name: headerIcon, size: "lg" },
4427
4429
  { type: "typography", content: pageTitle, variant: "h2" }
4428
4430
  ] },
4429
- { type: "stack", direction: "horizontal", gap: "sm", children: [
4431
+ { type: "stack", direction: "horizontal", gap: "sm", align: "center", children: [
4430
4432
  { type: "badge", label: "Filtered", variant: "primary" },
4431
- { type: "button", label: "Clear", event: "CLEAR_FILTERS", variant: "ghost", icon: "x" }
4433
+ { type: "button", label: "Clear All", event: "CLEAR_FILTERS", variant: "ghost", icon: "x" }
4432
4434
  ] }
4433
4435
  ]
4434
4436
  },
4437
+ activeFilterIndicator,
4435
4438
  { type: "divider" },
4436
- // activeFilterButtons show primary variant for selected state
4437
- ...activeFilterButtons,
4439
+ ...filterControls,
4440
+ ...switchControls.length > 0 ? [{ type: "divider" }, ...switchControls] : [],
4438
4441
  { type: "divider" },
4439
4442
  dataGrid
4440
4443
  ]
@@ -4450,14 +4453,29 @@ function buildTrait5(c) {
4450
4453
  ],
4451
4454
  events: [
4452
4455
  { key: "INIT", name: "Initialize" },
4453
- { key: "FILTER", name: "Filter" },
4456
+ { key: "FILTER", name: "Filter", payload: [
4457
+ { name: "field", type: "string", required: true },
4458
+ { name: "value", type: "string", required: true }
4459
+ ] },
4454
4460
  { key: "CLEAR_FILTERS", name: "Clear Filters" }
4455
4461
  ],
4456
4462
  transitions: [
4457
- { from: "browsing", to: "browsing", event: "INIT", effects: [["fetch", entityName], ["render-ui", "main", browsingView]] },
4458
- { from: "browsing", to: "filtered", event: "FILTER", effects: [["fetch", entityName], ["render-ui", "main", filteredView]] },
4459
- { from: "filtered", to: "filtered", event: "FILTER", effects: [["fetch", entityName], ["render-ui", "main", filteredView]] },
4460
- { from: "filtered", to: "browsing", event: "CLEAR_FILTERS", effects: [["fetch", entityName], ["render-ui", "main", browsingView]] }
4463
+ { from: "browsing", to: "browsing", event: "INIT", effects: [
4464
+ ["fetch", entityName],
4465
+ ["render-ui", "main", browsingView]
4466
+ ] },
4467
+ { from: "browsing", to: "filtered", event: "FILTER", effects: [
4468
+ ["fetch", entityName, ["==", ["object/get", "@entity", "@payload.field"], "@payload.value"]],
4469
+ ["render-ui", "main", filteredView]
4470
+ ] },
4471
+ { from: "filtered", to: "filtered", event: "FILTER", effects: [
4472
+ ["fetch", entityName, ["==", ["object/get", "@entity", "@payload.field"], "@payload.value"]],
4473
+ ["render-ui", "main", filteredView]
4474
+ ] },
4475
+ { from: "filtered", to: "browsing", event: "CLEAR_FILTERS", effects: [
4476
+ ["fetch", entityName],
4477
+ ["render-ui", "main", browsingView]
4478
+ ] }
4461
4479
  ]
4462
4480
  }
4463
4481
  };
@@ -4514,7 +4532,7 @@ function buildTrait6(c) {
4514
4532
  type: "button",
4515
4533
  label: f.charAt(0).toUpperCase() + f.slice(1),
4516
4534
  event: "SORT",
4517
- // secondary in idle; molecules can override active to primary
4535
+ actionPayload: { field: f, direction: "asc" },
4518
4536
  variant: "secondary",
4519
4537
  icon: "arrow-up-down"
4520
4538
  }))
@@ -4531,6 +4549,7 @@ function buildTrait6(c) {
4531
4549
  type: "button",
4532
4550
  label: f.charAt(0).toUpperCase() + f.slice(1),
4533
4551
  event: "SORT",
4552
+ actionPayload: { field: f, direction: f === activeField ? "desc" : "asc" },
4534
4553
  // highlight the active sort field with primary + directional arrow
4535
4554
  variant: f === activeField ? "primary" : "secondary",
4536
4555
  icon: f === activeField ? "chevron-up" : "arrow-up-down"
@@ -4544,10 +4563,9 @@ function buildTrait6(c) {
4544
4563
  emptyTitle: `No ${pluralName.toLowerCase()} yet`,
4545
4564
  emptyDescription: `Add ${pluralName.toLowerCase()} to see them here.`,
4546
4565
  className: "transition-shadow hover:shadow-md cursor-pointer",
4547
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: [
4548
- { type: "typography", variant: "h4", content: `@entity.${displayField}` },
4549
- // Show the first sortable field as a secondary datum so sorting is visually meaningful
4550
- ...sortableFields[1] ? [{ type: "typography", variant: "caption", color: "muted", content: `@entity.${sortableFields[1]}` }] : []
4566
+ renderItem: ["fn", "item", { type: "stack", direction: "horizontal", gap: "md", align: "center", justify: "space-between", children: [
4567
+ { type: "typography", variant: "h4", content: `@item.${displayField}` },
4568
+ ...sortableFields[1] ? [{ type: "typography", variant: "caption", color: "muted", content: `@item.${sortableFields[1]}` }] : []
4551
4569
  ] }]
4552
4570
  };
4553
4571
  const mainView = {
@@ -4562,7 +4580,6 @@ function buildTrait6(c) {
4562
4580
  ] }
4563
4581
  ] },
4564
4582
  { type: "divider" },
4565
- // Sort toolbar lives just above the data list
4566
4583
  sortToolbar,
4567
4584
  dataGrid
4568
4585
  ]
@@ -4593,12 +4610,21 @@ function buildTrait6(c) {
4593
4610
  states: [{ name: "idle", isInitial: true }, { name: "sorted" }],
4594
4611
  events: [
4595
4612
  { key: "INIT", name: "Initialize" },
4596
- { key: "SORT", name: "Sort" }
4613
+ { key: "SORT", name: "Sort", payload: [
4614
+ { name: "field", type: "string", required: true },
4615
+ { name: "direction", type: "string" }
4616
+ ] }
4597
4617
  ],
4598
4618
  transitions: [
4599
4619
  { from: "idle", to: "idle", event: "INIT", effects: [["fetch", entityName], ["render-ui", "main", mainView]] },
4600
- { from: "idle", to: "sorted", event: "SORT", effects: [["fetch", entityName], ["render-ui", "main", mainSortedView]] },
4601
- { from: "sorted", to: "sorted", event: "SORT", effects: [["fetch", entityName], ["render-ui", "main", mainSortedView]] },
4620
+ { from: "idle", to: "sorted", event: "SORT", effects: [
4621
+ ["fetch", entityName, null, ["concat", "@payload.field", ":", "@payload.direction"]],
4622
+ ["render-ui", "main", mainSortedView]
4623
+ ] },
4624
+ { from: "sorted", to: "sorted", event: "SORT", effects: [
4625
+ ["fetch", entityName, null, ["concat", "@payload.field", ":", "@payload.direction"]],
4626
+ ["render-ui", "main", mainSortedView]
4627
+ ] },
4602
4628
  { from: "sorted", to: "idle", event: "INIT", effects: [["fetch", entityName], ["render-ui", "main", mainView]] }
4603
4629
  ]
4604
4630
  }
@@ -4623,12 +4649,8 @@ function stdSort(params) {
4623
4649
  function resolve8(params) {
4624
4650
  const { entityName } = params;
4625
4651
  const baseFields = ensureIdField(params.fields);
4626
- const fields = [
4627
- ...baseFields,
4628
- ...baseFields.some((f) => f.name === "currentPage") ? [] : [{ name: "currentPage", type: "number", default: 1 }],
4629
- ...baseFields.some((f) => f.name === "pageSize") ? [] : [{ name: "pageSize", type: "number", default: 10 }]
4630
- ];
4631
- const nonIdFields = baseFields.filter((f) => f.name !== "id" && f.name !== "currentPage" && f.name !== "pageSize");
4652
+ const fields = baseFields;
4653
+ const nonIdFields = baseFields.filter((f) => f.name !== "id");
4632
4654
  const p = plural(entityName);
4633
4655
  return {
4634
4656
  entityName,
@@ -4682,34 +4704,22 @@ function buildTrait7(c) {
4682
4704
  emptyTitle: `No ${pluralName.toLowerCase()} yet`,
4683
4705
  emptyDescription: `Add ${pluralName.toLowerCase()} to see them here.`,
4684
4706
  className: "transition-shadow hover:shadow-md cursor-pointer",
4685
- children: [{
4707
+ renderItem: ["fn", "item", {
4686
4708
  type: "stack",
4687
4709
  direction: "vertical",
4688
4710
  gap: "sm",
4689
4711
  children: [
4690
- { type: "typography", variant: "h4", content: `@entity.${displayField}` },
4691
- // secondary caption row to distinguish items
4692
- { type: "typography", variant: "caption", color: "muted", content: `@entity.id` }
4712
+ { type: "typography", variant: "h4", content: "@item.name" },
4713
+ { type: "typography", variant: "caption", color: "muted", content: "@item.id" }
4693
4714
  ]
4694
4715
  }]
4695
4716
  },
4696
4717
  {
4697
- // Pagination footer with context: "Page N" and Prev/Next nav
4698
- type: "stack",
4699
- direction: "horizontal",
4700
- gap: "sm",
4701
- justify: "center",
4702
- align: "center",
4703
- children: [
4704
- { type: "button", label: "Previous", event: "PAGE", variant: "ghost", icon: "chevron-left" },
4705
- {
4706
- type: "typography",
4707
- variant: "body",
4708
- color: "muted",
4709
- content: ["concat", "Page ", "@entity.currentPage"]
4710
- },
4711
- { type: "button", label: "Next", event: "PAGE", variant: "ghost", icon: "chevron-right" }
4712
- ]
4718
+ type: "pagination",
4719
+ currentPage: 1,
4720
+ totalPages: 10,
4721
+ onPageChange: "PAGE",
4722
+ showPageSize: false
4713
4723
  }
4714
4724
  ]
4715
4725
  };
@@ -4743,10 +4753,58 @@ function buildTrait7(c) {
4743
4753
  to: "idle",
4744
4754
  event: "PAGE",
4745
4755
  effects: [
4746
- ["set", "@entity.currentPage", "@payload.page"],
4747
- ["set", "@entity.pageSize", "@payload.pageSize"],
4748
4756
  ["fetch", entityName],
4749
- ["render-ui", "main", mainView]
4757
+ ["render-ui", "main", {
4758
+ type: "stack",
4759
+ direction: "vertical",
4760
+ gap: "lg",
4761
+ children: [
4762
+ {
4763
+ type: "stack",
4764
+ direction: "horizontal",
4765
+ gap: "sm",
4766
+ justify: "space-between",
4767
+ align: "center",
4768
+ children: [
4769
+ {
4770
+ type: "stack",
4771
+ direction: "horizontal",
4772
+ gap: "sm",
4773
+ align: "center",
4774
+ children: [
4775
+ { type: "icon", name: headerIcon, size: "lg" },
4776
+ { type: "typography", content: pageTitle, variant: "h2" }
4777
+ ]
4778
+ }
4779
+ ]
4780
+ },
4781
+ { type: "divider" },
4782
+ {
4783
+ type: "data-grid",
4784
+ entity: entityName,
4785
+ emptyIcon: "inbox",
4786
+ emptyTitle: `No ${pluralName.toLowerCase()} yet`,
4787
+ emptyDescription: `Add ${pluralName.toLowerCase()} to see them here.`,
4788
+ className: "transition-shadow hover:shadow-md cursor-pointer",
4789
+ renderItem: ["fn", "item", {
4790
+ type: "stack",
4791
+ direction: "vertical",
4792
+ gap: "sm",
4793
+ children: [
4794
+ { type: "typography", variant: "h4", content: "@item.name" },
4795
+ { type: "typography", variant: "caption", color: "muted", content: "@item.id" }
4796
+ ]
4797
+ }]
4798
+ },
4799
+ {
4800
+ type: "pagination",
4801
+ currentPage: "@payload.page",
4802
+ totalPages: 10,
4803
+ onPageChange: "PAGE",
4804
+ showPageSize: false
4805
+ }
4806
+ ]
4807
+ }]
4750
4808
  ]
4751
4809
  }
4752
4810
  ]
@@ -4797,6 +4855,7 @@ function resolve9(params) {
4797
4855
  function buildEntity8(c) {
4798
4856
  return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence });
4799
4857
  }
4858
+ var ef = (field) => ["object/get", ["array/first", "@entity"], field];
4800
4859
  function buildTrait8(c) {
4801
4860
  const { entityName, nonIdFields, displayField, pluralName, drawerTitle, headerIcon } = c;
4802
4861
  const closedView = {
@@ -4831,60 +4890,63 @@ function buildTrait8(c) {
4831
4890
  emptyIcon: "inbox",
4832
4891
  emptyTitle: `No ${pluralName.toLowerCase()} yet`,
4833
4892
  emptyDescription: `Add ${pluralName.toLowerCase()} to see them here.`,
4834
- children: [{
4893
+ renderItem: ["fn", "item", {
4835
4894
  type: "stack",
4836
4895
  direction: "vertical",
4837
4896
  gap: "sm",
4838
4897
  children: [
4839
- { type: "typography", variant: "h4", content: `@entity.${displayField}` }
4898
+ { type: "typography", variant: "h4", content: `@item.${displayField}` }
4840
4899
  ]
4841
4900
  }]
4842
4901
  }
4843
4902
  ]
4844
4903
  };
4845
4904
  const openView = {
4846
- type: "stack",
4847
- direction: "vertical",
4848
- gap: "md",
4905
+ type: "drawer",
4906
+ title: drawerTitle,
4907
+ isOpen: true,
4849
4908
  children: [
4850
4909
  {
4851
4910
  type: "stack",
4852
- direction: "horizontal",
4853
- gap: "sm",
4854
- justify: "space-between",
4855
- align: "center",
4911
+ direction: "vertical",
4912
+ gap: "md",
4856
4913
  children: [
4914
+ {
4915
+ type: "accordion",
4916
+ items: [
4917
+ {
4918
+ id: "details",
4919
+ title: "Details",
4920
+ content: {
4921
+ type: "stack",
4922
+ direction: "vertical",
4923
+ gap: "sm",
4924
+ children: nonIdFields.map((field) => ({
4925
+ type: "stack",
4926
+ direction: "horizontal",
4927
+ gap: "md",
4928
+ justify: "space-between",
4929
+ children: [
4930
+ { type: "typography", variant: "caption", content: field.name.charAt(0).toUpperCase() + field.name.slice(1) },
4931
+ { type: "typography", variant: "body", content: ef(field.name) }
4932
+ ]
4933
+ }))
4934
+ }
4935
+ }
4936
+ ],
4937
+ defaultOpen: [0],
4938
+ multiple: true
4939
+ },
4940
+ { type: "divider" },
4857
4941
  {
4858
4942
  type: "stack",
4859
4943
  direction: "horizontal",
4860
4944
  gap: "sm",
4861
- align: "center",
4945
+ justify: "end",
4862
4946
  children: [
4863
- { type: "icon", name: headerIcon, size: "md" },
4864
- { type: "typography", content: drawerTitle, variant: "h3" }
4947
+ { type: "button", label: "Close", event: "CLOSE", variant: "ghost" }
4865
4948
  ]
4866
- },
4867
- { type: "button", label: "Close", event: "CLOSE", variant: "ghost", icon: "x" }
4868
- ]
4869
- },
4870
- { type: "divider" },
4871
- ...nonIdFields.map((field) => ({
4872
- type: "stack",
4873
- direction: "horizontal",
4874
- gap: "md",
4875
- children: [
4876
- { type: "typography", variant: "caption", content: field.name.charAt(0).toUpperCase() + field.name.slice(1) },
4877
- { type: "typography", variant: "body", content: `@entity.${field.name}` }
4878
- ]
4879
- })),
4880
- { type: "divider" },
4881
- {
4882
- type: "stack",
4883
- direction: "horizontal",
4884
- gap: "sm",
4885
- justify: "end",
4886
- children: [
4887
- { type: "button", label: "Close", event: "CLOSE", variant: "ghost" }
4949
+ }
4888
4950
  ]
4889
4951
  }
4890
4952
  ]
@@ -4927,7 +4989,9 @@ function buildTrait8(c) {
4927
4989
  to: "closed",
4928
4990
  event: "CLOSE",
4929
4991
  effects: [
4930
- ["render-ui", "drawer", null]
4992
+ ["render-ui", "drawer", null],
4993
+ ["fetch", entityName],
4994
+ ["render-ui", "main", closedView]
4931
4995
  ]
4932
4996
  }
4933
4997
  ]
@@ -4980,6 +5044,7 @@ function resolve10(params) {
4980
5044
  function buildEntity9(c) {
4981
5045
  return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence });
4982
5046
  }
5047
+ var ef2 = (field) => ["object/get", ["array/first", "@entity"], field];
4983
5048
  function buildTrait9(c) {
4984
5049
  const { entityName, headerIcon, pageTitle } = c;
4985
5050
  const hiddenView = {
@@ -4998,17 +5063,7 @@ function buildTrait9(c) {
4998
5063
  ]
4999
5064
  },
5000
5065
  { type: "divider" },
5001
- {
5002
- type: "stack",
5003
- direction: "vertical",
5004
- gap: "md",
5005
- align: "center",
5006
- children: [
5007
- { type: "icon", name: "bell-off", size: "lg" },
5008
- { type: "typography", content: "No notifications", variant: "body" },
5009
- { type: "typography", content: "New notifications will appear here.", variant: "caption" }
5010
- ]
5011
- }
5066
+ { type: "empty-state", icon: "bell-off", title: "No notifications", description: "New notifications will appear here." }
5012
5067
  ]
5013
5068
  };
5014
5069
  const visibleView = {
@@ -5038,22 +5093,9 @@ function buildTrait9(c) {
5038
5093
  },
5039
5094
  { type: "divider" },
5040
5095
  {
5041
- type: "stack",
5042
- direction: "horizontal",
5043
- gap: "md",
5044
- align: "center",
5045
- children: [
5046
- { type: "icon", name: headerIcon, size: "md" },
5047
- {
5048
- type: "stack",
5049
- direction: "vertical",
5050
- gap: "xs",
5051
- children: [
5052
- { type: "typography", content: "@entity.message", variant: "body" },
5053
- { type: "badge", label: "@entity.notificationType" }
5054
- ]
5055
- }
5056
- ]
5096
+ type: "alert",
5097
+ variant: ef2("notificationType"),
5098
+ message: ef2("message")
5057
5099
  }
5058
5100
  ]
5059
5101
  };
@@ -5168,6 +5210,7 @@ function resolve11(params) {
5168
5210
  function buildEntity10(c) {
5169
5211
  return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence });
5170
5212
  }
5213
+ var ef3 = (field) => ["object/get", ["array/first", "@entity"], field];
5171
5214
  function buildTrait10(c) {
5172
5215
  const { entityName, timerTitle, headerIcon } = c;
5173
5216
  const timerDisplay = {
@@ -5187,13 +5230,11 @@ function buildTrait10(c) {
5187
5230
  ]
5188
5231
  },
5189
5232
  { type: "divider" },
5190
- // Large MM:SS time display the entity.remaining field drives this
5191
- { type: "typography", content: "@entity.remaining", variant: "h1" },
5192
- // Unit/label subtitle: shows what is being timed
5193
- { type: "typography", content: "seconds remaining", variant: "caption", color: "muted" },
5194
- // Progress bar track — always visible, filled as timer decrements
5195
- { type: "progress-bar", value: "@entity.remaining", max: c.duration, color: "primary" },
5196
- { type: "badge", label: "@entity.status" }
5233
+ { type: "animated-counter", value: ef3("remaining"), suffix: "s", duration: 500 },
5234
+ { type: "stat-display", label: "Time Remaining", value: ef3("remaining"), max: c.duration },
5235
+ { type: "meter", value: ef3("remaining"), min: 0, max: c.duration },
5236
+ { type: "progress-bar", value: ef3("remaining"), max: c.duration, color: "primary", showPercentage: true },
5237
+ { type: "badge", label: ef3("status") }
5197
5238
  ]
5198
5239
  };
5199
5240
  const idleButtons = {
@@ -5403,11 +5444,7 @@ function resolve12(params) {
5403
5444
  const { entityName } = params;
5404
5445
  const baseFields = ensureIdField(params.fields);
5405
5446
  const p = plural(entityName);
5406
- const domainFields = [
5407
- { name: "activeTab", type: "string", default: "" }
5408
- ];
5409
- const userFieldNames = new Set(baseFields.map((f) => f.name));
5410
- const fields = [...baseFields, ...domainFields.filter((f) => !userFieldNames.has(f.name))];
5447
+ const fields = baseFields;
5411
5448
  const nonIdFields = fields.filter((f) => f.name !== "id");
5412
5449
  const tabItems = params.tabItems ?? nonIdFields.filter((f) => f.name !== "activeTab").map((f) => ({
5413
5450
  label: f.name.charAt(0).toUpperCase() + f.name.slice(1),
@@ -5434,7 +5471,21 @@ function buildEntity11(c) {
5434
5471
  }
5435
5472
  function buildTrait11(c) {
5436
5473
  const { entityName, displayField, pluralName, headerIcon, pageTitle, tabItems } = c;
5437
- const mainView = {
5474
+ const tabContentChildren = [
5475
+ {
5476
+ type: "data-grid",
5477
+ entity: entityName,
5478
+ emptyIcon: "inbox",
5479
+ emptyTitle: `No ${pluralName.toLowerCase()} yet`,
5480
+ emptyDescription: `Add ${pluralName.toLowerCase()} to see them here.`,
5481
+ className: "transition-shadow hover:shadow-md cursor-pointer",
5482
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: [
5483
+ { type: "typography", variant: "h4", content: `@item.${displayField}` },
5484
+ { type: "typography", variant: "caption", color: "muted", content: `@item.${tabItems[0]?.value ?? displayField}` }
5485
+ ] }]
5486
+ }
5487
+ ];
5488
+ const initView = {
5438
5489
  type: "stack",
5439
5490
  direction: "vertical",
5440
5491
  gap: "lg",
@@ -5448,24 +5499,31 @@ function buildTrait11(c) {
5448
5499
  type: "tabs",
5449
5500
  tabs: tabItems,
5450
5501
  defaultActiveTab: tabItems[0]?.value ?? "",
5451
- // active tab gets primary color underline and text
5452
- activeTab: "@entity.activeTab",
5453
5502
  onTabChange: "SELECT_TAB"
5454
5503
  },
5455
- // divider separates tab bar from content
5504
+ { type: "divider" },
5505
+ ...tabContentChildren
5506
+ ]
5507
+ };
5508
+ const tabSelectedView = {
5509
+ type: "stack",
5510
+ direction: "vertical",
5511
+ gap: "lg",
5512
+ children: [
5513
+ { type: "stack", direction: "horizontal", gap: "sm", align: "center", children: [
5514
+ { type: "icon", name: headerIcon, size: "lg" },
5515
+ { type: "typography", content: pageTitle, variant: "h2" }
5516
+ ] },
5456
5517
  { type: "divider" },
5457
5518
  {
5458
- type: "data-grid",
5459
- entity: entityName,
5460
- emptyIcon: "inbox",
5461
- emptyTitle: `No ${pluralName.toLowerCase()} yet`,
5462
- emptyDescription: `Add ${pluralName.toLowerCase()} to see them here.`,
5463
- className: "transition-shadow hover:shadow-md cursor-pointer",
5464
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: [
5465
- { type: "typography", variant: "h4", content: `@entity.${displayField}` },
5466
- { type: "typography", variant: "caption", color: "muted", content: `@entity.${tabItems[0]?.value ?? displayField}` }
5467
- ] }]
5468
- }
5519
+ type: "tabs",
5520
+ tabs: tabItems,
5521
+ defaultActiveTab: tabItems[0]?.value ?? "",
5522
+ activeTab: "@payload.tab",
5523
+ onTabChange: "SELECT_TAB"
5524
+ },
5525
+ { type: "divider" },
5526
+ ...tabContentChildren
5469
5527
  ]
5470
5528
  };
5471
5529
  return {
@@ -5476,11 +5534,13 @@ function buildTrait11(c) {
5476
5534
  states: [{ name: "idle", isInitial: true }],
5477
5535
  events: [
5478
5536
  { key: "INIT", name: "Initialize" },
5479
- { key: "SELECT_TAB", name: "Select Tab" }
5537
+ { key: "SELECT_TAB", name: "Select Tab", payload: [
5538
+ { name: "tab", type: "string", required: true }
5539
+ ] }
5480
5540
  ],
5481
5541
  transitions: [
5482
- { from: "idle", to: "idle", event: "INIT", effects: [["fetch", entityName], ["render-ui", "main", mainView]] },
5483
- { from: "idle", to: "idle", event: "SELECT_TAB", effects: [["fetch", entityName], ["render-ui", "main", mainView]] }
5542
+ { from: "idle", to: "idle", event: "INIT", effects: [["fetch", entityName], ["render-ui", "main", initView]] },
5543
+ { from: "idle", to: "idle", event: "SELECT_TAB", effects: [["fetch", entityName], ["render-ui", "main", tabSelectedView]] }
5484
5544
  ]
5485
5545
  }
5486
5546
  };
@@ -5536,7 +5596,6 @@ function buildTrait12(c) {
5536
5596
  align: "center",
5537
5597
  children: [
5538
5598
  {
5539
- // Neutral icon in idle (not the spinner — that lives only in the loading state)
5540
5599
  type: "stack",
5541
5600
  direction: "horizontal",
5542
5601
  gap: "sm",
@@ -5547,41 +5606,24 @@ function buildTrait12(c) {
5547
5606
  ]
5548
5607
  },
5549
5608
  { type: "divider" },
5550
- // Contextual description of what this loading operation does
5551
5609
  {
5552
5610
  type: "typography",
5553
5611
  variant: "body",
5554
5612
  color: "muted",
5555
- content: `Ready to load ${title.toLowerCase()}. Click Start to begin.`
5556
- },
5557
- { type: "button", label: "Start", event: "START", variant: "primary", icon: "play" }
5558
- ]
5559
- };
5560
- const loadingView = {
5561
- type: "stack",
5562
- direction: "vertical",
5563
- gap: "lg",
5564
- align: "center",
5565
- children: [
5566
- {
5567
- // Spinner icon appears only in the loading state — not permanently
5568
- type: "stack",
5569
- direction: "horizontal",
5570
- gap: "sm",
5571
- align: "center",
5572
- children: [
5573
- { type: "icon", name: "loader", size: "lg" },
5574
- { type: "typography", content: "Loading...", variant: "h2" }
5575
- ]
5576
- },
5577
- { type: "divider" },
5578
- { type: "progress-bar", value: 50 },
5579
- {
5580
- type: "typography",
5581
- variant: "caption",
5582
- color: "muted",
5583
- content: "Please wait while the operation completes."
5584
- }
5613
+ content: `Ready to load ${title.toLowerCase()}. Click Start to begin.`
5614
+ },
5615
+ { type: "button", label: "Start", event: "START", variant: "primary", icon: "play" }
5616
+ ]
5617
+ };
5618
+ const loadingView = {
5619
+ type: "stack",
5620
+ direction: "vertical",
5621
+ gap: "lg",
5622
+ align: "center",
5623
+ children: [
5624
+ { type: "loading-state", title: "Loading", message: `Loading ${title.toLowerCase()}...` },
5625
+ { type: "progress-bar", value: 50, showPercentage: true },
5626
+ { type: "skeleton", variant: "text" }
5585
5627
  ]
5586
5628
  };
5587
5629
  const successView = {
@@ -5601,7 +5643,7 @@ function buildTrait12(c) {
5601
5643
  ]
5602
5644
  },
5603
5645
  { type: "divider" },
5604
- { type: "typography", variant: "body", content: "Operation completed successfully." },
5646
+ { type: "alert", variant: "success", message: "Operation completed successfully." },
5605
5647
  { type: "button", label: "Reset", event: "RESET", variant: "ghost", icon: "rotate-ccw" }
5606
5648
  ]
5607
5649
  };
@@ -5611,18 +5653,7 @@ function buildTrait12(c) {
5611
5653
  gap: "lg",
5612
5654
  align: "center",
5613
5655
  children: [
5614
- {
5615
- type: "stack",
5616
- direction: "horizontal",
5617
- gap: "md",
5618
- align: "center",
5619
- children: [
5620
- { type: "icon", name: "alert-circle", size: "lg" },
5621
- { type: "typography", content: "Error", variant: "h2" }
5622
- ]
5623
- },
5624
- { type: "divider" },
5625
- { type: "typography", variant: "body", content: "Something went wrong." },
5656
+ { type: "error-state", title: "Error", message: "Something went wrong. Please try again.", onRetry: "START" },
5626
5657
  {
5627
5658
  type: "stack",
5628
5659
  direction: "horizontal",
@@ -5745,11 +5776,8 @@ function stdLoading(params) {
5745
5776
  function resolve14(params) {
5746
5777
  const { entityName } = params;
5747
5778
  const baseFields = ensureIdField(params.fields);
5748
- const fields = [
5749
- ...baseFields,
5750
- ...baseFields.some((f) => f.name === "selectedId") ? [] : [{ name: "selectedId", type: "string", default: "" }]
5751
- ];
5752
- const nonIdFields = baseFields.filter((f) => f.name !== "id" && f.name !== "selectedId");
5779
+ const fields = baseFields;
5780
+ const nonIdFields = baseFields.filter((f) => f.name !== "id");
5753
5781
  const p = plural(entityName);
5754
5782
  return {
5755
5783
  entityName,
@@ -5786,7 +5814,6 @@ function buildTrait13(c) {
5786
5814
  ]
5787
5815
  },
5788
5816
  { type: "divider" },
5789
- // Meaningful action prompt using entity name
5790
5817
  {
5791
5818
  type: "typography",
5792
5819
  variant: "caption",
@@ -5800,16 +5827,14 @@ function buildTrait13(c) {
5800
5827
  emptyTitle: `No ${pluralName.toLowerCase()} yet`,
5801
5828
  emptyDescription: `Add ${pluralName.toLowerCase()} to see them here.`,
5802
5829
  className: "transition-shadow hover:shadow-md cursor-pointer",
5803
- children: [{
5804
- // Checkbox-style affordance on LEFT of each row, then the entity name
5830
+ itemActions: [{ label: "Select", event: "SELECT", icon: "check" }],
5831
+ renderItem: ["fn", "item", {
5805
5832
  type: "stack",
5806
5833
  direction: "horizontal",
5807
5834
  gap: "sm",
5808
5835
  align: "center",
5809
5836
  children: [
5810
- { type: "icon", name: "circle", size: "sm", color: "muted" },
5811
- { type: "typography", variant: "h4", content: `@entity.${displayField}` },
5812
- { type: "button", label: "Select", event: "SELECT", variant: "ghost", icon: "check" }
5837
+ { type: "checkbox", label: `@item.${displayField}` }
5813
5838
  ]
5814
5839
  }]
5815
5840
  }
@@ -5851,22 +5876,35 @@ function buildTrait13(c) {
5851
5876
  },
5852
5877
  { type: "divider" },
5853
5878
  {
5854
- type: "stack",
5855
- direction: "horizontal",
5856
- gap: "md",
5857
- align: "center",
5858
- children: [
5859
- { type: "typography", variant: "caption", content: "Selected ID:" },
5860
- { type: "typography", variant: "body", content: "@entity.selectedId" }
5861
- ]
5879
+ type: "alert",
5880
+ variant: "info",
5881
+ message: ["concat", "Selected: ", "@payload.id"]
5882
+ },
5883
+ {
5884
+ type: "data-grid",
5885
+ entity: entityName,
5886
+ emptyIcon: "inbox",
5887
+ emptyTitle: `No ${pluralName.toLowerCase()} yet`,
5888
+ emptyDescription: `Add ${pluralName.toLowerCase()} to see them here.`,
5889
+ itemActions: [{ label: "Select", event: "SELECT", icon: "check" }],
5890
+ renderItem: ["fn", "item", {
5891
+ type: "stack",
5892
+ direction: "horizontal",
5893
+ gap: "sm",
5894
+ align: "center",
5895
+ children: [
5896
+ { type: "checkbox", label: `@item.${displayField}`, checked: ["==", "@item.id", "@payload.id"] }
5897
+ ]
5898
+ }]
5862
5899
  },
5900
+ { type: "divider" },
5863
5901
  {
5864
5902
  type: "stack",
5865
5903
  direction: "horizontal",
5866
5904
  gap: "sm",
5867
5905
  justify: "center",
5868
5906
  children: [
5869
- { type: "button", label: "Confirm", event: "CONFIRM_SELECTION", variant: "primary", icon: "check" },
5907
+ { type: "button", label: "Confirm", event: "CONFIRM_SELECTION", actionPayload: { id: "@payload.id" }, variant: "primary", icon: "check" },
5870
5908
  { type: "button", label: "Deselect", event: "DESELECT", variant: "ghost", icon: "x" }
5871
5909
  ]
5872
5910
  }
@@ -5898,6 +5936,11 @@ function buildTrait13(c) {
5898
5936
  ]
5899
5937
  },
5900
5938
  { type: "divider" },
5939
+ {
5940
+ type: "alert",
5941
+ variant: "success",
5942
+ message: "Selection confirmed successfully."
5943
+ },
5901
5944
  {
5902
5945
  type: "stack",
5903
5946
  direction: "horizontal",
@@ -5905,7 +5948,7 @@ function buildTrait13(c) {
5905
5948
  align: "center",
5906
5949
  children: [
5907
5950
  { type: "typography", variant: "caption", content: "Selected ID:" },
5908
- { type: "typography", variant: "body", content: "@entity.selectedId" }
5951
+ { type: "typography", variant: "body", content: "@payload.id" }
5909
5952
  ]
5910
5953
  },
5911
5954
  { type: "button", label: "Clear Selection", event: "CLEAR", variant: "ghost", icon: "rotate-ccw" }
@@ -5928,7 +5971,9 @@ function buildTrait13(c) {
5928
5971
  ] },
5929
5972
  { key: "DESELECT", name: "Deselect" },
5930
5973
  { key: "CLEAR", name: "Clear" },
5931
- { key: "CONFIRM_SELECTION", name: "Confirm Selection" }
5974
+ { key: "CONFIRM_SELECTION", name: "Confirm Selection", payload: [
5975
+ { name: "id", type: "string", required: true }
5976
+ ] }
5932
5977
  ],
5933
5978
  transitions: [
5934
5979
  {
@@ -5945,7 +5990,7 @@ function buildTrait13(c) {
5945
5990
  to: "selecting",
5946
5991
  event: "SELECT",
5947
5992
  effects: [
5948
- ["set", "@entity.selectedId", "@payload.id"],
5993
+ ["fetch", entityName],
5949
5994
  ["render-ui", "main", selectingView]
5950
5995
  ]
5951
5996
  },
@@ -5954,7 +5999,7 @@ function buildTrait13(c) {
5954
5999
  to: "selecting",
5955
6000
  event: "SELECT",
5956
6001
  effects: [
5957
- ["set", "@entity.selectedId", "@payload.id"],
6002
+ ["fetch", entityName],
5958
6003
  ["render-ui", "main", selectingView]
5959
6004
  ]
5960
6005
  },
@@ -5963,7 +6008,6 @@ function buildTrait13(c) {
5963
6008
  to: "idle",
5964
6009
  event: "DESELECT",
5965
6010
  effects: [
5966
- ["set", "@entity.selectedId", ""],
5967
6011
  ["fetch", entityName],
5968
6012
  ["render-ui", "main", idleView]
5969
6013
  ]
@@ -5973,7 +6017,6 @@ function buildTrait13(c) {
5973
6017
  to: "idle",
5974
6018
  event: "CLEAR",
5975
6019
  effects: [
5976
- ["set", "@entity.selectedId", ""],
5977
6020
  ["fetch", entityName],
5978
6021
  ["render-ui", "main", idleView]
5979
6022
  ]
@@ -5991,7 +6034,6 @@ function buildTrait13(c) {
5991
6034
  to: "idle",
5992
6035
  event: "CLEAR",
5993
6036
  effects: [
5994
- ["set", "@entity.selectedId", ""],
5995
6037
  ["fetch", entityName],
5996
6038
  ["render-ui", "main", idleView]
5997
6039
  ]
@@ -6047,6 +6089,7 @@ function resolve15(params) {
6047
6089
  function buildEntity14(c) {
6048
6090
  return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence });
6049
6091
  }
6092
+ var ef4 = (field) => ["object/get", ["array/first", "@entity"], field];
6050
6093
  function buildTrait14(c) {
6051
6094
  const { entityName, headerIcon, pageTitle } = c;
6052
6095
  const mainView = {
@@ -6060,17 +6103,22 @@ function buildTrait14(c) {
6060
6103
  { type: "typography", content: pageTitle, variant: "h2" }
6061
6104
  ] },
6062
6105
  { type: "stack", direction: "horizontal", gap: "sm", align: "center", children: [
6063
- { type: "button", label: "Undo", event: "UNDO", variant: "ghost", icon: "undo" },
6064
- { type: "button", label: "Redo", event: "REDO", variant: "ghost", icon: "redo" },
6065
- // gap-6 spacer between Redo and Clear to prevent misclicking destructive action
6106
+ { type: "tooltip", content: "Undo the last action", children: [
6107
+ { type: "button", label: "Undo", event: "UNDO", variant: "ghost", icon: "undo" }
6108
+ ] },
6109
+ { type: "tooltip", content: "Redo the last undone action", children: [
6110
+ { type: "button", label: "Redo", event: "REDO", variant: "ghost", icon: "redo" }
6111
+ ] },
6066
6112
  { type: "divider", orientation: "vertical" },
6067
- { type: "button", label: "Clear", event: "CLEAR", variant: "ghost", icon: "trash-2" }
6113
+ { type: "tooltip", content: "Clear all history", children: [
6114
+ { type: "button", label: "Clear", event: "CLEAR", variant: "ghost", icon: "trash-2" }
6115
+ ] }
6068
6116
  ] }
6069
6117
  ] },
6070
6118
  { type: "divider" },
6071
6119
  { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
6072
6120
  { type: "typography", variant: "caption", color: "muted", content: "Last action:" },
6073
- { type: "badge", label: "@entity.current" }
6121
+ { type: "badge", label: ef4("current") }
6074
6122
  ] }
6075
6123
  ]
6076
6124
  };
@@ -6167,6 +6215,7 @@ function resolve16(params) {
6167
6215
  function buildEntity15(c) {
6168
6216
  return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence });
6169
6217
  }
6218
+ var ef5 = (field) => ["object/get", ["array/first", "@entity"], field];
6170
6219
  function buildTrait15(c) {
6171
6220
  const { entityName, inputLabel, placeholder, headerIcon } = c;
6172
6221
  const inputView = {
@@ -6186,22 +6235,14 @@ function buildTrait15(c) {
6186
6235
  },
6187
6236
  { type: "divider" },
6188
6237
  {
6189
- // Form field pattern: label above, input below, help text below input
6190
- type: "stack",
6191
- direction: "vertical",
6192
- gap: "sm",
6238
+ type: "form-field",
6239
+ label: inputLabel,
6240
+ hint: "Type to enter a value.",
6193
6241
  children: [
6194
- { type: "typography", variant: "caption", content: inputLabel },
6195
- { type: "input", placeholder, event: "CHANGE" },
6196
- // show current entered value as status below the field (not a mystery bar)
6197
- {
6198
- type: "typography",
6199
- variant: "caption",
6200
- color: "muted",
6201
- content: "@entity.value"
6202
- }
6242
+ { type: "input", placeholder, event: "CHANGE" }
6203
6243
  ]
6204
- }
6244
+ },
6245
+ { type: "typography", variant: "caption", color: "muted", content: ef5("value") }
6205
6246
  ]
6206
6247
  };
6207
6248
  const validatingView = {
@@ -6221,21 +6262,14 @@ function buildTrait15(c) {
6221
6262
  },
6222
6263
  { type: "divider" },
6223
6264
  {
6224
- type: "stack",
6225
- direction: "vertical",
6226
- gap: "sm",
6265
+ type: "form-field",
6266
+ label: inputLabel,
6267
+ hint: "Validating...",
6227
6268
  children: [
6228
- { type: "typography", variant: "caption", content: inputLabel },
6229
- { type: "input", placeholder, event: "CHANGE" },
6230
- // semantic validation message — shown only in validating state
6231
- {
6232
- type: "typography",
6233
- variant: "caption",
6234
- color: "muted",
6235
- content: "Validating..."
6236
- }
6269
+ { type: "input", placeholder, event: "CHANGE" }
6237
6270
  ]
6238
- }
6271
+ },
6272
+ { type: "alert", variant: "info", message: "Validating input..." }
6239
6273
  ]
6240
6274
  };
6241
6275
  return {
@@ -6388,7 +6422,6 @@ function buildEntity16(c) {
6388
6422
  }
6389
6423
  function buildStepUI(c, stepIndex) {
6390
6424
  const step = c.steps[stepIndex];
6391
- const stepNumber = stepIndex + 1;
6392
6425
  const isFirst = stepIndex === 0;
6393
6426
  const navButtons = [];
6394
6427
  if (!isFirst) {
@@ -6410,7 +6443,7 @@ function buildStepUI(c, stepIndex) {
6410
6443
  { type: "typography", content: c.wizardTitle, variant: "h2" }
6411
6444
  ]
6412
6445
  },
6413
- { type: "badge", label: `Step ${stepNumber} of ${c.totalSteps}` },
6446
+ { type: "progress-dots", count: c.totalSteps, currentIndex: stepIndex },
6414
6447
  { type: "wizard-progress", steps: c.wizardProgressSteps, currentStep: stepIndex },
6415
6448
  { type: "divider" },
6416
6449
  { type: "typography", content: step.name, variant: "h3" },
@@ -6433,7 +6466,7 @@ function buildReviewUI(c) {
6433
6466
  justify: "space-between",
6434
6467
  children: [
6435
6468
  { type: "typography", variant: "caption", content: field.name.charAt(0).toUpperCase() + field.name.slice(1) },
6436
- { type: "typography", variant: "body", content: `@entity.${field.name}` }
6469
+ { type: "typography", variant: "body", content: `@item.${field.name}` }
6437
6470
  ]
6438
6471
  }));
6439
6472
  return {
@@ -6457,24 +6490,20 @@ function buildReviewUI(c) {
6457
6490
  {
6458
6491
  type: "data-list",
6459
6492
  entity: c.entityName,
6460
- children: [
6461
- {
6462
- type: "stack",
6463
- direction: "vertical",
6464
- gap: "sm",
6465
- children: reviewDetailChildren
6466
- }
6467
- ]
6493
+ renderItem: ["fn", "item", {
6494
+ type: "stack",
6495
+ direction: "vertical",
6496
+ gap: "sm",
6497
+ children: reviewDetailChildren
6498
+ }]
6468
6499
  },
6469
6500
  {
6470
- type: "stack",
6471
- direction: "horizontal",
6472
- gap: "sm",
6473
- justify: "end",
6474
- children: [
6475
- { type: "button", label: "Back", event: "PREV", variant: "ghost", icon: "arrow-left" },
6476
- { type: "button", label: c.submitButtonLabel, event: "COMPLETE", variant: "primary", icon: "check" }
6477
- ]
6501
+ type: "wizard-navigation",
6502
+ currentStep: c.totalSteps,
6503
+ totalSteps: c.totalSteps + 1,
6504
+ showBack: true,
6505
+ showComplete: true,
6506
+ showNext: false
6478
6507
  }
6479
6508
  ]
6480
6509
  };
@@ -6640,20 +6669,28 @@ function resolve18(params) {
6640
6669
  isInitial: params.isInitial ?? false
6641
6670
  };
6642
6671
  }
6672
+ var ef6 = (field) => ["object/get", ["array/first", "@entity"], field];
6643
6673
  function buildTrait17(c) {
6644
6674
  const { entityName, displayFields, headerIcon, pageTitle, refreshButtonLabel, columns } = c;
6645
- const cardChildren = displayFields.map((f) => ({
6646
- type: "card",
6647
- children: [{
6648
- type: "stack",
6649
- direction: "vertical",
6650
- gap: "sm",
6651
- children: [
6652
- { type: "typography", variant: "caption", content: f.charAt(0).toUpperCase() + f.slice(1) },
6653
- { type: "typography", variant: "h3", content: `@entity.${f}` }
6654
- ]
6655
- }]
6656
- }));
6675
+ const cardChildren = displayFields.map((f) => {
6676
+ const field = c.nonIdFields.find((nf) => nf.name === f);
6677
+ const isNumeric = field?.type === "number";
6678
+ if (isNumeric) {
6679
+ return { type: "stat-display", label: f.charAt(0).toUpperCase() + f.slice(1), value: ef6(f) };
6680
+ }
6681
+ return {
6682
+ type: "card",
6683
+ children: [{
6684
+ type: "stack",
6685
+ direction: "vertical",
6686
+ gap: "sm",
6687
+ children: [
6688
+ { type: "typography", variant: "caption", content: f.charAt(0).toUpperCase() + f.slice(1) },
6689
+ { type: "typography", variant: "h3", content: ef6(f) }
6690
+ ]
6691
+ }]
6692
+ };
6693
+ });
6657
6694
  const mainView = {
6658
6695
  type: "stack",
6659
6696
  direction: "vertical",
@@ -6758,6 +6795,7 @@ function buildTrait18(c) {
6758
6795
  ]
6759
6796
  },
6760
6797
  { type: "divider" },
6798
+ { type: "typography", variant: "body", color: "muted", content: `Ready to start ${entityName.toLowerCase()} operation.` },
6761
6799
  { type: "button", label: "Start", event: "START", variant: "primary", icon: "play" }
6762
6800
  ]
6763
6801
  };
@@ -6767,8 +6805,8 @@ function buildTrait18(c) {
6767
6805
  gap: "lg",
6768
6806
  align: "center",
6769
6807
  children: [
6770
- { type: "icon", name: "loader", size: "lg" },
6771
- { type: "typography", content: loadingMessage, variant: "h3" }
6808
+ { type: "loading-state", title: loadingMessage, message: `Processing ${entityName.toLowerCase()}...` },
6809
+ { type: "skeleton", variant: "text" }
6772
6810
  ]
6773
6811
  };
6774
6812
  const successUI = {
@@ -6778,7 +6816,7 @@ function buildTrait18(c) {
6778
6816
  align: "center",
6779
6817
  children: [
6780
6818
  { type: "icon", name: "check-circle", size: "lg" },
6781
- { type: "typography", content: successMessage, variant: "h3" },
6819
+ { type: "alert", variant: "success", message: successMessage },
6782
6820
  {
6783
6821
  type: "stack",
6784
6822
  direction: "horizontal",
@@ -6802,8 +6840,7 @@ function buildTrait18(c) {
6802
6840
  gap: "lg",
6803
6841
  align: "center",
6804
6842
  children: [
6805
- { type: "icon", name: "alert-circle", size: "lg" },
6806
- { type: "typography", content: errorMessage, variant: "h3" },
6843
+ { type: "error-state", title: "Operation Failed", message: errorMessage, onRetry: retryable ? "RETRY" : void 0 },
6807
6844
  {
6808
6845
  type: "stack",
6809
6846
  direction: "horizontal",
@@ -7134,6 +7171,7 @@ function resolve21(params) {
7134
7171
  function buildEntity19(c) {
7135
7172
  return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence, collection: c.collection });
7136
7173
  }
7174
+ var ef7 = (field) => ["object/get", ["array/first", "@entity"], field];
7137
7175
  function buildTrait20(c) {
7138
7176
  const { entityName, gameTitle, menuTitle, pauseTitle, gameoverTitle } = c;
7139
7177
  const menuUI = {
@@ -7147,8 +7185,8 @@ function buildTrait20(c) {
7147
7185
  const playingUI = {
7148
7186
  type: "game-hud",
7149
7187
  stats: [
7150
- { label: "Score", value: "@entity.score" },
7151
- { label: "Level", value: "@entity.level" }
7188
+ { label: "Score", value: ef7("score") },
7189
+ { label: "Level", value: ef7("level") }
7152
7190
  ]
7153
7191
  };
7154
7192
  const pausedModalUI = {
@@ -7163,8 +7201,8 @@ function buildTrait20(c) {
7163
7201
  type: "game-over-screen",
7164
7202
  title: gameoverTitle,
7165
7203
  stats: [
7166
- { label: "Score", value: "@entity.score" },
7167
- { label: "Level", value: "@entity.level" }
7204
+ { label: "Score", value: ef7("score") },
7205
+ { label: "Level", value: ef7("level") }
7168
7206
  ],
7169
7207
  menuItems: [
7170
7208
  { label: "Play Again", event: "RESTART", variant: "primary" },
@@ -7230,19 +7268,19 @@ function buildTrait20(c) {
7230
7268
  event: "PAUSE",
7231
7269
  effects: [["render-ui", "modal", pausedModalUI]]
7232
7270
  },
7233
- // RESUME: paused -> playing
7271
+ // RESUME: paused -> playing (dismiss modal, re-render main with HUD)
7234
7272
  {
7235
7273
  from: "paused",
7236
7274
  to: "playing",
7237
7275
  event: "RESUME",
7238
- effects: [["render-ui", "modal", null]]
7276
+ effects: [["render-ui", "modal", null], ["render-ui", "main", playingUI]]
7239
7277
  },
7240
7278
  // CLOSE: paused -> playing (modal exit requirement)
7241
7279
  {
7242
7280
  from: "paused",
7243
7281
  to: "playing",
7244
7282
  event: "CLOSE",
7245
- effects: [["render-ui", "modal", null]]
7283
+ effects: [["render-ui", "modal", null], ["render-ui", "main", playingUI]]
7246
7284
  },
7247
7285
  // GAME_OVER: playing -> gameover
7248
7286
  {
@@ -7314,19 +7352,35 @@ function resolve22(params) {
7314
7352
  };
7315
7353
  }
7316
7354
  function buildEntity20(c) {
7317
- return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence, collection: c.collection });
7355
+ const fields = [
7356
+ ...c.fields.filter((f) => !["x", "y"].includes(f.name)),
7357
+ { name: "x", type: "number", default: 0 },
7358
+ { name: "y", type: "number", default: 0 }
7359
+ ];
7360
+ return makeEntity({ name: c.entityName, fields, persistence: c.persistence, collection: c.collection });
7318
7361
  }
7362
+ var ef8 = (field) => ["object/get", ["array/first", "@entity"], field];
7319
7363
  function buildTrait21(c) {
7320
7364
  const { entityName, nonIdFields, headerIcon, pageTitle } = c;
7321
- const fieldSummaryChildren = nonIdFields.slice(0, 4).map((field) => ({
7322
- type: "stack",
7323
- direction: "horizontal",
7324
- gap: "md",
7325
- children: [
7326
- { type: "typography", variant: "caption", content: field.name.charAt(0).toUpperCase() + field.name.slice(1) },
7327
- { type: "typography", variant: "body", content: `@entity.${field.name}` }
7328
- ]
7329
- }));
7365
+ const fieldSummaryChildren = [
7366
+ {
7367
+ type: "simple-grid",
7368
+ columns: 2,
7369
+ children: [
7370
+ { type: "stat-display", label: "X", value: ef8(nonIdFields.find((f) => f.name === "x")?.name ?? "x") },
7371
+ { type: "stat-display", label: "Y", value: ef8(nonIdFields.find((f) => f.name === "y")?.name ?? "y") }
7372
+ ]
7373
+ },
7374
+ ...nonIdFields.slice(0, 4).filter((f) => f.name !== "x" && f.name !== "y").map((field) => ({
7375
+ type: "stack",
7376
+ direction: "horizontal",
7377
+ gap: "md",
7378
+ children: [
7379
+ { type: "typography", variant: "caption", content: field.name.charAt(0).toUpperCase() + field.name.slice(1) },
7380
+ { type: "typography", variant: "body", content: ef8(field.name) }
7381
+ ]
7382
+ }))
7383
+ ];
7330
7384
  const idleMainUI = {
7331
7385
  type: "stack",
7332
7386
  direction: "vertical",
@@ -7347,7 +7401,7 @@ function buildTrait21(c) {
7347
7401
  { type: "typography", content: pageTitle, variant: "h2" }
7348
7402
  ]
7349
7403
  },
7350
- { type: "badge", label: "Idle" }
7404
+ { type: "status-dot", status: "inactive", label: "Idle" }
7351
7405
  ]
7352
7406
  },
7353
7407
  { type: "divider" },
@@ -7384,7 +7438,7 @@ function buildTrait21(c) {
7384
7438
  { type: "typography", content: pageTitle, variant: "h2" }
7385
7439
  ]
7386
7440
  },
7387
- { type: "badge", label: "Moving" }
7441
+ { type: "status-dot", status: "active", pulse: true, label: "Moving" }
7388
7442
  ]
7389
7443
  },
7390
7444
  { type: "divider" },
@@ -7590,15 +7644,15 @@ function buildTrait22(c) {
7590
7644
  align: "center",
7591
7645
  children: [
7592
7646
  { type: "icon", name: headerIcon, size: "sm" },
7593
- { type: "typography", variant: "h4", content: `@entity.${listFields[0] ?? "id"}` }
7647
+ { type: "typography", variant: "h4", content: `@item.${listFields[0] ?? "id"}` }
7594
7648
  ]
7595
7649
  },
7596
- ...listFields.length > 1 ? [{ type: "badge", label: `@entity.${listFields[1]}` }] : []
7650
+ ...listFields.length > 1 ? [{ type: "badge", label: `@item.${listFields[1]}` }] : []
7597
7651
  ]
7598
7652
  }
7599
7653
  ];
7600
7654
  if (listFields.length > 2) {
7601
- listItemChildren.push({ type: "typography", variant: "caption", content: `@entity.${listFields[2]}` });
7655
+ listItemChildren.push({ type: "typography", variant: "caption", content: `@item.${listFields[2]}` });
7602
7656
  }
7603
7657
  const headerBar = {
7604
7658
  type: "stack",
@@ -7625,13 +7679,14 @@ function buildTrait22(c) {
7625
7679
  headerBar,
7626
7680
  { type: "divider" },
7627
7681
  {
7628
- type: "data-grid",
7682
+ type: "data-list",
7629
7683
  entity: entityName,
7684
+ groupBy: "status",
7630
7685
  emptyIcon: "inbox",
7631
7686
  emptyTitle,
7632
7687
  emptyDescription,
7633
7688
  itemActions: [{ label: "Accept", event: "ACCEPT" }],
7634
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
7689
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
7635
7690
  }
7636
7691
  ]
7637
7692
  };
@@ -7659,6 +7714,7 @@ function buildTrait22(c) {
7659
7714
  ]
7660
7715
  },
7661
7716
  { type: "divider" },
7717
+ { type: "progress-bar", value: 50, showPercentage: true },
7662
7718
  {
7663
7719
  type: "data-grid",
7664
7720
  entity: entityName,
@@ -7670,7 +7726,7 @@ function buildTrait22(c) {
7670
7726
  { label: "Complete", event: "COMPLETE" },
7671
7727
  { label: "Fail", event: "FAIL", variant: "danger" }
7672
7728
  ],
7673
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
7729
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
7674
7730
  }
7675
7731
  ]
7676
7732
  };
@@ -7682,7 +7738,7 @@ function buildTrait22(c) {
7682
7738
  children: [
7683
7739
  { type: "icon", name: "check-circle", size: "lg" },
7684
7740
  { type: "typography", content: "Quest Complete", variant: "h2" },
7685
- { type: "typography", content: "Congratulations! The quest has been completed.", variant: "body" },
7741
+ { type: "alert", variant: "success", message: "Congratulations! The quest has been completed." },
7686
7742
  { type: "button", label: "View Quests", event: "RESET", variant: "primary", icon: "arrow-left" }
7687
7743
  ]
7688
7744
  };
@@ -7694,7 +7750,7 @@ function buildTrait22(c) {
7694
7750
  children: [
7695
7751
  { type: "icon", name: "x-circle", size: "lg" },
7696
7752
  { type: "typography", content: "Quest Failed", variant: "h2" },
7697
- { type: "typography", content: "The quest was not completed. You can try again.", variant: "body" },
7753
+ { type: "alert", variant: "danger", message: "The quest was not completed. You can try again." },
7698
7754
  { type: "button", label: "View Quests", event: "RESET", variant: "primary", icon: "arrow-left" }
7699
7755
  ]
7700
7756
  };
@@ -7791,19 +7847,27 @@ function buildTrait22(c) {
7791
7847
  ["render-ui", "main", activeMainUI]
7792
7848
  ]
7793
7849
  },
7794
- // CANCEL: progressing -> active
7850
+ // CANCEL: progressing -> active (re-render main to avoid stale content)
7795
7851
  {
7796
7852
  from: "progressing",
7797
7853
  to: "active",
7798
7854
  event: "CANCEL",
7799
- effects: [["render-ui", "modal", null]]
7855
+ effects: [
7856
+ ["render-ui", "modal", null],
7857
+ ["fetch", entityName],
7858
+ ["render-ui", "main", activeMainUI]
7859
+ ]
7800
7860
  },
7801
- // CLOSE: progressing -> active
7861
+ // CLOSE: progressing -> active (re-render main to avoid stale content)
7802
7862
  {
7803
7863
  from: "progressing",
7804
7864
  to: "active",
7805
7865
  event: "CLOSE",
7806
- effects: [["render-ui", "modal", null]]
7866
+ effects: [
7867
+ ["render-ui", "modal", null],
7868
+ ["fetch", entityName],
7869
+ ["render-ui", "main", activeMainUI]
7870
+ ]
7807
7871
  },
7808
7872
  // COMPLETE: active -> complete
7809
7873
  {
@@ -7911,15 +7975,15 @@ function buildTrait23(c) {
7911
7975
  align: "center",
7912
7976
  children: [
7913
7977
  { type: "icon", name: "map-pin", size: "sm" },
7914
- { type: "typography", variant: "h4", content: `@entity.${listFields[0] ?? "id"}` }
7978
+ { type: "typography", variant: "h4", content: `@item.${listFields[0] ?? "id"}` }
7915
7979
  ]
7916
7980
  },
7917
- ...listFields.length > 1 ? [{ type: "badge", label: `@entity.${listFields[1]}` }] : []
7981
+ ...listFields.length > 1 ? [{ type: "badge", label: `@item.${listFields[1]}` }] : []
7918
7982
  ]
7919
7983
  }
7920
7984
  ];
7921
7985
  if (listFields.length > 2) {
7922
- listItemChildren.push({ type: "typography", variant: "caption", content: `@entity.${listFields[2]}` });
7986
+ listItemChildren.push({ type: "typography", variant: "caption", content: `@item.${listFields[2]}` });
7923
7987
  }
7924
7988
  const exploringMainUI = {
7925
7989
  type: "stack",
@@ -7941,10 +8005,11 @@ function buildTrait23(c) {
7941
8005
  { type: "typography", content: worldTitle, variant: "h2" }
7942
8006
  ]
7943
8007
  },
7944
- { type: "badge", label: "Exploring" }
8008
+ { type: "status-dot", status: "active", pulse: false, label: "Exploring" }
7945
8009
  ]
7946
8010
  },
7947
8011
  { type: "divider" },
8012
+ { type: "map-view", markers: [], height: "200px", zoom: 10 },
7948
8013
  {
7949
8014
  type: "data-grid",
7950
8015
  entity: entityName,
@@ -7952,7 +8017,7 @@ function buildTrait23(c) {
7952
8017
  emptyTitle,
7953
8018
  emptyDescription,
7954
8019
  itemActions: [{ label: "Travel", event: "TRAVEL" }],
7955
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
8020
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
7956
8021
  }
7957
8022
  ]
7958
8023
  };
@@ -7995,7 +8060,7 @@ function buildTrait23(c) {
7995
8060
  { type: "typography", content: pageTitle, variant: "h2" }
7996
8061
  ]
7997
8062
  },
7998
- { type: "badge", label: "Entered" }
8063
+ { type: "status-dot", status: "success", label: "Entered" }
7999
8064
  ]
8000
8065
  },
8001
8066
  { type: "divider" },
@@ -8005,7 +8070,7 @@ function buildTrait23(c) {
8005
8070
  emptyIcon: "inbox",
8006
8071
  emptyTitle: "Nothing here",
8007
8072
  emptyDescription: "This zone is empty.",
8008
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
8073
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
8009
8074
  },
8010
8075
  { type: "divider" },
8011
8076
  {
@@ -8120,50 +8185,79 @@ function resolve25(params) {
8120
8185
  };
8121
8186
  }
8122
8187
  function buildEntity23(c) {
8123
- return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence, collection: c.collection });
8188
+ const fields = [
8189
+ ...c.fields.filter((f) => !["failureCount", "successCount", "threshold"].includes(f.name)),
8190
+ { name: "failureCount", type: "number", default: 0 },
8191
+ { name: "successCount", type: "number", default: 0 },
8192
+ { name: "threshold", type: "number", default: 5 }
8193
+ ];
8194
+ return makeEntity({ name: c.entityName, fields, persistence: c.persistence, collection: c.collection });
8124
8195
  }
8196
+ var ef9 = (field) => ["object/get", ["array/first", "@entity"], field];
8125
8197
  function buildTrait24(c) {
8126
8198
  const { entityName, headerIcon, closedLabel, openLabel, halfOpenLabel } = c;
8127
8199
  const closedUI = {
8128
8200
  type: "stack",
8129
8201
  direction: "vertical",
8130
8202
  gap: "lg",
8131
- align: "center",
8132
8203
  children: [
8133
8204
  {
8134
8205
  type: "stack",
8135
8206
  direction: "horizontal",
8136
8207
  gap: "md",
8137
8208
  align: "center",
8209
+ justify: "space-between",
8138
8210
  children: [
8139
- { type: "icon", name: headerIcon, size: "lg" },
8140
- { type: "typography", content: entityName, variant: "h2" }
8211
+ { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
8212
+ { type: "icon", name: headerIcon, size: "lg" },
8213
+ { type: "typography", content: entityName, variant: "h2" }
8214
+ ] },
8215
+ { type: "status-dot", status: "success", pulse: false, label: closedLabel }
8141
8216
  ]
8142
8217
  },
8143
8218
  { type: "divider" },
8144
- { type: "badge", label: closedLabel },
8145
- { type: "typography", content: "Service is healthy. All requests are being processed.", variant: "body" }
8219
+ { type: "alert", variant: "success", message: "Service is healthy. All requests are being processed." },
8220
+ {
8221
+ type: "simple-grid",
8222
+ columns: 2,
8223
+ children: [
8224
+ { type: "stat-display", label: "Failures", value: ef9("failureCount") },
8225
+ { type: "stat-display", label: "Successes", value: ef9("successCount") }
8226
+ ]
8227
+ },
8228
+ { type: "meter", value: ef9("failureCount"), min: 0, max: ef9("threshold") }
8146
8229
  ]
8147
8230
  };
8148
8231
  const openUI = {
8149
8232
  type: "stack",
8150
8233
  direction: "vertical",
8151
8234
  gap: "lg",
8152
- align: "center",
8153
8235
  children: [
8154
8236
  {
8155
8237
  type: "stack",
8156
8238
  direction: "horizontal",
8157
8239
  gap: "md",
8158
8240
  align: "center",
8241
+ justify: "space-between",
8159
8242
  children: [
8160
- { type: "icon", name: "alert-triangle", size: "lg" },
8161
- { type: "typography", content: entityName, variant: "h2" }
8243
+ { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
8244
+ { type: "icon", name: "alert-triangle", size: "lg" },
8245
+ { type: "typography", content: entityName, variant: "h2" }
8246
+ ] },
8247
+ { type: "status-dot", status: "error", pulse: true, label: openLabel }
8162
8248
  ]
8163
8249
  },
8164
8250
  { type: "divider" },
8165
- { type: "badge", label: openLabel },
8166
- { type: "typography", content: "Circuit is open. Requests are being rejected to prevent cascading failures.", variant: "body" },
8251
+ { type: "alert", variant: "danger", message: "Circuit is open. Requests are being rejected to prevent cascading failures." },
8252
+ {
8253
+ type: "simple-grid",
8254
+ columns: 2,
8255
+ children: [
8256
+ { type: "stat-display", label: "Failures", value: ef9("failureCount") },
8257
+ { type: "stat-display", label: "Successes", value: ef9("successCount") }
8258
+ ]
8259
+ },
8260
+ { type: "meter", value: ef9("failureCount"), min: 0, max: ef9("threshold") },
8167
8261
  { type: "button", label: "Reset", event: "RESET", variant: "ghost", icon: "rotate-ccw" }
8168
8262
  ]
8169
8263
  };
@@ -8171,21 +8265,31 @@ function buildTrait24(c) {
8171
8265
  type: "stack",
8172
8266
  direction: "vertical",
8173
8267
  gap: "lg",
8174
- align: "center",
8175
8268
  children: [
8176
8269
  {
8177
8270
  type: "stack",
8178
8271
  direction: "horizontal",
8179
8272
  gap: "md",
8180
8273
  align: "center",
8274
+ justify: "space-between",
8181
8275
  children: [
8182
- { type: "icon", name: "activity", size: "lg" },
8183
- { type: "typography", content: entityName, variant: "h2" }
8276
+ { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
8277
+ { type: "icon", name: "activity", size: "lg" },
8278
+ { type: "typography", content: entityName, variant: "h2" }
8279
+ ] },
8280
+ { type: "status-dot", status: "warning", pulse: true, label: halfOpenLabel }
8184
8281
  ]
8185
8282
  },
8186
8283
  { type: "divider" },
8187
- { type: "badge", label: halfOpenLabel },
8188
- { type: "typography", content: "Testing recovery. Limited requests are being allowed through.", variant: "body" }
8284
+ { type: "alert", variant: "warning", message: "Testing recovery. Limited requests are being allowed through." },
8285
+ {
8286
+ type: "simple-grid",
8287
+ columns: 2,
8288
+ children: [
8289
+ { type: "stat-display", label: "Failures", value: ef9("failureCount") },
8290
+ { type: "stat-display", label: "Successes", value: ef9("successCount") }
8291
+ ]
8292
+ }
8189
8293
  ]
8190
8294
  };
8191
8295
  return {
@@ -8314,8 +8418,14 @@ function resolve26(params) {
8314
8418
  };
8315
8419
  }
8316
8420
  function buildEntity24(c) {
8317
- return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence, collection: c.collection });
8421
+ const fields = [
8422
+ ...c.fields.filter((f) => !["hitCount", "cacheAge"].includes(f.name)),
8423
+ { name: "hitCount", type: "number", default: 0 },
8424
+ { name: "cacheAge", type: "number", default: 0 }
8425
+ ];
8426
+ return makeEntity({ name: c.entityName, fields, persistence: c.persistence, collection: c.collection });
8318
8427
  }
8428
+ var ef10 = (field) => ["object/get", ["array/first", "@entity"], field];
8319
8429
  function buildTrait25(c) {
8320
8430
  const { entityName, listFields, headerIcon } = c;
8321
8431
  const { pageTitle, emptyTitle, emptyDescription } = c;
@@ -8333,15 +8443,15 @@ function buildTrait25(c) {
8333
8443
  align: "center",
8334
8444
  children: [
8335
8445
  { type: "icon", name: headerIcon, size: "sm" },
8336
- { type: "typography", variant: "h4", content: `@entity.${listFields[0] ?? "id"}` }
8446
+ { type: "typography", variant: "h4", content: `@item.${listFields[0] ?? "id"}` }
8337
8447
  ]
8338
8448
  },
8339
- ...listFields.length > 1 ? [{ type: "badge", label: `@entity.${listFields[1]}` }] : []
8449
+ ...listFields.length > 1 ? [{ type: "badge", label: `@item.${listFields[1]}` }] : []
8340
8450
  ]
8341
8451
  }
8342
8452
  ];
8343
8453
  if (listFields.length > 2) {
8344
- listItemChildren.push({ type: "typography", variant: "caption", content: `@entity.${listFields[2]}` });
8454
+ listItemChildren.push({ type: "typography", variant: "caption", content: `@item.${listFields[2]}` });
8345
8455
  }
8346
8456
  const headerBar = {
8347
8457
  type: "stack",
@@ -8366,7 +8476,16 @@ function buildTrait25(c) {
8366
8476
  direction: "vertical",
8367
8477
  gap: "lg",
8368
8478
  children: [
8369
- headerBar,
8479
+ {
8480
+ type: "stack",
8481
+ direction: "horizontal",
8482
+ gap: "md",
8483
+ justify: "space-between",
8484
+ children: [
8485
+ headerBar,
8486
+ { type: "status-dot", status: "inactive", pulse: false, label: "Empty" }
8487
+ ]
8488
+ },
8370
8489
  { type: "divider" },
8371
8490
  { type: "empty-state", icon: "inbox", title: emptyTitle, description: emptyDescription }
8372
8491
  ]
@@ -8395,21 +8514,30 @@ function buildTrait25(c) {
8395
8514
  type: "stack",
8396
8515
  direction: "horizontal",
8397
8516
  gap: "sm",
8517
+ align: "center",
8398
8518
  children: [
8399
- { type: "badge", label: "Cached" },
8519
+ { type: "status-dot", status: "success", pulse: false, label: "Cached" },
8400
8520
  { type: "button", label: "Invalidate", event: "INVALIDATE", variant: "ghost", icon: "trash" }
8401
8521
  ]
8402
8522
  }
8403
8523
  ]
8404
8524
  },
8405
8525
  { type: "divider" },
8526
+ {
8527
+ type: "simple-grid",
8528
+ columns: 2,
8529
+ children: [
8530
+ { type: "stat-display", label: "Hit Count", value: ef10("hitCount") },
8531
+ { type: "stat-display", label: "Cache Age", value: ef10("cacheAge") }
8532
+ ]
8533
+ },
8406
8534
  {
8407
8535
  type: "data-grid",
8408
8536
  entity: entityName,
8409
8537
  emptyIcon: "inbox",
8410
8538
  emptyTitle,
8411
8539
  emptyDescription,
8412
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
8540
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
8413
8541
  }
8414
8542
  ]
8415
8543
  };
@@ -8437,21 +8565,23 @@ function buildTrait25(c) {
8437
8565
  type: "stack",
8438
8566
  direction: "horizontal",
8439
8567
  gap: "sm",
8568
+ align: "center",
8440
8569
  children: [
8441
- { type: "badge", label: "Stale" },
8570
+ { type: "status-dot", status: "warning", pulse: true, label: "Stale" },
8442
8571
  { type: "button", label: "Refresh", event: "REFRESH", variant: "primary", icon: "refresh-cw" }
8443
8572
  ]
8444
8573
  }
8445
8574
  ]
8446
8575
  },
8447
8576
  { type: "divider" },
8577
+ { type: "alert", variant: "warning", message: "Cache data is stale. Refresh to get the latest data." },
8448
8578
  {
8449
8579
  type: "data-grid",
8450
8580
  entity: entityName,
8451
8581
  emptyIcon: "inbox",
8452
8582
  emptyTitle,
8453
8583
  emptyDescription,
8454
- children: [{ type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
8584
+ renderItem: ["fn", "item", { type: "stack", direction: "vertical", gap: "sm", children: listItemChildren }]
8455
8585
  }
8456
8586
  ]
8457
8587
  };
@@ -8595,6 +8725,7 @@ function resolve27(params) {
8595
8725
  function buildEntity25(c) {
8596
8726
  return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence });
8597
8727
  }
8728
+ var ef11 = (field) => ["object/get", ["array/first", "@entity"], field];
8598
8729
  function buildTrait26(c) {
8599
8730
  const { entityName } = c;
8600
8731
  const scoreView = {
@@ -8605,12 +8736,14 @@ function buildTrait26(c) {
8605
8736
  children: [
8606
8737
  {
8607
8738
  type: "score-board",
8608
- score: "@entity.total",
8739
+ score: ef11("total"),
8609
8740
  highScore: 0,
8610
- combo: "@entity.combo",
8741
+ combo: ef11("combo"),
8611
8742
  multiplier: 1,
8612
8743
  level: 1
8613
8744
  },
8745
+ { type: "animated-counter", value: ef11("total"), prefix: "Score: ", duration: 300 },
8746
+ { type: "trend-indicator", value: ef11("points"), showValue: true },
8614
8747
  {
8615
8748
  type: "stack",
8616
8749
  direction: "horizontal",
@@ -8743,46 +8876,35 @@ function resolve28(params) {
8743
8876
  function buildEntity26(c) {
8744
8877
  return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence });
8745
8878
  }
8879
+ var ef12 = (field) => ["object/get", ["array/first", "@entity"], field];
8746
8880
  function buildTrait27(c) {
8747
8881
  const { entityName, headerIcon, pageTitle } = c;
8748
8882
  const idleView = {
8749
8883
  type: "stack",
8750
8884
  direction: "vertical",
8751
8885
  gap: "lg",
8752
- align: "center",
8753
8886
  children: [
8754
8887
  {
8755
8888
  type: "stack",
8756
8889
  direction: "horizontal",
8757
8890
  gap: "md",
8758
8891
  align: "center",
8892
+ justify: "space-between",
8759
8893
  children: [
8760
- { type: "icon", name: headerIcon, size: "lg" },
8761
- { type: "typography", content: pageTitle, variant: "h2" }
8894
+ { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
8895
+ { type: "icon", name: headerIcon, size: "lg" },
8896
+ { type: "typography", content: pageTitle, variant: "h2" }
8897
+ ] },
8898
+ { type: "status-dot", status: "inactive", label: "Idle" }
8762
8899
  ]
8763
8900
  },
8764
8901
  { type: "divider" },
8765
8902
  {
8766
- type: "card",
8903
+ type: "simple-grid",
8904
+ columns: 2,
8767
8905
  children: [
8768
- {
8769
- type: "stack",
8770
- direction: "vertical",
8771
- gap: "sm",
8772
- children: [
8773
- { type: "typography", content: "Position", variant: "caption" },
8774
- {
8775
- type: "stack",
8776
- direction: "horizontal",
8777
- gap: "md",
8778
- children: [
8779
- { type: "typography", content: "@entity.x", variant: "body" },
8780
- { type: "typography", content: "@entity.y", variant: "body" }
8781
- ]
8782
- },
8783
- { type: "badge", label: "@entity.collisionStatus" }
8784
- ]
8785
- }
8906
+ { type: "stat-display", label: "X", value: ef12("x") },
8907
+ { type: "stat-display", label: "Y", value: ef12("y") }
8786
8908
  ]
8787
8909
  },
8788
8910
  {
@@ -8800,43 +8922,32 @@ function buildTrait27(c) {
8800
8922
  type: "stack",
8801
8923
  direction: "vertical",
8802
8924
  gap: "lg",
8803
- align: "center",
8804
8925
  children: [
8805
8926
  {
8806
8927
  type: "stack",
8807
8928
  direction: "horizontal",
8808
8929
  gap: "md",
8809
8930
  align: "center",
8931
+ justify: "space-between",
8810
8932
  children: [
8811
- { type: "icon", name: headerIcon, size: "lg" },
8812
- { type: "typography", content: pageTitle, variant: "h2" }
8933
+ { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
8934
+ { type: "icon", name: headerIcon, size: "lg" },
8935
+ { type: "typography", content: pageTitle, variant: "h2" }
8936
+ ] },
8937
+ { type: "status-dot", status: "warning", pulse: true, label: "Detecting" }
8813
8938
  ]
8814
8939
  },
8815
8940
  { type: "divider" },
8941
+ { type: "alert", variant: "warning", message: "Collision detection in progress..." },
8816
8942
  {
8817
- type: "card",
8943
+ type: "simple-grid",
8944
+ columns: 2,
8818
8945
  children: [
8819
- {
8820
- type: "stack",
8821
- direction: "vertical",
8822
- gap: "sm",
8823
- children: [
8824
- { type: "typography", content: "Position", variant: "caption" },
8825
- {
8826
- type: "stack",
8827
- direction: "horizontal",
8828
- gap: "md",
8829
- children: [
8830
- { type: "typography", content: "@entity.x", variant: "body" },
8831
- { type: "typography", content: "@entity.y", variant: "body" }
8832
- ]
8833
- },
8834
- { type: "badge", label: "Detecting..." },
8835
- { type: "typography", content: "@entity.targetId", variant: "body" }
8836
- ]
8837
- }
8946
+ { type: "stat-display", label: "X", value: ef12("x") },
8947
+ { type: "stat-display", label: "Y", value: ef12("y") }
8838
8948
  ]
8839
8949
  },
8950
+ { type: "typography", variant: "caption", color: "muted", content: ef12("targetId") },
8840
8951
  {
8841
8952
  type: "stack",
8842
8953
  direction: "horizontal",
@@ -9129,40 +9240,39 @@ function resolve30(params) {
9129
9240
  function buildEntity28(c) {
9130
9241
  return makeEntity({ name: c.entityName, fields: c.fields, persistence: c.persistence });
9131
9242
  }
9243
+ var ef13 = (field) => ["object/get", ["array/first", "@entity"], field];
9132
9244
  function buildTrait29(c) {
9133
9245
  const { entityName, headerIcon, pageTitle } = c;
9134
9246
  const openView = {
9135
9247
  type: "stack",
9136
9248
  direction: "vertical",
9137
9249
  gap: "lg",
9138
- align: "center",
9139
9250
  children: [
9140
9251
  {
9141
9252
  type: "stack",
9142
9253
  direction: "horizontal",
9143
9254
  gap: "md",
9144
9255
  align: "center",
9256
+ justify: "space-between",
9145
9257
  children: [
9146
- { type: "icon", name: headerIcon, size: "lg" },
9147
- { type: "typography", content: pageTitle, variant: "h2" }
9258
+ { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
9259
+ { type: "icon", name: headerIcon, size: "lg" },
9260
+ { type: "typography", content: pageTitle, variant: "h2" }
9261
+ ] },
9262
+ { type: "status-dot", status: "success", pulse: false, label: "Open" }
9148
9263
  ]
9149
9264
  },
9150
9265
  { type: "divider" },
9151
9266
  {
9152
- type: "card",
9267
+ type: "simple-grid",
9268
+ columns: 2,
9153
9269
  children: [
9154
- {
9155
- type: "stack",
9156
- direction: "vertical",
9157
- gap: "sm",
9158
- children: [
9159
- { type: "typography", content: "Requests", variant: "caption" },
9160
- { type: "typography", content: "@entity.count", variant: "h4" },
9161
- { type: "badge", label: "@entity.limiterStatus" }
9162
- ]
9163
- }
9270
+ { type: "stat-display", label: "Requests", value: ef13("count") },
9271
+ { type: "stat-display", label: "Window", value: ef13("window") }
9164
9272
  ]
9165
9273
  },
9274
+ { type: "meter", value: ef13("count"), min: 0, max: 100 },
9275
+ { type: "progress-bar", value: ef13("count"), max: 100, showPercentage: true },
9166
9276
  {
9167
9277
  type: "stack",
9168
9278
  direction: "horizontal",
@@ -9179,34 +9289,32 @@ function buildTrait29(c) {
9179
9289
  type: "stack",
9180
9290
  direction: "vertical",
9181
9291
  gap: "lg",
9182
- align: "center",
9183
9292
  children: [
9184
9293
  {
9185
9294
  type: "stack",
9186
9295
  direction: "horizontal",
9187
9296
  gap: "md",
9188
9297
  align: "center",
9298
+ justify: "space-between",
9189
9299
  children: [
9190
- { type: "icon", name: headerIcon, size: "lg" },
9191
- { type: "typography", content: pageTitle, variant: "h2" }
9300
+ { type: "stack", direction: "horizontal", gap: "md", align: "center", children: [
9301
+ { type: "icon", name: headerIcon, size: "lg" },
9302
+ { type: "typography", content: pageTitle, variant: "h2" }
9303
+ ] },
9304
+ { type: "status-dot", status: "error", pulse: true, label: "Throttled" }
9192
9305
  ]
9193
9306
  },
9194
9307
  { type: "divider" },
9308
+ { type: "alert", variant: "danger", message: "Rate limit exceeded. Requests are being throttled." },
9195
9309
  {
9196
- type: "card",
9310
+ type: "simple-grid",
9311
+ columns: 2,
9197
9312
  children: [
9198
- {
9199
- type: "stack",
9200
- direction: "vertical",
9201
- gap: "sm",
9202
- children: [
9203
- { type: "typography", content: "Requests", variant: "caption" },
9204
- { type: "typography", content: "@entity.count", variant: "h4" },
9205
- { type: "badge", label: "Throttled" }
9206
- ]
9207
- }
9313
+ { type: "stat-display", label: "Requests", value: ef13("count") },
9314
+ { type: "stat-display", label: "Window", value: ef13("window") }
9208
9315
  ]
9209
9316
  },
9317
+ { type: "meter", value: ef13("count"), min: 0, max: 100 },
9210
9318
  {
9211
9319
  type: "stack",
9212
9320
  direction: "horizontal",
@@ -10670,6 +10778,11 @@ function stdList(params) {
10670
10778
  if (!existingKeys.has("CONFIRM_DELETE")) sm.events.push({ key: "CONFIRM_DELETE", name: "Confirm Delete" });
10671
10779
  if (!existingKeys.has("CANCEL")) sm.events.push({ key: "CANCEL", name: "Cancel" });
10672
10780
  if (!existingKeys.has("CLOSE")) sm.events.push({ key: "CLOSE", name: "Close" });
10781
+ const initTransition = sm.transitions[0];
10782
+ const initRenderEffect = initTransition.effects.find(
10783
+ (e) => Array.isArray(e) && e[0] === "render-ui" && e[1] === "main"
10784
+ );
10785
+ const browseMainView = initRenderEffect ? initRenderEffect[2] : null;
10673
10786
  sm.transitions.push(
10674
10787
  // DELETE: browsing → deleting (fetch entity by ID, show confirmation modal)
10675
10788
  { from: "browsing", to: "deleting", event: "DELETE", effects: [
@@ -10692,15 +10805,24 @@ function stdList(params) {
10692
10805
  ]
10693
10806
  }]
10694
10807
  ] },
10695
- // CONFIRM_DELETE: deleting → browsing (persist delete using selected entity's ID)
10808
+ // CONFIRM_DELETE: deleting → browsing (persist delete, dismiss modal, re-render main)
10696
10809
  { from: "deleting", to: "browsing", event: "CONFIRM_DELETE", effects: [
10697
10810
  ["persist", "delete", entityName, "@entity.id"],
10698
10811
  ["render-ui", "modal", null],
10699
- ["fetch", entityName]
10812
+ ["fetch", entityName],
10813
+ ["render-ui", "main", browseMainView]
10814
+ ] },
10815
+ // CANCEL/CLOSE from deleting (dismiss modal, re-render main)
10816
+ { from: "deleting", to: "browsing", event: "CANCEL", effects: [
10817
+ ["render-ui", "modal", null],
10818
+ ["fetch", entityName],
10819
+ ["render-ui", "main", browseMainView]
10700
10820
  ] },
10701
- // CANCEL/CLOSE from deleting
10702
- { from: "deleting", to: "browsing", event: "CANCEL", effects: [["render-ui", "modal", null]] },
10703
- { from: "deleting", to: "browsing", event: "CLOSE", effects: [["render-ui", "modal", null]] }
10821
+ { from: "deleting", to: "browsing", event: "CLOSE", effects: [
10822
+ ["render-ui", "modal", null],
10823
+ ["fetch", entityName],
10824
+ ["render-ui", "main", browseMainView]
10825
+ ] }
10704
10826
  );
10705
10827
  const entity = makeEntity({ name: entityName, fields, persistence: c.persistence, collection: c.collection });
10706
10828
  const page = {
@@ -11644,19 +11766,19 @@ function buildBattleFlowTrait(c) {
11644
11766
  event: "PAUSE",
11645
11767
  effects: [["render-ui", "modal", pausedModalUI]]
11646
11768
  },
11647
- // RESUME: paused -> playing
11769
+ // RESUME: paused -> playing (dismiss modal, re-render main)
11648
11770
  {
11649
11771
  from: "paused",
11650
11772
  to: "playing",
11651
11773
  event: "RESUME",
11652
- effects: [["render-ui", "modal", null]]
11774
+ effects: [["render-ui", "modal", null], ["render-ui", "main", playingUI]]
11653
11775
  },
11654
11776
  // CLOSE: paused -> playing (modal exit requirement)
11655
11777
  {
11656
11778
  from: "paused",
11657
11779
  to: "playing",
11658
11780
  event: "CLOSE",
11659
- effects: [["render-ui", "modal", null]]
11781
+ effects: [["render-ui", "modal", null], ["render-ui", "main", playingUI]]
11660
11782
  },
11661
11783
  // GAME_OVER: playing -> gameover
11662
11784
  {
@@ -11911,19 +12033,19 @@ function buildPlatformerFlowTrait(c) {
11911
12033
  event: "PAUSE",
11912
12034
  effects: [["render-ui", "modal", pausedModalUI]]
11913
12035
  },
11914
- // RESUME: paused -> playing
12036
+ // RESUME: paused -> playing (dismiss modal, re-render main)
11915
12037
  {
11916
12038
  from: "paused",
11917
12039
  to: "playing",
11918
12040
  event: "RESUME",
11919
- effects: [["render-ui", "modal", null]]
12041
+ effects: [["render-ui", "modal", null], ["render-ui", "main", playingUI]]
11920
12042
  },
11921
12043
  // CLOSE: paused -> playing (modal exit requirement)
11922
12044
  {
11923
12045
  from: "paused",
11924
12046
  to: "playing",
11925
12047
  event: "CLOSE",
11926
- effects: [["render-ui", "modal", null]]
12048
+ effects: [["render-ui", "modal", null], ["render-ui", "main", playingUI]]
11927
12049
  },
11928
12050
  // GAME_OVER: playing -> gameover
11929
12051
  {
@@ -12163,19 +12285,19 @@ function buildPuzzleFlowTrait(c) {
12163
12285
  event: "PAUSE",
12164
12286
  effects: [["render-ui", "modal", pausedModalUI]]
12165
12287
  },
12166
- // RESUME: paused -> playing
12288
+ // RESUME: paused -> playing (dismiss modal, re-render main)
12167
12289
  {
12168
12290
  from: "paused",
12169
12291
  to: "playing",
12170
12292
  event: "RESUME",
12171
- effects: [["render-ui", "modal", null]]
12293
+ effects: [["render-ui", "modal", null], ["render-ui", "main", playingUI]]
12172
12294
  },
12173
12295
  // CLOSE: paused -> playing (modal exit requirement)
12174
12296
  {
12175
12297
  from: "paused",
12176
12298
  to: "playing",
12177
12299
  event: "CLOSE",
12178
- effects: [["render-ui", "modal", null]]
12300
+ effects: [["render-ui", "modal", null], ["render-ui", "main", playingUI]]
12179
12301
  },
12180
12302
  // GAME_OVER: playing -> gameover
12181
12303
  {