@almadar/std 16.239.0 → 16.242.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/behaviors/behaviors-registry.json +4814 -553
  2. package/behaviors/lolo/agent/atoms/std-agent-memory.lolo +38 -1
  3. package/behaviors/lolo/agent/atoms/std-agent-session.lolo +1074 -47
  4. package/behaviors/lolo/agent/atoms/std-agent-tool-loop.lolo +8 -7
  5. package/behaviors/lolo/agent/organisms/std-agent-assistant.lolo +56 -37
  6. package/behaviors/lolo/infra/atoms/std-page-open.lolo +59 -0
  7. package/behaviors/lolo/infra/atoms/std-page-search.lolo +134 -0
  8. package/behaviors/lolo/infra/atoms/std-page-treat.lolo +59 -0
  9. package/behaviors/lolo/infra/atoms/std-page-watch.lolo +86 -0
  10. package/behaviors/lolo/ui/core/atoms/std-board.lolo +53 -6
  11. package/behaviors/lolo/ui/core/atoms/std-book-reader.lolo +25 -1
  12. package/behaviors/lolo/ui/core/atoms/std-card-grid.lolo +9 -0
  13. package/behaviors/lolo/ui/core/atoms/std-doc-page.lolo +153 -0
  14. package/behaviors/lolo/ui/core/atoms/std-site-header.lolo +15 -3
  15. package/behaviors/lolo/ui/core/atoms/std-tag-strip.lolo +2 -2
  16. package/behaviors/lolo/ui/core/atoms/std-tag-taxonomy.lolo +7 -7
  17. package/behaviors/lolo/ui/core/atoms/std-version-history.lolo +1 -1
  18. package/behaviors/lolo/ui/core/molecules/ui-header.lolo +5 -0
  19. package/behaviors/lolo/ui/learning/atoms/std-learn-arrangement.lolo +124 -92
  20. package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +114 -55
  21. package/behaviors/lolo/ui/learning/atoms/std-learn-compare.lolo +40 -14
  22. package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +363 -123
  23. package/behaviors/lolo/ui/learning/atoms/std-learn-derivation.lolo +93 -48
  24. package/behaviors/lolo/ui/learning/atoms/std-learn-diagram.lolo +60 -28
  25. package/behaviors/lolo/ui/learning/atoms/std-learn-doser.lolo +193 -96
  26. package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +75 -32
  27. package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +142 -86
  28. package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +266 -98
  29. package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +103 -65
  30. package/behaviors/lolo/ui/learning/atoms/std-learn-live-sim.lolo +223 -109
  31. package/behaviors/lolo/ui/learning/atoms/std-learn-measure.lolo +232 -64
  32. package/behaviors/lolo/ui/learning/atoms/std-learn-param-explorer.lolo +69 -29
  33. package/behaviors/lolo/ui/learning/atoms/std-learn-perturb.lolo +363 -123
  34. package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +73 -41
  35. package/behaviors/lolo/ui/learning/atoms/std-learn-sample-accumulator.lolo +96 -38
  36. package/behaviors/lolo/ui/learning/atoms/std-learn-sandbox.lolo +65 -45
  37. package/behaviors/lolo/ui/learning/atoms/std-learn-scatter-fit.lolo +243 -117
  38. package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +76 -28
  39. package/behaviors/lolo/ui/learning/atoms/std-learn-sim-3d.lolo +228 -109
  40. package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +95 -44
  41. package/behaviors/lolo/ui/learning/atoms/std-learn-stepper.lolo +199 -125
  42. package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +92 -48
  43. package/behaviors/lolo/ui/learning/atoms/std-learn-trace-player.lolo +239 -78
  44. package/behaviors/lolo/ui/learning/atoms/std-learn-transport.lolo +147 -38
  45. package/behaviors/lolo/ui/learning/atoms/std-learn-tree.lolo +123 -58
  46. package/behaviors/lolo/ui/learning/atoms/ui-algo-graph-canvas.lolo +22 -0
  47. package/behaviors/lolo/ui/learning/atoms/ui-algorithm-canvas.lolo +26 -0
  48. package/behaviors/lolo/ui/learning/atoms/ui-biology-canvas.lolo +26 -0
  49. package/behaviors/lolo/ui/learning/atoms/ui-chemistry-canvas.lolo +27 -1
  50. package/behaviors/lolo/ui/learning/atoms/ui-learning-canvas.lolo +27 -1
  51. package/behaviors/lolo/ui/learning/atoms/ui-math-canvas.lolo +29 -9
  52. package/behaviors/lolo/ui/learning/atoms/ui-physics-canvas.lolo +26 -0
  53. package/behaviors/lolo-behavior-contracts.json +1 -1
  54. package/behaviors/registry/agent/atoms/std-agent-memory.orb +372 -2
  55. package/behaviors/registry/agent/atoms/std-agent-session.orb +4752 -348
  56. package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +54 -42
  57. package/behaviors/registry/agent/organisms/std-agent-assistant.orb +356 -122
  58. package/behaviors/registry/factory-signatures.json +1 -1
  59. package/behaviors/registry/infra/atoms/std-page-open.orb +435 -0
  60. package/behaviors/registry/infra/atoms/std-page-search.orb +867 -0
  61. package/behaviors/registry/infra/atoms/std-page-treat.orb +494 -0
  62. package/behaviors/registry/infra/atoms/std-page-watch.orb +554 -0
  63. package/behaviors/registry/ui/core/atoms/std-board.orb +110 -14
  64. package/behaviors/registry/ui/core/atoms/std-book-reader.orb +119 -0
  65. package/behaviors/registry/ui/core/atoms/std-card-grid.orb +61 -0
  66. package/behaviors/registry/ui/core/atoms/std-doc-page.orb +594 -0
  67. package/behaviors/registry/ui/core/atoms/std-site-header.orb +40 -2
  68. package/behaviors/registry/ui/core/atoms/std-tag-strip.orb +2 -0
  69. package/behaviors/registry/ui/core/atoms/std-tag-taxonomy.orb +24 -0
  70. package/behaviors/registry/ui/core/atoms/std-version-history.orb +8 -1
  71. package/behaviors/registry/ui/core/molecules/ui-header.orb +7 -0
  72. package/behaviors/registry/ui/learning/atoms/std-learn-arrangement.orb +903 -369
  73. package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1002 -232
  74. package/behaviors/registry/ui/learning/atoms/std-learn-compare.orb +253 -74
  75. package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +3624 -921
  76. package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +685 -144
  77. package/behaviors/registry/ui/learning/atoms/std-learn-diagram.orb +404 -52
  78. package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +1787 -210
  79. package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +699 -71
  80. package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +1102 -578
  81. package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +2760 -872
  82. package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +689 -152
  83. package/behaviors/registry/ui/learning/atoms/std-learn-live-sim.orb +1431 -633
  84. package/behaviors/registry/ui/learning/atoms/std-learn-measure.orb +2485 -512
  85. package/behaviors/registry/ui/learning/atoms/std-learn-param-explorer.orb +501 -197
  86. package/behaviors/registry/ui/learning/atoms/std-learn-perturb.orb +3642 -928
  87. package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +705 -125
  88. package/behaviors/registry/ui/learning/atoms/std-learn-sample-accumulator.orb +624 -114
  89. package/behaviors/registry/ui/learning/atoms/std-learn-sandbox.orb +405 -153
  90. package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +1911 -611
  91. package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +436 -128
  92. package/behaviors/registry/ui/learning/atoms/std-learn-sim-3d.orb +2482 -485
  93. package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +896 -192
  94. package/behaviors/registry/ui/learning/atoms/std-learn-stepper.orb +2001 -759
  95. package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +734 -228
  96. package/behaviors/registry/ui/learning/atoms/std-learn-trace-player.orb +2501 -764
  97. package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +1591 -173
  98. package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +883 -122
  99. package/behaviors/registry/ui/learning/atoms/ui-algo-graph-canvas.orb +176 -0
  100. package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +211 -0
  101. package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +211 -0
  102. package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +212 -1
  103. package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +212 -1
  104. package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +203 -9
  105. package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +211 -0
  106. package/behaviors/signatures.lolo +325 -655
  107. package/canonical-operators.json +35 -1
  108. package/dist/behaviors/exports-reader.js +41980 -35508
  109. package/dist/behaviors/functions/index.d.ts +1063 -140
  110. package/dist/behaviors/functions/index.js +41951 -35506
  111. package/dist/behaviors/index.d.ts +1 -1
  112. package/dist/behaviors/index.js +41981 -35509
  113. package/dist/behaviors/query.js +41980 -35508
  114. package/dist/behaviors-embeddings.hash.json +3 -3
  115. package/dist/behaviors-embeddings.json +47 -27
  116. package/dist/behaviors-registry.json +4814 -553
  117. package/dist/index.d.ts +4 -4
  118. package/dist/index.js +42019 -35509
  119. package/dist/knob-embeddings.hash.json +3 -3
  120. package/dist/knob-embeddings.json +623 -263
  121. package/dist/modules/anim.d.ts +1 -1
  122. package/dist/modules/array.d.ts +1 -1
  123. package/dist/modules/async.d.ts +1 -1
  124. package/dist/modules/behavior.d.ts +1 -1
  125. package/dist/modules/browser.d.ts +1 -1
  126. package/dist/modules/composition.d.ts +1 -1
  127. package/dist/modules/contract.d.ts +1 -1
  128. package/dist/modules/core.d.ts +1 -1
  129. package/dist/modules/core.js +2 -0
  130. package/dist/modules/data.d.ts +1 -1
  131. package/dist/modules/ease.d.ts +1 -1
  132. package/dist/modules/format.d.ts +1 -1
  133. package/dist/modules/geo.d.ts +1 -1
  134. package/dist/modules/graph.d.ts +1 -1
  135. package/dist/modules/grid.d.ts +1 -1
  136. package/dist/modules/i18n.d.ts +17 -0
  137. package/dist/modules/i18n.js +22 -0
  138. package/dist/modules/index.d.ts +2 -1
  139. package/dist/modules/index.js +24 -1
  140. package/dist/modules/integration.d.ts +1 -1
  141. package/dist/modules/json.d.ts +1 -1
  142. package/dist/modules/llm.d.ts +1 -1
  143. package/dist/modules/math.d.ts +1 -1
  144. package/dist/modules/memory.d.ts +1 -1
  145. package/dist/modules/nn.d.ts +1 -1
  146. package/dist/modules/noise.d.ts +1 -1
  147. package/dist/modules/object.d.ts +1 -1
  148. package/dist/modules/os.d.ts +1 -1
  149. package/dist/modules/path.d.ts +1 -1
  150. package/dist/modules/prob.d.ts +1 -1
  151. package/dist/modules/session.d.ts +1 -1
  152. package/dist/modules/str.d.ts +1 -1
  153. package/dist/modules/tensor.d.ts +1 -1
  154. package/dist/modules/time.d.ts +1 -1
  155. package/dist/modules/trace.d.ts +1 -1
  156. package/dist/modules/train.d.ts +1 -1
  157. package/dist/modules/validate.d.ts +1 -1
  158. package/dist/modules/vector.d.ts +1 -1
  159. package/dist/modules/workspace.d.ts +1 -1
  160. package/dist/registry/factory-signatures.json +1 -1
  161. package/dist/registry.d.ts +10 -3
  162. package/dist/registry.js +31 -1
  163. package/dist/{types-DLx38UFZ.d.ts → types-Cdb321uM.d.ts} +9 -3
  164. package/i18n/ar.json +1 -0
  165. package/i18n/en.json +1 -0
  166. package/i18n/sl.json +1 -0
  167. package/package.json +3 -3
