@titan-design/react-ui 0.5.0 → 0.6.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 (116) hide show
  1. package/dist/bodymap.js +232 -185
  2. package/dist/bodymap.js.map +1 -1
  3. package/dist/bodymap.mjs +232 -185
  4. package/dist/bodymap.mjs.map +1 -1
  5. package/dist/index.d.mts +164 -8
  6. package/dist/index.d.ts +164 -8
  7. package/dist/index.js +835 -342
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +816 -343
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/pages.js +570 -522
  12. package/dist/pages.js.map +1 -1
  13. package/dist/pages.mjs +570 -522
  14. package/dist/pages.mjs.map +1 -1
  15. package/dist/theme/index.d.mts +461 -199
  16. package/dist/theme/index.d.ts +461 -199
  17. package/dist/theme/index.js +311 -97
  18. package/dist/theme/index.js.map +1 -1
  19. package/dist/theme/index.mjs +303 -98
  20. package/dist/theme/index.mjs.map +1 -1
  21. package/dist/theme/tokens-css.js +148 -139
  22. package/dist/theme/tokens-css.js.map +1 -1
  23. package/dist/theme/tokens-css.mjs +148 -139
  24. package/dist/theme/tokens-css.mjs.map +1 -1
  25. package/package.json +3 -1
  26. package/src/components/custom/DateTime/DateTime.stories.tsx +82 -6
  27. package/src/components/custom/DateTime/DateTime.test.tsx +29 -3
  28. package/src/components/custom/DateTime/DateTime.tsx +55 -15
  29. package/src/components/custom/Gauge/Gauge.test.tsx +2 -2
  30. package/src/components/custom/Gauge/Gauge.tsx +6 -3
  31. package/src/components/custom/Scatter/Scatter.tsx +3 -5
  32. package/src/components/custom/Treemap/Treemap.tsx +3 -5
  33. package/src/components/custom/Typography/Typography.stories.tsx +45 -27
  34. package/src/components/custom/Typography/Typography.test.tsx +13 -3
  35. package/src/components/custom/Typography/Typography.tsx +5 -0
  36. package/src/components/custom/Workout/ActiveWorkoutPage.tsx +2 -1
  37. package/src/components/custom/Workout/BodyMap.tsx +6 -3
  38. package/src/components/custom/Workout/BodyMapDetailPanel.tsx +6 -3
  39. package/src/components/custom/Workout/CapacityBandChart.test.tsx +2 -2
  40. package/src/components/custom/Workout/CapacityBandChart.tsx +9 -6
  41. package/src/components/custom/Workout/DeviationBar.test.tsx +1 -1
  42. package/src/components/custom/Workout/DeviationBar.tsx +7 -4
  43. package/src/components/custom/Workout/ExerciseDetailPage.tsx +2 -1
  44. package/src/components/custom/Workout/InputBar.tsx +2 -1
  45. package/src/components/custom/Workout/IntensityBar.test.tsx +8 -8
  46. package/src/components/custom/Workout/IntensityBar.tsx +10 -6
  47. package/src/components/custom/Workout/MesoCard.tsx +8 -3
  48. package/src/components/custom/Workout/MesoProgressBar.test.tsx +1 -1
  49. package/src/components/custom/Workout/MesoProgressBar.tsx +3 -2
  50. package/src/components/custom/Workout/MesoStatusCard.tsx +20 -13
  51. package/src/components/custom/Workout/MuscleGroupChip.tsx +7 -4
  52. package/src/components/custom/Workout/PrBadge.tsx +5 -2
  53. package/src/components/custom/Workout/PrHistoryModal.tsx +4 -3
  54. package/src/components/custom/Workout/ProgramPlanningPage.tsx +2 -1
  55. package/src/components/custom/Workout/ReadinessCheck.tsx +7 -4
  56. package/src/components/custom/Workout/RestTimer.tsx +2 -1
  57. package/src/components/custom/Workout/SetRow.tsx +2 -1
  58. package/src/components/custom/Workout/Sparkline.tsx +2 -1
  59. package/src/components/custom/Workout/StatusDot.test.tsx +2 -2
  60. package/src/components/custom/Workout/StatusDot.tsx +12 -9
  61. package/src/components/custom/Workout/StrengthTrendChart.tsx +9 -6
  62. package/src/components/custom/Workout/SupersetWrapper.tsx +2 -1
  63. package/src/components/custom/Workout/TempoDisplay.tsx +6 -3
  64. package/src/components/custom/Workout/VelocityStrip.test.tsx +3 -3
  65. package/src/components/custom/Workout/WeekRow.tsx +3 -2
  66. package/src/components/custom/Workout/WeightBadge.tsx +6 -2
  67. package/src/components/custom/Workout/WorkoutCard.tsx +5 -2
  68. package/src/components/custom/Workout/WorkoutPill.tsx +12 -8
  69. package/src/components/custom/Workout/icons.tsx +6 -67
  70. package/src/components/icons/SvgIcon.tsx +50 -0
  71. package/src/components/icons/icons.stories.tsx +57 -0
  72. package/src/components/icons/icons.test.tsx +43 -0
  73. package/src/components/icons/icons.tsx +45 -0
  74. package/src/components/icons/index.ts +4 -0
  75. package/src/components/index.ts +6 -0
  76. package/src/components/shell/BrandLockup.stories.tsx +27 -0
  77. package/src/components/shell/BrandLockup.test.tsx +23 -0
  78. package/src/components/shell/BrandLockup.tsx +47 -0
  79. package/src/components/shell/DeviceIndicator.stories.tsx +28 -0
  80. package/src/components/shell/DeviceIndicator.test.tsx +26 -0
  81. package/src/components/shell/DeviceIndicator.tsx +52 -0
  82. package/src/components/shell/DeviceMenu.stories.tsx +47 -0
  83. package/src/components/shell/DeviceMenu.test.tsx +40 -0
  84. package/src/components/shell/DeviceMenu.tsx +65 -0
  85. package/src/components/shell/DeviceRow.stories.tsx +38 -0
  86. package/src/components/shell/DeviceRow.test.tsx +37 -0
  87. package/src/components/shell/DeviceRow.tsx +58 -0
  88. package/src/components/shell/README.md +86 -0
  89. package/src/components/shell/SessionStatePill.stories.tsx +27 -0
  90. package/src/components/shell/SessionStatePill.test.tsx +25 -0
  91. package/src/components/shell/SessionStatePill.tsx +46 -0
  92. package/src/components/shell/TopBar.stories.tsx +49 -0
  93. package/src/components/shell/TopBar.test.tsx +36 -0
  94. package/src/components/shell/TopBar.tsx +89 -0
  95. package/src/components/shell/index.ts +8 -0
  96. package/src/components/ui/indicator/Indicator.stories.tsx +37 -1
  97. package/src/components/ui/indicator/Indicator.test.tsx +19 -1
  98. package/src/components/ui/indicator/Indicator.tsx +45 -6
  99. package/src/components/ui/indicator/index.ts +1 -1
  100. package/src/components/ui/spinner/Spinner.tsx +3 -2
  101. package/src/components/ui/toolbar-button/ToolbarButton.tsx +2 -1
  102. package/src/theme/ColorSystem.stories.tsx +323 -0
  103. package/src/theme/Colors.stories.tsx +69 -1
  104. package/src/theme/barrel.ts +1 -0
  105. package/src/theme/config.ts +16 -3
  106. package/src/theme/extracted-colors-dataviz.ts +21 -0
  107. package/src/theme/extracted-colors-ui.ts +20 -0
  108. package/src/theme/global.css +64 -52
  109. package/src/theme/gradients.test.ts +25 -0
  110. package/src/theme/gradients.ts +36 -0
  111. package/src/theme/tokens/primitives.test.ts +232 -0
  112. package/src/theme/tokens/primitives.ts +247 -0
  113. package/src/theme/tokens/semantic.ts +93 -81
  114. package/src/theme/workout-tokens.ts +22 -21
  115. package/src/utils/avatar-color.ts +3 -3
  116. package/tailwind.config.js +10 -3
