@titan-design/react-ui 0.12.1 → 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 +1319 -216
  7. package/dist/index.d.ts +1319 -216
  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 +195 -134
  21. package/dist/theme/index.d.ts +195 -134
  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 +73 -5
  31. package/dist/theme/tokens.d.ts +73 -5
  32. package/dist/theme/tokens.js +55 -7
  33. package/dist/theme/tokens.js.map +1 -1
  34. package/dist/theme/tokens.mjs +55 -8
  35. package/dist/theme/tokens.mjs.map +1 -1
  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 +1 -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 +11 -6
  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 +89 -26
  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 +23 -21
  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 +1 -3
  480. package/src/theme/tokens/primitives.test.ts +15 -7
  481. package/src/theme/tokens/primitives.ts +65 -33
  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
package/dist/pages.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { createContext, useState, useMemo, useEffect, Fragment as Fragment$1, useSyncExternalStore, useContext, useCallback } from 'react';
1
+ import { createContext, useState, useMemo, useEffect, Fragment, useContext, useCallback } from 'react';
2
2
  import { Easing, Platform, View, Text, TextInput, Pressable, Animated, ScrollView } from 'react-native';
3
- import { Fragment, jsx as jsx$1, jsxs as jsxs$1 } from 'react/jsx-runtime';
3
+ import { Fragment as Fragment$1, jsx as jsx$1, jsxs as jsxs$1 } from 'react/jsx-runtime';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
 
@@ -9,6 +9,7 @@ import { twMerge } from 'tailwind-merge';
9
9
  // src/theme/tokens/primitives.ts
10
10
  var primitiveColors = {
11
11
  white: "#FFFFFF"};
12
+ var alertRedVivid = "#FF4757";
12
13
  var greyRamp = {
13
14
  50: "#F9F6F3",
14
15
  // L*97.0 W6
@@ -159,11 +160,7 @@ var WORKOUT_TOKENS = {
159
160
  intensity: {
160
161
  // matches status-error
161
162
  over2: primitiveRamps.red[700],
162
- over3: primitiveRamps.red[800]},
163
- // Placeholder strip
164
- placeholder: {
165
- fill: "#3A3A3A"
166
- }};
163
+ over3: primitiveRamps.red[800]}};
167
164
 
168
165
  // src/theme/tokens/semantic.ts