@@ -79,14 +79,21 @@ orbital LearnDoserOrbital {
79
79
  padding: md
80
80
  children: [
81
81
  { type: stack, direction: vertical, gap: md, children: [
82
- { type: typography, variant: h4, content: @entity.title },
83
- { type: stack, direction: horizontal, gap: sm, children: [
84
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
85
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
86
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
87
- { type: button, action: RESET, label: "Reset", variant: ghost }
88
- ] },
89
- { type: chemistry-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
82
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
83
+ { type: stack, direction: vertical, gap: xs, children: [
84
+ { type: typography, variant: h4, content: @entity.title },
85
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
86
+ ] },
87
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
88
+ ] },
89
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
90
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
91
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
92
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
93
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
94
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
95
+ ] },
96
+ { type: chemistry-canvas, series: @config.series, keyMap: { Space: TOGGLE_DRIP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
90
97
  { type: typography, variant: body, content: @entity.narration }
91
98
  ] }
92
99
  ]
@@ -96,18 +103,30 @@ orbital LearnDoserOrbital {
96
103
  padding: md
97
104
  children: [
98
105
  { type: stack, direction: vertical, gap: md, children: [
99
- { type: typography, variant: h4, content: @entity.title },
100
- { type: stack, direction: horizontal, gap: sm, children: [
101
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
102
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
103
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
104
- { type: button, action: RESET, label: "Reset", variant: ghost }
105
- ] }
106
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
107
+ { type: stack, direction: vertical, gap: xs, children: [
108
+ { type: typography, variant: h4, content: @entity.title },
109
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
110
+ ] },
111
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
112
+ ] },
113
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
114
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
115
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
116
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
117
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
118
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
119
+ ] }
106
120
  ] }