package/dist/bodymap.js CHANGED
@@ -24,37 +24,17 @@ var primitiveColors = {
24
24
  600: "#5048E5",
25
25
  // Primary main
26
26
  700: "#3832A0"},
27
- // Teal scale (success)
28
- teal: {
29
- 50: "#F0FDFA",
30
- 400: "#43C6B7",
31
- // Success light
32
- 500: "#14B8A6",
33
- 700: "#0E8074"},
34
27
  // Red scale (error)
35
28
  red: {
36
- 50: "#FEF2F2",
37
- 400: "#DA6868",
38
29
  // Error light
39
30
  500: "#EF4444",
40
- 600: "#D14343",
41
- // Error main
42
- 700: "#922E2E"},
43
- // Amber scale (warning)
44
- amber: {
45
- 50: "#FFFBEB",
46
- 400: "#FFBF4C",
47
- // Warning light
48
- 500: "#FFB020",
49
- // Warning main
50
- 600: "#B27B16"},
51
- // Sky/Blue scale (info)
52
- sky: {
53
- 50: "#F0F9FF",
54
- 400: "#64B6F7",
55
- // Info light
56
- 500: "#2196F3",
57
- 700: "#0B79D0"},
31
+ 600: "#D14343"},
32
+ // Vivid red scale (alert)
33
+ redVivid: {
34
+ 400: "#FF6070",
35
+ // Error vivid light
36
+ 500: "#FF4757",
37
+ 700: "#C42539"},
58
38
  // Neutral/Gray scale
