@bitcobblers/wod-wiki-tools 0.44.2159 → 0.45.2166

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 (632) hide show
  1. package/dist/bin/wod.cjs +151 -153
  2. package/dist/bin/wod.cjs.map +1 -1
  3. package/dist/bin/wod.mjs +4 -4
  4. package/dist/{chunk-BQ6HTRH3.mjs → chunk-EAFF2GVB.mjs} +29 -38
  5. package/dist/chunk-EAFF2GVB.mjs.map +1 -0
  6. package/dist/{chunk-IWT7U3WX.mjs → chunk-F7IXIJ4I.mjs} +3 -3
  7. package/dist/{chunk-IWT7U3WX.mjs.map → chunk-F7IXIJ4I.mjs.map} +1 -1
  8. package/dist/{chunk-RWNL6APX.mjs → chunk-FSOBPDUC.mjs} +3 -3
  9. package/dist/{chunk-RWNL6APX.mjs.map → chunk-FSOBPDUC.mjs.map} +1 -1
  10. package/dist/{chunk-SOGZC3TL.mjs → chunk-O5ZCOUQE.mjs} +3 -3
  11. package/dist/chunk-O5ZCOUQE.mjs.map +1 -0
  12. package/dist/{chunk-LGEZVB44.mjs → chunk-PF5BTGWZ.mjs} +99 -92
  13. package/dist/chunk-PF5BTGWZ.mjs.map +1 -0
  14. package/dist/compiler-ZMG22VH4.mjs +9 -0
  15. package/dist/{compiler-V2BLOB2B.mjs.map → compiler-ZMG22VH4.mjs.map} +1 -1
  16. package/dist/index.cjs +151 -153
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +1 -3
  19. package/dist/index.d.ts +1 -3
  20. package/dist/index.mjs +5 -5
  21. package/dist/{scaffoldCatalog-WNAHHEL2.mjs → scaffoldFeed-UXH3L5HM.mjs} +29 -29
  22. package/dist/scaffoldFeed-UXH3L5HM.mjs.map +1 -0
  23. package/dist/{server-2DVBA35J.mjs → server-5XDT7ITA.mjs} +4 -4
  24. package/dist/{server-2DVBA35J.mjs.map → server-5XDT7ITA.mjs.map} +1 -1
  25. package/dist/web/playground/assets/feedSync.worker-CEbxagtY.js +16 -0
  26. package/dist/web/playground/assets/main-BKDG9P36.css +2 -0
  27. package/dist/web/playground/assets/main-DAHoAykp.js +491 -0
  28. package/dist/web/playground/assets/{statementBuilderFlow-CFMsgRLA.js → statementBuilderFlow-DHSfYrHi.js} +2 -2
  29. package/dist/web/playground/assets/{vendor-BmgUyVmX.js → vendor-DKhA8bPd.js} +59 -59
  30. package/dist/web/{server/assets/vendor-codemirror-CFcn3kQd.js → playground/assets/vendor-codemirror-CnY0iCTs.js} +2 -2
  31. package/dist/web/playground/index.html +5 -5
  32. package/dist/web/playground/seed/core/chunks/canvas.9ad327d4.json +1 -0
  33. package/dist/web/playground/seed/core/chunks/{dashboards.302c4388.json → dashboards.f4196444.json} +1 -1
  34. package/dist/web/playground/seed/core/chunks/{efforts.835c18aa.json → efforts.7f0d2160.json} +1 -1
  35. package/dist/web/playground/seed/core/chunks/{equipment.5091d784.json → equipment.e7531ab5.json} +1 -1
  36. package/dist/web/playground/seed/core/indexes/notebooks/canvas.json +174 -183
  37. package/dist/web/playground/seed/core/indexes/notebooks/dashboards.json +13 -13
  38. package/dist/web/playground/seed/core/indexes/notebooks/efforts.json +323 -323
  39. package/dist/web/playground/seed/core/indexes/notebooks/equipment.json +47 -47
  40. package/dist/web/playground/seed/core/manifest.json +570 -604
  41. package/dist/web/playground/seed/core/markdown/canvas/ai-first/README.json +1 -1
  42. package/dist/web/playground/seed/core/markdown/canvas/guide/README.json +9 -9
  43. package/dist/web/playground/seed/core/markdown/canvas/guide/clock.json +2 -2
  44. package/dist/web/playground/seed/core/markdown/canvas/guide/dashboards.json +11 -11
  45. package/dist/web/playground/seed/core/markdown/canvas/guide/metrics.json +59 -59
  46. package/dist/web/playground/seed/core/markdown/canvas/guide/protocols.json +95 -95
  47. package/dist/web/playground/seed/core/markdown/canvas/guide/sessions.json +131 -131
  48. package/dist/web/playground/seed/core/markdown/canvas/guide/start.json +53 -53
  49. package/dist/web/playground/seed/core/markdown/canvas/guide/structure.json +101 -101
  50. package/dist/web/playground/seed/core/markdown/canvas/guide/wql.json +39 -39
  51. package/dist/web/playground/seed/core/markdown/canvas/home/sample-script.json +4 -4
  52. package/dist/web/playground/seed/core/markdown/canvas/home/welcome-1.json +2 -2
  53. package/dist/web/playground/seed/core/markdown/canvas/syntax/actions-comments.json +4 -4
  54. package/dist/web/playground/seed/core/markdown/canvas/syntax/alternating-emom.json +5 -5
  55. package/dist/web/playground/seed/core/markdown/canvas/syntax/basic-emom.json +4 -4
  56. package/dist/web/playground/seed/core/markdown/canvas/syntax/calculated-metrics.json +4 -4
  57. package/dist/web/playground/seed/core/markdown/canvas/syntax/classic-amrap.json +6 -6
  58. package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-barbell-cycling.json +4 -4
  59. package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-full-session.json +9 -9
  60. package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-nested-protocols.json +7 -7
  61. package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-partner-workout.json +7 -7
  62. package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-swimming.json +3 -3
  63. package/dist/web/playground/seed/core/markdown/canvas/syntax/core-rules.json +4 -4
  64. package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-and-calculated-metrics.json +8 -8
  65. package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-intervals.json +4 -4
  66. package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-1.json +4 -4
  67. package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-2.json +5 -5
  68. package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-3.json +2 -2
  69. package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-4.json +4 -4
  70. package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-5.json +4 -4
  71. package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-climb-bouldering.json +2 -2
  72. package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-climb-hangboard.json +2 -2
  73. package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-climb-sport.json +2 -2
  74. package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-log.json +4 -4
  75. package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-plan.json +8 -8
  76. package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-wod.json +5 -5
  77. package/dist/web/playground/seed/core/markdown/canvas/syntax/distance-intervals.json +3 -3
  78. package/dist/web/playground/seed/core/markdown/canvas/syntax/document-1.json +4 -4
  79. package/dist/web/playground/seed/core/markdown/canvas/syntax/document-2.json +5 -5
  80. package/dist/web/playground/seed/core/markdown/canvas/syntax/document-3.json +10 -10
  81. package/dist/web/playground/seed/core/markdown/canvas/syntax/document-4.json +4 -4
  82. package/dist/web/playground/seed/core/markdown/canvas/syntax/effort-notes.json +4 -4
  83. package/dist/web/playground/seed/core/markdown/canvas/syntax/groups-1.json +5 -5
  84. package/dist/web/playground/seed/core/markdown/canvas/syntax/groups-2.json +6 -6
  85. package/dist/web/playground/seed/core/markdown/canvas/syntax/groups-3.json +3 -3
  86. package/dist/web/playground/seed/core/markdown/canvas/syntax/groups-4.json +3 -3
  87. package/dist/web/playground/seed/core/markdown/canvas/syntax/longer-duration.json +4 -4
  88. package/dist/web/playground/seed/core/markdown/canvas/syntax/longer-intervals.json +4 -4
  89. package/dist/web/playground/seed/core/markdown/canvas/syntax/measurements.json +4 -4
  90. package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-1.json +5 -5
  91. package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-2.json +7 -7
  92. package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-3.json +8 -8
  93. package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-4.json +5 -5
  94. package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-5.json +5 -5
  95. package/dist/web/playground/seed/core/markdown/canvas/syntax/mixed-sections.json +8 -8
  96. package/dist/web/playground/seed/core/markdown/canvas/syntax/mixed-timers.json +5 -5
  97. package/dist/web/playground/seed/core/markdown/canvas/syntax/multiple-amrap-windows.json +7 -7
  98. package/dist/web/playground/seed/core/markdown/canvas/syntax/multiple-sets.json +4 -4
  99. package/dist/web/playground/seed/core/markdown/canvas/syntax/named-groups.json +5 -5
  100. package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-1.json +6 -6
  101. package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-2.json +4 -4
  102. package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-3.json +6 -6
  103. package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-4.json +3 -3
  104. package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-5.json +4 -4
  105. package/dist/web/playground/seed/core/markdown/canvas/syntax/single-movement.json +3 -3
  106. package/dist/web/playground/seed/core/markdown/canvas/syntax/supplemental-1.json +4 -4
  107. package/dist/web/playground/seed/core/markdown/canvas/syntax/supplemental-2.json +5 -5
  108. package/dist/web/playground/seed/core/markdown/canvas/syntax/supplemental-3.json +4 -4
  109. package/dist/web/playground/seed/core/markdown/canvas/syntax/supplemental-4.json +4 -4
  110. package/dist/web/playground/seed/core/markdown/canvas/syntax/time-cap.json +6 -6
  111. package/dist/web/playground/seed/core/markdown/canvas/syntax/timer-modifiers.json +6 -6
  112. package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-1.json +6 -6
  113. package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-2.json +4 -4
  114. package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-3.json +3 -3
  115. package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-4.json +4 -4
  116. package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-5.json +5 -5
  117. package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-rest.json +4 -4
  118. package/dist/web/playground/seed/core/markdown/canvas/wql-presets/aggregate-by-effort.json +2 -2
  119. package/dist/web/playground/seed/core/markdown/canvas/wql-presets/aggregate-by-week.json +2 -2
  120. package/dist/web/playground/seed/core/markdown/canvas/wql-presets/content-fran.json +2 -2
  121. package/dist/web/playground/seed/core/markdown/canvas/wql-presets/filter-combos.json +2 -2
  122. package/dist/web/playground/seed/core/markdown/canvas/wql-presets/pipes-limit.json +2 -2
  123. package/dist/web/playground/seed/core/markdown/canvas/wql-presets/session-rpe.json +2 -2
  124. package/dist/web/playground/seed/core/markdown/canvas/wql-presets/source-journal.json +2 -2
  125. package/dist/web/playground/seed/core/markdown/canvas/wql-presets/tis-trend.json +2 -2
  126. package/dist/web/playground/seed/core/markdown/canvas/wql-presets/where-join.json +2 -2
  127. package/dist/web/playground/seed/core/markdown/dashboards/benchmark-pr-board.json +6 -6
  128. package/dist/web/playground/seed/core/markdown/dashboards/finger-strength-v8.json +5 -5
  129. package/dist/web/playground/seed/core/markdown/dashboards/polarized-base-marathon.json +9 -9
  130. package/dist/web/playground/seed/core/markdown/dashboards/recovery-readiness.json +7 -7
  131. package/dist/web/playground/seed/core/markdown/dashboards/road-to-560-total.json +9 -9
  132. package/dist/web/playground/seed/core/markdown/dashboards/training-block-review.json +11 -11
  133. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/air-squat.json +1 -1
  134. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/box-jump.json +1 -1
  135. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/broad-jump.json +1 -1
  136. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/burpee-box-jump-over.json +1 -1
  137. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/burpee-over-dumbbell.json +1 -1
  138. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/burpee.json +1 -1
  139. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/dumbbell-squat-clean.json +1 -1
  140. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/ghd-sit-up.json +1 -1
  141. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/ground-kong.json +1 -1
  142. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/jumping-jack.json +1 -1
  143. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/kong-walk.json +1 -1
  144. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/lunge.json +1 -1
  145. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/overhead-squat.json +1 -1
  146. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/parkour-roll.json +1 -1
  147. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/parkour-squat.json +1 -1
  148. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/pistol-squat.json +1 -1
  149. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/plank.json +1 -1
  150. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/precision-burpee.json +1 -1
  151. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/precision-jump.json +1 -1
  152. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/quadrupedal-movement.json +1 -1
  153. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/russian-twist.json +1 -1
  154. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/sit-up.json +1 -1
  155. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/squat-clean.json +1 -1
  156. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/squat-hold.json +1 -1
  157. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/squat-snatch.json +1 -1
  158. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/tuck-jump.json +1 -1
  159. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/wall-ball.json +1 -1
  160. package/dist/web/playground/seed/core/markdown/efforts/bodyweight/wall-burpee.json +1 -1
  161. package/dist/web/playground/seed/core/markdown/efforts/cycling/assault-bike.json +1 -1
  162. package/dist/web/playground/seed/core/markdown/efforts/cycling/cycling-moderate.json +1 -1
  163. package/dist/web/playground/seed/core/markdown/efforts/cycling/cycling-vigorous.json +1 -1
  164. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/assisted-pull-up.json +1 -1
  165. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/burpee-pull-up.json +1 -1
  166. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/chest-to-bar-pull-up.json +1 -1
  167. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/dip.json +1 -1
  168. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/double-under.json +1 -1
  169. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/handstand-hold.json +1 -1
  170. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/handstand-push-up.json +1 -1
  171. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/handstand-walk.json +1 -1
  172. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/jump-rope.json +1 -1
  173. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/jumping-pull-up.json +1 -1
  174. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/jumping-push-up.json +1 -1
  175. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/l-sit-pull-up.json +1 -1
  176. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/muscle-up.json +1 -1
  177. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/pull-up.json +1 -1
  178. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/push-up.json +1 -1
  179. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/reverse-wall-dip.json +1 -1
  180. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/rope-climb.json +1 -1
  181. package/dist/web/playground/seed/core/markdown/efforts/gymnastics/toes-to-bar.json +1 -1
  182. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-arm-bar.json +1 -1
  183. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-around-the-world.json +1 -1
  184. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-bent-over-row.json +1 -1
  185. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-clean-and-jerk.json +1 -1
  186. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-clean-and-press.json +1 -1
  187. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-clean.json +1 -1
  188. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-deadlift.json +1 -1
  189. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-floor-press.json +1 -1
  190. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-front-squat.json +1 -1
  191. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-goblet-squat.json +1 -1
  192. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-gorilla-row.json +1 -1
  193. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-halo.json +1 -1
  194. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-jerk.json +1 -1
  195. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-overhead-squat.json +1 -1
  196. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-press.json +1 -1
  197. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-snatch.json +1 -1
  198. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-swing.json +1 -1
  199. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-windmill.json +1 -1
  200. package/dist/web/playground/seed/core/markdown/efforts/kettlebell/turkish-get-up.json +1 -1
  201. package/dist/web/playground/seed/core/markdown/efforts/recovery/rest.json +1 -1
  202. package/dist/web/playground/seed/core/markdown/efforts/recovery/stretching.json +1 -1
  203. package/dist/web/playground/seed/core/markdown/efforts/rowing/rowing-sprint.json +1 -1
  204. package/dist/web/playground/seed/core/markdown/efforts/rowing/rowing.json +1 -1
  205. package/dist/web/playground/seed/core/markdown/efforts/rowing/ski-erg.json +1 -1
  206. package/dist/web/playground/seed/core/markdown/efforts/running/backward-running.json +1 -1
  207. package/dist/web/playground/seed/core/markdown/efforts/running/running-6-mph.json +1 -1
  208. package/dist/web/playground/seed/core/markdown/efforts/running/running-8-mph.json +1 -1
  209. package/dist/web/playground/seed/core/markdown/efforts/running/running-sprint.json +1 -1
  210. package/dist/web/playground/seed/core/markdown/efforts/snatch.json +2 -2
  211. package/dist/web/playground/seed/core/markdown/efforts/strength/back-squat.json +1 -1
  212. package/dist/web/playground/seed/core/markdown/efforts/strength/bench-press.json +1 -1
  213. package/dist/web/playground/seed/core/markdown/efforts/strength/box-step-up.json +1 -1
  214. package/dist/web/playground/seed/core/markdown/efforts/strength/carioca.json +1 -1
  215. package/dist/web/playground/seed/core/markdown/efforts/strength/clean-and-jerk.json +1 -1
  216. package/dist/web/playground/seed/core/markdown/efforts/strength/cluster.json +1 -1
  217. package/dist/web/playground/seed/core/markdown/efforts/strength/dead-hang.json +1 -1
  218. package/dist/web/playground/seed/core/markdown/efforts/strength/deadlift.json +1 -1
  219. package/dist/web/playground/seed/core/markdown/efforts/strength/devils-press.json +1 -1
  220. package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-box-step-up.json +1 -1
  221. package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-clean.json +1 -1
  222. package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-fly.json +1 -1
  223. package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-row.json +1 -1
  224. package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-snatch.json +1 -1
  225. package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-thruster.json +1 -1
  226. package/dist/web/playground/seed/core/markdown/efforts/strength/elbows-to-knees.json +1 -1
  227. package/dist/web/playground/seed/core/markdown/efforts/strength/farmer-carry.json +1 -1
  228. package/dist/web/playground/seed/core/markdown/efforts/strength/frog-stand.json +1 -1
  229. package/dist/web/playground/seed/core/markdown/efforts/strength/front-squat.json +1 -1
  230. package/dist/web/playground/seed/core/markdown/efforts/strength/good-morning.json +1 -1
  231. package/dist/web/playground/seed/core/markdown/efforts/strength/hanging-leg-raise.json +1 -1
  232. package/dist/web/playground/seed/core/markdown/efforts/strength/hollow-rock.json +1 -1
  233. package/dist/web/playground/seed/core/markdown/efforts/strength/knees-to-elbows.json +1 -1
  234. package/dist/web/playground/seed/core/markdown/efforts/strength/l-sit.json +1 -1
  235. package/dist/web/playground/seed/core/markdown/efforts/strength/man-maker.json +1 -1
  236. package/dist/web/playground/seed/core/markdown/efforts/strength/medicine-ball-clean.json +1 -1
  237. package/dist/web/playground/seed/core/markdown/efforts/strength/overhead-press.json +1 -1
  238. package/dist/web/playground/seed/core/markdown/efforts/strength/parkour-vault.json +1 -1
  239. package/dist/web/playground/seed/core/markdown/efforts/strength/pig-flip.json +1 -1
  240. package/dist/web/playground/seed/core/markdown/efforts/strength/power-clean.json +1 -1
  241. package/dist/web/playground/seed/core/markdown/efforts/strength/power-snatch.json +1 -1
  242. package/dist/web/playground/seed/core/markdown/efforts/strength/push-jerk.json +1 -1
  243. package/dist/web/playground/seed/core/markdown/efforts/strength/push-press.json +1 -1
  244. package/dist/web/playground/seed/core/markdown/efforts/strength/romanian-deadlift.json +1 -1
  245. package/dist/web/playground/seed/core/markdown/efforts/strength/single-leg-deadlift.json +1 -1
  246. package/dist/web/playground/seed/core/markdown/efforts/strength/skull-crusher.json +1 -1
  247. package/dist/web/playground/seed/core/markdown/efforts/strength/slam-ball.json +1 -1
  248. package/dist/web/playground/seed/core/markdown/efforts/strength/sled-pull.json +1 -1
  249. package/dist/web/playground/seed/core/markdown/efforts/strength/sled-push.json +1 -1
  250. package/dist/web/playground/seed/core/markdown/efforts/strength/sumo-deadlift.json +1 -1
  251. package/dist/web/playground/seed/core/markdown/efforts/strength/thruster.json +1 -1
  252. package/dist/web/playground/seed/core/markdown/efforts/strength/triceps-extension.json +1 -1
  253. package/dist/web/playground/seed/core/markdown/efforts/strength/v-sit-hold.json +1 -1
  254. package/dist/web/playground/seed/core/markdown/efforts/strength/wall-walk.json +1 -1
  255. package/dist/web/playground/seed/core/markdown/efforts/strength/yoga-sun-salutation.json +1 -1
  256. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-assisted-sprint.json +1 -1
  257. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-backstroke.json +1 -1
  258. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-breaststroke-kick.json +1 -1
  259. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-breaststroke.json +1 -1
  260. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-butterfly.json +1 -1
  261. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-catch-up-drill.json +1 -1
  262. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-choice-stroke.json +1 -1
  263. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-dive-start.json +1 -1
  264. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-dolphin-kick.json +1 -1
  265. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-drafting.json +1 -1
  266. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-fingertip-drag.json +1 -1
  267. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-freestyle.json +1 -1
  268. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-individual-medley.json +1 -1
  269. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-kick.json +1 -1
  270. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-pull.json +1 -1
  271. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-resisted-sprint.json +1 -1
  272. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-rotation-drill.json +1 -1
  273. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-sighting.json +1 -1
  274. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-single-arm-drill.json +1 -1
  275. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-stroke-transition.json +1 -1
  276. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-two-kick-one-pull.json +1 -1
  277. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-vigorous.json +1 -1
  278. package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming.json +1 -1
  279. package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-arm-cast.json +1 -1
  280. package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-circles.json +1 -1
  281. package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-mill.json +1 -1
  282. package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-reverse-mill.json +1 -1
  283. package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-shield-cast.json +1 -1
  284. package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-10-to-2-swing.json +1 -1
  285. package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-360-swing.json +1 -1
  286. package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-barbarian-squat.json +1 -1
  287. package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-flow.json +1 -1
  288. package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-gravedigger.json +1 -1
  289. package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-touchdown.json +1 -1
  290. package/dist/web/playground/seed/core/markdown/efforts/unconventional/sandbag-bear-hug-carry.json +1 -1
  291. package/dist/web/playground/seed/core/markdown/efforts/unconventional/sandbag-bear-hug-extension.json +1 -1
  292. package/dist/web/playground/seed/core/markdown/efforts/unconventional/sandbag-over-shoulder.json +1 -1
  293. package/dist/web/playground/seed/core/markdown/efforts/walking/walking-3-mph.json +1 -1
  294. package/dist/web/playground/seed/core/markdown/equipment/air-bike.json +1 -1
  295. package/dist/web/playground/seed/core/markdown/equipment/barbell.json +1 -1
  296. package/dist/web/playground/seed/core/markdown/equipment/bench.json +1 -1
  297. package/dist/web/playground/seed/core/markdown/equipment/bike-erg.json +1 -1
  298. package/dist/web/playground/seed/core/markdown/equipment/climbing-rope.json +1 -1
  299. package/dist/web/playground/seed/core/markdown/equipment/clubs.json +1 -1
  300. package/dist/web/playground/seed/core/markdown/equipment/dumbbell.json +1 -1
  301. package/dist/web/playground/seed/core/markdown/equipment/ghd.json +1 -1
  302. package/dist/web/playground/seed/core/markdown/equipment/gymnastic-rings.json +1 -1
  303. package/dist/web/playground/seed/core/markdown/equipment/jump-rope.json +1 -1
  304. package/dist/web/playground/seed/core/markdown/equipment/kettlebell.json +1 -1
  305. package/dist/web/playground/seed/core/markdown/equipment/macebell.json +1 -1
  306. package/dist/web/playground/seed/core/markdown/equipment/medicine-ball.json +1 -1
  307. package/dist/web/playground/seed/core/markdown/equipment/parallettes.json +1 -1
  308. package/dist/web/playground/seed/core/markdown/equipment/plyo-box.json +1 -1
  309. package/dist/web/playground/seed/core/markdown/equipment/pull-up-bar.json +1 -1
  310. package/dist/web/playground/seed/core/markdown/equipment/rower.json +1 -1
  311. package/dist/web/playground/seed/core/markdown/equipment/sandbag.json +1 -1
  312. package/dist/web/playground/seed/core/markdown/equipment/ski-erg.json +1 -1
  313. package/dist/web/playground/seed/core/markdown/equipment/slam-ball.json +1 -1
  314. package/dist/web/playground/seed/core/markdown/equipment/sled.json +1 -1
  315. package/dist/web/playground/seed/core/markdown/equipment/sledgehammer.json +1 -1
  316. package/dist/web/playground/seed/core/markdown/equipment/weight-vest.json +1 -1
  317. package/dist/web/playground/seed/core/report.html +14 -15
  318. package/dist/web/server/assets/feedSync.worker-CEbxagtY.js +16 -0
  319. package/dist/web/server/assets/main-BKDG9P36.css +2 -0
  320. package/dist/web/server/assets/main-C_b1CczJ.js +491 -0
  321. package/dist/web/server/assets/{statementBuilderFlow-CQ3x0D5F.js → statementBuilderFlow-BPmNsGND.js} +2 -2
  322. package/dist/web/server/assets/{vendor-BmgUyVmX.js → vendor-DKhA8bPd.js} +59 -59
  323. package/dist/web/{playground/assets/vendor-codemirror-CFcn3kQd.js → server/assets/vendor-codemirror-CnY0iCTs.js} +2 -2
  324. package/dist/web/server/index.html +5 -5
  325. package/dist/web/server/seed/core/chunks/canvas.9ad327d4.json +1 -0
  326. package/dist/web/server/seed/core/chunks/{dashboards.302c4388.json → dashboards.f4196444.json} +1 -1
  327. package/dist/web/server/seed/core/chunks/{efforts.835c18aa.json → efforts.7f0d2160.json} +1 -1
  328. package/dist/web/server/seed/core/chunks/{equipment.5091d784.json → equipment.e7531ab5.json} +1 -1
  329. package/dist/web/server/seed/core/indexes/notebooks/canvas.json +174 -183
  330. package/dist/web/server/seed/core/indexes/notebooks/dashboards.json +13 -13
  331. package/dist/web/server/seed/core/indexes/notebooks/efforts.json +323 -323
  332. package/dist/web/server/seed/core/indexes/notebooks/equipment.json +47 -47
  333. package/dist/web/server/seed/core/manifest.json +570 -604
  334. package/dist/web/server/seed/core/markdown/canvas/ai-first/README.json +1 -1
  335. package/dist/web/server/seed/core/markdown/canvas/guide/README.json +9 -9
  336. package/dist/web/server/seed/core/markdown/canvas/guide/clock.json +2 -2
  337. package/dist/web/server/seed/core/markdown/canvas/guide/dashboards.json +11 -11
  338. package/dist/web/server/seed/core/markdown/canvas/guide/metrics.json +59 -59
  339. package/dist/web/server/seed/core/markdown/canvas/guide/protocols.json +95 -95
  340. package/dist/web/server/seed/core/markdown/canvas/guide/sessions.json +131 -131
  341. package/dist/web/server/seed/core/markdown/canvas/guide/start.json +53 -53
  342. package/dist/web/server/seed/core/markdown/canvas/guide/structure.json +101 -101
  343. package/dist/web/server/seed/core/markdown/canvas/guide/wql.json +39 -39
  344. package/dist/web/server/seed/core/markdown/canvas/home/sample-script.json +4 -4
  345. package/dist/web/server/seed/core/markdown/canvas/home/welcome-1.json +2 -2
  346. package/dist/web/server/seed/core/markdown/canvas/syntax/actions-comments.json +4 -4
  347. package/dist/web/server/seed/core/markdown/canvas/syntax/alternating-emom.json +5 -5
  348. package/dist/web/server/seed/core/markdown/canvas/syntax/basic-emom.json +4 -4
  349. package/dist/web/server/seed/core/markdown/canvas/syntax/calculated-metrics.json +4 -4
  350. package/dist/web/server/seed/core/markdown/canvas/syntax/classic-amrap.json +6 -6
  351. package/dist/web/server/seed/core/markdown/canvas/syntax/complex-barbell-cycling.json +4 -4
  352. package/dist/web/server/seed/core/markdown/canvas/syntax/complex-full-session.json +9 -9
  353. package/dist/web/server/seed/core/markdown/canvas/syntax/complex-nested-protocols.json +7 -7
  354. package/dist/web/server/seed/core/markdown/canvas/syntax/complex-partner-workout.json +7 -7
  355. package/dist/web/server/seed/core/markdown/canvas/syntax/complex-swimming.json +3 -3
  356. package/dist/web/server/seed/core/markdown/canvas/syntax/core-rules.json +4 -4
  357. package/dist/web/server/seed/core/markdown/canvas/syntax/custom-and-calculated-metrics.json +8 -8
  358. package/dist/web/server/seed/core/markdown/canvas/syntax/custom-intervals.json +4 -4
  359. package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-1.json +4 -4
  360. package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-2.json +5 -5
  361. package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-3.json +2 -2
  362. package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-4.json +4 -4
  363. package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-5.json +4 -4
  364. package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-climb-bouldering.json +2 -2
  365. package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-climb-hangboard.json +2 -2
  366. package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-climb-sport.json +2 -2
  367. package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-log.json +4 -4
  368. package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-plan.json +8 -8
  369. package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-wod.json +5 -5
  370. package/dist/web/server/seed/core/markdown/canvas/syntax/distance-intervals.json +3 -3
  371. package/dist/web/server/seed/core/markdown/canvas/syntax/document-1.json +4 -4
  372. package/dist/web/server/seed/core/markdown/canvas/syntax/document-2.json +5 -5
  373. package/dist/web/server/seed/core/markdown/canvas/syntax/document-3.json +10 -10
  374. package/dist/web/server/seed/core/markdown/canvas/syntax/document-4.json +4 -4
  375. package/dist/web/server/seed/core/markdown/canvas/syntax/effort-notes.json +4 -4
  376. package/dist/web/server/seed/core/markdown/canvas/syntax/groups-1.json +5 -5
  377. package/dist/web/server/seed/core/markdown/canvas/syntax/groups-2.json +6 -6
  378. package/dist/web/server/seed/core/markdown/canvas/syntax/groups-3.json +3 -3
  379. package/dist/web/server/seed/core/markdown/canvas/syntax/groups-4.json +3 -3
  380. package/dist/web/server/seed/core/markdown/canvas/syntax/longer-duration.json +4 -4
  381. package/dist/web/server/seed/core/markdown/canvas/syntax/longer-intervals.json +4 -4
  382. package/dist/web/server/seed/core/markdown/canvas/syntax/measurements.json +4 -4
  383. package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-1.json +5 -5
  384. package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-2.json +7 -7
  385. package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-3.json +8 -8
  386. package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-4.json +5 -5
  387. package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-5.json +5 -5
  388. package/dist/web/server/seed/core/markdown/canvas/syntax/mixed-sections.json +8 -8
  389. package/dist/web/server/seed/core/markdown/canvas/syntax/mixed-timers.json +5 -5
  390. package/dist/web/server/seed/core/markdown/canvas/syntax/multiple-amrap-windows.json +7 -7
  391. package/dist/web/server/seed/core/markdown/canvas/syntax/multiple-sets.json +4 -4
  392. package/dist/web/server/seed/core/markdown/canvas/syntax/named-groups.json +5 -5
  393. package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-1.json +6 -6
  394. package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-2.json +4 -4
  395. package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-3.json +6 -6
  396. package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-4.json +3 -3
  397. package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-5.json +4 -4
  398. package/dist/web/server/seed/core/markdown/canvas/syntax/single-movement.json +3 -3
  399. package/dist/web/server/seed/core/markdown/canvas/syntax/supplemental-1.json +4 -4
  400. package/dist/web/server/seed/core/markdown/canvas/syntax/supplemental-2.json +5 -5
  401. package/dist/web/server/seed/core/markdown/canvas/syntax/supplemental-3.json +4 -4
  402. package/dist/web/server/seed/core/markdown/canvas/syntax/supplemental-4.json +4 -4
  403. package/dist/web/server/seed/core/markdown/canvas/syntax/time-cap.json +6 -6
  404. package/dist/web/server/seed/core/markdown/canvas/syntax/timer-modifiers.json +6 -6
  405. package/dist/web/server/seed/core/markdown/canvas/syntax/timers-1.json +6 -6
  406. package/dist/web/server/seed/core/markdown/canvas/syntax/timers-2.json +4 -4
  407. package/dist/web/server/seed/core/markdown/canvas/syntax/timers-3.json +3 -3
  408. package/dist/web/server/seed/core/markdown/canvas/syntax/timers-4.json +4 -4
  409. package/dist/web/server/seed/core/markdown/canvas/syntax/timers-5.json +5 -5
  410. package/dist/web/server/seed/core/markdown/canvas/syntax/timers-rest.json +4 -4
  411. package/dist/web/server/seed/core/markdown/canvas/wql-presets/aggregate-by-effort.json +2 -2
  412. package/dist/web/server/seed/core/markdown/canvas/wql-presets/aggregate-by-week.json +2 -2
  413. package/dist/web/server/seed/core/markdown/canvas/wql-presets/content-fran.json +2 -2
  414. package/dist/web/server/seed/core/markdown/canvas/wql-presets/filter-combos.json +2 -2
  415. package/dist/web/server/seed/core/markdown/canvas/wql-presets/pipes-limit.json +2 -2
  416. package/dist/web/server/seed/core/markdown/canvas/wql-presets/session-rpe.json +2 -2
  417. package/dist/web/server/seed/core/markdown/canvas/wql-presets/source-journal.json +2 -2
  418. package/dist/web/server/seed/core/markdown/canvas/wql-presets/tis-trend.json +2 -2
  419. package/dist/web/server/seed/core/markdown/canvas/wql-presets/where-join.json +2 -2
  420. package/dist/web/server/seed/core/markdown/dashboards/benchmark-pr-board.json +6 -6
  421. package/dist/web/server/seed/core/markdown/dashboards/finger-strength-v8.json +5 -5
  422. package/dist/web/server/seed/core/markdown/dashboards/polarized-base-marathon.json +9 -9
  423. package/dist/web/server/seed/core/markdown/dashboards/recovery-readiness.json +7 -7
  424. package/dist/web/server/seed/core/markdown/dashboards/road-to-560-total.json +9 -9
  425. package/dist/web/server/seed/core/markdown/dashboards/training-block-review.json +11 -11
  426. package/dist/web/server/seed/core/markdown/efforts/bodyweight/air-squat.json +1 -1
  427. package/dist/web/server/seed/core/markdown/efforts/bodyweight/box-jump.json +1 -1
  428. package/dist/web/server/seed/core/markdown/efforts/bodyweight/broad-jump.json +1 -1
  429. package/dist/web/server/seed/core/markdown/efforts/bodyweight/burpee-box-jump-over.json +1 -1
  430. package/dist/web/server/seed/core/markdown/efforts/bodyweight/burpee-over-dumbbell.json +1 -1
  431. package/dist/web/server/seed/core/markdown/efforts/bodyweight/burpee.json +1 -1
  432. package/dist/web/server/seed/core/markdown/efforts/bodyweight/dumbbell-squat-clean.json +1 -1
  433. package/dist/web/server/seed/core/markdown/efforts/bodyweight/ghd-sit-up.json +1 -1
  434. package/dist/web/server/seed/core/markdown/efforts/bodyweight/ground-kong.json +1 -1
  435. package/dist/web/server/seed/core/markdown/efforts/bodyweight/jumping-jack.json +1 -1
  436. package/dist/web/server/seed/core/markdown/efforts/bodyweight/kong-walk.json +1 -1
  437. package/dist/web/server/seed/core/markdown/efforts/bodyweight/lunge.json +1 -1
  438. package/dist/web/server/seed/core/markdown/efforts/bodyweight/overhead-squat.json +1 -1
  439. package/dist/web/server/seed/core/markdown/efforts/bodyweight/parkour-roll.json +1 -1
  440. package/dist/web/server/seed/core/markdown/efforts/bodyweight/parkour-squat.json +1 -1
  441. package/dist/web/server/seed/core/markdown/efforts/bodyweight/pistol-squat.json +1 -1
  442. package/dist/web/server/seed/core/markdown/efforts/bodyweight/plank.json +1 -1
  443. package/dist/web/server/seed/core/markdown/efforts/bodyweight/precision-burpee.json +1 -1
  444. package/dist/web/server/seed/core/markdown/efforts/bodyweight/precision-jump.json +1 -1
  445. package/dist/web/server/seed/core/markdown/efforts/bodyweight/quadrupedal-movement.json +1 -1
  446. package/dist/web/server/seed/core/markdown/efforts/bodyweight/russian-twist.json +1 -1
  447. package/dist/web/server/seed/core/markdown/efforts/bodyweight/sit-up.json +1 -1
  448. package/dist/web/server/seed/core/markdown/efforts/bodyweight/squat-clean.json +1 -1
  449. package/dist/web/server/seed/core/markdown/efforts/bodyweight/squat-hold.json +1 -1
  450. package/dist/web/server/seed/core/markdown/efforts/bodyweight/squat-snatch.json +1 -1
  451. package/dist/web/server/seed/core/markdown/efforts/bodyweight/tuck-jump.json +1 -1
  452. package/dist/web/server/seed/core/markdown/efforts/bodyweight/wall-ball.json +1 -1
  453. package/dist/web/server/seed/core/markdown/efforts/bodyweight/wall-burpee.json +1 -1
  454. package/dist/web/server/seed/core/markdown/efforts/cycling/assault-bike.json +1 -1
  455. package/dist/web/server/seed/core/markdown/efforts/cycling/cycling-moderate.json +1 -1
  456. package/dist/web/server/seed/core/markdown/efforts/cycling/cycling-vigorous.json +1 -1
  457. package/dist/web/server/seed/core/markdown/efforts/gymnastics/assisted-pull-up.json +1 -1
  458. package/dist/web/server/seed/core/markdown/efforts/gymnastics/burpee-pull-up.json +1 -1
  459. package/dist/web/server/seed/core/markdown/efforts/gymnastics/chest-to-bar-pull-up.json +1 -1
  460. package/dist/web/server/seed/core/markdown/efforts/gymnastics/dip.json +1 -1
  461. package/dist/web/server/seed/core/markdown/efforts/gymnastics/double-under.json +1 -1
  462. package/dist/web/server/seed/core/markdown/efforts/gymnastics/handstand-hold.json +1 -1
  463. package/dist/web/server/seed/core/markdown/efforts/gymnastics/handstand-push-up.json +1 -1
  464. package/dist/web/server/seed/core/markdown/efforts/gymnastics/handstand-walk.json +1 -1
  465. package/dist/web/server/seed/core/markdown/efforts/gymnastics/jump-rope.json +1 -1
  466. package/dist/web/server/seed/core/markdown/efforts/gymnastics/jumping-pull-up.json +1 -1
  467. package/dist/web/server/seed/core/markdown/efforts/gymnastics/jumping-push-up.json +1 -1
  468. package/dist/web/server/seed/core/markdown/efforts/gymnastics/l-sit-pull-up.json +1 -1
  469. package/dist/web/server/seed/core/markdown/efforts/gymnastics/muscle-up.json +1 -1
  470. package/dist/web/server/seed/core/markdown/efforts/gymnastics/pull-up.json +1 -1
  471. package/dist/web/server/seed/core/markdown/efforts/gymnastics/push-up.json +1 -1
  472. package/dist/web/server/seed/core/markdown/efforts/gymnastics/reverse-wall-dip.json +1 -1
  473. package/dist/web/server/seed/core/markdown/efforts/gymnastics/rope-climb.json +1 -1
  474. package/dist/web/server/seed/core/markdown/efforts/gymnastics/toes-to-bar.json +1 -1
  475. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-arm-bar.json +1 -1
  476. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-around-the-world.json +1 -1
  477. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-bent-over-row.json +1 -1
  478. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-clean-and-jerk.json +1 -1
  479. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-clean-and-press.json +1 -1
  480. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-clean.json +1 -1
  481. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-deadlift.json +1 -1
  482. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-floor-press.json +1 -1
  483. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-front-squat.json +1 -1
  484. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-goblet-squat.json +1 -1
  485. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-gorilla-row.json +1 -1
  486. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-halo.json +1 -1
  487. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-jerk.json +1 -1
  488. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-overhead-squat.json +1 -1
  489. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-press.json +1 -1
  490. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-snatch.json +1 -1
  491. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-swing.json +1 -1
  492. package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-windmill.json +1 -1
  493. package/dist/web/server/seed/core/markdown/efforts/kettlebell/turkish-get-up.json +1 -1
  494. package/dist/web/server/seed/core/markdown/efforts/recovery/rest.json +1 -1
  495. package/dist/web/server/seed/core/markdown/efforts/recovery/stretching.json +1 -1
  496. package/dist/web/server/seed/core/markdown/efforts/rowing/rowing-sprint.json +1 -1
  497. package/dist/web/server/seed/core/markdown/efforts/rowing/rowing.json +1 -1
  498. package/dist/web/server/seed/core/markdown/efforts/rowing/ski-erg.json +1 -1
  499. package/dist/web/server/seed/core/markdown/efforts/running/backward-running.json +1 -1
  500. package/dist/web/server/seed/core/markdown/efforts/running/running-6-mph.json +1 -1
  501. package/dist/web/server/seed/core/markdown/efforts/running/running-8-mph.json +1 -1
  502. package/dist/web/server/seed/core/markdown/efforts/running/running-sprint.json +1 -1
  503. package/dist/web/server/seed/core/markdown/efforts/snatch.json +2 -2
  504. package/dist/web/server/seed/core/markdown/efforts/strength/back-squat.json +1 -1
  505. package/dist/web/server/seed/core/markdown/efforts/strength/bench-press.json +1 -1
  506. package/dist/web/server/seed/core/markdown/efforts/strength/box-step-up.json +1 -1
  507. package/dist/web/server/seed/core/markdown/efforts/strength/carioca.json +1 -1
  508. package/dist/web/server/seed/core/markdown/efforts/strength/clean-and-jerk.json +1 -1
  509. package/dist/web/server/seed/core/markdown/efforts/strength/cluster.json +1 -1
  510. package/dist/web/server/seed/core/markdown/efforts/strength/dead-hang.json +1 -1
  511. package/dist/web/server/seed/core/markdown/efforts/strength/deadlift.json +1 -1
  512. package/dist/web/server/seed/core/markdown/efforts/strength/devils-press.json +1 -1
  513. package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-box-step-up.json +1 -1
  514. package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-clean.json +1 -1
  515. package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-fly.json +1 -1
  516. package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-row.json +1 -1
  517. package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-snatch.json +1 -1
  518. package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-thruster.json +1 -1
  519. package/dist/web/server/seed/core/markdown/efforts/strength/elbows-to-knees.json +1 -1
  520. package/dist/web/server/seed/core/markdown/efforts/strength/farmer-carry.json +1 -1
  521. package/dist/web/server/seed/core/markdown/efforts/strength/frog-stand.json +1 -1
  522. package/dist/web/server/seed/core/markdown/efforts/strength/front-squat.json +1 -1
  523. package/dist/web/server/seed/core/markdown/efforts/strength/good-morning.json +1 -1
  524. package/dist/web/server/seed/core/markdown/efforts/strength/hanging-leg-raise.json +1 -1
  525. package/dist/web/server/seed/core/markdown/efforts/strength/hollow-rock.json +1 -1
  526. package/dist/web/server/seed/core/markdown/efforts/strength/knees-to-elbows.json +1 -1
  527. package/dist/web/server/seed/core/markdown/efforts/strength/l-sit.json +1 -1
  528. package/dist/web/server/seed/core/markdown/efforts/strength/man-maker.json +1 -1
  529. package/dist/web/server/seed/core/markdown/efforts/strength/medicine-ball-clean.json +1 -1
  530. package/dist/web/server/seed/core/markdown/efforts/strength/overhead-press.json +1 -1
  531. package/dist/web/server/seed/core/markdown/efforts/strength/parkour-vault.json +1 -1
  532. package/dist/web/server/seed/core/markdown/efforts/strength/pig-flip.json +1 -1
  533. package/dist/web/server/seed/core/markdown/efforts/strength/power-clean.json +1 -1
  534. package/dist/web/server/seed/core/markdown/efforts/strength/power-snatch.json +1 -1
  535. package/dist/web/server/seed/core/markdown/efforts/strength/push-jerk.json +1 -1
  536. package/dist/web/server/seed/core/markdown/efforts/strength/push-press.json +1 -1
  537. package/dist/web/server/seed/core/markdown/efforts/strength/romanian-deadlift.json +1 -1
  538. package/dist/web/server/seed/core/markdown/efforts/strength/single-leg-deadlift.json +1 -1
  539. package/dist/web/server/seed/core/markdown/efforts/strength/skull-crusher.json +1 -1
  540. package/dist/web/server/seed/core/markdown/efforts/strength/slam-ball.json +1 -1
  541. package/dist/web/server/seed/core/markdown/efforts/strength/sled-pull.json +1 -1
  542. package/dist/web/server/seed/core/markdown/efforts/strength/sled-push.json +1 -1
  543. package/dist/web/server/seed/core/markdown/efforts/strength/sumo-deadlift.json +1 -1
  544. package/dist/web/server/seed/core/markdown/efforts/strength/thruster.json +1 -1
  545. package/dist/web/server/seed/core/markdown/efforts/strength/triceps-extension.json +1 -1
  546. package/dist/web/server/seed/core/markdown/efforts/strength/v-sit-hold.json +1 -1
  547. package/dist/web/server/seed/core/markdown/efforts/strength/wall-walk.json +1 -1
  548. package/dist/web/server/seed/core/markdown/efforts/strength/yoga-sun-salutation.json +1 -1
  549. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-assisted-sprint.json +1 -1
  550. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-backstroke.json +1 -1
  551. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-breaststroke-kick.json +1 -1
  552. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-breaststroke.json +1 -1
  553. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-butterfly.json +1 -1
  554. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-catch-up-drill.json +1 -1
  555. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-choice-stroke.json +1 -1
  556. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-dive-start.json +1 -1
  557. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-dolphin-kick.json +1 -1
  558. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-drafting.json +1 -1
  559. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-fingertip-drag.json +1 -1
  560. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-freestyle.json +1 -1
  561. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-individual-medley.json +1 -1
  562. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-kick.json +1 -1
  563. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-pull.json +1 -1
  564. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-resisted-sprint.json +1 -1
  565. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-rotation-drill.json +1 -1
  566. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-sighting.json +1 -1
  567. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-single-arm-drill.json +1 -1
  568. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-stroke-transition.json +1 -1
  569. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-two-kick-one-pull.json +1 -1
  570. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-vigorous.json +1 -1
  571. package/dist/web/server/seed/core/markdown/efforts/swimming/swimming.json +1 -1
  572. package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-arm-cast.json +1 -1
  573. package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-circles.json +1 -1
  574. package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-mill.json +1 -1
  575. package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-reverse-mill.json +1 -1
  576. package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-shield-cast.json +1 -1
  577. package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-10-to-2-swing.json +1 -1
  578. package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-360-swing.json +1 -1
  579. package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-barbarian-squat.json +1 -1
  580. package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-flow.json +1 -1
  581. package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-gravedigger.json +1 -1
  582. package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-touchdown.json +1 -1
  583. package/dist/web/server/seed/core/markdown/efforts/unconventional/sandbag-bear-hug-carry.json +1 -1
  584. package/dist/web/server/seed/core/markdown/efforts/unconventional/sandbag-bear-hug-extension.json +1 -1
  585. package/dist/web/server/seed/core/markdown/efforts/unconventional/sandbag-over-shoulder.json +1 -1
  586. package/dist/web/server/seed/core/markdown/efforts/walking/walking-3-mph.json +1 -1
  587. package/dist/web/server/seed/core/markdown/equipment/air-bike.json +1 -1
  588. package/dist/web/server/seed/core/markdown/equipment/barbell.json +1 -1
  589. package/dist/web/server/seed/core/markdown/equipment/bench.json +1 -1
  590. package/dist/web/server/seed/core/markdown/equipment/bike-erg.json +1 -1
  591. package/dist/web/server/seed/core/markdown/equipment/climbing-rope.json +1 -1
  592. package/dist/web/server/seed/core/markdown/equipment/clubs.json +1 -1
  593. package/dist/web/server/seed/core/markdown/equipment/dumbbell.json +1 -1
  594. package/dist/web/server/seed/core/markdown/equipment/ghd.json +1 -1
  595. package/dist/web/server/seed/core/markdown/equipment/gymnastic-rings.json +1 -1
  596. package/dist/web/server/seed/core/markdown/equipment/jump-rope.json +1 -1
  597. package/dist/web/server/seed/core/markdown/equipment/kettlebell.json +1 -1
  598. package/dist/web/server/seed/core/markdown/equipment/macebell.json +1 -1
  599. package/dist/web/server/seed/core/markdown/equipment/medicine-ball.json +1 -1
  600. package/dist/web/server/seed/core/markdown/equipment/parallettes.json +1 -1
  601. package/dist/web/server/seed/core/markdown/equipment/plyo-box.json +1 -1
  602. package/dist/web/server/seed/core/markdown/equipment/pull-up-bar.json +1 -1
  603. package/dist/web/server/seed/core/markdown/equipment/rower.json +1 -1
  604. package/dist/web/server/seed/core/markdown/equipment/sandbag.json +1 -1
  605. package/dist/web/server/seed/core/markdown/equipment/ski-erg.json +1 -1
  606. package/dist/web/server/seed/core/markdown/equipment/slam-ball.json +1 -1
  607. package/dist/web/server/seed/core/markdown/equipment/sled.json +1 -1
  608. package/dist/web/server/seed/core/markdown/equipment/sledgehammer.json +1 -1
  609. package/dist/web/server/seed/core/markdown/equipment/weight-vest.json +1 -1
  610. package/dist/web/server/seed/core/report.html +14 -15
  611. package/package.json +6 -6
  612. package/dist/chunk-BQ6HTRH3.mjs.map +0 -1
  613. package/dist/chunk-LGEZVB44.mjs.map +0 -1
  614. package/dist/chunk-SOGZC3TL.mjs.map +0 -1
  615. package/dist/compiler-V2BLOB2B.mjs +0 -9
  616. package/dist/scaffoldCatalog-WNAHHEL2.mjs.map +0 -1
  617. package/dist/web/playground/assets/main-Ba8fwabQ.js +0 -209
  618. package/dist/web/playground/assets/main-bpDz6cBb.css +0 -2
  619. package/dist/web/playground/assets/seedSync.worker-CXyhCqQv.js +0 -16
  620. package/dist/web/playground/seed/core/apps/playground/app/templates/new-playground.json +0 -39
  621. package/dist/web/playground/seed/core/chunks/canvas.4ae0f2d2.json +0 -1
  622. package/dist/web/playground/seed/core/chunks/template.2d38f4df.json +0 -1
  623. package/dist/web/playground/seed/core/indexes/notebooks/template.json +0 -18
  624. package/dist/web/playground/seed/core/markdown/canvas/home/README.json +0 -11
  625. package/dist/web/server/assets/main-CESv8JYf.js +0 -209
  626. package/dist/web/server/assets/main-bpDz6cBb.css +0 -2
  627. package/dist/web/server/assets/seedSync.worker-CXyhCqQv.js +0 -16
  628. package/dist/web/server/seed/core/apps/playground/app/templates/new-playground.json +0 -39
  629. package/dist/web/server/seed/core/chunks/canvas.4ae0f2d2.json +0 -1
  630. package/dist/web/server/seed/core/chunks/template.2d38f4df.json +0 -1
  631. package/dist/web/server/seed/core/indexes/notebooks/template.json +0 -18
  632. package/dist/web/server/seed/core/markdown/canvas/home/README.json +0 -11