107
121
  ]
108
122
  }))
109
123
  (emit DOSER_UPDATED { running: @entity.running, dose: @entity.dose, bandLabel: @entity.bandLabel, done: @entity.done })
110
124
 
125
+ MODE_SELECTED -> idle when (and (not (== @config.matchMode "")) (not (== ?mode @config.matchMode)))
126
+ (set @entity.active false)
127
+ (set @entity.running false)
128
+ (render-ui main null)
129
+
111
130
  MODE_SELECTED -> idle when (== ?mode @config.matchMode)
112
131
  (set @entity.active true)
113
132
  (set @entity.title @config.title)
@@ -141,14 +160,21 @@ orbital LearnDoserOrbital {
141
160
  padding: md
142
161
  children: [
143
162
  { type: stack, direction: vertical, gap: md, children: [
144
- { type: typography, variant: h4, content: @entity.title },
145
- { type: stack, direction: horizontal, gap: sm, children: [
146
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
147
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
148
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
149
- { type: button, action: RESET, label: "Reset", variant: ghost }
150
- ] },
151
- { type: chemistry-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
163
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
164
+ { type: stack, direction: vertical, gap: xs, children: [
165
+ { type: typography, variant: h4, content: @entity.title },
166
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
167
+ ] },
168
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
169
+ ] },
170
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
171
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
172
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
173
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
174
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
175
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
176
+ ] },
177
+ { type: chemistry-canvas, series: @config.series, keyMap: { Space: TOGGLE_DRIP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
152
178
  { type: typography, variant: body, content: @entity.narration }
153
179
  ] }
154
180
  ]
