@titan-design/react-ui 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (509) hide show
  1. package/README.md +46 -47
  2. package/dist/bodymap.js +768 -701
  3. package/dist/bodymap.js.map +1 -1
  4. package/dist/bodymap.mjs +770 -703
  5. package/dist/bodymap.mjs.map +1 -1
  6. package/dist/index.d.mts +1320 -215
  7. package/dist/index.d.ts +1320 -215
  8. package/dist/index.js +5996 -4498
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +5773 -4357
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/{pages-CvsFqNtx.d.mts → pages-CpW3OB3g.d.mts} +21 -3
  13. package/dist/{pages-B1hqnGIC.d.ts → pages-_3Ajpiqu.d.ts} +21 -3
  14. package/dist/pages.d.mts +1 -1
  15. package/dist/pages.d.ts +1 -1
  16. package/dist/pages.js +1435 -1428
  17. package/dist/pages.js.map +1 -1
  18. package/dist/pages.mjs +1443 -1436
  19. package/dist/pages.mjs.map +1 -1
  20. package/dist/theme/index.d.mts +202 -1042
  21. package/dist/theme/index.d.ts +202 -1042
  22. package/dist/theme/index.js +215 -300
  23. package/dist/theme/index.js.map +1 -1
  24. package/dist/theme/index.mjs +202 -296
  25. package/dist/theme/index.mjs.map +1 -1
  26. package/dist/theme/tokens-css.js +62 -5
  27. package/dist/theme/tokens-css.js.map +1 -1
  28. package/dist/theme/tokens-css.mjs +62 -5
  29. package/dist/theme/tokens-css.mjs.map +1 -1
  30. package/dist/theme/tokens.d.mts +972 -0
  31. package/dist/theme/tokens.d.ts +972 -0
  32. package/dist/theme/tokens.js +904 -0
  33. package/dist/theme/tokens.js.map +1 -0
  34. package/dist/theme/tokens.mjs +880 -0
  35. package/dist/theme/tokens.mjs.map +1 -0
  36. package/docs/audits/2026-09-08-critique-addenda.md +51 -0
  37. package/docs/audits/2026-09-08-library-critique.md +212 -0
  38. package/docs/library-roadmap.md +99 -0
  39. package/package.json +7 -1
  40. package/src/arch/arch-graph.freshness.test.ts +52 -0
  41. package/src/arch/arch-graph.json +5021 -1617
  42. package/src/components/custom/ActiveWork/CoChangeChip.stories.tsx +44 -0
  43. package/src/components/custom/ActiveWork/CoChangeChip.test.tsx +29 -0
  44. package/src/components/custom/ActiveWork/CoChangeChip.tsx +48 -0
  45. package/src/components/custom/ActiveWork/Eyebrow.stories.tsx +25 -0
  46. package/src/components/custom/ActiveWork/Eyebrow.test.tsx +16 -0
  47. package/src/components/custom/ActiveWork/Eyebrow.tsx +26 -0
  48. package/src/components/custom/ActiveWork/FileActivityDetail.stories.tsx +50 -0
  49. package/src/components/custom/ActiveWork/FileActivityDetail.test.tsx +66 -0
  50. package/src/components/custom/ActiveWork/FileActivityDetail.tsx +202 -0
  51. package/src/components/custom/ActiveWork/FileActivityRow.stories.tsx +70 -0
  52. package/src/components/custom/ActiveWork/FileActivityRow.test.tsx +67 -0
  53. package/src/components/custom/ActiveWork/FileActivityRow.tsx +130 -0
  54. package/src/components/custom/ActiveWork/FileHistoryExplorer.stories.tsx +84 -0
  55. package/src/components/custom/ActiveWork/FileHistoryExplorer.test.tsx +99 -0
  56. package/src/components/custom/ActiveWork/FileHistoryExplorer.tsx +138 -0
  57. package/src/components/custom/ActiveWork/FilePathLabel.stories.tsx +39 -0
  58. package/src/components/custom/ActiveWork/FilePathLabel.test.tsx +53 -0
  59. package/src/components/custom/ActiveWork/FilePathLabel.tsx +63 -0
  60. package/src/components/custom/ActiveWork/InitiativeBrief.stories.tsx +50 -0
  61. package/src/components/custom/ActiveWork/InitiativeBrief.test.tsx +62 -0
  62. package/src/components/custom/ActiveWork/InitiativeBrief.tsx +181 -0
  63. package/src/components/custom/ActiveWork/InitiativeCard.stories.tsx +73 -0
  64. package/src/components/custom/ActiveWork/InitiativeCard.test.tsx +68 -0
  65. package/src/components/custom/ActiveWork/InitiativeCard.tsx +136 -0
  66. package/src/components/custom/ActiveWork/InitiativeHeader.stories.tsx +59 -0
  67. package/src/components/custom/ActiveWork/InitiativeHeader.test.tsx +40 -0
  68. package/src/components/custom/ActiveWork/InitiativeHeader.tsx +73 -0
  69. package/src/components/custom/ActiveWork/InitiativeReader.stories.tsx +145 -0
  70. package/src/components/custom/ActiveWork/OpenLoops.stories.tsx +58 -0
  71. package/src/components/custom/ActiveWork/OpenLoops.test.tsx +61 -0
  72. package/src/components/custom/ActiveWork/OpenLoops.tsx +107 -0
  73. package/src/components/custom/ActiveWork/PortfolioOverview.stories.tsx +101 -0
  74. package/src/components/custom/ActiveWork/PortfolioOverview.test.tsx +81 -0
  75. package/src/components/custom/ActiveWork/PortfolioOverview.tsx +83 -0
  76. package/src/components/custom/ActiveWork/README.md +305 -0
  77. package/src/components/custom/ActiveWork/SessionDetail.stories.tsx +71 -0
  78. package/src/components/custom/ActiveWork/SessionDetail.test.tsx +84 -0
  79. package/src/components/custom/ActiveWork/SessionDetail.tsx +180 -0
  80. package/src/components/custom/ActiveWork/SessionList.stories.tsx +69 -0
  81. package/src/components/custom/ActiveWork/SessionList.test.tsx +78 -0
  82. package/src/components/custom/ActiveWork/SessionList.tsx +103 -0
  83. package/src/components/custom/ActiveWork/SessionListItem.stories.tsx +64 -0
  84. package/src/components/custom/ActiveWork/SessionListItem.test.tsx +62 -0
  85. package/src/components/custom/ActiveWork/SessionListItem.tsx +152 -0
  86. package/src/components/custom/ActiveWork/SessionReader.stories.tsx +113 -0
  87. package/src/components/custom/ActiveWork/SeverityLabel.stories.tsx +51 -0
  88. package/src/components/custom/ActiveWork/SeverityLabel.test.tsx +68 -0
  89. package/src/components/custom/ActiveWork/SeverityLabel.tsx +97 -0
  90. package/src/components/custom/ActiveWork/TaskRow.stories.tsx +63 -0
  91. package/src/components/custom/ActiveWork/TaskRow.test.tsx +112 -0
  92. package/src/components/custom/ActiveWork/TaskRow.tsx +176 -0
  93. package/src/components/custom/ActiveWork/TaskTable.stories.tsx +123 -0
  94. package/src/components/custom/ActiveWork/TaskTable.test.tsx +233 -0
  95. package/src/components/custom/ActiveWork/TaskTable.tsx +321 -0
  96. package/src/components/custom/ActiveWork/active-work-depth.test.tsx +102 -0
  97. package/src/components/custom/ActiveWork/file-history-fixture.ts +91 -0
  98. package/src/components/custom/ActiveWork/format-time.test.ts +23 -0
  99. package/src/components/custom/ActiveWork/format-time.ts +32 -0
  100. package/src/components/custom/ActiveWork/index.ts +19 -0
  101. package/src/components/custom/ActiveWork/initiative-fixture.ts +104 -0
  102. package/src/components/custom/ActiveWork/session-fixture.ts +267 -0
  103. package/src/components/custom/ActiveWork/session-linkers.ts +56 -0
  104. package/src/components/custom/ActiveWork/task-list-fixture.ts +97 -0
  105. package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +4 -3
  106. package/src/components/custom/DateTime/DateTime.stories.tsx +2 -1
  107. package/src/components/custom/DateTime/DateTime.test.tsx +3 -1
  108. package/src/components/custom/EmptyState/EmptyState.stories.tsx +22 -9
  109. package/src/components/custom/EmptyState/EmptyState.test.tsx +7 -13
  110. package/src/components/custom/EmptyState/EmptyState.tsx +4 -18
  111. package/src/components/custom/Fatigue/DualGhostSpark.stories.tsx +4 -3
  112. package/src/components/custom/Fatigue/FatigueLights.stories.tsx +2 -2
  113. package/src/components/custom/Fatigue/GhostSpark.stories.tsx +4 -3
  114. package/src/components/custom/Fatigue/LiveFatigueCard.stories.tsx +2 -2
  115. package/src/components/custom/Fatigue/LiveFatigueCard.tsx +8 -4
  116. package/src/components/custom/Fatigue/LiveFatiguePanel.stories.tsx +116 -6
  117. package/src/components/custom/Fatigue/LiveFatiguePanel.test.tsx +134 -0
  118. package/src/components/custom/Fatigue/LiveFatiguePanel.tsx +54 -83
  119. package/src/components/custom/Fatigue/README.md +40 -3
  120. package/src/components/custom/Fatigue/RomProgressionChart.stories.tsx +2 -2
  121. package/src/components/custom/Fatigue/SilverRedPalette.stories.tsx +2 -1
  122. package/src/components/custom/Fatigue/VelocityHero.stories.tsx +4 -3
  123. package/src/components/custom/Fatigue/VerdictHero.stories.tsx +2 -2
  124. package/src/components/custom/Fatigue/fatigue-mock.test.ts +0 -5
  125. package/src/components/custom/Fatigue/fatigue-mock.ts +2 -10
  126. package/src/components/custom/Fatigue/fatigue-tokens.ts +12 -0
  127. package/src/components/custom/Fatigue/index.ts +17 -5
  128. package/src/components/custom/Fatigue/panel-layout.test.ts +149 -0
  129. package/src/components/custom/Fatigue/panel-layout.ts +185 -0
  130. package/src/components/custom/Gauge/Gauge.stories.tsx +2 -2
  131. package/src/components/custom/Gauge/Gauge.test.tsx +1 -1
  132. package/src/components/custom/Gauge/Gauge.tsx +4 -1
  133. package/src/components/custom/Metric/Metric.stories.tsx +10 -1
  134. package/src/components/custom/Metric/Metric.test.tsx +1 -3
  135. package/src/components/custom/Metric/Metric.tsx +5 -20
  136. package/src/components/custom/Prose/MarkdownProse.stories.tsx +88 -0
  137. package/src/components/custom/Prose/MarkdownProse.test.tsx +87 -0
  138. package/src/components/custom/Prose/MarkdownProse.tsx +201 -0
  139. package/src/components/custom/Prose/README.md +58 -0
  140. package/src/components/custom/Prose/index.ts +1 -0
  141. package/src/components/custom/Scatter/Scatter.stories.tsx +46 -8
  142. package/src/components/custom/Scatter/Scatter.test.tsx +2 -2
  143. package/src/components/custom/Scatter/Scatter.tsx +116 -14
  144. package/src/components/custom/Sidebar/Sidebar.stories.tsx +40 -7
  145. package/src/components/custom/Sidebar/Sidebar.test.tsx +5 -1
  146. package/src/components/custom/Sidebar/Sidebar.tsx +16 -33
  147. package/src/components/custom/Table/Table.stories.tsx +98 -15
  148. package/src/components/custom/Table/Table.test.tsx +273 -86
  149. package/src/components/custom/Table/Table.tsx +159 -67
  150. package/src/components/custom/Table/column-fit.test.ts +75 -0
  151. package/src/components/custom/Table/column-fit.ts +116 -0
  152. package/src/components/custom/Table/index.ts +9 -0
  153. package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +8 -6
  154. package/src/components/custom/Treemap/Treemap.stories.tsx +2 -2
  155. package/src/components/custom/Treemap/Treemap.test.tsx +1 -1
  156. package/src/components/custom/Treemap/Treemap.tsx +7 -2
  157. package/src/components/custom/Typography/Typography.stories.tsx +28 -1
  158. package/src/components/custom/Typography/Typography.test.tsx +34 -0
  159. package/src/components/custom/Typography/Typography.tsx +6 -0
  160. package/src/components/custom/Typography/index.ts +1 -8
  161. package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +9 -1
  162. package/src/components/custom/Workout/BaseBadge.stories.tsx +19 -7
  163. package/src/components/custom/Workout/BaseBadge.test.tsx +31 -11
  164. package/src/components/custom/Workout/BaseBadge.tsx +3 -0
  165. package/src/components/custom/Workout/BodyMap.stories.tsx +4 -1
  166. package/src/components/custom/Workout/BodyMap.tsx +3 -1
  167. package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +16 -4
  168. package/src/components/custom/Workout/BodyMapDetailPanel.test.tsx +11 -15
  169. package/src/components/custom/Workout/BodyMapDetailPanel.tsx +45 -9
  170. package/src/components/custom/Workout/CapacityBandChart.stories.tsx +10 -8
  171. package/src/components/custom/Workout/CapacityBandChart.test.tsx +24 -51
  172. package/src/components/custom/Workout/CapacityBandChart.tsx +139 -108
  173. package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
  174. package/src/components/custom/Workout/DeviationBar.test.tsx +5 -2
  175. package/src/components/custom/Workout/DeviationBar.tsx +21 -16
  176. package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +182 -0
  177. package/src/components/custom/Workout/DualVelocityStrip.test.tsx +3 -2
  178. package/src/components/custom/Workout/ExerciseCard.stories.tsx +8 -7
  179. package/src/components/custom/Workout/ExerciseCard.test.tsx +13 -3
  180. package/src/components/custom/Workout/ExerciseCard.tsx +42 -51
  181. package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +7 -7
  182. package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +9 -1
  183. package/src/components/custom/Workout/ExerciseHeading.stories.tsx +8 -8
  184. package/src/components/custom/Workout/ExerciseHeading.tsx +8 -5
  185. package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +6 -4
  186. package/src/components/custom/Workout/ExerciseIndicator.test.tsx +27 -11
  187. package/src/components/custom/Workout/ExerciseIndicator.tsx +14 -15
  188. package/src/components/custom/Workout/FatigueMeter.stories.tsx +5 -5
  189. package/src/components/custom/Workout/InputBar.stories.tsx +4 -5
  190. package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
  191. package/src/components/custom/Workout/IntensityBar.test.tsx +5 -1
  192. package/src/components/custom/Workout/IntensityBar.tsx +4 -2
  193. package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +5 -4
  194. package/src/components/custom/Workout/MesoCard.stories.tsx +4 -1
  195. package/src/components/custom/Workout/MesoCard.test.tsx +7 -18
  196. package/src/components/custom/Workout/MesoCard.tsx +12 -9
  197. package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
  198. package/src/components/custom/Workout/MesoProgressBar.test.tsx +18 -11
  199. package/src/components/custom/Workout/MesoProgressBar.tsx +15 -13
  200. package/src/components/custom/Workout/MesoStatusCard.stories.tsx +2 -1
  201. package/src/components/custom/Workout/MesoStatusCard.test.tsx +14 -44
  202. package/src/components/custom/Workout/MesoStatusCard.tsx +9 -23
  203. package/src/components/custom/Workout/MetricTiles.stories.tsx +3 -2
  204. package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +2 -8
  205. package/src/components/custom/Workout/MuscleGroupChip.test.tsx +23 -31
  206. package/src/components/custom/Workout/MuscleGroupChip.tsx +28 -67
  207. package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +1 -1
  208. package/src/components/custom/Workout/PlaceholderStrip.test.tsx +17 -10
  209. package/src/components/custom/Workout/PlaceholderStrip.tsx +9 -8
  210. package/src/components/custom/Workout/PrBadge.stories.tsx +2 -1
  211. package/src/components/custom/Workout/PrBadge.test.tsx +3 -9
  212. package/src/components/custom/Workout/PrBadge.tsx +13 -17
  213. package/src/components/custom/Workout/PrHistoryModal.stories.tsx +4 -1
  214. package/src/components/custom/Workout/PrHistoryModal.test.tsx +13 -36
  215. package/src/components/custom/Workout/PrHistoryModal.tsx +8 -4
  216. package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +6 -1
  217. package/src/components/custom/Workout/README.md +12 -7
  218. package/src/components/custom/Workout/ReadinessCheck.stories.tsx +3 -2
  219. package/src/components/custom/Workout/ReadinessCheck.test.tsx +12 -18
  220. package/src/components/custom/Workout/ReadinessCheck.tsx +19 -3
  221. package/src/components/custom/Workout/RestTimer.stories.tsx +3 -2
  222. package/src/components/custom/Workout/ScheduleTiles.stories.tsx +3 -2
  223. package/src/components/custom/Workout/ScheduleTiles.test.tsx +3 -4
  224. package/src/components/custom/Workout/ScheduleTiles.tsx +4 -7
  225. package/src/components/custom/Workout/SegmentedBar.stories.tsx +5 -5
  226. package/src/components/custom/Workout/SegmentedBar.tsx +6 -2
  227. package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +5 -5
  228. package/src/components/custom/Workout/SessionHeader.stories.tsx +6 -6
  229. package/src/components/custom/Workout/SessionHeader.tsx +12 -12
  230. package/src/components/custom/Workout/SessionRail.stories.tsx +12 -11
  231. package/src/components/custom/Workout/SessionRail.tsx +7 -9
  232. package/src/components/custom/Workout/SetBar.stories.tsx +10 -6
  233. package/src/components/custom/Workout/SetBar.test.tsx +49 -4
  234. package/src/components/custom/Workout/SetBar.tsx +38 -12
  235. package/src/components/custom/Workout/SetRow.stories.tsx +3 -2
  236. package/src/components/custom/Workout/SetRow.test.tsx +16 -2
  237. package/src/components/custom/Workout/SetRow.tsx +61 -23
  238. package/src/components/custom/Workout/SetStrip.stories.tsx +60 -5
  239. package/src/components/custom/Workout/SetStrip.test.tsx +25 -0
  240. package/src/components/custom/Workout/SetStrip.tsx +24 -4
  241. package/src/components/custom/Workout/SetTableHeader.stories.tsx +6 -6
  242. package/src/components/custom/Workout/SetTableHeader.tsx +9 -12
  243. package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +7 -7
  244. package/src/components/custom/Workout/SetsRepsLoad.tsx +3 -5
  245. package/src/components/custom/Workout/Sparkline.stories.tsx +1 -1
  246. package/src/components/custom/Workout/Sparkline.test.tsx +37 -19
  247. package/src/components/custom/Workout/Sparkline.tsx +14 -18
  248. package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
  249. package/src/components/custom/Workout/StatusDot.test.tsx +44 -5
  250. package/src/components/custom/Workout/StatusDot.tsx +93 -63
  251. package/src/components/custom/Workout/StatusPill.stories.tsx +1 -1
  252. package/src/components/custom/Workout/StatusPill.test.tsx +6 -15
  253. package/src/components/custom/Workout/StatusPill.tsx +27 -38
  254. package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +9 -3
  255. package/src/components/custom/Workout/StrengthTrendChart.test.tsx +15 -37
  256. package/src/components/custom/Workout/StrengthTrendChart.tsx +31 -30
  257. package/src/components/custom/Workout/SupersetWrapper.stories.tsx +27 -64
  258. package/src/components/custom/Workout/SupersetWrapper.test.tsx +16 -14
  259. package/src/components/custom/Workout/SupersetWrapper.tsx +17 -21
  260. package/src/components/custom/Workout/TempoDisplay.stories.tsx +22 -7
  261. package/src/components/custom/Workout/TempoDisplay.test.tsx +18 -4
  262. package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +9 -1
  263. package/src/components/custom/Workout/VelocityStrip.compact.stories.tsx +4 -1
  264. package/src/components/custom/Workout/VelocityStrip.dual.stories.tsx +7 -4
  265. package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +4 -1
  266. package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +4 -1
  267. package/src/components/custom/Workout/VelocityStrip.stories.tsx +12 -6
  268. package/src/components/custom/Workout/VelocityStrip.tsx +3 -0
  269. package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +6 -7
  270. package/src/components/custom/Workout/VolumeLandmarkBar.tsx +15 -6
  271. package/src/components/custom/Workout/WeekRow.stories.tsx +4 -1
  272. package/src/components/custom/Workout/WeekRow.test.tsx +18 -15
  273. package/src/components/custom/Workout/WeekRow.tsx +23 -16
  274. package/src/components/custom/Workout/WeightBadge.stories.tsx +2 -1
  275. package/src/components/custom/Workout/WeightBadge.test.tsx +50 -19
  276. package/src/components/custom/Workout/WeightBadge.tsx +28 -27
  277. package/src/components/custom/Workout/WorkoutCard.stories.tsx +6 -1
  278. package/src/components/custom/Workout/WorkoutCard.test.tsx +18 -0
  279. package/src/components/custom/Workout/WorkoutCard.tsx +35 -57
  280. package/src/components/custom/Workout/WorkoutPill.stories.tsx +5 -2
  281. package/src/components/custom/Workout/WorkoutPill.test.tsx +39 -7
  282. package/src/components/custom/Workout/WorkoutPill.tsx +88 -57
  283. package/src/components/custom/Workout/ZoneTrack.stories.tsx +7 -6
  284. package/src/components/custom/Workout/ZoneTrack.tsx +10 -9
  285. package/src/components/custom/Workout/index.ts +5 -0
  286. package/src/components/custom/Workout/metricText.stories.tsx +6 -5
  287. package/src/components/custom/Workout/metricText.tsx +4 -0
  288. package/src/components/custom/Workout/setHeadingKit.tsx +207 -26
  289. package/src/components/custom/charts/README.md +61 -0
  290. package/src/components/custom/charts/SetBarChart.test.tsx +30 -1
  291. package/src/components/custom/charts/SetBarChart.tsx +42 -4
  292. package/src/components/custom/charts/SparkBars.stories.tsx +55 -0
  293. package/src/components/custom/charts/SparkBars.test.tsx +69 -0
  294. package/src/components/custom/charts/SparkBars.tsx +85 -0
  295. package/src/components/custom/charts/index.ts +3 -0
  296. package/src/components/custom/index.ts +3 -0
  297. package/src/components/custom/stepper/Stepper.stories.tsx +13 -10
  298. package/src/components/custom/stepper/Stepper.test.tsx +1 -7
  299. package/src/components/custom/stepper/Stepper.tsx +13 -28
  300. package/src/components/icons/icons.stories.tsx +1 -1
  301. package/src/components/icons/icons.tsx +51 -0
  302. package/src/components/shell/AppShell.stories.tsx +150 -0
  303. package/src/components/shell/AppShell.test.tsx +70 -0
  304. package/src/components/shell/AppShell.tsx +90 -0
  305. package/src/components/shell/BrandLockup.stories.tsx +66 -5
  306. package/src/components/shell/BrandLockup.test.tsx +34 -1
  307. package/src/components/shell/BrandLockup.tsx +27 -11
  308. package/src/components/shell/NavItem.stories.tsx +4 -4
  309. package/src/components/shell/NavItem.test.tsx +17 -0
  310. package/src/components/shell/NavItem.tsx +17 -5
  311. package/src/components/shell/README.md +90 -27
  312. package/src/components/shell/SideNav.stories.tsx +38 -7
  313. package/src/components/shell/SideNav.test.tsx +16 -8
  314. package/src/components/shell/SideNav.tsx +17 -17
  315. package/src/components/shell/TopBar.stories.tsx +44 -19
  316. package/src/components/shell/TopBar.test.tsx +34 -12
  317. package/src/components/shell/TopBar.tsx +61 -40
  318. package/src/components/shell/brands.tsx +66 -0
  319. package/src/components/shell/index.ts +9 -8
  320. package/src/components/shell/{DeviceIndicator.stories.tsx → workout/DeviceIndicator.stories.tsx} +2 -2
  321. package/src/components/shell/{DeviceIndicator.tsx → workout/DeviceIndicator.tsx} +2 -2
  322. package/src/components/shell/{DeviceMenu.stories.tsx → workout/DeviceMenu.stories.tsx} +2 -2
  323. package/src/components/shell/{DeviceMenu.tsx → workout/DeviceMenu.tsx} +3 -3
  324. package/src/components/shell/{DeviceRow.stories.tsx → workout/DeviceRow.stories.tsx} +2 -2
  325. package/src/components/shell/{DeviceRow.tsx → workout/DeviceRow.tsx} +3 -3
  326. package/src/components/shell/{SessionStatePill.stories.tsx → workout/SessionStatePill.stories.tsx} +2 -2
  327. package/src/components/shell/{SessionStatePill.tsx → workout/SessionStatePill.tsx} +5 -3
  328. package/src/components/shell/workout/WorkoutShell.stories.tsx +71 -0
  329. package/src/components/shell/{DashboardShell.test.tsx → workout/WorkoutShell.test.tsx} +19 -8
  330. package/src/components/shell/workout/WorkoutShell.tsx +77 -0
  331. package/src/components/shell/workout/WorkoutTopBar.stories.tsx +58 -0
  332. package/src/components/shell/workout/WorkoutTopBar.test.tsx +39 -0
  333. package/src/components/shell/workout/WorkoutTopBar.tsx +52 -0
  334. package/src/components/shell/workout/index.ts +9 -0
  335. package/src/components/shell/workout/workoutNavItems.tsx +16 -0
  336. package/src/components/ui/README.md +110 -0
  337. package/src/components/ui/alert/Alert.stories.tsx +1 -1
  338. package/src/components/ui/autocomplete/Autocomplete.stories.tsx +11 -13
  339. package/src/components/ui/autocomplete/Autocomplete.test.tsx +7 -25
  340. package/src/components/ui/autocomplete/Autocomplete.tsx +21 -28
  341. package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
  342. package/src/components/ui/avatar/Avatar.tsx +2 -10
  343. package/src/components/ui/badge/Badge.stories.tsx +83 -28
  344. package/src/components/ui/badge/Badge.test.tsx +19 -3
  345. package/src/components/ui/badge/Badge.tsx +48 -55
  346. package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
  347. package/src/components/ui/breadcrumbs/Breadcrumbs.tsx +4 -16
  348. package/src/components/ui/button/Button.stories.tsx +46 -12
  349. package/src/components/ui/button/Button.tsx +32 -25
  350. package/src/components/ui/card/Card.stories.tsx +90 -94
  351. package/src/components/ui/card/Card.test.tsx +80 -6
  352. package/src/components/ui/card/Card.tsx +150 -203
  353. package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
  354. package/src/components/ui/checkbox/Checkbox.tsx +6 -26
  355. package/src/components/ui/chip/Chip.stories.tsx +37 -13
  356. package/src/components/ui/chip/Chip.test.tsx +10 -6
  357. package/src/components/ui/chip/Chip.tsx +76 -91
  358. package/src/components/ui/collapse/Collapse.stories.tsx +23 -23
  359. package/src/components/ui/collapse/Collapse.tsx +6 -11
  360. package/src/components/ui/data-row/DataRow.stories.tsx +9 -2
  361. package/src/components/ui/data-row/DataRow.test.tsx +5 -15
  362. package/src/components/ui/data-row/DataRow.tsx +18 -7
  363. package/src/components/ui/divider/Divider.stories.tsx +1 -1
  364. package/src/components/ui/divider/Divider.tsx +1 -5
  365. package/src/components/ui/drawer/Drawer.stories.tsx +5 -16
  366. package/src/components/ui/drawer/Drawer.tsx +13 -30
  367. package/src/components/ui/floating-overlay-depth.test.tsx +143 -0
  368. package/src/components/ui/form-field/FormField.stories.tsx +6 -20
  369. package/src/components/ui/form-field/FormField.test.tsx +1 -5
  370. package/src/components/ui/form-field/FormField.tsx +10 -46
  371. package/src/components/ui/help-tip/HelpTip.stories.tsx +8 -19
  372. package/src/components/ui/help-tip/HelpTip.test.tsx +1 -3
  373. package/src/components/ui/help-tip/HelpTip.tsx +21 -22
  374. package/src/components/ui/help-tip/index.ts +7 -1
  375. package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
  376. package/src/components/ui/icon-box/IconBox.test.tsx +1 -7
  377. package/src/components/ui/icon-box/IconBox.tsx +2 -12
  378. package/src/components/ui/indicator/Indicator.stories.tsx +1 -1
  379. package/src/components/ui/indicator/Indicator.tsx +20 -14
  380. package/src/components/ui/input/Input.stories.tsx +3 -11
  381. package/src/components/ui/input/Input.test.tsx +2 -10
  382. package/src/components/ui/input/Input.tsx +10 -25
  383. package/src/components/ui/input/index.ts +7 -1
  384. package/src/components/ui/link/Link.stories.tsx +19 -7
  385. package/src/components/ui/list-item/ListItem.stories.tsx +11 -2
  386. package/src/components/ui/list-item/ListItem.tsx +2 -9
  387. package/src/components/ui/menu/Menu.stories.tsx +21 -15
  388. package/src/components/ui/menu/Menu.test.tsx +2 -11
  389. package/src/components/ui/menu/Menu.tsx +12 -14
  390. package/src/components/ui/menu/index.ts +8 -1
  391. package/src/components/ui/modal/Modal.stories.tsx +2 -2
  392. package/src/components/ui/modal/Modal.tsx +29 -19
  393. package/src/components/ui/pill/Pill.stories.tsx +58 -23
  394. package/src/components/ui/pill/Pill.test.tsx +101 -3
  395. package/src/components/ui/pill/Pill.tsx +164 -49
  396. package/src/components/ui/pill/index.ts +1 -1
  397. package/src/components/ui/popover/Popover.stories.tsx +5 -7
  398. package/src/components/ui/popover/Popover.test.tsx +1 -6
  399. package/src/components/ui/popover/Popover.tsx +20 -15
  400. package/src/components/ui/popover/index.ts +7 -1
  401. package/src/components/ui/progress/Progress.stories.tsx +3 -12
  402. package/src/components/ui/progress/Progress.test.tsx +1 -5
  403. package/src/components/ui/radio/Radio.stories.tsx +42 -21
  404. package/src/components/ui/radio/Radio.test.tsx +6 -2
  405. package/src/components/ui/radio/Radio.tsx +23 -22
  406. package/src/components/ui/section/Section.stories.tsx +5 -14
  407. package/src/components/ui/section/Section.test.tsx +1 -6
  408. package/src/components/ui/section/Section.tsx +1 -3
  409. package/src/components/ui/section/index.ts +1 -5
  410. package/src/components/ui/select/Select.stories.tsx +3 -13
  411. package/src/components/ui/select/Select.test.tsx +2 -11
  412. package/src/components/ui/select/Select.tsx +14 -14
  413. package/src/components/ui/skeleton/Skeleton.stories.tsx +3 -11
  414. package/src/components/ui/skeleton/Skeleton.tsx +3 -14
  415. package/src/components/ui/skeleton/index.ts +1 -7
  416. package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
  417. package/src/components/ui/spinner/Spinner.tsx +1 -4
  418. package/src/components/ui/stack/Stack.stories.tsx +1 -1
  419. package/src/components/ui/stack/Stack.tsx +1 -1
  420. package/src/components/ui/surface/Surface.stories.tsx +17 -5
  421. package/src/components/ui/surface/Surface.test.tsx +88 -28
  422. package/src/components/ui/surface/Surface.tsx +37 -87
  423. package/src/components/ui/surface/SurfaceContext.ts +22 -62
  424. package/src/components/ui/surface/index.ts +8 -0
  425. package/src/components/ui/surface/resolveSurface.ts +98 -0
  426. package/src/components/ui/surface/surface.contract.test.ts +6 -1
  427. package/src/components/ui/switch/Switch.stories.tsx +1 -1
  428. package/src/components/ui/switch/Switch.tsx +7 -6
  429. package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
  430. package/src/components/ui/tabs/Tabs.tsx +7 -22
  431. package/src/components/ui/tabs/index.ts +1 -7
  432. package/src/components/ui/tile/Tile.stories.tsx +1 -1
  433. package/src/components/ui/tile/Tile.tsx +3 -0
  434. package/src/components/ui/toast/Toast.stories.tsx +1 -1
  435. package/src/components/ui/toast/Toast.test.tsx +2 -8
  436. package/src/components/ui/toast/Toast.tsx +43 -53
  437. package/src/components/ui/toast/index.ts +0 -1
  438. package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +92 -71
  439. package/src/components/ui/toolbar-button/ToolbarButton.test.tsx +3 -18
  440. package/src/components/ui/toolbar-button/ToolbarButton.tsx +25 -43
  441. package/src/components/ui/tooltip/Tooltip.stories.tsx +12 -3
  442. package/src/components/ui/tooltip/Tooltip.test.tsx +21 -3
  443. package/src/components/ui/tooltip/Tooltip.tsx +55 -36
  444. package/src/components/ui/tooltip/index.ts +1 -1
  445. package/src/components/ui/trigger/TriggerSurface.test.tsx +215 -0
  446. package/src/components/ui/trigger/TriggerSurface.tsx +81 -0
  447. package/src/components/ui/trigger/index.ts +2 -0
  448. package/src/stories/PresetShowcase.stories.tsx +100 -47
  449. package/src/test/no-device-internals.test.ts +3 -3
  450. package/src/theme/ChoosingTokens.stories.tsx +48 -0
  451. package/src/theme/ColorPalettes.stories.tsx +62 -45
  452. package/src/theme/ColorPrimitives.stories.tsx +35 -35
  453. package/src/theme/Depth.stories.tsx +132 -65
  454. package/src/theme/DepthCalibration.stories.tsx +24 -22
  455. package/src/theme/ThemeProvider.test.tsx +4 -4
  456. package/src/theme/barrel.ts +7 -6
  457. package/src/theme/color-stories.coverage.test.ts +1 -1
  458. package/src/theme/color-utils.ts +41 -29
  459. package/src/theme/config.completeness.test.ts +1 -1
  460. package/src/theme/config.ts +28 -0
  461. package/src/theme/elevation.test.ts +82 -56
  462. package/src/theme/elevation.ts +77 -561
  463. package/src/theme/global.css +30 -2
  464. package/src/theme/grey-ramp.test.ts +24 -8
  465. package/src/theme/lift.test.ts +39 -0
  466. package/src/theme/lift.ts +102 -0
  467. package/src/theme/materials.test.ts +5 -2
  468. package/src/theme/materials.ts +38 -4
  469. package/src/theme/native-theming-guard.test.ts +5 -5
  470. package/src/theme/presets/apply.ts +4 -0
  471. package/src/theme/presets/audiobook.ts +5 -2
  472. package/src/theme/presets/default.ts +4 -0
  473. package/src/theme/presets/index.ts +14 -1
  474. package/src/theme/presets/types.ts +1 -1
  475. package/src/theme/semantic-contrast.test.ts +13 -4
  476. package/src/theme/status-distinctness.test.ts +66 -0
  477. package/src/theme/surface-planes.test.ts +37 -0
  478. package/src/theme/surface-planes.ts +68 -0
  479. package/src/theme/token-export-guard.test.ts +102 -0
  480. package/src/theme/tokens/primitives.test.ts +15 -7
  481. package/src/theme/tokens/primitives.ts +67 -35
  482. package/src/theme/tokens/semantic.ts +71 -37
  483. package/src/theme/wash-ladder.test.ts +58 -0
  484. package/src/theme/workout-tokens.ts +1 -7
  485. package/src/types/jest-axe.d.ts +2 -6
  486. package/src/types/raw-md.d.ts +5 -0
  487. package/src/utils/colors.ts +4 -4
  488. package/src/utils/form.ts +1 -3
  489. package/src/utils/index.ts +2 -7
  490. package/src/utils/number-format.ts +17 -0
  491. package/src/utils/workout-format.ts +15 -6
  492. package/src/web-jsx/jsx-runtime.ts +1 -5
  493. package/tailwind.config.js +5 -0
  494. package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +0 -151
  495. package/src/components/custom/Workout/RowInventory.stories.tsx +0 -408
  496. package/src/components/custom/Workout/S3FullRail.stories.tsx +0 -46
  497. package/src/components/custom/Workout/S3SessionPace.stories.tsx +0 -95
  498. package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +0 -61
  499. package/src/components/custom/Workout/S3SetTypes.stories.tsx +0 -176
  500. package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +0 -240
  501. package/src/components/shell/DashboardShell.stories.tsx +0 -65
  502. package/src/components/shell/DashboardShell.tsx +0 -75
  503. package/src/components/shell/SessionRailSpecimen.stories.tsx +0 -753
  504. package/src/theme/elevation.stories.tsx +0 -346
  505. package/src/utils/useTheme.ts +0 -72
  506. /package/src/components/shell/{DeviceIndicator.test.tsx → workout/DeviceIndicator.test.tsx} +0 -0
  507. /package/src/components/shell/{DeviceMenu.test.tsx → workout/DeviceMenu.test.tsx} +0 -0
  508. /package/src/components/shell/{DeviceRow.test.tsx → workout/DeviceRow.test.tsx} +0 -0
  509. /package/src/components/shell/{SessionStatePill.test.tsx → workout/SessionStatePill.test.tsx} +0 -0