59
39
  neutral: {
60
40
  50: "#FAFAFA",
@@ -64,16 +44,9 @@ var primitiveColors = {
64
44
  500: "#6B7280",
65
45
  600: "#4B5563",
66
46
  900: "#111827"},
67
- // Orange scale (accent/brand color)
68
- accent: {
69
- 200: "#FF9630",
70
- 300: "#FF8500",
71
- 400: "#FF7900",
72
- 500: "#F56C00",
73
- 600: "#E06D10",
74
- 700: "#D0620C"},
75
47
  // Charcoal scale (dark backgrounds)
76
48
  charcoal: {
49
+ 200: "#3C3C3C",
77
50
  300: "#2C2C2C",
78
51
  400: "#1F1F1F",
79
52
  500: "#1C1C1C",
@@ -81,15 +54,58 @@ var primitiveColors = {
81
54
  700: "#161616",
82
55
  900: "#101010"
83
56
  },
84
- // Steel scale (cool accent)
85
- steel: {
86
- 300: "#678498",
87
- 400: "#557488",
88
- 500: "#406D87",
89
- 600: "#39617A",
90
- 700: "#32556D"},
91
57
  // Pure colors
92
58
  white: "#FFFFFF"};
59
+ var primitiveRamps = {
60
+ red: {
61
+ 50: "#FFF4F4",
62
+ 500: "#E05254",
63
+ 600: "#D14343",
64
+ // pin
65
+ 700: "#A4221C"},
66
+ orange: {
67
+ 200: "#FFC7A2",
68
+ 300: "#FFA063",
69
+ 400: "#FF7900",
70
+ // pin
71
+ 500: "#DA5F00",
72
+ 600: "#B94A00"},
73
+ amber: {
74
+ 50: "#FFF7DD",
75
+ 200: "#FFD352",
76
+ 300: "#F9B415",
77
+ 500: "#C27400"},
78
+ green: {
79
+ 50: "#E3FFEE",
80
+ 200: "#58F69E",
81
+ 300: "#2ED573",
82
+ 600: "#298732"},
83
+ cyan: {
84
+ 300: "#22D3EE",
85
+ // pin
86
+ 400: "#01B5D1",
87
+ 500: "#2697B7",
88
+ 600: "#307B9B",
89
+ 700: "#2A617F",
90
+ 800: "#22465F"},
91
+ blue: {
92
+ 50: "#EFF8FF",
93
+ 300: "#78C2FF",
94
+ 500: "#2196F3",
95
+ // pin
96
+ 600: "#1072CB"}};
97
+ var divergingScale = [
98
+ primitiveRamps.blue[500],
99
+ // under
100
+ primitiveRamps.cyan[300],
101
+ // maintenance
102
+ primitiveRamps.green[200],
103
+ // optimal (light center)
104
+ primitiveRamps.amber[300],
105
+ // approaching
106
+ primitiveRamps.red[600]
107
+ // over
108
+ ];
93
109
  var discreteRainbow = [
94
110
  "#E8ECFB",
95
111
  "#D9CCE3",
@@ -125,56 +141,43 @@ var discreteRainbow = [
125
141
  // src/theme/tokens/semantic.ts
126
142
  var semanticColorsLight = {
127
143
  // Brand colors (brand-*)
128
- "brand-primary": primitiveColors.accent[400],
129
- // #FF7900
130
- "brand-primary-light": primitiveColors.accent[200],
131
- // #FF9630
132
- "brand-primary-dark": primitiveColors.accent[700],
133
- // #D0620C
144
+ "brand-primary": primitiveRamps.orange[400],
145
+ "brand-primary-light": primitiveRamps.orange[300],
146
+ "brand-primary-dark": primitiveRamps.orange[500],
134
147
  "brand-primary-subtle": "rgba(255, 121, 0, 0.08)",
135
- "brand-primary-hover": primitiveColors.accent[500],
136
- "brand-primary-active": primitiveColors.accent[600],
137
- "brand-secondary": primitiveColors.steel[500],
138
- // #406D87
139
- "brand-secondary-light": primitiveColors.steel[300],
140
- // #678498
141
- "brand-secondary-dark": primitiveColors.steel[700],
142
- // #32556D
143
- "brand-secondary-subtle": "rgba(64, 109, 135, 0.08)",
144
- "brand-secondary-hover": primitiveColors.steel[600],
145
- "brand-secondary-active": primitiveColors.steel[700],
148
+ "brand-primary-hover": primitiveRamps.orange[500],
149
+ "brand-primary-active": primitiveRamps.orange[600],
150
+ "brand-secondary": primitiveRamps.cyan[600],
151
+ "brand-secondary-light": primitiveRamps.cyan[500],
152
+ "brand-secondary-dark": primitiveRamps.cyan[700],
153
+ "brand-secondary-subtle": "rgba(48, 123, 155, 0.08)",
154
+ "brand-secondary-hover": primitiveRamps.cyan[700],
155
+ "brand-secondary-active": primitiveRamps.cyan[800],
146
156
  // Text on brand backgrounds (on-*)
147
157
  "on-brand-primary": primitiveColors.white,
148
158
  "on-brand-secondary": primitiveColors.white,
149
159
  // Status colors (status-*)
150
- "status-success": primitiveColors.teal[500],
151
- // #14B8A6
152
- "status-success-light": primitiveColors.teal[400],
153
- // #43C6B7
154
- "status-success-dark": primitiveColors.teal[700],
155
- // #0E8074
156
- "status-success-subtle": primitiveColors.teal[50],
157
- "status-error": primitiveColors.red[600],
158
- // #D14343
159
- "status-error-light": primitiveColors.red[400],
160
- // #DA6868
161
- "status-error-dark": primitiveColors.red[700],
162
- // #922E2E
163
- "status-error-subtle": primitiveColors.red[50],
164
- "status-warning": primitiveColors.amber[500],
165
- // #FFB020
166
- "status-warning-light": primitiveColors.amber[400],
167
- // #FFBF4C
168
- "status-warning-dark": primitiveColors.amber[600],
169
- // #B27B16
170
- "status-warning-subtle": primitiveColors.amber[50],
171
- "status-info": primitiveColors.sky[500],
172
- // #2196F3
173
- "status-info-light": primitiveColors.sky[400],
174
- // #64B6F7
175
- "status-info-dark": primitiveColors.sky[700],
176
- // #0B79D0
177
- "status-info-subtle": primitiveColors.sky[50],
160
+ "status-success": primitiveRamps.green[300],
161
+ "status-success-light": primitiveRamps.green[200],
162
+ "status-success-dark": primitiveRamps.green[600],
163
+ "status-success-subtle": primitiveRamps.green[50],
164
+ "status-error": primitiveRamps.red[600],
165
+ "status-error-light": primitiveRamps.red[500],
166
+ "status-error-dark": primitiveRamps.red[700],
167
+ "status-error-subtle": primitiveRamps.red[50],
168
+ "status-error-vivid": primitiveColors.redVivid[500],
169
+ // vivid alert red
170
+ "status-error-vivid-light": primitiveColors.redVivid[400],
171
+ "status-error-vivid-dark": primitiveColors.redVivid[700],
172
+ "status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
173
+ "status-warning": primitiveRamps.amber[300],
174
+ "status-warning-light": primitiveRamps.amber[200],
175
+ "status-warning-dark": primitiveRamps.amber[500],
176
+ "status-warning-subtle": primitiveRamps.amber[50],
177
+ "status-info": primitiveRamps.blue[500],
178
+ "status-info-light": primitiveRamps.blue[300],
179
+ "status-info-dark": primitiveRamps.blue[600],
180
+ "status-info-subtle": primitiveRamps.blue[50],
178
181
  // Text on status backgrounds (on-status-*)
179
182
  "on-status-success": primitiveColors.white,
180
183
  "on-status-error": primitiveColors.white,
@@ -201,25 +204,25 @@ var semanticColorsLight = {
201
204
  // Data visualization colors (data-*)
202
205
  // First 10 colors from discrete rainbow optimized for charts
203
206
  "data-1": discreteRainbow[9],
204
- // #1965B0 - Blue
207
+ // Blue
205
208
  "data-2": discreteRainbow[14],
206
- // #4EB265 - Green
209
+ // Green
207
210
  "data-3": discreteRainbow[17],
208
- // #F7F056 - Yellow
211
+ // Yellow
209
212
  "data-4": discreteRainbow[25],
210
- // #DC050C - Red
213
+ // Red
211
214
  "data-5": discreteRainbow[8],
212
- // #882E72 - Purple
215
+ // Purple
213
216
  "data-6": discreteRainbow[20],
214
- // #F4A736 - Orange
217
+ // Orange
215
218
  "data-7": discreteRainbow[13],
216
- // #7BAFDE - Light Blue
219
+ // Light Blue
217
220
  "data-8": discreteRainbow[15],
218
- // #90C987 - Light Green
221
+ // Light Green
219
222
  "data-9": discreteRainbow[3],
220
- // #CAACCB - Lavender
223
+ // Lavender
221
224
  "data-10": discreteRainbow[22],
222
- // #EE8026 - Dark Orange
225
+ // Dark Orange
223
226
  // Text colors (text-*)
224
227
  "text-primary": "#121828",
225
228
  "text-secondary": "#65748B",
@@ -231,9 +234,9 @@ var semanticColorsLight = {
231
234
  // Surface colors (surface-*) - for elevated containers
232
235
  "surface-base": primitiveColors.white,
233
236
  "surface-elevated": primitiveColors.neutral[50],
234
- // #FAFAFA - slightly off-white for elevated cards
237
+ // slightly off-white for elevated cards
235
238
  "surface-raised": primitiveColors.neutral[100],
236
- // #F3F4F6 - light gray for raised cards
239
+ // light gray for raised cards
237
240
  "surface-overlay": primitiveColors.white,
238
241
  "surface-input": primitiveColors.neutral[50],
239
242
  // Input field background (filled variant)
@@ -245,6 +248,8 @@ var semanticColorsLight = {
245
248
  "border-default": "#E8E9EB",
246
249
  "border-subtle": primitiveColors.neutral[100],
247
250
  "border-strong": primitiveColors.neutral[300],
251
+ "border-prominent": primitiveColors.neutral[400],
252
+ // high-visibility divider
248
253
  "border-focus": primitiveColors.blue[600],
249
254
  "border-input": primitiveColors.neutral[300],
250
255
  // Input field border
@@ -269,37 +274,41 @@ var semanticColorsLight = {
269
274
  };
270
275
  var semanticColorsDark = {
271
276
  // Brand colors stay the same in dark mode
272
- "brand-primary": primitiveColors.accent[400],
273
- "brand-primary-light": primitiveColors.accent[200],
274
- "brand-primary-dark": primitiveColors.accent[700],
277
+ "brand-primary": primitiveRamps.orange[400],
278
+ "brand-primary-light": primitiveRamps.orange[300],
279
+ "brand-primary-dark": primitiveRamps.orange[500],
275
280
  "brand-primary-subtle": "rgba(255, 121, 0, 0.12)",
276
- "brand-primary-hover": primitiveColors.accent[300],
277
- "brand-primary-active": primitiveColors.accent[200],
278
- "brand-secondary": primitiveColors.steel[500],
279
- "brand-secondary-light": primitiveColors.steel[300],
280
- "brand-secondary-dark": primitiveColors.steel[700],
281
- "brand-secondary-subtle": "rgba(64, 109, 135, 0.12)",
282
- "brand-secondary-hover": primitiveColors.steel[400],
283
- "brand-secondary-active": primitiveColors.steel[300],
281
+ "brand-primary-hover": primitiveRamps.orange[300],
282
+ "brand-primary-active": primitiveRamps.orange[200],
283
+ "brand-secondary": primitiveRamps.cyan[600],
284
+ "brand-secondary-light": primitiveRamps.cyan[500],
285
+ "brand-secondary-dark": primitiveRamps.cyan[700],
286
+ "brand-secondary-subtle": "rgba(48, 123, 155, 0.12)",
287
+ "brand-secondary-hover": primitiveRamps.cyan[500],
288
+ "brand-secondary-active": primitiveRamps.cyan[400],
284
289
  // Text on brand backgrounds
285
290
  "on-brand-primary": primitiveColors.white,
286
291
  "on-brand-secondary": primitiveColors.white,
287
292
  // Status colors
288
- "status-success": primitiveColors.teal[500],
289
- "status-success-light": primitiveColors.teal[400],
290
- "status-success-dark": primitiveColors.teal[700],
291
- "status-success-subtle": "rgba(20, 184, 166, 0.12)",
292
- "status-error": primitiveColors.red[600],
293
- "status-error-light": primitiveColors.red[400],
294
- "status-error-dark": primitiveColors.red[700],
293
+ "status-success": primitiveRamps.green[300],
294
+ "status-success-light": primitiveRamps.green[200],
295
+ "status-success-dark": primitiveRamps.green[600],
296
+ "status-success-subtle": "rgba(46, 213, 115, 0.12)",
297
+ "status-error": primitiveRamps.red[600],
298
+ "status-error-light": primitiveRamps.red[500],
299
+ "status-error-dark": primitiveRamps.red[700],
295
300
  "status-error-subtle": "rgba(209, 67, 67, 0.12)",
296
- "status-warning": primitiveColors.amber[500],
297
- "status-warning-light": primitiveColors.amber[400],
298
- "status-warning-dark": primitiveColors.amber[600],
299
- "status-warning-subtle": "rgba(255, 176, 32, 0.12)",
300
- "status-info": primitiveColors.sky[500],
301
- "status-info-light": primitiveColors.sky[400],
302
- "status-info-dark": primitiveColors.sky[700],
301
+ "status-error-vivid": primitiveColors.redVivid[500],
302
+ "status-error-vivid-light": primitiveColors.redVivid[400],
303
+ "status-error-vivid-dark": primitiveColors.redVivid[700],
304
+ "status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
305
+ "status-warning": primitiveRamps.amber[300],
306
+ "status-warning-light": primitiveRamps.amber[200],
307
+ "status-warning-dark": primitiveRamps.amber[500],
308
+ "status-warning-subtle": "rgba(249, 180, 21, 0.12)",
309
+ "status-info": primitiveRamps.blue[500],
310
+ "status-info-light": primitiveRamps.blue[300],
311
+ "status-info-dark": primitiveRamps.blue[600],
303
312
  "status-info-subtle": "rgba(33, 150, 243, 0.12)",
304
313
  // Text on status backgrounds
305
314
  "on-status-success": primitiveColors.white,
@@ -341,29 +350,31 @@ var semanticColorsDark = {
341
350
  "text-link-hover": primitiveColors.blue[400],
342
351
  // Surface colors - dark backgrounds
343
352
  "surface-base": primitiveColors.charcoal[700],
344
- // #161616 - main surface
353
+ // main surface
345
354
  "surface-elevated": primitiveColors.charcoal[600],
346
- // #191919 - elevated surface
355
+ // elevated surface
347
356
  "surface-raised": primitiveColors.charcoal[500],
348
- // #1C1C1C - raised surface
357
+ // raised surface
349
358
  "surface-overlay": primitiveColors.charcoal[600],
350
- // #191919 - overlay surface
359
+ // overlay surface
351
360
  "surface-input": primitiveColors.charcoal[600],
352
- // #191919 - input surface
361
+ // input surface
353
362
  // Background colors
354
363
  "background-base": primitiveColors.charcoal[900],
355
- // #101010 - darkest charcoal
364
+ // darkest charcoal
356
365
  "background-default": primitiveColors.charcoal[700],
357
- // #161616 - main background
366
+ // main background
358
367
  "background-subtle": primitiveColors.charcoal[500],
359
- // #1C1C1C - subtle background
368
+ // subtle background
360
369
  // Border colors
361
370
  "border-default": primitiveColors.charcoal[400],
362
- // #1F1F1F - default border
371
+ // default border
363
372
  "border-subtle": primitiveColors.charcoal[500],
364
- // #1C1C1C - subtle border
373
+ // subtle border
365
374
  "border-strong": primitiveColors.charcoal[300],
366
- // #2C2C2C - strong border
375
+ // strong border
376
+ "border-prominent": primitiveColors.charcoal[200],
377
+ // high-visibility divider
367
378
  "border-focus": "#828DF8",
368
379
  "border-input": primitiveColors.neutral[600],
369
380
  "border-input-hover": primitiveColors.neutral[500],
@@ -378,7 +389,7 @@ var semanticColorsDark = {
378
389
  "interactive-disabled-text": "rgba(255, 255, 255, 0.26)",
379
390
  // Divider
380
391
  "divider": primitiveColors.charcoal[400],
381
- // #1F1F1F - divider color
392
+ // divider color
382
393
  // Avatar default
383
394
  "avatar-background": primitiveColors.neutral[600],
384
395
  "avatar-text": primitiveColors.white
@@ -394,21 +405,22 @@ function resolveColor(token, mode = "dark") {
394
405
 
395
406
  // src/theme/workout-tokens.ts
396
407
  var WORKOUT_TOKENS = {
397
- // BodyMap volume heatmap scale (drive dynamic SVG fills, so inline values).
398
- // Maps weekly-volume status against MEV/MAV/MRV landmarks to a fill color.
408
+ // BodyMap volume heatmap the canonical `divergingScale` (under optimal
409
+ // over): a true diverging shape with a light green center, cool-blue under-
410
+ // trained end and warm-red over-reaching end (colorblind-robust in lightness).
399
411
  heatmap: {
400
412
  none: "#E0E0E0",
401
- // gray — no training data
402
- under: "#4A90D9",
403
- // cool blue — below MEV
404
- maintenance: "#F5C842",
405
- // warm yellow — MEV to MAV
406
- productive: "#4CAF50",
407
- // green — MAV to MRV
408
- approaching: "#FFA502",
409
- // orange — near MRV
410
- over: "#FF6B35"
411
- // red-orange — over MRV
413
+ // no training data
414
+ under: divergingScale[0],
415
+ // below MEV
416
+ maintenance: divergingScale[1],
417
+ // MEV to MAV
418
+ productive: divergingScale[2],
419
+ // optimal center — MAV to MRV
420
+ approaching: divergingScale[3],
421
+ // near MRV
422
+ over: divergingScale[4]
423
+ // over MRV
412
424
  }};
413
425
 
414
426
  // src/components/custom/Workout/muscleTaxonomy.ts
@@ -614,6 +626,7 @@ var jsxs = wrapJsx(jsxRuntime.jsxs);
614
626
 
615
627
  // src/components/custom/Workout/BodyMap.tsx
616
628
  var Body = BodyHighlighter__default.default.default ?? BodyHighlighter__default.default;
629
+ var BRAND_PRIMARY = getSemanticColors("dark")["brand-primary"];
617
630
  var OUTLINE_FILL = "rgba(255,255,255,0.08)";
618
631
  var OUTLINE_BORDER = "rgba(255,255,255,0.12)";
619
632
  var BODY_SCALE = 0.8;
@@ -792,7 +805,7 @@ function ViewToggle({ view, onViewChange }) {
792
805
  borderRadius: 9999,
793
806
  backgroundColor: active ? "rgba(255,121,0,0.16)" : "transparent",
794
807
  borderWidth: 1,
795
- borderColor: active ? "#FF7900" : resolveColor("border-strong")
808
+ borderColor: active ? BRAND_PRIMARY : resolveColor("border-strong")
796
809
  },
797
810
  testID: `body-map-toggle-${side}`,
798
811
  children: /* @__PURE__ */ jsx(
@@ -802,7 +815,7 @@ function ViewToggle({ view, onViewChange }) {
802
815
  fontSize: 12,
803
816
  fontFamily: "Inter, sans-serif",
804
817
  fontWeight: active ? "700" : "500",
805
- color: active ? "#FF7900" : resolveColor("text-secondary"),
818
+ color: active ? BRAND_PRIMARY : resolveColor("text-secondary"),
806
819
  textTransform: "capitalize"
807
820
  },
808
821
  children: side
@@ -834,7 +847,7 @@ function MuscleButton({ entry, highlighted, onMusclePress }) {
834
847
  paddingVertical: 3,
835
848
  borderRadius: 9999,
836
849
  borderWidth: 1,
837
- borderColor: highlighted ? "#FF7900" : resolveColor("border-default")
850
+ borderColor: highlighted ? BRAND_PRIMARY : resolveColor("border-default")
838
851
  },
839
852
  testID: `body-map-muscle-${entry.key}`,
840
853
  children: [
@@ -875,7 +888,8 @@ var colorStyles = {
875
888
  success: "bg-status-success",
876
889
  error: "bg-status-error",
877
890
  warning: "bg-status-warning",
878
- info: "bg-status-info"
891
+ info: "bg-status-info",
892
+ "error-vivid": "bg-status-error-vivid"
879
893
  };
880
894
  function Indicator({
881
895
  size = "sm",
@@ -883,14 +897,40 @@ function Indicator({
883
897
  customColor,
884
898
  glow = false,
885
899
  ring = false,
900
+ pulse = false,
886
901
  className,
887
902
  style,
888
903
  ...props
889
904
  }) {
905
+ const pulseMode = pulse === true ? "opacity" : pulse || false;
906
+ const colorClass = !customColor ? colorStyles[color] : void 0;
907
+ const colorStyle = customColor ? { backgroundColor: customColor } : void 0;
908
+ if (pulseMode === "ping") {
909
+ return /* @__PURE__ */ jsxs(reactNative.View, { className: cn("relative", sizeStyles[size], className), style, ...props, children: [
910
+ /* @__PURE__ */ jsx(
911
+ reactNative.View,
912
+ {
913
+ className: cn("absolute inset-0 rounded-full animate-ping", colorClass),
914
+ style: colorStyle
915
+ }
916
+ ),
917
+ /* @__PURE__ */ jsx(
918
+ reactNative.View,
919
+ {
920
+ className: cn(
921
+ "relative rounded-full",
922
+ sizeStyles[size],
923
+ colorClass,
924
+ ring && "border-2 border-background-base"
925
+ ),
926
+ style: colorStyle
927
+ }
928
+ )
929
+ ] });
930
+ }
890
931
  const dynamicStyle = {
891
932
  ...typeof style === "object" ? style : {},
892
- ...customColor ? { backgroundColor: customColor } : {},
893
- ...glow && !customColor ? {} : {},
933
+ ...colorStyle ?? {},
894
934
  ...glow && customColor ? { boxShadow: `0 0 6px ${customColor}` } : {}
895
935
  };
896
936
  return /* @__PURE__ */ jsx(
@@ -899,12 +939,14 @@ function Indicator({
899
939
  className: cn(
900
940
  "rounded-full shrink-0",
901
941
  sizeStyles[size],
902
- !customColor && colorStyles[color],
942
+ colorClass,
943
+ pulseMode === "opacity" && "animate-pulse",
903
944
  ring && "border-2 border-background-base",
904
- glow && !customColor && color === "success" && "shadow-[0_0_6px_rgba(20,184,166,0.6)]",
945
+ glow && !customColor && color === "success" && "shadow-[0_0_6px_rgba(46,213,115,0.6)]",
905
946
  glow && !customColor && color === "error" && "shadow-[0_0_6px_rgba(239,68,68,0.6)]",
906
947
  glow && !customColor && color === "warning" && "shadow-[0_0_6px_rgba(245,158,11,0.6)]",
907
948
  glow && !customColor && color === "primary" && "shadow-[0_0_6px_rgba(255,121,0,0.6)]",
949
+ glow && !customColor && color === "error-vivid" && "shadow-[0_0_6px_rgba(255,71,87,0.6)]",
908
950
  className
909
951
  ),
910
952
  style: Object.keys(dynamicStyle).length > 0 ? dynamicStyle : style,
@@ -982,7 +1024,7 @@ function Badge({
982
1024
  }
983
1025
  );
984
1026
  }
985
- var BRAND_PRIMARY = "#FF7900";
1027
+ var BRAND_PRIMARY2 = getSemanticColors("dark")["brand-primary"];
986
1028
  function normalizeData(data, height) {
987
1029
  if (data.length === 0) return [];
988
1030
  const min = Math.min(...data);
@@ -1019,7 +1061,7 @@ function Sparkline({
1019
1061
  }
1020
1062
  );
1021
1063
  }
1022
- const resolvedColor = color ?? BRAND_PRIMARY;
1064
+ const resolvedColor = color ?? BRAND_PRIMARY2;
1023
1065
  const normalized = normalizeData(data, height);
1024
1066
  const stepX = data.length > 1 ? width / (data.length - 1) : 0;
1025
1067
  const dotSize = 3;
@@ -1135,8 +1177,9 @@ function Sparkline({
1135
1177
  }
1136
1178
 
1137
1179
  // src/components/custom/Workout/BodyMapDetailPanel.tsx
1138
- var BRAND_PRIMARY2 = "#FF7900";
1139
- var VOLUME_GRADIENT = "linear-gradient(90deg, #2196F3 0%, #14B8A6 50%, #D14343 100%)";
1180
+ var t = getSemanticColors("dark");
1181
+ var BRAND_PRIMARY3 = t["brand-primary"];
1182
+ var VOLUME_GRADIENT = `linear-gradient(90deg, ${t["status-info"]} 0%, ${t["status-success"]} 50%, ${t["status-error"]} 100%)`;
1140
1183
  var SLIDE_OFFSET = 400;
1141
1184
  var BACKDROP_OPACITY = 0.4;
1142
1185
  var STATUS_BADGE_COLOR = {
@@ -1534,7 +1577,7 @@ function BodyMapDetailPanel({
1534
1577
  borderColor: "rgba(255,121,0,0.3)"
1535
1578
  },
1536
1579
  testID: "body-map-detail-panel-view-exercises",
1537
- children: /* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 13, fontFamily: "Inter, sans-serif", fontWeight: "700", color: BRAND_PRIMARY2 }, children: "View exercises" })
1580
+ children: /* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 13, fontFamily: "Inter, sans-serif", fontWeight: "700", color: BRAND_PRIMARY3 }, children: "View exercises" })
1538
1581
  }
1539
1582
  )
1540
1583
  ]
@@ -2272,17 +2315,18 @@ function CardContent({ children, className }) {
2272
2315
  function CardFooter({ children, className }) {
2273
2316
  return /* @__PURE__ */ jsx(reactNative.View, { className: cn("px-6 py-4 flex-row items-center gap-2", className), children });
2274
2317
  }
2318
+ var t2 = getSemanticColors("dark");
2275
2319
  var solidVariantColors = {
2276
- success: "#14B8A6",
2277
- warning: "#FFB020",
2278
- error: "#D14343",
2320
+ success: t2["status-success"],
2321
+ warning: t2["status-warning"],
2322
+ error: t2["status-error"],
2279
2323
  neutral: "#6B7280"
2280
2324
  };
2281
2325
  var ringVariantStyles = {
2282
2326
  "on-track": {
2283
- backgroundColor: "rgba(20,184,166,0.15)",
2327
+ backgroundColor: "rgba(46,213,115,0.15)",
2284
2328
  borderWidth: 1,
2285
- borderColor: "rgba(20,184,166,0.3)"
2329
+ borderColor: "rgba(46,213,115,0.3)"
2286
2330
  },
2287
2331
  deviation: {
2288
2332
  backgroundColor: "rgba(245,158,11,0.15)",
@@ -2297,11 +2341,11 @@ var ringVariantStyles = {
2297
2341
  }
2298
2342
  };
2299
2343
  var glowStyles = {
2300
- success: { boxShadow: "0 0 4px rgba(20,184,166,0.4)" },
2344
+ success: { boxShadow: "0 0 4px rgba(46,213,115,0.4)" },
2301
2345
  warning: { boxShadow: "0 0 4px rgba(245,158,11,0.4)" },
2302
2346
  error: { boxShadow: "0 0 4px rgba(239,68,68,0.4)" },
2303
2347
  neutral: { boxShadow: "0 0 4px rgba(107,114,128,0.4)" },
2304
- "on-track": { boxShadow: "0 0 4px rgba(20,184,166,0.4)" },
2348
+ "on-track": { boxShadow: "0 0 4px rgba(46,213,115,0.4)" },
2305
2349
  deviation: { boxShadow: "0 0 4px rgba(245,158,11,0.4)" },
2306
2350
  future: { boxShadow: "0 0 4px rgba(107,114,128,0.4)" }
2307
2351
  };
@@ -2315,8 +2359,8 @@ var iconColors = {
2315
2359
  warning: "#6B4000",
2316
2360
  error: "#5C1A1A",
2317
2361
  neutral: "#D1D5DB",
2318
- "on-track": "#14B8A6",
2319
- deviation: "#FFB020",
2362
+ "on-track": t2["status-success"],
2363
+ deviation: t2["status-warning"],
2320
2364
  future: "#6B7280"
2321
2365
  };
2322
2366
  var sizeDimensions = {
@@ -2397,20 +2441,23 @@ function StatusDot({
2397
2441
  }
2398
2442
  return /* @__PURE__ */ jsx(reactNative.View, { className, ...props, children: dot });
2399
2443
  }
2444
+ var MESO_ACCENT_GRADIENT_DARK = primitiveRamps.orange[500];
2445
+ var MESO_ACCENT_GRADIENT_LIGHT = primitiveRamps.orange[300];
2400
2446
 
2401
2447
  // src/components/custom/Workout/MesoStatusCard.tsx
2402
- var BRAND_PRIMARY3 = "#FF7900";
2403
- var BRAND_PRIMARY_DARK = "#C45E00";
2404
- var BRAND_PRIMARY_LIGHT = "#FFB066";
2405
- var SUCCESS = "#14B8A6";
2406
- var WARNING = "#FFB020";
2407
- var ERROR = "#D14343";
2408
- var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY3, BRAND_PRIMARY_LIGHT];
2448
+ var t3 = getSemanticColors("dark");
2449
+ var BRAND_PRIMARY4 = t3["brand-primary"];
2450
+ var BRAND_PRIMARY_DARK = MESO_ACCENT_GRADIENT_DARK;
2451
+ var BRAND_PRIMARY_LIGHT = MESO_ACCENT_GRADIENT_LIGHT;
2452
+ var SUCCESS = t3["status-success"];
2453
+ var WARNING = t3["status-warning"];
2454
+ var ERROR = t3["status-error"];
2455
+ var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY4, BRAND_PRIMARY_LIGHT];
2409
2456
  var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
2410
- var GAUGE_GRADIENT = "linear-gradient(90deg, rgba(20,184,166,0.25) 0%, rgba(255,176,32,0.25) 50%, rgba(209,67,67,0.25) 100%)";
2457
+ var GAUGE_GRADIENT = "linear-gradient(90deg, rgba(46,213,115,0.25) 0%, rgba(249,180,21,0.25) 50%, rgba(209,67,67,0.25) 100%)";
2411
2458
  var STATUS_VARIANTS = {
2412
- success: { bg: "rgba(20,184,166,0.15)", border: "rgba(20,184,166,0.3)", text: SUCCESS },
2413
- warning: { bg: "rgba(255,176,32,0.15)", border: "rgba(255,176,32,0.3)", text: WARNING },
2459
+ success: { bg: "rgba(46,213,115,0.15)", border: "rgba(46,213,115,0.3)", text: SUCCESS },
2460
+ warning: { bg: "rgba(249,180,21,0.15)", border: "rgba(249,180,21,0.3)", text: WARNING },
2414
2461
  error: { bg: "rgba(209,67,67,0.15)", border: "rgba(209,67,67,0.25)", text: ERROR }
2415
2462
  };
2416
2463
  function clamp012(value) {
@@ -2702,9 +2749,9 @@ function MesoStatusCard({
2702
2749
  reactNative.View,
2703
2750
  {
2704
2751
  style: {
2705
- backgroundColor: "rgba(255,176,32,0.06)",
2752
+ backgroundColor: "rgba(249,180,21,0.06)",
2706
2753
  borderWidth: 1,
2707
- borderColor: "rgba(255,176,32,0.15)",
2754
+ borderColor: "rgba(249,180,21,0.15)",
2708
2755
  borderRadius: 8,
2709
2756
  paddingVertical: 10,
2710
2757
  paddingHorizontal: 12
@@ -2730,9 +2777,9 @@ function MesoStatusCard({
2730
2777
  className: "flex-row items-center",
2731
2778
  style: {
2732
2779
  gap: 8,
2733
- backgroundColor: "rgba(20,184,166,0.06)",
2780
+ backgroundColor: "rgba(46,213,115,0.06)",
2734
2781
  borderWidth: 1,
2735
- borderColor: "rgba(20,184,166,0.2)",
2782
+ borderColor: "rgba(46,213,115,0.2)",
2736
2783
  borderRadius: 8,
2737
2784
  paddingVertical: 10,
2738
2785
  paddingHorizontal: 12