@@ -158,13 +184,20 @@ orbital LearnDoserOrbital {
158
184
  padding: md
159
185
  children: [
160
186
  { type: stack, direction: vertical, gap: md, children: [
161
- { type: typography, variant: h4, content: @entity.title },
162
- { type: stack, direction: horizontal, gap: sm, children: [
163
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
164
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
165
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
166
- { type: button, action: RESET, label: "Reset", variant: ghost }
167
- ] }
187
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
188
+ { type: stack, direction: vertical, gap: xs, children: [
189
+ { type: typography, variant: h4, content: @entity.title },
190
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
191
+ ] },
192
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
193
+ ] },
194
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
195
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
196
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
197
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
198
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
199
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
200
+ ] }
168
201
  ] }
169
202
  ]
170
203
  }))
@@ -198,14 +231,21 @@ orbital LearnDoserOrbital {
198
231
  padding: md
199
232
  children: [
200
233
  { type: stack, direction: vertical, gap: md, children: [
201
- { type: typography, variant: h4, content: @entity.title },
202
- { type: stack, direction: horizontal, gap: sm, children: [
203
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
204
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
205
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
206
- { type: button, action: RESET, label: "Reset", variant: ghost }
207
- ] },
208
- { type: chemistry-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
234
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
235
+ { type: stack, direction: vertical, gap: xs, children: [
236
+ { type: typography, variant: h4, content: @entity.title },
237
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
238
+ ] },
239
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
240
+ ] },
241
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
242
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
243
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
244
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
245
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
246
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
247
+ ] },
248
+ { type: chemistry-canvas, series: @config.series, keyMap: { Space: TOGGLE_DRIP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
209
249
  { type: typography, variant: body, content: @entity.narration }
210
250
  ] }
211
251
  ]