@@ -1,20 +1,20 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
- import { View, Text } from 'react-native'
3
2
  import { SupersetWrapper } from './SupersetWrapper'
4
3
  import { ExerciseCard } from './ExerciseCard'
5
- import { getSemanticColors } from '../../../theme/tokens/semantic'
6
-
7
- const t = getSemanticColors('dark')
4
+ import { Card } from '../../ui/card'
5
+ import { Typography } from '../Typography'
6
+ import { Surface } from '../../ui/surface'
7
+ import { resolveColor } from '../../../theme/resolve-color'
8
8
 
9
9
  const meta: Meta<typeof SupersetWrapper> = {
10
- title: 'Workout/SupersetWrapper',
10
+ title: 'Custom/Workout/SupersetWrapper',
11
11
  component: SupersetWrapper,
12
12
  tags: ['autodocs'],
13
13
  decorators: [
14
14
  (Story) => (
15
- <View style={{ maxWidth: 400, padding: 16, backgroundColor: t['background-base'] }}>
15
+ <Surface level="background" style={{ maxWidth: 400, padding: 16 }}>
16
16
  <Story />
17
- </View>
17
+ </Surface>
18
18
  ),
19
19
  ],
20
20
  }
@@ -22,28 +22,21 @@ const meta: Meta<typeof SupersetWrapper> = {
22
22
  export default meta
23
23
  type Story = StoryObj<typeof SupersetWrapper>
24
24
 
25
+ /** Stand-in for a real exercise row: a filled Card on the wrapper's own plane. */
26
+ function DemoExercise({ name }: { name: string }) {
27
+ return (
28
+ <Card variant="filled" elevation={1} className="p-3">
29
+ <Typography variant="body2">{name}</Typography>
30
+ </Card>
31
+ )
32
+ }
33
+
25
34
  export const Default: Story = {
26
35
  args: {
27
36
  children: (
28
37
  <>
29
- <View
30
- style={{
31
- padding: 12,
32
- backgroundColor: t['surface-raised'],
33
- borderRadius: 8,
34
- }}
35
- >
36
- <Text style={{ color: '#F3F4F6', fontFamily: 'Inter, sans-serif' }}>Exercise A</Text>
37
- </View>
38
- <View
39
- style={{
40
- padding: 12,
41
- backgroundColor: t['surface-raised'],
42
- borderRadius: 8,
43
- }}
44
- >
45
- <Text style={{ color: '#F3F4F6', fontFamily: 'Inter, sans-serif' }}>Exercise B</Text>
46
- </View>
38
+ <DemoExercise name="Exercise A" />
39
+ <DemoExercise name="Exercise B" />
47
40
  </>
48
41
  ),
49
42
  },
@@ -54,24 +47,8 @@ export const CustomLabel: Story = {
54
47
  label: 'A1/A2',
55
48
  children: (
56
49
  <>
57
- <View
58
- style={{
59
- padding: 12,
60
- backgroundColor: t['surface-raised'],
61
- borderRadius: 8,
62
- }}
63
- >
64
- <Text style={{ color: '#F3F4F6', fontFamily: 'Inter, sans-serif' }}>Exercise A1</Text>
65
- </View>
66
- <View
67
- style={{
68
- padding: 12,
69
- backgroundColor: t['surface-raised'],
70
- borderRadius: 8,
71
- }}
72
- >
73
- <Text style={{ color: '#F3F4F6', fontFamily: 'Inter, sans-serif' }}>Exercise A2</Text>
74
- </View>
50
+ <DemoExercise name="Exercise A1" />
51
+ <DemoExercise name="Exercise A2" />
75
52
  </>
76
53
  ),
77
54
  },
@@ -79,39 +56,25 @@ export const CustomLabel: Story = {
79
56
 
80
57
  export const CustomColor: Story = {
81
58
  args: {
82
- color: '#22C55E',
59
+ color: resolveColor('status-success'),
83
60
  children: (
84
61
  <>
85
- <View
86
- style={{
87
- padding: 12,
88
- backgroundColor: t['surface-raised'],
89
- borderRadius: 8,
90
- }}
91
- >
92
- <Text style={{ color: '#F3F4F6', fontFamily: 'Inter, sans-serif' }}>Exercise A</Text>
93
- </View>
94
- <View
95
- style={{
96
- padding: 12,
97
- backgroundColor: t['surface-raised'],
98
- borderRadius: 8,
99
- }}
100
- >
101
- <Text style={{ color: '#F3F4F6', fontFamily: 'Inter, sans-serif' }}>Exercise B</Text>
102
- </View>
62
+ <DemoExercise name="Exercise A" />
63
+ <DemoExercise name="Exercise B" />
103
64
  </>
104
65
  ),
105
66
  },
106
67
  }
107
68
 
69
+ const supersetColor = resolveColor('brand-primary')
70
+
108
71
  const exerciseA = {
109
72
  name: 'Bench Press',
110
73
  state: 'collapsed' as const,
111
74
  onToggle: () => {},
112
75
  summary: { sets: 3, reps: 8, weight: 185, unit: 'lbs' as const },
113
76
  supersetPosition: 'first' as const,
114
- supersetColor: '#FF7900',
77
+ supersetColor,
115
78
  }
116
79
 
117
80
  const exerciseB = {
@@ -120,7 +83,7 @@ const exerciseB = {
120
83
  onToggle: () => {},
121
84
  summary: { sets: 3, reps: 8, weight: 155, unit: 'lbs' as const },
122
85
  supersetPosition: 'last' as const,
123
- supersetColor: '#FF7900',
86
+ supersetColor,
124
87
  }
125
88
 
126
89
  export const WithExerciseCards: Story = {
@@ -3,6 +3,7 @@ import { render, screen } from '@testing-library/react'
3
3
  import { axe } from 'jest-axe'
4
4
  import { View, Text } from 'react-native'
5
5
  import { SupersetWrapper } from './SupersetWrapper'
6
+ import { resolveColor } from '../../../theme/resolve-color'
6
7
 
7
8
  describe('SupersetWrapper', () => {
8
9
  describe('label', () => {
@@ -10,7 +11,7 @@ describe('SupersetWrapper', () => {
10
11
  render(
11
12
  <SupersetWrapper>
12
13
  <View />
13
- </SupersetWrapper>,
14
+ </SupersetWrapper>
14
15
  )
15
16
  expect(screen.getByTestId('superset-label')).toHaveTextContent('SS')
16
17
  })
@@ -19,31 +20,32 @@ describe('SupersetWrapper', () => {
19
20
  render(
20
21
  <SupersetWrapper label="A1/A2">
21
22
  <View />
22
- </SupersetWrapper>,
23
+ </SupersetWrapper>
23
24
  )
24
25
  expect(screen.getByTestId('superset-label')).toHaveTextContent('A1/A2')
25
26
  })
26
27
  })
27
28
 
28
29
  describe('color', () => {
29
- it('applies default color #FF7900 to border and label background', () => {
30
+ it('defaults border and label background to the brand-primary token', () => {
30
31
  render(
31
32
  <SupersetWrapper>
32
33
  <View />
33
- </SupersetWrapper>,
34
+ </SupersetWrapper>
34
35
  )
36
+ const brand = resolveColor('brand-primary')
35
37
  const wrapper = screen.getByTestId('superset-wrapper')
36
- expect(wrapper).toHaveStyle({ borderLeftColor: '#FF7900' })
38
+ expect(wrapper).toHaveStyle({ borderLeftColor: brand })
37
39
 
38
40
  const label = screen.getByTestId('superset-label')
39
- expect(label).toHaveStyle({ backgroundColor: '#FF7900' })
41
+ expect(label).toHaveStyle({ backgroundColor: brand })
40
42
  })
41
43
 
42
44
  it('applies custom color to border and label background', () => {
43
45
  render(
44
46
  <SupersetWrapper color="#22C55E">
45
47
  <View />
46
- </SupersetWrapper>,
48
+ </SupersetWrapper>
47
49
  )
48
50
  const wrapper = screen.getByTestId('superset-wrapper')
49
51
  expect(wrapper).toHaveStyle({ borderLeftColor: '#22C55E' })
@@ -59,7 +61,7 @@ describe('SupersetWrapper', () => {
59
61
  <SupersetWrapper>
60
62
  <Text testID="child-1">Exercise A</Text>
61
63
  <Text testID="child-2">Exercise B</Text>
62
- </SupersetWrapper>,
64
+ </SupersetWrapper>
63
65
  )
64
66
  expect(screen.getByTestId('child-1')).toHaveTextContent('Exercise A')
65
67
  expect(screen.getByTestId('child-2')).toHaveTextContent('Exercise B')
@@ -71,7 +73,7 @@ describe('SupersetWrapper', () => {
71
73
  render(
72
74
  <SupersetWrapper>
73
75
  <View />
74
- </SupersetWrapper>,
76
+ </SupersetWrapper>
75
77
  )
76
78
  expect(screen.getByRole('group')).toBeInTheDocument()
77
79
  })
@@ -80,7 +82,7 @@ describe('SupersetWrapper', () => {
80
82
  render(
81
83
  <SupersetWrapper>
82
84
  <View />
83
- </SupersetWrapper>,
85
+ </SupersetWrapper>
84
86
  )
85
87
  expect(screen.getByLabelText('Superset: SS')).toBeInTheDocument()
86
88
  })
@@ -89,7 +91,7 @@ describe('SupersetWrapper', () => {
89
91
  render(
90
92
  <SupersetWrapper label="A1/A2">
91
93
  <View />
92
- </SupersetWrapper>,
94
+ </SupersetWrapper>
93
95
  )
94
96
  expect(screen.getByLabelText('Superset: A1/A2')).toBeInTheDocument()
95
97
  })
@@ -99,7 +101,7 @@ describe('SupersetWrapper', () => {
99
101
  <SupersetWrapper>
100
102
  <Text>Exercise A</Text>
101
103
  <Text>Exercise B</Text>
102
- </SupersetWrapper>,
104
+ </SupersetWrapper>
103
105
  )
104
106
  const results = await axe(container)
105
107
  expect(results).toHaveNoViolations()
@@ -111,7 +113,7 @@ describe('SupersetWrapper', () => {
111
113
  render(
112
114
  <SupersetWrapper>
113
115
  <View />
114
- </SupersetWrapper>,
116
+ </SupersetWrapper>
115
117
  )
116
118
  const label = screen.getByTestId('superset-label')
117
119
  expect(label).toHaveStyle({ position: 'absolute' })
@@ -121,7 +123,7 @@ describe('SupersetWrapper', () => {
121
123
  render(
122
124
  <SupersetWrapper>
123
125
  <View />
124
- </SupersetWrapper>,
126
+ </SupersetWrapper>
125
127
  )
126
128
  const label = screen.getByTestId('superset-label')
127
129
  expect(label).toHaveStyle({ top: '-1px', left: '-3px' })
@@ -1,31 +1,27 @@
1
1
  // Font mapping: font-heading=Space Grotesk, font-body=Nunito Sans (UI), font-sans=Inter (body)
2
2
  import React from 'react'
3
- import { View, Text } from 'react-native'
4
- import { getSemanticColors } from '../../../theme/tokens/semantic'
3
+ import { View } from 'react-native'
4
+ import { Typography } from '../Typography'
5
+ import { resolveColor } from '../../../theme/resolve-color'
5
6
 
6
7
  export interface SupersetWrapperProps {
7
8
  label?: string
9
+ /** Rail and label-chip colour. Defaults to the `brand-primary` token. */
8
10
  color?: string
9
11
  children: React.ReactNode
10
12
  }
11
13
 
12
- const DEFAULTS = {
13
- label: 'SS',
14
- color: getSemanticColors('dark')['brand-primary'],
15
- bgBase: getSemanticColors('dark')['background-base'],
16
- } as const
14
+ const DEFAULT_LABEL = 'SS'
15
+
16
+ export function SupersetWrapper({ label = DEFAULT_LABEL, color, children }: SupersetWrapperProps) {
17
+ const rail = color ?? resolveColor('brand-primary')
17
18
 
18
- export function SupersetWrapper({
19
- label = DEFAULTS.label,
20
- color = DEFAULTS.color,
21
- children,
22
- }: SupersetWrapperProps) {
23
19
  return (
24
20
  <View
25
21
  style={{
26
22
  position: 'relative',
27
23
  borderLeftWidth: 3,
28
- borderLeftColor: color,
24
+ borderLeftColor: rail,
29
25
  paddingLeft: 8,
30
26
  marginHorizontal: 12,
31
27
  marginBottom: 8,
@@ -35,26 +31,26 @@ export function SupersetWrapper({
35
31
  accessibilityLabel={`Superset: ${label}`}
36
32
  testID="superset-wrapper"
37
33
  >
38
- <Text
34
+ {/* `microLabel` is the 10px uppercase micro-label form and carries its own
35
+ face, weight and tracking. The chip was 9px/700 with a hand-set 0.5px
36
+ tracking; 9px is off the type scale (TOKENS.md §4), so it rounds up. */}
37
+ <Typography
38
+ variant="microLabel"
39
+ color="inverse"
39
40
  style={{
40
41
  position: 'absolute',
41
42
  top: -1,
42
43
  left: -3,
43
- fontSize: 9,
44
- fontFamily: 'Inter, sans-serif',
45
- fontWeight: '700',
46
- backgroundColor: color,
47
- color: DEFAULTS.bgBase,
44
+ backgroundColor: rail,
48
45
  paddingVertical: 2,
49
46
  paddingHorizontal: 6,
50
47
  borderBottomRightRadius: 4,
51
- letterSpacing: 0.5,
52
48
  zIndex: 2,
53
49
  }}
54
50
  testID="superset-label"
55
51
  >
56
52
  {label}
57
- </Text>
53
+ </Typography>
58
54
  <View style={{ gap: 2 }} testID="superset-children">
59
55
  {children}
60
56
  </View>
@@ -6,7 +6,7 @@ import { TempoDisplay, type TempoLivePhase, type TempoLiveState } from './TempoD
6
6
 
7
7
  // tempo = [eccentric, pauseBottom, concentric, pauseTop]
8
8
  const meta: Meta<typeof TempoDisplay> = {
9
- title: 'Workout/TempoDisplay',
9
+ title: 'Custom/Workout/TempoDisplay',
10
10
  component: TempoDisplay,
11
11
  tags: ['autodocs'],
12
12
  parameters: {
@@ -14,9 +14,9 @@ const meta: Meta<typeof TempoDisplay> = {
14
14
  description: {
15
15
  component:
16
16
  '**Molecule.** The eccentric/pause/concentric/pause tempo display. Composes ' +
17
- '[MetricCell](?path=/docs/workout-metriccell--docs) ' +
17
+ '[MetricCell](?path=/docs/custom-workout-metriccell--docs) ' +
18
18
  '(shared value/separator cell). Used-by ↑ ' +
19
- '[ExerciseHeading](?path=/docs/workout-exerciseheading--docs) (`showLabel={false}`).',
19
+ '[ExerciseHeading](?path=/docs/custom-workout-exerciseheading--docs) (`showLabel={false}`).',
20
20
  },
21
21
  },
22
22
  },
@@ -26,7 +26,10 @@ const meta: Meta<typeof TempoDisplay> = {
26
26
  description: 'Tempo values [eccentric, pauseBottom, concentric, pauseTop] in seconds',
27
27
  },
28
28
  size: { control: 'select', options: ['sm', 'md'], description: 'Size variant' },
29
- fontSize: { control: { type: 'range', min: 9, max: 48, step: 1 }, description: 'Digit size (overrides `size`)' },
29
+ fontSize: {
30
+ control: { type: 'range', min: 9, max: 48, step: 1 },
31
+ description: 'Digit size (overrides `size`)',
32
+ },
30
33
  showLabel: { control: 'boolean', description: 'Show the TEMPO caption' },
31
34
  showInfo: { control: 'boolean', description: 'Show info tooltip on press' },
32
35
  live: {
@@ -273,21 +276,33 @@ export const ActiveTempoConditions: Story = {
273
276
  caption="Compact (14) · label off"
274
277
  tempo={TEMPO}
275
278
  fontSize={14}
276
- live={{ activePhase: 'concentric', phaseElapsedMs: 900, completed: { eccentric: 3000, pauseBottom: 1000 } }}
279
+ live={{
280
+ activePhase: 'concentric',
281
+ phaseElapsedMs: 900,
282
+ completed: { eccentric: 3000, pauseBottom: 1000 },
283
+ }}
277
284
  />
278
285
  <Condition
279
286
  caption="Default (22) · label on"
280
287
  tempo={TEMPO}
281
288
  fontSize={22}
282
289
  showLabel
283
- live={{ activePhase: 'concentric', phaseElapsedMs: 900, completed: { eccentric: 3000, pauseBottom: 1000 } }}
290
+ live={{
291
+ activePhase: 'concentric',
292
+ phaseElapsedMs: 900,
293
+ completed: { eccentric: 3000, pauseBottom: 1000 },
294
+ }}
284
295
  />
285
296
  <Condition
286
297
  caption="Wall (34) · label on"
287
298
  tempo={TEMPO}
288
299
  fontSize={34}
289
300
  showLabel
290
- live={{ activePhase: 'concentric', phaseElapsedMs: 900, completed: { eccentric: 3000, pauseBottom: 1000 } }}
301
+ live={{
302
+ activePhase: 'concentric',
303
+ phaseElapsedMs: 900,
304
+ completed: { eccentric: 3000, pauseBottom: 1000 },
305
+ }}
291
306
  />
292
307
  </Section>
293
308
 
@@ -120,12 +120,18 @@ describe('TempoDisplay', () => {
120
120
  it('locks the phases completed earlier in the rep, and resets on the first phase', () => {
121
121
  // Concentric active (3rd phase) → eccentric + pauseBottom are locked done.
122
122
  const mid = render(
123
- <TempoDisplay tempo={[3, 1, 2, 1]} live={{ activePhase: 'concentric', phaseElapsedMs: 800 }} />
123
+ <TempoDisplay
124
+ tempo={[3, 1, 2, 1]}
125
+ live={{ activePhase: 'concentric', phaseElapsedMs: 800 }}
126
+ />
124
127
  )
125
128
  expect(mid.getAllByTestId('tempo-live-done')).toHaveLength(2)
126
129
  // Back to the first phase (next rep) → nothing is locked yet.
127
130
  mid.rerender(
128
- <TempoDisplay tempo={[3, 1, 2, 1]} live={{ activePhase: 'eccentric', phaseElapsedMs: 200 }} />
131
+ <TempoDisplay
132
+ tempo={[3, 1, 2, 1]}
133
+ live={{ activePhase: 'eccentric', phaseElapsedMs: 200 }}
134
+ />
129
135
  )
130
136
  expect(mid.queryByTestId('tempo-live-done')).not.toBeInTheDocument()
131
137
  })
@@ -133,13 +139,21 @@ describe('TempoDisplay', () => {
133
139
  it('colours the TEMPO label live-muted while live', () => {
134
140
  const { getByText, rerender } = render(<TempoDisplay tempo={[3, 1, 1, 0]} />)
135
141
  const restColor = getByText('TEMPO').style.color
136
- rerender(<TempoDisplay tempo={[3, 1, 1, 0]} live={{ activePhase: 'eccentric', phaseElapsedMs: 500 }} />)
142
+ rerender(
143
+ <TempoDisplay
144
+ tempo={[3, 1, 1, 0]}
145
+ live={{ activePhase: 'eccentric', phaseElapsedMs: 500 }}
146
+ />
147
+ )
137
148
  expect(getByText('TEMPO').style.color).not.toBe(restColor)
138
149
  })
139
150
 
140
151
  it('shows upcoming phases as their prescribed time and the active as the live readout', () => {
141
152
  render(
142
- <TempoDisplay tempo={[5, 3, 2, 1]} live={{ activePhase: 'eccentric', phaseElapsedMs: 1000 }} />
153
+ <TempoDisplay
154
+ tempo={[5, 3, 2, 1]}
155
+ live={{ activePhase: 'eccentric', phaseElapsedMs: 1000 }}
156
+ />
143
157
  )
144
158
  // active eccentric: 5s target, 1s in → 4.0 remaining
145
159
  expect(screen.getByText('4.0')).toBeInTheDocument()
@@ -183,7 +183,15 @@ const muscles: TrainingStatusMuscle[] = [
183
183
  const meta: Meta<typeof TrainingStatusPage> = {
184
184
  title: 'Pages/Training Status',
185
185
  component: TrainingStatusPage,
186
- parameters: { layout: 'fullscreen' },
186
+ parameters: {
187
+ layout: 'fullscreen',
188
+ docs: {
189
+ description: {
190
+ component:
191
+ 'Composes **BodyMap** · **BodyMapDetailPanel** · **MesoStatusCard** · **MuscleGroup**.',
192
+ },
193
+ },
194
+ },
187
195
  tags: ['autodocs'],
188
196
  args: { title: 'Training Status', meso, muscles },
189
197
  }
@@ -23,8 +23,11 @@ import {
23
23
  * vertical space as a single — 2x is only forced for the value-height expanded.
24
24
  */
25
25
  const meta: Meta<typeof VelocityStrip> = {
26
- title: 'Workout/DataViz/VelocityStrip/Compact',
26
+ title: 'Custom/Workout/DataViz/VelocityStrip/Compact',
27
27
  component: VelocityStrip,
28
+ parameters: {
29
+ docs: { description: { component: 'Composes **SetBarChart** · **ChartSideRail**.' } },
30
+ },
28
31
  tags: ['autodocs'],
29
32
  }
30
33
  export default meta
@@ -17,9 +17,9 @@ import {
17
17
  * Dual is **not a fourth view**, so its scenario coverage lives in the
18
18
  * per-view groups, where every scenario renders single ABOVE dual on one
19
19
  * dataset:
20
- * [Compact](?path=/docs/workout-dataviz-velocitystrip-compact--docs) ·
21
- * [Expanded](?path=/docs/workout-dataviz-velocitystrip-expanded--docs) ·
22
- * [Hero](?path=/docs/workout-dataviz-velocitystrip-hero--docs).
20
+ * [Compact](?path=/docs/custom-workout-dataviz-velocitystrip-compact--docs) ·
21
+ * [Expanded](?path=/docs/custom-workout-dataviz-velocitystrip-expanded--docs) ·
22
+ * [Hero](?path=/docs/custom-workout-dataviz-velocitystrip-hero--docs).
23
23
  *
24
24
  * This group exists for the two things a pairing cannot carry: the exported
25
25
  * **API** (`DualVelocityStripProps`, in the args table below) and the layout
@@ -37,8 +37,11 @@ import {
37
37
  * not a hardcoded side. Single-slot sets keep using `VelocityStrip`.
38
38
  */
39
39
  const meta: Meta<typeof DualVelocityStrip> = {
40
- title: 'Workout/DataViz/VelocityStrip/Dual',
40
+ title: 'Custom/Workout/DataViz/VelocityStrip/Dual',
41
41
  component: DualVelocityStrip,
42
+ parameters: {
43
+ docs: { description: { component: 'Composes **SetBarChart** · **ChartSideRail**.' } },
44
+ },
42
45
  tags: ['autodocs'],
43
46
  decorators: [wallDecorator],
44
47
  argTypes: {
@@ -32,8 +32,11 @@ import {
32
32
  * meaning.
33
33
  */
34
34
  const meta: Meta<typeof VelocityStrip> = {
35
- title: 'Workout/DataViz/VelocityStrip/Expanded',
35
+ title: 'Custom/Workout/DataViz/VelocityStrip/Expanded',
36
36
  component: VelocityStrip,
37
+ parameters: {
38
+ docs: { description: { component: 'Composes **SetBarChart** · **ChartSideRail**.' } },
39
+ },
37
40
  tags: ['autodocs'],
38
41
  }
39
42
  export default meta
@@ -31,8 +31,11 @@ import {
31
31
  * sets and do not reflow as each rep lands.
32
32
  */
33
33
  const meta: Meta<typeof VelocityStrip> = {
34
- title: 'Workout/DataViz/VelocityStrip/Hero',
34
+ title: 'Custom/Workout/DataViz/VelocityStrip/Hero',
35
35
  component: VelocityStrip,
36
+ parameters: {
37
+ docs: { description: { component: 'Composes **SetBarChart** · **ChartSideRail**.' } },
38
+ },
36
39
  tags: ['autodocs'],
37
40
  }
38
41
  export default meta
@@ -16,14 +16,15 @@ import {
16
16
  REP_SET_LAGGING,
17
17
  type StripView,
18
18
  } from './velocity-story-kit'
19
+ import { Surface } from '../../ui/surface'
19
20
 
20
21
  /**
21
22
  * Per-rep velocity strip.
22
23
  *
23
24
  * Three views, each with its own story group:
24
- * - **[Compact](?path=/docs/workout-dataviz-velocitystrip-compact--docs)** — the flat resting strip
25
- * - **[Expanded](?path=/docs/workout-dataviz-velocitystrip-expanded--docs)** — the value-height chart
26
- * - **[Hero](?path=/docs/workout-dataviz-velocitystrip-hero--docs)** — the across-the-room wall treatment
25
+ * - **[Compact](?path=/docs/custom-workout-dataviz-velocitystrip-compact--docs)** — the flat resting strip
26
+ * - **[Expanded](?path=/docs/custom-workout-dataviz-velocitystrip-expanded--docs)** — the value-height chart
27
+ * - **[Hero](?path=/docs/custom-workout-dataviz-velocitystrip-hero--docs)** — the across-the-room wall treatment
27
28
  *
28
29
  * Dual is NOT a fourth view. It is the same strip when the exercise used two
29
30
  * Voltras, so every group pairs single above dual on one dataset.
@@ -39,8 +40,13 @@ import {
39
40
  * live in the three group files above.
40
41
  */
41
42
  const meta: Meta<typeof VelocityStrip> = {
42
- title: 'Workout/DataViz/VelocityStrip',
43
+ title: 'Custom/Workout/DataViz/VelocityStrip',
43
44
  component: VelocityStrip,
45
+ parameters: {
46
+ docs: {
47
+ description: { component: 'Composes **SetBarChart** · **ChartSideRail** · **SessionRail**.' },
48
+ },
49
+ },
44
50
  tags: ['autodocs'],
45
51
  argTypes: {
46
52
  variant: {
@@ -98,9 +104,9 @@ export const Playground: Story = {
98
104
  },
99
105
  decorators: [
100
106
  (Story) => (
101
- <View style={{ width: 300, padding: 16, backgroundColor: SURFACE_BG }}>
107
+ <Surface level="base" style={{ width: 300, padding: 16 }}>
102
108
  <Story />
103
- </View>
109
+ </Surface>
104
110
  ),
105
111
  ],
106
112
  }
@@ -1252,6 +1252,9 @@ export function VelocityStrip({
1252
1252
  label={label}
1253
1253
  showValueLabels
1254
1254
  formatValue={formatVelocity}
1255
+ // Only the diverging dual's composed wings opt in (TD-07.10) — the standalone single
1256
+ // hero is unchanged, per columnSlots being the dual-only signal (see the comment above).
1257
+ flipEdgeLabel={columnSlots != null}
1255
1258
  renderReference={(g) => velocityReferenceOverlay(g, lossBandsOn)}
1256
1259
  hideBaseline
1257
1260
  testID="velocity-strip-hero"
@@ -1,12 +1,10 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import { View } from 'react-native'
3
3
  import { VolumeLandmarkBar } from './VolumeLandmarkBar'
4
- import { getSemanticColors } from '../../../theme/tokens/semantic'
5
-
6
- const t = getSemanticColors('dark')
4
+ import { Surface } from '../../ui/surface'
7
5
 
8
6
  const meta: Meta<typeof VolumeLandmarkBar> = {
9
- title: 'Workout/DataViz/VolumeLandmarkBar',
7
+ title: 'Custom/Workout/DataViz/VolumeLandmarkBar',
10
8
  component: VolumeLandmarkBar,
11
9
  tags: ['autodocs'],
12
10
  parameters: {
@@ -15,7 +13,8 @@ const meta: Meta<typeof VolumeLandmarkBar> = {
15
13
  component:
16
14
  'Horizontal weekly-volume bar with MEV / MAV / MRV landmark ticks, a HEAT-scale ' +
17
15
  'fill positioned against the MAV target, and a % readout. Reuses the canonical ' +
18
- 'BodyMap volume heat scale (under → maintenance → productive → approaching → over).',
16
+ 'BodyMap volume heat scale (under → maintenance → productive → approaching → over).' +
17
+ ' Composes **ZoneTrack** · **DataRow**.',
19
18
  },
20
19
  },
21
20
  },
@@ -31,9 +30,9 @@ const meta: Meta<typeof VolumeLandmarkBar> = {
31
30
  },
32
31
  decorators: [
33
32
  (Story) => (
34
- <View style={{ padding: 24, paddingBottom: 40, backgroundColor: t['background-base'] }}>
33
+ <Surface level="background" style={{ padding: 24, paddingBottom: 40 }}>
35
34
  <Story />
36
- </View>
35
+ </Surface>
37
36
  ),
38
37
  ],
39
38
  }