@titan-design/react-ui 0.12.1 → 0.14.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 (531) hide show
  1. package/README.md +60 -47
  2. package/dist/bodymap.js +856 -736
  3. package/dist/bodymap.js.map +1 -1
  4. package/dist/bodymap.mjs +858 -738
  5. package/dist/bodymap.mjs.map +1 -1
  6. package/dist/index.d.mts +1431 -237
  7. package/dist/index.d.ts +1431 -237
  8. package/dist/index.js +6506 -4781
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +6280 -4642
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/{pages-B1hqnGIC.d.ts → pages-CsjsUn0G.d.ts} +51 -16
  13. package/dist/{pages-CvsFqNtx.d.mts → pages-ZbT_pD_U.d.mts} +51 -16
  14. package/dist/pages.d.mts +1 -1
  15. package/dist/pages.d.ts +1 -1
  16. package/dist/pages.js +1919 -1937
  17. package/dist/pages.js.map +1 -1
  18. package/dist/pages.mjs +1927 -1945
  19. package/dist/pages.mjs.map +1 -1
  20. package/dist/theme/index.d.mts +225 -140
  21. package/dist/theme/index.d.ts +225 -140
  22. package/dist/theme/index.js +298 -319
  23. package/dist/theme/index.js.map +1 -1
  24. package/dist/theme/index.mjs +283 -315
  25. package/dist/theme/index.mjs.map +1 -1
  26. package/dist/theme/tokens-css.js +145 -24
  27. package/dist/theme/tokens-css.js.map +1 -1
  28. package/dist/theme/tokens-css.mjs +145 -24
  29. package/dist/theme/tokens-css.mjs.map +1 -1
  30. package/dist/theme/tokens.d.mts +128 -11
  31. package/dist/theme/tokens.d.ts +128 -11
  32. package/dist/theme/tokens.js +126 -26
  33. package/dist/theme/tokens.js.map +1 -1
  34. package/dist/theme/tokens.mjs +124 -27
  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/docs/render-testing-pattern.md +130 -0
  40. package/package.json +1 -1
  41. package/src/arch/Architecture.stories.tsx +3 -1
  42. package/src/arch/arch-graph.freshness.test.ts +52 -0
  43. package/src/arch/arch-graph.json +4989 -1583
  44. package/src/components/custom/ActiveWork/CoChangeChip.stories.tsx +44 -0
  45. package/src/components/custom/ActiveWork/CoChangeChip.test.tsx +29 -0
  46. package/src/components/custom/ActiveWork/CoChangeChip.tsx +48 -0
  47. package/src/components/custom/ActiveWork/Eyebrow.stories.tsx +25 -0
  48. package/src/components/custom/ActiveWork/Eyebrow.test.tsx +16 -0
  49. package/src/components/custom/ActiveWork/Eyebrow.tsx +26 -0
  50. package/src/components/custom/ActiveWork/FileActivityDetail.stories.tsx +50 -0
  51. package/src/components/custom/ActiveWork/FileActivityDetail.test.tsx +66 -0
  52. package/src/components/custom/ActiveWork/FileActivityDetail.tsx +202 -0
  53. package/src/components/custom/ActiveWork/FileActivityRow.stories.tsx +70 -0
  54. package/src/components/custom/ActiveWork/FileActivityRow.test.tsx +67 -0
  55. package/src/components/custom/ActiveWork/FileActivityRow.tsx +130 -0
  56. package/src/components/custom/ActiveWork/FileHistoryExplorer.stories.tsx +84 -0
  57. package/src/components/custom/ActiveWork/FileHistoryExplorer.test.tsx +99 -0
  58. package/src/components/custom/ActiveWork/FileHistoryExplorer.tsx +138 -0
  59. package/src/components/custom/ActiveWork/FilePathLabel.stories.tsx +39 -0
  60. package/src/components/custom/ActiveWork/FilePathLabel.test.tsx +53 -0
  61. package/src/components/custom/ActiveWork/FilePathLabel.tsx +63 -0
  62. package/src/components/custom/ActiveWork/InitiativeBrief.stories.tsx +50 -0
  63. package/src/components/custom/ActiveWork/InitiativeBrief.test.tsx +62 -0
  64. package/src/components/custom/ActiveWork/InitiativeBrief.tsx +182 -0
  65. package/src/components/custom/ActiveWork/InitiativeCard.stories.tsx +73 -0
  66. package/src/components/custom/ActiveWork/InitiativeCard.test.tsx +68 -0
  67. package/src/components/custom/ActiveWork/InitiativeCard.tsx +136 -0
  68. package/src/components/custom/ActiveWork/InitiativeHeader.stories.tsx +59 -0
  69. package/src/components/custom/ActiveWork/InitiativeHeader.test.tsx +40 -0
  70. package/src/components/custom/ActiveWork/InitiativeHeader.tsx +73 -0
  71. package/src/components/custom/ActiveWork/InitiativeReader.stories.tsx +145 -0
  72. package/src/components/custom/ActiveWork/OpenLoops.stories.tsx +58 -0
  73. package/src/components/custom/ActiveWork/OpenLoops.test.tsx +61 -0
  74. package/src/components/custom/ActiveWork/OpenLoops.tsx +107 -0
  75. package/src/components/custom/ActiveWork/PortfolioOverview.stories.tsx +101 -0
  76. package/src/components/custom/ActiveWork/PortfolioOverview.test.tsx +81 -0
  77. package/src/components/custom/ActiveWork/PortfolioOverview.tsx +83 -0
  78. package/src/components/custom/ActiveWork/README.md +305 -0
  79. package/src/components/custom/ActiveWork/SessionDetail.stories.tsx +71 -0
  80. package/src/components/custom/ActiveWork/SessionDetail.test.tsx +84 -0
  81. package/src/components/custom/ActiveWork/SessionDetail.tsx +180 -0
  82. package/src/components/custom/ActiveWork/SessionList.stories.tsx +69 -0
  83. package/src/components/custom/ActiveWork/SessionList.test.tsx +78 -0
  84. package/src/components/custom/ActiveWork/SessionList.tsx +103 -0
  85. package/src/components/custom/ActiveWork/SessionListItem.stories.tsx +64 -0
  86. package/src/components/custom/ActiveWork/SessionListItem.test.tsx +62 -0
  87. package/src/components/custom/ActiveWork/SessionListItem.tsx +152 -0
  88. package/src/components/custom/ActiveWork/SessionReader.stories.tsx +113 -0
  89. package/src/components/custom/ActiveWork/SeverityLabel.stories.tsx +51 -0
  90. package/src/components/custom/ActiveWork/SeverityLabel.test.tsx +68 -0
  91. package/src/components/custom/ActiveWork/SeverityLabel.tsx +97 -0
  92. package/src/components/custom/ActiveWork/TaskRow.stories.tsx +63 -0
  93. package/src/components/custom/ActiveWork/TaskRow.test.tsx +112 -0
  94. package/src/components/custom/ActiveWork/TaskRow.tsx +176 -0
  95. package/src/components/custom/ActiveWork/TaskTable.stories.tsx +123 -0
  96. package/src/components/custom/ActiveWork/TaskTable.test.tsx +233 -0
  97. package/src/components/custom/ActiveWork/TaskTable.tsx +321 -0
  98. package/src/components/custom/ActiveWork/active-work-depth.test.tsx +102 -0
  99. package/src/components/custom/ActiveWork/file-history-fixture.ts +91 -0
  100. package/src/components/custom/ActiveWork/format-time.test.ts +23 -0
  101. package/src/components/custom/ActiveWork/format-time.ts +32 -0
  102. package/src/components/custom/ActiveWork/index.ts +19 -0
  103. package/src/components/custom/ActiveWork/initiative-fixture.ts +104 -0
  104. package/src/components/custom/ActiveWork/session-fixture.ts +267 -0
  105. package/src/components/custom/ActiveWork/session-linkers.ts +56 -0
  106. package/src/components/custom/ActiveWork/task-list-fixture.ts +97 -0
  107. package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +12 -6
  108. package/src/components/custom/DateTime/DateTime.stories.tsx +2 -1
  109. package/src/components/custom/DateTime/DateTime.test.tsx +3 -1
  110. package/src/components/custom/EmptyState/EmptyState.stories.tsx +22 -9
  111. package/src/components/custom/EmptyState/EmptyState.test.tsx +7 -13
  112. package/src/components/custom/EmptyState/EmptyState.tsx +4 -18
  113. package/src/components/custom/Fatigue/DualGhostSpark.stories.tsx +4 -3
  114. package/src/components/custom/Fatigue/FatigueLights.stories.tsx +2 -2
  115. package/src/components/custom/Fatigue/GhostSpark.stories.tsx +4 -3
  116. package/src/components/custom/Fatigue/LiveFatigueCard.stories.tsx +2 -2
  117. package/src/components/custom/Fatigue/LiveFatigueCard.tsx +8 -4
  118. package/src/components/custom/Fatigue/LiveFatiguePanel.stories.tsx +116 -6
  119. package/src/components/custom/Fatigue/LiveFatiguePanel.test.tsx +134 -0
  120. package/src/components/custom/Fatigue/LiveFatiguePanel.tsx +54 -83
  121. package/src/components/custom/Fatigue/README.md +40 -3
  122. package/src/components/custom/Fatigue/RomProgressionChart.stories.tsx +2 -2
  123. package/src/components/custom/Fatigue/SilverRedPalette.stories.tsx +2 -1
  124. package/src/components/custom/Fatigue/VelocityHero.stories.tsx +4 -3
  125. package/src/components/custom/Fatigue/VerdictHero.stories.tsx +2 -2
  126. package/src/components/custom/Fatigue/fatigue-mock.test.ts +0 -5
  127. package/src/components/custom/Fatigue/fatigue-mock.ts +2 -10
  128. package/src/components/custom/Fatigue/fatigue-tokens.ts +12 -0
  129. package/src/components/custom/Fatigue/index.ts +17 -5
  130. package/src/components/custom/Fatigue/panel-layout.test.ts +149 -0
  131. package/src/components/custom/Fatigue/panel-layout.ts +185 -0
  132. package/src/components/custom/Gauge/Gauge.stories.tsx +6 -3
  133. package/src/components/custom/Gauge/Gauge.test.tsx +1 -1
  134. package/src/components/custom/Gauge/Gauge.tsx +7 -2
  135. package/src/components/custom/Metric/Metric.stories.tsx +10 -1
  136. package/src/components/custom/Metric/Metric.test.tsx +1 -3
  137. package/src/components/custom/Metric/Metric.tsx +5 -20
  138. package/src/components/custom/Prose/MarkdownProse.stories.tsx +88 -0
  139. package/src/components/custom/Prose/MarkdownProse.test.tsx +87 -0
  140. package/src/components/custom/Prose/MarkdownProse.tsx +201 -0
  141. package/src/components/custom/Prose/README.md +58 -0
  142. package/src/components/custom/Prose/index.ts +1 -0
  143. package/src/components/custom/Scatter/Scatter.stories.tsx +55 -14
  144. package/src/components/custom/Scatter/Scatter.test.tsx +2 -2
  145. package/src/components/custom/Scatter/Scatter.tsx +122 -18
  146. package/src/components/custom/Sidebar/Sidebar.stories.tsx +41 -8
  147. package/src/components/custom/Sidebar/Sidebar.test.tsx +5 -1
  148. package/src/components/custom/Sidebar/Sidebar.tsx +16 -33
  149. package/src/components/custom/Table/Table.stories.tsx +99 -16
  150. package/src/components/custom/Table/Table.test.tsx +273 -86
  151. package/src/components/custom/Table/Table.tsx +159 -67
  152. package/src/components/custom/Table/column-fit.test.ts +75 -0
  153. package/src/components/custom/Table/column-fit.ts +116 -0
  154. package/src/components/custom/Table/index.ts +9 -0
  155. package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +8 -6
  156. package/src/components/custom/Treemap/Treemap.stories.tsx +15 -12
  157. package/src/components/custom/Treemap/Treemap.test.tsx +1 -1
  158. package/src/components/custom/Treemap/Treemap.tsx +11 -3
  159. package/src/components/custom/Typography/Typography.stories.tsx +28 -1
  160. package/src/components/custom/Typography/Typography.test.tsx +34 -0
  161. package/src/components/custom/Typography/Typography.tsx +6 -0
  162. package/src/components/custom/Typography/index.ts +1 -8
  163. package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +11 -2
  164. package/src/components/custom/Workout/BaseBadge.stories.tsx +27 -11
  165. package/src/components/custom/Workout/BaseBadge.test.tsx +31 -11
  166. package/src/components/custom/Workout/BaseBadge.tsx +6 -2
  167. package/src/components/custom/Workout/BodyMap.stories.tsx +4 -1
  168. package/src/components/custom/Workout/BodyMap.tsx +8 -4
  169. package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +28 -6
  170. package/src/components/custom/Workout/BodyMapDetailPanel.test.tsx +11 -15
  171. package/src/components/custom/Workout/BodyMapDetailPanel.tsx +50 -12
  172. package/src/components/custom/Workout/CapacityBandChart.stories.tsx +12 -9
  173. package/src/components/custom/Workout/CapacityBandChart.test.tsx +24 -51
  174. package/src/components/custom/Workout/CapacityBandChart.tsx +144 -111
  175. package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
  176. package/src/components/custom/Workout/DeviationBar.test.tsx +10 -4
  177. package/src/components/custom/Workout/DeviationBar.tsx +24 -16
  178. package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +183 -0
  179. package/src/components/custom/Workout/DualVelocityStrip.test.tsx +32 -18
  180. package/src/components/custom/Workout/ExerciseCard.stories.tsx +12 -11
  181. package/src/components/custom/Workout/ExerciseCard.test.tsx +52 -22
  182. package/src/components/custom/Workout/ExerciseCard.tsx +99 -183
  183. package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +95 -12
  184. package/src/components/custom/Workout/ExerciseCardHeading.test.tsx +189 -1
  185. package/src/components/custom/Workout/ExerciseCardHeading.tsx +167 -18
  186. package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +9 -1
  187. package/src/components/custom/Workout/ExerciseDetailPage.tsx +3 -2
  188. package/src/components/custom/Workout/ExerciseHeading.stories.tsx +8 -8
  189. package/src/components/custom/Workout/ExerciseHeading.tsx +194 -46
  190. package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +12 -9
  191. package/src/components/custom/Workout/ExerciseIndicator.test.tsx +27 -11
  192. package/src/components/custom/Workout/ExerciseIndicator.tsx +14 -15
  193. package/src/components/custom/Workout/FatigueMeter.stories.tsx +5 -5
  194. package/src/components/custom/Workout/InputBar.stories.tsx +4 -5
  195. package/src/components/custom/Workout/InputBar.tsx +4 -2
  196. package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
  197. package/src/components/custom/Workout/IntensityBar.test.tsx +5 -1
  198. package/src/components/custom/Workout/IntensityBar.tsx +8 -3
  199. package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +5 -4
  200. package/src/components/custom/Workout/MesoCard.stories.tsx +4 -1
  201. package/src/components/custom/Workout/MesoCard.test.tsx +7 -18
  202. package/src/components/custom/Workout/MesoCard.tsx +14 -10
  203. package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
  204. package/src/components/custom/Workout/MesoProgressBar.test.tsx +18 -11
  205. package/src/components/custom/Workout/MesoProgressBar.tsx +15 -13
  206. package/src/components/custom/Workout/MesoStatusCard.stories.tsx +2 -1
  207. package/src/components/custom/Workout/MesoStatusCard.test.tsx +14 -44
  208. package/src/components/custom/Workout/MesoStatusCard.tsx +20 -33
  209. package/src/components/custom/Workout/MetricTiles.stories.tsx +3 -2
  210. package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +2 -8
  211. package/src/components/custom/Workout/MuscleGroupChip.test.tsx +23 -31
  212. package/src/components/custom/Workout/MuscleGroupChip.tsx +28 -67
  213. package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +9 -4
  214. package/src/components/custom/Workout/PlaceholderStrip.test.tsx +17 -10
  215. package/src/components/custom/Workout/PlaceholderStrip.tsx +9 -8
  216. package/src/components/custom/Workout/PrBadge.stories.tsx +2 -1
  217. package/src/components/custom/Workout/PrBadge.test.tsx +3 -9
  218. package/src/components/custom/Workout/PrBadge.tsx +13 -17
  219. package/src/components/custom/Workout/PrHistoryModal.stories.tsx +16 -3
  220. package/src/components/custom/Workout/PrHistoryModal.test.tsx +13 -36
  221. package/src/components/custom/Workout/PrHistoryModal.tsx +8 -4
  222. package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +6 -1
  223. package/src/components/custom/Workout/README.md +68 -17
  224. package/src/components/custom/Workout/ReadinessCheck.stories.tsx +3 -2
  225. package/src/components/custom/Workout/ReadinessCheck.test.tsx +12 -18
  226. package/src/components/custom/Workout/ReadinessCheck.tsx +22 -4
  227. package/src/components/custom/Workout/RestTimer.stories.tsx +16 -4
  228. package/src/components/custom/Workout/RestTimer.tsx +4 -2
  229. package/src/components/custom/Workout/ScheduleTiles.stories.tsx +3 -2
  230. package/src/components/custom/Workout/ScheduleTiles.test.tsx +3 -4
  231. package/src/components/custom/Workout/ScheduleTiles.tsx +4 -7
  232. package/src/components/custom/Workout/SegmentedBar.stories.tsx +21 -17
  233. package/src/components/custom/Workout/SegmentedBar.tsx +10 -5
  234. package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +5 -5
  235. package/src/components/custom/Workout/SessionHeader.stories.tsx +6 -6
  236. package/src/components/custom/Workout/SessionHeader.tsx +12 -12
  237. package/src/components/custom/Workout/SessionRail.stories.tsx +12 -11
  238. package/src/components/custom/Workout/SessionRail.tsx +7 -9
  239. package/src/components/custom/Workout/SetBar.stories.tsx +10 -6
  240. package/src/components/custom/Workout/SetBar.test.tsx +49 -4
  241. package/src/components/custom/Workout/SetBar.tsx +38 -12
  242. package/src/components/custom/Workout/SetRow.stories.tsx +3 -2
  243. package/src/components/custom/Workout/SetRow.test.tsx +16 -2
  244. package/src/components/custom/Workout/SetRow.tsx +61 -23
  245. package/src/components/custom/Workout/SetStrip.stories.tsx +63 -7
  246. package/src/components/custom/Workout/SetStrip.test.tsx +25 -0
  247. package/src/components/custom/Workout/SetStrip.tsx +24 -4
  248. package/src/components/custom/Workout/SetTableHeader.stories.tsx +6 -6
  249. package/src/components/custom/Workout/SetTableHeader.tsx +9 -12
  250. package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +7 -7
  251. package/src/components/custom/Workout/SetsRepsLoad.tsx +24 -12
  252. package/src/components/custom/Workout/Sparkline.stories.tsx +14 -11
  253. package/src/components/custom/Workout/Sparkline.test.tsx +37 -19
  254. package/src/components/custom/Workout/Sparkline.tsx +14 -18
  255. package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
  256. package/src/components/custom/Workout/StatusDot.test.tsx +44 -5
  257. package/src/components/custom/Workout/StatusDot.tsx +93 -63
  258. package/src/components/custom/Workout/StatusPill.stories.tsx +1 -1
  259. package/src/components/custom/Workout/StatusPill.test.tsx +6 -15
  260. package/src/components/custom/Workout/StatusPill.tsx +27 -38
  261. package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +11 -4
  262. package/src/components/custom/Workout/StrengthTrendChart.test.tsx +15 -37
  263. package/src/components/custom/Workout/StrengthTrendChart.tsx +39 -36
  264. package/src/components/custom/Workout/SupersetWrapper.stories.tsx +27 -64
  265. package/src/components/custom/Workout/SupersetWrapper.test.tsx +16 -14
  266. package/src/components/custom/Workout/SupersetWrapper.tsx +17 -21
  267. package/src/components/custom/Workout/TempoDisplay.stories.tsx +26 -10
  268. package/src/components/custom/Workout/TempoDisplay.test.tsx +18 -4
  269. package/src/components/custom/Workout/TempoDisplay.tsx +2 -0
  270. package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +9 -1
  271. package/src/components/custom/Workout/VelocityStrip.compact.stories.tsx +4 -1
  272. package/src/components/custom/Workout/VelocityStrip.dual.stories.tsx +10 -6
  273. package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +5 -2
  274. package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +44 -1
  275. package/src/components/custom/Workout/VelocityStrip.stories.tsx +12 -6
  276. package/src/components/custom/Workout/VelocityStrip.test.tsx +48 -6
  277. package/src/components/custom/Workout/VelocityStrip.tsx +26 -14
  278. package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +6 -7
  279. package/src/components/custom/Workout/VolumeLandmarkBar.tsx +15 -6
  280. package/src/components/custom/Workout/WeekRow.stories.tsx +4 -1
  281. package/src/components/custom/Workout/WeekRow.test.tsx +18 -15
  282. package/src/components/custom/Workout/WeekRow.tsx +23 -16
  283. package/src/components/custom/Workout/WeightBadge.stories.tsx +2 -1
  284. package/src/components/custom/Workout/WeightBadge.test.tsx +50 -19
  285. package/src/components/custom/Workout/WeightBadge.tsx +28 -27
  286. package/src/components/custom/Workout/WorkoutCard.stories.tsx +6 -1
  287. package/src/components/custom/Workout/WorkoutCard.test.tsx +18 -0
  288. package/src/components/custom/Workout/WorkoutCard.tsx +35 -57
  289. package/src/components/custom/Workout/WorkoutPill.stories.tsx +5 -2
  290. package/src/components/custom/Workout/WorkoutPill.test.tsx +39 -7
  291. package/src/components/custom/Workout/WorkoutPill.tsx +88 -57
  292. package/src/components/custom/Workout/ZoneTrack.stories.tsx +10 -7
  293. package/src/components/custom/Workout/ZoneTrack.tsx +10 -9
  294. package/src/components/custom/Workout/exerciseRowState.ts +29 -0
  295. package/src/components/custom/Workout/index.ts +17 -2
  296. package/src/components/custom/Workout/metricText.stories.tsx +15 -13
  297. package/src/components/custom/Workout/metricText.tsx +8 -2
  298. package/src/components/custom/Workout/setHeadingKit.tsx +219 -36
  299. package/src/components/custom/Workout/velocity-story-kit.tsx +2 -2
  300. package/src/components/custom/charts/README.md +66 -0
  301. package/src/components/custom/charts/SetBarChart.test.tsx +46 -1
  302. package/src/components/custom/charts/SetBarChart.tsx +56 -9
  303. package/src/components/custom/charts/SparkBars.stories.tsx +55 -0
  304. package/src/components/custom/charts/SparkBars.test.tsx +69 -0
  305. package/src/components/custom/charts/SparkBars.tsx +85 -0
  306. package/src/components/custom/charts/flatBarGeometry.test.ts +41 -0
  307. package/src/components/custom/charts/flatBarGeometry.ts +32 -0
  308. package/src/components/custom/charts/index.ts +3 -0
  309. package/src/components/custom/index.ts +3 -0
  310. package/src/components/custom/stepper/Stepper.stories.tsx +13 -10
  311. package/src/components/custom/stepper/Stepper.test.tsx +1 -7
  312. package/src/components/custom/stepper/Stepper.tsx +21 -34
  313. package/src/components/icons/icons.stories.tsx +1 -1
  314. package/src/components/icons/icons.tsx +51 -0
  315. package/src/components/shell/AppShell.stories.tsx +150 -0
  316. package/src/components/shell/AppShell.test.tsx +70 -0
  317. package/src/components/shell/AppShell.tsx +90 -0
  318. package/src/components/shell/BrandLockup.stories.tsx +66 -5
  319. package/src/components/shell/BrandLockup.test.tsx +34 -1
  320. package/src/components/shell/BrandLockup.tsx +27 -11
  321. package/src/components/shell/NavItem.stories.tsx +4 -4
  322. package/src/components/shell/NavItem.test.tsx +17 -0
  323. package/src/components/shell/NavItem.tsx +17 -5
  324. package/src/components/shell/README.md +89 -26
  325. package/src/components/shell/SideNav.stories.tsx +38 -7
  326. package/src/components/shell/SideNav.test.tsx +16 -8
  327. package/src/components/shell/SideNav.tsx +17 -17
  328. package/src/components/shell/TopBar.stories.tsx +44 -19
  329. package/src/components/shell/TopBar.test.tsx +34 -12
  330. package/src/components/shell/TopBar.tsx +61 -40
  331. package/src/components/shell/brands.tsx +66 -0
  332. package/src/components/shell/index.ts +9 -8
  333. package/src/components/shell/{DeviceIndicator.stories.tsx → workout/DeviceIndicator.stories.tsx} +2 -2
  334. package/src/components/shell/{DeviceIndicator.tsx → workout/DeviceIndicator.tsx} +2 -2
  335. package/src/components/shell/{DeviceMenu.stories.tsx → workout/DeviceMenu.stories.tsx} +2 -2
  336. package/src/components/shell/{DeviceMenu.tsx → workout/DeviceMenu.tsx} +3 -3
  337. package/src/components/shell/{DeviceRow.stories.tsx → workout/DeviceRow.stories.tsx} +2 -2
  338. package/src/components/shell/{DeviceRow.tsx → workout/DeviceRow.tsx} +3 -3
  339. package/src/components/shell/{SessionStatePill.stories.tsx → workout/SessionStatePill.stories.tsx} +2 -2
  340. package/src/components/shell/{SessionStatePill.tsx → workout/SessionStatePill.tsx} +5 -3
  341. package/src/components/shell/workout/WorkoutShell.stories.tsx +71 -0
  342. package/src/components/shell/{DashboardShell.test.tsx → workout/WorkoutShell.test.tsx} +19 -8
  343. package/src/components/shell/workout/WorkoutShell.tsx +77 -0
  344. package/src/components/shell/workout/WorkoutTopBar.stories.tsx +58 -0
  345. package/src/components/shell/workout/WorkoutTopBar.test.tsx +39 -0
  346. package/src/components/shell/workout/WorkoutTopBar.tsx +52 -0
  347. package/src/components/shell/workout/index.ts +9 -0
  348. package/src/components/shell/workout/workoutNavItems.tsx +16 -0
  349. package/src/components/ui/README.md +110 -0
  350. package/src/components/ui/alert/Alert.stories.tsx +15 -5
  351. package/src/components/ui/alert/Alert.tsx +24 -3
  352. package/src/components/ui/autocomplete/Autocomplete.stories.tsx +11 -13
  353. package/src/components/ui/autocomplete/Autocomplete.test.tsx +7 -25
  354. package/src/components/ui/autocomplete/Autocomplete.tsx +21 -28
  355. package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
  356. package/src/components/ui/avatar/Avatar.tsx +2 -10
  357. package/src/components/ui/badge/Badge.stories.tsx +83 -28
  358. package/src/components/ui/badge/Badge.test.tsx +19 -3
  359. package/src/components/ui/badge/Badge.tsx +48 -55
  360. package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
  361. package/src/components/ui/breadcrumbs/Breadcrumbs.tsx +4 -16
  362. package/src/components/ui/button/Button.stories.tsx +46 -12
  363. package/src/components/ui/button/Button.tsx +44 -37
  364. package/src/components/ui/card/Card.stories.tsx +90 -94
  365. package/src/components/ui/card/Card.test.tsx +80 -6
  366. package/src/components/ui/card/Card.tsx +150 -203
  367. package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
  368. package/src/components/ui/checkbox/Checkbox.tsx +7 -27
  369. package/src/components/ui/chip/Chip.stories.tsx +37 -13
  370. package/src/components/ui/chip/Chip.test.tsx +10 -6
  371. package/src/components/ui/chip/Chip.tsx +76 -91
  372. package/src/components/ui/collapse/Collapse.stories.tsx +23 -23
  373. package/src/components/ui/collapse/Collapse.tsx +6 -11
  374. package/src/components/ui/data-row/DataRow.stories.tsx +14 -3
  375. package/src/components/ui/data-row/DataRow.test.tsx +5 -15
  376. package/src/components/ui/data-row/DataRow.tsx +18 -7
  377. package/src/components/ui/divider/Divider.stories.tsx +1 -1
  378. package/src/components/ui/divider/Divider.tsx +1 -5
  379. package/src/components/ui/drawer/Drawer.stories.tsx +5 -16
  380. package/src/components/ui/drawer/Drawer.tsx +13 -27
  381. package/src/components/ui/floating-overlay-depth.test.tsx +143 -0
  382. package/src/components/ui/form-field/FormField.stories.tsx +6 -20
  383. package/src/components/ui/form-field/FormField.test.tsx +1 -5
  384. package/src/components/ui/form-field/FormField.tsx +10 -46
  385. package/src/components/ui/help-tip/HelpTip.stories.tsx +8 -19
  386. package/src/components/ui/help-tip/HelpTip.test.tsx +1 -3
  387. package/src/components/ui/help-tip/HelpTip.tsx +21 -22
  388. package/src/components/ui/help-tip/index.ts +7 -1
  389. package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
  390. package/src/components/ui/icon-box/IconBox.test.tsx +1 -7
  391. package/src/components/ui/icon-box/IconBox.tsx +10 -18
  392. package/src/components/ui/indicator/Indicator.stories.tsx +5 -4
  393. package/src/components/ui/indicator/Indicator.tsx +20 -14
  394. package/src/components/ui/input/Input.stories.tsx +3 -11
  395. package/src/components/ui/input/Input.test.tsx +2 -10
  396. package/src/components/ui/input/Input.tsx +10 -25
  397. package/src/components/ui/input/index.ts +7 -1
  398. package/src/components/ui/link/Link.stories.tsx +19 -7
  399. package/src/components/ui/list-item/ListItem.stories.tsx +17 -5
  400. package/src/components/ui/list-item/ListItem.tsx +2 -9
  401. package/src/components/ui/menu/Menu.stories.tsx +21 -15
  402. package/src/components/ui/menu/Menu.test.tsx +2 -11
  403. package/src/components/ui/menu/Menu.tsx +12 -14
  404. package/src/components/ui/menu/index.ts +8 -1
  405. package/src/components/ui/modal/Modal.stories.tsx +2 -2
  406. package/src/components/ui/modal/Modal.tsx +31 -19
  407. package/src/components/ui/pill/Pill.stories.tsx +111 -23
  408. package/src/components/ui/pill/Pill.test.tsx +101 -3
  409. package/src/components/ui/pill/Pill.tsx +168 -49
  410. package/src/components/ui/pill/index.ts +1 -1
  411. package/src/components/ui/popover/Popover.stories.tsx +6 -8
  412. package/src/components/ui/popover/Popover.test.tsx +1 -6
  413. package/src/components/ui/popover/Popover.tsx +20 -15
  414. package/src/components/ui/popover/index.ts +7 -1
  415. package/src/components/ui/progress/Progress.stories.tsx +3 -12
  416. package/src/components/ui/progress/Progress.test.tsx +1 -5
  417. package/src/components/ui/progress/Progress.tsx +9 -6
  418. package/src/components/ui/radio/Radio.stories.tsx +42 -21
  419. package/src/components/ui/radio/Radio.test.tsx +6 -2
  420. package/src/components/ui/radio/Radio.tsx +23 -22
  421. package/src/components/ui/section/Section.stories.tsx +12 -21
  422. package/src/components/ui/section/Section.test.tsx +1 -6
  423. package/src/components/ui/section/Section.tsx +1 -3
  424. package/src/components/ui/section/index.ts +1 -5
  425. package/src/components/ui/select/Select.stories.tsx +3 -13
  426. package/src/components/ui/select/Select.test.tsx +2 -11
  427. package/src/components/ui/select/Select.tsx +16 -15
  428. package/src/components/ui/skeleton/Skeleton.stories.tsx +3 -11
  429. package/src/components/ui/skeleton/Skeleton.tsx +3 -14
  430. package/src/components/ui/skeleton/index.ts +1 -7
  431. package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
  432. package/src/components/ui/spinner/Spinner.tsx +4 -5
  433. package/src/components/ui/stack/Stack.stories.tsx +8 -8
  434. package/src/components/ui/stack/Stack.tsx +1 -1
  435. package/src/components/ui/surface/Surface.stories.tsx +92 -33
  436. package/src/components/ui/surface/Surface.test.tsx +88 -28
  437. package/src/components/ui/surface/Surface.tsx +37 -87
  438. package/src/components/ui/surface/SurfaceContext.ts +22 -62
  439. package/src/components/ui/surface/index.ts +8 -0
  440. package/src/components/ui/surface/resolveSurface.ts +98 -0
  441. package/src/components/ui/surface/surface.contract.test.ts +6 -1
  442. package/src/components/ui/switch/Switch.stories.tsx +1 -1
  443. package/src/components/ui/switch/Switch.tsx +7 -6
  444. package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
  445. package/src/components/ui/tabs/Tabs.tsx +8 -21
  446. package/src/components/ui/tabs/index.ts +1 -7
  447. package/src/components/ui/tile/Tile.stories.tsx +1 -1
  448. package/src/components/ui/tile/Tile.tsx +3 -0
  449. package/src/components/ui/toast/Toast.stories.tsx +1 -1
  450. package/src/components/ui/toast/Toast.test.tsx +2 -8
  451. package/src/components/ui/toast/Toast.tsx +49 -57
  452. package/src/components/ui/toast/index.ts +0 -1
  453. package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +92 -71
  454. package/src/components/ui/toolbar-button/ToolbarButton.test.tsx +3 -18
  455. package/src/components/ui/toolbar-button/ToolbarButton.tsx +38 -49
  456. package/src/components/ui/tooltip/Tooltip.stories.tsx +12 -3
  457. package/src/components/ui/tooltip/Tooltip.test.tsx +21 -3
  458. package/src/components/ui/tooltip/Tooltip.tsx +55 -36
  459. package/src/components/ui/tooltip/index.ts +1 -1
  460. package/src/components/ui/trigger/TriggerSurface.test.tsx +215 -0
  461. package/src/components/ui/trigger/TriggerSurface.tsx +81 -0
  462. package/src/components/ui/trigger/index.ts +2 -0
  463. package/src/stories/PresetShowcase.stories.tsx +101 -48
  464. package/src/test/no-device-internals.test.ts +3 -3
  465. package/src/test/no-raw-color.test.ts +39 -0
  466. package/src/theme/Alpha.stories.tsx +103 -0
  467. package/src/theme/ChoosingTokens.stories.tsx +48 -0
  468. package/src/theme/ColorPalettes.stories.tsx +62 -45
  469. package/src/theme/ColorPrimitives.stories.tsx +35 -35
  470. package/src/theme/Depth.stories.tsx +132 -65
  471. package/src/theme/DepthCalibration.stories.tsx +23 -21
  472. package/src/theme/ProposedTokensVW82.stories.tsx +414 -0
  473. package/src/theme/ThemeProvider.test.tsx +4 -4
  474. package/src/theme/barrel.ts +7 -6
  475. package/src/theme/color-stories.coverage.test.ts +1 -1
  476. package/src/theme/color-utils.ts +41 -29
  477. package/src/theme/config.completeness.test.ts +1 -1
  478. package/src/theme/config.ts +40 -0
  479. package/src/theme/elevation.test.ts +82 -56
  480. package/src/theme/elevation.ts +77 -561
  481. package/src/theme/global.css +45 -5
  482. package/src/theme/grey-ramp.test.ts +24 -8
  483. package/src/theme/lift.test.ts +39 -0
  484. package/src/theme/lift.ts +102 -0
  485. package/src/theme/materials.test.ts +5 -2
  486. package/src/theme/materials.ts +38 -4
  487. package/src/theme/native-theming-guard.test.ts +5 -5
  488. package/src/theme/presets/apply.ts +4 -0
  489. package/src/theme/presets/audiobook.ts +5 -2
  490. package/src/theme/presets/default.ts +4 -0
  491. package/src/theme/presets/index.ts +14 -1
  492. package/src/theme/presets/types.ts +1 -1
  493. package/src/theme/semantic-contrast.test.ts +13 -4
  494. package/src/theme/status-distinctness.test.ts +66 -0
  495. package/src/theme/subtle-tone-weight.test.ts +163 -0
  496. package/src/theme/surface-planes.test.ts +37 -0
  497. package/src/theme/surface-planes.ts +68 -0
  498. package/src/theme/tailwind-var-opacity.test.ts +163 -0
  499. package/src/theme/token-export-guard.test.ts +1 -3
  500. package/src/theme/tokens/primitives.test.ts +15 -7
  501. package/src/theme/tokens/primitives.ts +98 -33
  502. package/src/theme/tokens/semantic-hex-guard.test.ts +322 -0
  503. package/src/theme/tokens/semantic.ts +124 -54
  504. package/src/theme/wash-ladder.test.ts +58 -0
  505. package/src/theme/workout-tokens.ts +1 -7
  506. package/src/types/jest-axe.d.ts +2 -6
  507. package/src/types/raw-md.d.ts +5 -0
  508. package/src/utils/colors.alpha-adoption.test.ts +408 -0
  509. package/src/utils/colors.ts +4 -4
  510. package/src/utils/form.ts +1 -3
  511. package/src/utils/index.ts +2 -7
  512. package/src/utils/number-format.ts +17 -0
  513. package/src/utils/workout-format.ts +15 -6
  514. package/src/web-jsx/jsx-runtime.ts +1 -5
  515. package/tailwind.config.js +55 -9
  516. package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +0 -151
  517. package/src/components/custom/Workout/RowInventory.stories.tsx +0 -408
  518. package/src/components/custom/Workout/S3FullRail.stories.tsx +0 -46
  519. package/src/components/custom/Workout/S3SessionPace.stories.tsx +0 -95
  520. package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +0 -61
  521. package/src/components/custom/Workout/S3SetTypes.stories.tsx +0 -176
  522. package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +0 -240
  523. package/src/components/shell/DashboardShell.stories.tsx +0 -65
  524. package/src/components/shell/DashboardShell.tsx +0 -75
  525. package/src/components/shell/SessionRailSpecimen.stories.tsx +0 -753
  526. package/src/theme/elevation.stories.tsx +0 -346
  527. package/src/utils/useTheme.ts +0 -72
  528. /package/src/components/shell/{DeviceIndicator.test.tsx → workout/DeviceIndicator.test.tsx} +0 -0
  529. /package/src/components/shell/{DeviceMenu.test.tsx → workout/DeviceMenu.test.tsx} +0 -0
  530. /package/src/components/shell/{DeviceRow.test.tsx → workout/DeviceRow.test.tsx} +0 -0
  531. /package/src/components/shell/{SessionStatePill.test.tsx → workout/SessionStatePill.test.tsx} +0 -0