@@ -215,13 +255,20 @@ orbital LearnDoserOrbital {
215
255
  padding: md
216
256
  children: [
217
257
  { type: stack, direction: vertical, gap: md, children: [
218
- { type: typography, variant: h4, content: @entity.title },
219
- { type: stack, direction: horizontal, gap: sm, children: [
220
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
221
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
222
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
223
- { type: button, action: RESET, label: "Reset", variant: ghost }
224
- ] }
258
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
259
+ { type: stack, direction: vertical, gap: xs, children: [
260
+ { type: typography, variant: h4, content: @entity.title },
261
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
262
+ ] },
263
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
264
+ ] },
265
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
266
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
267
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
268
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
269
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
270
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
271
+ ] }
225
272
  ] }
226
273
  ]
227
274
  }))
@@ -256,14 +303,21 @@ orbital LearnDoserOrbital {
256
303
  padding: md
257
304
  children: [
258
305
  { type: stack, direction: vertical, gap: md, children: [
259
- { type: typography, variant: h4, content: @entity.title },
260
- { type: stack, direction: horizontal, gap: sm, children: [
261
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
262
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
263
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
264
- { type: button, action: RESET, label: "Reset", variant: ghost }
265
- ] },
266
- { type: chemistry-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
306
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
307
+ { type: stack, direction: vertical, gap: xs, children: [
308
+ { type: typography, variant: h4, content: @entity.title },
309
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
310
+ ] },
311
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
312
+ ] },
313
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
314
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
315
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
316
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
317
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
318
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
319
+ ] },
320
+ { type: chemistry-canvas, series: @config.series, keyMap: { Space: TOGGLE_DRIP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
267
321
  { type: typography, variant: body, content: @entity.narration }
268
322
  ] }
269
323
  ]
@@ -273,13 +327,20 @@ orbital LearnDoserOrbital {
273
327
  padding: md
274
328
  children: [
275
329
  { type: stack, direction: vertical, gap: md, children: [
276
- { type: typography, variant: h4, content: @entity.title },
277
- { type: stack, direction: horizontal, gap: sm, children: [
278
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
279
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
280
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
281
- { type: button, action: RESET, label: "Reset", variant: ghost }
282
- ] }
330
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
331
+ { type: stack, direction: vertical, gap: xs, children: [
332
+ { type: typography, variant: h4, content: @entity.title },
333
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
334
+ ] },
335
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
336
+ ] },
337
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
338
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
339
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
340
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
341
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
342
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
343
+ ] }
283
344
  ] }
284
345
  ]
285
346
  }))