@@ -5,7 +5,7 @@
5
5
  "blockIndex": [],
6
6
  "blockEfforts": [],
7
7
  "blockEquipment": [],
8
- "commit": "30e43c771d712a7c09bd8056d48d096ca769e705",
8
+ "commit": "32bda10ffc56a61ebfca76ae94f51eddba304498",
9
9
  "uuid": "a5c37d48-73da-5e5d-b0e3-53f08dce0fe8",
10
10
  "version": 1
11
11
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "path": "markdown/canvas/guide/README.md",
3
- "content": "# Learning Collection — Design Review & Page Map\n\n> **Status: SHIPPED (2026-10).** The eight chapters in this directory are the production guide: each carries `template: canvas` + `route: /guide/<slug>` frontmatter and renders as a live canvas page. The six editor chapters (start, protocols, structure, metrics, clock, sessions) have the sticky workout editor, chapter/quest gameplay, and Run; **wql and dashboards are sandbox chapters** — no workout editor or quests, but the sticky panel holds a live, editable ```query sandbox (wql: preset query tabs; dashboards: the real seeded boards loaded with live widgets). The old 18 routed learning pages (`syntax/*` hubs and routed chapters, `behaviors/*`, `analytics/*`) were deleted in the same cutover — §7 is the migration map that was applied, with no redirects left behind.\n>\n> Shipped vs contract, precisely: **§3.1–§3.3 (fresh note per Run, record exactly once including Stop, reset snapshots) are implemented in the canvas runtime and exercised for real** (first Run/Stop verified inline on a guide page). **§3.4–§5 (stage-driven run, sticky stage flow, reduced-motion runways) remain the homepage-rebuild contract** — these guide pages use the standard canvas sticky panel, not the stage machine. §1's counts and fixtures table are the **pre-cutover inventory** (historical: 18 routed learning pages then; today this directory's 8).\n\n**The shared example.** Every chapter from [First Workout](/guide/start) through Dashboards reuses one workout, `markdown/canvas/home/sample-script.md` verbatim:\n\n```time\n(3)\n 10 Kettlebell Swings 24kg\n *:30 Rest\n```\n\nYou edit it, run it, watch what the clock records (Metrics), query the records (WQL), and pin the query to a dashboard.\n\n---\n\n## 1. Design review of the pre-cutover learning surface (historical)\n\n**Exact routed count.** A route-frontmatter search across `markdown/` finds **20 routed pages**: syntax 8, analytics 6, behaviors 4, plus the homepage `canvas/home/README.md` (`/`) and `canvas/ai-first/README.md` (`/ai-first`). That gives **18 learning pages**. The inventory report's \"19 routed\" counted the homepage row but missed that `/ai-first` also carries `route:` frontmatter. Per scope, **homepage and `/ai-first` are product/marketing, not learning pages**, and are excluded from the collection (ai-first stays linked from First Workout as \"generate with AI\").\n\n**Orphans.** 65 of the 73 files in `markdown/canvas/syntax/` are non-routed tab-page fixtures (`search: hidden`, scroll-stage sources). They are compiled by tests and rendered only as scroll stages — several contradict their own routed captions. The collection de-orphans every unique topic without keeping the dead scroll plumbing.\n\n**Duplicates merged (unique topics preserved).**\n\n| Topic | Duplicates | Resolution |\n|---|---|---|\n| Calculated metrics ×3 | syntax/calculated-metrics.md (section document), custom-metrics-5.md (section custom-metrics), custom-and-calculated-metrics.md (section advanced) | one [Calculated](/guide/metrics?h=calculated) section in metrics.md |\n| AMRAP ×2 | protocols-1.md `20:00 (AMRAP)` vs classic-amrap.md `20:00 AMRAP` | keep the caption-blessed canonical `20:00 AMRAP` |\n| EMOM ×4 | protocols-2 `10:00 (EMOM)`, protocols-5 implicit, basic-emom `(10) :60 EMOM`, alternating/longer/custom variants | keep canonical `(10) :60 EMOM` + longer-interval + alternating branches |\n| Actions ×2 | supplemental-1 vs actions-comments | merged into [start.md#actions-comments](/guide/start?h=actions-comments) |\n| Rest ×2 | supplemental-2 vs timers-4 (both `*:30 Rest`) | merged into [protocols.md#required-rest](/guide/protocols?h=required-rest) |\n| Comments ×2 | supplemental-3 vs actions-comments | merged into start.md |\n| Unknown loads ×2 | supplemental-4 vs metrics-5 (`?lb`) | merged into [metrics.md#capture](/guide/metrics?h=capture) |\n| Cheatsheets ×2 | /guide/syntax/cheatsheet + /guide/analytics/cheatsheet | **no separate cheat-sheet page** — compact reference tables fold into [start.md#reference](/guide/start?h=reference) and [wql.md](/guide/wql?h=aggregate); 8 pages max |\n| Idioms tables | behaviors/README vs timers.md vs rounds.md (near row-for-row) | behaviors/README absorbed into [clock.md#run-next](/guide/clock?h=run-next) |\n| Prototype copies | root tour-redesign.prototype.html ≡ apps/playground copy | out of scope for markdown (IntegratedPrototype's); noted for cleanup |\n\n**Contradictions — resolved or flagged.** Ground truth = `packages/lang` parser/runtime + `packages/wql` vocabulary (verified in source, not from docs).\n\n| # | Docs say | Source says | Resolution in this collection |\n|---|---|---|---|\n| 1 | \"wrap your workout in a `wod` block\"; dialects page implies ```` ```wod ````/```` ```plan ````/```` ```climb ```` fences | runtime affords `time` (run) and `log` (record) fences only; dialect fixtures themselves use ```` ```time ````/```` ```log:climbing ```` | teach `time`/`log`/`log:climbing`; `wod`/`plan`/`climb` kept as *intent* vocabulary, flagged **needs validation** ([sessions.md#intent](/guide/sessions?h=intent)) |\n| 2 | home caption + prototypes: \"```` ```wql ```` for queries\"; cookbook shows ```wql copy blocks | real in-note fence is ```` ```query ````; no ```wql handling exists | use ```query everywhere; cookbook's ```wql snippet blocks flagged **needs validation** |\n| 3 | analytics/README + anatomy document `source:all` | parser hard-errors: \"source:all is retired — omit the source: filter\" | omitting `source:` **is** the all-sources default; never write `source:all` |\n| 4 | filters.md teaches singular `source:collection`/`source:feed` | every note belongs to `notebook/{slug}`; `notebook:<id>` pins a notebook and `WQL_SOURCE_VALUES` provides storage scopes | teach `notebook:<id>` and `notebook/{slug}`; `source:collection:<id>` remains a legacy storage-identity literal |\n| 5 | structure.md caption: name groups `(Warmup)`; named-groups/mixed-sections fixtures use `// Warmup` | classifier emits a labeled group node for `(Warmup)` (`RoundsMetric(label)`); `//` is a text comment — different mechanisms, both legal | both documented with the difference ([structure.md#named-sections](/guide/structure?h=named-sections)) |\n| 6 | `:?` placement: timers-3 prefixes (`:? Max Effort`), capture/cheatsheet append (`5:00 Run :?`) | `:?` is a standalone collectible-duration token; both positions parse | append taught as the convention; prefix noted as equally legal ([metrics.md#capture](/guide/metrics?h=capture)) |\n| 7 | behaviors/timers.md: movement without duration counts up; timers-5.md: \"no timer — stopwatch mode\" | `DurationMetric.direction`: value 0/undefined/collectible → **up** | same behavior, two descriptions: a bare movement runs a count-up stopwatch ([clock.md](/guide/clock)) |\n| 8 | capture.md queries `avg:wod.rpe by {week}` | no `wod.rpe` key exists anywhere; session RPE is typed metric `session-rpe` | corrected to `avg:session-rpe{} by {week}` ([metrics.md#session-rpe](/guide/metrics?h=session-rpe)) |\n| 9 | anatomy.md lists `metMinutes` as a base metric | vocabulary registers it as `calc.metMinutes` (engine-published) | listed under calculated metrics ([metrics.md#calculated](/guide/metrics?h=calculated)) |\n| 10 | prototypes use `{tag:benchmark}`, `{intensity:zone4}`, `since:2026-01-01` | real keys: `tags:`; intensity tiers `low|moderate|high`; windows `last <n>d|w` / `from … to …` | corrected vocabulary shipped in wql.md; IntegratedPrototype notified |\n| 11 | behaviors/README idiom `AMRAP 10` (label-first) | fixtures only show duration-first `20:00 AMRAP` (canonical per caption) | duration-first everywhere; label-first order flagged **needs validation** |\n| 12 | home/README still carries a retired 720vh ```scroll:chapters spec; HomeView error cites nonexistent routes/home.md | dead plumbing | out of scope here — flagged for the homepage rebuild owner |\n| 13 | behaviors/capture.md: `5:00 Run :?` asks for \"actual distance covered in the 5 minutes\"; \"prompt for load **before** the first squat\" | `:?` is a collectible **timer**: it mounts a count-up timer whose elapsed time is recorded on completion (compliance suites `timer.compliance`/`countup.compliance`; parse skill's collectible rule: prescribed time → collect distance with `?m`, prescribed distance → collect time with `:?`). No runtime evidence schedules a load prompt \"before the first rep\" — prompt timing is a capture-surface concern | metrics.md teaches the collectible family (`?` reps, `:?` time, `?lb`/`?kg` load, `?m`/`?km`/`?mile` distance) with prescribed-vs-outcome rule; prompt timing not asserted |\n\n**Honesty rules carried into every chapter.** No invented HR/trend numbers; calculated metrics document only real prerequisites (e.g. `calc.readiness` publishes a value for a day only when soreness, sleep, and HRV were all captured that day — verified in `calc/seeds.ts`). Unlanded `calc.*` surfaces render a labeled \"proposed\" placeholder in the app; dashboards label sample answers as sample.\n\n---\n\n## 2. The eight proposed pages\n\n| # | File | Proposed title | Sticky stages | Absorbs |\n|---|---|---|---|---|\n| 1 | [start.md](/guide/start) | First Workout | editor → runtime | basics.md, syntax/README hub, core syntax tab pages, the printable cheat sheet |\n| 2 | [protocols.md](/guide/protocols) | Timers & Protocols | editor → runtime | protocols.md, all timer/protocol tab pages, the timer half of behaviors/timers.md |\n| 3 | [structure.md](/guide/structure) | Structure & Rounds | editor → runtime | structure.md, group tab pages, behaviors/rounds.md |\n| 4 | [metrics.md](/guide/metrics) | Metrics: Planned, Recorded, Calculated | editor → runtime (results focus) | custom-metrics.md, metric/calculated tab pages, behaviors/capture.md |\n| 5 | [clock.md](/guide/clock) | Run, Track & Capture (the Clock) | editor → runtime (runtime is the subject) | behaviors/README.md, the runtime halves of timers.md/capture.md |\n| 6 | [wql.md](/guide/wql) | Query Your Training (WQL) | editor → WQL table (data focus) | analytics/README, anatomy, filters, joins |\n| 7 | [dashboards.md](/guide/dashboards) | Dashboards & Cookbook | WQL table → dashboard (data focus) | analytics/cookbook, the query-block half of analytics/cheatsheet, the 6 seeded boards |\n| 8 | [sessions.md](/guide/sessions) | Dialects & Complex Sessions | editor → runtime | dialects.md, complex.md, dialect/complex tab pages |\n\nThe stages column is mirrored verbatim in each page's chapter banner. Chapters 1–3 and 8 **run and save**; chapter 5 documents the runtime itself; chapters 4, 6, 7 focus on **reading the data** runs produce. No chapter defines its own result policy — every run saves under the one contract in [§3](#run-contract).\n\n### Common page model\n\nEvery chapter uses the same skeleton: `# Title`, chapter banner (chapter number, **Sticky stages** line, replaced routes, homepage placements), the teaching sections with their existing anchors, exactly one `## Try it {#try-it}`, and a one-line chapter footer (`**Next:** … · [Overview](/guide/start)`). A Try it block has three labeled parts — **Run** (what to paste/press), **Observe** (what the runtime should show), **Result query** where the chapter reads data — and any caption buttons reuse existing action labels only (`Run`, preset names, `Cast`); no invented controls, no duplicated nav prose.\n\nEntry and deep-link anchors (used by the homepage and the prototype's learn links):\n\n| Page | Entry anchor | Try it | Key deep anchors |\n|---|---|---|---|\n| start.md | `#first-workout` | `#try-it` | `#reference`, `#measurements` |\n| protocols.md | `#countdown-countup` | `#try-it` | `#amrap`, `#required-rest` |\n| structure.md | `#rounds` | `#try-it` | `#named-sections`, `#rep-schemes` |\n| metrics.md | `#planned-vs-recorded` | `#try-it` | `#capture`, `#calculated`, `#session-rpe` |\n| clock.md | `#run-next` | `#try-it` | `#casting`, `#provenance`, `#pause-skip`, `#capture-prompts` |\n| wql.md | `#planes` | `#try-it` | `#aggregate`, `#filters`, `#sources`, `#windows`, `#joins` |\n| dashboards.md | `#note-frontmatter` | `#try-it` | `#widgets`, `#cookbook`, `#seeded-boards`, `#composer` |\n| sessions.md | `#intent` | `#try-it` | `#full-session` |\n\nReading order is the numbered order; 1–3 teach writing, 4–5 teach what running records, 6–7 teach querying, 8 composes everything.\n\n---\n\n## 3. Run & save contract — today vs proposed {#run-contract}\n\n> **Everything in §3–§5 is PROPOSED** for the homepage rebuild and these eight chapters. \"Today\" statements come from source review of the intake/recorder seams, run refs, reset paths, and scroll drivers — no runtime behavior has been exercised, and nothing here is implemented. The eight drafts above carry **no `route:` frontmatter** and no runtime wiring.\n\n### 3.1 One active workspace, immutable run archive\n\n**Today.** One active persisted Note per *surface*: `ensurePlaygroundEntry` (`createPlaygroundPage.ts`) creates once, then **updates in place** under reuseKey `'home'`, `'chapter-<id>'`, or `canvas:<route>` (`getCanvasNoteId`, `canvasUtils.ts`) — deliberately, so the library doesn't fill with duplicate experiment entries. Fresh notes are minted only by explicit New/Reset page buttons, ZIP import, templates, and journal→playground copies (each named via `formatPlaygroundTimestampId`). Reset is in-memory only: `HomeTour.startNewSession` and `useCanvasRuntime.closeRun` unmount without recording — in-flight results are silently dropped.\n\n**Proposed.** Keep exactly one active **editable workspace** per surface — the hero editor remains the single authoring surface, sticky through its stage. Nothing overwrites the draft in place, and nothing is ever activated in place of a new note: **every Run creates a fresh note, and every Reset creates a separate fresh unstarted draft snapshot — both retained** (the extra archive entries are intentional; the user explicitly asked for clones of both). Reset finalizes the active run partial, restores the template content in the editor, and mints a fresh draft snapshot (status `reset-unstarted`) as its archive record; the next Run still mints its own fresh note — a reset draft is never activated. Snapshot name = `<page label> — <section label> — <formatPlaygroundTimestampId>`: labels taken verbatim from the page H1 and the section heading the run launched from; section is optional (hero runs use the section label `Run`); run state (`running` / `completed` / `stopped` / `reset-unstarted`) is note metadata, not a second naming scheme. One workspace ≠ one saved note — **all session data is always recorded**: the archive retains every run and reset snapshot; retention is §3.6.\n\n### 3.2 Create before run; capture identity at start\n\n**Today.** Runs already persist before execution: `ensurePlaygroundEntry` completes before the runtime mounts, and save failure = toast + abort — no execution without a saved note. Run identity `{noteId, resultId, block}` is captured once at start and never re-derived (`activeRun.current`, `useCanvasRuntime.ts:56`; `playgroundEntryRef`/`playgroundBlockRef`, `HomeTour.tsx:602-616`). Recording resolves `segmentId = runBlock?.id ?? blockId`, `blockContentId = runBlock?.contentId`, origin `'playground'` for playground notes (`resultRecorder.ts:104-133`); segment **version** is deferred to the persistence adapter at write time.\n\n**Proposed.** Unchanged mechanics, new target: the captured triple points at the run's **snapshot** note — minted fresh at every Run (never a reused reset draft) — and the snapshot **source** is captured at start the same way — captured results can never retroactively bind to a later-edited draft. Editing the draft mid-run is a *try-edit*: finalize the active run partial, halt, let the editor change live; the edited content becomes a snapshot only at the next Run.\n\n### 3.3 Record once — partial or full — with failure guards\n\n**Today.** `playgroundRecorder.record` is the only result seam; natural completion and Stop both record (Stop sends `completed:false`). But `handleWorkoutComplete` never consumes the captured run — a second completion call would re-record the same resultId — and reset paths drop without recording. Other sourced races: two concurrent same-reuseKey `ensureEntry` calls can mint two same-slug notes; `completeWorkout` (workbench) is a non-atomic two-write pair whose result-write failure is only console-logged.\n\n**Proposed.** One finalization path shared by **natural completion, Stop, and metrics-stage arrival** (entering the metrics stage stops the runtime and finalizes). Record **exactly once** per run — partial (`completed:false`) or full — by consuming the captured run on record (clear `activeRun.current` / generation check, or an id-keyed guard in the recorder). Guards:\n\n- **Reset while running:** finalize the partial first and **retain the snapshot — always, even with zero outputs**, marked reset/unstarted, with no fabricated performance rows (a zero-output note honestly records \"attempted, nothing captured\"; nothing is silently dropped). Reset then mints a **separate fresh unstarted draft snapshot** as its archive record; the next Run still creates its own fresh note — prepared/reset drafts are never activated (explicit user policy: each run creates a new note; the extra archive entry is requested).\n- **Save failure:** persist-before-run stays; a failed save must **never clear recorded output nor auto-start a new run** — the run and its results stay, retry is explicit.\n- Per-run snapshots retire the reuseKey race surface entirely (each run mints its own note; no shared-slug ensure).\n- In the HTML prototype, session recording stays **page-memory only** and is labelled visibly as such; production records through the recorder seam.\n\n### 3.4 No fullscreen; stage-driven run\n\n**Today.** Run mounts a fullscreen overlay (`TourTimerScreen` tour-side, `FullscreenTimer` canvas-side) with autostart gated in `RuntimeTimerPanel` (`(autoStart||pendingStart)&&ready&&idle`).\n\n**Proposed.** Run scrolls to the **inline runtime stage** — no fullscreen. Arrival autostarts **once per run**. Captions offer existing actions only, as optional explicit buttons (`Run`, `Next`, `Stop`, `Cast` — real control labels/testids, no hidden auto-Next, no auto-cast; the autoplay entrance is user-scroll-triggered). A previous runtime resumes only via explicit **Run** (which always mints a new snapshot).\n\n### 3.5 Stage observers are idempotent\n\nBackward scroll never restarts a run nor replays a one-shot stage effect (renormalized progress + reached-once guards, the `useReachedOnce` pattern). Forward **fast scroll** that resolves straight to a later stage cannot launch the skipped runtime stage: the stage machine emits one discrete stage per frame (`resolveScrollStage`), so skipped stages' enter effects (autostart included) never fire. Every stage-enter effect runs once per run, not once per direction.\n\n### 3.6 Bounded seams and cleanup scope\n\nAll changes are bounded to existing seams — no new subsystem:\n\n1. **Snapshot naming** — a policy inside `createPlaygroundIntake` (the single note-minting seam); callers (`HomeTour`, `useCanvasRuntime`) keep their signatures. Explicit New/Reset page buttons keep today's `createPage` semantics.\n2. **Record-once** — a guard at the recorder or the run hooks (consume captured run / id-keyed guard), closing the double-record race before any autostart re-runs exist.\n3. **Partial finalize on reset** — a `completed:false` record at the two reset points (`HomeTour.startNewSession`, `useCanvasRuntime.closeRun`), retained even at zero outputs, then a separate fresh unstarted draft snapshot is minted (Run never activates it).\n4. **One active session owner** — generalize the `useCanvasRuntime` pattern instead of scattered refs (HomeTour refs vs canvas `activeRun` vs workbench store). **The workbench keeps its own multi-note session store** (`completeWorkout`, autosave, `resetStore`): it serves journal/workbench routes and promotion — one-active is a *playground-surface policy*, not a storage policy. Don't delete general workbench multi-note session support because the homepage is one-active.\n5. **Retention** — snapshot growth is handled by the existing promotion invariant (`movePlaygroundToJournal` — moved notes can never be hijacked by a later same-key ensure) and `find:note{source:playground}` scoping, not new deletion logic.\n\n**Cleanup scope when the collection is approved** (not before — nothing here routes the eight drafts or retires any `/guide/*` route):\n\n- Safe to retire with their routed parents: the 65 non-routed syntax tab-page fixtures and their ```scroll stage plumbing (they exist as scroll-stage sources for routed pages), the duplicate prototype HTML copy (keep one canonical), the `ProtoTimerMobile` throwaway (`?proto-timer`), the retired 720vh ```scroll:chapters spec in `canvas/home/README.md`.\n- **Out of scope:** workbench/journal session store and its wiring, collections/feeds/journal surfaces, promotion, chapter-run reuse — multi-note session support serves routes beyond the homepage and survives a one-active homepage.\n\n---\n\n## 4. Sticky stage flow (desktop & mobile)\n\nFour sticky stages in page order: **editor → runtime → WQL table → dashboard**. Desktop is native **sticky push-off**: each stage is a tall section whose card sticks at the nav offset (`STICKY_NAV_HEIGHT` = 104px, card `h-[calc(100vh-104px)]` — the `TourSectionRunway` pattern) and is pushed off by the next stage's sticky card, driven by the existing pure stage machine (`resolveScrollStage` with clamp01/renormalize over a capture-phase scroll listener). The hero editor is **one reused instance** sticking through stage 1. Run scrolls editor→runtime; **Stop (or metrics arrival) slides the metrics view in**; the **WQL table stage** sticks bound to the **current run's facts**, with caption query actions (real queries, `ParsedQueryChips` vocabulary) and a floating **\"Revert current session\"** that re-binds the table to the current run — discarding view-state (query tweaks, sample overlay) only; the **dashboard stage** sticks a board with **load buttons** for the seeded boards.\n\nMobile (≤1023px, `MOBILE_BREAKPOINT_PX`): **bounded sticky stage windows** — one stage card at a time in the reading zone (top 65px window, `MOBILE_STICKY_TOP`), captions **below** the card, card-visibility IntersectionObserver as the stage driver (the `TourMobileRunway` pattern). Same stage order, same run contract.\n\nReduced motion wins everywhere (`RunwayAdapter`: reduced > mobile > desktop): flat card stack, no push-off, no scroll scrub; stage arrival is visibility-based and still once-per-run.\n\nGuarantees on every form factor:\n\n- Runtime arrival autostarts once; backward scroll never restarts; fast scroll to a later stage cannot launch the skipped runtime (§3.5).\n- Caption actions are explicit buttons using existing labels; no hidden auto-Next/auto-cast.\n- Sample fallbacks are badged **sample**; sample datasets and dashboard/board edits never mutate saved session results; **Revert** restores view only.\n\n---\n\n## 5. System organization\n\n| Term | Purpose | Scope / storage |\n|---|---|---|\n| **Note** | the markdown document + identity (uuidv7 id, slug, sourceId, type) | one IndexedDB store (notes + results + attachments + analytics) |\n| **Page** | a note bound to a surface (routed guide page, playground home/canvas) | bindings via reuseKey / `getCanvasNoteId` |\n| **Block** | one addressable fenced unit in a note; the run target | Block Content Id = content hash, stable across reorders/clones |\n| **Effort** | named workout registry entry (e.g. *fran*) | content-plane query target; aggregates `by {effort}` |\n| **Session** | one recorded run | `{noteId, resultId, block}` triple; results join `Session.noteId` |\n| **Journal** | default dated training notebook (`notebook/journal`) | `notebook:journal` (`source:journal`); promotion target |\n| **Playground** | default experiment notebook (`notebook/playground`) | `notebook:playground` (`source:playground`); run snapshots archive here until promoted |\n| **Notebook** | user-created or seed-delivered notebook (`notebook/{slug}`) | `notebook:<id>` (`source:notebooks`); seed notebooks are read-only and clone into writable notebooks |\n| **Dashboard** | a note with `dashboard: true`; its query blocks render as widgets | vault (editable) vs prebuilt (read-only, clone) |\n\n**`notebook:` & `source:` scope.** Filter by `notebook:<id>` (`journal`, `playground`, `guides`, `crossfit-girls`, etc.) or plural `source:` values; omitting both searches all notes. Learning runs record in `notebook/playground` until promotion re-homes the note to `notebook/journal`.\n\n**Session vs template vs sample dataset vs revert.**\n\n- **Session** — immutable recorded facts from one run against its snapshot note.\n- **Template** — read-only source content (`sample-script.md`, `WORKOUT_PRESETS`, catalog sessions, seeded boards). Running a template copies it into the active workspace/snapshot; **templates never mutate**.\n- **Sample dataset** — the SAMPLE fallback (`SAMPLE_HOME_ANALYTICS`, `SampleDataPrompt`) shown when the store has no facts; always badged sample; never persisted as your results.\n- **Revert** (\"Revert current session\") — discards view-state only (query tweaks, sample overlay) and re-binds the stage to the current run's recorded facts; never deletes saved sessions.\n\n---\n\n## 6. Homepage placements (existing slots only)\n\n| Homepage slot | Proposed links |\n|---|---|\n| Hero / editor-blank caption | \"Start Lesson 1\" → start.md#first-workout; add \"See the full syntax\" → start.md#reference |\n| 01 Write — editor-metrics caption | add \"What each line collects\" → metrics.md |\n| 01 Write — WORKOUT_PRESETS | each preset mirrors a protocols.md / structure.md example |\n| 02 Run — behaviors caption | point \"Read the behaviors explainer\" → clock.md |\n| 02 Run — timer-cast caption | clock.md#casting |\n| 03 Own — metrics-d (\"Measures ride along\") | add action → metrics.md |\n| 03 Own — metrics-c (\"Efforts × measures compound\") | add teaser → wql.md |\n| 04 Explore (currently no inline analytics links; `home:analytics_guide_opened` telemetry declared but never fired) | header actions: \"WQL in depth\" → wql.md, \"Copy-paste queries\" → dashboards.md#cookbook; wql-dashboard/wql-live captions → dashboards.md#seeded-boards |\n| CelebrationBridge (\"Now learn the language\") | render the 8-chapter map as the card row |\n| TourChapterPicker / TourLearnSection | CHAPTER_ROUTES gains the 8 files |\n| Footer \"Where to next?\" | add Learn column: start.md, wql.md, dashboards.md |\n| /ai-first | stays a standalone marketing page, linked from start.md (\"Generate with AI\") |\n\n## 7. Old route → new page/anchor map\n\nConcrete migration map for the 18 currently routed learning pages. Slugs follow the current routed files under `markdown/canvas/`; the eight targets are §2's files. **Both cheatsheets are absorbed into existing pages — there is no ninth page.** Nothing routes or redirects until the collection is approved; until then both trees coexist.\n\n| Old location (routed file) | New target |\n|---|---|\n| `syntax/README.md` (hub) | [start.md](/guide/start) header + [sessions.md#intent](/guide/sessions?h=intent) |\n| `syntax/basics.md` | [start.md#first-workout](/guide/start?h=first-workout) |\n| `syntax/protocols.md` | [protocols.md#countdown-countup](/guide/protocols?h=countdown-countup) |\n| `syntax/structure.md` | [structure.md#rounds](/guide/structure?h=rounds) |\n| `syntax/custom-metrics.md` | [metrics.md#planned-vs-recorded](/guide/metrics?h=planned-vs-recorded) |\n| `syntax/dialects.md` | [sessions.md#intent](/guide/sessions?h=intent) |\n| `syntax/complex.md` | [sessions.md#full-session](/guide/sessions?h=full-session) |\n| `syntax/cheatsheet.md` | [start.md#reference](/guide/start?h=reference) — **cheatsheet #1 absorbed** |\n| `behaviors/README.md` | [clock.md#run-next](/guide/clock?h=run-next) |\n| `behaviors/timers.md` | [protocols.md](/guide/protocols) (syntax forms) + [clock.md#pause-skip](/guide/clock?h=pause-skip) (runtime) |\n| `behaviors/rounds.md` | [structure.md#rep-schemes](/guide/structure?h=rep-schemes) + [clock.md#run-next](/guide/clock?h=run-next) |\n| `behaviors/capture.md` | [metrics.md#capture](/guide/metrics?h=capture) + [clock.md#capture-prompts](/guide/clock?h=capture-prompts) |\n| `analytics/README.md` | [wql.md#planes](/guide/wql?h=planes) |\n| `analytics/anatomy.md` | [wql.md#aggregate](/guide/wql?h=aggregate) |\n| `analytics/filters.md` | [wql.md#filters](/guide/wql?h=filters) · [#sources](/guide/wql?h=sources) · [#windows](/guide/wql?h=windows) |\n| `analytics/joins.md` | [wql.md#joins](/guide/wql?h=joins) |\n| `analytics/cookbook.md` | [dashboards.md#cookbook](/guide/dashboards?h=cookbook) |\n| `analytics/cheatsheet.md` | [wql.md#aggregate](/guide/wql?h=aggregate) tables + [dashboards.md#widgets](/guide/dashboards?h=widgets) — **cheatsheet #2 absorbed** |\n\nThe 65 non-routed tab-page fixtures follow their routed parents (their unique content is already merged — §8). `canvas/home/README.md` (homepage) and `canvas/ai-first/README.md` stay product pages, out of the collection.\n\n## 8. Source coverage\n\nEvery routed learning page (18) and every underlying non-routed lesson source (65 syntax tab pages + 2 home sources), mapped to its target. Merged duplicates list only once with their union.\n\n| Current source (routed unless marked) | Topics kept | → New page |\n|---|---|---|\n| syntax/README.md (hub) | core concepts map, dialect intro, new-note CTA | start.md (header/TOC), sessions.md#intent |\n| syntax/basics.md | fences, one-thing-per-line, indentation, measurements, `?lb`, effort words, actions, comments | start.md |\n| syntax/protocols.md + timers-rest, timer-modifiers, timers-1..5, longer-duration, mixed-timers, classic-amrap, time-cap, multiple-amrap-windows, basic-emom, longer-intervals, alternating-emom, protocols-1..5, custom-intervals, distance-intervals, supplemental-2 | countdown/countup/`^`/`*`/`:?`, H:MM:SS, AMRAP, caps, EMOM family, Tabata, intervals, rest | protocols.md |\n| syntax/structure.md + groups-1..4, named-groups, mixed-sections, multiple-sets | rounds, rep schemes, nesting, named sections, sets | structure.md |\n| syntax/custom-metrics.md + custom-metrics-1..5, calculated-metrics, custom-and-calculated-metrics, metrics-1..5, supplemental-4 | inline JSON, rpe/rir, multi-metric lines, calculate blocks, JSON rules, unknown loads `?lb`/`?kg` | metrics.md |\n| syntax/dialects.md + dialect-wod/log/plan, dialect-climb-bouldering/hangboard/sport | intent distinction, `log:climbing`, climbing signals | sessions.md |\n| syntax/complex.md + complex-nested-protocols, complex-full-session, complex-barbell-cycling, complex-partner-workout, complex-swimming | nested protocols, full session, EMOM chains, partner windows, swimming | sessions.md |\n| syntax/cheatsheet.md (routed) | one-page syntax | start.md#reference + per-page tables (no separate page) |\n| syntax/single-movement, core-rules, measurements, effort-notes, actions-comments, supplemental-1, supplemental-3, document-1..4, welcome-1 (home/), sample-script.md (home/) | smallest workout, three rules, headers/checklists/equipment-table document patterns, actions/comments | start.md |\n| behaviors/README.md | script→parse→compile→track, 3 behavior families, idioms | clock.md |\n| behaviors/timers.md | timer strategy selection, sound/pause/skip/required-rest | clock.md (+ protocols.md for syntax forms) |\n| behaviors/rounds.md | round behavior, rep math, supersets, interval groups, rounds↔timers | structure.md (+ clock.md) |\n| behaviors/capture.md | `:?`, `?lb`/`?kg`, session RPE, trendlines, fact origins | metrics.md (+ clock.md for prompt behavior) |\n| analytics/README.md | 3 WQL surfaces, 2 query planes, where-join | wql.md |\n| analytics/anatomy.md | aggregators, base/calc metrics, dimensions, rollups, find targets | wql.md |\n| analytics/filters.md | tag filters (negation/OR/substring), source filters, time windows, Library tri-state toggles | wql.md |\n| analytics/joins.md | where joins, Block Content Id mechanics | wql.md |\n| analytics/cookbook.md | 5 canonical queries, ```query embeds, dashboard notes, widget types/spans | dashboards.md (+ wql.md) |\n| analytics/cheatsheet.md | WQL one-pager | wql.md tables + dashboards.md#widgets (no separate page) |\n| markdown/dashboards/training-block-review.md | widget exemplars (see dashboards.md#seeded-boards) | dashboards.md |\n| markdown/dashboards/road-to-560-total.md | strength PR board exemplar | dashboards.md#seeded-boards |\n| markdown/dashboards/polarized-base-marathon.md | endurance polarization exemplar | dashboards.md#seeded-boards |\n| markdown/dashboards/finger-strength-v8.md | climbing board exemplar (wellness capture, `calc.mvcBw`) | dashboards.md#seeded-boards |\n| markdown/dashboards/benchmark-pr-board.md | benchmark table exemplar (`last:elapsed{tags:benchmark}`) | dashboards.md#seeded-boards |\n| markdown/dashboards/recovery-readiness.md | ```wellness capture + readiness exemplar | dashboards.md#seeded-boards (+ metrics.md#calculated) |\n\nNot counted as learning sources: `canvas/home/README.md` (product walkthrough — the homepage itself stays), `canvas/ai-first/README.md` (AI marketing, linked as an aside). Orphaned scroll plumbing (```scroll blocks, getTabExamples/getHomeExample, protocols-1's `(AMRAP)` spelling) is dropped, not migrated.\n\n## 9. Review method\n\nEach chapter ends with a **Try it** block: what to paste/press, what the runtime should show, and — for data chapters — the result query — a reviewer checklist, not a test report. Every syntax, behavior, and query claim in this collection comes from **source review only** (parser grammar, compiler metrics, WQL vocabulary/seeds, shipped fixtures). That was true at review time; since the cutover the chapters are production pages — the §3.1–§3.3 run/save behavior is implemented and exercised, while §3.4–§5 (stage flow) stay contract-only (see the status block).\n",
3
+ "content": "# Learning Collection — Design Review & Page Map\n\n> **Status: SHIPPED (2026-10).** The eight chapters in this directory are the production guide: each carries `template: canvas` + `route: /page/guide-<slug>` frontmatter and renders as a live canvas page. The six editor chapters (start, protocols, structure, metrics, clock, sessions) have the sticky workout editor, chapter/quest gameplay, and Run; **wql and dashboards are sandbox chapters** — no workout editor or quests, but the sticky panel holds a live, editable ```query sandbox (wql: preset query tabs; dashboards: the real seeded boards loaded with live widgets). The old 18 routed learning pages (`syntax/*` hubs and routed chapters, `behaviors/*`, `analytics/*`) were deleted in the same cutover — §7 is the migration map that was applied, with no redirects left behind.\n>\n> Shipped vs contract, precisely: **§3.1–§3.3 (fresh note per Run, record exactly once including Stop, reset snapshots) are implemented in the canvas runtime and exercised for real** (first Run/Stop verified inline on a guide page). **§3.4–§5 (stage-driven run, sticky stage flow, reduced-motion runways) remain the homepage-rebuild contract** — these guide pages use the standard canvas sticky panel, not the stage machine. §1's counts and fixtures table are the **pre-cutover inventory** (historical: 18 routed learning pages then; today this directory's 8).\n\n**The shared example.** Every chapter from [First Workout](/page/guide-start) through Dashboards reuses one workout, `markdown/canvas/home/sample-script.md` verbatim:\n\n```time\n(3)\n 10 Kettlebell Swings 24kg\n *:30 Rest\n```\n\nYou edit it, run it, watch what the clock records (Metrics), query the records (WQL), and pin the query to a dashboard.\n\n---\n\n## 1. Design review of the pre-cutover learning surface (historical)\n\n**Exact routed count.** A route-frontmatter search across `markdown/` finds **20 routed pages**: syntax 8, analytics 6, behaviors 4, plus the homepage `canvas/home/README.md` (`/`) and `canvas/ai-first/README.md` (`/ai-first`). That gives **18 learning pages**. The inventory report's \"19 routed\" counted the homepage row but missed that `/ai-first` also carries `route:` frontmatter. Per scope, **homepage and `/ai-first` are product/marketing, not learning pages**, and are excluded from the collection (ai-first stays linked from First Workout as \"generate with AI\").\n\n**Orphans.** 65 of the 73 files in `markdown/canvas/syntax/` are non-routed tab-page fixtures (`search: hidden`, scroll-stage sources). They are compiled by tests and rendered only as scroll stages — several contradict their own routed captions. The collection de-orphans every unique topic without keeping the dead scroll plumbing.\n\n**Duplicates merged (unique topics preserved).**\n\n| Topic | Duplicates | Resolution |\n|---|---|---|\n| Calculated metrics ×3 | syntax/calculated-metrics.md (section document), custom-metrics-5.md (section custom-metrics), custom-and-calculated-metrics.md (section advanced) | one [Calculated](/page/guide-metrics?h=calculated) section in metrics.md |\n| AMRAP ×2 | protocols-1.md `20:00 (AMRAP)` vs classic-amrap.md `20:00 AMRAP` | keep the caption-blessed canonical `20:00 AMRAP` |\n| EMOM ×4 | protocols-2 `10:00 (EMOM)`, protocols-5 implicit, basic-emom `(10) :60 EMOM`, alternating/longer/custom variants | keep canonical `(10) :60 EMOM` + longer-interval + alternating branches |\n| Actions ×2 | supplemental-1 vs actions-comments | merged into [start.md#actions-comments](/page/guide-start?h=actions-comments) |\n| Rest ×2 | supplemental-2 vs timers-4 (both `*:30 Rest`) | merged into [protocols.md#required-rest](/page/guide-protocols?h=required-rest) |\n| Comments ×2 | supplemental-3 vs actions-comments | merged into start.md |\n| Unknown loads ×2 | supplemental-4 vs metrics-5 (`?lb`) | merged into [metrics.md#capture](/page/guide-metrics?h=capture) |\n| Cheatsheets ×2 | /guide/syntax/cheatsheet + /guide/analytics/cheatsheet | **no separate cheat-sheet page** — compact reference tables fold into [start.md#reference](/page/guide-start?h=reference) and [wql.md](/page/guide-wql?h=aggregate); 8 pages max |\n| Idioms tables | behaviors/README vs timers.md vs rounds.md (near row-for-row) | behaviors/README absorbed into [clock.md#run-next](/page/guide-clock?h=run-next) |\n| Prototype copies | root tour-redesign.prototype.html ≡ apps/playground copy | out of scope for markdown (IntegratedPrototype's); noted for cleanup |\n\n**Contradictions — resolved or flagged.** Ground truth = `packages/lang` parser/runtime + `packages/wql` vocabulary (verified in source, not from docs).\n\n| # | Docs say | Source says | Resolution in this collection |\n|---|---|---|---|\n| 1 | \"wrap your workout in a `wod` block\"; dialects page implies ```` ```wod ````/```` ```plan ````/```` ```climb ```` fences | runtime affords `time` (run) and `log` (record) fences only; dialect fixtures themselves use ```` ```time ````/```` ```log:climbing ```` | teach `time`/`log`/`log:climbing`; `wod`/`plan`/`climb` kept as *intent* vocabulary, flagged **needs validation** ([sessions.md#intent](/page/guide-sessions?h=intent)) |\n| 2 | home caption + prototypes: \"```` ```wql ```` for queries\"; cookbook shows ```wql copy blocks | real in-note fence is ```` ```query ````; no ```wql handling exists | use ```query everywhere; cookbook's ```wql snippet blocks flagged **needs validation** |\n| 3 | analytics/README + anatomy document `source:all` | parser hard-errors: \"source:all is retired — omit the source: filter\" | omitting `source:` **is** the all-sources default; never write `source:all` |\n| 4 | filters.md teaches singular `source:collection`/`source:feed` | every note belongs to `notebook/{slug}`; `notebook:<id>` pins a notebook and `WQL_SOURCE_VALUES` provides storage scopes | teach `notebook:<id>` and `notebook/{slug}`; the retired `collection:`/`feed:` source literals hard-error at parse time (ticket 12) and stored occurrences rewrite to `notebook:` on read |\n| 5 | structure.md caption: name groups `(Warmup)`; named-groups/mixed-sections fixtures use `// Warmup` | classifier emits a labeled group node for `(Warmup)` (`RoundsMetric(label)`); `//` is a text comment — different mechanisms, both legal | both documented with the difference ([structure.md#named-sections](/page/guide-structure?h=named-sections)) |\n| 6 | `:?` placement: timers-3 prefixes (`:? Max Effort`), capture/cheatsheet append (`5:00 Run :?`) | `:?` is a standalone collectible-duration token; both positions parse | append taught as the convention; prefix noted as equally legal ([metrics.md#capture](/page/guide-metrics?h=capture)) |\n| 7 | behaviors/timers.md: movement without duration counts up; timers-5.md: \"no timer — stopwatch mode\" | `DurationMetric.direction`: value 0/undefined/collectible → **up** | same behavior, two descriptions: a bare movement runs a count-up stopwatch ([clock.md](/page/guide-clock)) |\n| 8 | capture.md queries `avg:wod.rpe by {week}` | no `wod.rpe` key exists anywhere; session RPE is typed metric `session-rpe` | corrected to `avg:session-rpe{} by {week}` ([metrics.md#session-rpe](/page/guide-metrics?h=session-rpe)) |\n| 9 | anatomy.md lists `metMinutes` as a base metric | vocabulary registers it as `calc.metMinutes` (engine-published) | listed under calculated metrics ([metrics.md#calculated](/page/guide-metrics?h=calculated)) |\n| 10 | prototypes use `{tag:benchmark}`, `{intensity:zone4}`, `since:2026-01-01` | real keys: `tags:`; intensity tiers `low|moderate|high`; windows `last <n>d|w` / `from … to …` | corrected vocabulary shipped in wql.md; IntegratedPrototype notified |\n| 11 | behaviors/README idiom `AMRAP 10` (label-first) | fixtures only show duration-first `20:00 AMRAP` (canonical per caption) | duration-first everywhere; label-first order flagged **needs validation** |\n| 12 | home/README still carries a retired 720vh ```scroll:chapters spec; HomeView error cites nonexistent routes/home.md | dead plumbing | out of scope here — flagged for the homepage rebuild owner |\n| 13 | behaviors/capture.md: `5:00 Run :?` asks for \"actual distance covered in the 5 minutes\"; \"prompt for load **before** the first squat\" | `:?` is a collectible **timer**: it mounts a count-up timer whose elapsed time is recorded on completion (compliance suites `timer.compliance`/`countup.compliance`; parse skill's collectible rule: prescribed time → collect distance with `?m`, prescribed distance → collect time with `:?`). No runtime evidence schedules a load prompt \"before the first rep\" — prompt timing is a capture-surface concern | metrics.md teaches the collectible family (`?` reps, `:?` time, `?lb`/`?kg` load, `?m`/`?km`/`?mile` distance) with prescribed-vs-outcome rule; prompt timing not asserted |\n\n**Honesty rules carried into every chapter.** No invented HR/trend numbers; calculated metrics document only real prerequisites (e.g. `calc.readiness` publishes a value for a day only when soreness, sleep, and HRV were all captured that day — verified in `calc/seeds.ts`). Unlanded `calc.*` surfaces render a labeled \"proposed\" placeholder in the app; dashboards label sample answers as sample.\n\n---\n\n## 2. The eight proposed pages\n\n| # | File | Proposed title | Sticky stages | Absorbs |\n|---|---|---|---|---|\n| 1 | [start.md](/page/guide-start) | First Workout | editor → runtime | basics.md, syntax/README hub, core syntax tab pages, the printable cheat sheet |\n| 2 | [protocols.md](/page/guide-protocols) | Timers & Protocols | editor → runtime | protocols.md, all timer/protocol tab pages, the timer half of behaviors/timers.md |\n| 3 | [structure.md](/page/guide-structure) | Structure & Rounds | editor → runtime | structure.md, group tab pages, behaviors/rounds.md |\n| 4 | [metrics.md](/page/guide-metrics) | Metrics: Planned, Recorded, Calculated | editor → runtime (results focus) | custom-metrics.md, metric/calculated tab pages, behaviors/capture.md |\n| 5 | [clock.md](/page/guide-clock) | Run, Track & Capture (the Clock) | editor → runtime (runtime is the subject) | behaviors/README.md, the runtime halves of timers.md/capture.md |\n| 6 | [wql.md](/page/guide-wql) | Query Your Training (WQL) | editor → WQL table (data focus) | analytics/README, anatomy, filters, joins |\n| 7 | [dashboards.md](/page/guide-dashboards) | Dashboards & Cookbook | WQL table → dashboard (data focus) | analytics/cookbook, the query-block half of analytics/cheatsheet, the 6 seeded boards |\n| 8 | [sessions.md](/page/guide-sessions) | Dialects & Complex Sessions | editor → runtime | dialects.md, complex.md, dialect/complex tab pages |\n\nThe stages column is mirrored verbatim in each page's chapter banner. Chapters 1–3 and 8 **run and save**; chapter 5 documents the runtime itself; chapters 4, 6, 7 focus on **reading the data** runs produce. No chapter defines its own result policy — every run saves under the one contract in [§3](#run-contract).\n\n### Common page model\n\nEvery chapter uses the same skeleton: `# Title`, chapter banner (chapter number, **Sticky stages** line, replaced routes, homepage placements), the teaching sections with their existing anchors, exactly one `## Try it {#try-it}`, and a one-line chapter footer (`**Next:** … · [Overview](/page/guide-start)`). A Try it block has three labeled parts — **Run** (what to paste/press), **Observe** (what the runtime should show), **Result query** where the chapter reads data — and any caption buttons reuse existing action labels only (`Run`, preset names, `Cast`); no invented controls, no duplicated nav prose.\n\nEntry and deep-link anchors (used by the homepage and the prototype's learn links):\n\n| Page | Entry anchor | Try it | Key deep anchors |\n|---|---|---|---|\n| start.md | `#first-workout` | `#try-it` | `#reference`, `#measurements` |\n| protocols.md | `#countdown-countup` | `#try-it` | `#amrap`, `#required-rest` |\n| structure.md | `#rounds` | `#try-it` | `#named-sections`, `#rep-schemes` |\n| metrics.md | `#planned-vs-recorded` | `#try-it` | `#capture`, `#calculated`, `#session-rpe` |\n| clock.md | `#run-next` | `#try-it` | `#casting`, `#provenance`, `#pause-skip`, `#capture-prompts` |\n| wql.md | `#planes` | `#try-it` | `#aggregate`, `#filters`, `#sources`, `#windows`, `#joins` |\n| dashboards.md | `#note-frontmatter` | `#try-it` | `#widgets`, `#cookbook`, `#seeded-boards`, `#composer` |\n| sessions.md | `#intent` | `#try-it` | `#full-session` |\n\nReading order is the numbered order; 1–3 teach writing, 4–5 teach what running records, 6–7 teach querying, 8 composes everything.\n\n---\n\n## 3. Run & save contract — today vs proposed {#run-contract}\n\n> **Everything in §3–§5 is PROPOSED** for the homepage rebuild and these eight chapters. \"Today\" statements come from source review of the intake/recorder seams, run refs, reset paths, and scroll drivers — no runtime behavior has been exercised, and nothing here is implemented. The eight drafts above carry **no `route:` frontmatter** and no runtime wiring.\n\n### 3.1 One active workspace, immutable run archive\n\n**Today.** One active persisted Note per *surface*: `ensurePlaygroundEntry` (`createPlaygroundPage.ts`) creates once, then **updates in place** under reuseKey `'home'`, `'chapter-<id>'`, or `canvas:<route>` (`getCanvasNoteId`, `canvasUtils.ts`) — deliberately, so the library doesn't fill with duplicate experiment entries. Fresh notes are minted only by explicit New/Reset page buttons, ZIP import, templates, and journal→playground copies (each named via `formatPlaygroundTimestampId`). Reset is in-memory only: `HomeTour.startNewSession` and `useCanvasRuntime.closeRun` unmount without recording — in-flight results are silently dropped.\n\n**Proposed.** Keep exactly one active **editable workspace** per surface — the hero editor remains the single authoring surface, sticky through its stage. Nothing overwrites the draft in place, and nothing is ever activated in place of a new note: **every Run creates a fresh note, and every Reset creates a separate fresh unstarted draft snapshot — both retained** (the extra archive entries are intentional; the user explicitly asked for clones of both). Reset finalizes the active run partial, restores the template content in the editor, and mints a fresh draft snapshot (status `reset-unstarted`) as its archive record; the next Run still mints its own fresh note — a reset draft is never activated. Snapshot name = `<page label> — <section label> — <formatPlaygroundTimestampId>`: labels taken verbatim from the page H1 and the section heading the run launched from; section is optional (hero runs use the section label `Run`); run state (`running` / `completed` / `stopped` / `reset-unstarted`) is note metadata, not a second naming scheme. One workspace ≠ one saved note — **all session data is always recorded**: the archive retains every run and reset snapshot; retention is §3.6.\n\n### 3.2 Create before run; capture identity at start\n\n**Today.** Runs already persist before execution: `ensurePlaygroundEntry` completes before the runtime mounts, and save failure = toast + abort — no execution without a saved note. Run identity `{noteId, resultId, block}` is captured once at start and never re-derived (`activeRun.current`, `useCanvasRuntime.ts:56`; `playgroundEntryRef`/`playgroundBlockRef`, `HomeTour.tsx:602-616`). Recording resolves `segmentId = runBlock?.id ?? blockId`, `blockContentId = runBlock?.contentId`, origin `'playground'` for playground notes (`resultRecorder.ts:104-133`); segment **version** is deferred to the persistence adapter at write time.\n\n**Proposed.** Unchanged mechanics, new target: the captured triple points at the run's **snapshot** note — minted fresh at every Run (never a reused reset draft) — and the snapshot **source** is captured at start the same way — captured results can never retroactively bind to a later-edited draft. Editing the draft mid-run is a *try-edit*: finalize the active run partial, halt, let the editor change live; the edited content becomes a snapshot only at the next Run.\n\n### 3.3 Record once — partial or full — with failure guards\n\n**Today.** `playgroundRecorder.record` is the only result seam; natural completion and Stop both record (Stop sends `completed:false`). But `handleWorkoutComplete` never consumes the captured run — a second completion call would re-record the same resultId — and reset paths drop without recording. Other sourced races: two concurrent same-reuseKey `ensureEntry` calls can mint two same-slug notes; `completeWorkout` (workbench) is a non-atomic two-write pair whose result-write failure is only console-logged.\n\n**Proposed.** One finalization path shared by **natural completion, Stop, and metrics-stage arrival** (entering the metrics stage stops the runtime and finalizes). Record **exactly once** per run — partial (`completed:false`) or full — by consuming the captured run on record (clear `activeRun.current` / generation check, or an id-keyed guard in the recorder). Guards:\n\n- **Reset while running:** finalize the partial first and **retain the snapshot — always, even with zero outputs**, marked reset/unstarted, with no fabricated performance rows (a zero-output note honestly records \"attempted, nothing captured\"; nothing is silently dropped). Reset then mints a **separate fresh unstarted draft snapshot** as its archive record; the next Run still creates its own fresh note — prepared/reset drafts are never activated (explicit user policy: each run creates a new note; the extra archive entry is requested).\n- **Save failure:** persist-before-run stays; a failed save must **never clear recorded output nor auto-start a new run** — the run and its results stay, retry is explicit.\n- Per-run snapshots retire the reuseKey race surface entirely (each run mints its own note; no shared-slug ensure).\n- In the HTML prototype, session recording stays **page-memory only** and is labelled visibly as such; production records through the recorder seam.\n\n### 3.4 No fullscreen; stage-driven run\n\n**Today.** Run mounts a fullscreen overlay (`TourTimerScreen` tour-side, `FullscreenTimer` canvas-side) with autostart gated in `RuntimeTimerPanel` (`(autoStart||pendingStart)&&ready&&idle`).\n\n**Proposed.** Run scrolls to the **inline runtime stage** — no fullscreen. Arrival autostarts **once per run**. Captions offer existing actions only, as optional explicit buttons (`Run`, `Next`, `Stop`, `Cast` — real control labels/testids, no hidden auto-Next, no auto-cast; the autoplay entrance is user-scroll-triggered). A previous runtime resumes only via explicit **Run** (which always mints a new snapshot).\n\n### 3.5 Stage observers are idempotent\n\nBackward scroll never restarts a run nor replays a one-shot stage effect (renormalized progress + reached-once guards, the `useReachedOnce` pattern). Forward **fast scroll** that resolves straight to a later stage cannot launch the skipped runtime stage: the stage machine emits one discrete stage per frame (`resolveScrollStage`), so skipped stages' enter effects (autostart included) never fire. Every stage-enter effect runs once per run, not once per direction.\n\n### 3.6 Bounded seams and cleanup scope\n\nAll changes are bounded to existing seams — no new subsystem:\n\n1. **Snapshot naming** — a policy inside `createPlaygroundIntake` (the single note-minting seam); callers (`HomeTour`, `useCanvasRuntime`) keep their signatures. Explicit New/Reset page buttons keep today's `createPage` semantics.\n2. **Record-once** — a guard at the recorder or the run hooks (consume captured run / id-keyed guard), closing the double-record race before any autostart re-runs exist.\n3. **Partial finalize on reset** — a `completed:false` record at the two reset points (`HomeTour.startNewSession`, `useCanvasRuntime.closeRun`), retained even at zero outputs, then a separate fresh unstarted draft snapshot is minted (Run never activates it).\n4. **One active session owner** — generalize the `useCanvasRuntime` pattern instead of scattered refs (HomeTour refs vs canvas `activeRun` vs workbench store). **The workbench keeps its own multi-note session store** (`completeWorkout`, autosave, `resetStore`): it serves journal/workbench routes and promotion — one-active is a *playground-surface policy*, not a storage policy. Don't delete general workbench multi-note session support because the homepage is one-active.\n5. **Retention** — snapshot growth is handled by the existing promotion invariant (`movePlaygroundToJournal` — moved notes can never be hijacked by a later same-key ensure) and `find:note{source:playground}` scoping, not new deletion logic.\n\n**Cleanup scope when the collection is approved** (not before — nothing here routes the eight drafts or retires any `/guide/*` route):\n\n- Safe to retire with their routed parents: the 65 non-routed syntax tab-page fixtures and their ```scroll stage plumbing (they exist as scroll-stage sources for routed pages), the duplicate prototype HTML copy (keep one canonical), the `ProtoTimerMobile` throwaway (`?proto-timer`), the retired 720vh ```scroll:chapters spec in `canvas/home/README.md`.\n- **Out of scope:** workbench/journal session store and its wiring, collections/feeds/journal surfaces, promotion, chapter-run reuse — multi-note session support serves routes beyond the homepage and survives a one-active homepage.\n\n---\n\n## 4. Sticky stage flow (desktop & mobile)\n\nFour sticky stages in page order: **editor → runtime → WQL table → dashboard**. Desktop is native **sticky push-off**: each stage is a tall section whose card sticks at the nav offset (`STICKY_NAV_HEIGHT` = 104px, card `h-[calc(100vh-104px)]` — the `TourSectionRunway` pattern) and is pushed off by the next stage's sticky card, driven by the existing pure stage machine (`resolveScrollStage` with clamp01/renormalize over a capture-phase scroll listener). The hero editor is **one reused instance** sticking through stage 1. Run scrolls editor→runtime; **Stop (or metrics arrival) slides the metrics view in**; the **WQL table stage** sticks bound to the **current run's facts**, with caption query actions (real queries, `ParsedQueryChips` vocabulary) and a floating **\"Revert current session\"** that re-binds the table to the current run — discarding view-state (query tweaks, sample overlay) only; the **dashboard stage** sticks a board with **load buttons** for the seeded boards.\n\nMobile (≤1023px, `MOBILE_BREAKPOINT_PX`): **bounded sticky stage windows** — one stage card at a time in the reading zone (top 65px window, `MOBILE_STICKY_TOP`), captions **below** the card, card-visibility IntersectionObserver as the stage driver (the `TourMobileRunway` pattern). Same stage order, same run contract.\n\nReduced motion wins everywhere (`RunwayAdapter`: reduced > mobile > desktop): flat card stack, no push-off, no scroll scrub; stage arrival is visibility-based and still once-per-run.\n\nGuarantees on every form factor:\n\n- Runtime arrival autostarts once; backward scroll never restarts; fast scroll to a later stage cannot launch the skipped runtime (§3.5).\n- Caption actions are explicit buttons using existing labels; no hidden auto-Next/auto-cast.\n- Sample fallbacks are badged **sample**; sample datasets and dashboard/board edits never mutate saved session results; **Revert** restores view only.\n\n---\n\n## 5. System organization\n\n| Term | Purpose | Scope / storage |\n|---|---|---|\n| **Note** | the markdown document + identity (uuidv7 id, slug, sourceId, type) | one IndexedDB store (notes + results + attachments + analytics) |\n| **Page** | a note bound to a surface (routed guide page, playground home/canvas) | bindings via reuseKey / `getCanvasNoteId` |\n| **Block** | one addressable fenced unit in a note; the run target | Block Content Id = content hash, stable across reorders/clones |\n| **Effort** | named workout registry entry (e.g. *fran*) | content-plane query target; aggregates `by {effort}` |\n| **Session** | one recorded run | `{noteId, resultId, block}` triple; results join `Session.noteId` |\n| **Journal** | default dated training notebook (`notebook/journal`) | `notebook:journal` (`source:journal`); promotion target |\n| **Playground** | default experiment notebook (`notebook/playground`) | `notebook:playground` (`source:playground`); run snapshots archive here until promoted |\n| **Notebook** | user-created or seed-delivered notebook (`notebook/{slug}`) | `notebook:<id>` (`source:notebooks`); seed notebooks are read-only and clone into writable notebooks |\n| **Dashboard** | a note with `dashboard: true`; its query blocks render as widgets | vault (editable) vs prebuilt (read-only, clone) |\n\n**`notebook:` & `source:` scope.** Filter by `notebook:<id>` (`journal`, `playground`, `guides`, `crossfit-girls`, etc.) or plural `source:` values; omitting both searches all notes. Learning runs record in `notebook/playground` until promotion re-homes the note to `notebook/journal`.\n\n**Session vs template vs sample dataset vs revert.**\n\n- **Session** — immutable recorded facts from one run against its snapshot note.\n- **Template** — read-only source content (`sample-script.md`, `WORKOUT_PRESETS`, seeded boards). Running a template copies it into the active workspace/snapshot; **templates never mutate**.\n- **Sample dataset** — the SAMPLE fallback (`SAMPLE_HOME_ANALYTICS`, `SampleDataPrompt`) shown when the store has no facts; always badged sample; never persisted as your results.\n- **Revert** (\"Revert current session\") — discards view-state only (query tweaks, sample overlay) and re-binds the stage to the current run's recorded facts; never deletes saved sessions.\n\n---\n\n## 6. Homepage placements (existing slots only)\n\n| Homepage slot | Proposed links |\n|---|---|\n| Hero / editor-blank caption | \"Start Lesson 1\" → start.md#first-workout; add \"See the full syntax\" → start.md#reference |\n| 01 Write — editor-metrics caption | add \"What each line collects\" → metrics.md |\n| 01 Write — WORKOUT_PRESETS | each preset mirrors a protocols.md / structure.md example |\n| 02 Run — behaviors caption | point \"Read the behaviors explainer\" → clock.md |\n| 02 Run — timer-cast caption | clock.md#casting |\n| 03 Own — metrics-d (\"Measures ride along\") | add action → metrics.md |\n| 03 Own — metrics-c (\"Efforts × measures compound\") | add teaser → wql.md |\n| 04 Explore (currently no inline analytics links; `home:analytics_guide_opened` telemetry declared but never fired) | header actions: \"WQL in depth\" → wql.md, \"Copy-paste queries\" → dashboards.md#cookbook; wql-dashboard/wql-live captions → dashboards.md#seeded-boards |\n| CelebrationBridge (\"Now learn the language\") | render the 8-chapter map as the card row |\n| TourChapterPicker / TourLearnSection | CHAPTER_ROUTES gains the 8 files |\n| Footer \"Where to next?\" | add Learn column: start.md, wql.md, dashboards.md |\n| /ai-first | stays a standalone marketing page, linked from start.md (\"Generate with AI\") |\n\n## 7. Old route → new page/anchor map\n\nConcrete migration map for the 18 currently routed learning pages. Slugs follow the current routed files under `markdown/canvas/`; the eight targets are §2's files. **Both cheatsheets are absorbed into existing pages — there is no ninth page.** Nothing routes or redirects until the collection is approved; until then both trees coexist.\n\n| Old location (routed file) | New target |\n|---|---|\n| `syntax/README.md` (hub) | [start.md](/page/guide-start) header + [sessions.md#intent](/page/guide-sessions?h=intent) |\n| `syntax/basics.md` | [start.md#first-workout](/page/guide-start?h=first-workout) |\n| `syntax/protocols.md` | [protocols.md#countdown-countup](/page/guide-protocols?h=countdown-countup) |\n| `syntax/structure.md` | [structure.md#rounds](/page/guide-structure?h=rounds) |\n| `syntax/custom-metrics.md` | [metrics.md#planned-vs-recorded](/page/guide-metrics?h=planned-vs-recorded) |\n| `syntax/dialects.md` | [sessions.md#intent](/page/guide-sessions?h=intent) |\n| `syntax/complex.md` | [sessions.md#full-session](/page/guide-sessions?h=full-session) |\n| `syntax/cheatsheet.md` | [start.md#reference](/page/guide-start?h=reference) — **cheatsheet #1 absorbed** |\n| `behaviors/README.md` | [clock.md#run-next](/page/guide-clock?h=run-next) |\n| `behaviors/timers.md` | [protocols.md](/page/guide-protocols) (syntax forms) + [clock.md#pause-skip](/page/guide-clock?h=pause-skip) (runtime) |\n| `behaviors/rounds.md` | [structure.md#rep-schemes](/page/guide-structure?h=rep-schemes) + [clock.md#run-next](/page/guide-clock?h=run-next) |\n| `behaviors/capture.md` | [metrics.md#capture](/page/guide-metrics?h=capture) + [clock.md#capture-prompts](/page/guide-clock?h=capture-prompts) |\n| `analytics/README.md` | [wql.md#planes](/page/guide-wql?h=planes) |\n| `analytics/anatomy.md` | [wql.md#aggregate](/page/guide-wql?h=aggregate) |\n| `analytics/filters.md` | [wql.md#filters](/page/guide-wql?h=filters) · [#sources](/page/guide-wql?h=sources) · [#windows](/page/guide-wql?h=windows) |\n| `analytics/joins.md` | [wql.md#joins](/page/guide-wql?h=joins) |\n| `analytics/cookbook.md` | [dashboards.md#cookbook](/page/guide-dashboards?h=cookbook) |\n| `analytics/cheatsheet.md` | [wql.md#aggregate](/page/guide-wql?h=aggregate) tables + [dashboards.md#widgets](/page/guide-dashboards?h=widgets) — **cheatsheet #2 absorbed** |\n\nThe 65 non-routed tab-page fixtures follow their routed parents (their unique content is already merged — §8). `canvas/home/README.md` (homepage) and `canvas/ai-first/README.md` stay product pages, out of the collection.\n\n## 8. Source coverage\n\nEvery routed learning page (18) and every underlying non-routed lesson source (65 syntax tab pages + 2 home sources), mapped to its target. Merged duplicates list only once with their union.\n\n| Current source (routed unless marked) | Topics kept | → New page |\n|---|---|---|\n| syntax/README.md (hub) | core concepts map, dialect intro, new-note CTA | start.md (header/TOC), sessions.md#intent |\n| syntax/basics.md | fences, one-thing-per-line, indentation, measurements, `?lb`, effort words, actions, comments | start.md |\n| syntax/protocols.md + timers-rest, timer-modifiers, timers-1..5, longer-duration, mixed-timers, classic-amrap, time-cap, multiple-amrap-windows, basic-emom, longer-intervals, alternating-emom, protocols-1..5, custom-intervals, distance-intervals, supplemental-2 | countdown/countup/`^`/`*`/`:?`, H:MM:SS, AMRAP, caps, EMOM family, Tabata, intervals, rest | protocols.md |\n| syntax/structure.md + groups-1..4, named-groups, mixed-sections, multiple-sets | rounds, rep schemes, nesting, named sections, sets | structure.md |\n| syntax/custom-metrics.md + custom-metrics-1..5, calculated-metrics, custom-and-calculated-metrics, metrics-1..5, supplemental-4 | inline JSON, rpe/rir, multi-metric lines, calculate blocks, JSON rules, unknown loads `?lb`/`?kg` | metrics.md |\n| syntax/dialects.md + dialect-wod/log/plan, dialect-climb-bouldering/hangboard/sport | intent distinction, `log:climbing`, climbing signals | sessions.md |\n| syntax/complex.md + complex-nested-protocols, complex-full-session, complex-barbell-cycling, complex-partner-workout, complex-swimming | nested protocols, full session, EMOM chains, partner windows, swimming | sessions.md |\n| syntax/cheatsheet.md (routed) | one-page syntax | start.md#reference + per-page tables (no separate page) |\n| syntax/single-movement, core-rules, measurements, effort-notes, actions-comments, supplemental-1, supplemental-3, document-1..4, welcome-1 (home/), sample-script.md (home/) | smallest workout, three rules, headers/checklists/equipment-table document patterns, actions/comments | start.md |\n| behaviors/README.md | script→parse→compile→track, 3 behavior families, idioms | clock.md |\n| behaviors/timers.md | timer strategy selection, sound/pause/skip/required-rest | clock.md (+ protocols.md for syntax forms) |\n| behaviors/rounds.md | round behavior, rep math, supersets, interval groups, rounds↔timers | structure.md (+ clock.md) |\n| behaviors/capture.md | `:?`, `?lb`/`?kg`, session RPE, trendlines, fact origins | metrics.md (+ clock.md for prompt behavior) |\n| analytics/README.md | 3 WQL surfaces, 2 query planes, where-join | wql.md |\n| analytics/anatomy.md | aggregators, base/calc metrics, dimensions, rollups, find targets | wql.md |\n| analytics/filters.md | tag filters (negation/OR/substring), source filters, time windows, Library tri-state toggles | wql.md |\n| analytics/joins.md | where joins, Block Content Id mechanics | wql.md |\n| analytics/cookbook.md | 5 canonical queries, ```query embeds, dashboard notes, widget types/spans | dashboards.md (+ wql.md) |\n| analytics/cheatsheet.md | WQL one-pager | wql.md tables + dashboards.md#widgets (no separate page) |\n| markdown/dashboards/training-block-review.md | widget exemplars (see dashboards.md#seeded-boards) | dashboards.md |\n| markdown/dashboards/road-to-560-total.md | strength PR board exemplar | dashboards.md#seeded-boards |\n| markdown/dashboards/polarized-base-marathon.md | endurance polarization exemplar | dashboards.md#seeded-boards |\n| markdown/dashboards/finger-strength-v8.md | climbing board exemplar (wellness capture, `calc.mvcBw`) | dashboards.md#seeded-boards |\n| markdown/dashboards/benchmark-pr-board.md | benchmark table exemplar (`last:elapsed{tags:benchmark}`) | dashboards.md#seeded-boards |\n| markdown/dashboards/recovery-readiness.md | ```wellness capture + readiness exemplar | dashboards.md#seeded-boards (+ metrics.md#calculated) |\n\nNot counted as learning sources: `canvas/home/README.md` (product walkthrough — the homepage itself stays), `canvas/ai-first/README.md` (AI marketing, linked as an aside). Orphaned scroll plumbing (```scroll blocks, getTabExamples/getHomeExample, protocols-1's `(AMRAP)` spelling) is dropped, not migrated.\n\n## 9. Review method\n\nEach chapter ends with a **Try it** block: what to paste/press, what the runtime should show, and — for data chapters — the result query — a reviewer checklist, not a test report. Every syntax, behavior, and query claim in this collection comes from **source review only** (parser grammar, compiler metrics, WQL vocabulary/seeds, shipped fixtures). That was true at review time; since the cutover the chapters are production pages — the §3.1–§3.3 run/save behavior is implemented and exercised, while §3.4–§5 (stage flow) stay contract-only (see the status block).\n",
4
4
  "blocks": {
5
5
  "seed:markdown/canvas/guide/README.md:0": {
6
6
  "id": "seed:markdown/canvas/guide/README.md:0",
7
7
  "kind": "wod",
8
- "from": 1554,
9
- "to": 1609,
8
+ "from": 1564,
9
+ "to": 1619,
10
10
  "sourceRevision": 1,
11
11
  "version": 1,
12
12
  "dialect": "time"
@@ -19,14 +19,14 @@
19
19
  "blockId": "seed:markdown/canvas/guide/README.md:0",
20
20
  "blockVersion": 1,
21
21
  "sourceRevision": 1,
22
- "from": 1554,
23
- "to": 1609,
22
+ "from": 1564,
23
+ "to": 1619,
24
24
  "position": 0,
25
25
  "dataType": "wod",
26
26
  "blockContentId": "bc-86bf9888",
27
27
  "rawContent": "```time\n(3)\n 10 Kettlebell Swings 24kg\n *:30 Rest\n```",
28
28
  "noteTitle": "Overview",
29
- "createdAt": 1792883209000,
29
+ "createdAt": 1793044829000,
30
30
  "isStatic": true,
31
31
  "sourceId": "guides:guide/README",
32
32
  "sourcePath": "markdown/canvas/guide/README.md"
@@ -41,7 +41,7 @@
41
41
  "effortSlug": "kettlebell-swing",
42
42
  "isStatic": true,
43
43
  "sourcePath": "markdown/canvas/guide/README.md",
44
- "createdAt": 1792883209000
44
+ "createdAt": 1793044829000
45
45
  }
46
46
  ],
