@titan-design/react-ui 0.13.0 → 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 (146) hide show
  1. package/README.md +14 -0
  2. package/dist/bodymap.js +129 -76
  3. package/dist/bodymap.js.map +1 -1
  4. package/dist/bodymap.mjs +129 -76
  5. package/dist/bodymap.mjs.map +1 -1
  6. package/dist/index.d.mts +117 -26
  7. package/dist/index.d.ts +117 -26
  8. package/dist/index.js +677 -450
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +673 -451
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/{pages-_3Ajpiqu.d.ts → pages-CsjsUn0G.d.ts} +30 -13
  13. package/dist/{pages-CpW3OB3g.d.mts → pages-ZbT_pD_U.d.mts} +30 -13
  14. package/dist/pages.d.mts +1 -1
  15. package/dist/pages.d.ts +1 -1
  16. package/dist/pages.js +676 -701
  17. package/dist/pages.js.map +1 -1
  18. package/dist/pages.mjs +676 -701
  19. package/dist/pages.mjs.map +1 -1
  20. package/dist/theme/index.d.mts +31 -7
  21. package/dist/theme/index.d.ts +31 -7
  22. package/dist/theme/index.js +84 -20
  23. package/dist/theme/index.js.map +1 -1
  24. package/dist/theme/index.mjs +83 -21
  25. package/dist/theme/index.mjs.map +1 -1
  26. package/dist/theme/tokens-css.js +84 -20
  27. package/dist/theme/tokens-css.js.map +1 -1
  28. package/dist/theme/tokens-css.mjs +84 -20
  29. package/dist/theme/tokens-css.mjs.map +1 -1
  30. package/dist/theme/tokens.d.mts +56 -7
  31. package/dist/theme/tokens.d.ts +56 -7
  32. package/dist/theme/tokens.js +72 -20
  33. package/dist/theme/tokens.js.map +1 -1
  34. package/dist/theme/tokens.mjs +71 -21
  35. package/dist/theme/tokens.mjs.map +1 -1
  36. package/docs/render-testing-pattern.md +130 -0
  37. package/package.json +1 -1
  38. package/src/arch/Architecture.stories.tsx +3 -1
  39. package/src/arch/arch-graph.json +74 -72
  40. package/src/components/custom/ActiveWork/InitiativeBrief.tsx +2 -1
  41. package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +8 -3
  42. package/src/components/custom/EmptyState/EmptyState.stories.tsx +1 -1
  43. package/src/components/custom/Gauge/Gauge.stories.tsx +4 -1
  44. package/src/components/custom/Gauge/Gauge.tsx +3 -1
  45. package/src/components/custom/Scatter/Scatter.stories.tsx +10 -7
  46. package/src/components/custom/Scatter/Scatter.tsx +6 -4
  47. package/src/components/custom/Sidebar/Sidebar.stories.tsx +1 -1
  48. package/src/components/custom/Table/Table.stories.tsx +1 -1
  49. package/src/components/custom/Table/Table.tsx +2 -2
  50. package/src/components/custom/Treemap/Treemap.stories.tsx +13 -10
  51. package/src/components/custom/Treemap/Treemap.tsx +4 -1
  52. package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +2 -1
  53. package/src/components/custom/Workout/BaseBadge.stories.tsx +11 -7
  54. package/src/components/custom/Workout/BaseBadge.tsx +3 -2
  55. package/src/components/custom/Workout/BodyMap.tsx +5 -3
  56. package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +13 -3
  57. package/src/components/custom/Workout/BodyMapDetailPanel.tsx +5 -3
  58. package/src/components/custom/Workout/CapacityBandChart.stories.tsx +2 -1
  59. package/src/components/custom/Workout/CapacityBandChart.tsx +5 -3
  60. package/src/components/custom/Workout/DeviationBar.test.tsx +5 -2
  61. package/src/components/custom/Workout/DeviationBar.tsx +5 -2
  62. package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +7 -6
  63. package/src/components/custom/Workout/DualVelocityStrip.test.tsx +29 -16
  64. package/src/components/custom/Workout/ExerciseCard.stories.tsx +8 -8
  65. package/src/components/custom/Workout/ExerciseCard.test.tsx +39 -19
  66. package/src/components/custom/Workout/ExerciseCard.tsx +92 -167
  67. package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +89 -6
  68. package/src/components/custom/Workout/ExerciseCardHeading.test.tsx +189 -1
  69. package/src/components/custom/Workout/ExerciseCardHeading.tsx +167 -18
  70. package/src/components/custom/Workout/ExerciseDetailPage.tsx +3 -2
  71. package/src/components/custom/Workout/ExerciseHeading.tsx +192 -47
  72. package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +6 -5
  73. package/src/components/custom/Workout/InputBar.tsx +4 -2
  74. package/src/components/custom/Workout/IntensityBar.tsx +4 -1
  75. package/src/components/custom/Workout/MesoCard.tsx +2 -1
  76. package/src/components/custom/Workout/MesoStatusCard.tsx +11 -10
  77. package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +8 -3
  78. package/src/components/custom/Workout/PrHistoryModal.stories.tsx +12 -2
  79. package/src/components/custom/Workout/README.md +58 -12
  80. package/src/components/custom/Workout/ReadinessCheck.tsx +4 -2
  81. package/src/components/custom/Workout/RestTimer.stories.tsx +13 -2
  82. package/src/components/custom/Workout/RestTimer.tsx +4 -2
  83. package/src/components/custom/Workout/SegmentedBar.stories.tsx +16 -12
  84. package/src/components/custom/Workout/SegmentedBar.tsx +4 -3
  85. package/src/components/custom/Workout/SetStrip.stories.tsx +3 -2
  86. package/src/components/custom/Workout/SetsRepsLoad.tsx +23 -9
  87. package/src/components/custom/Workout/Sparkline.stories.tsx +13 -10
  88. package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +2 -1
  89. package/src/components/custom/Workout/StrengthTrendChart.tsx +8 -6
  90. package/src/components/custom/Workout/TempoDisplay.stories.tsx +4 -3
  91. package/src/components/custom/Workout/TempoDisplay.tsx +2 -0
  92. package/src/components/custom/Workout/VelocityStrip.dual.stories.tsx +3 -2
  93. package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +1 -1
  94. package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +40 -0
  95. package/src/components/custom/Workout/VelocityStrip.test.tsx +48 -6
  96. package/src/components/custom/Workout/VelocityStrip.tsx +23 -14
  97. package/src/components/custom/Workout/ZoneTrack.stories.tsx +3 -1
  98. package/src/components/custom/Workout/exerciseRowState.ts +29 -0
  99. package/src/components/custom/Workout/index.ts +12 -2
  100. package/src/components/custom/Workout/metricText.stories.tsx +9 -8
  101. package/src/components/custom/Workout/metricText.tsx +4 -2
  102. package/src/components/custom/Workout/setHeadingKit.tsx +12 -10
  103. package/src/components/custom/Workout/velocity-story-kit.tsx +2 -2
  104. package/src/components/custom/charts/README.md +5 -0
  105. package/src/components/custom/charts/SetBarChart.test.tsx +16 -0
  106. package/src/components/custom/charts/SetBarChart.tsx +14 -5
  107. package/src/components/custom/charts/flatBarGeometry.test.ts +41 -0
  108. package/src/components/custom/charts/flatBarGeometry.ts +32 -0
  109. package/src/components/custom/stepper/Stepper.tsx +8 -6
  110. package/src/components/ui/alert/Alert.stories.tsx +14 -4
  111. package/src/components/ui/alert/Alert.tsx +24 -3
  112. package/src/components/ui/button/Button.tsx +12 -12
  113. package/src/components/ui/checkbox/Checkbox.tsx +2 -2
  114. package/src/components/ui/data-row/DataRow.stories.tsx +6 -2
  115. package/src/components/ui/drawer/Drawer.tsx +4 -1
  116. package/src/components/ui/icon-box/IconBox.tsx +8 -6
  117. package/src/components/ui/indicator/Indicator.stories.tsx +4 -3
  118. package/src/components/ui/list-item/ListItem.stories.tsx +7 -4
  119. package/src/components/ui/modal/Modal.tsx +2 -0
  120. package/src/components/ui/pill/Pill.stories.tsx +53 -0
  121. package/src/components/ui/pill/Pill.tsx +10 -6
  122. package/src/components/ui/popover/Popover.stories.tsx +1 -1
  123. package/src/components/ui/progress/Progress.tsx +9 -6
  124. package/src/components/ui/radio/Radio.tsx +1 -1
  125. package/src/components/ui/section/Section.stories.tsx +10 -10
  126. package/src/components/ui/select/Select.tsx +2 -1
  127. package/src/components/ui/spinner/Spinner.tsx +3 -1
  128. package/src/components/ui/stack/Stack.stories.tsx +7 -7
  129. package/src/components/ui/surface/Surface.stories.tsx +75 -28
  130. package/src/components/ui/switch/Switch.tsx +1 -1
  131. package/src/components/ui/tabs/Tabs.tsx +4 -2
  132. package/src/components/ui/toast/Toast.tsx +6 -4
  133. package/src/components/ui/toolbar-button/ToolbarButton.tsx +13 -6
  134. package/src/stories/PresetShowcase.stories.tsx +1 -1
  135. package/src/test/no-raw-color.test.ts +39 -0
  136. package/src/theme/Alpha.stories.tsx +103 -0
  137. package/src/theme/ProposedTokensVW82.stories.tsx +414 -0
  138. package/src/theme/config.ts +12 -0
  139. package/src/theme/global.css +15 -3
  140. package/src/theme/subtle-tone-weight.test.ts +163 -0
  141. package/src/theme/tailwind-var-opacity.test.ts +163 -0
  142. package/src/theme/tokens/primitives.ts +33 -0
  143. package/src/theme/tokens/semantic-hex-guard.test.ts +322 -0
  144. package/src/theme/tokens/semantic.ts +56 -20
  145. package/src/utils/colors.alpha-adoption.test.ts +408 -0
  146. package/tailwind.config.js +50 -9
package/dist/index.mjs CHANGED
@@ -180,33 +180,41 @@ var statusColors = {
180
180
  subtle: "bg-status-success-subtle",
181
181
  outline: "border-2 border-status-success bg-transparent",
182
182
  solid: "bg-status-success",
183
+ onSolid: "text-on-status-success",
183
184
  border: "border-status-success",
184
185
  icon: "text-status-success",
185
- text: "text-status-success"
186
+ text: "text-status-success",
187
+ subtleText: "text-on-status-success-subtle"
186
188
  },
187
189
  info: {
188
190
  subtle: "bg-status-info-subtle",
189
191
  outline: "border-2 border-status-info bg-transparent",
190
192
  solid: "bg-status-info",
193
+ onSolid: "text-on-status-info",
191
194
  border: "border-status-info",
192
195
  icon: "text-status-info",
193
- text: "text-status-info"
196
+ text: "text-status-info",
197
+ subtleText: "text-on-status-info-subtle"
194
198
  },
195
199
  warning: {
196
200
  subtle: "bg-status-warning-subtle",
197
201
  outline: "border-2 border-status-warning bg-transparent",
198
202
  solid: "bg-status-warning",
203
+ onSolid: "text-on-status-warning",
199
204
  border: "border-status-warning",
200
205
  icon: "text-status-warning",
201
- text: "text-status-warning"
206
+ text: "text-status-warning",
207
+ subtleText: "text-on-status-warning-subtle"
202
208
  },
203
209
  error: {
204
210
  subtle: "bg-status-error-subtle",
205
211
  outline: "border-2 border-status-error bg-transparent",
206
212
  solid: "bg-status-error",
213
+ onSolid: "text-on-status-error",
207
214
  border: "border-status-error",
208
215
  icon: "text-status-error",
209
- text: "text-status-error"
216
+ text: "text-status-error",
217
+ subtleText: "text-on-status-error-subtle"
210
218
  }
211
219
  };