@@ -295,14 +356,21 @@ orbital LearnDoserOrbital {
295
356
  padding: md
296
357
  children: [
297
358
  { type: stack, direction: vertical, gap: md, children: [
298
- { type: typography, variant: h4, content: @entity.title },
299
- { type: stack, direction: horizontal, gap: sm, children: [
300
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
301
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
302
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
303
- { type: button, action: RESET, label: "Reset", variant: ghost }
304
- ] },
305
- { type: chemistry-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
359
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
360
+ { type: stack, direction: vertical, gap: xs, children: [
361
+ { type: typography, variant: h4, content: @entity.title },
362
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
363
+ ] },
364
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
365
+ ] },
366
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
367
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
368
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
369
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
370
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
371
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
372
+ ] },
373
+ { type: chemistry-canvas, series: @config.series, keyMap: { Space: TOGGLE_DRIP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
306
374
  { type: typography, variant: body, content: @entity.narration }
307
375
  ] }
308
376
  ]
@@ -312,13 +380,20 @@ orbital LearnDoserOrbital {
312
380
  padding: md
313
381
  children: [
314
382
  { type: stack, direction: vertical, gap: md, children: [
315
- { type: typography, variant: h4, content: @entity.title },
316
- { type: stack, direction: horizontal, gap: sm, children: [
317
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
318
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
319
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
320
- { type: button, action: RESET, label: "Reset", variant: ghost }
321
- ] }
383
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
384
+ { type: stack, direction: vertical, gap: xs, children: [
385
+ { type: typography, variant: h4, content: @entity.title },
386
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
387
+ ] },
388
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
389
+ ] },
390
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
391
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
392
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
393
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
394
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
395
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
396
+ ] }
322
397
  ] }
323
398
  ]
324
399
  }))
@@ -356,14 +431,21 @@ orbital LearnDoserOrbital {
356
431
  padding: md
357
432
  children: [
358
433
  { type: stack, direction: vertical, gap: md, children: [
359
- { type: typography, variant: h4, content: @entity.title },
360
- { type: stack, direction: horizontal, gap: sm, children: [
361
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
362
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
363
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
364
- { type: button, action: RESET, label: "Reset", variant: ghost }
365
- ] },
366
- { type: chemistry-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
434
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
435
+ { type: stack, direction: vertical, gap: xs, children: [
436
+ { type: typography, variant: h4, content: @entity.title },
437
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
438
+ ] },
439
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
440
+ ] },
441
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
442
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
443
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
444
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
445
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
446
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
447
+ ] },
448
+ { type: chemistry-canvas, series: @config.series, keyMap: { Space: TOGGLE_DRIP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, containers: @entity.containers, readouts: @entity.readouts, traces: [ { series: [ { samples: @entity.doseSeries, label: @config.quantityLabel } ], xLabel: "step", yLabel: @config.quantityLabel } ] },
367
449
  { type: typography, variant: body, content: @entity.narration }
368
450
  ] }
369
451
  ]
@@ -373,13 +455,20 @@ orbital LearnDoserOrbital {
373
455
  padding: md
374
456
  children: [
375
457
  { type: stack, direction: vertical, gap: md, children: [
376
- { type: typography, variant: h4, content: @entity.title },
377
- { type: stack, direction: horizontal, gap: sm, children: [
378
- { type: button, action: ADD_SMALL, label: (str/concat "+ " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: primary },
379
- { type: button, action: ADD_LARGE, label: (str/concat "+ " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), variant: secondary },
380
- { type: button, action: TOGGLE_DRIP, label: (if @entity.running "Pause" "Auto-dose"), variant: secondary },
381
- { type: button, action: RESET, label: "Reset", variant: ghost }
382
- ] }
458
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
459
+ { type: stack, direction: vertical, gap: xs, children: [
460
+ { type: typography, variant: h4, content: @entity.title },
461
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
462
+ ] },
463
+ { type: badge, label: (if @entity.done "Locked" (if @entity.running "Auto-dosing" "Ready")), variant: (if @entity.done "warning" (if @entity.running "primary" "neutral")) }
464
+ ] },
465
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
466
+ { type: button, action: ADD_SMALL, label: (str/concat "Add " (str/concat (str/concat "" @config.stepSmall) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: primary, disabled: @entity.done },
467
+ { type: button, action: ADD_LARGE, label: (str/concat "Add " (str/concat (str/concat "" @config.stepLarge) (if (== @config.unit "") "" (str/concat " " @config.unit)))), icon: "plus", variant: secondary, disabled: @entity.done },
468
+ (if @entity.running { type: button, action: TOGGLE_DRIP, label: "Pause", icon: "pause", variant: secondary, aria-pressed: "true" } { type: button, action: TOGGLE_DRIP, label: "Auto-dose", icon: "play", variant: secondary, aria-pressed: "false", disabled: @entity.done }),
469
+ { type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
470
+ { type: typography, variant: caption, color: muted, content: (str/concat @config.quantityLabel (str/concat " " (str/concat (str/concat "" (math/round @entity.dose 2)) (str/concat " of " (str/concat (str/concat "" @config.capacity) (if (== @config.unit "") "" (str/concat " " @config.unit))))))) }
471
+ ] }
383
472
  ] }
384
473
  ]
385
474
  }))