@@ -17,7 +17,15 @@
17
17
  * - interactive-* : Hover/focus/active/disabled states
18
18
  */
19
19
 
20
- import { primitiveColors as p, primitiveRamps as ramp, greyRamp, discreteRainbow } from './primitives'
20
+ import {
21
+ primitiveColors as p,
22
+ primitiveRamps as ramp,
23
+ greyRamp,
24
+ discreteRainbow,
25
+ alertRedVivid,
26
+ resultPaletteColors,
27
+ semanticPins,
28
+ } from './primitives'
21
29
 
22
30
  /**
23
31
  * GREY MAPPING (TD-07.14) — how the old cool scales resolved onto `greyRamp`.
@@ -53,6 +61,8 @@ export const semanticColorsLight = {
53
61
  'brand-primary-light': ramp.orange[300],
54
62
  'brand-primary-dark': ramp.orange[500],
55
63
  'brand-primary-subtle': 'rgba(255, 121, 0, 0.08)',
64
+ 'brand-primary-muted': 'rgba(255, 121, 0, 0.30)',
65
+ 'brand-primary-strong': 'rgba(255, 121, 0, 0.50)',
56
66
  'brand-primary-hover': ramp.orange[500],
57
67
  'brand-primary-active': ramp.orange[600],
58
68
 
@@ -60,6 +70,8 @@ export const semanticColorsLight = {
60
70
  'brand-secondary-light': ramp.cyan[500],
61
71
  'brand-secondary-dark': ramp.cyan[700],
62
72
  'brand-secondary-subtle': 'rgba(48, 123, 155, 0.08)',
73
+ 'brand-secondary-muted': 'rgba(48, 123, 155, 0.30)',
74
+ 'brand-secondary-strong': 'rgba(48, 123, 155, 0.50)',
63
75
  'brand-secondary-hover': ramp.cyan[700],
64
76
  'brand-secondary-active': ramp.cyan[800],
65
77
 
@@ -67,11 +79,20 @@ export const semanticColorsLight = {
67
79
  'on-brand-primary': p.white,
68
80
  'on-brand-secondary': p.white,
69
81
 
82
+ // Text ON a `-subtle` fill. Light mode keeps today's pairing (the base token) so
83
+ // nothing moves here: light has the same disease mirrored — a light rung on a
84
+ // near-white ramp[50] fill — but correcting it belongs with the light-mode pass
85
+ // in AW-121, not this one.
86
+ 'on-brand-primary-subtle': ramp.orange[400],
87
+ 'on-brand-secondary-subtle': ramp.cyan[600],
88
+
70
89
  // Status colors (status-*)
71
90
  'status-success': ramp.green[300],
72
91
  'status-success-light': ramp.green[200],
73
92
  'status-success-dark': ramp.green[600],
74
93
  'status-success-subtle': ramp.green[50],
94
+ 'status-success-muted': 'rgba(46, 213, 115, 0.30)',
95
+ 'status-success-strong': 'rgba(46, 213, 115, 0.50)',
75
96
 
76
97
  // Live-session accent — its OWN role, decoupled from success so the two can diverge
77
98
  'status-live': ramp.green[300],
@@ -81,21 +102,35 @@ export const semanticColorsLight = {
81
102
  'status-error-light': ramp.red[500],
82
103
  'status-error-dark': ramp.red[700],
83
104
  'status-error-subtle': ramp.red[50],
105
+ 'status-error-muted': 'rgba(209, 67, 67, 0.30)',
106
+ 'status-error-strong': 'rgba(209, 67, 67, 0.50)',
84
107
 
85
- 'status-error-vivid': ramp.red[600], // vivid alert red
108
+ 'status-error-vivid': alertRedVivid, // NOT red[600], that is status-error
86
109
  'status-error-vivid-light': ramp.red[500],
87
110
  'status-error-vivid-dark': ramp.red[700],
88
111
  'status-error-vivid-subtle': 'rgba(255, 71, 87, 0.12)',
112
+ 'status-error-vivid-muted': 'rgba(255, 71, 87, 0.30)',
113
+ 'status-error-vivid-strong': 'rgba(255, 71, 87, 0.50)',
89
114
 
90
115
  'status-warning': ramp.amber[300],
91
116
  'status-warning-light': ramp.amber[200],
92
117
  'status-warning-dark': ramp.amber[500],
93
118
  'status-warning-subtle': ramp.amber[50],
119
+ 'status-warning-muted': 'rgba(249, 180, 21, 0.30)',
120
+ 'status-warning-strong': 'rgba(249, 180, 21, 0.50)',
94
121
 
95
122
  'status-info': ramp.blue[500],
96
123
  'status-info-light': ramp.blue[300],
97
124
  'status-info-dark': ramp.blue[600],
98
125
  'status-info-subtle': ramp.blue[50],
126
+ 'status-info-muted': 'rgba(33, 150, 243, 0.30)',
127
+ 'status-info-strong': 'rgba(33, 150, 243, 0.50)',
128
+
129
+ // Text ON a `-subtle` fill — see the on-brand-*-subtle note above.
130
+ 'on-status-success-subtle': ramp.green[300],
131
+ 'on-status-error-subtle': ramp.red[600],
132
+ 'on-status-warning-subtle': ramp.amber[300],
133
+ 'on-status-info-subtle': ramp.blue[500],
99
134
 
100
135
  // Text on status backgrounds (on-status-*)
101
136
  'on-status-success': p.white,
@@ -104,15 +139,15 @@ export const semanticColorsLight = {
104
139
  'on-status-info': p.white,
105
140
 
106
141
  // Result/outcome indicators (result-*)
107
- 'result-improve': '#4caf50', // Green - positive outcome
142
+ 'result-improve': resultPaletteColors.improve, // Green - positive outcome
108
143
  'result-improve-light': 'rgba(76, 175, 80, 0.12)',
109
- 'result-improve-dark': '#248a24',
110
- 'result-degrade': '#ef5350', // Red - negative outcome
144
+ 'result-improve-dark': resultPaletteColors.improveDark,
145
+ 'result-degrade': resultPaletteColors.degrade, // Red - negative outcome
111
146
  'result-degrade-light': 'rgba(239, 83, 80, 0.12)',
112
- 'result-degrade-dark': '#b30000',
113
- 'result-inconclusive': '#9E9A97', // Gray - no clear result
147
+ 'result-degrade-dark': resultPaletteColors.degradeDark,
148
+ 'result-inconclusive': resultPaletteColors.inconclusive, // Gray - no clear result
114
149
  'result-inconclusive-light': 'rgba(158, 154, 151, 0.12)',
115
- 'result-neutral': greyRamp[600], // Neutral baseline
150
+ 'result-neutral': greyRamp[600], // Neutral baseline
116
151
 
117
152
  // Text on result backgrounds (on-result-*)
118
153
  'on-result-improve': p.white,
@@ -121,20 +156,20 @@ export const semanticColorsLight = {
121
156
 
122
157
  // Data visualization colors (data-*)
123
158
  // First 10 colors from discrete rainbow optimized for charts
124
- 'data-1': discreteRainbow[9], // Blue
125
- 'data-2': discreteRainbow[14], // Green
126
- 'data-3': discreteRainbow[17], // Yellow
127
- 'data-4': discreteRainbow[25], // Red
128
- 'data-5': discreteRainbow[8], // Purple
129
- 'data-6': discreteRainbow[20], // Orange
130
- 'data-7': discreteRainbow[13], // Light Blue
131
- 'data-8': discreteRainbow[15], // Light Green
132
- 'data-9': discreteRainbow[3], // Lavender
133
- 'data-10': discreteRainbow[22], // Dark Orange
159
+ 'data-1': discreteRainbow[9], // Blue
160
+ 'data-2': discreteRainbow[14], // Green
161
+ 'data-3': discreteRainbow[17], // Yellow
162
+ 'data-4': discreteRainbow[25], // Red
163
+ 'data-5': discreteRainbow[8], // Purple
164
+ 'data-6': discreteRainbow[20], // Orange
165
+ 'data-7': discreteRainbow[13], // Light Blue
166
+ 'data-8': discreteRainbow[15], // Light Green
167
+ 'data-9': discreteRainbow[3], // Lavender
168
+ 'data-10': discreteRainbow[22], // Dark Orange
134
169
 
135
170
  // Text colors (text-*)
136
- 'text-primary': '#121828',
137
- 'text-secondary': '#65748B',
171
+ 'text-primary': semanticPins.textPrimaryLight,
172
+ 'text-secondary': semanticPins.textSecondaryLight,
138
173
  'text-tertiary': greyRamp[400],
139
174
  'text-disabled': 'rgba(55, 65, 81, 0.48)',
140
175
  'text-inverse': p.white,
@@ -143,13 +178,13 @@ export const semanticColorsLight = {
143
178
 
144
179
  // Surface colors (surface-*) - for elevated containers
145
180
  'surface-base': p.white,
146
- 'surface-elevated': greyRamp[50], // slightly off-white for elevated cards
147
- 'surface-raised': greyRamp[100], // light gray for raised cards
181
+ 'surface-elevated': greyRamp[50], // slightly off-white for elevated cards
182
+ 'surface-raised': greyRamp[100], // light gray for raised cards
148
183
  'surface-overlay': p.white,
149
- 'surface-input': greyRamp[50], // Input field background (filled variant)
184
+ 'surface-input': greyRamp[50], // Input field background (filled variant)
150
185
 
151
186
  // Background colors (background-*)
152
- 'background-base': '#EBEBEB',
187
+ 'background-base': semanticPins.backgroundBaseLight,
153
188
  'background-default': p.white,
154
189
  'background-subtle': greyRamp[50],
155
190
  // Frame/bezel chrome — top bar + side nav shell, one step below
@@ -157,12 +192,12 @@ export const semanticColorsLight = {
157
192
  'background-frame': greyRamp[400],
158
193
 
159
194
  // Border colors (border-*)
160
- 'border-prominent': greyRamp[400], // high-visibility divider
195
+ 'border-prominent': greyRamp[400], // high-visibility divider
161
196
  'border-focus': ramp.blue[600],
162
- 'border-input': greyRamp[200], // Input field border
163
- 'border-input-hover': greyRamp[400], // Input field border on hover
164
- 'border-input-focus': ramp.blue[600], // Input field border on focus
165
- 'border-input-error': ramp.red[600], // Input field border on error
197
+ 'border-input': greyRamp[200], // Input field border
198
+ 'border-input-hover': greyRamp[400], // Input field border on hover
199
+ 'border-input-focus': ramp.blue[600], // Input field border on focus
200
+ 'border-input-error': ramp.red[600], // Input field border on error
166
201
 
167
202
  // Alpha hairline separators (surface-independent — composite toward black on
168
203
  // light surfaces, mirroring the dark-mode white-alpha family). See §4/S-2.
@@ -179,7 +214,7 @@ export const semanticColorsLight = {
179
214
  'interactive-disabled-text': 'rgba(55, 65, 81, 0.26)',
180
215
 
181
216
  // Divider
182
- 'divider': '#E8E9EB',
217
+ divider: semanticPins.dividerLight,
183
218
 
184
219
  // Avatar default
185
220
  'avatar-background': greyRamp[600],
@@ -193,13 +228,17 @@ export const semanticColorsDark = {
193
228
  'brand-primary-light': ramp.orange[300],
194
229
  'brand-primary-dark': ramp.orange[500],
195
230
  'brand-primary-subtle': 'rgba(255, 121, 0, 0.12)',
231
+ 'brand-primary-muted': 'rgba(255, 121, 0, 0.30)',
232
+ 'brand-primary-strong': 'rgba(255, 121, 0, 0.50)',
196
233
  'brand-primary-hover': ramp.orange[300],
197
234
  'brand-primary-active': ramp.orange[200],
198
235
 
199
236
  'brand-secondary': ramp.cyan[600],
200
237
  'brand-secondary-light': ramp.cyan[500],
201
238
  'brand-secondary-dark': ramp.cyan[700],
202
- 'brand-secondary-subtle': 'rgba(48, 123, 155, 0.12)',
239
+ 'brand-secondary-subtle': 'rgba(34, 211, 238, 0.12)',
240
+ 'brand-secondary-muted': 'rgba(48, 123, 155, 0.30)',
241
+ 'brand-secondary-strong': 'rgba(48, 123, 155, 0.50)',
203
242
  'brand-secondary-hover': ramp.cyan[500],
204
243
  'brand-secondary-active': ramp.cyan[400],
205
244
 
@@ -207,11 +246,22 @@ export const semanticColorsDark = {
207
246
  'on-brand-primary': p.white,
208
247
  'on-brand-secondary': p.white,
209
248
 
249
+ // Text ON a `-subtle` fill. Its own role: `brand-primary` and friends are tuned to
250
+ // carry a white label as a solid fill, which makes the two deepest of them
251
+ // (cyan[600], red[600]) too dark to read as text on a dark plane. Levelling the
252
+ // family at rung 300 puts every tone within OKLCH L 0.769-0.813 instead of
253
+ // 0.550-0.813. Brand is deliberately left at its own orange[400] (operator, AW-133)
254
+ // so the Voltras tone never drifts; it is the one tone under AA on a raised card.
255
+ 'on-brand-primary-subtle': ramp.orange[400],
256
+ 'on-brand-secondary-subtle': ramp.cyan[300],
257
+
210
258
  // Status colors
211
259
  'status-success': ramp.green[300],
212
260
  'status-success-light': ramp.green[200],
213
261
  'status-success-dark': ramp.green[600],
214
262
  'status-success-subtle': 'rgba(46, 213, 115, 0.12)',
263
+ 'status-success-muted': 'rgba(46, 213, 115, 0.30)',
264
+ 'status-success-strong': 'rgba(46, 213, 115, 0.50)',
215
265
 
216
266
  // Live-session accent — its OWN role, decoupled from success so the two can diverge
217
267
  'status-live': ramp.green[300],
@@ -220,22 +270,33 @@ export const semanticColorsDark = {
220
270
  'status-error': ramp.red[600],
221
271
  'status-error-light': ramp.red[500],
222
272
  'status-error-dark': ramp.red[700],
223
- 'status-error-subtle': 'rgba(209, 67, 67, 0.12)',
224
-
225
- 'status-error-vivid': ramp.red[600],
273
+ // Alpha 0.08, not the family's 0.12: error's label is red[400], a rung darker than
274
+ // its siblings so it reads RED rather than pink (rung 300 has only 0.121 chroma).
275
+ // Thinning the fill buys back the contrast that extra darkness costs. See AW-133.
276
+ 'status-error-subtle': 'rgba(247, 113, 117, 0.08)',
277
+ 'status-error-muted': 'rgba(209, 67, 67, 0.30)',
278
+ 'status-error-strong': 'rgba(209, 67, 67, 0.50)',
279
+
280
+ 'status-error-vivid': alertRedVivid,
226
281
  'status-error-vivid-light': ramp.red[500],
227
282
  'status-error-vivid-dark': ramp.red[700],
228
283
  'status-error-vivid-subtle': 'rgba(255, 71, 87, 0.12)',
284
+ 'status-error-vivid-muted': 'rgba(255, 71, 87, 0.30)',
285
+ 'status-error-vivid-strong': 'rgba(255, 71, 87, 0.50)',
229
286
 
230
287
  'status-warning': ramp.amber[300],
231
288
  'status-warning-light': ramp.amber[200],
232
289
  'status-warning-dark': ramp.amber[500],
233
290
  'status-warning-subtle': 'rgba(249, 180, 21, 0.12)',
291
+ 'status-warning-muted': 'rgba(249, 180, 21, 0.30)',
292
+ 'status-warning-strong': 'rgba(249, 180, 21, 0.50)',
234
293
 
235
294
  'status-info': ramp.blue[500],
236
295
  'status-info-light': ramp.blue[300],
237
296
  'status-info-dark': ramp.blue[600],
238
- 'status-info-subtle': 'rgba(33, 150, 243, 0.12)',
297
+ 'status-info-subtle': 'rgba(120, 194, 255, 0.12)',
298
+ 'status-info-muted': 'rgba(33, 150, 243, 0.30)',
299
+ 'status-info-strong': 'rgba(33, 150, 243, 0.50)',
239
300
 
240
301
  // Text on status backgrounds
241
302
  'on-status-success': p.white,
@@ -243,14 +304,23 @@ export const semanticColorsDark = {
243
304
  'on-status-warning': p.white,
244
305
  'on-status-info': p.white,
245
306
 
307
+ // Text ON a `-subtle` fill — see the on-brand-*-subtle note above. Error is the
308
+ // second deliberate exception to the rung-300 rule (operator, AW-133): red[300]
309
+ // levelled perfectly but read PINK, because a red that light can only hold 0.121
310
+ // chroma. red[400] carries 0.165 and reads red; its fill is thinned to compensate.
311
+ 'on-status-success-subtle': ramp.green[300],
312
+ 'on-status-error-subtle': ramp.red[400],
313
+ 'on-status-warning-subtle': ramp.amber[300],
314
+ 'on-status-info-subtle': ramp.blue[300],
315
+
246
316
  // Result/outcome indicators (result-*)
247
- 'result-improve': '#4caf50',
317
+ 'result-improve': resultPaletteColors.improve,
248
318
  'result-improve-light': 'rgba(76, 175, 80, 0.16)',
249
- 'result-improve-dark': '#248a24',
250
- 'result-degrade': '#ef5350',
319
+ 'result-improve-dark': resultPaletteColors.improveDark,
320
+ 'result-degrade': resultPaletteColors.degrade,
251
321
  'result-degrade-light': 'rgba(239, 83, 80, 0.16)',
252
- 'result-degrade-dark': '#b30000',
253
- 'result-inconclusive': '#9E9A97',
322
+ 'result-degrade-dark': resultPaletteColors.degradeDark,
323
+ 'result-inconclusive': resultPaletteColors.inconclusive,
254
324
  'result-inconclusive-light': 'rgba(158, 154, 151, 0.16)',
255
325
  'result-neutral': greyRamp[400],
256
326
 
@@ -284,7 +354,7 @@ export const semanticColorsDark = {
284
354
  'text-tertiary': greyRamp[500],
285
355
  'text-disabled': 'rgba(255, 255, 255, 0.38)',
286
356
  'text-inverse': greyRamp[950],
287
- 'text-link': '#828DF8',
357
+ 'text-link': semanticPins.focusIndigoDark,
288
358
  'text-link-hover': ramp.blue[400],
289
359
 
290
360
  // Surface colors - dark backgrounds — warm-tapered DERIVED ramp (TD-surface-tokens,
@@ -295,20 +365,20 @@ export const semanticColorsDark = {
295
365
  // `background-base` backs `Surface level="background"` (SurfaceContext.SURFACE_LEVEL_TOKEN),
296
366
  // so it takes the ramp's shell role. The deepest plane is `background-frame`,
297
367
  // which is also the `SurfaceLevel` floor a pressed surface clamps at.
298
- 'surface-base': greyRamp[925], // main surface (#252321, L*13.9)
299
- 'surface-elevated': greyRamp[900], // elevated surface (#2C2A28, L*17.2 — nav/rail)
300
- 'surface-raised': greyRamp[875], // raised surface (#31302F, L*19.9 — cards)
301
- 'surface-overlay': greyRamp[850], // overlay surface (#373635, L*22.7 — hero/popover)
302
- 'surface-input': greyRamp[900], // input surface (#2C2A28 — one plane above base)
368
+ 'surface-base': greyRamp[925], // main surface (#252321, L*13.9)
369
+ 'surface-elevated': greyRamp[900], // elevated surface (#2C2A28, L*17.2 — nav/rail)
370
+ 'surface-raised': greyRamp[875], // raised surface (#31302F, L*19.9 — cards)
371
+ 'surface-overlay': greyRamp[850], // overlay surface (#373635, L*22.7 — hero/popover)
372
+ 'surface-input': greyRamp[900], // input surface (#2C2A28 — one plane above base)
303
373
 
304
374
  // Background colors — same ramp, the frame/shell end of it.
305
- 'background-base': greyRamp[950], // shell (#1C1916, L*9 — Surface level="background")
306
- 'background-default': greyRamp[925], // main background (#252321, L*13.9 — matches surface-base)
307
- 'background-subtle': greyRamp[900], // subtle background (#2C2A28, L*17.2 — matches surface-elevated)
375
+ 'background-base': greyRamp[950], // shell (#1C1916, L*9 — Surface level="background")
376
+ 'background-default': greyRamp[925], // main background (#252321, L*13.9 — matches surface-base)
377
+ 'background-subtle': greyRamp[900], // subtle background (#2C2A28, L*17.2 — matches surface-elevated)
308
378
  // Frame/bezel chrome — the top bar + side nav shell, one step BELOW
309
379
  // `background-base`. It used to be described as sitting OUTSIDE the ramp; it
310
380
  // is simply the ramp's last step now, and the floor `<Surface pressed>` clamps at.
311
- 'background-frame': greyRamp[975], // frame / bezel (#100D0A, L*3.8)
381
+ 'background-frame': greyRamp[975], // frame / bezel (#100D0A, L*3.8)
312
382
 
313
383
  // Border colors — solid dark borders are RETIRED (TD-07.14). Not a preference — a structural
314
384
  // consequence of one ramp. Every step from 850 to 975 is now a surface plane,
@@ -326,11 +396,11 @@ export const semanticColorsDark = {
326
396
  // `border-prominent` stays SOLID: it is the one border meant to be seen
327
397
  // outright (4 call sites, high-visibility dividers), and grey-800 is not a
328
398
  // plane, so it keeps its job without collision.
329
- 'border-prominent': greyRamp[800], // high-visibility divider
330
- 'border-focus': '#828DF8',
399
+ 'border-prominent': greyRamp[800], // high-visibility divider
400
+ 'border-focus': semanticPins.focusIndigoDark,
331
401
  'border-input': greyRamp[700],
332
402
  'border-input-hover': greyRamp[600],
333
- 'border-input-focus': '#828DF8',
403
+ 'border-input-focus': semanticPins.focusIndigoDark,
334
404
  'border-input-error': ramp.red[500],
335
405
 
336
406
  // Alpha hairline separators — the primary separation cue (§4/S-2). Self-
@@ -376,7 +446,7 @@ export const semanticColorsDark = {
376
446
  'interactive-disabled-text': 'rgba(255, 255, 255, 0.26)',
377
447
 
378
448
  // Divider
379
- 'divider': 'rgba(255, 255, 255, 0.09)',
449
+ divider: 'rgba(255, 255, 255, 0.09)',
380
450
 
381
451
  // Avatar default
382
452
  'avatar-background': greyRamp[700],
@@ -0,0 +1,58 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { semanticColorsDark, semanticColorsLight } from './tokens/semantic'
3
+
4
+ /**
5
+ * Status and brand roles publish three wash rungs. They exist so a component can
6
+ * express a weight ramp without hand-mixing alpha: MesoProgressBar's segment
7
+ * track collapsed to one weight in three hues when only `-subtle` was available.
8
+ *
9
+ * A rung that drifts out of order silently flattens every consumer, and the
10
+ * consumer's own test cannot catch it — under the RNW vitest alias the rendered
11
+ * value is a `var(...)` reference, not an rgba triplet.
12
+ */
13
+ const WASH_ROLES = [
14
+ 'brand-primary',
15
+ 'brand-secondary',
16
+ 'status-success',
17
+ 'status-error',
18
+ 'status-error-vivid',
19
+ 'status-warning',
20
+ 'status-info',
21
+ ] as const
22
+
23
+ const RUNGS = ['subtle', 'muted', 'strong'] as const
24
+
25
+ function alphaOf(value: string): number {
26
+ const parts = value.match(/rgba?\(([^)]+)\)/)?.[1].split(',')
27
+ if (!parts) return 1 // a solid ramp pin is fully opaque
28
+ return parts.length === 4 ? Number(parts[3].trim()) : 1
29
+ }
30
+
31
+ describe('wash ladder', () => {
32
+ for (const [mode, palette] of [
33
+ ['dark', semanticColorsDark],
34
+ ['light', semanticColorsLight],
35
+ ] as const) {
36
+ describe(mode, () => {
37
+ for (const role of WASH_ROLES) {
38
+ it(`${role} publishes all three rungs`, () => {
39
+ for (const rung of RUNGS) {
40
+ expect(palette, `${role}-${rung} is missing`).toHaveProperty(`${role}-${rung}`)
41
+ }
42
+ })
43
+ }
44
+ })
45
+ }
46
+
47
+ // Light mode's `-subtle` is still a solid ramp tint rather than a wash, so its
48
+ // ladder is not comparable yet. AW-121 owns bringing light onto this model.
49
+ for (const role of WASH_ROLES) {
50
+ it(`${role} rungs ascend in weight (dark)`, () => {
51
+ const [subtle, muted, strong] = RUNGS.map((r) =>
52
+ alphaOf(semanticColorsDark[`${role}-${r}` as keyof typeof semanticColorsDark] as string)
53
+ )
54
+ expect(muted, `${role}-muted must outweigh -subtle`).toBeGreaterThan(subtle)
55
+ expect(strong, `${role}-strong must outweigh -muted`).toBeGreaterThan(muted)
56
+ })
57
+ }
58
+ })
@@ -48,13 +48,7 @@ export const WORKOUT_TOKENS = {
48
48
  over2: ramp.red[700],
49
49
  over3: ramp.red[800],
50
50
  targetLine: 'rgba(33, 150, 243, 0.5)',
51
- atTargetGlow:
52
- '0 0 5px 1px rgba(33, 150, 243, 0.35), 0 0 10px 3px rgba(33, 150, 243, 0.15)',
53
- },
54
-
55
- // Placeholder strip
56
- placeholder: {
57
- fill: '#3A3A3A',
51
+ atTargetGlow: '0 0 5px 1px rgba(33, 150, 243, 0.35), 0 0 10px 3px rgba(33, 150, 243, 0.15)',
58
52
  },
59
53
 
60
54
  // Deviation bar
@@ -5,12 +5,8 @@ declare module 'jest-axe' {
5
5
  ): Promise<{ violations: unknown[] }>
6
6
 
7
7
  export const toHaveNoViolations: {
8
- toHaveNoViolations(
9
- results: { violations: unknown[] }
10
- ): { pass: boolean; message(): string }
8
+ toHaveNoViolations(results: { violations: unknown[] }): { pass: boolean; message(): string }
11
9
  }
12
10
 
13
- export function configureAxe(
14
- options?: Record<string, unknown>
15
- ): typeof axe
11
+ export function configureAxe(options?: Record<string, unknown>): typeof axe
16
12
  }
@@ -0,0 +1,5 @@
1
+ /** Vite's `?raw` suffix — imports a file's contents as a string. */
2
+ declare module '*.md?raw' {
3
+ const content: string
4
+ export default content
5
+ }