47
47
  "blockEquipment": [
@@ -53,10 +53,10 @@
53
53
  "equipmentSlug": "kettlebell",
54
54
  "isStatic": true,
55
55
  "sourcePath": "markdown/canvas/guide/README.md",
56
- "createdAt": 1792883209000
56
+ "createdAt": 1793044829000
57
57
  }
58
58
  ],
59
- "commit": "30e43c771d712a7c09bd8056d48d096ca769e705",
59
+ "commit": "32bda10ffc56a61ebfca76ae94f51eddba304498",
60
60
  "uuid": "13ff30e0-4a1b-5ec4-ba59-28bdfd3c7ae5",
61
61
  "version": 1
62
62
  }
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "path": "markdown/canvas/guide/clock.md",
3
- "content": "---\nsearch: hidden\ntemplate: canvas\nroute: /guide/clock\ntype: guide\ntitle: \"Run, Track & Capture (the Clock)\"\ndescription: \"Run the clock, advance with Next, pause, skip optional rest, and capture times mid-workout.\"\n---\n\n```chapter\nid: clock\ntitle: The Clock\nbadge: dumbbell\nquests: clock-run, clock-rest, clock-split\nsections: []\n```\n\n```quest\nid: clock-run\nlabel: Run the First Example\nvalidation:\n type: run-started\n```\n\n```quest\nid: clock-rest\nlabel: Program a required rest\nvalidation:\n type: contains-token\n value: '*:'\n```\n\n```quest\nid: clock-split\nlabel: Add a cue card action\nvalidation:\n type: contains-token\n value: \"[\"\n```\n\n# Run, Track & Capture (the Clock) {sticky dark full-bleed}\n\nSyntax is the plan; **behaviors** are what the runtime does with it. When you press Run, the compiler turns every line into a timeline of behaviors and the clock plays them in order.\n\n```view\nname: preview\nstate: note\nsource: wods/examples/home/sample-script.md\nruntime: in-memory\nlaunch: host\nalign: right\nwidth: 50%\n```\n\n## From script to clock {#run-next}\n\n1. **Script** — your Markdown note with fenced blocks.\n2. **Parse** — the grammar turns each line into statements of metrics.\n3. **Compile** — statements match to behaviors and lay out a timeline.\n4. **Track** — the clock steps through the timeline: counting, prompting, logging.\n\nThree behavior families cover every line:\n\n| Family | What it does | Example line | On the clock |\n|---|---|---|---|\n| **Timers** | counts up or down, repeats, rings | `20:00 AMRAP` | countdown + round counter |\n| **Rounds** | repeats, names, walks a rep scheme | `(21-15-9)` | three rounds with descending reps |\n| **Capture** | asks for actuals | `225lb ?lb`, `:?` | prompt when reached or finished |\n\n**Run** starts the current block; **Next** advances it and locks the elapsed time as a **split** — every click records where you are. Timers choose their strategy from the line ([chapter 2](/guide/protocols?h=countdown-countup)): duration → countdown, `^` or no duration → count-up stopwatch, `EMOM`/work-rest pair → interval, the word `Rest` → rest cue.\n\n## Pause, skip, and sound {#pause-skip}\n\n```button\nlabel: Try it: Required rest\ntarget: preview\npipeline:\n - set-source: wods/examples/syntax/timers-rest.md\n```\n\n- **Pause / resume** — countdowns stop and resume from the same elapsed time; interval timers keep round state, so an EMOM window never restarts from zero.\n- **Skip** — any timer without `*` can be skipped. `*:30 Rest` cannot; required timers force the full wait.\n- **Sound** — the runtime emits sound cues at timer start, the final ten seconds, and round transitions; audio surfaces subscribe to them.\n\nA movement line without a duration is not \"no timer\" — it's a count-up stopwatch tracking that block while you log reps.\n\nOn a stored note, **Stop** or **Exit** saves the captured partial run. Finishing the last block saves a completed run. The fullscreen results view shows **Saved ✓** only after the write succeeds. If saving fails, the clock keeps the run open; **Retry save** retries the same run without creating another session. Live \"results captured\" counts do not confirm a save.\n\n## Capture prompts {#capture-prompts}\n\nCollectible placeholders (`?lb`, `:?`, `?m`, `?`) mark the values the plan doesn't know; you supply the actuals during capture, and each lands in the fact store with its block. Session RPE is captured after the workout — skippable, and never blocking a save. Every recorded value carries a declared origin — see [Provenance](#provenance).\n\n## Casting {#casting}\n\nThe clock casts to a big screen: the timer surface — current block, round counter, countdown, cue cards — renders on a paired display while the controls stay on your device. Timers, cue cards (`[Change Plates]`), and round indicators all cross over; pauses on the device pause the cast.\n\n## Provenance {#provenance}\n\nEvery recorded fact carries its origin, which later tells analytics what to trust:\n\n| Origin | Producer | Example |\n|---|---|---|\n| `parser` / `compiler` | from your text | planned `24kg`, rep scheme values |\n| `runtime` | the clock | elapsed spans, splits, round counts |\n| `user` | you, at a prompt | captured loads, `:?` results, session RPE, wellness entries |\n| `analyzed` | the calc engine | `calc.*` values (estimated ones are marked `analyzed-estimated`) |\n\n## Try it {#try-it}\n\n**Run** — run the shared `(3) × 10 Kettlebell Swings 24kg / *:30 Rest` note and try each control: pause mid-round (elapsed freezes, resumes exactly), attempt to skip the `*` rest (refused), then `Next` through the last round — each split is locked with its timestamp. **Observe** — the review grid afterwards is just this provenance trail, organized. Runtime behavior is the subject here; run saving is the shared run contract.\n\n```button\nlabel: Run\ntarget: preview\nopen: view\npipeline:\n - set-state: track\n```\n\n",
3
+ "content": "---\nsearch: hidden\ntemplate: canvas\nroute: /page/guide-clock\ntype: guide\ntitle: \"Run, Track & Capture (the Clock)\"\ndescription: \"Run the clock, advance with Next, pause, skip optional rest, and capture times mid-workout.\"\n---\n\n```chapter\nid: clock\ntitle: The Clock\nbadge: dumbbell\nquests: clock-run, clock-rest, clock-split\nsections: []\n```\n\n```quest\nid: clock-run\nlabel: Run the First Example\nvalidation:\n type: run-started\n```\n\n```quest\nid: clock-rest\nlabel: Program a required rest\nvalidation:\n type: contains-token\n value: '*:'\n```\n\n```quest\nid: clock-split\nlabel: Add a cue card action\nvalidation:\n type: contains-token\n value: \"[\"\n```\n\n# Run, Track & Capture (the Clock) {sticky dark full-bleed}\n\nSyntax is the plan; **behaviors** are what the runtime does with it. When you press Run, the compiler turns every line into a timeline of behaviors and the clock plays them in order.\n\n```view\nname: preview\nstate: note\nsource: wods/examples/home/sample-script.md\nruntime: in-memory\nlaunch: host\nalign: right\nwidth: 50%\n```\n\n## From script to clock {#run-next}\n\n1. **Script** — your Markdown note with fenced blocks.\n2. **Parse** — the grammar turns each line into statements of metrics.\n3. **Compile** — statements match to behaviors and lay out a timeline.\n4. **Track** — the clock steps through the timeline: counting, prompting, logging.\n\nThree behavior families cover every line:\n\n| Family | What it does | Example line | On the clock |\n|---|---|---|---|\n| **Timers** | counts up or down, repeats, rings | `20:00 AMRAP` | countdown + round counter |\n| **Rounds** | repeats, names, walks a rep scheme | `(21-15-9)` | three rounds with descending reps |\n| **Capture** | asks for actuals | `225lb ?lb`, `:?` | prompt when reached or finished |\n\n**Run** starts the current block; **Next** advances it and locks the elapsed time as a **split** — every click records where you are. Timers choose their strategy from the line ([chapter 2](/page/guide-protocols?h=countdown-countup)): duration → countdown, `^` or no duration → count-up stopwatch, `EMOM`/work-rest pair → interval, the word `Rest` → rest cue.\n\n## Pause, skip, and sound {#pause-skip}\n\n```button\nlabel: Try it: Required rest\ntarget: preview\npipeline:\n - set-source: wods/examples/syntax/timers-rest.md\n```\n\n- **Pause / resume** — countdowns stop and resume from the same elapsed time; interval timers keep round state, so an EMOM window never restarts from zero.\n- **Skip** — any timer without `*` can be skipped. `*:30 Rest` cannot; required timers force the full wait.\n- **Sound** — the runtime emits sound cues at timer start, the final ten seconds, and round transitions; audio surfaces subscribe to them.\n\nA movement line without a duration is not \"no timer\" — it's a count-up stopwatch tracking that block while you log reps.\n\nOn a stored note, **Stop** or **Exit** saves the captured partial run. Finishing the last block saves a completed run. The fullscreen results view shows **Saved ✓** only after the write succeeds. If saving fails, the clock keeps the run open; **Retry save** retries the same run without creating another session. Live \"results captured\" counts do not confirm a save.\n\n## Capture prompts {#capture-prompts}\n\nCollectible placeholders (`?lb`, `:?`, `?m`, `?`) mark the values the plan doesn't know; you supply the actuals during capture, and each lands in the fact store with its block. Session RPE is captured after the workout — skippable, and never blocking a save. Every recorded value carries a declared origin — see [Provenance](#provenance).\n\n## Casting {#casting}\n\nThe clock casts to a big screen: the timer surface — current block, round counter, countdown, cue cards — renders on a paired display while the controls stay on your device. Timers, cue cards (`[Change Plates]`), and round indicators all cross over; pauses on the device pause the cast.\n\n## Provenance {#provenance}\n\nEvery recorded fact carries its origin, which later tells analytics what to trust:\n\n| Origin | Producer | Example |\n|---|---|---|\n| `parser` / `compiler` | from your text | planned `24kg`, rep scheme values |\n| `runtime` | the clock | elapsed spans, splits, round counts |\n| `user` | you, at a prompt | captured loads, `:?` results, session RPE, wellness entries |\n| `analyzed` | the calc engine | `calc.*` values (estimated ones are marked `analyzed-estimated`) |\n\n## Try it {#try-it}\n\n**Run** — run the shared `(3) × 10 Kettlebell Swings 24kg / *:30 Rest` note and try each control: pause mid-round (elapsed freezes, resumes exactly), attempt to skip the `*` rest (refused), then `Next` through the last round — each split is locked with its timestamp. **Observe** — the review grid afterwards is just this provenance trail, organized. Runtime behavior is the subject here; run saving is the shared run contract.\n\n```button\nlabel: Run\ntarget: preview\nopen: view\npipeline:\n - set-state: track\n```\n\n",
4
4
  "blocks": {},