@@ -447,6 +536,10 @@ orbital LearnDoserOrbital {
447
536
  @label "Title"
448
537
  @description "Title shown above the instrument."
449
538
  @tier "presentation"
539
+ summary : string = ""
540
+ @label "Concept"
541
+ @description "One line under the title saying what the learner is looking at (keep it under ~65 characters). Empty shows no line."
542
+ @tier "presentation"
450
543
  width : number = 600
451
544
  @label "Width"
452
545
  @description "Canvas width in pixels."
@@ -455,9 +548,13 @@ orbital LearnDoserOrbital {
455
548
  @label "Height"
456
549
  @description "Canvas height in pixels."
457
550
  @tier "presentation"
458
- backgroundColor : string = "#fafafa"
551
+ backgroundColor : string = ""
459
552
  @label "Background Color"
460
- @description "Canvas background color."
553
+ @description "Canvas ground. Empty uses the theme drawing ground."
554
+ @tier "presentation"
555
+ series : [string] = []
556
+ @label "Palette"
557
+ @description "Overrides the theme's categorical palette on the canvas (series-1…N) — a subject's real-world color convention, such as indicator colors. Empty uses the theme's palette."
461
558
  @tier "presentation"
462
559
  showCanvas : boolean = true
463
560
  @label "Show Canvas"
@@ -501,8 +598,8 @@ orbital LearnDoserOrbital {
501
598
  @description "Maximum points kept in the dose-history trace; older points drop off once exceeded."
502
599
  @tier "domain"
503
600
  bands : [DoserBand] = [
504
- { upperBound: 50, label: "Low", color: "#94a3b8", terminal: false },
505
- { upperBound: 999999999, label: "High", color: "#16a34a", terminal: true }
601
+ { upperBound: 50, label: "Low", color: "muted", terminal: false },
602
+ { upperBound: 999999999, label: "High", color: "success", terminal: true }
506
603
  ]
507
604
  @label "Bands"
508
605
  @description "Ordered ascending roster of dose bands/zones — each carries the dose upper bound it covers, a label, a color, and whether crossing into it is terminal (irreversible; sets done true until Reset). The accumulated dose is classified into the first band whose upperBound it does not exceed, falling through to the last band beyond all bounds."
@@ -518,9 +615,9 @@ orbital LearnDoserOrbital {
518
615
  @description "Label for the vessel that drains as dose is delivered from it."
519
616
  @synonyms "source, burette, supply, dispenser"
520
617
  @tier "presentation"
521
- sourceColor : string = "#60a5fa"
618
+ sourceColor : string = "series-1"
522
619
  @label "Source Color"
523
- @description "Fill color for the source vessel."
620
+ @description "Tone name for the source vessel fill (for example series-1)."
524
621
  @tier "presentation"
525
622
  }
526
623
  }