212
220
  var defaultIcons = {
@@ -250,7 +258,7 @@ function Alert({
250
258
  className: cn(
251
259
  "font-bold",
252
260
  isCompact ? "text-base" : "text-lg",
253
- isSolid ? "text-white" : colors.icon
261
+ isSolid ? colors.onSolid : variant === "subtle" ? colors.subtleText : colors.icon
254
262
  ),
255
263
  children: defaultIcons[status]
256
264
  }
@@ -259,7 +267,10 @@ function Alert({
259
267
  message != null && /* @__PURE__ */ jsx(
260
268
  Text,
261
269
  {
262
- className: cn("text-sm font-semibold", isSolid ? "text-white" : colors.text),
270
+ className: cn(
271
+ "text-sm font-semibold",
272
+ isSolid ? colors.onSolid : variant === "subtle" ? colors.subtleText : colors.text
273
+ ),
263
274
  testID: "alert-message",
264
275
  children: message
265
276
  }
@@ -273,7 +284,16 @@ function Alert({
273
284
  accessibilityRole: "button",
274
285
  accessibilityLabel: "Close alert",
275
286
  className: "ml-2 p-1 rounded web:hover:bg-black/10 active:bg-black/20",
276
- children: /* @__PURE__ */ jsx(Text, { className: cn("text-lg", isSolid ? "text-white/70" : "text-text-secondary"), children: "\xD7" })
287
+ children: /* @__PURE__ */ jsx(
288
+ Text,
289
+ {
290
+ className: cn(
291
+ "text-lg",
292
+ isSolid ? cn(colors.onSolid, "opacity-70") : "text-text-secondary"
293
+ ),
294
+ children: "\xD7"
295
+ }
296
+ )
277
297
  }
278
298
  )
279
299
  ]
@@ -294,6 +314,26 @@ var primitiveColors = {
294
314
  transparent: "transparent"
295
315
  };
296
316
  var alertRedVivid = "#FF4757";
317
+ var resultPaletteColors = {
318
+ improve: "#4caf50",
319
+ improveDark: "#248a24",
320
+ degrade: "#ef5350",
321
+ degradeDark: "#b30000",
322
+ inconclusive: "#9E9A97"
323
+ };
324
+ var semanticPins = {
325
+ // Cool navy-black; darker and more blue-shifted than any warm greyRamp step.
326
+ textPrimaryLight: "#121828",
327
+ // Cool blue-grey; outside greyRamp's warm (R>=G>=B) scale.
328
+ textSecondaryLight: "#65748B",
329
+ // Pure neutral grey (R=G=B); no warm greyRamp step lands on it exactly.
330
+ backgroundBaseLight: "#EBEBEB",
331
+ // Near-neutral grey, kept one step off backgroundBaseLight by design.
332
+ dividerLight: "#E8E9EB",
333
+ // Periwinkle/indigo; more purple than any primitiveRamps.blue step. Shared by
334
+ // dark-mode text-link, border-focus and border-input-focus.
335
+ focusIndigoDark: "#828DF8"
336
+ };
297
337
  var greyRamp = {
298
338
  50: "#F9F6F3",
299
339
  // L*97.0 W6
@@ -726,6 +766,12 @@ var semanticColorsLight = {
726
766
  // Text on brand backgrounds (on-*)
727
767
  "on-brand-primary": primitiveColors.white,
728
768
  "on-brand-secondary": primitiveColors.white,
769
+ // Text ON a `-subtle` fill. Light mode keeps today's pairing (the base token) so
770
+ // nothing moves here: light has the same disease mirrored — a light rung on a
771
+ // near-white ramp[50] fill — but correcting it belongs with the light-mode pass
772
+ // in AW-121, not this one.
773
+ "on-brand-primary-subtle": primitiveRamps.orange[400],
774
+ "on-brand-secondary-subtle": primitiveRamps.cyan[600],
729
775
  // Status colors (status-*)
730
776
  "status-success": primitiveRamps.green[300],
731
777
  "status-success-light": primitiveRamps.green[200],
@@ -761,21 +807,26 @@ var semanticColorsLight = {
761
807
  "status-info-subtle": primitiveRamps.blue[50],
762
808
  "status-info-muted": "rgba(33, 150, 243, 0.30)",
763
809
  "status-info-strong": "rgba(33, 150, 243, 0.50)",
810
+ // Text ON a `-subtle` fill — see the on-brand-*-subtle note above.
811
+ "on-status-success-subtle": primitiveRamps.green[300],
812
+ "on-status-error-subtle": primitiveRamps.red[600],
813
+ "on-status-warning-subtle": primitiveRamps.amber[300],
814
+ "on-status-info-subtle": primitiveRamps.blue[500],
764
815
  // Text on status backgrounds (on-status-*)
765
816
  "on-status-success": primitiveColors.white,
766
817
  "on-status-error": primitiveColors.white,
767
818
  "on-status-warning": primitiveColors.white,
768
819
  "on-status-info": primitiveColors.white,
769
820
  // Result/outcome indicators (result-*)
770
- "result-improve": "#4caf50",
821
+ "result-improve": resultPaletteColors.improve,
771
822
  // Green - positive outcome
772
823
  "result-improve-light": "rgba(76, 175, 80, 0.12)",
773
- "result-improve-dark": "#248a24",
774
- "result-degrade": "#ef5350",
824
+ "result-improve-dark": resultPaletteColors.improveDark,
825
+ "result-degrade": resultPaletteColors.degrade,
775
826
  // Red - negative outcome
776
827
  "result-degrade-light": "rgba(239, 83, 80, 0.12)",
777
- "result-degrade-dark": "#b30000",
778
- "result-inconclusive": "#9E9A97",
828
+ "result-degrade-dark": resultPaletteColors.degradeDark,
829
+ "result-inconclusive": resultPaletteColors.inconclusive,
779
830
  // Gray - no clear result
780
831
  "result-inconclusive-light": "rgba(158, 154, 151, 0.12)",
781
832
  "result-neutral": greyRamp[600],
@@ -807,8 +858,8 @@ var semanticColorsLight = {
807
858
  "data-10": discreteRainbow[22],
808
859
  // Dark Orange
809
860
  // Text colors (text-*)
810
- "text-primary": "#121828",
811
- "text-secondary": "#65748B",
861
+ "text-primary": semanticPins.textPrimaryLight,
862
+ "text-secondary": semanticPins.textSecondaryLight,
812
863
  "text-tertiary": greyRamp[400],
813
864
  "text-disabled": "rgba(55, 65, 81, 0.48)",
814
865
  "text-inverse": primitiveColors.white,
@@ -824,7 +875,7 @@ var semanticColorsLight = {
824
875
  "surface-input": greyRamp[50],
825
876
  // Input field background (filled variant)
826
877
  // Background colors (background-*)
827
- "background-base": "#EBEBEB",
878
+ "background-base": semanticPins.backgroundBaseLight,
828
879
  "background-default": primitiveColors.white,
829
880
  "background-subtle": greyRamp[50],
830
881
  // Frame/bezel chrome — top bar + side nav shell, one step below
@@ -855,7 +906,7 @@ var semanticColorsLight = {
855
906
  "interactive-disabled": "rgba(55, 65, 81, 0.12)",
856
907
  "interactive-disabled-text": "rgba(55, 65, 81, 0.26)",
857
908
  // Divider
858
- divider: "#E8E9EB",
909
+ divider: semanticPins.dividerLight,
859
910
  // Avatar default
860
911
  "avatar-background": greyRamp[600],
861
912
  "avatar-text": primitiveColors.white
@@ -873,7 +924,7 @@ var semanticColorsDark = {
873
924
  "brand-secondary": primitiveRamps.cyan[600],
874
925
  "brand-secondary-light": primitiveRamps.cyan[500],
875
926
  "brand-secondary-dark": primitiveRamps.cyan[700],
876
- "brand-secondary-subtle": "rgba(48, 123, 155, 0.12)",
927
+ "brand-secondary-subtle": "rgba(34, 211, 238, 0.12)",
877
928
  "brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
878
929
  "brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
879
930
  "brand-secondary-hover": primitiveRamps.cyan[500],
@@ -881,6 +932,14 @@ var semanticColorsDark = {
881
932
  // Text on brand backgrounds
882
933
  "on-brand-primary": primitiveColors.white,
883
934
  "on-brand-secondary": primitiveColors.white,
935
+ // Text ON a `-subtle` fill. Its own role: `brand-primary` and friends are tuned to
936
+ // carry a white label as a solid fill, which makes the two deepest of them
937
+ // (cyan[600], red[600]) too dark to read as text on a dark plane. Levelling the
938
+ // family at rung 300 puts every tone within OKLCH L 0.769-0.813 instead of
939
+ // 0.550-0.813. Brand is deliberately left at its own orange[400] (operator, AW-133)
940
+ // so the Voltras tone never drifts; it is the one tone under AA on a raised card.
941
+ "on-brand-primary-subtle": primitiveRamps.orange[400],
942
+ "on-brand-secondary-subtle": primitiveRamps.cyan[300],
884
943
  // Status colors
885
944
  "status-success": primitiveRamps.green[300],
886
945
  "status-success-light": primitiveRamps.green[200],
@@ -894,7 +953,10 @@ var semanticColorsDark = {
894
953
  "status-error": primitiveRamps.red[600],
895
954
  "status-error-light": primitiveRamps.red[500],
896
955
  "status-error-dark": primitiveRamps.red[700],
897
- "status-error-subtle": "rgba(209, 67, 67, 0.12)",
956
+ // Alpha 0.08, not the family's 0.12: error's label is red[400], a rung darker than
957
+ // its siblings so it reads RED rather than pink (rung 300 has only 0.121 chroma).
958
+ // Thinning the fill buys back the contrast that extra darkness costs. See AW-133.
959
+ "status-error-subtle": "rgba(247, 113, 117, 0.08)",
898
960
  "status-error-muted": "rgba(209, 67, 67, 0.30)",
899
961
  "status-error-strong": "rgba(209, 67, 67, 0.50)",
900
962
  "status-error-vivid": alertRedVivid,
@@ -912,7 +974,7 @@ var semanticColorsDark = {
912
974
  "status-info": primitiveRamps.blue[500],
913
975
  "status-info-light": primitiveRamps.blue[300],
914
976
  "status-info-dark": primitiveRamps.blue[600],
915
- "status-info-subtle": "rgba(33, 150, 243, 0.12)",
977
+ "status-info-subtle": "rgba(120, 194, 255, 0.12)",
916
978
  "status-info-muted": "rgba(33, 150, 243, 0.30)",
917
979
  "status-info-strong": "rgba(33, 150, 243, 0.50)",
918
980
  // Text on status backgrounds
@@ -920,14 +982,22 @@ var semanticColorsDark = {
920
982
  "on-status-error": primitiveColors.white,
921
983
  "on-status-warning": primitiveColors.white,
922
984
  "on-status-info": primitiveColors.white,
985
+ // Text ON a `-subtle` fill — see the on-brand-*-subtle note above. Error is the
986
+ // second deliberate exception to the rung-300 rule (operator, AW-133): red[300]
987
+ // levelled perfectly but read PINK, because a red that light can only hold 0.121
988
+ // chroma. red[400] carries 0.165 and reads red; its fill is thinned to compensate.
989
+ "on-status-success-subtle": primitiveRamps.green[300],
990
+ "on-status-error-subtle": primitiveRamps.red[400],
991
+ "on-status-warning-subtle": primitiveRamps.amber[300],
992
+ "on-status-info-subtle": primitiveRamps.blue[300],
923
993
  // Result/outcome indicators (result-*)
924
- "result-improve": "#4caf50",
994
+ "result-improve": resultPaletteColors.improve,
925
995
  "result-improve-light": "rgba(76, 175, 80, 0.16)",
926
- "result-improve-dark": "#248a24",
927
- "result-degrade": "#ef5350",
996
+ "result-improve-dark": resultPaletteColors.improveDark,
997
+ "result-degrade": resultPaletteColors.degrade,
928
998
  "result-degrade-light": "rgba(239, 83, 80, 0.16)",
929
- "result-degrade-dark": "#b30000",
930
- "result-inconclusive": "#9E9A97",
999
+ "result-degrade-dark": resultPaletteColors.degradeDark,
1000
+ "result-inconclusive": resultPaletteColors.inconclusive,
931
1001
  "result-inconclusive-light": "rgba(158, 154, 151, 0.16)",
932
1002
  "result-neutral": greyRamp[400],
933
1003
  // Text on result backgrounds
@@ -958,7 +1028,7 @@ var semanticColorsDark = {
958
1028
  "text-tertiary": greyRamp[500],
959
1029
  "text-disabled": "rgba(255, 255, 255, 0.38)",
960
1030
  "text-inverse": greyRamp[950],
961
- "text-link": "#828DF8",
1031
+ "text-link": semanticPins.focusIndigoDark,
962
1032
  "text-link-hover": primitiveRamps.blue[400],
963
1033
  // Surface colors - dark backgrounds — warm-tapered DERIVED ramp (TD-surface-tokens,
964
1034
  // S-1, re-spaced S-3). Shipped verbatim from `deriveSurfaceRamp()` — see
@@ -1008,10 +1078,10 @@ var semanticColorsDark = {
1008
1078
  // plane, so it keeps its job without collision.
1009
1079
  "border-prominent": greyRamp[800],
1010
1080
  // high-visibility divider
1011
- "border-focus": "#828DF8",
1081
+ "border-focus": semanticPins.focusIndigoDark,
1012
1082
  "border-input": greyRamp[700],
1013
1083
  "border-input-hover": greyRamp[600],
1014
- "border-input-focus": "#828DF8",
1084
+ "border-input-focus": semanticPins.focusIndigoDark,
1015
1085
  "border-input-error": primitiveRamps.red[500],
1016
1086
  // Alpha hairline separators — the primary separation cue (§4/S-2). Self-
1017
1087
  // normalizing: composites toward white by ~the same amount on ANY plane, so
@@ -1167,12 +1237,12 @@ function getSemanticColors(mode) {
1167
1237
  // src/components/ui/button/Button.tsx
1168
1238
  var textColorMap = {
1169
1239
  solid: {
1170
- primary: "#FFFFFF",
1171
- secondary: "#FFFFFF",
1172
- success: "#FFFFFF",
1173
- error: "#FFFFFF",
1174
- warning: "#FFFFFF",
1175
- info: "#FFFFFF"
1240
+ primary: semanticColorsDark["on-brand-primary"],
1241
+ secondary: semanticColorsDark["on-brand-secondary"],
1242
+ success: semanticColorsDark["on-status-success"],
1243
+ error: semanticColorsDark["on-status-error"],
1244
+ warning: semanticColorsDark["on-status-warning"],
1245
+ info: semanticColorsDark["on-status-info"]
1176
1246
  },
1177
1247
  outline: {
1178
1248
  primary: semanticColorsDark["brand-primary"],
@@ -1243,12 +1313,12 @@ var variantStyles = {
1243
1313
  };
1244
1314
  var textStyles = {
1245
1315
  solid: {
1246
- primary: "text-white",
1247
- secondary: "text-white",
1248
- success: "text-white",
1249
- error: "text-white",
1250
- warning: "text-white",
1251
- info: "text-white"
1316
+ primary: "text-on-brand-primary",
1317
+ secondary: "text-on-brand-secondary",
1318
+ success: "text-on-status-success",
1319
+ error: "text-on-status-error",
1320
+ warning: "text-on-status-warning",
1321
+ info: "text-on-status-info"
1252
1322
  },
1253
1323
  outline: {
1254
1324
  primary: "text-brand-primary",
@@ -2196,13 +2266,16 @@ var toneStyles = {
2196
2266
  // host is, and an alpha fill composites by the same amount on all of them.
2197
2267
  // A `surface-*` fill would vanish on the plane it names. Borderless like the
2198
2268
  // six coloured tones — the fill carries the capsule, not a ring.
2269
+ // Label comes from `on-*-subtle`, not the base tone token: the base is tuned to
2270
+ // carry a white label as a solid fill, which left error and accent unreadable
2271
+ // here (AW-133). The on-subtle tokens level the family at one weight.
2199
2272
  neutral: "bg-hairline-subtle border-transparent text-text-secondary",
2200
- brand: "bg-brand-primary-subtle border-transparent text-brand-primary",
2201
- "brand-secondary": "bg-brand-secondary-subtle border-transparent text-brand-secondary",
2202
- success: "bg-status-success-subtle border-transparent text-status-success",
2203
- warning: "bg-status-warning-subtle border-transparent text-status-warning",
2204
- error: "bg-status-error-subtle border-transparent text-status-error",
2205
- info: "bg-status-info-subtle border-transparent text-status-info"
2273
+ brand: "bg-brand-primary-subtle border-transparent text-on-brand-primary-subtle",
2274
+ "brand-secondary": "bg-brand-secondary-subtle border-transparent text-on-brand-secondary-subtle",
2275
+ success: "bg-status-success-subtle border-transparent text-on-status-success-subtle",
2276
+ warning: "bg-status-warning-subtle border-transparent text-on-status-warning-subtle",
2277
+ error: "bg-status-error-subtle border-transparent text-on-status-error-subtle",
2278
+ info: "bg-status-info-subtle border-transparent text-on-status-info-subtle"
2206
2279
  },
2207
2280
  outline: {
2208
2281
  neutral: "border-hairline text-text-secondary",
@@ -2371,7 +2444,8 @@ var sizeMap = {
2371
2444
  var colorMap = {
2372
2445
  primary: SPINNER_PRIMARY,
2373
2446
  secondary: SPINNER_SECONDARY,
2374
- white: "#FFFFFF",
2447
+ white: primitiveColors.white,
2448
+ // VW-82: Tailwind gray-500; no titan grey matches. Left raw, proposed in the PR.
2375
2449
  default: "#6B7280"
2376
2450
  };
2377
2451
  var containerSizes = {
@@ -2572,8 +2646,8 @@ var Checkbox = forwardRef(function Checkbox2({
2572
2646
  !isDisabled && "web:hover:border-brand-primary"
2573
2647
  ),
2574
2648
  children: [
2575
- isChecked && !isIndeterminate && /* @__PURE__ */ jsx(View, { className: cn("bg-white rounded-sm", styles2.icon), children: /* @__PURE__ */ jsx(Text, { className: "text-brand-primary font-bold text-center leading-none", children: "\u2713" }) }),
2576
- isIndeterminate && /* @__PURE__ */ jsx(View, { className: cn("bg-white h-0.5 w-2/3 rounded") })
2649
+ isChecked && !isIndeterminate && /* @__PURE__ */ jsx(View, { className: cn("bg-on-brand-primary rounded-sm", styles2.icon), children: /* @__PURE__ */ jsx(Text, { className: "text-brand-primary font-bold text-center leading-none", children: "\u2713" }) }),
2650
+ isIndeterminate && /* @__PURE__ */ jsx(View, { className: cn("bg-on-brand-primary h-0.5 w-2/3 rounded") })
2577
2651
  ]
2578
2652
  }
2579
2653
  ),
@@ -2630,7 +2704,7 @@ var Switch = forwardRef(function Switch2({
2630
2704
  View,
2631
2705
  {
2632
2706
  className: cn(
2633
- "rounded-full bg-white transition-transform",
2707
+ "rounded-full bg-on-brand-primary transition-transform",
2634
2708
  styles2.thumb,
2635
2709
  isChecked && styles2.translate
2636
2710
  ),
@@ -2690,6 +2764,8 @@ function Modal({
2690
2764
  onPress: handleBackdropPress,
2691
2765
  className: cn(
2692
2766
  "flex-1 items-center justify-center",
2767
+ // VW-82: scrims stay raw — Tailwind v3 drops the `/n` modifier on a
2768
+ // `var()` colour, so a translucent role has to be its own token (proposed).
2693
2769
  backdropBlur ? "bg-black/30 web:backdrop-blur-sm" : "bg-black/50",
2694
2770
  backdropClassName
2695
2771
  ),
@@ -2985,7 +3061,7 @@ function Tab({ index = 0, isDisabled = false, className, children }) {
2985
3061
  ),
2986
3062
  "soft-rounded": cn(
2987
3063
  "px-4 py-2 rounded-full",
2988
- isActive ? "bg-brand-primary text-white" : "text-text-secondary web:hover:text-text-primary"
3064
+ isActive ? "bg-brand-primary text-on-brand-primary" : "text-text-secondary web:hover:text-text-primary"
2989
3065
  )
2990
3066
  };
2991
3067
  return /* @__PURE__ */ jsx(
@@ -3006,7 +3082,7 @@ function Tab({ index = 0, isDisabled = false, className, children }) {
3006
3082
  {
3007
3083
  className: cn(
3008
3084
  "font-medium",
3009
- isActive ? variant === "soft-rounded" ? "text-white" : "text-text-primary" : "text-text-secondary"
3085
+ isActive ? variant === "soft-rounded" ? "text-on-brand-primary" : "text-text-primary" : "text-text-secondary"
3010
3086
  ),
3011
3087
  children
3012
3088
  }
@@ -3873,6 +3949,7 @@ function Select({
3873
3949
  accessibilityState: { expanded: isOpen, disabled: isDisabled },
3874
3950
  className: cn(
3875
3951
  "flex-row items-center justify-between px-4 py-2.5 rounded-md border",
3952
+ // VW-82: scrim-style fill, left raw (see Modal.tsx).
3876
3953
  variant === "filled" ? "bg-black/30" : "bg-surface-base",
3877
3954
  isInvalid ? "border-border-input-error" : variant === "filled" ? "border-hairline-subtle" : "border-border-input",
3878
3955
  !isDisabled && !isInvalid && "web:hover:border-border-input-hover",
@@ -3946,7 +4023,7 @@ function SelectOption({ option }) {
3946
4023
  "w-4 h-4 mr-3 rounded border",
3947
4024
  selected ? "bg-brand-primary border-brand-primary" : "border-hairline-strong"
3948
4025
  ),
3949
- children: selected && /* @__PURE__ */ jsx(Text, { className: "text-white text-xs text-center", children: "\u2713" })
4026
+ children: selected && /* @__PURE__ */ jsx(Text, { className: "text-on-brand-primary text-xs text-center", children: "\u2713" })
3950
4027
  }
3951
4028
  ),
3952
4029
  /* @__PURE__ */ jsx(
@@ -4003,6 +4080,8 @@ var lightThemeCSSVars = {
4003
4080
  "--color-brand-secondary-strong": semanticColorsLight["brand-secondary-strong"],
4004
4081
  "--color-on-brand-primary": semanticColorsLight["on-brand-primary"],
4005
4082
  "--color-on-brand-secondary": semanticColorsLight["on-brand-secondary"],
4083
+ "--color-on-brand-primary-subtle": semanticColorsLight["on-brand-primary-subtle"],
4084
+ "--color-on-brand-secondary-subtle": semanticColorsLight["on-brand-secondary-subtle"],
4006
4085
  "--color-status-success": semanticColorsLight["status-success"],
4007
4086
  "--color-status-success-subtle": semanticColorsLight["status-success-subtle"],
4008
4087
  "--color-status-success-muted": semanticColorsLight["status-success-muted"],
@@ -4064,6 +4143,10 @@ var lightThemeCSSVars = {
4064
4143
  "--color-on-status-error": semanticColorsLight["on-status-error"],
4065
4144
  "--color-on-status-warning": semanticColorsLight["on-status-warning"],
4066
4145
  "--color-on-status-info": semanticColorsLight["on-status-info"],
4146
+ "--color-on-status-success-subtle": semanticColorsLight["on-status-success-subtle"],
4147
+ "--color-on-status-error-subtle": semanticColorsLight["on-status-error-subtle"],
4148
+ "--color-on-status-warning-subtle": semanticColorsLight["on-status-warning-subtle"],
4149
+ "--color-on-status-info-subtle": semanticColorsLight["on-status-info-subtle"],
4067
4150
  "--color-result-improve": semanticColorsLight["result-improve"],
4068
4151
  "--color-result-improve-light": semanticColorsLight["result-improve-light"],
4069
4152
  "--color-result-improve-dark": semanticColorsLight["result-improve-dark"],
@@ -4116,6 +4199,8 @@ var darkThemeCSSVars = {
4116
4199
  "--color-brand-secondary-strong": semanticColorsDark["brand-secondary-strong"],
4117
4200
  "--color-on-brand-primary": semanticColorsDark["on-brand-primary"],
4118
4201
  "--color-on-brand-secondary": semanticColorsDark["on-brand-secondary"],
4202
+ "--color-on-brand-primary-subtle": semanticColorsDark["on-brand-primary-subtle"],
4203
+ "--color-on-brand-secondary-subtle": semanticColorsDark["on-brand-secondary-subtle"],
4119
4204
  "--color-status-success": semanticColorsDark["status-success"],
4120
4205
  "--color-status-success-subtle": semanticColorsDark["status-success-subtle"],
4121
4206
  "--color-status-success-muted": semanticColorsDark["status-success-muted"],
@@ -4177,6 +4262,10 @@ var darkThemeCSSVars = {
4177
4262
  "--color-on-status-error": semanticColorsDark["on-status-error"],
4178
4263
  "--color-on-status-warning": semanticColorsDark["on-status-warning"],
4179
4264
  "--color-on-status-info": semanticColorsDark["on-status-info"],
4265
+ "--color-on-status-success-subtle": semanticColorsDark["on-status-success-subtle"],
4266
+ "--color-on-status-error-subtle": semanticColorsDark["on-status-error-subtle"],
4267
+ "--color-on-status-warning-subtle": semanticColorsDark["on-status-warning-subtle"],
4268
+ "--color-on-status-info-subtle": semanticColorsDark["on-status-info-subtle"],
4180
4269
  "--color-result-improve": semanticColorsDark["result-improve"],
4181
4270
  "--color-result-improve-light": semanticColorsDark["result-improve-light"],
4182
4271
  "--color-result-improve-dark": semanticColorsDark["result-improve-dark"],
@@ -4524,7 +4613,67 @@ var audiobookPreset = {
4524
4613
  rootClasses: ["atmosphere-warm", "grain"]
4525
4614
  };
4526
4615
 
4616
+ // src/utils/colors.ts
4617
+ function getStatusColor(status) {
4618
+ return `var(--color-status-${status})`;
4619
+ }
4620
+ function getResultColor(result) {
4621
+ return `var(--color-result-${result})`;
4622
+ }
4623
+ function alpha(color, opacity) {
4624
+ const clampedOpacity = Math.max(0, Math.min(1, opacity));
4625
+ if (color.startsWith("#")) {
4626
+ const hex = color.slice(1);
4627
+ let r, g, b;
4628
+ if (hex.length === 3) {
4629
+ r = parseInt(hex[0] + hex[0], 16);
4630
+ g = parseInt(hex[1] + hex[1], 16);
4631
+ b = parseInt(hex[2] + hex[2], 16);
4632
+ } else if (hex.length === 6) {
4633
+ r = parseInt(hex.slice(0, 2), 16);
4634
+ g = parseInt(hex.slice(2, 4), 16);
4635
+ b = parseInt(hex.slice(4, 6), 16);
4636
+ } else {
4637
+ return color;
4638
+ }
4639
+ return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
4640
+ }
4641
+ const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
4642
+ if (rgbMatch) {
4643
+ const [, r, g, b] = rgbMatch;
4644
+ return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
4645
+ }
4646
+ const rgbaMatch = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/);
4647
+ if (rgbaMatch) {
4648
+ const [, r, g, b] = rgbaMatch;
4649
+ return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
4650
+ }
4651
+ return color;
4652
+ }
4653
+ function getLuminance(color) {
4654
+ if (!color.startsWith("#")) return "dark";
4655
+ const hex = color.slice(1);
4656
+ let r, g, b;
4657
+ if (hex.length === 3) {
4658
+ r = parseInt(hex[0] + hex[0], 16);
4659
+ g = parseInt(hex[1] + hex[1], 16);
4660
+ b = parseInt(hex[2] + hex[2], 16);
4661
+ } else if (hex.length === 6) {
4662
+ r = parseInt(hex.slice(0, 2), 16);
4663
+ g = parseInt(hex.slice(2, 4), 16);
4664
+ b = parseInt(hex.slice(4, 6), 16);
4665
+ } else {
4666
+ return "dark";
4667
+ }
4668
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
4669
+ return luminance > 0.5 ? "light" : "dark";
4670
+ }
4671
+ function getContrastText(backgroundColor) {
4672
+ return getLuminance(backgroundColor) === "light" ? "#000000" : "#FFFFFF";
4673
+ }
4674
+
4527
4675
  // src/components/ui/toolbar-button/ToolbarButton.tsx
4676
+ var ICON_IDLE = "#D1D1D1";
4528
4677
  var ToolbarButtonContext = createContext({
4529
4678
  isOpen: false,
4530
4679
  setIsOpen: () => {
@@ -4574,7 +4723,7 @@ function ToolbarButton({
4574
4723
  const showActive = isActive !== false;
4575
4724
  const getIconColor = () => {
4576
4725
  if (isActive === true) return resolveColor("brand-primary");
4577
- return showActive ? "#FFFFFF" : "#D1D1D1";
4726
+ return showActive ? primitiveColors.white : ICON_IDLE;
4578
4727
  };
4579
4728
  const getRaisedStyle = () => {
4580
4729
  if (isDisabled) return styles.disabledBg;
@@ -4663,7 +4812,7 @@ function ToolbarButton({
4663
4812
  var styles = StyleSheet.create({
4664
4813
  // Disabled - flat gray background, no shadows
4665
4814
  disabledBg: {
4666
- backgroundColor: "rgba(255, 255, 255, 0.12)",
4815
+ backgroundColor: alpha(primitiveColors.white, 0.12),
4667
4816
  ...Platform.select({
4668
4817
  web: { boxShadow: "none" },
4669
4818
  default: { shadowOpacity: 0, elevation: 0 }
@@ -4814,7 +4963,7 @@ function Radio({
4814
4963
  isChecked ? checked : unchecked,
4815
4964
  !isDisabled && !isChecked && "web:hover:border-brand-primary"
4816
4965
  ),
4817
- children: isChecked && /* @__PURE__ */ jsx(View, { className: cn("rounded-full bg-white", inner) })
4966
+ children: isChecked && /* @__PURE__ */ jsx(View, { className: cn("rounded-full bg-on-brand-primary", inner) })
4818
4967
  }
4819
4968
  ),
4820
4969
  children && /* @__PURE__ */ jsx(Text, { className: cn("ml-2 text-text-primary", text), children })
@@ -4877,7 +5026,13 @@ function Drawer({
4877
5026
  }
4878
5027
  };
4879
5028
  return /* @__PURE__ */ jsx(Modal$1, { visible: isOpen, transparent: true, animationType: "fade", onRequestClose: onClose, children: /* @__PURE__ */ jsxs(View, { className: "flex-1", children: [
4880
- /* @__PURE__ */ jsx(Pressable, { onPress: handleOverlayPress, className: "absolute inset-0 bg-black/50" }),
5029
+ /* @__PURE__ */ jsx(
5030
+ Pressable,
5031
+ {
5032
+ onPress: handleOverlayPress,
5033
+ className: "absolute inset-0 bg-black/50"
5034
+ }
5035
+ ),
4881
5036
  /* @__PURE__ */ jsxs(
4882
5037
  Surface,
4883
5038
  {
@@ -4955,12 +5110,12 @@ var colorStyles4 = {
4955
5110
  info: "bg-status-info"
4956
5111
  };
4957
5112
  var trackColorStyles = {
4958
- primary: "bg-brand-primary/20",
4959
- secondary: "bg-brand-secondary/20",
4960
- success: "bg-status-success/20",
4961
- error: "bg-status-error/20",
4962
- warning: "bg-status-warning/20",
4963
- info: "bg-status-info/20"
5113
+ primary: "bg-brand-primary-muted",
5114
+ secondary: "bg-brand-secondary-muted",
5115
+ success: "bg-status-success-muted",
5116
+ error: "bg-status-error-muted",
5117
+ warning: "bg-status-warning-muted",
5118
+ info: "bg-status-info-muted"
4964
5119
  };
4965
5120
  function Progress({
4966
5121
  value = 0,
@@ -5197,7 +5352,7 @@ function ToastProvider({
5197
5352
  [defaultDuration, maxToasts]
5198
5353
  );
5199
5354
  const removeToast = useCallback((id) => {
5200
- setToasts((prev) => prev.filter((t18) => t18.id !== id));
5355
+ setToasts((prev) => prev.filter((t19) => t19.id !== id));
5201
5356
  }, []);
5202
5357
  const removeAllToasts = useCallback(() => {
5203
5358
  setToasts([]);
@@ -5233,22 +5388,22 @@ function useToast() {
5233
5388
  }
5234
5389
  var statusStyles = {
5235
5390
  success: {
5236
- bg: "bg-status-success/10",
5391
+ bg: "bg-status-success-subtle",
5237
5392
  border: "border-status-success",
5238
5393
  icon: "\u2713"
5239
5394
  },
5240
5395
  error: {
5241
- bg: "bg-status-error/10",
5396
+ bg: "bg-status-error-subtle",
5242
5397
  border: "border-status-error",
5243
5398
  icon: "\u2715"
5244
5399
  },
5245
5400
  warning: {
5246
- bg: "bg-status-warning/10",
5401
+ bg: "bg-status-warning-subtle",
5247
5402
  border: "border-status-warning",
5248
5403
  icon: "\u26A0"
5249
5404
  },
5250
5405
  info: {
5251
- bg: "bg-status-info/10",
5406
+ bg: "bg-status-info-subtle",
5252
5407
  border: "border-status-info",
5253
5408
  icon: "\u2139"
5254
5409
  }
@@ -5858,12 +6013,12 @@ function DataRow({
5858
6013
  ] });
5859
6014
  }
5860
6015
  var colorClasses = {
5861
- primary: { bg: "bg-brand-primary/10", icon: "text-brand-primary" },
5862
- secondary: { bg: "bg-brand-secondary/10", icon: "text-brand-secondary" },
5863
- success: { bg: "bg-status-success/10", icon: "text-status-success" },
5864
- error: { bg: "bg-status-error/10", icon: "text-status-error" },
5865
- warning: { bg: "bg-status-warning/10", icon: "text-status-warning" },
5866
- info: { bg: "bg-status-info/10", icon: "text-status-info" },
6016
+ primary: { bg: "bg-brand-primary-subtle", icon: "text-brand-primary" },
6017
+ secondary: { bg: "bg-brand-secondary-subtle", icon: "text-brand-secondary" },
6018
+ success: { bg: "bg-status-success-subtle", icon: "text-status-success" },
6019
+ error: { bg: "bg-status-error-subtle", icon: "text-status-error" },
6020
+ warning: { bg: "bg-status-warning-subtle", icon: "text-status-warning" },
6021
+ info: { bg: "bg-status-info-subtle", icon: "text-status-info" },
5867
6022
  neutral: { bg: "bg-surface-elevated", icon: "text-text-secondary" }
5868
6023
  };
5869
6024
  var sizeClasses = {
@@ -6637,6 +6792,12 @@ function StepIndicator({
6637
6792
  upcoming: "bg-surface-base border-hairline-strong",
6638
6793
  error: "bg-status-error border-status-error"
6639
6794
  };
6795
+ const glyphStyles = {
6796
+ completed: "text-on-brand-primary",
6797
+ active: "text-on-brand-primary",
6798
+ upcoming: "text-text-secondary",
6799
+ error: "text-on-status-error"
6800
+ };
6640
6801
  return /* @__PURE__ */ jsx(
6641
6802
  View,
6642
6803
  {
@@ -6645,16 +6806,7 @@ function StepIndicator({
6645
6806
  statusStyles2[status],
6646
6807
  className
6647
6808
  ),
6648
- children: icon || /* @__PURE__ */ jsx(
6649
- Text,
6650
- {
6651
- className: cn(
6652
- "text-sm font-semibold",
6653
- status === "upcoming" ? "text-text-secondary" : "text-white"
6654
- ),
6655
- children: status === "completed" ? "\u2713" : index + 1
6656
- }
6657
- )
6809
+ children: icon || /* @__PURE__ */ jsx(Text, { className: cn("text-sm font-semibold", glyphStyles[status]), children: status === "completed" ? "\u2713" : index + 1 })
6658
6810
  }
6659
6811
  );
6660
6812
  }
@@ -7024,8 +7176,8 @@ var baseBadgeSizeConfig = {
7024
7176
  var variantColors = {
7025
7177
  plain: { backgroundColor: t2["surface-raised"], borderColor: t2["hairline-default"] },
7026
7178
  pr: {
7027
- backgroundColor: "rgba(255, 121, 0, 0.12)",
7028
- borderColor: "rgba(255, 121, 0, 0.3)"
7179
+ backgroundColor: alpha(t2["brand-primary"], 0.12),
7180
+ borderColor: alpha(t2["brand-primary"], 0.3)
7029
7181
  }
7030
7182
  };
7031
7183
  function BaseBadge({
@@ -7255,67 +7407,6 @@ function PrBadge({
7255
7407
  }
7256
7408
  return badge;
7257
7409
  }
7258
-
7259
- // src/utils/colors.ts
7260
- function getStatusColor(status) {
7261
- return `var(--color-status-${status})`;
7262
- }
7263
- function getResultColor(result) {
7264
- return `var(--color-result-${result})`;
7265
- }
7266
- function alpha(color, opacity) {
7267
- const clampedOpacity = Math.max(0, Math.min(1, opacity));
7268
- if (color.startsWith("#")) {
7269
- const hex = color.slice(1);
7270
- let r, g, b;
7271
- if (hex.length === 3) {
7272
- r = parseInt(hex[0] + hex[0], 16);
7273
- g = parseInt(hex[1] + hex[1], 16);
7274
- b = parseInt(hex[2] + hex[2], 16);
7275
- } else if (hex.length === 6) {
7276
- r = parseInt(hex.slice(0, 2), 16);
7277
- g = parseInt(hex.slice(2, 4), 16);
7278
- b = parseInt(hex.slice(4, 6), 16);
7279
- } else {
7280
- return color;
7281
- }
7282
- return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
7283
- }
7284
- const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
7285
- if (rgbMatch) {
7286
- const [, r, g, b] = rgbMatch;
7287
- return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
7288
- }
7289
- const rgbaMatch = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/);
7290
- if (rgbaMatch) {
7291
- const [, r, g, b] = rgbaMatch;
7292
- return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
7293
- }
7294
- return color;
7295
- }
7296
- function getLuminance(color) {
7297
- if (!color.startsWith("#")) return "dark";
7298
- const hex = color.slice(1);
7299
- let r, g, b;
7300
- if (hex.length === 3) {
7301
- r = parseInt(hex[0] + hex[0], 16);
7302
- g = parseInt(hex[1] + hex[1], 16);
7303
- b = parseInt(hex[2] + hex[2], 16);
7304
- } else if (hex.length === 6) {
7305
- r = parseInt(hex.slice(0, 2), 16);
7306
- g = parseInt(hex.slice(2, 4), 16);
7307
- b = parseInt(hex.slice(4, 6), 16);
7308
- } else {
7309
- return "dark";
7310
- }
7311
- const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
7312
- return luminance > 0.5 ? "light" : "dark";
7313
- }
7314
- function getContrastText(backgroundColor) {
7315
- return getLuminance(backgroundColor) === "light" ? "#000000" : "#FFFFFF";
7316
- }
7317
-
7318
- // src/components/custom/Workout/StatusDot.tsx
7319
7410
  var solidFillToken = {
7320
7411
  success: "status-success",
7321
7412
  warning: "status-warning",
@@ -7611,7 +7702,7 @@ function formatPrescription(p) {
7611
7702
  return full.length > 0 ? full : null;
7612
7703
  }
7613
7704
  var METRIC_FONT = "Inter, sans-serif";
7614
- function MetricCell({ children, color, fontSize = 11 }) {
7705
+ function MetricCell({ children, color, fontSize = 11, weight = 600 }) {
7615
7706
  return /* @__PURE__ */ jsx(
7616
7707
  Text,
7617
7708
  {
@@ -7619,7 +7710,7 @@ function MetricCell({ children, color, fontSize = 11 }) {
7619
7710
  fontFamily: METRIC_FONT,
7620
7711
  fontSize,
7621
7712
  color,
7622
- fontWeight: "600",
7713
+ fontWeight: String(weight),
7623
7714
  letterSpacing: 1
7624
7715
  },
7625
7716
  children
@@ -7966,7 +8057,10 @@ function DeviationBar({ deviation, width, className, ...props }) {
7966
8057
  width: resolvedWidth,
7967
8058
  borderRadius: 3,
7968
8059
  // react-native-web renders backgroundImage at runtime; not in RN ViewStyle types
7969
- backgroundImage: "linear-gradient(90deg, rgba(46,213,115,0.25) 0%, rgba(107,114,128,0.15) 50%, rgba(249,180,21,0.25) 100%)"
8060
+ // rgba(107,114,128,0.15) at 50% has no exact token match (nearest:
8061
+ // semanticPins.textSecondaryLight #65748B, ΔRGB ~12.7) — left as a
8062
+ // raw literal (VW-78).
8063
+ backgroundImage: `linear-gradient(90deg, ${alpha(t4["status-success"], 0.25)} 0%, rgba(107,114,128,0.15) 50%, ${alpha(t4["status-warning"], 0.25)} 100%)`
7970
8064
  }
7971
8065
  }
7972
8066
  ),
@@ -7997,7 +8091,7 @@ function DeviationBar({ deviation, width, className, ...props }) {
7997
8091
  var t5 = getSemanticColors("dark");
7998
8092
  var TRACK_BG = "#333333";
7999
8093
  var LABEL_COLOR = "#6B7280";
8000
- var TARGET_LINE_COLOR = "rgba(33, 150, 243, 0.5)";
8094
+ var TARGET_LINE_COLOR = alpha(t5["status-info"], 0.5);
8001
8095
  var AT_TARGET_GLOW = getGlowShadow(t5["status-info"], "subtle");
8002
8096
  var ZONE = {
8003
8097
  building: t5["status-success"],
@@ -8391,15 +8485,31 @@ function useLiveRepGrowth(active, liveRepIndex, liveVelocity, isNewPeak) {
8391
8485
  return liveGrowth;
8392
8486
  }
8393
8487
 
8488
+ // src/components/custom/charts/flatBarGeometry.ts
8489
+ var SET_LEVEL_FLAT_BAR = {
8490
+ /** Track height (px). */
8491
+ height: 8,
8492
+ /** Gap between segment slots (px) — also SetStrip's between-set gap, see `SEGMENTED_BAR_GAP`. */
8493
+ gap: 5,
8494
+ /** Corner radius (px). */
8495
+ radius: 2
8496
+ };
8497
+ var REP_LEVEL_FLAT_BAR = {
8498
+ /** Inter-bar gap is proportional (`gapRatio · barWidth`), floored at this many px. */
8499
+ gapFloor: 2,
8500
+ /** Corner radius (px) default. */
8501
+ radius: 5
8502
+ };
8503
+
8394
8504
  // src/components/custom/charts/SetBarChart.tsx
8395
- function mixHex(a, b, t18) {
8505
+ function mixHex(a, b, t19) {
8396
8506
  const parse = (h) => {
8397
8507
  const s = h.replace("#", "");
8398
8508
  return [parseInt(s.slice(0, 2), 16), parseInt(s.slice(2, 4), 16), parseInt(s.slice(4, 6), 16)];
8399
8509
  };
8400
8510
  const [ar, ag, ab] = parse(a);
8401
8511
  const [br, bg, bb] = parse(b);
8402
- const ch = (x, y) => Math.round(x + (y - x) * t18).toString(16).padStart(2, "0");
8512
+ const ch = (x, y) => Math.round(x + (y - x) * t19).toString(16).padStart(2, "0");
8403
8513
  return `#${ch(ar, br)}${ch(ag, bg)}${ch(ab, bb)}`;
8404
8514
  }
8405
8515
  var VARIABLE_FILL = primitiveRamps.cyan[900];
@@ -8407,7 +8517,7 @@ var CONTINUE_OUTLINE = primitiveRamps.cyan[800];
8407
8517
  var FIXED_MAX_VALUE = 1.15;
8408
8518
  var PEAK_HEADROOM = 1.03;
8409
8519
  function scaleDenominator(scale, maxValue) {
8410
- return scale === "fixed" ? FIXED_MAX_VALUE : maxValue * PEAK_HEADROOM;
8520
+ return (scale === "fixed" ? FIXED_MAX_VALUE : maxValue) * PEAK_HEADROOM;
8411
8521
  }
8412
8522
  function valueLabelFontSize(height) {
8413
8523
  return Math.round(Math.max(8, Math.min(12, height * 0.11)));
@@ -8423,12 +8533,12 @@ var SET_BAR_DEFAULT_HEIGHT = 220;
8423
8533
  var LABEL_ROW_HEIGHT = 16;
8424
8534
  var LABEL_GAP = 3;
8425
8535
  var GAP_RATIO = 0.08;
8426
- var MIN_BAR_GAP = 2;
8536
+ var MIN_BAR_GAP = REP_LEVEL_FLAT_BAR.gapFloor;
8427
8537
  var CHUNK_NOTCH_RATIO = 0.25;
8428
8538
  var CHUNK_NOTCH_MIN_PX = 10;
8429
8539
  var BAR_MAX_WIDTH = 120;
8430
8540
  var LABEL_MIN_BAR_WIDTH = 30;
8431
- var DEFAULT_BAR_RADIUS = 5;
8541
+ var DEFAULT_BAR_RADIUS = REP_LEVEL_FLAT_BAR.radius;
8432
8542
  var MIN_BAR_HEIGHT = 4;
8433
8543
  var FLAT_BAR_FRACTION = 0.5;
8434
8544
  var STUB_HEIGHT = 9;
@@ -9251,7 +9361,8 @@ function DualVelocityStrip({
9251
9361
  className,
9252
9362
  ...props
9253
9363
  }) {
9254
- const resolvedHeight = height ?? (variant === "hero" ? DUAL_HERO_HEIGHT : variant === "compact" ? DUAL_COMPACT_HEIGHT : DUAL_RAIL_HEIGHT);
9364
+ const resolvedVariant = variant === "rail" ? "dual-expanded" : variant;
9365
+ const resolvedHeight = height ?? (resolvedVariant === "hero" ? DUAL_HERO_HEIGHT : resolvedVariant === "compact" ? DUAL_COMPACT_HEIGHT : DUAL_RAIL_HEIGHT);
9255
9366
  const leftDone = streamDone(left);
9256
9367
  const rightDone = streamDone(right);
9257
9368
  const label = `Dual velocity chart, left ${leftDone.length} of ${Math.max(leftDone.length, targetReps ?? leftDone.length)} reps, right ${rightDone.length} of ${Math.max(rightDone.length, targetReps ?? rightDone.length)} reps`;
@@ -9271,8 +9382,9 @@ function DualVelocityStrip({
9271
9382
  label,
9272
9383
  viewProps: props
9273
9384
  };
9274
- if (variant === "rail") return /* @__PURE__ */ jsx(DualVelocityRail, { ...shared, liveRepIndex });
9275
- if (variant === "compact") return /* @__PURE__ */ jsx(DualVelocityCompactStrip, { ...shared });
9385
+ if (resolvedVariant === "dual-expanded")
9386
+ return /* @__PURE__ */ jsx(DualVelocityRail, { ...shared, liveRepIndex });
9387
+ if (resolvedVariant === "compact") return /* @__PURE__ */ jsx(DualVelocityCompactStrip, { ...shared });
9276
9388
  return /* @__PURE__ */ jsx(DualVelocityHero, { ...shared, liveRepIndex });
9277
9389
  }
9278
9390
  function VelocityStrip({
@@ -9885,7 +9997,9 @@ function SetRow(set) {
9885
9997
  }
9886
9998
  );
9887
9999
  }
9888
- var BRAND_PRIMARY = getSemanticColors("dark")["brand-primary"];
10000
+ var t6 = getSemanticColors("dark");
10001
+ var BRAND_PRIMARY = t6["brand-primary"];
10002
+ var ON_BRAND_PRIMARY = t6["on-brand-primary"];
9889
10003
  var INPUT_CLASSNAME = "bg-surface-raised border-hairline-strong text-text-primary";
9890
10004
  var inputStyle = {
9891
10005
  fontSize: 14,
@@ -10030,7 +10144,7 @@ function InputBar({
10030
10144
  fontSize: 13,
10031
10145
  fontWeight: "700",
10032
10146
  fontFamily: "Inter, sans-serif",
10033
- color: "#FFFFFF"
10147
+ color: ON_BRAND_PRIMARY
10034
10148
  },
10035
10149
  children: "Record"
10036
10150
  }
@@ -10050,7 +10164,7 @@ function RestActions({ onAddTime, onSkip }) {
10050
10164
  {
10051
10165
  onPress: onAddTime,
10052
10166
  style: {
10053
- backgroundColor: "rgba(255,255,255,0.06)",
10167
+ backgroundColor: alpha(primitiveColors.white, 0.06),
10054
10168
  paddingVertical: 8,
10055
10169
  paddingHorizontal: 20,
10056
10170
  borderRadius: 8
@@ -10073,7 +10187,7 @@ function RestActions({ onAddTime, onSkip }) {
10073
10187
  {
10074
10188
  onPress: onSkip,
10075
10189
  style: {
10076
- backgroundColor: "rgba(255,121,0,0.12)",
10190
+ backgroundColor: alpha(BRAND_PRIMARY2, 0.12),
10077
10191
  paddingVertical: 8,
10078
10192
  paddingHorizontal: 20,
10079
10193
  borderRadius: 8
@@ -10285,11 +10399,17 @@ function SetsRepsLoad({
10285
10399
  load,
10286
10400
  unit = "lb",
10287
10401
  fontSize,
10402
+ muted = false,
10288
10403
  className,
10289
10404
  ...props
10290
10405
  }) {
10291
- const value = useOnSurfaceColor("primary");
10292
- const sep = useOnSurfaceColor("tertiary");
10406
+ const primary = useOnSurfaceColor("primary");
10407
+ const tertiary = useOnSurfaceColor("tertiary");
10408
+ const secondary = useOnSurfaceColor("secondary");
10409
+ const value = muted ? secondary : primary;
10410
+ const sep = muted ? secondary : tertiary;
10411
+ const weight = muted ? 400 : 600;
10412
+ const times = muted ? TIMES : ` ${TIMES} `;
10293
10413
  return /* @__PURE__ */ jsxs(
10294
10414
  View,
10295
10415
  {
@@ -10299,19 +10419,19 @@ function SetsRepsLoad({
10299
10419
  testID: "sets-reps-load",
10300
10420
  ...props,
10301
10421
  children: [
10302
- /* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: sets }),
10303
- /* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${TIMES} ` }),
10304
- /* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: reps }),
10305
- /* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${AT} ` }),
10306
- /* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: load }),
10307
- /* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${unit}` })
10422
+ /* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, weight, children: sets }),
10423
+ /* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, weight, children: times }),
10424
+ /* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, weight, children: reps }),
10425
+ /* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, weight, children: ` ${AT} ` }),
10426
+ /* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, weight, children: load }),
10427
+ /* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, weight, children: ` ${unit}` })
10308
10428
  ]
10309
10429
  }
10310
10430
  );
10311
10431
  }
10312
10432
  var PULSE_HALF_MS = 950;
10313
10433
  var PULSE_MIN_OPACITY = 0.45;
10314
- var SEGMENTED_BAR_GAP = 5;
10434
+ var SEGMENTED_BAR_GAP = SET_LEVEL_FLAT_BAR.gap;
10315
10435
  function usePulse2(active) {
10316
10436
  const [value] = useState(() => new Animated.Value(0));
10317
10437
  useEffect(() => {
@@ -10339,9 +10459,9 @@ function usePulse2(active) {
10339
10459
  }
10340
10460
  function SegmentedBar({
10341
10461
  segments,
10342
- height = 8,
10462
+ height = SET_LEVEL_FLAT_BAR.height,
10343
10463
  gap = SEGMENTED_BAR_GAP,
10344
- radius = 2,
10464
+ radius = SET_LEVEL_FLAT_BAR.radius,
10345
10465
  marker = null,
10346
10466
  segmentTestID,
10347
10467
  style,
@@ -10702,41 +10822,102 @@ function ExerciseIndicator({ kind, onPress, className, ...props }) {
10702
10822
  }
10703
10823
  return chip;
10704
10824
  }
10705
- function headingLabel(name, sets, reps, load, unit) {
10706
- const loadLabel = typeof load === "number" ? roundWeight(load) : load;
10707
- return `${name}, ${sets}\xD7${reps} @ ${loadLabel} ${unit}`;
10825
+
10826
+ // src/components/custom/Workout/exerciseRowState.ts
10827
+ var ROW_STATE_TOKEN = {
10828
+ hovered: "interactive-hover",
10829
+ selected: "interactive-selected",
10830
+ pressed: "interactive-active"
10831
+ };
10832
+ function exerciseRowStateColor(state, mode = "dark") {
10833
+ return getSemanticColors(mode)[ROW_STATE_TOKEN[state]];
10834
+ }
10835
+ function exerciseLiveColor(mode = "dark") {
10836
+ return getSemanticColors(mode)["status-live"];
10837
+ }
10838
+
10839
+ // src/components/custom/Workout/ExerciseHeading.tsx
10840
+ var DIMMED_OPACITY = 0.55;
10841
+ function prescriptionText(p, unit) {
10842
+ if (p.prescription !== void 0) return p.prescription;
10843
+ if (p.sets === void 0) return void 0;
10844
+ const loadLabel = typeof p.load === "number" ? roundWeight(p.load) : p.load;
10845
+ return `${p.sets}\xD7${p.reps} @ ${loadLabel} ${unit}`;
10846
+ }
10847
+ function exerciseHeadingLabel(p, unit = p.unit ?? "lbs") {
10848
+ const prescription = prescriptionText(p, unit);
10849
+ return prescription ? `${p.name}, ${prescription}` : p.name;
10850
+ }
10851
+ function pressProps(p, unit) {
10852
+ return {
10853
+ onPress: p.onPress,
10854
+ onPressIn: p.onPressIn,
10855
+ onPressOut: p.onPressOut,
10856
+ onHoverIn: p.onHoverIn,
10857
+ onHoverOut: p.onHoverOut,
10858
+ accessibilityRole: "button",
10859
+ accessibilityLabel: exerciseHeadingLabel(p, unit)
10860
+ };
10708
10861
  }
10709
- function ExerciseHeading({
10862
+ function HeadingName({
10710
10863
  name,
10711
- sets,
10712
- reps,
10713
- load,
10714
- unit = "lbs",
10715
- tempo,
10716
- indicator,
10717
- dimmed,
10718
- onPress
10864
+ nameStyle,
10865
+ className
10719
10866
  }) {
10720
- return /* @__PURE__ */ jsxs(View, { style: { opacity: dimmed ? 0.55 : 1 }, testID: "exercise-heading", children: [
10867
+ return (
10868
+ // The row is a button label, not a heading, so `boldLabel` carries the weight and
10869
+ // no header role has to be undone. Size and the Space Grotesk face are pinned.
10870
+ /* @__PURE__ */ jsx(
10871
+ Typography,
10872
+ {
10873
+ variant: "boldLabel",
10874
+ color: nameStyle ? "inherit" : "primary",
10875
+ style: nameStyle,
10876
+ className: cn("font-heading text-sm leading-[normal]", className),
10877
+ testID: "exercise-card-name",
10878
+ children: name
10879
+ }
10880
+ )
10881
+ );
10882
+ }
10883
+ function prescriptionNode(p, unit) {
10884
+ if (p.prescription !== void 0) {
10885
+ return /* @__PURE__ */ jsx(
10886
+ Typography,
10887
+ {
10888
+ variant: "caption",
10889
+ color: "secondary",
10890
+ maxLines: 1,
10891
+ className: "font-sans shrink leading-[normal]",
10892
+ testID: "exercise-card-prescription",
10893
+ children: p.prescription
10894
+ }
10895
+ );
10896
+ }
10897
+ if (p.sets === void 0) return null;
10898
+ return /* @__PURE__ */ jsx(
10899
+ SetsRepsLoad,
10900
+ {
10901
+ sets: p.sets,
10902
+ reps: p.reps,
10903
+ load: p.load,
10904
+ unit,
10905
+ muted: p.mutedPrescription
10906
+ }
10907
+ );
10908
+ }
10909
+ function StackedHeading({ heading, nameStyle }) {
10910
+ const { unit = "lbs", tempo, indicator } = heading;
10911
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
10721
10912
  /* @__PURE__ */ jsxs(
10722
10913
  Pressable,
10723
10914
  {
10724
- onPress,
10725
- accessibilityRole: "button",
10726
- accessibilityLabel: headingLabel(name, sets, reps, load, unit),
10915
+ ...pressProps(heading, unit),
10727
10916
  className: "flex-row items-center",
10728
10917
  style: { gap: 8 },
10729
10918
  testID: "exercise-card-header",
10730
10919
  children: [
10731
- /* @__PURE__ */ jsx(
10732
- Typography,
10733
- {
10734
- variant: "boldLabel",
10735
- className: "font-heading text-sm leading-[normal]",
10736
- testID: "exercise-card-name",
10737
- children: name
10738
- }
10739
- ),
10920
+ /* @__PURE__ */ jsx(HeadingName, { name: heading.name, nameStyle }),
10740
10921
  /* @__PURE__ */ jsx(View, { className: "flex-1" }),
10741
10922
  indicator && /* @__PURE__ */ jsx(ExerciseIndicator, { kind: indicator })
10742
10923
  ]
@@ -10749,7 +10930,7 @@ function ExerciseHeading({
10749
10930
  style: { gap: 8, marginTop: 1 },
10750
10931
  testID: "exercise-card-summary",
10751
10932
  children: [
10752
- /* @__PURE__ */ jsx(SetsRepsLoad, { sets, reps, load, unit }),
10933
+ prescriptionNode(heading, unit),
10753
10934
  /* @__PURE__ */ jsx(View, { className: "flex-1" }),
10754
10935
  tempo && /* @__PURE__ */ jsx(TempoDisplay, { tempo, size: "sm", showLabel: false, showInfo: false })
10755
10936
  ]
@@ -10757,20 +10938,148 @@ function ExerciseHeading({
10757
10938
  )
10758
10939
  ] });
10759
10940
  }
10760
- function ExerciseCardHeading({
10761
- setStates,
10762
- stripHeight = 8,
10763
- dimmed,
10764
- testID = "exercise-card",
10765
- ...heading
10766
- }) {
10941
+ function InlineHeading({ heading, nameStyle }) {
10942
+ const { unit = "lbs", indicator, previousBest } = heading;
10943
+ const Row = heading.pressTarget === "ancestor" ? View : Pressable;
10767
10944
  return /* @__PURE__ */ jsxs(
10768
- View,
10945
+ Row,
10946
+ {
10947
+ ...heading.pressTarget === "ancestor" ? {} : pressProps(heading, unit),
10948
+ className: "flex-row items-center",
10949
+ style: { gap: 8 },
10950
+ testID: "exercise-card-header",
10951
+ children: [
10952
+ /* @__PURE__ */ jsx(HeadingName, { name: heading.name, nameStyle, className: "shrink-0" }),
10953
+ /* @__PURE__ */ jsx(View, { className: "shrink flex-row items-center", testID: "exercise-card-summary", children: prescriptionNode(heading, unit) }),
10954
+ /* @__PURE__ */ jsx(View, { className: "flex-1", style: { minWidth: 8 } }),
10955
+ indicator && /* @__PURE__ */ jsx(ExerciseIndicator, { kind: indicator }),
10956
+ previousBest && /* @__PURE__ */ jsx(
10957
+ Typography,
10958
+ {
10959
+ variant: "caption",
10960
+ color: "tertiary",
10961
+ maxLines: 1,
10962
+ className: "font-sans shrink text-2xs leading-[normal]",
10963
+ testID: "exercise-card-previous-best",
10964
+ children: previousBest
10965
+ }
10966
+ )
10967
+ ]
10968
+ }
10969
+ );
10970
+ }
10971
+ function ExerciseHeading(props) {
10972
+ const mode = useSurfaceMode();
10973
+ const nameStyle = props.isLive ? { color: exerciseLiveColor(mode) } : void 0;
10974
+ return /* @__PURE__ */ jsx(View, { style: { opacity: props.dimmed ? DIMMED_OPACITY : 1 }, testID: "exercise-heading", children: props.layout === "inline" ? /* @__PURE__ */ jsx(InlineHeading, { heading: props, nameStyle }) : /* @__PURE__ */ jsx(StackedHeading, { heading: props, nameStyle }) });
10975
+ }
10976
+ var DENSITY = {
10977
+ rail: {
10978
+ paddingVertical: 9,
10979
+ paddingHorizontal: 12,
10980
+ layout: "stacked",
10981
+ dimOpacity: 0.55,
10982
+ dimByDefault: false,
10983
+ mutedPrescription: false
10984
+ },
10985
+ compact: {
10986
+ paddingVertical: 12,
10987
+ paddingHorizontal: 14,
10988
+ layout: "inline",
10989
+ dimOpacity: 0.55,
10990
+ dimByDefault: false,
10991
+ mutedPrescription: true
10992
+ },
10993
+ upcoming: {
10994
+ paddingVertical: 12,
10995
+ paddingHorizontal: 14,
10996
+ layout: "inline",
10997
+ dimOpacity: 0.6,
10998
+ dimByDefault: true,
10999
+ mutedPrescription: true
11000
+ }
11001
+ };
11002
+ function useRowInteraction() {
11003
+ const { hovered: rowHovered, hoverProps } = useHoverState();
11004
+ const [headingHovered, setHeadingHovered] = useState(false);
11005
+ const [pressed, setPressed] = useState(false);
11006
+ return {
11007
+ hoverProps,
11008
+ pressed,
11009
+ hovered: rowHovered || headingHovered,
11010
+ headingHandlers: {
11011
+ onHoverIn: () => setHeadingHovered(true),
11012
+ onHoverOut: () => setHeadingHovered(false),
11013
+ onPressIn: () => setPressed(true),
11014
+ onPressOut: () => setPressed(false)
11015
+ }
11016
+ };
11017
+ }
11018
+ function rowWash(mode, state) {
11019
+ if (state.pressed) return exerciseRowStateColor("pressed", mode);
11020
+ if (state.isSelected) return exerciseRowStateColor("selected", mode);
11021
+ if (state.hovered) return exerciseRowStateColor("hovered", mode);
11022
+ return void 0;
11023
+ }
11024
+ function prescriptionProps(p) {
11025
+ const base = { name: p.name };
11026
+ if (p.prescription !== void 0) return { ...base, prescription: p.prescription };
11027
+ if (p.sets === void 0) return base;
11028
+ return { ...base, sets: p.sets, reps: p.reps, load: p.load };
11029
+ }
11030
+ function ExerciseCardHeading(props) {
11031
+ const {
11032
+ density = "rail",
11033
+ setStates = [],
11034
+ stripHeight = 8,
11035
+ dimmed,
11036
+ isSelected = false,
11037
+ isLive = false,
11038
+ testID = "exercise-card",
11039
+ style
11040
+ } = props;
11041
+ const spec = DENSITY[density];
11042
+ const { hoverProps, pressed, hovered, headingHandlers } = useRowInteraction();
11043
+ const wash = rowWash(useSurfaceMode(), { pressed, isSelected, hovered });
11044
+ const rowIsButton = spec.layout === "inline";
11045
+ const Root = rowIsButton ? Pressable : View;
11046
+ const rootPress = rowIsButton ? {
11047
+ ...headingHandlers,
11048
+ onPress: props.onPress,
11049
+ accessibilityRole: "button",
11050
+ accessibilityLabel: exerciseHeadingLabel(props)
11051
+ } : {};
11052
+ return /* @__PURE__ */ jsxs(
11053
+ Root,
10769
11054
  {
10770
- style: { paddingVertical: 9, paddingHorizontal: 12, opacity: dimmed ? 0.55 : 1 },
11055
+ ...hoverProps,
11056
+ ...rootPress,
11057
+ style: [
11058
+ {
11059
+ paddingVertical: spec.paddingVertical,
11060
+ paddingHorizontal: spec.paddingHorizontal,
11061
+ opacity: dimmed ?? spec.dimByDefault ? spec.dimOpacity : 1
11062
+ },
11063
+ wash ? { backgroundColor: wash } : null,
11064
+ style
11065
+ ],
10771
11066
  testID,
10772
11067
  children: [
10773
- /* @__PURE__ */ jsx(ExerciseHeading, { ...heading }),
11068
+ /* @__PURE__ */ jsx(
11069
+ ExerciseHeading,
11070
+ {
11071
+ ...prescriptionProps(props),
11072
+ ...rowIsButton ? { pressTarget: "ancestor" } : headingHandlers,
11073
+ unit: props.unit,
11074
+ tempo: props.tempo,
11075
+ indicator: props.indicator,
11076
+ previousBest: props.previousBest,
11077
+ onPress: rowIsButton ? void 0 : props.onPress,
11078
+ layout: spec.layout,
11079
+ mutedPrescription: spec.mutedPrescription,
11080
+ isLive
11081
+ }
11082
+ ),
10774
11083
  setStates.length > 0 && /* @__PURE__ */ jsx(View, { style: { marginTop: 7 }, testID: "exercise-card-strip", children: /* @__PURE__ */ jsx(SetStrip, { sets: setStates, height: stripHeight }) })
10775
11084
  ]
10776
11085
  }
@@ -10864,103 +11173,58 @@ function getSupersetMargin(position) {
10864
11173
  }
10865
11174
  return {};
10866
11175
  }
10867
- function formatSummary(summary) {
10868
- if (!summary) return "";
10869
- return `${summary.sets}\xD7${summary.reps} @ ${roundWeight(summary.weight)} ${summary.unit}`;
11176
+ function supersetChrome(position) {
11177
+ return { ...getSupersetBorderRadius(position), ...getSupersetMargin(position) };
10870
11178
  }
10871
- function formatAccessibilityLabel(name, summary, prescription) {
10872
- if (summary) return `${name}, ${formatSummary(summary)}`;
10873
- if (prescription) return `${name}, ${prescription}`;
10874
- return name;
11179
+ function deriveCollapsedSetStates(setVelocities, totalPlannedSets, plannedReps2) {
11180
+ const done = (setVelocities ?? []).map(
11181
+ (velocities) => ({ status: "done", velocities })
11182
+ );
11183
+ const remaining = Math.max(0, (totalPlannedSets ?? 0) - done.length);
11184
+ return [
11185
+ ...done,
11186
+ ...Array.from(
11187
+ { length: remaining },
11188
+ () => ({ status: "todo", planned: plannedReps2 })
11189
+ )
11190
+ ];
10875
11191
  }
10876
11192
  function CollapsedCard({
10877
11193
  name,
10878
11194
  onToggle,
10879
11195
  summary,
10880
11196
  isPR,
11197
+ indicator,
10881
11198
  setVelocities,
10882
- velocityZones,
11199
+ setStates,
10883
11200
  totalPlannedSets,
10884
- supersetPosition
11201
+ stripHeight,
11202
+ supersetPosition,
11203
+ isSelected,
11204
+ isLive
10885
11205
  }) {
10886
- const [pressed, setPressed] = useState(false);
10887
- const completedSets = setVelocities?.length ?? 0;
10888
- const remaining = Math.max(0, (totalPlannedSets ?? 0) - completedSets);
10889
- const borderRadius = getSupersetBorderRadius(supersetPosition);
10890
- const supersetMargin = getSupersetMargin(supersetPosition);
10891
- return /* @__PURE__ */ jsx(
10892
- Pressable,
11206
+ const plannedReps2 = typeof summary?.reps === "number" ? summary.reps : 0;
11207
+ const row = {
11208
+ density: "compact",
11209
+ name,
11210
+ indicator: indicator ?? (isPR ? "pr" : void 0),
11211
+ setStates: setStates ?? deriveCollapsedSetStates(setVelocities, totalPlannedSets, plannedReps2),
11212
+ stripHeight,
11213
+ isSelected,
11214
+ isLive,
11215
+ onPress: onToggle,
11216
+ style: supersetChrome(supersetPosition)
11217
+ };
11218
+ return summary ? /* @__PURE__ */ jsx(
11219
+ ExerciseCardHeading,
10893
11220
  {
10894
- onPress: onToggle,
10895
- onPressIn: () => setPressed(true),
10896
- onPressOut: () => setPressed(false),
10897
- accessibilityRole: "button",
10898
- accessibilityLabel: formatAccessibilityLabel(name, summary, void 0),
10899
- testID: "exercise-card",
10900
- children: /* @__PURE__ */ jsxs(
10901
- View,
10902
- {
10903
- className: pressed ? "bg-surface-raised" : void 0,
10904
- style: {
10905
- padding: 12,
10906
- paddingHorizontal: 14,
10907
- cursor: "pointer",
10908
- ...borderRadius,
10909
- ...supersetMargin
10910
- },
10911
- children: [
10912
- /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", testID: "exercise-card-header", children: [
10913
- /* @__PURE__ */ jsx(
10914
- Typography,
10915
- {
10916
- variant: "h6",
10917
- color: "primary",
10918
- className: "text-sm font-bold leading-[normal]",
10919
- testID: "exercise-card-name",
10920
- children: name
10921
- }
10922
- ),
10923
- /* @__PURE__ */ jsx(View, { className: "flex-1" }),
10924
- summary && /* The demo's "body" face is Inter, which is the library's `font-sans`
10925
- (the mapping B1 established for PrBadge), not Typography's `font-body`. */
10926
- /* @__PURE__ */ jsx(
10927
- Typography,
10928
- {
10929
- variant: "caption",
10930
- color: "secondary",
10931
- className: "font-sans mr-2 leading-[normal]",
10932
- testID: "exercise-card-summary",
10933
- children: formatSummary(summary)
10934
- }
10935
- ),
10936
- isPR && /* @__PURE__ */ jsx(View, { style: { marginLeft: 4 }, children: /* @__PURE__ */ jsx(PrBadge, { type: "e1rm", compact: true, animate: false }) })
10937
- ] }),
10938
- (completedSets > 0 || remaining > 0) && /* @__PURE__ */ jsxs(View, { className: "flex-row", style: { marginTop: 6, gap: 4 }, testID: "exercise-card-strips", children: [
10939
- setVelocities?.map((velocities, i) => /* @__PURE__ */ jsx(
10940
- VelocityStrip,
10941
- {
10942
- velocities,
10943
- zones: velocityZones,
10944
- variant: "compact",
10945
- height: 8,
10946
- hideBaseline: true,
10947
- testID: `exercise-card-velocity-strip-${i}`
10948
- },
10949
- i
10950
- )),
10951
- Array.from({ length: remaining }, (_, i) => /* @__PURE__ */ jsx(
10952
- PlaceholderStrip,
10953
- {
10954
- testID: `exercise-card-placeholder-${i}`
10955
- },
10956
- `placeholder-${i}`
10957
- ))
10958
- ] })
10959
- ]
10960
- }
10961
- )
11221
+ ...row,
11222
+ sets: summary.sets,
11223
+ reps: summary.reps,
11224
+ load: summary.weight,
11225
+ unit: summary.unit
10962
11226
  }
10963
- );
11227
+ ) : /* @__PURE__ */ jsx(ExerciseCardHeading, { ...row });
10964
11228
  }
10965
11229
  function deriveHeaderSetStates(sets) {
10966
11230
  return sets.map((set) => {
@@ -10985,10 +11249,9 @@ function ExpandedCard({
10985
11249
  setStates,
10986
11250
  stripHeight = 8,
10987
11251
  velocityZones,
10988
- supersetPosition
11252
+ supersetPosition,
11253
+ isLive
10989
11254
  }) {
10990
- const borderRadius = getSupersetBorderRadius(supersetPosition);
10991
- const supersetMargin = getSupersetMargin(supersetPosition);
10992
11255
  const unit = summary?.unit ?? sets?.[0]?.unit ?? "lbs";
10993
11256
  const headerStates = setStates ?? (sets ? deriveHeaderSetStates(sets) : []);
10994
11257
  const headerIndicator = indicator ?? (isPR ? "pr" : void 0);
@@ -10996,11 +11259,7 @@ function ExpandedCard({
10996
11259
  View,
10997
11260
  {
10998
11261
  className: "bg-surface-elevated border-hairline",
10999
- style: {
11000
- borderWidth: 1,
11001
- ...borderRadius,
11002
- ...supersetMargin
11003
- },
11262
+ style: { borderWidth: 1, ...supersetChrome(supersetPosition) },
11004
11263
  testID: "exercise-card",
11005
11264
  children: [
11006
11265
  /* @__PURE__ */ jsx(
@@ -11015,6 +11274,7 @@ function ExpandedCard({
11015
11274
  indicator: headerIndicator,
11016
11275
  setStates: headerStates,
11017
11276
  stripHeight,
11277
+ isLive,
11018
11278
  onPress: onToggle,
11019
11279
  testID: "exercise-card-heading"
11020
11280
  }
@@ -11042,62 +11302,21 @@ function UpcomingCard({
11042
11302
  name,
11043
11303
  prescription,
11044
11304
  previousBest,
11305
+ indicator,
11045
11306
  supersetPosition,
11307
+ isSelected,
11046
11308
  onToggle
11047
11309
  }) {
11048
- const borderRadius = getSupersetBorderRadius(supersetPosition);
11049
- const supersetMargin = getSupersetMargin(supersetPosition);
11050
- return /* @__PURE__ */ jsx(Pressable, { onPress: onToggle, accessibilityRole: "button", children: /* @__PURE__ */ jsx(
11051
- View,
11052
- {
11053
- style: {
11054
- opacity: 0.6,
11055
- padding: 12,
11056
- paddingHorizontal: 14,
11057
- ...borderRadius,
11058
- ...supersetMargin
11059
- },
11060
- accessibilityLabel: formatAccessibilityLabel(name, void 0, prescription),
11061
- testID: "exercise-card",
11062
- children: /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", children: [
11063
- /* @__PURE__ */ jsx(
11064
- Typography,
11065
- {
11066
- variant: "h6",
11067
- color: "primary",
11068
- className: "shrink-0 text-sm font-bold leading-[normal]",
11069
- testID: "exercise-card-name",
11070
- children: name
11071
- }
11072
- ),
11073
- prescription && /* @__PURE__ */ jsx(
11074
- Typography,
11075
- {
11076
- variant: "caption",
11077
- color: "secondary",
11078
- maxLines: 1,
11079
- className: "font-sans shrink ml-2 leading-[normal]",
11080
- testID: "exercise-card-prescription",
11081
- children: prescription
11082
- }
11083
- ),
11084
- /* @__PURE__ */ jsx(View, { className: "flex-1", style: { minWidth: 8 } }),
11085
- previousBest && /* 11px is off the type scale; `2xs` (10px) is the step below, as B2's
11086
- WorkoutCard date took for the same size. */
11087
- /* @__PURE__ */ jsx(
11088
- Typography,
11089
- {
11090
- variant: "caption",
11091
- color: "tertiary",
11092
- maxLines: 1,
11093
- className: "font-sans shrink text-2xs leading-[normal]",
11094
- testID: "exercise-card-previous-best",
11095
- children: previousBest
11096
- }
11097
- )
11098
- ] })
11099
- }
11100
- ) });
11310
+ const row = {
11311
+ density: "upcoming",
11312
+ name,
11313
+ previousBest,
11314
+ indicator,
11315
+ isSelected,
11316
+ onPress: onToggle,
11317
+ style: supersetChrome(supersetPosition)
11318
+ };
11319
+ return prescription !== void 0 ? /* @__PURE__ */ jsx(ExerciseCardHeading, { ...row, prescription }) : /* @__PURE__ */ jsx(ExerciseCardHeading, { ...row });
11101
11320
  }
11102
11321
  function ExerciseCard({
11103
11322
  upcoming,
@@ -11705,7 +11924,7 @@ var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY3, BRAND_PRIMARY_LIGHT];
11705
11924
  function heatmapColor(percentage) {
11706
11925
  const clamped = Math.max(0, Math.min(100, percentage));
11707
11926
  const opacity = 0.12 + clamped / 100 * 0.78;
11708
- return `rgba(255,121,0,${opacity.toFixed(3)})`;
11927
+ return alpha(BRAND_PRIMARY3, opacity);
11709
11928
  }
11710
11929
  function MesoCard({
11711
11930
  name,
@@ -12048,12 +12267,13 @@ function PrHistoryModal({
12048
12267
  }
12049
12268
  );
12050
12269
  }
12051
- var t6 = getSemanticColors("dark");
12052
- var BRAND_PRIMARY5 = t6["brand-primary"];
12053
- var BRAND_PRIMARY_SUBTLE = "rgba(255,121,0,0.12)";
12054
- var STATUS_SUCCESS2 = t6["status-success"];
12055
- var STATUS_WARNING2 = t6["status-warning"];
12056
- var STATUS_ERROR2 = t6["status-error"];
12270
+ var t7 = getSemanticColors("dark");
12271
+ var BRAND_PRIMARY5 = t7["brand-primary"];
12272
+ var ON_BRAND_PRIMARY2 = t7["on-brand-primary"];
12273
+ var BRAND_PRIMARY_SUBTLE = alpha(BRAND_PRIMARY5, 0.12);
12274
+ var STATUS_SUCCESS2 = t7["status-success"];
12275
+ var STATUS_WARNING2 = t7["status-warning"];
12276
+ var STATUS_ERROR2 = t7["status-error"];
12057
12277
  var EMOJI_SETS = {
12058
12278
  sleep: ["\u{1F634}", "\u{1F610}", "\u{1F642}", "\u{1F60A}", "\u{1F929}"],
12059
12279
  soreness: ["\u{1F635}", "\u{1F623}", "\u{1F610}", "\u{1F642}", "\u{1F4AA}"],
@@ -12250,7 +12470,7 @@ function ReadinessCheck({
12250
12470
  fontSize: 13,
12251
12471
  fontWeight: "700",
12252
12472
  fontFamily: "Inter, sans-serif",
12253
- color: "#FFFFFF"
12473
+ color: ON_BRAND_PRIMARY2
12254
12474
  },
12255
12475
  children: "Start Workout"
12256
12476
  }
@@ -12259,20 +12479,20 @@ function ReadinessCheck({
12259
12479
  )
12260
12480
  ] }) });
12261
12481
  }
12262
- var t7 = getSemanticColors("dark");
12263
- var BRAND_PRIMARY6 = t7["brand-primary"];
12482
+ var t8 = getSemanticColors("dark");
12483
+ var BRAND_PRIMARY6 = t8["brand-primary"];
12264
12484
  var BRAND_PRIMARY_DARK2 = MESO_ACCENT_GRADIENT_DARK;
12265
12485
  var BRAND_PRIMARY_LIGHT2 = MESO_ACCENT_GRADIENT_LIGHT;
12266
- var SUCCESS = t7["status-success"];
12267
- var WARNING = t7["status-warning"];
12268
- var ERROR = t7["status-error"];
12486
+ var SUCCESS = t8["status-success"];
12487
+ var WARNING = t8["status-warning"];
12488
+ var ERROR = t8["status-error"];
12269
12489
  var ACCENT_STOPS2 = [BRAND_PRIMARY_DARK2, BRAND_PRIMARY6, BRAND_PRIMARY_LIGHT2];
12270
12490
  var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
12271
- 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%)";
12491
+ var GAUGE_GRADIENT = `linear-gradient(90deg, ${alpha(SUCCESS, 0.25)} 0%, ${alpha(WARNING, 0.25)} 50%, ${alpha(ERROR, 0.25)} 100%)`;
12272
12492
  var STATUS_VARIANTS = {
12273
- success: { bg: "rgba(46,213,115,0.15)", border: "rgba(46,213,115,0.3)", text: SUCCESS },
12274
- warning: { bg: "rgba(249,180,21,0.15)", border: "rgba(249,180,21,0.3)", text: WARNING },
12275
- error: { bg: "rgba(209,67,67,0.15)", border: "rgba(209,67,67,0.25)", text: ERROR }
12493
+ success: { bg: alpha(SUCCESS, 0.15), border: alpha(SUCCESS, 0.3), text: SUCCESS },
12494
+ warning: { bg: alpha(WARNING, 0.15), border: alpha(WARNING, 0.3), text: WARNING },
12495
+ error: { bg: alpha(ERROR, 0.15), border: alpha(ERROR, 0.25), text: ERROR }
12276
12496
  };
12277
12497
  function clamp01(value) {
12278
12498
  if (!Number.isFinite(value)) return 0;
@@ -12425,7 +12645,7 @@ function Gauge({ gauge }) {
12425
12645
  bottom: 0,
12426
12646
  width: 1,
12427
12647
  marginLeft: -0.5,
12428
- backgroundColor: "rgba(255,255,255,0.3)"
12648
+ backgroundColor: alpha(primitiveColors.white, 0.3)
12429
12649
  },
12430
12650
  testID: "meso-status-card-gauge-center"
12431
12651
  }
@@ -12534,9 +12754,9 @@ function MesoStatusCard({
12534
12754
  View,
12535
12755
  {
12536
12756
  style: {
12537
- backgroundColor: "rgba(249,180,21,0.06)",
12757
+ backgroundColor: alpha(WARNING, 0.06),
12538
12758
  borderWidth: 1,
12539
- borderColor: "rgba(249,180,21,0.15)",
12759
+ borderColor: alpha(WARNING, 0.15),
12540
12760
  borderRadius: 8,
12541
12761
  paddingVertical: 10,
12542
12762
  paddingHorizontal: 12
@@ -12562,9 +12782,9 @@ function MesoStatusCard({
12562
12782
  className: "flex-row items-center",
12563
12783
  style: {
12564
12784
  gap: 8,
12565
- backgroundColor: "rgba(46,213,115,0.06)",
12785
+ backgroundColor: alpha(SUCCESS, 0.06),
12566
12786
  borderWidth: 1,
12567
- borderColor: "rgba(46,213,115,0.2)",
12787
+ borderColor: alpha(SUCCESS, 0.2),
12568
12788
  borderRadius: 8,
12569
12789
  paddingVertical: 10,
12570
12790
  paddingHorizontal: 12
@@ -12599,16 +12819,16 @@ var PROJECTION_LINE_COLOR = resolveColor("text-tertiary");
12599
12819
  var STATUS_SUCCESS3 = sem["status-success"];
12600
12820
  var STATUS_ERROR3 = sem["status-error"];
12601
12821
  var STATUS_WARNING3 = sem["status-warning"];
12602
- var GRID_LINE = "rgba(255,255,255,0.06)";
12603
- var SUCCESS_PILL_BG = "rgba(46,213,115,0.10)";
12604
- var SUCCESS_PILL_BORDER = "rgba(46,213,115,0.20)";
12605
- var ERROR_PILL_BG = "rgba(209,67,67,0.10)";
12606
- var ERROR_PILL_BORDER = "rgba(209,67,67,0.20)";
12822
+ var GRID_LINE = alpha(primitiveColors.white, 0.06);
12823
+ var SUCCESS_PILL_BG = alpha(STATUS_SUCCESS3, 0.1);
12824
+ var SUCCESS_PILL_BORDER = alpha(STATUS_SUCCESS3, 0.2);
12825
+ var ERROR_PILL_BG = alpha(STATUS_ERROR3, 0.1);
12826
+ var ERROR_PILL_BORDER = alpha(STATUS_ERROR3, 0.2);
12607
12827
  var PLOT_LEFT = 26;
12608
12828
  var TOOLTIP_WIDTH = 124;
12609
12829
  function timeOf(dateStr) {
12610
- const t18 = Date.parse(dateStr);
12611
- return Number.isNaN(t18) ? 0 : t18;
12830
+ const t19 = Date.parse(dateStr);
12831
+ return Number.isNaN(t19) ? 0 : t19;
12612
12832
  }
12613
12833
  function formatValue(value) {
12614
12834
  return `${Math.round(value)}`;
@@ -12848,7 +13068,7 @@ function StrengthTrendChart({
12848
13068
  height,
12849
13069
  borderLeftWidth: 1,
12850
13070
  borderStyle: "dashed",
12851
- borderLeftColor: "rgba(255,255,255,0.10)"
13071
+ borderLeftColor: alpha(primitiveColors.white, 0.1)
12852
13072
  }
12853
13073
  },
12854
13074
  `boundary-${i}`
@@ -13116,14 +13336,14 @@ function StrengthTrendChart({
13116
13336
  )
13117
13337
  ] });
13118
13338
  }
13119
- var t8 = getSemanticColors("dark");
13120
- var STATUS_SUCCESS4 = t8["status-success"];
13121
- var STATUS_WARNING4 = t8["status-warning"];
13122
- var STATUS_INFO = t8["status-info"];
13339
+ var t9 = getSemanticColors("dark");
13340
+ var STATUS_SUCCESS4 = t9["status-success"];
13341
+ var STATUS_WARNING4 = t9["status-warning"];
13342
+ var STATUS_INFO = t9["status-info"];
13123
13343
  var DOT_BORDER = "#F3F4F6";
13124
- var BAND_FILL = "rgba(46,213,115,0.1)";
13125
- var BAND_EDGE = "rgba(46,213,115,0.45)";
13126
- var PROJECTION_FILL = "rgba(46,213,115,0.05)";
13344
+ var BAND_FILL = alpha(STATUS_SUCCESS4, 0.1);
13345
+ var BAND_EDGE = alpha(STATUS_SUCCESS4, 0.45);
13346
+ var PROJECTION_FILL = alpha(STATUS_SUCCESS4, 0.05);
13127
13347
  var PADDING_LEFT = 28;
13128
13348
  var PADDING_RIGHT = 10;
13129
13349
  var PADDING_TOP = 8;
@@ -13162,8 +13382,8 @@ function interpEdge(pixels, x, key) {
13162
13382
  const a = pixels[i];
13163
13383
  const b = pixels[i + 1];
13164
13384
  if (x >= a.x && x <= b.x) {
13165
- const t18 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
13166
- return a[key] + t18 * (b[key] - a[key]);
13385
+ const t19 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
13386
+ return a[key] + t19 * (b[key] - a[key]);
13167
13387
  }
13168
13388
  }
13169
13389
  return pixels[pixels.length - 1][key];
@@ -13528,10 +13748,10 @@ function CapacityBandChart({
13528
13748
  }
13529
13749
  );
13530
13750
  }
13531
- var t9 = getSemanticColors("dark");
13751
+ var t10 = getSemanticColors("dark");
13532
13752
  var DEFAULT_TRACK_COLOR = greyRamp[800];
13533
13753
  var DEFAULT_MARKER_COLOR2 = primitiveColors.white;
13534
- var TICK_COLOR = t9["text-tertiary"];
13754
+ var TICK_COLOR = t10["text-tertiary"];
13535
13755
  var ZONE_SIZES = {
13536
13756
  default: {
13537
13757
  trackHeight: 14,
@@ -13714,7 +13934,7 @@ function ZoneTrack({
13714
13934
  ),
13715
13935
  ticks?.map((tick, i) => {
13716
13936
  const emphasized = tick.emphasized === true;
13717
- const lineColor = tick.color ?? (emphasized ? t9["brand-primary"] : TICK_COLOR);
13937
+ const lineColor = tick.color ?? (emphasized ? t10["brand-primary"] : TICK_COLOR);
13718
13938
  const lineWidth = emphasized ? s.tickLineEmphasized : s.tickLineNormal;
13719
13939
  return /* @__PURE__ */ jsx(
13720
13940
  View,
@@ -13745,7 +13965,7 @@ function ZoneTrack({
13745
13965
  if (tick.label == null) return null;
13746
13966
  const emphasized = tick.emphasized === true;
13747
13967
  if (!showTickLabel(i, emphasized)) return null;
13748
- const labelColor = tick.color ?? (emphasized ? t9["brand-primary"] : TICK_COLOR);
13968
+ const labelColor = tick.color ?? (emphasized ? t10["brand-primary"] : TICK_COLOR);
13749
13969
  const labelNode = /* @__PURE__ */ jsx(
13750
13970
  Text,
13751
13971
  {
@@ -13977,7 +14197,7 @@ function StatusPill2({ status, label, className, ...props }) {
13977
14197
  }
13978
14198
  );
13979
14199
  }
13980
- var t10 = getSemanticColors("dark");
14200
+ var t11 = getSemanticColors("dark");
13981
14201
  var categoryToken = {
13982
14202
  productive: null,
13983
14203
  threshold: "status-warning",
@@ -13990,7 +14210,7 @@ var floodOpacity = {
13990
14210
  };
13991
14211
  function liveAuraColor(category) {
13992
14212
  const token = categoryToken[category];
13993
- return token ? t10[token] : null;
14213
+ return token ? t11[token] : null;
13994
14214
  }
13995
14215
  function LiveAuraFrame({
13996
14216
  category,
@@ -14019,9 +14239,9 @@ function LiveAuraFrame({
14019
14239
  position: "relative",
14020
14240
  overflow: "hidden",
14021
14241
  borderRadius: 10,
14022
- backgroundColor: t10["background-base"],
14242
+ backgroundColor: t11["background-base"],
14023
14243
  borderWidth: 1,
14024
- borderColor: t10["hairline-default"]
14244
+ borderColor: t11["hairline-default"]
14025
14245
  },
14026
14246
  style
14027
14247
  ],
@@ -14128,14 +14348,14 @@ function panelBodySplit(bodyHeight, layout) {
14128
14348
  }
14129
14349
 
14130
14350
  // src/components/custom/Fatigue/fatigue-tokens.ts
14131
- var t11 = getSemanticColors("dark");
14351
+ var t12 = getSemanticColors("dark");
14132
14352
  var FONT_HEAD = '"Space Grotesk", sans-serif';
14133
14353
  var FONT_UI = '"Nunito Sans", sans-serif';
14134
14354
  var FONT_MONO = "monospace";
14135
14355
  var TONE_COLOR = {
14136
- ok: t11["status-success"],
14137
- warn: t11["status-warning"],
14138
- alarm: t11["status-error"]
14356
+ ok: t12["status-success"],
14357
+ warn: t12["status-warning"],
14358
+ alarm: t12["status-error"]
14139
14359
  };
14140
14360
  var STATE_LABEL = {
14141
14361
  good: "Good",
@@ -14194,13 +14414,13 @@ function auraForVerdict(state) {
14194
14414
  }
14195
14415
 
14196
14416
  // src/components/custom/Fatigue/VerdictHero.tsx
14197
- var t12 = getSemanticColors("dark");
14417
+ var t13 = getSemanticColors("dark");
14198
14418
  function formatRpe(rpe) {
14199
14419
  if (rpe == null) return "\u2014";
14200
14420
  return (Math.round(rpe * 2) / 2).toFixed(1);
14201
14421
  }
14202
14422
  function VerdictHero({ rpe, verdict }) {
14203
- const tone = verdict ? TONE_COLOR[verdict.tone] : t12["text-tertiary"];
14423
+ const tone = verdict ? TONE_COLOR[verdict.tone] : t13["text-tertiary"];
14204
14424
  const word = verdict ? STATE_LABEL[verdict.state] : "Warming up";
14205
14425
  return /* @__PURE__ */ jsxs(View, { style: { gap: 6 }, testID: "verdict-hero", children: [
14206
14426
  /* @__PURE__ */ jsx(
@@ -14210,7 +14430,7 @@ function VerdictHero({ rpe, verdict }) {
14210
14430
  fontSize: 9,
14211
14431
  letterSpacing: 1.5,
14212
14432
  fontFamily: FONT_MONO,
14213
- color: t12["text-tertiary"]
14433
+ color: t13["text-tertiary"]
14214
14434
  },
14215
14435
  children: "FATIGUE"
14216
14436
  }
@@ -14249,7 +14469,7 @@ function VerdictHero({ rpe, verdict }) {
14249
14469
  ] })
14250
14470
  ] });
14251
14471
  }
14252
- var t13 = getSemanticColors("dark");
14472
+ var t14 = getSemanticColors("dark");
14253
14473
  var TONE_VARIANT = {
14254
14474
  ok: "success",
14255
14475
  warn: "warning",
@@ -14277,7 +14497,7 @@ function Light({
14277
14497
  fontSize: 9,
14278
14498
  letterSpacing: 0.6,
14279
14499
  fontFamily: FONT_MONO,
14280
- color: t13["text-secondary"]
14500
+ color: t14["text-secondary"]
14281
14501
  },
14282
14502
  children: label
14283
14503
  }
@@ -14386,14 +14606,14 @@ function RomProgressionChart({
14386
14606
  }
14387
14607
 
14388
14608
  // src/components/custom/Fatigue/tempo-pacing.ts
14389
- var t14 = getSemanticColors("dark");
14609
+ var t15 = getSemanticColors("dark");
14390
14610
  var ON_TARGET_MS2 = 100;
14391
14611
  function phaseFillFraction(elapsedMs, targetMs) {
14392
14612
  if (targetMs == null || targetMs <= 0) return 1;
14393
14613
  return Math.min(1, Math.max(0, elapsedMs / targetMs));
14394
14614
  }
14395
14615
  function pacingTone(elapsedMs, targetMs) {
14396
- if (targetMs == null || targetMs <= 0) return t14["text-primary"];
14616
+ if (targetMs == null || targetMs <= 0) return t15["text-primary"];
14397
14617
  const remainingMs = targetMs - elapsedMs;
14398
14618
  if (remainingMs > ON_TARGET_MS2) return PACING_TONE.ahead;
14399
14619
  if (remainingMs >= -ON_TARGET_MS2) return PACING_TONE.onPace;
@@ -14409,11 +14629,11 @@ function prescribedSegments(tempo) {
14409
14629
  ["hold", pauseTop]
14410
14630
  ];
14411
14631
  const out = [];
14412
- let t18 = 0;
14632
+ let t19 = 0;
14413
14633
  for (const [phase, seconds] of order) {
14414
14634
  const ms = seconds * 1e3;
14415
- if (ms > 0) out.push({ phase, startMs: t18, endMs: t18 + ms });
14416
- t18 += ms;
14635
+ if (ms > 0) out.push({ phase, startMs: t19, endMs: t19 + ms });
14636
+ t19 += ms;
14417
14637
  }
14418
14638
  return out;
14419
14639
  }
@@ -14437,7 +14657,7 @@ function phaseTargetsMs(phases, tempo) {
14437
14657
  }
14438
14658
 
14439
14659
  // src/components/custom/Fatigue/GhostBand.tsx
14440
- var t15 = getSemanticColors("dark");
14660
+ var t16 = getSemanticColors("dark");
14441
14661
  var BAND_H = 16;
14442
14662
  var BAND_GAP = 4;
14443
14663
  var PHASE_LABEL = {
@@ -14457,7 +14677,7 @@ function GhostBand({
14457
14677
  top,
14458
14678
  height = BAND_H,
14459
14679
  showLabels = false,
14460
- labelColor = t15["text-primary"],
14680
+ labelColor = t16["text-primary"],
14461
14681
  targetTempoSeconds = null,
14462
14682
  prescribed = false
14463
14683
  }) {
@@ -14572,8 +14792,8 @@ function GhostBand({
14572
14792
  ] })
14573
14793
  ] });
14574
14794
  }
14575
- var t16 = getSemanticColors("dark");
14576
- var PARCH = t16["text-primary"];
14795
+ var t17 = getSemanticColors("dark");
14796
+ var PARCH = t17["text-primary"];
14577
14797
  function smoothPath(pts) {
14578
14798
  if (pts.length < 2) return pts.length ? `M ${pts[0][0]} ${pts[0][1]}` : "";
14579
14799
  let d = `M ${pts[0][0].toFixed(1)} ${pts[0][1].toFixed(1)}`;
@@ -14719,7 +14939,7 @@ function GhostSpark({
14719
14939
  var PAD = 18;
14720
14940
  var GHOST_GUTTER = 4;
14721
14941
  function LiveFatigueCard({ model, width = 318, height }) {
14722
- const t18 = getSemanticColors(useSurfaceMode());
14942
+ const t19 = getSemanticColors(useSurfaceMode());
14723
14943
  const chartW = width - PAD * 2 - GHOST_GUTTER * 2;
14724
14944
  const chartH = cardChartHeight(height);
14725
14945
  return /* @__PURE__ */ jsxs(
@@ -14733,8 +14953,8 @@ function LiveFatigueCard({ model, width = 318, height }) {
14733
14953
  borderRadius: 14,
14734
14954
  padding: PAD,
14735
14955
  borderWidth: 1,
14736
- borderColor: t18["hairline-default"],
14737
- ...barPaper(t18["surface-base"])
14956
+ borderColor: t19["hairline-default"],
14957
+ ...barPaper(t19["surface-base"])
14738
14958
  },
14739
14959
  children: [
14740
14960
  /* @__PURE__ */ jsxs(View, { style: { gap: 12 }, children: [
@@ -14837,7 +15057,7 @@ function LiveFatiguePanel({
14837
15057
  }
14838
15058
  );
14839
15059
  }
14840
- var t17 = getSemanticColors("dark");
15060
+ var t18 = getSemanticColors("dark");
14841
15061
  function phaseAt(segments, ms) {
14842
15062
  const hit = segments.find((s) => ms >= s.startMs && ms < s.endMs);
14843
15063
  return hit ? hit.phase : null;
@@ -14902,7 +15122,7 @@ function DualGhostSpark({
14902
15122
  cur,
14903
15123
  current: cur ? toPts(cur) : [],
14904
15124
  ghosts: curves.slice(0, -1).map(toPts),
14905
- tint: cur ? ghostLineColor(cur.tempoDeviation, cur.grindSignature) : t17["text-tertiary"]
15125
+ tint: cur ? ghostLineColor(cur.tempoDeviation, cur.grindSignature) : t18["text-tertiary"]
14906
15126
  };
14907
15127
  };
14908
15128
  const up = wing(left);
@@ -14936,7 +15156,7 @@ function DualGhostSpark({
14936
15156
  x,
14937
15157
  top: bandTop,
14938
15158
  showLabels: true,
14939
- labelColor: alpha(t17["text-primary"], 0.92),
15159
+ labelColor: alpha(t18["text-primary"], 0.92),
14940
15160
  targetTempoSeconds
14941
15161
  }
14942
15162
  ),
@@ -14950,7 +15170,7 @@ function DualGhostSpark({
14950
15170
  fontWeight: 800,
14951
15171
  letterSpacing: 1,
14952
15172
  fontFamily: FONT_UI,
14953
- fill: t17["text-tertiary"],
15173
+ fill: t18["text-tertiary"],
14954
15174
  children: leftLabel
14955
15175
  }
14956
15176
  ),
@@ -14963,7 +15183,7 @@ function DualGhostSpark({
14963
15183
  fontWeight: 800,
14964
15184
  letterSpacing: 1,
14965
15185
  fontFamily: FONT_UI,
14966
- fill: t17["text-tertiary"],
15186
+ fill: t18["text-tertiary"],
14967
15187
  children: rightLabel
14968
15188
  }
14969
15189
  )
@@ -15054,6 +15274,7 @@ function Treemap({
15054
15274
  {
15055
15275
  id: "__more__",
15056
15276
  value: restValue,
15277
+ // VW-82: no token at this value (nearest surface-overlay #373635); proposed, not swapped.
15057
15278
  color: "#3a3a3a",
15058
15279
  label: `+${clean.length - (maxTiles - 1)} more`
15059
15280
  }
@@ -15081,20 +15302,21 @@ function Treemap({
15081
15302
  borderRadius: 3,
15082
15303
  opacity: selected ? 1 : 0.9,
15083
15304
  borderWidth: selected ? 2 : 0,
15084
- borderColor: "#ffffff",
15305
+ borderColor: primitiveColors.white,
15085
15306
  padding: 4,
15086
15307
  overflow: "hidden"
15087
15308
  },
15088
- children: labelFits2 && /* @__PURE__ */ jsx(Text, { numberOfLines: 2, className: "text-[10px] font-semibold text-[#0b0b0b]", children: r.datum.label ?? r.datum.id })
15309
+ children: labelFits2 && // VW-82: label on a data-coloured tile; no on-data token exists yet.
15310
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 2, className: "text-[10px] font-semibold text-[#0b0b0b]", children: r.datum.label ?? r.datum.id })
15089
15311
  },
15090
15312
  r.datum.id
15091
15313
  );
15092
15314
  }) });
15093
15315
  }
15094
15316
  var PALETTE2 = DATAVIZ_CATEGORICAL_PALETTE;
15095
- var GRID_LINE2 = "rgba(255,255,255,0.07)";
15096
- var AXIS_LINE = "rgba(255,255,255,0.18)";
15097
- var DIAGONAL_LINE = "rgba(255,255,255,0.28)";
15317
+ var GRID_LINE2 = alpha(primitiveColors.white, 0.07);
15318
+ var AXIS_LINE = alpha(primitiveColors.white, 0.18);
15319
+ var DIAGONAL_LINE = alpha(primitiveColors.white, 0.28);
15098
15320
  var DEFAULT_R = 6;
15099
15321
  var PLOT_LEFT2 = 40;
15100
15322
  var PLOT_RIGHT = 12;
@@ -15189,8 +15411,8 @@ function Scatter({
15189
15411
  testID: "scatter-canvas",
15190
15412
  style: { position: "absolute", top: 0, left: 0, width, height, overflow: "hidden" },
15191
15413
  children: [
15192
- ticksOf(yd, TICK_COUNT).map((t18, i) => {
15193
- const y = toY(t18);
15414
+ ticksOf(yd, TICK_COUNT).map((t19, i) => {
15415
+ const y = toY(t19);
15194
15416
  return /* @__PURE__ */ jsx(
15195
15417
  View,
15196
15418
  {
@@ -15215,15 +15437,15 @@ function Scatter({
15215
15437
  width: PLOT_LEFT2 - 6,
15216
15438
  textAlign: "right"
15217
15439
  },
15218
- children: formatTick(t18)
15440
+ children: formatTick(t19)
15219
15441
  }
15220
15442
  )
15221
15443
  },
15222
15444
  `y-${i}`
15223
15445
  );
15224
15446
  }),
15225
- ticksOf(xd, TICK_COUNT).map((t18, i) => {
15226
- const x = toX(t18);
15447
+ ticksOf(xd, TICK_COUNT).map((t19, i) => {
15448
+ const x = toX(t19);
15227
15449
  return /* @__PURE__ */ jsx(
15228
15450
  View,
15229
15451
  {
@@ -15248,7 +15470,7 @@ function Scatter({
15248
15470
  width: 32,
15249
15471
  textAlign: "center"
15250
15472
  },
15251
- children: formatTick(t18)
15473
+ children: formatTick(t19)
15252
15474
  }
15253
15475
  )
15254
15476
  },
@@ -15354,7 +15576,7 @@ function Scatter({
15354
15576
  backgroundColor: p.color,
15355
15577
  opacity: selected ? 1 : 0.82,
15356
15578
  borderWidth: selected ? 2 : 0,
15357
- borderColor: "#ffffff"
15579
+ borderColor: primitiveColors.white
15358
15580
  },
15359
15581
  children: showLabel && /* @__PURE__ */ jsx(
15360
15582
  Text,
@@ -15382,7 +15604,7 @@ var sem2 = getSemanticColors("dark");
15382
15604
  var STATUS_SUCCESS5 = sem2["status-success"];
15383
15605
  var STATUS_WARNING5 = sem2["status-warning"];
15384
15606
  var STATUS_ERROR4 = sem2["status-error"];
15385
- var TRACK = "rgba(255,255,255,0.08)";
15607
+ var TRACK = alpha(primitiveColors.white, 0.08);
15386
15608
  var DEFAULT_THRESHOLDS2 = [
15387
15609
  { value: 0, color: STATUS_ERROR4 },
15388
15610
  { value: 60, color: STATUS_WARNING5 },
@@ -15453,23 +15675,23 @@ function Gauge2({
15453
15675
  testID: "gauge",
15454
15676
  ...props,
15455
15677
  children: [
15456
- ticks.map((t18) => /* @__PURE__ */ jsx(
15678
+ ticks.map((t19) => /* @__PURE__ */ jsx(
15457
15679
  View,
15458
15680
  {
15459
15681
  accessibilityElementsHidden: true,
15460
15682
  testID: "gauge-segment",
15461
15683
  style: {
15462
15684
  position: "absolute",
15463
- left: t18.left - tickThickness / 2,
15464
- top: t18.top - tickLength / 2,
15685
+ left: t19.left - tickThickness / 2,
15686
+ top: t19.top - tickLength / 2,
15465
15687
  width: tickThickness,
15466
15688
  height: tickLength,
15467
15689
  borderRadius: tickThickness / 2,
15468
- backgroundColor: t18.color,
15469
- transform: [{ rotate: t18.rotate }]
15690
+ backgroundColor: t19.color,
15691
+ transform: [{ rotate: t19.rotate }]
15470
15692
  }
15471
15693
  },
15472
- t18.key
15694
+ t19.key
15473
15695
  )),
15474
15696
  /* @__PURE__ */ jsxs(
15475
15697
  View,
@@ -16118,7 +16340,7 @@ var TASK_COMPARATORS = {
16118
16340
  function SeverityLegend({ tasks }) {
16119
16341
  const counts = useMemo(() => {
16120
16342
  const c2 = { critical: 0, high: 0, medium: 0, low: 0 };
16121
- for (const t18 of tasks) if (t18.severity) c2[t18.severity]++;
16343
+ for (const t19 of tasks) if (t19.severity) c2[t19.severity]++;
16122
16344
  return c2;
16123
16345
  }, [tasks]);
16124
16346
  return /* @__PURE__ */ jsx(View, { className: "flex-row items-center gap-3", children: SEVERITY_ORDER.map((severity) => /* @__PURE__ */ jsxs(View, { className: "flex-row items-center gap-1.5", children: [
@@ -16540,7 +16762,7 @@ function SessionDetail({
16540
16762
  }) {
16541
16763
  const refs = useMemo(() => extractTaskRefs(session.body), [session.body]);
16542
16764
  const touched = useMemo(
16543
- () => refs.map((id) => tasks.find((t18) => t18.id === id)).filter((t18) => !!t18),
16765
+ () => refs.map((id) => tasks.find((t19) => t19.id === id)).filter((t19) => !!t19),
16544
16766
  [refs, tasks]
16545
16767
  );
16546
16768
  const body = useMemo(() => stripLeadingHeading(session.body), [session.body]);
@@ -16624,7 +16846,7 @@ function StepButton({
16624
16846
  Typography,
16625
16847
  {
16626
16848
  variant: "body2",
16627
- className: cn("leading-none", disabled ? "text-text-tertiary/40" : "text-text-secondary"),
16849
+ className: cn("leading-none", disabled ? "text-text-disabled" : "text-text-secondary"),
16628
16850
  children: glyph
16629
16851
  }
16630
16852
  )
@@ -17280,6 +17502,6 @@ function composeValidators(...validators) {
17280
17502
  };
17281
17503
  }
17282
17504
 
17283
- export { Accordion, AccordionButton, AccordionItem, AccordionPanel, ActivityIcon, Alert, AlertDescription, AlertTitle, AlertTriangleIcon, AppShell, Autocomplete, Avatar, AvatarBadge, AvatarGroup, AwardIcon, BAND_GAP, BAND_H, Badge, BadgeText, BaseBadge, BluetoothIcon, BotIcon, BrainIcon, BrandLockup, BreadcrumbItem, Breadcrumbs, Button, ButtonIcon, ButtonSpinner, ButtonText, CARD_HEIGHT_SHARE_STACKED, CARD_WIDTH_BASE, CARD_WIDTH_MAX, CARD_WIDTH_XL_RATIO, CATEGORICAL_CVD_SAFE_MAX, COMPACT_SEVERITY_BELOW, CapacityBandChart, Caption, Card, CardContent, CardDescription, CardFooter, CardHeader, CardSkeleton, CardTitle, Checkbox, CheckboxGroup, Chip, CircleSlashIcon, CircularProgress, CircularTimer, CoChangeChip, Collapse, CollapseButton, CollapseContent, DRIFT_GREY, DashboardShell, DataRow, DateTime, DeviationBar, DeviceIndicator, DeviceMenu, DeviceRow, Divider, Drawer, DrawerBody, DrawerFooter, DrawerHeader, DualGhostSpark, DualVelocityStrip, DumbbellIcon, ELEVATION_PLANE, EmptyState, ExactTime, ExerciseCard, ExerciseCardHeading, ExerciseHeading, ExerciseIndicator, Eyebrow, FILE_EVENT_COLOR, FILE_EVENT_COLOR_CATEGORICAL, FILE_EVENT_COLOR_SEMANTIC, FLOATING_ELEVATION_MIN, FLOATING_LIFT_MIN, FatigueLights, FatigueMeter, FileActivityDetail, FileActivityRow, FileHistoryExplorer, FilePathLabel, FormActions, FormField, FormRow, FormSection, GRIND_THRESHOLD, Gauge2 as Gauge, GhostBand, GhostBloom, GhostSpark, HERO_EYEBROW_ALLOWANCE, HStack, Heading, HeadphonesIcon, HelpTip, HistoryIcon, INDICATOR_PRECEDENCE, INITIATIVE_STATE_META, IconBox, Indicator, InfoIcon, InitiativeBrief, InitiativeCard, InitiativeHeader, Input, InputBar, InputGroup, IntensityBar, KanbanIcon, LIFT_RIM_ALPHA, Label, LabelWithHelp, LayersIcon, Link, ListItem, ListItemContent, ListItemDivider, ListItemIcon, ListItemTrailing, LiveAuraFrame, LiveFatigueCard, LiveFatiguePanel, METRIC_FONT, MarkdownProse, Menu, MenuDivider, MenuGroup, MenuItem, MenuList, MenuTrigger, MesoCard, MesoProgressBar, MesoStatusCard, Metric, MetricCell, MetricGroup, MetricTiles, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalTitle, MuscleGroupChip, NavItem, OpenLoops, Overline, PANEL_BREAKPOINTS, PHASE_AXIS_COLOR, PLANE_ORDER, PRESSED_ELEVATION_LEVEL, PR_REF_PATTERN, Paragraph, PasswordInput, PersonStandingIcon, Pill, PlaceholderStrip, Popover, PopoverCloseButton, PopoverContent, PopoverTrigger, PortfolioOverview, PrBadge, PrHistoryModal, Progress, ProgressSteps, RED_DEEP, RED_LIGHT, RED_MID, Radio, RadioGroup, ReadinessCheck, RestTimer, RomProgressionChart, SET_STRIP_VARIABLE_COLOR, SET_STRIP_ZONES, SEVERITY_BAR_COLOR, SEVERITY_META, SEVERITY_ORDER, SEVERITY_RANK, SILVER, STATE_LABEL, SURFACE_LEVEL_TOKEN, SURFACE_PLANE_STEPS, ScaleIcon, Scatter, ScheduleTiles, Section, SectionContent, SectionHeader, SegmentedBar, SegmentedProgressBar, Select, SessionDetail, SessionHeader, SessionList, SessionListItem, SessionRail, SessionStatePill, SetBar, SetRow, SetStrip, SetTableHeader, SetsRepsLoad, SeverityLabel, SideNav, Sidebar, SidebarContent, SidebarDivider, SidebarFooter, SidebarHeader, SidebarItem, SidebarSection, Skeleton, SkeletonCard, SkeletonCircle, SkeletonListItem, SkeletonText, SparkBars, Sparkline, Spinner, Stack, StarIcon, StatusDot, StatusPill2 as StatusPill, StepContent, StepIndicator, StepLabel, Stepper, Step as StepperStep, StrengthTrendChart, SupersetWrapper, Surface, SurfaceContext, SvgIcon, Switch, TASK_COLUMN_WIDTHS, TASK_REF_PATTERN, TONE_COLOR, Tab, TabList, TabPanel, TabPanels, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TablePagination, TableRow, Tabs, TaskIds, TaskRow, TaskTable, TempoDisplay, Tile, TimerReadout, Toast, ToastProvider, ToolbarButton, ToolbarButtonGroup, Tooltip, TopBar, Treemap, TrendingDownIcon, Typography, VStack, VelocityHero, VelocityStrip, VerdictHero, VoltrasMark, VolumeLandmarkBar, WIKI_LINK_PATTERN, WeekRow, WeightBadge, WorkoutCard, WorkoutPill, WorkoutShell, WorkoutTopBar, ZoneTrack, alertRedVivid, alpha, applyThemePreset, audiobookPreset, auraForVerdict, barPaper, bestTextColor, brandKeys, brandPresets, buttonSizes, calculateMeanVelocity, calculateVelocityLoss, categoricalPalette, cn, composeValidators, createFieldId, darkThemeCSSVars, darken, debossLabel, defaultNavItems, defaultPreset, discreteRainbow, divergingScale, elevationPlane, extractTaskRefs, fitColumns, formatCompact, formatDateTime, formatDuration, formatPrescription, formatSessionDuration, formatSignedCompact, formatSignedPct, formatTaskAge, formatVelocity, getCategoricalColor, getContrastText, getDiscreteRainbowColor, getElevationShadow, getElevationSurface, getFieldAriaProps, getFieldValidationProps, getGlowShadow, getHoverColors, getLuminance, getPressedRecessShadow, getResultColor, getSemanticColors, getStatusColor, getThemeCSSVars, getVelocityZoneColor, getVelocityZoneName, ghostLineColor, gluestackConfig, grainForTone, grainOpacityForTone, greyRamp, groupByPeriod, hasMaxLength, hasMinLength, hexToRgb, hsvToRgb, insetWell, isCssPropertyManifest, isDark, isEmpty, isValidEmail, liftShadow, liftStyle, lightThemeCSSVars, lighten, linearGradient, liveAuraColor, mergePhaseSegments, onSurfaceColors, paceTone, paceToneColor, panelBodySplit, panelLayout, panelTier, paperSheet, parseProseBlocks, postIt, prRefLinker, pressedLevel, primitiveBorderRadius, primitiveBreakpoints, primitiveColors, primitiveRamps, primitiveSpacing, primitiveTypography, primitiveZIndex, raisedLevel, resolveColor, resolveIndicator, resolveSurfaceDepth, rgbToHex, rgbToHsv, roundRpe, roundTempo, roundWeight, rpeColor, semanticColorsDark, semanticColorsLight, semanticTypography, sequentialEffort, sessionLinkers, sessionPeriod, sessionRowMeta, severityRank, smoothPath, splitBriefSections, splitPath, statusPillColor, stripLeadingHeading, surfaceBackground, surfaceGradient, taskRefLinker, useColumnFit, useHoverState, useMeasuredWidth, useOnSurfaceColor, useResolvedSurface, useSurface, useSurfaceMode, useTable, useTimer, useToast, useToolbarButton, validateCssPropertyManifest, validationRules, velocityZoneColor, wikiLinkLinker, workoutNavItems };
17505
+ export { Accordion, AccordionButton, AccordionItem, AccordionPanel, ActivityIcon, Alert, AlertDescription, AlertTitle, AlertTriangleIcon, AppShell, Autocomplete, Avatar, AvatarBadge, AvatarGroup, AwardIcon, BAND_GAP, BAND_H, Badge, BadgeText, BaseBadge, BluetoothIcon, BotIcon, BrainIcon, BrandLockup, BreadcrumbItem, Breadcrumbs, Button, ButtonIcon, ButtonSpinner, ButtonText, CARD_HEIGHT_SHARE_STACKED, CARD_WIDTH_BASE, CARD_WIDTH_MAX, CARD_WIDTH_XL_RATIO, CATEGORICAL_CVD_SAFE_MAX, COMPACT_SEVERITY_BELOW, CapacityBandChart, Caption, Card, CardContent, CardDescription, CardFooter, CardHeader, CardSkeleton, CardTitle, Checkbox, CheckboxGroup, Chip, CircleSlashIcon, CircularProgress, CircularTimer, CoChangeChip, Collapse, CollapseButton, CollapseContent, DRIFT_GREY, DashboardShell, DataRow, DateTime, DeviationBar, DeviceIndicator, DeviceMenu, DeviceRow, Divider, Drawer, DrawerBody, DrawerFooter, DrawerHeader, DualGhostSpark, DualVelocityStrip, DumbbellIcon, ELEVATION_PLANE, EmptyState, ExactTime, ExerciseCard, ExerciseCardHeading, ExerciseHeading, ExerciseIndicator, Eyebrow, FILE_EVENT_COLOR, FILE_EVENT_COLOR_CATEGORICAL, FILE_EVENT_COLOR_SEMANTIC, FLOATING_ELEVATION_MIN, FLOATING_LIFT_MIN, FatigueLights, FatigueMeter, FileActivityDetail, FileActivityRow, FileHistoryExplorer, FilePathLabel, FormActions, FormField, FormRow, FormSection, GRIND_THRESHOLD, Gauge2 as Gauge, GhostBand, GhostBloom, GhostSpark, HERO_EYEBROW_ALLOWANCE, HStack, Heading, HeadphonesIcon, HelpTip, HistoryIcon, INDICATOR_PRECEDENCE, INITIATIVE_STATE_META, IconBox, Indicator, InfoIcon, InitiativeBrief, InitiativeCard, InitiativeHeader, Input, InputBar, InputGroup, IntensityBar, KanbanIcon, LIFT_RIM_ALPHA, Label, LabelWithHelp, LayersIcon, Link, ListItem, ListItemContent, ListItemDivider, ListItemIcon, ListItemTrailing, LiveAuraFrame, LiveFatigueCard, LiveFatiguePanel, METRIC_FONT, MarkdownProse, Menu, MenuDivider, MenuGroup, MenuItem, MenuList, MenuTrigger, MesoCard, MesoProgressBar, MesoStatusCard, Metric, MetricCell, MetricGroup, MetricTiles, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalTitle, MuscleGroupChip, NavItem, OpenLoops, Overline, PANEL_BREAKPOINTS, PHASE_AXIS_COLOR, PLANE_ORDER, PRESSED_ELEVATION_LEVEL, PR_REF_PATTERN, Paragraph, PasswordInput, PersonStandingIcon, Pill, PlaceholderStrip, Popover, PopoverCloseButton, PopoverContent, PopoverTrigger, PortfolioOverview, PrBadge, PrHistoryModal, Progress, ProgressSteps, RED_DEEP, RED_LIGHT, RED_MID, Radio, RadioGroup, ReadinessCheck, RestTimer, RomProgressionChart, SET_STRIP_VARIABLE_COLOR, SET_STRIP_ZONES, SEVERITY_BAR_COLOR, SEVERITY_META, SEVERITY_ORDER, SEVERITY_RANK, SILVER, STATE_LABEL, SURFACE_LEVEL_TOKEN, SURFACE_PLANE_STEPS, ScaleIcon, Scatter, ScheduleTiles, Section, SectionContent, SectionHeader, SegmentedBar, SegmentedProgressBar, Select, SessionDetail, SessionHeader, SessionList, SessionListItem, SessionRail, SessionStatePill, SetBar, SetRow, SetStrip, SetTableHeader, SetsRepsLoad, SeverityLabel, SideNav, Sidebar, SidebarContent, SidebarDivider, SidebarFooter, SidebarHeader, SidebarItem, SidebarSection, Skeleton, SkeletonCard, SkeletonCircle, SkeletonListItem, SkeletonText, SparkBars, Sparkline, Spinner, Stack, StarIcon, StatusDot, StatusPill2 as StatusPill, StepContent, StepIndicator, StepLabel, Stepper, Step as StepperStep, StrengthTrendChart, SupersetWrapper, Surface, SurfaceContext, SvgIcon, Switch, TASK_COLUMN_WIDTHS, TASK_REF_PATTERN, TONE_COLOR, Tab, TabList, TabPanel, TabPanels, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TablePagination, TableRow, Tabs, TaskIds, TaskRow, TaskTable, TempoDisplay, Tile, TimerReadout, Toast, ToastProvider, ToolbarButton, ToolbarButtonGroup, Tooltip, TopBar, Treemap, TrendingDownIcon, Typography, VStack, VelocityHero, VelocityStrip, VerdictHero, VoltrasMark, VolumeLandmarkBar, WIKI_LINK_PATTERN, WeekRow, WeightBadge, WorkoutCard, WorkoutPill, WorkoutShell, WorkoutTopBar, ZoneTrack, alertRedVivid, alpha, applyThemePreset, audiobookPreset, auraForVerdict, barPaper, bestTextColor, brandKeys, brandPresets, buttonSizes, calculateMeanVelocity, calculateVelocityLoss, categoricalPalette, cn, composeValidators, createFieldId, darkThemeCSSVars, darken, debossLabel, defaultNavItems, defaultPreset, discreteRainbow, divergingScale, elevationPlane, exerciseHeadingLabel, exerciseLiveColor, exerciseRowStateColor, extractTaskRefs, fitColumns, formatCompact, formatDateTime, formatDuration, formatPrescription, formatSessionDuration, formatSignedCompact, formatSignedPct, formatTaskAge, formatVelocity, getCategoricalColor, getContrastText, getDiscreteRainbowColor, getElevationShadow, getElevationSurface, getFieldAriaProps, getFieldValidationProps, getGlowShadow, getHoverColors, getLuminance, getPressedRecessShadow, getResultColor, getSemanticColors, getStatusColor, getThemeCSSVars, getVelocityZoneColor, getVelocityZoneName, ghostLineColor, gluestackConfig, grainForTone, grainOpacityForTone, greyRamp, groupByPeriod, hasMaxLength, hasMinLength, hexToRgb, hsvToRgb, insetWell, isCssPropertyManifest, isDark, isEmpty, isValidEmail, liftShadow, liftStyle, lightThemeCSSVars, lighten, linearGradient, liveAuraColor, mergePhaseSegments, onSurfaceColors, paceTone, paceToneColor, panelBodySplit, panelLayout, panelTier, paperSheet, parseProseBlocks, postIt, prRefLinker, pressedLevel, primitiveBorderRadius, primitiveBreakpoints, primitiveColors, primitiveRamps, primitiveSpacing, primitiveTypography, primitiveZIndex, raisedLevel, resolveColor, resolveIndicator, resolveSurfaceDepth, resultPaletteColors, rgbToHex, rgbToHsv, roundRpe, roundTempo, roundWeight, rpeColor, semanticColorsDark, semanticColorsLight, semanticPins, semanticTypography, sequentialEffort, sessionLinkers, sessionPeriod, sessionRowMeta, severityRank, smoothPath, splitBriefSections, splitPath, statusPillColor, stripLeadingHeading, surfaceBackground, surfaceGradient, taskRefLinker, useColumnFit, useHoverState, useMeasuredWidth, useOnSurfaceColor, useResolvedSurface, useSurface, useSurfaceMode, useTable, useTimer, useToast, useToolbarButton, validateCssPropertyManifest, validationRules, velocityZoneColor, wikiLinkLinker, workoutNavItems };
17284
17506
  //# sourceMappingURL=index.mjs.map
17285
17507
  //# sourceMappingURL=index.mjs.map