@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
@@ -11,6 +11,27 @@ var primitiveColors = {
11
11
  black: "#000000",
12
12
  transparent: "transparent"
13
13
  };
14
+ var alertRedVivid = "#FF4757";
15
+ var resultPaletteColors = {
16
+ improve: "#4caf50",
17
+ improveDark: "#248a24",
18
+ degrade: "#ef5350",
19
+ degradeDark: "#b30000",
20
+ inconclusive: "#9E9A97"
21
+ };
22
+ var semanticPins = {
23
+ // Cool navy-black; darker and more blue-shifted than any warm greyRamp step.
24
+ textPrimaryLight: "#121828",
25
+ // Cool blue-grey; outside greyRamp's warm (R>=G>=B) scale.
26
+ textSecondaryLight: "#65748B",
27
+ // Pure neutral grey (R=G=B); no warm greyRamp step lands on it exactly.
28
+ backgroundBaseLight: "#EBEBEB",
29
+ // Near-neutral grey, kept one step off backgroundBaseLight by design.
30
+ dividerLight: "#E8E9EB",
31
+ // Periwinkle/indigo; more purple than any primitiveRamps.blue step. Shared by
32
+ // dark-mode text-link, border-focus and border-input-focus.
33
+ focusIndigoDark: "#828DF8"
34
+ };
14
35
  var greyRamp = {
15
36
  50: "#F9F6F3",
16
37
  // L*97.0 W6
@@ -272,12 +293,30 @@ function getDiscreteRainbowColor(index, size) {
272
293
  }
273
294
  var primitiveTypography = {
274
295
  fontFamilies: {
275
- sans: ["Inter", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Helvetica", "Arial", "sans-serif"],
296
+ sans: [
297
+ "Inter",
298
+ "-apple-system",
299
+ "BlinkMacSystemFont",
300
+ "Segoe UI",
301
+ "Helvetica",
302
+ "Arial",
303
+ "sans-serif"
304
+ ],
276
305
  body: ["Nunito Sans", "sans-serif"],
277
306
  heading: ["Space Grotesk", "sans-serif"],
278
- mono: ["SF Mono", "Monaco", "Inconsolata", "Fira Mono", "Droid Sans Mono", "Source Code Pro", "monospace"]
307
+ mono: [
308
+ "SF Mono",
309
+ "Monaco",
310
+ "Inconsolata",
311
+ "Fira Mono",
312
+ "Droid Sans Mono",
313
+ "Source Code Pro",
314
+ "monospace"
315
+ ]
279
316
  },
280
317
  fontSizes: {
318
+ "2xs": "0.625rem",
319
+ // 10px
281
320
  xs: "0.75rem",
282
321
  // 12px
283
322
  sm: "0.875rem",
@@ -410,22 +449,34 @@ var semanticColorsLight = {
410
449
  "brand-primary-light": primitiveRamps.orange[300],
411
450
  "brand-primary-dark": primitiveRamps.orange[500],
412
451
  "brand-primary-subtle": "rgba(255, 121, 0, 0.08)",
452
+ "brand-primary-muted": "rgba(255, 121, 0, 0.30)",
453
+ "brand-primary-strong": "rgba(255, 121, 0, 0.50)",
413
454
  "brand-primary-hover": primitiveRamps.orange[500],
414
455
  "brand-primary-active": primitiveRamps.orange[600],
415
456
  "brand-secondary": primitiveRamps.cyan[600],
416
457
  "brand-secondary-light": primitiveRamps.cyan[500],
417
458
  "brand-secondary-dark": primitiveRamps.cyan[700],
418
459
  "brand-secondary-subtle": "rgba(48, 123, 155, 0.08)",
460
+ "brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
461
+ "brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
419
462
  "brand-secondary-hover": primitiveRamps.cyan[700],
420
463
  "brand-secondary-active": primitiveRamps.cyan[800],
421
464
  // Text on brand backgrounds (on-*)
422
465
  "on-brand-primary": primitiveColors.white,
423
466
  "on-brand-secondary": primitiveColors.white,
467
+ // Text ON a `-subtle` fill. Light mode keeps today's pairing (the base token) so
468
+ // nothing moves here: light has the same disease mirrored — a light rung on a
469
+ // near-white ramp[50] fill — but correcting it belongs with the light-mode pass
470
+ // in AW-121, not this one.
471
+ "on-brand-primary-subtle": primitiveRamps.orange[400],
472
+ "on-brand-secondary-subtle": primitiveRamps.cyan[600],
424
473
  // Status colors (status-*)
425
474
  "status-success": primitiveRamps.green[300],
426
475
  "status-success-light": primitiveRamps.green[200],
427
476
  "status-success-dark": primitiveRamps.green[600],
428
477
  "status-success-subtle": primitiveRamps.green[50],
478
+ "status-success-muted": "rgba(46, 213, 115, 0.30)",
479
+ "status-success-strong": "rgba(46, 213, 115, 0.50)",
429
480
  // Live-session accent — its OWN role, decoupled from success so the two can diverge
430
481
  "status-live": primitiveRamps.green[300],
431
482
  "status-live-muted": primitiveRamps.green[500],
@@ -433,34 +484,47 @@ var semanticColorsLight = {
433
484
  "status-error-light": primitiveRamps.red[500],
434
485
  "status-error-dark": primitiveRamps.red[700],
435
486
  "status-error-subtle": primitiveRamps.red[50],
436
- "status-error-vivid": primitiveRamps.red[600],
437
- // vivid alert red
487
+ "status-error-muted": "rgba(209, 67, 67, 0.30)",
488
+ "status-error-strong": "rgba(209, 67, 67, 0.50)",
489
+ "status-error-vivid": alertRedVivid,
490
+ // NOT red[600], that is status-error
438
491
  "status-error-vivid-light": primitiveRamps.red[500],
439
492
  "status-error-vivid-dark": primitiveRamps.red[700],
440
493
  "status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
494
+ "status-error-vivid-muted": "rgba(255, 71, 87, 0.30)",
495
+ "status-error-vivid-strong": "rgba(255, 71, 87, 0.50)",
441
496
  "status-warning": primitiveRamps.amber[300],
442
497
  "status-warning-light": primitiveRamps.amber[200],
443
498
  "status-warning-dark": primitiveRamps.amber[500],
444
499
  "status-warning-subtle": primitiveRamps.amber[50],
500
+ "status-warning-muted": "rgba(249, 180, 21, 0.30)",
501
+ "status-warning-strong": "rgba(249, 180, 21, 0.50)",
445
502
  "status-info": primitiveRamps.blue[500],
446
503
  "status-info-light": primitiveRamps.blue[300],
447
504
  "status-info-dark": primitiveRamps.blue[600],
448
505
  "status-info-subtle": primitiveRamps.blue[50],
506
+ "status-info-muted": "rgba(33, 150, 243, 0.30)",
507
+ "status-info-strong": "rgba(33, 150, 243, 0.50)",
508
+ // Text ON a `-subtle` fill — see the on-brand-*-subtle note above.
509
+ "on-status-success-subtle": primitiveRamps.green[300],
510
+ "on-status-error-subtle": primitiveRamps.red[600],
511
+ "on-status-warning-subtle": primitiveRamps.amber[300],
512
+ "on-status-info-subtle": primitiveRamps.blue[500],
449
513
  // Text on status backgrounds (on-status-*)
450
514
  "on-status-success": primitiveColors.white,
451
515
  "on-status-error": primitiveColors.white,
452
516
  "on-status-warning": primitiveColors.white,
453
517
  "on-status-info": primitiveColors.white,
454
518
  // Result/outcome indicators (result-*)
455
- "result-improve": "#4caf50",
519
+ "result-improve": resultPaletteColors.improve,
456
520
  // Green - positive outcome
457
521
  "result-improve-light": "rgba(76, 175, 80, 0.12)",
458
- "result-improve-dark": "#248a24",
459
- "result-degrade": "#ef5350",
522
+ "result-improve-dark": resultPaletteColors.improveDark,
523
+ "result-degrade": resultPaletteColors.degrade,
460
524
  // Red - negative outcome
461
525
  "result-degrade-light": "rgba(239, 83, 80, 0.12)",
462
- "result-degrade-dark": "#b30000",
463
- "result-inconclusive": "#9E9A97",
526
+ "result-degrade-dark": resultPaletteColors.degradeDark,
527
+ "result-inconclusive": resultPaletteColors.inconclusive,
464
528
  // Gray - no clear result
465
529
  "result-inconclusive-light": "rgba(158, 154, 151, 0.12)",
466
530
  "result-neutral": greyRamp[600],
@@ -492,8 +556,8 @@ var semanticColorsLight = {
492
556
  "data-10": discreteRainbow[22],
493
557
  // Dark Orange
494
558
  // Text colors (text-*)
495
- "text-primary": "#121828",
496
- "text-secondary": "#65748B",
559
+ "text-primary": semanticPins.textPrimaryLight,
560
+ "text-secondary": semanticPins.textSecondaryLight,
497
561
  "text-tertiary": greyRamp[400],
498
562
  "text-disabled": "rgba(55, 65, 81, 0.48)",
499
563
  "text-inverse": primitiveColors.white,
@@ -509,7 +573,7 @@ var semanticColorsLight = {
509
573
  "surface-input": greyRamp[50],
510
574
  // Input field background (filled variant)
511
575
  // Background colors (background-*)
512
- "background-base": "#EBEBEB",
576
+ "background-base": semanticPins.backgroundBaseLight,
513
577
  "background-default": primitiveColors.white,
514
578
  "background-subtle": greyRamp[50],
515
579
  // Frame/bezel chrome — top bar + side nav shell, one step below
@@ -540,7 +604,7 @@ var semanticColorsLight = {
540
604
  "interactive-disabled": "rgba(55, 65, 81, 0.12)",
541
605
  "interactive-disabled-text": "rgba(55, 65, 81, 0.26)",
542
606
  // Divider
543
- "divider": "#E8E9EB",
607
+ divider: semanticPins.dividerLight,
544
608
  // Avatar default
545
609
  "avatar-background": greyRamp[600],
546
610
  "avatar-text": primitiveColors.white
@@ -551,54 +615,87 @@ var semanticColorsDark = {
551
615
  "brand-primary-light": primitiveRamps.orange[300],
552
616
  "brand-primary-dark": primitiveRamps.orange[500],
553
617
  "brand-primary-subtle": "rgba(255, 121, 0, 0.12)",
618
+ "brand-primary-muted": "rgba(255, 121, 0, 0.30)",
619
+ "brand-primary-strong": "rgba(255, 121, 0, 0.50)",
554
620
  "brand-primary-hover": primitiveRamps.orange[300],
555
621
  "brand-primary-active": primitiveRamps.orange[200],
556
622
  "brand-secondary": primitiveRamps.cyan[600],
557
623
  "brand-secondary-light": primitiveRamps.cyan[500],
558
624
  "brand-secondary-dark": primitiveRamps.cyan[700],
559
- "brand-secondary-subtle": "rgba(48, 123, 155, 0.12)",
625
+ "brand-secondary-subtle": "rgba(34, 211, 238, 0.12)",
626
+ "brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
627
+ "brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
560
628
  "brand-secondary-hover": primitiveRamps.cyan[500],
561
629
  "brand-secondary-active": primitiveRamps.cyan[400],
562
630
  // Text on brand backgrounds
563
631
  "on-brand-primary": primitiveColors.white,
564
632
  "on-brand-secondary": primitiveColors.white,
633
+ // Text ON a `-subtle` fill. Its own role: `brand-primary` and friends are tuned to
634
+ // carry a white label as a solid fill, which makes the two deepest of them
635
+ // (cyan[600], red[600]) too dark to read as text on a dark plane. Levelling the
636
+ // family at rung 300 puts every tone within OKLCH L 0.769-0.813 instead of
637
+ // 0.550-0.813. Brand is deliberately left at its own orange[400] (operator, AW-133)
638
+ // so the Voltras tone never drifts; it is the one tone under AA on a raised card.
639
+ "on-brand-primary-subtle": primitiveRamps.orange[400],
640
+ "on-brand-secondary-subtle": primitiveRamps.cyan[300],
565
641
  // Status colors
566
642
  "status-success": primitiveRamps.green[300],
567
643
  "status-success-light": primitiveRamps.green[200],
568
644
  "status-success-dark": primitiveRamps.green[600],
569
645
  "status-success-subtle": "rgba(46, 213, 115, 0.12)",
646
+ "status-success-muted": "rgba(46, 213, 115, 0.30)",
647
+ "status-success-strong": "rgba(46, 213, 115, 0.50)",
570
648
  // Live-session accent — its OWN role, decoupled from success so the two can diverge
571
649
  "status-live": primitiveRamps.green[300],
572
650
  "status-live-muted": primitiveRamps.green[500],
573
651
  "status-error": primitiveRamps.red[600],
574
652
  "status-error-light": primitiveRamps.red[500],
575
653
  "status-error-dark": primitiveRamps.red[700],
576
- "status-error-subtle": "rgba(209, 67, 67, 0.12)",
577
- "status-error-vivid": primitiveRamps.red[600],
654
+ // Alpha 0.08, not the family's 0.12: error's label is red[400], a rung darker than
655
+ // its siblings so it reads RED rather than pink (rung 300 has only 0.121 chroma).
656
+ // Thinning the fill buys back the contrast that extra darkness costs. See AW-133.
657
+ "status-error-subtle": "rgba(247, 113, 117, 0.08)",
658
+ "status-error-muted": "rgba(209, 67, 67, 0.30)",
659
+ "status-error-strong": "rgba(209, 67, 67, 0.50)",
660
+ "status-error-vivid": alertRedVivid,
578
661
  "status-error-vivid-light": primitiveRamps.red[500],
579
662
  "status-error-vivid-dark": primitiveRamps.red[700],
580
663
  "status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
664
+ "status-error-vivid-muted": "rgba(255, 71, 87, 0.30)",
665
+ "status-error-vivid-strong": "rgba(255, 71, 87, 0.50)",
581
666
  "status-warning": primitiveRamps.amber[300],
582
667
  "status-warning-light": primitiveRamps.amber[200],
583
668
  "status-warning-dark": primitiveRamps.amber[500],
584
669
  "status-warning-subtle": "rgba(249, 180, 21, 0.12)",
670
+ "status-warning-muted": "rgba(249, 180, 21, 0.30)",
671
+ "status-warning-strong": "rgba(249, 180, 21, 0.50)",
585
672
  "status-info": primitiveRamps.blue[500],
586
673
  "status-info-light": primitiveRamps.blue[300],
587
674
  "status-info-dark": primitiveRamps.blue[600],
588
- "status-info-subtle": "rgba(33, 150, 243, 0.12)",
675
+ "status-info-subtle": "rgba(120, 194, 255, 0.12)",
676
+ "status-info-muted": "rgba(33, 150, 243, 0.30)",
677
+ "status-info-strong": "rgba(33, 150, 243, 0.50)",
589
678
  // Text on status backgrounds
590
679
  "on-status-success": primitiveColors.white,
591
680
  "on-status-error": primitiveColors.white,
592
681
  "on-status-warning": primitiveColors.white,
593
682
  "on-status-info": primitiveColors.white,
683
+ // Text ON a `-subtle` fill — see the on-brand-*-subtle note above. Error is the
684
+ // second deliberate exception to the rung-300 rule (operator, AW-133): red[300]
685
+ // levelled perfectly but read PINK, because a red that light can only hold 0.121
686
+ // chroma. red[400] carries 0.165 and reads red; its fill is thinned to compensate.
687
+ "on-status-success-subtle": primitiveRamps.green[300],
688
+ "on-status-error-subtle": primitiveRamps.red[400],
689
+ "on-status-warning-subtle": primitiveRamps.amber[300],
690
+ "on-status-info-subtle": primitiveRamps.blue[300],
594
691
  // Result/outcome indicators (result-*)
595
- "result-improve": "#4caf50",
692
+ "result-improve": resultPaletteColors.improve,
596
693
  "result-improve-light": "rgba(76, 175, 80, 0.16)",
597
- "result-improve-dark": "#248a24",
598
- "result-degrade": "#ef5350",
694
+ "result-improve-dark": resultPaletteColors.improveDark,
695
+ "result-degrade": resultPaletteColors.degrade,
599
696
  "result-degrade-light": "rgba(239, 83, 80, 0.16)",
600
- "result-degrade-dark": "#b30000",
601
- "result-inconclusive": "#9E9A97",
697
+ "result-degrade-dark": resultPaletteColors.degradeDark,
698
+ "result-inconclusive": resultPaletteColors.inconclusive,
602
699
  "result-inconclusive-light": "rgba(158, 154, 151, 0.16)",
603
700
  "result-neutral": greyRamp[400],
604
701
  // Text on result backgrounds
@@ -629,7 +726,7 @@ var semanticColorsDark = {
629
726
  "text-tertiary": greyRamp[500],
630
727
  "text-disabled": "rgba(255, 255, 255, 0.38)",
631
728
  "text-inverse": greyRamp[950],
632
- "text-link": "#828DF8",
729
+ "text-link": semanticPins.focusIndigoDark,
633
730
  "text-link-hover": primitiveRamps.blue[400],
634
731
  // Surface colors - dark backgrounds — warm-tapered DERIVED ramp (TD-surface-tokens,
635
732
  // S-1, re-spaced S-3). Shipped verbatim from `deriveSurfaceRamp()` — see
@@ -679,10 +776,10 @@ var semanticColorsDark = {
679
776
  // plane, so it keeps its job without collision.
680
777
  "border-prominent": greyRamp[800],
681
778
  // high-visibility divider
682
- "border-focus": "#828DF8",
779
+ "border-focus": semanticPins.focusIndigoDark,
683
780
  "border-input": greyRamp[700],
684
781
  "border-input-hover": greyRamp[600],
685
- "border-input-focus": "#828DF8",
782
+ "border-input-focus": semanticPins.focusIndigoDark,
686
783
  "border-input-error": primitiveRamps.red[500],
687
784
  // Alpha hairline separators — the primary separation cue (§4/S-2). Self-
688
785
  // normalizing: composites toward white by ~the same amount on ANY plane, so
@@ -725,7 +822,7 @@ var semanticColorsDark = {
725
822
  "interactive-disabled": "rgba(255, 255, 255, 0.12)",
726
823
  "interactive-disabled-text": "rgba(255, 255, 255, 0.26)",
727
824
  // Divider
728
- "divider": "rgba(255, 255, 255, 0.09)",
825
+ divider: "rgba(255, 255, 255, 0.09)",
729
826
  // Avatar default
730
827
  "avatar-background": greyRamp[700],
731
828
  "avatar-text": primitiveColors.white
@@ -864,26 +961,42 @@ var lightThemeCSSVars = {
864
961
  "--color-brand-primary-light": semanticColorsLight["brand-primary-light"],
865
962
  "--color-brand-primary-dark": semanticColorsLight["brand-primary-dark"],
866
963
  "--color-brand-primary-subtle": semanticColorsLight["brand-primary-subtle"],
964
+ "--color-brand-primary-muted": semanticColorsLight["brand-primary-muted"],
965
+ "--color-brand-primary-strong": semanticColorsLight["brand-primary-strong"],
867
966
  "--color-brand-secondary": semanticColorsLight["brand-secondary"],
868
967
  "--color-brand-secondary-light": semanticColorsLight["brand-secondary-light"],
869
968
  "--color-brand-secondary-dark": semanticColorsLight["brand-secondary-dark"],
870
969
  "--color-brand-secondary-subtle": semanticColorsLight["brand-secondary-subtle"],
970
+ "--color-brand-secondary-muted": semanticColorsLight["brand-secondary-muted"],
971
+ "--color-brand-secondary-strong": semanticColorsLight["brand-secondary-strong"],
871
972
  "--color-on-brand-primary": semanticColorsLight["on-brand-primary"],
872
973
  "--color-on-brand-secondary": semanticColorsLight["on-brand-secondary"],
974
+ "--color-on-brand-primary-subtle": semanticColorsLight["on-brand-primary-subtle"],
975
+ "--color-on-brand-secondary-subtle": semanticColorsLight["on-brand-secondary-subtle"],
873
976
  "--color-status-success": semanticColorsLight["status-success"],
874
977
  "--color-status-success-subtle": semanticColorsLight["status-success-subtle"],
978
+ "--color-status-success-muted": semanticColorsLight["status-success-muted"],
979
+ "--color-status-success-strong": semanticColorsLight["status-success-strong"],
875
980
  "--color-status-live": semanticColorsLight["status-live"],
876
981
  "--color-status-live-muted": semanticColorsLight["status-live-muted"],
877
982
  "--color-status-error": semanticColorsLight["status-error"],
878
983
  "--color-status-error-subtle": semanticColorsLight["status-error-subtle"],
984
+ "--color-status-error-muted": semanticColorsLight["status-error-muted"],
985
+ "--color-status-error-strong": semanticColorsLight["status-error-strong"],
879
986
  "--color-status-warning": semanticColorsLight["status-warning"],
880
987
  "--color-status-warning-subtle": semanticColorsLight["status-warning-subtle"],
988
+ "--color-status-warning-muted": semanticColorsLight["status-warning-muted"],
989
+ "--color-status-warning-strong": semanticColorsLight["status-warning-strong"],
881
990
  "--color-status-info": semanticColorsLight["status-info"],
882
991
  "--color-status-info-subtle": semanticColorsLight["status-info-subtle"],
992
+ "--color-status-info-muted": semanticColorsLight["status-info-muted"],
993
+ "--color-status-info-strong": semanticColorsLight["status-info-strong"],
883
994
  "--color-status-error-vivid": semanticColorsLight["status-error-vivid"],
884
995
  "--color-status-error-vivid-light": semanticColorsLight["status-error-vivid-light"],
885
996
  "--color-status-error-vivid-dark": semanticColorsLight["status-error-vivid-dark"],
886
997
  "--color-status-error-vivid-subtle": semanticColorsLight["status-error-vivid-subtle"],
998
+ "--color-status-error-vivid-muted": semanticColorsLight["status-error-vivid-muted"],
999
+ "--color-status-error-vivid-strong": semanticColorsLight["status-error-vivid-strong"],
887
1000
  "--color-text-primary": semanticColorsLight["text-primary"],
888
1001
  "--color-text-secondary": semanticColorsLight["text-secondary"],
889
1002
  "--color-text-tertiary": semanticColorsLight["text-tertiary"],
@@ -921,6 +1034,10 @@ var lightThemeCSSVars = {
921
1034
  "--color-on-status-error": semanticColorsLight["on-status-error"],
922
1035
  "--color-on-status-warning": semanticColorsLight["on-status-warning"],
923
1036
  "--color-on-status-info": semanticColorsLight["on-status-info"],
1037
+ "--color-on-status-success-subtle": semanticColorsLight["on-status-success-subtle"],
1038
+ "--color-on-status-error-subtle": semanticColorsLight["on-status-error-subtle"],
1039
+ "--color-on-status-warning-subtle": semanticColorsLight["on-status-warning-subtle"],
1040
+ "--color-on-status-info-subtle": semanticColorsLight["on-status-info-subtle"],
924
1041
  "--color-result-improve": semanticColorsLight["result-improve"],
925
1042
  "--color-result-improve-light": semanticColorsLight["result-improve-light"],
926
1043
  "--color-result-improve-dark": semanticColorsLight["result-improve-dark"],
@@ -963,26 +1080,42 @@ var darkThemeCSSVars = {
963
1080
  "--color-brand-primary-light": semanticColorsDark["brand-primary-light"],
964
1081
  "--color-brand-primary-dark": semanticColorsDark["brand-primary-dark"],
965
1082
  "--color-brand-primary-subtle": semanticColorsDark["brand-primary-subtle"],
1083
+ "--color-brand-primary-muted": semanticColorsDark["brand-primary-muted"],
1084
+ "--color-brand-primary-strong": semanticColorsDark["brand-primary-strong"],
966
1085
  "--color-brand-secondary": semanticColorsDark["brand-secondary"],
967
1086
  "--color-brand-secondary-light": semanticColorsDark["brand-secondary-light"],
968
1087
  "--color-brand-secondary-dark": semanticColorsDark["brand-secondary-dark"],
969
1088
  "--color-brand-secondary-subtle": semanticColorsDark["brand-secondary-subtle"],
1089
+ "--color-brand-secondary-muted": semanticColorsDark["brand-secondary-muted"],
1090
+ "--color-brand-secondary-strong": semanticColorsDark["brand-secondary-strong"],
970
1091
  "--color-on-brand-primary": semanticColorsDark["on-brand-primary"],
971
1092
  "--color-on-brand-secondary": semanticColorsDark["on-brand-secondary"],
1093
+ "--color-on-brand-primary-subtle": semanticColorsDark["on-brand-primary-subtle"],
1094
+ "--color-on-brand-secondary-subtle": semanticColorsDark["on-brand-secondary-subtle"],
972
1095
  "--color-status-success": semanticColorsDark["status-success"],
973
1096
  "--color-status-success-subtle": semanticColorsDark["status-success-subtle"],
1097
+ "--color-status-success-muted": semanticColorsDark["status-success-muted"],
1098
+ "--color-status-success-strong": semanticColorsDark["status-success-strong"],
974
1099
  "--color-status-live": semanticColorsDark["status-live"],
975
1100
  "--color-status-live-muted": semanticColorsDark["status-live-muted"],
976
1101
  "--color-status-error": semanticColorsDark["status-error"],
977
1102
  "--color-status-error-subtle": semanticColorsDark["status-error-subtle"],
1103
+ "--color-status-error-muted": semanticColorsDark["status-error-muted"],
1104
+ "--color-status-error-strong": semanticColorsDark["status-error-strong"],
978
1105
  "--color-status-warning": semanticColorsDark["status-warning"],
979
1106
  "--color-status-warning-subtle": semanticColorsDark["status-warning-subtle"],
1107
+ "--color-status-warning-muted": semanticColorsDark["status-warning-muted"],
1108
+ "--color-status-warning-strong": semanticColorsDark["status-warning-strong"],
980
1109
  "--color-status-info": semanticColorsDark["status-info"],
981
1110
  "--color-status-info-subtle": semanticColorsDark["status-info-subtle"],
1111
+ "--color-status-info-muted": semanticColorsDark["status-info-muted"],
1112
+ "--color-status-info-strong": semanticColorsDark["status-info-strong"],
982
1113
  "--color-status-error-vivid": semanticColorsDark["status-error-vivid"],
983
1114
  "--color-status-error-vivid-light": semanticColorsDark["status-error-vivid-light"],
984
1115
  "--color-status-error-vivid-dark": semanticColorsDark["status-error-vivid-dark"],
985
1116
  "--color-status-error-vivid-subtle": semanticColorsDark["status-error-vivid-subtle"],
1117
+ "--color-status-error-vivid-muted": semanticColorsDark["status-error-vivid-muted"],
1118
+ "--color-status-error-vivid-strong": semanticColorsDark["status-error-vivid-strong"],
986
1119
  "--color-text-primary": semanticColorsDark["text-primary"],
987
1120
  "--color-text-secondary": semanticColorsDark["text-secondary"],
988
1121
  "--color-text-tertiary": semanticColorsDark["text-tertiary"],
@@ -1020,6 +1153,10 @@ var darkThemeCSSVars = {
1020
1153
  "--color-on-status-error": semanticColorsDark["on-status-error"],
1021
1154
  "--color-on-status-warning": semanticColorsDark["on-status-warning"],
1022
1155
  "--color-on-status-info": semanticColorsDark["on-status-info"],
1156
+ "--color-on-status-success-subtle": semanticColorsDark["on-status-success-subtle"],
1157
+ "--color-on-status-error-subtle": semanticColorsDark["on-status-error-subtle"],
1158
+ "--color-on-status-warning-subtle": semanticColorsDark["on-status-warning-subtle"],
1159
+ "--color-on-status-info-subtle": semanticColorsDark["on-status-info-subtle"],
1023
1160
  "--color-result-improve": semanticColorsDark["result-improve"],
1024
1161
  "--color-result-improve-light": semanticColorsDark["result-improve-light"],
1025
1162
  "--color-result-improve-dark": semanticColorsDark["result-improve-dark"],
@@ -1174,6 +1311,19 @@ function barPaper(color, flip = false) {
1174
1311
  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)"
1175
1312
  };
1176
1313
  }
1314
+ function postIt(tone = c["surface-raised"], deg = -1.5) {
1315
+ return {
1316
+ backgroundColor: tone,
1317
+ backgroundImage: grainForTone(tone),
1318
+ boxShadow: "inset 0 1px 0 rgba(255,255,255,0.12), 0 6px 14px rgba(0,0,0,0.45)",
1319
+ transform: [{ rotate: `${deg}deg` }]
1320
+ };
1321
+ }
1322
+ var debossLabel = {
1323
+ textShadowColor: "rgba(255,255,255,0.11)",
1324
+ textShadowOffset: { width: 0, height: 1 },
1325
+ textShadowRadius: 0
1326
+ };
1177
1327
 
1178
1328
  // src/theme/color-utils.ts
1179
1329
  function hexToRgb(hex) {
@@ -1293,306 +1443,124 @@ function isDark(hex) {
1293
1443
  const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
1294
1444
  return hsv.v < 0.6;
1295
1445
  }
1296
- var elevationSystem = {
1297
- // Deep inset (recessed input fields, deeply pressed buttons)
1298
- [-2]: {
1299
- name: "deep-inset",
1300
- colorAdjustment: 0,
1301
- shadowIntensity: "strong",
1302
- shadowStyle: "pressed",
1303
- description: "Deeply recessed elements (e.g., input fields, deeply pressed buttons)"
1304
- },
1305
- // Shallow inset (pressed buttons, sunken panels)
1306
- [-1]: {
1307
- name: "inset",
1308
- colorAdjustment: 0,
1309
- shadowIntensity: "medium",
1310
- shadowStyle: "pressed",
1311
- description: "Shallow inset elements (e.g., pressed buttons, sunken panels within cards)"
1312
- },
1313
- // Base level (page background, default surface)
1314
- [0]: {
1315
- name: "base",
1316
- colorAdjustment: 0,
1317
- shadowIntensity: "subtle",
1318
- shadowStyle: "raised",
1319
- description: "Base surface level (page background, default containers)"
1320
- },
1321
- // Level 1: Subtle elevation (outline cards, subtle containers)
1322
- [1]: {
1323
- name: "subtle",
1324
- // The whole ladder was re-spaced in TD-07.16. It used to run
1325
- // 0.01/0.02/0.04/0.06/0.08, where the first step was ~2 RGB values — under
1326
- // the perceptual floor, so level 1 existed in the type system and nowhere on
1327
- // screen. With drop-shadow now gated off below FLOATING_ELEVATION_MIN, TONE
1328
- // is the only thing separating 0-3, so every step has to actually land.
1329
- // Even 0.025 spacing, verified in elevation.test.ts as ΔL* > 1 per step.
1330
- colorAdjustment: 0.025,
1331
- shadowIntensity: "subtle",
1332
- shadowStyle: "raised",
1333
- description: "Subtle elevation (outline cards, subtle containers)"
1334
- },
1335
- // Level 2: Standard elevation (default cards, buttons)
1336
- [2]: {
1337
- name: "standard",
1338
- colorAdjustment: 0.05,
1339
- shadowIntensity: "medium",
1340
- shadowStyle: "raised",
1341
- description: "Standard elevation (default cards, raised buttons)"
1342
- },
1343
- // Level 3: Prominent elevation (important cards, modals)
1344
- [3]: {
1345
- name: "prominent",
1346
- colorAdjustment: 0.075,
1347
- shadowIntensity: "strong",
1348
- shadowStyle: "raised",
1349
- description: "Prominent elevation (important cards, modals, dropdowns)"
1350
- },
1351
- // Level 4: High elevation (overlays, popovers)
1352
- [4]: {
1353
- name: "high",
1354
- colorAdjustment: 0.1,
1355
- shadowIntensity: "strong",
1356
- shadowStyle: "raised",
1357
- description: "High elevation (overlays, popovers, tooltips)"
1358
- },
1359
- // Level 5: Floating (toasts, floating action buttons)
1360
- [5]: {
1361
- name: "floating",
1362
- colorAdjustment: 0.13,
1363
- shadowIntensity: "strong",
1364
- shadowStyle: "raised",
1365
- description: "Floating elevation (toasts, floating action buttons, highest z-index)"
1366
- }
1446
+ var FLOATING_LIFT_MIN = 4;
1447
+ var LIFT_RIM_ALPHA = { dark: 0.12, light: 0.9 };
1448
+ var AMBIENT = {
1449
+ 1: [
1450
+ { y: 1, blur: 2, alpha: 0.35 },
1451
+ { y: 2, blur: 6, alpha: 0.3 }
1452
+ ],
1453
+ 2: [
1454
+ { y: 1, blur: 2, alpha: 0.35 },
1455
+ { y: 4, blur: 12, alpha: 0.32 }
1456
+ ],
1457
+ 3: [
1458
+ { y: 2, blur: 4, alpha: 0.35 },
1459
+ { y: 8, blur: 22, alpha: 0.35 }
1460
+ ],
1461
+ 4: [
1462
+ { y: 1, blur: 2, alpha: 0.35 },
1463
+ { y: 10, blur: 24, alpha: 0.3 },
1464
+ { y: 24, blur: 48, alpha: 0.2 }
1465
+ ],
1466
+ 5: [
1467
+ { y: 2, blur: 4, alpha: 0.4 },
1468
+ { y: 16, blur: 32, alpha: 0.35 },
1469
+ { y: 32, blur: 64, alpha: 0.25 }
1470
+ ]
1367
1471
  };
1368
- function calculateRimLightColor(baseColor, level) {
1369
- const rgb = hexToRgb(baseColor);
1370
- if (!rgb) {
1371
- return "rgba(255, 255, 255, 0.5)";
1372
- }
1373
- const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
1374
- const isLight = hsv.v > 0.6;
1375
- const isSaturated = hsv.s > 0.3;
1376
- const absLevel = Math.abs(level);
1377
- const opacityBoost = Math.max(0, (absLevel - 1) * 0.05);
1378
- if (isSaturated) {
1379
- const rimLightValue = 0.95;
1380
- const rimLightRgb = hsvToRgb(hsv.h, hsv.s * 0.3, rimLightValue);
1381
- const baseOpacity = isLight ? 0.9 : 0.5;
1382
- const finalOpacity = Math.min(1, baseOpacity + opacityBoost);
1383
- return `rgba(${rimLightRgb.r}, ${rimLightRgb.g}, ${rimLightRgb.b}, ${finalOpacity.toFixed(2)})`;
1384
- } else {
1385
- const baseOpacity = isLight ? 0.9 : 0.12;
1386
- const finalOpacity = Math.min(1, baseOpacity + opacityBoost);
1387
- return `rgba(255, 255, 255, ${finalOpacity.toFixed(2)})`;
1388
- }
1389
- }
1390
- function calculateDarkShadowColors(surfaceColor) {
1391
- const rgb = hexToRgb(surfaceColor);
1392
- if (!rgb) {
1393
- return {
1394
- dark: "rgba(0, 0, 0, 0.3)",
1395
- darker: "rgba(0, 0, 0, 0.4)"
1396
- };
1397
- }
1398
- const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
1399
- const isLight = hsv.v > 0.6;
1400
- const isSaturated = hsv.s > 0.3;
1401
- if (isSaturated) {
1402
- const darkShadowValue = 0.15;
1403
- const darkShadowRgb = hsvToRgb(hsv.h, hsv.s, darkShadowValue);
1404
- if (isLight) {
1405
- return {
1406
- dark: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.3)`,
1407
- darker: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.4)`
1408
- };
1409
- } else {
1410
- return {
1411
- dark: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.5)`,
1412
- darker: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.6)`
1413
- };
1414
- }
1415
- } else {
1416
- if (isLight) {
1417
- return {
1418
- dark: "rgba(0, 0, 0, 0.2)",
1419
- darker: "rgba(0, 0, 0, 0.3)"
1420
- };
1421
- } else {
1422
- return {
1423
- dark: "rgba(0, 0, 0, 0.5)",
1424
- darker: "rgba(0, 0, 0, 0.6)"
1425
- };
1426
- }
1427
- }
1428
- }
1429
- function getRimLightConfig() {
1430
- return {
1431
- offset: 1,
1432
- // Fixed 1px for crisp rim
1433
- blur: 1
1434
- // Tight blur for crisp edge
1435
- };
1472
+ var AMBIENT_ALPHA_SCALE = { dark: 1, light: 0.4 };
1473
+ function ambientLayers(step, mode) {
1474
+ const scale = AMBIENT_ALPHA_SCALE[mode];
1475
+ return AMBIENT[step].map(
1476
+ ({ y, blur, alpha }) => `0 ${y}px ${blur}px rgba(0,0,0,${(alpha * scale).toFixed(2)})`
1477
+ );
1436
1478
  }
1437
- function getElevationConfig(level) {
1438
- return elevationSystem[level];
1479
+ function liftShadow(step, mode = "dark", opts = {}) {
1480
+ const rim = opts.rim ?? LIFT_RIM_ALPHA[mode];
1481
+ const layers = ambientLayers(step, mode);
1482
+ if (rim > 0) layers.unshift(`inset 0 1px 0 rgba(255,255,255,${rim.toFixed(2)})`);
1483
+ return layers.join(", ");
1439
1484
  }
1440
- var elevationSurfaceCache = /* @__PURE__ */ new Map();
1441
- var MAX_CACHE_SIZE = 100;
1442
- function getCacheKey(baseColor, level, theme) {
1443
- return `${baseColor}-${level}-${theme}`;
1485
+ function liftStyle(step, mode = "dark", opts = {}) {
1486
+ const deepest = AMBIENT[step][AMBIENT[step].length - 1];
1487
+ return reactNative.Platform.select({
1488
+ web: { boxShadow: liftShadow(step, mode, opts) },
1489
+ default: {
1490
+ shadowColor: "#000",
1491
+ shadowOffset: { width: 0, height: Math.round(deepest.y / 2) },
1492
+ shadowOpacity: deepest.alpha * AMBIENT_ALPHA_SCALE[mode],
1493
+ shadowRadius: deepest.blur / 2,
1494
+ elevation: step
1495
+ }
1496
+ });
1444
1497
  }
1445
- function calculateElevationSurface(baseColor, level, theme) {
1446
- const config = elevationSystem[level];
1447
- if (config.colorAdjustment === 0) {
1448
- return baseColor;
1449
- }
1450
- if (level < 0) {
1451
- return baseColor;
1452
- }
1453
- return lighten(baseColor, config.colorAdjustment);
1498
+
1499
+ // src/theme/surface-planes.ts
1500
+ var SURFACE_LEVEL_TOKEN = {
1501
+ frame: "background-frame",
1502
+ background: "background-base",
1503
+ base: "surface-base",
1504
+ elevated: "surface-elevated",
1505
+ raised: "surface-raised",
1506
+ overlay: "surface-overlay"
1507
+ };
1508
+ var PLANE_ORDER = [
1509
+ "frame",
1510
+ "background",
1511
+ "base",
1512
+ "elevated",
1513
+ "raised",
1514
+ "overlay"
1515
+ ];
1516
+ function surfaceBackground(level, mode) {
1517
+ return getSemanticColors(mode)[SURFACE_LEVEL_TOKEN[level]];
1454
1518
  }
1455
- function getElevationSurface(baseColor, level, theme) {
1456
- const cacheKey = getCacheKey(baseColor, level, theme);
1457
- if (elevationSurfaceCache.has(cacheKey)) {
1458
- return elevationSurfaceCache.get(cacheKey);
1459
- }
1460
- const result = calculateElevationSurface(baseColor, level);
1461
- if (elevationSurfaceCache.size >= MAX_CACHE_SIZE) {
1462
- const firstKey = elevationSurfaceCache.keys().next().value;
1463
- elevationSurfaceCache.delete(firstKey);
1464
- }
1465
- elevationSurfaceCache.set(cacheKey, result);
1466
- return result;
1519
+ function stepPlane(from, delta) {
1520
+ const index = PLANE_ORDER.indexOf(from);
1521
+ const clamped = Math.min(PLANE_ORDER.length - 1, Math.max(0, index + delta));
1522
+ return PLANE_ORDER[clamped];
1467
1523
  }
1468
- var elevationShadowCache = /* @__PURE__ */ new Map();
1469
- var MAX_SHADOW_CACHE_SIZE = 50;
1470
- function getShadowCacheKey(baseColor, level, theme, isHovered) {
1471
- return `${baseColor}-${level}-${theme}-${isHovered}`;
1524
+ function pressedLevel(parent) {
1525
+ return stepPlane(parent, -1);
1472
1526
  }
1473
- function calculateElevationShadow(baseColor, level, theme, isHovered = false) {
1474
- const config = elevationSystem[level];
1475
- if (level === 0) {
1476
- return {};
1477
- }
1478
- const elevatedSurfaceColor = calculateElevationSurface(baseColor, level);
1479
- const rimLightColor = calculateRimLightColor(baseColor, level);
1480
- const darkShadowColors = calculateDarkShadowColors(elevatedSurfaceColor);
1481
- const intensityConfig = {
1482
- subtle: { offset: 1, blur: 2 },
1483
- medium: { offset: 2, blur: 4 },
1484
- strong: { offset: 2, blur: 5 }
1485
- };
1486
- const { offset, blur } = intensityConfig[config.shadowIntensity];
1487
- const rimConfig = getRimLightConfig();
1488
- if (config.shadowStyle === "pressed") {
1489
- if (isHovered) {
1490
- const hoverOffset = Math.max(1, Math.round(offset / 2));
1491
- const hoverBlur = Math.max(1, Math.round(blur / 2));
1492
- return reactNative.Platform.select({
1493
- web: {
1494
- boxShadow: `inset ${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${darkShadowColors.darker}, inset -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
1495
- },
1496
- default: {
1497
- shadowOpacity: 0,
1498
- elevation: 0
1499
- }
1500
- });
1501
- }
1502
- return reactNative.Platform.select({
1503
- web: {
1504
- boxShadow: `inset ${offset}px ${offset}px ${blur}px ${darkShadowColors.darker}, inset -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
1505
- },
1506
- default: {
1507
- shadowOpacity: 0,
1508
- elevation: 0
1509
- }
1510
- });
1511
- } else {
1512
- if (isHovered) {
1513
- const hoverOffset = Math.max(1, Math.round(offset / 2));
1514
- const hoverBlur = Math.max(1, Math.round(blur / 2));
1515
- return reactNative.Platform.select({
1516
- web: {
1517
- boxShadow: `${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${darkShadowColors.dark}, -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
1518
- },
1519
- default: {
1520
- shadowColor: "#000",
1521
- shadowOffset: { width: hoverOffset, height: hoverOffset },
1522
- shadowOpacity: 0.2,
1523
- shadowRadius: hoverBlur / 2,
1524
- elevation: hoverOffset
1525
- }
1526
- });
1527
- }
1528
- return reactNative.Platform.select({
1529
- web: {
1530
- boxShadow: `${offset}px ${offset}px ${blur}px ${darkShadowColors.dark}, -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
1531
- },
1532
- default: {
1533
- shadowColor: "#000",
1534
- shadowOffset: { width: offset, height: offset },
1535
- shadowOpacity: 0.3,
1536
- shadowRadius: blur / 2,
1537
- elevation: offset
1538
- }
1539
- });
1540
- }
1541
- }
1542
- var FLOATING_ELEVATION_MIN = 4;
1543
- function getElevationShadow(baseColor, level, theme, isHovered = false) {
1544
- const cacheKey = getShadowCacheKey(baseColor, level, theme, isHovered);
1545
- if (elevationShadowCache.has(cacheKey)) {
1546
- return elevationShadowCache.get(cacheKey);
1547
- }
1548
- const result = level > 0 && level < FLOATING_ELEVATION_MIN ? {} : calculateElevationShadow(baseColor, level, theme, isHovered);
1549
- if (elevationShadowCache.size >= MAX_SHADOW_CACHE_SIZE) {
1550
- const firstKey = elevationShadowCache.keys().next().value;
1551
- elevationShadowCache.delete(firstKey);
1552
- }
1553
- elevationShadowCache.set(cacheKey, result);
1554
- return result;
1527
+ function raisedLevel(parent, steps) {
1528
+ return stepPlane(parent, Math.max(0, steps));
1555
1529
  }
1530
+
1531
+ // src/theme/elevation.ts
1532
+ var ELEVATION_PLANE = {
1533
+ [-2]: "frame",
1534
+ [-1]: "background",
1535
+ [0]: "base",
1536
+ [1]: "elevated",
1537
+ [2]: "raised",
1538
+ [3]: "overlay",
1539
+ [4]: "overlay",
1540
+ [5]: "overlay"
1541
+ };
1542
+ var FLOATING_ELEVATION_MIN = FLOATING_LIFT_MIN;
1556
1543
  var PRESSED_ELEVATION_LEVEL = -1;
1557
- function getPressedRecessShadow(fillColor, theme) {
1558
- return getElevationShadow(fillColor, PRESSED_ELEVATION_LEVEL, theme);
1544
+ function elevationPlane(level) {
1545
+ return ELEVATION_PLANE[level];
1559
1546
  }
1560
- function getBaseSurfaceColor(theme) {
1561
- return theme === "light" ? semanticColorsLight["surface-raised"] : semanticColorsDark["surface-elevated"];
1547
+ function getElevationSurface(level, mode = "dark") {
1548
+ return surfaceBackground(ELEVATION_PLANE[level], mode);
1562
1549
  }
1563
- var componentElevationRanges = {
1564
- button: {
1565
- allowed: [2],
1566
- default: 2,
1567
- hover: 3
1568
- },
1569
- card: {
1570
- allowed: [1, 2, 3],
1571
- default: 2,
1572
- hover: 3
1573
- },
1574
- input: {
1575
- allowed: [-2, -1, 0],
1576
- default: -1
1577
- },
1578
- overlay: {
1579
- allowed: [4, 5],
1580
- default: 4
1581
- }
1582
- };
1583
- function getValidatedElevation(component, requested) {
1584
- const range = componentElevationRanges[component];
1585
- if (range.allowed.includes(requested)) {
1586
- return requested;
1587
- }
1588
- const sorted = [...range.allowed].sort((a, b) => a - b);
1589
- if (requested < sorted[0]) return sorted[0];
1590
- if (requested > sorted[sorted.length - 1]) return sorted[sorted.length - 1];
1591
- return sorted.reduce(
1592
- (prev, curr) => Math.abs(curr - requested) < Math.abs(prev - requested) ? curr : prev
1593
- );
1550
+ function getPressedRecessShadow(fillColor, _mode = "dark") {
1551
+ const { boxShadow } = insetWell(fillColor);
1552
+ return reactNative.Platform.select({
1553
+ web: { boxShadow },
1554
+ default: {}
1555
+ });
1556
+ }
1557
+ function getElevationShadow(level, mode = "dark", opts = {}) {
1558
+ if (level < 0) return getPressedRecessShadow(getElevationSurface(level, mode), mode);
1559
+ if (level === 0) return {};
1560
+ return liftStyle(level, mode, opts);
1594
1561
  }
1595
1562
  var glowConfig = {
1563
+ tight: { blur: 4, spread: 0, opacity: 0.4 },
1596
1564
  subtle: { blur: 12, spread: 0, opacity: 0.25 },
1597
1565
  medium: { blur: 20, spread: 2, opacity: 0.4 },
1598
1566
  strong: { blur: 30, spread: 4, opacity: 0.55 }
@@ -1839,7 +1807,7 @@ var audiobookPreset = {
1839
1807
  "interactive-focus": "rgba(255, 255, 255, 0.12)",
1840
1808
  "interactive-active": "rgba(255, 255, 255, 0.16)",
1841
1809
  "interactive-selected": "rgba(255, 255, 255, 0.08)",
1842
- "divider": "rgba(255, 255, 255, 0.06)",
1810
+ divider: "rgba(255, 255, 255, 0.06)",
1843
1811
  // Glow RGB values for shadow utilities
1844
1812
  "brand-primary-rgb": "212, 120, 42",
1845
1813
  "brand-secondary-rgb": "58, 155, 138",
@@ -1888,27 +1856,31 @@ function ThemeProvider({
1888
1856
  }
1889
1857
 
1890
1858
  exports.CATEGORICAL_CVD_SAFE_MAX = CATEGORICAL_CVD_SAFE_MAX;
1859
+ exports.ELEVATION_PLANE = ELEVATION_PLANE;
1891
1860
  exports.FLOATING_ELEVATION_MIN = FLOATING_ELEVATION_MIN;
1861
+ exports.FLOATING_LIFT_MIN = FLOATING_LIFT_MIN;
1862
+ exports.LIFT_RIM_ALPHA = LIFT_RIM_ALPHA;
1863
+ exports.PLANE_ORDER = PLANE_ORDER;
1892
1864
  exports.PRESSED_ELEVATION_LEVEL = PRESSED_ELEVATION_LEVEL;
1865
+ exports.SURFACE_LEVEL_TOKEN = SURFACE_LEVEL_TOKEN;
1893
1866
  exports.SURFACE_PLANE_STEPS = SURFACE_PLANE_STEPS;
1894
1867
  exports.ThemeProvider = ThemeProvider;
1868
+ exports.alertRedVivid = alertRedVivid;
1895
1869
  exports.applyThemePreset = applyThemePreset;
1896
1870
  exports.audiobookPreset = audiobookPreset;
1897
1871
  exports.barPaper = barPaper;
1898
1872
  exports.bestTextColor = bestTextColor;
1899
1873
  exports.buttonSizes = buttonSizes;
1900
1874
  exports.categoricalPalette = categoricalPalette;
1901
- exports.componentElevationRanges = componentElevationRanges;
1902
1875
  exports.darkThemeCSSVars = darkThemeCSSVars;
1903
1876
  exports.darken = darken;
1877
+ exports.debossLabel = debossLabel;
1904
1878
  exports.defaultPreset = defaultPreset;
1905
1879
  exports.discreteRainbow = discreteRainbow;
1906
1880
  exports.divergingScale = divergingScale;
1907
- exports.elevationSystem = elevationSystem;
1908
- exports.getBaseSurfaceColor = getBaseSurfaceColor;
1881
+ exports.elevationPlane = elevationPlane;
1909
1882
  exports.getCategoricalColor = getCategoricalColor;
1910
1883
  exports.getDiscreteRainbowColor = getDiscreteRainbowColor;
1911
- exports.getElevationConfig = getElevationConfig;
1912
1884
  exports.getElevationShadow = getElevationShadow;
1913
1885
  exports.getElevationSurface = getElevationSurface;
1914
1886
  exports.getGlowShadow = getGlowShadow;
@@ -1916,7 +1888,6 @@ exports.getHoverColors = getHoverColors;
1916
1888
  exports.getPressedRecessShadow = getPressedRecessShadow;
1917
1889
  exports.getSemanticColors = getSemanticColors;
1918
1890
  exports.getThemeCSSVars = getThemeCSSVars;
1919
- exports.getValidatedElevation = getValidatedElevation;
1920
1891
  exports.gluestackConfig = gluestackConfig;
1921
1892
  exports.grainForTone = grainForTone;
1922
1893
  exports.grainOpacityForTone = grainOpacityForTone;
@@ -1926,10 +1897,14 @@ exports.hsvToRgb = hsvToRgb;
1926
1897
  exports.insetWell = insetWell;
1927
1898
  exports.isCssPropertyManifest = isCssPropertyManifest;
1928
1899
  exports.isDark = isDark;
1900
+ exports.liftShadow = liftShadow;
1901
+ exports.liftStyle = liftStyle;
1929
1902
  exports.lightThemeCSSVars = lightThemeCSSVars;
1930
1903
  exports.lighten = lighten;
1931
1904
  exports.linearGradient = linearGradient;
1932
1905
  exports.paperSheet = paperSheet;
1906
+ exports.postIt = postIt;
1907
+ exports.pressedLevel = pressedLevel;
1933
1908
  exports.primitiveBorderRadius = primitiveBorderRadius;
1934
1909
  exports.primitiveBreakpoints = primitiveBreakpoints;
1935
1910
  exports.primitiveColors = primitiveColors;
@@ -1937,13 +1912,17 @@ exports.primitiveRamps = primitiveRamps;
1937
1912
  exports.primitiveSpacing = primitiveSpacing;
1938
1913
  exports.primitiveTypography = primitiveTypography;
1939
1914
  exports.primitiveZIndex = primitiveZIndex;
1915
+ exports.raisedLevel = raisedLevel;
1940
1916
  exports.resolveColor = resolveColor;
1917
+ exports.resultPaletteColors = resultPaletteColors;
1941
1918
  exports.rgbToHex = rgbToHex;
1942
1919
  exports.rgbToHsv = rgbToHsv;
1943
1920
  exports.semanticColorsDark = semanticColorsDark;
1944
1921
  exports.semanticColorsLight = semanticColorsLight;
1922
+ exports.semanticPins = semanticPins;
1945
1923
  exports.semanticTypography = semanticTypography;
1946
1924
  exports.sequentialEffort = sequentialEffort;
1925
+ exports.surfaceBackground = surfaceBackground;
1947
1926
  exports.surfaceGradient = surfaceGradient;
1948
1927
  exports.validateCssPropertyManifest = validateCssPropertyManifest;
1949
1928
  //# sourceMappingURL=index.js.map