5
5
  "blockIndex": [],
6
6
  "blockEfforts": [],
7
7
  "blockEquipment": [],
8
- "commit": "30e43c771d712a7c09bd8056d48d096ca769e705",
8
+ "commit": "32bda10ffc56a61ebfca76ae94f51eddba304498",
9
9
  "uuid": "905f9253-fa20-58cb-8447-6cb534e34a09",
10
10
  "version": 1
11
11
  }
@@ -1,39 +1,39 @@
1
1
  {
2
2
  "path": "markdown/canvas/guide/dashboards.md",
3
- "content": "---\nsearch: hidden\ntemplate: canvas\nroute: /guide/dashboards\ntype: guide\ntitle: \"Dashboards & Cookbook\"\ndescription: \"Dashboards are notes with query widgets — frontmatter tokens, widget fences, and the composer.\"\n---\n\n# Dashboards & Cookbook {sticky dark full-bleed}\n\nA dashboard is **just a note**: mark it `dashboard: true`, and every in-note query block becomes a widget on one grid. The panel on the right has the real Training Block Review board loaded — its ```query blocks render live results right in the sandbox, and you can edit a query without touching the seeded board.\n\n```view\nname: sandbox\nstate: note\nsource: dashboards/training-block-review.md\nruntime: in-memory\nlaunch: host\nalign: right\nwidth: 50%\n```\n\n## The note is the dashboard {#note-frontmatter}\n\nThe real board is already loaded in the sandbox.\n\n````markdown\n---\ntitle: Training Block Review\ndashboard: true\ndashboard.weeks: 16\n---\n\n## Avg TIS\nHow hard are sessions?\n\n```query:value\navg:tis{}\n```\n\n## Weekly tonnage\nIs volume rising?\n\n```query:timeseries-2\nsum:totalVolume{} by {week}\n```\n````\n\nThree conventions:\n\n- The **heading above a block** is the widget title.\n- The **paragraph directly above a block** is its question/subtitle.\n- `dashboard.weeks`, `dashboard.intensity: [low, moderate, high]`, or any `dashboard.<name>` value in frontmatter becomes a **token control** referenced as `$name` — `$weeks`, `$intensity`. List tokens render as segmented controls; unknown token references produce a visible refusal, never a silent blank.\n\n## Widget types and spans {#widgets}\n\n```button\nlabel: Try it: Benchmark PR board\ntarget: sandbox\npipeline:\n - set-source: dashboards/benchmark-pr-board.md\n```\n\nThe fence tag carries type and grid span (`query:<type>[-<1..4>|-full]`); a bare ```query defaults to `table`. Grid is 4 columns wide.\n\n| Tag | Widget |\n|---|---|\n| ```query | table (default) |\n| ```query:list / ```query:value | list / single big number |\n| ```query:timeseries / ```query:timeseries-2 / ```query:timeseries-4 | line over time, 1/2/4 columns |\n| ```query:bar / ```query:stacked-bar | bars / stacked bars |\n| ```query:toplist | ranked rows |\n| ```query:goal-rings / ```query:zone-distribution | progress rings / zone split |\n\nThe block body is **one WQL line** — everything from [the WQL chapter](/guide/wql?h=aggregate) works, including tokens:\n\n```query\nsum:sessionLoad{intensity:$intensity} by {week}\n```\n\nWellness data comes from a capture fence in any note — wellness keys are plain properties, one per line:\n\n```wellness\nsoreness: 7\nsleep: 7.5h\nhrv: 62\n```\n\nCapture those daily and boards like Recovery Readiness light up ([what feeds `calc.readiness`](/guide/metrics?h=calculated)).\n\n## Compose, inspect, clone {#composer}\n\n- **Vault boards** (`/dashboard/<your-note>`) are yours: add, edit, duplicate, reorder, and resize widgets in place; concurrent-edit guards refuse lost writes visibly.\n- **Prebuilt boards** are read-only, but **Inspect** shows any widget's query with a live preview, and **Clone to vault** copies the whole board into your journal to edit.\n- The widget composer is the same three steps for both: pick the **dataset** (a WQL line), the **calculation** (aggregator/metric/filters/window via the composer pills), and the **visualization** (type + span) — preview executes against your live journal with your range and kg/lb preferences.\n- Empty journal? Widgets stay honest with a sample-data prompt instead of fake numbers.\n\n## Cookbook {#cookbook}\n\nCopy-paste queries (paste into a ```query block, or straight into the Explorer):\n\n| Question | Query |\n|---|---|\n| Weekly strength volume | `sum:totalVolume{discipline:strength} by {week}` |\n| Top volume movements | `sum:totalVolume{} by {effort}` |\n| TIS trend | `avg:tis{} by {week}` |\n| Acute:chronic load | `avg:calc.acwr{}` |\n| Find benchmark notes | `:note{effort:fran,source:notebooks}` |\n| This week's swings volume | `sum:totalVolume{effort:kettlebell-swings} last 6w` |\n\nThe shared kettlebell note feeds the last row — [run it](/guide/start?h=try-it), and it appears among the sample rows.\n\n## Seeded boards {#seeded-boards}\n\nSix real dashboard notes ship with the app — open any of them, or Inspect → Clone:\n\n| Board | Built around |\n|---|---|\n| [Training Block Review](/d/training-block-review) | values (`avg:tis{}`, `sum:totalVolume{}`, `avg:calc.adherence{}`), weekly volume timeseries, volume by effort toplist, stacked load by intensity/week, distance by discipline |\n| [Road to 560 Total](/d/road-to-560-total) | strength PR progression toward a total |\n| [Polarized Base Marathon](/d/polarized-base-marathon) | endurance polarization (intensity split across weeks) |\n| [Finger Strength V8](/d/finger-strength-v8) | climbing: `calc.mvcBw` hang strength vs grade |\n| [Benchmark PR Board](/d/benchmark-pr-board) | `last:elapsed{tags:benchmark} by {effort}`, benchmark timeseries |\n| [Recovery Readiness](/d/recovery-readiness) | ```wellness capture → `last:calc.readiness{}`, HRV/monotony/ACWR trends |\n\n## Try it {#try-it}\n\n**Run** — the sandbox has the real board loaded: edit the *Weekly tonnage* query in the panel, change `by {week}` to `by {day}`, and watch the widget re-run — sandbox edits never touch the seeded board. Then open the live board: every widget executes against your journal, rows without facts badge as **sample answers until you have logged work of your own**. **Observe** — in the board view, inspect the *Weekly tonnage* widget and clone the board to keep an edit. Sample answers and board edits read saved sessions; they never rewrite them.\n\n```button\nlabel: Open Training Block Review →\ntarget: preview\npipeline:\n - navigate: /d/training-block-review\n```\n\n```button\nlabel: Browse all dashboards →\ntarget: preview\npipeline:\n - navigate: /dashboards\n```\n\n",
3
+ "content": "---\nsearch: hidden\ntemplate: canvas\nroute: /page/guide-dashboards\ntype: guide\ntitle: \"Dashboards & Cookbook\"\ndescription: \"Dashboards are notes with query widgets — frontmatter tokens, widget fences, and the composer.\"\n---\n\n# Dashboards & Cookbook {sticky dark full-bleed}\n\nA dashboard is **just a note**: mark it `dashboard: true`, and every in-note query block becomes a widget on one grid. The panel on the right has the real Training Block Review board loaded — its ```query blocks render live results right in the sandbox, and you can edit a query without touching the seeded board.\n\n```view\nname: sandbox\nstate: note\nsource: dashboards/training-block-review.md\nruntime: in-memory\nlaunch: host\nalign: right\nwidth: 50%\n```\n\n## The note is the dashboard {#note-frontmatter}\n\nThe real board is already loaded in the sandbox.\n\n````markdown\n---\ntitle: Training Block Review\ndashboard: true\ndashboard.weeks: 16\n---\n\n## Avg TIS\nHow hard are sessions?\n\n```query:value\navg:tis{}\n```\n\n## Weekly tonnage\nIs volume rising?\n\n```query:timeseries-2\nsum:totalVolume{} by {week}\n```\n````\n\nThree conventions:\n\n- The **heading above a block** is the widget title.\n- The **paragraph directly above a block** is its question/subtitle.\n- `dashboard.weeks`, `dashboard.intensity: [low, moderate, high]`, or any `dashboard.<name>` value in frontmatter becomes a **token control** referenced as `$name` — `$weeks`, `$intensity`. List tokens render as segmented controls; unknown token references produce a visible refusal, never a silent blank.\n\n## Widget types and spans {#widgets}\n\n```button\nlabel: Try it: Benchmark PR board\ntarget: sandbox\npipeline:\n - set-source: dashboards/benchmark-pr-board.md\n```\n\nThe fence tag carries type and grid span (`query:<type>[-<1..4>|-full]`); a bare ```query defaults to `table`. Grid is 4 columns wide.\n\n| Tag | Widget |\n|---|---|\n| ```query | table (default) |\n| ```query:list / ```query:value | list / single big number |\n| ```query:timeseries / ```query:timeseries-2 / ```query:timeseries-4 | line over time, 1/2/4 columns |\n| ```query:bar / ```query:stacked-bar | bars / stacked bars |\n| ```query:toplist | ranked rows |\n| ```query:goal-rings / ```query:zone-distribution | progress rings / zone split |\n\nThe block body is **one WQL line** — everything from [the WQL chapter](/page/guide-wql?h=aggregate) works, including tokens:\n\n```query\nsum:sessionLoad{intensity:$intensity} by {week}\n```\n\nWellness data comes from a capture fence in any note — wellness keys are plain properties, one per line:\n\n```wellness\nsoreness: 7\nsleep: 7.5h\nhrv: 62\n```\n\nCapture those daily and boards like Recovery Readiness light up ([what feeds `calc.readiness`](/page/guide-metrics?h=calculated)).\n\n## Compose, inspect, clone {#composer}\n\n- **Vault boards** (`/dashboard/<your-note>`) are yours: add, edit, duplicate, reorder, and resize widgets in place; concurrent-edit guards refuse lost writes visibly.\n- **Prebuilt boards** are read-only, but **Inspect** shows any widget's query with a live preview, and **Clone to vault** copies the whole board into your journal to edit.\n- The widget composer is the same three steps for both: pick the **dataset** (a WQL line), the **calculation** (aggregator/metric/filters/window via the composer pills), and the **visualization** (type + span) — preview executes against your live journal with your range and kg/lb preferences.\n- Empty journal? Widgets stay honest with a sample-data prompt instead of fake numbers.\n\n## Cookbook {#cookbook}\n\nCopy-paste queries (paste into a ```query block, or straight into the Explorer):\n\n| Question | Query |\n|---|---|\n| Weekly strength volume | `sum:totalVolume{discipline:strength} by {week}` |\n| Top volume movements | `sum:totalVolume{} by {effort}` |\n| TIS trend | `avg:tis{} by {week}` |\n| Acute:chronic load | `avg:calc.acwr{}` |\n| Find benchmark notes | `:note{effort:fran,source:notebooks}` |\n| This week's swings volume | `sum:totalVolume{effort:kettlebell-swings} last 6w` |\n\nThe shared kettlebell note feeds the last row — [run it](/page/guide-start?h=try-it), and it appears among the sample rows.\n\n## Seeded boards {#seeded-boards}\n\nSix real dashboard notes ship with the app — open any of them, or Inspect → Clone:\n\n| Board | Built around |\n|---|---|\n| [Training Block Review](/d/training-block-review) | values (`avg:tis{}`, `sum:totalVolume{}`, `avg:calc.adherence{}`), weekly volume timeseries, volume by effort toplist, stacked load by intensity/week, distance by discipline |\n| [Road to 560 Total](/d/road-to-560-total) | strength PR progression toward a total |\n| [Polarized Base Marathon](/d/polarized-base-marathon) | endurance polarization (intensity split across weeks) |\n| [Finger Strength V8](/d/finger-strength-v8) | climbing: `calc.mvcBw` hang strength vs grade |\n| [Benchmark PR Board](/d/benchmark-pr-board) | `last:elapsed{tags:benchmark} by {effort}`, benchmark timeseries |\n| [Recovery Readiness](/d/recovery-readiness) | ```wellness capture → `last:calc.readiness{}`, HRV/monotony/ACWR trends |\n\n## Try it {#try-it}\n\n**Run** — the sandbox has the real board loaded: edit the *Weekly tonnage* query in the panel, change `by {week}` to `by {day}`, and watch the widget re-run — sandbox edits never touch the seeded board. Then open the live board: every widget executes against your journal, rows without facts badge as **sample answers until you have logged work of your own**. **Observe** — in the board view, inspect the *Weekly tonnage* widget and clone the board to keep an edit. Sample answers and board edits read saved sessions; they never rewrite them.\n\n```button\nlabel: Open Training Block Review →\ntarget: preview\npipeline:\n - navigate: /d/training-block-review\n```\n\n```button\nlabel: Browse all dashboards →\ntarget: preview\npipeline:\n - navigate: /dashboards\n```\n\n",
4
4
  "blocks": {
5
5
  "seed:markdown/canvas/guide/dashboards.md:0": {
6
6
  "id": "seed:markdown/canvas/guide/dashboards.md:0",
7
7
  "kind": "query",
8
- "from": 2357,
9
- "to": 2417,
8
+ "from": 2367,
9
+ "to": 2427,
10
10
  "sourceRevision": 1,
11
11
  "version": 1
12
12
  }
13
13
  },
14
14
  "blockIndex": [
15
15
  {
16
- "id": "guide/dashboards:seed:markdown/canvas/guide/dashboards.md:0",
17
- "noteId": "guide/dashboards",
16
+ "id": "page/guide-dashboards:seed:markdown/canvas/guide/dashboards.md:0",
17
+ "noteId": "page/guide-dashboards",
18
18
  "blockId": "seed:markdown/canvas/guide/dashboards.md:0",
19
19
  "blockVersion": 1,
20
20
  "sourceRevision": 1,
21
- "from": 2357,
22
- "to": 2417,
21
+ "from": 2367,
22
+ "to": 2427,
23
23
  "position": 0,
24
24
  "dataType": "query",
25
25
  "rawContent": "```query\nsum:sessionLoad{intensity:$intensity} by {week}\n```",
26
26
  "noteTitle": "Dashboards",
27
- "createdAt": 1792883209000,
27
+ "createdAt": 1793044829000,
28
28
  "isStatic": true,
29
- "sourceId": "guides:guide/dashboards",
29
+ "sourceId": "guides:page/guide-dashboards",
30
30
  "sourcePath": "markdown/canvas/guide/dashboards.md",
31
- "routeId": "guide/dashboards"
31
+ "routeId": "page/guide-dashboards"
32
32
  }
33
33
  ],
34
34
  "blockEfforts": [],
35
35
  "blockEquipment": [],
36
- "commit": "30e43c771d712a7c09bd8056d48d096ca769e705",
36
+ "commit": "32bda10ffc56a61ebfca76ae94f51eddba304498",
37
37
  "uuid": "5055fffb-2ed1-571f-aa72-3e1525d2e01f",
38
38
  "version": 1
39
39
  }