169
166
  var semanticColorsLight = {
@@ -172,12 +169,16 @@ var semanticColorsLight = {
172
169
  "brand-primary-light": primitiveRamps.orange[300],
173
170
  "brand-primary-dark": primitiveRamps.orange[500],
174
171
  "brand-primary-subtle": "rgba(255, 121, 0, 0.08)",
172
+ "brand-primary-muted": "rgba(255, 121, 0, 0.30)",
173
+ "brand-primary-strong": "rgba(255, 121, 0, 0.50)",
175
174
  "brand-primary-hover": primitiveRamps.orange[500],
176
175
  "brand-primary-active": primitiveRamps.orange[600],
177
176
  "brand-secondary": primitiveRamps.cyan[600],
178
177
  "brand-secondary-light": primitiveRamps.cyan[500],
179
178
  "brand-secondary-dark": primitiveRamps.cyan[700],
180
179
  "brand-secondary-subtle": "rgba(48, 123, 155, 0.08)",
180
+ "brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
181
+ "brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
181
182
  "brand-secondary-hover": primitiveRamps.cyan[700],
182
183
  "brand-secondary-active": primitiveRamps.cyan[800],
183
184
  // Text on brand backgrounds (on-*)
@@ -188,6 +189,8 @@ var semanticColorsLight = {
188
189
  "status-success-light": primitiveRamps.green[200],
189
190
  "status-success-dark": primitiveRamps.green[600],
190
191
  "status-success-subtle": primitiveRamps.green[50],
192
+ "status-success-muted": "rgba(46, 213, 115, 0.30)",
193
+ "status-success-strong": "rgba(46, 213, 115, 0.50)",
191
194
  // Live-session accent — its OWN role, decoupled from success so the two can diverge
192
195
  "status-live": primitiveRamps.green[300],
193
196
  "status-live-muted": primitiveRamps.green[500],
@@ -195,19 +198,27 @@ var semanticColorsLight = {
195
198
  "status-error-light": primitiveRamps.red[500],
196
199
  "status-error-dark": primitiveRamps.red[700],
197
200
  "status-error-subtle": primitiveRamps.red[50],
198
- "status-error-vivid": primitiveRamps.red[600],
199
- // vivid alert red
201
+ "status-error-muted": "rgba(209, 67, 67, 0.30)",
202
+ "status-error-strong": "rgba(209, 67, 67, 0.50)",
203
+ "status-error-vivid": alertRedVivid,
204
+ // NOT red[600], that is status-error
200
205
  "status-error-vivid-light": primitiveRamps.red[500],
201
206
  "status-error-vivid-dark": primitiveRamps.red[700],
202
207
  "status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
208
+ "status-error-vivid-muted": "rgba(255, 71, 87, 0.30)",
209
+ "status-error-vivid-strong": "rgba(255, 71, 87, 0.50)",
203
210
  "status-warning": primitiveRamps.amber[300],
204
211
  "status-warning-light": primitiveRamps.amber[200],
205
212
  "status-warning-dark": primitiveRamps.amber[500],
206
213
  "status-warning-subtle": primitiveRamps.amber[50],
214
+ "status-warning-muted": "rgba(249, 180, 21, 0.30)",
215
+ "status-warning-strong": "rgba(249, 180, 21, 0.50)",
207
216
  "status-info": primitiveRamps.blue[500],
208
217
  "status-info-light": primitiveRamps.blue[300],
209
218
  "status-info-dark": primitiveRamps.blue[600],
210
219
  "status-info-subtle": primitiveRamps.blue[50],
220
+ "status-info-muted": "rgba(33, 150, 243, 0.30)",
221
+ "status-info-strong": "rgba(33, 150, 243, 0.50)",
211
222
  // Text on status backgrounds (on-status-*)
212
223
  "on-status-success": primitiveColors.white,
213
224
  "on-status-error": primitiveColors.white,
@@ -302,7 +313,7 @@ var semanticColorsLight = {
302
313
  "interactive-disabled": "rgba(55, 65, 81, 0.12)",
303
314
  "interactive-disabled-text": "rgba(55, 65, 81, 0.26)",
304
315
  // Divider
305
- "divider": "#E8E9EB",
316
+ divider: "#E8E9EB",
306
317
  // Avatar default
307
318
  "avatar-background": greyRamp[600],
308
319
  "avatar-text": primitiveColors.white
@@ -313,12 +324,16 @@ var semanticColorsDark = {
313
324
  "brand-primary-light": primitiveRamps.orange[300],
314
325
  "brand-primary-dark": primitiveRamps.orange[500],
315
326
  "brand-primary-subtle": "rgba(255, 121, 0, 0.12)",
327
+ "brand-primary-muted": "rgba(255, 121, 0, 0.30)",
328
+ "brand-primary-strong": "rgba(255, 121, 0, 0.50)",
316
329
  "brand-primary-hover": primitiveRamps.orange[300],
317
330
  "brand-primary-active": primitiveRamps.orange[200],
318
331
  "brand-secondary": primitiveRamps.cyan[600],
319
332
  "brand-secondary-light": primitiveRamps.cyan[500],
320
333
  "brand-secondary-dark": primitiveRamps.cyan[700],
321
334
  "brand-secondary-subtle": "rgba(48, 123, 155, 0.12)",
335
+ "brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
336
+ "brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
322
337
  "brand-secondary-hover": primitiveRamps.cyan[500],
323
338
  "brand-secondary-active": primitiveRamps.cyan[400],
324
339
  // Text on brand backgrounds
@@ -329,6 +344,8 @@ var semanticColorsDark = {
329
344
  "status-success-light": primitiveRamps.green[200],
330
345
  "status-success-dark": primitiveRamps.green[600],
331
346
  "status-success-subtle": "rgba(46, 213, 115, 0.12)",
347
+ "status-success-muted": "rgba(46, 213, 115, 0.30)",
348
+ "status-success-strong": "rgba(46, 213, 115, 0.50)",
332
349
  // Live-session accent — its OWN role, decoupled from success so the two can diverge
333
350
  "status-live": primitiveRamps.green[300],
334
351
  "status-live-muted": primitiveRamps.green[500],
@@ -336,18 +353,26 @@ var semanticColorsDark = {
336
353
  "status-error-light": primitiveRamps.red[500],
337
354
  "status-error-dark": primitiveRamps.red[700],
338
355
  "status-error-subtle": "rgba(209, 67, 67, 0.12)",
339
- "status-error-vivid": primitiveRamps.red[600],
356
+ "status-error-muted": "rgba(209, 67, 67, 0.30)",
357
+ "status-error-strong": "rgba(209, 67, 67, 0.50)",
358
+ "status-error-vivid": alertRedVivid,
340
359
  "status-error-vivid-light": primitiveRamps.red[500],
341
360
  "status-error-vivid-dark": primitiveRamps.red[700],
342
361
  "status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
362
+ "status-error-vivid-muted": "rgba(255, 71, 87, 0.30)",
363
+ "status-error-vivid-strong": "rgba(255, 71, 87, 0.50)",
343
364
  "status-warning": primitiveRamps.amber[300],
344
365
  "status-warning-light": primitiveRamps.amber[200],
345
366
  "status-warning-dark": primitiveRamps.amber[500],
346
367
  "status-warning-subtle": "rgba(249, 180, 21, 0.12)",
368
+ "status-warning-muted": "rgba(249, 180, 21, 0.30)",
369
+ "status-warning-strong": "rgba(249, 180, 21, 0.50)",
347
370
  "status-info": primitiveRamps.blue[500],
348
371
  "status-info-light": primitiveRamps.blue[300],
349
372
  "status-info-dark": primitiveRamps.blue[600],
350
373
  "status-info-subtle": "rgba(33, 150, 243, 0.12)",
374
+ "status-info-muted": "rgba(33, 150, 243, 0.30)",
375
+ "status-info-strong": "rgba(33, 150, 243, 0.50)",
351
376
  // Text on status backgrounds
352
377
  "on-status-success": primitiveColors.white,
353
378
  "on-status-error": primitiveColors.white,
@@ -487,7 +512,7 @@ var semanticColorsDark = {
487
512
  "interactive-disabled": "rgba(255, 255, 255, 0.12)",
488
513
  "interactive-disabled-text": "rgba(255, 255, 255, 0.26)",
489
514
  // Divider
490
- "divider": "rgba(255, 255, 255, 0.09)",
515
+ divider: "rgba(255, 255, 255, 0.09)",
491
516
  // Avatar default
492
517
  "avatar-background": greyRamp[700],
493
518
  "avatar-text": primitiveColors.white
@@ -513,79 +538,6 @@ function hexToRgb(hex) {
513
538
  }
514
539
  return { r, g, b };
515
540
  }
516
- function rgbToHsv(r, g, b) {
517
- const rNorm = r / 255;
518
- const gNorm = g / 255;
519
- const bNorm = b / 255;
520
- const max = Math.max(rNorm, gNorm, bNorm);
521
- const min = Math.min(rNorm, gNorm, bNorm);
522
- const delta = max - min;
523
- const v = max;
524
- const s = max === 0 ? 0 : delta / max;
525
- let h = 0;
526
- if (delta !== 0) {
527
- if (max === rNorm) {
528
- h = 60 * ((gNorm - bNorm) / delta % 6);
529
- } else if (max === gNorm) {
530
- h = 60 * ((bNorm - rNorm) / delta + 2);
531
- } else {
532
- h = 60 * ((rNorm - gNorm) / delta + 4);
533
- }
534
- }
535
- if (h < 0) h += 360;
536
- return { h, s, v };
537
- }
538
- function hsvToRgb(h, s, v) {
539
- const c2 = v * s;
540
- const x = c2 * (1 - Math.abs(h / 60 % 2 - 1));
541
- const m = v - c2;
542
- let rPrime, gPrime, bPrime;
543
- if (h >= 0 && h < 60) {
544
- rPrime = c2;
545
- gPrime = x;
546
- bPrime = 0;
547
- } else if (h >= 60 && h < 120) {
548
- rPrime = x;
549
- gPrime = c2;
550
- bPrime = 0;
551
- } else if (h >= 120 && h < 180) {
552
- rPrime = 0;
553
- gPrime = c2;
554
- bPrime = x;
555
- } else if (h >= 180 && h < 240) {
556
- rPrime = 0;
557
- gPrime = x;
558
- bPrime = c2;
559
- } else if (h >= 240 && h < 300) {
560
- rPrime = x;
561
- gPrime = 0;
562
- bPrime = c2;
563
- } else {
564
- rPrime = c2;
565
- gPrime = 0;
566
- bPrime = x;
567
- }
568
- return {
569
- r: Math.round((rPrime + m) * 255),
570
- g: Math.round((gPrime + m) * 255),
571
- b: Math.round((bPrime + m) * 255)
572
- };
573
- }
574
- function rgbToHex(r, g, b) {
575
- const toHex = (n) => {
576
- const clamped = Math.max(0, Math.min(255, Math.round(n)));
577
- return clamped.toString(16).padStart(2, "0");
578
- };
579
- return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
580
- }
581
- function lighten(hex, amount = 0.1) {
582
- const rgb = hexToRgb(hex);
583
- if (!rgb) return hex;
584
- const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
585
- const newV = Math.min(1, hsv.v + amount);
586
- const newRgb = hsvToRgb(hsv.h, hsv.s, newV);
587
- return rgbToHex(newRgb.r, newRgb.g, newRgb.b);
588
- }
589
541
 
590
542
  // src/utils/colors.ts
591
543
  function alpha(color, opacity) {
@@ -632,6 +584,17 @@ function formatVelocity(velocity) {
632
584
  function roundTempo(tempo) {
633
585
  return tempo.map((v) => Math.round(v * 10) / 10);
634
586
  }
587
+ function formatRepsRange(repsLow, repsHigh) {
588
+ if (repsLow != null && repsHigh != null) {
589
+ return repsLow === repsHigh ? `${repsLow}` : `${repsLow}\u2013${repsHigh}`;
590
+ }
591
+ if (repsLow != null) return `${repsLow}`;
592
+ if (repsHigh != null) return `${repsHigh}`;
593
+ return null;
594
+ }
595
+
596
+ // src/theme/materials.ts
597
+ var c = getSemanticColors("dark");
635
598
  function parseHex(hex) {
636
599
  const h = hex.replace("#", "");
637
600
  const full = h.length === 3 ? h.split("").map((ch) => ch + ch).join("") : h;
@@ -655,12 +618,20 @@ function grainForTone(baseColor) {
655
618
  const op = grainOpacityForTone(baseColor).toFixed(3);
656
619
  return `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='${op}'/%3E%3C/svg%3E")`;
657
620
  }
621
+ function insetWell(tone = c["surface-input"]) {
622
+ return {
623
+ backgroundColor: tone,
624
+ boxShadow: "inset 0 2px 6px rgba(0,0,0,0.55), inset 0 -1px 0 rgba(255,255,255,0.12)"
625
+ };
626
+ }
658
627
  function barPaper(color, flip = false) {
659
628
  return {
660
629
  backgroundImage: grainForTone(color),
661
630
  boxShadow: flip ? "0 -6px 16px rgba(0,0,0,0.45)" : "inset 0 1.5px 0 rgba(255,255,255,0.22), 0 6px 16px rgba(0,0,0,0.45)"
662
631
  };
663
632
  }
633
+
634
+ // src/theme/surface-planes.ts
664
635
  var SURFACE_LEVEL_TOKEN = {
665
636
  frame: "background-frame",
666
637
  background: "background-base",
@@ -669,6 +640,30 @@ var SURFACE_LEVEL_TOKEN = {
669
640
  raised: "surface-raised",
670
641
  overlay: "surface-overlay"
671
642
  };
643
+ var PLANE_ORDER = [
644
+ "frame",
645
+ "background",
646
+ "base",
647
+ "elevated",
648
+ "raised",
649
+ "overlay"
650
+ ];
651
+ function surfaceBackground(level, mode) {
652
+ return getSemanticColors(mode)[SURFACE_LEVEL_TOKEN[level]];
653
+ }
654
+ function stepPlane(from, delta) {
655
+ const index = PLANE_ORDER.indexOf(from);
656
+ const clamped = Math.min(PLANE_ORDER.length - 1, Math.max(0, index + delta));
657
+ return PLANE_ORDER[clamped];
658
+ }
659
+ function pressedLevel(parent) {
660
+ return stepPlane(parent, -1);
661
+ }
662
+ function raisedLevel(parent, steps) {
663
+ return stepPlane(parent, Math.max(0, steps));
664
+ }
665
+
666
+ // src/components/ui/surface/SurfaceContext.ts
672
667
  var ON_SURFACE_TOKEN = {
673
668
  primary: "text-primary",
674
669
  secondary: "text-secondary",
@@ -685,9 +680,6 @@ function useSurfaceMode() {
685
680
  function useOnSurfaceColor(role = "primary") {
686
681
  return getSemanticColors(useSurfaceMode())[ON_SURFACE_TOKEN[role]];
687
682
  }
688
- function surfaceBackground(level, mode) {
689
- return getSemanticColors(mode)[SURFACE_LEVEL_TOKEN[level]];
690
- }
691
683
  var ANIMATION_EASING = Easing.bezier(0.22, 1, 0.36, 1);
692
684
  var PEAK_OVERSHOOT = 1.12;
693
685
  function getReducedMotionPreference() {
@@ -761,14 +753,14 @@ var jsx = wrapJsx(jsx$1);
761
753
  var jsxs = wrapJsx(jsxs$1);
762
754
 
763
755
  // src/components/custom/charts/SetBarChart.tsx
764
- function mixHex(a, b, t12) {
756
+ function mixHex(a, b, t7) {
765
757
  const parse = (h) => {
766
758
  const s = h.replace("#", "");
767
759
  return [parseInt(s.slice(0, 2), 16), parseInt(s.slice(2, 4), 16), parseInt(s.slice(4, 6), 16)];
768
760
  };
769
761
  const [ar, ag, ab] = parse(a);
770
762
  const [br, bg, bb] = parse(b);
771
- const ch = (x, y) => Math.round(x + (y - x) * t12).toString(16).padStart(2, "0");
763
+ const ch = (x, y) => Math.round(x + (y - x) * t7).toString(16).padStart(2, "0");
772
764
  return `#${ch(ar, br)}${ch(ag, bg)}${ch(ab, bb)}`;
773
765
  }
774
766
  var VARIABLE_FILL = primitiveRamps.cyan[900];
@@ -781,6 +773,13 @@ function scaleDenominator(scale, maxValue) {
781
773
  function valueLabelFontSize(height) {
782
774
  return Math.round(Math.max(8, Math.min(12, height * 0.11)));
783
775
  }
776
+ var LABEL_GLYPH_WIDTH_RATIO = 0.62;
777
+ function estimateValueLabelWidth(text, fontSize) {
778
+ return text.length * fontSize * LABEL_GLYPH_WIDTH_RATIO;
779
+ }
780
+ function shouldFlipEdgeLabel(roomPx, labelWidthPx) {
781
+ return labelWidthPx / 2 > roomPx;
782
+ }
784
783
  var SET_BAR_DEFAULT_HEIGHT = 220;
785
784
  var LABEL_ROW_HEIGHT = 16;
786
785
  var LABEL_GAP = 3;
@@ -824,6 +823,7 @@ function SetBarChart({
824
823
  flat = false,
825
824
  showValueLabels: showValueLabelsProp = false,
826
825
  formatValue: formatValue2 = String,
826
+ flipEdgeLabel = false,
827
827
  todoVariant = "solid",
828
828
  minColumns,
829
829
  renderReference,
@@ -939,6 +939,12 @@ function SetBarChart({
939
939
  }) : isLive ? liveGrowth.interpolate({ inputRange: [0, 1], outputRange: [0, barHeight(value)] }) : barHeight(value);
940
940
  const ownLabel = showValueLabels && !renderBarOverlay && showBarLabel(repIndex);
941
941
  const labelBottom = (expandProgress ? valueBarHeight(best) : barHeight(best)) + LABEL_GAP;
942
+ const isLastCell = i === cells.length - 1;
943
+ const labelText = formatValue2(value);
944
+ const flipLabel = flipEdgeLabel && isLastCell && shouldFlipEdgeLabel(
945
+ barWidth / 2,
946
+ estimateValueLabelWidth(labelText, valueLabelFontSize(height))
947
+ );
942
948
  return /* @__PURE__ */ jsxs(View, { accessibilityElementsHidden: renderBarOverlay == null, style: column, children: [
943
949
  ownLabel && // All labels pin to one aligned row JUST ABOVE THE PEAK BAR (not the container top),
944
950
  // in the muted on-surface-secondary tone — so the row hugs the bars, no floating void.
@@ -948,9 +954,8 @@ function SetBarChart({
948
954
  style: {
949
955
  position: "absolute",
950
956
  bottom: labelBottom,
951
- left: 0,
952
- right: 0,
953
- alignItems: "center",
957
+ ...flipLabel ? { right: 0 } : { left: 0, right: 0 },
958
+ alignItems: flipLabel ? "flex-end" : "center",
954
959
  ...expandProgress ? { opacity: expandProgress } : null
955
960
  },
956
961
  pointerEvents: "none",
@@ -960,7 +965,7 @@ function SetBarChart({
960
965
  className: "text-text-secondary",
961
966
  style: [{ fontSize: valueLabelFontSize(height), fontWeight: "700" }, flipStyle],
962
967
  testID: `${testIDPrefix}-label-${repIndex}`,
963
- children: formatValue2(value)
968
+ children: labelText
964
969
  }
965
970
  )
966
971
  }
@@ -1314,7 +1319,7 @@ function VelocityLossBands({
1314
1319
  },
1315
1320
  children: [
1316
1321
  /* @__PURE__ */ jsx(View, { style: { flex: 9, borderTopWidth: 1, borderStyle: "dashed", borderColor: color } }),
1317
- showLabels ? /* @__PURE__ */ jsxs(Fragment, { children: [
1322
+ showLabels ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
1318
1323
  /* @__PURE__ */ jsx(
1319
1324
  Text,
1320
1325
  {
@@ -1352,7 +1357,7 @@ function VelocityLossBands({
1352
1357
  }
1353
1358
  function velocityReferenceOverlay(g, showLossBands) {
1354
1359
  const referencePx = g.best > 0 && g.scaleDenom > 0 ? Math.min(g.plotHeight, g.yOf(g.best)) : 0;
1355
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1360
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1356
1361
  showLossBands && /* @__PURE__ */ jsx(
1357
1362
  VelocityLossBands,
1358
1363
  {
@@ -1455,6 +1460,7 @@ function VelocityStrip({
1455
1460
  label,
1456
1461
  showValueLabels: true,
1457
1462
  formatValue: formatVelocity,
1463
+ flipEdgeLabel: columnSlots != null,
1458
1464
  renderReference: (g) => velocityReferenceOverlay(g, lossBandsOn),
1459
1465
  hideBaseline: true,
1460
1466
  testID: "velocity-strip-hero",
@@ -1534,7 +1540,7 @@ function VelocityStrip({
1534
1540
  leadingGap: sl.leadingGap
1535
1541
  })) : doneVelocities.map((v) => ({ kind: "rep", value: v }));
1536
1542
  const needsBarOverlay = showNumbers || onRepPress != null;
1537
- const renderFramedBarOverlay = needsBarOverlay ? (repIndex, value) => /* @__PURE__ */ jsxs(Fragment, { children: [
1543
+ const renderFramedBarOverlay = needsBarOverlay ? (repIndex, value) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
1538
1544
  showNumbers && /* @__PURE__ */ jsx(
1539
1545
  Animated.View,
1540
1546
  {
@@ -1659,8 +1665,12 @@ function VelocityStrip({
1659
1665
  function cn(...inputs) {
1660
1666
  return twMerge(clsx(inputs));
1661
1667
  }
1668
+ function resolveColor(token, mode = "dark") {
1669
+ return Platform.OS === "web" ? `var(--color-${token})` : getSemanticColors(mode)[token];
1670
+ }
1662
1671
 
1663
1672
  // src/components/custom/Workout/PlaceholderStrip.tsx
1673
+ var RAIL_TOKEN = "border-prominent";
1664
1674
  function SingleStrip({
1665
1675
  width,
1666
1676
  className,
@@ -1673,7 +1683,7 @@ function SingleStrip({
1673
1683
  style: [
1674
1684
  {
1675
1685
  height: 3,
1676
- backgroundColor: WORKOUT_TOKENS.placeholder.fill,
1686
+ backgroundColor: resolveColor(RAIL_TOKEN),
1677
1687
  borderRadius: 2,
1678
1688
  opacity: 0.5
1679
1689
  },
@@ -1710,7 +1720,7 @@ function SegmentedStrip({
1710
1720
  style: {
1711
1721
  flex: 1,
1712
1722
  height: 3,
1713
- backgroundColor: WORKOUT_TOKENS.placeholder.fill,
1723
+ backgroundColor: resolveColor(RAIL_TOKEN),
1714
1724
  borderRadius: 1,
1715
1725
  minWidth: 4
1716
1726
  },
@@ -1722,11 +1732,7 @@ function SegmentedStrip({
1722
1732
  }
1723
1733
  );
1724
1734
  }
1725
- function PlaceholderStrip({
1726
- mode = "single",
1727
- segments,
1728
- ...props
1729
- }) {
1735
+ function PlaceholderStrip({ mode = "single", segments, ...props }) {
1730
1736
  if (mode === "segmented") {
1731
1737
  return /* @__PURE__ */ jsx(SegmentedStrip, { segments, ...props });
1732
1738
  }
@@ -1885,9 +1891,98 @@ function BaseBadge({
1885
1891
  }
1886
1892
  return badge;
1887
1893
  }
1894
+ var variantStyles = {
1895
+ h1: "font-heading text-5xl font-bold leading-tight",
1896
+ h2: "font-heading text-4xl font-bold leading-tight",
1897
+ h3: "font-heading text-3xl font-bold leading-tight",
1898
+ h4: "font-heading text-2xl font-bold leading-tight",
1899
+ h5: "font-heading text-xl font-semibold leading-tight",
1900
+ h6: "font-heading text-lg font-semibold leading-tight",
1901
+ body1: "font-body text-base font-normal leading-normal",
1902
+ body2: "font-body text-sm font-normal leading-normal",
1903
+ subtitle1: "font-body text-base font-medium leading-relaxed",
1904
+ subtitle2: "font-body text-sm font-medium leading-normal",
1905
+ caption: "font-body text-xs font-normal leading-loose",
1906
+ overline: "font-body text-xs font-semibold uppercase tracking-widest leading-relaxed",
1907
+ button: "font-sans text-sm font-semibold leading-relaxed",
1908
+ // Monospace technical readouts (clocks, ids, metrics) and their all-caps label form.
1909
+ mono: "font-mono text-xs font-normal leading-normal",
1910
+ monoLabel: "font-mono text-xs font-bold uppercase tracking-wide leading-normal",
1911
+ // The sans (Inter) label pair: 10px for dense table/column headers, 12px bold for
1912
+ // badge and row labels. `overline` is the 12px font-body form of the same idea.
1913
+ microLabel: "font-sans text-2xs font-semibold uppercase tracking-widest leading-normal",
1914
+ boldLabel: "font-sans text-xs font-bold leading-normal"
1915
+ };
1916
+ var colorStyles = {
1917
+ primary: "text-text-primary",
1918
+ secondary: "text-text-secondary",
1919
+ tertiary: "text-text-tertiary",
1920
+ disabled: "text-text-disabled",
1921
+ inverse: "text-text-inverse",
1922
+ success: "text-status-success",
1923
+ error: "text-status-error",
1924
+ warning: "text-status-warning",
1925
+ info: "text-status-info",
1926
+ inherit: ""
1927
+ // No color class, inherit from parent
1928
+ };
1929
+ var alignStyles = {
1930
+ left: "text-left",
1931
+ center: "text-center",
1932
+ right: "text-right",
1933
+ justify: "text-justify"
1934
+ };
1935
+ var headingVariants = ["h1", "h2", "h3", "h4", "h5", "h6"];
1936
+ var marginBottomStyles = {
1937
+ none: "",
1938
+ sm: "mb-1",
1939
+ md: "mb-2",
1940
+ lg: "mb-4"
1941
+ };
1942
+ function Typography({
1943
+ variant = "body1",
1944
+ color = "primary",
1945
+ align,
1946
+ truncate = false,
1947
+ noWrap = false,
1948
+ // deprecated, kept for backward compatibility
1949
+ marginBottom,
1950
+ gutterBottom = false,
1951
+ // deprecated, kept for backward compatibility
1952
+ maxLines,
1953
+ className,
1954
+ children,
1955
+ ...props
1956
+ }) {
1957
+ const isHeading = headingVariants.includes(variant);
1958
+ const shouldTruncate = truncate || noWrap;
1959
+ const mb = marginBottom || (gutterBottom ? "md" : "none");
1960
+ let numLines;
1961
+ if (maxLines) {
1962
+ numLines = maxLines;
1963
+ } else if (shouldTruncate) {
1964
+ numLines = 1;
1965
+ }
1966
+ return /* @__PURE__ */ jsx(
1967
+ Text,
1968
+ {
1969
+ accessibilityRole: isHeading ? "header" : "text",
1970
+ numberOfLines: numLines,
1971
+ className: cn(
1972
+ variantStyles[variant],
1973
+ color !== "inherit" && colorStyles[color],
1974
+ align && alignStyles[align],
1975
+ shouldTruncate && "truncate",
1976
+ marginBottomStyles[mb],
1977
+ className
1978
+ ),
1979
+ ...props,
1980
+ children
1981
+ }
1982
+ );
1983
+ }
1888
1984
 
1889
1985
  // src/components/custom/Workout/PrBadge.tsx
1890
- var BRAND_PRIMARY = getSemanticColors("dark")["brand-primary"];
1891
1986
  var typeLabels = {
1892
1987
  e1rm: "PR e1RM",
1893
1988
  weight: "PR Weight",
@@ -1904,6 +1999,7 @@ function PrBadge({
1904
1999
  ...props
1905
2000
  }) {
1906
2001
  const resolvedLabel = labelProp ?? typeLabels[type];
2002
+ const brandPrimary = resolveColor("brand-primary");
1907
2003
  const [scale] = useState(() => new Animated.Value(animate ? 0.8 : 1));
1908
2004
  const [opacity] = useState(() => new Animated.Value(animate ? 0 : 1));
1909
2005
  useEffect(() => {
@@ -1931,7 +2027,7 @@ function PrBadge({
1931
2027
  accessibilityLabel: `Personal record: ${resolvedLabel}`,
1932
2028
  testID: "pr-badge-star",
1933
2029
  ...props,
1934
- children: /* @__PURE__ */ jsx(StarIcon, { size: 14, color: BRAND_PRIMARY, fill: BRAND_PRIMARY, strokeWidth: 2 })
2030
+ children: /* @__PURE__ */ jsx(StarIcon, { size: 14, color: brandPrimary, fill: brandPrimary, strokeWidth: 2 })
1935
2031
  }
1936
2032
  ) : /* @__PURE__ */ jsx(
1937
2033
  BaseBadge,
@@ -1941,14 +2037,11 @@ function PrBadge({
1941
2037
  accessibilityLabel: `Personal record: ${resolvedLabel}`,
1942
2038
  ...props,
1943
2039
  children: /* @__PURE__ */ jsxs(
1944
- Text,
2040
+ Typography,
1945
2041
  {
1946
- style: {
1947
- fontSize: 12,
1948
- color: BRAND_PRIMARY,
1949
- fontWeight: "700",
1950
- fontFamily: "Inter, sans-serif"
1951
- },
2042
+ variant: "boldLabel",
2043
+ color: "inherit",
2044
+ className: "leading-[normal] text-brand-primary",
1952
2045
  children: [
1953
2046
  "\u2605",
1954
2047
  " ",
@@ -1959,28 +2052,15 @@ function PrBadge({
1959
2052
  }
1960
2053
  );
1961
2054
  if (animate) {
1962
- return /* @__PURE__ */ jsx(
1963
- Animated.View,
1964
- {
1965
- style: { transform: [{ scale }], opacity },
1966
- testID: "pr-badge-animated",
1967
- children: badge
1968
- }
1969
- );
2055
+ return /* @__PURE__ */ jsx(Animated.View, { style: { transform: [{ scale }], opacity }, testID: "pr-badge-animated", children: badge });
1970
2056
  }
1971
2057
  return badge;
1972
2058
  }
1973
- var DARK = getSemanticColors("dark");
1974
- var TEXT_ACTIVE = DARK["text-primary"];
1975
- var TEXT_MUTED = DARK["text-secondary"];
2059
+ var TEXT_ACTIVE = "text-primary";
2060
+ var TEXT_MUTED = "text-secondary";
1976
2061
  var COL = { set: 36, reps: 44, load: 56, rpe: 36 };
1977
- var cellText = { fontFamily: "Inter, sans-serif", fontSize: 13, fontWeight: "600" };
1978
- var typeBadge = {
1979
- fontSize: 10,
1980
- fontWeight: "700",
1981
- fontFamily: "Inter, sans-serif",
1982
- color: WORKOUT_TOKENS.scale.orange,
1983
- backgroundColor: "rgba(255,165,2,0.12)",
2062
+ var CELL_CLASS = "font-semibold leading-[normal]";
2063
+ var typeBadgeStyle = {
1984
2064
  paddingVertical: 1,
1985
2065
  paddingHorizontal: 5,
1986
2066
  borderRadius: 3,
@@ -2041,7 +2121,8 @@ function RowStrip({ set }) {
2041
2121
  }
2042
2122
  function SetRow(set) {
2043
2123
  const live = set.state === "live";
2044
- const valueColor = live ? TEXT_ACTIVE : TEXT_MUTED;
2124
+ const valueColor = resolveColor(live ? TEXT_ACTIVE : TEXT_MUTED);
2125
+ const mutedColor = resolveColor(TEXT_MUTED);
2045
2126
  const rpe = set.state === "todo" ? null : set.rpe;
2046
2127
  return /* @__PURE__ */ jsxs(
2047
2128
  View,
@@ -2051,10 +2132,60 @@ function SetRow(set) {
2051
2132
  testID: "set-row",
2052
2133
  children: [
2053
2134
  /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { justifyContent: "space-between" }, children: [
2054
- /* @__PURE__ */ jsx(Cell, { width: COL.set, testID: "set-row-set-number", children: set.setType ? /* @__PURE__ */ jsx(Text, { style: typeBadge, testID: "set-row-type-badge", children: set.setType }) : /* @__PURE__ */ jsx(Text, { style: { ...cellText, color: valueColor, fontWeight: live ? "700" : "600" }, children: set.setNumber }) }),
2055
- /* @__PURE__ */ jsx(Cell, { width: COL.reps, testID: "set-row-reps", children: /* @__PURE__ */ jsx(Text, { style: { ...cellText, color: valueColor }, children: displayReps(set) }) }),
2056
- /* @__PURE__ */ jsx(Cell, { width: COL.load, testID: "set-row-weight", children: /* @__PURE__ */ jsx(Text, { style: { ...cellText, color: valueColor }, children: roundWeight(displayWeight(set)) }) }),
2057
- /* @__PURE__ */ jsx(Cell, { width: COL.rpe, testID: "set-row-rpe", children: /* @__PURE__ */ jsx(Text, { style: { ...cellText, color: TEXT_MUTED }, children: rpe != null ? roundRpe(rpe) : "\u2014" }) })
2135
+ /* @__PURE__ */ jsx(Cell, { width: COL.set, testID: "set-row-set-number", children: set.setType ? /* @__PURE__ */ jsx(
2136
+ Typography,
2137
+ {
2138
+ variant: "boldLabel",
2139
+ color: "inherit",
2140
+ className: "text-2xs leading-[normal]",
2141
+ style: {
2142
+ ...typeBadgeStyle,
2143
+ color: resolveColor("brand-primary"),
2144
+ backgroundColor: resolveColor("brand-primary-subtle")
2145
+ },
2146
+ testID: "set-row-type-badge",
2147
+ children: set.setType
2148
+ }
2149
+ ) : /* @__PURE__ */ jsx(
2150
+ Typography,
2151
+ {
2152
+ variant: "boldLabel",
2153
+ color: "inherit",
2154
+ className: live ? "font-bold leading-[normal]" : CELL_CLASS,
2155
+ style: { color: valueColor },
2156
+ children: set.setNumber
2157
+ }
2158
+ ) }),
2159
+ /* @__PURE__ */ jsx(Cell, { width: COL.reps, testID: "set-row-reps", children: /* @__PURE__ */ jsx(
2160
+ Typography,
2161
+ {
2162
+ variant: "boldLabel",
2163
+ color: "inherit",
2164
+ className: CELL_CLASS,
2165
+ style: { color: valueColor },
2166
+ children: displayReps(set)
2167
+ }
2168
+ ) }),
2169
+ /* @__PURE__ */ jsx(Cell, { width: COL.load, testID: "set-row-weight", children: /* @__PURE__ */ jsx(
2170
+ Typography,
2171
+ {
2172
+ variant: "boldLabel",
2173
+ color: "inherit",
2174
+ className: CELL_CLASS,
2175
+ style: { color: valueColor },
2176
+ children: roundWeight(displayWeight(set))
2177
+ }
2178
+ ) }),
2179
+ /* @__PURE__ */ jsx(Cell, { width: COL.rpe, testID: "set-row-rpe", children: /* @__PURE__ */ jsx(
2180
+ Typography,
2181
+ {
2182
+ variant: "boldLabel",
2183
+ color: "inherit",
2184
+ className: CELL_CLASS,
2185
+ style: { color: mutedColor },
2186
+ children: rpe != null ? roundRpe(rpe) : "\u2014"
2187
+ }
2188
+ ) })
2058
2189
  ] }),
2059
2190
  /* @__PURE__ */ jsx(View, { style: { marginTop: live ? 6 : 4 }, testID: "set-row-strip", children: /* @__PURE__ */ jsx(RowStrip, { set }) })
2060
2191
  ]
@@ -2062,6 +2193,7 @@ function SetRow(set) {
2062
2193
  );
2063
2194
  }
2064
2195
  var PREV_COLUMN = { label: "PREV", width: void 0 };
2196
+ var COLUMN_LABEL = "leading-[normal]";
2065
2197
  function buildColumns(unit, showPrevious) {
2066
2198
  return [
2067
2199
  { label: "SET", width: 36 },
@@ -2100,20 +2232,7 @@ function SetTableHeader({
2100
2232
  gap: 8
2101
2233
  },
2102
2234
  ...isFlex ? { className: "flex-1" } : {},
2103
- children: /* @__PURE__ */ jsx(
2104
- Text,
2105
- {
2106
- className: "text-text-tertiary",
2107
- style: {
2108
- fontSize: 10,
2109
- fontWeight: "600",
2110
- fontFamily: "Inter, sans-serif",
2111
- textTransform: "uppercase",
2112
- letterSpacing: 0.8
2113
- },
2114
- children: label
2115
- }
2116
- )
2235
+ children: /* @__PURE__ */ jsx(Typography, { variant: "microLabel", color: "tertiary", className: COLUMN_LABEL, children: label })
2117
2236
  },
2118
2237
  label
2119
2238
  );
@@ -2139,7 +2258,6 @@ function MetricCell({ children, color, fontSize = 11 }) {
2139
2258
  }
2140
2259
 
2141
2260
  // src/components/custom/Workout/SetsRepsLoad.tsx
2142
- var t2 = getSemanticColors("dark");
2143
2261
  var TIMES = "\xD7";
2144
2262
  var AT = "@";
2145
2263
  function SetsRepsLoad({
@@ -2151,8 +2269,8 @@ function SetsRepsLoad({
2151
2269
  className,
2152
2270
  ...props
2153
2271
  }) {
2154
- const value = t2["text-primary"];
2155
- const sep = t2["text-tertiary"];
2272
+ const value = useOnSurfaceColor("primary");
2273
+ const sep = useOnSurfaceColor("tertiary");
2156
2274
  return /* @__PURE__ */ jsxs(
2157
2275
  View,
2158
2276
  {
@@ -2172,19 +2290,19 @@ function SetsRepsLoad({
2172
2290
  }
2173
2291
  );
2174
2292
  }
2175
- var t3 = getSemanticColors("dark");
2293
+ var t2 = getSemanticColors("dark");
2176
2294
  var INTER = "Inter, sans-serif";
2177
2295
  var TEXT_TERTIARY = "#6B7280";
2178
- var STATUS_ERROR = t3["status-error"];
2179
- var STATUS_SUCCESS = t3["status-success"];
2180
- var STATUS_WARNING = t3["status-warning"];
2296
+ var STATUS_ERROR = t2["status-error"];
2297
+ var STATUS_SUCCESS = t2["status-success"];
2298
+ var STATUS_WARNING = t2["status-warning"];
2181
2299
  var ON_TARGET_MS = 100;
2182
2300
  function getTempoFillPct(elapsedMs, targetMs) {
2183
2301
  if (!targetMs) return 100;
2184
2302
  return Math.min(100, elapsedMs / targetMs * 100);
2185
2303
  }
2186
2304
  function activeNumberTone(elapsedMs, targetMs) {
2187
- if (targetMs == null) return t3["text-primary"];
2305
+ if (targetMs == null) return t2["text-primary"];
2188
2306
  const remainingMs = targetMs - elapsedMs;
2189
2307
  if (remainingMs > ON_TARGET_MS) return STATUS_WARNING;
2190
2308
  if (remainingMs >= -ON_TARGET_MS) return STATUS_SUCCESS;
@@ -2282,7 +2400,7 @@ function LiveTempoRow({
2282
2400
  readout
2283
2401
  }) {
2284
2402
  const activeIndex = live.activePhase ? LIVE_PHASES.findIndex((p) => p.key === live.activePhase) : -1;
2285
- return /* @__PURE__ */ jsx(Fragment, { children: LIVE_PHASES.map((phase, i) => {
2403
+ return /* @__PURE__ */ jsx(Fragment$1, { children: LIVE_PHASES.map((phase, i) => {
2286
2404
  const status = activeIndex < 0 || i > activeIndex ? "upcoming" : i < activeIndex ? "done" : "active";
2287
2405
  return /* @__PURE__ */ jsxs(View, { style: { flexDirection: "row", alignItems: "center" }, children: [
2288
2406
  i > 0 && /* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
@@ -2336,7 +2454,7 @@ function TempoDisplay({
2336
2454
  style: {
2337
2455
  flexDirection: "row",
2338
2456
  alignItems: "center",
2339
- backgroundColor: t3["surface-raised"],
2457
+ backgroundColor: t2["surface-raised"],
2340
2458
  paddingHorizontal: chromePadX,
2341
2459
  paddingVertical: chromePadY,
2342
2460
  borderRadius: chromeRadius
@@ -2351,7 +2469,7 @@ function TempoDisplay({
2351
2469
  fontSize: labelFont,
2352
2470
  fontWeight: "500",
2353
2471
  // Live-muted green while a rep is running, tertiary at rest.
2354
- color: live ? t3["status-live-muted"] : TEXT_TERTIARY,
2472
+ color: live ? t2["status-live-muted"] : TEXT_TERTIARY,
2355
2473
  letterSpacing: 0.5,
2356
2474
  textTransform: "uppercase",
2357
2475
  marginRight: Math.round(fontSize * 0.5)
@@ -2369,7 +2487,7 @@ function TempoDisplay({
2369
2487
  }
2370
2488
  ) : (
2371
2489
  // Static prescription: the phase-coloured lockup (the same colours the live row rests at).
2372
- /* @__PURE__ */ jsxs(Fragment, { children: [
2490
+ /* @__PURE__ */ jsxs(Fragment$1, { children: [
2373
2491
  /* @__PURE__ */ jsx(TempoValue, { value: eccentric, color: phaseColors.eccentric, fontSize }),
2374
2492
  /* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
2375
2493
  /* @__PURE__ */ jsx(TempoValue, { value: pauseBottom, color: phaseColors.pauseBottom, fontSize }),
@@ -2409,7 +2527,7 @@ function TempoDisplay({
2409
2527
  View,
2410
2528
  {
2411
2529
  style: {
2412
- backgroundColor: t3["surface-overlay"],
2530
+ backgroundColor: t2["surface-overlay"],
2413
2531
  borderRadius: 6,
2414
2532
  paddingVertical: 8,
2415
2533
  paddingHorizontal: 12,
@@ -2462,17 +2580,17 @@ function TempoDisplay({
2462
2580
  }
2463
2581
  );
2464
2582
  }
2465
- var t4 = getSemanticColors("dark");
2466
2583
  var INDICATOR_CONFIG = {
2467
- imbalance: { Icon: ScaleIcon, color: t4["status-error"], label: "Left/right imbalance" },
2468
- overshoot: { Icon: AlertTriangleIcon, color: t4["status-error"], label: "Load overshoot" },
2469
- "velocity-loss": { Icon: TrendingDownIcon, color: t4["status-warning"], label: "Velocity loss" },
2470
- "missed-reps": { Icon: CircleSlashIcon, color: t4["status-warning"], label: "Missed reps" },
2471
- pr: { Icon: AwardIcon, color: t4["status-success"], label: "Personal record" },
2472
- info: { Icon: InfoIcon, color: t4["status-info"], label: "More info" }
2584
+ imbalance: { Icon: ScaleIcon, token: "status-error", label: "Left/right imbalance" },
2585
+ overshoot: { Icon: AlertTriangleIcon, token: "status-error", label: "Load overshoot" },
2586
+ "velocity-loss": { Icon: TrendingDownIcon, token: "status-warning", label: "Velocity loss" },
2587
+ "missed-reps": { Icon: CircleSlashIcon, token: "status-warning", label: "Missed reps" },
2588
+ pr: { Icon: AwardIcon, token: "status-success", label: "Personal record" },
2589
+ info: { Icon: InfoIcon, token: "status-info", label: "More info" }
2473
2590
  };
2474
2591
  function ExerciseIndicator({ kind, onPress, className, ...props }) {
2475
- const { Icon, color, label } = INDICATOR_CONFIG[kind];
2592
+ const { Icon, token, label } = INDICATOR_CONFIG[kind];
2593
+ const color = resolveColor(token);
2476
2594
  const chip = /* @__PURE__ */ jsx(
2477
2595
  View,
2478
2596
  {
@@ -2527,10 +2645,10 @@ function ExerciseHeading({
2527
2645
  testID: "exercise-card-header",
2528
2646
  children: [
2529
2647
  /* @__PURE__ */ jsx(
2530
- Text,
2648
+ Typography,
2531
2649
  {
2532
- className: "text-text-primary",
2533
- style: { fontSize: 14, fontFamily: '"Space Grotesk", sans-serif', fontWeight: "700" },
2650
+ variant: "boldLabel",
2651
+ className: "font-heading text-sm leading-[normal]",
2534
2652
  testID: "exercise-card-name",
2535
2653
  children: name
2536
2654
  }
@@ -2659,12 +2777,12 @@ function SegmentedBar({
2659
2777
 
2660
2778
  // src/components/custom/Workout/SetBar.tsx
2661
2779
  var SET_STRIP_ZONES = {
2662
- slow: primitiveRamps.red[600],
2663
- moderate: primitiveRamps.orange[400],
2664
- fast: primitiveRamps.amber[300],
2665
- fastest: primitiveRamps.green[300]
2780
+ slow: WORKOUT_TOKENS.scale.red,
2781
+ moderate: WORKOUT_TOKENS.scale.orange,
2782
+ fast: WORKOUT_TOKENS.scale.yellow,
2783
+ fastest: WORKOUT_TOKENS.scale.green
2666
2784
  };
2667
- var TODO_COLOR = greyRamp[900];
2785
+ var TODO_COLOR = resolveColor("border-prominent");
2668
2786
  var SET_STRIP_VARIABLE_COLOR = primitiveRamps.cyan[900];
2669
2787
  var NOTCH_GAP = 2;
2670
2788
  var CLUSTER_GAP = 3;
@@ -2778,6 +2896,10 @@ function describeSets(sets) {
2778
2896
  const upcoming = sets.filter((s) => setCategory(s) === "upcoming").length;
2779
2897
  return `Set progress: ${done} done, ${active} in progress, ${upcoming} upcoming`;
2780
2898
  }
2899
+ function repsRangeLabel(set) {
2900
+ if (set.status !== "todo" && set.status !== "active") return null;
2901
+ return formatRepsRange(set.repsLow, set.repsHigh);
2902
+ }
2781
2903
  function SetStrip({ sets, height = 8, className, ...props }) {
2782
2904
  return /* @__PURE__ */ jsx(
2783
2905
  View,
@@ -2788,7 +2910,22 @@ function SetStrip({ sets, height = 8, className, ...props }) {
2788
2910
  accessibilityLabel: describeSets(sets),
2789
2911
  testID: "set-strip",
2790
2912
  ...props,
2791
- children: sets.map((set, i) => /* @__PURE__ */ jsx(SetBar, { set, height }, i))
2913
+ children: sets.map((set, i) => {
2914
+ const label = repsRangeLabel(set);
2915
+ if (label == null) return /* @__PURE__ */ jsx(SetBar, { set, height }, i);
2916
+ return /* @__PURE__ */ jsxs(View, { style: { flex: 1, minWidth: 0, position: "relative" }, children: [
2917
+ /* @__PURE__ */ jsx(
2918
+ Text,
2919
+ {
2920
+ className: "text-text-secondary text-2xs font-semibold text-center",
2921
+ style: { position: "absolute", bottom: height + 3, left: 0, right: 0 },
2922
+ testID: "set-strip-reps-label",
2923
+ children: label
2924
+ }
2925
+ ),
2926
+ /* @__PURE__ */ jsx(SetBar, { set, height })
2927
+ ] }, i);
2928
+ })
2792
2929
  }
2793
2930
  );
2794
2931
  }
@@ -2900,28 +3037,24 @@ function CollapsedCard({
2900
3037
  children: [
2901
3038
  /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", testID: "exercise-card-header", children: [
2902
3039
  /* @__PURE__ */ jsx(
2903
- Text,
3040
+ Typography,
2904
3041
  {
2905
- className: "text-text-primary",
2906
- style: {
2907
- fontSize: 14,
2908
- fontFamily: '"Space Grotesk", sans-serif',
2909
- fontWeight: "700"
2910
- },
3042
+ variant: "h6",
3043
+ color: "primary",
3044
+ className: "text-sm font-bold leading-[normal]",
2911
3045
  testID: "exercise-card-name",
2912
3046
  children: name
2913
3047
  }
2914
3048
  ),
2915
3049
  /* @__PURE__ */ jsx(View, { className: "flex-1" }),
2916
- summary && /* @__PURE__ */ jsx(
2917
- Text,
3050
+ summary && /* The demo's "body" face is Inter, which is the library's `font-sans`
3051
+ (the mapping B1 established for PrBadge), not Typography's `font-body`. */
3052
+ /* @__PURE__ */ jsx(
3053
+ Typography,
2918
3054
  {
2919
- className: "text-text-secondary",
2920
- style: {
2921
- fontSize: 12,
2922
- fontFamily: "Inter, sans-serif",
2923
- marginRight: 8
2924
- },
3055
+ variant: "caption",
3056
+ color: "secondary",
3057
+ className: "font-sans mr-2 leading-[normal]",
2925
3058
  testID: "exercise-card-summary",
2926
3059
  children: formatSummary(summary)
2927
3060
  }
@@ -2955,8 +3088,6 @@ function CollapsedCard({
2955
3088
  }
2956
3089
  );
2957
3090
  }
2958
- var DARK2 = getSemanticColors("dark");
2959
- var BODY_DIVIDER = DARK2["hairline-subtle"];
2960
3091
  function deriveHeaderSetStates(sets) {
2961
3092
  return sets.map((set) => {
2962
3093
  switch (set.state) {
@@ -3017,7 +3148,11 @@ function ExpandedCard({
3017
3148
  /* @__PURE__ */ jsxs(
3018
3149
  View,
3019
3150
  {
3020
- style: { borderTopWidth: 1, borderTopColor: BODY_DIVIDER, paddingBottom: 6 },
3151
+ style: {
3152
+ borderTopWidth: 1,
3153
+ borderTopColor: resolveColor("hairline-subtle"),
3154
+ paddingBottom: 6
3155
+ },
3021
3156
  testID: "exercise-card-body",
3022
3157
  children: [
3023
3158
  /* @__PURE__ */ jsx(SetTableHeader, { unit, showPrevious: false, testID: "exercise-card-column-headers" }),
@@ -3052,45 +3187,36 @@ function UpcomingCard({
3052
3187
  testID: "exercise-card",
3053
3188
  children: /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", children: [
3054
3189
  /* @__PURE__ */ jsx(
3055
- Text,
3190
+ Typography,
3056
3191
  {
3057
- className: "text-text-primary",
3058
- style: {
3059
- flexShrink: 0,
3060
- fontSize: 14,
3061
- fontFamily: '"Space Grotesk", sans-serif',
3062
- fontWeight: "700"
3063
- },
3192
+ variant: "h6",
3193
+ color: "primary",
3194
+ className: "shrink-0 text-sm font-bold leading-[normal]",
3064
3195
  testID: "exercise-card-name",
3065
3196
  children: name
3066
3197
  }
3067
3198
  ),
3068
3199
  prescription && /* @__PURE__ */ jsx(
3069
- Text,
3200
+ Typography,
3070
3201
  {
3071
- className: "text-text-secondary",
3072
- numberOfLines: 1,
3073
- style: {
3074
- flexShrink: 1,
3075
- fontSize: 12,
3076
- fontFamily: "Inter, sans-serif",
3077
- marginLeft: 8
3078
- },
3202
+ variant: "caption",
3203
+ color: "secondary",
3204
+ maxLines: 1,
3205
+ className: "font-sans shrink ml-2 leading-[normal]",
3079
3206
  testID: "exercise-card-prescription",
3080
3207
  children: prescription
3081
3208
  }
3082
3209
  ),
3083
3210
  /* @__PURE__ */ jsx(View, { className: "flex-1", style: { minWidth: 8 } }),
3084
- previousBest && /* @__PURE__ */ jsx(
3085
- Text,
3211
+ previousBest && /* 11px is off the type scale; `2xs` (10px) is the step below, as B2's
3212
+ WorkoutCard date took for the same size. */
3213
+ /* @__PURE__ */ jsx(
3214
+ Typography,
3086
3215
  {
3087
- className: "text-text-tertiary",
3088
- numberOfLines: 1,
3089
- style: {
3090
- flexShrink: 1,
3091
- fontSize: 11,
3092
- fontFamily: "Inter, sans-serif"
3093
- },
3216
+ variant: "caption",
3217
+ color: "tertiary",
3218
+ maxLines: 1,
3219
+ className: "font-sans shrink text-2xs leading-[normal]",
3094
3220
  testID: "exercise-card-previous-best",
3095
3221
  children: previousBest
3096
3222
  }
@@ -3117,12 +3243,7 @@ function ExerciseCard({
3117
3243
  if (upcoming) return /* @__PURE__ */ jsx(UpcomingCard, { ...rest, onToggle });
3118
3244
  return isExpanded ? /* @__PURE__ */ jsx(ExpandedCard, { ...rest, onToggle }) : /* @__PURE__ */ jsx(CollapsedCard, { ...rest, onToggle });
3119
3245
  }
3120
- function resolveColor(token, mode = "dark") {
3121
- return Platform.OS === "web" ? `var(--color-${token})` : getSemanticColors(mode)[token];
3122
- }
3123
-
3124
- // src/components/custom/Workout/InputBar.tsx
3125
- var BRAND_PRIMARY2 = getSemanticColors("dark")["brand-primary"];
3246
+ var BRAND_PRIMARY = getSemanticColors("dark")["brand-primary"];
3126
3247
  var INPUT_CLASSNAME = "bg-surface-raised border-hairline-strong text-text-primary";
3127
3248
  var inputStyle = {
3128
3249
  fontSize: 14,
@@ -3251,7 +3372,7 @@ function InputBar({
3251
3372
  onPress: onRecord,
3252
3373
  disabled: !canRecord,
3253
3374
  style: ({ pressed }) => ({
3254
- backgroundColor: BRAND_PRIMARY2,
3375
+ backgroundColor: BRAND_PRIMARY,
3255
3376
  borderRadius: 8,
3256
3377
  paddingVertical: 10,
3257
3378
  paddingHorizontal: 16,
@@ -3485,7 +3606,7 @@ function CircularTimer({
3485
3606
  }
3486
3607
 
3487
3608
  // src/components/custom/Workout/RestTimer.tsx
3488
- var BRAND_PRIMARY3 = getSemanticColors("dark")["brand-primary"];
3609
+ var BRAND_PRIMARY2 = getSemanticColors("dark")["brand-primary"];
3489
3610
  var RING_DEFAULT_SIZE = 180;
3490
3611
  function RestActions({ onAddTime, onSkip }) {
3491
3612
  return /* @__PURE__ */ jsxs(View, { style: { flexDirection: "row", gap: 8 }, children: [
@@ -3532,7 +3653,7 @@ function RestActions({ onAddTime, onSkip }) {
3532
3653
  fontSize: 11,
3533
3654
  fontFamily: "Inter, sans-serif",
3534
3655
  fontWeight: "600",
3535
- color: BRAND_PRIMARY3
3656
+ color: BRAND_PRIMARY2
3536
3657
  },
3537
3658
  children: "Skip"
3538
3659
  }
@@ -3707,7 +3828,7 @@ function RestTimer({
3707
3828
  {
3708
3829
  style: {
3709
3830
  height: "100%",
3710
- backgroundColor: BRAND_PRIMARY3,
3831
+ backgroundColor: BRAND_PRIMARY2,
3711
3832
  borderRadius: 2,
3712
3833
  width: `${progressPct}%`
3713
3834
  },
@@ -3721,23 +3842,16 @@ function RestTimer({
3721
3842
  }
3722
3843
  );
3723
3844
  }
3724
- var DEFAULTS = {
3725
- label: "SS",
3726
- color: getSemanticColors("dark")["brand-primary"],
3727
- bgBase: getSemanticColors("dark")["background-base"]
3728
- };
3729
- function SupersetWrapper({
3730
- label = DEFAULTS.label,
3731
- color = DEFAULTS.color,
3732
- children
3733
- }) {
3845
+ var DEFAULT_LABEL = "SS";
3846
+ function SupersetWrapper({ label = DEFAULT_LABEL, color, children }) {
3847
+ const rail = color ?? resolveColor("brand-primary");
3734
3848
  return /* @__PURE__ */ jsxs(
3735
3849
  View,
3736
3850
  {
3737
3851
  style: {
3738
3852
  position: "relative",
3739
3853
  borderLeftWidth: 3,
3740
- borderLeftColor: color,
3854
+ borderLeftColor: rail,
3741
3855
  paddingLeft: 8,
3742
3856
  marginHorizontal: 12,
3743
3857
  marginBottom: 8,
@@ -3748,21 +3862,18 @@ function SupersetWrapper({
3748
3862
  testID: "superset-wrapper",
3749
3863
  children: [
3750
3864
  /* @__PURE__ */ jsx(
3751
- Text,
3865
+ Typography,
3752
3866
  {
3867
+ variant: "microLabel",
3868
+ color: "inverse",
3753
3869
  style: {
3754
3870
  position: "absolute",
3755
3871
  top: -1,
3756
3872
  left: -3,
3757
- fontSize: 9,
3758
- fontFamily: "Inter, sans-serif",
3759
- fontWeight: "700",
3760
- backgroundColor: color,
3761
- color: DEFAULTS.bgBase,
3873
+ backgroundColor: rail,
3762
3874
  paddingVertical: 2,
3763
3875
  paddingHorizontal: 6,
3764
3876
  borderBottomRightRadius: 4,
3765
- letterSpacing: 0.5,
3766
3877
  zIndex: 2
3767
3878
  },
3768
3879
  testID: "superset-label",
@@ -3776,7 +3887,7 @@ function SupersetWrapper({
3776
3887
  }
3777
3888
 
3778
3889
  // src/components/custom/Workout/ActiveWorkoutPage.tsx
3779
- var BRAND_PRIMARY4 = getSemanticColors("dark")["brand-primary"];
3890
+ var BRAND_PRIMARY3 = getSemanticColors("dark")["brand-primary"];
3780
3891
  function countCompletedSets(exercise) {
3781
3892
  if (exercise.setVelocities != null) return exercise.setVelocities.length;
3782
3893
  if (exercise.status === "completed") return exercise.totalPlannedSets;
@@ -3890,7 +4001,7 @@ function WorkoutHeader({
3890
4001
  fontSize: 15,
3891
4002
  fontFamily: '"Space Grotesk", sans-serif',
3892
4003
  fontWeight: "700",
3893
- color: BRAND_PRIMARY4,
4004
+ color: BRAND_PRIMARY3,
3894
4005
  fontVariant: ["tabular-nums"]
3895
4006
  },
3896
4007
  children: `${progress.completedExercises}/${progress.totalExercises}`
@@ -3924,7 +4035,7 @@ function WorkoutHeader({
3924
4035
  style: {
3925
4036
  height: "100%",
3926
4037
  width: `${Math.round(progress.fraction * 100)}%`,
3927
- backgroundColor: BRAND_PRIMARY4,
4038
+ backgroundColor: BRAND_PRIMARY3,
3928
4039
  borderRadius: 2
3929
4040
  },
3930
4041
  testID: "active-workout-page-progress-fill"
@@ -4058,348 +4169,159 @@ function ActiveWorkoutPage({
4058
4169
  }
4059
4170
  );
4060
4171
  }
4061
- var elevationSystem = {
4062
- // Deep inset (recessed input fields, deeply pressed buttons)
4063
- [-2]: {
4064
- name: "deep-inset",
4065
- colorAdjustment: 0,
4066
- shadowIntensity: "strong",
4067
- shadowStyle: "pressed",
4068
- description: "Deeply recessed elements (e.g., input fields, deeply pressed buttons)"
4069
- },
4070
- // Shallow inset (pressed buttons, sunken panels)
4071
- [-1]: {
4072
- name: "inset",
4073
- colorAdjustment: 0,
4074
- shadowIntensity: "medium",
4075
- shadowStyle: "pressed",
4076
- description: "Shallow inset elements (e.g., pressed buttons, sunken panels within cards)"
4077
- },
4078
- // Base level (page background, default surface)
4079
- [0]: {
4080
- name: "base",
4081
- colorAdjustment: 0,
4082
- shadowIntensity: "subtle",
4083
- shadowStyle: "raised",
4084
- description: "Base surface level (page background, default containers)"
4085
- },
4086
- // Level 1: Subtle elevation (outline cards, subtle containers)
4087
- [1]: {
4088
- name: "subtle",
4089
- // The whole ladder was re-spaced in TD-07.16. It used to run
4090
- // 0.01/0.02/0.04/0.06/0.08, where the first step was ~2 RGB values — under
4091
- // the perceptual floor, so level 1 existed in the type system and nowhere on
4092
- // screen. With drop-shadow now gated off below FLOATING_ELEVATION_MIN, TONE
4093
- // is the only thing separating 0-3, so every step has to actually land.
4094
- // Even 0.025 spacing, verified in elevation.test.ts as ΔL* > 1 per step.
4095
- colorAdjustment: 0.025,
4096
- shadowIntensity: "subtle",
4097
- shadowStyle: "raised",
4098
- description: "Subtle elevation (outline cards, subtle containers)"
4099
- },
4100
- // Level 2: Standard elevation (default cards, buttons)
4101
- [2]: {
4102
- name: "standard",
4103
- colorAdjustment: 0.05,
4104
- shadowIntensity: "medium",
4105
- shadowStyle: "raised",
4106
- description: "Standard elevation (default cards, raised buttons)"
4107
- },
4108
- // Level 3: Prominent elevation (important cards, modals)
4109
- [3]: {
4110
- name: "prominent",
4111
- colorAdjustment: 0.075,
4112
- shadowIntensity: "strong",
4113
- shadowStyle: "raised",
4114
- description: "Prominent elevation (important cards, modals, dropdowns)"
4115
- },
4116
- // Level 4: High elevation (overlays, popovers)
4117
- [4]: {
4118
- name: "high",
4119
- colorAdjustment: 0.1,
4120
- shadowIntensity: "strong",
4121
- shadowStyle: "raised",
4122
- description: "High elevation (overlays, popovers, tooltips)"
4123
- },
4124
- // Level 5: Floating (toasts, floating action buttons)
4125
- [5]: {
4126
- name: "floating",
4127
- colorAdjustment: 0.13,
4128
- shadowIntensity: "strong",
4129
- shadowStyle: "raised",
4130
- description: "Floating elevation (toasts, floating action buttons, highest z-index)"
4131
- }
4172
+ var FLOATING_LIFT_MIN = 4;
4173
+ var LIFT_RIM_ALPHA = { dark: 0.12, light: 0.9 };
4174
+ var AMBIENT = {
4175
+ 1: [
4176
+ { y: 1, blur: 2, alpha: 0.35 },
4177
+ { y: 2, blur: 6, alpha: 0.3 }
4178
+ ],
4179
+ 2: [
4180
+ { y: 1, blur: 2, alpha: 0.35 },
4181
+ { y: 4, blur: 12, alpha: 0.32 }
4182
+ ],
4183
+ 3: [
4184
+ { y: 2, blur: 4, alpha: 0.35 },
4185
+ { y: 8, blur: 22, alpha: 0.35 }
4186
+ ],
4187
+ 4: [
4188
+ { y: 1, blur: 2, alpha: 0.35 },
4189
+ { y: 10, blur: 24, alpha: 0.3 },
4190
+ { y: 24, blur: 48, alpha: 0.2 }
4191
+ ],
4192
+ 5: [
4193
+ { y: 2, blur: 4, alpha: 0.4 },
4194
+ { y: 16, blur: 32, alpha: 0.35 },
4195
+ { y: 32, blur: 64, alpha: 0.25 }
4196
+ ]
4132
4197
  };
4133
- function calculateRimLightColor(baseColor, level) {
4134
- const rgb = hexToRgb(baseColor);
4135
- if (!rgb) {
4136
- return "rgba(255, 255, 255, 0.5)";
4137
- }
4138
- const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
4139
- const isLight = hsv.v > 0.6;
4140
- const isSaturated = hsv.s > 0.3;
4141
- const absLevel = Math.abs(level);
4142
- const opacityBoost = Math.max(0, (absLevel - 1) * 0.05);
4143
- if (isSaturated) {
4144
- const rimLightValue = 0.95;
4145
- const rimLightRgb = hsvToRgb(hsv.h, hsv.s * 0.3, rimLightValue);
4146
- const baseOpacity = isLight ? 0.9 : 0.5;
4147
- const finalOpacity = Math.min(1, baseOpacity + opacityBoost);
4148
- return `rgba(${rimLightRgb.r}, ${rimLightRgb.g}, ${rimLightRgb.b}, ${finalOpacity.toFixed(2)})`;
4149
- } else {
4150
- const baseOpacity = isLight ? 0.9 : 0.12;
4151
- const finalOpacity = Math.min(1, baseOpacity + opacityBoost);
4152
- return `rgba(255, 255, 255, ${finalOpacity.toFixed(2)})`;
4153
- }
4198
+ var AMBIENT_ALPHA_SCALE = { dark: 1, light: 0.4 };
4199
+ function ambientLayers(step, mode) {
4200
+ const scale = AMBIENT_ALPHA_SCALE[mode];
4201
+ return AMBIENT[step].map(
4202
+ ({ y, blur, alpha: alpha2 }) => `0 ${y}px ${blur}px rgba(0,0,0,${(alpha2 * scale).toFixed(2)})`
4203
+ );
4154
4204
  }
4155
- function calculateDarkShadowColors(surfaceColor) {
4156
- const rgb = hexToRgb(surfaceColor);
4157
- if (!rgb) {
4158
- return {
4159
- dark: "rgba(0, 0, 0, 0.3)",
4160
- darker: "rgba(0, 0, 0, 0.4)"
4161
- };
4162
- }
4163
- const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
4164
- const isLight = hsv.v > 0.6;
4165
- const isSaturated = hsv.s > 0.3;
4166
- if (isSaturated) {
4167
- const darkShadowValue = 0.15;
4168
- const darkShadowRgb = hsvToRgb(hsv.h, hsv.s, darkShadowValue);
4169
- if (isLight) {
4170
- return {
4171
- dark: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.3)`,
4172
- darker: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.4)`
4173
- };
4174
- } else {
4175
- return {
4176
- dark: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.5)`,
4177
- darker: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.6)`
4178
- };
4179
- }
4180
- } else {
4181
- if (isLight) {
4182
- return {
4183
- dark: "rgba(0, 0, 0, 0.2)",
4184
- darker: "rgba(0, 0, 0, 0.3)"
4185
- };
4186
- } else {
4187
- return {
4188
- dark: "rgba(0, 0, 0, 0.5)",
4189
- darker: "rgba(0, 0, 0, 0.6)"
4190
- };
4205
+ function liftShadow(step, mode = "dark", opts = {}) {
4206
+ const rim = opts.rim ?? LIFT_RIM_ALPHA[mode];
4207
+ const layers = ambientLayers(step, mode);
4208
+ if (rim > 0) layers.unshift(`inset 0 1px 0 rgba(255,255,255,${rim.toFixed(2)})`);
4209
+ return layers.join(", ");
4210
+ }
4211
+ function liftStyle(step, mode = "dark", opts = {}) {
4212
+ const deepest = AMBIENT[step][AMBIENT[step].length - 1];
4213
+ return Platform.select({
4214
+ web: { boxShadow: liftShadow(step, mode, opts) },
4215
+ default: {
4216
+ shadowColor: "#000",
4217
+ shadowOffset: { width: 0, height: Math.round(deepest.y / 2) },
4218
+ shadowOpacity: deepest.alpha * AMBIENT_ALPHA_SCALE[mode],
4219
+ shadowRadius: deepest.blur / 2,
4220
+ elevation: step
4191
4221
  }
4192
- }
4193
- }
4194
- function getRimLightConfig() {
4195
- return {
4196
- offset: 1,
4197
- // Fixed 1px for crisp rim
4198
- blur: 1
4199
- // Tight blur for crisp edge
4200
- };
4201
- }
4202
- var elevationSurfaceCache = /* @__PURE__ */ new Map();
4203
- var MAX_CACHE_SIZE = 100;
4204
- function getCacheKey(baseColor, level, theme) {
4205
- return `${baseColor}-${level}-${theme}`;
4222
+ });
4206
4223
  }
4207
- function calculateElevationSurface(baseColor, level, theme) {
4208
- const config = elevationSystem[level];
4209
- if (config.colorAdjustment === 0) {
4210
- return baseColor;
4211
- }
4212
- if (level < 0) {
4213
- return baseColor;
4214
- }
4215
- return lighten(baseColor, config.colorAdjustment);
4224
+ var FLOATING_ELEVATION_MIN = FLOATING_LIFT_MIN;
4225
+ function getPressedRecessShadow(fillColor, _mode = "dark") {
4226
+ const { boxShadow } = insetWell(fillColor);
4227
+ return Platform.select({
4228
+ web: { boxShadow },
4229
+ default: {}
4230
+ });
4216
4231
  }
4217
- function getElevationSurface(baseColor, level, theme) {
4218
- const cacheKey = getCacheKey(baseColor, level, theme);
4219
- if (elevationSurfaceCache.has(cacheKey)) {
4220
- return elevationSurfaceCache.get(cacheKey);
4221
- }
4222
- const result = calculateElevationSurface(baseColor, level);
4223
- if (elevationSurfaceCache.size >= MAX_CACHE_SIZE) {
4224
- const firstKey = elevationSurfaceCache.keys().next().value;
4225
- elevationSurfaceCache.delete(firstKey);
4226
- }
4227
- elevationSurfaceCache.set(cacheKey, result);
4228
- return result;
4229
- }
4230
- var elevationShadowCache = /* @__PURE__ */ new Map();
4231
- var MAX_SHADOW_CACHE_SIZE = 50;
4232
- function getShadowCacheKey(baseColor, level, theme, isHovered) {
4233
- return `${baseColor}-${level}-${theme}-${isHovered}`;
4234
- }
4235
- function calculateElevationShadow(baseColor, level, theme, isHovered = false) {
4236
- const config = elevationSystem[level];
4237
- if (level === 0) {
4238
- return {};
4239
- }
4240
- const elevatedSurfaceColor = calculateElevationSurface(baseColor, level);
4241
- const rimLightColor = calculateRimLightColor(baseColor, level);
4242
- const darkShadowColors = calculateDarkShadowColors(elevatedSurfaceColor);
4243
- const intensityConfig = {
4244
- subtle: { offset: 1, blur: 2 },
4245
- medium: { offset: 2, blur: 4 },
4246
- strong: { offset: 2, blur: 5 }
4247
- };
4248
- const { offset, blur } = intensityConfig[config.shadowIntensity];
4249
- const rimConfig = getRimLightConfig();
4250
- if (config.shadowStyle === "pressed") {
4251
- if (isHovered) {
4252
- const hoverOffset = Math.max(1, Math.round(offset / 2));
4253
- const hoverBlur = Math.max(1, Math.round(blur / 2));
4254
- return Platform.select({
4255
- web: {
4256
- boxShadow: `inset ${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${darkShadowColors.darker}, inset -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
4257
- },
4258
- default: {
4259
- shadowOpacity: 0,
4260
- elevation: 0
4261
- }
4262
- });
4263
- }
4264
- return Platform.select({
4265
- web: {
4266
- boxShadow: `inset ${offset}px ${offset}px ${blur}px ${darkShadowColors.darker}, inset -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
4267
- },
4268
- default: {
4269
- shadowOpacity: 0,
4270
- elevation: 0
4271
- }
4272
- });
4273
- } else {
4274
- if (isHovered) {
4275
- const hoverOffset = Math.max(1, Math.round(offset / 2));
4276
- const hoverBlur = Math.max(1, Math.round(blur / 2));
4277
- return Platform.select({
4278
- web: {
4279
- boxShadow: `${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${darkShadowColors.dark}, -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
4280
- },
4281
- default: {
4282
- shadowColor: "#000",
4283
- shadowOffset: { width: hoverOffset, height: hoverOffset },
4284
- shadowOpacity: 0.2,
4285
- shadowRadius: hoverBlur / 2,
4286
- elevation: hoverOffset
4287
- }
4288
- });
4232
+ var glowConfig = {
4233
+ tight: { blur: 4, spread: 0, opacity: 0.4 },
4234
+ subtle: { blur: 12, spread: 0, opacity: 0.25 },
4235
+ medium: { blur: 20, spread: 2, opacity: 0.4 },
4236
+ strong: { blur: 30, spread: 4, opacity: 0.55 }
4237
+ };
4238
+ function getGlowShadow(color, intensity = "medium") {
4239
+ const config = glowConfig[intensity];
4240
+ const rgb = hexToRgb(color);
4241
+ if (!rgb) return {};
4242
+ return Platform.select({
4243
+ web: {
4244
+ boxShadow: `0 0 ${config.blur}px ${config.spread}px rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${config.opacity})`
4245
+ },
4246
+ default: {
4247
+ shadowColor: color,
4248
+ shadowOffset: { width: 0, height: 0 },
4249
+ shadowOpacity: config.opacity,
4250
+ shadowRadius: config.blur / 2,
4251
+ elevation: 0
4289
4252
  }
4290
- return Platform.select({
4291
- web: {
4292
- boxShadow: `${offset}px ${offset}px ${blur}px ${darkShadowColors.dark}, -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
4293
- },
4294
- default: {
4295
- shadowColor: "#000",
4296
- shadowOffset: { width: offset, height: offset },
4297
- shadowOpacity: 0.3,
4298
- shadowRadius: blur / 2,
4299
- elevation: offset
4300
- }
4301
- });
4302
- }
4303
- }
4304
- var FLOATING_ELEVATION_MIN = 4;
4305
- function getElevationShadow(baseColor, level, theme, isHovered = false) {
4306
- const cacheKey = getShadowCacheKey(baseColor, level, theme, isHovered);
4307
- if (elevationShadowCache.has(cacheKey)) {
4308
- return elevationShadowCache.get(cacheKey);
4309
- }
4310
- const result = level > 0 && level < FLOATING_ELEVATION_MIN ? {} : calculateElevationShadow(baseColor, level, theme, isHovered);
4311
- if (elevationShadowCache.size >= MAX_SHADOW_CACHE_SIZE) {
4312
- const firstKey = elevationShadowCache.keys().next().value;
4313
- elevationShadowCache.delete(firstKey);
4314
- }
4315
- elevationShadowCache.set(cacheKey, result);
4316
- return result;
4317
- }
4318
- function getBaseSurfaceColor(theme) {
4319
- return theme === "light" ? semanticColorsLight["surface-raised"] : semanticColorsDark["surface-elevated"];
4253
+ });
4320
4254
  }
4321
- var componentElevationRanges = {
4322
- button: {
4323
- allowed: [2],
4324
- default: 2,
4325
- hover: 3
4326
- },
4327
- card: {
4328
- allowed: [1, 2, 3],
4329
- default: 2,
4330
- hover: 3
4331
- },
4332
- input: {
4333
- allowed: [-2, -1, 0],
4334
- default: -1
4335
- },
4336
- overlay: {
4337
- allowed: [4, 5],
4338
- default: 4
4255
+ function recessDepth(inherited, planesDown, mode) {
4256
+ let plane = inherited.level;
4257
+ for (let i = 0; i < planesDown; i++) plane = pressedLevel(plane);
4258
+ const backgroundColor = surfaceBackground(plane, mode);
4259
+ return { plane, backgroundColor, depthStyle: getPressedRecessShadow(backgroundColor, mode) };
4260
+ }
4261
+ function resolveSurfaceDepth(inherited, props) {
4262
+ const mode = props.theme ?? inherited.mode;
4263
+ const elevation = props.elevation ?? 0;
4264
+ if (props.pressed || elevation < 0) {
4265
+ const down = props.pressed ? 1 : -elevation;
4266
+ return { mode, step: 0, lifted: false, ...recessDepth(inherited, down, mode) };
4339
4267
  }
4340
- };
4341
- function getValidatedElevation(component, requested) {
4342
- const range = componentElevationRanges[component];
4343
- if (range.allowed.includes(requested)) {
4344
- return requested;
4345
- }
4346
- const sorted = [...range.allowed].sort((a, b) => a - b);
4347
- if (requested < sorted[0]) return sorted[0];
4348
- if (requested > sorted[sorted.length - 1]) return sorted[sorted.length - 1];
4349
- return sorted.reduce(
4350
- (prev, curr) => Math.abs(curr - requested) < Math.abs(prev - requested) ? curr : prev
4268
+ const step = props.level != null ? 0 : props.raise ?? elevation;
4269
+ const floating = step >= FLOATING_ELEVATION_MIN;
4270
+ const plane = props.level ?? (floating ? "overlay" : raisedLevel(inherited.level, step));
4271
+ const lifted = props.lift ?? step > 0;
4272
+ const liftStep = Math.max(1, Math.min(5, step));
4273
+ const depthStyle = lifted ? liftStyle(liftStep, mode, props.liftOptions) : {};
4274
+ return { mode, plane, backgroundColor: surfaceBackground(plane, mode), depthStyle, step, lifted };
4275
+ }
4276
+ function useResolvedSurface(props) {
4277
+ const inherited = useSurface();
4278
+ const { level, raise, elevation, pressed, lift, liftOptions, theme } = props;
4279
+ return useMemo(
4280
+ () => resolveSurfaceDepth(inherited, {
4281
+ level,
4282
+ raise,
4283
+ elevation,
4284
+ pressed,
4285
+ lift,
4286
+ liftOptions,
4287
+ theme
4288
+ }),
4289
+ [inherited, level, raise, elevation, pressed, lift, liftOptions, theme]
4351
4290
  );
4352
4291
  }
4353
- function getTheme() {
4354
- if (typeof document === "undefined") return "dark";
4355
- return document.documentElement.classList.contains("light") ? "light" : "dark";
4356
- }
4357
- var listeners = [];
4358
- function subscribe(listener) {
4359
- listeners = [...listeners, listener];
4360
- if (typeof document !== "undefined" && listeners.length === 1) {
4361
- const observer = new MutationObserver((mutations) => {
4362
- for (const mutation of mutations) {
4363
- if (mutation.type === "attributes" && mutation.attributeName === "class") {
4364
- listeners.forEach((l) => l());
4365
- }
4366
- }
4367
- });
4368
- observer.observe(document.documentElement, {
4369
- attributes: true,
4370
- attributeFilter: ["class"]
4371
- });
4372
- subscribe._observer = observer;
4373
- }
4374
- return () => {
4375
- listeners = listeners.filter((l) => l !== listener);
4376
- if (listeners.length === 0 && subscribe._observer) {
4377
- subscribe._observer.disconnect();
4378
- subscribe._observer = null;
4379
- }
4380
- };
4381
- }
4382
- function getSnapshot() {
4383
- return getTheme();
4384
- }
4385
- function getServerSnapshot() {
4386
- return "dark";
4387
- }
4388
- function useTheme() {
4389
- return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
4390
- }
4391
4292
 
4392
4293
  // src/components/ui/card/Card.tsx
4393
- var variantStyles = {
4294
+ var EDGE_CLASS = {
4394
4295
  elevated: "",
4395
- // Will be set dynamically via elevation system
4396
- outline: "border-2 border-hairline-strong",
4397
- // Thicker border with stronger contrast
4296
+ accent: "",
4398
4297
  filled: "",
4399
- // Will be set dynamically via elevation system
4400
- accent: "border border-hairline",
4298
+ outline: "border border-hairline-strong",
4401
4299
  subtle: "border border-hairline-subtle"
4402
4300
  };
4301
+ var LIFTED = {
4302
+ elevated: true,
4303
+ accent: true,
4304
+ filled: false,
4305
+ outline: false,
4306
+ subtle: false
4307
+ };
4308
+ var STAYS_ON_HOST = {
4309
+ elevated: false,
4310
+ accent: false,
4311
+ filled: false,
4312
+ outline: true,
4313
+ subtle: true
4314
+ };
4315
+ function useCardDepth(variant, elevation, hovered) {
4316
+ const raise = STAYS_ON_HOST[variant] ? void 0 : elevation;
4317
+ const resolved = useResolvedSurface({ raise, lift: LIFTED[variant] });
4318
+ const depthStyle = useMemo(() => {
4319
+ if (!hovered || !LIFTED[variant]) return resolved.depthStyle;
4320
+ const hoverStep = Math.min(3, resolved.step + 1);
4321
+ return liftStyle(hoverStep, resolved.mode);
4322
+ }, [hovered, variant, resolved]);
4323
+ return { ...resolved, depthStyle };
4324
+ }
4403
4325
  function Card({
4404
4326
  variant = "elevated",
4405
4327
  elevation = 2,
@@ -4420,89 +4342,54 @@ function Card({
4420
4342
  }) {
4421
4343
  const isClickable = isInteractive || !!onPress;
4422
4344
  const [isHovered, setIsHovered] = useState(false);
4423
- const theme = useTheme();
4424
- const elevationLevel = useMemo(() => {
4425
- const validated = getValidatedElevation("card", elevation);
4426
- if (variant === "outline" || variant === "accent" || variant === "subtle") {
4427
- return 1;
4428
- }
4429
- return validated;
4430
- }, [variant, elevation]);
4431
- const baseColor = useMemo(() => getBaseSurfaceColor(theme), [theme]);
4432
- const surfaceColor = useMemo(() => {
4433
- if ((variant === "outline" || variant === "accent") && theme === "light") {
4434
- return "#FAFAFA";
4435
- }
4436
- if (variant === "subtle") {
4437
- return getElevationSurface(baseColor, 0, theme);
4438
- }
4439
- return getElevationSurface(baseColor, elevationLevel, theme);
4440
- }, [baseColor, elevationLevel, theme, variant]);
4441
- const shadowStyle = useMemo(() => {
4442
- const shouldHover = isHovered && isClickable;
4443
- return getElevationShadow(baseColor, elevationLevel, theme, shouldHover);
4444
- }, [baseColor, elevationLevel, theme, isHovered, isClickable]);
4445
- const cardContent = isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
4446
- skeletonHasHeader && /* @__PURE__ */ jsxs(CardHeader, { children: [
4447
- /* @__PURE__ */ jsx(View, { className: "h-5 w-1/3 bg-interactive-disabled rounded" }),
4448
- /* @__PURE__ */ jsx(View, { className: "mt-2 h-4 w-2/3 bg-interactive-disabled rounded" })
4449
- ] }),
4450
- /* @__PURE__ */ jsx(CardContent, { children: Array.from({ length: skeletonContentLines }).map((_, i) => /* @__PURE__ */ jsx(
4451
- View,
4452
- {
4453
- className: cn(
4454
- "h-4 bg-interactive-disabled rounded",
4455
- i < skeletonContentLines - 1 ? "mb-2 w-full" : "w-4/5"
4456
- )
4457
- },
4458
- i
4459
- )) }),
4460
- skeletonHasFooter && /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(View, { className: "h-9 w-24 bg-interactive-disabled rounded" }) })
4461
- ] }) : children;
4345
+ const depth = useCardDepth(variant, elevation, isHovered && isClickable);
4462
4346
  const baseClassName = cn(
4463
4347
  "rounded-lg overflow-hidden relative",
4464
- // Apply variant styles, but only use default border color if no custom borderColor
4465
- variant === "outline" ? borderColor ? "border-2" : variantStyles[variant] : variantStyles[variant],
4466
- // Remove Tailwind shadow classes - we're using elevation shadows via style prop
4348
+ borderColor ? "border" : EDGE_CLASS[variant],
4467
4349
  isClickable && "web:cursor-pointer web:transition-all web:duration-150",
4468
4350
  isClickable && "web:hover:-translate-y-0.5 active:scale-[0.99]",
4469
4351
  isLoading && "pointer-events-none animate-pulse",
4470
4352
  className
4471
4353
  );
4472
- const accentStyle = useMemo(() => variant === "accent" ? {
4473
- borderLeftWidth: accentWidth ?? 3,
4474
- borderLeftColor: accentColor ?? "var(--color-brand-primary)"
4475
- } : {}, [variant, accentWidth, accentColor]);
4476
4354
  const mergedStyle = useMemo(() => {
4477
- const elevationStyle = {
4478
- backgroundColor: bgColor || surfaceColor,
4355
+ const own = {
4356
+ backgroundColor: bgColor || depth.backgroundColor,
4479
4357
  borderRadius: 8,
4480
4358
  overflow: "hidden",
4481
- ...shadowStyle,
4482
- ...accentStyle
4359
+ ...depth.depthStyle
4483
4360
  };
4484
- if (borderColor) {
4485
- elevationStyle.borderColor = borderColor;
4361
+ if (variant === "accent") {
4362
+ own.borderLeftWidth = accentWidth ?? 3;
4363
+ own.borderLeftColor = accentColor ?? "var(--color-brand-primary)";
4486
4364
  }
4487
- if (!style) return elevationStyle;
4488
- return [elevationStyle, style];
4489
- }, [style, surfaceColor, shadowStyle, borderColor, bgColor, accentStyle]);
4490
- if (isClickable) {
4491
- return /* @__PURE__ */ jsx(
4492
- Pressable,
4493
- {
4494
- onPress,
4495
- onHoverIn: () => setIsHovered(true),
4496
- onHoverOut: () => setIsHovered(false),
4497
- accessibilityRole: "button",
4498
- className: baseClassName,
4499
- style: mergedStyle,
4500
- ...props,
4501
- children: cardContent
4502
- }
4503
- );
4504
- }
4505
- return /* @__PURE__ */ jsx(View, { className: baseClassName, style: mergedStyle, ...props, children: cardContent });
4365
+ if (borderColor) own.borderColor = borderColor;
4366
+ return style ? [own, style] : own;
4367
+ }, [style, depth, bgColor, borderColor, variant, accentWidth, accentColor]);
4368
+ const context = useMemo(
4369
+ () => ({ mode: depth.mode, level: depth.plane }),
4370
+ [depth.mode, depth.plane]
4371
+ );
4372
+ const content = isLoading ? /* @__PURE__ */ jsx(
4373
+ SkeletonBody,
4374
+ {
4375
+ hasHeader: skeletonHasHeader,
4376
+ hasFooter: skeletonHasFooter,
4377
+ contentLines: skeletonContentLines
4378
+ }
4379
+ ) : children;
4380
+ return /* @__PURE__ */ jsx(SurfaceContext.Provider, { value: context, children: isClickable ? /* @__PURE__ */ jsx(
4381
+ Pressable,
4382
+ {
4383
+ onPress,
4384
+ onHoverIn: () => setIsHovered(true),
4385
+ onHoverOut: () => setIsHovered(false),
4386
+ accessibilityRole: "button",
4387
+ className: baseClassName,
4388
+ style: mergedStyle,
4389
+ ...props,
4390
+ children: content
4391
+ }
4392
+ ) : /* @__PURE__ */ jsx(View, { className: baseClassName, style: mergedStyle, ...props, children: content }) });
4506
4393
  }
4507
4394
  function CardHeader({ children, className }) {
4508
4395
  return /* @__PURE__ */ jsx(View, { className: cn("px-6 py-6", className), children });
@@ -4513,60 +4400,88 @@ function CardContent({ children, className }) {
4513
4400
  function CardFooter({ children, className }) {
4514
4401
  return /* @__PURE__ */ jsx(View, { className: cn("px-6 py-4 flex-row items-center gap-2", className), children });
4515
4402
  }
4516
- var t5 = getSemanticColors("dark");
4517
- var solidVariantColors = {
4518
- success: t5["status-success"],
4519
- warning: t5["status-warning"],
4520
- error: t5["status-error"],
4521
- neutral: greyRamp[500]
4403
+ function SkeletonBody({ hasHeader, hasFooter, contentLines }) {
4404
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
4405
+ hasHeader && /* @__PURE__ */ jsxs(CardHeader, { children: [
4406
+ /* @__PURE__ */ jsx(View, { className: "h-5 w-1/3 bg-interactive-disabled rounded" }),
4407
+ /* @__PURE__ */ jsx(View, { className: "mt-2 h-4 w-2/3 bg-interactive-disabled rounded" })
4408
+ ] }),
4409
+ /* @__PURE__ */ jsx(CardContent, { children: Array.from({ length: contentLines }).map((_, i) => /* @__PURE__ */ jsx(
4410
+ View,
4411
+ {
4412
+ className: cn(
4413
+ "h-4 bg-interactive-disabled rounded",
4414
+ i < contentLines - 1 ? "mb-2 w-full" : "w-4/5"
4415
+ )
4416
+ },
4417
+ i
4418
+ )) }),
4419
+ hasFooter && /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(View, { className: "h-9 w-24 bg-interactive-disabled rounded" }) })
4420
+ ] });
4421
+ }
4422
+ var solidFillToken = {
4423
+ success: "status-success",
4424
+ warning: "status-warning",
4425
+ error: "status-error",
4426
+ neutral: "text-tertiary"
4522
4427
  };
4523
- var ringVariantStyles = {
4524
- "on-track": {
4525
- backgroundColor: "rgba(46,213,115,0.15)",
4526
- borderWidth: 1,
4527
- borderColor: "rgba(46,213,115,0.3)"
4528
- },
4529
- deviation: {
4530
- backgroundColor: "rgba(245,158,11,0.15)",
4531
- borderWidth: 1,
4532
- borderColor: "rgba(245,158,11,0.25)"
4533
- },
4534
- future: {
4535
- backgroundColor: "rgba(107,114,128,0.1)",
4536
- borderWidth: 1,
4537
- borderStyle: "dashed",
4538
- borderColor: "rgba(107,114,128,0.2)"
4539
- }
4428
+ var ringWashToken = {
4429
+ "on-track": { fill: "status-success-subtle", border: "status-success-muted" },
4430
+ deviation: { fill: "status-warning-subtle", border: "status-warning-muted" }
4540
4431
  };
4541
- var glowStyles = {
4542
- success: { boxShadow: "0 0 4px rgba(46,213,115,0.4)" },
4543
- warning: { boxShadow: "0 0 4px rgba(245,158,11,0.4)" },
4544
- error: { boxShadow: "0 0 4px rgba(239,68,68,0.4)" },
4545
- neutral: { boxShadow: "0 0 4px rgba(107,114,128,0.4)" },
4546
- "on-track": { boxShadow: "0 0 4px rgba(46,213,115,0.4)" },
4547
- deviation: { boxShadow: "0 0 4px rgba(245,158,11,0.4)" },
4548
- future: { boxShadow: "0 0 4px rgba(107,114,128,0.4)" }
4432
+ var FUTURE_FILL = alpha(greyRamp[500], 0.1);
4433
+ var FUTURE_BORDER = alpha(greyRamp[500], 0.2);
4434
+ var glyphToken = {
4435
+ success: "text-inverse",
4436
+ warning: "text-inverse",
4437
+ error: "text-inverse",
4438
+ neutral: "text-inverse",
4439
+ "on-track": "status-success",
4440
+ deviation: "status-warning",
4441
+ future: "text-tertiary"
4549
4442
  };
4443
+ var glowColors = {
4444
+ success: semanticColorsDark["status-success"],
4445
+ warning: semanticColorsDark["status-warning"],
4446
+ error: semanticColorsDark["status-error"],
4447
+ neutral: greyRamp[500],
4448
+ "on-track": semanticColorsDark["status-success"],
4449
+ deviation: semanticColorsDark["status-warning"],
4450
+ future: greyRamp[500]
4451
+ };
4452
+ var glowStyles = Object.fromEntries(
4453
+ Object.entries(glowColors).map(([variant, color]) => [variant, getGlowShadow(color, "subtle")])
4454
+ );
4550
4455
  var iconChars = {
4551
4456
  check: "\u2713",
4552
4457
  exclamation: "!",
4553
4458
  dash: "\u2014"
4554
4459
  };
4555
- var iconColors = {
4556
- success: "#0A5C52",
4557
- warning: "#6B4000",
4558
- error: "#5C1A1A",
4559
- neutral: greyRamp[200],
4560
- "on-track": t5["status-success"],
4561
- deviation: t5["status-warning"],
4562
- future: greyRamp[500]
4563
- };
4564
4460
  var sizeDimensions = {
4565
4461
  sm: { size: 8, showIcon: false },
4566
4462
  md: { size: 18, showIcon: true }
4567
4463
  };
4568
4464
  function isSolidVariant(variant) {
4569
- return variant in solidVariantColors;
4465
+ return variant in solidFillToken;
4466
+ }
4467
+ function ringStyle(variant) {
4468
+ if (variant === "future") {
4469
+ return {
4470
+ backgroundColor: FUTURE_FILL,
4471
+ borderWidth: 1,
4472
+ borderStyle: "dashed",
4473
+ borderColor: FUTURE_BORDER
4474
+ };
4475
+ }
4476
+ if (variant === "on-track" || variant === "deviation") {
4477
+ const tokens = ringWashToken[variant];
4478
+ return {
4479
+ backgroundColor: resolveColor(tokens.fill),
4480
+ borderWidth: 1,
4481
+ borderColor: resolveColor(tokens.border)
4482
+ };
4483
+ }
4484
+ return void 0;
4570
4485
  }
4571
4486
  function StatusDot({
4572
4487
  variant,
@@ -4579,7 +4494,7 @@ function StatusDot({
4579
4494
  }) {
4580
4495
  const config = sizeDimensions[size];
4581
4496
  const solid = isSolidVariant(variant);
4582
- const ring = ringVariantStyles[variant];
4497
+ const ring = ringStyle(variant);
4583
4498
  const glowStyle = glow ? glowStyles[variant] : null;
4584
4499
  const dot = /* @__PURE__ */ jsx(
4585
4500
  View,
@@ -4593,22 +4508,22 @@ function StatusDot({
4593
4508
  justifyContent: "center",
4594
4509
  flexShrink: 0
4595
4510
  },
4596
- solid ? { backgroundColor: solidVariantColors[variant] } : void 0,
4597
- ring ? ring : void 0,
4511
+ solid ? { backgroundColor: resolveColor(solidFillToken[variant]) } : void 0,
4512
+ ring,
4598
4513
  glowStyle ? glowStyle : void 0
4599
4514
  ],
4600
4515
  accessibilityRole: "image",
4601
4516
  accessibilityLabel: `${variant} status`,
4602
4517
  testID: "status-dot",
4603
- children: config.showIcon && icon && /* @__PURE__ */ jsx(
4604
- Text,
4518
+ children: config.showIcon && icon && // The glyph was 11px/900, off the type scale (TOKENS.md §4); `boldLabel` is
4519
+ // the 12px sans label step and `font-black` keeps the original weight.
4520
+ /* @__PURE__ */ jsx(
4521
+ Typography,
4605
4522
  {
4606
- style: {
4607
- fontSize: 11,
4608
- lineHeight: 11,
4609
- fontWeight: "900",
4610
- color: iconColors[variant]
4611
- },
4523
+ variant: "boldLabel",
4524
+ color: "inherit",
4525
+ className: "font-black leading-none",
4526
+ style: { color: resolveColor(glyphToken[variant]) },
4612
4527
  accessibilityElementsHidden: true,
4613
4528
  children: iconChars[icon]
4614
4529
  }
@@ -4626,9 +4541,11 @@ function StatusDot({
4626
4541
  children: [
4627
4542
  /* @__PURE__ */ jsx(View, { accessibilityElementsHidden: true, children: dot }),
4628
4543
  /* @__PURE__ */ jsx(
4629
- Text,
4544
+ Typography,
4630
4545
  {
4631
- style: { fontSize: 12, lineHeight: 16, color: greyRamp[400] },
4546
+ variant: "caption",
4547
+ color: "secondary",
4548
+ className: "leading-4",
4632
4549
  accessibilityElementsHidden: true,
4633
4550
  children: label
4634
4551
  }
@@ -4644,14 +4561,14 @@ var MESO_ACCENT_GRADIENT_LIGHT = primitiveRamps.orange[300];
4644
4561
  var WORKOUT_PILL_DELOAD = primitiveRamps.magenta[600];
4645
4562
 
4646
4563
  // src/components/custom/Workout/MesoStatusCard.tsx
4647
- var t6 = getSemanticColors("dark");
4648
- var BRAND_PRIMARY5 = t6["brand-primary"];
4564
+ var t3 = getSemanticColors("dark");
4565
+ var BRAND_PRIMARY4 = t3["brand-primary"];
4649
4566
  var BRAND_PRIMARY_DARK = MESO_ACCENT_GRADIENT_DARK;
4650
4567
  var BRAND_PRIMARY_LIGHT = MESO_ACCENT_GRADIENT_LIGHT;
4651
- var SUCCESS = t6["status-success"];
4652
- var WARNING = t6["status-warning"];
4653
- var ERROR = t6["status-error"];
4654
- var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY5, BRAND_PRIMARY_LIGHT];
4568
+ var SUCCESS = t3["status-success"];
4569
+ var WARNING = t3["status-warning"];
4570
+ var ERROR = t3["status-error"];
4571
+ var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY4, BRAND_PRIMARY_LIGHT];
4655
4572
  var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
4656
4573
  var GAUGE_GRADIENT = "linear-gradient(90deg, rgba(46,213,115,0.25) 0%, rgba(249,180,21,0.25) 50%, rgba(209,67,67,0.25) 100%)";
4657
4574
  var STATUS_VARIANTS = {
@@ -4676,15 +4593,7 @@ function renderCoachingText(text, highlights) {
4676
4593
  if (escaped.length === 0) return text;
4677
4594
  const regex = new RegExp(`(${escaped.join("|")})`, "g");
4678
4595
  return text.split(regex).map(
4679
- (part, index) => highlights.includes(part) ? /* @__PURE__ */ jsx(
4680
- Text,
4681
- {
4682
- className: "text-text-primary",
4683
- style: { fontWeight: "700" },
4684
- children: part
4685
- },
4686
- `${part}-${index}`
4687
- ) : /* @__PURE__ */ jsx(Fragment$1, { children: part }, `t-${index}`)
4596
+ (part, index) => highlights.includes(part) ? /* @__PURE__ */ jsx(Text, { className: "text-text-primary", style: { fontWeight: "700" }, children: part }, `${part}-${index}`) : /* @__PURE__ */ jsx(Fragment, { children: part }, `t-${index}`)
4688
4597
  );
4689
4598
  }
4690
4599
  function StatusPill({ badge }) {
@@ -4769,41 +4678,34 @@ function Gauge({ gauge }) {
4769
4678
  "aria-valuemax": 100,
4770
4679
  testID: "meso-status-card-gauge",
4771
4680
  children: [
4772
- /* @__PURE__ */ jsxs(
4773
- View,
4774
- {
4775
- className: "flex-row items-center justify-between",
4776
- accessibilityElementsHidden: true,
4777
- children: [
4778
- /* @__PURE__ */ jsx(
4779
- Text,
4780
- {
4781
- className: "text-text-secondary",
4782
- style: {
4783
- fontSize: 10,
4784
- fontFamily: "Inter, sans-serif",
4785
- fontWeight: "500",
4786
- letterSpacing: 0.5,
4787
- textTransform: "uppercase"
4788
- },
4789
- children: gauge.label
4790
- }
4791
- ),
4792
- gauge.sublabel != null && /* @__PURE__ */ jsx(
4793
- Text,
4794
- {
4795
- className: "text-text-tertiary",
4796
- style: {
4797
- fontSize: 10,
4798
- fontFamily: "Inter, sans-serif",
4799
- fontWeight: "500"
4800
- },
4801
- children: gauge.sublabel
4802
- }
4803
- )
4804
- ]
4805
- }
4806
- ),
4681
+ /* @__PURE__ */ jsxs(View, { className: "flex-row items-center justify-between", accessibilityElementsHidden: true, children: [
4682
+ /* @__PURE__ */ jsx(
4683
+ Text,
4684
+ {
4685
+ className: "text-text-secondary",
4686
+ style: {
4687
+ fontSize: 10,
4688
+ fontFamily: "Inter, sans-serif",
4689
+ fontWeight: "500",
4690
+ letterSpacing: 0.5,
4691
+ textTransform: "uppercase"
4692
+ },
4693
+ children: gauge.label
4694
+ }
4695
+ ),
4696
+ gauge.sublabel != null && /* @__PURE__ */ jsx(
4697
+ Text,
4698
+ {
4699
+ className: "text-text-tertiary",
4700
+ style: {
4701
+ fontSize: 10,
4702
+ fontFamily: "Inter, sans-serif",
4703
+ fontWeight: "500"
4704
+ },
4705
+ children: gauge.sublabel
4706
+ }
4707
+ )
4708
+ ] }),
4807
4709
  /* @__PURE__ */ jsxs(
4808
4710
  View,
4809
4711
  {
@@ -4844,7 +4746,8 @@ function Gauge({ gauge }) {
4844
4746
  borderRadius: 9999,
4845
4747
  borderWidth: 2,
4846
4748
  backgroundColor: markerColor,
4847
- boxShadow: "0 0 4px rgba(0,0,0,0.5)"
4749
+ // A knob resting on the gauge: lift, with the ring as its edge.
4750
+ ...liftStyle(1, "dark", { rim: 0 })
4848
4751
  },
4849
4752
  testID: "meso-status-card-gauge-marker"
4850
4753
  }
@@ -4896,30 +4799,23 @@ function MesoStatusCard({
4896
4799
  ),
4897
4800
  /* @__PURE__ */ jsxs(View, { style: { padding: 14, gap: 14 }, testID: "meso-status-card-body", children: [
4898
4801
  /* @__PURE__ */ jsxs(View, { testID: "meso-status-card-header", children: [
4899
- /* @__PURE__ */ jsxs(
4900
- View,
4901
- {
4902
- className: "flex-row items-center justify-between",
4903
- style: { gap: 8 },
4904
- children: [
4905
- /* @__PURE__ */ jsx(
4906
- Text,
4907
- {
4908
- className: "text-text-primary",
4909
- style: {
4910
- flexShrink: 1,
4911
- fontSize: 15,
4912
- fontFamily: '"Space Grotesk", sans-serif',
4913
- fontWeight: "700"
4914
- },
4915
- testID: "meso-status-card-name",
4916
- children: mesoName
4917
- }
4918
- ),
4919
- /* @__PURE__ */ jsx(StatusPill, { badge: statusBadge })
4920
- ]
4921
- }
4922
- ),
4802
+ /* @__PURE__ */ jsxs(View, { className: "flex-row items-center justify-between", style: { gap: 8 }, children: [
4803
+ /* @__PURE__ */ jsx(
4804
+ Text,
4805
+ {
4806
+ className: "text-text-primary",
4807
+ style: {
4808
+ flexShrink: 1,
4809
+ fontSize: 15,
4810
+ fontFamily: '"Space Grotesk", sans-serif',
4811
+ fontWeight: "700"
4812
+ },
4813
+ testID: "meso-status-card-name",
4814
+ children: mesoName
4815
+ }
4816
+ ),
4817
+ /* @__PURE__ */ jsx(StatusPill, { badge: statusBadge })
4818
+ ] }),
4923
4819
  /* @__PURE__ */ jsx(
4924
4820
  Text,
4925
4821
  {
@@ -4934,15 +4830,7 @@ function MesoStatusCard({
4934
4830
  }
4935
4831
  )
4936
4832
  ] }),
4937
- metrics.length > 0 && /* @__PURE__ */ jsx(
4938
- View,
4939
- {
4940
- className: "flex-row flex-wrap",
4941
- style: { gap: 8 },
4942
- testID: "meso-status-card-metrics",
4943
- children: metrics.map((metric, index) => /* @__PURE__ */ jsx(MetricCell2, { metric }, `${metric.label}-${index}`))
4944
- }
4945
- ),
4833
+ metrics.length > 0 && /* @__PURE__ */ jsx(View, { className: "flex-row flex-wrap", style: { gap: 8 }, testID: "meso-status-card-metrics", children: metrics.map((metric, index) => /* @__PURE__ */ jsx(MetricCell2, { metric }, `${metric.label}-${index}`)) }),
4946
4834
  gauges.length > 0 && /* @__PURE__ */ jsx(View, { style: { gap: 12 }, testID: "meso-status-card-gauges", children: gauges.map((gauge, index) => /* @__PURE__ */ jsx(Gauge, { gauge }, `${gauge.label}-${index}`)) }),
4947
4835
  coaching != null && /* @__PURE__ */ jsx(
4948
4836
  View,
@@ -5008,7 +4896,7 @@ function MesoStatusCard({
5008
4896
  );
5009
4897
  }
5010
4898
  var sem = getSemanticColors("dark");
5011
- var BRAND_PRIMARY6 = sem["brand-primary"];
4899
+ var BRAND_PRIMARY5 = sem["brand-primary"];
5012
4900
  var PROJECTION_LINE_COLOR = resolveColor("text-tertiary");
5013
4901
  var STATUS_SUCCESS2 = sem["status-success"];
5014
4902
  var STATUS_ERROR2 = sem["status-error"];
@@ -5021,8 +4909,8 @@ var ERROR_PILL_BORDER = "rgba(209,67,67,0.20)";
5021
4909
  var PLOT_LEFT = 26;
5022
4910
  var TOOLTIP_WIDTH = 124;
5023
4911
  function timeOf(dateStr) {
5024
- const t12 = Date.parse(dateStr);
5025
- return Number.isNaN(t12) ? 0 : t12;
4912
+ const t7 = Date.parse(dateStr);
4913
+ return Number.isNaN(t7) ? 0 : t7;
5026
4914
  }
5027
4915
  function formatValue(value) {
5028
4916
  return `${Math.round(value)}`;
@@ -5063,9 +4951,7 @@ function buildGeometry(data, projection, boundaries, width, height) {
5063
4951
  point,
5064
4952
  index
5065
4953
  }));
5066
- const tickValues = Array.from(
5067
- new Set([yMax, (yMin + yMax) / 2, yMin].map((v) => Math.round(v)))
5068
- );
4954
+ const tickValues = Array.from(new Set([yMax, (yMin + yMax) / 2, yMin].map((v) => Math.round(v))));
5069
4955
  const gridLines = tickValues.map((v) => ({ y: toY(v), label: formatValue(v) }));
5070
4956
  return {
5071
4957
  hasData: true,
@@ -5101,7 +4987,7 @@ function ChartLine({
5101
4987
  dashed,
5102
4988
  testID
5103
4989
  }) {
5104
- return /* @__PURE__ */ jsx(Fragment, { children: coords.map((c2, i) => {
4990
+ return /* @__PURE__ */ jsx(Fragment$1, { children: coords.map((c2, i) => {
5105
4991
  if (i === 0) return null;
5106
4992
  const prev = coords[i - 1];
5107
4993
  const dx = c2.x - prev.x;
@@ -5154,10 +5040,7 @@ function StrengthTrendChart({
5154
5040
  () => buildGeometry(data, projection, mesoBoundaries, width, height),
5155
5041
  [data, projection, mesoBoundaries, width, height]
5156
5042
  );
5157
- const trend = useMemo(
5158
- () => computeTrend(data, mesoBoundaries),
5159
- [data, mesoBoundaries]
5160
- );
5043
+ const trend = useMemo(() => computeTrend(data, mesoBoundaries), [data, mesoBoundaries]);
5161
5044
  const [reveal] = useState(() => new Animated.Value(animateOnMount ? 0 : 1));
5162
5045
  const [selected, setSelected] = useState(null);
5163
5046
  useEffect(() => {
@@ -5194,7 +5077,14 @@ function StrengthTrendChart({
5194
5077
  alignItems: "center",
5195
5078
  justifyContent: "center"
5196
5079
  },
5197
- children: /* @__PURE__ */ jsx(Text, { className: "text-text-tertiary", style: { fontSize: 12, fontFamily: "Inter, sans-serif" }, children: "No strength data yet" })
5080
+ children: /* @__PURE__ */ jsx(
5081
+ Text,
5082
+ {
5083
+ className: "text-text-tertiary",
5084
+ style: { fontSize: 12, fontFamily: "Inter, sans-serif" },
5085
+ children: "No strength data yet"
5086
+ }
5087
+ )
5198
5088
  }
5199
5089
  )
5200
5090
  }
@@ -5205,316 +5095,333 @@ function StrengthTrendChart({
5205
5095
  outputRange: [0, width]
5206
5096
  });
5207
5097
  const selectedCoord = selected != null ? geometry.actual[selected] : void 0;
5208
- return /* @__PURE__ */ jsxs(
5209
- View,
5210
- {
5211
- style: { width },
5212
- className: cn(className),
5213
- testID: "strength-trend-chart",
5214
- ...props,
5215
- children: [
5216
- /* @__PURE__ */ jsxs(View, { style: { width, height, position: "relative" }, children: [
5217
- /* @__PURE__ */ jsxs(
5218
- View,
5219
- {
5220
- style: { position: "absolute", top: 0, left: 0, width, height },
5221
- accessibilityRole: "image",
5222
- accessibilityLabel: ariaLabel,
5223
- testID: "strength-trend-chart-canvas",
5224
- children: [
5225
- geometry.gridLines.map((line, i) => /* @__PURE__ */ jsx(
5226
- View,
5227
- {
5228
- accessibilityElementsHidden: true,
5229
- testID: "strength-trend-chart-gridline",
5230
- style: {
5231
- position: "absolute",
5232
- left: PLOT_LEFT,
5233
- right: 0,
5234
- top: line.y,
5235
- height: 1,
5236
- backgroundColor: GRID_LINE
5237
- },
5238
- children: /* @__PURE__ */ jsx(
5239
- Text,
5240
- {
5241
- className: "text-text-tertiary",
5242
- style: {
5243
- position: "absolute",
5244
- left: -PLOT_LEFT,
5245
- top: -6,
5246
- width: PLOT_LEFT - 4,
5247
- textAlign: "right",
5248
- fontSize: 9,
5249
- fontFamily: "Inter, sans-serif"
5250
- },
5251
- children: line.label
5252
- }
5253
- )
5254
- },
5255
- `grid-${i}`
5256
- )),
5257
- geometry.boundaries.map((boundary, i) => /* @__PURE__ */ jsx(
5258
- View,
5259
- {
5260
- accessibilityElementsHidden: true,
5261
- testID: "strength-trend-chart-meso-boundary",
5262
- style: {
5263
- position: "absolute",
5264
- left: boundary.x,
5265
- top: 0,
5266
- width: 0,
5267
- height,
5268
- borderLeftWidth: 1,
5269
- borderStyle: "dashed",
5270
- borderLeftColor: "rgba(255,255,255,0.10)"
5271
- }
5272
- },
5273
- `boundary-${i}`
5274
- )),
5275
- /* @__PURE__ */ jsx(
5276
- Animated.View,
5098
+ return /* @__PURE__ */ jsxs(View, { style: { width }, className: cn(className), testID: "strength-trend-chart", ...props, children: [
5099
+ /* @__PURE__ */ jsxs(View, { style: { width, height, position: "relative" }, children: [
5100
+ /* @__PURE__ */ jsxs(
5101
+ View,
5102
+ {
5103
+ style: { position: "absolute", top: 0, left: 0, width, height },
5104
+ accessibilityRole: "image",
5105
+ accessibilityLabel: ariaLabel,
5106
+ testID: "strength-trend-chart-canvas",
5107
+ children: [
5108
+ geometry.gridLines.map((line, i) => /* @__PURE__ */ jsx(
5109
+ View,
5110
+ {
5111
+ accessibilityElementsHidden: true,
5112
+ testID: "strength-trend-chart-gridline",
5113
+ style: {
5114
+ position: "absolute",
5115
+ left: PLOT_LEFT,
5116
+ right: 0,
5117
+ top: line.y,
5118
+ height: 1,
5119
+ backgroundColor: GRID_LINE
5120
+ },
5121
+ children: /* @__PURE__ */ jsx(
5122
+ Text,
5277
5123
  {
5124
+ className: "text-text-tertiary",
5278
5125
  style: {
5279
5126
  position: "absolute",
5280
- top: 0,
5281
- left: 0,
5282
- width: revealWidth,
5283
- height,
5284
- overflow: "hidden"
5127
+ left: -PLOT_LEFT,
5128
+ top: -6,
5129
+ width: PLOT_LEFT - 4,
5130
+ textAlign: "right",
5131
+ fontSize: 9,
5132
+ fontFamily: "Inter, sans-serif"
5285
5133
  },
5286
- testID: "strength-trend-chart-reveal",
5287
- children: /* @__PURE__ */ jsxs(View, { style: { width, height, position: "absolute", top: 0, left: 0 }, children: [
5288
- /* @__PURE__ */ jsx(
5289
- ChartLine,
5290
- {
5291
- coords: geometry.projection,
5292
- color: PROJECTION_LINE_COLOR,
5293
- strokeWidth: 2,
5294
- dashed: true,
5295
- testID: "strength-trend-chart-projection-segment"
5296
- }
5297
- ),
5298
- /* @__PURE__ */ jsx(
5299
- ChartLine,
5300
- {
5301
- coords: geometry.actual,
5302
- color: BRAND_PRIMARY6,
5303
- strokeWidth: 2.5,
5304
- testID: "strength-trend-chart-actual-segment"
5305
- }
5306
- )
5307
- ] })
5134
+ children: line.label
5308
5135
  }
5309
- ),
5310
- geometry.actual.map(
5311
- (c2) => c2.point.isPR ? /* @__PURE__ */ jsx(
5312
- Text,
5313
- {
5314
- accessibilityElementsHidden: true,
5315
- testID: "strength-trend-chart-pr-star",
5316
- style: {
5317
- position: "absolute",
5318
- left: c2.x - 7,
5319
- top: c2.y - 20,
5320
- fontSize: 12,
5321
- color: STATUS_WARNING2
5322
- },
5323
- children: "\u2605"
5324
- },
5325
- `star-${c2.index}`
5326
- ) : null
5327
5136
  )
5328
- ]
5329
- }
5330
- ),
5331
- /* @__PURE__ */ jsx(
5332
- View,
5333
- {
5334
- style: { position: "absolute", top: 0, left: 0, width, height },
5335
- testID: "strength-trend-chart-points",
5336
- children: geometry.actual.map((c2) => {
5337
- const label = c2.point.sessionLabel ?? c2.point.date;
5338
- return /* @__PURE__ */ jsx(
5339
- Pressable,
5340
- {
5341
- testID: "strength-trend-chart-point",
5342
- accessibilityRole: "button",
5343
- accessibilityLabel: `${label}: ${formatValue(c2.point.e1rm)} ${unit}${c2.point.isPR ? ", personal record" : ""}`,
5344
- onPress: () => {
5345
- setSelected(c2.index);
5346
- onPointPress?.(c2.point);
5347
- },
5348
- style: {
5349
- position: "absolute",
5350
- left: c2.x - 4,
5351
- top: c2.y - 4,
5352
- width: 8,
5353
- height: 8,
5354
- borderRadius: 1,
5355
- backgroundColor: BRAND_PRIMARY6
5137
+ },
5138
+ `grid-${i}`
5139
+ )),
5140
+ geometry.boundaries.map((boundary, i) => /* @__PURE__ */ jsx(
5141
+ View,
5142
+ {
5143
+ accessibilityElementsHidden: true,
5144
+ testID: "strength-trend-chart-meso-boundary",
5145
+ style: {
5146
+ position: "absolute",
5147
+ left: boundary.x,
5148
+ top: 0,
5149
+ width: 0,
5150
+ height,
5151
+ borderLeftWidth: 1,
5152
+ borderStyle: "dashed",
5153
+ borderLeftColor: "rgba(255,255,255,0.10)"
5154
+ }
5155
+ },
5156
+ `boundary-${i}`
5157
+ )),
5158
+ /* @__PURE__ */ jsx(
5159
+ Animated.View,
5160
+ {
5161
+ style: {
5162
+ position: "absolute",
5163
+ top: 0,
5164
+ left: 0,
5165
+ width: revealWidth,
5166
+ height,
5167
+ overflow: "hidden"
5168
+ },
5169
+ testID: "strength-trend-chart-reveal",
5170
+ children: /* @__PURE__ */ jsxs(View, { style: { width, height, position: "absolute", top: 0, left: 0 }, children: [
5171
+ /* @__PURE__ */ jsx(
5172
+ ChartLine,
5173
+ {
5174
+ coords: geometry.projection,
5175
+ color: PROJECTION_LINE_COLOR,
5176
+ strokeWidth: 2,
5177
+ dashed: true,
5178
+ testID: "strength-trend-chart-projection-segment"
5356
5179
  }
5180
+ ),
5181
+ /* @__PURE__ */ jsx(
5182
+ ChartLine,
5183
+ {
5184
+ coords: geometry.actual,
5185
+ color: BRAND_PRIMARY5,
5186
+ strokeWidth: 2.5,
5187
+ testID: "strength-trend-chart-actual-segment"
5188
+ }
5189
+ )
5190
+ ] })
5191
+ }
5192
+ ),
5193
+ geometry.actual.map(
5194
+ (c2) => c2.point.isPR ? /* @__PURE__ */ jsx(
5195
+ Text,
5196
+ {
5197
+ accessibilityElementsHidden: true,
5198
+ testID: "strength-trend-chart-pr-star",
5199
+ style: {
5200
+ position: "absolute",
5201
+ left: c2.x - 7,
5202
+ top: c2.y - 20,
5203
+ fontSize: 12,
5204
+ color: STATUS_WARNING2
5357
5205
  },
5358
- `point-${c2.index}`
5359
- );
5360
- })
5361
- }
5362
- ),
5363
- selectedCoord && /* @__PURE__ */ jsxs(
5364
- View,
5365
- {
5366
- testID: "strength-trend-chart-tooltip",
5367
- accessibilityElementsHidden: true,
5368
- className: "bg-surface-elevated border-hairline-strong",
5369
- style: {
5370
- position: "absolute",
5371
- left: Math.max(
5372
- 0,
5373
- Math.min(width - TOOLTIP_WIDTH, selectedCoord.x - TOOLTIP_WIDTH / 2)
5374
- ),
5375
- top: Math.max(0, selectedCoord.y - 52),
5376
- maxWidth: TOOLTIP_WIDTH,
5377
- borderWidth: 1,
5378
- borderRadius: 8,
5379
- paddingVertical: 8,
5380
- paddingHorizontal: 10
5206
+ children: "\u2605"
5207
+ },
5208
+ `star-${c2.index}`
5209
+ ) : null
5210
+ )
5211
+ ]
5212
+ }
5213
+ ),
5214
+ /* @__PURE__ */ jsx(
5215
+ View,
5216
+ {
5217
+ style: { position: "absolute", top: 0, left: 0, width, height },
5218
+ testID: "strength-trend-chart-points",
5219
+ children: geometry.actual.map((c2) => {
5220
+ const label = c2.point.sessionLabel ?? c2.point.date;
5221
+ return /* @__PURE__ */ jsx(
5222
+ Pressable,
5223
+ {
5224
+ testID: "strength-trend-chart-point",
5225
+ accessibilityRole: "button",
5226
+ accessibilityLabel: `${label}: ${formatValue(c2.point.e1rm)} ${unit}${c2.point.isPR ? ", personal record" : ""}`,
5227
+ onPress: () => {
5228
+ setSelected(c2.index);
5229
+ onPointPress?.(c2.point);
5230
+ },
5231
+ style: {
5232
+ position: "absolute",
5233
+ left: c2.x - 4,
5234
+ top: c2.y - 4,
5235
+ width: 8,
5236
+ height: 8,
5237
+ borderRadius: 1,
5238
+ backgroundColor: BRAND_PRIMARY5
5239
+ }
5381
5240
  },
5382
- children: [
5383
- /* @__PURE__ */ jsx(
5384
- Text,
5385
- {
5386
- className: "text-text-tertiary",
5387
- style: {
5388
- fontSize: 10,
5389
- fontFamily: "Inter, sans-serif"
5390
- },
5391
- children: selectedCoord.point.sessionLabel ?? selectedCoord.point.date
5392
- }
5393
- ),
5394
- /* @__PURE__ */ jsx(
5395
- Text,
5396
- {
5397
- className: "text-text-primary",
5398
- style: {
5399
- marginTop: 2,
5400
- fontSize: 13,
5401
- fontFamily: "Inter, sans-serif",
5402
- fontWeight: "700"
5403
- },
5404
- children: `${formatValue(selectedCoord.point.e1rm)} ${unit}`
5405
- }
5406
- ),
5407
- selected != null && selected > 0 && /* @__PURE__ */ jsx(
5408
- Text,
5409
- {
5410
- style: {
5411
- marginTop: 1,
5412
- fontSize: 10,
5413
- fontFamily: "Inter, sans-serif",
5414
- color: selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? STATUS_SUCCESS2 : STATUS_ERROR2
5415
- },
5416
- children: `${selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? "+" : "-"}${Math.abs(
5417
- selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm
5418
- ).toFixed(1)} ${unit}`
5419
- }
5420
- )
5421
- ]
5422
- }
5423
- )
5424
- ] }),
5425
- geometry.boundaries.length > 0 && /* @__PURE__ */ jsx(
5426
- View,
5427
- {
5428
- style: { width, height: 14, position: "relative", marginTop: 2 },
5429
- accessibilityElementsHidden: true,
5430
- testID: "strength-trend-chart-axis",
5431
- children: geometry.boundaries.map((boundary, i) => /* @__PURE__ */ jsx(
5241
+ `point-${c2.index}`
5242
+ );
5243
+ })
5244
+ }
5245
+ ),
5246
+ selectedCoord && /* @__PURE__ */ jsxs(
5247
+ View,
5248
+ {
5249
+ testID: "strength-trend-chart-tooltip",
5250
+ accessibilityElementsHidden: true,
5251
+ className: "bg-surface-elevated border-hairline-strong",
5252
+ style: {
5253
+ position: "absolute",
5254
+ left: Math.max(
5255
+ 0,
5256
+ Math.min(width - TOOLTIP_WIDTH, selectedCoord.x - TOOLTIP_WIDTH / 2)
5257
+ ),
5258
+ top: Math.max(0, selectedCoord.y - 52),
5259
+ maxWidth: TOOLTIP_WIDTH,
5260
+ borderWidth: 1,
5261
+ borderRadius: 8,
5262
+ paddingVertical: 8,
5263
+ paddingHorizontal: 10
5264
+ },
5265
+ children: [
5266
+ /* @__PURE__ */ jsx(
5432
5267
  Text,
5433
5268
  {
5434
- testID: "strength-trend-chart-axis-label",
5435
5269
  className: "text-text-tertiary",
5436
5270
  style: {
5437
- position: "absolute",
5438
- left: boundary.x - 24,
5439
- width: 48,
5440
- textAlign: "center",
5441
5271
  fontSize: 10,
5442
5272
  fontFamily: "Inter, sans-serif"
5443
5273
  },
5444
- children: boundary.label
5445
- },
5446
- `axis-${i}`
5447
- ))
5448
- }
5449
- ),
5450
- /* @__PURE__ */ jsx(View, { className: "flex-row", style: { marginTop: 8 }, children: /* @__PURE__ */ jsx(
5451
- View,
5452
- {
5453
- testID: "strength-trend-chart-trend-pill",
5454
- accessibilityLabel: `Strength trend: ${trendText}`,
5455
- style: {
5456
- paddingVertical: 3,
5457
- paddingHorizontal: 8,
5458
- borderRadius: 4,
5459
- borderWidth: 1,
5460
- backgroundColor: trend.positive ? SUCCESS_PILL_BG : ERROR_PILL_BG,
5461
- borderColor: trend.positive ? SUCCESS_PILL_BORDER : ERROR_PILL_BORDER
5462
- },
5463
- children: /* @__PURE__ */ jsx(
5274
+ children: selectedCoord.point.sessionLabel ?? selectedCoord.point.date
5275
+ }
5276
+ ),
5277
+ /* @__PURE__ */ jsx(
5278
+ Text,
5279
+ {
5280
+ className: "text-text-primary",
5281
+ style: {
5282
+ marginTop: 2,
5283
+ fontSize: 13,
5284
+ fontFamily: "Inter, sans-serif",
5285
+ fontWeight: "700"
5286
+ },
5287
+ children: `${formatValue(selectedCoord.point.e1rm)} ${unit}`
5288
+ }
5289
+ ),
5290
+ selected != null && selected > 0 && /* @__PURE__ */ jsx(
5464
5291
  Text,
5465
5292
  {
5466
5293
  style: {
5467
- fontSize: 11,
5294
+ marginTop: 1,
5295
+ fontSize: 10,
5468
5296
  fontFamily: "Inter, sans-serif",
5469
- fontWeight: "600",
5470
- color: trend.positive ? STATUS_SUCCESS2 : STATUS_ERROR2
5297
+ color: selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? STATUS_SUCCESS2 : STATUS_ERROR2
5471
5298
  },
5472
- children: trendText
5299
+ children: `${selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? "+" : "-"}${Math.abs(
5300
+ selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm
5301
+ ).toFixed(1)} ${unit}`
5473
5302
  }
5474
5303
  )
5475
- }
5476
- ) }),
5477
- /* @__PURE__ */ jsxs(
5478
- View,
5304
+ ]
5305
+ }
5306
+ )
5307
+ ] }),
5308
+ geometry.boundaries.length > 0 && /* @__PURE__ */ jsx(
5309
+ View,
5310
+ {
5311
+ style: { width, height: 14, position: "relative", marginTop: 2 },
5312
+ accessibilityElementsHidden: true,
5313
+ testID: "strength-trend-chart-axis",
5314
+ children: geometry.boundaries.map((boundary, i) => /* @__PURE__ */ jsx(
5315
+ Text,
5479
5316
  {
5480
- className: "flex-row items-center",
5481
- style: { marginTop: 8, gap: 14 },
5482
- testID: "strength-trend-chart-legend",
5483
- children: [
5484
- /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 5 }, children: [
5485
- /* @__PURE__ */ jsx(View, { style: { width: 14, height: 2.5, borderRadius: 1.5, backgroundColor: BRAND_PRIMARY6 } }),
5486
- /* @__PURE__ */ jsx(Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "Actual" })
5487
- ] }),
5488
- /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 5 }, children: [
5489
- /* @__PURE__ */ jsx(
5490
- View,
5491
- {
5492
- style: {
5493
- width: 14,
5494
- height: 0,
5495
- borderTopWidth: 2,
5496
- borderStyle: "dashed",
5497
- borderTopColor: PROJECTION_LINE_COLOR
5498
- }
5499
- }
5500
- ),
5501
- /* @__PURE__ */ jsx(Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "Projected" })
5502
- ] }),
5503
- /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 5 }, children: [
5504
- /* @__PURE__ */ jsx(Text, { style: { fontSize: 12, color: STATUS_WARNING2 }, children: "\u2605" }),
5505
- /* @__PURE__ */ jsx(Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "PR" })
5506
- ] })
5507
- ]
5317
+ testID: "strength-trend-chart-axis-label",
5318
+ className: "text-text-tertiary",
5319
+ style: {
5320
+ position: "absolute",
5321
+ left: boundary.x - 24,
5322
+ width: 48,
5323
+ textAlign: "center",
5324
+ fontSize: 10,
5325
+ fontFamily: "Inter, sans-serif"
5326
+ },
5327
+ children: boundary.label
5328
+ },
5329
+ `axis-${i}`
5330
+ ))
5331
+ }
5332
+ ),
5333
+ /* @__PURE__ */ jsx(View, { className: "flex-row", style: { marginTop: 8 }, children: /* @__PURE__ */ jsx(
5334
+ View,
5335
+ {
5336
+ testID: "strength-trend-chart-trend-pill",
5337
+ accessibilityLabel: `Strength trend: ${trendText}`,
5338
+ style: {
5339
+ paddingVertical: 3,
5340
+ paddingHorizontal: 8,
5341
+ borderRadius: 4,
5342
+ borderWidth: 1,
5343
+ backgroundColor: trend.positive ? SUCCESS_PILL_BG : ERROR_PILL_BG,
5344
+ borderColor: trend.positive ? SUCCESS_PILL_BORDER : ERROR_PILL_BORDER
5345
+ },
5346
+ children: /* @__PURE__ */ jsx(
5347
+ Text,
5348
+ {
5349
+ style: {
5350
+ fontSize: 11,
5351
+ fontFamily: "Inter, sans-serif",
5352
+ fontWeight: "600",
5353
+ color: trend.positive ? STATUS_SUCCESS2 : STATUS_ERROR2
5354
+ },
5355
+ children: trendText
5508
5356
  }
5509
5357
  )
5510
- ]
5511
- }
5512
- );
5358
+ }
5359
+ ) }),
5360
+ /* @__PURE__ */ jsxs(
5361
+ View,
5362
+ {
5363
+ className: "flex-row items-center",
5364
+ style: { marginTop: 8, gap: 14 },
5365
+ testID: "strength-trend-chart-legend",
5366
+ children: [
5367
+ /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 5 }, children: [
5368
+ /* @__PURE__ */ jsx(
5369
+ View,
5370
+ {
5371
+ style: { width: 14, height: 2.5, borderRadius: 1.5, backgroundColor: BRAND_PRIMARY5 }
5372
+ }
5373
+ ),
5374
+ /* @__PURE__ */ jsx(
5375
+ Text,
5376
+ {
5377
+ className: "text-text-secondary",
5378
+ style: { fontSize: 10, fontFamily: "Inter, sans-serif" },
5379
+ children: "Actual"
5380
+ }
5381
+ )
5382
+ ] }),
5383
+ /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 5 }, children: [
5384
+ /* @__PURE__ */ jsx(
5385
+ View,
5386
+ {
5387
+ style: {
5388
+ width: 14,
5389
+ height: 0,
5390
+ borderTopWidth: 2,
5391
+ borderStyle: "dashed",
5392
+ borderTopColor: PROJECTION_LINE_COLOR
5393
+ }
5394
+ }
5395
+ ),
5396
+ /* @__PURE__ */ jsx(
5397
+ Text,
5398
+ {
5399
+ className: "text-text-secondary",
5400
+ style: { fontSize: 10, fontFamily: "Inter, sans-serif" },
5401
+ children: "Projected"
5402
+ }
5403
+ )
5404
+ ] }),
5405
+ /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 5 }, children: [
5406
+ /* @__PURE__ */ jsx(Text, { style: { fontSize: 12, color: STATUS_WARNING2 }, children: "\u2605" }),
5407
+ /* @__PURE__ */ jsx(
5408
+ Text,
5409
+ {
5410
+ className: "text-text-secondary",
5411
+ style: { fontSize: 10, fontFamily: "Inter, sans-serif" },
5412
+ children: "PR"
5413
+ }
5414
+ )
5415
+ ] })
5416
+ ]
5417
+ }
5418
+ )
5419
+ ] });
5513
5420
  }
5514
- var t7 = getSemanticColors("dark");
5515
- var STATUS_SUCCESS3 = t7["status-success"];
5516
- var STATUS_WARNING3 = t7["status-warning"];
5517
- var STATUS_INFO = t7["status-info"];
5421
+ var t4 = getSemanticColors("dark");
5422
+ var STATUS_SUCCESS3 = t4["status-success"];
5423
+ var STATUS_WARNING3 = t4["status-warning"];
5424
+ var STATUS_INFO = t4["status-info"];
5518
5425
  var DOT_BORDER = "#F3F4F6";
5519
5426
  var BAND_FILL = "rgba(46,213,115,0.1)";
5520
5427
  var BAND_EDGE = "rgba(46,213,115,0.45)";
@@ -5557,8 +5464,8 @@ function interpEdge(pixels, x, key) {
5557
5464
  const a = pixels[i];
5558
5465
  const b = pixels[i + 1];
5559
5466
  if (x >= a.x && x <= b.x) {
5560
- const t12 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
5561
- return a[key] + t12 * (b[key] - a[key]);
5467
+ const t7 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
5468
+ return a[key] + t7 * (b[key] - a[key]);
5562
5469
  }
5563
5470
  }
5564
5471
  return pixels[pixels.length - 1][key];
@@ -5744,18 +5651,53 @@ function CapacityBandChart({
5744
5651
  /* @__PURE__ */ jsx(
5745
5652
  Animated.View,
5746
5653
  {
5747
- style: { position: "absolute", top: 0, left: 0, height, width: revealWidth, overflow: "hidden" },
5654
+ style: {
5655
+ position: "absolute",
5656
+ top: 0,
5657
+ left: 0,
5658
+ height,
5659
+ width: revealWidth,
5660
+ overflow: "hidden"
5661
+ },
5748
5662
  accessibilityElementsHidden: true,
5749
5663
  importantForAccessibility: "no-hide-descendants",
5750
5664
  testID: "capacity-band-chart-reveal",
5751
5665
  children: /* @__PURE__ */ jsxs(View, { style: { width, height, position: "relative" }, children: [
5752
5666
  projection && /* @__PURE__ */ jsxs(View, { testID: "capacity-band-chart-projection", children: [
5753
- renderColumns(buildColumns2(trainingPixels, COLUMN_STEP), PROJECTION_FILL, "capacity-band-chart-projection-fill"),
5754
- renderColumns(buildColumns2(restPixels, COLUMN_STEP), PROJECTION_FILL, "capacity-band-chart-projection-fill"),
5755
- renderEdges(buildEdges(trainingPixels, "yHigh"), STATUS_SUCCESS3, true, "capacity-band-chart-projection-training"),
5756
- renderEdges(buildEdges(trainingPixels, "yLow"), STATUS_SUCCESS3, true, "capacity-band-chart-projection-training"),
5757
- renderEdges(buildEdges(restPixels, "yHigh"), STATUS_INFO, true, "capacity-band-chart-projection-rest"),
5758
- renderEdges(buildEdges(restPixels, "yLow"), STATUS_INFO, true, "capacity-band-chart-projection-rest"),
5667
+ renderColumns(
5668
+ buildColumns2(trainingPixels, COLUMN_STEP),
5669
+ PROJECTION_FILL,
5670
+ "capacity-band-chart-projection-fill"
5671
+ ),
5672
+ renderColumns(
5673
+ buildColumns2(restPixels, COLUMN_STEP),
5674
+ PROJECTION_FILL,
5675
+ "capacity-band-chart-projection-fill"
5676
+ ),
5677
+ renderEdges(
5678
+ buildEdges(trainingPixels, "yHigh"),
5679
+ STATUS_SUCCESS3,
5680
+ true,
5681
+ "capacity-band-chart-projection-training"
5682
+ ),
5683
+ renderEdges(
5684
+ buildEdges(trainingPixels, "yLow"),
5685
+ STATUS_SUCCESS3,
5686
+ true,
5687
+ "capacity-band-chart-projection-training"
5688
+ ),
5689
+ renderEdges(
5690
+ buildEdges(restPixels, "yHigh"),
5691
+ STATUS_INFO,
5692
+ true,
5693
+ "capacity-band-chart-projection-rest"
5694
+ ),
5695
+ renderEdges(
5696
+ buildEdges(restPixels, "yLow"),
5697
+ STATUS_INFO,
5698
+ true,
5699
+ "capacity-band-chart-projection-rest"
5700
+ ),
5759
5701
  /* @__PURE__ */ jsx(
5760
5702
  Text,
5761
5703
  {
@@ -5890,7 +5832,7 @@ function CapacityBandChart({
5890
5832
  }
5891
5833
 
5892
5834
  // src/components/custom/Workout/ExerciseDetailPage.tsx
5893
- var BRAND_PRIMARY7 = getSemanticColors("dark")["brand-primary"];
5835
+ var BRAND_PRIMARY6 = getSemanticColors("dark")["brand-primary"];
5894
5836
  var CHART_WIDTH = 326;
5895
5837
  var CHART_HEIGHT = 150;
5896
5838
  var EXERCISE_DETAIL_TABS = [
@@ -5953,7 +5895,7 @@ function TabBar({ active, onSelect }) {
5953
5895
  alignItems: "center",
5954
5896
  paddingVertical: 10,
5955
5897
  borderBottomWidth: 2,
5956
- borderBottomColor: isActive ? BRAND_PRIMARY7 : "transparent"
5898
+ borderBottomColor: isActive ? BRAND_PRIMARY6 : "transparent"
5957
5899
  },
5958
5900
  testID: `exercise-detail-page-tab-${key}`,
5959
5901
  children: /* @__PURE__ */ jsx(
@@ -6284,7 +6226,7 @@ function ExerciseDetailPage({
6284
6226
  fontSize: 15,
6285
6227
  fontFamily: '"Space Grotesk", sans-serif',
6286
6228
  fontWeight: "700",
6287
- color: BRAND_PRIMARY7
6229
+ color: BRAND_PRIMARY6
6288
6230
  },
6289
6231
  children: `${exercise.currentE1rm} ${exercise.unit}`
6290
6232
  }
@@ -6350,11 +6292,10 @@ function ExerciseDetailPage({
6350
6292
  }
6351
6293
  );
6352
6294
  }
6353
- var BRAND_PRIMARY8 = getSemanticColors("dark")["brand-primary"];
6354
- var segmentBgColors = {
6355
- completed: "rgba(46,213,115,0.3)",
6356
- current: "rgba(255,121,0,0.5)",
6357
- upcoming: "rgba(255,255,255,0.06)"
6295
+ var segmentTrackToken = {
6296
+ completed: "status-success-muted",
6297
+ current: "brand-primary-strong",
6298
+ upcoming: "hairline-subtle"
6358
6299
  };
6359
6300
  function clampProgress(currentWeek, weekCount) {
6360
6301
  if (currentWeek == null || weekCount <= 0) return 0;
@@ -6363,6 +6304,7 @@ function clampProgress(currentWeek, weekCount) {
6363
6304
  }
6364
6305
  function MesoSegment({ meso, isActive, onPress }) {
6365
6306
  const [pressScale] = useState(() => new Animated.Value(1));
6307
+ const brandPrimary = resolveColor("brand-primary");
6366
6308
  const handlePressIn = () => {
6367
6309
  Animated.timing(pressScale, {
6368
6310
  toValue: 0.98,
@@ -6397,12 +6339,12 @@ function MesoSegment({ meso, isActive, onPress }) {
6397
6339
  height: 8,
6398
6340
  borderRadius: 4,
6399
6341
  overflow: "hidden",
6400
- backgroundColor: segmentBgColors[meso.status],
6342
+ backgroundColor: resolveColor(segmentTrackToken[meso.status]),
6401
6343
  transform: [{ scale: pressScale }]
6402
6344
  },
6403
6345
  isActive ? {
6404
6346
  borderWidth: 2,
6405
- borderColor: BRAND_PRIMARY8,
6347
+ borderColor: brandPrimary,
6406
6348
  transform: [{ scale: 1.02 }, { scale: pressScale }]
6407
6349
  } : void 0
6408
6350
  ],
@@ -6416,7 +6358,7 @@ function MesoSegment({ meso, isActive, onPress }) {
6416
6358
  top: 0,
6417
6359
  bottom: 0,
6418
6360
  width: `${progress * 100}%`,
6419
- backgroundColor: BRAND_PRIMARY8
6361
+ backgroundColor: brandPrimary
6420
6362
  },
6421
6363
  testID: `meso-segment-fill-${meso.id}`
6422
6364
  }
@@ -6463,7 +6405,7 @@ var sizeStyles = {
6463
6405
  md: "w-2 h-2",
6464
6406
  lg: "w-2.5 h-2.5"
6465
6407
  };
6466
- var colorStyles = {
6408
+ var colorStyles2 = {
6467
6409
  default: "bg-text-tertiary",
6468
6410
  primary: "bg-brand-primary",
6469
6411
  success: "bg-status-success",
@@ -6473,6 +6415,17 @@ var colorStyles = {
6473
6415
  info: "bg-status-info",
6474
6416
  "error-vivid": "bg-status-error-vivid"
6475
6417
  };
6418
+ var t5 = getSemanticColors("dark");
6419
+ var glowColors2 = {
6420
+ default: greyRamp[500],
6421
+ primary: t5["brand-primary"],
6422
+ success: t5["status-success"],
6423
+ live: t5["status-live"],
6424
+ error: t5["status-error"],
6425
+ warning: t5["status-warning"],
6426
+ info: t5["status-info"],
6427
+ "error-vivid": t5["status-error-vivid"]
6428
+ };
6476
6429
  function Indicator({
6477
6430
  size = "sm",
6478
6431
  color = "default",
@@ -6485,7 +6438,7 @@ function Indicator({
6485
6438
  ...props
6486
6439
  }) {
6487
6440
  const pulseMode = pulse === true ? "opacity" : pulse || false;
6488
- const colorClass = !customColor ? colorStyles[color] : void 0;
6441
+ const colorClass = !customColor ? colorStyles2[color] : void 0;
6489
6442
  const colorStyle = customColor ? { backgroundColor: customColor } : void 0;
6490
6443
  if (pulseMode === "ping") {
6491
6444
  return /* @__PURE__ */ jsxs(View, { className: cn("relative", sizeStyles[size], className), style, ...props, children: [
@@ -6510,11 +6463,7 @@ function Indicator({
6510
6463
  )
6511
6464
  ] });
6512
6465
  }
6513
- const dynamicStyle = {
6514
- ...typeof style === "object" ? style : {},
6515
- ...colorStyle ?? {},
6516
- ...glow && customColor ? { boxShadow: `0 0 6px ${customColor}` } : {}
6517
- };
6466
+ const glowStyle = glow ? getGlowShadow(customColor ?? glowColors2[color], "subtle") : null;
6518
6467
  return /* @__PURE__ */ jsx(
6519
6468
  View,
6520
6469
  {
@@ -6524,54 +6473,165 @@ function Indicator({
6524
6473
  colorClass,
6525
6474
  pulseMode === "opacity" && "animate-pulse",
6526
6475
  ring && "border-2 border-background-base",
6527
- glow && !customColor && (color === "success" || color === "live") && "shadow-[0_0_6px_rgba(46,213,115,0.6)]",
6528
- glow && !customColor && color === "error" && "shadow-[0_0_6px_rgba(239,68,68,0.6)]",
6529
- glow && !customColor && color === "warning" && "shadow-[0_0_6px_rgba(245,158,11,0.6)]",
6530
- glow && !customColor && color === "primary" && "shadow-[0_0_6px_rgba(255,121,0,0.6)]",
6531
- glow && !customColor && color === "error-vivid" && "shadow-[0_0_6px_rgba(255,71,87,0.6)]",
6532
6476
  className
6533
6477
  ),
6534
- style: Object.keys(dynamicStyle).length > 0 ? dynamicStyle : style,
6478
+ style: [style, colorStyle, glowStyle],
6535
6479
  ...props
6536
6480
  }
6537
6481
  );
6538
6482
  }
6539
-
6540
- // src/components/ui/badge/Badge.tsx
6541
- var variantColorStyles = {
6483
+ var colorToTone = {
6484
+ default: "neutral",
6485
+ primary: "brand",
6486
+ secondary: "brand-secondary",
6487
+ success: "success",
6488
+ error: "error",
6489
+ warning: "warning",
6490
+ info: "info"
6491
+ };
6492
+ var toneStyles = {
6542
6493
  solid: {
6543
- default: "bg-hairline-strong text-text-inverse",
6544
- primary: "bg-brand-primary text-text-inverse",
6545
- secondary: "bg-brand-secondary text-text-inverse",
6546
- success: "bg-status-success text-text-inverse",
6547
- error: "bg-status-error text-text-inverse",
6548
- warning: "bg-status-warning text-text-inverse",
6549
- info: "bg-status-info text-text-inverse"
6494
+ neutral: "bg-hairline-strong border-transparent text-text-inverse",
6495
+ brand: "bg-brand-primary border-transparent text-text-inverse",
6496
+ "brand-secondary": "bg-brand-secondary border-transparent text-text-inverse",
6497
+ success: "bg-status-success border-transparent text-text-inverse",
6498
+ warning: "bg-status-warning border-transparent text-text-inverse",
6499
+ error: "bg-status-error border-transparent text-text-inverse",
6500
+ info: "bg-status-info border-transparent text-text-inverse"
6550
6501
  },
6551
6502
  subtle: {
6552
- default: "bg-surface-raised text-text-secondary",
6553
- primary: "bg-brand-primary-subtle text-brand-primary",
6554
- secondary: "bg-brand-secondary-subtle text-brand-secondary",
6555
- success: "bg-status-success-subtle text-status-success",
6556
- error: "bg-status-error-subtle text-status-error",
6557
- warning: "bg-status-warning-subtle text-status-warning",
6558
- info: "bg-status-info-subtle text-status-info"
6503
+ // Alpha-white rather than a ramp step: a pill sits on whatever plane its
6504
+ // host is, and an alpha fill composites by the same amount on all of them.
6505
+ // A `surface-*` fill would vanish on the plane it names. Borderless like the
6506
+ // six coloured tones — the fill carries the capsule, not a ring.
6507
+ neutral: "bg-hairline-subtle border-transparent text-text-secondary",
6508
+ brand: "bg-brand-primary-subtle border-transparent text-brand-primary",
6509
+ "brand-secondary": "bg-brand-secondary-subtle border-transparent text-brand-secondary",
6510
+ success: "bg-status-success-subtle border-transparent text-status-success",
6511
+ warning: "bg-status-warning-subtle border-transparent text-status-warning",
6512
+ error: "bg-status-error-subtle border-transparent text-status-error",
6513
+ info: "bg-status-info-subtle border-transparent text-status-info"
6559
6514
  },
6560
6515
  outline: {
6561
- default: "border border-hairline-strong text-text-secondary",
6562
- primary: "border border-brand-primary text-brand-primary",
6563
- secondary: "border border-brand-secondary text-brand-secondary",
6564
- success: "border border-status-success text-status-success",
6565
- error: "border border-status-error text-status-error",
6566
- warning: "border border-status-warning text-status-warning",
6567
- info: "border border-status-info text-status-info"
6516
+ neutral: "border-hairline text-text-secondary",
6517
+ brand: "border-brand-primary text-brand-primary",
6518
+ "brand-secondary": "border-brand-secondary text-brand-secondary",
6519
+ success: "border-status-success text-status-success",
6520
+ warning: "border-status-warning text-status-warning",
6521
+ error: "border-status-error text-status-error",
6522
+ info: "border-status-info text-status-info"
6568
6523
  }
6569
6524
  };
6525
+ var dotToneStyles = {
6526
+ neutral: "bg-text-tertiary",
6527
+ brand: "bg-brand-primary",
6528
+ "brand-secondary": "bg-brand-secondary",
6529
+ success: "bg-status-success",
6530
+ warning: "bg-status-warning",
6531
+ error: "bg-status-error",
6532
+ info: "bg-status-info"
6533
+ };
6570
6534
  var sizeStyles2 = {
6571
- sm: "px-1.5 py-0.5 text-xs",
6572
- md: "px-2 py-0.5 text-xs",
6573
- lg: "px-2.5 py-1 text-sm"
6535
+ xs: { container: "px-1 py-px", text: "text-3xs" },
6536
+ sm: { container: "px-2 py-0.5", text: "text-2xs" },
6537
+ md: { container: "px-2.5 py-1", text: "text-xs" },
6538
+ lg: { container: "px-3 py-1.5", text: "text-sm" },
6539
+ xl: { container: "px-4 py-2", text: "text-base" }
6540
+ };
6541
+ function PillDot({ tone, testID }) {
6542
+ return /* @__PURE__ */ jsx(
6543
+ View,
6544
+ {
6545
+ className: cn("w-1.5 h-1.5 rounded-full shrink-0", dotToneStyles[tone]),
6546
+ accessibilityElementsHidden: true,
6547
+ testID: testID ? `${testID}-dot` : "pill-dot"
6548
+ }
6549
+ );
6550
+ }
6551
+ function containerClasses(p, tone) {
6552
+ return cn(
6553
+ "flex-row items-center gap-1 border self-start shrink-0",
6554
+ p.rounded === false ? "rounded" : "rounded-full",
6555
+ toneStyles[p.variant ?? "subtle"][tone],
6556
+ sizeStyles2[p.size ?? "sm"].container,
6557
+ p.isDisabled && "opacity-50",
6558
+ p.className
6559
+ );
6560
+ }
6561
+ function PillContent({ tone, ...p }) {
6562
+ const textClasses = cn(
6563
+ "font-heading font-semibold text-inherit",
6564
+ sizeStyles2[p.size ?? "sm"].text,
6565
+ p.textClassName
6566
+ );
6567
+ const slot = p.leading ?? p.leftElement;
6568
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
6569
+ slot === "dot" ? /* @__PURE__ */ jsx(PillDot, { tone: p.dotTone ?? tone, testID: p.testID }) : slot,
6570
+ typeof p.children === "string" ? /* @__PURE__ */ jsx(Text, { className: textClasses, children: p.children }) : p.children,
6571
+ p.trailing
6572
+ ] });
6573
+ }
6574
+ function Pill(props) {
6575
+ const {
6576
+ variant,
6577
+ tone,
6578
+ color,
6579
+ size,
6580
+ rounded,
6581
+ leading,
6582
+ dotTone: dotTone2,
6583
+ leftElement,
6584
+ trailing,
6585
+ onPress,
6586
+ isDisabled,
6587
+ className,
6588
+ textClassName,
6589
+ children,
6590
+ ...viewProps
6591
+ } = props;
6592
+ const resolvedTone = tone ?? (color ? colorToTone[color] : "neutral");
6593
+ const classes = containerClasses(props, resolvedTone);
6594
+ const content = /* @__PURE__ */ jsx(PillContent, { ...props, tone: resolvedTone });
6595
+ if (onPress) {
6596
+ return /* @__PURE__ */ jsx(
6597
+ Pressable,
6598
+ {
6599
+ onPress,
6600
+ disabled: isDisabled,
6601
+ accessibilityRole: "button",
6602
+ className: classes,
6603
+ ...viewProps,
6604
+ children: content
6605
+ }
6606
+ );
6607
+ }
6608
+ return /* @__PURE__ */ jsx(View, { className: classes, ...viewProps, children: content });
6609
+ }
6610
+
6611
+ // src/components/ui/badge/Badge.tsx
6612
+ var colorToTone2 = {
6613
+ default: "neutral",
6614
+ primary: "brand",
6615
+ secondary: "brand-secondary",
6616
+ success: "success",
6617
+ error: "error",
6618
+ warning: "warning",
6619
+ info: "info"
6574
6620
  };
6621
+ var sizeStyles3 = {
6622
+ sm: "px-1.5 py-0.5",
6623
+ md: "px-2 py-0.5",
6624
+ lg: "px-2.5 py-1"
6625
+ };
6626
+ var textSizeStyles = {
6627
+ sm: "text-xs",
6628
+ md: "text-xs",
6629
+ lg: "text-sm"
6630
+ };
6631
+ function dotIndicatorColor(color, dotColor) {
6632
+ if (dotColor) return dotColor;
6633
+ return color === "default" || color === "secondary" ? "default" : color;
6634
+ }
6575
6635
  function Badge({
6576
6636
  variant = "subtle",
6577
6637
  color = "default",
@@ -6582,56 +6642,62 @@ function Badge({
6582
6642
  children,
6583
6643
  ...props
6584
6644
  }) {
6585
- return /* @__PURE__ */ jsxs(
6586
- View,
6645
+ return /* @__PURE__ */ jsx(
6646
+ Pill,
6587
6647
  {
6648
+ variant,
6649
+ tone: colorToTone2[color],
6650
+ leading: dot ? /* @__PURE__ */ jsx(Indicator, { size: "xs", color: dotIndicatorColor(color, dotColor), className: "mr-0.5" }) : void 0,
6588
6651
  className: cn(
6589
- "inline-flex items-center justify-center rounded-full font-medium",
6590
- variantColorStyles[variant][color],
6591
- sizeStyles2[size],
6652
+ "justify-center self-auto gap-0",
6653
+ variant === "outline" ? "border" : "border-0",
6654
+ sizeStyles3[size],
6592
6655
  className
6593
6656
  ),
6657
+ textClassName: cn("font-sans font-medium", textSizeStyles[size]),
6594
6658
  ...props,
6595
- children: [
6596
- dot && /* @__PURE__ */ jsx(
6597
- Indicator,
6598
- {
6599
- size: "xs",
6600
- color: dotColor ?? (color === "default" || color === "secondary" ? "default" : color),
6601
- className: "mr-0.5"
6602
- }
6603
- ),
6604
- typeof children === "string" ? /* @__PURE__ */ jsx(Text, { className: "text-inherit font-medium", children }) : children
6605
- ]
6659
+ children
6606
6660
  }
6607
6661
  );
6608
6662
  }
6609
- var HAIRLINE_DEFAULT = getSemanticColors("dark")["hairline-default"];
6610
- var t8 = getSemanticColors("dark");
6611
- var statusBgColors = {
6612
- completed: "rgba(46,213,115,0.15)",
6613
- current: "rgba(255,121,0,0.15)",
6614
- next: "transparent",
6615
- upcoming: t8["surface-raised"],
6616
- missed: "rgba(209,67,67,0.1)",
6617
- deload: "rgba(186,41,150,0.15)"
6618
- };
6619
- var statusBorderStyles = {
6620
- completed: { borderWidth: 1, borderColor: "rgba(46,213,115,0.3)" },
6621
- current: { borderWidth: 1, borderColor: "rgba(255,121,0,0.3)" },
6622
- next: { borderWidth: 1, borderColor: "rgba(255,121,0,0.4)" },
6623
- upcoming: { borderWidth: 1, borderColor: HAIRLINE_DEFAULT },
6624
- missed: { borderWidth: 1, borderColor: "rgba(209,67,67,0.25)" },
6625
- deload: { borderWidth: 1, borderColor: "rgba(186,41,150,0.3)" }
6626
- };
6627
- var textColors = {
6628
- completed: t8["status-success"],
6629
- current: t8["brand-primary"],
6630
- next: t8["brand-primary"],
6631
- upcoming: greyRamp[500],
6632
- missed: "rgba(209,67,67,0.7)",
6633
- deload: WORKOUT_PILL_DELOAD
6634
- };
6663
+ var DELOAD_WASH = alpha(WORKOUT_PILL_DELOAD, 0.12);
6664
+ var DELOAD_RIM = alpha(WORKOUT_PILL_DELOAD, 0.3);
6665
+ function paintFor(status) {
6666
+ switch (status) {
6667
+ case "completed":
6668
+ return {
6669
+ background: resolveColor("status-success-subtle"),
6670
+ border: resolveColor("status-success-muted"),
6671
+ text: resolveColor("status-success")
6672
+ };
6673
+ case "current":
6674
+ return {
6675
+ background: resolveColor("brand-primary-subtle"),
6676
+ border: resolveColor("brand-primary-muted"),
6677
+ text: resolveColor("brand-primary")
6678
+ };
6679
+ case "next":
6680
+ return {
6681
+ background: "transparent",
6682
+ border: resolveColor("brand-primary-strong"),
6683
+ text: resolveColor("brand-primary")
6684
+ };
6685
+ case "upcoming":
6686
+ return {
6687
+ background: resolveColor("surface-raised"),
6688
+ border: resolveColor("hairline-default"),
6689
+ text: resolveColor("text-tertiary")
6690
+ };
6691
+ case "missed":
6692
+ return {
6693
+ background: resolveColor("status-error-subtle"),
6694
+ border: resolveColor("status-error-muted"),
6695
+ text: resolveColor("status-error-dark")
6696
+ };
6697
+ case "deload":
6698
+ return { background: DELOAD_WASH, border: DELOAD_RIM, text: WORKOUT_PILL_DELOAD };
6699
+ }
6700
+ }
6635
6701
  function usePulse2(enabled) {
6636
6702
  const [opacity] = useState(() => new Animated.Value(1));
6637
6703
  useEffect(() => {
@@ -6673,6 +6739,8 @@ function WorkoutPill({
6673
6739
  const pulseOpacity = usePulse2(shouldPulse);
6674
6740
  const isCompleted = status === "completed";
6675
6741
  const isMissed = status === "missed";
6742
+ const paint = paintFor(status);
6743
+ const labelClass = "font-semibold leading-[normal]";
6676
6744
  const pill = /* @__PURE__ */ jsx(
6677
6745
  Animated.View,
6678
6746
  {
@@ -6689,53 +6757,46 @@ function WorkoutPill({
6689
6757
  paddingHorizontal: 10,
6690
6758
  paddingVertical: 4,
6691
6759
  borderRadius: 6,
6692
- backgroundColor: statusBgColors[status]
6760
+ backgroundColor: paint.background,
6761
+ borderWidth: 1,
6762
+ borderColor: paint.border
6693
6763
  },
6694
- statusBorderStyles[status],
6695
6764
  highlighted ? { borderWidth: 2, transform: [{ scale: 1.02 }] } : void 0
6696
6765
  ],
6697
6766
  accessibilityLabel: onPress ? void 0 : `${name} workout, ${status}`,
6698
6767
  ...props,
6699
6768
  children: [
6700
6769
  isCompleted && /* @__PURE__ */ jsx(
6701
- Text,
6770
+ Typography,
6702
6771
  {
6703
- style: {
6704
- fontWeight: "600",
6705
- fontFamily: '"Nunito Sans", sans-serif',
6706
- fontSize: 11,
6707
- color: textColors[status],
6708
- marginRight: 4
6709
- },
6772
+ variant: "caption",
6773
+ color: "inherit",
6774
+ className: labelClass,
6775
+ style: { color: paint.text, marginRight: 4 },
6710
6776
  accessibilityElementsHidden: true,
6711
6777
  testID: "workout-pill-check",
6712
6778
  children: "\u2713"
6713
6779
  }
6714
6780
  ),
6715
6781
  isMissed && /* @__PURE__ */ jsx(
6716
- Text,
6782
+ Typography,
6717
6783
  {
6718
- style: {
6719
- fontWeight: "600",
6720
- fontFamily: '"Nunito Sans", sans-serif',
6721
- fontSize: 11,
6722
- color: textColors[status],
6723
- marginRight: 4
6724
- },
6784
+ variant: "caption",
6785
+ color: "inherit",
6786
+ className: labelClass,
6787
+ style: { color: paint.text, marginRight: 4 },
6725
6788
  accessibilityElementsHidden: true,
6726
6789
  testID: "workout-pill-dash",
6727
6790
  children: "\u2014"
6728
6791
  }
6729
6792
  ),
6730
6793
  /* @__PURE__ */ jsx(
6731
- Text,
6794
+ Typography,
6732
6795
  {
6733
- style: {
6734
- fontWeight: "600",
6735
- fontFamily: '"Nunito Sans", sans-serif',
6736
- fontSize: 11,
6737
- color: textColors[status]
6738
- },
6796
+ variant: "caption",
6797
+ color: "inherit",
6798
+ className: labelClass,
6799
+ style: { color: paint.text },
6739
6800
  accessibilityElementsHidden: onPress != null,
6740
6801
  testID: "workout-pill-name",
6741
6802
  children: name
@@ -6760,19 +6821,19 @@ function WorkoutPill({
6760
6821
  }
6761
6822
  return pill;
6762
6823
  }
6763
- var t9 = getSemanticColors("dark");
6824
+ var t6 = getSemanticColors("dark");
6764
6825
  var TRACK_BG = "#333333";
6765
6826
  var LABEL_COLOR = "#6B7280";
6766
6827
  var TARGET_LINE_COLOR = "rgba(33, 150, 243, 0.5)";
6767
- var AT_TARGET_GLOW = "0 0 5px 1px rgba(33, 150, 243, 0.35), 0 0 10px 3px rgba(33, 150, 243, 0.15)";
6828
+ var AT_TARGET_GLOW = getGlowShadow(t6["status-info"], "subtle");
6768
6829
  var ZONE = {
6769
- building: t9["status-success"],
6830
+ building: t6["status-success"],
6770
6831
  // below target ramp-up
6771
- approaching: t9["status-warning"],
6832
+ approaching: t6["status-warning"],
6772
6833
  // nearing target
6773
- target: t9["brand-primary"],
6834
+ target: t6["brand-primary"],
6774
6835
  // exactly at target
6775
- over1: t9["status-error"],
6836
+ over1: t6["status-error"],
6776
6837
  // mild over-target
6777
6838
  over2: WORKOUT_TOKENS.intensity.over2,
6778
6839
  // moderate over-target
@@ -6887,7 +6948,7 @@ function IntensityBar({
6887
6948
  borderRadius: 3,
6888
6949
  backgroundColor: zone.color,
6889
6950
  zIndex: 2,
6890
- ...atTarget ? { boxShadow: AT_TARGET_GLOW } : null
6951
+ ...atTarget ? AT_TARGET_GLOW : null
6891
6952
  },
6892
6953
  testID: "intensity-fill"
6893
6954
  }
@@ -6935,7 +6996,7 @@ function IntensityBar({
6935
6996
  }
6936
6997
 
6937
6998
  // src/components/custom/Workout/WeekRow.tsx
6938
- var BRAND_PRIMARY9 = getSemanticColors("dark")["brand-primary"];
6999
+ var DELOAD_ROW_WASH = alpha(WORKOUT_PILL_DELOAD, 0.06);
6939
7000
  function WeekRow({
6940
7001
  weekNumber,
6941
7002
  totalWeeks,
@@ -6947,6 +7008,7 @@ function WeekRow({
6947
7008
  className,
6948
7009
  ...props
6949
7010
  }) {
7011
+ const brandPrimary = resolveColor("brand-primary");
6950
7012
  const rowStyle = {
6951
7013
  flexDirection: "row",
6952
7014
  alignItems: "center",
@@ -6955,12 +7017,12 @@ function WeekRow({
6955
7017
  gap: 12
6956
7018
  };
6957
7019
  if (isDeload) {
6958
- rowStyle.backgroundColor = "rgba(186,41,150,0.06)";
7020
+ rowStyle.backgroundColor = DELOAD_ROW_WASH;
6959
7021
  }
6960
7022
  if (isCurrent) {
6961
- rowStyle.backgroundColor = "rgba(255,121,0,0.04)";
7023
+ rowStyle.backgroundColor = resolveColor("brand-primary-subtle");
6962
7024
  rowStyle.borderLeftWidth = 2;
6963
- rowStyle.borderLeftColor = BRAND_PRIMARY9;
7025
+ rowStyle.borderLeftColor = brandPrimary;
6964
7026
  }
6965
7027
  return /* @__PURE__ */ jsxs(
6966
7028
  View,
@@ -6984,22 +7046,18 @@ function WeekRow({
6984
7046
  width: 6,
6985
7047
  height: 6,
6986
7048
  borderRadius: 3,
6987
- backgroundColor: BRAND_PRIMARY9
7049
+ backgroundColor: brandPrimary
6988
7050
  },
6989
7051
  accessibilityElementsHidden: true,
6990
7052
  testID: "week-row-current-dot"
6991
7053
  }
6992
7054
  ),
6993
7055
  /* @__PURE__ */ jsx(
6994
- Text,
7056
+ Typography,
6995
7057
  {
6996
- className: isCurrent ? void 0 : "text-text-primary",
6997
- style: {
6998
- fontSize: 13,
6999
- fontWeight: "700",
7000
- fontFamily: "Inter, sans-serif",
7001
- color: isCurrent ? BRAND_PRIMARY9 : void 0
7002
- },
7058
+ variant: "boldLabel",
7059
+ color: isCurrent ? "inherit" : "primary",
7060
+ className: isCurrent ? "text-brand-primary" : void 0,
7003
7061
  accessibilityElementsHidden: true,
7004
7062
  children: `W${weekNumber}`
7005
7063
  }
@@ -7039,12 +7097,12 @@ function WeekRow({
7039
7097
  }
7040
7098
 
7041
7099
  // src/components/custom/Workout/MesoCard.tsx
7042
- var HAIRLINE_DEFAULT2 = getSemanticColors("dark")["hairline-default"];
7043
- var BRAND_PRIMARY10 = getSemanticColors("dark")["brand-primary"];
7100
+ var HAIRLINE_DEFAULT = getSemanticColors("dark")["hairline-default"];
7101
+ var BRAND_PRIMARY7 = getSemanticColors("dark")["brand-primary"];
7044
7102
  var BRAND_PRIMARY_DARK2 = MESO_ACCENT_GRADIENT_DARK;
7045
7103
  var BRAND_PRIMARY_LIGHT2 = MESO_ACCENT_GRADIENT_LIGHT;
7046
- var BORDER_DEFAULT = HAIRLINE_DEFAULT2;
7047
- var ACCENT_STOPS2 = [BRAND_PRIMARY_DARK2, BRAND_PRIMARY10, BRAND_PRIMARY_LIGHT2];
7104
+ var BORDER_DEFAULT = HAIRLINE_DEFAULT;
7105
+ var ACCENT_STOPS2 = [BRAND_PRIMARY_DARK2, BRAND_PRIMARY7, BRAND_PRIMARY_LIGHT2];
7048
7106
  function heatmapColor(percentage) {
7049
7107
  const clamped = Math.max(0, Math.min(100, percentage));
7050
7108
  const opacity = 0.12 + clamped / 100 * 0.78;
@@ -7079,130 +7137,139 @@ function MesoCard({
7079
7137
  }, [highlighted, highlight]);
7080
7138
  const borderColor = highlight.interpolate({
7081
7139
  inputRange: [0, 1],
7082
- outputRange: [BORDER_DEFAULT, BRAND_PRIMARY10]
7140
+ outputRange: [BORDER_DEFAULT, BRAND_PRIMARY7]
7083
7141
  });
7084
- const header = /* @__PURE__ */ jsxs(View, { style: { paddingHorizontal: 14, paddingTop: 12, paddingBottom: 10 }, testID: "meso-card-body", children: [
7085
- /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 8 }, testID: "meso-card-header", children: [
7086
- /* @__PURE__ */ jsx(
7087
- Text,
7088
- {
7089
- className: "text-text-primary",
7090
- style: {
7091
- fontSize: 15,
7092
- fontFamily: '"Space Grotesk", sans-serif',
7093
- fontWeight: "700"
7094
- },
7095
- testID: "meso-card-name",
7096
- children: name
7097
- }
7098
- ),
7099
- /* @__PURE__ */ jsx(Badge, { variant: "subtle", color: "primary", size: "sm", testID: "meso-card-goal-badge", children: goal })
7100
- ] }),
7101
- /* @__PURE__ */ jsx(
7102
- Text,
7103
- {
7104
- className: "text-text-secondary",
7105
- style: {
7106
- marginTop: 4,
7107
- fontSize: 12,
7108
- fontFamily: "Inter, sans-serif"
7109
- },
7110
- testID: "meso-card-subheader",
7111
- children: `${split} \xB7 ${weekRange}`
7112
- }
7113
- ),
7114
- volumeHeatmap && volumeHeatmap.length > 0 && /* @__PURE__ */ jsx(
7115
- View,
7116
- {
7117
- className: "flex-row items-center",
7118
- style: { marginTop: 10, gap: 3 },
7119
- accessibilityElementsHidden: true,
7120
- testID: "meso-card-heatmap",
7121
- children: volumeHeatmap.map((entry) => /* @__PURE__ */ jsx(
7122
- View,
7123
- {
7124
- style: {
7125
- flex: 1,
7126
- height: 8,
7127
- borderRadius: 2,
7128
- backgroundColor: heatmapColor(entry.percentage)
7129
- },
7130
- testID: "meso-card-heatmap-cell"
7131
- },
7132
- entry.group
7133
- ))
7134
- }
7135
- )
7136
- ] });
7137
- return /* @__PURE__ */ jsx(Animated.View, { style: highlighted ? { transform: [{ scale: 1 }] } : void 0, testID: "meso-card-wrapper", children: /* @__PURE__ */ jsxs(
7138
- Card,
7142
+ const header = /* @__PURE__ */ jsxs(
7143
+ View,
7139
7144
  {
7140
- variant: "outline",
7141
- elevation: 2,
7142
- borderColor: highlighted ? BRAND_PRIMARY10 : BORDER_DEFAULT,
7143
- className,
7144
- style: [
7145
- { borderColor },
7146
- highlighted ? { boxShadow: "0 0 12px 2px rgba(255,121,0,0.25)" } : void 0
7147
- ],
7148
- testID: "meso-card",
7149
- ...props,
7145
+ style: { paddingHorizontal: 14, paddingTop: 12, paddingBottom: 10 },
7146
+ testID: "meso-card-body",
7150
7147
  children: [
7148
+ /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 8 }, testID: "meso-card-header", children: [
7149
+ /* @__PURE__ */ jsx(
7150
+ Text,
7151
+ {
7152
+ className: "text-text-primary",
7153
+ style: {
7154
+ fontSize: 15,
7155
+ fontFamily: '"Space Grotesk", sans-serif',
7156
+ fontWeight: "700"
7157
+ },
7158
+ testID: "meso-card-name",
7159
+ children: name
7160
+ }
7161
+ ),
7162
+ /* @__PURE__ */ jsx(Badge, { variant: "subtle", color: "primary", size: "sm", testID: "meso-card-goal-badge", children: goal })
7163
+ ] }),
7151
7164
  /* @__PURE__ */ jsx(
7152
- View,
7153
- {
7154
- className: "flex-row",
7155
- style: { position: "absolute", top: 0, left: 0, right: 0, height: 3, zIndex: 1 },
7156
- accessibilityElementsHidden: true,
7157
- testID: "meso-card-accent",
7158
- children: ACCENT_STOPS2.map((color) => /* @__PURE__ */ jsx(View, { style: { flex: 1, backgroundColor: color } }, color))
7159
- }
7160
- ),
7161
- isExpandable ? /* @__PURE__ */ jsx(
7162
- Pressable,
7163
- {
7164
- onPress: onToggle,
7165
- accessibilityRole: "button",
7166
- accessibilityLabel: `${name}, ${goal}, ${weekRange}`,
7167
- "aria-expanded": expanded,
7168
- testID: "meso-card-toggle",
7169
- children: header
7170
- }
7171
- ) : /* @__PURE__ */ jsx(
7172
- View,
7165
+ Text,
7173
7166
  {
7174
- accessibilityLabel: `${name}, ${goal}, ${weekRange}`,
7175
- testID: "meso-card-static",
7176
- children: header
7167
+ className: "text-text-secondary",
7168
+ style: {
7169
+ marginTop: 4,
7170
+ fontSize: 12,
7171
+ fontFamily: "Inter, sans-serif"
7172
+ },
7173
+ testID: "meso-card-subheader",
7174
+ children: `${split} \xB7 ${weekRange}`
7177
7175
  }
7178
7176
  ),
7179
- expanded && weeks.length > 0 && /* @__PURE__ */ jsx(
7177
+ volumeHeatmap && volumeHeatmap.length > 0 && /* @__PURE__ */ jsx(
7180
7178
  View,
7181
7179
  {
7182
- style: { borderTopWidth: 1, borderTopColor: BORDER_DEFAULT },
7183
- testID: "meso-card-weeks",
7184
- children: weeks.map((week) => /* @__PURE__ */ jsx(
7185
- WeekRow,
7180
+ className: "flex-row items-center",
7181
+ style: { marginTop: 10, gap: 3 },
7182
+ accessibilityElementsHidden: true,
7183
+ testID: "meso-card-heatmap",
7184
+ children: volumeHeatmap.map((entry) => /* @__PURE__ */ jsx(
7185
+ View,
7186
7186
  {
7187
- ...week,
7188
- totalWeeks: week.totalWeeks ?? totalWeeks,
7189
- isCurrent: week.isCurrent ?? week.weekNumber === currentWeek
7187
+ style: {
7188
+ flex: 1,
7189
+ height: 8,
7190
+ borderRadius: 2,
7191
+ backgroundColor: heatmapColor(entry.percentage)
7192
+ },
7193
+ testID: "meso-card-heatmap-cell"
7190
7194
  },
7191
- week.weekNumber
7195
+ entry.group
7192
7196
  ))
7193
7197
  }
7194
7198
  )
7195
7199
  ]
7196
7200
  }
7197
- ) });
7201
+ );
7202
+ return /* @__PURE__ */ jsx(
7203
+ Animated.View,
7204
+ {
7205
+ style: highlighted ? { transform: [{ scale: 1 }] } : void 0,
7206
+ testID: "meso-card-wrapper",
7207
+ children: /* @__PURE__ */ jsxs(
7208
+ Card,
7209
+ {
7210
+ variant: "outline",
7211
+ elevation: 2,
7212
+ borderColor: highlighted ? BRAND_PRIMARY7 : BORDER_DEFAULT,
7213
+ className,
7214
+ style: [
7215
+ { borderColor },
7216
+ // Highlight is emphasis, not depth: a brand glow through the shared builder.
7217
+ highlighted ? getGlowShadow(BRAND_PRIMARY7, "subtle") : void 0
7218
+ ],
7219
+ testID: "meso-card",
7220
+ ...props,
7221
+ children: [
7222
+ /* @__PURE__ */ jsx(
7223
+ View,
7224
+ {
7225
+ className: "flex-row",
7226
+ style: { position: "absolute", top: 0, left: 0, right: 0, height: 3, zIndex: 1 },
7227
+ accessibilityElementsHidden: true,
7228
+ testID: "meso-card-accent",
7229
+ children: ACCENT_STOPS2.map((color) => /* @__PURE__ */ jsx(View, { style: { flex: 1, backgroundColor: color } }, color))
7230
+ }
7231
+ ),
7232
+ isExpandable ? /* @__PURE__ */ jsx(
7233
+ Pressable,
7234
+ {
7235
+ onPress: onToggle,
7236
+ accessibilityRole: "button",
7237
+ accessibilityLabel: `${name}, ${goal}, ${weekRange}`,
7238
+ "aria-expanded": expanded,
7239
+ testID: "meso-card-toggle",
7240
+ children: header
7241
+ }
7242
+ ) : /* @__PURE__ */ jsx(View, { accessibilityLabel: `${name}, ${goal}, ${weekRange}`, testID: "meso-card-static", children: header }),
7243
+ expanded && weeks.length > 0 && /* @__PURE__ */ jsx(
7244
+ View,
7245
+ {
7246
+ style: { borderTopWidth: 1, borderTopColor: BORDER_DEFAULT },
7247
+ testID: "meso-card-weeks",
7248
+ children: weeks.map((week) => /* @__PURE__ */ jsx(
7249
+ WeekRow,
7250
+ {
7251
+ ...week,
7252
+ totalWeeks: week.totalWeeks ?? totalWeeks,
7253
+ isCurrent: week.isCurrent ?? week.weekNumber === currentWeek
7254
+ },
7255
+ week.weekNumber
7256
+ ))
7257
+ }
7258
+ )
7259
+ ]
7260
+ }
7261
+ )
7262
+ }
7263
+ );
7198
7264
  }
7199
- var t10 = getSemanticColors("dark");
7200
- var dotColorMap = {
7201
- untrained: greyRamp[900],
7202
- behind: t10["brand-secondary"],
7203
- ontrack: t10["status-success"],
7204
- target: t10["brand-primary"],
7205
- over: t10["status-error"]
7265
+
7266
+ // src/components/custom/Workout/MuscleGroupChip.tsx
7267
+ var dotTone = {
7268
+ untrained: "neutral",
7269
+ behind: "brand-secondary",
7270
+ ontrack: "success",
7271
+ target: "brand",
7272
+ over: "error"
7206
7273
  };
7207
7274
  function MuscleGroupChip({
7208
7275
  name,
@@ -7211,83 +7278,31 @@ function MuscleGroupChip({
7211
7278
  className,
7212
7279
  ...props
7213
7280
  }) {
7214
- const dotColor = volumeStatus ? dotColorMap[volumeStatus] : greyRamp[900];
7215
7281
  const statusLabel = volumeStatus ?? "no status";
7216
- const content = /* @__PURE__ */ jsxs(
7217
- View,
7282
+ return /* @__PURE__ */ jsx(
7283
+ Pill,
7218
7284
  {
7219
- className: ["bg-surface-raised border-hairline", className].filter(Boolean).join(" "),
7220
- style: {
7221
- flexDirection: "row",
7222
- alignItems: "center",
7223
- borderRadius: 9999,
7224
- paddingHorizontal: 9,
7225
- paddingVertical: 3,
7226
- borderWidth: 1
7227
- },
7228
- accessibilityLabel: onPress ? void 0 : `${name}, volume status: ${statusLabel}`,
7229
- testID: "muscle-group-chip",
7285
+ tone: "neutral",
7286
+ dotTone: volumeStatus ? dotTone[volumeStatus] : "neutral",
7287
+ variant: "subtle",
7288
+ size: "md",
7289
+ leading: "dot",
7290
+ onPress,
7291
+ className: ["gap-1.5", className].filter(Boolean).join(" "),
7292
+ textClassName: "font-sans font-medium text-text-secondary",
7293
+ accessibilityLabel: `${name}, volume status: ${statusLabel}`,
7294
+ testID: onPress ? "muscle-group-chip-pressable" : "muscle-group-chip",
7230
7295
  ...props,
7231
- children: [
7232
- /* @__PURE__ */ jsx(
7233
- View,
7234
- {
7235
- style: {
7236
- width: 6,
7237
- height: 6,
7238
- borderRadius: 9999,
7239
- marginRight: 5,
7240
- flexShrink: 0,
7241
- backgroundColor: dotColor
7242
- },
7243
- accessibilityElementsHidden: true,
7244
- testID: "muscle-group-chip-dot"
7245
- }
7246
- ),
7247
- /* @__PURE__ */ jsx(
7248
- Text,
7249
- {
7250
- className: "text-text-secondary",
7251
- style: {
7252
- fontFamily: "Inter, sans-serif",
7253
- fontWeight: "500",
7254
- fontSize: 11
7255
- },
7256
- accessibilityElementsHidden: true,
7257
- children: name
7258
- }
7259
- )
7260
- ]
7296
+ children: name
7261
7297
  }
7262
7298
  );
7263
- if (onPress) {
7264
- return /* @__PURE__ */ jsx(
7265
- Pressable,
7266
- {
7267
- onPress,
7268
- accessibilityRole: "button",
7269
- accessibilityLabel: `${name}, volume status: ${statusLabel}`,
7270
- testID: "muscle-group-chip-pressable",
7271
- children: content
7272
- }
7273
- );
7274
- }
7275
- return content;
7276
7299
  }
7277
7300
 
7278
7301
  // src/components/custom/Workout/WorkoutCard.tsx
7279
- var HAIRLINE_DEFAULT3 = getSemanticColors("dark")["hairline-default"];
7280
- var t11 = getSemanticColors("dark");
7281
- var COLORS = {
7282
- statusSuccess: t11["status-success"],
7283
- brandPrimary: t11["brand-primary"],
7284
- borderDefault: HAIRLINE_DEFAULT3,
7285
- brandPrimarySubtle: "rgba(255,121,0,0.06)"
7286
- };
7287
- var statusBorderColors = {
7288
- completed: COLORS.statusSuccess,
7289
- today: COLORS.brandPrimary,
7290
- upcoming: COLORS.borderDefault
7302
+ var statusAccentToken = {
7303
+ completed: "status-success",
7304
+ today: "brand-primary",
7305
+ upcoming: "hairline-default"
7291
7306
  };
7292
7307
  var volumeStatusMap = {
7293
7308
  under: "behind",
@@ -7322,41 +7337,33 @@ function WorkoutCard({
7322
7337
  const summary = /* @__PURE__ */ jsxs(View, { style: { padding: 14 }, testID: "workout-card-body", children: [
7323
7338
  /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", testID: "workout-card-header", children: [
7324
7339
  /* @__PURE__ */ jsx(
7325
- Text,
7340
+ Typography,
7326
7341
  {
7327
- className: "text-text-primary",
7328
- style: {
7329
- fontSize: 15,
7330
- fontFamily: '"Space Grotesk", sans-serif',
7331
- fontWeight: "700"
7332
- },
7342
+ variant: "h6",
7343
+ color: "primary",
7344
+ className: "text-base font-bold leading-[normal]",
7333
7345
  testID: "workout-card-name",
7334
7346
  children: name
7335
7347
  }
7336
7348
  ),
7337
7349
  /* @__PURE__ */ jsx(View, { className: "flex-1" }),
7338
7350
  /* @__PURE__ */ jsx(
7339
- Text,
7351
+ Typography,
7340
7352
  {
7341
- className: "text-text-tertiary",
7342
- style: {
7343
- fontSize: 11,
7344
- fontFamily: "Inter, sans-serif"
7345
- },
7353
+ variant: "caption",
7354
+ color: "tertiary",
7355
+ className: "text-2xs leading-[normal]",
7346
7356
  testID: "workout-card-date",
7347
7357
  children: date
7348
7358
  }
7349
7359
  )
7350
7360
  ] }),
7351
7361
  /* @__PURE__ */ jsx(
7352
- Text,
7362
+ Typography,
7353
7363
  {
7354
- className: "text-text-secondary",
7355
- style: {
7356
- marginTop: 4,
7357
- fontSize: 12,
7358
- fontFamily: "Inter, sans-serif"
7359
- },
7364
+ variant: "caption",
7365
+ color: "secondary",
7366
+ className: "mt-1 leading-[normal]",
7360
7367
  testID: "workout-card-stats",
7361
7368
  children: formatStats(totalSets, totalVolume, unit, duration)
7362
7369
  }
@@ -7385,8 +7392,8 @@ function WorkoutCard({
7385
7392
  {
7386
7393
  variant: "accent",
7387
7394
  elevation: 1,
7388
- accentColor: statusBorderColors[status],
7389
- bgColor: isToday ? COLORS.brandPrimarySubtle : void 0,
7395
+ accentColor: resolveColor(statusAccentToken[status]),
7396
+ bgColor: isToday ? resolveColor("brand-primary-subtle") : void 0,
7390
7397
  className,
7391
7398
  style: isUpcoming ? { opacity: 0.6 } : void 0,
7392
7399
  testID: "workout-card",
@@ -7424,7 +7431,7 @@ function WorkoutCard({
7424
7431
  }
7425
7432
 
7426
7433
  // src/components/custom/Workout/ProgramPlanningPage.tsx
7427
- var BRAND_PRIMARY11 = getSemanticColors("dark")["brand-primary"];
7434
+ var BRAND_PRIMARY8 = getSemanticColors("dark")["brand-primary"];
7428
7435
  var WORKOUT_PILL_STATUS = {
7429
7436
  completed: "completed",
7430
7437
  today: "current",
@@ -7492,7 +7499,7 @@ function Breadcrumbs({ crumbs, onNavigate }) {
7492
7499
  fontSize: 12,
7493
7500
  fontFamily: "Inter, sans-serif",
7494
7501
  fontWeight: isLast ? "700" : "500",
7495
- color: isLast ? void 0 : BRAND_PRIMARY11
7502
+ color: isLast ? void 0 : BRAND_PRIMARY8
7496
7503
  },
7497
7504
  children: crumb.label
7498
7505
  }