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